Merge "MediaMetadataRetrieverTest: remove unused import to fix compile error." into kitkat-cts-dev am: 2afd52cfae am: e749459d32
am: 6247829995

* commit '624782999528b40264c01a054114c14ff4bc0ea0':
  MediaMetadataRetrieverTest: remove unused import to fix compile error.
diff --git a/CtsBuild.mk b/CtsBuild.mk
index dbe93c7..ba158ce 100644
--- a/CtsBuild.mk
+++ b/CtsBuild.mk
@@ -14,32 +14,10 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# Test XMLs, native executables, and packages will be placed in this
-# directory before creating the final CTS distribution.
-CTS_TESTCASES_OUT := $(HOST_OUT)/cts-testcases
-
-# Scanners of source files for tests which are then inputed into
-# the XML generator to produce test XMLs.
-CTS_NATIVE_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-native-scanner
-CTS_JAVA_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-java-scanner
-CTS_JAVA_TEST_SCANNER_DOCLET := $(HOST_OUT_JAVA_LIBRARIES)/cts-java-scanner-doclet.jar
-
-# Generator of test XMLs from scanner output.
-CTS_XML_GENERATOR := $(HOST_OUT_EXECUTABLES)/cts-xml-generator
-
-# File indicating which tests should be blacklisted due to problems.
-CTS_EXPECTATIONS := cts/tests/expectations/knownfailures.txt
-
-# File indicating which tests should be blacklisted due to unsupported abi.
-CTS_UNSUPPORTED_ABIS := cts/tests/expectations/unsupportedabis.txt
-
-# Holds the target architecture to build for.
-CTS_TARGET_ARCH := $(TARGET_ARCH)
-
 # Functions to get the paths of the build outputs.
 
 define cts-get-lib-paths
-	$(foreach lib,$(1),$(HOST_OUT_JAVA_LIBRARIES)/$(lib).jar)
+	$(foreach lib,$(1),$(CTS_TESTCASES_OUT)/$(lib).jar)
 endef
 
 define cts-get-ui-lib-paths
@@ -47,7 +25,7 @@
 endef
 
 define cts-get-native-paths
-	$(foreach exe,$(1),$(call intermediates-dir-for,EXECUTABLES,$(exe),,,$(3))/$(exe)$(2))
+	$(foreach exe,$(1),$(CTS_TESTCASES_OUT)/$(exe)$(2))
 endef
 
 define cts-get-package-paths
@@ -62,6 +40,10 @@
 	$(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),$(CTS_TESTCASES_OUT)/com.drawelements.deqp.$(api).xml)
+	$(foreach api,$(1),$(call cts-get-deqp-api-test-xmls,$(api)))
 endef
diff --git a/CtsCoverage.mk b/CtsCoverage.mk
index 4b01005..1fb98dc 100644
--- a/CtsCoverage.mk
+++ b/CtsCoverage.mk
@@ -17,8 +17,6 @@
 # Makefile for producing CTS coverage reports.
 # Run "make cts-test-coverage" in the $ANDROID_BUILD_TOP directory.
 
-include cts/CtsTestCaseList.mk
-
 cts_api_coverage_exe := $(HOST_OUT_EXECUTABLES)/cts-api-coverage
 dexdeps_exe := $(HOST_OUT_EXECUTABLES)/dexdeps
 
@@ -38,41 +36,40 @@
 
 cts_api_coverage_dependencies := $(cts_api_coverage_exe) $(dexdeps_exe) $(api_xml_description)
 
-cts_coverage_test_cases_dependencies := $(foreach c, $(CTS_COVERAGE_TEST_CASE_LIST), $(call intermediates-dir-for,APPS,$(c))/package.apk)
-$(cts-test-coverage-report): PRIVATE_TEST_CASES_APKS := $(cts_coverage_test_cases_dependencies)
+android_cts_zip := $(HOST_OUT)/cts/android-cts.zip
+cts_verifier_apk := $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk
+
+$(cts-test-coverage-report): PRIVATE_TEST_CASES := $(CTS_TESTCASES_OUT)
 $(cts-test-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
 $(cts-test-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
 $(cts-test-coverage-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-test-coverage-report) : $(cts_coverage_test_cases_dependencies) $(cts_api_coverage_dependencies) | $(ACP)
+$(cts-test-coverage-report) : $(android_cts_zip) $(cts_api_coverage_dependencies) | $(ACP)
 	$(call generate-coverage-report,"CTS Tests API Coverage Report",\
-			$(PRIVATE_TEST_CASES_APKS),html)
+			$(PRIVATE_TEST_CASES),html)
 
-cts_coverage_test_cases_dependencies := $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk
-$(cts-verifier-coverage-report): PRIVATE_TEST_CASES_APKS := $(cts_coverage_test_cases_dependencies)
+$(cts-verifier-coverage-report): PRIVATE_TEST_CASES := $(cts_verifier_apk)
 $(cts-verifier-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
 $(cts-verifier-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
 $(cts-verifier-coverage-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-verifier-coverage-report) : $(cts_coverage_test_cases_dependencies) $(cts_api_coverage_dependencies) | $(ACP)
+$(cts-verifier-coverage-report) : $(cts_verifier_apk) $(cts_api_coverage_dependencies) | $(ACP)
 	$(call generate-coverage-report,"CTS Verifier API Coverage Report",\
-			$(PRIVATE_TEST_CASES_APKS),html)
+			$(PRIVATE_TEST_CASES),html)
 
-cts_coverage_test_cases_dependencies := $(foreach c, $(CTS_COVERAGE_TEST_CASE_LIST) CtsVerifier, $(call intermediates-dir-for,APPS,$(c))/package.apk)
-$(cts-combined-coverage-report): PRIVATE_TEST_CASES_APKS := $(cts_coverage_test_cases_dependencies)
+$(cts-combined-coverage-report): PRIVATE_TEST_CASES := $(foreach c, $(cts_verifier_apk) $(CTS_TESTCASES_OUT), $(c))
 $(cts-combined-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
 $(cts-combined-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
 $(cts-combined-coverage-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-combined-coverage-report) : $(cts_coverage_test_cases_dependencies) $(cts_api_coverage_dependencies) | $(ACP)
+$(cts-combined-coverage-report) : $(android_cts_zip) $(cts_verifier_apk) $(cts_api_coverage_dependencies) | $(ACP)
 	$(call generate-coverage-report,"CTS Combined API Coverage Report",\
-			$(PRIVATE_TEST_CASES_APKS),html)
+			$(PRIVATE_TEST_CASES),html)
 
-cts_coverage_test_cases_dependencies := $(foreach c, $(CTS_COVERAGE_TEST_CASE_LIST) CtsVerifier, $(call intermediates-dir-for,APPS,$(c))/package.apk)
-$(cts-combined-xml-coverage-report): PRIVATE_TEST_CASES_APKS := $(cts_coverage_test_cases_dependencies)
+$(cts-combined-xml-coverage-report): PRIVATE_TEST_CASES := $(foreach c, $(cts_verifier_apk) $(CTS_TESTCASES_OUT), $(c))
 $(cts-combined-xml-coverage-report): PRIVATE_CTS_API_COVERAGE_EXE := $(cts_api_coverage_exe)
 $(cts-combined-xml-coverage-report): PRIVATE_DEXDEPS_EXE := $(dexdeps_exe)
 $(cts-combined-xml-coverage-report): PRIVATE_API_XML_DESC := $(api_xml_description)
-$(cts-combined-xml-coverage-report) : $(cts_coverage_test_cases_dependencies) $(cts_api_coverage_dependencies) | $(ACP)
+$(cts-combined-xml-coverage-report) : $(android_cts_zip) $(cts_verifier_apk) $(cts_api_coverage_dependencies) | $(ACP)
 	$(call generate-coverage-report,"CTS Combined API Coverage Report - XML",\
-			$(PRIVATE_TEST_CASES_APKS),xml)
+			$(PRIVATE_TEST_CASES),xml)
 
 .PHONY: cts-test-coverage
 cts-test-coverage : $(cts-test-coverage-report)
@@ -106,7 +103,6 @@
 
 # Reset temp vars
 cts_api_coverage_dependencies :=
-cts_coverage_test_cases_dependencies :=
 cts-combined-coverage-report :=
 cts-combined-xml-coverage-report :=
 cts-verifier-coverage-report :=
@@ -116,3 +112,5 @@
 coverage_out :=
 dexdeps_exe :=
 cts_api_coverage_exe :=
+cts_verifier_apk :=
+android_cts_zip :=
diff --git a/CtsTestCaseList.mk b/CtsTestCaseList.mk
index 6f475cc..765dda0 100644
--- a/CtsTestCaseList.mk
+++ b/CtsTestCaseList.mk
@@ -19,6 +19,11 @@
     CtsDocumentClient \
     CtsExternalStorageApp \
     CtsInstrumentationAppDiffCert \
+    CtsNetSecPolicyUsesCleartextTrafficFalse \
+    CtsNetSecPolicyUsesCleartextTrafficTrue \
+    CtsNetSecPolicyUsesCleartextTrafficUnspecified \
+    CtsUsePermissionApp \
+    CtsUsePermissionAppCompat \
     CtsPermissionDeclareApp \
     CtsPermissionDeclareAppCompat \
     CtsReadExternalStorageApp \
@@ -57,13 +62,33 @@
     CtsKeySetSigningBUpgradeB \
     CtsKeySetSigningAAndBUpgradeA \
     CtsKeySetSigningAAndCUpgradeB \
-    CtsKeySetSigningAUpgradeNone
+    CtsKeySetSigningAUpgradeNone \
+    CtsKeySetSharedUserSigningAUpgradeB \
+    CtsKeySetSharedUserSigningBUpgradeB \
+    CtsKeySetSigningABadUpgradeB \
+    CtsKeySetSigningCBadAUpgradeAB \
+    CtsKeySetSigningANoDefUpgradeB \
+    CtsKeySetSigningAUpgradeEcA \
+    CtsKeySetSigningEcAUpgradeA
+
+cts_account_support_packages := \
+    CtsUnaffiliatedAccountAuthenticators
 
 cts_support_packages := \
     CtsAccelerationTestStubs \
+    CtsAlarmClockService \
     CtsAppTestStubs \
+    CtsAssistService \
+    CtsAssistApp \
+    CtsAtraceTestApp \
+    CtsCertInstallerApp \
     CtsDeviceAdmin \
     CtsDeviceOpenGl \
+    CtsWifiConfigCreator \
+    CtsDeviceAndProfileOwnerApp \
+    CtsDeviceAppUsageTestApp \
+    CtsDeviceInfo \
+    CtsDeviceOsTestApp \
     CtsDeviceOwnerApp \
     CtsDeviceTaskswitchingAppA \
     CtsDeviceTaskswitchingAppB \
@@ -74,15 +99,25 @@
     CtsIntentSenderApp \
     CtsLauncherAppsTests \
     CtsLauncherAppsTestsSupport \
+    CtsLeanbackJank \
     CtsManagedProfileApp \
     CtsMonkeyApp \
     CtsMonkeyApp2 \
+    CtsPackageInstallerApp \
+    CtsPermissionApp \
+    CtsPreconditionsApp \
     CtsSimpleApp \
+    CtsSimplePreMApp \
     CtsSomeAccessibilityServices \
     CtsThemeDeviceApp \
     TestDeviceSetup \
     CtsUiAutomatorApp \
     CtsUsbSerialTestApp \
+    CtsVoiceInteractionService \
+    CtsVoiceInteractionApp \
+    CtsVoiceSettingsService \
+    CtsWidgetProviderApp \
+    $(cts_account_support_packages) \
     $(cts_security_apps_list) \
     $(cts_security_keysets_list)
 
@@ -111,11 +146,15 @@
     CtsAccessibilityServiceTestCases \
     CtsAccessibilityTestCases \
     CtsAdminTestCases \
+    CtsAlarmClockTestCases \
     CtsAnimationTestCases \
     CtsAppTestCases \
     CtsAppWidgetTestCases \
+    CtsAssistTestCases \
     CtsBluetoothTestCases \
     CtsCalendarcommon2TestCases \
+    CtsCallLogTestCases \
+    CtsCameraTestCases \
     CtsContentTestCases \
     CtsDatabaseTestCases \
     CtsDisplayTestCases \
@@ -128,16 +167,25 @@
     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 \
@@ -154,18 +202,23 @@
     CtsSecurityTestCases \
     CtsSignatureTestCases \
     CtsSpeechTestCases \
+    CtsSystemUiTestCases \
+    CtsTelecomTestCases \
+    CtsTelecomTestCases2 \
     CtsTelephonyTestCases \
     CtsTextTestCases \
     CtsTextureViewTestCases \
     CtsThemeTestCases \
+    CtsTransitionTestCases \
     CtsTvTestCases \
     CtsUiAutomationTestCases \
     CtsUiRenderingTestCases \
     CtsUsageStatsTestCases \
     CtsUtilTestCases \
     CtsViewTestCases \
+    CtsVoiceInteractionTestCases \
+    CtsVoiceSettingsTestCases \
     CtsWebkitTestCases \
-    CtsWebGLTestCases \
     CtsWidgetTestCases
 
 # All APKs that need to be scanned by the coverage utilities.
@@ -177,6 +230,7 @@
 cts_host_libraries := \
     CtsAdbTests \
     CtsAppSecurityTests \
+    CtsAtraceHostTestCases \
     CtsDevicePolicyManagerTestCases \
     CtsDumpsysHostTestCases \
     CtsHostJank \
@@ -184,7 +238,9 @@
     CtsHostUi \
     CtsJdwpSecurityHostTestCases \
     CtsMonkeyTestCases \
+    CtsOsHostTestCases \
     CtsThemeHostTestCases \
+    CtsUsageHostTestCases \
     CtsSecurityHostTestCases \
     CtsUsbTests
 
@@ -205,16 +261,14 @@
 
 cts_device_jars := \
     CtsDeviceJank \
-    CtsJdwpApp \
-    CtsPrintInstrument
-
-cts_device_executables := \
-    print-instrument
+    CtsJdwpApp
 
 cts_target_junit_tests := \
     CtsJdwp
 
 cts_deqp_test_apis := \
+    egl \
+    gles2 \
     gles3 \
     gles31
 
@@ -225,14 +279,8 @@
     $(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))
-
-# NOTE: If compiling on a 64 bit target, TARGET_2ND_ARCH will be non-empty
-# and will cause the function to expand to the secondary arch object
-# directory. If compiling on a 32 bit target, TARGET_2ND_ARCH will be
-# empty and will cause the function to expand to the primary arch object
-# directory.
-CTS_TEST_CASES += $(call cts-get-native-paths,$(cts_native_tests),32,$(TARGET_2ND_ARCH))
+    $(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)
diff --git a/apps/CameraITS/CameraITS.pdf b/apps/CameraITS/CameraITS.pdf
index 2430420..8953af9 100644
--- a/apps/CameraITS/CameraITS.pdf
+++ b/apps/CameraITS/CameraITS.pdf
Binary files differ
diff --git a/apps/CameraITS/pymodules/its/caps.py b/apps/CameraITS/pymodules/its/caps.py
index 24f4e75..95f19d9 100644
--- a/apps/CameraITS/pymodules/its/caps.py
+++ b/apps/CameraITS/pymodules/its/caps.py
@@ -133,6 +133,17 @@
     """
     return len(its.objects.get_available_output_sizes("raw10", props)) > 0
 
+def raw12(props):
+    """Returns whether a device supports RAW12 output.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return len(its.objects.get_available_output_sizes("raw12", props)) > 0
+
 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.
@@ -222,6 +233,109 @@
     return props.has_key("android.control.aeCompensationRange") and \
            props["android.control.aeCompensationRange"] != [0, 0]
 
+def ae_lock(props):
+    """Returns whether a device supports AE lock
+
+    Args:
+        props: Camera properties object.
+
+    Return:
+        Boolean.
+    """
+    return props.has_key("android.control.aeLockAvailable") and \
+           props["android.control.aeLockAvailable"] == 1
+
+def awb_lock(props):
+    """Returns whether a device supports AWB lock
+
+    Args:
+        props: Camera properties object.
+
+    Return:
+        Boolean.
+    """
+    return props.has_key("android.control.awbLockAvailable") and \
+           props["android.control.awbLockAvailable"] == 1
+
+def lsc_map(props):
+    """Returns whether a device supports lens shading map output
+
+    Args:
+        props: Camera properties object.
+
+    Return:
+        Boolean.
+    """
+    return props.has_key(
+            "android.statistics.info.availableLensShadingMapModes") and \
+        1 in props["android.statistics.info.availableLensShadingMapModes"]
+
+def lsc_off(props):
+    """Returns whether a device supports disabling lens shading correction
+
+    Args:
+        props: Camera properties object.
+
+    Return:
+        Boolean.
+    """
+    return props.has_key(
+            "android.shading.availableModes") and \
+        0 in props["android.shading.availableModes"]
+
+def yuv_reprocess(props):
+    """Returns whether a device supports YUV reprocessing.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.request.availableCapabilities") and \
+           7 in props["android.request.availableCapabilities"]
+
+def private_reprocess(props):
+    """Returns whether a device supports PRIVATE reprocessing.
+
+    Args:
+        props: Camera properties object.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key("android.request.availableCapabilities") and \
+           4 in props["android.request.availableCapabilities"]
+
+def noise_reduction_mode(props, mode):
+    """Returns whether a device supports the noise reduction mode.
+
+    Args:
+        props: Camera properties objects.
+        mode: Integer, indicating the noise reduction mode to check for
+              availability.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key(
+            "android.noiseReduction.availableNoiseReductionModes") and mode \
+            in props["android.noiseReduction.availableNoiseReductionModes"];
+
+def edge_mode(props, mode):
+    """Returns whether a device supports the edge mode.
+
+    Args:
+        props: Camera properties objects.
+        mode: Integer, indicating the edge mode to check for availability.
+
+    Returns:
+        Boolean.
+    """
+    return props.has_key(
+            "android.edge.availableEdgeModes") and mode \
+            in props["android.edge.availableEdgeModes"];
+
 class __UnitTest(unittest.TestCase):
     """Run a suite of unit tests on this module.
     """
diff --git a/apps/CameraITS/pymodules/its/device.py b/apps/CameraITS/pymodules/its/device.py
index ad9786e..835a4a4 100644
--- a/apps/CameraITS/pymodules/its/device.py
+++ b/apps/CameraITS/pymodules/its/device.py
@@ -41,12 +41,21 @@
         sock: The open socket.
     """
 
-    # Open a connection to localhost:6000, forwarded to port 6000 on the device.
-    # TODO: Support multiple devices running over different TCP ports.
+    # Open a connection to localhost:<host_port>, forwarded to port 6000 on the
+    # device. <host_port> is determined at run-time to support multiple
+    # connected devices.
     IPADDR = '127.0.0.1'
-    PORT = 6000
+    REMOTE_PORT = 6000
     BUFFER_SIZE = 4096
 
+    # LOCK_PORT is used as a mutex lock to protect the list of forwarded ports
+    # among all processes. The script assumes LOCK_PORT is available and will
+    # try to use ports between CLIENT_PORT_START and
+    # CLIENT_PORT_START+MAX_NUM_PORTS-1 on host for ITS sessions.
+    CLIENT_PORT_START = 6000
+    MAX_NUM_PORTS = 100
+    LOCK_PORT = CLIENT_PORT_START + MAX_NUM_PORTS
+
     # Seconds timeout on each socket operation.
     SOCK_TIMEOUT = 10.0
     SEC_TO_NSEC = 1000*1000*1000.0
@@ -58,8 +67,8 @@
     EXTRA_SUCCESS = 'camera.its.extra.SUCCESS'
     EXTRA_SUMMARY = 'camera.its.extra.SUMMARY'
 
-    # TODO: Handle multiple connected devices.
-    ADB = "adb -d"
+    adb = "adb -d"
+    device_id = ""
 
     # Definitions for some of the common output format options for do_capture().
     # Each gets images of full resolution for each requested format.
@@ -75,12 +84,83 @@
     CAP_RAW_YUV_JPEG = [{"format":"raw"}, {"format":"yuv"}, {"format":"jpeg"}]
     CAP_DNG_YUV_JPEG = [{"format":"dng"}, {"format":"yuv"}, {"format":"jpeg"}]
 
-    # Method to handle the case where the service isn't already running.
-    # This occurs when a test is invoked directly from the command line, rather
-    # than as a part of a separate test harness which is setting up the device
-    # and the TCP forwarding.
-    def __pre_init(self):
+    # 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
+    def __init_socket_port(self):
+        NUM_RETRIES = 100
+        RETRY_WAIT_TIME_SEC = 0.05
 
+        # Bind a socket to use as mutex lock
+        socket_lock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        for i in range(NUM_RETRIES):
+            try:
+                socket_lock.bind((ItsSession.IPADDR, ItsSession.LOCK_PORT))
+                break
+            except socket.error:
+                if i == NUM_RETRIES - 1:
+                    raise its.error.Error(self.device_id,
+                                          "acquiring socket lock timed out")
+                else:
+                    time.sleep(RETRY_WAIT_TIME_SEC)
+
+        # Check if a port is already assigned to the device.
+        command = "adb forward --list"
+        proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
+        output, error = proc.communicate()
+
+        port = None
+        used_ports = []
+        for line in output.split(os.linesep):
+            # each line should be formatted as:
+            # "<device_id> tcp:<host_port> tcp:<remote_port>"
+            forward_info = line.split()
+            if len(forward_info) >= 3 and \
+               len(forward_info[1]) > 4 and forward_info[1][:4] == "tcp:" and \
+               len(forward_info[2]) > 4 and forward_info[2][:4] == "tcp:":
+                local_p = int(forward_info[1][4:])
+                remote_p = int(forward_info[2][4:])
+                if forward_info[0] == self.device_id and \
+                   remote_p == ItsSession.REMOTE_PORT:
+                    port = local_p
+                    break;
+                else:
+                    used_ports.append(local_p)
+
+        # Find the first available port if no port is assigned to the device.
+        if port is None:
+            for p in range(ItsSession.CLIENT_PORT_START,
+                           ItsSession.CLIENT_PORT_START +
+                           ItsSession.MAX_NUM_PORTS):
+                if p not in used_ports:
+                    # Try to run "adb forward" with the port
+                    command = "%s forward tcp:%d tcp:%d" % \
+                              (self.adb, p, self.REMOTE_PORT)
+                    proc = subprocess.Popen(command.split(),
+                                            stdout=subprocess.PIPE,
+                                            stderr=subprocess.PIPE)
+                    output, error = proc.communicate()
+
+                    # Check if there is no error
+                    if error is None or error.find("error") < 0:
+                        port = p
+                        break
+
+        if port is None:
+            raise its.error.Error(self.device_id, " cannot find an available " +
+                                  "port")
+
+        # Release the socket as mutex unlock
+        socket_lock.close()
+
+        # Connect to the socket
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        self.sock.connect((self.IPADDR, port))
+        self.sock.settimeout(self.SOCK_TIMEOUT)
+
+    # Reboot the device if needed and wait for the service to be ready for
+    # connection.
+    def __wait_for_service(self):
         # This also includes the optional reboot handling: if the user
         # provides a "reboot" or "reboot=N" arg, then reboot the device,
         # waiting for N seconds (default 30) before returning.
@@ -90,19 +170,19 @@
                 if len(s) > 7 and s[6] == "=":
                     duration = int(s[7:])
                 print "Rebooting device"
-                _run("%s reboot" % (ItsSession.ADB));
-                _run("%s wait-for-device" % (ItsSession.ADB))
+                _run("%s reboot" % (self.adb));
+                _run("%s wait-for-device" % (self.adb))
                 time.sleep(duration)
                 print "Reboot complete"
 
         # TODO: Figure out why "--user 0" is needed, and fix the problem.
-        _run('%s shell am force-stop --user 0 %s' % (ItsSession.ADB, self.PACKAGE))
+        _run('%s shell am force-stop --user 0 %s' % (self.adb, self.PACKAGE))
         _run(('%s shell am startservice --user 0 -t text/plain '
-              '-a %s') % (ItsSession.ADB, self.INTENT_START))
+              '-a %s') % (self.adb, self.INTENT_START))
 
         # Wait until the socket is ready to accept a connection.
         proc = subprocess.Popen(
-                ItsSession.ADB.split() + ["logcat"],
+                self.adb.split() + ["logcat"],
                 stdout=subprocess.PIPE)
         logcat = proc.stdout
         while True:
@@ -111,15 +191,14 @@
                 break
         proc.kill()
 
-        # Setup the TCP-over-ADB forwarding.
-        _run('%s forward tcp:%d tcp:%d' % (ItsSession.ADB,self.PORT,self.PORT))
-
     def __init__(self):
-        if "noinit" not in sys.argv:
-            self.__pre_init()
-        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.sock.connect((self.IPADDR, self.PORT))
-        self.sock.settimeout(self.SOCK_TIMEOUT)
+        # Initialize device id and adb command.
+        self.device_id = get_device_id()
+        self.adb = "adb -s " + self.device_id
+
+        self.__wait_for_service()
+        self.__init_socket_port()
+
         self.__close_camera()
         self.__open_camera()
 
@@ -360,7 +439,7 @@
             raise its.error.Error('3A failed to converge')
         return ae_sens, ae_exp, awb_gains, awb_transform, af_dist
 
-    def do_capture(self, cap_request, out_surfaces=None):
+    def do_capture(self, cap_request, out_surfaces=None, reprocess_format=None):
         """Issue capture request(s), and read back the image(s) and metadata.
 
         The main top-level function for capturing one or more images using the
@@ -369,8 +448,8 @@
 
         The out_surfaces field can specify the width(s), height(s), and
         format(s) of the captured image. The formats may be "yuv", "jpeg",
-        "dng", "raw", or "raw10". The default is a YUV420 frame ("yuv")
-        corresponding to a full sensor frame.
+        "dng", "raw", "raw10", "raw12", or "rawStats". The default is a YUV420
+        frame ("yuv") corresponding to a full sensor frame.
 
         Note that one or more surfaces can be specified, allowing a capture to
         request images back in multiple formats (e.g.) raw+yuv, raw+jpeg,
@@ -379,6 +458,18 @@
         surface. At most one output surface can be specified for a given format,
         and raw+dng, raw10+dng, and raw+raw10 are not supported as combinations.
 
+        If reprocess_format is not None, for each request, an intermediate
+        buffer of the given reprocess_format will be captured from camera and
+        the intermediate buffer will be reprocessed to the output surfaces. The
+        following settings will be turned off when capturing the intermediate
+        buffer and will be applied when reprocessing the intermediate buffer.
+            1. android.noiseReduction.mode
+            2. android.edge.mode
+            3. android.reprocess.effectiveExposureFactor
+
+        Supported reprocess format are "yuv" and "private". Supported output
+        surface formats when reprocessing is enabled are "yuv" and "jpeg".
+
         Example of a single capture request:
 
             {
@@ -445,11 +536,32 @@
             yuv_caps           = do_capture( [req1,req2], yuv_fmt           )
             yuv_caps, raw_caps = do_capture( [req1,req2], [yuv_fmt,raw_fmt] )
 
+        The "rawStats" format processes the raw image and returns a new image
+        of statistics from the raw image. The format takes additional keys,
+        "gridWidth" and "gridHeight" which are size of grid cells in a 2D grid
+        of the raw image. For each grid cell, the mean and variance of each raw
+        channel is computed, and the do_capture call returns two 4-element float
+        images of dimensions (rawWidth / gridWidth, rawHeight / gridHeight),
+        concatenated back-to-back, where the first iamge contains the 4-channel
+        means and the second contains the 4-channel variances.
+
+        For the rawStats format, if the gridWidth is not provided then the raw
+        image width is used as the default, and similarly for gridHeight. With
+        this, the following is an example of a output description that computes
+        the mean and variance across each image row:
+
+            {
+                "gridHeight": 1,
+                "format": "rawStats"
+            }
+
         Args:
             cap_request: The Python dict/list specifying the capture(s), which
                 will be converted to JSON and sent to the device.
             out_surfaces: (Optional) specifications of the output image formats
                 and sizes to use for each capture.
+            reprocess_format: (Optional) The reprocessing format. If not None,
+                reprocessing will be enabled.
 
         Returns:
             An object, list of objects, or list of lists of objects, where each
@@ -457,11 +569,16 @@
             * data: the image data as a numpy array of bytes.
             * width: the width of the captured image.
             * height: the height of the captured image.
-            * format: image the format, in ["yuv","jpeg","raw","raw10","dng"].
+            * format: image the format, in [
+                        "yuv","jpeg","raw","raw10","raw12","rawStats","dng"].
             * metadata: the capture result object (Python dictionary).
         """
         cmd = {}
-        cmd["cmdName"] = "doCapture"
+        if reprocess_format != None:
+            cmd["cmdName"] = "doReprocessCapture"
+            cmd["reprocessFormat"] = reprocess_format
+        else:
+            cmd["cmdName"] = "doCapture"
         if not isinstance(cap_request, list):
             cmd["captureRequests"] = [cap_request]
         else:
@@ -480,9 +597,13 @@
         nsurf = 1 if out_surfaces is None else len(cmd["outputSurfaces"])
         if len(formats) > len(set(formats)):
             raise its.error.Error('Duplicate format requested')
-        if "dng" in formats and "raw" in formats or \
-                "dng" in formats and "raw10" in formats or \
-                "raw" in formats and "raw10" in formats:
+        raw_formats = 0;
+        raw_formats += 1 if "dng" in formats else 0
+        raw_formats += 1 if "raw" in formats else 0
+        raw_formats += 1 if "raw10" in formats else 0
+        raw_formats += 1 if "raw12" in formats else 0
+        raw_formats += 1 if "rawStats" in formats else 0
+        if raw_formats > 1:
             raise its.error.Error('Different raw formats not supported')
 
         # Detect long exposure time and set timeout accordingly
@@ -506,14 +627,16 @@
         # the burst, however individual images of different formats can come
         # out in any order for that capture.
         nbufs = 0
-        bufs = {"yuv":[], "raw":[], "raw10":[], "dng":[], "jpeg":[]}
+        bufs = {"yuv":[], "raw":[], "raw10":[], "raw12":[],
+                "rawStats":[], "dng":[], "jpeg":[]}
         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', \
-                    'raw10Image', 'dngImage'] and buf is not None:
+                    'raw10Image', 'raw12Image', 'rawStatsImage', 'dngImage'] \
+                    and buf is not None:
                 fmt = jsonObj['tag'][:-5]
                 bufs[fmt].append(buf)
                 nbufs += 1
@@ -540,10 +663,52 @@
         self.sock.settimeout(self.SOCK_TIMEOUT)
         return rets if len(rets)>1 else rets[0]
 
-def report_result(camera_id, success, summary_path=None):
+def get_device_id():
+    """ Return the ID of the device that the test is running on.
+
+    Return the device ID provided in the command line if it's connected. If no
+    device ID is provided in the command line and there is only one device
+    connected, return the device ID by parsing the result of "adb devices".
+
+    Raise an exception if no device is connected; or the device ID provided in
+    the command line is not connected; or no device ID is provided in the
+    command line and there are more than 1 device connected.
+
+    Returns:
+        Device ID string.
+    """
+    device_id = None
+    for s in sys.argv[1:]:
+        if s[:7] == "device=" and len(s) > 7:
+            device_id = str(s[7:])
+
+    # Get a list of connected devices
+    devices = []
+    command = "adb devices"
+    proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
+    output, error = proc.communicate()
+    for line in output.split(os.linesep):
+        device_info = line.split()
+        if len(device_info) == 2 and device_info[1] == "device":
+            devices.append(device_info[0])
+
+    if len(devices) == 0:
+        raise its.error.Error("No device is connected!")
+    elif device_id is not None and device_id not in devices:
+        raise its.error.Error(device_id + " is not connected!")
+    elif device_id is None and len(devices) >= 2:
+        raise its.error.Error("More than 1 device are connected. " +
+                "Use device=<device_id> to specify a device to test.")
+    elif len(devices) == 1:
+        device_id = devices[0]
+
+    return device_id
+
+def report_result(device_id, camera_id, success, summary_path=None):
     """Send a pass/fail result to the device, via an intent.
 
     Args:
+        device_id: The ID string of the device to report the results to.
         camera_id: The ID string of the camera for which to report pass/fail.
         success: Boolean, indicating if the result was pass or fail.
         summary_path: (Optional) path to ITS summary file on host PC
@@ -551,18 +716,19 @@
     Returns:
         Nothing.
     """
+    adb = "adb -s " + device_id
     device_summary_path = "/sdcard/camera_" + camera_id + "_its_summary.txt"
     if summary_path is not None:
         _run("%s push %s %s" % (
-                ItsSession.ADB, summary_path, device_summary_path))
+                adb, summary_path, device_summary_path))
         _run("%s shell am broadcast -a %s --es %s %s --es %s %s --es %s %s" % (
-                ItsSession.ADB, ItsSession.ACTION_ITS_RESULT,
+                adb, ItsSession.ACTION_ITS_RESULT,
                 ItsSession.EXTRA_CAMERA_ID, camera_id,
                 ItsSession.EXTRA_SUCCESS, 'True' if success else 'False',
                 ItsSession.EXTRA_SUMMARY, device_summary_path))
     else:
         _run("%s shell am broadcast -a %s --es %s %s --es %s %s --es %s %s" % (
-                ItsSession.ADB, ItsSession.ACTION_ITS_RESULT,
+                adb, ItsSession.ACTION_ITS_RESULT,
                 ItsSession.EXTRA_CAMERA_ID, camera_id,
                 ItsSession.EXTRA_SUCCESS, 'True' if success else 'False',
                 ItsSession.EXTRA_SUMMARY, "null"))
diff --git a/apps/CameraITS/pymodules/its/image.py b/apps/CameraITS/pymodules/its/image.py
index b3bdb65..a5ac60b 100644
--- a/apps/CameraITS/pymodules/its/image.py
+++ b/apps/CameraITS/pymodules/its/image.py
@@ -64,11 +64,14 @@
     if cap["format"] == "raw10":
         assert(props is not None)
         cap = unpack_raw10_capture(cap, props)
+    if cap["format"] == "raw12":
+        assert(props is not None)
+        cap = unpack_raw12_capture(cap, props)
     if cap["format"] == "yuv":
         y = cap["data"][0:w*h]
         u = cap["data"][w*h:w*h*5/4]
         v = cap["data"][w*h*5/4:w*h*6/4]
-        return convert_yuv420_to_rgb_image(y, u, v, w, h)
+        return convert_yuv420_planar_to_rgb_image(y, u, v, w, h)
     elif cap["format"] == "jpeg":
         return decompress_jpeg_to_rgb_image(cap["data"])
     elif cap["format"] == "raw":
@@ -78,6 +81,25 @@
     else:
         raise its.error.Error('Invalid format %s' % (cap["format"]))
 
+def unpack_rawstats_capture(cap):
+    """Unpack a rawStats capture to the mean and variance images.
+
+    Args:
+        cap: A capture object as returned by its.device.do_capture.
+
+    Returns:
+        Tuple (mean_image var_image) of float-4 images, with non-normalized
+        pixel values computed from the RAW16 images on the device
+    """
+    assert(cap["format"] == "rawStats")
+    w = cap["width"]
+    h = cap["height"]
+    img = numpy.ndarray(shape=(2*h*w*4,), dtype='<f', buffer=cap["data"])
+    analysis_image = img.reshape(2,h,w,4)
+    mean_image = analysis_image[0,:,:,:].reshape(h,w,4)
+    var_image = analysis_image[1,:,:,:].reshape(h,w,4)
+    return mean_image, var_image
+
 def unpack_raw10_capture(cap, props):
     """Unpack a raw-10 capture to a raw-16 capture.
 
@@ -114,12 +136,12 @@
         raise its.error.Error('Invalid raw-10 buffer width')
     w = img.shape[1]*4/5
     h = img.shape[0]
-    # Cut out the 4x8b MSBs and shift to bits [10:2] in 16b words.
+    # Cut out the 4x8b MSBs and shift to bits [9:2] in 16b words.
     msbs = numpy.delete(img, numpy.s_[4::5], 1)
     msbs = msbs.astype(numpy.uint16)
     msbs = numpy.left_shift(msbs, 2)
     msbs = msbs.reshape(h,w)
-    # Cut out the 4x2b LSBs and put each in bits [2:0] of their own 8b words.
+    # Cut out the 4x2b LSBs and put each in bits [1:0] of their own 8b words.
     lsbs = img[::, 4::5].reshape(h,w/4)
     lsbs = numpy.right_shift(
             numpy.packbits(numpy.unpackbits(lsbs).reshape(h,w/4,4,2),3), 6)
@@ -128,6 +150,56 @@
     img16 = numpy.bitwise_or(msbs, lsbs).reshape(h,w)
     return img16
 
+def unpack_raw12_capture(cap, props):
+    """Unpack a raw-12 capture to a raw-16 capture.
+
+    Args:
+        cap: A raw-12 capture object.
+        props: Camera properties object.
+
+    Returns:
+        New capture object with raw-16 data.
+    """
+    # Data is packed as 4x10b pixels in 5 bytes, with the first 4 bytes holding
+    # the MSBs of the pixels, and the 5th byte holding 4x2b LSBs.
+    w,h = cap["width"], cap["height"]
+    if w % 2 != 0:
+        raise its.error.Error('Invalid raw-12 buffer width')
+    cap = copy.deepcopy(cap)
+    cap["data"] = unpack_raw12_image(cap["data"].reshape(h,w*3/2))
+    cap["format"] = "raw"
+    return cap
+
+def unpack_raw12_image(img):
+    """Unpack a raw-12 image to a raw-16 image.
+
+    Output image will have the 12 LSBs filled in each 16b word, and the 4 MSBs
+    will be set to zero.
+
+    Args:
+        img: A raw-12 image, as a uint8 numpy array.
+
+    Returns:
+        Image as a uint16 numpy array, with all row padding stripped.
+    """
+    if img.shape[1] % 3 != 0:
+        raise its.error.Error('Invalid raw-12 buffer width')
+    w = img.shape[1]*2/3
+    h = img.shape[0]
+    # Cut out the 2x8b MSBs and shift to bits [11:4] in 16b words.
+    msbs = numpy.delete(img, numpy.s_[2::3], 1)
+    msbs = msbs.astype(numpy.uint16)
+    msbs = numpy.left_shift(msbs, 4)
+    msbs = msbs.reshape(h,w)
+    # Cut out the 2x4b LSBs and put each in bits [3:0] of their own 8b words.
+    lsbs = img[::, 2::3].reshape(h,w/2)
+    lsbs = numpy.right_shift(
+            numpy.packbits(numpy.unpackbits(lsbs).reshape(h,w/2,2,4),3), 4)
+    lsbs = lsbs.reshape(h,w)
+    # Fuse the MSBs and LSBs back together
+    img16 = numpy.bitwise_or(msbs, lsbs).reshape(h,w)
+    return img16
+
 def convert_capture_to_planes(cap, props=None):
     """Convert a captured image object to separate image planes.
 
@@ -158,6 +230,9 @@
     if cap["format"] == "raw10":
         assert(props is not None)
         cap = unpack_raw10_capture(cap, props)
+    if cap["format"] == "raw12":
+        assert(props is not None)
+        cap = unpack_raw12_capture(cap, props)
     if cap["format"] == "yuv":
         y = cap["data"][0:w*h]
         u = cap["data"][w*h:w*h*5/4]
@@ -176,6 +251,36 @@
         img = numpy.ndarray(shape=(h*w,), dtype='<u2',
                             buffer=cap["data"][0:w*h*2])
         img = img.astype(numpy.float32).reshape(h,w) / white_level
+        # Crop the raw image to the active array region.
+        if props.has_key("android.sensor.info.activeArraySize") \
+                and props["android.sensor.info.activeArraySize"] is not None \
+                and props.has_key("android.sensor.info.pixelArraySize") \
+                and props["android.sensor.info.pixelArraySize"] is not None:
+            # Note that the Rect class is defined such that the left,top values
+            # are "inside" while the right,bottom values are "outside"; that is,
+            # it's inclusive of the top,left sides only. So, the width is
+            # computed as right-left, rather than right-left+1, etc.
+            wfull = props["android.sensor.info.pixelArraySize"]["width"]
+            hfull = props["android.sensor.info.pixelArraySize"]["height"]
+            xcrop = props["android.sensor.info.activeArraySize"]["left"]
+            ycrop = props["android.sensor.info.activeArraySize"]["top"]
+            wcrop = props["android.sensor.info.activeArraySize"]["right"]-xcrop
+            hcrop = props["android.sensor.info.activeArraySize"]["bottom"]-ycrop
+            assert(wfull >= wcrop >= 0)
+            assert(hfull >= hcrop >= 0)
+            assert(wfull - wcrop >= xcrop >= 0)
+            assert(hfull - hcrop >= ycrop >= 0)
+            if w == wfull and h == hfull:
+                # Crop needed; extract the center region.
+                img = img[ycrop:ycrop+hcrop,xcrop:xcrop+wcrop]
+                w = wcrop
+                h = hcrop
+            elif w == wcrop and h == hcrop:
+                # No crop needed; image is already cropped to the active array.
+                None
+            else:
+                raise its.error.Error('Invalid image size metadata')
+        # Separate the image planes.
         imgs = [img[::2].reshape(w*h/2)[::2].reshape(h/2,w/2,1),
                 img[::2].reshape(w*h/2)[1::2].reshape(h/2,w/2,1),
                 img[1::2].reshape(w*h/2)[::2].reshape(h/2,w/2,1),
@@ -285,10 +390,10 @@
     img = numpy.dot(img.reshape(w*h,3), ccm.T).reshape(h,w,3).clip(0.0,1.0)
     return img
 
-def convert_yuv420_to_rgb_image(y_plane, u_plane, v_plane,
-                                w, h,
-                                ccm_yuv_to_rgb=DEFAULT_YUV_TO_RGB_CCM,
-                                yuv_off=DEFAULT_YUV_OFFSETS):
+def convert_yuv420_planar_to_rgb_image(y_plane, u_plane, v_plane,
+                                       w, h,
+                                       ccm_yuv_to_rgb=DEFAULT_YUV_TO_RGB_CCM,
+                                       yuv_off=DEFAULT_YUV_OFFSETS):
     """Convert a YUV420 8-bit planar image to an RGB image.
 
     Args:
@@ -316,16 +421,44 @@
     rgb.reshape(w*h*3)[:] = flt.reshape(w*h*3)[:]
     return rgb.astype(numpy.float32) / 255.0
 
+def load_rgb_image(fname):
+    """Load a standard image file (JPG, PNG, etc.).
+
+    Args:
+        fname: The path of the file to load.
+
+    Returns:
+        RGB float-3 image array, with pixel values in [0.0, 1.0].
+    """
+    img = Image.open(fname)
+    w = img.size[0]
+    h = img.size[1]
+    a = numpy.array(img)
+    if len(a.shape) == 3 and a.shape[2] == 3:
+        # RGB
+        return a.reshape(h,w,3) / 255.0
+    elif len(a.shape) == 2 or len(a.shape) == 3 and a.shape[2] == 1:
+        # Greyscale; convert to RGB
+        return a.reshape(h*w).repeat(3).reshape(h,w,3) / 255.0
+    else:
+        raise its.error.Error('Unsupported image type')
+
 def load_yuv420_to_rgb_image(yuv_fname,
                              w, h,
+                             layout="planar",
                              ccm_yuv_to_rgb=DEFAULT_YUV_TO_RGB_CCM,
                              yuv_off=DEFAULT_YUV_OFFSETS):
     """Load a YUV420 image file, and return as an RGB image.
 
+    Supported layouts include "planar" and "nv21". The "yuv" formatted captures
+    returned from the device via do_capture are in the "planar" layout; other
+    layouts may only be needed for loading files from other sources.
+
     Args:
         yuv_fname: The path of the YUV420 file.
         w: The width of the image.
         h: The height of the image.
+        layout: (Optional) the layout of the YUV data (as a string).
         ccm_yuv_to_rgb: (Optional) the 3x3 CCM to convert from YUV to RGB.
         yuv_off: (Optional) offsets to subtract from each of Y,U,V values.
 
@@ -333,13 +466,24 @@
         RGB float-3 image array, with pixel values in [0.0, 1.0].
     """
     with open(yuv_fname, "rb") as f:
-        y = numpy.fromfile(f, numpy.uint8, w*h, "")
-        v = numpy.fromfile(f, numpy.uint8, w*h/4, "")
-        u = numpy.fromfile(f, numpy.uint8, w*h/4, "")
-        return convert_yuv420_to_rgb_image(y,u,v,w,h,ccm_yuv_to_rgb,yuv_off)
+        if layout == "planar":
+            # Plane of Y, plane of V, plane of U.
+            y = numpy.fromfile(f, numpy.uint8, w*h, "")
+            v = numpy.fromfile(f, numpy.uint8, w*h/4, "")
+            u = numpy.fromfile(f, numpy.uint8, w*h/4, "")
+        elif layout == "nv21":
+            # Plane of Y, plane of interleaved VUVUVU...
+            y = numpy.fromfile(f, numpy.uint8, w*h, "")
+            vu = numpy.fromfile(f, numpy.uint8, w*h/2, "")
+            v = vu[0::2]
+            u = vu[1::2]
+        else:
+            raise its.error.Error('Unsupported image layout')
+        return convert_yuv420_planar_to_rgb_image(
+                y,u,v,w,h,ccm_yuv_to_rgb,yuv_off)
 
-def load_yuv420_to_yuv_planes(yuv_fname, w, h):
-    """Load a YUV420 image file, and return separate Y, U, and V plane images.
+def load_yuv420_planar_to_yuv_planes(yuv_fname, w, h):
+    """Load a YUV420 planar image file, and return Y, U, and V plane images.
 
     Args:
         yuv_fname: The path of the YUV420 file.
@@ -479,6 +623,21 @@
         variances.append(numpy.var(img[:,:,i], dtype=numpy.float64))
     return variances
 
+def compute_image_snrs(img):
+    """Calculate the SNR (db) of each color channel in the image.
+
+    Args:
+        img: Numpy float image array, with pixel values in [0,1].
+
+    Returns:
+        A list of SNR value, one per color channel in the image.
+    """
+    means = compute_image_means(img)
+    variances = compute_image_variances(img)
+    std_devs = [math.sqrt(v) for v in variances]
+    snr = [20 * math.log10(m/s) for m,s in zip(means, std_devs)]
+    return snr
+
 def write_image(img, fname, apply_gamma=False):
     """Save a float-3 numpy array image to a file.
 
@@ -540,169 +699,24 @@
     img = numpy.vstack(chs).T.reshape(h/f,w/f,chans)
     return img
 
-def __get_color_checker_patch(img, xc,yc, patch_size):
-    r = patch_size/2
-    tile = img[yc-r:yc+r:, xc-r:xc+r:, ::]
-    return tile
-
-def __measure_color_checker_patch(img, xc,yc, patch_size):
-    tile = __get_color_checker_patch(img, xc,yc, patch_size)
-    means = tile.mean(1).mean(0)
-    return means
-
-def get_color_checker_chart_patches(img, debug_fname_prefix=None):
-    """Return the center coords of each patch in a color checker chart.
-
-    Assumptions:
-    * Chart is vertical or horizontal w.r.t. camera, but not diagonal.
-    * Chart is (roughly) planar-parallel to the camera.
-    * Chart is centered in frame (roughly).
-    * Around/behind chart is white/grey background.
-    * The only black pixels in the image are from the chart.
-    * Chart is 100% visible and contained within image.
-    * No other objects within image.
-    * Image is well-exposed.
-    * Standard color checker chart with standard-sized black borders.
-
-    The values returned are in the coordinate system of the chart; that is,
-    patch (0,0) is the brown patch that is in the chart's top-left corner when
-    it is in the normal upright/horizontal orientation. (The chart may be any
-    of the four main orientations in the image.)
+def compute_image_sharpness(img):
+    """Calculate the sharpness of input image.
 
     Args:
-        img: Input image, as a numpy array with pixels in [0,1].
-        debug_fname_prefix: If not None, the (string) name of a file prefix to
-            use to save a number of debug images for visualizing the output of
-            this function; can be used to see if the patches are being found
-            successfully.
+        img: Numpy float RGB/luma image array, with pixel values in [0,1].
 
     Returns:
-        6x4 list of lists of integer (x,y) coords of the center of each patch,
-        ordered in the "chart order" (6x4 row major).
+        A sharpness estimation value based on the average of gradient magnitude.
+        Larger value means the image is sharper.
     """
+    chans = img.shape[2]
+    assert(chans == 1 or chans == 3)
+    luma = img
+    if (chans == 3):
+        luma = 0.299 * img[:,:,0] + 0.587 * img[:,:,1] + 0.114 * img[:,:,2]
 
-    # Shrink the original image.
-    DOWNSCALE_FACTOR = 4
-    img_small = downscale_image(img, DOWNSCALE_FACTOR)
-
-    # Make a threshold image, which is 1.0 where the image is black,
-    # and 0.0 elsewhere.
-    BLACK_PIXEL_THRESH = 0.2
-    mask_img = scipy.stats.threshold(
-                img_small.max(2), BLACK_PIXEL_THRESH, 1.1, 0.0)
-    mask_img = 1.0 - scipy.stats.threshold(mask_img, -0.1, 0.1, 1.0)
-
-    if debug_fname_prefix is not None:
-        h,w = mask_img.shape
-        write_image(img, debug_fname_prefix+"_0.jpg")
-        write_image(mask_img.repeat(3).reshape(h,w,3),
-                debug_fname_prefix+"_1.jpg")
-
-    # Mask image flattened to a single row or column (by averaging).
-    # Also apply a threshold to these arrays.
-    FLAT_PIXEL_THRESH = 0.05
-    flat_row = mask_img.mean(0)
-    flat_col = mask_img.mean(1)
-    flat_row = [0 if v < FLAT_PIXEL_THRESH else 1 for v in flat_row]
-    flat_col = [0 if v < FLAT_PIXEL_THRESH else 1 for v in flat_col]
-
-    # Start and end of the non-zero region of the flattened row/column.
-    flat_row_nonzero = [i for i in range(len(flat_row)) if flat_row[i]>0]
-    flat_col_nonzero = [i for i in range(len(flat_col)) if flat_col[i]>0]
-    flat_row_min, flat_row_max = min(flat_row_nonzero), max(flat_row_nonzero)
-    flat_col_min, flat_col_max = min(flat_col_nonzero), max(flat_col_nonzero)
-
-    # Orientation of chart, and number of grid cells horz. and vertically.
-    orient = "h" if flat_row_max-flat_row_min>flat_col_max-flat_col_min else "v"
-    xgrids = 6 if orient=="h" else 4
-    ygrids = 6 if orient=="v" else 4
-
-    # Get better bounds on the patches region, lopping off some of the excess
-    # black border.
-    HRZ_BORDER_PAD_FRAC = 0.0138
-    VERT_BORDER_PAD_FRAC = 0.0395
-    xpad = HRZ_BORDER_PAD_FRAC if orient=="h" else VERT_BORDER_PAD_FRAC
-    ypad = HRZ_BORDER_PAD_FRAC if orient=="v" else VERT_BORDER_PAD_FRAC
-    xchart = flat_row_min + (flat_row_max - flat_row_min) * xpad
-    ychart = flat_col_min + (flat_col_max - flat_col_min) * ypad
-    wchart = (flat_row_max - flat_row_min) * (1 - 2*xpad)
-    hchart = (flat_col_max - flat_col_min) * (1 - 2*ypad)
-
-    # Get the colors of the 4 corner patches, in clockwise order, by measuring
-    # the average value of a small patch at each of the 4 patch centers.
-    colors = []
-    centers = []
-    for (x,y) in [(0,0), (xgrids-1,0), (xgrids-1,ygrids-1), (0,ygrids-1)]:
-        xc = xchart + (x + 0.5)*wchart/xgrids
-        yc = ychart + (y + 0.5)*hchart/ygrids
-        xc = int(xc * DOWNSCALE_FACTOR + 0.5)
-        yc = int(yc * DOWNSCALE_FACTOR + 0.5)
-        centers.append((xc,yc))
-        chan_means = __measure_color_checker_patch(img, xc,yc, 32)
-        colors.append(sum(chan_means) / len(chan_means))
-
-    # The brightest corner is the white patch, the darkest is the black patch.
-    # The black patch should be counter-clockwise from the white patch.
-    white_patch_index = None
-    for i in range(4):
-        if colors[i] == max(colors) and \
-                colors[(i-1+4)%4] == min(colors):
-            white_patch_index = i%4
-    assert(white_patch_index is not None)
-
-    # Return the coords of the origin (top-left when the chart is in the normal
-    # upright orientation) patch's center, and the vector displacement to the
-    # center of the second patch on the first row of the chart (when in the
-    # normal upright orientation).
-    origin_index = (white_patch_index+1)%4
-    prev_index = (origin_index-1+4)%4
-    next_index = (origin_index+1)%4
-    origin_center = centers[origin_index]
-    prev_center = centers[prev_index]
-    next_center = centers[next_index]
-    vec_across = tuple([(next_center[i]-origin_center[i])/5.0 for i in [0,1]])
-    vec_down = tuple([(prev_center[i]-origin_center[i])/3.0 for i in [0,1]])
-
-    # Compute the center of each patch.
-    patches = [[],[],[],[]]
-    for yi in range(4):
-        for xi in range(6):
-            x0,y0 = origin_center
-            dxh,dyh = vec_across
-            dxv,dyv = vec_down
-            xc = int(x0 + dxh*xi + dxv*yi)
-            yc = int(y0 + dyh*xi + dyv*yi)
-            patches[yi].append((xc,yc))
-
-    # Sanity check: test that the R,G,B,black,white patches are correct.
-    sanity_failed = False
-    patch_info = [(2,2,[0]), # Red
-                  (2,1,[1]), # Green
-                  (2,0,[2]), # Blue
-                  (3,0,[0,1,2]), # White
-                  (3,5,[])] # Black
-    for i in range(len(patch_info)):
-        yi,xi,high_chans = patch_info[i]
-        low_chans = [i for i in [0,1,2] if i not in high_chans]
-        xc,yc = patches[yi][xi]
-        means = __measure_color_checker_patch(img, xc,yc, 64)
-        if (min([means[i] for i in high_chans]+[1]) < \
-                max([means[i] for i in low_chans]+[0])):
-            sanity_failed = True
-
-    if debug_fname_prefix is not None:
-        gridimg = numpy.zeros([4*(32+2), 6*(32+2), 3])
-        for yi in range(4):
-            for xi in range(6):
-                xc,yc = patches[yi][xi]
-                tile = __get_color_checker_patch(img, xc,yc, 32)
-                gridimg[yi*(32+2)+1:yi*(32+2)+1+32,
-                        xi*(32+2)+1:xi*(32+2)+1+32, :] = tile
-        write_image(gridimg, debug_fname_prefix+"_2.png")
-
-    assert(not sanity_failed)
-
-    return patches
+    [gy, gx] = numpy.gradient(luma)
+    return numpy.average(numpy.sqrt(gy*gy + gx*gx))
 
 class __UnitTest(unittest.TestCase):
     """Run a suite of unit tests on this module.
diff --git a/apps/CameraITS/pymodules/its/objects.py b/apps/CameraITS/pymodules/its/objects.py
index 5967599..ac384fb 100644
--- a/apps/CameraITS/pymodules/its/objects.py
+++ b/apps/CameraITS/pymodules/its/objects.py
@@ -70,7 +70,8 @@
     else:
         return float(r["numerator"]) / float(r["denominator"])
 
-def manual_capture_request(sensitivity, exp_time, linear_tonemap=False):
+def manual_capture_request(
+        sensitivity, exp_time, linear_tonemap=False, props=None):
     """Return a capture request with everything set to manual.
 
     Uses identity/unit color correction, and the default tonemap curve.
@@ -82,6 +83,9 @@
             with.
         linear_tonemap: [Optional] whether a linear tonemap should be used
             in this request.
+        props: [Optional] the object returned from
+            its.device.get_camera_properties(). Must present when
+            linear_tonemap is True.
 
     Returns:
         The default manual capture request, ready to be passed to the
@@ -105,10 +109,20 @@
         "android.shading.mode": 1
         }
     if linear_tonemap:
-        req["android.tonemap.mode"] = 0
-        req["android.tonemap.curveRed"] = [0.0,0.0, 1.0,1.0]
-        req["android.tonemap.curveGreen"] = [0.0,0.0, 1.0,1.0]
-        req["android.tonemap.curveBlue"] = [0.0,0.0, 1.0,1.0]
+        assert(props is not None)
+        #CONTRAST_CURVE mode
+        if 0 in props["android.tonemap.availableToneMapModes"]:
+            req["android.tonemap.mode"] = 0
+            req["android.tonemap.curveRed"] = [0.0,0.0, 1.0,1.0]
+            req["android.tonemap.curveGreen"] = [0.0,0.0, 1.0,1.0]
+            req["android.tonemap.curveBlue"] = [0.0,0.0, 1.0,1.0]
+        #GAMMA_VALUE mode
+        elif 3 in props["android.tonemap.availableToneMapModes"]:
+            req["android.tonemap.mode"] = 3
+            req["android.tonemap.gamma"] = 1.0
+        else:
+            print "Linear tonemap is not supported"
+            assert(False)
     return req
 
 def auto_capture_request():
@@ -142,7 +156,8 @@
     """Return a sorted list of available output sizes for a given format.
 
     Args:
-        fmt: the output format, as a string in ["jpg", "yuv", "raw"].
+        fmt: the output format, as a string in
+            ["jpg", "yuv", "raw", "raw10", "raw12"].
         props: the object returned from its.device.get_camera_properties().
         max_size: (Optional) A (w,h) tuple.
             Sizes larger than max_size (either w or h)  will be discarded.
@@ -154,7 +169,8 @@
         A sorted list of (w,h) tuples (sorted large-to-small).
     """
     AR_TOLERANCE = 0.03
-    fmt_codes = {"raw":0x20, "raw10":0x25, "yuv":0x23, "jpg":0x100, "jpeg":0x100}
+    fmt_codes = {"raw":0x20, "raw10":0x25, "raw12":0x26,"yuv":0x23,
+                 "jpg":0x100, "jpeg":0x100}
     configs = props['android.scaler.streamConfigurationMap']\
                    ['availableStreamConfigurations']
     fmt_configs = [cfg for cfg in configs if cfg['format'] == fmt_codes[fmt]]
diff --git a/apps/CameraITS/tests/dng_noise_model/DngNoiseModel.pdf b/apps/CameraITS/tests/dng_noise_model/DngNoiseModel.pdf
index 01389fa..d979a06 100644
--- a/apps/CameraITS/tests/dng_noise_model/DngNoiseModel.pdf
+++ b/apps/CameraITS/tests/dng_noise_model/DngNoiseModel.pdf
Binary files differ
diff --git a/apps/CameraITS/tests/dng_noise_model/dng_noise_model.py b/apps/CameraITS/tests/dng_noise_model/dng_noise_model.py
index 19b6c92..8f4682a 100644
--- a/apps/CameraITS/tests/dng_noise_model/dng_noise_model.py
+++ b/apps/CameraITS/tests/dng_noise_model/dng_noise_model.py
@@ -13,144 +13,249 @@
 # limitations under the License.
 
 import its.device
+import its.caps
 import its.objects
 import its.image
-import pprint
-import pylab
 import os.path
+import pylab
 import matplotlib
-import matplotlib.pyplot
-import numpy
+import matplotlib.pyplot as plt
 import math
+import Image
+import time
+import numpy as np
+import scipy.stats
+import scipy.signal
+
+# Convert a 2D array a to a 4D array with dimensions [tile_size,
+# tile_size, row, col] where row, col are tile indices.
+def tile(a, tile_size):
+    tile_rows, tile_cols = a.shape[0]/tile_size, a.shape[1]/tile_size
+    a = a.reshape([tile_rows, tile_size, tile_cols, tile_size])
+    a = a.transpose([1, 3, 0, 2])
+    return a
 
 def main():
-    """Compute the DNG noise model from a color checker chart.
-
-    TODO: Make this more robust; some manual futzing may be needed.
+    """Capture a set of raw images with increasing gains and measure the noise.
     """
     NAME = os.path.basename(__file__).split(".")[0]
 
-    with its.device.ItsSession() as cam:
+    # How many sensitivities per stop to sample.
+    steps_per_stop = 2
+    # How large of tiles to use to compute mean/variance.
+    tile_size = 64
+    # Exposure bracketing range in stops
+    bracket_stops = 4
+    # How high to allow the mean of the tiles to go.
+    max_signal_level = 0.5
+    # Colors used for plotting the data for each exposure.
+    colors = 'rygcbm'
 
+    # Define a first order high pass filter to eliminate low frequency
+    # signal content when computing variance.
+    f = np.array([-1, 1]).astype('float32')
+    # Make it a higher order filter by convolving the first order
+    # filter with itself a few times.
+    f = np.convolve(f, f)
+    f = np.convolve(f, f)
+
+    # Compute the normalization of the filter to preserve noise
+    # power. Let a be the normalization factor we're looking for, and
+    # Let X and X' be the random variables representing the noise
+    # before and after filtering, respectively. First, compute
+    # Var[a*X']:
+    #
+    #   Var[a*X'] = a^2*Var[X*f_0 + X*f_1 + ... + X*f_N-1]
+    #             = a^2*(f_0^2*Var[X] + f_1^2*Var[X] + ... + (f_N-1)^2*Var[X])
+    #             = sum(f_i^2)*a^2*Var[X]
+    #
+    # We want Var[a*X'] to be equal to Var[X]:
+    #
+    #    sum(f_i^2)*a^2*Var[X] = Var[X] -> a = sqrt(1/sum(f_i^2))
+    #
+    # We can just bake this normalization factor into the high pass
+    # filter kernel.
+    f = f/math.sqrt(np.dot(f, f))
+
+    bracket_factor = math.pow(2, bracket_stops)
+
+    with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
 
-        white_level = float(props['android.sensor.info.whiteLevel'])
+        # Get basic properties we need.
+        sens_min, sens_max = props['android.sensor.info.sensitivityRange']
+        sens_max_analog = props['android.sensor.maxAnalogSensitivity']
+        white_level = props['android.sensor.info.whiteLevel']
         black_levels = props['android.sensor.blackLevelPattern']
         idxs = its.image.get_canonical_cfa_order(props)
         black_levels = [black_levels[i] for i in idxs]
 
-        # Expose for the scene with min sensitivity
-        sens_min, sens_max = props['android.sensor.info.sensitivityRange']
-        s_ae,e_ae,awb_gains,awb_ccm,_  = cam.do_3a(get_results=True)
-        s_e_prod = s_ae * e_ae
+        print "Sensitivity range: [%f, %f]" % (sens_min, sens_max)
+        print "Max analog sensitivity: %f" % (sens_max_analog)
 
-        # Make the image brighter since the script looks at linear Bayer
-        # raw patches rather than gamma-encoded YUV patches (and the AE
-        # probably under-exposes a little for this use-case).
-        s_e_prod *= 2
+        # Do AE to get a rough idea of where we are.
+        s_ae,e_ae,_,_,_  = \
+            cam.do_3a(get_results=True, do_awb=False, do_af=False)
+        # Underexpose to get more data for low signal levels.
+        auto_e = s_ae*e_ae/bracket_factor
 
-        # Capture raw frames across the full sensitivity range.
-        NUM_SENS_STEPS = 9
-        sens_step = int((sens_max - sens_min - 1) / float(NUM_SENS_STEPS))
-        reqs = []
-        sens = []
-        for s in range(sens_min, sens_max, sens_step):
-            e = int(s_e_prod / float(s))
-            req = its.objects.manual_capture_request(s, e)
-            req["android.colorCorrection.transform"] = \
-                    its.objects.float_to_rational(awb_ccm)
-            req["android.colorCorrection.gains"] = awb_gains
-            reqs.append(req)
-            sens.append(s)
+        # If the auto-exposure result is too bright for the highest
+        # sensitivity or too dark for the lowest sensitivity, report
+        # an error.
+        min_exposure_ns, max_exposure_ns = \
+            props['android.sensor.info.exposureTimeRange']
+        if auto_e < min_exposure_ns*sens_max:
+            raise its.error.Error("Scene is too bright to properly expose \
+                                  at the highest sensitivity")
+        if auto_e*bracket_factor > max_exposure_ns*sens_min:
+            raise its.error.Error("Scene is too dark to properly expose \
+                                  at the lowest sensitivity")
 
-        caps = cam.do_capture(reqs, cam.CAP_RAW)
+        # Start the sensitivities at the minimum.
+        s = sens_min
 
-        # A list of the (x,y) coords of the center pixel of a collection of
-        # patches of a color checker chart. Each patch should be uniform,
-        # however the actual color doesn't matter. Note that the coords are
-        # relative to the *converted* RGB image, which is 1/2 x 1/2 of the
-        # full size; convert back to full.
-        img = its.image.convert_capture_to_rgb_image(caps[0], props=props)
-        patches = its.image.get_color_checker_chart_patches(img, NAME+"_debug")
-        patches = [(2*x,2*y) for (x,y) in sum(patches,[])]
+        samples = []
+        plots = []
+        measured_models = []
+        while s <= sens_max + 1:
+            print "ISO %d" % round(s)
+            fig = plt.figure()
+            plt_s = fig.gca()
+            plt_s.set_title("ISO %d" % round(s))
+            plt_s.set_xlabel("Mean signal level")
+            plt_s.set_ylabel("Variance")
 
-        lines = []
-        for iouter, (s,cap) in enumerate(zip(sens,caps)):
-            # For each capture, compute the mean value in each patch, for each
-            # Bayer plane; discard patches where pixels are close to clamped.
-            # Also compute the variance.
-            CLAMP_THRESH = 0.2
-            planes = its.image.convert_capture_to_planes(cap, props)
-            points = []
-            for i,plane in enumerate(planes):
-                plane = (plane * white_level - black_levels[i]) / (
-                        white_level - black_levels[i])
-                for j,(x,y) in enumerate(patches):
-                    tile = plane[y/2-16:y/2+16:,x/2-16:x/2+16:,::]
-                    mean = its.image.compute_image_means(tile)[0]
-                    var = its.image.compute_image_variances(tile)[0]
-                    if (mean > CLAMP_THRESH and mean < 1.0-CLAMP_THRESH):
-                        # Each point is a (mean,variance) tuple for a patch;
-                        # for a given ISO, there should be a linear
-                        # relationship between these values.
-                        points.append((mean,var))
+            samples_s = []
+            for b in range(0, bracket_stops + 1):
+                # Get the exposure for this sensitivity and exposure time.
+                e = int(math.pow(2, b)*auto_e/float(s))
+                req = its.objects.manual_capture_request(round(s), e)
+                cap = cam.do_capture(req, cam.CAP_RAW)
+                planes = its.image.convert_capture_to_planes(cap, props)
 
-            # Fit a line to the points, with a line equation: y = mx + b.
-            # This line is the relationship between mean and variance (i.e.)
-            # between signal level and noise, for this particular sensor.
-            # In the DNG noise model, the gradient (m) is "S", and the offset
-            # (b) is "O".
-            points.sort()
-            xs = [x for (x,y) in points]
-            ys = [y for (x,y) in points]
-            m,b = numpy.polyfit(xs, ys, 1)
-            lines.append((s,m,b))
-            print s, "->", m, b
+                samples_e = []
+                for (pidx, p) in enumerate(planes):
+                    p = p.squeeze()
 
-            # TODO: Clean up these checks (which currently fail in some cases).
-            # Some sanity checks:
-            # * Noise levels should increase with brightness.
-            # * Extrapolating to a black image, the noise should be positive.
-            # Basically, the "b" value should correspond to the read noise,
-            # which is the noise level if the sensor was operating in zero
-            # light.
-            #assert(m > 0)
-            #assert(b >= 0)
+                    # Crop the plane to be a multiple of the tile size.
+                    p = p[0:p.shape[0] - p.shape[0]%tile_size, 
+                          0:p.shape[1] - p.shape[1]%tile_size]
 
-            if iouter == 0:
-                pylab.plot(xs, ys, 'r', label="Measured")
-                pylab.plot([0,xs[-1]],[b,m*xs[-1]+b],'b', label="Fit")
-            else:
-                pylab.plot(xs, ys, 'r')
-                pylab.plot([0,xs[-1]],[b,m*xs[-1]+b],'b')
+                    # convert_capture_to_planes normalizes the range
+                    # to [0, 1], but without subtracting the black
+                    # level.
+                    black_level = black_levels[pidx]
+                    p = p*white_level
+                    p = (p - black_level)/(white_level - black_level)
 
-        pylab.xlabel("Mean")
-        pylab.ylabel("Variance")
-        pylab.legend()
-        matplotlib.pyplot.savefig("%s_plot_mean_vs_variance.png" % (NAME))
+                    # Use our high pass filter to filter this plane.
+                    hp = scipy.signal.sepfir2d(p, f, f).astype('float32')
 
-        # Now fit a line across the (m,b) line parameters for each sensitivity.
-        # The gradient (m) params are fit to the "S" line, and the offset (b)
-        # params are fit to the "O" line, both as a function of sensitivity.
-        gains = [d[0] for d in lines]
-        Ss = [d[1] for d in lines]
-        Os = [d[2] for d in lines]
-        mS,bS = numpy.polyfit(gains, Ss, 1)
-        mO,bO = numpy.polyfit(gains, Os, 1)
+                    means_tiled = \
+                        np.mean(tile(p, tile_size), axis=(0, 1)).flatten()
+                    vars_tiled = \
+                        np.var(tile(hp, tile_size), axis=(0, 1)).flatten()
 
-        # Plot curve "O" as 10x, so it fits in the same scale as curve "S".
-        fig = matplotlib.pyplot.figure()
-        pylab.plot(gains, [10*o for o in Os], 'r', label="Measured")
-        pylab.plot([gains[0],gains[-1]],
-                [10*mO*gains[0]+10*bO, 10*mO*gains[-1]+10*bO],'r--',label="Fit")
-        pylab.plot(gains, Ss, 'b', label="Measured")
-        pylab.plot([gains[0],gains[-1]], [mS*gains[0]+bS,mS*gains[-1]+bS],'b--',
-                label="Fit")
-        pylab.xlabel("Sensitivity")
-        pylab.ylabel("Model parameter: S (blue), O x10 (red)")
-        pylab.legend()
-        matplotlib.pyplot.savefig("%s_plot_S_O.png" % (NAME))
+                    for (mean, var) in zip(means_tiled, vars_tiled):
+                        # Don't include the tile if it has samples that might 
+                        # be clipped.
+                        if mean + 2*math.sqrt(var) < max_signal_level:
+                            samples_e.append([mean, var])
 
+                    means_e, vars_e = zip(*samples_e)
+                    plt_s.plot(means_e, vars_e, colors[b%len(colors)] + ',')
+
+                    samples_s.extend(samples_e)
+
+            [S, O, R, p, stderr] = scipy.stats.linregress(samples_s)
+            measured_models.append([round(s), S, O])
+            print "Sensitivity %d: %e*y + %e (R=%f)" % (round(s), S, O, R)
+
+            # Add the samples for this sensitivity to the global samples list.
+            samples.extend([(round(s), mean, var) for (mean, var) in samples_s])
+
+            # Add the linear fit to the plot for this sensitivity.
+            plt_s.plot([0, max_signal_level], [O, O + S*max_signal_level], 'r-', 
+                       label="Linear fit")
+            xmax = max([x for (x, _) in samples_s])*1.25
+            plt_s.set_xlim(xmin=0, xmax=xmax)
+            plt_s.set_ylim(ymin=0, ymax=(O + S*xmax)*1.25)
+            fig.savefig("%s_samples_iso%04d.png" % (NAME, round(s)))
+            plots.append([round(s), fig])
+
+            # Move to the next sensitivity.
+            s = s*math.pow(2, 1.0/steps_per_stop)
+
+        # Grab the sensitivities and line parameters from each sensitivity.
+        S_measured = [e[1] for e in measured_models]
+        O_measured = [e[2] for e in measured_models]
+        sens = np.asarray([e[0] for e in measured_models])
+        sens_sq = np.square(sens)
+
+        # Use a global linear optimization to fit the noise model.
+        gains = np.asarray([s[0] for s in samples])
+        means = np.asarray([s[1] for s in samples])
+        vars_ = np.asarray([s[2] for s in samples])
+
+        # Define digital gain as the gain above the max analog gain
+        # per the Camera2 spec. Also, define a corresponding C
+        # expression snippet to use in the generated model code.
+        digital_gains = np.maximum(gains/sens_max_analog, 1)
+        digital_gain_cdef = "(sens / %d.0) < 1.0 ? 1.0 : (sens / %d.0)" % \
+            (sens_max_analog, sens_max_analog)
+
+        # Find the noise model parameters via least squares fit.
+        ad = gains*means
+        bd = means
+        cd = gains*gains
+        dd = digital_gains*digital_gains
+        a = np.asarray([ad, bd, cd, dd]).T
+        b = vars_
+
+        # To avoid overfitting to high ISOs (high variances), divide the system
+        # by the gains.
+        a = a/(np.tile(gains, (a.shape[1], 1)).T)
+        b = b/gains
+
+        [A, B, C, D], _, _, _ = np.linalg.lstsq(a, b)
+
+        # Plot the noise model components with the values predicted by the 
+        # noise model.
+        S_model = A*sens + B
+        O_model = \
+            C*sens_sq + D*np.square(np.maximum(sens/sens_max_analog, 1))
+
+        (fig, (plt_S, plt_O)) = plt.subplots(2, 1)
+        plt_S.set_title("Noise model")
+        plt_S.set_ylabel("S")
+        plt_S.loglog(sens, S_measured, 'r+', basex=10, basey=10, 
+                     label="Measured")
+        plt_S.loglog(sens, S_model, 'bx', basex=10, basey=10, label="Model")
+        plt_S.legend(loc=2)
+
+        plt_O.set_xlabel("ISO")
+        plt_O.set_ylabel("O")
+        plt_O.loglog(sens, O_measured, 'r+', basex=10, basey=10, 
+                     label="Measured")
+        plt_O.loglog(sens, O_model, 'bx', basex=10, basey=10, label="Model")
+        fig.savefig("%s.png" % (NAME))
+
+        for [s, fig] in plots:
+            plt_s = fig.gca()
+
+            dg = max(s/sens_max_analog, 1)
+            S = A*s + B
+            O = C*s*s + D*dg*dg
+            plt_s.plot([0, max_signal_level], [O, O + S*max_signal_level], 'b-', 
+                       label="Model")
+            plt_s.legend(loc=2)
+
+            plt.figure(fig.number)
+
+            # Re-save the plot with the global model.
+            fig.savefig("%s_samples_iso%04d.png" % (NAME, round(s)))
+
+        # Generate the noise model implementation.
         print """
         /* Generated test code to dump a table of data for external validation
          * of the noise model parameters.
@@ -176,11 +281,13 @@
             double s = %e * sens + %e;
             return s < 0.0 ? 0.0 : s;
         }
+
         double compute_noise_model_entry_O(int sens) {
-            double o = %e * sens + %e;
+            double digital_gain = %s;
+            double o = %e * sens * sens + %e * digital_gain * digital_gain;
             return o < 0.0 ? 0.0 : o;
         }
-        """%(sens_min,sens_max,mS,bS,mO,bO)
+        """ % (sens_min, sens_max, A, B, digital_gain_cdef, C, D)
 
 if __name__ == '__main__':
     main()
diff --git a/apps/CameraITS/tests/inprog/test_burst_sameness_auto.py b/apps/CameraITS/tests/inprog/test_burst_sameness_auto.py
index 87500c7..6629df8 100644
--- a/apps/CameraITS/tests/inprog/test_burst_sameness_auto.py
+++ b/apps/CameraITS/tests/inprog/test_burst_sameness_auto.py
@@ -39,7 +39,8 @@
 
         # Capture at the smallest resolution.
         props = cam.get_camera_properties()
-        its.caps.skip_unless(its.caps.manual_sensor(props))
+        its.caps.skip_unless(its.caps.manual_sensor(props) and
+                             its.caps.awb_lock(props))
 
         _, fmt = its.objects.get_fastest_manual_capture_settings(props)
         w,h = fmt["width"], fmt["height"]
diff --git a/apps/CameraITS/tests/inprog/test_burst_sameness_fullres_auto.py b/apps/CameraITS/tests/inprog/test_burst_sameness_fullres_auto.py
index 932c051..fa37174 100644
--- a/apps/CameraITS/tests/inprog/test_burst_sameness_fullres_auto.py
+++ b/apps/CameraITS/tests/inprog/test_burst_sameness_fullres_auto.py
@@ -15,6 +15,7 @@
 import its.image
 import its.device
 import its.objects
+import its.caps
 import os.path
 import numpy
 import pylab
@@ -41,6 +42,8 @@
 
         # Capture at full resolution.
         props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.manual_sensor(props) and
+                             its.caps.awb_lock(props))
         w,h = its.objects.get_available_output_sizes("yuv", props)[0]
 
         # Converge 3A prior to capture.
diff --git a/apps/CameraITS/tests/inprog/test_faces.py b/apps/CameraITS/tests/inprog/test_faces.py
deleted file mode 100644
index 228dac8..0000000
--- a/apps/CameraITS/tests/inprog/test_faces.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 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.
-
-import its.image
-import its.device
-import its.objects
-import os.path
-
-def main():
-    """Test face detection.
-    """
-    NAME = os.path.basename(__file__).split(".")[0]
-
-    with its.device.ItsSession() as cam:
-        cam.do_3a()
-        req = its.objects.auto_capture_request()
-        req['android.statistics.faceDetectMode'] = 2
-        caps = cam.do_capture([req]*5)
-        for i,cap in enumerate(caps):
-            md = cap['metadata']
-            print "Frame %d face metadata:" % i
-            print "  Ids:", md['android.statistics.faceIds']
-            print "  Landmarks:", md['android.statistics.faceLandmarks']
-            print "  Rectangles:", md['android.statistics.faceRectangles']
-            print "  Scores:", md['android.statistics.faceScores']
-            print ""
-
-if __name__ == '__main__':
-    main()
-
diff --git a/apps/CameraITS/tests/inprog/test_rawstats.py b/apps/CameraITS/tests/inprog/test_rawstats.py
new file mode 100644
index 0000000..8083f0b
--- /dev/null
+++ b/apps/CameraITS/tests/inprog/test_rawstats.py
@@ -0,0 +1,48 @@
+# 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 its.target
+import os.path
+import math
+
+def main():
+    """Test capturing some rawstats data.
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+
+    with its.device.ItsSession() as cam:
+
+        cam.do_3a(do_af=False);
+        req = its.objects.auto_capture_request()
+
+        for (gw,gh) in [(16,16)]:#,(4080,1)]:
+            cap = cam.do_capture(req,
+                {"format":"rawStats","gridWidth":gw,"gridHeight":gh})
+            mean_image, var_image = its.image.unpack_rawstats_capture(cap)
+
+            if gw > 1 and gh > 1:
+                h,w,_ = mean_image.shape
+                for ch in range(4):
+                    m = mean_image[:,:,ch].reshape(h,w,1)/1023.0
+                    v = var_image[:,:,ch].reshape(h,w,1)
+                    its.image.write_image(m, "%s_mean_ch%d.jpg" % (NAME,ch), True)
+                    its.image.write_image(v, "%s_var_ch%d.jpg" % (NAME,ch), True)
+
+if __name__ == '__main__':
+    main()
+
diff --git a/apps/CameraITS/tests/scene0/test_metadata.py b/apps/CameraITS/tests/scene0/test_metadata.py
index 375a6af..44663bb 100644
--- a/apps/CameraITS/tests/scene0/test_metadata.py
+++ b/apps/CameraITS/tests/scene0/test_metadata.py
@@ -72,8 +72,6 @@
     check('props.has_key("android.scaler.croppingType")')
     check('props["android.scaler.croppingType"] is not None')
     check('props["android.scaler.croppingType"] in [0,1]')
-    if full:
-        check('props["android.scaler.croppingType"] == 1')
 
     assert(not failed)
 
diff --git a/apps/CameraITS/tests/scene1/test_black_white.py b/apps/CameraITS/tests/scene1/test_black_white.py
index 68d7de6..56bc5ec 100644
--- a/apps/CameraITS/tests/scene1/test_black_white.py
+++ b/apps/CameraITS/tests/scene1/test_black_white.py
@@ -76,9 +76,9 @@
         matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
 
         for val in black_means:
-            assert(val < 0.025)
+            assert(val < 0.035)
         for val in white_means:
-            assert(val > 0.975)
+            assert(val > 0.965)
 
 if __name__ == '__main__':
     main()
diff --git a/apps/CameraITS/tests/scene1/test_crop_region_raw.py b/apps/CameraITS/tests/scene1/test_crop_region_raw.py
index 189e987..7973755 100644
--- a/apps/CameraITS/tests/scene1/test_crop_region_raw.py
+++ b/apps/CameraITS/tests/scene1/test_crop_region_raw.py
@@ -64,7 +64,7 @@
         # Use a manual request with a linear tonemap so that the YUV and RAW
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
-        req = its.objects.manual_capture_request(s,e, True)
+        req = its.objects.manual_capture_request(s,e, True, props)
         cap1_raw, cap1_yuv = cam.do_capture(req, cam.CAP_RAW_YUV)
 
         # Capture with a crop region.
diff --git a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
index 9b43a74..5fd8f73 100644
--- a/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
+++ b/apps/CameraITS/tests/scene1/test_ev_compensation_advanced.py
@@ -41,10 +41,12 @@
         range_max = ev_compensation_range[1]
         ev_per_step = its.objects.rational_to_float(
                 props['android.control.aeCompensationStep'])
-        steps_per_ev = int(1.0 / ev_per_step)
-        evs = range(range_min, range_max + 1, steps_per_ev)
+        steps_per_ev = int(round(1.0 / ev_per_step))
+        ev_steps = range(range_min, range_max + 1, steps_per_ev)
+        imid = len(ev_steps) / 2
+        ev_shifts = [pow(2, step * ev_per_step) for step in ev_steps]
         lumas = []
-        for ev in evs:
+        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.
@@ -65,19 +67,16 @@
             tile = its.image.get_image_patch(y, 0.45,0.45,0.1,0.1)
             lumas.append(its.image.compute_image_means(tile)[0])
 
-        luma_increase_per_step = pow(2, ev_per_step)
         print "ev_step_size_in_stops", ev_per_step
-        imid = len(lumas) / 2
-        expected_lumas = [lumas[imid] / pow(luma_increase_per_step, i)
-                          for i in range(imid , 0, -1)]  + \
-                         [lumas[imid] * pow(luma_increase_per_step, i-imid)
-                          for i in range(imid, len(evs))]
+        shift_mid = ev_shifts[imid]
+        luma_normal = lumas[imid] / shift_mid
+        expected_lumas = [luma_normal * ev_shift for ev_shift in ev_shifts]
 
-        pylab.plot(evs, lumas, 'r')
-        pylab.plot(evs, expected_lumas, 'b')
+        pylab.plot(ev_steps, lumas, 'r')
+        pylab.plot(ev_steps, expected_lumas, 'b')
         matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
 
-        luma_diffs = [expected_lumas[i] - lumas[i] for i in range(len(evs))]
+        luma_diffs = [expected_lumas[i] - lumas[i] for i in range(len(ev_steps))]
         max_diff = max(abs(i) for i in luma_diffs)
         avg_diff = abs(numpy.array(luma_diffs)).mean()
         print "Max delta between modeled and measured lumas:", max_diff
diff --git a/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py b/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
index d09f2fd..e3755eb 100644
--- a/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
+++ b/apps/CameraITS/tests/scene1/test_ev_compensation_basic.py
@@ -29,7 +29,8 @@
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
-        its.caps.skip_unless(its.caps.ev_compensation(props))
+        its.caps.skip_unless(its.caps.ev_compensation(props) and
+                             its.caps.ae_lock(props))
 
         ev_per_step = its.objects.rational_to_float(
                 props['android.control.aeCompensationStep'])
diff --git a/apps/CameraITS/tests/scene1/test_exposure.py b/apps/CameraITS/tests/scene1/test_exposure.py
index a9cc42b..e448f80 100644
--- a/apps/CameraITS/tests/scene1/test_exposure.py
+++ b/apps/CameraITS/tests/scene1/test_exposure.py
@@ -35,12 +35,16 @@
     THRESHOLD_MAX_OUTLIER_DIFF = 0.1
     THRESHOLD_MIN_LEVEL = 0.1
     THRESHOLD_MAX_LEVEL = 0.9
-    THRESHOLD_MAX_LEVEL_DIFF = 0.025
+    THRESHOLD_MAX_LEVEL_DIFF = 0.03
+    THRESHOLD_MAX_LEVEL_DIFF_WIDE_RANGE = 0.05
+    THRESHOLD_ROUND_DOWN_GAIN = 0.1
+    THRESHOLD_ROUND_DOWN_EXP = 0.05
 
     mults = []
     r_means = []
     g_means = []
     b_means = []
+    threshold_max_level_diff = THRESHOLD_MAX_LEVEL_DIFF
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
@@ -48,27 +52,45 @@
                              its.caps.per_frame_control(props))
 
         e,s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
+        s_e_product = s*e
         expt_range = props['android.sensor.info.exposureTimeRange']
         sens_range = props['android.sensor.info.sensitivityRange']
 
-        m = 1
+        m = 1.0
         while s*m < sens_range[1] and e/m > expt_range[0]:
             mults.append(m)
-            req = its.objects.manual_capture_request(s*m, e/m, True, props)
+            s_test = round(s*m)
+            e_test = s_e_product / s_test
+            print "Testsing s:", s_test, "e:", e_test
+            req = its.objects.manual_capture_request(
+                    s_test, e_test, True, props)
             cap = cam.do_capture(req)
+            s_res = cap["metadata"]["android.sensor.sensitivity"]
+            e_res = cap["metadata"]["android.sensor.exposureTime"]
+            assert(0 <= s_test - s_res < s_test * THRESHOLD_ROUND_DOWN_GAIN)
+            assert(0 <= e_test - e_res < e_test * THRESHOLD_ROUND_DOWN_EXP)
+            s_e_product_res = s_res * e_res
+            request_result_ratio = s_e_product / s_e_product_res
+            print "Capture result s:", s_test, "e:", e_test
             img = its.image.convert_capture_to_rgb_image(cap)
-            its.image.write_image(img, "%s_mult=%02d.jpg" % (NAME, m))
+            its.image.write_image(img, "%s_mult=%3.2f.jpg" % (NAME, m))
             tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
             rgb_means = its.image.compute_image_means(tile)
-            r_means.append(rgb_means[0])
-            g_means.append(rgb_means[1])
-            b_means.append(rgb_means[2])
-            m = m + 4
+            # Adjust for the difference between request and result
+            r_means.append(rgb_means[0] * request_result_ratio)
+            g_means.append(rgb_means[1] * request_result_ratio)
+            b_means.append(rgb_means[2] * request_result_ratio)
+            # Test 3 steps per 2x gain
+            m = m * pow(2, 1.0 / 3)
+
+        # Allow more threshold for devices with wider exposure range
+        if m >= 64.0:
+            threshold_max_level_diff = THRESHOLD_MAX_LEVEL_DIFF_WIDE_RANGE
 
     # Draw a plot.
-    pylab.plot(mults, r_means, 'r')
-    pylab.plot(mults, g_means, 'g')
-    pylab.plot(mults, b_means, 'b')
+    pylab.plot(mults, r_means, 'r.-')
+    pylab.plot(mults, g_means, 'g.-')
+    pylab.plot(mults, b_means, 'b.-')
     pylab.ylim([0,1])
     matplotlib.pyplot.savefig("%s_plot_means.png" % (NAME))
 
@@ -83,7 +105,7 @@
         max_diff = max_val - min_val
         print "Channel %d line fit (y = mx+b): m = %f, b = %f" % (chan, m, b)
         print "Channel max %f min %f diff %f" % (max_val, min_val, max_diff)
-        assert(max_diff < THRESHOLD_MAX_LEVEL_DIFF)
+        assert(max_diff < threshold_max_level_diff)
         assert(b > THRESHOLD_MIN_LEVEL and b < THRESHOLD_MAX_LEVEL)
         for v in values:
             assert(v > THRESHOLD_MIN_LEVEL and v < THRESHOLD_MAX_LEVEL)
diff --git a/apps/CameraITS/tests/scene1/test_jpeg.py b/apps/CameraITS/tests/scene1/test_jpeg.py
index 25c2038..7bc038d 100644
--- a/apps/CameraITS/tests/scene1/test_jpeg.py
+++ b/apps/CameraITS/tests/scene1/test_jpeg.py
@@ -33,7 +33,7 @@
                              its.caps.per_frame_control(props))
 
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
+        req = its.objects.manual_capture_request(s, e, True, props)
 
         # YUV
         size = its.objects.get_available_output_sizes("yuv", props)[0]
diff --git a/apps/CameraITS/tests/scene1/test_latching.py b/apps/CameraITS/tests/scene1/test_latching.py
index 3bc4356..176f01b 100644
--- a/apps/CameraITS/tests/scene1/test_latching.py
+++ b/apps/CameraITS/tests/scene1/test_latching.py
@@ -45,20 +45,20 @@
         b_means = []
 
         reqs = [
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s*2,e,   True),
-            its.objects.manual_capture_request(s*2,e,   True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e*2, True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s*2,e,   True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e*2, True),
-            its.objects.manual_capture_request(s,  e,   True),
-            its.objects.manual_capture_request(s,  e*2, True),
-            its.objects.manual_capture_request(s,  e*2, True),
+            its.objects.manual_capture_request(s,  e,   True, props),
+            its.objects.manual_capture_request(s,  e,   True, props),
+            its.objects.manual_capture_request(s*2,e,   True, props),
+            its.objects.manual_capture_request(s*2,e,   True, props),
+            its.objects.manual_capture_request(s,  e,   True, props),
+            its.objects.manual_capture_request(s,  e,   True, props),
+            its.objects.manual_capture_request(s,  e*2, True, props),
+            its.objects.manual_capture_request(s,  e,   True, props),
+            its.objects.manual_capture_request(s*2,e,   True, props),
+            its.objects.manual_capture_request(s,  e,   True, props),
+            its.objects.manual_capture_request(s,  e*2, True, props),
+            its.objects.manual_capture_request(s,  e,   True, props),
+            its.objects.manual_capture_request(s,  e*2, True, props),
+            its.objects.manual_capture_request(s,  e*2, True, props),
             ]
 
         caps = cam.do_capture(reqs, fmt)
diff --git a/apps/CameraITS/tests/scene1/test_locked_burst.py b/apps/CameraITS/tests/scene1/test_locked_burst.py
index a33a9f8..6552c73 100644
--- a/apps/CameraITS/tests/scene1/test_locked_burst.py
+++ b/apps/CameraITS/tests/scene1/test_locked_burst.py
@@ -38,6 +38,8 @@
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.ae_lock(props) and
+                             its.caps.awb_lock(props))
 
         # Converge 3A prior to capture.
         cam.do_3a(do_af=True, lock_ae=True, lock_awb=True)
diff --git a/apps/CameraITS/tests/scene1/test_param_color_correction.py b/apps/CameraITS/tests/scene1/test_param_color_correction.py
index b7fdc7b..09b3707 100644
--- a/apps/CameraITS/tests/scene1/test_param_color_correction.py
+++ b/apps/CameraITS/tests/scene1/test_param_color_correction.py
@@ -42,7 +42,7 @@
 
         # Baseline request
         e, s = its.target.get_target_exposure_combos(cam)["midSensitivity"]
-        req = its.objects.manual_capture_request(s, e, True)
+        req = its.objects.manual_capture_request(s, e, True, props)
         req["android.colorCorrection.mode"] = 0
 
         # Transforms:
diff --git a/apps/CameraITS/tests/scene1/test_param_exposure_time.py b/apps/CameraITS/tests/scene1/test_param_exposure_time.py
index e6078d9..0c0aab1 100644
--- a/apps/CameraITS/tests/scene1/test_param_exposure_time.py
+++ b/apps/CameraITS/tests/scene1/test_param_exposure_time.py
@@ -39,7 +39,7 @@
 
         e,s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
         for i,e_mult in enumerate([0.8, 0.9, 1.0, 1.1, 1.2]):
-            req = its.objects.manual_capture_request(s, e * e_mult, True)
+            req = its.objects.manual_capture_request(s, e * e_mult, True, props)
             cap = cam.do_capture(req)
             img = its.image.convert_capture_to_rgb_image(cap)
             its.image.write_image(
diff --git a/apps/CameraITS/tests/scene1/test_param_flash_mode.py b/apps/CameraITS/tests/scene1/test_param_flash_mode.py
index aae56aa..38f864f 100644
--- a/apps/CameraITS/tests/scene1/test_param_flash_mode.py
+++ b/apps/CameraITS/tests/scene1/test_param_flash_mode.py
@@ -39,7 +39,7 @@
         # linear tonemap.
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
         e /= 4
-        req = its.objects.manual_capture_request(s, e, True)
+        req = its.objects.manual_capture_request(s, e, True, props)
 
         for f in [0,1,2]:
             req["android.flash.mode"] = f
diff --git a/apps/CameraITS/tests/scene1/test_param_noise_reduction.py b/apps/CameraITS/tests/scene1/test_param_noise_reduction.py
index 219927d..1072684 100644
--- a/apps/CameraITS/tests/scene1/test_param_noise_reduction.py
+++ b/apps/CameraITS/tests/scene1/test_param_noise_reduction.py
@@ -17,10 +17,11 @@
 import its.device
 import its.objects
 import its.target
-import pylab
-import os.path
 import matplotlib
 import matplotlib.pyplot
+import numpy
+import os.path
+import pylab
 
 def main():
     """Test that the android.noiseReduction.mode param is applied when set.
@@ -34,18 +35,21 @@
     """
     NAME = os.path.basename(__file__).split(".")[0]
 
-    # List of variances for R,G,B.
-    variances = [[],[],[]]
+    NUM_SAMPLES_PER_MODE = 4
+    SNR_TOLERANCE = 3 # unit in db
+    # List of SNRs for R,G,B.
+    snrs = [[], [], []]
 
-    # Reference (baseline) variance for each of R,G,B.
-    ref_variance = []
+    # Reference (baseline) SNR for each of R,G,B.
+    ref_snr = []
 
     nr_modes_reported = []
 
     with its.device.ItsSession() as cam:
         props = cam.get_camera_properties()
         its.caps.skip_unless(its.caps.compute_target_exposure(props) and
-                             its.caps.per_frame_control(props))
+                             its.caps.per_frame_control(props) and
+                             its.caps.noise_reduction_mode(props, 0))
 
         # NR mode 0 with low gain
         e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
@@ -57,41 +61,84 @@
                 rgb_image,
                 "%s_low_gain.jpg" % (NAME))
         rgb_tile = its.image.get_image_patch(rgb_image, 0.45, 0.45, 0.1, 0.1)
-        ref_variance = its.image.compute_image_variances(rgb_tile)
-        print "Ref variances:", ref_variance
+        ref_snr = its.image.compute_image_snrs(rgb_tile)
+        print "Ref SNRs:", ref_snr
 
         e, s = its.target.get_target_exposure_combos(cam)["maxSensitivity"]
-        for i in range(3):
-            # NR modes 0, 1, 2 with high gain
-            req = its.objects.manual_capture_request(s, e)
-            req["android.noiseReduction.mode"] = i
-            cap = cam.do_capture(req)
-            rgb_image = its.image.convert_capture_to_rgb_image(cap)
-            nr_modes_reported.append(
-                    cap["metadata"]["android.noiseReduction.mode"])
-            its.image.write_image(
-                    rgb_image,
-                    "%s_high_gain_nr=%d.jpg" % (NAME, i))
-            rgb_tile = its.image.get_image_patch(
-                    rgb_image, 0.45, 0.45, 0.1, 0.1)
-            rgb_vars = its.image.compute_image_variances(rgb_tile)
+        # NR modes 0, 1, 2, 3, 4 with high gain
+        for mode in range(5):
+            # Skip unavailable modes
+            if not its.caps.noise_reduction_mode(props, mode):
+                nr_modes_reported.append(mode)
+                for channel in range(3):
+                    snrs[channel].append(0)
+                continue;
+
+            rgb_snr_list = []
+            # Capture several images to account for per frame noise variations
+            for n in range(NUM_SAMPLES_PER_MODE):
+                req = its.objects.manual_capture_request(s, e)
+                req["android.noiseReduction.mode"] = mode
+                cap = cam.do_capture(req)
+                rgb_image = its.image.convert_capture_to_rgb_image(cap)
+                if n == 0:
+                    nr_modes_reported.append(
+                            cap["metadata"]["android.noiseReduction.mode"])
+                    its.image.write_image(
+                            rgb_image,
+                            "%s_high_gain_nr=%d.jpg" % (NAME, mode))
+                rgb_tile = its.image.get_image_patch(
+                        rgb_image, 0.45, 0.45, 0.1, 0.1)
+                rgb_snrs = its.image.compute_image_snrs(rgb_tile)
+                rgb_snr_list.append(rgb_snrs)
+
+            r_snrs = [rgb[0] for rgb in rgb_snr_list]
+            g_snrs = [rgb[1] for rgb in rgb_snr_list]
+            b_snrs = [rgb[2] for rgb in rgb_snr_list]
+            rgb_snrs = [numpy.mean(r_snrs), numpy.mean(g_snrs), numpy.mean(b_snrs)]
+            print "NR mode", mode, "SNRs:"
+            print "    R SNR:", rgb_snrs[0],\
+                    "Min:", min(r_snrs), "Max:", max(r_snrs)
+            print "    G SNR:", rgb_snrs[1],\
+                    "Min:", min(g_snrs), "Max:", max(g_snrs)
+            print "    B SNR:", rgb_snrs[2],\
+                    "Min:", min(b_snrs), "Max:", max(b_snrs)
+
             for chan in range(3):
-                variance = rgb_vars[chan]
-                variances[chan].append(variance / ref_variance[chan])
-        print "Variances with NR mode [0,1,2]:", variances
+                snrs[chan].append(rgb_snrs[chan])
 
     # Draw a plot.
     for j in range(3):
-        pylab.plot(range(3), variances[j], "rgb"[j])
-    matplotlib.pyplot.savefig("%s_plot_variances.png" % (NAME))
+        pylab.plot(range(5), snrs[j], "rgb"[j])
+    matplotlib.pyplot.savefig("%s_plot_SNRs.png" % (NAME))
 
-    assert(nr_modes_reported == [0,1,2])
+    assert(nr_modes_reported == [0,1,2,3,4])
 
-    # Check that the variance of the NR=0 image is higher than for the
-    # NR=1 and NR=2 images.
     for j in range(3):
-        for i in range(1,3):
-            assert(variances[j][i] < variances[j][0])
+        # Larger SNR is better
+        # Verify OFF(0) is not better than FAST(1)
+        assert(snrs[j][0] <
+               snrs[j][1] + SNR_TOLERANCE)
+        # Verify FAST(1) is not better than HQ(2)
+        assert(snrs[j][1] <
+               snrs[j][2] + SNR_TOLERANCE)
+        # Verify HQ(2) is better than OFF(0)
+        assert(snrs[j][0] < snrs[j][2])
+        if its.caps.noise_reduction_mode(props, 3):
+            # Verify OFF(0) is not better than MINIMAL(3)
+            assert(snrs[j][0] <
+                   snrs[j][3] + SNR_TOLERANCE)
+            # Verify MINIMAL(3) is not better than HQ(2)
+            assert(snrs[j][3] <
+                   snrs[j][2] + SNR_TOLERANCE)
+            if its.caps.noise_reduction_mode(props, 4):
+                # Verify ZSL(4) is close to MINIMAL(3)
+                assert(numpy.isclose(snrs[j][4], snrs[j][3],
+                                     atol=SNR_TOLERANCE))
+        elif its.caps.noise_reduction_mode(props, 4):
+            # Verify ZSL(4) is close to OFF(0)
+            assert(numpy.isclose(snrs[j][4], snrs[j][0],
+                                 atol=SNR_TOLERANCE))
 
 if __name__ == '__main__':
     main()
diff --git a/apps/CameraITS/tests/scene1/test_param_shading_mode.py b/apps/CameraITS/tests/scene1/test_param_shading_mode.py
new file mode 100644
index 0000000..8538675
--- /dev/null
+++ b/apps/CameraITS/tests/scene1/test_param_shading_mode.py
@@ -0,0 +1,115 @@
+# 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.caps
+import its.device
+import its.objects
+import matplotlib
+import numpy
+import os
+import os.path
+import pylab
+
+def main():
+    """Test that the android.shading.mode param is applied.
+
+    Switching shading modes and checks that the lens shading maps are
+    modified as expected.
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+
+    NUM_SHADING_MODE_SWITCH_LOOPS = 3
+    THRESHOLD_DIFF_RATIO = 0.15
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+
+        its.caps.skip_unless(its.caps.per_frame_control(props) and
+                             its.caps.lsc_map(props) and
+                             its.caps.lsc_off(props))
+
+        assert(props.has_key("android.lens.info.shadingMapSize") and
+               props["android.lens.info.shadingMapSize"] != None)
+
+        # lsc_off devices should always support OFF(0), FAST(1), and HQ(2)
+        assert(props.has_key("android.shading.availableModes") and
+               set(props["android.shading.availableModes"]) == set([0, 1, 2]))
+
+        num_map_gains = props["android.lens.info.shadingMapSize"]["width"] * \
+                        props["android.lens.info.shadingMapSize"]["height"] * 4
+
+        # Test 1: Switching shading modes several times and verify:
+        #   1. Lens shading maps with mode OFF are all 1.0
+        #   2. Lens shading maps with mode FAST are similar after switching
+        #      shading modes.
+        #   3. Lens shading maps with mode HIGH_QUALITY are similar after
+        #      switching shading modes.
+        cam.do_3a();
+
+        # Get the reference lens shading maps for OFF, FAST, and HIGH_QUALITY
+        # in different sessions.
+        # reference_maps[mode]
+        reference_maps = [[] for mode in range(3)]
+        reference_maps[0] = [1.0] * num_map_gains
+        for mode in range(1, 3):
+            req = its.objects.auto_capture_request();
+            req["android.statistics.lensShadingMapMode"] = 1
+            req["android.shading.mode"] = mode
+            reference_maps[mode] = cam.do_capture(req)["metadata"] \
+                    ["android.statistics.lensShadingMap"]
+
+        # Get the lens shading maps while switching modes in one session.
+        reqs = []
+        for i in range(NUM_SHADING_MODE_SWITCH_LOOPS):
+            for mode in range(3):
+                req = its.objects.auto_capture_request();
+                req["android.statistics.lensShadingMapMode"] = 1
+                req["android.shading.mode"] = mode
+                reqs.append(req);
+
+        caps = cam.do_capture(reqs)
+
+        # shading_maps[mode][loop]
+        shading_maps = [[[] for loop in range(NUM_SHADING_MODE_SWITCH_LOOPS)]
+                for mode in range(3)]
+
+        # Get the shading maps out of capture results
+        for i in range(len(caps)):
+            shading_maps[i % 3][i / 3] = \
+                    caps[i]["metadata"]["android.statistics.lensShadingMap"]
+
+        # Draw the maps
+        for mode in range(3):
+            for i in range(NUM_SHADING_MODE_SWITCH_LOOPS):
+                pylab.clf()
+                pylab.plot(range(num_map_gains), shading_maps[mode][i], 'r')
+                pylab.plot(range(num_map_gains), reference_maps[mode], 'g')
+                pylab.xlim([0, num_map_gains])
+                pylab.ylim([0.9, 4.0])
+                matplotlib.pyplot.savefig("%s_ls_maps_mode_%d_loop_%d.png" %
+                                          (NAME, mode, i))
+
+        print "Verifying lens shading maps with mode OFF are all 1.0"
+        for i in range(NUM_SHADING_MODE_SWITCH_LOOPS):
+            assert(numpy.allclose(shading_maps[0][i], reference_maps[0]))
+
+        for mode in range(1, 3):
+            print "Verifying lens shading maps with mode", mode, "are similar"
+            for i in range(NUM_SHADING_MODE_SWITCH_LOOPS):
+                assert(numpy.allclose(shading_maps[mode][i],
+                                      reference_maps[mode],
+                                      THRESHOLD_DIFF_RATIO))
+
+if __name__ == '__main__':
+    main()
diff --git a/apps/CameraITS/tests/scene1/test_reprocess_noise_reduction.py b/apps/CameraITS/tests/scene1/test_reprocess_noise_reduction.py
new file mode 100644
index 0000000..f0a6fbe
--- /dev/null
+++ b/apps/CameraITS/tests/scene1/test_reprocess_noise_reduction.py
@@ -0,0 +1,168 @@
+# 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 its.target
+import math
+import matplotlib
+import matplotlib.pyplot
+import numpy
+import os.path
+import pylab
+
+def main():
+    """Test that the android.noiseReduction.mode param is applied when set for
+       reprocessing requests.
+
+    Capture reprocessed images with the camera dimly lit. Uses a high analog
+    gain to ensure the captured image is noisy.
+
+    Captures three reprocessed images, for NR off, "fast", and "high quality".
+    Also captures a reprocessed image with low gain and NR off, and uses the
+    variance of this as the baseline.
+    """
+
+    NAME = os.path.basename(__file__).split(".")[0]
+
+    NUM_SAMPLES_PER_MODE = 4
+    SNR_TOLERANCE = 3 # unit in db
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+
+        its.caps.skip_unless(its.caps.compute_target_exposure(props) and
+                             its.caps.per_frame_control(props) and
+                             its.caps.noise_reduction_mode(props, 0) and
+                             (its.caps.yuv_reprocess(props) or
+                              its.caps.private_reprocess(props)))
+
+        # If reprocessing is supported, ZSL NR mode must be avaiable.
+        assert(its.caps.noise_reduction_mode(props, 4))
+
+        reprocess_formats = []
+        if (its.caps.yuv_reprocess(props)):
+            reprocess_formats.append("yuv")
+        if (its.caps.private_reprocess(props)):
+            reprocess_formats.append("private")
+
+        for reprocess_format in reprocess_formats:
+            # List of variances for R, G, B.
+            snrs = [[], [], []]
+            nr_modes_reported = []
+
+            # NR mode 0 with low gain
+            e, s = its.target.get_target_exposure_combos(cam)["minSensitivity"]
+            req = its.objects.manual_capture_request(s, e)
+            req["android.noiseReduction.mode"] = 0
+
+            # Test reprocess_format->JPEG reprocessing
+            # TODO: Switch to reprocess_format->YUV when YUV reprocessing is
+            #       supported.
+            size = its.objects.get_available_output_sizes("jpg", props)[0]
+            out_surface = {"width":size[0], "height":size[1], "format":"jpg"}
+            cap = cam.do_capture(req, out_surface, reprocess_format)
+            img = its.image.decompress_jpeg_to_rgb_image(cap["data"])
+            its.image.write_image(img, "%s_low_gain_fmt=jpg.jpg" % (NAME))
+            tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
+            ref_snr = its.image.compute_image_snrs(tile)
+            print "Ref SNRs:", ref_snr
+
+            e, s = its.target.get_target_exposure_combos(cam)["maxSensitivity"]
+            for nr_mode in range(5):
+                # Skip unavailable modes
+                if not its.caps.noise_reduction_mode(props, nr_mode):
+                    nr_modes_reported.append(nr_mode)
+                    for channel in range(3):
+                        snrs[channel].append(0)
+                    continue
+
+                rgb_snr_list = []
+                # Capture several images to account for per frame noise
+                # variations
+                for n in range(NUM_SAMPLES_PER_MODE):
+                    req = its.objects.manual_capture_request(s, e)
+                    req["android.noiseReduction.mode"] = nr_mode
+                    cap = cam.do_capture(req, out_surface, reprocess_format)
+
+                    img = its.image.decompress_jpeg_to_rgb_image(cap["data"])
+                    if n == 0:
+                        its.image.write_image(
+                                img,
+                                "%s_high_gain_nr=%d_fmt=jpg.jpg"
+                                        %(NAME, nr_mode))
+                        nr_modes_reported.append(
+                                cap["metadata"]["android.noiseReduction.mode"])
+
+                    tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
+                    # Get the variances for R, G, and B channels
+                    rgb_snrs = its.image.compute_image_snrs(tile)
+                    rgb_snr_list.append(rgb_snrs)
+
+                r_snrs = [rgb[0] for rgb in rgb_snr_list]
+                g_snrs = [rgb[1] for rgb in rgb_snr_list]
+                b_snrs = [rgb[2] for rgb in rgb_snr_list]
+                rgb_snrs = [numpy.mean(r_snrs),
+                            numpy.mean(g_snrs),
+                            numpy.mean(b_snrs)]
+                print "NR mode", nr_mode, "SNRs:"
+                print "    R SNR:", rgb_snrs[0],\
+                        "Min:", min(r_snrs), "Max:", max(r_snrs)
+                print "    G SNR:", rgb_snrs[1],\
+                        "Min:", min(g_snrs), "Max:", max(g_snrs)
+                print "    B SNR:", rgb_snrs[2],\
+                        "Min:", min(b_snrs), "Max:", max(b_snrs)
+
+                for chan in range(3):
+                    snrs[chan].append(rgb_snrs[chan])
+
+            # Draw a plot.
+            for channel in range(3):
+                pylab.plot(range(5), snrs[channel], "rgb"[channel])
+
+            matplotlib.pyplot.savefig("%s_plot_%s_SNRs.png" %
+                                      (NAME, reprocess_format))
+
+            assert(nr_modes_reported == [0,1,2,3,4])
+
+            for j in range(3):
+                # Larger is better
+                # Verify OFF(0) is not better than FAST(1)
+                assert(snrs[j][0] <
+                       snrs[j][1] + SNR_TOLERANCE)
+                # Verify FAST(1) is not better than HQ(2)
+                assert(snrs[j][1] <
+                       snrs[j][2] + SNR_TOLERANCE)
+                # Verify HQ(2) is better than OFF(0)
+                assert(snrs[j][0] < snrs[j][2])
+                if its.caps.noise_reduction_mode(props, 3):
+                    # Verify OFF(0) is not better than MINIMAL(3)
+                    assert(snrs[j][0] <
+                           snrs[j][3] + SNR_TOLERANCE)
+                    # Verify MINIMAL(3) is not better than HQ(2)
+                    assert(snrs[j][3] <
+                           snrs[j][2] + SNR_TOLERANCE)
+                    # Verify ZSL(4) is close to MINIMAL(3)
+                    assert(numpy.isclose(snrs[j][4], snrs[j][3],
+                                         atol=SNR_TOLERANCE))
+                else:
+                    # Verify ZSL(4) is close to OFF(0)
+                    assert(numpy.isclose(snrs[j][4], snrs[j][0],
+                                         atol=SNR_TOLERANCE))
+
+if __name__ == '__main__':
+    main()
+
diff --git a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py b/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
index 18ca506..7c87ca2 100644
--- a/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
+++ b/apps/CameraITS/tests/scene1/test_tonemap_sequence.py
@@ -40,7 +40,7 @@
         means = []
 
         # Capture 3 manual shots with a linear tonemap.
-        req = its.objects.manual_capture_request(sens, exp_time, True)
+        req = its.objects.manual_capture_request(sens, exp_time, True, props)
         for i in [0,1,2]:
             cap = cam.do_capture(req)
             img = its.image.convert_capture_to_rgb_image(cap)
diff --git a/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py b/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
index 1b278ef..0c428fc 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_jpeg_all.py
@@ -35,7 +35,7 @@
         # Use a manual request with a linear tonemap so that the YUV and JPEG
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
+        req = its.objects.manual_capture_request(s, e, True, props)
 
         rgbs = []
 
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py b/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py
index e58cb1d..78378eb 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_jpeg.py
@@ -41,7 +41,7 @@
         # Use a manual request with a linear tonemap so that the YUV and JPEG
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
+        req = its.objects.manual_capture_request(s, e, True, props)
 
         cap_yuv, cap_jpeg = cam.do_capture(req, [fmt_yuv, fmt_jpeg])
 
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
index 2e7804b..bfa6a28 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw.py
@@ -36,7 +36,7 @@
         # Use a manual request with a linear tonemap so that the YUV and RAW
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
+        req = its.objects.manual_capture_request(s, e, True, props)
 
         max_raw_size = \
                 its.objects.get_available_output_sizes("raw", props)[0]
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
index d02f84e..322af10 100644
--- a/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw10.py
@@ -36,7 +36,7 @@
         # Use a manual request with a linear tonemap so that the YUV and RAW
         # should look the same (once converted by the its.image module).
         e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
-        req = its.objects.manual_capture_request(s, e, True)
+        req = its.objects.manual_capture_request(s, e, True, props)
 
         max_raw10_size = \
                 its.objects.get_available_output_sizes("raw10", props)[0]
diff --git a/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py b/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py
new file mode 100644
index 0000000..b3cca0b
--- /dev/null
+++ b/apps/CameraITS/tests/scene1/test_yuv_plus_raw12.py
@@ -0,0 +1,68 @@
+# 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 its.target
+import os.path
+import math
+
+def main():
+    """Test capturing a single frame as both RAW12 and YUV outputs.
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+
+    THRESHOLD_MAX_RMS_DIFF = 0.035
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        its.caps.skip_unless(its.caps.compute_target_exposure(props) and
+                             its.caps.raw12(props) and
+                             its.caps.per_frame_control(props))
+
+        # Use a manual request with a linear tonemap so that the YUV and RAW
+        # should look the same (once converted by the its.image module).
+        e, s = its.target.get_target_exposure_combos(cam)["midExposureTime"]
+        req = its.objects.manual_capture_request(s, e, True, props)
+
+        max_raw12_size = \
+                its.objects.get_available_output_sizes("raw12", props)[0]
+        w,h = its.objects.get_available_output_sizes(
+                "yuv", props, (1920, 1080), max_raw12_size)[0]
+        cap_raw, cap_yuv = cam.do_capture(req,
+                [{"format":"raw12"},
+                 {"format":"yuv", "width":w, "height":h}])
+
+        img = its.image.convert_capture_to_rgb_image(cap_yuv)
+        its.image.write_image(img, "%s_yuv.jpg" % (NAME), True)
+        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
+        rgb0 = its.image.compute_image_means(tile)
+
+        # Raw shots are 1/2 x 1/2 smaller after conversion to RGB, so scale the
+        # tile appropriately.
+        img = its.image.convert_capture_to_rgb_image(cap_raw, props=props)
+        its.image.write_image(img, "%s_raw.jpg" % (NAME), True)
+        tile = its.image.get_image_patch(img, 0.475, 0.475, 0.05, 0.05)
+        rgb1 = its.image.compute_image_means(tile)
+
+        rms_diff = math.sqrt(
+                sum([pow(rgb0[i] - rgb1[i], 2.0) for i in range(3)]) / 3.0)
+        print "RMS difference:", rms_diff
+        assert(rms_diff < THRESHOLD_MAX_RMS_DIFF)
+
+if __name__ == '__main__':
+    main()
+
diff --git a/apps/CameraITS/tests/scene2/SampleTarget.jpg b/apps/CameraITS/tests/scene2/SampleTarget.jpg
new file mode 100644
index 0000000..c054f7e
--- /dev/null
+++ b/apps/CameraITS/tests/scene2/SampleTarget.jpg
Binary files differ
diff --git a/apps/CameraITS/tests/scene2/test_faces.py b/apps/CameraITS/tests/scene2/test_faces.py
new file mode 100644
index 0000000..cce74e7
--- /dev/null
+++ b/apps/CameraITS/tests/scene2/test_faces.py
@@ -0,0 +1,102 @@
+# Copyright 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.
+
+import its.image
+import its.device
+import its.objects
+import os.path
+
+def main():
+    """Test face detection.
+    """
+    NAME = os.path.basename(__file__).split(".")[0]
+    NUM_TEST_FRAMES = 20
+    FD_MODE_OFF = 0
+    FD_MODE_SIMPLE = 1
+    FD_MODE_FULL = 2
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+        fd_modes = props['android.statistics.info.availableFaceDetectModes']
+        a = props['android.sensor.info.activeArraySize']
+        aw, ah = a['right'] - a['left'], a['bottom'] - a['top']
+        cam.do_3a()
+        for fd_mode in fd_modes:
+            assert(FD_MODE_OFF <= fd_mode <= FD_MODE_FULL)
+            req = its.objects.auto_capture_request()
+            req['android.statistics.faceDetectMode'] = fd_mode
+            caps = cam.do_capture([req]*NUM_TEST_FRAMES)
+            for i,cap in enumerate(caps):
+                md = cap['metadata']
+                assert(md['android.statistics.faceDetectMode'] == fd_mode)
+                faces = md['android.statistics.faces']
+
+                # 0 faces should be returned for OFF mode
+                if fd_mode == FD_MODE_OFF:
+                    assert(len(faces) == 0)
+                    continue
+                # Face detection could take several frames to warm up,
+                # but it should detect at least one face in last frame
+                if i == NUM_TEST_FRAMES - 1:
+                    if len(faces) == 0:
+                        print "Error: no face detected in mode", fd_mode
+                        assert(0)
+                if len(faces) == 0:
+                    continue
+
+                print "Frame %d face metadata:" % i
+                print "  Faces:", faces
+                print ""
+
+                face_scores = [face['score'] for face in faces]
+                face_rectangles = [face['bounds'] for face in faces]
+                for score in face_scores:
+                    assert(score >= 1 and score <= 100)
+                # Face bounds should be within active array
+                for rect in face_rectangles:
+                    assert(rect['top'] < rect['bottom'])
+                    assert(rect['left'] < rect['right'])
+                    assert(0 <= rect['top'] <= ah)
+                    assert(0 <= rect['bottom'] <= ah)
+                    assert(0 <= rect['left'] <= aw)
+                    assert(0 <= rect['right'] <= aw)
+
+                # Face landmarks are reported if and only if fd_mode is FULL
+                # Face ID should be -1 for SIMPLE and unique for FULL
+                if fd_mode == FD_MODE_SIMPLE:
+                    for face in faces:
+                        assert('leftEye' not in face)
+                        assert('rightEye' not in face)
+                        assert('mouth' not in face)
+                        assert(face['id'] == -1)
+                elif fd_mode == FD_MODE_FULL:
+                    face_ids = [face['id'] for face in faces]
+                    assert(len(face_ids) == len(set(face_ids)))
+                    # Face landmarks should be within face bounds
+                    for face in faces:
+                        left_eye = face['leftEye']
+                        right_eye = face['rightEye']
+                        mouth = face['mouth']
+                        l, r = face['bounds']['left'], face['bounds']['right']
+                        t, b = face['bounds']['top'], face['bounds']['bottom']
+                        assert(l <= left_eye['x'] <= r)
+                        assert(t <= left_eye['y'] <= b)
+                        assert(l <= right_eye['x'] <= r)
+                        assert(t <= right_eye['y'] <= b)
+                        assert(l <= mouth['x'] <= r)
+                        assert(t <= mouth['y'] <= b)
+
+if __name__ == '__main__':
+    main()
+
diff --git a/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py b/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py
new file mode 100644
index 0000000..e96a9ee
--- /dev/null
+++ b/apps/CameraITS/tests/scene3/test_reprocess_edge_enhancement.py
@@ -0,0 +1,208 @@
+# 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 its.target
+import math
+import matplotlib
+import matplotlib.pyplot
+import numpy
+import os.path
+import pylab
+
+
+def test_edge_mode(cam, edge_mode, sensitivity, exp, fd, out_surface,
+                   reprocess_format=None):
+    """Return sharpness of the output image and the capture result metadata
+       for a capture request with the given edge mode, sensitivity, exposure
+       time, focus distance, output surface parameter, and reprocess format
+       (None for a regular request.)
+
+    Args:
+        cam: An open device session.
+        edge_mode: Edge mode for the request as defined in android.edge.mode
+        sensitivity: Sensitivity for the request as defined in
+            android.sensor.sensitivity
+        exp: Exposure time for the request as defined in
+            android.sensor.exposureTime.
+        fd: Focus distance for the request as defined in
+            android.lens.focusDistance
+        output_surface: Specifications of the output image format and size.
+        reprocess_format: (Optional) The reprocessing format. If not None,
+                reprocessing will be enabled.
+
+    Returns:
+        Object containing reported edge mode and the sharpness of the output
+        image, keyed by the following strings:
+            "edge_mode"
+            "sharpness"
+    """
+
+    NAME = os.path.basename(__file__).split(".")[0]
+    NUM_SAMPLES = 4
+
+    req = its.objects.manual_capture_request(sensitivity, exp)
+    req["android.lens.focusDistance"] = fd
+    req["android.edge.mode"] = edge_mode
+    if (reprocess_format != None):
+        req["android.reprocess.effectiveExposureFactor"] = 1.0
+
+    sharpness_list = []
+    for n in range(NUM_SAMPLES):
+        cap = cam.do_capture(req, out_surface, reprocess_format)
+        img = its.image.decompress_jpeg_to_rgb_image(cap["data"])
+        if n == 0:
+            its.image.write_image(img, "%s_reprocess_fmt_%s_edge=%d.jpg" %
+                (NAME, reprocess_format, edge_mode))
+            res_edge_mode = cap["metadata"]["android.edge.mode"]
+        tile = its.image.get_image_patch(img, 0.45, 0.45, 0.1, 0.1)
+        sharpness_list.append(its.image.compute_image_sharpness(tile))
+
+    ret = {}
+    ret["edge_mode"] = res_edge_mode
+    ret["sharpness"] = numpy.mean(sharpness_list)
+
+    return ret
+
+def main():
+    """Test that the android.edge.mode param is applied when set for
+       reprocessing requests.
+
+    Capture non-reprocess images for each edge mode and calculate their
+    sharpness as a baseline.
+
+    Capture reprocessed images for each supported reprocess format and edge_mode
+    mode. Calculate the sharpness of reprocessed images and compare them against
+    the sharpess of non-reprocess images.
+    """
+
+    THRESHOLD_RELATIVE_SHARPNESS_DIFF = 0.1
+
+    with its.device.ItsSession() as cam:
+        props = cam.get_camera_properties()
+
+        its.caps.skip_unless(its.caps.read_3a(props) and
+                             its.caps.per_frame_control(props) and
+                             its.caps.edge_mode(props, 0) and
+                             (its.caps.yuv_reprocess(props) or
+                              its.caps.private_reprocess(props)))
+
+        # If reprocessing is supported, ZSL EE mode must be avaiable.
+        assert(its.caps.edge_mode(props, 3))
+
+        reprocess_formats = []
+        if (its.caps.yuv_reprocess(props)):
+            reprocess_formats.append("yuv")
+        if (its.caps.private_reprocess(props)):
+            reprocess_formats.append("private")
+
+        size = its.objects.get_available_output_sizes("jpg", props)[0]
+        out_surface = {"width":size[0], "height":size[1], "format":"jpg"}
+
+        # Get proper sensitivity, exposure time, and focus distance.
+        s,e,_,_,fd = cam.do_3a(get_results=True)
+
+        # Get the sharpness for each edge mode for regular requests
+        sharpness_regular = []
+        edge_mode_reported_regular = []
+        for edge_mode in range(4):
+            # Skip unavailable modes
+            if not its.caps.edge_mode(props, edge_mode):
+                edge_mode_reported_regular.append(edge_mode)
+                sharpness_regular.append(0)
+                continue
+            ret = test_edge_mode(cam, edge_mode, s, e, fd, out_surface)
+            edge_mode_reported_regular.append(ret["edge_mode"])
+            sharpness_regular.append(ret["sharpness"])
+
+        print "Reported edge modes:", edge_mode_reported_regular
+        print "Sharpness with EE mode [0,1,2,3]:", sharpness_regular
+
+        # Get the sharpness for each reprocess format and edge mode for
+        # reprocess requests.
+        sharpnesses_reprocess = []
+        edge_mode_reported_reprocess = []
+
+        for reprocess_format in reprocess_formats:
+            # List of sharpness
+            sharpnesses = []
+            edge_mode_reported = []
+            for edge_mode in range(4):
+                # Skip unavailable modes
+                if not its.caps.edge_mode(props, edge_mode):
+                    edge_mode_reported.append(edge_mode)
+                    sharpnesses.append(0)
+                    continue
+
+                ret = test_edge_mode(cam, edge_mode, s, e, fd, out_surface,
+                    reprocess_format)
+                edge_mode_reported.append(ret["edge_mode"])
+                sharpnesses.append(ret["sharpness"])
+
+            sharpnesses_reprocess.append(sharpnesses)
+            edge_mode_reported_reprocess.append(edge_mode_reported)
+
+            print "Reported edge modes:", edge_mode_reported
+            print "Sharpness with EE mode [0,1,2,3] for %s reprocess:" % \
+                (reprocess_format) , sharpnesses
+
+
+        # Verify HQ(2) is sharper than OFF(0)
+        assert(sharpness_regular[2] > sharpness_regular[0])
+
+        # Verify ZSL(3) is similar to OFF(0)
+        assert(numpy.isclose(sharpness_regular[3], sharpness_regular[0],
+                             THRESHOLD_RELATIVE_SHARPNESS_DIFF))
+
+        # Verify OFF(0) is not sharper than FAST(1)
+        assert(sharpness_regular[1] >
+               sharpness_regular[0] * (1.0 - THRESHOLD_RELATIVE_SHARPNESS_DIFF))
+
+        # Verify FAST(1) is not sharper than HQ(2)
+        assert(sharpness_regular[2] >
+               sharpness_regular[1] * (1.0 - THRESHOLD_RELATIVE_SHARPNESS_DIFF))
+
+        for reprocess_format in range(len(reprocess_formats)):
+            # Verify HQ(2) is sharper than OFF(0)
+            assert(sharpnesses_reprocess[reprocess_format][2] >
+                   sharpnesses_reprocess[reprocess_format][0])
+
+            # Verify ZSL(3) is similar to OFF(0)
+            assert(numpy.isclose(sharpnesses_reprocess[reprocess_format][3],
+                                 sharpnesses_reprocess[reprocess_format][0],
+                                 THRESHOLD_RELATIVE_SHARPNESS_DIFF))
+
+            # Verify OFF(0) is not sharper than FAST(1)
+            assert(sharpnesses_reprocess[reprocess_format][1] >
+                   sharpnesses_reprocess[reprocess_format][0] *
+                   (1.0 - THRESHOLD_RELATIVE_SHARPNESS_DIFF))
+
+            # Verify FAST(1) is not sharper than HQ(2)
+            assert(sharpnesses_reprocess[reprocess_format][2] >
+                   sharpnesses_reprocess[reprocess_format][1] *
+                   (1.0 - THRESHOLD_RELATIVE_SHARPNESS_DIFF))
+
+            # Verify reprocessing HQ(2) is similar to regular HQ(2) relative to
+            # OFF(0)
+            assert(numpy.isclose(sharpnesses_reprocess[reprocess_format][2] /
+                                    sharpnesses_reprocess[reprocess_format][0],
+                                 sharpness_regular[2] / sharpness_regular[0],
+                                 THRESHOLD_RELATIVE_SHARPNESS_DIFF))
+
+if __name__ == '__main__':
+    main()
+
diff --git a/apps/CameraITS/tools/config.py b/apps/CameraITS/tools/config.py
index 6e83412..52929aa 100644
--- a/apps/CameraITS/tools/config.py
+++ b/apps/CameraITS/tools/config.py
@@ -44,7 +44,7 @@
     # Command line args, ignoring any args that will be passed down to the
     # ItsSession constructor.
     args = [s for s in sys.argv if s[:6] not in \
-            ["reboot", "camera", "target", "noinit"]]
+            ["reboot", "camera", "target", "device"]]
 
     if len(args) == 1:
         with its.device.ItsSession() as cam:
diff --git a/apps/CameraITS/tools/convert_yuv_to_jpg.py b/apps/CameraITS/tools/convert_yuv_to_jpg.py
new file mode 100644
index 0000000..4498c2a
--- /dev/null
+++ b/apps/CameraITS/tools/convert_yuv_to_jpg.py
@@ -0,0 +1,37 @@
+# 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 sys
+
+def main():
+    """Open a YUV420 file and save it as a JPEG.
+
+    Command line args:
+        filename.yuv: The YUV420 file to open.
+        w: The width of the image.
+        h: The height of the image.
+        layout: The layout of the data, in ["planar", "nv21"].
+    """
+    if len(sys.argv) != 5:
+        print "Usage: python %s <filename.yuv> <w> <h> <layout>"%(sys.argv[0])
+    else:
+        fname, w,h = sys.argv[1], int(sys.argv[2]), int(sys.argv[3])
+        layout = sys.argv[4]
+        img = its.image.load_yuv420_to_rgb_image(fname, w,h, layout=layout)
+        its.image.write_image(img, fname.replace(".yuv",".jpg"), False)
+
+if __name__ == '__main__':
+    main()
+
diff --git a/apps/CameraITS/tools/run_all_tests.py b/apps/CameraITS/tools/run_all_tests.py
index 2bbd387..dd12512 100644
--- a/apps/CameraITS/tools/run_all_tests.py
+++ b/apps/CameraITS/tools/run_all_tests.py
@@ -41,12 +41,20 @@
             "test_ev_compensation_advanced",
             "test_ev_compensation_basic",
             "test_yuv_plus_jpeg"
-        ]
+        ],
+        "scene2":[],
+        "scene3":[]
     }
 
     # Get all the scene0 and scene1 tests, which can be run using the same
     # physical setup.
-    scenes = ["scene0", "scene1"]
+    scenes = ["scene0", "scene1", "scene2", "scene3"]
+    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"
+    }
     tests = []
     for d in scenes:
         tests += [(d,s[:-3],os.path.join("tests", d, s))
@@ -58,6 +66,10 @@
     topdir = tempfile.mkdtemp()
     print "Saving output files to:", topdir, "\n"
 
+    device_id = its.device.get_device_id()
+    device_id_arg = "device=" + device_id
+    print "Testing device " + device_id
+
     camera_ids = []
     for s in sys.argv[1:]:
         if s[:7] == "camera=" and len(s) > 7:
@@ -68,7 +80,8 @@
         camera_ids_path = os.path.join(topdir, "camera_ids.txt")
         out_arg = "out=" + camera_ids_path
         cmd = ['python',
-               os.path.join(os.getcwd(),"tools/get_camera_ids.py"), out_arg]
+               os.path.join(os.getcwd(),"tools/get_camera_ids.py"), out_arg,
+               device_id_arg]
         retcode = subprocess.call(cmd,cwd=topdir)
         assert(retcode == 0)
         with open(camera_ids_path, "r") as f:
@@ -86,14 +99,6 @@
         for d in scenes:
             os.mkdir(os.path.join(topdir, camera_id, d))
 
-        out_path = os.path.join(topdir, camera_id, "scene.jpg")
-        out_arg = "out=" + out_path
-        cmd = ['python',
-               os.path.join(os.getcwd(),"tools/validate_scene.py"),
-               camera_id_arg, out_arg]
-        retcode = subprocess.call(cmd,cwd=topdir)
-        assert(retcode == 0)
-
         print "Start running ITS on camera: ", camera_id
         # Run each test, capturing stdout and stderr.
         summary = "ITS test result summary for camera " + camera_id + "\n"
@@ -102,7 +107,19 @@
         numnotmandatedfail = 0
         numfail = 0
 
+        prev_scene = ""
         for (scene,testname,testpath) in tests:
+            if scene != prev_scene and scene_req[scene] != None:
+                out_path = os.path.join(topdir, camera_id, scene+".jpg")
+                out_arg = "out=" + out_path
+                scene_arg = "scene=" + scene_req[scene]
+                cmd = ['python',
+                        os.path.join(os.getcwd(),"tools/validate_scene.py"),
+                        camera_id_arg, out_arg, scene_arg, device_id_arg]
+                retcode = subprocess.call(cmd,cwd=topdir)
+                assert(retcode == 0)
+                print "Start running tests for", scene
+            prev_scene = scene
             cmd = ['python', os.path.join(os.getcwd(),testpath)] + \
                   sys.argv[1:] + [camera_id_arg]
             outdir = os.path.join(topdir,camera_id,scene)
@@ -158,7 +175,7 @@
         summary_path = os.path.join(topdir, camera_id, "summary.txt")
         with open(summary_path, "w") as f:
             f.write(summary)
-        its.device.report_result(camera_id, result, summary_path)
+        its.device.report_result(device_id, camera_id, result, summary_path)
 
     print "ITS tests finished. Please go back to CtsVerifier and proceed"
 
diff --git a/apps/CameraITS/tools/validate_scene.py b/apps/CameraITS/tools/validate_scene.py
index e1e89f2..1f35163 100644
--- a/apps/CameraITS/tools/validate_scene.py
+++ b/apps/CameraITS/tools/validate_scene.py
@@ -16,17 +16,26 @@
 import its.device
 import its.objects
 import its.image
+import its.caps
+import re
 
 def main():
     """capture a yuv image and save it to argv[1]
     """
     camera_id = -1
     out_path = ""
+    scene_name = ""
+    scene_desc = "No requirement"
     for s in sys.argv[1:]:
         if s[:7] == "camera=" and len(s) > 7:
             camera_id = s[7:]
         elif s[:4] == "out=" and len(s) > 4:
             out_path = s[4:]
+        elif s[:6] == "scene=" and len(s) > 6:
+            scene_desc = s[6:]
+
+    if out_path != "":
+        scene_name = re.split("/|\.", out_path)[-2]
 
     if camera_id == -1:
         print "Error: need to specify which camera to use"
@@ -34,13 +43,16 @@
 
     with its.device.ItsSession() as cam:
         raw_input("Press Enter after placing camera " + camera_id +
-                " to frame the test scene")
+                " to frame the test scene: " + scene_name +
+                "\nThe scene setup should be: " + scene_desc )
         # Converge 3A prior to capture.
         cam.do_3a(do_af=True, lock_ae=True, lock_awb=True)
         props = cam.get_camera_properties()
         req = its.objects.fastest_auto_capture_request(props)
-        req["android.control.awbLock"] = True
-        req["android.control.aeLock"] = True
+        if its.caps.ae_lock(props):
+            req["android.control.awbLock"] = True
+        if its.caps.awb_lock(props):
+            req["android.control.aeLock"] = True
         while True:
             print "Capture an image to check the test scene"
             cap = cam.do_capture(req)
@@ -49,7 +61,8 @@
                 its.image.write_image(img, out_path)
             print "Please check scene setup in", out_path
             choice = raw_input(
-                "Is the image okay for ITS scene1? (Y/N)").lower()
+                "Is the image okay for ITS " + scene_name +\
+                "? (Y/N)").lower()
             if choice == "y":
                 break
             else:
diff --git a/apps/CtsVerifier/Android.mk b/apps/CtsVerifier/Android.mk
index dc5fda5..a752519 100644
--- a/apps/CtsVerifier/Android.mk
+++ b/apps/CtsVerifier/Android.mk
@@ -30,11 +30,18 @@
                                compatibility-common-util-devicesidelib_v2 \
                                cts-sensors-tests \
                                ctstestrunner \
+                               apache-commons-math \
+                               androidplot \
+                               ctsverifier-opencv \
+                               core-tests \
+                               android-support-v4  \
+                               mockito-target \
+                               mockwebserver \
+                               compatibility-device-util_v2 \
 
 LOCAL_PACKAGE_NAME := CtsVerifier
 
-LOCAL_JNI_SHARED_LIBRARIES := libctsverifier_jni \
-	#libcameraanalyzer # Needed for the disabled CameraAnalyzer tests
+LOCAL_JNI_SHARED_LIBRARIES := libctsverifier_jni libaudioloopback_jni
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
@@ -44,13 +51,51 @@
 
 include $(BUILD_PACKAGE)
 
+# Build CTS verifier framework as a libary.
+
+include $(CLEAR_VARS)
+
+define java-files-in
+$(sort $(patsubst ./%,%, \
+  $(shell cd $(LOCAL_PATH) ; \
+          find -L $(1) -maxdepth 1 -name *.java -and -not -name ".*") \
+ ))
+endef
+
+LOCAL_MODULE := cts-verifier-framework
+LOCAL_AAPT_FLAGS := --auto-add-overlay --extra-packages android.support.v4
+LOCAL_SDK_VERSION := current
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+LOCAL_SRC_FILES := \
+    $(call java-files-in, src/com/android/cts/verifier) \
+    $(call java-files-in, src/com/android/cts/verifier/backup) \
+    $(call all-java-files-under, src/android) \
+    $(call all-Iaidl-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 \
+                               compatibility-common-util-devicesidelib_v2 \
+                               compatibility-device-util_v2 \
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# opencv library
+include $(CLEAR_VARS)
+
+LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := \
+        ctsverifier-opencv:libs/opencv-android.jar
+
+include $(BUILD_MULTI_PREBUILT)
+
+
 notification-bot := $(call intermediates-dir-for,APPS,NotificationBot)/package.apk
+permission-app := $(call intermediates-dir-for,APPS,CtsPermissionApp)/package.apk
 
 # Builds and launches CTS Verifier on a device.
 .PHONY: cts-verifier
-cts-verifier: CtsVerifier adb NotificationBot
+cts-verifier: CtsVerifier adb NotificationBot CtsPermissionApp
 	adb install -r $(PRODUCT_OUT)/data/app/CtsVerifier/CtsVerifier.apk \
 		&& adb install -r $(notification-bot) \
+		&& adb install -r $(permission-app) \
 		&& adb shell "am start -n com.android.cts.verifier/.CtsVerifierActivity"
 
 #
@@ -87,10 +132,12 @@
 endif
 $(verifier-zip) : $(HOST_OUT)/CameraITS
 $(verifier-zip) : $(notification-bot)
+$(verifier-zip) : $(permission-app)
 $(verifier-zip) : $(call intermediates-dir-for,APPS,CtsVerifier)/package.apk | $(ACP)
 		$(hide) mkdir -p $(verifier-dir)
 		$(hide) $(ACP) -fp $< $(verifier-dir)/CtsVerifier.apk
 		$(ACP) -fp $(notification-bot) $(verifier-dir)/NotificationBot.apk
+		$(ACP) -fp $(permission-app) $(verifier-dir)/CtsPermissionApp.apk
 ifeq ($(HOST_OS),linux)
 		$(hide) $(ACP) -fp $(HOST_OUT)/bin/cts-usb-accessory $(verifier-dir)/cts-usb-accessory
 endif
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index cec1cca..e03f5dd 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -18,9 +18,9 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
       package="com.android.cts.verifier"
       android:versionCode="5"
-      android:versionName="5.1_r4">
+      android:versionName="6.0_r2">
 
-    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="21"/>
+    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="23"/>
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -57,6 +57,7 @@
     <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"/>
 
     <!-- Needed by the Audio Quality Verifier to store the sound samples that will be mailed. -->
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@@ -109,6 +110,26 @@
         <!-- A generic activity for intent based tests -->
         <activity android:name=".IntentDrivenTestActivity"/>
 
+        <activity android:name=".admin.DeviceAdminKeyguardDisabledFeaturesActivity"
+                android:label="@string/da_kg_disabled_features_test"
+                android:configChanges="keyboardHidden|orientation|screenSize">
+            <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_device_admin" />
+        </activity>
+
+        <activity android:name=".admin.RedactedNotificationKeyguardDisabledFeaturesActivity"
+                android:label="@string/rn_kg_disabled_features_test"
+                android:configChanges="keyboardHidden|orientation|screenSize">
+            <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_device_admin" />
+        </activity>
+
         <activity android:name=".admin.ScreenLockTestActivity"
                 android:label="@string/da_screen_lock_test"
                 android:configChanges="keyboardHidden|orientation|screenSize">
@@ -121,15 +142,6 @@
                        android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
         </activity>
 
-        <receiver android:name=".admin.TestDeviceAdminReceiver"
-                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=".backup.BackupTestActivity" android:label="@string/backup_test">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -353,6 +365,29 @@
             <meta-data android:name="test_category" android:value="@string/test_category_security" />
         </activity>
 
+        <activity android:name=".security.FingerprintBoundKeysTest"
+                android:label="@string/sec_fingerprint_bound_key_test"
+                android:configChanges="keyboardHidden|orientation|screenSize" >
+            <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_security" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.fingerprint" />
+        </activity>
+        <activity android:name=".security.ScreenLockBoundKeysTest"
+                android:label="@string/sec_lock_bound_key_test"
+                android:configChanges="keyboardHidden|orientation|screenSize" >
+            <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_security" />
+            <meta-data android:name="test_excluded_features"
+                       android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
+        </activity>
         <activity android:name=".security.LockConfirmBypassTest"
                 android:label="@string/lock_confirm_test_title"
                 android:configChanges="keyboardHidden|orientation|screenSize" >
@@ -401,6 +436,17 @@
             <meta-data android:name="test_required_features" android:value="android.hardware.location.gps" />
         </activity>
 
+        <activity android:name=".net.ConnectivityScreenOffTestActivity"
+                android:label="@string/network_screen_off_test"
+                android:screenOrientation="portrait">
+            <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_networking" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.wifi" />
+        </activity>
+
         <activity android:name=".nfc.NfcTestActivity"
                 android:label="@string/nfc_test"
                 android:configChanges="keyboardHidden|orientation|screenSize">
@@ -430,6 +476,10 @@
                 android:label="@string/nfc_ndef_push_receiver"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
 
+        <activity android:name=".nfc.LlcpVersionActivity"
+                android:label="@string/nfc_llcp_version_check"
+                android:configChanges="keyboardHidden|orientation|screenSize" />
+
         <activity android:name=".nfc.TagVerifierActivity"
                 android:label="@string/nfc_tag_verifier"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
@@ -720,6 +770,31 @@
                        android:value="android.hardware.sensor.compass" />
         </activity>
 
+        <activity
+            android:name=".sensors.RVCVXCheckTestActivity"
+            android:keepScreenOn="true"
+            android:label="@string/snsr_rvcvxchk_test"
+            android:screenOrientation="locked" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.cts.intent.category.MANUAL_TEST_disabled"/>
+            </intent-filter>
+
+            <meta-data
+                android:name="test_category"
+                android:value="@string/test_category_sensors" />
+            <meta-data
+                android:name="test_required_features"
+                android:value="android.hardware.sensor.accelerometer:android.hardware.sensor.gyroscope:android.hardware.sensor.compass:android.hardware.camera.any" />
+        </activity>
+        <activity
+            android:name=".sensors.RVCVRecordActivity"
+            android:keepScreenOn="true"
+            android:label="@string/snsr_rvcvxchk_test_rec"
+            android:screenOrientation="locked" >
+        </activity>
+
+
         <!-- TODO: enable when a full set of verifications can be implemented -->
         <!--activity android:name=".sensors.RotationVectorTestActivity"
                   android:label="@string/snsr_rot_vec_test"
@@ -872,23 +947,6 @@
 
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any"/>
         </activity>
-<!-- Experimental. If re-enabling, libcameraanalyzer must be included in the build
-        <activity android:name=".camera.analyzer.CameraAnalyzerActivity"
-                 android:label="@string/camera_analyzer"
-                 android:screenOrientation="landscape">
-            <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_camera" />
-
-            <intent-filter>
-                <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
-            </intent-filter>
-            <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
-                android:resource="@xml/accessory_filter_adk" />
-        </activity>
--->
 
         <activity android:name=".camera.intents.CameraIntentsActivity"
                  android:label="@string/camera_intents">
@@ -962,6 +1020,17 @@
             <meta-data android:name="test_required_features" android:value="android.hardware.camera.any" />
         </activity>
 
+        <activity android:name=".camera.flashlight.CameraFlashlightActivity"
+                  android:label="@string/camera_flashlight_test"
+                  android:configChanges="keyboardHidden|orientation|screenSize">
+            <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_camera" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.camera.flash" />
+        </activity>
+
         <activity android:name=".usb.UsbAccessoryTestActivity"
                 android:label="@string/usb_accessory_test"
                 android:configChanges="keyboardHidden|orientation|screenSize">
@@ -1069,6 +1138,22 @@
                     android:value="android.software.leanback" />
         </activity>
 
+        <activity android:name=".security.KeyChainTest"
+                android:label="@string/keychain_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_security" />
+            <!-- KeyChain is only installed on communication-oriented devices inheriting core.mk -->
+            <meta-data android:name="test_excluded_features"
+                    android:value="android.hardware.type.watch" />
+            <meta-data android:name="test_excluded_features"
+                    android:value="android.hardware.type.television" />
+            <meta-data android:name="test_excluded_features"
+                    android:value="android.software.leanback" />
+        </activity>
+
         <activity android:name=".p2p.GoNegRequesterTestListActivity"
                 android:label="@string/p2p_go_neg_requester"
                 android:configChanges="keyboardHidden|orientation|screenSize" />
@@ -1133,8 +1218,6 @@
             <meta-data android:name="test_category" android:value="@string/test_category_other" />
             <meta-data android:name="test_required_features"
                     android:value="android.software.app_widgets" />
-            <meta-data android:name="test_excluded_features"
-                       android:value="android.software.leanback" />
         </activity>
 
         <activity android:name=".deskclock.DeskClockTestsActivity"
@@ -1166,6 +1249,23 @@
                        android:value="android.hardware.type.television:android.software.leanback" />
         </activity>
 -->
+          <activity
+                android:name="com.android.cts.verifier.sensors.DeviceSuspendTestActivity"
+                android:label="@string/snsr_device_suspend_test"
+                android:screenOrientation="nosensor" >
+            <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_sensors" />
+        </activity>
+
+        <receiver android:name="com.android.cts.verifier.sensors.DeviceSuspendTestActivity$AlarmReceiver">
+        </receiver>
+
+        <receiver android:name="com.android.cts.verifier.sensors.SignificantMotionTestActivity$AlarmReceiver">
+        </receiver>
+
         <activity
             android:name="com.android.cts.verifier.sensors.SignificantMotionTestActivity"
             android:label="@string/snsr_significant_motion_test"
@@ -1266,16 +1366,80 @@
                  android:label="@string/projection_service_name"
                  android:process=":projectionservice" />
 
-        <activity android:name=".managedprovisioning.DeviceOwnerTestActivity"
+        <activity android:name=".managedprovisioning.DeviceOwnerNegativeTestActivity"
                 android:label="@string/provisioning_device_owner">
             <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" />
+            <meta-data android:name="test_required_features" android:value="android.software.device_admin" />
         </activity>
 
+        <activity android:name=".managedprovisioning.DeviceOwnerPositiveTestActivity"
+                android:label="@string/positive_device_owner">
+            <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.device_admin" />
+        </activity>
+
+        <activity android:name=".managedprovisioning.DeviceOwnerPositiveTestActivity$CommandReceiver"
+                android:exported="false"
+                android:theme="@android:style/Theme.NoDisplay"
+                android:noHistory="true"
+                android:autoRemoveFromRecents="true"
+                android:stateNotNeeded="true">
+        </activity>
+
+        <activity android:name=".managedprovisioning.KeyguardDisabledFeaturesActivity"
+                android:label="@string/provisioning_byod_keyguard_disabled_features">
+        </activity>
+
+        <activity android:name=".managedprovisioning.WifiLockdownTestActivity"
+                android:label="@string/device_owner_wifi_lockdown_test">
+        </activity>
+
+        <activity android:name=".managedprovisioning.VpnTestActivity"
+                android:label="@string/device_owner_vpn_test">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.VPN" />
+                <category android:name="android.intent.category.DEFAULT"></category>
+            </intent-filter>
+        </activity>
+
+        <service android:name=".managedprovisioning.VpnTestActivity$MyTestVpnService"
+                android:permission="android.permission.BIND_VPN_SERVICE">
+            <intent-filter>
+                <action android:name="android.net.VpnService"/>
+            </intent-filter>
+        </service>
+
+        <activity android:name=".managedprovisioning.PermissionLockdownTestActivity"
+                android:label="@string/device_profile_owner_permission_lockdown_test">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_PERMISSION_LOCKDOWN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity-alias
+                android:name=".managedprovisioning.ManagedProfilePermissionLockdownTestActivity"
+                android:targetActivity=".managedprovisioning.PermissionLockdownTestActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity-alias>
+
+        <activity android:name=".managedprovisioning.AuthenticationBoundKeyTestActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.AUTH_BOUND_KEY_TEST" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
 
         <activity android:name=".managedprovisioning.ByodFlowTestActivity"
                 android:launchMode="singleTask"
@@ -1297,10 +1461,19 @@
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_QUERY" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_REMOVE" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_INSTALL_APK" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.CHECK_INTENT_FILTERS" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_IMAGE" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_VIDEO" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_AUDIO" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_KEYGUARD_DISABLED_FEATURES" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_LOCKNOW" />
                 <action android:name="com.android.cts.verifier.managedprovisioning.TEST_NFC_BEAM" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.TEST_CROSS_PROFILE_INTENTS_DIALOG" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.action.TEST_APP_LINKING_DIALOG" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.BYOD_SET_LOCATION_AND_CHECK" />
+                <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" />
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
         </activity>
@@ -1326,23 +1499,109 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".managedprovisioning.CrossProfileTestActivity">
+        <activity android:name=".managedprovisioning.HandleIntentActivity"
+                android:enabled="false">
             <intent-filter>
-                <action android:name="com.android.cts.verifier.managedprovisioning.CROSS_PROFILE" />
-                <category android:name="android.intent.category.DEFAULT"></category>
+                <!-- We need to have at least one activity listening to these intents on the device
+                     to test if these are forwarded from the managed profile to the parent or
+                     the other way around. -->
+                <action android:name="android.provider.MediaStore.RECORD_SOUND" />
+                <action android:name="android.speech.action.RECOGNIZE_SPEECH" />
+                <action android:name="android.app.action.SET_NEW_PASSWORD" />
+                <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
+                <action android:name="android.intent.action.WEB_SEARCH" />
+                <action android:name="android.intent.action.VIEW_DOWNLOADS" />
+                <action android:name="android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL" />
+                <action android:name="android.settings.SHOW_INPUT_METHOD_PICKER" />
+                <action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
+                <action android:name="com.android.settings.TTS_SETTINGS" />
+                <action android:name="android.settings.ZEN_MODE_SETTINGS" />
+                <action android:name="android.settings.BATTERY_SAVER_SETTINGS" />
+                <action android:name="android.settings.INPUT_METHOD_SETTINGS" />
+                <action android:name="android.settings.INPUT_METHOD_SUBTYPE_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.SEND" />
+                <action android:name="android.intent.action.SEND_MULTIPLE" />
+                <data android:mimeType="*/*" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.GET_CONTENT" />
+                <action android:name="android.intent.action.OPEN_DOCUMENT" />
+                <data android:mimeType="*/*" />
+                <category android:name="android.intent.category.OPENABLE" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.SENDTO" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="sms" />
+                <data android:scheme="smsto" />
+                <data android:scheme="mms" />
+                <data android:scheme="mmsto" />
+                <data android:scheme="mailto" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.CALL" />
+                <action android:name="android.intent.action.DIAL" />
+                <action android:name="android.intent.action.CALL_PRIVILEGED" />
+                <action android:name="android.intent.action.CALL_EMERGENCY" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="tel" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.INSERT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="content" />
+                <data android:mimeType="*/*" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="http" android:host="com.android.cts.verifier" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="http" />
+                <data android:mimeType="video/mp4" />
+                <data android:mimeType="audio/*" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:scheme="http" />
+                <data android:scheme="geo" />
+                <data android:scheme="market" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".managedprovisioning.WorkNotificationTestActivity">
+        <activity android:name=".managedprovisioning.CrossProfileTestActivity">
             <intent-filter>
-                <action android:name="com.android.cts.verifier.managedprovisioning.WORK_NOTIFICATION" />
-                <action android:name="com.android.cts.verifier.managedprovisioning.CLEAR_WORK_NOTIFICATION" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.CROSS_PROFILE_TO_PERSONAL" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.CROSS_PROFILE_TO_WORK" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".managedprovisioning.WorkStatusTestActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.verifier.managedprovisioning.WORK_STATUS_ICON" />
+                <action android:name="com.android.cts.verifier.managedprovisioning.WORK_STATUS_TOAST" />
                 <category android:name="android.intent.category.DEFAULT"></category>
             </intent-filter>
         </activity>
 
         <receiver android:name=".managedprovisioning.DeviceAdminTestReceiver"
-                android:label="@string/provisioning_byod_device_admin"
+                android:label="@string/afw_device_admin"
                 android:permission="android.permission.BIND_DEVICE_ADMIN">
             <meta-data android:name="android.app.device_admin"
                        android:resource="@xml/device_admin_byod" />
@@ -1427,6 +1686,29 @@
                     android:value="android.software.live_tv" />
         </activity>
 
+        <activity android:name=".tv.TimeShiftTestActivity"
+                android:label="@string/tv_time_shift_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_tv" />
+            <meta-data android:name="test_required_features"
+                    android:value="android.software.live_tv" />
+        </activity>
+
+        <activity android:name=".tv.AppLinkTestActivity"
+            android:label="@string/tv_app_link_test"
+            android:launchMode="singleTask">
+            <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_tv" />
+            <meta-data android:name="test_required_features"
+                android:value="android.software.live_tv" />
+        </activity>
+
         <activity android:name=".screenpinning.ScreenPinningTestActivity"
             android:label="@string/screen_pinning_test">
             <intent-filter>
@@ -1438,16 +1720,119 @@
                        android:value="android.hardware.type.television:android.software.leanback:android.hardware.type.watch" />
         </activity>
 
-        <activity android:name=".tv.MockTvInputSettingsActivity">
+        <activity android:name=".tv.MockTvInputSetupActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
         </activity>
 
-        <activity android:name=".tv.MockTvInputSetupActivity">
+        <activity android:name=".audio.HifiUltrasoundTestActivity"
+                android:label="@string/hifi_ultrasound_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_audio" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.microphone" />
+        </activity>
+
+        <activity android:name=".audio.HifiUltrasoundSpeakerTestActivity"
+                android:label="@string/hifi_ultrasound_speaker_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_audio" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.audio.output" />
+        </activity>
+
+        <activity android:name=".audio.AudioOutputDeviceNotificationsActivity"
+                  android:label="@string/audio_out_devices_notifications_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.audio.output" />
+        </activity>
+
+        <activity android:name=".audio.AudioInputDeviceNotificationsActivity"
+                  android:label="@string/audio_in_devices_notifications_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>
+
+        <activity android:name=".audio.AudioOutputRoutingNotificationsActivity"
+                  android:label="@string/audio_output_routingnotifications_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.audio.output" />
+            </activity>
+
+        <activity android:name=".audio.AudioInputRoutingNotificationsActivity"
+                  android:label="@string/audio_input_routingnotifications_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>
+
+        <activity android:name=".audio.AudioLoopbackActivity"
+                  android:label="@string/audio_loopback_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" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.audio.output" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.watch" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.television" />
+        </activity>
+
+        <activity android:name=".audio.AudioFrequencyLineActivity"
+                  android:label="@string/audio_frequency_line_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" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.audio.output" />
+        </activity>
+
+        <activity android:name=".audio.AudioFrequencySpeakerActivity"
+                  android:label="@string/audio_frequency_speaker_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.audio.output" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.usb.host" />
+        </activity>
+
+        <activity android:name=".audio.AudioFrequencyMicActivity"
+                  android:label="@string/audio_frequency_mic_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" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.audio.output" />
+            <meta-data android:name="test_required_features" android:value="android.hardware.usb.host" />
         </activity>
 
         <service android:name=".tv.MockTvInputService"
diff --git a/apps/CtsVerifier/create_test_certs.sh b/apps/CtsVerifier/create_test_certs.sh
new file mode 100755
index 0000000..b59974a
--- /dev/null
+++ b/apps/CtsVerifier/create_test_certs.sh
@@ -0,0 +1,85 @@
+#!/bin/bash
+
+#
+# Creates or overwrites 3 files in ./res/raw:
+#   - cacert.der
+#   - userkey.der
+#   - usercert.der
+#
+
+tmpdir=$(mktemp -d './XXXXXXXX')
+trap 'rm -r ${tmpdir}; echo; exit 1' EXIT INT QUIT
+
+# CA_default defined in openssl.cnf
+CA_DIR='demoCA'
+
+SUBJECT=\
+'/C=US'\
+'/ST=CA'\
+'/L=Mountain View'\
+'/O=Android'\
+'/CN=localhost'
+PASSWORD='androidtest'
+
+echo "Creating directory '$CA_DIR'..."
+mkdir -p "$tmpdir"/"$CA_DIR"/newcerts \
+    && echo '01' > "$tmpdir"/"$CA_DIR"/serial \
+    && touch "$tmpdir"/"$CA_DIR"/index.txt
+
+echo "Generating CA certificate..."
+(cd "$tmpdir" \
+    && openssl req \
+        -new \
+        -x509 \
+        -days 3650 \
+        -extensions v3_ca \
+        -keyout 'cakey.pem' \
+        -out 'cacert.pem' \
+        -subj "$SUBJECT" \
+        -passout 'pass:'"$PASSWORD" \
+    && openssl x509 \
+        -outform DER \
+        -in 'cacert.pem' \
+        -out 'cacert.der')
+
+echo "Generating user key..."
+(cd "$tmpdir" \
+    && openssl req \
+        -newkey rsa:2048 \
+        -sha256 \
+        -keyout 'userkey.pem' \
+        -nodes \
+        -days 3650 \
+        -out 'userkey.req' \
+        -subj "$SUBJECT" \
+    && openssl pkcs8 \
+        -topk8 \
+        -outform DER \
+        -in 'userkey.pem' \
+        -out 'userkey.der' \
+        -nocrypt)
+
+echo "Generating user certificate..."
+(cd "$tmpdir" \
+    && openssl ca \
+        -out 'usercert.pem' \
+        -in 'userkey.req' \
+        -cert 'cacert.pem' \
+        -keyfile 'cakey.pem' \
+        -days 3650 \
+        -passin 'pass:'"$PASSWORD" \
+        -batch \
+    && openssl x509 \
+        -outform DER \
+        -in 'usercert.pem' \
+        -out 'usercert.der')
+
+# Copy important files to raw resources directory
+cp \
+    "$tmpdir"/cacert.der \
+    "$tmpdir"/userkey.der \
+    "$tmpdir"/usercert.der \
+    'res/raw/'
+
+echo "Finished"
+exit
diff --git a/apps/CtsVerifier/jni/audio_loopback/Android.mk b/apps/CtsVerifier/jni/audio_loopback/Android.mk
new file mode 100644
index 0000000..3dfbc34
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/Android.mk
@@ -0,0 +1,28 @@
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE      := libaudioloopback_jni
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES   := \
+	sles.cpp \
+	jni_sles.c
+
+LOCAL_C_INCLUDES := \
+        system/media/audio_utils/include \
+        frameworks/wilhelm/include
+
+LOCAL_SHARED_LIBRARIES := \
+	libutils \
+	libcutils \
+	libOpenSLES \
+	libnbaio \
+	liblog \
+	libaudioutils
+
+LOCAL_PRELINK_MODULE := false
+
+LOCAL_LDFLAGS := -Wl,--hash-style=sysv
+LOCAL_CFLAGS := -DSTDC_HEADERS
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/apps/CtsVerifier/jni/audio_loopback/jni_sles.c b/apps/CtsVerifier/jni/audio_loopback/jni_sles.c
new file mode 100644
index 0000000..a865078
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/jni_sles.c
@@ -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.
+ */
+
+#include <android/log.h>
+#include "sles.h"
+#include "jni_sles.h"
+#include <stdio.h>
+#include <stddef.h>
+
+/////
+JNIEXPORT jlong JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesInit
+  (JNIEnv *env __unused, jobject obj __unused, jint samplingRate, jint frameCount, jint micSource) {
+
+    sles_data * pSles = NULL;
+
+    if (slesInit(&pSles, samplingRate, frameCount, micSource) != SLES_FAIL) {
+
+        return (long)pSles;
+    }
+    // FIXME This should be stored as a (long) field in the object,
+    //       so that incorrect Java code could not synthesize a bad sles pointer.
+    return 0;
+}
+
+JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesProcessNext
+  (JNIEnv *env __unused, jobject obj __unused, jlong sles, jdoubleArray samplesArray,
+          jlong offset) {
+    sles_data * pSles= (sles_data*) ((long)sles);
+
+    long maxSamples = (*env)->GetArrayLength(env, samplesArray);
+    double *pSamples = (*env)->GetDoubleArrayElements(env, samplesArray,0);
+
+    long availableSamples = maxSamples-offset;
+    double *pCurrentSample = pSamples+offset;
+
+    SLES_PRINTF("jni slesProcessNext pSles:%p, currentSample %p, availableSamples %ld ", pSles,
+            pCurrentSample, availableSamples);
+
+    int samplesRead = slesProcessNext(pSles, pCurrentSample, availableSamples);
+
+    return samplesRead;
+}
+
+JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesDestroy
+  (JNIEnv *env __unused, jobject obj __unused, jlong sles) {
+    sles_data * pSles= (sles_data*) ((long) sles);
+
+    int status = slesDestroy(&pSles);
+
+    return status;
+}
diff --git a/apps/CtsVerifier/jni/audio_loopback/jni_sles.h b/apps/CtsVerifier/jni/audio_loopback/jni_sles.h
new file mode 100644
index 0000000..7bff040
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/jni_sles.h
@@ -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.
+ */
+
+#include <jni.h>
+
+#ifndef _Included_org_drrickorang_loopback_jni
+#define _Included_org_drrickorang_loopback_jni
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+////////////////////////
+JNIEXPORT jlong JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesInit
+  (JNIEnv *, jobject, jint, jint, jint );
+
+JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesProcessNext
+  (JNIEnv *, jobject , jlong, jdoubleArray, jlong );
+
+JNIEXPORT jint JNICALL Java_com_android_cts_verifier_audio_NativeAudioThread_slesDestroy
+  (JNIEnv *, jobject , jlong );
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif //_Included_org_drrickorang_loopback_jni
diff --git a/apps/CtsVerifier/jni/audio_loopback/sles.cpp b/apps/CtsVerifier/jni/audio_loopback/sles.cpp
new file mode 100644
index 0000000..7859d35
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/sles.cpp
@@ -0,0 +1,655 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+////////////////////////////////////////////
+/// Actual sles functions.
+
+
+// Test program to record from default audio input and playback to default audio output.
+// It will generate feedback (Larsen effect) if played through on-device speakers,
+// or acts as a delay if played through headset.
+
+#include "sles.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+
+#include <assert.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+int slesInit(sles_data ** ppSles, int samplingRate, int frameCount, int micSource) {
+    int status = SLES_FAIL;
+    if (ppSles != NULL) {
+        sles_data * pSles = (sles_data*) calloc(1, sizeof (sles_data));
+
+        SLES_PRINTF("malloc %d 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);
+        }
+    }
+    return status;
+}
+int slesDestroy(sles_data ** ppSles) {
+    int status = SLES_FAIL;
+    if (ppSles != NULL) {
+        slesDestroyServer(*ppSles);
+
+        if (*ppSles != NULL)
+        {
+            free(*ppSles);
+            *ppSles = 0;
+        }
+        status = SLES_SUCCESS;
+    }
+    return status;
+}
+
+#define ASSERT_EQ(x, y) do { if ((x) == (y)) ; else { fprintf(stderr, "0x%x != 0x%x\n", \
+        (unsigned) (x), (unsigned) (y)); assert((x) == (y)); } } while (0)
+
+
+// Called after audio recorder fills a buffer with data
+static void recorderCallback(SLAndroidSimpleBufferQueueItf caller __unused, void *context) {
+    sles_data *pSles = (sles_data*) context;
+    if (pSles != NULL) {
+
+
+
+        SLresult result;
+
+        pthread_mutex_lock(&(pSles->mutex));
+        //ee  SLES_PRINTF("<R");
+
+        // We should only be called when a recording buffer is done
+        assert(pSles->rxFront <= pSles->rxBufCount);
+        assert(pSles->rxRear <= pSles->rxBufCount);
+        assert(pSles->rxFront != pSles->rxRear);
+        char *buffer = pSles->rxBuffers[pSles->rxFront];
+
+        // Remove buffer from record queue
+        if (++pSles->rxFront > pSles->rxBufCount) {
+            pSles->rxFront = 0;
+        }
+
+        ssize_t actual = audio_utils_fifo_write(&(pSles->fifo), buffer,
+                (size_t) pSles->bufSizeInFrames);
+        if (actual != (ssize_t) pSles->bufSizeInFrames) {
+            write(1, "?", 1);
+        }
+
+        // This is called by a realtime (SCHED_FIFO) thread,
+        // and it is unsafe to do I/O as it could block for unbounded time.
+        // Flash filesystem is especially notorious for blocking.
+        if (pSles->fifo2Buffer != NULL) {
+            actual = audio_utils_fifo_write(&(pSles->fifo2), buffer,
+                    (size_t) pSles->bufSizeInFrames);
+            if (actual != (ssize_t) pSles->bufSizeInFrames) {
+                write(1, "?", 1);
+            }
+        }
+
+        // Enqueue this same buffer for the recorder to fill again.
+        result = (*(pSles->recorderBufferQueue))->Enqueue(pSles->recorderBufferQueue, buffer,
+                pSles->bufSizeInBytes);
+        ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+        // Update our model of the record queue
+        SLuint32 rxRearNext = pSles->rxRear+1;
+        if (rxRearNext > pSles->rxBufCount) {
+            rxRearNext = 0;
+        }
+        assert(rxRearNext != pSles->rxFront);
+        pSles->rxBuffers[pSles->rxRear] = buffer;
+        pSles->rxRear = rxRearNext;
+
+
+
+        //ee  SLES_PRINTF("r>");
+        pthread_mutex_unlock(&(pSles->mutex));
+
+    } //pSles not null
+}
+
+
+// Called after audio player empties a buffer of data
+static void playerCallback(SLBufferQueueItf caller __unused, void *context) {
+    sles_data *pSles = (sles_data*) context;
+    if (pSles != NULL) {
+
+        SLresult result;
+
+        pthread_mutex_lock(&(pSles->mutex));
+        //ee  SLES_PRINTF("<P");
+
+        // Get the buffer that just finished playing
+        assert(pSles->txFront <= pSles->txBufCount);
+        assert(pSles->txRear <= pSles->txBufCount);
+        assert(pSles->txFront != pSles->txRear);
+        char *buffer = pSles->txBuffers[pSles->txFront];
+        if (++pSles->txFront > pSles->txBufCount) {
+            pSles->txFront = 0;
+        }
+
+
+        ssize_t actual = audio_utils_fifo_read(&(pSles->fifo), buffer, pSles->bufSizeInFrames);
+        if (actual != (ssize_t) pSles->bufSizeInFrames) {
+            write(1, "/", 1);
+            // on underrun from pipe, substitute silence
+            memset(buffer, 0, pSles->bufSizeInFrames * pSles->channels * sizeof(short));
+        }
+
+        if (pSles->injectImpulse == -1) {
+            // Experimentally, a single frame impulse was insufficient to trigger feedback.
+            // Also a Nyquist frequency signal was also insufficient, probably because
+            // the response of output and/or input path was not adequate at high frequencies.
+            // This short burst of a few cycles of square wave at Nyquist/4 was found to work well.
+            for (unsigned i = 0; i < pSles->bufSizeInFrames / 8; i += 8) {
+                for (int j = 0; j < 8; j++) {
+                    for (unsigned k = 0; k < pSles->channels; k++) {
+                        ((short *)buffer)[(i+j)*pSles->channels+k] = j < 4 ? 0x7FFF : 0x8000;
+                    }
+                }
+            }
+            pSles->injectImpulse = 0;
+        }
+
+        // Enqueue the filled buffer for playing
+        result = (*(pSles->playerBufferQueue))->Enqueue(pSles->playerBufferQueue, buffer,
+                pSles->bufSizeInBytes);
+        ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+        // Update our model of the player queue
+        assert(pSles->txFront <= pSles->txBufCount);
+        assert(pSles->txRear <= pSles->txBufCount);
+        SLuint32 txRearNext = pSles->txRear+1;
+        if (txRearNext > pSles->txBufCount) {
+            txRearNext = 0;
+        }
+        assert(txRearNext != pSles->txFront);
+        pSles->txBuffers[pSles->txRear] = buffer;
+        pSles->txRear = txRearNext;
+
+
+        //ee    SLES_PRINTF("p>");
+        pthread_mutex_unlock(&(pSles->mutex));
+
+    } //pSles not null
+}
+
+int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount, int micSource) {
+    int status = SLES_FAIL;
+
+    if (pSles == NULL) {
+        return status;
+    }
+
+    //        adb shell slesTest_feedback -r1 -t1 -s48000 -f240 -i300 -e3 -o/sdcard/log.wav
+    //            r1 and t1 are the receive and transmit buffer counts, typically 1
+    //            s is the sample rate, typically 48000 or 44100
+    //            f is the frame count per buffer, typically 240 or 256
+    //            i is the number of milliseconds before impulse.  You may need to adjust this.
+    //            e is number of seconds to record
+    //            o is output .wav file name
+
+
+    //        // default values
+    //        SLuint32 rxBufCount = 1;     // -r#
+    //        SLuint32 txBufCount = 1;     // -t#
+    //        SLuint32 bufSizeInFrames = 240;  // -f#
+    //        SLuint32 channels = 1;       // -c#
+    //        SLuint32 sampleRate = 48000; // -s#
+    //        SLuint32 exitAfterSeconds = 3; // -e#
+    //        SLuint32 freeBufCount = 0;   // calculated
+    //        SLuint32 bufSizeInBytes = 0; // calculated
+    //        int injectImpulse = 300; // -i#i
+    //
+    //        // Storage area for the buffer queues
+    //        char **rxBuffers;
+    //        char **txBuffers;
+    //        char **freeBuffers;
+    //
+    //        // Buffer indices
+    //        SLuint32 rxFront;    // oldest recording
+    //        SLuint32 rxRear;     // next to be recorded
+    //        SLuint32 txFront;    // oldest playing
+    //        SLuint32 txRear;     // next to be played
+    //        SLuint32 freeFront;  // oldest free
+    //        SLuint32 freeRear;   // next to be freed
+    //
+    //        audio_utils_fifo fifo; //(*)
+    //        SLAndroidSimpleBufferQueueItf recorderBufferQueue;
+    //        SLBufferQueueItf playerBufferQueue;
+
+    // default values
+    pSles->rxBufCount = 1;     // -r#
+    pSles->txBufCount = 1;     // -t#
+    pSles->bufSizeInFrames = frameCount;//240;  // -f#
+    pSles->channels = 1;       // -c#
+    pSles->sampleRate = samplingRate;//48000; // -s#
+    pSles->exitAfterSeconds = 3; // -e#
+    pSles->freeBufCount = 0;   // calculated
+    pSles->bufSizeInBytes = 0; // calculated
+    pSles->injectImpulse = 300; // -i#i
+
+    // Storage area for the buffer queues
+    //        char **rxBuffers;
+    //        char **txBuffers;
+    //        char **freeBuffers;
+
+    // Buffer indices
+    pSles->rxFront;    // oldest recording
+    pSles->rxRear;     // next to be recorded
+    pSles->txFront;    // oldest playing
+    pSles->txRear;     // next to be played
+    pSles->freeFront;  // oldest free
+    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;
+    // compute buffer size
+    pSles->bufSizeInBytes = pSles->channels * pSles->bufSizeInFrames * sizeof(short);
+
+    // Initialize free buffers
+    pSles->freeBuffers = (char **) calloc(pSles->freeBufCount+1, sizeof(char *));
+    unsigned j;
+    for (j = 0; j < pSles->freeBufCount; ++j) {
+        pSles->freeBuffers[j] = (char *) malloc(pSles->bufSizeInBytes);
+    }
+    pSles->freeFront = 0;
+    pSles->freeRear = pSles->freeBufCount;
+    pSles->freeBuffers[j] = NULL;
+
+    // Initialize record queue
+    pSles->rxBuffers = (char **) calloc(pSles->rxBufCount+1, sizeof(char *));
+    pSles->rxFront = 0;
+    pSles->rxRear = 0;
+
+    // Initialize play queue
+    pSles->txBuffers = (char **) calloc(pSles->txBufCount+1, sizeof(char *));
+    pSles->txFront = 0;
+    pSles->txRear = 0;
+
+    size_t frameSize = pSles->channels * sizeof(short);
+#define FIFO_FRAMES 1024
+    pSles->fifoBuffer = new short[FIFO_FRAMES * pSles->channels];
+    audio_utils_fifo_init(&(pSles->fifo), FIFO_FRAMES, frameSize, pSles->fifoBuffer);
+
+    //        SNDFILE *sndfile;
+    //        if (outFileName != NULL) {
+    // create .wav writer
+    //            SF_INFO info;
+    //            info.frames = 0;
+    //            info.samplerate = sampleRate;
+    //            info.channels = channels;
+    //            info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+    //            sndfile = sf_open(outFileName, SFM_WRITE, &info);
+    //            if (sndfile != NULL) {
+#define FIFO2_FRAMES 65536
+    pSles->fifo2Buffer = new short[FIFO2_FRAMES * pSles->channels];
+    audio_utils_fifo_init(&(pSles->fifo2), FIFO2_FRAMES, frameSize, pSles->fifo2Buffer);
+    //            } else {
+    //                fprintf(stderr, "sf_open failed\n");
+    //            }
+    //        } else {
+    //            sndfile = NULL;
+    //        }
+
+    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);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    SLEngineItf engineEngine;
+    result = (*(pSles->engineObject))->GetInterface(pSles->engineObject, SL_IID_ENGINE,
+            &engineEngine);
+    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);
+    result = (*(pSles->outputmixObject))->Realize(pSles->outputmixObject, SL_BOOLEAN_FALSE);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+    // create an audio player with buffer queue source and output mix sink
+    SLDataSource audiosrc;
+    SLDataSink audiosnk;
+    SLDataFormat_PCM pcm;
+    SLDataLocator_OutputMix locator_outputmix;
+    SLDataLocator_BufferQueue locator_bufferqueue_tx;
+    locator_bufferqueue_tx.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
+    locator_bufferqueue_tx.numBuffers = pSles->txBufCount;
+    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
+    locator_outputmix.outputMix = pSles->outputmixObject;
+    pcm.formatType = SL_DATAFORMAT_PCM;
+    pcm.numChannels = pSles->channels;
+    pcm.samplesPerSec = pSles->sampleRate * 1000;
+    pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
+    pcm.containerSize = 16;
+    pcm.channelMask = pSles->channels == 1 ? SL_SPEAKER_FRONT_CENTER :
+            (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT);
+    pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
+    audiosrc.pLocator = &locator_bufferqueue_tx;
+    audiosrc.pFormat = &pcm;
+    audiosnk.pLocator = &locator_outputmix;
+    audiosnk.pFormat = NULL;
+    pSles->playerObject = NULL;
+    pSles->recorderObject = NULL;
+    SLInterfaceID ids_tx[1] = {SL_IID_BUFFERQUEUE};
+    SLboolean flags_tx[1] = {SL_BOOLEAN_TRUE};
+    result = (*engineEngine)->CreateAudioPlayer(engineEngine, &(pSles->playerObject),
+            &audiosrc, &audiosnk, 1, ids_tx, flags_tx);
+    if (SL_RESULT_CONTENT_UNSUPPORTED == result) {
+        fprintf(stderr, "Could not create audio player (result %x), check sample rate\n",
+                result);
+        SLES_PRINTF("ERROR: Could not create audio player (result %x), check sample rate\n",
+                result);
+        goto cleanup;
+    }
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    result = (*(pSles->playerObject))->Realize(pSles->playerObject, SL_BOOLEAN_FALSE);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    SLPlayItf playerPlay;
+    result = (*(pSles->playerObject))->GetInterface(pSles->playerObject, SL_IID_PLAY,
+            &playerPlay);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    result = (*(pSles->playerObject))->GetInterface(pSles->playerObject, SL_IID_BUFFERQUEUE,
+            &(pSles->playerBufferQueue));
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    result = (*(pSles->playerBufferQueue))->RegisterCallback(pSles->playerBufferQueue,
+            playerCallback, pSles);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+    // Enqueue some zero buffers for the player
+    for (j = 0; j < pSles->txBufCount; ++j) {
+
+        // allocate a free buffer
+        assert(pSles->freeFront != pSles->freeRear);
+        char *buffer = pSles->freeBuffers[pSles->freeFront];
+        if (++pSles->freeFront > pSles->freeBufCount) {
+            pSles->freeFront = 0;
+        }
+
+        // put on play queue
+        SLuint32 txRearNext = pSles->txRear + 1;
+        if (txRearNext > pSles->txBufCount) {
+            txRearNext = 0;
+        }
+        assert(txRearNext != pSles->txFront);
+        pSles->txBuffers[pSles->txRear] = buffer;
+        pSles->txRear = txRearNext;
+        result = (*(pSles->playerBufferQueue))->Enqueue(pSles->playerBufferQueue,
+                buffer, pSles->bufSizeInBytes);
+        ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    }
+
+    result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_PLAYING);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+    // Create an audio recorder with microphone device source and buffer queue sink.
+    // The buffer queue as sink is an Android-specific extension.
+
+    SLDataLocator_IODevice locator_iodevice;
+    SLDataLocator_AndroidSimpleBufferQueue locator_bufferqueue_rx;
+    locator_iodevice.locatorType = SL_DATALOCATOR_IODEVICE;
+    locator_iodevice.deviceType = SL_IODEVICE_AUDIOINPUT;
+    locator_iodevice.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
+    locator_iodevice.device = NULL;
+    audiosrc.pLocator = &locator_iodevice;
+    audiosrc.pFormat = NULL;
+    locator_bufferqueue_rx.locatorType = SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE;
+    locator_bufferqueue_rx.numBuffers = pSles->rxBufCount;
+    audiosnk.pLocator = &locator_bufferqueue_rx;
+    audiosnk.pFormat = &pcm;
+    {
+        SLInterfaceID ids_rx[2] = {SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+                SL_IID_ANDROIDCONFIGURATION};
+        SLboolean flags_rx[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
+        result = (*engineEngine)->CreateAudioRecorder(engineEngine, &(pSles->recorderObject),
+                &audiosrc, &audiosnk, 2, ids_rx, flags_rx);
+        if (SL_RESULT_SUCCESS != result) {
+            fprintf(stderr, "Could not create audio recorder (result %x), "
+                    "check sample rate and channel count\n", result);
+            status = SLES_FAIL;
+
+            SLES_PRINTF("ERROR: Could not create audio recorder (result %x), "
+                    "check sample rate and channel count\n", result);
+            goto cleanup;
+        }
+    }
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+    {
+        /* Get the Android configuration interface which is explicit */
+        SLAndroidConfigurationItf configItf;
+        result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject,
+                SL_IID_ANDROIDCONFIGURATION, (void*)&configItf);
+        ASSERT_EQ(SL_RESULT_SUCCESS, result);
+        SLuint32 presetValue = micSource;
+        /* Use the configuration interface to configure the recorder before it's realized */
+        if (presetValue != SL_ANDROID_RECORDING_PRESET_NONE) {
+            result = (*configItf)->SetConfiguration(configItf, SL_ANDROID_KEY_RECORDING_PRESET,
+                    &presetValue, sizeof(SLuint32));
+            ASSERT_EQ(SL_RESULT_SUCCESS, result);
+        }
+
+    }
+
+    result = (*(pSles->recorderObject))->Realize(pSles->recorderObject, SL_BOOLEAN_FALSE);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    SLRecordItf recorderRecord;
+    result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject, SL_IID_RECORD,
+            &recorderRecord);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject,
+            SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &(pSles->recorderBufferQueue));
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    result = (*(pSles->recorderBufferQueue))->RegisterCallback(pSles->recorderBufferQueue,
+            recorderCallback, pSles);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+    // Enqueue some empty buffers for the recorder
+    for (j = 0; j < pSles->rxBufCount; ++j) {
+
+        // allocate a free buffer
+        assert(pSles->freeFront != pSles->freeRear);
+        char *buffer = pSles->freeBuffers[pSles->freeFront];
+        if (++pSles->freeFront > pSles->freeBufCount) {
+            pSles->freeFront = 0;
+        }
+
+        // put on record queue
+        SLuint32 rxRearNext = pSles->rxRear + 1;
+        if (rxRearNext > pSles->rxBufCount) {
+            rxRearNext = 0;
+        }
+        assert(rxRearNext != pSles->rxFront);
+        pSles->rxBuffers[pSles->rxRear] = buffer;
+        pSles->rxRear = rxRearNext;
+        result = (*(pSles->recorderBufferQueue))->Enqueue(pSles->recorderBufferQueue,
+                buffer, pSles->bufSizeInBytes);
+        ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    }
+
+    // Kick off the recorder
+    result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_RECORDING);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+    // Tear down the objects and exit
+    status = SLES_SUCCESS;
+    cleanup:
+    SLES_PRINTF("Finished initialization with status: %d", status);
+
+    return status;
+}
+
+int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples) {
+    //int status = SLES_FAIL;
+
+    SLES_PRINTF("slesProcessNext: pSles = %p, currentSample: %p,  maxSamples = %ld", pSles,
+            pSamples, maxSamples);
+
+    int samplesRead = 0;
+
+    int currentSample = 0;
+    double *pCurrentSample = pSamples;
+    int maxValue = 32768;
+
+    if (pSles == NULL) {
+        return samplesRead;
+    }
+
+    SLresult result;
+    for (int i = 0; i < 10; i++) {
+        usleep(100000);
+        if (pSles->fifo2Buffer != NULL) {
+            for (;;) {
+                short buffer[pSles->bufSizeInFrames * pSles->channels];
+                ssize_t actual = audio_utils_fifo_read(&(pSles->fifo2), buffer,
+                        pSles->bufSizeInFrames);
+                if (actual <= 0)
+                    break;
+                {
+                    for (int jj =0; jj<actual && currentSample < maxSamples; jj++) {
+                        *(pCurrentSample++) = ((double)buffer[jj])/maxValue;
+                        currentSample++;
+                    }
+                }
+                samplesRead +=actual;
+            }
+        }
+        if (pSles->injectImpulse > 0) {
+            if (pSles->injectImpulse <= 100) {
+                pSles->injectImpulse = -1;
+                write(1, "I", 1);
+            } else {
+                if ((pSles->injectImpulse % 1000) < 100) {
+                    write(1, "i", 1);
+                }
+                pSles->injectImpulse -= 100;
+            }
+        } else if (i == 9) {
+            write(1, ".", 1);
+        }
+    }
+    SLBufferQueueState playerBQState;
+    result = (*(pSles->playerBufferQueue))->GetState(pSles->playerBufferQueue,
+            &playerBQState);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    SLAndroidSimpleBufferQueueState recorderBQState;
+    result = (*(pSles->recorderBufferQueue))->GetState(pSles->recorderBufferQueue,
+            &recorderBQState);
+    ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+    SLES_PRINTF("End of slesProcessNext: pSles = %p, samplesRead = %d, maxSamples= %ld", pSles,
+            samplesRead, maxSamples);
+
+    return samplesRead;
+}
+
+int slesDestroyServer(sles_data *pSles) {
+    int status = SLES_FAIL;
+
+    SLES_PRINTF("Start slesDestroyServer: pSles = %p", pSles);
+    if (pSles == NULL) {
+        return status;
+    }
+
+    if (NULL != pSles->playerObject) {
+
+        SLES_PRINTF("stopping player...");
+        SLPlayItf playerPlay;
+        SLresult result = (*(pSles->playerObject))->GetInterface(pSles->playerObject,
+                SL_IID_PLAY, &playerPlay);
+
+        ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+        //stop player and recorder if they exist
+        result = (*playerPlay)->SetPlayState(playerPlay, SL_PLAYSTATE_STOPPED);
+        ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    }
+
+    if (NULL != pSles->recorderObject) {
+        SLES_PRINTF("stopping recorder...");
+        SLRecordItf recorderRecord;
+        SLresult result = (*(pSles->recorderObject))->GetInterface(pSles->recorderObject,
+                SL_IID_RECORD, &recorderRecord);
+        ASSERT_EQ(SL_RESULT_SUCCESS, result);
+
+        result = (*recorderRecord)->SetRecordState(recorderRecord, SL_RECORDSTATE_STOPPED);
+        ASSERT_EQ(SL_RESULT_SUCCESS, result);
+    }
+
+    usleep(1000);
+
+    audio_utils_fifo_deinit(&(pSles->fifo));
+    delete[] pSles->fifoBuffer;
+
+    SLES_PRINTF("slesDestroyServer 2");
+
+    //        if (sndfile != NULL) {
+    audio_utils_fifo_deinit(&(pSles->fifo2));
+    delete[] pSles->fifo2Buffer;
+
+    SLES_PRINTF("slesDestroyServer 3");
+
+    //            sf_close(sndfile);
+    //        }
+    if (NULL != pSles->playerObject) {
+        (*(pSles->playerObject))->Destroy(pSles->playerObject);
+    }
+
+    SLES_PRINTF("slesDestroyServer 4");
+
+    if (NULL != pSles->recorderObject) {
+        (*(pSles->recorderObject))->Destroy(pSles->recorderObject);
+    }
+
+    SLES_PRINTF("slesDestroyServer 5");
+
+    (*(pSles->outputmixObject))->Destroy(pSles->outputmixObject);
+    SLES_PRINTF("slesDestroyServer 6");
+    (*(pSles->engineObject))->Destroy(pSles->engineObject);
+    SLES_PRINTF("slesDestroyServer 7");
+
+    //        free(pSles);
+    //        pSles=NULL;
+
+    status = SLES_SUCCESS;
+
+    SLES_PRINTF("End slesDestroyServer: status = %d", status);
+    return status;
+}
+
diff --git a/apps/CtsVerifier/jni/audio_loopback/sles.h b/apps/CtsVerifier/jni/audio_loopback/sles.h
new file mode 100644
index 0000000..2550b81
--- /dev/null
+++ b/apps/CtsVerifier/jni/audio_loopback/sles.h
@@ -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.
+ */
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+#include <pthread.h>
+#include <android/log.h>
+
+#ifndef _Included_org_drrickorang_loopback_sles
+#define _Included_org_drrickorang_loopback_sles
+
+//struct audio_utils_fifo;
+#define SLES_PRINTF(...)  __android_log_print(ANDROID_LOG_INFO, "sles_jni", __VA_ARGS__);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <audio_utils/fifo.h>
+
+typedef struct {
+    SLuint32 rxBufCount;     // -r#
+    SLuint32 txBufCount;     // -t#
+    SLuint32 bufSizeInFrames;  // -f#
+    SLuint32 channels;       // -c#
+    SLuint32 sampleRate; // -s#
+    SLuint32 exitAfterSeconds; // -e#
+    SLuint32 freeBufCount;   // calculated
+    SLuint32 bufSizeInBytes; // calculated
+    int injectImpulse; // -i#i
+
+    // Storage area for the buffer queues
+    char **rxBuffers;
+    char **txBuffers;
+    char **freeBuffers;
+
+    // Buffer indices
+    SLuint32 rxFront;    // oldest recording
+    SLuint32 rxRear;     // next to be recorded
+    SLuint32 txFront;    // oldest playing
+    SLuint32 txRear;     // next to be played
+    SLuint32 freeFront;  // oldest free
+    SLuint32 freeRear;   // next to be freed
+
+    struct audio_utils_fifo fifo; //(*)
+    struct audio_utils_fifo fifo2;
+    short *fifo2Buffer;
+    short *fifoBuffer;
+    SLAndroidSimpleBufferQueueItf recorderBufferQueue;
+    SLBufferQueueItf playerBufferQueue;
+
+    pthread_mutex_t mutex;// = PTHREAD_MUTEX_INITIALIZER;
+
+    //other things that belong here
+    SLObjectItf playerObject;
+    SLObjectItf recorderObject;
+    SLObjectItf outputmixObject;
+    SLObjectItf engineObject;
+} sles_data;
+
+enum {
+    SLES_SUCCESS = 0,
+    SLES_FAIL = 1,
+} SLES_STATUS_ENUM;
+
+int slesInit(sles_data ** ppSles, int samplingRate, int frameCount, int micSource);
+
+//note the double pointer to properly free the memory of the structure
+int slesDestroy(sles_data ** ppSles);
+
+///full
+int slesFull(sles_data *pSles);
+
+int slesCreateServer(sles_data *pSles, int samplingRate, int frameCount, int micSource);
+int slesProcessNext(sles_data *pSles, double *pSamples, long maxSamples);
+int slesDestroyServer(sles_data *pSles);
+
+#ifdef __cplusplus
+}
+#endif
+#endif //_Included_org_drrickorang_loopback_sles
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/Android.mk b/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
deleted file mode 100644
index ed66992..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/Android.mk
+++ /dev/null
@@ -1,40 +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)
-include external/stlport/libstlport.mk
-
-LOCAL_MODULE := libcameraanalyzer
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := com_android_cts_verifier_camera_analyzer_CameraTests.cpp \
-                com_android_cts_verifier_camera_analyzer_ColorCheckerTest.cpp \
-                com_android_cts_verifier_camera_analyzer_ExposureCompensationTest.cpp \
-                com_android_cts_verifier_camera_analyzer_AutoLockTest.cpp \
-                com_android_cts_verifier_camera_analyzer_MeteringTest.cpp \
-                com_android_cts_verifier_camera_analyzer_WhiteBalanceTest.cpp
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../include/colorchecker $(JNI_H_INCLUDE)
-
-LOCAL_STATIC_LIBRARIES := libcolorchecker
-LOCAL_SHARED_LIBRARIES := libjnigraphics \
-                          libstlport \
-                          libcutils \
-                          libutils liblog
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_AutoLockTest.cpp b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_AutoLockTest.cpp
deleted file mode 100644
index fac39e1..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_AutoLockTest.cpp
+++ /dev/null
@@ -1,95 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "AutoLockJNI"
-#include <utils/Log.h>
-#include "com_android_cts_verifier_camera_analyzer_AutoLockTest.h"
-
-#include <vector>
-#include <string>
-#include <string.h>
-
-#include "testingimage.h"
-#include "autolocktest.h"
-#include "vec2.h"
-#include "android/bitmap.h"
-
-jlong Java_com_android_cts_verifier_camera_analyzer_AutoLockTest_createAutoLockTest(
-        JNIEnv*      env,
-        jobject      thiz) {
-
-    AutoLockTest* testHandler = new AutoLockTest();
-    long handlerAddress = (long)testHandler;
-    return handlerAddress;
-}
-
-void Java_com_android_cts_verifier_camera_analyzer_AutoLockTest_createAutoLockClass(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputImageAddress,
-        jlong        inputHandlerAddress,
-        jlong        checkercenterAddress,
-        jlong        checkerradiusAddress) {
-
-    ALOGV("JNI createAutoLockClass starts!");
-    long imageAddress = (long)inputImageAddress;
-    long handlerAddress = (long)inputHandlerAddress;
-
-    TestingImage *image = (TestingImage*) imageAddress;
-    AutoLockTest *testHandler = (AutoLockTest*) handlerAddress;
-
-    std::vector<std::vector< Vec2f > >* checkerCenter =
-            (std::vector<std::vector< Vec2f > >*) (long) checkercenterAddress;
-    std::vector<std::vector< float > >* checkerRadius =
-            (std::vector<std::vector< float > >*) (long) checkerradiusAddress;
-    ALOGV("Classes recovered");
-
-    // Uses only the gray patches on the color checker for comparison.
-    testHandler->addDataToList(image->getColorChecker(3, 4, 0, 6,
-                                                      checkerCenter,
-                                                      checkerRadius));
-
-    delete image;
-}
-
-void Java_com_android_cts_verifier_camera_analyzer_AutoLockTest_processAutoLockTest(
-        JNIEnv*          env,
-        jobject          thiz,
-        jlong            inputHandlerAddress,
-        jbooleanArray    tempArray) {
-
-    ALOGV("Processing Auto Lock data!");
-
-    long handlerAddress = (long) inputHandlerAddress;
-    AutoLockTest *testHandler = (AutoLockTest*) handlerAddress;
-
-    testHandler->processData();
-
-    // Converts the native boolean array into a java boolean array.
-    const std::vector<bool>* nativeComparisonResults =
-            testHandler->getComparisonResults();
-    jboolean comparisonResults[nativeComparisonResults->size()];
-
-    for (int i = 0; i < nativeComparisonResults->size(); ++i) {
-        comparisonResults[i] = (jboolean) (*nativeComparisonResults)[i];
-    }
-
-    env->SetBooleanArrayRegion(tempArray,
-                               0, nativeComparisonResults->size(),
-                               comparisonResults);
-    testHandler->clearData();
-}
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_AutoLockTest.h b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_AutoLockTest.h
deleted file mode 100644
index dc40bc2..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_AutoLockTest.h
+++ /dev/null
@@ -1,52 +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.
- */
-
-#ifndef JNI_CAMERAANALYZER_AUTOLOCKTEST_H
-#define JNI_CAMERAANALYZER_AUTOLOCKTEST_H
-
-#include <jni.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-JNIEXPORT jlong JNICALL
-Java_com_android_cts_verifier_camera_analyzer_AutoLockTest_createAutoLockTest(
-        JNIEnv*      env,
-        jobject      thiz);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_AutoLockTest_createAutoLockClass(
-        JNIEnv *env,
-        jobject thiz,
-        jlong inputImageAddress,
-        jlong inputHandlerAddress,
-        jlong checkercenterAddress,
-        jlong checkerradiusAddress);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_AutoLockTest_processAutoLockTest(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress,
-        jbooleanArray    tempArray);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.cpp b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.cpp
deleted file mode 100644
index ed91233..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.cpp
+++ /dev/null
@@ -1,223 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "CameraTestsJNI"
-#include <utils/Log.h>
-#include "com_android_cts_verifier_camera_analyzer_CameraTests.h"
-#include "android/bitmap.h"
-#include "testingimage.h"
-#include "imagetesthandler.h"
-
-#include <string.h>
-
-jlong Java_com_android_cts_verifier_camera_analyzer_CameraTests_findNative(
-        JNIEnv*      env,
-        jobject      thiz,
-        jobject      inputBitmap) {
-
-    ALOGV("JNI findNative starts!");
-
-    // Verify that we can handle the input bitmap
-    AndroidBitmapInfo inputInfo;
-    AndroidBitmap_getInfo(env, inputBitmap, &inputInfo);
-    if (inputInfo.format != ANDROID_BITMAP_FORMAT_RGBA_8888 &&
-        inputInfo.format != ANDROID_BITMAP_FORMAT_RGB_565) {
-        ALOGE("Only RGBA_8888 and RGB_565 bitmaps are supported, type was %d.",
-             inputInfo.format);
-    }
-
-    // Get some references to the fields and class type of ColorChecker
-    jclass thizCls = env->GetObjectClass(thiz);
-    ALOGV("ColorChecker field and classes reference finished!");
-
-    // Get raw inputs and outputs ready
-    uint8_t *inputBuffer = NULL;
-    int result = AndroidBitmap_lockPixels(
-            env,
-            inputBitmap,
-            reinterpret_cast<void**>(&inputBuffer));
-
-    if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
-        ALOGE("Unable to lock input bitmap");
-    }
-
-    uint8_t *outputImage = NULL;
-    int outputWidth, outputHeight;
-
-    ALOGV("Input and output images created!");
-
-    // Find the color checker
-    bool success;
-    uint8_t *inputBufferRGBA = NULL;
-    int inputStride;
-    bool freeInputRGBA = false;
-    switch (inputInfo.format) {
-        case ANDROID_BITMAP_FORMAT_RGB_565: {
-            // First convert to RGBA_8888
-            inputBufferRGBA = new uint8_t[inputInfo.width *
-                                          inputInfo.height *
-                                          4];
-            inputStride = inputInfo.width * 4;
-            uint8_t *outP = inputBufferRGBA;
-            for (int y = 0; y < inputInfo.height; y++ ) {
-                uint16_t *inP = (uint16_t*)(&inputBuffer[y * inputInfo.stride]);
-                for (int x = 0; x < inputInfo.width; x++) {
-                    *(outP++) = ( ((*inP) >> 0) & 0x001F) << 3;
-                    *(outP++) = ( ((*inP) >> 5) & 0x003F) << 2;
-                    *(outP++) = ( ((*inP) >> 11) & 0x001F) << 3;
-                    outP++;
-                    inP++;
-                }
-            }
-            freeInputRGBA = true;
-
-            ALOGV("RGB_565 Format with width, height and stride as %d, %d, %d",
-                 inputInfo.width, inputInfo.height, inputStride);
-            break;
-        }
-        case ANDROID_BITMAP_FORMAT_RGBA_8888: {
-            // Already in RGBA
-            inputBufferRGBA = inputBuffer;
-            inputStride = inputInfo.stride;
-            ALOGV("RGB_8888 Format with width, height and stride as %d, %d, %d",
-                 inputInfo.width, inputInfo.height, inputStride);
-            break;
-        }
-    }
-
-    TestingImage *input_testing_image =
-            new TestingImage(inputBufferRGBA, inputInfo.height, inputInfo.width,
-                             4, inputStride, 120, 160);
-
-    long lp = (long)input_testing_image;
-
-    result = AndroidBitmap_unlockPixels(env, inputBitmap);
-    if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
-        ALOGE("Unable to unlock input bitmap");
-    }
-
-    if (freeInputRGBA) {
-        ALOGV("Deleteing inputbufferRGBA");
-        delete[] inputBufferRGBA;
-    }
-
-    return lp;
-    ALOGV("Input format switched!");
-}
-
-jlong Java_com_android_cts_verifier_camera_analyzer_CameraTests_createImageTestHandler(
-        JNIEnv*      env,
-        jobject      thiz,
-        jint         debugHeight,
-        jint         debugWidth) {
-
-    ImageTestHandler* testHandler =
-            new ImageTestHandler(debugHeight, debugWidth);
-    long handlerAddress = (long)testHandler;
-    return handlerAddress;
-}
-
-void Java_com_android_cts_verifier_camera_analyzer_CameraTests_cleanUpHandler(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress) {
-
-    ImageTestHandler* testHandler = (ImageTestHandler*) (long) inputHandlerAddress;
-    delete testHandler;
-}
-
-void Java_com_android_cts_verifier_camera_analyzer_CameraTests_displayHandlerDebugOutput(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress) {
-
-    jclass thizCls = env->GetObjectClass(thiz);
-    jfieldID outputId = env->GetFieldID(thizCls, "mDebugOutput",
-                                        "Landroid/graphics/Bitmap;");
-
-    ImageTestHandler* testHandler = (ImageTestHandler*) (long) inputHandlerAddress;
-    uint8_t *outputImage =  new uint8_t[testHandler->getDebugHeight() *
-                                        testHandler->getDebugWidth() * 4];
-
-    const unsigned char *debugoutput = testHandler->debug_output();
-    memcpy(outputImage, debugoutput, testHandler->getDebugHeight() *
-            testHandler->getDebugWidth() * 4);
-
-    int outputWidth = testHandler->getDebugWidth();
-    int outputHeight = testHandler->getDebugHeight();
-    bool success = false;
-
-    if (outputImage == NULL) {
-        ALOGV("output Image is null!");
-    } else {
-        ALOGV("output Image is ready!");
-    }
-
-    // Create debug bitmap from output image data
-    if (outputImage != NULL) {
-        // Get method handles, create inputs to createBitmap
-        jclass bitmapClass =
-                env->FindClass("android/graphics/Bitmap");
-        jclass bitmapConfigClass =
-                env->FindClass("android/graphics/Bitmap$Config");
-
-        jmethodID createBitmap = env->GetStaticMethodID(
-            bitmapClass, "createBitmap",
-            "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
-
-        jmethodID getConfig = env->GetStaticMethodID(
-            bitmapConfigClass, "valueOf",
-            "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
-
-        // Create bitmap config and bitmap
-        jstring bitmapConfigValue = env->NewStringUTF("ARGB_8888");
-        jobject rgbaConfig = env->CallStaticObjectMethod(bitmapConfigClass,
-                                                         getConfig,
-                                                         bitmapConfigValue);
-        jobject outputBitmap = env->CallStaticObjectMethod(bitmapClass,
-                                                           createBitmap,
-                                                           outputWidth,
-                                                           outputHeight,
-                                                           rgbaConfig);
-        // Copy output image into it
-        uint8_t *outputBuffer;
-        int result = AndroidBitmap_lockPixels(
-                env,
-                outputBitmap,
-                reinterpret_cast<void**>(&outputBuffer) );
-
-        if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
-            ALOGE("Unable to lock output bitmap");
-        }
-
-        memcpy(outputBuffer, outputImage, outputWidth * outputHeight * 4);
-
-        result = AndroidBitmap_unlockPixels(env, outputBitmap);
-        if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
-            ALOGE("Unable to unlock output bitmap");
-        }
-
-        // Write new Bitmap reference into mDebugOutput class member
-        env->SetObjectField(thiz, outputId, outputBitmap);
-        ALOGV("Copied to outputBitmap");
-        delete [] outputImage;
-        env->DeleteLocalRef(outputBitmap);
-        env->DeleteLocalRef(rgbaConfig);
-        env->DeleteLocalRef(bitmapClass);
-        env->DeleteLocalRef(bitmapConfigClass);
-    }
-}
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.h b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.h
deleted file mode 100644
index e071dc1..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_CameraTests.h
+++ /dev/null
@@ -1,57 +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.
- */
-
-#ifndef JNI_CAMERAANALYZER_CAMERATESTS_H
-#define JNI_CAMERAANALYZER_CAMERATESTS_H
-
-#include <jni.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-JNIEXPORT jlong JNICALL
-Java_com_android_cts_verifier_camera_analyzer_CameraTests_findNative(
-        JNIEnv *env,
-        jobject thiz,
-        jobject inputBitmap);
-
-JNIEXPORT jlong JNICALL
-Java_com_android_cts_verifier_camera_analyzer_CameraTests_createImageTestHandler(
-        JNIEnv*      env,
-        jobject      thiz,
-        jint         debugHeight,
-        jint         debugWidth);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_CameraTests_cleanUpHandler(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_CameraTests_displayHandlerDebugOutput(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.cpp b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.cpp
deleted file mode 100644
index 94e3ac2..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.cpp
+++ /dev/null
@@ -1,84 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "FindColorCheckerJNI"
-#include <utils/Log.h>
-#include "com_android_cts_verifier_camera_analyzer_ColorCheckerTest.h"
-
-#include <string.h>
-#include "android/bitmap.h"
-#include "colorcheckertest.h"
-#include "testingimage.h"
-
-jlong Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_createColorCheckerTest(
-        JNIEnv*      env,
-        jobject      thiz,
-        jint         debugHeight,
-        jint         debugWidth) {
-    ColorCheckerTest* testHandler = new ColorCheckerTest(debugHeight,
-                                                         debugWidth);
-    long testHandlerAddress = (long)testHandler;
-    return testHandlerAddress;
-}
-
-void Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_createColorCheckerClass(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputImageAddress,
-        jlong        inputHandlerAddress) {
-    ALOGV("JNI createColorCheckerClass starts!");
-
-    TestingImage *testImage = (TestingImage*) (long) inputImageAddress;
-    ColorCheckerTest *testHandler = (ColorCheckerTest*)
-            (long) inputHandlerAddress;
-
-    testHandler->addTestingImage(testImage);
-}
-
-jboolean Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_processColorCheckerTest(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress) {
-
-    ColorCheckerTest *testHandler = (ColorCheckerTest*)
-            (long) inputHandlerAddress;
-    testHandler->processData();
-    return testHandler->getSuccess();
-}
-
-jlong Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_getColorCheckerRadiusAdd(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress) {
-
-    ColorCheckerTest *testHandler = (ColorCheckerTest*)
-            (long) inputHandlerAddress;
-    long rtn = (long) testHandler->getCheckerRadiusAdd();
-    return rtn;
-}
-
-jlong Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_getColorCheckerCenterAdd(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress) {
-
-    ColorCheckerTest *testHandler = (ColorCheckerTest*)
-            (long) inputHandlerAddress;
-
-    long rtn = (long) testHandler->getCheckerCenterAdd();
-    return rtn;
-}
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.h b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.h
deleted file mode 100644
index fb87735..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ColorCheckerTest.h
+++ /dev/null
@@ -1,63 +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.
- */
-
-#ifndef JNI_CAMERAANALYZER_COLORCHECKERTEST_H
-#define JNI_CAMERAANALYZER_COLORCHECKERTEST_H
-
-#include <jni.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-JNIEXPORT jlong JNICALL
-Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_createColorCheckerTest(
-    JNIEnv*      env,
-    jobject      thiz,
-    jint         output_height,
-    jint         output_width);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_createColorCheckerClass(
-    JNIEnv *env,
-    jobject thiz,
-    jlong buffer_address,
-    jlong handler_address);
-
-JNIEXPORT jlong JNICALL
-Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_getColorCheckerRadiusAdd(
-    JNIEnv *env,
-    jobject thiz,
-    jlong handler_address);
-
-JNIEXPORT jlong JNICALL
-Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_getColorCheckerCenterAdd(
-    JNIEnv *env,
-    jobject thiz,
-    jlong handler_address);
-
-JNIEXPORT jboolean JNICALL
-Java_com_android_cts_verifier_camera_analyzer_ColorCheckerTest_processColorCheckerTest(
-    JNIEnv*      env,
-    jobject      thiz,
-    jlong        handler_address);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ExposureCompensationTest.cpp b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ExposureCompensationTest.cpp
deleted file mode 100644
index 0224639..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ExposureCompensationTest.cpp
+++ /dev/null
@@ -1,88 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "ExposureCompensationJNI"
-#include <utils/Log.h>
-#include <vector>
-#include <string.h>
-
-#include "android/bitmap.h"
-#include "testingimage.h"
-#include "exposurecompensationtest.h"
-#include "vec2.h"
-
-#include "com_android_cts_verifier_camera_analyzer_ExposureCompensationTest.h"
-
-jlong Java_com_android_cts_verifier_camera_analyzer_ExposureCompensationTest_createExposureCompensationTest(
-      JNIEnv*      env,
-      jobject      thiz,
-      jint         debugHeight,
-      jint         debugWidth) {
-
-    ExposureCompensationTest* testHandler =
-            new ExposureCompensationTest(debugHeight, debugWidth);
-    long handlerAddress = (long)testHandler;
-
-    return handlerAddress;
-}
-
-void Java_com_android_cts_verifier_camera_analyzer_ExposureCompensationTest_createExposureCompensationClass(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputImageAddress,
-        jlong        inputHandlerAddress,
-        jlong        checkerCenterAddress,
-        jlong        checkerRadiusAddress,
-        jfloat       exposureValue) {
-
-    ALOGV("JNI createExposureCompensationClass starts!");
-
-    long imageAddress = (long)inputImageAddress;
-    long handlerAddress = (long)inputHandlerAddress;
-
-    TestingImage *inputImage = (TestingImage*) imageAddress;
-    ExposureCompensationTest *testHandler =
-            (ExposureCompensationTest*) handlerAddress;
-
-    std::vector<std::vector< Vec2f > >* checkerCenter =
-            (std::vector<std::vector< Vec2f > >*) (long) checkerCenterAddress;
-    std::vector<std::vector< float > >* checkerRadius =
-            (std::vector<std::vector< float > >*) (long) checkerRadiusAddress;
-
-    const std::vector<Vec3f>* checkerValue =
-            inputImage->getColorChecker(3, 4, 0, 6,
-                                        checkerCenter, checkerRadius);
-    testHandler->addDataToList((float) exposureValue, checkerValue);
-    delete inputImage;
-    delete checkerValue;
-}
-
-jstring Java_com_android_cts_verifier_camera_analyzer_ExposureCompensationTest_processExposureCompensationTest(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress) {
-
-    long handlerAddress = (long) inputHandlerAddress;
-    ExposureCompensationTest *testHandler =
-            (ExposureCompensationTest*) handlerAddress;
-
-    testHandler->processData();
-
-    const char* nativeDebugText = testHandler->getDebugText();
-    ALOGV("%s", nativeDebugText);
-    return env->NewStringUTF(nativeDebugText);
-}
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ExposureCompensationTest.h b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ExposureCompensationTest.h
deleted file mode 100644
index 8e8761d..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_ExposureCompensationTest.h
+++ /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.
- */
-
-#ifndef JNI_CAMERAANALYZER_EXPOSURECOMPENSATIONTEST_H
-#define JNI_CAMERAANALYZER_EXPOSURECOMPENSATIONTEST_H
-
-#include <jni.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-JNIEXPORT jlong JNICALL
-Java_com_android_cts_verifier_camera_analyzer_ExposureCompensationTest_createExposureCompensationTest(
-        JNIEnv*      env,
-        jobject      thiz,
-        jint         debugHeight,
-        jint         debugWidth);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_ExposureCompensationTest_createExposureCompensationClass(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputImageAddress,
-        jlong        inputHandlerAddress,
-        jlong        checkerCenterAddress,
-        jlong        checkerRadiusAddress,
-        jfloat       exposureValue);
-
-
-JNIEXPORT jstring JNICALL
-Java_com_android_cts_verifier_camera_analyzer_ExposureCompensationTest_processExposureCompensationTest(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputHandlerAddress);
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_MeteringTest.cpp b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_MeteringTest.cpp
deleted file mode 100644
index faebe21..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_MeteringTest.cpp
+++ /dev/null
@@ -1,142 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "MeteringJNI"
-#include <utils/Log.h>
-#include "com_android_cts_verifier_camera_analyzer_MeteringTest.h"
-
-#include <vector>
-#include <string>
-#include <string.h>
-#include <math.h>
-
-#include "testingimage.h"
-#include "meteringtest.h"
-#include "vec2.h"
-#include "android/bitmap.h"
-
-jlong Java_com_android_cts_verifier_camera_analyzer_MeteringTest_createMeteringTest(
-        JNIEnv*      env,
-        jobject      thiz) {
-
-    MeteringTest* testHandler = new MeteringTest();
-    long handlerAddress = (long)testHandler;
-    return handlerAddress;
-}
-
-void Java_com_android_cts_verifier_camera_analyzer_MeteringTest_createMeteringClass(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputImageAddress,
-        jlong        inputHandlerAddress,
-        jlong        checkercenterAddress,
-        jlong        checkerradiusAddress){
-
-    ALOGV("JNI createMeteringClass starts!");
-    long imageAddress = (long)inputImageAddress;
-    long handlerAddress = (long)inputHandlerAddress;
-
-    TestingImage *image = (TestingImage*) imageAddress;
-    MeteringTest *testHandler = (MeteringTest*) handlerAddress;
-
-    std::vector<std::vector< Vec2f > >* checkerCenter =
-            (std::vector<std::vector< Vec2f > >*) (long) checkercenterAddress;
-    std::vector<std::vector< float > >* checkerRadius =
-            (std::vector<std::vector< float > >*) (long) checkerradiusAddress;
-    ALOGV("Classes recovered");
-
-    testHandler->addDataToList(image->getColorChecker(3, 4, 0, 6,
-                                                      checkerCenter,
-                                                      checkerRadius));
-
-    delete image;
-}
-
-void Java_com_android_cts_verifier_camera_analyzer_MeteringTest_processMeteringTest(
-        JNIEnv*          env,
-        jobject          thiz,
-        jlong            inputHandlerAddress,
-        jbooleanArray    tempArray) {
-
-    ALOGV("Processing Auto Lock data!");
-
-    long handlerAddress = (long) inputHandlerAddress;
-    MeteringTest *testHandler = (MeteringTest*) handlerAddress;
-
-    testHandler->processData();
-
-    const std::vector<bool>* nativeComparisonResults =
-            testHandler->getComparisonResults();
-    jboolean jComparisonResults[nativeComparisonResults->size()];
-
-    for (int i = 0; i < nativeComparisonResults->size(); ++i) {
-        jComparisonResults[i] = (jboolean) (*nativeComparisonResults)[i];
-    }
-
-    env->SetBooleanArrayRegion(tempArray,
-                               0, nativeComparisonResults->size(),
-                               jComparisonResults);
-    testHandler->clearData();
-}
-
-// Find the gray checker borders from the native array of checker center and
-// radius. Convert the coordinate to the coordinates accepted by Android
-// Camera.Area type, which defines the top left corner to (-1000, -1000) and
-// bottom right corner to (1000, 1000).
-void Java_com_android_cts_verifier_camera_analyzer_MeteringTest_findGreyCoordinates(
-        JNIEnv*      env,
-        jobject      thiz,
-        jintArray    greyCoordinates,
-        jlong        checkercenterAddress,
-        jlong        checkerradiusAddress){
-
-    ALOGV("Start finding grey coordinates");
-
-    std::vector<std::vector< Vec2f > >* checkerCenter =
-            (std::vector<std::vector< Vec2f > >*) (long) checkercenterAddress;
-    std::vector<std::vector< float > >* checkerRadius =
-            (std::vector<std::vector< float > >*) (long) checkerradiusAddress;
-
-    ALOGV("Checker recovered!");
-    int nativeGreyCoordinates[24];
-
-    for (int i = 0; i < 6; ++i) {
-        float radius = sqrt((*checkerRadius)[3][i]);
-        nativeGreyCoordinates[i * 4] = static_cast<int>(
-                ((*checkerCenter)[3][i].y() - radius)
-                / 160.0 * 2000.0 - 1000.0);
-        nativeGreyCoordinates[i * 4 + 1] = static_cast<int>(
-                ((*checkerCenter)[3][i].x() - radius)
-                / 120.0 * 2000.0 - 1000.0);
-        nativeGreyCoordinates[i * 4 + 2] = static_cast<int>(
-                ((*checkerCenter)[3][i].y() + radius)
-                / 160.0 * 2000.0 - 1000.0);
-        nativeGreyCoordinates[i * 4 + 3] = static_cast<int>(
-                ((*checkerCenter)[3][i].x() + radius)
-                / 120.0 * 2000.0 - 1000.0);
-
-        ALOGV("checker is bounded by %f, %f, %f",
-             (*checkerCenter)[3][i].x(), (*checkerCenter)[3][i].y(), radius);
-
-        ALOGV("Square is bounded by %d, %d, %d, %d",
-             nativeGreyCoordinates[i * 4], nativeGreyCoordinates[i * 4 + 1],
-             nativeGreyCoordinates[i * 4 + 2],
-             nativeGreyCoordinates[i * 4 + 3]);
-    }
-
-    env->SetIntArrayRegion(greyCoordinates, 0, 24, nativeGreyCoordinates);
-}
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_MeteringTest.h b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_MeteringTest.h
deleted file mode 100644
index ecc1b96..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_MeteringTest.h
+++ /dev/null
@@ -1,60 +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.
- */
-
-#ifndef JNI_CAMERAANALYZER_METERINGTEST_H
-#define JNI_CAMERAANALYZER_METERINGTEST_H
-
-#include <jni.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-JNIEXPORT jlong JNICALL
-Java_com_android_cts_verifier_camera_analyzer_MeteringTest_createMeteringTest(
-        JNIEnv*      env,
-        jobject      thiz);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_MeteringTest_createMeteringClass(
-        JNIEnv *env,
-        jobject thiz,
-        jlong inputAddress,
-        jlong handlerAddress,
-        jlong checkercenterAddress,
-        jlong checkerradiusAddress);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_MeteringTest_processMeteringTest(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        handlerAddress,
-        jbooleanArray    tempArray);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_MeteringTest_findGreyCoordinates(
-        JNIEnv*      env,
-        jobject      thiz,
-        jintArray    greyCoordinates,
-        jlong        checkercenterAddress,
-        jlong        checkerradiusAddress);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_WhiteBalanceTest.cpp b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_WhiteBalanceTest.cpp
deleted file mode 100644
index bce0fca..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_WhiteBalanceTest.cpp
+++ /dev/null
@@ -1,90 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "WhiteBalanceJNI"
-#include <utils/Log.h>
-#include "com_android_cts_verifier_camera_analyzer_WhiteBalanceTest.h"
-
-#include <vector>
-#include <string>
-#include <string.h>
-
-#include "testingimage.h"
-#include "whitebalancetest.h"
-#include "vec2.h"
-#include "android/bitmap.h"
-
-jlong Java_com_android_cts_verifier_camera_analyzer_WhiteBalanceTest_createWhiteBalanceTest(
-        JNIEnv*      env,
-        jobject      thiz) {
-
-    WhiteBalanceTest* testHandler = new WhiteBalanceTest();
-    long handlerAddress = (long)testHandler;
-    return handlerAddress;
-}
-
-void Java_com_android_cts_verifier_camera_analyzer_WhiteBalanceTest_createWhiteBalanceClass(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        inputImageAddress,
-        jlong        inputHandlerAddress,
-        jlong        checkercenterAddress,
-        jlong        checkerradiusAddress,
-        jstring      whiteBalance){
-
-    ALOGV("JNI createWhiteBalanceClass starts!");
-    long imageAddress = (long)inputImageAddress;
-    long handlerAddress = (long)inputHandlerAddress;
-
-    TestingImage *image = (TestingImage*) imageAddress;
-    WhiteBalanceTest *testHandler = (WhiteBalanceTest*) handlerAddress;
-
-    std::vector<std::vector< Vec2f > >* checkerCenter =
-        (std::vector<std::vector< Vec2f > >*) (long) checkercenterAddress;
-    std::vector<std::vector< float > >* checkerRadius =
-        (std::vector<std::vector< float > >*) (long) checkerradiusAddress;
-    ALOGV("Classes recovered");
-
-    jboolean isCopy;
-    const char* stringWhiteBalance =
-            env->GetStringUTFChars(whiteBalance, &isCopy);
-    ALOGV("White Balance is %s", stringWhiteBalance);
-
-    // Adds the gray checker's RGB values to the test handler.
-    testHandler->addDataToList(stringWhiteBalance,
-                               image->getColorChecker(3, 4, 0, 6,
-                                                      checkerCenter,
-                                                      checkerRadius));
-
-    env->ReleaseStringUTFChars(whiteBalance, stringWhiteBalance);
-    delete image;
-}
-
-jint Java_com_android_cts_verifier_camera_analyzer_WhiteBalanceTest_processWhiteBalanceTest(
-    JNIEnv*      env,
-    jobject      thiz,
-    jlong        inputHandlerAddress) {
-  ALOGV("Processing white balance test");
-
-  long handlerAddress = (long) inputHandlerAddress;
-  WhiteBalanceTest *testHandler = (WhiteBalanceTest*) handlerAddress;
-
-  testHandler->processData();
-
-  ALOGV("CCT is %d", testHandler->getCorrelatedColorTemp());
-  return testHandler->getCorrelatedColorTemp();
-}
diff --git a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_WhiteBalanceTest.h b/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_WhiteBalanceTest.h
deleted file mode 100644
index 88cf52e..0000000
--- a/apps/CtsVerifier/jni/cameraanalyzer/com_android_cts_verifier_camera_analyzer_WhiteBalanceTest.h
+++ /dev/null
@@ -1,53 +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.
- */
-
-#ifndef JNI_CAMERAANALYZER_WHITEBALANCETEST_H
-#define JNI_CAMERAANALYZER_WHITEBALANCETEST_H
-
-#include <jni.h>
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-JNIEXPORT jlong JNICALL
-Java_com_android_cts_verifier_camera_analyzer_WhiteBalanceTest_createWhiteBalanceTest(
-        JNIEnv*      env,
-        jobject      thiz);
-
-JNIEXPORT void JNICALL
-Java_com_android_cts_verifier_camera_analyzer_WhiteBalanceTest_createWhiteBalanceClass(
-        JNIEnv *env,
-        jobject thiz,
-        jlong inputAddress,
-        jlong handlerAddress,
-        jlong checkercenterAddress,
-        jlong checkerradiusAddress,
-        jstring whiteBalance);
-
-JNIEXPORT jint JNICALL
-Java_com_android_cts_verifier_camera_analyzer_WhiteBalanceTest_processWhiteBalanceTest(
-        JNIEnv*      env,
-        jobject      thiz,
-        jlong        handlerAddress);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/apps/CtsVerifier/jni/verifier/Android.mk b/apps/CtsVerifier/jni/verifier/Android.mk
index da4687d..4840e62 100644
--- a/apps/CtsVerifier/jni/verifier/Android.mk
+++ b/apps/CtsVerifier/jni/verifier/Android.mk
@@ -25,8 +25,11 @@
 
 LOCAL_SRC_FILES := \
 		CtsVerifierJniOnLoad.cpp \
-		com_android_cts_verifier_os_FileUtils.cpp	
+		com_android_cts_verifier_camera_StatsImage.cpp \
+		com_android_cts_verifier_os_FileUtils.cpp
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
+LOCAL_SHARED_LIBRARIES := liblog
+
 include $(BUILD_SHARED_LIBRARY)
diff --git a/apps/CtsVerifier/jni/verifier/CtsVerifierJniOnLoad.cpp b/apps/CtsVerifier/jni/verifier/CtsVerifierJniOnLoad.cpp
index 81e5690..399275b 100644
--- a/apps/CtsVerifier/jni/verifier/CtsVerifierJniOnLoad.cpp
+++ b/apps/CtsVerifier/jni/verifier/CtsVerifierJniOnLoad.cpp
@@ -1,4 +1,4 @@
-/* 
+/*
  * Copyright (C) 2010 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,6 +18,7 @@
 #include <stdio.h>
 
 extern int register_com_android_cts_verifier_os_FileUtils(JNIEnv*);
+extern int register_com_android_cts_verifier_camera_its_StatsImage(JNIEnv*);
 
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv *env = NULL;
@@ -30,5 +31,9 @@
         return JNI_ERR;
     }
 
+    if (register_com_android_cts_verifier_camera_its_StatsImage(env)) {
+        return JNI_ERR;
+    }
+
     return JNI_VERSION_1_4;
 }
diff --git a/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp b/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp
new file mode 100644
index 0000000..16dff85
--- /dev/null
+++ b/apps/CtsVerifier/jni/verifier/com_android_cts_verifier_camera_StatsImage.cpp
@@ -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.
+ */
+
+#define LOG_TAG "ITS-StatsImage-JNI"
+// #define LOG_NDEBUG 0
+#include <android/log.h>
+#include <utils/Log.h>
+
+#include <jni.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <inttypes.h>
+#include <string.h>
+
+jfloatArray com_android_cts_verifier_camera_its_computeStatsImage(JNIEnv* env, jobject thiz,
+        jbyteArray img, jint width, jint height, jint gridWidth, jint gridHeight)
+{
+    int bufSize = (int)(env->GetArrayLength(img));
+    unsigned char *buf = (unsigned char*)env->GetByteArrayElements(img, /*is_copy*/NULL);
+
+    // Size of the raw image.
+    const int w = width;
+    const int h = height;
+    // Size of each grid cell.
+    const int gw = gridWidth;
+    const int gh = gridHeight;
+    // Number of grid cells (rounding down to full cells only at right+bottom edges).
+    const int ngx = w / gw;
+    const int ngy = h / gh;
+
+    float *mean = new float[ngy*ngx*4];
+    float *var = new float[ngy*ngx*4];
+    for (int gy = 0; gy < ngy; gy++) {
+        for (int gx = 0; gx < ngx; gx++) {
+            float sum[4] = {0};
+            float sumSq[4] = {0};
+            int count[4] = {0};
+            for (int y = gy*gh; y < (gy+1)*gh; y++) {
+                int chnOffset = (y & 0x1) * 2;
+                unsigned char *pbuf = buf + 2*y*w + 2*gx*gw;
+                for (int x = gx*gw; x < (gx+1)*gw; x++) {
+                    // input is RAW16
+                    int byte0 = *pbuf++;
+                    int byte1 = *pbuf++;
+                    int pixelValue = (byte1 << 8) | byte0;
+                    int ch = chnOffset + (x & 1);
+                    sum[ch] += pixelValue;
+                    sumSq[ch] += pixelValue * pixelValue;
+                    count[ch] += 1;
+                }
+            }
+            for (int ch = 0; ch < 4; ch++) {
+                float m = (float)sum[ch] / count[ch];
+                float mSq = (float)sumSq[ch] / count[ch];
+                mean[gy*ngx*4 + gx*4 + ch] = m;
+                var[gy*ngx*4 + gx*4 + ch] = mSq - m*m;
+            }
+        }
+    }
+
+    jfloatArray ret = env->NewFloatArray(ngx*ngy*4*2);
+    env->SetFloatArrayRegion(ret, 0, ngx*ngy*4, (float*)mean);
+    env->SetFloatArrayRegion(ret, ngx*ngy*4, ngx*ngy*4, (float*)var);
+    delete [] mean;
+    delete [] var;
+    return ret;
+}
+
+static JNINativeMethod gMethods[] = {
+    {  "computeStatsImage", "([BIIII)[F",
+            (void *) com_android_cts_verifier_camera_its_computeStatsImage  },
+};
+
+int register_com_android_cts_verifier_camera_its_StatsImage(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("com/android/cts/verifier/camera/its/StatsImage");
+
+    return env->RegisterNatives(clazz, gMethods,
+            sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/apps/CtsVerifier/lib/Android.mk b/apps/CtsVerifier/lib/Android.mk
deleted file mode 100644
index 56a3fa8..0000000
--- a/apps/CtsVerifier/lib/Android.mk
+++ /dev/null
@@ -1,17 +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.
-#
-
-include $(call all-subdir-makefiles)
diff --git a/apps/CtsVerifier/lib/colorchecker/Android.mk b/apps/CtsVerifier/lib/colorchecker/Android.mk
deleted file mode 100644
index 38f595f..0000000
--- a/apps/CtsVerifier/lib/colorchecker/Android.mk
+++ /dev/null
@@ -1,42 +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)
-
-#####################
-# Build image analysis library
-
-include $(CLEAR_VARS)
-include external/stlport/libstlport.mk
-
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := libcolorchecker
-
-LOCAL_SRC_FILES += testingimage.cpp \
-                   vec3.cpp \
-                   vec2.cpp \
-                   imagetesthandler.cpp \
-                   colorcheckertest.cpp \
-                   exposurecompensationtest.cpp \
-                   autolocktest.cpp \
-                   meteringtest.cpp \
-                   whitebalancetest.cpp
-
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../include/colorchecker
-LOCAL_SHARED_LIBRARIES := libstlport \
-                          libcutils \
-                          libutils
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/apps/CtsVerifier/lib/colorchecker/autolocktest.cpp b/apps/CtsVerifier/lib/colorchecker/autolocktest.cpp
deleted file mode 100644
index 6bfa922..0000000
--- a/apps/CtsVerifier/lib/colorchecker/autolocktest.cpp
+++ /dev/null
@@ -1,101 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "AutoLockTest"
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <cmath>
-#include <string>
-
-#include "vec2.h"
-#include "vec3.h"
-#include "autolocktest.h"
-
-const float kOverExposure = 230.f;
-const float kEqThreshold = 0.05f;
-// Processes the color checker values and compare the two values from
-// the same individual test.
-void AutoLockTest::processData() {
-    ALOGV("Start Processing Auto Lock Test Data!");
-
-    int numTests = mCheckerColors.size() / 2;
-    mNumPatches = 0;
-
-    if (numTests > 0) {
-        mNumPatches = mCheckerColors[0].size();
-    }
-
-    for (int i = 0; i < numTests; ++i) {
-        mComparisonResults.push_back(
-                IsBrighterThan((&mCheckerColors[i * 2]),
-                               (&mCheckerColors[i * 2 + 1])));
-        mComparisonResults.push_back(
-                IsEquivalentTo((&mCheckerColors[i * 2]),
-                               (&mCheckerColors[i * 2 + 1])));
-    }
-}
-
-// Compares whether one array of gray color patches is brighter than
-// another one.
-bool AutoLockTest::IsBrighterThan(
-        const std::vector<Vec3f>* colorCheckers1,
-        const std::vector<Vec3f>* colorCheckers2) const {
-    float meanRatio = 0.f;
-    int meanNumCount = 0;
-
-    for (int i = 0; i < mNumPatches; ++i) {
-        float luminance1 = (*colorCheckers1)[i].convertToLuminance();
-        float luminance2 = (*colorCheckers2)[i].convertToLuminance();
-
-        // Consider a 5% raise as a considerably large increase.
-        if ((luminance1 < kOverExposure) && (luminance2 != 0.f)) {
-            meanRatio += luminance1 / luminance2;
-            ++meanNumCount;
-        }
-    }
-    meanRatio = meanRatio / meanNumCount;
-
-    return (meanRatio > 1 + kEqThreshold);
-}
-
-// Compares whether one array of gray color patches is within a small range
-// of the other one to be considered equivalent.
-bool AutoLockTest::IsEquivalentTo(
-        const std::vector<Vec3f>* colorCheckers1,
-        const std::vector<Vec3f>* colorCheckers2) const {
-    float meanRatio = 0.f;
-    int meanNumCount = 0;
-
-    for (int i = 0; i < mNumPatches; ++i) {
-        float luminance1 = (*colorCheckers1)[i].convertToLuminance();
-        float luminance2 = (*colorCheckers2)[i].convertToLuminance();
-        ALOGV("Luma_1 and Luma_2 is %f, %f", luminance1, luminance2);
-
-        if ((luminance1 < kOverExposure) && (luminance2 < kOverExposure)) {
-              meanRatio += luminance2 / luminance1;
-              ++meanNumCount;
-        }
-    }
-    meanRatio = meanRatio / meanNumCount;
-
-    return ((meanRatio >= 1 - kEqThreshold) && (meanRatio <= 1 + kEqThreshold));
-}
-
-void AutoLockTest::clearData() {
-    mCheckerColors.clear();
-    mComparisonResults.clear();
-}
diff --git a/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp b/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp
deleted file mode 100644
index 46b8cc8..0000000
--- a/apps/CtsVerifier/lib/colorchecker/colorcheckertest.cpp
+++ /dev/null
@@ -1,979 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "ColorCheckerTest"
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <cmath>
-#include <string>
-
-#include "vec2.h"
-#include "vec3.h"
-#include "colorcheckertest.h"
-
-const float GAMMA_CORRECTION = 2.2f;
-const float COLOR_ERROR_THRESHOLD = 200.f;
-ColorCheckerTest::~ColorCheckerTest() {
-    ALOGV("Deleting color checker test handler");
-
-    if (mImage != NULL) {
-        delete mImage;
-    }
-    ALOGV("Image deleted");
-
-    int numHorizontalLines = mCandidateColors.size();
-    int numVerticalLines = mCandidateColors[0].size();
-
-    for (int i = 0; i < numHorizontalLines; ++i) {
-        for (int j = 0; j < numVerticalLines; ++j) {
-            if (mCandidateColors[i][j] != NULL) {
-                delete mCandidateColors[i][j];
-            }
-            if (mCandidatePositions[i][j] != NULL) {
-                delete mCandidatePositions[i][j];
-            }
-        }
-    }
-    ALOGV("Candidates deleted!");
-
-    for (int i = 0; i < 4; ++i) {
-        for (int j = 0; j < 6; ++j) {
-            if (mMatchPositions[i][j] != NULL) {
-                delete mMatchPositions[i][j];
-            }
-            if (mReferenceColors[i][j] != NULL) {
-                delete mReferenceColors[i][j];
-            }
-            if (mMatchColors[i][j] != NULL) {
-                delete mMatchColors[i][j];
-            }
-        }
-    }
-}
-
-// Adds a new image to the test handler.
-void ColorCheckerTest::addTestingImage(TestingImage* inputImage) {
-    if (mImage != NULL) {
-        delete mImage;
-    }
-    mImage = NULL;
-    ALOGV("Original image deleted");
-    mImage = inputImage;
-
-    if ((mImage->getHeight() == getDebugHeight()) &&
-        (mImage->getWidth() == getDebugWidth())) {
-        copyDebugImage(getDebugHeight(), getDebugWidth(), mImage->getImage());
-    }
-}
-
-void ColorCheckerTest::processData() {
-    mSuccess = false;
-    initializeRefColor();
-    edgeDetection();
-}
-
-void ColorCheckerTest::initializeRefColor() {
-    mReferenceColors.resize(4, std::vector<Vec3i*>(6, NULL));
-    mMatchPositions.resize(4, std::vector<Vec2f*>(6, NULL));
-    mMatchColors.resize(4, std::vector<Vec3f*>(6, NULL));
-    mMatchRadius.resize(4, std::vector<float>(6, 0.f));
-
-    mReferenceColors[0][0]= new Vec3i(115, 82, 68);
-    mReferenceColors[0][1]= new Vec3i(194, 150, 130);
-    mReferenceColors[0][2]= new Vec3i(98, 122, 157);
-    mReferenceColors[0][3]= new Vec3i(87, 108, 67);
-    mReferenceColors[0][4]= new Vec3i(133, 128, 177);
-    mReferenceColors[0][5]= new Vec3i(103, 189, 170);
-    mReferenceColors[1][0]= new Vec3i(214, 126, 44);
-    mReferenceColors[1][1]= new Vec3i(80, 91, 166);
-    mReferenceColors[1][2]= new Vec3i(193, 90, 99);
-    mReferenceColors[1][3]= new Vec3i(94,  60, 108);
-    mReferenceColors[1][4]= new Vec3i(157, 188, 64);
-    mReferenceColors[1][5]= new Vec3i(224, 163, 46);
-    mReferenceColors[2][0]= new Vec3i(56, 61, 150);
-    mReferenceColors[2][1]= new Vec3i(70, 148, 73);
-    mReferenceColors[2][2]= new Vec3i(175, 54, 60);
-    mReferenceColors[2][3]= new Vec3i(231, 199, 31);
-    mReferenceColors[2][4]= new Vec3i(187, 86, 149);
-    mReferenceColors[2][5]= new Vec3i(8, 133, 161);
-    mReferenceColors[3][0]= new Vec3i(243, 243, 242);
-    mReferenceColors[3][1]= new Vec3i(200, 200, 200);
-    mReferenceColors[3][2]= new Vec3i(160, 160, 160);
-    mReferenceColors[3][3]= new Vec3i(122, 122, 121);
-    mReferenceColors[3][4]= new Vec3i(85, 85, 85);
-    mReferenceColors[3][5]= new Vec3i(52, 52, 52);
-}
-
-void ColorCheckerTest::edgeDetection() {
-    int width = mImage->getWidth();
-    int height = mImage->getHeight();
-
-    bool* edgeMap = new bool[height * width];
-    unsigned char* grayImage = new unsigned char[height * width];
-
-    // If the image is a color image and can be converted to a luminance layer
-    if (mImage->rgbToGrayScale(grayImage)) {
-        float* gradientMap = new float[height * width * 2];
-
-        // Computes the gradient image on the luminance layer.
-        computeGradient(grayImage, gradientMap);
-
-        float* gradientMagnitude = new float[height * width];
-        int* gradientDirectionInt = new int[height * width];
-        float* gradientDirection = new float[height * width];
-
-        // Computes the absolute gradient of the image without padding.
-        for (int i = 1; i < height - 1; ++i) {
-            for (int j = 1; j < width - 1; ++j) {
-                gradientMagnitude[i * width + j] =
-                        sqrt(gradientMap[(i * width + j) * 2] *
-                             gradientMap[(i * width + j) * 2] +
-                             gradientMap[(i * width + j ) * 2 + 1] *
-                             gradientMap[(i * width + j ) * 2 + 1]);
-
-                // Computes the gradient direction of the image.
-                if (gradientMap[(i * width + j) * 2] == 0 ) {
-                    // If the vertical gradient is 0, the edge is horizontal
-                    // Mark the gradient direction as 90 degrees.
-                    gradientDirectionInt[i * width + j] = 2;
-                    gradientDirection[i * width + j] = 90.0f;
-                } else {
-                    // Otherwise the atan operation is valid and can decide
-                    // the gradient direction of the edge.
-                    float gradient = atan(gradientMap[(i * width + j) * 2 + 1]
-                            / gradientMap[(i * width + j) * 2])
-                            / (M_PI / 4);
-
-                    gradientDirection[i * width + j] = gradient * 45.0f;
-
-                    // Maps the gradient direction to 4 major directions with
-                    // 0 mapped to up and 2 mapped to right.
-                    if (gradient - floor(gradient) > 0.5) {
-                        gradientDirectionInt[i * width + j] =
-                                (static_cast<int>(ceil(gradient)) + 4) % 4;
-                    } else {
-                        gradientDirectionInt[i * width + j] =
-                                (static_cast<int>(floor(gradient)) + 4) % 4;
-                    }
-                }
-            }
-        }
-
-        // Compute a boolean map to show whether a pixel is on the edge.
-        for (int i = 1; i < height - 1; ++i) {
-            for (int j = 1; j < width - 1; ++j) {
-                edgeMap[i * width + j] = false;
-
-                switch (gradientDirectionInt[i * width + j]) {
-                    case 0:
-                        // If the gradient points rightwards, the pixel is
-                        // on an edge if it has a larger absolute gradient than
-                        // pixels on its left and right sides.
-                        if ((gradientMagnitude[i * width + j] >=
-                                gradientMagnitude[i * width + j + 1]) &&
-                            (gradientMagnitude[i * width + j] >=
-                                gradientMagnitude[i * width + j - 1])) {
-                            edgeMap[i * width + j] = true;
-                        }
-                        break;
-                    case 1:
-                        // If the gradient points right-downwards, the pixel is
-                        // on an edge if it has a larger absolute gradient than
-                        // pixels on its upper left and bottom right sides.
-                        if ((gradientMagnitude[i * width + j] >=
-                                gradientMagnitude[(i + 1) * width + j + 1]) &&
-                            (gradientMagnitude[i * width + j] >=
-                                gradientMagnitude[(i - 1) * width + j - 1])) {
-                            edgeMap[i * width + j] = true;
-                        }
-                        break;
-                    case 2:
-                        // If the gradient points upwards, the pixel is
-                        // on an edge if it has a larger absolute gradient than
-                        // pixels on its up and down sides.
-                        if ((gradientMagnitude[i * width + j] >=
-                                gradientMagnitude[(i + 1) * width + j]) &&
-                            (gradientMagnitude[i * width + j] >=
-                                gradientMagnitude[(i - 1) * width + j])) {
-                            edgeMap[i * width + j] = true;
-                        }
-                        break;
-                    case 3:
-                        // If the gradient points right-upwards, the pixel is
-                        // on an edge if it has a larger absolute gradient than
-                        // pixels on its bottom left and upper right sides.
-                        if ((gradientMagnitude[i * width + j] >=
-                                gradientMagnitude[(i - 1) * width + j + 1]) &&
-                            (gradientMagnitude[i * width + j] >=
-                                gradientMagnitude[(i + 1) * width + j - 1])) {
-                            edgeMap[i * width + j] = true;
-                        }
-                  }
-
-             }
-        }
-
-        houghLineDetection(edgeMap, gradientMagnitude, gradientDirection);
-
-        // Cleans up
-        delete[] gradientMap;
-        delete[] gradientDirectionInt;
-        delete[] gradientMagnitude;
-        delete[] gradientDirection;
-
-    } else {
-        ALOGE("Not a color image!");
-    }
-
-    delete[] edgeMap;
-    delete[] grayImage;
-}
-
-// Runs the hough voting algorithm to find the grid of the color checker
-// with the edge map, gradient direction and gradient magnitude as inputs.
-void ColorCheckerTest::houghLineDetection(bool* edgeMap,
-                                          float* gradientMagnitude,
-                                          float* gradientDirection) {
-    // Constructs a graph for Hough voting. The vertical axis counts the vote
-    // for a certain angle. The horizontal axis counts the vote for the distance
-    // of a line from the origin of the image.
-    int houghHeight = 180;
-    int houghWidth = 200;
-    int houghCounts[houghHeight][houghWidth];
-    int houghSum[houghHeight][houghWidth];
-
-    int** houghVote;
-    houghVote = new int*[180];
-    for (int i = 0; i < 180; ++i) {
-        houghVote[i] = new int[200];
-    }
-
-    for (int i = 0; i < houghHeight; ++i) {
-        for (int j = 0; j < houghWidth; ++j) {
-            houghCounts[i][j] = 0;
-            houghVote[i][j] = 0;
-            houghSum[i][j] = 0;
-        }
-    }
-
-    // Vectors to record lines in two orthogonal directions.
-    // Each line is represented by its direction and its distance to the origin.
-    std::vector<std::vector<int> > verticalLines;
-    std::vector<std::vector<int> > horizontalLines;
-    float radius;
-    int height = mImage->getHeight();
-    int width = mImage->getWidth();
-
-    // Processes the signicant edge pixels and cast vote for the corresponding
-    // edge passing this pixel.
-    for (int i = 1; i < height - 1; ++i) {
-        for (int j = 1; j < width - 1; ++j) {
-            // Sets threashold for the gradient magnitude to discount noises
-            if (edgeMap[i * width + j] &&
-                (gradientMagnitude[i * width + j] > 15)) {
-                int shiftedAngle;
-
-                // Shifts angles for 45 degrees so the vertical and horizontal
-                // direction is mapped to 45 and 135 degrees to avoid padding.
-                // This uses the assumption that the color checker is placed
-                // roughly parallel to the image boarders. So that the edges
-                // at the angle of 45 will be rare.
-                shiftedAngle = (static_cast<int>(
-                        -gradientDirection[i * width + j]) + 225 % 180);
-                float shiftedAngleRad = static_cast<float>(shiftedAngle)
-                        * M_PI / 180.0f;
-
-                // Computes the distance of the line from the origin.
-                float a, b;
-                a = static_cast<float>(i - j) / sqrt(2.0f);
-                b = static_cast<float>(i + j) / sqrt(2.0f);
-                radius = a * sin(shiftedAngleRad) - b * cos(shiftedAngleRad);
-
-                // Adds one vote for the line. The line's angle is shifted by
-                // 45 degrees to avoid avoid padding for the vertical lines,
-                // which is more common than diagonal lines. The line's
-                // distance is mapped to [0, 200] from [-200, 200].
-                ++houghCounts[shiftedAngle][static_cast<int>((radius / 2.0f) +
-                                                              100.0f)];
-
-                drawPoint(i, j, Vec3i(255, 255, 255));
-            }
-        }
-    }
-
-    int houghAngleSum[houghHeight];
-    int primaryVerticalAngle, primaryHorizontalAngle;
-    int max1 = 0;
-    int max2 = 0;
-
-    // Looking for the two primary angles of the lines.
-    for (int i = 5; i < houghHeight - 5; ++i) {
-        houghAngleSum[i] = 0;
-        for (int j = 0; j < houghWidth; ++j) {
-            for (int l = -5; l <= 5; ++l) {
-                houghSum[i][j] += houghCounts[i + l][j];
-            }
-            houghAngleSum[i] += houghSum[i][j];
-        }
-
-        if ((i < houghHeight / 2) && (houghAngleSum[i] > max1)) {
-            max1 = houghAngleSum[i];
-            primaryVerticalAngle = i;
-        } else if ((i > houghHeight / 2) && (houghAngleSum[i] > max2)) {
-            max2 = houghAngleSum[i];
-            primaryHorizontalAngle = i;
-        }
-    }
-
-    ALOGV("Primary angles are %d, %d",
-         primaryVerticalAngle, primaryHorizontalAngle);
-
-    int angle;
-
-    // For each primary angle, look for the highest voted lines.
-    for (int k = 0; k < 2; ++k) {
-        if (k == 0) {
-            angle = primaryVerticalAngle;
-        } else {
-            angle = primaryHorizontalAngle;
-        }
-
-        std::vector<int> line(2);
-        for (int j = 2; j < houghWidth - 2; ++j) {
-            houghVote[angle][j] = houghSum[angle][j];
-            houghSum[angle][j] = 0;
-        }
-
-        // For each radius, average the vote with nearby ones.
-        for (int j = 2; j < houghWidth - 2; ++j) {
-            for (int m = -2; m <= 2; ++m) {
-                houghSum[angle][j] += houghVote[angle][j + m];
-            }
-        }
-
-        bool isCandidate[houghWidth];
-
-        // Find whether a lines is a candidate by rejecting the ones that have
-        // lower vote than others in the neighborhood.
-        for (int j = 2; j < houghWidth - 2; ++j) {
-            isCandidate[j] = true;
-            for (int m = -2; ((isCandidate[j]) && (m <= 2)); ++m) {
-                if ((houghSum[angle][j] < 20) ||
-                    (houghSum[angle][j] < houghSum[angle][j + m])) {
-                    isCandidate[j] = false;
-                }
-            }
-        }
-
-        int iter1 = 0;
-        int iter2 = 0;
-        int count = 0;
-
-        // Finds the lines that are not too close to each other and add to the
-        // detected lines.
-        while (iter2 < houghWidth) {
-            while ((!isCandidate[iter2]) && (iter2 < houghWidth)) {
-                ++iter2;
-            }
-            if ((isCandidate[iter2]) && (iter2 - iter1 < 5)) {
-                iter1 = (iter2 + iter1) / 2;
-                ++iter2;
-            } else {
-                line[0] = angle;
-                line[1] = (iter1 - 100) * 2;
-                if (iter1 != 0) {
-                    if (k == 0) {
-                        verticalLines.push_back(line);
-                        Vec3i color(verticalLines.size() * 20, 0, 0);
-                        drawLine(line[0], line[1], color);
-                    } else {
-                        horizontalLines.push_back(line);
-                        Vec3i color(0, horizontalLines.size() * 20, 0);
-                        drawLine(line[0], line[1], color);
-                    }
-                }
-                iter1 = iter2;
-                ++iter2;
-                ALOGV("pushing back line %d %d", line[0], line[1]);
-            }
-        }
-    }
-
-    ALOGV("Numbers of lines in each direction is %d, %d",
-         verticalLines.size(), horizontalLines.size());
-
-    for (int i = 0; i < 180; ++i) {
-        delete[] houghVote[i];
-    }
-    delete[] houghVote;
-
-    findCheckerBoards(verticalLines, horizontalLines);
-}
-
-// Computes the gradient in both x and y direction of a layer
-void ColorCheckerTest::computeGradient(unsigned char* layer,
-                                       float* gradientMap) {
-    int width = mImage->getWidth();
-    int height = mImage->getHeight();
-
-    // Computes the gradient in the whole image except the image boarders.
-    for (int i = 1; i < height - 1; ++i) {
-        for (int j = 1; j < width - 1; ++j) {
-            gradientMap[(i * width + j) * 2] =
-                    0.5f * (layer[i * width + j + 1] -
-                            layer[i * width + j - 1]);
-            gradientMap[(i * width + j) * 2 + 1] =
-                    0.5f * (layer[(i + 1) * width + j] -
-                           layer[(i - 1) * width + j]);
-        }
-    }
-}
-
-// Tries to find the checker boards with the highest voted lines
-void ColorCheckerTest::findCheckerBoards(
-        std::vector<std::vector<int> > verticalLines,
-        std::vector<std::vector<int> > horizontalLines) {
-    ALOGV("Start looking for Color checker");
-
-    int numHorizontalLines = mCandidateColors.size();
-    int numVerticalLines;
-    if (numHorizontalLines > 0) {
-        numVerticalLines = mCandidateColors[0].size();
-        for (int i = 0; i < numHorizontalLines; ++i) {
-            for (int j = 0; j < numVerticalLines; ++j) {
-                if (mCandidateColors[i][j] != NULL) {
-                    delete mCandidateColors[i][j];
-                }
-                if (mCandidatePositions[i][j] != NULL) {
-                    delete mCandidatePositions[i][j];
-                }
-            }
-            mCandidateColors[i].clear();
-            mCandidatePositions[i].clear();
-        }
-    }
-    mCandidateColors.clear();
-    mCandidatePositions.clear();
-
-    ALOGV("Candidates deleted!");
-
-    numVerticalLines = verticalLines.size();
-    numHorizontalLines = horizontalLines.size();
-    Vec2f pointUpperLeft;
-    Vec2f pointBottomRight;
-
-    mCandidateColors.resize(numHorizontalLines - 1);
-    mCandidatePositions.resize(numHorizontalLines - 1);
-
-    for (int i = numVerticalLines - 1; i >= 1; --i) {
-        for (int j = 0; j < numHorizontalLines - 1; ++j) {
-            // Finds the upper left and bottom right corner of each rectangle
-            // formed by two neighboring highest voted lines.
-            pointUpperLeft = findCrossing(verticalLines[i], horizontalLines[j]);
-            pointBottomRight = findCrossing(verticalLines[i - 1],
-                                            horizontalLines[j + 1]);
-
-            Vec3i* color = new Vec3i();
-            Vec2f* pointCenter = new Vec2f();
-            // Verifies if they are separated by a reasonable distance.
-            if (verifyPointPair(pointUpperLeft, pointBottomRight,
-                                pointCenter, color)) {
-                mCandidatePositions[j].push_back(pointCenter);
-                mCandidateColors[j].push_back(color);
-                ALOGV("Color at (%d, %d) is (%d, %d, %d)", j, i,color->r(), color->g(), color->b());
-
-            } else {
-                mCandidatePositions[j].push_back(NULL);
-                mCandidateColors[j].push_back(NULL);
-                delete color;
-                delete pointCenter;
-            }
-        }
-    }
-
-    ALOGV("Candidates Number (%d, %d)", mCandidateColors.size(), mCandidateColors[0].size());
-    // Verifies whether the current line candidates form a valid color checker.
-    verifyColorGrid();
-}
-
-// Returns the corssing point of two lines given the lines.
-Vec2f ColorCheckerTest::findCrossing(std::vector<int> line1,
-                                     std::vector<int> line2) {
-    Vec2f crossingPoint;
-    float r1 = static_cast<float>(line1[1]);
-    float r2 = static_cast<float>(line2[1]);
-    float ang1, ang2;
-    float y1, y2;
-
-    ang1 = static_cast<float>(line1[0]) / 180.0f * M_PI;
-    ang2 = static_cast<float>(line2[0]) / 180.0f * M_PI;
-
-    float x, y;
-    x = (r1 * cos(ang2) - r2 * cos(ang1)) / sin(ang1 - ang2);
-    y = (r1 * sin(ang2) - r2 * sin(ang1)) / sin(ang1 - ang2);
-
-    crossingPoint.set((x + y) / sqrt(2.0), (y - x) / sqrt(2.0));
-
-    //ALOGV("Crosspoint at (%f, %f)", crossingPoint.x(), crossingPoint.y());
-    return crossingPoint;
-}
-
-// Verifies whether two opposite corners on a quadrilateral actually can be
-// the two corners of a color checker.
-bool ColorCheckerTest::verifyPointPair(Vec2f pointUpperLeft,
-                                       Vec2f pointBottomRight,
-                                       Vec2f* pointCenter,
-                                       Vec3i* color) {
-    bool success = true;
-
-    /** 5 and 30 are the threshold tuned for resolution 640*480*/
-    if ((pointUpperLeft.x() < 0) ||
-        (pointUpperLeft.x() >= mImage->getHeight()) ||
-        (pointUpperLeft.y() < 0) ||
-        (pointUpperLeft.y() >= mImage->getWidth()) ||
-        (pointBottomRight.x() < 0) ||
-        (pointBottomRight.x() >= mImage->getHeight()) ||
-        (pointBottomRight.y() < 0) ||
-        (pointBottomRight.y() >= mImage->getWidth()) ||
-        (abs(pointUpperLeft.x() - pointBottomRight.x()) <= 5) ||
-        (abs(pointUpperLeft.y() - pointBottomRight.y()) <= 5) ||
-        (abs(pointUpperLeft.x() - pointBottomRight.x()) >= 30) ||
-        (abs(pointUpperLeft.y() - pointBottomRight.y()) >= 30)) {
-
-        // If any of the quadrilateral corners are out of the image or if
-        // the distance between them are too large or too big, the quadrilateral
-        // could not be one of the checkers
-        success = false;
-    } else {
-        // Find the checker center if the corners of the rectangle meet criteria
-        pointCenter->set((pointUpperLeft.x() + pointBottomRight.x()) / 2.0f,
-                       (pointUpperLeft.y() + pointBottomRight.y()) / 2.0f);
-        color->set(mImage->getPixelValue(*pointCenter).r(),
-                   mImage->getPixelValue(*pointCenter).g(),
-                   mImage->getPixelValue(*pointCenter).b());
-        ALOGV("Color at (%f, %f) is (%d, %d, %d)", pointCenter->x(), pointCenter->y(),color->r(), color->g(), color->b());
-    }
-    return success;
-}
-
-// Verifies the color checker centers and finds the match between the detected
-// color checker and the reference MacBeth color checker
-void ColorCheckerTest::verifyColorGrid() {
-    ALOGV("Start looking for Color Grid");
-    int numHorizontalLines = mCandidateColors.size();
-    int numVerticalLines = mCandidateColors[0].size();
-    bool success = false;
-
-    // Computes the standard deviation of one row/column of the proposed color
-    // checker. Discards the row/column if the std is below a threshold.
-    for (int i = 0; i < numHorizontalLines; ++i) {
-        Vec3f meanColor(0.f, 0.f, 0.f);
-        int numNonZero = 0;
-
-        for (int j = 0; j < numVerticalLines; ++j) {
-            if (mCandidateColors[i][j] != NULL) {
-                ALOGV("candidate color (%d, %d) is (%d, %d, %d)", i, j, mCandidateColors[i][j]->r(), mCandidateColors[i][j]->g(), mCandidateColors[i][j]->b());
-
-                meanColor = meanColor + (*mCandidateColors[i][j]);
-                ++numNonZero;
-            }
-        }
-        if (numNonZero > 0) {
-            meanColor = meanColor / numNonZero;
-        }
-        ALOGV("Mean color for vertical direction computed!");
-
-        float std = 0;
-        for (int j = 0; j < numVerticalLines; ++j) {
-            if (mCandidateColors[i][j] != NULL) {
-                std += mCandidateColors[i][j]->squareDistance<float>(meanColor);
-            }
-        }
-        if (numNonZero > 0) {
-            std = sqrt(std / (3 * numNonZero));
-        }
-        ALOGV("st. deviation for the %d dir1 is %d", i, static_cast<int>(std));
-
-        if ((std <= 30) && (numNonZero > 1)) {
-            for (int j = 0; j < numVerticalLines; ++j) {
-                if (mCandidateColors[i][j] != NULL) {
-                    delete mCandidateColors[i][j];
-                    mCandidateColors[i][j] = NULL;
-                }
-            }
-        }
-    }
-
-    // Discards the column/row of the color checker if the std is below a
-    // threshold.
-    for (int j = 0; j < numVerticalLines; ++j) {
-        Vec3f meanColor(0.f, 0.f, 0.f);
-        int numNonZero = 0;
-
-        for (int i = 0; i < numHorizontalLines; ++i) {
-            if (mCandidateColors[i][j] != NULL) {
-                meanColor = meanColor + (*mCandidateColors[i][j]);
-                ++numNonZero;
-            }
-        }
-        if (numNonZero > 0) {
-            meanColor = meanColor / numNonZero;
-        }
-
-        float std = 0;
-        for (int i = 0; i < numHorizontalLines; ++i) {
-            if (mCandidateColors[i][j] != NULL) {
-                std += mCandidateColors[i][j]->squareDistance<float>(meanColor);
-            }
-        }
-        if (numNonZero > 0) {
-            std = sqrt(std / (3 * numNonZero));
-        }
-
-        ALOGV("st. deviation for the %d dir2 is %d", j, static_cast<int>(std));
-
-        if ((std <= 30) && (numNonZero > 1)) {
-            for (int i = 0; i < numHorizontalLines; ++i) {
-                if (mCandidateColors[i][j] != NULL) {
-                    delete mCandidateColors[i][j];
-                    mCandidateColors[i][j] = NULL;
-                }
-            }
-        }
-    }
-
-    for (int i = 0; i < numHorizontalLines; ++i) {
-        for (int j = 0; j < numVerticalLines; ++j) {
-            if (mCandidateColors[i][j] != NULL) {
-                ALOGV("position (%d, %d) is at (%f, %f) with color (%d, %d, %d)",
-                     i, j,
-                     mCandidatePositions[i][j]->x(),
-                     mCandidatePositions[i][j]->y(),
-                     mCandidateColors[i][j]->r(),
-                     mCandidateColors[i][j]->g(),
-                     mCandidateColors[i][j]->b());
-            } else {
-                ALOGV("position (%d, %d) is 0", i, j);
-            }
-        }
-    }
-
-    // Finds the match between the detected color checker and the reference
-    // MacBeth color checker.
-    int rowStart = 0;
-    int rowEnd = 0;
-
-    // Loops until all dectected color checker has been processed.
-    while (!success) {
-        int columnStart = 0;
-        int columnEnd = 0;
-        bool isRowStart = false;
-        bool isRowEnd = true;
-
-        // Finds the row start of the next block of detected color checkers.
-        while ((!isRowStart) && (rowStart <  numHorizontalLines)) {
-            for (int j = 0; j < numVerticalLines; ++j) {
-                if (mCandidateColors[rowStart][j] != NULL) {
-                    isRowStart = true;
-                }
-            }
-            ++rowStart;
-        }
-        rowStart--;
-        rowEnd = rowStart;
-        ALOGV("rowStart is %d", rowStart);
-
-        // Finds the row end of the next block of detected color checkers.
-        while ((isRowEnd) && (rowEnd < numHorizontalLines)) {
-            isRowEnd = false;
-            for (int j = 0; j < numVerticalLines; ++j) {
-                if (mCandidateColors[rowEnd][j] != NULL) {
-                    isRowEnd= true;
-                }
-            }
-            if (isRowEnd) {
-                ++rowEnd;
-            }
-        }
-        if ((!isRowEnd) && isRowStart) {
-            rowEnd--;
-        }
-        if ((isRowEnd) && (rowEnd == numHorizontalLines)) {
-            rowEnd--;
-            isRowEnd = false;
-        }
-        ALOGV("rowEnd is %d", rowEnd);
-
-        // Matches color checkers between the start row and the end row.
-        bool successVertical = false;
-
-        while (!successVertical) {
-            bool isColumnEnd = true;
-            bool isColumnStart = false;
-
-            // Finds the start column of the next block of color checker
-            while ((!isColumnStart) && (columnStart < numVerticalLines)) {
-                if (mCandidateColors[rowStart][columnStart] != NULL) {
-                    isColumnStart = true;
-                }
-                ++columnStart;
-            }
-            columnStart--;
-            columnEnd = columnStart;
-
-            // Finds the end column of the next block of color checker
-            while ((isColumnEnd) && (columnEnd < numVerticalLines)) {
-                isColumnEnd = false;
-                if (mCandidateColors[rowStart][columnEnd] != NULL)
-                    isColumnEnd = true;
-                if (isColumnEnd) {
-                    ++columnEnd;
-                }
-            }
-
-            if ((!isColumnEnd) && isColumnStart) {
-                columnEnd--;
-            }
-            if ((isColumnEnd) && (columnEnd == numVerticalLines)) {
-                columnEnd--;
-                isColumnEnd = false;
-            }
-
-            // Finds the best match on the MacBeth reference color checker for
-            // the continuous block of detected color checker
-            if (isRowStart && (!isRowEnd) &&
-                isColumnStart && (!isColumnEnd)) {
-                findBestMatch(rowStart, rowEnd, columnStart, columnEnd);
-            }
-            ALOGV("FindBestMatch for %d, %d, %d, %d", rowStart,
-                 rowEnd, columnStart, columnEnd);
-
-            // If the column search finishes, go out of the loop
-            if (columnEnd >= numVerticalLines - 1) {
-                successVertical = true;
-            } else {
-                columnStart = columnEnd + 1;
-            }
-        }
-        ALOGV("Continuing to search for direction 1");
-
-        // If the row search finishes, go out of the loop
-        if (rowEnd >= numHorizontalLines - 1) {
-            success = true;
-        } else {
-            rowStart = rowEnd + 1;
-        }
-    }
-
-    for (int i = 0; i < 4; ++i) {
-        for (int j = 0; j < 6; ++j) {
-            if (mMatchPositions[i][j] != NULL) {
-                ALOGV("Reference Match position for (%d, %d) is (%f, %f)", i, j,
-                     mMatchPositions[i][j]->x(), mMatchPositions[i][j]->y());
-            }
-        }
-    }
-
-    fillRefColorGrid();
-}
-
-// Finds the best match on the MacBeth color checker for the continuous block of
-// detected color checkers bounded by row i1, row i2 and column j1 and column j2
-// Assumes that the subsample is less than 4*6.
-void ColorCheckerTest::findBestMatch(int i1, int i2, int j1, int j2) {
-    int numHorizontalGrid = i2 - i1 + 1;
-    int numVerticalGrid = j2 - j1 + 1;
-
-    if (((numHorizontalGrid > 1) || (numVerticalGrid > 1)) &&
-        (numHorizontalGrid <= 4) && (numVerticalGrid <= 6)) {
-        ALOGV("i1, j2, j1, j2 is %d, %d, %d, %d", i1, i2, j1, j2);
-        float minError;
-        float error = 0.f;
-        int horizontalMatch, verticalMatch;
-
-        // Finds the match start point where the error is minimized.
-        for (int i = 0; i < numHorizontalGrid; ++i) {
-            for (int j = 0; j < numVerticalGrid; ++j) {
-                if (mCandidateColors[i1 + i][j1 + j] != NULL) {
-                    error += mCandidateColors[i1 + i][j1 + j]->squareDistance<int>(
-                            *mReferenceColors[i][j]);
-                }
-            }
-        }
-        ALOGV("Error is %f", error);
-        minError = error;
-        horizontalMatch = 0;
-        verticalMatch = 0;
-
-        for (int i = 0; i <= 4 - numHorizontalGrid; ++i) {
-            for (int j = 0; j <= 6 - numVerticalGrid; ++j) {
-                error = 0.f;
-
-                for (int id = 0; id < numHorizontalGrid; ++id) {
-                    for (int jd = 0; jd < numVerticalGrid; ++jd) {
-                        if (mCandidateColors[i1 + id][j1 + jd] != NULL) {
-                            error += mCandidateColors[i1 + id][j1 + jd]->
-                                    squareDistance<int>(
-                                            *mReferenceColors[i + id][j + jd]);
-                        }
-                    }
-                }
-
-                if (error < minError) {
-                    minError = error;
-                    horizontalMatch = i;
-                    verticalMatch = j;
-                }
-                ALOGV("Processed %d, %d and error is %f", i, j, error );
-            }
-        }
-
-        for (int id = 0; id < numHorizontalGrid; ++id) {
-            for (int jd = 0; jd < numVerticalGrid; ++jd) {
-                if (mCandidatePositions[i1 + id][j1 + jd] != NULL) {
-                    mMatchPositions[horizontalMatch + id][verticalMatch + jd] =
-                            new Vec2f(mCandidatePositions[i1 + id][j1 + jd]->x(),
-                                      mCandidatePositions[i1 + id][j1 + jd]->y());
-                }
-            }
-        }
-        ALOGV("Grid match starts at %d, %d", horizontalMatch, verticalMatch);
-    }
-}
-
-// Finds the boundary of a color checker by its color similarity to the center.
-// Also predicts the location of unmatched checkers.
-void ColorCheckerTest::fillRefColorGrid() {
-    int rowStart = 0;
-    int columnStart = 0;
-    bool foundStart = true;
-
-    for (int i = 0; (i < 4) && foundStart; ++i) {
-        for (int j = 0; (j < 6) && foundStart; ++j) {
-            if (mMatchPositions[i][j] != NULL) {
-                rowStart = i;
-                columnStart = j;
-                foundStart = false;
-            }
-        }
-    }
-    ALOGV("First match found at (%d, %d)", rowStart, columnStart);
-
-    float rowDistance, columnDistance;
-    rowDistance = 0;
-    columnDistance = 0;
-    int numRowGrids = 0;
-    int numColumnGrids = 0;
-
-    for (int i = rowStart; i < 4; ++i) {
-        for (int j = columnStart; j < 6; ++j) {
-            if (mMatchPositions[i][j] != NULL) {
-                if (i > rowStart) {
-                    ++numRowGrids;
-                    rowDistance += (mMatchPositions[i][j]->x() -
-                                mMatchPositions[rowStart][columnStart]->x()) /
-                                static_cast<float>(i - rowStart);
-                }
-                if (j > columnStart) {
-                    ++numColumnGrids;
-                    columnDistance += (mMatchPositions[i][j]->y() -
-                                mMatchPositions[rowStart][columnStart]->y()) /
-                                static_cast<float>(j - columnStart);
-                }
-            }
-        }
-    }
-
-    if ((numRowGrids > 0) && (numColumnGrids > 0)) {
-        rowDistance = rowDistance / numRowGrids;
-        columnDistance = columnDistance / numColumnGrids;
-        ALOGV("delta is %f, %f", rowDistance, columnDistance);
-
-        for (int i = 0; i < 4; ++i) {
-            for (int j = 0 ; j < 6; ++j) {
-                if (mMatchPositions[i][j] == NULL) {
-                    mMatchPositions[i][j] = new Vec2f(
-                            mMatchPositions[rowStart][columnStart]->x() +
-                                    (i - rowStart) * rowDistance,
-                            mMatchPositions[rowStart][columnStart]->y() +
-                                    (j - columnStart) * columnDistance);
-                }
-            }
-        }
-        for (int i = 0; i < 4; ++i) {
-            for (int j = 0; j < 6; ++j) {
-                float radius = 0;
-                Vec3i color = mImage->getPixelValue(*mMatchPositions[i][j]);
-                Vec3f meanColor(0.f , 0.f, 0.f);
-
-                int numPixels = 0;
-                for (int ii  = static_cast<int>(mMatchPositions[i][j]->x() -
-                                                rowDistance/2);
-                     ii <= static_cast<int>(mMatchPositions[i][j]->x() +
-                                            rowDistance/2);
-                     ++ii) {
-                    for (int jj = static_cast<int>(mMatchPositions[i][j]->y() -
-                                                   columnDistance/2);
-                         jj <= static_cast<int>(mMatchPositions[i][j]->y() +
-                                                columnDistance/2);
-                         ++jj) {
-                        if ((ii >= 0) && (ii < mImage->getHeight()) &&
-                            (jj >= 0) && (jj < mImage->getWidth())) {
-                            Vec3i pixelColor = mImage->getPixelValue(ii,jj);
-                            float error = color.squareDistance<int>(pixelColor);
-
-                            if (error < COLOR_ERROR_THRESHOLD) {
-                                drawPoint(ii, jj, *mReferenceColors[i][j]);
-                                meanColor = meanColor + pixelColor;
-                                numPixels++;
-                                Vec2i pixelPosition(ii, jj);
-
-                                if (pixelPosition.squareDistance<float>(
-                                        *mMatchPositions[i][j]) > radius) {
-                                    radius = pixelPosition.squareDistance<float>(
-                                            *mMatchPositions[i][j]);
-                                }
-                            }
-                        }
-                    }
-                }
-
-                /** Computes the radius of the checker.
-                 * The above computed radius is the squared distance to the
-                 * furthest point with a matching color. To be conservative, we
-                 * only consider an area with radius half of the above computed
-                 * value. Since radius is computed as a squared root, the one
-                 * that will be recorded is 1/4 of the above computed value.
-                 */
-                mMatchRadius[i][j] = radius / 4.f;
-                mMatchColors[i][j] = new Vec3f(meanColor / numPixels);
-
-                ALOGV("Reference color at (%d, %d) is (%d, %d, %d)", i, j,
-                     mReferenceColors[i][j]->r(),
-                     mReferenceColors[i][j]->g(),
-                     mReferenceColors[i][j]->b());
-                ALOGV("Average color at (%d, %d) is (%f, %f, %f)", i, j,
-                     mMatchColors[i][j]->r(),
-                     mMatchColors[i][j]->g(),
-                     mMatchColors[i][j]->b());
-                ALOGV("Radius is %f", mMatchRadius[i][j]);
-            }
-        }
-
-        mSuccess = true;
-    }
-}
diff --git a/apps/CtsVerifier/lib/colorchecker/exposurecompensationtest.cpp b/apps/CtsVerifier/lib/colorchecker/exposurecompensationtest.cpp
deleted file mode 100644
index da9fc40..0000000
--- a/apps/CtsVerifier/lib/colorchecker/exposurecompensationtest.cpp
+++ /dev/null
@@ -1,96 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "ExposureCompensationTest"
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <cmath>
-#include <string>
-#include <stdio.h>
-
-#include "vec2.h"
-#include "vec3.h"
-#include "exposurecompensationtest.h"
-
-const float GAMMA_CORRECTION = 2.2f;
-void ExposureCompensationTest::processData() {
-    ALOGV("Start Processing Exposure Compensation Test Data!");
-    clearDebugImage();
-
-    if (mDebugText != NULL) {
-        delete mDebugText;
-        mDebugText = NULL;
-    }
-
-    int numTests = mExposureValues.size();
-    int numPatches = mCheckerColors[0].size();
-    ALOGV("Processing %d tests with %d patches", numTests, numPatches);
-
-    mDebugText = new char[320 * numTests];
-    mDebugText[0] = 0;
-    char* debugText = new char[50];
-
-    Vec3i red(255, 0, 0);
-    Vec3i green(0, 255, 0);
-    Vec3i blue(0, 0, 255);
-
-    float minExposure = -3.0f;
-    float scale = 9.0f;
-    for (int i = 0; i < numTests; ++i) {
-        snprintf(debugText, 50, "Exposure is %f \n", mExposureValues[i]);
-        strcat(mDebugText, debugText);
-        for (int j = 0; j < numPatches; ++j) {
-            int exposureRed = static_cast<int>((
-                log(static_cast<float>(mReferenceColors[j].r()))
-                / log(2.0f) * GAMMA_CORRECTION +
-                mExposureValues[i] - minExposure) * scale);
-            int exposureGreen = static_cast<int>((
-                log(static_cast<float>(mReferenceColors[j].g()))
-                / log(2.0f) * GAMMA_CORRECTION +
-                mExposureValues[i] - minExposure) * scale);
-            int exposureBlue = static_cast<int>((
-                log(static_cast<float>(mReferenceColors[j].b()))
-                / log(2.0f) * GAMMA_CORRECTION +
-                mExposureValues[i] - minExposure) * scale);
-
-            snprintf(debugText, 50, "%d %f %d %f %d %f \n",
-                    exposureRed, mCheckerColors[i][j].r(),
-                    exposureGreen, mCheckerColors[i][j].g(),
-                    exposureBlue, mCheckerColors[i][j].b());
-
-            ALOGV("%s", debugText);
-            strcat(mDebugText, debugText);
-
-            drawPoint(200 - exposureRed, mCheckerColors[i][j].r(), red);
-            drawPoint(200 - exposureGreen, mCheckerColors[i][j].g(), green);
-            drawPoint(200 - exposureBlue, mCheckerColors[i][j].b(), blue);
-        }
-    }
-    mExposureValues.clear();
-    mCheckerColors.clear();
-}
-
-void ExposureCompensationTest::initializeReferenceColors() {
-    mReferenceColors.resize(6);
-
-    mReferenceColors[0].set(243, 243, 242);
-    mReferenceColors[1].set(200, 200, 200);
-    mReferenceColors[2].set(160, 160, 160);
-    mReferenceColors[3].set(122, 122, 121);
-    mReferenceColors[4].set(85, 85, 85);
-    mReferenceColors[5].set(52, 52, 52);
-}
diff --git a/apps/CtsVerifier/lib/colorchecker/imagetesthandler.cpp b/apps/CtsVerifier/lib/colorchecker/imagetesthandler.cpp
deleted file mode 100644
index 1c5bc17..0000000
--- a/apps/CtsVerifier/lib/colorchecker/imagetesthandler.cpp
+++ /dev/null
@@ -1,101 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "ImageTestHandler"
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <cmath>
-
-#include "vec2.h"
-#include "vec3.h"
-#include "imagetesthandler.h"
-
-void ImageTestHandler::initDebugImage() {
-    mDebugOutput = NULL;
-}
-
-// Initializes the  debug image with a given height and width.
-void ImageTestHandler::initDebugImage(int debugHeight,
-                                      int debugWidth) {
-    mDebugOutput = NULL;
-    mDebugOutput = new unsigned char[debugHeight * debugWidth * 4];
-    memset(mDebugOutput, 0, debugHeight * debugWidth * 4);
-
-    mDebugHeight = debugHeight;
-    mDebugWidth = debugWidth;
-}
-
-// Copies an existing image to the debug image.
-void ImageTestHandler::copyDebugImage(int inputHeight, int inputWidth,
-                                      const unsigned char* inputImage) {
-    if ((inputHeight == mDebugHeight) && (inputWidth == mDebugWidth)) {
-        ALOGV("Copying debug images");
-        memcpy(mDebugOutput, inputImage, mDebugHeight * mDebugWidth * 4);
-    }
-}
-
-void ImageTestHandler::clearDebugImage() {
-    if (mDebugOutput != NULL) {
-        delete[] mDebugOutput;
-        mDebugOutput = new unsigned char[mDebugHeight * mDebugWidth * 4];
-        memset(mDebugOutput, 0, mDebugHeight * mDebugWidth * 4);
-    }
-}
-
-
-// Draws a point of a given color.
-void ImageTestHandler::drawPoint(int row, int column, const Vec3i &color) {
-    if ((row >= 0) && (column >= 0) &&
-        (column < mDebugWidth) && (row < mDebugHeight)) {
-        mDebugOutput[(row*mDebugWidth + column) * 4] = color.r();
-        mDebugOutput[(row*mDebugWidth + column) * 4+1] = color.g();
-        mDebugOutput[(row*mDebugWidth + column) * 4+2] = color.b();
-        mDebugOutput[(row*mDebugWidth + column) * 4+3] = 255;
-    }
-}
-
-// Draws a point in Vec2 format of a given color.
-void ImageTestHandler::drawPoint(const Vec2i &point, const Vec3i &color) {
-    drawPoint((int) point.y(), (int) point.x(), color);
-}
-
-// Draws a line of a given color.
-void ImageTestHandler::drawLine(int angle, int radius, const Vec3i &color) {
-    const int r = color.r();
-    const int g = color.g();
-    const int b = color.b();
-    const int a = 255;
-
-    int shiftedMin = -113;
-    int shiftedMax = 83;
-
-    float radiusDouble = static_cast<float>(radius);
-
-    float angleRad = static_cast<float>(angle) * M_PI / 180.0;
-
-    //ALOGV("draw line for (%d, %d)", angle, radius);
-    for (int i = shiftedMin; i <= shiftedMax; ++i) {
-        float j;
-
-        assert(angle != 0);
-        j = (i - radiusDouble / sin(angleRad)) * tan(angleRad);
-        float x = (static_cast<float>(i) + j) / sqrt(2.0);
-        float y = (j - static_cast<float>(i)) / sqrt(2.0);
-
-        drawPoint(x, y, color);
-    }
-}
diff --git a/apps/CtsVerifier/lib/colorchecker/meteringtest.cpp b/apps/CtsVerifier/lib/colorchecker/meteringtest.cpp
deleted file mode 100644
index 47de5d8..0000000
--- a/apps/CtsVerifier/lib/colorchecker/meteringtest.cpp
+++ /dev/null
@@ -1,102 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "MeteringTest"
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <cmath>
-#include <string>
-
-#include "vec2.h"
-#include "vec3.h"
-#include "meteringtest.h"
-
-const float kOverExposure = 230.f;
-const float kEqThreshold = 0.05f;
-// Processes the checker colors stored by comparing the pixel values from the
-// two scenarios in a test.
-void MeteringTest::processData() {
-    ALOGV("Start Processing Metering Test Data!");
-
-    int numTests = mCheckerColors.size() / 2;
-    mNumPatches = 0;
-
-    if (numTests > 0) {
-        mNumPatches = mCheckerColors[0].size();
-    }
-
-    for (int i = 0; i < numTests; ++i) {
-        mComparisonResults.push_back(
-                isEquivalentTo((&mCheckerColors[i * 2]),
-                               (&mCheckerColors[i * 2 + 1])));
-        mComparisonResults.push_back(
-                isDarkerThan((&mCheckerColors[i * 2]),
-                             (&mCheckerColors[i * 2 + 1])));
-    }
-}
-
-void MeteringTest::clearData() {
-    mComparisonResults.clear();
-    mCheckerColors.clear();
-}
-
-// Compares two given arrays of pixel values and decide whether the first one is
-// significantly darker than the second one.
-bool MeteringTest::isDarkerThan(
-        const std::vector<Vec3f>* checkerColors1,
-        const std::vector<Vec3f>* checkerColors2) const {
-    float meanRatio = 0.f;
-    int meanNumCount = 0;
-
-    for (int i = 0; i < mNumPatches; ++i) {
-        float luminance1 = (*checkerColors1)[i].convertToLuminance();
-        float luminance2 = (*checkerColors2)[i].convertToLuminance();
-
-        // Out of the saturation rage, define 5% as a margin for being
-        // significantly brighter.
-        if ((luminance2 < kOverExposure) && (luminance1 != 0.f)) {
-            meanRatio += luminance2 / luminance1;
-            ++meanNumCount;
-        }
-    }
-    meanRatio = meanRatio / meanNumCount;
-
-    return (meanRatio > 1 + kEqThreshold);
-}
-
-// Compares the two givn arrays of pixel values and decide whether they are
-// equivalent within an acceptable range.
-bool MeteringTest::isEquivalentTo(
-        const std::vector<Vec3f>* checkerColors1,
-        const std::vector<Vec3f>* checkerColors2) const {
-    float meanRatio = 0.f;
-    int meanNumCount = 0;
-
-    for (int i = 0; i < mNumPatches; ++i) {
-        float luminance1 = (*checkerColors1)[i].convertToLuminance();
-        float luminance2 = (*checkerColors2)[i].convertToLuminance();
-        ALOGV("Luma_1 and Luma_2 is %f, %f", luminance1, luminance2);
-
-        if ((luminance1 < kOverExposure) && (luminance2 < kOverExposure)) {
-              meanRatio += luminance2 / luminance1;
-              ++meanNumCount;
-        }
-    }
-    meanRatio = meanRatio / meanNumCount;
-
-    return ((meanRatio >= 1 - kEqThreshold) && (meanRatio <= 1 + kEqThreshold));
-}
diff --git a/apps/CtsVerifier/lib/colorchecker/testingimage.cpp b/apps/CtsVerifier/lib/colorchecker/testingimage.cpp
deleted file mode 100644
index 28f025f..0000000
--- a/apps/CtsVerifier/lib/colorchecker/testingimage.cpp
+++ /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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "TestingImage"
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <string.h>
-#include <cmath>
-#include <vector>
-#include <assert.h>
-#include "vec3.h"
-
-#include "testingimage.h"
-
-const float GAMMA_CORRECTION = 2.2f;
-
-// Constructs an instance with the given image byte array.
-TestingImage::TestingImage(const unsigned char* inputImage,
-                           int inputHeight, int inputWidth,
-                           int inputChannel, int inputRowSpan) {
-    mImage = new unsigned char[inputRowSpan * inputHeight];
-
-    ALOGV("mImage format created! with size as %d, %d, %d",
-         inputRowSpan, inputHeight, inputChannel);
-    mWidth = inputWidth;
-    mHeight = inputHeight;
-    mChannels = inputChannel;
-    mRowSpan = mWidth * mChannels;
-
-    for (int i = 0; i < mHeight; ++i) {
-        for (int j = 0; j < mWidth; ++j) {
-            for (int k = 0; k < mChannels; ++k) {
-                mImage[i * mRowSpan + j* mChannels + k] =
-                        inputImage[i * inputRowSpan + j * inputChannel + k];
-            }
-        }
-    }
-    ALOGV("mImage converted!");
-}
-
-// Constructs an instance with the given image and resize it to a new size.
-TestingImage::TestingImage(const unsigned char* inputImage,
-                           int inputHeight, int inputWidth,
-                           int inputChannel, int inputRowSpan,
-                           int newHeight, int newWidth) {
-    mImage = new unsigned char[newHeight * newWidth * inputChannel];
-
-    ALOGV("mImage format created! with size as %d, %d, %d",
-         newHeight, newWidth, inputChannel);
-    mHeight = newHeight;
-    mWidth = newWidth;
-    mChannels = inputChannel;
-    mRowSpan = mWidth * mChannels;
-
-    // Computes how many pixels in the original image corresponds to one pixel
-    // in the new image.
-    int heightScale = inputHeight / newHeight;
-    int widthScale = inputWidth / newWidth;
-
-    // Average the corresponding pixels in the original image to compute the
-    // pixel value of the new image.
-    for (int i = 0; i < mHeight; ++i) {
-        for (int j = 0; j < mWidth; ++j) {
-            for (int k = 0; k < mChannels; ++k) {
-                int pixelValue = 0;
-
-                for (int l = 0; l < heightScale; ++l) {
-                    for (int m = 0; m < widthScale; ++m) {
-                        pixelValue += inputImage[
-                                (i * heightScale + l) * inputRowSpan
-                                + (j * widthScale + m) * inputChannel + k];
-                    }
-                }
-                pixelValue = pixelValue / (heightScale * widthScale);
-                mImage[i * mRowSpan + j * mChannels + k] =
-                        (unsigned char) pixelValue;
-            }
-        }
-    }
-}
-
-TestingImage::~TestingImage() {
-    if (mImage!=NULL) {
-        delete[] mImage;
-    }
-}
-
-int TestingImage::getPixelValue(int row, int column, int channel) const {
-    assert ((row >= 0) && (row < mHeight));
-    assert ((column >= 0) && (column < mWidth));
-    assert ((channel >= 0) && (channel < mChannels));
-    return (int)mImage[row * mRowSpan + column * mChannels + channel];
-}
-
-Vec3i TestingImage::getPixelValue(int row, int column) const {
-    Vec3i current_color(getPixelValue(row, column, 0),
-                        getPixelValue(row, column, 1),
-                        getPixelValue(row, column, 2));
-    return current_color;
-}
-
-Vec3i TestingImage::getPixelValue(const Vec2i &pixelPosition) const {
-    return getPixelValue(pixelPosition.x(), pixelPosition.y());
-}
-
-Vec3i TestingImage::getPixelValue(const Vec2f &pixelPosition) const {
-    return getPixelValue(static_cast<int>(pixelPosition.x()),
-                         static_cast<int>(pixelPosition.y()));
-}
-
-// Returns a vector of the colors in the requested block of color checkers.
-// The vector is formatted by going through the block from left to right and
-// from top to bottom.
-const std::vector<Vec3f>* TestingImage::getColorChecker(
-      int rowStart, int rowEnd, int columnStart, int columnEnd,
-      const std::vector<std::vector< Vec2f > >* centerAddress,
-      const std::vector<std::vector< float > >* radiusAddress) const {
-    std::vector<Vec3f>* checkerColors = new std::vector<Vec3f>;
-
-    // Average the pixel values of the pixels within the given radius to the
-    // given center position.
-    for (int i = rowStart; i < rowEnd; ++i) {
-        for (int j = columnStart; j < columnEnd; ++j) {
-            float radius = sqrt((*radiusAddress)[i][j]);
-            Vec2f center((*centerAddress)[i][j].x(),
-                               (*centerAddress)[i][j].y());
-            Vec3f meanColor(0.f, 0.f, 0.f);
-            int numPixels = 0;
-
-            for (int ii = static_cast<int>(center.x() - radius);
-                 ii < static_cast<int>(center.x() + radius); ++ii) {
-                for (int jj = static_cast<int>(center.y() - radius);
-                     jj < static_cast<int>(center.y() + radius); ++jj) {
-
-                    Vec2i pixelPosition(ii,jj);
-                    if (pixelPosition.squareDistance<float>(center) <
-                        (*radiusAddress)[i][j]) {
-                        meanColor = meanColor + getPixelValue(pixelPosition);
-                        ++numPixels;
-                    }
-                }
-            }
-            meanColor = meanColor / numPixels;
-            checkerColors->push_back(meanColor);
-        }
-    }
-
-    return checkerColors;
-}
-
-bool TestingImage::rgbToGrayScale(unsigned char* grayLayer) const {
-    if (mChannels == 4) {
-        for (int i = 0; i < mWidth; i++) {
-            for (int j = 0; j < mHeight; j++) {
-                float redLinear = pow(getPixelValue(j, i, 0),
-                                       GAMMA_CORRECTION);
-                float greenLinear = pow(getPixelValue(j,i,1),
-                                         GAMMA_CORRECTION);
-                float blueLinear = pow(getPixelValue(j,i,2),
-                                        GAMMA_CORRECTION);
-
-                // Computes the luminance value
-                grayLayer[j * mWidth + i] =
-                        (unsigned char)((int)pow((0.299f * redLinear
-                                                  + 0.587f * greenLinear
-                                                  + 0.114f * blueLinear),
-                                                  1/GAMMA_CORRECTION));
-            }
-        }
-
-        return true;
-    } else {
-
-        return false;
-    }
-}
diff --git a/apps/CtsVerifier/lib/colorchecker/vec2.cpp b/apps/CtsVerifier/lib/colorchecker/vec2.cpp
deleted file mode 100644
index 29736bb..0000000
--- a/apps/CtsVerifier/lib/colorchecker/vec2.cpp
+++ /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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "Vec2"
-#include <utils/Log.h>
-#include <utils/Timers.h>
-
-#include "vec2.h"
diff --git a/apps/CtsVerifier/lib/colorchecker/vec3.cpp b/apps/CtsVerifier/lib/colorchecker/vec3.cpp
deleted file mode 100644
index ac16620..0000000
--- a/apps/CtsVerifier/lib/colorchecker/vec3.cpp
+++ /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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "Vec3"
-#include <utils/Log.h>
-#include <utils/Timers.h>
-
-#include "vec3.h"
diff --git a/apps/CtsVerifier/lib/colorchecker/whitebalancetest.cpp b/apps/CtsVerifier/lib/colorchecker/whitebalancetest.cpp
deleted file mode 100644
index 6413a2b..0000000
--- a/apps/CtsVerifier/lib/colorchecker/whitebalancetest.cpp
+++ /dev/null
@@ -1,122 +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.
- */
-#define LOG_NDEBUG 0
-
-#define LOG_TAG "WhiteBalanceTest"
-#include <utils/Log.h>
-#include <utils/Timers.h>
-#include <cmath>
-#include <string>
-
-#include "vec2.h"
-#include "vec3.h"
-#include "whitebalancetest.h"
-
-// White point in XYZ color space under 5200k illumination.
-const Vec3f kDaylightWhitePoint(0.9781f, 1.f, 0.9021f);
-
-// Process the data of checker colors collected under different white balance.
-// Assuming the Daylight CCT is set to 5200k, compute the CCT of other white
-// balance modes.
-void WhiteBalanceTest::processData() {
-    ALOGV("Start Processing White Balance Test Data!");
-
-    int numPatches = mCheckerColors.size();
-    ALOGV("Processing %d tests with %d patches", 2, numPatches);
-
-    std::vector<Vec3f> xyzColors(numPatches);
-    for (int j = 0; j < numPatches; ++j) {
-        Vec3f xyzCheckerColor = initializeFromRGB(mCheckerColors[j]);
-        xyzColors[j] = xyzCheckerColor;
-        ALOGV("XYZ coordinate is %f, %f, %f", xyzCheckerColor.r(),
-              xyzCheckerColor.g(), xyzCheckerColor.b());
-    }
-
-    Vec3f meanScale(0.f, 0.f, 0.f);
-
-    if (mMode == "daylight") {
-        mXyzColorsDaylight = xyzColors;
-        // For testing the auto white balance mode. Compute a CCT that would
-        // map the gray checkers to a white point.
-        for (int j = 1; j < numPatches; ++j) {
-            meanScale = meanScale +
-                    (mXyzColorsDaylight[j] / kDaylightWhitePoint);
-        }
-    } else {
-        for (int j = 1; j < numPatches; ++j) {
-            meanScale = meanScale + (mXyzColorsDaylight[j] / xyzColors[j]);
-        }
-    }
-
-    meanScale = meanScale / (numPatches - 1);
-    ALOGV("Scale: %f, %f, %f", meanScale.r(), meanScale.g(), meanScale.b());
-
-    Vec3f whitePoint;
-    whitePoint = meanScale * kDaylightWhitePoint;
-
-    ALOGV("White point is %f, %f, %f", whitePoint.r(),
-         whitePoint.g(), whitePoint.b());
-
-    mCorrelatedColorTemp = findCorrelatedColorTemp(whitePoint);
-    ALOGV("CCT is %d", mCorrelatedColorTemp);
-}
-
-// Given a white point, find the correlated color temperature.
-// Formula taken from the paper "Calculating Correlated Color Temperatures
-// Across the Entire Gamut of Daylight and Skylight Chromaticities" by Hernandez
-// Andres et al. in 1999. The numbers are fitting parameters.
-int WhiteBalanceTest::findCorrelatedColorTemp(const Vec3f &whitePoint) {
-    Vec2f chromaOfWhitePoint(
-        whitePoint.r() / (whitePoint.r() + whitePoint.g() + whitePoint.b()),
-        whitePoint.g() / (whitePoint.r() + whitePoint.g() + whitePoint.b()));
-
-    float n = (chromaOfWhitePoint.x() - 0.3366f)
-                / (chromaOfWhitePoint.y() - 0.1735f);
-    float y = -949.86315f + 6253.80338f * exp(-n / 0.92159f)
-               + 28.70599f * exp(-n / 0.20039f) + 0.00004f * exp(-n / 0.07125f);
-
-    return static_cast<int>(y);
-}
-
-// Converts a RGB pixel value to XYZ color space.
-Vec3f WhiteBalanceTest::initializeFromRGB(const Vec3f &rgb) {
-    float linearRed = convertToLinear(rgb.r());
-    float linearGreen = convertToLinear(rgb.g());
-    float linearBlue = convertToLinear(rgb.b());
-
-    float x = 0.4124f * linearRed + 0.3576f * linearGreen +
-            0.1805f * linearBlue;
-    float y = 0.2126f * linearRed + 0.7152f * linearGreen +
-            0.0722f * linearBlue;
-    float z = 0.0193f * linearRed + 0.1192f * linearGreen +
-            0.9505f * linearBlue;
-
-    return Vec3f(x, y, z);
-}
-
-float WhiteBalanceTest::convertToLinear(float color) {
-    float norm = color/ 255.0f;
-    float linearColor;
-
-    // Convert from sRGB space to linear RGB value
-    if (norm > 0.04045f) {
-        linearColor = pow(((norm + 0.055f) / 1.055f), 2.4f);
-    } else {
-        linearColor = norm / 12.92f;
-    }
-
-    return linearColor;
-}
diff --git a/apps/CtsVerifier/libs/opencv-android.jar b/apps/CtsVerifier/libs/opencv-android.jar
new file mode 100644
index 0000000..1c13eee
--- /dev/null
+++ b/apps/CtsVerifier/libs/opencv-android.jar
Binary files differ
diff --git a/apps/CtsVerifier/libs/opencv-android_LICENSE b/apps/CtsVerifier/libs/opencv-android_LICENSE
new file mode 100644
index 0000000..5e32d88
--- /dev/null
+++ b/apps/CtsVerifier/libs/opencv-android_LICENSE
@@ -0,0 +1,33 @@
+By downloading, copying, installing or using the software you agree to this license.
+If you do not agree to this license, do not download, install,
+copy or use the software.
+
+
+                          License Agreement
+               For Open Source Computer Vision Library
+                       (3-clause BSD License)
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+  * Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+  * Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+
+  * Neither the names of the copyright holders nor the names of the contributors
+    may be used to endorse or promote products derived from this software
+    without specific prior written permission.
+
+This software is provided by the copyright holders and contributors "as is" and
+any express or implied warranties, including, but not limited to, the implied
+warranties of merchantability and fitness for a particular purpose are disclaimed.
+In no event shall copyright holders or contributors be liable for any direct,
+indirect, incidental, special, exemplary, or consequential damages
+(including, but not limited to, procurement of substitute goods or services;
+loss of use, data, or profits; or business interruption) however caused
+and on any theory of liability, whether in contract, strict liability,
+or tort (including negligence or otherwise) arising in any way out of
+the use of this software, even if advised of the possibility of such damage.
diff --git a/apps/CtsVerifier/proguard.flags b/apps/CtsVerifier/proguard.flags
index ca4680f..5a2beb5 100644
--- a/apps/CtsVerifier/proguard.flags
+++ b/apps/CtsVerifier/proguard.flags
@@ -16,6 +16,14 @@
 
 -keepclasseswithmembers class * extends com.android.cts.verifier.location.LocationModeTestActivity
 
+# keep mockito methods
+-keep class org.mockito.** { *; }
+-keep interface org.mockito.** { *; }
+-keep class com.google.dexmaker.** { *; }
+-keep interface com.google.dexmaker.** { *; }
+
 -dontwarn android.hardware.Sensor
 -dontwarn android.test.AndroidTestRunner
 -dontwarn java.util.concurrent.ConcurrentLinkedDeque
+-dontwarn android.cts.util.**
+-dontwarn junit.**
diff --git a/apps/CtsVerifier/res/drawable/app_link_img.png b/apps/CtsVerifier/res/drawable/app_link_img.png
new file mode 100644
index 0000000..851fc6f
--- /dev/null
+++ b/apps/CtsVerifier/res/drawable/app_link_img.png
Binary files differ
diff --git a/apps/CtsVerifier/res/drawable/prompt_x.png b/apps/CtsVerifier/res/drawable/prompt_x.png
new file mode 100644
index 0000000..64302dc
--- /dev/null
+++ b/apps/CtsVerifier/res/drawable/prompt_x.png
Binary files differ
diff --git a/apps/CtsVerifier/res/drawable/prompt_y.png b/apps/CtsVerifier/res/drawable/prompt_y.png
new file mode 100644
index 0000000..01926b5
--- /dev/null
+++ b/apps/CtsVerifier/res/drawable/prompt_y.png
Binary files differ
diff --git a/apps/CtsVerifier/res/drawable/prompt_z.png b/apps/CtsVerifier/res/drawable/prompt_z.png
new file mode 100644
index 0000000..f4d86d6
--- /dev/null
+++ b/apps/CtsVerifier/res/drawable/prompt_z.png
Binary files differ
diff --git a/apps/CtsVerifier/res/drawable/stat_sys_managed_profile_status.xml b/apps/CtsVerifier/res/drawable/stat_sys_managed_profile_status.xml
new file mode 100644
index 0000000..b04059e
--- /dev/null
+++ b/apps/CtsVerifier/res/drawable/stat_sys_managed_profile_status.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="23.0dp"
+        android:height="18.0dp"
+        android:viewportWidth="21.0"
+        android:viewportHeight="17.0">
+    <group android:translateX="2.0">
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M9.9,11.6H7v-1.1H2.1v2.8c0,0.8,0.6,1.4,1.4,1.4h9.9c0.8,0,1.4,-0.6,1.4,-1.4v-2.8H9.9V11.6z"/>
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M14.1,4.2h-2.5V3.2l-1.1,-1.1H6.3L5.3,3.2v1H2.8C2,4.2,1.4,4.9,1.4,5.6v2.8c0,0.8,0.6,1.4,1.4,1.4H7V8.8h2.8v1.1h4.2     c0.8,0,1.4,-0.6,1.4,-1.4V5.6C15.5,4.9,14.8,4.2,14.1,4.2z M10.6,4.2H6.3V3.2h4.2V4.2z"/>
+    </group>
+</vector>
diff --git a/apps/CtsVerifier/res/layout/audio_dev_notify.xml b/apps/CtsVerifier/res/layout/audio_dev_notify.xml
new file mode 100644
index 0000000..ceedf1c
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_dev_notify.xml
@@ -0,0 +1,87 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+        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:padding="20dp"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scrollbars="vertical"
+            android:gravity="bottom"
+            android:id="@+id/audio_general_headset_port_exists"
+            android:text="@string/audio_general_headset_port_exists" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/audio_general_headset_no"
+                android:text="@string/audio_general_headset_no" />
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/audio_general_headset_yes"
+                android:text="@string/audio_general_headset_yes" />
+        </LinearLayout>
+
+    <TextView
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:scrollbars="vertical"
+      android:gravity="bottom"
+      android:id="@+id/info_text"/>
+
+  <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="vertical">
+      <Button
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:id="@+id/audio_dev_notification_connect_clearmsgs_btn"
+          android:text="@string/audio_dev_notification_clearmsgs"/>
+
+      <TextView
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:id="@+id/audio_dev_notification_connect_msg"/>
+
+      <TextView
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:id="@+id/audio_dev_notification_disconnect_msg"/>
+
+    </LinearLayout>
+
+  <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
+</ScrollView>
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml
new file mode 100644
index 0000000..c1b62af
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_frequency_line_activity.xml
@@ -0,0 +1,117 @@
+<?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_general_headset_port_exists"
+                android:text="@string/audio_general_headset_port_exists" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+            >
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/audio_general_headset_no"
+                    android:text="@string/audio_general_headset_no" />
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/audio_general_headset_yes"
+                    android:text="@string/audio_general_headset_yes" />
+
+            </LinearLayout>
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:scrollbars="vertical"
+                android:gravity="bottom"
+                android:id="@+id/info_text"
+                android:text="@string/audio_frequency_line_instructions" />
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+            >
+                <Button
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/audio_frequency_line_plug_ready_btn"
+                    android:text="@string/audio_frequency_line_plug_ready_btn" />
+
+                <LinearLayout
+                    android:orientation="vertical"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                >
+
+                    <LinearLayout
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:orientation="horizontal"
+                        android:id="@+id/audio_frequency_line_layout"
+                    >
+                        <Button
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:text="@string/audio_frequency_line_test_btn"
+                            android:id="@+id/audio_frequency_line_test_btn" />
+
+                        <ProgressBar
+                            android:layout_width="wrap_content"
+                            android:layout_height="wrap_content"
+                            android:id="@+id/audio_frequency_line_progress_bar" />
+                    </LinearLayout>
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/audio_frequency_line_results_text"
+                        android:id="@+id/audio_frequency_line_results_text" />
+
+                </LinearLayout>
+            </LinearLayout>
+
+            <include layout="@layout/pass_fail_buttons" />
+        </LinearLayout>
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
new file mode 100644
index 0000000..db52998
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_frequency_mic_activity.xml
@@ -0,0 +1,168 @@
+<?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_general_headset_port_exists"
+                android:text="@string/audio_general_headset_port_exists" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+            >
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/audio_general_headset_no"
+                    android:text="@string/audio_general_headset_no" />
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/audio_general_headset_yes"
+                    android:text="@string/audio_general_headset_yes" />
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+            >
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:id="@+id/info_text"
+                    android:text="@string/audio_frequency_mic_instructions" />
+
+                <ProgressBar
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="1"
+                    android:id="@+id/audio_frequency_mic_progress_bar" />
+            </LinearLayout>
+
+            <Button
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/audio_frequency_mic_speakers_ready_btn"
+                android:text="@string/audio_frequency_mic_speakers_ready_btn" />
+
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:scrollbars="vertical"
+                android:gravity="bottom"
+                android:id="@+id/audio_frequency_mic_speakers_ready_status"
+                android:text="@string/audio_frequency_mic_speakers_ready_status" />
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:id="@+id/audio_frequency_mic_layout_test1"
+            >
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_mic_instructions2"
+                    android:id="@+id/audio_frequency_mic_instructions2" />
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_mic_test1_btn"
+                    android:id="@+id/audio_frequency_mic_test1_btn" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_mic_results_text"
+                    android:id="@+id/audio_frequency_mic_results1_text" />
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:id="@+id/audio_frequency_mic_layout_test2a"
+            >
+
+                <Button
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/audio_frequency_mic_mic_ready_btn"
+                    android:text="@string/audio_frequency_mic_mic_ready_btn" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_mic_usb_status"
+                    android:id="@+id/audio_frequency_mic_usb_status" />
+            </LinearLayout>
+
+            <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:id="@+id/audio_frequency_mic_layout_test2b"
+            >
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_mic_test2_btn"
+                    android:id="@+id/audio_frequency_mic_test2_btn" />
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_mic_results_text"
+                    android:id="@+id/audio_frequency_mic_results_text" />
+
+            </LinearLayout>
+
+            <include layout="@layout/pass_fail_buttons" />
+        </LinearLayout>
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
new file mode 100644
index 0000000..5dd55b1
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_frequency_speaker_activity.xml
@@ -0,0 +1,92 @@
+<?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/info_text"
+            android:text="@string/audio_frequency_speaker_instructions"/>
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="vertical">
+            <Button
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:id="@+id/audio_frequency_speaker_mic_ready_btn"
+                android:text="@string/audio_frequency_speaker_mic_ready_btn"/>
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/audio_frequency_speaker_usb_status"
+                android:id="@+id/audio_frequency_speaker_usb_status"/>
+
+            <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent">
+
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    android:id="@+id/audio_frequency_speaker_layout">
+                    <Button
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/audio_frequency_speaker_test_btn"
+                        android:id="@+id/audio_frequency_speaker_test_btn"/>
+
+                    <ProgressBar
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:id="@+id/audio_frequency_speaker_progress_bar"/>
+                </LinearLayout>
+
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/audio_frequency_speaker_results_text"
+                    android:id="@+id/audio_frequency_speaker_results_text"/>
+
+            </LinearLayout>
+        </LinearLayout>
+
+        <include layout="@layout/pass_fail_buttons"/>
+        </LinearLayout>
+      </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml b/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml
new file mode 100644
index 0000000..60a12ef
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_input_routingnotifications_test.xml
@@ -0,0 +1,99 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+        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:padding = "20dp"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scrollbars="vertical"
+            android:gravity="bottom"
+            android:id="@+id/audio_general_headset_port_exists"
+            android:text="@string/audio_general_headset_port_exists" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/audio_general_headset_no"
+                android:text="@string/audio_general_headset_no" />
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/audio_general_headset_yes"
+                android:text="@string/audio_general_headset_yes" />
+        </LinearLayout>
+
+    <TextView
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:scrollbars="vertical"
+      android:gravity="bottom"
+      android:id="@+id/info_text"
+      android:text="@string/audio_input_routingnotification_instructions" />
+
+  <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="vertical"
+      android:id="@+id/audioRecordRoutingLayout">
+      <TextView
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+              android:text="@string/audio_routingnotification_recHeader"/>
+
+      <TextView
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:id="@+id/audio_routingnotification_audioRecord_change"/>
+
+      <LinearLayout
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:orientation="horizontal">
+          <Button
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:id="@+id/audio_routingnotification_recordBtn"
+              android:text="@string/audio_routingnotification_recBtn"/>
+
+          <Button
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:id="@+id/audio_routingnotification_recordStopBtn"
+              android:text="@string/audio_routingnotification_recStopBtn"/>
+      </LinearLayout>
+    </LinearLayout>
+
+  <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
+</ScrollView>
diff --git a/apps/CtsVerifier/res/layout/audio_loopback_activity.xml b/apps/CtsVerifier/res/layout/audio_loopback_activity.xml
new file mode 100644
index 0000000..815f2bc
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_loopback_activity.xml
@@ -0,0 +1,132 @@
+<?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_general_headset_port_exists"
+                android:text="@string/audio_general_headset_port_exists" />
+
+            <LinearLayout
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="horizontal"
+            >
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/audio_general_headset_no"
+                    android:text="@string/audio_general_headset_no" />
+
+                <Button
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/audio_general_headset_yes"
+                    android:text="@string/audio_general_headset_yes" />
+
+            </LinearLayout>
+
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:id="@+id/audio_loopback_headset_port"
+            >
+
+                <TextView
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:scrollbars="vertical"
+                    android:gravity="bottom"
+                    android:id="@+id/info_text"
+                    android:text="@string/audio_loopback_instructions" />
+
+                <Button
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/audio_loopback_plug_ready_btn"
+                    android:text="@string/audio_loopback_plug_ready_btn" />
+
+                <LinearLayout
+                    android:orientation="vertical"
+                    android:layout_width="match_parent"
+                    android:layout_height="match_parent"
+                    android:id="@+id/audio_loopback_layout"
+                >
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/audio_loopback_instructions2"
+                        android:id="@+id/audio_loopback_instructions2" />
+
+                    <SeekBar
+                        android:layout_width="match_parent"
+                        android:layout_height="wrap_content"
+                        android:id="@+id/audio_loopback_level_seekbar" />
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/audio_loopback_level_text"
+                        android:id="@+id/audio_loopback_level_text" />
+
+                    <Button
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/audio_loopback_test_btn"
+                        android:id="@+id/audio_loopback_test_btn" />
+
+                    <ProgressBar
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:id="@+id/audio_loopback_progress_bar" />
+
+                    <TextView
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content"
+                        android:text="@string/audio_loopback_results_text"
+                        android:id="@+id/audio_loopback_results_text" />
+                </LinearLayout>
+
+            </LinearLayout>
+            <include layout="@layout/pass_fail_buttons" />
+        </LinearLayout>
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml b/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml
new file mode 100644
index 0000000..d039691
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/audio_output_routingnotifications_test.xml
@@ -0,0 +1,100 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+        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:padding="20dp"
+        android:orientation="vertical">
+
+        <TextView
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:scrollbars="vertical"
+            android:gravity="bottom"
+            android:id="@+id/audio_general_headset_port_exists"
+            android:text="@string/audio_general_headset_port_exists" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:orientation="horizontal">
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/audio_general_headset_no"
+                android:text="@string/audio_general_headset_no" />
+
+            <Button
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:id="@+id/audio_general_headset_yes"
+                android:text="@string/audio_general_headset_yes" />
+
+        </LinearLayout>
+
+    <TextView
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:scrollbars="vertical"
+      android:gravity="bottom"
+      android:id="@+id/info_text"
+      android:text="@string/audio_output_routingnotification_instructions" />
+
+  <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:orientation="vertical"
+      android:id="@+id/audioTrackRoutingLayout">
+      <TextView
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+              android:text="@string/audio_routingnotification_playHeader"/>
+
+      <TextView
+          android:layout_width="match_parent"
+          android:layout_height="wrap_content"
+          android:id="@+id/audio_routingnotification_audioTrack_change"/>
+
+      <LinearLayout
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:orientation="horizontal">
+          <Button
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:id="@+id/audio_routingnotification_playBtn"
+              android:text="@string/audio_routingnotification_playBtn"/>
+
+          <Button
+              android:layout_width="match_parent"
+              android:layout_height="wrap_content"
+              android:id="@+id/audio_routingnotification_playStopBtn"
+              android:text="@string/audio_routingnotification_playStopBtn"/>
+      </LinearLayout>
+    </LinearLayout>
+
+  <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
+</ScrollView>
diff --git a/apps/CtsVerifier/res/layout/byod_nfc_test_activity.xml b/apps/CtsVerifier/res/layout/byod_nfc_test_activity.xml
index a31632e..52251b4 100644
--- a/apps/CtsVerifier/res/layout/byod_nfc_test_activity.xml
+++ b/apps/CtsVerifier/res/layout/byod_nfc_test_activity.xml
@@ -17,9 +17,15 @@
     xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
     android:layout_height="match_parent" >
 
+    <Button android:text="@string/provisioning_byod_send_manual_beam"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:id="@+id/manual_beam_button" />
+
     <Button android:text="@string/provisioning_byod_send_share_intent"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:id="@+id/intent_share_button" />
+        android:id="@+id/intent_share_button"
+        android:layout_below="@+id/manual_beam_button" />
 
 </RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/ca_main.xml b/apps/CtsVerifier/res/layout/ca_main.xml
deleted file mode 100644
index 274430d..0000000
--- a/apps/CtsVerifier/res/layout/ca_main.xml
+++ /dev/null
@@ -1,81 +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.wearable.view.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:layout_box="all"
-      android:orientation="vertical" android:layout_width="fill_parent"
-      android:layout_height="fill_parent">
-
-
-      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="horizontal" android:layout_width="fill_parent"
-        android:layout_height="wrap_content">
-        <!--Button android:id="@+id/focusmodesbutton" android:layout_width="0px"
-          android:layout_height="wrap_content" android:text="@string/ca_focus_modes_label"
-          android:layout_weight="1" /-->
-        <Button android:id="@+id/findcheckerboardbutton" android:layout_width="0px"
-          android:layout_height="wrap_content" android:text="@string/ca_find_checkerboard_label"
-          android:layout_weight="1" />
-
-        <Button android:id="@+id/meteringbutton" android:layout_width="0px"
-          android:layout_height="wrap_content" android:text="@string/ca_metering_label"
-          android:layout_weight="1" />
-
-        <Button android:id="@+id/exposurecompensationbutton" android:layout_width="0px"
-          android:layout_height="wrap_content" android:text="@string/ca_exposure_test_label"
-          android:layout_weight="1"/>
-
-        <Button android:id="@+id/whitebalancebutton" android:layout_width="0px"
-          android:layout_height="wrap_content" android:text="@string/ca_wb_test_label"
-          android:layout_weight="1" />
-
-        <Button android:id="@+id/lockbutton" android:layout_width="0px"
-          android:layout_height="wrap_content" android:text="@string/ca_lock_test_label"
-          android:layout_weight="1" />
-      </LinearLayout>
-
-      <LinearLayout android:orientation="horizontal"
-        android:layout_width="fill_parent" android:layout_height="0px"
-        android:layout_weight="1">
-
-        <SurfaceView android:id="@+id/cameraview" android:layout_height="fill_parent"
-          android:layout_width="wrap_content"
-          android:layout_weight="0" />
-
-        <LinearLayout android:orientation="vertical"
-          android:layout_width="fill_parent" android:layout_height="match_parent"
-          android:layout_weight="1">
-
-           <ListView android:id="@+id/ca_tests"
-                android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
-                android:layout_weight="1"
-                android:layout_marginLeft="10px"/>
-
-          <ImageView android:id="@+id/resultview" android:layout_height="wrap_content"
-            android:layout_width="fill_parent"
-            android:layout_weight="1" />
-        </LinearLayout>
-
-      </LinearLayout>
-
-      <include layout="@layout/pass_fail_buttons" />
-
-    </LinearLayout>
-</android.support.wearable.view.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout/cam_preview_overlay.xml b/apps/CtsVerifier/res/layout/cam_preview_overlay.xml
new file mode 100644
index 0000000..41bbeb1
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/cam_preview_overlay.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:keepScreenOn="true">
+    <view
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        class="com.android.cts.verifier.sensors.RVCVCameraPreview"
+        android:id="@+id/cam_preview"
+        android:layout_centerVertical="true"
+        android:layout_centerHorizontal="true" />
+
+    <!--
+    <ImageView
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_centerVertical="true"
+        android:id="@+id/cam_overlay"
+        android:src="@drawable/icon"
+        android:scaleType="fitStart"
+        />
+    -->
+    <view
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        class="com.android.cts.verifier.sensors.MotionIndicatorView"
+        android:id="@+id/cam_indicator"
+        android:layout_centerVertical="true"
+        android:layout_centerHorizontal="true" />
+
+    <ImageView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_centerInParent="true"
+        android:id="@+id/cam_overlay"
+        android:scaleType="fitStart"
+        />
+</RelativeLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/camera_flashlight.xml b/apps/CtsVerifier/res/layout/camera_flashlight.xml
new file mode 100644
index 0000000..2d4378c
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/camera_flashlight.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:layout_gravity="bottom"
+    android:orientation="vertical">
+
+        <TextView
+            android:id="@+id/flash_instruction_text"
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="2"
+            android:gravity="center"
+            android:text="@string/camera_flashlight_start_text" />
+
+        <Button
+            android:id="@+id/flash_instruction_button"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="100dp"
+            android:layout_marginRight="100dp"
+            android:text="@string/camera_flashlight_start_button" />
+
+        <LinearLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:layout_marginLeft="50dp"
+            android:layout_marginRight="50dp"
+            android:layout_marginBottom="50dp"
+            android:orientation="horizontal">
+
+            <Button
+                android:id="@+id/flash_on_button"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:text="@string/camera_flashlight_on_button" />
+
+            <Button
+                android:id="@+id/flash_off_button"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:text="@string/camera_flashlight_off_button" />
+
+        </LinearLayout>
+
+    <include layout="@layout/pass_fail_buttons"/>
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/byod_custom_view.xml b/apps/CtsVerifier/res/layout/dialog_custom_view.xml
similarity index 100%
rename from apps/CtsVerifier/res/layout/byod_custom_view.xml
rename to apps/CtsVerifier/res/layout/dialog_custom_view.xml
diff --git a/apps/CtsVerifier/res/layout/hifi_ultrasound.xml b/apps/CtsVerifier/res/layout/hifi_ultrasound.xml
new file mode 100644
index 0000000..7d2de5a
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/hifi_ultrasound.xml
@@ -0,0 +1,51 @@
+<?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">
+
+  <TextView
+      android:layout_width="match_parent"
+      android:layout_height="0dp"
+      android:layout_weight="7"
+      android:scrollbars="vertical"
+      android:gravity="bottom"
+      android:id="@+id/info_text"/>
+
+  <LinearLayout
+      android:layout_width="match_parent"
+      android:layout_height="0dp"
+      android:layout_weight="3"
+      android:orientation="horizontal">
+    <Button
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="5"
+        android:text="@string/hifi_ultrasound_test_record"
+        android:id="@+id/recorder_button"/>
+    <Button
+        android:layout_width="0dp"
+        android:layout_height="match_parent"
+        android:layout_weight="5"
+        android:text="@string/hifi_ultrasound_test_play"
+        android:id="@+id/player_button"/>
+  </LinearLayout>
+
+  <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/hifi_ultrasound_popup.xml b/apps/CtsVerifier/res/layout/hifi_ultrasound_popup.xml
new file mode 100644
index 0000000..afff2c9
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/hifi_ultrasound_popup.xml
@@ -0,0 +1,33 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:background="@android:color/white"
+              android:gravity="center"
+              android:orientation="vertical" >
+
+    <com.androidplot.xy.XYPlot
+        android:id="@+id/responseChart"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="9"
+        androidPlot.domainLabel="kHz"
+        androidPlot.rangeLabel="dB"
+        androidPlot.domainLabelWidget.labelPaint.textSize="16dp"
+        androidPlot.rangeLabelWidget.labelPaint.textSize="16dp"
+        androidPlot.graphWidget.rangeLabelPaint.textSize="16dp"
+        androidPlot.graphWidget.rangeOriginLabelPaint.textSize="16dp"
+        androidPlot.graphWidget.domainLabelPaint.textSize="16dp"
+        androidPlot.graphWidget.domainOriginLabelPaint.textSize="16dp"
+        androidPlot.legendWidget.textPaint.textSize="16dp"
+        androidPlot.legendWidget.iconSizeMetrics.heightMetric.value="16dp"
+        androidPlot.legendWidget.iconSizeMetrics.widthMetric.value="16dp"
+        androidPlot.legendWidget.heightMetric.value="16dp"
+        androidPlot.graphWidget.gridLinePaint.color="#000000" />
+
+    <Button
+        android:id="@+id/dismiss"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:text="@string/hifi_ultrasound_test_dismiss" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/hifi_ultrasound_popup_instru.xml b/apps/CtsVerifier/res/layout/hifi_ultrasound_popup_instru.xml
new file mode 100644
index 0000000..42af6e9
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/hifi_ultrasound_popup_instru.xml
@@ -0,0 +1,21 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:gravity="center"
+              android:background="@android:color/black"
+              android:padding="5dp"
+              android:orientation="vertical" >
+
+  <TextView
+      android:id="@+id/instru"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:layout_weight="5" />
+
+  <Button
+      android:id="@+id/ok"
+      android:layout_width="match_parent"
+      android:layout_height="match_parent"
+      android:text="@string/hifi_ultrasound_test_ok"
+      android:layout_weight="1" />
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/js_charging.xml b/apps/CtsVerifier/res/layout/js_charging.xml
index 8d9ed1d..2888714 100644
--- a/apps/CtsVerifier/res/layout/js_charging.xml
+++ b/apps/CtsVerifier/res/layout/js_charging.xml
@@ -29,30 +29,29 @@
                 android:text="@string/js_start_test_text"
                 android:onClick="startTest"
                 android:enabled="false"/>
-
-            <LinearLayout
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/js_padding"
-                android:layout_marginBottom="@dimen/js_padding">
-                <ImageView
-                    android:id="@+id/charging_off_test_image"
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:src="@drawable/fs_indeterminate"
-                    android:layout_marginRight="@dimen/js_padding"/>
-                <TextView
-                    android:layout_width="wrap_content"
-                    android:layout_height="wrap_content"
-                    android:text="@string/js_charging_off_test"
-                    android:textSize="16dp"/>
-            </LinearLayout>
             <TextView
+                android:id="@+id/js_waiting_for_charging_text_view"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_margin="@dimen/js_padding"
-                android:text="@string/js_charging_description_2"
-                android:textStyle="bold"/>
+                android:text="@string/js_charging_description_3"
+                android:textStyle="bold"
+                android:visibility="gone"/>
+            <com.android.cts.verifier.TimerProgressBar
+                android:id="@+id/js_waiting_for_charging_progress_bar"
+                style="?android:attr/progressBarStyleHorizontal"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:layout_margin="@dimen/js_padding"
+                android:visibility="gone"/>
+            <TextView
+                android:id="@+id/js_problem_with_charger_text_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_margin="@dimen/js_padding"
+                android:text="@string/js_charging_description_4"
+                android:textStyle="bold"
+                android:visibility="gone"/>
             <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
@@ -70,6 +69,29 @@
                     android:text="@string/js_charging_on_test"
                     android:textSize="16dp"/>
             </LinearLayout>
+            <TextView
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_margin="@dimen/js_padding"
+                android:text="@string/js_charging_description_2"
+                android:textStyle="bold"/>
+            <LinearLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/js_padding"
+                android:layout_marginBottom="@dimen/js_padding">
+                <ImageView
+                    android:id="@+id/charging_off_test_image"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:src="@drawable/fs_indeterminate"
+                    android:layout_marginRight="@dimen/js_padding"/>
+                <TextView
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:text="@string/js_charging_off_test"
+                    android:textSize="16dp"/>
+            </LinearLayout>
             <include layout="@layout/pass_fail_buttons" />
         </LinearLayout>
     </ScrollView>
diff --git a/apps/CtsVerifier/res/layout/js_idle.xml b/apps/CtsVerifier/res/layout/js_idle.xml
index 4277173..5289b98 100644
--- a/apps/CtsVerifier/res/layout/js_idle.xml
+++ b/apps/CtsVerifier/res/layout/js_idle.xml
@@ -15,13 +15,6 @@
                 android:layout_height="wrap_content"
                 android:text="@string/js_test_description"
                 android:layout_margin="@dimen/js_padding"/>
-            <TextView
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="@string/js_idle_description_1"
-                android:layout_margin="@dimen/js_padding"
-                android:textStyle="bold"/>
-
             <Button
                 android:id="@+id/js_idle_start_test_button"
                 android:layout_width="wrap_content"
@@ -30,6 +23,14 @@
                 android:text="@string/js_start_test_text"
                 android:onClick="startTest"
                 android:enabled="false"/>
+            <TextView
+                android:id="@+id/js_idle_continue_instruction_view"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:text="@string/js_idle_continue_instruction"
+                android:layout_margin="@dimen/js_padding"
+                android:textStyle="bold"
+                android:visibility="gone"/>
 
             <LinearLayout
                 android:layout_width="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/keychain_main.xml b/apps/CtsVerifier/res/layout/keychain_main.xml
new file mode 100644
index 0000000..3f695cd
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/keychain_main.xml
@@ -0,0 +1,95 @@
+<?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.
+-->
+<android.support.wearable.view.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 xmlns:app="http://schemas.android.com/apk/res-auto"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:orientation="vertical"
+        android:padding="10dip">
+
+        <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1"
+            android:fillViewport="true">
+
+            <LinearLayout
+                android:id="@+id/test_messages"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical">
+
+                <TextView
+                    android:id="@+id/test_instruction"
+                    style="@style/InstructionsFont"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_weight="0" />
+
+                <TextView
+                    android:id="@+id/test_log"
+                    android:layout_width="match_parent"
+                    android:layout_height="0dp"
+                    android:layout_weight="1"
+                    android:orientation="vertical" />
+
+            </LinearLayout>
+        </ScrollView>
+
+        <LinearLayout
+            android:id="@+id/action_buttons"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            android:orientation="horizontal">
+
+            <Button
+                android:id="@+id/action_reset"
+                android:text="@string/keychain_reset"
+                android:layout_weight="1"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content" />
+
+            <Button
+                android:id="@+id/action_skip"
+                android:text="@string/keychain_skip"
+                android:layout_weight="1"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content" />
+
+            <Button
+                android:id="@+id/action_next"
+                android:text="@string/next_button_text"
+                android:layout_weight="1"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content" />
+
+        </LinearLayout>
+
+        <include
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="0"
+            layout="@layout/pass_fail_buttons" />
+
+    </LinearLayout>
+</android.support.wearable.view.BoxInsetLayout>
diff --git a/apps/CtsVerifier/res/layout/network_screen_off.xml b/apps/CtsVerifier/res/layout/network_screen_off.xml
new file mode 100644
index 0000000..5a2446d
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/network_screen_off.xml
@@ -0,0 +1,46 @@
+<?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">
+
+    <Button android:id="@+id/start_btn"
+            android:text="@string/network_screen_off_test_start"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerHorizontal="true"
+            />
+
+    <ScrollView android:id="@+id/scroll"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:layout_below="@id/start_btn"
+            android:layout_above="@id/pass_fail_buttons"
+            >
+        <TextView android:id="@+id/text"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                style="@style/InstructionsFont"
+                />
+    </ScrollView>
+
+    <include android:id="@+id/pass_fail_buttons"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            layout="@layout/pass_fail_buttons" />
+</RelativeLayout>
diff --git a/apps/CtsVerifier/res/layout/permission_lockdown.xml b/apps/CtsVerifier/res/layout/permission_lockdown.xml
new file mode 100644
index 0000000..ea295dd
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/permission_lockdown.xml
@@ -0,0 +1,110 @@
+<?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:id="@+id/permission_lockdown_activity"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+
+    <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:text="@string/device_profile_owner_permission_lockdown_test_instructions"
+                android:textSize="18sp"
+                android:padding="10dp" />
+    </ScrollView>
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="0dp"
+            android:layout_weight="1">
+        <LinearLayout
+                android:orientation="vertical"
+                android:layout_width="match_parent"
+                android:layout_height="match_parent"
+                android:layout_gravity="center_vertical"
+                android:paddingStart="10dp"
+                android:paddingEnd="10dp">
+
+            <LinearLayout
+                    android:orientation="horizontal"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:paddingTop="4dp">
+                <ImageView
+                        android:id="@+id/package_icon"
+                        android:layout_width="48dp"
+                        android:layout_height="48dp"
+                        android:scaleType="centerInside"
+                        android:gravity="center" />
+                <TextView
+                        android:id="@+id/package_name"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        android:gravity="center_vertical"
+                        android:paddingLeft="10dp"
+                        android:textSize="16sp"
+                        android:singleLine="true"
+                        android:ellipsize="end" />
+            </LinearLayout>
+
+            <TextView
+                    android:id="@+id/permission_name"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:textSize="16sp"
+                    android:paddingTop="4dp" />
+
+            <RadioGroup
+                    android:id="@+id/permission_group"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:orientation="vertical"
+                    android:paddingTop="4dp">
+                <RadioButton
+                        android:id="@+id/permission_allow"
+                        android:text="@string/permission_allow"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content" />
+                <RadioButton
+                        android:id="@+id/permission_default"
+                        android:text="@string/permission_default"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content" />
+                <RadioButton
+                        android:id="@+id/permission_deny"
+                        android:text="@string/permission_deny"
+                        android:layout_width="wrap_content"
+                        android:layout_height="wrap_content" />
+            </RadioGroup>
+
+            <Button
+                    android:id="@+id/open_settings"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:layout_gravity="center_horizontal"
+                    android:text="@string/open_settings_button_label"
+                    android:onClick="openSettings" />
+        </LinearLayout>
+    </ScrollView>
+
+</LinearLayout>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/positive_device_owner.xml b/apps/CtsVerifier/res/layout/positive_device_owner.xml
new file mode 100644
index 0000000..f5d10e0
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/positive_device_owner.xml
@@ -0,0 +1,49 @@
+<?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="match_parent"
+        android:layout_height="match_parent"
+        >
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="320dp"
+            android:layout_weight="2">
+        <TextView
+                android:id="@+id/positive_device_owner_instructions"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="10dip"
+                android:text="@string/device_owner_positive_tests_instructions"
+                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>
\ No newline at end of file
diff --git a/apps/CtsVerifier/res/layout/provisioning_byod.xml b/apps/CtsVerifier/res/layout/provisioning_byod.xml
index b1b75ba..375c3ab 100644
--- a/apps/CtsVerifier/res/layout/provisioning_byod.xml
+++ b/apps/CtsVerifier/res/layout/provisioning_byod.xml
@@ -24,19 +24,17 @@
             android:layout_height="320dp"
             android:layout_weight="2">
         <TextView
-                android:id="@+id/byod_instructions"
+                android:id="@+id/test_instructions"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:padding="10dip"
-                android:text="@string/provisioning_byod_instructions"
                 android:textSize="18dip" />
     </ScrollView>
 
     <Button
-        android:id="@+id/byod_start"
+        android:id="@+id/prepare_test_button"
         android:layout_width="204dp"
-        android:layout_height="wrap_content"
-        android:text="@string/provisioning_byod_start" />
+        android:layout_height="wrap_content" />
 
     <ListView
         android:id="@+id/android:list"
diff --git a/apps/CtsVerifier/res/layout/sec_screen_lock_keys_main.xml b/apps/CtsVerifier/res/layout/sec_screen_lock_keys_main.xml
new file mode 100644
index 0000000..af53335
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/sec_screen_lock_keys_main.xml
@@ -0,0 +1,36 @@
+<?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"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="10dip"
+        >
+
+    <Button android:id="@+id/sec_start_test_button"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_centerInParent="true"
+            android:text="@string/sec_start_test"
+            />
+
+    <include android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentBottom="true"
+            layout="@layout/pass_fail_buttons"
+            />
+
+</RelativeLayout>
+
diff --git a/apps/CtsVerifier/res/layout/vpn_test.xml b/apps/CtsVerifier/res/layout/vpn_test.xml
new file mode 100644
index 0000000..83c0c1b
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/vpn_test.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.
+-->
+<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="320dp"
+            android:layout_weight="2">
+        <TextView
+                android:id="@+id/device_owner_vpn_info"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="10dip"
+                android:text="@string/device_owner_vpn_info_default"
+                android:textSize="18dip" />
+    </ScrollView>
+
+    <include layout="@layout/pass_fail_buttons" />
+
+</LinearLayout>
diff --git a/apps/CtsVerifier/res/layout/wifi_lockdown.xml b/apps/CtsVerifier/res/layout/wifi_lockdown.xml
new file mode 100644
index 0000000..2ac337e
--- /dev/null
+++ b/apps/CtsVerifier/res/layout/wifi_lockdown.xml
@@ -0,0 +1,76 @@
+<?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="match_parent"
+        android:layout_height="match_parent">
+
+    <ScrollView
+            android:layout_width="match_parent"
+            android:layout_height="320dp"
+            android:layout_weight="2">
+        <TextView
+                android:id="@+id/device_owner_wifi_lockdown_info"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:padding="10dip"
+                android:text="@string/device_owner_wifi_lockdown_info"
+                android:textSize="18dip" />
+    </ScrollView>
+
+    <EditText
+        android:id="@+id/device_owner_wifi_ssid"
+        android:hint="(SSID)"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <RadioGroup
+        android:id="@+id/device_owner_keyManagementMethods"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal">
+        <RadioButton
+            android:id="@+id/device_owner_keymgmnt_none"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/device_owner_wifi_key_management_none_button" />
+        <RadioButton
+            android:id="@+id/device_owner_keymgmnt_wpa"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/device_owner_wifi_key_management_wpa_button" />
+        <RadioButton
+            android:id="@+id/device_owner_keymgmnt_wep"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:text="@string/device_owner_wifi_key_management_wep_button" />
+    </RadioGroup>
+
+    <Button
+        android:id="@+id/create_wifi_config_button"
+        android:layout_width="204dp"
+        android:layout_height="wrap_content"
+        android:text="@string/create_wifi_config_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/raw/cacert.der b/apps/CtsVerifier/res/raw/cacert.der
new file mode 100644
index 0000000..3934e1b
--- /dev/null
+++ b/apps/CtsVerifier/res/raw/cacert.der
Binary files differ
diff --git a/apps/CtsVerifier/res/raw/next_axis.mp3 b/apps/CtsVerifier/res/raw/next_axis.mp3
new file mode 100644
index 0000000..0a3174d
--- /dev/null
+++ b/apps/CtsVerifier/res/raw/next_axis.mp3
Binary files differ
diff --git a/apps/CtsVerifier/res/raw/stereo_mono_white_noise_48.mp3 b/apps/CtsVerifier/res/raw/stereo_mono_white_noise_48.mp3
new file mode 100644
index 0000000..e877fc1
--- /dev/null
+++ b/apps/CtsVerifier/res/raw/stereo_mono_white_noise_48.mp3
Binary files differ
diff --git a/apps/CtsVerifier/res/raw/usercert.der b/apps/CtsVerifier/res/raw/usercert.der
new file mode 100644
index 0000000..cdfb8f7
--- /dev/null
+++ b/apps/CtsVerifier/res/raw/usercert.der
Binary files differ
diff --git a/apps/CtsVerifier/res/raw/userkey.der b/apps/CtsVerifier/res/raw/userkey.der
new file mode 100644
index 0000000..31f1f8c
--- /dev/null
+++ b/apps/CtsVerifier/res/raw/userkey.der
Binary files differ
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 37c2cf4..985767c 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -22,6 +22,7 @@
     <string name="info_button_text">Info</string>
     <string name="fail_button_text">Fail</string>
     <string name="next_button_text">Next</string>
+    <string name="go_button_text">Go</string>
 
     <!-- Strings for TestListActivity -->
     <string name="test_category_audio">Audio</string>
@@ -43,6 +44,7 @@
     <string name="test_results_cleared">Test results cleared.</string>
     <string name="view">View</string>
     <string name="test_results_error">Couldn\'t create test results report.</string>
+    <string name="runtime_permissions_error">Cannot continue. Please grant runtime permissions</string>
     <string name="export">Export</string>
     <string name="no_storage">Cannot save report to external storage, see log for details.</string>
     <string name="report_saved">Report saved to: %s</string>
@@ -122,10 +124,30 @@
         settings that may specify a timeout.\n\nClick the \"Force Lock\" button to lock the screen.
         Your screen should be locked and require the password to be entered.
     </string>
+    <string name="da_kg_disabled_features_test">Keyguard Disabled Features Test</string>
+    <string name="rn_kg_disabled_features_test">Redacted Notifications Keyguard Disabled Features Test</string>
     <string name="da_force_lock">Force Lock</string>
     <string name="da_lock_success">It appears the screen was locked successfully!</string>
     <string name="da_lock_error">It does not look like the screen was locked...</string>
 
+    <!-- Strings for lock bound keys test -->
+    <string name="sec_lock_bound_key_test">Lock Bound Keys Test</string>
+    <string name="sec_lock_bound_key_test_info">
+        This test ensures that Keystore cryptographic keys that are bound to lock screen authentication
+        are unusable without a recent enough authentication. You need to set up a screen lock in order to
+        complete this test. If available, this test should be run by using fingerprint authentication
+        as well as PIN/pattern/password authentication.
+    </string>
+    <string name="sec_fingerprint_bound_key_test">Fingerprint Bound Keys Test</string>
+    <string name="sec_fingerprint_bound_key_test_info">
+        This test ensures that Keystore cryptographic keys that are bound to fingerprint authentication
+        are unusable without an authentication. You need to set up a fingerprint order to
+        complete this test.
+    </string>
+    <string name="sec_fp_dialog_message">Authenticate now with fingerprint</string>
+    <string name="sec_fp_auth_failed">Authentication failed</string>
+    <string name="sec_start_test">Start Test</string>
+
     <!-- Strings for BluetoothActivity -->
     <string name="bluetooth_test">Bluetooth Test</string>
     <string name="bluetooth_test_info">The Bluetooth Control tests check whether or not the device
@@ -298,6 +320,53 @@
 
     <string name="empty"></string>
 
+    <!-- Strings for HifiUltrasoundTestActivity -->
+    <string name="hifi_ultrasound_test">Hifi Ultrasound Microphone Test</string>
+    <string name="hifi_ultrasound_test_info">
+        This is a test for near-ultrasound (18500Hz - 20000Hz) microphone response.\n
+        This test requires two devices.\n</string>
+    <string name="hifi_ultrasound_test_play">PLAY</string>
+    <string name="hifi_ultrasound_test_record">RECORD</string>
+    <string name="hifi_ultrasound_test_plot">PLOT</string>
+    <string name="hifi_ultrasound_test_dismiss">DISMISS</string>
+    <string name="hifi_ultrasound_test_ok">OK</string>
+    <string name="hifi_ultrasound_test_instruction1">
+        Open Hifi Ultrasound Microphone Test on the test device and the reference device.\n
+        Set the media volume of the reference device at 70% and hold it with one hand.\n
+        Hold the testing device with the other hand\n
+        Press the RECORD button on the testing device, then the PLAY button on the reference device within one second.\n
+        After the test, report result on the testing (recording) device.\n</string>
+    <string name="hifi_ultrasound_test_pass">PASS</string>
+    <string name="hifi_ultrasound_test_fail">FAIL</string>
+    <string name="hifi_ultrasound_test_default_false_string">false</string>
+    <string name="hifi_ultrasound_test_mic_no_support">
+        Device does not support near-ultrasound recording.\n
+        Please report PASS.\n</string>
+    <string name="hifi_ultrasound_test_spkr_no_support">
+        Device does not support near-ultrasound playback.\n
+        If this is your reference device, please use a different reference device.\n</string>
+
+    <string name="hifi_ultrasound_speaker_test">Hifi Ultrasound Speaker Test</string>
+    <string name="hifi_ultrasound_speaker_test_info">
+        This is a test for near-ultrasound (18500Hz - 20000Hz) speaker response.\n
+        This test requires two devices.\n</string>
+    <string name="hifi_ultrasound_speaker_test_instruction1">
+        Open Hifi Ultrasound Speaker Test on the test device and the reference device.\n
+        Set the media volume of the testing device at 70% and hold it with one hand.\n
+        Hold the reference device with the other hand\n
+        Press the RECORD button on the reference device, then the PLAY button on the testing device within one second.\n
+        After the test, report result on the testing (playback) device.\n</string>
+    <string name="hifi_ultrasound_speaker_test_mic_no_support">
+        Device does not support near-ultrasound recording.\n
+        If this is your reference device, please use a different reference device.\n</string>
+    <string name="hifi_ultrasound_speaker_test_spkr_no_support">
+        Device does not support near-ultrasound playback.\n
+        Please report PASS.\n</string>
+    <string name="hifi_ultrasound_speaker_test_test_side">
+        Please wait for the result on the reference device then report here.</string>
+    <string name="hifi_ultrasound_speaker_test_reference_side">
+        Please report on the testing device.\n</string>
+
     <!-- Strings for Location tests -->
     <string name="location_gps_test">GPS Test</string>
     <string name="location_gps_test_info">This test verifies basic GPS behavior
@@ -306,6 +375,21 @@
         (for example, outside, or near a window)
         and then press OK to run the automated tests.</string>
 
+    <!-- Strings for net.ConnectivityScreenOffTestActivity -->
+    <string name="network_screen_off_test">Network Connectivity Screen Off Test</string>
+    <string name="network_screen_off_test_instructions">
+        This test verifies that IPv6 network connectivity continues to work
+        when the screen is off.\n\n
+
+        1. Join a Wi-Fi network with IPv6 Internet access.\n
+        2. If the device has battery power, disconnect all power connectors.\n
+        3. Turn the screen off.\n
+        4. Wait until the screen turns on (it will take at least two minutes).\n
+        5. If necessary, unlock the device.\n
+        6. Please mark the test according to the result status indicated.\n
+    </string>
+    <string name="network_screen_off_test_start">Start</string>
+
     <!-- Strings for NfcTestActivity -->
     <string name="nfc_test">NFC Test</string>
     <string name="nfc_test_info">The Peer-to-Peer Data Exchange tests require two devices with
@@ -331,6 +415,7 @@
     <string name="nfc_pee_2_pee">Peer-to-Peer Data Exchange</string>
     <string name="nfc_ndef_push_sender">NDEF Push Sender</string>
     <string name="nfc_ndef_push_receiver">NDEF Push Receiver</string>
+    <string name="nfc_llcp_version_check">LLCP version check</string>
 
     <string name="nfc_tag_verification">Tag Verification</string>
     <string name="nfc_ndef">NDEF</string>
@@ -352,6 +437,13 @@
     <string name="nfc_ndef_push_receive_failure">Failed to receive the correct NDEF push
         message.</string>
 
+    <string name="nfc_llcp_version_check_info">This test requires two candidate devices
+       with NFC enabled to exchange P2P messages. Start the \"LLCP version check\" test on
+       the other candidate device also, and touch the devices back to back. This test
+       then verifies that the candidate device correctly advises the LLCP version as 1.2</string>
+    <string name="nfc_llcp_version_check_failure">The candidate devices does not report LLCP
+       version 1.2 or higher.</string>
+    <string name="nfc_llcp_version_check_success">The candidate device has a valid LLCP version.</string>
     <string name="nfc_tag_verifier">NFC Tag Verifier</string>
     <string name="nfc_tag_verifier_info">Follow the on-screen instructions to write and read
         a tag of the chosen technology.</string>
@@ -496,6 +588,8 @@
     <string name="snsr_test_skipped">SKIPPED</string>
     <string name="snsr_test_fail">FAIL</string>
     <string name="snsr_execution_time">Test execution time %1$s sec</string>
+    <string name="snsr_rvcvxchk_test">Rotation Vector CV XCheck</string>
+    <string name="snsr_rvcvxchk_test_rec">Rotation Vector CV XCheck Recording</string>
 
     <!-- Strings to interact with users in Sensor Tests -->
     <string name="snsr_test_play_sound">A sound will be played once the verification is complete...</string>
@@ -600,6 +694,14 @@
     <string name="snsr_step_counter_event">%1$d | Step Counter event. count=%2$d.</string>
     <string name="snsr_step_detector_event">%1$d | Step Detector event.</string>
 
+    <!-- Device suspend tests -->
+    <string name="snsr_device_suspend_test">Device Suspend Tests</string>
+    <string name="snsr_device_did_not_go_into_suspend">Device did not go into suspend mode during test execution </string>
+    <string name="snsr_batch_did_not_arrive_at_expected_time">Batch did not arrive at the expected time estimatedBatchArrivalMs=%1$d
+    firstEventReceivedMs=%2$d diffMs=%3$d toleranceMs=%4$d </string>
+    <string name="snsr_device_suspend_test_instr">One you begin the test, disconnect USB, turn off the display and allow
+    the device to go into suspend mode. The screen will turn on and a sound will be played once all the tests are completed.</string>
+
     <!-- Significant Motion -->
     <string name="snsr_significant_motion_test">Significant Motion Tests</string>
     <string name="snsr_significant_motion_event_arrival">Event expected to trigger. Triggered=%1$s.</string>
@@ -614,6 +716,9 @@
     <string name="snsr_significant_motion_test_deactivation">Once you begin the test, you will need to walk to ensure Significant Motion triggers only once.</string>
     <string name="snsr_significant_motion_registration">Expected to be able to register for TriggerSensor. Found=%1$b.</string>
     <string name="snsr_significant_motion_cancelation">Expected to be able to cancel TriggerSensor. Found=%b.</string>
+    <string name="snsr_significant_motion_ap_suspend">One you begin the test, disconnect USB, turn off the display and allow the device to go into suspend.
+    You will need to walk to ensure that Significant Motion triggers. The screen will turn on and a sound will be played once the test completes.</string>
+    <string name="snsr_device_did_not_wake_up_at_trigger">Device did not wakeup at tigger time. wakeTime=%1$d ms triggerTime=%2$d ms</string>
 
     <!-- Strings for Sensor CTS tests inside CtsVerifier -->
     <string name="snsr_single_sensor_tests">CTS Single Sensor Tests</string>
@@ -636,18 +741,6 @@
     <string name="congratulations">Congratulations!</string>
     <string name="no_suid_files">No unauthorized suid files detected!</string>
 
-    <!-- Strings for Camera Analyzer -->
-    <string name="camera_analyzer">Camera Analyzer</string>
-    <string name="ca_find_checkerboard_label">Find target</string>
-    <string name="ca_check_formats_label">Output formats</string>
-    <string name="ca_exposure_test_label">Exposure Comp.</string>
-    <string name="ca_result_label">Results will be here</string>
-    <string name="ca_wb_test_label">White Balance</string>
-    <string name="ca_lock_test_label">AE Lock</string>
-    <string name="ca_metering_label">Metering Area</string>
-    <string name="ca_focus_modes_label">Focus Modes</string>
-    <string name="ca_info">This test checks the image quality of the camera of this device. It requires a MacBeth 4x6 color checker. With an ADK board and a lamp connected to it on the Relay 1 port, all tests can be run automatically. Without the ADK board, all the tests except the Auto Exposure Lock Test can be run automatically and the Auto Exposure Lock Test will require users to turn on/off a lamp according to the instruction given. </string>
-
     <!-- Strings for Camera Orientation -->
     <string name="camera_orientation">Camera Orientation</string>
     <string name="co_info">This test verifies the orientation capabilities of
@@ -815,6 +908,25 @@
     <string name="its_test_passed">All Camera ITS tests passed.  Pass button enabled!</string>
     <string name="its_test_failed">Some Camera ITS tests failed.</string>
 
+    <!-- Strings for the Camera Flashlight test activity -->
+    <string name="camera_flashlight_test">Camera Flashlight</string>
+    <string name="camera_flashlight_info">
+        This test checks the flashlight functionality. It will turn on and off the flashlight of
+        each camera device that has a flash unit. Follow the instructions on screen and observe the
+        flashlight status changing.
+    </string>
+    <string name="camera_flashlight_start_button">Start</string>
+    <string name="camera_flashlight_next_button">Next</string>
+    <string name="camera_flashlight_done_button">Done</string>
+    <string name="camera_flashlight_on_button">On</string>
+    <string name="camera_flashlight_off_button">Off</string>
+    <string name="camera_flashlight_start_text">Press Start to start flashlight test.</string>
+    <string name="camera_flashlight_question_text">Is Camera %1$s flashlight on or off?</string>
+    <string name="camera_flashlight_next_text">Ok. Press next.</string>
+    <string name="camera_flashlight_failed_text">Test failed. Press Done or Fail button.</string>
+    <string name="camera_flashlight_passed_text">All tests passed. Press Done or Pass button.
+    </string>
+
     <!-- Strings for StreamingVideoActivity -->
     <string name="streaming_video">Streaming Video Quality Verifier</string>
     <string name="streaming_video_info">This is a test for assessing the quality of streaming videos.  Play each stream and verify that the video is smooth and in sync with the audio, and that there are no quality problems.</string>
@@ -1001,13 +1113,12 @@
         respecting user preferences about notification ranking and filtering.
     </string>
     <string name="attention_ready">I\'m done</string>
-    <string name="attention_filter_all">Please set the notification filter to \"All\" in the dialog
-        that appears when you change the device\'s volume.</string>
-    <string name="attention_filter_priority">Please set the notification filter to \"Priority\" in
-        the dialog that appears when you change the device\'s volume, and allow messages from
-        starred contacts.</string>
-    <string name="attention_filter_none">Please set the notification filter to \"None\" in the dialog
-        that appears when you change the device\'s volume.</string>
+    <string name="attention_filter_all">Please disable \"Do not disturb\" by tapping the Quick Settings tile.</string>
+    <string name="attention_filter_priority">Please select \"Priority only\" in the dialog that appears
+        when you tap the \"Do not disturb\" tile in Quick Settings, and customize the setting to allow messages from
+        starred contacts only by tapping "More settings".</string>
+    <string name="attention_filter_none">Please select \"Total silence\" in the dialog that appears
+        when you tap the \"Do not disturb\" tile in Quick Settings.</string>
     <string name="attention_create_contacts">Create contacts for notification annotations.</string>
     <string name="attention_delete_contacts">Delete test contacts.</string>
     <string name="attention_default_order">Check that ranker defaults to time order.</string>
@@ -1109,6 +1220,23 @@
     <string name="caboot_reboot_desc">Please reboot the device and return to this test.</string>
     <string name="caboot_after_boot">AFTER REBOOTING: Check that there is a notification that the network may be monitored. Opening that notification should show a dialog box giving more information, with a button to check trusted credentials. This should open up the same view of trusted credentials that you get via the "Check credentials" button.</string>
 
+    <!-- Strings for KeyChain -->
+    <string name="keychain_test">KeyChain Storage Test</string>
+    <string name="keychain_info">This test checks that credentials installed to the system can be granted, retrieved, and used to create valid HTTPS connections.</string>
+    <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
+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
+ 1. Clear device credentials.\n
+ 2. Change the lock screen type to \'None\'.</string>
+
     <!-- Strings for Widget -->
     <string name="widget_framework_test">Widget Framework Test</string>
     <string name="widget_framework_test_info">This test checks some basic features of the widget
@@ -1166,6 +1294,24 @@
     <string name="provisioning_byod_capture_media_error">Error while capturing media from managed profile.</string>
     <string name="provisioning_byod_capture_image_error">Error while capturing image from managed profile.</string>
 
+    <string name="provisioning_byod_auth_bound_key">Autentication-boud keys</string>
+    <string name="provisioning_byod_auth_bound_key_info">
+        This test verifies keystore cryptographic keys can be bound to device credentials.
+        These keys should only be available if there was a recent enough authentication.
+    </string>
+    <string name="provisioning_byod_auth_bound_key_instruction">
+        This test verifies keystore cryptographic keys can be bound to device lockscreen challenge or fingerprints (if available).
+        These keys should only be available if there was a recent enough authentication. \n
+
+        1. Press "Set up" to open Security settings. Create a lockscreen password and if available, enroll a fingerprint.\n
+        2. Go through the list of tests.\n
+        3. Mark the overall test pass or fail.\n
+        4. Once the set of tests are completed, remove the lockscreen challenge.
+    </string>
+    <string name="provisioning_byod_auth_bound_key_set_up">Set up</string>
+    <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>
     <!-- Strings for DeskClock -->
     <string name="deskclock_tests">Alarms and Timers Tests</string>
     <string name="deskclock_tests_info">
@@ -1211,8 +1357,8 @@
         1. Press the "Create Alarm" button.\n
         2. Verify that you see one alarm with the following information:\n
            Name of alarm: Create Alarm Test. \n
-           Vibrate: on.\n
-           Ringtone: silent.\n
+           Vibrate: on. (if the device supports vibrate).\n
+           Ringtone: silent. (if the device has a speaker).\n
            Time:  01:23. \n
            Repeating on: Monday and Wednesday. \n
     </string>
@@ -1294,9 +1440,32 @@
     <string name="snsr_rotation_vector_set_final">Place the device back to the reference position.</string>
     <string name="snsr_rotation_vector_verification">Angular deviation [%1$4.1f %2$4.1f %3$4.1f]. Current: %4$f deg. Max tolerated: %5$f.</string>
 
+    <!-- Strings for device admin tests -->
+    <string name="device_admin_notification">This is device admin notification</string>
+    <string name="device_admin_keyguard_disable_camera">Disable camera</string>
+    <string name="device_admin_keyguard_disable_camera_instruction">
+        Please press the Go button to lock the screen. Then try to open the camera
+        from the lower right corner of the screen. Expected result is you cannot
+        open the camera from lock screen and it will ask for password instead.
+    </string>
+    <string name="device_admin_disable_notifications">Disable notifications</string>
+    <string name="device_admin_disable_notifications_instruction">
+        Please press the Go button to lock the screen. Wait a few seconds to see
+        if a notification appears. Expected result is no notifications appear.
+        You should be able to see one after unlocking.
+    </string>
+    <string name="device_admin_disable_unredacted_notifications">Disable unredacted notifications</string>
+    <string name="device_admin_disable_unredacted_notifications_instruction">
+        Please press the Go button to lock the screen. Wait a few seconds to see
+        if a notification appears. Expected result is a notification appear with
+        its content hidden. You should be able to see the content after unlocking.
+    </string>
+
+    <!-- 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="test_category_managed_provisioning">Managed Provisioning</string>
-    <string name="provisioning_byod_device_admin">CTS Verifier - BYOD Admin</string>
     <string name="provisioning_byod">BYOD Managed Provisioning</string>
     <string name="provisioning_byod_info">
         This test exercises the BYOD managed provisioning flow.
@@ -1322,12 +1491,13 @@
     <string name="provisioning_byod_profile_visible">Profile-aware accounts settings</string>
     <string name="provisioning_byod_admin_visible">Profile-aware device administrator settings</string>
     <string name="provisioning_byod_workapps_visible">Badged work apps visible in Launcher</string>
-    <string name="provisioning_byod_cross_profile">Open app cross profiles</string>
-    <string name="provisioning_byod_cross_profile_app_personal">
-        You selected the CTS Verifier option.
-    </string>
+    <string name="provisioning_byod_cross_profile_from_personal">Open app cross profiles from the personal side</string>
+    <string name="provisioning_byod_cross_profile_from_work">Open app cross profiles from the work side</string>
+    <string name="provisioning_app_linking">App links from the work side</string>
+    <string name="provisioning_byod_cross_profile_app_personal">You selected the personal option.</string>
     <string name="provisioning_byod_cross_profile_app_work">You selected the Work option.</string>
-    <string name="provisioning_byod_cross_profile_instruction">
+    <string name="provisioning_byod_cross_profile_app_ctsverifier"> You selected the ctsverifier option </string>
+    <string name="provisioning_byod_cross_profile_from_personal_instruction">
         Please press the Go button to start an action.\n
         \n
         You should be asked to choose either \"CTS Verifier\" or \"Work\" to complete the action.
@@ -1335,13 +1505,99 @@
         \n
         Verify that you are prompted with the above choices and both options work as intended. Then mark this test accordingly.
     </string>
+    <string name="provisioning_byod_cross_profile_from_work_instruction">
+        Please press the Go button to start an action.\n
+        \n
+        You should be asked to choose either \"CTS Verifier\" or \"Personal\" to complete the action.
+        Pressing either should bring up a page stating your choice.\n
+        \n
+        Verify that you are prompted with the above choices and both options work as intended. Then mark this test accordingly.
+    </string>
+    <string name="provisioning_byod_app_linking_instruction">
+        Please press the Go button to start an action.\n
+        \n
+        You should be asked to choose either \"CTS Verifier\" or \"Personal\" to complete the action.\n
+        - If you choose \"CTS Verifier\", you should see a page stating your chose \"CTS Verifier\".\n
+        - If you choose \"Personal\", you should be presented with another dialog between \"CTS Verifier\"
+        and some other apps. In this case, you should choose \"CTS verifier\".\n
+        You should then see a page stating you chose \"Personal\".\n
+        \n
+        Verify that you are prompted with the above choices and both options work as intended. Then mark this test accordingly.
+    </string>
+    <string name="provisioning_byod_keyguard_disabled_features">Keyguard disabled features</string>
+    <string name="provisioning_byod_keyguard_disabled_features_info">
+        This test exercises Keyguard Disabled Features. Follow instructions above.
+    </string>
+    <string name="provisioning_byod_keyguard_disabled_features_instruction">
+        Please go to Settings &gt; Security &gt; Device administrators and set
+        \"CTS Verifier\" as active admin.\n
+        After that please press the \"Prepare test\" button to disable trust agents.\n
+        Then please press through the following verification steps.\n
+        Note: Device password will be set to \"testpassword\". After leaving the screen device
+        password and active admin status will be cleared.
+    </string>
+    <string name="provisioning_byod_keyguard_disabled_features_prepare_button">Prepare test</string>
+    <string name="provisioning_byod_keyguard_disabled_features_not_admin">CtsVerifier is not active admin. Please follow instructions.</string>
+    <string name="provisioning_byod_disable_trust_agents">Disable trust agents</string>
+    <string name="provisioning_byod_disable_trust_agents_instruction">
+        Please press the Go button to go to Settings > Security. Then go to Trusted agents and\n
+        check if the agents are shown as disabled by the administrator.
+        Then please press Back and mark the test as \"Pass\" or \"Fail\".
+    </string>
+    <string name="provisioning_byod_fingerprint_disabled_in_settings">Fingerprint is disabled in Settings</string>
+    <string name="provisioning_byod_fingerprint_disabled_in_settings_instruction">
+        Please press the Go button to go to Settings > Security. Then go to Fingerprint and\n
+        check if the disclaimer at the bottom of screen is altered to warn the users for\n
+        fingerprint being disabled in lock screen. Then please press Back and mark the \n
+        test as \"Pass\" or \"Fail\".
+    </string>
+    <string name="provisioning_byod_disable_fingerprint">Fingerprint disabled on keyguard</string>
+    <string name="provisioning_byod_disable_fingerprint_instruction">
+        Please press the Go button to lock the screen. Then try to log in using the fingerprint reader.\n
+        Expected result is you cannot log in using your fingerprint.\n
+        After you log back in, please navigate back to CtsVerifier and mark the test as \"Pass\" or \"Fail\".
+    </string>
+    <string name="provisioning_byod_disable_unredacted_notifications">Unredacted notifications disabled on keyguard</string>
+    <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
+        (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>
     <string name="provisioning_byod_work_notification">Work notification is badged</string>
     <string name="provisioning_byod_work_notification_instruction">
         Please press the Go button to trigger a notification.\n
         \n
         Verify that the notification is badged (see sample badge below). Then mark this test accordingly.
     </string>
-    <string name="provisioning_byod_work_notification_title">This is a work notification</string>
+    <string name="provisioning_byod_notification_title">This is a notification</string>
+    <string name="provisioning_byod_work_status_icon">Work status icon is displayed</string>
+    <string name="provisioning_byod_work_status_icon_instruction">
+        Verify that the current status bar does not have a work status icon (see sample icon below).
+        \n\n
+        Please press the Go button to launch a work activity.
+        \n\n
+        Verify that the status bar now has a work status icon. Then mark this test accordingly.
+    </string>
+    <string name="provisioning_byod_work_status_icon_activity">
+        Verify that the current status bar has a work status notification.
+        \n\n
+        Please press finish to return to the tests and then mark this test accordingly.
+    </string>
+    <string name="provisioning_byod_work_status_toast">Work status toast is displayed</string>
+    <string name="provisioning_byod_work_status_toast_instruction">
+        Please press the Go button to launch a work activity.
+        \n\n
+        Follow instructions and then return and mark this test accordingly.
+    </string>
+    <string name="provisioning_byod_work_status_toast_activity">
+        Turn off the screen and wait a few seconds then turn on the screen again.
+        \n\n
+        Verify that a toast was displayed saying you are in the work profile.
+        \n\n
+        Please press finish to return to the tests and then mark this test accordingly.
+    </string>
     <string name="provisioning_byod_profile_visible_instruction">
         Please press the Go button to open the Settings page.
         Navigate to Accounts and confirm that:\n
@@ -1349,6 +1605,10 @@
         - Both Personal and Work categories exist.\n
         - \"Remove work profile\" exists under the Work category.\n
         \n
+        Furthermore, hit the action overflow button (3 dots) and verify that:\n
+        - There are two auto-sync options present, one for personal and one for work data.\n
+        - De-selecting either option prompts a warning dialog.\n
+        \n
         Use the Back button to return to this page.
     </string>
     <string name="provisioning_byod_admin_visible_instruction">
@@ -1356,7 +1616,7 @@
         Navigate to Device administrators and confirm that:\n
         \n
         - Both Personal and Work categories exist.\n
-        - \"CTS Verifier - BYOD Admin\" exists under the Work category, and is activated.\n
+        - \"CTS Verifier\" exists under the Work category, and is activated.\n
         \n
         Use the Back button to return to this page.
     </string>
@@ -1389,6 +1649,29 @@
         Then use the Back button to return to this test and mark accordingly.
     </string>
 
+    <string name="provisioning_byod_battery_settings">Profile-aware battery settings</string>
+    <string name="provisioning_byod_battery_settings_instruction">
+        Please press the Go button to open Battery page in settings.\n
+        \n
+        Verify that Battery page shows both badged and unbadged apps in the usage list.\n
+        \n
+        Note that the usage list only displays usage since last charge,
+        so you may need to unplug your device and use a badged and unbadged app
+        for a little while before they will appear in the list.\n
+        \n
+        Then use the Back button to return to this test and mark accordingly.
+    </string>
+
+    <string name="provisioning_byod_data_usage_settings">Profile-aware data usage settings</string>
+    <string name="provisioning_byod_data_usage_settings_instruction">
+        Please press the Go button to open the Settings page.\n
+        \n
+        Navigate to Data usage page and confirm that it includes a Work profile section,
+        and that tapping it shows just work profile data usage.\n
+        \n
+        Then use the Back button to return to this test and mark accordingly.
+    </string>
+
     <string name="provisioning_byod_cred_settings">Profile-aware trusted credential settings</string>
     <string name="provisioning_byod_cred_settings_instruction">
         Please press the Go button to open the Security settings.
@@ -1410,11 +1693,15 @@
         Then use the Back button to return to this test and mark accordingly.
     </string>
 
+    <string name="provisioning_byod_cross_profile_intent_filters">Cross profile intent filters are set</string>
+
     <string name="provisioning_byod_nfc_beam">Disable Nfc beam</string>
     <string name="provisioning_byod_nfc_beam_allowed_instruction">
         Please press the Go button to test if Nfc beam can be triggered in the work profile.\n
         \n
-        Press \"Send share intent\" to trigger a beam. Verify that the beam is invoked.\n
+        For the first test, press \"Send manual beam\" to trigger a beam, then bump into another device to send the file. Verify that the file is successfully received.\n
+        \n
+        For the second test, press \"Send share intent\" to trigger a beam, then bump into another device to send the file. Verify that the file is successfully received.\n
         \n
         Then use the Back button to return to this test and mark accordingly.
     </string>
@@ -1429,14 +1716,35 @@
     <string name="provisioning_byod_send_share_intent">Send share intent</string>
     <string name="provisioning_byod_cannot_resolve_beam_activity">Cannot find beam activity</string>
 
+    <string name="test_failed_cannot_start_intent">Cannot start the given intent.</string>
     <string name="provisioning_byod_no_activity">Cannot communicate with activity in the work profile.</string>
     <string name="provisioning_byod_delete_profile">Initiate deletion of work profile.</string>
     <string name="provisioning_byod_profile_deleted">Work profile deleted.</string>
     <string name="provisioning_byod_disabled">Device provisioning is not enabled.</string>
-    <string name="provisioning_byod_go">Go</string>
     <string name="provisioning_button_finish">Finish</string>
     <string name="provisioning_cross_profile_chooser">Choose an app to complete action</string>
 
+    <string name="provisioning_byod_no_gps_location_feature">No GPS feature present. Skip test.</string>
+    <string name="provisioning_byod_location_mode_enable">Enable location</string>
+    <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
+        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_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. 
+        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>
+
     <!-- Strings for DeviceOwnerProvisioningTest -->
     <string name="provisioning_device_owner">Device Owner Provisioning</string>
     <string name="device_owner_provisioning_tests">Device Owner provisioning tests</string>
@@ -1445,6 +1753,201 @@
     <string name="device_owner_negative_test">Device owner negative test</string>
     <string name="device_owner_negative_test_info">Please click the "Start provisioning" button, and when you see a warning dialog telling the device is already set up, select "pass". Otherwise, select "fail".</string>
     <string name="start_device_owner_provisioning_button">Start provisioning</string>
+    <string name="positive_device_owner">Device Owner Tests</string>
+    <string name="device_owner_positive_tests">Device Owner positive tests</string>
+    <string name="device_owner_positive_tests_instructions">
+            The positive device owner tests verify policies 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_positive_tests_info">
+            The positive device owner tests verify policies 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_positive_category">Device Owner Tests</string>
+    <string name="set_device_owner_button_label">Set up device owner</string>
+    <string name="set_device_owner_dialog_title">Set up device owner</string>
+    <string name="set_device_owner_dialog_text">
+            Please set the device owner by enabling USB debugging on the device and issuing the following command on the host:\n
+            adb shell dpm set-device-owner \'com.android.cts.verifier/com.android.cts.verifier.managedprovisioning.DeviceAdminTestReceiver\'
+    </string>
+    <string name="device_owner_remove_device_owner_test">Remove device owner</string>
+    <string name="device_owner_remove_device_owner_test_info">
+            Please check in Settings &gt; Security &gt; Device Administrators if CTSVerifier is
+            Device Owner. Then press the button below, and check that CTSVerifier is NOT Device
+            Owner anymore.
+    </string>
+    <string name="remove_device_owner_button">Remove device owner</string>
+    <string name="device_owner_check_device_owner_test">Check device owner</string>
+    <string name="device_owner_incorrect_device_owner">Missing or incorrect device owner: CTSVerifier is not DO!</string>
+    <string name="device_owner_wifi_lockdown_test">WiFi configuration lockdown</string>
+    <string name="device_owner_wifi_lockdown_info">
+            Please enter the SSID and auth method of an available WiFi Access Point and press the button to create a
+            WiFi configuration. This configuration can be seen on Settings &gt; WiFi. The test cases
+            are going to use this config. Please go through test cases in order (from top to bottom).
+    </string>
+    <string name="switch_wifi_lockdown_off_button">WiFi config lockdown off</string>
+    <string name="switch_wifi_lockdown_on_button">WiFi config lockdown on</string>
+    <string name="wifi_lockdown_go_settings_wifi_button">Go to WiFi Settings</string>
+    <string name="device_owner_wifi_key_management_none_button">None</string>
+    <string name="device_owner_wifi_key_management_wpa_button">WPA</string>
+    <string name="device_owner_wifi_key_management_wep_button">WEP</string>
+    <string name="create_wifi_config_button_label">Create WiFi configuration</string>
+    <string name="wifi_lockdown_add_network_failed_dialog_title">WiFi configuration could not be created</string>
+    <string name="wifi_lockdown_add_network_failed_dialog_text">
+            There was an error during creation of WiFi configuration. Check if WiFi is switched on.
+    </string>
+    <string name="device_owner_wifi_config_unlocked_modification_test">Unlocked config is modifiable in Settings</string>
+    <string name="device_owner_wifi_config_unlocked_modification_test_info">
+            Please press the button to ensure WiFi config lockdown is NOT in effect. Then go to
+            Settings &gt; WiFi and see if the CTSVerifier created WiFi configuration can be edited.
+            Please make sure you can connect to it. The test is successful if the config is editable
+            and can be connected to.
+    </string>
+    <string name="device_owner_wifi_config_locked_modification_test">Locked config is not modifiable in Settings</string>
+    <string name="device_owner_wifi_config_locked_modification_test_info">
+            Please press the button to ensure WiFi config lockdown is in effect. Then go to
+            Settings &gt; WiFi and see if the CTSVerifier created WiFi configuration can NOT be edited
+            or removed. The test is successful if the config is NOT modifiable.
+    </string>
+    <string name="device_owner_wifi_config_locked_connection_test">Locked config can be connected to</string>
+    <string name="device_owner_wifi_config_locked_connection_test_info">
+            Please press the button to ensure WiFi config lockdown is in effect. Then go to
+            Settings &gt; WiFi and see if the CTSVerifier created WiFi configuration can be connected
+            to manually. The test is successful if the connection can be established.
+    </string>
+    <string name="device_owner_wifi_config_unlocked_removal_test">Unlocked config can be forgotten in Settings</string>
+    <string name="device_owner_wifi_config_unlocked_removal_test_info">
+            Please press the button to ensure WiFi config lockdown is NOT in effect. Then go to
+            Settings &gt; WiFi and see if the CTSVerifier created WiFi configuration can be forgotten.
+            The test is successful if the config could be forgotten and is removed from the list of saved configs.
+    </string>
+    <string name="device_owner_disable_statusbar_test">Disable status bar</string>
+    <string name="device_owner_disable_statusbar_test_info">
+            Please press the below button to disable the status bar and verify that quick settings, notifications
+            and the assist gesture are no longer available.\n
+            Next, press the button to reenable the status bar and verify that quick settings, notification
+            and the assist gesture are available again.\n
+            Please mark the test accordingly.
+    </string>
+    <string name="device_owner_disable_statusbar_button">Disable status bar</string>
+    <string name="device_owner_reenable_statusbar_button">Reenable status bar</string>
+    <string name="device_owner_disable_keyguard_test">Disable keyguard</string>
+    <string name="device_owner_disable_keyguard_test_info">
+            Note that any device passwords that you might have set will be deleted during this test.\n
+            Please press the below button to disable the keyguard. Press the power button on your device to
+            switch off the screen. Then press the power button to switch the screen back on and verify that
+            no keyguard was shown.\n
+            Next, press the button to reenable the keyguard and repeat the above steps, this time verifying that
+            a keyguard was shown again.\n
+            Please mark the test accordingly.
+    </string>
+    <string name="device_owner_disable_keyguard_button">Disable keyguard</string>
+    <string name="device_owner_reenable_keyguard_button">Reenable keyguard</string>
+    <string name="device_profile_owner_permission_lockdown_test">Permissions lockdown</string>
+    <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>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
+            Please mark the test accordingly.
+    </string>
+    <string name="device_owner_permission_lockdown_test_info">
+        This test checks if the permissions state in settings UI is locked down according to the state set by the device owner.
+    </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
+        </b>
+        This test checks if the permissions state in settings UI is locked down correctly depending on the state set by the profile owner.
+    </string>
+    <string name="package_not_found">You must install %s (aka CtsPermissionApp).</string>
+    <string name="permission_allow">Grant</string>
+    <string name="permission_default">Let user decide</string>
+    <string name="permission_deny">Deny</string>
+    <string name="not_profile_owner">%s is not profile owner.</string>
+    <string name="not_device_owner">%s is not device owner.</string>
+    <string name="activity_not_found">No activity found to handle intent: %s</string>
+    <string name="open_settings_button_label">Open Application Settings</string>
+    <string name="finish_button_label">Finish</string>
+    <string name="device_owner_device_admin_visible">Device administrator settings</string>
+    <string name="device_owner_device_admin_visible_info">
+        Please press the Go button to open the Security page in Settings.
+        Navigate to Device administrators and confirm that:\n
+        \n
+        - \"CTS Verifier\" exists and is activated.\n
+        - \"CTS Verifier\" cannot be disabled.\n
+        \n
+        Use the Back button to return to this page.
+    </string>
+    <string name="device_owner_disallow_config_bt">Disallow configuring Bluetooth</string>
+    <string name="device_owner_disallow_config_bt_info">
+        Please press the Set restriction button to set the user restriction.
+        Then press Go to open the Bluetooth page in Settings.
+        Confirm that:\n
+        \n
+        - You cannot view Bluetooth devices in range.\n
+        - You cannot edit, add or remove any already paired devices.\n
+        \n
+        Use the Back button to return to this page.
+    </string>
+    <string name="device_owner_disallow_config_wifi">Disallow configuring WiFi</string>
+    <string name="device_owner_disallow_config_wifi_info">
+        Please press the Set restriction button to set the user restriction.
+        Then press Go to open the WiFi page in Settings.
+        Confirm that:\n
+        \n
+        - You cannot view WiFi networks in range.\n
+        - You cannot edit, add or remove any existing WiFi configs.\n
+        \n
+        Use the Back button to return to this page.
+    </string>
+    <string name="device_owner_user_restriction_set">Set restriction</string>
+    <string name="device_owner_settings_go">Go</string>
+
+    <string name="device_owner_vpn_connection">
+        Vpn connection has been established.\n
+        This is not as expected.\n
+        Mark this test as failed.\n
+    </string>
+    <string name="device_owner_vpn_connection_close_failed">
+        Established vpn connection cannot be closed.\n
+        This is not as expected.\n
+        Mark this test as failed.\n
+    </string>
+    <string name="device_owner_no_vpn_connection">
+        Cannot establish a VPN connection.\n
+        This was expected.\n
+        Mark this test as passed.\n
+    </string>
+    <string name="device_owner_vpn_connection_canceled">
+        Cannot establish a VPN connection.\n
+        Connection canceled by user.\n
+    </string>
+    <string name="device_owner_vpn_test">Check VPN</string>
+    <string name="device_owner_vpn_info_default">Vpn test message</string>
+
+    <string name="device_owner_disallow_config_vpn">Disallow configuring VPN</string>
+    <string name="device_owner_disallow_config_vpn_info">
+        Please press the Set VPN restriction button to set the VPN restriction.
+        Perform tests in order. Mark test as passed if both test cases pass\n\n
+        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
+        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 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>
@@ -1453,15 +1956,20 @@
     <string name="js_start_test_text">Start test</string>
     <string name="js_idle_instructions">Verify the behaviour of the JobScheduler API for when the device is in idle mode. Simply follow the on-screen instructions.</string>
     <string name="js_idle_description_1">Turn the screen off and then back on in order to begin.</string>
+    <string name="js_idle_continue_instruction">
+        Switch off screen and wait for it to turn on to continue.
+    </string>
     <string name="js_idle_item_idle_off">Idle job does not execute when device is not idle.</string>
     <string name="js_idle_item_idle_on">Idle job does execute when device is forced into idle.</string>
 
     <string name="js_charging_test">Charging Constraints</string>
     <string name="js_charging_instructions">Verify the behaviour of the JobScheduler API for when the device is on power and unplugged from power. Simply follow the on-screen instructions.</string>
-    <string name="js_charging_description_1">Unplug the device in order to begin.</string>
+    <string name="js_charging_description_1">Plug in the charger if it isn\'t already plugged in.</string>
     <string name="js_charging_off_test">Device not charging will not execute a job with a charging constraint.</string>
     <string name="js_charging_on_test">Device when charging will execute a job with a charging constraint.</string>
-    <string name="js_charging_description_2">After the above test has passed, plug the device back in to continue. If the above failed, you can simply fail this test.</string>
+    <string name="js_charging_description_2">After the above test has passed, remove the charger to continue. If the above failed, you can simply fail this test.</string>
+    <string name="js_charging_description_3">Device is plugged in. Please wait while it get\s into stable charging state.</string>
+    <string name="js_charging_description_4">There seems to be a problem with your charger. Pleasy try again.</string>
 
     <string name="js_connectivity_test">Connectivity Constraints</string>
     <string name="js_connectivity_instructions">Verify the behaviour of the JobScheduler API for when the device has no access to data connectivity. Simply follow the on-screen instructions.</string>
@@ -1506,7 +2014,6 @@
     Do you see the programs named \"Dummy Program\" and their descriptions
     "Dummy Program Description" in the EPG?
     </string>
-    <string name="tv_input_discover_test_yes">Yes</string>
 
     <string name="tv_parental_control_test">TV app parental controls test</string>
     <string name="tv_parental_control_test_info">
@@ -1560,6 +2067,59 @@
     The Spanish audio track should be selected.
     </string>
 
+    <string name="tv_time_shift_test">TV app time shift test</string>
+    <string name="tv_time_shift_test_info">
+    This test verifies that the TV app invokes proper time shift APIs in the framwork.
+    </string>
+    <string name="tv_time_shift_test_pause_resume">
+    Press the \"Launch TV app\" button. Verify that the playback control is available.
+    Pause the playback and then resume it.
+    </string>
+    <string name="tv_time_shift_test_verify_resume_after_pause">
+    The playback should resume after pause.
+    </string>
+    <string name="tv_time_shift_test_verify_position_tracking">
+    The playback position tracking should be activated.
+    </string>
+    <string name="tv_time_shift_test_speed_rate">
+    Press the \"Launch TV app\" button. Verify that the playback control is available.
+    Rewind the playback and in a few seconds fast-forward it.
+    </string>
+    <string name="tv_time_shift_test_verify_rewind">
+    The playback should rewind.
+    </string>
+    <string name="tv_time_shift_test_verify_fast_forward">
+    The playback should fast-forward.
+    </string>
+    <string name="tv_time_shift_test_seek">
+    Press the \"Launch TV app\" button. Verify that the playback control is available.
+    Seek to previous and then seek to next.
+    </string>
+    <string name="tv_time_shift_test_verify_seek_to_previous">
+    The playback position should be moved to the previous position.
+    </string>
+    <string name="tv_time_shift_test_verify_seek_to_next">
+    The playback position should be moved to the next position.
+    </string>
+
+    <string name="tv_app_link_test">TV app app-link test</string>
+    <string name="tv_app_link_test_info">
+    Verify that the bundled TV app supports linking to channel apps. If a TV input service provides
+    links for its specific channels, the TV app should show the links in a proper format.
+    </string>
+    <string name="tv_app_link_test_select_app_link">
+    Select the \"Launch TV app\" button, then check if you can see a menu with \"Cts App-Link Text\"
+    text in red background. If you see the link, select it to follow the link.
+    </string>
+    <string name="tv_app_link_test_verify_link_clicked">
+    The app-link must have been clicked and the activity should be changed correctly.
+    </string>
+    <string name="tv_input_link_test_verify_link_interface">
+    Do you see the app-link card similar to the image on the left?\n
+    1) You should see the poster art image, but the color may be different.\n
+    2) You should see the text \"Cts App-Link Text\".\n
+    </string>
+
     <string name="overlay_view_text">Overlay View Dummy Text</string>
     <string name="fake_rating">Fake</string>
 
@@ -1579,4 +2139,134 @@
     <string name="error_screen_pinning_did_not_start">Screen was not pinned.</string>
     <string name="error_screen_pinning_did_not_exit">Screen was not unpinned.</string>
     <string name="error_screen_pinning_couldnt_exit">Could not exit screen pinning through API.</string>
+
+    <!--  Audio Devices Notifcations Tests -->
+    <string name="audio_out_devices_notifications_test">Audio Output Devices Notifications Test</string>
+    <string name="audio_out_devices_notification_instructions">
+          Click the "Clear Messages" button then connect and disconnect a wired headset.
+          Note if the appropriate notification messages appear below.
+    </string>
+    <string name="audio_in_devices_notifications_test">Audio Input Devices Notifications Test</string>
+    <string name="audio_in_devices_notification_instructions">
+          Click the "Clear Messages" button then connect and disconnect a microphone or wired headset.
+          Note if the appropriate notification messages appear below.
+    </string>
+    <string name="audio_dev_notification_clearmsgs">Clear Messages</string>
+    <string name="audio_dev_notification_connectMsg">CONNECT DETECTED</string>
+    <string name="audio_dev_notification_disconnectMsg">DISCONNECT DETECTED</string>
+
+    <string name="audio_input_routingnotifications_test">Audio Input Routing Notifications Test</string>
+    <string name="audio_input_routingnotification_instructions">
+          Click on the "Record" button in the AudioRecord Routing Notifications section below to
+          start recording. Insert a wired headset or microphone. Observe a message acknowledging the
+          rerouting event below. Remove the wired headset and observe the new routing message.
+          Click on the "Stop" button to stop recording.\n
+    </string>
+    <string name="audio_output_routingnotifications_test">Audio Output Routing Notifications Test</string>
+    <string name="audio_output_routingnotification_instructions">
+          Click on the "Play" button in the AudioTrack Routing Notifications section below to
+          start (silent) playback. Insert a wired headset. Observe a message acknowledging the
+          rerouting event below. Remove the wired headset and observe the new routing message.
+          Click on the "Stop" button to stop playback.\n
+    </string>
+    <string name="audio_routingnotification_playBtn">Play</string>
+    <string name="audio_routingnotification_playStopBtn">Stop</string>
+    <string name="audio_routingnotification_recBtn">Record</string>
+    <string name="audio_routingnotification_recStopBtn">Stop</string>
+    <string name="audio_routingnotification_playHeader">AudioTrack Routing Notifications</string>
+    <string name="audio_routingnotification_recHeader">AudioRecord Routing Notifications</string>
+    <string name="audio_routingnotification_trackRoutingMsg">AudioTrack rerouting</string>
+    <string name="audio_routingnotification_recordRoutingMsg">AudioRecord rerouting</string>
+
+    <!-- Audio general text -->
+    <string name="audio_general_headset_port_exists">Does this device have a headset port?</string>
+    <string name="audio_general_headset_no">No</string>
+    <string name="audio_general_headset_yes">Yes</string>
+    <string name="audio_general_deficiency_found">WARNING: Some results show potential deficiencies on the system.
+    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>
+
+    <!-- Audio Loopback Latency Test -->
+    <string name="audio_loopback_test">Audio Loopback Latency Test</string>
+     <string name="audio_loopback_info">
+          This test requires the Loopback Plug. Please connect a Loopback Plug into the headset
+          connector, and proceed with the instructions on the screen.
+          The system will measure the input-output audio latency by injecting a pulse on the output,
+          and computing the distance between replicas of the pulse.
+          You can vary the Audio Level slider to ensure the pulse will feed back at adequate levels.
+          Repeat until a confidence level >= 0.6 is achieved.
+    </string>
+    <string name="audio_loopback_instructions">
+          Please connect a "Loopback Plug" and press "Loopback Plug Ready".
+    </string>
+    <string name="audio_loopback_plug_ready_btn">Loopback Plug Ready</string>
+    <string name="audio_loopback_instructions2">
+          Set the audio level to a suitable value, then press Test button.
+          It might require multiple tries until a confidence >= 0.6 is achieved.
+    </string>
+    <string name="audio_loopback_level_text">Audio Level</string>
+    <string name="audio_loopback_test_btn">Test</string>
+    <string name="audio_loopback_results_text">Results...</string>
+
+   <!-- Audio Frequency Line Test -->
+    <string name="audio_frequency_line_test">Audio Frequency Line Test</string>
+    <string name="audio_frequency_line_info">
+        The system will measure the frequency response of the left and right line outputs,
+        by feeding them back thru the microphone conection with the loopback jack.
+        This test requires the Loopback Plug. Please connect a Loopback Plug on the headset
+        connector, and proceed with the instructions on the screen.
+        </string>
+    <string name="audio_frequency_line_instructions">
+          Please connect a "Loopback Plug" and press "Loopback Plug Ready".
+    </string>
+    <string name="audio_frequency_line_plug_ready_btn">Loopback Plug Ready</string>
+
+    <string name="audio_frequency_line_test_btn">Test</string>
+    <string name="audio_frequency_line_results_text">Results...</string>
+
+    <!-- Audio Frequency Speaker Test -->
+    <string name="audio_frequency_speaker_test">Audio Frequency Speaker Test</string>
+    <string name="audio_frequency_speaker_info">
+        This test requires an external USB reference microphone. Please connect the USB microphone and proceed with the instructions on the screen.
+        The system will measure frequency response of the left and right speakers (if there are two speakers), or the response of the mono speaker twice.
+       </string>
+    <string name="audio_frequency_speaker_instructions">
+          Please connect an USB reference microphone and press "USB Reference microphone ready"
+    </string>
+    <string name="audio_frequency_speaker_usb_status">Waiting for USB microphone...</string>
+    <string name="audio_frequency_speaker_mic_ready_btn">USB Reference microphone ready</string>
+    <string name="audio_frequency_speaker_mic_ready_text">USB Audio device detected\n\nPlease set up Device Under test
+    in quiet room, and Microphone 20 cms perpendicular to center of screen, then press TEST</string>
+    <string name="audio_frequency_speaker_mic_not_ready_text">"No USB Audio device detected. Please reconnect."</string>
+    <string name="audio_frequency_speaker_test_btn">Test</string>
+    <string name="audio_frequency_speaker_results_text">Results...</string>
+
+    <!-- Audio Frequency Microphone Test -->
+    <string name="audio_frequency_mic_test">Audio Frequency Microphone Test</string>
+    <string name="audio_frequency_mic_info">
+        This test requires an external USB reference microphone and external speakers.
+        Please use the headphone connector to connect external speakers. Position the device 40 cms
+        from the speakers and proceed with the instructions on the screen.
+        The system will measure frequency response of the built in microphone.
+       </string>
+    <string name="audio_frequency_mic_instructions">
+          Please connect external speakers using the headphone connector. Please unplug any USB audio device (if any)
+    </string>
+    <string name="audio_frequency_mic_speakers_ready_btn">External speakers ready</string>
+    <string name="audio_frequency_mic_speakers_ready_status">...</string>
+    <string name="audio_frequency_mic_instructions2">
+          Please position the speakers 40 cms from the device under test and press TEST 1
+    </string>
+    <string name="audio_frequency_mic_test1_btn">Test 1</string>
+    <string name="audio_frequency_mic_usb_status">Waiting for USB microphone...</string>
+    <string name="audio_frequency_mic_connect_mic">Please Connect USB microphone, position it next to
+    the built in microphone in the device and press USB reference microphone</string>
+    <string name="audio_frequency_mic_mic_ready_btn">USB Reference microphone ready</string>
+    <string name="audio_frequency_mic_mic_ready_text">USB Audio device detected\n\nPlease set up Device Under test
+    in quiet room, and Microphone 20 cms perpendicular to center of screen, then press TEST</string>
+    <string name="audio_frequency_mic_mic_not_ready_text">"No USB Audio device detected. Please reconnect."</string>
+    <string name="audio_frequency_mic_test2_btn">Test 2</string>
+    <string name="audio_frequency_mic_results_text">Results...</string>
+
 </resources>
diff --git a/apps/CtsVerifier/res/xml/device_admin.xml b/apps/CtsVerifier/res/xml/device_admin.xml
deleted file mode 100644
index 49d705a..0000000
--- a/apps/CtsVerifier/res/xml/device_admin.xml
+++ /dev/null
@@ -1,25 +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.
--->
-
-<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
-    <uses-policies>
-        <limit-password />
-        <watch-login />
-        <reset-password />
-        <force-lock />
-        <wipe-data />
-        <expire-password />
-    </uses-policies>
-</device-admin>
diff --git a/apps/CtsVerifier/res/xml/device_admin_byod.xml b/apps/CtsVerifier/res/xml/device_admin_byod.xml
index 0408ce2..ce44794 100644
--- a/apps/CtsVerifier/res/xml/device_admin_byod.xml
+++ b/apps/CtsVerifier/res/xml/device_admin_byod.xml
@@ -19,6 +19,9 @@
     <uses-policies>
         <encrypted-storage />
         <wipe-data />
+        <reset-password />
+        <disable-keyguard-features />
+        <force-lock />
     </uses-policies>
 </device-admin>
 <!-- END_INCLUDE(meta_data) -->
diff --git a/apps/CtsVerifier/res/xml/mock_tv_input_service.xml b/apps/CtsVerifier/res/xml/mock_tv_input_service.xml
index 1a2cf86..d9cb867 100644
--- a/apps/CtsVerifier/res/xml/mock_tv_input_service.xml
+++ b/apps/CtsVerifier/res/xml/mock_tv_input_service.xml
@@ -15,5 +15,4 @@
 -->
 
 <tv-input xmlns:android="http://schemas.android.com/apk/res/android"
-    android:setupActivity="com.android.cts.verifier.tv.MockTvInputSetupActivity"
-    android:settingsActivity="com.android.cts.verifier.tv.MockTvInputSettingsActivity" />
+    android:setupActivity="com.android.cts.verifier.tv.MockTvInputSetupActivity" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml
new file mode 100644
index 0000000..9c6de77
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_median.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<config
+        linePaint.strokeWidth="3dp"
+        linePaint.color="#AA0000"
+        vertexPaint.color="#770000"
+        fillPaint.color="#00000000" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml
new file mode 100644
index 0000000..8fb236e
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_noise.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<config
+        linePaint.strokeWidth="2dp"
+        linePaint.color="#777777"
+        vertexPaint.color="777777"
+        fillPaint.color="#00000000" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml
new file mode 100644
index 0000000..9a6c29a
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_pass.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<config
+        linePaint.strokeWidth="2dp"
+        linePaint.color="#007700"
+        vertexPaint.color="#007700"
+        fillPaint.color="#00000000" />
diff --git a/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml
new file mode 100644
index 0000000..3f9ffc2
--- /dev/null
+++ b/apps/CtsVerifier/res/xml/ultrasound_line_formatter_trials.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<config
+        linePaint.strokeWidth="1dp"
+        linePaint.color="#AAAAAA"
+        vertexPaint.color="#777777"
+        fillPaint.color="#00000000" />
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
index 409b0db..3132219 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/AbstractTestListActivity.java
@@ -44,8 +44,13 @@
     }
 
     @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    protected final void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
+        handleActivityResult(requestCode, resultCode, data);
+    }
+
+    /** Override this in subclasses instead of onActivityResult */
+    protected void handleActivityResult(int requestCode, int resultCode, Intent data) {
         switch (requestCode) {
             case LAUNCH_TEST_REQUEST_CODE:
                 handleLaunchTestResult(resultCode, data);
@@ -66,7 +71,7 @@
         setContentView(R.layout.list_content);
     }
 
-    private void handleLaunchTestResult(int resultCode, Intent data) {
+    protected void handleLaunchTestResult(int resultCode, Intent data) {
         if (resultCode == RESULT_OK) {
             TestResult testResult = TestResult.fromActivityResult(resultCode, data);
             mAdapter.setTestResult(testResult);
@@ -75,8 +80,13 @@
 
     /** Launch the activity when its {@link ListView} item is clicked. */
     @Override
-    protected void onListItemClick(ListView listView, View view, int position, long id) {
+    protected final void onListItemClick(ListView listView, View view, int position, long id) {
         super.onListItemClick(listView, view, position, id);
+        handleItemClick(listView, view, position, id);
+    }
+
+    /** Override this in subclasses instead of onListItemClick */
+    protected void handleItemClick(ListView listView, View view, int position, long id) {
         Intent intent = getIntent(position);
         startActivityForResult(intent, LAUNCH_TEST_REQUEST_CODE);
     }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
new file mode 100644
index 0000000..167fd84
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/DialogTestListActivity.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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;
+
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.cts.verifier.R;
+
+/**
+ * Test list activity that supports showing dialogs with pass/fail buttons instead of
+ * starting new activities.
+ * In addition to that dialogs have a 'go' button that can be configured to launch an intent.
+ * Instructions are shown on top of the screen and a test preparation button is provided.
+ */
+public abstract class DialogTestListActivity extends PassFailButtons.TestListActivity {
+    private final String TAG = "DialogTestListActivity";
+    private final int mLayoutId;
+    private final int mTitleStringId;
+    private final int mInfoStringId;
+    private final int mInstructionsStringId;
+
+    protected Button mPrepareTestButton;
+
+    protected int mCurrentTestPosition;
+
+    protected DialogTestListActivity(int layoutId, int titleStringId, int infoStringId,
+            int instructionsStringId) {
+        mLayoutId = layoutId;
+        mTitleStringId = titleStringId;
+        mInfoStringId = infoStringId;
+        mInstructionsStringId = instructionsStringId;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(mLayoutId);
+        setInfoResources(mTitleStringId, mInfoStringId, -1);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+        setResult(RESULT_CANCELED);
+
+        ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+
+        setupTests(adapter);
+
+        adapter.registerDataSetObserver(new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                updatePassButton();
+            }
+        });
+
+        setTestListAdapter(adapter);
+
+        mCurrentTestPosition = 0;
+
+        TextView instructionTextView = (TextView)findViewById(R.id.test_instructions);
+        instructionTextView.setText(mInstructionsStringId);
+        mPrepareTestButton = (Button)findViewById(R.id.prepare_test_button);
+    }
+
+    /**
+     * Subclasses must add their tests items to the provided adapter(usually instances of
+     * {@link DialogTestListItem} or {@link DialogTestListItemWithIcon} but any class deriving from
+     * {@link TestListAdapter.TestListItem} will do).
+     * @param adapter The adapter to add test items to.
+     */
+    protected abstract void setupTests(ArrayTestListAdapter adapter);
+
+    public class DefaultTestCallback implements DialogTestListItem.TestCallback {
+        final private DialogTestListItem mTest;
+
+        public DefaultTestCallback(DialogTestListItem test) {
+            mTest = test;
+        }
+
+        @Override
+        public void onPass() {
+            clearRemainingState(mTest);
+            setTestResult(mTest, TestResult.TEST_RESULT_PASSED);
+        }
+
+        @Override
+        public void onFail() {
+            clearRemainingState(mTest);
+            setTestResult(mTest, TestResult.TEST_RESULT_FAILED);
+        }
+    }
+
+    public void showManualTestDialog(final DialogTestListItem test) {
+        showManualTestDialog(test, new DefaultTestCallback(test));
+    }
+
+    public void showManualTestDialog(final DialogTestListItem test,
+            final DialogTestListItem.TestCallback callback) {
+        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this)
+                .setIcon(android.R.drawable.ic_dialog_info)
+                .setTitle(mTitleStringId)
+                .setNeutralButton(R.string.go_button_text, null)
+                .setPositiveButton(R.string.pass_button_text, new AlertDialog.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        callback.onPass();
+                    }
+                })
+                .setNegativeButton(R.string.fail_button_text, new AlertDialog.OnClickListener() {
+                    @Override
+                    public void onClick(DialogInterface dialog, int which) {
+                        callback.onFail();
+                    }
+                });
+        View customView = test.getCustomView();
+        if (customView != null) {
+            dialogBuilder.setView(customView);
+        } else {
+            dialogBuilder.setMessage(test.getManualTestInstruction());
+        }
+        final AlertDialog dialog = dialogBuilder.show();
+        // Note: Setting the OnClickListener on the Dialog rather than the Builder, prevents the
+        // dialog being dismissed on onClick.
+        dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                if (!startTestIntent(test)) {
+                    dialog.dismiss();
+                }
+            }
+        });
+    }
+
+    @Override
+    protected void handleItemClick(ListView l, View v, int position, long id) {
+        TestListAdapter.TestListItem test = (TestListAdapter.TestListItem) getListAdapter()
+                .getItem(position);
+        if (test instanceof DialogTestListItem) {
+            mCurrentTestPosition = position;
+            ((DialogTestListItem)test).performTest(this);
+        } else {
+            try {
+                super.handleItemClick(l, v, position, id);
+            } catch (ActivityNotFoundException e) {
+                Log.d(TAG, "handleItemClick() threw exception: ", e);
+                setTestResult(test, TestResult.TEST_RESULT_FAILED);
+                showToast(R.string.test_failed_cannot_start_intent);
+            }
+        }
+    }
+
+
+    /**
+     * Start a test's manual intent
+     * @param test The test the manual intent of which is to be started.
+     * @return true if activity could be started successfully, false otherwise.
+     */
+    boolean startTestIntent(final DialogTestListItem test) {
+        final Intent intent = test.intent;
+        try {
+            startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            Log.w(TAG, "Cannot start activity.", e);
+            Toast.makeText(this, "Cannot start " + intent, Toast.LENGTH_LONG).show();
+            setTestResult(test, TestResult.TEST_RESULT_FAILED);
+            return false;
+        }
+        return true;
+    }
+
+    protected void clearRemainingState(final DialogTestListItem test) {
+        // do nothing, override in subclass if needed
+    }
+
+    protected void setTestResult(TestListAdapter.TestListItem test, int result) {
+        // Bundle result in an intent to feed into handleLaunchTestResult
+        Intent resultIntent = new Intent();
+        TestResult.addResultData(resultIntent, result, test.testName, /* testDetails */ null,
+                /* reportLog */ null);
+        handleLaunchTestResult(RESULT_OK, resultIntent);
+        getListView().smoothScrollToPosition(mCurrentTestPosition + 1);
+    }
+
+    protected void showToast(int messageId) {
+        String message = getString(messageId);
+        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
+    }
+
+    protected static class DialogTestListItem extends TestListAdapter.TestListItem {
+
+        public interface TestCallback {
+            void onPass();
+            void onFail();
+        }
+
+        private String mManualInstruction;
+
+        public DialogTestListItem(Context context, int nameResId, String testId) {
+            super(context.getString(nameResId), testId, null, null, null, null);
+        }
+
+        public DialogTestListItem(Context context, int nameResId, String testId,
+                int testInstructionResId, Intent testIntent) {
+            super(context.getString(nameResId), testId, testIntent, null, null, null);
+            mManualInstruction = context.getString(testInstructionResId);
+        }
+
+        public void performTest(DialogTestListActivity activity) {
+            activity.showManualTestDialog(this);
+        }
+
+        public String getManualTestInstruction() {
+            return mManualInstruction;
+        }
+
+        public Intent getManualTestIntent() {
+            return intent;
+        }
+
+        public View getCustomView() {
+            return null;
+        }
+
+        @Override
+        boolean isTest() {
+            return true;
+        }
+    }
+
+    protected static class DialogTestListItemWithIcon extends DialogTestListItem {
+
+        private final int mImageResId;
+        private final Context mContext;
+
+        public DialogTestListItemWithIcon(Context context, int nameResId, String testId,
+                int testInstructionResId, Intent testIntent, int imageResId) {
+            super(context, nameResId, testId, testInstructionResId, testIntent);
+            mContext = context;
+            mImageResId = imageResId;
+        }
+
+        @Override
+        public View getCustomView() {
+            LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+            View view = layoutInflater.inflate(R.layout.dialog_custom_view,
+                    null /* root */);
+            ((ImageView) view.findViewById(R.id.sample_icon)).setImageResource(mImageResId);
+            ((TextView) view.findViewById(R.id.message)).setText(getManualTestInstruction());
+            return view;
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
index 5a08558..2c3d35d 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/PassFailButtons.java
@@ -262,6 +262,10 @@
 
         @Override
         public ReportLog getReportLog() { return reportLog; }
+
+        public void updatePassButton() {
+            getPassButton().setEnabled(mAdapter.allTestsPassed());
+        }
     }
 
     private static <T extends android.app.Activity & PassFailActivity>
@@ -399,16 +403,14 @@
     private static void setTestResultAndFinish(android.app.Activity activity, String testId,
             String testDetails, ReportLog reportLog, View target) {
         boolean passed;
-        switch (target.getId()) {
-            case R.id.pass_button:
-                passed = true;
-                break;
-            case R.id.fail_button:
-                passed = false;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown id: " + target.getId());
+        if (target.getId() == R.id.pass_button) {
+            passed = true;
+        } else if (target.getId() == R.id.fail_button) {
+            passed = false;
+        } else {
+            throw new IllegalArgumentException("Unknown id: " + target.getId());
         }
+
         setTestResultAndFinishHelper(activity, testId, testDetails, passed, reportLog);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
index 8cfc6df..807e02a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListActivity.java
@@ -16,8 +16,13 @@
 
 package com.android.cts.verifier;
 
+import android.Manifest;
 import android.app.ListActivity;
 import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.PermissionInfo;
 import android.os.Bundle;
 import android.util.Log;
 import android.view.Menu;
@@ -31,6 +36,7 @@
 
 /** Top-level {@link ListActivity} for launching tests and managing results. */
 public class TestListActivity extends AbstractTestListActivity implements View.OnClickListener {
+    private static final int CTS_VERIFIER_PERMISSION_REQUEST = 1;
 
     private static final String TAG = TestListActivity.class.getSimpleName();
 
@@ -43,6 +49,38 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
+        try {
+            PackageManager pm = getPackageManager();
+            PackageInfo packageInfo = pm.getPackageInfo(
+                    getApplicationInfo().packageName, PackageManager.GET_PERMISSIONS);
+
+            if (packageInfo.requestedPermissions != null) {
+                for (String permission : packageInfo.requestedPermissions) {
+                    Log.v(TAG, "Checking permissions for: " + permission);
+                    try {
+                        PermissionInfo info = pm.getPermissionInfo(permission, 0);
+                        if ((info.protectionLevel & PermissionInfo.PROTECTION_DANGEROUS) == 0) {
+                            continue;
+                        }
+                    } catch (NameNotFoundException e) {
+                        Log.v(TAG, "Checking permissions for: " + permission + "not found");
+                        continue;
+                    }
+                    if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
+                        requestPermissions(packageInfo.requestedPermissions,
+                                CTS_VERIFIER_PERMISSION_REQUEST);
+                        return;
+                    }
+                }
+            }
+            createContinue();
+        } catch (NameNotFoundException e) {
+            Log.e(TAG, "Unable to load package's permissions", e);
+            Toast.makeText(this, R.string.runtime_permissions_error, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    private void createContinue() {
         if (!isTaskRoot()) {
             finish();
         }
@@ -63,6 +101,19 @@
     }
 
     @Override
+    public void onRequestPermissionsResult(
+            int requestCode, String permissions[], int[] grantResults) {
+        if (requestCode == CTS_VERIFIER_PERMISSION_REQUEST) {
+            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+                createContinue();
+                return;
+            }
+            Log.v(TAG, "Permission not granted.");
+            Toast.makeText(this, R.string.runtime_permissions_error, Toast.LENGTH_SHORT).show();
+        }
+    }
+
+    @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.test_list_menu, menu);
@@ -96,21 +147,16 @@
     }
 
     private boolean handleMenuItemSelected(int id) {
-        switch (id) {
-            case R.id.clear:
-                handleClearItemSelected();
-                return true;
-
-            case R.id.view:
-                handleViewItemSelected();
-                return true;
-
-            case R.id.export:
-                handleExportItemSelected();
-                return true;
-
-            default:
-                return false;
+        if (id == R.id.clear) {
+            handleClearItemSelected();
+        } else if (id == R.id.view) {
+            handleViewItemSelected();
+        } else if (id == R.id.export) {
+            handleExportItemSelected();
+        } else {
+            return false;
         }
+
+        return true;
     }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
index 2160902..ce092cc 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestListAdapter.java
@@ -141,7 +141,7 @@
             return new TestListItem(title, null, null, null, null, null);
         }
 
-        private TestListItem(String title, String testName, Intent intent,
+        protected TestListItem(String title, String testName, Intent intent,
                 String[] requiredFeatures, String[] excludedFeatures, String[] applicableFeatures) {
             this.title = title;
             this.testName = testName;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java b/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java
index d8a675c..c5d2d52 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TestResult.java
@@ -71,13 +71,18 @@
     private static Intent createResult(Activity activity, int testResult, String testName,
             String testDetails, ReportLog reportLog) {
         Intent data = new Intent(activity, activity.getClass());
-        data.putExtra(TEST_NAME, testName);
-        data.putExtra(TEST_RESULT, testResult);
-        data.putExtra(TEST_DETAILS, testDetails);
-        data.putExtra(TEST_METRICS, reportLog);
+        addResultData(data, testResult, testName, testDetails, reportLog);
         return data;
     }
 
+    public static void addResultData(Intent intent, int testResult, String testName,
+            String testDetails, ReportLog reportLog) {
+        intent.putExtra(TEST_NAME, testName);
+        intent.putExtra(TEST_RESULT, testResult);
+        intent.putExtra(TEST_DETAILS, testDetails);
+        intent.putExtra(TEST_METRICS, reportLog);
+    }
+
     /**
      * Convert the test activity's result into a {@link TestResult}. Only meant to be used by
      * {@link TestListActivity}.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/TimerProgressBar.java b/apps/CtsVerifier/src/com/android/cts/verifier/TimerProgressBar.java
new file mode 100644
index 0000000..4e0f61e
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/TimerProgressBar.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.AttributeSet;
+import android.widget.ProgressBar;
+
+/**
+ * Can be used to show time outs for events. A progress bar will be displayed to the user.
+ * On calling start, it will start filling up.
+ */
+public class TimerProgressBar extends ProgressBar {
+  public TimerProgressBar(Context context) {
+    super(context);
+    setHandler(context);
+  }
+
+  public TimerProgressBar(Context context, AttributeSet attrs) {
+    super(context, attrs);
+    setHandler(context);
+  }
+
+  public TimerProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
+    super(context, attrs, defStyleAttr);
+    setHandler(context);
+  }
+
+  @TargetApi(21)
+  public TimerProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+    super(context, attrs, defStyleAttr, defStyleRes);
+    setHandler(context);
+  }
+
+  private void setHandler(Context context) {
+    mHandler = new Handler(context.getMainLooper());
+  }
+
+  private Handler mHandler;
+  private TimerExpiredCallback mTimerExpiredCallback;
+  private long mStartTime;
+  private long mDuration;
+  private long mStepSize;
+  private boolean mForceComplete;
+
+  private Runnable mProgressCallback = new Runnable() {
+    @Override
+    public void run() {
+      if (mForceComplete) {
+        TimerProgressBar.this.setProgress(TimerProgressBar.this.getMax());
+        return;
+      }
+
+      long currentTime = SystemClock.elapsedRealtime();
+      int progress = (int) ((currentTime - mStartTime) / mStepSize);
+      progress = Math.min(progress, TimerProgressBar.this.getMax());
+      TimerProgressBar.this.setProgress(progress);
+
+      if (mStartTime + mDuration > currentTime) {
+        mHandler.postDelayed(this, mStepSize);
+      } else {
+        if (mTimerExpiredCallback != null) {
+          mTimerExpiredCallback.onTimerExpired();
+        }
+      }
+    }
+  };
+
+  public void start(long duration, long stepSize) {
+    start(duration, stepSize, null);
+  }
+
+  /**
+   * Start filling up the progress bar.
+   *
+   * @param duration Time in milliseconds the progress bar takes to fill up completely
+   * @param stepSize Time in milliseconds between consecutive updates to progress bar's progress
+   * @param callback Callback that should be executed after the progress bar is filled completely (i.e. timer expires)
+   */
+  public void start(long duration, long stepSize, TimerExpiredCallback callback) {
+    mDuration = duration;
+    mStepSize = stepSize;
+    mStartTime = SystemClock.elapsedRealtime();
+    mForceComplete = false;
+    mTimerExpiredCallback = callback;
+    this.setMax((int) (duration / stepSize));
+    this.setProgress(0);
+    mHandler.post(mProgressCallback);
+  }
+
+  /**
+   * Fill the progress bar completely. Timer expired callback won't be executed.
+   */
+  public void forceComplete() {
+    mForceComplete = true;
+  }
+
+  public interface TimerExpiredCallback {
+    void onTimerExpired();
+  }
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/DeviceAdminKeyguardDisabledFeaturesActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/admin/DeviceAdminKeyguardDisabledFeaturesActivity.java
new file mode 100644
index 0000000..2ad77f6
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/DeviceAdminKeyguardDisabledFeaturesActivity.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.verifier.admin;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.fingerprint.FingerprintManager;
+import android.provider.Settings;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.DialogTestListActivity;
+import com.android.cts.verifier.managedprovisioning.ByodHelperActivity;
+import com.android.cts.verifier.managedprovisioning.DeviceAdminTestReceiver;
+import com.android.cts.verifier.managedprovisioning.KeyguardDisabledFeaturesActivity;
+
+
+/**
+ * Tests for Device Admin keyguard disabled features.
+ */
+public class DeviceAdminKeyguardDisabledFeaturesActivity extends KeyguardDisabledFeaturesActivity {
+    @Override
+    protected int getKeyguardDisabledFeatures() {
+        return DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_ALL;
+    }
+
+    @Override
+    protected void setKeyguardDisabledFeatures() {
+        int flags = getKeyguardDisabledFeatures();
+        mDpm.setKeyguardDisabledFeatures(getAdminComponent(), flags);
+    }
+
+    @Override
+    protected String getTestIdPrefix() {
+        return "DeviceAdmin_";
+    }
+
+    @Override
+    protected void setupTests(ArrayTestListAdapter adapter) {
+        setupFingerprintTests(adapter);
+        setupDisableTrustAgentsTest(adapter);
+        adapter.add(new DialogTestListItem(this, R.string.device_admin_keyguard_disable_camera,
+                getTestIdPrefix()+"KeyguardDisableCamera",
+                R.string.device_admin_keyguard_disable_camera_instruction,
+                new Intent(ByodHelperActivity.ACTION_LOCKNOW)));
+
+        adapter.add(new DialogTestListItem(this, R.string.device_admin_disable_notifications,
+                "DeviceAdmin_DisableNotifications",
+                R.string.device_admin_disable_notifications_instruction,
+                new Intent(ByodHelperActivity.ACTION_NOTIFICATION_ON_LOCKSCREEN)));
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java
index 1591df3..ee24868 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/PolicySerializationTestActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.verifier.admin;
 
+import com.android.cts.verifier.managedprovisioning.DeviceAdminTestReceiver;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
@@ -73,7 +74,7 @@
         setPassFailButtonClickListeners();
 
         mDevicePolicyManager = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
-        mAdmin = TestDeviceAdminReceiver.getComponent(this);
+        mAdmin = DeviceAdminTestReceiver.getReceiverComponentName();
 
         mGeneratePolicyButton = findViewById(R.id.generate_policy_button);
         mGeneratePolicyButton.setOnClickListener(new OnClickListener() {
@@ -136,7 +137,7 @@
     private void applyPolicy() {
         Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
         intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
-                TestDeviceAdminReceiver.getComponent(this));
+                DeviceAdminTestReceiver.getReceiverComponentName());
         startActivityForResult(intent, ADD_DEVICE_ADMIN_REQUEST_CODE);
     }
 
@@ -152,7 +153,7 @@
 
     private void handleAddDeviceAdminResult(int resultCode, Intent data) {
         if (resultCode == RESULT_OK) {
-            ComponentName admin = TestDeviceAdminReceiver.getComponent(this);
+            ComponentName admin = DeviceAdminTestReceiver.getReceiverComponentName();
             for (PolicyItem<?> item : mPolicyItems) {
                 item.applyExpectedValue(mDevicePolicyManager, admin);
             }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/RedactedNotificationKeyguardDisabledFeaturesActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/admin/RedactedNotificationKeyguardDisabledFeaturesActivity.java
new file mode 100644
index 0000000..711fd8c
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/RedactedNotificationKeyguardDisabledFeaturesActivity.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.cts.verifier.admin;
+
+import android.app.admin.DevicePolicyManager;
+
+import android.content.Intent;
+
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.DialogTestListActivity;
+import com.android.cts.verifier.managedprovisioning.ByodHelperActivity;
+
+/**
+ * Tests for Device Admin keyguard redacted notification feature. This test is taken out from
+ * DeviceAdminKeyguardDisabledFeaturesActivity class, because KEYGUARD_DISABLE_SECURE_NOTIFICATIONS
+ * would mask KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS.
+ *  */
+
+public class RedactedNotificationKeyguardDisabledFeaturesActivity
+    extends DeviceAdminKeyguardDisabledFeaturesActivity {
+  @Override
+  protected int getKeyguardDisabledFeatures() {
+    return DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+  }
+
+  @Override
+  protected void setupTests(ArrayTestListAdapter adapter) {
+    adapter.add(new DialogTestListItem(this, R.string.device_admin_disable_unredacted_notifications,
+        "DeviceAdmin_DisableUnredactedNotifications",
+        R.string.device_admin_disable_unredacted_notifications_instruction,
+        new Intent(ByodHelperActivity.ACTION_NOTIFICATION_ON_LOCKSCREEN)));
+  }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/ScreenLockTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/admin/ScreenLockTestActivity.java
index 5520bb7..41217a6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/admin/ScreenLockTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/admin/ScreenLockTestActivity.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.verifier.admin;
 
+import com.android.cts.verifier.managedprovisioning.DeviceAdminTestReceiver;
 import com.android.cts.verifier.PassFailButtons;
 import com.android.cts.verifier.R;
 
@@ -72,7 +73,7 @@
     private void sendAddDeviceAdminIntent() {
         Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
         intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
-                TestDeviceAdminReceiver.getComponent(this));
+                DeviceAdminTestReceiver.getReceiverComponentName());
         startActivityForResult(intent, ADD_DEVICE_ADMIN_REQUEST_CODE);
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/admin/TestDeviceAdminReceiver.java b/apps/CtsVerifier/src/com/android/cts/verifier/admin/TestDeviceAdminReceiver.java
deleted file mode 100644
index 5ecb36d..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/admin/TestDeviceAdminReceiver.java
+++ /dev/null
@@ -1,28 +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.verifier.admin;
-
-import android.app.admin.DeviceAdminReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-
-public class TestDeviceAdminReceiver extends DeviceAdminReceiver {
-
-    public static ComponentName getComponent(Context context) {
-        return new ComponentName(context, TestDeviceAdminReceiver.class);
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioBandSpecs.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioBandSpecs.java
new file mode 100644
index 0000000..9af4af1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioBandSpecs.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 com.android.cts.verifier.audio;
+
+public class AudioBandSpecs {
+    double mFreqStart;
+    double mFreqStop;
+    double mRippleStartTop;
+    double mRippleStartBottom;
+
+    double mRippleStopTop;
+    double mRippleStopBottom;
+
+    double mOffset;
+
+    public AudioBandSpecs(double fStart, double fStop, double startTop, double startBottom,
+            double stopTop, double stopBottom) {
+        initFreq(fStart, fStop);
+        initRipple(startTop, startBottom, stopTop, stopBottom);
+        setOffset(0);
+    }
+
+    public void initRipple(double startTop, double startBottom, double stopTop, double stopBottom) {
+        mRippleStartTop = startTop;
+        mRippleStartBottom = startBottom;
+        mRippleStopTop = stopTop;
+        mRippleStopBottom = stopBottom;
+        // note: top should be >= bottom, but no check is done here.
+    }
+
+    public void initFreq(double fStart, double fStop) {
+        mFreqStart = fStart;
+        mFreqStop = fStop;
+    }
+
+    public void setOffset(double offset) {
+        mOffset = offset;
+    }
+
+    /**
+     * Check if the given point is in bounds in this band.
+     */
+    public boolean isInBounds(double freq, double value) {
+        if (freq < mFreqStart || freq > mFreqStop) {
+            return false;
+        }
+
+        double d = mFreqStop - mFreqStart;
+        if (d <= 0) {
+            return false;
+        }
+
+        double e = freq - mFreqStart;
+        double vTop = (e / d) * (mRippleStopTop - mRippleStartTop) + mRippleStartTop + mOffset;
+        if (value > vTop) {
+            return false;
+        }
+
+        double vBottom = (e / d) * (mRippleStopBottom - mRippleStartBottom) + mRippleStartBottom
+                + mOffset;
+
+        if (value < vBottom) {
+            return false;
+        }
+        return true;
+    }
+
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(String.format("Freq %.1f - %.1f |", mFreqStart, mFreqStop));
+        sb.append(String.format("start [%.1f : %.1f] |", mRippleStartTop, mRippleStartBottom));
+        sb.append(String.format("stop  [%.1f : %.1f] |", mRippleStopTop, mRippleStopBottom));
+        sb.append(String.format("offset %.1f", mOffset));
+        return sb.toString();
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
new file mode 100644
index 0000000..edb3bf0
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyLineActivity.java
@@ -0,0 +1,697 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.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 Device roundtrip latency by using a loopback plug.
+ */
+public class AudioFrequencyLineActivity extends PassFailButtons.Activity implements Runnable,
+    AudioRecord.OnRecordPositionUpdateListener {
+    private static final String TAG = "AudioFrequencyLineActivity";
+
+    static final int TEST_STARTED = 900;
+    static final int TEST_ENDED = 901;
+    static final int TEST_MESSAGE = 902;
+    static final double MIN_ENERGY_BAND_1 = -20.0;
+    static final double MIN_FRACTION_POINTS_IN_BAND = 0.3;
+
+    OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+    Context mContext;
+
+    Button mHeadsetPortYes;
+    Button mHeadsetPortNo;
+
+    Button mLoopbackPlugReady;
+    LinearLayout mLinearLayout;
+    Button mTestButton;
+    TextView mResultText;
+    ProgressBar mProgressBar;
+    //recording
+    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 = 1024;
+    private final int mSamplingRate = 48000;
+    private final int mSelectedRecordSource = MediaRecorder.AudioSource.VOICE_RECOGNITION;
+    private final int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;
+    private final int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+    private volatile Thread mRecordThread;
+    private boolean mRecordThreadShutdown = false;
+
+    PipeShort mPipe = new PipeShort(65536);
+    SoundPlayerObject mSPlayer;
+
+    private DspBufferComplex mC;
+    private DspBufferDouble mData;
+
+    private DspWindow mWindow;
+    private DspFftServer mFftServer;
+    private VectorAverage mFreqAverageMain = new VectorAverage();
+
+    private VectorAverage mFreqAverage0 = new VectorAverage();
+    private VectorAverage mFreqAverage1 = new VectorAverage();
+
+    private int mCurrentTest = -1;
+    int mBands = 4;
+    AudioBandSpecs[] bandSpecsArray = new AudioBandSpecs[mBands];
+
+    int mMaxLevel;
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.audio_frequency_line_plug_ready_btn:
+                    Log.i(TAG, "audio loopback plug ready");
+                    //enable all the other views.
+                    enableLayout(true);
+                    break;
+                case R.id.audio_frequency_line_test_btn:
+                    Log.i(TAG, "audio loopback test");
+                    startAudioTest();
+                    break;
+                case R.id.audio_general_headset_yes:
+                    Log.i(TAG, "User confirms Headset Port existence");
+                    mLoopbackPlugReady.setEnabled(true);
+                    recordHeasetPortFound(true);
+                    mHeadsetPortYes.setEnabled(false);
+                    mHeadsetPortNo.setEnabled(false);
+                    break;
+                case R.id.audio_general_headset_no:
+                    Log.i(TAG, "User denies Headset Port existence");
+                    recordHeasetPortFound(false);
+                    getPassButton().setEnabled(true);
+                    mHeadsetPortYes.setEnabled(false);
+                    mHeadsetPortNo.setEnabled(false);
+                    break;
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_frequency_line_activity);
+
+        mContext = this;
+
+        mHeadsetPortYes = (Button)findViewById(R.id.audio_general_headset_yes);
+        mHeadsetPortYes.setOnClickListener(mBtnClickListener);
+        mHeadsetPortNo = (Button)findViewById(R.id.audio_general_headset_no);
+        mHeadsetPortNo.setOnClickListener(mBtnClickListener);
+
+        mLoopbackPlugReady = (Button)findViewById(R.id.audio_frequency_line_plug_ready_btn);
+        mLoopbackPlugReady.setOnClickListener(mBtnClickListener);
+        mLoopbackPlugReady.setEnabled(false);
+        mLinearLayout = (LinearLayout)findViewById(R.id.audio_frequency_line_layout);
+        mTestButton = (Button)findViewById(R.id.audio_frequency_line_test_btn);
+        mTestButton.setOnClickListener(mBtnClickListener);
+        mResultText = (TextView)findViewById(R.id.audio_frequency_line_results_text);
+        mProgressBar = (ProgressBar)findViewById(R.id.audio_frequency_line_progress_bar);
+        showWait(false);
+        enableLayout(false);         //disabled all content
+
+        mSPlayer = new SoundPlayerObject();
+        mSPlayer.setSoundWithResId(getApplicationContext(), R.raw.stereo_mono_white_noise_48);
+        mSPlayer.setBalance(0.5f);
+
+        //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_line_test,
+                R.string.audio_frequency_line_info, -1);
+
+        //Init bands
+        bandSpecsArray[0] = new AudioBandSpecs(
+                50, 500,        /* frequency start,stop */
+                -20.0, -50,     /* start top,bottom value */
+                4.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 */);
+    }
+
+    /**
+     * enable test ui elements
+     */
+    private void enableLayout(boolean enable) {
+        for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
+            View view = mLinearLayout.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);
+    }
+
+    /**
+     *  Start the loopback audio test
+     */
+    private void startAudioTest() {
+        if (mTestThread != null && !mTestThread.isAlive()) {
+            mTestThread = null; //kill it.
+        }
+
+        if (mTestThread == null) {
+            Log.v(TAG,"Executing test Thread");
+            mTestThread = new Thread(mPlayRunnable);
+            getPassButton().setEnabled(false);
+            if (!mSPlayer.isAlive())
+                mSPlayer.start();
+            mTestThread.start();
+        } else {
+            Log.v(TAG,"test Thread already running.");
+        }
+    }
+
+    Thread mTestThread;
+    Runnable mPlayRunnable = new Runnable() {
+        public void run() {
+            Message msg = Message.obtain();
+            msg.what = TEST_STARTED;
+            mMessageHandler.sendMessage(msg);
+            setMaxLevel();
+
+            sendMessage("Testing Left Capture");
+            mCurrentTest = 0;
+            mFreqAverage0.reset();
+            mSPlayer.setBalance(0.0f);
+            play();
+
+            sendMessage("Testing Right Capture");
+            mCurrentTest = 1;
+            mFreqAverage1.reset();
+            mSPlayer.setBalance(1.0f);
+            play();
+
+            mCurrentTest = -1;
+            sendMessage("Testing Completed");
+
+            Message msg2 = Message.obtain();
+            msg2.what = TEST_ENDED;
+            mMessageHandler.sendMessage(msg2);
+        }
+
+        private void play() {
+            startRecording();
+            mSPlayer.play(true);
+
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            mSPlayer.play(false);
+            stopRecording();
+        }
+
+        private void sendMessage(String str) {
+            Message msg = Message.obtain();
+            msg.what = TEST_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);
+                computeResults();
+                break;
+            case TEST_MESSAGE:
+                String str = (String)msg.obj;
+                if (str != null) {
+                    mResultText.setText(str);
+                }
+                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 test results
+     */
+    private void computeResults() {
+        Results resultsLeft = new Results("Left");
+        computeResultsForVector(mFreqAverage0, resultsLeft);
+        Results resultsRight = new Results("Right");
+        computeResultsForVector(mFreqAverage1, resultsRight);
+        if (resultsLeft.testAll() && resultsRight.testAll()) {
+            String strSuccess = getResources().getString(R.string.audio_general_test_passed);
+            appendResultsToScreen(strSuccess);
+        } else {
+            String strFailed = getResources().getString(R.string.audio_general_test_failed);
+            appendResultsToScreen(strFailed + "\n");
+            String strWarning = getResources().getString(R.string.audio_general_deficiency_found);
+            appendResultsToScreen(strWarning);
+        }
+        getPassButton().setEnabled(true); //Everybody passes! (for now...)
+    }
+
+    private void computeResultsForVector(VectorAverage freqAverage,Results results) {
+
+        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 > bandSpecsArray[currentBand].mFreqStop) {
+                    currentBand++;
+                    if (currentBand >= mBands)
+                        break;
+                }
+
+                if (freq >= bandSpecsArray[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++) {
+                bandSpecsArray[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 >  bandSpecsArray[currentBand].mFreqStop) {
+                    currentBand++;
+                    if (currentBand >= mBands)
+                        break;
+                }
+
+                if (freq >= bandSpecsArray[currentBand].mFreqStart) {
+                    double value = results.mValuesLog[i];
+                    if (bandSpecsArray[currentBand].isInBounds(freq, value)) {
+                        results.mInBoundPointsPerBand[currentBand]++;
+                    }
+                }
+            }
+
+            appendResultsToScreen(results.toString());
+            //store results
+            recordTestResults(results);
+        } else {
+            appendResultsToScreen("Failed testing channel " + results.mLabel);
+        }
+    }
+
+    //append results
+    private void appendResultsToScreen(String str) {
+        String currentText = mResultText.getText().toString();
+        mResultText.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(AudioFrequencyLineActivity.this);
+            mRecordThread.setName("FrequencyAnalyzerThread");
+            mRecordThreadShutdown = false;
+        }
+        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;
+        mRecordThreadShutdown = true;
+        if (zeThread != null) {
+            zeThread.interrupt();
+            try {
+                zeThread.join();
+            } catch(InterruptedException e) {
+                Log.v(TAG,"Error shutting down recording thread " + e);
+                //we don't really care about this error, just logging it.
+            }
+        }
+         // 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.
+            double maxval = Math.pow(2, 15);
+            int clipcount = 0;
+            double cliplevel = (maxval-10) / maxval;
+            double sum = 0;
+            double maxabs = 0;
+            int i;
+            int index = 0;
+
+            for (i = 0; i < samplesNeeded; i++) {
+                double value = mAudioShortArray2[i] / maxval;
+                double valueabs = Math.abs(value);
+
+                if (valueabs > maxabs) {
+                    maxabs = valueabs;
+                }
+
+                if (valueabs > cliplevel) {
+                    clipcount++;
+                }
+
+                sum += value * value;
+                //fft stuff
+                if (index < mBlockSizeSamples) {
+                    mData.mData[index] = value;
+                }
+                index++;
+            }
+
+            //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!
+
+            switch(mCurrentTest) {
+                case 0:
+                    mFreqAverage0.setData(halfMagnitude, false);
+                    break;
+                case 1:
+                    mFreqAverage1.setData(halfMagnitude, false);
+                    break;
+            }
+        }
+    }
+
+    public void onMarkerReached(AudioRecord track) {
+    }
+
+    // ---------------------------------------------------------
+    // Implementation of Runnable for the audio recording + playback
+    // --------------------
+    public void run() {
+        int nSamplesRead = 0;
+
+        Thread thisThread = Thread.currentThread();
+        while (mRecordThread == thisThread && !mRecordThreadShutdown) {
+            // read from native recorder
+            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/AudioFrequencyMicActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
new file mode 100644
index 0000000..03d84e1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencyMicActivity.java
@@ -0,0 +1,883 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 using external speakers and USB reference microphone.
+ */
+public class AudioFrequencyMicActivity extends PassFailButtons.Activity implements Runnable,
+    AudioRecord.OnRecordPositionUpdateListener {
+    private static final String TAG = "AudioFrequencyMicActivity";
+
+    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 mHeadsetPortYes;
+    Button mHeadsetPortNo;
+
+    Button mSpeakersReady;              //user signal to have connected external speakers
+    Button mTest1Button;                //execute test 1
+    Button mUsbMicReady;          //user signal to have connected USB Microphone
+    Button mTest2Button;                 //user to start test
+    String mUsbDevicesInfo;             //usb device info for report
+    LinearLayout mLayoutTest1;
+    LinearLayout mLayoutTest2a;
+    LinearLayout mLayoutTest2b;
+
+    TextView mSpeakerReadyText;
+    TextView mTest2Result;
+    TextView mUsbStatusText;
+    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 = 1024;
+    private final int mSamplingRate = 48000;
+    private final int mSelectedRecordSource = MediaRecorder.AudioSource.VOICE_RECOGNITION;
+    private final int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;
+    private final int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+    private Thread mRecordThread;
+
+    PipeShort mPipe = new PipeShort(65536);
+    SoundPlayerObject mSPlayer;
+
+    private DspBufferComplex mC;
+    private DspBufferDouble mData;
+
+    private DspWindow mWindow;
+    private DspFftServer mFftServer;
+    private VectorAverage mFreqAverageMain = new VectorAverage();
+
+    private VectorAverage mFreqAverageBase = new VectorAverage();
+    private VectorAverage mFreqAverageBuiltIn = new VectorAverage();
+    private VectorAverage mFreqAverageReference = new VectorAverage();
+
+    private int mCurrentTest = -1;
+    int mBands = 4;
+    AudioBandSpecs[] bandSpecsArray = new AudioBandSpecs[mBands];
+    AudioBandSpecs[] baseBandSpecsArray = new AudioBandSpecs[mBands];
+
+    int mMaxLevel;
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+            case R.id.audio_frequency_mic_speakers_ready_btn:
+                testSpeakersReady();
+                break;
+            case R.id.audio_frequency_mic_test1_btn:
+                startTest1();
+                break;
+            case R.id.audio_frequency_mic_mic_ready_btn:
+                testUSB();
+                break;
+            case R.id.audio_frequency_mic_test2_btn:
+                startTest2();
+                break;
+            case R.id.audio_general_headset_yes:
+                Log.i(TAG, "User confirms Headset Port existence");
+                mSpeakersReady.setEnabled(true);
+                recordHeasetPortFound(true);
+                mHeadsetPortYes.setEnabled(false);
+                mHeadsetPortNo.setEnabled(false);
+                break;
+            case R.id.audio_general_headset_no:
+                Log.i(TAG, "User denies Headset Port existence");
+                recordHeasetPortFound(false);
+                getPassButton().setEnabled(true);
+                mHeadsetPortYes.setEnabled(false);
+                mHeadsetPortNo.setEnabled(false);
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_frequency_mic_activity);
+        mContext = this;
+
+        mHeadsetPortYes = (Button)findViewById(R.id.audio_general_headset_yes);
+        mHeadsetPortYes.setOnClickListener(mBtnClickListener);
+        mHeadsetPortNo = (Button)findViewById(R.id.audio_general_headset_no);
+        mHeadsetPortNo.setOnClickListener(mBtnClickListener);
+
+        mSpeakerReadyText = (TextView) findViewById(R.id.audio_frequency_mic_speakers_ready_status);
+
+        mSpeakersReady  = (Button)findViewById(R.id.audio_frequency_mic_speakers_ready_btn);
+        mSpeakersReady.setOnClickListener(mBtnClickListener);
+        mSpeakersReady.setEnabled(false);
+        mTest1Button = (Button)findViewById(R.id.audio_frequency_mic_test1_btn);
+        mTest1Button.setOnClickListener(mBtnClickListener);
+        mTest1Result = (TextView)findViewById(R.id.audio_frequency_mic_results1_text);
+        mLayoutTest1 = (LinearLayout) findViewById(R.id.audio_frequency_mic_layout_test1);
+        mLayoutTest2a = (LinearLayout) findViewById(R.id.audio_frequency_mic_layout_test2a);
+        mLayoutTest2b = (LinearLayout) findViewById(R.id.audio_frequency_mic_layout_test2b);
+        mUsbMicReady = (Button)findViewById(R.id.audio_frequency_mic_mic_ready_btn);
+        mUsbMicReady.setOnClickListener(mBtnClickListener);
+
+        mUsbStatusText = (TextView)findViewById(R.id.audio_frequency_mic_usb_status);
+        mTest2Button = (Button)findViewById(R.id.audio_frequency_mic_test2_btn);
+        mTest2Button.setOnClickListener(mBtnClickListener);
+        mTest2Result = (TextView)findViewById(R.id.audio_frequency_mic_results_text);
+        mProgressBar = (ProgressBar)findViewById(R.id.audio_frequency_mic_progress_bar);
+        showWait(false);
+        enableLayout(mLayoutTest1, false);
+        enableLayout(mLayoutTest2a, false);
+        enableLayout(mLayoutTest2b, false);
+
+        mSPlayer = new SoundPlayerObject();
+        mSPlayer.setSoundWithResId(getApplicationContext(), R.raw.stereo_mono_white_noise_48);
+        mSPlayer.setBalance(0.5f);
+
+        //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_mic_test,
+                R.string.audio_frequency_mic_info, -1);
+
+        //Init bands for BuiltIn/Reference test
+        bandSpecsArray[0] = new AudioBandSpecs(
+                50, 500,        /* frequency start,stop */
+                -20.0, -50,     /* start top,bottom value */
+                4.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 */);
+
+        //Init base bands for silence
+        baseBandSpecsArray[0] = new AudioBandSpecs(
+                50, 500,        /* frequency start,stop */
+                40.0, -50.0,     /* start top,bottom value */
+                5.0, -50.0       /* stop top,bottom value */);
+
+        baseBandSpecsArray[1] = new AudioBandSpecs(
+                500,4000,       /* frequency start,stop */
+                5.0, -50.0,      /* start top,bottom value */
+                5.0, -50.0        /* stop top,bottom value */);
+
+        baseBandSpecsArray[2] = new AudioBandSpecs(
+                4000, 12000,    /* frequency start,stop */
+                5.0, -50.0,      /* start top,bottom value */
+                5.0, -50.0       /* stop top,bottom value */);
+
+        baseBandSpecsArray[3] = new AudioBandSpecs(
+                12000, 20000,   /* frequency start,stop */
+                5.0, -50.0,      /* start top,bottom value */
+                5.0, -50.0      /* stop top,bottom value */);
+
+    }
+
+    /**
+     * 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);
+    }
+
+    /**
+     *  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);
+            //getPassButton().setEnabled(false);
+            if (!mSPlayer.isAlive())
+                mSPlayer.start();
+            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);
+
+            setMinLevel();
+            sendMessage("Testing Background Environment");
+            mCurrentTest = 0;
+            mSPlayer.setBalance(0.5f);
+            mFreqAverageBase.reset();
+            play();
+
+            setMaxLevel();
+            sendMessage("Testing Built in Microphone");
+            mCurrentTest = 1;
+            mFreqAverageBuiltIn.reset();
+            mSPlayer.setBalance(0.5f);
+            play();
+
+            mCurrentTest = -1;
+            sendMessage("Testing Completed");
+
+            Message msg2 = Message.obtain();
+            msg2.what = TEST1_ENDED;
+            mMessageHandler.sendMessage(msg2);
+        }
+
+        private void play() {
+            startRecording();
+            mSPlayer.play(true);
+
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+                //restore interrupted status
+                Thread.currentThread().interrupt();
+            }
+
+            mSPlayer.play(false);
+            stopRecording();
+        }
+
+        private void sendMessage(String str) {
+            Message msg = Message.obtain();
+            msg.what = TEST1_MESSAGE;
+            msg.obj = str;
+            mMessageHandler.sendMessage(msg);
+        }
+    };
+
+    /**
+     *  Start the loopback audio test
+     */
+    private void startTest2() {
+        if (mTestThread != null && !mTestThread.isAlive()) {
+            mTestThread = null; //kill it.
+        }
+
+        if (mTestThread == null) {
+            Log.v(TAG,"Executing test2 Thread");
+            mTestThread = new Thread(mTest2Runnable);
+            //getPassButton().setEnabled(false);
+            if (!mSPlayer.isAlive())
+                mSPlayer.start();
+            mTestThread.start();
+        } else {
+            Log.v(TAG,"test Thread already running.");
+        }
+    }
+
+    Runnable mTest2Runnable = new Runnable() {
+        public void run() {
+            Message msg = Message.obtain();
+            msg.what = TEST_STARTED;
+            mMessageHandler.sendMessage(msg);
+
+            sendMessage("Testing Reference USB Microphone");
+            mCurrentTest = 2;
+            mFreqAverageReference.reset();
+            mSPlayer.setBalance(0.5f);
+            play();
+
+            mCurrentTest = -1;
+            sendMessage("Testing Completed");
+
+            Message msg2 = Message.obtain();
+            msg2.what = TEST_ENDED;
+            mMessageHandler.sendMessage(msg2);
+        }
+
+        private void play() {
+            startRecording();
+            mSPlayer.play(true);
+
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+                //restore interrupted status
+                Thread.currentThread().interrupt();
+            }
+
+            mSPlayer.play(false);
+            stopRecording();
+        }
+
+        private void sendMessage(String str) {
+            Message msg = Message.obtain();
+            msg.what = TEST_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: {
+                    String str = (String)msg.obj;
+                    if (str != null) {
+                        mTest2Result.setText(str);
+                    }
+                }
+                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 boolean mIsBaseMeasurement = false;
+        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") +
+                    (mIsBaseMeasurement ? " (Base Meas.)" : "") + "\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 (mIsBaseMeasurement && mAverageEnergyPerBand[1] <= MAX_ENERGY_BAND_1_BASE) {
+                return true;
+            } else 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 resultsBase = new Results("Base");
+        if (computeResultsForVector(mFreqAverageBase, resultsBase, true, baseBandSpecsArray)) {
+            appendResultsToScreen(resultsBase.toString(), mTest1Result);
+            recordTestResults(resultsBase);
+        }
+
+        Results resultsBuiltIn = new Results("BuiltIn");
+        if (computeResultsForVector(mFreqAverageBuiltIn, resultsBuiltIn, false, bandSpecsArray)) {
+            appendResultsToScreen(resultsBuiltIn.toString(), mTest1Result);
+            recordTestResults(resultsBuiltIn);
+        }
+
+        //tell user to connect USB Microphone
+        appendResultsToScreen("\n\n" +
+                getResources().getText(R.string.audio_frequency_mic_connect_mic), mTest1Result);
+        enableLayout(mLayoutTest2a, true);
+    }
+
+    /**
+     * compute test results
+     */
+    private void computeTest2Results() {
+        Results resultsReference = new Results("Reference");
+        if (computeResultsForVector(mFreqAverageReference, resultsReference,
+                false, bandSpecsArray)) {
+            appendResultsToScreen(resultsReference.toString(),mTest2Result);
+            recordTestResults(resultsReference);
+            getPassButton().setEnabled(true);
+        }
+    }
+
+    private boolean computeResultsForVector(VectorAverage freqAverage, Results results,
+            boolean isBase, AudioBandSpecs[] bandSpecs) {
+
+        results.mIsBaseMeasurement = isBase;
+        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(AudioFrequencyMicActivity.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!
+
+            switch(mCurrentTest) {
+                case 0:
+                    mFreqAverageBase.setData(halfMagnitude, false);
+                    break;
+                case 1:
+                    mFreqAverageBuiltIn.setData(halfMagnitude, false);
+                    break;
+                case 2:
+                    mFreqAverageReference.setData(halfMagnitude, false);
+                    break;
+            }
+        }
+    }
+
+    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);
+            }
+        }
+    }
+
+    private void testSpeakersReady() {
+        boolean isUsbConnected =
+                UsbMicrophoneTester.getIsMicrophoneConnected(getApplicationContext());
+        if (isUsbConnected) {
+            mSpeakerReadyText.setText(" USB device detected, please remove it");
+            enableLayout(mLayoutTest1, false);
+            //fail
+        } else {
+            mSpeakerReadyText.setText(" No USB device detected. OK");
+            enableLayout(mLayoutTest1, true);
+        }
+    }
+
+    private void testUSB() {
+        boolean isConnected = UsbMicrophoneTester.getIsMicrophoneConnected(getApplicationContext());
+        mUsbDevicesInfo = UsbMicrophoneTester.getUSBDeviceListString(getApplicationContext());
+
+        if (isConnected) {
+            mUsbStatusText.setText(
+                    getResources().getText(R.string.audio_frequency_mic_mic_ready_text));
+            enableLayout(mLayoutTest2b, true);
+        } else {
+            mUsbStatusText.setText(
+                    getResources().getText(R.string.audio_frequency_mic_mic_not_ready_text));
+            enableLayout(mLayoutTest2b, false);
+        }
+    }
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
new file mode 100644
index 0000000..ba7b86d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioFrequencySpeakerActivity.java
@@ -0,0 +1,739 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 Device roundtrip latency by using a loopback plug.
+ */
+public class AudioFrequencySpeakerActivity extends PassFailButtons.Activity implements Runnable,
+    AudioRecord.OnRecordPositionUpdateListener {
+    private static final String TAG = "AudioFrequencySpeakerActivity";
+
+    static final int TEST_STARTED = 900;
+    static final int TEST_ENDED = 901;
+    static final int TEST_MESSAGE = 902;
+    static final double MIN_ENERGY_BAND_1 = -50.0;          //dB Full Scale
+    static final double MAX_ENERGY_BAND_1_BASE = -60.0;     //dB Full Scale
+    static final double MIN_FRACTION_POINTS_IN_BAND = 0.3;
+
+    final OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+    Context mContext;
+
+    Button mLoopbackPlugReady;          //user signal to have connected USB Microphone
+    Button mTestButton;                 //user to start test
+    String mUsbDevicesInfo;             //usb device info for report
+    LinearLayout mLinearLayout;
+    TextView mResultText;
+    TextView mUsbStatusText;
+    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 = 1024;
+    private final int mSamplingRate = 48000;
+    private final int mSelectedRecordSource = MediaRecorder.AudioSource.VOICE_RECOGNITION;
+    private final int mChannelConfig = AudioFormat.CHANNEL_IN_MONO;
+    private final int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+    private Thread mRecordThread;
+    private boolean mRecordThreadShutdown = false;
+
+    PipeShort mPipe = new PipeShort(65536);
+    SoundPlayerObject mSPlayer;
+
+    private DspBufferComplex mC;
+    private DspBufferDouble mData;
+
+    private DspWindow mWindow;
+    private DspFftServer mFftServer;
+    private VectorAverage mFreqAverageMain = new VectorAverage();
+
+    private VectorAverage mFreqAverageBase = new VectorAverage();
+    private VectorAverage mFreqAverageLeft = new VectorAverage();
+    private VectorAverage mFreqAverageRight = new VectorAverage();
+
+    private int mCurrentTest = -1;
+    int mBands = 4;
+    AudioBandSpecs[] bandSpecsArray = new AudioBandSpecs[mBands];
+    AudioBandSpecs[] baseBandSpecsArray = new AudioBandSpecs[mBands];
+
+    int mMaxLevel;
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+            case R.id.audio_frequency_speaker_mic_ready_btn:
+                testUSB();
+                break;
+            case R.id.audio_frequency_speaker_test_btn:
+                startAudioTest();
+                break;
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_frequency_speaker_activity);
+
+        mContext = this;
+
+        mLoopbackPlugReady = (Button)findViewById(R.id.audio_frequency_speaker_mic_ready_btn);
+        mLoopbackPlugReady.setOnClickListener(mBtnClickListener);
+        mLinearLayout = (LinearLayout)findViewById(R.id.audio_frequency_speaker_layout);
+        mUsbStatusText = (TextView)findViewById(R.id.audio_frequency_speaker_usb_status);
+        mTestButton = (Button)findViewById(R.id.audio_frequency_speaker_test_btn);
+        mTestButton.setOnClickListener(mBtnClickListener);
+        mResultText = (TextView)findViewById(R.id.audio_frequency_speaker_results_text);
+        mProgressBar = (ProgressBar)findViewById(R.id.audio_frequency_speaker_progress_bar);
+        showWait(false);
+        enableLayout(false);         //disabled all content
+
+        mSPlayer = new SoundPlayerObject();
+        mSPlayer.setSoundWithResId(getApplicationContext(), R.raw.stereo_mono_white_noise_48);
+        mSPlayer.setBalance(0.5f);
+
+        //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_speaker_test,
+                R.string.audio_frequency_speaker_info, -1);
+
+        //Init bands for Left/Right test
+        bandSpecsArray[0] = new AudioBandSpecs(
+                50, 500,        /* frequency start,stop */
+                -20.0, -50,     /* start top,bottom value */
+                4.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 */);
+
+        //Init base bands for silence
+        baseBandSpecsArray[0] = new AudioBandSpecs(
+                50, 500,        /* frequency start,stop */
+                40.0, -50.0,     /* start top,bottom value */
+                5.0, -50.0       /* stop top,bottom value */);
+
+        baseBandSpecsArray[1] = new AudioBandSpecs(
+                500,4000,       /* frequency start,stop */
+                5.0, -50.0,      /* start top,bottom value */
+                5.0, -50.0        /* stop top,bottom value */);
+
+        baseBandSpecsArray[2] = new AudioBandSpecs(
+                4000, 12000,    /* frequency start,stop */
+                5.0, -50.0,      /* start top,bottom value */
+                5.0, -50.0       /* stop top,bottom value */);
+
+        baseBandSpecsArray[3] = new AudioBandSpecs(
+                12000, 20000,   /* frequency start,stop */
+                5.0, -50.0,      /* start top,bottom value */
+                5.0, -50.0      /* stop top,bottom value */);
+
+    }
+
+    /**
+     * enable test ui elements
+     */
+    private void enableLayout(boolean enable) {
+        for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
+            View view = mLinearLayout.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);
+    }
+
+    /**
+     *  Start the loopback audio test
+     */
+    private void startAudioTest() {
+        if (mTestThread != null && !mTestThread.isAlive()) {
+            mTestThread = null; //kill it.
+        }
+
+        if (mTestThread == null) {
+            Log.v(TAG,"Executing test Thread");
+            mTestThread = new Thread(mPlayRunnable);
+            getPassButton().setEnabled(false);
+            if (!mSPlayer.isAlive())
+                mSPlayer.start();
+            mTestThread.start();
+        } else {
+            Log.v(TAG,"test Thread already running.");
+        }
+    }
+
+    Thread mTestThread;
+    Runnable mPlayRunnable = new Runnable() {
+        public void run() {
+            Message msg = Message.obtain();
+            msg.what = TEST_STARTED;
+            mMessageHandler.sendMessage(msg);
+
+            setMinLevel();
+            sendMessage("Testing Background Environment");
+            mCurrentTest = 0;
+            mSPlayer.setBalance(0.5f);
+            mFreqAverageBase.reset();
+            play();
+
+            setMaxLevel();
+            sendMessage("Testing Left Capture");
+            mCurrentTest = 1;
+            mFreqAverageLeft.reset();
+            mSPlayer.setBalance(0.0f);
+            play();
+
+            sendMessage("Testing Right Capture");
+            mCurrentTest = 2;
+            mFreqAverageRight.reset();
+            mSPlayer.setBalance(1.0f);
+            play();
+
+            mCurrentTest = -1;
+            sendMessage("Testing Completed");
+
+            Message msg2 = Message.obtain();
+            msg2.what = TEST_ENDED;
+            mMessageHandler.sendMessage(msg2);
+        }
+
+        private void play() {
+            startRecording();
+            mSPlayer.play(true);
+
+            try {
+                Thread.sleep(2000);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            mSPlayer.play(false);
+            stopRecording();
+        }
+
+        private void sendMessage(String str) {
+            Message msg = Message.obtain();
+            msg.what = TEST_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);
+                computeResults();
+                break;
+            case TEST_MESSAGE:
+                String str = (String)msg.obj;
+                if (str != null) {
+                    mResultText.setText(str);
+                }
+                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 boolean mIsBaseMeasurement = false;
+        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") +
+                    (mIsBaseMeasurement ? " (Base Meas.)" : "") + "\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 (mIsBaseMeasurement && mAverageEnergyPerBand[1] <= MAX_ENERGY_BAND_1_BASE) {
+                return true;
+            } else 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 test results
+     */
+    private void computeResults() {
+
+        Results resultsBase = new Results("Base");
+        computeResultsForVector(mFreqAverageBase, resultsBase, true, baseBandSpecsArray);
+        Results resultsLeft = new Results("Left");
+        computeResultsForVector(mFreqAverageLeft, resultsLeft, false, bandSpecsArray);
+        Results resultsRight = new Results("Right");
+        computeResultsForVector(mFreqAverageRight, resultsRight, false, bandSpecsArray);
+        if (resultsLeft.testAll() && resultsRight.testAll() && resultsBase.testAll()) {
+            //enable button
+            String strSuccess = getResources().getString(R.string.audio_general_test_passed);
+            appendResultsToScreen(strSuccess);
+        } else {
+            String strFailed = getResources().getString(R.string.audio_general_test_failed);
+            appendResultsToScreen(strFailed + "\n");
+            String strWarning = getResources().getString(R.string.audio_general_deficiency_found);
+            appendResultsToScreen(strWarning);
+        }
+        getPassButton().setEnabled(true); //Everybody passes! (for now...)
+    }
+
+    private void computeResultsForVector(VectorAverage freqAverage,Results results, boolean isBase,
+            AudioBandSpecs[] bandSpecs) {
+
+        results.mIsBaseMeasurement = isBase;
+        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]++;
+                    }
+                }
+            }
+
+            appendResultsToScreen(results.toString());
+            //store results
+            recordTestResults(results);
+        } else {
+            appendResultsToScreen("Failed testing channel " + results.mLabel);
+        }
+    }
+
+    //append results
+    private void appendResultsToScreen(String str) {
+        String currentText = mResultText.getText().toString();
+        mResultText.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 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(AudioFrequencySpeakerActivity.this);
+            mRecordThread.setName("FrequencyAnalyzerThread");
+            mRecordThreadShutdown = false;
+        }
+        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;
+        mRecordThreadShutdown = true;
+        if (zeThread != null) {
+            zeThread.interrupt();
+            try {
+                zeThread.join();
+            } catch(InterruptedException e) {
+                Log.v(TAG,"Error shutting down recording thread " + e);
+                //we don't really care about this error, just logging it.
+            }
+        }
+         // 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.
+            double maxval = Math.pow(2, 15);
+            int clipcount = 0;
+            double cliplevel = (maxval-10) / maxval;
+            double sum = 0;
+            double maxabs = 0;
+            int i;
+            int index = 0;
+
+            for (i = 0; i < samplesNeeded; i++) {
+                double value = mAudioShortArray2[i] / maxval;
+                double valueabs = Math.abs(value);
+
+                if (valueabs > maxabs) {
+                    maxabs = valueabs;
+                }
+
+                if (valueabs > cliplevel) {
+                    clipcount++;
+                }
+
+                sum += value * value;
+                //fft stuff
+                if (index < mBlockSizeSamples) {
+                    mData.mData[index] = value;
+                }
+                index++;
+            }
+
+            //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!
+
+            switch(mCurrentTest) {
+                case 0:
+                    mFreqAverageBase.setData(halfMagnitude, false);
+                    break;
+                case 1:
+                    mFreqAverageLeft.setData(halfMagnitude, false);
+                    break;
+                case 2:
+                    mFreqAverageRight.setData(halfMagnitude, false);
+                    break;
+            }
+        }
+    }
+
+    public void onMarkerReached(AudioRecord track) {
+    }
+
+    // ---------------------------------------------------------
+    // Implementation of Runnable for the audio recording + playback
+    // --------------------
+    public void run() {
+        int nSamplesRead = 0;
+
+        Thread thisThread = Thread.currentThread();
+        while (mRecordThread == thisThread && !mRecordThreadShutdown) {
+            // read from native recorder
+            nSamplesRead = mRecorder.read(mAudioShortArray, 0, mMinRecordBufferSizeInSamples);
+            if (nSamplesRead > 0) {
+                mPipe.write(mAudioShortArray, 0, nSamplesRead);
+            }
+        }
+    }
+
+    private void testUSB() {
+        boolean isConnected = UsbMicrophoneTester.getIsMicrophoneConnected(getApplicationContext());
+        mUsbDevicesInfo = UsbMicrophoneTester.getUSBDeviceListString(getApplicationContext());
+
+        if (isConnected) {
+            mUsbStatusText.setText(
+                    getResources().getText(R.string.audio_frequency_speaker_mic_ready_text));
+            enableLayout(true);
+        } else {
+            mUsbStatusText.setText(
+                    getResources().getText(R.string.audio_frequency_speaker_mic_not_ready_text));
+            enableLayout(false);
+        }
+    }
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputDeviceNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputDeviceNotificationsActivity.java
new file mode 100644
index 0000000..e253635
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputDeviceNotificationsActivity.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.R;
+
+import android.content.Context;
+
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+
+import android.os.Bundle;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Tests Audio Device Connection events for output by prompting the user to insert/remove a
+ * wired headset (or microphone) and noting the presence (or absence) of notifications.
+ */
+public class AudioInputDeviceNotificationsActivity extends HeadsetHonorSystemActivity {
+    Context mContext;
+
+    TextView mConnectView;
+    TextView mDisconnectView;
+    Button mClearMsgsBtn;
+
+    private class TestAudioDeviceCallback extends AudioDeviceCallback {
+        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+            if (addedDevices.length != 0) {
+                mConnectView.setText(
+                    mContext.getResources().getString(R.string.audio_dev_notification_connectMsg));
+            }
+        }
+
+        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+            if (removedDevices.length != 0) {
+                mDisconnectView.setText(
+                    mContext.getResources().getString(
+                        R.string.audio_dev_notification_disconnectMsg));
+            }
+        }
+    }
+
+    @Override
+    protected void enableTestButtons(boolean enabled) {
+        // Nothing to do.
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_dev_notify);
+
+        mContext = this;
+
+        mConnectView = (TextView)findViewById(R.id.audio_dev_notification_connect_msg);
+        mDisconnectView = (TextView)findViewById(R.id.audio_dev_notification_disconnect_msg);
+
+        ((TextView)findViewById(R.id.info_text)).setText(mContext.getResources().getString(
+                R.string.audio_in_devices_notification_instructions));
+
+        mClearMsgsBtn = (Button)findViewById(R.id.audio_dev_notification_connect_clearmsgs_btn);
+        mClearMsgsBtn.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                mConnectView.setText("");
+                mDisconnectView.setText("");
+            }
+        });
+
+        AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
+        audioManager.registerAudioDeviceCallback(new TestAudioDeviceCallback(), null);
+
+        // "Honor System" buttons
+        super.setup();
+
+        setPassFailButtonClickListeners();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.java
new file mode 100644
index 0000000..eefa9e4
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioInputRoutingNotificationsActivity.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.cts.verifier.audio;
+
+import com.android.cts.verifier.R;
+
+import android.content.Context;
+
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+
+import android.os.Bundle;
+import android.os.Handler;
+
+import android.util.Log;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Tests AudioRecord (re)Routing messages.
+ */
+public class AudioInputRoutingNotificationsActivity extends HeadsetHonorSystemActivity {
+    private static final String TAG = "AudioInputRoutingNotificationsActivity";
+
+    Button recordBtn;
+    Button stopBtn;
+
+    Context mContext;
+
+    int mNumRecordNotifications = 0;
+
+    OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+
+    TrivialRecorder mAudioRecorder = new TrivialRecorder();
+
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.audio_routingnotification_recordBtn:
+                    mAudioRecorder.start();
+                    break;
+
+                case R.id.audio_routingnotification_recordStopBtn:
+                    mAudioRecorder.stop();
+                    break;
+            }
+        }
+    }
+
+    private class AudioRecordRoutingChangeListener implements AudioRecord.OnRoutingChangedListener {
+        public void onRoutingChanged(AudioRecord audioRecord) {
+            mNumRecordNotifications++;
+            TextView textView =
+                    (TextView)findViewById(R.id.audio_routingnotification_audioRecord_change);
+            String msg = mContext.getResources().getString(
+                    R.string.audio_routingnotification_recordRoutingMsg);
+            AudioDeviceInfo routedDevice = audioRecord.getRoutedDevice();
+            CharSequence deviceName = routedDevice != null ? routedDevice.getProductName() : "none";
+            int deviceType = routedDevice != null ? routedDevice.getType() : -1;
+            textView.setText(msg + " - " +
+                             deviceName + " [0x" + Integer.toHexString(deviceType) + "]" +
+                             " - " + mNumRecordNotifications);
+        }
+    }
+
+    protected void enableTestButtons(boolean enabled) {
+        recordBtn.setEnabled(enabled);
+        stopBtn.setEnabled(enabled);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_input_routingnotifications_test);
+
+        Button btn;
+        recordBtn = (Button)findViewById(R.id.audio_routingnotification_recordBtn);
+        recordBtn.setOnClickListener(mBtnClickListener);
+        stopBtn = (Button)findViewById(R.id.audio_routingnotification_recordStopBtn);
+        stopBtn.setOnClickListener(mBtnClickListener);
+
+        mContext = this;
+
+        AudioRecord audioRecord = mAudioRecorder.getAudioRecord();
+        audioRecord.addOnRoutingChangedListener(
+            new AudioRecordRoutingChangeListener(), new Handler());
+
+        // "Honor System" buttons
+        super.setup();
+
+        setPassFailButtonClickListeners();
+    }
+
+    @Override
+    public void onBackPressed () {
+        mAudioRecorder.shutDown();
+        super.onBackPressed();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java
new file mode 100644
index 0000000..fbec57a
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioLoopbackActivity.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+import android.content.Context;
+
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+
+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 Device roundtrip latency by using a loopback plug.
+ */
+public class AudioLoopbackActivity extends PassFailButtons.Activity {
+    private static final String TAG = "AudioLoopbackActivity";
+
+    public static final int BYTES_PER_FRAME = 2;
+
+    NativeAudioThread nativeAudioThread = null;
+
+    private int mSamplingRate = 44100;
+    private int mMinBufferSizeInFrames = 0;
+    private static final double CONFIDENCE_THRESHOLD = 0.6;
+    private Correlation mCorrelation = new Correlation();
+
+    OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+    Context mContext;
+
+    Button mHeadsetPortYes;
+    Button mHeadsetPortNo;
+
+    Button mLoopbackPlugReady;
+    TextView mAudioLevelText;
+    SeekBar mAudioLevelSeekbar;
+    LinearLayout mLinearLayout;
+    Button mTestButton;
+    TextView mResultText;
+    ProgressBar mProgressBar;
+
+    int mMaxLevel;
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.audio_loopback_plug_ready_btn:
+                    Log.i(TAG, "audio loopback plug ready");
+                    //enable all the other views.
+                    enableLayout(true);
+                    break;
+                case R.id.audio_loopback_test_btn:
+                    Log.i(TAG, "audio loopback test");
+                    startAudioTest();
+                    break;
+                case R.id.audio_general_headset_yes:
+                    Log.i(TAG, "User confirms Headset Port existence");
+                    mLoopbackPlugReady.setEnabled(true);
+                    recordHeasetPortFound(true);
+                    mHeadsetPortYes.setEnabled(false);
+                    mHeadsetPortNo.setEnabled(false);
+                    break;
+                case R.id.audio_general_headset_no:
+                    Log.i(TAG, "User denies Headset Port existence");
+                    recordHeasetPortFound(false);
+                    getPassButton().setEnabled(true);
+                    mHeadsetPortYes.setEnabled(false);
+                    mHeadsetPortNo.setEnabled(false);
+                    break;
+            }
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_loopback_activity);
+
+        mContext = this;
+
+        mHeadsetPortYes = (Button)findViewById(R.id.audio_general_headset_yes);
+        mHeadsetPortYes.setOnClickListener(mBtnClickListener);
+        mHeadsetPortNo = (Button)findViewById(R.id.audio_general_headset_no);
+        mHeadsetPortNo.setOnClickListener(mBtnClickListener);
+
+        mLoopbackPlugReady = (Button)findViewById(R.id.audio_loopback_plug_ready_btn);
+        mLoopbackPlugReady.setOnClickListener(mBtnClickListener);
+        mLoopbackPlugReady.setEnabled(false);
+        mLinearLayout = (LinearLayout)findViewById(R.id.audio_loopback_layout);
+        mAudioLevelText = (TextView)findViewById(R.id.audio_loopback_level_text);
+        mAudioLevelSeekbar = (SeekBar)findViewById(R.id.audio_loopback_level_seekbar);
+        mTestButton =(Button)findViewById(R.id.audio_loopback_test_btn);
+        mTestButton.setOnClickListener(mBtnClickListener);
+        mResultText = (TextView)findViewById(R.id.audio_loopback_results_text);
+        mProgressBar = (ProgressBar)findViewById(R.id.audio_loopback_progress_bar);
+        showWait(false);
+
+        enableLayout(false);         //disabled all content
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        mMaxLevel = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
+        mAudioLevelSeekbar.setMax(mMaxLevel);
+        am.setStreamVolume(AudioManager.STREAM_MUSIC, (int)(0.7 * mMaxLevel), 0);
+        refreshLevel();
+
+        mAudioLevelSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+            @Override
+            public void onStopTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onStartTrackingTouch(SeekBar seekBar) {
+            }
+
+            @Override
+            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+
+                AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+                am.setStreamVolume(AudioManager.STREAM_MUSIC,
+                        progress, 0);
+                refreshLevel();
+                Log.i(TAG,"Changed stream volume to: " + progress);
+            }
+        });
+
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+        setInfoResources(R.string.audio_loopback_test, R.string.audio_loopback_info, -1);
+    }
+
+    /**
+     * refresh Audio Level seekbar and text
+     */
+    private void refreshLevel() {
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+
+        int currentLevel = am.getStreamVolume(AudioManager.STREAM_MUSIC);
+        mAudioLevelSeekbar.setProgress(currentLevel);
+
+        String levelText = String.format("%s: %d/%d",
+                getResources().getString(R.string.audio_loopback_level_text),
+                currentLevel, mMaxLevel);
+        mAudioLevelText.setText(levelText);
+    }
+
+    /**
+     * enable test ui elements
+     */
+    private void enableLayout(boolean enable) {
+        for (int i = 0; i<mLinearLayout.getChildCount(); i++) {
+            View view = mLinearLayout.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) ;
+        }
+    }
+
+    /**
+     *  Start the loopback audio test
+     */
+    private void startAudioTest() {
+        getPassButton().setEnabled(false);
+
+        //get system defaults for sampling rate, buffers.
+        AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+        String value = am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER);
+        mMinBufferSizeInFrames = Integer.parseInt(value);
+
+        int minBufferSizeInBytes = BYTES_PER_FRAME * mMinBufferSizeInFrames;
+
+        mSamplingRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
+
+        Log.i(TAG, String.format("startAudioTest sr:%d , buffer:%d frames",
+                mSamplingRate, mMinBufferSizeInFrames));
+
+        nativeAudioThread = new NativeAudioThread();
+        if (nativeAudioThread != null) {
+            nativeAudioThread.setMessageHandler(mMessageHandler);
+            nativeAudioThread.mSessionId = 0;
+            nativeAudioThread.setParams(mSamplingRate,
+                    minBufferSizeInBytes,
+                    minBufferSizeInBytes,
+                    0x03 /*voice recognition*/);
+            nativeAudioThread.start();
+
+            try {
+                Thread.sleep(200);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+            nativeAudioThread.runTest();
+
+        }
+    }
+
+    /**
+     * handler for messages from audio thread
+     */
+    private Handler mMessageHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            super.handleMessage(msg);
+            switch(msg.what) {
+                case NativeAudioThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED:
+                    Log.v(TAG,"got message native rec started!!");
+                    showWait(true);
+                    mResultText.setText("Test Running...");
+                    break;
+                case NativeAudioThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR:
+                    Log.v(TAG,"got message native rec can't start!!");
+                    showWait(false);
+                    mResultText.setText("Test Error.");
+                    break;
+                case NativeAudioThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE:
+                case NativeAudioThread.NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS:
+                    if (nativeAudioThread != null) {
+                        Log.v(TAG,"Finished recording.");
+                        double [] waveData = nativeAudioThread.getWaveData();
+                        mCorrelation.computeCorrelation(waveData, mSamplingRate);
+                        mResultText.setText(String.format(
+                                "Test Finished\nLatency:%.2f ms\nConfidence: %.2f",
+                                mCorrelation.mEstimatedLatencyMs,
+                                mCorrelation.mEstimatedLatencyConfidence));
+
+                        recordTestResults();
+                        if (mCorrelation.mEstimatedLatencyConfidence >= CONFIDENCE_THRESHOLD) {
+                            getPassButton().setEnabled(true);
+                        }
+
+                        //close
+                        if (nativeAudioThread != null) {
+                            nativeAudioThread.isRunning = false;
+                            try {
+                                nativeAudioThread.finish();
+                                nativeAudioThread.join();
+                            } catch (InterruptedException e) {
+                                e.printStackTrace();
+                            }
+                            nativeAudioThread = null;
+                        }
+                        showWait(false);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    };
+
+    /**
+     * Store test results in log
+     */
+    private void recordTestResults() {
+
+        getReportLog().addValue(
+                "Estimated Latency",
+                mCorrelation.mEstimatedLatencyMs,
+                ResultType.LOWER_BETTER,
+                ResultUnit.MS);
+
+        getReportLog().addValue(
+                "Confidence",
+                mCorrelation.mEstimatedLatencyConfidence,
+                ResultType.HIGHER_BETTER,
+                ResultUnit.NONE);
+
+        int audioLevel = mAudioLevelSeekbar.getProgress();
+        getReportLog().addValue(
+                "Audio Level",
+                audioLevel,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        getReportLog().addValue(
+                "Frames Buffer Size",
+                mMinBufferSizeInFrames,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+
+        getReportLog().addValue(
+                "Sampling Rate",
+                mSamplingRate,
+                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);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputDeviceNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputDeviceNotificationsActivity.java
new file mode 100644
index 0000000..ad8ba68
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputDeviceNotificationsActivity.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.R;
+
+import android.content.Context;
+
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+
+import android.os.Bundle;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Tests Audio Device Connection events for output devices by prompting the user to
+ * insert/remove a wired headset and noting the presence (or absence) of notifications.
+ */
+public class AudioOutputDeviceNotificationsActivity extends HeadsetHonorSystemActivity {
+    Context mContext;
+
+    TextView mConnectView;
+    TextView mDisconnectView;
+    Button mClearMsgsBtn;
+
+    private class TestAudioDeviceCallback extends AudioDeviceCallback {
+        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+            if (addedDevices.length != 0) {
+                mConnectView.setText(
+                    mContext.getResources().getString(R.string.audio_dev_notification_connectMsg));
+            }
+        }
+
+        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+            if (removedDevices.length != 0) {
+                mDisconnectView.setText(
+                    mContext.getResources().getString(
+                        R.string.audio_dev_notification_disconnectMsg));
+            }
+        }
+    }
+
+    @Override
+    protected void enableTestButtons(boolean enabled) {
+        // Nothing to do.
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_dev_notify);
+
+        mContext = this;
+
+        mConnectView = (TextView)findViewById(R.id.audio_dev_notification_connect_msg);
+        mDisconnectView = (TextView)findViewById(R.id.audio_dev_notification_disconnect_msg);
+
+        ((TextView)findViewById(R.id.info_text)).setText(mContext.getResources().getString(
+                R.string.audio_out_devices_notification_instructions));
+
+        mClearMsgsBtn = (Button)findViewById(R.id.audio_dev_notification_connect_clearmsgs_btn);
+        mClearMsgsBtn.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View v) {
+                mConnectView.setText("");
+                mDisconnectView.setText("");
+            }
+        });
+
+        AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
+        audioManager.registerAudioDeviceCallback(new TestAudioDeviceCallback(), null);
+
+        // "Honor System" buttons
+        super.setup();
+
+        setPassFailButtonClickListeners();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.java
new file mode 100644
index 0000000..a6d8846
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioOutputRoutingNotificationsActivity.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.cts.verifier.audio;
+
+import com.android.cts.verifier.R;
+
+import android.content.Context;
+
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+
+import android.os.Bundle;
+import android.os.Handler;
+
+import android.util.Log;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Tests AudioTrack and AudioRecord (re)Routing messages.
+ */
+public class AudioOutputRoutingNotificationsActivity extends HeadsetHonorSystemActivity {
+    private static final String TAG = "AudioOutputRoutingNotificationsActivity";
+
+    Context mContext;
+
+    Button playBtn;
+    Button stopBtn;
+
+    private OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+
+    int mNumTrackNotifications = 0;
+
+    TrivialPlayer mAudioPlayer = new TrivialPlayer();
+
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.audio_routingnotification_playBtn:
+                    mAudioPlayer.start();
+                    break;
+
+                case R.id.audio_routingnotification_playStopBtn:
+                    mAudioPlayer.stop();
+                    break;
+            }
+        }
+    }
+
+    private class AudioTrackRoutingChangeListener implements AudioTrack.OnRoutingChangedListener {
+        public void onRoutingChanged(AudioTrack audioTrack) {
+            mNumTrackNotifications++;
+            TextView textView =
+                (TextView)findViewById(R.id.audio_routingnotification_audioTrack_change);
+            String msg = mContext.getResources().getString(
+                    R.string.audio_routingnotification_trackRoutingMsg);
+            AudioDeviceInfo routedDevice = audioTrack.getRoutedDevice();
+            CharSequence deviceName = routedDevice != null ? routedDevice.getProductName() : "none";
+            int deviceType = routedDevice != null ? routedDevice.getType() : -1;
+            textView.setText(msg + " - " +
+                             deviceName + " [0x" + Integer.toHexString(deviceType) + "]" +
+                             " - " + mNumTrackNotifications);
+        }
+    }
+
+    @Override
+    protected void enableTestButtons(boolean enabled) {
+        playBtn.setEnabled(enabled);
+        stopBtn.setEnabled(enabled);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.audio_output_routingnotifications_test);
+
+        mContext = this;
+
+        playBtn = (Button)findViewById(R.id.audio_routingnotification_playBtn);
+        playBtn.setOnClickListener(mBtnClickListener);
+        stopBtn = (Button)findViewById(R.id.audio_routingnotification_playStopBtn);
+        stopBtn.setOnClickListener(mBtnClickListener);
+
+        AudioTrack audioTrack = mAudioPlayer.getAudioTrack();
+        audioTrack.addOnRoutingChangedListener(
+            new AudioTrackRoutingChangeListener(), new Handler());
+
+        // "Honor System" buttons
+        super.setup();
+
+        setPassFailButtonClickListeners();
+    }
+
+    @Override
+    public void onBackPressed () {
+        mAudioPlayer.shutDown();
+        super.onBackPressed();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioRecordHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioRecordHelper.java
new file mode 100644
index 0000000..80dd250
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/AudioRecordHelper.java
@@ -0,0 +1,144 @@
+package com.android.cts.verifier.audio;
+
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+import android.media.AudioTrack;
+import android.media.MediaRecorder;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+/**
+ * A wrapper on AudioRecord class.
+ */
+public class AudioRecordHelper {
+
+  private static final int[] SOURCE = {
+      MediaRecorder.AudioSource.MIC, MediaRecorder.AudioSource.VOICE_RECOGNITION};
+  private static final int[] SAMPLE_RATES_HZ = {
+    AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC), 48000, 44100};
+
+  private static final int CHANNEL = AudioFormat.CHANNEL_CONFIGURATION_MONO;
+  private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
+  private static final String TAG = "AudioRecordHelper";
+  private static AudioRecordHelper instance;
+  private final int bufferSize;
+  private final int sampleRate;
+  private final int source;
+  private ByteArrayOutputStream os;
+  private AudioRecord audioRecord;
+  private volatile boolean isRecording = false;
+
+  private AudioRecordHelper() {
+    int tmpBufferSize = 0;
+    int tmpSampleRate = 0;
+    int tmpSource = 0;
+    initialization:
+    for (int source : SOURCE) {
+      for (int rate : SAMPLE_RATES_HZ) {
+        tmpBufferSize = AudioRecord.getMinBufferSize(rate, CHANNEL, ENCODING);
+        AudioRecord testAudioRecord = new AudioRecord(source, rate, CHANNEL, ENCODING,
+            tmpBufferSize);
+        if (testAudioRecord.getState() == AudioRecord.STATE_INITIALIZED) {
+          testAudioRecord.release();
+          tmpSampleRate = rate;
+          tmpSource = source;
+          break initialization;
+        }
+      }
+    }
+    if (tmpBufferSize == 0 || tmpSampleRate == 0) {
+      Log.e(TAG, "Failed to initialize");
+    }
+    bufferSize = tmpBufferSize;
+    sampleRate = tmpSampleRate;
+    source = tmpSource;
+    Log.d(TAG, "Sample rate = " + sampleRate + "Hz, Source = "
+        + source + " (VOICE_RECOGNITION = 6 , MIC = 1)");
+  }
+
+  public static AudioRecordHelper getInstance() {
+    if (instance == null) {
+      instance = new AudioRecordHelper();
+    }
+    return instance;
+  }
+
+  /**
+   * Start recording.
+   */
+  public void start() {
+    if (!isRecording) {
+      isRecording = true;
+      os = new ByteArrayOutputStream();
+      audioRecord = new AudioRecord(source, sampleRate, CHANNEL, ENCODING, bufferSize);
+      audioRecord.startRecording();
+      startPullingData();
+    }
+  }
+
+  /**
+   * Stop recording
+   */
+  public void stop() {
+    if (isRecording) {
+      isRecording = false;
+      audioRecord.stop();
+      audioRecord.release();
+      audioRecord = null;
+      try {
+        os.close();
+      } catch (IOException e) {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  private void startPullingData() {
+    new Thread() {
+      @Override
+      public void run(){
+        byte data[] = new byte[bufferSize];
+        while (isRecording) {
+          int read = audioRecord.read(data, 0, bufferSize);
+          if (read > 0) {
+            os.write(data, 0, read);
+          }
+          if (read < 0) {
+            break;
+          }
+        }
+      }
+    }.start();
+  }
+
+  /**
+   * Returns the sample rate for this recorder.
+   */
+  public int getSampleRate() {
+    return sampleRate;
+  }
+
+  /**
+   * Returns the audio source currently being used.
+   */
+  public int getAudioSource() {
+    return source;
+  }
+
+  /**
+   * Returns true if recorder is recording; False if not.
+   */
+  public boolean isRecording() {
+    return isRecording;
+  }
+
+  /**
+   * Returns the raw data.
+   */
+  public byte[] getByte() {
+    return os.toByteArray();
+  }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/Common.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Common.java
new file mode 100644
index 0000000..df7460a
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Common.java
@@ -0,0 +1,142 @@
+package com.android.cts.verifier.audio;
+
+import android.media.AudioManager;
+import android.media.AudioTrack;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+/**
+ * This class stores common constants and methods.
+ */
+public class Common {
+
+  public static final int RECORDING_SAMPLE_RATE_HZ
+      = AudioRecordHelper.getInstance().getSampleRate();
+  public static final int PLAYING_SAMPLE_RATE_HZ
+      = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
+
+  // Default constants.
+  public static final double PASSING_THRESHOLD_DB = -40.0;
+  public static final double PIP_DURATION_S = 0.004;
+  public static final double PAUSE_DURATION_S = 0.016;
+  public static final int PREFIX_NUM_CHIPS = 1023;
+  public static final int PREFIX_SAMPLES_PER_CHIP = 4;
+  public static final double PREFIX_LENGTH_S = 0.1;
+  public static final double PAUSE_BEFORE_PREFIX_DURATION_S = 0.5;
+  public static final double PAUSE_AFTER_PREFIX_DURATION_S = 0.4;
+  public static final double MIN_FREQUENCY_HZ = 500;
+  public static final double MAX_FREQUENCY_HZ = 21000;
+  public static final double FREQUENCY_STEP_HZ = 100;
+  public static final int SIGNAL_MIN_STRENGTH_DB_ABOVE_NOISE = 10;
+  public static final int REPETITIONS = 5;
+  public static final int NOISE_SAMPLES = 3;
+
+  public static final double[] FREQUENCIES_ORIGINAL = originalFrequencies();
+  public static final int PIP_NUM = FREQUENCIES_ORIGINAL.length;
+  public static final int[] ORDER = order();
+  public static final double[] FREQUENCIES = frequencies();
+
+  public static final double[] WINDOW_FOR_RECORDER =
+      hann(Util.toLength(PIP_DURATION_S, RECORDING_SAMPLE_RATE_HZ));
+  public static final double[] WINDOW_FOR_PLAYER =
+      hann(Util.toLength(PIP_DURATION_S, PLAYING_SAMPLE_RATE_HZ));
+
+  public static final double[] PREFIX_FOR_RECORDER = prefix(RECORDING_SAMPLE_RATE_HZ);
+  public static final double[] PREFIX_FOR_PLAYER = prefix(PLAYING_SAMPLE_RATE_HZ);
+
+  /**
+   * Get a Hann window.
+   */
+  private static double[] hann(int windowWidth) {
+    double[] envelopeArray = new double[windowWidth];
+    for (int i = 0; i < windowWidth; i++) {
+      envelopeArray[i] = 0.5
+          * (1 - Math.cos(2 * Math.PI * i / windowWidth));
+    }
+    return envelopeArray;
+  }
+
+  /**
+   * Get a maximum length sequence, used as prefix to indicate start of signal.
+   */
+  private static double[] prefix(int rate) {
+    double[] codeSequence = new double[PREFIX_NUM_CHIPS];
+    for (int i = 0; i < PREFIX_NUM_CHIPS; i++) {
+      if (i < 10) {
+        codeSequence[i] = 1;
+      } else {
+        codeSequence[i] = -codeSequence[i - 6] * codeSequence[i - 7]
+            * codeSequence[i - 9] * codeSequence[i - 10];
+      }
+    }
+    double[] prefixArray = new double[PREFIX_NUM_CHIPS * PREFIX_SAMPLES_PER_CHIP];
+    int offset = 0;
+    for (int i = 0; i < PREFIX_NUM_CHIPS; i++) {
+      double value = codeSequence[i];
+      for (int j = 0; j < PREFIX_SAMPLES_PER_CHIP; j++) {
+        prefixArray[offset + j] = value;
+      }
+      offset += PREFIX_SAMPLES_PER_CHIP;
+    }
+    int prefixLength = (int) Math.round(PREFIX_LENGTH_S * rate);
+    double[] samplePrefixArray = new double[prefixLength];
+    for (int i = 0; i < prefixLength; i++) {
+      double index = (double) i / prefixLength * (prefixArray.length - 1);
+      samplePrefixArray[i] = (1 - index + Math.floor(index)) * prefixArray[(int) Math.floor(index)]
+          + (1 + index - Math.ceil(index)) * prefixArray[(int) Math.ceil(index)];
+    }
+    return samplePrefixArray;
+  }
+
+  /**
+   * Returns array consists the frequencies of the test pips in the order that will be used in test.
+   */
+  private static double[] frequencies() {
+    double[] originalFrequencies = originalFrequencies();
+
+    double[] randomFrequencies = new double[Common.REPETITIONS * originalFrequencies.length];
+    for (int i = 0; i < REPETITIONS * originalFrequencies.length; i++) {
+      randomFrequencies[i] = originalFrequencies[ORDER[i] % originalFrequencies.length];
+    }
+
+    return randomFrequencies;
+  }
+
+  /**
+   * Returns array consists the frequencies of the test pips.
+   */
+  private static double[] originalFrequencies() {
+    ArrayList<Double> frequencies = new ArrayList<Double>();
+    double frequency = Common.MIN_FREQUENCY_HZ;
+    while (frequency <= Common.MAX_FREQUENCY_HZ) {
+      frequencies.add(new Double(frequency));
+      if ((frequency >= 18500) && (frequency < 20000)) {
+        frequency += Common.FREQUENCY_STEP_HZ;
+      } else {
+        frequency += Common.FREQUENCY_STEP_HZ * 10;
+      }
+    }
+    Double[] frequenciesArray = frequencies.toArray(new Double[frequencies.size()]);
+    double[] frequenciesPrimitiveArray = new double[frequenciesArray.length];
+    for (int i = 0; i < frequenciesArray.length; i++) {
+      frequenciesPrimitiveArray[i] = frequenciesArray[i];
+    }
+    return frequenciesPrimitiveArray;
+  }
+
+  /**
+   * Fisher-Yates shuffle.
+   */
+  private static int[] order() {
+    int[] order = new int[REPETITIONS * PIP_NUM];
+    long seed = 0;
+    Random generator = new Random(seed);
+    for (int i = 0; i < REPETITIONS * PIP_NUM; i++) {
+      int j = generator.nextInt(i + 1);
+      order[i] = order[j];
+      order[j] = i;
+    }
+    return order;
+  }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.java
new file mode 100644
index 0000000..98d1365
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Correlation.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 com.android.cts.verifier.audio;
+
+import android.util.Log;
+
+
+public class Correlation {
+
+    private int mBlockSize = 4096;
+    private int mSamplingRate = 44100;
+    private double [] mDataDownsampled = new double [mBlockSize];
+    private double [] mDataAutocorrelated = new double[mBlockSize];
+
+    public double mEstimatedLatencySamples = 0;
+    public double mEstimatedLatencyMs = 0;
+    public double mEstimatedLatencyConfidence = 0.0;
+
+    private double mAmplitudeThreshold = 0.001;  // 0.001 = -60 dB noise
+
+    public void init(int blockSize, int samplingRate) {
+        mBlockSize = blockSize;
+        mSamplingRate = samplingRate;
+    }
+
+    public boolean computeCorrelation(double [] data, int samplingRate) {
+        boolean status = false;
+        log("Started Auto Correlation for data with " + data.length + " points");
+        mSamplingRate = samplingRate;
+
+        downsampleData(data, mDataDownsampled, mAmplitudeThreshold);
+
+        //correlation vector
+        autocorrelation(mDataDownsampled, mDataAutocorrelated);
+
+        int N = data.length; //all samples available
+        double groupSize =  (double) N / mBlockSize;  //samples per downsample point.
+
+        double maxValue = 0;
+        int maxIndex = -1;
+
+        double minLatencyMs = 8; //min latency expected. This algorithm should be improved.
+        int minIndex = (int)(0.5 + minLatencyMs * mSamplingRate / (groupSize*1000));
+
+        double average = 0;
+        double rms = 0;
+        //find max
+        for (int i=minIndex; i<mDataAutocorrelated.length; i++) {
+            average += mDataAutocorrelated[i];
+            rms += mDataAutocorrelated[i]*mDataAutocorrelated[i];
+            if (mDataAutocorrelated[i] > maxValue) {
+                maxValue = mDataAutocorrelated[i];
+                maxIndex = i;
+            }
+        }
+
+        rms = Math.sqrt(rms/mDataAutocorrelated.length);
+        average = average/mDataAutocorrelated.length;
+        log(String.format(" Maxvalue %f, max Index : %d/%d (%d)  minIndex=%d",maxValue, maxIndex,
+                mDataAutocorrelated.length, data.length, minIndex));
+
+        log(String.format("  average : %.3f  rms: %.3f", average, rms));
+
+        mEstimatedLatencyConfidence = 0.0;
+        if (average>0) {
+            double factor = 3.0;
+
+            double raw = (rms-average) /(factor*average);
+            log(String.format("Raw: %.3f",raw));
+            mEstimatedLatencyConfidence = Math.max(Math.min(raw, 1.0),0.0);
+        }
+
+        log(String.format(" ****Confidence: %.2f",mEstimatedLatencyConfidence));
+
+        mEstimatedLatencySamples = maxIndex*groupSize;
+
+        mEstimatedLatencyMs = mEstimatedLatencySamples *1000/mSamplingRate;
+
+        log(String.format(" latencySamples: %.2f  %.2f ms", mEstimatedLatencySamples,
+                mEstimatedLatencyMs));
+
+        status = true;
+        return status;
+    }
+
+    private boolean downsampleData(double [] data, double [] dataDownsampled, double threshold) {
+
+        boolean status = false;
+        // mDataDownsampled = new double[mBlockSize];
+        for (int i=0; i<mBlockSize; i++) {
+            dataDownsampled[i] = 0;
+        }
+
+        int N = data.length; //all samples available
+        double groupSize =  (double) N / mBlockSize;
+
+        int ignored = 0;
+
+        int currentIndex = 0;
+        double nextGroup = groupSize;
+        for (int i = 0; i<N && currentIndex<mBlockSize; i++) {
+
+            if (i> nextGroup) { //advanced to next group.
+                currentIndex++;
+                nextGroup += groupSize;
+            }
+
+            if (currentIndex>=mBlockSize) {
+                break;
+            }
+
+            double value =  Math.abs(data[i]);
+            if (value >= threshold) {
+                dataDownsampled[currentIndex] += value;
+            } else {
+                ignored++;
+            }
+        }
+
+        log(String.format(" Threshold: %.3f, ignored:%d/%d (%%.2f)", threshold, ignored, N,
+                (double) ignored/(double)N));
+
+        status = true;
+        return status;
+    }
+
+    private boolean autocorrelation(double [] data, double [] dataOut) {
+        boolean status = false;
+
+        double sumsquared = 0;
+        int N = data.length;
+        for (int i=0; i<N; i++) {
+            double value = data[i];
+            sumsquared += value*value;
+        }
+
+        if (sumsquared>0) {
+            for (int i = 0; i < N; i++) {
+                dataOut[i] = 0;
+                for (int j = 0; j < N - i; j++) {
+
+                    dataOut[i] += data[j] * data[i + j];
+                }
+                dataOut[i] = dataOut[i] / sumsquared;
+            }
+            status = true;
+        }
+
+        return status;
+    }
+
+    private static void log(String msg) {
+        Log.v("Recorder", msg);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HeadsetHonorSystemActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HeadsetHonorSystemActivity.java
new file mode 100644
index 0000000..a82b994
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HeadsetHonorSystemActivity.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.compatibility.common.util.ReportLog;
+import com.android.compatibility.common.util.ResultType;
+import com.android.compatibility.common.util.ResultUnit;
+
+import android.content.Context;
+
+import android.os.Bundle;
+import android.os.Handler;
+
+import android.util.Log;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import android.widget.Button;
+//import android.widget.TextView;
+
+abstract class HeadsetHonorSystemActivity extends PassFailButtons.Activity {
+    private static final String TAG = "HeadsetHonorSystemActivity";
+
+    private OnBtnClickListener mBtnClickListener = new OnBtnClickListener();
+
+    abstract protected void enableTestButtons(boolean enabled);
+
+    private void recordHeadsetPortFound(boolean found) {
+        getReportLog().addValue(
+                "User Reported Headset Port",
+                found ? 1.0 : 0,
+                ResultType.NEUTRAL,
+                ResultUnit.NONE);
+    }
+
+    protected void setup() {
+        // The "Honor" system buttons
+        ((Button)findViewById(R.id.audio_general_headset_no)).
+            setOnClickListener(mBtnClickListener);
+        ((Button)findViewById(R.id.audio_general_headset_yes)).
+            setOnClickListener(mBtnClickListener);
+
+        enableTestButtons(false);
+    }
+
+    private class OnBtnClickListener implements OnClickListener {
+        @Override
+        public void onClick(View v) {
+            switch (v.getId()) {
+                case R.id.audio_general_headset_no:
+                    Log.i(TAG, "User denies Headset Port existence");
+                    enableTestButtons(false);
+                    recordHeadsetPortFound(false);
+                    break;
+
+                case R.id.audio_general_headset_yes:
+                    Log.i(TAG, "User confirms Headset Port existence");
+                    enableTestButtons(true);
+                    recordHeadsetPortFound(true);
+                    break;
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
new file mode 100644
index 0000000..dc81e19
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundSpeakerTestActivity.java
@@ -0,0 +1,430 @@
+/*
+ * 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.audio;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.content.Context;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+import java.util.Arrays;
+
+import com.androidplot.xy.SimpleXYSeries;
+import com.androidplot.xy.XYSeries;
+import com.androidplot.xy.*;
+
+public class HifiUltrasoundSpeakerTestActivity extends PassFailButtons.Activity {
+
+  public enum Status {
+    START, RECORDING, DONE, PLAYER
+  }
+
+  private static final String TAG = "HifiUltrasoundTestActivity";
+
+  private Status status = Status.START;
+  private boolean onPlotScreen = false;
+  private boolean onInstruScreen = false;
+  private TextView info;
+  private Button playerButton;
+  private Button recorderButton;
+  private AudioTrack audioTrack;
+  private LayoutInflater layoutInflater;
+  private View popupView;
+  private View instruView;
+  private PopupWindow popupWindow;
+  private PopupWindow instruWindow;
+  private boolean micSupport = true;
+  private boolean spkrSupport = true;
+
+  @Override
+  public void onBackPressed () {
+    if (onPlotScreen) {
+      popupWindow.dismiss();
+      onPlotScreen = false;
+      recorderButton.setEnabled(true);
+    } else if (onInstruScreen) {
+      instruWindow.dismiss();
+      onInstruScreen = false;
+      if (status == Status.PLAYER) {
+        playerButton.setEnabled(spkrSupport);
+      } else {
+        recorderButton.setEnabled(micSupport);
+      }
+      if (status == Status.PLAYER) {
+        getPassButton().setEnabled(true);
+      }
+    } else {
+      super.onBackPressed();
+    }
+  }
+
+  @Override
+  protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    setContentView(R.layout.hifi_ultrasound);
+    setInfoResources(R.string.hifi_ultrasound_speaker_test,
+        R.string.hifi_ultrasound_speaker_test_info, -1);
+    setPassFailButtonClickListeners();
+    getPassButton().setEnabled(false);
+
+    info = (TextView) findViewById(R.id.info_text);
+    info.setMovementMethod(new ScrollingMovementMethod());
+    info.setText(R.string.hifi_ultrasound_speaker_test_instruction1);
+
+    AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+    String micSupportString = audioManager.getProperty(
+        AudioManager.PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND);
+    String spkrSupportString = audioManager.getProperty(
+        AudioManager.PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND);
+    Log.d(TAG, "PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = " + micSupportString);
+    Log.d(TAG, "PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = " + spkrSupportString);
+
+    if (micSupportString == null) {
+      micSupportString = "null";
+    }
+    if (spkrSupportString == null) {
+      spkrSupportString = "null";
+    }
+    if (micSupportString.equalsIgnoreCase(getResources().getString(
+        R.string.hifi_ultrasound_test_default_false_string))) {
+      micSupport = false;
+      getPassButton().setEnabled(true);
+      info.append(getResources().getString(R.string.hifi_ultrasound_speaker_test_mic_no_support));
+    }
+    if (spkrSupportString.equalsIgnoreCase(getResources().getString(
+        R.string.hifi_ultrasound_test_default_false_string))) {
+      spkrSupport = false;
+      info.append(getResources().getString(R.string.hifi_ultrasound_speaker_test_spkr_no_support));
+    }
+
+    layoutInflater = (LayoutInflater) getBaseContext().getSystemService(
+        LAYOUT_INFLATER_SERVICE);
+    popupView = layoutInflater.inflate(R.layout.hifi_ultrasound_popup, null);
+    popupWindow = new PopupWindow(
+        popupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+    instruView = layoutInflater.inflate(R.layout.hifi_ultrasound_popup_instru, null);
+    instruWindow = new PopupWindow(
+        instruView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+
+    final AudioRecordHelper audioRecorder = AudioRecordHelper.getInstance();
+    final int recordRate = audioRecorder.getSampleRate();
+
+    recorderButton = (Button) findViewById(R.id.recorder_button);
+    recorderButton.setEnabled(micSupport);
+    recorderButton.setOnClickListener(new View.OnClickListener() {
+      private WavAnalyzerTask wavAnalyzerTask = null;
+      private void stopRecording() {
+        audioRecorder.stop();
+        wavAnalyzerTask = new WavAnalyzerTask(audioRecorder.getByte());
+        wavAnalyzerTask.execute();
+        status = Status.DONE;
+      }
+      @Override
+      public void onClick(View v) {
+        switch (status) {
+          case START:
+            info.append("Recording at " + recordRate + "Hz using ");
+            final int source = audioRecorder.getAudioSource();
+            switch (source) {
+              case 1:
+                info.append("MIC");
+                break;
+              case 6:
+                info.append("VOICE_RECOGNITION");
+                break;
+              default:
+                info.append("UNEXPECTED " + source);
+                break;
+            }
+            info.append("\n");
+            status = Status.RECORDING;
+            playerButton.setEnabled(false);
+            recorderButton.setEnabled(false);
+            audioRecorder.start();
+
+            final View finalV = v;
+            new Thread() {
+              @Override
+              public void run() {
+                Double recordingDuration_millis = new Double(1000 * (2.5
+                    + Common.PREFIX_LENGTH_S
+                    + Common.PAUSE_BEFORE_PREFIX_DURATION_S
+                    + Common.PAUSE_AFTER_PREFIX_DURATION_S
+                    + Common.PIP_NUM * (Common.PIP_DURATION_S + Common.PAUSE_DURATION_S)
+                    * Common.REPETITIONS));
+                Log.d(TAG, "Recording for " + recordingDuration_millis + "ms");
+                try {
+                  Thread.sleep(recordingDuration_millis.intValue());
+                } catch (InterruptedException e) {
+                  throw new RuntimeException(e);
+                }
+                runOnUiThread(new Runnable() {
+                  @Override
+                  public void run() {
+                    stopRecording();
+                  }
+                });
+              }
+            }.start();
+
+            break;
+
+          case DONE:
+            plotResponse(wavAnalyzerTask);
+            break;
+
+          default: break;
+        }
+      }
+    });
+
+    playerButton = (Button) findViewById(R.id.player_button);
+    playerButton.setEnabled(spkrSupport);
+    playerButton.setOnClickListener(new View.OnClickListener() {
+      @Override
+      public void onClick(View v) {
+        recorderButton.setEnabled(false);
+        status = Status.PLAYER;
+        play();
+
+        Button okButton = (Button)instruView.findViewById(R.id.ok);
+        okButton.setOnClickListener(new Button.OnClickListener() {
+          @Override
+          public void onClick(View v) {
+            instruWindow.dismiss();
+            onInstruScreen = false;
+            if (status == Status.PLAYER) {
+              playerButton.setEnabled(spkrSupport);
+            } else {
+              recorderButton.setEnabled(micSupport);
+            }
+            getPassButton().setEnabled(true);
+          }
+        });
+        TextView instruction = (TextView)instruView.findViewById(R.id.instru);
+        instruction.setText(R.string.hifi_ultrasound_speaker_test_test_side);
+        instruWindow.showAtLocation(info, Gravity.CENTER, 0, 0);
+        recorderButton.setEnabled(false);
+        playerButton.setEnabled(false);
+        onInstruScreen = true;
+      }
+    });
+  }
+
+  private void plotResponse(WavAnalyzerTask wavAnalyzerTask) {
+    Button dismissButton = (Button)popupView.findViewById(R.id.dismiss);
+    dismissButton.setOnClickListener(new Button.OnClickListener(){
+      @Override
+      public void onClick(View v) {
+        popupWindow.dismiss();
+        onPlotScreen = false;
+        recorderButton.setEnabled(true);
+      }});
+    popupWindow.showAtLocation(info, Gravity.CENTER, 0, 0);
+    onPlotScreen = true;
+
+    recorderButton.setEnabled(false);
+
+    XYPlot plot = (XYPlot) popupView.findViewById(R.id.responseChart);
+    plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 2000);
+
+    Double[] frequencies = new Double[Common.PIP_NUM];
+    for (int i = 0; i < Common.PIP_NUM; i++) {
+      frequencies[i] = new Double(Common.FREQUENCIES_ORIGINAL[i]);
+    }
+
+    if (wavAnalyzerTask != null) {
+
+      double[][] power = wavAnalyzerTask.getPower();
+      for(int i = 0; i < Common.REPETITIONS; i++) {
+        Double[] powerWrap = new Double[Common.PIP_NUM];
+        for (int j = 0; j < Common.PIP_NUM; j++) {
+          powerWrap[j] = new Double(10 * Math.log10(power[j][i]));
+        }
+        XYSeries series = new SimpleXYSeries(
+            Arrays.asList(frequencies),
+            Arrays.asList(powerWrap),
+            "");
+        LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
+        seriesFormat.configure(getApplicationContext(),
+            R.xml.ultrasound_line_formatter_trials);
+        seriesFormat.setPointLabelFormatter(null);
+        plot.addSeries(series, seriesFormat);
+      }
+
+      double[] noiseDB = wavAnalyzerTask.getNoiseDB();
+      Double[] noiseDBWrap = new Double[Common.PIP_NUM];
+      for (int i = 0; i < Common.PIP_NUM; i++) {
+        noiseDBWrap[i] = new Double(noiseDB[i]);
+      }
+
+      XYSeries noiseSeries = new SimpleXYSeries(
+          Arrays.asList(frequencies),
+          Arrays.asList(noiseDBWrap),
+          "background noise");
+      LineAndPointFormatter noiseSeriesFormat = new LineAndPointFormatter();
+      noiseSeriesFormat.configure(getApplicationContext(),
+          R.xml.ultrasound_line_formatter_noise);
+      noiseSeriesFormat.setPointLabelFormatter(null);
+      plot.addSeries(noiseSeries, noiseSeriesFormat);
+
+      double[] dB = wavAnalyzerTask.getDB();
+      Double[] dBWrap = new Double[Common.PIP_NUM];
+      for (int i = 0; i < Common.PIP_NUM; i++) {
+        dBWrap[i] = new Double(dB[i]);
+      }
+
+      XYSeries series = new SimpleXYSeries(
+          Arrays.asList(frequencies),
+          Arrays.asList(dBWrap),
+          "median");
+      LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
+      seriesFormat.configure(getApplicationContext(),
+          R.xml.ultrasound_line_formatter_median);
+      seriesFormat.setPointLabelFormatter(null);
+      plot.addSeries(series, seriesFormat);
+
+      Double[] passX = new Double[] {Common.MIN_FREQUENCY_HZ, Common.MAX_FREQUENCY_HZ};
+      Double[] passY = new Double[] {wavAnalyzerTask.getThreshold(), wavAnalyzerTask.getThreshold()};
+      XYSeries passSeries = new SimpleXYSeries(
+          Arrays.asList(passX), Arrays.asList(passY), "passing");
+      LineAndPointFormatter passSeriesFormat = new LineAndPointFormatter();
+      passSeriesFormat.configure(getApplicationContext(),
+          R.xml.ultrasound_line_formatter_pass);
+      passSeriesFormat.setPointLabelFormatter(null);
+      plot.addSeries(passSeries, passSeriesFormat);
+    }
+  }
+
+  /**
+   * Plays the generated pips.
+   */
+  private void play() {
+    play(SoundGenerator.getInstance().getByte(), Common.PLAYING_SAMPLE_RATE_HZ);
+  }
+
+  /**
+   * Plays the sound data.
+   */
+  private void play(byte[] data, int sampleRate) {
+    if (audioTrack != null) {
+      audioTrack.stop();
+      audioTrack.release();
+    }
+    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
+        sampleRate, AudioFormat.CHANNEL_OUT_MONO,
+        AudioFormat.ENCODING_PCM_16BIT, Math.max(data.length, AudioTrack.getMinBufferSize(
+        sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT)),
+        AudioTrack.MODE_STATIC);
+    audioTrack.write(data, 0, data.length);
+    audioTrack.play();
+  }
+
+  /**
+   * AsyncTask class for the analyzing.
+   */
+  private class WavAnalyzerTask extends AsyncTask<Void, String, String>
+      implements WavAnalyzer.Listener {
+
+    private static final String TAG = "WavAnalyzerTask";
+    WavAnalyzer wavAnalyzer;
+
+    public WavAnalyzerTask(byte[] recording) {
+      wavAnalyzer = new WavAnalyzer(recording, Common.RECORDING_SAMPLE_RATE_HZ,
+          WavAnalyzerTask.this);
+    }
+
+    double[] getDB() {
+      return wavAnalyzer.getDB();
+    }
+
+    double[][] getPower() {
+      return wavAnalyzer.getPower();
+    }
+
+    double[] getNoiseDB() {
+      return wavAnalyzer.getNoiseDB();
+    }
+
+    double getThreshold() {
+      return wavAnalyzer.getThreshold();
+    }
+
+    @Override
+    protected String doInBackground(Void... params) {
+      boolean result = wavAnalyzer.doWork();
+      if (result) {
+        return getString(R.string.hifi_ultrasound_test_pass);
+      }
+      return getString(R.string.hifi_ultrasound_test_fail);
+    }
+
+    @Override
+    protected void onPostExecute(String result) {
+      info.append(result);
+      recorderButton.setEnabled(true);
+      recorderButton.setText(R.string.hifi_ultrasound_test_plot);
+
+      Button okButton = (Button)instruView.findViewById(R.id.ok);
+      okButton.setOnClickListener(new Button.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+          instruWindow.dismiss();
+          onInstruScreen = false;
+          if (status == HifiUltrasoundSpeakerTestActivity.Status.PLAYER) {
+            playerButton.setEnabled(spkrSupport);
+          } else {
+            recorderButton.setEnabled(micSupport);
+          }
+        }
+      });
+      TextView instruction = (TextView) instruView.findViewById(R.id.instru);
+      instruction.setText(R.string.hifi_ultrasound_speaker_test_reference_side);
+      instruWindow.showAtLocation(info, Gravity.CENTER, 0, 0);
+      recorderButton.setEnabled(false);
+      playerButton.setEnabled(false);
+      onInstruScreen = true;
+    }
+
+    @Override
+    protected void onProgressUpdate(String... values) {
+      for (String message : values) {
+        info.append(message);
+        Log.d(TAG, message);
+      }
+    }
+
+    @Override
+    public void sendMessage(String message) {
+      publishProgress(message);
+    }
+  }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java
new file mode 100644
index 0000000..85b3e37
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/HifiUltrasoundTestActivity.java
@@ -0,0 +1,374 @@
+/*
+ * 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.audio;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.content.Context;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
+import android.widget.PopupWindow;
+import android.widget.TextView;
+import java.util.Arrays;
+
+import com.androidplot.xy.SimpleXYSeries;
+import com.androidplot.xy.XYSeries;
+import com.androidplot.xy.*;
+
+public class HifiUltrasoundTestActivity extends PassFailButtons.Activity {
+
+  public enum Status {
+    START, RECORDING, DONE, PLAYER
+  }
+
+  private static final String TAG = "HifiUltrasoundTestActivity";
+
+  private Status status = Status.START;
+  private boolean onPlotScreen = false;
+  private TextView info;
+  private Button playerButton;
+  private Button recorderButton;
+  private AudioTrack audioTrack;
+  private LayoutInflater layoutInflater;
+  private View popupView;
+  private PopupWindow popupWindow;
+  private boolean micSupport = true;
+  private boolean spkrSupport = true;
+
+  @Override
+  public void onBackPressed () {
+    if (onPlotScreen) {
+      popupWindow.dismiss();
+      onPlotScreen = false;
+      recorderButton.setEnabled(true);
+    } else {
+      super.onBackPressed();
+    }
+  }
+
+  @Override
+  protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    setContentView(R.layout.hifi_ultrasound);
+    setInfoResources(R.string.hifi_ultrasound_test, R.string.hifi_ultrasound_test_info, -1);
+    setPassFailButtonClickListeners();
+    getPassButton().setEnabled(false);
+
+    info = (TextView) findViewById(R.id.info_text);
+    info.setMovementMethod(new ScrollingMovementMethod());
+    info.setText(R.string.hifi_ultrasound_test_instruction1);
+
+    AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+    String micSupportString = audioManager.getProperty(
+        AudioManager.PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND);
+    String spkrSupportString = audioManager.getProperty(
+        AudioManager.PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND);
+    Log.d(TAG, "PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND = " + micSupportString);
+    Log.d(TAG, "PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND = " + spkrSupportString);
+
+    if (micSupportString == null) {
+      micSupportString = "null";
+    }
+    if (spkrSupportString == null) {
+      spkrSupportString = "null";
+    }
+    if (micSupportString.equalsIgnoreCase(getResources().getString(
+        R.string.hifi_ultrasound_test_default_false_string))) {
+      micSupport = false;
+      getPassButton().setEnabled(true);
+      info.append(getResources().getString(R.string.hifi_ultrasound_test_mic_no_support));
+    }
+    if (spkrSupportString.equalsIgnoreCase(getResources().getString(
+        R.string.hifi_ultrasound_test_default_false_string))) {
+      spkrSupport = false;
+      info.append(getResources().getString(R.string.hifi_ultrasound_test_spkr_no_support));
+    }
+
+    layoutInflater = (LayoutInflater) getBaseContext().getSystemService(
+        LAYOUT_INFLATER_SERVICE);
+    popupView = layoutInflater.inflate(R.layout.hifi_ultrasound_popup, null);
+    popupWindow = new PopupWindow(
+        popupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+
+    final AudioRecordHelper audioRecorder = AudioRecordHelper.getInstance();
+    final int recordRate = audioRecorder.getSampleRate();
+
+    recorderButton = (Button) findViewById(R.id.recorder_button);
+    recorderButton.setEnabled(micSupport);
+    recorderButton.setOnClickListener(new View.OnClickListener() {
+      private WavAnalyzerTask wavAnalyzerTask = null;
+      private void stopRecording() {
+        audioRecorder.stop();
+        wavAnalyzerTask = new WavAnalyzerTask(audioRecorder.getByte());
+        wavAnalyzerTask.execute();
+        status = Status.DONE;
+      }
+      @Override
+      public void onClick(View v) {
+        switch (status) {
+          case START:
+            info.append("Recording at " + recordRate + "Hz using ");
+            final int source = audioRecorder.getAudioSource();
+            switch (source) {
+              case 1:
+                info.append("MIC");
+                break;
+              case 6:
+                info.append("VOICE_RECOGNITION");
+                break;
+              default:
+                info.append("UNEXPECTED " + source);
+                break;
+            }
+            info.append("\n");
+            status = Status.RECORDING;
+            playerButton.setEnabled(false);
+            recorderButton.setEnabled(false);
+            audioRecorder.start();
+
+            final View finalV = v;
+            new Thread() {
+              @Override
+              public void run() {
+                Double recordingDuration_millis = new Double(1000 * (2.5
+                    + Common.PREFIX_LENGTH_S
+                    + Common.PAUSE_BEFORE_PREFIX_DURATION_S
+                    + Common.PAUSE_AFTER_PREFIX_DURATION_S
+                    + Common.PIP_NUM * (Common.PIP_DURATION_S + Common.PAUSE_DURATION_S)
+                    * Common.REPETITIONS));
+                Log.d(TAG, "Recording for " + recordingDuration_millis + "ms");
+                try {
+                  Thread.sleep(recordingDuration_millis.intValue());
+                } catch (InterruptedException e) {
+                  throw new RuntimeException(e);
+                }
+                runOnUiThread(new Runnable() {
+                  @Override
+                  public void run() {
+                    stopRecording();
+                  }
+                });
+              }
+            }.start();
+
+            break;
+
+          case DONE:
+            plotResponse(wavAnalyzerTask);
+            break;
+
+          default: break;
+        }
+      }
+    });
+
+    playerButton = (Button) findViewById(R.id.player_button);
+    playerButton.setEnabled(spkrSupport);
+    playerButton.setOnClickListener(new View.OnClickListener() {
+      @Override
+      public void onClick(View v) {
+        recorderButton.setEnabled(false);
+        status = Status.PLAYER;
+        play();
+      }
+    });
+  }
+
+  private void plotResponse(WavAnalyzerTask wavAnalyzerTask) {
+    Button dismissButton = (Button)popupView.findViewById(R.id.dismiss);
+    dismissButton.setOnClickListener(new Button.OnClickListener(){
+      @Override
+      public void onClick(View v) {
+        popupWindow.dismiss();
+        onPlotScreen = false;
+        recorderButton.setEnabled(true);
+      }});
+    popupWindow.showAtLocation(info, Gravity.CENTER, 0, 0);
+    onPlotScreen = true;
+
+    recorderButton.setEnabled(false);
+
+    XYPlot plot = (XYPlot) popupView.findViewById(R.id.responseChart);
+    plot.setDomainStep(XYStepMode.INCREMENT_BY_VAL, 2000);
+
+    Double[] frequencies = new Double[Common.PIP_NUM];
+    for (int i = 0; i < Common.PIP_NUM; i++) {
+      frequencies[i] = new Double(Common.FREQUENCIES_ORIGINAL[i]);
+    }
+
+    if (wavAnalyzerTask != null) {
+
+      double[][] power = wavAnalyzerTask.getPower();
+      for(int i = 0; i < Common.REPETITIONS; i++) {
+        Double[] powerWrap = new Double[Common.PIP_NUM];
+        for (int j = 0; j < Common.PIP_NUM; j++) {
+          powerWrap[j] = new Double(10 * Math.log10(power[j][i]));
+        }
+        XYSeries series = new SimpleXYSeries(
+            Arrays.asList(frequencies),
+            Arrays.asList(powerWrap),
+            "");
+        LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
+        seriesFormat.configure(getApplicationContext(),
+            R.xml.ultrasound_line_formatter_trials);
+        seriesFormat.setPointLabelFormatter(null);
+        plot.addSeries(series, seriesFormat);
+      }
+
+      double[] noiseDB = wavAnalyzerTask.getNoiseDB();
+      Double[] noiseDBWrap = new Double[Common.PIP_NUM];
+      for (int i = 0; i < Common.PIP_NUM; i++) {
+        noiseDBWrap[i] = new Double(noiseDB[i]);
+      }
+
+      XYSeries noiseSeries = new SimpleXYSeries(
+          Arrays.asList(frequencies),
+          Arrays.asList(noiseDBWrap),
+          "background noise");
+      LineAndPointFormatter noiseSeriesFormat = new LineAndPointFormatter();
+      noiseSeriesFormat.configure(getApplicationContext(),
+          R.xml.ultrasound_line_formatter_noise);
+      noiseSeriesFormat.setPointLabelFormatter(null);
+      plot.addSeries(noiseSeries, noiseSeriesFormat);
+
+      double[] dB = wavAnalyzerTask.getDB();
+      Double[] dBWrap = new Double[Common.PIP_NUM];
+      for (int i = 0; i < Common.PIP_NUM; i++) {
+        dBWrap[i] = new Double(dB[i]);
+      }
+
+      XYSeries series = new SimpleXYSeries(
+          Arrays.asList(frequencies),
+          Arrays.asList(dBWrap),
+          "median");
+      LineAndPointFormatter seriesFormat = new LineAndPointFormatter();
+      seriesFormat.configure(getApplicationContext(),
+          R.xml.ultrasound_line_formatter_median);
+      seriesFormat.setPointLabelFormatter(null);
+      plot.addSeries(series, seriesFormat);
+
+      Double[] passX = new Double[] {Common.MIN_FREQUENCY_HZ, Common.MAX_FREQUENCY_HZ};
+      Double[] passY = new Double[] {wavAnalyzerTask.getThreshold(), wavAnalyzerTask.getThreshold()};
+      XYSeries passSeries = new SimpleXYSeries(
+          Arrays.asList(passX), Arrays.asList(passY), "passing");
+      LineAndPointFormatter passSeriesFormat = new LineAndPointFormatter();
+      passSeriesFormat.configure(getApplicationContext(),
+          R.xml.ultrasound_line_formatter_pass);
+      passSeriesFormat.setPointLabelFormatter(null);
+      plot.addSeries(passSeries, passSeriesFormat);
+    }
+  }
+
+  /**
+   * Plays the generated pips.
+   */
+  private void play() {
+    play(SoundGenerator.getInstance().getByte(), Common.PLAYING_SAMPLE_RATE_HZ);
+  }
+
+  /**
+   * Plays the sound data.
+   */
+  private void play(byte[] data, int sampleRate) {
+    if (audioTrack != null) {
+      audioTrack.stop();
+      audioTrack.release();
+    }
+    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
+        sampleRate, AudioFormat.CHANNEL_OUT_MONO,
+        AudioFormat.ENCODING_PCM_16BIT, Math.max(data.length, AudioTrack.getMinBufferSize(
+        sampleRate, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT)),
+        AudioTrack.MODE_STATIC);
+    audioTrack.write(data, 0, data.length);
+    audioTrack.play();
+  }
+
+  /**
+   * AsyncTask class for the analyzing.
+   */
+  private class WavAnalyzerTask extends AsyncTask<Void, String, String>
+      implements WavAnalyzer.Listener {
+
+    private static final String TAG = "WavAnalyzerTask";
+    WavAnalyzer wavAnalyzer;
+
+    public WavAnalyzerTask(byte[] recording) {
+      wavAnalyzer = new WavAnalyzer(recording, Common.RECORDING_SAMPLE_RATE_HZ,
+          WavAnalyzerTask.this);
+    }
+
+    double[] getDB() {
+      return wavAnalyzer.getDB();
+    }
+
+    double[][] getPower() {
+      return wavAnalyzer.getPower();
+    }
+
+    double[] getNoiseDB() {
+      return wavAnalyzer.getNoiseDB();
+    }
+
+    double getThreshold() {
+      return wavAnalyzer.getThreshold();
+    }
+
+    @Override
+    protected String doInBackground(Void... params) {
+      boolean result = wavAnalyzer.doWork();
+      if (result) {
+        return getString(R.string.hifi_ultrasound_test_pass);
+      }
+      return getString(R.string.hifi_ultrasound_test_fail);
+    }
+
+    @Override
+    protected void onPostExecute(String result) {
+      info.append(result);
+      recorderButton.setEnabled(true);
+      if (wavAnalyzer.getResult()) {
+        getPassButton().setEnabled(true);
+      }
+      recorderButton.setText(R.string.hifi_ultrasound_test_plot);
+    }
+
+    @Override
+    protected void onProgressUpdate(String... values) {
+      for (String message : values) {
+        info.append(message);
+        Log.d(TAG, message);
+      }
+    }
+
+    @Override
+    public void sendMessage(String message) {
+      publishProgress(message);
+    }
+  }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java
new file mode 100644
index 0000000..224d4c8
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/NativeAudioThread.java
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.drrickorang.loopback;
+
+package com.android.cts.verifier.audio;
+
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+//import android.media.MediaPlayer;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+import android.util.Log;
+
+import android.os.Handler;
+import  android.os.Message;
+
+/**
+ * A thread/audio track based audio synth.
+ */
+public class NativeAudioThread extends Thread {
+
+    public boolean isRunning = false;
+    double twoPi = 6.28318530718;
+
+    public int mSessionId;
+
+    public double[] mvSamples; //captured samples
+    int mSamplesIndex;
+
+    private final int mSecondsToRun = 2;
+    public int mSamplingRate = 48000;
+    private int mChannelConfigIn = AudioFormat.CHANNEL_IN_MONO;
+    private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+
+    int mMinPlayBufferSizeInBytes = 0;
+    int mMinRecordBuffSizeInBytes = 0;
+    private int mChannelConfigOut = AudioFormat.CHANNEL_OUT_MONO;
+
+    int mMicSource = 0;
+
+//    private double [] samples = new double[50000];
+
+    boolean isPlaying = false;
+    private Handler mMessageHandler;
+    boolean isDestroying = false;
+    boolean hasDestroyingErrors = false;
+
+    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED = 892;
+    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR = 893;
+    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE = 894;
+    static final int NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS = 895;
+
+    public void setParams(int samplingRate, int playBufferInBytes, int recBufferInBytes,
+            int micSource) {
+        mSamplingRate = samplingRate;
+        mMinPlayBufferSizeInBytes = playBufferInBytes;
+        mMinRecordBuffSizeInBytes = recBufferInBytes;
+        mMicSource = micSource;
+    }
+
+    //JNI load
+    static {
+        try {
+            System.loadLibrary("audioloopback_jni");
+        } catch (UnsatisfiedLinkError e) {
+            log("Error loading loopback JNI library");
+            e.printStackTrace();
+        }
+
+        /* TODO: gracefully fail/notify if the library can't be loaded */
+    }
+
+    //jni calls
+    public native long slesInit(int samplingRate, int frameCount, int micSource);
+    public native int slesProcessNext(long sles_data, double[] samples, long offset);
+    public native int slesDestroy(long sles_data);
+
+    public void run() {
+
+        setPriority(Thread.MAX_PRIORITY);
+        isRunning = true;
+
+        //erase output buffer
+        if (mvSamples != null)
+            mvSamples = null;
+
+        //resize
+        int nNewSize = (int)(1.1* mSamplingRate * mSecondsToRun ); //10% more just in case
+        mvSamples = new double[nNewSize];
+        mSamplesIndex = 0; //reset index
+
+        //clear samples
+        for (int i=0; i<nNewSize; i++) {
+            mvSamples[i] = 0;
+        }
+
+        //start playing
+        isPlaying = true;
+
+
+        log(" Started capture test");
+        if (mMessageHandler != null) {
+            Message msg = Message.obtain();
+            msg.what = NATIVE_AUDIO_THREAD_MESSAGE_REC_STARTED;
+            mMessageHandler.sendMessage(msg);
+        }
+
+
+
+        log(String.format("about to init, sampling rate: %d, buffer:%d", mSamplingRate,
+                mMinPlayBufferSizeInBytes/2 ));
+        long sles_data = slesInit(mSamplingRate, mMinPlayBufferSizeInBytes/2, mMicSource);
+        log(String.format("sles_data = 0x%X",sles_data));
+
+        if (sles_data == 0 ) {
+            log(" ERROR at JNI initialization");
+            if (mMessageHandler != null) {
+                Message msg = Message.obtain();
+                msg.what = NATIVE_AUDIO_THREAD_MESSAGE_REC_ERROR;
+                mMessageHandler.sendMessage(msg);
+            }
+        }  else {
+
+            //wait a little bit...
+            try {
+                sleep(10); //just to let it start properly?
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+
+
+
+            mSamplesIndex = 0;
+            int totalSamplesRead = 0;
+            long offset = 0;
+            for (int ii = 0; ii < mSecondsToRun; ii++) {
+                log(String.format("block %d...", ii));
+                int samplesRead = slesProcessNext(sles_data, mvSamples,offset);
+                totalSamplesRead += samplesRead;
+
+                offset += samplesRead;
+                log(" [" + ii + "] jni samples read:" + samplesRead + "  currentOffset:" + offset);
+            }
+
+            log(String.format(" samplesRead: %d, sampleOffset:%d", totalSamplesRead, offset));
+            log(String.format("about to destroy..."));
+
+            runDestroy(sles_data);
+
+            int maxTry = 20;
+            int tryCount = 0;
+            //isDestroying = true;
+            while (isDestroying) {
+
+                try {
+                    sleep(40);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+
+                tryCount++;
+
+                log("destroy try: " + tryCount);
+
+                if (tryCount >= maxTry) {
+                    hasDestroyingErrors = true;
+                    log("WARNING: waited for max time to properly destroy JNI.");
+                    break;
+                }
+            }
+            log(String.format("after destroying. TotalSamplesRead = %d", totalSamplesRead));
+
+            if (totalSamplesRead==0)
+            {
+                hasDestroyingErrors = true;
+            }
+
+            endTest();
+        }
+    }
+
+    public void setMessageHandler(Handler messageHandler) {
+        mMessageHandler = messageHandler;
+    }
+
+    private void runDestroy(final long sles_data ) {
+        isDestroying = true;
+
+        //start thread
+
+        final long local_sles_data = sles_data;
+        ////
+        Thread thread = new Thread(new Runnable() {
+            public void run() {
+                isDestroying = true;
+                log("**Start runnable destroy");
+
+                int status = slesDestroy(local_sles_data);
+                log(String.format("**End runnable destroy sles delete status: %d", status));
+                isDestroying = false;
+            }
+        });
+
+        thread.start();
+
+
+
+        log("end of runDestroy()");
+
+
+    }
+
+    public void togglePlay() {
+
+    }
+
+    public void runTest() {
+
+
+    }
+
+   public void endTest() {
+       log("--Ending capture test--");
+       isPlaying = false;
+
+
+       if (mMessageHandler != null) {
+           Message msg = Message.obtain();
+           if (hasDestroyingErrors)
+               msg.what = NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE_ERRORS;
+           else
+               msg.what = NATIVE_AUDIO_THREAD_MESSAGE_REC_COMPLETE;
+           mMessageHandler.sendMessage(msg);
+       }
+
+   }
+
+    public void finish() {
+
+        if (isRunning) {
+            isRunning = false;
+            try {
+                sleep(20);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private static void log(String msg) {
+        Log.v("Loopback", msg);
+    }
+
+    double [] getWaveData () {
+        return mvSamples;
+    }
+
+}  //end thread.
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/SoundGenerator.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/SoundGenerator.java
new file mode 100644
index 0000000..0ad9371
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/SoundGenerator.java
@@ -0,0 +1,81 @@
+package com.android.cts.verifier.audio;
+
+/**
+ * Sound generator.
+ */
+public class SoundGenerator {
+
+  private static SoundGenerator instance;
+
+  private final byte[] generatedSound;
+  private final double[] sample;
+
+  private SoundGenerator() {
+    // Initialize sample.
+    int pipNum = Common.PIP_NUM;
+    int prefixTotalLength = Util.toLength(Common.PREFIX_LENGTH_S, Common.PLAYING_SAMPLE_RATE_HZ)
+        + Util.toLength(Common.PAUSE_BEFORE_PREFIX_DURATION_S, Common.PLAYING_SAMPLE_RATE_HZ)
+        + Util.toLength(Common.PAUSE_AFTER_PREFIX_DURATION_S, Common.PLAYING_SAMPLE_RATE_HZ);
+    int repetitionLength = pipNum * Util.toLength(
+        Common.PIP_DURATION_S + Common.PAUSE_DURATION_S, Common.PLAYING_SAMPLE_RATE_HZ);
+    int sampleLength = prefixTotalLength + Common.REPETITIONS * repetitionLength;
+    sample = new double[sampleLength];
+
+    // Fill sample with prefix.
+    System.arraycopy(Common.PREFIX_FOR_PLAYER, 0, sample,
+        Util.toLength(Common.PAUSE_BEFORE_PREFIX_DURATION_S, Common.PLAYING_SAMPLE_RATE_HZ),
+        Common.PREFIX_FOR_PLAYER.length);
+
+    // Fill the sample.
+    for (int i = 0; i < pipNum * Common.REPETITIONS; i++) {
+      double[] pip = getPip(Common.WINDOW_FOR_PLAYER, Common.FREQUENCIES[i]);
+      System.arraycopy(pip, 0, sample,
+          prefixTotalLength + i * Util.toLength(
+              Common.PIP_DURATION_S + Common.PAUSE_DURATION_S, Common.PLAYING_SAMPLE_RATE_HZ),
+          pip.length);
+    }
+
+    // Convert sample to byte.
+    generatedSound = new byte[2 * sample.length];
+    int i = 0;
+    for (double dVal : sample) {
+      short val = (short) ((dVal * 32767));
+      generatedSound[i++] = (byte) (val & 0x00ff);
+      generatedSound[i++] = (byte) ((val & 0xff00) >>> 8);
+    }
+  }
+
+  public static SoundGenerator getInstance() {
+    if (instance == null) {
+      instance = new SoundGenerator();
+    }
+    return instance;
+  }
+
+  /**
+   * Gets a pip sample.
+   */
+  private static double[] getPip(double[] window, double frequency) {
+    int pipArrayLength = window.length;
+    double[] pipArray = new double[pipArrayLength];
+    double radPerSample = 2 * Math.PI / (Common.PLAYING_SAMPLE_RATE_HZ / frequency);
+    for (int i = 0; i < pipArrayLength; i++) {
+      pipArray[i] = window[i] * Math.sin(i * radPerSample);
+    }
+    return pipArray;
+  }
+
+  /**
+   * Get generated sound in byte[].
+   */
+  public byte[] getByte() {
+    return generatedSound;
+  }
+
+  /**
+   * Get sample in double[].
+   */
+  public double[] getSample() {
+    return sample;
+  }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/SoundPlayerObject.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/SoundPlayerObject.java
new file mode 100644
index 0000000..23b71c0
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/SoundPlayerObject.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 android.content.Context;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.net.rtp.AudioStream;
+import android.util.Log;
+
+import com.android.cts.verifier.audio.wavelib.PipeShort;
+
+import java.io.IOException;
+
+public class SoundPlayerObject extends Thread {
+    private static final String LOGTAG = "SoundPlayerObject";
+    private MediaPlayer mMediaPlayer;
+    private boolean isInitialized = false;
+    private boolean isRunning = false;
+
+    public PipeShort mPipe = new PipeShort(65536);
+    private short[] mAudioShortArray;
+
+    public AudioTrack mAudioTrack;
+    public int mSamplingRate = 48000;
+    private int mChannelConfigOut = AudioFormat.CHANNEL_OUT_MONO;
+    private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+    int mMinPlayBufferSizeInBytes = 0;
+    int mMinBufferSizeInSamples = 0;
+
+    private int mStreamType = AudioManager.STREAM_MUSIC;
+    private int mResId = -1;
+    private boolean mUseMediaPlayer = true;
+    private float mBalance = 0.5f; //0 left, 1 right
+
+    public int getCurrentResId() {
+        return mResId;
+    }
+
+    public int getStreamType () {
+        return mStreamType;
+    }
+
+    public void run() {
+        setPriority(Thread.MAX_PRIORITY);
+        isRunning = true;
+        while (isRunning) {
+
+            if (!mUseMediaPlayer && isInitialized && isPlaying()) {
+                int valuesAvailable = mPipe.availableToRead();
+                if (valuesAvailable > 0) {
+
+                    int valuesOfInterest = valuesAvailable;
+                    if (mMinBufferSizeInSamples < valuesOfInterest) {
+                        valuesOfInterest = mMinBufferSizeInSamples;
+                    }
+                    mPipe.read(mAudioShortArray, 0,valuesOfInterest);
+                    //inject into output.
+                    mAudioTrack.write(mAudioShortArray, 0, valuesOfInterest);
+                }
+            } else {
+                try {
+                    sleep(10);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public void setBalance(float balance) {
+        mBalance = balance;
+        if (mUseMediaPlayer) {
+            if (mMediaPlayer != null) {
+                float left = Math.min(2.0f * (1.0f - mBalance), 1.0f);
+                float right = Math.min(2.0f * mBalance, 1.0f);
+                mMediaPlayer.setVolume(left, right);
+                log(String.format("Setting balance to %f", mBalance));
+            }
+        }
+    }
+
+    public void setStreamType(int streamType) {
+        mStreamType = streamType;
+    }
+
+    public void rewind() {
+        if (mUseMediaPlayer) {
+            if (mMediaPlayer != null) {
+                mMediaPlayer.seekTo(0);
+            }
+        }
+    }
+
+    public void setSoundWithResId(Context context, int resId) {
+        boolean playing = isPlaying();
+        //release player
+        releasePlayer();
+        mResId = resId;
+        if (mUseMediaPlayer) {
+            mMediaPlayer = new MediaPlayer();
+            try {
+                log("opening resource with stream type: " + mStreamType);
+                mMediaPlayer.setAudioStreamType(mStreamType);
+                mMediaPlayer.setDataSource(context.getApplicationContext(),
+                        Uri.parse("android.resource://com.android.cts.verifier/" + resId));
+                mMediaPlayer.prepare();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+            mMediaPlayer.setLooping(true);
+            setBalance(mBalance);
+        } else {
+            mMinPlayBufferSizeInBytes = AudioTrack.getMinBufferSize(mSamplingRate,
+                    mChannelConfigOut, mAudioFormat);
+
+            mMinBufferSizeInSamples = mMinPlayBufferSizeInBytes / 2;
+            mAudioShortArray = new short[mMinBufferSizeInSamples * 4];
+
+            mAudioTrack = new AudioTrack(mStreamType,
+                    mSamplingRate,
+                    mChannelConfigOut,
+                    mAudioFormat,
+                    mMinPlayBufferSizeInBytes,
+                    AudioTrack.MODE_STREAM /* FIXME runtime test for API level 9 ,
+                mSessionId */);
+            mPipe.flush();
+            isInitialized = true;
+        }
+
+        log("done preparing media player");
+        if (playing)
+            play(true); //start playing if it was playing before
+    }
+
+    public boolean isPlaying() {
+        boolean result = false;
+        if (mUseMediaPlayer) {
+            if (mMediaPlayer != null) {
+                result = mMediaPlayer.isPlaying();
+            }
+        } else {
+            if (mAudioTrack != null) {
+                result = mAudioTrack.getPlayState() == AudioTrack.PLAYSTATE_PLAYING;
+            }
+        }
+        return result;
+    }
+
+    public void play(boolean play) {
+        if (mUseMediaPlayer) {
+            if (mMediaPlayer != null) {
+                if (play) {
+                    mMediaPlayer.start();
+                } else {
+                    mMediaPlayer.pause();
+                }
+            }
+        } else {
+            if (mAudioTrack != null && isInitialized) {
+                if (play) {
+                    mPipe.flush();
+                    mAudioTrack.flush();
+                    mAudioTrack.play();
+                } else {
+                    mAudioTrack.pause();
+                }
+            }
+        }
+    }
+
+    public void finish() {
+        play(false);
+        releasePlayer();
+    }
+
+    private void releasePlayer() {
+        if (mMediaPlayer != null) {
+            mMediaPlayer.stop();
+            mMediaPlayer.release();
+            mMediaPlayer = null;
+        }
+
+        if (mAudioTrack != null) {
+            mAudioTrack.stop();
+            mAudioTrack.release();
+            mAudioTrack = null;
+        }
+        isInitialized = false;
+    }
+
+    /*
+       Misc
+    */
+    private static void log(String msg) {
+        Log.v(LOGTAG, msg);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/TrivialPlayer.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/TrivialPlayer.java
new file mode 100644
index 0000000..af09504
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/TrivialPlayer.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+
+import java.lang.InterruptedException;
+import java.lang.Math;
+import java.lang.Runnable;
+
+public class TrivialPlayer implements Runnable {
+    AudioTrack mAudioTrack;
+    int mBufferSize;
+
+    boolean mPlay;
+    boolean mIsPlaying;
+
+    short[] mAudioData;
+
+    Thread mFillerThread = null;
+
+    public TrivialPlayer() {
+        mBufferSize =
+                AudioTrack.getMinBufferSize(
+                    41000,
+                    AudioFormat.CHANNEL_OUT_STEREO,
+                    AudioFormat.ENCODING_PCM_16BIT);
+        mAudioTrack =
+            new AudioTrack(
+                AudioManager.STREAM_MUSIC,
+                41000,
+                AudioFormat.CHANNEL_OUT_STEREO,
+                AudioFormat.ENCODING_PCM_16BIT,
+                mBufferSize,
+                AudioTrack.MODE_STREAM);
+
+        mPlay = false;
+        mIsPlaying = false;
+
+        // setup audio data (silence will suffice)
+        mAudioData = new short[mBufferSize];
+        for (int index = 0; index < mBufferSize; index++) {
+            // mAudioData[index] = 0;
+            // keep this code since one might want to hear the playnig audio
+            // for debugging/verification.
+            mAudioData[index] =
+                (short)(((Math.random() * 2.0) - 1.0) * (double)Short.MAX_VALUE/2.0);
+        }
+    }
+
+    public AudioTrack getAudioTrack() { return mAudioTrack; }
+
+    public boolean isPlaying() {
+        synchronized (this) {
+            return mIsPlaying;
+        }
+    }
+
+    public void start() {
+        mPlay = true;
+        mFillerThread = new Thread(this);
+        mFillerThread.start();
+    }
+
+    public void stop() {
+        mPlay = false;
+        mFillerThread = null;
+    }
+
+    public void shutDown() {
+        stop();
+        while (isPlaying()) {
+            try {
+                Thread.sleep(10);
+            } catch (InterruptedException ex) {
+            }
+        }
+        mAudioTrack.release();
+    }
+
+    @Override
+    public void run() {
+        mAudioTrack.play();
+        synchronized (this) {
+            mIsPlaying = true;
+        }
+        while (mAudioTrack != null && mPlay) {
+            mAudioTrack.write(mAudioData, 0, mBufferSize);
+        }
+        synchronized (this) {
+            mIsPlaying = false;
+        }
+        mAudioTrack.stop();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/TrivialRecorder.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/TrivialRecorder.java
new file mode 100644
index 0000000..f684681
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/TrivialRecorder.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 com.android.cts.verifier.audio;
+
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+
+import android.media.MediaRecorder;
+
+import java.lang.InterruptedException;
+import java.lang.Runnable;
+
+public class TrivialRecorder implements Runnable {
+    AudioRecord mAudioRecord;
+    int mBufferSize;
+
+    boolean mRecord;
+    boolean mIsRecording;
+
+    short[] mAudioData;
+
+    Thread mReaderThread = null;
+
+    public TrivialRecorder() {
+        mBufferSize =
+                AudioRecord.getMinBufferSize(
+                    41000,
+                    AudioFormat.CHANNEL_IN_MONO,
+                    AudioFormat.ENCODING_PCM_16BIT);
+        mAudioRecord =
+            new AudioRecord(
+                MediaRecorder.AudioSource.DEFAULT,
+                41000,
+                AudioFormat.CHANNEL_IN_MONO,
+                AudioFormat.ENCODING_PCM_16BIT,
+                mBufferSize);
+
+        mRecord = false;
+        mIsRecording = false;
+
+        // setup audio data (silence will suffice)
+        mAudioData = new short[mBufferSize];
+    }
+
+    public AudioRecord getAudioRecord() { return mAudioRecord; }
+
+    public boolean mIsRecording() {
+        synchronized (this) {
+            return mIsRecording;
+        }
+    }
+
+    public void start() {
+        mRecord = true;
+        mReaderThread = new Thread(this);
+        mReaderThread.start();
+    }
+
+    public void stop() {
+        mRecord = false;
+        mReaderThread = null;
+    }
+
+    public void shutDown() {
+        stop();
+        while (mIsRecording()) {
+            try {
+                Thread.sleep(10);
+            } catch (InterruptedException ex) {
+            }
+        }
+        mAudioRecord.release();
+    }
+
+    @Override
+    public void run() {
+        mAudioRecord.startRecording();
+        synchronized (this) {
+            mIsRecording = true;
+        }
+       while (mRecord) {
+            mAudioRecord.read(mAudioData, 0, mBufferSize);
+        }
+        mAudioRecord.stop();
+        synchronized (this) {
+            mIsRecording = false;
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/UsbMicrophoneTester.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/UsbMicrophoneTester.java
new file mode 100644
index 0000000..c0b6b6a
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/UsbMicrophoneTester.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 android.content.Context;
+
+import android.hardware.usb.UsbAccessory;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+public class UsbMicrophoneTester {
+
+    public static String getUSBDeviceListString(Context context) {
+        UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
+        StringBuilder sb = new StringBuilder();
+        HashMap<String, UsbDevice> devicelist = manager.getDeviceList();
+        for(UsbDevice usbDevice : devicelist.values()) {
+            sb.append("Model    : " + usbDevice.getDeviceName() + "\n");
+            sb.append(" Id      : " + usbDevice.getDeviceId() + "\n");
+            sb.append(" Class   : " + usbDevice.getDeviceClass() + "\n");
+            sb.append(" Prod.Id : " + usbDevice.getProductId() + "\n");
+            sb.append(" Vendor.Id : " + usbDevice.getVendorId() + "\n");
+            int iCount = usbDevice.getInterfaceCount();
+            for (int i = 0; i < iCount; i++) {
+                UsbInterface usbInterface = usbDevice.getInterface(i);
+                sb.append("    Interface " + i + " :\n");
+                sb.append("     Class: " + usbInterface.getInterfaceClass() + "\n");
+            }
+        }
+        return sb.toString();
+    }
+
+    public static boolean getIsMicrophoneConnected(Context context) {
+        UsbManager manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
+        StringBuilder sb = new StringBuilder();
+        HashMap<String, UsbDevice> devicelist = manager.getDeviceList();
+        for(UsbDevice usbDevice : devicelist.values()) {
+            int iCount = usbDevice.getInterfaceCount();
+            for (int i = 0; i < iCount; i++) {
+                UsbInterface usbInterface = usbDevice.getInterface(i);
+                if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_AUDIO) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/Util.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Util.java
new file mode 100644
index 0000000..4ef62d9
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/Util.java
@@ -0,0 +1,152 @@
+package com.android.cts.verifier.audio;
+
+import org.apache.commons.math.complex.Complex;
+import org.apache.commons.math.stat.descriptive.moment.Mean;
+import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
+import org.apache.commons.math.stat.descriptive.rank.Median;
+import org.apache.commons.math.transform.FastFourierTransformer;
+
+/**
+ * This class contains util functions used in the WavAnalyzer.
+ */
+public class Util {
+
+  /**
+   * Convert time in second to sample array length.
+   */
+  public static int toLength(double duration, int sampleRate) {
+    return (int) Math.round(duration * sampleRate);
+  }
+
+  /**
+   * Calculate mean of data.
+   */
+  public static double mean(double[] data) {
+    Mean mean = new Mean();
+    return mean.evaluate(data);
+  }
+
+  /**
+   * Calculate standard deviation of data.
+   */
+  public static double std(double[] data) {
+    StandardDeviation std = new StandardDeviation();
+    return std.evaluate(data);
+  }
+
+  /**
+   * Calculate median of data.
+   */
+  public static double median(double[] data) {
+    Median median = new Median();
+    median.setData(data);
+    return median.evaluate();
+  }
+
+  /**
+   * Pad zeros at the end, total length of array will be specified as length. If length is smaller
+   * than the length of the data, it returns the data truncated to the length.
+   */
+  public static Complex[] padZeros(Complex[] data, int length) {
+    Complex[] result = new Complex[length];
+    if (length < data.length) {
+      System.arraycopy(data, 0, result, 0, length);
+    } else {
+      System.arraycopy(data, 0, result, 0, data.length);
+      for (int i = data.length; i < result.length; i++) {
+        result[i] = new Complex(0, 0);
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Calculate cross correlation using FFT with periodic boundary handling.
+   */
+  public static double[] computeCrossCorrelation(Complex[] data1, Complex[] data2) {
+    FastFourierTransformer fft = new FastFourierTransformer();
+    int n = nextPowerOfTwo(Math.max(data1.length, data2.length));
+    Complex[] data1Fft = fft.transform(padZeros(data1, n));
+    Complex[] data2Fft = fft.transform(padZeros(data2, n));
+    Complex[] dottedData = new Complex[n];
+    for (int i = 0; i < n; i++) {
+      dottedData[i] = data1Fft[i].multiply(data2Fft[i].conjugate());
+    }
+    Complex[] resultComplex = fft.inversetransform(dottedData);
+    double[] resultDouble = new double[resultComplex.length];
+    for (int i = 0; i < resultComplex.length; i++) {
+      resultDouble[i] = resultComplex[i].abs();
+    }
+    return resultDouble;
+  }
+
+  /**
+   * Convert an short array to a double array.
+   */
+  public static double[] toDouble(short[] data) {
+    double[] result = new double[data.length];
+    for (int i = 0; i < data.length; i++) {
+      result[i] = data[i];
+    }
+    return result;
+  }
+
+  /**
+   * Convert a double array to a complex array.
+   */
+  public static Complex[] toComplex(double[] data) {
+    Complex[] result = new Complex[data.length];
+    for (int i = 0; i < data.length; i++) {
+      result[i] = new Complex(data[i], 0.0);
+    }
+    return result;
+  }
+
+  /**
+   * Calculates the next power of 2, greater than or equal to the input positive integer. If the
+   * input is not a positive integer, it returns 1.
+   */
+  public static int nextPowerOfTwo(int n) {
+    return 1 << (32 - Integer.numberOfLeadingZeros(n - 1));
+  }
+
+  /**
+   * Find the index with the max value in an array.
+   */
+  public static int findMaxIndex(double[] data) {
+    return findMaxIndex(data, 0, data.length - 1);
+  }
+
+  /**
+   * Find the index with the max value in a sub-array.
+   */
+  public static int findMaxIndex(double[] data, int startIndex, int endIndex) {
+    int maxIndex = startIndex;
+    for (int i = startIndex + 1; i <= endIndex; i++) {
+      if (data[i] > data[maxIndex]) {
+        maxIndex = i;
+      }
+    }
+    return maxIndex;
+  }
+
+  /**
+   * Returns the index of an array with the array value closest to the desired value.
+   */
+  public static int findClosest(double[] array, double value) {
+    double[] diffArray = new double[array.length];
+    for (int i = 0; i < array.length; i++) {
+      diffArray[i] = Math.abs(value - array[i]);
+    }
+    int index = 0;
+    for (int i = 1; i < array.length; i++) {
+      if (diffArray[i] < diffArray[index]) {
+        index = i;
+        if (diffArray[index] == 0) {
+          break;
+        }
+      }
+    }
+    return index;
+  }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/WavAnalyzer.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/WavAnalyzer.java
new file mode 100644
index 0000000..b75c40b
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/WavAnalyzer.java
@@ -0,0 +1,263 @@
+package com.android.cts.verifier.audio;
+
+import org.apache.commons.math.complex.Complex;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+/**
+ * Class contains the analysis to calculate frequency response.
+ */
+public class WavAnalyzer {
+  private final Listener listener;
+  private final int sampleRate;  // Recording sampling rate.
+  private double[] data;  // Whole recording data.
+  private double[] dB;  // Average response
+  private double[][] power;  // power of each trial
+  private double[] noiseDB;  // background noise
+  private double[][] noisePower;
+  private double threshold;  // threshold of passing, drop off compared to 2000 kHz
+  private boolean result = false;  // result of the test
+
+  /**
+   * Constructor of WavAnalyzer.
+   */
+  public WavAnalyzer(byte[] byteData, int sampleRate, Listener listener) {
+    this.listener = listener;
+    this.sampleRate = sampleRate;
+
+    short[] shortData = new short[byteData.length >> 1];
+    ByteBuffer.wrap(byteData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shortData);
+    this.data = Util.toDouble(shortData);
+    for (int i = 0; i < data.length; i++) {
+      data[i] = data[i] / Short.MAX_VALUE;
+    }
+  }
+
+  /**
+   * Do the analysis. Returns true if passing, false if failing.
+   */
+  public boolean doWork() {
+    if (isClipped()) {
+      return false;
+    }
+    // Calculating the pip strength.
+    listener.sendMessage("Calculating... Please wait...\n");
+    try {
+      dB = measurePipStrength();
+    } catch (IndexOutOfBoundsException e) {
+      listener.sendMessage("WARNING: May have missed the prefix."
+          + " Turn up the volume of the playback device or move to a quieter location.\n");
+      return false;
+    }
+    if (!isConsistent()) {
+      return false;
+    }
+    result = responsePassesHifiTest(dB);
+    return result;
+  }
+
+  /**
+   * Check if the recording is clipped.
+   */
+  boolean isClipped() {
+    for (int i = 1; i < data.length; i++) {
+      if ((Math.abs(data[i]) >= Short.MAX_VALUE) && (Math.abs(data[i - 1]) >= Short.MAX_VALUE)) {
+        listener.sendMessage("WARNING: Data is clipped."
+            + " Turn down the volume of the playback device and redo the procedure.\n");
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Check if the result is consistant across trials.
+   */
+  boolean isConsistent() {
+    double[] coeffOfVar = new double[Common.PIP_NUM];
+    for (int i = 0; i < Common.PIP_NUM; i++) {
+      double[] powerAtFreq = new double[Common.REPETITIONS];
+      for (int j = 0; j < Common.REPETITIONS; j++) {
+        powerAtFreq[j] = power[i][j];
+      }
+      coeffOfVar[i] = Util.std(powerAtFreq) / Util.mean(powerAtFreq);
+    }
+    if (Util.mean(coeffOfVar) > 1.0) {
+      listener.sendMessage("WARNING: Inconsistent result across trials."
+          + " Turn up the volume of the playback device or move to a quieter location.\n");
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Determine test pass/fail using the frequency response. Package visible for unit testing.
+   */
+  boolean responsePassesHifiTest(double[] dB) {
+    for (int i = 0; i < dB.length; i++) {
+      // Precautionary; NaN should not happen.
+      if (Double.isNaN(dB[i])) {
+        listener.sendMessage(
+            "WARNING: Unexpected NaN in result. Redo the test.\n");
+        return false;
+      }
+    }
+
+    if (Util.mean(dB) - Util.mean(noiseDB) < Common.SIGNAL_MIN_STRENGTH_DB_ABOVE_NOISE) {
+      listener.sendMessage("WARNING: Signal is too weak or background noise is too strong."
+          + " Turn up the volume of the playback device or move to a quieter location.\n");
+      return false;
+    }
+
+    int indexOf2000Hz = Util.findClosest(Common.FREQUENCIES_ORIGINAL, 2000.0);
+    threshold = dB[indexOf2000Hz] + Common.PASSING_THRESHOLD_DB;
+    int indexOf18500Hz = Util.findClosest(Common.FREQUENCIES_ORIGINAL, 18500.0);
+    int indexOf20000Hz = Util.findClosest(Common.FREQUENCIES_ORIGINAL, 20000.0);
+    double[] responseInRange = new double[indexOf20000Hz - indexOf18500Hz];
+    System.arraycopy(dB, indexOf18500Hz, responseInRange, 0, responseInRange.length);
+    if (Util.mean(responseInRange) < threshold) {
+      listener.sendMessage(
+          "WARNING: Failed. Retry with different orientations or report failed.\n");
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Calculate the Fourier Coefficient at the pip frequency to calculate the frequency response.
+   * Package visible for unit testing.
+   */
+  double[] measurePipStrength() {
+    listener.sendMessage("Aligning data... Please wait...\n");
+    final int dataStartI = alignData();
+    final int prefixTotalLength = dataStartI
+        + Util.toLength(Common.PREFIX_LENGTH_S + Common.PAUSE_AFTER_PREFIX_DURATION_S, sampleRate);
+    listener.sendMessage("Done.\n");
+    listener.sendMessage("Prefix starts at " + (double) dataStartI / sampleRate + " s \n");
+    if (dataStartI > Math.round(sampleRate * (Common.PREFIX_LENGTH_S
+            + Common.PAUSE_BEFORE_PREFIX_DURATION_S + Common.PAUSE_AFTER_PREFIX_DURATION_S))) {
+      listener.sendMessage("WARNING: Unexpected prefix start time. May have missed the prefix.\n"
+          + "PLAY button should be pressed on the playback device within one second"
+          + " after RECORD is pressed on the recording device.\n"
+          + "If this happens repeatedly,"
+          + " turn up the volume of the playback device or move to a quieter location.\n");
+    }
+
+    listener.sendMessage("Analyzing noise strength... Please wait...\n");
+    noisePower = new double[Common.PIP_NUM][Common.NOISE_SAMPLES];
+    noiseDB = new double[Common.PIP_NUM];
+    for (int s = 0; s < Common.NOISE_SAMPLES; s++) {
+      double[] noisePoints = new double[Common.WINDOW_FOR_RECORDER.length];
+      System.arraycopy(data, dataStartI - (s + 1) * noisePoints.length - 1,
+          noisePoints, 0, noisePoints.length);
+      for (int j = 0; j < noisePoints.length; j++) {
+        noisePoints[j] = noisePoints[j] * Common.WINDOW_FOR_RECORDER[j];
+      }
+      for (int i = 0; i < Common.PIP_NUM; i++) {
+        double freq = Common.FREQUENCIES_ORIGINAL[i];
+        Complex fourierCoeff = new Complex(0, 0);
+        final Complex rotator = new Complex(0,
+            -2.0 * Math.PI * freq / sampleRate).exp();
+        Complex phasor = new Complex(1, 0);
+        for (int j = 0; j < noisePoints.length; j++) {
+          fourierCoeff = fourierCoeff.add(phasor.multiply(noisePoints[j]));
+          phasor = phasor.multiply(rotator);
+        }
+        fourierCoeff = fourierCoeff.multiply(1.0 / noisePoints.length);
+        noisePower[i][s] = fourierCoeff.multiply(fourierCoeff.conjugate()).abs();
+      }
+    }
+    for (int i = 0; i < Common.PIP_NUM; i++) {
+      double meanNoisePower = 0;
+      for (int j = 0; j < Common.NOISE_SAMPLES; j++) {
+        meanNoisePower += noisePower[i][j];
+      }
+      meanNoisePower /= Common.NOISE_SAMPLES;
+      noiseDB[i] = 10 * Math.log10(meanNoisePower);
+    }
+
+    listener.sendMessage("Analyzing pips... Please wait...\n");
+    power = new double[Common.PIP_NUM][Common.REPETITIONS];
+    for (int i = 0; i < Common.PIP_NUM * Common.REPETITIONS; i++) {
+      if (i % Common.PIP_NUM == 0) {
+        listener.sendMessage("#" + (i / Common.PIP_NUM + 1) + "\n");
+      }
+
+      int pipExpectedStartI;
+      pipExpectedStartI = prefixTotalLength
+          + Util.toLength(i * (Common.PIP_DURATION_S + Common.PAUSE_DURATION_S), sampleRate);
+      // Cut out the data points for the current pip.
+      double[] pipPoints = new double[Common.WINDOW_FOR_RECORDER.length];
+      System.arraycopy(data, pipExpectedStartI, pipPoints, 0, pipPoints.length);
+      for (int j = 0; j < Common.WINDOW_FOR_RECORDER.length; j++) {
+        pipPoints[j] = pipPoints[j] * Common.WINDOW_FOR_RECORDER[j];
+      }
+      Complex fourierCoeff = new Complex(0, 0);
+      final Complex rotator = new Complex(0,
+          -2.0 * Math.PI * Common.FREQUENCIES[i] / sampleRate).exp();
+      Complex phasor = new Complex(1, 0);
+      for (int j = 0; j < pipPoints.length; j++) {
+        fourierCoeff = fourierCoeff.add(phasor.multiply(pipPoints[j]));
+        phasor = phasor.multiply(rotator);
+      }
+      fourierCoeff = fourierCoeff.multiply(1.0 / pipPoints.length);
+      int j = Common.ORDER[i];
+      power[j % Common.PIP_NUM][j / Common.PIP_NUM] =
+          fourierCoeff.multiply(fourierCoeff.conjugate()).abs();
+    }
+
+    // Calculate median of trials.
+    double[] dB = new double[Common.PIP_NUM];
+    for (int i = 0; i < Common.PIP_NUM; i++) {
+      dB[i] = 10 * Math.log10(Util.median(power[i]));
+    }
+    return dB;
+  }
+
+  /**
+   * Align data using prefix. Package visible for unit testing.
+   */
+  int alignData() {
+    // Zeropadding samples to add in the correlation to avoid FFT wraparound.
+    final int zeroPad = Util.toLength(Common.PREFIX_LENGTH_S, Common.RECORDING_SAMPLE_RATE_HZ) - 1;
+    int fftSize = Util.nextPowerOfTwo((int) Math.round(sampleRate * (Common.PREFIX_LENGTH_S
+            + Common.PAUSE_BEFORE_PREFIX_DURATION_S + Common.PAUSE_AFTER_PREFIX_DURATION_S + 0.5))
+        + zeroPad);
+
+    double[] dataCut = new double[fftSize - zeroPad];
+    System.arraycopy(data, 0, dataCut, 0, fftSize - zeroPad);
+    double[] xCorrDataPrefix = Util.computeCrossCorrelation(
+        Util.padZeros(Util.toComplex(dataCut), fftSize),
+        Util.padZeros(Util.toComplex(Common.PREFIX_FOR_RECORDER), fftSize));
+    return Util.findMaxIndex(xCorrDataPrefix);
+  }
+
+  double[] getDB() {
+    return dB;
+  }
+
+  double[][] getPower() {
+    return power;
+  }
+
+  double[] getNoiseDB() {
+    return noiseDB;
+  }
+
+  double getThreshold() {
+    return threshold;
+  }
+
+  boolean getResult() {
+    return result;
+  }
+
+  /**
+   * An interface for listening a message publishing the progress of the analyzer.
+   */
+  public interface Listener {
+
+    void sendMessage(String message);
+  }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferBase.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferBase.java
new file mode 100644
index 0000000..0a8bdde
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferBase.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.cts.verifier.audio.wavelib;
+
+public abstract class DspBufferBase {
+    private int mSize;
+
+    public DspBufferBase() {
+        setSize(0);
+    }
+
+    public DspBufferBase(int size) {
+        setSize(size);
+    }
+
+    public int getSize() {
+        return mSize;
+    }
+
+    public void setSize(int size) {
+        mSize = size;
+    }
+
+    public abstract void setValue(int index, double value);
+
+    public abstract void setValues(int index, double... values);
+
+    @Override
+    public String toString() {
+        return String.format("Size: %d", mSize);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferComplex.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferComplex.java
new file mode 100644
index 0000000..2b71343
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferComplex.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.cts.verifier.audio.wavelib;
+
+public class DspBufferComplex extends DspBufferBase {
+    public double[] mReal;
+    public double[] mImag;
+
+    public DspBufferComplex(int size) {
+        super(size);
+    }
+
+    @Override
+    public void setSize(int size) {
+        if (size == getSize()) {
+            return;
+        }
+        mReal = new double[size];
+        mImag = new double[size];
+        super.setSize(size);
+    }
+
+    // Warning, these methods don't check for bounds!
+    @Override
+    public void setValues(int index, double... values) {
+        mReal[index] = values[0];
+        mImag[index] = values[1];
+    }
+
+    @Override
+    public void setValue(int index, double value) {
+        mReal[index] = value;
+        mImag[index] = 0;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        int size = getSize();
+        sb.append(String.format("Size: %d { ", size));
+        for (int i = 0; i < size; i++) {
+            sb.append(String.format("(%.3f, %3f) ", mReal[i], mImag[i]));
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferDouble.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferDouble.java
new file mode 100644
index 0000000..1b75da6
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferDouble.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.cts.verifier.audio.wavelib;
+
+public class DspBufferDouble extends DspBufferBase {
+    public double[] mData;
+
+    public DspBufferDouble(int size) {
+        super(size);
+    }
+
+    @Override
+    public void setSize(int size) {
+        if (size == getSize()) {
+            return;
+        }
+        mData = new double[size];
+        super.setSize(size);
+    }
+
+    // Warning, these methods don't check for bounds!
+    @Override
+    public void setValues(int index, double... values) {
+        mData[index] = values[0];
+    }
+
+    @Override
+    public void setValue(int index, double value) {
+        mData[index] = value;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        int size = getSize();
+        sb.append(String.format("Size: %d { ", size));
+        int i = 0;
+        for (; i < size - 1; i++) {
+            sb.append(String.format("%.3f, ", mData[i]));
+        }
+        for(; i < size; i++) {
+            sb.append(String.format("%.3f", mData[i]));
+        }
+        sb.append(" }");
+        return sb.toString();
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferMath.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferMath.java
new file mode 100644
index 0000000..a9cbbd0
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspBufferMath.java
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.wavelib;
+
+import android.util.Log;
+
+public class DspBufferMath {
+    private static final String TAG = "DspBufferMath";
+    public static final int OPERANDS_TYPE_UNKNOWN  = -1;
+    public static final int OPERANDS_TYPE_REAL     = 0;
+    public static final int OPERANDS_TYPE_COMPLEX  = 1;
+    public static final int OPERANDS_TYPE_MIXED    = 2;
+
+    public static final int MATH_RESULT_UNDEFINED  = -1;
+    public static final int MATH_RESULT_SUCCESS    = 0;
+    public static final int MATH_RESULT_ERROR      = 1;
+
+    static private<T extends DspBufferBase> int estimateOperandsType(T a, T b) {
+        if (a instanceof DspBufferComplex) {
+            if (b instanceof DspBufferComplex) {
+                return OPERANDS_TYPE_COMPLEX;
+            } else if (b instanceof DspBufferDouble) {
+                return OPERANDS_TYPE_MIXED;
+            }
+        } else if (a instanceof DspBufferDouble) {
+            if (b instanceof DspBufferComplex) {
+                return OPERANDS_TYPE_MIXED;
+            } else if (b instanceof DspBufferDouble) {
+                return OPERANDS_TYPE_REAL;
+            }
+        }
+        return OPERANDS_TYPE_UNKNOWN;
+    }
+
+    /**
+     * adds r = a + b; element by element
+     *
+     * If the result is double vector, the imaginary part of complex operations is ignored.
+     */
+    static public <T extends DspBufferBase> int add(T r, T a, T b) {
+        int size = Math.min(a.getSize(), b.getSize());
+        r.setSize(size);
+
+        T x = a;
+        T y = b;
+        int opType = estimateOperandsType(a, b);
+
+        if (opType == OPERANDS_TYPE_MIXED) {
+            if (a instanceof  DspBufferDouble)  {
+                x = b; //Complex first
+                y = a;
+            }
+        }
+
+        if (opType == OPERANDS_TYPE_UNKNOWN) {
+            return MATH_RESULT_UNDEFINED;
+        }
+
+        if (r instanceof DspBufferComplex) {
+            switch (opType) {
+                case OPERANDS_TYPE_REAL:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferComplex) r).mReal[i] =
+                                ((DspBufferDouble) x).mData[i] + ((DspBufferDouble) y).mData[i];
+                        ((DspBufferComplex) r).mImag[i] = 0;
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_COMPLEX:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferComplex) r).mReal[i] =
+                                ((DspBufferComplex) x).mReal[i] + ((DspBufferComplex) y).mReal[i];
+                        ((DspBufferComplex) r).mImag[i] =
+                                ((DspBufferComplex) x).mImag[i] + ((DspBufferComplex) y).mImag[i];
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_MIXED:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferComplex) r).mReal[i] =
+                                ((DspBufferComplex) x).mReal[i] + ((DspBufferDouble) y).mData[i];
+                        ((DspBufferComplex) r).mImag[i] = ((DspBufferComplex) x).mImag[i];
+                    }
+                    return MATH_RESULT_SUCCESS;
+            }
+        } else if (r instanceof DspBufferDouble) {
+            switch (opType) {
+                case OPERANDS_TYPE_REAL:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferDouble) r).mData[i] =
+                                ((DspBufferDouble) x).mData[i] + ((DspBufferDouble) y).mData[i];
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_COMPLEX:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferDouble) r).mData[i] =
+                                ((DspBufferComplex) x).mReal[i] + ((DspBufferComplex) y).mReal[i];
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_MIXED:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferDouble) r).mData[i] =
+                                ((DspBufferComplex) x).mReal[i] + ((DspBufferDouble) y).mData[i];
+                    }
+                    return MATH_RESULT_SUCCESS;
+            }
+        }
+        return MATH_RESULT_ERROR;
+    }
+
+    /**
+     * mult r = a * b; element by element
+     */
+    static public <T extends DspBufferBase> int mult(T r, T a, T b) {
+        int size = Math.min(a.getSize(), b.getSize());
+        r.setSize(size);
+
+        T x = a;
+        T y = b;
+        int opType = estimateOperandsType(a, b);
+
+        if (opType == OPERANDS_TYPE_MIXED) {
+            if (a instanceof  DspBufferDouble)  {
+                x = b; //Complex first
+                y = a;
+            }
+        }
+
+        if (opType == OPERANDS_TYPE_UNKNOWN) {
+            return MATH_RESULT_UNDEFINED;
+        }
+
+        if (r instanceof DspBufferComplex) {
+            switch (opType) {
+                case OPERANDS_TYPE_REAL:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferComplex) r).mReal[i] =
+                                ((DspBufferDouble) x).mData[i] * ((DspBufferDouble) y).mData[i];
+                        ((DspBufferComplex) r).mImag[i] = 0;
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_COMPLEX:
+                    for (int i = 0; i < size; i++) {
+                        double A = ((DspBufferComplex) x).mReal[i];
+                        double B = ((DspBufferComplex) x).mImag[i];
+                        double C = ((DspBufferComplex) y).mReal[i];
+                        double D = ((DspBufferComplex) y).mImag[i];
+                        ((DspBufferComplex) r).mReal[i] = (C * A) - (B * D);
+                        ((DspBufferComplex) r).mImag[i] = (C * B) + (A * D);
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_MIXED:
+                    for (int i = 0; i < size; i++) {
+                        double A = ((DspBufferComplex) x).mReal[i];
+                        double B = ((DspBufferComplex) x).mImag[i];
+                        double C = ((DspBufferDouble) y).mData[i];
+                        //double D = 0;
+                        ((DspBufferComplex) r).mReal[i] = C * A;
+                        ((DspBufferComplex) r).mImag[i] = C * B;
+                    }
+                    return MATH_RESULT_SUCCESS;
+            }
+        } else if (r instanceof DspBufferDouble) {
+            switch (opType) {
+                case OPERANDS_TYPE_REAL:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferDouble) r).mData[i] =
+                                ((DspBufferDouble) x).mData[i] * ((DspBufferDouble) y).mData[i];
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_COMPLEX:
+                    for (int i = 0; i < size; i++) {
+                        double A = ((DspBufferComplex) x).mReal[i];
+                        double B = ((DspBufferComplex) x).mImag[i];
+                        double C = ((DspBufferComplex) y).mReal[i];
+                        double D = ((DspBufferComplex) y).mImag[i];
+                        ((DspBufferDouble) r).mData[i] = (C * A) - (B * D);
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_MIXED:
+                    for (int i = 0; i < size; i++) {
+                        double A = ((DspBufferComplex) x).mReal[i];
+                        double B = ((DspBufferComplex) x).mImag[i];
+                        double C = ((DspBufferDouble) y).mData[i];
+                        //double D = 0;
+                        ((DspBufferDouble) r).mData[i] = C * A;
+                    }
+                    return MATH_RESULT_SUCCESS;
+            }
+        }
+        return MATH_RESULT_ERROR;
+    }
+
+    /**
+     * mult r = a * v; element by element
+     */
+    static public <T extends DspBufferBase> int mult(T r, T a, double v) {
+        int size = a.getSize();
+        r.setSize(size);
+
+        T x = a;
+        int opType = estimateOperandsType(r, a);
+
+        if (opType == OPERANDS_TYPE_UNKNOWN) {
+            return MATH_RESULT_UNDEFINED;
+        }
+
+        if (r instanceof DspBufferComplex) {
+            switch (opType) {
+                case OPERANDS_TYPE_MIXED:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferComplex) r).mReal[i] = ((DspBufferDouble) x).mData[i] * v;
+                        ((DspBufferComplex) r).mImag[i] = 0;
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_COMPLEX:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferComplex) r).mReal[i] = ((DspBufferComplex) x).mReal[i] * v;
+                        ((DspBufferComplex) r).mImag[i] = ((DspBufferComplex) x).mImag[i] * v;
+                    }
+                    return MATH_RESULT_SUCCESS;
+            }
+        } else if (r instanceof DspBufferDouble) {
+            switch (opType) {
+                case OPERANDS_TYPE_REAL:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferDouble) r).mData[i] = ((DspBufferDouble) x).mData[i] * v;
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_MIXED:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferDouble) r).mData[i] = ((DspBufferComplex) x).mReal[i] * v;
+                    }
+                    return MATH_RESULT_SUCCESS;
+            }
+        }
+        return MATH_RESULT_ERROR;
+    }
+
+    /**
+     * set r = a ; element by element
+     */
+    static public <T extends DspBufferBase> int set(T r, T a) {
+        int size = a.getSize();
+        r.setSize(size);
+
+        T x = a;
+        int opType = estimateOperandsType(r, a);
+
+        if (opType == OPERANDS_TYPE_UNKNOWN) {
+            return MATH_RESULT_UNDEFINED;
+        }
+
+        if (r instanceof DspBufferComplex) {
+            switch (opType) {
+                case OPERANDS_TYPE_MIXED:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferComplex) r).mReal[i] = ((DspBufferDouble) x).mData[i];
+                        ((DspBufferComplex) r).mImag[i] = 0;
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_COMPLEX:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferComplex) r).mReal[i] = ((DspBufferComplex) x).mReal[i];
+                        ((DspBufferComplex) r).mImag[i] = ((DspBufferComplex) x).mImag[i];
+                    }
+                    return MATH_RESULT_SUCCESS;
+            }
+        } else if (r instanceof DspBufferDouble) {
+            switch(opType) {
+                case OPERANDS_TYPE_REAL:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferDouble) r).mData[i] = ((DspBufferDouble) x).mData[i];
+                    }
+                    return MATH_RESULT_SUCCESS;
+                case OPERANDS_TYPE_MIXED:
+                    for (int i = 0; i < size; i++) {
+                        ((DspBufferDouble) r).mData[i] = ((DspBufferComplex) x).mReal[i];
+                    }
+                    return MATH_RESULT_SUCCESS;
+            }
+        }
+        return MATH_RESULT_ERROR;
+    }
+
+
+    /**
+     * set r = v ; all elements the same
+     * It keeps the size of the return vector
+     */
+    static public <T extends DspBufferBase> int set(T r, double ...values) {
+        int size = r.getSize();
+
+        double a = 0;
+        double b = 0;
+        if (values.length > 0) {
+            a = values[0];
+        }
+        if (values.length > 1) {
+            b = values[1];
+        }
+
+        if (r instanceof DspBufferComplex) {
+            for (int i = 0; i < size; i++) {
+                ((DspBufferComplex) r).mReal[i] = a;
+                ((DspBufferComplex) r).mImag[i] = b;
+            }
+            return MATH_RESULT_SUCCESS;
+        } else if (r instanceof DspBufferDouble) {
+            for (int i = 0; i < size; i++) {
+                ((DspBufferDouble) r).mData[i] = a;
+            }
+            return MATH_RESULT_SUCCESS;
+        }
+        return MATH_RESULT_ERROR;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspFftServer.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspFftServer.java
new file mode 100644
index 0000000..09337f1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspFftServer.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.cts.verifier.audio.wavelib;
+
+public class DspFftServer {
+    private int mN = 0;
+    private int mOrder = 0;
+
+    DspBufferDouble mCos;
+    DspBufferDouble mSin;
+    public boolean isInitialized = false;
+
+    public DspFftServer(int size) {
+        init(size);
+    }
+
+    public boolean init(int size) {
+        boolean status = false;
+        mN=size;
+
+        mOrder = (int) (Math.log(mN) / Math.log(2));
+        if (mN == (1 << mOrder)) {
+            mCos = new DspBufferDouble(mN / 2);
+            mSin = new DspBufferDouble(mN / 2);
+            for (int i = 0; i < mN / 2; i++) {
+                mCos.mData[i] = Math.cos(-2 * Math.PI * i / mN);
+                mSin.mData[i] = Math.sin(-2 * Math.PI * i / mN);
+            }
+            status = true;
+        } else {
+            mN = 0;
+            throw new RuntimeException("FFT must be power of 2");
+        }
+        isInitialized = status;
+        return status;
+    }
+
+    public void fft(DspBufferComplex r, int sign) {
+        int ii, jj, kk, n1, n2, aa;
+        double cc, ss, t1, t2;
+
+        // Bit-reverse
+        jj = 0;
+        n2 = mN / 2;
+        for (ii = 1; ii < mN - 1; ii++) {
+            n1 = n2;
+            while (jj >= n1) {
+                jj = jj - n1;
+                n1 = n1 / 2;
+            }
+            jj = jj + n1;
+
+            if (ii < jj) {
+                t1 =  r.mReal[ii];
+                r.mReal[ii] = r.mReal[jj];
+                r.mReal[jj] = t1;
+                t1 = r.mImag[ii];
+                r.mImag[ii] = r.mImag[jj];
+                r.mImag[jj] = t1;
+            }
+        }
+
+        // FFT
+        n1 = 0;
+        n2 = 1;
+        for (ii = 0; ii < mOrder; ii++) {
+            n1 = n2;
+            n2 = n2 + n2;
+            aa = 0;
+
+            for (jj = 0; jj < n1; jj++) {
+                cc = mCos.mData[aa];
+                ss = sign * mSin.mData[aa];
+                aa += 1 << (mOrder - ii - 1);
+                for (kk = jj; kk < mN; kk = kk + n2) {
+                    t1 = cc * r.mReal[kk + n1] - ss * r.mImag[kk + n1];
+                    t2 = ss * r.mReal[kk + n1] + cc * r.mImag[kk + n1];
+                    r.mReal[kk + n1] = r.mReal[kk] - t1;
+                    r.mImag[kk + n1] = r.mImag[kk] - t2;
+                    r.mReal[kk] = r.mReal[kk] + t1;
+                    r.mImag[kk] = r.mImag[kk] + t2;
+                }
+            }
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspWindow.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspWindow.java
new file mode 100644
index 0000000..3ccca43
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/DspWindow.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.wavelib;
+
+public class DspWindow {
+    public DspBufferDouble mBuffer;
+    private int mWindowType = WINDOW_RECTANGULAR;
+    private int mSize;
+    private int mOverlap;
+
+    private static final double TWOPI = Math.PI * 2;
+
+    public static final int WINDOW_RECTANGULAR = 0;
+    public static final int WINDOW_TRIANGULAR = 1;
+    public static final int WINDOW_TRIANGULAR_FLAT_TOP = 2;
+    public static final int WINDOW_HAMMING = 3;
+    public static final int WINDOW_HAMMING_FLAT_TOP = 4;
+    public static final int WINDOW_HANNING = 5;
+    public static final int WINDOW_HANNING_FLAT_TOP = 6;
+
+    public DspWindow(int windowType, int size, int overlap) {
+        init(windowType, size, overlap);
+    }
+
+    public DspWindow(int windowType, int size)  {
+        init(windowType, size, size / 2);
+    }
+
+    public void init(int windowType, int size, int overlap) {
+        if (size > 0 && overlap > 0) {
+            mSize = size;
+            mOverlap = overlap;
+            if (mOverlap > mSize / 2) {
+                mOverlap = mSize / 2;
+            }
+
+            mBuffer = new DspBufferDouble(mSize);
+            if (fillWindow(mBuffer, windowType, mOverlap)) {
+                mWindowType = windowType;
+            }
+        }
+    }
+
+    public void scale(double scale) {
+        DspBufferMath.mult(mBuffer, mBuffer, scale);
+    }
+
+    public static boolean fillWindow(DspBufferDouble r, int type, int overlap) {
+        boolean status = false;
+        int size = r.getSize();
+        if (overlap > size / 2) {
+            overlap = size / 2;
+        }
+
+        switch(type) {
+            case WINDOW_RECTANGULAR:
+                status = fillRectangular(r);
+                break;
+            case WINDOW_TRIANGULAR:
+                status = fillTriangular(r, size / 2);
+                break;
+            case WINDOW_TRIANGULAR_FLAT_TOP:
+                status = fillTriangular(r, overlap);
+                break;
+            case WINDOW_HAMMING:
+                status = fillHamming(r, size / 2);
+                break;
+            case WINDOW_HAMMING_FLAT_TOP:
+                status = fillHamming(r, overlap);
+                break;
+            case WINDOW_HANNING:
+                status = fillHanning(r, size / 2);
+                break;
+            case WINDOW_HANNING_FLAT_TOP:
+                status = fillHanning(r, overlap);
+                break;
+        }
+        return status;
+    }
+
+    private static boolean fillRectangular(DspBufferDouble r) {
+        if (DspBufferMath.set(r, 1.0) == DspBufferMath.MATH_RESULT_SUCCESS) {
+            return true;
+        }
+        return false;
+    }
+
+    private static boolean fillTriangular(DspBufferDouble b, int overlap) {
+        int size = b.getSize();
+        if (overlap > size / 2) {
+            overlap = size / 2;
+        }
+
+        double value;
+        //ramp up
+        int i = 0;
+        if (overlap > 0) {
+            for (i = 0; i < overlap; i++) {
+                value = (2.0 * i + 1) / (2 * overlap);
+                b.mData[i] = value;
+            }
+        }
+
+        //flat top
+        for (; i < size - overlap; i++) {
+            b.mData[i] = 1.0;
+        }
+
+        //ramp down
+        if (overlap > 0) {
+            for (; i < size; i++) {
+                value = (2.0 * (size - i) - 1) / (2 * overlap);
+                b.mData[i] = value;
+            }
+        }
+        return true;
+    }
+
+    private static boolean fillHamming(DspBufferDouble b, int overlap) {
+        int size = b.getSize();
+        if (overlap > size / 2)
+            overlap = size / 2;
+
+        //create window, then copy
+        double value;
+
+        int twoOverlap = 2 * overlap;
+        //ramp up
+        int i = 0;
+        if (overlap > 0) {
+            for (i = 0; i < overlap; i++) {
+                value = 0.54 - 0.46 * Math.cos(TWOPI * i / (twoOverlap - 1));
+                b.mData[i] = value;
+            }
+        }
+
+        //flat top
+        for (; i < size - overlap; i++) {
+            b.mData[i] = 1.0;
+        }
+
+        //ramp down
+        int k;
+        if (overlap > 0) {
+            for (; i < size; i++) {
+                k = i - (size - 2 * overlap);
+                value = 0.54 - 0.46 * Math.cos(TWOPI * k / (twoOverlap - 1));
+                b.mData[i] = value;
+            }
+        }
+        return true;
+    }
+
+    private static boolean fillHanning(DspBufferDouble b, int overlap) {
+        int size = b.getSize();
+        if (overlap > size / 2)
+            overlap = size / 2;
+
+        //create window, then copy
+        double value;
+
+        int twoOverlap = 2*overlap;
+        //ramp up
+        int i = 0;
+        if (overlap > 0) {
+            for (i = 0; i < overlap; i++) {
+                value = 0.5 * (1.0 - Math.cos(TWOPI * i / (twoOverlap - 1)));
+                b.mData[i] = value;
+            }
+        }
+
+        //flat top
+        for (; i < size - overlap; i++) {
+            b.mData[i] = 1.0;
+        }
+
+        //ramp down
+        if (overlap > 0) {
+            for (; i < size; i++) {
+                int k = i - (size - 2 * overlap);
+                value = 0.5 * (1.0 - Math.cos(TWOPI * k / (twoOverlap - 1)));
+                b.mData[i] = value;
+            }
+        }
+        return true;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/PipeShort.java b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/PipeShort.java
new file mode 100644
index 0000000..83b171f
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/PipeShort.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.wavelib;
+
+// Non-blocking pipe supports a single writer and single reader.
+// The write side of a pipe permits overruns; flow control is the caller's responsibility.
+
+public class PipeShort {
+    private int mFront;
+    private int mRear;
+    private short mBuffer[];
+    private volatile int mVolatileRear; // written by write(), read by read()
+    private int mMaxValues;
+    private int mBytesOverrun;
+    private int mOverruns;
+    public static final int OVERRUN = -2;
+
+    // maxBytes will be rounded up to a power of 2, and all slots are available. Must be >= 2.
+    public PipeShort(int maxValues)
+    {
+        mMaxValues = roundup(maxValues);
+        mBuffer = new short[mMaxValues];
+    }
+
+    // buffer must != null.
+    // offset must be >= 0.
+    // count is maximum number of bytes to copy, and must be >= 0.
+    // offset + count must be <= buffer.length.
+    // Returns actual number of bytes copied >= 0.
+    public int write(short[] buffer, int offset, int count)
+    {
+        int rear = mRear & (mMaxValues - 1);
+        int written = mMaxValues - rear;
+        if (written > count) {
+            written = count;
+        }
+        System.arraycopy(buffer, offset, mBuffer, rear, written);
+        if (rear + written == mMaxValues) {
+            if ((count -= written) > rear) {
+                count = rear;
+            }
+            if (count > 0) {
+                System.arraycopy(buffer, offset + written, mBuffer, 0, count);
+                written += count;
+            }
+        }
+        mRear += written;
+        mVolatileRear = mRear;
+        return written;
+    }
+
+    public int availableToRead()
+    {
+        int rear = mVolatileRear;
+        int avail = rear - mFront;
+        if (avail > mMaxValues) {
+            // Discard 1/16 of the most recent data in pipe to avoid another overrun immediately
+            int oldFront = mFront;
+            mFront = rear - mMaxValues + (mMaxValues >> 4);
+            mBytesOverrun += mFront - oldFront;
+            ++mOverruns;
+            return OVERRUN;
+        }
+        return avail;
+    }
+
+    // buffer must != null.
+    // offset must be >= 0.
+    // count is maximum number of bytes to copy, and must be >= 0.
+    // offset + count must be <= buffer.length.
+    // Returns actual number of bytes copied >= 0.
+    public int read(short[] buffer, int offset, int count)
+    {
+        int avail = availableToRead();
+        if (avail <= 0) {
+            return avail;
+        }
+        // An overrun can occur from here on and be silently ignored,
+        // but it will be caught at next read()
+        if (count > avail) {
+            count = avail;
+        }
+        int front = mFront & (mMaxValues - 1);
+        int red = mMaxValues - front;
+        if (red > count) {
+            red = count;
+        }
+        // In particular, an overrun during the System.arraycopy will result in reading corrupt data
+        System.arraycopy(mBuffer, front, buffer, offset, red);
+        // We could re-read the rear pointer here to detect the corruption, but why bother?
+        if (front + red == mMaxValues) {
+            if ((count -= red) > front) {
+                count = front;
+            }
+            if (count > 0) {
+                System.arraycopy(mBuffer, 0, buffer, offset + red, count);
+                red += count;
+            }
+        }
+        mFront += red;
+        return red;
+    }
+
+    public void flush()
+    {
+        mRear = mFront;
+        mVolatileRear = mFront;
+    }
+
+    // Round up to the next highest power of 2
+    private static int roundup(int v)
+    {
+        // Integer.numberOfLeadingZeros() returns 32 for zero input
+        if (v == 0) {
+            v = 1;
+        }
+        int lz = Integer.numberOfLeadingZeros(v);
+        int rounded = 0x80000000 >>> lz;
+        // 0x800000001 and higher are actually rounded _down_ to prevent overflow
+        if (v > rounded && lz > 0) {
+            rounded <<= 1;
+        }
+        return rounded;
+    }
+
+}
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
new file mode 100644
index 0000000..41f0411
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/audio/wavelib/VectorAverage.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.wavelib;
+
+import android.util.Log;
+
+public class VectorAverage {
+    private static final String LOGTAG = "VectorAverage";
+    private static final int mVersion = 0;
+    private double[] mData;
+    private int mValueCount = 0;
+
+    public void setData(double[] data, boolean replace) {
+        int size = data.length;
+        if (mData == null || mData.length != size) {
+            mData = new double[size];
+            mValueCount = 0;
+        }
+        if (replace || mValueCount == 0) {
+            System.arraycopy(data, 0, mData, 0, size);
+            mValueCount = 1;
+        } else {
+            for (int i = 0; i < size; i++) {
+                mData[i] += data[i];
+            }
+            mValueCount++;
+        }
+    }
+
+    public int getData(double[] data, boolean raw) {
+        int nCount = 0;
+        if (mData != null && mData.length <= data.length) {
+            nCount = mData.length;
+            if (mValueCount == 0) {
+                for (int i = 0; i < nCount; i++) {
+                    data[i] = 0;
+                }
+            } else if (!raw && mValueCount > 1) {
+                for (int i = 0; i < nCount; i++) {
+                    data[i] = mData[i] / mValueCount;
+                }
+            } else {
+                for (int i = 0; i < nCount; i++) {
+                    data[i] = mData[i];
+                }
+            }
+        }
+        return nCount;
+    }
+
+    public int getCount() {
+        return mValueCount;
+    }
+
+    public int getSize() {
+        if (mData != null) {
+            return mData.length;
+        }
+        return 0;
+    }
+
+    public void reset() {
+        mValueCount = 0;
+    }
+
+    private final String SERIALIZED_VERSION = "VECTOR_AVERAGE_VERSION";
+    private final String SERIALIZED_COUNT = "COUNT";
+
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+
+        //version
+        sb.append(SERIALIZED_VERSION +"="+ mVersion +"\n");
+
+        double[] data = new double[getSize()];
+        getData(data,false);
+
+        //element count
+        int nCount = data.length;
+        sb.append(SERIALIZED_COUNT + "=" + nCount +"\n");
+
+        for (int i = 0; i < nCount; i++) {
+            sb.append(String.format("%f\n",data[i]));
+        }
+
+        return sb.toString();
+    }
+
+    public boolean initFromString(String string) {
+        boolean success = false;
+
+        String[] lines = string.split(System.getProperty("line.separator"));
+
+        int lineCount = lines.length;
+        if (lineCount > 3) {
+            int nVersion = -1;
+            int nCount = -1;
+            int nIndex = 0;
+
+            //search for version:
+            while (nIndex < lineCount) {
+                String[] separated = lines[nIndex].split("=");
+                nIndex++;
+                if (separated.length > 1 && separated[0].equalsIgnoreCase(SERIALIZED_VERSION)) {
+                    nVersion = Integer.parseInt(separated[1]);
+                    break;
+                }
+            }
+
+            if (nVersion >= 0) {
+                //get count
+
+                while (nIndex < lineCount) {
+                    String[] separated = lines[nIndex].split("=");
+                    nIndex++;
+                    if (separated.length > 1 && separated[0].equalsIgnoreCase(SERIALIZED_COUNT)) {
+                        nCount = Integer.parseInt(separated[1]);
+                        break;
+                    }
+                }
+
+                if (nCount > 0 && nCount <= lineCount-2 && nCount < 20000) { //foolproof
+                    //now add nCount to the vector.
+                    double[] data = new double[nCount];
+                    int dataIndex=0;
+
+                    while (nIndex < lineCount) {
+                        double value = Double.parseDouble(lines[nIndex]);
+                        data[dataIndex++] = value;
+                        nIndex++;
+                    }
+                    setData(data, true);
+                    success = true;
+                }
+            }
+        }
+
+        return success;
+    }
+
+    private static void log(String msg) {
+        Log.v(LOGTAG, msg);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserService.java
index b4a6416..5a60ad0 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleAdvertiserService.java
@@ -42,7 +42,7 @@
 public class BleAdvertiserService extends Service {
 
     public static final boolean DEBUG = true;
-    public static final String TAG = "BleAdvertiseService";
+    public static final String TAG = "BleAdvertiserService";
 
     public static final int COMMAND_START_ADVERTISE = 0;
     public static final int COMMAND_STOP_ADVERTISE = 1;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java b/apps/CtsVerifier/src/com/android/cts/verifier/bluetooth/BleServerService.java
old mode 100644
new mode 100755
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/AutoLockTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/AutoLockTest.java
deleted file mode 100644
index 9181b29..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/AutoLockTest.java
+++ /dev/null
@@ -1,1078 +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.verifier.camera.analyzer;
-
-import android.app.PendingIntent;
-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.graphics.ImageFormat;
-import android.hardware.Camera;
-import android.hardware.usb.UsbAccessory;
-import android.hardware.usb.UsbManager;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-import android.view.SurfaceView;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Implements a test to verify whether the Auto Exposure Lock functions as
- * described in the API.
- *
- * The test consists three sub-categories. The first set of tests focus on
- * testing whether the auto exposure lock works in various situations.
- * For all tests in this set, the lock is set during the period when the camera
- * preview is open. In this way the lock locks exposure according to the
- * lighting at the moment of setting the lock. The second set of tests focus on
- * testing whether the auto exposure lock works as expected after turning the
- * preview off and on. The lock is set during the period when the camera
- * preview is turned off. The lock is expected to lock an exposure level
- * identical to the one before the preview is turned off. One special case in
- * this category is to set lock before the preview is turned on for the first
- * time.
- */
-public class AutoLockTest extends CameraTests {
-
-    private static final String TAG = "AutoLockTest";
-    /** USB permission to connect to ADK. */
-    private static final String ACTION_USB_PERMISSION = "com.android.cts.verifier.USB_PERMISSION";
-    /** Defines a long sleep period.*/
-    private static final int SHORT_SLEEP = 2000;
-    /** Defines a short sleep period. */
-    private static final int LONG_SLEEP = 4000;
-
-    /** Test results in text format. */
-    private String mDebugText = new String();
-    /** Detailed report. */
-    private String mResultText = new String();
-    /** Thread lock of the camera callbacks. */
-    private final Object mProcessingImage = new Object();
-    /** Memory address of the native test handler. */
-    private long mTestHandler;
-    /** Array storing the reference test results. */
-    private ArrayList<Boolean> mReferenceCompareResults;
-    /** Array storing the reference test scenario logs. */
-    private ArrayList<String> mReferenceLogs;
-    /** Number of tests so far. */
-    private int mTestCount;
-
-    /** Usb Manager of the USB connections. */
-    private UsbManager mUsbManager;
-    /** Intent for getting the permission to access the ADK. */
-    private PendingIntent mPermissionIntent;
-    /** Boolean to represent whether a permission is gained. */
-    private boolean mPermissionRequestPending;
-    /** USB accessory pointing to the ADK. */
-    private UsbAccessory mAccessory;
-    /** File descriptor of the USB communication port. */
-    private ParcelFileDescriptor mFileDescriptor;
-    /** Output stream to write commands for ADK to. */
-    private FileOutputStream mOutputStream;
-
-    /** Pointer to the CameraAnalyzerActivity activity. */
-    private CameraAnalyzerActivity mActivity;
-    /** Boolean to tell whether the accessory is opened. */
-    private boolean mSetupReady;
-    /** Thread lock for setting up the usb. */
-    private final Object mUsbSetup = new Object();
-    /** Boolean to indicate whether there is an ADK attached. */
-    private boolean mUsingUsb = false;
-    /** Test results.*/
-    private int[] mTestResults;
-    /** Number of tests. */
-    private int mNumTests;
-    /** Singleton test instance.*/
-    private static AutoLockTest singletonTest = null;
-
-    /**
-     * Receives the notice of whether the connection to ADK is granted or
-     * denied.
-     */
-    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            Log.v(TAG, String.format("Received USB broadcast with action %s ", action));
-
-            if (ACTION_USB_PERMISSION.equals(action)) {
-                synchronized (this) {
-                    UsbAccessory accessory =
-                        (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
-
-                    if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
-                        // Grants the permission to connect to the ADK.
-                        Log.v(TAG, "Open accessory 3");
-                        openAccessory(accessory);
-                        // Overwrites the old camera instsance with the one currently opened
-                        // by the CameraAnalyzerActivity instance, since the permission
-                        // dialogue pauses the CameraAnalyzerActivity and forces the camera to
-                        // be released and reopened when the dialogue disappears.
-                        mTestCamera = mActivity.getCameraInstance();
-                    } else {
-                        // Denies the permission to connect to the ADK.
-                        Log.d(TAG, "permission denied for accessory " + accessory);
-                    }
-                    // Marks that the permission request has been processed.
-                    mPermissionRequestPending = false;
-                }
-            } else if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
-                // Invokes when the USB is detached.
-                // Closes the accessory if it has not been closed.
-                Log.v(TAG, "Usb device detached");
-                mUsingUsb = false;
-                UsbAccessory accessory =
-                    (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
-                if (accessory != null && accessory.equals(mAccessory)) {
-                    closeAccessory();
-                }
-            }
-        }
-    };
-
-    /**
-     * Opens the ADK from USB and attaches the output stream with it.
-     *
-     * Notifies the tread lock that the USB setup is ready.
-     */
-    private void openAccessory(UsbAccessory accessory) {
-        Log.d(TAG, "openAccessory: " + accessory);
-        mFileDescriptor = mUsbManager.openAccessory(accessory);
-
-        if (mFileDescriptor != null) {
-            mAccessory = accessory;
-            FileDescriptor fd = mFileDescriptor.getFileDescriptor();
-            mOutputStream = new FileOutputStream(fd);
-            Log.d(TAG, "accessory opened");
-        } else {
-            Log.d(TAG, "accessory open fail");
-        }
-
-        // Unlocks the thread lock of waiting for the USB to be ready.
-        synchronized (mUsbSetup) {
-            mSetupReady = true;
-            Log.v(TAG, "Setup ready");
-            mUsbSetup.notifyAll();
-        }
-    }
-
-    /**
-     * Closes the ADK and detaches the output stream from it.
-     */
-    private void closeAccessory() {
-        try {
-            if (mFileDescriptor != null) {
-                mFileDescriptor.close();
-            }
-        } catch (IOException e) {
-        } finally {
-            mFileDescriptor = null;
-            mAccessory = null;
-        }
-    }
-
-    /**
-     * Constructs the AutoLockTest class, which can execute a series of tests
-     * to verify whether the device's Auto Exposure Lock is working properly.
-     *
-     * The test uses the LED lights on an ADK device as light source to change
-     * the lighting condition of the environment. The usb connection to the
-     * ADK board is established in the constructor.
-     *
-     * @param hostActivity pointer to the <code>CameraAnalyzerActivity</code>
-     * that instructs the Auto Lock Test
-     * @param mCamera pointer to the current camera instance
-     */
-    private AutoLockTest(){
-        super();
-    }
-
-    public static synchronized AutoLockTest getSingletonTest() {
-        if (singletonTest == null) {
-            Log.v(TAG, "Creating a new AutoLockTest instance");
-            singletonTest = new AutoLockTest();
-            singletonTest.initializeTest();
-        }
-        return singletonTest;
-    }
-
-    private void initializeTest() {
-        // Creates a native test handler with a 120x160 pixel debug output
-        mTestHandler = createAutoLockTest();
-        mReferenceCompareResults = new ArrayList<Boolean>();
-        mReferenceLogs = new ArrayList<String>();
-        mNumTests = 4;
-        mTestResults = new int[mNumTests];
-        for (int i = 0; i < mNumTests; ++i) {
-            mTestResults[i] = CameraTests.CAMERA_TEST_NOT_RUN;
-        }
-    }
-
-    public void updateCamera() {}
-
-    public void setActivity(CameraAnalyzerActivity hostActivity){
-        if (mUsingUsb) {
-            closeConnection();
-        }
-
-        mActivity = hostActivity;
-
-        mSetupReady = false;
-
-        Log.v(TAG, "Start to test ADK connection");
-        // Starts to establish the connection to the ADK board.
-        mUsbManager = (UsbManager) mActivity.getSystemService(Context.USB_SERVICE);
-        mPermissionIntent = PendingIntent.getBroadcast(mActivity, 0,
-                                                       new Intent(ACTION_USB_PERMISSION), 0);
-        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
-        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
-        filter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
-        mActivity.registerReceiver(mUsbReceiver, filter);
-
-        if (mActivity.getLastNonConfigurationInstance() != null) {
-            mAccessory = (UsbAccessory) mActivity.getLastNonConfigurationInstance();
-            Log.v(TAG, "Open acceossory 1");
-            openAccessory(mAccessory);
-        }
-
-        // Skips the permission listener if the user already grants the ADK
-        // permission previously in the app.
-        UsbAccessory[] accessories = mUsbManager.getAccessoryList();
-        UsbAccessory accessory = (accessories == null ? null : accessories[0]);
-        if (accessory != null) {
-            if (mUsbManager.hasPermission(accessory)) {
-                Log.v(TAG, "Open accessory 2");
-                openAccessory(accessory);
-            } else {
-                synchronized (mUsbReceiver) {
-                    if (!mPermissionRequestPending) {
-                        mUsbManager.requestPermission(accessory, mPermissionIntent);
-                        mPermissionRequestPending = true;
-                    }
-                }
-            }
-            mUsingUsb = true;
-        } else {
-            Log.d(TAG, "accessory is null");
-            mUsingUsb = false;
-        }
-
-    }
-
-    /**
-     * Closes the accessories and unregister the USB listener at the end of
-     * tests.
-     */
-    public void closeConnection() {
-        closeAccessory();
-        mActivity.unregisterReceiver(mUsbReceiver);
-    }
-
-    protected void finalize ()  {
-        if (mUsingUsb) {
-            closeConnection();
-        }
-    }
-
-    /**
-     * Runs the Auto Lock tests. A total of 19 tests have been coded and
-     * included. Developers can freely comment out tests not interested. In
-     * the release version, all tests will be executed.
-     */
-    @Override
-    public synchronized void run(int index){
-        if (index == 0) {
-            for (int i = 1; i < mNumTests; ++i) {
-                run(i);
-            }
-            return;
-        }
-
-        Log.v(TAG, "AutoLockTest thread started!");
-
-        if (mUsingUsb && (!mSetupReady)) {
-            // USB connection is not set up. Locks thread and wait.
-            Log.v(TAG, "Setup not ready, waiting");
-            synchronized (mUsbSetup) {
-                try{
-                    Log.v(TAG, "Start waiting for Image");
-                    mUsbSetup.wait();
-                } catch (InterruptedException e) {
-                    Log.v(TAG, "Callback wait fails!");
-                }
-            }
-        }
-
-        // Restarts the camera intance and attach the preview to the corrent
-        // UI elements.
-        restartCamera();
-        startPreview();
-
-        mTestCount = 0;
-        switch (index) {
-            case 1:
-                Log.v(TAG, "SP -> TP1 -> SP -> +1 -> Lock -> -1 -> TP2");
-                test0();
-                Log.v(TAG, "SP -> TP1 -> SP -> Lock -> +1 -> TP2 -> -1");
-                test1();
-                Log.v(TAG, "SP -> Lock -> +1 -> TP1 -> SP -> -1 -> Lock -> TP2");
-                test2();
-                Log.v(TAG, "SP -> Lock -> +1 -> TP1 -> SP -> Lock -> -1 -> TP2");
-                test3();
-                break;
-            case 2:
-                Log.v(TAG, "SP -> +1 -> TP1 -> -1 -> Lock -> SP -> TP2");
-                test4();
-                Log.v(TAG, "SP -> +1 -> TP1 -> Lock -> SP -> -1 -> TP2");
-                test5();
-                Log.v(TAG, "SP -> TP1 -> +1 -> Lock -> SP -> -1 -> TP2");
-                test6();
-                Log.v(TAG, "SP -> TP1 -> +1 -> Lock -> SP -> TP2");
-                test7();
-                Log.v(TAG, "SP -> TP1 -> Lock -> SP -> +1 -> TP2");
-                test8();
-                Log.v(TAG, "SP -> +1 -> Lock -> -1 -> TP1 -> Lock -> SP -> TP2");
-                test9();
-                Log.v(TAG, "SP -> +1 -> Lock -> TP1 -> -1 -> Lock -> SP -> TP2");
-                test10();
-                Log.v(TAG, "SP -> Lock -> TP1 -> +1 -> Lock -> SP -> -1 -> TP2");
-                test11();
-                break;
-            case 3:
-                Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> Restart -> Lock -> SP -> +1 -> TP2");
-                test12();
-                Log.v(TAG, "Restart -> Lock -> SP -> +1 -> TP1 -> -1 -> Lock -> SP -> TP2");
-                test13();
-                Log.v(TAG, "Restart -> Lock -> SP -> +1 -> TP1 -> Lock -> SP -> -1 -> TP2");
-                test14();
-                Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> +1 -> Lock -> SP -> -1 -> TP2");
-                test15();
-                Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> +1 -> Lock -> SP -> TP2");
-                test16();
-                Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> Lock -> SP -> +1 -> TP2");
-                test17();
-                Log.v(TAG, "Restart -> Lock -> SP -> TP1 -> Lock -> SP -> TP2");
-                test18();
-                break;
-            default:
-                break;
-        }
-
-        releaseLock();
-
-        Log.v(TAG, "Ready to process data");
-        boolean[] testCompareResults = new boolean[2 * mTestCount];
-
-        // Processes the data stored in the native test handler instance.
-        // Stores the test results into a boolean array.
-        processAutoLockTest(mTestHandler, testCompareResults);
-
-        // Prepares the test result text output with the booelan result array.
-        prepareDebugText(testCompareResults, index);
-        mReferenceCompareResults.clear();
-        mReferenceLogs.clear();
-    }
-
-    /**
-     * Compares two images taken under the same lighting, Image 1 without AE
-     * lock and Image 2 with AE locked under a bright light. Image 1 is
-     * expected to be brighter than Image 2.
-     * Tests whether AE lock works compared to no AE lock.
-     */
-    private void test0() {
-        releaseLock();
-        takePicture();
-        startPreview();
-        turnOnLight();
-        setLock();
-        turnOffLight();
-        takePicture();
-        startPreview();
-        releaseLock();
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Same lighting condition with one different lock");
-        ++mTestCount;
-    }
-
-    /**
-     * Compares two images taken under different lighting, Image 1 without AE
-     * lock and Image 2 with with AE locked under the same light Image 1 is
-     * taken. Image 2 is taken under a bright light. Image 1 is expected to be
-     * darker than Image 2.
-     * Tests whether AE lock works compared to no AE lock.
-     */
-    private void test1() {
-        releaseLock();
-        takePicture();
-        startPreview();
-        setLock();
-        turnOnLight();
-        takePicture();
-        turnOffLight();
-        startPreview();
-        releaseLock();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("One same lock with different lighting");
-        ++mTestCount;
-    }
-
-    /**
-     * Compares two images taken under different light, both with AE locked
-     * under the same lighting. Image 1 is taken under a brighter light.
-     * Image 1 is expected to be brighter than Image 2.
-     * Tests whether AE locks the exposure to the same level in the same
-     * lighting condition after preview restarts.
-     */
-     private void test2() {
-        releaseLock();
-        setLock();
-        turnOnLight();
-        takePicture();
-        startPreview();
-        turnOffLight();
-        setLock();
-        takePicture();
-        startPreview();
-        releaseLock();
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Same locking locations with different lighting");
-        ++mTestCount;
-    }
-
-    /**
-     * Compares two images taken under different light, Image 1 with AE locked
-     * under normal light and Image 2 with AE locked under a bright light.
-     * Image 1 is taken under a bright light and Image 2 is taken in the normal
-     * lighting. Image 1 is expected to be brighter than Image 2.
-     * Tests whether AE lock can adjust to change of lighting conditions.
-     */
-    private void test3() {
-        releaseLock();
-        setLock();
-        turnOnLight();
-        takePicture();
-        startPreview();
-        setLock();
-        turnOffLight();
-        takePicture();
-        startPreview();
-        releaseLock();
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Different locking locations with different lighting");
-        ++mTestCount;
-    }
-
-    /**
-     * Compares two images taken under different lighting, Image 1 without
-     * AE lock and Image 2 with AE lock set before camera preview resumes.
-     * Image 1 is taken under a bright light and the light is turned off before
-     * camera preview starts again. Image 1 is expected to be brighter than
-     * Image 2.
-     * Tests whether setting AE lock between camera preview stops and restarts
-     * can retain the exposure level of the previous AE-unlocked photo.
-     */
-    private void test4() {
-        releaseLock();
-        turnOnLight();
-        takePicture();
-        turnOffLight();
-        setLock();
-        startPreview();
-        takePicture();
-        startPreview();
-        releaseLock();
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock after takePicture and light change, before preview");
-        ++mTestCount;
-    }
-
-    /**
-     * Compares two images taken under different lighting, Image 1 without
-     * AE lock and Image 2 with AE lock set before camera preview resumes.
-     * Image 1 is taken under a bright light and the light is turned off after
-     * preview restars but before Image 2 is taken. Image 1 is expected to be
-     * brighter than Image 2.
-     * Tests whether setting AE lock between camera preview stops and restarts
-     * can retain the exposure level of the previous AE-unlocked photo.
-     */
-    private void test5() {
-        releaseLock();
-        turnOnLight();
-        takePicture();
-        setLock();
-        startPreview();
-        turnOffLight();
-        takePicture();
-        startPreview();
-        releaseLock();
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock between takePicture and light change, w/o light change");
-        ++mTestCount;
-    }
-
-    private void test6() {
-        releaseLock();
-        takePicture();
-        turnOnLight();
-        setLock();
-        startPreview();
-        turnOffLight();
-        takePicture();
-        startPreview();
-        releaseLock();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add("Lock after takePicture and light change, before preview.");
-        ++mTestCount;
-    }
-
-    private void test7() {
-        releaseLock();
-        takePicture();
-        turnOnLight();
-        setLock();
-        startPreview();
-        takePicture();
-        startPreview();
-        releaseLock();
-        turnOffLight();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock after takePicture and light change, before preview.");
-        ++mTestCount;
-    }
-
-    private void test8() {
-        releaseLock();
-        takePicture();
-        setLock();
-        startPreview();
-        turnOnLight();
-        takePicture();
-        startPreview();
-        releaseLock();
-        turnOffLight();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock after takePicture and before startPreview.");
-        ++mTestCount;
-    }
-
-    private void test9() {
-        releaseLock();
-        turnOnLight();
-        setLock();
-        turnOffLight();
-        takePicture();
-        setLock();
-        startPreview();
-        takePicture();
-        releaseLock();
-        startPreview();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add("Lock after first lock with changing light");
-        ++mTestCount;
-    }
-
-    private void test10() {
-        releaseLock();
-        turnOnLight();
-        setLock();
-        takePicture();
-        turnOffLight();
-        setLock();
-        startPreview();
-        takePicture();
-        releaseLock();
-        startPreview();
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock after first lock with changing light");
-        ++mTestCount;
-    }
-
-    private void test11() {
-        releaseLock();
-        setLock();
-        takePicture();
-        turnOnLight();
-        setLock();
-        startPreview();
-        turnOffLight();
-        takePicture();
-        releaseLock();
-        startPreview();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add("Lock after first lock with changing light");
-        ++mTestCount;
-    }
-
-    private void test12() {
-        //"Restart -> Lock -> SP -> TP1 -> Restart -> Lock -> SP -> +1 -> TP2"
-        restartCamera();
-        setLock();
-        startPreview();
-        takePicture();
-        releaseLock();
-        restartCamera();
-        setLock();
-        startPreview();
-        turnOnLight();
-        takePicture();
-        releaseLock();
-        turnOffLight();
-        startPreview();
-        //mTestCamera.release();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock before first preview");
-        ++mTestCount;
-    }
-
-    private void test13() {
-        //"Restart -> Lock -> SP -> +1 -> TP1 -> -1 -> Lock -> SP -> TP2"
-        restartCamera();
-        setLock();
-        startPreview();
-        turnOnLight();
-        takePicture();
-        turnOffLight();
-        setLock();
-        startPreview();
-        takePicture();
-        releaseLock();
-        startPreview();
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock after first lock with changing light");
-        ++mTestCount;
-    }
-
-    private void test14() {
-        //"Restart -> Lock -> SP -> +1 -> TP1 -> Lock -> SP -> -1 -> TP2"
-        restartCamera();
-        setLock();
-        startPreview();
-        turnOnLight();
-        takePicture();
-        setLock();
-        startPreview();
-        turnOffLight();
-        takePicture();
-        releaseLock();
-        startPreview();
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock after first lock with changing light");
-        ++mTestCount;
-    }
-
-    private void test15() {
-        //"Restart -> Lock -> SP -> TP1 -> +1 -> Lock -> SP -> -1 -> TP2"
-         restartCamera();
-        setLock();
-        startPreview();
-        takePicture();
-        turnOnLight();
-        setLock();
-        startPreview();
-        turnOffLight();
-        takePicture();
-        releaseLock();
-        startPreview();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add("Lock after first lock with changing light");
-        ++mTestCount;
-    }
-
-    private void test16() {
-        //"Restart -> Lock -> SP -> TP1 -> +1 -> Lock -> SP -> TP2"
-        restartCamera();
-        setLock();
-        startPreview();
-        takePicture();
-        turnOnLight();
-        setLock();
-        startPreview();
-        takePicture();
-        turnOffLight();
-        releaseLock();
-        startPreview();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock after first lock with changing light");
-        ++mTestCount;
-    }
-
-    private void test17() {
-        //"Restart -> Lock -> SP -> TP1 -> Lock -> SP -> +1 -> TP2"
-        restartCamera();
-        setLock();
-        startPreview();
-        takePicture();
-        setLock();
-        startPreview();
-        turnOnLight();
-        takePicture();
-        turnOffLight();
-        releaseLock();
-        startPreview();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add("Lock after first lock with changing light");
-        ++mTestCount;
-    }
-
-    private void test18() {
-        //"Restart -> Lock -> SP -> TP1 -> Lock -> SP -> TP2"
-        restartCamera();
-        setLock();
-        startPreview();
-        takePicture();
-        setLock();
-        startPreview();
-        takePicture();
-        releaseLock();
-        startPreview();
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add("Lock after first lock with changing light");
-        ++mTestCount;
-    }
-
-    /**
-     * Restarts the camera by releasing the current instance and get a new
-     * instance. Also connects this new camera instance's preview to the proper
-     * UI surfaceview.
-     */
-    private void restartCamera() {
-        Log.v(TAG, "Restarting Camera");
-
-        mTestCamera.release();
-        Log.v(TAG, "Camera released");
-
-        try {
-            mTestCamera = Camera.open(mActivity.getCameraIdx());
-        } catch (RuntimeException e) {
-            throw new RuntimeException("Failed to open the camera", e);
-        }
-
-        Camera.Parameters params = mTestCamera.getParameters();
-        params.setPictureFormat(ImageFormat.JPEG);
-        params.setPictureSize(640, 480);
-        mTestCamera.setParameters(params);
-
-        try {
-            mTestCamera.setPreviewDisplay(super.getCameraView().getHolder());
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to connect camera to display: " + e);
-        }
-    }
-
-    /**
-     * Starts Camera preview with a delay of 2 seconds to let it adjust to
-     * the lighting condition.
-     */
-    private void startPreview() {
-        mTestCamera.startPreview();
-        try{
-            Log.v(TAG, "Waiting");
-            Thread.sleep(2000);
-            Log.v(TAG, "END Waiting");
-        } catch (InterruptedException e){}
-    }
-
-    /**
-     * Sends command to ADK to turn on all the LED lights to white.
-     * Waits for 4 seconds for the camera to adjust to the new lighting.
-     */
-    private void turnOnLight() {
-        Log.v(TAG, "Turn on light");
-        if (mUsingUsb) {
-            byte[] buffer = new byte[3];
-
-            buffer[0] = (byte) 3;
-            buffer[1] = (byte) 0;
-            buffer[2] = (byte) 1;
-            if (mOutputStream != null && buffer[1] != -1) {
-                try {
-                    mOutputStream.write(buffer);
-                } catch (IOException e) {
-                    Log.e(TAG, "write failed", e);
-                }
-            }
-        } else {
-            mActivity.runOnUiThread(new Runnable() {
-                public void run() {
-                    Toast.makeText(mActivity.getApplicationContext(), "Turn on light!", 4).show();
-
-                }
-            });
-        }
-
-        try{
-            Log.v(TAG, "Waiting, Please Turn on light");
-            Thread.sleep(LONG_SLEEP);
-            Log.v(TAG, "END Waiting");
-        } catch (InterruptedException e){}
-    }
-
-    /**
-     * Sends command to ADK to turn off all LED lights.
-     * Waits for 4 seconds for the camera to adjust to the new lighting.
-     */
-    private void turnOffLight() {
-        Log.v(TAG, "Turn off light");
-        if (mUsingUsb) {
-            byte[] buffer = new byte[3];
-
-            buffer[0] = (byte) 3;
-            buffer[1] = (byte) 0;
-            buffer[2] = (byte) 0;
-            if (mOutputStream != null && buffer[1] != -1) {
-                try {
-                    mOutputStream.write(buffer);
-                } catch (IOException e) {
-                    Log.e(TAG, "write failed", e);
-                }
-            }
-        } else {
-            mActivity.runOnUiThread(new Runnable() {
-                public void run() {
-                    Toast.makeText(mActivity.getApplicationContext(), "Turn off light!", 4).show();
-
-                }
-            });
-        }
-
-        try{
-            Log.v(TAG, "Waiting, Please Turn off light");
-            Thread.sleep(LONG_SLEEP);
-            Log.v(TAG, "END Waiting");
-        } catch (InterruptedException e){}
-    }
-
-    /**
-     * Sets the Auto Exposure Lock.
-     * Waits for 2 seonds for the lock to function.
-     */
-    private void setLock() {
-        Camera.Parameters params = mTestCamera.getParameters();
-
-        params.setAutoExposureLock(true);
-        params.setAutoWhiteBalanceLock(true);
-        mTestCamera.setParameters(params);
-        try{
-            Log.v(TAG, "Waiting to set lock");
-            Thread.sleep(2000);
-            Log.v(TAG, "END Waiting");
-        } catch (InterruptedException e){}
-    }
-
-    /**
-     * Releases the Auto Exposure Lock.
-     * Waits for 4 seconds afterwards for the Auto Exposure to be adjusted
-     * to the lighting condition.
-     */
-    private void releaseLock() {
-        Camera.Parameters params = mTestCamera.getParameters();
-
-        params.setAutoExposureLock(false);
-        params.setAutoWhiteBalanceLock(false);
-        mTestCamera.setParameters(params);
-        try{
-            Log.v(TAG, "Waiting to release lock");
-            Thread.sleep(LONG_SLEEP);
-            Log.v(TAG, "END Waiting");
-        } catch (InterruptedException e){}
-
-    }
-
-    /**
-     * Takes a picture and locks thread until the picture callback finishes.
-     */
-    private void takePicture(){
-        mTestCamera.takePicture(null, null, null, mTestJpegListener);
-
-        synchronized (mProcessingImage) {
-            try{
-                Log.v(TAG, "Start waiting for Image");
-              //  System.gc();
-                mProcessingImage.wait();
-            } catch (InterruptedException e){
-                 Log.v(TAG, "Callback wait fails!");
-            }
-        }
-    }
-
-    /**
-     * Prepare for the result to be shown in the UI. The result for each single
-     * test is shown in green if it matches the reference result. It is shown
-     * in red otherwise.
-     */
-    private void prepareDebugText(boolean[] testCompareResults, int index) {
-        boolean groupTestPassed = true;
-         for (int i = 0; i < mTestCount; ++i) {
-              String testLog;
-              boolean testPassed = true;
-              testLog = mReferenceLogs.get(i);
-              mDebugText += (testLog + "<br/>");
-
-              if (testCompareResults[i * 2] == mReferenceCompareResults.get(i * 2)) {
-                  mDebugText += String.format(
-                      "Picture 1 brighter than Picture 2 is %b \n",
-                      testCompareResults[i * 2]);
-              } else {
-                  mDebugText += String.format(
-                      "Picture 1 brighter than Picture 2 is %b \n",
-                      testCompareResults[i * 2]);
-                  testPassed = false;
-              }
-
-              if (testCompareResults[i * 2 + 1] == mReferenceCompareResults.get(i * 2 + 1)) {
-                  mDebugText += String.format(
-                      "Picture 1 is equivalent to Picture 2 is %b \n",
-                      testCompareResults[i * 2 + 1]);
-              } else {
-                  mDebugText += String.format(
-                      "Picture 1 is equivalent to Picture 2 is %b \n",
-                      testCompareResults[i * 2 + 1]);
-                  testPassed = false;
-              }
-
-              if (testPassed) {
-                  mDebugText += "Test passed! \n";
-              } else {
-                  mDebugText += "Test failed! \n";
-                  groupTestPassed = false;
-              }
-         }
-        if (groupTestPassed) {
-            mTestResults[index] = CameraTests.CAMERA_TEST_SUCCESS;
-        } else {
-            mTestResults[index] = CameraTests.CAMERA_TEST_FAILURE;
-        }
-    }
-
-    /**
-     * Clears the debug text so that new test results can be added.
-     */
-    public void clearDebugText() {
-        mDebugText = "";
-    }
-
-    @Override
-    public String getDebugText() {
-        return mDebugText;
-    }
-
-    @Override
-    public String getResultText() {
-        return mDebugText;
-    }
-
-    @Override
-    public String getTestName() {
-        return "Auto Exposure Lock test: \n";
-    }
-
-    @Override
-    public String getTestName(int index) {
-        switch (index) {
-            case 0:
-                return "Run all tests";
-            case 1:
-                return "Compulsory tests";
-            case 2:
-                return "Recommended tests (preview behavior)";
-            case 3:
-                return "Optional tests (default lock)";
-            default:
-                return "";
-        }
-    }
-
-    @Override
-    public int getResult(int index) {
-        return mTestResults[index];
-    }
-
-    @Override
-    public int getNumTests() {
-        return mNumTests;
-    }
-
-    private Camera.PictureCallback mTestJpegListener = new Camera.PictureCallback() {
-        public void onPictureTaken(byte[] data, Camera mCamera) {
-            Log.v(TAG, "Shutter pressed down!");
-            Bitmap inputImage;
-
-            // Decodes the camera input data into Bitmap.
-            // Constructs a native image class with the image.
-            inputImage = BitmapFactory.decodeByteArray(data, 0, data.length);
-            long bufferAddress = findNative(inputImage);
-            Log.v(TAG, "findNative method finishes");
-
-            // Cleans up memory taken by the Bitmap.
-            data = null;
-            inputImage.recycle();
-            inputImage = null;
-            System.gc();
-
-            // Passes data from the native image class to the native
-            // test handler.
-            createAutoLockClass(bufferAddress, mTestHandler,
-                                getCheckerCenter(), getCheckerRadius());
-
-            // Unlocks the thread lock.
-            synchronized (mProcessingImage) {
-                mProcessingImage.notifyAll();
-            }
-        }
-    };
-
-    private native long createAutoLockTest();
-
-    private native void createAutoLockClass(long bufferAddress, long handlerAddress,
-                                            long checkerCenterAddress,
-                                            long checkerRadiusAddress);
-
-    private native void processAutoLockTest(long handlerAddress, boolean[] testCompareResults);
-
-    static {
-        System.loadLibrary("cameraanalyzer");
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraAnalyzerActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraAnalyzerActivity.java
deleted file mode 100644
index 34e8d2d..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraAnalyzerActivity.java
+++ /dev/null
@@ -1,500 +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.verifier.camera.analyzer;
-
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-
-import android.app.Activity;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Color;
-import android.graphics.ImageFormat;
-import android.hardware.Camera;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.Size;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.text.Html;
-import android.text.method.ScrollingMovementMethod;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Button;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.content.Context;
-
-import java.io.IOException;
-import java.lang.Thread;
-import java.util.List;
-
-/**
- * Controls the UI activities of the camera quality test app. It is created
- * as soon as the app started. Users can launch different quality tests with
- * the buttons in the UI. This class will manage the threading for different
- * tests. Also it will provide debug output or debug text results for tests.
- */
-public class CameraAnalyzerActivity extends PassFailButtons.Activity {
-
-    private static final String TAG = "CameraAnalyzer";
-    private SurfaceView mCameraView;
-    private ImageView mResultView;
-    private Button mFindCheckerButton;
-    private Button mExposureCompensationButton;
-    private Button mWhiteBalanceButton;
-    private Button mAutoLockButton;
-    private Button mMeteringButton;
-    private ListView mTestList;
-    private TwoColumnAdapter mAdapter;
-
-    private Camera mCamera;
-    private int mCameraIdx = 0;
-    private boolean mIsCameraOpen = false;
-
-    private PowerManager mPowerManager;
-    private PowerManager.WakeLock mWakeLock;
-
-    private boolean mProcessingPicture = false;
-    private boolean mTestInProgress = false;
-    private final Object mProcessingTest = new Object();
-    private CameraTests mCurrentTest = null;
-
-    private long mCheckerCenterAddress;
-    private long mCheckerRadiusAddress;
-
-    private String mResultReport = "";
-    static final String[] TESTS = new String[] {"Test1", "Test2"};
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.ca_main);
-        setPassFailButtonClickListeners();
-        setInfoResources(R.string.camera_analyzer, R.string.ca_info, -1);
-
-        mFindCheckerButton = (Button) findViewById(R.id.findcheckerboardbutton);
-        mExposureCompensationButton = (Button) findViewById(R.id.exposurecompensationbutton);
-        mWhiteBalanceButton = (Button) findViewById(R.id.whitebalancebutton);
-        mAutoLockButton = (Button) findViewById(R.id.lockbutton);
-        mMeteringButton = (Button) findViewById(R.id.meteringbutton);
-        mCameraView = (SurfaceView) findViewById(R.id.cameraview);
-        mResultView = (ImageView) findViewById(R.id.resultview);
-        mTestList = (ListView) findViewById(R.id.ca_tests);
-        mAdapter = new TwoColumnAdapter(this);
-
-        // Initialize the list view.
-        initializeAdapter();
-        mTestList.setAdapter(mAdapter);
-        mTestList.setOnItemClickListener(mListListener);
-
-        mFindCheckerButton.setOnClickListener(mFindCheckerListener);
-        mExposureCompensationButton.setOnClickListener(mExposureCompensationListener);
-        mWhiteBalanceButton.setOnClickListener(mWhiteBalanceListener);
-        mAutoLockButton.setOnClickListener(mAutoLockListener);
-        mMeteringButton.setOnClickListener(mMeteringListener);
-        mCameraView.getHolder().addCallback(mSurfaceChangeListener);
-
-        // Disables all test buttons except the color checker test one.
-        // They will be enabled after the color checker is located.
-        mExposureCompensationButton.setEnabled(false);
-        mWhiteBalanceButton.setEnabled(false);
-        mAutoLockButton.setEnabled(false);
-        mMeteringButton.setEnabled(false);
-    }
-
-    @Override
-    public void onResume() {
-        super.onResume();
-
-        openCamera(mCameraIdx);
-        Camera.Parameters params = mCamera.getParameters();
-        params.setPictureFormat(ImageFormat.JPEG);
-        params.setPictureSize(640, 480);
-        mCamera.setParameters(params);
-        Log.v(TAG, "Set resolution to 640*480");
-    }
-
-    @Override
-    public void onPause() {
-        super.onPause();
-        CameraTests.getCamera().release();
-        mIsCameraOpen = false;
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.ca_menu, menu);
-
-        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
-        int cameraCount = Camera.getNumberOfCameras();
-        for (int camIdx = 0; camIdx < cameraCount; ++camIdx) {
-            MenuItem cameraMenuItem = menu.add(0, camIdx, Menu.NONE,
-                                               String.format("Open Camera %d", camIdx));
-        }
-      return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        if (item.getItemId() != mCameraIdx) {
-            mCameraIdx = item.getItemId();
-            new SwitchCameraTask().execute(mCameraIdx);
-        }
-        return false;
-    }
-
-    private class SwitchCameraTask extends AsyncTask<Integer, Void, Void> {
-        @Override
-        protected Void doInBackground(Integer... camIdx) {
-            if (mTestInProgress) {
-                synchronized (mProcessingTest) {
-                    try{
-                        Log.v(TAG, "Waiting for test to finish");
-                        mProcessingTest.wait();
-                    } catch (InterruptedException e){
-                         Log.v(TAG, "test wait fails!");
-                    }
-                }
-            }
-
-            openCamera((int)camIdx[0]);
-            return null;
-        }
-    }
-
-    private synchronized void openCamera(int camIdx) {
-        if (mIsCameraOpen) {
-            CameraTests.getCamera().release();
-            Log.v(TAG, "Releasing the cameratests camera");
-        }
-        try {
-            mCamera = Camera.open(camIdx);
-            mIsCameraOpen = true;
-        } catch (RuntimeException e) {
-            throw new RuntimeException("Failed to open the camera", e);
-        }
-
-        try {
-            mCamera.setPreviewDisplay(mCameraView.getHolder());
-        } catch (IOException e) {
-            throw new RuntimeException("Unable to connect camera to display: " + e);
-        }
-        mCamera.startPreview();
-        CameraTests.setCamera(mCamera);
-
-        ColorCheckerTest.getSingletonTest().updateCamera();
-        WhiteBalanceTest.getSingletonTest().updateCamera();
-        ExposureCompensationTest.getSingletonTest().updateCamera();
-        MeteringTest.getSingletonTest().updateCamera();
-        AutoLockTest.getSingletonTest().updateCamera();
-    }
-
-    public Camera getCameraInstance() {
-        return mCamera;
-    }
-
-    public void disableAll() {
-        mExposureCompensationButton.setEnabled(false);
-        mWhiteBalanceButton.setEnabled(false);
-        mAutoLockButton.setEnabled(false);
-        mMeteringButton.setEnabled(false);
-        mFindCheckerButton.setEnabled(false);
-    }
-
-    public void enableAll() {
-        mExposureCompensationButton.setEnabled(true);
-        mWhiteBalanceButton.setEnabled(true);
-        mAutoLockButton.setEnabled(true);
-        mMeteringButton.setEnabled(true);
-        mFindCheckerButton.setEnabled(true);
-    }
-
-    /**
-     * Provides an abstraction for the Camera tests. The camera tests will
-     * run in the background and the results will be shown in the UI thread
-     * after the tests are processed.
-     */
-    private class DebugOutputProcessingTask extends AsyncTask<Integer,
-                                                              Integer,
-                                                              Integer> {
-        @Override
-        protected Integer doInBackground(Integer... cameraTestIndex) {
-            Log.v(TAG, "Do in Background started!");
-
-            mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
-            mWakeLock = mPowerManager.newWakeLock(
-                    PowerManager.SCREEN_DIM_WAKE_LOCK, "CameraQualityTest");
-            mWakeLock.acquire();
-
-            mTestInProgress = true;
-
-            // Processes the camera tests one by one and publishes their
-            // debug output or debug text results after each test is done.
-            mCurrentTest.run((int)cameraTestIndex[0]);
-            publishProgress(cameraTestIndex);
-
-            Log.v(TAG, "Do in Background thread returns!");
-            return cameraTestIndex[0];
-        }
-
-        @Override
-        protected void onProgressUpdate(Integer... cameraTestIndex) {
-            Log.v(TAG, "Prepare to get debug output!");
-
-            // Copies the debug output image or text results to the UI.
-            mResultView.setImageBitmap(mCurrentTest.getDebugOutput());
-            mResultReport += (mCurrentTest.getTestName() + mCurrentTest.getDebugText());
-            mAdapter.notifyDataSetChanged();
-        }
-
-        @Override
-        protected void onPostExecute(Integer cameraTestIndex) {
-
-            // If the test is to find the color checker, copy the memory
-            // address of the found color checker centers and radius to the
-            // CameraTests class' static fields.
-            if (mCurrentTest.copyCheckerAddress()) {
-                mCheckerCenterAddress = CameraTests.getCheckerCenter();
-                mCheckerRadiusAddress = CameraTests.getCheckerRadius();
-            }
-
-            if (mCurrentTest.copyCheckerAddress() ||
-                !mCurrentTest.getTestName().contains("Color Checker")) {
-                // Enables the button of all other tests after the color checker
-                // is found. Now the user can start all other available tests.
-                enableAll();
-            }
-
-            mWakeLock.release();
-            mTestInProgress = false;
-            synchronized (mProcessingTest) {
-                mProcessingTest.notifyAll();
-            }
-
-        }
-    }
-
-    // Creates and runs a new test to find color checker in the captured image.
-    // It is invoked when users press the Find color checker button in the UI.
-    private View.OnClickListener mFindCheckerListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            Log.v(TAG, "Running new color checker finding tests!");
-            ColorCheckerTest colorCheckerTest = ColorCheckerTest.getSingletonTest();
-
-            mCurrentTest = colorCheckerTest;
-            initializeAdapter();
-        }
-    };
-
-    // Creates and runs a new test to test the exposure compensation function.
-    // It is invoked when users press the Exposure Compensation Test button
-    // in the UI.
-    private View.OnClickListener mExposureCompensationListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            Log.v(TAG, "Running new exposure compensation tests!");
-
-            ExposureCompensationTest exposureCompensationTest =
-                    ExposureCompensationTest.getSingletonTest();
-
-            mCurrentTest = exposureCompensationTest;
-            initializeAdapter();
-
-            // Loads the memory address of the checker centers and radius
-            // from the this class and set the two values for the new test.
-            ExposureCompensationTest.setCheckerAddress(mCheckerCenterAddress,
-                                                   mCheckerRadiusAddress);
-        }
-    };
-
-    // Creates and runs a new test to test the white balance function.
-    // It is invoked when users press the White Balance Test button in the UI.
-    private View.OnClickListener mWhiteBalanceListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            Log.v(TAG, "Running new white balance tests!");
-
-            WhiteBalanceTest whiteBalanceTest = WhiteBalanceTest.getSingletonTest();
-
-            mCurrentTest = whiteBalanceTest;
-            initializeAdapter();
-
-            // Loads the memory address of the checker centers and radius
-            // from the this class and set the two values for the new test.
-            WhiteBalanceTest.setCheckerAddress(mCheckerCenterAddress, mCheckerRadiusAddress);
-        }
-    };
-
-    // Creates and runs a new test to test the camera metering function.
-    // It is invoked when users press the Metering Test button in the UI.
-    private View.OnClickListener mMeteringListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            Log.v(TAG, "Running new metering tests!");
-
-            MeteringTest meteringTest = MeteringTest.getSingletonTest();
-
-            mCurrentTest = meteringTest;
-            initializeAdapter();
-
-            // Loads the memory address of the checker centers and radius
-            // from the this class and set the two values for the new test.
-            MeteringTest.setCheckerAddress(mCheckerCenterAddress, mCheckerRadiusAddress);
-        }
-    };
-
-    // Creates and runs new tests to test the camera auto exposure lock.
-    // It is invoked when users press the AWB and AE Lock Test button
-    // in the UI.
-    private View.OnClickListener mAutoLockListener = new View.OnClickListener() {
-        @Override
-        public void onClick(View v) {
-            Log.v(TAG, "Running New auto exposure/wb lock tests!");
-
-            // Loads the memory address of the checker centers and radius
-            // from the this class and set the two values for the new test.
-            AutoLockTest.setCheckerAddress(mCheckerCenterAddress, mCheckerRadiusAddress);
-
-            // Construct all base case test scenearios for the Auto Lock test.
-            // Detailed documentation on each test can be found in native code.
-            AutoLockTest autoLockTest = AutoLockTest.getSingletonTest();
-            autoLockTest.setActivity(CameraAnalyzerActivity.this);
-
-            mCurrentTest = autoLockTest;
-            initializeAdapter();
-
-        }
-    };
-
-    // Creates a list listner that launches the experiment with the user's click
-    private AdapterView.OnItemClickListener mListListener = new AdapterView.OnItemClickListener() {
-        @Override
-        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
-            Log.v(TAG, String.format("Item %d selected!", position));
-            if (!mTestInProgress) {
-                DebugOutputProcessingTask captureTask = new DebugOutputProcessingTask();
-                disableAll();
-                captureTask.execute(position);
-            }
-        }
-    };
-
-    private SurfaceHolder.Callback mSurfaceChangeListener =
-            new SurfaceHolder.Callback() {
-
-        // Sets the aspect ratio of the camera preview to 4:3
-        @Override
-        public void surfaceChanged(SurfaceHolder holder,
-                                   int format,
-                                   int width,
-                                   int height) {
-            int x = mCameraView.getWidth();
-            int y = mCameraView.getHeight();
-            Log.v(TAG, String.format("Measures are %d, %d", x, y));
-
-            if ( x > 4.0 / 3.0 * y) {
-                android.view.ViewGroup.LayoutParams lp = mCameraView.getLayoutParams();
-                lp.height =  y;
-                lp.width = (int)(4.0 / 3.0 * lp.height);
-                Log.v(TAG, String.format("params are %d, %d", lp.width, lp.height));
-                mCameraView.setLayoutParams(lp);
-            }
-
-            try {
-                mCamera.setPreviewDisplay(mCameraView.getHolder());
-            } catch (IOException e) {
-                throw new RuntimeException("Unable to connect camera to display: " + e);
-            }
-            CameraTests.setCameraView(mCameraView);
-            mCamera.startPreview();
-        }
-
-        @Override
-        public void surfaceCreated(SurfaceHolder holder) {}
-
-        @Override
-        public void surfaceDestroyed(SurfaceHolder holder) {}
-    };
-
-    @Override
-    public String getTestDetails() {
-        return mResultReport;
-    }
-
-    class TwoColumnAdapter extends ArrayAdapter<String> {
-        TwoColumnAdapter(Context context) {
-            super(context, R.layout.ca_row);
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            LayoutInflater inflater = getLayoutInflater();
-            View row = inflater.inflate(R.layout.ca_row, parent, false);
-            ImageView iconField = (ImageView) row.findViewById(R.id.caTestIcon);
-            TextView nameField = (TextView) row.findViewById(R.id.caTestName);
-            TextView resultField = (TextView) row.findViewById(R.id.caTestResult);
-            if (mCurrentTest != null) {
-                nameField.setText(mCurrentTest.getTestName(position));
-                int result = mCurrentTest.getResult(position);
-                switch (result) {
-                    case CameraTests.CAMERA_TEST_SUCCESS:
-                        resultField.setText("Success");
-                        iconField.setBackgroundColor(Color.rgb(0x99,0xCC,00));
-                        resultField.setTextColor(Color.rgb(0x99,0xCC,00));
-                        break;
-                    case CameraTests.CAMERA_TEST_FAILURE:
-                        resultField.setText("Failed!");
-                        iconField.setBackgroundColor(Color.rgb(0xFF,0x44,0x44));
-                        resultField.setTextColor(Color.rgb(0xFF,0x44,0x44));
-                        break;
-                    case CameraTests.CAMERA_TEST_NOT_RUN:
-                        resultField.setText("Tap to run");
-                        iconField.setBackgroundColor(Color.rgb(0x00,0x99,0xCC));
-                        resultField.setTextColor(Color.rgb(0x33,0xB5,0xE5));
-                        break;
-                }
-            }
-            return row;
-        }
-    }
-
-    private void initializeAdapter() {
-        mAdapter.clear();
-        if (mCurrentTest != null) {
-            for (int i = 0; i < mCurrentTest.getNumTests(); ++i) {
-                mAdapter.add(mCurrentTest.getTestName(i));
-            }
-        }
-    }
-
-    public int getCameraIdx() {
-        return mCameraIdx;
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraTests.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraTests.java
deleted file mode 100644
index ed99524..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/CameraTests.java
+++ /dev/null
@@ -1,201 +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.verifier.camera.analyzer;
-
-import android.graphics.Bitmap;
-import android.hardware.Camera;
-import android.os.Environment;
-import android.util.Log;
-import android.view.SurfaceView;
-
-import java.io.FileOutputStream;
-import java.io.File;
-import java.lang.Runnable;
-
-/**
- * Provides an abstraction for all camera tests and allows communication
- * between camera test classes with the UI thread. This base class provides
- * functions to contruct and access debug output images. It can access and
- * set the pointer address of checkerboard centers and radius. It also provides
- * native methods to convert an image shot by the camera into a native
- * character array. Another native method it provides is to create a native
- * test handler with desired debug height and width.
- */
-public abstract class CameraTests{
-
-    public static final int CAMERA_TEST_NOT_RUN = 0;
-    public static final int CAMERA_TEST_SUCCESS = 1;
-    public static final int CAMERA_TEST_FAILURE = 2;
-
-    private static final String TAG = "CameraTests";
-
-    /** Memory address of the color checker centers. */
-    private static long sCheckerCenterAddress = 0;
-    /** Memory address of the color checker radius. */
-    private static long sCheckerRadiusAddress = 0;
-    /** The surface view linked with the camera preview. */
-    private static SurfaceView sCameraView;
-    /** Image debug output. */
-    private Bitmap mDebugOutput;
-    /** Shared camera instance. */
-    protected static Camera mTestCamera = null;
-
-    /**
-     * Constructs the base CameraTests class.
-     */
-    public CameraTests() {}
-
-    /**
-     * Returns debug Bitmap image. In the test to find the color checker,
-     * the debug image will be the captured image with a matched color checker
-     * overlay on top. In the exposure compensation test, the debug image
-     * will be the response curve of the camera.
-     * @return A low-resolution Bitmap to be displayed in the UI.
-     */
-    public Bitmap getDebugOutput() {
-        return mDebugOutput;
-    }
-
-    public String getDebugText() {
-        return "";
-    }
-
-    public abstract String getTestName();
-
-    /**
-     * Gets the detailed report for CTS output.
-     */
-    public String getResultText(){
-        return "Details not available \n";
-    }
-
-    /**
-     * Provides a polymorphism to start the run() method for all child classes.
-     */
-    public abstract void run(int index);
-
-    public SurfaceView getCameraView() {
-        return sCameraView;
-    }
-
-    public static void setCameraView(SurfaceView cameraView) {
-        sCameraView = cameraView;
-    }
-
-    /**
-     * Refreshes the camera instance when the activity opens a new camera.
-     */
-    public static void setCamera(Camera newCamera) {
-        mTestCamera = newCamera;
-    }
-
-    public static Camera getCamera() {
-        return mTestCamera;
-    }
-
-    /**
-     * Sets the memory address of the checker centers and checker radius.
-     *
-     * @param inputCenterAddress the new memory address of
-     *                           the color checker centers
-     * @param inputRadiusAddress the new memory address of
-     *                           the color checker radius
-     */
-    public static void setCheckerAddress(long inputCenterAddress, long inputRadiusAddress) {
-        sCheckerCenterAddress = inputCenterAddress;
-        sCheckerRadiusAddress = inputRadiusAddress;
-    }
-
-    /**
-     * Provides polymorphism to indicate whether the checker memory addresses
-     * should be copied.
-     *
-     * @return <code>true</code> if the class invoking the method needs to
-     *                           update the memory address of the color checker
-     *                           centers and radius;
-     *         <code>false</code> if the class invoking the method does NOT
-     *                           update the memory address of the color checker
-     *                           centers and radius.
-     */
-    public boolean copyCheckerAddress() {
-        return false;
-    }
-
-    public void cleanUp() {
-    }
-
-    public static long getCheckerCenter() {
-        return sCheckerCenterAddress;
-    }
-
-    public static long getCheckerRadius() {
-        return sCheckerRadiusAddress;
-    }
-
-    public abstract String getTestName(int index);
-
-    public abstract int getResult(int index);
-
-    public abstract int getNumTests();
-
-    /**
-     * Provides a native method to convert the input Bitmap of the captured
-     * image into a native character array and constructs a native image class
-     * with this character array. This method currently supports conversion
-     * of Bitmaps in the formats of RGB_565 and RGB_8888.
-     *
-     * @param input the input Bitmap, which is decoded from the camrea data.
-     *
-     * @return the memory address of the native image class which contains
-     * the character array.
-     */
-    public native long findNative(Bitmap input);
-
-    /**
-     * Provides a native method to create a native image handler class. The
-     * native image handler class is the base class for all test classes and
-     * contains the debug output as a character array.
-     *
-     * @param outputHeight the desired height for the debug output
-     * @param outputWidth the desired width for the debug output
-     *
-     * @return the memory address of the native test handler class.
-     */
-    public native long createImageTestHandler(int outputHeight, int outputWidth);
-
-    /**
-     * Provides a native method to clean up the memory taken by the handler.
-     *
-     * @param handlerAddress the memory address of the native test handler,
-     * which contains the debug output.
-     */
-    public native void cleanUpHandler(long handlerAddress);
-
-    /**
-     * Provides a native method to convert the native debug output from
-     * character array back to Bitmap and copy it to the debug output of this
-     * class.
-     *
-     * @param handlerAddress the memory address of the native test handler,
-     * which contains the debug output.
-     */
-    public native void displayHandlerDebugOutput(long handlerAddress);
-
-    static {
-        System.loadLibrary("cameraanalyzer");
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ColorCheckerTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ColorCheckerTest.java
deleted file mode 100644
index ad171b4..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ColorCheckerTest.java
+++ /dev/null
@@ -1,299 +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.verifier.camera.analyzer;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.hardware.Camera;
-import android.util.Log;
-import android.widget.ImageView;
-
-import java.util.List;
-
-/** Locates a Xrite Classic Color Checker grid pattern in an image, stores the
- * center positions and the color checker radius, and provides a function to
- * get the memory address of these two properties.
- *
- * The pattern is a 6x4 grid of square color patches. The detection routine
- * assumes the pattern is placed roughly facing the camera, with the long size
- * roughly horizontal. It also assumes that the grey squares are in the bottom
- * row.
- */
-public class ColorCheckerTest extends CameraTests {
-
-    private static final String TAG = "ColorCheckerTest";
-
-    /** Memory address of the image class instance that contains the image. */
-    private long mClassAddress;
-    /** Memory address of the image test class instance. */
-    private long mTestHandler;
-    /** Thread lock. */
-    private final Object mProcessingImage = new Object();
-    /** Boolean to tell whether auto focus has succeded.*/
-    private boolean mAutoFocusSuccess;
-    /** Boolean to tell whether auto focus is supported.*/
-    private boolean mAutoFocusEnabled = false;
-    /** Singleton instance of the class.*/
-    private static ColorCheckerTest singletonTest = null;
-
-    private boolean mFindCheckerSuccess = false;
-    private boolean mHasRunOnce = false;
-
-    /**
-     * Constructs a <code>ColorCheckerTest</code> instance with a given
-     * Camera pointer.
-     */
-    private ColorCheckerTest() {
-        super();
-    }
-
-    /**
-     * Updates the camera and parameter when the activity switches camera.
-     */
-    public void updateCamera() {
-        Camera.Parameters params = mTestCamera.getParameters();
-        List<String> supportedFocusModes = params.getSupportedFocusModes();
-
-        // Sets camera focus mode to Auto focus if it is supported.
-        if (supportedFocusModes.contains(params.FOCUS_MODE_AUTO)) {
-            Log.v(TAG, "Auto focus possible");
-            params.setFocusMode(params.FOCUS_MODE_AUTO);
-            mTestCamera.setParameters(params);
-            mAutoFocusEnabled = true;
-        } else {
-            mAutoFocusEnabled = false;
-        }
-    }
-
-    public static synchronized ColorCheckerTest getSingletonTest() {
-        if (singletonTest == null) {
-            Log.v(TAG, "Creating a new ColorCheckerTest instance");
-            singletonTest = new ColorCheckerTest();
-            singletonTest.initializeTest();
-        }
-        return singletonTest;
-    }
-
-    private void initializeTest() {
-        // Creates a native test handler with a 120x160 pixel debug output
-        mTestHandler = createColorCheckerTest(120, 160);
-    }
-
-    @Override
-    public synchronized void run(int index) {
-        Log.v(TAG, "ColorCheckerTest thread started!");
-        mAutoFocusSuccess = false;
-        mFindCheckerSuccess = false;
-        mHasRunOnce = true;
-        // Sets camera focus mode to Auto focus if it is supported.
-        if (mAutoFocusEnabled) {
-            while (!mAutoFocusSuccess) {
-                // Starts the auto focus process of the camera.
-                mTestCamera.autoFocus(mAutoFocusListener);
-
-                // Locks thread until the camera finishes taking picture.
-                synchronized (mProcessingImage) {
-                    try{
-                        Log.v(TAG, "Start waiting for Image");
-                        mProcessingImage.wait();
-                    } catch (InterruptedException e) {
-                        Log.v(TAG, "Callback wait fails!");
-                    }
-                }
-            }
-        } else {
-            mTestCamera.takePicture(null, null, null, mTestJpegListener);
-            synchronized (mProcessingImage) {
-                try{
-                    Log.v(TAG, "Start waiting for Image");
-                    mProcessingImage.wait();
-                } catch (InterruptedException e) {
-                    Log.v(TAG, "Callback wait fails!");
-                }
-            }
-        }
-
-        // Launches the native method to find the color checker in the image.
-        mFindCheckerSuccess = processColorCheckerTest(mTestHandler);
-        // Displays the debug output from the native test handler instance.
-        displayHandlerDebugOutput(mTestHandler);
-
-        Log.v(TAG, "Callback has returned!");
-    }
-
-    private Camera.AutoFocusCallback mAutoFocusListener = new Camera.AutoFocusCallback() {
-        public void onAutoFocus(boolean mSuccess, Camera mCamera) {
-            if (mSuccess) {
-                mAutoFocusSuccess = true;
-                Log.v(TAG, "Autofocus success!");
-                mCamera.takePicture(null, null, null, mTestJpegListener);
-            } else {
-                try{
-                    Log.v(TAG, "Autofocus failed. Please adjust!");
-                    Thread.sleep(4000);
-                    Log.v(TAG, "END Waiting");
-                } catch (InterruptedException e){}
-
-                synchronized (mProcessingImage) {
-                    mProcessingImage.notifyAll();
-                }
-            }
-        }
-    };
-
-    private Camera.PictureCallback mTestJpegListener = new Camera.PictureCallback() {
-        public void onPictureTaken(byte[] data, Camera mCamera) {
-            Log.v(TAG, "Shutter pressed down!");
-
-            // Changes the focus mode to fixed to avoid focus shift after
-            // auto focus is successful.
-            //Camera.Parameters params = mCamera.getParameters();
-            //params.setFocusMode(params.FOCUS_MODE_FIXED);
-            //mCamera.setParameters(params);
-
-            // Decodes the camera data to Bitmap and creates a native image
-            // class with the Bitmap.
-            Bitmap inputImage;
-            inputImage = BitmapFactory.decodeByteArray(data, 0, data.length);
-            long bufferAddress = findNative(inputImage);
-            Log.v(TAG, "findNative method finishes");
-
-            // Cleans up the Bitmap memory space.
-            inputImage.recycle();
-            data = null;
-            inputImage = null;
-            System.gc();
-
-            // Constructs a test handler class to handle the image.
-            createColorCheckerClass(bufferAddress, mTestHandler);
-
-            mCamera.startPreview();
-
-            // Notifies the thread lock the image capture is done.
-            synchronized (mProcessingImage) {
-                mProcessingImage.notifyAll();
-            }
-        }
-    };
-
-    /**
-     * Overrides the base class method and use the memory addresses of the
-     * checker centers and radius computed by the native test handler class
-     * to update the values stored in the base class.
-     *
-     * @return <code>true</code> indicating a memory address upload is needed.
-     */
-    @Override
-    public boolean copyCheckerAddress() {
-        if (mFindCheckerSuccess) {
-            setCheckerAddress(getColorCheckerCenterAdd(mTestHandler),
-                              getColorCheckerRadiusAdd(mTestHandler));
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    @Override
-    public void cleanUp() {
-        cleanUpHandler(mTestHandler);
-    }
-
-    @Override
-    public String getTestName() {
-        return "Color Checker test: \n";
-    }
-
-    @Override
-    public String getTestName(int index) {
-        return "Find color checker";
-    }
-
-    @Override
-    public int getResult(int index) {
-        if (mFindCheckerSuccess) {
-            return CameraTests.CAMERA_TEST_SUCCESS;
-        } else {
-            if (mHasRunOnce) {
-                return CameraTests.CAMERA_TEST_FAILURE;
-            } else {
-                return CameraTests.CAMERA_TEST_NOT_RUN;
-            }
-        }
-    }
-
-    @Override
-    public int getNumTests() {
-        return 1;
-    }
-
-    /**
-     * Gets the memory address of the vector storing the color checker centers
-     * from the native test handler instance.
-     *
-     * @param handlerAddress the memory address of the native test handler
-     * instance
-     *
-     * @return memory address of the native vector storing the color checker
-     * centers' coordinates
-     */
-    private native long getColorCheckerRadiusAdd(long handlerAddress);
-
-    /**
-     * Gets the memory address of the vector storing the color checker radius
-     * from the native test handler instance.
-     *
-     * @param handlerAddress the memory address of the native test handler
-     * instance.
-     *
-     * @return memory address of the native vector storing the color checker
-     * centers' coordinates
-     */
-    private native long getColorCheckerCenterAdd(long handlerAddress);
-
-    /**
-     * Creates a native color checker test handler instance.
-     *
-     * @param outputWidth the desired width for the debug output
-     * @param outputHeight the desired height of the debug output
-     *
-     * @return memory address of the native test handler instance
-     */
-    private native long createColorCheckerTest(int outputWidth, int outputHeight);
-
-    /**
-     * Loads a native image class instances and extracts data from it to add
-     * to the test handler.
-     *
-     * @param bufferAddress the memory address of the image class instance
-     * @param handlerAddress the memory address of the test handler instance
-     */
-    private native void createColorCheckerClass(long bufferAddress, long handlerAddress);
-
-    /**
-     * Processes the data in the native test handler instance. Computes test
-     * results with all the data and construct a debug image or debug text
-     * outputs.
-     *
-     * @param handlerAddress the memory address of the test handler instance
-     */
-    private native boolean processColorCheckerTest(long handlerAddress);
-
-    static {
-        System.loadLibrary("cameraanalyzer");
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ExposureCompensationTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ExposureCompensationTest.java
deleted file mode 100644
index 9a8d9f0..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/ExposureCompensationTest.java
+++ /dev/null
@@ -1,215 +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.verifier.camera.analyzer;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.ImageFormat;
-import android.hardware.Camera;
-import android.util.Log;
-import android.widget.ImageView;
-
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.Random;
-
-public class ExposureCompensationTest extends CameraTests {
-
-    private static final String TAG = "ExposureCompensationTest";
-
-    /** Records the current exposure level. */
-    private float mExposureLevel;
-    /** Lock for the camera object.*/
-    private final Object mProcessingImage = new Object();
-    /** Lock for the camera's auto focusing task.*/
-    private final Object mAutoFocusing = new Object();
-    /** Memory address of the native test handler.*/
-    private long mTestHandler;
-    /** Test results. */
-    private int[] mTestResults;
-    /** Number of sub-tests. */
-    private int mNumTests;
-    /** Camera Parameters. */
-    private Camera.Parameters mParams;
-    /** Debug results in text. */
-    private String mDebugText;
-
-    private static ExposureCompensationTest singletonTest = null;
-
-    private ExposureCompensationTest(){
-        super();
-    }
-
-    /** Prepares the camera and the related parameters for the test.*/
-    public void updateCamera() {
-        mParams = mTestCamera.getParameters();
-        Log.v(TAG, String.format("Exposure level is from %d to %d",
-                                 mParams.getMinExposureCompensation(),
-                                 mParams.getMaxExposureCompensation()));
-        mNumTests = (int) ((float) (mParams.getMaxExposureCompensation() -
-                                    mParams.getMinExposureCompensation())
-                            * mParams.getExposureCompensationStep());
-        mTestResults = new int[mNumTests + 1];
-        for (int i = 0; i < mNumTests + 1; ++i) {
-            mTestResults[i] = CameraTests.CAMERA_TEST_NOT_RUN;
-        }
-    }
-
-    public static synchronized ExposureCompensationTest getSingletonTest() {
-        if (singletonTest == null) {
-            Log.v(TAG, "Creating a new ExposureCompensationTest instance");
-            singletonTest = new ExposureCompensationTest();
-            singletonTest.initializeTest();
-        }
-        return singletonTest;
-    }
-
-    private void initializeTest() {
-        mDebugText = new String();
-        // Creates a native test handler with a 120x160 pixel debug output
-        mTestHandler = createExposureCompensationTest(200, 280);
-    }
-
-    @Override
-    public synchronized void run(int index){
-        Log.v(TAG, "ExposureCompensationTest thread started!");
-
-        int testRangeMin, testRangeMax;
-        if (index == 0) {
-            testRangeMin = mParams.getMinExposureCompensation();
-            testRangeMax = mParams.getMaxExposureCompensation();
-        } else {
-            testRangeMin = (int) ((float)(index - 1) / mParams.getExposureCompensationStep())
-                    + mParams.getMinExposureCompensation();
-            testRangeMax = (int) ((float)(index) / mParams.getExposureCompensationStep())
-                    + mParams.getMinExposureCompensation();
-        }
-
-        /** Checks for each exposure compensation setting within the test range.*/
-        for (int i = testRangeMin;
-                i <= testRangeMax; i += 1){
-            mExposureLevel = i * mParams.getExposureCompensationStep();
-            Log.v(TAG, String.format("Current exposure level is %d", i));
-            int mCameraExposure;
-
-            do{
-                mParams.setExposureCompensation(i);
-                mTestCamera.setParameters(mParams);
-
-                try{
-                    Log.v(TAG, "Waiting");
-                    Thread.sleep(4000);
-                    Log.v(TAG, "END Waiting");
-                } catch (InterruptedException e){
-                    //TODO: error handling.
-                }
-
-                mParams = mTestCamera.getParameters();
-                mCameraExposure = mParams.getExposureCompensation();
-                Log.v(TAG, String.format("Camera exposure level is %d", mCameraExposure));
-            } while (mCameraExposure != i);
-
-            mTestCamera.takePicture(null, null, null, mTestJpegListener);
-
-            synchronized (mProcessingImage) {
-                try{
-                    Log.v(TAG, "Start waiting for Image");
-                    mProcessingImage.wait();
-                } catch (InterruptedException e){
-                    Log.v(TAG, "Callback wait fails!");
-                }
-            }
-        }
-
-        mDebugText = processExposureCompensationTest(mTestHandler);
-        displayHandlerDebugOutput(mTestHandler);
-
-        Log.v(TAG, "Callback has returned!");
-        mParams.setExposureCompensation(0);
-        mTestCamera.setParameters(mParams);
-    }
-
-    private Camera.PictureCallback mTestJpegListener = new Camera.PictureCallback() {
-        public void onPictureTaken(byte[] data, Camera mCamera) {
-            Log.v(TAG, "Shutter pressed down!");
-            Log.v(TAG, String.format("Current exposure is %f", mExposureLevel));
-
-            Bitmap inputImage;
-
-            inputImage = BitmapFactory.decodeByteArray(data, 0, data.length);
-            long bufferAddress = findNative(inputImage);
-            Log.v(TAG, "findNative method finishes");
-
-            inputImage.recycle();
-            data = null;
-            inputImage = null;
-            System.gc();
-
-            createExposureCompensationClass(bufferAddress, mTestHandler,
-                                            getCheckerCenter(), getCheckerRadius(),
-                                            mExposureLevel);
-            mCamera.startPreview();
-
-            synchronized (mProcessingImage) {
-                mProcessingImage.notifyAll();
-            }
-        }
-    };
-
-    @Override
-    public String getTestName(int index) {
-        switch (index) {
-            case 0:
-                return "EC All Range";
-            default:
-                return String.format("EC %d -> %d", (index - mNumTests / 2 - 1) * 10,
-                                     (index - mNumTests / 2) * 10);
-        }
-    }
-
-    @Override
-    public int getResult(int index) {
-        return mTestResults[index];
-    }
-
-    @Override
-    public int getNumTests() {
-        return mNumTests + 1;
-    }
-
-    @Override
-    public String getTestName() {
-        return "Exposure Compensation Test: \n";
-    }
-
-    @Override
-    public String getDebugText() {
-        return mDebugText;
-    }
-
-    private native long createExposureCompensationTest(int outputHeight, int outputWidth);
-
-    private native void createExposureCompensationClass(long bufferAddress, long handlerAddress,
-            long checkerCenterAddress, long checkerAadiusAddress, float mExposureLevel);
-
-    private native String processExposureCompensationTest(long handlerAddress);
-
-    static {
-        System.loadLibrary("cameraanalyzer");
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/MeteringTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/MeteringTest.java
deleted file mode 100644
index 9ff559f..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/MeteringTest.java
+++ /dev/null
@@ -1,685 +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.verifier.camera.analyzer;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.ImageFormat;
-import android.graphics.Rect;
-import android.hardware.Camera;
-import android.hardware.Camera.Area;
-import android.util.Log;
-import android.widget.ImageView;
-
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
-/**
- * Implements a test to verify whether the camera metering system works as
- * described in the API.
- *
- * The test consists two sub-categories. The first one has tests with only
- * one metering area defined. The second one has tests with two metering areas
- * defined. For each single sub-test, we use a random number generator to
- * decide where to put some of the metering areas to and how much weight should
- * be assigned to each area. For different tests, we use different ways to
- * define other metering areas and their weight, in order to cover all possible
- * fail cases. The metering areas are contrained to the grey squares in the
- * bottom of the color checker.
- */
-public class MeteringTest extends CameraTests {
-
-    private static final String TAG = "MeteringTest";
-
-    /** A long wait.*/
-    private static final int LONG_SLEEP = 4000;
-    /** Debug result in text. */
-    private String mDebugText;
-    /** Thread lock. */
-    private final Object mProcessingImage = new Object();
-    /** Memory address of the native test handler. */
-    private long mTestHandler;
-    /** The maximum number of metering area the device supports. */
-    private int mMaxNumMeteringArea;
-    /** The metering areas. */
-    private List<Camera.Area> mGreyAreas;
-    /** The coordinates of the grey squares on the color checker. */
-    private int[] mGreyCoordinates = new int[24];
-    /** Random number generator. */
-    private final Random mRandomGenerator = new Random();
-    /** Reference comparison result for tests. */
-    private ArrayList<Boolean>  mReferenceCompareResults;
-    /** Number of tests in the same instance. */
-    private int mTestCount;
-    /** Reference test logs. */
-    private ArrayList<String> mReferenceLogs;
-    /** Test result to show. */
-    private int[] mTestResults;
-    /** Number of tests. */
-    private int mNumTests;
-    /** Camera Parameters. */
-    private Camera.Parameters mParams;
-    /** Singleton test instance. */
-    private static MeteringTest singletonTest = null;
-
-    /** Constructs a <code>MeteringTest</code> instance with the given
-     * camera pointer.
-     */
-    private MeteringTest() {
-        super();
-    }
-
-    public void updateCamera() {
-        // Looks up how many metering area the device supports.
-        mParams = mTestCamera.getParameters();
-        mMaxNumMeteringArea = mParams.getMaxNumMeteringAreas();
-        Log.v(TAG, String.format("Maximum number if metering area is %d", mMaxNumMeteringArea));
-        if (mMaxNumMeteringArea == 0) {
-            mDebugText = "Custom Metering not supported!";
-            Log.v(TAG, "Custom Metering not supported");
-        }
-    }
-
-    public static synchronized MeteringTest getSingletonTest() {
-        if (singletonTest == null) {
-            Log.v(TAG, "Creating a new MeteringTest instance");
-            singletonTest = new MeteringTest();
-            singletonTest.initializeTest();
-        }
-        return singletonTest;
-    }
-
-    private void initializeTest() {
-        // Creates a native metering test handler.
-        mTestHandler = createMeteringTest();
-        mDebugText = new String();
-        mReferenceCompareResults = new ArrayList<Boolean>();
-        mReferenceLogs = new ArrayList<String>();
-        mNumTests = 3;
-        mTestResults = new int[mNumTests];
-        for (int i = 0; i < mNumTests; ++i) {
-            mTestResults[i] = CameraTests.CAMERA_TEST_NOT_RUN;
-        }
-    }
-
-    /**
-     * Runs the metering test instance.
-     */
-    @Override
-    public synchronized void run(int index) {
-        if (index == 0) {
-            run(1);
-            run(2);
-            return;
-        }
-        Log.v(TAG, "MeteringTest thread started!");
-
-        // Finds the coordinates of the grey squares on the color checker.
-        // The coordinate system has (-1000, -1000) on the upper left corner.
-        // And (1000, 1000) on the bottom right corner.
-        findGreyCoordinates(mGreyCoordinates, getCheckerCenter(), getCheckerRadius());
-
-        if (mMaxNumMeteringArea > 0) {
-            mTestCount = 0;
-            // Runs the metering tests category by category.
-            switch (index) {
-                case 1:
-                    runOneAreaTest();
-                    break;
-                case 2:
-                    if (mMaxNumMeteringArea > 1) {
-                        runTwoAreasTest();
-                    }
-                    break;
-                default:
-                    break;
-            }
-        }
-
-        mParams = mTestCamera.getParameters();
-        mParams.setMeteringAreas(null);
-        mTestCamera.setParameters(mParams);
-
-        boolean[] testCompareResults = new boolean[2 * mTestCount];
-
-        // Processes the image data taken so far and stores the test results.
-        processMeteringTest(mTestHandler, testCompareResults);
-        // Prepares debug output based on the test results.
-        prepareDebugText(testCompareResults, index);
-
-        mReferenceCompareResults.clear();
-        mReferenceLogs.clear();
-    }
-
-    /**
-     * Prepares the test results in HTML text string to show in the UI.
-     *
-     * If the test result is the same as the reference result, the text will be
-     * shown in green. Otherwise it would be shown as red.
-     *
-     * @param testCompareResults the array storing the comparison results from
-     * the data taken by the camera so far.
-     */
-    private void prepareDebugText(boolean[] testCompareResults, int index) {
-        mDebugText = "";
-        boolean groupTestPassed = true;
-        for (int i = 0; i < mTestCount; ++i) {
-              String testLog;
-              boolean testPassed = true;
-              testLog = mReferenceLogs.get(i);
-              mDebugText += (testLog + "<br/>");
-
-              if (testCompareResults[i * 2] == mReferenceCompareResults.get(i * 2)) {
-                  mDebugText += String.format(
-                      "Picture 1 equivalent to Picture 2 is %b \n",
-                      testCompareResults[i * 2]);
-              } else {
-                  mDebugText += String.format(
-                      "Picture 1 equivalent to Picture 2 is %b \n",
-                      testCompareResults[i * 2]);
-                  testPassed = false;
-              }
-
-              if (testCompareResults[i * 2 + 1] == mReferenceCompareResults.get(i * 2 + 1)) {
-                  mDebugText += String.format(
-                      "Picture 1 darker than Picture 2 is %b \n",
-                      testCompareResults[i * 2 + 1]);
-              } else {
-                  mDebugText += String.format(
-                      "Picture 1 darker than Picture 2 is %b \n",
-                      testCompareResults[i * 2 + 1]);
-                  testPassed = false;
-              }
-
-              if (testPassed) {
-                  mDebugText += "Test passed! \n";
-              } else {
-                  mDebugText += "Test failed! \n";
-                  groupTestPassed = false;
-              }
-              Log.v(TAG, String.format("%s", mDebugText));
-         }
-
-        if (groupTestPassed) {
-            mTestResults[index] = CameraTests.CAMERA_TEST_SUCCESS;
-        } else {
-            mTestResults[index] = CameraTests.CAMERA_TEST_FAILURE;
-        }
-
-    }
-
-    /**
-     * Runs tests to check whether the metering functionalities work properly
-     * when one metering area is added.
-     */
-    private void runOneAreaTest() {
-        int weight1;
-        int weight2;
-        int square1;
-        int square2;
-
-        Log.v(TAG, "Running one area Test");
-
-        // Test case 1: Two images have the same metering area. Image 1 has
-        // a diffent weight than Image 2. The result images should be
-        // identical.
-        // Tests whether weight normalization works.
-        square1 = mRandomGenerator.nextInt(6);
-        weight1 = mRandomGenerator.nextInt(100) + 1;
-        runSingleTest(square1, square1, weight1);
-
-        square2 = square1;
-        weight2 = mRandomGenerator.nextInt(100) + 901;
-        runSingleTest(square2, square2, weight2);
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        Log.v(TAG, String.format("Running test for %d square with weights %d, %d",
-                                 square1, weight1, weight2));
-        mReferenceLogs.add(String.format(
-            "Running test for %d 1x1 square with weights %d, %d", square1, weight1, weight2));
-        ++mTestCount;
-
-        // Test case 2: Two images have different metering areas. Image 1 has
-        // one of the grey squares as its metering area. Image 2 has a darker
-        // grey square as its metering area. The weights for both images are
-        // the same. Image 1 is expected to be darker than Image 2.
-        // Tests whether metering on uni-brightness patches work.
-        square1 = mRandomGenerator.nextInt(5);
-        weight1 = mRandomGenerator.nextInt(1000) + 1;
-        runSingleTest(square1, square1, weight1);
-
-        square2 = mRandomGenerator.nextInt(6 - square1 - 1) + square1 + 1;
-        weight2 = weight1;
-        runSingleTest(square2, square2, weight2);
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add(String.format(
-            "Running test for %d, %d 1x1 square with weight %d", square1, square2, weight1));
-        ++mTestCount;
-
-        // Test case 3: Two images have different metering areas. Image one has
-        // one of the grey squares as its metering area. Image 2 has a
-        // rectangle which contains Image 1's metering area and the neighboring
-        // darker grey square. The weights for both tests are the same. Image 1
-        // is expected to be darker than Image 2.
-        // Tests whether metering on patches with different brightness works.
-        square1 = mRandomGenerator.nextInt(5);
-        weight1 = mRandomGenerator.nextInt(1000) + 1;
-        runSingleTest(square1, square1, weight1);
-
-        square2 = square1;
-        weight2 = weight1;
-        runSingleTest(square2, square2 + 1, weight2);
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add(String.format(
-            "Running test for %d 1x1, 1x2 square with weight %d", square1, weight1));
-        ++mTestCount;
-
-        // Test case 4: Two images have different metering areas. Image one has
-        // two neighboring grey squares as its metering area. Image 2 has two
-        // darker neighboring grey squares as its metering area. Weights are
-        // the same for both images. Image 1 is expected to be darker than
-        // Image 2.
-        // Tests whether metering on two mixed-brightness patches work.
-        square1 = mRandomGenerator.nextInt(4);
-        weight1 = mRandomGenerator.nextInt(1000) + 1;
-        runSingleTest(square1, square1 + 1, weight1);
-
-        square2 = mRandomGenerator.nextInt(5 - square1 - 1) + square1 + 1;
-        weight2 = weight1;
-        runSingleTest(square2, square2 + 1, weight2);
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add(String.format(
-            "Running test for %d, %d 1x2 square with weight %d", square1, square2, weight1));
-        ++mTestCount;
-
-        // Test case 5: Two images have different metering areas. Image one has
-        // three neighboring grey squares as its metering area. Image 2 has
-        // three darker neighboring grey squares as its metering area. Weights
-        // are the same. Image 1 is expected to be darker than Image 2.
-        // Tests whether metering on three mixed-brightness patches work.
-        square1 = mRandomGenerator.nextInt(3);
-        weight1 = mRandomGenerator.nextInt(1000) + 1;
-        runSingleTest(square1, square1 + 2, weight1);
-
-        square2 = mRandomGenerator.nextInt(4 - square1 - 1) + square1 + 1;
-        weight2 = weight1;
-        runSingleTest(square2, square2 + 2, weight2);
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add(String.format(
-            "Running test for %d, %d 1x3 square with weight %d", square1, square2, weight1));
-        ++mTestCount;
-    }
-
-    /**
-     * Runs metering tests to verify the functionalities when there are two
-     * areas set as the metering area.
-     */
-    private void runTwoAreasTest() {
-        int[] weight1 = new int[2];
-        int[] weight2 = new int[2];
-        int[] square1Start = new int[2];
-        int[] square2Start = new int[2];
-        int[] square1End = new int[2];
-        int[] square2End = new int[2];
-
-        Log.v(TAG, "Running two-area Test");
-
-        // Test case 1: Image 1 has two metering areas. They are two adjacent
-        // grey squares (each set as a metering area). The two areas have the
-        // same weight. Image 2 has one metering area, which is the combination
-        // of Image 1's two metering areas as a rectangle. The weight is the
-        // same as that of Image 1's individual area. Image 1 is expected to
-        // be equivalent to Image 2.
-        // Tests whether having seperating a metering area into two will yield
-        // the same result.
-        square1Start[0] = mRandomGenerator.nextInt(5);
-        square1End[0] = square1Start[0];
-        weight1[0] = mRandomGenerator.nextInt(1000) + 1;
-        square1Start[1] = square1Start[0] + 1;
-        square1End[1] = square1Start[1];
-        weight1[1] = weight1[0];
-        runMultipleAreaTest(square1Start, square1End, weight1);
-
-        square2Start[0] = square1Start[0];
-        weight2[0] = weight1[0];
-        runSingleTest(square2Start[0], square2Start[0] + 1, weight2[0]);
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add(String.format(
-            "Running test for %d, %d 1x1 square with weight %d",
-            square1Start[0], square1Start[1], weight1[0]));
-        ++mTestCount;
-
-        // Test case 2: Image 1 has two metering areas. They are two random
-        // grey squareson the color checker. The brighter square has a larger
-        // weight than the darker square. Image 2 has the same two metering
-        // areas as Image 1. The weights for both are equal to the weight of
-        // the darker square in Image 1, which is smaller than the weight of
-        // the brighter square in Image 1. Image 1 is expected to be darker
-        // than Image 2.
-        // Tests whether giving one of the two metering areas a different
-        // weight would change the image in the correct way.
-        square1Start[0] = mRandomGenerator.nextInt(4);
-        square1End[0] = square1Start[0];
-        weight1[0] = mRandomGenerator.nextInt(100) + 901;
-        square1Start[1] = mRandomGenerator.nextInt(5 - square1Start[0] - 1) + square1Start[0] + 1;
-        square1End[1] = square1Start[1];
-        weight1[1] = mRandomGenerator.nextInt(100) + 1;
-        runMultipleAreaTest(square1Start, square1End, weight1);
-
-        square2Start[0] = square1Start[0];
-        square2End[0] = square2Start[0];
-        weight2[0] = weight1[1];
-        square2Start[1] = square1Start[1];
-        square2End[1] = square1End[1];
-        weight2[1] = weight2[0];
-        runMultipleAreaTest(square2Start, square2End, weight2);
-        mReferenceCompareResults.add(false);
-        mReferenceCompareResults.add(true);
-        mReferenceLogs.add(String.format(
-            "Running test for %d, %d 1x1 square with weight %d, %d",
-            square1Start[0], square1Start[1], weight1[0], weight2[1]));
-        ++mTestCount;
-
-        // Test case 3: Image 1 has two metering areas. Both are set to the
-        // same random grey square on the color checker. The weight for both
-        // are the same. Image 2 has one meterig area, which is the same as
-        // Image 1's chosen grey square. The weight for it is the same as
-        // Image 1's weight for one metering area. Image 1 is expected to be
-        // equivalent to Image 2.
-        // Tests whether defining overlapping metering area works.
-        square1Start[0] = mRandomGenerator.nextInt(6);
-        square1End[0] = square1Start[0];
-        weight1[0] = mRandomGenerator.nextInt(1000) + 1;
-        square1Start[1] = square1Start[0];
-        square1End[1] = square1Start[1];
-        weight1[1] = weight1[0];
-        runMultipleAreaTest(square1Start, square1End, weight1);
-
-        square2Start[0] = square1Start[0];
-        square2End[0] = square2Start[0];
-        weight2[0] = weight1[0];
-        runSingleTest(square2Start[0], square2End[0], weight2[0]);
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add(String.format(
-            "Running test for %d 1x1 square with weight %d,", square1Start[0], weight1[0]));
-        ++mTestCount;
-
-        // Test case 4: Image 1 has two metering areas. The first one is a
-        // grey square on the color checker. The second one is a rectangle
-        // containing the first metering area's grey square and its neighboring
-        // darker square. The weights for both metering area are the same.
-        // Image 2 has two metering areas. The first one is the same grey
-        // square as Image 1's first metering area. The second one is the
-        // neighboring darker grey square. The weight for the brighter square
-        // is double the weight of Image 1's weights for each metering area.
-        // The weight for the Image 2's darker grey square is the same as
-        // Image 1's weight for each of its metering areas. Image 1 is expected
-        // to be equivalent to Image 2.
-        // Tests whether the weights for overlapping metering area add up.
-        square1Start[0] = mRandomGenerator.nextInt(2);
-        square1End[0] = square1Start[0];
-        weight1[0] = mRandomGenerator.nextInt(500) + 1;
-        square1Start[1] = square1Start[0];
-        square1End[1] = square1Start[1] + 1;
-        weight1[1] = weight1[0];
-        runMultipleAreaTest(square1Start, square1End, weight1);
-
-        square2Start[0] = square1Start[0];
-        square2End[0] = square1End[0];
-        weight2[0] = weight1[0] * 2;
-        square2Start[1] = square2Start[0] + 1;
-        square2End[1] = square2Start[1];
-        weight2[1] = weight1[1];
-        runMultipleAreaTest(square2Start, square2End, weight2);
-        mReferenceCompareResults.add(true);
-        mReferenceCompareResults.add(false);
-        mReferenceLogs.add(String.format(
-            "Running test for %d 1x2 1x1 and 1x2 square with weight %d,",
-            square1Start[0], weight1[0]));
-        ++mTestCount;
-    }
-
-    /**
-     * Runs the metering test when multiple metering areas are defined.
-     *
-     * @param startIndex the array storing the index of the grey square where
-     * one metering area starts
-     * @param endIndex the array storing the index of the grey square where one
-     * metering area ends.
-     * @param weight the array storing the weight for each metering area.
-     */
-    private void runMultipleAreaTest(int[] startIndex, int[] endIndex, int[] weight) {
-        int numAreas = startIndex.length;
-        mParams = mTestCamera.getParameters();
-        List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
-
-        for (int i = 0; i < numAreas; ++i) {
-            meteringAreas.add(makeArea(startIndex[i], endIndex[i], weight[i]));
-            Log.v(TAG, String.format("Add metering area for %d, %d, %d",
-                                     startIndex[i], endIndex[i], weight[i]));
-        }
-        mParams.setMeteringAreas(meteringAreas);
-        mTestCamera.setParameters(mParams);
-        takePicture();
-    }
-
-    /**
-     * Runs the metering test when one metering area is defined.
-     *
-     * @param startIndex the index of the grey square where the metering area
-     * starts
-     * @param endIndex the index of the grey square where the metering area
-     * ends.
-     * @param weight the weight for the metering area.
-     */
-    private void runSingleTest(int startIndex, int endIndex, int weight) {
-        mParams = mTestCamera.getParameters();
-        List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
-
-        Log.v(TAG, String.format("Single test for %d, %d, %d", startIndex, endIndex, weight));
-        meteringAreas.add(makeArea(startIndex, endIndex, weight));
-        mParams.setMeteringAreas(meteringAreas);
-        mTestCamera.setParameters(mParams);
-        takePicture();
-    }
-
-    /**
-     * Takes picture with the camera instance linked to this test class.
-     */
-    private void takePicture() {
-        // Waits for the metering to be stable
-        try{
-            Log.v(TAG, "Waiting for metering");
-            Thread.sleep(LONG_SLEEP);
-            Log.v(TAG, "END Waiting");
-        } catch (InterruptedException e) {}
-
-        mTestCamera.takePicture(null, null, null, mTestJpegListener);
-
-        // Locks thread until picture is taken and ready for processing.
-        synchronized (mProcessingImage) {
-            try{
-                Log.v(TAG, "Start waiting for Image");
-
-                mProcessingImage.wait();
-            } catch (InterruptedException e) {
-                Log.v(TAG, "Callback wait fails!");
-            }
-        }
-    }
-
-    /**
-     * Constructs a <code>Camera.Area</code> object of the metering area.
-     * Given the start and end index of one metering area, it takes the upper
-     * left corner of the starting square and the bottom right corner of the
-     * end square to construct an Area.
-     *
-     * @param startIndex the index of the grey square where the metering area
-     * starts
-     * @param endIndex the index of the grey square where the metering area
-     * ends
-     * @param weight the weight of this metering area.
-     *
-     * @return a <code>Camera.Area</code> object which represents this metering
-     * area
-     */
-    private Camera.Area makeArea(int startIndex, int endIndex, int weight) {
-        Rect areaRect = new Rect(mGreyCoordinates[startIndex * 4],
-                                 mGreyCoordinates[startIndex * 4 + 1],
-                                 mGreyCoordinates[endIndex * 4 + 2],
-                                 mGreyCoordinates[endIndex * 4 + 3]);
-        Camera.Area area = new Camera.Area(areaRect, weight);
-
-        return area;
-    }
-
-    @Override
-    public String getDebugText() {
-        return mDebugText;
-    }
-
-    @Override
-    public String getResultText() {
-        return mDebugText;
-    }
-
-    @Override
-    public String getTestName() {
-        return "Metering Test: \n";
-    }
-
-    @Override
-    public String getTestName(int index) {
-        switch (index) {
-            case 0:
-                return "Run all tests";
-            case 1:
-                return "One metering area tests";
-            case 2:
-                return "Multiple metering areas tests";
-            default:
-                return "";
-        }
-    }
-
-    @Override
-    public int getResult(int index) {
-        return mTestResults[index];
-    }
-
-    @Override
-    public int getNumTests() {
-        return mNumTests;
-    }
-
-    private Camera.PictureCallback mTestJpegListener = new Camera.PictureCallback() {
-        public void onPictureTaken(byte[] data, Camera mCamera) {
-            Log.v(TAG, "Shutter pressed down!");
-            Bitmap inputImage;
-            try {
-                FileOutputStream outStream = new FileOutputStream(
-                    String.format("/sdcard/metering%d.jpg", System.currentTimeMillis()));
-                outStream.write(data);
-                outStream.close();
-            } catch (FileNotFoundException e) {
-            } catch (IOException e) {}
-
-            // Decodes the input data of the camera.
-            inputImage = BitmapFactory.decodeByteArray(data, 0, data.length);
-
-            // Records the memory address of the native image class instance.
-            long bufferAddress = findNative(inputImage);
-            Log.v(TAG, "findNative method finishes");
-
-            // Cleans up the memory taken by the bitmap.
-            inputImage.recycle();
-            data = null;
-            inputImage = null;
-            System.gc();
-
-            // Add the image data to the native test handler.
-            createMeteringClass(bufferAddress, mTestHandler,
-                                getCheckerCenter(), getCheckerRadius());
-            mCamera.startPreview();
-
-            // Releases thread lock after the image is processed.
-            synchronized (mProcessingImage) {
-                mProcessingImage.notifyAll();
-            }
-        }
-    };
-
-    /**
-     * Finds the coordinates of the grey squares on the color checker.
-     * The coordinates are computed by using the checker center and radius.
-     * The coordinates are converted to a system with (-1000, -1000) in the
-     * upper left corner and (1000, 1000) in the  bottom right corner.
-     *
-     * @param greyCoordinates the array to store the coordinates of the grey
-     * squares
-     * @param checkerCenterAddress the memory address pointing to the vector
-     * storing the color checker's centers.
-     * @param checkerRadiusAddress the memory address pointing to the vetor
-     * storing the color checker's radius.
-     */
-    private native void findGreyCoordinates(int[] greyCoordinates,
-                                            long checkerCenterAddress, long checkerRadiusAddress);
-
-    /**
-     * Creates the native metering test handler with no debug image.
-     *
-     * @return the memory address pointing to the native test handler instance
-     */
-    private native long createMeteringTest();
-
-    /**
-     * Adds the data from the native image class instance to the native test
-     * handler.
-     *
-     * @param bufferAddress the meory address of the native image class
-     * @param handlerAddress the memory address of the native test handler
-     * @param checkerCenterAddress the memory address of the checker cneters
-     * @param checkerRadiusAddress the meory address of the checker radius
-     */
-    private native void createMeteringClass(long bufferAddress, long handlerAddress,
-                                            long checkerCenterAddress,
-                                            long checkerRadiusAddress);
-
-    /**
-     * Process the data stored in the native test handler and stores the
-     * comparison results.
-     *
-     * @param handlerAddress the memory address of the native test handler
-     * @param testCompareResults the boolean array to store the test comparison
-     * results
-     */
-    private native void processMeteringTest(long handlerAddress, boolean[] testCompareResults);
-
-    static {
-        System.loadLibrary("cameraanalyzer");
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/WhiteBalanceTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/WhiteBalanceTest.java
deleted file mode 100644
index a4111eb..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/analyzer/WhiteBalanceTest.java
+++ /dev/null
@@ -1,398 +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.verifier.camera.analyzer;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.ImageFormat;
-import android.hardware.Camera;
-import android.util.Log;
-import android.widget.ImageView;
-import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-
-import java.util.List;
-
-/**
- * Implements a test to verify whether the correlated color temperatures (CTT)
- * of the supported white balance modes are inside the range camera
- * manufacturers generally agree on.
- *
- * The test assumes that the Daylight white balance mode has a CCT of 5200K,
- * which is widely agreed in industry and academics. It then use this as a
- * benchmark and compare images taken with other white balance settings.
- * Using the pixel values of the grey squares on the color checker, the CCT
- * of other white balance modes can be computed. The reference ranges were
- * summarized with the help of online resources. For the Auto mode, the
- * reference CCT is computed as the CCT that will keep the grey squares appear
- * grey in the result image.
- */
-public class WhiteBalanceTest extends CameraTests {
-
-    private static final String TAG = "WhiteBalanceTest";
-
-    /** Current white balance mode. */
-    private String mWhiteBalance;
-    /** Array to store the reference CCT's of each mode. */
-    private int[][] mReferenceTemperature;
-    /** List of supported white balance mode on a device. */
-    private List<String> mWhiteBalanceList;
-    /** The index of the white balance mode "Auto". */
-    private int mAutoId;
-
-    /** Debug results in text. */
-    private String mDebugText;
-    /** Memory address of the native test handler instance. */
-    private long mTestHandler;
-    /** Thread lock. */
-    private final Object mProcessingImage = new Object();
-    /** Test result to show. */
-    private int[] mTestResults;
-    /** Number of test. */
-    private int mNumTests;
-    /** Camera Parameters. */
-    private Camera.Parameters mParams;
-    /** Singleton test instance. */
-    private static WhiteBalanceTest singletonTest = null;
-    /** Boolean to check whehter daylight wb has been recorded. */
-    private boolean mHasDaylight = false;
-
-    /**
-     * Constructs a <code>WhiteBalanceTest</code> instance with a given
-     * Camera pointer.
-     */
-    private WhiteBalanceTest() {
-        super();
-    }
-
-    public void updateCamera() {
-        mAutoId = 0;
-        mHasDaylight = false;
-        mParams = mTestCamera.getParameters();
-        mWhiteBalanceList = mParams.getSupportedWhiteBalance();
-        mNumTests = mWhiteBalanceList.size() + 1;
-        mTestResults = new int[mNumTests];
-        for (int i = 0; i < mNumTests; ++i) {
-            mTestResults[i] = CameraTests.CAMERA_TEST_NOT_RUN;
-        }
-
-        if (mWhiteBalanceList != null) {
-            mReferenceTemperature = new int[mWhiteBalanceList.size()][2];
-
-            // Sets the reference CCT of the supported white balance modes
-            for (int i = 0; i < mWhiteBalanceList.size(); i++) {
-                setReferenceTemperature(i, mWhiteBalanceList.get(i));
-                if (mWhiteBalanceList.get(i).equals("auto")) {
-                    mAutoId = i;
-                }
-            }
-        }
-    }
-
-    public static synchronized WhiteBalanceTest getSingletonTest() {
-        if (singletonTest == null) {
-            Log.v(TAG, "Creating a new WhiteBalanceTest instance");
-            singletonTest = new WhiteBalanceTest();
-            singletonTest.initializeTest();
-        }
-        return singletonTest;
-    }
-
-    private void initializeTest() {
-        mDebugText = new String();
-        // Creates a native white balance test handler.
-        // mTestHandler stores the memory address of this instance.
-        mTestHandler = createWhiteBalanceTest();
-    }
-
-    private void initializeWhiteBalanceTest() {
-        mWhiteBalance = "daylight";
-        takePicture(mWhiteBalance);
-        int colorTemperature = processWhiteBalanceTest(mTestHandler);
-
-        setReferenceTemperature(mAutoId, colorTemperature);
-        mHasDaylight = true;
-    }
-
-    private void takePicture(String whiteBalance) {
-        mParams.setWhiteBalance(whiteBalance);
-        mTestCamera.setParameters(mParams);
-
-        try{
-            Log.v(TAG, "Waiting for white balance to adjust");
-            Thread.sleep(4000);
-            Log.v(TAG, "END Waiting");
-        } catch (InterruptedException e) {}
-
-        mTestCamera.takePicture(null, null, null, mTestJpegListener);
-
-        // Thread locks until image capture is done
-        synchronized (mProcessingImage) {
-            try{
-                Log.v(TAG, "Start waiting for Image");
-                mProcessingImage.wait();
-            } catch (InterruptedException e) {
-                Log.v(TAG, "Callback wait fails!");
-            }
-        }
-    }
-
-    /**
-     * Runs the white balance camera test instance.
-     */
-    @Override
-    public synchronized void run(int index) {
-        Log.v(TAG, "WhiteBalanceTest thread started!");
-
-        if (!mHasDaylight) {
-            initializeWhiteBalanceTest();
-        }
-
-        if (index != 0) {
-            // Retrieves the list of supported white balance mode.
-            mParams = mTestCamera.getParameters();
-
-            int i = index - 1;
-            mWhiteBalance = mWhiteBalanceList.get(i);
-
-            Log.v(TAG, "Current white balance is " + mWhiteBalance);
-
-            takePicture(mWhiteBalance);
-
-            // Processes the white balance test data in the native code.
-            // Returns an array of CCT of each white balance modes, given the CCT
-            // of the "Daylight" mode is 5200K.
-            int colorTemperature = 0;
-
-            Log.v(TAG, "Finished taking picture, ready to process");
-            colorTemperature = processWhiteBalanceTest(mTestHandler);
-
-            // Records the index of the "Auto" white balance mode
-            if (mWhiteBalance.equals("daylight")) {
-                setReferenceTemperature(mAutoId, colorTemperature);
-                prepareDebugText(5200, index);
-                // Computes the reference CCT range of the "Auto" mode. Assuming that
-                // all grey squares on the color checker should be imaged as grey under
-                // a CCT, this CCT is used as a middle point to provide a range.
-                //setReferenceTemperature(mAutoId, colorTemperature[mWhiteBalanceList.size()]);
-            } else {
-                // Prepares the debug output.
-                prepareDebugText(colorTemperature, index);
-            }
-        } else {
-            for (int i = 0; i < mWhiteBalanceList.size(); i++) {
-                run(i + 1);
-            }
-        }
-
-        mParams.setWhiteBalance("auto");
-        mTestCamera.setParameters(mParams);
-    }
-
-    /**
-     * Prepares the debug results in HTML text. For each white balance mode,
-     * the CCT will be printed in green if it is in the reference range and
-     * red otherwise. The reference CCT range is also printed below, with
-     * green meaning the CCT range is satisfied and red otherwise.
-     *
-     * @param colorTemperature the CCT of the supported white balance modes
-     */
-    private void prepareDebugText(int colorTemperature, int index) {
-        mDebugText += String.format("CCT Ref is %d, %d, and CCT is %d",
-                                  mReferenceTemperature[index - 1][0],
-                                  mReferenceTemperature[index - 1][1],
-                                  colorTemperature);
-        Log.v(TAG, String.format("CCT Ref is %d, %d, and CCT is %d",
-                                  mReferenceTemperature[index - 1][0],
-                                  mReferenceTemperature[index - 1][1],
-                                  colorTemperature));
-        if ((colorTemperature >= mReferenceTemperature[index - 1][0]) &&
-                (colorTemperature <= mReferenceTemperature[index - 1][1])) {
-            mTestResults[index] = CameraTests.CAMERA_TEST_SUCCESS;
-        } else {
-            mTestResults[index] = CameraTests.CAMERA_TEST_FAILURE;
-        }
-
-    }
-
-    @Override
-    public String getDebugText() {
-        return mDebugText;
-    }
-
-    @Override
-    public String getResultText() {
-        return mDebugText;
-    }
-
-    @Override
-    public String getTestName() {
-        return "White Balance Test: \n";
-    }
-
-    @Override
-    public String getTestName(int index) {
-        if (index != 0){
-            return String.format("%s mode test", mWhiteBalanceList.get(index - 1));
-        } else {
-            return "Run all tests";
-        }
-    }
-
-    @Override
-    public int getResult(int index) {
-        return mTestResults[index];
-    }
-
-    @Override
-    public int getNumTests() {
-        return mNumTests;
-    }
-
-    /**
-     * Sets the reference temperatures for the white balance modes of
-     * incandescent, fluorescent, warm-fluorescent, daylight, cloudy, shade
-     * and twilight. These are the currently supported White balance mode
-     * listed on the Android camera API.
-     *
-     * The reference range are summarized based on the published settings of
-     * Canon, Nikon and the references from Wikipedia on color temperature.
-     *
-     * @param i the index of the current white balance mode
-     * @param referenceWhiteBalance the name of the white balance mode.
-     */
-    private void setReferenceTemperature(int i, String referenceWhiteBalance) {
-        if (referenceWhiteBalance.equals("incandescent")) {
-            mReferenceTemperature[i][0] = 2500;
-            mReferenceTemperature[i][1] = 3500;
-        } else if (referenceWhiteBalance.equals("fluorescent")) {
-            mReferenceTemperature[i][0] = 3000;
-            mReferenceTemperature[i][1] = 6500;
-        } else if (referenceWhiteBalance.equals("warm-fluorescent")) {
-            mReferenceTemperature[i][0] = 2500;
-            mReferenceTemperature[i][1] = 3000;
-        } else if (referenceWhiteBalance.equals("daylight")) {
-            mReferenceTemperature[i][0] = 5000;
-            mReferenceTemperature[i][1] = 5400;
-        } else if (referenceWhiteBalance.equals("cloudy-daylight")) {
-            mReferenceTemperature[i][0] = 5500;
-            mReferenceTemperature[i][1] = 7500;
-        } else if (referenceWhiteBalance.equals("shade")) {
-            mReferenceTemperature[i][0] = 6800;
-            mReferenceTemperature[i][1] = 8000;
-        } else if (referenceWhiteBalance.equals("twilight")) {
-            mReferenceTemperature[i][0] = 10000;
-            mReferenceTemperature[i][1] = 14000;
-        }
-    }
-
-    /** Sets a reference range of CCT based on a given middle point CCT.
-     * The rerence range is from -10% of the CCT value to +10%.
-     *
-     * @param i the index of the current white balance mode
-     * @param t the middle point CCT.
-     */
-    private void setReferenceTemperature(int i, int t) {
-        mReferenceTemperature[i][0] = (int)((double)t * 0.9);
-        mReferenceTemperature[i][1] = (int)((double)t * 1.1);
-    }
-
-    private Camera.PictureCallback mTestJpegListener = new Camera.PictureCallback() {
-        public void onPictureTaken(byte[] data, Camera mCamera) {
-            Log.v(TAG, "Shutter pressed down!");
-            Bitmap inputImage;
-            try {
-                FileOutputStream outStream = new FileOutputStream(
-                        String.format("/sdcard/wb%d.jpg", System.currentTimeMillis()));
-                outStream.write(data);
-                outStream.close();
-            } catch (FileNotFoundException e) {
-            } catch (IOException e) {}
-            // Decodes the camera data to Bitmap and creates a native image
-            // class with the Bitmap.
-            inputImage = BitmapFactory.decodeByteArray(data, 0, data.length);
-            long bufferAddress = findNative(inputImage);
-            Log.v(TAG, "findNative method finishes");
-
-            // Cleans up the Bitmap memory space.
-            inputImage.recycle();
-            data = null;
-            inputImage = null;
-            System.gc();
-
-            // Adds the data from the current image base class to the native
-            // white balance test handler.
-            createWhiteBalanceClass(bufferAddress, mTestHandler,
-                                    getCheckerCenter(), getCheckerRadius(), mWhiteBalance);
-
-            mCamera.startPreview();
-
-            // Notifies the thread lock that the image capture is finished
-            synchronized (mProcessingImage) {
-                mProcessingImage.notifyAll();
-            }
-        }
-    };
-
-    /**
-     * Creates a native white balance test handler.
-     *
-     * @return the memory address of the test handler
-     */
-    private native long createWhiteBalanceTest();
-
-    /**
-     * Adds the data of interest from the image class pointed by
-     * <code>bufferAddress</code> to the handler class pointed by
-     * <code>handlerAddress</code> by using the color checker coordinates.
-     * Also sets the white balance of this test.
-     *
-     * @param bufferAddress the memory address of the native image class
-     * containing the current camera captured image
-     * @param handlerAddress the memory address of the native white balance
-     * test handler instance
-     * @param checkerCenterAddress the memory address of the color checker
-     * center coordinates
-     * @param checkerRadiusAddress the memory address of the color checker
-     * radius
-     * @param whiteBalance the white balance mode used for shooting the image
-     */
-    private native void createWhiteBalanceClass(long bufferAddress, long handlerAddress,
-                                                long checkerCenterAddress,
-                                                long checkerRadiusAddress,
-                                                String whiteBalance);
-
-    /**
-     * Processes the white balance test in the native code. This is executed
-     * after the images are taken with all possible white balance modes. It
-     * uses the "Daylight" white balance mode as reference and computes the
-     * CCT of other white balance modes.
-     *
-     * @param handlerAddress the memory address of the native white balance
-     * test handler instance.
-     * @param colorTemperature the array to store the computed CCT of all white
-     * balance modes.
-     */
-    private native int processWhiteBalanceTest(long handlerAddress);
-
-    private native int getAutoTemperature(long handlerAddress);
-
-    static {
-        System.loadLibrary("cameraanalyzer");
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/flashlight/CameraFlashlightActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/flashlight/CameraFlashlightActivity.java
new file mode 100644
index 0000000..4d37b3ee
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/flashlight/CameraFlashlightActivity.java
@@ -0,0 +1,275 @@
+/*
+ * 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 com.android.cts.verifier.camera.flashlight;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.content.Context;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraCharacteristics;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import java.util.HashSet;
+import java.util.HashMap;
+
+/**
+ * This test checks the flashlight functionality by turning on and off the flashlight. After it
+ * turns on or off the flashlight, it asks for user input to verify the flashlight status. The
+ * test will pass when the user input is correct for all camera devices with a flash unit.
+ */
+public class CameraFlashlightActivity extends PassFailButtons.Activity {
+
+    private static final String TAG = "CameraFlashlight";
+
+    private CameraManager mCameraManager;
+    private TestState mTestState;
+    private final HashSet<String> mPendingCameraIds = new HashSet<>();
+    private String mCurrentCameraId;
+
+    private Button mInstructionButton;
+    private Button mOnButton;
+    private Button mOffButton;
+    private TextView mInstructionTextView;
+    private final HashSet<View> mAllButtons = new HashSet<>();
+    // TestState -> enabled buttons
+    private final HashMap<TestState, HashSet<View>> mStateButtonsMap = new HashMap<>();
+
+    private enum TestState {
+        NOT_STARTED,
+        TESTING_ON,
+        WAITING_ON_CALLBACK_ON,
+        RESPONDED_ON_CORRECTLY,
+        WAITING_ON_CALLBACK_OFF,
+        TESTING_OFF,
+        RESPONDED_OFF_CORRECTLY,
+        ALL_PASSED,
+        FAILED
+    }
+
+    private final View.OnClickListener mInstructionButtonListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            switch (mTestState) {
+                case NOT_STARTED:
+                    // Start testing turning on the first camera's flashlight.
+                    // Fall through.
+                case RESPONDED_OFF_CORRECTLY:
+                    // Current camera passed. Start testing turning on next camera's flashlight.
+                    if (mPendingCameraIds.size() == 0) {
+                        // Passed
+                        mTestState = TestState.ALL_PASSED;
+                        updateButtonsAndInstructionLocked();
+                        return;
+                    }
+
+                    mCurrentCameraId = (String)mPendingCameraIds.toArray()[0];
+                    mPendingCameraIds.remove(mCurrentCameraId);
+
+                    try {
+                        mCameraManager.setTorchMode(mCurrentCameraId, true);
+                        mTestState = TestState.WAITING_ON_CALLBACK_ON;
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        mTestState = TestState.FAILED;
+                    }
+                    break;
+
+                case RESPONDED_ON_CORRECTLY:
+                    // Flashlight is on and user responded correctly.
+                    // Turning off the flashlight.
+                    try {
+                        mCameraManager.setTorchMode(mCurrentCameraId, false);
+                        mTestState = TestState.WAITING_ON_CALLBACK_OFF;
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                        mTestState = TestState.FAILED;
+                    }
+                    break;
+
+                case FAILED:
+                    // The test failed, report failure.
+                    if (mCurrentCameraId != null) {
+                        try {
+                            mCameraManager.setTorchMode(mCurrentCameraId, false);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                            Log.e(TAG, "Test failed but cannot turn off the torch");
+                        }
+                    }
+                    setTestResultAndFinish(false);
+                    break;
+
+                case ALL_PASSED:
+                    // The test passed, report pass.
+                    setTestResultAndFinish(true);
+                    break;
+            }
+
+            updateButtonsAndInstructionLocked();
+        }
+    };
+
+    private final View.OnClickListener mOnButtonListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            // Check if user responded correctly.
+            if (mTestState == TestState.TESTING_ON) {
+                mTestState = TestState.RESPONDED_ON_CORRECTLY;
+            } else {
+                mTestState = TestState.FAILED;
+            }
+            updateButtonsAndInstructionLocked();
+        }
+    };
+
+    private final View.OnClickListener mOffButtonListener = new View.OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            // Check if user responded correctly.
+            if (mTestState == TestState.TESTING_OFF) {
+                mTestState = TestState.RESPONDED_OFF_CORRECTLY;
+            } else {
+                mTestState = TestState.FAILED;
+            }
+            updateButtonsAndInstructionLocked();
+        }
+    };
+
+    private final CameraManager.TorchCallback mTorchCallback = new CameraManager.TorchCallback() {
+        @Override
+        public void onTorchModeChanged(String cameraId, boolean enabled) {
+            if (!cameraId.equals(mCurrentCameraId)) {
+                return;
+            }
+
+            // Move to next state after receiving the expected callback.
+            if (mTestState == TestState.WAITING_ON_CALLBACK_ON && enabled) {
+                mTestState = TestState.TESTING_ON;
+            } else if (mTestState == TestState.WAITING_ON_CALLBACK_OFF && !enabled) {
+                mTestState = TestState.TESTING_OFF;
+            }
+            updateButtonsAndInstructionLocked();
+        }
+    };
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // initialize state -> buttons map
+        for (TestState state : TestState.values()) {
+            mStateButtonsMap.put(state, new HashSet<View>());
+        }
+
+        mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
+
+        try {
+            String[] cameraIds = mCameraManager.getCameraIdList();
+            for (String id : cameraIds) {
+                CameraCharacteristics info = mCameraManager.getCameraCharacteristics(id);
+                if (info.get(CameraCharacteristics.FLASH_INFO_AVAILABLE).booleanValue() ==
+                        true) {
+                    mPendingCameraIds.add(id);
+                }
+            }
+            mCameraManager.registerTorchCallback(mTorchCallback, new Handler());
+        } catch (Exception e) {
+            e.printStackTrace();
+            mTestState = TestState.FAILED;
+            updateButtonsAndInstructionLocked();
+            return;
+        }
+
+        // Setup the UI.
+        setContentView(R.layout.camera_flashlight);
+        setPassFailButtonClickListeners();
+        setInfoResources(R.string.camera_flashlight_test, R.string.camera_flashlight_info, -1);
+
+        mInstructionTextView = (TextView) findViewById(R.id.flash_instruction_text);
+
+        // Get the buttons and attach the listener.
+        mInstructionButton = (Button) findViewById(R.id.flash_instruction_button);
+        mInstructionButton.setOnClickListener(mInstructionButtonListener);
+        mStateButtonsMap.get(TestState.NOT_STARTED).add(mInstructionButton);
+        mStateButtonsMap.get(TestState.RESPONDED_ON_CORRECTLY).add(mInstructionButton);
+        mStateButtonsMap.get(TestState.RESPONDED_OFF_CORRECTLY).add(mInstructionButton);
+        mStateButtonsMap.get(TestState.ALL_PASSED).add(mInstructionButton);
+        mStateButtonsMap.get(TestState.FAILED).add(mInstructionButton);
+        mAllButtons.add(mInstructionButton);
+
+        mOnButton = (Button) findViewById(R.id.flash_on_button);
+        mOnButton.setOnClickListener(mOnButtonListener);
+        mStateButtonsMap.get(TestState.TESTING_ON).add(mOnButton);
+        mStateButtonsMap.get(TestState.TESTING_OFF).add(mOnButton);
+        mAllButtons.add(mOnButton);
+
+        mOffButton = (Button) findViewById(R.id.flash_off_button);
+        mOffButton.setOnClickListener(mOffButtonListener);
+        mStateButtonsMap.get(TestState.TESTING_ON).add(mOffButton);
+        mStateButtonsMap.get(TestState.TESTING_OFF).add(mOffButton);
+        mAllButtons.add(mOffButton);
+
+        View passButton = getPassButton();
+        mStateButtonsMap.get(TestState.ALL_PASSED).add(passButton);
+        mAllButtons.add(passButton);
+
+        mTestState = TestState.NOT_STARTED;
+        updateButtonsAndInstructionLocked();
+    }
+
+
+    private void updateButtonsAndInstructionLocked() {
+        for (View v : mAllButtons) {
+            v.setEnabled(false);
+        }
+
+        // Only enable the buttons for this state.
+        HashSet<View> views = mStateButtonsMap.get(mTestState);
+        for (View v : views) {
+            v.setEnabled(true);
+        }
+
+        switch (mTestState) {
+            case TESTING_ON:
+            case TESTING_OFF:
+                mInstructionTextView.setText(String.format(
+                        getString(R.string.camera_flashlight_question_text), mCurrentCameraId));
+                break;
+            case RESPONDED_ON_CORRECTLY:
+            case RESPONDED_OFF_CORRECTLY:
+                mInstructionTextView.setText(R.string.camera_flashlight_next_text);
+                mInstructionButton.setText(R.string.camera_flashlight_next_button);
+                break;
+            case FAILED:
+                mInstructionTextView.setText(R.string.camera_flashlight_failed_text);
+                mInstructionButton.setText(R.string.camera_flashlight_done_button);
+                break;
+            case ALL_PASSED:
+                mInstructionTextView.setText(R.string.camera_flashlight_passed_text);
+                mInstructionButton.setText(R.string.camera_flashlight_done_button);
+                break;
+            default:
+                break;
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
index cf8365a..9abfa9a 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsSerializer.java
@@ -116,9 +116,15 @@
         faceObj.put("bounds", serializeRect(face.getBounds()));
         faceObj.put("score", face.getScore());
         faceObj.put("id", face.getId());
-        faceObj.put("leftEye", serializePoint(face.getLeftEyePosition()));
-        faceObj.put("rightEye", serializePoint(face.getRightEyePosition()));
-        faceObj.put("mouth", serializePoint(face.getMouthPosition()));
+        if (face.getLeftEyePosition() != null) {
+            faceObj.put("leftEye", serializePoint(face.getLeftEyePosition()));
+        }
+        if (face.getRightEyePosition() != null) {
+            faceObj.put("rightEye", serializePoint(face.getRightEyePosition()));
+        }
+        if (face.getMouthPosition() != null) {
+            faceObj.put("mouth", serializePoint(face.getMouthPosition()));
+        }
         return faceObj;
     }
 
@@ -145,6 +151,19 @@
                         cfgArray.put(obj);
                     }
                 }
+                sizes = map.getHighResolutionOutputSizes(fmts[fi]);
+                if (sizes != null) {
+                    for (int si = 0; si < Array.getLength(sizes); si++) {
+                        JSONObject obj = new JSONObject();
+                        obj.put("format", fmts[fi]);
+                        obj.put("width",sizes[si].getWidth());
+                        obj.put("height", sizes[si].getHeight());
+                        obj.put("input", false);
+                        obj.put("minFrameDuration",
+                                map.getOutputMinFrameDuration(fmts[fi],sizes[si]));
+                        cfgArray.put(obj);
+                    }
+                }
             }
         }
         mapObj.put("availableStreamConfigurations", cfgArray);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
index ce10535..e3ff74b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsService.java
@@ -30,6 +30,7 @@
 import android.hardware.camera2.CaptureResult;
 import android.hardware.camera2.DngCreator;
 import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.InputConfiguration;
 import android.hardware.camera2.params.MeteringRectangle;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
@@ -37,12 +38,15 @@
 import android.hardware.SensorManager;
 import android.media.Image;
 import android.media.ImageReader;
+import android.media.ImageWriter;
+import android.media.Image.Plane;
 import android.net.Uri;
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.IBinder;
 import android.os.Message;
+import android.os.SystemClock;
 import android.os.Vibrator;
 import android.util.Log;
 import android.util.Rational;
@@ -54,6 +58,8 @@
 import com.android.ex.camera2.blocking.BlockingStateCallback;
 import com.android.ex.camera2.blocking.BlockingSessionCallback;
 
+import com.android.cts.verifier.camera.its.StatsImage;
+
 import org.json.JSONArray;
 import org.json.JSONObject;
 
@@ -67,8 +73,9 @@
 import java.math.BigInteger;
 import java.net.ServerSocket;
 import java.net.Socket;
-import java.net.SocketTimeoutException;
 import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
 import java.nio.charset.Charset;
 import java.security.MessageDigest;
 import java.util.ArrayList;
@@ -78,6 +85,7 @@
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -121,7 +129,8 @@
     private BlockingStateCallback mCameraListener = null;
     private CameraDevice mCamera = null;
     private CameraCaptureSession mSession = null;
-    private ImageReader[] mCaptureReaders = null;
+    private ImageReader[] mOutputImageReaders = null;
+    private ImageReader mInputImageReader = null;
     private CameraCharacteristics mCameraCharacteristics = null;
 
     private Vibrator mVibrator = null;
@@ -146,10 +155,14 @@
     private AtomicInteger mCountCallbacksRemaining = new AtomicInteger();
     private AtomicInteger mCountRawOrDng = new AtomicInteger();
     private AtomicInteger mCountRaw10 = new AtomicInteger();
+    private AtomicInteger mCountRaw12 = new AtomicInteger();
     private AtomicInteger mCountJpg = new AtomicInteger();
     private AtomicInteger mCountYuv = new AtomicInteger();
     private AtomicInteger mCountCapRes = new AtomicInteger();
     private boolean mCaptureRawIsDng;
+    private boolean mCaptureRawIsStats;
+    private int mCaptureStatsGridWidth;
+    private int mCaptureStatsGridHeight;
     private CaptureResult mCaptureResults[] = null;
 
     private volatile ConditionVariable mInterlock3A = new ConditionVariable(true);
@@ -400,7 +413,7 @@
                             continue;
                         }
                         if (b.hasArray()) {
-                            mOpenSocket.getOutputStream().write(b.array());
+                            mOpenSocket.getOutputStream().write(b.array(), 0, b.capacity());
                         } else {
                             byte[] barray = new byte[b.capacity()];
                             b.get(barray);
@@ -493,6 +506,7 @@
                         mSocketWriteQueue.clear();
                         mOpenSocket.close();
                         mOpenSocket = null;
+                        mSocketWriteRunnable.setOpenSocket(null);
                         Logt.i(TAG, "Socket disconnected");
                     }
                 } catch (java.io.IOException e) {
@@ -505,9 +519,12 @@
             Logt.i(TAG, "Socket server loop exited");
             mThreadExitFlag = true;
             try {
-                if (mOpenSocket != null) {
-                    mOpenSocket.close();
-                    mOpenSocket = null;
+                synchronized(mSocketWriteDrainLock) {
+                    if (mOpenSocket != null) {
+                        mOpenSocket.close();
+                        mOpenSocket = null;
+                        mSocketWriteRunnable.setOpenSocket(null);
+                    }
                 }
             } catch (java.io.IOException e) {
                 Logt.w(TAG, "Exception closing socket");
@@ -546,6 +563,8 @@
                     doVibrate(cmdObj);
                 } else if ("getCameraIds".equals(cmdObj.getString("cmdName"))) {
                     doGetCameraIds();
+                } else if ("doReprocessCapture".equals(cmdObj.getString("cmdName"))) {
+                    doReprocessCapture(cmdObj);
                 } else {
                     throw new ItsException("Unknown command: " + cmd);
                 }
@@ -655,9 +674,20 @@
                     jsonSurface.put("height", readers[i].getHeight());
                     int format = readers[i].getImageFormat();
                     if (format == ImageFormat.RAW_SENSOR) {
-                        jsonSurface.put("format", "raw");
+                        if (mCaptureRawIsStats) {
+                            jsonSurface.put("format", "rawStats");
+                            jsonSurface.put("width", readers[i].getWidth()/mCaptureStatsGridWidth);
+                            jsonSurface.put("height",
+                                    readers[i].getHeight()/mCaptureStatsGridHeight);
+                        } else if (mCaptureRawIsDng) {
+                            jsonSurface.put("format", "dng");
+                        } else {
+                            jsonSurface.put("format", "raw");
+                        }
                     } else if (format == ImageFormat.RAW10) {
                         jsonSurface.put("format", "raw10");
+                    } else if (format == ImageFormat.RAW12) {
+                        jsonSurface.put("format", "raw12");
                     } else if (format == ImageFormat.JPEG) {
                         jsonSurface.put("format", "jpeg");
                     } else if (format == ImageFormat.YUV_420_888) {
@@ -763,18 +793,42 @@
         }
     }
 
-    private void prepareCaptureReader(int[] widths, int[] heights, int formats[], int numSurfaces) {
-        if (mCaptureReaders != null) {
-            for (int i = 0; i < mCaptureReaders.length; i++) {
-                if (mCaptureReaders[i] != null) {
-                    mCaptureReaders[i].close();
+    private void prepareImageReaders(Size[] outputSizes, int[] outputFormats, Size inputSize,
+            int inputFormat, int maxInputBuffers) {
+        closeImageReaders();
+        mOutputImageReaders = new ImageReader[outputSizes.length];
+        for (int i = 0; i < outputSizes.length; i++) {
+            // Check if the output image reader can be shared with the input image reader.
+            if (outputSizes[i].equals(inputSize) && outputFormats[i] == inputFormat) {
+                mOutputImageReaders[i] = ImageReader.newInstance(outputSizes[i].getWidth(),
+                        outputSizes[i].getHeight(), outputFormats[i],
+                        MAX_CONCURRENT_READER_BUFFERS + maxInputBuffers);
+                mInputImageReader = mOutputImageReaders[i];
+            } else {
+                mOutputImageReaders[i] = ImageReader.newInstance(outputSizes[i].getWidth(),
+                        outputSizes[i].getHeight(), outputFormats[i],
+                        MAX_CONCURRENT_READER_BUFFERS);
+            }
+        }
+
+        if (inputSize != null && mInputImageReader == null) {
+            mInputImageReader = ImageReader.newInstance(inputSize.getWidth(), inputSize.getHeight(),
+                    inputFormat, maxInputBuffers);
+        }
+    }
+
+    private void closeImageReaders() {
+        if (mOutputImageReaders != null) {
+            for (int i = 0; i < mOutputImageReaders.length; i++) {
+                if (mOutputImageReaders[i] != null) {
+                    mOutputImageReaders[i].close();
+                    mOutputImageReaders[i] = null;
                 }
             }
         }
-        mCaptureReaders = new ImageReader[numSurfaces];
-        for (int i = 0; i < numSurfaces; i++) {
-            mCaptureReaders[i] = ImageReader.newInstance(widths[i], heights[i], formats[i],
-                    MAX_CONCURRENT_READER_BUFFERS);
+        if (mInputImageReader != null) {
+            mInputImageReader.close();
+            mInputImageReader = null;
         }
     }
 
@@ -785,18 +839,17 @@
 
             // 3A happens on full-res frames.
             Size sizes[] = ItsUtils.getYuvOutputSizes(mCameraCharacteristics);
-            int widths[] = new int[1];
-            int heights[] = new int[1];
-            int formats[] = new int[1];
-            widths[0] = sizes[0].getWidth();
-            heights[0] = sizes[0].getHeight();
-            formats[0] = ImageFormat.YUV_420_888;
-            int width = widths[0];
-            int height = heights[0];
+            int outputFormats[] = new int[1];
+            outputFormats[0] = ImageFormat.YUV_420_888;
+            Size[] outputSizes = new Size[1];
+            outputSizes[0] = sizes[0];
+            int width = outputSizes[0].getWidth();
+            int height = outputSizes[0].getHeight();
 
-            prepareCaptureReader(widths, heights, formats, 1);
+            prepareImageReaders(outputSizes, outputFormats, /*inputSize*/null, /*inputFormat*/0,
+                    /*maxInputBuffers*/0);
             List<Surface> outputSurfaces = new ArrayList<Surface>(1);
-            outputSurfaces.add(mCaptureReaders[0].getSurface());
+            outputSurfaces.add(mOutputImageReaders[0].getSurface());
             BlockingSessionCallback sessionListener = new BlockingSessionCallback();
             mCamera.createCaptureSession(outputSurfaces, sessionListener, mCameraHandler);
             mSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS);
@@ -804,7 +857,7 @@
             // Add a listener that just recycles buffers; they aren't saved anywhere.
             ImageReader.OnImageAvailableListener readerListener =
                     createAvailableListenerDropper(mCaptureCallback);
-            mCaptureReaders[0].setOnImageAvailableListener(readerListener, mSaveHandlers[0]);
+            mOutputImageReaders[0].setOnImageAvailableListener(readerListener, mSaveHandlers[0]);
 
             // Get the user-specified regions for AE, AWB, AF.
             // Note that the user specifies normalized [x,y,w,h], which is converted below
@@ -950,7 +1003,7 @@
                         triggeredAF = true;
                     }
 
-                    req.addTarget(mCaptureReaders[0].getSurface());
+                    req.addTarget(mOutputImageReaders[0].getSurface());
 
                     mIssuedRequest3A = true;
                     mSession.capture(req.build(), mCaptureResultListener, mResultHandler);
@@ -988,88 +1041,131 @@
         }
     }
 
+    /**
+     * Parse jsonOutputSpecs to get output surface sizes and formats. Create input and output
+     * image readers for the parsed output surface sizes, output formats, and the given input
+     * size and format.
+     */
+    private void prepareImageReadersWithOutputSpecs(JSONArray jsonOutputSpecs, Size inputSize,
+            int inputFormat, int maxInputBuffers) throws ItsException {
+        Size outputSizes[];
+        int outputFormats[];
+        int numSurfaces = 0;
+
+        if (jsonOutputSpecs != null) {
+            try {
+                numSurfaces = jsonOutputSpecs.length();
+                if (numSurfaces > MAX_NUM_OUTPUT_SURFACES) {
+                    throw new ItsException("Too many output surfaces");
+                }
+
+                outputSizes = new Size[numSurfaces];
+                outputFormats = new int[numSurfaces];
+                for (int i = 0; i < numSurfaces; i++) {
+                    // Get the specified surface.
+                    JSONObject surfaceObj = jsonOutputSpecs.getJSONObject(i);
+                    String sformat = surfaceObj.optString("format");
+                    Size sizes[];
+                    if ("yuv".equals(sformat) || "".equals(sformat)) {
+                        // Default to YUV if no format is specified.
+                        outputFormats[i] = ImageFormat.YUV_420_888;
+                        sizes = ItsUtils.getYuvOutputSizes(mCameraCharacteristics);
+                    } else if ("jpg".equals(sformat) || "jpeg".equals(sformat)) {
+                        outputFormats[i] = ImageFormat.JPEG;
+                        sizes = ItsUtils.getJpegOutputSizes(mCameraCharacteristics);
+                    } else if ("raw".equals(sformat)) {
+                        outputFormats[i] = ImageFormat.RAW_SENSOR;
+                        sizes = ItsUtils.getRaw16OutputSizes(mCameraCharacteristics);
+                    } else if ("raw10".equals(sformat)) {
+                        outputFormats[i] = ImageFormat.RAW10;
+                        sizes = ItsUtils.getRaw10OutputSizes(mCameraCharacteristics);
+                    } else if ("raw12".equals(sformat)) {
+                        outputFormats[i] = ImageFormat.RAW12;
+                        sizes = ItsUtils.getRaw12OutputSizes(mCameraCharacteristics);
+                    } else if ("dng".equals(sformat)) {
+                        outputFormats[i] = ImageFormat.RAW_SENSOR;
+                        sizes = ItsUtils.getRaw16OutputSizes(mCameraCharacteristics);
+                        mCaptureRawIsDng = true;
+                    } else if ("rawStats".equals(sformat)) {
+                        outputFormats[i] = ImageFormat.RAW_SENSOR;
+                        sizes = ItsUtils.getRaw16OutputSizes(mCameraCharacteristics);
+                        mCaptureRawIsStats = true;
+                        mCaptureStatsGridWidth = surfaceObj.optInt("gridWidth");
+                        mCaptureStatsGridHeight = surfaceObj.optInt("gridHeight");
+                    } else {
+                        throw new ItsException("Unsupported format: " + sformat);
+                    }
+                    // If the size is omitted, then default to the largest allowed size for the
+                    // format.
+                    int width = surfaceObj.optInt("width");
+                    int height = surfaceObj.optInt("height");
+                    if (width <= 0) {
+                        if (sizes == null || sizes.length == 0) {
+                            throw new ItsException(String.format(
+                                    "Zero stream configs available for requested format: %s",
+                                    sformat));
+                        }
+                        width = ItsUtils.getMaxSize(sizes).getWidth();
+                    }
+                    if (height <= 0) {
+                        height = ItsUtils.getMaxSize(sizes).getHeight();
+                    }
+                    if (mCaptureStatsGridWidth <= 0) {
+                        mCaptureStatsGridWidth = width;
+                    }
+                    if (mCaptureStatsGridHeight <= 0) {
+                        mCaptureStatsGridHeight = height;
+                    }
+
+                    // TODO: Crop to the active array in the stats image analysis.
+
+                    outputSizes[i] = new Size(width, height);
+                }
+            } catch (org.json.JSONException e) {
+                throw new ItsException("JSON error", e);
+            }
+        } else {
+            // No surface(s) specified at all.
+            // Default: a single output surface which is full-res YUV.
+            Size sizes[] = ItsUtils.getYuvOutputSizes(mCameraCharacteristics);
+            numSurfaces = 1;
+
+            outputSizes = new Size[1];
+            outputFormats = new int[1];
+            outputSizes[0] = sizes[0];
+            outputFormats[0] = ImageFormat.YUV_420_888;
+        }
+
+        prepareImageReaders(outputSizes, outputFormats, inputSize, inputFormat, maxInputBuffers);
+    }
+
     private void doCapture(JSONObject params) throws ItsException {
         try {
             // Parse the JSON to get the list of capture requests.
             List<CaptureRequest.Builder> requests = ItsSerializer.deserializeRequestList(
                     mCamera, params);
 
-            // Set the output surface(s) and listeners.
-            int widths[] = new int[MAX_NUM_OUTPUT_SURFACES];
-            int heights[] = new int[MAX_NUM_OUTPUT_SURFACES];
-            int formats[] = new int[MAX_NUM_OUTPUT_SURFACES];
             int numSurfaces = 0;
             try {
                 mCountRawOrDng.set(0);
                 mCountJpg.set(0);
                 mCountYuv.set(0);
                 mCountRaw10.set(0);
+                mCountRaw12.set(0);
                 mCountCapRes.set(0);
                 mCaptureRawIsDng = false;
+                mCaptureRawIsStats = false;
                 mCaptureResults = new CaptureResult[requests.size()];
 
                 JSONArray jsonOutputSpecs = ItsUtils.getOutputSpecs(params);
-                if (jsonOutputSpecs != null) {
-                    numSurfaces = jsonOutputSpecs.length();
-                    if (numSurfaces > MAX_NUM_OUTPUT_SURFACES) {
-                        throw new ItsException("Too many output surfaces");
-                    }
-                    for (int i = 0; i < numSurfaces; i++) {
-                        // Get the specified surface.
-                        JSONObject surfaceObj = jsonOutputSpecs.getJSONObject(i);
-                        String sformat = surfaceObj.optString("format");
-                        Size sizes[];
-                        if ("yuv".equals(sformat) || "".equals(sformat)) {
-                            // Default to YUV if no format is specified.
-                            formats[i] = ImageFormat.YUV_420_888;
-                            sizes = ItsUtils.getYuvOutputSizes(mCameraCharacteristics);
-                        } else if ("jpg".equals(sformat) || "jpeg".equals(sformat)) {
-                            formats[i] = ImageFormat.JPEG;
-                            sizes = ItsUtils.getJpegOutputSizes(mCameraCharacteristics);
-                        } else if ("raw".equals(sformat)) {
-                            formats[i] = ImageFormat.RAW_SENSOR;
-                            sizes = ItsUtils.getRawOutputSizes(mCameraCharacteristics);
-                        } else if ("raw10".equals(sformat)) {
-                            formats[i] = ImageFormat.RAW10;
-                            sizes = ItsUtils.getRawOutputSizes(mCameraCharacteristics);
-                        } else if ("dng".equals(sformat)) {
-                            formats[i] = ImageFormat.RAW_SENSOR;
-                            sizes = ItsUtils.getRawOutputSizes(mCameraCharacteristics);
-                            mCaptureRawIsDng = true;
-                        } else {
-                            throw new ItsException("Unsupported format: " + sformat);
-                        }
-                        // If the size is omitted, then default to the largest allowed size for the
-                        // format.
-                        widths[i] = surfaceObj.optInt("width");
-                        heights[i] = surfaceObj.optInt("height");
-                        if (widths[i] <= 0) {
-                            if (sizes == null || sizes.length == 0) {
-                                throw new ItsException(String.format(
-                                        "Zero stream configs available for requested format: %s",
-                                        sformat));
-                            }
-                            widths[i] = sizes[0].getWidth();
-                        }
-                        if (heights[i] <= 0) {
-                            heights[i] = sizes[0].getHeight();
-                        }
-                    }
-                } else {
-                    // No surface(s) specified at all.
-                    // Default: a single output surface which is full-res YUV.
-                    Size sizes[] =
-                            ItsUtils.getYuvOutputSizes(mCameraCharacteristics);
-                    numSurfaces = 1;
-                    widths[0] = sizes[0].getWidth();
-                    heights[0] = sizes[0].getHeight();
-                    formats[0] = ImageFormat.YUV_420_888;
-                }
 
-                prepareCaptureReader(widths, heights, formats, numSurfaces);
+                prepareImageReadersWithOutputSpecs(jsonOutputSpecs, /*inputSize*/null,
+                        /*inputFormat*/0, /*maxInputBuffers*/0);
+                numSurfaces = mOutputImageReaders.length;
+
                 List<Surface> outputSurfaces = new ArrayList<Surface>(numSurfaces);
                 for (int i = 0; i < numSurfaces; i++) {
-                    outputSurfaces.add(mCaptureReaders[i].getSurface());
+                    outputSurfaces.add(mOutputImageReaders[i].getSurface());
                 }
                 BlockingSessionCallback sessionListener = new BlockingSessionCallback();
                 mCamera.createCaptureSession(outputSurfaces, sessionListener, mCameraHandler);
@@ -1078,7 +1174,8 @@
                 for (int i = 0; i < numSurfaces; i++) {
                     ImageReader.OnImageAvailableListener readerListener =
                             createAvailableListener(mCaptureCallback);
-                    mCaptureReaders[i].setOnImageAvailableListener(readerListener,mSaveHandlers[i]);
+                    mOutputImageReaders[i].setOnImageAvailableListener(readerListener,
+                            mSaveHandlers[i]);
                 }
 
                 // Plan for how many callbacks need to be received throughout the duration of this
@@ -1089,8 +1186,6 @@
 
             } catch (CameraAccessException e) {
                 throw new ItsException("Error configuring outputs", e);
-            } catch (org.json.JSONException e) {
-                throw new ItsException("JSON error", e);
             }
 
             // Initiate the captures.
@@ -1107,7 +1202,7 @@
                 }
 
                 for (int j = 0; j < numSurfaces; j++) {
-                    req.addTarget(mCaptureReaders[j].getSurface());
+                    req.addTarget(mOutputImageReaders[j].getSurface());
                 }
                 mSession.capture(req.build(), mCaptureResultListener, mResultHandler);
             }
@@ -1137,6 +1232,182 @@
         }
     }
 
+    /**
+     * Perform reprocess captures.
+     *
+     * It takes captureRequests in a JSON object and perform capture requests in two steps:
+     * regular capture request to get reprocess input and reprocess capture request to get
+     * reprocess outputs.
+     *
+     * Regular capture requests:
+     *   1. For each capture request in the JSON object, create a full-size capture request with
+     *      the settings in the JSON object.
+     *   2. Remember and clear noise reduction, edge enhancement, and effective exposure factor
+     *      from the regular capture requests. (Those settings will be used for reprocess requests.)
+     *   3. Submit the regular capture requests.
+     *
+     * Reprocess capture requests:
+     *   4. Wait for the regular capture results and use them to create reprocess capture requests.
+     *   5. Wait for the regular capture output images and queue them to the image writer.
+     *   6. Set the noise reduction, edge enhancement, and effective exposure factor from #2.
+     *   7. Submit the reprocess capture requests.
+     *
+     * The output images and results for the regular capture requests won't be written to socket.
+     * The output images and results for the reprocess capture requests will be written to socket.
+     */
+    private void doReprocessCapture(JSONObject params) throws ItsException {
+        ImageWriter imageWriter = null;
+        ArrayList<Integer> noiseReductionModes = new ArrayList<>();
+        ArrayList<Integer> edgeModes = new ArrayList<>();
+        ArrayList<Float> effectiveExposureFactors = new ArrayList<>();
+
+        mCountRawOrDng.set(0);
+        mCountJpg.set(0);
+        mCountYuv.set(0);
+        mCountRaw10.set(0);
+        mCountRaw12.set(0);
+        mCountCapRes.set(0);
+        mCaptureRawIsDng = false;
+        mCaptureRawIsStats = false;
+
+        try {
+            // Parse the JSON to get the list of capture requests.
+            List<CaptureRequest.Builder> inputRequests =
+                    ItsSerializer.deserializeRequestList(mCamera, params);
+
+            // Prepare the image readers for reprocess input and reprocess outputs.
+            int inputFormat = getReprocessInputFormat(params);
+            Size inputSize = ItsUtils.getMaxOutputSize(mCameraCharacteristics, inputFormat);
+            JSONArray jsonOutputSpecs = ItsUtils.getOutputSpecs(params);
+            prepareImageReadersWithOutputSpecs(jsonOutputSpecs, inputSize, inputFormat,
+                    inputRequests.size());
+
+            // Prepare a reprocessable session.
+            int numOutputSurfaces = mOutputImageReaders.length;
+            InputConfiguration inputConfig = new InputConfiguration(inputSize.getWidth(),
+                    inputSize.getHeight(), inputFormat);
+            List<Surface> outputSurfaces = new ArrayList<Surface>();
+            boolean addSurfaceForInput = true;
+            for (int i = 0; i < numOutputSurfaces; i++) {
+                outputSurfaces.add(mOutputImageReaders[i].getSurface());
+                if (mOutputImageReaders[i] == mInputImageReader) {
+                    // If input and one of the outputs share the same image reader, avoid
+                    // adding the same surfaces twice.
+                    addSurfaceForInput = false;
+                }
+            }
+
+            if (addSurfaceForInput) {
+                // Besides the output surfaces specified in JSON object, add an additional one
+                // for reprocess input.
+                outputSurfaces.add(mInputImageReader.getSurface());
+            }
+
+            BlockingSessionCallback sessionListener = new BlockingSessionCallback();
+            mCamera.createReprocessableCaptureSession(inputConfig, outputSurfaces, sessionListener,
+                    mCameraHandler);
+            mSession = sessionListener.waitAndGetSession(TIMEOUT_IDLE_MS);
+
+            // Create an image writer for reprocess input.
+            Surface inputSurface = mSession.getInputSurface();
+            imageWriter = ImageWriter.newInstance(inputSurface, inputRequests.size());
+
+            // Set up input reader listener and capture callback listener to get
+            // reprocess input buffers and the results in order to create reprocess capture
+            // requests.
+            ImageReaderListenerWaiter inputReaderListener = new ImageReaderListenerWaiter();
+            mInputImageReader.setOnImageAvailableListener(inputReaderListener, mSaveHandlers[0]);
+
+            CaptureCallbackWaiter captureCallbackWaiter = new CaptureCallbackWaiter();
+            // Prepare the reprocess input request
+            for (CaptureRequest.Builder inputReqest : inputRequests) {
+                // Remember and clear noise reduction, edge enhancement, and effective exposure
+                // factors.
+                noiseReductionModes.add(inputReqest.get(CaptureRequest.NOISE_REDUCTION_MODE));
+                edgeModes.add(inputReqest.get(CaptureRequest.EDGE_MODE));
+                effectiveExposureFactors.add(inputReqest.get(
+                        CaptureRequest.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR));
+
+                inputReqest.set(CaptureRequest.NOISE_REDUCTION_MODE,
+                        CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG);
+                inputReqest.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_ZERO_SHUTTER_LAG);
+                inputReqest.set(CaptureRequest.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR, null);
+                inputReqest.addTarget(mInputImageReader.getSurface());
+                mSession.capture(inputReqest.build(), captureCallbackWaiter, mResultHandler);
+            }
+
+            // Wait for reprocess input images
+            ArrayList<CaptureRequest.Builder> reprocessOutputRequests = new ArrayList<>();
+            for (int i = 0; i < inputRequests.size(); i++) {
+                TotalCaptureResult result =
+                        captureCallbackWaiter.getResult(TIMEOUT_CALLBACK * 1000);
+                reprocessOutputRequests.add(mCamera.createReprocessCaptureRequest(result));
+                imageWriter.queueInputImage(inputReaderListener.getImage(TIMEOUT_CALLBACK * 1000));
+            }
+
+            // Start performing reprocess captures.
+
+            mCaptureResults = new CaptureResult[inputRequests.size()];
+
+            // Prepare reprocess capture requests.
+            for (int i = 0; i < numOutputSurfaces; i++) {
+                ImageReader.OnImageAvailableListener outputReaderListener =
+                        createAvailableListener(mCaptureCallback);
+                mOutputImageReaders[i].setOnImageAvailableListener(outputReaderListener,
+                        mSaveHandlers[i]);
+            }
+
+            // Initiate the captures.
+            for (int i = 0; i < reprocessOutputRequests.size(); i++) {
+                CaptureRequest.Builder req = reprocessOutputRequests.get(i);
+                for (ImageReader outputImageReader : mOutputImageReaders) {
+                    req.addTarget(outputImageReader.getSurface());
+                }
+
+                req.set(CaptureRequest.NOISE_REDUCTION_MODE, noiseReductionModes.get(i));
+                req.set(CaptureRequest.EDGE_MODE, edgeModes.get(i));
+                req.set(CaptureRequest.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR,
+                        effectiveExposureFactors.get(i));
+
+                mSession.capture(req.build(), mCaptureResultListener, mResultHandler);
+            }
+
+            // Plan for how many callbacks need to be received throughout the duration of this
+            // sequence of capture requests. There is one callback per image surface, and one
+            // callback for the CaptureResult, for each capture.
+            int numCaptures = reprocessOutputRequests.size();
+            mCountCallbacksRemaining.set(numCaptures * (numOutputSurfaces + 1));
+
+            // Make sure all callbacks have been hit (wait until captures are done).
+            // If no timeouts are received after a timeout, then fail.
+            int currentCount = mCountCallbacksRemaining.get();
+            while (currentCount > 0) {
+                try {
+                    Thread.sleep(TIMEOUT_CALLBACK*1000);
+                } catch (InterruptedException e) {
+                    throw new ItsException("Timeout failure", e);
+                }
+                int newCount = mCountCallbacksRemaining.get();
+                if (newCount == currentCount) {
+                    throw new ItsException(
+                            "No callback received within timeout");
+                }
+                currentCount = newCount;
+            }
+        } catch (android.hardware.camera2.CameraAccessException e) {
+            throw new ItsException("Access error: ", e);
+        } finally {
+            closeImageReaders();
+            if (mSession != null) {
+                mSession.close();
+                mSession = null;
+            }
+            if (imageWriter != null) {
+                imageWriter.close();
+            }
+        }
+    }
+
     @Override
     public final void onSensorChanged(SensorEvent event) {
         synchronized(mEventLock) {
@@ -1179,13 +1450,39 @@
                     ByteBuffer buf = ByteBuffer.wrap(img);
                     int count = mCountRaw10.getAndIncrement();
                     mSocketRunnableObj.sendResponseCaptureBuffer("raw10Image", buf);
+                } else if (format == ImageFormat.RAW12) {
+                    Logt.i(TAG, "Received RAW12 capture");
+                    byte[] img = ItsUtils.getDataFromImage(capture);
+                    ByteBuffer buf = ByteBuffer.wrap(img);
+                    int count = mCountRaw12.getAndIncrement();
+                    mSocketRunnableObj.sendResponseCaptureBuffer("raw12Image", buf);
                 } else if (format == ImageFormat.RAW_SENSOR) {
                     Logt.i(TAG, "Received RAW16 capture");
                     int count = mCountRawOrDng.getAndIncrement();
                     if (! mCaptureRawIsDng) {
                         byte[] img = ItsUtils.getDataFromImage(capture);
-                        ByteBuffer buf = ByteBuffer.wrap(img);
-                        mSocketRunnableObj.sendResponseCaptureBuffer("rawImage", buf);
+                        if (! mCaptureRawIsStats) {
+                            ByteBuffer buf = ByteBuffer.wrap(img);
+                            mSocketRunnableObj.sendResponseCaptureBuffer("rawImage", buf);
+                        } else {
+                            // Compute the requested stats on the raw frame, and return the results
+                            // in a new "stats image".
+                            long startTimeMs = SystemClock.elapsedRealtime();
+                            int w = capture.getWidth();
+                            int h = capture.getHeight();
+                            int gw = mCaptureStatsGridWidth;
+                            int gh = mCaptureStatsGridHeight;
+                            float[] stats = StatsImage.computeStatsImage(img, w, h, gw, gh);
+                            long endTimeMs = SystemClock.elapsedRealtime();
+                            Log.e(TAG, "Raw stats computation takes " + (endTimeMs - startTimeMs) + " ms");
+
+                            ByteBuffer bBuf = ByteBuffer.allocateDirect(stats.length * 4);
+                            bBuf.order(ByteOrder.nativeOrder());
+                            FloatBuffer fBuf = bBuf.asFloatBuffer();
+                            fBuf.put(stats);
+                            fBuf.position(0);
+                            mSocketRunnableObj.sendResponseCaptureBuffer("rawStatsImage", bBuf);
+                        }
                     } else {
                         // Wait until the corresponding capture result is ready, up to a timeout.
                         long t0 = android.os.SystemClock.elapsedRealtime();
@@ -1379,7 +1676,7 @@
                     int count = mCountCapRes.getAndIncrement();
                     mCaptureResults[count] = result;
                     mSocketRunnableObj.sendResponseCaptureResult(mCameraCharacteristics,
-                            request, result, mCaptureReaders);
+                            request, result, mOutputImageReaders);
                     mCountCallbacksRemaining.decrementAndGet();
                 }
             } catch (ItsException e) {
@@ -1395,4 +1692,93 @@
             Logt.e(TAG, "Script error: capture failed");
         }
     };
+
+    private class CaptureCallbackWaiter extends CameraCaptureSession.CaptureCallback {
+        private final LinkedBlockingQueue<TotalCaptureResult> mResultQueue =
+                new LinkedBlockingQueue<>();
+
+        @Override
+        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
+                long timestamp, long frameNumber) {
+        }
+
+        @Override
+        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
+                TotalCaptureResult result) {
+            try {
+                mResultQueue.put(result);
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onImageAvailable");
+            }
+        }
+
+        @Override
+        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
+                CaptureFailure failure) {
+            Logt.e(TAG, "Script error: capture failed");
+        }
+
+        public TotalCaptureResult getResult(long timeoutMs) throws ItsException {
+            TotalCaptureResult result;
+            try {
+                result = mResultQueue.poll(timeoutMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                throw new ItsException(e);
+            }
+
+            if (result == null) {
+                throw new ItsException("Getting an image timed out after " + timeoutMs +
+                        "ms");
+            }
+
+            return result;
+        }
+    }
+
+    private static class ImageReaderListenerWaiter implements ImageReader.OnImageAvailableListener {
+        private final LinkedBlockingQueue<Image> mImageQueue = new LinkedBlockingQueue<>();
+
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            try {
+                mImageQueue.put(reader.acquireNextImage());
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onImageAvailable");
+            }
+        }
+
+        public Image getImage(long timeoutMs) throws ItsException {
+            Image image;
+            try {
+                image = mImageQueue.poll(timeoutMs, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                throw new ItsException(e);
+            }
+
+            if (image == null) {
+                throw new ItsException("Getting an image timed out after " + timeoutMs +
+                        "ms");
+            }
+            return image;
+        }
+    }
+
+    private int getReprocessInputFormat(JSONObject params) throws ItsException {
+        String reprocessFormat;
+        try {
+            reprocessFormat = params.getString("reprocessFormat");
+        } catch (org.json.JSONException e) {
+            throw new ItsException("Error parsing reprocess format: " + e);
+        }
+
+        if (reprocessFormat.equals("yuv")) {
+            return ImageFormat.YUV_420_888;
+        } else if (reprocessFormat.equals("private")) {
+            return ImageFormat.PRIVATE;
+        }
+
+        throw new ItsException("Uknown reprocess format: " + reprocessFormat);
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
index 2011314..6fd050b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/ItsUtils.java
@@ -91,11 +91,21 @@
         }
     }
 
-    public static Size[] getRawOutputSizes(CameraCharacteristics ccs)
+    public static Size[] getRaw16OutputSizes(CameraCharacteristics ccs)
             throws ItsException {
         return getOutputSizes(ccs, ImageFormat.RAW_SENSOR);
     }
 
+    public static Size[] getRaw10OutputSizes(CameraCharacteristics ccs)
+            throws ItsException {
+        return getOutputSizes(ccs, ImageFormat.RAW10);
+    }
+
+    public static Size[] getRaw12OutputSizes(CameraCharacteristics ccs)
+            throws ItsException {
+        return getOutputSizes(ccs, ImageFormat.RAW12);
+    }
+
     public static Size[] getJpegOutputSizes(CameraCharacteristics ccs)
             throws ItsException {
         return getOutputSizes(ccs, ImageFormat.JPEG);
@@ -106,6 +116,11 @@
         return getOutputSizes(ccs, ImageFormat.YUV_420_888);
     }
 
+    public static Size getMaxOutputSize(CameraCharacteristics ccs, int format)
+            throws ItsException {
+        return getMaxSize(getOutputSizes(ccs, format));
+    }
+
     private static Size[] getOutputSizes(CameraCharacteristics ccs, int format)
             throws ItsException {
         StreamConfigurationMap configMap = ccs.get(
@@ -113,7 +128,37 @@
         if (configMap == null) {
             throw new ItsException("Failed to get stream config");
         }
-        return configMap.getOutputSizes(format);
+        Size[] normalSizes = configMap.getOutputSizes(format);
+        Size[] slowSizes = configMap.getHighResolutionOutputSizes(format);
+        Size[] allSizes = null;
+        if (normalSizes != null && slowSizes != null) {
+            allSizes = new Size[normalSizes.length + slowSizes.length];
+            System.arraycopy(normalSizes, 0, allSizes, 0,
+                    normalSizes.length);
+            System.arraycopy(slowSizes, 0, allSizes, normalSizes.length,
+                    slowSizes.length);
+        } else if (normalSizes != null) {
+            allSizes = normalSizes;
+        } else if (slowSizes != null) {
+            allSizes = slowSizes;
+        }
+        return allSizes;
+    }
+
+    public static Size getMaxSize(Size[] sizes) {
+        if (sizes == null || sizes.length == 0) {
+            throw new IllegalArgumentException("sizes was empty");
+        }
+
+        Size maxSize = sizes[0];
+        for (int i = 1; i < sizes.length; i++) {
+            if (sizes[i].getWidth() * sizes[i].getHeight() >
+                    maxSize.getWidth() * maxSize.getHeight()) {
+                maxSize = sizes[i];
+            }
+        }
+
+        return maxSize;
     }
 
     public static byte[] getDataFromImage(Image image)
@@ -139,7 +184,7 @@
             buffer.get(data);
             return data;
         } else if (format == ImageFormat.YUV_420_888 || format == ImageFormat.RAW_SENSOR
-                || format == ImageFormat.RAW10) {
+                || format == ImageFormat.RAW10 || format == ImageFormat.RAW12) {
             int offset = 0;
             data = new byte[width * height * ImageFormat.getBitsPerPixel(format) / 8];
             int maxRowSize = planes[0].getRowStride();
@@ -213,6 +258,7 @@
                 return 3 == planes.length;
             case ImageFormat.RAW_SENSOR:
             case ImageFormat.RAW10:
+            case ImageFormat.RAW12:
             case ImageFormat.JPEG:
                 return 1 == planes.length;
             default:
@@ -220,4 +266,3 @@
         }
     }
 }
-
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/StatsImage.java b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/StatsImage.java
new file mode 100644
index 0000000..037177c
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/camera/its/StatsImage.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.cts.verifier.camera.its;
+
+import android.util.Log;
+
+public class StatsImage {
+
+    static {
+        try {
+            System.loadLibrary("ctsverifier_jni");
+        } catch (UnsatisfiedLinkError e) {
+            Log.e("StatsImage", "Error loading cts verifier JNI library");
+            e.printStackTrace();
+        }
+    }
+
+    public native static float[] computeStatsImage(
+            byte[] img, int width, int height, int gridW, int gridH);
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
index fcd88d1..aaea279 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/deskclock/DeskClockTestsActivity.java
@@ -165,13 +165,6 @@
         }
     }
 
-    /**
-     * Enable Pass Button when the all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-
     public static class DeskClockIntentFactory implements IntentFactory {
         @Override
         public Intent[] createIntents(String testId, int buttonText) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
index 36acf42..285c8da 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/features/FeatureSummaryActivity.java
@@ -230,6 +230,14 @@
             new Feature("android.software.voice_recognizers", false),
     };
 
+    public static final Feature[] ALL_MNC_FEATURES = {
+            new Feature(PackageManager.FEATURE_MIDI, false),
+            new Feature(PackageManager.FEATURE_AUDIO_PRO, false),
+            new Feature(PackageManager.FEATURE_AUTOMOTIVE, false),
+            new Feature(PackageManager.FEATURE_HIFI_SENSORS, false),
+            new Feature(PackageManager.FEATURE_FINGERPRINT, false),
+    };
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -261,6 +269,9 @@
 
         // add features from latest to last so that the latest requirements are put in the set first
         int apiVersion = Build.VERSION.SDK_INT;
+        if (apiVersion >= Build.VERSION_CODES.M) {
+            Collections.addAll(features, ALL_MNC_FEATURES);
+        }
         if (apiVersion >= Build.VERSION_CODES.LOLLIPOP) {
             Collections.addAll(features, ALL_LOLLIPOP_FEATURES);
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ChargingConstraintTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ChargingConstraintTestActivity.java
index 2a94ace..4b70b894 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ChargingConstraintTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ChargingConstraintTestActivity.java
@@ -9,17 +9,21 @@
 import android.content.IntentFilter;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.BatteryManager;
 import android.widget.Button;
 import android.widget.ImageView;
+import android.widget.TextView;
+import android.view.View;
 
 import com.android.cts.verifier.R;
+import com.android.cts.verifier.TimerProgressBar;
 
 /**
  *  This activity runs the following tests:
- *     - Ask the tester to unplug the phone, and verify that jobs with charging constraints will
- *      not run.
  *     - Ask the tester to ensure the phone is plugged in, and verify that jobs with charging
  *      constraints are run.
+ *     - Ask the tester to unplug the phone, and verify that jobs with charging constraints will
+ *      not run.
  */
 @TargetApi(21)
 public class ChargingConstraintTestActivity extends ConstraintTestActivity {
@@ -29,6 +33,19 @@
     private static final int OFF_CHARGING_JOB_ID =
             ChargingConstraintTestActivity.class.hashCode() + 1;
 
+    // Time in milliseconds to wait after power is connected for the phone
+    // to get into charging mode.
+    private static final long WAIT_FOR_CHARGING_DURATION = 3 * 60 * 1000;
+
+    private static final int STATE_NOT_RUNNING = 0;
+    private static final int STATE_WAITING_TO_START_ON_CHARGING_TEST = 1;
+    private static final int STATE_ON_CHARGING_TEST_PASSED = 2;
+
+    private int mTestState;
+    TimerProgressBar mWaitingForChargingProgressBar;
+    TextView mWaitingForChargingTextView;
+    TextView mProblemWithChargerTextView;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -38,6 +55,20 @@
         setPassFailButtonClickListeners();
         setInfoResources(R.string.js_charging_test, R.string.js_charging_instructions, -1);
         mStartButton = (Button) findViewById(R.id.js_charging_start_test_button);
+        mWaitingForChargingProgressBar = (TimerProgressBar) findViewById(
+            R.id.js_waiting_for_charging_progress_bar);
+        mWaitingForChargingTextView = (TextView) findViewById(
+            R.id.js_waiting_for_charging_text_view);
+        mProblemWithChargerTextView = (TextView) findViewById(
+            R.id.js_problem_with_charger_text_view);
+
+        if (isDevicePluggedIn()){
+            mStartButton.setEnabled(true);
+        }
+
+        hideWaitingForStableChargingViews();
+
+        mTestState = STATE_NOT_RUNNING;
 
         mJobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
 
@@ -45,6 +76,8 @@
         IntentFilter intentFilter = new IntentFilter();
         intentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
         intentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
+        intentFilter.addAction(BatteryManager.ACTION_CHARGING);
+        intentFilter.addAction(BatteryManager.ACTION_DISCHARGING);
 
         registerReceiver(mChargingChangedReceiver, intentFilter);
     }
@@ -55,22 +88,47 @@
         unregisterReceiver(mChargingChangedReceiver);
     }
 
+    private boolean isDevicePluggedIn() {
+        IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
+        Intent batteryStatus = registerReceiver(null, ifilter);
+        int status = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
+        // 0 indicates device is on battery power
+        return status != 0;
+    }
+
     @Override
     public void startTestImpl() {
-        new TestDeviceUnpluggedConstraint().execute();
+        BatteryManager bm = (BatteryManager) getSystemService(BATTERY_SERVICE);
+        if (bm.isCharging()) {
+            new TestDevicePluggedInConstraint().execute();
+        } else if (isDevicePluggedIn()) {
+            mTestState = STATE_WAITING_TO_START_ON_CHARGING_TEST;
+            showWaitingForStableChargingViews();
+        }
     }
 
     private BroadcastReceiver mChargingChangedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_POWER_DISCONNECTED.equals(intent.getAction())) {
-                mDeviceUnpluggedTestPassed = false;
-                mStartButton.setEnabled(true);
-            } else if (Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())) {
-                mStartButton.setEnabled(false);
-                if (mDeviceUnpluggedTestPassed) {
-                    continueTest();
+            if (BatteryManager.ACTION_CHARGING.equals(intent.getAction())) {
+                if (mTestState == STATE_WAITING_TO_START_ON_CHARGING_TEST) {
+                    mWaitingForChargingProgressBar.forceComplete();
+                    hideWaitingForStableChargingViews();
+                    new TestDevicePluggedInConstraint().execute();
                 }
+            } else if (BatteryManager.ACTION_DISCHARGING.equals(intent.getAction())) {
+                if (mTestState == STATE_ON_CHARGING_TEST_PASSED) {
+                    new TestDeviceUnpluggedConstraint().execute();
+                }
+            } else if (Intent.ACTION_POWER_CONNECTED.equals(intent.getAction())) {
+                if (mTestState == STATE_WAITING_TO_START_ON_CHARGING_TEST) {
+                    showWaitingForStableChargingViews();
+                } else if (mTestState == STATE_NOT_RUNNING) {
+                    mStartButton.setEnabled(true);
+                }
+                mStartButton.setEnabled(true);
+            } else if (Intent.ACTION_POWER_DISCONNECTED.equals(intent.getAction())) {
+                hideWaitingForStableChargingViews();
             }
         }
     };
@@ -79,15 +137,6 @@
     private boolean mDeviceUnpluggedTestPassed = false;
 
     /**
-     * After the first test has passed, and preconditions are met, this will kick off the second
-     * test.
-     * See {@link #startTest(android.view.View)}.
-     */
-    private void continueTest() {
-        new TestDevicePluggedInConstraint().execute();
-    }
-
-    /**
      * Test blocks and can't be run on the main thread.
      */
     private void testChargingConstraintFails_notCharging() {
@@ -99,17 +148,12 @@
                 .build();
         mJobScheduler.schedule(runOnCharge);
 
-        // Send intent to kick off any jobs. This will be a no-op as the device is not plugged in;
-        // the JobScheduler tracks charging state independently.
-        sendBroadcastAndBlockForResult(EXPEDITE_STABLE_CHARGING);
-
         boolean testPassed;
         try {
             testPassed = mTestEnvironment.awaitTimeout();
         } catch (InterruptedException e) {
             testPassed = false;
         }
-        mDeviceUnpluggedTestPassed = testPassed;
         runOnUiThread(new ChargingConstraintTestResultRunner(OFF_CHARGING_JOB_ID, testPassed));
     }
 
@@ -127,15 +171,14 @@
         mTestEnvironment.setExpectedExecutions(1);
         mJobScheduler.schedule(delayConstraintAndUnexpiredDeadline);
 
-        // Force the JobScheduler to consider any jobs that have charging constraints.
-        sendBroadcast(EXPEDITE_STABLE_CHARGING);
-
         boolean testPassed;
         try {
             testPassed = mTestEnvironment.awaitExecution();
         } catch (InterruptedException e) {
             testPassed = false;
         }
+
+        mTestState = testPassed ? STATE_ON_CHARGING_TEST_PASSED : STATE_NOT_RUNNING;
         runOnUiThread(new ChargingConstraintTestResultRunner(ON_CHARGING_JOB_ID, testPassed));
     }
 
@@ -144,11 +187,15 @@
         @Override
         protected Void doInBackground(Void... voids) {
             testChargingConstraintFails_notCharging();
-
-            // Do not call notifyTestCompleted here, as we're still waiting for the user to put
-            // the device back on charge to continue with TestDevicePluggedInConstraint.
+            notifyTestCompleted();
             return null;
         }
+
+        @Override
+        protected void onPostExecute(Void res) {
+            mTestState = STATE_NOT_RUNNING;
+            mStartButton.setEnabled(true);
+        }
     }
 
     /** Run test for when the <bold>device is connected to power.</bold> */
@@ -156,8 +203,6 @@
         @Override
         protected Void doInBackground(Void... voids) {
             testChargingConstraintExecutes_onCharging();
-
-            notifyTestCompleted();
             return null;
         }
     }
@@ -181,4 +226,25 @@
             view.setImageResource(mTestPassed ? R.drawable.fs_good : R.drawable.fs_error);
         }
     }
+
+    private void showWaitingForStableChargingViews() {
+        mWaitingForChargingProgressBar.start(WAIT_FOR_CHARGING_DURATION, 1000,
+            new TimerProgressBar.TimerExpiredCallback(){
+                @Override
+                public void onTimerExpired() {
+                    mProblemWithChargerTextView.setVisibility(View.VISIBLE);
+                }
+            }
+        );
+        mWaitingForChargingProgressBar.setVisibility(View.VISIBLE);
+        mWaitingForChargingTextView.setVisibility(View.VISIBLE);
+        mProblemWithChargerTextView.setVisibility(View.GONE);
+    }
+
+    private void hideWaitingForStableChargingViews() {
+        mWaitingForChargingProgressBar.forceComplete();
+        mWaitingForChargingProgressBar.setVisibility(View.GONE);
+        mWaitingForChargingTextView.setVisibility(View.GONE);
+        mProblemWithChargerTextView.setVisibility(View.GONE);
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ConnectivityConstraintTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ConnectivityConstraintTestActivity.java
index 8d10bda..aaf68e6 100755
--- a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ConnectivityConstraintTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ConnectivityConstraintTestActivity.java
@@ -106,11 +106,6 @@
         mJobScheduler.schedule(testJob1);
         mJobScheduler.schedule(testJob2);
 
-        /*
-        // Send intent to kick off ready jobs that the JobScheduler might be lazily holding on to.
-        sendBroadcastAndBlockForResult(EXPEDITE_STABLE_CHARGING);
-        */
-
         boolean testPassed;
         try {
             testPassed = mTestEnvironment.awaitExecution();
@@ -132,9 +127,6 @@
 
         mJobScheduler.schedule(testJob);
 
-        // Send intent to kick off ready jobs that the JobScheduler might be lazily holding on to.
-        sendBroadcastAndBlockForResult(EXPEDITE_STABLE_CHARGING);
-
         boolean testPassed;
         try {
             testPassed = mTestEnvironment.awaitTimeout();
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ConstraintTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ConstraintTestActivity.java
index da0862a..0d8d13f 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ConstraintTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/ConstraintTestActivity.java
@@ -18,13 +18,7 @@
 
 @TargetApi(21)
 public abstract class ConstraintTestActivity extends PassFailButtons.Activity {
-    /**
-     * Intent we use to force the job scheduler to consider any ready jobs that otherwise it may
-     * have decided to be lazy about.
-     */
-    protected static final Intent EXPEDITE_STABLE_CHARGING =
-            new Intent("com.android.server.task.controllers.BatteryController.ACTION_CHARGING_STABLE");
-
+    
     protected ComponentName mMockComponent;
 
     protected MockJobService.TestEnvironment mTestEnvironment;
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java
index a8bd993..05c1a2e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/jobscheduler/IdleConstraintTestActivity.java
@@ -26,15 +26,17 @@
 import android.content.IntentFilter;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.PowerManager;
 import android.util.Log;
+import android.view.View;
 import android.widget.Button;
 import android.widget.ImageView;
+import android.widget.TextView;
 
 /**
  *  Idle constraints:
- *      The framework doesn't support turning idle mode off. Use the manual tester to ensure that
- *      the device is not in idle mode (by turning the screen off and then back on) before running
- *      the tests.
+ *      The framework doesn't support turning the screen off. Use the manual tester to
+ *      turn off the screen to run to run tests that require idle mode to be on.
  */
 @TargetApi(21)
 public class IdleConstraintTestActivity extends ConstraintTestActivity {
@@ -57,22 +59,35 @@
      */
     private static final int IDLE_ON_JOB_ID = IdleConstraintTestActivity.class.hashCode() + 1;
 
+    private static final int IDLE_ON_TEST_STATE_NOT_IN_PROGRESS = 0;
+    private static final int IDLE_ON_TEST_STATE_WAITING_FOR_SCREEN_OFF = 1;
+
     /**
-     * Listens for idle mode off/on events, namely {@link #ACTION_EXPEDITE_IDLE_MODE} and
-     * {@link Intent#ACTION_SCREEN_ON}.
-     * On ACTION_EXPEDITE_IDLE_MODE, we will disable the {@link #mStartButton}, and on
-     * ACTION_SCREEN_ON we enable it. This is to avoid the start button being clicked when the
-     * device is in idle mode.
+     * mTestState stores the state of the tests. It is used to ensure that we only run
+     * the 'idle on' test if screen is turned off after the user has started tests.
      */
-    private BroadcastReceiver mIdleChangedReceiver = new BroadcastReceiver() {
+    private int mTestState = IDLE_ON_TEST_STATE_NOT_IN_PROGRESS;
+
+    private PowerManager mPowerManager;
+    private TextView mContinueInstructionTextView;
+
+    /**
+     * Listens for screen off event. Starts an async task to force device into
+     * idle mode and run the 'idle on' test.
+     */
+    private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
-                mStartButton.setEnabled(true);
-            } else if (ACTION_EXPEDITE_IDLE_MODE.equals(intent.getAction())) {
-                mStartButton.setEnabled(false);
+            if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
+                if (mTestState == IDLE_ON_TEST_STATE_WAITING_FOR_SCREEN_OFF) {
+                    mContinueInstructionTextView.setVisibility(View.GONE);
+                    PowerManager.WakeLock wl = mPowerManager.newWakeLock(
+                        PowerManager.PARTIAL_WAKE_LOCK, TAG);
+                    wl.acquire();
+                    new TestIdleModeTaskIdle().execute(wl);
+                }
             } else {
-                Log.e(TAG, "Invalid broadcast received, was expecting SCREEN_ON");
+                Log.e(TAG, "Invalid broadcast received, was expecting SCREEN_OFF");
             }
         }
     };
@@ -86,47 +101,88 @@
         setPassFailButtonClickListeners();
         setInfoResources(R.string.js_idle_test, R.string.js_idle_instructions, -1);
         mStartButton = (Button) findViewById(R.id.js_idle_start_test_button);
+        mContinueInstructionTextView = (TextView) findViewById(
+            R.id.js_idle_continue_instruction_view);
 
-        // Register receiver for idle off/on events.
+        // Register receiver for screen off event.
         IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(Intent.ACTION_SCREEN_ON);
-        intentFilter.addAction(ACTION_EXPEDITE_IDLE_MODE);
+        intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
 
-        registerReceiver(mIdleChangedReceiver, intentFilter);
+        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+
+        registerReceiver(mScreenOffReceiver, intentFilter);
+
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        // Enable start button only if tests are not in progress.
+        if (mTestState == IDLE_ON_TEST_STATE_NOT_IN_PROGRESS) {
+            mStartButton.setEnabled(true);
+            mContinueInstructionTextView.setVisibility(View.GONE);
+        }
     }
 
     @Override
     protected void onDestroy() {
         super.onDestroy();
-        unregisterReceiver(mIdleChangedReceiver);
+        unregisterReceiver(mScreenOffReceiver);
     }
 
     @Override
     protected void startTestImpl() {
-        new TestIdleModeTask().execute();
+        mStartButton.setEnabled(false);
+        new TestIdleModeTaskNotIdle().execute();
     }
 
-    /** Background task that will run the actual test. */
-    private class TestIdleModeTask extends AsyncTask<Void, Void, Void> {
-
+    /** Background task that will run the 'not idle' test. */
+    private class TestIdleModeTaskNotIdle extends AsyncTask<Void, Void, Void> {
         @Override
         protected Void doInBackground(Void... voids) {
             testIdleConstraintFails_notIdle();
+            return null;
+        }
 
+        @Override
+        protected void onPostExecute(Void result) {
+            mTestState = IDLE_ON_TEST_STATE_WAITING_FOR_SCREEN_OFF;
+            mContinueInstructionTextView.setVisibility(View.VISIBLE);
+        }
+    }
 
-            // Send the {@link #ACTION_EXPEDITE_IDLE_MODE} broadcast as an ordered broadcast, this
-            // function will block until all receivers have processed the broadcast.
+    /** Background task that will run the 'idle' test. */
+    private class TestIdleModeTaskIdle extends AsyncTask<PowerManager.WakeLock, Void, Void> {
+
+        private PowerManager.WakeLock mPartialWakeLock;
+
+        @Override
+        protected Void doInBackground(PowerManager.WakeLock... wakeLocks) {
+            mPartialWakeLock = wakeLocks[0];
+
             if (!sendBroadcastAndBlockForResult(new Intent(ACTION_EXPEDITE_IDLE_MODE))) {
-                // Fail the test if the broadcast wasn't processed.
                 runOnUiThread(new IdleTestResultRunner(IDLE_ON_JOB_ID, false));
+            } else {
+                testIdleConstraintExecutes_onIdle();
             }
-
-            testIdleConstraintExecutes_onIdle();
-
             notifyTestCompleted();
             return null;
         }
 
+        @Override
+        protected void onPostExecute(Void result) {
+            // Reset test state
+            mTestState = IDLE_ON_TEST_STATE_NOT_IN_PROGRESS;
+
+            PowerManager.WakeLock fullWakeLock = mPowerManager.newWakeLock(
+                PowerManager.FULL_WAKE_LOCK
+                | PowerManager.ACQUIRE_CAUSES_WAKEUP
+                | PowerManager.ON_AFTER_RELEASE, TAG);
+            // Turn on screen and release both locks
+            fullWakeLock.acquire();
+            fullWakeLock.release();
+            mPartialWakeLock.release();
+        }
     }
 
     /**
@@ -154,6 +210,10 @@
         runOnUiThread(new IdleTestResultRunner(IDLE_OFF_JOB_ID, testPassed));
     }
 
+    /**
+     * Called after screen is switched off and device is forced into idle mode.
+     * Schedule a job with an idle constraint and verify that it executes.
+     */
     private void testIdleConstraintExecutes_onIdle() {
         mTestEnvironment.setUp();
         mJobScheduler.cancelAll();
@@ -172,6 +232,7 @@
             // We'll just indicate that it failed, not why.
             testPassed = false;
         }
+
         runOnUiThread(new IdleTestResultRunner(IDLE_ON_JOB_ID, testPassed));
     }
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/AuthenticationBoundKeyTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/AuthenticationBoundKeyTestActivity.java
new file mode 100644
index 0000000..073412d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/AuthenticationBoundKeyTestActivity.java
@@ -0,0 +1,381 @@
+package com.android.cts.verifier.managedprovisioning;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.KeyguardManager;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.os.CountDownTimer;
+import android.provider.Settings;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.UserNotAuthenticatedException;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Toast;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.DialogTestListActivity;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestResult;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+
+/**
+ * Test device credential-bound keys in work profile.
+ * Currently there are two types, one is keys bound to lockscreen passwords which can be configured
+ * to remain available within a certain timeout after the latest successful user authentication.
+ * The other is keys bound to fingerprint authentication which require explicit fingerprint
+ * authentication before they can be accessed.
+ */
+public class AuthenticationBoundKeyTestActivity extends DialogTestListActivity {
+
+    public static final String ACTION_AUTH_BOUND_KEY_TEST =
+            "com.android.cts.verifier.managedprovisioning.action.AUTH_BOUND_KEY_TEST";
+
+    private static final int AUTHENTICATION_DURATION_SECONDS = 5;
+    private static final String LOCKSCREEN_KEY_NAME = "mp_lockscreen_key";
+    private static final String FINGERPRINT_KEY_NAME = "mp_fingerprint_key";
+    private static final byte[] SECRET_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6};
+    private static final int CONFIRM_CREDENTIALS_REQUEST_CODE = 1;
+    private static final int FINGERPRINT_PERMISSION_REQUEST_CODE = 0;
+
+    private static final int LOCKSCREEN = 1;
+    private static final int FINGERPRINT = 2;
+
+    private static final String KEYSTORE_NAME = "AndroidKeyStore";
+    private static final String CIPHER_TRANSFORMATION =  KeyProperties.KEY_ALGORITHM_AES + "/"
+            + KeyProperties.BLOCK_MODE_CBC + "/" + KeyProperties.ENCRYPTION_PADDING_PKCS7;
+
+
+    private KeyguardManager mKeyguardManager;
+    private FingerprintManager mFingerprintManager;
+    private boolean mFingerprintSupported;
+
+    private DialogTestListItem mLockScreenBoundKeyTest;
+    private DialogTestListItem mFingerprintBoundKeyTest;
+
+    private Cipher mFingerprintCipher;
+
+    public AuthenticationBoundKeyTestActivity() {
+        super(R.layout.provisioning_byod,
+                R.string.provisioning_byod_auth_bound_key,
+                R.string.provisioning_byod_auth_bound_key_info,
+                R.string.provisioning_byod_auth_bound_key_instruction);
+    }
+
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        mKeyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
+        mFingerprintManager = (FingerprintManager) getSystemService(FINGERPRINT_SERVICE);
+        mFingerprintSupported = mFingerprintManager != null
+                && mFingerprintManager.isHardwareDetected();
+        // Need to have valid mFingerprintSupported value before calling super.onCreate() because
+        // mFingerprintSupported is used in setupTests() which gets called by super.onCreate().
+        super.onCreate(savedInstanceState);
+
+        mPrepareTestButton.setText(R.string.provisioning_byod_auth_bound_key_set_up);
+        mPrepareTestButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View arg0) {
+                startActivity(new Intent(Settings.ACTION_SECURITY_SETTINGS));
+            }
+        });
+        if (mFingerprintSupported) {
+            requestPermissions(new String[] {Manifest.permission.USE_FINGERPRINT},
+                    FINGERPRINT_PERMISSION_REQUEST_CODE);
+        }
+    }
+
+    private class LockscreenCountDownTester extends CountDownTimer {
+
+        private Toast mToast;
+
+        public LockscreenCountDownTester() {
+            // Wait for AUTHENTICATION_DURATION_SECONDS so the key is evicted before the real test.
+            super(AUTHENTICATION_DURATION_SECONDS * 1000, 1000);
+            mToast = Toast.makeText(AuthenticationBoundKeyTestActivity.this, "", Toast.LENGTH_SHORT);
+        }
+
+        @Override
+        public void onFinish() {
+            mToast.cancel();
+            if (tryEncryptWithLockscreenKey()) {
+                showToast("Test failed. Key accessible without auth.");
+                setTestResult(mLockScreenBoundKeyTest, TestResult.TEST_RESULT_FAILED);
+            } else {
+                // Start the Confirm Credentials screen.
+                Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null);
+                if (intent != null) {
+                    startActivityForResult(intent, CONFIRM_CREDENTIALS_REQUEST_CODE);
+                } else {
+                    showToast("Test failed. No lockscreen password exists.");
+                    setTestResult(mLockScreenBoundKeyTest, TestResult.TEST_RESULT_FAILED);
+                }
+            }
+        }
+
+        @Override
+        public void onTick(long millisUntilFinished) {
+            mToast.setText(String.format("Lockscreen challenge start in %d seconds..",
+                    millisUntilFinished / 1000));
+            mToast.show();
+        }
+    }
+
+
+    @Override
+    protected void setupTests(ArrayTestListAdapter adapter) {
+        mLockScreenBoundKeyTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_lockscreen_bound_key,
+                "BYOD_LockScreenBoundKeyTest") {
+
+            @Override
+            public void performTest(DialogTestListActivity activity) {
+                if (checkPreconditions()) {
+                    createKey(LOCKSCREEN);
+                    new LockscreenCountDownTester().start();
+                }
+            }
+        };
+        adapter.add(mLockScreenBoundKeyTest);
+
+        if (mFingerprintSupported) {
+            mFingerprintBoundKeyTest = new DialogTestListItem(this,
+                    R.string.provisioning_byod_fingerprint_bound_key,
+                    "BYOD_FingerprintBoundKeyTest") {
+
+                @Override
+                public void performTest(DialogTestListActivity activity) {
+                    if (checkPreconditions()) {
+                        createKey(FINGERPRINT);
+                        mFingerprintCipher = initFingerprintEncryptionCipher();
+                        if (tryEncryptWithFingerprintKey(mFingerprintCipher)) {
+                            showToast("Test failed. Key accessible without auth.");
+                            setTestResult(mFingerprintBoundKeyTest, TestResult.TEST_RESULT_FAILED);
+                        } else {
+                            new FingerprintAuthDialogFragment().show(getFragmentManager(),
+                                    "fingerprint_dialog");
+                        }
+                    }
+                }
+            };
+            adapter.add(mFingerprintBoundKeyTest);
+        }
+    }
+
+    private boolean checkPreconditions() {
+        if (!mKeyguardManager.isKeyguardSecure()) {
+            showToast("Please set a lockscreen password.");
+            return false;
+        } else if (mFingerprintSupported && !mFingerprintManager.hasEnrolledFingerprints()) {
+            showToast("Please enroll a fingerprint.");
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    private String getKeyName(int testType) {
+        return testType == LOCKSCREEN ? LOCKSCREEN_KEY_NAME : FINGERPRINT_KEY_NAME;
+    }
+    /**
+     * Creates a symmetric key in the Android Key Store which can only be used after the user has
+     * authenticated with device credentials.
+     */
+    private void createKey(int testType) {
+        try {
+            // Set the alias of the entry in Android KeyStore where the key will appear
+            // and the constrains (purposes) in the constructor of the Builder
+            KeyGenParameterSpec.Builder builder;
+            builder = new KeyGenParameterSpec.Builder(getKeyName(testType),
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
+                    .setUserAuthenticationRequired(true)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7);
+            if (testType == LOCKSCREEN) {
+                // Require that the user unlocked the lockscreen in the last 5 seconds
+                builder.setUserAuthenticationValidityDurationSeconds(
+                        AUTHENTICATION_DURATION_SECONDS);
+            }
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(
+                    KeyProperties.KEY_ALGORITHM_AES, KEYSTORE_NAME);
+            keyGenerator.init(builder.build());
+            keyGenerator.generateKey();
+        } catch (NoSuchAlgorithmException | NoSuchProviderException
+                | InvalidAlgorithmParameterException e) {
+            throw new RuntimeException("Failed to create a symmetric key", e);
+        }
+    }
+
+    private SecretKey loadSecretKey(int testType) {
+        try {
+            KeyStore keyStore = KeyStore.getInstance(KEYSTORE_NAME);
+            keyStore.load(null);
+            return (SecretKey) keyStore.getKey(getKeyName(testType), null);
+        } catch (UnrecoverableKeyException  | CertificateException |KeyStoreException | IOException
+                | NoSuchAlgorithmException e) {
+            throw new RuntimeException("Failed to load a symmetric key", e);
+        }
+    }
+
+    private boolean tryEncryptWithLockscreenKey() {
+        try {
+            // Try encrypting something, it will only work if the user authenticated within
+            // the last AUTHENTICATION_DURATION_SECONDS seconds.
+            Cipher cipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
+            cipher.init(Cipher.ENCRYPT_MODE, loadSecretKey(LOCKSCREEN));
+            cipher.doFinal(SECRET_BYTE_ARRAY);
+            return true;
+        } catch (UserNotAuthenticatedException e) {
+            // User is not authenticated, let's authenticate with device credentials.
+            return false;
+        } catch (KeyPermanentlyInvalidatedException e) {
+            // This happens if the lock screen has been disabled or reset after the key was
+            // generated.
+            createKey(LOCKSCREEN);
+            showToast("Set up lockscreen after test ran. Retry the test.");
+            return false;
+        } catch (IllegalBlockSizeException | BadPaddingException | InvalidKeyException
+                | NoSuchPaddingException | NoSuchAlgorithmException e) {
+            throw new RuntimeException("Encrypt with lockscreen-bound key failed", e);
+        }
+    }
+
+    private Cipher initFingerprintEncryptionCipher() {
+        try {
+            Cipher cipher =  Cipher.getInstance(CIPHER_TRANSFORMATION);
+            cipher.init(Cipher.ENCRYPT_MODE, loadSecretKey(FINGERPRINT));
+            return cipher;
+        } catch (NoSuchPaddingException | NoSuchAlgorithmException e) {
+            return null;
+        } catch (KeyPermanentlyInvalidatedException e) {
+            // This happens if the lock screen has been disabled or reset after the key was
+            // generated after the key was generated.
+            createKey(FINGERPRINT);
+            showToast("Set up lockscreen after test ran. Retry the test.");
+            return null;
+        } catch (InvalidKeyException e) {
+            throw new RuntimeException("Init cipher with fingerprint-bound key failed", e);
+        }
+    }
+
+    private boolean tryEncryptWithFingerprintKey(Cipher cipher) {
+
+        try {
+            cipher.doFinal(SECRET_BYTE_ARRAY);
+            return true;
+        } catch (IllegalBlockSizeException e) {
+            // Cannot encrypt, key is unavailable
+            return false;
+        } catch (BadPaddingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    protected void handleActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case CONFIRM_CREDENTIALS_REQUEST_CODE:
+                if (resultCode == RESULT_OK) {
+                    if (tryEncryptWithLockscreenKey()) {
+                        setTestResult(mLockScreenBoundKeyTest, TestResult.TEST_RESULT_PASSED);
+                    } else {
+                        showToast("Test failed. Key not accessible after auth");
+                        setTestResult(mLockScreenBoundKeyTest, TestResult.TEST_RESULT_FAILED);
+                    }
+                } else {
+                    showToast("Lockscreen challenge canceled.");
+                    setTestResult(mLockScreenBoundKeyTest, TestResult.TEST_RESULT_FAILED);
+                }
+                break;
+            default:
+                super.handleActivityResult(requestCode, resultCode, data);
+        }
+    }
+
+    private void showToast(String message) {
+        Toast.makeText(this, message, Toast.LENGTH_LONG).show();
+    }
+
+    public class FingerprintAuthDialogFragment extends DialogFragment {
+
+        private CancellationSignal mCancellationSignal;
+        private FingerprintManagerCallback mFingerprintManagerCallback;
+        private boolean mSelfCancelled;
+
+        class FingerprintManagerCallback extends FingerprintManager.AuthenticationCallback {
+            @Override
+            public void onAuthenticationError(int errMsgId, CharSequence errString) {
+                if (!mSelfCancelled) {
+                    showToast(errString.toString());
+                }
+            }
+
+            @Override
+            public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
+                showToast(helpString.toString());
+            }
+
+            @Override
+            public void onAuthenticationFailed() {
+                showToast(getString(R.string.sec_fp_auth_failed));
+            }
+
+            @Override
+            public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
+                if (tryEncryptWithFingerprintKey(mFingerprintCipher)) {
+                    showToast("Test passed.");
+                    setTestResult(mFingerprintBoundKeyTest, TestResult.TEST_RESULT_PASSED);
+                } else {
+                    showToast("Test failed. Key not accessible after auth");
+                    setTestResult(mFingerprintBoundKeyTest, TestResult.TEST_RESULT_FAILED);
+                }
+                FingerprintAuthDialogFragment.this.dismiss();
+            }
+        }
+
+        @Override
+        public void onDismiss(DialogInterface dialog) {
+            mCancellationSignal.cancel();
+            mSelfCancelled = true;
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            mCancellationSignal = new CancellationSignal();
+            mSelfCancelled = false;
+            mFingerprintManagerCallback = new FingerprintManagerCallback();
+            mFingerprintManager.authenticate(new FingerprintManager.CryptoObject(mFingerprintCipher),
+                    mCancellationSignal, 0, mFingerprintManagerCallback, null);
+            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+            builder.setMessage(R.string.sec_fp_dialog_message);
+            return builder.create();
+        }
+
+    }
+
+}
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 af3a7d5..9e3b2aa 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodFlowTestActivity.java
@@ -16,33 +16,25 @@
 
 package com.android.cts.verifier.managedprovisioning;
 
-import android.app.AlertDialog;
 import android.app.admin.DevicePolicyManager;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.provider.Settings;
 import android.util.Log;
-import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
 import android.widget.Toast;
 
-import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.DialogTestListActivity;
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.TestListActivity;
-
-import java.util.ArrayList;
-import java.util.List;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+import com.android.cts.verifier.TestResult;
 
 /**
  * CTS verifier test for BYOD managed provisioning flow.
@@ -55,61 +47,59 @@
  * The first two verifications are performed automatically, by interacting with profile owner using
  * cross-profile intents, while the last two are carried out manually by the user.
  */
-public class ByodFlowTestActivity extends PassFailButtons.ListActivity {
+public class ByodFlowTestActivity extends DialogTestListActivity {
 
     private final String TAG = "ByodFlowTestActivity";
-    private static final int REQUEST_STATUS = 1;
+    private static final int REQUEST_MANAGED_PROVISIONING = 0;
+    private static final int REQUEST_PROFILE_OWNER_STATUS = 1;
+    private static final int REQUEST_INTENT_FILTERS_STATUS = 2;
 
     private ComponentName mAdminReceiverComponent;
 
-    private TestAdapter mTestListAdapter;
-    private View mStartProvisioningButton;
-    private List<TestItem> mTests = new ArrayList<TestItem>();
+    private DialogTestListItem mProfileOwnerInstalled;
+    private DialogTestListItem mProfileAccountVisibleTest;
+    private DialogTestListItem mDeviceAdminVisibleTest;
+    private DialogTestListItem mWorkAppVisibleTest;
+    private DialogTestListItem mCrossProfileIntentFiltersTestFromPersonal;
+    private DialogTestListItem mCrossProfileIntentFiltersTestFromWork;
+    private DialogTestListItem mAppLinkingTest;
+    private DialogTestListItem mDisableNonMarketTest;
+    private DialogTestListItem mEnableNonMarketTest;
+    private DialogTestListItem mWorkNotificationBadgedTest;
+    private DialogTestListItem mWorkStatusBarIconTest;
+    private DialogTestListItem mWorkStatusBarToastTest;
+    private DialogTestListItem mAppSettingsVisibleTest;
+    private DialogTestListItem mLocationSettingsVisibleTest;
+    private DialogTestListItem mBatterySettingsVisibleTest;
+    private DialogTestListItem mDataUsageSettingsVisibleTest;
+    private DialogTestListItem mCredSettingsVisibleTest;
+    private DialogTestListItem mPrintSettingsVisibleTest;
+    private DialogTestListItem mIntentFiltersTest;
+    private DialogTestListItem mPermissionLockdownTest;
+    private DialogTestListItem mCrossProfileImageCaptureSupportTest;
+    private DialogTestListItem mCrossProfileVideoCaptureSupportTest;
+    private DialogTestListItem mCrossProfileAudioCaptureSupportTest;
+    private TestListItem mKeyguardDisabledFeaturesTest;
+    private DialogTestListItem mDisableNfcBeamTest;
+    private TestListItem mAuthenticationBoundKeyTest;
+    private DialogTestListItem mEnableLocationModeTest;
+    private DialogTestListItem mDisableLocationModeTest;
+    private TestListItem mVpnTest;
 
-    protected DevicePolicyManager mDevicePolicyManager;
-
-    private TestItem mProfileOwnerInstalled;
-    private TestItem mProfileAccountVisibleTest;
-    private TestItem mDeviceAdminVisibleTest;
-    private TestItem mWorkAppVisibleTest;
-    private TestItem mCrossProfileIntentFiltersTest;
-    private TestItem mDisableNonMarketTest;
-    private TestItem mEnableNonMarketTest;
-    private TestItem mWorkNotificationBadgedTest;
-    private TestItem mAppSettingsVisibleTest;
-    private TestItem mLocationSettingsVisibleTest;
-    private TestItem mCredSettingsVisibleTest;
-    private TestItem mPrintSettingsVisibleTest;
-    private TestItem mCrossProfileImageCaptureSupportTest;
-    private TestItem mCrossProfileVideoCaptureSupportTest;
-    private TestItem mCrossProfileAudioCaptureSupportTest;
-    private TestItem mDisableNfcBeamTest;
-
-    private int mCurrentTestPosition;
+    public ByodFlowTestActivity() {
+        super(R.layout.provisioning_byod,
+                R.string.provisioning_byod, R.string.provisioning_byod_info,
+                R.string.provisioning_byod_instructions);
+    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
-        mDevicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
-        disableComponent();
 
-        setContentView(R.layout.provisioning_byod);
-        setInfoResources(R.string.provisioning_byod, R.string.provisioning_byod_info, -1);
-        setPassFailButtonClickListeners();
-        getPassButton().setEnabled(false);
-        setResult(RESULT_CANCELED);
-
-        setupTests();
-
-        mTestListAdapter = new TestAdapter(this);
-        setListAdapter(mTestListAdapter);
-        mTestListAdapter.addAll(mTests);
-
-        mCurrentTestPosition = 0;
-
-        mStartProvisioningButton = findViewById(R.id.byod_start);
-        mStartProvisioningButton.setOnClickListener(new OnClickListener() {
+        enableComponent(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
+        mPrepareTestButton.setText(R.string.provisioning_byod_start);
+        mPrepareTestButton.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
                 startByodProvisioning();
@@ -135,22 +125,34 @@
         // This is called when managed provisioning completes successfully without reboot.
         super.onNewIntent(intent);
         if (ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS.equals(intent.getAction())) {
-            handleStatusUpdate(intent);
+            handleStatusUpdate(RESULT_OK, intent);
         }
     }
 
     @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        // Called after queryProfileOwner()
-        super.onActivityResult(requestCode, resultCode, data);
-        if (requestCode == REQUEST_STATUS && resultCode == RESULT_OK) {
-            handleStatusUpdate(data);
+    protected void handleActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case REQUEST_MANAGED_PROVISIONING:
+                return;
+            case REQUEST_PROFILE_OWNER_STATUS: {
+                // Called after queryProfileOwner()
+                handleStatusUpdate(resultCode, data);
+            } break;
+            case REQUEST_INTENT_FILTERS_STATUS: {
+                // Called after checkIntentFilters()
+                handleIntentFiltersStatus(resultCode);
+            } break;
+            default: {
+                super.handleActivityResult(requestCode, resultCode, data);
+            }
         }
     }
 
-    private void handleStatusUpdate(Intent data) {
-        boolean provisioned = data.getBooleanExtra(ByodHelperActivity.EXTRA_PROVISIONED, false);
-        setTestResult(mProfileOwnerInstalled, provisioned ? TestResult.Passed : TestResult.Failed);
+    private void handleStatusUpdate(int resultCode, Intent data) {
+        boolean provisioned = data != null &&
+                data.getBooleanExtra(ByodHelperActivity.EXTRA_PROVISIONED, false);
+        setTestResult(mProfileOwnerInstalled, (provisioned && resultCode == RESULT_OK) ?
+                TestResult.TEST_RESULT_PASSED : TestResult.TEST_RESULT_FAILED);
     }
 
     @Override
@@ -158,13 +160,17 @@
         // Pass and fail buttons are known to call finish() when clicked, and this is when we want to
         // clean up the provisioned profile.
         requestDeleteProfileOwner();
+        enableComponent(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT);
         super.finish();
     }
 
-    private void setupTests() {
-        mProfileOwnerInstalled = new TestItem(this, R.string.provisioning_byod_profileowner) {
+    @Override
+    protected void setupTests(ArrayTestListAdapter adapter) {
+        mProfileOwnerInstalled = new DialogTestListItem(this,
+                R.string.provisioning_byod_profileowner,
+                "BYOD_ProfileOwnerInstalled") {
             @Override
-            public void performTest(ByodFlowTestActivity activity) {
+            public void performTest(DialogTestListActivity activity) {
                 queryProfileOwner(true);
             }
         };
@@ -173,86 +179,196 @@
          * To keep the image in this test up to date, use the instructions in
          * {@link ByodIconSamplerActivity}.
          */
-        mWorkAppVisibleTest = new TestItemWithIcon(this,
+        mWorkAppVisibleTest = new DialogTestListItemWithIcon(this,
                 R.string.provisioning_byod_workapps_visible,
+                "BYOD_WorkAppVisibleTest",
                 R.string.provisioning_byod_workapps_visible_instruction,
                 new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME),
                 R.drawable.badged_icon);
 
-        mWorkNotificationBadgedTest = new TestItemWithIcon(this,
+        mWorkNotificationBadgedTest = new DialogTestListItemWithIcon(this,
                 R.string.provisioning_byod_work_notification,
+                "BYOD_WorkNotificationBadgedTest",
                 R.string.provisioning_byod_work_notification_instruction,
-                new Intent(WorkNotificationTestActivity.ACTION_WORK_NOTIFICATION),
+                new Intent(ByodHelperActivity.ACTION_NOTIFICATION),
                 R.drawable.ic_corp_icon);
 
-        mDisableNonMarketTest = new TestItem(this, R.string.provisioning_byod_nonmarket_deny,
+        Intent workStatusIcon = new Intent(WorkStatusTestActivity.ACTION_WORK_STATUS_ICON);
+        workStatusIcon.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mWorkStatusBarIconTest = new DialogTestListItemWithIcon(this,
+                R.string.provisioning_byod_work_status_icon,
+                "BYOD_WorkStatusBarIconTest",
+                R.string.provisioning_byod_work_status_icon_instruction,
+                workStatusIcon,
+                R.drawable.stat_sys_managed_profile_status);
+
+        Intent workStatusToast = new Intent(WorkStatusTestActivity.ACTION_WORK_STATUS_TOAST);
+        workStatusToast.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mWorkStatusBarToastTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_work_status_toast,
+                "BYOD_WorkStatusBarToastTest",
+                R.string.provisioning_byod_work_status_toast_instruction,
+                workStatusToast);
+
+        mDisableNonMarketTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_nonmarket_deny,
+                "BYOD_DisableNonMarketTest",
                 R.string.provisioning_byod_nonmarket_deny_info,
                 new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
                         .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, false));
 
-        mEnableNonMarketTest = new TestItem(this, R.string.provisioning_byod_nonmarket_allow,
+        mEnableNonMarketTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_nonmarket_allow,
+                "BYOD_EnableNonMarketTest",
                 R.string.provisioning_byod_nonmarket_allow_info,
                 new Intent(ByodHelperActivity.ACTION_INSTALL_APK)
                         .putExtra(ByodHelperActivity.EXTRA_ALLOW_NON_MARKET_APPS, true));
 
-        mProfileAccountVisibleTest = new TestItem(this, R.string.provisioning_byod_profile_visible,
+        mProfileAccountVisibleTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_profile_visible,
+                "BYOD_ProfileAccountVisibleTest",
                 R.string.provisioning_byod_profile_visible_instruction,
                 new Intent(Settings.ACTION_SETTINGS));
 
-        mAppSettingsVisibleTest = new TestItem(this, R.string.provisioning_byod_app_settings,
+        mAppSettingsVisibleTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_app_settings,
+                "BYOD_AppSettingsVisibleTest",
                 R.string.provisioning_byod_app_settings_instruction,
                 new Intent(Settings.ACTION_APPLICATION_SETTINGS));
 
-        mDeviceAdminVisibleTest = new TestItem(this, R.string.provisioning_byod_admin_visible,
+        mDeviceAdminVisibleTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_admin_visible,
+                "BYOD_DeviceAdminVisibleTest",
                 R.string.provisioning_byod_admin_visible_instruction,
                 new Intent(Settings.ACTION_SECURITY_SETTINGS));
 
-        mCredSettingsVisibleTest = new TestItem(this, R.string.provisioning_byod_cred_settings,
+        mCredSettingsVisibleTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_cred_settings,
+                "BYOD_CredSettingsVisibleTest",
                 R.string.provisioning_byod_cred_settings_instruction,
                 new Intent(Settings.ACTION_SECURITY_SETTINGS));
 
-        mLocationSettingsVisibleTest = new TestItem(this,
+        mLocationSettingsVisibleTest = new DialogTestListItem(this,
                 R.string.provisioning_byod_location_settings,
+                "BYOD_LocationSettingsVisibleTest",
                 R.string.provisioning_byod_location_settings_instruction,
                 new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
 
-        mPrintSettingsVisibleTest = new TestItem(this, R.string.provisioning_byod_print_settings,
+        mBatterySettingsVisibleTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_battery_settings,
+                "BYOD_BatterySettingsVisibleTest",
+                R.string.provisioning_byod_battery_settings_instruction,
+                new Intent(Intent.ACTION_POWER_USAGE_SUMMARY));
+
+        mDataUsageSettingsVisibleTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_data_usage_settings,
+                "BYOD_DataUsageSettingsVisibleTest",
+                R.string.provisioning_byod_data_usage_settings_instruction,
+                new Intent(Settings.ACTION_SETTINGS));
+
+        mPrintSettingsVisibleTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_print_settings,
+                "BYOD_PrintSettingsVisibleTest",
                 R.string.provisioning_byod_print_settings_instruction,
                 new Intent(Settings.ACTION_PRINT_SETTINGS));
 
-        Intent intent = new Intent(CrossProfileTestActivity.ACTION_CROSS_PROFILE);
+        Intent intent = new Intent(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_WORK);
+        intent.putExtra(CrossProfileTestActivity.EXTRA_STARTED_FROM_WORK, false);
         Intent chooser = Intent.createChooser(intent,
                 getResources().getString(R.string.provisioning_cross_profile_chooser));
-        mCrossProfileIntentFiltersTest = new TestItem(this,
-                R.string.provisioning_byod_cross_profile,
-                R.string.provisioning_byod_cross_profile_instruction,
+        mCrossProfileIntentFiltersTestFromPersonal = new DialogTestListItem(this,
+                R.string.provisioning_byod_cross_profile_from_personal,
+                "BYOD_CrossProfileIntentFiltersTestFromPersonal",
+                R.string.provisioning_byod_cross_profile_from_personal_instruction,
                 chooser);
 
-        mTests.add(mProfileOwnerInstalled);
+        mCrossProfileIntentFiltersTestFromWork = new DialogTestListItem(this,
+                R.string.provisioning_byod_cross_profile_from_work,
+                "BYOD_CrossProfileIntentFiltersTestFromWork",
+                R.string.provisioning_byod_cross_profile_from_work_instruction,
+                new Intent(ByodHelperActivity.ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG));
+
+        mAppLinkingTest = new DialogTestListItem(this,
+                R.string.provisioning_app_linking,
+                "BYOD_AppLinking",
+                R.string.provisioning_byod_app_linking_instruction,
+                new Intent(ByodHelperActivity.ACTION_TEST_APP_LINKING_DIALOG));
+
+        mKeyguardDisabledFeaturesTest = TestListItem.newTest(this,
+                R.string.provisioning_byod_keyguard_disabled_features,
+                KeyguardDisabledFeaturesActivity.class.getName(),
+                new Intent(this, KeyguardDisabledFeaturesActivity.class), null);
+
+        mAuthenticationBoundKeyTest = TestListItem.newTest(this,
+                R.string.provisioning_byod_auth_bound_key,
+                AuthenticationBoundKeyTestActivity.class.getName(),
+                new Intent(AuthenticationBoundKeyTestActivity.ACTION_AUTH_BOUND_KEY_TEST),
+                null);
+
+        mVpnTest = TestListItem.newTest(this,
+                R.string.provisioning_byod_vpn,
+                VpnTestActivity.class.getName(),
+                new Intent(VpnTestActivity.ACTION_VPN),
+                null);
+
+        // Test for checking if the required intent filters are set during managed provisioning.
+        mIntentFiltersTest = new DialogTestListItem(this,
+                R.string.provisioning_byod_cross_profile_intent_filters,
+                "BYOD_IntentFiltersTest") {
+            @Override
+            public void performTest(DialogTestListActivity activity) {
+                checkIntentFilters();
+            }
+        };
+
+        Intent permissionCheckIntent = new Intent(
+                PermissionLockdownTestActivity.ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN);
+        mPermissionLockdownTest = new DialogTestListItem(this,
+                R.string.device_profile_owner_permission_lockdown_test,
+                "BYOD_PermissionLockdownTest",
+                R.string.profile_owner_permission_lockdown_test_info,
+                permissionCheckIntent);
+
+        adapter.add(mProfileOwnerInstalled);
 
         // Badge related tests
-        mTests.add(mWorkAppVisibleTest);
-        mTests.add(mWorkNotificationBadgedTest);
+        adapter.add(mWorkAppVisibleTest);
+        adapter.add(mWorkNotificationBadgedTest);
+        adapter.add(mWorkStatusBarIconTest);
+        adapter.add(mWorkStatusBarToastTest);
 
         // Settings related tests.
-        mTests.add(mProfileAccountVisibleTest);
-        mTests.add(mDeviceAdminVisibleTest);
-        mTests.add(mCredSettingsVisibleTest);
-        mTests.add(mAppSettingsVisibleTest);
-        mTests.add(mLocationSettingsVisibleTest);
-        mTests.add(mPrintSettingsVisibleTest);
+        adapter.add(mProfileAccountVisibleTest);
+        adapter.add(mDeviceAdminVisibleTest);
+        adapter.add(mCredSettingsVisibleTest);
+        adapter.add(mAppSettingsVisibleTest);
+        adapter.add(mLocationSettingsVisibleTest);
+        adapter.add(mBatterySettingsVisibleTest);
+        adapter.add(mDataUsageSettingsVisibleTest);
+        adapter.add(mPrintSettingsVisibleTest);
 
-        mTests.add(mCrossProfileIntentFiltersTest);
-        mTests.add(mDisableNonMarketTest);
-        mTests.add(mEnableNonMarketTest);
+        adapter.add(mCrossProfileIntentFiltersTestFromPersonal);
+        adapter.add(mCrossProfileIntentFiltersTestFromWork);
+        adapter.add(mAppLinkingTest);
+        adapter.add(mDisableNonMarketTest);
+        adapter.add(mEnableNonMarketTest);
+        adapter.add(mIntentFiltersTest);
+        adapter.add(mPermissionLockdownTest);
+        adapter.add(mKeyguardDisabledFeaturesTest);
+        adapter.add(mAuthenticationBoundKeyTest);
+        adapter.add(mVpnTest);
 
+        /* If there is an application that handles ACTION_IMAGE_CAPTURE, test that it handles it
+         * well.
+         */
         if (canResolveIntent(ByodHelperActivity.getCaptureImageIntent())) {
             // Capture image intent can be resolved in primary profile, so test.
-            mCrossProfileImageCaptureSupportTest = new TestItem(this,
+            mCrossProfileImageCaptureSupportTest = new DialogTestListItem(this,
                     R.string.provisioning_byod_capture_image_support,
+                    "BYOD_CrossProfileImageCaptureSupportTest",
                     R.string.provisioning_byod_capture_image_support_info,
                     new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_IMAGE));
-            mTests.add(mCrossProfileImageCaptureSupportTest);
+            adapter.add(mCrossProfileImageCaptureSupportTest);
         } else {
             // Capture image intent cannot be resolved in primary profile, so skip test.
             Toast.makeText(ByodFlowTestActivity.this,
@@ -260,13 +376,17 @@
                     .show();
         }
 
+        /* If there is an application that handles ACTION_VIDEO_CAPTURE, test that it handles it
+         * well.
+         */
         if (canResolveIntent(ByodHelperActivity.getCaptureVideoIntent())) {
             // Capture video intent can be resolved in primary profile, so test.
-            mCrossProfileVideoCaptureSupportTest = new TestItem(this,
+            mCrossProfileVideoCaptureSupportTest = new DialogTestListItem(this,
                     R.string.provisioning_byod_capture_video_support,
+                    "BYOD_CrossProfileVideoCaptureSupportTest",
                     R.string.provisioning_byod_capture_video_support_info,
                     new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_VIDEO));
-            mTests.add(mCrossProfileVideoCaptureSupportTest);
+            adapter.add(mCrossProfileVideoCaptureSupportTest);
         } else {
             // Capture video intent cannot be resolved in primary profile, so skip test.
             Toast.makeText(ByodFlowTestActivity.this,
@@ -275,11 +395,12 @@
         }
 
         if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC)) {
-            mDisableNfcBeamTest = new TestItem(this, R.string.provisioning_byod_nfc_beam,
+            mDisableNfcBeamTest = new DialogTestListItem(this, R.string.provisioning_byod_nfc_beam,
+                    "BYOD_DisableNfcBeamTest",
                     R.string.provisioning_byod_nfc_beam_allowed_instruction,
                     new Intent(ByodHelperActivity.ACTION_TEST_NFC_BEAM)) {
                 @Override
-                public void performTest(final ByodFlowTestActivity activity) {
+                public void performTest(final DialogTestListActivity activity) {
                     activity.showManualTestDialog(mDisableNfcBeamTest,
                             new DefaultTestCallback(mDisableNfcBeamTest) {
                         @Override
@@ -289,8 +410,10 @@
                                     ByodHelperActivity.ACTION_TEST_NFC_BEAM);
                             testNfcBeamIntent.putExtra(NfcTestActivity.EXTRA_DISALLOW_BY_POLICY,
                                     true);
-                            TestItem disableNfcBeamTest2 = new TestItem(activity,
+                            DialogTestListItem disableNfcBeamTest2 =
+                                    new DialogTestListItem(activity,
                                     R.string.provisioning_byod_nfc_beam,
+                                    "BYOD_DisableNfcBeamTest",
                                     R.string.provisioning_byod_nfc_beam_disallowed_instruction,
                                     testNfcBeamIntent);
                             // The result should be reflected on the original test.
@@ -300,32 +423,47 @@
                     });
                 }
             };
-            mTests.add(mDisableNfcBeamTest);
+            adapter.add(mDisableNfcBeamTest);
         }
 
-        /* TODO: reinstate when bug b/20131958 is fixed
+        /* If there is an application that handles RECORD_SOUND_ACTION, test that it handles it
+         * well.
+         */
         if (canResolveIntent(ByodHelperActivity.getCaptureAudioIntent())) {
             // Capture audio intent can be resolved in primary profile, so test.
-            mCrossProfileAudioCaptureSupportTest = new TestItem(this,
+            mCrossProfileAudioCaptureSupportTest = new DialogTestListItem(this,
                     R.string.provisioning_byod_capture_audio_support,
+                    "BYOD_CrossProfileAudioCaptureSupportTest",
                     R.string.provisioning_byod_capture_audio_support_info,
                     new Intent(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_AUDIO));
-            mTests.add(mCrossProfileAudioCaptureSupportTest);
+            adapter.add(mCrossProfileAudioCaptureSupportTest);
         } else {
             // Capture audio intent cannot be resolved in primary profile, so skip test.
             Toast.makeText(ByodFlowTestActivity.this,
                     R.string.provisioning_byod_no_audio_capture_resolver, Toast.LENGTH_SHORT)
                     .show();
         }
-        */
-    }
 
-    @Override
-    protected void onListItemClick(ListView l, View v, int position, long id) {
-        super.onListItemClick(l, v, position, id);
-        mCurrentTestPosition = position;
-        TestItem test = (TestItem) getListAdapter().getItem(position);
-        test.performTest(this);
+        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS)) {
+            mEnableLocationModeTest = new DialogTestListItem(this,
+                    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,
+                    R.string.provisioning_byod_location_mode_disable,
+                    "BYOD_LocationModeDisableTest",
+                    R.string.provisioning_byod_location_mode_disable_instruction,
+                    new Intent(ByodHelperActivity.ACTION_SET_LOCATION_AND_CHECK_UPDATES));
+
+            adapter.add(mEnableLocationModeTest);
+            adapter.add(mDisableLocationModeTest);
+        } else {
+            // The system does not support GPS feature, so skip test.
+            Toast.makeText(ByodFlowTestActivity.this,
+                    R.string.provisioning_byod_no_gps_location_feature, Toast.LENGTH_SHORT)
+                    .show();
+        }
     }
 
     // Return whether the intent can be resolved in the current profile
@@ -333,106 +471,29 @@
         return intent.resolveActivity(getPackageManager()) != null;
     }
 
-    private class DefaultTestCallback implements TestItem.TestCallback {
-        final private TestItem mTest;
-
-        public DefaultTestCallback(TestItem test) {
-            mTest = test;
-        }
-
-        @Override
-        public void onPass() {
-            clearRemainingState(mTest);
-            setTestResult(mTest, TestResult.Passed);
-        }
-
-        @Override
-        public void onFail() {
-            clearRemainingState(mTest);
-            setTestResult(mTest, TestResult.Failed);
-        }
-    }
-
-    private void showManualTestDialog(final TestItem test) {
-        showManualTestDialog(test, new DefaultTestCallback(test));
-    }
-
-    private void showManualTestDialog(final TestItem test, final TestItem.TestCallback callback) {
-        AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this)
-                .setIcon(android.R.drawable.ic_dialog_info)
-                .setTitle(R.string.provisioning_byod)
-                .setNeutralButton(R.string.provisioning_byod_go, null)
-                .setPositiveButton(R.string.pass_button_text, new AlertDialog.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        callback.onPass();
-                    }
-                })
-                .setNegativeButton(R.string.fail_button_text, new AlertDialog.OnClickListener() {
-                    @Override
-                    public void onClick(DialogInterface dialog, int which) {
-                        callback.onFail();
-                    }
-                });
-        View customView = test.getCustomView();
-        if (customView != null) {
-            dialogBuilder.setView(customView);
-        } else {
-            dialogBuilder.setMessage(test.getManualTestInstruction());
-        }
-        final AlertDialog dialog = dialogBuilder.show();
-        // Note: Setting the OnClickListener on the Dialog rather than the Builder, prevents the
-        // dialog being dismissed on onClick.
-        dialog.getButton(AlertDialog.BUTTON_NEUTRAL).setOnClickListener(new OnClickListener() {
-            @Override
-            public void onClick(View v) {
-                try {
-                    ByodFlowTestActivity.this.startActivity(test.getManualTestIntent());
-                } catch (ActivityNotFoundException e) {
-                    Toast.makeText(ByodFlowTestActivity.this,
-                            "Cannot start " + test.getManualTestIntent(), Toast.LENGTH_LONG).show();
-                    setTestResult(test, TestResult.Failed);
-                    dialog.dismiss();
-                }
-            }
-        });
-    }
-
-    private void clearRemainingState(final TestItem test) {
-        if (WorkNotificationTestActivity.ACTION_WORK_NOTIFICATION.equals(
+    @Override
+    protected void clearRemainingState(final DialogTestListItem test) {
+        super.clearRemainingState(test);
+        if (ByodHelperActivity.ACTION_NOTIFICATION.equals(
                 test.getManualTestIntent().getAction())) {
             try {
-                ByodFlowTestActivity.this.startActivity(new Intent(
-                        WorkNotificationTestActivity.ACTION_CLEAR_WORK_NOTIFICATION));
+                startActivity(new Intent(
+                        ByodHelperActivity.ACTION_CLEAR_NOTIFICATION));
             } catch (ActivityNotFoundException e) {
                 // User shouldn't run this test before work profile is set up.
             }
         }
     }
 
-    private void setTestResult(TestItem test, TestResult result) {
-        test.setPassFailState(result);
-
-        boolean testSucceeds = true;
-        for(TestItem aTest : mTests) {
-            testSucceeds &= (aTest.getPassFailState() == TestResult.Passed);
-        }
-        getPassButton().setEnabled(testSucceeds);
-        mTestListAdapter.notifyDataSetChanged();
-
-        this.getListView().smoothScrollToPosition(mCurrentTestPosition + 1);
-    }
-
     private void startByodProvisioning() {
         Intent sending = new Intent(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE);
-        sending.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_PACKAGE_NAME,
-                mAdminReceiverComponent.getPackageName());
-        sending.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminReceiverComponent);
+        sending.putExtra(DevicePolicyManager.EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME,
+                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, 0);
+            startActivityForResult(sending, REQUEST_MANAGED_PROVISIONING);
         } else {
             showToast(R.string.provisioning_byod_disabled);
         }
@@ -441,11 +502,11 @@
     private void queryProfileOwner(boolean showToast) {
         try {
             Intent intent = new Intent(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
-            startActivityForResult(intent, REQUEST_STATUS);
+            startActivityForResult(intent, REQUEST_PROFILE_OWNER_STATUS);
         }
         catch (ActivityNotFoundException e) {
             Log.d(TAG, "queryProfileOwner: ActivityNotFoundException", e);
-            setTestResult(mProfileOwnerInstalled, TestResult.Failed);
+            setTestResult(mProfileOwnerInstalled, TestResult.TEST_RESULT_FAILED);
             if (showToast) {
                 showToast(R.string.provisioning_byod_no_activity);
             }
@@ -463,140 +524,65 @@
         }
     }
 
-    private void disableComponent() {
-        // Disable app components in the current profile, so only the counterpart in the other profile
-        // can respond (via cross-profile intent filter)
-        getPackageManager().setComponentEnabledSetting(new ComponentName(
-                this, ByodHelperActivity.class),
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                PackageManager.DONT_KILL_APP);
-        getPackageManager().setComponentEnabledSetting(new ComponentName(
-                this, WorkNotificationTestActivity.class),
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
-                PackageManager.DONT_KILL_APP);
-    }
-
-    private void showToast(int messageId) {
-        String message = getString(messageId);
-        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
-    }
-
-    enum TestResult {
-        Unknown, Failed, Passed
-    }
-
-    static class TestItem {
-
-        public interface TestCallback {
-            void onPass();
-            void onFail();
-        }
-
-        private String mDisplayName;
-        private TestResult mPassed;
-        private boolean mManualTest;
-        private String mManualInstruction;
-        private Intent mManualIntent;
-
-        public TestItem(Context context, int nameResId) {
-            mDisplayName = context.getString(nameResId);
-            mPassed = TestResult.Unknown;
-            mManualTest = false;
-        }
-
-        public void performTest(ByodFlowTestActivity activity) {
-            if (isManualTest()) {
-                activity.showManualTestDialog(this);
-            }
-        }
-
-        public TestItem(Context context, int nameResId, int testInstructionResId, Intent testIntent) {
-            mDisplayName = context.getString(nameResId);
-            mPassed = TestResult.Unknown;
-            mManualTest = true;
-            mManualInstruction = context.getString(testInstructionResId);
-            mManualIntent = testIntent;
-        }
-
-        @Override
-        public String toString() {
-            return mDisplayName;
-        }
-
-        TestResult getPassFailState() {
-            return mPassed;
-        }
-
-        void setPassFailState(TestResult state) {
-            mPassed = state;
-        }
-
-        public boolean isManualTest() {
-            return mManualTest;
-        }
-
-        public String getManualTestInstruction() {
-            return mManualInstruction;
-        }
-
-        public Intent getManualTestIntent() {
-            return mManualIntent;
-        }
-
-        public View getCustomView() {
-            return null;
+    private void checkIntentFilters() {
+        try {
+            // Enable component HandleIntentActivity before intent filters are checked.
+            setHandleIntentActivityEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
+            // We disable the ByodHelperActivity in the primary profile. So, this intent
+            // will be handled by the ByodHelperActivity in the managed profile.
+            Intent intent = new Intent(ByodHelperActivity.ACTION_CHECK_INTENT_FILTERS);
+            startActivityForResult(intent, REQUEST_INTENT_FILTERS_STATUS);
+        } catch (ActivityNotFoundException e) {
+            // Disable component HandleIntentActivity if intent filters check fails.
+            setHandleIntentActivityEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
+            Log.d(TAG, "checkIntentFilters: ActivityNotFoundException", e);
+            setTestResult(mIntentFiltersTest, TestResult.TEST_RESULT_FAILED);
+            showToast(R.string.provisioning_byod_no_activity);
         }
     }
 
-    static class TestItemWithIcon extends TestItem {
+    private void handleIntentFiltersStatus(int resultCode) {
+        // Disable component HandleIntentActivity after intent filters are checked.
+        setHandleIntentActivityEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
+        // we use the resultCode from ByodHelperActivity in the managed profile to know if certain
+        // intents fired from the managed profile are forwarded.
+        final boolean intentFiltersSetForManagedIntents = (resultCode == RESULT_OK);
+        // Since the ByodFlowTestActivity is running in the primary profile, we directly use
+        // the IntentFiltersTestHelper to know if certain intents fired from the primary profile
+        // are forwarded.
+        final boolean intentFiltersSetForPrimaryIntents =
+                new IntentFiltersTestHelper(this).checkCrossProfileIntentFilters(
+                        IntentFiltersTestHelper.FLAG_INTENTS_FROM_PRIMARY);
+        final boolean intentFiltersSet =
+                intentFiltersSetForPrimaryIntents & intentFiltersSetForManagedIntents;
+        setTestResult(mIntentFiltersTest,
+                intentFiltersSet ? TestResult.TEST_RESULT_PASSED : TestResult.TEST_RESULT_FAILED);
+    }
 
-        private int mImageResId;
-        private Context mContext;
-
-        public TestItemWithIcon(Context context, int nameResId, int testInstructionResId,
-                Intent testIntent, int imageResId) {
-            super(context, nameResId, testInstructionResId, testIntent);
-            mContext = context;
-            mImageResId = imageResId;
-        }
-
-        @Override
-        public View getCustomView() {
-            LayoutInflater layoutInflater = LayoutInflater.from(mContext);
-            View view = layoutInflater.inflate(R.layout.byod_custom_view,
-                    null /* root */);
-            ((ImageView) view.findViewById(R.id.sample_icon)).setImageResource(mImageResId);
-            ((TextView) view.findViewById(R.id.message)).setText(getManualTestInstruction());
-            return view;
+    /**
+     *  Disable or enable app components in the current profile. When they are disabled only the
+     * counterpart in the other profile can respond (via cross-profile intent filter).
+     * @param enabledState {@link PackageManager#COMPONENT_ENABLED_STATE_DISABLED} or
+     *                      {@link PackageManager#COMPONENT_ENABLED_STATE_DEFAULT}
+     */
+    private void enableComponent(final int enabledState) {
+        final String[] components = {
+            ByodHelperActivity.class.getName(),
+            WorkStatusTestActivity.class.getName(),
+            PermissionLockdownTestActivity.ACTIVITY_ALIAS,
+            AuthenticationBoundKeyTestActivity.class.getName(),
+            VpnTestActivity.class.getName()
+        };
+        for (String component : components) {
+            getPackageManager().setComponentEnabledSetting(new ComponentName(this, component),
+                    enabledState, PackageManager.DONT_KILL_APP);
         }
     }
 
-    static class TestAdapter extends ArrayAdapter<TestItem> {
-
-        public TestAdapter(Context context) {
-            super(context, android.R.layout.simple_list_item_1);
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            TextView view = (TextView) super.getView(position, convertView, parent);
-
-            TestItem item = getItem(position);
-            int backgroundResource = 0;
-            int iconResource = 0;
-            if (item.getPassFailState() == TestResult.Passed) {
-                backgroundResource = R.drawable.test_pass_gradient;
-                iconResource = R.drawable.fs_good;
-            } else if (item.getPassFailState() == TestResult.Failed){
-                backgroundResource = R.drawable.test_fail_gradient;
-                iconResource = R.drawable.fs_error;
-            }
-            view.setBackgroundResource(backgroundResource);
-            view.setPadding(10, 0, 10, 0);
-            view.setCompoundDrawablePadding(10);
-            view.setCompoundDrawablesWithIntrinsicBounds(0, 0, iconResource, 0);
-
-            return view;
-        }
+    private void setHandleIntentActivityEnabledSetting(final int enableState) {
+        getPackageManager().setComponentEnabledSetting(
+            new ComponentName(ByodFlowTestActivity.this, HandleIntentActivity.class.getName()),
+            enableState, PackageManager.DONT_KILL_APP);
     }
+
 }
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 800137a..ef7c952 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/ByodHelperActivity.java
@@ -19,14 +19,22 @@
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
 import android.app.Dialog;
+import android.app.Notification;
+import android.app.NotificationManager;
 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.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.UserManager;
 import android.provider.MediaStore;
 import android.provider.Settings;
 import android.support.v4.content.FileProvider;
@@ -39,7 +47,6 @@
 import java.util.ArrayList;
 
 import com.android.cts.verifier.R;
-import com.android.cts.verifier.managedprovisioning.ByodFlowTestActivity.TestResult;
 import com.android.cts.verifier.managedprovisioning.ByodPresentMediaDialog.DialogCallback;
 
 /**
@@ -51,7 +58,7 @@
  *
  * Note: We have to use a dummy activity because cross-profile intents only work for activities.
  */
-public class ByodHelperActivity extends Activity implements DialogCallback {
+public class ByodHelperActivity extends Activity implements DialogCallback, Handler.Callback {
     static final String TAG = "ByodHelperActivity";
 
     // Primary -> managed intent: query if the profile owner has been set up.
@@ -68,30 +75,86 @@
     public static final String ACTION_CAPTURE_AND_CHECK_VIDEO = "com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_VIDEO";
     // Primage -> managed intent: request to capture and check an audio recording
     public static final String ACTION_CAPTURE_AND_CHECK_AUDIO = "com.android.cts.verifier.managedprovisioning.BYOD_CAPTURE_AND_CHECK_AUDIO";
+    public static final String ACTION_KEYGUARD_DISABLED_FEATURES =
+            "com.android.cts.verifier.managedprovisioning.BYOD_KEYGUARD_DISABLED_FEATURES";
+    public static final String ACTION_LOCKNOW =
+            "com.android.cts.verifier.managedprovisioning.BYOD_LOCKNOW";
     public static final String ACTION_TEST_NFC_BEAM = "com.android.cts.verifier.managedprovisioning.TEST_NFC_BEAM";
 
     public static final String EXTRA_PROVISIONED = "extra_provisioned";
+    public static final String EXTRA_PARAMETER_1 = "extra_parameter_1";
 
     // Primary -> managed intent: set unknown sources restriction and install package
     public static final String ACTION_INSTALL_APK = "com.android.cts.verifier.managedprovisioning.BYOD_INSTALL_APK";
     public static final String EXTRA_ALLOW_NON_MARKET_APPS = INSTALL_NON_MARKET_APPS;
 
+    // Primary -> managed intent: check if the required cross profile intent filters are set.
+    public static final String ACTION_CHECK_INTENT_FILTERS =
+            "com.android.cts.verifier.managedprovisioning.action.CHECK_INTENT_FILTERS";
+
+    // Primary -> managed intent: will send a cross profile intent and check if the user sees an
+    // intent picker dialog and can open the apps.
+    public static final String ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG =
+            "com.android.cts.verifier.managedprovisioning.action.TEST_CROSS_PROFILE_INTENTS_DIALOG";
+
+    // Primary -> managed intent: will send an app link intent and check if the user sees a
+    // dialog and can open the apps. This test is extremely similar to
+    // ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG, but the intent used is a web intent, and there is
+    // some behavior which is specific to web intents.
+    public static final String ACTION_TEST_APP_LINKING_DIALOG =
+            "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 =
+            "com.android.cts.verifier.managedprovisioning.BYOD_SET_LOCATION_AND_CHECK";
+    public static final String ACTION_NOTIFICATION =
+            "com.android.cts.verifier.managedprovisioning.NOTIFICATION";
+    public static final String ACTION_NOTIFICATION_ON_LOCKSCREEN =
+            "com.android.cts.verifier.managedprovisioning.LOCKSCREEN_NOTIFICATION";
+    public static final String ACTION_CLEAR_NOTIFICATION =
+            "com.android.cts.verifier.managedprovisioning.CLEAR_NOTIFICATION";
+
+    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 = 3;
     private static final int REQUEST_AUDIO_CAPTURE = 4;
+    private static final int REQUEST_LOCATION_UPDATE = 5;
 
     private static final String ORIGINAL_SETTINGS_NAME = "original settings";
+
+    private static final int NOTIFICATION_ID = 7;
+
+    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;
 
     private ArrayList<File> mTempFiles = new ArrayList<File>();
 
+    private void showNotification(int visibility) {
+        final Notification notification = new Notification.Builder(this)
+                .setSmallIcon(R.drawable.icon)
+                .setContentTitle(getString(R.string.provisioning_byod_notification_title))
+                .setVisibility(visibility)
+                .setAutoCancel(true)
+                .build();
+        mNotificationManager.notify(NOTIFICATION_ID, notification);
+    }
+
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -105,6 +168,10 @@
         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();
         Log.d(TAG, "ByodHelperActivity.onCreate: " + action);
@@ -123,6 +190,8 @@
             // Request to delete work profile.
         } else if (action.equals(ACTION_REMOVE_PROFILE_OWNER)) {
             if (isProfileOwner()) {
+                Log.d(TAG, "Clearing cross profile intents");
+                mDevicePolicyManager.clearCrossProfileIntentFilters(mAdminReceiverComponent);
                 mDevicePolicyManager.wipeData(0);
                 showToast(R.string.provisioning_byod_profile_deleted);
             }
@@ -143,7 +212,15 @@
 
             // Not yet ready to finish- wait until the result comes back
             return;
+            // Queried by CtsVerifier in the primary side using startActivityForResult.
+        } else if (action.equals(ACTION_CHECK_INTENT_FILTERS)) {
+            final boolean intentFiltersSetForManagedIntents =
+                    new IntentFiltersTestHelper(this).checkCrossProfileIntentFilters(
+                            IntentFiltersTestHelper.FLAG_INTENTS_FROM_MANAGED);
+            setResult(intentFiltersSetForManagedIntents? RESULT_OK : RESULT_FAILED, null);
         } else if (action.equals(ACTION_CAPTURE_AND_CHECK_IMAGE)) {
+            // We need the camera permission to send the image capture intent.
+            grantCameraPermissionToSelf();
             Intent captureImageIntent = getCaptureImageIntent();
             mImageUri = getTempUri("image.jpg");
             captureImageIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
@@ -156,6 +233,8 @@
             }
             return;
         } else if (action.equals(ACTION_CAPTURE_AND_CHECK_VIDEO)) {
+            // We need the camera permission to send the video capture intent.
+            grantCameraPermissionToSelf();
             Intent captureVideoIntent = getCaptureVideoIntent();
             mVideoUri = getTempUri("video.mp4");
             captureVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, mVideoUri);
@@ -177,12 +256,55 @@
                 finish();
             }
             return;
+        } 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);
+        } else if (ACTION_LOCKNOW.equals(action)) {
+            mDevicePolicyManager.lockNow();
+            setResult(RESULT_OK);
         } else if (action.equals(ACTION_TEST_NFC_BEAM)) {
             Intent testNfcBeamIntent = new Intent(this, NfcTestActivity.class);
             testNfcBeamIntent.putExtras(intent);
             startActivity(testNfcBeamIntent);
             finish();
             return;
+        } else if (action.equals(ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG)) {
+            sendIntentInsideChooser(new Intent(
+                    CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_PERSONAL));
+        } else if (action.equals(ACTION_TEST_APP_LINKING_DIALOG)) {
+            mDevicePolicyManager.addUserRestriction(
+                    DeviceAdminTestReceiver.getReceiverComponentName(),
+                    UserManager.ALLOW_PARENT_PROFILE_APP_LINKING);
+            Intent toSend = new Intent(Intent.ACTION_VIEW);
+            toSend.setData(Uri.parse("http://com.android.cts.verifier"));
+            sendIntentInsideChooser(toSend);
+        } 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);
+            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();
+            showNotification(Notification.VISIBILITY_PRIVATE);
+        } else if (ACTION_CLEAR_NOTIFICATION.equals(action)) {
+            mNotificationManager.cancel(NOTIFICATION_ID);
         }
         // This activity has no UI and is only used to respond to CtsVerifier in the primary side.
         finish();
@@ -238,6 +360,13 @@
                 }
                 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);
                 break;
@@ -263,6 +392,14 @@
         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);
+    }
+
     private Uri getTempUri(String fileName) {
         final File file = new File(getFilesDir() + File.separator + "images"
                 + File.separator + fileName);
@@ -308,8 +445,62 @@
         Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
     }
 
+    private void grantCameraPermissionToSelf() {
+        mDevicePolicyManager.setPermissionGrantState(mAdminReceiverComponent, getPackageName(),
+                android.Manifest.permission.CAMERA,
+                DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+    }
+
+    private void sendIntentInsideChooser(Intent toSend) {
+        toSend.putExtra(CrossProfileTestActivity.EXTRA_STARTED_FROM_WORK, true);
+        Intent chooser = Intent.createChooser(toSend,
+                getResources().getString(R.string.provisioning_cross_profile_chooser));
+        startActivity(chooser);
+    }
+
+    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;
+    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfileTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfileTestActivity.java
index 6c38e12..3f316f21 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfileTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/CrossProfileTestActivity.java
@@ -35,7 +35,12 @@
  */
 public class CrossProfileTestActivity extends Activity {
     // Intent for app in both profiles
-    public static final String ACTION_CROSS_PROFILE = "com.android.cts.verifier.managedprovisioning.CROSS_PROFILE";
+    public static final String ACTION_CROSS_PROFILE_TO_PERSONAL =
+            "com.android.cts.verifier.managedprovisioning.CROSS_PROFILE_TO_PERSONAL";
+    public static final String ACTION_CROSS_PROFILE_TO_WORK =
+            "com.android.cts.verifier.managedprovisioning.CROSS_PROFILE_TO_WORK";
+    public static final String EXTRA_STARTED_FROM_WORK
+            = "com.android.cts.verifier.managedprovisioning.STARTED_FROM_WORK";
 
     @Override
     public void onCreate(Bundle savedInstanceState) {
@@ -45,9 +50,15 @@
 
         // Check if we are running in the work or personal side, by testing if currently we are the
         // profile owner or not.
-        textView.setText(isProfileOwner() ? R.string.provisioning_byod_cross_profile_app_work
-                : R.string.provisioning_byod_cross_profile_app_personal);
-
+        boolean inWorkProfile = isProfileOwner();
+        boolean startedFromWork = getIntent().getBooleanExtra(EXTRA_STARTED_FROM_WORK, false);
+        if (inWorkProfile && !startedFromWork) {
+            textView.setText(R.string.provisioning_byod_cross_profile_app_work);
+        } else if (!inWorkProfile && startedFromWork) {
+            textView.setText(R.string.provisioning_byod_cross_profile_app_personal);
+        } else { // started from the same side we're currently running in
+            textView.setText(R.string.provisioning_byod_cross_profile_app_ctsverifier);
+        }
         findViewById(R.id.button_finish).setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
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 15349ab..039cc09 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceAdminTestReceiver.java
@@ -22,9 +22,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
+import android.provider.Settings;
 import android.util.Log;
-import android.widget.Toast;
 
 /**
  * Profile owner receiver for BYOD flow test.
@@ -32,6 +31,16 @@
  */
 public class DeviceAdminTestReceiver extends DeviceAdminReceiver {
         private static final String TAG = "DeviceAdminTestReceiver";
+        private static final String DEVICE_OWNER_PKG =
+                "com.android.cts.verifier";
+        private static final String ADMIN_RECEIVER_TEST_CLASS =
+                DEVICE_OWNER_PKG + ".managedprovisioning.DeviceAdminTestReceiver";
+        private static final ComponentName RECEIVER_COMPONENT_NAME = new ComponentName(
+                DEVICE_OWNER_PKG, ADMIN_RECEIVER_TEST_CLASS);
+
+        public static ComponentName getReceiverComponentName() {
+            return RECEIVER_COMPONENT_NAME;
+        }
 
         @Override
         public void onProfileProvisioningComplete(Context context, Intent intent) {
@@ -49,19 +58,33 @@
             filter.addAction(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
             filter.addAction(ByodHelperActivity.ACTION_REMOVE_PROFILE_OWNER);
             filter.addAction(ByodHelperActivity.ACTION_INSTALL_APK);
+            filter.addAction(ByodHelperActivity.ACTION_CHECK_INTENT_FILTERS);
             filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_IMAGE);
             filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_VIDEO);
             filter.addAction(ByodHelperActivity.ACTION_CAPTURE_AND_CHECK_AUDIO);
+            filter.addAction(ByodHelperActivity.ACTION_KEYGUARD_DISABLED_FEATURES);
+            filter.addAction(ByodHelperActivity.ACTION_LOCKNOW);
             filter.addAction(ByodHelperActivity.ACTION_TEST_NFC_BEAM);
-            filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE);
-            filter.addAction(WorkNotificationTestActivity.ACTION_WORK_NOTIFICATION);
-            filter.addAction(WorkNotificationTestActivity.ACTION_CLEAR_WORK_NOTIFICATION);
+            filter.addAction(ByodHelperActivity.ACTION_TEST_CROSS_PROFILE_INTENTS_DIALOG);
+            filter.addAction(ByodHelperActivity.ACTION_TEST_APP_LINKING_DIALOG);
+            filter.addAction(ByodHelperActivity.ACTION_NOTIFICATION);
+            filter.addAction(ByodHelperActivity.ACTION_NOTIFICATION_ON_LOCKSCREEN);
+            filter.addAction(ByodHelperActivity.ACTION_CLEAR_NOTIFICATION);
+            filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_WORK);
+            filter.addAction(WorkStatusTestActivity.ACTION_WORK_STATUS_TOAST);
+            filter.addAction(WorkStatusTestActivity.ACTION_WORK_STATUS_ICON);
+            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(VpnTestActivity.ACTION_VPN);
             dpm.addCrossProfileIntentFilter(getWho(context), filter,
                     DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT);
 
             // Work -> primary direction
             filter = new IntentFilter();
             filter.addAction(ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS);
+            filter.addAction(CrossProfileTestActivity.ACTION_CROSS_PROFILE_TO_PERSONAL);
             dpm.addCrossProfileIntentFilter(getWho(context), filter,
                     DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
 
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
new file mode 100644
index 0000000..3c0955d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerNegativeTestActivity.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.database.DataSetObserver;
+import android.os.Bundle;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.IntentDrivenTestActivity;
+import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
+import com.android.cts.verifier.IntentDrivenTestActivity.TestInfo;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.TestListAdapter.TestListItem;
+
+/**
+ * Activity that lists all device owner negative tests.
+ */
+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);
+
+    private static final String DEVICE_OWNER_NEGATIVE_TEST = "DEVICE_OWNER_PROVISIONING_NEGATIVE";
+    private static final TestInfo DEVICE_OWNER_NEGATIVE_TEST_INFO = new TestInfo(
+                    DEVICE_OWNER_NEGATIVE_TEST,
+                    R.string.device_owner_negative_test,
+                    R.string.device_owner_negative_test_info,
+                    new ButtonInfo(
+                            R.string.start_device_owner_provisioning_button,
+                            PROVISION_DEVICE_INTENT));
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pass_fail_list);
+        setInfoResources(R.string.device_owner_provisioning_tests,
+                R.string.device_owner_provisioning_tests_info, 0);
+        setPassFailButtonClickListeners();
+
+        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+        adapter.add(TestListItem.newCategory(this, R.string.device_owner_provisioning_category));
+
+        Intent startTestIntent = new Intent(this, IntentDrivenTestActivity.class)
+                    .putExtra(IntentDrivenTestActivity.EXTRA_ID,
+                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getTestId())
+                    .putExtra(IntentDrivenTestActivity.EXTRA_TITLE,
+                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getTitle())
+                    .putExtra(IntentDrivenTestActivity.EXTRA_INFO,
+                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getInfoText())
+                    .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS,
+                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getButtons());
+
+
+        adapter.add(TestListItem.newTest(this, DEVICE_OWNER_NEGATIVE_TEST_INFO.getTitle(),
+                DEVICE_OWNER_NEGATIVE_TEST_INFO.getTestId(), startTestIntent, null));
+
+        adapter.registerDataSetObserver(new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                updatePassButton();
+            }
+        });
+
+        setTestListAdapter(adapter);
+    }
+}
+
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
new file mode 100644
index 0000000..72361c1
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerPositiveTestActivity.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.database.DataSetObserver;
+import android.os.Bundle;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.IntentDrivenTestActivity;
+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 positive 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 DeviceOwnerPositiveTestActivity extends PassFailButtons.TestListActivity {
+    private static final String TAG = "DeviceOwnerPositiveTestActivity";
+
+    static final String EXTRA_COMMAND = "extra-command";
+    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";
+    private static final String WIFI_LOCKDOWN_TEST_ID = WifiLockdownTestActivity.class.getName();
+    private static final String DISABLE_STATUS_BAR_TEST_ID = "DISABLE_STATUS_BAR";
+    private static final String DISABLE_KEYGUARD_TEST_ID = "DISABLE_KEYGUARD";
+    private static final String CHECK_PERMISSION_LOCKDOWN_TEST_ID =
+            PermissionLockdownTestActivity.class.getName();
+    private static final String DISALLOW_CONFIG_BT_ID = "DISALLOW_CONFIG_BT";
+    private static final String DISALLOW_CONFIG_WIFI_ID = "DISALLOW_CONFIG_WIFI";
+    private static final String DISALLOW_CONFIG_VPN_ID = "DISALLOW_CONFIG_VPN";
+    //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 REMOVE_DEVICE_OWNER_TEST_ID = "REMOVE_DEVICE_OWNER";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.positive_device_owner);
+        setInfoResources(R.string.device_owner_positive_tests,
+                R.string.device_owner_positive_tests_info, 0);
+        setPassFailButtonClickListeners();
+
+        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+        adapter.add(TestListItem.newCategory(this, R.string.device_owner_positive_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(
+                        DeviceOwnerPositiveTestActivity.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() {
+        // 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)
+                        ));
+
+        // device admin settings
+        adapter.add(createInteractiveTestItem(this, DEVICE_ADMIN_SETTINGS_ID,
+                R.string.device_owner_device_admin_visible,
+                R.string.device_owner_device_admin_visible_info,
+                new ButtonInfo(
+                        R.string.device_owner_settings_go,
+                        new Intent(Settings.ACTION_SECURITY_SETTINGS))));
+
+        PackageManager packageManager = getPackageManager();
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            // WiFi Lock down tests
+            adapter.add(createTestItem(this, WIFI_LOCKDOWN_TEST_ID,
+                    R.string.device_owner_wifi_lockdown_test,
+                    new Intent(this, WifiLockdownTestActivity.class)));
+
+            // DISALLOW_CONFIG_WIFI
+            adapter.add(createInteractiveTestItem(this, DISALLOW_CONFIG_WIFI_ID,
+                    R.string.device_owner_disallow_config_wifi,
+                    R.string.device_owner_disallow_config_wifi_info,
+                    new ButtonInfo[] {
+                            new ButtonInfo(
+                                    R.string.device_owner_user_restriction_set,
+                                    createSetUserRestrictionIntent(
+                                            UserManager.DISALLOW_CONFIG_WIFI)),
+                            new ButtonInfo(
+                                    R.string.device_owner_settings_go,
+                                    new Intent(Settings.ACTION_WIFI_SETTINGS))}));
+        }
+
+        // DISALLOW_CONFIG_VPN
+        adapter.add(createInteractiveTestItem(this, DISALLOW_CONFIG_VPN_ID,
+                R.string.device_owner_disallow_config_vpn,
+                R.string.device_owner_disallow_config_vpn_info,
+                new ButtonInfo[] {
+                        new ButtonInfo(
+                                R.string.device_owner_user_vpn_restriction_set,
+                                createSetUserRestrictionIntent(
+                                        UserManager.DISALLOW_CONFIG_VPN)),
+                        new ButtonInfo(
+                                R.string.device_owner_settings_go,
+                                new Intent(ACTION_VPN_SETTINGS)),
+                        new ButtonInfo(
+                                R.string.device_owner_vpn_test,
+                                new Intent(this, VpnTestActivity.class))}));
+
+        // DISALLOW_CONFIG_BLUETOOTH
+        if (packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)) {
+            adapter.add(createInteractiveTestItem(this, DISALLOW_CONFIG_BT_ID,
+                    R.string.device_owner_disallow_config_bt,
+                    R.string.device_owner_disallow_config_bt_info,
+                    new ButtonInfo[] {
+                            new ButtonInfo(
+                                    R.string.device_owner_user_restriction_set,
+                                    createSetUserRestrictionIntent(
+                                            UserManager.DISALLOW_CONFIG_BLUETOOTH)),
+                            new ButtonInfo(
+                                    R.string.device_owner_settings_go,
+                                    new Intent(Settings.ACTION_BLUETOOTH_SETTINGS))}));
+        }
+
+        // setStatusBarDisabled
+        adapter.add(createInteractiveTestItem(this, DISABLE_STATUS_BAR_TEST_ID,
+                R.string.device_owner_disable_statusbar_test,
+                R.string.device_owner_disable_statusbar_test_info,
+                new ButtonInfo[] {
+                        new ButtonInfo(
+                                R.string.device_owner_disable_statusbar_button,
+                                createDeviceOwnerIntentWithBooleanParameter(
+                                        COMMAND_SET_STATUSBAR_DISABLED, true)),
+                        new ButtonInfo(
+                                R.string.device_owner_reenable_statusbar_button,
+                                createDeviceOwnerIntentWithBooleanParameter(
+                                        COMMAND_SET_STATUSBAR_DISABLED, false))}));
+
+        // setKeyguardDisabled
+        adapter.add(createInteractiveTestItem(this, DISABLE_KEYGUARD_TEST_ID,
+                R.string.device_owner_disable_keyguard_test,
+                R.string.device_owner_disable_keyguard_test_info,
+                new ButtonInfo[] {
+                        new ButtonInfo(
+                                R.string.device_owner_disable_keyguard_button,
+                                createDeviceOwnerIntentWithBooleanParameter(
+                                        COMMAND_SET_KEYGUARD_DISABLED, true)),
+                        new ButtonInfo(
+                                R.string.device_owner_reenable_keyguard_button,
+                                createDeviceOwnerIntentWithBooleanParameter(
+                                        COMMAND_SET_KEYGUARD_DISABLED, false))}));
+
+        // 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)));
+
+        // 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 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);
+    }
+
+    private Intent createTearDownIntent() {
+        return new Intent(this, CommandReceiver.class)
+                .putExtra(EXTRA_COMMAND, COMMAND_TEAR_DOWN);
+    }
+
+    private Intent createDeviceOwnerIntentWithBooleanParameter(String command, boolean value) {
+        return new Intent(this, CommandReceiver.class)
+                .putExtra(EXTRA_COMMAND, command)
+                .putExtra(EXTRA_PARAMETER_1, value);
+    }
+
+    private Intent createSetUserRestrictionIntent(String restriction) {
+        return new Intent(this, CommandReceiver.class)
+                .putExtra(EXTRA_COMMAND, COMMAND_ADD_USER_RESTRICTION)
+                .putExtra(EXTRA_RESTRICTION, restriction);
+    }
+
+    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());
+        }
+    }
+}
+
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerTestActivity.java
deleted file mode 100644
index 7cb3825..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/DeviceOwnerTestActivity.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package com.android.cts.verifier.managedprovisioning;
-
-import android.app.AlertDialog;
-import android.app.admin.DevicePolicyManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.database.DataSetObserver;
-import android.os.Bundle;
-import android.provider.Settings;
-import android.util.Log;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.View.OnClickListener;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.cts.verifier.ArrayTestListAdapter;
-import com.android.cts.verifier.IntentDrivenTestActivity;
-import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
-import com.android.cts.verifier.IntentDrivenTestActivity.TestInfo;
-import com.android.cts.verifier.PassFailButtons;
-import com.android.cts.verifier.R;
-import com.android.cts.verifier.TestListAdapter.TestListItem;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Activity that lists all device owner provisioning tests.
- */
-public class DeviceOwnerTestActivity 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);
-
-    private static final String DEVICE_OWNER_NEGATIVE_TEST = "DEVICE_OWNER_PROVISIONING_NEGATIVE";
-    private static final TestInfo DEVICE_OWNER_NEGATIVE_TEST_INFO = new TestInfo(
-                    DEVICE_OWNER_NEGATIVE_TEST,
-                    R.string.device_owner_negative_test,
-                    R.string.device_owner_negative_test_info,
-                    new ButtonInfo(
-                            R.string.start_device_owner_provisioning_button,
-                            PROVISION_DEVICE_INTENT));
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.pass_fail_list);
-        setInfoResources(R.string.device_owner_provisioning_tests,
-                R.string.device_owner_provisioning_tests_info, 0);
-        setPassFailButtonClickListeners();
-
-        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
-        adapter.add(TestListItem.newCategory(this, R.string.device_owner_provisioning_category));
-
-        Intent startTestIntent = new Intent(this, IntentDrivenTestActivity.class)
-                    .putExtra(IntentDrivenTestActivity.EXTRA_ID,
-                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getTestId())
-                    .putExtra(IntentDrivenTestActivity.EXTRA_TITLE,
-                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getTitle())
-                    .putExtra(IntentDrivenTestActivity.EXTRA_INFO,
-                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getInfoText())
-                    .putExtra(IntentDrivenTestActivity.EXTRA_BUTTONS,
-                            DEVICE_OWNER_NEGATIVE_TEST_INFO.getButtons());
-
-
-        adapter.add(TestListItem.newTest(this, DEVICE_OWNER_NEGATIVE_TEST_INFO.getTitle(),
-                DEVICE_OWNER_NEGATIVE_TEST_INFO.getTestId(), startTestIntent, null));
-
-        adapter.registerDataSetObserver(new DataSetObserver() {
-            @Override
-            public void onChanged() {
-                updatePassButton();
-            }
-        });
-
-        setTestListAdapter(adapter);
-    }
-
-    /**
-     * Enable Pass Button when the all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-}
-
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/HandleIntentActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/HandleIntentActivity.java
new file mode 100644
index 0000000..88cf105
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/HandleIntentActivity.java
@@ -0,0 +1,21 @@
+/*
+ * 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.verifier.managedprovisioning;
+
+import android.app.Activity;
+
+public class HandleIntentActivity extends Activity { }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
new file mode 100644
index 0000000..21c7331
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/IntentFiltersTestHelper.java
@@ -0,0 +1,380 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.app.DownloadManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.media.audiofx.AudioEffect;
+import android.net.Uri;
+import android.nfc.cardemulation.CardEmulation;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.provider.AlarmClock;
+import android.provider.CalendarContract.Events;
+import android.provider.MediaStore;
+import android.provider.Settings;
+import android.speech.RecognizerIntent;
+import android.util.Log;
+import android.widget.Toast;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Helper class for testing if the required cross profile intent filters are set during the
+ * managed provisioning.
+ */
+public class IntentFiltersTestHelper {
+
+    private static final String TAG = "IntentFiltersTestHelper";
+
+    // These are the intents which can be forwarded to the managed profile.
+    private static final ArrayList<Intent> forwardedIntentsFromPrimary =
+            new ArrayList<>(Arrays.asList(
+                new Intent(Intent.ACTION_SEND).setType("*/*"),
+                new Intent(Intent.ACTION_SEND_MULTIPLE).setType("*/*")
+            ));
+
+    // These are the intents which can be forwarded to the primary profile.
+    private static final ArrayList<Intent> forwardedIntentsFromManaged =
+            new ArrayList<>(Arrays.asList(
+                new Intent(AlarmClock.ACTION_SET_ALARM),
+                new Intent(AlarmClock.ACTION_SET_TIMER),
+                new Intent(AlarmClock.ACTION_SHOW_ALARMS),
+                new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS),
+                new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS),
+                new Intent(Settings.ACTION_CAPTIONING_SETTINGS),
+                new Intent(Settings.ACTION_DATE_SETTINGS),
+                new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS),
+                new Intent(Settings.ACTION_DISPLAY_SETTINGS),
+                new Intent(Settings.ACTION_LOCALE_SETTINGS),
+                new Intent(Settings.ACTION_PRIVACY_SETTINGS),
+                new Intent(Settings.ACTION_SETTINGS),
+                new Intent(Settings.ACTION_WIRELESS_SETTINGS),
+                new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD),
+                new Intent("android.net.vpn.SETTINGS"),
+                new Intent("android.settings.ACCOUNT_SYNC_SETTINGS"),
+                new Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS),
+                new Intent("android.settings.LICENSE"),
+                new Intent("android.settings.NOTIFICATION_SETTINGS"),
+                new Intent("android.settings.USER_SETTINGS"),
+                new Intent("android.settings.ZEN_MODE_SETTINGS"),
+                new Intent("com.android.settings.ACCESSIBILITY_COLOR_SPACE_SETTINGS"),
+                new Intent("com.android.settings.TTS_SETTINGS"),
+                new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS),
+                new Intent(Settings.ACTION_SYNC_SETTINGS),
+                new Intent(Settings.ACTION_ADD_ACCOUNT),
+                new Intent(Intent.ACTION_GET_CONTENT).setType("*/*").addCategory(
+                        Intent.CATEGORY_OPENABLE),
+                new Intent(Intent.ACTION_OPEN_DOCUMENT).setType("*/*").addCategory(
+                        Intent.CATEGORY_OPENABLE),
+                new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS),
+                new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS),
+                new Intent(Settings.ACTION_APPLICATION_SETTINGS)
+            ));
+
+    // These are the intents which cannot be forwarded to the primary profile.
+    private static final ArrayList<Intent> notForwardedIntentsFromManaged =
+            new ArrayList<>(Arrays.asList(
+                new Intent(Intent.ACTION_INSERT).setData(
+                        Uri.parse("content://browser/bookmarks")),
+                new Intent(Intent.ACTION_VIEW).setData(
+                        Uri.parse("http://www.example.com")).addCategory(
+                        Intent.CATEGORY_BROWSABLE),
+                new Intent(Intent.ACTION_SENDTO).setData(
+                        Uri.parse("mailto:user@example.com")),
+                new Intent(Intent.ACTION_VIEW).setData(
+                        Uri.parse("mailto:user@example.com")).addCategory(
+                        Intent.CATEGORY_BROWSABLE),
+                new Intent(Intent.ACTION_VIEW).setData(
+                        Uri.parse("geo:0,0?q=BuckinghamPalace")),
+                new Intent(Intent.ACTION_VIEW).setData(
+                        Uri.parse("http://example.com/oceans.mp4")).setType("video/mp4"),
+                new Intent(Intent.ACTION_VIEW).setData(
+                        Uri.parse("http://www.example.com/horse.mp3")).setType("audio/*"),
+                new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH),
+                new Intent(Intent.ACTION_VIEW).setData(
+                        Uri.parse("market://details?id=com.android.chrome")).addCategory(
+                        Intent.CATEGORY_BROWSABLE),
+                new Intent(Intent.ACTION_WEB_SEARCH),
+                new Intent(Settings.ACTION_SEARCH_SETTINGS),
+                new Intent(Intent.ACTION_MANAGE_NETWORK_USAGE),
+                new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).setData(
+                        Uri.parse("package:com.android.chrome")),
+                new Intent(Intent.ACTION_INSERT).setData(Events.CONTENT_URI),
+                new Intent(DownloadManager.ACTION_VIEW_DOWNLOADS)
+            ));
+
+    // This flag specifies we are dealing with intents fired from the primary profile.
+    public static final int FLAG_INTENTS_FROM_PRIMARY = 1;
+    // This flag specifies we are dealing with intents fired from the managed profile.
+    public static final int FLAG_INTENTS_FROM_MANAGED = 2;
+
+    private Context mContext;
+
+    IntentFiltersTestHelper(Context context) {
+        mContext = context;
+
+        addIntentsThatDependOnDeviceFeatures();
+    }
+
+    private void addIntentsThatDependOnDeviceFeatures() {
+        PackageManager pm = mContext.getPackageManager();
+
+        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(
+                            Uri.parse("tel:123")),
+                    new Intent(Intent.ACTION_VIEW).setData(Uri.parse("tel:123")).addCategory(
+                            Intent.CATEGORY_BROWSABLE),
+                    new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS),
+                    new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS),
+                    new Intent(Intent.ACTION_SENDTO).setData(Uri.parse("sms:07700900100")),
+                    new Intent(Intent.ACTION_SENDTO).setData(Uri.parse("smsto:07700900100")),
+                    new Intent(Intent.ACTION_SENDTO).setData(Uri.parse("mms:07700900100")),
+                    new Intent(Intent.ACTION_SENDTO).setData(Uri.parse("mmsto:07700900100")),
+                    new Intent(Intent.ACTION_VIEW).setData(
+                            Uri.parse("sms:07700900100?body=Hello%20world")).addCategory(
+                            Intent.CATEGORY_BROWSABLE),
+                    new Intent(Intent.ACTION_VIEW).setData(
+                            Uri.parse("smsto:07700900100?body=Hello%20world")).addCategory(
+                            Intent.CATEGORY_BROWSABLE),
+                    new Intent(Intent.ACTION_VIEW).setData(
+                            Uri.parse("mms:07700900100?body=Hello%20world")).addCategory(
+                            Intent.CATEGORY_BROWSABLE),
+                    new Intent(Intent.ACTION_VIEW).setData(
+                            Uri.parse("mmsto:07700900100?body=Hello%20world")).addCategory(
+                            Intent.CATEGORY_BROWSABLE),
+                    new Intent(Settings.ACTION_APN_SETTINGS)));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) {
+            forwardedIntentsFromManaged.addAll(Arrays.asList(
+                    new Intent(Settings.ACTION_NFC_SETTINGS),
+                    new Intent(Settings.ACTION_NFCSHARING_SETTINGS),
+                    new Intent(Settings.ACTION_NFC_PAYMENT_SETTINGS)));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
+            forwardedIntentsFromManaged.add(
+                    new Intent(CardEmulation.ACTION_CHANGE_DEFAULT));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
+            forwardedIntentsFromManaged.addAll(Arrays.asList(
+                    new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
+                    new Intent(MediaStore.ACTION_VIDEO_CAPTURE),
+                    new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA),
+                    new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA),
+                    new Intent(MediaStore.ACTION_IMAGE_CAPTURE_SECURE),
+                    new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)));
+        }
+
+        final String state = Environment.getExternalStorageState();
+        if (Environment.MEDIA_MOUNTED.equals(state)) {
+            forwardedIntentsFromManaged.add(
+                    new Intent(Settings.ACTION_MEMORY_CARD_SETTINGS));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            forwardedIntentsFromManaged.addAll(Arrays.asList(
+                    new Intent(Settings.ACTION_WIFI_IP_SETTINGS),
+                    new Intent(Settings.ACTION_WIFI_SETTINGS)));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
+            forwardedIntentsFromManaged.addAll(Arrays.asList(
+                    new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION),
+                    new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_LOCATION)) {
+            forwardedIntentsFromManaged.add(
+                    new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
+            forwardedIntentsFromManaged.addAll(Arrays.asList(
+                    new Intent(Settings.ACTION_SOUND_SETTINGS),
+                    new Intent("android.settings.ACTION_OTHER_SOUND_SETTINGS")));
+            notForwardedIntentsFromManaged.add(
+                    new Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_HOME_SCREEN)) {
+            forwardedIntentsFromManaged.add(
+                    new Intent(Settings.ACTION_HOME_SETTINGS));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_INPUT_METHODS)) {
+            forwardedIntentsFromManaged.addAll(Arrays.asList(
+                    new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS),
+                    new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS)));
+            notForwardedIntentsFromManaged.add(
+                    new Intent("android.settings.SHOW_INPUT_METHOD_PICKER"));
+        }
+
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            forwardedIntentsFromManaged.add(
+                    new Intent(Settings.ACTION_DREAM_SETTINGS));
+        }
+
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+            forwardedIntentsFromManaged.add(
+                    new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS));
+        }
+
+        if (pm.hasSystemFeature(PackageManager.FEATURE_PRINTING)) {
+            notForwardedIntentsFromManaged.add(
+                    new Intent(Settings.ACTION_PRINT_SETTINGS));
+        }
+    }
+
+    public boolean checkCrossProfileIntentFilters(int flag) {
+        boolean crossProfileIntentFiltersSet;
+        if (flag == FLAG_INTENTS_FROM_PRIMARY) {
+            crossProfileIntentFiltersSet = checkForIntentsFromPrimary();
+        } else {
+            crossProfileIntentFiltersSet = checkForIntentsFromManaged();
+        }
+        return crossProfileIntentFiltersSet;
+    }
+
+    /**
+     * Checks if required cross profile intent filters are set for the intents fired from the
+     * primary profile.
+     */
+    private boolean checkForIntentsFromPrimary() {
+        // Get the class name of the intentForwarderActivity in the primary profile by firing an
+        // intent which we know will be forwarded from primary profile to managed profile.
+        ActivityInfo forwarderActivityInfo =
+                getForwarderActivityInfo(ByodHelperActivity.ACTION_QUERY_PROFILE_OWNER);
+        if (forwarderActivityInfo == null) {
+            return false;
+        }
+
+        // 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;
+    }
+
+    /**
+     * Checks if required cross profile intent filters are set for the intents fired from the
+     * managed profile.
+     */
+    private boolean checkForIntentsFromManaged() {
+        // Get the class name of the intentForwarderActivity in the managed profile by firing an
+        // intent which we know will be forwarded from managed profile to primary profile.
+        ActivityInfo forwarderActivityInfo =
+                getForwarderActivityInfo(ByodHelperActivity.ACTION_PROFILE_OWNER_STATUS);
+        if (forwarderActivityInfo == null) {
+            return false;
+        }
+
+        // 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;
+        }
+
+        // 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;
+    }
+
+    /**
+     * Checks if the intentForwarderActivity can handle the intent passed.
+     */
+    private boolean canForwarderActivityHandleIntent(Intent intent,
+            ActivityInfo forwarderActivityInfo) {
+        // Get all the activities which can handle the intent.
+        List<ResolveInfo> resolveInfoList =
+                mContext.getPackageManager().queryIntentActivities(intent,
+                        PackageManager.MATCH_DEFAULT_ONLY);
+        // Check if intentForwarderActivity is part of the list.
+        for (ResolveInfo resolveInfo : resolveInfoList) {
+            if (forwarderActivityInfo.packageName.equals(resolveInfo.activityInfo.packageName)
+                    && forwarderActivityInfo.name.equals(resolveInfo.activityInfo.name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the class name of the intentForwarderActivity.
+     */
+    private ActivityInfo getForwarderActivityInfo(String action) {
+        Intent intent = new Intent(action);
+        List<ResolveInfo> resolveInfoList =
+                mContext.getPackageManager().queryIntentActivities(intent,
+                        PackageManager.MATCH_DEFAULT_ONLY);
+        if (resolveInfoList.isEmpty() || resolveInfoList.size() > 1) {
+            Log.d(TAG, "There should be exactly one activity IntentForwarder which " +
+                    "handles the intent " + intent);
+            return null;
+        }
+        return resolveInfoList.get(0).activityInfo;
+    }
+
+    /**
+     * 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.
+     */
+    private Intent checkForIntentsNotHandled(ArrayList<Intent> intentList,
+            ActivityInfo expectedForwarderActivityInfo, boolean canResolve) {
+        for (Intent intent : intentList) {
+            if (canForwarderActivityHandleIntent(intent,
+                    expectedForwarderActivityInfo) != canResolve) {
+                return intent;
+            }
+        }
+        return null;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
new file mode 100644
index 0000000..1b4edcf
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/KeyguardDisabledFeaturesActivity.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Toast;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.DialogTestListActivity;
+import com.android.cts.verifier.R;
+
+public class KeyguardDisabledFeaturesActivity extends DialogTestListActivity {
+
+    protected DevicePolicyManager mDpm;
+
+    public KeyguardDisabledFeaturesActivity() {
+        super(R.layout.provisioning_byod,
+                R.string.provisioning_byod_keyguard_disabled_features,
+                R.string.provisioning_byod_keyguard_disabled_features_info,
+                R.string.provisioning_byod_keyguard_disabled_features_instruction);
+    }
+
+    protected int getKeyguardDisabledFeatures() {
+        return DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS
+                | DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT
+                | DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+
+        mPrepareTestButton.setText(
+                R.string.provisioning_byod_keyguard_disabled_features_prepare_button);
+        mPrepareTestButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    if (!mDpm.isAdminActive(getAdminComponent())) {
+                        Toast.makeText(KeyguardDisabledFeaturesActivity.this,
+                                R.string.provisioning_byod_keyguard_disabled_features_not_admin,
+                                Toast.LENGTH_SHORT).show();
+                        return;
+                    }
+                    setKeyguardDisabledFeatures();
+                    mDpm.resetPassword("testpassword", 0);
+                }
+            });
+    }
+    
+    protected ComponentName getAdminComponent() { 
+        return DeviceAdminTestReceiver.getReceiverComponentName();
+    }
+    
+    protected String getTestIdPrefix() {
+        return "BYOD_";
+    }
+
+    @Override
+    public void finish() {
+        // Pass and fail buttons are known to call finish() when clicked, and this is when we want to
+        // clear the password.
+        final ComponentName adminComponent = getAdminComponent();
+        if (mDpm.isAdminActive(adminComponent)) {
+            mDpm.resetPassword(null, 0);
+            mDpm.removeActiveAdmin(adminComponent);
+        }
+        super.finish();
+    }
+
+    protected void setKeyguardDisabledFeatures() {
+        int flags = getKeyguardDisabledFeatures();
+        Intent setKeyguardDisabledFeaturesIntent = new Intent(
+                ByodHelperActivity.ACTION_KEYGUARD_DISABLED_FEATURES)
+                        .putExtra(ByodHelperActivity.EXTRA_PARAMETER_1, flags);
+        startActivity(setKeyguardDisabledFeaturesIntent);
+    }
+    
+    protected void setupDisableTrustAgentsTest(ArrayTestListAdapter adapter) {
+        adapter.add(new DialogTestListItem(this, R.string.provisioning_byod_disable_trust_agents,
+                getTestIdPrefix() + "DisableTrustAgentsTest",
+                R.string.provisioning_byod_disable_trust_agents_instruction,
+                new Intent(Settings.ACTION_SECURITY_SETTINGS)));
+    }
+    
+    protected void setupDisableUnredactedWorkNotification(ArrayTestListAdapter adapter) {
+        adapter.add(new DialogTestListItemWithIcon(this,
+                R.string.provisioning_byod_disable_unredacted_notifications,
+                getTestIdPrefix() + "DisableUnredactedNotifications",
+                R.string.provisioning_byod_disable_unredacted_notifications_instruction,
+                new Intent(ByodHelperActivity.ACTION_NOTIFICATION_ON_LOCKSCREEN),
+                R.drawable.ic_corp_icon));
+    }
+    
+    protected void setupFingerprintTests(ArrayTestListAdapter adapter) {
+        FingerprintManager fpm = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);
+        if (fpm.isHardwareDetected()) {
+            adapter.add(new DialogTestListItem(this,
+                    R.string.provisioning_byod_fingerprint_disabled_in_settings,
+                    getTestIdPrefix() + "FingerprintDisabledInSettings",
+                    R.string.provisioning_byod_fingerprint_disabled_in_settings_instruction,
+                    new Intent(Settings.ACTION_SECURITY_SETTINGS)));
+            adapter.add(new DialogTestListItem(this, R.string.provisioning_byod_disable_fingerprint,
+                    getTestIdPrefix() + "DisableFingerprint",
+                    R.string.provisioning_byod_disable_fingerprint_instruction,
+                    ByodHelperActivity.createLockIntent()));
+        }
+    }
+
+    @Override
+    protected void setupTests(ArrayTestListAdapter adapter) {
+        setupDisableTrustAgentsTest(adapter);
+        setupDisableUnredactedWorkNotification(adapter);
+        setupFingerprintTests(adapter);
+        
+    }
+
+    @Override
+    protected void clearRemainingState(final DialogTestListItem test) {
+        super.clearRemainingState(test);
+        if (ByodHelperActivity.ACTION_NOTIFICATION_ON_LOCKSCREEN.equals(
+                test.getManualTestIntent().getAction())) {
+            try {
+                startActivity(new Intent(
+                        ByodHelperActivity.ACTION_CLEAR_NOTIFICATION));
+            } catch (ActivityNotFoundException e) {
+                // User shouldn't run this test before work profile is set up.
+            }
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/NfcTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/NfcTestActivity.java
index d0916a8..2f7619c 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/NfcTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/NfcTestActivity.java
@@ -82,6 +82,12 @@
         mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
         mNfcAdapter.setBeamPushUris(uris, this);
 
+        findViewById(R.id.manual_beam_button).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                mNfcAdapter.invokeBeam(NfcTestActivity.this);
+            }
+        });
         findViewById(R.id.intent_share_button).setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View view) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java
new file mode 100644
index 0000000..ea7e801
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/PermissionLockdownTestActivity.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.ActivityNotFoundException;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.RadioGroup;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+public class PermissionLockdownTestActivity extends PassFailButtons.Activity
+        implements RadioGroup.OnCheckedChangeListener {
+    private static final String PERMISSION_APP_PACKAGE = "com.android.cts.permissionapp";
+
+    // Alias used for starting the activity from ByodFlowTestActivity (Managed profile tests).
+    static final String ACTIVITY_ALIAS
+            = "com.android.cts.verifier.managedprovisioning" +
+                    ".ManagedProfilePermissionLockdownTestActivity";
+
+    private static final String MANAGED_PROVISIONING_ACTION_PREFIX
+            = "com.android.cts.verifier.managedprovisioning.action.";
+    // Indicates that activity is started for device owner case.
+    static final String ACTION_CHECK_PERMISSION_LOCKDOWN
+            = MANAGED_PROVISIONING_ACTION_PREFIX + "CHECK_PERMISSION_LOCKDOWN";
+    // Indicates that activity is started for profile owner case.
+    static final String ACTION_MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN
+            = MANAGED_PROVISIONING_ACTION_PREFIX + "MANAGED_PROFILE_CHECK_PERMISSION_LOCKDOWN";
+
+    // Permission grant states will be set on this permission.
+    private static final String CONTACTS_PERMISSION = android.Manifest.permission.READ_CONTACTS;
+
+    private boolean mDeviceOwnerTest;
+    private DevicePolicyManager mDevicePolicyManager;
+    private ComponentName mAdmin;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.permission_lockdown);
+
+        mDevicePolicyManager =
+                (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mAdmin = DeviceAdminTestReceiver.getReceiverComponentName();
+
+        mDeviceOwnerTest =
+                ACTION_CHECK_PERMISSION_LOCKDOWN.equals(getIntent().getAction()) ? true : false;
+        // Return immediately if we are neither profile nor device owner.
+        if (!isProfileOrDeviceOwner()) {
+            setTestResultAndFinish(false);
+            return;
+        }
+
+        buildLayout();
+    }
+
+    private void buildLayout() {
+        PackageManager packageManager = getPackageManager();
+        ApplicationInfo applicationInfo = null;
+        try {
+            // We need to make sure that the CtsPermissionApp is installed on the device or
+            // work profile.
+            applicationInfo = packageManager.getApplicationInfo(
+                    PERMISSION_APP_PACKAGE, 0 /* flags */);
+        } catch (PackageManager.NameNotFoundException e) {
+            showToast(getString(R.string.package_not_found, PERMISSION_APP_PACKAGE));
+            setTestResultAndFinish(false);
+            return;
+        }
+
+        ImageView packageIconImageView = (ImageView) findViewById(R.id.package_icon);
+        packageIconImageView.setImageDrawable(packageManager.getApplicationIcon(applicationInfo));
+        TextView packageNameTextView = (TextView) findViewById(R.id.package_name);
+        packageNameTextView.setText(packageManager.getApplicationLabel(applicationInfo));
+
+        TextView permissionNameTextView = (TextView) findViewById(R.id.permission_name);
+        permissionNameTextView.setText(CONTACTS_PERMISSION);
+
+        // Get the current permission grant state for initializing the RadioGroup.
+        int currentPermissionState = mDevicePolicyManager.getPermissionGrantState(mAdmin,
+                    PERMISSION_APP_PACKAGE, CONTACTS_PERMISSION);
+        RadioGroup permissionRadioGroup = (RadioGroup) findViewById(R.id.permission_group);
+        switch (currentPermissionState) {
+            case DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED: {
+                permissionRadioGroup.check(R.id.permission_allow);
+            } break;
+            case DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT: {
+                permissionRadioGroup.check(R.id.permission_default);
+            } break;
+            case  DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED: {
+                permissionRadioGroup.check(R.id.permission_deny);
+            } break;
+        }
+        permissionRadioGroup.setOnCheckedChangeListener(this);
+
+        addFinishOrPassFailButtons();
+    }
+
+    private void addFinishOrPassFailButtons() {
+        // In case of device owner, we include the pass-fail buttons where as in case of profile
+        // owner, we add a finish button.
+        ViewGroup parentView = (ViewGroup) findViewById(R.id.permission_lockdown_activity);
+        if (mDeviceOwnerTest) {
+            parentView.addView(
+                    getLayoutInflater().inflate(R.layout.pass_fail_buttons, parentView, false));
+            setInfoResources(R.string.device_profile_owner_permission_lockdown_test,
+                    R.string.device_owner_permission_lockdown_test_info, 0);
+            setPassFailButtonClickListeners();
+        } else {
+            Button finishButton = new Button(this);
+            finishButton.setText(R.string.finish_button_label);
+            finishButton.setOnClickListener(new View.OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    PermissionLockdownTestActivity.this.setTestResultAndFinish(false);
+                }
+            });
+            parentView.addView(finishButton);
+        }
+    }
+
+    // Dispatches an intent to open the Settings screen for CtsPermissionApp.
+    public void openSettings(View v) {
+        Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+                .setData(Uri.fromParts("package", PERMISSION_APP_PACKAGE, null))
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            startActivity(intent);
+        } catch (ActivityNotFoundException e) {
+            showToast(getString(R.string.activity_not_found, intent));
+        }
+    }
+
+    @Override
+    public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
+        int permissionGrantState = -1;
+        switch (checkedId) {
+            case R.id.permission_allow: {
+                permissionGrantState = DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED;
+            } break;
+            case R.id.permission_default: {
+                permissionGrantState = DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT;
+            } break;
+            case R.id.permission_deny: {
+                permissionGrantState = DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED;
+            } break;
+        }
+        mDevicePolicyManager.setPermissionGrantState(mAdmin, PERMISSION_APP_PACKAGE,
+                CONTACTS_PERMISSION, permissionGrantState);
+    }
+
+    private boolean isProfileOrDeviceOwner() {
+        String adminPackage = mAdmin.getPackageName();
+        if (mDeviceOwnerTest && !mDevicePolicyManager.isDeviceOwnerApp(adminPackage)) {
+            showToast(getString(R.string.not_device_owner, adminPackage));
+            return false;
+        } else if (!mDeviceOwnerTest && !mDevicePolicyManager.isProfileOwnerApp(adminPackage)) {
+            showToast(getString(R.string.not_profile_owner, adminPackage));
+            return false;
+        }
+        return true;
+    }
+
+    private void showToast(String toast) {
+        Toast.makeText(this, toast, Toast.LENGTH_LONG).show();
+    }
+}
\ No newline at end of file
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/VpnTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/VpnTestActivity.java
new file mode 100644
index 0000000..49c0c20
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/VpnTestActivity.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.cts.verifier.managedprovisioning;
+
+import android.app.AlertDialog;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.VpnService;
+import android.net.VpnService.Builder;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.util.Log;
+import android.widget.TextView;
+import android.net.VpnService;
+import android.os.ParcelFileDescriptor;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import java.io.IOException;
+
+/**
+ * Activity to test Vpn configuration
+ */
+public class VpnTestActivity extends PassFailButtons.Activity {
+
+    public static final String ACTION_VPN = "com.android.cts.verifier.managedprovisioning.VPN";
+
+    public static class MyTestVpnService extends VpnService {
+        /*
+         * MyVpnTestService is just a stub. This class exists because the framework needs a class
+         * inside the app to refer back to, just using VpnService itself won't work.
+         */
+    }
+
+    private ParcelFileDescriptor descriptor = null;
+    private ComponentName mAdminReceiverComponent;
+    private DevicePolicyManager mDevicePolicyManager;
+    private UserManager mUserManager;
+    private static final String TAG = "DeviceOwnerPositiveTestActivity";
+    private static final int REQUEST_VPN_CODE = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.vpn_test);
+        setPassFailButtonClickListeners();
+        mAdminReceiverComponent = new ComponentName(this, DeviceAdminTestReceiver.class.getName());
+        mDevicePolicyManager = (DevicePolicyManager) getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+        mDevicePolicyManager.addUserRestriction(mAdminReceiverComponent,
+                UserManager.DISALLOW_CONFIG_VPN);
+        mUserManager = (UserManager) getSystemService(Context.USER_SERVICE);
+        testVpnEstablishFails();
+    }
+
+    @Override
+    public void finish() {
+        mDevicePolicyManager.clearUserRestriction(mAdminReceiverComponent,
+                UserManager.DISALLOW_CONFIG_VPN);
+        super.finish();
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int result, Intent data) {
+        if (requestCode == REQUEST_VPN_CODE && result == RESULT_OK) {
+            establishVpn();
+        } else {
+            // vpn connection canceled by user
+            Log.w(TAG, "Test failed, canceled by user");
+            populateInfo(R.string.device_owner_vpn_connection_canceled);
+        }
+    }
+
+    public void testVpnEstablishFails() {
+        Intent newIntent = VpnService.prepare(this);
+        if (newIntent != null) {
+            startActivityForResult(newIntent, REQUEST_VPN_CODE);
+        } else {
+            establishVpn();
+        }
+    }
+
+    public void establishVpn() {
+        MyTestVpnService service = new MyTestVpnService();
+        descriptor = service.new Builder().addAddress("8.8.8.8", 30).establish();
+        if (descriptor == null) {
+            // vpn connection not established, as expected, test case succeeds
+            Log.i(TAG, "Test succeeded: descriptor is null");
+            populateInfo(R.string.device_owner_no_vpn_connection);
+            return;
+        }
+        // vpn connection established, not expected, test case fails
+        Log.w(TAG, "vpn connection established, not expected, test case fails");
+        try {
+            descriptor.close();
+            populateInfo(R.string.device_owner_vpn_connection);
+        } catch (IOException e) {
+            Log.i(TAG, "Closing vpn connection failed. Caught exception: ", e);
+            populateInfo(R.string.device_owner_vpn_connection_close_failed);
+        }
+    }
+
+    private void populateInfo(int messageId) {
+        TextView vpnInfoTextView = (TextView) findViewById(R.id.device_owner_vpn_info);
+        vpnInfoTextView.setText(getString(messageId));
+    }
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
new file mode 100644
index 0000000..77f36b6
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WifiLockdownTestActivity.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.AlertDialog;
+import android.content.Intent;
+import android.database.DataSetObserver;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.EditText;
+import android.widget.RadioGroup;
+
+import com.android.cts.verifier.ArrayTestListAdapter;
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.IntentDrivenTestActivity.ButtonInfo;
+
+import com.android.compatibility.common.util.WifiConfigCreator;
+import static com.android.compatibility.common.util.WifiConfigCreator.SECURITY_TYPE_NONE;
+import static com.android.compatibility.common.util.WifiConfigCreator.SECURITY_TYPE_WPA;
+import static com.android.compatibility.common.util.WifiConfigCreator.SECURITY_TYPE_WEP;
+
+/**
+ * Activity to test WiFi configuration lockdown functionality. A locked down WiFi config
+ * must not be editable/forgettable in Settings.
+ */
+public class WifiLockdownTestActivity extends PassFailButtons.TestListActivity {
+    private static final String TAG = "WifiLockdownTestActivity";
+
+    private static final int NONE = R.id.device_owner_keymgmnt_none;
+    private static final int WPA = R.id.device_owner_keymgmnt_wpa;
+    private static final int WEP = R.id.device_owner_keymgmnt_wep;
+
+    private static final String CONFIG_MODIFIABLE_WHEN_UNLOCKED_TEST_ID = "UNLOCKED_MODIFICATION";
+    private static final String CONFIG_NOT_MODIFIABLE_WHEN_LOCKED_TEST_ID = "LOCKED_MODIFICATION";
+    private static final String CONFIG_CONNECTABLE_WHEN_LOCKED_TEST_ID = "LOCKED_CONNECT";
+    private static final String CONFIG_REMOVABLE_WHEN_UNLOCKED_TEST_ID = "UNLOCKED_REMOVE";
+
+    private WifiConfigCreator mConfigCreator;
+    private ButtonInfo[] mSwitchLockdownOffButtonInfos;
+    private ButtonInfo[] mSwitchLockdownOnButtonInfos;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mConfigCreator = new WifiConfigCreator(this);
+        setContentView(R.layout.wifi_lockdown);
+        setInfoResources(R.string.device_owner_wifi_lockdown_test,
+                R.string.device_owner_wifi_lockdown_info, 0);
+        setPassFailButtonClickListeners();
+
+        final ArrayTestListAdapter adapter = new ArrayTestListAdapter(this);
+
+        final ButtonInfo goToWifiSettings = new ButtonInfo(
+                R.string.wifi_lockdown_go_settings_wifi_button,
+                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,
+                                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN)
+                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_PARAMETER_1, "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,
+                                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN)
+                        .putExtra(DeviceOwnerPositiveTestActivity.EXTRA_PARAMETER_1, "1"
+                )), goToWifiSettings };
+
+        addTestsToAdapter(adapter);
+
+        adapter.registerDataSetObserver(new DataSetObserver() {
+            @Override
+            public void onChanged() {
+                updatePassButton();
+            }
+        });
+
+        setTestListAdapter(adapter);
+
+        View createConfigButton = findViewById(R.id.create_wifi_config_button);
+        createConfigButton .setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                EditText ssidEditor = (EditText) findViewById(R.id.device_owner_wifi_ssid);
+                RadioGroup authMethods = (RadioGroup) findViewById(
+                        R.id.device_owner_keyManagementMethods);
+                int checkedRadioId = authMethods.getCheckedRadioButtonId();
+                if (checkedRadioId == -1) {
+                    checkedRadioId = NONE;
+                }
+                int netId;
+                try {
+                    netId = mConfigCreator.addNetwork(ssidEditor.getText().toString(), false,
+                            convertKeyManagement(checkedRadioId), "defaultpassword");
+                } catch (InterruptedException e) {
+                    netId = -1;
+                }
+                if (netId == -1) {
+                    new AlertDialog.Builder(
+                            WifiLockdownTestActivity.this)
+                            .setIcon(android.R.drawable.ic_dialog_info)
+                            .setTitle(R.string.wifi_lockdown_add_network_failed_dialog_title)
+                            .setMessage(R.string.wifi_lockdown_add_network_failed_dialog_text)
+                            .setPositiveButton(android.R.string.ok, null)
+                            .show();
+                }
+            }
+        });
+    }
+
+    private void addTestsToAdapter(final ArrayTestListAdapter adapter) {
+        adapter.add(DeviceOwnerPositiveTestActivity.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,
+                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,
+                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,
+                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,
+                mSwitchLockdownOffButtonInfos));
+    }
+
+    private int convertKeyManagement(int radioButtonId) {
+        switch (radioButtonId) {
+            case NONE: {
+                return SECURITY_TYPE_NONE;
+            }
+            case WPA: {
+                return SECURITY_TYPE_WPA;
+            }
+            case WEP: {
+                return SECURITY_TYPE_WEP;
+            }
+        }
+        return SECURITY_TYPE_NONE;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkNotificationTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkNotificationTestActivity.java
deleted file mode 100644
index c85ccf5..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkNotificationTestActivity.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.verifier.managedprovisioning;
-
-import android.app.Activity;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.content.Context;
-import android.os.Bundle;
-
-import com.android.cts.verifier.R;
-
-/**
- * Test activity used to generate a notification.
- */
-public class WorkNotificationTestActivity extends Activity {
-    public static final String ACTION_WORK_NOTIFICATION =
-            "com.android.cts.verifier.managedprovisioning.WORK_NOTIFICATION";
-    public static final String ACTION_CLEAR_WORK_NOTIFICATION =
-            "com.android.cts.verifier.managedprovisioning.CLEAR_WORK_NOTIFICATION";
-    private static final int NOTIFICATION_ID = 7;
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        final String action = getIntent().getAction();
-        final NotificationManager notificationManager = (NotificationManager)
-                getSystemService(Context.NOTIFICATION_SERVICE);
-        if (ACTION_WORK_NOTIFICATION.equals(action)) {
-            final Notification notification = new Notification.Builder(this)
-                .setSmallIcon(R.drawable.icon)
-                .setContentTitle(getString(R.string.provisioning_byod_work_notification_title))
-                .setVisibility(Notification.VISIBILITY_PUBLIC)
-                .setAutoCancel(true)
-                .build();
-            notificationManager.notify(NOTIFICATION_ID, notification);
-        } else if (ACTION_CLEAR_WORK_NOTIFICATION.equals(action)) {
-            notificationManager.cancel(NOTIFICATION_ID);
-        }
-        finish();
-    }
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkStatusTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkStatusTestActivity.java
new file mode 100644
index 0000000..ee9aa44
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/managedprovisioning/WorkStatusTestActivity.java
@@ -0,0 +1,61 @@
+/*
+ * 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.verifier.managedprovisioning;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+
+import com.android.cts.verifier.R;
+
+/**
+ * Test activity for work status tests.
+ */
+public class WorkStatusTestActivity extends Activity {
+    public static final String ACTION_WORK_STATUS_ICON
+            = "com.android.cts.verifier.managedprovisioning.WORK_STATUS_ICON";
+    public static final String ACTION_WORK_STATUS_TOAST
+            = "com.android.cts.verifier.managedprovisioning.WORK_STATUS_TOAST";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.provisioning_cross_profile);
+
+        findViewById(R.id.button_finish).setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                WorkStatusTestActivity.this.finish();
+            }
+        });
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        String action = getIntent().getAction();
+        TextView textView = (TextView) findViewById(R.id.text);
+        if (ACTION_WORK_STATUS_ICON.equals(action)) {
+            textView.setText(R.string.provisioning_byod_work_status_icon_activity);
+        } else if (ACTION_WORK_STATUS_TOAST.equals(action)) {
+            textView.setText(R.string.provisioning_byod_work_status_toast_activity);
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/net/ConnectivityScreenOffTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/net/ConnectivityScreenOffTestActivity.java
new file mode 100644
index 0000000..e529b67
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/net/ConnectivityScreenOffTestActivity.java
@@ -0,0 +1,632 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.net;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Typeface;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.os.BatteryManager;
+import android.os.Bundle;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowManager.LayoutParams;
+import android.widget.Button;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.HttpURLConnection;
+import java.net.UnknownHostException;
+import java.net.URL;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.Random;
+
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
+
+/**
+ * A CTS Verifier test case for testing IPv6 network connectivity while the screen is off.
+ *
+ * This tests that Wi-Fi implementations are compliant with section 7.4.5
+ * ("Minimum Network Capability") of the CDD. Specifically, it requires that: "unicast IPv6
+ * packets sent to the device MUST NOT be dropped, even when the screen is not in an active
+ * state."
+ *
+ * The verification is attempted as follows:
+ *
+ *     [1] The device must have Wi-Fi capability.
+ *     [2] The device must join an IPv6-capable network (basic IPv6 connectivity to an
+ *         Internet resource is tested).
+ *     [3] If the device has a battery, the device must be disconnected from any power source.
+ *     [4] The screen is put to sleep.
+ *     [5] After two minutes, another IPv6 connectivity test is performed.
+ */
+public class ConnectivityScreenOffTestActivity extends PassFailButtons.Activity {
+
+    private static final String TAG = ConnectivityScreenOffTestActivity.class.getSimpleName();
+    private static final String V6CONN_URL = "https://ipv6.google.com/generate_204";
+    private static final String V6ADDR_URL = "https://google-ipv6test.appspot.com/ip.js?fmt=text";
+
+    private static final long MIN_SCREEN_OFF_MS = 1000 * (30 + (long) new Random().nextInt(51));
+    private static final long MIN_POWER_DISCONNECT_MS = MIN_SCREEN_OFF_MS;
+
+    private final Object mLock;
+    private final AppState mState;
+    private BackgroundTestingThread mTestingThread;
+
+    private final ScreenAndPlugStateReceiver mReceiver;
+    private final IntentFilter mIntentFilter;
+    private boolean mHasBattery;
+
+    private PowerManager mPowerManager;
+    private PowerManager.WakeLock mWakeLock;
+    private ConnectivityManager mCM;
+    private NetworkCallback mNetworkCallback;
+
+    private ScrollView mScrollView;
+    private TextView mTextView;
+    private long mUserActivityTimeout = -1;
+
+
+    public ConnectivityScreenOffTestActivity() {
+        mLock = new Object();
+        mState = new AppState();
+
+        mReceiver = new ScreenAndPlugStateReceiver();
+
+        mIntentFilter = new IntentFilter();
+        mIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
+        mIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+        mIntentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
+        mIntentFilter.addAction(Intent.ACTION_POWER_DISCONNECTED);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        configureFromSystemServices();
+        setupUserInterface();
+    }
+
+    @Override
+    protected void onDestroy() {
+        clearNetworkCallback();
+        stopAnyExistingTestingThread();
+        unregisterReceiver(mReceiver);
+        mWakeLock.release();
+        super.onDestroy();
+    }
+
+    private void setupUserInterface() {
+        setContentView(R.layout.network_screen_off);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+        setInfoResources(
+                R.string.network_screen_off_test,
+                R.string.network_screen_off_test_instructions,
+                -1);
+
+        mScrollView = (ScrollView) findViewById(R.id.scroll);
+        mTextView = (TextView) findViewById(R.id.text);
+        mTextView.setTypeface(Typeface.MONOSPACE);
+        mTextView.setTextSize(14.0f);
+
+        // Get the start button and attach the listener.
+        getStartButton().setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                getStartButton().setEnabled(false);
+                startTest();
+            }
+        });
+    }
+
+    private void configureFromSystemServices() {
+        final Intent batteryInfo = registerReceiver(
+                null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
+
+        // Whether or not this device (currently) has a battery.
+        mHasBattery = batteryInfo.getBooleanExtra(BatteryManager.EXTRA_PRESENT, true);
+
+        // Check if the device is already on battery power.
+        if (mHasBattery) {
+            BatteryManager battMgr = (BatteryManager) getSystemService(Context.BATTERY_SERVICE);
+            if (!battMgr.isCharging()) {
+                mState.setPowerDisconnected();
+            }
+        }
+
+        mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
+        mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+        mWakeLock.acquire();
+
+        registerReceiver(mReceiver, mIntentFilter);
+
+        mCM = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    private void clearNetworkCallback() {
+        if (mNetworkCallback != null) {
+            mCM.unregisterNetworkCallback(mNetworkCallback);
+            mNetworkCallback = null;
+        }
+    }
+
+    private void stopAnyExistingTestingThread() {
+        synchronized (mLock) {
+            if (mTestingThread != null) {
+                // The testing thread will observe this and exit on its own (eventually).
+                mTestingThread.setStopped();
+            }
+        }
+    }
+
+    private void setTestPassing() {
+        logAndUpdate("Test PASSED!");
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                getPassButton().setEnabled(true);
+            }
+        });
+    }
+
+    private void logAndUpdate(final String msg) {
+        Log.d(TAG, msg);
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mTextView.append(msg);
+                mTextView.append("\n");
+                mScrollView.fullScroll(View.FOCUS_DOWN);  // Scroll to bottom
+            }
+        });
+    }
+
+    private Button getStartButton() {
+        return (Button) findViewById(R.id.start_btn);
+    }
+
+    private void setUserActivityTimeout(long timeout) {
+        final LayoutParams params = getWindow().getAttributes();
+
+        try {
+            final Field field = params.getClass().getField("userActivityTimeout");
+            // Save the original value.
+            if (mUserActivityTimeout < 0) {
+                mUserActivityTimeout = field.getLong(params);
+                Log.d(TAG, "saving userActivityTimeout: " + mUserActivityTimeout);
+            }
+            field.setLong(params, 1);
+        } catch (NoSuchFieldException e) {
+            Log.d(TAG, "No luck with userActivityTimeout: ", e);
+            return;
+        } catch (IllegalAccessException e) {
+            Log.d(TAG, "No luck with userActivityTimeout: ", e);
+            return;
+        }
+
+        getWindow().setAttributes(params);
+    }
+
+    private void tryScreenOff() {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                setUserActivityTimeout(1);
+            }
+        });
+    }
+
+    private void tryScreenOn() {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                PowerManager.WakeLock screenOnLock = mPowerManager.newWakeLock(
+                        PowerManager.FULL_WAKE_LOCK
+                        | PowerManager.ACQUIRE_CAUSES_WAKEUP
+                        | PowerManager.ON_AFTER_RELEASE, TAG + ":screenOn");
+                screenOnLock.acquire();
+                setUserActivityTimeout((mUserActivityTimeout > 0)
+                        ? mUserActivityTimeout
+                        : 30);  // No good value to restore, use 30 seconds.
+                screenOnLock.release();
+            }
+        });
+    }
+
+    private void startTest() {
+        clearNetworkCallback();
+        stopAnyExistingTestingThread();
+        mTextView.setText("");
+        logAndUpdate("Starting test...");
+
+        mCM.registerNetworkCallback(
+                new NetworkRequest.Builder()
+                        .addTransportType(TRANSPORT_WIFI)
+                        .addCapability(NET_CAPABILITY_INTERNET)
+                        .build(),
+                createNetworkCallback());
+
+        new BackgroundTestingThread().start();
+    }
+
+    /**
+     * TODO(ek): Evaluate reworking the code roughly as follows:
+     *     - Move all the shared state here, including mHasBattery (and mTestingThread).
+     *     - Move from synchronizing on mLock to synchronizing on this since the
+     *       AppState object is final, and delete mLock.
+     *     - Synchronize the methods below, and add some required new methods.
+     *     - Remove copying entire state into the BackgroundTestingThread.
+     */
+    class AppState {
+        Network mNetwork;
+        LinkProperties mLinkProperties;
+        long mScreenOffTime;
+        long mPowerDisconnectTime;
+        boolean mPassedInitialIPv6Check;
+
+        void setNetwork(Network network) {
+            mNetwork = network;
+            mLinkProperties = null;
+            mPassedInitialIPv6Check = false;
+        }
+
+        void setScreenOn() { mScreenOffTime = 0; }
+        void setScreenOff() { mScreenOffTime = SystemClock.elapsedRealtime(); }
+        boolean validScreenStateForTesting() { return (mScreenOffTime > 0); }
+
+        void setPowerConnected() { mPowerDisconnectTime = 0; }
+        void setPowerDisconnected() { mPowerDisconnectTime = SystemClock.elapsedRealtime(); }
+        boolean validPowerStateForTesting() { return !mHasBattery || (mPowerDisconnectTime > 0); }
+    }
+
+    class ScreenAndPlugStateReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_SCREEN_ON.equals(action)) {
+                Log.d(TAG, "got ACTION_SCREEN_ON");
+                synchronized (mLock) {
+                    mState.setScreenOn();
+                    mLock.notify();
+                }
+            } else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
+                Log.d(TAG, "got ACTION_SCREEN_OFF");
+                synchronized (mLock) {
+                    mState.setScreenOff();
+                    mLock.notify();
+                }
+            } else if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
+                Log.d(TAG, "got ACTION_POWER_CONNECTED");
+                synchronized (mLock) {
+                    mState.setPowerConnected();
+                    mLock.notify();
+                }
+            } else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
+                Log.d(TAG, "got ACTION_POWER_DISCONNECTED");
+                synchronized (mLock) {
+                    mState.setPowerDisconnected();
+                    mLock.notify();
+                }
+            }
+        }
+    }
+
+    private NetworkCallback createNetworkCallback() {
+        return new NetworkCallback() {
+            @Override
+            public void onAvailable(Network network) {
+                synchronized (mLock) {
+                    mState.setNetwork(network);
+                    mLock.notify();
+                }
+            }
+
+            @Override
+            public void onLost(Network network) {
+                synchronized (mLock) {
+                    if (network.equals(mState.mNetwork)) {
+                        mState.setNetwork(null);
+                        mLock.notify();
+                    }
+                }
+            }
+
+            @Override
+            public void onLinkPropertiesChanged(Network network, LinkProperties newLp) {
+                synchronized (mLock) {
+                    if (network.equals(mState.mNetwork)) {
+                        mState.mLinkProperties = newLp;
+                        mLock.notify();
+                    }
+                }
+            }
+        };
+    }
+
+    private class BackgroundTestingThread extends Thread {
+        final int POLLING_INTERVAL_MS = 5000;
+        final int CONNECTIVITY_CHECKING_INTERVAL_MS = 1000 + 100 * (new Random().nextInt(20));
+        final int MAX_CONNECTIVITY_CHECKS = 3;
+        final AppState localState = new AppState();
+        final AtomicBoolean isRunning = new AtomicBoolean(false);
+        int numConnectivityChecks = 0;
+        int numConnectivityChecksPassing = 0;
+
+        @Override
+        public void run() {
+            Log.d(TAG, getId() + " started");
+
+            maybeWaitForPreviousThread();
+
+            try {
+                mainLoop();
+            } finally {
+                runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        getStartButton().setEnabled(true);
+                    }
+                });
+                tryScreenOn();
+            }
+
+            synchronized (mLock) { mTestingThread = null; }
+
+            Log.d(TAG, getId() + " exiting");
+        }
+
+        private void mainLoop() {
+            int nextSleepDurationMs = 0;
+
+            while (stillRunning()) {
+                awaitNotification(nextSleepDurationMs);
+                if (!stillRunning()) { break; }
+                nextSleepDurationMs = POLLING_INTERVAL_MS;
+
+                if (localState.mNetwork == null) {
+                    logAndUpdate("waiting for available network");
+                    continue;
+                }
+
+                if (localState.mLinkProperties == null) {
+                    synchronized (mLock) {
+                        mState.mLinkProperties = mCM.getLinkProperties(mState.mNetwork);
+                        dupStateLocked();
+                    }
+                }
+
+                if (!localState.mPassedInitialIPv6Check) {
+                    if (!hasBasicIPv6Connectivity()) {
+                        logAndUpdate("waiting for basic IPv6 connectivity");
+                        continue;
+                    }
+                    synchronized (mLock) {
+                        mState.mPassedInitialIPv6Check = true;
+                    }
+                }
+
+                if (!localState.validPowerStateForTesting()) {
+                    resetConnectivityCheckStatistics();
+                    logAndUpdate("waiting for ACTION_POWER_DISCONNECTED");
+                    continue;
+                }
+
+                if (!localState.validScreenStateForTesting()) {
+                    resetConnectivityCheckStatistics();
+                    tryScreenOff();
+                    logAndUpdate("waiting for ACTION_SCREEN_OFF");
+                    continue;
+                }
+
+                if (mHasBattery) {
+                    final long delta = SystemClock.elapsedRealtime() - localState.mPowerDisconnectTime;
+                    if (delta < MIN_POWER_DISCONNECT_MS) {
+                        nextSleepDurationMs = (int) (MIN_POWER_DISCONNECT_MS - delta);
+                        // Not a lot of point in going to sleep for fewer than 500ms.
+                        if (nextSleepDurationMs > 500) {
+                            Log.d(TAG, "waiting for power to be disconnected for at least "
+                                    + MIN_POWER_DISCONNECT_MS + "ms, "
+                                    + nextSleepDurationMs + "ms left.");
+                            continue;
+                        }
+                    }
+                }
+
+                final long delta = SystemClock.elapsedRealtime() - localState.mScreenOffTime;
+                if (delta < MIN_SCREEN_OFF_MS) {
+                    nextSleepDurationMs = (int) (MIN_SCREEN_OFF_MS - delta);
+                    // Not a lot of point in going to sleep for fewer than 500ms.
+                    if (nextSleepDurationMs > 500) {
+                        Log.d(TAG, "waiting for screen to be off for at least "
+                                + MIN_SCREEN_OFF_MS + "ms, "
+                                + nextSleepDurationMs + "ms left.");
+                        continue;
+                    }
+                }
+
+                numConnectivityChecksPassing += hasGlobalIPv6Connectivity() ? 1 : 0;
+                numConnectivityChecks++;
+                if (numConnectivityChecks >= MAX_CONNECTIVITY_CHECKS) {
+                    break;
+                }
+                nextSleepDurationMs = CONNECTIVITY_CHECKING_INTERVAL_MS;
+            }
+
+            if (!stillRunning()) { return; }
+
+            // We require that 100% of IPv6 HTTPS queries succeed.
+            if (numConnectivityChecksPassing == MAX_CONNECTIVITY_CHECKS) {
+                setTestPassing();
+            } else {
+                logAndUpdate("Test FAILED with score: "
+                        + numConnectivityChecksPassing + "/" + MAX_CONNECTIVITY_CHECKS);
+            }
+        }
+
+        private boolean stillRunning() {
+            return isRunning.get();
+        }
+
+        public void setStopped() {
+            isRunning.set(false);
+        }
+
+        private void maybeWaitForPreviousThread() {
+            BackgroundTestingThread previousThread;
+            synchronized (mLock) {
+                previousThread = mTestingThread;
+            }
+
+            if (previousThread != null) {
+                previousThread.setStopped();
+                try {
+                    previousThread.join();
+                } catch (InterruptedException ignored) {}
+            }
+
+            synchronized (mLock) {
+                if (mTestingThread == null || mTestingThread == previousThread) {
+                    mTestingThread = this;
+                    isRunning.set(true);
+                }
+            }
+        }
+
+        private void dupStateLocked() {
+            localState.mNetwork = mState.mNetwork;
+            localState.mLinkProperties = mState.mLinkProperties;
+            localState.mScreenOffTime = mState.mScreenOffTime;
+            localState.mPowerDisconnectTime = mState.mPowerDisconnectTime;
+            localState.mPassedInitialIPv6Check = mState.mPassedInitialIPv6Check;
+        }
+
+        private void awaitNotification(int timeoutMs) {
+            synchronized (mLock) {
+                if (timeoutMs > 0) {
+                    try {
+                        mLock.wait(timeoutMs);
+                    } catch (InterruptedException e) {}
+                }
+                dupStateLocked();
+            }
+        }
+
+        private void resetConnectivityCheckStatistics() {
+            numConnectivityChecks = 0;
+            numConnectivityChecksPassing = 0;
+        }
+
+        boolean hasBasicIPv6Connectivity() {
+            final HttpResult result = getHttpResource(localState.mNetwork, V6CONN_URL, true);
+            if (result.rcode != 204) {
+                if (result.msg != null && !result.msg.isEmpty()) {
+                    logAndUpdate(result.msg);
+                }
+                return false;
+            }
+            return true;
+        }
+
+        boolean hasGlobalIPv6Connectivity() {
+            final boolean doClose = ((numConnectivityChecks % 2) == 0);
+            final HttpResult result = getHttpResource(localState.mNetwork, V6ADDR_URL, doClose);
+            if (result.rcode != 200) {
+                if (result.msg != null && !result.msg.isEmpty()) {
+                    logAndUpdate(result.msg);
+                }
+                return false;
+            }
+
+            InetAddress reflectedIp;
+            try {
+                // TODO: replace with Os.inet_pton().
+                reflectedIp = InetAddress.getByName(result.msg);
+            } catch (UnknownHostException e) {
+                logAndUpdate("Failed to parse '" + result.msg + "' as an IP address");
+                return false;
+            }
+            if (!(reflectedIp instanceof Inet6Address)) {
+                logAndUpdate(reflectedIp.getHostAddress() + " is not a valid IPv6 address");
+                return false;
+            }
+
+            for (LinkAddress linkAddr : localState.mLinkProperties.getLinkAddresses()) {
+                if (linkAddr.getAddress().equals(reflectedIp)) {
+                    logAndUpdate("Found reflected IP " + linkAddr.getAddress().getHostAddress());
+                    return true;
+                }
+            }
+
+            logAndUpdate("Link IP addresses do not include: " + reflectedIp.getHostAddress());
+            return false;
+        }
+    }
+
+    private static class HttpResult {
+        public final int rcode;
+        public final String msg;
+
+        public HttpResult(int rcode, String msg) {
+            this.rcode = rcode;
+            this.msg = msg;
+        }
+    }
+
+    private static HttpResult getHttpResource(
+            final Network network, final String url, boolean doClose) {
+        int rcode = -1;
+        String msg = null;
+
+        try {
+            final HttpURLConnection conn =
+                    (HttpURLConnection) network.openConnection(new URL(url));
+            conn.setConnectTimeout(10 * 1000);
+            conn.setReadTimeout(10 * 1000);
+            if (doClose) { conn.setRequestProperty("connection", "close"); }
+            rcode = conn.getResponseCode();
+            if (rcode >= 200 && rcode <= 299) {
+                msg = new BufferedReader(new InputStreamReader(conn.getInputStream())).readLine();
+            }
+            if (doClose) { conn.disconnect(); }  // try not to have reusable sessions
+        } catch (IOException e) {
+            msg = "HTTP GET of '" + url + "' encountered " + e;
+        }
+
+        return new HttpResult(rcode, msg);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/LlcpVersionActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/LlcpVersionActivity.java
new file mode 100644
index 0000000..ce5a3d4
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/LlcpVersionActivity.java
@@ -0,0 +1,123 @@
+/*
+ * 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.nfc;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcEvent;
+import android.nfc.NfcManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.widget.TextView;
+
+import java.nio.charset.Charset;
+
+/**
+ * Test activity that sends a particular NDEF Push message to another NFC device.
+ */
+public class LlcpVersionActivity extends PassFailButtons.Activity implements
+        NfcAdapter.CreateNdefMessageCallback {
+
+    private static final int NFC_NOT_ENABLED_DIALOG_ID = 1;
+    private static final int NDEF_PUSH_NOT_ENABLED_DIALOG_ID = 2;
+
+    private NfcAdapter mNfcAdapter;
+    private TextView mTextView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.pass_fail_text);
+        setInfoResources(R.string.nfc_llcp_version_check, R.string.nfc_llcp_version_check_info, 0);
+        setPassFailButtonClickListeners();
+        getPassButton().setEnabled(false);
+
+        mTextView = (TextView) findViewById(R.id.text);
+        mTextView.setText(R.string.nfc_llcp_version_check_info);
+
+        NfcManager nfcManager = (NfcManager) getSystemService(NFC_SERVICE);
+        mNfcAdapter = nfcManager.getDefaultAdapter();
+    }
+
+    private static NdefMessage getTestMessage() {
+        byte[] mimeBytes = "application/com.android.cts.verifier.nfc"
+                .getBytes(Charset.forName("US-ASCII"));
+        byte[] id = new byte[] {1, 3, 3, 7};
+        byte[] payload = "CTS Verifier NDEF Push Tag".getBytes(Charset.forName("US-ASCII"));
+        return new NdefMessage(new NdefRecord[] {
+                new NdefRecord(NdefRecord.TNF_MIME_MEDIA, mimeBytes, id, payload)
+        });
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        if (!mNfcAdapter.isEnabled()) {
+            showDialog(NFC_NOT_ENABLED_DIALOG_ID);
+        } else if (!mNfcAdapter.isNdefPushEnabled()) {
+            /* Sender must have NDEF push enabled */
+            showDialog(NDEF_PUSH_NOT_ENABLED_DIALOG_ID);
+        }
+
+        mNfcAdapter.setNdefPushMessageCallback(this, this);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    }
+
+    @Override
+    public Dialog onCreateDialog(int id, Bundle args) {
+        switch (id) {
+            case NFC_NOT_ENABLED_DIALOG_ID:
+                return NfcDialogs.createNotEnabledDialog(this);
+            case NDEF_PUSH_NOT_ENABLED_DIALOG_ID:
+                return NfcDialogs.createNdefPushNotEnabledDialog(this);
+            default:
+                return super.onCreateDialog(id, args);
+        }
+    }
+
+    @Override
+    public NdefMessage createNdefMessage(NfcEvent event) {
+        if (event.peerLlcpMajorVersion <= 1 && event.peerLlcpMinorVersion < 2) {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    mTextView.setText(R.string.nfc_llcp_version_check_failure);
+                }
+            });
+        } else {
+            runOnUiThread(new Runnable() {
+                @Override
+                public void run() {
+                    getPassButton().setEnabled(true);
+                    mTextView.setText(R.string.nfc_llcp_version_check_success);
+                }
+            });
+        }
+        return null;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NdefPushSenderActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NdefPushSenderActivity.java
index f3f37c4..2f77895 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NdefPushSenderActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NdefPushSenderActivity.java
@@ -23,6 +23,7 @@
 import android.nfc.NdefMessage;
 import android.nfc.NdefRecord;
 import android.nfc.NfcAdapter;
+import android.nfc.NfcEvent;
 import android.nfc.NfcManager;
 import android.os.Bundle;
 import android.widget.TextView;
@@ -32,7 +33,8 @@
 /**
  * Test activity that sends a particular NDEF Push message to another NFC device.
  */
-public class NdefPushSenderActivity extends PassFailButtons.Activity {
+public class NdefPushSenderActivity extends PassFailButtons.Activity implements
+        NfcAdapter.CreateNdefMessageCallback {
 
     static final NdefMessage TEST_MESSAGE = getTestMessage();
 
@@ -76,13 +78,12 @@
             showDialog(NDEF_PUSH_NOT_ENABLED_DIALOG_ID);
         }
 
-        mNfcAdapter.enableForegroundNdefPush(this, TEST_MESSAGE);
+        mNfcAdapter.setNdefPushMessageCallback(this, this);
     }
 
     @Override
     protected void onPause() {
         super.onPause();
-        mNfcAdapter.disableForegroundNdefPush(this);
     }
 
     @Override
@@ -96,4 +97,9 @@
                 return super.onCreateDialog(id, args);
         }
     }
+
+    @Override
+    public NdefMessage createNdefMessage(NfcEvent event) {
+        return getTestMessage();
+    }
 }
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 cb90241..68fc027 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/NfcTestActivity.java
@@ -28,6 +28,7 @@
 import android.nfc.tech.MifareUltralight;
 import android.nfc.tech.Ndef;
 import android.nfc.tech.TagTechnology;
+import android.os.Build;
 import android.os.Bundle;
 
 /** Activity that lists all the NFC tests. */
@@ -58,6 +59,11 @@
                 NdefPushReceiverActivity.class.getName(),
                 new Intent(this, NdefPushReceiverActivity.class), null));
 
+        if ("MNC".equals(Build.VERSION.CODENAME) || Build.VERSION.SDK_INT >= 23) {
+            adapter.add(TestListItem.newTest(this, R.string.nfc_llcp_version_check,
+                    LlcpVersionActivity.class.getName(),
+                    new Intent(this, LlcpVersionActivity.class), null));
+        }
         adapter.add(TestListItem.newCategory(this, R.string.nfc_tag_verification));
         adapter.add(TestListItem.newTest(this, R.string.nfc_ndef,
                 NDEF_ID, getTagIntent(Ndef.class), null));
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java
index 035ce86..879916b 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/nfc/hce/HceReaderTestActivity.java
@@ -40,12 +40,6 @@
 
         if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC_HOST_CARD_EMULATION)) {
             adapter.add(TestListItem.newCategory(this, R.string.nfc_hce_reader_tests));
-            /*
-             * Only add this test when supported in platform
-            adapter.add(TestListItem.newTest(this, R.string.nfc_hce_default_route_reader,
-                    SimpleReaderActivity.class.getName(),
-                    DefaultRouteEmulatorActivity.buildReaderIntent(this), null));
-             */
 
             adapter.add(TestListItem.newTest(this, R.string.nfc_hce_protocol_params_reader,
                     ProtocolParamsReaderActivity.class.getName(),
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java
index d8f196a..4898ab2 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/AttentionManagementVerifierActivity.java
@@ -85,6 +85,7 @@
         tests.add(new InsertContactsTest());
         tests.add(new SetModeNoneTest());
         tests.add(new NoneInterceptsAllTest());
+        tests.add(new SetModeAllTest());
         tests.add(new SetModePriorityTest());
         tests.add(new PriorityInterceptsSomeTest());
         tests.add(new SetModeAllTest());
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
index 07d9cc9..25a36b6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/notifications/InteractiveVerifierActivity.java
@@ -165,8 +165,9 @@
     protected void onSaveInstanceState (Bundle outState) {
         final int stateIndex = mTestList.indexOf(mCurrentTest);
         outState.putInt(STATE, stateIndex);
-        outState.putInt(STATUS, mCurrentTest.status);
-        Log.i(TAG, "saved state(" + stateIndex + "}, status(" + (mCurrentTest.status) + ")");
+        final int status = mCurrentTest == null ? SETUP : mCurrentTest.status;
+        outState.putInt(STATUS, status);
+        Log.i(TAG, "saved state(" + stateIndex + "}, status(" + status + ")");
     }
 
     @Override
@@ -383,6 +384,7 @@
 
         @Override
         void test() {
+            mNm.cancelAll();
             Intent settings = new Intent(NOTIFICATION_LISTENER_SETTINGS);
             if (settings.resolveActivity(mPackageManager) == null) {
                 logFail("no settings activity");
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java
index d133eda..5985be6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/P2pTestListActivity.java
@@ -125,12 +125,12 @@
      * If WiFi Direct is disabled, show the dialog to jump to system setting activity.
      **/
     @Override
-    protected void onListItemClick(ListView listView, View view, int position, long id) {
+    protected void handleItemClick(ListView listView, View view, int position, long id) {
         if (!mIsP2pEnabled) {
             showP2pEnableDialog();
             return;
         }
-        super.onListItemClick(listView, view, position, id);
+        super.handleItemClick(listView, view, position, id);
     }
 
     /**
@@ -153,13 +153,6 @@
     }
 
     /**
-     * Enable Pass Button when the all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-
-    /**
      * Receive the WIFI_P2P_STATE_CHANGED_ACTION action.
      */
     class P2pBroadcastReceiver extends BroadcastReceiver {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java
index e6f94af..dd53d33 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/p2p/RequesterTestListActivity.java
@@ -103,11 +103,4 @@
         adapter.add(TestListItem.newTest(testcase.getTestName(), testcase.getTestId(),
                 intent, null));
     }
-
-    /**
-     * Enable Pass Button when the all tests passed.
-     */
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
 }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/screenpinning/ScreenPinningTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/screenpinning/ScreenPinningTestActivity.java
index 8e72ebb..0728fb5 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/screenpinning/ScreenPinningTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/screenpinning/ScreenPinningTestActivity.java
@@ -31,6 +31,8 @@
 
     private static final String TAG = "ScreenPinningTestActivity";
     private static final String KEY_CURRENT_TEST = "keyCurrentTest";
+    private static final long TASK_MODE_CHECK_DELAY = 200;
+    private static final int MAX_TASK_MODE_CHECK_COUNT = 5;
 
     private Test[] mTests;
     private int mTestIndex;
@@ -203,10 +205,18 @@
                 return;
             }
             stopLockTask();
-            if (!mActivityManager.isInLockTaskMode()) {
-                succeed();
-            } else {
-                error(R.string.error_screen_pinning_couldnt_exit);
+            for (int retry = MAX_TASK_MODE_CHECK_COUNT; retry > 0; retry--) {
+                try {
+                    Thread.sleep(TASK_MODE_CHECK_DELAY);
+                } catch (InterruptedException e) {
+                }
+                Log.d(TAG, "Check unpin ... " + retry);
+                if (!mActivityManager.isInLockTaskMode()) {
+                    succeed();
+                    break;
+                } else if (retry == 1) {
+                    error(R.string.error_screen_pinning_couldnt_exit);
+                }
             }
         };
     };
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.java
new file mode 100644
index 0000000..bca7a66
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/FingerprintBoundKeysTest.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 com.android.cts.verifier.security;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.Manifest;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
+import android.os.Bundle;
+import android.os.CancellationSignal;
+import android.util.Log;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.UserNotAuthenticatedException;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+
+public class FingerprintBoundKeysTest extends PassFailButtons.Activity {
+    private static final String TAG = "FingerprintBoundKeysTest";
+
+    /** Alias for our key in the Android Key Store. */
+    private static final String KEY_NAME = "my_key";
+    private static final byte[] SECRET_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6};
+    private static final int AUTHENTICATION_DURATION_SECONDS = 5;
+    private static final int CONFIRM_CREDENTIALS_REQUEST_CODE = 1;
+    private static final int FINGERPRINT_PERMISSION_REQUEST_CODE = 0;
+
+    private FingerprintManager mFingerprintManager;
+    private KeyguardManager mKeyguardManager;
+    private FingerprintAuthDialogFragment mFingerprintDialog;
+    private Cipher mCipher;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.sec_screen_lock_keys_main);
+        setPassFailButtonClickListeners();
+        setInfoResources(R.string.sec_fingerprint_bound_key_test, R.string.sec_fingerprint_bound_key_test_info, -1);
+        getPassButton().setEnabled(false);
+        requestPermissions(new String[]{Manifest.permission.USE_FINGERPRINT},
+                FINGERPRINT_PERMISSION_REQUEST_CODE);
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] state) {
+        if (requestCode == FINGERPRINT_PERMISSION_REQUEST_CODE && state[0] == PackageManager.PERMISSION_GRANTED) {
+            mFingerprintManager = (FingerprintManager) getSystemService(Context.FINGERPRINT_SERVICE);
+            mKeyguardManager = (KeyguardManager) getSystemService(KeyguardManager.class);
+            Button startTestButton = (Button) findViewById(R.id.sec_start_test_button);
+
+            if (!mKeyguardManager.isKeyguardSecure()) {
+                // Show a message that the user hasn't set up a lock screen.
+                showToast( "Secure lock screen hasn't been set up.\n"
+                                + "Go to 'Settings -> Security -> Screen lock' to set up a lock screen");
+                startTestButton.setEnabled(false);
+                return;
+            } else if (!mFingerprintManager.hasEnrolledFingerprints()) {
+                showToast("No fingerprints enrolled.\n"
+                                + "Go to 'Settings -> Security -> Fingerprint' to set up a fingerprint");
+                startTestButton.setEnabled(false);
+                return;
+            }
+
+            createKey();
+
+            try {
+                KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+                keyStore.load(null);
+                SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_NAME, null);
+                mCipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/"
+                            + KeyProperties.BLOCK_MODE_CBC + "/"
+                            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
+
+                mCipher.init(Cipher.ENCRYPT_MODE, secretKey);
+            } catch (KeyPermanentlyInvalidatedException e) {
+                createKey();
+                showToast("The key has been invalidated, please try again.\n");
+            } catch (NoSuchPaddingException | KeyStoreException | CertificateException | UnrecoverableKeyException | IOException
+                    | NoSuchAlgorithmException | InvalidKeyException e) {
+                throw new RuntimeException("Failed to init Cipher", e);
+            }
+
+            startTestButton.setOnClickListener(new OnClickListener() {
+                @Override
+                public void onClick(View v) {
+                    if (tryEncrypt()) {
+                        showToast("Test failed. Key accessible without auth.");
+                    } else {
+                        showAuthenticationScreen();
+                    }
+                }
+            });
+        }
+    }
+
+    /**
+     * Creates a symmetric key in the Android Key Store which can only be used after the user has
+     * authenticated with device credentials within the last X seconds.
+     */
+    private void createKey() {
+        // Generate a key to decrypt payment credentials, tokens, etc.
+        // This will most likely be a registration step for the user when they are setting up your app.
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(
+                    KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
+
+            // Set the alias of the entry in Android KeyStore where the key will appear
+            // and the constrains (purposes) in the constructor of the Builder
+            keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
+                    .setUserAuthenticationRequired(true)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                    .build());
+            keyGenerator.generateKey();
+        } catch (NoSuchAlgorithmException | NoSuchProviderException
+                | InvalidAlgorithmParameterException | KeyStoreException
+                | CertificateException | IOException e) {
+            throw new RuntimeException("Failed to create a symmetric key", e);
+        }
+    }
+
+    /**
+     * Tries to encrypt some data with the generated key in {@link #createKey} which is
+     * only works if the user has just authenticated via device credentials.
+     */
+    private boolean tryEncrypt() {
+        try {
+            mCipher.doFinal(SECRET_BYTE_ARRAY);
+            return true;
+        } catch (BadPaddingException | IllegalBlockSizeException e) {
+            return false;
+        }
+    }
+
+    private void showAuthenticationScreen() {
+        mFingerprintDialog = new FingerprintAuthDialogFragment();
+        mFingerprintDialog.show(getFragmentManager(), "fingerprint_dialog");
+    }
+
+    private void showToast(String message) {
+        Toast.makeText(this, message, Toast.LENGTH_LONG)
+            .show();
+    }
+
+    public class FingerprintAuthDialogFragment extends DialogFragment {
+
+        private CancellationSignal mCancellationSignal;
+        private FingerprintManagerCallback mFingerprintManagerCallback;
+        private boolean mSelfCancelled;
+
+        class FingerprintManagerCallback extends FingerprintManager.AuthenticationCallback {
+            @Override
+            public void onAuthenticationError(int errMsgId, CharSequence errString) {
+                if (!mSelfCancelled) {
+                    showToast(errString.toString());
+                }
+            }
+
+            @Override
+            public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
+                showToast(helpString.toString());
+            }
+
+            @Override
+            public void onAuthenticationFailed() {
+                showToast(getString(R.string.sec_fp_auth_failed));
+            }
+
+            @Override
+            public void onAuthenticationSucceeded(FingerprintManager.AuthenticationResult result) {
+                if (tryEncrypt()) {
+                    showToast("Test passed.");
+                    getPassButton().setEnabled(true);
+                    FingerprintAuthDialogFragment.this.dismiss();
+                } else {
+                    showToast("Test failed. Key not accessible after auth");
+                }
+            }
+        }
+
+        @Override
+        public void onDismiss(DialogInterface dialog) {
+            mCancellationSignal.cancel();
+            mSelfCancelled = true;
+        }
+
+        @Override
+        public Dialog onCreateDialog(Bundle savedInstanceState) {
+            mCancellationSignal = new CancellationSignal();
+            mSelfCancelled = false;
+            mFingerprintManagerCallback = new FingerprintManagerCallback();
+            mFingerprintManager.authenticate(new FingerprintManager.CryptoObject(mCipher),
+                    mCancellationSignal, 0, mFingerprintManagerCallback, null);
+            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+            builder.setMessage(R.string.sec_fp_dialog_message);
+            return builder.create();
+        }
+
+    }
+}
+
+
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/KeyChainTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/KeyChainTest.java
new file mode 100644
index 0000000..ebdb4c0
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/KeyChainTest.java
@@ -0,0 +1,464 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.security;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.security.KeyChain;
+import android.security.KeyChainAliasCallback;
+import android.security.KeyChainException;
+import android.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.MockWebServer;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.net.Socket;
+import java.net.URL;
+import java.security.GeneralSecurityException;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+import java.util.List;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.X509ExtendedKeyManager;
+
+import libcore.java.security.TestKeyStore;
+import libcore.javax.net.ssl.TestSSLContext;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mockito;
+
+/**
+ * Simple activity based test that exercises the KeyChain API
+ */
+public class KeyChainTest extends PassFailButtons.Activity implements View.OnClickListener {
+
+    private static final String TAG = "KeyChainTest";
+
+    private static final int REQUEST_CA_INSTALL = 1;
+
+    private TextView mInstructionView;
+    private TextView mLogView;
+    private Button mResetButton;
+    private Button mSkipButton;
+    private Button mNextButton;
+
+    private List<Step> mSteps;
+    int mCurrentStep;
+
+    private KeyStore mKeyStore;
+    private static final char[] KEYSTORE_PASSWORD = "".toCharArray();
+
+    // How long to wait before giving up on the user selecting a key alias.
+    private static final int KEYCHAIN_ALIAS_TIMEOUT_MS = (int) TimeUnit.MINUTES.toMillis(5L);
+
+    @Override public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        View root = getLayoutInflater().inflate(R.layout.keychain_main, null);
+        setContentView(root);
+
+        setInfoResources(R.string.keychain_test, R.string.keychain_info, -1);
+        setPassFailButtonClickListeners();
+
+        mInstructionView = (TextView) root.findViewById(R.id.test_instruction);
+        mLogView = (TextView) root.findViewById(R.id.test_log);
+        mLogView.setMovementMethod(new ScrollingMovementMethod());
+
+        mNextButton = (Button) root.findViewById(R.id.action_next);
+        mNextButton.setOnClickListener(this);
+
+        mResetButton = (Button) root.findViewById(R.id.action_reset);
+        mResetButton.setOnClickListener(this);
+
+        mSkipButton = (Button) root.findViewById(R.id.action_skip);
+        mSkipButton.setOnClickListener(this);
+
+        resetProgress();
+    }
+
+    @Override
+    public void onClick(View v) {
+        Step step = mSteps.get(mCurrentStep);
+        if (v == mNextButton) {
+            switch (step.task.getStatus()) {
+                case PENDING: {
+                    step.task.execute();
+                    break;
+                }
+                case FINISHED: {
+                    if (mCurrentStep + 1 < mSteps.size()) {
+                        mCurrentStep += 1;
+                        updateUi();
+                    } else {
+                        mSkipButton.setVisibility(View.INVISIBLE);
+                        mNextButton.setVisibility(View.INVISIBLE);
+                    }
+                    break;
+                }
+            }
+        } else if (v == mSkipButton) {
+            step.task.cancel(false);
+            mCurrentStep += 1;
+            updateUi();
+        } else if (v == mResetButton) {
+            resetProgress();
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        switch (requestCode) {
+            case REQUEST_CA_INSTALL: {
+                if (resultCode == RESULT_OK) {
+                    log("CA Certificate installed successfully");
+                } else {
+                    log("REQUEST_CA_INSTALL failed with result code: " + resultCode);
+                }
+                break;
+            }
+            default:
+                throw new IllegalStateException("requestCode == " + requestCode);
+        }
+    }
+
+    private void resetProgress() {
+        getPassButton().setEnabled(false);
+        mLogView.setText("");
+
+        mSteps = new ArrayList<>();
+        mSteps.add(new Step(R.string.keychain_setup_desc, false, new SetupTestKeyStoreTask()));
+        mSteps.add(new Step(R.string.keychain_install_desc, true, new InstallCredentialsTask()));
+        mSteps.add(new Step(R.string.keychain_https_desc, false, new TestHttpsRequestTask()));
+        mSteps.add(new Step(R.string.keychain_reset_desc, true, new ClearCredentialsTask()));
+        mCurrentStep = 0;
+
+        updateUi();
+    }
+
+    private void updateUi() {
+        mLogView.setText("");
+
+        if (mCurrentStep >= mSteps.size()) {
+            mSkipButton.setVisibility(View.INVISIBLE);
+            mNextButton.setVisibility(View.INVISIBLE);
+            getPassButton().setEnabled(true);
+            return;
+        }
+
+        final Step step = mSteps.get(mCurrentStep);
+        if (step.task.getStatus() == AsyncTask.Status.PENDING) {
+            mInstructionView.setText(step.instructionTextId);
+        }
+        mSkipButton.setVisibility(step.skippable ? View.VISIBLE : View.INVISIBLE);
+        mNextButton.setVisibility(View.VISIBLE);
+    }
+
+    private class SetupTestKeyStoreTask extends AsyncTask<Void, Void, Void> {
+        @Override
+        protected Void doInBackground(Void... params) {
+            final Certificate[] chain = new Certificate[2];
+            final Key privKey;
+
+            log("Reading resources");
+            Resources res = getResources();
+            ByteArrayOutputStream userKey = new ByteArrayOutputStream();
+            try {
+                InputStream is = res.openRawResource(R.raw.userkey);
+                byte[] buffer = new byte[4096];
+                for (int n; (n = is.read(buffer, 0, buffer.length)) != -1;) {
+                    userKey.write(buffer, 0, n);
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Reading private key failed", e);
+                return null;
+            }
+            log("Private key length: " + userKey.size() + " bytes");
+
+            log("Setting up KeyStore");
+            try {
+                KeyFactory keyFact = KeyFactory.getInstance("RSA");
+                privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(userKey.toByteArray()));
+
+                final CertificateFactory f = CertificateFactory.getInstance("X.509");
+                chain[0] = f.generateCertificate(res.openRawResource(R.raw.usercert));
+                chain[1] = f.generateCertificate(res.openRawResource(R.raw.cacert));
+            } catch (GeneralSecurityException gse) {
+                Log.w(TAG, "Certificate generation failed", gse);
+                return null;
+            }
+
+            try {
+                // Create a PKCS12 keystore populated with key + certificate chain
+                KeyStore ks = KeyStore.getInstance("PKCS12");
+                ks.load(null, null);
+                ks.setKeyEntry("alias", privKey, KEYSTORE_PASSWORD, chain);
+                mKeyStore = ks;
+                log("KeyStore initialized");
+            } catch (Exception e) {
+                log("KeyStore initialization failed");
+                Log.e(TAG, "", e);
+            }
+            return null;
+        }
+    }
+
+    private class InstallCredentialsTask extends AsyncTask<Void, Void, Void> {
+        @Override
+        protected Void doInBackground(Void... params) {
+            try {
+                Intent intent = KeyChain.createInstallIntent();
+                intent.putExtra(KeyChain.EXTRA_NAME, TAG);
+
+                // Write keystore to byte array for installation
+                ByteArrayOutputStream pkcs12 = new ByteArrayOutputStream();
+                mKeyStore.store(pkcs12, KEYSTORE_PASSWORD);
+                if (pkcs12.size() == 0) {
+                    throw new AssertionError("Credential archive is empty");
+                }
+                log("Requesting install of server's credentials");
+                intent.putExtra(KeyChain.EXTRA_PKCS12, pkcs12.toByteArray());
+                startActivityForResult(intent, REQUEST_CA_INSTALL);
+            } catch (Exception e) {
+                log("Failed to install credentials: " + e);
+            }
+            return null;
+        }
+    }
+
+    private class TestHttpsRequestTask extends AsyncTask<Void, Void, Void> {
+        @Override
+        protected Void doInBackground(Void... params) {
+            try {
+                URL url = startWebServer();
+                makeHttpsRequest(url);
+            } catch (Exception e) {
+                Log.e(TAG, "HTTPS request unsuccessful", e);
+                log("Connection failed");
+                return null;
+            }
+
+            runOnUiThread(new Runnable() {
+                @Override public void run() {
+                    getPassButton().setEnabled(true);
+                }
+            });
+            return null;
+        }
+
+        /**
+         * Create a mock web server.
+         * The server authenticates itself to the client using the key pair and certificate from the
+         * PKCS#12 keystore used in this test. Client authentication uses default trust management:
+         * the server trusts only the certificates installed in the credential storage of this
+         * user/profile.
+         */
+        private URL startWebServer() throws Exception {
+            log("Starting web server");
+            String kmfAlgoritm = KeyManagerFactory.getDefaultAlgorithm();
+            KeyManagerFactory kmf = KeyManagerFactory.getInstance(kmfAlgoritm);
+            kmf.init(mKeyStore, KEYSTORE_PASSWORD);
+            SSLContext serverContext = SSLContext.getInstance("TLS");
+            serverContext.init(kmf.getKeyManagers(),
+                    null /* TrustManager[] */,
+                    null /* SecureRandom */);
+            SSLSocketFactory sf = serverContext.getSocketFactory();
+            SSLSocketFactory needsClientAuth = TestSSLContext.clientAuth(sf,
+                    false /* Want client auth */,
+                    true /* Need client auth */);
+            MockWebServer server = new MockWebServer();
+            server.useHttps(needsClientAuth, false /* tunnelProxy */);
+            server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
+            server.play();
+            return server.getUrl("/");
+        }
+
+        /**
+         * Open a new connection to the server.
+         * The client authenticates itself to the server using a private key and certificate
+         * supplied by KeyChain. Server authentication uses default trust management: the client
+         * trusts only certificates installed in the credential storage of this user/profile. This
+         * setup is expected to work because the server uses a private key whose certificate was
+         * installed earlier during this test.
+         */
+        private void makeHttpsRequest(URL url) throws Exception {
+            log("Making https request to " + url);
+            SSLContext clientContext = SSLContext.getInstance("TLS");
+            clientContext.init(new KeyManager[] { new KeyChainKeyManager() },
+                    null /* TrustManager[] */,
+                    null /* SecureRandom */);
+            HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
+            connection.setSSLSocketFactory(clientContext.getSocketFactory());
+            if (connection.getResponseCode() != 200) {
+                log("Connection failed. Response code: " + connection.getResponseCode());
+                throw new AssertionError();
+            }
+            log("Connection succeeded.");
+        }
+    }
+
+    private class ClearCredentialsTask extends AsyncTask<Void, Void, Void> {
+        @Override
+        protected Void doInBackground(Void... params) {
+            final Intent securitySettingsIntent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
+            startActivity(securitySettingsIntent);
+            log("Started action: " + Settings.ACTION_SECURITY_SETTINGS);
+            log("All tests complete!");
+            return null;
+        }
+    }
+
+    /**
+     * Key manager which synchronously prompts for its aliases via KeyChain
+     */
+    private class KeyChainKeyManager extends X509ExtendedKeyManager {
+        @Override
+        public String chooseClientAlias(String[] keyTypes, Principal[] issuers, Socket socket) {
+            log("KeyChainKeyManager chooseClientAlias");
+            KeyChainAliasCallback aliasCallback = Mockito.mock(KeyChainAliasCallback.class);
+            KeyChain.choosePrivateKeyAlias(KeyChainTest.this, aliasCallback,
+                                           keyTypes, issuers,
+                                           socket.getInetAddress().getHostName(), socket.getPort(),
+                                           null);
+
+            ArgumentCaptor<String> aliasCaptor = ArgumentCaptor.forClass(String.class);
+            Mockito.verify(aliasCallback, Mockito.timeout((int) KEYCHAIN_ALIAS_TIMEOUT_MS))
+                    .alias(aliasCaptor.capture());
+
+            log("Certificate alias: \"" + aliasCaptor.getValue() + "\"");
+            return aliasCaptor.getValue();
+        }
+
+        @Override
+        public String chooseServerAlias(String keyType,
+                                                  Principal[] issuers,
+                                                  Socket socket) {
+            // Not a client SSLSocket callback
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public X509Certificate[] getCertificateChain(String alias) {
+            try {
+                log("KeyChainKeyManager getCertificateChain");
+                X509Certificate[] certificateChain =
+                        KeyChain.getCertificateChain(KeyChainTest.this, alias);
+                if (certificateChain == null) {
+                    log("Null certificate chain!");
+                    return null;
+                }
+                log("Returned " + certificateChain.length + " certificates in chain");
+                for (int i = 0; i < certificateChain.length; i++) {
+                    Log.d(TAG, "certificate[" + i + "]=" + certificateChain[i]);
+                }
+                return certificateChain;
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                return null;
+            } catch (KeyChainException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        @Override
+        public String[] getClientAliases(String keyType, Principal[] issuers) {
+            // not a client SSLSocket callback
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public String[] getServerAliases(String keyType, Principal[] issuers) {
+            // not a client SSLSocket callback
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public PrivateKey getPrivateKey(String alias) {
+            try {
+                log("KeyChainKeyManager.getPrivateKey(\"" + alias + "\")");
+                PrivateKey privateKey = KeyChain.getPrivateKey(KeyChainTest.this, alias);
+                Log.d(TAG, "privateKey = " + privateKey);
+                return privateKey;
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                return null;
+            } catch (KeyChainException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Write a message to the log, also to a visible TextView if available.
+     */
+    private void log(final String message) {
+        Log.d(TAG, message);
+        if (mLogView != null) {
+            runOnUiThread(new Runnable() {
+                @Override public void run() {
+                    mLogView.append(message + "\n");
+                }
+            });
+        }
+    }
+
+    /**
+     * Utility class to store one step per object.
+     */
+    private static class Step {
+        // Instruction message to show before running
+        int instructionTextId;
+
+        // Whether to allow a 'skip' button for this step
+        boolean skippable;
+
+        // Set of commands to run when 'next' is pressed
+        AsyncTask<Void, Void, Void> task;
+
+        public Step(int instructionTextId, boolean skippable, AsyncTask<Void, Void, Void> task) {
+            this.instructionTextId = instructionTextId;
+            this.skippable = skippable;
+            this.task = task;
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/security/ScreenLockBoundKeysTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/security/ScreenLockBoundKeysTest.java
new file mode 100644
index 0000000..863488b
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/security/ScreenLockBoundKeysTest.java
@@ -0,0 +1,204 @@
+/*
+ * 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.security;
+
+import com.android.cts.verifier.PassFailButtons;
+import com.android.cts.verifier.R;
+
+import android.app.AlertDialog;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyPermanentlyInvalidatedException;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.UserNotAuthenticatedException;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.Toast;
+
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+
+public class ScreenLockBoundKeysTest extends PassFailButtons.Activity {
+
+    /** Alias for our key in the Android Key Store. */
+    private static final String KEY_NAME = "my_lock_key";
+    private static final byte[] SECRET_BYTE_ARRAY = new byte[] {1, 2, 3, 4, 5, 6};
+    private static final int AUTHENTICATION_DURATION_SECONDS = 5;
+    private static final int CONFIRM_CREDENTIALS_REQUEST_CODE = 1;
+
+    private KeyguardManager mKeyguardManager;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.sec_screen_lock_keys_main);
+        setPassFailButtonClickListeners();
+        setInfoResources(R.string.sec_lock_bound_key_test, R.string.sec_lock_bound_key_test_info, -1);
+
+        mKeyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
+
+        getPassButton().setEnabled(false);
+
+        Button startTestButton = (Button) findViewById(R.id.sec_start_test_button);
+        startTestButton.setOnClickListener(new OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                showToast("Test running...");
+                v.postDelayed(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (tryEncrypt()) {
+                            showToast("Test failed. Key accessible without auth.");
+                        } else {
+                            showAuthenticationScreen();
+                        }
+                    }
+                },
+                AUTHENTICATION_DURATION_SECONDS * 1000);
+            }
+
+        });
+
+        if (!mKeyguardManager.isKeyguardSecure()) {
+            // Show a message that the user hasn't set up a lock screen.
+            Toast.makeText(this,
+                    "Secure lock screen hasn't set up.\n"
+                            + "Go to 'Settings -> Security -> Screenlock' to set up a lock screen",
+                    Toast.LENGTH_LONG).show();
+            startTestButton.setEnabled(false);
+            return;
+        }
+
+        createKey();
+    }
+
+    /**
+     * Creates a symmetric key in the Android Key Store which can only be used after the user has
+     * authenticated with device credentials within the last X seconds.
+     */
+    private void createKey() {
+        // Generate a key to decrypt payment credentials, tokens, etc.
+        // This will most likely be a registration step for the user when they are setting up your app.
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            KeyGenerator keyGenerator = KeyGenerator.getInstance(
+                    KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
+
+            // Set the alias of the entry in Android KeyStore where the key will appear
+            // and the constrains (purposes) in the constructor of the Builder
+            keyGenerator.init(new KeyGenParameterSpec.Builder(KEY_NAME,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
+                    .setUserAuthenticationRequired(true)
+                            // Require that the user has unlocked in the last 30 seconds
+                    .setUserAuthenticationValidityDurationSeconds(AUTHENTICATION_DURATION_SECONDS)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                    .build());
+            keyGenerator.generateKey();
+        } catch (NoSuchAlgorithmException | NoSuchProviderException
+                | InvalidAlgorithmParameterException | KeyStoreException
+                | CertificateException | IOException e) {
+            throw new RuntimeException("Failed to create a symmetric key", e);
+        }
+    }
+
+    /**
+     * Tries to encrypt some data with the generated key in {@link #createKey} which is
+     * only works if the user has just authenticated via device credentials.
+     */
+    private boolean tryEncrypt() {
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null);
+            SecretKey secretKey = (SecretKey) keyStore.getKey(KEY_NAME, null);
+            Cipher cipher = Cipher.getInstance(
+                    KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_CBC + "/"
+                            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
+
+            // Try encrypting something, it will only work if the user authenticated within
+            // the last AUTHENTICATION_DURATION_SECONDS seconds.
+            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
+            cipher.doFinal(SECRET_BYTE_ARRAY);
+            return true;
+        } catch (UserNotAuthenticatedException e) {
+            // User is not authenticated, let's authenticate with device credentials.
+            return false;
+        } catch (KeyPermanentlyInvalidatedException e) {
+            // This happens if the lock screen has been disabled or reset after the key was
+            // generated after the key was generated.
+            createKey();
+            Toast.makeText(this, "Set up lockscreen after test ran. Retry the test.\n"
+                            + e.getMessage(),
+                    Toast.LENGTH_LONG).show();
+            return false;
+        } catch (BadPaddingException | IllegalBlockSizeException | KeyStoreException |
+                CertificateException | UnrecoverableKeyException | IOException
+                | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void showAuthenticationScreen() {
+        // Create the Confirm Credentials screen. You can customize the title and description. Or
+        // we will provide a generic one for you if you leave it null
+        Intent intent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null);
+        if (intent != null) {
+            startActivityForResult(intent, CONFIRM_CREDENTIALS_REQUEST_CODE);
+        }
+    }
+
+    private void showToast(String message) {
+        Toast.makeText(this, message, Toast.LENGTH_LONG)
+            .show();
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+        switch (requestCode) {
+            case CONFIRM_CREDENTIALS_REQUEST_CODE:
+                if (resultCode == RESULT_OK) {
+                    if (tryEncrypt()) {
+                        showToast("Test passed.");
+                        getPassButton().setEnabled(true);
+                    } else {
+                        showToast("Test failed. Key not accessible after auth");
+                    }
+                }
+        }
+    }
+}
+
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/CtsMediaOutputSurface.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/CtsMediaOutputSurface.java
new file mode 100644
index 0000000..b28e06b
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/CtsMediaOutputSurface.java
@@ -0,0 +1,322 @@
+/*
+ * 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.sensors;
+
+import android.graphics.SurfaceTexture;
+import android.opengl.EGL14;
+import android.opengl.EGLConfig;
+import android.opengl.EGLContext;
+import android.opengl.EGLDisplay;
+import android.opengl.EGLSurface;
+import android.util.Log;
+import android.view.Surface;
+
+
+//
+// This file is copied from android.hardware.cts.media
+//
+
+/**
+ * Holds state associated with a Surface used for MediaCodec decoder output.
+ * <p>
+ * The (width,height) constructor for this class will prepare GL, create a SurfaceTexture,
+ * and then create a Surface for that SurfaceTexture.  The Surface can be passed to
+ * MediaCodec.configure() to receive decoder output.  When a frame arrives, we latch the
+ * texture with updateTexImage, then render the texture with GL to a pbuffer.
+ * <p>
+ * The no-arg constructor skips the GL preparation step and doesn't allocate a pbuffer.
+ * Instead, it just creates the Surface and SurfaceTexture, and when a frame arrives
+ * we just draw it on whatever surface is current.
+ * <p>
+ * By default, the Surface will be using a BufferQueue in asynchronous mode, so we
+ * can potentially drop frames.
+ */
+class CtsMediaOutputSurface implements SurfaceTexture.OnFrameAvailableListener {
+    private static final String TAG = "OutputSurface";
+    private static final boolean VERBOSE = false;
+
+    private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
+    private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
+    private EGLSurface mEGLSurface = EGL14.EGL_NO_SURFACE;
+
+    private SurfaceTexture mSurfaceTexture;
+    private Surface mSurface;
+
+    private Object mFrameSyncObject = new Object();     // guards mFrameAvailable
+    private boolean mFrameAvailable;
+
+    private CtsMediaTextureRender mTextureRender;
+
+    /**
+     * Creates an OutputSurface backed by a pbuffer with the specifed dimensions.  The new
+     * EGL context and surface will be made current.  Creates a Surface that can be passed
+     * to MediaCodec.configure().
+     */
+    public CtsMediaOutputSurface(int width, int height) {
+        if (width <= 0 || height <= 0) {
+            throw new IllegalArgumentException();
+        }
+
+        eglSetup(width, height);
+        makeCurrent();
+
+        setup(this);
+    }
+
+    /**
+     * Creates an OutputSurface using the current EGL context (rather than establishing a
+     * new one).  Creates a Surface that can be passed to MediaCodec.configure().
+     */
+    public CtsMediaOutputSurface() {
+        setup(this);
+    }
+
+    public CtsMediaOutputSurface(final SurfaceTexture.OnFrameAvailableListener listener) {
+        setup(listener);
+    }
+
+    /**
+     * Creates instances of TextureRender and SurfaceTexture, and a Surface associated
+     * with the SurfaceTexture.
+     */
+    private void setup(SurfaceTexture.OnFrameAvailableListener listener) {
+        mTextureRender = new CtsMediaTextureRender();
+        mTextureRender.surfaceCreated();
+
+        // Even if we don't access the SurfaceTexture after the constructor returns, we
+        // still need to keep a reference to it.  The Surface doesn't retain a reference
+        // at the Java level, so if we don't either then the object can get GCed, which
+        // causes the native finalizer to run.
+        if (VERBOSE) Log.d(TAG, "textureID=" + mTextureRender.getTextureId());
+        mSurfaceTexture = new SurfaceTexture(mTextureRender.getTextureId());
+
+        // This doesn't work if OutputSurface is created on the thread that CTS started for
+        // these test cases.
+        //
+        // The CTS-created thread has a Looper, and the SurfaceTexture constructor will
+        // create a Handler that uses it.  The "frame available" message is delivered
+        // there, but since we're not a Looper-based thread we'll never see it.  For
+        // this to do anything useful, OutputSurface must be created on a thread without
+        // a Looper, so that SurfaceTexture uses the main application Looper instead.
+        //
+        // Java language note: passing "this" out of a constructor is generally unwise,
+        // but we should be able to get away with it here.
+        mSurfaceTexture.setOnFrameAvailableListener(listener);
+
+        mSurface = new Surface(mSurfaceTexture);
+    }
+
+    /**
+     * Prepares EGL.  We want a GLES 2.0 context and a surface that supports pbuffer.
+     */
+    private void eglSetup(int width, int height) {
+        mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
+        if (mEGLDisplay == EGL14.EGL_NO_DISPLAY) {
+            throw new RuntimeException("unable to get EGL14 display");
+        }
+        int[] version = new int[2];
+        if (!EGL14.eglInitialize(mEGLDisplay, version, 0, version, 1)) {
+            mEGLDisplay = null;
+            throw new RuntimeException("unable to initialize EGL14");
+        }
+
+        // Configure EGL for pbuffer and OpenGL ES 2.0.  We want enough RGB bits
+        // to be able to tell if the frame is reasonable.
+        int[] attribList = {
+                EGL14.EGL_RED_SIZE, 8,
+                EGL14.EGL_GREEN_SIZE, 8,
+                EGL14.EGL_BLUE_SIZE, 8,
+                EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,
+                EGL14.EGL_SURFACE_TYPE, EGL14.EGL_PBUFFER_BIT,
+                EGL14.EGL_NONE
+        };
+        EGLConfig[] configs = new EGLConfig[1];
+        int[] numConfigs = new int[1];
+        if (!EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, configs, 0, configs.length,
+                numConfigs, 0)) {
+            throw new RuntimeException("unable to find RGB888+recordable ES2 EGL config");
+        }
+
+        // Configure context for OpenGL ES 2.0.
+        int[] attrib_list = {
+                EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
+                EGL14.EGL_NONE
+        };
+        mEGLContext = EGL14.eglCreateContext(mEGLDisplay, configs[0], EGL14.EGL_NO_CONTEXT,
+                attrib_list, 0);
+        checkEglError("eglCreateContext");
+        if (mEGLContext == null) {
+            throw new RuntimeException("null context");
+        }
+
+        // Create a pbuffer surface.  By using this for output, we can use glReadPixels
+        // to test values in the output.
+        int[] surfaceAttribs = {
+                EGL14.EGL_WIDTH, width,
+                EGL14.EGL_HEIGHT, height,
+                EGL14.EGL_NONE
+        };
+        mEGLSurface = EGL14.eglCreatePbufferSurface(mEGLDisplay, configs[0], surfaceAttribs, 0);
+        checkEglError("eglCreatePbufferSurface");
+        if (mEGLSurface == null) {
+            throw new RuntimeException("surface was null");
+        }
+    }
+
+    /**
+     * Discard all resources held by this class, notably the EGL context.
+     */
+    public void release() {
+        if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) {
+            EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);
+            EGL14.eglDestroyContext(mEGLDisplay, mEGLContext);
+            EGL14.eglReleaseThread();
+            EGL14.eglTerminate(mEGLDisplay);
+        }
+
+        mSurface.release();
+
+        // this causes a bunch of warnings that appear harmless but might confuse someone:
+        //  W BufferQueue: [unnamed-3997-2] cancelBuffer: BufferQueue has been abandoned!
+        //mSurfaceTexture.release();
+
+        mEGLDisplay = EGL14.EGL_NO_DISPLAY;
+        mEGLContext = EGL14.EGL_NO_CONTEXT;
+        mEGLSurface = EGL14.EGL_NO_SURFACE;
+
+        mTextureRender = null;
+        mSurface = null;
+        mSurfaceTexture = null;
+    }
+
+    /**
+     * Makes our EGL context and surface current.
+     */
+    public void makeCurrent() {
+        if (!EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
+            throw new RuntimeException("eglMakeCurrent failed");
+        }
+    }
+
+    /**
+     * Returns the Surface that we draw onto.
+     */
+    public Surface getSurface() {
+        return mSurface;
+    }
+
+    /**
+     * Replaces the fragment shader.
+     */
+    public void changeFragmentShader(String fragmentShader) {
+        mTextureRender.changeFragmentShader(fragmentShader);
+    }
+
+    /**
+     * Latches the next buffer into the texture.  Must be called from the thread that created
+     * the OutputSurface object, after the onFrameAvailable callback has signaled that new
+     * data is available.
+     */
+    public void awaitNewImage() {
+        final int TIMEOUT_MS = 500;
+
+        synchronized (mFrameSyncObject) {
+            while (!mFrameAvailable) {
+                try {
+                    // Wait for onFrameAvailable() to signal us.  Use a timeout to avoid
+                    // stalling the test if it doesn't arrive.
+                    mFrameSyncObject.wait(TIMEOUT_MS);
+                    if (!mFrameAvailable) {
+                        // TODO: if "spurious wakeup", continue while loop
+                        throw new RuntimeException("Surface frame wait timed out");
+                    }
+                } catch (InterruptedException ie) {
+                    // shouldn't happen
+                    throw new RuntimeException(ie);
+                }
+            }
+            mFrameAvailable = false;
+        }
+
+        // Latch the data.
+        mTextureRender.checkGlError("before updateTexImage");
+        mSurfaceTexture.updateTexImage();
+    }
+
+    /**
+     * Wait up to given timeout until new image become available.
+     * @param timeoutMs
+     * @return true if new image is available. false for no new image until timeout.
+     */
+    public boolean checkForNewImage(int timeoutMs) {
+        synchronized (mFrameSyncObject) {
+            while (!mFrameAvailable) {
+                try {
+                    // Wait for onFrameAvailable() to signal us.  Use a timeout to avoid
+                    // stalling the test if it doesn't arrive.
+                    mFrameSyncObject.wait(timeoutMs);
+                    if (!mFrameAvailable) {
+                        return false;
+                    }
+                } catch (InterruptedException ie) {
+                    // shouldn't happen
+                    throw new RuntimeException(ie);
+                }
+            }
+            mFrameAvailable = false;
+        }
+
+        // Latch the data.
+        mTextureRender.checkGlError("before updateTexImage");
+        mSurfaceTexture.updateTexImage();
+        return true;
+    }
+
+    /**
+     * Draws the data from SurfaceTexture onto the current EGL surface.
+     */
+    public void drawImage() {
+        mTextureRender.drawFrame(mSurfaceTexture);
+    }
+
+    public void latchImage() {
+        mTextureRender.checkGlError("before updateTexImage");
+        mSurfaceTexture.updateTexImage();
+    }
+
+    @Override
+    public void onFrameAvailable(SurfaceTexture st) {
+        if (VERBOSE) Log.d(TAG, "new frame available");
+        synchronized (mFrameSyncObject) {
+            if (mFrameAvailable) {
+                throw new RuntimeException("mFrameAvailable already set, frame could be dropped");
+            }
+            mFrameAvailable = true;
+            mFrameSyncObject.notifyAll();
+        }
+    }
+
+    /**
+     * Checks for EGL errors.
+     */
+    private void checkEglError(String msg) {
+        int error;
+        if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) {
+            throw new RuntimeException(msg + ": EGL error: 0x" + Integer.toHexString(error));
+        }
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/CtsMediaTextureRender.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/CtsMediaTextureRender.java
new file mode 100644
index 0000000..a96033d
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/CtsMediaTextureRender.java
@@ -0,0 +1,306 @@
+/*
+ * 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.sensors;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import android.graphics.Bitmap;
+import android.graphics.SurfaceTexture;
+import android.opengl.GLES11Ext;
+import android.opengl.GLES20;
+import android.opengl.Matrix;
+import android.util.Log;
+
+
+//
+// This file is copied from android.hardware.cts.media
+//
+
+/**
+ * Code for rendering a texture onto a surface using OpenGL ES 2.0.
+ */
+class CtsMediaTextureRender {
+    private static final String TAG = "TextureRender";
+
+    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 final float[] mTriangleVerticesData = {
+        // 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 FloatBuffer mTriangleVertices;
+
+    private static final String VERTEX_SHADER =
+            "uniform mat4 uMVPMatrix;\n" +
+            "uniform mat4 uSTMatrix;\n" +
+            "attribute vec4 aPosition;\n" +
+            "attribute vec4 aTextureCoord;\n" +
+            "varying vec2 vTextureCoord;\n" +
+            "void main() {\n" +
+            "  gl_Position = uMVPMatrix * aPosition;\n" +
+            "  vTextureCoord = (uSTMatrix * 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 float[] mMVPMatrix = new float[16];
+    private float[] mSTMatrix = new float[16];
+
+    private int mProgram;
+    private int mTextureID = -12345;
+    private int muMVPMatrixHandle;
+    private int muSTMatrixHandle;
+    private int maPositionHandle;
+    private int maTextureHandle;
+
+    public CtsMediaTextureRender() {
+        mTriangleVertices = ByteBuffer.allocateDirect(
+            mTriangleVerticesData.length * FLOAT_SIZE_BYTES)
+                .order(ByteOrder.nativeOrder()).asFloatBuffer();
+        mTriangleVertices.put(mTriangleVerticesData).position(0);
+
+        Matrix.setIdentityM(mSTMatrix, 0);
+    }
+
+    public int getTextureId() {
+        return mTextureID;
+    }
+
+    public void drawFrame(SurfaceTexture st) {
+        checkGlError("onDrawFrame start");
+        st.getTransformMatrix(mSTMatrix);
+
+        GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
+        GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+
+        GLES20.glUseProgram(mProgram);
+        checkGlError("glUseProgram");
+
+        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
+
+        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
+        GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
+            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+        checkGlError("glVertexAttribPointer maPosition");
+        GLES20.glEnableVertexAttribArray(maPositionHandle);
+        checkGlError("glEnableVertexAttribArray maPositionHandle");
+
+        mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
+        GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false,
+            TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+        checkGlError("glVertexAttribPointer maTextureHandle");
+        GLES20.glEnableVertexAttribArray(maTextureHandle);
+        checkGlError("glEnableVertexAttribArray maTextureHandle");
+
+        Matrix.setIdentityM(mMVPMatrix, 0);
+        GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
+        GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
+
+        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+        checkGlError("glDrawArrays");
+        GLES20.glFinish();
+    }
+
+    /**
+     * Initializes GL state.  Call this after the EGL surface has been created and made current.
+     */
+    public void surfaceCreated() {
+        mProgram = createProgram(VERTEX_SHADER, FRAGMENT_SHADER);
+        if (mProgram == 0) {
+            throw new RuntimeException("failed creating program");
+        }
+        maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
+        checkGlError("glGetAttribLocation aPosition");
+        if (maPositionHandle == -1) {
+            throw new RuntimeException("Could not get attrib location for aPosition");
+        }
+        maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
+        checkGlError("glGetAttribLocation aTextureCoord");
+        if (maTextureHandle == -1) {
+            throw new RuntimeException("Could not get attrib location for aTextureCoord");
+        }
+
+        muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+        checkGlError("glGetUniformLocation uMVPMatrix");
+        if (muMVPMatrixHandle == -1) {
+            throw new RuntimeException("Could not get attrib location for uMVPMatrix");
+        }
+
+        muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
+        checkGlError("glGetUniformLocation uSTMatrix");
+        if (muSTMatrixHandle == -1) {
+            throw new RuntimeException("Could not get attrib location for uSTMatrix");
+        }
+
+
+        int[] textures = new int[1];
+        GLES20.glGenTextures(1, textures, 0);
+
+        mTextureID = textures[0];
+        GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mTextureID);
+        checkGlError("glBindTexture mTextureID");
+
+        GLES20.glTexParameterf(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
+                GLES20.GL_NEAREST);
+        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");
+    }
+
+    /**
+     * Replaces the fragment shader.
+     */
+    public void changeFragmentShader(String fragmentShader) {
+        GLES20.glDeleteProgram(mProgram);
+        mProgram = createProgram(VERTEX_SHADER, fragmentShader);
+        if (mProgram == 0) {
+            throw new RuntimeException("failed creating program");
+        }
+    }
+
+    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();
+        checkGlError("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;
+    }
+
+    public void checkGlError(String op) {
+        int error;
+        while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+            Log.e(TAG, op + ": glError " + error);
+            throw new RuntimeException(op + ": glError " + error);
+        }
+    }
+
+    /**
+     * Saves the current frame to disk as a PNG image.  Frame starts from (0,0).
+     * <p>
+     * Useful for debugging.
+     */
+    public static void saveFrame(String filename, int width, int height) {
+        // glReadPixels gives us a ByteBuffer filled with what is essentially big-endian RGBA
+        // data (i.e. a byte of red, followed by a byte of green...).  We need an int[] filled
+        // with native-order ARGB data to feed to Bitmap.
+        //
+        // If we implement this as a series of buf.get() calls, we can spend 2.5 seconds just
+        // copying data around for a 720p frame.  It's better to do a bulk get() and then
+        // rearrange the data in memory.  (For comparison, the PNG compress takes about 500ms
+        // for a trivial frame.)
+        //
+        // So... we set the ByteBuffer to little-endian, which should turn the bulk IntBuffer
+        // get() into a straight memcpy on most Android devices.  Our ints will hold ABGR data.
+        // Swapping B and R gives us ARGB.  We need about 30ms for the bulk get(), and another
+        // 270ms for the color swap.
+        //
+        // Making this even more interesting is the upside-down nature of GL, which means we
+        // may want to flip the image vertically here.
+
+        ByteBuffer buf = ByteBuffer.allocateDirect(width * height * 4);
+        buf.order(ByteOrder.LITTLE_ENDIAN);
+        GLES20.glReadPixels(0, 0, width, height, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buf);
+        buf.rewind();
+
+        int pixelCount = width * height;
+        int[] colors = new int[pixelCount];
+        buf.asIntBuffer().get(colors);
+        for (int i = 0; i < pixelCount; i++) {
+            int c = colors[i];
+            colors[i] = (c & 0xff00ff00) | ((c & 0x00ff0000) >> 16) | ((c & 0x000000ff) << 16);
+        }
+
+        FileOutputStream fos = null;
+        try {
+            fos = new FileOutputStream(filename);
+            Bitmap bmp = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888);
+            bmp.compress(Bitmap.CompressFormat.PNG, 90, fos);
+            bmp.recycle();
+        } catch (IOException ioe) {
+            throw new RuntimeException("Failed to write file " + filename, ioe);
+        } finally {
+            try {
+                if (fos != null) fos.close();
+            } catch (IOException ioe2) {
+                throw new RuntimeException("Failed to close file " + filename, ioe2);
+            }
+        }
+        Log.d(TAG, "Saved " + width + "x" + height + " frame as '" + filename + "'");
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/DeviceSuspendTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/DeviceSuspendTestActivity.java
new file mode 100644
index 0000000..ab8546b
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/DeviceSuspendTestActivity.java
@@ -0,0 +1,337 @@
+package com.android.cts.verifier.sensors;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import com.android.cts.verifier.R;
+import com.android.cts.verifier.sensors.base.SensorCtsVerifierTestActivity;
+import com.android.cts.verifier.sensors.helpers.SensorTestScreenManipulator;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
+import android.hardware.cts.helpers.MovementDetectorHelper;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.SensorTestStateNotSupportedException;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEvent;
+import android.hardware.cts.helpers.TestSensorEventListener;
+import android.hardware.cts.helpers.TestSensorManager;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.SensorNotSupportedException;
+import android.hardware.cts.helpers.sensorverification.BatchArrivalVerification;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.os.SystemClock;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.View;
+
+import junit.framework.Assert;
+
+public class DeviceSuspendTestActivity
+            extends SensorCtsVerifierTestActivity {
+        public DeviceSuspendTestActivity() {
+            super(DeviceSuspendTestActivity.class);
+        }
+
+        private SensorTestScreenManipulator mScreenManipulator;
+        private PowerManager.WakeLock mDeviceSuspendLock;
+        private PendingIntent mPendingIntent;
+        private AlarmManager mAlarmManager;
+        private static String ACTION_ALARM = "DeviceSuspendTestActivity.ACTION_ALARM";
+        private static String TAG = "DeviceSuspendSensorTest";
+        private SensorManager mSensorManager;
+
+        @Override
+        protected void activitySetUp() throws InterruptedException {
+            mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
+            mScreenManipulator = new SensorTestScreenManipulator(this);
+            mScreenManipulator.initialize(this);
+            LocalBroadcastManager.getInstance(this).registerReceiver(myBroadCastReceiver,
+                                            new IntentFilter(ACTION_ALARM));
+
+            Intent intent = new Intent(this, AlarmReceiver.class);
+            mPendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
+
+            mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
+
+            PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
+            mDeviceSuspendLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                                                "DeviceSuspendTestActivity");
+            mDeviceSuspendLock.acquire();
+            SensorTestLogger logger = getTestLogger();
+            logger.logInstructions(R.string.snsr_device_suspend_test_instr);
+            waitForUserToBegin();
+        }
+
+        @Override
+        protected void activityCleanUp() {
+            mScreenManipulator.turnScreenOn();
+            try {
+                playSound();
+            } catch(InterruptedException e) {
+              // Ignore.
+            }
+            LocalBroadcastManager.getInstance(this).unregisterReceiver(myBroadCastReceiver);
+        }
+
+        @Override
+        protected void onDestroy() {
+            super.onDestroy();
+            if (mScreenManipulator != null) {
+                mScreenManipulator.releaseScreenOn();
+                mScreenManipulator.close();
+            }
+            if (mDeviceSuspendLock.isHeld()) {
+                mDeviceSuspendLock.release();
+            }
+        }
+
+        public static class AlarmReceiver extends BroadcastReceiver {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                Intent alarm_intent = new Intent(context, DeviceSuspendTestActivity.class);
+                alarm_intent.setAction(DeviceSuspendTestActivity.ACTION_ALARM);
+                LocalBroadcastManager.getInstance(context).sendBroadcastSync(alarm_intent);
+            }
+        }
+
+        public BroadcastReceiver myBroadCastReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (!mDeviceSuspendLock.isHeld()) {
+                    mDeviceSuspendLock.acquire();
+                }
+            }
+        };
+
+        public String testAPWakeUpWhenReportLatencyExpiresAccel() throws Throwable {
+            Sensor wakeUpSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER, true);
+            if (wakeUpSensor == null) {
+                throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER, true);
+            }
+            return runAPWakeUpWhenReportLatencyExpires(wakeUpSensor);
+        }
+
+        public String testAPWakeUpWhenReportLatencyExpiresGyro() throws Throwable {
+            Sensor wakeUpSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE, true);
+            if (wakeUpSensor == null) {
+                throw new SensorNotSupportedException(Sensor.TYPE_GYROSCOPE, true);
+            }
+            return runAPWakeUpWhenReportLatencyExpires(wakeUpSensor);
+        }
+
+        public String testAPWakeUpWhenReportLatencyExpiresMag() throws Throwable {
+            Sensor wakeUpSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD,true);
+            if (wakeUpSensor == null) {
+                throw new SensorNotSupportedException(Sensor.TYPE_MAGNETIC_FIELD, true);
+            }
+            return runAPWakeUpWhenFIFOFull(wakeUpSensor);
+        }
+
+        public String testAPWakeUpWhenFIFOFullAccel() throws Throwable {
+            Sensor wakeUpSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER, true);
+            if (wakeUpSensor == null) {
+                throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER, true);
+            }
+            return runAPWakeUpWhenFIFOFull(wakeUpSensor);
+        }
+
+        public String testAPWakeUpWhenFIFOFullGyro() throws Throwable {
+            Sensor wakeUpSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE, true);
+            if (wakeUpSensor == null) {
+                throw new SensorNotSupportedException(Sensor.TYPE_GYROSCOPE, true);
+            }
+            return runAPWakeUpWhenFIFOFull(wakeUpSensor);
+        }
+
+        public String testAPWakeUpWhenFIFOFullMag() throws Throwable {
+            Sensor wakeUpSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD,true);
+            if (wakeUpSensor == null) {
+                throw new SensorNotSupportedException(Sensor.TYPE_MAGNETIC_FIELD, true);
+            }
+            return runAPWakeUpWhenFIFOFull(wakeUpSensor);
+        }
+
+        public String testAccelBatchingInAPSuspendLargeReportLatency() throws Throwable {
+            Sensor accel = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+            if (accel == null) {
+                throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER, false);
+            }
+            return runAPWakeUpByAlarmNonWakeSensor(accel, (int)TimeUnit.SECONDS.toMicros(1000));
+        }
+
+        public String testAccelBatchingInAPSuspendZeroReportLatency() throws Throwable {
+            Sensor accel = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+           if (accel == null) {
+                throw new SensorNotSupportedException(Sensor.TYPE_ACCELEROMETER, false);
+            }
+            return runAPWakeUpByAlarmNonWakeSensor(accel, 0);
+        }
+
+        public String runAPWakeUpWhenReportLatencyExpires(Sensor sensor) throws Throwable {
+
+            verifyBatchingSupport(sensor);
+
+            int fifoMaxEventCount = sensor.getFifoMaxEventCount();
+            int samplingPeriodUs = sensor.getMaxDelay();
+            if (samplingPeriodUs == 0) {
+                // If maxDelay is not defined, set the value for 5 Hz.
+                samplingPeriodUs = 200000;
+            }
+
+            long fifoBasedReportLatencyUs = maxBatchingPeriod(sensor, samplingPeriodUs);
+            verifyBatchingPeriod(fifoBasedReportLatencyUs);
+
+            final long MAX_REPORT_LATENCY_US = TimeUnit.SECONDS.toMicros(15); // 15 seconds
+            TestSensorEnvironment environment = new TestSensorEnvironment(
+                    this,
+                    sensor,
+                    false,
+                    samplingPeriodUs,
+                    (int) MAX_REPORT_LATENCY_US,
+                    true /*isDeviceSuspendTest*/);
+
+            TestSensorOperation op = TestSensorOperation.createOperation(environment,
+                                                                          mDeviceSuspendLock,
+                                                                          false);
+            final long ALARM_WAKE_UP_DELAY_MS =
+                    TimeUnit.MICROSECONDS.toMillis(MAX_REPORT_LATENCY_US) +
+                    TimeUnit.SECONDS.toMillis(10);
+
+            op.addVerification(BatchArrivalVerification.getDefault(environment));
+            mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                                    SystemClock.elapsedRealtime() + ALARM_WAKE_UP_DELAY_MS,
+                                    mPendingIntent);
+            try {
+                Log.i(TAG, "Running .. " + getCurrentTestNode().getName() + " " + sensor.getName());
+                op.execute(getCurrentTestNode());
+            } finally {
+                mAlarmManager.cancel(mPendingIntent);
+            }
+            return null;
+        }
+
+        public String runAPWakeUpWhenFIFOFull(Sensor sensor) throws Throwable {
+            verifyBatchingSupport(sensor);
+
+            // Try to fill the FIFO at the fastest rate and check if the time is enough to run
+            // the manual test.
+            int samplingPeriodUs = sensor.getMinDelay();
+
+            long fifoBasedReportLatencyUs = maxBatchingPeriod(sensor, samplingPeriodUs);
+
+            final long MIN_LATENCY_US = TimeUnit.SECONDS.toMicros(20);
+            // Ensure that FIFO based report latency is at least 20 seconds, we need at least 10
+            // seconds of time to allow the device to be in suspend state.
+            if (fifoBasedReportLatencyUs < MIN_LATENCY_US) {
+                int fifoMaxEventCount = sensor.getFifoMaxEventCount();
+                samplingPeriodUs = (int) MIN_LATENCY_US/fifoMaxEventCount;
+                fifoBasedReportLatencyUs = MIN_LATENCY_US;
+            }
+
+            final int MAX_REPORT_LATENCY_US = Integer.MAX_VALUE;
+            final long ALARM_WAKE_UP_DELAY_MS =
+                    TimeUnit.MICROSECONDS.toMillis(fifoBasedReportLatencyUs) +
+                    TimeUnit.SECONDS.toMillis(10);
+
+            TestSensorEnvironment environment = new TestSensorEnvironment(
+                    this,
+                    sensor,
+                    false,
+                    (int) samplingPeriodUs,
+                    (int) MAX_REPORT_LATENCY_US,
+                    true /*isDeviceSuspendTest*/);
+
+            TestSensorOperation op = TestSensorOperation.createOperation(environment,
+                                                                        mDeviceSuspendLock,
+                                                                        true);
+            mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                                    SystemClock.elapsedRealtime() + ALARM_WAKE_UP_DELAY_MS,
+                                    mPendingIntent);
+            op.addDefaultVerifications();
+            try {
+                Log.i(TAG, "Running .. " + getCurrentTestNode().getName() + " " + sensor.getName());
+                op.execute(getCurrentTestNode());
+            } finally {
+                mAlarmManager.cancel(mPendingIntent);
+            }
+            return null;
+        }
+
+        public String runAPWakeUpByAlarmNonWakeSensor(Sensor sensor, int maxReportLatencyUs)
+            throws  Throwable {
+            verifyBatchingSupport(sensor);
+
+            int samplingPeriodUs = sensor.getMaxDelay();
+            if (samplingPeriodUs == 0 || samplingPeriodUs > 200000) {
+                // If maxDelay is not defined, set the value for 5 Hz.
+                samplingPeriodUs = 200000;
+            }
+
+            long fifoBasedReportLatencyUs = maxBatchingPeriod(sensor, samplingPeriodUs);
+            verifyBatchingPeriod(fifoBasedReportLatencyUs);
+
+            TestSensorEnvironment environment = new TestSensorEnvironment(
+                    this,
+                    sensor,
+                    false,
+                    (int) samplingPeriodUs,
+                    maxReportLatencyUs,
+                    true /*isDeviceSuspendTest*/);
+
+            final long ALARM_WAKE_UP_DELAY_MS = 20000;
+            TestSensorOperation op = TestSensorOperation.createOperation(environment,
+                                                                         mDeviceSuspendLock,
+                                                                         true);
+            mAlarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                                    SystemClock.elapsedRealtime() + ALARM_WAKE_UP_DELAY_MS,
+                                    mPendingIntent);
+            try {
+                Log.i(TAG, "Running .. " + getCurrentTestNode().getName() + " " + sensor.getName());
+                op.execute(getCurrentTestNode());
+            } finally {
+                mAlarmManager.cancel(mPendingIntent);
+            }
+            return null;
+        }
+
+        private void verifyBatchingSupport(Sensor sensor)
+                throws SensorTestStateNotSupportedException {
+            int fifoMaxEventCount = sensor.getFifoMaxEventCount();
+            if (fifoMaxEventCount == 0) {
+                throw new SensorTestStateNotSupportedException("Batching not supported.");
+            }
+        }
+
+        private void verifyBatchingPeriod(long periodUs)
+                throws SensorTestStateNotSupportedException {
+            // Ensure that FIFO based report latency is at least 20 seconds, we need at least 10
+            // seconds of time to allow the device to be in suspend state.
+            if (periodUs < TimeUnit.SECONDS.toMicros(20)) {
+                throw new SensorTestStateNotSupportedException("FIFO too small to test reliably");
+            }
+        }
+
+        private long maxBatchingPeriod (Sensor sensor, long samplePeriod) {
+            long fifoMaxEventCount = sensor.getFifoMaxEventCount();
+            return fifoMaxEventCount * samplePeriod;
+        }
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MotionIndicatorView.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MotionIndicatorView.java
new file mode 100644
index 0000000..12d4582
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/MotionIndicatorView.java
@@ -0,0 +1,409 @@
+/*
+ * 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.sensors;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.RectF;
+import android.hardware.SensorManager;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+
+/**
+ * A view class that draws the user prompt
+ *
+ * The following piece of code should show how to use this view.
+ *
+ *  public void testUI()  {
+ *     final int MAX_TILT_ANGLE = 70; // +/- 70
+ *
+ *     final int TILT_ANGLE_STEP = 5; // 5 degree(s) per step
+ *     final int YAW_ANGLE_STEP = 10; // 10 degree(s) per step
+ *
+ *     RangeCoveredRegister xCovered, yCovered, zCovered;
+ *     xCovered = new RangeCoveredRegister(-MAX_TILT_ANGLE, +MAX_TILT_ANGLE, TILT_ANGLE_STEP);
+ *
+ *     yCovered = new RangeCoveredRegister(-MAX_TILT_ANGLE, +MAX_TILT_ANGLE, TILT_ANGLE_STEP);
+ *     zCovered = new RangeCoveredRegister(YAW_ANGLE_STEP);
+ *
+ *     xCovered.update(40);
+ *     xCovered.update(-40);
+ *     xCovered.update(12);
+ *
+ *     yCovered.update(50);
+ *     yCovered.update(-51);
+ *
+ *     zCovered.update(150);
+ *     zCovered.update(42);
+ *
+ *     setDataProvider(xCovered, yCovered, zCovered);
+ *     enableAxis(RVCVRecordActivity.AXIS_ALL); //debug mode, show all three axis
+ * }
+ */
+public class MotionIndicatorView extends View {
+    private final String TAG = "MotionIndicatorView";
+    private final boolean LOCAL_LOGV = false;
+
+    private Paint mCursorPaint;
+    private Paint mLimitPaint;
+    private Paint mCoveredPaint;
+    private Paint mRangePaint;
+    private Paint mEraserPaint;
+
+    // UI settings
+    private final int XBAR_WIDTH = 50;
+    private final int XBAR_MARGIN = 50;
+    private final int XBAR_CURSOR_ADD = 20;
+
+    private final int YBAR_WIDTH = 50;
+    private final int YBAR_MARGIN = 50;
+    private final int YBAR_CURSOR_ADD = 20;
+
+    private final int ZRING_WIDTH = 50;
+    private final int ZRING_CURSOR_ADD = 30;
+
+
+    private int mXSize, mYSize;
+    private RectF mZBoundOut, mZBoundOut2, mZBoundIn, mZBoundIn2;
+
+    private RangeCoveredRegister mXCovered, mYCovered, mZCovered;
+
+    private boolean mXEnabled, mYEnabled, mZEnabled;
+
+    /**
+     * Constructor
+     * @param context
+     */
+    public MotionIndicatorView(Context context) {
+        super(context);
+        init();
+    }
+
+    /**
+     * Constructor
+     * @param context Application context
+     * @param attrs
+     */
+    public MotionIndicatorView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    /**
+     * Initialize the Paint objects
+     */
+    private void init() {
+
+        mCursorPaint = new Paint();
+        mCursorPaint.setColor(Color.BLUE);
+
+        mLimitPaint = new Paint();
+        mLimitPaint.setColor(Color.YELLOW);
+
+        mCoveredPaint = new Paint();
+        mCoveredPaint.setColor(Color.CYAN);
+
+        mRangePaint = new Paint();
+        mRangePaint.setColor(Color.DKGRAY);
+
+        mEraserPaint = new Paint();
+        mEraserPaint.setColor(Color.TRANSPARENT);
+        // ensure the erasing effect
+        mEraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
+    }
+
+    /**
+     * Connect the view to certain data provider objects
+     * @param x Data provider for x direction tilt angle
+     * @param y Data provider for y direction tilt angle
+     * @param z Data provider for z rotation
+     */
+    public void setDataProvider(RangeCoveredRegister x,
+                                RangeCoveredRegister y,
+                                RangeCoveredRegister z)    {
+        mXCovered = x;
+        mYCovered = y;
+        mZCovered = z;
+    }
+
+    /**
+     * Set the active axis for display
+     *
+     * @param axis AXIS_X, AXIS_Y, AXIS_Z for x, y, z axis indicators, or AXIS_ALL for all three.
+     */
+    public void enableAxis(int axis)  {
+        mXEnabled = mYEnabled = mZEnabled = false;
+
+        switch(axis)
+        {
+            case SensorManager.AXIS_X:
+                mXEnabled = true;
+                break;
+            case SensorManager.AXIS_Y:
+                mYEnabled = true;
+                break;
+            case SensorManager.AXIS_Z:
+                mZEnabled = true;
+                break;
+            case RVCVRecordActivity.AXIS_ALL:
+                mXEnabled = mYEnabled = mZEnabled = true;
+        }
+    }
+
+    /**
+     * Doing some pre-calculation that only changes when view dimensions are changed.
+     * @param w
+     * @param h
+     * @param oldw
+     * @param oldh
+     */
+    @Override
+    protected void onSizeChanged (int w, int h, int oldw, int oldh) {
+        mXSize = w;
+        mYSize = h;
+
+        mZBoundOut = new RectF(w/2-w/2.5f, h/2-w/2.5f, w/2+w/2.5f, h/2+w/2.5f);
+        mZBoundOut2 = new RectF(
+                w/2-w/2.5f-ZRING_CURSOR_ADD, h/2-w/2.5f-ZRING_CURSOR_ADD,
+                w/2+w/2.5f+ZRING_CURSOR_ADD, h/2+w/2.5f+ZRING_CURSOR_ADD);
+        mZBoundIn = new RectF(
+                w/2-w/2.5f+ZRING_WIDTH, h/2-w/2.5f+ZRING_WIDTH,
+                w/2+w/2.5f-ZRING_WIDTH, h/2+w/2.5f-ZRING_WIDTH);
+        mZBoundIn2 = new RectF(
+                w/2-w/2.5f+ZRING_WIDTH+ZRING_CURSOR_ADD, h/2-w/2.5f+ZRING_WIDTH+ZRING_CURSOR_ADD,
+                w/2+w/2.5f-ZRING_WIDTH-ZRING_CURSOR_ADD, h/2+w/2.5f-ZRING_WIDTH-ZRING_CURSOR_ADD);
+
+        if (LOCAL_LOGV) Log.v(TAG, "New view size = ("+w+", "+h+")");
+    }
+
+    /**
+     * Draw UI depends on the selected axis and registered value
+     *
+     * @param canvas the canvas to draw on
+     */
+    @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        int i,t;
+
+        Paint p = new Paint();
+        p.setColor(Color.YELLOW);
+        canvas.drawRect(10,10, 50, 50, p);
+
+        if (mXEnabled && mXCovered != null) {
+            int xNStep = mXCovered.getNSteps() + 4; // two on each side as a buffer
+            int xStepSize = mXSize * 3/4 / xNStep;
+            int xLeft = mXSize * 1/8 + (mXSize * 3/4 % xNStep)/2;
+
+            // base bar
+            canvas.drawRect(xLeft, XBAR_MARGIN,
+                    xLeft+xStepSize*xNStep-1, XBAR_WIDTH+XBAR_MARGIN, mRangePaint);
+
+            // covered range
+            for (i=0; i<mXCovered.getNSteps(); ++i) {
+                if (mXCovered.isCovered(i)) {
+                    canvas.drawRect(
+                            xLeft+xStepSize*(i+2), XBAR_MARGIN,
+                            xLeft+xStepSize*(i+3)-1, XBAR_WIDTH + XBAR_MARGIN,
+                            mCoveredPaint);
+                }
+            }
+
+            // limit
+            canvas.drawRect(xLeft+xStepSize*2-4, XBAR_MARGIN,
+                    xLeft+xStepSize*2+3, XBAR_WIDTH+XBAR_MARGIN, mLimitPaint);
+            canvas.drawRect(xLeft+xStepSize*(xNStep-2)-4, XBAR_MARGIN,
+                    xLeft+xStepSize*(xNStep-2)+3, XBAR_WIDTH+XBAR_MARGIN, mLimitPaint);
+
+            // cursor
+            t = (int)(xLeft+xStepSize*(mXCovered.getLastValue()+2));
+            canvas.drawRect(t-4, XBAR_MARGIN-XBAR_CURSOR_ADD, t+3,
+                    XBAR_WIDTH+XBAR_MARGIN+XBAR_CURSOR_ADD, mCursorPaint);
+        }
+        if (mYEnabled && mYCovered != null) {
+            int yNStep = mYCovered.getNSteps() + 4; // two on each side as a buffer
+            int yStepSize = mYSize * 3/4 / yNStep;
+            int yLeft = mYSize * 1/8 + (mYSize * 3/4 % yNStep)/2;
+
+            // base bar
+            canvas.drawRect(YBAR_MARGIN, yLeft,
+                    YBAR_WIDTH+YBAR_MARGIN, yLeft+yStepSize*yNStep-1, mRangePaint);
+
+            // covered range
+            for (i=0; i<mYCovered.getNSteps(); ++i) {
+                if (mYCovered.isCovered(i)) {
+                    canvas.drawRect(
+                            YBAR_MARGIN, yLeft+yStepSize*(i+2),
+                            YBAR_WIDTH + YBAR_MARGIN, yLeft+yStepSize*(i+3)-1,
+                            mCoveredPaint);
+                }
+            }
+
+            // limit
+            canvas.drawRect(YBAR_MARGIN, yLeft + yStepSize * 2 - 4,
+                    YBAR_WIDTH + YBAR_MARGIN, yLeft + yStepSize * 2 + 3, mLimitPaint);
+            canvas.drawRect(YBAR_MARGIN, yLeft + yStepSize * (yNStep - 2) - 4,
+                    YBAR_WIDTH + YBAR_MARGIN, yLeft + yStepSize * (yNStep - 2) + 3, mLimitPaint);
+
+            // cursor
+            t = (int)(yLeft+yStepSize*(mYCovered.getLastValue()+2));
+            canvas.drawRect( YBAR_MARGIN-YBAR_CURSOR_ADD, t-4,
+                    YBAR_WIDTH+YBAR_MARGIN+YBAR_CURSOR_ADD, t+3, mCursorPaint);
+        }
+
+        if (mZEnabled && mZCovered != null) {
+            float stepSize  = 360.0f/mZCovered.getNSteps();
+
+            // base bar
+            canvas.drawArc(mZBoundOut,0, 360, true, mRangePaint);
+
+            // covered range
+            for (i=0; i<mZCovered.getNSteps(); ++i) {
+                if (mZCovered.isCovered(i)) {
+                    canvas.drawArc(mZBoundOut,i*stepSize-0.2f, stepSize+0.4f,
+                            true, mCoveredPaint);
+                }
+            }
+            // clear center
+            canvas.drawArc(mZBoundIn, 0, 360, true, mEraserPaint);
+            // cursor
+            canvas.drawArc(mZBoundOut2, mZCovered.getLastValue()*stepSize- 1, 2,
+                    true, mCursorPaint);
+            canvas.drawArc(mZBoundIn2, mZCovered.getLastValue()*stepSize-1.5f, 3,
+                    true, mEraserPaint);
+        }
+    }
+}
+
+/**
+ *  A range register class for the RVCVRecord Activity
+ */
+class RangeCoveredRegister {
+    enum MODE {
+        LINEAR,
+        ROTATE2D
+    }
+
+    private boolean[] mCovered;
+    private MODE mMode;
+    private int mStep;
+    private int mLow, mHigh;
+    private int mLastData;
+
+    // high is not inclusive
+    RangeCoveredRegister(int low, int high, int step) {
+        mMode = MODE.LINEAR;
+        mStep = step;
+        mLow = low;
+        mHigh = high;
+        init();
+    }
+
+    RangeCoveredRegister(int step) {
+        mMode = MODE.ROTATE2D;
+        mStep = step;
+        mLow = 0;
+        mHigh = 360;
+        init();
+    }
+
+    private void init() {
+        if (mMode == MODE.LINEAR) {
+            mCovered = new boolean[(mHigh-mLow)/mStep];
+        }else {
+            mCovered = new boolean[360/mStep];
+        }
+    }
+
+    /**
+     * Test if the range defined is fully covered.
+     *
+     * @return if the range is fully covered, return true; otherwise false.
+     */
+    public boolean isFullyCovered() {
+        for (boolean i:mCovered) {
+            if (!i) return false;
+        }
+        return true;
+    }
+
+    /**
+     * Test if a specific step is covered.
+     *
+     * @param i the step number
+     * @return if the step specified is covered, return true; otherwise false.
+     */
+    public boolean isCovered(int i) {
+        return mCovered[i];
+    }
+
+    /**
+     *
+     *
+     * @param data
+     * @return if this update changes the status of
+     */
+    public boolean update(int data) {
+        mLastData = data;
+
+        if (mMode == MODE.ROTATE2D) {
+            data %= 360;
+        }
+
+        int iStep = (data - mLow)/mStep;
+
+        if (iStep>=0 && iStep<getNSteps()) {
+            // only record valid data
+            mLastData = data;
+
+            if (mCovered[iStep]) {
+                return false;
+            } else {
+                mCovered[iStep] = true;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Get the number of steps in this register
+     *
+     * @return The number of steps in this register
+     */
+    public int getNSteps() {
+        //if (mCovered == null) {
+        //return 0;
+        //}
+        return mCovered.length;
+    }
+
+    /**
+     * Get the last value updated
+     *
+     * @return The last value updated
+     */
+    public float getLastValue() {
+        // ensure float division
+        return ((float)(mLastData - mLow))/mStep;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java
new file mode 100644
index 0000000..fa89b71
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVCameraPreview.java
@@ -0,0 +1,136 @@
+/*
+ * 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.sensors;
+
+// ----------------------------------------------------------------------
+
+import android.content.Context;
+import android.hardware.Camera;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.ViewGroup;
+
+import java.io.IOException;
+
+/** Camera preview class */
+public class RVCVCameraPreview extends SurfaceView implements SurfaceHolder.Callback {
+    private static final String TAG = "RVCVCameraPreview";
+    private static final boolean LOCAL_LOGD = true;
+
+    private SurfaceHolder mHolder;
+    private Camera mCamera;
+    private float mAspect;
+    private int mRotation;
+
+    /**
+     * Constructor
+     * @param context Activity context
+     */
+    public RVCVCameraPreview(Context context) {
+        super(context);
+        mCamera = null;
+        initSurface();
+    }
+
+    /**
+     * Constructor
+     * @param context Activity context
+     * @param attrs
+     */
+    public RVCVCameraPreview(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void init(Camera camera, float aspectRatio, int rotation)  {
+        this.mCamera = camera;
+        mAspect = aspectRatio;
+        mRotation = rotation;
+        initSurface();
+    }
+
+    private void initSurface() {
+        // Install a SurfaceHolder.Callback so we get notified when the
+        // underlying surface is created and destroyed.
+        mHolder = getHolder();
+        mHolder.addCallback(this);
+
+        // deprecated
+        // TODO: update this code to match new API level.
+        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+    }
+
+    /**
+     *  SurfaceHolder.Callback
+     *  Surface is created, it is OK to start the camera preview now.
+     */
+    public void surfaceCreated(SurfaceHolder holder) {
+        // The Surface has been created, now tell the camera where to draw the preview.
+
+        if (mCamera == null) {
+            // preview camera does not exist
+            return;
+        }
+
+        try {
+            mCamera.setPreviewDisplay(holder);
+            mCamera.startPreview();
+            int v_height = getHeight();
+            int v_width = getWidth();
+            ViewGroup.LayoutParams layout = getLayoutParams();
+            if ( (float)v_height/v_width  >
+                    mAspect) {
+                layout.height = (int)(v_width * mAspect);
+                layout.width = v_width;
+            }else {
+                layout.width = (int)(v_height / mAspect);
+                layout.height = v_height;
+            }
+            Log.d(TAG, String.format("Layout (%d, %d) -> (%d, %d)", v_width, v_height,
+                    layout.width, layout.height));
+            setLayoutParams(layout);
+        } catch (IOException e) {
+            if (LOCAL_LOGD) Log.d(TAG, "Error when starting camera preview: " + e.getMessage());
+        }
+    }
+    /**
+     *  SurfaceHolder.Callback
+     */
+    public void surfaceDestroyed(SurfaceHolder holder) {
+        // empty. Take care of releasing the Camera preview in your activity.
+    }
+
+    /**
+     *  SurfaceHolder.Callback
+     *  Restart camera preview if surface changed
+     */
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+
+        if (mHolder.getSurface() == null || mCamera == null){
+            // preview surface or camera does not exist
+            return;
+        }
+
+        // stop preview before making changes
+        mCamera.stopPreview();
+
+        mCamera.setDisplayOrientation(mRotation);
+
+        //do the same as if it is created again
+        surfaceCreated(holder);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java
new file mode 100644
index 0000000..be5ec52
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVRecordActivity.java
@@ -0,0 +1,993 @@
+/*
+ * 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.
+ */
+
+package com.android.cts.verifier.sensors;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.Camera;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.media.AudioManager;
+import android.media.CamcorderProfile;
+import android.media.MediaRecorder;
+import android.media.SoundPool;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.JsonWriter;
+import android.util.Log;
+import android.view.Window;
+import android.widget.ImageView;
+import android.widget.Toast;
+
+import com.android.cts.verifier.R;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+
+
+// ----------------------------------------------------------------------
+
+/**
+ *  An activity that does recording of the camera video and rotation vector data at the same time.
+ */
+public class RVCVRecordActivity extends Activity {
+    private static final String TAG = "RVCVRecordActivity";
+    private static final boolean LOCAL_LOGV = false;
+
+    private MotionIndicatorView mIndicatorView;
+
+    private SoundPool mSoundPool;
+    private int [] mSoundPoolLookup;
+
+    private File mRecordDir;
+    private RecordProcedureController mController;
+    private VideoRecorder           mVideoRecorder;
+    private RVSensorLogger          mRVSensorLogger;
+    private CoverageManager         mCoverManager;
+    private CameraContext mCameraContext;
+
+    public static final int AXIS_NONE = 0;
+    public static final int AXIS_ALL = SensorManager.AXIS_X +
+                                       SensorManager.AXIS_Y +
+                                       SensorManager.AXIS_Z;
+
+    // For Rotation Vector algorithm research use
+    private final static boolean     LOG_RAW_SENSORS = false;
+    private RawSensorLogger          mRawSensorLogger;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Hide the window title.
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        // inflate xml
+        setContentView(R.layout.cam_preview_overlay);
+
+        // locate views
+        mIndicatorView = (MotionIndicatorView) findViewById(R.id.cam_indicator);
+
+        initStoragePath();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+        mController.quit();
+
+        mCameraContext.end();
+        endSoundPool();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        // delay the initialization as much as possible
+        init();
+    }
+
+    /** display toast message
+     *
+     * @param msg Message content
+     */
+    private void message(String msg) {
+
+        Context context = getApplicationContext();
+        int duration = Toast.LENGTH_SHORT;
+
+        Toast toast = Toast.makeText(context, msg, duration);
+        toast.show();
+    }
+
+    /**
+     *  Initialize components
+     *
+     */
+    private void init() {
+        mCameraContext = new CameraContext();
+        mCameraContext.init();
+
+        mCoverManager = new CoverageManager();
+        mIndicatorView.setDataProvider(
+                mCoverManager.getAxis(SensorManager.AXIS_X),
+                mCoverManager.getAxis(SensorManager.AXIS_Y),
+                mCoverManager.getAxis(SensorManager.AXIS_Z)  );
+
+        initSoundPool();
+        mRVSensorLogger = new RVSensorLogger(this);
+
+        mVideoRecorder = new VideoRecorder(mCameraContext.getCamera(), mCameraContext.getProfile());
+
+        if (LOG_RAW_SENSORS) {
+            mRawSensorLogger = new RawSensorLogger(mRecordDir);
+        }
+
+        mController = new RecordProcedureController(this);
+    }
+
+    /**
+     * Notify recording is completed. This is the successful exit.
+     */
+    public void notifyComplete() {
+        message("Capture completed!");
+
+        Uri resultUri = Uri.fromFile(mRecordDir);
+        Intent result = new Intent();
+        result.setData(resultUri);
+        setResult(Activity.RESULT_OK, result);
+
+        finish();
+    }
+
+    /**
+     * Notify the user what to do next in text
+     *
+     * @param axis SensorManager.AXIS_X or SensorManager.AXIS_Y or SensorManager.AXIS_Z
+     */
+    private void notifyPrompt(int axis) {
+        // It is not XYZ because of earlier design have different definition of
+        // X and Y
+        final String axisName = "YXZ";
+
+        message("Manipulate the device in " + axisName.charAt(axis - 1) +
+                " axis (as illustrated) about the pattern.");
+    }
+
+    /**
+     *  Ask indicator view to redraw
+     */
+    private void redrawIndicator() {
+        mIndicatorView.invalidate();
+    }
+
+    /**
+     * Switch to a different axis for display and logging
+     * @param axis
+     */
+    private void switchAxis(int axis) {
+        ImageView imageView = (ImageView) findViewById(R.id.cam_overlay);
+
+        final int [] prompts = {R.drawable.prompt_x, R.drawable.prompt_y, R.drawable.prompt_z};
+
+        if (axis >=SensorManager.AXIS_X && axis <=SensorManager.AXIS_Z) {
+            imageView.setImageResource(prompts[axis-1]);
+            mIndicatorView.enableAxis(axis);
+            mRVSensorLogger.updateRegister(mCoverManager.getAxis(axis), axis);
+            notifyPrompt(axis);
+        } else {
+            imageView.setImageDrawable(null);
+            mIndicatorView.enableAxis(AXIS_NONE);
+        }
+        redrawIndicator();
+    }
+
+    /**
+     * Asynchronized way to call switchAxis. Use this if caller is not on UI thread.
+     * @param axis @param axis SensorManager.AXIS_X or SensorManager.AXIS_Y or SensorManager.AXIS_Z
+     */
+    public void switchAxisAsync(int axis) {
+        // intended to be called from a non-UI thread
+        final int fAxis = axis;
+        runOnUiThread(new Runnable() {
+            public void run() {
+                // UI code goes here
+                switchAxis(fAxis);
+            }
+        });
+    }
+
+    /**
+     * Initialize sound pool for user notification
+     */
+    private void initSoundPool() {
+        final int MAX_STREAM = 10;
+        int i=0;
+        mSoundPool = new SoundPool(MAX_STREAM, AudioManager.STREAM_MUSIC, 0);
+        mSoundPoolLookup = new int[MAX_STREAM];
+
+        // TODO: add different sound into this
+        mSoundPoolLookup[i++] = mSoundPool.load(this, R.raw.next_axis, 1);
+        mSoundPoolLookup[i++] = mSoundPool.load(this, R.raw.next_axis, 1);
+        mSoundPoolLookup[i++] = mSoundPool.load(this, R.raw.next_axis, 1);
+
+    }
+    private void endSoundPool() {
+        mSoundPool.release();
+    }
+
+    /**
+     * Play notify sound to user
+     * @param id ID of the sound to be played
+     */
+    public void playNotifySound(int id) {
+        mSoundPool.play(mSoundPoolLookup[id], 1, 1, 0, 0, 1);
+    }
+
+    /**
+     * Start the sensor recording
+     */
+    public void startRecordSensor() {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                mRVSensorLogger.init();
+                if (LOG_RAW_SENSORS) {
+                    mRawSensorLogger.init();
+                }
+            }
+        });
+    }
+
+    /**
+     * Stop the sensor recording
+     */
+    public void stopRecordSensor() {
+        runOnUiThread(new Runnable() {
+            public void run() {
+                mRVSensorLogger.end();
+                if (LOG_RAW_SENSORS) {
+                    mRawSensorLogger.end();
+                }
+            }
+        });
+    }
+
+    /**
+     * Start video recording
+     */
+    public void startRecordVideo() {
+        mVideoRecorder.init();
+    }
+
+    /**
+     * Stop video recording
+     */
+    public void stopRecordVideo() {
+        mVideoRecorder.end();
+    }
+
+    /**
+     * Wait until a sensor recording for a certain axis is fully covered
+     * @param axis
+     */
+    public void waitUntilCovered(int axis) {
+        mCoverManager.waitUntilCovered(axis);
+    }
+
+
+    /**
+     *
+     */
+    private void initStoragePath() {
+        File rxcvRecDataDir = new File(Environment.getExternalStorageDirectory(),"RVCVRecData");
+
+        // Create the storage directory if it does not exist
+        if (! rxcvRecDataDir.exists()) {
+            if (! rxcvRecDataDir.mkdirs()) {
+                Log.e(TAG, "failed to create main data directory");
+            }
+        }
+
+        mRecordDir = new File(rxcvRecDataDir, new SimpleDateFormat("yyMMdd-hhmmss").format(new Date()));
+
+        if (! mRecordDir.mkdirs()) {
+            Log.e(TAG, "failed to create rec data directory");
+        }
+    }
+
+    /**
+     * Get the sensor log file path
+     * @return Path of the sensor log file
+     */
+    public String getSensorLogFilePath() {
+        return new File(mRecordDir, "sensor.log").getPath();
+    }
+
+    /**
+     * Get the video recording file path
+     * @return Path of the video recording file
+     */
+    public String getVideoRecFilePath() {
+        return new File(mRecordDir, "video.mp4").getPath();
+    }
+
+    /**
+     * Write out important camera/video information to a JSON file
+     * @param width         width of frame
+     * @param height        height of frame
+     * @param frameRate     frame rate in fps
+     * @param fovW          field of view in width direction
+     * @param fovH          field of view in height direction
+     */
+    public void writeVideoMetaInfo(int width, int height, float frameRate, float fovW, float fovH) {
+        try {
+            JsonWriter writer =
+                    new JsonWriter(
+                        new OutputStreamWriter(
+                                new FileOutputStream(
+                                        new File(mRecordDir, "videometa.json").getPath()
+                                )
+                        )
+                    );
+            writer.beginObject();
+            writer.name("fovW").value(fovW);
+            writer.name("fovH").value(fovH);
+            writer.name("width").value(width);
+            writer.name("height").value(height);
+            writer.name("frameRate").value(frameRate);
+            writer.endObject();
+
+            writer.close();
+        }catch (FileNotFoundException e) {
+            // Not very likely to happen
+            e.printStackTrace();
+        }catch (IOException e) {
+            // do nothing
+            e.printStackTrace();
+            Log.e(TAG, "Writing video meta data failed.");
+        }
+    }
+
+    /**
+     * Camera preview control class
+     */
+    class CameraContext {
+        private Camera mCamera;
+        private CamcorderProfile mProfile;
+        private Camera.CameraInfo mCameraInfo;
+
+        private int [] mPreferredProfiles = {
+                CamcorderProfile.QUALITY_480P,  // smaller -> faster
+                CamcorderProfile.QUALITY_720P,
+                CamcorderProfile.QUALITY_1080P,
+                CamcorderProfile.QUALITY_HIGH // existence guaranteed
+        };
+
+        CameraContext() {
+            try {
+                mCamera = Camera.open(); // attempt to get a default Camera instance (0)
+                mProfile = null;
+                if (mCamera != null) {
+                    mCameraInfo = new Camera.CameraInfo();
+                    Camera.getCameraInfo(0, mCameraInfo);
+                    setupCamera();
+                }
+            }
+            catch (Exception e){
+                // Camera is not available (in use or does not exist)
+                Log.e(TAG, "Cannot obtain Camera!");
+            }
+        }
+
+        /**
+         * Find a preferred camera profile and set preview and picture size property accordingly.
+         */
+        void setupCamera() {
+            CamcorderProfile profile = null;
+            Camera.Parameters param = mCamera.getParameters();
+            List<Camera.Size> pre_sz = param.getSupportedPreviewSizes();
+            List<Camera.Size> pic_sz = param.getSupportedPictureSizes();
+
+            for (int i : mPreferredProfiles) {
+                if (CamcorderProfile.hasProfile(i)) {
+                    profile = CamcorderProfile.get(i);
+
+                    int valid = 0;
+                    for (Camera.Size j : pre_sz) {
+                        if (j.width == profile.videoFrameWidth &&
+                                j.height == profile.videoFrameHeight) {
+                            ++valid;
+                            break;
+                        }
+                    }
+                    for (Camera.Size j : pic_sz) {
+                        if (j.width == profile.videoFrameWidth &&
+                                j.height == profile.videoFrameHeight) {
+                            ++valid;
+                            break;
+                        }
+                    }
+                    if (valid == 2) {
+                        param.setPreviewSize(profile.videoFrameWidth, profile.videoFrameHeight);
+                        param.setPictureSize(profile.videoFrameWidth, profile.videoFrameHeight);
+                        mCamera.setParameters(param);
+                        break;
+                    } else {
+                        profile = null;
+                    }
+                }
+            }
+            if (profile != null) {
+                float fovW = param.getHorizontalViewAngle();
+                float fovH = param.getVerticalViewAngle();
+                writeVideoMetaInfo(profile.videoFrameWidth, profile.videoFrameHeight,
+                        profile.videoFrameRate, fovW, fovH);
+            } else {
+                Log.e(TAG, "Cannot find a proper video profile");
+            }
+            mProfile = profile;
+
+        }
+
+
+        /**
+         * Get sensor information of the camera being used
+         */
+        public Camera.CameraInfo getCameraInfo() {
+            return mCameraInfo;
+        }
+
+        /**
+         * Get the camera to be previewed
+         * @return Reference to Camera used
+         */
+        public Camera getCamera() {
+            return mCamera;
+        }
+
+        /**
+         * Get the camera profile to be used
+         * @return Reference to Camera profile
+         */
+        public CamcorderProfile getProfile() {
+            return mProfile;
+        }
+
+        /**
+         * Setup the camera
+         */
+        public void init() {
+            if (mCamera != null) {
+                double alpha = mCamera.getParameters().getHorizontalViewAngle()*Math.PI/180.0;
+                int width = mProfile.videoFrameWidth;
+                double fx = width/2/Math.tan(alpha/2.0);
+
+                if (LOCAL_LOGV) Log.v(TAG, "View angle="
+                        + mCamera.getParameters().getHorizontalViewAngle() +"  Estimated fx = "+fx);
+
+                RVCVCameraPreview cameraPreview =
+                        (RVCVCameraPreview) findViewById(R.id.cam_preview);
+                cameraPreview.init(mCamera,
+                        (float)mProfile.videoFrameWidth/mProfile.videoFrameHeight,
+                        mCameraInfo.orientation);
+            } else {
+                message("Cannot open camera!");
+                finish();
+            }
+        }
+
+        /**
+         * End the camera preview
+         */
+        public void end() {
+            if (mCamera != null) {
+                mCamera.release();        // release the camera for other applications
+                mCamera = null;
+            }
+        }
+    }
+
+    /**
+     * Manage a set of RangeCoveredRegister objects
+     */
+    class CoverageManager {
+        // settings
+        private final int MAX_TILT_ANGLE = 60; // +/- 60
+        //private final int REQUIRED_TILT_ANGLE = 50; // +/- 50
+        private final int TILT_ANGLE_STEP = 5; // 5 degree(s) per step
+        private final int YAW_ANGLE_STEP = 10; // 10 degree(s) per step
+
+        RangeCoveredRegister[] mAxisCovered;
+
+        CoverageManager() {
+            mAxisCovered = new RangeCoveredRegister[3];
+            // X AXIS
+            mAxisCovered[0] = new RangeCoveredRegister(-MAX_TILT_ANGLE, +MAX_TILT_ANGLE, TILT_ANGLE_STEP);
+            // Y AXIS
+            mAxisCovered[1] = new RangeCoveredRegister(-MAX_TILT_ANGLE, +MAX_TILT_ANGLE, TILT_ANGLE_STEP);
+            // Z AXIS
+            mAxisCovered[2] = new RangeCoveredRegister(YAW_ANGLE_STEP);
+        }
+
+        public RangeCoveredRegister getAxis(int axis) {
+            // SensorManager.AXIS_X = 1, need offset -1 for mAxisCovered array
+            return mAxisCovered[axis-1];
+        }
+
+        public void waitUntilCovered(int axis) {
+            // SensorManager.AXIS_X = 1, need offset -1 for mAxisCovered array
+            while(!mAxisCovered[axis-1].isFullyCovered()) {
+                try {
+                    Thread.sleep(500);
+                } catch (InterruptedException e) {
+                    if (LOCAL_LOGV) {
+                        Log.v(TAG, "waitUntilCovered axis = "+ axis + " is interrupted");
+                    }
+                }
+            }
+        }
+    }
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * A class controls the video recording
+     */
+    class VideoRecorder
+    {
+        private MediaRecorder mRecorder;
+        private CamcorderProfile mProfile;
+        private Camera mCamera;
+        private boolean mRunning = false;
+
+        VideoRecorder(Camera camera, CamcorderProfile profile){
+            mCamera = camera;
+            mProfile = profile;
+        }
+
+        /**
+         * Initialize and start recording
+         */
+        public void init() {
+            if (mCamera == null  || mProfile ==null){
+                return;
+            }
+
+            mRecorder = new MediaRecorder();
+            mCamera.unlock();
+            mRecorder.setCamera(mCamera);
+
+            mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+            mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
+
+            mRecorder.setProfile(mProfile);
+
+            try {
+                mRecorder.setOutputFile(getVideoRecFilePath());
+                mRecorder.prepare();
+            } catch (IOException e) {
+                Log.e(TAG, "Preparation for recording failed.");
+                return;
+            }
+
+            try {
+                mRecorder.start();
+            } catch (RuntimeException e) {
+                Log.e(TAG, "Starting recording failed.");
+                mRecorder.reset();
+                mRecorder.release();
+                mCamera.lock();
+                return;
+            }
+            mRunning = true;
+        }
+
+        /**
+         * Stop recording
+         */
+        public void end() {
+            if (mRunning) {
+                try {
+                    mRecorder.stop();
+                    mRecorder.reset();
+                    mRecorder.release();
+                    mCamera.lock();
+                } catch (RuntimeException e) {
+                    e.printStackTrace();
+                    Log.e(TAG, "Runtime error in stopping recording.");
+                }
+            }
+            mRecorder = null;
+        }
+
+    }
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     *  Log all raw sensor readings, for Rotation Vector sensor algorithms research
+     */
+    class RawSensorLogger implements SensorEventListener {
+        private final String TAG = "RawSensorLogger";
+
+        private final static int SENSOR_RATE = SensorManager.SENSOR_DELAY_FASTEST;
+        private File mRecPath;
+
+        SensorManager mSensorManager;
+        Sensor mAccSensor, mGyroSensor, mMagSensor;
+        OutputStreamWriter mAccLogWriter, mGyroLogWriter, mMagLogWriter;
+
+        private float[] mRTemp = new float[16];
+
+        RawSensorLogger(File recPath) {
+            mRecPath = recPath;
+        }
+
+        /**
+         * Initialize and start recording
+         */
+        public void init() {
+            mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
+
+            mAccSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+            mGyroSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED);
+            mMagSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED);
+
+            mSensorManager.registerListener(this, mAccSensor, SENSOR_RATE);
+            mSensorManager.registerListener(this, mGyroSensor, SENSOR_RATE);
+            mSensorManager.registerListener(this, mMagSensor, SENSOR_RATE);
+
+            try {
+                mAccLogWriter= new OutputStreamWriter(
+                        new FileOutputStream(new File(mRecPath, "raw_acc.log")));
+                mGyroLogWriter= new OutputStreamWriter(
+                        new FileOutputStream(new File(mRecPath, "raw_uncal_gyro.log")));
+                mMagLogWriter= new OutputStreamWriter(
+                        new FileOutputStream(new File(mRecPath, "raw_uncal_mag.log")));
+
+            } catch (FileNotFoundException e) {
+                Log.e(TAG, "Sensor log file open failed: " + e.toString());
+            }
+        }
+
+        /**
+         * Stop recording and clean up
+         */
+        public void end() {
+            mSensorManager.flush(this);
+            mSensorManager.unregisterListener(this);
+
+            try {
+                if (mAccLogWriter != null) {
+                    OutputStreamWriter writer = mAccLogWriter;
+                    mAccLogWriter = null;
+                    writer.close();
+                }
+                if (mGyroLogWriter != null) {
+                    OutputStreamWriter writer = mGyroLogWriter;
+                    mGyroLogWriter = null;
+                    writer.close();
+                }
+                if (mMagLogWriter != null) {
+                    OutputStreamWriter writer = mMagLogWriter;
+                    mMagLogWriter = null;
+                    writer.close();
+                }
+
+            } catch (IOException e) {
+                Log.e(TAG, "Sensor log file close failed: " + e.toString());
+            }
+        }
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int i) {
+            // do not care
+        }
+
+        @Override
+        public void onSensorChanged(SensorEvent event) {
+            OutputStreamWriter writer=null;
+            switch(event.sensor.getType()) {
+                case Sensor.TYPE_ACCELEROMETER:
+                    writer = mAccLogWriter;
+                    break;
+                case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
+                    writer = mGyroLogWriter;
+                    break;
+                case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+                    writer = mMagLogWriter;
+                    break;
+
+            }
+            if (writer!=null)  {
+                float[] data = event.values;
+                try {
+                    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
+                        writer.write(String.format("%d %f %f %f\r\n",
+                                event.timestamp, data[0], data[1], data[2]));
+                    }else // TYPE_GYROSCOPE_UNCALIBRATED and TYPE_MAGNETIC_FIELD_UNCALIBRATED
+                    {
+                        writer.write(String.format("%d %f %f %f %f %f %f\r\n", event.timestamp,
+                                data[0], data[1], data[2], data[3], data[4], data[5]));
+                    }
+                }catch (IOException e)
+                {
+                    Log.e(TAG, "Write to raw sensor log file failed.");
+                }
+
+            }
+        }
+    }
+
+    /**
+     *  Rotation sensor logger class
+     */
+    class RVSensorLogger implements SensorEventListener {
+        private final String TAG = "RVSensorLogger";
+
+        private final static int SENSOR_RATE = SensorManager.SENSOR_DELAY_FASTEST;
+        RangeCoveredRegister mRegister;
+        int mAxis;
+        RVCVRecordActivity mActivity;
+
+        SensorManager mSensorManager;
+        Sensor mRVSensor;
+        OutputStreamWriter mLogWriter;
+
+        private float[] mRTemp = new float[16];
+
+        RVSensorLogger(RVCVRecordActivity activity) {
+            mActivity = activity;
+        }
+
+        /**
+         * Initialize and start recording
+         */
+        public void init() {
+            mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
+            if (mSensorManager == null) {
+                Log.e(TAG,"SensorManager is null!");
+            }
+            mRVSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
+            if (mRVSensor != null) {
+                if (LOCAL_LOGV) Log.v(TAG, "Got RV Sensor");
+            }else {
+                Log.e(TAG, "Did not get RV sensor");
+            }
+            if(mSensorManager.registerListener(this, mRVSensor, SENSOR_RATE)) {
+                if (LOCAL_LOGV) Log.v(TAG,"Register listener successfull");
+            } else {
+                Log.e(TAG,"Register listener failed");
+            }
+
+            try {
+                mLogWriter= new OutputStreamWriter(
+                        new FileOutputStream(mActivity.getSensorLogFilePath()));
+            } catch (FileNotFoundException e) {
+                Log.e(TAG, "Sensor log file open failed: " + e.toString());
+            }
+        }
+
+        /**
+         * Stop recording and clean up
+         */
+        public void end() {
+            mSensorManager.flush(this);
+            mSensorManager.unregisterListener(this);
+
+            try {
+                if (mLogWriter != null) {
+                    OutputStreamWriter writer = mLogWriter;
+                    mLogWriter = null;
+                    writer.close();
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Sensor log file close failed: " + e.toString());
+            }
+
+            updateRegister(null, AXIS_NONE);
+        }
+
+        private void onNewData(float[] data, long timestamp) {
+            // LOG
+            try {
+                if (mLogWriter != null) {
+                    mLogWriter.write(String.format("%d %f %f %f %f\r\n", timestamp,
+                            data[3], data[0], data[1], data[2]));
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "Sensor log file write failed: " + e.toString());
+            }
+
+            // Update UI
+            if (mRegister != null) {
+                int d = 0;
+                int dx, dy, dz;
+                boolean valid = false;
+                SensorManager.getRotationMatrixFromVector(mRTemp, data);
+
+                dx = (int)(Math.asin(mRTemp[8])*(180.0/Math.PI));
+                dy = (int)(Math.asin(mRTemp[9])*(180.0/Math.PI));
+                dz = (int)((Math.atan2(mRTemp[4], mRTemp[0])+Math.PI)*(180.0/Math.PI));
+
+                switch(mAxis) {
+                    case SensorManager.AXIS_X:
+                        d = dx;
+                        valid = (Math.abs(dy) < 30);
+                        break;
+                    case SensorManager.AXIS_Y:
+                        d = dy;
+                        valid = (Math.abs(dx) < 30);
+                        break;
+                    case SensorManager.AXIS_Z:
+                        d = dz;
+                        valid = (Math.abs(dx) < 20 && Math.abs(dy) < 20);
+                        break;
+                }
+
+                if (valid) {
+                    mRegister.update(d);
+                    mActivity.redrawIndicator();
+                }
+            }
+
+        }
+
+        public void updateRegister(RangeCoveredRegister reg, int axis) {
+            mRegister = reg;
+            mAxis = axis;
+        }
+
+
+        @Override
+        public void onAccuracyChanged(Sensor sensor, int i) {
+            // do not care
+        }
+
+        @Override
+        public void onSensorChanged(SensorEvent event) {
+            if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
+                onNewData(event.values, event.timestamp);
+            }
+        }
+    }
+
+
+    ////////////////////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Controls the over all logic of record procedure: first x-direction, then y-direction and
+     * then z-direction.
+     */
+    class RecordProcedureController implements Runnable {
+        private static final boolean LOCAL_LOGV = false;
+
+        private final RVCVRecordActivity mActivity;
+        private Thread mThread = null;
+
+        RecordProcedureController(RVCVRecordActivity activity) {
+            mActivity = activity;
+            mThread = new Thread(this);
+            mThread.start();
+        }
+
+        /**
+         * Run the record procedure
+         */
+        public void run() {
+            if (LOCAL_LOGV) Log.v(TAG, "Controller Thread Started.");
+            //start recording & logging
+            delay(2000);
+
+            init();
+            if (LOCAL_LOGV) Log.v(TAG, "Controller Thread init() finished.");
+
+            // test 3 axis
+            // It is in YXZ order because UI element design use opposite definition
+            // of XY axis. To ensure the user see X Y Z, it is flipped here.
+            recordAxis(SensorManager.AXIS_Y);
+            if (LOCAL_LOGV) Log.v(TAG, "Controller Thread axis 0 finished.");
+
+            recordAxis(SensorManager.AXIS_X);
+            if (LOCAL_LOGV) Log.v(TAG, "Controller Thread axis 1 finished.");
+
+            recordAxis(SensorManager.AXIS_Z);
+            if (LOCAL_LOGV) Log.v(TAG, "Controller Thread axis 2 finished.");
+
+            delay(1000);
+            end();
+            if (LOCAL_LOGV) Log.v(TAG, "Controller Thread End.");
+        }
+
+        private void delay(int milli) {
+            try{
+                Thread.sleep(milli);
+            } catch(InterruptedException e) {
+                if (LOCAL_LOGV) Log.v(TAG, "Controller Thread Interrupted.");
+            }
+        }
+        private void init() {
+            // start video recording
+            mActivity.startRecordVideo();
+
+            // start sensor logging & listening
+            mActivity.startRecordSensor();
+        }
+
+        private void end() {
+            // stop video recording
+            mActivity.stopRecordVideo();
+
+            // stop sensor logging
+            mActivity.stopRecordSensor();
+
+            // notify ui complete
+            runOnUiThread(new Runnable(){
+                public void run() {
+                    mActivity.notifyComplete();
+                }
+            });
+        }
+
+        private void recordAxis(int axis) {
+            // delay 2 seconds?
+            delay(1000);
+
+            // change ui
+            mActivity.switchAxisAsync(axis);
+
+            // play start sound
+            mActivity.playNotifySound(0);
+
+            // wait until axis covered
+            mActivity.waitUntilCovered(axis);
+
+            // play stop sound
+            mActivity.playNotifySound(1);
+        }
+
+        /**
+         * Force quit
+         */
+        public void quit() {
+            mThread.interrupt();
+            try {
+                if (LOCAL_LOGV) Log.v(TAG, "Wait for controller to end");
+
+                // stop video recording
+                mActivity.stopRecordVideo();
+
+                // stop sensor logging
+                mActivity.stopRecordSensor();
+
+            } catch (Exception e)
+            {
+                e.printStackTrace();
+            }
+        }
+    }
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
new file mode 100644
index 0000000..3dc7270
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckAnalyzer.java
@@ -0,0 +1,1322 @@
+package com.android.cts.verifier.sensors;
+
+/*
+ * 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.
+ */
+import android.media.MediaCodec;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.os.Debug;
+import android.os.Environment;
+import android.os.PowerManager;
+import android.util.JsonWriter;
+import android.util.Log;
+
+import org.opencv.core.Mat;
+import org.opencv.core.CvType;
+import org.opencv.core.MatOfDouble;
+import org.opencv.core.MatOfFloat;
+import org.opencv.core.MatOfPoint2f;
+import org.opencv.core.MatOfPoint3f;
+import org.opencv.core.Size;
+import org.opencv.highgui.Highgui;
+import org.opencv.imgproc.Imgproc;
+import org.opencv.calib3d.Calib3d;
+import org.opencv.core.Core;
+
+import org.json.JSONObject;
+import org.json.JSONException;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+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.io.OutputStreamWriter;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+
+import android.opengl.GLES20;
+import javax.microedition.khronos.opengles.GL10;
+
+/**
+ *  This class does analysis on the recorded RVCVCXCheck data sets.
+ */
+public class RVCVXCheckAnalyzer {
+    private static final String TAG = "RVCVXAnalysis";
+    private static final boolean LOCAL_LOGV = false;
+    private static final boolean LOCAL_LOGD = true;
+    private final String mPath;
+
+    private static final boolean OUTPUT_DEBUG_IMAGE = false;
+    private static final double VALID_FRAME_THRESHOLD = 0.8;
+    private static final double REPROJECTION_THREASHOLD = 4.0;
+    private static final boolean FORCE_CV_ANALYSIS  = false;
+    private static final boolean TRACE_VIDEO_ANALYSIS = false;
+    private static final double DECIMATION_FPS_TARGET = 15.0;
+
+    RVCVXCheckAnalyzer(String path)
+    {
+        mPath = path;
+    }
+
+    /**
+     * A class that contains  the analysis results
+     *
+     */
+    class AnalyzeReport {
+        public boolean error=true;
+        public String reason = "incomplete";
+
+        // roll pitch yaw RMS error ( \sqrt{\frac{1}{n} \sum e_i^2 })
+        // unit in rad
+        public double roll_rms_error;
+        public double pitch_rms_error;
+        public double yaw_rms_error;
+
+        // roll pitch yaw max error
+        // unit in rad
+        public double roll_max_error;
+        public double pitch_max_error;
+        public double yaw_max_error;
+
+        // optimal t delta between sensor and camera data set to make best match
+        public double optimal_delta_t;
+        // the associate yaw offset based on initial values
+        public double yaw_offset;
+
+        public int n_of_frame;
+        public int n_of_valid_frame;
+
+        // both data below are in [sec]
+        public double sensor_period_avg;
+        public double sensor_period_stdev;
+
+        /**
+         * write Json format serialization to a file in case future processing need the data
+         */
+        public void writeToFile(File file) {
+            try {
+                writeJSONToStream(new FileOutputStream(file));
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+                Log.e(TAG, "Cannot create analyze report file.");
+            }
+        }
+
+        /**
+         * Get the JSON format serialization
+         *@return Json format serialization as String
+         */
+        @Override
+        public String toString() {
+            ByteArrayOutputStream s = new ByteArrayOutputStream();
+            writeJSONToStream(s);
+            return new String(s.toByteArray(),  java.nio.charset.StandardCharsets.UTF_8);
+        }
+
+        private void writeJSONToStream(OutputStream s) {
+            try{
+                JsonWriter writer =
+                        new JsonWriter(
+                                new OutputStreamWriter( s )
+                        );
+                writer.beginObject();
+                writer.setLenient(true);
+
+                writer.name("roll_rms_error").value(roll_rms_error);
+                writer.name("pitch_rms_error").value(pitch_rms_error);
+                writer.name("yaw_rms_error").value(yaw_rms_error);
+                writer.name("roll_max_error").value(roll_max_error);
+                writer.name("pitch_max_error").value(pitch_max_error);
+                writer.name("yaw_max_error").value(yaw_max_error);
+                writer.name("optimal_delta_t").value(optimal_delta_t);
+                writer.name("yaw_offset").value(yaw_offset);
+                writer.name("n_of_frame").value(n_of_frame);
+                writer.name("n_of_valid_frame").value(n_of_valid_frame);
+                writer.name("sensor_period_avg").value(sensor_period_avg);
+                writer.name("sensor_period_stdev").value(sensor_period_stdev);
+
+                writer.endObject();
+
+                writer.close();
+            } catch (IOException e) {
+                // do nothing
+                Log.e(TAG, "Error in serialize analyze report to JSON");
+            } catch (IllegalArgumentException e) {
+                e.printStackTrace();
+                Log.e(TAG, "Invalid parameter to write into JSON format");
+            }
+        }
+    }
+
+    /**
+     *  Process data set stored in the path specified in constructor
+     *  and return an analyze report to caller
+     *
+     *  @return An AnalyzeReport that contains detailed information about analysis
+     */
+    public AnalyzeReport processDataSet() {
+        int nframe;// number of frames in video
+        int nslog; // number of sensor log
+        int nvlog; // number of video generated log
+
+
+        AnalyzeReport report = new AnalyzeReport();
+
+        ArrayList<AttitudeRec> srecs = new ArrayList<>();
+        ArrayList<AttitudeRec> vrecs = new ArrayList<>();
+        ArrayList<AttitudeRec> srecs2 = new ArrayList<>();
+
+
+        final boolean use_solved = new File(mPath, "vision_rpy.log").exists() && !FORCE_CV_ANALYSIS;
+
+        if (use_solved) {
+            nframe = nvlog = loadAttitudeRecs(new File(mPath, "vision_rpy.log"), vrecs);
+            nslog = loadAttitudeRecs(new File(mPath, "sensor_rpy.log"),srecs);
+        }else {
+            nframe = analyzeVideo(vrecs);
+            nvlog = vrecs.size();
+
+            if (LOCAL_LOGV) {
+                Log.v(TAG, "Post video analysis nvlog = " + nvlog + " nframe=" + nframe);
+            }
+            if (nvlog <= 0 || nframe <= 0) {
+                // invalid results
+                report.reason = "Unable to to load recorded video.";
+                return report;
+            }
+            if ((double) nvlog / nframe < VALID_FRAME_THRESHOLD) {
+                // too many invalid frames
+                Log.w(TAG, "Too many invalid frames, n valid frame = " + nvlog +
+                        ", n total frame = " + nframe);
+                report.reason = "Too many invalid frames.";
+                return report;
+            }
+
+            fixFlippedAxis(vrecs);
+
+            nslog = loadSensorLog(srecs);
+        }
+
+        // Gradient descent will have faster performance than this simple search,
+        // but the performance is dominated by the vision part, so it is not very necessary.
+        double delta_t;
+        double min_rms = Double.MAX_VALUE;
+        double min_delta_t =0.;
+        double min_yaw_offset =0.;
+
+        // pre-allocation
+        for (AttitudeRec i: vrecs) {
+            srecs2.add(new AttitudeRec(0,0,0,0));
+        }
+
+        // find optimal offset
+        for (delta_t = -2.0; delta_t<2.0; delta_t +=0.01) {
+            double rms;
+            resampleSensorLog(srecs, vrecs, delta_t, 0.0, srecs2);
+            rms = Math.sqrt(calcSqrErr(vrecs, srecs2, 0)+ calcSqrErr(vrecs, srecs2, 1));
+            if (rms < min_rms) {
+                min_rms = rms;
+                min_delta_t = delta_t;
+                min_yaw_offset = vrecs.get(0).yaw - srecs2.get(0).yaw;
+            }
+        }
+        // sample at optimal offset
+        resampleSensorLog(srecs, vrecs, min_delta_t, min_yaw_offset, srecs2);
+
+        if (!use_solved) {
+            dumpAttitudeRecs(new File(mPath, "vision_rpy.log"), vrecs);
+            dumpAttitudeRecs(new File(mPath, "sensor_rpy.log"), srecs);
+        }
+        dumpAttitudeRecs(new File(mPath, "sensor_rpy_resampled.log"), srecs2);
+        dumpAttitudeError(new File(mPath, "attitude_error.log"), vrecs, srecs2);
+
+        // fill report fields
+        report.roll_rms_error = Math.sqrt(calcSqrErr(vrecs, srecs2, 0));
+        report.pitch_rms_error = Math.sqrt(calcSqrErr(vrecs, srecs2, 1));
+        report.yaw_rms_error = Math.sqrt(calcSqrErr(vrecs, srecs2, 2));
+
+        report.roll_max_error = calcMaxErr(vrecs, srecs2, 0);
+        report.pitch_max_error = calcMaxErr(vrecs, srecs2, 1);
+        report.yaw_max_error = calcMaxErr(vrecs, srecs2, 2);
+
+        report.optimal_delta_t = min_delta_t;
+        report.yaw_offset = (min_yaw_offset);
+
+        report.n_of_frame = nframe;
+        report.n_of_valid_frame = nvlog;
+
+        double [] sensor_period_stat = calcSensorPeriodStat(srecs);
+        report.sensor_period_avg = sensor_period_stat[0];
+        report.sensor_period_stdev = sensor_period_stat[1];
+
+        // output report to file and log in JSON format as well
+        report.writeToFile(new File(mPath, "report.json"));
+        if (LOCAL_LOGV)    Log.v(TAG, "Report in JSON:" + report.toString());
+
+        report.reason = "Completed";
+        report.error = false;
+        return report;
+    }
+
+    /**
+     * Generate pattern geometry like this one
+     * http://docs.opencv.org/trunk/_downloads/acircles_pattern.png
+     *
+     * @return Array of 3D points
+     */
+    private MatOfPoint3f asymmetricalCircleGrid(Size size) {
+        final int cn = 3;
+
+        int n = (int)(size.width * size.height);
+        float positions[] = new float[n * cn];
+        float unit=0.02f;
+        MatOfPoint3f grid = new MatOfPoint3f();
+
+        for (int i = 0; i < size.height; i++) {
+            for (int j = 0; j < size.width * cn; j += cn) {
+                positions[(int) (i * size.width * cn + j + 0)] =
+                        (2 * (j / cn) + i % 2) * (float) unit;
+                positions[(int) (i * size.width * cn + j + 1)] =
+                        i * unit;
+                positions[(int) (i * size.width * cn + j + 2)] = 0;
+            }
+        }
+        grid.create(n, 1, CvType.CV_32FC3);
+        grid.put(0, 0, positions);
+        return grid;
+    }
+
+    /**
+     *  Create a camera intrinsic matrix using input parameters
+     *
+     *  The camera intrinsic matrix will be like:
+     *
+     *       +-                       -+
+     *       |  f   0    center.width  |
+     *   A = |  0   f    center.height |
+     *       |  0   0         1        |
+     *       +-                       -+
+     *
+     *  @return An approximated (not actually calibrated) camera matrix
+     */
+    private static Mat cameraMatrix(float f, Size center) {
+        final double [] data = {f, 0, center.width, 0, f, center.height, 0, 0, 1f};
+        Mat m = new Mat(3,3, CvType.CV_64F);
+        m.put(0, 0, data);
+        return m;
+    }
+
+    /**
+     *  Attitude record in time roll pitch yaw format.
+     *
+     */
+    private class AttitudeRec {
+        public double time;
+        public double roll;
+        public double pitch;
+        public double yaw;
+
+        // ctor
+        AttitudeRec(double atime, double aroll, double apitch, double ayaw) {
+            time = atime;
+            roll = aroll;
+            pitch = apitch;
+            yaw = ayaw;
+        }
+
+        // ctor
+        AttitudeRec(double atime, double [] rpy) {
+            time = atime;
+            roll = rpy[0];
+            pitch = rpy[1];
+            yaw = rpy[2];
+        }
+
+        // copy value of another to this
+        void assign(AttitudeRec rec) {
+            time = rec.time;
+            roll = rec.time;
+            pitch = rec.pitch;
+            yaw = rec.yaw;
+        }
+
+        // copy roll-pitch-yaw value but leave the time specified by atime
+        void assign(AttitudeRec rec, double atime) {
+            time = atime;
+            roll = rec.time;
+            pitch = rec.pitch;
+            yaw = rec.yaw;
+        }
+
+        // set each field separately
+        void set(double atime, double aroll, double apitch, double ayaw) {
+            time = atime;
+            roll = aroll;
+            pitch = apitch;
+            yaw = ayaw;
+        }
+    }
+
+
+    /**
+     *  Load the sensor log in (time Roll-pitch-yaw) format to a ArrayList<AttitudeRec>
+     *
+     *  @return the number of sensor log items
+     */
+    private int loadSensorLog(ArrayList<AttitudeRec> recs) {
+        //ArrayList<AttitudeRec> recs = new ArrayList<AttitudeRec>();
+        File csvFile = new File(mPath, "sensor.log");
+        BufferedReader br=null;
+        String line;
+
+        // preallocate and reuse
+        double [] quat = new double[4];
+        double [] rpy = new double[3];
+
+        double t0 = -1;
+
+        try {
+            br = new BufferedReader(new FileReader(csvFile));
+            while ((line = br.readLine()) != null) {
+                //space separator
+                String[] items = line.split(" ");
+
+                if (items.length != 5) {
+                    recs.clear();
+                    return -1;
+                }
+
+                quat[0] = Double.parseDouble(items[1]);
+                quat[1] = Double.parseDouble(items[2]);
+                quat[2] = Double.parseDouble(items[3]);
+                quat[3] = Double.parseDouble(items[4]);
+
+                //
+                quat2rpy(quat, rpy);
+
+                if (t0 < 0) {
+                    t0 = Long.parseLong(items[0])/1e9;
+                }
+                recs.add(new AttitudeRec(Long.parseLong(items[0])/1e9-t0, rpy));
+            }
+
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            Log.e(TAG, "Cannot find sensor logging data");
+        } catch (IOException e) {
+            e.printStackTrace();
+            Log.e(TAG, "Cannot read sensor logging data");
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return recs.size();
+    }
+
+    /**
+     * Read video meta info
+     */
+    private class VideoMetaInfo {
+        public double fps;
+        public int frameWidth;
+        public int frameHeight;
+        public double fovWidth;
+        public double fovHeight;
+        public boolean valid = false;
+
+        VideoMetaInfo(File file) {
+
+            BufferedReader br=null;
+            String line;
+            String content="";
+            try {
+                br = new BufferedReader(new FileReader(file));
+                while ((line = br.readLine()) != null) {
+                    content = content +line;
+                }
+
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+                Log.e(TAG, "Cannot find video meta info file");
+            } catch (IOException e) {
+                e.printStackTrace();
+                Log.e(TAG, "Cannot read video meta info file");
+            } finally {
+                if (br != null) {
+                    try {
+                        br.close();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+
+            if (content.isEmpty()) {
+                return;
+            }
+
+            try {
+                JSONObject json = new JSONObject(content);
+                frameWidth = json.getInt("width");
+                frameHeight = json.getInt("height");
+                fps = json.getDouble("frameRate");
+                fovWidth = json.getDouble("fovW")*Math.PI/180.0;
+                fovHeight = json.getDouble("fovH")*Math.PI/180.0;
+            } catch (JSONException e) {
+                return;
+            }
+
+            valid = true;
+
+        }
+    }
+
+
+
+    /**
+     * Debugging helper function, load ArrayList<AttitudeRec> from a file dumped out by
+     * dumpAttitudeRecs
+     */
+    private int loadAttitudeRecs(File file, ArrayList<AttitudeRec> recs) {
+        BufferedReader br=null;
+        String line;
+        double time;
+        double [] rpy = new double[3];
+
+        try {
+            br = new BufferedReader(new FileReader(file));
+            while ((line = br.readLine()) != null) {
+                //space separator
+                String[] items = line.split(" ");
+
+                if (items.length != 4) {
+                    recs.clear();
+                    return -1;
+                }
+
+                time = Double.parseDouble(items[0]);
+                rpy[0] = Double.parseDouble(items[1]);
+                rpy[1] = Double.parseDouble(items[2]);
+                rpy[2] = Double.parseDouble(items[3]);
+
+                recs.add(new AttitudeRec(time, rpy));
+            }
+
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            Log.e(TAG, "Cannot find AttitudeRecs file specified.");
+        } catch (IOException e) {
+            e.printStackTrace();
+            Log.e(TAG, "Read AttitudeRecs file failure");
+        } finally {
+            if (br != null) {
+                try {
+                    br.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+
+        return recs.size();
+    }
+    /**
+     * Debugging helper function, Dump an ArrayList<AttitudeRec> to a file
+     */
+    private void dumpAttitudeRecs(File file, ArrayList<AttitudeRec> recs) {
+        OutputStreamWriter w=null;
+        try {
+            w = new OutputStreamWriter(new FileOutputStream(file));
+
+            for (AttitudeRec r : recs) {
+                w.write(String.format("%f %f %f %f\r\n", r.time, r.roll, r.pitch, r.yaw));
+            }
+            w.close();
+        } catch(FileNotFoundException e) {
+            e.printStackTrace();
+            Log.e(TAG, "Cannot create AttitudeRecs file.");
+        } catch (IOException e) {
+            Log.e(TAG, "Write AttitudeRecs file failure");
+        } finally {
+            if (w!=null) {
+                try {
+                    w.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    /**
+     *  Read the sensor log in ArrayList<AttitudeRec> format and find out the sensor sample time
+     *  statistics: mean and standard deviation.
+     *
+     *  @return The returned value will be a double array with exact 2 items, first [0] will be
+     *  mean and the second [1]  will be the standard deviation.
+     *
+     */
+    private double [] calcSensorPeriodStat(ArrayList<AttitudeRec> srec)   {
+        double tp = srec.get(0).time;
+        int i;
+        double sum = 0.0;
+        double sumsq = 0.0;
+        for(i=1; i<srec.size(); ++i) {
+            double dt;
+            dt = srec.get(i).time - tp;
+            sum += dt;
+            sumsq += dt*dt;
+            tp += dt;
+        }
+        double [] ret = new double[2];
+        ret[0] = sum/srec.size();
+        ret[1] = Math.sqrt(sumsq/srec.size() - ret[0]*ret[0]);
+        return ret;
+    }
+
+    /**
+     * Flipping the axis as the image are flipped upside down in OpenGL frames
+     */
+    private void fixFlippedAxis(ArrayList<AttitudeRec> vrecs)   {
+        for (AttitudeRec i: vrecs) {
+            i.yaw = -i.yaw;
+        }
+    }
+
+    /**
+     *  Calculate the maximum error on the specified axis between two time aligned (resampled)
+     *  ArrayList<AttitudeRec>. Yaw axis needs special treatment as 0 and 2pi error are same thing
+     *
+     * @param ra  one ArrayList of AttitudeRec
+     * @param rb  the other ArrayList of AttitudeRec
+     * @param axis axis id for the comparison (0 = roll, 1 = pitch, 2 = yaw)
+     * @return Maximum error
+     */
+    private double calcMaxErr(ArrayList<AttitudeRec> ra, ArrayList<AttitudeRec> rb, int axis)  {
+        // check if they are valid and comparable data
+        if (ra.size() != rb.size()) {
+            throw new ArrayIndexOutOfBoundsException("Two array has to be the same");
+        }
+        // check input parameter validity
+        if (axis<0 || axis > 2) {
+            throw new IllegalArgumentException("Invalid data axis.");
+        }
+
+        int i;
+        double max = 0.0;
+        double diff = 0.0;
+        for(i=0; i<ra.size(); ++i) {
+            // make sure they are aligned data
+            if (ra.get(i).time != rb.get(i).time) {
+                throw new IllegalArgumentException("Element "+i+
+                        " of two inputs has different time.");
+            }
+            switch(axis) {
+                case 0:
+                    diff = ra.get(i).roll - rb.get(i).roll; // they always opposite of each other..
+                    break;
+                case 1:
+                    diff = ra.get(i).pitch - rb.get(i).pitch;
+                    break;
+                case 2:
+                    diff = Math.abs(((4*Math.PI + ra.get(i).yaw - rb.get(i).yaw)%(2*Math.PI))
+                            -Math.PI)-Math.PI;
+                    break;
+            }
+            diff = Math.abs(diff);
+            if (diff>max) {
+                max = diff;
+            }
+        }
+        return max;
+    }
+
+    /**
+     *  Calculate the RMS error on the specified axis between two time aligned (resampled)
+     *  ArrayList<AttitudeRec>. Yaw axis needs special treatment as 0 and 2pi error are same thing
+     *
+     * @param ra  one ArrayList of AttitudeRec
+     * @param rb  the other ArrayList of AttitudeRec
+     * @param axis axis id for the comparison (0 = roll, 1 = pitch, 2 = yaw)
+     * @return Mean square error
+     */
+    private double calcSqrErr(ArrayList<AttitudeRec> ra, ArrayList<AttitudeRec> rb, int axis) {
+        // check if they are valid and comparable data
+        if (ra.size() != rb.size()) {
+            throw new ArrayIndexOutOfBoundsException("Two array has to be the same");
+        }
+        // check input parameter validity
+        if (axis<0 || axis > 2) {
+            throw new IllegalArgumentException("Invalid data axis.");
+        }
+
+        int i;
+        double sum = 0.0;
+        double diff = 0.0;
+        for(i=0; i<ra.size(); ++i) {
+            // check input data validity
+            if (ra.get(i).time != rb.get(i).time) {
+                throw new IllegalArgumentException("Element "+i+
+                        " of two inputs has different time.");
+            }
+
+            switch(axis) {
+                case 0:
+                    diff = ra.get(i).roll - rb.get(i).roll;
+                    break;
+                case 1:
+                    diff = ra.get(i).pitch - rb.get(i).pitch;
+                    break;
+                case 2:
+                    diff = Math.abs(((4*Math.PI + ra.get(i).yaw - rb.get(i).yaw)%(2*Math.PI))-
+                            Math.PI)-Math.PI;
+                    break;
+            }
+
+            sum += diff*diff;
+        }
+        return sum/ra.size();
+    }
+
+    /**
+     * Debugging helper function. Dump the error between two time aligned ArrayList<AttitudeRec>'s
+     *
+     * @param file File to write to
+     * @param ra  one ArrayList of AttitudeRec
+     * @param rb  the other ArrayList of AttitudeRec
+     */
+    private void dumpAttitudeError(File file, ArrayList<AttitudeRec> ra, ArrayList<AttitudeRec> rb){
+        if (ra.size() != rb.size()) {
+            throw new ArrayIndexOutOfBoundsException("Two array has to be the same");
+        }
+
+        int i;
+
+        ArrayList<AttitudeRec> rerr = new ArrayList<>();
+        for(i=0; i<ra.size(); ++i) {
+            if (ra.get(i).time != rb.get(i).time) {
+                throw new IllegalArgumentException("Element "+ i
+                        + " of two inputs has different time.");
+            }
+
+            rerr.add(new AttitudeRec(ra.get(i).time, ra.get(i).roll - rb.get(i).roll,
+                    ra.get(i).pitch - rb.get(i).pitch,
+                    (Math.abs(((4*Math.PI + ra.get(i).yaw - rb.get(i).yaw)%(2*Math.PI))
+                            -Math.PI)-Math.PI)));
+
+        }
+        dumpAttitudeRecs(file, rerr);
+    }
+
+    /**
+     * Resample one ArrayList<AttitudeRec> with respect to another ArrayList<AttitudeRec>
+     *
+     * @param rec           the ArrayList of AttitudeRec to be sampled
+     * @param timebase      the other ArrayList of AttitudeRec that serves as time base
+     * @param delta_t       offset in time before resample
+     * @param yaw_offset    offset in yaw axis
+     * @param resampled     output ArrayList of AttitudeRec
+     */
+
+    private void resampleSensorLog(ArrayList<AttitudeRec> rec, ArrayList<AttitudeRec> timebase,
+            double delta_t, double yaw_offset, ArrayList<AttitudeRec> resampled)    {
+        int i;
+        int j = -1;
+        for(i=0; i<timebase.size(); i++) {
+            double time = timebase.get(i).time + delta_t;
+
+            while(j<rec.size()-1 && rec.get(j+1).time < time) j++;
+
+            if (j == -1) {
+                //use first
+                resampled.get(i).assign(rec.get(0), timebase.get(i).time);
+            } else if (j == rec.size()-1) {
+                // use last
+                resampled.get(i).assign(rec.get(j), timebase.get(i).time);
+            } else {
+                // do linear resample
+                double alpha = (time - rec.get(j).time)/((rec.get(j+1).time - rec.get(j).time));
+                double roll = (1-alpha) * rec.get(j).roll + alpha * rec.get(j+1).roll;
+                double pitch = (1-alpha) * rec.get(j).pitch + alpha * rec.get(j+1).pitch;
+                double yaw = (1-alpha) * rec.get(j).yaw + alpha * rec.get(j+1).yaw + yaw_offset;
+                resampled.get(i).set(timebase.get(i).time, roll, pitch, yaw);
+            }
+        }
+    }
+
+    /**
+     * Analyze video frames using computer vision approach and generate a ArrayList<AttitudeRec>
+     *
+     * @param recs  output ArrayList of AttitudeRec
+     * @return total number of frame of the video
+     */
+    private int analyzeVideo(ArrayList<AttitudeRec> recs) {
+        VideoMetaInfo meta = new VideoMetaInfo(new File(mPath, "videometa.json"));
+
+        int decimation = 1;
+        boolean use_timestamp = true;
+
+        // roughly determine if decimation is necessary
+        if (meta.fps > DECIMATION_FPS_TARGET) {
+            decimation = (int)(meta.fps / DECIMATION_FPS_TARGET);
+            meta.fps /=decimation;
+        }
+
+        VideoDecoderForOpenCV videoDecoder = new VideoDecoderForOpenCV(
+                new File(mPath, "video.mp4"), decimation);
+
+
+        Mat frame;
+        Mat gray = new Mat();
+        int i = -1;
+
+        Size frameSize = videoDecoder.getSize();
+
+        if (frameSize.width != meta.frameWidth || frameSize.height != meta.frameHeight) {
+            // this is very unlikely
+            return -1;
+        }
+
+        if (TRACE_VIDEO_ANALYSIS) {
+            Debug.startMethodTracing("cvprocess");
+        }
+
+        Size patternSize = new Size(4,11);
+
+        float fc = (float)(meta.frameWidth/2.0/Math.tan(meta.fovWidth/2.0));
+        Mat camMat = cameraMatrix(fc, new Size(frameSize.width/2, frameSize.height/2));
+        MatOfDouble coeff = new MatOfDouble(); // dummy
+
+        MatOfPoint2f centers = new MatOfPoint2f();
+        MatOfPoint3f grid = asymmetricalCircleGrid(patternSize);
+        Mat rvec = new MatOfFloat();
+        Mat tvec = new MatOfFloat();
+
+        MatOfPoint2f reprojCenters = new MatOfPoint2f();
+
+        if (LOCAL_LOGV) {
+            Log.v(TAG, "Camera Mat = \n" + camMat.dump());
+        }
+
+        long startTime = System.nanoTime();
+        long [] ts = new long[1];
+
+        while ((frame = videoDecoder.getFrame(ts)) !=null) {
+            if (LOCAL_LOGV) {
+                Log.v(TAG, "got a frame " + i);
+            }
+
+            if (use_timestamp && ts[0] == -1) {
+                use_timestamp = false;
+            }
+
+            // has to be in front, as there are cases where execution
+            // will skip the later part of this while
+            i++;
+
+            // convert to gray manually as by default findCirclesGridDefault uses COLOR_BGR2GRAY
+            Imgproc.cvtColor(frame, gray, Imgproc.COLOR_RGB2GRAY);
+
+            boolean foundPattern = Calib3d.findCirclesGridDefault(
+                    gray,  patternSize, centers, Calib3d.CALIB_CB_ASYMMETRIC_GRID);
+
+            if (!foundPattern) {
+                // skip to next frame
+                continue;
+            }
+
+            if (OUTPUT_DEBUG_IMAGE) {
+                Calib3d.drawChessboardCorners(frame, patternSize, centers, true);
+            }
+
+            // figure out the extrinsic parameters using real ground truth 3D points and the pixel
+            // position of blobs found in findCircleGrid, an estimated camera matrix and
+            // no-distortion are assumed.
+            boolean foundSolution =
+                    Calib3d.solvePnP(grid, centers, camMat, coeff, rvec, tvec,
+                            false, Calib3d.CV_ITERATIVE);
+
+            if (!foundSolution) {
+                // skip to next frame
+                if (LOCAL_LOGV) {
+                    Log.v(TAG, "cannot find pnp solution in frame " + i + ", skipped.");
+                }
+                continue;
+            }
+
+            // reproject points to for evaluation of result accuracy of solvePnP
+            Calib3d.projectPoints(grid, rvec, tvec, camMat, coeff, reprojCenters);
+
+            // error is evaluated in norm2, which is real error in pixel distance / sqrt(2)
+            double error = Core.norm(centers, reprojCenters, Core.NORM_L2);
+
+            if (LOCAL_LOGV) {
+                Log.v(TAG, "Found attitude, re-projection error = " + error);
+            }
+
+            // if error is reasonable, add it into the results
+            if (error < REPROJECTION_THREASHOLD) {
+                double [] rv = new double[3];
+                double timestamp;
+
+                rvec.get(0,0, rv);
+                if (use_timestamp) {
+                    timestamp = (double)ts[0] / 1e6;
+                } else {
+                    timestamp = (double) i / meta.fps;
+                }
+                if (LOCAL_LOGV) Log.v(TAG, String.format("Added frame %d  ts = %f", i, timestamp));
+                recs.add(new AttitudeRec(timestamp, rodr2rpy(rv)));
+            }
+
+            if (OUTPUT_DEBUG_IMAGE) {
+                Calib3d.drawChessboardCorners(frame, patternSize, reprojCenters, true);
+                Highgui.imwrite(Environment.getExternalStorageDirectory().getPath()
+                        + "/RVCVRecData/DebugCV/img" + i + ".png", frame);
+            }
+        }
+
+        if (LOCAL_LOGV) {
+            Log.v(TAG, "Finished decoding");
+        }
+
+        if (TRACE_VIDEO_ANALYSIS) {
+            Debug.stopMethodTracing();
+        }
+
+        if (LOCAL_LOGV) {
+            // time analysis
+            double totalTime = (System.nanoTime()-startTime)/1e9;
+            Log.i(TAG, "Total time: "+totalTime +"s, Per frame time: "+totalTime/i );
+        }
+        return i;
+    }
+
+    /**
+     * OpenCV for Android have not support the VideoCapture from file
+     * This is a make shift solution before it is supported.
+     * One issue right now is that the glReadPixels is quite slow .. around 6.5ms for a 720p frame
+     */
+    private class VideoDecoderForOpenCV implements Runnable {
+        static final String TAG = "VideoDecoderForOpenCV";
+
+        private MediaExtractor extractor=null;
+        private MediaCodec decoder=null;
+        private CtsMediaOutputSurface surface=null;
+
+        private MatBuffer mMatBuffer;
+
+        private final File mVideoFile;
+
+        private boolean valid;
+        private Object setupSignal;
+
+        private Thread mThread;
+        private int mDecimation;
+
+        /**
+         * Constructor
+         * @param file video file
+         * @param decimation process every "decimation" number of frame
+         */
+        VideoDecoderForOpenCV(File file, int decimation) {
+            mVideoFile = file;
+            mDecimation = decimation;
+            valid = false;
+
+            start();
+        }
+
+        /**
+         * Constructor
+         * @param file video file
+         */
+        VideoDecoderForOpenCV(File file)   {
+            this(file, 1);
+        }
+
+        /**
+         * Test if video decoder is in valid states ready to output video.
+         * @return true of force.
+         */
+        public boolean isValid() {
+            return valid;
+        }
+
+        private void start() {
+            setupSignal = new Object();
+            mThread = new Thread(this);
+            mThread.start();
+
+            synchronized (setupSignal) {
+                try {
+                    setupSignal.wait();
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Interrupted when waiting for video decoder setup ready");
+                }
+            }
+        }
+        private void stop() {
+            if (mThread != null) {
+                mThread.interrupt();
+                try {
+                    mThread.join();
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Interrupted when waiting for video decoder thread to stop");
+                }
+                try {
+                    decoder.stop();
+                }catch (IllegalStateException e) {
+                    Log.e(TAG, "Video decoder is not in a state that can be stopped");
+                }
+            }
+            mThread = null;
+        }
+
+        void teardown() {
+            if (decoder!=null) {
+                decoder.release();
+                decoder = null;
+            }
+            if (surface!=null) {
+                surface.release();
+                surface = null;
+            }
+            if (extractor!=null) {
+                extractor.release();
+                extractor = null;
+            }
+        }
+
+        void setup() {
+            int width=0, height=0;
+
+            extractor = new MediaExtractor();
+
+            try {
+                extractor.setDataSource(mVideoFile.getPath());
+            } catch (IOException e) {
+                return;
+            }
+
+            for (int i = 0; i < extractor.getTrackCount(); i++) {
+                MediaFormat format = extractor.getTrackFormat(i);
+                String mime = format.getString(MediaFormat.KEY_MIME);
+                width = format.getInteger(MediaFormat.KEY_WIDTH);
+                height = format.getInteger(MediaFormat.KEY_HEIGHT);
+
+                if (mime.startsWith("video/")) {
+                    extractor.selectTrack(i);
+                    try {
+                        decoder = MediaCodec.createDecoderByType(mime);
+                    }catch (IOException e) {
+                        continue;
+                    }
+                    // Decode to surface
+                    //decoder.configure(format, surface, null, 0);
+
+                    // Decode to offscreen surface
+                    surface = new CtsMediaOutputSurface(width, height);
+                    mMatBuffer = new MatBuffer(width, height);
+
+                    decoder.configure(format, surface.getSurface(), null, 0);
+                    break;
+                }
+            }
+
+            if (decoder == null) {
+                Log.e(TAG, "Can't find video info!");
+                return;
+            }
+            valid = true;
+        }
+
+        @Override
+        public void run() {
+            setup();
+
+            synchronized (setupSignal) {
+                setupSignal.notify();
+            }
+
+            if (!valid) {
+                return;
+            }
+
+            decoder.start();
+
+            ByteBuffer[] inputBuffers = decoder.getInputBuffers();
+            ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
+            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+
+            boolean isEOS = false;
+            long startMs = System.currentTimeMillis();
+            long timeoutUs = 10000;
+
+            int iframe = 0;
+            long frameTimestamp = 0;
+
+            while (!Thread.interrupted()) {
+                if (!isEOS) {
+                    int inIndex = decoder.dequeueInputBuffer(10000);
+                    if (inIndex >= 0) {
+                        ByteBuffer buffer = inputBuffers[inIndex];
+                        int sampleSize = extractor.readSampleData(buffer, 0);
+                        if (sampleSize < 0) {
+                            if (LOCAL_LOGD) {
+                                Log.d("VideoDecoderForOpenCV",
+                                        "InputBuffer BUFFER_FLAG_END_OF_STREAM");
+                            }
+                            decoder.queueInputBuffer(inIndex, 0, 0, 0,
+                                    MediaCodec.BUFFER_FLAG_END_OF_STREAM);
+                            isEOS = true;
+                        } else {
+                            frameTimestamp = extractor.getSampleTime();
+                            decoder.queueInputBuffer(inIndex, 0, sampleSize, frameTimestamp, 0);
+                            if (LOCAL_LOGD) {
+                                Log.d(TAG, String.format("Frame %d sample time %f s",
+                                            iframe, (double)frameTimestamp/1e6));
+                            }
+                            extractor.advance();
+                        }
+                    }
+                }
+
+                int outIndex = decoder.dequeueOutputBuffer(info, 10000);
+                MediaFormat outFormat;
+                switch (outIndex) {
+                    case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
+                        if (LOCAL_LOGD) {
+                            Log.d(TAG, "INFO_OUTPUT_BUFFERS_CHANGED");
+                        }
+                        outputBuffers = decoder.getOutputBuffers();
+                        break;
+                    case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
+                        outFormat = decoder.getOutputFormat();
+                        if (LOCAL_LOGD) {
+                            Log.d(TAG, "New format " + outFormat);
+                        }
+                        break;
+                    case MediaCodec.INFO_TRY_AGAIN_LATER:
+                        if (LOCAL_LOGD) {
+                            Log.d(TAG, "dequeueOutputBuffer timed out!");
+                        }
+                        break;
+                    default:
+
+                        ByteBuffer buffer = outputBuffers[outIndex];
+                        boolean doRender = (info.size != 0);
+
+                        // As soon as we call releaseOutputBuffer, the buffer will be forwarded
+                        // to SurfaceTexture to convert to a texture.  The API doesn't
+                        // guarantee that the texture will be available before the call
+                        // returns, so we need to wait for the onFrameAvailable callback to
+                        // fire.  If we don't wait, we risk rendering from the previous frame.
+                        decoder.releaseOutputBuffer(outIndex, doRender);
+
+                        if (doRender) {
+                            surface.awaitNewImage();
+                            surface.drawImage();
+                            if (LOCAL_LOGV) {
+                                Log.v(TAG, "Finish drawing a frame!");
+                            }
+                            if ((iframe++ % mDecimation) == 0) {
+                                //Send the frame for processing
+                                mMatBuffer.put(frameTimestamp);
+                            }
+                        }
+                        break;
+                }
+
+                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                    if (LOCAL_LOGD) {
+                        Log.d("VideoDecoderForOpenCV", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
+                    }
+                    break;
+                }
+            }
+            mMatBuffer.invalidate();
+
+            decoder.stop();
+
+            teardown();
+            mThread = null;
+        }
+
+
+        /**
+         * Get next valid frame
+         * @return Frame in OpenCV mat
+         */
+        public Mat getFrame(long ts[]) {
+            return mMatBuffer.get(ts);
+        }
+
+        /**
+         * Get the size of the frame
+         * @return size of the frame
+         */
+        Size getSize() {
+            return mMatBuffer.getSize();
+        }
+
+        /**
+         * A synchronized buffer
+         */
+        class MatBuffer {
+            private Mat mat;
+            private byte[] bytes;
+            private ByteBuffer buf;
+            private long timestamp;
+            private boolean full;
+
+            private int mWidth, mHeight;
+            private boolean mValid = false;
+
+            MatBuffer(int width, int height) {
+                mWidth = width;
+                mHeight = height;
+
+                mat = new Mat(height, width, CvType.CV_8UC4); //RGBA
+                buf = ByteBuffer.allocateDirect(width*height*4);
+                bytes = new byte[width*height*4];
+                timestamp = -1;
+
+                mValid = true;
+                full = false;
+            }
+
+            public synchronized void invalidate() {
+                mValid = false;
+                notifyAll();
+            }
+
+            public synchronized Mat get(long ts[]) {
+
+                if (!mValid) return null;
+                while (full == false) {
+                    try {
+                        wait();
+                        if (!mValid) return null;
+                    } catch (InterruptedException e) {
+                        return null;
+                    }
+                }
+                mat.put(0,0, bytes);
+                full = false;
+                notifyAll();
+                ts[0] = timestamp;
+                return mat;
+            }
+
+            public synchronized void put(long ts) {
+                while (full) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                        Log.e(TAG, "Interrupted when waiting for space in buffer");
+                    }
+                }
+                GLES20.glReadPixels(0, 0, mWidth, mHeight, GL10.GL_RGBA,
+                        GL10.GL_UNSIGNED_BYTE, buf);
+                buf.get(bytes);
+                buf.rewind();
+
+                timestamp = ts;
+                full = true;
+                notifyAll();
+            }
+
+            public Size getSize() {
+                if (valid) {
+                    return mat.size();
+                }
+                return new Size();
+            }
+        }
+    }
+
+
+    /* a small set of math functions */
+    private static double [] quat2rpy( double [] q) {
+        double [] rpy = {Math.atan2(2*(q[0]*q[1]+q[2]*q[3]), 1-2*(q[1]*q[1]+q[2]*q[2])),
+                Math.asin(2*(q[0]*q[2] - q[3]*q[1])),
+                Math.atan2(2*(q[0]*q[3]+q[1]*q[2]), 1-2*(q[2]*q[2]+q[3]*q[3]))};
+        return rpy;
+    }
+
+    private static void quat2rpy( double [] q, double[] rpy) {
+        rpy[0] = Math.atan2(2*(q[0]*q[1]+q[2]*q[3]), 1-2*(q[1]*q[1]+q[2]*q[2]));
+        rpy[1] = Math.asin(2*(q[0]*q[2] - q[3]*q[1]));
+        rpy[2] = Math.atan2(2*(q[0]*q[3]+q[1]*q[2]), 1-2*(q[2]*q[2]+q[3]*q[3]));
+    }
+
+    private static Mat quat2rpy(Mat quat) {
+        double [] q = new double[4];
+        quat.get(0,0,q);
+
+        double [] rpy = {Math.atan2(2*(q[0]*q[1]+q[2]*q[3]), 1-2*(q[1]*q[1]+q[2]*q[2])),
+                Math.asin(2*(q[0]*q[2] - q[3]*q[1])),
+                Math.atan2(2*(q[0]*q[3]+q[1]*q[2]), 1-2*(q[2]*q[2]+q[3]*q[3]))};
+
+        Mat rpym = new Mat(3,1, CvType.CV_64F);
+        rpym.put(0,0, rpy);
+        return rpym;
+    }
+
+    private static double [] rodr2quat( double [] r) {
+        double t = Math.sqrt(r[0]*r[0]+r[1]*r[1]+r[2]*r[2]);
+        double [] quat = {Math.cos(t/2), Math.sin(t/2)*r[0]/t,Math.sin(t/2)*r[1]/t,
+                Math.sin(t/2)*r[2]/t};
+        return quat;
+    }
+
+    private static void rodr2quat( double [] r, double [] quat) {
+        double t = Math.sqrt(r[0]*r[0]+r[1]*r[1]+r[2]*r[2]);
+        quat[0] = Math.cos(t/2);
+        quat[1] = Math.sin(t/2)*r[0]/t;
+        quat[2] = Math.sin(t/2)*r[1]/t;
+        quat[3] = Math.sin(t/2)*r[2]/t;
+    }
+
+    private static Mat rodr2quat(Mat rodr) {
+        double t = Core.norm(rodr);
+        double [] r = new double[3];
+        rodr.get(0,0,r);
+
+        double [] quat = {Math.cos(t/2), Math.sin(t/2)*r[0]/t,Math.sin(t/2)*r[1]/t,
+                Math.sin(t/2)*r[2]/t};
+        Mat quatm = new Mat(4,1, CvType.CV_64F);
+        quatm.put(0, 0, quat);
+        return quatm;
+    }
+
+    private static double [] rodr2rpy( double [] r) {
+        return quat2rpy(rodr2quat(r));
+    }
+    //////////////////
+
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
new file mode 100644
index 0000000..35c4d56
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/RVCVXCheckTestActivity.java
@@ -0,0 +1,346 @@
+/*
+ * 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.verifier.sensors;
+
+import android.content.Context;
+import android.hardware.cts.helpers.SensorTestStateNotSupportedException;
+import android.os.Bundle;
+import android.os.PowerManager;
+
+import com.android.cts.verifier.sensors.base.SensorCtsVerifierTestActivity;
+import com.android.cts.verifier.sensors.helpers.OpenCVLibrary;
+
+import junit.framework.Assert;
+
+import android.content.Intent;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This test (Rotation Vector - Computer Vision Cross Check, or RXCVXCheck for short) verifies that
+ * mobile device can detect the orientation of itself in a relatively accurate manner.
+ *
+ * Currently only ROTATION_VECTOR sensor is used.
+ *
+ */
+public class RVCVXCheckTestActivity
+        extends SensorCtsVerifierTestActivity {
+    public RVCVXCheckTestActivity() {
+        super(RVCVXCheckTestActivity.class);
+    }
+
+    CountDownLatch mRecordActivityFinishedSignal = null;
+
+    private static final int REQ_CODE_TXCVRECORD = 0x012345678;
+    private static final boolean TEST_USING_DEBUGGING_DATA = false;
+    private static final String PATH_DEBUGGING_DATA = "/sdcard/RXCVRecData/150313-014443/";
+
+    private String mRecPath;
+
+    RVCVXCheckAnalyzer.AnalyzeReport mReport = null;
+
+    private boolean mRecordSuccessful = false;
+    private boolean mOpenCVLoadSuccessful = false;
+
+    private static class Criterion {
+        public static final float roll_rms_error = 0.15f;
+        public static final float pitch_rms_error = 0.15f;
+        public static final float yaw_rms_error = 0.25f;
+
+        public static final float roll_max_error = 0.30f;
+        public static final float pitch_max_error = 0.30f;
+        public static final float yaw_max_error = 0.45f;
+
+        public static final float sensor_period_stdev = 0.25e-3f;
+    };
+
+
+    /**
+     * The activity setup collects all the required data for test cases.
+     * This approach allows to test all sensors at once.
+     */
+    @Override
+    protected void activitySetUp() throws InterruptedException {
+
+        mRecPath = "";
+
+        showUserMessage("Loading OpenCV Library...");
+        int retry = 10;
+
+        while(retry-->0) {
+            try {
+                Thread.sleep(250);
+            } catch (InterruptedException e) {
+                //
+            }
+            if (OpenCVLibrary.isLoaded()) {
+                break;
+            }
+        }
+        if (!OpenCVLibrary.isLoaded()) {
+            // failed requirement test
+            clearText();
+            return;
+        }
+        showUserMessage("OpenCV Library Successfully Loaded");
+
+        mOpenCVLoadSuccessful = true;
+
+        if (TEST_USING_DEBUGGING_DATA) {
+            mRecPath = PATH_DEBUGGING_DATA;
+
+            // assume the data is there already
+            mRecordSuccessful = true;
+        } else {
+            showUserMessage("Take the test as instructed below:\n" +
+                "1. Print out the test pattern and place it on a "+
+                   "horizontal surface.\n" +
+                "2. Start the test and align the yellow square on the screen "+
+                   "roughly to the yellow sqaure.\n" +
+                "3. Follow the prompt to rotate the phone while keeping the "+
+                   "entire test pattern inside view of camera. This requires " +
+                   "orbiting the phone around and aiming the "+
+                   "camera at the test pattern at the same time.\n" +
+                "4. Wait patiently for the analysis to finish.\n");
+
+            waitForUserToContinue();
+
+            // prepare sync signal
+            mRecordActivityFinishedSignal = new CountDownLatch(1);
+
+            // record both sensor and camera
+            Intent intent = new Intent(this, RVCVRecordActivity.class);
+            startActivityForResult(intent, REQ_CODE_TXCVRECORD);
+
+            // wait for record finish
+            mRecordActivityFinishedSignal.await();
+
+            if ("".equals(mRecPath)) {
+                showUserMessage("Recording failed or exited prematurely.");
+                waitForUserToContinue();
+            } else {
+                showUserMessage("Recording is done!");
+                showUserMessage("Result are in path: " + mRecPath);
+                mRecordSuccessful = true;
+            }
+        }
+
+
+        if (mRecordSuccessful) {
+            showUserMessage("Please wait for the analysis ... \n"+
+                            "It may take a few minutes, you will be noted when "+
+                            "its finished by sound and vibration. ");
+
+            // Analysis of recorded video and sensor data using RVCXAnalyzer
+            RVCVXCheckAnalyzer analyzer = new RVCVXCheckAnalyzer(mRecPath);
+
+            // acquire a partial wake lock just in case CPU fall asleep
+            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+            PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                    "RVCVXCheckAnalyzer");
+
+            wl.acquire();
+            mReport = analyzer.processDataSet();
+            wl.release();
+
+            playSound();
+            vibrate(500);
+
+            if (mReport == null) {
+                showUserMessage("Analysis failed due to unknown reason!");
+            } else {
+                if (mReport.error) {
+                    showUserMessage("Analysis failed: " + mReport.reason);
+                } else {
+                    showUserMessage(String.format("Analysis finished!\n" +
+                                    "Roll error (Rms, max) = %4.3f, %4.3f rad\n" +
+                                    "Pitch error (Rms, max) = %4.3f, %4.3f rad\n" +
+                                    "Yaw error (Rms, max) = %4.3f, %4.3f rad\n" +
+                                    "N of Frame (valid, total) = %d, %d\n" +
+                                    "Sensor period (mean, stdev) = %4.3f, %4.3f ms\n" +
+                                    "Time offset: %4.3f s \n" +
+                                    "Yaw offset: %4.3f rad \n\n",
+                            mReport.roll_rms_error, mReport.roll_max_error,
+                            mReport.pitch_rms_error, mReport.pitch_max_error,
+                            mReport.yaw_rms_error, mReport.yaw_max_error,
+                            mReport.n_of_valid_frame, mReport.n_of_frame,
+                            mReport.sensor_period_avg * 1000.0, mReport.sensor_period_stdev*1000.0,
+                            mReport.optimal_delta_t, mReport.yaw_offset));
+                    showUserMessage("Please click next after details reviewed.");
+                    waitForUserToContinue();
+                }
+            }
+        }
+        clearText();
+    }
+
+    /**
+    Receiving the results from the RVCVRecordActivity, which is a patch where the recorded
+    video and sensor data is stored.
+    */
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        // Check which request we're responding to
+        if (requestCode == REQ_CODE_TXCVRECORD) {
+            // Make sure the request was successful
+
+            if (resultCode == RESULT_OK) {
+                mRecPath = data.getData().getPath();
+            }
+
+            // notify it is finished
+            mRecordActivityFinishedSignal.countDown();
+        }
+        super.onActivityResult(requestCode, resultCode, data);
+    }
+
+    /**
+     * Test cases.
+     */
+
+    public String test00OpenCV() throws Throwable {
+
+        String message = "OpenCV is loaded";
+        Assert.assertTrue("OpenCV library cannot be loaded.", mOpenCVLoadSuccessful);
+        return message;
+    }
+
+
+    public String test01Recording() throws Throwable {
+
+        loadOpenCVSuccessfulOrSkip();
+
+        String message = "Record is successful.";
+        Assert.assertTrue("Record is not successful.", mRecordSuccessful);
+        return message;
+    }
+
+    public String test02Analysis() throws Throwable {
+
+        loadOpenCVSuccessfulOrSkip();
+        recordSuccessfulOrSkip();
+
+        String message = "Analysis result: " + mReport.reason;
+        Assert.assertTrue(message, (mReport!=null && !mReport.error));
+        return message;
+    }
+
+    public String test1RollAxis() throws Throwable {
+
+        loadOpenCVSuccessfulOrSkip();
+        recordSuccessfulOrSkip();
+        analyzeSuccessfulOrSkip();
+
+        String message = "Test Roll Axis Accuracy";
+
+        Assert.assertEquals("Roll RMS error", 0.0, mReport.roll_rms_error,
+                Criterion.roll_rms_error);
+        Assert.assertEquals("Roll max error", 0.0, mReport.roll_max_error,
+                Criterion.roll_max_error);
+        return message;
+    }
+
+    public String test2PitchAxis() throws Throwable {
+
+        loadOpenCVSuccessfulOrSkip();
+        recordSuccessfulOrSkip();
+        analyzeSuccessfulOrSkip();
+
+        String message = "Test Pitch Axis Accuracy";
+
+        Assert.assertEquals("Pitch RMS error", 0.0, mReport.pitch_rms_error,
+                Criterion.pitch_rms_error);
+        Assert.assertEquals("Pitch max error", 0.0, mReport.pitch_max_error,
+                Criterion.pitch_max_error);
+        return message;
+    }
+
+    public String test3YawAxis() throws Throwable {
+
+        loadOpenCVSuccessfulOrSkip();
+        recordSuccessfulOrSkip();
+        analyzeSuccessfulOrSkip();
+
+        String message = "Test Yaw Axis Accuracy";
+
+        Assert.assertEquals("Yaw RMS error", 0.0, mReport.yaw_rms_error,
+                Criterion.yaw_rms_error);
+        Assert.assertEquals("Yaw max error", 0.0, mReport.yaw_max_error,
+                Criterion.yaw_max_error);
+        return message;
+    }
+
+    public String test4SensorPeriod() throws Throwable {
+
+        loadOpenCVSuccessfulOrSkip();
+        recordSuccessfulOrSkip();
+        analyzeSuccessfulOrSkip();
+
+        String message = "Test Sensor Period";
+
+        // we do not know what the maximum frequency can be, so just test the stdev value
+        Assert.assertEquals("Sensor sample period stdev.", 0.0, mReport.sensor_period_stdev,
+                Criterion.sensor_period_stdev);
+        return message;
+    }
+
+    private void loadOpenCVSuccessfulOrSkip() throws SensorTestStateNotSupportedException {
+        if (!mOpenCVLoadSuccessful)
+            throw new SensorTestStateNotSupportedException("Skipped due to OpenCV cannot be loaded");
+    }
+
+    private void recordSuccessfulOrSkip() throws SensorTestStateNotSupportedException {
+        if (!mRecordSuccessful)
+            throw new SensorTestStateNotSupportedException("Skipped due to record failure.");
+    }
+
+    private void analyzeSuccessfulOrSkip() throws SensorTestStateNotSupportedException {
+        if (mReport == null || mReport.error)
+            throw new SensorTestStateNotSupportedException("Skipped due to CV Analysis failure.");
+    }
+
+    /*
+     *  This function serves as a proxy as showUserMessage is marked to be deprecated.
+     *  When appendText is removed, this function will have a different implementation.
+     *
+     */
+    void showUserMessage(String s) {
+        appendText(s);
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+
+        super.onCreate(savedInstanceState);
+
+        // GlSurfaceView is not necessary for this test
+        closeGlSurfaceView();
+
+        OpenCVLibrary.loadAsync(this);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
index faba445..2dfc7c8 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/SignificantMotionTestActivity.java
@@ -16,22 +16,36 @@
 
 package com.android.cts.verifier.sensors;
 
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
 import com.android.cts.verifier.R;
 import com.android.cts.verifier.sensors.base.SensorCtsVerifierTestActivity;
+import com.android.cts.verifier.sensors.helpers.SensorTestScreenManipulator;
 
-import junit.framework.Assert;
-
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
 import android.hardware.TriggerEvent;
 import android.hardware.TriggerEventListener;
 import android.hardware.cts.helpers.SensorNotSupportedException;
 import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.SuspendStateMonitor;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.PowerManager;
 import android.os.SystemClock;
+import android.support.v4.content.LocalBroadcastManager;
+import android.util.Log;
 
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
+import junit.framework.Assert;
 
 /**
  * Test cases for Significant Motion sensor.
@@ -46,20 +60,30 @@
     private static final long MAX_ACCEPTABLE_EVENT_TIME_DELAY_NANOS =
             TimeUnit.MILLISECONDS.toNanos(500);
 
+    // acceptable time difference between event time and AP wake up time.
+    private static final long MAX_ACCEPTABLE_DELAY_EVENT_AP_WAKE_UP_NS =
+            TimeUnit.MILLISECONDS.toNanos(2000);
+
+    // time to wait for SMD after the device has gone into suspend. Even after
+    // 45 secs if SMD does not trigger, the test will fail.
+    private static final long ALARM_WAKE_TIME_DELAY_MS = TimeUnit.SECONDS.toMillis(45);
+
     // time for the test to wait for a trigger
     private static final int TRIGGER_MAX_DELAY_SECONDS = 30;
     private static final int VIBRATE_DURATION_MILLIS = 10000;
 
     private static final int EVENT_VALUES_LENGTH = 1;
     private static final float EXPECTED_EVENT_VALUE = 1.0f;
+    private static String ACTION_ALARM = "SignificantMotionTestActivity.ACTION_ALARM";
 
     private SensorManager mSensorManager;
     private Sensor mSensorSignificantMotion;
+    private TriggerVerifier mVerifier;
+    private SensorTestScreenManipulator mScreenManipulator;
 
     /**
      * Test cases.
      */
-
     @SuppressWarnings("unused")
     public String testTrigger() throws Throwable {
         return runTest(
@@ -131,6 +155,69 @@
         return result;
     }
 
+    public static class AlarmReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Intent alarm_intent = new Intent(context, SignificantMotionTestActivity.class);
+            alarm_intent.setAction(SignificantMotionTestActivity.ACTION_ALARM);
+            LocalBroadcastManager.getInstance(context).sendBroadcastSync(alarm_intent);
+        }
+    }
+
+    public BroadcastReceiver myBroadCastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            mVerifier.releaseLatch();
+            mScreenManipulator.turnScreenOn();
+            try {
+                playSound();
+            } catch (InterruptedException e) {
+                // Ignore ...
+            }
+        }
+    };
+
+    @SuppressWarnings("unused")
+    public String testAPWakeUpOnSMDTrigger() throws Throwable {
+        SensorTestLogger logger = getTestLogger();
+        logger.logInstructions(R.string.snsr_significant_motion_ap_suspend);
+        waitForUserToBegin();
+        mVerifier = new TriggerVerifier();
+        mSensorManager.requestTriggerSensor(mVerifier, mSensorSignificantMotion);
+        long testStartTimeNs = SystemClock.elapsedRealtimeNanos();
+        Handler handler = new Handler(Looper.getMainLooper());
+        SuspendStateMonitor suspendStateMonitor = new SuspendStateMonitor();
+
+        Intent intent = new Intent(this, AlarmReceiver.class);
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
+
+        AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
+        am.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP,
+                     SystemClock.elapsedRealtime() + ALARM_WAKE_TIME_DELAY_MS, pendingIntent);
+        try {
+            // Wait for the first event to trigger. Device is expected to go into suspend here.
+            mVerifier.verifyEventTriggered();
+            long eventTimeStampNs = mVerifier.getTimeStampForTriggerEvent();
+            long endTimeNs = SystemClock.elapsedRealtimeNanos();
+            long lastWakeupTimeNs = TimeUnit.MILLISECONDS.toNanos(
+                    suspendStateMonitor.getLastWakeUpTime());
+            Assert.assertTrue(getString(R.string.snsr_device_did_not_go_into_suspend),
+                              testStartTimeNs < lastWakeupTimeNs && lastWakeupTimeNs < endTimeNs);
+            long timestampDelta = Math.abs(lastWakeupTimeNs - eventTimeStampNs);
+            Assert.assertTrue(
+                    String.format(getString(R.string.snsr_device_did_not_wake_up_at_trigger),
+                              TimeUnit.NANOSECONDS.toMillis(lastWakeupTimeNs),
+                              TimeUnit.NANOSECONDS.toMillis(eventTimeStampNs)),
+                              timestampDelta < MAX_ACCEPTABLE_DELAY_EVENT_AP_WAKE_UP_NS);
+        } finally {
+            am.cancel(pendingIntent);
+            suspendStateMonitor.cancel();
+            mScreenManipulator.turnScreenOn();
+            playSound();
+        }
+        return null;
+    }
+
     /**
      * @param instructionsResId Instruction to be shown to testers
      * @param isMotionExpected Should the device detect significant motion event
@@ -187,6 +274,29 @@
         if (mSensorSignificantMotion == null) {
             throw new SensorNotSupportedException(Sensor.TYPE_SIGNIFICANT_MOTION);
         }
+
+        mScreenManipulator = new SensorTestScreenManipulator(this);
+        try {
+            mScreenManipulator.initialize(this);
+        } catch (InterruptedException e) {
+        }
+        PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
+        LocalBroadcastManager.getInstance(this).registerReceiver(myBroadCastReceiver,
+                                            new IntentFilter(ACTION_ALARM));
+    }
+
+    @Override
+    protected void activityCleanUp() {
+        if (mScreenManipulator != null) {
+            mScreenManipulator.turnScreenOff();
+        }
+        LocalBroadcastManager.getInstance(this).unregisterReceiver(myBroadCastReceiver);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mScreenManipulator.close();
     }
 
     /**
@@ -196,6 +306,7 @@
     private class TriggerVerifier extends TriggerEventListener {
         private volatile CountDownLatch mCountDownLatch;
         private volatile TriggerEventRegistry mEventRegistry;
+        private volatile long mTimestampForTriggeredEvent = 0;
 
         // TODO: refactor out if needed
         private class TriggerEventRegistry {
@@ -214,6 +325,16 @@
             mCountDownLatch.countDown();
         }
 
+        public void releaseLatch() {
+            if (mCountDownLatch != null) {
+                mCountDownLatch.countDown();
+            }
+        }
+
+        public long getTimeStampForTriggerEvent() {
+            return mTimestampForTriggeredEvent;
+        }
+
         public String verifyEventTriggered() throws Throwable {
             TriggerEventRegistry registry = awaitForEvent();
 
@@ -269,10 +390,14 @@
         private TriggerEventRegistry awaitForEvent() throws InterruptedException {
             mCountDownLatch = new CountDownLatch(1);
             mCountDownLatch.await(TRIGGER_MAX_DELAY_SECONDS, TimeUnit.SECONDS);
-
             TriggerEventRegistry registry = mEventRegistry;
-            mEventRegistry = null;
 
+            // Save the last timestamp when the event triggered.
+            if (mEventRegistry != null && mEventRegistry.triggerEvent != null) {
+                mTimestampForTriggeredEvent = mEventRegistry.triggerEvent.timestamp;
+            }
+
+            mEventRegistry = null;
             playSound();
             return registry != null ? registry : new TriggerEventRegistry(null, 0);
         }
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/OpenCVLibrary.java b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/OpenCVLibrary.java
new file mode 100644
index 0000000..2f5c873
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/helpers/OpenCVLibrary.java
@@ -0,0 +1,71 @@
+/*
+ * 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.sensors.helpers;
+
+import android.content.Context;
+import android.os.Looper;
+import android.util.Log;
+
+import org.opencv.android.BaseLoaderCallback;
+import org.opencv.android.LoaderCallbackInterface;
+import org.opencv.android.OpenCVLoader;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * OpenCV library loader class
+ */
+public class OpenCVLibrary {
+
+    private static String TAG = "OpenCVLibraryProbe";
+    private static boolean mLoaded = false;
+
+    /**
+     * Load OpenCV Library in async mode
+     * @param context Activity context
+     */
+    public static void loadAsync(Context context) {
+        // only need to load once
+        if (isLoaded())  return;
+
+        // Load the library through loader
+        OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_9, context,
+                new BaseLoaderCallback(context) {
+                    @Override
+                    public void onManagerConnected(int status) {
+                        Log.v(TAG, "New Loading status: "+status);
+                        switch (status) {
+                            case LoaderCallbackInterface.SUCCESS: {
+                                mLoaded = true;
+                            }
+                            break;
+                            default: {
+                                super.onManagerConnected(status);
+                            }
+                            break;
+                        }
+                    }
+                });
+    }
+
+    /**
+     * Test if the library is loaded
+     * @return a boolean indicates whether the OpenCV library is loaded.
+     */
+    public static boolean isLoaded() {
+        return mLoaded;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
index 9684d97..00a52ae 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/streamquality/StreamingVideoActivity.java
@@ -117,7 +117,7 @@
 
     private static final Stream[] HTTP_STREAMS = {
         new Stream("H263 Video, AMR Audio", "http_h263_amr",
-                "http://redirector.c.play.google.com/"
+                "http://redirector.gvt1.com/"
                 + "videoplayback?id=271de9756065677e"
                 + "&itag=13&ip=0.0.0.0&ipbits=0&expire=19000000000"
                 + "&sparams=ip,ipbits,expire,id,itag"
@@ -126,7 +126,7 @@
                 + "&source=youtube"
                 + "&key=ik0&user=android-device-test"),
         new Stream("MPEG4 SP Video, AAC Audio", "http_mpeg4_aac",
-                "http://redirector.c.play.google.com/"
+                "http://redirector.gvt1.com/"
                 + "videoplayback?id=271de9756065677e"
                 + "&itag=17&ip=0.0.0.0&ipbits=0&expire=19000000000"
                 + "&sparams=ip,ipbits,expire,id,itag"
@@ -135,7 +135,7 @@
                 + "&source=youtube"
                 + "&key=ik0&user=android-device-test"),
         new Stream("H264 Base Video, AAC Audio", "http_h264_aac",
-                "http://redirector.c.play.google.com/"
+                "http://redirector.gvt1.com/"
                 + "videoplayback?id=271de9756065677e"
                 + "&itag=18&ip=0.0.0.0&ipbits=0&expire=19000000000"
                 + "&sparams=ip,ipbits,expire,id,itag"
@@ -220,10 +220,6 @@
                 i, null));
     }
 
-    private void updatePassButton() {
-        getPassButton().setEnabled(mAdapter.allTestsPassed());
-    }
-
     /** @returns the appropriate RTSP url, or null in case of failure */
     private String lookupRtspUrl(int itag, String signature) {
         String rtspLookupUri = String.format(RTSP_LOOKUP_URI_TEMPLATE, itag, signature);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/AppLinkTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/AppLinkTestActivity.java
new file mode 100644
index 0000000..43f293a
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/AppLinkTestActivity.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.cts.verifier.tv;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.media.tv.TvContract;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.cts.verifier.R;
+
+/**
+ * Tests for verifying TV app behavior for TV app-link.
+ */
+public class AppLinkTestActivity extends TvAppVerifierActivity implements View.OnClickListener {
+    private static final long TIMEOUT_MS = 5l * 60l * 1000l;  // 5 mins.
+
+    private boolean mSelectAppLinkItemPassed;
+    private View mSelectAppLinkItem;
+    private View mVerifyAppLinkIntentItem;
+    private View mVerifyAppLinkCardItem;
+
+    Runnable mSelectAppLinkFailCallback;
+
+    @Override
+    public void onClick(View v) {
+        final View postTarget = getPostTarget();
+
+        if (containsButton(mSelectAppLinkItem, v)) {
+            Intent tvAppIntent = null;
+            String[] projection = { TvContract.Channels._ID };
+            try (Cursor cursor = getContentResolver().query(
+                    TvContract.buildChannelsUriForInput(MockTvInputService.getInputId(this)),
+                    projection, null, null, null)) {
+                if (cursor != null && cursor.moveToNext()) {
+                    tvAppIntent = new Intent(Intent.ACTION_VIEW,
+                            TvContract.buildChannelUri(cursor.getLong(0)));
+                }
+            }
+            if (tvAppIntent == null) {
+                Toast.makeText(this, R.string.tv_channel_not_found, Toast.LENGTH_SHORT).show();
+                return;
+            }
+
+            mSelectAppLinkFailCallback = new Runnable() {
+                @Override
+                public void run() {
+                    mSelectAppLinkItemPassed = false;
+                    setPassState(mSelectAppLinkItem, false);
+                    setPassState(mVerifyAppLinkIntentItem, false);
+                }
+            };
+            postTarget.postDelayed(mSelectAppLinkFailCallback, TIMEOUT_MS);
+            mSelectAppLinkItemPassed = true;
+            setPassState(mSelectAppLinkItem, true);
+
+            startActivity(tvAppIntent);
+        } else if (containsButton(mVerifyAppLinkCardItem, v)) {
+            setPassState(mVerifyAppLinkCardItem, true);
+            getPassButton().setEnabled(true);
+        }
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        if (mSelectAppLinkItemPassed
+                && TextUtils.equals(MockTvInputSetupActivity.APP_LINK_TEST_VALUE,
+                        intent.getStringExtra(MockTvInputSetupActivity.APP_LINK_TEST_KEY))) {
+            getPostTarget().removeCallbacks(mSelectAppLinkFailCallback);
+            setPassState(mVerifyAppLinkIntentItem, true);
+            setButtonEnabled(mVerifyAppLinkCardItem, true);
+        }
+    }
+
+    @Override
+    protected void createTestItems() {
+        mSelectAppLinkItem = createUserItem(R.string.tv_app_link_test_select_app_link,
+                R.string.tv_launch_tv_app, this);
+        setButtonEnabled(mSelectAppLinkItem, true);
+        mVerifyAppLinkIntentItem = createAutoItem(
+                R.string.tv_app_link_test_verify_link_clicked);
+        mVerifyAppLinkCardItem = createUserItem(R.string.tv_input_link_test_verify_link_interface,
+                android.R.string.yes, this);
+        TextView instructions = (TextView) mVerifyAppLinkCardItem.findViewById(R.id.instructions);
+        Drawable image = getDrawable(R.drawable.app_link_img);
+        image.setBounds(0, 0, 317, 241);
+        instructions.setCompoundDrawablePadding(10);
+        instructions.setCompoundDrawables(image, null, null, null);
+    }
+
+    @Override
+    protected void setInfoResources() {
+        setInfoResources(R.string.tv_app_link_test, R.string.tv_app_link_test_info, -1);
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
index e7d1d79..f875684 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputService.java
@@ -16,9 +16,9 @@
 
 package com.android.cts.verifier.tv;
 
-import com.android.cts.verifier.R;
-
+import android.annotation.SuppressLint;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -27,20 +27,29 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Rect;
+import android.media.PlaybackParams;
 import android.media.tv.TvContentRating;
+import android.media.tv.TvContract;
 import android.media.tv.TvInputManager;
 import android.media.tv.TvInputService;
 import android.media.tv.TvTrackInfo;
 import android.net.Uri;
 import android.os.Bundle;
-import android.view.Surface;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
 import android.view.LayoutInflater;
+import android.view.Surface;
 import android.view.View;
 import android.widget.TextView;
 
+import com.android.cts.verifier.R;
+
 import java.util.ArrayList;
 import java.util.List;
 
+@SuppressLint("NewApi")
 public class MockTvInputService extends TvInputService {
     private static final String TAG = "MockTvInputService";
 
@@ -48,6 +57,7 @@
     private static final String SELECT_TRACK_TYPE = "type";
     private static final String SELECT_TRACK_ID = "id";
     private static final String CAPTION_ENABLED = "enabled";
+    private static final String PAUSE_CALLED = "pause_called";
 
     private static Object sLock = new Object();
     private static Callback sTuneCallback = null;
@@ -56,6 +66,14 @@
     private static Callback sUnblockContentCallback = null;
     private static Callback sSelectTrackCallback = null;
     private static Callback sSetCaptionEnabledCallback = null;
+    // Callbacks for time shift.
+    private static Callback sResumeAfterPauseCallback = null;
+    private static Callback sPositionTrackingCallback = null;
+    private static Callback sRewindCallback = null;
+    private static Callback sFastForwardCallback = null;
+    private static Callback sSeekToPreviousCallback = null;
+    private static Callback sSeekToNextCallback = null;
+
     private static TvContentRating sRating = null;
 
     static final TvTrackInfo sEngAudioTrack =
@@ -142,6 +160,47 @@
         }
     }
 
+    static void expectResumeAfterPause(View postTarget, Runnable successCallback) {
+        synchronized (sLock) {
+            sResumeAfterPauseCallback = new Callback(postTarget, successCallback);
+        }
+    }
+
+    static void expectPositionTracking(View postTarget, Runnable successCallback) {
+        synchronized (sLock) {
+            sPositionTrackingCallback = new Callback(postTarget, successCallback);
+        }
+    }
+
+    static void expectRewind(View postTarget, Runnable successCallback) {
+        synchronized (sLock) {
+            sRewindCallback = new Callback(postTarget, successCallback);
+        }
+    }
+
+    static void expectFastForward(View postTarget, Runnable successCallback) {
+        synchronized (sLock) {
+            sFastForwardCallback = new Callback(postTarget, successCallback);
+        }
+    }
+
+    static void expectSeekToPrevious(View postTarget, Runnable successCallback) {
+        synchronized (sLock) {
+            sSeekToPreviousCallback = new Callback(postTarget, successCallback);
+        }
+    }
+
+    static void expectSeekToNext(View postTarget, Runnable successCallback) {
+        synchronized (sLock) {
+            sSeekToNextCallback = new Callback(postTarget, successCallback);
+        }
+    }
+
+    static String getInputId(Context context) {
+        return TvContract.buildInputId(new ComponentName(context,
+                        MockTvInputService.class.getName()));
+    }
+
     @Override
     public void onCreate() {
         super.onCreate();
@@ -165,10 +224,45 @@
     }
 
     private static class MockSessionImpl extends Session {
+        private static final int MSG_SEEK = 1000;
+        private static final int SEEK_DELAY_MS = 300;
+
         private final Context mContext;
         private Surface mSurface = null;
         private List<TvTrackInfo> mTracks = new ArrayList<>();
 
+        private long mRecordStartTimeMs;
+        private long mPausedTimeMs;
+        // The time in milliseconds when the current position is lastly updated.
+        private long mLastCurrentPositionUpdateTimeMs;
+        // The current playback position.
+        private long mCurrentPositionMs;
+        // The current playback speed rate.
+        private float mSpeed;
+
+        private final Handler mHandler = new Handler(Looper.getMainLooper()) {
+            @Override
+            public void handleMessage(Message msg) {
+                if (msg.what == MSG_SEEK) {
+                    // Actually, this input doesn't play any videos, it just shows the image.
+                    // So we should simulate the playback here by changing the current playback
+                    // position periodically in order to test the time shift.
+                    // If the playback is paused, the current playback position doesn't need to be
+                    // changed.
+                    if (mPausedTimeMs == 0) {
+                        long currentTimeMs = System.currentTimeMillis();
+                        mCurrentPositionMs += (long) ((currentTimeMs
+                                - mLastCurrentPositionUpdateTimeMs) * mSpeed);
+                        mCurrentPositionMs = Math.max(mRecordStartTimeMs,
+                                Math.min(mCurrentPositionMs, currentTimeMs));
+                        mLastCurrentPositionUpdateTimeMs = currentTimeMs;
+                    }
+                    sendEmptyMessageDelayed(MSG_SEEK, SEEK_DELAY_MS);
+                }
+                super.handleMessage(msg);
+            }
+        };
+
         private MockSessionImpl(Context context) {
             super(context);
             mContext = context;
@@ -256,6 +350,12 @@
             notifyTracksChanged(mTracks);
             notifyTrackSelected(TvTrackInfo.TYPE_AUDIO, sEngAudioTrack.getId());
             notifyTrackSelected(TvTrackInfo.TYPE_SUBTITLE, null);
+            notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
+            mRecordStartTimeMs = mCurrentPositionMs = mLastCurrentPositionUpdateTimeMs
+                    = System.currentTimeMillis();
+            mPausedTimeMs = 0;
+            mHandler.sendEmptyMessageDelayed(MSG_SEEK, SEEK_DELAY_MS);
+            mSpeed = 1;
             return true;
         }
 
@@ -298,6 +398,88 @@
                 }
             }
         }
+
+        @Override
+        public long onTimeShiftGetCurrentPosition() {
+            synchronized (sLock) {
+                if (sPositionTrackingCallback != null) {
+                    sPositionTrackingCallback.post();
+                    sPositionTrackingCallback = null;
+                }
+            }
+            Log.d(TAG, "currentPositionMs=" + mCurrentPositionMs);
+            return mCurrentPositionMs;
+        }
+
+        @Override
+        public long onTimeShiftGetStartPosition() {
+            return mRecordStartTimeMs;
+        }
+
+        @Override
+        public void onTimeShiftPause() {
+            synchronized (sLock) {
+                if (sResumeAfterPauseCallback != null) {
+                    sResumeAfterPauseCallback.mBundle.putBoolean(PAUSE_CALLED, true);
+                }
+            }
+            mCurrentPositionMs = mPausedTimeMs = mLastCurrentPositionUpdateTimeMs
+                    = System.currentTimeMillis();
+        }
+
+        @Override
+        public void onTimeShiftResume() {
+            synchronized (sLock) {
+                if (sResumeAfterPauseCallback != null
+                        && sResumeAfterPauseCallback.mBundle.getBoolean(PAUSE_CALLED)) {
+                    sResumeAfterPauseCallback.post();
+                    sResumeAfterPauseCallback = null;
+                }
+            }
+            mSpeed = 1;
+            mPausedTimeMs = 0;
+            mLastCurrentPositionUpdateTimeMs = System.currentTimeMillis();
+        }
+
+        @Override
+        public void onTimeShiftSeekTo(long timeMs) {
+            synchronized (sLock) {
+                if (mCurrentPositionMs > timeMs) {
+                    if (sSeekToPreviousCallback != null) {
+                        sSeekToPreviousCallback.post();
+                        sSeekToPreviousCallback = null;
+                    }
+                } else if (mCurrentPositionMs < timeMs) {
+                    if (sSeekToNextCallback != null) {
+                        sSeekToNextCallback.post();
+                        sSeekToNextCallback = null;
+                    }
+                }
+            }
+            mLastCurrentPositionUpdateTimeMs = System.currentTimeMillis();
+            mCurrentPositionMs = Math.max(mRecordStartTimeMs,
+                    Math.min(timeMs, mLastCurrentPositionUpdateTimeMs));
+        }
+
+        @Override
+        public void onTimeShiftSetPlaybackParams(PlaybackParams params) {
+            synchronized(sLock) {
+                if (params != null) {
+                    if (params.getSpeed() > 1) {
+                        if (sFastForwardCallback != null) {
+                            sFastForwardCallback.post();
+                            sFastForwardCallback = null;
+                        }
+                    } else if (params.getSpeed() < 1) {
+                        if (sRewindCallback != null) {
+                            sRewindCallback.post();
+                            sRewindCallback = null;
+                        }
+                    }
+                }
+            }
+            mSpeed = params.getSpeed();
+        }
     }
 
     private static class Callback {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSettingsActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSettingsActivity.java
deleted file mode 100644
index 4231db7..0000000
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSettingsActivity.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.cts.verifier.tv;
-
-import android.preference.PreferenceActivity;
-
-public class MockTvInputSettingsActivity extends PreferenceActivity {
-
-}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSetupActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSetupActivity.java
index c05b753..43ed7da 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSetupActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MockTvInputSetupActivity.java
@@ -17,9 +17,12 @@
 package com.android.cts.verifier.tv;
 
 import android.app.Activity;
+import android.content.ComponentName;
 import android.content.ContentUris;
 import android.content.ContentValues;
+import android.content.Intent;
 import android.database.Cursor;
+import android.graphics.Color;
 import android.media.tv.TvContract;
 import android.media.tv.TvContract.Programs;
 import android.media.tv.TvInputInfo;
@@ -28,6 +31,8 @@
 import android.util.Pair;
 import android.view.View;
 
+import com.android.cts.verifier.R;
+
 import java.util.ArrayList;
 
 public class MockTvInputSetupActivity extends Activity {
@@ -38,6 +43,10 @@
 
     /* package-private */ static final String PROGRAM_TITLE = "Dummy Program";
     /* package-private */ static final String PROGRAM_DESCRIPTION = "Dummy Program Description";
+
+    /* package-private */ static final String APP_LINK_TEST_KEY = "app_link_test_key";
+    /* package-private */ static final String APP_LINK_TEST_VALUE = "app_link_test_value";
+    private static final String APP_LINK_TEXT = "Cts App-Link Text";
     private static final long PROGRAM_LENGTH_MILLIS = 60 * 60 * 1000;
     private static final int PROGRAM_COUNT = 24;
 
@@ -69,6 +78,18 @@
             values.put(TvContract.Channels.COLUMN_INPUT_ID, inputId);
             values.put(TvContract.Channels.COLUMN_DISPLAY_NUMBER, CHANNEL_NUMBER);
             values.put(TvContract.Channels.COLUMN_DISPLAY_NAME, CHANNEL_NAME);
+            values.put(TvContract.Channels.COLUMN_APP_LINK_TEXT, APP_LINK_TEXT);
+            values.put(TvContract.Channels.COLUMN_APP_LINK_COLOR, Color.RED);
+            values.put(TvContract.Channels.COLUMN_APP_LINK_ICON_URI,
+                    "android.resource://" + getPackageName() + "/" + R.drawable.icon);
+            values.put(TvContract.Channels.COLUMN_APP_LINK_POSTER_ART_URI,
+                    "android.resource://" + getPackageName() + "/" + R.raw.sns_texture);
+            Intent appLinkIntentUri = new Intent(this, AppLinkTestActivity.class);
+            appLinkIntentUri.putExtra(APP_LINK_TEST_KEY, APP_LINK_TEST_VALUE);
+            appLinkIntentUri.setFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
+            values.put(TvContract.Channels.COLUMN_APP_LINK_INTENT_URI,
+                    appLinkIntentUri.toUri(Intent.URI_INTENT_SCHEME));
+
             Uri channelUri = getContentResolver().insert(uri, values);
             // If the channel's ID happens to be zero, we add another and delete the one.
             if (ContentUris.parseId(channelUri) == 0) {
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MultipleTracksTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MultipleTracksTestActivity.java
index 66af4c6..a912cc6 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/MultipleTracksTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/MultipleTracksTestActivity.java
@@ -17,7 +17,7 @@
 package com.android.cts.verifier.tv;
 
 import com.android.cts.verifier.R;
-
+import android.annotation.SuppressLint;
 import android.content.Intent;
 import android.database.Cursor;
 import android.media.tv.TvContentRating;
@@ -36,6 +36,7 @@
 /**
  * Tests for verifying TV app behavior on multiple tracks and subtitle.
  */
+@SuppressLint("NewApi")
 public class MultipleTracksTestActivity extends TvAppVerifierActivity
         implements View.OnClickListener {
     private static final String TAG = "MultipleTracksTestActivity";
@@ -113,7 +114,8 @@
         }
         if (mTvAppIntent == null) {
             String[] projection = { TvContract.Channels._ID };
-            try (Cursor cursor = getContentResolver().query(TvContract.Channels.CONTENT_URI,
+            try (Cursor cursor = getContentResolver().query(
+                    TvContract.buildChannelsUriForInput(MockTvInputService.getInputId(this)),
                     projection, null, null, null)) {
                 if (cursor != null && cursor.moveToNext()) {
                     mTvAppIntent = new Intent(Intent.ACTION_VIEW,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/ParentalControlTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/ParentalControlTestActivity.java
index 284b485..c99da46 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/ParentalControlTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/ParentalControlTestActivity.java
@@ -17,7 +17,7 @@
 package com.android.cts.verifier.tv;
 
 import com.android.cts.verifier.R;
-
+import android.annotation.SuppressLint;
 import android.content.Intent;
 import android.database.Cursor;
 import android.media.tv.TvContentRating;
@@ -35,6 +35,7 @@
 /**
  * Tests for verifying TV app behavior on parental control.
  */
+@SuppressLint("NewApi")
 public class ParentalControlTestActivity extends TvAppVerifierActivity
         implements View.OnClickListener {
     private static final String TAG = "ParentalControlTestActivity";
@@ -110,7 +111,8 @@
         }
         if (mTvAppIntent == null) {
             String[] projection = { TvContract.Channels._ID };
-            try (Cursor cursor = getContentResolver().query(TvContract.Channels.CONTENT_URI,
+            try (Cursor cursor = getContentResolver().query(
+                    TvContract.buildChannelsUriForInput(MockTvInputService.getInputId(this)),
                     projection, null, null, null)) {
                 if (cursor != null && cursor.moveToNext()) {
                     mTvAppIntent = new Intent(Intent.ACTION_VIEW,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java
new file mode 100644
index 0000000..5e4036c
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TimeShiftTestActivity.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.tv;
+
+import android.content.Intent;
+import android.database.Cursor;
+import android.media.tv.TvContract;
+import android.view.View;
+import android.widget.Toast;
+
+import com.android.cts.verifier.R;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for verifying TV app behavior on time shift.
+ */
+public class TimeShiftTestActivity extends TvAppVerifierActivity
+        implements View.OnClickListener {
+    private static final long TIMEOUT_MS = TimeUnit.MINUTES.toMillis(5);
+    private static final boolean NOT_PASSED = false;
+    private static final boolean PASSED = true;
+
+    private View mPauseResumeItem;
+    private View mVerifyResumeAfterPauseItem;
+    private View mVerifyPositionTrackingItem;
+
+    private View mSetPlaybackParamsItem;
+    private View mVerifyRewindItem;
+    private View mVerifyFastForwardItem;
+
+    private View mSeekToItem;
+    private View mVerifySeekToPreviousItem;
+    private View mVerifySeekToNextItem;
+
+    private Intent mTvAppIntent = null;
+
+    @Override
+    public void onClick(View v) {
+        final View postTarget = getPostTarget();
+
+        if (containsButton(mPauseResumeItem, v)) {
+            mVerifyResumeAfterPauseItem.setTag(NOT_PASSED);
+            mVerifyPositionTrackingItem.setTag(NOT_PASSED);
+
+            final Runnable failCallback = new Runnable() {
+                @Override
+                public void run() {
+                    setPassState(mVerifyResumeAfterPauseItem, false);
+                    setPassState(mVerifyPositionTrackingItem, false);
+                }
+            };
+            postTarget.postDelayed(failCallback, TIMEOUT_MS);
+            MockTvInputService.expectResumeAfterPause(postTarget, new Runnable() {
+                @Override
+                public void run() {
+                    postTarget.removeCallbacks(failCallback);
+                    setPassState(mPauseResumeItem, true);
+                    setPassState(mVerifyResumeAfterPauseItem, true);
+                    mVerifyResumeAfterPauseItem.setTag(PASSED);
+                    if (isPassedState(mVerifyResumeAfterPauseItem)
+                            && isPassedState(mVerifyPositionTrackingItem)) {
+                        setButtonEnabled(mSetPlaybackParamsItem, true);
+                    }
+                }
+            });
+            MockTvInputService.expectPositionTracking(postTarget, new Runnable() {
+                @Override
+                public void run() {
+                    postTarget.removeCallbacks(failCallback);
+                    setPassState(mPauseResumeItem, true);
+                    setPassState(mVerifyPositionTrackingItem, true);
+                    mVerifyPositionTrackingItem.setTag(PASSED);
+                    if (isPassedState(mVerifyResumeAfterPauseItem)
+                            && isPassedState(mVerifyPositionTrackingItem)) {
+                        setButtonEnabled(mSetPlaybackParamsItem, true);
+                    }
+                }
+            });
+        } else if (containsButton(mSetPlaybackParamsItem, v)) {
+            mVerifyRewindItem.setTag(NOT_PASSED);
+            mVerifyFastForwardItem.setTag(NOT_PASSED);
+
+            final Runnable failCallback = new Runnable() {
+                @Override
+                public void run() {
+                    setPassState(mVerifyRewindItem, false);
+                    setPassState(mVerifyFastForwardItem, false);
+                }
+            };
+            postTarget.postDelayed(failCallback, TIMEOUT_MS);
+            MockTvInputService.expectRewind(postTarget, new Runnable() {
+                @Override
+                public void run() {
+                    postTarget.removeCallbacks(failCallback);
+                    setPassState(mSetPlaybackParamsItem, true);
+                    setPassState(mVerifyRewindItem, true);
+                    mVerifyRewindItem.setTag(PASSED);
+                    if (isPassedState(mVerifyRewindItem) && isPassedState(mVerifyFastForwardItem)) {
+                        setButtonEnabled(mSeekToItem, true);
+                    }
+                }
+            });
+            MockTvInputService.expectFastForward(postTarget, new Runnable() {
+                @Override
+                public void run() {
+                    postTarget.removeCallbacks(failCallback);
+                    setPassState(mSetPlaybackParamsItem, true);
+                    setPassState(mVerifyFastForwardItem, true);
+                    mVerifyFastForwardItem.setTag(PASSED);
+                    if (isPassedState(mVerifyRewindItem) && isPassedState(mVerifyFastForwardItem)) {
+                        setButtonEnabled(mSeekToItem, true);
+                    }
+                }
+            });
+        } else if (containsButton(mSeekToItem, v)) {
+            mVerifySeekToPreviousItem.setTag(NOT_PASSED);
+            mVerifySeekToNextItem.setTag(NOT_PASSED);
+
+            final Runnable failCallback = new Runnable() {
+                @Override
+                public void run() {
+                    setPassState(mVerifySeekToPreviousItem, false);
+                    setPassState(mVerifySeekToNextItem, false);
+                }
+            };
+            postTarget.postDelayed(failCallback, TIMEOUT_MS);
+            MockTvInputService.expectSeekToPrevious(postTarget, new Runnable() {
+                @Override
+                public void run() {
+                    postTarget.removeCallbacks(failCallback);
+                    setPassState(mSeekToItem, true);
+                    setPassState(mVerifySeekToPreviousItem, true);
+                    mVerifySeekToPreviousItem.setTag(PASSED);
+                    if (isPassedState(mVerifySeekToPreviousItem)
+                            && isPassedState(mVerifySeekToNextItem)) {
+                        getPassButton().setEnabled(true);
+                    }
+                }
+            });
+            MockTvInputService.expectSeekToNext(postTarget, new Runnable() {
+                @Override
+                public void run() {
+                    postTarget.removeCallbacks(failCallback);
+                    setPassState(mSeekToItem, true);
+                    setPassState(mVerifySeekToNextItem, true);
+                    mVerifySeekToNextItem.setTag(PASSED);
+                    if (isPassedState(mVerifySeekToPreviousItem)
+                            && isPassedState(mVerifySeekToNextItem)) {
+                        getPassButton().setEnabled(true);
+                    }
+                }
+            });
+        }
+        if (mTvAppIntent == null) {
+            String[] projection = { TvContract.Channels._ID };
+            try (Cursor cursor = getContentResolver().query(
+                    TvContract.buildChannelsUriForInput(MockTvInputService.getInputId(this)),
+                    projection, null, null, null)) {
+                if (cursor != null && cursor.moveToNext()) {
+                    mTvAppIntent = new Intent(Intent.ACTION_VIEW,
+                            TvContract.buildChannelUri(cursor.getLong(0)));
+                }
+            }
+            if (mTvAppIntent == null) {
+                Toast.makeText(this, R.string.tv_channel_not_found, Toast.LENGTH_SHORT).show();
+                return;
+            }
+        }
+        startActivity(mTvAppIntent);
+    }
+
+    @Override
+    protected void createTestItems() {
+        mPauseResumeItem = createUserItem(
+                R.string.tv_time_shift_test_pause_resume,
+                R.string.tv_launch_tv_app, this);
+        setButtonEnabled(mPauseResumeItem, true);
+        mVerifyResumeAfterPauseItem = createAutoItem(
+                R.string.tv_time_shift_test_verify_resume_after_pause);
+        mVerifyPositionTrackingItem = createAutoItem(
+                R.string.tv_time_shift_test_verify_position_tracking);
+        mSetPlaybackParamsItem = createUserItem(
+                R.string.tv_time_shift_test_speed_rate,
+                R.string.tv_launch_tv_app, this);
+        mVerifyRewindItem = createAutoItem(
+                R.string.tv_time_shift_test_verify_rewind);
+        mVerifyFastForwardItem = createAutoItem(
+                R.string.tv_time_shift_test_verify_fast_forward);
+        mSeekToItem = createUserItem(
+                R.string.tv_time_shift_test_seek,
+                R.string.tv_launch_tv_app, this);
+        mVerifySeekToPreviousItem = createAutoItem(
+                R.string.tv_time_shift_test_verify_seek_to_previous);
+        mVerifySeekToNextItem = createAutoItem(
+                R.string.tv_time_shift_test_verify_seek_to_next);
+    }
+
+    @Override
+    protected void setInfoResources() {
+        setInfoResources(R.string.tv_time_shift_test,
+                R.string.tv_time_shift_test_info, -1);
+    }
+
+    private boolean isPassedState(View view) {
+        return ((Boolean) view.getTag()) == PASSED;
+    }
+}
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java
index 12e9652..acab18e 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvAppVerifierActivity.java
@@ -35,8 +35,6 @@
 public abstract class TvAppVerifierActivity extends PassFailButtons.Activity {
     private static final String TAG = "TvAppVerifierActivity";
 
-    private static final long TIMEOUT_MS = 5l * 60l * 1000l;  // 5 mins.
-
     private LayoutInflater mInflater;
     private ViewGroup mItemList;
     private View mPostTarget;
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 06f4f6f..e8e2cee 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/tv/TvInputDiscoveryTestActivity.java
@@ -25,8 +25,6 @@
 
 import com.android.cts.verifier.R;
 
-import java.util.List;
-
 /**
  * Tests for verifying TV app behavior for third-party TV input apps.
  */
@@ -131,7 +129,7 @@
         mGoToEpgItem = createUserItem(R.string.tv_input_discover_test_go_to_epg,
                 R.string.tv_launch_epg, this);
         mVerifyEpgItem = createUserItem(R.string.tv_input_discover_test_verify_epg,
-                R.string.tv_input_discover_test_yes, this);
+                android.R.string.yes, this);
     }
 
     @Override
diff --git a/apps/PermissionApp/Android.mk b/apps/PermissionApp/Android.mk
new file mode 100644
index 0000000..57950da
--- /dev/null
+++ b/apps/PermissionApp/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 := 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)
+
+LOCAL_PACKAGE_NAME := CtsPermissionApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/apps/PermissionApp/AndroidManifest.xml b/apps/PermissionApp/AndroidManifest.xml
new file mode 100644
index 0000000..82e3617
--- /dev/null
+++ b/apps/PermissionApp/AndroidManifest.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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.permissionapp">
+
+    <uses-sdk android:minSdkVersion="23"/>
+
+    <uses-permission android:name="android.permission.READ_CONTACTS"/>
+
+    <application android:label="CtsPermissionApp"
+            android:icon="@drawable/ic_permissionapp">
+        <activity android:name=".PermissionActivity" >
+            <intent-filter>
+                <action android:name="com.android.cts.permission.action.CHECK_HAS_PERMISSION" />
+                <action android:name="com.android.cts.permission.action.REQUEST_PERMISSION" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
+
diff --git a/apps/PermissionApp/res/drawable-hdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-hdpi/ic_permissionapp.png
new file mode 100644
index 0000000..6fe4112
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-hdpi/ic_permissionapp.png
Binary files differ
diff --git a/apps/PermissionApp/res/drawable-mdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-mdpi/ic_permissionapp.png
new file mode 100644
index 0000000..a7a5666
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-mdpi/ic_permissionapp.png
Binary files differ
diff --git a/apps/PermissionApp/res/drawable-xhdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-xhdpi/ic_permissionapp.png
new file mode 100644
index 0000000..1e47732
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-xhdpi/ic_permissionapp.png
Binary files differ
diff --git a/apps/PermissionApp/res/drawable-xxhdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-xxhdpi/ic_permissionapp.png
new file mode 100644
index 0000000..0e849b3
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-xxhdpi/ic_permissionapp.png
Binary files differ
diff --git a/apps/PermissionApp/res/drawable-xxxhdpi/ic_permissionapp.png b/apps/PermissionApp/res/drawable-xxxhdpi/ic_permissionapp.png
new file mode 100644
index 0000000..242a6b1
--- /dev/null
+++ b/apps/PermissionApp/res/drawable-xxxhdpi/ic_permissionapp.png
Binary files differ
diff --git a/apps/PermissionApp/src/com/android/cts/permission/permissionapp/PermissionActivity.java b/apps/PermissionApp/src/com/android/cts/permission/permissionapp/PermissionActivity.java
new file mode 100644
index 0000000..01b60d3
--- /dev/null
+++ b/apps/PermissionApp/src/com/android/cts/permission/permissionapp/PermissionActivity.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 com.android.cts.permissionapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity that requests permissions and returns the result.
+ */
+public class PermissionActivity extends Activity {
+    private static final String TAG = "PermissionActivity";
+
+    private static final String ACTION_CHECK_HAS_PERMISSION
+            = "com.android.cts.permission.action.CHECK_HAS_PERMISSION";
+    private static final String ACTION_REQUEST_PERMISSION
+            = "com.android.cts.permission.action.REQUEST_PERMISSION";
+    private static final String ACTION_PERMISSION_RESULT
+            = "com.android.cts.permission.action.PERMISSION_RESULT";
+    private static final String EXTRA_PERMISSION
+            = "com.android.cts.permission.extra.PERMISSION";
+    private static final String EXTRA_GRANT_STATE
+            = "com.android.cts.permission.extra.GRANT_STATE";
+    private static final int PERMISSION_ERROR = -2;
+    private static final int PERMISSIONS_REQUEST_CODE = 100;
+
+    private String mPermission;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final Intent received = getIntent();
+        Log.d(TAG, "Started with " + received);
+
+        final String action = received.getAction();
+        mPermission = received.getStringExtra(EXTRA_PERMISSION);
+        if (ACTION_REQUEST_PERMISSION.equals(action)) {
+            Log.d(TAG, "Requesting permission " + mPermission);
+            requestPermissions(new String[] {mPermission}, PERMISSIONS_REQUEST_CODE);
+        } else if (ACTION_CHECK_HAS_PERMISSION.equals(action)) {
+            Log.d(TAG, "Checking permission " + mPermission);
+            sendResultBroadcast(checkSelfPermission(mPermission));
+        } else {
+            Log.w(TAG, "Unknown intent received: " + received);
+            finish();
+        }
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions,
+            int[] grantResults) {
+        if (requestCode != PERMISSIONS_REQUEST_CODE ||
+                permissions.length != 1 ||
+                !permissions[0].equals(mPermission)) {
+            Log.d(TAG, "Received wrong permissions result");
+            sendResultBroadcast(PERMISSION_ERROR);
+        } else {
+            Log.d(TAG, "Received valid permission result: " + grantResults[0]);
+            sendResultBroadcast(grantResults[0]);
+        }
+    }
+
+    private void sendResultBroadcast(int result) {
+        Log.d(TAG, "Sending result broadcast: " + result);
+        Intent broadcast = new Intent(ACTION_PERMISSION_RESULT);
+        broadcast.putExtra(EXTRA_GRANT_STATE, result);
+        sendBroadcast(broadcast);
+        finish();
+    }
+}
diff --git a/apps/cts-usb-accessory/Android.mk b/apps/cts-usb-accessory/Android.mk
index 8d18da3..f3a7ebd 100644
--- a/apps/cts-usb-accessory/Android.mk
+++ b/apps/cts-usb-accessory/Android.mk
@@ -33,6 +33,7 @@
 LOCAL_STATIC_LIBRARIES := libusbhost libcutils
 LOCAL_LDLIBS += -lpthread
 LOCAL_CFLAGS := -g -O0
+LOCAL_CXX_STL := none
 
 include $(BUILD_HOST_EXECUTABLE)
 
diff --git a/build/config.mk b/build/config.mk
index 931220b..56d4ae6 100644
--- a/build/config.mk
+++ b/build/config.mk
@@ -12,6 +12,32 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# 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
+
+# Scanners of source files for tests which are then inputed into
+# the XML generator to produce test XMLs.
+CTS_NATIVE_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-native-scanner
+CTS_JAVA_TEST_SCANNER := $(HOST_OUT_EXECUTABLES)/cts-java-scanner
+CTS_JAVA_TEST_SCANNER_DOCLET := $(HOST_OUT_JAVA_LIBRARIES)/cts-java-scanner-doclet.jar
+
+# Generator of test XMLs from scanner output.
+CTS_XML_GENERATOR := $(HOST_OUT_EXECUTABLES)/cts-xml-generator
+
+# File indicating which tests should be blacklisted due to problems.
+CTS_EXPECTATIONS := cts/tests/expectations/knownfailures.txt
+
+# File indicating which tests should be blacklisted due to unsupported abi.
+CTS_UNSUPPORTED_ABIS := cts/tests/expectations/unsupportedabis.txt
+
+# Holds the target architecture to build for.
+CTS_TARGET_ARCH := $(TARGET_ARCH)
+
+# default module config filename
+CTS_MODULE_TEST_CONFIG := AndroidTest.xml
+
+# CTS build rules
 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
@@ -19,3 +45,6 @@
 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
+BUILD_CTS_DEVICE_INFO_PACKAGE := cts/build/device_info_package.mk
diff --git a/build/device_info_package.mk b/build/device_info_package.mk
new file mode 100644
index 0000000..0aaa8aa
--- /dev/null
+++ b/build/device_info_package.mk
@@ -0,0 +1,67 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 package which can be instrumented to retrieve information about the device under test.
+#
+
+DEVICE_INFO_PACKAGE := com.android.compatibility.common.deviceinfo
+DEVICE_INFO_INSTRUMENT := com.android.compatibility.common.deviceinfo.DeviceInfoInstrument
+DEVICE_INFO_PERMISSIONS += android.permission.WRITE_EXTERNAL_STORAGE
+DEVICE_INFO_ACTIVITIES += $(DEVICE_INFO_PACKAGE).GenericDeviceInfo $(DEVICE_INFO_PACKAGE).PackageDeviceInfo
+
+# Add the base device info
+LOCAL_STATIC_JAVA_LIBRARIES += compatibility-device-info
+
+# Generator of APK manifests.
+MANIFEST_GENERATOR_JAR := $(HOST_OUT_JAVA_LIBRARIES)/compatibility-manifest-generator.jar
+MANIFEST_GENERATOR := java -jar $(MANIFEST_GENERATOR_JAR)
+
+# Generate the manifest
+manifest_xml := $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/AndroidManifest.xml
+$(manifest_xml): PRIVATE_INFO_PERMISSIONS := $(foreach permission, $(DEVICE_INFO_PERMISSIONS),-r $(permission))
+$(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)
+
+# 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
+	$(hide) echo Generating manifest for $(PRIVATE_NAME)
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(MANIFEST_GENERATOR) \
+						$(PRIVATE_INFO_PERMISSIONS) \
+						$(PRIVATE_INFO_ACTIVITIES) \
+						-p $(PRIVATE_PACKAGE) \
+						-i $(PRIVATE_INSTRUMENT) \
+						-o $@
+
+# Reset variables
+DEVICE_INFO_PACKAGE :=
+DEVICE_INFO_INSTRUMENT :=
+DEVICE_INFO_PERMISSIONS :=
+DEVICE_INFO_ACTIVITIES :=
+
+LOCAL_FULL_MANIFEST_FILE := $(manifest_xml)
+# Disable by default
+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_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/build/module_test_config.mk b/build/module_test_config.mk
new file mode 100644
index 0000000..6584ef2
--- /dev/null
+++ b/build/module_test_config.mk
@@ -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.
+
+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)
+	$(call copy-file-to-target)
+endif
diff --git a/build/support_package.mk b/build/support_package.mk
new file mode 100644
index 0000000..16a254e
--- /dev/null
+++ b/build/support_package.mk
@@ -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.
+
+#
+# Builds a package which is needed by a test package and copies it to CTS
+#
+# Replace "include $(BUILD_PACKAGE)" with "include $(BUILD_CTS_SUPPORT_PACKAGE)"
+#
+
+# Disable by default so "m cts" will work in emulator builds
+LOCAL_DEX_PREOPT := false
+LOCAL_PROGUARD_ENABLED := disabled
+
+include $(BUILD_PACKAGE)
+
+cts_support_apks :=
+$(foreach fp, $(ALL_MODULES.$(LOCAL_PACKAGE_NAME).BUILT_INSTALLED),\
+  $(eval pair := $(subst :,$(space),$(fp)))\
+  $(eval built := $(word 1,$(pair)))\
+  $(eval installed := $(CTS_TESTCASES_OUT)/$(notdir $(word 2,$(pair))))\
+  $(eval $(call copy-one-file, $(built), $(installed)))\
+  $(eval cts_support_apks += $(installed)))
+
+# 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_support_apks)
diff --git a/build/test_deqp_package.mk b/build/test_deqp_package.mk
index b07876d..650875c 100644
--- a/build/test_deqp_package.mk
+++ b/build/test_deqp_package.mk
@@ -18,16 +18,14 @@
 
 CTS_DEQP_CONFIG_PATH := $(call my-dir)
 
-cts_library_xml := $(CTS_TESTCASES_OUT)/com.drawelements.deqp.$(DEQP_API).xml
-
-$(cts_library_xml): MUSTPASS_XML_FILE := external/deqp/android/cts/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): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk external/deqp/android/cts/com.drawelements.deqp.$(DEQP_API).xml $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_XML_GENERATOR)
-	$(hide) echo Generating test description for $(PRIVATE_TEST_NAME)
+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 $@
 	$(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 \
@@ -37,8 +35,7 @@
 										-a $(CTS_TARGET_ARCH) \
 										< $(PRIVATE_DUMMY_CASELIST) \
 										| grep --only-matching -e " abis=\"[^\"]*\""))
-	
 # Patch xml caselist with supported abi
-	$(hide) $(SED_EXTENDED) -e 's:^<Test (.*)/>$$:<Test \1 $(supported_abi_attr) />:' \
-				< $(MUSTPASS_XML_FILE) \
+	$(hide) $(SED_EXTENDED) -e 's:^(\s*)<Test ((.[^/]|[^/])*)(/?)>$$:\1<Test \2 $(supported_abi_attr)\4>:' \
+				< $< \
 				> $@
diff --git a/build/test_executable.mk b/build/test_executable.mk
index 02b3e4c..979f59e 100644
--- a/build/test_executable.mk
+++ b/build/test_executable.mk
@@ -23,15 +23,24 @@
 #    as needed by CTS.
 #
 
+LOCAL_CXX_STL := libc++
 include $(BUILD_EXECUTABLE)
+include $(BUILD_CTS_MODULE_TEST_CONFIG)
+
+cts_executable_bin :=
+$(foreach fp, $(ALL_MODULES.$(LOCAL_MODULE).BUILT) $(ALL_MODULES.$(LOCAL_MODULE)$(TARGET_2ND_ARCH_MODULE_SUFFIX).BUILT),\
+  $(eval installed := $(CTS_TESTCASES_OUT)/$(notdir $(fp)))\
+  $(eval $(call copy-one-file, $(fp), $(installed)))\
+  $(eval cts_executable_bin += $(installed)))
 
 cts_executable_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
-
 $(cts_executable_xml): PRIVATE_TEST_PACKAGE := $(LOCAL_CTS_TEST_PACKAGE)
 $(cts_executable_xml): PRIVATE_EXECUTABLE := $(LOCAL_MODULE)
 $(cts_executable_xml): PRIVATE_LIST_EXECUTABLE := $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)_list
 $(cts_executable_xml): $(HOST_OUT_EXECUTABLES)/$(LOCAL_MODULE)_list
-$(cts_executable_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR) $(cts_list_executable)
+$(cts_executable_xml): $(cts_executable_bin)
+$(cts_executable_xml): $(cts_module_test_config)
+$(cts_executable_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES)) $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR)
 	$(hide) echo Generating test description for native package $(PRIVATE_TEST_PACKAGE)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) $(PRIVATE_LIST_EXECUTABLE) --gtest_list_tests | \
@@ -45,4 +54,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_executable_xml)
+$(my_register_name) : $(cts_executable_bin) $(cts_executable_xml) $(cts_module_test_config)
diff --git a/build/test_gtest_package.mk b/build/test_gtest_package.mk
index dd1269b..6f71830 100644
--- a/build/test_gtest_package.mk
+++ b/build/test_gtest_package.mk
@@ -23,23 +23,19 @@
 LOCAL_DEX_PREOPT := false
 LOCAL_PROGUARD_ENABLED := disabled
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+include $(BUILD_CTS_MODULE_TEST_CONFIG)
 
-cts_package_apk := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).apk
 cts_package_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).xml
-cts_test_list := $(LOCAL_PATH)/$(LOCAL_MODULE)_list.txt
-
-$(cts_package_apk): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
-$(cts_package_apk): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk | $(ACP)
-	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
-	$(hide) $(ACP) -fp $(call intermediates-dir-for,APPS,$(PRIVATE_PACKAGE))/package.apk $@
-
 $(cts_package_xml): PRIVATE_PATH := $(LOCAL_PATH)
 $(cts_package_xml): PRIVATE_TEST_PACKAGE := android.$(notdir $(LOCAL_PATH))
 $(cts_package_xml): PRIVATE_EXECUTABLE := $(LOCAL_MODULE)
 $(cts_package_xml): PRIVATE_MANIFEST := $(LOCAL_PATH)/AndroidManifest.xml
-$(cts_package_xml): PRIVATE_TEST_LIST := $(cts_test_list)
-$(cts_package_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES))  $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR) $(cts_test_list)
+$(cts_package_xml): PRIVATE_TEST_LIST := $(LOCAL_PATH)/$(LOCAL_MODULE)_list.txt
+$(cts_package_xml): $(LOCAL_PATH)/$(LOCAL_MODULE)_list.txt
+$(cts_package_xml): $(cts_support_apks)
+$(cts_package_xml): $(cts_module_test_config)
+$(cts_package_xml): $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES))  $(CTS_NATIVE_TEST_SCANNER) $(CTS_XML_GENERATOR)
 	$(hide) echo Generating test description for wrapped native package $(PRIVATE_EXECUTABLE)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) cat $(PRIVATE_TEST_LIST) | \
@@ -54,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_package_apk) $(cts_package_xml)
+$(my_register_name) : $(cts_package_xml) $(cts_module_test_config)
diff --git a/build/test_host_java_library.mk b/build/test_host_java_library.mk
index 8ed5670..b4c7e63 100644
--- a/build/test_host_java_library.mk
+++ b/build/test_host_java_library.mk
@@ -18,18 +18,29 @@
 #
 
 include $(BUILD_HOST_JAVA_LIBRARY)
+include $(BUILD_CTS_MODULE_TEST_CONFIG)
 
-cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
+cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
+$(cts_library_jar): $(LOCAL_BUILT_MODULE)
+	$(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
+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)
 $(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
-$(cts_library_xml): $(HOST_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE).jar $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(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 host library $(PRIVATE_LIBRARY)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) $(CTS_JAVA_TEST_SCANNER) $(PRIVATE_SRC_DIRS) \
@@ -38,10 +49,11 @@
 						-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) \
 						-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_xml)
+$(my_register_name) : $(cts_library_jar) $(cts_library_xml) $(cts_module_test_config)
diff --git a/build/test_package.mk b/build/test_package.mk
index 7589787..13e582e 100644
--- a/build/test_package.mk
+++ b/build/test_package.mk
@@ -23,20 +23,14 @@
 LOCAL_DEX_PREOPT := false
 LOCAL_PROGUARD_ENABLED := disabled
 
-include $(BUILD_PACKAGE)
-
-cts_package_apk := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).apk
-cts_package_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).xml
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+include $(BUILD_CTS_MODULE_TEST_CONFIG)
 
 cts_src_dirs := $(LOCAL_PATH)
 cts_src_dirs += $(sort $(dir $(LOCAL_GENERATED_SOURCES)))
 cts_src_dirs := $(addprefix -s , $(cts_src_dirs))
 
-$(cts_package_apk): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
-$(cts_package_apk): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk | $(ACP)
-	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
-	$(hide) $(ACP) -fp $(call intermediates-dir-for,APPS,$(PRIVATE_PACKAGE))/package.apk $@
-
+cts_package_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_PACKAGE_NAME).xml
 $(cts_package_xml): PRIVATE_SRC_DIRS := $(cts_src_dirs)
 $(cts_package_xml): PRIVATE_INSTRUMENTATION := $(LOCAL_INSTRUMENTATION_FOR)
 $(cts_package_xml): PRIVATE_PACKAGE := $(LOCAL_PACKAGE_NAME)
@@ -45,10 +39,17 @@
 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),'')
-$(cts_package_xml): $(call intermediates-dir-for,APPS,$(LOCAL_PACKAGE_NAME))/package.apk $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(cts_package_xml): $(cts_support_apks)
+$(cts_package_xml): $(cts_module_test_config)
+$(cts_package_xml): $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
 	$(hide) echo Generating test description for java package $(PRIVATE_PACKAGE)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) $(CTS_JAVA_TEST_SCANNER) \
@@ -60,10 +61,13 @@
 						-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_apk) $(cts_package_xml)
+$(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 04fffb9..fe1000a 100644
--- a/build/test_target_java_library.mk
+++ b/build/test_target_java_library.mk
@@ -19,8 +19,10 @@
 # Disable by default so "m cts" will work in emulator builds
 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) | $(ACP)
+$(cts_library_jar): $(LOCAL_BUILT_MODULE)
 	$(copy-file-to-target)
 
 cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml
@@ -30,7 +32,9 @@
 $(cts_library_xml): PRIVATE_LIBRARY := $(LOCAL_MODULE)
 $(cts_library_xml): PRIVATE_JAR_PATH := $(LOCAL_MODULE).jar
 $(cts_library_xml): PRIVATE_RUNTIME_ARGS := $(LOCAL_CTS_TARGET_RUNTIME_ARGS)
-$(cts_library_xml): $(TARGET_OUT_JAVA_LIBRARIES)/$(LOCAL_MODULE).jar $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(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 target library $(PRIVATE_LIBRARY)
 	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
 	$(hide) $(CTS_JAVA_TEST_SCANNER) -s $(PRIVATE_PATH) \
@@ -46,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)
+$(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
index cad6e4f..a191d72 100644
--- a/build/test_uiautomator.mk
+++ b/build/test_uiautomator.mk
@@ -20,26 +20,26 @@
 LOCAL_DEX_PREOPT := false
 
 include $(BUILD_JAVA_LIBRARY)
+include $(BUILD_CTS_MODULE_TEST_CONFIG)
 
-cts_library_xml := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).xml 
 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_jar): PRIVATE_MODULE := $(LOCAL_MODULE)
-$(cts_library_jar): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE))/javalib.jar | $(ACP)
-	$(hide) mkdir -p $(CTS_TESTCASES_OUT)
-	$(hide) $(ACP) -fp $(call intermediates-dir-for,JAVA_LIBRARIES,$(PRIVATE_MODULE))/javalib.jar $@
-
+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): $(call intermediates-dir-for,JAVA_LIBRARIES,$(LOCAL_MODULE))/javalib.jar $(CTS_EXPECTATIONS) $(CTS_UNSUPPORTED_ABIS) $(CTS_JAVA_TEST_SCANNER_DOCLET) $(CTS_JAVA_TEST_SCANNER) $(CTS_XML_GENERATOR)
+$(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) \
@@ -57,4 +57,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)
+$(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
new file mode 100644
index 0000000..0f5e8d3
--- /dev/null
+++ b/common/device-side/device-info/Android.mk
@@ -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.
+
+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-info
+
+# uncomment when b/13282254 is fixed
+#LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
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
new file mode 100644
index 0000000..f9de6eb
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivity.java
@@ -0,0 +1,450 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.text.TextUtils;
+import android.util.JsonWriter;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * 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 JsonWriter mJsonWriter = null;
+    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);
+        if (createFilePath()) {
+            createJsonWriter();
+            startJsonWriter();
+            collectDeviceInfo();
+            closeJsonWriter();
+
+            if (mResultCode == DEVICE_INFO_RESULT_STARTED) {
+                mResultCode = DEVICE_INFO_RESULT_OK;
+            }
+        }
+
+        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();
+
+    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);
+    }
+
+    private boolean createFilePath() {
+        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            failed("External storage is not mounted");
+            return false;
+        }
+        final File dir = new File(Environment.getExternalStorageDirectory(), "device-info-files");
+        if (!dir.mkdirs() && !dir.isDirectory()) {
+            failed("Cannot create directory for device info files");
+            return false;
+        }
+
+        // Create file at /sdcard/device-info-files/<class_name>.deviceinfo.json
+        final File jsonFile = new File(dir, getClass().getSimpleName() + ".deviceinfo.json");
+        try {
+            jsonFile.createNewFile();
+        } catch (Exception e) {
+            failed("Cannot create file to collect device info");
+            return false;
+        }
+        mResultFilePath = jsonFile.getAbsolutePath();
+        return true;
+    }
+
+    private void createJsonWriter() {
+        try {
+            FileOutputStream out = new FileOutputStream(mResultFilePath);
+            mJsonWriter = new JsonWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8));
+            // TODO(agathaman): remove to make json output less pretty
+            mJsonWriter.setIndent("  ");
+        } catch (Exception e) {
+            failed("Failed to create JSON writer: " + e.getMessage());
+        }
+    }
+
+    private void startJsonWriter() {
+        try {
+            mJsonWriter.beginObject();
+        } catch (Exception e) {
+            failed("Failed to begin JSON object: " + e.getMessage());
+        }
+    }
+
+    private void closeJsonWriter() {
+        try {
+            mJsonWriter.endObject();
+            mJsonWriter.close();
+        } catch (Exception e) {
+            failed("Failed to close JSON object: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Start a new group of result.
+     */
+    public void startGroup() {
+        try {
+            mJsonWriter.beginObject();
+        } catch (Exception e) {
+            error("Failed to begin JSON group: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Start a new group of result with specified name.
+     */
+    public void startGroup(String name) {
+        try {
+            mJsonWriter.name(name);
+            mJsonWriter.beginObject();
+        } catch (Exception e) {
+            error("Failed to begin JSON group: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Complete adding result to the last started group.
+     */
+    public void endGroup() {
+        try {
+            mJsonWriter.endObject();
+        } catch (Exception e) {
+            error("Failed to end JSON group: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Start a new array of result.
+     */
+    public void startArray() {
+        try {
+            mJsonWriter.beginArray();
+        } catch (Exception e) {
+            error("Failed to begin JSON array: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Start a new array of result with specified name.
+     */
+    public void startArray(String name) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name);
+            mJsonWriter.beginArray();
+        } catch (Exception e) {
+            error("Failed to begin JSON array: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Complete adding result to the last started array.
+     */
+    public void endArray() {
+        try {
+            mJsonWriter.endArray();
+        } catch (Exception e) {
+            error("Failed to end JSON group: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Add a double value result.
+     */
+    public void addResult(String name, double value) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name).value(value);
+        } catch (Exception e) {
+            error("Failed to add result for type double: " + e.getMessage());
+        }
+    }
+
+    /**
+    * Add a long value result.
+    */
+    public void addResult(String name, long value) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name).value(value);
+        } catch (Exception e) {
+            error("Failed to add result for type long: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Add an int value result.
+     */
+    public void addResult(String name, int value) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name).value((Number) value);
+        } catch (Exception e) {
+            error("Failed to add result for type int: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Add a boolean value result.
+     */
+    public void addResult(String name, boolean value) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name).value(value);
+        } catch (Exception e) {
+            error("Failed to add result for type boolean: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Add a String value result.
+     */
+    public void addResult(String name, String value) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name).value(checkString(value));
+        } catch (Exception e) {
+            error("Failed to add result for type String: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Add a double array result.
+     */
+    public void addArray(String name, double[] list) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name);
+            mJsonWriter.beginArray();
+            for (double value : checkArray(list)) {
+                mJsonWriter.value(value);
+            }
+            mJsonWriter.endArray();
+        } catch (Exception e) {
+            error("Failed to add result array for type double: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Add a long array result.
+     */
+    public void addArray(String name, long[] list) {
+        checkName(name);
+        try {
+        mJsonWriter.name(name);
+        mJsonWriter.beginArray();
+        for (long value : checkArray(list)) {
+            mJsonWriter.value(value);
+        }
+            mJsonWriter.endArray();
+        } catch (Exception e) {
+            error("Failed to add result array for type long: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Add an int array result.
+     */
+    public void addArray(String name, int[] list) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name);
+            mJsonWriter.beginArray();
+            for (int value : checkArray(list)) {
+                mJsonWriter.value((Number) value);
+            }
+            mJsonWriter.endArray();
+        } catch (Exception e) {
+            error("Failed to add result array for type int: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Add a boolean array result.
+     */
+    public void addArray(String name, boolean[] list) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name);
+            mJsonWriter.beginArray();
+            for (boolean value : checkArray(list)) {
+                mJsonWriter.value(value);
+            }
+            mJsonWriter.endArray();
+        } catch (Exception e) {
+            error("Failed to add result array for type boolean: " + e.getMessage());
+        }
+    }
+
+    /**
+     * Add a String array result.
+     */
+    public void addArray(String name, String[] list) {
+        checkName(name);
+        try {
+            mJsonWriter.name(name);
+            mJsonWriter.beginArray();
+            for (String value : checkArray(list)) {
+                mJsonWriter.value(checkString(value));
+            }
+            mJsonWriter.endArray();
+        } catch (Exception e) {
+            error("Failed to add result array for type Sting: " + e.getMessage());
+        }
+    }
+
+    private static boolean[] checkArray(boolean[] 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 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 String[] checkArray(String[] values) {
+        if (values.length > MAX_ARRAY_LENGTH) {
+            return Arrays.copyOf(values, MAX_ARRAY_LENGTH);
+        } else {
+            return values;
+        }
+    }
+
+    private static String checkString(String value) {
+        if (value.length() > MAX_STRING_VALUE_LENGTH) {
+            return value.substring(0, MAX_STRING_VALUE_LENGTH);
+        }
+        return value;
+    }
+
+    private static String checkName(String value) {
+        if (TextUtils.isEmpty(value)) {
+            throw new NullPointerException();
+        }
+        return value;
+    }
+}
+
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
new file mode 100644
index 0000000..2f80911
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/DeviceInfoInstrument.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.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/GenericDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.java
new file mode 100644
index 0000000..7df3dae
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/GenericDeviceInfo.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 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;
+import android.os.SystemProperties;
+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 com.android.compatibility.common.deviceinfo.DeviceInfoActivity;
+
+/**
+ * Generic device info collector.
+ */
+public class GenericDeviceInfo extends DeviceInfoActivity {
+
+    public static final String BUILD_ID = "build_id";
+    public static final String BUILD_PRODUCT = "build_product";
+    public static final String BUILD_DEVICE = "build_device";
+    public static final String BUILD_BOARD = "build_board";
+    public static final String BUILD_MANUFACTURER = "build_manufacturer";
+    public static final String BUILD_BRAND = "build_brand";
+    public static final String BUILD_MODEL = "build_model";
+    public static final String BUILD_TYPE = "build_type";
+    public static final String BUILD_FINGERPRINT = "build_fingerprint";
+    public static final String BUILD_ABI = "build_abi";
+    public static final String BUILD_ABI2 = "build_abi2";
+    public static final String BUILD_ABIS = "build_abis";
+    public static final String BUILD_ABIS_32 = "build_abis_32";
+    public static final String BUILD_ABIS_64 = "build_abis_64";
+    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_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);
+    }
+
+    @Override
+    protected void collectDeviceInfo() {
+        addResult(BUILD_ID, Build.ID);
+        addResult(BUILD_PRODUCT, Build.PRODUCT);
+        addResult(BUILD_DEVICE, Build.DEVICE);
+        addResult(BUILD_BOARD, Build.BOARD);
+        addResult(BUILD_MANUFACTURER, Build.MANUFACTURER);
+        addResult(BUILD_BRAND, Build.BRAND);
+        addResult(BUILD_MODEL, Build.MODEL);
+        addResult(BUILD_TYPE, Build.TYPE);
+        addResult(BUILD_FINGERPRINT, Build.FINGERPRINT);
+        addResult(BUILD_ABI, Build.CPU_ABI);
+        addResult(BUILD_ABI2, Build.CPU_ABI2);
+        addResult(BUILD_SERIAL, Build.SERIAL);
+        addResult(BUILD_VERSION_RELEASE, Build.VERSION.RELEASE);
+        addResult(BUILD_VERSION_SDK, Build.VERSION.SDK);
+
+         // Collect build fields available in API level 21
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            addResult(BUILD_ABIS, TextUtils.join(",", Build.SUPPORTED_ABIS));
+            addResult(BUILD_ABIS_32, TextUtils.join(",", Build.SUPPORTED_32_BIT_ABIS));
+            addResult(BUILD_ABIS_64, TextUtils.join(",", Build.SUPPORTED_64_BIT_ABIS));
+        }
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+            addResult(BUILD_VERSION_BASE_OS, Build.VERSION.BASE_OS);
+            addResult(BUILD_VERSION_SECURITY_PATCH, Build.VERSION.SECURITY_PATCH);
+        } else {
+            // Access system properties directly because Build.Version.BASE_OS and
+            // Build.Version.SECURITY_PATCH are not defined pre-M.
+            addResult(BUILD_VERSION_BASE_OS,
+                    SystemProperties.get("ro.build.version.base_os", ""));
+            addResult(BUILD_VERSION_SECURITY_PATCH,
+                    SystemProperties.get("ro.build.version.security_patch", ""));
+        }
+    }
+}
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
new file mode 100644
index 0000000..4d9ad46
--- /dev/null
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.PackageInfo;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+
+import com.android.compatibility.common.deviceinfo.DeviceInfoActivity;
+
+/**
+ * PackageDeviceInfo collector.
+ */
+public class PackageDeviceInfo extends DeviceInfoActivity {
+
+    private static final String PACKAGE = "package";
+    private static final String NAME = "name";
+    private static final String VERSION_NAME = "version_name";
+    private static final String SYSTEM_PRIV = "system_priv";
+    private static final String PRIV_APP_DIR = "/system/priv-app";
+
+    @Override
+    protected void collectDeviceInfo() {
+        PackageManager pm = this.getPackageManager();
+        startArray(PACKAGE);
+        for (PackageInfo pkg : pm.getInstalledPackages(0)) {
+            startGroup();
+            addResult(NAME, pkg.packageName);
+            addResult(VERSION_NAME, pkg.versionName);
+
+            String dir = pkg.applicationInfo.sourceDir;
+            addResult(SYSTEM_PRIV, dir != null && dir.startsWith(PRIV_APP_DIR));
+            endGroup();
+        }
+        endArray(); // Package
+    }
+}
diff --git a/common/device-side/device-info/tests/Android.mk b/common/device-side/device-info/tests/Android.mk
new file mode 100644
index 0000000..e24c5c1
--- /dev/null
+++ b/common/device-side/device-info/tests/Android.mk
@@ -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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-info
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_MODULE_TAGS := optional
+
+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
new file mode 100644
index 0000000..d092f4e
--- /dev/null
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/DeviceInfoActivityTest.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.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/ExampleObjects.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/ExampleObjects.java
new file mode 100644
index 0000000..570bdd5
--- /dev/null
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/ExampleObjects.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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;
+
+/**
+ * Example Objects for {@link DeviceInfoActivity} test package.
+ */
+public final class ExampleObjects {
+
+    // Must match DeviceInfoActivity.MAX_STRING_VALUE_LENGTH and
+    // DeviceInfoActivity.MAX_ARRAY_LENGTH
+    private static final int MAX_LENGTH = 1000;
+
+    private static final String TEST_DEVICE_INFO_JSON = "{\n" +
+        "  \"test_boolean\": true,\n" +
+        "  \"test_double\": 1.23456789,\n" +
+        "  \"test_int\": 123456789,\n" +
+        "  \"test_long\": 9223372036854775807,\n" +
+        "  \"test_string\": \"test string\",\n" +
+        "  \"test_strings\": [\n" +
+        "    \"test string 1\",\n" +
+        "    \"test string 2\",\n" +
+        "    \"test string 3\"\n" +
+        "  ],\n" +
+        "  \"test_group\": {\n" +
+        "    \"test_boolean\": false,\n" +
+        "    \"test_double\": 9.87654321,\n" +
+        "    \"test_int\": 987654321,\n" +
+        "    \"test_long\": 9223372036854775807,\n" +
+        "    \"test_string\": \"test group string\",\n" +
+        "    \"test_strings\": [\n" +
+        "      \"test group string 1\",\n" +
+        "      \"test group string 2\",\n" +
+        "      \"test group string 3\"\n" +
+        "    ]\n" +
+        "  },\n" +
+        "  \"test_groups\": [\n" +
+        "    {\n" +
+        "      \"test_string\": \"test groups string 1\",\n" +
+        "      \"test_strings\": [\n" +
+        "        \"test groups string 1-1\",\n" +
+        "        \"test groups string 1-2\",\n" +
+        "        \"test groups string 1-3\"\n" +
+        "      ]\n" +
+        "    },\n" +
+        "    {\n" +
+        "      \"test_string\": \"test groups string 2\",\n" +
+        "      \"test_strings\": [\n" +
+        "        \"test groups string 2-1\",\n" +
+        "        \"test groups string 2-2\",\n" +
+        "        \"test groups string 2-3\"\n" +
+        "      ]\n" +
+        "    },\n" +
+        "    {\n" +
+        "      \"test_string\": \"test groups string 3\",\n" +
+        "      \"test_strings\": [\n" +
+        "        \"test groups string 3-1\",\n" +
+        "        \"test groups string 3-2\",\n" +
+        "        \"test groups string 3-3\"\n" +
+        "      ]\n" +
+        "    }\n" +
+        "  ],\n" +
+        "  \"max_length_string\": \"%s\",\n" +
+        "  \"max_num_ints\": [\n%s" +
+        "  ]\n" +
+        "}\n";
+
+    public static String testDeviceInfoJson() {
+        StringBuilder longStringSb = new StringBuilder();
+        StringBuilder longArraySb = new StringBuilder();
+        int lastNum = MAX_LENGTH - 1;
+        for (int i = 0; i < MAX_LENGTH; i++) {
+            longStringSb.append("a");
+            longArraySb.append(String.format("    %d%s\n", i, ((i == lastNum)? "" : ",")));
+        }
+        return String.format(TEST_DEVICE_INFO_JSON,
+            longStringSb.toString(), longArraySb.toString());
+    }
+}
\ No newline at end of file
diff --git a/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.java b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.java
new file mode 100644
index 0000000..7da9951
--- /dev/null
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/SampleDeviceInfo.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.os.Bundle;
+
+import java.lang.StringBuilder;
+
+/**
+ * Sample device info collector.
+ */
+public class SampleDeviceInfo extends DeviceInfoActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void collectDeviceInfo() {
+        boolean[] booleans = {Boolean.TRUE, Boolean.FALSE};
+        double[] doubles = {Double.MAX_VALUE, Double.MIN_VALUE};
+        int[] ints = {Integer.MAX_VALUE, Integer.MIN_VALUE};
+        long[] longs = {Long.MAX_VALUE, Long.MIN_VALUE};
+
+        // Group Foo
+        startGroup("foo");
+        addResult("foo_boolean", Boolean.TRUE);
+
+        // Group Bar
+        startGroup("bar");
+        addArray("bar_string", new String[] {
+                "bar-string-1",
+                "bar-string-2",
+                "bar-string-3"});
+
+        addArray("bar_boolean", booleans);
+        addArray("bar_double", doubles);
+        addArray("bar_int", ints);
+        addArray("bar_long", longs);
+        endGroup(); // bar
+
+        addResult("foo_double", Double.MAX_VALUE);
+        addResult("foo_int", Integer.MAX_VALUE);
+        addResult("foo_long", Long.MAX_VALUE);
+        addResult("foo_string", "foo-string");
+
+        StringBuilder sb = new StringBuilder();
+        int[] arr = new int[1001];
+        for (int i = 0; i < 1001; i++) {
+            sb.append("a");
+            arr[i] = i;
+        }
+        addResult("long_string", sb.toString());
+        addArray("long_int_array", arr);
+
+        endGroup(); // foo
+    }
+}
+
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
new file mode 100644
index 0000000..7f82942
--- /dev/null
+++ b/common/device-side/device-info/tests/src/com/android/compatibility/common/deviceinfo/TestDeviceInfo.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 java.lang.StringBuilder;
+
+/**
+ * Collector for testing DeviceInfoActivity
+ */
+public class TestDeviceInfo extends DeviceInfoActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void collectDeviceInfo() {
+
+        // Test primitive results
+        addResult("test_boolean", true);
+        addResult("test_double", 1.23456789);
+        addResult("test_int", 123456789);
+        addResult("test_long", Long.MAX_VALUE);
+        addResult("test_string", "test string");
+        addArray("test_strings", new String[] {
+            "test string 1",
+            "test string 2",
+            "test string 3",
+        });
+
+        // Test group
+        startGroup("test_group");
+        addResult("test_boolean", false);
+        addResult("test_double", 9.87654321);
+        addResult("test_int", 987654321);
+        addResult("test_long", Long.MAX_VALUE);
+        addResult("test_string", "test group string");
+        addArray("test_strings", new String[] {
+            "test group string 1",
+            "test group string 2",
+            "test group string 3"
+        });
+        endGroup(); // test_group
+
+        // Test array of groups
+        startArray("test_groups");
+        for (int i = 1; i < 4; i++) {
+            startGroup();
+            addResult("test_string", "test groups string " + i);
+            addArray("test_strings", new String[] {
+                "test groups string " + i + "-1",
+                "test groups string " + i + "-2",
+                "test groups string " + i + "-3"
+            });
+            endGroup();
+        }
+        endArray(); // test_groups
+
+        // Test max
+        StringBuilder sb = new StringBuilder();
+        int[] arr = new int[1001];
+        for (int i = 0; i < 1001; i++) {
+            sb.append("a");
+            arr[i] = i;
+        }
+        addResult("max_length_string", sb.toString());
+        addArray("max_num_ints", arr);
+    }
+}
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/WifiConfigCreator.java b/common/device-side/util/src/com/android/compatibility/common/util/WifiConfigCreator.java
new file mode 100755
index 0000000..ac30fe1
--- /dev/null
+++ b/common/device-side/util/src/com/android/compatibility/common/util/WifiConfigCreator.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.List;
+
+import static android.net.wifi.WifiManager.EXTRA_WIFI_STATE;
+import static android.net.wifi.WifiManager.WIFI_STATE_ENABLED;
+
+/**
+ * A simple activity to create and manage wifi configurations.
+ */
+public class WifiConfigCreator {
+    public static final String ACTION_CREATE_WIFI_CONFIG =
+            "com.android.compatibility.common.util.CREATE_WIFI_CONFIG";
+    public static final String ACTION_UPDATE_WIFI_CONFIG =
+            "com.android.compatibility.common.util.UPDATE_WIFI_CONFIG";
+    public static final String ACTION_REMOVE_WIFI_CONFIG =
+            "com.android.compatibility.common.util.REMOVE_WIFI_CONFIG";
+    public static final String EXTRA_NETID = "extra-netid";
+    public static final String EXTRA_SSID = "extra-ssid";
+    public static final String EXTRA_SECURITY_TYPE = "extra-security-type";
+    public static final String EXTRA_PASSWORD = "extra-password";
+
+    public static final int SECURITY_TYPE_NONE = 1;
+    public static final int SECURITY_TYPE_WPA = 2;
+    public static final int SECURITY_TYPE_WEP = 3;
+
+    private static final String TAG = "WifiConfigCreator";
+
+    private static final long ENABLE_WIFI_WAIT_SEC = 10L;
+
+    private final Context mContext;
+    private final WifiManager mWifiManager;
+
+    public WifiConfigCreator(Context context) {
+        mContext = context;
+        mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+    }
+
+    /**
+     * Adds a new WiFi network.
+     * @return network id or -1 in case of error
+     */
+    public int addNetwork(String ssid, boolean hidden, int securityType,
+            String password) throws InterruptedException, SecurityException {
+        checkAndEnableWifi();
+
+        WifiConfiguration wifiConf = createConfig(ssid, hidden, securityType, password);
+
+        int netId = mWifiManager.addNetwork(wifiConf);
+
+        if (netId != -1) {
+            mWifiManager.enableNetwork(netId, true);
+        } else {
+            Log.w(TAG, "Unable to add SSID '" + ssid + "': netId = " + netId);
+        }
+        return netId;
+    }
+
+    /**
+     * Updates a new WiFi network.
+     * @return network id (may differ from original) or -1 in case of error
+     */
+    public int updateNetwork(WifiConfiguration wifiConf, String ssid, boolean hidden,
+            int securityType, String password) throws InterruptedException, SecurityException {
+        checkAndEnableWifi();
+        if (wifiConf == null) {
+            return -1;
+        }
+
+        WifiConfiguration conf = createConfig(ssid, hidden, securityType, password);
+        conf.networkId = wifiConf.networkId;
+
+        int newNetId = mWifiManager.updateNetwork(conf);
+
+        if (newNetId != -1) {
+            mWifiManager.saveConfiguration();
+            mWifiManager.enableNetwork(newNetId, true);
+        } else {
+            Log.w(TAG, "Unable to update SSID '" + ssid + "': netId = " + newNetId);
+        }
+        return newNetId;
+    }
+
+    /**
+     * Updates a new WiFi network.
+     * @return network id (may differ from original) or -1 in case of error
+     */
+    public int updateNetwork(int netId, String ssid, boolean hidden,
+            int securityType, String password) throws InterruptedException, SecurityException {
+        checkAndEnableWifi();
+
+        WifiConfiguration wifiConf = null;
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        for (WifiConfiguration config : configs) {
+            if (config.networkId == netId) {
+                wifiConf = config;
+                break;
+            }
+        }
+        return updateNetwork(wifiConf, ssid, hidden, securityType, password);
+    }
+
+    public boolean removeNetwork(int netId) {
+        return mWifiManager.removeNetwork(netId);
+    }
+
+    /**
+     * Creates a WifiConfiguration set up according to given parameters
+     * @param ssid SSID of the network
+     * @param hidden Is SSID not broadcast?
+     * @param securityType One of {@link #SECURITY_TYPE_NONE}, {@link #SECURITY_TYPE_WPA} or
+     *                     {@link #SECURITY_TYPE_WEP}
+     * @param password Password for WPA or WEP
+     * @return Created configuration object
+     */
+    private WifiConfiguration createConfig(String ssid, boolean hidden, int securityType,
+            String password) {
+        WifiConfiguration wifiConf = new WifiConfiguration();
+        if (!TextUtils.isEmpty(ssid)) {
+            wifiConf.SSID = '"' + ssid + '"';
+        }
+        wifiConf.status = WifiConfiguration.Status.ENABLED;
+        wifiConf.hiddenSSID = hidden;
+        switch (securityType) {
+            case SECURITY_TYPE_NONE:
+                wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+                break;
+            case SECURITY_TYPE_WPA:
+                updateForWPAConfiguration(wifiConf, password);
+                break;
+            case SECURITY_TYPE_WEP:
+                updateForWEPConfiguration(wifiConf, password);
+                break;
+        }
+        return wifiConf;
+    }
+
+    private void updateForWPAConfiguration(WifiConfiguration wifiConf, String wifiPassword) {
+        wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+        if (!TextUtils.isEmpty(wifiPassword)) {
+            wifiConf.preSharedKey = '"' + wifiPassword + '"';
+        }
+    }
+
+    private void updateForWEPConfiguration(WifiConfiguration wifiConf, String password) {
+        wifiConf.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+        wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+        wifiConf.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
+        if (!TextUtils.isEmpty(password)) {
+            int length = password.length();
+            if ((length == 10 || length == 26
+                    || length == 58) && password.matches("[0-9A-Fa-f]*")) {
+                wifiConf.wepKeys[0] = password;
+            } else {
+                wifiConf.wepKeys[0] = '"' + password + '"';
+            }
+            wifiConf.wepTxKeyIndex = 0;
+        }
+    }
+
+    private void checkAndEnableWifi() throws InterruptedException {
+        final CountDownLatch enabledLatch = new CountDownLatch(1);
+
+        // Register a change receiver first to pick up events between isEnabled and setEnabled
+        final BroadcastReceiver watcher = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (intent.getIntExtra(EXTRA_WIFI_STATE, -1) == WIFI_STATE_ENABLED) {
+                    enabledLatch.countDown();
+                }
+            }
+        };
+
+        mContext.registerReceiver(watcher, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
+        try {
+            // In case wifi is not already enabled, wait for it to come up
+            if (!mWifiManager.isWifiEnabled()) {
+                mWifiManager.setWifiEnabled(true);
+                enabledLatch.await(ENABLE_WIFI_WAIT_SEC, TimeUnit.SECONDS);
+            }
+        } finally {
+            mContext.unregisterReceiver(watcher);
+        }
+    }
+}
+
diff --git a/common/host-side/manifest-generator/Android.mk b/common/host-side/manifest-generator/Android.mk
new file mode 100644
index 0000000..ca08928
--- /dev/null
+++ b/common/host-side/manifest-generator/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 := kxml2-2.3.0
+
+LOCAL_JAR_MANIFEST := MANIFEST.mf
+
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
+
+LOCAL_MODULE := compatibility-manifest-generator
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/common/host-side/manifest-generator/MANIFEST.mf b/common/host-side/manifest-generator/MANIFEST.mf
new file mode 100644
index 0000000..4f62631
--- /dev/null
+++ b/common/host-side/manifest-generator/MANIFEST.mf
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: com.android.compatibility.common.generator.ManifestGenerator
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
new file mode 100644
index 0000000..e23e254
--- /dev/null
+++ b/common/host-side/manifest-generator/src/com/android/compatibility/common/generator/ManifestGenerator.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.generator;
+
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.kxml2.io.KXmlSerializer;
+
+public class ManifestGenerator {
+
+    private static final String USAGE = "Usage: "
+        + "manifest-generator -n NAME -p PACKAGE_NAME -o OUTPUT_FILE -i INSTRUMENT_NAME "
+        + "[-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";
+    private static final String APPLICATION = "application";
+    private static final String INSTRUMENTATION = "instrumentation";
+    private static final String ACTIVITY = "activity";
+
+    public static void main(String[] args) {
+        String pkgName = null;
+        String instrumentName = null;
+        List<String> permissions = new ArrayList<>();
+        List<String> activities = new ArrayList<>();
+        String output = null;
+
+        for (int i = 0; i < args.length - 1; i++) {
+            if (args[i].equals("-p")) {
+                pkgName = args[++i];
+            } else if (args[i].equals("-a")) {
+                activities.add(args[++i]);
+            } else if (args[i].equals("-o")) {
+                output = args[++i];
+            } else if (args[i].equals("-i")) {
+                instrumentName = args[++i];
+            } else if (args[i].equals("-r")) {
+                permissions.add(args[++i]);
+            }
+        }
+
+        if (pkgName == null) {
+            error("Missing package name");
+        } else if (instrumentName == null) {
+            error("Missing instrumentation name");
+        } else if (activities.isEmpty()) {
+            error("No activities");
+        } else if (output == null) {
+            error("Missing output file");
+        }
+
+        FileOutputStream out = null;
+        try {
+          out = new FileOutputStream(output);
+          generate(out, pkgName, instrumentName, permissions, activities);
+        } catch (Exception e) {
+          System.err.println("Couldn't create manifest file");
+        } finally {
+          if (out != null) {
+              try {
+                  out.close();
+              } catch (Exception e) {
+                  // Ignore
+              }
+          }
+        }
+    }
+
+    /*package*/ static void generate(OutputStream out, String pkgName, String instrumentName,
+            List<String> permissions, List<String> activities) throws Exception {
+        final String ns = null;
+        KXmlSerializer serializer = new KXmlSerializer();
+        serializer.setOutput(out, "UTF-8");
+        serializer.startDocument("UTF-8", true);
+        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+        serializer.startTag(ns, MANIFEST);
+        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.endTag(ns, USES_SDK);
+        for (String permission : permissions) {
+            serializer.startTag(ns, USES_PERMISSION);
+            serializer.attribute(ns, "android:name", permission);
+            serializer.endTag(ns, USES_PERMISSION);
+        }
+        serializer.startTag(ns, APPLICATION);
+        for (String activity : activities) {
+            serializer.startTag(ns, ACTIVITY);
+            serializer.attribute(ns, "android:name", activity);
+            serializer.endTag(ns, ACTIVITY);
+        }
+        serializer.endTag(ns, APPLICATION);
+        serializer.startTag(ns, INSTRUMENTATION);
+        serializer.attribute(ns, "android:name", instrumentName);
+        serializer.attribute(ns, "android:targetPackage", pkgName);
+        serializer.endTag(ns, INSTRUMENTATION);
+        serializer.endTag(ns, MANIFEST);
+        serializer.endDocument();
+        out.flush();
+    }
+
+    private static void error(String message) {
+        System.err.println(message);
+        System.err.println(USAGE);
+        System.exit(1);
+    }
+
+}
diff --git a/common/host-side/manifest-generator/tests/Android.mk b/common/host-side/manifest-generator/tests/Android.mk
new file mode 100644
index 0000000..2eb5d2f
--- /dev/null
+++ b/common/host-side/manifest-generator/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-manifest-generator junit
+
+LOCAL_MODULE := compatibility-manifest-generator-tests
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_HOST_JAVA_LIBRARY)
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
new file mode 100644
index 0000000..457bbb8
--- /dev/null
+++ b/common/host-side/manifest-generator/tests/src/com/android/compatibility/common/generator/ManifestGeneratorTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.generator;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+/** Unit tests for {@link ManifestGenerator}. */
+public class ManifestGeneratorTest extends TestCase {
+
+    private static final String PACKAGE = "test.package";
+    private static final String INSTRUMENT = "test.package.TestInstrument";
+    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"
+        + "%s"
+        + "  <application>\r\n"
+        + "%s"
+        + "  </application>\r\n"
+        + "  <instrumentation android:name=\"test.package.TestInstrument\" "
+        + "android:targetPackage=\"test.package\" />\r\n"
+        + "</manifest>";
+    private static final String PERMISSION = "  <uses-permission android:name=\"%s\" />\r\n";
+    private static final String PERMISSION_A = "android.permission.PermissionA";
+    private static final String PERMISSION_B = "android.permission.PermissionB";
+    private static final String ACTIVITY = "    <activity android:name=\"%s\" />\r\n";
+    private static final String ACTIVITY_A = "test.package.ActivityA";
+    private static final String ACTIVITY_B = "test.package.ActivityB";
+
+    public void testManifest() throws Exception {
+        List<String> permissions = new ArrayList<>();
+        permissions.add(PERMISSION_A);
+        permissions.add(PERMISSION_B);
+        List<String> activities = new ArrayList<>();
+        activities.add(ACTIVITY_A);
+        activities.add(ACTIVITY_B);
+        OutputStream output = new OutputStream() {
+            private StringBuilder string = new StringBuilder();
+            @Override
+            public void write(int b) throws IOException {
+                this.string.append((char) b);
+            }
+
+            @Override
+            public String toString(){
+                return this.string.toString();
+            }
+        };
+        ManifestGenerator.generate(output, PACKAGE, INSTRUMENT, permissions, activities);
+        String permissionXml = String.format(PERMISSION, PERMISSION_A)
+                + String.format(PERMISSION, PERMISSION_B);
+        String activityXml = String.format(ACTIVITY, ACTIVITY_A)
+                + String.format(ACTIVITY, ACTIVITY_B);
+        String expected = String.format(MANIFEST, permissionXml, activityXml);
+        assertEquals("Wrong manifest output", expected, output.toString());
+    }
+
+}
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
index d0a3a37..efb53d5 100644
--- 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
@@ -22,9 +22,9 @@
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
-import vogar.Expectation;
 import vogar.ExpectationStore;
 import vogar.ModeId;
+import vogar.Result;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -161,7 +161,7 @@
     }
 
     public static boolean isKnownFailure(ExpectationStore store, String fullname) {
-        return store != null && store.get(fullname) != Expectation.SUCCESS;
+        return store != null && store.get(fullname).getResult() != Result.SUCCESS;
     }
 
     public static void main(String[] args) 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
new file mode 100644
index 0000000..4675231
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/MetricsReportLog.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.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
new file mode 100644
index 0000000..9eeb94a
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/MetricsStore.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.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/ReportLog.java b/common/util/src/com/android/compatibility/common/util/ReportLog.java
index 8cfc086..7209ac8 100644
--- a/common/util/src/com/android/compatibility/common/util/ReportLog.java
+++ b/common/util/src/com/android/compatibility/common/util/ReportLog.java
@@ -16,28 +16,37 @@
 
 package com.android.compatibility.common.util;
 
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.StringTokenizer;
+import java.util.regex.Pattern;
 
 /**
  * Utility class to add results to the report.
  */
-public abstract class ReportLog implements Serializable {
+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>();
 
-    class Result implements Serializable {
-        private static final int CALLER_STACKTRACE_DEPTH = 5;
+    static class Result implements Serializable {
         private String mLocation;
         private String mMessage;
         private double[] mValues;
         private ResultType mType;
         private ResultUnit mUnit;
+        private Double mTarget;
+
+
+        private Result(String location, String message, double[] values,
+                ResultType type, ResultUnit unit) {
+            this(location, message, values, null /*target*/, type, unit);
+        }
 
         /**
          * Creates a result object to be included in the report. Each object has a message
@@ -47,23 +56,22 @@
          *
          * @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)
-         * @param depth A number used to increase the depth the stack is queried. This should only
-         * be given in the case that the report is populated by a helper function, in which case it
-         * would be 1, or else 0.
          */
-        private Result(String message, double[] values, ResultType type,
-                ResultUnit unit, int depth) {
-            final StackTraceElement[] trace = Thread.currentThread().getStackTrace();
-            final StackTraceElement e =
-                    trace[Math.min(CALLER_STACKTRACE_DEPTH + depth, trace.length - 1)];
-            mLocation = String.format(
-                    "%s#%s:%d", e.getClassName(), e.getMethodName(), e.getLineNumber());
+        private Result(String location, String message, double[] values,
+                Double target, ResultType type, ResultUnit unit) {
+            mLocation = location;
             mMessage = message;
             mValues = values;
             mType = type;
             mUnit = unit;
+            mTarget = target;
+        }
+
+        public double getTarget() {
+            return mTarget;
         }
 
         public String getLocation() {
@@ -85,51 +93,89 @@
         public ResultUnit getUnit() {
             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(" ");
+            }
+            return builder.toString();
+        }
+
+        static Result fromEncodedString(String encodedString) {
+            String[] elems = encodedString.split(Pattern.quote(LOG_ELEM_SEPARATOR));
+            if (elems.length < 5) {
+                return null;
+            }
+
+            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]);
+            }
+            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*/);
+        }
     }
 
     /**
      * Adds an array of values to the report.
      */
     public void addValues(String message, double[] values, ResultType type, ResultUnit unit) {
-        mDetails.add(new Result(message, values, type, unit, 0));
+        mDetails.add(new Result(Stacktrace.getTestCallerClassMethodNameLineNumber(),
+                message, values, type, unit));
     }
 
     /**
      * Adds an array of values to the report.
      */
-    public void addValues(String message, double[] values, ResultType type,
-            ResultUnit unit, int depth) {
-        mDetails.add(new Result(message, values, type, unit, depth));
+    public void addValues(
+            String message, double[] values, ResultType type, ResultUnit unit, String location) {
+        mDetails.add(new Result(location, message, values, type, unit));
     }
 
     /**
      * Adds a value to the report.
      */
     public void addValue(String message, double value, ResultType type, ResultUnit unit) {
-        mDetails.add(new Result(message, new double[] {value}, type, unit, 0));
+        mDetails.add(new Result(Stacktrace.getTestCallerClassMethodNameLineNumber(), message,
+                new double[] {value}, type, unit));
     }
 
     /**
      * Adds a value to the report.
      */
     public void addValue(String message, double value, ResultType type,
-            ResultUnit unit, int depth) {
-        mDetails.add(new Result(message, new double[] {value}, type, unit, depth));
+            ResultUnit unit, String location) {
+        mDetails.add(new Result(location, message, new double[] {value}, type, unit));
     }
 
     /**
      * Sets the summary of the report.
      */
     public void setSummary(String message, double value, ResultType type, ResultUnit unit) {
-        mSummary = new Result(message, new double[] {value}, type, unit, 0);
-    }
-
-    /**
-     * Sets the summary of the report.
-     */
-    public void setSummary(String message, double value, ResultType type,
-            ResultUnit unit, int depth) {
-        mSummary = new Result(message, new double[] {value}, type, unit, depth);
+        mSummary = new Result(Stacktrace.getTestCallerClassMethodNameLineNumber(),
+                message, new double[] {value}, type, unit);
     }
 
     public Result getSummary() {
@@ -139,4 +185,46 @@
     public List<Result> getDetailedMetrics() {
         return new ArrayList<Result>(mDetails);
     }
+
+    /**
+     * Parse a String encoded {@link com.android.compatibility.common.util.ReportLog}
+     */
+    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());
+        }
+        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()));
+            }
+        }
+        return reportLog;
+    }
+
+    /**
+     * @return a String representation of this report or null if not collected
+     */
+    protected String toEncodedString() {
+        if ((mSummary == null) && mDetails.isEmpty()) {
+            // just return empty string
+            return null;
+        }
+        StringBuilder builder = new StringBuilder();
+        builder.append(mSummary.toEncodedString());
+        builder.append(SUMMARY_SEPARATOR);
+        for (Result result : mDetails) {
+            builder.append(result.toEncodedString());
+            builder.append(LOG_SEPARATOR);
+        }
+        // delete the last separator
+        if (builder.length() >= LOG_SEPARATOR.length()) {
+            builder.delete(builder.length() - LOG_SEPARATOR.length(), builder.length());
+        }
+        return builder.toString();
+    }
 }
diff --git a/common/util/src/com/android/compatibility/common/util/Stacktrace.java b/common/util/src/com/android/compatibility/common/util/Stacktrace.java
new file mode 100644
index 0000000..27bf9ca
--- /dev/null
+++ b/common/util/src/com/android/compatibility/common/util/Stacktrace.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 com.android.compatibility.common.util;
+
+/**
+ * Helper methods for dealing with stack traces
+ */
+public class Stacktrace {
+
+    private static final int SAFETY_DEPTH = 4;
+    private static final String TEST_POSTFIX = "Test";
+
+    private Stacktrace() {}
+
+    /**
+     * @return classname#methodname from call stack of the current thread
+     */
+    public static String getTestCallerClassMethodName() {
+        return getTestCallerClassMethodName(false /*includeLineNumber*/);
+    }
+
+    /**
+     * @return classname#methodname from call stack of the current thread
+     */
+    public static String getTestCallerClassMethodNameLineNumber() {
+        return getTestCallerClassMethodName(true /*includeLineNumber*/);
+    }
+
+    /**
+     * @return classname#methodname from call stack of the current thread
+     */
+    private static String getTestCallerClassMethodName(boolean includeLineNumber) {
+        StackTraceElement[] elements = Thread.currentThread().getStackTrace();
+        // Look for the first class name in the elements array that ends with Test
+        for (int i = 0; i < elements.length; i++) {
+            if (elements[i].getClassName().endsWith(TEST_POSTFIX)) {
+                return buildClassMethodName(elements, i, includeLineNumber);
+            }
+        }
+
+        // Use a reasonable default if the test name isn't found
+        return buildClassMethodName(elements, SAFETY_DEPTH, includeLineNumber);
+    }
+
+    private static String buildClassMethodName(
+            StackTraceElement[] elements, int depth, boolean includeLineNumber) {
+        depth = Math.min(depth, elements.length - 1);
+        StringBuilder builder = new StringBuilder();
+        builder.append(elements[depth].getClassName()).append("#")
+                .append(elements[depth].getMethodName());
+        if (includeLineNumber) {
+            builder.append(":").append(elements[depth].getLineNumber());
+        }
+        return builder.toString();
+    }
+}
diff --git a/common/util/tests/src/com/android/compatibility/common/util/MetricsStoreTest.java b/common/util/tests/src/com/android/compatibility/common/util/MetricsStoreTest.java
new file mode 100644
index 0000000..944cc43
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/MetricsStoreTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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 MetricsStore}
+ */
+public class MetricsStoreTest extends TestCase {
+
+    private static final String DEVICE_SERIAL = "DEVICE_SERIAL";
+    private static final String ABI = "ABI";
+    private static final String CLASSMETHOD_NAME = "CLASSMETHOD_NAME";
+
+    private static final double[] VALUES = new double[] {1, 11, 21, 1211, 111221};
+
+    private ReportLog mReportLog;
+
+    @Override
+    protected void setUp() throws Exception {
+        this.mReportLog = new ReportLog();
+    }
+
+    public void testStoreAndRemove() {
+        mReportLog.setSummary("Sample Summary", 1.0, ResultType.HIGHER_BETTER, ResultUnit.BYTE);
+        mReportLog.addValues("Details", VALUES, ResultType.NEUTRAL, ResultUnit.FPS);
+        MetricsStore.storeResult(DEVICE_SERIAL, ABI, CLASSMETHOD_NAME, mReportLog);
+
+        ReportLog reportLog = MetricsStore.removeResult(DEVICE_SERIAL, ABI, CLASSMETHOD_NAME);
+        assertSame(mReportLog, reportLog);
+        assertNull(MetricsStore.removeResult("blah", ABI, CLASSMETHOD_NAME));
+    }
+
+}
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 70da820..05e69d8 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
@@ -36,7 +36,8 @@
             HEADER
             + "<Summary message=\"Sample\" scoreType=\"higher_better\" unit=\"byte\">1.0</Summary>"
             + "<Details>"
-                    + "<ValueArray source=\"sun.reflect.NativeMethodAccessorImpl#invoke0:-2\""
+                    + "<ValueArray source=\"com.android.compatibility.common.util."
+                    + "MetricsXmlSerializerTest#testSerialize:84\""
                     + " message=\"Details\" scoreType=\"neutral\" unit=\"fps\">"
                         + "<Value>1.0</Value>"
                         + "<Value>11.0</Value>"
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
new file mode 100644
index 0000000..a5f3306
--- /dev/null
+++ b/common/util/tests/src/com/android/compatibility/common/util/ReportLogTest.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.compatibility.common.util;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+
+/**
+ * Unit tests for {@link ReportLog}
+ */
+public class ReportLogTest extends TestCase {
+
+    private static final double[] VALUES = new double[] {1, 11, 21, 1211, 111221};
+
+    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;
+
+    @Override
+    protected void setUp() throws Exception {
+        this.reportLog = 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());
+    }
+}
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 b9a17e1..348c680 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
@@ -26,6 +26,8 @@
     public UnitTests() {
         super();
 
+        addTestSuite(MetricsStoreTest.class);
         addTestSuite(MetricsXmlSerializerTest.class);
+        addTestSuite(ReportLogTest.class);
     }
 }
diff --git a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java
index a036382..b0fb1fb 100644
--- a/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java
+++ b/hostsidetests/aadb/src/com/android/cts/aadb/TestDeviceFuncTest.java
@@ -86,7 +86,8 @@
      * Verify that a simple {@link TestDevice#executeShellCommand(String)} command is successful.
      */
     private void assertSimpleShellCommand() throws DeviceNotAvailableException {
-        final String output = mTestDevice.executeShellCommand("ls");
+    	// Check for expected contents of device's root directory
+        final String output = mTestDevice.executeShellCommand("ls /");
         assertTrue(output.contains("data"));
         assertTrue(output.contains("system"));
     }
diff --git a/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-dsa-a.pk8 b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-dsa-a.pk8
new file mode 100644
index 0000000..ac0b0c1
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-dsa-a.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.pk8 b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.pk8
new file mode 100644
index 0000000..ec27be1
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.pk8
Binary files differ
diff --git a/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.x509.pem b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.x509.pem
new file mode 100644
index 0000000..183691d
--- /dev/null
+++ b/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-ec-a.x509.pem
@@ -0,0 +1,10 @@
+-----BEGIN CERTIFICATE-----
+MIIBejCCAR+gAwIBAgIJAMsY4Fz5jr/IMAoGCCqGSM49BAMCMBkxFzAVBgNVBAMM
+DnVuaXRfdGVzdF9lY19hMB4XDTE1MDYwMTIxNDU1M1oXDTQyMTAxNzIxNDU1M1ow
+GTEXMBUGA1UEAwwOdW5pdF90ZXN0X2VjX2EwWTATBgcqhkjOPQIBBggqhkjOPQMB
+BwNCAAR8Q+7lg4KSOs2Be0XhFwlFCsiCCIh3iX2t6fE+V/MD+QBT1265hIyBKEH/
+oAsTpLy8FdGKLC0x+TwuCedui0SBo1AwTjAdBgNVHQ4EFgQUX4h7gPTgwQXorm0H
+7R12wN2yNrwwHwYDVR0jBBgwFoAUX4h7gPTgwQXorm0H7R12wN2yNrwwDAYDVR0T
+BAUwAwEB/zAKBggqhkjOPQQDAgNJADBGAiEA5kHO4aK20dwt81mCABAywD7Y6V1O
+vqoff9yIx3USW8oCIQDTzo8tbHuPc+i3vBsb5Uo1+4BE/pcOe/je6PGlRHG8rg==
+-----END CERTIFICATE-----
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AdoptableHostTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AdoptableHostTest.java
new file mode 100644
index 0000000..2ae2e10
--- /dev/null
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AdoptableHostTest.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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
index 4d9ef00..bf9e81c 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/AppSecurityTests.java
@@ -19,16 +19,8 @@
 import com.android.cts.tradefed.build.CtsBuildHelper;
 import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.Log;
-import com.android.ddmlib.testrunner.InstrumentationResultParser;
-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.IAbi;
 import com.android.tradefed.testtype.IAbiReceiver;
@@ -36,15 +28,13 @@
 
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.util.Map;
 
 /**
- * Set of tests that verify various security checks involving multiple apps are properly enforced.
+ * Set of tests that verify various security checks involving multiple apps are
+ * properly enforced.
  */
 public class AppSecurityTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
 
-    private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
-
     // testSharedUidDifferentCerts constants
     private static final String SHARED_UI_APK = "CtsSharedUidInstall.apk";
     private static final String SHARED_UI_PKG = "com.android.cts.shareuidinstall";
@@ -69,18 +59,6 @@
     private static final String APP_ACCESS_DATA_APK = "CtsAppAccessData.apk";
     private static final String APP_ACCESS_DATA_PKG = "com.android.cts.appaccessdata";
 
-    // External storage constants
-    private static final String COMMON_EXTERNAL_STORAGE_APP_CLASS = "com.android.cts.externalstorageapp.CommonExternalStorageTest";
-    private static final String EXTERNAL_STORAGE_APP_APK = "CtsExternalStorageApp.apk";
-    private static final String EXTERNAL_STORAGE_APP_PKG = "com.android.cts.externalstorageapp";
-    private static final String EXTERNAL_STORAGE_APP_CLASS = EXTERNAL_STORAGE_APP_PKG + ".ExternalStorageTest";
-    private static final String READ_EXTERNAL_STORAGE_APP_APK = "CtsReadExternalStorageApp.apk";
-    private static final String READ_EXTERNAL_STORAGE_APP_PKG = "com.android.cts.readexternalstorageapp";
-    private static final String READ_EXTERNAL_STORAGE_APP_CLASS = READ_EXTERNAL_STORAGE_APP_PKG + ".ReadExternalStorageTest";
-    private static final String WRITE_EXTERNAL_STORAGE_APP_APK = "CtsWriteExternalStorageApp.apk";
-    private static final String WRITE_EXTERNAL_STORAGE_APP_PKG = "com.android.cts.writeexternalstorageapp";
-    private static final String WRITE_EXTERNAL_STORAGE_APP_CLASS = WRITE_EXTERNAL_STORAGE_APP_PKG + ".WriteExternalStorageTest";
-
     // testInstrumentationDiffCert constants
     private static final String TARGET_INSTRUMENT_APK = "CtsTargetInstrumentationApp.apk";
     private static final String TARGET_INSTRUMENT_PKG = "com.android.cts.targetinstrumentationapp";
@@ -98,13 +76,6 @@
     private static final String PERMISSION_DIFF_CERT_PKG =
         "com.android.cts.usespermissiondiffcertapp";
 
-    private static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
-
-    private static final String MULTIUSER_STORAGE_APK = "CtsMultiUserStorageApp.apk";
-    private static final String MULTIUSER_STORAGE_PKG = "com.android.cts.multiuserstorageapp";
-    private static final String MULTIUSER_STORAGE_CLASS = MULTIUSER_STORAGE_PKG
-            + ".MultiUserStorageTest";
-
     private static final String LOG_TAG = "AppSecurityTests";
 
     private IAbi mAbi;
@@ -155,8 +126,7 @@
             assertNotNull("shared uid app with different cert than existing app installed " +
                     "successfully", installResult);
             assertEquals("INSTALL_FAILED_SHARED_USER_INCOMPATIBLE", installResult);
-        }
-        finally {
+        } finally {
             getDevice().uninstallPackage(SHARED_UI_PKG);
             getDevice().uninstallPackage(SHARED_UI_DIFF_CERT_PKG);
         }
@@ -182,8 +152,7 @@
             assertNotNull("app upgrade with different cert than existing app installed " +
                     "successfully", installResult);
             assertEquals("INSTALL_FAILED_UPDATE_INCOMPATIBLE", installResult);
-        }
-        finally {
+        } finally {
             getDevice().uninstallPackage(SIMPLE_APP_PKG);
         }
     }
@@ -204,115 +173,21 @@
             assertNull(String.format("failed to install app with data. Reason: %s", installResult),
                     installResult);
             // run appwithdata's tests to create private data
-            assertTrue("failed to create app's private data", runDeviceTests(APP_WITH_DATA_PKG,
-                    APP_WITH_DATA_CLASS, APP_WITH_DATA_CREATE_METHOD));
+            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
-            assertTrue("could access app's private data", runDeviceTests(APP_ACCESS_DATA_PKG));
-        }
-        finally {
+            runDeviceTests(APP_ACCESS_DATA_PKG);
+        } finally {
             getDevice().uninstallPackage(APP_WITH_DATA_PKG);
             getDevice().uninstallPackage(APP_ACCESS_DATA_PKG);
         }
     }
 
     /**
-     * Verify that app with no external storage permissions works correctly.
-     */
-    public void testExternalStorageNone() throws Exception {
-        try {
-            wipePrimaryExternalStorage(getDevice());
-
-            getDevice().uninstallPackage(EXTERNAL_STORAGE_APP_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            assertNull(getDevice()
-                    .installPackage(getTestAppFile(EXTERNAL_STORAGE_APP_APK), false, options));
-            assertTrue("Failed external storage with no permissions",
-                    runDeviceTests(EXTERNAL_STORAGE_APP_PKG));
-        } finally {
-            getDevice().uninstallPackage(EXTERNAL_STORAGE_APP_PKG);
-        }
-    }
-
-    /**
-     * Verify that app with
-     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} works
-     * correctly.
-     */
-    public void testExternalStorageRead() throws Exception {
-        try {
-            wipePrimaryExternalStorage(getDevice());
-
-            getDevice().uninstallPackage(READ_EXTERNAL_STORAGE_APP_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            assertNull(getDevice()
-                    .installPackage(getTestAppFile(READ_EXTERNAL_STORAGE_APP_APK), false, options));
-            assertTrue("Failed external storage with read permissions",
-                    runDeviceTests(READ_EXTERNAL_STORAGE_APP_PKG));
-        } finally {
-            getDevice().uninstallPackage(READ_EXTERNAL_STORAGE_APP_PKG);
-        }
-    }
-
-    /**
-     * Verify that app with
-     * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} works
-     * correctly.
-     */
-    public void testExternalStorageWrite() throws Exception {
-        try {
-            wipePrimaryExternalStorage(getDevice());
-
-            getDevice().uninstallPackage(WRITE_EXTERNAL_STORAGE_APP_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            assertNull(getDevice()
-                    .installPackage(getTestAppFile(WRITE_EXTERNAL_STORAGE_APP_APK), false, options));
-            assertTrue("Failed external storage with write permissions",
-                    runDeviceTests(WRITE_EXTERNAL_STORAGE_APP_PKG));
-        } finally {
-            getDevice().uninstallPackage(WRITE_EXTERNAL_STORAGE_APP_PKG);
-        }
-    }
-
-    /**
-     * 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 {
-        try {
-            wipePrimaryExternalStorage(getDevice());
-
-            getDevice().uninstallPackage(EXTERNAL_STORAGE_APP_PKG);
-            getDevice().uninstallPackage(READ_EXTERNAL_STORAGE_APP_PKG);
-            getDevice().uninstallPackage(WRITE_EXTERNAL_STORAGE_APP_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            assertNull(getDevice()
-                    .installPackage(getTestAppFile(EXTERNAL_STORAGE_APP_APK), false, options));
-            assertNull(getDevice()
-                    .installPackage(getTestAppFile(READ_EXTERNAL_STORAGE_APP_APK), false, options));
-            assertNull(getDevice()
-                    .installPackage(getTestAppFile(WRITE_EXTERNAL_STORAGE_APP_APK), false, options));
-
-            assertTrue("Failed to write gifts", runDeviceTests(WRITE_EXTERNAL_STORAGE_APP_PKG,
-                    WRITE_EXTERNAL_STORAGE_APP_CLASS, "doWriteGifts"));
-
-            assertTrue("Read failed to verify gifts", runDeviceTests(READ_EXTERNAL_STORAGE_APP_PKG,
-                    READ_EXTERNAL_STORAGE_APP_CLASS, "doVerifyGifts"));
-            assertTrue("None failed to verify gifts", runDeviceTests(EXTERNAL_STORAGE_APP_PKG,
-                    EXTERNAL_STORAGE_APP_CLASS, "doVerifyGifts"));
-
-        } finally {
-            getDevice().uninstallPackage(EXTERNAL_STORAGE_APP_PKG);
-            getDevice().uninstallPackage(READ_EXTERNAL_STORAGE_APP_PKG);
-            getDevice().uninstallPackage(WRITE_EXTERNAL_STORAGE_APP_PKG);
-        }
-    }
-
-    /**
      * Test that uninstall of an app removes its private data.
      */
     public void testUninstallRemovesData() throws Exception {
@@ -327,8 +202,7 @@
             assertNull(String.format("failed to install app with data. Reason: %s", installResult),
                     installResult);
             // run appwithdata's tests to create private data
-            assertTrue("failed to create app's private data", runDeviceTests(APP_WITH_DATA_PKG,
-                    APP_WITH_DATA_CLASS, APP_WITH_DATA_CREATE_METHOD));
+            runDeviceTests(APP_WITH_DATA_PKG, APP_WITH_DATA_CLASS, APP_WITH_DATA_CREATE_METHOD);
 
             getDevice().uninstallPackage(APP_WITH_DATA_PKG);
 
@@ -337,11 +211,9 @@
             assertNull(String.format("failed to install app with data second time. Reason: %s",
                     installResult), installResult);
             // run appwithdata's 'check if file exists' test
-            assertTrue("app's private data still exists after install", runDeviceTests(
-                    APP_WITH_DATA_PKG, APP_WITH_DATA_CLASS, APP_WITH_DATA_CHECK_NOEXIST_METHOD));
-
-        }
-        finally {
+            runDeviceTests(APP_WITH_DATA_PKG, APP_WITH_DATA_CLASS,
+                    APP_WITH_DATA_CHECK_NOEXIST_METHOD);
+        } finally {
             getDevice().uninstallPackage(APP_WITH_DATA_PKG);
         }
     }
@@ -371,10 +243,8 @@
             // run INSTRUMENT_DIFF_CERT_PKG tests
             // this test will attempt to call startInstrumentation directly and verify
             // SecurityException is thrown
-            assertTrue("running instrumentation with diff cert unexpectedly succeeded",
-                    runDeviceTests(INSTRUMENT_DIFF_CERT_PKG));
-        }
-        finally {
+            runDeviceTests(INSTRUMENT_DIFF_CERT_PKG);
+        } finally {
             getDevice().uninstallPackage(TARGET_INSTRUMENT_PKG);
             getDevice().uninstallPackage(INSTRUMENT_DIFF_CERT_PKG);
         }
@@ -409,191 +279,20 @@
             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
-            TestRunResult result = doRunTests(PERMISSION_DIFF_CERT_PKG, null, null);
-            assertDeviceTestsPass(result);
-        }
-        finally {
+            runDeviceTests(PERMISSION_DIFF_CERT_PKG);
+        } finally {
             getDevice().uninstallPackage(DECLARE_PERMISSION_PKG);
             getDevice().uninstallPackage(DECLARE_PERMISSION_COMPAT_PKG);
             getDevice().uninstallPackage(PERMISSION_DIFF_CERT_PKG);
         }
     }
 
-    /**
-     * Test multi-user emulated storage environment, ensuring that each user has
-     * isolated storage.
-     */
-    public void testMultiUserStorage() throws Exception {
-        final String PACKAGE = MULTIUSER_STORAGE_PKG;
-        final String CLAZZ = MULTIUSER_STORAGE_CLASS;
-
-        if (!isMultiUserSupportedOnDevice(getDevice())) {
-            Log.d(LOG_TAG, "Single user device; skipping isolated storage tests");
-            return;
-        }
-
-        int owner = 0;
-        int secondary = -1;
-        try {
-            // Create secondary user
-            secondary = createUserOnDevice(getDevice());
-
-            // Install our test app
-            getDevice().uninstallPackage(MULTIUSER_STORAGE_PKG);
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            final String installResult = getDevice()
-                    .installPackage(getTestAppFile(MULTIUSER_STORAGE_APK), false, options);
-            assertNull("Failed to install: " + installResult, installResult);
-
-            // Clear data from previous tests
-            assertDeviceTestsPass(
-                    doRunTestsAsUser(PACKAGE, CLAZZ, "cleanIsolatedStorage", owner));
-            assertDeviceTestsPass(
-                    doRunTestsAsUser(PACKAGE, CLAZZ, "cleanIsolatedStorage", secondary));
-
-            // Have both users try writing into isolated storage
-            assertDeviceTestsPass(
-                    doRunTestsAsUser(PACKAGE, CLAZZ, "writeIsolatedStorage", owner));
-            assertDeviceTestsPass(
-                    doRunTestsAsUser(PACKAGE, CLAZZ, "writeIsolatedStorage", secondary));
-
-            // Verify they both have isolated view of storage
-            assertDeviceTestsPass(
-                    doRunTestsAsUser(PACKAGE, CLAZZ, "readIsolatedStorage", owner));
-            assertDeviceTestsPass(
-                    doRunTestsAsUser(PACKAGE, CLAZZ, "readIsolatedStorage", secondary));
-        } finally {
-            getDevice().uninstallPackage(MULTIUSER_STORAGE_PKG);
-            if (secondary != -1) {
-                removeUserOnDevice(getDevice(), secondary);
-            }
-        }
+    private void runDeviceTests(String packageName) throws DeviceNotAvailableException {
+        Utils.runDeviceTests(getDevice(), packageName);
     }
 
-    /**
-     * 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) {
-        // TODO: consider rerunning if this occurred
-        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 will 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 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)
+    private void runDeviceTests(String packageName, 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();
-    }
-
-    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) {
-            fail("Failed to parse result: " + output);
-        }
-        return false;
-    }
-
-    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 {
-                return Integer.parseInt(output.substring(output.lastIndexOf(" ")).trim());
-            } catch (NumberFormatException e) {
-                fail("Failed to parse result: " + output);
-            }
-        } else {
-            fail("Failed to create user: " + output);
-        }
-        throw new IllegalStateException();
-    }
-
-    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")) {
-            fail("Failed to remove user: " + output);
-        }
-    }
-
-    private TestRunResult doRunTestsAsUser(
-            String pkgName, String testClassName, String testMethodName, int userId)
-            throws DeviceNotAvailableException {
-        // TODO: move this to RemoteAndroidTestRunner once it supports users
-        final String cmd = "am instrument --user " + userId + " -w -r -e class " + testClassName
-                + "#" + testMethodName + " " + pkgName + "/" + RUNNER;
-        Log.i(LOG_TAG, "Running " + cmd + " on " + getDevice().getSerialNumber());
-
-        CollectingTestListener listener = new CollectingTestListener();
-        InstrumentationResultParser parser = new InstrumentationResultParser(pkgName, listener);
-
-        getDevice().executeShellCommand(cmd, parser);
-        return listener.getCurrentRunResults();
-    }
-
-    private static void wipePrimaryExternalStorage(ITestDevice device)
-            throws DeviceNotAvailableException {
-        device.executeShellCommand("rm -rf /sdcard/*");
+        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
index fbde558..a4ec65a 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/DocumentsTest.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/DocumentsTest.java
@@ -24,6 +24,10 @@
 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";
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/ExternalStorageHostTest.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/ExternalStorageHostTest.java
new file mode 100644
index 0000000..9c22bdc
--- /dev/null
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/ExternalStorageHostTest.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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
index dae5ee7..9637a6c 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/KeySetHostTest.java
@@ -66,6 +66,20 @@
             "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 =
@@ -432,4 +446,70 @@
         testKeyRotationPerm(PERM_DEF_A_SIGNED, PERM_USE_A_SIGNED, PERM_DEF_B_SIGNED,
                 true, false);
     }
-}
\ No newline at end of file
+
+    /*
+     * 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
new file mode 100644
index 0000000..20a92aa
--- /dev/null
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/PermissionsHostTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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
index 90cbed9..ef3af8d 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/SplitTests.java
@@ -36,14 +36,15 @@
  * Tests that verify installing of various split APKs from host side.
  */
 public class SplitTests extends DeviceTestCase implements IAbiReceiver, IBuildReceiver {
-    private static final String PKG = "com.android.cts.splitapp";
+    static final String PKG = "com.android.cts.splitapp";
+    static final String CLASS = ".SplitAppTest";
 
-    private static final String APK = "CtsSplitApp.apk";
+    static final String APK = "CtsSplitApp.apk";
 
-    private static final String APK_mdpi = "CtsSplitApp_mdpi-v4.apk";
-    private static final String APK_hdpi = "CtsSplitApp_hdpi-v4.apk";
-    private static final String APK_xhdpi = "CtsSplitApp_xhdpi-v4.apk";
-    private static final String APK_xxhdpi = "CtsSplitApp_xxhdpi-v4.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";
@@ -69,7 +70,7 @@
     private static final String APK_FEATURE = "CtsSplitAppFeature.apk";
     private static final String APK_FEATURE_v7 = "CtsSplitAppFeature_v7.apk";
 
-    private static final HashMap<String, String> ABI_TO_APK = new HashMap<>();
+    static final HashMap<String, String> ABI_TO_APK = new HashMap<>();
 
     static {
         ABI_TO_APK.put("x86", APK_x86);
@@ -113,18 +114,18 @@
 
     public void testSingleBase() throws Exception {
         new InstallMultiple().addApk(APK).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testSingleBase");
+        runDeviceTests(PKG, CLASS, "testSingleBase");
     }
 
     public void testDensitySingle() throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testDensitySingle");
+        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, ".SplitAppTest", "testDensityAll");
+        runDeviceTests(PKG, CLASS, "testDensityAll");
     }
 
     /**
@@ -133,11 +134,11 @@
      */
     public void testDensityBest() throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_mdpi).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testDensityBest1");
+        runDeviceTests(PKG, CLASS, "testDensityBest1");
 
         // Now splice in an additional split which offers better resources
         new InstallMultiple().inheritFrom(PKG).addApk(APK_xxhdpi).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testDensityBest2");
+        runDeviceTests(PKG, CLASS, "testDensityBest2");
     }
 
     /**
@@ -146,12 +147,12 @@
      */
     public void testApi() throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_v7).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testApi");
+        runDeviceTests(PKG, CLASS, "testApi");
     }
 
     public void testLocale() throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_de).addApk(APK_fr).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testLocale");
+        runDeviceTests(PKG, CLASS, "testLocale");
     }
 
     /**
@@ -164,7 +165,7 @@
         assertNotNull("Failed to find APK for ABI " + abi, apk);
 
         new InstallMultiple().addApk(APK).addApk(apk).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testNative");
+        runDeviceTests(PKG, CLASS, "testNative");
     }
 
     /**
@@ -179,7 +180,7 @@
         assertNotNull("Failed to find APK for ABI " + abi, apk);
 
         new InstallMultiple().useNaturalAbi().addApk(APK).addApk(apk).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testNative");
+        runDeviceTests(PKG, CLASS, "testNative");
     }
 
     /**
@@ -192,7 +193,7 @@
             inst.addApk(apk);
         }
         inst.run();
-        runDeviceTests(PKG, ".SplitAppTest", "testNative");
+        runDeviceTests(PKG, CLASS, "testNative");
     }
 
     /**
@@ -207,7 +208,7 @@
             inst.addApk(apk);
         }
         inst.run();
-        runDeviceTests(PKG, ".SplitAppTest", "testNative");
+        runDeviceTests(PKG, CLASS, "testNative");
     }
 
     public void testDuplicateBase() throws Exception {
@@ -238,21 +239,21 @@
 
     public void testDiffRevision() throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_DIFF_REVISION_v7).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testRevision0_12");
+        runDeviceTests(PKG, CLASS, "testRevision0_12");
     }
 
     public void testDiffRevisionInheritBase() throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_v7).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testRevision0_0");
+        runDeviceTests(PKG, CLASS, "testRevision0_0");
         new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION_v7).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testRevision0_12");
+        runDeviceTests(PKG, CLASS, "testRevision0_12");
     }
 
     public void testDiffRevisionInheritSplit() throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_v7).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testRevision0_0");
+        runDeviceTests(PKG, CLASS, "testRevision0_0");
         new InstallMultiple().inheritFrom(PKG).addApk(APK_DIFF_REVISION).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testRevision12_0");
+        runDeviceTests(PKG, CLASS, "testRevision12_0");
     }
 
     public void testDiffRevisionDowngrade() throws Exception {
@@ -262,12 +263,12 @@
 
     public void testFeatureBase() throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_FEATURE).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testFeatureBase");
+        runDeviceTests(PKG, CLASS, "testFeatureBase");
     }
 
     public void testFeatureApi() throws Exception {
         new InstallMultiple().addApk(APK).addApk(APK_FEATURE).addApk(APK_FEATURE_v7).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testFeatureApi");
+        runDeviceTests(PKG, CLASS, "testFeatureApi");
     }
 
     public void testInheritUpdatedBase() throws Exception {
@@ -283,35 +284,72 @@
      */
     public void testClearCodeCache() throws Exception {
         new InstallMultiple().addApk(APK).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testCodeCacheWrite");
+        runDeviceTests(PKG, CLASS, "testCodeCacheWrite");
         new InstallMultiple().addArg("-r").addApk(APK_DIFF_VERSION).run();
-        runDeviceTests(PKG, ".SplitAppTest", "testCodeCacheRead");
+        runDeviceTests(PKG, CLASS, "testCodeCacheRead");
     }
 
-    class InstallMultiple {
-        private List<String> mArgs = new ArrayList<>();
-        private List<File> mApks = new ArrayList<>();
+    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;
 
-        InstallMultiple addArg(String arg) {
+        public BaseInstallMultiple(ITestDevice device, CtsBuildHelper build, IAbi abi) {
+            mDevice = device;
+            mBuild = build;
+            mAbi = abi;
+            addArg("-g");
+        }
+
+        T addArg(String arg) {
             mArgs.add(arg);
-            return this;
+            return (T) this;
         }
 
-        InstallMultiple addApk(String apk) throws FileNotFoundException {
-            mApks.add(mCtsBuild.getTestApp(apk));
-            return this;
+        T addApk(String apk) throws FileNotFoundException {
+            mApks.add(mBuild.getTestApp(apk));
+            return (T) this;
         }
 
-        InstallMultiple inheritFrom(String packageName) {
+        T inheritFrom(String packageName) {
             addArg("-r");
             addArg("-p " + packageName);
-            return this;
+            return (T) this;
         }
 
-        InstallMultiple useNaturalAbi() {
+        T useNaturalAbi() {
             mUseNaturalAbi = true;
-            return this;
+            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 {
@@ -323,7 +361,7 @@
         }
 
         private void run(boolean expectingSuccess) throws DeviceNotAvailableException {
-            final ITestDevice device = getDevice();
+            final ITestDevice device = mDevice;
 
             // Create an install session
             final StringBuilder cmd = new StringBuilder();
diff --git a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/Utils.java b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/Utils.java
index c58d6bf..fdf84d3 100644
--- a/hostsidetests/appsecurity/src/com/android/cts/appsecurity/Utils.java
+++ b/hostsidetests/appsecurity/src/com/android/cts/appsecurity/Utils.java
@@ -16,6 +16,7 @@
 
 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;
@@ -28,13 +29,37 @@
 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);
+        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;
         }
@@ -43,6 +68,13 @@
                 "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();
@@ -68,4 +100,66 @@
             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/AppAccessData/Android.mk b/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
index 2c9c624..4459e69 100644
--- a/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/AppAccessData/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk b/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
index 098ce9c..0916254 100644
--- a/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/AppWithData/Android.mk
@@ -29,4 +29,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/DocumentClient/Android.mk b/hostsidetests/appsecurity/test-apps/DocumentClient/Android.mk
index 910e3cd..272ef28 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentClient/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/DocumentClient/Android.mk
@@ -31,4 +31,4 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/DocumentProvider/Android.mk b/hostsidetests/appsecurity/test-apps/DocumentProvider/Android.mk
index a886fb2..bbf7734 100644
--- a/hostsidetests/appsecurity/test-apps/DocumentProvider/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/DocumentProvider/Android.mk
@@ -31,4 +31,4 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
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 fb8993c..14f215c 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
@@ -239,13 +239,16 @@
             new AsyncTask<Void, Void, Void>() {
                 @Override
                 protected Void doInBackground(Void... params) {
-                    try {
-                        final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
-                                pipe[0]);
-                        doc.contents = readFullyNoClose(is);
-                        is.close();
-                    } catch (IOException e) {
-                        Log.w(TAG, "Failed to stream", e);
+                    synchronized (doc) {
+                        try {
+                            final InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(
+                                    pipe[0]);
+                            doc.contents = readFullyNoClose(is);
+                            is.close();
+                            doc.notifyAll();
+                        } catch (IOException e) {
+                            Log.w(TAG, "Failed to stream", e);
+                        }
                     }
                     return null;
                 }
@@ -255,13 +258,20 @@
             new AsyncTask<Void, Void, Void>() {
                 @Override
                 protected Void doInBackground(Void... params) {
-                    try {
-                        final OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(
-                                pipe[1]);
-                        os.write(doc.contents);
-                        os.close();
-                    } catch (IOException e) {
-                        Log.w(TAG, "Failed to stream", e);
+                    synchronized (doc) {
+                        try {
+                            final OutputStream os = new ParcelFileDescriptor.AutoCloseOutputStream(
+                                    pipe[1]);
+                            while (doc.contents == null) {
+                                doc.wait();
+                            }
+                            os.write(doc.contents);
+                            os.close();
+                        } catch (IOException e) {
+                            Log.w(TAG, "Failed to stream", e);
+                        } catch (InterruptedException e) {
+                            Log.w(TAG, "Interuppted", e);
+                        }
                     }
                     return null;
                 }
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
index afc8764..a7de92a 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/Android.mk
@@ -25,4 +25,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/AndroidManifest.xml
index 9d8f615..98fe92a 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/AndroidManifest.xml
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/AndroidManifest.xml
@@ -23,4 +23,6 @@
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
         android:targetPackage="com.android.cts.externalstorageapp" />
 
+    <uses-permission android:name="android.permission.INTERNET" />
+
 </manifest>
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 5b4d9f7..7fe0b80 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
@@ -16,18 +16,29 @@
 
 package com.android.cts.externalstorageapp;
 
+import android.content.ContentResolver;
+import android.content.ContentValues;
 import android.content.Context;
+import android.net.Uri;
 import android.os.Environment;
+import android.provider.MediaStore;
+import android.provider.MediaStore.Images;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
@@ -43,6 +54,14 @@
     public static final String PACKAGE_WRITE = "com.android.cts.writeexternalstorageapp";
 
     /**
+     * Dump helpful debugging details.
+     */
+    public void testDumpDebug() throws Exception {
+        logCommand("/system/bin/id");
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+    }
+
+    /**
      * Primary storage must always be mounted.
      */
     public void testExternalStorageMounted() {
@@ -88,7 +107,7 @@
         for (File path : paths) {
             assertNotNull("Valid media must be inserted during CTS", path);
             assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
-                    Environment.getStorageState(path));
+                    Environment.getExternalStorageState(path));
 
             assertDirReadWriteAccess(path);
 
@@ -149,6 +168,21 @@
         return paths;
     }
 
+    public static List<File> getMountPaths() throws IOException {
+        final List<File> paths = new ArrayList<>();
+        final BufferedReader br = new BufferedReader(new FileReader("/proc/self/mounts"));
+        try {
+            String line;
+            while ((line = br.readLine()) != null) {
+                final String[] fields = line.split(" ");
+                paths.add(new File(fields[1]));
+            }
+        } finally {
+            br.close();
+        }
+        return paths;
+    }
+
     private static File[] dropFirst(File[] before) {
         final File[] after = new File[before.length - 1];
         System.arraycopy(before, 1, after, 0, after.length);
@@ -274,6 +308,35 @@
         }
     }
 
+    public static void assertMediaNoAccess(ContentResolver resolver) throws Exception {
+        final ContentValues values = new ContentValues();
+        values.put(Images.Media.MIME_TYPE, "image/jpeg");
+        values.put(Images.Media.DATA,
+                buildProbeFile(Environment.getExternalStorageDirectory()).getAbsolutePath());
+
+        try {
+            resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
+            fail("Expected access to be blocked");
+        } catch (Exception expected) {
+        }
+    }
+
+    public static void assertMediaReadWriteAccess(ContentResolver resolver) throws Exception {
+        final ContentValues values = new ContentValues();
+        values.put(Images.Media.MIME_TYPE, "image/jpeg");
+        values.put(Images.Media.DATA,
+                buildProbeFile(Environment.getExternalStorageDirectory()).getAbsolutePath());
+
+        final Uri uri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
+        try {
+            resolver.openFileDescriptor(uri, "rw").close();
+            resolver.openFileDescriptor(uri, "w").close();
+            resolver.openFileDescriptor(uri, "r").close();
+        } finally {
+            resolver.delete(uri, null, null);
+        }
+    }
+
     private static boolean isWhiteList(File file) {
         final String[] whiteLists = {
                 "autorun.inf", ".android_secure", "android_secure"
@@ -315,7 +378,9 @@
             }
 
             File[] dirs = removeWhiteList(dir.listFiles());
-            assertEquals(0, dirs.length);
+            if (dirs.length != 0) {
+                fail("Expected wiped storage but found: " + Arrays.toString(dirs));
+            }
         }
     }
 
@@ -336,4 +401,27 @@
             is.close();
         }
     }
+
+    public static void logCommand(String... cmd) throws Exception {
+        final Process proc = new ProcessBuilder(cmd).redirectErrorStream(true).start();
+
+        final ByteArrayOutputStream buf = new ByteArrayOutputStream();
+        copy(proc.getInputStream(), buf);
+        final int res = proc.waitFor();
+
+        Log.d(TAG, Arrays.toString(cmd) + " result " + res + ":");
+        Log.d(TAG, buf.toString());
+    }
+
+    /** Shamelessly lifted from libcore.io.Streams */
+    public static int copy(InputStream in, OutputStream out) throws IOException {
+        int total = 0;
+        byte[] buffer = new byte[8192];
+        int c;
+        while ((c = in.read(buffer)) != -1) {
+            total += c;
+            out.write(buffer, 0, c);
+        }
+        return total;
+    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/ExternalStorageTest.java b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/ExternalStorageTest.java
index 425815f..6030f1c 100644
--- a/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/ExternalStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/ExternalStorageTest.java
@@ -16,21 +16,31 @@
 
 package com.android.cts.externalstorageapp;
 
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_NONE;
-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.assertDirNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoWriteAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
-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.getAllPackageSpecificPaths;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getMountPaths;
 
+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.database.Cursor;
+import android.net.Uri;
 import android.os.Environment;
+import android.os.SystemClock;
 import android.test.AndroidTestCase;
+import android.text.format.DateUtils;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 
 /**
@@ -62,7 +72,7 @@
             }
 
             // Keep walking up until we leave device
-            while (Environment.MEDIA_MOUNTED.equals(Environment.getStorageState(path))) {
+            while (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState(path))) {
                 assertDirNoAccess(path);
                 path = path.getParentFile();
             }
@@ -70,17 +80,123 @@
     }
 
     /**
-     * Verify we can read only our gifts.
+     * Verify that we don't have read access to any storage mountpoints.
      */
-    public void doVerifyGifts() throws Exception {
-        final File none = buildGiftForPackage(getContext(), PACKAGE_NONE);
-        assertFileReadWriteAccess(none);
-        assertEquals(100, readInt(none));
+    public void testMountPointsNotReadable() throws Exception {
+        final String userId = Integer.toString(android.os.Process.myUid() / 100000);
+        final List<File> mountPaths = getMountPaths();
+        for (File path : mountPaths) {
+            if (path.getAbsolutePath().startsWith("/mnt/")
+                    || path.getAbsolutePath().startsWith("/storage/")) {
+                // Mount points could be multi-user aware, so try probing both
+                // top level and user-specific directory.
+                final File userPath = new File(path, userId);
 
-        final File read = buildGiftForPackage(getContext(), PACKAGE_READ);
-        assertFileNoAccess(read);
+                assertDirNoAccess(path);
+                assertDirNoAccess(userPath);
+            }
+        }
+    }
 
-        final File write = buildGiftForPackage(getContext(), PACKAGE_WRITE);
-        assertFileNoAccess(write);
+    /**
+     * Verify that we can't download things outside package directory.
+     */
+    public void testDownloadManager() throws Exception {
+        final DownloadManager dm = getContext().getSystemService(DownloadManager.class);
+        try {
+            final Uri source = Uri.parse("http://www.example.com");
+            final File target = new File(
+                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "meow");
+            dm.enqueue(new Request(source).setDestinationUri(Uri.fromFile(target)));
+            fail("Unexpected success writing outside package directory");
+        } catch (SecurityException expected) {
+        }
+    }
+
+    /**
+     * Verify that we can download things into our package directory.
+     */
+    public void testDownloadManagerPackage() throws Exception {
+        final DownloadManager dm = getContext().getSystemService(DownloadManager.class);
+        final DownloadCompleteReceiver receiver = new DownloadCompleteReceiver();
+        try {
+            IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
+            mContext.registerReceiver(receiver, intentFilter);
+
+            final Uri source = Uri.parse("http://www.example.com");
+            final File target = new File(
+                    getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "meow");
+
+            final long id = dm.enqueue(new Request(source).setDestinationUri(Uri.fromFile(target)));
+            receiver.waitForDownloadComplete(30 * DateUtils.SECOND_IN_MILLIS, id);
+            assertSuccessfulDownload(id, target);
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    /**
+     * Shamelessly borrowed from DownloadManagerTest.java
+     */
+    private static 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 assertSuccessfulDownload(long id, File location) {
+        final DownloadManager dm = getContext().getSystemService(DownloadManager.class);
+
+        Cursor cursor = null;
+        try {
+            cursor = dm.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();
+            }
+        }
     }
 }
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
new file mode 100644
index 0000000..e482b2f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/ExternalStorageApp/src/com/android/cts/externalstorageapp/GiftTest.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.cts.externalstorageapp;
+
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_NONE;
+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.assertFileNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertFileReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.buildGiftForPackage;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
+
+import android.test.AndroidTestCase;
+
+import java.io.File;
+
+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 File read = buildGiftForPackage(getContext(), PACKAGE_READ);
+        assertFileNoAccess(read);
+
+        final File write = buildGiftForPackage(getContext(), PACKAGE_WRITE);
+        assertFileNoAccess(write);
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
index e8ce3b8..4c64204 100644
--- a/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/InstrumentationAppDiffCert/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
index 1dd109a..c37d052 100644
--- a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/Android.mk
@@ -27,4 +27,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java
index 2a80c75..d9f00d2 100644
--- a/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java
+++ b/hostsidetests/appsecurity/test-apps/MultiUserStorageApp/src/com/android/cts/multiuserstorageapp/MultiUserStorageTest.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.multiuserstorageapp;
 
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPathsExceptObb;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.writeInt;
@@ -45,7 +46,9 @@
 
     private void wipeTestFiles(File dir) {
         dir.mkdirs();
-        for (File file : dir.listFiles()) {
+        final File[] files = dir.listFiles();
+        if (files == null) return;
+        for (File file : files) {
             if (file.getName().startsWith(FILE_PREFIX)) {
                 Log.d(TAG, "Wiping " + file);
                 file.delete();
@@ -53,11 +56,11 @@
         }
     }
 
-    public void cleanIsolatedStorage() throws Exception {
+    public void testCleanIsolatedStorage() throws Exception {
         wipeTestFiles(Environment.getExternalStorageDirectory());
     }
 
-    public void writeIsolatedStorage() throws Exception {
+    public void testWriteIsolatedStorage() throws Exception {
         final int uid = android.os.Process.myUid();
 
         writeInt(buildApiPath(FILE_SINGLETON), uid);
@@ -67,13 +70,13 @@
         for (File path : getAllPackageSpecificPathsExceptObb(getContext())) {
             assertNotNull("Valid media must be inserted during CTS", path);
             assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
-                    Environment.getStorageState(path));
+                    Environment.getExternalStorageState(path));
 
             writeInt(new File(path, FILE_SINGLETON), uid);
         }
     }
 
-    public void readIsolatedStorage() throws Exception {
+    public void testReadIsolatedStorage() throws Exception {
         final int uid = android.os.Process.myUid();
 
         // Expect that the value we wrote earlier is still valid and wasn't
@@ -91,23 +94,23 @@
         for (File path : getAllPackageSpecificPathsExceptObb(getContext())) {
             assertNotNull("Valid media must be inserted during CTS", path);
             assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
-                    Environment.getStorageState(path));
+                    Environment.getExternalStorageState(path));
 
             assertEquals("Unexpected value in singleton file at " + path, uid,
                     readInt(new File(path, FILE_SINGLETON)));
         }
     }
 
-    public void cleanObbStorage() throws Exception {
+    public void testCleanObbStorage() throws Exception {
         wipeTestFiles(getContext().getObbDir());
     }
 
-    public void writeObbStorage() throws Exception {
+    public void testWriteObbStorage() throws Exception {
         writeInt(buildApiObbPath(FILE_OBB_API_SINGLETON), OBB_API_VALUE);
         writeInt(buildEnvObbPath(FILE_OBB_SINGLETON), OBB_VALUE);
     }
 
-    public void readObbStorage() throws Exception {
+    public void testReadObbStorage() throws Exception {
         assertEquals("Failed to read OBB file from API path", OBB_API_VALUE,
                 readInt(buildApiObbPath(FILE_OBB_API_SINGLETON)));
 
@@ -117,6 +120,24 @@
                 readInt(buildRawObbPath(FILE_OBB_SINGLETON)));
     }
 
+    /**
+     * Verify that we can't poke at storage of other users.
+     */
+    public void testUserIsolation() throws Exception {
+        final File myPath = Environment.getExternalStorageDirectory();
+        final int myId = android.os.Process.myUid() / 100000;
+        assertEquals(String.valueOf(myId), myPath.getName());
+
+        Log.d(TAG, "My path is " + myPath);
+        final File basePath = myPath.getParentFile();
+        for (int i = 0; i < 128; i++) {
+            if (i == myId) continue;
+
+            final File otherPath = new File(basePath, String.valueOf(i));
+            assertDirNoAccess(otherPath);
+        }
+    }
+
     private File buildApiObbPath(String file) {
         return new File(getContext().getObbDir(), file);
     }
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
index 60d6fad..43d3547 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareApp/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
index ba7285c..5109c99 100644
--- a/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/PermissionDeclareAppCompat/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/Android.mk
index 3e392e3..c662d39 100644
--- a/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/Android.mk
@@ -27,4 +27,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+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 bbd1e7a..995da90 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
@@ -16,16 +16,11 @@
 
 package com.android.cts.readexternalstorageapp;
 
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_NONE;
-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.assertDirNoWriteAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadOnlyAccess;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
-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.getAllPackageSpecificPaths;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getMountPaths;
 
 import android.os.Environment;
 import android.test.AndroidTestCase;
@@ -54,7 +49,7 @@
         for (File path : paths) {
             assertNotNull("Valid media must be inserted during CTS", path);
             assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
-                    Environment.getStorageState(path));
+                    Environment.getExternalStorageState(path));
 
             assertTrue(path.getAbsolutePath().contains(packageName));
 
@@ -65,7 +60,7 @@
             }
 
             // Keep walking up until we leave device
-            while (Environment.MEDIA_MOUNTED.equals(Environment.getStorageState(path))) {
+            while (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState(path))) {
                 assertDirReadOnlyAccess(path);
                 path = path.getParentFile();
             }
@@ -73,19 +68,21 @@
     }
 
     /**
-     * Verify we can read all gifts.
+     * Verify that we don't have write access to any mountpoints.
      */
-    public void doVerifyGifts() throws Exception {
-        final File none = buildGiftForPackage(getContext(), PACKAGE_NONE);
-        assertFileReadOnlyAccess(none);
-        assertEquals(100, readInt(none));
+    public void testMountPointsNotWritable() throws Exception {
+        final String userId = Integer.toString(android.os.Process.myUid() / 100000);
+        final List<File> mountPaths = getMountPaths();
+        for (File path : mountPaths) {
+            if (path.getAbsolutePath().startsWith("/mnt/")
+                    || path.getAbsolutePath().startsWith("/storage/")) {
+                // Mount points could be multi-user aware, so try probing both
+                // top level and user-specific directory.
+                final File userPath = new File(path, userId);
 
-        final File read = buildGiftForPackage(getContext(), PACKAGE_READ);
-        assertFileReadWriteAccess(read);
-        assertEquals(101, readInt(read));
-
-        final File write = buildGiftForPackage(getContext(), PACKAGE_WRITE);
-        assertFileReadOnlyAccess(write);
-        assertEquals(102, readInt(write));
+                assertDirNoWriteAccess(path);
+                assertDirNoWriteAccess(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
new file mode 100644
index 0000000..e72be77
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/ReadExternalStorageApp/src/com/android/cts/readexternalstorageapp/ReadGiftTest.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.cts.readexternalstorageapp;
+
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_NONE;
+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.assertFileReadOnlyAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertFileReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.buildGiftForPackage;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
+
+import android.test.AndroidTestCase;
+
+import java.io.File;
+
+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 File read = buildGiftForPackage(getContext(), PACKAGE_READ);
+        assertFileReadWriteAccess(read);
+        assertEquals(101, readInt(read));
+
+        final File write = buildGiftForPackage(getContext(), PACKAGE_WRITE);
+        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 76187ab..05438ef 100644
--- a/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SharedUidInstall/Android.mk
@@ -32,4 +32,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
index c1422ec..eaed910 100644
--- a/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SharedUidInstallDiffCert/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk b/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
index fb925cd..01cffdb 100644
--- a/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SimpleAppInstall/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
index 2224d72..032ef57 100644
--- a/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SimpleAppInstallDiffCert/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
index bf89576..de46dea 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/Android.mk
@@ -35,7 +35,7 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 
 #################################################
@@ -59,7 +59,7 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 
 ################################################
@@ -82,7 +82,7 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 
 ################################################
@@ -105,7 +105,7 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 
 ifeq (,$(ONE_SHOT_MAKEFILE))
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
index 809a6b8..fbb7764 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/feature/Android.mk
@@ -35,4 +35,4 @@
 
 LOCAL_AAPT_FLAGS += --feature-of $(featureOfApk)
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
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 543e4ac..9faaba1 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/arm64-v8a/Android.mk
@@ -25,4 +25,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
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 7cdef62..87b32aa 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi-v7a/Android.mk
@@ -25,4 +25,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
index 26ec5bd..fe289e0 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/armeabi/Android.mk
@@ -25,4 +25,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
index fea0603..d66d674 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips/Android.mk
@@ -25,4 +25,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
index 3cc5609..7232324 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/mips64/Android.mk
@@ -25,4 +25,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
index d45ca8f..f1cd994 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86/Android.mk
@@ -25,4 +25,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
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 fa0e488..521f6f2 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/libs/x86_64/Android.mk
@@ -25,4 +25,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
 LOCAL_AAPT_FLAGS := --version-code 100 --replace-version
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
index 3d6cee7..c5f0fd0 100644
--- a/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
+++ b/hostsidetests/appsecurity/test-apps/SplitApp/src/com/android/cts/splitapp/SplitAppTest.java
@@ -19,6 +19,7 @@
 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
 import static org.xmlpull.v1.XmlPullParser.START_TAG;
 
+import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
@@ -27,9 +28,17 @@
 import android.content.pm.ResolveInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.drawable.Drawable;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.os.StatFs;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
 import android.test.AndroidTestCase;
 import android.test.MoreAsserts;
 import android.util.DisplayMetrics;
@@ -39,7 +48,12 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.lang.reflect.Field;
@@ -51,9 +65,14 @@
     private static final String TAG = "SplitAppTest";
     private static final String PKG = "com.android.cts.splitapp";
 
+    private static final long MB_IN_BYTES = 1 * 1024 * 1024;
+
     public static boolean sFeatureTouched = false;
     public static String sFeatureValue = null;
 
+    public void testNothing() throws Exception {
+    }
+
     public void testSingleBase() throws Exception {
         final Resources r = getContext().getResources();
         final PackageManager pm = getContext().getPackageManager();
@@ -311,6 +330,131 @@
         assertEquals(0, result.size());
     }
 
+    /**
+     * Write app data in a number of locations that expect to remain intact over
+     * long periods of time, such as across app moves.
+     */
+    public void testDataWrite() throws Exception {
+        final String token = String.valueOf(android.os.Process.myUid());
+        writeString(getContext().getFileStreamPath("my_int"), token);
+
+        final SQLiteDatabase db = getContext().openOrCreateDatabase("my_db",
+                Context.MODE_PRIVATE, null);
+        try {
+            db.execSQL("DROP TABLE IF EXISTS my_table");
+            db.execSQL("CREATE TABLE my_table(value INTEGER)");
+            db.execSQL("INSERT INTO my_table VALUES (101), (102), (103)");
+        } finally {
+            db.close();
+        }
+    }
+
+    /**
+     * Verify that data written by {@link #testDataWrite()} is still intact.
+     */
+    public void testDataRead() throws Exception {
+        final String token = String.valueOf(android.os.Process.myUid());
+        assertEquals(token, readString(getContext().getFileStreamPath("my_int")));
+
+        final SQLiteDatabase db = getContext().openOrCreateDatabase("my_db",
+                Context.MODE_PRIVATE, null);
+        try {
+            final Cursor cursor = db.query("my_table", null, null, null, null, null, "value ASC");
+            try {
+                assertEquals(3, cursor.getCount());
+                assertTrue(cursor.moveToPosition(0));
+                assertEquals(101, cursor.getInt(0));
+                assertTrue(cursor.moveToPosition(1));
+                assertEquals(102, cursor.getInt(0));
+                assertTrue(cursor.moveToPosition(2));
+                assertEquals(103, cursor.getInt(0));
+            } finally {
+                cursor.close();
+            }
+        } finally {
+            db.close();
+        }
+    }
+
+    /**
+     * Verify that app is installed on internal storage.
+     */
+    public void testDataInternal() throws Exception {
+        final StructStat internal = Os.stat(Environment.getDataDirectory().getAbsolutePath());
+        final StructStat actual = Os.stat(getContext().getFilesDir().getAbsolutePath());
+        assertEquals(internal.st_dev, actual.st_dev);
+    }
+
+    /**
+     * Verify that app is not installed on internal storage.
+     */
+    public void testDataNotInternal() throws Exception {
+        final StructStat internal = Os.stat(Environment.getDataDirectory().getAbsolutePath());
+        final StructStat actual = Os.stat(getContext().getFilesDir().getAbsolutePath());
+        MoreAsserts.assertNotEqual(internal.st_dev, actual.st_dev);
+    }
+
+    public void testPrimaryDataWrite() throws Exception {
+        final String token = String.valueOf(android.os.Process.myUid());
+        writeString(new File(getContext().getExternalFilesDir(null), "my_ext"), token);
+    }
+
+    public void testPrimaryDataRead() throws Exception {
+        final String token = String.valueOf(android.os.Process.myUid());
+        assertEquals(token, readString(new File(getContext().getExternalFilesDir(null), "my_ext")));
+    }
+
+    /**
+     * Verify shared storage behavior when on internal storage.
+     */
+    public void testPrimaryInternal() throws Exception {
+        assertTrue("emulated", Environment.isExternalStorageEmulated());
+        assertFalse("removable", Environment.isExternalStorageRemovable());
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+    }
+
+    /**
+     * Verify shared storage behavior when on physical storage.
+     */
+    public void testPrimaryPhysical() throws Exception {
+        assertFalse("emulated", Environment.isExternalStorageEmulated());
+        assertTrue("removable", Environment.isExternalStorageRemovable());
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+    }
+
+    /**
+     * Verify shared storage behavior when on adopted storage.
+     */
+    public void testPrimaryAdopted() throws Exception {
+        assertTrue("emulated", Environment.isExternalStorageEmulated());
+        assertTrue("removable", Environment.isExternalStorageRemovable());
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+    }
+
+    /**
+     * Verify that shared storage is unmounted.
+     */
+    public void testPrimaryUnmounted() throws Exception {
+        MoreAsserts.assertNotEqual(Environment.MEDIA_MOUNTED,
+                Environment.getExternalStorageState());
+    }
+
+    /**
+     * Verify that shared storage lives on same volume as app.
+     */
+    public void testPrimaryOnSameVolume() throws Exception {
+        final File current = getContext().getFilesDir();
+        final File primary = Environment.getExternalStorageDirectory();
+
+        // Shared storage may jump through another filesystem for permission
+        // enforcement, so we verify that total/free space are identical.
+        final long totalDelta = Math.abs(current.getTotalSpace() - primary.getTotalSpace());
+        final long freeDelta = Math.abs(current.getFreeSpace() - primary.getFreeSpace());
+        if (totalDelta > MB_IN_BYTES || freeDelta > MB_IN_BYTES) {
+            fail("Expected primary storage to be on same volume as app");
+        }
+    }
+
     public void testCodeCacheWrite() throws Exception {
         assertTrue(new File(getContext().getFilesDir(), "normal.raw").createNewFile());
         assertTrue(new File(getContext().getCodeCacheDir(), "cache.raw").createNewFile());
@@ -390,4 +534,22 @@
             if (in != null) in.close();
         }
     }
+
+    private static void writeString(File file, String value) throws IOException {
+        final DataOutputStream os = new DataOutputStream(new FileOutputStream(file));
+        try {
+            os.writeUTF(value);
+        } finally {
+            os.close();
+        }
+    }
+
+    private static String readString(File file) throws IOException {
+        final DataInputStream is = new DataInputStream(new FileInputStream(file));
+        try {
+            return is.readUTF();
+        } finally {
+            is.close();
+        }
+    }
 }
diff --git a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
index 38a0511..f5ac52f 100644
--- a/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/TargetInstrumentationApp/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionApp/Android.mk
new file mode 100644
index 0000000..f91d0c4
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp/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_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) \
+    ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+
+LOCAL_PACKAGE_NAME := CtsUsePermissionApp
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.xml
new file mode 100644
index 0000000..ece4ebe
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp/AndroidManifest.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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.usepermission">
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name=".MyActivity" />
+    </application>
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.usepermission" />
+
+    <!-- Note that WRITE_EXTERNAL_STORAGE implies READ_EXTERNAL_STORAGE;
+         this is a special case. -->
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <!-- Deliberately request WRITE_CONTACTS but *not* READ_CONTACTS -->
+    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+
+    <!-- Request two different permissions within the same group -->
+    <uses-permission android:name="android.permission.SEND_SMS" />
+    <uses-permission android:name="android.permission.RECEIVE_SMS" />
+
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/MyActivity.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/MyActivity.java
new file mode 100644
index 0000000..5af3886
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/MyActivity.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.usepermission;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.TimeUnit;
+
+public class MyActivity extends Activity {
+    private final SynchronousQueue<Result> mResult = new SynchronousQueue<>();
+
+    public static class Result {
+        public final int requestCode;
+        public final String[] permissions;
+        public final int[] grantResults;
+
+        public Result(int requestCode, String[] permissions, int[] grantResults) {
+            this.requestCode = requestCode;
+            this.permissions = permissions;
+            this.grantResults = grantResults;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
+                | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
+    }
+
+    @Override
+    public void onRequestPermissionsResult(int requestCode, String[] permissions,
+            int[] grantResults) {
+        try {
+            mResult.offer(new Result(requestCode, permissions, grantResults), 5, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public Result getResult() {
+        try {
+            return mResult.take();
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java
new file mode 100644
index 0000000..8d3b976
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionApp/src/com/android/cts/usepermission/UsePermissionTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.usepermission;
+
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
+
+import android.content.pm.PackageManager;
+import android.os.Environment;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject;
+import android.support.test.uiautomator.UiSelector;
+import android.test.InstrumentationTestCase;
+
+public class UsePermissionTest extends InstrumentationTestCase {
+    private static final String TAG = "UsePermissionTest";
+
+    private UiDevice mDevice;
+    private MyActivity mActivity;
+
+    public void testFail() throws Exception {
+        fail("Expected");
+    }
+
+    public void testKill() throws Exception {
+        android.os.Process.killProcess(android.os.Process.myPid());
+    }
+
+    public void testDefault() throws Exception {
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // New permission model is denied by default
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirNoAccess(Environment.getExternalStorageDirectory());
+        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
+        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver());
+    }
+
+    public void testGranted() throws Exception {
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
+        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
+        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+    }
+
+    public void testInteractiveGrant() throws Exception {
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // Start out without permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirNoAccess(Environment.getExternalStorageDirectory());
+        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
+        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver());
+
+        // Go through normal grant flow
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                MyActivity.class, null);
+        mDevice.waitForIdle();
+
+        mActivity.requestPermissions(new String[] {
+                android.Manifest.permission.READ_EXTERNAL_STORAGE,
+                android.Manifest.permission.WRITE_EXTERNAL_STORAGE }, 42);
+        mDevice.waitForIdle();
+
+        new UiObject(new UiSelector()
+                .resourceId("com.android.packageinstaller:id/permission_allow_button")).click();
+        mDevice.waitForIdle();
+
+        MyActivity.Result result = mActivity.getResult();
+        assertEquals(42, result.requestCode);
+        assertEquals(android.Manifest.permission.READ_EXTERNAL_STORAGE, result.permissions[0]);
+        assertEquals(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, result.permissions[1]);
+        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
+        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[1]);
+
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // We should have permission now!
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE));
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
+        assertDirReadWriteAccess(getInstrumentation().getContext().getExternalCacheDir());
+        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+
+        mActivity.finish();
+    }
+
+    public void testRuntimeGroupGrantSpecificity() throws Exception {
+        // Start out without permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.WRITE_CONTACTS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.READ_CONTACTS));
+
+        // Go through normal grant flow
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                MyActivity.class, null);
+        mDevice.waitForIdle();
+
+        // request only one permission from the 'contacts' permission group
+        mActivity.requestPermissions(new String[] {
+                android.Manifest.permission.WRITE_CONTACTS }, 43);
+        mDevice.waitForIdle();
+
+        new UiObject(new UiSelector()
+                .resourceId("com.android.packageinstaller:id/permission_allow_button")).click();
+        mDevice.waitForIdle();
+
+        MyActivity.Result result = mActivity.getResult();
+        assertEquals(43, result.requestCode);
+        assertEquals(android.Manifest.permission.WRITE_CONTACTS, result.permissions[0]);
+        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
+
+        // We should have only the explicitly requested permission from this group
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.WRITE_CONTACTS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.READ_CONTACTS));
+
+        mActivity.finish();
+    }
+
+    public void testRuntimeGroupGrantExpansion() throws Exception {
+        // Start out without permission
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.RECEIVE_SMS));
+        assertEquals(PackageManager.PERMISSION_DENIED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.SEND_SMS));
+
+        // Go through normal grant flow
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mActivity = launchActivity(getInstrumentation().getTargetContext().getPackageName(),
+                MyActivity.class, null);
+        mDevice.waitForIdle();
+
+        // request only one permission from the 'SMS' permission group at runtime,
+        // but two from this group are <uses-permission> in the manifest
+        mActivity.requestPermissions(new String[] {
+                android.Manifest.permission.RECEIVE_SMS }, 44);
+        mDevice.waitForIdle();
+
+        new UiObject(new UiSelector()
+                .resourceId("com.android.packageinstaller:id/permission_allow_button")).click();
+        mDevice.waitForIdle();
+
+        MyActivity.Result result = mActivity.getResult();
+        assertEquals(44, result.requestCode);
+        assertEquals(android.Manifest.permission.RECEIVE_SMS, result.permissions[0]);
+        assertEquals(PackageManager.PERMISSION_GRANTED, result.grantResults[0]);
+
+        // We should now have been granted both of the permissions from this group
+        // that are mentioned in our manifest
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.RECEIVE_SMS));
+        assertEquals(PackageManager.PERMISSION_GRANTED, getInstrumentation().getContext()
+                .checkSelfPermission(android.Manifest.permission.SEND_SMS));
+
+        mActivity.finish();
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/Android.mk
new file mode 100644
index 0000000..70b4b0f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/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_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := 21
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test ctsdeviceutil ctstestrunner ub-uiautomator
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) \
+    ../ExternalStorageApp/src/com/android/cts/externalstorageapp/CommonExternalStorageTest.java
+
+LOCAL_PACKAGE_NAME := CtsUsePermissionAppCompat
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+
+LOCAL_PROGUARD_ENABLED := disabled
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/AndroidManifest.xml
new file mode 100644
index 0000000..253d85d
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/AndroidManifest.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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.usepermission">
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name=".MyActivity" />
+    </application>
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.usepermission" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/src/com/android/cts/usepermission/UsePermissionCompatTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/src/com/android/cts/usepermission/UsePermissionCompatTest.java
new file mode 100644
index 0000000..7f21d3400
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionAppCompat/src/com/android/cts/usepermission/UsePermissionCompatTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.usepermission;
+
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertDirReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaNoAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.assertMediaReadWriteAccess;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getAllPackageSpecificPaths;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.logCommand;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Environment;
+import android.os.Process;
+import android.test.InstrumentationTestCase;
+
+import java.io.File;
+
+public class UsePermissionCompatTest extends InstrumentationTestCase {
+    private static final String TAG = "UsePermissionTest";
+
+    public void testCompatDefault() throws Exception {
+        final Context context = getInstrumentation().getContext();
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // Legacy permission model is granted by default
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                context.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
+                        Process.myPid(), Process.myUid()));
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                context.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                        Process.myPid(), Process.myUid()));
+        assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState());
+        assertDirReadWriteAccess(Environment.getExternalStorageDirectory());
+        for (File path : getAllPackageSpecificPaths(context)) {
+            if (path != null) {
+                assertDirReadWriteAccess(path);
+            }
+        }
+        assertMediaReadWriteAccess(getInstrumentation().getContext().getContentResolver());
+    }
+
+    public void testCompatRevoked() throws Exception {
+        final Context context = getInstrumentation().getContext();
+        logCommand("/system/bin/cat", "/proc/self/mountinfo");
+
+        // Legacy permission model appears granted, but storage looks and
+        // behaves like it's ejected
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                context.checkPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE,
+                        Process.myPid(), Process.myUid()));
+        assertEquals(PackageManager.PERMISSION_GRANTED,
+                context.checkPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE,
+                        Process.myPid(), Process.myUid()));
+        assertEquals(Environment.MEDIA_UNMOUNTED, Environment.getExternalStorageState());
+        assertDirNoAccess(Environment.getExternalStorageDirectory());
+        for (File dir : getAllPackageSpecificPaths(context)) {
+            if (dir != null) {
+                assertDirNoAccess(dir);
+            }
+        }
+        assertMediaNoAccess(getInstrumentation().getContext().getContentResolver());
+
+        // Just to be sure, poke explicit path
+        assertDirNoAccess(new File(Environment.getExternalStorageDirectory(),
+                "/Android/data/" + getInstrumentation().getContext().getPackageName()));
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
index 8878c47..6e0d090 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/Android.mk
@@ -31,4 +31,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/ModifyInstallerPackageTest.java b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/ModifyInstallerPackageTest.java
index f2fcc78..989e24b 100644
--- a/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/ModifyInstallerPackageTest.java
+++ b/hostsidetests/appsecurity/test-apps/UsePermissionDiffCert/src/com/android/cts/usespermissiondiffcertapp/ModifyInstallerPackageTest.java
@@ -43,7 +43,6 @@
         boolean mHaveResult = false;
         boolean mGoodResult = false;
         boolean mSucceeded = false;
-        static final int TIMEOUT_MS = 30000;
 
         @Override
         public void onReceive(Context context, Intent intent) {
@@ -71,10 +70,10 @@
                 final long startTime = SystemClock.uptimeMillis();
                 while (!mHaveResult) {
                     try {
-                        wait(TIMEOUT_MS);
+                        wait(5000);
                     } catch (InterruptedException e) {
                     }
-                    if (SystemClock.uptimeMillis() >= (startTime+TIMEOUT_MS)) {
+                    if (SystemClock.uptimeMillis() >= (startTime+5000)) {
                         throw new RuntimeException("Timeout");
                     }
                 }
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
index a98fcea..cdd77e8 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/Android.mk
@@ -27,4 +27,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
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 6857236..3861ddf 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
@@ -17,17 +17,14 @@
 package com.android.cts.writeexternalstorageapp;
 
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_NONE;
-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.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.assertFileReadWriteAccess;
-import static com.android.cts.externalstorageapp.CommonExternalStorageTest.buildGiftForPackage;
 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.getMountPaths;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getPrimaryPackageSpecificPaths;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.getSecondaryPackageSpecificPaths;
 import static com.android.cts.externalstorageapp.CommonExternalStorageTest.readInt;
@@ -39,9 +36,7 @@
 
 import com.android.cts.externalstorageapp.CommonExternalStorageTest;
 
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
 import java.util.List;
 import java.util.Random;
 
@@ -93,6 +88,17 @@
         assertEquals(readInt(TEST_FILE), 32);
     }
 
+    public void testWriteExternalStorageDirs() throws Exception {
+        final File probe = new File(
+                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
+                "100CTS");
+
+        assertFalse(probe.exists());
+        assertTrue(probe.mkdirs());
+
+        assertDirReadWriteAccess(probe);
+    }
+
     /**
      * Verify that legacy filesystem paths continue working, and that they all
      * point to same location.
@@ -131,12 +137,12 @@
         for (File path : paths) {
             assertNotNull("Valid media must be inserted during CTS", path);
             assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
-                    Environment.getStorageState(path));
+                    Environment.getExternalStorageState(path));
 
             assertTrue(path.getAbsolutePath().contains(packageName));
 
             // Walk until we leave device, writing the whole way
-            while (Environment.MEDIA_MOUNTED.equals(Environment.getStorageState(path))) {
+            while (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState(path))) {
                 assertDirReadWriteAccess(path);
                 path = path.getParentFile();
             }
@@ -148,11 +154,10 @@
      * storage.
      */
     public void testPrimaryOtherPackageWriteAccess() throws Exception {
-        deleteContents(Environment.getExternalStorageDirectory());
-
         final File ourCache = getContext().getExternalCacheDir();
         final File otherCache = new File(ourCache.getAbsolutePath()
                 .replace(getContext().getPackageName(), PACKAGE_NONE));
+        deleteContents(otherCache);
 
         assertTrue(otherCache.mkdirs());
         assertDirReadWriteAccess(otherCache);
@@ -168,7 +173,7 @@
         int depth = 0;
         while (depth++ < 32) {
             assertDirReadWriteAccess(path);
-            assertEquals(Environment.MEDIA_MOUNTED, Environment.getStorageState(path));
+            assertEquals(Environment.MEDIA_MOUNTED, Environment.getExternalStorageState(path));
 
             if (path.getAbsolutePath().equals(top.getAbsolutePath())) {
                 break;
@@ -183,7 +188,7 @@
         // And going one step further should be outside our reach
         path = path.getParentFile();
         assertDirNoWriteAccess(path);
-        assertEquals(Environment.MEDIA_UNKNOWN, Environment.getStorageState(path));
+        assertEquals(Environment.MEDIA_UNKNOWN, Environment.getExternalStorageState(path));
     }
 
     /**
@@ -191,11 +196,11 @@
      */
     public void testMountStatus() {
         assertEquals(Environment.MEDIA_UNKNOWN,
-                Environment.getStorageState(new File("/meow-should-never-exist")));
+                Environment.getExternalStorageState(new File("/meow-should-never-exist")));
 
         // Internal data isn't a mount point
         assertEquals(Environment.MEDIA_UNKNOWN,
-                Environment.getStorageState(getContext().getCacheDir()));
+                Environment.getExternalStorageState(getContext().getCacheDir()));
     }
 
     /**
@@ -209,7 +214,7 @@
         for (File path : paths) {
             assertNotNull("Valid media must be inserted during CTS", path);
             assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
-                    Environment.getStorageState(path));
+                    Environment.getExternalStorageState(path));
 
             assertTrue(path.getAbsolutePath().contains(packageName));
 
@@ -220,7 +225,7 @@
             }
 
             // Keep walking up until we leave device
-            while (Environment.MEDIA_MOUNTED.equals(Environment.getStorageState(path))) {
+            while (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState(path))) {
                 assertDirReadOnlyAccess(path);
                 path = path.getParentFile();
             }
@@ -231,20 +236,21 @@
      * Verify that .nomedia is created correctly.
      */
     public void testVerifyNoMediaCreated() throws Exception {
-        deleteContents(Environment.getExternalStorageDirectory());
-
+        for (File file : getAllPackageSpecificPaths(getContext())) {
+            deleteContents(file);
+        }
         final List<File> paths = getAllPackageSpecificPaths(getContext());
 
         // Require that .nomedia was created somewhere above each dir
         for (File path : paths) {
             assertNotNull("Valid media must be inserted during CTS", path);
             assertEquals("Valid media must be inserted during CTS", Environment.MEDIA_MOUNTED,
-                    Environment.getStorageState(path));
+                    Environment.getExternalStorageState(path));
 
             final File start = path;
 
             boolean found = false;
-            while (Environment.MEDIA_MOUNTED.equals(Environment.getStorageState(path))) {
+            while (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState(path))) {
                 final File test = new File(path, ".nomedia");
                 if (test.exists()) {
                     found = true;
@@ -266,57 +272,29 @@
      * {@link CommonExternalStorageTest#testAllPackageDirsWritable()}.
      */
     public void testSecondaryMountPointsNotWritable() throws Exception {
+        // Probe path could be /storage/emulated/0 or /storage/1234-5678
         final File probe = buildProbeFile(Environment.getExternalStorageDirectory());
         assertTrue(probe.createNewFile());
 
-        final BufferedReader br = new BufferedReader(new FileReader("/proc/self/mounts"));
-        try {
-            String line;
-            while ((line = br.readLine()) != null) {
-                final String[] fields = line.split(" ");
-                final File testMount = new File(fields[1]);
-                final File testProbe = new File(testMount, probe.getName());
-                if (testProbe.exists()) {
-                    Log.d(TAG, "Primary external mountpoint " + testMount);
-                } else {
-                    // This mountpoint is not primary external storage; we must
-                    // not be able to write.
-                    Log.d(TAG, "Other mountpoint " + testMount);
-                    assertDirNoWriteAccess(testProbe.getParentFile());
-                }
+        final String userId = Integer.toString(android.os.Process.myUid() / 100000);
+        final List<File> mountPaths = getMountPaths();
+        for (File path : mountPaths) {
+            // Mount points could be multi-user aware, so try probing both top
+            // level and user-specific directory.
+            final File userPath = new File(path, userId);
+
+            final File testProbe = new File(path, probe.getName());
+            final File testUserProbe = new File(userPath, probe.getName());
+
+            if (testProbe.exists() || testUserProbe.exists()) {
+                Log.d(TAG, "Primary external mountpoint " + path);
+            } else {
+                // This mountpoint is not primary external storage; we must
+                // not be able to write.
+                Log.d(TAG, "Other mountpoint " + path);
+                assertDirNoWriteAccess(path);
+                assertDirNoWriteAccess(userPath);
             }
-       } finally {
-           br.close();
-           probe.delete();
-       }
-    }
-
-    /**
-     * Leave gifts for other packages in their primary external cache dirs.
-     */
-    public void doWriteGifts() throws Exception {
-        final File none = buildGiftForPackage(getContext(), PACKAGE_NONE);
-        none.getParentFile().mkdirs();
-        none.createNewFile();
-        assertFileReadWriteAccess(none);
-
-        writeInt(none, 100);
-        assertEquals(100, readInt(none));
-
-        final File read = buildGiftForPackage(getContext(), PACKAGE_READ);
-        read.getParentFile().mkdirs();
-        read.createNewFile();
-        assertFileReadWriteAccess(read);
-
-        writeInt(read, 101);
-        assertEquals(101, readInt(read));
-
-        final File write = buildGiftForPackage(getContext(), PACKAGE_WRITE);
-        write.getParentFile().mkdirs();
-        write.createNewFile();
-        assertFileReadWriteAccess(write);
-
-        writeInt(write, 102);
-        assertEquals(102, readInt(write));
+        }
     }
 }
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
new file mode 100644
index 0000000..5da42da
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/WriteGiftTest.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.cts.writeexternalstorageapp;
+
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.PACKAGE_NONE;
+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.readInt;
+import static com.android.cts.externalstorageapp.CommonExternalStorageTest.writeInt;
+
+import android.test.AndroidTestCase;
+
+import java.io.File;
+
+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);
+
+        writeInt(none, 100);
+        assertEquals(100, readInt(none));
+
+        final File read = buildGiftForPackage(getContext(), PACKAGE_READ);
+        read.getParentFile().mkdirs();
+        read.createNewFile();
+        assertFileReadWriteAccess(read);
+
+        writeInt(read, 101);
+        assertEquals(101, readInt(read));
+
+        final File write = buildGiftForPackage(getContext(), PACKAGE_WRITE);
+        write.getParentFile().mkdirs();
+        write.createNewFile();
+        assertFileReadWriteAccess(write);
+
+        writeInt(write, 102);
+        assertEquals(102, readInt(write));
+    }
+}
diff --git a/hostsidetests/appsecurity/test-apps/keysets/malBadKey/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/malBadKey/Android.mk
new file mode 100644
index 0000000..207160f
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/malBadKey/Android.mk
@@ -0,0 +1,27 @@
+# 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)
+
+#apks signed 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 := CtsKeySetSigningABadUpgradeB
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/malBadKey/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/keysets/malBadKey/AndroidManifest.xml
new file mode 100644
index 0000000..e18bde5
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/malBadKey/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?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.keysets">
+    <application android:hasCode="false">
+    </application>
+    <key-sets>
+        <key-set android:name="B" >
+          <public-key android:name="keyB"
+                      android:value="makebadpubkeyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoeFZqMqTbZiozFTXMkXtSKJRzn2qODZgvVXAAwKTi50xYcbPcHTfKxtif8+q7OCp/50JYDH32bg6wkUunn5+dEaHkxZY8d7uw46tQtl5dNGi+6cc4MezVLCS6nkqNDusAgdvgLU6Fl6SGi02KTp1vkt6CwLO977YJP7kt9ouDRTG7ASJiq3OyRRoOqYHhD9gpsbUq4w+1bXGfuuZujA1dXyovXtvrHUGOdFIEBYOVYGfCcwh3lXPmjNJMlHtKQkurq8/LH7a1B5ocoXCGsyR8YHdlWfrqRAfzgOB1KCnNNmWqskU9LOci3uQn9IDeMEFmAd8FqF8SwV+4Ludk/xWGQIDAQAB" />
+        </key-set>
+        <upgrade-key-set android:name="B"/>
+    </key-sets>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/keysets/malNoDef/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/malNoDef/Android.mk
new file mode 100644
index 0000000..84f3f75
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/malNoDef/Android.mk
@@ -0,0 +1,27 @@
+# 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)
+
+#apks signed 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 := CtsKeySetSigningANoDefUpgradeB
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/malNoDef/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/keysets/malNoDef/AndroidManifest.xml
new file mode 100644
index 0000000..aac717b
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/malNoDef/AndroidManifest.xml
@@ -0,0 +1,23 @@
+<?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.keysets">
+    <application android:hasCode="false">
+    </application>
+    <key-sets>
+        <upgrade-key-set android:name="B"/>
+    </key-sets>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/keysets/malOneDef/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/malOneDef/Android.mk
new file mode 100644
index 0000000..7290f06
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/malOneDef/Android.mk
@@ -0,0 +1,27 @@
+# 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)
+
+#apks signed 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 := CtsKeySetSigningCBadAUpgradeAB
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-c
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/malOneDef/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/keysets/malOneDef/AndroidManifest.xml
new file mode 100644
index 0000000..8242f6c
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/malOneDef/AndroidManifest.xml
@@ -0,0 +1,29 @@
+<?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.keysets">
+    <application android:hasCode="false">
+    </application>
+    <key-sets>
+        <key-set android:name="AB" >
+          <public-key android:name="keyA"
+                      android:value="makebadpubkeyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwf5zJblvYSB7Ym7or/7GggAAu7mp7RrykPJsXhod8doFhVT5s7eF3A4MCE55vvANP7HvwMw2b+T6qx7Pq0VJtbbSDtlBHBtIc47Pjq0CsDg590BUcgKp7PdJ9J6UVgtzDnV6cGEpXmSag3sY+lqiW04ytPhCVwzYTWGdYe9+TIl47cBrveRfLOlGrcuFQe+zCTmDFqzBKCRHK9b7l5PDWvXXyg65Uu/MBUA/TZWO0fEqOlxZG/nn6DUKQLhPdmJRXWJ3WqMNMhJGD+nKtkmdX703xRqmg4h+6g0S7M9Y3IQ2NUGyw05AYzCguHB/Mv6uVIiW659wpbyb45TgKG3UhQIDAQAB" />
+          <public-key android:name="keyB"
+                      android:value="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoeFZqMqTbZiozFTXMkXtSKJRzn2qODZgvVXAAwKTi50xYcbPcHTfKxtif8+q7OCp/50JYDH32bg6wkUunn5+dEaHkxZY8d7uw46tQtl5dNGi+6cc4MezVLCS6nkqNDusAgdvgLU6Fl6SGi02KTp1vkt6CwLO977YJP7kt9ouDRTG7ASJiq3OyRRoOqYHhD9gpsbUq4w+1bXGfuuZujA1dXyovXtvrHUGOdFIEBYOVYGfCcwh3lXPmjNJMlHtKQkurq8/LH7a1B5ocoXCGsyR8YHdlWfrqRAfzgOB1KCnNNmWqskU9LOci3uQn9IDeMEFmAd8FqF8SwV+4Ludk/xWGQIDAQAB" />
+        </key-set>
+        <upgrade-key-set android:name="AB"/>
+    </key-sets>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk
index 715905a..f5a7286 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/permDef/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed cts-keyset-test-b
 include $(CLEAR_VARS)
@@ -36,4 +36,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+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 eceea38..678d89d 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/permUse/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed cts-keyset-test-b
 include $(CLEAR_VARS)
@@ -36,4 +36,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+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 ed6db690..b8acc99 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/testApp/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/testApp/Android.mk
@@ -23,4 +23,4 @@
 LOCAL_PACKAGE_NAME := CtsKeySetTestApp
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
index efba345..79d053b 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uA/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed by cts-keyset-test-b
 include $(CLEAR_VARS)
@@ -35,7 +35,19 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+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
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed by cts-keyset-test-a and cts-keyset-test-b
 include $(CLEAR_VARS)
@@ -47,4 +59,4 @@
 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
-include $(BUILD_PACKAGE)
+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 219689e..406529c 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uAB/Android.mk
@@ -24,4 +24,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk
index 040c378..23d6b17 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uAuB/Android.mk
@@ -24,4 +24,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk
index 62b5461..f2cedf9 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uB/Android.mk
@@ -24,7 +24,7 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed cts-keyset-test-b
 include $(CLEAR_VARS)
@@ -36,7 +36,7 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 #apks signed by cts-keyset-test-a and cts-keyset-test-c
 include $(CLEAR_VARS)
@@ -49,4 +49,4 @@
 LOCAL_ADDITIONAL_CERTIFICATES := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-c
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+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
new file mode 100644
index 0000000..1d6d5a5
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/uBsharedUser/Android.mk
@@ -0,0 +1,39 @@
+# 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)
+
+#apks signed 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 := CtsKeySetSharedUserSigningAUpgradeB
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
+
+#apks signed cts-keyset-test-b
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+LOCAL_PACKAGE_NAME := CtsKeySetSharedUserSigningBUpgradeB
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-b
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uBsharedUser/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/keysets/uBsharedUser/AndroidManifest.xml
new file mode 100644
index 0000000..55a1c24
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/uBsharedUser/AndroidManifest.xml
@@ -0,0 +1,28 @@
+<?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.keysets"
+        android:sharedUserId="com.android.cts.keysets.shareduser">
+    <application android:hasCode="false">
+    </application>
+    <key-sets>
+        <key-set android:name="B" >
+          <public-key android:name="keyB"
+                      android:value="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoeFZqMqTbZiozFTXMkXtSKJRzn2qODZgvVXAAwKTi50xYcbPcHTfKxtif8+q7OCp/50JYDH32bg6wkUunn5+dEaHkxZY8d7uw46tQtl5dNGi+6cc4MezVLCS6nkqNDusAgdvgLU6Fl6SGi02KTp1vkt6CwLO977YJP7kt9ouDRTG7ASJiq3OyRRoOqYHhD9gpsbUq4w+1bXGfuuZujA1dXyovXtvrHUGOdFIEBYOVYGfCcwh3lXPmjNJMlHtKQkurq8/LH7a1B5ocoXCGsyR8YHdlWfrqRAfzgOB1KCnNNmWqskU9LOci3uQn9IDeMEFmAd8FqF8SwV+4Ludk/xWGQIDAQAB" />
+        </key-set>
+        <upgrade-key-set android:name="B"/>
+    </key-sets>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk
new file mode 100644
index 0000000..3d0109a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/uEcA/Android.mk
@@ -0,0 +1,27 @@
+# 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)
+
+#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 := CtsKeySetSigningAUpgradeEcA
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
+LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uEcA/AndroidManifest.xml b/hostsidetests/appsecurity/test-apps/keysets/uEcA/AndroidManifest.xml
new file mode 100644
index 0000000..a84704a
--- /dev/null
+++ b/hostsidetests/appsecurity/test-apps/keysets/uEcA/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?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.keysets">
+    <application android:hasCode="false">
+    </application>
+    <key-sets>
+        <key-set android:name="EcA" >
+          <public-key android:name="keyEcA"
+                      android:value="MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfEPu5YOCkjrNgXtF4RcJRQrIggiId4l9renxPlfzA/kAU9duuYSMgShB/6ALE6S8vBXRiiwtMfk8LgnnbotEgQ=="/>
+        </key-set>
+        <upgrade-key-set android:name="EcA"/>
+    </key-sets>
+</manifest>
diff --git a/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk b/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk
index 5fc4ab9..9b327fe 100644
--- a/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk
+++ b/hostsidetests/appsecurity/test-apps/keysets/uNone/Android.mk
@@ -24,4 +24,4 @@
 LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/keysets/cts-keyset-test-a
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/atrace/Android.mk b/hostsidetests/atrace/Android.mk
new file mode 100644
index 0000000..1fd7102
--- /dev/null
+++ b/hostsidetests/atrace/Android.mk
@@ -0,0 +1,30 @@
+# 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)
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_MODULE := CtsAtraceHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.host.atrace
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/atrace/AtraceTestApp/Android.mk b/hostsidetests/atrace/AtraceTestApp/Android.mk
new file mode 100644
index 0000000..0eb7cfd
--- /dev/null
+++ b/hostsidetests/atrace/AtraceTestApp/Android.mk
@@ -0,0 +1,33 @@
+# 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+LOCAL_PACKAGE_NAME := CtsAtraceTestApp
+
+# sign this app with a different cert than CtsSimpleAppInstallDiffCert
+#LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey1
+
+#LOCAL_DEX_PREOPT := false
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/atrace/AtraceTestApp/AndroidManifest.xml b/hostsidetests/atrace/AtraceTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..c460300
--- /dev/null
+++ b/hostsidetests/atrace/AtraceTestApp/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.cts.atracetestapp">
+    <!--
+    A simple app with a tracing section to test that apps tracing signals are
+    emitted by atrace.
+    -->
+    <application android:debuggable="true"> <!-- Debuggable to enable tracing -->
+        <activity android:name=".AtraceTestAppActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/hostsidetests/atrace/AtraceTestApp/src/com/android/cts/atracetestapp/AtraceTestAppActivity.java b/hostsidetests/atrace/AtraceTestApp/src/com/android/cts/atracetestapp/AtraceTestAppActivity.java
new file mode 100644
index 0000000..0269d0d
--- /dev/null
+++ b/hostsidetests/atrace/AtraceTestApp/src/com/android/cts/atracetestapp/AtraceTestAppActivity.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.cts.atracetestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Trace;
+
+public class AtraceTestAppActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        Trace.beginSection("traceable-app-test-section");
+        super.onCreate(savedInstanceState);
+        Trace.endSection();
+    }
+}
diff --git a/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java b/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java
new file mode 100644
index 0000000..760723e
--- /dev/null
+++ b/hostsidetests/atrace/src/android/atrace/cts/AtraceHostTest.java
@@ -0,0 +1,299 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.atrace.cts;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+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.IBuildReceiver;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Test to check that atrace is usable, to enable usage of systrace.
+ */
+public class AtraceHostTest extends DeviceTestCase implements IBuildReceiver {
+    private static final String TEST_APK = "CtsAtraceTestApp.apk";
+    private static final String TEST_PKG = "com.android.cts.atracetestapp";
+
+    private interface FtraceEntryCallback {
+        void onTraceEntry(String threadName, int pid, int tid, String eventType, String args);
+        void onFinished();
+    }
+
+    /**
+     * Helper for parsing ftrace data.
+     * Regexs copied from (and should be kept in sync with) ftrace importer in catapult.
+     */
+    private static class FtraceParser {
+        // Matches the trace record in 3.2 and later with the print-tgid option:
+        //          <idle>-0    0 [001] d...  1.23: sched_switch
+        private static final Pattern sLineWithTgid = Pattern.compile(
+                "^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]"
+                + "\\s+[dX.][N.][Hhs.][0-9a-f.]"
+                + "\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)");
+
+        // Matches the default trace record in 3.2 and later (includes irq-info):
+        //          <idle>-0     [001] d...  1.23: sched_switch
+        private static final Pattern sLineWithIrqInfo = Pattern.compile(
+                "^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]"
+                + "\\s+[dX.][N.][Hhs.][0-9a-f.]"
+                + "\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$");
+
+        // Matches the default trace record pre-3.2:
+        //          <idle>-0     [001]  1.23: sched_switch
+        private static final Pattern sLineLegacy = Pattern.compile(
+                "^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]\\s*(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)");
+        private static void parseLine(String line, FtraceEntryCallback callback) {
+            Matcher m = sLineWithTgid.matcher(line);
+            if (m.matches()) {
+                callback.onTraceEntry(
+                        /*threadname*/ m.group(1),
+                        /*pid*/ m.group(3).startsWith("-") ? -1 : Integer.parseInt(m.group(3)),
+                        /*tid*/ Integer.parseInt(m.group(2)),
+                        /*eventName*/ m.group(6),
+                        /*details*/ m.group(7));
+                return;
+            }
+
+            m = sLineWithIrqInfo.matcher(line);
+            if (m.matches()) {
+                callback.onTraceEntry(
+                        /*threadname*/ m.group(1),
+                        /*pid*/ -1,
+                        /*tid*/ Integer.parseInt(m.group(2)),
+                        /*eventName*/ m.group(5),
+                        /*details*/ m.group(6));
+                return;
+            }
+
+            m = sLineLegacy.matcher(line);
+            if (m.matches()) {
+                callback.onTraceEntry(
+                        /*threadname*/ m.group(1),
+                        /*pid*/ -1,
+                        /*tid*/ Integer.parseInt(m.group(2)),
+                        /*eventName*/ m.group(5),
+                        /*details*/ m.group(6));
+                return;
+            }
+            System.err.println("line doesn't match: " + line);
+        }
+
+        private static void parse(Reader reader, FtraceEntryCallback callback) throws Exception {
+            try {
+                BufferedReader bufferedReader = new BufferedReader(reader);
+                String line;
+                while ((line = bufferedReader.readLine()) != null) {
+                    FtraceParser.parseLine(line, callback);
+                }
+            } finally {
+                callback.onFinished();
+            }
+        }
+    }
+
+    private CtsBuildHelper mCtsBuild;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    // Collection of all userspace tags, and 'sched'
+    private static final List<String> sRequiredCategoriesList = Arrays.asList(
+            "sched",
+            "gfx",
+            "input",
+            "view",
+            "webview",
+            "wm",
+            "am",
+            "sm",
+            "audio",
+            "video",
+            "camera",
+            "hal",
+            "app",
+            "res",
+            "dalvik",
+            "rs",
+            "bionic",
+            "power"
+    );
+
+    /**
+     * Tests that atrace exists and is runnable with no args
+     */
+    public void testSimpleRun() throws Exception {
+        String output = getDevice().executeShellCommand("atrace");
+        String[] lines = output.split("\\r?\\n");
+
+        // check for expected stdout
+        assertEquals("capturing trace... done", lines[0]);
+        assertEquals("TRACE:", lines[1]);
+
+        // commented trace marker starts here
+        assertEquals("# tracer: nop", lines[2]);
+    }
+
+    /**
+     * Tests the output of "atrace --list_categories" to ensure required categories exist.
+     */
+    public void testCategories() throws Exception {
+        String output = getDevice().executeShellCommand("atrace --list_categories");
+        String[] categories = output.split("\\r?\\n");
+
+        Set<String> requiredCategories = new HashSet<String>(sRequiredCategoriesList);
+
+        for (String category : categories) {
+            int dashIndex = category.indexOf("-");
+
+            assertTrue(dashIndex > 1); // must match category output format
+            category = category.substring(0, dashIndex).trim();
+
+            requiredCategories.remove(category);
+        }
+
+        if (!requiredCategories.isEmpty()) {
+            for (String missingCategory : requiredCategories) {
+                System.err.println("missing category: " + missingCategory);
+            }
+            fail("Expected categories missing from atrace");
+        }
+    }
+
+    /**
+     * Tests that atrace captures app launch, including app level tracing
+     */
+    public void testTracingContent() throws Exception {
+        String atraceOutput = null;
+        try {
+            // cleanup test apps that might be installed from previous partial test run
+            getDevice().uninstallPackage(TEST_PKG);
+
+            // install the test app
+            File testAppFile = mCtsBuild.getTestApp(TEST_APK);
+            String installResult = getDevice().installPackage(testAppFile, false);
+            assertNull(
+                    String.format("failed to install atrace test app. Reason: %s", installResult),
+                    installResult);
+
+            // capture a launch of the app with async tracing
+            // content traced by 'view' tag tested below, 'sched' used to ensure tgid printed
+            String atraceArgs = "-a " + TEST_PKG + " -c -b 16000 view"; // TODO: zipping
+            getDevice().executeShellCommand("atrace --async_stop " + atraceArgs);
+            getDevice().executeShellCommand("atrace --async_start " + atraceArgs);
+            getDevice().executeShellCommand("am start " + TEST_PKG);
+            getDevice().executeShellCommand("sleep 1");
+            atraceOutput = getDevice().executeShellCommand("atrace --async_stop " + atraceArgs);
+        } finally {
+            assertNotNull("unable to capture atrace output", atraceOutput);
+            getDevice().uninstallPackage(TEST_PKG);
+        }
+
+
+        // now parse the trace data (see external/chromium-trace/systrace.py)
+        final String MARKER = "TRACE:";
+        int dataStart = atraceOutput.indexOf(MARKER);
+        assertTrue(dataStart >= 0);
+        String traceData = atraceOutput.substring(dataStart + MARKER.length());
+
+        FtraceEntryCallback callback = new FtraceEntryCallback() {
+            private int userSpaceMatches = 0;
+            private int beginMatches = 0;
+            private int nextSectionIndex = -1;
+            private int appTid = -1;
+
+
+            private final String initialSection = "traceable-app-test-section";
+            // list of tags expected to be seen on app launch, in order, after the initial.
+            private final String[] requiredSectionList = {
+                    "inflate",
+                    "Choreographer#doFrame",
+                    "traversal",
+                    "measure",
+                    "layout",
+                    "draw",
+                    "Record View#draw()"
+            };
+
+            @Override
+            public void onTraceEntry(String truncatedThreadName, int pid, int tid,
+                    String eventName, String details) {
+                if (!"tracing_mark_write".equals(eventName)) {
+                    // not userspace trace, ignore
+                    return;
+                }
+
+                assertNotNull(truncatedThreadName);
+                assertTrue(tid > 0);
+                userSpaceMatches++;
+
+                if (details == null || !details.startsWith("B|")) {
+                    // not a begin event
+                    return;
+                }
+                beginMatches++;
+
+                if (details.endsWith("|" + initialSection)) {
+                    // initial section observed, start looking for others in order
+                    assertEquals(nextSectionIndex, -1);
+                    nextSectionIndex = 0;
+                    appTid = tid;
+                    return;
+                }
+
+                if (nextSectionIndex >= 0
+                        && tid == appTid
+                        && nextSectionIndex < requiredSectionList.length
+                        && details.endsWith("|" + requiredSectionList[nextSectionIndex])) {
+                    // found next required section in sequence
+                    nextSectionIndex++;
+                }
+            }
+
+            @Override
+            public void onFinished() {
+                assertTrue("Unable to parse any userspace sections from atrace output",
+                        userSpaceMatches != 0);
+                assertTrue("Unable to parse any section begin events from atrace output",
+                        beginMatches != 0);
+                assertTrue("Unable to parse initial userspace sections from test app",
+                        nextSectionIndex >= 0);
+                assertEquals("Didn't see required list of traced sections, in order",
+                        requiredSectionList.length, nextSectionIndex);
+            }
+        };
+
+        FtraceParser.parse(new StringReader(traceData), callback);
+    }
+}
diff --git a/hostsidetests/devicepolicy/Android.mk b/hostsidetests/devicepolicy/Android.mk
index 6708c3d..dc5e117 100644
--- a/hostsidetests/devicepolicy/Android.mk
+++ b/hostsidetests/devicepolicy/Android.mk
@@ -26,6 +26,8 @@
 
 LOCAL_CTS_TEST_PACKAGE := android.adminhostside
 
+cts_runtime_hint := 70
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 # Build the test APKs using their own makefiles
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/Android.mk b/hostsidetests/devicepolicy/app/CertInstaller/Android.mk
new file mode 100644
index 0000000..22a78e2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CertInstaller/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_PACKAGE_NAME := CtsCertInstallerApp
+
+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
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml b/hostsidetests/devicepolicy/app/CertInstaller/AndroidManifest.xml
new file mode 100644
index 0000000..c50e5fd
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CertInstaller/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="com.android.cts.certinstaller">
+
+    <uses-sdk android:minSdkVersion="22"/>
+
+    <application>
+        <activity android:name="CertInstallerActivity">
+            <intent-filter>
+                <action android:name="com.android.cts.certinstaller.install_cert" />
+                <action android:name="com.android.cts.certinstaller.remove_cert" />
+                <action android:name="com.android.cts.certinstaller.verify_cert" />
+                <action android:name="com.android.cts.certinstaller.install_keypair" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/CertInstallerActivity.java b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/CertInstallerActivity.java
new file mode 100644
index 0000000..b14822b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/CertInstaller/src/com/android/cts/certinstaller/CertInstallerActivity.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.certinstaller;
+
+import android.app.Activity;
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Base64;
+import android.util.Base64InputStream;
+import android.util.Log;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.util.List;
+
+/**
+ * Delegated certificate installer app that responds to specific intents and executes various DPM
+ * certificate manipulation APIs. The following APIs are exercised:
+ * {@link DevicePolicyManager#installCaCert},
+ * {@link DevicePolicyManager#uninstallCaCert},
+ * {@link DevicePolicyManager#hasCaCertInstalled},
+ * {@link DevicePolicyManager#getInstalledCaCerts},
+ * {@link DevicePolicyManager#installKeyPair}.
+ */
+public class CertInstallerActivity extends Activity {
+
+    private static final String TAG = "DelegatedCertInstaller";
+    // exercises {@link DevicePolicyManager#installCaCert} and
+    // {@link DevicePolicyManager#hasCaCertInstalled},
+    private static final String ACTION_INSTALL_CERT = "com.android.cts.certinstaller.install_cert";
+    // exercises {@link DevicePolicyManager#uninstallCaCert} and
+    // {@link DevicePolicyManager#hasCaCertInstalled},
+    private static final String ACTION_REMOVE_CERT = "com.android.cts.certinstaller.remove_cert";
+    // exercises {@link DevicePolicyManager#getInstalledCaCerts},
+    private static final String ACTION_VERIFY_CERT = "com.android.cts.certinstaller.verify_cert";
+    // exercises {@link DevicePolicyManager#installKeyPair},
+    private static final String ACTION_INSTALL_KEYPAIR =
+            "com.android.cts.certinstaller.install_keypair";
+
+    private static final String ACTION_CERT_OPERATION_DONE = "com.android.cts.certinstaller.done";
+
+    private static final String EXTRA_CERT_DATA = "extra_cert_data";
+    private static final String EXTRA_KEY_DATA = "extra_key_data";
+    private static final String EXTRA_KEY_ALIAS = "extra_key_alias";
+    private static final String EXTRA_RESULT_VALUE = "extra_result_value";
+    private static final String EXTRA_RESULT_EXCEPTION = "extra_result_exception";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = getIntent();
+        if (intent == null) {
+            finish();
+            return;
+        }
+
+        String action = intent.getAction();
+        DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(
+                Context.DEVICE_POLICY_SERVICE);
+
+        byte[] certBuffer;
+
+        if (ACTION_INSTALL_CERT.equals(action)) {
+            try {
+                certBuffer = intent.getByteArrayExtra(EXTRA_CERT_DATA);
+                // Verify cert is not currently installed.
+                if (dpm.hasCaCertInstalled(null, certBuffer)) {
+                    throw new RuntimeException("Cert already on device?");
+                }
+                if (!dpm.installCaCert(null, certBuffer)) {
+                    throw new RuntimeException("installCaCert returned false.");
+                }
+                if (!dpm.hasCaCertInstalled(null, certBuffer)) {
+                    throw new RuntimeException("Cannot find cert after installation.");
+                }
+                sendResult(true, null);
+            } catch (Exception e) {
+                Log.e(TAG, "Exception raised duing ACTION_INSTALL_CERT", e);
+                sendResult(false, e);
+            }
+        } else if (ACTION_REMOVE_CERT.equals(action)) {
+            try {
+                certBuffer = intent.getByteArrayExtra(EXTRA_CERT_DATA);
+                if (!dpm.hasCaCertInstalled(null, certBuffer)) {
+                    throw new RuntimeException("Trying to uninstall a non-existent cert.");
+                }
+                dpm.uninstallCaCert(null, certBuffer);
+                sendResult(!dpm.hasCaCertInstalled(null, certBuffer), null);
+            } catch (Exception e) {
+                Log.e(TAG, "Exception raised duing ACTION_REMOVE_CERT", e);
+                sendResult(false, e);
+            }
+        } else if (ACTION_VERIFY_CERT.equals(action)) {
+            try {
+                certBuffer = intent.getByteArrayExtra(EXTRA_CERT_DATA);
+                sendResult(containsCertificate(dpm.getInstalledCaCerts(null), certBuffer), null);
+            } catch (Exception e) {
+                Log.e(TAG, "Exception raised duing ACTION_VERIFY_CERT", e);
+                sendResult(false, e);
+            }
+        } else if (ACTION_INSTALL_KEYPAIR.equals(action)) {
+            String alias = intent.getStringExtra(EXTRA_KEY_ALIAS);
+            String key = intent.getStringExtra(EXTRA_KEY_DATA);
+            String cert = intent.getStringExtra(EXTRA_CERT_DATA);
+            try {
+                PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(
+                        Base64.decode(key, Base64.DEFAULT));
+                KeyFactory kf = KeyFactory.getInstance("RSA");
+                PrivateKey privatekey = kf.generatePrivate(keySpec);
+
+                Certificate certificate = CertificateFactory.getInstance("X.509")
+                        .generateCertificate(
+                                new Base64InputStream(new ByteArrayInputStream(cert.getBytes()),
+                                        Base64.DEFAULT));
+                // Unfortunately there is no programmatically way to check if the given private key
+                // is indeed in the key store as a unprivileged app. So we just rely on
+                // installKeyPair() returning true as the success criteria of this test. Separate
+                // CTS keychain tests will make sure the API's behaviour is correct.
+                // Note: installKeyPair() will silently return false if there is no lockscreen
+                // password, however the test setup should have set one already.
+                sendResult(dpm.installKeyPair(null, privatekey, certificate,  alias), null);
+            } catch (Exception e) {
+                Log.e(TAG, "Exception raised duing ACTION_INSTALL_KEYPAIR", e);
+                sendResult(false, e);
+            }
+        }
+        finish();
+    }
+
+    private void sendResult(boolean succeed, Exception e) {
+        Intent intent = new Intent();
+        intent.setAction(ACTION_CERT_OPERATION_DONE);
+        intent.putExtra(EXTRA_RESULT_VALUE, succeed);
+        if (e != null) {
+            intent.putExtra(EXTRA_RESULT_EXCEPTION, e);
+        }
+        sendBroadcast(intent);
+    }
+
+    private boolean containsCertificate(List<byte[]> certificates, byte[] toMatch)
+            throws CertificateException {
+        Certificate certificateToMatch = readCertificate(toMatch);
+        for (byte[] certBuffer : certificates) {
+            Certificate cert = readCertificate(certBuffer);
+            if (certificateToMatch.equals(cert)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private Certificate readCertificate(byte[] certBuffer) throws CertificateException {
+        final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
+        return certFactory.generateCertificate(new ByteArrayInputStream(certBuffer));
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk
new file mode 100644
index 0000000..0548af6
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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_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)
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml
new file mode 100644
index 0000000..fe07bcb
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/AndroidManifest.xml
@@ -0,0 +1,86 @@
+<?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/res/values/strings.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/values/strings.xml
new file mode 100644
index 0000000..4aca824
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/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">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
new file mode 100644
index 0000000..0d8ecd8
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/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.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
new file mode 100644
index 0000000..69a661c
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/device_admin.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.
+-->
+<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/DeviceAndProfileOwner/res/xml/primary_device_admin.xml b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/primary_device_admin.xml
new file mode 100644
index 0000000..a6aff49
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/res/xml/primary_device_admin.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.
+-->
+<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
new file mode 100644
index 0000000..d93c8f2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountManagementTest.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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
new file mode 100644
index 0000000..7a9e5ad
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/AccountUtilsTest.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.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/ApplicationHiddenTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationHiddenTest.java
new file mode 100644
index 0000000..d8be42f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationHiddenTest.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.cts.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.Uri;
+import android.util.Log;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for {@link DevicePolicyManager#setApplicationHidden} and
+ * {@link DevicePolicyManager#isApplicationHidden} APIs.
+ */
+public class ApplicationHiddenTest extends BaseDeviceAdminTest {
+
+    private static final String TAG = "ApplicationHiddenTest";
+
+    private static final String PACKAGE_TO_HIDE = "com.android.cts.permissionapp";
+    private static final String NONEXISTING_PACKAGE_NAME = "a.b.c.d";
+
+    private static final IntentFilter PACKAGE_INTENT_FILTER;
+    static {
+        PACKAGE_INTENT_FILTER = new IntentFilter();
+        PACKAGE_INTENT_FILTER.addAction(Intent.ACTION_PACKAGE_ADDED);
+        PACKAGE_INTENT_FILTER.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        PACKAGE_INTENT_FILTER.addDataScheme("package");
+    }
+    private final ApplicationHiddenReceiver mReceiver = new ApplicationHiddenReceiver();
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext.registerReceiver(mReceiver, PACKAGE_INTENT_FILTER);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mContext.unregisterReceiver(mReceiver);
+        mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT, PACKAGE_TO_HIDE, false);
+        super.tearDown();
+    }
+
+    public void testSetApplicationHidden() throws Exception {
+        assertTrue(mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT,
+                PACKAGE_TO_HIDE, true));
+        assertTrue(mDevicePolicyManager.isApplicationHidden(ADMIN_RECEIVER_COMPONENT,
+                PACKAGE_TO_HIDE));
+        mReceiver.waitForRemovedBroadcast();
+        assertTrue(mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT,
+                PACKAGE_TO_HIDE, false));
+        assertFalse(mDevicePolicyManager.isApplicationHidden(ADMIN_RECEIVER_COMPONENT,
+                PACKAGE_TO_HIDE));
+        mReceiver.waitForAddedBroadcast();
+    }
+
+    public void testCannotHideActiveAdmin() throws Exception {
+        assertFalse(mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT,
+                PACKAGE_NAME, true));
+    }
+
+    public void testCannotHideNonExistingPackage() throws Exception {
+        assertFalse(mDevicePolicyManager.setApplicationHidden(ADMIN_RECEIVER_COMPONENT,
+                NONEXISTING_PACKAGE_NAME, true));
+    }
+
+    private class ApplicationHiddenReceiver extends BroadcastReceiver {
+        private final Semaphore mAddedSemaphore = new Semaphore(0);
+        private final Semaphore mRemovedSemaphore = new Semaphore(0);
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Uri uri = intent.getData();
+            if (uri == null) {
+                return;
+            }
+            String pkgName = uri.getSchemeSpecificPart();
+            if (!PACKAGE_TO_HIDE.equals(pkgName)) {
+                return;
+            }
+            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
+                Log.d(TAG, "Received PACKAGE_ADDED broadcast");
+                mAddedSemaphore.release();
+            } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+                Log.d(TAG, "Received PACKAGE_REMOVED broadcast");
+                mRemovedSemaphore.release();
+            }
+        }
+
+        public void waitForAddedBroadcast() throws Exception {
+            if (!mAddedSemaphore.tryAcquire(60, TimeUnit.SECONDS)) {
+                fail("Did not receive PACKAGE_ADDED broadcast.");
+            }
+        }
+
+        public void waitForRemovedBroadcast() throws Exception {
+            if (!mRemovedSemaphore.tryAcquire(60, TimeUnit.SECONDS)) {
+                fail("Did not receive PACKAGE_REMOVED broadcast.");
+            }
+        }
+    }
+}
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
new file mode 100644
index 0000000..ccf8222
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationRestrictionsActivity.java
@@ -0,0 +1,93 @@
+/*
+ * 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
new file mode 100644
index 0000000..98ae202
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ApplicationRestrictionsTest.java
@@ -0,0 +1,241 @@
+/*
+ * 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.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Parcelable;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Functionality tests for setApplicationRestrictions and getApplicationRestrictions
+ * in DevicePolicyManager.
+ *
+ * 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.
+ */
+public class ApplicationRestrictionsTest extends BaseDeviceAdminTest {
+
+    private static final String[] testStrings = 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 Bundle mReceivedRestrictions;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ApplicationRestrictionsActivity.REGISTERED_ACTION);
+        filter.addAction(ApplicationRestrictionsActivity.RESTRICTION_ACTION);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mContext.unregisterReceiver(mReceiver);
+        super.tearDown();
+    }
+
+    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);
+
+        // 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));
+
+        // The test activity should have received a change_restriction broadcast
+        // and relay the value back to us.
+        assertBundle0(waitForChangedRestriction());
+
+        // Test overwriting
+        mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE,
+                bundle1);
+        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(ADMIN_RECEIVER_COMPONENT,
+                CTS_PACKAGE));
+        assertBundle1(waitForChangedRestriction());
+
+        // Cleanup
+        mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE,
+                new Bundle());
+        assertTrue(mDevicePolicyManager.getApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, CTS_PACKAGE).isEmpty());
+        assertTrue(waitForChangedRestriction().isEmpty());
+        mDevicePolicyManager.setApplicationRestrictions(ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE,
+                new Bundle());
+        assertTrue(mDevicePolicyManager.getApplicationRestrictions(
+                ADMIN_RECEIVER_COMPONENT, OTHER_PACKAGE).isEmpty());
+
+        finish();
+    }
+
+    // Should be consistent with assertBundle0
+    private Bundle createBundle0() {
+        Bundle result = new Bundle();
+        // Tests for 6 allowed types: Integer, Boolean, String, String[], Bundle and Parcelable[]
+        // Also test for string escaping handling
+        result.putBoolean("boolean_0", false);
+        result.putBoolean("boolean_1", true);
+        result.putInt("integer", 0x7fffffff);
+        // If a null is stored, "" will be read back
+        result.putString("empty", "");
+        result.putString("string", "text");
+        result.putStringArray("string[]", testStrings);
+
+        // Adding a bundle, which contain 2 nested restrictions - bundle_string and bundle_int
+        Bundle bundle = new Bundle();
+        bundle.putString("bundle_string", "bundle_string");
+        bundle.putInt("bundle_int", 1);
+        result.putBundle("bundle", bundle);
+
+        // Adding an array of 2 bundles
+        Bundle[] bundleArray = new Bundle[2];
+        bundleArray[0] = new Bundle();
+        bundleArray[0].putString("bundle_array_string", "bundle_array_string");
+        // Put bundle inside bundle
+        bundleArray[0].putBundle("bundle_array_bundle", bundle);
+        bundleArray[1] = new Bundle();
+        bundleArray[1].putString("bundle_array_string2", "bundle_array_string2");
+        result.putParcelableArray("bundle_array", bundleArray);
+        return result;
+    }
+
+    // Should be consistent with createBundle0
+    private void assertBundle0(Bundle bundle) {
+        assertEquals(8, bundle.size());
+        assertEquals(false, bundle.getBoolean("boolean_0"));
+        assertEquals(true, bundle.getBoolean("boolean_1"));
+        assertEquals(0x7fffffff, bundle.getInt("integer"));
+        assertEquals("", bundle.getString("empty"));
+        assertEquals("text", bundle.getString("string"));
+
+        String[] strings = bundle.getStringArray("string[]");
+        assertTrue(strings != null && strings.length == testStrings.length);
+        for (int i = 0; i < strings.length; i++) {
+            assertEquals(strings[i], testStrings[i]);
+        }
+
+        Bundle childBundle = bundle.getBundle("bundle");
+        assertEquals("bundle_string", childBundle.getString("bundle_string"));
+        assertEquals(1, childBundle.getInt("bundle_int"));
+
+        Parcelable[] bundleArray = bundle.getParcelableArray("bundle_array");
+        assertEquals(2, bundleArray.length);
+        // Verifying bundle_array[0]
+        Bundle bundle1 = (Bundle) bundleArray[0];
+        assertEquals("bundle_array_string", bundle1.getString("bundle_array_string"));
+        Bundle bundle1ChildBundle = bundle1.getBundle("bundle_array_bundle");
+        assertNotNull(bundle1ChildBundle);
+        assertEquals("bundle_string", bundle1ChildBundle.getString("bundle_string"));
+        assertEquals(1, bundle1ChildBundle.getInt("bundle_int"));
+        // Verifying bundle_array[1]
+        Bundle bundle2 = (Bundle) bundleArray[1];
+        assertEquals("bundle_array_string2", bundle2.getString("bundle_array_string2"));
+    }
+
+    // Should be consistent with assertBundle1
+    private Bundle createBundle1() {
+        Bundle result = new Bundle();
+        result.putInt("dummy", 1);
+        return result;
+    }
+
+    // Should be consistent with createBundle1
+    private void assertBundle1(Bundle bundle) {
+        assertEquals(1, bundle.size());
+        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 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 waitForChangedRestriction() {
+        try {
+            assertTrue(mOnRestrictionSemaphore.tryAcquire(5, TimeUnit.SECONDS));
+        } catch (InterruptedException e) {
+            fail("getRestrictionsAndWait() interrupted");
+        }
+
+        return mReceivedRestrictions;
+    }
+
+    private void finish() {
+        startTestActivity(ApplicationRestrictionsActivity.FINISH);
+    }
+
+}
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
new file mode 100644
index 0000000..148d8a8
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/BaseDeviceAdminTest.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.cts.deviceandprofileowner;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Base class for profile and device based tests.
+ *
+ * This class handles making sure that the test is the profile or device owner and that it has an
+ * active admin registered, so that all tests may assume these are done.
+ */
+public class BaseDeviceAdminTest extends InstrumentationTestCase {
+
+    public static class BasicAdminReceiver extends DeviceAdminReceiver {
+    }
+
+    public static final String PACKAGE_NAME = BasicAdminReceiver.class.getPackage().getName();
+    public static final ComponentName ADMIN_RECEIVER_COMPONENT = new ComponentName(
+            PACKAGE_NAME, BasicAdminReceiver.class.getName());
+
+    protected DevicePolicyManager mDevicePolicyManager;
+    protected Context mContext;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+
+        mDevicePolicyManager = (DevicePolicyManager)
+            mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        assertNotNull(mDevicePolicyManager);
+
+        assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
+        assertTrue("App is neither device nor profile owner",
+                mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME) ||
+                mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME));
+    }
+}
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
new file mode 100644
index 0000000..2fe0569
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ClearDeviceOwnerTest.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.cts.deviceandprofileowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.AndroidTestCase;
+
+public class ClearDeviceOwnerTest extends AndroidTestCase {
+
+    private DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void tearDown() throws Exception {
+        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));
+        }
+
+        super.tearDown();
+    }
+
+    // This test clears the device owner and active admin on tearDown(). To be called from the host
+    // 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/DelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
new file mode 100644
index 0000000..3eb8c35
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.KeyguardManager;
+import android.app.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.security.KeyChain;
+import android.security.KeyChainException;
+import android.test.AndroidTestCase;
+import android.util.Base64;
+import android.util.Base64InputStream;
+
+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;
+
+/**
+ * Exercise delegated cert installer APIs in {@link DevicePolicyManager} by setting the test app
+ * (CtsCertInstallerApp) as a delegated cert installer and then asking it to invoke various
+ * cert-related APIs. The expected certificate changes are validated both remotely and locally.
+ */
+public class DelegatedCertInstallerTest extends BaseDeviceAdminTest {
+
+    private static final String CERT_INSTALLER_PACKAGE = "com.android.cts.certinstaller";
+
+    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";
+    private static final String ACTION_VERIFY_CERT = "com.android.cts.certinstaller.verify_cert";
+    private static final String ACTION_INSTALL_KEYPAIR =
+            "com.android.cts.certinstaller.install_keypair";
+    private static final String ACTION_CERT_OPERATION_DONE = "com.android.cts.certinstaller.done";
+
+    private static final String EXTRA_CERT_DATA = "extra_cert_data";
+    private static final String EXTRA_KEY_DATA = "extra_key_data";
+    private static final String EXTRA_KEY_ALIAS = "extra_key_alias";
+    private static final String EXTRA_RESULT_VALUE = "extra_result_value";
+    private static final String EXTRA_RESULT_EXCEPTION = "extra_result_exception";
+
+    /*
+     * The CA and keypair below are generated with:
+     *
+     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
+     * openssl req -newkey rsa:1024 -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
+     */
+
+     // Content from cacert.pem
+    private static final String TEST_CA =
+            "-----BEGIN CERTIFICATE-----\n" +
+            "MIIDXTCCAkWgAwIBAgIJAK9Tl/F9V8kSMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n" +
+            "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n" +
+            "aWRnaXRzIFB0eSBMdGQwHhcNMTUwMzA2MTczMjExWhcNMjUwMzAzMTczMjExWjBF\n" +
+            "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n" +
+            "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" +
+            "CgKCAQEAvItOutsE75WBTgTyNAHt4JXQ3JoseaGqcC3WQij6vhrleWi5KJ0jh1/M\n" +
+            "Rpry7Fajtwwb4t8VZa0NuM2h2YALv52w1xivql88zce/HU1y7XzbXhxis9o6SCI+\n" +
+            "oVQSbPeXRgBPppFzBEh3ZqYTVhAqw451XhwdA4Aqs3wts7ddjwlUzyMdU44osCUg\n" +
+            "kVg7lfPf9sTm5IoHVcfLSCWH5n6Nr9sH3o2ksyTwxuOAvsN11F/a0mmUoPciYPp+\n" +
+            "q7DzQzdi7akRG601DZ4YVOwo6UITGvDyuAAdxl5isovUXqe6Jmz2/myTSpAKxGFs\n" +
+            "jk9oRoG6WXWB1kni490GIPjJ1OceyQIDAQABo1AwTjAdBgNVHQ4EFgQUH1QIlPKL\n" +
+            "p2OQ/AoLOjKvBW4zK3AwHwYDVR0jBBgwFoAUH1QIlPKLp2OQ/AoLOjKvBW4zK3Aw\n" +
+            "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcMi4voMMJHeQLjtq8Oky\n" +
+            "Azpyk8moDwgCd4llcGj7izOkIIFqq/lyqKdtykVKUWz2bSHO5cLrtaOCiBWVlaCV\n" +
+            "DYAnnVLM8aqaA6hJDIfaGs4zmwz0dY8hVMFCuCBiLWuPfiYtbEmjHGSmpQTG6Qxn\n" +
+            "ZJlaK5CZyt5pgh5EdNdvQmDEbKGmu0wpCq9qjZImwdyAul1t/B0DrsWApZMgZpeI\n" +
+            "d2od0VBrCICB1K4p+C51D93xyQiva7xQcCne+TAnGNy9+gjQ/MyR8MRpwRLv5ikD\n" +
+            "u0anJCN8pXo6IMglfMAsoton1J6o5/ae5uhC6caQU8bNUsCK570gpNfjkzo6rbP0\n" +
+            "wQ==\n" +
+            "-----END CERTIFICATE-----";
+    // Content from userkey.pem without the private key header and footer.
+    private static final String TEST_KEY =
+            "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALCYprGsTU+5L3KM\n" +
+            "fhkm0gXM2xjGUH+543YLiMPGVr3eVS7biue1/tQlL+fJsw3rqsPKJe71RbVWlpqU\n" +
+            "mhegxG4s3IvGYVB0KZoRIjDKmnnvlx6nngL2ZJ8O27U42pHsw4z4MKlcQlWkjL3T\n" +
+            "9sV6zW2Wzri+f5mvzKjhnArbLktHAgMBAAECgYBlfVVPhtZnmuXJzzQpAEZzTugb\n" +
+            "tN1OimZO0RIocTQoqj4KT+HkiJOLGFQPwbtFpMre+q4SRqNpM/oZnI1yRtKcCmIc\n" +
+            "mZgkwJ2k6pdSxqO0ofxFFTdT9czJ3rCnqBHy1g6BqUQFXT4olcygkxUpKYUwzlz1\n" +
+            "oAl487CoPxyr4sVEAQJBANwiUOHcdGd2RoRILDzw5WOXWBoWPOKzX/K9wt0yL+mO\n" +
+            "wlFNFSymqo9eLheHcEq/VD9qK9rT700dCewJfWj6+bECQQDNXmWNYIxGii5NJilT\n" +
+            "OBOHiMD/F0NE178j+/kmacbhDJwpkbLYXaP8rW4+Iswrm4ORJ59lvjNuXaZ28+sx\n" +
+            "fFp3AkA6Z7Bl/IO135+eATgbgx6ZadIqObQ1wbm3Qbmtzl7/7KyJvZXcnuup1icM\n" +
+            "fxa//jtwB89S4+Ad6ZJ0WaA4dj5BAkEAuG7V9KmIULE388EZy8rIfyepa22Q0/qN\n" +
+            "hdt8XasRGHsio5Jdc0JlSz7ViqflhCQde/aBh/XQaoVgQeO8jKyI8QJBAJHekZDj\n" +
+            "WA0w1RsBVVReN1dVXgjm1CykeAT8Qx8TUmBUfiDX6w6+eGQjKtS7f4KC2IdRTV6+\n" +
+            "bDzDoHBChHNC9ms=\n";
+
+    // Content from usercert.pem without the header and footer.
+    private static final String TEST_CERT =
+            "MIIDEjCCAfqgAwIBAgIBATANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJBVTET\n" +
+            "MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ\n" +
+            "dHkgTHRkMB4XDTE1MDUwMTE2NTQwNVoXDTI1MDQyODE2NTQwNVowWzELMAkGA1UE\n" +
+            "BhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdp\n" +
+            "ZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLY2xpZW50IGNlcnQwgZ8wDQYJKoZIhvcN\n" +
+            "AQEBBQADgY0AMIGJAoGBALCYprGsTU+5L3KMfhkm0gXM2xjGUH+543YLiMPGVr3e\n" +
+            "VS7biue1/tQlL+fJsw3rqsPKJe71RbVWlpqUmhegxG4s3IvGYVB0KZoRIjDKmnnv\n" +
+            "lx6nngL2ZJ8O27U42pHsw4z4MKlcQlWkjL3T9sV6zW2Wzri+f5mvzKjhnArbLktH\n" +
+            "AgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2Vu\n" +
+            "ZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBQ8GL+jKSarvTn9fVNA2AzjY7qq\n" +
+            "gjAfBgNVHSMEGDAWgBRzBBA5sNWyT/fK8GrhN3tOqO5tgjANBgkqhkiG9w0BAQsF\n" +
+            "AAOCAQEAgwQEd2bktIDZZi/UOwU1jJUgGq7NiuBDPHcqgzjxhGFLQ8SQAAP3v3PR\n" +
+            "mLzcfxsxnzGynqN5iHQT4rYXxxaqrp1iIdj9xl9Wl5FxjZgXITxhlRscOd/UOBvG\n" +
+            "oMrazVczjjdoRIFFnjtU3Jf0Mich68HD1Z0S3o7X6sDYh6FTVR5KbLcxbk6RcoG4\n" +
+            "VCI5boR5LUXgb5Ed5UxczxvN12S71fyxHYVpuuI0z0HTIbAxKeRw43I6HWOmR1/0\n" +
+            "G6byGCNL/1Fz7Y+264fGqABSNTKdZwIU2K4ANEH7F+9scnhoO6OBp+gjBe5O+7jb\n" +
+            "wZmUCAoTka4hmoaOCj7cqt/IkmxozQ==\n";
+
+    private DevicePolicyManager mDpm;
+    private volatile boolean mReceivedResult;
+    private volatile Exception mReceivedException;
+    private Semaphore mAvailableResultSemaphore;
+
+    private final BroadcastReceiver receiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (ACTION_CERT_OPERATION_DONE.equals(intent.getAction())) {
+                synchronized (DelegatedCertInstallerTest.this) {
+                    mReceivedResult = intent.getBooleanExtra(EXTRA_RESULT_VALUE, false);
+                    mReceivedException =
+                            (Exception) intent.getSerializableExtra(EXTRA_RESULT_EXCEPTION);
+                    mAvailableResultSemaphore.release();
+                }
+            }
+        }
+    };
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mDpm = (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mAvailableResultSemaphore = new Semaphore(0);
+        mReceivedResult = false;
+        mReceivedException = null;
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ACTION_CERT_OPERATION_DONE);
+        mContext.registerReceiver(receiver, filter);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mContext.unregisterReceiver(receiver);
+        mDpm.uninstallCaCert(ADMIN_RECEIVER_COMPONENT, TEST_CA.getBytes());
+        // Installed private key pair will be removed once the lockscreen password is cleared,
+        // which is done in the hostside test.
+        mDpm.setCertInstallerPackage(ADMIN_RECEIVER_COMPONENT, null);
+        super.tearDown();
+    }
+
+    public void testCaCertsOperations() throws InterruptedException {
+        byte[] cert = TEST_CA.getBytes();
+
+        mDpm.setCertInstallerPackage(ADMIN_RECEIVER_COMPONENT, CERT_INSTALLER_PACKAGE);
+        assertEquals(CERT_INSTALLER_PACKAGE,
+                mDpm.getCertInstallerPackage(ADMIN_RECEIVER_COMPONENT));
+
+        // Exercise installCaCert()
+        installCaCert(cert);
+        assertResult("installCaCert", true);
+        assertTrue("Certificate is not installed properly", mDpm.hasCaCertInstalled(
+                ADMIN_RECEIVER_COMPONENT, cert));
+
+        // Exercise getInstalledCaCerts()
+        verifyCaCert(cert);
+        assertResult("getInstalledCaCerts()", true);
+
+        // Exercise uninstallCaCert()
+        removeCaCert(cert);
+        assertResult("uninstallCaCert()", true);
+        assertFalse("Certificate is not removed properly", mDpm.hasCaCertInstalled(
+                ADMIN_RECEIVER_COMPONENT, cert));
+
+        // Clear delegated cert installer.
+        // Tests after this are expected to fail.
+        mDpm.setCertInstallerPackage(ADMIN_RECEIVER_COMPONENT, null);
+
+        installCaCert(cert);
+        assertResult("installCaCert", false);
+    }
+
+    public void testInstallKeyPair() throws InterruptedException, KeyChainException {
+        final String alias = "delegated-cert-installer-test-key";
+
+        // Clear delegated cert installer.
+        mDpm.setCertInstallerPackage(ADMIN_RECEIVER_COMPONENT, null);
+        // The app is not the cert installer , it shouldn't have have privilege to call
+        // installKeyPair().
+        installKeyPair(TEST_KEY, TEST_CERT, alias);
+        assertResult("installKeyPair", false);
+
+        // Set the app to be cert installer.
+        mDpm.setCertInstallerPackage(ADMIN_RECEIVER_COMPONENT, CERT_INSTALLER_PACKAGE);
+        assertEquals(CERT_INSTALLER_PACKAGE,
+                mDpm.getCertInstallerPackage(ADMIN_RECEIVER_COMPONENT));
+
+        // Exercise installKeyPair()
+        checkKeyguardPrecondition();
+        installKeyPair(TEST_KEY, TEST_CERT, alias);
+        assertResult("installKeyPair", true);
+    }
+
+    /**
+     * installKeyPair() requires the system to have a lockscreen password, which should have been
+     * set by the host side test.
+     */
+    private void checkKeyguardPrecondition() throws InterruptedException {
+        KeyguardManager km = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
+        if (!km.isKeyguardSecure()) {
+            Thread.sleep(5000);
+          }
+          assertTrue("A lockscreen password is required before keypair can be installed",
+                          km.isKeyguardSecure());
+    }
+
+    private void installCaCert(byte[] cert) {
+        Intent intent = new Intent();
+        intent.setAction(ACTION_INSTALL_CERT);
+        intent.putExtra(EXTRA_CERT_DATA, cert);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    private void removeCaCert(byte[] cert) {
+        Intent intent = new Intent();
+        intent.setAction(ACTION_REMOVE_CERT);
+        intent.putExtra(EXTRA_CERT_DATA, cert);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    private void verifyCaCert(byte[] cert) {
+        Intent intent = new Intent();
+        intent.setAction(ACTION_VERIFY_CERT);
+        intent.putExtra(EXTRA_CERT_DATA, cert);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    private void assertResult(String testName, Boolean expectSuccess) throws InterruptedException {
+        assertTrue("Cert installer did not respond in time.",
+                mAvailableResultSemaphore.tryAcquire(5, TimeUnit.SECONDS));
+        synchronized (this) {
+            if (expectSuccess) {
+                assertTrue(testName + " failed unexpectedly.", mReceivedResult);
+                assertNull(testName + " raised exception", mReceivedException);
+            } else {
+                assertFalse(testName + " succeeded unexpectedly.", mReceivedResult);
+                assertTrue(testName + " did not raise SecurityException",
+                        mReceivedException != null &&
+                        mReceivedException instanceof SecurityException);
+            }
+        }
+    }
+
+    private void installKeyPair(String key, String cert, String alias) {
+        Intent intent = new Intent();
+        intent.setAction(ACTION_INSTALL_KEYPAIR);
+        intent.putExtra(EXTRA_CERT_DATA, cert);
+        intent.putExtra(EXTRA_KEY_DATA, key);
+        intent.putExtra(EXTRA_KEY_ALIAS, alias);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ExampleIntentReceivingActivity1.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ExampleIntentReceivingActivity1.java
new file mode 100644
index 0000000..bbcc3b1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ExampleIntentReceivingActivity1.java
@@ -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.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class ExampleIntentReceivingActivity1 extends Activity {
+    static final String CONFIRM_ACTION = "com.android.cts.deviceandprofileowner.CONFIRM_1";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (getIntent().getAction().equals(PersistentIntentResolvingTest.EXAMPLE_ACTION)) {
+            sendBroadcast(new Intent(CONFIRM_ACTION));
+        }
+        finish();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ExampleIntentReceivingActivity2.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ExampleIntentReceivingActivity2.java
new file mode 100644
index 0000000..5122b06
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ExampleIntentReceivingActivity2.java
@@ -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.
+ */
+
+package com.android.cts.deviceandprofileowner;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class ExampleIntentReceivingActivity2 extends Activity {
+    static final String CONFIRM_ACTION = "com.android.cts.deviceandprofileowner.CONFIRM_2";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (getIntent().getAction().equals(PersistentIntentResolvingTest.EXAMPLE_ACTION)) {
+            sendBroadcast(new Intent(CONFIRM_ACTION));
+        }
+        finish();
+    }
+}
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
new file mode 100644
index 0000000..e8e5b45
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/MockAccountAuthenticator.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.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
new file mode 100644
index 0000000..dfedccb
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/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.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/PermissionsTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
new file mode 100644
index 0000000..d181ad5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PermissionsTest.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.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.UserManager;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiDevice;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.UiWatcher;
+import android.support.test.uiautomator.Until;
+import android.util.Log;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test Runtime Permissions APIs in DevicePolicyManager.
+ */
+public class PermissionsTest extends BaseDeviceAdminTest {
+    private static final String TAG = "PermissionsTest";
+
+    private static final String PERMISSION_APP_PACKAGE_NAME
+            = "com.android.cts.permissionapp";
+    private static final String SIMPLE_PRE_M_APP_PACKAGE_NAME =
+            "com.android.cts.launcherapps.simplepremapp";
+    private static final String PERMISSION_NAME = "android.permission.READ_CONTACTS";
+
+    private static final String PERMISSIONS_ACTIVITY_NAME
+            = PERMISSION_APP_PACKAGE_NAME + ".PermissionActivity";
+    private static final String ACTION_CHECK_HAS_PERMISSION
+            = "com.android.cts.permission.action.CHECK_HAS_PERMISSION";
+    private static final String ACTION_REQUEST_PERMISSION
+            = "com.android.cts.permission.action.REQUEST_PERMISSION";
+    private static final String ACTION_PERMISSION_RESULT
+            = "com.android.cts.permission.action.PERMISSION_RESULT";
+    private static final String EXTRA_PERMISSION
+            = "com.android.cts.permission.extra.PERMISSION";
+    private static final String EXTRA_GRANT_STATE
+            = "com.android.cts.permission.extra.GRANT_STATE";
+    private static final int PERMISSION_ERROR = -2;
+    private static final BySelector CRASH_POPUP_BUTTON_SELECTOR = By
+            .clazz(android.widget.Button.class.getName())
+            .text("OK")
+            .pkg("android");
+    private static final BySelector CRASH_POPUP_TEXT_SELECTOR = By
+            .clazz(android.widget.TextView.class.getName())
+            .pkg("android");
+    private static final String CRASH_WATCHER_ID = "CRASH";
+
+    private PermissionBroadcastReceiver mReceiver;
+    private PackageManager mPackageManager;
+    private UiDevice mDevice;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mReceiver = new PermissionBroadcastReceiver();
+        mContext.registerReceiver(mReceiver, new IntentFilter(ACTION_PERMISSION_RESULT));
+        mPackageManager = mContext.getPackageManager();
+        mDevice = UiDevice.getInstance(getInstrumentation());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mContext.unregisterReceiver(mReceiver);
+        mDevice.removeWatcher(CRASH_WATCHER_ID);
+        super.tearDown();
+    }
+
+    public void testPermissionGrantState() throws Exception {
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
+        assertPermissionGrantState(PackageManager.PERMISSION_DENIED);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED);
+
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+        // Should stay denied
+        assertPermissionGrantState(PackageManager.PERMISSION_DENIED);
+
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+        assertPermissionGrantState(PackageManager.PERMISSION_GRANTED);
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
+
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+        // Should stay granted
+        assertPermissionGrantState(PackageManager.PERMISSION_GRANTED);
+    }
+
+    public void testPermissionPolicy() throws Exception {
+        // reset permission to denied and unlocked
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED);
+        // permission should be locked, so changing the policy should not change the grant state
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED);
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED);
+
+        // reset permission to denied and unlocked
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
+        // permission should be locked, so changing the policy should not change the grant state
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
+
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
+    }
+
+    public void testPermissionMixedPolicies() throws Exception {
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED);
+
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED);
+
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED);
+
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
+
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
+
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
+    }
+
+    public void testPermissionPrompts() throws Exception {
+        // register a crash watcher
+        mDevice.registerWatcher(CRASH_WATCHER_ID, new UiWatcher() {
+            @Override
+            public boolean checkForCondition() {
+                UiObject2 button = mDevice.findObject(CRASH_POPUP_BUTTON_SELECTOR);
+                if (button != null) {
+                    UiObject2 text = mDevice.findObject(CRASH_POPUP_TEXT_SELECTOR);
+                    Log.d(TAG, "Removing an error dialog: " + text != null ? text.getText() : null);
+                    button.click();
+                    return true;
+                }
+                return false;
+            }
+        });
+        mDevice.runWatchers();
+
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_PROMPT);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED, "permission_deny_button");
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED, "permission_allow_button");
+    }
+
+    public void testPermissionUpdate_setDeniedState() throws Exception {
+        assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+                PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
+                DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
+    }
+
+    public void testPermissionUpdate_setAutoDeniedPolicy() throws Exception {
+        assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+                PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
+                DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_DENY);
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED);
+    }
+
+    public void testPermissionUpdate_checkDenied() throws Exception {
+        assertPermissionRequest(PackageManager.PERMISSION_DENIED);
+        assertPermissionGrantState(PackageManager.PERMISSION_DENIED);
+    }
+
+    public void testPermissionUpdate_setGrantedState() throws Exception {
+        assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+                PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
+                DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+        assertSetPermissionGrantState(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+    }
+
+    public void testPermissionUpdate_setAutoGrantedPolicy() throws Exception {
+        assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+                PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
+                DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+        assertSetPermissionPolicy(DevicePolicyManager.PERMISSION_POLICY_AUTO_GRANT);
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
+    }
+
+    public void testPermissionUpdate_checkGranted() throws Exception {
+        assertPermissionRequest(PackageManager.PERMISSION_GRANTED);
+        assertPermissionGrantState(PackageManager.PERMISSION_GRANTED);
+    }
+
+    public void testPermissionGrantStatePreMApp() throws Exception {
+        // These tests are to make sure that pre-M apps are not granted runtime permissions
+        // by a profile owner
+        assertSetPermissionGrantStatePreMApp(DevicePolicyManager.PERMISSION_GRANT_STATE_DENIED);
+        assertSetPermissionGrantStatePreMApp(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED);
+    }
+
+    private void assertPermissionRequest(int expected) throws Exception {
+        assertPermissionRequest(expected, null);
+    }
+
+    private void assertPermissionRequest(int expected, String buttonResource) throws Exception {
+        Intent launchIntent = new Intent();
+        launchIntent.setComponent(new ComponentName(PERMISSION_APP_PACKAGE_NAME,
+                PERMISSIONS_ACTIVITY_NAME));
+        launchIntent.putExtra(EXTRA_PERMISSION, PERMISSION_NAME);
+        launchIntent.setAction(ACTION_REQUEST_PERMISSION);
+        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+        mContext.startActivity(launchIntent);
+        pressPermissionPromptButton(buttonResource);
+        assertEquals(expected, mReceiver.waitForBroadcast());
+        assertEquals(expected, mPackageManager.checkPermission(PERMISSION_NAME,
+                PERMISSION_APP_PACKAGE_NAME));
+    }
+
+    private void assertPermissionGrantState(int expected) throws Exception {
+        assertEquals(expected, mPackageManager.checkPermission(PERMISSION_NAME,
+                PERMISSION_APP_PACKAGE_NAME));
+        Intent launchIntent = new Intent();
+        launchIntent.setComponent(new ComponentName(PERMISSION_APP_PACKAGE_NAME,
+                PERMISSIONS_ACTIVITY_NAME));
+        launchIntent.putExtra(EXTRA_PERMISSION, PERMISSION_NAME);
+        launchIntent.setAction(ACTION_CHECK_HAS_PERMISSION);
+        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+        mContext.startActivity(launchIntent);
+        assertEquals(expected, mReceiver.waitForBroadcast());
+    }
+
+    private void assertSetPermissionPolicy(int value) throws Exception {
+        mDevicePolicyManager.setPermissionPolicy(ADMIN_RECEIVER_COMPONENT,
+                value);
+        assertEquals(mDevicePolicyManager.getPermissionPolicy(ADMIN_RECEIVER_COMPONENT),
+                value);
+    }
+
+    private void assertSetPermissionGrantState(int value) throws Exception {
+        mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+                PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME,
+                value);
+        assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+                PERMISSION_APP_PACKAGE_NAME, PERMISSION_NAME),
+                value);
+    }
+
+    private void assertSetPermissionGrantStatePreMApp(int value) throws Exception {
+        assertFalse(mDevicePolicyManager.setPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+                SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME,
+                value));
+        assertEquals(mDevicePolicyManager.getPermissionGrantState(ADMIN_RECEIVER_COMPONENT,
+                SIMPLE_PRE_M_APP_PACKAGE_NAME, PERMISSION_NAME),
+                DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT);
+        // Install time permissions should always be granted
+        assertEquals(mPackageManager.checkPermission(PERMISSION_NAME,
+                SIMPLE_PRE_M_APP_PACKAGE_NAME),
+                PackageManager.PERMISSION_GRANTED);
+    }
+
+    private void pressPermissionPromptButton(String resName) throws Exception {
+        if (resName == null) {
+            return;
+        }
+
+        BySelector selector = By
+                .clazz(android.widget.Button.class.getName())
+                .res("com.android.packageinstaller", resName);
+        mDevice.wait(Until.hasObject(selector), 5000);
+        UiObject2 button = mDevice.findObject(selector);
+        assertNotNull("Couldn't find button with resource id: " + resName, button);
+        button.click();
+    }
+
+    private class PermissionBroadcastReceiver extends BroadcastReceiver {
+        private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer> (1);
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Integer result = new Integer(intent.getIntExtra(EXTRA_GRANT_STATE, PERMISSION_ERROR));
+            Log.d(TAG, "Grant state received " + result);
+            assertTrue(mQueue.add(result));
+        }
+
+        public int waitForBroadcast() throws Exception {
+            Integer result = mQueue.poll(30, TimeUnit.SECONDS);
+            mQueue.clear();
+            assertNotNull(result);
+            Log.d(TAG, "Grant state retrieved " + result.intValue());
+            return result.intValue();
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PersistentIntentResolvingTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PersistentIntentResolvingTest.java
new file mode 100644
index 0000000..41526ec
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PersistentIntentResolvingTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.SystemClock;
+
+public class PersistentIntentResolvingTest extends BaseDeviceAdminTest {
+    static final String EXAMPLE_ACTION = "com.android.cts.deviceandprofileowner.EXAMPLE_ACTION";
+
+    private boolean mReceivedConfirmationFrom1;
+    private boolean mReceivedConfirmationFrom2;
+    private BroadcastReceiver mReceiver;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ExampleIntentReceivingActivity1.CONFIRM_ACTION);
+        filter.addAction(ExampleIntentReceivingActivity2.CONFIRM_ACTION);
+
+        mReceiver = new ConfirmReceiver();
+        mContext.registerReceiver(mReceiver, filter);
+
+        synchronized(this) {
+            mReceivedConfirmationFrom1 = false;
+            mReceivedConfirmationFrom2 = false;
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager.clearPackagePersistentPreferredActivities(ADMIN_RECEIVER_COMPONENT,
+                PACKAGE_NAME);
+        mContext.unregisterReceiver(mReceiver);
+
+        super.tearDown();
+    }
+
+    public void testNoPersistentPreferredActivityYieldsResolverActivity() {
+        sendExampleIntent();
+        SystemClock.sleep(5000);
+
+        // Default behavior: intent results in resolver activity, since there are two potential
+        // receivers. No intent is received.
+        synchronized(this) {
+            assertFalse(mReceivedConfirmationFrom1);
+            assertFalse(mReceivedConfirmationFrom2);
+        }
+    }
+
+    public void testAddPersistentPreferredActivityYieldsReceptionAtTarget() {
+        addPersistentPreferredActivity();
+        sendExampleIntent();
+        SystemClock.sleep(5000);
+
+        // Persistent preferred activity present: intent should be received by activity 2.
+        synchronized(this) {
+            assertFalse(mReceivedConfirmationFrom1);
+            assertTrue(mReceivedConfirmationFrom2);
+        }
+    }
+
+    public void testAddAndClearPersistentPreferredActivitiesYieldsResolverActivity() {
+        addPersistentPreferredActivity();
+        mDevicePolicyManager.clearPackagePersistentPreferredActivities(ADMIN_RECEIVER_COMPONENT,
+                PACKAGE_NAME);
+
+        sendExampleIntent();
+        SystemClock.sleep(5000);
+
+        // Default behavior: intent results in resolver activity, since there are two potential
+        // receivers. No intent is received.
+        synchronized(this) {
+            assertFalse(mReceivedConfirmationFrom1);
+            assertFalse(mReceivedConfirmationFrom2);
+        }
+    }
+
+    public class ConfirmReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(ExampleIntentReceivingActivity1.CONFIRM_ACTION)) {
+                synchronized (PersistentIntentResolvingTest.this) {
+                    mReceivedConfirmationFrom1 = true;
+                }
+            } else if (intent.getAction().equals(ExampleIntentReceivingActivity2
+                            .CONFIRM_ACTION)) {
+                synchronized (PersistentIntentResolvingTest.this) {
+                    mReceivedConfirmationFrom2 = true;
+                }
+            }
+        }
+    }
+
+    private void sendExampleIntent() {
+        Intent exampleIntent = new Intent(EXAMPLE_ACTION);
+        exampleIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(exampleIntent);
+    }
+
+    private void addPersistentPreferredActivity() {
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(EXAMPLE_ACTION);
+        filter.addCategory(Intent.CATEGORY_DEFAULT);
+        ComponentName targetComponent = new ComponentName(PACKAGE_NAME,
+                ExampleIntentReceivingActivity2.class.getName());
+        mDevicePolicyManager.addPersistentPreferredActivity(ADMIN_RECEIVER_COMPONENT, filter,
+                targetComponent);
+    }
+}
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
new file mode 100644
index 0000000..7fc0173
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserAdminHelper.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.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
new file mode 100644
index 0000000..f3c8ff6
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/PrimaryUserDeviceAdmin.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.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/ScreenCaptureDisabledActivity.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledActivity.java
new file mode 100644
index 0000000..b5b4fdc
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledActivity.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.cts.deviceandprofileowner;
+
+import android.app.Activity;
+import android.content.Intent;
+
+/**
+ * Test activity for setScreenCaptureDisabled().
+ */
+public class ScreenCaptureDisabledActivity extends Activity {
+
+    static final String ACTIVITY_RESUMED =
+            "com.android.cts.deviceandprofileowner.ACTIVITY_RESUMED";
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        sendBroadcast(new Intent(ACTIVITY_RESUMED));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java
new file mode 100644
index 0000000..e2deaa4
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/ScreenCaptureDisabledTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.admin.DevicePolicyManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Tests for {@link DevicePolicyManager#setScreenCaptureDisabled} and
+ * {@link DevicePolicyManager#getScreenCaptureDisabled} APIs.
+ */
+public class ScreenCaptureDisabledTest extends BaseDeviceAdminTest {
+
+    private static final String TAG = "ScreenCaptureDisabledTest";
+
+    private ScreenCaptureBroadcastReceiver mReceiver = new ScreenCaptureBroadcastReceiver();
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext.registerReceiver(mReceiver, new IntentFilter(
+                ScreenCaptureDisabledActivity.ACTIVITY_RESUMED));
+    }
+
+    protected void tearDown() throws Exception {
+        mContext.unregisterReceiver(mReceiver);
+        super.tearDown();
+    }
+
+    public void testSetScreenCaptureDisabled_false() throws Exception {
+        mDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, false);
+        assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT));
+        assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
+        startTestActivity();
+        assertNotNull(getInstrumentation().getUiAutomation().takeScreenshot());
+    }
+
+    public void testSetScreenCaptureDisabled_true() throws Exception {
+        mDevicePolicyManager.setScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT, true);
+        assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(ADMIN_RECEIVER_COMPONENT));
+        assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
+        startTestActivity();
+        assertNull(getInstrumentation().getUiAutomation().takeScreenshot());
+    }
+
+    public void testScreenCapturePossible() throws Exception {
+        assertNotNull(getInstrumentation().getUiAutomation().takeScreenshot());
+    }
+
+    // We need to launch an activity before trying to take a screen shot, because screenshots are
+    // only blocked on a per-user basis in the profile owner case depending on the owner of the
+    // foreground activity.
+    private void startTestActivity() throws Exception {
+        Intent launchIntent = new Intent();
+        launchIntent.setComponent(new ComponentName(PACKAGE_NAME,
+                ScreenCaptureDisabledActivity.class.getName()));
+        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(launchIntent);
+        assertTrue(mReceiver.waitForBroadcast());
+        Thread.sleep(1000);
+    }
+
+    private class ScreenCaptureBroadcastReceiver extends BroadcastReceiver {
+        private final Semaphore mSemaphore = new Semaphore(0);
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.d(TAG, "Broadcast received");
+            mSemaphore.release();
+        }
+
+        public boolean waitForBroadcast() throws Exception {
+            if (mSemaphore.tryAcquire(5, TimeUnit.SECONDS)) {
+                return true;
+            }
+            return false;
+        }
+    }
+}
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
new file mode 100644
index 0000000..fed1a79
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/UserRestrictionActivity.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 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/DeviceOwner/Android.mk b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
index e621933..314f996 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/Android.mk
@@ -26,6 +26,8 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
 
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner compatibility-device-util_v2
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
index dfc7e9c..e424f18 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/AndroidManifest.xml
@@ -21,6 +21,8 @@
 
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
     <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" />
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -33,22 +35,15 @@
                 <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
             </intent-filter>
         </receiver>
-        <activity android:name="com.android.cts.deviceowner.ExampleIntentReceivingActivity1">
-            <intent-filter>
-                <action android:name="com.android.cts.deviceowner.EXAMPLE_ACTION" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
 
-        <activity android:name="com.android.cts.deviceowner.ExampleIntentReceivingActivity2">
-            <intent-filter>
-                <action android:name="com.android.cts.deviceowner.EXAMPLE_ACTION" />
-                <category android:name="android.intent.category.DEFAULT" />
-            </intent-filter>
-        </activity>
+        <activity
+            android:name="com.android.cts.deviceowner.KeyManagementActivity" />
 
         <activity
             android:name="com.android.cts.deviceowner.LockTaskUtilityActivity" />
+        <activity
+            android:name="com.android.cts.deviceowner.LockTaskUtilityActivityIfWhitelisted"
+            android:lockTaskMode="if_whitelisted" />
 
         <!-- we need to give a different taskAffinity so that when we use
              FLAG_ACTIVITY_NEW_TASK, the system tries to start it in a different task
@@ -57,11 +52,9 @@
             android:name="com.android.cts.deviceowner.LockTaskTest$IntentReceivingActivity"
             android:taskAffinity="com.android.cts.deviceowner.LockTaskTest.IntentReceivingActivity"
             />
-        <activity
-            android:name="com.android.cts.deviceowner.ApplicationRestrictionActivity" />
     </application>
 
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
                      android:targetPackage="com.android.cts.deviceowner"
                      android:label="Device Owner CTS tests"/>
 </manifest>
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionActivity.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionActivity.java
deleted file mode 100644
index 4d8e4f2..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionActivity.java
+++ /dev/null
@@ -1,94 +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.deviceowner;
-
-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 ApplicationRestrictionActivity extends Activity {
-
-    // Incoming intent type
-    public static final String FINISH = "finishActivity";
-
-    // Outgoing broadcast
-    public static final String REGISTERED_ACTION =
-            "com.android.cts.deviceowner.APP_RESTRICTION_REGISTERED";
-    public static final String RESTRICTION_ACTION =
-            "com.android.cts.deviceowner.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/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionsTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionsTest.java
deleted file mode 100644
index 5e03de9..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ApplicationRestrictionsTest.java
+++ /dev/null
@@ -1,199 +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.deviceowner;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Bundle;
-
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Functionality tests for setApplicationRestrictions and getApplicationRestrictions
- * in DevicePolicyManager.
- *
- * 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.
- */
-public class ApplicationRestrictionsTest extends BaseDeviceOwnerTest {
-
-    private static final String[] testStrings = 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 Bundle mReceivedRestrictions;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ApplicationRestrictionActivity.REGISTERED_ACTION);
-        filter.addAction(ApplicationRestrictionActivity.RESTRICTION_ACTION);
-        mContext.registerReceiver(mReceiver, filter);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mContext.unregisterReceiver(mReceiver);
-        super.tearDown();
-    }
-
-    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(getWho(), CTS_PACKAGE, bundle0);
-        mDevicePolicyManager.setApplicationRestrictions(getWho(), OTHER_PACKAGE, bundle1);
-
-        // Retrieve restrictions locally and make sure they are what we put in.
-        assertBundle0(mDevicePolicyManager.getApplicationRestrictions(getWho(), CTS_PACKAGE));
-        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(getWho(), OTHER_PACKAGE));
-
-        // The test activity should have received a change_restriction broadcast
-        // and relay the value back to us.
-        assertBundle0(waitForChangedRestriction());
-
-        // Test overwriting
-        mDevicePolicyManager.setApplicationRestrictions(getWho(), CTS_PACKAGE, bundle1);
-        assertBundle1(mDevicePolicyManager.getApplicationRestrictions(getWho(), CTS_PACKAGE));
-        assertBundle1(waitForChangedRestriction());
-
-        // Cleanup
-        mDevicePolicyManager.setApplicationRestrictions(getWho(), CTS_PACKAGE, new Bundle());
-        assertTrue(
-                mDevicePolicyManager.getApplicationRestrictions(getWho(), CTS_PACKAGE).isEmpty());
-        assertTrue(waitForChangedRestriction().isEmpty());
-        mDevicePolicyManager.setApplicationRestrictions(getWho(), OTHER_PACKAGE, new Bundle());
-        assertTrue(
-                mDevicePolicyManager.getApplicationRestrictions(getWho(), OTHER_PACKAGE).isEmpty());
-
-        finish();
-    }
-
-    // Should be consistent with assertBundle0
-    private Bundle createBundle0() {
-        Bundle result = new Bundle();
-        // Tests for four allowed types: Integer, Boolean, String and String[]
-        // Also test for string escaping handling
-        result.putBoolean("boolean_0", false);
-        result.putBoolean("boolean_1", true);
-        result.putInt("integer", 0x7fffffff);
-        // If a null is stored, "" will be read back
-        result.putString("empty", "");
-        result.putString("string", "text");
-        result.putStringArray("string[]", testStrings);
-        return result;
-    }
-
-    // Should be consistent with createBundle0
-    private void assertBundle0(Bundle bundle) {
-        assertEquals(6, bundle.size());
-        assertEquals(false, bundle.getBoolean("boolean_0"));
-        assertEquals(true, bundle.getBoolean("boolean_1"));
-        assertEquals(0x7fffffff, bundle.getInt("integer"));
-        assertEquals("", bundle.getString("empty"));
-        assertEquals("text", bundle.getString("string"));
-
-        String[] strings = bundle.getStringArray("string[]");
-        assertTrue(strings != null && strings.length == testStrings.length);
-        for (int i = 0; i < strings.length; i++) {
-            assertEquals(strings[i], testStrings[i]);
-        }
-    }
-
-    // Should be consistent with assertBundle1
-    private Bundle createBundle1() {
-        Bundle result = new Bundle();
-        result.putInt("dummy", 1);
-        return result;
-    }
-
-    // Should be consistent with createBundle1
-    private void assertBundle1(Bundle bundle) {
-        assertEquals(1, bundle.size());
-        assertEquals(1, bundle.getInt("dummy"));
-    }
-
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            String action = intent.getAction();
-            if (ApplicationRestrictionActivity.REGISTERED_ACTION.equals(action)) {
-                mOnRegisteredSemaphore.release();
-            } else if (ApplicationRestrictionActivity.RESTRICTION_ACTION.equals(action)) {
-                mReceivedRestrictions = intent.getBundleExtra("value");
-                mOnRestrictionSemaphore.release();
-            }
-        }
-    };
-
-    private void startTestActivity(String command) {
-        Intent intent = new Intent();
-        intent.setClassName(PACKAGE_NAME, ApplicationRestrictionActivity.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 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 waitForChangedRestriction() {
-        try {
-            assertTrue(mOnRestrictionSemaphore.tryAcquire(5, TimeUnit.SECONDS));
-        } catch (InterruptedException e) {
-            fail("getRestrictionsAndWait() interrupted");
-        }
-
-        return mReceivedRestrictions;
-    }
-
-    private void finish() {
-        startTestActivity(ApplicationRestrictionActivity.FINISH);
-    }
-
-}
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 e4f5134b..b6815fd 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
@@ -19,6 +19,9 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Process;
 import android.test.AndroidTestCase;
 
 /**
@@ -32,6 +35,14 @@
 public class BaseDeviceOwnerTest extends AndroidTestCase {
 
     public static class BasicAdminReceiver extends DeviceAdminReceiver {
+        @Override
+        public String onChoosePrivateKeyAlias(Context context, Intent intent, int uid, Uri uri,
+                String suggestedAlias) {
+            if (uid != Process.myUid() || uri == null) {
+                return null;
+            }
+            return uri.getQueryParameter("alias");
+        }
     }
 
     public static final String PACKAGE_NAME = BaseDeviceOwnerTest.class.getPackage().getName();
@@ -44,11 +55,16 @@
 
         mDevicePolicyManager = (DevicePolicyManager)
                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-        assertTrue(mDevicePolicyManager.isAdminActive(getWho()));
-        assertTrue(mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME));
+        assertDeviceOwner(mDevicePolicyManager);
     }
 
-    public static ComponentName getWho() {
+    static void assertDeviceOwner(DevicePolicyManager dpm) {
+        assertNotNull(dpm);
+        assertTrue(dpm.isAdminActive(getWho()));
+        assertTrue(dpm.isDeviceOwnerApp(PACKAGE_NAME));
+    }
+
+    protected static ComponentName getWho() {
         return new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName());
     }
-}
\ No newline at end of file
+}
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 9127dab..51c575c 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,69 +15,143 @@
  */
 package com.android.cts.deviceowner;
 
-import static com.android.cts.deviceowner.FakeKeys.FAKE_RSA_1;
-import static com.android.cts.deviceowner.FakeKeys.FAKE_DSA_1;
-
 import java.io.ByteArrayInputStream;
+import java.security.GeneralSecurityException;
+import java.security.KeyStore;
+import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
-import java.security.cert.Certificate;
+import java.util.Arrays;
 import java.util.List;
 
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509TrustManager;
+
+import static com.android.cts.deviceowner.FakeKeys.FAKE_DSA_1;
+import static com.android.cts.deviceowner.FakeKeys.FAKE_RSA_1;
+
 public class CaCertManagementTest extends BaseDeviceOwnerTest {
+    /**
+     * Test: device admins should be able to list all installed certs.
+     *
+     * <p>The list of certificates must never be {@code null}.
+     */
     public void testCanRetrieveListOfInstalledCaCerts() {
         List<byte[]> caCerts = mDevicePolicyManager.getInstalledCaCerts(getWho());
         assertNotNull(caCerts);
     }
 
+    /**
+     * Test: a valid cert should be installable and also removable.
+     */
     public void testCanInstallAndUninstallACaCert()
-    throws CertificateException {
-        assertFalse(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
-        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+            throws CertificateException, GeneralSecurityException {
+        assertUninstalled(FAKE_RSA_1.caCertificate);
+        assertUninstalled(FAKE_DSA_1.caCertificate);
+
         assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_RSA_1.caCertificate));
-        assertTrue(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
-        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+        assertInstalled(FAKE_RSA_1.caCertificate);
+        assertUninstalled(FAKE_DSA_1.caCertificate);
+
         mDevicePolicyManager.uninstallCaCert(getWho(), FAKE_RSA_1.caCertificate);
-        assertFalse(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
-        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+        assertUninstalled(FAKE_RSA_1.caCertificate);
+        assertUninstalled(FAKE_DSA_1.caCertificate);
     }
 
-    public void testUninstallationIsSelective() throws CertificateException {
+    /**
+     * Test: removing one certificate must not remove any others.
+     */
+    public void testUninstallationIsSelective()
+            throws CertificateException, GeneralSecurityException {
         assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_RSA_1.caCertificate));
         assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_DSA_1.caCertificate));
+
         mDevicePolicyManager.uninstallCaCert(getWho(), FAKE_DSA_1.caCertificate);
-        assertTrue(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
-        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+        assertInstalled(FAKE_RSA_1.caCertificate);
+        assertUninstalled(FAKE_DSA_1.caCertificate);
+
         mDevicePolicyManager.uninstallCaCert(getWho(), FAKE_RSA_1.caCertificate);
     }
 
-    public void testCanUninstallAllUserCaCerts() throws CertificateException {
+    /**
+     * Test: uninstallAllUserCaCerts should be equivalent to calling uninstallCaCert on every
+     * supplementary installed certificate.
+     */
+    public void testCanUninstallAllUserCaCerts()
+            throws CertificateException, GeneralSecurityException {
         assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_RSA_1.caCertificate));
         assertTrue(mDevicePolicyManager.installCaCert(getWho(), FAKE_DSA_1.caCertificate));
+
         mDevicePolicyManager.uninstallAllUserCaCerts(getWho());
-        assertFalse(hasCaCertInstalled(FAKE_RSA_1.caCertificate));
-        assertFalse(hasCaCertInstalled(FAKE_DSA_1.caCertificate));
+        assertUninstalled(FAKE_RSA_1.caCertificate);
+        assertUninstalled(FAKE_DSA_1.caCertificate);
     }
 
-    private boolean hasCaCertInstalled(byte [] caCert) throws CertificateException {
-        boolean result = mDevicePolicyManager.hasCaCertInstalled(getWho(), caCert);
-        assertEquals(result, containsCertificate(
-            mDevicePolicyManager.getInstalledCaCerts(getWho()), caCert));
-        return result;
+    private void assertInstalled(byte[] caBytes)
+            throws CertificateException, GeneralSecurityException {
+        Certificate caCert = readCertificate(caBytes);
+        assertTrue(isCaCertInstalledAndTrusted(caCert));
     }
 
-    private static boolean containsCertificate(List<byte[]> certificates, byte [] toMatch)
-            throws CertificateException {
-        Certificate certificateToMatch = readCertificate(toMatch);
-        for (byte[] certBuffer : certificates) {
-            Certificate cert = readCertificate(certBuffer);
-            if (certificateToMatch.equals(cert)) {
-                return true;
+    private void assertUninstalled(byte[] caBytes)
+            throws CertificateException, GeneralSecurityException {
+        Certificate caCert = readCertificate(caBytes);
+        assertFalse(isCaCertInstalledAndTrusted(caCert));
+    }
+
+    /**
+     * Whether a given cert, or one a lot like it, has been installed system-wide and is available
+     * to all apps.
+     *
+     * <p>A CA certificate is "installed" if it matches all of the following conditions:
+     * <ul>
+     *   <li>{@link DevicePolicyManager#hasCaCertInstalled} returns {@code true}.</li>
+     *   <li>{@link DevicePolicyManager#getInstalledCaCerts} lists a matching certificate (not
+     *       necessarily exactly the same) in its response.</li>
+     *   <li>Any new instances of {@link TrustManager} should report the certificate among their
+     *       accepted issuer list -- older instances may keep the set of issuers they were created
+     *       with until explicitly refreshed.</li>
+     *
+     * @return {@code true} if installed by all metrics, {@code false} if not installed by any
+     *         metric. In any other case an {@link AssertionError} will be thrown.
+     */
+    private boolean isCaCertInstalledAndTrusted(Certificate caCert)
+            throws GeneralSecurityException, CertificateException {
+        boolean installed = mDevicePolicyManager.hasCaCertInstalled(getWho(), caCert.getEncoded());
+
+        boolean listed = false;
+        for (byte[] certBuffer : mDevicePolicyManager.getInstalledCaCerts(getWho())) {
+            if (caCert.equals(readCertificate(certBuffer))) {
+                listed = true;
             }
         }
-        return false;
+
+        boolean trusted = false;
+        final TrustManagerFactory tmf =
+                TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        tmf.init((KeyStore) null);
+        for (TrustManager trustManager : tmf.getTrustManagers()) {
+             if (trustManager instanceof X509TrustManager) {
+                final X509TrustManager tm = (X509TrustManager) trustManager;
+                if (Arrays.asList(tm.getAcceptedIssuers()).contains(caCert)) {
+                    trusted = true;
+                }
+            }
+        }
+
+        // All three responses should match - if an installed certificate isn't trusted or (worse)
+        // a trusted certificate isn't even installed we should 
+        assertEquals(installed, listed);
+        assertEquals(installed, trusted);
+        return installed;
     }
 
+    /**
+     * Convert an encoded certificate back into a {@link Certificate}.
+     *
+     * Instantiates a fresh CertificateFactory every time for repeatability.
+     */
     private static Certificate readCertificate(byte[] certBuffer) throws CertificateException {
         final CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
         return certFactory.generateCertificate(new ByteArrayInputStream(certBuffer));
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity1.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity1.java
deleted file mode 100644
index 03ca9a4..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity1.java
+++ /dev/null
@@ -1,34 +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.deviceowner;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-
-public class ExampleIntentReceivingActivity1 extends Activity {
-    public static final String CONFIRM_ACTION = "com.android.cts.deviceowner.CONFIRM_1";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (getIntent().getAction().equals(PersistentIntentResolvingTest.EXAMPLE_ACTION)) {
-            sendBroadcast(new Intent(CONFIRM_ACTION));
-        }
-        finish();
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity2.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity2.java
deleted file mode 100644
index 65ccb36..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ExampleIntentReceivingActivity2.java
+++ /dev/null
@@ -1,34 +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.deviceowner;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.os.Bundle;
-
-public class ExampleIntentReceivingActivity2 extends Activity {
-    public static final String CONFIRM_ACTION = "com.android.cts.deviceowner.CONFIRM_2";
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        if (getIntent().getAction().equals(PersistentIntentResolvingTest.EXAMPLE_ACTION)) {
-            sendBroadcast(new Intent(CONFIRM_ACTION));
-        }
-        finish();
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java
new file mode 100644
index 0000000..c108d24
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementActivity.java
@@ -0,0 +1,30 @@
+/*
+ * 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.deviceowner;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class KeyManagementActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        finish();
+    }
+}
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
old mode 100644
new mode 100755
index fe2bdda..27fd36f
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/KeyManagementTest.java
@@ -15,11 +15,21 @@
  */
 package com.android.cts.deviceowner;
 
+import static com.android.cts.deviceowner.BaseDeviceOwnerTest.getWho;
 import static com.android.cts.deviceowner.FakeKeys.FAKE_RSA_1;
 
+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;
+import android.test.ActivityInstrumentationTestCase2;
 
 import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.Certificate;
@@ -28,17 +38,38 @@
 import java.security.PrivateKey;
 import java.security.spec.InvalidKeySpecException;
 import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
-public class KeyManagementTest extends BaseDeviceOwnerTest {
+import android.content.ComponentName;
+import android.content.Context;
+
+public class KeyManagementTest extends
+        ActivityInstrumentationTestCase2<KeyManagementActivity> {
+
+    private static final int KEYCHAIN_TIMEOUT_MS = 6 * 60 * 1000;
+    private DevicePolicyManager mDevicePolicyManager;
+
+    public KeyManagementTest() {
+        super(KeyManagementActivity.class);
+    }
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+
+        // Confirm our DeviceOwner is set up
+        mDevicePolicyManager = (DevicePolicyManager)
+                getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
+        BaseDeviceOwnerTest.assertDeviceOwner(mDevicePolicyManager);
+
+        // Enable credential storage by setting a nonempty password.
         assertTrue(mDevicePolicyManager.resetPassword("test", 0));
     }
 
     @Override
     protected void tearDown() throws Exception {
+        // Delete all keys by resetting our password to null, which clears the keystore.
         mDevicePolicyManager.setPasswordQuality(getWho(),
                 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
         mDevicePolicyManager.setPasswordMinimumLength(getWho(), 0);
@@ -47,27 +78,32 @@
     }
 
     public void testCanInstallValidRsaKeypair()
-            throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException {
+            throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException,
+                    KeyChainException, InterruptedException, UnsupportedEncodingException {
         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");
     }
 
-    public void testNullKeyParamsFailGracefully()
+    public void testNullKeyParamsFailPredictably()
             throws CertificateException, NoSuchAlgorithmException, InvalidKeySpecException {
         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);
         try {
-            assertFalse(mDevicePolicyManager.installKeyPair(getWho(), null, cert, alias));
-        } catch (NullPointerException accept) {
-            // Accept either false return value or NPE
+            mDevicePolicyManager.installKeyPair(getWho(), null, cert, alias);
+            fail("Exception should have been thrown for null PrivateKey");
+        } catch (NullPointerException expected) {
         }
         try {
-            assertFalse(mDevicePolicyManager.installKeyPair(getWho(), privKey, null, alias));
-        } catch (NullPointerException accept) {
-            // Accept either false return value or NPE
+            mDevicePolicyManager.installKeyPair(getWho(), privKey, null, alias);
+            fail("Exception should have been thrown for null Certificate");
+        } catch (NullPointerException expected) {
         }
     }
 
@@ -77,21 +113,46 @@
         final PrivateKey privKey = getPrivateKey(FAKE_RSA_1.privateKey, "RSA");
         final Certificate cert = getCertificate(FAKE_RSA_1.caCertificate);
         try {
-            assertFalse(mDevicePolicyManager.installKeyPair(null, privKey, cert, alias));
+            mDevicePolicyManager.installKeyPair(null, privKey, cert, alias);
             fail("Exception should have been thrown for null ComponentName");
-        } catch (SecurityException | NullPointerException expected) {
+        } catch (SecurityException expected) {
         }
     }
 
-    PrivateKey getPrivateKey(final byte[] key, String type)
+    private static PrivateKey getPrivateKey(final byte[] key, String type)
             throws NoSuchAlgorithmException, InvalidKeySpecException {
         return KeyFactory.getInstance(type).generatePrivate(
                 new PKCS8EncodedKeySpec(key));
     }
 
-    Certificate getCertificate(byte[] cert) throws CertificateException {
+    private static Certificate getCertificate(byte[] cert) throws CertificateException {
         return CertificateFactory.getInstance("X.509").generateCertificate(
                 new ByteArrayInputStream(cert));
     }
 
+    private class KeyChainAliasFuture implements KeyChainAliasCallback {
+        private final CountDownLatch mLatch = new CountDownLatch(1);
+        private String mChosenAlias = null;
+
+        @Override
+        public void alias(final String chosenAlias) {
+            mChosenAlias = chosenAlias;
+            mLatch.countDown();
+        }
+
+        public KeyChainAliasFuture(String alias) throws UnsupportedEncodingException {
+            /* Pass the alias as a GET to an imaginary server instead of explicitly asking for it,
+             * to make sure the DPC actually has to do some work to grant the cert.
+             */
+            final Uri uri =
+                    Uri.parse("https://example.org/?alias=" + URLEncoder.encode(alias, "UTF-8"));
+            KeyChain.choosePrivateKeyAlias(getActivity(), this,
+                    null /* keyTypes */, null /* issuers */, uri, null /* alias */);
+        }
+
+        public String get() throws InterruptedException {
+            assertTrue("Chooser timeout", mLatch.await(KEYCHAIN_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+            return mChosenAlias;
+        }
+    };
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
index 69c5bf7..f6f8dbbc 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskTest.java
@@ -18,6 +18,7 @@
 import android.app.Activity;
 import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
@@ -32,12 +33,24 @@
 
     private static final String TEST_PACKAGE = "com.google.android.example.somepackage";
 
+    private static final String UTILITY_ACTIVITY
+            = "com.android.cts.deviceowner.LockTaskUtilityActivity";
+    private static final String UTILITY_ACTIVITY_IF_WHITELISTED
+            = "com.android.cts.deviceowner.LockTaskUtilityActivityIfWhitelisted";
+
+    private static final String RECEIVING_ACTIVITY_PACKAGE_NAME
+            = "com.android.cts.intent.receiver";
+    private static final String RECEIVING_ACTIVITY_NAME
+            = "com.android.cts.intent.receiver.IntentReceiverActivity";
+    private static final String ACTION_JUST_CREATE =
+            "com.android.cts.action.JUST_CREATE";
+
     private static final int ACTIVITY_RESUMED_TIMEOUT_MILLIS = 20000;  // 20 seconds
     private static final int ACTIVITY_RUNNING_TIMEOUT_MILLIS = 10000;  // 10 seconds
     private static final int ACTIVITY_DESTROYED_TIMEOUT_MILLIS = 60000;  // 60 seconds
-
+    private static final int UPDATE_LOCK_TASK_TIMEOUT_MILLIS = 1000; // 1 second
     public static final String RECEIVING_ACTIVITY_CREATED_ACTION
-            = "com.android.cts.deviceowner.RECEIVER_ACTIVITY_STARTED_ACTION";
+            = "com.android.cts.deviceowner.RECEIVING_ACTIVITY_CREATED_ACTION";
     /**
      * The tests below need to keep detailed track of the state of the activity
      * that is started and stopped frequently.  To do this it sends a number of
@@ -102,9 +115,13 @@
     private final Object mReceivingActivityCreatedLock = new Object();
     private Boolean mIntentHandled;
 
+    private ActivityManager mActivityManager;
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[0]);
+        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
         IntentFilter filter = new IntentFilter();
         filter.addAction(LockTaskUtilityActivity.CREATE_ACTION);
         filter.addAction(LockTaskUtilityActivity.DESTROY_ACTION);
@@ -117,10 +134,12 @@
 
     @Override
     protected void tearDown() throws Exception {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[0]);
         mContext.unregisterReceiver(mReceiver);
         super.tearDown();
     }
 
+    // Setting and unsetting the lock task packages.
     public void testSetLockTaskPackages() {
         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { TEST_PACKAGE });
         assertTrue(mDevicePolicyManager.isLockTaskPermitted(TEST_PACKAGE));
@@ -132,45 +151,60 @@
     // Start lock task, verify that ActivityManager knows thats what is going on.
     public void testStartLockTask() {
         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
-        startLockTask();
+        startLockTask(UTILITY_ACTIVITY);
         waitForResume();
 
         // Verify that activity open and activity manager is in lock task.
-        ActivityManager activityManager = (ActivityManager)
-                mContext.getSystemService(Context.ACTIVITY_SERVICE);
-        assertTrue(activityManager.isInLockTaskMode());
+        assertLockTaskModeActive();
         assertTrue(mIsActivityRunning);
         assertTrue(mIsActivityResumed);
 
-        stopAndFinish(activityManager);
+        stopAndFinish(UTILITY_ACTIVITY);
     }
 
     // Verifies that the act of finishing is blocked by ActivityManager in lock task.
     // This results in onDestroy not being called until stopLockTask is called before finish.
     public void testCannotFinish() {
         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
-        startLockTask();
+        startLockTask(UTILITY_ACTIVITY);
 
         // If lock task has not exited then the activity shouldn't actually receive onDestroy.
-        finishAndWait();
-        ActivityManager activityManager = (ActivityManager)
-                mContext.getSystemService(Context.ACTIVITY_SERVICE);
-        assertTrue(activityManager.isInLockTaskMode());
+        finishAndWait(UTILITY_ACTIVITY);
+        assertLockTaskModeActive();
         assertTrue(mIsActivityRunning);
 
-        stopAndFinish(activityManager);
+        stopAndFinish(UTILITY_ACTIVITY);
+    }
+
+    // Verifies that updating the whitelisting during lock task mode finishes the locked task.
+    public void testUpdateWhitelisting() {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+        startLockTask(UTILITY_ACTIVITY);
+
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[0]);
+
+        synchronized (mActivityRunningLock) {
+            try {
+                mActivityRunningLock.wait(UPDATE_LOCK_TASK_TIMEOUT_MILLIS);
+            } catch (InterruptedException e) {
+            }
+        }
+
+        assertLockTaskModeInactive();
+        assertFalse(mIsActivityRunning);
+        assertFalse(mIsActivityResumed);
     }
 
     // This launches an activity that is in the current task.
-    // this should be permitted as a part of lock task (since it isn't a new task).
-    public void testStartActivityWithinTask() {
+    // This should always be permitted as a part of lock task (since it isn't a new task).
+    public void testStartActivity_withinTask() {
         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
-        startLockTask();
+        startLockTask(UTILITY_ACTIVITY);
         waitForResume();
 
         mReceivingActivityWasCreated = false;
-        Intent launchIntent = new Intent(mContext, IntentReceivingActivity.class);
-        Intent lockTaskUtility = getLockTaskUtility();
+        Intent launchIntent = getIntentReceivingActivityIntent(0);
+        Intent lockTaskUtility = getLockTaskUtility(UTILITY_ACTIVITY);
         lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent);
         mContext.startActivity(lockTaskUtility);
 
@@ -181,18 +215,19 @@
             }
             assertTrue(mReceivingActivityWasCreated);
         }
-        stopAndFinish(null);
+        stopAndFinish(UTILITY_ACTIVITY);
     }
 
-    // This launches an activity that is not part of the current task and therefore
-    // should be blocked.
-    public void testCannotStartActivityOutsideTask() {
-        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
-        startLockTask();
+    // This launches a whitelisted activity that is not part of the current task.
+    // This should be permitted as a part of lock task.
+    public void testStartActivity_outsideTaskWhitelisted() {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME,
+                RECEIVING_ACTIVITY_PACKAGE_NAME });
+        startLockTask(UTILITY_ACTIVITY);
         waitForResume();
 
         mReceivingActivityWasCreated = false;
-        Intent launchIntent = new Intent(mContext, IntentReceivingActivity.class);
+        Intent launchIntent = getIntentReceivingActivityIntent(0);
         launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
         mContext.startActivity(launchIntent);
         synchronized (mReceivingActivityCreatedLock) {
@@ -200,9 +235,108 @@
                 mReceivingActivityCreatedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
             } catch (InterruptedException e) {
             }
+            assertTrue(mReceivingActivityWasCreated);
+        }
+        stopAndFinish(UTILITY_ACTIVITY);
+    }
+
+    // This launches a non-whitelisted activity that is not part of the current task.
+    // This should be blocked.
+    public void testStartActivity_outsideTaskNonWhitelisted() {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+        startLockTask(UTILITY_ACTIVITY);
+        waitForResume();
+
+        Intent launchIntent = getIntentReceivingActivityIntent(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(launchIntent);
+        synchronized (mActivityResumedLock) {
+            try {
+                mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
+            } catch (InterruptedException e) {
+            }
             assertFalse(mReceivingActivityWasCreated);
         }
-        stopAndFinish(null);
+        stopAndFinish(UTILITY_ACTIVITY);
+    }
+
+    // Test the lockTaskMode flag for an activity declaring if_whitelisted.
+    // Whitelist the activity and verify that lock task mode is started.
+    public void testManifestArgument_whitelisted() {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+        startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
+        waitForResume();
+
+        assertLockTaskModeActive();
+        assertTrue(mIsActivityRunning);
+        assertTrue(mIsActivityResumed);
+
+        stopAndFinish(UTILITY_ACTIVITY_IF_WHITELISTED);
+    }
+
+    // Test the lockTaskMode flag for an activity declaring if_whitelisted.
+    // Don't whitelist the activity and verify that lock task mode is not started.
+    public void testManifestArgument_nonWhitelisted() {
+        startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
+        waitForResume();
+
+        assertLockTaskModeInactive();
+        assertTrue(mIsActivityRunning);
+        assertTrue(mIsActivityResumed);
+
+        stopAndFinish(UTILITY_ACTIVITY_IF_WHITELISTED);
+    }
+
+    // Test the lockTaskMode flag for an activity declaring if_whitelisted.
+    // An activity locked via manifest argument cannot finish without calling stopLockTask.
+    public void testManifestArgument_cannotFinish() {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+        startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
+        waitForResume();
+
+        // If lock task has not exited then the activity shouldn't actually receive onDestroy.
+        finishAndWait(UTILITY_ACTIVITY_IF_WHITELISTED);
+        assertLockTaskModeActive();
+        assertTrue(mIsActivityRunning);
+
+        stopAndFinish(UTILITY_ACTIVITY_IF_WHITELISTED);
+    }
+
+    // Test the lockTaskMode flag for an activity declaring if_whitelisted.
+    // Verifies that updating the whitelisting during lock task mode finishes the locked task.
+    public void testManifestArgument_updateWhitelisting() {
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
+        startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
+        waitForResume();
+
+        mDevicePolicyManager.setLockTaskPackages(getWho(), new String[0]);
+
+        synchronized (mActivityRunningLock) {
+            try {
+                mActivityRunningLock.wait(UPDATE_LOCK_TASK_TIMEOUT_MILLIS);
+            } catch (InterruptedException e) {
+            }
+        }
+
+        assertLockTaskModeInactive();
+        assertFalse(mIsActivityRunning);
+        assertFalse(mIsActivityResumed);
+    }
+
+    /**
+     * Checks that lock task mode is active and fails the test if it isn't.
+     */
+    private void assertLockTaskModeActive() {
+        assertTrue(mActivityManager.isInLockTaskMode());
+        assertEquals(ActivityManager.LOCK_TASK_MODE_LOCKED,
+                mActivityManager.getLockTaskModeState());
+    }
+
+    /**
+     * Checks that lock task mode is not active and fails the test if it is.
+     */
+    private void assertLockTaskModeInactive() {
+        assertFalse(mActivityManager.isInLockTaskMode());
+        assertEquals(ActivityManager.LOCK_TASK_MODE_NONE, mActivityManager.getLockTaskModeState());
     }
 
     /**
@@ -213,12 +347,10 @@
      * If activityManager is not null then verify that the ActivityManager
      * is no longer in lock task mode.
      */
-    private void stopAndFinish(ActivityManager activityManager) {
-        stopLockTask();
-        finishAndWait();
-        if (activityManager != null) {
-            assertFalse(activityManager.isInLockTaskMode());
-        }
+    private void stopAndFinish(String className) {
+        stopLockTask(className);
+        finishAndWait(className);
+        assertLockTaskModeInactive();
         assertFalse(mIsActivityRunning);
     }
 
@@ -226,9 +358,9 @@
      * Call finish on the LockTaskUtilityActivity and wait for
      * onDestroy to be called.
      */
-    private void finishAndWait() {
+    private void finishAndWait(String className) {
         synchronized (mActivityRunningLock) {
-            finish();
+            finish(className);
             if (mIsActivityRunning) {
                 try {
                     mActivityRunningLock.wait(ACTIVITY_DESTROYED_TIMEOUT_MILLIS);
@@ -256,8 +388,8 @@
     /**
      * Calls startLockTask on the LockTaskUtilityActivity
      */
-    private void startLockTask() {
-        Intent intent = getLockTaskUtility();
+    private void startLockTask(String className) {
+        Intent intent = getLockTaskUtility(className);
         intent.putExtra(LockTaskUtilityActivity.START_LOCK_TASK, true);
         startAndWait(intent);
     }
@@ -265,8 +397,8 @@
     /**
      * Calls stopLockTask on the LockTaskUtilityActivity
      */
-    private void stopLockTask() {
-        Intent intent = getLockTaskUtility();
+    private void stopLockTask(String className) {
+        Intent intent = getLockTaskUtility(className);
         intent.putExtra(LockTaskUtilityActivity.STOP_LOCK_TASK, true);
         startAndWait(intent);
     }
@@ -274,8 +406,8 @@
     /**
      * Calls finish on the LockTaskUtilityActivity
      */
-    private void finish() {
-        Intent intent = getLockTaskUtility();
+    private void finish(String className) {
+        Intent intent = getLockTaskUtility(className);
         intent.putExtra(LockTaskUtilityActivity.FINISH, true);
         startAndWait(intent);
     }
@@ -303,10 +435,19 @@
      *
      * This intent includes the flags to make it act as single top.
      */
-    private Intent getLockTaskUtility() {
+    private Intent getLockTaskUtility(String className) {
         Intent intent = new Intent();
-        intent.setClassName(PACKAGE_NAME, LockTaskUtilityActivity.class.getName());
+        intent.setClassName(PACKAGE_NAME, className);
         intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
         return intent;
     }
+
+    private Intent getIntentReceivingActivityIntent(int flags) {
+        Intent intent = new Intent();
+        intent.setComponent(
+                new ComponentName(RECEIVING_ACTIVITY_PACKAGE_NAME, RECEIVING_ACTIVITY_NAME));
+        intent.setAction(ACTION_JUST_CREATE);
+        intent.setFlags(flags);
+        return intent;
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivityIfWhitelisted.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivityIfWhitelisted.java
new file mode 100644
index 0000000..4cf6efa
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/LockTaskUtilityActivityIfWhitelisted.java
@@ -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.
+ */
+
+package com.android.cts.deviceowner;
+
+public class LockTaskUtilityActivityIfWhitelisted extends LockTaskUtilityActivity {
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PersistentIntentResolvingTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PersistentIntentResolvingTest.java
deleted file mode 100644
index fcef05f..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/PersistentIntentResolvingTest.java
+++ /dev/null
@@ -1,126 +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.deviceowner;
-
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.SystemClock;
-
-public class PersistentIntentResolvingTest extends BaseDeviceOwnerTest {
-    public static final String EXAMPLE_ACTION = "com.android.cts.deviceowner.EXAMPLE_ACTION";
-
-    private boolean mReceivedConfirmationFrom1;
-    private boolean mReceivedConfirmationFrom2;
-    private BroadcastReceiver mReceiver;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(ExampleIntentReceivingActivity1.CONFIRM_ACTION);
-        filter.addAction(ExampleIntentReceivingActivity2.CONFIRM_ACTION);
-
-        mReceiver = new ConfirmReceiver();
-        mContext.registerReceiver(mReceiver, filter);
-
-        synchronized(this) {
-            mReceivedConfirmationFrom1 = false;
-            mReceivedConfirmationFrom2 = false;
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mDevicePolicyManager.clearPackagePersistentPreferredActivities(getWho(), PACKAGE_NAME);
-        mContext.unregisterReceiver(mReceiver);
-
-        super.tearDown();
-    }
-
-    public void testNoPersistentPreferredActivityYieldsResolverActivity() {
-        sendExampleIntent();
-        SystemClock.sleep(5000);
-
-        // Default behavior: intent results in resolver activity, since there are two potential
-        // receivers. No intent is received.
-        synchronized(this) {
-            assertFalse(mReceivedConfirmationFrom1);
-            assertFalse(mReceivedConfirmationFrom2);
-        }
-    }
-
-    public void testAddPersistentPreferredActivityYieldsReceptionAtTarget() {
-        addPersistentPreferredActivity();
-        sendExampleIntent();
-        SystemClock.sleep(5000);
-
-        // Persistent preferred activity present: intent should be received by activity 2.
-        synchronized(this) {
-            assertFalse(mReceivedConfirmationFrom1);
-            assertTrue(mReceivedConfirmationFrom2);
-        }
-    }
-
-    public void testAddAndClearPersistentPreferredActivitiesYieldsResolverActivity() {
-        addPersistentPreferredActivity();
-        mDevicePolicyManager.clearPackagePersistentPreferredActivities(getWho(), PACKAGE_NAME);
-
-        sendExampleIntent();
-        SystemClock.sleep(5000);
-
-        // Default behavior: intent results in resolver activity, since there are two potential
-        // receivers. No intent is received.
-        synchronized(this) {
-            assertFalse(mReceivedConfirmationFrom1);
-            assertFalse(mReceivedConfirmationFrom2);
-        }
-    }
-
-    public class ConfirmReceiver extends BroadcastReceiver {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(ExampleIntentReceivingActivity1.CONFIRM_ACTION)) {
-                synchronized (PersistentIntentResolvingTest.this) {
-                    mReceivedConfirmationFrom1 = true;
-                }
-            } else if (intent.getAction().equals(ExampleIntentReceivingActivity2
-                            .CONFIRM_ACTION)) {
-                synchronized (PersistentIntentResolvingTest.this) {
-                    mReceivedConfirmationFrom2 = true;
-                }
-            }
-        }
-    }
-
-    private void sendExampleIntent() {
-        Intent exampleIntent = new Intent(EXAMPLE_ACTION);
-        exampleIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-        mContext.startActivity(exampleIntent);
-    }
-
-    private void addPersistentPreferredActivity() {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(EXAMPLE_ACTION);
-        filter.addCategory(Intent.CATEGORY_DEFAULT);
-        ComponentName targetComponent = new ComponentName(PACKAGE_NAME,
-                ExampleIntentReceivingActivity2.class.getName());
-        mDevicePolicyManager.addPersistentPreferredActivity(getWho(), filter, targetComponent);
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ScreenCaptureDisabledTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ScreenCaptureDisabledTest.java
deleted file mode 100644
index 59b9773..0000000
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/ScreenCaptureDisabledTest.java
+++ /dev/null
@@ -1,45 +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.deviceowner;
-
-import android.app.admin.DevicePolicyManager;
-
-/**
- * Tests for {@link DevicePolicyManager#setScreenCaptureDisabled} and
- * {@link DevicePolicyManager#getScreenCaptureDisabled} APIs.
- */
-public class ScreenCaptureDisabledTest extends BaseDeviceOwnerTest {
-
-    public void testSetScreenCaptureDisabled_false() throws Exception {
-        mDevicePolicyManager.setScreenCaptureDisabled(getWho(), false);
-        assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(getWho()));
-    }
-
-    public void testSetScreenCaptureDisabled_true() throws Exception {
-        mDevicePolicyManager.setScreenCaptureDisabled(getWho(), true);
-        assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(getWho()));
-    }
-
-    public void testSetScreenCaptureDisabled_anyAdminTrue() {
-        mDevicePolicyManager.setScreenCaptureDisabled(getWho(), true);
-        assertTrue(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
-    }
-
-    public void testSetScreenCaptureDisabled_anyAdminFalse() {
-        mDevicePolicyManager.setScreenCaptureDisabled(getWho(), false);
-        assertFalse(mDevicePolicyManager.getScreenCaptureDisabled(null /* any admin */));
-    }
-}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.java
new file mode 100644
index 0000000..ac96e0b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/SystemUpdatePolicyTest.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 com.android.cts.deviceowner;
+
+import android.app.admin.DevicePolicyManager;
+import android.app.admin.SystemUpdatePolicy;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Build;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test {@link SystemUpdatePolicy}, {@link DevicePolicyManager#setSystemUpdatePolicy} and
+ * {@link DevicePolicyManager#getSystemUpdatePolicy}
+ */
+public class SystemUpdatePolicyTest extends BaseDeviceOwnerTest {
+
+    private static final int TIMEOUT_MS = 20_000;
+
+    private final Semaphore mPolicyChangedSemaphore = new Semaphore(0);
+    private final BroadcastReceiver policyChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context arg0, Intent arg1) {
+            mPolicyChangedSemaphore.release();
+        }
+    };
+    private boolean mHasFeature;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mHasFeature = Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1;
+
+        if (mHasFeature) {
+            IntentFilter filter = new IntentFilter();
+            filter.addAction(DevicePolicyManager.ACTION_SYSTEM_UPDATE_POLICY_CHANGED);
+            mContext.registerReceiver(policyChangedReceiver, filter);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            mContext.unregisterReceiver(policyChangedReceiver);
+            mDevicePolicyManager.setSystemUpdatePolicy(getWho(), null);
+        }
+        super.tearDown();
+    }
+
+    public void testSetEmptytInstallPolicy() {
+        if (!mHasFeature) {
+            return;
+        }
+        testPolicy(null);
+    }
+
+    public void testSetAutomaticInstallPolicy() {
+        if (!mHasFeature) {
+            return;
+        }
+        testPolicy(SystemUpdatePolicy.createAutomaticInstallPolicy());
+    }
+
+    public void testSetWindowedInstallPolicy() {
+        if (!mHasFeature) {
+            return;
+        }
+        testPolicy(SystemUpdatePolicy.createWindowedInstallPolicy(0, 720));
+    }
+
+    public void testSetPostponeInstallPolicy() {
+        if (!mHasFeature) {
+            return;
+        }
+        testPolicy(SystemUpdatePolicy.createPostponeInstallPolicy());
+    }
+
+    public void testShouldFailInvalidWindowPolicy() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        try {
+            SystemUpdatePolicy.createWindowedInstallPolicy(24 * 60 + 1, 720);
+            fail("Invalid window start should not be accepted.");
+        } catch (IllegalArgumentException expected) { }
+        try {
+            SystemUpdatePolicy.createWindowedInstallPolicy(-1, 720);
+            fail("Invalid window start should not be accepted.");
+        } catch (IllegalArgumentException expected) { }
+        try {
+            SystemUpdatePolicy.createWindowedInstallPolicy(0, 24 * 60 + 1);
+            fail("Invalid window end should not be accepted.");
+        } catch (IllegalArgumentException expected) { }
+        try {
+            SystemUpdatePolicy.createWindowedInstallPolicy(0, -1);
+            fail("Invalid window end should not be accepted.");
+        } catch (IllegalArgumentException expected) { }
+    }
+
+    private void testPolicy(SystemUpdatePolicy policy) {
+        mDevicePolicyManager.setSystemUpdatePolicy(getWho(), policy);
+        waitForBroadcast();
+        SystemUpdatePolicy newPolicy = mDevicePolicyManager.getSystemUpdatePolicy();
+        if (policy == null) {
+            assertNull(newPolicy);
+        } else {
+            assertNotNull(newPolicy);
+            assertEquals(policy.toString(), newPolicy.toString());
+            assertEquals(policy.getPolicyType(), newPolicy.getPolicyType());
+            if (policy.getPolicyType() == SystemUpdatePolicy.TYPE_INSTALL_WINDOWED) {
+                assertEquals(policy.getInstallWindowStart(), newPolicy.getInstallWindowStart());
+                assertEquals(policy.getInstallWindowEnd(), newPolicy.getInstallWindowEnd());
+            }
+        }
+    }
+    private void waitForBroadcast() {
+        try {
+            assertTrue("Timeout while waiting for broadcast.",
+                    mPolicyChangedSemaphore.tryAcquire(TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        } catch (InterruptedException e) {
+            fail("Interrupted while waiting for broadcast.");
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java
new file mode 100644
index 0000000..1627961
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/WifiConfigLockdownTest.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.Intent;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.provider.Settings;
+
+import com.android.compatibility.common.util.WifiConfigCreator;
+
+import java.util.List;
+
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_CREATE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_NETID;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_PASSWORD;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SECURITY_TYPE;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SSID;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_REMOVE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.SECURITY_TYPE_NONE;
+import static com.android.compatibility.common.util.WifiConfigCreator.SECURITY_TYPE_WPA;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_UPDATE_WIFI_CONFIG;
+
+/**
+ * Testing WiFi configuration lockdown by Device Owner
+ */
+public class WifiConfigLockdownTest extends BaseDeviceOwnerTest {
+    private static final String TAG = "WifiConfigLockdownTest";
+    private static final String ORIGINAL_DEVICE_OWNER_SSID = "DOCTSTest";
+    private static final String CHANGED_DEVICE_OWNER_SSID = "DOChangedCTSTest";
+    private static final String ORIGINAL_REGULAR_SSID = "RegularCTSTest";
+    private static final String CHANGED_REGULAR_SSID = "RegularChangedCTSTest";
+    private static final String ORIGINAL_PASSWORD = "originalpassword";
+    private WifiManager mWifiManager;
+    private WifiConfigCreator mConfigCreator;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+        mConfigCreator = new WifiConfigCreator(mContext);
+        mDevicePolicyManager.setGlobalSetting(getWho(),
+                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, "1");
+        mConfigCreator.addNetwork(ORIGINAL_DEVICE_OWNER_SSID, true, SECURITY_TYPE_WPA,
+                ORIGINAL_PASSWORD);
+        startRegularActivity(ACTION_CREATE_WIFI_CONFIG, -1, ORIGINAL_REGULAR_SSID,
+                SECURITY_TYPE_WPA, ORIGINAL_PASSWORD);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mDevicePolicyManager.setGlobalSetting(getWho(),
+                Settings.Global.WIFI_DEVICE_OWNER_CONFIGS_LOCKDOWN, "0");
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        for (WifiConfiguration config : configs) {
+            if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID) ||
+                    areMatchingSsids(CHANGED_DEVICE_OWNER_SSID, config.SSID) ||
+                    areMatchingSsids(ORIGINAL_REGULAR_SSID, config.SSID) ||
+                    areMatchingSsids(CHANGED_REGULAR_SSID, config.SSID)) {
+                mWifiManager.removeNetwork(config.networkId);
+            }
+        }
+        super.tearDown();
+    }
+
+    public void testDeviceOwnerCanUpdateConfig() throws Exception {
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        int updateCount = 0;
+        for (WifiConfiguration config : configs) {
+            if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID)) {
+                assertFalse(-1 == mConfigCreator.updateNetwork(config,
+                        CHANGED_DEVICE_OWNER_SSID, true, SECURITY_TYPE_NONE, null));
+                ++updateCount;
+            }
+            if (areMatchingSsids(ORIGINAL_REGULAR_SSID, config.SSID)) {
+                assertFalse(-1 == mConfigCreator.updateNetwork(config,
+                        CHANGED_REGULAR_SSID, true, SECURITY_TYPE_NONE, null));
+                ++updateCount;
+            }
+        }
+        assertEquals("Expected to update two configs: the DO created one and the regular one." +
+                " Instead updated: " + updateCount, 2, updateCount);
+    }
+
+    public void testDeviceOwnerCanRemoveConfig() throws Exception {
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        int removeCount = 0;
+        for (WifiConfiguration config : configs) {
+            if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID) ||
+                    areMatchingSsids(ORIGINAL_REGULAR_SSID, config.SSID)) {
+                assertTrue(mWifiManager.removeNetwork(config.networkId));
+                ++removeCount;
+            }
+        }
+        assertEquals("Expected to remove two configs: the DO created one and the regular one." +
+                " Instead removed: " + removeCount, 2, removeCount);
+    }
+
+    public void testRegularAppCannotUpdateDeviceOwnerConfig() throws Exception {
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        int updateCount = 0;
+        for (WifiConfiguration config : configs) {
+            if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID)) {
+                startRegularActivity(ACTION_UPDATE_WIFI_CONFIG, config.networkId,
+                        CHANGED_DEVICE_OWNER_SSID, SECURITY_TYPE_NONE, null);
+                ++updateCount;
+            }
+        }
+        assertEquals("Expected to have tried to update one config: the DO created one" +
+                " Instead tried to update: " + updateCount, 1, updateCount);
+
+        // Assert nothing has changed
+        configs = mWifiManager.getConfiguredNetworks();
+        int notChangedCount = 0;
+        for (WifiConfiguration config : configs) {
+            assertFalse(areMatchingSsids(CHANGED_DEVICE_OWNER_SSID, config.SSID));
+            if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID)) {
+                ++notChangedCount;
+            }
+        }
+        assertEquals("Expected to see one unchanged config, saw instead: " + notChangedCount, 1,
+                notChangedCount);
+    }
+
+    public void testRegularAppCannotRemoveDeviceOwnerConfig() throws Exception {
+        List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks();
+        int removeCount = 0;
+        for (WifiConfiguration config : configs) {
+            if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID)) {
+                startRegularActivity(ACTION_REMOVE_WIFI_CONFIG, config.networkId,
+                        null, SECURITY_TYPE_NONE, null);
+                ++removeCount;
+            }
+        }
+        assertEquals("Expected to try to remove one config: the DO created one." +
+                " Instead tried to remove: " + removeCount, 1, removeCount);
+
+        // Assert nothing has changed
+        configs = mWifiManager.getConfiguredNetworks();
+        int notChangedCount = 0;
+        for (WifiConfiguration config : configs) {
+            if (areMatchingSsids(ORIGINAL_DEVICE_OWNER_SSID, config.SSID)) {
+                ++notChangedCount;
+            }
+        }
+        assertEquals("Expected to see one unchanged config, saw instead: " + notChangedCount, 1,
+                notChangedCount);
+    }
+
+    private void startRegularActivity(String action, int netId, String ssid, int securityType,
+            String password) throws InterruptedException {
+        Intent createRegularConfig = new Intent(action);
+        createRegularConfig.putExtra(EXTRA_NETID, netId);
+        createRegularConfig.putExtra(EXTRA_SSID, ssid);
+        createRegularConfig.putExtra(EXTRA_SECURITY_TYPE, securityType);
+        createRegularConfig.putExtra(EXTRA_PASSWORD, password);
+        createRegularConfig.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(createRegularConfig);
+
+        // Give some time for the other app to finish the action
+        Thread.sleep(2000);
+    }
+
+    private boolean areMatchingSsids(String s1, String s2) {
+        if (s1 == null || s2 == null) {
+            return false;
+        }
+        return s1.replace("\"", "").equals(s2.replace("\"", ""));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/Android.mk b/hostsidetests/devicepolicy/app/IntentReceiver/Android.mk
index 62c7f28..98cdf52 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/Android.mk
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/Android.mk
@@ -26,6 +26,8 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 ctstestrunner
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml b/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
index 5bbdf76..1512bb2 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/AndroidManifest.xml
@@ -22,15 +22,53 @@
     <uses-permission android:name="com.android.cts.managedprofile.permission.SAMPLE"/>
 
     <application>
+
+        <uses-library android:name="android.test.runner" />
+
         <activity android:name="com.android.cts.intent.receiver.IntentReceiverActivity">
             <intent-filter>
                 <action android:name="com.android.cts.action.COPY_TO_CLIPBOARD" />
                 <action android:name="com.android.cts.action.READ_FROM_URI" />
                 <action android:name="com.android.cts.action.TAKE_PERSISTABLE_URI_PERMISSION" />
                 <action android:name="com.android.cts.action.WRITE_TO_URI" />
+                <action android:name="com.android.cts.action.JUST_CREATE" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
+
+        <activity android:name=".SimpleIntentReceiverActivity" android:exported="true"/>
+
+        <activity-alias android:name=".BrowserActivity"
+            android:targetActivity=".SimpleIntentReceiverActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE"/>
+                <data android:scheme="http"/>
+            </intent-filter>
+        </activity-alias>
+
+        <activity-alias android:name=".AppLinkActivity"
+            android:targetActivity=".SimpleIntentReceiverActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <category android:name="android.intent.category.BROWSABLE"/>
+                <data android:scheme="http" android:host="com.android.cts.intent.receiver"/>
+            </intent-filter>
+        </activity-alias>
+
+        <receiver android:name=".BroadcastIntentReceiver">
+            <intent-filter>
+                <action android:name="android.app.action.DEVICE_OWNER_CHANGED"/>
+            </intent-filter>
+        </receiver>
+
     </application>
 
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:targetPackage="com.android.cts.intent.receiver"
+        android:label="Intent Receiver CTS Tests" />
+
 </manifest>
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/BroadcastIntentReceiver.java b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/BroadcastIntentReceiver.java
new file mode 100644
index 0000000..34b8798
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/BroadcastIntentReceiver.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.cts.intent.receiver;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+
+public class BroadcastIntentReceiver extends BroadcastReceiver {
+
+    static final String OWNER_CHANGED_BROADCAST_RECEIVED_KEY
+         = "owner-changed-broadcast-received";
+
+    static final String PREFERENCES_NAME = "BroadcastIntentReceiver";
+
+    @Override
+    public void onReceive(Context c, Intent i) {
+        SharedPreferences prefs = c.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE);
+        SharedPreferences.Editor editor = prefs.edit();
+        editor.putBoolean(OWNER_CHANGED_BROADCAST_RECEIVED_KEY, true);
+        editor.apply();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
index 294c678..9aa948e 100644
--- a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/IntentReceiverActivity.java
@@ -49,6 +49,11 @@
     private static final String ACTION_WRITE_TO_URI =
             "com.android.cts.action.WRITE_TO_URI";
 
+    private static final String ACTION_JUST_CREATE =
+            "com.android.cts.action.JUST_CREATE";
+
+    public static final String RECEIVING_ACTIVITY_CREATED_ACTION
+            = "com.android.cts.deviceowner.RECEIVING_ACTIVITY_CREATED_ACTION";
 
     private static final String EXTRA_CAUGHT_SECURITY_EXCEPTION = "extra_caught_security_exception";
 
@@ -98,6 +103,8 @@
                 Log.i(TAG, "Caught a IOException while trying to write to " + uri, e);
             }
             setResult(Activity.RESULT_OK, result);
+        } else if (ACTION_JUST_CREATE.equals(action)) {
+            sendBroadcast(new Intent(RECEIVING_ACTIVITY_CREATED_ACTION));
         }
         finish();
     }
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/OwnerChangedBroadcastTest.java b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/OwnerChangedBroadcastTest.java
new file mode 100644
index 0000000..f305e86
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/OwnerChangedBroadcastTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.intent.receiver;
+
+import android.app.admin.DevicePolicyManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.test.InstrumentationTestCase;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.lang.InterruptedException;
+
+public class OwnerChangedBroadcastTest extends InstrumentationTestCase {
+
+    private SharedPreferences mPreferences;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        Context context = getInstrumentation().getTargetContext();
+        mPreferences = context.getSharedPreferences(
+                BroadcastIntentReceiver.PREFERENCES_NAME, Context.MODE_PRIVATE);
+    }
+
+    // We can't just register a broadcast receiver in the code because the broadcast
+    // may have been sent before this test is run. So we have a manifest receiver
+    // listening to the broadcast and writing to a shared preference when it receives it.
+    public void testOwnerChangedBroadcastReceived() throws InterruptedException {
+        final Semaphore mPreferenceChanged = new Semaphore(0);
+
+        OnSharedPreferenceChangeListener listener = new OnSharedPreferenceChangeListener() {
+            @Override
+            public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+                if (key.equals(BroadcastIntentReceiver.OWNER_CHANGED_BROADCAST_RECEIVED_KEY)) {
+                    mPreferenceChanged.release();
+                }
+            }
+        };
+        mPreferences.registerOnSharedPreferenceChangeListener(listener);
+
+        if (mPreferences.getBoolean(BroadcastIntentReceiver.OWNER_CHANGED_BROADCAST_RECEIVED_KEY,
+                false)) {
+            // The broadcast intent has already been received? good
+            // Otherwise, we'll wait until we receive it.
+            return;
+        }
+        // We're relying on background broadcast intents, which can take a long time.
+        assertTrue(mPreferenceChanged.tryAcquire(2, TimeUnit.MINUTES));
+        assertTrue(mPreferences.getBoolean(
+                BroadcastIntentReceiver.OWNER_CHANGED_BROADCAST_RECEIVED_KEY, false));
+    }
+
+    public void testOwnerChangedBroadcastNotReceived() {
+        assertFalse(mPreferences.getBoolean(
+                BroadcastIntentReceiver.OWNER_CHANGED_BROADCAST_RECEIVED_KEY, false));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/SimpleIntentReceiverActivity.java b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/SimpleIntentReceiverActivity.java
new file mode 100644
index 0000000..23755df
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentReceiver/src/com/android/cts/intent/receiver/SimpleIntentReceiverActivity.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.cts.intent.receiver;
+
+import android.app.admin.DevicePolicyManager;
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+import android.os.Bundle;
+
+/**
+ * An activity that receives an intent and returns immediately, indicating its own name and if it is
+ * running in a managed profile.
+ */
+public class SimpleIntentReceiverActivity extends Activity {
+    private static final String TAG = "SimpleIntentReceiverActivity";
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        String className = getIntent().getComponent().getClassName();
+
+        // We try to check if we are in a managed profile or not.
+        // To do this, check if com.android.cts.managedprofile is the profile owner.
+        DevicePolicyManager dpm =
+                (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
+        boolean inManagedProfile = dpm.isProfileOwnerApp("com.android.cts.managedprofile");
+
+        Log.i(TAG, "activity " + className + " started, is in managed profile: "
+                + inManagedProfile);
+        Intent result = new Intent();
+        result.putExtra("extra_receiver_class", className);
+        result.putExtra("extra_in_managed_profile", inManagedProfile);
+        setResult(Activity.RESULT_OK, result);
+        finish();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/IntentSender/Android.mk b/hostsidetests/devicepolicy/app/IntentSender/Android.mk
index e45ec31..e5246c5 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/Android.mk
+++ b/hostsidetests/devicepolicy/app/IntentSender/Android.mk
@@ -26,7 +26,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 ctstestrunner
 
 LOCAL_SDK_VERSION := current
 
diff --git a/hostsidetests/devicepolicy/app/IntentSender/AndroidManifest.xml b/hostsidetests/devicepolicy/app/IntentSender/AndroidManifest.xml
index 070ef40..cc27298 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/IntentSender/AndroidManifest.xml
@@ -52,7 +52,7 @@
     </application>
 
     <instrumentation
-        android:name="android.test.InstrumentationTestRunner"
+        android:name="android.support.test.runner.AndroidJUnitRunner"
         android:targetPackage="com.android.cts.intent.sender"
         android:label="Intent Sender CTS Tests" />
 
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
new file mode 100644
index 0000000..51ff362
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/AppLinkTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.intent.sender;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+public class AppLinkTest extends InstrumentationTestCase {
+
+    private static final String TAG = "AppLinkTest";
+
+    private Context mContext;
+    private IntentSenderActivity mActivity;
+
+    private static final String EXTRA_IN_MANAGED_PROFILE = "extra_in_managed_profile";
+    private static final String EXTRA_RECEIVER_CLASS = "extra_receiver_class";
+    private static final String APP_LINK_ACTIVITY
+            = "com.android.cts.intent.receiver.AppLinkActivity";
+    private static final String BROWSER_ACTIVITY
+            = "com.android.cts.intent.receiver.BrowserActivity";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getTargetContext();
+        mActivity = launchActivity(mContext.getPackageName(), IntentSenderActivity.class, null);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        mActivity.finish();
+        super.tearDown();
+    }
+
+    public void testReceivedByAppLinkActivityInPrimary() throws Exception {
+        checkHttpIntentResult(APP_LINK_ACTIVITY, false);
+    }
+
+    public void testReceivedByAppLinkActivityInManaged() throws Exception {
+        checkHttpIntentResult(APP_LINK_ACTIVITY, true);
+    }
+
+    public void testReceivedByBrowserActivityInManaged() throws Exception {
+        checkHttpIntentResult(BROWSER_ACTIVITY, true);
+    }
+
+    public void testTwoReceivers() {
+        assertNumberOfReceivers(2);
+    }
+
+    public void testThreeReceivers() {
+        assertNumberOfReceivers(3);
+    }
+
+    // Should not be called if there are several possible receivers to the intent
+    // (see getHttpIntent)
+    private void checkHttpIntentResult(String receiverClassName, boolean inManagedProfile)
+            throws Exception {
+        PackageManager pm = mContext.getPackageManager();
+
+        Intent result = mActivity.getResult(getHttpIntent());
+        // 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));
+        assertTrue(result.hasExtra(EXTRA_IN_MANAGED_PROFILE));
+        assertEquals(inManagedProfile, result.getBooleanExtra(EXTRA_IN_MANAGED_PROFILE, false));
+    }
+
+    private void assertNumberOfReceivers(int n) {
+        PackageManager pm = mContext.getPackageManager();
+        assertEquals(n, pm.queryIntentActivities(getHttpIntent(), /* flags = */ 0).size());
+    }
+
+    private Intent getHttpIntent() {
+        Intent i = new Intent(Intent.ACTION_VIEW);
+        i.addCategory(Intent.CATEGORY_BROWSABLE);
+        i.setData(Uri.parse("http://com.android.cts.intent.receiver"));
+        return i;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java
index a5d83db..46fc0c4 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/CopyPasteTest.java
@@ -44,7 +44,7 @@
         super.setUp();
         Context context = getInstrumentation().getTargetContext();
         mActivity = launchActivity(context.getPackageName(), IntentSenderActivity.class, null);
-        mClipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
+        mClipboard = (ClipboardManager) mActivity.getSystemService(Context.CLIPBOARD_SERVICE);
     }
 
     @Override
diff --git a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
index fd421ac..eb64d47 100644
--- a/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
+++ b/hostsidetests/devicepolicy/app/IntentSender/src/com/android/cts/intent/sender/IntentSenderActivity.java
@@ -66,8 +66,12 @@
     }
 
     public Intent getResult(Intent intent) throws Exception {
+        Log.d(TAG, "Sending intent " + intent);
         startActivityForResult(intent, 42);
         final Result result = mResult.poll(30, TimeUnit.SECONDS);
+        if (result != null) {
+            Log.d(TAG, "Result intent: " + result.data);
+        }
         return (result != null) ? result.data : null;
     }
 
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
index 4517ea2..5f645b6 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
+++ b/hostsidetests/devicepolicy/app/LauncherTests/Android.mk
@@ -26,6 +26,8 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
 
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctstestrunner
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml b/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml
index a21b8c2..5ded006 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/LauncherTests/AndroidManifest.xml
@@ -23,7 +23,7 @@
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
                      android:targetPackage="com.android.cts.launchertests"
                      android:label="Launcher Apps CTS Tests"/>
 </manifest>
diff --git a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
index e076fc3..35c16ea 100644
--- a/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
+++ b/hostsidetests/devicepolicy/app/LauncherTests/src/com/android/cts/launchertests/LauncherAppsTests.java
@@ -38,8 +38,8 @@
 import android.os.ResultReceiver;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.test.InstrumentationTestCase;
-import android.test.InstrumentationTestRunner;
+import android.support.test.InstrumentationRegistry;
+import android.test.AndroidTestCase;
 import android.util.Pair;
 
 import java.util.concurrent.Semaphore;
@@ -49,7 +49,7 @@
 /**
  * Tests for LauncherApps service
  */
-public class LauncherAppsTests extends InstrumentationTestCase {
+public class LauncherAppsTests extends AndroidTestCase {
 
     public static final String SIMPLE_APP_PACKAGE = "com.android.cts.launcherapps.simpleapp";
 
@@ -69,7 +69,7 @@
 
     private LauncherApps mLauncherApps;
     private UserHandle mUser;
-    private InstrumentationTestRunner mInstrumentation;
+    private Instrumentation mInstrumentation;
     private Messenger mService;
     private Connection mConnection;
     private Result mResult;
@@ -78,8 +78,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mInstrumentation = (InstrumentationTestRunner) getInstrumentation();
-        Bundle arguments = mInstrumentation.getArguments();
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
+        Bundle arguments = InstrumentationRegistry.getArguments();
         UserManager userManager = (UserManager) mInstrumentation.getContext().getSystemService(
                 Context.USER_SERVICE);
         mUser = getUserHandleArgument(userManager, "testUser", arguments);
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk b/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
index 46e3cf7..b31e74b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/Android.mk
@@ -26,7 +26,8 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner cts-junit
 
-LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4
+LOCAL_STATIC_JAVA_LIBRARIES = android-support-v4 ctstestrunner compatibility-device-util_v2 \
+	ub-uiautomator
 
 LOCAL_SDK_VERSION := current
 
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
index e430785..8e27e72 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/AndroidManifest.xml
@@ -18,10 +18,12 @@
     package="com.android.cts.managedprofile">
 
     <uses-sdk android:minSdkVersion="20"/>
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
+    <uses-permission android:name="android.permission.CAMERA" />
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -34,6 +36,15 @@
                 <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
             </intent-filter>
         </receiver>
+        <receiver
+            android:name="com.android.cts.managedprofile.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=".PrimaryUserFilterSetterActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -41,12 +52,7 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        <activity android:name=".ComponentDisablingActivity" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.DEFAULT"/>
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
+        <activity android:name=".ComponentDisablingActivity" android:exported="true">
         </activity>
         <activity android:name=".ManagedProfileActivity">
             <intent-filter>
@@ -66,7 +72,7 @@
                 <action android:name="com.android.cts.managedprofile.ACTION_TEST_ALL_ACTIVITY" />
             </intent-filter>
         </activity>
-        <activity android:name=".UserRestrictionActivity" >
+        <activity android:name=".SetPolicyActivity" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT"/>
@@ -75,7 +81,7 @@
         <activity android:name=".TestActivity" />
     </application>
 
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
                      android:targetPackage="com.android.cts.managedprofile"
                      android:label="Managed Profile CTS Tests"/>
 </manifest>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
index 8f39ed0..c3d5c98 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/device_admin.xml
@@ -15,5 +15,6 @@
 <device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
     <uses-policies>
         <wipe-data />
+        <disable-camera />
     </uses-policies>
 </device-admin>
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml
new file mode 100644
index 0000000..4bac8a5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/res/xml/primary_device_admin.xml
@@ -0,0 +1,19 @@
+<!-- Copyright (C) 2015 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT 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>
+         <disable-camera />
+    </uses-policies>
+</device-admin>
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 2a54d97..49754d0 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
@@ -19,7 +19,8 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.ComponentName;
 import android.content.Context;
-import android.test.AndroidTestCase;
+import android.support.test.uiautomator.UiDevice;
+import android.test.InstrumentationTestCase;
 
 /**
  * Base class for profile-owner based tests.
@@ -27,7 +28,7 @@
  * This class handles making sure that the test is the profile owner and that it has an active admin
  * registered, so that all tests may assume these are done.
  */
-public class BaseManagedProfileTest extends AndroidTestCase {
+public class BaseManagedProfileTest extends InstrumentationTestCase {
 
     public static class BasicAdminReceiver extends DeviceAdminReceiver {
     }
@@ -36,21 +37,23 @@
             BasicAdminReceiver.class.getPackage().getName(), BasicAdminReceiver.class.getName());
 
     protected DevicePolicyManager mDevicePolicyManager;
+    protected Context mContext;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        mContext = getInstrumentation().getContext();
 
-       mDevicePolicyManager = (DevicePolicyManager)
-               mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
-       assertNotNull(mDevicePolicyManager);
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        assertNotNull(mDevicePolicyManager);
 
-       // TODO: Only check the below if we are running as the profile user. If running under the
-       // user owner, can we check that there is a profile and that the below holds for it? If we
-       // don't want to do these checks every time we could get rid of this class altogether and
-       // just have a single test case running under the profile user that do them.
-       assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
-       assertTrue(mDevicePolicyManager.isProfileOwnerApp(
-               ADMIN_RECEIVER_COMPONENT.getPackageName()));
+        // TODO: Only check the below if we are running as the profile user. If running under the
+        // user owner, can we check that there is a profile and that the below holds for it? If we
+        // don't want to do these checks every time we could get rid of this class altogether and
+        // just have a single test case running under the profile user that do them.
+        assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
+        assertTrue(mDevicePolicyManager.isProfileOwnerApp(
+                ADMIN_RECEIVER_COMPONENT.getPackageName()));
     }
 }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraPolicyTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraPolicyTest.java
new file mode 100644
index 0000000..25e0b94
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraPolicyTest.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.content.Context;
+import android.hardware.camera2.CameraManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.test.AndroidTestCase;
+
+
+public class CameraPolicyTest extends AndroidTestCase {
+
+    protected static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
+
+    private static final String PRIMARY_ADMIN_RECEIVER_TEST_CLASS =
+            MANAGED_PROFILE_PKG + ".PrimaryUserDeviceAdmin";
+
+    private static final String MANAGED_PROFILE_ADMIN_RECEIVER_TEST_CLASS =
+            MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
+
+    private DevicePolicyManager mDevicePolicyManager;
+
+    private CameraManager mCameraManager;
+
+    private ComponentName mPrimaryAdminComponent;
+
+    private ComponentName mManagedProfileAdminComponent;
+
+    private HandlerThread mBackgroundThread;
+
+    /**
+     * A {@link Handler} for running tasks in the background.
+     */
+    private Handler mBackgroundHandler;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mDevicePolicyManager = (DevicePolicyManager) getContext()
+                .getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mCameraManager = (CameraManager) getContext().getSystemService(Context.CAMERA_SERVICE);
+        mPrimaryAdminComponent = new ComponentName(MANAGED_PROFILE_PKG,
+                PRIMARY_ADMIN_RECEIVER_TEST_CLASS);
+        mManagedProfileAdminComponent = new ComponentName(MANAGED_PROFILE_PKG,
+                MANAGED_PROFILE_ADMIN_RECEIVER_TEST_CLASS);
+        startBackgroundThread();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        stopBackgroundThread();
+        super.tearDown();
+    }
+
+    public void testDisableCameraInManagedProfile() throws Exception {
+        mDevicePolicyManager.setCameraDisabled(mManagedProfileAdminComponent, true);
+        assertTrue(mDevicePolicyManager.getCameraDisabled(mManagedProfileAdminComponent));
+        assertTrue(mDevicePolicyManager.getCameraDisabled(null));
+        checkCanOpenCamera(false);
+    }
+
+    public void testEnableCameraInManagedProfile() throws Exception {
+        mDevicePolicyManager.setCameraDisabled(mManagedProfileAdminComponent, false);
+        assertFalse(mDevicePolicyManager.getCameraDisabled(mManagedProfileAdminComponent));
+        assertFalse(mDevicePolicyManager.getCameraDisabled(null));
+        checkCanOpenCamera(true);
+    }
+
+    public void testDisableCameraInPrimaryProfile() throws Exception {
+        mDevicePolicyManager.setCameraDisabled(mPrimaryAdminComponent, true);
+        assertTrue(mDevicePolicyManager.getCameraDisabled(mPrimaryAdminComponent));
+        assertTrue(mDevicePolicyManager.getCameraDisabled(null));
+        checkCanOpenCamera(false);
+    }
+
+    public void testEnableCameraInPrimaryProfile() throws Exception {
+        mDevicePolicyManager.setCameraDisabled(mPrimaryAdminComponent, false);
+        assertFalse(mDevicePolicyManager.getCameraDisabled(mPrimaryAdminComponent));
+        assertFalse(mDevicePolicyManager.getCameraDisabled(null));
+        checkCanOpenCamera(true);
+    }
+
+    public void testIsCameraEnabledInPrimaryProfile() throws Exception {
+        assertFalse(mDevicePolicyManager.getCameraDisabled(mPrimaryAdminComponent));
+        assertFalse(mDevicePolicyManager.getCameraDisabled(null));
+        checkCanOpenCamera(true);
+    }
+
+    public void testIsCameraEnabledInManagedProfile() throws Exception {
+        assertFalse(mDevicePolicyManager.getCameraDisabled(mManagedProfileAdminComponent));
+        assertFalse(mDevicePolicyManager.getCameraDisabled(null));
+        checkCanOpenCamera(true);
+    }
+
+    private void checkCanOpenCamera(boolean canOpen) {
+        boolean successToOpen = CameraUtils
+                .blockUntilOpenCamera(mCameraManager, mBackgroundHandler);
+        assertEquals(canOpen, successToOpen);
+    }
+
+    /**
+     * Starts a background thread and its {@link Handler}.
+     */
+    private void startBackgroundThread() {
+        mBackgroundThread = new HandlerThread("CameraBackground");
+        mBackgroundThread.start();
+        mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
+    }
+
+    /**
+     * Stops the background thread and its {@link Handler}.
+     */
+    private void stopBackgroundThread() {
+        mBackgroundThread.quitSafely();
+        try {
+            mBackgroundThread.join();
+            mBackgroundThread = null;
+            mBackgroundHandler = null;
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraUtils.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraUtils.java
new file mode 100644
index 0000000..516e244
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CameraUtils.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.os.Handler;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A util class to help open camera in a blocking way.
+ */
+class CameraUtils {
+
+    private static final String TAG = "CameraUtils";
+
+    /**
+     * @return true if success to open camera, false otherwise.
+     */
+    public static boolean blockUntilOpenCamera(CameraManager cameraManager, Handler handler) {
+        try {
+            String[] cameraIdList = cameraManager.getCameraIdList();
+            if (cameraIdList == null || cameraIdList.length == 0) {
+                return false;
+            }
+            String cameraId = cameraIdList[0];
+            CameraCallback callback = new CameraCallback();
+            cameraManager.openCamera(cameraId, callback, handler);
+            return callback.waitForResult();
+        } catch (Exception ex) {
+            // No matter what is going wrong, it means fail to open camera.
+            ex.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state.
+     */
+    private static class CameraCallback extends CameraDevice.StateCallback {
+
+        private static final int OPEN_TIMEOUT_SECONDS = 5;
+
+        private final CountDownLatch mLatch = new CountDownLatch(1);
+
+        private AtomicBoolean mResult = new AtomicBoolean(false);
+
+        @Override
+        public void onOpened(CameraDevice cameraDevice) {
+            Log.d(TAG, "open camera successfully");
+            mResult.set(true);
+            if (cameraDevice != null) {
+                cameraDevice.close();
+            }
+            mLatch.countDown();
+        }
+
+        @Override
+        public void onDisconnected(CameraDevice cameraDevice) {
+            Log.d(TAG, "disconnect camera");
+            mLatch.countDown();
+        }
+
+        @Override
+        public void onError(CameraDevice cameraDevice, int error) {
+            Log.e(TAG, "Fail to open camera, error code = " + error);
+            mLatch.countDown();
+        }
+
+        public boolean waitForResult() throws InterruptedException {
+            mLatch.await(OPEN_TIMEOUT_SECONDS, TimeUnit.SECONDS);
+            return mResult.get();
+        }
+    }
+}
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 faee6dc..77ecfe1 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
@@ -28,13 +28,16 @@
 import android.os.Build;
 import android.os.RemoteException;
 import android.provider.ContactsContract;
+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.PhoneLookup;
 import android.provider.ContactsContract.RawContacts;
 import android.test.AndroidTestCase;
 
 import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
@@ -44,15 +47,30 @@
 
     private static final String TEST_ACCOUNT_NAME = "CTS";
     private static final String TEST_ACCOUNT_TYPE = "com.android.cts.test";
+    // details of a sample primary contact
     private static final String PRIMARY_CONTACT_DISPLAY_NAME = "Primary";
     private static final String PRIMARY_CONTACT_PHONE = "00000001";
+    private static final String PRIMARY_CONTACT_EMAIL = "one@primary.com";
+    private static final String PRIMARY_CONTACT_SIP = "foo@sip";
+
+    // details of a sample managed contact
     private static final String MANAGED_CONTACT_DISPLAY_NAME = "Managed";
     private static final String MANAGED_CONTACT_PHONE = "6891999";
+    private static final String MANAGED_CONTACT_EMAIL = "one@managed.com";
+    private static final String MANAGED_CONTACT_SIP = "bar@sip";
+
+    // details of a sample primary and a sample managed contact, with the same phone & email
+    private static final String PRIMARY_CONTACT_DISPLAY_NAME_2 = "PrimaryShared";
+    private static final String MANAGED_CONTACT_DISPLAY_NAME_2 = "ManagedShared";
+    private static final String SHARED_CONTACT_PHONE = "00000002";
+    private static final String SHARED_CONTACT_EMAIL = "shared@shared.com";
+    private static final String SHARED_CONTACT_SIP = "baz@sip";
 
     private DevicePolicyManager mDevicePolicyManager;
     private ContentResolver mResolver;
 
-    private static class ContactInfo {
+    private class ContactInfo { // Not static to access outer world.
+
         String contactId;
         String displayName;
         String photoUri;
@@ -68,8 +86,14 @@
             this.photoId = photoId;
         }
 
-        private boolean hasPhotoUri() {
-            return photoUri != null && photoThumbnailUri != null;
+        private void assertNoPhotoUri() {
+            assertNull(photoUri);
+            assertNull(photoThumbnailUri);
+        }
+
+        private void assertPhotoUrisReadable() throws IOException {
+            assertPhotoUriReadable(photoUri);
+            assertPhotoUriReadable(photoThumbnailUri);
         }
 
         private boolean hasPhotoId() {
@@ -85,72 +109,254 @@
                 .getSystemService(Context.DEVICE_POLICY_SERVICE);
     }
 
-    public void testPrimaryProfilePhoneLookup_insertedAndfound() throws RemoteException,
+    public void testPrimaryProfilePhoneAndEmailLookup_insertedAndfound() throws RemoteException,
             OperationApplicationException, NotFoundException, IOException {
         assertFalse(isManagedProfile());
         // Do not insert to primary contact
-        insertContact(PRIMARY_CONTACT_DISPLAY_NAME, PRIMARY_CONTACT_PHONE, 0);
+        insertContact(PRIMARY_CONTACT_DISPLAY_NAME, PRIMARY_CONTACT_PHONE,
+                PRIMARY_CONTACT_EMAIL, PRIMARY_CONTACT_SIP, 0);
 
         ContactInfo contactInfo = getContactInfo(PRIMARY_CONTACT_PHONE);
         assertNotNull(contactInfo);
         assertEquals(PRIMARY_CONTACT_DISPLAY_NAME, contactInfo.displayName);
-        assertFalse(contactInfo.hasPhotoUri());
+        contactInfo.assertNoPhotoUri();
         assertFalse(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
+
+        contactInfo = getContactInfoFromEmail(PRIMARY_CONTACT_EMAIL);
+        assertNotNull(contactInfo);
+        assertEquals(PRIMARY_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        contactInfo.assertNoPhotoUri();
+        assertFalse(contactInfo.hasPhotoId());
+        assertFalse(isEnterpriseContactId(contactInfo.contactId));
+
     }
 
-    public void testManagedProfilePhoneLookup_insertedAndfound() throws RemoteException,
+    public void testManagedProfilePhoneAndEmailLookup_insertedAndfound() throws RemoteException,
             OperationApplicationException, NotFoundException, IOException {
         assertTrue(isManagedProfile());
         // Insert ic_contact_picture as photo in managed contact
-        insertContact(MANAGED_CONTACT_DISPLAY_NAME, MANAGED_CONTACT_PHONE,
+        insertContact(MANAGED_CONTACT_DISPLAY_NAME,
+                MANAGED_CONTACT_PHONE,
+                MANAGED_CONTACT_EMAIL,
+                MANAGED_CONTACT_SIP,
                 com.android.cts.managedprofile.R.raw.ic_contact_picture);
 
         ContactInfo contactInfo = getContactInfo(MANAGED_CONTACT_PHONE);
         assertNotNull(contactInfo);
         assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
-        assertTrue(contactInfo.hasPhotoUri());
+        contactInfo.assertPhotoUrisReadable();
+        assertTrue(contactInfo.hasPhotoId());
+        assertFalse(isEnterpriseContactId(contactInfo.contactId));
+
+        contactInfo = getContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
+        assertNotNull(contactInfo);
+        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        contactInfo.assertPhotoUrisReadable();
         assertTrue(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
     }
 
-    public void testPrimaryProfileEnterprisePhoneLookup_canAccessEnterpriseContact() {
+    public void testPrimaryProfileDuplicatedPhoneEmailContact_insertedAndfound() throws
+            RemoteException, OperationApplicationException, NotFoundException, IOException {
+        assertFalse(isManagedProfile());
+        insertContact(PRIMARY_CONTACT_DISPLAY_NAME_2,
+                SHARED_CONTACT_PHONE,
+                SHARED_CONTACT_EMAIL,
+                SHARED_CONTACT_SIP,
+                com.android.cts.managedprofile.R.raw.ic_contact_picture);
+
+        ContactInfo contactInfo = getContactInfo(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);
+        assertNotNull(contactInfo);
+        assertEquals(PRIMARY_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
+        contactInfo.assertPhotoUrisReadable();
+        assertTrue(contactInfo.hasPhotoId());
+        assertFalse(isEnterpriseContactId(contactInfo.contactId));
+    }
+
+    public void testManagedProfileDuplicatedPhoneEmailContact_insertedAndfound() throws
+            RemoteException, OperationApplicationException, NotFoundException, IOException {
+        assertTrue(isManagedProfile());
+        insertContact(MANAGED_CONTACT_DISPLAY_NAME_2, SHARED_CONTACT_PHONE,
+                SHARED_CONTACT_EMAIL, SHARED_CONTACT_SIP , 0);
+
+        ContactInfo contactInfo = getContactInfo(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);
+        assertNotNull(contactInfo);
+        assertEquals(MANAGED_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
+        contactInfo.assertNoPhotoUri();
+        assertFalse(contactInfo.hasPhotoId());
+        assertFalse(isEnterpriseContactId(contactInfo.contactId));
+    }
+
+    public void testPrimaryProfileEnterprisePhoneLookup_canAccessEnterpriseContact()
+            throws IOException {
         assertFalse(isManagedProfile());
         ContactInfo contactInfo = getEnterpriseContactInfo(MANAGED_CONTACT_PHONE);
         assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
-        assertTrue(contactInfo.hasPhotoUri());
+        contactInfo.assertPhotoUrisReadable();
         // Cannot get photo id in ENTERPRISE_CONTENT_FILTER_URI
         assertFalse(contactInfo.hasPhotoId());
         assertTrue(isEnterpriseContactId(contactInfo.contactId));
     }
 
-    public void testPrimaryProfilePhoneLookup_canAccessPrimaryContact() {
+    public void testPrimaryProfileEnterpriseSipLookup_canAccessEnterpriseContact()
+            throws IOException {
         assertFalse(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(PRIMARY_CONTACT_PHONE);
-        assertEquals(PRIMARY_CONTACT_DISPLAY_NAME, contactInfo.displayName);
-        assertFalse(contactInfo.hasPhotoUri());
+        ContactInfo contactInfo = getEnterpriseContactInfoFromSipAddress(MANAGED_CONTACT_SIP);
+        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        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));
+    }
+
+    public void testPrimaryProfileEnterpriseEmailLookup_canAccessEnterpriseContact()
+            throws IOException {
+        assertFalse(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
+        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        contactInfo.assertPhotoUrisReadable();
+        // Cannot get photo id in ENTERPRISE_CONTENT_FILTER_URI
+        assertFalse(contactInfo.hasPhotoId());
+        assertTrue(isEnterpriseContactId(contactInfo.contactId));
+    }
+
+    public void testPrimaryProfileEnterprisePhoneLookupDuplicated_canAccessPrimaryContact()
+            throws IOException {
+        assertFalse(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfo(SHARED_CONTACT_PHONE);
+        assertEquals(PRIMARY_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
+        contactInfo.assertPhotoUrisReadable();
+        assertTrue(contactInfo.hasPhotoId());
+        assertFalse(isEnterpriseContactId(contactInfo.contactId));
+    }
+
+    public void testPrimaryProfileEnterpriseEmailLookupDuplicated_canAccessPrimaryContact()
+            throws IOException {
+        assertFalse(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(SHARED_CONTACT_EMAIL);
+        assertEquals(PRIMARY_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
+        contactInfo.assertPhotoUrisReadable();
+        assertTrue(contactInfo.hasPhotoId());
+        assertFalse(isEnterpriseContactId(contactInfo.contactId));
+    }
+
+    public void testManagedProfileEnterprisePhoneLookupDuplicated_canAccessEnterpriseContact() {
+        assertTrue(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfo(SHARED_CONTACT_PHONE);
+        assertEquals(MANAGED_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
+        contactInfo.assertNoPhotoUri();
         assertFalse(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
     }
 
-    public void testManagedProfilePhoneLookup_canAccessEnterpriseContact() {
+    public void testManagedProfileEnterpriseEmailLookupDuplicated_canAccessEnterpriseContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(MANAGED_CONTACT_PHONE);
-        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
-        assertTrue(contactInfo.hasPhotoUri());
-        assertTrue(contactInfo.hasPhotoId());
+        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(SHARED_CONTACT_EMAIL);
+        assertEquals(MANAGED_CONTACT_DISPLAY_NAME_2, contactInfo.displayName);
+        contactInfo.assertNoPhotoUri();
+        assertFalse(contactInfo.hasPhotoId());
         assertFalse(isEnterpriseContactId(contactInfo.contactId));
     }
 
     public void testPrimaryProfilePhoneLookup_canNotAccessEnterpriseContact() {
         assertFalse(isManagedProfile());
+        ContactInfo contactInfo = getContactInfo(MANAGED_CONTACT_PHONE);
+        assertNull(contactInfo);
+    }
+
+    public void testPrimaryProfileEmailLookup_canNotAccessEnterpriseContact() {
+        assertFalse(isManagedProfile());
+        ContactInfo contactInfo = getContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
+        assertNull(contactInfo);
+    }
+
+    public void testPrimaryProfileEnterprisePhoneLookup_canAccessPrimaryContact() {
+        assertFalse(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfo(PRIMARY_CONTACT_PHONE);
+        assertEquals(PRIMARY_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        contactInfo.assertNoPhotoUri();
+        assertFalse(contactInfo.hasPhotoId());
+        assertFalse(isEnterpriseContactId(contactInfo.contactId));
+    }
+
+    public void testPrimaryProfileEnterpriseEmailLookup_canAccessPrimaryContact() {
+        assertFalse(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(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 {
+        assertTrue(isManagedProfile());
         ContactInfo contactInfo = getEnterpriseContactInfo(MANAGED_CONTACT_PHONE);
+        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        contactInfo.assertPhotoUrisReadable();
+        assertTrue(contactInfo.hasPhotoId());
+        assertFalse(isEnterpriseContactId(contactInfo.contactId));
+    }
+
+    public void testManagedProfileEnterpriseEmailLookup_canAccessEnterpriseContact()
+            throws IOException {
+        assertTrue(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
+        assertEquals(MANAGED_CONTACT_DISPLAY_NAME, contactInfo.displayName);
+        contactInfo.assertPhotoUrisReadable();
+        assertTrue(contactInfo.hasPhotoId());
+        assertFalse(isEnterpriseContactId(contactInfo.contactId));
+    }
+
+    public void testManagedProfileEnterprisePhoneLookup_canNotAccessPrimaryContact() {
+        assertTrue(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfo(PRIMARY_CONTACT_PHONE);
+        assertNull(contactInfo);
+    }
+
+    public void testManagedProfileEnterpriseEmailLookup_canNotAccessPrimaryContact() {
+        assertTrue(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(PRIMARY_CONTACT_EMAIL);
         assertNull(contactInfo);
     }
 
     public void testManagedProfilePhoneLookup_canNotAccessPrimaryContact() {
         assertTrue(isManagedProfile());
-        ContactInfo contactInfo = getEnterpriseContactInfo(PRIMARY_CONTACT_PHONE);
+        ContactInfo contactInfo = getContactInfo(PRIMARY_CONTACT_PHONE);
+        assertNull(contactInfo);
+    }
+
+    public void testManagedProfileEmailLookup_canNotAccessPrimaryContact() {
+        assertTrue(isManagedProfile());
+        ContactInfo contactInfo = getContactInfoFromEmail(PRIMARY_CONTACT_EMAIL);
+        assertNull(contactInfo);
+    }
+
+    public void testPrimaryProfileEnterpriseEmailLookup_canNotAccessEnterpriseContact() {
+        assertFalse(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfoFromEmail(MANAGED_CONTACT_EMAIL);
+        assertNull(contactInfo);
+    }
+
+    public void testPrimaryProfileEnterprisePhoneLookup_canNotAccessEnterpriseContact() {
+        assertFalse(isManagedProfile());
+        ContactInfo contactInfo = getEnterpriseContactInfo(MANAGED_CONTACT_PHONE);
         assertNull(contactInfo);
     }
 
@@ -170,14 +376,25 @@
         removeAllTestContactsInProfile();
     }
 
+    public void testSetBluetoothContactSharingDisabled_setterAndGetter() {
+        mDevicePolicyManager.setBluetoothContactSharingDisabled(
+                BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, false);
+        assertFalse(mDevicePolicyManager.getBluetoothContactSharingDisabled(
+                BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT));
+        mDevicePolicyManager.setBluetoothContactSharingDisabled(
+                BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, true);
+        assertTrue(mDevicePolicyManager.getBluetoothContactSharingDisabled(
+                BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT));
+    }
+
     private boolean isManagedProfile() {
         String adminPackage = BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT.getPackageName();
         return mDevicePolicyManager.isProfileOwnerApp(adminPackage);
     }
 
-    private void insertContact(String displayName, String phoneNumber, int photoResId)
-            throws RemoteException,
-            OperationApplicationException, NotFoundException, IOException {
+    private void insertContact(String displayName, String phoneNumber, String email,
+            String sipAddress, int photoResId)
+            throws RemoteException, OperationApplicationException, NotFoundException, IOException {
         ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
         ops.add(ContentProviderOperation
                 .newInsert(ContactsContract.RawContacts.CONTENT_URI)
@@ -205,25 +422,61 @@
                 .withValue(ContactsContract.CommonDataKinds.Phone.TYPE,
                         Phone.TYPE_MOBILE)
                 .build());
+        ops.add(ContentProviderOperation
+                .newInsert(ContactsContract.Data.CONTENT_URI)
+                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+                .withValue(
+                        ContactsContract.Data.MIMETYPE,
+                        ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
+                .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS,
+                        email)
+                .withValue(ContactsContract.CommonDataKinds.Email.TYPE,
+                        Email.TYPE_WORK)
+                .build());
+        ops.add(ContentProviderOperation
+                .newInsert(ContactsContract.Data.CONTENT_URI)
+                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+                .withValue(
+                        ContactsContract.Data.MIMETYPE,
+                        ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
+                .withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS,
+                        sipAddress)
+                .withValue(ContactsContract.CommonDataKinds.SipAddress.TYPE,
+                        ContactsContract.CommonDataKinds.SipAddress.TYPE_WORK)
+                .build());
+
         if (photoResId != 0) {
             InputStream phoneInputStream = mContext.getResources().openRawResource(photoResId);
-            byte[] rawPhoto = getByteFromStream(phoneInputStream);
-            ops.add(ContentProviderOperation
-                    .newInsert(ContactsContract.Data.CONTENT_URI)
-                    .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
-                    .withValue(
-                            ContactsContract.Data.MIMETYPE,
-                            ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
-                    .withValue(Photo.PHOTO, rawPhoto)
-                    .build());
+            try {
+                byte[] rawPhoto = getByteFromStream(phoneInputStream);
+                ops.add(ContentProviderOperation
+                        .newInsert(ContactsContract.Data.CONTENT_URI)
+                        .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+                        .withValue(
+                                ContactsContract.Data.MIMETYPE,
+                                ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE)
+                        .withValue(Photo.PHOTO, rawPhoto)
+                        .build());
+            } finally {
+                phoneInputStream.close();
+            }
         }
 
         mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
     }
 
     private ContactInfo getContactInfoFromUri(Uri phoneLookupUri, String phoneNumber) {
-        Uri uri = Uri.withAppendedPath(phoneLookupUri,
-                Uri.encode(phoneNumber));
+        return getContactInfoFromPhoneLookup(Uri.withAppendedPath(phoneLookupUri,
+                        Uri.encode(phoneNumber)), /* forSip =*/ false);
+    }
+
+    private ContactInfo getContactInfoFromSipUri(Uri phoneLookupUri, String sipAddress) {
+        return getContactInfoFromPhoneLookup(
+                phoneLookupUri.buildUpon().appendEncodedPath(sipAddress).appendQueryParameter(
+                        PhoneLookup.QUERY_PARAMETER_SIP_ADDRESS, "1").build(), /* forSip =*/ true);
+    }
+
+    private ContactInfo getContactInfoFromPhoneLookup(Uri uri, boolean isForSip) {
         Cursor cursor = mResolver.query(uri,
                 new String[] {
                         PhoneLookup._ID, PhoneLookup.DISPLAY_NAME, PhoneLookup.PHOTO_URI,
@@ -245,17 +498,61 @@
         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);
+    }
+
     private void removeAllTestContactsInProfile() {
         ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
         ops.add(ContentProviderOperation.newDelete(RawContacts.CONTENT_URI)
@@ -282,4 +579,18 @@
     private boolean isEnterpriseContactId(String contactId) {
         return ContactsContract.Contacts.isEnterpriseContactId(Long.valueOf(contactId));
     }
+
+    private void assertPhotoUriReadable(String uri) throws IOException {
+        assertNotNull(uri);
+        final InputStream is = mResolver.openInputStream(Uri.parse(uri));
+        try {
+            // Make sure it's readabe.  Don't have to read all content.
+            is.read();
+        } finally {
+            try {
+                is.close();
+            } catch (IOException ignore) {
+            }
+        }
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
index 49001e9..6a63cea 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileUtils.java
@@ -20,9 +20,16 @@
 
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
+import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
 import android.os.UserManager;
 import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.util.List;
 
 /**
  * The methods in this class are not really tests.
@@ -31,6 +38,8 @@
  * device-side methods from the host.
  */
 public class CrossProfileUtils extends AndroidTestCase {
+    private static final String TAG = "CrossProfileUtils";
+
     private static final String ACTION_READ_FROM_URI = "com.android.cts.action.READ_FROM_URI";
 
     private static final String ACTION_WRITE_TO_URI = "com.android.cts.action.WRITE_TO_URI";
@@ -40,8 +49,8 @@
 
     private static String ACTION_COPY_TO_CLIPBOARD = "com.android.cts.action.COPY_TO_CLIPBOARD";
 
-    public void addParentCanAccessManagedFilters() {
-        removeAllFilters();
+    public void testAddParentCanAccessManagedFilters() {
+        testRemoveAllFilters();
 
         final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
@@ -49,8 +58,8 @@
                 DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED);
     }
 
-    public void addManagedCanAccessParentFilters() {
-        removeAllFilters();
+    public void testAddManagedCanAccessParentFilters() {
+        testRemoveAllFilters();
 
         final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
@@ -67,23 +76,37 @@
         return intentFilter;
     }
 
-    public void removeAllFilters() {
+    public void testRemoveAllFilters() {
         final DevicePolicyManager dpm = (DevicePolicyManager) getContext().getSystemService(
                 Context.DEVICE_POLICY_SERVICE);
         dpm.clearCrossProfileIntentFilters(ADMIN_RECEIVER_COMPONENT);
     }
 
-    public void disallowCrossProfileCopyPaste() {
+    public void testDisallowCrossProfileCopyPaste() {
         DevicePolicyManager dpm = (DevicePolicyManager)
                getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
         dpm.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
                 UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
     }
 
-    public void allowCrossProfileCopyPaste() {
+    public void testAllowCrossProfileCopyPaste() {
         DevicePolicyManager dpm = (DevicePolicyManager)
                getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
         dpm.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
                 UserManager.DISALLOW_CROSS_PROFILE_COPY_PASTE);
     }
+
+    // Disables all browsers in current user
+    public void testDisableAllBrowsers() {
+        PackageManager pm = (PackageManager) getContext().getPackageManager();
+        DevicePolicyManager dpm = (DevicePolicyManager)
+               getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
+        Intent webIntent = new Intent(Intent.ACTION_VIEW);
+        webIntent.setData(Uri.parse("http://com.android.cts.intent.receiver"));
+        List<ResolveInfo> ris = pm.queryIntentActivities(webIntent, 0 /* no flags*/);
+        for (ResolveInfo ri : ris) {
+            Log.d(TAG, "Hiding " + ri.activityInfo.packageName);
+            dpm.setApplicationHidden(ADMIN_RECEIVER_COMPONENT, ri.activityInfo.packageName, true);
+        }
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetPrimaryUserTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetPrimaryUserTest.java
new file mode 100644
index 0000000..bb1640b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetPrimaryUserTest.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This class contains tests for cross profile widget providers that are run on the primary users.
+ * The tests connect to a {@link android.appwidget.AppWidgetHost} and check whether the cross
+ * cross-profile widget can / cannot be found from the primary user.
+ * The tests cannot be run independently, but are part of one hostside test.
+ */
+public class CrossProfileWidgetPrimaryUserTest extends AndroidTestCase {
+    private static final String TAG = "CrossProfileWidgetPrimaryUserTest";
+
+    private static final int MSG_RESULT = 0;
+    private static final int MSG_PROVIDER_PRESENT = 1;
+    private static final int MSG_PROVIDER_UPDATES = 2;
+
+    private static final int RESULT_UNKNOWN = 0;
+    private static final int RESULT_PRESENT = 1;
+    private static final int RESULT_NOTPRESENT = 2;
+    private static final int RESULT_INTERRUPTED = 3;
+    private static final int RESULT_TIMEOUT = 4;
+
+    private static final String PACKAGE_EXTRA = "package-extra";
+
+    private Messenger mService;
+    private Connection mConnection;
+    private Result mResult;
+    private Messenger mResultMessenger;
+
+    @Override
+    protected void setUp() throws Exception {
+        final Intent intent = new Intent();
+        intent.setComponent(new ComponentName(CrossProfileWidgetTest.WIDGET_PROVIDER_PKG,
+                CrossProfileWidgetTest.WIDGET_PROVIDER_PKG + ".SimpleAppWidgetHostService"));
+        mConnection = new Connection();
+        getContext().bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+        mConnection.waitForService();
+        mResult = new Result(Looper.getMainLooper());
+        mResultMessenger = new Messenger(mResult);
+    }
+
+    public void testHasCrossProfileWidgetProvider_false() throws Exception {
+        int result = sendMessageToCallbacksService(MSG_PROVIDER_PRESENT,
+                CrossProfileWidgetTest.WIDGET_PROVIDER_PKG);
+        assertEquals(RESULT_NOTPRESENT, result);
+    }
+
+    public void testHostReceivesWidgetUpdates_false() throws Exception {
+        int result = sendMessageToCallbacksService(MSG_PROVIDER_UPDATES,
+                CrossProfileWidgetTest.WIDGET_PROVIDER_PKG);
+        assertEquals(RESULT_NOTPRESENT, result);
+    }
+
+    public void testHasCrossProfileWidgetProvider_true() throws Exception {
+        int result = sendMessageToCallbacksService(MSG_PROVIDER_PRESENT,
+                CrossProfileWidgetTest.WIDGET_PROVIDER_PKG);
+        assertEquals(RESULT_PRESENT, result);
+    }
+
+    public void testHostReceivesWidgetUpdates_true() throws Exception {
+        int result = sendMessageToCallbacksService(MSG_PROVIDER_UPDATES,
+                CrossProfileWidgetTest.WIDGET_PROVIDER_PKG);
+        assertEquals(RESULT_PRESENT, result);
+    }
+
+    private int sendMessageToCallbacksService(int msg, String packageName)
+            throws Exception {
+        Bundle params = new Bundle();
+        params.putString(PACKAGE_EXTRA, packageName);
+
+        Message message = Message.obtain(null, msg, params);
+        message.replyTo = mResultMessenger;
+
+        mService.send(message);
+
+        return mResult.waitForResult();
+    }
+
+    private static class Result extends Handler {
+
+        private final Semaphore mSemaphore = new Semaphore(0);
+        public int result = 0;
+
+        public Result(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == MSG_RESULT) {
+                result = msg.arg1;
+                mSemaphore.release();
+            } else {
+                super.handleMessage(msg);
+            }
+        }
+
+        public int waitForResult() {
+            try {
+                if (mSemaphore.tryAcquire(120, TimeUnit.SECONDS)) {
+                    return result;
+                }
+            } catch (InterruptedException e) {
+                Log.e(TAG, "Interrupted when talking to service", e);
+            }
+            return RESULT_TIMEOUT;
+        }
+    }
+
+    private class Connection implements ServiceConnection {
+        private final Semaphore mSemaphore = new Semaphore(0);
+
+        @Override
+        public void onServiceConnected(ComponentName className, IBinder service) {
+            mService = new Messenger(service);
+            mSemaphore.release();
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName className) {
+            mService = null;
+        }
+
+        public void waitForService() {
+            try {
+                if (mSemaphore.tryAcquire(5, TimeUnit.SECONDS)) {
+                    return;
+                }
+            } catch (InterruptedException e) {
+                Log.e(TAG, "Interrupted when connecting to service", e);
+            }
+            fail("failed to connect to service");
+        }
+    };
+
+}
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
new file mode 100644
index 0000000..085d56f
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/CrossProfileWidgetTest.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.managedprofile;
+
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Process;
+import android.os.UserHandle;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This class contains tests for cross profile widget providers that are run on the managed
+ * profile. Policies are set using {@link SetPolicyActivity} and then verified in these tests.
+ * The tests cannot be run independently, but are part of one hostside test.
+ */
+public class CrossProfileWidgetTest extends BaseManagedProfileTest {
+    static final String WIDGET_PROVIDER_PKG = "com.android.cts.widgetprovider";
+
+    private AppWidgetManager mAppWidgetManager;
+
+    public void setUp() throws Exception {
+        super.setUp();
+        mAppWidgetManager = (AppWidgetManager) mContext.getSystemService(Context.APPWIDGET_SERVICE);
+    }
+
+    /**
+     * This test checks that the widget provider was successfully whitelisted and verifies that
+     * if was added successfully and can be found inside the profile.
+     */
+    public void testCrossProfileWidgetProviderAdded() {
+        List<String> providers = mDevicePolicyManager.getCrossProfileWidgetProviders(
+                ADMIN_RECEIVER_COMPONENT);
+        assertEquals(1, providers.size());
+        assertTrue(providers.contains(WIDGET_PROVIDER_PKG));
+        // check that widget can be found inside the profile
+        assertTrue(containsWidgetProviderPkg(mAppWidgetManager.getInstalledProviders()));
+    }
+
+    /**
+     * This test verifies that the widget provider was successfully removed from the whitelist.
+     */
+    public void testCrossProfileWidgetProviderRemoved() {
+        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()));
+    }
+
+    private boolean containsWidgetProviderPkg(List<AppWidgetProviderInfo> widgets) {
+        for (AppWidgetProviderInfo widget : widgets) {
+            if (WIDGET_PROVIDER_PKG.equals(widget.provider.getPackageName())) {
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileTest.java
index 47ecfcb..e655d7b 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/ManagedProfileTest.java
@@ -21,6 +21,7 @@
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.test.ActivityInstrumentationTestCase2;
+import android.support.test.InstrumentationRegistry;
 
 import static com.android.cts.managedprofile.BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT;
 
@@ -43,6 +44,10 @@
     @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());
         mPackageManager = getActivity().getPackageManager();
         mDevicePolicyManager = (DevicePolicyManager)
                 getActivity().getSystemService(Context.DEVICE_POLICY_SERVICE);
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.java
new file mode 100644
index 0000000..47f8716
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserAdminHelper.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 com.android.cts.managedprofile;
+
+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.
+ */
+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));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserDeviceAdmin.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserDeviceAdmin.java
new file mode 100644
index 0000000..8662daf
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserDeviceAdmin.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.cts.managedprofile;
+
+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/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserTest.java
index 40ff6c5..4163ba8 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/PrimaryUserTest.java
@@ -20,6 +20,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.test.ActivityInstrumentationTestCase2;
+import android.support.test.InstrumentationRegistry;
 
 /**
  * Test for {@link DevicePolicyManager#addCrossProfileIntentFilter} API, for
@@ -43,6 +44,10 @@
     @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());
         mPackageManager = getActivity().getPackageManager();
     }
 
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/SetPolicyActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/SetPolicyActivity.java
new file mode 100644
index 0000000..f59363b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/SetPolicyActivity.java
@@ -0,0 +1,99 @@
+/*
+ * 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.managedprofile;
+
+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;
+
+import com.android.cts.managedprofile.BaseManagedProfileTest;
+
+/**
+ * Simple activity that adds or clears a user restriction 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_PACKAGE_NAME = "extra-package-name";
+    private static final String EXTRA_COMMAND = "extra-command";
+
+    private static final String ADD_RESTRICTION_COMMAND = "add-restriction";
+    private static final String CLEAR_RESTRICTION_COMMAND = "clear-restriction";
+    private static final String ADD_CROSS_PROFILE_WIDGET_COMMAND = "add-cross-profile-widget";
+    private static final String REMOVE_CROSS_PROFILE_WIDGET_COMMAND = "remove-cross-profile-widget";
+
+    @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 (ADD_RESTRICTION_COMMAND.equals(command)) {
+            String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
+            dpm.addUserRestriction(BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
+            Log.i(TAG, "Added user restriction " + restrictionKey
+                    + " for user " + Process.myUserHandle());
+        } else if (CLEAR_RESTRICTION_COMMAND.equals(command)) {
+            String restrictionKey = intent.getStringExtra(EXTRA_RESTRICTION_KEY);
+            dpm.clearUserRestriction(
+                    BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
+            Log.i(TAG, "Cleared user restriction " + restrictionKey
+                    + " for user " + Process.myUserHandle());
+        } else if (ADD_CROSS_PROFILE_WIDGET_COMMAND.equals(command)) {
+            String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
+            dpm.addCrossProfileWidgetProvider(BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT,
+                    packageName);
+            Log.i(TAG, "Added cross-profile widget provider for package:" + packageName
+                    + " for user " + Process.myUserHandle());
+        } else if (REMOVE_CROSS_PROFILE_WIDGET_COMMAND.equals(command)) {
+            String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
+            dpm.removeCrossProfileWidgetProvider(BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT,
+                    packageName);
+            Log.i(TAG, "Removed cross-profile widget provider for package:" + packageName
+                    + " for user " + Process.myUserHandle());
+        } else {
+            Log.e(TAG, "Invalid command: " + command);
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/UserRestrictionActivity.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/UserRestrictionActivity.java
deleted file mode 100644
index e8decf8..0000000
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/UserRestrictionActivity.java
+++ /dev/null
@@ -1,83 +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.managedprofile;
-
-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;
-
-import com.android.cts.managedprofile.BaseManagedProfileTest;
-
-/**
- * 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(BaseManagedProfileTest.ADMIN_RECEIVER_COMPONENT, restrictionKey);
-            Log.i(TAG, "Added user restriction " + restrictionKey
-                    + " for user " + Process.myUserHandle());
-        } else if (CLEAR_COMMAND.equals(command)) {
-            dpm.clearUserRestriction(
-                    BaseManagedProfileTest.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/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.java
new file mode 100644
index 0000000..c4c02e8
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WifiTest.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 com.android.cts.managedprofile;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiManager;
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+
+import java.util.concurrent.TimeUnit;
+
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_CREATE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_REMOVE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_NETID;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SSID;
+
+/**
+ * Driven by the host-side test: com.android.cts.devicepolicy.ManagedProfileTest
+ *
+ * Each of these tests can run independently but have side-effects. The side-effects are used as
+ * building blocks to test various cleanup routines, for example that networks belonging to one
+ * user are deleted
+ */
+public class WifiTest extends AndroidTestCase {
+    private static final String TAG = WifiTest.class.getSimpleName();
+
+    // Unique SSID to use for this test (max SSID length is 32)
+    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_INTERVAL_MS = TimeUnit.SECONDS.toMillis(1);
+
+    // Shared WifiManager instance.
+    private WifiManager mWifiManager;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+    }
+
+    /**
+     * Add a network through the WifiManager API. Verifies that the network was actually added.
+     *
+     * <p>Side effects:
+     * <ul>
+     *   <li>Network with SSID {@link WifiTest#NETWORK_SSID} is created.</li>
+     * </ul>
+     */
+    public void testAddWifiNetwork() throws Exception {
+        Intent intent = new Intent(ACTION_CREATE_WIFI_CONFIG);
+        intent.putExtra(EXTRA_SSID, NETWORK_SSID);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        getContext().startActivity(intent);
+
+        // Wait for configuration to appear in networks list.
+        assertTrue(awaitNetworkState(NETWORK_SSID, /* exists */ true));
+    }
+
+    /**
+     * Remove any network through the WifiManager API with a certain SSID. Verifies that the network
+     * was actually removed.
+     *
+     * <p>Side effects:
+     * <ul>
+     *   <li>If a network with SSID {@link WifiTest#NETWORK_SSID} exists, it will be deleted.</li>
+     * </ul>
+     */
+    public void testRemoveWifiNetworkIfExists() throws Exception {
+        WifiConfiguration config = getNetworkForSsid(NETWORK_SSID);
+
+        if (config != null && config.networkId != -1) {
+            Intent intent = new Intent(ACTION_REMOVE_WIFI_CONFIG);
+            intent.putExtra(EXTRA_NETID, config.networkId);
+            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            getContext().startActivity(intent);
+        }
+
+        assertTrue(awaitNetworkState(NETWORK_SSID, /* exists */ false));
+    }
+
+    /**
+     * Verify that no network exists with a certain SSID.
+     *
+     * <p>The SSID that will be checked for is {@link WifiTest#NETWORK_SSID}.
+     */
+    public void testWifiNetworkDoesNotExist() throws Exception {
+        assertTrue(awaitNetworkState(NETWORK_SSID, /* exists */ false));
+    }
+
+    /**
+     * Block until a network configuration with a certain SSID either exists or ceases to.
+     * Wait for up to {@link WifiTest#UPDATE_TIMEOUT_MS} milliseconds, in increments of
+     * {@link WifiTest#UPDATE_INTERVAL_MS}.
+     */
+    private boolean awaitNetworkState(String ssid, boolean exists) {
+        for (int probes = 0; probes * UPDATE_INTERVAL_MS <= UPDATE_TIMEOUT_MS; probes++) {
+            if (probes != 0) {
+                SystemClock.sleep(UPDATE_INTERVAL_MS);
+            }
+            if ((getNetworkForSsid(ssid) != null) == exists) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Internal method to find an existing {@link WifiConfiguration} with the given SSID.
+     *
+     * @return A {@link WifiConfiguration} matching the specification, or {@code null} if no such
+     *         configuration exists.
+     */
+    private WifiConfiguration getNetworkForSsid(String ssid) {
+        if (!ssid.startsWith("\"")) {
+            ssid = '"' + ssid + '"';
+        }
+        for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) {
+            if (ssid.equals(config.SSID)) {
+                return config;
+            }
+        }
+        return null;
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
index 76a9e44..9646e61 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/WipeDataTest.java
@@ -64,11 +64,4 @@
         // Verify the profile is deleted
         assertFalse(mUserManager.getUserProfiles().contains(currentUser));
     }
-
-    // Override this test inherited from base class, as it will trigger another round of setUp()
-    // which would fail because the managed profile has been removed by this test.
-    @Override
-    @Ignore
-    public void testAndroidTestCaseSetupProperly() {
-    }
 }
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk b/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk
new file mode 100644
index 0000000..e68c884
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 := CtsPackageInstallerApp
+
+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_STATIC_JAVA_LIBRARIES := android-support-v4 ctstestrunner ub-uiautomator
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/AndroidManifest.xml b/hostsidetests/devicepolicy/app/PackageInstaller/AndroidManifest.xml
new file mode 100644
index 0000000..aaa88f2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/AndroidManifest.xml
@@ -0,0 +1,41 @@
+<?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.packageinstaller">
+
+    <uses-sdk android:minSdkVersion="21"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <receiver
+            android:name=".ClearDeviceOwnerTest$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.packageinstaller"
+        android:label="Package Installer CTS Tests" />
+
+</manifest>
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/res/xml/device_admin.xml b/hostsidetests/devicepolicy/app/PackageInstaller/res/xml/device_admin.xml
new file mode 100644
index 0000000..de4a9e1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/res/xml/device_admin.xml
@@ -0,0 +1,3 @@
+<device-admin xmlns:android="http://schemas.android.com/apk/res/android" android:visible="false">
+    <uses-policies />
+</device-admin>
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/BasePackageInstallTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/BasePackageInstallTest.java
new file mode 100644
index 0000000..f994e9e
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/BasePackageInstallTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.packageinstaller;
+
+import android.app.PendingIntent;
+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.IntentSender;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageInstaller;
+import android.content.pm.PackageManager;
+import android.support.test.uiautomator.UiDevice;
+import android.test.InstrumentationTestCase;
+
+import com.android.cts.packageinstaller.ClearDeviceOwnerTest.BasicAdminReceiver;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Base test case for testing PackageInstaller.
+ */
+public class BasePackageInstallTest extends InstrumentationTestCase {
+    protected static final String TEST_APP_LOCATION = "/data/local/tmp/CtsSimpleApp.apk";
+    protected static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
+    protected static final int PACKAGE_INSTALLER_TIMEOUT_MS = 60000; // 60 seconds
+    private static final String ACTION_INSTALL_COMMIT =
+            "com.android.cts.deviceowner.INTENT_PACKAGE_INSTALL_COMMIT";
+    protected static final int PACKAGE_INSTALLER_STATUS_UNDEFINED = -1000;
+    public static final String PACKAGE_NAME = SilentPackageInstallTest.class.getPackage().getName();
+
+    protected Context mContext;
+    protected UiDevice mDevice;
+    protected DevicePolicyManager mDevicePolicyManager;
+    private PackageManager mPackageManager;
+    private PackageInstaller mPackageInstaller;
+    private PackageInstaller.Session mSession;
+    protected boolean mCallbackReceived;
+    protected int mCallbackStatus;
+    protected Intent mCallbackIntent;
+
+    protected final Object mPackageInstallerTimeoutLock = new Object();
+
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            synchronized (mPackageInstallerTimeoutLock) {
+                mCallbackStatus = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,
+                        PACKAGE_INSTALLER_STATUS_UNDEFINED);
+                if (mCallbackStatus == PackageInstaller.STATUS_SUCCESS) {
+                    mContext.unregisterReceiver(this);
+                    assertEquals(TEST_APP_PKG, intent.getStringExtra(
+                            PackageInstaller.EXTRA_PACKAGE_NAME));
+                } else if (mCallbackStatus == PackageInstaller.STATUS_PENDING_USER_ACTION) {
+                    mCallbackIntent = (Intent) intent.getExtras().get(Intent.EXTRA_INTENT);
+                }
+                mCallbackReceived = true;
+                mPackageInstallerTimeoutLock.notify();
+            }
+        }
+    };
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        mDevice = UiDevice.getInstance(getInstrumentation());
+        mDevicePolicyManager = (DevicePolicyManager)
+                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
+        mPackageManager = mContext.getPackageManager();
+        mPackageInstaller = mPackageManager.getPackageInstaller();
+        assertNotNull(mPackageInstaller);
+
+        // check that app is not already installed
+        assertFalse(isPackageInstalled(TEST_APP_PKG));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME) ||
+                mDevicePolicyManager.isProfileOwnerApp(PACKAGE_NAME)) {
+            mDevicePolicyManager.setUninstallBlocked(getWho(), TEST_APP_PKG, false);
+        }
+        try {
+            mContext.unregisterReceiver(mBroadcastReceiver);
+        } catch (IllegalArgumentException e) {
+            // ignore
+        }
+        if (mSession != null) {
+            mSession.abandon();
+        }
+        super.tearDown();
+    }
+
+    protected static ComponentName getWho() {
+        return new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName());
+    }
+
+    protected void assertInstallPackage() throws Exception {
+        assertFalse(isPackageInstalled(TEST_APP_PKG));
+        synchronized (mPackageInstallerTimeoutLock) {
+            mCallbackReceived = false;
+            mCallbackStatus = PACKAGE_INSTALLER_STATUS_UNDEFINED;
+        }
+        installPackage(TEST_APP_LOCATION);
+        synchronized (mPackageInstallerTimeoutLock) {
+            try {
+                mPackageInstallerTimeoutLock.wait(PACKAGE_INSTALLER_TIMEOUT_MS);
+            } catch (InterruptedException e) {
+            }
+            assertTrue(mCallbackReceived);
+            assertEquals(PackageInstaller.STATUS_SUCCESS, mCallbackStatus);
+        }
+        assertTrue(isPackageInstalled(TEST_APP_PKG));
+    }
+
+    protected boolean tryUninstallPackage() throws Exception {
+        assertTrue(isPackageInstalled(TEST_APP_PKG));
+        synchronized (mPackageInstallerTimeoutLock) {
+            mCallbackReceived = false;
+            mCallbackStatus = PACKAGE_INSTALLER_STATUS_UNDEFINED;
+        }
+        mPackageInstaller.uninstall(TEST_APP_PKG, getCommitCallback(0));
+        synchronized (mPackageInstallerTimeoutLock) {
+            try {
+                mPackageInstallerTimeoutLock.wait(PACKAGE_INSTALLER_TIMEOUT_MS);
+            } catch (InterruptedException e) {
+            }
+            assertTrue(mCallbackReceived);
+            return mCallbackStatus == PackageInstaller.STATUS_SUCCESS;
+        }
+    }
+
+    protected void installPackage(String packageLocation) throws Exception {
+        PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
+                PackageInstaller.SessionParams.MODE_FULL_INSTALL);
+        int sessionId = mPackageInstaller.createSession(params);
+        mSession = mPackageInstaller.openSession(sessionId);
+
+        File file = new File(packageLocation);
+        InputStream in = new FileInputStream(file);
+        OutputStream out = mSession.openWrite("SilentPackageInstallerTest", 0, file.length());
+        byte[] buffer = new byte[65536];
+        int c;
+        while ((c = in.read(buffer)) != -1) {
+            out.write(buffer, 0, c);
+        }
+        mSession.fsync(out);
+        out.close();
+        mSession.commit(getCommitCallback(sessionId));
+        mSession.close();
+    }
+
+    private IntentSender getCommitCallback(int sessionId) {
+        // Create an intent-filter and register the receiver
+        String action = ACTION_INSTALL_COMMIT + "." + sessionId;
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(action);
+        mContext.registerReceiver(mBroadcastReceiver, intentFilter);
+
+        // Create a PendingIntent and use it to generate the IntentSender
+        Intent broadcastIntent = new Intent(action);
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(
+                mContext,
+                sessionId,
+                broadcastIntent,
+                PendingIntent.FLAG_UPDATE_CURRENT);
+        return pendingIntent.getIntentSender();
+    }
+
+    protected boolean isPackageInstalled(String packageName) {
+        try {
+            PackageInfo pi = mPackageManager.getPackageInfo(packageName, 0);
+            return pi != null;
+        } catch (PackageManager.NameNotFoundException e) {
+            return false;
+        }
+    }
+}
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
new file mode 100644
index 0000000..a06271b
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ClearDeviceOwnerTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.packageinstaller;
+
+import android.app.admin.DeviceAdminReceiver;
+import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Base class for profile and device based tests.
+ *
+ * This class handles making sure that the test is the profile or device owner and that it has an
+ * active admin registered, so that all tests may assume these are done.
+ */
+public class ClearDeviceOwnerTest extends InstrumentationTestCase {
+
+    public static class BasicAdminReceiver extends DeviceAdminReceiver {
+    }
+
+    public static final String PACKAGE_NAME = BasicAdminReceiver.class.getPackage().getName();
+    public static final ComponentName ADMIN_RECEIVER_COMPONENT = new ComponentName(
+            PACKAGE_NAME, BasicAdminReceiver.class.getName());
+
+    private DevicePolicyManager mDevicePolicyManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mDevicePolicyManager = (DevicePolicyManager)
+                getInstrumentation().getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
+        assertNotNull(mDevicePolicyManager);
+
+        assertTrue(mDevicePolicyManager.isAdminActive(ADMIN_RECEIVER_COMPONENT));
+        assertTrue("App is not device owner", mDevicePolicyManager.isDeviceOwnerApp(PACKAGE_NAME));
+    }
+
+    @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));
+
+        super.tearDown();
+    }
+
+    // This test clears the device owner and active admin on tearDown(). To be called from the host
+    // 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/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java
new file mode 100644
index 0000000..96affae
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/ManualPackageInstallTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.packageinstaller;
+
+import android.content.Intent;
+import android.content.pm.PackageInstaller;
+import android.support.test.uiautomator.By;
+import android.support.test.uiautomator.BySelector;
+import android.support.test.uiautomator.UiObject2;
+import android.support.test.uiautomator.Until;
+
+/**
+ * This class tests manual package install and uninstall by a device owner.
+ */
+public class ManualPackageInstallTest extends BasePackageInstallTest {
+    private static final int AUTOMATOR_WAIT_TIMEOUT = 5000;
+    private static final int INSTALL_WAIT_TIME = 5000;
+
+    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");
+    private static final BySelector INSTALL_BUTTON_SELECTOR = By
+            .clazz(android.widget.Button.class.getName())
+            .res("com.android.packageinstaller:id/ok_button")
+            .pkg("com.google.android.packageinstaller");
+
+    public void testManualInstallSucceeded() throws Exception {
+        assertInstallPackage();
+    }
+
+    public void testManualInstallBlocked() throws Exception {
+        synchronized (mPackageInstallerTimeoutLock) {
+            mCallbackReceived = false;
+            mCallbackStatus = PACKAGE_INSTALLER_STATUS_UNDEFINED;
+        }
+        // Calls the original installPackage which does not click through the install button.
+        super.installPackage(TEST_APP_LOCATION);
+        synchronized (mPackageInstallerTimeoutLock) {
+            try {
+                mPackageInstallerTimeoutLock.wait(PACKAGE_INSTALLER_TIMEOUT_MS);
+            } catch (InterruptedException e) {
+            }
+            assertTrue(mCallbackReceived);
+            assertEquals(PackageInstaller.STATUS_PENDING_USER_ACTION, mCallbackStatus);
+        }
+
+        mCallbackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(mCallbackIntent);
+
+        automateDismissInstallBlockedDialog();
+
+        // Assuming installation is not synchronous, we should wait a while before checking.
+        Thread.sleep(INSTALL_WAIT_TIME);
+        assertFalse(isPackageInstalled(TEST_APP_PKG));
+    }
+
+    @Override
+    protected void installPackage(String packageLocation) throws Exception {
+        super.installPackage(packageLocation);
+
+        synchronized (mPackageInstallerTimeoutLock) {
+            try {
+                mPackageInstallerTimeoutLock.wait(PACKAGE_INSTALLER_TIMEOUT_MS);
+            } catch (InterruptedException e) {
+            }
+            assertTrue(mCallbackReceived);
+            assertEquals(PackageInstaller.STATUS_PENDING_USER_ACTION, mCallbackStatus);
+        }
+
+        // Use a receiver to listen for package install.
+        synchronized (mPackageInstallerTimeoutLock) {
+            mCallbackReceived = false;
+            mCallbackStatus = PACKAGE_INSTALLER_STATUS_UNDEFINED;
+        }
+
+        mCallbackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(mCallbackIntent);
+
+        automateInstallClick();
+    }
+
+    private void automateInstallClick() {
+        mDevice.wait(Until.hasObject(INSTALL_BUTTON_SELECTOR), AUTOMATOR_WAIT_TIMEOUT);
+        UiObject2 button = mDevice.findObject(INSTALL_BUTTON_SELECTOR);
+        assertNotNull("Install button not found", button);
+        button.click();
+    }
+
+    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);
+        // "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);
+        button.click();
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/SilentPackageInstallTest.java b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/SilentPackageInstallTest.java
new file mode 100644
index 0000000..f1a80b9
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/PackageInstaller/src/com/android/cts/packageinstaller/SilentPackageInstallTest.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.cts.packageinstaller;
+
+/**
+ * This class tests silent package install and uninstall by a device owner.
+ */
+public class SilentPackageInstallTest extends BasePackageInstallTest {
+    public void testSilentInstallUninstall() throws Exception {
+        // install the app
+        assertInstallPackage();
+
+        // uninstall the app again
+        assertTrue(tryUninstallPackage());
+        assertFalse(isPackageInstalled(TEST_APP_PKG));
+    }
+
+    public void testUninstallBlocked() throws Exception {
+        // install the app
+        assertInstallPackage();
+
+        mDevicePolicyManager.setUninstallBlocked(getWho(), TEST_APP_PKG, true);
+        assertTrue(mDevicePolicyManager.isUninstallBlocked(getWho(), TEST_APP_PKG));
+        assertTrue(mDevicePolicyManager.isUninstallBlocked(null, TEST_APP_PKG));
+        assertFalse(tryUninstallPackage());
+        assertTrue(isPackageInstalled(TEST_APP_PKG));
+
+        mDevicePolicyManager.setUninstallBlocked(getWho(), TEST_APP_PKG, false);
+        assertFalse(mDevicePolicyManager.isUninstallBlocked(getWho(), TEST_APP_PKG));
+        assertFalse(mDevicePolicyManager.isUninstallBlocked(null, TEST_APP_PKG));
+        assertTrue(tryUninstallPackage());
+        assertFalse(isPackageInstalled(TEST_APP_PKG));
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml
index 848317c..791ae56 100644
--- a/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml
+++ b/hostsidetests/devicepolicy/app/SimpleApp/AndroidManifest.xml
@@ -18,6 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.cts.launcherapps.simpleapp">
 
+    <uses-permission android:name="android.permission.READ_CONTACTS"/>
+
     <application>
         <activity android:name=".SimpleActivity" >
             <intent-filter>
@@ -31,6 +33,18 @@
         <activity android:name=".NonLauncherActivity">
             android:exported="true">
         </activity>
+        <activity android:name=".SimpleActivityImmediateExit" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".SimpleActivityChainExit" >
+            <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/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivityChainExit.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivityChainExit.java
new file mode 100644
index 0000000..49f14da
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivityChainExit.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.cts.launcherapps.simpleapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * This activity starts another activity. Once the other activity gets terminated, this one will
+ * terminate as well.
+ */
+public class SimpleActivityChainExit extends Activity {
+    private static final String TAG = "SimpleActivityChainExit";
+    // This action.
+    private final static String ACTIVITY_CHAIN_EXIT_ACTION =
+            "com.android.cts.launchertests.LauncherAppsTests.CHAIN_EXIT_ACTION";
+    // The action which will be called from here and then immediately exit again.
+    private static final String SIMPLE_ACTIVITY_IMMEDIATE_EXIT = ".SimpleActivityImmediateExit";
+    // Our package name.
+    private static final String SIMPLE_PACKAGE_NAME = "com.android.cts.launcherapps.simpleapp";
+    // Set to true once the activity was paused. Upon next resume the activity gets finished.
+    private boolean mPaused = false;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        Log.i(TAG, "Created SimpleActivityChainExit.");
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        // Start our second activity which will quit itself immediately giving back control.
+        Intent intent = new Intent(Intent.ACTION_MAIN);
+        intent.setClassName(SIMPLE_PACKAGE_NAME,
+                SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_IMMEDIATE_EXIT);
+        startActivityForResult(intent, 0);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        mPaused = true;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        // We ignore any resumes coming in before we got at least paused once.
+        if (mPaused) {
+            // Since we were paused once we can finish ourselves now.
+            finish();
+        }
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        // Notify a listener that this activity will end now.
+        Intent reply = new Intent();
+        reply.setAction(ACTIVITY_CHAIN_EXIT_ACTION);
+        sendBroadcast(reply);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivityImmediateExit.java b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivityImmediateExit.java
new file mode 100644
index 0000000..15cc3f6
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimpleApp/src/com/android/cts/launcherapps/simpleapp/SimpleActivityImmediateExit.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.cts.launcherapps.simpleapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * A simple activity which quits itself immediately after starting.
+ */
+public class SimpleActivityImmediateExit extends Activity {
+    private final static String ACTIVITY_EXIT_ACTION =
+            "com.android.cts.launchertests.LauncherAppsTests.EXIT_ACTION";
+    private static final String TAG = "SimpleActivityImmediateExit";
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        Log.i(TAG, "Created SimpleActivityImmediateExit.");
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        finish();
+    }
+
+    @Override
+    protected void onStop() {
+        super.onStop();
+        // Notify any listener that this activity is about to end now.
+        Intent reply = new Intent();
+        reply.setAction(ACTIVITY_EXIT_ACTION);
+        sendBroadcast(reply);
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk b/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk
new file mode 100644
index 0000000..7460552
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimplePreMApp/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 app is meant for testing device policy permission APIs on legacy apps (pre-M)
+
+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)
+
+LOCAL_PACKAGE_NAME := CtsSimplePreMApp
+
+LOCAL_SDK_VERSION := 21
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/SimplePreMApp/AndroidManifest.xml b/hostsidetests/devicepolicy/app/SimplePreMApp/AndroidManifest.xml
new file mode 100644
index 0000000..85962a1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimplePreMApp/AndroidManifest.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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.launcherapps.simplepremapp">
+
+    <uses-sdk android:targetSdkVersion="21"/>
+
+    <uses-permission android:name="android.permission.READ_CONTACTS"/>
+
+    <application>
+        <activity android:name=".SimpleActivity" >
+            <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/devicepolicy/app/SimplePreMApp/src/com/android/cts/launcherapps/simplepremapp/SimpleActivity.java b/hostsidetests/devicepolicy/app/SimplePreMApp/src/com/android/cts/launcherapps/simplepremapp/SimpleActivity.java
new file mode 100644
index 0000000..0dba719
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/SimplePreMApp/src/com/android/cts/launcherapps/simplepremapp/SimpleActivity.java
@@ -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.
+ */
+
+package com.android.cts.launcherapps.simplepremapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.lang.Override;
+
+/**
+ * A simple activity to install for various users to test LauncherApps.
+ */
+public class SimpleActivity extends Activity {
+
+    private static final String TAG = "SimpleActivity";
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
+    }
+
+}
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/Android.mk b/hostsidetests/devicepolicy/app/WidgetProvider/Android.mk
new file mode 100644
index 0000000..c0e35fa
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/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_PACKAGE_NAME := CtsWidgetProviderApp
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/AndroidManifest.xml b/hostsidetests/devicepolicy/app/WidgetProvider/AndroidManifest.xml
new file mode 100644
index 0000000..77246b5
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/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="com.android.cts.widgetprovider">
+
+    <uses-permission android:name="android.permission.BIND_APPWIDGET"/>
+
+    <application>
+        <receiver android:name="SimpleWidgetProvider" >
+            <intent-filter>
+                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
+            </intent-filter>
+            <meta-data android:name="android.appwidget.provider"
+                       android:resource="@xml/simple_widget_provider_info" />
+        </receiver>
+        <service android:name=".SimpleAppWidgetHostService" >
+            <intent-filter>
+                <action android:name="com.android.cts.widgetprovider.REGISTER_CALLBACK" />
+            </intent-filter>
+        </service>
+    </application>
+
+</manifest>
+
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/res/layout/simple_widget.xml b/hostsidetests/devicepolicy/app/WidgetProvider/res/layout/simple_widget.xml
new file mode 100644
index 0000000..338c57a
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/res/layout/simple_widget.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+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.
+-->
+
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    android:padding="10dip">
+
+    <ImageView
+        android:id="@+id/pkg_icon"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"/>
+
+    <TextView
+        android:id="@+id/pkg_name"
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:layout_centerVertical="true"
+        android:paddingLeft="10dip"
+        android:layout_toRightOf="@id/pkg_icon"/>
+
+</RelativeLayout>
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/res/xml/simple_widget_provider_info.xml b/hostsidetests/devicepolicy/app/WidgetProvider/res/xml/simple_widget_provider_info.xml
new file mode 100644
index 0000000..8a002d2
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/res/xml/simple_widget_provider_info.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.
+-->
+<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
+    android:minWidth="40dp"
+    android:minHeight="40dp"
+    android:resizeMode="horizontal|vertical"
+    android:widgetCategory="home_screen">
+</appwidget-provider>
\ No newline at end of file
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.java b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.java
new file mode 100644
index 0000000..b5b6003
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleAppWidgetHostService.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.cts.widgetprovider;
+
+import android.app.Service;
+import android.appwidget.AppWidgetHost;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+import java.util.List;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Service that acts as AppWidgetHost that listens to onProvidersChanged callbacks and updates the
+ * internally stored list of profile widgets. The service reacts to messages sent from the device
+ * side tests and returns whether the expected widget provider is currently present or not.
+ */
+public class SimpleAppWidgetHostService extends Service {
+    private static final String TAG = "SimpleAppWidgetHostService";
+
+    private static final int MSG_RESULT = 0;
+    private static final int MSG_PROVIDER_PRESENT = 1;
+    private static final int MSG_PROVIDER_UPDATES = 2;
+
+    private static final int RESULT_UNKNOWN = 0;
+    private static final int RESULT_PRESENT = 1;
+    private static final int RESULT_NOT_PRESENT = 2;
+    private static final int RESULT_INTERRUPTED = 3;
+    private static final int RESULT_TIMEOUT = 4;
+
+    public static final String USER_EXTRA = "user-extra";
+    public static final String PACKAGE_EXTRA = "package-extra";
+    public static final String REPLY_EXTRA = "reply-extra";
+
+    private AppWidgetManager mAppWidgetManager;
+    private SimpleAppWidgetHost mAppWidgetHost;
+    private SimpleAppWidgetHostView mAppWidgetHostView;
+    private int mAppWidgetId;
+    private Messenger mMessenger;
+    private UserHandle mUserHandle;
+    private Semaphore mWidgetUpdateSemaphore = new Semaphore(0);
+    private RemoteViews mRemoteViews;
+
+    class CheckHandler extends Handler {
+        public CheckHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            Bundle params = null;
+            if (msg.obj instanceof Bundle) {
+                params = (Bundle) (msg.obj);
+            }
+            try {
+                switch (msg.what) {
+                    case MSG_PROVIDER_PRESENT: {
+                        Log.d(TAG, "MSG_PROVIDER_PRESENT");
+                        int result = RESULT_UNKNOWN;
+                        try {
+                            AppWidgetProviderInfo info = mAppWidgetHost.getProvider(params);
+                            result = (info != null) ? RESULT_PRESENT : RESULT_NOT_PRESENT;
+                            if (info != null) {
+                                bindAppWidget(info);
+                            }
+                        } catch (InterruptedException e) {
+                            result = RESULT_INTERRUPTED;
+                        }
+                        msg.replyTo.send(Message.obtain(null, MSG_RESULT, result
+                                , 0 /* not used */));
+                        break;
+                    }
+                    case MSG_PROVIDER_UPDATES: {
+                        Log.d(TAG, "MSG_PROVIDER_UPDATES");
+                        int result = RESULT_UNKNOWN;
+                        try {
+                            updateWidgetViaWidgetId();
+                            boolean update = waitForUpdate();
+                            result = update ? RESULT_PRESENT : RESULT_NOT_PRESENT;
+                        } catch (InterruptedException e) {
+                            result = RESULT_INTERRUPTED;
+                        }
+                        msg.replyTo.send(Message.obtain(null, MSG_RESULT, result
+                                , 0 /* not used */));
+                        break;
+                    }
+                    default:
+                        super.handleMessage(msg);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to report test status");
+            }
+        }
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        if (intent == null) {
+            return START_NOT_STICKY;
+        }
+        if ("com.android.cts.widgetprovider.REGISTER_CALLBACK".equals(intent.getAction())) {
+            mUserHandle = getUserHandleArgument(this, USER_EXTRA, intent);
+            Log.d(TAG, "mUserHandle=" + mUserHandle);
+            setup();
+        }
+        return START_STICKY;
+    }
+
+    private void setup() {
+        HandlerThread handlerThread = new HandlerThread("Widget test callback handler");
+        handlerThread.start();
+        mMessenger = new Messenger(new CheckHandler(handlerThread.getLooper()));
+        mAppWidgetManager = (AppWidgetManager) getSystemService(Context.APPWIDGET_SERVICE);
+        mAppWidgetHost = new SimpleAppWidgetHost(this, 0);
+        mAppWidgetHost.deleteHost();
+        mAppWidgetHost.startListening();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mMessenger.getBinder();
+    }
+
+    @Override
+    public void onDestroy() {
+        mAppWidgetHost.stopListening();
+        mAppWidgetHost.deleteAppWidgetId(mAppWidgetId);
+        mAppWidgetHost.deleteHost();
+    }
+
+    private void bindAppWidget(AppWidgetProviderInfo info) {
+        mAppWidgetId = mAppWidgetHost.allocateAppWidgetId();
+        Log.d(TAG, "Registering app widget with id:" + mAppWidgetId);
+        mAppWidgetManager.bindAppWidgetIdIfAllowed(mAppWidgetId, mUserHandle, info.provider, null);
+        mAppWidgetHostView = (SimpleAppWidgetHostView) mAppWidgetHost.createView(this,
+                mAppWidgetId, info);
+        mRemoteViews = new RemoteViews(info.provider.getPackageName(), R.layout.simple_widget);
+    }
+
+    private UserHandle getUserHandleArgument(Context context, String key,
+            Intent intent) {
+        UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
+        int serial = intent.getIntExtra(key, 0);
+        Log.d(TAG, "userId=" + serial);
+        return um.getUserForSerialNumber(serial);
+    }
+
+    private void updateWidgetViaWidgetId() {
+        Log.d(TAG, "Forcing widget update via widget id");
+        mWidgetUpdateSemaphore.drainPermits();
+        // trigger a widget update
+        mAppWidgetManager.updateAppWidget(mAppWidgetId, mRemoteViews);
+    }
+
+    private boolean waitForUpdate() throws InterruptedException {
+        // wait for updateAppWidget to arrive
+        return mWidgetUpdateSemaphore.tryAcquire(20, TimeUnit.SECONDS);
+    }
+
+    private class SimpleAppWidgetHost extends AppWidgetHost {
+        private List<AppWidgetProviderInfo> mProviders;
+        private Semaphore mSemaphore = new Semaphore(0);
+        public SimpleAppWidgetHost(Context context, int hostId) {
+            super(context, hostId);
+            synchronized (this) {
+                mProviders = mAppWidgetManager.getInstalledProvidersForProfile(mUserHandle);
+            }
+        }
+
+        @Override
+        protected void onProvidersChanged() {
+            super.onProvidersChanged();
+            Log.d(TAG, "onProvidersChanged callback received");
+            synchronized (this) {
+                mProviders = mAppWidgetManager.getInstalledProvidersForProfile(mUserHandle);
+            }
+            mSemaphore.release();
+        }
+
+        @Override
+        protected AppWidgetHostView onCreateView(Context context, int id, AppWidgetProviderInfo info) {
+            return new SimpleAppWidgetHostView(context);
+        }
+
+        public AppWidgetProviderInfo getProvider(Bundle params) throws InterruptedException {
+            String packageName = params.getString(PACKAGE_EXTRA);
+            while (mSemaphore.tryAcquire(30, TimeUnit.SECONDS)) {
+                mSemaphore.drainPermits();
+                Log.d(TAG, "checking for " + packageName + " " + mUserHandle);
+                synchronized (this) {
+                    for (AppWidgetProviderInfo providerInfo : mProviders) {
+                        if (providerInfo.provider.getPackageName().equals(packageName)) {
+                            Log.d(TAG, "Provider exists " + packageName
+                                    + " for user " + mUserHandle);
+                            return providerInfo;
+                        }
+                    }
+                }
+            }
+            return null;
+        }
+    }
+
+    private class SimpleAppWidgetHostView extends AppWidgetHostView {
+        public SimpleAppWidgetHostView(Context context) {
+            super(context);
+        }
+
+        @Override
+        public void updateAppWidget(RemoteViews views) {
+            super.updateAppWidget(views);
+            Log.d(TAG, "Host view received widget update");
+            mWidgetUpdateSemaphore.release();
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleWidgetProvider.java b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleWidgetProvider.java
new file mode 100644
index 0000000..3bd4530
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WidgetProvider/src/com/android/cts/widgetprovider/SimpleWidgetProvider.java
@@ -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.
+ */
+
+package com.android.cts.widgetprovider;
+
+import android.appwidget.AppWidgetProvider;
+
+/**
+ * A simple widget provider to test cross-profile widgets.
+ */
+public class SimpleWidgetProvider extends AppWidgetProvider {}
diff --git a/hostsidetests/devicepolicy/app/WifiConfigCreator/Android.mk b/hostsidetests/devicepolicy/app/WifiConfigCreator/Android.mk
new file mode 100644
index 0000000..47db44e
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WifiConfigCreator/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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)
+
+LOCAL_PACKAGE_NAME := CtsWifiConfigCreator
+
+LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util_v2
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/hostsidetests/devicepolicy/app/WifiConfigCreator/AndroidManifest.xml b/hostsidetests/devicepolicy/app/WifiConfigCreator/AndroidManifest.xml
new file mode 100644
index 0000000..1b98259
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WifiConfigCreator/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?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.deviceowner.wificonfigcreator">
+
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+
+    <application>
+        <activity android:name=".WifiConfigCreatorActivity"
+            android:exported="true"
+            android:theme="@android:style/Theme.NoDisplay"
+            android:noHistory="true"
+            android:autoRemoveFromRecents="true"
+            android:stateNotNeeded="true" >
+            <intent-filter>
+                <action android:name="com.android.compatibility.common.util.CREATE_WIFI_CONFIG" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="com.android.compatibility.common.util.UPDATE_WIFI_CONFIG" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="com.android.compatibility.common.util.REMOVE_WIFI_CONFIG" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
+
diff --git a/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java b/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.java
new file mode 100644
index 0000000..32d53d1
--- /dev/null
+++ b/hostsidetests/devicepolicy/app/WifiConfigCreator/src/com/android/cts/deviceowner/wificonfigcreator/WifiConfigCreatorActivity.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.cts.deviceowner.wificonfigcreator;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.compatibility.common.util.WifiConfigCreator;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_CREATE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_NETID;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_PASSWORD;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SECURITY_TYPE;
+import static com.android.compatibility.common.util.WifiConfigCreator.EXTRA_SSID;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_REMOVE_WIFI_CONFIG;
+import static com.android.compatibility.common.util.WifiConfigCreator.SECURITY_TYPE_NONE;
+import static com.android.compatibility.common.util.WifiConfigCreator.ACTION_UPDATE_WIFI_CONFIG;
+
+/**
+ * A simple activity to create and manage wifi configurations.
+ */
+public class WifiConfigCreatorActivity extends Activity {
+    private static final String TAG = "WifiConfigCreatorActivity";
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        Log.i(TAG, "Created for user " + android.os.Process.myUserHandle());
+        WifiConfigCreator configCreator = new WifiConfigCreator(this);
+        try {
+            Intent intent = getIntent();
+            String action = intent.getAction();
+            if (ACTION_CREATE_WIFI_CONFIG.equals(action)) {
+                String ssid = intent.getStringExtra(EXTRA_SSID);
+                int securityType = intent.getIntExtra(EXTRA_SECURITY_TYPE, SECURITY_TYPE_NONE);
+                String password = intent.getStringExtra(EXTRA_PASSWORD);
+                configCreator.addNetwork(ssid, false, securityType, password);
+            } else if (ACTION_UPDATE_WIFI_CONFIG.equals(action)) {
+                int netId = intent.getIntExtra(EXTRA_NETID, -1);
+                String ssid = intent.getStringExtra(EXTRA_SSID);
+                int securityType = intent.getIntExtra(EXTRA_SECURITY_TYPE, SECURITY_TYPE_NONE);
+                String password = intent.getStringExtra(EXTRA_PASSWORD);
+                configCreator.updateNetwork(netId, ssid, false, securityType, password);
+            } else if (ACTION_REMOVE_WIFI_CONFIG.equals(action)) {
+                int netId = intent.getIntExtra(EXTRA_NETID, -1);
+                if (netId != -1) {
+                    configCreator.removeNetwork(netId);
+                }
+            } else {
+                Log.i(TAG, "Unknown command: " + action);
+            }
+        } catch (InterruptedException ie) {
+            Log.e(TAG, "Interrupted while changing wifi settings", ie);
+        } finally {
+            finish();
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 5149a74..4fc14e4 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -17,7 +17,6 @@
 package com.android.cts.devicepolicy;
 
 import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.InstrumentationResultParser;
 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner;
@@ -47,15 +46,11 @@
  */
 public class BaseDevicePolicyTest extends DeviceTestCase implements IBuildReceiver {
 
-    protected static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
-    protected static final String MANAGED_PROFILE_APK = "CtsManagedProfileApp.apk";
-    protected static final String ADMIN_RECEIVER_TEST_CLASS =
-            MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
+    private static final String RUNNER = "android.support.test.runner.AndroidJUnitRunner";
 
-    private static final String RUNNER = "android.test.InstrumentationTestRunner";
+    protected CtsBuildHelper mCtsBuild;
 
-    private CtsBuildHelper mCtsBuild;
-
+    private String mPackageVerifier;
     private HashSet<String> mAvailableFeatures;
     protected boolean mHasFeature;
 
@@ -70,6 +65,18 @@
         assertNotNull(mCtsBuild);  // ensure build has been set before test is run.
         mHasFeature = getDevice().getApiLevel() >= 21 /* Build.VERSION_CODES.L */
                 && hasDeviceFeature("android.software.device_admin");
+        // 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");
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // reset the package verifier setting to its original value
+        getDevice().executeShellCommand("settings put global package_verifier_enable "
+                + mPackageVerifier);
+        super.tearDown();
     }
 
     protected void installApp(String fileName)
@@ -91,7 +98,7 @@
         }
 
         final String result = device.executeShellCommand(
-                "pm install --user " + userId + " " + remotePath);
+                "pm install -r --user " + userId + " " + remotePath);
         assertTrue(result, result.contains("\nSuccess"));
     }
 
@@ -103,8 +110,6 @@
         CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
         assertTrue(commandOutput + " expected to start with \"Success:\"",
                 commandOutput.startsWith("Success:"));
-        // Wait 60 seconds for intents generated to be handled.
-        Thread.sleep(60 * 1000);
     }
 
     protected int getMaxNumberOfUsersSupported() throws DeviceNotAvailableException {
@@ -144,12 +149,22 @@
     }
 
     protected void removeUser(int userId) throws Exception  {
+        String stopUserCommand = "am stop-user -w " + 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));
-        // Wait 60 seconds for user to finish being removed.
-        Thread.sleep(60 * 1000);
+    }
+
+    protected void removeTestUsers() throws Exception {
+        for (int userId : listUsers()) {
+            if (userId != 0) {
+                removeUser(userId);
+            }
+        }
     }
 
     /** Returns true if the specified tests passed. Tests are run as user owner. */
@@ -169,9 +184,6 @@
     protected boolean runDeviceTestsAsUser(
             String pkgName, @Nullable String testClassName, String testMethodName, int userId)
             throws DeviceNotAvailableException {
-        if (testClassName.startsWith(".")) {
-            testClassName = pkgName + testClassName;
-        }
         return runDeviceTests(pkgName, testClassName, testMethodName, userId);
     }
 
@@ -184,6 +196,9 @@
     protected boolean runDeviceTests(String pkgName, @Nullable String testClassName,
             @Nullable String testMethodName, @Nullable Integer userId, @Nullable 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,
@@ -280,8 +295,6 @@
         String[] tokens = commandOutput.split("\\s+");
         assertTrue(tokens.length > 0);
         assertEquals("Success:", tokens[0]);
-        // Wait 60 seconds for intents generated to be handled.
-        Thread.sleep(60 * 1000);
         return Integer.parseInt(tokens[tokens.length-1]);
     }
 
@@ -300,7 +313,6 @@
         return Integer.parseInt(tokens[tokens.length-1]);
     }
 
-
     protected int getUserSerialNumber(int userId) throws DeviceNotAvailableException{
         // dumpsys user return lines like "UserInfo{0:Owner:13} serialNo=0"
         String commandOutput = getDevice().executeShellCommand("dumpsys user");
@@ -320,12 +332,50 @@
         return -1;
     }
 
-    protected void setProfileOwner(String componentName, int userId)
+    protected boolean setProfileOwner(String componentName, int userId)
             throws DeviceNotAvailableException {
-        String command = "dpm set-profile-owner '" + componentName + "' " + userId;
+        String command = "dpm set-profile-owner --user " + userId + " '" + componentName + "'";
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+        return commandOutput.startsWith("Success:");
+    }
+
+    protected void setProfileOwnerOrFail(String componentName, int userId)
+            throws Exception {
+        if (!setProfileOwner(componentName, userId)) {
+            removeUser(userId);
+            fail("Failed to set profile owner");
+        }
+    }
+
+    protected void setDeviceAdmin(String componentName) throws DeviceNotAvailableException {
+        String command = "dpm set-active-admin '" + componentName + "'";
         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 boolean setDeviceOwner(String componentName) throws DeviceNotAvailableException {
+        String command = "dpm set-device-owner '" + componentName + "'";
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+        return commandOutput.startsWith("Success:");
+    }
+
+    protected String getSettings(String namespace, String name, int userId)
+            throws DeviceNotAvailableException {
+        String command = "settings --user " + userId + " get " + namespace + " " + name;
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+        return commandOutput.replace("\n", "").replace("\r", "");
+    }
+
+    protected void putSettings(String namespace, String name, String value, int userId)
+            throws DeviceNotAvailableException {
+        String command = "settings --user " + userId + " put " + namespace + " " + name
+                + " " + value;
+        String commandOutput = getDevice().executeShellCommand(command);
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java
index dec8bd2..b106ffd 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseLauncherAppsTest.java
@@ -45,14 +45,6 @@
         getDevice().uninstallPackage(SIMPLE_APP_PKG);
     }
 
-    protected void removeTestUsers() throws Exception {
-        for (int userId : listUsers()) {
-            if (userId != 0) {
-                removeUser(userId);
-            }
-        }
-    }
-
     protected void startCallbackService() throws Exception {
         String command = "am startservice --user 0 "
                 + "-a " + LAUNCHER_TESTS_SUPPORT_PKG + ".REGISTER_CALLBACK "
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.java
new file mode 100644
index 0000000..8d22638
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/CustomDeviceOwnerTest.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.cts.devicepolicy;
+
+import java.io.File;
+import java.lang.Exception;
+
+/**
+ * This class is used for tests that need to do something special before setting the device
+ * owner, so they cannot use the regular DeviceOwnerTest class
+ */
+public class CustomDeviceOwnerTest extends BaseDevicePolicyTest {
+
+    private static final String DEVICE_OWNER_PKG = "com.android.cts.deviceowner";
+    private static final String DEVICE_OWNER_APK = "CtsDeviceOwnerApp.apk";
+    private static final String DEVICE_OWNER_ADMIN
+            = DEVICE_OWNER_PKG + ".BaseDeviceOwnerTest$BasicAdminReceiver";
+    private static final String DEVICE_OWNER_ADMIN_COMPONENT
+            = DEVICE_OWNER_PKG + "/" + DEVICE_OWNER_ADMIN;
+    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";
+
+    private static final String TEST_APP_APK = "CtsSimpleApp.apk";
+    private static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
+    private static final String TEST_APP_LOCATION = "/data/local/tmp/";
+
+    private static final String PACKAGE_INSTALLER_PKG = "com.android.cts.packageinstaller";
+    private static final String PACKAGE_INSTALLER_APK = "CtsPackageInstallerApp.apk";
+    private static final String PACKAGE_INSTALLER_ADMIN_COMPONENT =
+            PACKAGE_INSTALLER_PKG + "/" + ".ClearDeviceOwnerTest$BasicAdminReceiver";
+    private static final String PACKAGE_INSTALLER_CLEAR_DEVICE_OWNER_TEST_CLASS =
+            PACKAGE_INSTALLER_PKG + ".ClearDeviceOwnerTest";
+
+    @Override
+    public void tearDown() throws Exception {
+        if (mHasFeature) {
+            getDevice().uninstallPackage(DEVICE_OWNER_PKG);
+            getDevice().uninstallPackage(DEVICE_AND_PROFILE_OWNER_PKG);
+        }
+
+        super.tearDown();
+    }
+
+    public void testOwnerChangedBroadcast() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installApp(DEVICE_OWNER_APK);
+        try {
+            installApp(INTENT_RECEIVER_APK);
+
+            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));
+
+            // Setting the device owner should send the owner changed broadcast.
+            assertTrue(setDeviceOwner(DEVICE_OWNER_ADMIN_COMPONENT));
+
+            assertTrue(runDeviceTests(INTENT_RECEIVER_PKG, testClass,
+                    "testOwnerChangedBroadcastReceived", 0));
+        } finally {
+            getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
+            assertTrue("Failed to remove device owner.",
+                    runDeviceTests(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR));
+        }
+    }
+
+    public void testCannotSetDeviceOwnerWhenSecondaryUserPresent() throws Exception {
+        if (!mHasFeature || getMaxNumberOfUsersSupported() < 2) {
+            return;
+        }
+        int userId = -1;
+        installApp(DEVICE_OWNER_APK);
+        try {
+            userId = createUser();
+            assertFalse(setDeviceOwner(DEVICE_OWNER_ADMIN_COMPONENT));
+        } finally {
+            removeUser(userId);
+            // make sure we clean up in case we succeeded in setting the device owner
+            runDeviceTests(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR);
+        }
+    }
+
+    public void testCannotSetDeviceOwnerWhenAccountPresent() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installApp(DEVICE_AND_PROFILE_OWNER_APK);
+        try {
+            assertTrue(runDeviceTestsAsUser(DEVICE_AND_PROFILE_OWNER_PKG, ".AccountUtilsTest",
+                    "testAddAccount", 0));
+            assertFalse(setDeviceOwner(DEVICE_AND_PROFILE_OWNER_ADMIN_COMPONENT));
+        } 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));
+        }
+    }
+
+    public void testSilentPackageInstall() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        final File apk = mCtsBuild.getTestApp(TEST_APP_APK);
+        try {
+            // Install the test and prepare the test apk.
+            installApp(PACKAGE_INSTALLER_APK);
+            assertTrue(setDeviceOwner(PACKAGE_INSTALLER_ADMIN_COMPONENT));
+
+            getDevice().uninstallPackage(TEST_APP_PKG);
+            assertTrue(getDevice().pushFile(apk, TEST_APP_LOCATION + apk.getName()));
+            assertTrue(runDeviceTests(PACKAGE_INSTALLER_PKG,
+                    PACKAGE_INSTALLER_PKG + ".SilentPackageInstallTest"));
+        } finally {
+            assertTrue("Failed to remove device owner.", runDeviceTests(PACKAGE_INSTALLER_PKG,
+                    PACKAGE_INSTALLER_CLEAR_DEVICE_OWNER_TEST_CLASS));
+            String command = "rm " + TEST_APP_LOCATION + apk.getName();
+            String commandOutput = getDevice().executeShellCommand(command);
+            getDevice().uninstallPackage(TEST_APP_PKG);
+            getDevice().uninstallPackage(PACKAGE_INSTALLER_PKG);
+        }
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
new file mode 100644
index 0000000..43e6730
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceAndProfileOwnerTest.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.ddmlib.Log.LogLevel;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+
+import java.io.File;
+
+/**
+ * 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.
+ */
+public abstract class DeviceAndProfileOwnerTest extends BaseDevicePolicyTest {
+
+    protected static final String DEVICE_ADMIN_PKG = "com.android.cts.deviceandprofileowner";
+    protected static final String DEVICE_ADMIN_APK = "CtsDeviceAndProfileOwnerApp.apk";
+    protected static final String ADMIN_RECEIVER_TEST_CLASS
+            = ".BaseDeviceAdminTest$BasicAdminReceiver";
+
+    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 CERT_INSTALLER_PKG = "com.android.cts.certinstaller";
+    private static final String CERT_INSTALLER_APK = "CtsCertInstallerApp.apk";
+
+    private static final String TEST_APP_APK = "CtsSimpleApp.apk";
+    private static final String TEST_APP_PKG = "com.android.cts.launcherapps.simpleapp";
+    private static final String TEST_APP_LOCATION = "/data/local/tmp/";
+
+    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 ADD_RESTRICTION_COMMAND = "add-restriction";
+    private static final String CLEAR_RESTRICTION_COMMAND = "clear-restriction";
+
+    // 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.
+    protected int mUserId;
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            getDevice().uninstallPackage(DEVICE_ADMIN_PKG);
+            getDevice().uninstallPackage(PERMISSIONS_APP_PKG);
+            getDevice().uninstallPackage(SIMPLE_PRE_M_APP_PKG);
+            getDevice().uninstallPackage(CERT_INSTALLER_PKG);
+        }
+        super.tearDown();
+    }
+
+    public void testApplicationRestrictions() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeDeviceTestClass(".ApplicationRestrictionsTest");
+    }
+
+    public void testPermissionGrant() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionGrantState");
+    }
+
+    public void testPermissionPolicy() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionPolicy");
+    }
+
+    public void testPermissionMixedPolicies() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionMixedPolicies");
+    }
+
+    public void testPermissionPrompts() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionPrompts");
+    }
+
+    public void testPermissionAppUpdate() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_setDeniedState");
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkDenied");
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkDenied");
+
+        assertNull(getDevice().uninstallPackage(PERMISSIONS_APP_PKG));
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_setGrantedState");
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkGranted");
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkGranted");
+
+        assertNull(getDevice().uninstallPackage(PERMISSIONS_APP_PKG));
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_setAutoDeniedPolicy");
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkDenied");
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkDenied");
+
+        assertNull(getDevice().uninstallPackage(PERMISSIONS_APP_PKG));
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_setAutoGrantedPolicy");
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkGranted");
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionUpdate_checkGranted");
+    }
+
+    public void testPermissionGrantPreMApp() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(SIMPLE_PRE_M_APP_APK, mUserId);
+        executeDeviceTestMethod(".PermissionsTest", "testPermissionGrantStatePreMApp");
+    }
+
+    public void testPersistentIntentResolving() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        executeDeviceTestClass(".PersistentIntentResolvingTest");
+    }
+
+    public void testScreenCaptureDisabled() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // We need to ensure that the policy is deactivated for the device owner case, so making
+        // sure the second test is run even if the first one fails
+        try {
+            executeDeviceTestMethod(".ScreenCaptureDisabledTest",
+                    "testSetScreenCaptureDisabled_true");
+        } finally {
+            executeDeviceTestMethod(".ScreenCaptureDisabledTest",
+                    "testSetScreenCaptureDisabled_false");
+        }
+    }
+
+    public void testApplicationHidden() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        installAppAsUser(PERMISSIONS_APP_APK, mUserId);
+        executeDeviceTestClass(".ApplicationHiddenTest");
+    }
+
+    public void testAccountManagement() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        executeDeviceTestClass(".AccountManagementTest");
+
+        // 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 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";
+        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 */));
+            assertTrue("DelegatedCertInstaller failed", runDeviceTestsAsUser(DEVICE_ADMIN_PKG,
+                    ".DelegatedCertInstallerTest", mUserId));
+        } finally {
+            // Reset lockscreen password and remove device admin.
+            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 */));
+        }
+    }
+
+    public void testPackageInstallUserRestrictions() throws Exception {
+        // UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES
+        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);
+        String unknownSourceSetting = null;
+        try {
+            // Install the test and prepare the test apk.
+            installApp(PACKAGE_INSTALLER_APK);
+            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);
+            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);
+
+            // Enable Unknown sources in Settings.
+            unknownSourceSetting =
+                    getSettings(SECURE_SETTING_CATEGORY, UNKNOWN_SOURCES_SETTING, mUserId);
+            putSettings(SECURE_SETTING_CATEGORY, UNKNOWN_SOURCES_SETTING, "1", mUserId);
+            assertEquals("1",
+                    getSettings(SECURE_SETTING_CATEGORY, UNKNOWN_SOURCES_SETTING, mUserId));
+            assertTrue(runDeviceTestsAsUser(PACKAGE_INSTALLER_PKG, ".ManualPackageInstallTest",
+                    "testManualInstallSucceeded", mUserId));
+        } finally {
+            String command = "rm " + TEST_APP_LOCATION + apk.getName();
+            getDevice().executeShellCommand(command);
+            getDevice().uninstallPackage(TEST_APP_PKG);
+            getDevice().uninstallPackage(PACKAGE_INSTALLER_APK);
+            if (unknownSourceSetting != null) {
+                putSettings(SECURE_SETTING_CATEGORY, UNKNOWN_SOURCES_SETTING, unknownSourceSetting,
+                        mUserId);
+            }
+        }
+    }
+
+    protected void executeDeviceTestClass(String className) throws Exception {
+        assertTrue(runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, mUserId));
+    }
+
+    protected void executeDeviceTestMethod(String className, String testName) throws Exception {
+        assertTrue(runDeviceTestsAsUser(DEVICE_ADMIN_PKG, className, testName, mUserId));
+    }
+
+    private void changeUserRestrictionForUser(String key, String command, 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";
+        String commandOutput = getDevice().executeShellCommand(adbCommand);
+        CLog.logAndDisplay(LogLevel.INFO,
+                "Output for command " + adbCommand + ": " + commandOutput);
+        assertTrue("Command was expected to succeed " + commandOutput,
+                commandOutput.contains("Status: ok"));
+    }
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
index b84e9fe..96ca469 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/DeviceOwnerTest.java
@@ -16,10 +16,6 @@
 
 package com.android.cts.devicepolicy;
 
-import com.android.ddmlib.Log.LogLevel;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-
 /**
  * Set of tests for Device Owner use cases.
  */
@@ -28,6 +24,18 @@
     private static final String DEVICE_OWNER_PKG = "com.android.cts.deviceowner";
     private static final String DEVICE_OWNER_APK = "CtsDeviceOwnerApp.apk";
 
+    private static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
+    private static final String MANAGED_PROFILE_APK = "CtsManagedProfileApp.apk";
+    private static final String MANAGED_PROFILE_ADMIN =
+            MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$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 WIFI_CONFIG_CREATOR_PKG =
+            "com.android.cts.deviceowner.wificonfigcreator";
+    private static final String WIFI_CONFIG_CREATOR_APK = "CtsWifiConfigCreator.apk";
+
     private static final String ADMIN_RECEIVER_TEST_CLASS =
             DEVICE_OWNER_PKG + ".BaseDeviceOwnerTest$BasicAdminReceiver";
     private static final String CLEAR_DEVICE_OWNER_TEST_CLASS =
@@ -38,7 +46,8 @@
         super.setUp();
         if (mHasFeature) {
             installApp(DEVICE_OWNER_APK);
-            setDeviceOwner(DEVICE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS);
+            assertTrue("Failed to set device owner",
+                    setDeviceOwner(DEVICE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
         }
     }
 
@@ -53,10 +62,6 @@
         super.tearDown();
     }
 
-    public void testApplicationRestrictions() throws Exception {
-        executeDeviceOwnerTest("ApplicationRestrictionsTest");
-    }
-
     public void testCaCertManagement() throws Exception {
         executeDeviceOwnerTest("CaCertManagementTest");
     }
@@ -70,15 +75,44 @@
     }
 
     public void testLockTask() throws Exception {
-        executeDeviceOwnerTest("LockTaskTest");
+        try {
+            installApp(INTENT_RECEIVER_APK);
+            executeDeviceOwnerTest("LockTaskTest");
+        } finally {
+            getDevice().uninstallPackage(INTENT_RECEIVER_PKG);
+        }
     }
 
-    public void testPersistentIntentResolving() throws Exception {
-        executeDeviceOwnerTest("PersistentIntentResolvingTest");
+    public void testSystemUpdatePolicy() throws Exception {
+        executeDeviceOwnerTest("SystemUpdatePolicyTest");
     }
 
-    public void testScreenCaptureDisabled() throws Exception {
-        executeDeviceOwnerTest("ScreenCaptureDisabledTest");
+    public void testWifiConfigLockdown() throws Exception {
+        final boolean hasWifi = hasDeviceFeature("android.hardware.wifi");
+        if (hasWifi && mHasFeature) {
+            try {
+                installApp(WIFI_CONFIG_CREATOR_APK);
+                executeDeviceOwnerTest("WifiConfigLockdownTest");
+            } finally {
+                getDevice().uninstallPackage(WIFI_CONFIG_CREATOR_PKG);
+            }
+        }
+    }
+
+    public void testCannotSetDeviceOwnerAgain() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // verify that we can't set the same admin receiver as device owner again
+        assertFalse(setDeviceOwner(DEVICE_OWNER_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
+
+        // 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));
+        } finally {
+            getDevice().uninstallPackage(MANAGED_PROFILE_PKG);
+        }
     }
 
     private void executeDeviceOwnerTest(String testClassName) throws Exception {
@@ -88,13 +122,4 @@
         String testClass = DEVICE_OWNER_PKG + "." + testClassName;
         assertTrue(testClass + " failed.", runDeviceTests(DEVICE_OWNER_PKG, testClass));
     }
-
-    private void setDeviceOwner(String componentName) throws DeviceNotAvailableException {
-        String command = "dpm set-device-owner '" + componentName + "'";
-        String commandOutput = getDevice().executeShellCommand(command);
-        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": " + commandOutput);
-        assertTrue(commandOutput + " expected to start with \"Success:\"",
-                commandOutput.startsWith("Success:"));
-    }
-
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
index 43f1f5a..bb26df1 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/LauncherAppsProfileTest.java
@@ -25,6 +25,11 @@
  */
 public class LauncherAppsProfileTest extends BaseLauncherAppsTest {
 
+    private static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
+    private static final String MANAGED_PROFILE_APK = "CtsManagedProfileApp.apk";
+    private static final String ADMIN_RECEIVER_TEST_CLASS =
+            MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
+
     private int mProfileUserId;
     private int mProfileSerialNumber;
     private int mMainUserSerialNumber;
@@ -39,7 +44,8 @@
             // Create a managed profile
             mProfileUserId = createManagedProfile();
             installApp(MANAGED_PROFILE_APK);
-            setProfileOwner(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mProfileUserId);
+            setProfileOwnerOrFail(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS,
+                    mProfileUserId);
             mProfileSerialNumber = getUserSerialNumber(mProfileUserId);
             mMainUserSerialNumber = getUserSerialNumber(0);
             startUser(mProfileUserId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index f8fa222..6dc47e6 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -20,6 +20,8 @@
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.log.LogUtil.CLog;
 
+import junit.framework.AssertionFailedError;
+
 /**
  * Set of tests for Managed Profile use cases.
  */
@@ -28,19 +30,41 @@
     private static final String MANAGED_PROFILE_PKG = "com.android.cts.managedprofile";
     private static final String MANAGED_PROFILE_APK = "CtsManagedProfileApp.apk";
 
+    private static final String DEVICE_OWNER_PKG = "com.android.cts.deviceowner";
+    private static final String DEVICE_OWNER_APK = "CtsDeviceOwnerApp.apk";
+    private static final String DEVICE_OWNER_ADMIN =
+            DEVICE_OWNER_PKG + ".BaseDeviceOwnerTest$BasicAdminReceiver";
+    private static final String DEVICE_OWNER_CLEAR = DEVICE_OWNER_PKG + ".ClearDeviceOwnerTest";
+
     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 INTENT_RECEIVER_PKG = "com.android.cts.intent.receiver";
     private static final String INTENT_RECEIVER_APK = "CtsIntentReceiverApp.apk";
 
+    private static final String WIFI_CONFIG_CREATOR_PKG = "com.android.cts.wificonfigcreator";
+    private static final String WIFI_CONFIG_CREATOR_APK = "CtsWifiConfigCreator.apk";
+
+    private static final String WIDGET_PROVIDER_APK = "CtsWidgetProviderApp.apk";
+    private static final String WIDGET_PROVIDER_PKG = "com.android.cts.widgetprovider";
+
     private static final String ADMIN_RECEIVER_TEST_CLASS =
             MANAGED_PROFILE_PKG + ".BaseManagedProfileTest$BasicAdminReceiver";
 
     private static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
+    private static final String FEATURE_CAMERA = "android.hardware.camera";
+    private static final String FEATURE_WIFI = "android.hardware.wifi";
+
+    private static final String ADD_RESTRICTION_COMMAND = "add-restriction";
+
+    private static final int USER_OWNER = 0;
+
+    // ID of the profile we'll create. This will always be a profile of USER_OWNER.
     private int mUserId;
+    private String mPackageVerifier;
+
     private boolean mHasNfcFeature;
-    
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -51,11 +75,11 @@
         mHasNfcFeature = hasDeviceFeature("android.hardware.nfc");
 
         if (mHasFeature) {
+            removeTestUsers();
             mUserId = createManagedProfile();
+
             installApp(MANAGED_PROFILE_APK);
-            installApp(INTENT_RECEIVER_APK);
-            installApp(INTENT_SENDER_APK);
-            setProfileOwner(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
+            setProfileOwnerOrFail(MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId);
             startUser(mUserId);
         }
     }
@@ -94,6 +118,42 @@
         assertFalse(listUsers().contains(mUserId));
     }
 
+    public void testMaxOneManagedProfile() throws Exception {
+        int newUserId = -1;
+        try {
+            newUserId = createManagedProfile();
+        } catch (AssertionFailedError expected) {
+        }
+        if (newUserId > 0) {
+            removeUser(newUserId);
+            fail(mHasFeature ? "Device must allow creating only one managed profile"
+                    : "Device must not allow creating a managed profile");
+        }
+    }
+
+    /**
+     * Verify that removing a managed profile will remove all networks owned by that profile.
+     */
+    public void testProfileWifiCleanup() throws Exception {
+        if (!mHasFeature || !hasDeviceFeature(FEATURE_WIFI)) {
+            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));
+
+            // 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);
+        }
+    }
+
     public void testCrossProfileIntentFilters() throws Exception {
         if (!mHasFeature) {
             return;
@@ -115,6 +175,45 @@
         // TODO: Test with startActivity
     }
 
+    public void testAppLinks() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // 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);
+
+        changeVerificationStatus(USER_OWNER, INTENT_RECEIVER_PKG, "ask");
+        changeVerificationStatus(mUserId, 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);
+        // 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");
+        // 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");
+        // 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");
+        // We have one always in the primary user and one always in the managed profile: the managed
+        // profile one should have precedence.
+        assertAppLinkResult("testReceivedByAppLinkActivityInManaged");
+    }
+
+
     public void testSettingsIntents() throws Exception {
         if (!mHasFeature) {
             return;
@@ -127,19 +226,21 @@
         if (!mHasFeature) {
             return;
         }
+        installApp(INTENT_RECEIVER_APK);
+        installApp(INTENT_SENDER_APK);
 
         // Test from parent to managed
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "removeAllFilters", mUserId));
+                "testRemoveAllFilters", mUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "addManagedCanAccessParentFilters", mUserId));
+                "testAddManagedCanAccessParentFilters", mUserId));
         assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", 0));
 
         // Test from managed to parent
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "removeAllFilters", mUserId));
+                "testRemoveAllFilters", mUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "addParentCanAccessManagedFilters", mUserId));
+                "testAddParentCanAccessManagedFilters", mUserId));
         assertTrue(runDeviceTestsAsUser(INTENT_SENDER_PKG, ".ContentTest", mUserId));
 
     }
@@ -148,16 +249,18 @@
         if (!mHasFeature) {
             return;
         }
+        installApp(INTENT_RECEIVER_APK);
+        installApp(INTENT_SENDER_APK);
 
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "allowCrossProfileCopyPaste", mUserId));
+                "testAllowCrossProfileCopyPaste", mUserId));
         // Test that managed can see what is copied in the parent.
         testCrossProfileCopyPasteInternal(mUserId, true);
         // Test that the parent can see what is copied in managed.
         testCrossProfileCopyPasteInternal(0, true);
 
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "disallowCrossProfileCopyPaste", mUserId));
+                "testDisallowCrossProfileCopyPaste", mUserId));
         // Test that managed can still see what is copied in the parent.
         testCrossProfileCopyPasteInternal(mUserId, true);
         // Test that the parent cannot see what is copied in managed.
@@ -166,10 +269,11 @@
 
     private void testCrossProfileCopyPasteInternal(int userId, boolean shouldSucceed)
             throws DeviceNotAvailableException {
-        final String direction = (userId == 0) ? "addManagedCanAccessParentFilters"
-                : "addParentCanAccessManagedFilters";
+        final String direction = (userId == 0)
+                ? "testAddManagedCanAccessParentFilters"
+                : "testAddParentCanAccessManagedFilters";
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
-                "removeAllFilters", mUserId));
+                "testRemoveAllFilters", mUserId));
         assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CrossProfileUtils",
                 direction, mUserId));
         if (shouldSucceed) {
@@ -191,18 +295,25 @@
         if (!mHasFeature) {
             return;
         }
+        // If adb is running as root, then the adb uid is 0 instead of SHELL_UID,
+        // so the DISALLOW_DEBUGGING_FEATURES restriction does not work and this test
+        // fails.
+        if (getDevice().isAdbRoot()) {
+            CLog.logAndDisplay(LogLevel.INFO,
+                    "Cannot test testNoDebuggingFeaturesRestriction() in eng/userdebug build");
+            return;
+        }
         String restriction = "no_debugging_features";  // UserManager.DISALLOW_DEBUGGING_FEATURES
-        String command = "add-restriction";
 
         String addRestrictionCommandOutput =
-                changeUserRestrictionForUser(restriction, command, mUserId);
+                changeUserRestrictionForUser(restriction, ADD_RESTRICTION_COMMAND, mUserId);
         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, command, mUserId);
+                changeUserRestrictionForUser(restriction, ADD_RESTRICTION_COMMAND, mUserId);
         assertTrue(
                 "Expected SecurityException when starting the activity "
                         + addRestrictionCommandOutput,
@@ -226,6 +337,52 @@
                 "testGetRemoteDevice", mUserId));
     }
 
+    public void testCameraPolicy() throws Exception {
+        boolean hasCamera = hasDeviceFeature(FEATURE_CAMERA);
+        if (!mHasFeature || !hasCamera) {
+            return;
+        }
+        try {
+            setDeviceAdmin(MANAGED_PROFILE_PKG + "/.PrimaryUserDeviceAdmin");
+
+            // Disable managed profile camera.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+                    "testDisableCameraInManagedProfile",
+                    mUserId));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+                    "testIsCameraEnabledInPrimaryProfile",
+                    0));
+
+            // Enable managed profile camera.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+                    "testEnableCameraInManagedProfile",
+                    mUserId));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+                    "testIsCameraEnabledInPrimaryProfile",
+                    0));
+
+            // Disable primary profile camera.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+                    "testDisableCameraInPrimaryProfile",
+                    0));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+                    "testIsCameraEnabledInManagedProfile",
+                    mUserId));
+
+            // Enable primary profile camera.
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+                    "testEnableCameraInPrimaryProfile",
+                    0));
+            assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".CameraPolicyTest",
+                    "testIsCameraEnabledInManagedProfile",
+                    mUserId));
+        } finally {
+            final String adminHelperClass = ".PrimaryUserAdminHelper";
+            assertTrue("Clear device admin failed", runDeviceTestsAsUser(MANAGED_PROFILE_PKG,
+                    adminHelperClass, "testClearDeviceAdmin", 0 /* user 0 */));
+        }
+    }
+
     public void testManagedContacts() throws Exception {
         if (!mHasFeature) {
             return;
@@ -234,39 +391,115 @@
         try {
             // Insert Primary profile Contacts
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testPrimaryProfilePhoneLookup_insertedAndfound", 0));
+                    "testPrimaryProfilePhoneAndEmailLookup_insertedAndfound", 0));
             // Insert Managed profile Contacts
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfilePhoneLookup_insertedAndfound", mUserId));
+                    "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));
 
-            // Managed user can use ENTERPRISE_CONTENT_FILTER_URI
-            // To access managed contacts but not primary contacts
+            // Primary user cannot use ordinary phone/email lookup api to access managed contacts
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfilePhoneLookup_canAccessEnterpriseContact", mUserId));
+                    "testPrimaryProfilePhoneLookup_canNotAccessEnterpriseContact", 0));
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
-                    "testManagedProfilePhoneLookup_canNotAccessPrimaryContact", mUserId));
-
-            // Primary user can use ENTERPRISE_CONTENT_FILTER_URI
-            // To access both primary and managed contacts
+                    "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",
-                    "testPrimaryProfilePhoneLookup_canAccessPrimaryContact", 0));
+                    "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 ENTERPRISE_CONTENT_FILTER_URI to access managed contacts
+            // Primary user cannot use ordinary phone/email lookup api to access managed contacts
             assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
                     "testPrimaryProfilePhoneLookup_canNotAccessEnterpriseContact", 0));
-            // Managed user cannot use ENTERPRISE_CONTENT_FILTER_URI to access primary contacts
+            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",
@@ -276,6 +509,42 @@
         }
     }
 
+    public void testBluetoothContactSharingDisabled() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        assertTrue(runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
+                "testSetBluetoothContactSharingDisabled_setterAndGetter", mUserId));
+    }
+
+    public void testCannotSetProfileOwnerAgain() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+        // verify that we can't set the same admin receiver as profile owner again
+        assertFalse(setProfileOwner(
+                MANAGED_PROFILE_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS, mUserId));
+
+        // 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));
+    }
+
+    public void testCannotSetDeviceOwnerWhenProfilePresent() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        try {
+            installApp(DEVICE_OWNER_APK);
+            assertFalse(setDeviceOwner(DEVICE_OWNER_PKG + "/" + DEVICE_OWNER_ADMIN));
+        } finally {
+            // make sure we clean up in case we succeeded in setting the device owner
+            runDeviceTests(DEVICE_OWNER_PKG, DEVICE_OWNER_CLEAR);
+            getDevice().uninstallPackage(DEVICE_OWNER_PKG);
+        }
+    }
+
     public void testNfcRestriction() throws Exception {
         if (!mHasFeature || !mHasNfcFeature) {
             return;
@@ -300,6 +569,47 @@
                 "testNfcShareEnabled", 0));
     }
 
+    public void testCrossProfileWidgets() throws Exception {
+        if (!mHasFeature) {
+            return;
+        }
+
+        try {
+            installApp(WIDGET_PROVIDER_APK);
+            getDevice().executeShellCommand("appwidget grantbind --user 0 --package "
+                    + WIDGET_PROVIDER_PKG);
+            startWidgetHostService();
+
+            String commandOutput = changeCrossProfileWidgetForUser(WIDGET_PROVIDER_PKG,
+                    "add-cross-profile-widget", mUserId);
+            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));
+
+            commandOutput = changeCrossProfileWidgetForUser(WIDGET_PROVIDER_PKG,
+                    "remove-cross-profile-widget", mUserId);
+            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));
+        } finally {
+            changeCrossProfileWidgetForUser(WIDGET_PROVIDER_PKG, "remove-cross-profile-widget",
+                    mUserId);
+            getDevice().uninstallPackage(WIDGET_PROVIDER_PKG);
+        }
+    }
+
     private void disableActivityForUser(String activityName, int userId)
             throws DeviceNotAvailableException {
         String command = "am start -W --user " + userId
@@ -316,10 +626,44 @@
                 + " -c android.intent.category.DEFAULT "
                 + " --es extra-command " + command
                 + " --es extra-restriction-key " + key
-                + " " + MANAGED_PROFILE_PKG + "/.UserRestrictionActivity";
+                + " " + MANAGED_PROFILE_PKG + "/.SetPolicyActivity";
         String commandOutput = getDevice().executeShellCommand(adbCommand);
         CLog.logAndDisplay(LogLevel.INFO,
                 "Output for command " + adbCommand + ": " + commandOutput);
         return commandOutput;
     }
+
+    private String changeCrossProfileWidgetForUser(String packageName, String command, int userId)
+            throws DeviceNotAvailableException {
+        String adbCommand = "am start -W --user " + userId
+                + " -c android.intent.category.DEFAULT "
+                + " --es extra-command " + command
+                + " --es extra-package-name " + packageName
+                + " " + MANAGED_PROFILE_PKG + "/.SetPolicyActivity";
+        String commandOutput = getDevice().executeShellCommand(adbCommand);
+        CLog.logAndDisplay(LogLevel.INFO,
+                "Output for command " + adbCommand + ": " + commandOutput);
+        return commandOutput;
+    }
+
+    // status should be one of never, undefined, ask, always
+    private void changeVerificationStatus(int userId, String packageName, String status)
+            throws DeviceNotAvailableException {
+        String command = "pm set-app-link --user " + userId + " " + packageName + " " + status;
+        CLog.logAndDisplay(LogLevel.INFO, "Output for command " + command + ": "
+                + getDevice().executeShellCommand(command));
+    }
+
+    protected void startWidgetHostService() throws Exception {
+        String command = "am startservice --user 0 "
+                + "-a " + WIDGET_PROVIDER_PKG + ".REGISTER_CALLBACK "
+                + "--ei user-extra " + getUserSerialNumber(mUserId)
+                + " " + 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));
+    }
 }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.java
new file mode 100644
index 0000000..b996de3
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedDeviceOwnerTest.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.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 device owner use cases that also apply to profile owners.
+ * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTest.
+ */
+public class MixedDeviceOwnerTest extends DeviceAndProfileOwnerTest {
+
+    private static final String CLEAR_DEVICE_OWNER_TEST_CLASS =
+            DEVICE_ADMIN_PKG + ".ClearDeviceOwnerTest";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        if (mHasFeature) {
+            mUserId = USER_OWNER;
+
+            installApp(DEVICE_ADMIN_APK);
+            assertTrue("Failed to set device owner",
+                    setDeviceOwner(DEVICE_ADMIN_PKG + "/" + ADMIN_RECEIVER_TEST_CLASS));
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mHasFeature) {
+            assertTrue("Failed to remove device owner.",
+                    runDeviceTests(DEVICE_ADMIN_PKG, CLEAR_DEVICE_OWNER_TEST_CLASS));
+        }
+        super.tearDown();
+    }
+
+    // All tests for this class are defined in DeviceAndProfileOwnerTest
+}
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
new file mode 100644
index 0000000..bcc5bf9
--- /dev/null
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/MixedProfileOwnerTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.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.
+ * Tests that should be run identically in both cases are added in DeviceAndProfileOwnerTest.
+ */
+public class MixedProfileOwnerTest extends DeviceAndProfileOwnerTest {
+
+    @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();
+
+            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 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/dumpsys/Android.mk b/hostsidetests/dumpsys/Android.mk
index 51ea31f..5b63199 100644
--- a/hostsidetests/dumpsys/Android.mk
+++ b/hostsidetests/dumpsys/Android.mk
@@ -18,8 +18,6 @@
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_MODULE_TAGS := optional
-
 # Must match the package name in CtsTestCaseList.mk
 LOCAL_MODULE := CtsDumpsysHostTestCases
 
diff --git a/hostsidetests/dumpsys/FramestatsTestApp/Android.mk b/hostsidetests/dumpsys/FramestatsTestApp/Android.mk
new file mode 100644
index 0000000..1104523
--- /dev/null
+++ b/hostsidetests/dumpsys/FramestatsTestApp/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
+LOCAL_PACKAGE_NAME := CtsFramestatsTestApp
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/dumpsys/FramestatsTestApp/AndroidManifest.xml b/hostsidetests/dumpsys/FramestatsTestApp/AndroidManifest.xml
new file mode 100644
index 0000000..3a9f902
--- /dev/null
+++ b/hostsidetests/dumpsys/FramestatsTestApp/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.cts.framestatstestapp">
+    <!--
+    A simple app that draws at least one frame. Used by framestats
+    test.
+    -->
+    <application>
+        <activity android:name=".FramestatsTestAppActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/hostsidetests/dumpsys/FramestatsTestApp/src/com/android/cts/framestatstestapp/FramestatsTestAppActivity.java b/hostsidetests/dumpsys/FramestatsTestApp/src/com/android/cts/framestatstestapp/FramestatsTestAppActivity.java
new file mode 100644
index 0000000..7370508
--- /dev/null
+++ b/hostsidetests/dumpsys/FramestatsTestApp/src/com/android/cts/framestatstestapp/FramestatsTestAppActivity.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.cts.framestatstestapp;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Trace;
+import android.view.View;
+
+public class FramestatsTestAppActivity extends Activity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        View v = new View(this);
+        v.setBackgroundColor(0xFF00FF00);
+        setContentView(v);
+    }
+}
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java
index e12135a..0daae03 100644
--- a/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java
+++ b/hostsidetests/dumpsys/src/android/dumpsys/cts/DumpsysHostTest.java
@@ -16,11 +16,15 @@
 
 package android.dumpsys.cts;
 
-import com.android.ddmlib.Log;
+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.BufferedReader;
+import java.io.File;
+import java.io.IOException;
 import java.io.StringReader;
 import java.util.HashSet;
 import java.util.Set;
@@ -28,8 +32,10 @@
 /**
  * Test to check the format of the dumps of various services (currently only procstats is tested).
  */
-public class DumpsysHostTest extends DeviceTestCase {
+public class DumpsysHostTest extends DeviceTestCase implements IBuildReceiver {
     private static final String TAG = "DumpsysHostTest";
+    private static final String TEST_APK = "CtsFramestatsTestApp.apk";
+    private static final String TEST_PKG = "com.android.cts.framestatstestapp";
 
     /**
      * A reference to the device under test.
@@ -49,11 +55,6 @@
      * @throws Exception
      */
     public void testProcstatsOutput() throws Exception {
-        if (mDevice.getApiLevel() < 19) {
-            Log.i(TAG, "No Procstats output before KitKat, skipping test.");
-            return;
-        }
-
         String procstats = mDevice.executeShellCommand("dumpsys procstats -c");
         assertNotNull(procstats);
         assertTrue(procstats.length() > 0);
@@ -338,11 +339,6 @@
      * @throws Exception
      */
     public void testBatterystatsOutput() throws Exception {
-        if (mDevice.getApiLevel() < 21) {
-            Log.i(TAG, "Batterystats output before Lollipop, skipping test.");
-            return;
-        }
-
         String batterystats = mDevice.executeShellCommand("dumpsys batterystats --checkin");
         assertNotNull(batterystats);
         assertTrue(batterystats.length() > 0);
@@ -359,7 +355,12 @@
                     continue;
                 }
 
-                String[] parts = line.split(",");
+
+                // With a default limit of 0, empty strings at the end are discarded.
+                // We still consider the empty string as a valid value in some cases.
+                // Using any negative number for the limit will preserve a trailing empty string.
+                // @see String#split(String, int)
+                String[] parts = line.split(",", -1);
                 assertInteger(parts[0]); // old version
                 assertInteger(parts[1]); // UID
                 switch (parts[2]) { // aggregation type
@@ -658,23 +659,22 @@
     }
 
     private void checkMisc(String[] parts) {
-        assertTrue(parts.length >= 20);
+        assertTrue(parts.length >= 19);
         assertInteger(parts[4]);      // screenOnTime
         assertInteger(parts[5]);      // phoneOnTime
-        assertInteger(parts[6]);      // wifiOnTime
-        assertInteger(parts[7]);      // wifiRunningTime
-        assertInteger(parts[8]);      // bluetoothOnTime
-        assertInteger(parts[9]);      // mobileRxTotalBytes
-        assertInteger(parts[10]);     // mobileTxTotalBytes
-        assertInteger(parts[11]);     // wifiRxTotalBytes
-        assertInteger(parts[12]);     // wifiTxTotalBytes
-        assertInteger(parts[13]);     // fullWakeLockTimeTotal
-        assertInteger(parts[14]);     // partialWakeLockTimeTotal
-        assertEquals("0", parts[15]); // legacy input event count
-        assertInteger(parts[16]);     // mobileRadioActiveTime
-        assertInteger(parts[17]);     // mobileRadioActiveAdjustedTime
-        assertInteger(parts[18]);     // interactiveTime
-        assertInteger(parts[19]);     // lowPowerModeEnabledTime
+        assertInteger(parts[6]);      // fullWakeLockTimeTotal
+        assertInteger(parts[7]);      // partialWakeLockTimeTotal
+        assertInteger(parts[8]);      // mobileRadioActiveTime
+        assertInteger(parts[9]);      // mobileRadioActiveAdjustedTime
+        assertInteger(parts[10]);     // interactiveTime
+        assertInteger(parts[11]);     // lowPowerModeEnabledTime
+        assertInteger(parts[12]);     // connChanges
+        assertInteger(parts[13]);     // deviceIdleModeEnabledTime
+        assertInteger(parts[14]);     // deviceIdleModeEnabledCount
+        assertInteger(parts[15]);     // deviceIdlingTime
+        assertInteger(parts[16]);     // deviceIdlingCount
+        assertInteger(parts[17]);     // mobileRadioActiveCount
+        assertInteger(parts[18]);     // mobileRadioActiveUnknownTime
     }
 
     private void checkGlobalNetwork(String[] parts) {
@@ -794,13 +794,14 @@
     }
 
     private void checkChargeDischargeStep(String[] parts) {
-        assertEquals(8, parts.length);
+        assertEquals(9, parts.length);
         assertInteger(parts[4]); // duration
         if (!parts[5].equals("?")) {
             assertInteger(parts[5]); // level
         }
         assertNotNull(parts[6]); // screen
         assertNotNull(parts[7]); // power-save
+        assertNotNull(parts[8]); // device-idle
     }
 
     private void checkDischargeTimeRemain(String[] parts) {
@@ -813,11 +814,108 @@
         assertInteger(parts[4]); // chargeTimeRemaining
     }
 
-    private static void assertInteger(String input) {
+    /**
+     * Tests the output of "dumpsys gfxinfo framestats".
+     *
+     * @throws Exception
+     */
+    public void testGfxinfoFramestats() throws Exception {
+        final String MARKER = "---PROFILEDATA---";
+
         try {
-            Long.parseLong(input);
+            // cleanup test apps that might be installed from previous partial test run
+            getDevice().uninstallPackage(TEST_PKG);
+
+            // install the test app
+            File testAppFile = mCtsBuild.getTestApp(TEST_APK);
+            String installResult = getDevice().installPackage(testAppFile, false);
+            assertNull(
+                    String.format("failed to install atrace test app. Reason: %s", installResult),
+                    installResult);
+
+            getDevice().executeShellCommand("am start -W " + TEST_PKG);
+
+            String frameinfo = mDevice.executeShellCommand("dumpsys gfxinfo " +
+                    TEST_PKG + " framestats");
+            assertNotNull(frameinfo);
+            assertTrue(frameinfo.length() > 0);
+            int profileStart = frameinfo.indexOf(MARKER);
+            int profileEnd = frameinfo.indexOf(MARKER, profileStart + 1);
+            assertTrue(profileStart >= 0);
+            assertTrue(profileEnd > profileStart);
+            String profileData = frameinfo.substring(profileStart + MARKER.length(), profileEnd);
+            assertTrue(profileData.length() > 0);
+            validateProfileData(profileData);
+        } finally {
+            getDevice().uninstallPackage(TEST_PKG);
+        }
+    }
+
+    private void validateProfileData(String profileData) throws IOException {
+        final int TIMESTAMP_COUNT = 14;
+        boolean foundAtLeastOneRow = false;
+        try (BufferedReader reader = new BufferedReader(
+                new StringReader(profileData))) {
+            String line;
+            // First line needs to be the headers
+            while ((line = reader.readLine()) != null && line.isEmpty()) {}
+
+            assertNotNull(line);
+            assertTrue("First line was not the expected header",
+                    line.startsWith("Flags,IntendedVsync,Vsync,OldestInputEvent" +
+                            ",NewestInputEvent,HandleInputStart,AnimationStart" +
+                            ",PerformTraversalsStart,DrawStart,SyncQueued,SyncStart" +
+                            ",IssueDrawCommandsStart,SwapBuffers,FrameCompleted"));
+
+            long[] numparts = new long[TIMESTAMP_COUNT];
+            while ((line = reader.readLine()) != null && !line.isEmpty()) {
+
+                String[] parts = line.split(",");
+                assertTrue(parts.length >= TIMESTAMP_COUNT);
+                for (int i = 0; i < TIMESTAMP_COUNT; i++) {
+                    numparts[i] = assertInteger(parts[i]);
+                }
+                if (numparts[0] != 0) {
+                    continue;
+                }
+                // assert VSYNC >= INTENDED_VSYNC
+                assertTrue(numparts[2] >= numparts[1]);
+                // assert time is flowing forwards, skipping index 3 & 4
+                // as those are input timestamps that may or may not be present
+                assertTrue(numparts[5] >= numparts[2]);
+                for (int i = 6; i < TIMESTAMP_COUNT; i++) {
+                    assertTrue("Index " + i + " did not flow forward, " +
+                            numparts[i] + " not larger than " + numparts[i - 1],
+                            numparts[i] >= numparts[i-1]);
+                }
+                long totalDuration = numparts[13] - numparts[1];
+                assertTrue("Frame did not take a positive amount of time to process",
+                        totalDuration > 0);
+                assertTrue("Bogus frame duration, exceeds 100 seconds",
+                        totalDuration < 100000000000L);
+                foundAtLeastOneRow = true;
+            }
+        }
+        assertTrue(foundAtLeastOneRow);
+    }
+
+    private CtsBuildHelper mCtsBuild;
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setBuild(IBuildInfo buildInfo) {
+        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+    }
+
+    private static long assertInteger(String input) {
+        try {
+            return Long.parseLong(input);
         } catch (NumberFormatException e) {
             fail("Expected an integer but found \"" + input + "\"");
+            // Won't be hit, above throws AssertException
+            return -1;
         }
     }
 
diff --git a/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk b/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
index f6543fb..c04d4b2 100644
--- a/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
+++ b/hostsidetests/monkey/test-apps/CtsMonkeyApp/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/monkey/test-apps/CtsMonkeyApp/AndroidManifest.xml b/hostsidetests/monkey/test-apps/CtsMonkeyApp/AndroidManifest.xml
index a3dfc83..efb1288 100644
--- a/hostsidetests/monkey/test-apps/CtsMonkeyApp/AndroidManifest.xml
+++ b/hostsidetests/monkey/test-apps/CtsMonkeyApp/AndroidManifest.xml
@@ -18,14 +18,18 @@
 
     <application android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
 
-        <activity android:name=".MonkeyActivity">
+        <activity
+            android:name=".MonkeyActivity"
+            android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
-        
-        <activity android:name=".BaboonActivity">
+
+        <activity
+            android:name=".BaboonActivity"
+            android:screenOrientation="locked">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.MONKEY" />
diff --git a/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk b/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
index 29bf9d6..b3cb181 100644
--- a/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
+++ b/hostsidetests/monkey/test-apps/CtsMonkeyApp2/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/net/app/Android.mk b/hostsidetests/net/app/Android.mk
index 29b620d..055287a 100644
--- a/hostsidetests/net/app/Android.mk
+++ b/hostsidetests/net/app/Android.mk
@@ -29,4 +29,4 @@
 LOCAL_PROGUARD_ENABLED := disabled
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/os/Android.mk b/hostsidetests/os/Android.mk
new file mode 100644
index 0000000..6962e0c
--- /dev/null
+++ b/hostsidetests/os/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_MODULE_TAGS := optional
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_MODULE := CtsOsHostTestCases
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.host.os
+
+LOCAL_CTS_MODULE_CONFIG := $(LOCAL_PATH)/$(CTS_MODULE_TEST_CONFIG)
+
+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/os/AndroidTest.xml b/hostsidetests/os/AndroidTest.xml
new file mode 100644
index 0000000..6694c30
--- /dev/null
+++ b/hostsidetests/os/AndroidTest.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
new file mode 100644
index 0000000..46861d69
--- /dev/null
+++ b/hostsidetests/os/app/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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
+
+LOCAL_PACKAGE_NAME := CtsDeviceOsTestApp
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/os/app/AndroidManifest.xml b/hostsidetests/os/app/AndroidManifest.xml
new file mode 100755
index 0000000..103cf63
--- /dev/null
+++ b/hostsidetests/os/app/AndroidManifest.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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.app.os.test">
+
+    <application>
+        <activity android:name=".TestNonExported"
+                android:exported="false" />
+    </application>
+</manifest>
+
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
new file mode 100644
index 0000000..c865c89
--- /dev/null
+++ b/hostsidetests/os/app/src/com/android/cts/app/os/test/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 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/com/android/cts/app/os/OsHostTests.java b/hostsidetests/os/src/com/android/cts/app/os/OsHostTests.java
new file mode 100644
index 0000000..d01a521
--- /dev/null
+++ b/hostsidetests/os/src/com/android/cts/app/os/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 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/security/Android.mk b/hostsidetests/security/Android.mk
index 0c976a3..d9fbc65 100644
--- a/hostsidetests/security/Android.mk
+++ b/hostsidetests/security/Android.mk
@@ -29,7 +29,15 @@
 
 LOCAL_CTS_TEST_PACKAGE := android.host.security
 
-LOCAL_JAVA_RESOURCE_FILES := $(HOST_OUT_EXECUTABLES)/sepolicy-analyze
+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_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)
 
 selinux_general_policy := $(call intermediates-dir-for,ETC,general_sepolicy.conf)/general_sepolicy.conf
 
diff --git a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
index c93295a..abb1ac4 100644
--- a/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/cts/security/SELinuxHostTest.java
@@ -20,19 +20,30 @@
 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.
@@ -44,7 +55,17 @@
 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.
@@ -74,10 +95,44 @@
         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");
     }
 
     /**
@@ -104,4 +159,606 @@
         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/theme/Android.mk b/hostsidetests/theme/Android.mk
index 71027c7..188bf7a 100644
--- a/hostsidetests/theme/Android.mk
+++ b/hostsidetests/theme/Android.mk
@@ -29,6 +29,8 @@
 
 LOCAL_CTS_TEST_PACKAGE := android.host.theme
 
+LOCAL_SDK_VERSION := current
+
 include $(BUILD_CTS_HOST_JAVA_LIBRARY)
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/theme/README b/hostsidetests/theme/README
new file mode 100644
index 0000000..bce711a
--- /dev/null
+++ b/hostsidetests/theme/README
@@ -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.
+
+
+INTRODUCTION
+
+The Android theme tests ensure that the Holo and Material themes have not been
+modified. They consist of API-specific sets of reference images representing
+specific themes and widgets that must be identical across devices. To pass the
+theme tests, a device must be able to generate images that are identical to the
+reference images.
+
+NOTE: Reference images should only be updated by the CTS test maintainers. Any
+      modifications to the reference images will invalidate the test results.
+
+
+INSTRUCTIONS
+
+I. Generating reference images (CTS maintainers only)
+
+Reference images are typically only generated for new API revisions. To
+generate a new set of reference images, do the following:
+
+  1. Connect one device for each DPI bucket (ldpi, xxxhdpi, etc.) that you wish
+     to generate references images for. Confirm that all devices are connected
+     with:
+
+     adb devices
+
+  2. Image generation occurs on all devices in parallel. Resulting sets of
+     reference images are saved in assets/<api>/<dpi>.zip and will overwrite
+     any existing sets. Image generation may be started using:
+
+     .cts/hostsidetests/theme/generate_images.sh
+
+A complete collection of reference images for a given API revision must include
+a set for each possible DPI bucket (tvdpi, xxhdpi, etc.) that may be tested.
+
+
+II. Building theme tests
+
+1. If you have not already built the CTS tests, run an initial make:
+
+   make cts -j32
+
+2. Subsequent changes to the theme tests, including changes to the reference
+   images, may be built using mmm:
+
+   mmm cts/hostsidetests/theme -j32
+
+
+III. Running theme tests
+
+1. Connect the device that you wish to test. Confirm that is is connected with:
+
+   adb devices
+
+2. Run the theme tests using cts-tradefed:
+
+   cts-tradefed run cts -c android.theme.cts.ThemeHostTest
+
+3. Wait for the tests to complete. This should take less than five minutes.
diff --git a/hostsidetests/theme/android_device.py b/hostsidetests/theme/android_device.py
new file mode 100644
index 0000000..97b5fdd
--- /dev/null
+++ b/hostsidetests/theme/android_device.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT 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 os
+import re
+import sys
+import threading
+import subprocess
+import time
+
+# class for running android device from python
+# it will fork the device processor
+class androidDevice(object):
+    def __init__(self, adbDevice):
+        self._adbDevice = adbDevice
+
+    def runAdbCommand(self, cmd):
+        self.waitForAdbDevice()
+        adbCmd = "adb -s %s %s" %(self._adbDevice, cmd)
+        adbProcess = subprocess.Popen(adbCmd.split(" "), bufsize = -1, stdout = subprocess.PIPE)
+        return adbProcess.communicate()
+
+    def runShellCommand(self, cmd):
+        return self.runAdbCommand("shell " + cmd)
+
+    def waitForAdbDevice(self):
+        os.system("adb -s %s wait-for-device" %self._adbDevice)
+
+    def waitForBootComplete(self, timeout = 240):
+        boot_complete = False
+        attempts = 0
+        wait_period = 5
+        while not boot_complete and (attempts*wait_period) < timeout:
+            (output, err) = self.runShellCommand("getprop dev.bootcomplete")
+            output = output.strip()
+            if output == "1":
+                boot_complete = True
+            else:
+                time.sleep(wait_period)
+                attempts += 1
+        if not boot_complete:
+            print "***boot not complete within timeout. will proceed to the next step"
+        return boot_complete
+
+    def installApk(self, apkPath):
+        (out, err) = self.runAdbCommand("install -r -d -g " + apkPath)
+        result = out.split()
+        return (out, err, "Success" in result)
+
+    def uninstallApk(self, package):
+        (out, err) = self.runAdbCommand("uninstall " + package)
+        result = out.split()
+        return "Success" in result
+
+    def runInstrumentationTest(self, option):
+        return self.runShellCommand("am instrument -w " + option)
+
+    def isProcessAlive(self, processName):
+        (out, err) = self.runShellCommand("ps")
+        names = out.split()
+        # very lazy implementation as it does not filter out things like uid
+        # should work mostly unless processName is too simple to overlap with
+        # uid. So only use name like com.android.xyz
+        return processName in names
+
+    def getDensity(self):
+        if "emulator" in self._adbDevice:
+          return int(self.runShellCommand("getprop qemu.sf.lcd_density")[0])
+        else:
+          return int(self.runShellCommand("getprop ro.sf.lcd_density")[0])
+
+    def getSdkLevel(self):
+        return int(self.runShellCommand("getprop ro.build.version.sdk")[0])
+
+    def getOrientation(self):
+        return int(self.runShellCommand("dumpsys | grep SurfaceOrientation")[0].split()[1])
+
+def runAdbDevices():
+    devices = subprocess.check_output(["adb", "devices"])
+    devices = devices.split('\n')[1:]
+
+    deviceSerial = []
+
+    for device in devices:
+        if device is not "":
+            info = device.split('\t')
+            if info[1] == "device":
+                deviceSerial.append(info[0])
+
+    return deviceSerial
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/hostsidetests/theme/app/Android.mk b/hostsidetests/theme/app/Android.mk
index 70623cb..1be2983 100644
--- a/hostsidetests/theme/app/Android.mk
+++ b/hostsidetests/theme/app/Android.mk
@@ -26,6 +26,8 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 #Flags to tell the Android Asset Packaging Tool not to strip for some densities
diff --git a/hostsidetests/theme/app/AndroidManifest.xml b/hostsidetests/theme/app/AndroidManifest.xml
index 81a4d9d..4e81ab0 100755
--- a/hostsidetests/theme/app/AndroidManifest.xml
+++ b/hostsidetests/theme/app/AndroidManifest.xml
@@ -22,9 +22,10 @@
 
     <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=".HoloDeviceActivity">
+        <activity android:name=".ThemeDeviceActivity">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
@@ -37,6 +38,13 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name=".GenerateImagesActivity"
+                  android:exported="true" />
     </application>
 
+    <!--  self-instrumenting test package. -->
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.theme.app"
+                     android:label="Generates Theme reference images"/>
+
 </manifest>
diff --git a/hostsidetests/theme/app/res/layout/holo_test.xml b/hostsidetests/theme/app/res/layout/theme_test.xml
similarity index 100%
rename from hostsidetests/theme/app/res/layout/holo_test.xml
rename to hostsidetests/theme/app/res/layout/theme_test.xml
diff --git a/hostsidetests/theme/app/res/values/strings.xml b/hostsidetests/theme/app/res/values/strings.xml
index a69a2e0..d9d6602 100644
--- a/hostsidetests/theme/app/res/values/strings.xml
+++ b/hostsidetests/theme/app/res/values/strings.xml
@@ -14,8 +14,6 @@
      limitations under the License.
 -->
 <resources>
-    <string name="holo_test_utilities">Holo Test Utilities</string>
-
     <string name="display_info">Display Info</string>
     <string name="display_info_text">Density DPI: %1$d\nDensity Bucket: %2$s\nWidth DP: %3$d\nHeight DP: %4$d</string>
 
diff --git a/hostsidetests/theme/app/src/android/theme/app/DisplayInfoActivity.java b/hostsidetests/theme/app/src/android/theme/app/DisplayInfoActivity.java
index f263eef..530675d 100644
--- a/hostsidetests/theme/app/src/android/theme/app/DisplayInfoActivity.java
+++ b/hostsidetests/theme/app/src/android/theme/app/DisplayInfoActivity.java
@@ -25,7 +25,8 @@
 import android.widget.TextView;
 
 /**
- * An activity to display information about the device, including density bucket and dimensions.
+ * An activity to display information about the device, including density
+ * bucket and dimensions.
  */
 public class DisplayInfoActivity extends Activity {
 
@@ -62,9 +63,15 @@
             case DisplayMetrics.DENSITY_XHIGH:
                 return "xhdpi";
 
+            case DisplayMetrics.DENSITY_360:
+                return "360dpi";
+
             case DisplayMetrics.DENSITY_400:
                 return "400dpi";
 
+            case DisplayMetrics.DENSITY_420:
+                return "420dpi";
+
             case DisplayMetrics.DENSITY_XXHIGH:
                 return "xxhdpi";
 
diff --git a/hostsidetests/theme/app/src/android/theme/app/GenerateBitmapTask.java b/hostsidetests/theme/app/src/android/theme/app/GenerateBitmapTask.java
new file mode 100644
index 0000000..05b6dcf
--- /dev/null
+++ b/hostsidetests/theme/app/src/android/theme/app/GenerateBitmapTask.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.theme.app;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.Canvas;
+import android.os.AsyncTask;
+import android.os.Environment;
+import android.util.Log;
+import android.view.View;
+
+import java.io.File;
+import java.io.FileOutputStream;
+
+/**
+ * A task which gets the UI element to render to a bitmap and then saves that
+ * as a PNG asynchronously.
+ */
+class GenerateBitmapTask extends AsyncTask<Void, Void, Boolean> {
+    private static final String TAG = "GenerateBitmapTask";
+
+    private final View mView;
+    private final File mOutDir;
+
+    private Bitmap mBitmap;
+
+    protected final String mName;
+
+    public GenerateBitmapTask(View view, File outDir, String name) {
+        mView = view;
+        mOutDir = outDir;
+        mName = name;
+    }
+
+    @Override
+    protected void onPreExecute() {
+        if (mView.getWidth() == 0 || mView.getHeight() == 0) {
+            Log.e(TAG, "Unable to draw view due to incorrect size: " + mName);
+            return;
+        }
+
+        mBitmap = Bitmap.createBitmap(mView.getWidth(), mView.getHeight(),
+                Bitmap.Config.ARGB_8888);
+
+        final Canvas canvas = new Canvas(mBitmap);
+        mView.draw(canvas);
+    }
+
+    @Override
+    protected Boolean doInBackground(Void... ignored) {
+        final Bitmap bitmap = mBitmap;
+        if (bitmap == null) {
+            return false;
+        }
+
+        final File file = new File(mOutDir, mName + ".png");
+        if (file.exists() && !file.canWrite()) {
+            Log.e(TAG, "Unable to write file: " + file.getAbsolutePath());
+            return false;
+        }
+
+        boolean success = false;
+        try {
+            FileOutputStream stream = null;
+            try {
+                stream = new FileOutputStream(file);
+                success = bitmap.compress(CompressFormat.PNG, 100, stream);
+            } finally {
+                if (stream != null) {
+                    stream.flush();
+                    stream.close();
+                }
+            }
+        } catch (Exception e) {
+            Log.e(TAG, e.getMessage());
+        } finally {
+            bitmap.recycle();
+        }
+
+        return success;
+    }
+}
diff --git a/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
new file mode 100644
index 0000000..e7f5aa2
--- /dev/null
+++ b/hostsidetests/theme/app/src/android/theme/app/GenerateImagesActivity.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.theme.app;
+
+import android.Manifest.permission;
+import android.app.Activity;
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.Build.VERSION;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.util.Log;
+import android.view.WindowManager.LayoutParams;
+
+import java.io.File;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Generates images by iterating through all themes and launching instances of
+ * {@link ThemeDeviceActivity}.
+ */
+public class GenerateImagesActivity extends Activity {
+    private static final String TAG = "GenerateImagesActivity";
+
+    private static final String OUT_DIR = "cts-theme-assets";
+    private static final int REQUEST_CODE = 1;
+
+    private final CountDownLatch mLatch = new CountDownLatch(1);
+
+    private File mOutputDir;
+    private int mCurrentTheme;
+    private String mFinishReason;
+    private boolean mFinishSuccess;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON
+                | LayoutParams.FLAG_TURN_SCREEN_ON
+                | LayoutParams.FLAG_DISMISS_KEYGUARD);
+
+        mOutputDir = new File(Environment.getExternalStorageDirectory(), OUT_DIR);
+        ThemeTestUtils.deleteDirectory(mOutputDir);
+        mOutputDir.mkdirs();
+
+        if (!mOutputDir.exists()) {
+            finish("Failed to create output directory " + mOutputDir.getAbsolutePath(), false);
+            return;
+        }
+
+        final boolean canDisableKeyguard = checkCallingOrSelfPermission(
+                permission.DISABLE_KEYGUARD) == PackageManager.PERMISSION_GRANTED;
+        if (!canDisableKeyguard) {
+            finish("Not granted permission to disable keyguard", false);
+            return;
+        }
+
+        new KeyguardCheck(this) {
+            @Override
+            public void onSuccess() {
+                generateNextImage();
+            }
+
+            @Override
+            public void onFailure() {
+                finish("Device is locked", false);
+            }
+        }.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;
+    }
+
+    public String getFinishReason() {
+        return mFinishReason;
+    }
+
+    static abstract class KeyguardCheck implements Runnable {
+        private static final int MAX_RETRIES = 3;
+        private static final int RETRY_DELAY = 500;
+
+        private final Handler mHandler;
+        private final KeyguardManager mKeyguard;
+
+        private int mRetries;
+
+        public KeyguardCheck(Context context) {
+            mHandler = new Handler(context.getMainLooper());
+            mKeyguard = (KeyguardManager) context.getSystemService(KEYGUARD_SERVICE);
+        }
+
+        public void start() {
+            mRetries = 0;
+
+            mHandler.removeCallbacks(this);
+            mHandler.post(this);
+        }
+
+        public void cancel() {
+            mHandler.removeCallbacks(this);
+        }
+
+        @Override
+        public void run() {
+            if (!mKeyguard.isKeyguardLocked()) {
+                onSuccess();
+            } else if (mRetries < MAX_RETRIES) {
+                mRetries++;
+                mHandler.postDelayed(this, RETRY_DELAY);
+            } else {
+                onFailure();
+            }
+
+        }
+
+        public abstract void onSuccess();
+        public abstract void onFailure();
+    }
+
+    public File getOutputDir() {
+        return mOutputDir;
+    }
+
+    /**
+     * Starts the activity to generate the next image.
+     */
+    private boolean generateNextImage() {
+        final ThemeDeviceActivity.Theme theme = ThemeDeviceActivity.THEMES[mCurrentTheme];
+        if (theme.apiLevel > VERSION.SDK_INT) {
+            Log.v(TAG, "Skipping theme \"" + theme.name
+                    + "\" (requires API " + theme.apiLevel + ")");
+            return false;
+        }
+
+        Log.v(TAG, "Generating images for theme \"" + theme.name + "\"...");
+
+        final Intent intent = new Intent(this, ThemeDeviceActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
+        intent.putExtra(ThemeDeviceActivity.EXTRA_THEME, mCurrentTheme);
+        intent.putExtra(ThemeDeviceActivity.EXTRA_OUTPUT_DIR, mOutputDir.getAbsolutePath());
+        startActivityForResult(intent, REQUEST_CODE);
+        return true;
+    }
+
+    @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();
+            return;
+        }
+
+        // Keep trying themes until one works.
+        boolean success = false;
+        while (++mCurrentTheme < ThemeDeviceActivity.THEMES.length && !success) {
+            success = generateNextImage();
+        }
+
+        // If we ran out of themes, we're done.
+        if (!success) {
+            finish("Image generation complete!", true);
+        }
+    }
+
+    public void finish() {
+        mLatch.countDown();
+        super.finish();
+    }
+
+    public void waitForCompletion() throws InterruptedException {
+        mLatch.await();
+    }
+}
diff --git a/hostsidetests/theme/app/src/android/theme/app/HoloDeviceActivity.java b/hostsidetests/theme/app/src/android/theme/app/HoloDeviceActivity.java
deleted file mode 100644
index 8ae9fc8..0000000
--- a/hostsidetests/theme/app/src/android/theme/app/HoloDeviceActivity.java
+++ /dev/null
@@ -1,331 +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.theme.app;
-
-import android.app.Activity;
-import android.content.Intent;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.CompressFormat;
-import android.graphics.Canvas;
-import android.os.AsyncTask;
-import android.os.Environment;
-import android.os.Bundle;
-import android.os.Handler;
-import android.theme.app.modifiers.DatePickerModifier;
-import android.theme.app.modifiers.ProgressBarModifier;
-import android.theme.app.modifiers.SearchViewModifier;
-import android.theme.app.modifiers.TimePickerModifier;
-import android.theme.app.modifiers.ViewCheckedModifier;
-import android.theme.app.modifiers.ViewPressedModifier;
-import android.theme.app.R;
-import android.theme.app.ReferenceViewGroup;
-import android.util.Log;
-import android.view.View;
-import android.widget.CheckBox;
-import android.widget.DatePicker;
-import android.widget.LinearLayout;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.Override;
-
-/**
- * A activity which display various UI elements with Holo theme.
- */
-public class HoloDeviceActivity extends Activity {
-
-    public static final String EXTRA_THEME = "holo_theme_extra";
-
-    private static final String TAG = HoloDeviceActivity.class.getSimpleName();
-
-    /**
-     * The duration of the CalendarView adjustement to settle to its final position.
-     */
-    private static final long CALENDAR_VIEW_ADJUSTMENT_DURATION = 540;
-
-    private Theme mTheme;
-
-    private ReferenceViewGroup mViewGroup;
-
-    private int mLayoutIndex;
-
-    @Override
-    protected void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        mTheme = THEMES[getIntent().getIntExtra(EXTRA_THEME, 0)];
-        setTheme(mTheme.mId);
-        setContentView(R.layout.holo_test);
-        mViewGroup = (ReferenceViewGroup) findViewById(R.id.reference_view_group);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        setNextLayout();
-    }
-
-    @Override
-    protected void onPause() {
-        if (!isFinishing()) {
-            // The Activity got paused for some reasons, for finish it as the host won't move on to
-            // the next theme otherwise.
-            Log.w(TAG, "onPause called without a call to finish().");
-            finish();
-        }
-        super.onPause();
-    }
-
-    @Override
-    protected void onDestroy() {
-        if (mLayoutIndex != LAYOUTS.length) {
-            Log.w(TAG, "Not all layouts got rendered: " + mLayoutIndex);
-        }
-        Log.i(TAG, "OKAY:" + mTheme.mName);
-        super.onDestroy();
-    }
-
-    /**
-     * Sets the next layout in the UI.
-     */
-    private void setNextLayout() {
-        if (mLayoutIndex >= LAYOUTS.length) {
-            finish();
-            return;
-        }
-        final Layout layout = LAYOUTS[mLayoutIndex++];
-        final String layoutName = String.format("%s_%s", mTheme.mName, layout.mName);
-
-        mViewGroup.removeAllViews();
-        final View view = getLayoutInflater().inflate(layout.mId, mViewGroup, false);
-        if (layout.mModifier != null) {
-            layout.mModifier.modifyView(view);
-        }
-        mViewGroup.addView(view);
-        view.setFocusable(false);
-
-        final Runnable generateBitmapRunnable = new Runnable() {
-            @Override
-            public void run() {
-                new GenerateBitmapTask(view, layoutName).execute();
-            }
-        };
-
-        if (view instanceof DatePicker) {
-            // DatePicker uses a CalendarView that has a non-configurable adjustment duration of
-            // 540ms
-            view.postDelayed(generateBitmapRunnable, CALENDAR_VIEW_ADJUSTMENT_DURATION);
-        } else {
-            view.post(generateBitmapRunnable);
-        }
-    }
-
-    /**
-     * A task which gets the UI element to render to a bitmap and then saves that as a png
-     * asynchronously
-     */
-    private class GenerateBitmapTask extends AsyncTask<Void, Void, Boolean> {
-
-        private final View mView;
-
-        private final String mName;
-
-        public GenerateBitmapTask(final View view, final String name) {
-            super();
-            mView = view;
-            mName = name;
-        }
-
-        @Override
-        protected Boolean doInBackground(Void... ignored) {
-            if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
-                Log.i(TAG, "External storage for saving bitmaps is not mounted");
-                return false;
-            }
-            if (mView.getWidth() == 0 || mView.getHeight() == 0) {
-                Log.w(TAG, "Unable to draw View due to incorrect size: " + mName);
-                return false;
-            }
-
-            final Bitmap bitmap = Bitmap.createBitmap(
-                    mView.getWidth(), mView.getHeight(), Bitmap.Config.ARGB_8888);
-            final Canvas canvas = new Canvas(bitmap);
-
-            mView.draw(canvas);
-            final File dir = new File(Environment.getExternalStorageDirectory(), "cts-holo-assets");
-            dir.mkdirs();
-            boolean success = false;
-            try {
-                final File file = new File(dir, mName + ".png");
-                FileOutputStream stream = null;
-                try {
-                    stream = new FileOutputStream(file);
-                    success = bitmap.compress(CompressFormat.PNG, 100, stream);
-                } finally {
-                    if (stream != null) {
-                        stream.close();
-                    }
-                }
-            } catch (Exception e) {
-                Log.e(TAG, e.getMessage());
-            } finally {
-                bitmap.recycle();
-            }
-            return success;
-        }
-
-        @Override
-        protected void onPostExecute(Boolean success) {
-            setNextLayout();
-        }
-    }
-
-    /**
-     * A class to encapsulate information about a holo theme.
-     */
-    private static class Theme {
-
-        public final int mId;
-
-        public final String mName;
-
-        private Theme(int id, String name) {
-            mId = id;
-            mName = name;
-        }
-    }
-
-    private static final Theme[] THEMES = {
-            new Theme(android.R.style.Theme_Holo,
-                    "holo"),
-            new Theme(android.R.style.Theme_Holo_Dialog,
-                    "holo_dialog"),
-            new Theme(android.R.style.Theme_Holo_Dialog_MinWidth,
-                    "holo_dialog_minwidth"),
-            new Theme(android.R.style.Theme_Holo_Dialog_NoActionBar,
-                    "holo_dialog_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_Dialog_NoActionBar_MinWidth,
-                    "holo_dialog_noactionbar_minwidth"),
-            new Theme(android.R.style.Theme_Holo_DialogWhenLarge,
-                    "holo_dialogwhenlarge"),
-            new Theme(android.R.style.Theme_Holo_DialogWhenLarge_NoActionBar,
-                    "holo_dialogwhenlarge_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_InputMethod,
-                    "holo_inputmethod"),
-            new Theme(android.R.style.Theme_Holo_Light,
-                    "holo_light"),
-            new Theme(android.R.style.Theme_Holo_Light_DarkActionBar,
-                    "holo_light_darkactionbar"),
-            new Theme(android.R.style.Theme_Holo_Light_Dialog,
-                    "holo_light_dialog"),
-            new Theme(android.R.style.Theme_Holo_Light_Dialog_MinWidth,
-                    "holo_light_dialog_minwidth"),
-            new Theme(android.R.style.Theme_Holo_Light_Dialog_NoActionBar,
-                    "holo_light_dialog_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_Light_Dialog_NoActionBar_MinWidth,
-                    "holo_light_dialog_noactionbar_minwidth"),
-            new Theme(android.R.style.Theme_Holo_Light_DialogWhenLarge,
-                    "holo_light_dialogwhenlarge"),
-            new Theme(android.R.style.Theme_Holo_Light_DialogWhenLarge_NoActionBar,
-                    "holo_light_dialogwhenlarge_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_Light_NoActionBar,
-                    "holo_light_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_Light_NoActionBar_Fullscreen,
-                    "holo_light_noactionbar_fullscreen"),
-            new Theme(android.R.style.Theme_Holo_Light_Panel,
-                    "holo_light_panel"),
-            new Theme(android.R.style.Theme_Holo_NoActionBar,
-                    "holo_noactionbar"),
-            new Theme(android.R.style.Theme_Holo_NoActionBar_Fullscreen,
-                    "holo_noactionbar_fullscreen"),
-            new Theme(android.R.style.Theme_Holo_Panel,
-                    "holo_panel"),
-            new Theme(android.R.style.Theme_Holo_Wallpaper,
-                    "holo_wallpaper"),
-            new Theme(android.R.style.Theme_Holo_Wallpaper_NoTitleBar,
-                    "holo_wallpaper_notitlebar")
-    };
-
-    /**
-     * A class to encapsulate information about a holo layout.
-     */
-    private static class Layout {
-
-        public final int mId;
-
-        public final String mName;
-
-        public final LayoutModifier mModifier;
-
-        private Layout(int id, String name, LayoutModifier modifier) {
-            mId = id;
-            mName = name;
-            mModifier = modifier;
-        }
-    }
-
-    private static final Layout[] LAYOUTS = {
-            new Layout(R.layout.button, "button", null),
-            new Layout(R.layout.button, "button_pressed", new ViewPressedModifier()),
-            new Layout(R.layout.checkbox, "checkbox", null),
-            new Layout(R.layout.checkbox, "checkbox_checked", new ViewCheckedModifier()),
-            new Layout(R.layout.chronometer, "chronometer", null),
-            new Layout(R.layout.color_blue_bright, "color_blue_bright", null),
-            new Layout(R.layout.color_blue_dark, "color_blue_dark", null),
-            new Layout(R.layout.color_blue_light, "color_blue_light", null),
-            new Layout(R.layout.color_green_dark, "color_green_dark", null),
-            new Layout(R.layout.color_green_light, "color_green_light", null),
-            new Layout(R.layout.color_orange_dark, "color_orange_dark", null),
-            new Layout(R.layout.color_orange_light, "color_orange_light", null),
-            new Layout(R.layout.color_purple, "color_purple", null),
-            new Layout(R.layout.color_red_dark, "color_red_dark", null),
-            new Layout(R.layout.color_red_light, "color_red_light", null),
-            new Layout(R.layout.datepicker, "datepicker", new DatePickerModifier()),
-            new Layout(R.layout.display_info, "display_info", null),
-            new Layout(R.layout.edittext, "edittext", null),
-            new Layout(R.layout.progressbar_horizontal_0, "progressbar_horizontal_0", null),
-            new Layout(R.layout.progressbar_horizontal_100, "progressbar_horizontal_100", null),
-            new Layout(R.layout.progressbar_horizontal_50, "progressbar_horizontal_50", null),
-            new Layout(R.layout.progressbar_large, "progressbar_large", new ProgressBarModifier()),
-            new Layout(R.layout.progressbar_small, "progressbar_small", new ProgressBarModifier()),
-            new Layout(R.layout.progressbar, "progressbar", new ProgressBarModifier()),
-            new Layout(R.layout.radiobutton_checked, "radiobutton_checked", null),
-            new Layout(R.layout.radiobutton, "radiobutton", null),
-            new Layout(R.layout.radiogroup_horizontal, "radiogroup_horizontal", null),
-            new Layout(R.layout.radiogroup_vertical, "radiogroup_vertical", null),
-            new Layout(R.layout.ratingbar_0, "ratingbar_0", null),
-            new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5", null),
-            new Layout(R.layout.ratingbar_5, "ratingbar_5", null),
-            new Layout(R.layout.ratingbar_0, "ratingbar_0_pressed", new ViewPressedModifier()),
-            new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5_pressed", new ViewPressedModifier()),
-            new Layout(R.layout.ratingbar_5, "ratingbar_5_pressed", new ViewPressedModifier()),
-            new Layout(R.layout.searchview, "searchview_query", new SearchViewModifier(SearchViewModifier.QUERY)),
-            new Layout(R.layout.searchview, "searchview_query_hint", new SearchViewModifier(SearchViewModifier.QUERY_HINT)),
-            new Layout(R.layout.seekbar_0, "seekbar_0", null),
-            new Layout(R.layout.seekbar_100, "seekbar_100", null),
-            new Layout(R.layout.seekbar_50, "seekbar_50", null),
-            new Layout(R.layout.spinner, "spinner", null),
-            new Layout(R.layout.switch_button_checked, "switch_button_checked", null),
-            new Layout(R.layout.switch_button, "switch_button", null),
-            new Layout(R.layout.textview, "textview", null),
-            new Layout(R.layout.timepicker, "timepicker", new TimePickerModifier()),
-            new Layout(R.layout.togglebutton_checked, "togglebutton_checked", null),
-            new Layout(R.layout.togglebutton, "togglebutton", null),
-            new Layout(R.layout.zoomcontrols, "zoomcontrols", null),
-    };
-}
diff --git a/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java b/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.java
new file mode 100644
index 0000000..7569252
--- /dev/null
+++ b/hostsidetests/theme/app/src/android/theme/app/ReferenceImagesTest.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 android.theme.app;
+
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.io.File;
+
+/**
+ * Activity test case used to instrument generation of reference images.
+ */
+public class ReferenceImagesTest extends ActivityInstrumentationTestCase2<GenerateImagesActivity> {
+
+    public ReferenceImagesTest() {
+        super(GenerateImagesActivity.class);
+    }
+
+    public void testGenerateReferenceImages() throws Exception {
+        setActivityInitialTouchMode(true);
+
+        final GenerateImagesActivity activity = getActivity();
+        activity.waitForCompletion();
+
+        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());
+    }
+}
diff --git a/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java b/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java
new file mode 100644
index 0000000..d8b1f30
--- /dev/null
+++ b/hostsidetests/theme/app/src/android/theme/app/ThemeDeviceActivity.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.theme.app;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Build;
+import android.os.Bundle;
+import android.theme.app.modifiers.DatePickerModifier;
+import android.theme.app.modifiers.ProgressBarModifier;
+import android.theme.app.modifiers.SearchViewModifier;
+import android.theme.app.modifiers.TimePickerModifier;
+import android.theme.app.modifiers.ViewCheckedModifier;
+import android.theme.app.modifiers.ViewPressedModifier;
+import android.util.Log;
+import android.view.View;
+import android.view.WindowManager.LayoutParams;
+import android.widget.DatePicker;
+
+import java.io.File;
+import java.lang.Override;
+
+/**
+ * A activity which display various UI elements with non-modifiable themes.
+ */
+public class ThemeDeviceActivity extends Activity {
+    public static final String EXTRA_THEME = "theme";
+    public static final String EXTRA_OUTPUT_DIR = "outputDir";
+
+    private static final String TAG = "ThemeDeviceActivity";
+
+    /**
+     * The duration of the CalendarView adjustment to settle to its final
+     * position.
+     */
+    private static final long CALENDAR_VIEW_ADJUSTMENT_DURATION = 540;
+
+    private Theme mTheme;
+    private ReferenceViewGroup mViewGroup;
+    private File mOutputDir;
+    private int mLayoutIndex;
+    private boolean mIsRunning;
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        final Intent intent = getIntent();
+        final int themeIndex = intent.getIntExtra(EXTRA_THEME, -1);
+        if (themeIndex < 0) {
+            Log.e(TAG, "No theme specified");
+            finish();
+        }
+
+        final String outputDir = intent.getStringExtra(EXTRA_OUTPUT_DIR);
+        if (outputDir == null) {
+            Log.e(TAG, "No output directory specified");
+            finish();
+        }
+
+        mOutputDir = new File(outputDir);
+        mTheme = THEMES[themeIndex];
+
+        setTheme(mTheme.id);
+        setContentView(R.layout.theme_test);
+
+        mViewGroup = (ReferenceViewGroup) findViewById(R.id.reference_view_group);
+
+        getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON
+                | LayoutParams.FLAG_TURN_SCREEN_ON
+                | LayoutParams.FLAG_DISMISS_KEYGUARD );
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        mIsRunning = true;
+
+        setNextLayout();
+    }
+
+    @Override
+    protected void onPause() {
+        mIsRunning = false;
+
+        if (!isFinishing()) {
+            // The activity paused for some reason, likely a system crash
+            // dialog. Finish it so we can move to the next theme.
+            Log.w(TAG, "onPause() called without a call to finish()", new RuntimeException());
+            finish();
+        }
+
+        super.onPause();
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (mLayoutIndex < LAYOUTS.length) {
+            Log.e(TAG, "Not all layouts got rendered: " + mLayoutIndex);
+            setResult(RESULT_CANCELED);
+        }
+
+        super.onDestroy();
+    }
+
+    /**
+     * Sets the next layout in the UI.
+     */
+    private void setNextLayout() {
+        if (mLayoutIndex >= LAYOUTS.length) {
+            setResult(RESULT_OK);
+            finish();
+            return;
+        }
+
+        mViewGroup.removeAllViews();
+
+        final Layout layout = LAYOUTS[mLayoutIndex++];
+        final String layoutName = String.format("%s_%s", mTheme.name, layout.name);
+        final View view = getLayoutInflater().inflate(layout.id, mViewGroup, false);
+        if (layout.modifier != null) {
+            layout.modifier.modifyView(view);
+        }
+
+        mViewGroup.addView(view);
+        view.setFocusable(false);
+
+        Log.v(TAG, "Rendering layout " + layoutName
+                + " (" + mLayoutIndex + "/" + LAYOUTS.length + ")");
+
+        final Runnable generateBitmapRunnable = new Runnable() {
+            @Override
+            public void run() {
+                new BitmapTask(view, layoutName).execute();
+            }
+        };
+
+        if (view instanceof DatePicker) {
+            // The Holo-styled DatePicker uses a CalendarView that has a
+            // non-configurable adjustment duration of 540ms.
+            view.postDelayed(generateBitmapRunnable, CALENDAR_VIEW_ADJUSTMENT_DURATION);
+        } else {
+            view.post(generateBitmapRunnable);
+        }
+    }
+
+    private class BitmapTask extends GenerateBitmapTask {
+        public BitmapTask(View view, String name) {
+            super(view, mOutputDir, name);
+        }
+
+        @Override
+        protected void onPostExecute(Boolean success) {
+            if (success && mIsRunning) {
+                setNextLayout();
+            } else {
+                Log.e(TAG, "Failed to render view to bitmap: " + mName + " (activity running? "
+                        + mIsRunning + ")");
+                finish();
+            }
+        }
+    }
+
+    /**
+     * A class to encapsulate information about a theme.
+     */
+    static class Theme {
+        public final int id;
+        public final int apiLevel;
+        public final String name;
+
+        private Theme(int id, int apiLevel, String name) {
+            this.id = id;
+            this.apiLevel = apiLevel;
+            this.name = name;
+        }
+    }
+
+    // List of themes to verify.
+    static final Theme[] THEMES = {
+            // Holo
+            new Theme(android.R.style.Theme_Holo,
+                    Build.VERSION_CODES.HONEYCOMB, "holo"),
+            new Theme(android.R.style.Theme_Holo_Dialog,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_dialog"),
+            new Theme(android.R.style.Theme_Holo_Dialog_MinWidth,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_dialog_minwidth"),
+            new Theme(android.R.style.Theme_Holo_Dialog_NoActionBar,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_dialog_noactionbar"),
+            new Theme(android.R.style.Theme_Holo_Dialog_NoActionBar_MinWidth,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_dialog_noactionbar_minwidth"),
+            new Theme(android.R.style.Theme_Holo_DialogWhenLarge,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_dialogwhenlarge"),
+            new Theme(android.R.style.Theme_Holo_DialogWhenLarge_NoActionBar,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_dialogwhenlarge_noactionbar"),
+            new Theme(android.R.style.Theme_Holo_InputMethod,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_inputmethod"),
+            new Theme(android.R.style.Theme_Holo_NoActionBar,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_noactionbar"),
+            new Theme(android.R.style.Theme_Holo_NoActionBar_Fullscreen,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_noactionbar_fullscreen"),
+            new Theme(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,
+                    Build.VERSION_CODES.KITKAT, "holo_noactionbar_translucentdecor"),
+            new Theme(android.R.style.Theme_Holo_Panel,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_panel"),
+            new Theme(android.R.style.Theme_Holo_Wallpaper,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_wallpaper"),
+            new Theme(android.R.style.Theme_Holo_Wallpaper_NoTitleBar,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_wallpaper_notitlebar"),
+
+            // Holo Light
+            new Theme(android.R.style.Theme_Holo_Light,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_light"),
+            new Theme(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,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog"),
+            new Theme(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,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_light_dialog_noactionbar"),
+            new Theme(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,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_light_dialogwhenlarge"),
+            new Theme(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,
+                    Build.VERSION_CODES.HONEYCOMB_MR2, "holo_light_noactionbar"),
+            new Theme(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,
+                    Build.VERSION_CODES.JELLY_BEAN_MR2, "holo_light_noactionbar_overscan"),
+            new Theme(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,
+                    Build.VERSION_CODES.HONEYCOMB, "holo_light_panel"),
+
+            // Material
+            new Theme(android.R.style.Theme_Material,
+                    Build.VERSION_CODES.LOLLIPOP, "material"),
+            new Theme(android.R.style.Theme_Material_Dialog,
+                    Build.VERSION_CODES.LOLLIPOP, "material_dialog"),
+            new Theme(android.R.style.Theme_Material_Dialog_Alert,
+                    Build.VERSION_CODES.LOLLIPOP, "material_dialog_alert"),
+            new Theme(android.R.style.Theme_Material_Dialog_MinWidth,
+                    Build.VERSION_CODES.LOLLIPOP, "material_dialog_minwidth"),
+            new Theme(android.R.style.Theme_Material_Dialog_NoActionBar,
+                    Build.VERSION_CODES.LOLLIPOP, "material_dialog_noactionbar"),
+            new Theme(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,
+                    Build.VERSION_CODES.LOLLIPOP, "material_dialog_presentation"),
+            new Theme(android.R.style.Theme_Material_DialogWhenLarge,
+                    Build.VERSION_CODES.LOLLIPOP, "material_dialogwhenlarge"),
+            new Theme(android.R.style.Theme_Material_DialogWhenLarge_NoActionBar,
+                    Build.VERSION_CODES.LOLLIPOP, "material_dialogwhenlarge_noactionbar"),
+            new Theme(android.R.style.Theme_Material_InputMethod,
+                    Build.VERSION_CODES.LOLLIPOP, "material_inputmethod"),
+            new Theme(android.R.style.Theme_Material_NoActionBar,
+                    Build.VERSION_CODES.LOLLIPOP, "material_noactionbar"),
+            new Theme(android.R.style.Theme_Material_NoActionBar_Fullscreen,
+                    Build.VERSION_CODES.LOLLIPOP, "material_noactionbar_fullscreen"),
+            new Theme(android.R.style.Theme_Material_NoActionBar_Overscan,
+                    Build.VERSION_CODES.LOLLIPOP, "material_noactionbar_overscan"),
+            new Theme(android.R.style.Theme_Material_NoActionBar_TranslucentDecor,
+                    Build.VERSION_CODES.LOLLIPOP, "material_noactionbar_translucentdecor"),
+            new Theme(android.R.style.Theme_Material_Panel,
+                    Build.VERSION_CODES.LOLLIPOP, "material_panel"),
+            new Theme(android.R.style.Theme_Material_Settings,
+                    Build.VERSION_CODES.LOLLIPOP, "material_settings"),
+            new Theme(android.R.style.Theme_Material_Voice,
+                    Build.VERSION_CODES.LOLLIPOP, "material_voice"),
+            new Theme(android.R.style.Theme_Material_Wallpaper,
+                    Build.VERSION_CODES.LOLLIPOP, "material_wallpaper"),
+            new Theme(android.R.style.Theme_Material_Wallpaper_NoTitleBar,
+                    Build.VERSION_CODES.LOLLIPOP, "material_wallpaper_notitlebar"),
+
+            // Material Light
+            new Theme(android.R.style.Theme_Material_Light,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light"),
+            new Theme(android.R.style.Theme_Material_Light_DarkActionBar,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light_darkactionbar"),
+            new Theme(android.R.style.Theme_Material_Light_Dialog,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light_dialog"),
+            new Theme(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,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_minwidth"),
+            new Theme(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,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light_dialog_noactionbar_minwidth"),
+            new Theme(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,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light_dialogwhenlarge"),
+            new Theme(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,
+                    Build.VERSION_CODES.M, "material_light_lightstatusbar"),
+            new Theme(android.R.style.Theme_Material_Light_NoActionBar,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar"),
+            new Theme(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,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light_noactionbar_overscan"),
+            new Theme(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,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light_panel"),
+            new Theme(android.R.style.Theme_Material_Light_Voice,
+                    Build.VERSION_CODES.LOLLIPOP, "material_light_voice")
+    };
+
+    /**
+     * A class to encapsulate information about a layout.
+     */
+    private static class Layout {
+        public final int id;
+        public final String name;
+        public final LayoutModifier modifier;
+
+        private Layout(int id, String name) {
+            this(id, name, null);
+        }
+
+        private Layout(int id, String name, LayoutModifier modifier) {
+            this.id = id;
+            this.name = name;
+            this.modifier = modifier;
+        }
+    }
+
+    // List of layouts to verify for each theme.
+    private static final Layout[] LAYOUTS = {
+            new Layout(R.layout.button, "button"),
+            new Layout(R.layout.button, "button_pressed",
+                    new ViewPressedModifier()),
+            new Layout(R.layout.checkbox, "checkbox"),
+            new Layout(R.layout.checkbox, "checkbox_checked",
+                    new ViewCheckedModifier()),
+            new Layout(R.layout.chronometer, "chronometer"),
+            new Layout(R.layout.color_blue_bright, "color_blue_bright"),
+            new Layout(R.layout.color_blue_dark, "color_blue_dark"),
+            new Layout(R.layout.color_blue_light, "color_blue_light"),
+            new Layout(R.layout.color_green_dark, "color_green_dark"),
+            new Layout(R.layout.color_green_light, "color_green_light"),
+            new Layout(R.layout.color_orange_dark, "color_orange_dark"),
+            new Layout(R.layout.color_orange_light, "color_orange_light"),
+            new Layout(R.layout.color_purple, "color_purple"),
+            new Layout(R.layout.color_red_dark, "color_red_dark"),
+            new Layout(R.layout.color_red_light, "color_red_light"),
+            new Layout(R.layout.datepicker, "datepicker",
+                    new DatePickerModifier()),
+            new Layout(R.layout.display_info, "display_info"),
+            new Layout(R.layout.edittext, "edittext"),
+            new Layout(R.layout.progressbar_horizontal_0, "progressbar_horizontal_0"),
+            new Layout(R.layout.progressbar_horizontal_100, "progressbar_horizontal_100"),
+            new Layout(R.layout.progressbar_horizontal_50, "progressbar_horizontal_50"),
+            new Layout(R.layout.progressbar_large, "progressbar_large",
+                    new ProgressBarModifier()),
+            new Layout(R.layout.progressbar_small, "progressbar_small",
+                    new ProgressBarModifier()),
+            new Layout(R.layout.progressbar, "progressbar",
+                    new ProgressBarModifier()),
+            new Layout(R.layout.radiobutton_checked, "radiobutton_checked"),
+            new Layout(R.layout.radiobutton, "radiobutton"),
+            new Layout(R.layout.radiogroup_horizontal, "radiogroup_horizontal"),
+            new Layout(R.layout.radiogroup_vertical, "radiogroup_vertical"),
+            new Layout(R.layout.ratingbar_0, "ratingbar_0"),
+            new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5"),
+            new Layout(R.layout.ratingbar_5, "ratingbar_5"),
+            new Layout(R.layout.ratingbar_0, "ratingbar_0_pressed",
+                    new ViewPressedModifier()),
+            new Layout(R.layout.ratingbar_2point5, "ratingbar_2point5_pressed",
+                    new ViewPressedModifier()),
+            new Layout(R.layout.ratingbar_5, "ratingbar_5_pressed",
+                    new ViewPressedModifier()),
+            new Layout(R.layout.searchview, "searchview_query",
+                    new SearchViewModifier(SearchViewModifier.QUERY)),
+            new Layout(R.layout.searchview, "searchview_query_hint",
+                    new SearchViewModifier(SearchViewModifier.QUERY_HINT)),
+            new Layout(R.layout.seekbar_0, "seekbar_0"),
+            new Layout(R.layout.seekbar_100, "seekbar_100"),
+            new Layout(R.layout.seekbar_50, "seekbar_50"),
+            new Layout(R.layout.spinner, "spinner"),
+            new Layout(R.layout.switch_button_checked, "switch_button_checked"),
+            new Layout(R.layout.switch_button, "switch_button"),
+            new Layout(R.layout.textview, "textview"),
+            new Layout(R.layout.timepicker, "timepicker",
+                    new TimePickerModifier()),
+            new Layout(R.layout.togglebutton_checked, "togglebutton_checked"),
+            new Layout(R.layout.togglebutton, "togglebutton"),
+            new Layout(R.layout.zoomcontrols, "zoomcontrols"),
+    };
+}
diff --git a/hostsidetests/theme/app/src/android/theme/app/ThemeTestUtils.java b/hostsidetests/theme/app/src/android/theme/app/ThemeTestUtils.java
new file mode 100644
index 0000000..4daca6c
--- /dev/null
+++ b/hostsidetests/theme/app/src/android/theme/app/ThemeTestUtils.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 android.theme.app;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+public class ThemeTestUtils {
+
+    /**
+     * Compresses the contents of a directory to a ZIP file.
+     *
+     * @param dir the directory to compress
+     * @return {@code true} on success, {@code false} on failure
+     */
+    public static boolean compressDirectory(File dir, File file) throws IOException {
+        if (dir == null || !dir.exists() || file == null || file.exists()) {
+            return false;
+        }
+
+        final File[] srcFiles = dir.listFiles();
+        if (srcFiles.length == 0) {
+            return false;
+        }
+
+        final ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(file));
+        final byte[] data = new byte[4096];
+        for (int i = 0; i < srcFiles.length; i++) {
+            final FileInputStream fileIn = new FileInputStream(srcFiles[i]);
+            final ZipEntry entry = new ZipEntry(srcFiles[i].getName());
+            zipOut.putNextEntry(entry);
+
+            int count;
+            while ((count = fileIn.read(data, 0, data.length)) != -1) {
+                zipOut.write(data, 0, count);
+                zipOut.flush();
+            }
+
+            zipOut.closeEntry();
+            fileIn.close();
+        }
+
+        zipOut.close();
+        return true;
+    }
+
+    /**
+     * Recursively deletes a directory and its contents.
+     *
+     * @param dir the directory to delete
+     * @return {@code true} on success, {@code false} on failure
+     */
+    public static boolean deleteDirectory(File dir) {
+        final File files[] = dir.listFiles();
+        if (files != null) {
+            for (File file : files) {
+                deleteDirectory(file);
+            }
+        }
+        return dir.delete();
+    }
+}
diff --git a/hostsidetests/theme/assets/23/400dpi.zip b/hostsidetests/theme/assets/23/400dpi.zip
new file mode 100644
index 0000000..be0891f
--- /dev/null
+++ b/hostsidetests/theme/assets/23/400dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/23/560dpi.zip b/hostsidetests/theme/assets/23/560dpi.zip
new file mode 100644
index 0000000..cf0a559
--- /dev/null
+++ b/hostsidetests/theme/assets/23/560dpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/23/hdpi.zip b/hostsidetests/theme/assets/23/hdpi.zip
new file mode 100644
index 0000000..80c12a7
--- /dev/null
+++ b/hostsidetests/theme/assets/23/hdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/23/ldpi.zip b/hostsidetests/theme/assets/23/ldpi.zip
new file mode 100644
index 0000000..937914a
--- /dev/null
+++ b/hostsidetests/theme/assets/23/ldpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/23/mdpi.zip b/hostsidetests/theme/assets/23/mdpi.zip
new file mode 100644
index 0000000..f842676
--- /dev/null
+++ b/hostsidetests/theme/assets/23/mdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/23/tvdpi.zip b/hostsidetests/theme/assets/23/tvdpi.zip
new file mode 100644
index 0000000..77386e5
--- /dev/null
+++ b/hostsidetests/theme/assets/23/tvdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/23/xhdpi.zip b/hostsidetests/theme/assets/23/xhdpi.zip
new file mode 100644
index 0000000..a8310d5
--- /dev/null
+++ b/hostsidetests/theme/assets/23/xhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/assets/23/xxhdpi.zip b/hostsidetests/theme/assets/23/xxhdpi.zip
new file mode 100644
index 0000000..f88711f
--- /dev/null
+++ b/hostsidetests/theme/assets/23/xxhdpi.zip
Binary files differ
diff --git a/hostsidetests/theme/generate_images.sh b/hostsidetests/theme/generate_images.sh
new file mode 100755
index 0000000..9bcc3e5
--- /dev/null
+++ b/hostsidetests/theme/generate_images.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 script is used to generate reference images for the CTS theme tests.
+# See the accompanying README file for more information.
+
+# retry <command> <tries> <message> <delay>
+function retry {
+  RETRY="0"
+  while true; do
+    if (("$RETRY" >= "$2")); then
+      echo $OUTPUT
+      exit
+    fi
+
+    OUTPUT=`$1 |& grep error`
+
+    if [ -z "$OUTPUT" ]; then
+      break
+    fi
+
+    echo $3
+    sleep $4
+    RETRY=$[$RETRY + 1]
+  done
+}
+
+themeApkPath="$ANDROID_HOST_OUT/cts/android-cts/repository/testcases/CtsThemeDeviceApp.apk"
+outDir="$ANDROID_BUILD_TOP/cts/hostsidetests/theme/assets"
+exe="$ANDROID_BUILD_TOP/cts/hostsidetests/theme/run_theme_capture_device.py"
+
+if [ -z "$ANDROID_BUILD_TOP" ]; then
+  echo "Missing environment variables. Did you run build/envsetup.sh and lunch?"
+  exit
+fi
+
+if [ ! -e "$themeApkPath" ]; then
+  echo "Couldn't find test APK. Did you run make cts?"
+  exit
+fi
+
+adb devices
+python $exe $themeApkPath $outDir
diff --git a/hostsidetests/theme/run_theme_capture_device.py b/hostsidetests/theme/run_theme_capture_device.py
new file mode 100755
index 0000000..23171db
--- /dev/null
+++ b/hostsidetests/theme/run_theme_capture_device.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the 'License');
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an 'AS IS' BASIS,
+# WITHOUT 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 os
+import sys
+import threading
+import time
+import Queue
+sys.path.append(sys.path[0])
+from android_device import *
+
+CTS_THEME_dict = {
+    120 : "ldpi",
+    160 : "mdpi",
+    213 : "tvdpi",
+    240 : "hdpi",
+    320 : "xhdpi",
+    400 : "400dpi",
+    480 : "xxhdpi",
+    560 : "560dpi",
+    640 : "xxxhdpi",
+}
+
+OUT_FILE = "/sdcard/cts-theme-assets.zip"
+
+# pass a function with number of instances to be executed in parallel
+# each thread continues until config q is empty.
+def executeParallel(tasks, setup, q, numberThreads):
+    class ParallelExecutor(threading.Thread):
+        def __init__(self, tasks, q):
+            threading.Thread.__init__(self)
+            self._q = q
+            self._tasks = tasks
+            self._setup = setup
+            self._result = 0
+
+        def run(self):
+            try:
+                while True:
+                    config = q.get(block=True, timeout=2)
+                    for t in self._tasks:
+                        try:
+                            if t(self._setup, config):
+                                self._result += 1
+                        except KeyboardInterrupt:
+                            raise
+                        except:
+                            print "Failed to execute thread:", sys.exc_info()[0]
+                    q.task_done()
+            except KeyboardInterrupt:
+                raise
+            except Queue.Empty:
+                pass
+
+        def getResult(self):
+            return self._result
+
+    result = 0;
+    threads = []
+    for i in range(numberThreads):
+        t = ParallelExecutor(tasks, q)
+        t.start()
+        threads.append(t)
+    for t in threads:
+        t.join()
+        result += t.getResult()
+    return result;
+
+def printAdbResult(device, out, err):
+    print "device: " + device
+    if out is not None:
+        print "out:\n" + out
+    if err is not None:
+        print "err:\n" + err
+
+def getResDir(outPath, resName):
+    resDir = outPath + "/" + resName
+    return resDir
+
+def doCapturing(setup, deviceSerial):
+    (themeApkPath, outPath) = setup
+
+    print "Found device: " + deviceSerial
+    device = androidDevice(deviceSerial)
+
+    # outPath = outPath + "/%d/" % (device.getSdkLevel()) + deviceSerial
+    outPath = outPath + "/%d" % (device.getSdkLevel())
+    density = device.getDensity()
+    resName = CTS_THEME_dict[density]
+
+    device.uninstallApk("android.theme.app")
+
+    (out, err, success) = device.installApk(themeApkPath)
+    if not success:
+        print "Failed to install APK on " + deviceSerial
+        printAdbResult(device, out, err)
+        return False
+
+    print "Generating images on " + deviceSerial + "..."
+    try:
+        (out, err) = device.runInstrumentationTest("android.theme.app/android.support.test.runner.AndroidJUnitRunner")
+    except KeyboardInterrupt:
+        raise
+    except:
+        (out, err) = device.runInstrumentationTest("android.theme.app/android.test.InstrumentationTestRunner")
+
+    # Detect test failure and abort.
+    if "FAILURES!!!" in out.split():
+        printAdbResult(deviceSerial, out, err)
+        return False
+
+    # Make sure that the run is complete by checking the process itself
+    print "Waiting for " + deviceSerial + "..."
+    waitTime = 0
+    while device.isProcessAlive("android.theme.app"):
+        time.sleep(1)
+        waitTime = waitTime + 1
+        if waitTime > 180:
+            print "Timed out"
+            break
+
+    time.sleep(10)
+    resDir = getResDir(outPath, resName)
+
+    print "Pulling images from " + deviceSerial + " to " + resDir + ".zip"
+    device.runAdbCommand("pull " + OUT_FILE + " " + resDir + ".zip")
+    device.runAdbCommand("shell rm -rf " + OUT_FILE)
+    return True
+
+def main(argv):
+    if len(argv) < 3:
+        print "run_theme_capture_device.py themeApkPath outDir"
+        sys.exit(1)
+    themeApkPath = argv[1]
+    outPath = os.path.abspath(argv[2])
+    os.system("mkdir -p " + outPath)
+
+    tasks = []
+    tasks.append(doCapturing)
+
+    devices = runAdbDevices();
+    numberThreads = len(devices)
+
+    configQ = Queue.Queue()
+    for device in devices:
+        configQ.put(device)
+    setup = (themeApkPath, outPath)
+    result = executeParallel(tasks, setup, configQ, numberThreads)
+
+    if result > 0:
+        print 'Generated reference images for %(count)d devices' % {"count": result}
+    else:
+        print 'Failed to generate reference images'
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
index 7277b9f..0e11111 100755
--- a/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
+++ b/hostsidetests/theme/src/android/theme/cts/ComparisonTask.java
@@ -23,6 +23,7 @@
 import java.awt.Color;
 import java.awt.image.BufferedImage;
 import java.io.File;
+import java.io.IOException;
 import java.lang.String;
 import java.util.concurrent.Callable;
 
@@ -32,59 +33,50 @@
  * Compares the images generated by the device with the reference images.
  */
 public class ComparisonTask implements Callable<Boolean> {
-
-    private static final String TAG = ComparisonTask.class.getSimpleName();
+    private static final String TAG = "ComparisonTask";
 
     private static final int IMAGE_THRESHOLD = 2;
 
-    private static final String STORAGE_PATH_DEVICE = "/sdcard/cts-holo-assets/%s.png";
-
     private final ITestDevice mDevice;
+    private final File mExpected;
+    private final File mActual;
 
-    private final File mReference;
-
-    private final String mName;
-
-    public ComparisonTask(ITestDevice device, File reference, String name) {
+    public ComparisonTask(ITestDevice device, File expected, File actual) {
         mDevice = device;
-        mReference = reference;
-        mName = name;
+        mExpected = expected;
+        mActual = actual;
     }
 
     public Boolean call() {
         boolean success = false;
-        File generated = null;
+
         try {
-            generated = File.createTempFile("gen_" + mName, ".png");
-
-            final String remoteGenerated = String.format(STORAGE_PATH_DEVICE, mName);
-            if (!mDevice.doesFileExist(remoteGenerated)) {
-                Log.logAndDisplay(LogLevel.ERROR, TAG, "File " + remoteGenerated + " have not been saved on device");
-                return false;
-            }
-            mDevice.pullFile(remoteGenerated, generated);
-
-            final BufferedImage ref = ImageIO.read(mReference);
-            final BufferedImage gen = ImageIO.read(generated);
-            if (compare(ref, gen, IMAGE_THRESHOLD)) {
+            final BufferedImage expected = ImageIO.read(mExpected);
+            final BufferedImage actual = ImageIO.read(mActual);
+            if (compare(expected, actual, IMAGE_THRESHOLD)) {
                 success = true;
             } else {
-                File diff = File.createTempFile("diff_" + mName, ".png");
-                createDiff(ref, gen, diff);
+                final File diff = File.createTempFile("diff_" + mExpected.getName(), ".png");
+                createDiff(expected, actual, diff);
                 Log.logAndDisplay(LogLevel.INFO, TAG, "Diff created: " + diff.getPath());
             }
-        } catch (Exception e) {
-            Log.logAndDisplay(LogLevel.ERROR, TAG, String.format(STORAGE_PATH_DEVICE, mName));
+        } catch (IOException e) {
             Log.logAndDisplay(LogLevel.ERROR, TAG, e.toString());
             e.printStackTrace();
-        } finally {
-            if (generated != null) {
-                generated.delete();
-            }
         }
+
         return success;
     }
 
+    /**
+     * Verifies that the pixels of reference and generated images are similar
+     * within a specified threshold.
+     *
+     * @param expected expected image
+     * @param actual actual image
+     * @param threshold maximum difference per channel
+     * @return {@code true} if the images are similar, false otherwise
+     */
     private static int getAlphaScaledBlue(final int color) {
         return (color & 0x000000FF) * getAlpha(color) / 255;
     }
@@ -128,45 +120,49 @@
         return true;
     }
 
-    private static void createDiff(BufferedImage image1, BufferedImage image2, File out)
-            throws Exception {
-        final int w1 = image1.getWidth();
-        final int h1 = image1.getHeight();
-        final int w2 = image2.getWidth();
-        final int h2 = image2.getHeight();
+    private static void createDiff(BufferedImage expected, BufferedImage actual, File out)
+            throws IOException {
+        final int w1 = expected.getWidth();
+        final int h1 = expected.getHeight();
+        final int w2 = actual.getWidth();
+        final int h2 = actual.getHeight();
         final int width = Math.max(w1, w2);
         final int height = Math.max(h1, h2);
+
         // The diff will contain image1, image2 and the difference between the two.
-        final BufferedImage diff = new BufferedImage(width * 3, height, BufferedImage.TYPE_INT_ARGB);
+        final BufferedImage diff = new BufferedImage(
+                width * 3, height, BufferedImage.TYPE_INT_ARGB);
 
         for (int i = 0; i < width; i++) {
             for (int j = 0; j < height; j++) {
                 final boolean inBounds1 = i < w1 && j < h1;
                 final boolean inBounds2 = i < w2 && j < h2;
-                int color1 = Color.WHITE.getRGB();
-                int color2 = Color.WHITE.getRGB();
-                int color3;
+                int colorExpected = Color.WHITE.getRGB();
+                int colorActual = Color.WHITE.getRGB();
+                int colorDiff;
                 if (inBounds1 && inBounds2) {
-                    color1 = image1.getRGB(i, j);
-                    color2 = image2.getRGB(i, j);
-                    color3 = color1 == color2 ? color1 : Color.RED.getRGB();
+                    colorExpected = expected.getRGB(i, j);
+                    colorActual = actual.getRGB(i, j);
+                    colorDiff = colorExpected == colorActual ? colorExpected : Color.RED.getRGB();
                 } else if (inBounds1 && !inBounds2) {
-                    color1 = image1.getRGB(i, j);
-                    color3 = Color.BLUE.getRGB();
+                    colorExpected = expected.getRGB(i, j);
+                    colorDiff = Color.BLUE.getRGB();
                 } else if (!inBounds1 && inBounds2) {
-                    color2 = image2.getRGB(i, j);
-                    color3 = Color.GREEN.getRGB();
+                    colorActual = actual.getRGB(i, j);
+                    colorDiff = Color.GREEN.getRGB();
                 } else {
-                    color3 = Color.MAGENTA.getRGB();
+                    colorDiff = Color.MAGENTA.getRGB();
                 }
+
                 int x = i;
-                diff.setRGB(x, j, color1);
+                diff.setRGB(x, j, colorExpected);
                 x += width;
-                diff.setRGB(x, j, color2);
+                diff.setRGB(x, j, colorActual);
                 x += width;
-                diff.setRGB(x, j, color3);
+                diff.setRGB(x, j, colorDiff);
             }
         }
+
         ImageIO.write(diff, "png", out);
     }
 
diff --git a/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java b/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
index 8326b1f..b4bb748 100644
--- a/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
+++ b/hostsidetests/theme/src/android/theme/cts/ThemeHostTest.java
@@ -21,8 +21,8 @@
 import com.android.cts.util.TimeoutReq;
 import com.android.ddmlib.Log;
 import com.android.ddmlib.Log.LogLevel;
-import com.android.ddmlib.IShellOutputReceiver;
 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;
@@ -30,145 +30,44 @@
 import com.android.tradefed.testtype.IBuildReceiver;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.lang.String;
-import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Scanner;
-import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ExecutorCompletionService;
 import java.util.concurrent.ExecutorService;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
 /**
- * Test to check the Holo theme has not been changed.
+ * 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";
 
-    private static final String TAG = ThemeHostTest.class.getSimpleName();
-
-    private static final int ADB_TIMEOUT = 60 * 60 * 1000;//60mins in ms
-
-    /** The package name of the APK. */
-    private static final String PACKAGE = "android.theme.app";
-
-    /** The file name of the APK. */
-    private static final String APK = "CtsThemeDeviceApp.apk";
+    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 = "HoloDeviceActivity";
+    private static final String CLASS = "GenerateImagesActivity";
 
     /** The command to launch the main activity. */
     private static final String START_CMD = String.format(
-            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", PACKAGE, PACKAGE, CLASS);
+            "am start -W -a android.intent.action.MAIN -n %s/%s.%s", APP_PACKAGE_NAME,
+            APP_PACKAGE_NAME, CLASS);
 
-    private static final String CLEAR_GENERATED_CMD = "rm -rf /sdcard/cts-holo-assets/*.png";
-
-    private static final String STOP_CMD = String.format("am force-stop %s", PACKAGE);
-
+    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);
     private static final String HARDWARE_TYPE_CMD = "dumpsys | grep android.hardware.type";
-
     private static final String DENSITY_PROP_DEVICE = "ro.sf.lcd_density";
-
     private static final String DENSITY_PROP_EMULATOR = "qemu.sf.lcd_density";
 
-    // Intent extras
-    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";
-
-    // Intent extra keys
-    private static final String EXTRA_THEME = "holo_theme_extra";
-
-    private static final String[] THEMES = {
-            "holo",
-            "holo_dialog",
-            "holo_dialog_minwidth",
-            "holo_dialog_noactionbar",
-            "holo_dialog_noactionbar_minwidth",
-            "holo_dialogwhenlarge",
-            "holo_dialogwhenlarge_noactionbar",
-            "holo_inputmethod",
-            "holo_light",
-            "holo_light_darkactionbar",
-            "holo_light_dialog",
-            "holo_light_dialog_minwidth",
-            "holo_light_dialog_noactionbar",
-            "holo_light_dialog_noactionbar_minwidth",
-            "holo_light_dialogwhenlarge",
-            "holo_light_dialogwhenlarge_noactionbar",
-            "holo_light_noactionbar",
-            "holo_light_noactionbar_fullscreen",
-            "holo_light_panel",
-            "holo_noactionbar",
-            "holo_noactionbar_fullscreen",
-            "holo_panel",
-            "holo_wallpaper",
-            "holo_wallpaper_notitlebar",
-    };
-
-    private final int NUM_THEMES = THEMES.length;
-
-    private static final String[] LAYOUTS = {
-            "button",
-            "button_pressed",
-            "checkbox",
-            "checkbox_checked",
-            "chronometer",
-            "color_blue_bright",
-            "color_blue_dark",
-            "color_blue_light",
-            "color_green_dark",
-            "color_green_light",
-            "color_orange_dark",
-            "color_orange_light",
-            "color_purple",
-            "color_red_dark",
-            "color_red_light",
-            "datepicker",
-            "display_info",
-            "edittext",
-            "progressbar_horizontal_0",
-            "progressbar_horizontal_100",
-            "progressbar_horizontal_50",
-            "progressbar_large",
-            "progressbar_small",
-            "progressbar",
-            "radiobutton_checked",
-            "radiobutton",
-            "radiogroup_horizontal",
-            "radiogroup_vertical",
-            "ratingbar_0",
-            "ratingbar_2point5",
-            "ratingbar_5",
-            "ratingbar_0_pressed",
-            "ratingbar_2point5_pressed",
-            "ratingbar_5_pressed",
-            "searchview_query",
-            "searchview_query_hint",
-            "seekbar_0",
-            "seekbar_100",
-            "seekbar_50",
-            "spinner",
-            "switch_button_checked",
-            "switch_button",
-            "textview",
-            "timepicker",
-            "togglebutton_checked",
-            "togglebutton",
-            "zoomcontrols",
-    };
-
-    private final int NUM_LAYOUTS = LAYOUTS.length;
-
-    private final HashMap<String, File> mReferences = new HashMap<String, File>();
+    private final HashMap<String, File> mReferences = new HashMap<>();
 
     /** The ABI to use. */
     private IAbi mAbi;
@@ -197,32 +96,21 @@
     @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);
+        mDevice.uninstallPackage(APP_PACKAGE_NAME);
+
         // 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.
+        final File app = mBuild.getTestApp(String.format("%s.apk", APK_NAME));
+        final String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
+
         mDevice.installPackage(app, false, options);
-        // Remove previously generated images.
-        mDevice.executeShellCommand(CLEAR_GENERATED_CMD);
-        final String densityProp;
 
-        if (mDevice.getSerialNumber().startsWith("emulator-")) {
-            densityProp = DENSITY_PROP_EMULATOR;
-        } else {
-            densityProp = DENSITY_PROP_DEVICE;
-        }
+        final String density = getDensityBucketForDevice(mDevice);
+        final String zipFile = String.format("/%s.zip", density);
+        Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Loading resources from " + zipFile);
 
-        final String zip = String.format("/%s.zip",
-                getDensityBucket(Integer.parseInt(mDevice.getProperty(densityProp))));
-        Log.logAndDisplay(LogLevel.INFO, TAG, "Loading resources from " + zip);
-
-
-        final InputStream zipStream = this.getClass().getResourceAsStream(zip);
+        final InputStream zipStream = ThemeHostTest.class.getResourceAsStream(zipFile);
         if (zipStream != null) {
             final ZipInputStream in = new ZipInputStream(zipStream);
             try {
@@ -232,21 +120,28 @@
                     final String name = ze.getName();
                     final File tmp = File.createTempFile("ref_" + name, ".png");
                     final FileOutputStream out = new FileOutputStream(tmp);
+
                     int count;
                     while ((count = in.read(buffer)) != -1) {
                         out.write(buffer, 0, count);
                     }
+
                     out.flush();
                     out.close();
                     mReferences.put(name, tmp);
                 }
+            } catch (IOException e) {
+                Log.logAndDisplay(LogLevel.ERROR, LOG_TAG, "Failed to unzip assets: " + zipFile);
             } finally {
                 in.close();
             }
+        } else {
+            Log.logAndDisplay(LogLevel.ERROR, LOG_TAG, "Failed to get resource: " + zipFile);
         }
 
-        mExecutionService = Executors.newFixedThreadPool(2);// 2 worker threads
-        mCompletionService = new ExecutorCompletionService<Boolean>(mExecutionService);
+        final int numCores = Runtime.getRuntime().availableProcessors();
+        mExecutionService = Executors.newFixedThreadPool(numCores * 2);
+        mCompletionService = new ExecutorCompletionService<>(mExecutionService);
     }
 
     @Override
@@ -255,86 +150,148 @@
         for (File ref : mReferences.values()) {
             ref.delete();
         }
+
         mExecutionService.shutdown();
+
         // Remove the APK.
-        mDevice.uninstallPackage(PACKAGE);
+        mDevice.uninstallPackage(APP_PACKAGE_NAME);
+
         // Remove generated images.
         mDevice.executeShellCommand(CLEAR_GENERATED_CMD);
+
         super.tearDown();
     }
 
     @TimeoutReq(minutes = 60)
-    public void testHoloThemes() throws Exception {
-        if (checkHardwareTypeSkipTest(
-                mDevice.executeShellCommand(HARDWARE_TYPE_CMD).trim())) {
-            Log.logAndDisplay(LogLevel.INFO, TAG, "Skipped HoloThemes test for watch and TV");
+    public void testThemes() throws Exception {
+        if (checkHardwareTypeSkipTest(mDevice.executeShellCommand(HARDWARE_TYPE_CMD).trim())) {
+            Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Skipped themes test for watch");
             return;
         }
 
         if (mReferences.isEmpty()) {
-            Log.logAndDisplay(LogLevel.INFO, TAG,
-                    "Skipped HoloThemes test due to no reference images");
+            Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Skipped themes test due to no 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);
+
         int numTasks = 0;
-        for (int i = 0; i < NUM_THEMES; i++) {
-            final String themeName = THEMES[i];
-            runCapture(i, themeName);
-            for (int j = 0; j < NUM_LAYOUTS; j++) {
-                final String name = String.format("%s_%s", themeName, LAYOUTS[j]);
-                final File ref = mReferences.get(name + ".png");
-                if (!ref.exists()) {
-                    Log.logAndDisplay(LogLevel.INFO, TAG,
-                            "Skipping theme test due to missing reference for reference image " +
-                            name);
-                    continue;
+
+        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);
                 }
-                mCompletionService.submit(new ComparisonTask(mDevice, ref, name));
+
+                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...");
+
         int failures = 0;
-        for (int i = 0; i < numTasks; i++) {
+        for (int i = numTasks; i > 0; i--) {
             failures += mCompletionService.take().get() ? 0 : 1;
         }
+
         assertTrue(failures + " failures in theme test", failures == 0);
+
+        Log.logAndDisplay(LogLevel.INFO, LOG_TAG, "Finished!");
     }
 
-    private void runCapture(int themeId, String themeName) throws Exception {
-        final StringBuilder sb = new StringBuilder(START_CMD);
-        sb.append(String.format(INTENT_INTEGER_EXTRA, EXTRA_THEME, themeId));
-        final String startCommand = sb.toString();
+    private boolean generateDeviceImages() throws Exception {
         // Clear logcat
         mDevice.executeAdbCommand("logcat", "-c");
+
         // Stop any existing instances
         mDevice.executeShellCommand(STOP_CMD);
-        // Start activity
-        mDevice.executeShellCommand(startCommand);
 
+        // Start activity
+        mDevice.executeShellCommand(START_CMD);
+
+        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(":");
-                    final String s = lineSplit[1].trim();
-                    final String themeNameGenerated = lineSplit[2].trim();
-                    if (s.equals("OKAY") && themeNameGenerated.equals(themeName)) {
-                        waiting = false;
+                    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);
+        } while (waiting && !aborted);
+
+        Log.logAndDisplay(LogLevel.VERBOSE, LOG_TAG, "Image generation completed!");
+
+        return !aborted;
     }
 
-    private static String getDensityBucket(int density) {
+    private static String getDensityBucketForDevice(ITestDevice device) {
+        final String densityProp;
+        if (device.getSerialNumber().startsWith("emulator-")) {
+            densityProp = DENSITY_PROP_EMULATOR;
+        } else {
+            densityProp = DENSITY_PROP_DEVICE;
+        }
+
+        final int density;
+        try {
+            density = Integer.parseInt(device.getProperty(densityProp));
+        } catch (DeviceNotAvailableException e) {
+            return "unknown";
+        }
+
         switch (density) {
             case 120:
                 return "ldpi";
@@ -363,9 +320,7 @@
         if (hardwareTypeString.contains("android.hardware.type.watch")) {
             return true;
         }
-        if (hardwareTypeString.contains("android.hardware.type.television")) {
-            return true;
-        }
+
         return false;
     }
 }
diff --git a/hostsidetests/usage/Android.mk b/hostsidetests/usage/Android.mk
new file mode 100644
index 0000000..1d4e36d
--- /dev/null
+++ b/hostsidetests/usage/Android.mk
@@ -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.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_MODULE := CtsUsageHostTestCases
+
+LOCAL_JAVA_LIBRARIES := cts-tradefed tradefed-prebuilt
+
+LOCAL_CTS_TEST_PACKAGE := android.host.app.usage
+
+include $(BUILD_CTS_HOST_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/hostsidetests/usage/app/Android.mk b/hostsidetests/usage/app/Android.mk
new file mode 100644
index 0000000..b23efbc
--- /dev/null
+++ b/hostsidetests/usage/app/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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
+
+LOCAL_PACKAGE_NAME := CtsDeviceAppUsageTestApp
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/hostsidetests/usage/app/AndroidManifest.xml b/hostsidetests/usage/app/AndroidManifest.xml
new file mode 100755
index 0000000..bad453f
--- /dev/null
+++ b/hostsidetests/usage/app/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?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.app.usage.test">
+
+    <application>
+        <activity android:name=".TestActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
+
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
new file mode 100644
index 0000000..9432477
--- /dev/null
+++ b/hostsidetests/usage/app/src/com/android/cts/app/usage/test/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 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/com/android/cts/app/usage/AppIdleHostTest.java b/hostsidetests/usage/src/com/android/cts/app/usage/AppIdleHostTest.java
new file mode 100644
index 0000000..b94d086
--- /dev/null
+++ b/hostsidetests/usage/src/com/android/cts/app/usage/AppIdleHostTest.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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/libs/commonutil/src/com/android/cts/util/ReportLog.java b/libs/commonutil/src/com/android/cts/util/ReportLog.java
index 56b431a..dd4b414 100644
--- a/libs/commonutil/src/com/android/cts/util/ReportLog.java
+++ b/libs/commonutil/src/com/android/cts/util/ReportLog.java
@@ -42,26 +42,55 @@
 
     /**
      * print array of values to output log
+     * <p>Note: test identifier is inferred from call stack trace based on class and method name
      */
     public void printArray(String message, double[] values, ResultType type, ResultUnit unit) {
         doPrintArray(message, values, type, unit);
     }
 
     /**
+     * print array of values to output log
+     */
+    public void printArray(String testId, String message,
+            double[] values, ResultType type, ResultUnit unit) {
+        doPrintArray(testId, message, values, type, unit);
+    }
+
+    /**
      * Print a value to output log
+     * <p>Note: test identifier is inferred from call stack trace based on class and method name
      */
     public void printValue(String message, double value, ResultType type, ResultUnit unit) {
         double[] vals = { value };
         doPrintArray(message, vals, type, unit);
     }
 
+    /**
+     * Print a value to output log
+     */
+    public void printValue(String testId, String message,
+            double value, ResultType type, ResultUnit unit) {
+        double[] vals = { value };
+        doPrintArray(testId, message, vals, type, unit);
+    }
+
     private void doPrintArray(String message, double[] values, ResultType type, ResultUnit unit) {
+        doPrintArray(getClassMethodNames(mDepth + 1, true), message, values, type, unit);
+    }
+
+    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(getClassMethodNames(mDepth + 1, true) + LOG_ELEM_SEPARATOR + message +
-                LOG_ELEM_SEPARATOR + type.getXmlString() + LOG_ELEM_SEPARATOR +
-                unit.getXmlString() + LOG_ELEM_SEPARATOR);
+        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(" ");
diff --git a/libs/commonutil/src/com/android/cts/util/StatisticsUtils.java b/libs/commonutil/src/com/android/cts/util/StatisticsUtils.java
new file mode 100644
index 0000000..d6589af
--- /dev/null
+++ b/libs/commonutil/src/com/android/cts/util/StatisticsUtils.java
@@ -0,0 +1,112 @@
+/*
+ * 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
new file mode 100644
index 0000000..d78ba99
--- /dev/null
+++ b/libs/commonutil/src/com/android/cts/util/StatisticsUtilsTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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/src/android/cts/util/LocationUtils.java b/libs/deviceutil/src/android/cts/util/LocationUtils.java
new file mode 100644
index 0000000..1f7af86
--- /dev/null
+++ b/libs/deviceutil/src/android/cts/util/LocationUtils.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 android.cts.util;
+
+import android.app.Instrumentation;
+import android.util.Log;
+
+import java.io.IOException;
+
+public class LocationUtils {
+    private static String TAG = "LocationUtils";
+
+    public static void registerMockLocationProvider(Instrumentation instrumentation,
+            boolean enable) {
+        StringBuilder command = new StringBuilder();
+        command.append("appops set ");
+        command.append(instrumentation.getContext().getPackageName());
+        command.append(" android:mock_location ");
+        command.append(enable ? "allow" : "deny");
+        try {
+            SystemUtil.runShellCommand(instrumentation, command.toString());
+        } catch (IOException e) {
+            Log.e(TAG, "Error managing mock location app. Command: " + command, e);
+        }
+    }
+}
diff --git a/libs/deviceutil/src/android/cts/util/MediaUtils.java b/libs/deviceutil/src/android/cts/util/MediaUtils.java
index 5908923..0a454b6 100755
--- a/libs/deviceutil/src/android/cts/util/MediaUtils.java
+++ b/libs/deviceutil/src/android/cts/util/MediaUtils.java
@@ -19,13 +19,22 @@
 import android.content.res.AssetFileDescriptor;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.VideoCapabilities;
 import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
 import android.net.Uri;
+import android.util.Range;
+
+import com.android.cts.util.ReportLog;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+
 import java.lang.reflect.Method;
 import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isStatic;
+import java.util.Arrays;
 import java.util.Map;
 import android.util.Log;
 
@@ -151,6 +160,14 @@
         return null;
     }
 
+    public static boolean canEncode(MediaFormat format) {
+        if (sMCL.findEncoderForFormat(format) == null) {
+            Log.i(TAG, "no encoder for " + format);
+            return false;
+        }
+        return true;
+    }
+
     public static boolean canDecode(MediaFormat format) {
         if (sMCL.findDecoderForFormat(format) == null) {
             Log.i(TAG, "no decoder for " + format);
@@ -159,6 +176,40 @@
         return true;
     }
 
+    public static boolean supports(String codecName, String mime, int w, int h) {
+        MediaCodec codec;
+        try {
+            codec = MediaCodec.createByCodecName(codecName);
+        } catch (IOException e) {
+            return false;
+        }
+
+        CodecCapabilities cap = null;
+        try {
+            cap = codec.getCodecInfo().getCapabilitiesForType(mime);
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "not supported mime: " + mime);
+            codec.release();
+            return false;
+        }
+
+        VideoCapabilities vidCap = cap.getVideoCapabilities();
+        if (vidCap == null) {
+            Log.w(TAG, "not a video codec: " + codecName);
+            codec.release();
+            return false;
+        }
+        try {
+            Range<Double> fps = vidCap.getSupportedFrameRatesFor(w, h);
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "unsupported size " + w + "x" + h);
+            codec.release();
+            return false;
+        }
+        codec.release();
+        return true;
+    }
+
     public static boolean hasCodecForTrack(MediaExtractor ex, int track) {
         int count = ex.getTrackCount();
         if (track < 0 || track >= count) {
@@ -287,13 +338,34 @@
                 ex.release();
             }
         }
-        return false;
+        return true;
     }
 
     public static boolean checkCodecsForPath(Context context, String path) {
         return check(hasCodecsForPath(context, path), "no decoder found");
     }
 
+    public static boolean hasCodecForDomain(boolean encoder, String domain) {
+        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
+            if (encoder != info.isEncoder()) {
+                continue;
+            }
+
+            for (String type : info.getSupportedTypes()) {
+                if (type.toLowerCase().startsWith(domain.toLowerCase() + "/")) {
+                    Log.i(TAG, "found codec " + info.getName() + " for mime " + type);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public static boolean checkCodecForDomain(boolean encoder, String domain) {
+        return check(hasCodecForDomain(encoder, domain),
+                "no " + domain + (encoder ? " encoder" : " decoder") + " found");
+    }
+
     private static boolean hasCodecForMime(boolean encoder, String mime) {
         for (MediaCodecInfo info : sMCL.getCodecInfos()) {
             if (encoder != info.isEncoder()) {
@@ -343,7 +415,159 @@
         return canDecode(format);
     }
 
+    public static boolean checkEncoderForFormat(MediaFormat format) {
+        return check(canEncode(format), "no encoder for " + format);
+    }
+
     public static boolean checkDecoderForFormat(MediaFormat format) {
         return check(canDecode(format), "no decoder for " + format);
     }
+
+    public static MediaExtractor createMediaExtractorForMimeType(
+            Context context, int resourceId, String mimeTypePrefix)
+            throws IOException {
+        MediaExtractor extractor = new MediaExtractor();
+        AssetFileDescriptor afd = context.getResources().openRawResourceFd(resourceId);
+        try {
+            extractor.setDataSource(
+                    afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+        } finally {
+            afd.close();
+        }
+        int trackIndex;
+        for (trackIndex = 0; trackIndex < extractor.getTrackCount(); trackIndex++) {
+            MediaFormat trackMediaFormat = extractor.getTrackFormat(trackIndex);
+            if (trackMediaFormat.getString(MediaFormat.KEY_MIME).startsWith(mimeTypePrefix)) {
+                extractor.selectTrack(trackIndex);
+                break;
+            }
+        }
+        if (trackIndex == extractor.getTrackCount()) {
+            extractor.release();
+            throw new IllegalStateException("couldn't get a track for " + mimeTypePrefix);
+        }
+
+        return extractor;
+    }
+
+    /**
+     * return the average value of the passed array.
+     */
+    public static double getAverage(double[] data) {
+        int num = data.length;
+        if (num == 0) {
+            return 0;
+        }
+
+        double sum = data[0];
+        for (int i = 1; i < num; i++) {
+            sum += data[i];
+        }
+        return sum / num;
+    }
+
+    /**
+     * return the standard deviation value of the passed array
+     */
+    public static double getStdev(double[] data) {
+        double average = getAverage(data);
+        int num = data.length;
+        if (num == 0) {
+            return 0;
+        }
+        double variance = 0;
+        for (int i = 0; i < num; ++i) {
+            variance += (data[i] - average) * (data[i] - average);
+        }
+        variance /= num;
+        return Math.sqrt(variance);
+    }
+
+    public static double[] calculateMovingAverage(double[] array, int n) {
+        int num = array.length;
+        if (num < n) {
+            return null;
+        }
+        int avgsNum = num - n + 1;
+        double[] avgs = new double[avgsNum];
+        double sum = array[0];
+        for (int i = 1; i < n; ++i) {
+            sum += array[i];
+        }
+        avgs[0] = sum / n;
+
+        for (int i = n; i < num; ++i) {
+            sum = sum - array[i - n] + array[i];
+            avgs[i - n + 1] = sum / n;
+        }
+        return avgs;
+    }
+
+    public static String logResults(ReportLog log, String prefix,
+            double min, double max, double avg, double stdev) {
+        String msg = prefix;
+        msg += " min=" + Math.round(min / 1000) + " max=" + Math.round(max / 1000) +
+                " avg=" + Math.round(avg / 1000) + " stdev=" + Math.round(stdev / 1000);
+        log.printValue(msg, 1000000000 / min, ResultType.HIGHER_BETTER, ResultUnit.FPS);
+        return msg;
+    }
+
+    public static VideoCapabilities getVideoCapabilities(String codecName, String mime) {
+        for (MediaCodecInfo info : sMCL.getCodecInfos()) {
+            if (!info.getName().equalsIgnoreCase(codecName)) {
+                continue;
+            }
+            CodecCapabilities caps;
+            try {
+                caps = info.getCapabilitiesForType(mime);
+            } catch (IllegalArgumentException e) {
+                // mime is not supported
+                continue;
+            }
+            return caps.getVideoCapabilities();
+        }
+        return null;
+    }
+
+    public static Range<Double> getAchievableFrameRatesFor(
+            String codecName, String mimeType, int width, int height) {
+        VideoCapabilities cap = getVideoCapabilities(codecName, mimeType);
+        if (cap == null) {
+            return null;
+        }
+        return cap.getAchievableFrameRatesFor(width, height);
+    }
+
+    private static final double FRAMERATE_TOLERANCE = Math.sqrt(12.1);
+    public static boolean verifyResults(String name, String mime, int w, int h, double measured) {
+        Range<Double> reported = getAchievableFrameRatesFor(name, mime, w, h);
+        if (reported == null) {
+            Log.d(TAG, "Failed to getAchievableFrameRatesFor " +
+                    name + " " + mime + " " + w + "x" + h);
+            return false;
+        }
+        double lowerBoundary1 = reported.getLower() / FRAMERATE_TOLERANCE;
+        double upperBoundary1 = reported.getUpper() * FRAMERATE_TOLERANCE;
+        double lowerBoundary2 = reported.getUpper() / Math.pow(FRAMERATE_TOLERANCE, 2);
+        double upperBoundary2 = reported.getLower() * Math.pow(FRAMERATE_TOLERANCE, 2);
+        Log.d(TAG, name + " " + mime + " " + w + "x" + h + " " +
+                "lowerBoundary1 " + lowerBoundary1 + " upperBoundary1 " + upperBoundary1 +
+                " lowerBoundary2 " + lowerBoundary2 + " upperBoundary2 " + upperBoundary2 +
+                " measured " + measured);
+        return (measured >= lowerBoundary1 && measured <= upperBoundary1 &&
+                measured >= lowerBoundary2 && measured <= upperBoundary2);
+    }
+
+    public static String getErrorMessage(
+            Range<Double> reportedRange, double[] measuredFps, String[] rawData) {
+        String msg = "";
+        if (reportedRange == null) {
+            msg += "Failed to get achievable frame rate.\n";
+        } else {
+            msg += "Expected achievable frame rate range: " + reportedRange + ".\n";
+        }
+        msg += "Measured frame rate: " + Arrays.toString(measuredFps) + ".\n";
+        msg += "Raw data: " + Arrays.toString(rawData) + ".\n";
+        return msg;
+    }
 }
diff --git a/libs/deviceutil/src/android/cts/util/SystemUtil.java b/libs/deviceutil/src/android/cts/util/SystemUtil.java
index e6222cb..6e7fd38 100644
--- a/libs/deviceutil/src/android/cts/util/SystemUtil.java
+++ b/libs/deviceutil/src/android/cts/util/SystemUtil.java
@@ -18,9 +18,14 @@
 
 import android.app.ActivityManager;
 import android.app.ActivityManager.MemoryInfo;
+import android.app.Instrumentation;
 import android.content.Context;
+import android.os.ParcelFileDescriptor;
 import android.os.StatFs;
 
+import java.io.FileInputStream;
+import java.io.IOException;
+
 public class SystemUtil {
     public static long getFreeDiskSize(Context context) {
         StatFs statFs = new StatFs(context.getFilesDir().getAbsolutePath());
@@ -40,4 +45,28 @@
         activityManager.getMemoryInfo(info);
         return info.totalMem; // TODO totalMem N/A in ICS.
     }
+
+    /**
+     * Executes a shell command using shell user identity, and return the standard output in string
+     * <p>Note: calling this function requires API level 21 or above
+     * @param instrumentation {@link Instrumentation} instance, obtained from a test running in
+     * instrumentation framework
+     * @param cmd the command to run
+     * @return the standard output of the command
+     * @throws Exception
+     */
+    public static String runShellCommand(Instrumentation instrumentation, String cmd)
+            throws IOException {
+        ParcelFileDescriptor pfd = instrumentation.getUiAutomation().executeShellCommand(cmd);
+        byte[] buf = new byte[512];
+        int bytesRead;
+        FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+        StringBuffer stdout = new StringBuffer();
+        while ((bytesRead = fis.read(buf)) != -1) {
+            stdout.append(new String(buf, 0, bytesRead));
+        }
+        fis.close();
+        return stdout.toString();
+    }
+
 }
diff --git a/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
index bcb8cb2..b9ee987 100644
--- a/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
+++ b/libs/deviceutillegacy/src/android/webkit/cts/WebViewOnUiThread.java
@@ -21,6 +21,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Picture;
 import android.graphics.Rect;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Looper;
 import android.os.Message;
@@ -36,9 +37,12 @@
 import android.webkit.ValueCallback;
 import android.webkit.WebBackForwardList;
 import android.webkit.WebChromeClient;
+import android.webkit.WebMessage;
+import android.webkit.WebMessagePort;
 import android.webkit.WebSettings;
 import android.webkit.WebView.HitTestResult;
 import android.webkit.WebView.PictureListener;
+import android.webkit.WebView.VisualStateCallback;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 
@@ -306,6 +310,24 @@
         });
     }
 
+    public WebMessagePort[] createWebMessageChannel() {
+        return getValue(new ValueGetter<WebMessagePort[]>() {
+            @Override
+            public WebMessagePort[] capture() {
+                return mWebView.createWebMessageChannel();
+            }
+        });
+    }
+
+    public void postWebMessage(final WebMessage message, final Uri targetOrigin) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mWebView.postWebMessage(message, targetOrigin);
+            }
+        });
+    }
+
     public void addJavascriptInterface(final Object object, final String name) {
         runOnUiThread(new Runnable() {
             @Override
@@ -628,6 +650,15 @@
         });
     }
 
+    public void postVisualStateCallback(final long requestId, final VisualStateCallback callback) {
+        runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mWebView.postVisualStateCallback(requestId, callback);
+            }
+        });
+    }
+
     public int[] getLocationOnScreen() {
         final int[] location = new int[2];
         return getValue(new ValueGetter<int[]>() {
diff --git a/libs/testserver/Android.mk b/libs/testserver/Android.mk
index dfe357b..488af53 100644
--- a/libs/testserver/Android.mk
+++ b/libs/testserver/Android.mk
@@ -22,4 +22,6 @@
 
 LOCAL_MODULE := ctstestserver
 
+LOCAL_SDK_VERSION := 16
+
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/libs/testserver/src/android/webkit/cts/CtsTestServer.java b/libs/testserver/src/android/webkit/cts/CtsTestServer.java
index 22cbb7b..de88f3b 100644
--- a/libs/testserver/src/android/webkit/cts/CtsTestServer.java
+++ b/libs/testserver/src/android/webkit/cts/CtsTestServer.java
@@ -15,7 +15,6 @@
  */
 package android.webkit.cts;
 
-import libcore.io.Base64;
 import org.apache.http.Header;
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpEntityEnclosingRequest;
@@ -44,6 +43,7 @@
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Environment;
+import android.util.Base64;
 import android.util.Log;
 import android.webkit.MimeTypeMap;
 
@@ -229,12 +229,30 @@
             // request for shutdown and having the server's one thread
             // sequentially call accept() and close().
             URL url = new URL(mServerUri + SHUTDOWN_PREFIX);
-            URLConnection connection = openConnection(url);
-            connection.connect();
+            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();
+                // 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();
@@ -947,7 +965,7 @@
          * for the result.
          */
         private static KeyManager[] getKeyManagers() throws Exception {
-            byte[] bytes = Base64.decode(SERVER_KEYS_BKS.getBytes());
+            byte[] bytes = Base64.decode(SERVER_KEYS_BKS.getBytes(), Base64.DEFAULT);
             InputStream inputStream = new ByteArrayInputStream(bytes);
 
             KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
@@ -1014,7 +1032,7 @@
                         conn.receiveRequestEntity( (HttpEntityEnclosingRequest) request);
                     }
 
-                    mExecutorService.submit(new HandleResponseTask(conn, request));
+                    mExecutorService.execute(new HandleResponseTask(conn, request));
                 } catch (IOException e) {
                     // normal during shutdown, ignore
                     Log.w(TAG, e);
@@ -1045,7 +1063,7 @@
             return path.equals(SHUTDOWN_PREFIX);
         }
 
-        private class HandleResponseTask implements Callable<Void> {
+        private class HandleResponseTask implements Runnable {
 
             private DefaultHttpServerConnection mConnection;
 
@@ -1058,12 +1076,15 @@
             }
 
             @Override
-            public Void call() throws Exception {
-                HttpResponse response = mServer.getResponse(mRequest);
-                mConnection.sendResponseHeader(response);
-                mConnection.sendResponseEntity(response);
-                mConnection.close();
-                return null;
+            public void run() {
+                try {
+                    HttpResponse response = mServer.getResponse(mRequest);
+                    mConnection.sendResponseHeader(response);
+                    mConnection.sendResponseEntity(response);
+                    mConnection.close();
+                } catch (Exception e) {
+                    Log.e(TAG, "Error handling request:", e);
+                }
             }
         }
     }
diff --git a/libs/vogar-expect/src/vogar/Expectation.java b/libs/vogar-expect/src/vogar/Expectation.java
index f065f42..ddbc233f 100644
--- a/libs/vogar-expect/src/vogar/Expectation.java
+++ b/libs/vogar-expect/src/vogar/Expectation.java
@@ -16,7 +16,6 @@
 
 package vogar;
 
-import java.util.Collections;
 import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.regex.Pattern;
@@ -37,14 +36,6 @@
  */
 public final class Expectation {
 
-    /** The pattern to use when no expected output is specified */
-    public static final Pattern MATCH_ALL_PATTERN
-            = Pattern.compile(".*", Pattern.MULTILINE | Pattern.DOTALL);
-
-    /** The expectation of a general successful run. */
-    public static final Expectation SUCCESS = new Expectation(Result.SUCCESS, MATCH_ALL_PATTERN,
-            Collections.<String>emptySet(), "", -1);
-
     /** Justification for this expectation */
     private final String description;
 
diff --git a/libs/vogar-expect/src/vogar/ExpectationStore.java b/libs/vogar-expect/src/vogar/ExpectationStore.java
index cfa20e9..090322d 100644
--- a/libs/vogar-expect/src/vogar/ExpectationStore.java
+++ b/libs/vogar-expect/src/vogar/ExpectationStore.java
@@ -26,6 +26,7 @@
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -50,7 +51,17 @@
  * expectation, the outcome expectation will be returned.
  */
 public final class ExpectationStore {
+
+    /** The pattern to use when no expected output is specified */
+    private static final Pattern MATCH_ALL_PATTERN
+            = Pattern.compile(".*", Pattern.MULTILINE | Pattern.DOTALL);
+
+    /** The expectation of a general successful run. */
+    private static final Expectation SUCCESS = new Expectation(Result.SUCCESS, MATCH_ALL_PATTERN,
+            Collections.<String>emptySet(), "", -1);
+
     private static final int PATTERN_FLAGS = Pattern.MULTILINE | Pattern.DOTALL;
+
     private final Map<String, Expectation> outcomes = new LinkedHashMap<String, Expectation>();
     private final Map<String, Expectation> failures = new LinkedHashMap<String, Expectation>();
 
@@ -62,7 +73,7 @@
      */
     public Expectation get(String name) {
         Expectation byName = getByNameOrPackage(name);
-        return byName != null ? byName : Expectation.SUCCESS;
+        return byName != null ? byName : SUCCESS;
     }
 
     /**
@@ -87,7 +98,7 @@
         }
 
         Expectation byName = getByNameOrPackage(outcome.getName());
-        return byName != null ? byName : Expectation.SUCCESS;
+        return byName != null ? byName : SUCCESS;
     }
 
     private Expectation getByNameOrPackage(String name) {
@@ -141,8 +152,8 @@
 
     private void readExpectation(JsonReader reader, ModeId mode) throws IOException {
         boolean isFailure = false;
-        Result result = Result.SUCCESS;
-        Pattern pattern = Expectation.MATCH_ALL_PATTERN;
+        Result result = Result.EXEC_FAILED;
+        Pattern pattern = MATCH_ALL_PATTERN;
         Set<String> names = new LinkedHashSet<String>();
         Set<String> tags = new LinkedHashSet<String>();
         Set<ModeId> modes = null;
@@ -159,6 +170,12 @@
             } else if (name.equals("names")) {
                 readStrings(reader, names);
             } else if (name.equals("failure")) {
+                // isFailure is somewhat arbitrarily keyed on the existence of a "failure"
+                // element instead of looking at the "result" field. There are only about 5
+                // expectations in our entire expectation store that have this tag.
+                //
+                // TODO: Get rid of it and the "failures" map and just use the outcomes
+                // map for everything. Both uses seem useless.
                 isFailure = true;
                 names.add(reader.nextString());
             } else if (name.equals("pattern")) {
diff --git a/suite/audio_quality/test/Android.mk b/suite/audio_quality/test/Android.mk
index 4582fe7..bd0033f 100644
--- a/suite/audio_quality/test/Android.mk
+++ b/suite/audio_quality/test/Android.mk
@@ -34,7 +34,7 @@
 # functions and linker error happens
 LOCAL_WHOLE_STATIC_LIBRARIES := libcts_audio_quality
 LOCAL_CFLAGS:= -g -fno-exceptions
-LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions -lpthread
+LOCAL_LDFLAGS:= -g -lrt -ldl -lm -fno-exceptions -lpthread
 LOCAL_MODULE:= cts_audio_quality_test
 include $(BUILD_HOST_EXECUTABLE)
 
diff --git a/suite/cts/deviceTests/filesystemperf/Android.mk b/suite/cts/deviceTests/filesystemperf/Android.mk
index 843d21a..7ee93de 100644
--- a/suite/cts/deviceTests/filesystemperf/Android.mk
+++ b/suite/cts/deviceTests/filesystemperf/Android.mk
@@ -26,5 +26,7 @@
 
 LOCAL_SDK_VERSION := 16
 
+cts_runtime_hint := 28
+
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/suite/cts/deviceTests/jank2/Android.mk b/suite/cts/deviceTests/jank2/Android.mk
new file mode 100644
index 0000000..346297e
--- /dev/null
+++ b/suite/cts/deviceTests/jank2/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_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
new file mode 100644
index 0000000..a4c8337
--- /dev/null
+++ b/suite/cts/deviceTests/jank2/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="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
new file mode 100644
index 0000000..2fbbac7
--- /dev/null
+++ b/suite/cts/deviceTests/jank2/AndroidTest.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 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
new file mode 100644
index 0000000..cb5c122
--- /dev/null
+++ b/suite/cts/deviceTests/jank2/src/android/cts/jank/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.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
new file mode 100644
index 0000000..884f83c
--- /dev/null
+++ b/suite/cts/deviceTests/jank2/src/android/cts/jank/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.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/jni/graphics/Renderer.cpp b/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp
index b8e2acf..16504fd 100644
--- a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/graphics/Renderer.cpp
@@ -22,6 +22,14 @@
 
 // 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;
 
@@ -66,7 +74,7 @@
         EGL_NONE };
 
 static const EGLint configAttribs[] = {
-        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
+        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
         EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
         EGL_RED_SIZE, 8,
         EGL_GREEN_SIZE, 8,
@@ -78,53 +86,60 @@
 
 static const int FBO_SIZE = 128;
 
-Renderer::Renderer(ANativeWindow* window, bool offscreen, int workload) :
-        mOffscreen(offscreen), mWindow(window), mEglDisplay(EGL_NO_DISPLAY),
-        mEglSurface(EGL_NO_SURFACE), mEglContext(EGL_NO_CONTEXT), mWorkload(workload) {
+Renderer::Renderer(EGLNativeWindowType window, bool offscreen) :
+        mOffscreen(offscreen), mEglDisplay(EGL_NO_DISPLAY), mEglSurface(EGL_NO_SURFACE),
+        mEglContext(EGL_NO_CONTEXT), mWindow(window)  {
 }
 
-bool Renderer::setUp() {
+bool Renderer::eglSetUp() {
     SCOPED_TRACE();
     mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    if (EGL_NO_DISPLAY == mEglDisplay || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+    EGL_RESULT_CHECK(mEglDisplay != EGL_NO_DISPLAY);
 
     EGLint major;
     EGLint minor;
-    if (!eglInitialize(mEglDisplay, &major, &minor) || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+    EGL_RESULT_CHECK(eglInitialize(mEglDisplay, &major, &minor));
 
     EGLint numConfigs = 0;
-    if (!eglChooseConfig(mEglDisplay, configAttribs, &mGlConfig, 1, &numConfigs)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+    EGL_RESULT_CHECK(eglChooseConfig(mEglDisplay, configAttribs, &mGlConfig, 1, &numConfigs)
+                     && (numConfigs > 0));
 
     mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig, mWindow, NULL);
-    if (EGL_NO_SURFACE == mEglSurface || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+    EGL_RESULT_CHECK(mEglSurface != EGL_NO_SURFACE);
 
     mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT, contextAttribs);
-    if (EGL_NO_CONTEXT == mEglContext || EGL_SUCCESS != eglGetError()) {
-        return false;
+    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 (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
+    if (mEglSurface != EGL_NO_SURFACE) {
+        mEglSurface = EGL_NO_SURFACE;
     }
 
-    if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &mWidth)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
+    if (mEglDisplay != EGL_NO_DISPLAY) {
+        eglTerminate(mEglDisplay);
+        mEglDisplay = EGL_NO_DISPLAY;
     }
-    if (!eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &mHeight)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+}
+
+bool Renderer::setUp(int /*workload*/) {
+    SCOPED_TRACE();
+
+    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
 
     if (mOffscreen) {
         mFboWidth = FBO_SIZE;
@@ -178,6 +193,7 @@
         ALOGE("GLError %d in setUp", err);
         return false;
     }
+
     return true;
 }
 
@@ -202,29 +218,14 @@
         ALOGE("GLError %d in tearDown", err);
         return false;
     }
-    if (mEglContext != EGL_NO_CONTEXT) {
-        eglDestroyContext(mEglDisplay, mEglContext);
-        mEglContext = EGL_NO_CONTEXT;
-    }
-    if (mEglSurface != EGL_NO_SURFACE) {
-        eglDestroySurface(mEglDisplay, mEglSurface);
-        mEglSurface = EGL_NO_SURFACE;
-    }
-    if (mEglDisplay != EGL_NO_DISPLAY) {
-        eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-        eglTerminate(mEglDisplay);
-        mEglDisplay = EGL_NO_DISPLAY;
-    }
 
-    return EGL_SUCCESS == eglGetError();
+    return true;
 }
 
 bool Renderer::draw() {
     SCOPED_TRACE();
-    if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)
-            || EGL_SUCCESS != eglGetError()) {
-        return false;
-    }
+
+    EGL_RESULT_CHECK(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext));
 
     glBindFramebuffer(GL_FRAMEBUFFER, 0);
     glViewport(0, 0, mWidth, mHeight);
@@ -287,5 +288,6 @@
         return false;
     }
 
-    return eglSwapBuffers(mEglDisplay, mEglSurface);
+    EGL_RESULT_CHECK(eglSwapBuffers(mEglDisplay, mEglSurface)); 
+    return true;
 }
diff --git a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.h b/suite/cts/deviceTests/opengl/jni/graphics/Renderer.h
index caa1634..3c62a26 100644
--- a/suite/cts/deviceTests/opengl/jni/graphics/Renderer.h
+++ b/suite/cts/deviceTests/opengl/jni/graphics/Renderer.h
@@ -14,17 +14,18 @@
 #ifndef RENDERER_H
 #define RENDERER_H
 
-#include <android/native_window.h>
-
 #include <EGL/egl.h>
 #include <GLES2/gl2.h>
 #include <GLES2/gl2ext.h>
 
 class Renderer {
 public:
-    Renderer(ANativeWindow* window, bool offscreen, int workload);
-    virtual bool setUp();
+    Renderer(EGLNativeWindowType window, bool offscreen);
+    virtual bool setUp(int workload);
     virtual bool tearDown();
+    bool eglSetUp();
+    void eglTearDown();
+
     bool draw();
     virtual void drawWorkload() = 0;
     virtual ~Renderer() {};
@@ -32,7 +33,6 @@
     static const int OFFSCREEN_GRID_SIZE = 10;
     bool mOffscreen;
 protected:
-    ANativeWindow* mWindow;
     EGLDisplay mEglDisplay;
     EGLSurface mEglSurface;
     EGLContext mEglContext;
@@ -40,7 +40,6 @@
     GLuint mProgramId;
     EGLint mWidth;
     EGLint mHeight;
-    int mWorkload;
     int mFboWidth;// Frame buffer width
     int mFboHeight;// Frame buffer height
     GLuint mFboId;// Frame buffer id
@@ -52,5 +51,7 @@
     GLuint mFboYOffsetUniformHandle;// Frame buffer y offset uniform handle
     GLuint mFboPositionHandle;// Frame buffer position handle
     GLuint mFboTexCoordHandle;// Frame buffer texture coordinate handle
+private:
+    EGLNativeWindowType mWindow;
 };
 #endif
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp b/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
index 9d39af9..856da1e 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/GLPrimitive.cpp
@@ -28,16 +28,24 @@
 
 // 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 numFrames, jdoubleArray frameTimes) {
+        JNIEnv* env, jclass /*clazz*/, jint workload, jint numFrames, jdoubleArray frameTimes) {
     if (gRenderer == NULL) {
         return false;
     }
 
     // Sets up the renderer.
-    bool success = gRenderer->setUp();
+    bool success = gRenderer->setUp(workload);
 
     // Records the start time.
     double start = GLUtils::currentTimeMillis();
@@ -60,41 +68,56 @@
     double times[] = {start, end};
     env->SetDoubleArrayRegion(frameTimes, 0, 2, times);
 
-    // Tears down and deletes the renderer.
     success = gRenderer->tearDown() && success;
-    delete gRenderer;
-    gRenderer = NULL;
     return success;
 }
 
 // The following functions create the renderers for the various benchmarks.
 extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupFullPipelineBenchmark(
-        JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint workload) {
-    gRenderer = new FullPipelineRenderer(
-            ANativeWindow_fromSurface(env, surface), offscreen, workload);
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupPixelOutputBenchmark(
-        JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint workload) {
-    gRenderer = new PixelOutputRenderer(
-            ANativeWindow_fromSurface(env, surface), offscreen, workload);
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupShaderPerfBenchmark(
-        JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint workload) {
-    gRenderer = new ShaderPerfRenderer(
-            ANativeWindow_fromSurface(env, surface), offscreen, workload);
-}
-
-extern "C" JNIEXPORT void JNICALL
-Java_com_android_cts_opengl_primitive_GLPrimitiveActivity_setupContextSwitchBenchmark(
-        JNIEnv* env, jclass clazz, jobject surface, jboolean offscreen, jint workload) {
-    if (workload <= 8) {
-        // This test uses 8 iterations, so workload can't be more than 8.
-        gRenderer = new ContextSwitchRenderer(
-                ANativeWindow_fromSurface(env, surface), offscreen, workload);
+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
index 7fd4093..1127d88 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.cpp
@@ -74,13 +74,14 @@
         "  gl_FragColor = texture2D(u_Texture, v_TexCoord);"
         "}";
 
-ContextSwitchRenderer::ContextSwitchRenderer(ANativeWindow* window, bool offscreen, int workload) :
-        Renderer(window, offscreen, workload), mContexts(NULL) {
+ContextSwitchRenderer::ContextSwitchRenderer(ANativeWindow* window, bool offscreen) :
+        Renderer(window, offscreen), mContexts(NULL), mWorkload(0) {
 }
 
-bool ContextSwitchRenderer::setUp() {
+bool ContextSwitchRenderer::setUp(int workload) {
     SCOPED_TRACE();
-    if (!Renderer::setUp()) {
+    mWorkload = workload;
+    if (!Renderer::setUp(workload)) {
         return false;
     }
 
@@ -137,7 +138,7 @@
 bool ContextSwitchRenderer::tearDown() {
     SCOPED_TRACE();
     if (mContexts) {
-        // Destroy the contexts, the main one will be handled by Renderer::tearDown().
+        // 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) {
@@ -146,6 +147,7 @@
                     mFboIds[i] = 0;
                 }
             }
+            eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
             eglDestroyContext(mEglDisplay, mContexts[i]);
         }
         delete[] mContexts;
@@ -163,6 +165,11 @@
 
 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);
@@ -216,6 +223,7 @@
         }
     }
 
+    eglWaitSyncKHR(mEglDisplay, fence, 0);
     eglDestroySyncKHR(mEglDisplay, fence);
 
     // Switch back to the main context.
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h b/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
index 51a4376..ae320ff 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/primitive/contextswitch/ContextSwitchRenderer.h
@@ -18,9 +18,9 @@
 
 class ContextSwitchRenderer: public Renderer {
 public:
-    ContextSwitchRenderer(ANativeWindow* window, bool offscreen, int workload);
+    ContextSwitchRenderer(ANativeWindow* window, bool offscreen);
     virtual ~ContextSwitchRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     bool tearDown();
     void drawWorkload();
 private:
@@ -31,6 +31,7 @@
     GLuint mTranslateUniformHandle;
     GLuint mPositionHandle;
     GLuint mTexCoordHandle;
+    int mWorkload;
 };
 
 #endif
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp b/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
index 97462b5..0f75f81 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.cpp
@@ -91,15 +91,15 @@
         "  gl_FragColor = (diffuse * texture2D(u_Texture, v_TexCoordinate));\n"
         "}";
 
-FullPipelineRenderer::FullPipelineRenderer(ANativeWindow* window, bool offscreen, int workload) :
-        Renderer(window, offscreen, workload), mProgram(NULL), mSceneGraph(NULL),
+FullPipelineRenderer::FullPipelineRenderer(ANativeWindow* window, bool offscreen) :
+        Renderer(window, offscreen), mProgram(NULL), mSceneGraph(NULL),
         mModelMatrix(NULL), mViewMatrix(NULL), mProjectionMatrix(NULL), mMesh(NULL),
         mTextureId(0) {
 }
 
-bool FullPipelineRenderer::setUp() {
+bool FullPipelineRenderer::setUp(int workload) {
     SCOPED_TRACE();
-    if (!Renderer::setUp()) {
+    if (!Renderer::setUp(workload)) {
         return false;
     }
 
@@ -147,7 +147,7 @@
         return false;
     }
 
-    float count = mWorkload * mWorkload;
+    float count = workload * workload;
     float middle = count / 2.0f;
     float scale = 2.0f / count;
 
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h b/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h
index 84616b4..ce44760 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/primitive/fullpipeline/FullPipelineRenderer.h
@@ -22,9 +22,9 @@
 
 class FullPipelineRenderer: public Renderer {
 public:
-    FullPipelineRenderer(ANativeWindow* window, bool offscreen, int workload);
+    FullPipelineRenderer(ANativeWindow* window, bool offscreen);
     virtual ~FullPipelineRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     bool tearDown();
     void drawWorkload();
 private:
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp b/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
index 287ebfb..3a3b9d1 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.cpp
@@ -50,13 +50,14 @@
         "  gl_FragColor = texture2D(u_Texture, v_TexCoord);"
         "}";
 
-PixelOutputRenderer::PixelOutputRenderer(ANativeWindow* window, bool offscreen, int workload) :
-        Renderer(window, offscreen, workload) {
+PixelOutputRenderer::PixelOutputRenderer(ANativeWindow* window, bool offscreen) :
+        Renderer(window, offscreen), mWorkload(0) {
 }
 
-bool PixelOutputRenderer::setUp() {
+bool PixelOutputRenderer::setUp(int workload) {
     SCOPED_TRACE();
-    if (!Renderer::setUp()) {
+    mWorkload = workload;
+    if (!Renderer::setUp(workload)) {
         return false;
     }
 
@@ -80,6 +81,11 @@
 
 bool PixelOutputRenderer::tearDown() {
     SCOPED_TRACE();
+    if (mProgramId != 0)
+    {
+        glDeleteProgram(mProgramId);
+        mProgramId = 0;
+    }
     if (mTextureId != 0) {
         glDeleteTextures(1, &mTextureId);
         mTextureId = 0;
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h b/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h
index e6b5692..816da6a 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/primitive/pixeloutput/PixelOutputRenderer.h
@@ -18,9 +18,9 @@
 
 class PixelOutputRenderer: public Renderer {
 public:
-    PixelOutputRenderer(ANativeWindow* window, bool offscreen, int workload);
+    PixelOutputRenderer(ANativeWindow* window, bool offscreen);
     virtual ~PixelOutputRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     bool tearDown();
     void drawWorkload();
 private:
@@ -28,6 +28,7 @@
     GLuint mTextureUniformHandle;
     GLuint mPositionHandle;
     GLuint mTexCoordHandle;
+    int mWorkload;
 };
 
 #endif
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp b/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
index 1cbc839..a02f4fe 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.cpp
@@ -91,13 +91,13 @@
     return destAddr - destStart;
 }
 
-ShaderPerfRenderer::ShaderPerfRenderer(ANativeWindow* window, bool offscreen, int workload) :
-        Renderer(window, offscreen, workload) {
+ShaderPerfRenderer::ShaderPerfRenderer(ANativeWindow* window, bool offscreen) :
+        Renderer(window, offscreen) {
 }
 
-bool ShaderPerfRenderer::setUp() {
+bool ShaderPerfRenderer::setUp(int workload) {
     SCOPED_TRACE();
-    if (!Renderer::setUp()) {
+    if (!Renderer::setUp(workload)) {
         return false;
     }
 
@@ -106,7 +106,7 @@
     // Add the first part.
     int index = charCopy(SP_FRAGMENT_1, spFragment, 0);
     // Add the count, overwriting the '\0' added by charCopy.
-    spFragment[index - 1] = (char) (((int) '0') + mWorkload);
+    spFragment[index - 1] = (char) (((int) '0') + workload);
     // Add the second part.
     index += charCopy(SP_FRAGMENT_2, spFragment, index);
     // Create program.
diff --git a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h b/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h
index 52fac43..c804202 100644
--- a/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/primitive/shaderperf/ShaderPerfRenderer.h
@@ -18,9 +18,9 @@
 
 class ShaderPerfRenderer: public Renderer {
 public:
-    ShaderPerfRenderer(ANativeWindow* window, bool offscreen, int workload);
+    ShaderPerfRenderer(ANativeWindow* window, bool offscreen);
     virtual ~ShaderPerfRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     void drawWorkload();
 private:
     GLuint mTextureId;
diff --git a/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp b/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp
index 1857848..dc0b4e2 100644
--- a/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp
+++ b/suite/cts/deviceTests/opengl/jni/reference/GLReference.cpp
@@ -23,7 +23,7 @@
 
 extern "C" JNIEXPORT jboolean JNICALL
 Java_com_android_cts_opengl_reference_GLGameActivity_startBenchmark(
-        JNIEnv* env, jclass clazz, jobject assetManager, jobject surface, jint numFrames,
+    JNIEnv* env, jclass /*clazz*/, jobject assetManager, jobject surface, jint numFrames,
         jdoubleArray setUpTimes, jdoubleArray updateTimes, jdoubleArray renderTimes) {
 
     GLUtils::setEnvAndAssetManager(env, assetManager);
@@ -32,9 +32,10 @@
         return false;
     }
 
-    ReferenceRenderer* renderer = new ReferenceRenderer(ANativeWindow_fromSurface(env, surface));
-
-    bool success = renderer->setUp();
+    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);
 
@@ -54,7 +55,11 @@
     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
index 8f7703e..3b12ee1 100644
--- a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp
+++ b/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.cpp
@@ -22,10 +22,10 @@
 #include <Trace.h>
 
 ReferenceRenderer::ReferenceRenderer(ANativeWindow* window) :
-        Renderer(window, false, 0) {
+        Renderer(window, false) {
 }
 
-bool ReferenceRenderer::setUp() {
+bool ReferenceRenderer::setUp(int workload) {
     SCOPED_TRACE();
     // Reset the times.
     for (int i = 0; i < NUM_SETUP_TIMES; i++) {
@@ -33,7 +33,7 @@
     }
     // Set up OpenGLES.
     double start = GLUtils::currentTimeMillis();
-    if (!Renderer::setUp()) {
+    if (!Renderer::setUp(workload)) {
         return false;
     }
     mSetUpTimes[0] = GLUtils::currentTimeMillis() - start;
diff --git a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h b/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h
index d10297a..f5c4b65 100644
--- a/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h
+++ b/suite/cts/deviceTests/opengl/jni/reference/ReferenceRenderer.h
@@ -23,7 +23,7 @@
 public:
     ReferenceRenderer(ANativeWindow* window);
     virtual ~ReferenceRenderer() {};
-    bool setUp();
+    bool setUp(int workload);
     bool tearDown();
     bool update(int frame);
     void drawWorkload();
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h b/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h
index e50acd0..3e4367a 100644
--- a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h
+++ b/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/Boid.h
@@ -16,6 +16,7 @@
 #define BOID_H
 
 #include <graphics/Vector2D.h>
+#include <utils/Compat.h>
 
 class Boid {
 public:
@@ -24,14 +25,14 @@
     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 float MAX_SPEED = 2.0f;// Upper limit of boid velocity.
-    static const float MAX_FORCE = 0.05f;// Upper limit of the force used to push a boid.
-    static const float NEIGHBOUR_RADIUS = 70.0f;// Radius used to find neighbours, was 50.
-    static const float DESIRED_BOID_DIST = 35.0f;// Distance boids want to be from others, was 25.
+    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 float SEPARATION_WEIGHT = 2.0f;
-    static const float ALIGNMENT_WEIGHT = 1.0f;
-    static const float COHESION_WEIGHT = 1.0f;
+    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;
diff --git a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h b/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h
index 97bd4cc..7cdcffe 100644
--- a/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h
+++ b/suite/cts/deviceTests/opengl/jni/reference/scene/flocking/FlockingScene.h
@@ -15,6 +15,7 @@
 #define FLOCKINGSCENE_H
 
 #include <graphics/Program.h>
+#include <utils/Compat.h>
 
 #include "../Scene.h"
 #include "Boid.h"
@@ -41,6 +42,6 @@
     float mBoardHeight;
     Program* mMainProgram;
     Program* mWaterProgram;
-    static const float BOID_SCALE = 1.0f / 50.0f;
+    static const CONSTEXPR float BOID_SCALE = 1.0f / 50.0f;
 };
 #endif
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
index 5dc9b88..6defdb7 100644
--- 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
@@ -102,19 +102,12 @@
         }
     }
 
-    private static native void setupFullPipelineBenchmark(
-            Surface surface, boolean offscreen, int workload);
+    private static native boolean setupBenchmark(
+            Surface surface, int benchmark, boolean offscreen);
 
-    private static native void setupPixelOutputBenchmark(
-            Surface surface, boolean offscreen, int workload);
+    private static native boolean startBenchmark(int workload, int numFrames, double[] frameTimes);
 
-    private static native void setupShaderPerfBenchmark(
-            Surface surface, boolean offscreen, int workload);
-
-    private static native void setupContextSwitchBenchmark(
-            Surface surface, boolean offscreen, int workload);
-
-    private static native boolean startBenchmark(int numFrames, double[] frameTimes);
+    private static native void tearDownBenchmark();
 
     /**
      * This thread runs the benchmarks, freeing the UI thread.
@@ -138,36 +131,29 @@
             watchDog = new WatchDog(mTimeout, this);
             // Used to record the start and end time of the iteration.
             double[] times = new double[2];
-            for (int i = 0; i < mNumIterations && success; i++) {
-                // The workload to use for this iteration.
-                int workload = i + 1;
+            try {
                 // Setup the benchmark.
-                switch (mBenchmark) {
-                    case FullPipeline:
-                        setupFullPipelineBenchmark(mSurface, mOffscreen, workload);
-                        break;
-                    case PixelOutput:
-                        setupPixelOutputBenchmark(mSurface, mOffscreen, workload);
-                        break;
-                    case ShaderPerf:
-                        setupShaderPerfBenchmark(mSurface, mOffscreen, workload);
-                        break;
-                    case ContextSwitch:
-                        setupContextSwitchBenchmark(mSurface, mOffscreen, workload);
-                        break;
-                }
-                watchDog.start();
-                // Start benchmark.
-                success = startBenchmark(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]);
+                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");
         }
diff --git a/suite/cts/deviceTests/opengl/test/Android.mk b/suite/cts/deviceTests/opengl/test/Android.mk
index a4abe4f..5270bac 100644
--- a/suite/cts/deviceTests/opengl/test/Android.mk
+++ b/suite/cts/deviceTests/opengl/test/Android.mk
@@ -18,6 +18,7 @@
 
 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); \
@@ -26,8 +27,8 @@
 
 #$(info $(LOCAL_SRC_FILES))
 LOCAL_C_INCLUDES += external/gtest/include $(LOCAL_PATH)/../jni/graphics/
-LOCAL_STATIC_LIBRARIES := libutils libcutils libgtest_host libgtest_main_host liblog
-LOCAL_LDFLAGS:= -g -lrt -ldl -lstdc++ -lm -fno-exceptions -lpthread
+LOCAL_STATIC_LIBRARIES := libgtest_host libgtest_main_host liblog
+LOCAL_LDFLAGS:= -g -lpthread
 LOCAL_MODULE:= cts_device_opengl_test
 include $(BUILD_HOST_EXECUTABLE)
 
diff --git a/suite/cts/deviceTests/videoperf/Android.mk b/suite/cts/deviceTests/videoperf/Android.mk
index a393683..b589475 100644
--- a/suite/cts/deviceTests/videoperf/Android.mk
+++ b/suite/cts/deviceTests/videoperf/Android.mk
@@ -33,5 +33,7 @@
 
 LOCAL_SDK_VERSION := current
 
+cts_runtime_hint := 50
+
 include $(BUILD_CTS_PACKAGE)
 
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
index 462794b..ccb3126 100644
--- a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
+++ b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/CodecInfo.java
@@ -16,6 +16,7 @@
 
 package com.android.cts.videoperf;
 
+import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaCodecInfo.CodecProfileLevel;
@@ -23,7 +24,9 @@
 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.
@@ -43,32 +46,25 @@
     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
-     * @param isEncoder whether the codec is encoder or decoder
      * @return null if the configuration is not supported.
      */
     public static CodecInfo getSupportedFormatInfo(
-            String mimeType, int w, int h, boolean isEncoder) {
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        MediaFormat format = MediaFormat.createVideoFormat(mimeType, w, h);
-        String codec = isEncoder
-                ? mcl.findEncoderForFormat(format)
-                : mcl.findDecoderForFormat(format);
-        if (codec == null) { // not supported
+            String codecName, String mimeType, int w, int h) {
+        MediaCodec codec;
+        try {
+            codec = MediaCodec.createByCodecName(codecName);
+        } catch (IOException e) {
             return null;
         }
-        CodecCapabilities cap = null;
-        for (MediaCodecInfo info : mcl.getCodecInfos()) {
-            if (info.getName().equals(codec)) {
-                cap = info.getCapabilitiesForType(mimeType);
-                break;
-            }
-        }
 
+        CodecCapabilities cap = codec.getCodecInfo().getCapabilitiesForType(mimeType);
         if (cap.colorFormats.length == 0) {
             Log.w(TAG, "no supported color format");
+            codec.release();
             return null;
         }
 
@@ -84,25 +80,16 @@
         printIntArray("supported colors", cap.colorFormats);
 
         VideoCapabilities vidCap = cap.getVideoCapabilities();
-        if (mimeType.equals(VIDEO_AVC)) {
+        try {
             info.mFps = vidCap.getSupportedFrameRatesFor(w, h).getUpper().intValue();
-            info.mBitRate = vidCap.getBitrateRange().getUpper();
-
-            // we don't parse bitrate-range on L, so need to adjust bitrate to supported
-            // baseline or main profiles only.
-            int maxBitRate = 0;
-            for (CodecProfileLevel pl : cap.profileLevels) {
-                if (pl.profile == pl.AVCProfileBaseline || pl.profile == pl.AVCProfileMain) {
-                    VideoCapabilities vidCapPL =
-                        CodecCapabilities.createFromProfileLevel(mimeType, pl.profile, pl.level)
-                                .getVideoCapabilities();
-                    maxBitRate = Math.max(maxBitRate, vidCapPL.getBitrateRange().getUpper());
-                }
-            }
-            info.mBitRate = Math.min(info.mBitRate, maxBitRate);
-
-            Log.i(TAG, "AVC bit rate " + info.mBitRate + " fps " + info.mFps);
+        } 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;
     }
 
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
index bf02d9c..62f37c5 100644
--- a/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
+++ b/suite/cts/deviceTests/videoperf/src/com/android/cts/videoperf/VideoEncoderDecoderTest.java
@@ -16,6 +16,8 @@
 
 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;
@@ -23,19 +25,28 @@
 import android.media.Image;
 import android.media.Image.Plane;
 import android.media.MediaCodec;
-import android.media.MediaCodecList;
+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;
 
@@ -57,10 +68,15 @@
     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 int TOTAL_FRAMES = 300;
-    private static final int NUMBER_OF_REPEAT = 10;
+    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;
@@ -75,20 +91,40 @@
     private int mVideoHeight;
     private int mFrameRate;
 
-    private Vector<ByteBuffer> mEncodedOutputBuffer;
+    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 Vector<ByteBuffer>(TOTAL_FRAMES * 2);
+        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();
     }
 
@@ -101,23 +137,77 @@
         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 {
-        doTest(VIDEO_AVC, 176, 144, NUMBER_OF_REPEAT);
+        doTestDefault(VIDEO_AVC, 176, 144);
     }
 
     public void testAvc0352x0288() throws Exception {
-        doTest(VIDEO_AVC, 352, 288, NUMBER_OF_REPEAT);
+        doTestDefault(VIDEO_AVC, 352, 288);
     }
 
     public void testAvc0720x0480() throws Exception {
-        doTest(VIDEO_AVC, 720, 480, NUMBER_OF_REPEAT);
+        doTestDefault(VIDEO_AVC, 720, 480);
     }
 
     public void testAvc1280x0720() throws Exception {
-        doTest(VIDEO_AVC, 1280, 720, NUMBER_OF_REPEAT);
+        doTestDefault(VIDEO_AVC, 1280, 720);
     }
 
     /**
@@ -126,7 +216,133 @@
      * which is not specified in API documentation.
      */
     public void testAvc1920x1072() throws Exception {
-        doTest(VIDEO_AVC, 1920, 1072, NUMBER_OF_REPEAT);
+        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() {
@@ -156,20 +372,77 @@
         }
     }
 
+    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
-     * @param numberRepeat how many times to repeat the encoding / decoding process
      */
-    private void doTest(String mimeType, int w, int h, int numberRepeat) throws Exception {
-        CodecInfo infoEnc = CodecInfo.getSupportedFormatInfo(mimeType, w, h, true /* encoder */);
+    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(mimeType, w, h, false /* encoder */);
+        CodecInfo infoDec = CodecInfo.getSupportedFormatInfo(decoderName, mimeType, w, h);
         assertNotNull(infoDec);
         mVideoWidth = w;
         mVideoHeight = h;
@@ -181,12 +454,17 @@
                    ", dec format " + mDstColorFormat);
 
         initYUVPlane(w + YUV_PLANE_ADDITIONAL_LENGTH, h + YUV_PLANE_ADDITIONAL_LENGTH);
-        double[] encoderFpsResults = new double[numberRepeat];
-        double[] decoderFpsResults = new double[numberRepeat];
-        double[] totalFpsResults = new double[numberRepeat];
-        double[] decoderRmsErrorResults = new double[numberRepeat];
+        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 < numberRepeat && success; i++) {
+        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);
@@ -196,22 +474,24 @@
             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(VIDEO_AVC, format, TOTAL_FRAMES);
+
+            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(VIDEO_AVC, format);
+            double[] decoderResult = runDecoder(decoderName, format);
             if (decoderResult == null) {
                 success = false;
             } else {
                 double decodingTime = decoderResult[0];
                 decoderRmsErrorResults[i] = decoderResult[1];
-                encoderFpsResults[i] = (double)TOTAL_FRAMES / encodingTime * 1000.0;
-                decoderFpsResults[i] = (double)TOTAL_FRAMES / decodingTime * 1000.0;
-                totalFpsResults[i] = (double)TOTAL_FRAMES / (encodingTime + decodingTime) * 1000.0;
+                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
@@ -219,34 +499,106 @@
             // it will be good to clean everything to make every run the same.
             System.gc();
         }
-        getReportLog().printArray("encoder", encoderFpsResults, ResultType.HIGHER_BETTER,
+        mReportLog.printArray("encoder", encoderFpsResults, ResultType.HIGHER_BETTER,
                 ResultUnit.FPS);
-        getReportLog().printArray("rms error", decoderRmsErrorResults, ResultType.LOWER_BETTER,
+        mReportLog.printArray("rms error", decoderRmsErrorResults, ResultType.LOWER_BETTER,
                 ResultUnit.NONE);
-        getReportLog().printArray("decoder", decoderFpsResults, ResultType.HIGHER_BETTER,
+        mReportLog.printArray("decoder", decoderFpsResults, ResultType.HIGHER_BETTER,
                 ResultUnit.FPS);
-        getReportLog().printArray("encoder decoder", totalFpsResults, ResultType.HIGHER_BETTER,
+        mReportLog.printArray("encoder decoder", totalFpsResults, ResultType.HIGHER_BETTER,
                 ResultUnit.FPS);
-        getReportLog().printSummary("encoder decoder", Stat.getAverage(totalFpsResults),
+        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);
-        // make sure that rms error is not too big.
-        for (int i = 0; i < numberRepeat; i++) {
-            assertTrue(decoderRmsErrorResults[i] < PIXEL_RMS_ERROR_MARGAIN);
+
+        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 mimeType encoder type like video/avc
+     * @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 mimeType, MediaFormat format, int totalFrames) {
+    private double runEncoder(String encoderName, MediaFormat format, int totalFrames) {
         MediaCodec codec = null;
         try {
-            MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-            String encoderName = mcl.findEncoderForFormat(format);
             codec = MediaCodec.createByCodecName(encoderName);
             codec.configure(
                     format,
@@ -254,19 +606,21 @@
                     null /* crypto */,
                     MediaCodec.CONFIGURE_FLAG_ENCODE);
         } catch (IllegalStateException e) {
-            Log.e(TAG, "codec '" + mimeType + "' failed configuration.");
+            Log.e(TAG, "codec '" + encoderName + "' failed configuration.");
             codec.release();
-            assertTrue("codec '" + mimeType + "' failed configuration.", false);
+            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;
@@ -275,6 +629,10 @@
                 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) {
@@ -283,14 +641,12 @@
                         assertTrue(image != null);
                         size = queueInputImageEncoder(
                                 codec, image, index, inFramesCount,
-                                (inFramesCount == (totalFrames - 1)) ?
-                                        MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+                                eos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
                     } else {
                         ByteBuffer buffer = codec.getInputBuffer(index);
                         size = queueInputBufferEncoder(
                                 codec, buffer, index, inFramesCount,
-                                (inFramesCount == (totalFrames - 1)) ?
-                                        MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+                                eos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
                     }
                     inFramesCount++;
                     numBytesSubmitted += size;
@@ -305,9 +661,19 @@
             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) {
@@ -322,6 +688,10 @@
             }
         }
         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.");
@@ -532,28 +902,27 @@
             MediaCodec codec, ByteBuffer[] outputBuffers,
             int index, MediaCodec.BufferInfo info) {
         ByteBuffer output = outputBuffers[index];
-        output.clear();
         int l = info.size;
         ByteBuffer copied = ByteBuffer.allocate(l);
         output.get(copied.array(), 0, l);
-        mEncodedOutputBuffer.add(copied);
+        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 mimeType encoder type like video/avc
+     * @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 mimeType, MediaFormat format) {
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        String decoderName = mcl.findDecoderForFormat(format);
+    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 codec for " + format);
+            Log.i(TAG, "could not find decoder for " + format);
             return null;
         }
         codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
@@ -569,6 +938,7 @@
         int outFrameCount = 0;
         YUVValue expected = new YUVValue();
         YUVValue decoded = new YUVValue();
+        long lastOutputTimeNs = 0;
         long start = System.currentTimeMillis();
         while (!sawOutputEOS) {
             if (inputLeft > 0) {
@@ -577,15 +947,22 @@
                 if (inputBufIndex >= 0) {
                     ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
                     dstBuf.clear();
-                    ByteBuffer src = mEncodedOutputBuffer.get(inputBufferCount);
+                    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,
-                            0,
-                            (inputLeft == 1) ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+                            srcInfo.presentationTimeUs,
+                            flags);
                     inputLeft --;
                     inputBufferCount ++;
                 }
@@ -597,29 +974,57 @@
 
                 // only do YUV compare on EOS frame if the buffer size is none-zero
                 if (info.size > 0) {
-                    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);
+                    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);
-                            getPixelValuesFromOutputBuffer(buf, w, h, decoded);
+                            getPixelValuesFromImage(image, w, h, decoded);
                             if (VERBOSE) {
-                                Log.i(TAG, outFrameCount + "-" + i + "- th round: ByteBuffer:"
-                                        + " expected "
+                                Log.i(TAG, outFrameCount + "-" + i + "- th round: FlexYUV:"
+                                        + " expcted "
                                         + expected.mY + "," + expected.mU + "," + expected.mV
                                         + " decoded "
                                         + decoded.mY + "," + decoded.mU + "," + decoded.mV);
@@ -627,23 +1032,6 @@
                             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 */);
@@ -652,9 +1040,9 @@
                     sawOutputEOS = true;
                 }
             } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
-                MediaFormat oformat = codec.getOutputFormat();
-                Log.d(TAG, "output format has changed to " + oformat);
-                int colorFormat = oformat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
+                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;
@@ -666,10 +1054,14 @@
             }
         }
         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;
-        assertTrue(outFrameCount >= TOTAL_FRAMES);
+
         // 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 };
diff --git a/suite/cts/hostTests/jank/app/src/com/android/cts/jank/ui/CtsDeviceJankUi.java b/suite/cts/hostTests/jank/app/src/com/android/cts/jank/ui/CtsDeviceJankUi.java
deleted file mode 100644
index ea1f685..0000000
--- a/suite/cts/hostTests/jank/app/src/com/android/cts/jank/ui/CtsDeviceJankUi.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.jank.ui;
-
-import android.util.Log;
-import android.widget.ListView;
-
-import com.android.cts.jank.CtsJankTestBase;
-import com.android.uiautomator.core.UiScrollable;
-import com.android.uiautomator.core.UiSelector;
-import com.android.uiautomator.platform.SurfaceFlingerHelper;
-
-public class CtsDeviceJankUi extends CtsJankTestBase {
-    private final static String TAG = CtsDeviceJankUi.class.getName();
-    private final static String PACKAGE = "com.android.cts.ui";
-    private final static String COMPONENT =
-            PACKAGE + "/" + PACKAGE + ".ScrollingActivity";
-    private final static int NUM_ELEMENTS = 1000;
-    private static String APP_WINDOW_NAME = COMPONENT;
-
-    // TODO(stuartscott): expand deviceTests/ui app to have a more complex UI
-    /**
-     * Runs the ScrollingActivity and measures jank during a scroll.
-     */
-    public void testScrolling() throws Exception {
-        // Start activity command
-        final StringBuilder sb = new StringBuilder();
-        sb.append(String.format(START_CMD, COMPONENT));
-        sb.append(String.format(INTENT_INTEGER_EXTRA, "num_elements", NUM_ELEMENTS));
-        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);
-
-            UiScrollable list = new UiScrollable(
-                    new UiSelector().className(ListView.class.getName()));
-
-            // Start systrace
-            startTrace(mTestCaseName, i);
-
-            // Clear SurfaceFlinger buffer
-            Log.i(TAG, "Clearing SurfaceFlinger buffer");
-            SurfaceFlingerHelper.clearBuffer(APP_WINDOW_NAME);
-
-            list.flingToEnd(2);
-
-            // 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/ui/CtsHostJankUi.java b/suite/cts/hostTests/jank/src/com/android/cts/jank/ui/CtsHostJankUi.java
deleted file mode 100644
index a07171e..0000000
--- a/suite/cts/hostTests/jank/src/com/android/cts/jank/ui/CtsHostJankUi.java
+++ /dev/null
@@ -1,53 +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.ui;
-
-import com.android.cts.jank.CtsHostJankTest;
-import com.android.cts.util.AbiUtils;
-import java.io.File;
-
-public class CtsHostJankUi extends CtsHostJankTest {
-
-    private static final String APK_PACKAGE = "com.android.cts";
-    private static final String APK = "CtsDeviceUi.apk";
-    private static final String PACKAGE = "com.android.cts.jank.ui";
-    private static final String HOST_CLASS = CtsHostJankUi.class.getName();
-    private static final String DEVICE_CLASS = PACKAGE + ".CtsDeviceJankUi";
-    private static final String JAR_NAME = "CtsDeviceJank.jar";
-
-    public CtsHostJankUi() {
-        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 testScrolling() throws Exception {
-        runUiAutomatorTest("testScrolling");
-    }
-}
diff --git a/suite/cts/hostTests/uihost/appA/Android.mk b/suite/cts/hostTests/uihost/appA/Android.mk
index 3e76fdb..17f076f 100644
--- a/suite/cts/hostTests/uihost/appA/Android.mk
+++ b/suite/cts/hostTests/uihost/appA/Android.mk
@@ -26,8 +26,6 @@
 
 LOCAL_PACKAGE_NAME := CtsDeviceTaskswitchingAppA
 
-LOCAL_SDK_VERSION := 16
+LOCAL_SDK_VERSION := current
 
-include $(BUILD_CTS_PACKAGE)
-
-
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/suite/cts/hostTests/uihost/appB/Android.mk b/suite/cts/hostTests/uihost/appB/Android.mk
index 13af40f..ebb36d2 100644
--- a/suite/cts/hostTests/uihost/appB/Android.mk
+++ b/suite/cts/hostTests/uihost/appB/Android.mk
@@ -26,8 +26,6 @@
 
 LOCAL_PACKAGE_NAME := CtsDeviceTaskswitchingAppB
 
-LOCAL_SDK_VERSION := 16
+LOCAL_SDK_VERSION := current
 
-include $(BUILD_CTS_PACKAGE)
-
-
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/suite/cts/hostTests/uihost/control/Android.mk b/suite/cts/hostTests/uihost/control/Android.mk
index 3770918..4de9ae8 100644
--- a/suite/cts/hostTests/uihost/control/Android.mk
+++ b/suite/cts/hostTests/uihost/control/Android.mk
@@ -26,6 +26,6 @@
 
 LOCAL_PACKAGE_NAME := CtsDeviceTaskswitchingControl
 
-LOCAL_SDK_VERSION := 16
+LOCAL_SDK_VERSION := current
 
-include $(BUILD_CTS_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
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
index 894b824..2d33436 100644
--- a/suite/cts/hostTests/uihost/src/com/android/cts/uihost/TaskSwitchingTest.java
+++ b/suite/cts/hostTests/uihost/src/com/android/cts/uihost/TaskSwitchingTest.java
@@ -115,7 +115,9 @@
         @Override
         public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
             // necessary as testMetrics passed from CollectingTestListerner is empty
-            mCtsReport = testMetrics.get("CTS_TEST_RESULT");
+            if (testMetrics.containsKey("CTS_TEST_RESULT")) {
+                mCtsReport = testMetrics.get("CTS_TEST_RESULT");
+            }
             super.testEnded(test, testMetrics);
         }
     }
diff --git a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
index 38a753d..4f549f8 100644
--- a/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
+++ b/tests/JobScheduler/src/android/jobscheduler/MockJobService.java
@@ -46,7 +46,7 @@
     public boolean onStartJob(JobParameters params) {
         Log.i(TAG, "Test job executing: " + params.getJobId());
 
-        TestEnvironment.getTestEnvironment().notifyExecution(params.getJobId());
+        TestEnvironment.getTestEnvironment().notifyExecution(params);
         return false;  // No work to do.
     }
 
@@ -63,10 +63,10 @@
     public static final class TestEnvironment {
 
         private static TestEnvironment kTestEnvironment;
-        public static final int INVALID_JOB_ID = -1;
+        //public static final int INVALID_JOB_ID = -1;
 
         private CountDownLatch mLatch;
-        private int mExecutedJobId;
+        private JobParameters mExecutedJobParameters;
 
         public static TestEnvironment getTestEnvironment() {
             if (kTestEnvironment == null) {
@@ -75,6 +75,10 @@
             return kTestEnvironment;
         }
 
+        public JobParameters getLastJobParameters() {
+            return mExecutedJobParameters;
+        }
+
         /**
          * Block the test thread, waiting on the JobScheduler to execute some previously scheduled
          * job on this service.
@@ -93,9 +97,9 @@
             return !mLatch.await(DEFAULT_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
         }
 
-        private void notifyExecution(int jobId) {
-            Log.d(TAG, "Job executed:" + jobId);
-            mExecutedJobId = jobId;
+        private void notifyExecution(JobParameters params) {
+            Log.d(TAG, "Job executed:" + params.getJobId());
+            mExecutedJobParameters = params;
             mLatch.countDown();
         }
 
@@ -111,7 +115,7 @@
         /** Called in each testCase#setup */
         public void setUp() {
             mLatch = null;
-            mExecutedJobId = INVALID_JOB_ID;
+            mExecutedJobParameters = null;
         }
 
     }
diff --git a/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java b/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java
index ed9cadd..40b67c8 100644
--- a/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java
+++ b/tests/JobScheduler/src/android/jobscheduler/cts/TimingConstraintsTest.java
@@ -17,6 +17,7 @@
 
 import android.annotation.TargetApi;
 import android.app.job.JobInfo;
+import android.app.job.JobParameters;
 
 /**
  * Schedules jobs with various timing constraints and ensures that they are executed when
@@ -26,6 +27,8 @@
 public class TimingConstraintsTest extends ConstraintTest {
     private static final int TIMING_JOB_ID = TimingConstraintsTest.class.hashCode() + 0;
     private static final int CANCEL_JOB_ID = TimingConstraintsTest.class.hashCode() + 1;
+    private static final int EXPIRED_JOB_ID = TimingConstraintsTest.class.hashCode() + 2;
+    private static final int UNEXPIRED_JOB_ID = TimingConstraintsTest.class.hashCode() + 3;
 
     public void testScheduleOnce() throws Exception {
         JobInfo oneTimeJob = new JobInfo.Builder(TIMING_JOB_ID, kJobServiceComponent)
@@ -63,4 +66,44 @@
         assertTrue("Cancel failed: job executed when it shouldn't have.",
                 kTestEnvironment.awaitTimeout());
     }
+
+    /**
+     * Ensure that when a job is executed because its deadline has expired, that
+     * {@link JobParameters#isOverrideDeadlineExpired()} returns the correct value.
+     */
+    public void testJobParameters_expiredDeadline() throws Exception {
+
+        JobInfo deadlineJob =
+                new JobInfo.Builder(EXPIRED_JOB_ID, kJobServiceComponent)
+                        .setOverrideDeadline(2000L)
+                        .build();
+        kTestEnvironment.setExpectedExecutions(1);
+        mJobScheduler.schedule(deadlineJob);
+        assertTrue("Failed to execute deadline job", kTestEnvironment.awaitExecution());
+        assertTrue("Job that had its deadline expire didn't have" +
+                        " JobParameters#isOverrideDeadlineExpired=true",
+                kTestEnvironment.getLastJobParameters().isOverrideDeadlineExpired());
+    }
+
+
+    /**
+     * Ensure that when a job is executed and its deadline hasn't expired, that
+     * {@link JobParameters#isOverrideDeadlineExpired()} returns the correct value.
+     */
+    public void testJobParameters_unexpiredDeadline() throws Exception {
+
+        JobInfo deadlineJob =
+                new JobInfo.Builder(UNEXPIRED_JOB_ID, kJobServiceComponent)
+                        .setMinimumLatency(500L)
+                        .setRequiresCharging(true)
+                        .build();
+        kTestEnvironment.setExpectedExecutions(1);
+        mJobScheduler.schedule(deadlineJob);
+        // Run everything by pretending the device was just plugged in.
+        sendExpediteStableChargingBroadcast();
+        assertTrue("Failed to execute non-deadline job", kTestEnvironment.awaitExecution());
+        assertFalse("Job that ran early (unexpired) didn't have" +
+                        " 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 a6d6022..f36b64b 100644
--- a/tests/acceleration/Android.mk
+++ b/tests/acceleration/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_SDK_VERSION := current
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/accessibility/Android.mk b/tests/accessibility/Android.mk
index 43fa291..bddbb58 100644
--- a/tests/accessibility/Android.mk
+++ b/tests/accessibility/Android.mk
@@ -28,4 +28,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/app/Android.mk b/tests/app/Android.mk
index 69bf590..f4f0a13 100644
--- a/tests/app/Android.mk
+++ b/tests/app/Android.mk
@@ -23,7 +23,7 @@
 
 LOCAL_PROGUARD_ENABLED := disabled
 
-LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common voip-common
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common voip-common org.apache.http.legacy
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ctstestserver
 
@@ -32,4 +32,4 @@
 
 LOCAL_PACKAGE_NAME := CtsAppTestStubs
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/app/AndroidManifest.xml b/tests/app/AndroidManifest.xml
index 0d61e20..8d7729e 100644
--- a/tests/app/AndroidManifest.xml
+++ b/tests/app/AndroidManifest.xml
@@ -49,6 +49,7 @@
                 android:name="android.app.cts.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.cts.ActionBarActivity" />
 
diff --git a/tests/camera/Android.mk b/tests/camera/Android.mk
new file mode 100644
index 0000000..4cae7c4
--- /dev/null
+++ b/tests/camera/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)
+
+# CtsCameraTestCases package
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil \
+	ctstestrunner \
+	mockito-target \
+	android-ex-camera2
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsCameraTestCases
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+cts_runtime_hint := 120
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/camera/AndroidManifest.xml b/tests/camera/AndroidManifest.xml
new file mode 100644
index 0000000..2b39fca
--- /dev/null
+++ b/tests/camera/AndroidManifest.xml
@@ -0,0 +1,81 @@
+<?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.camera.cts">
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.RECORD_AUDIO" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.REORDER_TASKS" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <activity android:name="android.hardware.cts.CameraCtsActivity"
+            android:label="CameraCtsActivity"
+            android:screenOrientation="landscape"
+            android:configChanges="keyboardHidden|orientation|screenSize">
+        </activity>
+
+        <activity android:name="android.hardware.camera2.cts.Camera2SurfaceViewCtsActivity"
+            android:label="Camera2CtsActivity"
+            android:screenOrientation="landscape"
+            android:configChanges="keyboardHidden|orientation|screenSize">
+        </activity>
+
+        <activity android:name="android.hardware.camera2.cts.Camera2MultiViewCtsActivity"
+            android:label="Camera2MultiViewCtsActivity"
+            android:screenOrientation="landscape"
+            android:configChanges="keyboardHidden|orientation|screenSize">
+        </activity>
+
+        <activity android:name="android.hardware.cts.GLSurfaceViewCtsActivity"
+            android:label="GLSurfaceViewCtsActivity"/>
+
+        <service android:name="android.hardware.multiprocess.camera.cts.ErrorLoggingService"
+            android:label="ErrorLoggingService"
+            android:process=":errorLoggingServiceProcess"
+            android:exported="false">
+        </service>
+
+        <activity android:name="android.hardware.multiprocess.camera.cts.Camera1Activity"
+            android:label="RemoteCamera1Activity"
+            android:screenOrientation="landscape"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:process=":camera1ActivityProcess">
+        </activity>
+
+        <activity android:name="android.hardware.multiprocess.camera.cts.Camera2Activity"
+            android:label="RemoteCamera2Activity"
+            android:screenOrientation="landscape"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:process=":camera2ActivityProcess">
+        </activity>
+
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.camera.cts"
+                     android:label="CTS tests of android camera">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/hardware/res/layout/multi_view.xml b/tests/camera/res/layout/multi_view.xml
similarity index 100%
rename from tests/tests/hardware/res/layout/multi_view.xml
rename to tests/camera/res/layout/multi_view.xml
diff --git a/tests/tests/hardware/res/layout/surface_view.xml b/tests/camera/res/layout/surface_view.xml
similarity index 100%
rename from tests/tests/hardware/res/layout/surface_view.xml
rename to tests/camera/res/layout/surface_view.xml
diff --git a/tests/tests/hardware/res/layout/surface_view_2.xml b/tests/camera/res/layout/surface_view_2.xml
similarity index 100%
rename from tests/tests/hardware/res/layout/surface_view_2.xml
rename to tests/camera/res/layout/surface_view_2.xml
diff --git a/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
new file mode 100644
index 0000000..0476477
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/AllocationTest.java
@@ -0,0 +1,860 @@
+/*
+ * Copyright 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.hardware.camera2.cts;
+
+import static android.graphics.ImageFormat.YUV_420_888;
+import static android.hardware.camera2.cts.helpers.Preconditions.*;
+import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static com.android.ex.camera2.blocking.BlockingStateCallback.*;
+
+import android.content.Context;
+import android.graphics.ImageFormat;
+import android.graphics.RectF;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.params.ColorSpaceTransform;
+import android.hardware.camera2.params.RggbChannelVector;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.util.Size;
+import android.hardware.camera2.cts.helpers.MaybeNull;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.rs.RenderScriptSingleton;
+import android.hardware.camera2.cts.rs.ScriptGraph;
+import android.hardware.camera2.cts.rs.ScriptYuvCrop;
+import android.hardware.camera2.cts.rs.ScriptYuvMeans1d;
+import android.hardware.camera2.cts.rs.ScriptYuvMeans2dTo1d;
+import android.hardware.camera2.cts.rs.ScriptYuvToRgb;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.renderscript.Allocation;
+import android.renderscript.Script.LaunchOptions;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.util.Rational;
+import android.view.Surface;
+
+import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
+import com.android.ex.camera2.blocking.BlockingStateCallback;
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Suite of tests for camera2 -> RenderScript APIs.
+ *
+ * <p>It uses CameraDevice as producer, camera sends the data to the surface provided by
+ * Allocation. Only the below format is tested:</p>
+ *
+ * <p>YUV_420_888: flexible YUV420, it is a mandatory format for camera.</p>
+ */
+public class AllocationTest extends AndroidTestCase {
+    private static final String TAG = "AllocationTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    private CameraManager mCameraManager;
+    private CameraDevice mCamera;
+    private CameraCaptureSession mSession;
+    private BlockingStateCallback mCameraListener;
+    private BlockingSessionCallback mSessionListener;
+
+    private String[] mCameraIds;
+
+    private Handler mHandler;
+    private HandlerThread mHandlerThread;
+
+    private CameraIterable mCameraIterable;
+    private SizeIterable mSizeIterable;
+    private ResultIterable mResultIterable;
+
+    @Override
+    public synchronized void setContext(Context context) {
+        super.setContext(context);
+        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+        assertNotNull("Can't connect to camera manager!", mCameraManager);
+
+        RenderScriptSingleton.setContext(context);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCameraIds = mCameraManager.getCameraIdList();
+        mHandlerThread = new HandlerThread("AllocationTest");
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mCameraListener = new BlockingStateCallback();
+
+        mCameraIterable = new CameraIterable();
+        mSizeIterable = new SizeIterable();
+        mResultIterable = new ResultIterable();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        MaybeNull.close(mCamera);
+        RenderScriptSingleton.clearContext();
+        mHandlerThread.quitSafely();
+        mHandler = null;
+        super.tearDown();
+    }
+
+    /**
+     * Update the request with a default manual request template.
+     *
+     * @param request A builder for a CaptureRequest
+     * @param sensitivity ISO gain units (e.g. 100)
+     * @param expTimeNs Exposure time in nanoseconds
+     */
+    private static void setManualCaptureRequest(CaptureRequest.Builder request, int sensitivity,
+            long expTimeNs) {
+        final Rational ONE = new Rational(1, 1);
+        final Rational ZERO = new Rational(0, 1);
+
+        if (VERBOSE) {
+            Log.v(TAG, String.format("Create manual capture request, sensitivity = %d, expTime = %f",
+                    sensitivity, expTimeNs / (1000.0 * 1000)));
+        }
+
+        request.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
+        request.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
+        request.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
+        request.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
+        request.set(CaptureRequest.CONTROL_EFFECT_MODE, CaptureRequest.CONTROL_EFFECT_MODE_OFF);
+        request.set(CaptureRequest.SENSOR_FRAME_DURATION, 0L);
+        request.set(CaptureRequest.SENSOR_SENSITIVITY, sensitivity);
+        request.set(CaptureRequest.SENSOR_EXPOSURE_TIME, expTimeNs);
+        request.set(CaptureRequest.COLOR_CORRECTION_MODE,
+                CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
+
+        // Identity transform
+        request.set(CaptureRequest.COLOR_CORRECTION_TRANSFORM,
+            new ColorSpaceTransform(new Rational[] {
+                ONE, ZERO, ZERO,
+                ZERO, ONE, ZERO,
+                ZERO, ZERO, ONE
+            }));
+
+        // Identity gains
+        request.set(CaptureRequest.COLOR_CORRECTION_GAINS,
+                new RggbChannelVector(1.0f, 1.0f, 1.0f, 1.0f ));
+        request.set(CaptureRequest.TONEMAP_MODE, CaptureRequest.TONEMAP_MODE_FAST);
+    }
+
+    /**
+     * Calculate the absolute crop window from a {@link Size},
+     * and configure {@link LaunchOptions} for it.
+     */
+    // TODO: split patch crop window and the application against a particular size into 2 classes
+    public static class Patch {
+        /**
+         * Create a new {@link Patch} from relative crop coordinates.
+         *
+         * <p>All float values must be normalized coordinates between [0, 1].</p>
+         *
+         * @param size Size of the original rectangle that is being cropped.
+         * @param xNorm The X coordinate defining the left side of the rectangle (in [0, 1]).
+         * @param yNorm The Y coordinate defining the top side of the rectangle (in [0, 1]).
+         * @param wNorm The width of the crop rectangle (normalized between [0, 1]).
+         * @param hNorm The height of the crop rectangle (normalized between [0, 1]).
+         *
+         * @throws NullPointerException if size was {@code null}.
+         * @throws AssertionError if any of the normalized coordinates were out of range
+         */
+        public Patch(Size size, float xNorm, float yNorm, float wNorm, float hNorm) {
+            checkNotNull("size", size);
+
+            assertInRange(xNorm, 0.0f, 1.0f);
+            assertInRange(yNorm, 0.0f, 1.0f);
+            assertInRange(wNorm, 0.0f, 1.0f);
+            assertInRange(hNorm, 0.0f, 1.0f);
+
+            wFull = size.getWidth();
+            hFull = size.getWidth();
+
+            xTile = (int)Math.ceil(xNorm * wFull);
+            yTile = (int)Math.ceil(yNorm * hFull);
+
+            wTile = (int)Math.ceil(wNorm * wFull);
+            hTile = (int)Math.ceil(hNorm * hFull);
+
+            mSourceSize = size;
+        }
+
+        /**
+         * Get the original size used to create this {@link Patch}.
+         *
+         * @return source size
+         */
+        public Size getSourceSize() {
+            return mSourceSize;
+        }
+
+        /**
+         * Get the cropped size after applying the normalized crop window.
+         *
+         * @return cropped size
+         */
+        public Size getSize() {
+            return new Size(wFull, hFull);
+        }
+
+        /**
+         * Get the {@link LaunchOptions} that can be used with a {@link android.renderscript.Script}
+         * to apply a kernel over a subset of an {@link Allocation}.
+         *
+         * @return launch options
+         */
+        public LaunchOptions getLaunchOptions() {
+            return (new LaunchOptions())
+                    .setX(xTile, xTile + wTile)
+                    .setY(yTile, yTile + hTile);
+        }
+
+        /**
+         * Get the cropped width after applying the normalized crop window.
+         *
+         * @return cropped width
+         */
+        public int getWidth() {
+            return wTile;
+        }
+
+        /**
+         * Get the cropped height after applying the normalized crop window.
+         *
+         * @return cropped height
+         */
+        public int getHeight() {
+            return hTile;
+        }
+
+        /**
+         * Convert to a {@link RectF} where each corner is represented by a
+         * normalized coordinate in between [0.0, 1.0] inclusive.
+         *
+         * @return a new rectangle
+         */
+        public RectF toRectF() {
+            return new RectF(
+                    xTile * 1.0f / wFull,
+                    yTile * 1.0f / hFull,
+                    (xTile + wTile) * 1.0f / wFull,
+                    (yTile + hTile) * 1.0f / hFull);
+        }
+
+        private final Size mSourceSize;
+        private final int wFull;
+        private final int hFull;
+        private final int xTile;
+        private final int yTile;
+        private final int wTile;
+        private final int hTile;
+    }
+
+    /**
+     * Convert a single YUV pixel (3 byte elements) to an RGB pixel.
+     *
+     * <p>The color channels must be in the following order:
+     * <ul><li>Y - 0th channel
+     * <li>U - 1st channel
+     * <li>V - 2nd channel
+     * </ul></p>
+     *
+     * <p>Each channel has data in the range 0-255.</p>
+     *
+     * <p>Output data is a 3-element pixel with each channel in the range of [0,1].
+     * Each channel is saturated to avoid over/underflow.</p>
+     *
+     * <p>The conversion is done using JFIF File Interchange Format's "Conversion to and from RGB":
+     * <ul>
+     * <li>R = Y + 1.042 (Cr - 128)
+     * <li>G = Y - 0.34414 (Cb - 128) - 0.71414 (Cr - 128)
+     * <li>B = Y + 1.772 (Cb - 128)
+     * </ul>
+     *
+     * Where Cr and Cb are aliases of V and U respectively.
+     * </p>
+     *
+     * @param yuvData An array of a YUV pixel (at least 3 bytes large)
+     *
+     * @return an RGB888 pixel with each channel in the range of [0,1]
+     */
+    private static float[] convertPixelYuvToRgb(byte[] yuvData) {
+        final int CHANNELS = 3; // yuv
+        final float COLOR_RANGE = 255f;
+
+        assertTrue("YUV pixel must be at least 3 bytes large", CHANNELS <= yuvData.length);
+
+        float[] rgb = new float[CHANNELS];
+
+        float y = yuvData[0] & 0xFF;  // Y channel
+        float cb = yuvData[1] & 0xFF; // U channel
+        float cr = yuvData[2] & 0xFF; // V channel
+
+        // convert YUV -> RGB (from JFIF's "Conversion to and from RGB" section)
+        float r = y + 1.402f * (cr - 128);
+        float g = y - 0.34414f * (cb - 128) - 0.71414f * (cr - 128);
+        float b = y + 1.772f * (cb - 128);
+
+        // normalize [0,255] -> [0,1]
+        rgb[0] = r / COLOR_RANGE;
+        rgb[1] = g / COLOR_RANGE;
+        rgb[2] = b / COLOR_RANGE;
+
+        // Clamp to range [0,1]
+        for (int i = 0; i < CHANNELS; ++i) {
+            rgb[i] = Math.max(0.0f, Math.min(1.0f, rgb[i]));
+        }
+
+        if (VERBOSE) {
+            Log.v(TAG, String.format("RGB calculated (r,g,b) = (%f, %f, %f)", rgb[0], rgb[1],
+                    rgb[2]));
+        }
+
+        return rgb;
+    }
+
+    /**
+     * Configure the camera with the target surface;
+     * create a capture request builder with {@code cameraTarget} as the sole surface target.
+     *
+     * <p>Outputs are configured with the new surface targets, and this function blocks until
+     * the camera has finished configuring.</p>
+     *
+     * <p>The capture request is created from the {@link CameraDevice#TEMPLATE_PREVIEW} template.
+     * No other keys are set.
+     * </p>
+     */
+    private CaptureRequest.Builder configureAndCreateRequestForSurface(Surface cameraTarget)
+            throws CameraAccessException {
+        List<Surface> outputSurfaces = new ArrayList<Surface>(/*capacity*/1);
+        assertNotNull("Failed to get Surface", cameraTarget);
+        outputSurfaces.add(cameraTarget);
+
+        mSessionListener = new BlockingSessionCallback();
+        mCamera.createCaptureSession(outputSurfaces, mSessionListener, mHandler);
+        mSession = mSessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+        CaptureRequest.Builder captureBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        assertNotNull("Fail to create captureRequest", captureBuilder);
+        captureBuilder.addTarget(cameraTarget);
+
+        if (VERBOSE) Log.v(TAG, "configureAndCreateRequestForSurface - done");
+
+        return captureBuilder;
+    }
+
+    /**
+     * Submit a single request to the camera, block until the buffer is available.
+     *
+     * <p>Upon return from this function, script has been executed against the latest buffer.
+     * </p>
+     */
+    private void captureSingleShotAndExecute(CaptureRequest request, ScriptGraph graph)
+            throws CameraAccessException {
+        checkNotNull("request", request);
+        checkNotNull("graph", graph);
+
+        mSession.capture(request, new CameraCaptureSession.CaptureCallback() {
+            @Override
+            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
+                    TotalCaptureResult result) {
+                if (VERBOSE) Log.v(TAG, "Capture completed");
+            }
+        }, mHandler);
+
+        if (VERBOSE) Log.v(TAG, "Waiting for single shot buffer");
+        graph.advanceInputWaiting();
+        if (VERBOSE) Log.v(TAG, "Got the buffer");
+        graph.execute();
+    }
+
+    private void stopCapture() throws CameraAccessException {
+        if (VERBOSE) Log.v(TAG, "Stopping capture and waiting for idle");
+        // Stop repeat, wait for captures to complete, and disconnect from surfaces
+        mSession.close();
+        mSessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_CLOSED,
+                SESSION_CLOSE_TIMEOUT_MS);
+        mSession = null;
+        mSessionListener = null;
+    }
+
+    /**
+     * Extremely dumb validator. Makes sure there is at least one non-zero RGB pixel value.
+     */
+    private void validateInputOutputNotZeroes(ScriptGraph scriptGraph, Size size) {
+        final int BPP = 8; // bits per pixel
+
+        int width = size.getWidth();
+        int height = size.getHeight();
+        /**
+         * Check the input allocation is sane.
+         * - Byte size matches what we expect.
+         * - The input is not all zeroes.
+         */
+
+        // Check that input data was updated first. If it wasn't, the rest of the test will fail.
+        byte[] data = scriptGraph.getInputData();
+        assertArrayNotAllZeroes("Input allocation data was not updated", data);
+
+        // Minimal required size to represent YUV 4:2:0 image
+        int packedSize =
+                width * height * ImageFormat.getBitsPerPixel(YUV_420_888) / BPP;
+        if (VERBOSE) Log.v(TAG, "Expected image size = " + packedSize);
+        int actualSize = data.length;
+        // Actual size may be larger due to strides or planes being non-contiguous
+        assertTrue(
+                String.format(
+                        "YUV 420 packed size (%d) should be at least as large as the actual size " +
+                        "(%d)", packedSize, actualSize), packedSize <= actualSize);
+        /**
+         * Check the output allocation by converting to RGBA.
+         * - Byte size matches what we expect
+         * - The output is not all zeroes
+         */
+        final int RGBA_CHANNELS = 4;
+
+        int actualSizeOut = scriptGraph.getOutputAllocation().getBytesSize();
+        int packedSizeOut = width * height * RGBA_CHANNELS;
+
+        byte[] dataOut = scriptGraph.getOutputData();
+        assertEquals("RGB mismatched byte[] and expected size",
+                packedSizeOut, dataOut.length);
+
+        if (VERBOSE) {
+            Log.v(TAG, "checkAllocationByConvertingToRgba - RGB data size " + dataOut.length);
+        }
+
+        assertArrayNotAllZeroes("RGBA data was not updated", dataOut);
+        // RGBA8888 stride should be equal to the width
+        assertEquals("RGBA 8888 mismatched byte[] and expected size", packedSizeOut, actualSizeOut);
+
+        if (VERBOSE) Log.v(TAG, "validating Buffer , size = " + actualSize);
+    }
+
+    public void testAllocationFromCameraFlexibleYuv() throws Exception {
+
+        /** number of frame (for streaming requests) to be verified. */
+        final int NUM_FRAME_VERIFIED = 1;
+
+        mCameraIterable.forEachCamera(new CameraBlock() {
+            @Override
+            public void run(CameraDevice camera) throws CameraAccessException {
+
+                // Iterate over each size in the camera
+                mSizeIterable.forEachSize(YUV_420_888, new SizeBlock() {
+                    @Override
+                    public void run(final Size size) throws CameraAccessException {
+                        // Create a script graph that converts YUV to RGB
+                        final ScriptGraph scriptGraph = ScriptGraph.create()
+                                .configureInputWithSurface(size, YUV_420_888)
+                                .chainScript(ScriptYuvToRgb.class)
+                                .buildGraph();
+
+                        if (VERBOSE) Log.v(TAG, "Prepared ScriptYuvToRgb for size " + size);
+
+                        // Run the graph against camera input and validate we get some input
+                        try {
+                            CaptureRequest request =
+                                    configureAndCreateRequestForSurface(scriptGraph.getInputSurface()).build();
+
+                            // Block until we get 1 result, then iterate over the result
+                            mResultIterable.forEachResultRepeating(
+                                    request, NUM_FRAME_VERIFIED, new ResultBlock() {
+                                @Override
+                                public void run(CaptureResult result) throws CameraAccessException {
+                                    scriptGraph.advanceInputWaiting();
+                                    scriptGraph.execute();
+                                    validateInputOutputNotZeroes(scriptGraph, size);
+                                    scriptGraph.advanceInputAndDrop();
+                                }
+                            });
+
+                            stopCapture();
+                        } finally {
+                            scriptGraph.close();
+                        }
+                    }
+                });
+            }
+        });
+    }
+
+    /**
+     * Take two shots and ensure per-frame-control with exposure/gain is working correctly.
+     *
+     * <p>Takes a shot with very low ISO and exposure time. Expect it to be black.</p>
+     *
+     * <p>Take a shot with very high ISO and exposure time. Expect it to be white.</p>
+     *
+     * @throws Exception
+     */
+    public void testBlackWhite() throws CameraAccessException {
+
+        /** low iso + low exposure (first shot) */
+        final float THRESHOLD_LOW = 0.025f;
+        /** high iso + high exposure (second shot) */
+        final float THRESHOLD_HIGH = 0.975f;
+
+        mCameraIterable.forEachCamera(/*fullHwLevel*/false, new CameraBlock() {
+            @Override
+            public void run(CameraDevice camera) throws CameraAccessException {
+                final StaticMetadata staticInfo =
+                        new StaticMetadata(mCameraManager.getCameraCharacteristics(camera.getId()));
+
+                // This test requires PFC and manual sensor control
+                if (!staticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR) ||
+                        !staticInfo.isPerFrameControlSupported()) {
+                    return;
+                }
+
+                final Size maxSize = getMaxSize(
+                        getSupportedSizeForFormat(YUV_420_888, camera.getId(), mCameraManager));
+
+                ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize);
+
+                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);
+
+                CaptureRequest lowIsoExposureShot = req.build();
+                captureSingleShotAndExecute(lowIsoExposureShot, scriptGraph);
+
+                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);
+
+                CaptureRequest highIsoExposureShot = req.build();
+                captureSingleShotAndExecute(highIsoExposureShot, scriptGraph);
+
+                float[] whiteMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
+
+                // 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);
+            }
+        });
+    }
+
+    /**
+     * Test that the android.sensitivity.parameter is applied.
+     */
+    public void testParamSensitivity() throws CameraAccessException {
+        final float THRESHOLD_MAX_MIN_DIFF = 0.3f;
+        final float THRESHOLD_MAX_MIN_RATIO = 2.0f;
+        final int NUM_STEPS = 5;
+        final long EXPOSURE_TIME_NS = 2000000; // 2 seconds
+        final int RGB_CHANNELS = 3;
+
+        mCameraIterable.forEachCamera(/*fullHwLevel*/false, new CameraBlock() {
+
+
+            @Override
+            public void run(CameraDevice camera) throws CameraAccessException {
+                final StaticMetadata staticInfo =
+                        new StaticMetadata(mCameraManager.getCameraCharacteristics(camera.getId()));
+                // This test requires PFC and manual sensor control
+                if (!staticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR) ||
+                        !staticInfo.isPerFrameControlSupported()) {
+                    return;
+                }
+
+                final List<float[]> rgbMeans = new ArrayList<float[]>();
+                final Size maxSize = getMaxSize(
+                        getSupportedSizeForFormat(YUV_420_888, camera.getId(), mCameraManager));
+
+                final int sensitivityMin = staticInfo.getSensitivityMinimumOrDefault();
+                final int sensitivityMax = staticInfo.getSensitivityMaximumOrDefault();
+
+                // List each sensitivity from min-max in NUM_STEPS increments
+                int[] sensitivities = new int[NUM_STEPS];
+                for (int i = 0; i < NUM_STEPS; ++i) {
+                    int delta = (sensitivityMax - sensitivityMin) / (NUM_STEPS - 1);
+                    sensitivities[i] = sensitivityMin + delta * i;
+                }
+
+                ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize);
+
+                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);
+
+                    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);
+
+                    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);
+                }
+            }
+        });
+
+    }
+
+    /**
+     * Common script graph for manual-capture based tests that determine the average pixel
+     * values of a cropped sub-region.
+     *
+     * <p>Processing chain:
+     *
+     * <pre>
+     * input:  YUV_420_888 surface
+     * output: mean YUV value of a central section of the image,
+     *         YUV 4:4:4 encoded as U8_3
+     * steps:
+     *      1) crop [0.45,0.45] - [0.55, 0.55]
+     *      2) average columns
+     *      3) average rows
+     * </pre>
+     * </p>
+     */
+    private static ScriptGraph createGraphForYuvCroppedMeans(final Size size) {
+        ScriptGraph scriptGraph = ScriptGraph.create()
+                .configureInputWithSurface(size, YUV_420_888)
+                .configureScript(ScriptYuvCrop.class)
+                    .set(ScriptYuvCrop.CROP_WINDOW,
+                            new Patch(size, /*x*/0.45f, /*y*/0.45f, /*w*/0.1f, /*h*/0.1f).toRectF())
+                    .buildScript()
+                .chainScript(ScriptYuvMeans2dTo1d.class)
+                .chainScript(ScriptYuvMeans1d.class)
+                // TODO: Make a script for YUV 444 -> RGB 888 conversion
+                .buildGraph();
+        return scriptGraph;
+    }
+
+    /*
+     * TODO: Refactor below code into separate classes and to not depend on AllocationTest
+     * inner variables.
+     *
+     * TODO: add javadocs to below methods
+     *
+     * TODO: Figure out if there's some elegant way to compose these forEaches together, so that
+     * the callers don't have to do a ton of nesting
+     */
+
+    interface CameraBlock {
+        void run(CameraDevice camera) throws CameraAccessException;
+    }
+
+    class CameraIterable {
+        public void forEachCamera(CameraBlock runnable)
+                throws CameraAccessException {
+            forEachCamera(/*fullHwLevel*/false, runnable);
+        }
+
+        public void forEachCamera(boolean fullHwLevel, CameraBlock runnable)
+                throws CameraAccessException {
+            assertNotNull("No camera manager", mCameraManager);
+            assertNotNull("No camera IDs", mCameraIds);
+
+            for (int i = 0; i < mCameraIds.length; i++) {
+                // Don't execute the runnable against non-FULL cameras if FULL is required
+                CameraCharacteristics properties =
+                        mCameraManager.getCameraCharacteristics(mCameraIds[i]);
+                StaticMetadata staticInfo = new StaticMetadata(properties);
+                if (fullHwLevel && !staticInfo.isHardwareLevelFull()) {
+                    Log.i(TAG, String.format(
+                            "Skipping this test for camera %s, needs FULL hw level",
+                            mCameraIds[i]));
+                    continue;
+                }
+                if (!staticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, String.format(
+                        "Skipping this test for camera %s, does not support regular outputs",
+                        mCameraIds[i]));
+                    continue;
+                }
+                // Open camera and execute test
+                Log.i(TAG, "Testing Camera " + mCameraIds[i]);
+                try {
+                    openDevice(mCameraIds[i]);
+
+                    runnable.run(mCamera);
+                } finally {
+                    closeDevice(mCameraIds[i]);
+                }
+            }
+        }
+
+        private void openDevice(String cameraId) {
+            if (mCamera != null) {
+                throw new IllegalStateException("Already have open camera device");
+            }
+            try {
+                mCamera = openCamera(
+                    mCameraManager, cameraId, mCameraListener, mHandler);
+            } catch (CameraAccessException e) {
+                fail("Fail to open camera synchronously, " + Log.getStackTraceString(e));
+            } catch (BlockingOpenException e) {
+                fail("Fail to open camera asynchronously, " + Log.getStackTraceString(e));
+            }
+            mCameraListener.waitForState(STATE_OPENED, CAMERA_OPEN_TIMEOUT_MS);
+        }
+
+        private void closeDevice(String cameraId) {
+            if (mCamera != null) {
+                mCamera.close();
+                mCameraListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
+                mCamera = null;
+            }
+        }
+    }
+
+    interface SizeBlock {
+        void run(Size size) throws CameraAccessException;
+    }
+
+    class SizeIterable {
+        public void forEachSize(int format, SizeBlock runnable) throws CameraAccessException {
+            assertNotNull("No camera opened", mCamera);
+            assertNotNull("No camera manager", mCameraManager);
+
+            CameraCharacteristics properties =
+                    mCameraManager.getCameraCharacteristics(mCamera.getId());
+
+            assertNotNull("Can't get camera properties!", properties);
+
+            StreamConfigurationMap config =
+                    properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+            int[] availableOutputFormats = config.getOutputFormats();
+            assertArrayNotEmpty(availableOutputFormats,
+                    "availableOutputFormats should not be empty");
+            Arrays.sort(availableOutputFormats);
+            assertTrue("Can't find the format " + format + " in supported formats " +
+                    Arrays.toString(availableOutputFormats),
+                    Arrays.binarySearch(availableOutputFormats, format) >= 0);
+
+            Size[] availableSizes = getSupportedSizeForFormat(format, mCamera.getId(),
+                    mCameraManager);
+            assertArrayNotEmpty(availableSizes, "availableSizes should not be empty");
+
+            for (Size size : availableSizes) {
+
+                if (VERBOSE) {
+                    Log.v(TAG, "Testing size " + size.toString() +
+                            " for camera " + mCamera.getId());
+                }
+                runnable.run(size);
+            }
+        }
+    }
+
+    interface ResultBlock {
+        void run(CaptureResult result) throws CameraAccessException;
+    }
+
+    class ResultIterable {
+        public void forEachResultOnce(CaptureRequest request, ResultBlock block)
+                throws CameraAccessException {
+            forEachResult(request, /*count*/1, /*repeating*/false, block);
+        }
+
+        public void forEachResultRepeating(CaptureRequest request, int count, ResultBlock block)
+                throws CameraAccessException {
+            forEachResult(request, count, /*repeating*/true, block);
+        }
+
+        public void forEachResult(CaptureRequest request, int count, boolean repeating,
+                ResultBlock block) throws CameraAccessException {
+
+            // TODO: start capture, i.e. configureOutputs
+
+            SimpleCaptureCallback listener = new SimpleCaptureCallback();
+
+            if (!repeating) {
+                for (int i = 0; i < count; ++i) {
+                    mSession.capture(request, listener, mHandler);
+                }
+            } else {
+                mSession.setRepeatingRequest(request, listener, mHandler);
+            }
+
+            // Assume that the device is already IDLE.
+            mSessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_ACTIVE,
+                    CAMERA_ACTIVE_TIMEOUT_MS);
+
+            for (int i = 0; i < count; ++i) {
+                if (VERBOSE) {
+                    Log.v(TAG, String.format("Testing with result %d of %d for camera %s",
+                            i, count, mCamera.getId()));
+                }
+
+                CaptureResult result = listener.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
+                block.run(result);
+            }
+
+            if (repeating) {
+                mSession.stopRepeating();
+                mSessionListener.getStateWaiter().waitForState(
+                    BlockingSessionCallback.SESSION_READY, CAMERA_IDLE_TIMEOUT_MS);
+            }
+
+            // TODO: Make a Configure decorator or some such for configureOutputs
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
new file mode 100644
index 0000000..41e2045
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureRawTest.java
@@ -0,0 +1,725 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureRequest.Builder;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleImageReaderListener;
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.Image;
+import android.util.Log;
+import android.util.Range;
+import android.util.Size;
+
+import java.util.ArrayList;
+
+/**
+ * Basic tests for burst capture in RAW formats.
+ */
+public class BurstCaptureRawTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "BurstCaptureRawTest";
+    private static final int RAW_FORMATS[] = {
+            ImageFormat.RAW10, ImageFormat.RAW12, ImageFormat.RAW_SENSOR };
+    private static final int NONSTALL_RAW_FORMATS[] = {
+        ImageFormat.RAW10, ImageFormat.RAW12 };
+    private static final long EXPOSURE_MULTIPLIERS[] = {
+            1, 3, 5 };
+    private static final int SENSITIVITY_MLTIPLIERS[] = {
+            1, 3, 5 };
+    private static final int MAX_FRAMES_BURST =
+            EXPOSURE_MULTIPLIERS.length * SENSITIVITY_MLTIPLIERS.length;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Verify raw sensor size information is correctly configured.
+     */
+    public void testRawSensorSize() throws Exception {
+        Log.i(TAG, "Begin testRawSensorSize");
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+
+                ArrayList<Integer> supportedRawList = new ArrayList<Integer>(RAW_FORMATS.length);
+                if (!checkCapability(supportedRawList, RAW_FORMATS)) {
+                    Log.i(TAG, "Capability is not supported on camera " + id
+                            + ". Skip the test.");
+                    continue;
+                }
+
+                Size[] rawSizes = mStaticInfo.getRawOutputSizesChecked();
+                assertTrue("No capture sizes available for RAW format!", rawSizes.length != 0);
+
+                // Check happens in getRawDimensChecked.
+                Size rawSize = mStaticInfo.getRawDimensChecked();
+            } finally {
+                closeDevice();
+            }
+        }
+        Log.i(TAG, "End testRawSensorSize");
+    }
+
+    /**
+     * Round [exposure, gain] down, rather than to the nearest, in RAW 10/16
+     * <p>
+     * Verify the value of metadata (exposure and sensitivity) is rounded down if the request cannot
+     * be honored.
+     * </p>
+     */
+    public void testMetadataRoundDown() throws Exception {
+        Log.i(TAG, "Begin testMetadataRoundDown");
+
+        performTestRoutine(new TestMetaDataRoundDownRoutine(), RAW_FORMATS);
+
+        Log.i(TAG, "End testMetadataRoundDown");
+    }
+
+    /**
+     * Manual and Auto setting test in RAW formats
+     * <p>
+     * Make sure switching between manual and auto setting would not make the capture results out of
+     * sync.
+     * </p>
+     */
+    public void testManualAutoSwitch() throws Exception {
+        Log.i(TAG, "Begin testManualAutoSwitch");
+
+        performTestRoutine(new TestManualAutoSwitch(), RAW_FORMATS);
+
+        Log.i(TAG, "End testManualAutoSwitch");
+    }
+
+    /**
+     * Per frame timestamp test in non-stalled RAW formats
+     */
+    public void testTimestamp() throws Exception {
+        Log.i(TAG, "Begin testTimestamp");
+
+        performTestRoutine(new TestTimestamp(), NONSTALL_RAW_FORMATS);
+
+        Log.i(TAG, "End testTimestamp");
+    }
+
+    /*
+     * Below are private infrastructure for all tests
+     */
+
+    /**
+     * A structure encapsulates all the parameters for setting up preview, and RAW capture.
+     */
+    class CaptureSetup
+    {
+        public CaptureSetup(Size previewCaptureSize, Size rawCaptureSize,
+                CaptureRequest.Builder previewRequestBuilder,
+                CaptureRequest.Builder rawRequestBuilder,
+                SimpleCaptureCallback previewCaptureCallback,
+                SimpleCaptureCallback rawCaptureCallback,
+                SimpleImageReaderListener rawReaderListener)
+        {
+            mPreviewCaptureSize = previewCaptureSize;
+            mRawCaptureSize = rawCaptureSize;
+            mPreviewRequestBuilder = previewRequestBuilder;
+            mRawRequestBuilder = rawRequestBuilder;
+            mPreviewCaptureCallback = previewCaptureCallback;
+            mRawCaptureCallback = rawCaptureCallback;
+            mRawReaderListener = rawReaderListener;
+        }
+
+        public Size getPreviewCaptureSize()
+        {
+            return mPreviewCaptureSize;
+        }
+
+        public Size getRawCaptureSize()
+        {
+            return mRawCaptureSize;
+        }
+
+        public CaptureRequest.Builder getPreviewRequestBuilder()
+        {
+            return mPreviewRequestBuilder;
+        }
+
+        public CaptureRequest.Builder getRawRequestBuilder() {
+            return mRawRequestBuilder;
+        }
+
+        public SimpleCaptureCallback getPreviewCaptureCallback() {
+            return mPreviewCaptureCallback;
+        }
+
+        public SimpleCaptureCallback getRawCaptureCallback() {
+            return mRawCaptureCallback;
+        }
+
+        public SimpleImageReaderListener getRawReaderListener() {
+            return mRawReaderListener;
+        }
+
+        private Size mPreviewCaptureSize;
+        private Size mRawCaptureSize;
+        private CaptureRequest.Builder mPreviewRequestBuilder;
+        private CaptureRequest.Builder mRawRequestBuilder;
+
+        /** all the non-testing requests are sent to here */
+        private SimpleCaptureCallback mPreviewCaptureCallback;
+        /** all the testing requests are sent to here */
+        private SimpleCaptureCallback mRawCaptureCallback;
+        /** all the testing framebuffers are sent to here */
+        private SimpleImageReaderListener mRawReaderListener;
+    }
+
+    /**
+     * Interface for the test routines that are being called by performTestRoutines(). Implement
+     * different test cases in execute().
+     */
+    interface TestRoutine {
+        public void execute(CaptureRequest.Builder rawBurstBuilder,
+                SimpleCaptureCallback rawCaptureCallback,
+                SimpleImageReaderListener rawReaderListener, int rawFormat) throws Exception;
+    }
+
+    /**
+     * Implementation of metadata round down test.
+     */
+    class TestMetaDataRoundDownRoutine implements TestRoutine
+    {
+        @Override
+        public void execute(CaptureRequest.Builder rawBurstBuilder,
+                SimpleCaptureCallback rawCaptureCallback,
+                SimpleImageReaderListener rawReaderListener, int rawFormat) throws Exception
+        {
+            // build burst capture
+            ArrayList<CaptureRequest> rawRequestList = createBurstRequest(rawBurstBuilder);
+
+            // submit captrue
+            Log.i(TAG, "Submitting Burst Request.");
+            mSession.captureBurst(rawRequestList, rawCaptureCallback, mHandler);
+
+            // verify metadata
+            for (int i = 0; i < MAX_FRAMES_BURST; i++) {
+                CaptureResult result = rawCaptureCallback.getCaptureResult(
+                        CAPTURE_IMAGE_TIMEOUT_MS);
+
+                long resultExposure = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
+                int resultSensitivity = result.get(CaptureResult.SENSOR_SENSITIVITY);
+                long desiredExposure = rawRequestList.get(i).get(
+                        CaptureRequest.SENSOR_EXPOSURE_TIME);
+                int desiredSensitivity = rawRequestList.get(i).get(
+                        CaptureRequest.SENSOR_SENSITIVITY);
+
+                Log.i(TAG, String.format(
+                        "Received capture result, exposure = %d, sensitivity = %d. "
+                                + "Requested exposure = %d, sensitivity = %d.",
+                        resultExposure,
+                        resultSensitivity, desiredExposure, desiredSensitivity));
+
+                mCollector.expectTrue(
+                        String.format("Exposure value is greater than requested: "
+                                + "requested = %d, result = %d.",
+                                desiredExposure, resultExposure),
+                                resultExposure <= desiredExposure);
+
+                mCollector.expectTrue(
+                        String.format("Sensitivity value is greater than requested: "
+                                + "requested = %d, result = %d.",
+                                desiredSensitivity, resultSensitivity),
+                                resultSensitivity <= desiredSensitivity);
+            }
+        }
+    }
+
+    /**
+     * Implementation of manual-auto switching test.
+     */
+    class TestManualAutoSwitch implements TestRoutine
+    {
+        @Override
+        public void execute(CaptureRequest.Builder rawBurstBuilder,
+                SimpleCaptureCallback rawCaptureCallback,
+                SimpleImageReaderListener rawReaderListener, int rawFormat) throws Exception
+        {
+            // create a capture request builder to preserve all the original values
+            CaptureRequest.Builder originBuilder = mCamera.createCaptureRequest(
+                    CameraDevice.TEMPLATE_STILL_CAPTURE);
+            copyBurstRequetBuilder(originBuilder, rawBurstBuilder);
+
+            // build burst capture
+            ArrayList<CaptureRequest> rawRequestList = createBurstRequest(rawBurstBuilder);
+
+            // submit captrue but ignore
+            mSession.captureBurst(rawRequestList, rawCaptureCallback, mHandler);
+
+            // drain the capture result
+            drainQueues(rawReaderListener, rawCaptureCallback);
+
+            // reset and build capture with 3A
+            copyBurstRequetBuilder(rawBurstBuilder, originBuilder);
+            rawRequestList = createBurstRequestWith3A(rawBurstBuilder);
+
+            // submit captrue but ignore
+            mSession.captureBurst(rawRequestList, rawCaptureCallback, mHandler);
+
+            // drain the capture result
+            drainQueues(rawReaderListener, rawCaptureCallback);
+
+            // reset and rebuild manual raw burst capture
+            copyBurstRequetBuilder(rawBurstBuilder, originBuilder);
+            rawRequestList = createBurstRequest(rawBurstBuilder);
+
+            // submit capture
+            Log.i(TAG, "Submitting Burst Request.");
+            mSession.captureBurst(rawRequestList, rawCaptureCallback, mHandler);
+
+            // verify metadata
+            for (int i = 0; i < MAX_FRAMES_BURST; i++) {
+                CaptureResult result = rawCaptureCallback.getCaptureResult(
+                        CAPTURE_IMAGE_TIMEOUT_MS);
+
+                long resultExposure = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
+                int resultSensitivity = result.get(CaptureResult.SENSOR_SENSITIVITY);
+                int resultEdgeMode = result.get(CaptureResult.EDGE_MODE);
+                int resultNoiseReductionMode = result.get(
+                        CaptureResult.NOISE_REDUCTION_MODE);
+                long desiredExposure = rawRequestList.get(i).get(
+                        CaptureRequest.SENSOR_EXPOSURE_TIME);
+                int desiredSensitivity = rawRequestList.get(i).get(
+                        CaptureRequest.SENSOR_SENSITIVITY);
+
+                Log.i(TAG, String.format(
+                        "Received capture result, exposure = %d, sensitivity = %d. "
+                                + "Requested exposure = %d, sensitivity = %d.",
+                        resultExposure,
+                        resultSensitivity, desiredExposure, desiredSensitivity));
+
+                mCollector.expectTrue(String.format("Edge mode is not turned off."),
+                        resultEdgeMode == CaptureRequest.EDGE_MODE_OFF);
+
+                mCollector.expectTrue(String.format("Noise reduction is not turned off."),
+                        resultNoiseReductionMode
+                        == CaptureRequest.NOISE_REDUCTION_MODE_OFF);
+
+                mCollector.expectTrue(
+                        String.format("Exposure value is greater than requested: "
+                                + "requested = %d, result = %d.",
+                                desiredExposure, resultExposure),
+                                resultExposure <= desiredExposure);
+
+                mCollector.expectTrue(
+                        String.format("Sensitivity value is greater than requested: "
+                                + "requested = %d, result = %d.",
+                                desiredSensitivity, resultSensitivity),
+                                resultSensitivity <= desiredSensitivity);
+            }
+
+        }
+    }
+
+    /**
+     * Implementation of timestamp test
+     */
+    class TestTimestamp implements TestRoutine
+    {
+        private final double THRESHOLD = 5000000.0; // 5ms
+        private final long EXPOSURE_MULTIPLIERS_PRIVATE[] = {
+                1, 1, 1 };
+        private final int SENSITIVITY_MLTIPLIERS_PRIVATE[] = {
+                1, 1, 1 };
+        private final int MAX_FRAMES_BURST_PRIVATE =
+                EXPOSURE_MULTIPLIERS_PRIVATE.length * SENSITIVITY_MLTIPLIERS_PRIVATE.length;
+
+        @Override
+        public void execute(Builder rawBurstBuilder, SimpleCaptureCallback rawCaptureCallback,
+                SimpleImageReaderListener rawReaderListener, int rawFormat) throws Exception {
+            // prepare some local variables
+            ArrayList<Long> sensorTime = new ArrayList<Long>(MAX_FRAMES_BURST_PRIVATE);
+
+            // build burst capture
+            ArrayList<CaptureRequest> rawRequestList = createBurstRequest(rawBurstBuilder,
+                    EXPOSURE_MULTIPLIERS_PRIVATE, SENSITIVITY_MLTIPLIERS_PRIVATE);
+
+            // submit capture while recording timestamp
+            Log.i(TAG, "Submitting Burst Request.");
+            mSession.captureBurst(rawRequestList, rawCaptureCallback, mHandler);
+
+            // receive frames while recording timestamp
+            for (int i = 0; i < MAX_FRAMES_BURST_PRIVATE; i++) {
+                CaptureResult result = rawCaptureCallback.getCaptureResult(
+                        CAPTURE_IMAGE_TIMEOUT_MS);
+                long resultExposure = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
+                int resultSensitivity = result.get(CaptureResult.SENSOR_SENSITIVITY);
+                long resultTimestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
+                Log.i(TAG, String.format(
+                        "Received capture result, exposure = %d, sensitivity = %d, timestamp = %d",
+                        resultExposure, resultSensitivity, resultTimestamp));
+
+                sensorTime.add(resultTimestamp);
+            }
+
+            // compare sensor time and compute the difference
+            ArrayList<Long> deltaList = new ArrayList<Long>();
+            for (int i = 1; i < MAX_FRAMES_BURST_PRIVATE; i++)
+            {
+                deltaList.add(sensorTime.get(i) - sensorTime.get(i - 1));
+            }
+
+            // compute the average and standard deviation of the differences
+            double average = 0.0;
+            for (int i = 0; i < deltaList.size(); i++)
+            {
+                average += deltaList.get(i);
+            }
+            average /= deltaList.size();
+
+            double stddev = 0.0;
+            for (int i = 0; i < deltaList.size(); i++)
+            {
+                double diff = deltaList.get(i) - average;
+                stddev += diff * diff;
+            }
+            stddev = Math.sqrt(stddev / deltaList.size());
+
+            Log.i(TAG, String.format("average = %.2f, stddev = %.2f", average, stddev));
+
+            StringBuilder sensorTimestampMessage = new StringBuilder();
+            for (int i = 0; i < sensorTime.size(); i++)
+            {
+                sensorTimestampMessage.append("frame [");
+                sensorTimestampMessage.append(i);
+                sensorTimestampMessage.append("] SENSOR_TIMESTAMP = ");
+                sensorTimestampMessage.append(sensorTime.get(i));
+                sensorTimestampMessage.append("\n");
+            }
+
+            mCollector.expectLessOrEqual(
+                    "The standard deviation of frame interval is larger then threshold: " +
+                    String.format("stddev = %.2f, threshold = %.2f.\n", stddev, THRESHOLD) +
+                    sensorTimestampMessage.toString(),
+                    THRESHOLD, stddev);
+        }
+    }
+
+    /**
+     * Check sensor capability prior to the test.
+     *
+     * @return true if the it is has the capability to execute the test.
+     */
+    private boolean checkCapability(ArrayList<Integer> supportedRawList, int[] testedFormats) {
+        // make sure the sensor has manual support
+        if (!mStaticInfo.isCapabilitySupported(
+                CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL)) {
+            Log.w(TAG, "Full hardware level is not supported");
+            return false;
+        }
+
+        // get the list of supported RAW format
+        StreamConfigurationMap config = mStaticInfo.getValueFromKeyNonNull(
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+
+        // check for the RAW support
+        supportedRawList.clear();
+        for (int rawFormat : testedFormats) {
+            if (!config.isOutputSupportedFor(rawFormat)) {
+                continue;
+            }
+            supportedRawList.add(rawFormat);
+        }
+
+        if (supportedRawList.size() == 0)
+        {
+            Log.w(TAG, "RAW output is not supported!");
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Return the sensor format to human readable string.
+     *
+     * @param format Sensor image format.
+     * @return Human readable string.
+     */
+    private String imageFormatToString(int format) {
+        switch (format) {
+            case ImageFormat.RAW10:
+                return "RAW10";
+            case ImageFormat.RAW12:
+                return "RAW12";
+            case ImageFormat.RAW_SENSOR:
+                return "RAW_SENSOR";
+        }
+
+        return "Unknown";
+    }
+
+    /**
+     * Setting up various classes prior to the request, e.g.: capture size, builder, callback and
+     * listener
+     *
+     * @return initialized variables that can be directly fed into prepareCaptureAndStartPreview().
+     */
+    private CaptureSetup initCaptureSetupForPreviewAndRaw() throws Exception
+    {
+        // capture size
+        Size previewSize = mOrderedPreviewSizes.get(0);
+        Size rawSize = mStaticInfo.getRawDimensChecked();
+
+        // builder
+        CaptureRequest.Builder previewCaptureBuilder = mCamera.createCaptureRequest(
+                CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder rawCaptureBuilder = mCamera.createCaptureRequest(
+                CameraDevice.TEMPLATE_STILL_CAPTURE);
+
+        // callback
+        SimpleCaptureCallback previewCaptureCallback = new SimpleCaptureCallback();
+        SimpleCaptureCallback rawCaptureCallback = new SimpleCaptureCallback();
+        SimpleImageReaderListener rawReaderListener = new SimpleImageReaderListener();
+
+        CaptureSetup setup = new CaptureSetup(previewSize, rawSize, previewCaptureBuilder,
+                rawCaptureBuilder, previewCaptureCallback, rawCaptureCallback, rawReaderListener);
+
+        return setup;
+    }
+
+    /**
+     * Construct an array of burst request with manual exposure and sensitivity.
+     * <p>
+     * For each capture request, 3A and post processing (noise reduction, sharpening, etc) will be
+     * turned off. Then exposure and sensitivity value will be configured, which are determined by
+     * EXPOSURE_MULIPLIERS and SENSITIVITY_MULTIPLIERS.
+     * </p>
+     *
+     * @param rawBurstBuilder The builder needs to have targets setup.
+     * @return An array list capture request for burst.
+     */
+    private ArrayList<CaptureRequest> createBurstRequest(CaptureRequest.Builder rawBurstBuilder)
+    {
+        return createBurstRequest(rawBurstBuilder, EXPOSURE_MULTIPLIERS, SENSITIVITY_MLTIPLIERS);
+    }
+
+    private ArrayList<CaptureRequest> createBurstRequest(CaptureRequest.Builder rawBurstBuilder,
+            long[] exposureMultipliers, int[] sensitivityMultipliers) {
+        // set manual mode
+        rawBurstBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
+        rawBurstBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
+        rawBurstBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
+                CaptureRequest.NOISE_REDUCTION_MODE_OFF);
+        rawBurstBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_OFF);
+        // exposure has higher priority over frame duration; therefore the frame readout time:
+        // exposure time + overhead
+        rawBurstBuilder.set(CaptureRequest.SENSOR_FRAME_DURATION, 0L);
+
+        // get the exposure and sensitivity range
+        Range<Long> exposureRangeNs = new Range<Long>(mStaticInfo.getExposureMinimumOrDefault(),
+                mStaticInfo.getExposureMaximumOrDefault());
+
+        Range<Integer> isoRange = new Range<Integer>(mStaticInfo.getSensitivityMinimumOrDefault(),
+                mStaticInfo.getSensitivityMaximumOrDefault());
+
+        Log.i(TAG, String.format("Exposure time - max: %d, min: %d.", exposureRangeNs.getUpper(),
+                exposureRangeNs.getLower()));
+        Log.i(TAG, String.format("Sensitivity - max: %d, min: %d.", isoRange.getUpper(),
+                isoRange.getLower()));
+
+        // building burst request
+        int maxFramesBurst = exposureMultipliers.length * sensitivityMultipliers.length;
+        Log.i(TAG, String.format("Setting up burst = %d frames.", maxFramesBurst));
+        ArrayList<CaptureRequest> rawRequestList = new ArrayList<CaptureRequest>(maxFramesBurst);
+
+        for (int i = 0; i < exposureMultipliers.length; i++) {
+            for (int j = 0; j < sensitivityMultipliers.length; j++) {
+                long desiredExposure = Math.min(
+                        exposureRangeNs.getLower() * exposureMultipliers[i],
+                        exposureRangeNs.getUpper());
+
+                int desiredSensitivity =
+                        Math.min(isoRange.getLower() * sensitivityMultipliers[j],
+                                isoRange.getUpper());
+
+                rawBurstBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, desiredExposure);
+                rawBurstBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, desiredSensitivity);
+
+                rawRequestList.add(rawBurstBuilder.build());
+            }
+        }
+        return rawRequestList;
+    }
+
+    /**
+     * Construct an array of burst request with 3A
+     * <p>
+     * For each capture request, 3A and post processing (noise reduction, sharpening, etc) will be
+     * turned on.
+     * </p>
+     *
+     * @param rawBurstBuilder The builder needs to have targets setup.
+     * @return An array list capture request for burst.
+     */
+    private ArrayList<CaptureRequest> createBurstRequestWith3A(
+            CaptureRequest.Builder rawBurstBuilder)
+    {
+        // set 3A mode to simulate regular still capture
+        rawBurstBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
+        rawBurstBuilder.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_AUTO);
+        rawBurstBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE,
+                CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
+        rawBurstBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_HIGH_QUALITY);
+
+        // building burst request
+        Log.i(TAG, String.format("Setting up burst = %d frames.", MAX_FRAMES_BURST));
+        ArrayList<CaptureRequest> rawRequestList = new ArrayList<CaptureRequest>(MAX_FRAMES_BURST);
+
+        for (int i = 0; i < MAX_FRAMES_BURST; i++) {
+            rawRequestList.add(rawBurstBuilder.build());
+        }
+
+        return rawRequestList;
+    }
+
+    /**
+     * An utility method to copy capture request builders. This is used for recovery purpose to
+     * reverse the changes we made to the builder.
+     *
+     * @param dst the builder to write into.
+     * @param src the builder that needs to be copied.
+     */
+    private void copyBurstRequetBuilder(CaptureRequest.Builder dst, CaptureRequest.Builder src)
+    {
+        dst.set(CaptureRequest.CONTROL_AE_MODE, src.get(CaptureRequest.CONTROL_AE_MODE));
+        dst.set(CaptureRequest.CONTROL_AWB_MODE, src.get(CaptureRequest.CONTROL_AWB_MODE));
+        dst.set(CaptureRequest.NOISE_REDUCTION_MODE, src.get(CaptureRequest.NOISE_REDUCTION_MODE));
+        dst.set(CaptureRequest.EDGE_MODE, src.get(CaptureRequest.EDGE_MODE));
+        dst.set(CaptureRequest.SENSOR_FRAME_DURATION,
+                src.get(CaptureRequest.SENSOR_FRAME_DURATION));
+        dst.set(CaptureRequest.SENSOR_EXPOSURE_TIME, src.get(CaptureRequest.SENSOR_EXPOSURE_TIME));
+        dst.set(CaptureRequest.SENSOR_SENSITIVITY, src.get(CaptureRequest.SENSOR_SENSITIVITY));
+    }
+
+    /**
+     * Draining the image reader and capture callback queue
+     *
+     * @param readerListener Image reader listener needs to be drained.
+     * @param captureCallback Capture callback needs to be drained.
+     * @throws Exception Exception from the queue.
+     */
+    private void drainQueues(SimpleImageReaderListener readerListener,
+            SimpleCaptureCallback captureCallback) throws Exception
+    {
+        for (int i = 0; i < MAX_FRAMES_BURST; i++) {
+            Image image = readerListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            image.close();
+
+            CaptureResult result = captureCallback.getCaptureResult(
+                    CAPTURE_IMAGE_TIMEOUT_MS);
+            long timestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
+            Log.d(TAG, String.format("timestamp = %d", timestamp));
+        }
+    }
+
+    /**
+     * Stop preview and remove the target surfaces inside the CaptureRequest.Builder.
+     *
+     * @param previewBuilder Configured builder for preview.
+     * @param rawBurstBuilder Configured builder for RAW.
+     * @throws Exception Exceptions from stopPreview.
+     */
+    private void stopPreviewAndClearSurface(CaptureRequest.Builder previewBuilder,
+            CaptureRequest.Builder rawBurstBuilder) throws Exception
+    {
+        previewBuilder.removeTarget(mPreviewSurface);
+        rawBurstBuilder.removeTarget(mPreviewSurface);
+        rawBurstBuilder.removeTarget(mReaderSurface);
+
+        stopPreview();
+    }
+
+    private void performTestRoutine(TestRoutine routine, int[] testedFormats) throws Exception
+    {
+        final int PREPARE_TIMEOUT_MS = 10000;
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+
+                ArrayList<Integer> supportedRawList = new ArrayList<Integer>(RAW_FORMATS.length);
+                if (!checkCapability(supportedRawList, testedFormats)) {
+                    Log.i(TAG, "Capability is not supported on camera " + id
+                            + ". Skip the test.");
+                    continue;
+                }
+
+                // test each supported RAW format
+                for (int rawFormat : supportedRawList) {
+                    Log.i(TAG, "Testing format " + imageFormatToString(rawFormat) + ".");
+
+                    // prepare preview and still RAW capture
+                    CaptureSetup captureSetup = initCaptureSetupForPreviewAndRaw();
+
+                    Size previewCaptureSize = captureSetup.getPreviewCaptureSize();
+                    Size rawCaptureSize = captureSetup.getRawCaptureSize();
+
+                    CaptureRequest.Builder previewBuilder = captureSetup.getPreviewRequestBuilder();
+                    CaptureRequest.Builder rawBurstBuilder = captureSetup.getRawRequestBuilder();
+
+                    SimpleCaptureCallback previewCaptureCallback =
+                            captureSetup.getPreviewCaptureCallback();
+                    SimpleCaptureCallback rawCaptureCallback = captureSetup.getRawCaptureCallback();
+                    SimpleImageReaderListener rawReaderListener = captureSetup
+                            .getRawReaderListener();
+
+                    // start preview and prepare RAW capture
+                    prepareCaptureAndStartPreview(previewBuilder, rawBurstBuilder,
+                            previewCaptureSize, rawCaptureSize, rawFormat, previewCaptureCallback,
+                            MAX_FRAMES_BURST, rawReaderListener);
+
+                    // Prepare still surface to prevent large allocations slow down capture
+                    mSession.prepare(mReaderSurface);
+                    mSessionListener.waitForSurfacePrepared(
+                            mSession, mReaderSurface, PREPARE_TIMEOUT_MS);
+
+                    // execute test routine
+                    routine.execute(rawBurstBuilder, rawCaptureCallback, rawReaderListener,
+                            rawFormat);
+
+                    // clear out the surface and camera session
+                    stopPreviewAndClearSurface(previewBuilder, rawBurstBuilder);
+                    rawReaderListener.drain();
+                    closeImageReader();
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java
new file mode 100644
index 0000000..d8fae6d
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/BurstCaptureTest.java
@@ -0,0 +1,374 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.Image;
+import android.util.Log;
+import android.util.Range;
+import android.util.Size;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class BurstCaptureTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "BurstCaptureTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    /**
+     * Test YUV burst capture with full-AUTO control.
+     * Also verifies sensor settings operation if READ_SENSOR_SETTINGS is available.
+     */
+    public void testYuvBurst() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                String id = mCameraIds[i];
+                Log.i(TAG, "Testing YUV Burst for camera " + id);
+                openDevice(id);
+
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                }
+                if (!mStaticInfo.isAeLockSupported() || !mStaticInfo.isAwbLockSupported()) {
+                    Log.i(TAG, "AE/AWB lock is not supported in camera " + id +
+                            ". Skip the test");
+                    continue;
+                }
+
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    Log.i(TAG, "Legacy camera doesn't report min frame duration" +
+                            ". Skip the test");
+                    continue;
+                }
+
+                yuvBurstTestByCamera(id);
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    private void yuvBurstTestByCamera(String cameraId) throws Exception {
+        // Parameters
+        final int MAX_CONVERGENCE_FRAMES = 150; // 5 sec at 30fps
+        final long MAX_PREVIEW_RESULT_TIMEOUT_MS = 1000;
+        final int BURST_SIZE = 100;
+        final float FRAME_DURATION_MARGIN_FRACTION = 0.1f;
+
+        // Find a good preview size (bound to 1080p)
+        final Size previewSize = mOrderedPreviewSizes.get(0);
+
+        // Get maximum YUV_420_888 size
+        final Size stillSize = getSortedSizesForFormat(
+                cameraId, mCameraManager, ImageFormat.YUV_420_888, /*bound*/null).get(0);
+
+        // Find max pipeline depth and sync latency
+        final int maxPipelineDepth = mStaticInfo.getCharacteristics().get(
+            CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH);
+        final int maxSyncLatency = mStaticInfo.getCharacteristics().get(
+            CameraCharacteristics.SYNC_MAX_LATENCY);
+
+        // Find minimum frame duration for full-res YUV_420_888
+        StreamConfigurationMap config = mStaticInfo.getCharacteristics().get(
+            CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+        final long minStillFrameDuration =
+                config.getOutputMinFrameDuration(ImageFormat.YUV_420_888, stillSize);
+
+        // Find suitable target FPS range - as high as possible
+        List<Range<Integer> > fpsRanges = Arrays.asList(
+                mStaticInfo.getAeAvailableTargetFpsRangesChecked());
+        Range<Integer> targetRange = mStaticInfo.getAeMaxTargetFpsRange();
+        // Add 0.05 here so Fps like 29.99 evaluated to 30
+        int minBurstFps = (int) Math.floor(1e9 / minStillFrameDuration + 0.05f);
+        boolean foundConstantMaxYUVRange = false;
+        boolean foundYUVStreamingRange = false;
+
+        for (Range<Integer> fpsRange : fpsRanges) {
+            if (fpsRange.getLower() == minBurstFps && fpsRange.getUpper() == minBurstFps) {
+                foundConstantMaxYUVRange = true;
+            }
+            if (fpsRange.getLower() <= 15 && fpsRange.getUpper() == minBurstFps) {
+                foundYUVStreamingRange = true;
+            }
+        }
+
+        assertTrue(String.format("Cam %s: Target FPS range of (%d, %d) must be supported",
+                cameraId, minBurstFps, minBurstFps), foundConstantMaxYUVRange);
+        assertTrue(String.format(
+                "Cam %s: Target FPS range of (x, %d) where x <= 15 must be supported",
+                cameraId, minBurstFps), foundYUVStreamingRange);
+        assertTrue(String.format("Cam %s: No target FPS range found with minimum FPS above " +
+                        " 1/minFrameDuration (%d fps, duration %d ns) for full-resolution YUV",
+                        cameraId, minBurstFps, minStillFrameDuration),
+                targetRange.getLower() >= minBurstFps);
+
+        Log.i(TAG, String.format("Selected frame rate range %d - %d for YUV burst",
+                        targetRange.getLower(), targetRange.getUpper()));
+
+        // Check if READ_SENSOR_SETTINGS is supported
+        final boolean checkSensorSettings = mStaticInfo.isCapabilitySupported(
+            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS);
+
+        // Configure basic preview and burst settings
+
+        CaptureRequest.Builder previewBuilder =
+            mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder burstBuilder =
+            mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+        previewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
+                targetRange);
+        burstBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
+                targetRange);
+        burstBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
+        burstBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
+
+        // Create session and start up preview
+
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        ImageDropperListener imageDropper = new ImageDropperListener();
+
+        prepareCaptureAndStartPreview(
+            previewBuilder, burstBuilder,
+            previewSize, stillSize,
+            ImageFormat.YUV_420_888, resultListener,
+            /*maxNumImages*/ 3, imageDropper);
+
+        // Create burst
+
+        List<CaptureRequest> burst = new ArrayList<>();
+        for (int i = 0; i < BURST_SIZE; i++) {
+            burst.add(burstBuilder.build());
+        }
+
+        // Converge AE/AWB
+
+        int frameCount = 0;
+        while (true) {
+            CaptureResult result = resultListener.getCaptureResult(MAX_PREVIEW_RESULT_TIMEOUT_MS);
+            int aeState = result.get(CaptureResult.CONTROL_AE_STATE);
+            int awbState = result.get(CaptureResult.CONTROL_AWB_STATE);
+
+            if (DEBUG) {
+                Log.d(TAG, "aeState: " + aeState + ". awbState: " + awbState);
+            }
+
+            if ((aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED ||
+                    aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED) &&
+                    awbState == CaptureResult.CONTROL_AWB_STATE_CONVERGED) {
+                break;
+            }
+            frameCount++;
+            assertTrue(String.format("Cam %s: Can not converge AE and AWB within %d frames",
+                    cameraId, MAX_CONVERGENCE_FRAMES),
+                frameCount < MAX_CONVERGENCE_FRAMES);
+        }
+
+        // Lock AF if there's a focuser
+
+        if (mStaticInfo.hasFocuser()) {
+            previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                CaptureRequest.CONTROL_AF_TRIGGER_START);
+            mSession.capture(previewBuilder.build(), resultListener, mHandler);
+            previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
+
+            frameCount = 0;
+            while (true) {
+                CaptureResult result = resultListener.getCaptureResult(MAX_PREVIEW_RESULT_TIMEOUT_MS);
+                int afState = result.get(CaptureResult.CONTROL_AF_STATE);
+
+                if (DEBUG) {
+                    Log.d(TAG, "afState: " + afState);
+                }
+
+                if (afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
+                    afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
+                    break;
+                }
+                frameCount++;
+                assertTrue(String.format("Cam %s: Cannot lock AF within %d frames", cameraId,
+                        MAX_CONVERGENCE_FRAMES),
+                    frameCount < MAX_CONVERGENCE_FRAMES);
+            }
+        }
+
+        // Lock AE/AWB
+
+        previewBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
+        previewBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
+
+        CaptureRequest lockedRequest = previewBuilder.build();
+        mSession.setRepeatingRequest(lockedRequest, resultListener, mHandler);
+
+        // Wait for first result with locking
+        resultListener.drain();
+        CaptureResult lockedResult =
+                resultListener.getCaptureResultForRequest(lockedRequest, maxPipelineDepth);
+
+        int pipelineDepth = lockedResult.get(CaptureResult.REQUEST_PIPELINE_DEPTH);
+
+        // Then start waiting on results to get the first result that should be synced
+        // up, and also fire the burst as soon as possible
+
+        if (maxSyncLatency == CameraCharacteristics.SYNC_MAX_LATENCY_PER_FRAME_CONTROL) {
+            // The locked result we have is already synchronized so start the burst
+            mSession.captureBurst(burst, resultListener, mHandler);
+        } else {
+            // Need to get a synchronized result, and may need to start burst later to
+            // be synchronized correctly
+
+            boolean burstSent = false;
+
+            // Calculate how many requests we need to still send down to camera before we
+            // know the settings have settled for the burst
+
+            int numFramesWaited = maxSyncLatency;
+            if (numFramesWaited == CameraCharacteristics.SYNC_MAX_LATENCY_UNKNOWN) {
+                numFramesWaited = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY;
+            }
+
+            int requestsNeededToSync = numFramesWaited - pipelineDepth;
+            for (int i = 0; i < numFramesWaited; i++) {
+                if (!burstSent && requestsNeededToSync <= 0) {
+                    mSession.captureBurst(burst, resultListener, mHandler);
+                    burstSent = true;
+                }
+                lockedResult = resultListener.getCaptureResult(MAX_PREVIEW_RESULT_TIMEOUT_MS);
+                requestsNeededToSync--;
+            }
+
+            assertTrue("Cam " + cameraId + ": Burst failed to fire!", burstSent);
+        }
+
+        // Read in locked settings if supported
+
+        long burstExposure = 0;
+        long burstFrameDuration = 0;
+        int burstSensitivity = 0;
+        if (checkSensorSettings) {
+            burstExposure = lockedResult.get(CaptureResult.SENSOR_EXPOSURE_TIME);
+            burstFrameDuration = lockedResult.get(CaptureResult.SENSOR_FRAME_DURATION);
+            burstSensitivity = lockedResult.get(CaptureResult.SENSOR_SENSITIVITY);
+
+            assertTrue(String.format("Cam %s: Frame duration %d ns too short compared to " +
+                    "exposure time %d ns", cameraId, burstFrameDuration, burstExposure),
+                burstFrameDuration >= burstExposure);
+
+            assertTrue(String.format("Cam %s: Exposure time is not valid: %d",
+                    cameraId, burstExposure),
+                burstExposure > 0);
+            assertTrue(String.format("Cam %s: Frame duration is not valid: %d",
+                    cameraId, burstFrameDuration),
+                burstFrameDuration > 0);
+            assertTrue(String.format("Cam %s: Sensitivity is not valid: %d",
+                    cameraId, burstSensitivity),
+                burstSensitivity > 0);
+        }
+
+        // Process burst results
+        int burstIndex = 0;
+        CaptureResult burstResult =
+                resultListener.getCaptureResultForRequest(burst.get(burstIndex),
+                    maxPipelineDepth + 1);
+        long prevTimestamp = -1;
+        final long frameDurationBound = (long)
+                (minStillFrameDuration * (1 + FRAME_DURATION_MARGIN_FRACTION) );
+
+        List<Long> frameDurations = new ArrayList<>();
+
+        while(true) {
+            // Verify the result
+            assertTrue("Cam " + cameraId + ": Result doesn't match expected request",
+                    burstResult.getRequest() == burst.get(burstIndex));
+
+            // Verify locked settings
+            if (checkSensorSettings) {
+                long exposure = burstResult.get(CaptureResult.SENSOR_EXPOSURE_TIME);
+                int sensitivity = burstResult.get(CaptureResult.SENSOR_SENSITIVITY);
+                assertTrue("Cam " + cameraId + ": Exposure not locked!",
+                    exposure == burstExposure);
+                assertTrue("Cam " + cameraId + ": Sensitivity not locked!",
+                    sensitivity == burstSensitivity);
+            }
+
+            // Collect inter-frame durations
+            long timestamp = burstResult.get(CaptureResult.SENSOR_TIMESTAMP);
+            if (prevTimestamp != -1) {
+                long frameDuration = timestamp - prevTimestamp;
+                frameDurations.add(frameDuration);
+                if (DEBUG) {
+                    Log.i(TAG, String.format("Frame %03d    Duration %.2f ms", burstIndex,
+                            frameDuration/1e6));
+                }
+            }
+            prevTimestamp = timestamp;
+
+            // Get next result
+            burstIndex++;
+            if (burstIndex == BURST_SIZE) break;
+            burstResult = resultListener.getCaptureResult(MAX_PREVIEW_RESULT_TIMEOUT_MS);
+        }
+
+        // Verify inter-frame durations
+
+        long meanFrameSum = 0;
+        for (Long duration : frameDurations) {
+            meanFrameSum += duration;
+        }
+        float meanFrameDuration = (float) meanFrameSum / frameDurations.size();
+
+        float stddevSum = 0;
+        for (Long duration : frameDurations) {
+            stddevSum += (duration - meanFrameDuration) * (duration - meanFrameDuration);
+        }
+        float stddevFrameDuration = (float)
+                Math.sqrt(1.f / (frameDurations.size() - 1 ) * stddevSum);
+
+        Log.i(TAG, String.format("Cam %s: Burst frame duration mean: %.1f, stddev: %.1f", cameraId,
+                meanFrameDuration, stddevFrameDuration));
+
+        assertTrue(
+            String.format("Cam %s: Burst frame duration mean %.1f ns is larger than acceptable, " +
+                "expecting below %d ns, allowing below %d", cameraId,
+                meanFrameDuration, minStillFrameDuration, frameDurationBound),
+            meanFrameDuration <= frameDurationBound);
+
+        // Calculate upper 97.5% bound (assuming durations are normally distributed...)
+        float limit95FrameDuration = meanFrameDuration + 2 * stddevFrameDuration;
+
+        // Don't enforce this yet, but warn
+        if (limit95FrameDuration > frameDurationBound) {
+            Log.w(TAG,
+                String.format("Cam %s: Standard deviation is too large compared to limit: " +
+                    "mean: %.1f ms, stddev: %.1f ms: 95%% bound: %f ms", cameraId,
+                    meanFrameDuration/1e6, stddevFrameDuration/1e6,
+                    limit95FrameDuration/1e6));
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/Camera2MultiViewCtsActivity.java b/tests/camera/src/android/hardware/camera2/cts/Camera2MultiViewCtsActivity.java
new file mode 100644
index 0000000..d6350fc
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/Camera2MultiViewCtsActivity.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 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.hardware.camera2.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.SurfaceView;
+import android.view.TextureView;
+import android.view.WindowManager;
+
+import android.camera.cts.R;
+
+public class Camera2MultiViewCtsActivity extends Activity {
+    private final static String TAG = "Camera2MultiViewCtsActivity";
+    private TextureView[] mTextureView = new TextureView[2];
+    private SurfaceView[] mSurfaceView = new SurfaceView[2];
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.multi_view);
+        mTextureView[0] = (TextureView) findViewById(R.id.texture_view_1);
+        mTextureView[1] = (TextureView) findViewById(R.id.texture_view_2);
+        mSurfaceView[0] = (SurfaceView) findViewById(R.id.surface_view_1);
+        mSurfaceView[1] = (SurfaceView) findViewById(R.id.surface_view_2);
+
+        //Make sure screen is on when this activity window is visible to the user.
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+    }
+
+    public TextureView getTextureView(int index) {
+        if (index < 0 || index > 1) {
+            throw new IllegalArgumentException("Texture view index must be 0 or 1");
+        }
+        return mTextureView[index];
+    }
+
+    public SurfaceView getSurfaceView(int index) {
+        if (index < 0 || index > 1) {
+            throw new IllegalArgumentException("Surface view index must be 0 or 1");
+        }
+        return mSurfaceView[index];
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java b/tests/camera/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
new file mode 100644
index 0000000..6773a9b
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 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.hardware.camera2.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.ConditionVariable;
+import android.os.SystemClock;
+import android.util.Log;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.camera.cts.R;
+
+public class Camera2SurfaceViewCtsActivity extends Activity implements SurfaceHolder.Callback {
+    private final static String TAG = "Camera2SurfaceViewCtsActivity";
+    private final ConditionVariable surfaceChangedDone = new ConditionVariable();
+
+    private SurfaceView mSurfaceView;
+    private int currentWidth = 0;
+    private int currentHeight = 0;
+    private final Object sizeLock = new Object();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.surface_view_2);
+        mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
+        mSurfaceView.getHolder().addCallback(this);
+    }
+
+    public SurfaceView getSurfaceView() {
+        return mSurfaceView;
+    }
+
+    public boolean waitForSurfaceSizeChanged(int timeOutMs, int expectWidth, int expectHeight) {
+        if (timeOutMs <= 0 || expectWidth <= 0 || expectHeight <= 0) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "timeout(%d), expectWidth(%d), and expectHeight(%d) " +
+                            "should all be positive numbers",
+                            timeOutMs, expectWidth, expectHeight));
+        }
+
+        synchronized(sizeLock) {
+            if (expectWidth == currentWidth && expectHeight == currentHeight) {
+                return true;
+            }
+        }
+
+        int waitTimeMs = timeOutMs;
+        boolean changeSucceeded = false;
+        while (!changeSucceeded && waitTimeMs > 0) {
+            long startTimeMs = SystemClock.elapsedRealtime();
+            changeSucceeded = surfaceChangedDone.block(waitTimeMs);
+            if (!changeSucceeded) {
+                Log.e(TAG, "Wait for surface change timed out after " + timeOutMs + " ms");
+                return changeSucceeded;
+            } else {
+                // Get a surface change callback, need to check if the size is expected.
+                surfaceChangedDone.close();
+                if (currentWidth == expectWidth && currentHeight == expectHeight) {
+                    return changeSucceeded;
+                }
+                // Do a further iteration surface change check as surfaceChanged could be called
+                // again.
+                changeSucceeded = false;
+            }
+            waitTimeMs -= (SystemClock.elapsedRealtime() - startTimeMs);
+        }
+
+        // Couldn't get expected surface size change.
+        return false;
+     }
+
+    @Override
+    public void surfaceCreated(SurfaceHolder holder) {
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+        Log.i(TAG, "Surface Changed to: " + width + "x" + height);
+        synchronized (sizeLock) {
+            currentWidth = width;
+            currentHeight = height;
+        }
+        surfaceChangedDone.open();
+    }
+
+    @Override
+    public void surfaceDestroyed(SurfaceHolder holder) {
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
new file mode 100644
index 0000000..44fda14
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraDeviceTest.java
@@ -0,0 +1,1805 @@
+/*
+ * 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 android.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static com.android.ex.camera2.blocking.BlockingStateCallback.*;
+import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
+import static org.mockito.Mockito.*;
+import static android.hardware.camera2.CaptureRequest.*;
+
+import android.content.Context;
+import android.graphics.SurfaceTexture;
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.media.ImageReader;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.Range;
+import android.view.Surface;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.ex.camera2.blocking.BlockingStateCallback;
+import com.android.ex.camera2.utils.StateWaiter;
+
+import org.mockito.ArgumentMatcher;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import android.util.Size;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * <p>Basic test for CameraDevice APIs.</p>
+ */
+public class CameraDeviceTest extends Camera2AndroidTestCase {
+    private static final String TAG = "CameraDeviceTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final int ERROR_LISTENER_WAIT_TIMEOUT_MS = 1000;
+    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 CameraCaptureSession mSession;
+
+    private BlockingStateCallback mCameraMockListener;
+    private int mLatestDeviceState = STATE_UNINITIALIZED;
+    private BlockingSessionCallback mSessionMockListener;
+    private StateWaiter mSessionWaiter;
+    private int mLatestSessionState = -1; // uninitialized
+
+    private static int[] sTemplates = new int[] {
+            CameraDevice.TEMPLATE_PREVIEW,
+            CameraDevice.TEMPLATE_RECORD,
+            CameraDevice.TEMPLATE_STILL_CAPTURE,
+            CameraDevice.TEMPLATE_VIDEO_SNAPSHOT
+    };
+
+    // Request templates that are unsupported by LEGACY mode.
+    private static Set<Integer> sLegacySkipTemplates = new HashSet<>();
+    static {
+        sLegacySkipTemplates.add(CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
+        sLegacySkipTemplates.add(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
+        sLegacySkipTemplates.add(CameraDevice.TEMPLATE_MANUAL);
+    }
+
+    @Override
+    public void setContext(Context context) {
+        super.setContext(context);
+
+        /**
+         * Workaround for mockito and JB-MR2 incompatibility
+         *
+         * Avoid java.lang.IllegalArgumentException: dexcache == null
+         * https://code.google.com/p/dexmaker/issues/detail?id=2
+         */
+        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
+
+        /**
+         * Create error listener in context scope, to catch asynchronous device error.
+         * Use spy object here since we want to use the SimpleDeviceListener callback
+         * implementation (spy doesn't stub the functions unless we ask it to do so).
+         */
+        mCameraMockListener = spy(new BlockingStateCallback());
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        /**
+         * Due to the asynchronous nature of camera device error callback, we
+         * have to make sure device doesn't run into error state before. If so,
+         * fail the rest of the tests. This is especially needed when error
+         * callback is fired too late.
+         */
+        verify(mCameraMockListener, never())
+                .onError(
+                    any(CameraDevice.class),
+                    anyInt());
+        verify(mCameraMockListener, never())
+                .onDisconnected(
+                    any(CameraDevice.class));
+
+        mCameraListener = mCameraMockListener;
+        createDefaultImageReader(DEFAULT_CAPTURE_SIZE, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
+                new ImageDropperListener());
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * <p>
+     * Test camera capture request preview capture template.
+     * </p>
+     *
+     * <p>
+     * The request template returned by the camera device must include a
+     * necessary set of metadata keys, and their values must be set correctly.
+     * It mainly requires below settings:
+     * </p>
+     * <ul>
+     * <li>All 3A settings are auto.</li>
+     * <li>All sensor settings are not null.</li>
+     * <li>All ISP processing settings should be non-manual, and the camera
+     * device should make sure the stable frame rate is guaranteed for the given
+     * settings.</li>
+     * </ul>
+     */
+    public void testCameraDevicePreviewTemplate() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_PREVIEW);
+        }
+
+        // TODO: test the frame rate sustainability in preview use case test.
+    }
+
+    /**
+     * <p>
+     * Test camera capture request still capture template.
+     * </p>
+     *
+     * <p>
+     * The request template returned by the camera device must include a
+     * necessary set of metadata keys, and their values must be set correctly.
+     * It mainly requires below settings:
+     * </p>
+     * <ul>
+     * <li>All 3A settings are auto.</li>
+     * <li>All sensor settings are not null.</li>
+     * <li>All ISP processing settings should be non-manual, and the camera
+     * device should make sure the high quality takes priority to the stable
+     * frame rate for the given settings.</li>
+     * </ul>
+     */
+    public void testCameraDeviceStillTemplate() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_STILL_CAPTURE);
+        }
+    }
+
+    /**
+     * <p>
+     * Test camera capture video recording template.
+     * </p>
+     *
+     * <p>
+     * The request template returned by the camera device must include a
+     * necessary set of metadata keys, and their values must be set correctly.
+     * It has the similar requirement as preview, with one difference:
+     * </p>
+     * <ul>
+     * <li>Frame rate should be stable, for example, wide fps range like [7, 30]
+     * is a bad setting.</li>
+     */
+    public void testCameraDeviceRecordingTemplate() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_RECORD);
+        }
+
+        // TODO: test the frame rate sustainability in recording use case test.
+    }
+
+    /**
+     *<p>Test camera capture video snapshot template.</p>
+     *
+     * <p>The request template returned by the camera device must include a necessary set of
+     * metadata keys, and their values must be set correctly. It has the similar requirement
+     * as recording, with an additional requirement: the settings should maximize image quality
+     * without compromising stable frame rate.</p>
+     */
+    public void testCameraDeviceVideoSnapShotTemplate() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
+        }
+
+        // TODO: test the frame rate sustainability in video snapshot use case test.
+    }
+
+    /**
+     *<p>Test camera capture request zero shutter lag template.</p>
+     *
+     * <p>The request template returned by the camera device must include a necessary set of
+     * metadata keys, and their values must be set correctly. It has the similar requirement
+     * as preview, with an additional requirement: </p>
+     */
+    public void testCameraDeviceZSLTemplate() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
+        }
+    }
+
+    /**
+     * <p>
+     * Test camera capture request manual template.
+     * </p>
+     *
+     * <p>
+     * The request template returned by the camera device must include a
+     * necessary set of metadata keys, and their values must be set correctly. It
+     * mainly requires below settings:
+     * </p>
+     * <ul>
+     * <li>All 3A settings are manual.</li>
+     * <li>ISP processing parameters are set to preview quality.</li>
+     * <li>The manual capture parameters (exposure, sensitivity, and so on) are
+     * set to reasonable defaults.</li>
+     * </ul>
+     */
+    public void testCameraDeviceManualTemplate() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_MANUAL);
+        }
+    }
+
+    public void testCameraDeviceCreateCaptureBuilder() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i], mCameraMockListener);
+                /**
+                 * Test: that each template type is supported, and that its required fields are
+                 * present.
+                 */
+                for (int j = 0; j < sTemplates.length; j++) {
+                    // Skip video snapshots for LEGACY mode
+                    if (mStaticInfo.isHardwareLevelLegacy() &&
+                            sTemplates[j] == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) {
+                        continue;
+                    }
+                    // Skip non-PREVIEW templates for non-color output
+                    if (!mStaticInfo.isColorOutputSupported() &&
+                            sTemplates[j] != CameraDevice.TEMPLATE_PREVIEW) {
+                        continue;
+                    }
+                    CaptureRequest.Builder capReq = mCamera.createCaptureRequest(sTemplates[j]);
+                    assertNotNull("Failed to create capture request", capReq);
+                    if (mStaticInfo.areKeysAvailable(CaptureRequest.SENSOR_EXPOSURE_TIME)) {
+                        assertNotNull("Missing field: SENSOR_EXPOSURE_TIME",
+                                capReq.get(CaptureRequest.SENSOR_EXPOSURE_TIME));
+                    }
+                    if (mStaticInfo.areKeysAvailable(CaptureRequest.SENSOR_SENSITIVITY)) {
+                        assertNotNull("Missing field: SENSOR_SENSITIVITY",
+                                capReq.get(CaptureRequest.SENSOR_SENSITIVITY));
+                    }
+                }
+            }
+            finally {
+                try {
+                    closeSession();
+                } finally {
+                    closeDevice(mCameraIds[i], mCameraMockListener);
+                }
+            }
+        }
+    }
+
+    public void testCameraDeviceSetErrorListener() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i], mCameraMockListener);
+                /**
+                 * Test: that the error listener can be set without problems.
+                 * Also, wait some time to check if device doesn't run into error.
+                 */
+                SystemClock.sleep(ERROR_LISTENER_WAIT_TIMEOUT_MS);
+                verify(mCameraMockListener, never())
+                        .onError(
+                                any(CameraDevice.class),
+                                anyInt());
+            }
+            finally {
+                try {
+                    closeSession();
+                } finally {
+                    closeDevice(mCameraIds[i], mCameraMockListener);
+                }
+            }
+        }
+    }
+
+    public void testCameraDeviceCapture() throws Exception {
+        runCaptureTest(/*burst*/false, /*repeating*/false, /*abort*/false);
+    }
+
+    public void testCameraDeviceCaptureBurst() throws Exception {
+        runCaptureTest(/*burst*/true, /*repeating*/false, /*abort*/false);
+    }
+
+    public void testCameraDeviceRepeatingRequest() throws Exception {
+        runCaptureTest(/*burst*/false, /*repeating*/true, /*abort*/false);
+    }
+
+    public void testCameraDeviceRepeatingBurst() throws Exception {
+        runCaptureTest(/*burst*/true, /*repeating*/true, /*abort*/false);
+    }
+
+    /**
+     * Test {@link android.hardware.camera2.CameraCaptureSession#abortCaptures} API.
+     *
+     * <p>Abort is the fastest way to idle the camera device for reconfiguration with
+     * {@link android.hardware.camera2.CameraCaptureSession#abortCaptures}, at the cost of
+     * discarding in-progress work. Once the abort is complete, the idle callback will be called.
+     * </p>
+     */
+    public void testCameraDeviceAbort() throws Exception {
+        runCaptureTest(/*burst*/false, /*repeating*/true, /*abort*/true);
+        runCaptureTest(/*burst*/true, /*repeating*/true, /*abort*/true);
+        /**
+         * TODO: this is only basic test of abort. we probably should also test below cases:
+         *
+         * 1. Performance. Make sure abort is faster than stopRepeating, we can test each one a
+         * couple of times, then compare the average. Also, for abortCaptures() alone, we should
+         * make sure it doesn't take too long time (e.g. <100ms for full devices, <500ms for limited
+         * devices), after the abort, we should be able to get all results back very quickly.  This
+         * can be done in performance test.
+         *
+         * 2. Make sure all in-flight request comes back after abort, e.g. submit a couple of
+         * long exposure single captures, then abort, then check if we can get the pending
+         * request back quickly.
+         *
+         * 3. Also need check onCaptureSequenceCompleted for repeating burst after abortCaptures().
+         */
+    }
+
+    /**
+     * Test invalid capture (e.g. null or empty capture request).
+     */
+    public void testInvalidCapture() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i], mCameraMockListener);
+                waitForDeviceState(STATE_OPENED, CAMERA_OPEN_TIMEOUT_MS);
+
+                prepareCapture();
+
+                invalidRequestCaptureTestByCamera();
+
+                closeSession();
+            }
+            finally {
+                closeDevice(mCameraIds[i], mCameraMockListener);
+            }
+        }
+    }
+
+    /**
+     * Test to ensure that we can call camera2 API methods inside callbacks.
+     *
+     * Tests:
+     *  onOpened -> createCaptureSession, createCaptureRequest
+     *  onConfigured -> getDevice, abortCaptures,
+     *     createCaptureRequest, capture, setRepeatingRequest, stopRepeating
+     *  onCaptureCompleted -> createCaptureRequest, getDevice, abortCaptures,
+     *     capture, setRepeatingRequest, stopRepeating, session+device.close
+     */
+    public void testChainedOperation() throws Throwable {
+
+        final ArrayList<Surface> outputs = new ArrayList<>();
+        outputs.add(mReaderSurface);
+
+        // A queue for the chained listeners to push results to
+        // A success Throwable indicates no errors; other Throwables detail a test failure;
+        // nulls indicate timeouts.
+        final Throwable success = new Throwable("Success");
+        final LinkedBlockingQueue<Throwable> results = new LinkedBlockingQueue<>();
+
+        // Define listeners
+        // A cascade of Device->Session->Capture listeners, each of which invokes at least one
+        // method on the camera device or session.
+
+        class ChainedCaptureCallback extends CameraCaptureSession.CaptureCallback {
+            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
+                    TotalCaptureResult result) {
+                try {
+                    CaptureRequest.Builder request2 =
+                            session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                    request2.addTarget(mReaderSurface);
+
+                    // Some calls to the camera for coverage
+                    session.abortCaptures();
+                    session.capture(request2.build(),
+                            /*listener*/ null, /*handler*/ null);
+                    session.setRepeatingRequest(request2.build(),
+                            /*listener*/ null, /*handler*/ null);
+                    session.stopRepeating();
+
+                    CameraDevice camera = session.getDevice();
+                    session.close();
+                    camera.close();
+
+                    results.offer(success);
+                } catch (Throwable t) {
+                    results.offer(t);
+                }
+            }
+
+            public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
+                    CaptureFailure failure) {
+                try {
+                    CameraDevice camera = session.getDevice();
+                    session.close();
+                    camera.close();
+                    fail("onCaptureFailed invoked with failure reason: " + failure.getReason());
+                } catch (Throwable t) {
+                    results.offer(t);
+                }
+            }
+        }
+
+        class ChainedSessionListener extends CameraCaptureSession.StateCallback {
+            private final ChainedCaptureCallback mCaptureCallback = new ChainedCaptureCallback();
+
+            public void onConfigured(CameraCaptureSession session) {
+                try {
+                    CaptureRequest.Builder request =
+                            session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                    request.addTarget(mReaderSurface);
+                    // Some calls to the camera for coverage
+                    session.getDevice();
+                    session.abortCaptures();
+                    // The important call for the next level of chaining
+                    session.capture(request.build(), mCaptureCallback, mHandler);
+                    // Some more calls
+                    session.setRepeatingRequest(request.build(),
+                            /*listener*/ null, /*handler*/ null);
+                    session.stopRepeating();
+                    results.offer(success);
+                } catch (Throwable t) {
+                    results.offer(t);
+                }
+            }
+
+            public void onConfigureFailed(CameraCaptureSession session) {
+                try {
+                    CameraDevice camera = session.getDevice();
+                    session.close();
+                    camera.close();
+                    fail("onConfigureFailed was invoked");
+                } catch (Throwable t) {
+                    results.offer(t);
+                }
+            }
+        }
+
+        class ChainedCameraListener extends CameraDevice.StateCallback {
+            private final ChainedSessionListener mSessionListener = new ChainedSessionListener();
+
+            public CameraDevice cameraDevice;
+
+            public void onOpened(CameraDevice camera) {
+
+                cameraDevice = camera;
+                try {
+                    // Some calls for coverage
+                    camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                    // The important call for next level of chaining
+                    camera.createCaptureSession(outputs, mSessionListener, mHandler);
+                    results.offer(success);
+                } catch (Throwable t) {
+                    try {
+                        camera.close();
+                        results.offer(t);
+                    } catch (Throwable t2) {
+                        Log.e(TAG,
+                                "Second failure reached; discarding first exception with trace " +
+                                Log.getStackTraceString(t));
+                        results.offer(t2);
+                    }
+                }
+            }
+
+            public void onDisconnected(CameraDevice camera) {
+                try {
+                    camera.close();
+                    fail("onDisconnected invoked");
+                } catch (Throwable t) {
+                    results.offer(t);
+                }
+            }
+
+            public void onError(CameraDevice camera, int error) {
+                try {
+                    camera.close();
+                    fail("onError invoked with error code: " + error);
+                } catch (Throwable t) {
+                    results.offer(t);
+                }
+            }
+        }
+
+        // Actual test code
+
+        for (int i = 0; i < mCameraIds.length; i++) {
+            Throwable result;
+
+            if (!(new StaticMetadata(mCameraManager.getCameraCharacteristics(mCameraIds[i]))).
+                    isColorOutputSupported()) {
+                Log.i(TAG, "Camera " + mCameraIds[i] + " does not support color outputs, skipping");
+                continue;
+            }
+
+            // Start chained cascade
+            ChainedCameraListener cameraListener = new ChainedCameraListener();
+            mCameraManager.openCamera(mCameraIds[i], cameraListener, mHandler);
+
+            // Check if open succeeded
+            result = results.poll(CAMERA_OPEN_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            if (result != success) {
+                if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
+                if (result == null) {
+                    fail("Timeout waiting for camera open");
+                } else {
+                    throw result;
+                }
+            }
+
+            // Check if configure succeeded
+            result = results.poll(SESSION_CONFIGURE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            if (result != success) {
+                if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
+                if (result == null) {
+                    fail("Timeout waiting for session configure");
+                } else {
+                    throw result;
+                }
+            }
+
+            // Check if capture succeeded
+            result = results.poll(CAPTURE_RESULT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            if (result != success) {
+                if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
+                if (result == null) {
+                    fail("Timeout waiting for capture completion");
+                } else {
+                    throw result;
+                }
+            }
+        }
+    }
+
+    /**
+     * Verify basic semantics and error conditions of the prepare call.
+     *
+     */
+    public void testPrepare() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i], mCameraMockListener);
+                waitForDeviceState(STATE_OPENED, CAMERA_OPEN_TIMEOUT_MS);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+
+                prepareTestByCamera();
+            }
+            finally {
+                closeDevice(mCameraIds[i], mCameraMockListener);
+            }
+        }
+    }
+
+    /**
+     * Verify creating sessions back to back.
+     */
+    public void testCreateSessions() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i], mCameraMockListener);
+                waitForDeviceState(STATE_OPENED, CAMERA_OPEN_TIMEOUT_MS);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+
+                testCreateSessionsByCamera(mCameraIds[i]);
+            }
+            finally {
+                closeDevice(mCameraIds[i], mCameraMockListener);
+            }
+        }
+    }
+
+    /**
+     * Verify creating sessions back to back and only the last one is valid for
+     * submitting requests.
+     */
+    private void testCreateSessionsByCamera(String cameraId) throws Exception {
+        final int NUM_SESSIONS = 3;
+        final int SESSION_TIMEOUT_MS = 1000;
+        final int CAPTURE_TIMEOUT_MS = 3000;
+
+        if (VERBOSE) {
+            Log.v(TAG, "Testing creating sessions for camera " + cameraId);
+        }
+
+        Size yuvSize = getSortedSizesForFormat(cameraId, mCameraManager, ImageFormat.YUV_420_888,
+                /*bound*/null).get(0);
+        Size jpegSize = getSortedSizesForFormat(cameraId, mCameraManager, ImageFormat.JPEG,
+                /*bound*/null).get(0);
+
+        // Create a list of image readers. JPEG for last one and YUV for the rest.
+        List<ImageReader> imageReaders = new ArrayList<>();
+        List<CameraCaptureSession> allSessions = new ArrayList<>();
+
+        try {
+            for (int i = 0; i < NUM_SESSIONS - 1; i++) {
+                imageReaders.add(ImageReader.newInstance(yuvSize.getWidth(), yuvSize.getHeight(),
+                        ImageFormat.YUV_420_888, /*maxImages*/1));
+            }
+            imageReaders.add(ImageReader.newInstance(jpegSize.getWidth(), jpegSize.getHeight(),
+                    ImageFormat.JPEG, /*maxImages*/1));
+
+            // Create multiple sessions back to back.
+            MultipleSessionCallback sessionListener =
+                    new MultipleSessionCallback(/*failOnConfigureFailed*/true);
+            for (int i = 0; i < NUM_SESSIONS; i++) {
+                List<Surface> outputs = new ArrayList<>();
+                outputs.add(imageReaders.get(i).getSurface());
+                mCamera.createCaptureSession(outputs, sessionListener, mHandler);
+            }
+
+            // Verify we get onConfigured() for all sessions.
+            allSessions = sessionListener.getAllSessions(NUM_SESSIONS,
+                    SESSION_TIMEOUT_MS * NUM_SESSIONS);
+            assertEquals(String.format("Got %d sessions but configured %d sessions",
+                    allSessions.size(), NUM_SESSIONS), allSessions.size(), NUM_SESSIONS);
+
+            // Verify all sessions except the last one are closed.
+            for (int i = 0; i < NUM_SESSIONS - 1; i++) {
+                sessionListener.waitForSessionClose(allSessions.get(i), SESSION_TIMEOUT_MS);
+            }
+
+            // Verify we can capture a frame with the last session.
+            CameraCaptureSession session = allSessions.get(allSessions.size() - 1);
+            SimpleCaptureCallback captureListener = new SimpleCaptureCallback();
+            ImageReader reader = imageReaders.get(imageReaders.size() - 1);
+            SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+            reader.setOnImageAvailableListener(imageListener, mHandler);
+
+            CaptureRequest.Builder builder =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+            builder.addTarget(reader.getSurface());
+            CaptureRequest request = builder.build();
+
+            session.capture(request, captureListener, mHandler);
+            captureListener.getCaptureResultForRequest(request, CAPTURE_TIMEOUT_MS);
+            imageListener.getImage(CAPTURE_TIMEOUT_MS).close();
+        } finally {
+            for (ImageReader reader : imageReaders) {
+                reader.close();
+            }
+            for (CameraCaptureSession session : allSessions) {
+                session.close();
+            }
+        }
+    }
+
+    private void prepareTestByCamera() throws Exception {
+        final int PREPARE_TIMEOUT_MS = 10000;
+
+        mSessionMockListener = spy(new BlockingSessionCallback());
+
+        SurfaceTexture output1 = new SurfaceTexture(1);
+        Surface output1Surface = new Surface(output1);
+        SurfaceTexture output2 = new SurfaceTexture(2);
+        Surface output2Surface = new Surface(output2);
+
+        List<Surface> outputSurfaces = new ArrayList<>(
+            Arrays.asList(output1Surface, output2Surface));
+        mCamera.createCaptureSession(outputSurfaces, mSessionMockListener, mHandler);
+
+        mSession = mSessionMockListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+
+        // Try basic prepare
+
+        mSession.prepare(output1Surface);
+
+        verify(mSessionMockListener, timeout(PREPARE_TIMEOUT_MS).times(1))
+                .onSurfacePrepared(eq(mSession), eq(output1Surface));
+
+        // Should not complain if preparing already prepared stream
+
+        mSession.prepare(output1Surface);
+
+        verify(mSessionMockListener, timeout(PREPARE_TIMEOUT_MS).times(2))
+                .onSurfacePrepared(eq(mSession), eq(output1Surface));
+
+        // Check surface not included in session
+
+        SurfaceTexture output3 = new SurfaceTexture(3);
+        Surface output3Surface = new Surface(output3);
+        try {
+            mSession.prepare(output3Surface);
+            // Legacy camera prepare always succeed
+            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                fail("Preparing surface not part of session must throw IllegalArgumentException");
+            }
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        // Ensure second prepare also works
+
+        mSession.prepare(output2Surface);
+
+        verify(mSessionMockListener, timeout(PREPARE_TIMEOUT_MS).times(1))
+                .onSurfacePrepared(eq(mSession), eq(output2Surface));
+
+        // Use output1
+
+        CaptureRequest.Builder r = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        r.addTarget(output1Surface);
+
+        mSession.capture(r.build(), null, null);
+
+        try {
+            mSession.prepare(output1Surface);
+            // Legacy camera prepare always succeed
+            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                fail("Preparing already-used surface must throw IllegalArgumentException");
+            }
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        // Create new session with outputs 1 and 3, ensure output1Surface still can't be prepared
+        // again
+
+        mSessionMockListener = spy(new BlockingSessionCallback());
+
+        outputSurfaces = new ArrayList<>(
+            Arrays.asList(output1Surface, output3Surface));
+        mCamera.createCaptureSession(outputSurfaces, mSessionMockListener, mHandler);
+
+        mSession = mSessionMockListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+
+        try {
+            mSession.prepare(output1Surface);
+            // Legacy camera prepare always succeed
+            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                fail("Preparing surface used in previous session must throw " +
+                        "IllegalArgumentException");
+            }
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        // Use output3, wait for result, then make sure prepare still doesn't work
+
+        r = mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        r.addTarget(output3Surface);
+
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        mSession.capture(r.build(), resultListener, mHandler);
+
+        resultListener.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
+
+        try {
+            mSession.prepare(output3Surface);
+            // Legacy camera prepare always succeed
+            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                fail("Preparing already-used surface must throw IllegalArgumentException");
+            }
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        // Create new session with outputs 1 and 2, ensure output2Surface can be prepared again
+
+        mSessionMockListener = spy(new BlockingSessionCallback());
+
+        outputSurfaces = new ArrayList<>(
+            Arrays.asList(output1Surface, output2Surface));
+        mCamera.createCaptureSession(outputSurfaces, mSessionMockListener, mHandler);
+
+        mSession = mSessionMockListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+
+        mSession.prepare(output2Surface);
+
+        verify(mSessionMockListener, timeout(PREPARE_TIMEOUT_MS).times(1))
+                .onSurfacePrepared(eq(mSession), eq(output2Surface));
+
+        try {
+            mSession.prepare(output1Surface);
+            // Legacy camera prepare always succeed
+            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                fail("Preparing surface used in previous session must throw " +
+                        "IllegalArgumentException");
+            }
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+    }
+
+
+    private void invalidRequestCaptureTestByCamera() throws Exception {
+        if (VERBOSE) Log.v(TAG, "invalidRequestCaptureTestByCamera");
+
+        List<CaptureRequest> emptyRequests = new ArrayList<CaptureRequest>();
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest unConfiguredRequest = requestBuilder.build();
+        List<CaptureRequest> unConfiguredRequests = new ArrayList<CaptureRequest>();
+        unConfiguredRequests.add(unConfiguredRequest);
+
+        try {
+            // Test: CameraCaptureSession capture should throw IAE for null request.
+            mSession.capture(/*request*/null, /*listener*/null, mHandler);
+            mCollector.addMessage(
+                    "Session capture should throw IllegalArgumentException for null request");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+
+        try {
+            // Test: CameraCaptureSession capture should throw IAE for request
+            // without surface configured.
+            mSession.capture(unConfiguredRequest, /*listener*/null, mHandler);
+            mCollector.addMessage("Session capture should throw " +
+                    "IllegalArgumentException for request without surface configured");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+
+        try {
+            // Test: CameraCaptureSession setRepeatingRequest should throw IAE for null request.
+            mSession.setRepeatingRequest(/*request*/null, /*listener*/null, mHandler);
+            mCollector.addMessage("Session setRepeatingRequest should throw " +
+                    "IllegalArgumentException for null request");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+
+        try {
+            // Test: CameraCaptureSession setRepeatingRequest should throw IAE for for request
+            // without surface configured.
+            mSession.setRepeatingRequest(unConfiguredRequest, /*listener*/null, mHandler);
+            mCollector.addMessage("Capture zero burst should throw IllegalArgumentException " +
+                    "for request without surface configured");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+
+        try {
+            // Test: CameraCaptureSession captureBurst should throw IAE for null request list.
+            mSession.captureBurst(/*requests*/null, /*listener*/null, mHandler);
+            mCollector.addMessage("Session captureBurst should throw " +
+                    "IllegalArgumentException for null request list");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+
+        try {
+            // Test: CameraCaptureSession captureBurst should throw IAE for empty request list.
+            mSession.captureBurst(emptyRequests, /*listener*/null, mHandler);
+            mCollector.addMessage("Session captureBurst should throw " +
+                    " IllegalArgumentException for empty request list");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+
+        try {
+            // Test: CameraCaptureSession captureBurst should throw IAE for request
+            // without surface configured.
+            mSession.captureBurst(unConfiguredRequests, /*listener*/null, mHandler);
+            fail("Session captureBurst should throw IllegalArgumentException " +
+                    "for null request list");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+
+        try {
+            // Test: CameraCaptureSession setRepeatingBurst should throw IAE for null request list.
+            mSession.setRepeatingBurst(/*requests*/null, /*listener*/null, mHandler);
+            mCollector.addMessage("Session setRepeatingBurst should throw " +
+                    "IllegalArgumentException for null request list");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+
+        try {
+            // Test: CameraCaptureSession setRepeatingBurst should throw IAE for empty request list.
+            mSession.setRepeatingBurst(emptyRequests, /*listener*/null, mHandler);
+            mCollector.addMessage("Session setRepeatingBurst should throw " +
+                    "IllegalArgumentException for empty request list");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+
+        try {
+            // Test: CameraCaptureSession setRepeatingBurst should throw IAE for request
+            // without surface configured.
+            mSession.setRepeatingBurst(unConfiguredRequests, /*listener*/null, mHandler);
+            mCollector.addMessage("Session setRepeatingBurst should throw " +
+                    "IllegalArgumentException for request without surface configured");
+        } catch (IllegalArgumentException e) {
+            // Pass.
+        }
+    }
+
+    private class IsCaptureResultNotEmpty
+            extends ArgumentMatcher<TotalCaptureResult> {
+        @Override
+        public boolean matches(Object obj) {
+            /**
+             * Do the simple verification here. Only verify the timestamp for now.
+             * TODO: verify more required capture result metadata fields.
+             */
+            TotalCaptureResult result = (TotalCaptureResult) obj;
+            Long timeStamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
+            if (timeStamp != null && timeStamp.longValue() > 0L) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Run capture test with different test configurations.
+     *
+     * @param burst If the test uses {@link CameraCaptureSession#captureBurst} or
+     * {@link CameraCaptureSession#setRepeatingBurst} to capture the burst.
+     * @param repeating If the test uses {@link CameraCaptureSession#setRepeatingBurst} or
+     * {@link CameraCaptureSession#setRepeatingRequest} for repeating capture.
+     * @param abort If the test uses {@link CameraCaptureSession#abortCaptures} to stop the
+     * repeating capture.  It has no effect if repeating is false.
+     */
+    private void runCaptureTest(boolean burst, boolean repeating, boolean abort) throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i], mCameraMockListener);
+                waitForDeviceState(STATE_OPENED, CAMERA_OPEN_TIMEOUT_MS);
+
+                prepareCapture();
+
+                if (!burst) {
+                    // Test: that a single capture of each template type succeeds.
+                    for (int j = 0; j < sTemplates.length; j++) {
+                        // Skip video snapshots for LEGACY mode
+                        if (mStaticInfo.isHardwareLevelLegacy() &&
+                                sTemplates[j] == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) {
+                            continue;
+                        }
+                        // Skip non-PREVIEW templates for non-color output
+                        if (!mStaticInfo.isColorOutputSupported() &&
+                                sTemplates[j] != CameraDevice.TEMPLATE_PREVIEW) {
+                            continue;
+                        }
+                        captureSingleShot(mCameraIds[i], sTemplates[j], repeating, abort);
+                    }
+                }
+                else {
+                    // Test: burst of one shot
+                    captureBurstShot(mCameraIds[i], sTemplates, 1, repeating, abort);
+
+                    int template = mStaticInfo.isColorOutputSupported() ?
+                        CameraDevice.TEMPLATE_STILL_CAPTURE :
+                        CameraDevice.TEMPLATE_PREVIEW;
+                    int[] templates = new int[] {
+                        template,
+                        template,
+                        template,
+                        template,
+                        template
+                    };
+
+                    // Test: burst of 5 shots of the same template type
+                    captureBurstShot(mCameraIds[i], templates, templates.length, repeating, abort);
+
+                    // Test: burst of 5 shots of different template types
+                    captureBurstShot(
+                            mCameraIds[i], sTemplates, sTemplates.length, repeating, abort);
+                }
+                verify(mCameraMockListener, never())
+                        .onError(
+                                any(CameraDevice.class),
+                                anyInt());
+            } catch (Exception e) {
+                mCollector.addError(e);
+            } finally {
+                try {
+                    closeSession();
+                } catch (Exception e) {
+                    mCollector.addError(e);
+                }finally {
+                    closeDevice(mCameraIds[i], mCameraMockListener);
+                }
+            }
+        }
+    }
+
+    private void captureSingleShot(
+            String id,
+            int template,
+            boolean repeating, boolean abort) throws Exception {
+
+        assertEquals("Bad initial state for preparing to capture",
+                mLatestSessionState, SESSION_READY);
+
+        CaptureRequest.Builder requestBuilder = mCamera.createCaptureRequest(template);
+        assertNotNull("Failed to create capture request", requestBuilder);
+        requestBuilder.addTarget(mReaderSurface);
+        CameraCaptureSession.CaptureCallback mockCaptureCallback =
+                mock(CameraCaptureSession.CaptureCallback.class);
+
+        if (VERBOSE) {
+            Log.v(TAG, String.format("Capturing shot for device %s, template %d",
+                    id, template));
+        }
+
+        startCapture(requestBuilder.build(), repeating, mockCaptureCallback, mHandler);
+        waitForSessionState(SESSION_ACTIVE, SESSION_ACTIVE_TIMEOUT_MS);
+
+        int expectedCaptureResultCount = repeating ? REPEATING_CAPTURE_EXPECTED_RESULT_COUNT : 1;
+        verifyCaptureResults(mockCaptureCallback, expectedCaptureResultCount);
+
+        if (repeating) {
+            if (abort) {
+                mSession.abortCaptures();
+            } else {
+                mSession.stopRepeating();
+            }
+        }
+        waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
+    }
+
+    private void captureBurstShot(
+            String id,
+            int[] templates,
+            int len,
+            boolean repeating,
+            boolean abort) throws Exception {
+
+        assertEquals("Bad initial state for preparing to capture",
+                mLatestSessionState, SESSION_READY);
+
+        assertTrue("Invalid args to capture function", len <= templates.length);
+        List<CaptureRequest> requests = new ArrayList<CaptureRequest>();
+        for (int i = 0; i < len; i++) {
+            // Skip video snapshots for LEGACY mode
+            if (mStaticInfo.isHardwareLevelLegacy() &&
+                    templates[i] == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) {
+                continue;
+            }
+            // Skip non-PREVIEW templates for non-color outpu
+            if (!mStaticInfo.isColorOutputSupported() &&
+                    templates[i] != CameraDevice.TEMPLATE_PREVIEW) {
+                continue;
+            }
+            CaptureRequest.Builder requestBuilder = mCamera.createCaptureRequest(templates[i]);
+            assertNotNull("Failed to create capture request", requestBuilder);
+            requestBuilder.addTarget(mReaderSurface);
+            requests.add(requestBuilder.build());
+        }
+        CameraCaptureSession.CaptureCallback mockCaptureCallback =
+                mock(CameraCaptureSession.CaptureCallback.class);
+
+        if (VERBOSE) {
+            Log.v(TAG, String.format("Capturing burst shot for device %s", id));
+        }
+
+        if (!repeating) {
+            mSession.captureBurst(requests, mockCaptureCallback, mHandler);
+        }
+        else {
+            mSession.setRepeatingBurst(requests, mockCaptureCallback, mHandler);
+        }
+        waitForSessionState(SESSION_ACTIVE, SESSION_READY_TIMEOUT_MS);
+
+        int expectedResultCount = requests.size();
+        if (repeating) {
+            expectedResultCount *= REPEATING_CAPTURE_EXPECTED_RESULT_COUNT;
+        }
+
+        verifyCaptureResults(mockCaptureCallback, expectedResultCount);
+
+        if (repeating) {
+            if (abort) {
+                mSession.abortCaptures();
+            } else {
+                mSession.stopRepeating();
+            }
+        }
+        waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
+    }
+
+    /**
+     * Precondition: Device must be in known OPENED state (has been waited for).
+     *
+     * <p>Creates a new capture session and waits until it is in the {@code SESSION_READY} state.
+     * </p>
+     *
+     * <p>Any existing capture session will be closed as a result of calling this.</p>
+     * */
+    private void prepareCapture() throws Exception {
+        if (VERBOSE) Log.v(TAG, "prepareCapture");
+
+        assertTrue("Bad initial state for preparing to capture",
+                mLatestDeviceState == STATE_OPENED);
+
+        if (mSession != null) {
+            if (VERBOSE) Log.v(TAG, "prepareCapture - closing existing session");
+            closeSession();
+        }
+
+        // Create a new session listener each time, it's not reusable across cameras
+        mSessionMockListener = spy(new BlockingSessionCallback());
+        mSessionWaiter = mSessionMockListener.getStateWaiter();
+
+        if (!mStaticInfo.isColorOutputSupported()) {
+            createDefaultImageReader(getMaxDepthSize(mCamera.getId(), mCameraManager),
+                    ImageFormat.DEPTH16, MAX_NUM_IMAGES, new ImageDropperListener());
+        }
+
+        List<Surface> outputSurfaces = new ArrayList<>(Arrays.asList(mReaderSurface));
+        mCamera.createCaptureSession(outputSurfaces, mSessionMockListener, mHandler);
+
+        mSession = mSessionMockListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+        waitForSessionState(SESSION_CONFIGURED, SESSION_CONFIGURE_TIMEOUT_MS);
+        waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
+    }
+
+    private void waitForDeviceState(int state, long timeoutMs) {
+        mCameraMockListener.waitForState(state, timeoutMs);
+        mLatestDeviceState = state;
+    }
+
+    private void waitForSessionState(int state, long timeoutMs) {
+        mSessionWaiter.waitForState(state, timeoutMs);
+        mLatestSessionState = state;
+    }
+
+    private void verifyCaptureResults(
+            CameraCaptureSession.CaptureCallback mockListener,
+            int expectResultCount) {
+        final int TIMEOUT_PER_RESULT_MS = 2000;
+        // Should receive expected number of capture results.
+        verify(mockListener,
+                timeout(TIMEOUT_PER_RESULT_MS * expectResultCount).atLeast(expectResultCount))
+                        .onCaptureCompleted(
+                                eq(mSession),
+                                isA(CaptureRequest.class),
+                                argThat(new IsCaptureResultNotEmpty()));
+        // Should not receive any capture failed callbacks.
+        verify(mockListener, never())
+                        .onCaptureFailed(
+                                eq(mSession),
+                                isA(CaptureRequest.class),
+                                isA(CaptureFailure.class));
+        // Should receive expected number of capture shutter calls
+        verify(mockListener,
+                atLeast(expectResultCount))
+                        .onCaptureStarted(
+                               eq(mSession),
+                               isA(CaptureRequest.class),
+                               anyLong(),
+                               anyLong());
+    }
+
+    private void checkFpsRange(CaptureRequest.Builder request, int template,
+            CameraCharacteristics props) {
+        CaptureRequest.Key<Range<Integer>> fpsRangeKey = CONTROL_AE_TARGET_FPS_RANGE;
+        Range<Integer> fpsRange;
+        if ((fpsRange = mCollector.expectKeyValueNotNull(request, fpsRangeKey)) == null) {
+            return;
+        }
+
+        int minFps = fpsRange.getLower();
+        int maxFps = fpsRange.getUpper();
+        Range<Integer>[] availableFpsRange = props
+                .get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
+        boolean foundRange = false;
+        for (int i = 0; i < availableFpsRange.length; i += 1) {
+            if (minFps == availableFpsRange[i].getLower()
+                    && maxFps == availableFpsRange[i].getUpper()) {
+                foundRange = true;
+                break;
+            }
+        }
+        if (!foundRange) {
+            mCollector.addMessage(String.format("Unable to find the fps range (%d, %d)",
+                    minFps, maxFps));
+            return;
+        }
+
+
+        if (template != CameraDevice.TEMPLATE_MANUAL &&
+                template != CameraDevice.TEMPLATE_STILL_CAPTURE) {
+            if (maxFps < MIN_FPS_REQUIRED_FOR_STREAMING) {
+                mCollector.addMessage("Max fps should be at least "
+                        + MIN_FPS_REQUIRED_FOR_STREAMING);
+                return;
+            }
+
+            // Relax framerate constraints on legacy mode
+            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                // Need give fixed frame rate for video recording template.
+                if (template == CameraDevice.TEMPLATE_RECORD) {
+                    if (maxFps != minFps) {
+                        mCollector.addMessage("Video recording frame rate should be fixed");
+                    }
+                }
+            }
+        }
+    }
+
+    private void checkAfMode(CaptureRequest.Builder request, int template,
+            CameraCharacteristics props) {
+        boolean hasFocuser = props.getKeys().contains(CameraCharacteristics.
+                LENS_INFO_MINIMUM_FOCUS_DISTANCE) &&
+                (props.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE) > 0f);
+
+        if (!hasFocuser) {
+            return;
+        }
+
+        int targetAfMode = CaptureRequest.CONTROL_AF_MODE_AUTO;
+        int[] availableAfMode = props.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
+        if (template == CameraDevice.TEMPLATE_PREVIEW ||
+                template == CameraDevice.TEMPLATE_STILL_CAPTURE ||
+                template == CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG) {
+            // Default to CONTINUOUS_PICTURE if it is available, otherwise AUTO.
+            for (int i = 0; i < availableAfMode.length; i++) {
+                if (availableAfMode[i] == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE) {
+                    targetAfMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
+                    break;
+                }
+            }
+        } else if (template == CameraDevice.TEMPLATE_RECORD ||
+                template == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) {
+            // Default to CONTINUOUS_VIDEO if it is available, otherwise AUTO.
+            for (int i = 0; i < availableAfMode.length; i++) {
+                if (availableAfMode[i] == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO) {
+                    targetAfMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO;
+                    break;
+                }
+            }
+        } else if (template == CameraDevice.TEMPLATE_MANUAL) {
+            targetAfMode = CaptureRequest.CONTROL_AF_MODE_OFF;
+        }
+
+        mCollector.expectKeyValueEquals(request, CONTROL_AF_MODE, targetAfMode);
+        if (mStaticInfo.areKeysAvailable(CaptureRequest.LENS_FOCUS_DISTANCE)) {
+            mCollector.expectKeyValueNotNull(request, LENS_FOCUS_DISTANCE);
+        }
+    }
+
+    private void checkAntiBandingMode(CaptureRequest.Builder request, int template) {
+        if (template == CameraDevice.TEMPLATE_MANUAL) {
+            return;
+        }
+
+        if (!mStaticInfo.isColorOutputSupported()) return;
+
+        List<Integer> availableAntiBandingModes =
+                Arrays.asList(toObject(mStaticInfo.getAeAvailableAntiBandingModesChecked()));
+
+        if (availableAntiBandingModes.contains(CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO)) {
+            mCollector.expectKeyValueEquals(request, CONTROL_AE_ANTIBANDING_MODE,
+                    CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO);
+        } else {
+            mCollector.expectKeyValueIsIn(request, CONTROL_AE_ANTIBANDING_MODE,
+                    CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_50HZ,
+                    CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_60HZ);
+        }
+    }
+
+    /**
+     * <p>Check if 3A metering settings are "up to HAL" in request template</p>
+     *
+     * <p>This function doesn't fail the test immediately, it updates the
+     * test pass/fail status and appends the failure message to the error collector each key.</p>
+     *
+     * @param regions The metering rectangles to be checked
+     */
+    private void checkMeteringRect(MeteringRectangle[] regions) {
+        if (regions == null) {
+            return;
+        }
+        mCollector.expectNotEquals("Number of metering region should not be 0", 0, regions.length);
+        for (int i = 0; i < regions.length; i++) {
+            mCollector.expectEquals("Default metering regions should have all zero weight",
+                    0, regions[i].getMeteringWeight());
+        }
+    }
+
+    /**
+     * <p>Check if the request settings are suitable for a given request template.</p>
+     *
+     * <p>This function doesn't fail the test immediately, it updates the
+     * test pass/fail status and appends the failure message to the error collector each key.</p>
+     *
+     * @param request The request to be checked.
+     * @param template The capture template targeted by this request.
+     * @param props The CameraCharacteristics this request is checked against with.
+     */
+    private void checkRequestForTemplate(CaptureRequest.Builder request, int template,
+            CameraCharacteristics props) {
+        // 3A settings--control.mode.
+        if (template != CameraDevice.TEMPLATE_MANUAL) {
+            mCollector.expectKeyValueEquals(request, CONTROL_MODE,
+                    CaptureRequest.CONTROL_MODE_AUTO);
+        }
+
+        // 3A settings--AE/AWB/AF.
+        Integer maxRegionsAeVal = props.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AE);
+        int maxRegionsAe = maxRegionsAeVal != null ? maxRegionsAeVal : 0;
+        Integer maxRegionsAwbVal = props.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB);
+        int maxRegionsAwb = maxRegionsAwbVal != null ? maxRegionsAwbVal : 0;
+        Integer maxRegionsAfVal = props.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF);
+        int maxRegionsAf = maxRegionsAfVal != null ? maxRegionsAfVal : 0;
+
+        checkFpsRange(request, template, props);
+
+        checkAfMode(request, template, props);
+        checkAntiBandingMode(request, template);
+
+        if (template == CameraDevice.TEMPLATE_MANUAL) {
+            mCollector.expectKeyValueEquals(request, CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
+            mCollector.expectKeyValueEquals(request, CONTROL_AE_MODE,
+                    CaptureRequest.CONTROL_AE_MODE_OFF);
+            mCollector.expectKeyValueEquals(request, CONTROL_AWB_MODE,
+                    CaptureRequest.CONTROL_AWB_MODE_OFF);
+        } else {
+            if (mStaticInfo.isColorOutputSupported()) {
+                mCollector.expectKeyValueEquals(request, CONTROL_AE_MODE,
+                        CaptureRequest.CONTROL_AE_MODE_ON);
+                mCollector.expectKeyValueEquals(request, CONTROL_AE_EXPOSURE_COMPENSATION, 0);
+                mCollector.expectKeyValueEquals(request, CONTROL_AE_PRECAPTURE_TRIGGER,
+                        CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
+                // if AE lock is not supported, expect the control key to be non-exist or false
+                if (mStaticInfo.isAeLockSupported() || request.get(CONTROL_AE_LOCK) != null) {
+                    mCollector.expectKeyValueEquals(request, CONTROL_AE_LOCK, false);
+                }
+
+                mCollector.expectKeyValueEquals(request, CONTROL_AF_TRIGGER,
+                        CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
+
+                mCollector.expectKeyValueEquals(request, CONTROL_AWB_MODE,
+                        CaptureRequest.CONTROL_AWB_MODE_AUTO);
+                // if AWB lock is not supported, expect the control key to be non-exist or false
+                if (mStaticInfo.isAwbLockSupported() || request.get(CONTROL_AWB_LOCK) != null) {
+                    mCollector.expectKeyValueEquals(request, CONTROL_AWB_LOCK, false);
+                }
+
+                // Check 3A regions.
+                if (VERBOSE) {
+                    Log.v(TAG, String.format("maxRegions is: {AE: %s, AWB: %s, AF: %s}",
+                                    maxRegionsAe, maxRegionsAwb, maxRegionsAf));
+                }
+                if (maxRegionsAe > 0) {
+                    mCollector.expectKeyValueNotNull(request, CONTROL_AE_REGIONS);
+                    MeteringRectangle[] aeRegions = request.get(CONTROL_AE_REGIONS);
+                    checkMeteringRect(aeRegions);
+                }
+                if (maxRegionsAwb > 0) {
+                    mCollector.expectKeyValueNotNull(request, CONTROL_AWB_REGIONS);
+                    MeteringRectangle[] awbRegions = request.get(CONTROL_AWB_REGIONS);
+                    checkMeteringRect(awbRegions);
+                }
+                if (maxRegionsAf > 0) {
+                    mCollector.expectKeyValueNotNull(request, CONTROL_AF_REGIONS);
+                    MeteringRectangle[] afRegions = request.get(CONTROL_AF_REGIONS);
+                    checkMeteringRect(afRegions);
+                }
+            }
+        }
+
+        // Sensor settings.
+
+        mCollector.expectEquals("Lens aperture must be present in request if available apertures " +
+                        "are present in metadata, and vice-versa.",
+                mStaticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES),
+                mStaticInfo.areKeysAvailable(CaptureRequest.LENS_APERTURE));
+        if (mStaticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES)) {
+            float[] availableApertures =
+                    props.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES);
+            if (availableApertures.length > 1) {
+                mCollector.expectKeyValueNotNull(request, LENS_APERTURE);
+            }
+        }
+
+        mCollector.expectEquals("Lens filter density must be present in request if available " +
+                        "filter densities are present in metadata, and vice-versa.",
+                mStaticInfo.areKeysAvailable(CameraCharacteristics.
+                        LENS_INFO_AVAILABLE_FILTER_DENSITIES),
+                mStaticInfo.areKeysAvailable(CaptureRequest.LENS_FILTER_DENSITY));
+        if (mStaticInfo.areKeysAvailable(CameraCharacteristics.
+                LENS_INFO_AVAILABLE_FILTER_DENSITIES)) {
+            float[] availableFilters =
+                    props.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FILTER_DENSITIES);
+            if (availableFilters.length > 1) {
+                mCollector.expectKeyValueNotNull(request, LENS_FILTER_DENSITY);
+            }
+        }
+
+        float[] availableFocalLen =
+                props.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
+        if (availableFocalLen.length > 1) {
+            mCollector.expectKeyValueNotNull(request, LENS_FOCAL_LENGTH);
+        }
+
+        mCollector.expectEquals("Lens optical stabilization must be present in request if " +
+                        "available optical stabilizations are present in metadata, and vice-versa.",
+                mStaticInfo.areKeysAvailable(CameraCharacteristics.
+                        LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION),
+                mStaticInfo.areKeysAvailable(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE));
+        if (mStaticInfo.areKeysAvailable(CameraCharacteristics.
+                LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION)) {
+            int[] availableOIS =
+                    props.get(CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION);
+            if (availableOIS.length > 1) {
+                mCollector.expectKeyValueNotNull(request, LENS_OPTICAL_STABILIZATION_MODE);
+            }
+        }
+
+        if (mStaticInfo.areKeysAvailable(BLACK_LEVEL_LOCK)) {
+            mCollector.expectKeyValueEquals(request, BLACK_LEVEL_LOCK, false);
+        }
+
+        if (mStaticInfo.areKeysAvailable(SENSOR_FRAME_DURATION)) {
+            mCollector.expectKeyValueNotNull(request, SENSOR_FRAME_DURATION);
+        }
+
+        if (mStaticInfo.areKeysAvailable(SENSOR_EXPOSURE_TIME)) {
+            mCollector.expectKeyValueNotNull(request, SENSOR_EXPOSURE_TIME);
+        }
+
+        if (mStaticInfo.areKeysAvailable(SENSOR_SENSITIVITY)) {
+            mCollector.expectKeyValueNotNull(request, SENSOR_SENSITIVITY);
+        }
+
+        // ISP-processing settings.
+        if (mStaticInfo.isColorOutputSupported()) {
+            mCollector.expectKeyValueEquals(
+                    request, STATISTICS_FACE_DETECT_MODE,
+                    CaptureRequest.STATISTICS_FACE_DETECT_MODE_OFF);
+            mCollector.expectKeyValueEquals(request, FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
+        }
+
+        List<Integer> availableCaps = mStaticInfo.getAvailableCapabilitiesChecked();
+        if (mStaticInfo.areKeysAvailable(STATISTICS_LENS_SHADING_MAP_MODE)) {
+            // If the device doesn't support RAW, all template should have OFF as default.
+            if (!availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                mCollector.expectKeyValueEquals(
+                        request, STATISTICS_LENS_SHADING_MAP_MODE,
+                        CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE_OFF);
+            }
+        }
+
+        // Edge enhancement and noise reduction modes
+        boolean supportReprocessing =
+                availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING) ||
+                availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);
+
+        if (template == CameraDevice.TEMPLATE_STILL_CAPTURE) {
+            // Not enforce high quality here, as some devices may not effectively have high quality
+            // mode.
+            if (mStaticInfo.areKeysAvailable(COLOR_CORRECTION_MODE)) {
+                mCollector.expectKeyValueNotEquals(
+                        request, COLOR_CORRECTION_MODE,
+                        CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
+            }
+
+            mCollector.expectEquals("Edge mode must be present in request if " +
+                            "available edge modes are present in metadata, and vice-versa.",
+                    mStaticInfo.areKeysAvailable(CameraCharacteristics.
+                            EDGE_AVAILABLE_EDGE_MODES),
+                    mStaticInfo.areKeysAvailable(CaptureRequest.EDGE_MODE));
+            if (mStaticInfo.areKeysAvailable(EDGE_MODE)) {
+                List<Integer> availableEdgeModes =
+                        Arrays.asList(toObject(mStaticInfo.getAvailableEdgeModesChecked()));
+                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);
+                }
+            }
+
+            mCollector.expectEquals("Noise reduction mode must be present in request if " +
+                            "available noise reductions are present in metadata, and vice-versa.",
+                    mStaticInfo.areKeysAvailable(CameraCharacteristics.
+                            NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES),
+                    mStaticInfo.areKeysAvailable(CaptureRequest.NOISE_REDUCTION_MODE));
+            if (mStaticInfo.areKeysAvailable(
+                    CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES)) {
+                List<Integer> availableNoiseReductionModes =
+                        Arrays.asList(toObject(mStaticInfo.getAvailableNoiseReductionModesChecked()));
+                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);
+                }
+            }
+        } 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 (mStaticInfo.areKeysAvailable(EDGE_MODE)) {
+                mCollector.expectKeyValueNotNull(request, EDGE_MODE);
+            }
+
+            if (mStaticInfo.areKeysAvailable(NOISE_REDUCTION_MODE)) {
+                mCollector.expectKeyValueNotNull(request, NOISE_REDUCTION_MODE);
+            }
+        }
+
+        // Tone map and lens shading modes.
+        if (template == CameraDevice.TEMPLATE_STILL_CAPTURE) {
+            mCollector.expectEquals("Tonemap mode must be present in request if " +
+                            "available tonemap modes are present in metadata, and vice-versa.",
+                    mStaticInfo.areKeysAvailable(CameraCharacteristics.
+                            TONEMAP_AVAILABLE_TONE_MAP_MODES),
+                    mStaticInfo.areKeysAvailable(CaptureRequest.TONEMAP_MODE));
+            if (mStaticInfo.areKeysAvailable(
+                    CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES)) {
+                List<Integer> availableToneMapModes =
+                        Arrays.asList(toObject(mStaticInfo.getAvailableToneMapModesChecked()));
+                if (availableToneMapModes.contains(CaptureRequest.TONEMAP_MODE_HIGH_QUALITY)) {
+                    mCollector.expectKeyValueEquals(request, TONEMAP_MODE,
+                            CaptureRequest.TONEMAP_MODE_HIGH_QUALITY);
+                } else {
+                    mCollector.expectKeyValueEquals(request, TONEMAP_MODE,
+                            CaptureRequest.TONEMAP_MODE_FAST);
+                }
+            }
+
+            // Still capture template should have android.statistics.lensShadingMapMode ON when
+            // RAW capability is supported.
+            if (mStaticInfo.areKeysAvailable(STATISTICS_LENS_SHADING_MAP_MODE) &&
+                    availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                    mCollector.expectKeyValueEquals(request, STATISTICS_LENS_SHADING_MAP_MODE,
+                            STATISTICS_LENS_SHADING_MAP_MODE_ON);
+            }
+        } else {
+            if (mStaticInfo.areKeysAvailable(TONEMAP_MODE)) {
+                mCollector.expectKeyValueNotEquals(request, TONEMAP_MODE,
+                        CaptureRequest.TONEMAP_MODE_CONTRAST_CURVE);
+                mCollector.expectKeyValueNotEquals(request, TONEMAP_MODE,
+                        CaptureRequest.TONEMAP_MODE_GAMMA_VALUE);
+                mCollector.expectKeyValueNotEquals(request, TONEMAP_MODE,
+                        CaptureRequest.TONEMAP_MODE_PRESET_CURVE);
+            }
+            if (mStaticInfo.areKeysAvailable(STATISTICS_LENS_SHADING_MAP_MODE)) {
+                mCollector.expectKeyValueNotNull(request, STATISTICS_LENS_SHADING_MAP_MODE);
+            }
+        }
+
+        mCollector.expectKeyValueEquals(request, CONTROL_CAPTURE_INTENT, template);
+
+        // TODO: use the list of keys from CameraCharacteristics to avoid expecting
+        //       keys which are not available by this CameraDevice.
+    }
+
+    private void captureTemplateTestByCamera(String cameraId, int template) throws Exception {
+        try {
+            openDevice(cameraId, mCameraMockListener);
+
+            assertTrue("Camera template " + template + " is out of range!",
+                    template >= CameraDevice.TEMPLATE_PREVIEW
+                            && template <= CameraDevice.TEMPLATE_MANUAL);
+
+            mCollector.setCameraId(cameraId);
+
+            try {
+                CaptureRequest.Builder request = mCamera.createCaptureRequest(template);
+                assertNotNull("Failed to create capture request for template " + template, request);
+
+                CameraCharacteristics props = mStaticInfo.getCharacteristics();
+                checkRequestForTemplate(request, template, props);
+            } catch (IllegalArgumentException e) {
+                if (template == CameraDevice.TEMPLATE_MANUAL &&
+                        !mStaticInfo.isCapabilitySupported(CameraCharacteristics.
+                                REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                    // OK
+                } else if (template == CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG &&
+                        !mStaticInfo.isCapabilitySupported(CameraCharacteristics.
+                                REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING)) {
+                    // OK.
+                } else if (sLegacySkipTemplates.contains(template) &&
+                        mStaticInfo.isHardwareLevelLegacy()) {
+                    // OK
+                } else if (template != CameraDevice.TEMPLATE_PREVIEW &&
+                        mStaticInfo.isDepthOutputSupported() &&
+                        !mStaticInfo.isColorOutputSupported()) {
+                    // OK, depth-only devices need only support PREVIEW template
+                } else {
+                    throw e; // rethrow
+                }
+            }
+        }
+        finally {
+            try {
+                closeSession();
+            } finally {
+                closeDevice(cameraId, mCameraMockListener);
+            }
+        }
+    }
+
+    /**
+     * Start capture with given {@link #CaptureRequest}.
+     *
+     * @param request The {@link #CaptureRequest} to be captured.
+     * @param repeating If the capture is single capture or repeating.
+     * @param listener The {@link #CaptureCallback} camera device used to notify callbacks.
+     * @param handler The handler camera device used to post callbacks.
+     */
+    protected void startCapture(CaptureRequest request, boolean repeating,
+            CameraCaptureSession.CaptureCallback listener, Handler handler)
+                    throws CameraAccessException {
+        if (VERBOSE) Log.v(TAG, "Starting capture from session");
+
+        if (repeating) {
+            mSession.setRepeatingRequest(request, listener, handler);
+        } else {
+            mSession.capture(request, listener, handler);
+        }
+    }
+
+    /**
+     * Close a {@link #CameraCaptureSession capture session}; blocking until
+     * the close finishes with a transition to {@link CameraCaptureSession.StateCallback#onClosed}.
+     */
+    protected void closeSession() {
+        if (mSession == null) {
+            return;
+        }
+
+        mSession.close();
+        waitForSessionState(SESSION_CLOSED, SESSION_CLOSE_TIMEOUT_MS);
+        mSession = null;
+
+        mSessionMockListener = null;
+        mSessionWaiter = null;
+    }
+
+    /**
+     * A camera capture session listener that keeps all the configured and closed sessions.
+     */
+    private class MultipleSessionCallback extends CameraCaptureSession.StateCallback {
+        public static final int SESSION_CONFIGURED = 0;
+        public static final int SESSION_CLOSED = 1;
+
+        final List<CameraCaptureSession> mSessions = new ArrayList<>();
+        final Map<CameraCaptureSession, Integer> mSessionStates = new HashMap<>();
+        CameraCaptureSession mCurrentConfiguredSession = null;
+
+        final ReentrantLock mLock = new ReentrantLock();
+        final Condition mNewStateCond = mLock.newCondition();
+
+        final boolean mFailOnConfigureFailed;
+
+        /**
+         * If failOnConfigureFailed is true, it calls fail() when onConfigureFailed() is invoked
+         * for any session.
+         */
+        public MultipleSessionCallback(boolean failOnConfigureFailed) {
+            mFailOnConfigureFailed = failOnConfigureFailed;
+        }
+
+        @Override
+        public void onClosed(CameraCaptureSession session) {
+            mLock.lock();
+            mSessionStates.put(session, SESSION_CLOSED);
+            mNewStateCond.signal();
+            mLock.unlock();
+        }
+
+        @Override
+        public void onConfigured(CameraCaptureSession session) {
+            mLock.lock();
+            mSessions.add(session);
+            mSessionStates.put(session, SESSION_CONFIGURED);
+            mNewStateCond.signal();
+            mLock.unlock();
+        }
+
+        @Override
+        public void onConfigureFailed(CameraCaptureSession session) {
+            if (mFailOnConfigureFailed) {
+                fail("Configuring a session failed");
+            }
+        }
+
+        /**
+         * Get a number of sessions that have been configured.
+         */
+        public List<CameraCaptureSession> getAllSessions(int numSessions, int timeoutMs)
+                throws Exception {
+            long remainingTime = timeoutMs;
+            mLock.lock();
+            try {
+                while (mSessions.size() < numSessions) {
+                    long startTime = SystemClock.elapsedRealtime();
+                    boolean ret = mNewStateCond.await(remainingTime, TimeUnit.MILLISECONDS);
+                    remainingTime -= (SystemClock.elapsedRealtime() - startTime);
+                    ret &= remainingTime > 0;
+
+                    assertTrue("Get " + numSessions + " sessions timed out after " + timeoutMs +
+                            "ms", ret);
+                }
+
+                return mSessions;
+            } finally {
+                mLock.unlock();
+            }
+        }
+
+        /**
+         * Wait until a previously-configured sessoin is closed or it times out.
+         */
+        public void waitForSessionClose(CameraCaptureSession session, int timeoutMs) throws Exception {
+            long remainingTime = timeoutMs;
+            mLock.lock();
+            try {
+                while (mSessionStates.get(session).equals(SESSION_CLOSED) == false) {
+                    long startTime = SystemClock.elapsedRealtime();
+                    boolean ret = mNewStateCond.await(remainingTime, TimeUnit.MILLISECONDS);
+                    remainingTime -= (SystemClock.elapsedRealtime() - startTime);
+                    ret &= remainingTime > 0;
+
+                    assertTrue("Wait for session close timed out after " + timeoutMs + "ms", ret);
+                }
+            } finally {
+                mLock.unlock();
+            }
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
new file mode 100644
index 0000000..67c08fe
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraManagerTest.java
@@ -0,0 +1,604 @@
+/*
+ * 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 android.hardware.camera2.cts;
+
+import static org.mockito.Mockito.*;
+import static org.mockito.AdditionalMatchers.not;
+import static org.mockito.AdditionalMatchers.and;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraDevice.StateCallback;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.cts.CameraTestUtils.MockStateCallback;
+import android.hardware.camera2.cts.helpers.CameraErrorCollector;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import com.android.ex.camera2.blocking.BlockingStateCallback;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * <p>Basic test for CameraManager class.</p>
+ */
+public class CameraManagerTest extends AndroidTestCase {
+    private static final String TAG = "CameraManagerTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final int NUM_CAMERA_REOPENS = 10;
+
+    private PackageManager mPackageManager;
+    private CameraManager mCameraManager;
+    private NoopCameraListener mListener;
+    private HandlerThread mHandlerThread;
+    private Handler mHandler;
+    private BlockingStateCallback mCameraListener;
+    private CameraErrorCollector mCollector;
+
+    @Override
+    public void setContext(Context context) {
+        super.setContext(context);
+        mCameraManager = (CameraManager)context.getSystemService(Context.CAMERA_SERVICE);
+        assertNotNull("Can't connect to camera manager", mCameraManager);
+        mPackageManager = context.getPackageManager();
+        assertNotNull("Can't get package manager", mPackageManager);
+        mListener = new NoopCameraListener();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        /**
+         * Workaround for mockito and JB-MR2 incompatibility
+         *
+         * Avoid java.lang.IllegalArgumentException: dexcache == null
+         * https://code.google.com/p/dexmaker/issues/detail?id=2
+         */
+        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
+
+        mCameraListener = spy(new BlockingStateCallback());
+
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mCollector = new CameraErrorCollector();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mHandlerThread.quitSafely();
+        mHandler = null;
+
+        try {
+            mCollector.verify();
+        } catch (Throwable e) {
+            // When new Exception(e) is used, exception info will be printed twice.
+            throw new Exception(e.getMessage());
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    /**
+     * Verifies that the reason is in the range of public-only codes.
+     */
+    private static int checkCameraAccessExceptionReason(CameraAccessException e) {
+        int reason = e.getReason();
+
+        switch (reason) {
+            case CameraAccessException.CAMERA_DISABLED:
+            case CameraAccessException.CAMERA_DISCONNECTED:
+            case CameraAccessException.CAMERA_ERROR:
+                return reason;
+        }
+
+        fail("Invalid CameraAccessException code: " + reason);
+
+        return -1; // unreachable
+    }
+
+    public void testCameraManagerGetDeviceIdList() throws Exception {
+
+        // Test: that the getCameraIdList method runs without exceptions.
+        String[] ids = mCameraManager.getCameraIdList();
+        if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(ids));
+
+        /**
+         * Test: that if there is at least one reported id, then the system must have
+         * the FEATURE_CAMERA_ANY feature.
+         */
+        assertTrue("System camera feature and camera id list don't match",
+                ids.length == 0 ||
+                mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY));
+
+        /**
+         * Test: that if the device has front or rear facing cameras, then there
+         * must be matched system features.
+         */
+        for (int i = 0; i < ids.length; i++) {
+            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+            assertNotNull("Can't get camera characteristics for camera " + ids[i], props);
+            Integer lensFacing = props.get(CameraCharacteristics.LENS_FACING);
+            assertNotNull("Can't get lens facing info", lensFacing);
+            if (lensFacing == CameraCharacteristics.LENS_FACING_FRONT) {
+                assertTrue("System doesn't have front camera feature",
+                        mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) ||
+                        mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
+            } else if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
+                assertTrue("System doesn't have back camera feature",
+                        mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA));
+            } else {
+                fail("Unknown camera lens facing " + lensFacing.toString());
+            }
+        }
+
+        /**
+         * Test: that if there is one camera device, then the system must have some
+         * specific features.
+         */
+        assertTrue("Missing system feature: FEATURE_CAMERA_ANY",
+               ids.length == 0
+            || mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY));
+        assertTrue("Missing system feature: FEATURE_CAMERA or FEATURE_CAMERA_FRONT",
+               ids.length == 0
+            || mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
+            || mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT));
+    }
+
+    // Test: that properties can be queried from each device, without exceptions.
+    public void testCameraManagerGetCameraCharacteristics() throws Exception {
+        String[] ids = mCameraManager.getCameraIdList();
+        for (int i = 0; i < ids.length; i++) {
+            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
+            assertNotNull(
+                    String.format("Can't get camera characteristics from: ID %s", ids[i]), props);
+        }
+    }
+
+    // Test: that an exception is thrown if an invalid device id is passed down.
+    public void testCameraManagerInvalidDevice() throws Exception {
+        String[] ids = mCameraManager.getCameraIdList();
+        // Create an invalid id by concatenating all the valid ids together.
+        StringBuilder invalidId = new StringBuilder();
+        invalidId.append("INVALID");
+        for (int i = 0; i < ids.length; i++) {
+            invalidId.append(ids[i]);
+        }
+
+        try {
+            mCameraManager.getCameraCharacteristics(
+                invalidId.toString());
+            fail(String.format("Accepted invalid camera ID: %s", invalidId.toString()));
+        } catch (IllegalArgumentException e) {
+            // This is the exception that should be thrown in this case.
+        }
+    }
+
+    // Test: that each camera device can be opened one at a time, several times.
+    public void testCameraManagerOpenCamerasSerially() throws Exception {
+        String[] ids = mCameraManager.getCameraIdList();
+        for (int i = 0; i < ids.length; i++) {
+            for (int j = 0; j < NUM_CAMERA_REOPENS; j++) {
+                CameraDevice camera = null;
+                try {
+                    MockStateCallback mockListener = MockStateCallback.mock();
+                    mCameraListener = new BlockingStateCallback(mockListener);
+
+                    mCameraManager.openCamera(ids[i], mCameraListener, mHandler);
+
+                    // Block until unConfigured
+                    mCameraListener.waitForState(BlockingStateCallback.STATE_OPENED,
+                            CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+
+                    // Ensure state transitions are in right order:
+                    // -- 1) Opened
+                    // Ensure no other state transitions have occurred:
+                    camera = verifyCameraStateOpened(ids[i], mockListener);
+                } finally {
+                    if (camera != null) {
+                        camera.close();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Test: one or more camera devices can be open at the same time, or the right error state
+     * is set if this can't be done.
+     */
+    public void testCameraManagerOpenAllCameras() throws Exception {
+        String[] ids = mCameraManager.getCameraIdList();
+        assertNotNull("Camera ids shouldn't be null", ids);
+
+        // Skip test if the device doesn't have multiple cameras.
+        if (ids.length <= 1) {
+            return;
+        }
+
+        List<CameraDevice> cameraList = new ArrayList<CameraDevice>();
+        List<MockStateCallback> listenerList = new ArrayList<MockStateCallback>();
+        List<BlockingStateCallback> blockingListenerList = new ArrayList<BlockingStateCallback>();
+        try {
+            for (int i = 0; i < ids.length; i++) {
+                // Ignore state changes from other cameras
+                MockStateCallback mockListener = MockStateCallback.mock();
+                mCameraListener = new BlockingStateCallback(mockListener);
+
+                /**
+                 * Track whether or not we got a synchronous error from openCamera.
+                 *
+                 * A synchronous error must also be accompanied by an asynchronous
+                 * StateCallback#onError callback.
+                 */
+                boolean expectingError = false;
+
+                String cameraId = ids[i];
+                try {
+                    mCameraManager.openCamera(cameraId, mCameraListener,
+                            mHandler);
+                } catch (CameraAccessException e) {
+                    if (checkCameraAccessExceptionReason(e) == CameraAccessException.CAMERA_ERROR) {
+                        expectingError = true;
+                    } else {
+                        // TODO: We should handle a Disabled camera by passing here and elsewhere
+                        fail("Camera must not be disconnected or disabled for this test" + ids[i]);
+                    }
+                }
+
+                List<Integer> expectedStates = new ArrayList<Integer>();
+                expectedStates.add(BlockingStateCallback.STATE_OPENED);
+                expectedStates.add(BlockingStateCallback.STATE_ERROR);
+                int state = mCameraListener.waitForAnyOfStates(
+                        expectedStates, CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+
+                // It's possible that we got an asynchronous error transition only. This is ok.
+                if (expectingError) {
+                    assertEquals("Throwing a CAMERA_ERROR exception must be accompanied with a " +
+                            "StateCallback#onError callback",
+                            BlockingStateCallback.STATE_ERROR, state);
+                }
+
+                /**
+                 * Two situations are considered passing:
+                 * 1) The camera opened successfully.
+                 *     => No error must be set.
+                 * 2) The camera did not open because there were too many other cameras opened.
+                 *     => Only MAX_CAMERAS_IN_USE error must be set.
+                 *
+                 * Any other situation is considered a failure.
+                 *
+                 * For simplicity we treat disconnecting asynchronously as a failure, so
+                 * camera devices should not be physically unplugged during this test.
+                 */
+
+                CameraDevice camera;
+                if (state == BlockingStateCallback.STATE_ERROR) {
+                    // Camera did not open because too many other cameras were opened
+                    // => onError called exactly once with a non-null camera
+                    assertTrue("At least one camera must be opened successfully",
+                            cameraList.size() > 0);
+
+                    ArgumentCaptor<CameraDevice> argument =
+                            ArgumentCaptor.forClass(CameraDevice.class);
+
+                    verify(mockListener)
+                            .onError(
+                                    argument.capture(),
+                                    eq(CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE));
+                    verifyNoMoreInteractions(mockListener);
+
+                    camera = argument.getValue();
+                    assertNotNull("Expected a non-null camera for the error transition for ID: "
+                            + ids[i], camera);
+                } else if (state == BlockingStateCallback.STATE_OPENED) {
+                    // Camera opened successfully.
+                    // => onOpened called exactly once
+                    camera = verifyCameraStateOpened(cameraId,
+                            mockListener);
+                } else {
+                    fail("Unexpected state " + state);
+                    camera = null; // unreachable. but need this for java compiler
+                }
+
+                // Keep track of cameras so we can close it later
+                cameraList.add(camera);
+                listenerList.add(mockListener);
+                blockingListenerList.add(mCameraListener);
+            }
+        } finally {
+            for (CameraDevice camera : cameraList) {
+                camera.close();
+            }
+            for (BlockingStateCallback blockingListener : blockingListenerList) {
+                blockingListener.waitForState(
+                        BlockingStateCallback.STATE_CLOSED,
+                        CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+            }
+        }
+
+        /*
+         * Ensure that no state transitions have bled through from one camera to another
+         * after closing the cameras.
+         */
+        int i = 0;
+        for (MockStateCallback listener : listenerList) {
+            CameraDevice camera = cameraList.get(i);
+
+            verify(listener).onClosed(eq(camera));
+            verifyNoMoreInteractions(listener);
+            i++;
+            // Only a #close can happen on the camera since we were done with it.
+            // Also nothing else should've happened between the close and the open.
+        }
+    }
+
+    /**
+     * Verifies the camera in this listener was opened and then unconfigured exactly once.
+     *
+     * <p>This assumes that no other action to the camera has been done (e.g.
+     * it hasn't been configured, or closed, or disconnected). Verification is
+     * performed immediately without any timeouts.</p>
+     *
+     * <p>This checks that the state has previously changed first for opened and then unconfigured.
+     * Any other state transitions will fail. A test failure is thrown if verification fails.</p>
+     *
+     * @param cameraId Camera identifier
+     * @param listener Listener which was passed to {@link CameraManager#openCamera}
+     *
+     * @return The camera device (non-{@code null}).
+     */
+    private static CameraDevice verifyCameraStateOpened(String cameraId,
+            MockStateCallback listener) {
+        ArgumentCaptor<CameraDevice> argument =
+                ArgumentCaptor.forClass(CameraDevice.class);
+        InOrder inOrder = inOrder(listener);
+
+        /**
+         * State transitions (in that order):
+         *  1) onOpened
+         *
+         * No other transitions must occur for successful #openCamera
+         */
+        inOrder.verify(listener)
+                .onOpened(argument.capture());
+
+        CameraDevice camera = argument.getValue();
+        assertNotNull(
+                String.format("Failed to open camera device ID: %s", cameraId),
+                camera);
+
+        // Do not use inOrder here since that would skip anything called before onOpened
+        verifyNoMoreInteractions(listener);
+
+        return camera;
+    }
+
+    /**
+     * Test: that opening the same device multiple times and make sure the right
+     * error state is set.
+     */
+    public void testCameraManagerOpenCameraTwice() throws Exception {
+        String[] ids = mCameraManager.getCameraIdList();
+
+        // Test across every camera device.
+        for (int i = 0; i < ids.length; ++i) {
+            CameraDevice successCamera = null;
+            mCollector.setCameraId(ids[i]);
+
+            try {
+                MockStateCallback mockSuccessListener = MockStateCallback.mock();
+                MockStateCallback mockFailListener = MockStateCallback.mock();
+
+                BlockingStateCallback successListener =
+                        new BlockingStateCallback(mockSuccessListener);
+                BlockingStateCallback failListener =
+                        new BlockingStateCallback(mockFailListener);
+
+                mCameraManager.openCamera(ids[i], successListener, mHandler);
+                mCameraManager.openCamera(ids[i], failListener,
+                        mHandler);
+
+                successListener.waitForState(BlockingStateCallback.STATE_OPENED,
+                        CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+                ArgumentCaptor<CameraDevice> argument =
+                        ArgumentCaptor.forClass(CameraDevice.class);
+                verify(mockSuccessListener, atLeastOnce()).onOpened(argument.capture());
+                verify(mockSuccessListener, atLeastOnce()).onDisconnected(argument.capture());
+
+                failListener.waitForState(BlockingStateCallback.STATE_OPENED,
+                        CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+                verify(mockFailListener, atLeastOnce()).onOpened(argument.capture());
+
+                successCamera = verifyCameraStateOpened(
+                        ids[i], mockFailListener);
+
+                verifyNoMoreInteractions(mockFailListener);
+            } finally {
+                if (successCamera != null) {
+                    successCamera.close();
+                }
+            }
+        }
+    }
+
+    private class NoopCameraListener extends CameraManager.AvailabilityCallback {
+        @Override
+        public void onCameraAvailable(String cameraId) {
+            // No-op
+        }
+
+        @Override
+        public void onCameraUnavailable(String cameraId) {
+            // No-op
+        }
+    }
+
+    /**
+     * Test: that the APIs to register and unregister a listener run successfully;
+     * doesn't test that the listener actually gets invoked at the right time.
+     * Registering a listener multiple times should have no effect, and unregistering
+     * a listener that isn't registered should have no effect.
+     */
+    public void testCameraManagerListener() throws Exception {
+        mCameraManager.unregisterAvailabilityCallback(mListener);
+        mCameraManager.registerAvailabilityCallback(mListener, mHandler);
+        mCameraManager.registerAvailabilityCallback(mListener, mHandler);
+        mCameraManager.unregisterAvailabilityCallback(mListener);
+        mCameraManager.unregisterAvailabilityCallback(mListener);
+    }
+
+    /**
+     * Test that the availability callbacks fire when expected
+     */
+    public void testCameraManagerListenerCallbacks() throws Exception {
+        final int AVAILABILITY_TIMEOUT_MS = 10;
+
+        final LinkedBlockingQueue<String> availableEventQueue = new LinkedBlockingQueue<>();
+        final LinkedBlockingQueue<String> unavailableEventQueue = new LinkedBlockingQueue<>();
+
+        CameraManager.AvailabilityCallback ac = new CameraManager.AvailabilityCallback() {
+            @Override
+            public void onCameraAvailable(String cameraId) {
+                availableEventQueue.offer(cameraId);
+            }
+
+            @Override
+            public void onCameraUnavailable(String cameraId) {
+                unavailableEventQueue.offer(cameraId);
+            }
+        };
+
+        mCameraManager.registerAvailabilityCallback(ac, mHandler);
+        String[] cameras = mCameraManager.getCameraIdList();
+
+        if (cameras.length == 0) {
+            Log.i(TAG, "No cameras present, skipping test");
+            return;
+        }
+
+        // Verify we received available for all cameras' initial state in a reasonable amount of time
+        HashSet<String> expectedAvailableCameras = new HashSet<String>(Arrays.asList(cameras));
+        while (expectedAvailableCameras.size() > 0) {
+            String id = availableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+                    java.util.concurrent.TimeUnit.MILLISECONDS);
+            assertTrue("Did not receive initial availability notices for some cameras",
+                       id != null);
+            expectedAvailableCameras.remove(id);
+        }
+        // Verify no unavailable cameras were reported
+        assertTrue("Some camera devices are initially unavailable",
+                unavailableEventQueue.size() == 0);
+
+        // Verify transitions for individual cameras
+        for (String id : cameras) {
+            MockStateCallback mockListener = MockStateCallback.mock();
+            mCameraListener = new BlockingStateCallback(mockListener);
+
+            mCameraManager.openCamera(id, mCameraListener, mHandler);
+
+            // Block until opened
+            mCameraListener.waitForState(BlockingStateCallback.STATE_OPENED,
+                    CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+            // Then verify only open happened, and get the camera handle
+            CameraDevice camera = verifyCameraStateOpened(id, mockListener);
+
+            // Verify that we see the expected 'unavailable' event.
+            String candidateId = unavailableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+                    java.util.concurrent.TimeUnit.MILLISECONDS);
+            assertTrue(String.format("Received unavailability notice for wrong ID " +
+                            "(expected %s, got %s)", id, candidateId),
+                    id.equals(candidateId));
+            assertTrue("Availability events received unexpectedly",
+                    availableEventQueue.size() == 0);
+
+            // Verify that we see the expected 'available' event after closing the camera
+
+            camera.close();
+
+            mCameraListener.waitForState(BlockingStateCallback.STATE_CLOSED,
+                    CameraTestUtils.CAMERA_CLOSE_TIMEOUT_MS);
+
+            candidateId = availableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+                    java.util.concurrent.TimeUnit.MILLISECONDS);
+            assertTrue(String.format("Received availability notice for wrong ID " +
+                            "(expected %s, got %s)", id, candidateId),
+                    id.equals(candidateId));
+            assertTrue("Unavailability events received unexpectedly",
+                    unavailableEventQueue.size() == 0);
+
+        }
+
+        // Verify that we can unregister the listener and see no more events
+        assertTrue("Availability events received unexpectedly",
+                availableEventQueue.size() == 0);
+        assertTrue("Unavailability events received unexpectedly",
+                    unavailableEventQueue.size() == 0);
+
+        mCameraManager.unregisterAvailabilityCallback(ac);
+
+        {
+            // Open an arbitrary camera and make sure we don't hear about it
+
+            MockStateCallback mockListener = MockStateCallback.mock();
+            mCameraListener = new BlockingStateCallback(mockListener);
+
+            mCameraManager.openCamera(cameras[0], mCameraListener, mHandler);
+
+            // Block until opened
+            mCameraListener.waitForState(BlockingStateCallback.STATE_OPENED,
+                    CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+            // Then verify only open happened, and close the camera
+            CameraDevice camera = verifyCameraStateOpened(cameras[0], mockListener);
+
+            camera.close();
+
+            mCameraListener.waitForState(BlockingStateCallback.STATE_CLOSED,
+                    CameraTestUtils.CAMERA_CLOSE_TIMEOUT_MS);
+
+            // No unavailability or availability callback should have occured
+            String candidateId = unavailableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+                    java.util.concurrent.TimeUnit.MILLISECONDS);
+            assertTrue(String.format("Received unavailability notice for ID %s unexpectedly ",
+                            candidateId),
+                    candidateId == null);
+
+            candidateId = availableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
+                    java.util.concurrent.TimeUnit.MILLISECONDS);
+            assertTrue(String.format("Received availability notice for ID %s unexpectedly ",
+                            candidateId),
+                    candidateId == null);
+
+
+        }
+
+    } // testCameraManagerListenerCallbacks
+
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
new file mode 100644
index 0000000..d78b3b5
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/CameraTestUtils.java
@@ -0,0 +1,2130 @@
+/*
+ * 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 android.hardware.camera2.cts;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.cts.helpers.CameraErrorCollector;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.params.InputConfiguration;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.cts.helpers.CameraUtils;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.location.Location;
+import android.location.LocationManager;
+import android.media.ExifInterface;
+import android.media.Image;
+import android.media.ImageReader;
+import android.media.ImageWriter;
+import android.media.Image.Plane;
+import android.os.Build;
+import android.os.Environment;
+import android.os.Handler;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Size;
+import android.view.Display;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import com.android.ex.camera2.blocking.BlockingCameraManager;
+import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.ex.camera2.blocking.BlockingStateCallback;
+import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
+
+import junit.framework.Assert;
+
+import org.mockito.Mockito;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+
+/**
+ * A package private utility class for wrapping up the camera2 cts test common utility functions
+ */
+public class CameraTestUtils extends Assert {
+    private static final String TAG = "CameraTestUtils";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    public static final Size SIZE_BOUND_1080P = new Size(1920, 1088);
+    public static final Size SIZE_BOUND_2160P = new Size(3840, 2160);
+    // Only test the preview size that is no larger than 1080p.
+    public static final Size PREVIEW_SIZE_BOUND = SIZE_BOUND_1080P;
+    // Default timeouts for reaching various states
+    public static final int CAMERA_OPEN_TIMEOUT_MS = 3000;
+    public static final int CAMERA_CLOSE_TIMEOUT_MS = 3000;
+    public static final int CAMERA_IDLE_TIMEOUT_MS = 3000;
+    public static final int CAMERA_ACTIVE_TIMEOUT_MS = 1000;
+    public static final int CAMERA_BUSY_TIMEOUT_MS = 1000;
+    public static final int CAMERA_UNCONFIGURED_TIMEOUT_MS = 1000;
+    public static final int CAMERA_CONFIGURE_TIMEOUT_MS = 3000;
+    public static final int CAPTURE_RESULT_TIMEOUT_MS = 3000;
+    public static final int CAPTURE_IMAGE_TIMEOUT_MS = 3000;
+
+    public static final int SESSION_CONFIGURE_TIMEOUT_MS = 3000;
+    public static final int SESSION_CLOSE_TIMEOUT_MS = 3000;
+    public static final int SESSION_READY_TIMEOUT_MS = 3000;
+    public static final int SESSION_ACTIVE_TIMEOUT_MS = 1000;
+
+    public static final int MAX_READER_IMAGES = 5;
+
+    private static final int EXIF_DATETIME_LENGTH = 19;
+    private static final int EXIF_DATETIME_ERROR_MARGIN_SEC = 60;
+    private static final float EXIF_FOCAL_LENGTH_ERROR_MARGIN = 0.001f;
+    private static final float EXIF_EXPOSURE_TIME_ERROR_MARGIN_RATIO = 0.05f;
+    private static final float EXIF_EXPOSURE_TIME_MIN_ERROR_MARGIN_SEC = 0.002f;
+    private static final float EXIF_APERTURE_ERROR_MARGIN = 0.001f;
+
+    private static final Location sTestLocation0 = new Location(LocationManager.GPS_PROVIDER);
+    private static final Location sTestLocation1 = new Location(LocationManager.GPS_PROVIDER);
+    private static final Location sTestLocation2 = new Location(LocationManager.NETWORK_PROVIDER);
+
+    protected static final String DEBUG_FILE_NAME_BASE =
+            Environment.getExternalStorageDirectory().getPath();
+
+    static {
+        sTestLocation0.setTime(1199145600L);
+        sTestLocation0.setLatitude(37.736071);
+        sTestLocation0.setLongitude(-122.441983);
+        sTestLocation0.setAltitude(21.0);
+
+        sTestLocation1.setTime(1199145601L);
+        sTestLocation1.setLatitude(0.736071);
+        sTestLocation1.setLongitude(0.441983);
+        sTestLocation1.setAltitude(1.0);
+
+        sTestLocation2.setTime(1199145602L);
+        sTestLocation2.setLatitude(-89.736071);
+        sTestLocation2.setLongitude(-179.441983);
+        sTestLocation2.setAltitude(100000.0);
+    }
+
+    // Exif test data vectors.
+    public static final ExifTestData[] EXIF_TEST_DATA = {
+            new ExifTestData(
+                    /*gpsLocation*/ sTestLocation0,
+                    /* orientation */90,
+                    /* jpgQuality */(byte) 80,
+                    /* thumbQuality */(byte) 75),
+            new ExifTestData(
+                    /*gpsLocation*/ sTestLocation1,
+                    /* orientation */180,
+                    /* jpgQuality */(byte) 90,
+                    /* thumbQuality */(byte) 85),
+            new ExifTestData(
+                    /*gpsLocation*/ sTestLocation2,
+                    /* orientation */270,
+                    /* jpgQuality */(byte) 100,
+                    /* thumbQuality */(byte) 100)
+    };
+
+    /**
+     * Create an {@link android.media.ImageReader} object and get the surface.
+     *
+     * @param size The size of this ImageReader to be created.
+     * @param format The format of this ImageReader to be created
+     * @param maxNumImages The max number of images that can be acquired simultaneously.
+     * @param listener The listener used by this ImageReader to notify callbacks.
+     * @param handler The handler to use for any listener callbacks.
+     */
+    public static ImageReader makeImageReader(Size size, int format, int maxNumImages,
+            ImageReader.OnImageAvailableListener listener, Handler handler) {
+        ImageReader reader;
+        reader = ImageReader.newInstance(size.getWidth(), size.getHeight(), format,
+                maxNumImages);
+        reader.setOnImageAvailableListener(listener, handler);
+        if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size);
+        return reader;
+    }
+
+    /**
+     * Create an ImageWriter and hook up the ImageListener.
+     *
+     * @param inputSurface The input surface of the ImageWriter.
+     * @param maxImages The max number of Images that can be dequeued simultaneously.
+     * @param listener The listener used by this ImageWriter to notify callbacks
+     * @param handler The handler to post listener callbacks.
+     * @return ImageWriter object created.
+     */
+    public static ImageWriter makeImageWriter(
+            Surface inputSurface, int maxImages,
+            ImageWriter.OnImageReleasedListener listener, Handler handler) {
+        ImageWriter writer = ImageWriter.newInstance(inputSurface, maxImages);
+        writer.setOnImageReleasedListener(listener, handler);
+        return writer;
+    }
+
+    /**
+     * Close pending images and clean up an {@link android.media.ImageReader} object.
+     * @param reader an {@link android.media.ImageReader} to close.
+     */
+    public static void closeImageReader(ImageReader reader) {
+        if (reader != null) {
+            reader.close();
+        }
+    }
+
+    /**
+     * Close pending images and clean up an {@link android.media.ImageWriter} object.
+     * @param writer an {@link android.media.ImageWriter} to close.
+     */
+    public static void closeImageWriter(ImageWriter writer) {
+        if (writer != null) {
+            writer.close();
+        }
+    }
+
+    /**
+     * Dummy listener that release the image immediately once it is available.
+     *
+     * <p>
+     * It can be used for the case where we don't care the image data at all.
+     * </p>
+     */
+    public static class ImageDropperListener implements ImageReader.OnImageAvailableListener {
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            Image image = null;
+            try {
+                image = reader.acquireNextImage();
+            } finally {
+                if (image != null) {
+                    image.close();
+                }
+            }
+        }
+    }
+
+    /**
+     * Image listener that release the image immediately after validating the image
+     */
+    public static class ImageVerifierListener implements ImageReader.OnImageAvailableListener {
+        private Size mSize;
+        private int mFormat;
+
+        public ImageVerifierListener(Size sz, int format) {
+            mSize = sz;
+            mFormat = format;
+        }
+
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            Image image = null;
+            try {
+                image = reader.acquireNextImage();
+            } finally {
+                if (image != null) {
+                    validateImage(image, mSize.getWidth(), mSize.getHeight(), mFormat, null);
+                    image.close();
+                }
+            }
+        }
+    }
+
+    public static class SimpleImageReaderListener
+            implements ImageReader.OnImageAvailableListener {
+        private final LinkedBlockingQueue<Image> mQueue =
+                new LinkedBlockingQueue<Image>();
+        // Indicate whether this listener will drop images or not,
+        // when the queued images reaches the reader maxImages
+        private final boolean mAsyncMode;
+        // maxImages held by the queue in async mode.
+        private final int mMaxImages;
+
+        /**
+         * Create a synchronous SimpleImageReaderListener that queues the images
+         * automatically when they are available, no image will be dropped. If
+         * the caller doesn't call getImage(), the producer will eventually run
+         * into buffer starvation.
+         */
+        public SimpleImageReaderListener() {
+            mAsyncMode = false;
+            mMaxImages = 0;
+        }
+
+        /**
+         * Create a synchronous/asynchronous SimpleImageReaderListener that
+         * queues the images automatically when they are available. For
+         * asynchronous listener, image will be dropped if the queued images
+         * reach to maxImages queued. If the caller doesn't call getImage(), the
+         * producer will not be blocked. For synchronous listener, no image will
+         * be dropped. If the caller doesn't call getImage(), the producer will
+         * eventually run into buffer starvation.
+         *
+         * @param asyncMode If the listener is operating at asynchronous mode.
+         * @param maxImages The max number of images held by this listener.
+         */
+        /**
+         *
+         * @param asyncMode
+         */
+        public SimpleImageReaderListener(boolean asyncMode, int maxImages) {
+            mAsyncMode = asyncMode;
+            mMaxImages = maxImages;
+        }
+
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            try {
+                mQueue.put(reader.acquireNextImage());
+                if (mAsyncMode && mQueue.size() >= mMaxImages) {
+                    Image img = mQueue.poll();
+                    img.close();
+                }
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onImageAvailable");
+            }
+        }
+
+        /**
+         * Get an image from the image reader.
+         *
+         * @param timeout Timeout value for the wait.
+         * @return The image from the image reader.
+         */
+        public Image getImage(long timeout) throws InterruptedException {
+            Image image = mQueue.poll(timeout, TimeUnit.MILLISECONDS);
+            assertNotNull("Wait for an image timed out in " + timeout + "ms", image);
+            return image;
+        }
+
+        /**
+         * Drain the pending images held by this listener currently.
+         *
+         */
+        public void drain() {
+            while (!mQueue.isEmpty()) {
+                Image image = mQueue.poll();
+                assertNotNull("Unable to get an image", image);
+                image.close();
+            }
+        }
+    }
+
+    public static class SimpleImageWriterListener implements ImageWriter.OnImageReleasedListener {
+        private final Semaphore mImageReleasedSema = new Semaphore(0);
+        private final ImageWriter mWriter;
+        @Override
+        public void onImageReleased(ImageWriter writer) {
+            if (writer != mWriter) {
+                return;
+            }
+
+            if (VERBOSE) {
+                Log.v(TAG, "Input image is released");
+            }
+            mImageReleasedSema.release();
+        }
+
+        public SimpleImageWriterListener(ImageWriter writer) {
+            if (writer == null) {
+                throw new IllegalArgumentException("writer cannot be null");
+            }
+            mWriter = writer;
+        }
+
+        public void waitForImageReleased(long timeoutMs) throws InterruptedException {
+            if (!mImageReleasedSema.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS)) {
+                fail("wait for image available timed out after " + timeoutMs + "ms");
+            }
+        }
+    }
+
+    public static class SimpleCaptureCallback extends CameraCaptureSession.CaptureCallback {
+        private final LinkedBlockingQueue<TotalCaptureResult> mQueue =
+                new LinkedBlockingQueue<TotalCaptureResult>();
+        private final LinkedBlockingQueue<CaptureFailure> mFailureQueue =
+                new LinkedBlockingQueue<>();
+        // Pair<CaptureRequest, Long> is a pair of capture request and timestamp.
+        private final LinkedBlockingQueue<Pair<CaptureRequest, Long>> mCaptureStartQueue =
+                new LinkedBlockingQueue<>();
+
+        private AtomicLong mNumFramesArrived = new AtomicLong(0);
+
+        @Override
+        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
+                long timestamp, long frameNumber) {
+            try {
+                mCaptureStartQueue.put(new Pair(request, timestamp));
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onCaptureStarted");
+            }
+        }
+
+        @Override
+        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
+                TotalCaptureResult result) {
+            try {
+                mNumFramesArrived.incrementAndGet();
+                mQueue.put(result);
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onCaptureCompleted");
+            }
+        }
+
+        @Override
+        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
+                CaptureFailure failure) {
+            try {
+                mFailureQueue.put(failure);
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onCaptureFailed");
+            }
+        }
+
+        @Override
+        public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId,
+                long frameNumber) {
+        }
+
+        public long getTotalNumFrames() {
+            return mNumFramesArrived.get();
+        }
+
+        public CaptureResult getCaptureResult(long timeout) {
+            return getTotalCaptureResult(timeout);
+        }
+
+        public TotalCaptureResult getCaptureResult(long timeout, long timestamp) {
+            try {
+                long currentTs = -1L;
+                TotalCaptureResult result;
+                while (true) {
+                    result = mQueue.poll(timeout, TimeUnit.MILLISECONDS);
+                    if (result == null) {
+                        throw new RuntimeException(
+                                "Wait for a capture result timed out in " + timeout + "ms");
+                    }
+                    currentTs = result.get(CaptureResult.SENSOR_TIMESTAMP);
+                    if (currentTs == timestamp) {
+                        return result;
+                    }
+                }
+
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
+            }
+        }
+
+        public TotalCaptureResult getTotalCaptureResult(long timeout) {
+            try {
+                TotalCaptureResult result = mQueue.poll(timeout, TimeUnit.MILLISECONDS);
+                assertNotNull("Wait for a capture result timed out in " + timeout + "ms", result);
+                return result;
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
+            }
+        }
+
+        /**
+         * Get the {@link #CaptureResult capture result} for a given
+         * {@link #CaptureRequest capture request}.
+         *
+         * @param myRequest The {@link #CaptureRequest capture request} whose
+         *            corresponding {@link #CaptureResult capture result} was
+         *            being waited for
+         * @param numResultsWait Number of frames to wait for the capture result
+         *            before timeout.
+         * @throws TimeoutRuntimeException If more than numResultsWait results are
+         *            seen before the result matching myRequest arrives, or each
+         *            individual wait for result times out after
+         *            {@value #CAPTURE_RESULT_TIMEOUT_MS}ms.
+         */
+        public CaptureResult getCaptureResultForRequest(CaptureRequest myRequest,
+                int numResultsWait) {
+            return getTotalCaptureResultForRequest(myRequest, numResultsWait);
+        }
+
+        /**
+         * Get the {@link #TotalCaptureResult total capture result} for a given
+         * {@link #CaptureRequest capture request}.
+         *
+         * @param myRequest The {@link #CaptureRequest capture request} whose
+         *            corresponding {@link #TotalCaptureResult capture result} was
+         *            being waited for
+         * @param numResultsWait Number of frames to wait for the capture result
+         *            before timeout.
+         * @throws TimeoutRuntimeException If more than numResultsWait results are
+         *            seen before the result matching myRequest arrives, or each
+         *            individual wait for result times out after
+         *            {@value #CAPTURE_RESULT_TIMEOUT_MS}ms.
+         */
+        public TotalCaptureResult getTotalCaptureResultForRequest(CaptureRequest myRequest,
+                int numResultsWait) {
+            ArrayList<CaptureRequest> captureRequests = new ArrayList<>(1);
+            captureRequests.add(myRequest);
+            return getTotalCaptureResultsForRequests(captureRequests, numResultsWait)[0];
+        }
+
+        /**
+         * Get an array of {@link #TotalCaptureResult total capture results} for a given list of
+         * {@link #CaptureRequest capture requests}. This can be used when the order of results
+         * may not the same as the order of requests.
+         *
+         * @param captureRequests The list of {@link #CaptureRequest capture requests} whose
+         *            corresponding {@link #TotalCaptureResult capture results} are
+         *            being waited for.
+         * @param numResultsWait Number of frames to wait for the capture results
+         *            before timeout.
+         * @throws TimeoutRuntimeException If more than numResultsWait results are
+         *            seen before all the results matching captureRequests arrives.
+         */
+        public TotalCaptureResult[] getTotalCaptureResultsForRequests(
+                List<CaptureRequest> captureRequests, int numResultsWait) {
+            if (numResultsWait < 0) {
+                throw new IllegalArgumentException("numResultsWait must be no less than 0");
+            }
+            if (captureRequests == null || captureRequests.size() == 0) {
+                throw new IllegalArgumentException("captureRequests must have at least 1 request.");
+            }
+
+            // Create a request -> a list of result indices map that it will wait for.
+            HashMap<CaptureRequest, ArrayList<Integer>> remainingResultIndicesMap = new HashMap<>();
+            for (int i = 0; i < captureRequests.size(); i++) {
+                CaptureRequest request = captureRequests.get(i);
+                ArrayList<Integer> indices = remainingResultIndicesMap.get(request);
+                if (indices == null) {
+                    indices = new ArrayList<>();
+                    remainingResultIndicesMap.put(request, indices);
+                }
+                indices.add(i);
+            }
+
+            TotalCaptureResult[] results = new TotalCaptureResult[captureRequests.size()];
+            int i = 0;
+            do {
+                TotalCaptureResult result = getTotalCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
+                CaptureRequest request = result.getRequest();
+                ArrayList<Integer> indices = remainingResultIndicesMap.get(request);
+                if (indices != null) {
+                    results[indices.get(0)] = result;
+                    indices.remove(0);
+
+                    // Remove the entry if all results for this request has been fulfilled.
+                    if (indices.isEmpty()) {
+                        remainingResultIndicesMap.remove(request);
+                    }
+                }
+
+                if (remainingResultIndicesMap.isEmpty()) {
+                    return results;
+                }
+            } while (i++ < numResultsWait);
+
+            throw new TimeoutRuntimeException("Unable to get the expected capture result after "
+                    + "waiting for " + numResultsWait + " results");
+        }
+
+        /**
+         * Get an array list of {@link #CaptureFailure capture failure} with maxNumFailures entries
+         * at most. If it times out before maxNumFailures failures are received, return the failures
+         * received so far.
+         *
+         * @param maxNumFailures The maximal number of failures to return. If it times out before
+         *                       the maximal number of failures are received, return the received
+         *                       failures so far.
+         * @throws UnsupportedOperationException If an error happens while waiting on the failure.
+         */
+        public ArrayList<CaptureFailure> getCaptureFailures(long maxNumFailures) {
+            ArrayList<CaptureFailure> failures = new ArrayList<>();
+            try {
+                for (int i = 0; i < maxNumFailures; i++) {
+                    CaptureFailure failure = mFailureQueue.poll(CAPTURE_RESULT_TIMEOUT_MS,
+                            TimeUnit.MILLISECONDS);
+                    if (failure == null) {
+                        // If waiting on a failure times out, return the failures so far.
+                        break;
+                    }
+                    failures.add(failure);
+                }
+            }  catch (InterruptedException e) {
+                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
+            }
+
+            return failures;
+        }
+
+        /**
+         * Wait until the capture start of a request and expected timestamp arrives or it times
+         * out after a number of capture starts.
+         *
+         * @param request The request for the capture start to wait for.
+         * @param timestamp The timestamp for the capture start to wait for.
+         * @param numCaptureStartsWait The number of capture start events to wait for before timing
+         *                             out.
+         */
+        public void waitForCaptureStart(CaptureRequest request, Long timestamp,
+                int numCaptureStartsWait) throws Exception {
+            Pair<CaptureRequest, Long> expectedShutter = new Pair<>(request, timestamp);
+
+            int i = 0;
+            do {
+                Pair<CaptureRequest, Long> shutter = mCaptureStartQueue.poll(
+                        CAPTURE_RESULT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+
+                if (shutter == null) {
+                    throw new TimeoutRuntimeException("Unable to get any more capture start " +
+                            "event after waiting for " + CAPTURE_RESULT_TIMEOUT_MS + " ms.");
+                } else if (expectedShutter.equals(shutter)) {
+                    return;
+                }
+
+            } while (i++ < numCaptureStartsWait);
+
+            throw new TimeoutRuntimeException("Unable to get the expected capture start " +
+                    "event after waiting for " + numCaptureStartsWait + " capture starts");
+        }
+
+        public boolean hasMoreResults()
+        {
+            return mQueue.isEmpty();
+        }
+
+        public void drain() {
+            mQueue.clear();
+            mNumFramesArrived.getAndSet(0);
+            mFailureQueue.clear();
+            mCaptureStartQueue.clear();
+        }
+    }
+
+    /**
+     * Block until the camera is opened.
+     *
+     * <p>Don't use this to test #onDisconnected/#onError since this will throw
+     * an AssertionError if it fails to open the camera device.</p>
+     *
+     * @return CameraDevice opened camera device
+     *
+     * @throws IllegalArgumentException
+     *            If the handler is null, or if the handler's looper is current.
+     * @throws CameraAccessException
+     *            If open fails immediately.
+     * @throws BlockingOpenException
+     *            If open fails after blocking for some amount of time.
+     * @throws TimeoutRuntimeException
+     *            If opening times out. Typically unrecoverable.
+     */
+    public static CameraDevice openCamera(CameraManager manager, String cameraId,
+            CameraDevice.StateCallback listener, Handler handler) throws CameraAccessException,
+            BlockingOpenException {
+
+        /**
+         * Although camera2 API allows 'null' Handler (it will just use the current
+         * thread's Looper), this is not what we want for CTS.
+         *
+         * In CTS the default looper is used only to process events in between test runs,
+         * so anything sent there would not be executed inside a test and the test would fail.
+         *
+         * In this case, BlockingCameraManager#openCamera performs the check for us.
+         */
+        return (new BlockingCameraManager(manager)).openCamera(cameraId, listener, handler);
+    }
+
+
+    /**
+     * Block until the camera is opened.
+     *
+     * <p>Don't use this to test #onDisconnected/#onError since this will throw
+     * an AssertionError if it fails to open the camera device.</p>
+     *
+     * @throws IllegalArgumentException
+     *            If the handler is null, or if the handler's looper is current.
+     * @throws CameraAccessException
+     *            If open fails immediately.
+     * @throws BlockingOpenException
+     *            If open fails after blocking for some amount of time.
+     * @throws TimeoutRuntimeException
+     *            If opening times out. Typically unrecoverable.
+     */
+    public static CameraDevice openCamera(CameraManager manager, String cameraId, Handler handler)
+            throws CameraAccessException,
+            BlockingOpenException {
+        return openCamera(manager, cameraId, /*listener*/null, handler);
+    }
+
+    /**
+     * Configure a new camera session with output surfaces and type.
+     *
+     * @param camera The CameraDevice to be configured.
+     * @param outputSurfaces The surface list that used for camera output.
+     * @param listener The callback CameraDevice will notify when capture results are available.
+     */
+    public static CameraCaptureSession configureCameraSession(CameraDevice camera,
+            List<Surface> outputSurfaces, boolean isHighSpeed,
+            CameraCaptureSession.StateCallback listener, Handler handler)
+            throws CameraAccessException {
+        BlockingSessionCallback sessionListener = new BlockingSessionCallback(listener);
+        if (isHighSpeed) {
+            camera.createConstrainedHighSpeedCaptureSession(outputSurfaces,
+                    sessionListener, handler);
+        } else {
+            camera.createCaptureSession(outputSurfaces, sessionListener, handler);
+        }
+        CameraCaptureSession session =
+                sessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
+        assertFalse("Camera session should not be a reprocessable session",
+                session.isReprocessable());
+        String sessionType = isHighSpeed ? "High Speed" : "Normal";
+        assertTrue("Capture session type must be " + sessionType,
+                isHighSpeed ==
+                CameraConstrainedHighSpeedCaptureSession.class.isAssignableFrom(session.getClass()));
+
+        return session;
+    }
+
+    /**
+     * Configure a new camera session with output surfaces.
+     *
+     * @param camera The CameraDevice to be configured.
+     * @param outputSurfaces The surface list that used for camera output.
+     * @param listener The callback CameraDevice will notify when capture results are available.
+     */
+    public static CameraCaptureSession configureCameraSession(CameraDevice camera,
+            List<Surface> outputSurfaces,
+            CameraCaptureSession.StateCallback listener, Handler handler)
+            throws CameraAccessException {
+
+        return configureCameraSession(camera, outputSurfaces, /*isHighSpeed*/false,
+                listener, handler);
+    }
+
+    public static CameraCaptureSession configureReprocessableCameraSession(CameraDevice camera,
+            InputConfiguration inputConfiguration, List<Surface> outputSurfaces,
+            CameraCaptureSession.StateCallback listener, Handler handler)
+            throws CameraAccessException {
+        BlockingSessionCallback sessionListener = new BlockingSessionCallback(listener);
+        camera.createReprocessableCaptureSession(inputConfiguration, outputSurfaces,
+                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);
+    }
+
+    /**
+     * Check if the format is a legal YUV format camera supported.
+     */
+    public static void checkYuvFormat(int format) {
+        if ((format != ImageFormat.YUV_420_888) &&
+                (format != ImageFormat.NV21) &&
+                (format != ImageFormat.YV12)) {
+            fail("Wrong formats: " + format);
+        }
+    }
+
+    /**
+     * Check if image size and format match given size and format.
+     */
+    public static void checkImage(Image image, int width, int height, int format) {
+        // Image reader will wrap YV12/NV21 image by YUV_420_888
+        if (format == ImageFormat.NV21 || format == ImageFormat.YV12) {
+            format = ImageFormat.YUV_420_888;
+        }
+        assertNotNull("Input image is invalid", image);
+        assertEquals("Format doesn't match", format, image.getFormat());
+        assertEquals("Width doesn't match", width, image.getWidth());
+        assertEquals("Height doesn't match", height, image.getHeight());
+    }
+
+    /**
+     * <p>Read data from all planes of an Image into a contiguous unpadded, unpacked
+     * 1-D linear byte array, such that it can be write into disk, or accessed by
+     * software conveniently. It supports YUV_420_888/NV21/YV12 and JPEG input
+     * Image format.</p>
+     *
+     * <p>For YUV_420_888/NV21/YV12/Y8/Y16, it returns a byte array that contains
+     * the Y plane data first, followed by U(Cb), V(Cr) planes if there is any
+     * (xstride = width, ystride = height for chroma and luma components).</p>
+     *
+     * <p>For JPEG, it returns a 1-D byte array contains a complete JPEG image.</p>
+     */
+    public static byte[] getDataFromImage(Image image) {
+        assertNotNull("Invalid image:", image);
+        int format = image.getFormat();
+        int width = image.getWidth();
+        int height = image.getHeight();
+        int rowStride, pixelStride;
+        byte[] data = null;
+
+        // Read image data
+        Plane[] planes = image.getPlanes();
+        assertTrue("Fail to get image planes", planes != null && planes.length > 0);
+
+        // Check image validity
+        checkAndroidImageFormat(image);
+
+        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) {
+            buffer = planes[0].getBuffer();
+            assertNotNull("Fail to get jpeg or depth ByteBuffer", buffer);
+            data = new byte[buffer.remaining()];
+            buffer.get(data);
+            buffer.rewind();
+            return data;
+        }
+
+        int offset = 0;
+        data = new byte[width * height * ImageFormat.getBitsPerPixel(format) / 8];
+        int maxRowSize = planes[0].getRowStride();
+        for (int i = 0; i < planes.length; i++) {
+            if (maxRowSize < planes[i].getRowStride()) {
+                maxRowSize = planes[i].getRowStride();
+            }
+        }
+        byte[] rowData = new byte[maxRowSize];
+        if(VERBOSE) Log.v(TAG, "get data from " + planes.length + " planes");
+        for (int i = 0; i < planes.length; i++) {
+            buffer = planes[i].getBuffer();
+            assertNotNull("Fail to get bytebuffer from plane", buffer);
+            rowStride = planes[i].getRowStride();
+            pixelStride = planes[i].getPixelStride();
+            assertTrue("pixel stride " + pixelStride + " is invalid", pixelStride > 0);
+            if (VERBOSE) {
+                Log.v(TAG, "pixelStride " + pixelStride);
+                Log.v(TAG, "rowStride " + rowStride);
+                Log.v(TAG, "width " + width);
+                Log.v(TAG, "height " + height);
+            }
+            // For multi-planar yuv images, assuming yuv420 with 2x2 chroma subsampling.
+            int w = (i == 0) ? width : width / 2;
+            int h = (i == 0) ? height : height / 2;
+            assertTrue("rowStride " + rowStride + " should be >= width " + w , rowStride >= w);
+            for (int row = 0; row < h; row++) {
+                int bytesPerPixel = ImageFormat.getBitsPerPixel(format) / 8;
+                int length;
+                if (pixelStride == bytesPerPixel) {
+                    // Special case: optimized read of the entire row
+                    length = w * bytesPerPixel;
+                    buffer.get(data, offset, length);
+                    offset += length;
+                } else {
+                    // Generic case: should work for any pixelStride but slower.
+                    // Use intermediate buffer to avoid read byte-by-byte from
+                    // DirectByteBuffer, which is very bad for performance
+                    length = (w - 1) * pixelStride + bytesPerPixel;
+                    buffer.get(rowData, 0, length);
+                    for (int col = 0; col < w; col++) {
+                        data[offset++] = rowData[col * pixelStride];
+                    }
+                }
+                // Advance buffer the remainder of the row stride
+                if (row < h - 1) {
+                    buffer.position(buffer.position() + rowStride - length);
+                }
+            }
+            if (VERBOSE) Log.v(TAG, "Finished reading data from plane " + i);
+            buffer.rewind();
+        }
+        return data;
+    }
+
+    /**
+     * <p>Check android image format validity for an image, only support below formats:</p>
+     *
+     * <p>YUV_420_888/NV21/YV12, can add more for future</p>
+     */
+    public static void checkAndroidImageFormat(Image image) {
+        int format = image.getFormat();
+        Plane[] planes = image.getPlanes();
+        switch (format) {
+            case ImageFormat.YUV_420_888:
+            case ImageFormat.NV21:
+            case ImageFormat.YV12:
+                assertEquals("YUV420 format Images should have 3 planes", 3, planes.length);
+                break;
+            case ImageFormat.JPEG:
+            case ImageFormat.RAW_SENSOR:
+            case ImageFormat.DEPTH16:
+            case ImageFormat.DEPTH_POINT_CLOUD:
+                assertEquals("JPEG/RAW/depth Images should have one plane", 1, planes.length);
+                break;
+            default:
+                fail("Unsupported Image Format: " + format);
+        }
+    }
+
+    public static void dumpFile(String fileName, Bitmap data) {
+        FileOutputStream outStream;
+        try {
+            Log.v(TAG, "output will be saved as " + fileName);
+            outStream = new FileOutputStream(fileName);
+        } catch (IOException ioe) {
+            throw new RuntimeException("Unable to create debug output file " + fileName, ioe);
+        }
+
+        try {
+            data.compress(Bitmap.CompressFormat.JPEG, /*quality*/90, outStream);
+            outStream.close();
+        } catch (IOException ioe) {
+            throw new RuntimeException("failed writing data to file " + fileName, ioe);
+        }
+    }
+
+    public static void dumpFile(String fileName, byte[] data) {
+        FileOutputStream outStream;
+        try {
+            Log.v(TAG, "output will be saved as " + fileName);
+            outStream = new FileOutputStream(fileName);
+        } catch (IOException ioe) {
+            throw new RuntimeException("Unable to create debug output file " + fileName, ioe);
+        }
+
+        try {
+            outStream.write(data);
+            outStream.close();
+        } catch (IOException ioe) {
+            throw new RuntimeException("failed writing data to file " + fileName, ioe);
+        }
+    }
+
+    /**
+     * Get the available output sizes for the user-defined {@code format}.
+     *
+     * <p>Note that implementation-defined/hidden formats are not supported.</p>
+     */
+    public static Size[] getSupportedSizeForFormat(int format, String cameraId,
+            CameraManager cameraManager) throws CameraAccessException {
+        CameraCharacteristics properties = cameraManager.getCameraCharacteristics(cameraId);
+        assertNotNull("Can't get camera characteristics!", properties);
+        if (VERBOSE) {
+            Log.v(TAG, "get camera characteristics for camera: " + cameraId);
+        }
+        StreamConfigurationMap configMap =
+                properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+        Size[] availableSizes = configMap.getOutputSizes(format);
+        assertArrayNotEmpty(availableSizes, "availableSizes should not be empty for format: "
+                + format);
+        Size[] highResAvailableSizes = configMap.getHighResolutionOutputSizes(format);
+        if (highResAvailableSizes != null && highResAvailableSizes.length > 0) {
+            Size[] allSizes = new Size[availableSizes.length + highResAvailableSizes.length];
+            System.arraycopy(availableSizes, 0, allSizes, 0,
+                    availableSizes.length);
+            System.arraycopy(highResAvailableSizes, 0, allSizes, availableSizes.length,
+                    highResAvailableSizes.length);
+            availableSizes = allSizes;
+        }
+        if (VERBOSE) Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(availableSizes));
+        return availableSizes;
+    }
+
+    /**
+     * Get the available output sizes for the given class.
+     *
+     */
+    public static Size[] getSupportedSizeForClass(Class klass, String cameraId,
+            CameraManager cameraManager) throws CameraAccessException {
+        CameraCharacteristics properties = cameraManager.getCameraCharacteristics(cameraId);
+        assertNotNull("Can't get camera characteristics!", properties);
+        if (VERBOSE) {
+            Log.v(TAG, "get camera characteristics for camera: " + cameraId);
+        }
+        StreamConfigurationMap configMap =
+                properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+        Size[] availableSizes = configMap.getOutputSizes(klass);
+        assertArrayNotEmpty(availableSizes, "availableSizes should not be empty for class: "
+                + klass);
+        Size[] highResAvailableSizes = configMap.getHighResolutionOutputSizes(ImageFormat.PRIVATE);
+        if (highResAvailableSizes != null && highResAvailableSizes.length > 0) {
+            Size[] allSizes = new Size[availableSizes.length + highResAvailableSizes.length];
+            System.arraycopy(availableSizes, 0, allSizes, 0,
+                    availableSizes.length);
+            System.arraycopy(highResAvailableSizes, 0, allSizes, availableSizes.length,
+                    highResAvailableSizes.length);
+            availableSizes = allSizes;
+        }
+        if (VERBOSE) Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(availableSizes));
+        return availableSizes;
+    }
+
+    /**
+     * Size comparator that compares the number of pixels it covers.
+     *
+     * <p>If two the areas of two sizes are same, compare the widths.</p>
+     */
+    public static class SizeComparator implements Comparator<Size> {
+        @Override
+        public int compare(Size lhs, Size rhs) {
+            return CameraUtils
+                    .compareSizes(lhs.getWidth(), lhs.getHeight(), rhs.getWidth(), rhs.getHeight());
+        }
+    }
+
+    /**
+     * Get sorted size list in descending order. Remove the sizes larger than
+     * the bound. If the bound is null, don't do the size bound filtering.
+     */
+    static public List<Size> getSupportedPreviewSizes(String cameraId,
+            CameraManager cameraManager, Size bound) throws CameraAccessException {
+
+        Size[] rawSizes = getSupportedSizeForClass(android.view.SurfaceHolder.class, cameraId,
+                cameraManager);
+        assertArrayNotEmpty(rawSizes,
+                "Available sizes for SurfaceHolder class should not be empty");
+        if (VERBOSE) {
+            Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(rawSizes));
+        }
+
+        if (bound == null) {
+            return getAscendingOrderSizes(Arrays.asList(rawSizes), /*ascending*/false);
+        }
+
+        List<Size> sizes = new ArrayList<Size>();
+        for (Size sz: rawSizes) {
+            if (sz.getWidth() <= bound.getWidth() && sz.getHeight() <= bound.getHeight()) {
+                sizes.add(sz);
+            }
+        }
+        return getAscendingOrderSizes(sizes, /*ascending*/false);
+    }
+
+    /**
+     * Get a sorted list of sizes from a given size list.
+     *
+     * <p>
+     * The size is compare by area it covers, if the areas are same, then
+     * compare the widths.
+     * </p>
+     *
+     * @param sizeList The input size list to be sorted
+     * @param ascending True if the order is ascending, otherwise descending order
+     * @return The ordered list of sizes
+     */
+    static public List<Size> getAscendingOrderSizes(final List<Size> sizeList, boolean ascending) {
+        if (sizeList == null) {
+            throw new IllegalArgumentException("sizeList shouldn't be null");
+        }
+
+        Comparator<Size> comparator = new SizeComparator();
+        List<Size> sortedSizes = new ArrayList<Size>();
+        sortedSizes.addAll(sizeList);
+        Collections.sort(sortedSizes, comparator);
+        if (!ascending) {
+            Collections.reverse(sortedSizes);
+        }
+
+        return sortedSizes;
+    }
+
+    /**
+     * Get sorted (descending order) size list for given format. Remove the sizes larger than
+     * the bound. If the bound is null, don't do the size bound filtering.
+     */
+    static public List<Size> getSortedSizesForFormat(String cameraId,
+            CameraManager cameraManager, int format, Size bound) throws CameraAccessException {
+        Comparator<Size> comparator = new SizeComparator();
+        Size[] sizes = getSupportedSizeForFormat(format, cameraId, cameraManager);
+        List<Size> sortedSizes = null;
+        if (bound != null) {
+            sortedSizes = new ArrayList<Size>(/*capacity*/1);
+            for (Size sz : sizes) {
+                if (comparator.compare(sz, bound) <= 0) {
+                    sortedSizes.add(sz);
+                }
+            }
+        } else {
+            sortedSizes = Arrays.asList(sizes);
+        }
+        assertTrue("Supported size list should have at least one element",
+                sortedSizes.size() > 0);
+
+        Collections.sort(sortedSizes, comparator);
+        // Make it in descending order.
+        Collections.reverse(sortedSizes);
+        return sortedSizes;
+    }
+
+    /**
+     * Get supported video size list for a given camera device.
+     *
+     * <p>
+     * Filter out the sizes that are larger than the bound. If the bound is
+     * null, don't do the size bound filtering.
+     * </p>
+     */
+    static public List<Size> getSupportedVideoSizes(String cameraId,
+            CameraManager cameraManager, Size bound) throws CameraAccessException {
+
+        Size[] rawSizes = getSupportedSizeForClass(android.media.MediaRecorder.class,
+                cameraId, cameraManager);
+        assertArrayNotEmpty(rawSizes,
+                "Available sizes for MediaRecorder class should not be empty");
+        if (VERBOSE) {
+            Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(rawSizes));
+        }
+
+        if (bound == null) {
+            return getAscendingOrderSizes(Arrays.asList(rawSizes), /*ascending*/false);
+        }
+
+        List<Size> sizes = new ArrayList<Size>();
+        for (Size sz: rawSizes) {
+            if (sz.getWidth() <= bound.getWidth() && sz.getHeight() <= bound.getHeight()) {
+                sizes.add(sz);
+            }
+        }
+        return getAscendingOrderSizes(sizes, /*ascending*/false);
+    }
+
+    /**
+     * Get supported video size list (descending order) for a given camera device.
+     *
+     * <p>
+     * Filter out the sizes that are larger than the bound. If the bound is
+     * null, don't do the size bound filtering.
+     * </p>
+     */
+    static public List<Size> getSupportedStillSizes(String cameraId,
+            CameraManager cameraManager, Size bound) throws CameraAccessException {
+        return getSortedSizesForFormat(cameraId, cameraManager, ImageFormat.JPEG, bound);
+    }
+
+    static public Size getMinPreviewSize(String cameraId, CameraManager cameraManager)
+            throws CameraAccessException {
+        List<Size> sizes = getSupportedPreviewSizes(cameraId, cameraManager, null);
+        return sizes.get(sizes.size() - 1);
+    }
+
+    /**
+     * Get max supported preview size for a camera device.
+     */
+    static public Size getMaxPreviewSize(String cameraId, CameraManager cameraManager)
+            throws CameraAccessException {
+        return getMaxPreviewSize(cameraId, cameraManager, /*bound*/null);
+    }
+
+    /**
+     * Get max preview size for a camera device in the supported sizes that are no larger
+     * than the bound.
+     */
+    static public Size getMaxPreviewSize(String cameraId, CameraManager cameraManager, Size bound)
+            throws CameraAccessException {
+        List<Size> sizes = getSupportedPreviewSizes(cameraId, cameraManager, bound);
+        return sizes.get(0);
+    }
+
+    /**
+     * Get max depth size for a camera device.
+     */
+    static public Size getMaxDepthSize(String cameraId, CameraManager cameraManager)
+            throws CameraAccessException {
+        List<Size> sizes = getSortedSizesForFormat(cameraId, cameraManager, ImageFormat.DEPTH16,
+                /*bound*/ null);
+        return sizes.get(0);
+    }
+
+    /**
+     * Get the largest size by area.
+     *
+     * @param sizes an array of sizes, must have at least 1 element
+     *
+     * @return Largest Size
+     *
+     * @throws IllegalArgumentException if sizes was null or had 0 elements
+     */
+    public static Size getMaxSize(Size... sizes) {
+        if (sizes == null || sizes.length == 0) {
+            throw new IllegalArgumentException("sizes was empty");
+        }
+
+        Size sz = sizes[0];
+        for (Size size : sizes) {
+            if (size.getWidth() * size.getHeight() > sz.getWidth() * sz.getHeight()) {
+                sz = size;
+            }
+        }
+
+        return sz;
+    }
+
+    /**
+     * Returns true if the given {@code array} contains the given element.
+     *
+     * @param array {@code array} to check for {@code elem}
+     * @param elem {@code elem} to test for
+     * @return {@code true} if the given element is contained
+     */
+    public static boolean contains(int[] array, int elem) {
+        if (array == null) return false;
+        for (int i = 0; i < array.length; i++) {
+            if (elem == array[i]) return true;
+        }
+        return false;
+    }
+
+    /**
+     * Get object array from byte array.
+     *
+     * @param array Input byte array to be converted
+     * @return Byte object array converted from input byte array
+     */
+    public static Byte[] toObject(byte[] array) {
+        return convertPrimitiveArrayToObjectArray(array, Byte.class);
+    }
+
+    /**
+     * Get object array from int array.
+     *
+     * @param array Input int array to be converted
+     * @return Integer object array converted from input int array
+     */
+    public static Integer[] toObject(int[] array) {
+        return convertPrimitiveArrayToObjectArray(array, Integer.class);
+    }
+
+    /**
+     * Get object array from float array.
+     *
+     * @param array Input float array to be converted
+     * @return Float object array converted from input float array
+     */
+    public static Float[] toObject(float[] array) {
+        return convertPrimitiveArrayToObjectArray(array, Float.class);
+    }
+
+    /**
+     * Get object array from double array.
+     *
+     * @param array Input double array to be converted
+     * @return Double object array converted from input double array
+     */
+    public static Double[] toObject(double[] array) {
+        return convertPrimitiveArrayToObjectArray(array, Double.class);
+    }
+
+    /**
+     * Convert a primitive input array into its object array version (e.g. from int[] to Integer[]).
+     *
+     * @param array Input array object
+     * @param wrapperClass The boxed class it converts to
+     * @return Boxed version of primitive array
+     */
+    private static <T> T[] convertPrimitiveArrayToObjectArray(final Object array,
+            final Class<T> wrapperClass) {
+        // getLength does the null check and isArray check already.
+        int arrayLength = Array.getLength(array);
+        if (arrayLength == 0) {
+            throw new IllegalArgumentException("Input array shouldn't be empty");
+        }
+
+        @SuppressWarnings("unchecked")
+        final T[] result = (T[]) Array.newInstance(wrapperClass, arrayLength);
+        for (int i = 0; i < arrayLength; i++) {
+            Array.set(result, i, Array.get(array, i));
+        }
+        return result;
+    }
+
+    /**
+     * Validate image based on format and size.
+     *
+     * @param image The image to be validated.
+     * @param width The image width.
+     * @param height The image height.
+     * @param format The image format.
+     * @param filePath The debug dump file path, null if don't want to dump to
+     *            file.
+     * @throws UnsupportedOperationException if calling with an unknown format
+     */
+    public static void validateImage(Image image, int width, int height, int format,
+            String filePath) {
+        checkImage(image, width, height, format);
+
+        /**
+         * TODO: validate timestamp:
+         * 1. capture result timestamp against the image timestamp (need
+         * consider frame drops)
+         * 2. timestamps should be monotonically increasing for different requests
+         */
+        if(VERBOSE) Log.v(TAG, "validating Image");
+        byte[] data = getDataFromImage(image);
+        assertTrue("Invalid image data", data != null && data.length > 0);
+
+        switch (format) {
+            case ImageFormat.JPEG:
+                validateJpegData(data, width, height, filePath);
+                break;
+            case ImageFormat.YUV_420_888:
+            case ImageFormat.YV12:
+                validateYuvData(data, width, height, format, image.getTimestamp(), filePath);
+                break;
+            case ImageFormat.RAW_SENSOR:
+                validateRaw16Data(data, width, height, format, image.getTimestamp(), filePath);
+                break;
+            case ImageFormat.DEPTH16:
+                validateDepth16Data(data, width, height, format, image.getTimestamp(), filePath);
+                break;
+            case ImageFormat.DEPTH_POINT_CLOUD:
+                validateDepthPointCloudData(data, width, height, format, image.getTimestamp(), filePath);
+                break;
+            default:
+                throw new UnsupportedOperationException("Unsupported format for validation: "
+                        + format);
+        }
+    }
+
+    /**
+     * Provide a mock for {@link CameraDevice.StateCallback}.
+     *
+     * <p>Only useful because mockito can't mock {@link CameraDevice.StateCallback} which is an
+     * abstract class.</p>
+     *
+     * <p>
+     * Use this instead of other classes when needing to verify interactions, since
+     * trying to spy on {@link BlockingStateCallback} (or others) will cause unnecessary extra
+     * interactions which will cause false test failures.
+     * </p>
+     *
+     */
+    public static class MockStateCallback extends CameraDevice.StateCallback {
+
+        @Override
+        public void onOpened(CameraDevice camera) {
+        }
+
+        @Override
+        public void onDisconnected(CameraDevice camera) {
+        }
+
+        @Override
+        public void onError(CameraDevice camera, int error) {
+        }
+
+        private MockStateCallback() {}
+
+        /**
+         * Create a Mockito-ready mocked StateCallback.
+         */
+        public static MockStateCallback mock() {
+            return Mockito.spy(new MockStateCallback());
+        }
+    }
+
+    private static void validateJpegData(byte[] jpegData, int width, int height, String filePath) {
+        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
+        // DecodeBound mode: only parse the frame header to get width/height.
+        // it doesn't decode the pixel.
+        bmpOptions.inJustDecodeBounds = true;
+        BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length, bmpOptions);
+        assertEquals(width, bmpOptions.outWidth);
+        assertEquals(height, bmpOptions.outHeight);
+
+        // Pixel decoding mode: decode whole image. check if the image data
+        // is decodable here.
+        assertNotNull("Decoding jpeg failed",
+                BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length));
+        if (DEBUG && filePath != null) {
+            String fileName =
+                    filePath + "/" + width + "x" + height + ".jpeg";
+            dumpFile(fileName, jpegData);
+        }
+    }
+
+    private static void validateYuvData(byte[] yuvData, int width, int height, int format,
+            long ts, String filePath) {
+        checkYuvFormat(format);
+        if (VERBOSE) Log.v(TAG, "Validating YUV data");
+        int expectedSize = width * height * ImageFormat.getBitsPerPixel(format) / 8;
+        assertEquals("Yuv data doesn't match", expectedSize, yuvData.length);
+
+        // TODO: Can add data validation for test pattern.
+
+        if (DEBUG && filePath != null) {
+            String fileName =
+                    filePath + "/" + width + "x" + height + "_" + ts / 1e6 + ".yuv";
+            dumpFile(fileName, yuvData);
+        }
+    }
+
+    private static void validateRaw16Data(byte[] rawData, int width, int height, int format,
+            long ts, String filePath) {
+        if (VERBOSE) Log.v(TAG, "Validating raw data");
+        int expectedSize = width * height * ImageFormat.getBitsPerPixel(format) / 8;
+        assertEquals("Raw data doesn't match", expectedSize, rawData.length);
+
+        // TODO: Can add data validation for test pattern.
+
+        if (DEBUG && filePath != null) {
+            String fileName =
+                    filePath + "/" + width + "x" + height + "_" + ts / 1e6 + ".raw16";
+            dumpFile(fileName, rawData);
+        }
+
+        return;
+    }
+
+    private static void validateDepth16Data(byte[] depthData, int width, int height, int format,
+            long ts, String filePath) {
+
+        if (VERBOSE) Log.v(TAG, "Validating depth16 data");
+        int expectedSize = width * height * ImageFormat.getBitsPerPixel(format) / 8;
+        assertEquals("Depth data doesn't match", expectedSize, depthData.length);
+
+
+        if (DEBUG && filePath != null) {
+            String fileName =
+                    filePath + "/" + width + "x" + height + "_" + ts / 1e6 + ".depth16";
+            dumpFile(fileName, depthData);
+        }
+
+        return;
+
+    }
+
+    private static void validateDepthPointCloudData(byte[] depthData, int width, int height, int format,
+            long ts, String filePath) {
+
+        if (VERBOSE) Log.v(TAG, "Validating depth point cloud data");
+
+        // Can't validate size since it is variable
+
+        if (DEBUG && filePath != null) {
+            String fileName =
+                    filePath + "/" + width + "x" + height + "_" + ts / 1e6 + ".depth_point_cloud";
+            dumpFile(fileName, depthData);
+        }
+
+        return;
+
+    }
+
+    public static <T> T getValueNotNull(CaptureResult result, CaptureResult.Key<T> key) {
+        if (result == null) {
+            throw new IllegalArgumentException("Result must not be null");
+        }
+
+        T value = result.get(key);
+        assertNotNull("Value of Key " + key.getName() + "shouldn't be null", value);
+        return value;
+    }
+
+    public static <T> T getValueNotNull(CameraCharacteristics characteristics,
+            CameraCharacteristics.Key<T> key) {
+        if (characteristics == null) {
+            throw new IllegalArgumentException("Camera characteristics must not be null");
+        }
+
+        T value = characteristics.get(key);
+        assertNotNull("Value of Key " + key.getName() + "shouldn't be null", value);
+        return value;
+    }
+
+    /**
+     * Get a crop region for a given zoom factor and center position.
+     * <p>
+     * The center position is normalized position in range of [0, 1.0], where
+     * (0, 0) represents top left corner, (1.0. 1.0) represents bottom right
+     * corner. The center position could limit the effective minimal zoom
+     * factor, for example, if the center position is (0.75, 0.75), the
+     * effective minimal zoom position becomes 2.0. If the requested zoom factor
+     * is smaller than 2.0, a crop region with 2.0 zoom factor will be returned.
+     * </p>
+     * <p>
+     * The aspect ratio of the crop region is maintained the same as the aspect
+     * ratio of active array.
+     * </p>
+     *
+     * @param zoomFactor The zoom factor to generate the crop region, it must be
+     *            >= 1.0
+     * @param center The normalized zoom center point that is in the range of [0, 1].
+     * @param maxZoom The max zoom factor supported by this device.
+     * @param activeArray The active array size of this device.
+     * @return crop region for the given normalized center and zoom factor.
+     */
+    public static Rect getCropRegionForZoom(float zoomFactor, final PointF center,
+            final float maxZoom, final Rect activeArray) {
+        if (zoomFactor < 1.0) {
+            throw new IllegalArgumentException("zoom factor " + zoomFactor + " should be >= 1.0");
+        }
+        if (center.x > 1.0 || center.x < 0) {
+            throw new IllegalArgumentException("center.x " + center.x
+                    + " should be in range of [0, 1.0]");
+        }
+        if (center.y > 1.0 || center.y < 0) {
+            throw new IllegalArgumentException("center.y " + center.y
+                    + " should be in range of [0, 1.0]");
+        }
+        if (maxZoom < 1.0) {
+            throw new IllegalArgumentException("max zoom factor " + maxZoom + " should be >= 1.0");
+        }
+        if (activeArray == null) {
+            throw new IllegalArgumentException("activeArray must not be null");
+        }
+
+        float minCenterLength = Math.min(Math.min(center.x, 1.0f - center.x),
+                Math.min(center.y, 1.0f - center.y));
+        float minEffectiveZoom =  0.5f / minCenterLength;
+        if (minEffectiveZoom > maxZoom) {
+            throw new IllegalArgumentException("Requested center " + center.toString() +
+                    " has minimal zoomable factor " + minEffectiveZoom + ", which exceeds max"
+                            + " zoom factor " + maxZoom);
+        }
+
+        if (zoomFactor < minEffectiveZoom) {
+            Log.w(TAG, "Requested zoomFactor " + zoomFactor + " > minimal zoomable factor "
+                    + minEffectiveZoom + ". It will be overwritten by " + minEffectiveZoom);
+            zoomFactor = minEffectiveZoom;
+        }
+
+        int cropCenterX = (int)(activeArray.width() * center.x);
+        int cropCenterY = (int)(activeArray.height() * center.y);
+        int cropWidth = (int) (activeArray.width() / zoomFactor);
+        int cropHeight = (int) (activeArray.height() / zoomFactor);
+
+        return new Rect(
+                /*left*/cropCenterX - cropWidth / 2,
+                /*top*/cropCenterY - cropHeight / 2,
+                /*right*/ cropCenterX + cropWidth / 2 - 1,
+                /*bottom*/cropCenterY + cropHeight / 2 - 1);
+    }
+
+    /**
+     * Calculate output 3A region from the intersection of input 3A region and cropped region.
+     *
+     * @param requestRegions The input 3A regions
+     * @param cropRect The cropped region
+     * @return expected 3A regions output in capture result
+     */
+    public static MeteringRectangle[] getExpectedOutputRegion(
+            MeteringRectangle[] requestRegions, Rect cropRect){
+        MeteringRectangle[] resultRegions = new MeteringRectangle[requestRegions.length];
+        for (int i = 0; i < requestRegions.length; i++) {
+            Rect requestRect = requestRegions[i].getRect();
+            Rect resultRect = new Rect();
+            assertTrue("Input 3A region must intersect cropped region",
+                        resultRect.setIntersect(requestRect, cropRect));
+            resultRegions[i] = new MeteringRectangle(
+                    resultRect,
+                    requestRegions[i].getMeteringWeight());
+        }
+        return resultRegions;
+    }
+
+    /**
+     * Copy source image data to destination image.
+     *
+     * @param src The source image to be copied from.
+     * @param dst The destination image to be copied to.
+     * @throws IllegalArgumentException If the source and destination images have
+     *             different format, or one of the images is not copyable.
+     */
+    public static void imageCopy(Image src, Image dst) {
+        if (src == null || dst == null) {
+            throw new IllegalArgumentException("Images should be non-null");
+        }
+        if (src.getFormat() != dst.getFormat()) {
+            throw new IllegalArgumentException("Src and dst images should have the same format");
+        }
+        if (src.getFormat() == ImageFormat.PRIVATE ||
+                dst.getFormat() == ImageFormat.PRIVATE) {
+            throw new IllegalArgumentException("PRIVATE format images are not copyable");
+        }
+
+        // TODO: check the owner of the dst image, it must be from ImageWriter, other source may
+        // not be writable. Maybe we should add an isWritable() method in image class.
+
+        Plane[] srcPlanes = src.getPlanes();
+        Plane[] dstPlanes = dst.getPlanes();
+        ByteBuffer srcBuffer = null;
+        ByteBuffer dstBuffer = null;
+        for (int i = 0; i < srcPlanes.length; i++) {
+            srcBuffer = srcPlanes[i].getBuffer();
+            int srcPos = srcBuffer.position();
+            srcBuffer.rewind();
+            dstBuffer = dstPlanes[i].getBuffer();
+            dstBuffer.rewind();
+            dstBuffer.put(srcBuffer);
+            srcBuffer.position(srcPos);
+            dstBuffer.rewind();
+        }
+    }
+
+    /**
+     * <p>
+     * Checks whether the two images are strongly equal.
+     * </p>
+     * <p>
+     * Two images are strongly equal if and only if the data, formats, sizes,
+     * and timestamps are same. For {@link ImageFormat#PRIVATE PRIVATE} format
+     * images, the image data is not not accessible thus the data comparison is
+     * effectively skipped as the number of planes is zero.
+     * </p>
+     * <p>
+     * Note that this method compares the pixel data even outside of the crop
+     * region, which may not be necessary for general use case.
+     * </p>
+     *
+     * @param lhsImg First image to be compared with.
+     * @param rhsImg Second image to be compared with.
+     * @return true if the two images are equal, false otherwise.
+     * @throws IllegalArgumentException If either of image is null.
+     */
+    public static boolean isImageStronglyEqual(Image lhsImg, Image rhsImg) {
+        if (lhsImg == null || rhsImg == null) {
+            throw new IllegalArgumentException("Images should be non-null");
+        }
+
+        if (lhsImg.getFormat() != rhsImg.getFormat()) {
+            Log.i(TAG, "lhsImg format " + lhsImg.getFormat() + " is different with rhsImg format "
+                    + rhsImg.getFormat());
+            return false;
+        }
+
+        if (lhsImg.getWidth() != rhsImg.getWidth()) {
+            Log.i(TAG, "lhsImg width " + lhsImg.getWidth() + " is different with rhsImg width "
+                    + rhsImg.getWidth());
+            return false;
+        }
+
+        if (lhsImg.getHeight() != rhsImg.getHeight()) {
+            Log.i(TAG, "lhsImg height " + lhsImg.getHeight() + " is different with rhsImg height "
+                    + rhsImg.getHeight());
+            return false;
+        }
+
+        if (lhsImg.getTimestamp() != rhsImg.getTimestamp()) {
+            Log.i(TAG, "lhsImg timestamp " + lhsImg.getTimestamp()
+                    + " is different with rhsImg timestamp " + rhsImg.getTimestamp());
+            return false;
+        }
+
+        if (!lhsImg.getCropRect().equals(rhsImg.getCropRect())) {
+            Log.i(TAG, "lhsImg crop rect " + lhsImg.getCropRect()
+                    + " is different with rhsImg crop rect " + rhsImg.getCropRect());
+            return false;
+        }
+
+        // Compare data inside of the image.
+        Plane[] lhsPlanes = lhsImg.getPlanes();
+        Plane[] rhsPlanes = rhsImg.getPlanes();
+        ByteBuffer lhsBuffer = null;
+        ByteBuffer rhsBuffer = null;
+        for (int i = 0; i < lhsPlanes.length; i++) {
+            lhsBuffer = lhsPlanes[i].getBuffer();
+            rhsBuffer = rhsPlanes[i].getBuffer();
+            if (!lhsBuffer.equals(rhsBuffer)) {
+                Log.i(TAG, "byte buffers for plane " +  i + " don't matach.");
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Set jpeg related keys in a capture request builder.
+     *
+     * @param builder The capture request builder to set the keys inl
+     * @param exifData The exif data to set.
+     * @param thumbnailSize The thumbnail size to set.
+     * @param collector The camera error collector to collect errors.
+     */
+    public static void setJpegKeys(CaptureRequest.Builder builder, ExifTestData exifData,
+            Size thumbnailSize, CameraErrorCollector collector) {
+        builder.set(CaptureRequest.JPEG_THUMBNAIL_SIZE, thumbnailSize);
+        builder.set(CaptureRequest.JPEG_GPS_LOCATION, exifData.gpsLocation);
+        builder.set(CaptureRequest.JPEG_ORIENTATION, exifData.jpegOrientation);
+        builder.set(CaptureRequest.JPEG_QUALITY, exifData.jpegQuality);
+        builder.set(CaptureRequest.JPEG_THUMBNAIL_QUALITY,
+                exifData.thumbnailQuality);
+
+        // Validate request set and get.
+        collector.expectEquals("JPEG thumbnail size request set and get should match",
+                thumbnailSize, builder.get(CaptureRequest.JPEG_THUMBNAIL_SIZE));
+        collector.expectTrue("GPS locations request set and get should match.",
+                areGpsFieldsEqual(exifData.gpsLocation,
+                builder.get(CaptureRequest.JPEG_GPS_LOCATION)));
+        collector.expectEquals("JPEG orientation request set and get should match",
+                exifData.jpegOrientation,
+                builder.get(CaptureRequest.JPEG_ORIENTATION));
+        collector.expectEquals("JPEG quality request set and get should match",
+                exifData.jpegQuality, builder.get(CaptureRequest.JPEG_QUALITY));
+        collector.expectEquals("JPEG thumbnail quality request set and get should match",
+                exifData.thumbnailQuality,
+                builder.get(CaptureRequest.JPEG_THUMBNAIL_QUALITY));
+    }
+
+    /**
+     * Simple validation of JPEG image size and format.
+     * <p>
+     * Only validate the image object sanity. It is fast, but doesn't actually
+     * check the buffer data. Assert is used here as it make no sense to
+     * continue the test if the jpeg image captured has some serious failures.
+     * </p>
+     *
+     * @param image The captured jpeg image
+     * @param expectedSize Expected capture jpeg size
+     */
+    public static void basicValidateJpegImage(Image image, Size expectedSize) {
+        Size imageSz = new Size(image.getWidth(), image.getHeight());
+        assertTrue(
+                String.format("Image size doesn't match (expected %s, actual %s) ",
+                        expectedSize.toString(), imageSz.toString()), expectedSize.equals(imageSz));
+        assertEquals("Image format should be JPEG", ImageFormat.JPEG, image.getFormat());
+        assertNotNull("Image plane shouldn't be null", image.getPlanes());
+        assertEquals("Image plane number should be 1", 1, image.getPlanes().length);
+
+        // Jpeg decoding validate was done in ImageReaderTest, no need to duplicate the test here.
+    }
+
+    /**
+     * Verify the JPEG EXIF and JPEG related keys in a capture result are expected.
+     * - Capture request get values are same as were set.
+     * - capture result's exif data is the same as was set by
+     *   the capture request.
+     * - new tags in the result set by the camera service are
+     *   present and semantically correct.
+     *
+     * @param image The output JPEG image to verify.
+     * @param captureResult The capture result to verify.
+     * @param expectedSize The expected JPEG size.
+     * @param expectedThumbnailSize The expected thumbnail size.
+     * @param expectedExifData The expected EXIF data
+     * @param staticInfo The static metadata for the camera device.
+     * @param jpegFilename The filename to dump the jpeg to.
+     * @param collector The camera error collector to collect errors.
+     */
+    public static void verifyJpegKeys(Image image, CaptureResult captureResult, Size expectedSize,
+            Size expectedThumbnailSize, ExifTestData expectedExifData, StaticMetadata staticInfo,
+            CameraErrorCollector collector) throws Exception {
+
+        basicValidateJpegImage(image, expectedSize);
+
+        byte[] jpegBuffer = getDataFromImage(image);
+        // Have to dump into a file to be able to use ExifInterface
+        String jpegFilename = DEBUG_FILE_NAME_BASE + "/verifyJpegKeys.jpeg";
+        dumpFile(jpegFilename, jpegBuffer);
+        ExifInterface exif = new ExifInterface(jpegFilename);
+
+        if (expectedThumbnailSize.equals(new Size(0,0))) {
+            collector.expectTrue("Jpeg shouldn't have thumbnail when thumbnail size is (0, 0)",
+                    !exif.hasThumbnail());
+        } else {
+            collector.expectTrue("Jpeg must have thumbnail for thumbnail size " +
+                    expectedThumbnailSize, exif.hasThumbnail());
+        }
+
+        // Validate capture result vs. request
+        Size resultThumbnailSize = captureResult.get(CaptureResult.JPEG_THUMBNAIL_SIZE);
+        int orientationTested = expectedExifData.jpegOrientation;
+        // Legacy shim always doesn't rotate thumbnail size
+        if ((orientationTested == 90 || orientationTested == 270) &&
+                staticInfo.isHardwareLevelLimitedOrBetter()) {
+            int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
+                    /*defaultValue*/-1);
+            if (exifOrientation == ExifInterface.ORIENTATION_UNDEFINED) {
+                // Device physically rotated image+thumbnail data
+                // Expect thumbnail size to be also rotated
+                resultThumbnailSize = new Size(resultThumbnailSize.getHeight(),
+                        resultThumbnailSize.getWidth());
+            }
+        }
+
+        collector.expectEquals("JPEG thumbnail size result and request should match",
+                expectedThumbnailSize, resultThumbnailSize);
+        if (collector.expectKeyValueNotNull(captureResult, CaptureResult.JPEG_GPS_LOCATION) !=
+                null) {
+            collector.expectTrue("GPS location result and request should match.",
+                    areGpsFieldsEqual(expectedExifData.gpsLocation,
+                    captureResult.get(CaptureResult.JPEG_GPS_LOCATION)));
+        }
+        collector.expectEquals("JPEG orientation result and request should match",
+                expectedExifData.jpegOrientation,
+                captureResult.get(CaptureResult.JPEG_ORIENTATION));
+        collector.expectEquals("JPEG quality result and request should match",
+                expectedExifData.jpegQuality, captureResult.get(CaptureResult.JPEG_QUALITY));
+        collector.expectEquals("JPEG thumbnail quality result and request should match",
+                expectedExifData.thumbnailQuality,
+                captureResult.get(CaptureResult.JPEG_THUMBNAIL_QUALITY));
+
+        // Validate other exif tags for all non-legacy devices
+        if (!staticInfo.isHardwareLevelLegacy()) {
+            verifyJpegExifExtraTags(exif, expectedSize, captureResult, staticInfo, collector);
+        }
+    }
+
+    /**
+     * Get the degree of an EXIF orientation.
+     */
+    private static int getExifOrientationInDegree(int exifOrientation,
+            CameraErrorCollector collector) {
+        switch (exifOrientation) {
+            case ExifInterface.ORIENTATION_NORMAL:
+                return 0;
+            case ExifInterface.ORIENTATION_ROTATE_90:
+                return 90;
+            case ExifInterface.ORIENTATION_ROTATE_180:
+                return 180;
+            case ExifInterface.ORIENTATION_ROTATE_270:
+                return 270;
+            default:
+                collector.addMessage("It is impossible to get non 0, 90, 180, 270 degress exif" +
+                        "info based on the request orientation range");
+                return 0;
+        }
+    }
+
+    /**
+     * Validate and return the focal length.
+     *
+     * @param result Capture result to get the focal length
+     * @return Focal length from capture result or -1 if focal length is not available.
+     */
+    private static float validateFocalLength(CaptureResult result, StaticMetadata staticInfo,
+            CameraErrorCollector collector) {
+        float[] focalLengths = staticInfo.getAvailableFocalLengthsChecked();
+        Float resultFocalLength = result.get(CaptureResult.LENS_FOCAL_LENGTH);
+        if (collector.expectTrue("Focal length is invalid",
+                resultFocalLength != null && resultFocalLength > 0)) {
+            List<Float> focalLengthList =
+                    Arrays.asList(CameraTestUtils.toObject(focalLengths));
+            collector.expectTrue("Focal length should be one of the available focal length",
+                    focalLengthList.contains(resultFocalLength));
+            return resultFocalLength;
+        }
+        return -1;
+    }
+
+    /**
+     * Validate and return the aperture.
+     *
+     * @param result Capture result to get the aperture
+     * @return Aperture from capture result or -1 if aperture is not available.
+     */
+    private static float validateAperture(CaptureResult result, StaticMetadata staticInfo,
+            CameraErrorCollector collector) {
+        float[] apertures = staticInfo.getAvailableAperturesChecked();
+        Float resultAperture = result.get(CaptureResult.LENS_APERTURE);
+        if (collector.expectTrue("Capture result aperture is invalid",
+                resultAperture != null && resultAperture > 0)) {
+            List<Float> apertureList =
+                    Arrays.asList(CameraTestUtils.toObject(apertures));
+            collector.expectTrue("Aperture should be one of the available apertures",
+                    apertureList.contains(resultAperture));
+            return resultAperture;
+        }
+        return -1;
+    }
+
+    /**
+     * Return the closest value in an array of floats.
+     */
+    private static float getClosestValueInArray(float[] values, float target) {
+        int minIdx = 0;
+        float minDistance = Math.abs(values[0] - target);
+        for(int i = 0; i < values.length; i++) {
+            float distance = Math.abs(values[i] - target);
+            if (minDistance > distance) {
+                minDistance = distance;
+                minIdx = i;
+            }
+        }
+
+        return values[minIdx];
+    }
+
+    /**
+     * Return if two Location's GPS field are the same.
+     */
+    private static boolean areGpsFieldsEqual(Location a, Location b) {
+        if (a == null || b == null) {
+            return false;
+        }
+
+        return a.getTime() == b.getTime() && a.getLatitude() == b.getLatitude() &&
+                a.getLongitude() == b.getLongitude() && a.getAltitude() == b.getAltitude() &&
+                a.getProvider() == b.getProvider();
+    }
+
+    /**
+     * Verify extra tags in JPEG EXIF
+     */
+    private static void verifyJpegExifExtraTags(ExifInterface exif, Size jpegSize,
+            CaptureResult result, StaticMetadata staticInfo, CameraErrorCollector collector)
+            throws ParseException {
+        /**
+         * TAG_IMAGE_WIDTH and TAG_IMAGE_LENGTH and TAG_ORIENTATION.
+         * Orientation and exif width/height need to be tested carefully, two cases:
+         *
+         * 1. Device rotate the image buffer physically, then exif width/height may not match
+         * the requested still capture size, we need swap them to check.
+         *
+         * 2. Device use the exif tag to record the image orientation, it doesn't rotate
+         * the jpeg image buffer itself. In this case, the exif width/height should always match
+         * the requested still capture size, and the exif orientation should always match the
+         * requested orientation.
+         *
+         */
+        int exifWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, /*defaultValue*/0);
+        int exifHeight = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, /*defaultValue*/0);
+        Size exifSize = new Size(exifWidth, exifHeight);
+        // Orientation could be missing, which is ok, default to 0.
+        int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
+                /*defaultValue*/-1);
+        // Get requested orientation from result, because they should be same.
+        if (collector.expectKeyValueNotNull(result, CaptureResult.JPEG_ORIENTATION) != null) {
+            int requestedOrientation = result.get(CaptureResult.JPEG_ORIENTATION);
+            final int ORIENTATION_MIN = ExifInterface.ORIENTATION_UNDEFINED;
+            final int ORIENTATION_MAX = ExifInterface.ORIENTATION_ROTATE_270;
+            boolean orientationValid = collector.expectTrue(String.format(
+                    "Exif orientation must be in range of [%d, %d]",
+                    ORIENTATION_MIN, ORIENTATION_MAX),
+                    exifOrientation >= ORIENTATION_MIN && exifOrientation <= ORIENTATION_MAX);
+            if (orientationValid) {
+                /**
+                 * Device captured image doesn't respect the requested orientation,
+                 * which means it rotates the image buffer physically. Then we
+                 * should swap the exif width/height accordingly to compare.
+                 */
+                boolean deviceRotatedImage = exifOrientation == ExifInterface.ORIENTATION_UNDEFINED;
+
+                if (deviceRotatedImage) {
+                    // Case 1.
+                    boolean needSwap = (requestedOrientation % 180 == 90);
+                    if (needSwap) {
+                        exifSize = new Size(exifHeight, exifWidth);
+                    }
+                } else {
+                    // Case 2.
+                    collector.expectEquals("Exif orientaiton should match requested orientation",
+                            requestedOrientation, getExifOrientationInDegree(exifOrientation,
+                            collector));
+                }
+            }
+        }
+
+        /**
+         * Ideally, need check exifSize == jpegSize == actual buffer size. But
+         * jpegSize == jpeg decode bounds size(from jpeg jpeg frame
+         * header, not exif) was validated in ImageReaderTest, no need to
+         * validate again here.
+         */
+        collector.expectEquals("Exif size should match jpeg capture size", jpegSize, exifSize);
+
+        // TAG_DATETIME, it should be local time
+        long currentTimeInMs = System.currentTimeMillis();
+        long currentTimeInSecond = currentTimeInMs / 1000;
+        Date date = new Date(currentTimeInMs);
+        String localDatetime = new SimpleDateFormat("yyyy:MM:dd HH:").format(date);
+        String dateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
+        if (collector.expectTrue("Exif TAG_DATETIME shouldn't be null", dateTime != null)) {
+            collector.expectTrue("Exif TAG_DATETIME is wrong",
+                    dateTime.length() == EXIF_DATETIME_LENGTH);
+            long exifTimeInSecond =
+                    new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").parse(dateTime).getTime() / 1000;
+            long delta = currentTimeInSecond - exifTimeInSecond;
+            collector.expectTrue("Capture time deviates too much from the current time",
+                    Math.abs(delta) < EXIF_DATETIME_ERROR_MARGIN_SEC);
+            // It should be local time.
+            collector.expectTrue("Exif date time should be local time",
+                    dateTime.startsWith(localDatetime));
+        }
+
+        // TAG_FOCAL_LENGTH.
+        float[] focalLengths = staticInfo.getAvailableFocalLengthsChecked();
+        float exifFocalLength = (float)exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, -1);
+        collector.expectEquals("Focal length should match",
+                getClosestValueInArray(focalLengths, exifFocalLength),
+                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);
+
+        // TAG_EXPOSURE_TIME
+        // ExifInterface API gives exposure time value in the form of float instead of rational
+        String exposureTime = exif.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
+        collector.expectNotNull("Exif TAG_EXPOSURE_TIME shouldn't be null", exposureTime);
+        if (staticInfo.areKeysAvailable(CaptureResult.SENSOR_EXPOSURE_TIME)) {
+            if (exposureTime != null) {
+                double exposureTimeValue = Double.parseDouble(exposureTime);
+                long expTimeResult = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
+                double expected = expTimeResult / 1e9;
+                double tolerance = expected * EXIF_EXPOSURE_TIME_ERROR_MARGIN_RATIO;
+                tolerance = Math.max(tolerance, EXIF_EXPOSURE_TIME_MIN_ERROR_MARGIN_SEC);
+                collector.expectEquals("Exif exposure time doesn't match", expected,
+                        exposureTimeValue, tolerance);
+            }
+        }
+
+        // TAG_APERTURE
+        // ExifInterface API gives aperture value in the form of float instead of rational
+        String exifAperture = exif.getAttribute(ExifInterface.TAG_APERTURE);
+        collector.expectNotNull("Exif TAG_APERTURE shouldn't be null", exifAperture);
+        if (staticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES)) {
+            float[] apertures = staticInfo.getAvailableAperturesChecked();
+            if (exifAperture != null) {
+                float apertureValue = Float.parseFloat(exifAperture);
+                collector.expectEquals("Aperture value should match",
+                        getClosestValueInArray(apertures, apertureValue),
+                        apertureValue, EXIF_APERTURE_ERROR_MARGIN);
+                // More checks for aperture.
+                collector.expectEquals("Exif aperture length should match capture result",
+                        validateAperture(result, staticInfo, collector), apertureValue);
+            }
+        }
+
+        /**
+         * TAG_FLASH. TODO: For full devices, can check a lot more info
+         * (http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html#Flash)
+         */
+        String flash = exif.getAttribute(ExifInterface.TAG_FLASH);
+        collector.expectNotNull("Exif TAG_FLASH shouldn't be null", flash);
+
+        /**
+         * TAG_WHITE_BALANCE. TODO: For full devices, with the DNG tags, we
+         * should be able to cross-check android.sensor.referenceIlluminant.
+         */
+        String whiteBalance = exif.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
+        collector.expectNotNull("Exif TAG_WHITE_BALANCE shouldn't be null", whiteBalance);
+
+        // TAG_MAKE
+        String make = exif.getAttribute(ExifInterface.TAG_MAKE);
+        collector.expectEquals("Exif TAG_MAKE is incorrect", Build.MANUFACTURER, make);
+
+        // TAG_MODEL
+        String model = exif.getAttribute(ExifInterface.TAG_MODEL);
+        collector.expectEquals("Exif TAG_MODEL is incorrect", Build.MODEL, model);
+
+
+        // TAG_ISO
+        int iso = exif.getAttributeInt(ExifInterface.TAG_ISO, /*defaultValue*/-1);
+        if (staticInfo.areKeysAvailable(CaptureResult.SENSOR_SENSITIVITY)) {
+            int expectedIso = result.get(CaptureResult.SENSOR_SENSITIVITY);
+            collector.expectEquals("Exif TAG_ISO is incorrect", expectedIso, iso);
+        }
+
+        // TAG_DATETIME_DIGITIZED (a.k.a Create time for digital cameras).
+        String digitizedTime = exif.getAttribute(ExifInterface.TAG_DATETIME_DIGITIZED);
+        collector.expectNotNull("Exif TAG_DATETIME_DIGITIZED shouldn't be null", digitizedTime);
+        if (digitizedTime != null) {
+            String expectedDateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
+            collector.expectNotNull("Exif TAG_DATETIME shouldn't be null", expectedDateTime);
+            if (expectedDateTime != null) {
+                collector.expectEquals("dataTime should match digitizedTime",
+                        expectedDateTime, digitizedTime);
+            }
+        }
+
+        /**
+         * TAG_SUBSEC_TIME. Since the sub second tag strings are truncated to at
+         * most 9 digits in ExifInterface implementation, use getAttributeInt to
+         * sanitize it. When the default value -1 is returned, it means that
+         * this exif tag either doesn't exist or is a non-numerical invalid
+         * string. Same rule applies to the rest of sub second tags.
+         */
+        int subSecTime = exif.getAttributeInt(ExifInterface.TAG_SUBSEC_TIME, /*defaultValue*/-1);
+        collector.expectTrue("Exif TAG_SUBSEC_TIME value is null or invalid!", subSecTime > 0);
+
+        // TAG_SUBSEC_TIME_ORIG
+        int subSecTimeOrig = exif.getAttributeInt(ExifInterface.TAG_SUBSEC_TIME_ORIG,
+                /*defaultValue*/-1);
+        collector.expectTrue("Exif TAG_SUBSEC_TIME_ORIG value is null or invalid!",
+                subSecTimeOrig > 0);
+
+        // TAG_SUBSEC_TIME_DIG
+        int subSecTimeDig = exif.getAttributeInt(ExifInterface.TAG_SUBSEC_TIME_DIG,
+                /*defaultValue*/-1);
+        collector.expectTrue(
+                "Exif TAG_SUBSEC_TIME_DIG value is null or invalid!", subSecTimeDig > 0);
+    }
+
+
+    /**
+     * Immutable class wrapping the exif test data.
+     */
+    public static class ExifTestData {
+        public final Location gpsLocation;
+        public final int jpegOrientation;
+        public final byte jpegQuality;
+        public final byte thumbnailQuality;
+
+        public ExifTestData(Location location, int orientation,
+                byte jpgQuality, byte thumbQuality) {
+            gpsLocation = location;
+            jpegOrientation = orientation;
+            jpegQuality = jpgQuality;
+            thumbnailQuality = thumbQuality;
+        }
+    }
+
+    public static Size getPreviewSizeBound(WindowManager windowManager, Size bound) {
+        Display display = windowManager.getDefaultDisplay();
+
+        int width = display.getWidth();
+        int height = display.getHeight();
+
+        if (height > width) {
+            height = width;
+            width = display.getHeight();
+        }
+
+        if (bound.getWidth() <= width &&
+            bound.getHeight() <= height)
+            return bound;
+        else
+            return new Size(width, height);
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
new file mode 100644
index 0000000..dd4e3e3
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureRequestTest.java
@@ -0,0 +1,2420 @@
+/*
+ * Copyright 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static android.hardware.camera2.CameraCharacteristics.*;
+
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+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.util.Log;
+import android.util.Range;
+import android.util.Rational;
+import android.util.Size;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * <p>
+ * Basic test for camera CaptureRequest key controls.
+ * </p>
+ * <p>
+ * Several test categories are covered: manual sensor control, 3A control,
+ * manual ISP control and other per-frame control and synchronization.
+ * </p>
+ */
+public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "CaptureRequestTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final int NUM_FRAMES_VERIFIED = 15;
+    private static final int NUM_FACE_DETECTION_FRAMES_VERIFIED = 60;
+    /** 30ms exposure time must be supported by full capability devices. */
+    private static final long DEFAULT_EXP_TIME_NS = 30000000L;
+    private static final int DEFAULT_SENSITIVITY = 100;
+    private static final int RGGB_COLOR_CHANNEL_COUNT = 4;
+    private static final int MAX_SHADING_MAP_SIZE = 64 * 64 * RGGB_COLOR_CHANNEL_COUNT;
+    private static final int MIN_SHADING_MAP_SIZE = 1 * 1 * RGGB_COLOR_CHANNEL_COUNT;
+    private static final long IGNORE_REQUESTED_EXPOSURE_TIME_CHECK = -1L;
+    private static final long EXPOSURE_TIME_BOUNDARY_50HZ_NS = 10000000L; // 10ms
+    private static final long EXPOSURE_TIME_BOUNDARY_60HZ_NS = 8333333L; // 8.3ms, Approximation.
+    private static final long EXPOSURE_TIME_ERROR_MARGIN_NS = 100000L; // 100us, Approximation.
+    private static final float EXPOSURE_TIME_ERROR_MARGIN_RATE = 0.03f; // 3%, Approximation.
+    private static final float SENSITIVITY_ERROR_MARGIN_RATE = 0.03f; // 3%, Approximation.
+    private static final int DEFAULT_NUM_EXPOSURE_TIME_STEPS = 3;
+    private static final int DEFAULT_NUM_SENSITIVITY_STEPS = 16;
+    private static final int DEFAULT_SENSITIVITY_STEP_SIZE = 100;
+    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;
+    // 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
+    private static final float FOCUS_DISTANCE_ERROR_PERCENT_UNCALIBRATED = 0.25f;
+    // 10 percent error margin for approximate device
+    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;
+
+    // Linear tone mapping curve example.
+    private static final float[] TONEMAP_CURVE_LINEAR = {0, 0, 1.0f, 1.0f};
+    // Standard sRGB tone mapping, per IEC 61966-2-1:1999, with 16 control points.
+    private static final float[] TONEMAP_CURVE_SRGB = {
+            0.0000f, 0.0000f, 0.0667f, 0.2864f, 0.1333f, 0.4007f, 0.2000f, 0.4845f,
+            0.2667f, 0.5532f, 0.3333f, 0.6125f, 0.4000f, 0.6652f, 0.4667f, 0.7130f,
+            0.5333f, 0.7569f, 0.6000f, 0.7977f, 0.6667f, 0.8360f, 0.7333f, 0.8721f,
+            0.8000f, 0.9063f, 0.8667f, 0.9389f, 0.9333f, 0.9701f, 1.0000f, 1.0000f
+    };
+    private final Rational ZERO_R = new Rational(0, 1);
+    private final Rational ONE_R = new Rational(1, 1);
+
+    private final int NUM_ALGORITHMS = 3; // AE, AWB and AF
+    private final int INDEX_ALGORITHM_AE = 0;
+    private final int INDEX_ALGORITHM_AWB = 1;
+    private final int INDEX_ALGORITHM_AF = 2;
+
+    private enum TorchSeqState {
+        RAMPING_UP,
+        FIRED,
+        RAMPING_DOWN
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Test black level lock when exposure value change.
+     * <p>
+     * When {@link CaptureRequest#BLACK_LEVEL_LOCK} is true in a request, the
+     * camera device should lock the black level. When the exposure values are changed,
+     * the camera may require reset black level Since changes to certain capture
+     * parameters (such as exposure time) may require resetting of black level
+     * compensation. However, the black level must remain locked after exposure
+     * value changes (when requests have lock ON).
+     * </p>
+     */
+    public void testBlackLevelLock() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i]);
+
+                if (!mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                    continue;
+                }
+
+                SimpleCaptureCallback listener = new SimpleCaptureCallback();
+                CaptureRequest.Builder requestBuilder =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+                // Start with default manual exposure time, with black level being locked.
+                requestBuilder.set(CaptureRequest.BLACK_LEVEL_LOCK, true);
+                changeExposure(requestBuilder, DEFAULT_EXP_TIME_NS, DEFAULT_SENSITIVITY);
+
+                Size previewSz =
+                        getMaxPreviewSize(mCamera.getId(), mCameraManager,
+                        getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
+
+                startPreview(requestBuilder, previewSz, listener);
+                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+                // No lock OFF state is allowed as the exposure is not changed.
+                verifyBlackLevelLockResults(listener, NUM_FRAMES_VERIFIED, /*maxLockOffCnt*/0);
+
+                // Double the exposure time and gain, with black level still being locked.
+                changeExposure(requestBuilder, DEFAULT_EXP_TIME_NS * 2, DEFAULT_SENSITIVITY * 2);
+                listener = new SimpleCaptureCallback();
+                startPreview(requestBuilder, previewSz, listener);
+                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+                // Allow at most one lock OFF state as the exposure is changed once.
+                verifyBlackLevelLockResults(listener, NUM_FRAMES_VERIFIED, /*maxLockOffCnt*/1);
+
+                stopPreview();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Basic lens shading map request test.
+     * <p>
+     * When {@link CaptureRequest#SHADING_MODE} is set to OFF, no lens shading correction will
+     * be applied by the camera device, and an identity lens shading map data
+     * will be provided if {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE} is ON.
+     * </p>
+     * <p>
+     * When {@link CaptureRequest#SHADING_MODE} is set to other modes, lens shading correction
+     * will be applied by the camera device. The lens shading map data can be
+     * requested by setting {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE} to ON.
+     * </p>
+     */
+    public void testLensShadingMap() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i]);
+
+                if (!mStaticInfo.isManualLensShadingMapSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " doesn't support lens shading controls, skipping test");
+                    continue;
+                }
+
+                List<Integer> lensShadingMapModes = Arrays.asList(CameraTestUtils.toObject(
+                        mStaticInfo.getAvailableLensShadingMapModesChecked()));
+
+                if (!lensShadingMapModes.contains(STATISTICS_LENS_SHADING_MAP_MODE_ON)) {
+                    continue;
+                }
+
+                SimpleCaptureCallback listener = new SimpleCaptureCallback();
+                CaptureRequest.Builder requestBuilder =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                requestBuilder.set(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE,
+                        STATISTICS_LENS_SHADING_MAP_MODE_ON);
+
+                Size previewSz =
+                        getMaxPreviewSize(mCamera.getId(), mCameraManager,
+                        getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
+                List<Integer> lensShadingModes = Arrays.asList(CameraTestUtils.toObject(
+                        mStaticInfo.getAvailableLensShadingModesChecked()));
+
+                // Shading map mode OFF, lensShadingMapMode ON, camera device
+                // should output unity maps.
+                if (lensShadingModes.contains(SHADING_MODE_OFF)) {
+                    requestBuilder.set(CaptureRequest.SHADING_MODE, SHADING_MODE_OFF);
+                    listener = new SimpleCaptureCallback();
+                    startPreview(requestBuilder, previewSz, listener);
+                    waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+                    verifyShadingMap(listener, NUM_FRAMES_VERIFIED, SHADING_MODE_OFF);
+                }
+
+                // Shading map mode FAST, lensShadingMapMode ON, camera device
+                // should output valid maps.
+                if (lensShadingModes.contains(SHADING_MODE_FAST)) {
+                    requestBuilder.set(CaptureRequest.SHADING_MODE, SHADING_MODE_FAST);
+
+                    listener = new SimpleCaptureCallback();
+                    startPreview(requestBuilder, previewSz, listener);
+                    waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+                    // Allow at most one lock OFF state as the exposure is changed once.
+                    verifyShadingMap(listener, NUM_FRAMES_VERIFIED, SHADING_MODE_FAST);
+                }
+
+                // Shading map mode HIGH_QUALITY, lensShadingMapMode ON, camera device
+                // should output valid maps.
+                if (lensShadingModes.contains(SHADING_MODE_HIGH_QUALITY)) {
+                    requestBuilder.set(CaptureRequest.SHADING_MODE, SHADING_MODE_HIGH_QUALITY);
+
+                    listener = new SimpleCaptureCallback();
+                    startPreview(requestBuilder, previewSz, listener);
+                    waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+                    verifyShadingMap(listener, NUM_FRAMES_VERIFIED, SHADING_MODE_HIGH_QUALITY);
+                }
+
+                stopPreview();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE} control.
+     * <p>
+     * Test all available anti-banding modes, check if the exposure time adjustment is
+     * correct.
+     * </p>
+     */
+    public void testAntiBandingModes() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                openDevice(mCameraIds[i]);
+
+                // Without manual sensor control, exposure time cannot be verified
+                if (!mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                    continue;
+                }
+
+                int[] modes = mStaticInfo.getAeAvailableAntiBandingModesChecked();
+
+                Size previewSz =
+                        getMaxPreviewSize(mCamera.getId(), mCameraManager,
+                        getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
+
+                for (int mode : modes) {
+                    antiBandingTestByMode(previewSz, mode);
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+
+    }
+
+    /**
+     * Test AE mode and lock.
+     *
+     * <p>
+     * For AE lock, when it is locked, exposure parameters shouldn't be changed.
+     * For AE modes, each mode should satisfy the per frame controls defined in
+     * API specifications.
+     * </p>
+     */
+    public void testAeModeAndLock() 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;
+                }
+
+                Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
+
+                // Update preview surface with given size for all sub-tests.
+                updatePreviewSurface(maxPreviewSz);
+
+                // Test aeMode and lock
+                int[] aeModes = mStaticInfo.getAeAvailableModesChecked();
+                for (int mode : aeModes) {
+                    aeModeAndLockTestByMode(mode);
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /** Test {@link CaptureRequest#FLASH_MODE} control.
+     * <p>
+     * For each {@link CaptureRequest#FLASH_MODE} mode, test the flash control
+     * and {@link CaptureResult#FLASH_STATE} result.
+     * </p>
+     */
+    public void testFlashControl() 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;
+                }
+
+                SimpleCaptureCallback listener = new SimpleCaptureCallback();
+                CaptureRequest.Builder requestBuilder =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+                Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
+
+                startPreview(requestBuilder, maxPreviewSz, listener);
+
+                // Flash control can only be used when the AE mode is ON or OFF.
+                flashTestByAeMode(listener, CaptureRequest.CONTROL_AE_MODE_ON);
+
+                // LEGACY won't support AE mode OFF
+                boolean aeOffModeSupported = false;
+                for (int aeMode : mStaticInfo.getAeAvailableModesChecked()) {
+                    if (aeMode == CaptureRequest.CONTROL_AE_MODE_OFF) {
+                        aeOffModeSupported = true;
+                    }
+                }
+                if (aeOffModeSupported) {
+                    flashTestByAeMode(listener, CaptureRequest.CONTROL_AE_MODE_OFF);
+                }
+
+                stopPreview();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test face detection modes and results.
+     */
+    public void testFaceDetection() 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;
+                }
+                faceDetectionTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test tone map modes and controls.
+     */
+    public void testToneMapControl() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isManualToneMapSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " doesn't support tone mapping controls, skipping test");
+                    continue;
+                }
+                toneMapTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test color correction modes and controls.
+     */
+    public void testColorCorrectionControl() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isColorCorrectionSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " doesn't support color correction controls, skipping test");
+                    continue;
+                }
+                colorCorrectionTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    public void testEdgeModeControl() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isEdgeModeControlSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " doesn't support EDGE_MODE controls, skipping test");
+                    continue;
+                }
+
+                edgeModesTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test focus distance control.
+     */
+    public void testFocusDistanceControl() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.hasFocuser()) {
+                    Log.i(TAG, "Camera " + id + " has no focuser, skipping test");
+                    continue;
+                }
+
+                if (!mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                    Log.i(TAG, "Camera " + id +
+                            " does not support MANUAL_SENSOR, skipping test");
+                    continue;
+                }
+
+                focusDistanceTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    public void testNoiseReductionModeControl() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isNoiseReductionModeControlSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " doesn't support noise reduction mode, skipping test");
+                    continue;
+                }
+
+                noiseReductionModeTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test AWB lock control.
+     *
+     * <p>The color correction gain and transform shouldn't be changed when AWB is locked.</p>
+     */
+    public void testAwbModeAndLock() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                awbModeAndLockTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test different AF modes.
+     */
+    public void testAfModes() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                afModeTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test video and optical stabilizations.
+     */
+    public void testCameraStabilizations() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                List<Key<?>> keys = mStaticInfo.getCharacteristics().getKeys();
+                if (!(keys.contains(
+                        CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES) ||
+                        keys.contains(
+                                CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION))) {
+                    Log.i(TAG, "Camera " + id + " doesn't support any stabilization modes");
+                    continue;
+                }
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                stabilizationTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test digitalZoom (center wise and non-center wise), validate the returned crop regions.
+     * The max preview size is used for each camera.
+     */
+    public void testDigitalZoom() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+                digitalZoomTestByCamera(maxPreviewSize);
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test digital zoom and all preview size combinations.
+     * TODO: this and above test should all be moved to preview test class.
+     */
+    public void testDigitalZoomPreviewCombinations() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                digitalZoomPreviewCombinationTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test scene mode controls.
+     */
+    public void testSceneModes() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (mStaticInfo.isSceneModeSupported()) {
+                    sceneModeTestByCamera();
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test effect mode controls.
+     */
+    public void testEffectModes() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                effectModeTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    // TODO: add 3A state machine test.
+
+    private void noiseReductionModeTestByCamera() throws Exception {
+        Size maxPrevSize = mOrderedPreviewSizes.get(0);
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        int[] availableModes = mStaticInfo.getAvailableNoiseReductionModesChecked();
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        startPreview(requestBuilder, maxPrevSize, resultListener);
+
+        for (int mode : availableModes) {
+            requestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, mode);
+            resultListener = new SimpleCaptureCallback();
+            mSession.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
+            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+            verifyCaptureResultForKey(CaptureResult.NOISE_REDUCTION_MODE, mode,
+                    resultListener, NUM_FRAMES_VERIFIED);
+
+            // Test that OFF and FAST mode should not slow down the frame rate.
+            if (mode == CaptureRequest.NOISE_REDUCTION_MODE_OFF ||
+                    mode == CaptureRequest.NOISE_REDUCTION_MODE_FAST) {
+                verifyFpsNotSlowDown(requestBuilder, NUM_FRAMES_VERIFIED);
+            }
+        }
+
+        stopPreview();
+    }
+
+    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);
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        startPreview(requestBuilder, maxPrevSize, resultListener);
+
+        CaptureRequest request;
+        float[] resultDistances = new float[testDistances.length];
+        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);
+            if (VERBOSE) {
+                Log.v(TAG, "Capture request focus distance: " + testDistances[i] + " result: "
+                        + resultDistances[i]);
+            }
+        }
+
+        // Verify the monotonicity
+        mCollector.checkArrayMonotonicityAndNotAllEqual(CameraTestUtils.toObject(resultDistances),
+                /*ascendingOrder*/true);
+
+        if (mStaticInfo.getCharacteristics().getKeys().
+                contains(CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE)) {
+
+            // Test hyperfocal distance optionally
+            float hyperFocalDistance = mStaticInfo.getHyperfocalDistanceChecked();
+            if (hyperFocalDistance > 0) {
+                requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, hyperFocalDistance);
+                request = requestBuilder.build();
+                resultListener = new SimpleCaptureCallback();
+                mSession.setRepeatingRequest(request, resultListener, mHandler);
+                waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+                // 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,
+                        hyperFocalDistance * (1.0f - errorMargin),
+                        hyperFocalDistance * (1.0f + 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
+     */
+    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?
+        }
+
+        float minValue = 0;
+        float maxValue = mStaticInfo.getMinimumFocusDistanceChecked();
+        mCollector.expectInRange("Result focus distance is out of range",
+                resultDistance, minValue, maxValue);
+
+        return resultDistance;
+    }
+
+    /**
+     * Verify edge mode control results.
+     */
+    private void edgeModesTestByCamera() throws Exception {
+        Size maxPrevSize = mOrderedPreviewSizes.get(0);
+        int[] edgeModes = mStaticInfo.getAvailableEdgeModesChecked();
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        startPreview(requestBuilder, maxPrevSize, resultListener);
+
+        for (int mode : edgeModes) {
+            requestBuilder.set(CaptureRequest.EDGE_MODE, mode);
+            resultListener = new SimpleCaptureCallback();
+            mSession.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
+            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+            verifyCaptureResultForKey(CaptureResult.EDGE_MODE, mode, resultListener,
+                    NUM_FRAMES_VERIFIED);
+
+            // Test that OFF and FAST mode should not slow down the frame rate.
+            if (mode == CaptureRequest.EDGE_MODE_OFF ||
+                    mode == CaptureRequest.EDGE_MODE_FAST) {
+                verifyFpsNotSlowDown(requestBuilder, NUM_FRAMES_VERIFIED);
+            }
+        }
+
+        stopPreview();
+    }
+
+    /**
+     * Test color correction controls.
+     *
+     * <p>Test different color correction modes. For TRANSFORM_MATRIX, only test
+     * the unit gain and identity transform.</p>
+     */
+    private void colorCorrectionTestByCamera() throws Exception {
+        CaptureRequest request;
+        CaptureResult result;
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
+        updatePreviewSurface(maxPreviewSz);
+        CaptureRequest.Builder manualRequestBuilder = createRequestForPreview();
+        CaptureRequest.Builder previewRequestBuilder = createRequestForPreview();
+        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+
+        startPreview(previewRequestBuilder, maxPreviewSz, listener);
+
+        // Default preview result should give valid color correction metadata.
+        result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        validateColorCorrectionResult(result,
+                previewRequestBuilder.get(CaptureRequest.COLOR_CORRECTION_MODE));
+        int colorCorrectionMode = CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX;
+        // TRANSFORM_MATRIX mode
+        // Only test unit gain and identity transform
+        List<Integer> availableControlModes = Arrays.asList(
+                CameraTestUtils.toObject(mStaticInfo.getAvailableControlModesChecked()));
+        List<Integer> availableAwbModes = Arrays.asList(
+                CameraTestUtils.toObject(mStaticInfo.getAwbAvailableModesChecked()));
+        boolean isManualCCSupported =
+                availableControlModes.contains(CaptureRequest.CONTROL_MODE_OFF) ||
+                availableAwbModes.contains(CaptureRequest.CONTROL_AWB_MODE_OFF);
+        if (isManualCCSupported) {
+            if (!availableControlModes.contains(CaptureRequest.CONTROL_MODE_OFF)) {
+                // Only manual AWB mode is supported
+                manualRequestBuilder.set(CaptureRequest.CONTROL_MODE,
+                        CaptureRequest.CONTROL_MODE_AUTO);
+                manualRequestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,
+                        CaptureRequest.CONTROL_AWB_MODE_OFF);
+            } else {
+                // All 3A manual controls are supported, it doesn't matter what we set for AWB mode.
+                manualRequestBuilder.set(CaptureRequest.CONTROL_MODE,
+                        CaptureRequest.CONTROL_MODE_OFF);
+            }
+
+            RggbChannelVector UNIT_GAIN = new RggbChannelVector(1.0f, 1.0f, 1.0f, 1.0f);
+
+            ColorSpaceTransform IDENTITY_TRANSFORM = new ColorSpaceTransform(
+                new Rational[] {
+                    ONE_R, ZERO_R, ZERO_R,
+                    ZERO_R, ONE_R, ZERO_R,
+                    ZERO_R, ZERO_R, ONE_R
+                });
+
+            manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, colorCorrectionMode);
+            manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_GAINS, UNIT_GAIN);
+            manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_TRANSFORM, IDENTITY_TRANSFORM);
+            request = manualRequestBuilder.build();
+            mSession.capture(request, listener, mHandler);
+            result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
+            RggbChannelVector gains = result.get(CaptureResult.COLOR_CORRECTION_GAINS);
+            ColorSpaceTransform transform = result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM);
+            validateColorCorrectionResult(result, colorCorrectionMode);
+            mCollector.expectEquals("control mode result/request mismatch",
+                    CaptureResult.CONTROL_MODE_OFF, result.get(CaptureResult.CONTROL_MODE));
+            mCollector.expectEquals("Color correction gain result/request mismatch",
+                    UNIT_GAIN, gains);
+            mCollector.expectEquals("Color correction gain result/request mismatch",
+                    IDENTITY_TRANSFORM, transform);
+
+        }
+
+        // FAST mode
+        colorCorrectionMode = CaptureRequest.COLOR_CORRECTION_MODE_FAST;
+        manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
+        manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, colorCorrectionMode);
+        request = manualRequestBuilder.build();
+        mSession.capture(request, listener, mHandler);
+        result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
+        validateColorCorrectionResult(result, colorCorrectionMode);
+        mCollector.expectEquals("control mode result/request mismatch",
+                CaptureResult.CONTROL_MODE_AUTO, result.get(CaptureResult.CONTROL_MODE));
+
+        // HIGH_QUALITY mode
+        colorCorrectionMode = CaptureRequest.COLOR_CORRECTION_MODE_HIGH_QUALITY;
+        manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
+        manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, colorCorrectionMode);
+        request = manualRequestBuilder.build();
+        mSession.capture(request, listener, mHandler);
+        result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
+        validateColorCorrectionResult(result, colorCorrectionMode);
+        mCollector.expectEquals("control mode result/request mismatch",
+                CaptureResult.CONTROL_MODE_AUTO, result.get(CaptureResult.CONTROL_MODE));
+    }
+
+    private void validateColorCorrectionResult(CaptureResult result, int colorCorrectionMode) {
+        final RggbChannelVector ZERO_GAINS = new RggbChannelVector(0, 0, 0, 0);
+        final int TRANSFORM_SIZE = 9;
+        Rational[] zeroTransform = new Rational[TRANSFORM_SIZE];
+        Arrays.fill(zeroTransform, ZERO_R);
+        final ColorSpaceTransform ZERO_TRANSFORM = new ColorSpaceTransform(zeroTransform);
+
+        RggbChannelVector resultGain;
+        if ((resultGain = mCollector.expectKeyValueNotNull(result,
+                CaptureResult.COLOR_CORRECTION_GAINS)) != null) {
+            mCollector.expectKeyValueNotEquals(result,
+                    CaptureResult.COLOR_CORRECTION_GAINS, ZERO_GAINS);
+        }
+
+        ColorSpaceTransform resultTransform;
+        if ((resultTransform = mCollector.expectKeyValueNotNull(result,
+                CaptureResult.COLOR_CORRECTION_TRANSFORM)) != null) {
+            mCollector.expectKeyValueNotEquals(result,
+                    CaptureResult.COLOR_CORRECTION_TRANSFORM, ZERO_TRANSFORM);
+        }
+
+        mCollector.expectEquals("color correction mode result/request mismatch",
+                colorCorrectionMode, result.get(CaptureResult.COLOR_CORRECTION_MODE));
+    }
+
+    /**
+     * Test flash mode control by AE mode.
+     * <p>
+     * Only allow AE mode ON or OFF, because other AE mode could run into conflict with
+     * flash manual control. This function expects the camera to already have an active
+     * repeating request and be sending results to the listener.
+     * </p>
+     *
+     * @param listener The Capture listener that is used to wait for capture result
+     * @param aeMode The AE mode for flash to test with
+     */
+    private void flashTestByAeMode(SimpleCaptureCallback listener, int aeMode) throws Exception {
+        CaptureResult result;
+        final int NUM_FLASH_REQUESTS_TESTED = 10;
+        CaptureRequest.Builder requestBuilder = createRequestForPreview();
+
+        if (aeMode == CaptureRequest.CONTROL_AE_MODE_ON) {
+            requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, aeMode);
+        } else if (aeMode == CaptureRequest.CONTROL_AE_MODE_OFF) {
+            changeExposure(requestBuilder, DEFAULT_EXP_TIME_NS, DEFAULT_SENSITIVITY);
+        } else {
+            throw new IllegalArgumentException("This test only works when AE mode is ON or OFF");
+        }
+
+        mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+        waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+        // For camera that doesn't have flash unit, flash state should always be UNAVAILABLE.
+        if (mStaticInfo.getFlashInfoChecked() == false) {
+            for (int i = 0; i < NUM_FLASH_REQUESTS_TESTED; i++) {
+                result = listener.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
+                mCollector.expectEquals("No flash unit available, flash state must be UNAVAILABLE"
+                        + "for AE mode " + aeMode, CaptureResult.FLASH_STATE_UNAVAILABLE,
+                        result.get(CaptureResult.FLASH_STATE));
+            }
+
+            return;
+        }
+
+        // Test flash SINGLE mode control. Wait for flash state to be READY first.
+        if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            waitForResultValue(listener, CaptureResult.FLASH_STATE, CaptureResult.FLASH_STATE_READY,
+                    NUM_RESULTS_WAIT_TIMEOUT);
+        } // else the settings were already waited on earlier
+
+        requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE);
+        CaptureRequest flashSinglerequest = requestBuilder.build();
+
+        int flashModeSingleRequests = captureRequestsSynchronized(
+                flashSinglerequest, listener, mHandler);
+        waitForNumResults(listener, flashModeSingleRequests - 1);
+        result = listener.getCaptureResultForRequest(flashSinglerequest, NUM_RESULTS_WAIT_TIMEOUT);
+        // Result mode must be SINGLE, state must be FIRED.
+        mCollector.expectEquals("Flash mode result must be SINGLE",
+                CaptureResult.FLASH_MODE_SINGLE, result.get(CaptureResult.FLASH_MODE));
+        mCollector.expectEquals("Flash state result must be FIRED",
+                CaptureResult.FLASH_STATE_FIRED, result.get(CaptureResult.FLASH_STATE));
+
+        // Test flash TORCH mode control.
+        requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
+        CaptureRequest torchRequest = requestBuilder.build();
+
+        int flashModeTorchRequests = captureRequestsSynchronized(torchRequest,
+                NUM_FLASH_REQUESTS_TESTED, listener, mHandler);
+        waitForNumResults(listener, flashModeTorchRequests - NUM_FLASH_REQUESTS_TESTED);
+
+        // Verify the results
+        TorchSeqState state = TorchSeqState.RAMPING_UP;
+        for (int i = 0; i < NUM_FLASH_REQUESTS_TESTED; i++) {
+            result = listener.getCaptureResultForRequest(torchRequest,
+                    NUM_RESULTS_WAIT_TIMEOUT);
+            int flashMode = result.get(CaptureResult.FLASH_MODE);
+            int flashState = result.get(CaptureResult.FLASH_STATE);
+            // Result mode must be TORCH
+            mCollector.expectEquals("Flash mode result " + i + " must be TORCH",
+                    CaptureResult.FLASH_MODE_TORCH, result.get(CaptureResult.FLASH_MODE));
+            if (state == TorchSeqState.RAMPING_UP &&
+                    flashState == CaptureResult.FLASH_STATE_FIRED) {
+                state = TorchSeqState.FIRED;
+            } else if (state == TorchSeqState.FIRED &&
+                    flashState == CaptureResult.FLASH_STATE_PARTIAL) {
+                state = TorchSeqState.RAMPING_DOWN;
+            }
+
+            if (i == 0 && mStaticInfo.isPerFrameControlSupported()) {
+                mCollector.expectTrue(
+                        "Per frame control device must enter FIRED state on first torch request",
+                        state == TorchSeqState.FIRED);
+            }
+
+            if (state == TorchSeqState.FIRED) {
+                mCollector.expectEquals("Flash state result " + i + " must be FIRED",
+                        CaptureResult.FLASH_STATE_FIRED, result.get(CaptureResult.FLASH_STATE));
+            } else {
+                mCollector.expectEquals("Flash state result " + i + " must be PARTIAL",
+                        CaptureResult.FLASH_STATE_PARTIAL, result.get(CaptureResult.FLASH_STATE));
+            }
+        }
+        mCollector.expectTrue("Torch state FIRED never seen",
+                state == TorchSeqState.FIRED || state == TorchSeqState.RAMPING_DOWN);
+
+        // Test flash OFF mode control
+        requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
+        CaptureRequest flashOffrequest = requestBuilder.build();
+
+        int flashModeOffRequests = captureRequestsSynchronized(flashOffrequest, listener, mHandler);
+        waitForNumResults(listener, flashModeOffRequests - 1);
+        result = listener.getCaptureResultForRequest(flashOffrequest, NUM_RESULTS_WAIT_TIMEOUT);
+        mCollector.expectEquals("Flash mode result must be OFF", CaptureResult.FLASH_MODE_OFF,
+                result.get(CaptureResult.FLASH_MODE));
+    }
+
+    private void verifyAntiBandingMode(SimpleCaptureCallback listener, int numFramesVerified,
+            int mode, boolean isAeManual, long requestExpTime) throws Exception {
+        // Skip the first a couple of frames as antibanding may not be fully up yet.
+        final int NUM_FRAMES_SKIPPED = 5;
+        for (int i = 0; i < NUM_FRAMES_SKIPPED; i++) {
+            listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        }
+
+        for (int i = 0; i < numFramesVerified; i++) {
+            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            Long resultExpTime = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
+            assertNotNull("Exposure time shouldn't be null", resultExpTime);
+            Integer flicker = result.get(CaptureResult.STATISTICS_SCENE_FLICKER);
+            // Scene flicker result should be always available.
+            assertNotNull("Scene flicker must not be null", flicker);
+            assertTrue("Scene flicker is invalid", flicker >= STATISTICS_SCENE_FLICKER_NONE &&
+                    flicker <= STATISTICS_SCENE_FLICKER_60HZ);
+
+            if (isAeManual) {
+                // First, round down not up, second, need close enough.
+                validateExposureTime(requestExpTime, resultExpTime);
+                return;
+            }
+
+            long expectedExpTime = resultExpTime; // Default, no exposure adjustment.
+            if (mode == CONTROL_AE_ANTIBANDING_MODE_50HZ) {
+                // result exposure time must be adjusted by 50Hz illuminant source.
+                expectedExpTime =
+                        getAntiFlickeringExposureTime(ANTI_FLICKERING_50HZ, resultExpTime);
+            } else if (mode == CONTROL_AE_ANTIBANDING_MODE_60HZ) {
+                // result exposure time must be adjusted by 60Hz illuminant source.
+                expectedExpTime =
+                        getAntiFlickeringExposureTime(ANTI_FLICKERING_60HZ, resultExpTime);
+            } else if (mode == CONTROL_AE_ANTIBANDING_MODE_AUTO){
+                /**
+                 * Use STATISTICS_SCENE_FLICKER to tell the illuminant source
+                 * and do the exposure adjustment.
+                 */
+                expectedExpTime = resultExpTime;
+                if (flicker == STATISTICS_SCENE_FLICKER_60HZ) {
+                    expectedExpTime =
+                            getAntiFlickeringExposureTime(ANTI_FLICKERING_60HZ, resultExpTime);
+                } else if (flicker == STATISTICS_SCENE_FLICKER_50HZ) {
+                    expectedExpTime =
+                            getAntiFlickeringExposureTime(ANTI_FLICKERING_50HZ, resultExpTime);
+                }
+            }
+
+            if (Math.abs(resultExpTime - expectedExpTime) > EXPOSURE_TIME_ERROR_MARGIN_NS) {
+                mCollector.addMessage(String.format("Result exposure time %dns diverges too much"
+                        + " from expected exposure time %dns for mode %d when AE is auto",
+                        resultExpTime, expectedExpTime, mode));
+            }
+        }
+    }
+
+    private void antiBandingTestByMode(Size size, int mode)
+            throws Exception {
+        if(VERBOSE) {
+            Log.v(TAG, "Anti-banding test for mode " + mode + " for camera " + mCamera.getId());
+        }
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+        requestBuilder.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE, mode);
+
+        // Test auto AE mode anti-banding behavior
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        startPreview(requestBuilder, size, resultListener);
+        waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+        verifyAntiBandingMode(resultListener, NUM_FRAMES_VERIFIED, mode, /*isAeManual*/false,
+                IGNORE_REQUESTED_EXPOSURE_TIME_CHECK);
+
+        // Test manual AE mode anti-banding behavior
+        // 65ms, must be supported by full capability devices.
+        final long TEST_MANUAL_EXP_TIME_NS = 65000000L;
+        long manualExpTime = mStaticInfo.getExposureClampToRange(TEST_MANUAL_EXP_TIME_NS);
+        changeExposure(requestBuilder, manualExpTime);
+        resultListener = new SimpleCaptureCallback();
+        startPreview(requestBuilder, size, resultListener);
+        waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+        verifyAntiBandingMode(resultListener, NUM_FRAMES_VERIFIED, mode, /*isAeManual*/true,
+                manualExpTime);
+
+        stopPreview();
+    }
+
+    /**
+     * Test the all available AE modes and AE lock.
+     * <p>
+     * For manual AE mode, test iterates through different sensitivities and
+     * exposure times, validate the result exposure time correctness. For
+     * CONTROL_AE_MODE_ON_ALWAYS_FLASH mode, the AE lock and flash are tested.
+     * For the rest of the AUTO mode, AE lock is tested.
+     * </p>
+     *
+     * @param mode
+     */
+    private void aeModeAndLockTestByMode(int mode)
+            throws Exception {
+        switch (mode) {
+            case CONTROL_AE_MODE_OFF:
+                if (mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                    // Test manual exposure control.
+                    aeManualControlTest();
+                } else {
+                    Log.w(TAG,
+                            "aeModeAndLockTestByMode - can't test AE mode OFF without " +
+                            "manual sensor control");
+                }
+                break;
+            case CONTROL_AE_MODE_ON:
+            case CONTROL_AE_MODE_ON_AUTO_FLASH:
+            case CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
+            case CONTROL_AE_MODE_ON_ALWAYS_FLASH:
+                // Test AE lock for above AUTO modes.
+                aeAutoModeTestLock(mode);
+                break;
+            default:
+                throw new UnsupportedOperationException("Unhandled AE mode " + mode);
+        }
+    }
+
+    /**
+     * Test AE auto modes.
+     * <p>
+     * Use single request rather than repeating request to test AE lock per frame control.
+     * </p>
+     */
+    private void aeAutoModeTestLock(int mode) throws Exception {
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        if (mStaticInfo.isAeLockSupported()) {
+            requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
+        }
+        requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, mode);
+        configurePreviewOutput(requestBuilder);
+
+        final int MAX_NUM_CAPTURES_DURING_LOCK = 5;
+        for (int i = 1; i <= MAX_NUM_CAPTURES_DURING_LOCK; i++) {
+            autoAeMultipleCapturesThenTestLock(requestBuilder, mode, i);
+        }
+    }
+
+    /**
+     * Issue multiple auto AE captures, then lock AE, validate the AE lock vs.
+     * the first capture result after the AE lock. The right AE lock behavior is:
+     * When it is locked, it locks to the current exposure value, and all subsequent
+     * request with lock ON will have the same exposure value locked.
+     */
+    private void autoAeMultipleCapturesThenTestLock(
+            CaptureRequest.Builder requestBuilder, int aeMode, int numCapturesDuringLock)
+            throws Exception {
+        if (numCapturesDuringLock < 1) {
+            throw new IllegalArgumentException("numCapturesBeforeLock must be no less than 1");
+        }
+        if (VERBOSE) {
+            Log.v(TAG, "Camera " + mCamera.getId() + ": Testing auto AE mode and lock for mode "
+                    + aeMode + " with " + numCapturesDuringLock + " captures before lock");
+        }
+
+        final int NUM_CAPTURES_BEFORE_LOCK = 2;
+        SimpleCaptureCallback listener =  new SimpleCaptureCallback();
+
+        CaptureResult[] resultsDuringLock = new CaptureResult[numCapturesDuringLock];
+        boolean canSetAeLock = mStaticInfo.isAeLockSupported();
+
+        // Reset the AE lock to OFF, since we are reusing this builder many times
+        if (canSetAeLock) {
+            requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
+        }
+
+        // Just send several captures with auto AE, lock off.
+        CaptureRequest request = requestBuilder.build();
+        for (int i = 0; i < NUM_CAPTURES_BEFORE_LOCK; i++) {
+            mSession.capture(request, listener, mHandler);
+        }
+        waitForNumResults(listener, NUM_CAPTURES_BEFORE_LOCK);
+
+        if (!canSetAeLock) {
+            // Without AE lock, the remaining tests items won't work
+            return;
+        }
+
+        // Then fire several capture to lock the AE.
+        requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
+
+        int requestCount = captureRequestsSynchronized(
+                requestBuilder.build(), numCapturesDuringLock, listener, mHandler);
+
+        int[] sensitivities = new int[numCapturesDuringLock];
+        long[] expTimes = new long[numCapturesDuringLock];
+        Arrays.fill(sensitivities, -1);
+        Arrays.fill(expTimes, -1L);
+
+        // Get the AE lock on result and validate the exposure values.
+        waitForNumResults(listener, requestCount - numCapturesDuringLock);
+        for (int i = 0; i < resultsDuringLock.length; i++) {
+            resultsDuringLock[i] = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        }
+
+        for (int i = 0; i < numCapturesDuringLock; i++) {
+            mCollector.expectKeyValueEquals(
+                    resultsDuringLock[i], CaptureResult.CONTROL_AE_LOCK, true);
+        }
+
+        // Can't read manual sensor/exposure settings without manual sensor
+        if (mStaticInfo.isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS)) {
+            int sensitivityLocked =
+                    getValueNotNull(resultsDuringLock[0], CaptureResult.SENSOR_SENSITIVITY);
+            long expTimeLocked =
+                    getValueNotNull(resultsDuringLock[0], CaptureResult.SENSOR_EXPOSURE_TIME);
+            for (int i = 1; i < resultsDuringLock.length; i++) {
+                mCollector.expectKeyValueEquals(
+                        resultsDuringLock[i], CaptureResult.SENSOR_EXPOSURE_TIME, expTimeLocked);
+                mCollector.expectKeyValueEquals(
+                        resultsDuringLock[i], CaptureResult.SENSOR_SENSITIVITY, sensitivityLocked);
+            }
+        }
+    }
+
+    /**
+     * Iterate through exposure times and sensitivities for manual AE control.
+     * <p>
+     * Use single request rather than repeating request to test manual exposure
+     * value change per frame control.
+     * </p>
+     */
+    private void aeManualControlTest()
+            throws Exception {
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+        requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF);
+        configurePreviewOutput(requestBuilder);
+        SimpleCaptureCallback listener =  new SimpleCaptureCallback();
+
+        long[] expTimes = getExposureTimeTestValues();
+        int[] sensitivities = getSensitivityTestValues();
+        // Submit single request at a time, then verify the result.
+        for (int i = 0; i < expTimes.length; i++) {
+            for (int j = 0; j < sensitivities.length; j++) {
+                if (VERBOSE) {
+                    Log.v(TAG, "Camera " + mCamera.getId() + ": Testing sensitivity "
+                            + sensitivities[j] + ", exposure time " + expTimes[i] + "ns");
+                }
+
+                changeExposure(requestBuilder, expTimes[i], sensitivities[j]);
+                mSession.capture(requestBuilder.build(), listener, mHandler);
+
+                // make sure timeout is long enough for long exposure time
+                long timeout = WAIT_FOR_RESULT_TIMEOUT_MS + expTimes[i];
+                CaptureResult result = listener.getCaptureResult(timeout);
+                long resultExpTime = getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
+                int resultSensitivity = getValueNotNull(result, CaptureResult.SENSOR_SENSITIVITY);
+                validateExposureTime(expTimes[i], resultExpTime);
+                validateSensitivity(sensitivities[j], resultSensitivity);
+                validateFrameDurationForCapture(result);
+            }
+        }
+        // TODO: Add another case to test where we can submit all requests, then wait for
+        // results, which will hide the pipeline latency. this is not only faster, but also
+        // test high speed per frame control and synchronization.
+    }
+
+
+    /**
+     * Verify black level lock control.
+     */
+    private void verifyBlackLevelLockResults(SimpleCaptureCallback listener, int numFramesVerified,
+            int maxLockOffCnt) throws Exception {
+        int noLockCnt = 0;
+        for (int i = 0; i < numFramesVerified; i++) {
+            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            Boolean blackLevelLock = result.get(CaptureResult.BLACK_LEVEL_LOCK);
+            assertNotNull("Black level lock result shouldn't be null", blackLevelLock);
+
+            // Count the lock == false result, which could possibly occur at most once.
+            if (blackLevelLock == false) {
+                noLockCnt++;
+            }
+
+            if(VERBOSE) {
+                Log.v(TAG, "Black level lock result: " + blackLevelLock);
+            }
+        }
+        assertTrue("Black level lock OFF occurs " + noLockCnt + " times,  expect at most "
+                + maxLockOffCnt + " for camera " + mCamera.getId(), noLockCnt <= maxLockOffCnt);
+    }
+
+    /**
+     * Verify shading map for different shading modes.
+     */
+    private void verifyShadingMap(SimpleCaptureCallback listener, int numFramesVerified,
+            int shadingMode) throws Exception {
+
+        for (int i = 0; i < numFramesVerified; i++) {
+            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            mCollector.expectEquals("Shading mode result doesn't match request",
+                    shadingMode, result.get(CaptureResult.SHADING_MODE));
+            LensShadingMap mapObj = result.get(
+                    CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
+            assertNotNull("Map object must not be null", mapObj);
+            int numElementsInMap = mapObj.getGainFactorCount();
+            float[] map = new float[numElementsInMap];
+            mapObj.copyGainFactors(map, /*offset*/0);
+            assertNotNull("Map must not be null", map);
+            assertFalse(String.format(
+                    "Map size %d should be less than %d", numElementsInMap, MAX_SHADING_MAP_SIZE),
+                    numElementsInMap >= MAX_SHADING_MAP_SIZE);
+            assertFalse(String.format("Map size %d should be no less than %d", numElementsInMap,
+                    MIN_SHADING_MAP_SIZE), numElementsInMap < MIN_SHADING_MAP_SIZE);
+
+            if (shadingMode == CaptureRequest.SHADING_MODE_FAST ||
+                    shadingMode == CaptureRequest.SHADING_MODE_HIGH_QUALITY) {
+                // shading mode is FAST or HIGH_QUALITY, expect to receive a map with all
+                // elements >= 1.0f
+
+                int badValueCnt = 0;
+                // Detect the bad values of the map data.
+                for (int j = 0; j < numElementsInMap; j++) {
+                    if (Float.isNaN(map[j]) || map[j] < 1.0f) {
+                        badValueCnt++;
+                    }
+                }
+                assertEquals("Number of value in the map is " + badValueCnt + " out of "
+                        + numElementsInMap, /*expected*/0, /*actual*/badValueCnt);
+            } else if (shadingMode == CaptureRequest.SHADING_MODE_OFF) {
+                float[] unityMap = new float[numElementsInMap];
+                Arrays.fill(unityMap, 1.0f);
+                // shading mode is OFF, expect to receive a unity map.
+                assertTrue("Result map " + Arrays.toString(map) + " must be an unity map",
+                        Arrays.equals(unityMap, map));
+            }
+        }
+    }
+
+    /**
+     * Test face detection for a camera.
+     */
+    private void faceDetectionTestByCamera() throws Exception {
+        int[] faceDetectModes = mStaticInfo.getAvailableFaceDetectModesChecked();
+
+        SimpleCaptureCallback listener;
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
+        for (int mode : faceDetectModes) {
+            requestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, mode);
+            if (VERBOSE) {
+                Log.v(TAG, "Start testing face detection mode " + mode);
+            }
+
+            // Create a new listener for each run to avoid the results from one run spill
+            // into another run.
+            listener = new SimpleCaptureCallback();
+            startPreview(requestBuilder, maxPreviewSz, listener);
+            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+            verifyFaceDetectionResults(listener, NUM_FACE_DETECTION_FRAMES_VERIFIED, mode);
+        }
+
+        stopPreview();
+    }
+
+    /**
+     * Verify face detection results for different face detection modes.
+     *
+     * @param listener The listener to get capture result
+     * @param numFramesVerified Number of results to be verified
+     * @param faceDetectionMode Face detection mode to be verified against
+     */
+    private void verifyFaceDetectionResults(SimpleCaptureCallback listener, int numFramesVerified,
+            int faceDetectionMode) {
+        for (int i = 0; i < numFramesVerified; i++) {
+            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            mCollector.expectEquals("Result face detection mode should match the request",
+                    faceDetectionMode, result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE));
+
+            Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
+            List<Integer> faceIds = new ArrayList<Integer>(faces.length);
+            List<Integer> faceScores = new ArrayList<Integer>(faces.length);
+            if (faceDetectionMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_OFF) {
+                mCollector.expectEquals("Number of detection faces should always 0 for OFF mode",
+                        0, faces.length);
+            } else if (faceDetectionMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_SIMPLE) {
+                for (Face face : faces) {
+                    mCollector.expectNotNull("Face rectangle shouldn't be null", face.getBounds());
+                    faceScores.add(face.getScore());
+                    mCollector.expectTrue("Face id is expected to be -1 for SIMPLE mode",
+                            face.getId() == Face.ID_UNSUPPORTED);
+                }
+            } else if (faceDetectionMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_FULL) {
+                if (VERBOSE) {
+                    Log.v(TAG, "Number of faces detected: " + faces.length);
+                }
+
+                for (Face face : faces) {
+                    Rect faceBound;
+                    boolean faceRectAvailable =  mCollector.expectTrue("Face rectangle "
+                            + "shouldn't be null", face.getBounds() != null);
+                    if (!faceRectAvailable) {
+                        continue;
+                    }
+                    faceBound = face.getBounds();
+
+                    faceScores.add(face.getScore());
+                    faceIds.add(face.getId());
+
+                    mCollector.expectTrue("Face id is shouldn't be -1 for FULL mode",
+                            face.getId() != Face.ID_UNSUPPORTED);
+                    boolean leftEyeAvailable =
+                            mCollector.expectTrue("Left eye position shouldn't be null",
+                                    face.getLeftEyePosition() != null);
+                    boolean rightEyeAvailable =
+                            mCollector.expectTrue("Right eye position shouldn't be null",
+                                    face.getRightEyePosition() != null);
+                    boolean mouthAvailable =
+                            mCollector.expectTrue("Mouth position shouldn't be null",
+                            face.getMouthPosition() != null);
+                    // Eyes/mouth position should be inside of the face rect.
+                    if (leftEyeAvailable) {
+                        Point leftEye = face.getLeftEyePosition();
+                        mCollector.expectTrue("Left eye " + leftEye + "should be"
+                                + "inside of face rect " + faceBound,
+                                faceBound.contains(leftEye.x, leftEye.y));
+                    }
+                    if (rightEyeAvailable) {
+                        Point rightEye = face.getRightEyePosition();
+                        mCollector.expectTrue("Right eye " + rightEye + "should be"
+                                + "inside of face rect " + faceBound,
+                                faceBound.contains(rightEye.x, rightEye.y));
+                    }
+                    if (mouthAvailable) {
+                        Point mouth = face.getMouthPosition();
+                        mCollector.expectTrue("Mouth " + mouth +  " should be inside of"
+                                + " face rect " + faceBound,
+                                faceBound.contains(mouth.x, mouth.y));
+                    }
+                }
+            }
+            mCollector.expectValuesInRange("Face scores are invalid", faceScores,
+                    Face.SCORE_MIN, Face.SCORE_MAX);
+            mCollector.expectValuesUnique("Face ids are invalid", faceIds);
+        }
+    }
+
+    /**
+     * Test tone map mode and result by camera
+     */
+    private void toneMapTestByCamera() throws Exception {
+        if (!mStaticInfo.isManualToneMapSupported()) {
+            return;
+        }
+
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        int[] toneMapModes = mStaticInfo.getAvailableToneMapModesChecked();
+        for (int mode : toneMapModes) {
+            if (VERBOSE) {
+                Log.v(TAG, "Testing tonemap mode " + mode);
+            }
+
+            requestBuilder.set(CaptureRequest.TONEMAP_MODE, mode);
+            switch (mode) {
+                case CaptureRequest.TONEMAP_MODE_CONTRAST_CURVE:
+                    TonemapCurve toneCurve = new TonemapCurve(TONEMAP_CURVE_LINEAR,
+                            TONEMAP_CURVE_LINEAR, TONEMAP_CURVE_LINEAR);
+                    requestBuilder.set(CaptureRequest.TONEMAP_CURVE, toneCurve);
+                    testToneMapMode(NUM_FRAMES_VERIFIED, requestBuilder);
+
+                    toneCurve = new TonemapCurve(TONEMAP_CURVE_SRGB,
+                            TONEMAP_CURVE_SRGB, TONEMAP_CURVE_SRGB);
+                    requestBuilder.set(CaptureRequest.TONEMAP_CURVE, toneCurve);
+                    testToneMapMode(NUM_FRAMES_VERIFIED, requestBuilder);
+                    break;
+                case CaptureRequest.TONEMAP_MODE_GAMMA_VALUE:
+                    requestBuilder.set(CaptureRequest.TONEMAP_GAMMA, 1.0f);
+                    testToneMapMode(NUM_FRAMES_VERIFIED, requestBuilder);
+                    requestBuilder.set(CaptureRequest.TONEMAP_GAMMA, 2.2f);
+                    testToneMapMode(NUM_FRAMES_VERIFIED, requestBuilder);
+                    requestBuilder.set(CaptureRequest.TONEMAP_GAMMA, 5.0f);
+                    testToneMapMode(NUM_FRAMES_VERIFIED, requestBuilder);
+                    break;
+                case CaptureRequest.TONEMAP_MODE_PRESET_CURVE:
+                    requestBuilder.set(CaptureRequest.TONEMAP_PRESET_CURVE,
+                            CaptureRequest.TONEMAP_PRESET_CURVE_REC709);
+                    testToneMapMode(NUM_FRAMES_VERIFIED, requestBuilder);
+                    requestBuilder.set(CaptureRequest.TONEMAP_PRESET_CURVE,
+                            CaptureRequest.TONEMAP_PRESET_CURVE_SRGB);
+                    testToneMapMode(NUM_FRAMES_VERIFIED, requestBuilder);
+                    break;
+                default:
+                    testToneMapMode(NUM_FRAMES_VERIFIED, requestBuilder);
+                    break;
+            }
+        }
+
+
+    }
+
+    /**
+     * Test tonemap mode with speficied request settings
+     *
+     * @param numFramesVerified Number of results to be verified
+     * @param requestBuilder the request builder of settings to be tested
+     */
+    private void testToneMapMode (int numFramesVerified,
+            CaptureRequest.Builder requestBuilder)  throws Exception  {
+        final int MIN_TONEMAP_CURVE_POINTS = 2;
+        final Float ZERO = new Float(0);
+        final Float ONE = new Float(1.0f);
+
+        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+        int tonemapMode = requestBuilder.get(CaptureRequest.TONEMAP_MODE);
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
+        startPreview(requestBuilder, maxPreviewSz, listener);
+        waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+        int maxCurvePoints = mStaticInfo.getMaxTonemapCurvePointChecked();
+        for (int i = 0; i < numFramesVerified; i++) {
+            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            mCollector.expectEquals("Capture result tonemap mode should match request", tonemapMode,
+                    result.get(CaptureResult.TONEMAP_MODE));
+            TonemapCurve tc = getValueNotNull(result, CaptureResult.TONEMAP_CURVE);
+            int pointCount = tc.getPointCount(TonemapCurve.CHANNEL_RED);
+            float[] mapRed = new float[pointCount * TonemapCurve.POINT_SIZE];
+            pointCount = tc.getPointCount(TonemapCurve.CHANNEL_GREEN);
+            float[] mapGreen = new float[pointCount * TonemapCurve.POINT_SIZE];
+            pointCount = tc.getPointCount(TonemapCurve.CHANNEL_BLUE);
+            float[] mapBlue = new float[pointCount * TonemapCurve.POINT_SIZE];
+            tc.copyColorCurve(TonemapCurve.CHANNEL_RED, mapRed, 0);
+            tc.copyColorCurve(TonemapCurve.CHANNEL_GREEN, mapGreen, 0);
+            tc.copyColorCurve(TonemapCurve.CHANNEL_BLUE, mapBlue, 0);
+            if (tonemapMode == CaptureResult.TONEMAP_MODE_CONTRAST_CURVE) {
+                /**
+                 * TODO: need figure out a good way to measure the difference
+                 * between request and result, as they may have different array
+                 * size.
+                 */
+            } else if (tonemapMode == CaptureResult.TONEMAP_MODE_GAMMA_VALUE) {
+                mCollector.expectEquals("Capture result gamma value should match request",
+                        requestBuilder.get(CaptureRequest.TONEMAP_GAMMA),
+                        result.get(CaptureResult.TONEMAP_GAMMA));
+            } else if (tonemapMode == CaptureResult.TONEMAP_MODE_PRESET_CURVE) {
+                mCollector.expectEquals("Capture result preset curve should match request",
+                        requestBuilder.get(CaptureRequest.TONEMAP_PRESET_CURVE),
+                        result.get(CaptureResult.TONEMAP_PRESET_CURVE));
+            }
+
+            // Tonemap curve result availability and basic sanity check for all modes.
+            mCollector.expectValuesInRange("Tonemap curve red values are out of range",
+                    CameraTestUtils.toObject(mapRed), /*min*/ZERO, /*max*/ONE);
+            mCollector.expectInRange("Tonemap curve red length is out of range",
+                    mapRed.length, MIN_TONEMAP_CURVE_POINTS, maxCurvePoints * 2);
+            mCollector.expectValuesInRange("Tonemap curve green values are out of range",
+                    CameraTestUtils.toObject(mapGreen), /*min*/ZERO, /*max*/ONE);
+            mCollector.expectInRange("Tonemap curve green length is out of range",
+                    mapGreen.length, MIN_TONEMAP_CURVE_POINTS, maxCurvePoints * 2);
+            mCollector.expectValuesInRange("Tonemap curve blue values are out of range",
+                    CameraTestUtils.toObject(mapBlue), /*min*/ZERO, /*max*/ONE);
+            mCollector.expectInRange("Tonemap curve blue length is out of range",
+                    mapBlue.length, MIN_TONEMAP_CURVE_POINTS, maxCurvePoints * 2);
+        }
+        stopPreview();
+    }
+
+    /**
+     * Test awb mode control.
+     * <p>
+     * Test each supported AWB mode, verify the AWB mode in capture result
+     * matches request. When AWB is locked, the color correction gains and
+     * transform should remain unchanged.
+     * </p>
+     */
+    private void awbModeAndLockTestByCamera() throws Exception {
+        int[] awbModes = mStaticInfo.getAwbAvailableModesChecked();
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        boolean canSetAwbLock = mStaticInfo.isAwbLockSupported();
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        startPreview(requestBuilder, maxPreviewSize, /*listener*/null);
+
+        for (int mode : awbModes) {
+            SimpleCaptureCallback listener;
+            requestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, mode);
+            listener = new SimpleCaptureCallback();
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+            // Verify AWB mode in capture result.
+            verifyCaptureResultForKey(CaptureResult.CONTROL_AWB_MODE, mode, listener,
+                    NUM_FRAMES_VERIFIED);
+
+            if (mode == CameraMetadata.CONTROL_AWB_MODE_AUTO && canSetAwbLock) {
+                // Verify color correction transform and gains stay unchanged after a lock.
+                requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
+                listener = new SimpleCaptureCallback();
+                mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+                if (mStaticInfo.areKeysAvailable(CaptureResult.CONTROL_AWB_STATE)) {
+                    waitForResultValue(listener, CaptureResult.CONTROL_AWB_STATE,
+                            CaptureResult.CONTROL_AWB_STATE_LOCKED, NUM_RESULTS_WAIT_TIMEOUT);
+                }
+
+            }
+            // Don't verify auto mode result if AWB lock is not supported
+            if (mode != CameraMetadata.CONTROL_AWB_MODE_AUTO || canSetAwbLock) {
+                verifyAwbCaptureResultUnchanged(listener, NUM_FRAMES_VERIFIED);
+            }
+        }
+    }
+
+    private void verifyAwbCaptureResultUnchanged(SimpleCaptureCallback listener,
+            int numFramesVerified) {
+        // Skip check if cc gains/transform/mode are not available
+        if (!mStaticInfo.areKeysAvailable(
+                CaptureResult.COLOR_CORRECTION_GAINS,
+                CaptureResult.COLOR_CORRECTION_TRANSFORM,
+                CaptureResult.COLOR_CORRECTION_MODE)) {
+            return;
+        }
+
+        CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        RggbChannelVector lockedGains =
+                getValueNotNull(result, CaptureResult.COLOR_CORRECTION_GAINS);
+        ColorSpaceTransform lockedTransform =
+                getValueNotNull(result, CaptureResult.COLOR_CORRECTION_TRANSFORM);
+
+        for (int i = 0; i < numFramesVerified; i++) {
+            result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            // Color correction mode check is skipped here, as it is checked in colorCorrectionTest.
+            validateColorCorrectionResult(result, result.get(CaptureResult.COLOR_CORRECTION_MODE));
+
+            RggbChannelVector gains = getValueNotNull(result, CaptureResult.COLOR_CORRECTION_GAINS);
+            ColorSpaceTransform transform =
+                    getValueNotNull(result, CaptureResult.COLOR_CORRECTION_TRANSFORM);
+            mCollector.expectEquals("Color correction gains should remain unchanged after awb lock",
+                    lockedGains, gains);
+            mCollector.expectEquals("Color correction transform should remain unchanged after"
+                    + " awb lock", lockedTransform, transform);
+        }
+    }
+
+    /**
+     * Test AF mode control.
+     * <p>
+     * Test all supported AF modes, verify the AF mode in capture result matches
+     * request. When AF mode is one of the CONTROL_AF_MODE_CONTINUOUS_* mode,
+     * verify if the AF can converge to PASSIVE_FOCUSED or PASSIVE_UNFOCUSED
+     * state within certain amount of frames.
+     * </p>
+     */
+    private void afModeTestByCamera() throws Exception {
+        int[] afModes = mStaticInfo.getAfAvailableModesChecked();
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        startPreview(requestBuilder, maxPreviewSize, /*listener*/null);
+
+        for (int mode : afModes) {
+            SimpleCaptureCallback listener;
+            requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, mode);
+            listener = new SimpleCaptureCallback();
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+            // Verify AF mode in capture result.
+            verifyCaptureResultForKey(CaptureResult.CONTROL_AF_MODE, mode, listener,
+                    NUM_FRAMES_VERIFIED);
+
+            // Verify AF can finish a scan for CONTROL_AF_MODE_CONTINUOUS_* modes.
+            // 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() &&
+                    (mode == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE ||
+                    mode == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO)) {
+                List<Integer> afStateList = new ArrayList<Integer>();
+                afStateList.add(CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED);
+                afStateList.add(CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED);
+                waitForAnyResultValue(listener, CaptureResult.CONTROL_AF_STATE, afStateList,
+                        NUM_RESULTS_WAIT_TIMEOUT);
+            }
+        }
+    }
+
+    /**
+     * Test video and optical stabilizations if they are supported by a given camera.
+     */
+    private void stabilizationTestByCamera() throws Exception {
+        // video stabilization test.
+        List<Key<?>> keys = mStaticInfo.getCharacteristics().getKeys();
+
+        Integer[] videoStabModes = (keys.contains(CameraCharacteristics.
+                CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES)) ?
+                CameraTestUtils.toObject(mStaticInfo.getAvailableVideoStabilizationModesChecked()) :
+                    new Integer[0];
+        int[] opticalStabModes = (keys.contains(
+                CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION)) ?
+                mStaticInfo.getAvailableOpticalStabilizationChecked() : new int[0];
+
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+        startPreview(requestBuilder, maxPreviewSize, listener);
+
+        for (Integer mode : videoStabModes) {
+            listener = new SimpleCaptureCallback();
+            requestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, mode);
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+            // Video stabilization could return any modes.
+            verifyAnyCaptureResultForKey(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE,
+                    videoStabModes, listener, NUM_FRAMES_VERIFIED);
+        }
+
+        for (int mode : opticalStabModes) {
+            listener = new SimpleCaptureCallback();
+            requestBuilder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, mode);
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+            verifyCaptureResultForKey(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE, mode,
+                    listener, NUM_FRAMES_VERIFIED);
+        }
+
+        stopPreview();
+    }
+
+    private void digitalZoomTestByCamera(Size previewSize) throws Exception {
+        final int ZOOM_STEPS = 15;
+        final PointF[] TEST_ZOOM_CENTERS;
+
+        final int croppingType = mStaticInfo.getScalerCroppingTypeChecked();
+        if (croppingType ==
+                CameraCharacteristics.SCALER_CROPPING_TYPE_FREEFORM) {
+            TEST_ZOOM_CENTERS = new PointF[] {
+                new PointF(0.5f, 0.5f),   // Center point
+                new PointF(0.25f, 0.25f), // top left corner zoom, minimal zoom: 2x
+                new PointF(0.75f, 0.25f), // top right corner zoom, minimal zoom: 2x
+                new PointF(0.25f, 0.75f), // bottom left corner zoom, minimal zoom: 2x
+                new PointF(0.75f, 0.75f), // bottom right corner zoom, minimal zoom: 2x
+            };
+
+            if (VERBOSE) {
+                Log.v(TAG, "Testing zoom with CROPPING_TYPE = FREEFORM");
+            }
+        } else {
+            // CENTER_ONLY
+            TEST_ZOOM_CENTERS = new PointF[] {
+                    new PointF(0.5f, 0.5f),   // Center point
+            };
+
+            if (VERBOSE) {
+                Log.v(TAG, "Testing zoom with CROPPING_TYPE = CENTER_ONLY");
+            }
+        }
+
+        final float maxZoom = mStaticInfo.getAvailableMaxDigitalZoomChecked();
+        final Rect activeArraySize = mStaticInfo.getActiveArraySizeChecked();
+        Rect[] cropRegions = new Rect[ZOOM_STEPS];
+        MeteringRectangle[][] expectRegions = new MeteringRectangle[ZOOM_STEPS][];
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+
+        updatePreviewSurface(previewSize);
+        configurePreviewOutput(requestBuilder);
+
+        CaptureRequest[] requests = new CaptureRequest[ZOOM_STEPS];
+
+        // Set algorithm regions to full active region
+        // TODO: test more different 3A regions
+        final MeteringRectangle[] defaultMeteringRect = new MeteringRectangle[] {
+                new MeteringRectangle (
+                        /*x*/0, /*y*/0, activeArraySize.width(), activeArraySize.height(),
+                        /*meteringWeight*/1)
+        };
+
+        for (int algo = 0; algo < NUM_ALGORITHMS; algo++) {
+            update3aRegion(requestBuilder, algo,  defaultMeteringRect);
+        }
+
+        final int CAPTURE_SUBMIT_REPEAT;
+        {
+            int maxLatency = mStaticInfo.getSyncMaxLatency();
+            if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
+                CAPTURE_SUBMIT_REPEAT = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY + 1;
+            } else {
+                CAPTURE_SUBMIT_REPEAT = maxLatency + 1;
+            }
+        }
+
+        if (VERBOSE) {
+            Log.v(TAG, "Testing zoom with CAPTURE_SUBMIT_REPEAT = " + CAPTURE_SUBMIT_REPEAT);
+        }
+
+        for (PointF center : TEST_ZOOM_CENTERS) {
+            Rect previousCrop = null;
+
+            for (int i = 0; i < ZOOM_STEPS; i++) {
+                /*
+                 * Submit capture request
+                 */
+                float zoomFactor = (float) (1.0f + (maxZoom - 1.0) * i / ZOOM_STEPS);
+                cropRegions[i] = getCropRegionForZoom(zoomFactor, center, maxZoom, activeArraySize);
+                if (VERBOSE) {
+                    Log.v(TAG, "Testing Zoom for factor " + zoomFactor + " and center " +
+                            center + " The cropRegion is " + cropRegions[i] +
+                            " Preview size is " + previewSize);
+                }
+                requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, cropRegions[i]);
+                requests[i] = requestBuilder.build();
+                for (int j = 0; j < CAPTURE_SUBMIT_REPEAT; ++j) {
+                    if (VERBOSE) {
+                        Log.v(TAG, "submit crop region " + cropRegions[i]);
+                    }
+                    mSession.capture(requests[i], listener, mHandler);
+                }
+
+                /*
+                 * Validate capture result
+                 */
+                waitForNumResults(listener, CAPTURE_SUBMIT_REPEAT - 1); // Drop first few frames
+                CaptureResult result = listener.getCaptureResultForRequest(
+                        requests[i], NUM_RESULTS_WAIT_TIMEOUT);
+                Rect cropRegion = getValueNotNull(result, CaptureResult.SCALER_CROP_REGION);
+
+                /*
+                 * Validate resulting crop regions
+                 */
+                if (previousCrop != null) {
+                    Rect currentCrop = cropRegion;
+                    mCollector.expectTrue(String.format(
+                            "Crop region should shrink or stay the same " +
+                                    "(previous = %s, current = %s)",
+                                    previousCrop, currentCrop),
+                            previousCrop.equals(currentCrop) ||
+                                (previousCrop.width() > currentCrop.width() &&
+                                 previousCrop.height() > currentCrop.height()));
+                }
+
+                if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                    mCollector.expectRectsAreSimilar(
+                            "Request and result crop region should be similar",
+                            cropRegions[i], cropRegion, CROP_REGION_ERROR_PERCENT_DELTA);
+                }
+
+                if (croppingType == SCALER_CROPPING_TYPE_CENTER_ONLY) {
+                    mCollector.expectRectCentered(
+                            "Result crop region should be centered inside the active array",
+                            new Size(activeArraySize.width(), activeArraySize.height()),
+                            cropRegion, CROP_REGION_ERROR_PERCENT_CENTERED);
+                }
+
+                /*
+                 * Validate resulting metering regions
+                 */
+
+                // Use the actual reported crop region to calculate the resulting metering region
+                expectRegions[i] = getExpectedOutputRegion(
+                        /*requestRegion*/defaultMeteringRect,
+                        /*cropRect*/     cropRegion);
+
+                // Verify Output 3A region is intersection of input 3A region and crop region
+                for (int algo = 0; algo < NUM_ALGORITHMS; algo++) {
+                    validate3aRegion(result, algo, expectRegions[i]);
+                }
+
+                previousCrop = cropRegion;
+            }
+
+            if (maxZoom > 1.0f) {
+                mCollector.expectTrue(
+                        String.format("Most zoomed-in crop region should be smaller" +
+                                        "than active array w/h" +
+                                        "(last crop = %s, active array = %s)",
+                                        previousCrop, activeArraySize),
+                            (previousCrop.width() < activeArraySize.width() &&
+                             previousCrop.height() < activeArraySize.height()));
+            }
+        }
+    }
+
+    private void digitalZoomPreviewCombinationTestByCamera() throws Exception {
+        final double ASPECT_RATIO_THRESHOLD = 0.001;
+        List<Double> aspectRatiosTested = new ArrayList<Double>();
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        aspectRatiosTested.add((double)(maxPreviewSize.getWidth()) / maxPreviewSize.getHeight());
+
+        for (Size size : mOrderedPreviewSizes) {
+            // Max preview size was already tested in testDigitalZoom test. skip it.
+            if (size.equals(maxPreviewSize)) {
+                continue;
+            }
+
+            // Only test the largest size for each aspect ratio.
+            double aspectRatio = (double)(size.getWidth()) / size.getHeight();
+            if (isAspectRatioContained(aspectRatiosTested, aspectRatio, ASPECT_RATIO_THRESHOLD)) {
+                continue;
+            }
+
+            if (VERBOSE) {
+                Log.v(TAG, "Test preview size " + size.toString() + " digital zoom");
+            }
+
+            aspectRatiosTested.add(aspectRatio);
+            digitalZoomTestByCamera(size);
+        }
+    }
+
+    private static boolean isAspectRatioContained(List<Double> aspectRatioList,
+            double aspectRatio, double delta) {
+        for (Double ratio : aspectRatioList) {
+            if (Math.abs(ratio - aspectRatio) < delta) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private void sceneModeTestByCamera() throws Exception {
+        int[] sceneModes = mStaticInfo.getAvailableSceneModesChecked();
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+        requestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_USE_SCENE_MODE);
+        startPreview(requestBuilder, maxPreviewSize, listener);
+
+        for(int mode : sceneModes) {
+            requestBuilder.set(CaptureRequest.CONTROL_SCENE_MODE, mode);
+            listener = new SimpleCaptureCallback();
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+            verifyCaptureResultForKey(CaptureResult.CONTROL_SCENE_MODE,
+                    mode, listener, NUM_FRAMES_VERIFIED);
+            // This also serves as purpose of showing preview for NUM_FRAMES_VERIFIED
+            verifyCaptureResultForKey(CaptureResult.CONTROL_MODE,
+                    CaptureRequest.CONTROL_MODE_USE_SCENE_MODE, listener, NUM_FRAMES_VERIFIED);
+        }
+    }
+
+    private void effectModeTestByCamera() throws Exception {
+        int[] effectModes = mStaticInfo.getAvailableEffectModesChecked();
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        requestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
+        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+        startPreview(requestBuilder, maxPreviewSize, listener);
+
+        for(int mode : effectModes) {
+            requestBuilder.set(CaptureRequest.CONTROL_EFFECT_MODE, mode);
+            listener = new SimpleCaptureCallback();
+            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
+            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+            verifyCaptureResultForKey(CaptureResult.CONTROL_EFFECT_MODE,
+                    mode, listener, NUM_FRAMES_VERIFIED);
+            // This also serves as purpose of showing preview for NUM_FRAMES_VERIFIED
+            verifyCaptureResultForKey(CaptureResult.CONTROL_MODE,
+                    CaptureRequest.CONTROL_MODE_AUTO, listener, NUM_FRAMES_VERIFIED);
+        }
+    }
+
+    //----------------------------------------------------------------
+    //---------Below are common functions for all tests.--------------
+    //----------------------------------------------------------------
+
+    /**
+     * Enable exposure manual control and change exposure and sensitivity and
+     * clamp the value into the supported range.
+     */
+    private void changeExposure(CaptureRequest.Builder requestBuilder,
+            long expTime, int sensitivity) {
+        // Check if the max analog sensitivity is available and no larger than max sensitivity.
+        // The max analog sensitivity is not actually used here. This is only an extra sanity check.
+        mStaticInfo.getMaxAnalogSensitivityChecked();
+
+        expTime = mStaticInfo.getExposureClampToRange(expTime);
+        sensitivity = mStaticInfo.getSensitivityClampToRange(sensitivity);
+
+        requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF);
+        requestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, expTime);
+        requestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, sensitivity);
+    }
+    /**
+     * Enable exposure manual control and change exposure time and
+     * clamp the value into the supported range.
+     *
+     * <p>The sensitivity is set to default value.</p>
+     */
+    private void changeExposure(CaptureRequest.Builder requestBuilder, long expTime) {
+        changeExposure(requestBuilder, expTime, DEFAULT_SENSITIVITY);
+    }
+
+    /**
+     * Get the exposure time array that contains multiple exposure time steps in
+     * the exposure time range.
+     */
+    private long[] getExposureTimeTestValues() {
+        long[] testValues = new long[DEFAULT_NUM_EXPOSURE_TIME_STEPS + 1];
+        long maxExpTime = mStaticInfo.getExposureMaximumOrDefault(DEFAULT_EXP_TIME_NS);
+        long minExpTime = mStaticInfo.getExposureMinimumOrDefault(DEFAULT_EXP_TIME_NS);
+
+        long range = maxExpTime - minExpTime;
+        double stepSize = range / (double)DEFAULT_NUM_EXPOSURE_TIME_STEPS;
+        for (int i = 0; i < testValues.length; i++) {
+            testValues[i] = maxExpTime - (long)(stepSize * i);
+            testValues[i] = mStaticInfo.getExposureClampToRange(testValues[i]);
+        }
+
+        return testValues;
+    }
+
+    /**
+     * Generate test focus distances in range of [0, minFocusDistance] in increasing order.
+     */
+    private float[] getFocusDistanceTestValuesInOrder() {
+        float[] testValues = new float[NUM_TEST_FOCUS_DISTANCES + 1];
+        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;
+        }
+
+        return testValues;
+    }
+
+    /**
+     * Get the sensitivity array that contains multiple sensitivity steps in the
+     * sensitivity range.
+     * <p>
+     * Sensitivity number of test values is determined by
+     * {@value #DEFAULT_SENSITIVITY_STEP_SIZE} and sensitivity range, and
+     * bounded by {@value #DEFAULT_NUM_SENSITIVITY_STEPS}.
+     * </p>
+     */
+    private int[] getSensitivityTestValues() {
+        int maxSensitivity = mStaticInfo.getSensitivityMaximumOrDefault(
+                DEFAULT_SENSITIVITY);
+        int minSensitivity = mStaticInfo.getSensitivityMinimumOrDefault(
+                DEFAULT_SENSITIVITY);
+
+        int range = maxSensitivity - minSensitivity;
+        int stepSize = DEFAULT_SENSITIVITY_STEP_SIZE;
+        int numSteps = range / stepSize;
+        // Bound the test steps to avoid supper long test.
+        if (numSteps > DEFAULT_NUM_SENSITIVITY_STEPS) {
+            numSteps = DEFAULT_NUM_SENSITIVITY_STEPS;
+            stepSize = range / numSteps;
+        }
+        int[] testValues = new int[numSteps + 1];
+        for (int i = 0; i < testValues.length; i++) {
+            testValues[i] = maxSensitivity - stepSize * i;
+            testValues[i] = mStaticInfo.getSensitivityClampToRange(testValues[i]);
+        }
+
+        return testValues;
+    }
+
+    /**
+     * Validate the AE manual control exposure time.
+     *
+     * <p>Exposure should be close enough, and only round down if they are not equal.</p>
+     *
+     * @param request Request exposure time
+     * @param result Result exposure time
+     */
+    private void validateExposureTime(long request, long result) {
+        long expTimeDelta = request - result;
+        long expTimeErrorMargin = (long)(Math.max(EXPOSURE_TIME_ERROR_MARGIN_NS, request
+                * EXPOSURE_TIME_ERROR_MARGIN_RATE));
+        // First, round down not up, second, need close enough.
+        mCollector.expectTrue("Exposture time is invalid for AE manaul control test, request: "
+                + request + " result: " + result,
+                expTimeDelta < expTimeErrorMargin && expTimeDelta >= 0);
+    }
+
+    /**
+     * Validate AE manual control sensitivity.
+     *
+     * @param request Request sensitivity
+     * @param result Result sensitivity
+     */
+    private void validateSensitivity(int request, int result) {
+        float sensitivityDelta = (float)(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: "
+                + request + " result: " + result,
+                sensitivityDelta < sensitivityErrorMargin && sensitivityDelta >= 0);
+    }
+
+    /**
+     * Validate frame duration for a given capture.
+     *
+     * <p>Frame duration should be longer than exposure time.</p>
+     *
+     * @param result The capture result for a given capture
+     */
+    private void validateFrameDurationForCapture(CaptureResult result) {
+        long expTime = getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
+        long frameDuration = getValueNotNull(result, CaptureResult.SENSOR_FRAME_DURATION);
+        if (VERBOSE) {
+            Log.v(TAG, "frame duration: " + frameDuration + " Exposure time: " + expTime);
+        }
+
+        mCollector.expectTrue(String.format("Frame duration (%d) should be longer than exposure"
+                + " time (%d) for a given capture", frameDuration, expTime),
+                frameDuration >= expTime);
+
+        validatePipelineDepth(result);
+    }
+
+    /**
+     * Basic verification for the control mode capture result.
+     *
+     * @param key The capture result key to be verified against
+     * @param requestMode The request mode for this result
+     * @param listener The capture listener to get capture results
+     * @param numFramesVerified The number of capture results to be verified
+     */
+    private <T> void verifyCaptureResultForKey(CaptureResult.Key<T> key, T requestMode,
+            SimpleCaptureCallback listener, int numFramesVerified) {
+        for (int i = 0; i < numFramesVerified; i++) {
+            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            validatePipelineDepth(result);
+            T resultMode = getValueNotNull(result, key);
+            if (VERBOSE) {
+                Log.v(TAG, "Expect value: " + requestMode.toString() + " result value: "
+                        + resultMode.toString());
+            }
+            mCollector.expectEquals("Key " + key.getName() + " result should match request",
+                    requestMode, resultMode);
+        }
+    }
+
+    /**
+     * Basic verification that the value of a capture result key should be one of the expected
+     * values.
+     *
+     * @param key The capture result key to be verified against
+     * @param expectedModes The list of any possible expected modes for this result
+     * @param listener The capture listener to get capture results
+     * @param numFramesVerified The number of capture results to be verified
+     */
+    private <T> void verifyAnyCaptureResultForKey(CaptureResult.Key<T> key, T[] expectedModes,
+            SimpleCaptureCallback listener, int numFramesVerified) {
+        for (int i = 0; i < numFramesVerified; i++) {
+            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            validatePipelineDepth(result);
+            T resultMode = getValueNotNull(result, key);
+            if (VERBOSE) {
+                Log.v(TAG, "Expect values: " + Arrays.toString(expectedModes) + " result value: "
+                        + resultMode.toString());
+            }
+            // Capture result should be one of the expected values.
+            mCollector.expectContains(expectedModes, resultMode);
+        }
+    }
+
+    /**
+     * Verify if the fps is slow down for given input request with certain
+     * controls inside.
+     * <p>
+     * This method selects a max preview size for each fps range, and then
+     * configure the preview stream. Preview is started with the max preview
+     * size, and then verify if the result frame duration is in the frame
+     * duration range.
+     * </p>
+     *
+     * @param requestBuilder The request builder that contains post-processing
+     *            controls that could impact the output frame rate, such as
+     *            {@link CaptureRequest.NOISE_REDUCTION_MODE}. The value of
+     *            these controls must be set to some values such that the frame
+     *            rate is not slow down.
+     * @param numFramesVerified The number of frames to be verified
+     */
+    private void verifyFpsNotSlowDown(CaptureRequest.Builder requestBuilder,
+            int numFramesVerified)  throws Exception {
+        boolean frameDurationAvailable = true;
+        // Allow a few frames for AE to settle on target FPS range
+        final int NUM_FRAME_TO_SKIP = 6;
+        float frameDurationErrorMargin = FRAME_DURATION_ERROR_MARGIN;
+        if (!mStaticInfo.areKeysAvailable(CaptureResult.SENSOR_FRAME_DURATION)) {
+            frameDurationAvailable = false;
+            // Allow a larger error margin (1.5%) for timestamps
+            frameDurationErrorMargin = 0.015f;
+        }
+
+        Range<Integer>[] fpsRanges = mStaticInfo.getAeAvailableTargetFpsRangesChecked();
+        boolean antiBandingOffIsSupported = mStaticInfo.isAntiBandingOffModeSupported();
+        Range<Integer> fpsRange;
+        SimpleCaptureCallback resultListener;
+
+        for (int i = 0; i < fpsRanges.length; i += 1) {
+            fpsRange = fpsRanges[i];
+            Size previewSz = getMaxPreviewSizeForFpsRange(fpsRange);
+            // If unable to find a preview size, then log the failure, and skip this run.
+            if (previewSz == null) {
+                if (mStaticInfo.isCapabilitySupported(
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                    mCollector.addMessage(String.format(
+                            "Unable to find a preview size supporting given fps range %s",
+                            fpsRange));
+                }
+                continue;
+            }
+
+            if (VERBOSE) {
+                Log.v(TAG, String.format("Test fps range %s for preview size %s",
+                        fpsRange, previewSz.toString()));
+            }
+            requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
+            // Turn off auto antibanding to avoid exposure time and frame duration interference
+            // from antibanding algorithm.
+            if (antiBandingOffIsSupported) {
+                requestBuilder.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
+                        CaptureRequest.CONTROL_AE_ANTIBANDING_MODE_OFF);
+            } else {
+                // The device doesn't implement the OFF mode, test continues. It need make sure
+                // that the antibanding algorithm doesn't slow down the fps.
+                Log.i(TAG, "OFF antibanding mode is not supported, the camera device output must" +
+                        " not slow down the frame rate regardless of its current antibanding" +
+                        " mode");
+            }
+
+            resultListener = new SimpleCaptureCallback();
+            startPreview(requestBuilder, previewSz, resultListener);
+            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+            // Wait several more frames for AE to settle on target FPS range
+            waitForNumResults(resultListener, NUM_FRAME_TO_SKIP);
+
+            long[] frameDurationRange = new long[]{
+                    (long) (1e9 / fpsRange.getUpper()), (long) (1e9 / fpsRange.getLower())};
+            long captureTime = 0, prevCaptureTime = 0;
+            for (int j = 0; j < numFramesVerified; j++) {
+                long frameDuration = frameDurationRange[0];
+                CaptureResult result =
+                        resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+                validatePipelineDepth(result);
+                if (frameDurationAvailable) {
+                    frameDuration = getValueNotNull(result, CaptureResult.SENSOR_FRAME_DURATION);
+                } else {
+                    // if frame duration is not available, check timestamp instead
+                    captureTime = getValueNotNull(result, CaptureResult.SENSOR_TIMESTAMP);
+                    if (j > 0) {
+                        frameDuration = captureTime - prevCaptureTime;
+                    }
+                    prevCaptureTime = captureTime;
+                }
+                mCollector.expectInRange(
+                        "Frame duration must be in the range of " +
+                                Arrays.toString(frameDurationRange),
+                        frameDuration,
+                        (long) (frameDurationRange[0] * (1 - frameDurationErrorMargin)),
+                        (long) (frameDurationRange[1] * (1 + frameDurationErrorMargin)));
+            }
+        }
+
+        mSession.stopRepeating();
+    }
+
+    /**
+     * Validate the pipeline depth result.
+     *
+     * @param result The capture result to get pipeline depth data
+     */
+    private void validatePipelineDepth(CaptureResult result) {
+        final byte MIN_PIPELINE_DEPTH = 1;
+        byte maxPipelineDepth = mStaticInfo.getPipelineMaxDepthChecked();
+        Byte pipelineDepth = getValueNotNull(result, CaptureResult.REQUEST_PIPELINE_DEPTH);
+        mCollector.expectInRange(String.format("Pipeline depth must be in the range of [%d, %d]",
+                MIN_PIPELINE_DEPTH, maxPipelineDepth), pipelineDepth, MIN_PIPELINE_DEPTH,
+                maxPipelineDepth);
+    }
+
+    /**
+     * Calculate the anti-flickering corrected exposure time.
+     * <p>
+     * If the input exposure time is very short (shorter than flickering
+     * boundary), which indicate the scene is bright and very likely at outdoor
+     * environment, skip the correction, as it doesn't make much sense by doing so.
+     * </p>
+     * <p>
+     * For long exposure time (larger than the flickering boundary), find the
+     * exposure time that is closest to the flickering boundary.
+     * </p>
+     *
+     * @param flickeringMode The flickering mode
+     * @param exposureTime The input exposureTime to be corrected
+     * @return anti-flickering corrected exposure time
+     */
+    private long getAntiFlickeringExposureTime(int flickeringMode, long exposureTime) {
+        if (flickeringMode != ANTI_FLICKERING_50HZ && flickeringMode != ANTI_FLICKERING_60HZ) {
+            throw new IllegalArgumentException("Input anti-flickering mode must be 50 or 60Hz");
+        }
+        long flickeringBoundary = EXPOSURE_TIME_BOUNDARY_50HZ_NS;
+        if (flickeringMode == ANTI_FLICKERING_60HZ) {
+            flickeringBoundary = EXPOSURE_TIME_BOUNDARY_60HZ_NS;
+        }
+
+        if (exposureTime <= flickeringBoundary) {
+            return exposureTime;
+        }
+
+        // Find the closest anti-flickering corrected exposure time
+        long correctedExpTime = exposureTime + (flickeringBoundary / 2);
+        correctedExpTime = correctedExpTime - (correctedExpTime % flickeringBoundary);
+        return correctedExpTime;
+    }
+
+    /**
+     * Update one 3A region in capture request builder if that region is supported. Do nothing
+     * if the specified 3A region is not supported by camera device.
+     * @param requestBuilder The request to be updated
+     * @param algoIdx The index to the algorithm. (AE: 0, AWB: 1, AF: 2)
+     * @param regions The 3A regions to be set
+     */
+    private void update3aRegion(
+            CaptureRequest.Builder requestBuilder, int algoIdx, MeteringRectangle[] regions)
+    {
+        int maxRegions;
+        CaptureRequest.Key<MeteringRectangle[]> key;
+
+        if (regions == null || regions.length == 0) {
+            throw new IllegalArgumentException("Invalid input 3A region!");
+        }
+
+        switch (algoIdx) {
+            case INDEX_ALGORITHM_AE:
+                maxRegions = mStaticInfo.getAeMaxRegionsChecked();
+                key = CaptureRequest.CONTROL_AE_REGIONS;
+                break;
+            case INDEX_ALGORITHM_AWB:
+                maxRegions = mStaticInfo.getAwbMaxRegionsChecked();
+                key = CaptureRequest.CONTROL_AWB_REGIONS;
+                break;
+            case INDEX_ALGORITHM_AF:
+                maxRegions = mStaticInfo.getAfMaxRegionsChecked();
+                key = CaptureRequest.CONTROL_AF_REGIONS;
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown 3A Algorithm!");
+        }
+
+        if (maxRegions >= regions.length) {
+            requestBuilder.set(key, regions);
+        }
+    }
+
+    /**
+     * Validate one 3A region in capture result equals to expected region if that region is
+     * supported. Do nothing if the specified 3A region is not supported by camera device.
+     * @param result The capture result to be validated
+     * @param algoIdx The index to the algorithm. (AE: 0, AWB: 1, AF: 2)
+     * @param expectRegions The 3A regions expected in capture result
+     */
+    private void validate3aRegion(
+            CaptureResult result, int algoIdx, MeteringRectangle[] expectRegions)
+    {
+        int maxRegions;
+        CaptureResult.Key<MeteringRectangle[]> key;
+        MeteringRectangle[] actualRegion;
+
+        switch (algoIdx) {
+            case INDEX_ALGORITHM_AE:
+                maxRegions = mStaticInfo.getAeMaxRegionsChecked();
+                key = CaptureResult.CONTROL_AE_REGIONS;
+                break;
+            case INDEX_ALGORITHM_AWB:
+                maxRegions = mStaticInfo.getAwbMaxRegionsChecked();
+                key = CaptureResult.CONTROL_AWB_REGIONS;
+                break;
+            case INDEX_ALGORITHM_AF:
+                maxRegions = mStaticInfo.getAfMaxRegionsChecked();
+                key = CaptureResult.CONTROL_AF_REGIONS;
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown 3A Algorithm!");
+        }
+
+        if (maxRegions > 0)
+        {
+            actualRegion = getValueNotNull(result, key);
+            mCollector.expectEquals(
+                    "Expected 3A regions: " + Arrays.toString(expectRegions) +
+                    " does not match actual one: " + Arrays.toString(actualRegion),
+                    expectRegions, actualRegion);
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
new file mode 100644
index 0000000..2ae29c3
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/CaptureResultTest.java
@@ -0,0 +1,799 @@
+/*
+ * 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 android.hardware.camera2.cts;
+
+import android.content.Context;
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.media.Image;
+import android.media.ImageReader;
+import android.os.SystemClock;
+import android.util.Pair;
+import android.util.Size;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static android.hardware.camera2.cts.helpers.CameraSessionUtils.*;
+
+import android.util.Log;
+import android.view.Surface;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class CaptureResultTest extends Camera2AndroidTestCase {
+    private static final String TAG = "CaptureResultTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final int MAX_NUM_IMAGES = MAX_READER_IMAGES;
+    private static final int NUM_FRAMES_VERIFIED = 30;
+    private static final long WAIT_FOR_RESULT_TIMEOUT_MS = 3000;
+
+    // List that includes all public keys from CaptureResult
+    List<CaptureResult.Key<?>> mAllKeys;
+
+    // List tracking the failed test keys.
+
+    @Override
+    public void setContext(Context context) {
+        mAllKeys = getAllCaptureResultKeys();
+        super.setContext(context);
+
+        /**
+         * Workaround for mockito and JB-MR2 incompatibility
+         *
+         * Avoid java.lang.IllegalArgumentException: dexcache == null
+         * https://code.google.com/p/dexmaker/issues/detail?id=2
+         */
+        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * <p>
+     * Basic non-null check test for multiple capture results.
+     * </p>
+     * <p>
+     * When capturing many frames, some camera devices may return some results that have null keys
+     * randomly, which is an API violation and could cause application crash randomly. This test
+     * runs a typical flexible yuv capture many times, and checks if there is any null entries in
+     * a capture result.
+     * </p>
+     */
+    public void testCameraCaptureResultAllKeys() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (mStaticInfo.isColorOutputSupported()) {
+                    // Create image reader and surface.
+                    Size size = mOrderedPreviewSizes.get(0);
+                    createDefaultImageReader(size, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
+                            new ImageDropperListener());
+                } else {
+                    Size size = getMaxDepthSize(id, mCameraManager);
+                    createDefaultImageReader(size, ImageFormat.DEPTH16, MAX_NUM_IMAGES,
+                            new ImageDropperListener());
+                }
+
+                // Configure output streams.
+                List<Surface> outputSurfaces = new ArrayList<Surface>(1);
+                outputSurfaces.add(mReaderSurface);
+                createSession(outputSurfaces);
+
+                CaptureRequest.Builder requestBuilder =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                assertNotNull("Failed to create capture request", requestBuilder);
+                requestBuilder.addTarget(mReaderSurface);
+
+                // Start capture
+                SimpleCaptureCallback captureListener = new SimpleCaptureCallback();
+                startCapture(requestBuilder.build(), /*repeating*/true, captureListener, mHandler);
+
+                // Get the waived keys for current camera device
+                List<CaptureResult.Key<?>> waiverkeys = getWaiverKeysForCamera();
+
+                // Verify results
+                validateCaptureResult(captureListener, waiverkeys, requestBuilder,
+                        NUM_FRAMES_VERIFIED);
+
+                stopCapture(/*fast*/false);
+            } finally {
+                closeDevice(id);
+                closeDefaultImageReader();
+            }
+        }
+    }
+
+    /**
+     * Check partial results conform to its specification.
+     * <p>
+     * The test is skipped if partial result is not supported on device. </p>
+     * <p>Test summary:<ul>
+     * <li>1. Number of partial results is less than or equal to
+     * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT}.
+     * <li>2. Each key appeared in partial results must be unique across all partial results.
+     * <li>3. All keys appeared in partial results must be present in TotalCaptureResult
+     * <li>4. Also test onCaptureComplete callback always happen after onCaptureStart or
+     * onCaptureProgressed callbacks.
+     * </ul></p>
+     */
+    public void testPartialResult() throws Exception {
+        final int NUM_FRAMES_TESTED = 30;
+        final int WAIT_FOR_RESULT_TIMOUT_MS = 2000;
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+
+                // Skip the test if partial result is not supported
+                int partialResultCount = mStaticInfo.getPartialResultCount();
+                if (partialResultCount == 1) {
+                    continue;
+                }
+
+                // Create image reader and surface.
+                if (mStaticInfo.isColorOutputSupported()) {
+                    Size size = mOrderedPreviewSizes.get(0);
+                    createDefaultImageReader(size, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
+                            new ImageDropperListener());
+                } else {
+                    Size size = getMaxDepthSize(id, mCameraManager);
+                    createDefaultImageReader(size, ImageFormat.DEPTH16, MAX_NUM_IMAGES,
+                            new ImageDropperListener());
+                }
+
+                // Configure output streams.
+                List<Surface> outputSurfaces = new ArrayList<Surface>(1);
+                outputSurfaces.add(mReaderSurface);
+                createSession(outputSurfaces);
+
+                CaptureRequest.Builder requestBuilder =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                assertNotNull("Failed to create capture request", requestBuilder);
+                requestBuilder.addTarget(mReaderSurface);
+                TotalAndPartialResultListener listener =
+                        new TotalAndPartialResultListener();
+
+                // Start capture
+                for (Integer frame = 0; frame < NUM_FRAMES_TESTED; frame++) {
+                    // Set a different tag for each request so the listener can group
+                    // partial results by each request
+                    requestBuilder.setTag(frame);
+                    startCapture(
+                            requestBuilder.build(), /*repeating*/false,
+                            listener, mHandler);
+                }
+
+                // Verify capture results
+                for (int frame = 0; frame < NUM_FRAMES_TESTED; frame++) {
+                    Pair<TotalCaptureResult, List<CaptureResult>> resultPair =
+                            listener.getCaptureResultPairs(WAIT_FOR_RESULT_TIMOUT_MS);
+
+                    List<CaptureResult> partialResults = resultPair.second;
+
+                    if (partialResults == null) {
+                        // HAL only sends total result is legal
+                        partialResults = new ArrayList<>();
+                    }
+
+                    TotalCaptureResult totalResult = resultPair.first;
+
+                    mCollector.expectLessOrEqual("Too many partial results",
+                            partialResultCount, partialResults.size());
+                    Set<CaptureResult.Key<?>> appearedPartialKeys =
+                            new HashSet<CaptureResult.Key<?>>();
+                    for (CaptureResult partialResult : partialResults) {
+                        List<CaptureResult.Key<?>> partialKeys = partialResult.getKeys();
+                        mCollector.expectValuesUnique("Partial result keys: ", partialKeys);
+                        for (CaptureResult.Key<?> key : partialKeys) {
+                            mCollector.expectTrue(
+                                    String.format("Key %s appears in multiple partial results",
+                                            key.getName()),
+                                    !appearedPartialKeys.contains(key));
+                        }
+                        appearedPartialKeys.addAll(partialKeys);
+                    }
+
+                    // Test total result against the partial results
+                    List<CaptureResult.Key<?>> totalResultKeys = totalResult.getKeys();
+                    mCollector.expectTrue(
+                            "TotalCaptureResult must be a super set of partial capture results",
+                            totalResultKeys.containsAll(appearedPartialKeys));
+
+                    List<CaptureResult> totalResultPartials = totalResult.getPartialResults();
+                    mCollector.expectEquals("TotalCaptureResult's partial results must match " +
+                            "the ones observed by #onCaptureProgressed",
+                            partialResults, totalResultPartials);
+
+                    if (VERBOSE) {
+                        Log.v(TAG, "testPartialResult - Observed " +
+                                partialResults.size() + "; queried for " +
+                                totalResultPartials.size());
+                    }
+                }
+
+                int errorCode = listener.getErrorCode();
+                if ((errorCode & TotalAndPartialResultListener.ERROR_DUPLICATED_REQUEST) != 0) {
+                    mCollector.addMessage("Listener received multiple onCaptureComplete" +
+                            " callback for the same request");
+                }
+                if ((errorCode & TotalAndPartialResultListener.ERROR_WRONG_CALLBACK_ORDER) != 0) {
+                    mCollector.addMessage("Listener received onCaptureStart or" +
+                            " onCaptureProgressed after onCaptureComplete");
+                }
+
+                stopCapture(/*fast*/false);
+            } finally {
+                closeDevice(id);
+                closeDefaultImageReader();
+            }
+        }
+    }
+
+    /**
+     * Check that the timestamps passed in the results, buffers, and capture callbacks match for
+     * a single request, and increase monotonically
+     */
+    public void testResultTimestamps() throws Exception {
+        for (String id : mCameraIds) {
+            ImageReader previewReader = null;
+            ImageReader jpegReader = null;
+
+            SimpleImageReaderListener jpegListener = new SimpleImageReaderListener();
+            SimpleImageReaderListener prevListener = new SimpleImageReaderListener();
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+
+                CaptureRequest.Builder previewBuilder =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                CaptureRequest.Builder multiBuilder =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+
+                // Create image reader and surface.
+                Size previewSize = mOrderedPreviewSizes.get(0);
+                Size jpegSize = mOrderedStillSizes.get(0);
+
+                // Create ImageReaders.
+                previewReader = makeImageReader(previewSize, ImageFormat.YUV_420_888,
+                        MAX_NUM_IMAGES, prevListener, mHandler);
+                jpegReader = makeImageReader(jpegSize, ImageFormat.JPEG,
+                        MAX_NUM_IMAGES, jpegListener, mHandler);
+
+                // Configure output streams with preview and jpeg streams.
+                List<Surface> outputSurfaces = new ArrayList<>(Arrays.asList(
+                        previewReader.getSurface(), jpegReader.getSurface()));
+
+                SessionListener mockSessionListener = getMockSessionListener();
+
+                CameraCaptureSession session = configureAndVerifySession(mockSessionListener,
+                        mCamera, outputSurfaces, mHandler);
+
+                // Configure the requests.
+                previewBuilder.addTarget(previewReader.getSurface());
+                multiBuilder.addTarget(previewReader.getSurface());
+                multiBuilder.addTarget(jpegReader.getSurface());
+
+                CaptureCallback mockCaptureCallback = getMockCaptureListener();
+
+                // Capture targeting only preview
+                Pair<TotalCaptureResult, Long> result = captureAndVerifyResult(mockCaptureCallback,
+                        session, previewBuilder.build(), mHandler);
+
+                // Check if all timestamps are the same
+                Image prevImage = prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+                validateTimestamps("Result 1", result.first,
+                        prevImage, result.second);
+                prevImage.close();
+
+                // Capture targeting both jpeg and preview
+                Pair<TotalCaptureResult, Long> result2 = captureAndVerifyResult(mockCaptureCallback,
+                        session, multiBuilder.build(), mHandler);
+
+                // Check if all timestamps are the same
+                prevImage = prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+                Image jpegImage = jpegListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+                validateTimestamps("Result 2 Preview", result2.first,
+                        prevImage, result2.second);
+                validateTimestamps("Result 2 Jpeg", result2.first,
+                        jpegImage, result2.second);
+                prevImage.close();
+                jpegImage.close();
+
+                // Check if timestamps are increasing
+                mCollector.expectGreater("Timestamps must be increasing.", result.second,
+                        result2.second);
+
+                // Capture two preview frames
+                long startTime = SystemClock.elapsedRealtimeNanos();
+                Pair<TotalCaptureResult, Long> result3 = captureAndVerifyResult(mockCaptureCallback,
+                        session, previewBuilder.build(), mHandler);
+                Pair<TotalCaptureResult, Long> result4 = captureAndVerifyResult(mockCaptureCallback,
+                        session, previewBuilder.build(), mHandler);
+                long clockDiff = SystemClock.elapsedRealtimeNanos() - startTime;
+                long resultDiff = result4.second - result3.second;
+
+                // Check if all timestamps are the same
+                prevImage = prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+                validateTimestamps("Result 3", result3.first,
+                        prevImage, result3.second);
+                prevImage.close();
+                prevImage = prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+                validateTimestamps("Result 4", result4.first,
+                        prevImage, result4.second);
+                prevImage.close();
+
+                // Check that the timestamps monotonically increase at a reasonable rate
+                mCollector.expectGreaterOrEqual("Timestamps increase faster than system clock.",
+                        resultDiff, clockDiff);
+                mCollector.expectGreater("Timestamps must be increasing.", result3.second,
+                        result4.second);
+            } finally {
+                closeDevice(id);
+                closeImageReader(previewReader);
+                closeImageReader(jpegReader);
+            }
+        }
+    }
+
+    private void validateTimestamps(String msg, TotalCaptureResult result, Image resultImage,
+                                    long captureTime) {
+        mCollector.expectKeyValueEquals(result, CaptureResult.SENSOR_TIMESTAMP, captureTime);
+        mCollector.expectEquals(msg + ": Capture timestamp must be same as resultImage timestamp",
+                resultImage.getTimestamp(), captureTime);
+    }
+
+    private void validateCaptureResult(SimpleCaptureCallback captureListener,
+            List<CaptureResult.Key<?>> skippedKeys, CaptureRequest.Builder requestBuilder,
+            int numFramesVerified) throws Exception {
+        CaptureResult result = null;
+        for (int i = 0; i < numFramesVerified; i++) {
+            String failMsg = "Failed capture result " + i + " test ";
+            result = captureListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+
+            for (CaptureResult.Key<?> key : mAllKeys) {
+                if (!skippedKeys.contains(key)) {
+                    /**
+                     * Check the critical tags here.
+                     * TODO: Can use the same key for request and result when request/result
+                     * becomes symmetric (b/14059883). Then below check can be wrapped into
+                     * a generic function.
+                     */
+                    String msg = failMsg + "for key " + key.getName();
+                    if (key.equals(CaptureResult.CONTROL_AE_MODE)) {
+                        mCollector.expectEquals(msg,
+                                requestBuilder.get(CaptureRequest.CONTROL_AE_MODE),
+                                result.get(CaptureResult.CONTROL_AE_MODE));
+                    } else if (key.equals(CaptureResult.CONTROL_AF_MODE)) {
+                        mCollector.expectEquals(msg,
+                                requestBuilder.get(CaptureRequest.CONTROL_AF_MODE),
+                                result.get(CaptureResult.CONTROL_AF_MODE));
+                    } else if (key.equals(CaptureResult.CONTROL_AWB_MODE)) {
+                        mCollector.expectEquals(msg,
+                                requestBuilder.get(CaptureRequest.CONTROL_AWB_MODE),
+                                result.get(CaptureResult.CONTROL_AWB_MODE));
+                    } else if (key.equals(CaptureResult.CONTROL_MODE)) {
+                        mCollector.expectEquals(msg,
+                                requestBuilder.get(CaptureRequest.CONTROL_MODE),
+                                result.get(CaptureResult.CONTROL_MODE));
+                    } else if (key.equals(CaptureResult.STATISTICS_FACE_DETECT_MODE)) {
+                        mCollector.expectEquals(msg,
+                                requestBuilder.get(CaptureRequest.STATISTICS_FACE_DETECT_MODE),
+                                result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE));
+                    } else if (key.equals(CaptureResult.NOISE_REDUCTION_MODE)) {
+                        mCollector.expectEquals(msg,
+                                requestBuilder.get(CaptureRequest.NOISE_REDUCTION_MODE),
+                                result.get(CaptureResult.NOISE_REDUCTION_MODE));
+                    } else if (key.equals(CaptureResult.NOISE_REDUCTION_MODE)) {
+                        mCollector.expectEquals(msg,
+                                requestBuilder.get(CaptureRequest.NOISE_REDUCTION_MODE),
+                                result.get(CaptureResult.NOISE_REDUCTION_MODE));
+                    } else if (key.equals(CaptureResult.REQUEST_PIPELINE_DEPTH)) {
+
+                    } else {
+                        // Only do non-null check for the rest of keys.
+                        mCollector.expectKeyValueNotNull(failMsg, result, key);
+                    }
+                } else {
+                    // These keys should always be null
+                    if (key.equals(CaptureResult.CONTROL_AE_REGIONS)) {
+                        mCollector.expectNull(
+                                "Capture result contains AE regions but aeMaxRegions is 0",
+                                result.get(CaptureResult.CONTROL_AE_REGIONS));
+                    } else if (key.equals(CaptureResult.CONTROL_AWB_REGIONS)) {
+                        mCollector.expectNull(
+                                "Capture result contains AWB regions but awbMaxRegions is 0",
+                                result.get(CaptureResult.CONTROL_AWB_REGIONS));
+                    } else if (key.equals(CaptureResult.CONTROL_AF_REGIONS)) {
+                        mCollector.expectNull(
+                                "Capture result contains AF regions but afMaxRegions is 0",
+                                result.get(CaptureResult.CONTROL_AF_REGIONS));
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * Add waiver keys per camera device hardware level and capability.
+     *
+     * Must be called after camera device is opened.
+     */
+    private List<CaptureResult.Key<?>> getWaiverKeysForCamera() {
+        List<CaptureResult.Key<?>> waiverKeys = new ArrayList<>();
+
+        // Global waiver keys
+        waiverKeys.add(CaptureResult.JPEG_GPS_LOCATION);
+        waiverKeys.add(CaptureResult.JPEG_ORIENTATION);
+        waiverKeys.add(CaptureResult.JPEG_QUALITY);
+        waiverKeys.add(CaptureResult.JPEG_THUMBNAIL_QUALITY);
+        waiverKeys.add(CaptureResult.JPEG_THUMBNAIL_SIZE);
+
+        // Keys only present when corresponding control is on are being
+        // verified in its own functional test
+        // Only present in certain tonemap mode. Test in CaptureRequestTest.
+        waiverKeys.add(CaptureResult.TONEMAP_CURVE);
+        waiverKeys.add(CaptureResult.TONEMAP_GAMMA);
+        waiverKeys.add(CaptureResult.TONEMAP_PRESET_CURVE);
+        // Only present when test pattern mode is SOLID_COLOR.
+        // TODO: verify this key in test pattern test later
+        waiverKeys.add(CaptureResult.SENSOR_TEST_PATTERN_DATA);
+        // Only present when STATISTICS_LENS_SHADING_MAP_MODE is ON
+        waiverKeys.add(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
+        // Only present when STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES is ON
+        waiverKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP);
+        // Only present when face detection is on
+        waiverKeys.add(CaptureResult.STATISTICS_FACES);
+        // Only present in reprocessing capture result.
+        waiverKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);
+
+        //Keys not required if RAW is not supported
+        if (!mStaticInfo.isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+            waiverKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
+            waiverKeys.add(CaptureResult.SENSOR_GREEN_SPLIT);
+            waiverKeys.add(CaptureResult.SENSOR_NOISE_PROFILE);
+        }
+
+        //Keys for depth output capability
+        if (!mStaticInfo.isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT)) {
+            waiverKeys.add(CaptureResult.LENS_POSE_ROTATION);
+            waiverKeys.add(CaptureResult.LENS_POSE_TRANSLATION);
+            waiverKeys.add(CaptureResult.LENS_INTRINSIC_CALIBRATION);
+            waiverKeys.add(CaptureResult.LENS_RADIAL_DISTORTION);
+        }
+
+        if (mStaticInfo.getAeMaxRegionsChecked() == 0) {
+            waiverKeys.add(CaptureResult.CONTROL_AE_REGIONS);
+        }
+        if (mStaticInfo.getAwbMaxRegionsChecked() == 0) {
+            waiverKeys.add(CaptureResult.CONTROL_AWB_REGIONS);
+        }
+        if (mStaticInfo.getAfMaxRegionsChecked() == 0) {
+            waiverKeys.add(CaptureResult.CONTROL_AF_REGIONS);
+        }
+
+        if (mStaticInfo.isHardwareLevelFull()) {
+            return waiverKeys;
+        }
+
+        /*
+         * Hardware Level = LIMITED or LEGACY
+         */
+        // Key not present if certain control is not supported
+        if (!mStaticInfo.isColorCorrectionSupported()) {
+            waiverKeys.add(CaptureResult.COLOR_CORRECTION_GAINS);
+            waiverKeys.add(CaptureResult.COLOR_CORRECTION_MODE);
+            waiverKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM);
+        }
+
+        if (!mStaticInfo.isManualColorAberrationControlSupported()) {
+            waiverKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE);
+        }
+
+        if (!mStaticInfo.isManualToneMapSupported()) {
+            waiverKeys.add(CaptureResult.TONEMAP_MODE);
+        }
+
+        if (!mStaticInfo.isEdgeModeControlSupported()) {
+            waiverKeys.add(CaptureResult.EDGE_MODE);
+        }
+
+        if (!mStaticInfo.isHotPixelMapModeControlSupported()) {
+            waiverKeys.add(CaptureResult.HOT_PIXEL_MODE);
+        }
+
+        if (!mStaticInfo.isNoiseReductionModeControlSupported()) {
+            waiverKeys.add(CaptureResult.NOISE_REDUCTION_MODE);
+        }
+
+        if (!mStaticInfo.isManualLensShadingMapSupported()) {
+            waiverKeys.add(CaptureResult.SHADING_MODE);
+        }
+
+        //Keys not required if neither MANUAL_SENSOR nor READ_SENSOR_SETTINGS is supported
+        if (!mStaticInfo.isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR) &&
+            !mStaticInfo.isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS)) {
+            waiverKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME);
+            waiverKeys.add(CaptureResult.SENSOR_SENSITIVITY);
+            waiverKeys.add(CaptureResult.LENS_FOCUS_DISTANCE);
+            waiverKeys.add(CaptureResult.LENS_APERTURE);
+        }
+
+        if (!mStaticInfo.isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+            waiverKeys.add(CaptureResult.SENSOR_FRAME_DURATION);
+            waiverKeys.add(CaptureResult.BLACK_LEVEL_LOCK);
+            waiverKeys.add(CaptureResult.LENS_FOCUS_RANGE);
+            waiverKeys.add(CaptureResult.LENS_STATE);
+            waiverKeys.add(CaptureResult.LENS_FILTER_DENSITY);
+        }
+
+        if (mStaticInfo.isHardwareLevelLimited() && mStaticInfo.isColorOutputSupported()) {
+            return waiverKeys;
+        }
+
+        /*
+         * Hardware Level = LEGACY or no regular output is supported
+         */
+        waiverKeys.add(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER);
+        waiverKeys.add(CaptureResult.CONTROL_AE_STATE);
+        waiverKeys.add(CaptureResult.CONTROL_AWB_STATE);
+        waiverKeys.add(CaptureResult.FLASH_STATE);
+        waiverKeys.add(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE);
+        waiverKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW);
+        waiverKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP_MODE);
+        waiverKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER);
+        waiverKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE);
+        waiverKeys.add(CaptureResult.CONTROL_AE_TARGET_FPS_RANGE);
+        waiverKeys.add(CaptureResult.CONTROL_AF_TRIGGER);
+
+        if (mStaticInfo.isHardwareLevelLegacy()) {
+            return waiverKeys;
+        }
+
+        /*
+         * Regular output not supported, only depth, waive color-output-related keys
+         */
+        waiverKeys.add(CaptureResult.CONTROL_SCENE_MODE);
+        waiverKeys.add(CaptureResult.CONTROL_EFFECT_MODE);
+        waiverKeys.add(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE);
+        waiverKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE);
+        waiverKeys.add(CaptureResult.NOISE_REDUCTION_MODE);
+        waiverKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE);
+        waiverKeys.add(CaptureResult.CONTROL_AE_ANTIBANDING_MODE);
+        waiverKeys.add(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION);
+        waiverKeys.add(CaptureResult.CONTROL_AE_LOCK);
+        waiverKeys.add(CaptureResult.CONTROL_AE_MODE);
+        waiverKeys.add(CaptureResult.CONTROL_AF_MODE);
+        waiverKeys.add(CaptureResult.CONTROL_AWB_MODE);
+        waiverKeys.add(CaptureResult.CONTROL_AWB_LOCK);
+        waiverKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE);
+        waiverKeys.add(CaptureResult.FLASH_MODE);
+        waiverKeys.add(CaptureResult.SCALER_CROP_REGION);
+
+        return waiverKeys;
+    }
+
+    /**
+     * A capture listener implementation for collecting both partial and total results.
+     *
+     * <p> This is not a full-blown class and has some implicit assumptions. The class groups
+     * capture results by capture request, so the user must guarantee each request this listener
+     * is listening is unique. This class is not thread safe, so don't attach an instance object
+     * with multiple handlers.</p>
+     * */
+    private static class TotalAndPartialResultListener
+            extends CameraCaptureSession.CaptureCallback {
+        static final int ERROR_DUPLICATED_REQUEST = 1 << 0;
+        static final int ERROR_WRONG_CALLBACK_ORDER = 1 << 1;
+
+        private final LinkedBlockingQueue<Pair<TotalCaptureResult, List<CaptureResult>> > mQueue =
+                new LinkedBlockingQueue<>();
+        private final HashMap<CaptureRequest, List<CaptureResult>> mPartialResultsMap =
+                new HashMap<CaptureRequest, List<CaptureResult>>();
+        private final HashSet<CaptureRequest> completedRequests = new HashSet<>();
+        private int errorCode = 0;
+
+        @Override
+        public void onCaptureStarted(
+            CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber)
+        {
+            checkCallbackOrder(request);
+            createMapEntryIfNecessary(request);
+        }
+
+        @Override
+        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
+                TotalCaptureResult result) {
+            try {
+                List<CaptureResult> partialResultsList = mPartialResultsMap.get(request);
+                if (partialResultsList == null) {
+                    Log.w(TAG, "onCaptureCompleted: unknown request");
+                }
+                mQueue.put(new Pair<TotalCaptureResult, List<CaptureResult>>(
+                        result, partialResultsList));
+                mPartialResultsMap.remove(request);
+                boolean newEntryAdded = completedRequests.add(request);
+                if (!newEntryAdded) {
+                    Integer frame = (Integer) request.getTag();
+                    Log.e(TAG, "Frame " + frame + "ERROR_DUPLICATED_REQUEST");
+                    errorCode |= ERROR_DUPLICATED_REQUEST;
+                }
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onCaptureCompleted");
+            }
+        }
+
+        @Override
+        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
+                CaptureResult partialResult) {
+            createMapEntryIfNecessary(request);
+            List<CaptureResult> partialResultsList = mPartialResultsMap.get(request);
+            partialResultsList.add(partialResult);
+        }
+
+        private void createMapEntryIfNecessary(CaptureRequest request) {
+            if (!mPartialResultsMap.containsKey(request)) {
+                // create a new entry in the map
+                mPartialResultsMap.put(request, new ArrayList<CaptureResult>());
+            }
+        }
+
+        private void checkCallbackOrder(CaptureRequest request) {
+            if (completedRequests.contains(request)) {
+                Integer frame = (Integer) request.getTag();
+                Log.e(TAG, "Frame " + frame + "ERROR_WRONG_CALLBACK_ORDER");
+                errorCode |= ERROR_WRONG_CALLBACK_ORDER;
+            }
+        }
+
+        public Pair<TotalCaptureResult, List<CaptureResult>> getCaptureResultPairs(long timeout) {
+            try {
+                Pair<TotalCaptureResult, List<CaptureResult>> result =
+                        mQueue.poll(timeout, TimeUnit.MILLISECONDS);
+                assertNotNull("Wait for a capture result timed out in " + timeout + "ms", result);
+                return result;
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
+            }
+        }
+
+        public int getErrorCode() {
+            return errorCode;
+        }
+    }
+
+    /**
+     * TODO: Use CameraCharacteristics.getAvailableCaptureResultKeys() once we can filter out
+     * @hide keys.
+     *
+     */
+
+    /*@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 List<CaptureResult.Key<?>> getAllCaptureResultKeys() {
+        ArrayList<CaptureResult.Key<?>> resultKeys = new ArrayList<CaptureResult.Key<?>>();
+        resultKeys.add(CaptureResult.COLOR_CORRECTION_MODE);
+        resultKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM);
+        resultKeys.add(CaptureResult.COLOR_CORRECTION_GAINS);
+        resultKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE);
+        resultKeys.add(CaptureResult.CONTROL_AE_ANTIBANDING_MODE);
+        resultKeys.add(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION);
+        resultKeys.add(CaptureResult.CONTROL_AE_LOCK);
+        resultKeys.add(CaptureResult.CONTROL_AE_MODE);
+        resultKeys.add(CaptureResult.CONTROL_AE_REGIONS);
+        resultKeys.add(CaptureResult.CONTROL_AE_TARGET_FPS_RANGE);
+        resultKeys.add(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER);
+        resultKeys.add(CaptureResult.CONTROL_AF_MODE);
+        resultKeys.add(CaptureResult.CONTROL_AF_REGIONS);
+        resultKeys.add(CaptureResult.CONTROL_AF_TRIGGER);
+        resultKeys.add(CaptureResult.CONTROL_AWB_LOCK);
+        resultKeys.add(CaptureResult.CONTROL_AWB_MODE);
+        resultKeys.add(CaptureResult.CONTROL_AWB_REGIONS);
+        resultKeys.add(CaptureResult.CONTROL_CAPTURE_INTENT);
+        resultKeys.add(CaptureResult.CONTROL_EFFECT_MODE);
+        resultKeys.add(CaptureResult.CONTROL_MODE);
+        resultKeys.add(CaptureResult.CONTROL_SCENE_MODE);
+        resultKeys.add(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE);
+        resultKeys.add(CaptureResult.CONTROL_AE_STATE);
+        resultKeys.add(CaptureResult.CONTROL_AF_STATE);
+        resultKeys.add(CaptureResult.CONTROL_AWB_STATE);
+        resultKeys.add(CaptureResult.EDGE_MODE);
+        resultKeys.add(CaptureResult.FLASH_MODE);
+        resultKeys.add(CaptureResult.FLASH_STATE);
+        resultKeys.add(CaptureResult.HOT_PIXEL_MODE);
+        resultKeys.add(CaptureResult.JPEG_GPS_LOCATION);
+        resultKeys.add(CaptureResult.JPEG_ORIENTATION);
+        resultKeys.add(CaptureResult.JPEG_QUALITY);
+        resultKeys.add(CaptureResult.JPEG_THUMBNAIL_QUALITY);
+        resultKeys.add(CaptureResult.JPEG_THUMBNAIL_SIZE);
+        resultKeys.add(CaptureResult.LENS_APERTURE);
+        resultKeys.add(CaptureResult.LENS_FILTER_DENSITY);
+        resultKeys.add(CaptureResult.LENS_FOCAL_LENGTH);
+        resultKeys.add(CaptureResult.LENS_FOCUS_DISTANCE);
+        resultKeys.add(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE);
+        resultKeys.add(CaptureResult.LENS_POSE_ROTATION);
+        resultKeys.add(CaptureResult.LENS_POSE_TRANSLATION);
+        resultKeys.add(CaptureResult.LENS_FOCUS_RANGE);
+        resultKeys.add(CaptureResult.LENS_STATE);
+        resultKeys.add(CaptureResult.LENS_INTRINSIC_CALIBRATION);
+        resultKeys.add(CaptureResult.LENS_RADIAL_DISTORTION);
+        resultKeys.add(CaptureResult.NOISE_REDUCTION_MODE);
+        resultKeys.add(CaptureResult.REQUEST_PIPELINE_DEPTH);
+        resultKeys.add(CaptureResult.SCALER_CROP_REGION);
+        resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME);
+        resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION);
+        resultKeys.add(CaptureResult.SENSOR_SENSITIVITY);
+        resultKeys.add(CaptureResult.SENSOR_TIMESTAMP);
+        resultKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
+        resultKeys.add(CaptureResult.SENSOR_NOISE_PROFILE);
+        resultKeys.add(CaptureResult.SENSOR_GREEN_SPLIT);
+        resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_DATA);
+        resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE);
+        resultKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW);
+        resultKeys.add(CaptureResult.SHADING_MODE);
+        resultKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE);
+        resultKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE);
+        resultKeys.add(CaptureResult.STATISTICS_FACES);
+        resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
+        resultKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER);
+        resultKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP);
+        resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP_MODE);
+        resultKeys.add(CaptureResult.TONEMAP_CURVE);
+        resultKeys.add(CaptureResult.TONEMAP_MODE);
+        resultKeys.add(CaptureResult.TONEMAP_GAMMA);
+        resultKeys.add(CaptureResult.TONEMAP_PRESET_CURVE);
+        resultKeys.add(CaptureResult.BLACK_LEVEL_LOCK);
+        resultKeys.add(CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);
+
+        return resultKeys;
+    }
+
+    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
+     * End generated code
+     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
new file mode 100644
index 0000000..bddbd52
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/DngCreatorTest.java
@@ -0,0 +1,634 @@
+/*
+ * Copyright 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.hardware.camera2.cts;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.DngCreator;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.rs.BitmapUtils;
+import android.hardware.camera2.cts.rs.RawConverter;
+import android.hardware.camera2.cts.rs.RenderScriptSingleton;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+import android.location.Location;
+import android.media.ExifInterface;
+import android.media.Image;
+import android.media.ImageReader;
+import android.os.ConditionVariable;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Size;
+import android.view.Surface;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
+
+/**
+ * Tests for the DngCreator API.
+ */
+public class DngCreatorTest extends Camera2AndroidTestCase {
+    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 double IMAGE_DIFFERENCE_TOLERANCE = 65;
+    private static final int DEFAULT_PATCH_DIMEN = 512;
+    private static final int AE_TIMEOUT_MS = 2000;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        RenderScriptSingleton.clearContext();
+
+        super.tearDown();
+    }
+
+    @Override
+    public synchronized void setContext(Context context) {
+        super.setContext(context);
+
+        RenderScriptSingleton.setContext(context);
+    }
+
+    /**
+     * Test basic raw capture and DNG saving functionality for each of the available cameras.
+     *
+     * <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.
+     * </p>
+     *
+     * <p>
+     * Note: Enabling adb shell setprop log.tag.DngCreatorTest VERBOSE will also cause the
+     * raw image captured for the first reported camera device to be saved to an output file.
+     * </p>
+     */
+    public void testSingleImageBasic() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            String deviceId = mCameraIds[i];
+            ImageReader captureReader = null;
+            FileOutputStream fileStream = null;
+            ByteArrayOutputStream outputStream = 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.");
+                    continue;
+                }
+
+                Size activeArraySize = mStaticInfo.getRawDimensChecked();
+
+                // Create capture image reader
+                CameraTestUtils.SimpleImageReaderListener captureListener
+                        = new CameraTestUtils.SimpleImageReaderListener();
+                captureReader = createImageReader(activeArraySize, ImageFormat.RAW_SENSOR, 2,
+                        captureListener);
+                Pair<Image, CaptureResult> resultPair = captureSingleRawShot(activeArraySize,
+                        /*waitForAe*/false, captureReader, captureListener);
+                CameraCharacteristics characteristics = mStaticInfo.getCharacteristics();
+
+                // Test simple writeImage, no header checks
+                DngCreator dngCreator = new DngCreator(characteristics, resultPair.second);
+                outputStream = new ByteArrayOutputStream();
+                dngCreator.writeImage(outputStream, resultPair.first);
+
+                if (VERBOSE) {
+                    // Write DNG to file
+                    String dngFilePath = DEBUG_FILE_NAME_BASE + "/camera_basic_" + deviceId + "_" +
+                            DEBUG_DNG_FILE;
+                    // Write out captured DNG file for the first camera device if setprop is enabled
+                    fileStream = new FileOutputStream(dngFilePath);
+                    fileStream.write(outputStream.toByteArray());
+                    fileStream.flush();
+                    fileStream.close();
+                    Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + dngFilePath);
+                }
+            } finally {
+                closeDevice(deviceId);
+                closeImageReader(captureReader);
+
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+
+                if (fileStream != null) {
+                    fileStream.close();
+                }
+            }
+        }
+    }
+
+    /**
+     * Test basic raw capture and DNG saving with a thumbnail, rotation, usercomment, and GPS tags
+     * set.
+     *
+     * <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.
+     * </p>
+     *
+     * <p>
+     * Note: Enabling adb shell setprop log.tag.DngCreatorTest VERBOSE will also cause the
+     * raw image captured for the first reported camera device to be saved to an output file.
+     * </p>
+     */
+    public void testSingleImageThumbnail() 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>();
+            FileOutputStream fileStream = null;
+            ByteArrayOutputStream outputStream = 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.");
+                    continue;
+                }
+
+                Size activeArraySize = mStaticInfo.getRawDimensChecked();
+
+                Size[] targetPreviewSizes =
+                        mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.YUV_420_888,
+                                StaticMetadata.StreamDirection.Output);
+                // Get smallest preview size
+                Size previewSize = mOrderedPreviewSizes.get(mOrderedPreviewSizes.size() - 1);
+
+                // Create capture image reader
+                CameraTestUtils.SimpleImageReaderListener captureListener
+                        = new CameraTestUtils.SimpleImageReaderListener();
+                captureReaders.add(createImageReader(activeArraySize, ImageFormat.RAW_SENSOR, 2,
+                        captureListener));
+                captureListeners.add(captureListener);
+
+                CameraTestUtils.SimpleImageReaderListener previewListener
+                        = new CameraTestUtils.SimpleImageReaderListener();
+
+                captureReaders.add(createImageReader(previewSize, ImageFormat.YUV_420_888, 2,
+                        previewListener));
+                captureListeners.add(previewListener);
+
+                Pair<List<Image>, CaptureResult> resultPair = captureSingleRawShot(activeArraySize,
+                        captureReaders, /*waitForAe*/false, captureListeners);
+                CameraCharacteristics characteristics = mStaticInfo.getCharacteristics();
+
+                // Test simple writeImage, no header checks
+                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());
+                dngCreator.setLocation(l);
+
+                dngCreator.setDescription("helloworld");
+                dngCreator.setOrientation(ExifInterface.ORIENTATION_FLIP_VERTICAL);
+                dngCreator.setThumbnail(resultPair.first.get(1));
+                outputStream = new ByteArrayOutputStream();
+                dngCreator.writeImage(outputStream, resultPair.first.get(0));
+
+                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);
+                }
+            } finally {
+                closeDevice(deviceId);
+                for (ImageReader r : captureReaders) {
+                    closeImageReader(r);
+                }
+
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+
+                if (fileStream != null) {
+                    fileStream.close();
+                }
+            }
+        }
+    }
+
+    /**
+     * Test basic RAW capture, and ensure that the rendered RAW output is similar to the JPEG
+     * created for the same frame.
+     *
+     * <p>
+     * This test renders the RAW buffer into an RGB bitmap using a rendering pipeline
+     * similar to one in the Adobe DNG validation tool.  JPEGs produced by the vendor hardware may
+     * have different tonemapping and saturation applied than the RGB bitmaps produced
+     * from this DNG rendering pipeline, and this test allows for fairly wide variations
+     * between the histograms for the RAW and JPEG buffers to avoid false positives.
+     * </p>
+     *
+     * <p>
+     * To ensure more subtle errors in the colorspace transforms returned for the HAL's RAW
+     * metadata, the DNGs and JPEGs produced here should also be manually compared using external
+     * DNG rendering tools.  The DNG, rendered RGB bitmap, and JPEG buffer for this test can be
+     * dumped to the SD card for further examination by enabling the 'verbose' mode for this test
+     * using:
+     * adb shell setprop log.tag.DngCreatorTest VERBOSE
+     * </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>();
+            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.");
+                    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);
+
+                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
+                raw.getPlanes()[0].getBuffer().get(rawPlane);
+                raw.getPlanes()[0].getBuffer().rewind();
+
+                RawConverter.convertToSRGB(RenderScriptSingleton.getRS(), raw.getWidth(),
+                        raw.getHeight(), raw.getPlanes()[0].getRowStride(), rawPlane,
+                        characteristics, resultPair.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);
+
+                    // Write DNG to file
+                    String dngFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_" +
+                            DEBUG_DNG_FILE;
+                    // Write out captured DNG file for the first camera device if setprop is enabled
+                    fileStream = new FileOutputStream(dngFilePath);
+                    dngCreator.writeImage(fileStream, raw);
+                    fileStream.flush();
+                    fileStream.close();
+                    Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + dngFilePath);
+
+                    // Write JPEG to file
+                    String jpegFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_jpeg.jpg";
+                    // Write out captured DNG file for the first camera device if setprop is enabled
+                    fileChannel = new FileOutputStream(jpegFilePath).getChannel();
+                    ByteBuffer jPlane = jpeg.getPlanes()[0].getBuffer();
+                    fileChannel.write(jPlane);
+                    fileChannel.close();
+                    jPlane.rewind();
+                    Log.v(TAG, "Test JPEG file for camera " + deviceId + " saved to " +
+                            jpegFilePath);
+
+                    // Write jpeg generated from demosaiced RAW frame to file
+                    String rawFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_raw.jpg";
+                    // Write out captured DNG file for the first camera device if setprop is enabled
+                    fileStream = new FileOutputStream(rawFilePath);
+                    rawBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileStream);
+                    fileStream.flush();
+                    fileStream.close();
+                    Log.v(TAG, "Test converted RAW file for camera " + deviceId + " saved to " +
+                            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);
+                }
+
+            } finally {
+                closeDevice(deviceId);
+                for (ImageReader r : captureReaders) {
+                    closeImageReader(r);
+                }
+
+                if (fileChannel != null) {
+                    fileChannel.close();
+                }
+
+                if (outputStream != null) {
+                    outputStream.close();
+                }
+
+                if (fileStream != null) {
+                    fileStream.close();
+                }
+            }
+        }
+    }
+
+    private Pair<Image, CaptureResult> captureSingleRawShot(Size s, boolean waitForAe,
+            ImageReader captureReader,
+            CameraTestUtils.SimpleImageReaderListener captureListener) throws Exception {
+        List<ImageReader> readers = new ArrayList<ImageReader>();
+        readers.add(captureReader);
+        List<CameraTestUtils.SimpleImageReaderListener> listeners =
+                new ArrayList<CameraTestUtils.SimpleImageReaderListener>();
+        listeners.add(captureListener);
+        Pair<List<Image>, CaptureResult> res = captureSingleRawShot(s, readers, waitForAe,
+                listeners);
+        return new Pair<Image, CaptureResult>(res.first.get(0), res.second);
+    }
+
+    private Pair<List<Image>, CaptureResult> captureSingleRawShot(Size s,
+            List<ImageReader> captureReaders, boolean waitForAe,
+            List<CameraTestUtils.SimpleImageReaderListener> captureListeners) throws Exception {
+        return captureRawShots(s, captureReaders, waitForAe, captureListeners, 1).get(0);
+    }
+
+    /**
+     * Capture raw images.
+     *
+     * <p>Capture raw images for a given size.</p>
+     *
+     * @param s The size of the raw image to capture.  Must be one of the available sizes for this
+     *          device.
+     * @return a list of pairs containing a {@link Image} and {@link CaptureResult} used for
+     *          each capture.
+     */
+    private List<Pair<List<Image>, CaptureResult>> captureRawShots(Size s,
+            List<ImageReader> captureReaders, boolean waitForAe,
+            List<CameraTestUtils.SimpleImageReaderListener> captureListeners,
+            int numShots) throws Exception {
+        if (VERBOSE) {
+            Log.v(TAG, "captureSingleRawShot - Capturing raw image.");
+        }
+
+        Size[] targetCaptureSizes =
+                mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
+                        StaticMetadata.StreamDirection.Output);
+
+        // Validate size
+        boolean validSize = false;
+        for (int i = 0; i < targetCaptureSizes.length; ++i) {
+            if (targetCaptureSizes[i].equals(s)) {
+                validSize = true;
+                break;
+            }
+        }
+        assertTrue("Capture size is supported.", validSize);
+
+        // Capture images.
+        final List<Surface> outputSurfaces = new ArrayList<Surface>();
+        for (ImageReader captureReader : captureReaders) {
+            Surface captureSurface = captureReader.getSurface();
+            outputSurfaces.add(captureSurface);
+        }
+
+        // Set up still capture template targeting JPEG/RAW outputs
+        CaptureRequest.Builder request =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+        assertNotNull("Fail to get captureRequest", request);
+        for (Surface surface : outputSurfaces) {
+            request.addTarget(surface);
+        }
+
+        ImageReader previewReader = null;
+        if (waitForAe) {
+            // Also setup a small YUV output for AE metering if needed
+            Size yuvSize = (mOrderedPreviewSizes.size() == 0) ? null :
+                    mOrderedPreviewSizes.get(mOrderedPreviewSizes.size() - 1);
+            assertNotNull("Must support at least one small YUV size.", yuvSize);
+            previewReader = createImageReader(yuvSize, ImageFormat.YUV_420_888,
+                        /*maxNumImages*/2, new CameraTestUtils.ImageDropperListener());
+            outputSurfaces.add(previewReader.getSurface());
+        }
+
+        createSession(outputSurfaces);
+
+        if (waitForAe) {
+            CaptureRequest.Builder precaptureRequest =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+            assertNotNull("Fail to get captureRequest", precaptureRequest);
+            precaptureRequest.addTarget(previewReader.getSurface());
+            precaptureRequest.set(CaptureRequest.CONTROL_MODE,
+                    CaptureRequest.CONTROL_MODE_AUTO);
+            precaptureRequest.set(CaptureRequest.CONTROL_AE_MODE,
+                    CaptureRequest.CONTROL_AE_MODE_ON);
+
+            final ConditionVariable waitForAeCondition = new ConditionVariable(/*isOpen*/false);
+            CameraCaptureSession.CaptureCallback captureCallback =
+                    new CameraCaptureSession.CaptureCallback() {
+                @Override
+                public void onCaptureProgressed(CameraCaptureSession session,
+                        CaptureRequest request, CaptureResult partialResult) {
+                    if (partialResult.get(CaptureResult.CONTROL_AE_STATE) ==
+                            CaptureRequest.CONTROL_AE_STATE_CONVERGED) {
+                        waitForAeCondition.open();
+                    }
+                }
+
+                @Override
+                public void onCaptureCompleted(CameraCaptureSession session,
+                        CaptureRequest request, TotalCaptureResult result) {
+                    if (result.get(CaptureResult.CONTROL_AE_STATE) ==
+                            CaptureRequest.CONTROL_AE_STATE_CONVERGED) {
+                        waitForAeCondition.open();
+                    }
+                }
+            };
+            startCapture(precaptureRequest.build(), /*repeating*/true, captureCallback, mHandler);
+
+            precaptureRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+            startCapture(precaptureRequest.build(), /*repeating*/false, captureCallback, mHandler);
+            assertTrue("Timeout out waiting for AE to converge",
+                    waitForAeCondition.block(AE_TIMEOUT_MS));
+        }
+
+        request.set(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE,
+                CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE_ON);
+        CameraTestUtils.SimpleCaptureCallback resultListener =
+                new CameraTestUtils.SimpleCaptureCallback();
+
+        CaptureRequest request1 = request.build();
+        for (int i = 0; i < numShots; i++) {
+            startCapture(request1, /*repeating*/false, resultListener, mHandler);
+        }
+        List<Pair<List<Image>, CaptureResult>> ret = new ArrayList<>();
+        for (int i = 0; i < numShots; i++) {
+            // Verify capture result and images
+            CaptureResult result = resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
+
+            List<Image> resultImages = new ArrayList<Image>();
+            for (CameraTestUtils.SimpleImageReaderListener captureListener : captureListeners) {
+                Image captureImage = captureListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
+
+            /*CameraTestUtils.validateImage(captureImage, s.getWidth(), s.getHeight(),
+                    ImageFormat.RAW_SENSOR, null);*/
+                resultImages.add(captureImage);
+            }
+            ret.add(new Pair<List<Image>, CaptureResult>(resultImages, result));
+        }
+        // Stop capture, delete the streams.
+        stopCapture(/*fast*/false);
+
+        return ret;
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
new file mode 100644
index 0000000..28693c6
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
@@ -0,0 +1,1376 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import android.content.Context;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraCharacteristics.Key;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.cts.helpers.CameraErrorCollector;
+import android.hardware.camera2.params.BlackLevelPattern;
+import android.hardware.camera2.params.ColorSpaceTransform;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.CamcorderProfile;
+import android.media.ImageReader;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.util.Rational;
+import android.util.Range;
+import android.util.Size;
+import android.view.Surface;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
+
+/**
+ * Extended tests for static camera characteristics.
+ */
+public class ExtendedCameraCharacteristicsTest extends AndroidTestCase {
+    private static final String TAG = "ExChrsTest"; // must be short so next line doesn't throw
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    private static final String PREFIX_ANDROID = "android";
+    private static final String PREFIX_VENDOR = "com";
+
+    /*
+     * Constants for static RAW metadata.
+     */
+    private static final int MIN_ALLOWABLE_WHITELEVEL = 32; // must have sensor bit depth > 5
+
+    private CameraManager mCameraManager;
+    private List<CameraCharacteristics> mCharacteristics;
+    private String[] mIds;
+    private CameraErrorCollector mCollector;
+
+    private static final Size FULLHD = new Size(1920, 1080);
+    private static final Size FULLHD_ALT = new Size(1920, 1088);
+    private static final Size HD = new Size(1280, 720);
+    private static final Size VGA = new Size(640, 480);
+    private static final Size QVGA = new Size(320, 240);
+
+    /*
+     * HW Levels short hand
+     */
+    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 OPT = Integer.MAX_VALUE;  // For keys that are optional on all hardware levels.
+
+    /*
+     * Capabilities short hand
+     */
+    private static final int NONE = -1;
+    private static final int BC =
+            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE;
+    private static final int MANUAL_SENSOR =
+            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR;
+    private static final int MANUAL_POSTPROC =
+            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING;
+    private static final int RAW =
+            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW;
+    private static final int YUV_REPROCESS =
+            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING;
+    private static final int OPAQUE_REPROCESS =
+            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING;
+    private static final int CONSTRAINED_HIGH_SPEED =
+            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO;
+    private static final int HIGH_SPEED_FPS_LOWER_MIN = 30;
+    private static final int HIGH_SPEED_FPS_UPPER_MIN = 120;
+
+    @Override
+    public void setContext(Context context) {
+        super.setContext(context);
+        mCameraManager = (CameraManager)context.getSystemService(Context.CAMERA_SERVICE);
+        assertNotNull("Can't connect to camera manager", mCameraManager);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mIds = mCameraManager.getCameraIdList();
+        mCharacteristics = new ArrayList<>();
+        mCollector = new CameraErrorCollector();
+        for (int i = 0; i < mIds.length; i++) {
+            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(mIds[i]);
+            assertNotNull(String.format("Can't get camera characteristics from: ID %s", mIds[i]),
+                    props);
+            mCharacteristics.add(props);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mCharacteristics = null;
+
+        try {
+            mCollector.verify();
+        } catch (Throwable e) {
+            // When new Exception(e) is used, exception info will be printed twice.
+            throw new Exception(e.getMessage());
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    /**
+     * Test that the available stream configurations contain a few required formats and sizes.
+     */
+    public void testAvailableStreamConfigs() {
+        int counter = 0;
+        for (CameraCharacteristics c : mCharacteristics) {
+            StreamConfigurationMap config =
+                    c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+            assertNotNull(String.format("No stream configuration map found for: ID %s",
+                    mIds[counter]), config);
+            int[] outputFormats = config.getOutputFormats();
+
+            int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+            assertNotNull("android.request.availableCapabilities must never be null",
+                    actualCapabilities);
+
+            // Check required formats exist (JPEG, and YUV_420_888).
+            if (!arrayContains(actualCapabilities, BC)) {
+                Log.i(TAG, "Camera " + mIds[counter] +
+                    ": BACKWARD_COMPATIBLE capability not supported, skipping test");
+                continue;
+            }
+
+            assertArrayContains(
+                    String.format("No valid YUV_420_888 preview formats found for: ID %s",
+                            mIds[counter]), outputFormats, ImageFormat.YUV_420_888);
+            assertArrayContains(String.format("No JPEG image format for: ID %s",
+                    mIds[counter]), outputFormats, ImageFormat.JPEG);
+
+            Size[] yuvSizes = config.getOutputSizes(ImageFormat.YUV_420_888);
+            Size[] jpegSizes = config.getOutputSizes(ImageFormat.JPEG);
+            Size[] privateSizes = config.getOutputSizes(ImageFormat.PRIVATE);
+
+            CameraTestUtils.assertArrayNotEmpty(yuvSizes,
+                    String.format("No sizes for preview format %x for: ID %s",
+                            ImageFormat.YUV_420_888, mIds[counter]));
+
+            Rect activeRect = CameraTestUtils.getValueNotNull(
+                    c, CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+            Size activeArraySize = new Size(activeRect.width(), activeRect.height());
+            Integer hwLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+
+            if (activeArraySize.getWidth() >= FULLHD.getWidth() &&
+                    activeArraySize.getHeight() >= FULLHD.getHeight()) {
+                assertArrayContainsAnyOf(String.format(
+                        "Required FULLHD size not found for format %x for: ID %s",
+                        ImageFormat.JPEG, mIds[counter]), jpegSizes,
+                        new Size[] {FULLHD, FULLHD_ALT});
+            }
+
+            if (activeArraySize.getWidth() >= HD.getWidth() &&
+                    activeArraySize.getHeight() >= HD.getHeight()) {
+                assertArrayContains(String.format(
+                        "Required HD size not found for format %x for: ID %s",
+                        ImageFormat.JPEG, mIds[counter]), jpegSizes, HD);
+            }
+
+            if (activeArraySize.getWidth() >= VGA.getWidth() &&
+                    activeArraySize.getHeight() >= VGA.getHeight()) {
+                assertArrayContains(String.format(
+                        "Required VGA size not found for format %x for: ID %s",
+                        ImageFormat.JPEG, mIds[counter]), jpegSizes, VGA);
+            }
+
+            if (activeArraySize.getWidth() >= QVGA.getWidth() &&
+                    activeArraySize.getHeight() >= QVGA.getHeight()) {
+                assertArrayContains(String.format(
+                        "Required QVGA size not found for format %x for: ID %s",
+                        ImageFormat.JPEG, mIds[counter]), jpegSizes, QVGA);
+            }
+
+            ArrayList<Size> jpegSizesList = new ArrayList<>(Arrays.asList(jpegSizes));
+            ArrayList<Size> yuvSizesList = new ArrayList<>(Arrays.asList(yuvSizes));
+            ArrayList<Size> privateSizesList = new ArrayList<>(Arrays.asList(privateSizes));
+
+            CamcorderProfile maxVideoProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
+            Size maxVideoSize = new Size(
+                    maxVideoProfile.videoFrameWidth, maxVideoProfile.videoFrameHeight);
+
+            // Handle FullHD special case first
+            if (jpegSizesList.contains(FULLHD)) {
+                if (hwLevel == FULL || (hwLevel == LIMITED &&
+                        maxVideoSize.getWidth() >= FULLHD.getWidth() &&
+                        maxVideoSize.getHeight() >= FULLHD.getHeight())) {
+                    boolean yuvSupportFullHD = yuvSizesList.contains(FULLHD) ||
+                            yuvSizesList.contains(FULLHD_ALT);
+                    boolean privateSupportFullHD = privateSizesList.contains(FULLHD) ||
+                            privateSizesList.contains(FULLHD_ALT);
+                    assertTrue("Full device FullHD YUV size not found", yuvSupportFullHD);
+                    assertTrue("Full device FullHD PRIVATE size not found", privateSupportFullHD);
+                }
+                // remove all FullHD or FullHD_Alt sizes for the remaining of the test
+                jpegSizesList.remove(FULLHD);
+                jpegSizesList.remove(FULLHD_ALT);
+            }
+
+            // Check all sizes other than FullHD
+            if (hwLevel == LIMITED) {
+                // Remove all jpeg sizes larger than max video size
+                ArrayList<Size> toBeRemoved = new ArrayList<>();
+                for (Size size : jpegSizesList) {
+                    if (size.getWidth() >= maxVideoSize.getWidth() &&
+                            size.getHeight() >= maxVideoSize.getHeight()) {
+                        toBeRemoved.add(size);
+                    }
+                }
+                jpegSizesList.removeAll(toBeRemoved);
+            }
+
+            if (hwLevel == FULL || hwLevel == LIMITED) {
+                if (!yuvSizesList.containsAll(jpegSizesList)) {
+                    for (Size s : jpegSizesList) {
+                        if (!yuvSizesList.contains(s)) {
+                            fail("Size " + s + " not found in YUV format");
+                        }
+                    }
+                }
+            }
+
+            if (!privateSizesList.containsAll(yuvSizesList)) {
+                for (Size s : yuvSizesList) {
+                    if (!privateSizesList.contains(s)) {
+                        fail("Size " + s + " not found in PRIVATE format");
+                    }
+                }
+            }
+
+            counter++;
+        }
+    }
+
+    /**
+     * Test {@link CameraCharacteristics#getKeys}
+     */
+    public void testKeys() {
+        int counter = 0;
+        for (CameraCharacteristics c : mCharacteristics) {
+            mCollector.setCameraId(mIds[counter]);
+
+            if (VERBOSE) {
+                Log.v(TAG, "testKeys - testing characteristics for camera " + mIds[counter]);
+            }
+
+            List<CameraCharacteristics.Key<?>> allKeys = c.getKeys();
+            assertNotNull("Camera characteristics keys must not be null", allKeys);
+            assertFalse("Camera characteristics keys must have at least 1 key",
+                    allKeys.isEmpty());
+
+            for (CameraCharacteristics.Key<?> key : allKeys) {
+                assertKeyPrefixValid(key.getName());
+
+                // All characteristics keys listed must never be null
+                mCollector.expectKeyValueNotNull(c, key);
+
+                // TODO: add a check that key must not be @hide
+            }
+
+            /*
+             * List of keys that must be present in camera characteristics (not null).
+             *
+             * Keys for LIMITED, FULL devices might be available despite lacking either
+             * the hardware level or the capability. This is *OK*. This only lists the
+             * *minimal* requirements for a key to be listed.
+             *
+             * LEGACY devices are a bit special since they map to api1 devices, so we know
+             * for a fact most keys are going to be illegal there so they should never be
+             * available.
+             *
+             * For LIMITED-level keys, if the level is >= LIMITED, then the capabilities are used to
+             * do the actual checking.
+             */
+            {
+                //                                           (Key Name)                                     (HW Level)  (Capabilities <Var-Arg>)
+                expectKeyAvailable(c, CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES     , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AVAILABLE_MODES                         , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES          , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES                      , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES          , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE                   , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP                    , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE                       , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES                      , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS                       , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES                   , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES     , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES                     , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE                      , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_MAX_REGIONS_AE                          , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_MAX_REGIONS_AF                          , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.CONTROL_MAX_REGIONS_AWB                         , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES                       , FULL     ,   NONE                 );
+                expectKeyAvailable(c, CameraCharacteristics.FLASH_INFO_AVAILABLE                            , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES             , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL                   , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES                  , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.LENS_FACING                                     , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES                   , FULL     ,   MANUAL_SENSOR        );
+                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_AVAILABLE_FILTER_DENSITIES            , FULL     ,   MANUAL_SENSOR        );
+                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS               , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION       , LIMITED  ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION            , LIMITED  ,   MANUAL_SENSOR        );
+                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE                   , LIMITED  ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE                , LIMITED  ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES                  , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.REQUEST_MAX_NUM_INPUT_STREAMS                   , OPT      ,   YUV_REPROCESS, OPAQUE_REPROCESS);
+                expectKeyAvailable(c, CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP                 , OPT      ,   CONSTRAINED_HIGH_SPEED);
+                expectKeyAvailable(c, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC                     , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING            , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW                      , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT                    , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH                      , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM               , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP                 , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SCALER_CROPPING_TYPE                            , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES             , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN                      , FULL     ,   MANUAL_SENSOR, RAW   );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1                   , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_COLOR_TRANSFORM1                         , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_FORWARD_MATRIX1                          , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE                   , OPT      ,   BC, RAW              );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT            , FULL     ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE                 , FULL     ,   MANUAL_SENSOR        );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION                  , FULL     ,   MANUAL_SENSOR        );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE                       , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE                    , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE                   , FULL     ,   MANUAL_SENSOR        );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL                         , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE                    , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_MAX_ANALOG_SENSITIVITY                   , FULL     ,   MANUAL_SENSOR        );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_ORIENTATION                              , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1                    , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.SHADING_AVAILABLE_MODES                         , LIMITED  ,   MANUAL_POSTPROC, RAW );
+                expectKeyAvailable(c, CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES     , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES   , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES, LIMITED  ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT                  , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.SYNC_MAX_LATENCY                                , OPT      ,   BC                   );
+                expectKeyAvailable(c, CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES                , FULL     ,   MANUAL_POSTPROC      );
+                expectKeyAvailable(c, CameraCharacteristics.TONEMAP_MAX_CURVE_POINTS                        , FULL     ,   MANUAL_POSTPROC      );
+
+                // Future: Use column editors for modifying above, ignore line length to keep 1 key per line
+
+                // TODO: check that no other 'android' keys are listed in #getKeys if they aren't in the above list
+            }
+
+            // Only check for these if the second reference illuminant is included
+            if (allKeys.contains(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2)) {
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2                    , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_COLOR_TRANSFORM2                         , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2                   , OPT      ,   RAW                  );
+                expectKeyAvailable(c, CameraCharacteristics.SENSOR_FORWARD_MATRIX2                          , OPT      ,   RAW                  );
+            }
+
+            counter++;
+        }
+    }
+
+    /**
+     * Test values for static metadata used by the RAW capability.
+     */
+    public void testStaticRawCharacteristics() {
+        int counter = 0;
+        for (CameraCharacteristics c : mCharacteristics) {
+            int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+            assertNotNull("android.request.availableCapabilities must never be null",
+                    actualCapabilities);
+            if (!arrayContains(actualCapabilities,
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                Log.i(TAG, "RAW capability is not supported in camera " + counter++ +
+                        ". Skip the test.");
+                continue;
+            }
+
+            Integer actualHwLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+            if (actualHwLevel != null && actualHwLevel == FULL) {
+                mCollector.expectKeyValueContains(c,
+                        CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
+                        CameraCharacteristics.HOT_PIXEL_MODE_FAST);
+            }
+            mCollector.expectKeyValueContains(c,
+                    CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES, false);
+            mCollector.expectKeyValueGreaterThan(c, CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL,
+                    MIN_ALLOWABLE_WHITELEVEL);
+
+            mCollector.expectKeyValueIsIn(c,
+                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
+                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB,
+                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG,
+                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG,
+                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR);
+            // TODO: SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB isn't supported yet.
+
+            mCollector.expectKeyValueInRange(c, CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1,
+                    CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT,
+                    CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN);
+            mCollector.expectKeyValueInRange(c, CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2,
+                    (byte) CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT,
+                    (byte) CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN);
+
+            Rational[] zeroes = new Rational[9];
+            Arrays.fill(zeroes, Rational.ZERO);
+
+            ColorSpaceTransform zeroed = new ColorSpaceTransform(zeroes);
+            mCollector.expectNotEquals("Forward Matrix1 should not contain all zeroes.", zeroed,
+                    c.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX1));
+            mCollector.expectNotEquals("Forward Matrix2 should not contain all zeroes.", zeroed,
+                    c.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX2));
+            mCollector.expectNotEquals("Calibration Transform1 should not contain all zeroes.",
+                    zeroed, c.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1));
+            mCollector.expectNotEquals("Calibration Transform2 should not contain all zeroes.",
+                    zeroed, c.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2));
+            mCollector.expectNotEquals("Color Transform1 should not contain all zeroes.",
+                    zeroed, c.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM1));
+            mCollector.expectNotEquals("Color Transform2 should not contain all zeroes.",
+                    zeroed, c.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM2));
+
+            BlackLevelPattern blackLevel = mCollector.expectKeyValueNotNull(c,
+                    CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN);
+            if (blackLevel != null) {
+                String blackLevelPatternString = blackLevel.toString();
+                if (VERBOSE) {
+                    Log.v(TAG, "Black level pattern: " + blackLevelPatternString);
+                }
+                int[] blackLevelPattern = new int[BlackLevelPattern.COUNT];
+                blackLevel.copyTo(blackLevelPattern, /*offset*/0);
+                Integer whitelevel = c.get(CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL);
+                if (whitelevel != null) {
+                    mCollector.expectValuesInRange("BlackLevelPattern", blackLevelPattern, 0,
+                            whitelevel);
+                } else {
+                    mCollector.addMessage(
+                            "No WhiteLevel available, cannot check BlackLevelPattern range.");
+                }
+            }
+
+            // TODO: profileHueSatMap, and profileToneCurve aren't supported yet.
+            counter++;
+        }
+    }
+
+    /**
+     * Test values for static metadata used by the BURST capability.
+     */
+    public void testStaticBurstCharacteristics() throws Exception {
+        int counter = 0;
+        final float SIZE_ERROR_MARGIN = 0.03f;
+        for (CameraCharacteristics c : mCharacteristics) {
+            int[] actualCapabilities = CameraTestUtils.getValueNotNull(
+                    c, CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+
+            // Check if the burst capability is defined
+            boolean haveBurstCapability = arrayContains(actualCapabilities,
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
+            boolean haveBC = arrayContains(actualCapabilities,
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
+
+            if(haveBurstCapability && !haveBC) {
+                fail("Must have BACKWARD_COMPATIBLE capability if BURST_CAPTURE capability is defined");
+            }
+
+            if (!haveBC) continue;
+
+            StreamConfigurationMap config =
+                    c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+            assertNotNull(String.format("No stream configuration map found for: ID %s",
+                    mIds[counter]), config);
+            Rect activeRect = CameraTestUtils.getValueNotNull(
+                    c, CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+            Size sensorSize = new Size(activeRect.width(), activeRect.height());
+
+            // Ensure that max YUV size matches max JPEG size
+            Size maxYuvSize = CameraTestUtils.getMaxSize(
+                    config.getOutputSizes(ImageFormat.YUV_420_888));
+            Size maxFastYuvSize = maxYuvSize;
+
+            Size[] slowYuvSizes = config.getHighResolutionOutputSizes(ImageFormat.YUV_420_888);
+            if (haveBurstCapability && slowYuvSizes != null && slowYuvSizes.length > 0) {
+                Size maxSlowYuvSize = CameraTestUtils.getMaxSize(slowYuvSizes);
+                maxYuvSize = CameraTestUtils.getMaxSize(new Size[]{maxYuvSize, maxSlowYuvSize});
+            }
+
+            Size maxJpegSize = CameraTestUtils.getMaxSize(CameraTestUtils.getSupportedSizeForFormat(
+                    ImageFormat.JPEG, mIds[counter], mCameraManager));
+
+            boolean haveMaxYuv = maxYuvSize != null ?
+                (maxJpegSize.getWidth() <= maxYuvSize.getWidth() &&
+                        maxJpegSize.getHeight() <= maxYuvSize.getHeight()) : false;
+
+            boolean maxYuvMatchSensor =
+                    (maxYuvSize.getWidth() <= sensorSize.getWidth() * (1.0 + SIZE_ERROR_MARGIN) &&
+                     maxYuvSize.getWidth() >= sensorSize.getWidth() * (1.0 - SIZE_ERROR_MARGIN) &&
+                     maxYuvSize.getHeight() <= sensorSize.getHeight() * (1.0 + SIZE_ERROR_MARGIN) &&
+                     maxYuvSize.getHeight() >= sensorSize.getHeight() * (1.0 - SIZE_ERROR_MARGIN));
+
+            // No need to do null check since framework will generate the key if HAL don't supply
+            boolean haveAeLock = CameraTestUtils.getValueNotNull(
+                    c, CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE);
+            boolean haveAwbLock = CameraTestUtils.getValueNotNull(
+                    c, CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE);
+
+            // Ensure that max YUV output is fast enough - needs to be at least 10 fps
+
+            long maxYuvRate =
+                config.getOutputMinFrameDuration(ImageFormat.YUV_420_888, maxYuvSize);
+            final long MIN_MAXSIZE_DURATION_BOUND_NS = 100000000; // 100 ms, 10 fps
+            boolean haveMaxYuvRate = maxYuvRate <= MIN_MAXSIZE_DURATION_BOUND_NS;
+
+            // Ensure that some >=8MP YUV output is fast enough - needs to be at least 20 fps
+
+            long maxFastYuvRate =
+                    config.getOutputMinFrameDuration(ImageFormat.YUV_420_888, maxFastYuvSize);
+            final long MIN_8MP_DURATION_BOUND_NS = 200000000; // 50 ms, 20 fps
+            boolean haveFastYuvRate = maxFastYuvRate <= MIN_8MP_DURATION_BOUND_NS;
+
+            final int SIZE_8MP_BOUND = 8000000;
+            boolean havefast8MPYuv = (maxFastYuvSize.getWidth() * maxFastYuvSize.getHeight()) >
+                    SIZE_8MP_BOUND;
+
+            // Ensure that there's an FPS range that's fast enough to capture at above
+            // minFrameDuration, for full-auto bursts at the fast resolutions
+            Range[] fpsRanges = CameraTestUtils.getValueNotNull(
+                    c, CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
+            float minYuvFps = 1.f / maxFastYuvRate;
+
+            boolean haveFastAeTargetFps = false;
+            for (Range<Integer> r : fpsRanges) {
+                if (r.getLower() >= minYuvFps) {
+                    haveFastAeTargetFps = true;
+                    break;
+                }
+            }
+
+            // Ensure that maximum sync latency is small enough for fast setting changes, even if
+            // it's not quite per-frame
+
+            Integer maxSyncLatencyValue = c.get(CameraCharacteristics.SYNC_MAX_LATENCY);
+            assertNotNull(String.format("No sync latency declared for ID %s", mIds[counter]),
+                    maxSyncLatencyValue);
+
+            int maxSyncLatency = maxSyncLatencyValue;
+            final long MAX_LATENCY_BOUND = 4;
+            boolean haveFastSyncLatency =
+                (maxSyncLatency <= MAX_LATENCY_BOUND) && (maxSyncLatency >= 0);
+
+            if (haveBurstCapability) {
+                assertTrue("Must have slow YUV size array when BURST_CAPTURE capability is defined!",
+                        slowYuvSizes != null);
+                assertTrue(
+                        String.format("BURST-capable camera device %s does not have maximum YUV " +
+                                "size that is at least max JPEG size",
+                                mIds[counter]),
+                        haveMaxYuv);
+                assertTrue(
+                        String.format("BURST-capable camera device %s max-resolution " +
+                                "YUV frame rate is too slow" +
+                                "(%d ns min frame duration reported, less than %d ns expected)",
+                                mIds[counter], maxYuvRate, MIN_MAXSIZE_DURATION_BOUND_NS),
+                        haveMaxYuvRate);
+                assertTrue(
+                        String.format("BURST-capable camera device %s >= 8MP YUV output " +
+                                "frame rate is too slow" +
+                                "(%d ns min frame duration reported, less than %d ns expected)",
+                                mIds[counter], maxYuvRate, MIN_8MP_DURATION_BOUND_NS),
+                        haveFastYuvRate);
+                assertTrue(
+                        String.format("BURST-capable camera device %s does not list an AE target " +
+                                " FPS range with min FPS >= %f, for full-AUTO bursts",
+                                mIds[counter], minYuvFps),
+                        haveFastAeTargetFps);
+                assertTrue(
+                        String.format("BURST-capable camera device %s YUV sync latency is too long" +
+                                "(%d frames reported, [0, %d] frames expected)",
+                                mIds[counter], maxSyncLatency, MAX_LATENCY_BOUND),
+                        haveFastSyncLatency);
+                assertTrue(
+                        String.format("BURST-capable camera device %s max YUV size %s should be" +
+                                "close to active array size %s",
+                                mIds[counter], maxYuvSize.toString(), sensorSize.toString()),
+                        maxYuvMatchSensor);
+                assertTrue(
+                        String.format("BURST-capable camera device %s does not support AE lock",
+                                mIds[counter]),
+                        haveAeLock);
+                assertTrue(
+                        String.format("BURST-capable camera device %s does not support AWB lock",
+                                mIds[counter]),
+                        haveAwbLock);
+            } else {
+                assertTrue("Must have null slow YUV size array when no BURST_CAPTURE capability!",
+                        slowYuvSizes == null);
+                assertTrue(
+                        String.format("Camera device %s has all the requirements for BURST" +
+                                " capability but does not report it!", mIds[counter]),
+                        !(haveMaxYuv && haveMaxYuvRate && haveFastAeTargetFps &&
+                                haveFastSyncLatency && maxYuvMatchSensor &&
+                                haveAeLock && haveAwbLock));
+            }
+
+            counter++;
+        }
+    }
+
+    /**
+     * Check reprocessing capabilities.
+     */
+    public void testReprocessingCharacteristics() {
+        int counter = 0;
+
+        for (CameraCharacteristics c : mCharacteristics) {
+            Log.i(TAG, "testReprocessingCharacteristics: Testing camera ID " + mIds[counter]);
+
+            int[] capabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+            assertNotNull("android.request.availableCapabilities must never be null",
+                    capabilities);
+            boolean supportYUV = arrayContains(capabilities,
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);
+            boolean supportOpaque = arrayContains(capabilities,
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);
+            StreamConfigurationMap configs =
+                    c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+            Integer maxNumInputStreams =
+                    c.get(CameraCharacteristics.REQUEST_MAX_NUM_INPUT_STREAMS);
+            int[] availableEdgeModes = c.get(CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES);
+            int[] availableNoiseReductionModes = c.get(
+                    CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES);
+
+            int[] inputFormats = configs.getInputFormats();
+
+            boolean supportZslEdgeMode = false;
+            boolean supportZslNoiseReductionMode = false;
+
+            if (availableEdgeModes != null) {
+                supportZslEdgeMode = Arrays.asList(CameraTestUtils.toObject(availableEdgeModes)).
+                        contains(CaptureRequest.EDGE_MODE_ZERO_SHUTTER_LAG);
+            }
+
+            if (availableNoiseReductionModes != null) {
+                supportZslNoiseReductionMode = Arrays.asList(
+                        CameraTestUtils.toObject(availableNoiseReductionModes)).contains(
+                        CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG);
+            }
+
+            if (supportYUV || supportOpaque) {
+                mCollector.expectTrue("Support reprocessing but max number of input stream is " +
+                        maxNumInputStreams, maxNumInputStreams != null && maxNumInputStreams > 0);
+                mCollector.expectTrue("Support reprocessing but EDGE_MODE_ZERO_SHUTTER_LAG is " +
+                        "not supported", supportZslEdgeMode);
+                mCollector.expectTrue("Support reprocessing but " +
+                        "NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG is not supported",
+                        supportZslNoiseReductionMode);
+
+                // 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));
+                mCollector.expectTrue("PRIVATE input must be supported for OPAQUE reprocessing",
+                        !supportOpaque || arrayContains(inputFormats, ImageFormat.PRIVATE));
+
+                // max capture stall must be reported if one of the reprocessing is supported.
+                final int MAX_ALLOWED_STALL_FRAMES = 4;
+                Integer maxCaptureStall = c.get(CameraCharacteristics.REPROCESS_MAX_CAPTURE_STALL);
+                mCollector.expectTrue("max capture stall must be non-null and no larger than "
+                        + MAX_ALLOWED_STALL_FRAMES,
+                        maxCaptureStall != null && maxCaptureStall <= MAX_ALLOWED_STALL_FRAMES);
+
+                for (int input : inputFormats) {
+                    // Verify mandatory output formats are supported
+                    int[] outputFormats = configs.getValidOutputFormatsForInput(input);
+                    mCollector.expectTrue("YUV_420_888 output must be supported for reprocessing",
+                            arrayContains(outputFormats, ImageFormat.YUV_420_888));
+                    mCollector.expectTrue("JPEG output must be supported for reprocessing",
+                            arrayContains(outputFormats, ImageFormat.JPEG));
+
+                    // Verify camera can output the reprocess input formats and sizes.
+                    Size[] inputSizes = configs.getInputSizes(input);
+                    Size[] outputSizes = configs.getOutputSizes(input);
+                    Size[] highResOutputSizes = configs.getHighResolutionOutputSizes(input);
+                    mCollector.expectTrue("no input size supported for format " + input,
+                            inputSizes.length > 0);
+                    mCollector.expectTrue("no output size supported for format " + input,
+                            outputSizes.length > 0);
+
+                    for (Size inputSize : inputSizes) {
+                        mCollector.expectTrue("Camera must be able to output the supported " +
+                                "reprocessing input size",
+                                arrayContains(outputSizes, inputSize) ||
+                                arrayContains(highResOutputSizes, inputSize));
+                    }
+                }
+            } else {
+                mCollector.expectTrue("Doesn't support reprocessing but report input format: " +
+                        Arrays.toString(inputFormats), inputFormats.length == 0);
+                mCollector.expectTrue("Doesn't support reprocessing but max number of input " +
+                        "stream is " + maxNumInputStreams,
+                        maxNumInputStreams == null || maxNumInputStreams == 0);
+                mCollector.expectTrue("Doesn't support reprocessing but " +
+                        "EDGE_MODE_ZERO_SHUTTER_LAG is supported", !supportZslEdgeMode);
+                mCollector.expectTrue("Doesn't support reprocessing but " +
+                        "NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG is supported",
+                        !supportZslNoiseReductionMode);
+            }
+        }
+    }
+
+    /**
+     * Check depth output capability
+     */
+    public void testDepthOutputCharacteristics() {
+        int counter = 0;
+
+        for (CameraCharacteristics c : mCharacteristics) {
+            Log.i(TAG, "testDepthOutputCharacteristics: Testing camera ID " + mIds[counter]);
+
+            int[] capabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+            assertNotNull("android.request.availableCapabilities must never be null",
+                    capabilities);
+            boolean supportDepth = arrayContains(capabilities,
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT);
+            StreamConfigurationMap configs =
+                    c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+
+            int[] outputFormats = configs.getOutputFormats();
+            boolean hasDepth16 = arrayContains(outputFormats, ImageFormat.DEPTH16);
+
+            Boolean depthIsExclusive = c.get(CameraCharacteristics.DEPTH_DEPTH_IS_EXCLUSIVE);
+
+            float[] poseRotation = c.get(CameraCharacteristics.LENS_POSE_ROTATION);
+            float[] poseTranslation = c.get(CameraCharacteristics.LENS_POSE_TRANSLATION);
+            float[] cameraIntrinsics = c.get(CameraCharacteristics.LENS_INTRINSIC_CALIBRATION);
+            float[] radialDistortion = c.get(CameraCharacteristics.LENS_RADIAL_DISTORTION);
+
+            if (supportDepth) {
+                mCollector.expectTrue("Supports DEPTH_OUTPUT but does not support DEPTH16",
+                        hasDepth16);
+                if (hasDepth16) {
+                    Size[] depthSizes = configs.getOutputSizes(ImageFormat.DEPTH16);
+                    mCollector.expectTrue("Supports DEPTH_OUTPUT but no sizes for DEPTH16 supported!",
+                            depthSizes != null && depthSizes.length > 0);
+                    if (depthSizes != null) {
+                        for (Size depthSize : depthSizes) {
+                            mCollector.expectTrue("All depth16 sizes must be positive",
+                                    depthSize.getWidth() > 0 && depthSize.getHeight() > 0);
+                            long minFrameDuration = configs.getOutputMinFrameDuration(
+                                    ImageFormat.DEPTH16, depthSize);
+                            mCollector.expectTrue("Non-negative min frame duration for depth size "
+                                    + depthSize + " expected, got " + minFrameDuration,
+                                    minFrameDuration >= 0);
+                            long stallDuration = configs.getOutputStallDuration(
+                                    ImageFormat.DEPTH16, depthSize);
+                            mCollector.expectTrue("Non-negative stall duration for depth size "
+                                    + depthSize + " expected, got " + stallDuration,
+                                    stallDuration >= 0);
+                        }
+                    }
+                }
+                if (arrayContains(outputFormats, ImageFormat.DEPTH_POINT_CLOUD)) {
+                    Size[] depthCloudSizes = configs.getOutputSizes(ImageFormat.DEPTH_POINT_CLOUD);
+                    mCollector.expectTrue("Supports DEPTH_POINT_CLOUD " +
+                            "but no sizes for DEPTH_POINT_CLOUD supported!",
+                            depthCloudSizes != null && depthCloudSizes.length > 0);
+                    if (depthCloudSizes != null) {
+                        for (Size depthCloudSize : depthCloudSizes) {
+                            mCollector.expectTrue("All depth point cloud sizes must be nonzero",
+                                    depthCloudSize.getWidth() > 0);
+                            mCollector.expectTrue("All depth point cloud sizes must be N x 1",
+                                    depthCloudSize.getHeight() == 1);
+                            long minFrameDuration = configs.getOutputMinFrameDuration(
+                                    ImageFormat.DEPTH_POINT_CLOUD, depthCloudSize);
+                            mCollector.expectTrue("Non-negative min frame duration for depth size "
+                                    + depthCloudSize + " expected, got " + minFrameDuration,
+                                    minFrameDuration >= 0);
+                            long stallDuration = configs.getOutputStallDuration(
+                                    ImageFormat.DEPTH_POINT_CLOUD, depthCloudSize);
+                            mCollector.expectTrue("Non-negative stall duration for depth size "
+                                    + depthCloudSize + " expected, got " + stallDuration,
+                                    stallDuration >= 0);
+                        }
+                    }
+                }
+
+                mCollector.expectTrue("Supports DEPTH_OUTPUT but DEPTH_IS_EXCLUSIVE is not defined",
+                        depthIsExclusive != null);
+
+                mCollector.expectTrue(
+                        "Supports DEPTH_OUTPUT but LENS_POSE_ROTATION not right size",
+                        poseRotation != null && poseRotation.length == 4);
+                mCollector.expectTrue(
+                        "Supports DEPTH_OUTPUT but LENS_POSE_TRANSLATION not right size",
+                        poseTranslation != null && poseTranslation.length == 3);
+                mCollector.expectTrue(
+                        "Supports DEPTH_OUTPUT but LENS_INTRINSIC_CALIBRATION not right size",
+                        cameraIntrinsics != null && cameraIntrinsics.length == 5);
+                mCollector.expectTrue(
+                        "Supports DEPTH_OUTPUT but LENS_RADIAL_DISTORTION not right size",
+                        radialDistortion != null && radialDistortion.length == 6);
+
+                if (poseRotation != null && poseRotation.length == 4) {
+                    float normSq =
+                        poseRotation[0] * poseRotation[0] +
+                        poseRotation[1] * poseRotation[1] +
+                        poseRotation[2] * poseRotation[2] +
+                        poseRotation[3] * poseRotation[3];
+                    mCollector.expectTrue(
+                            "LENS_POSE_ROTATION quarternion must be unit-length",
+                            0.9999f < normSq && normSq < 1.0001f);
+
+                    // TODO: Cross-validate orientation/facing and poseRotation
+                    Integer orientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION);
+                    Integer facing = c.get(CameraCharacteristics.LENS_FACING);
+                }
+
+                if (poseTranslation != null && poseTranslation.length == 3) {
+                    float normSq =
+                        poseTranslation[0] * poseTranslation[0] +
+                        poseTranslation[1] * poseTranslation[1] +
+                        poseTranslation[2] * poseTranslation[2];
+                    mCollector.expectTrue("Pose translation is larger than 1 m",
+                            normSq < 1.f);
+                }
+
+                Rect precorrectionArray =
+                    c.get(CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE);
+                mCollector.expectTrue("Supports DEPTH_OUTPUT but does not have " +
+                        "precorrection active array defined", precorrectionArray != null);
+
+                if (cameraIntrinsics != null && precorrectionArray != null) {
+                    float fx = cameraIntrinsics[0];
+                    float fy = cameraIntrinsics[1];
+                    float cx = cameraIntrinsics[2];
+                    float cy = cameraIntrinsics[3];
+                    float s = cameraIntrinsics[4];
+                    mCollector.expectTrue("Optical center expected to be within precorrection array",
+                            0 <= cx && cx < precorrectionArray.width() &&
+                            0 <= cy && cy < precorrectionArray.height());
+
+                    // TODO: Verify focal lengths and skew are reasonable
+                }
+
+                if (radialDistortion != null) {
+                    // TODO: Verify radial distortion
+                }
+
+            } else {
+                boolean hasFields =
+                    hasDepth16 && (poseTranslation != null) &&
+                    (poseRotation != null) && (cameraIntrinsics != null) &&
+                    (radialDistortion != null) && (depthIsExclusive != null);
+
+                mCollector.expectTrue(
+                        "All necessary depth fields defined, but DEPTH_OUTPUT capability is not listed",
+                        !hasFields);
+            }
+        }
+    }
+
+    /**
+     * Cross-check StreamConfigurationMap output
+     */
+    public void testStreamConfigurationMap() throws Exception {
+        int counter = 0;
+        for (CameraCharacteristics c : mCharacteristics) {
+            Log.i(TAG, "testStreamConfigurationMap: Testing camera ID " + mIds[counter]);
+            StreamConfigurationMap config =
+                    c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+            assertNotNull(String.format("No stream configuration map found for: ID %s",
+                            mIds[counter]), config);
+
+            int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+            assertNotNull("android.request.availableCapabilities must never be null",
+                    actualCapabilities);
+
+            if (arrayContains(actualCapabilities, BC)) {
+                assertTrue("ImageReader must be supported",
+                    config.isOutputSupportedFor(android.media.ImageReader.class));
+                assertTrue("MediaRecorder must be supported",
+                    config.isOutputSupportedFor(android.media.MediaRecorder.class));
+                assertTrue("MediaCodec must be supported",
+                    config.isOutputSupportedFor(android.media.MediaCodec.class));
+                assertTrue("Allocation must be supported",
+                    config.isOutputSupportedFor(android.renderscript.Allocation.class));
+                assertTrue("SurfaceHolder must be supported",
+                    config.isOutputSupportedFor(android.view.SurfaceHolder.class));
+                assertTrue("SurfaceTexture must be supported",
+                    config.isOutputSupportedFor(android.graphics.SurfaceTexture.class));
+
+                assertTrue("YUV_420_888 must be supported",
+                    config.isOutputSupportedFor(ImageFormat.YUV_420_888));
+                assertTrue("JPEG must be supported",
+                    config.isOutputSupportedFor(ImageFormat.JPEG));
+            } else {
+                assertTrue("YUV_420_88 may not be supported if BACKWARD_COMPATIBLE capability is not listed",
+                    !config.isOutputSupportedFor(ImageFormat.YUV_420_888));
+                assertTrue("JPEG may not be supported if BACKWARD_COMPATIBLE capability is not listed",
+                    !config.isOutputSupportedFor(ImageFormat.JPEG));
+            }
+
+            // Legacy YUV formats should not be listed
+            assertTrue("NV21 must not be supported",
+                    !config.isOutputSupportedFor(ImageFormat.NV21));
+
+            // Check RAW
+
+            if (arrayContains(actualCapabilities,
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                assertTrue("RAW_SENSOR must be supported if RAW capability is advertised",
+                    config.isOutputSupportedFor(ImageFormat.RAW_SENSOR));
+            }
+
+            // Cross check public formats and sizes
+
+            int[] supportedFormats = config.getOutputFormats();
+            for (int format : supportedFormats) {
+                assertTrue("Format " + format + " fails cross check",
+                        config.isOutputSupportedFor(format));
+                List<Size> supportedSizes = CameraTestUtils.getAscendingOrderSizes(
+                        Arrays.asList(config.getOutputSizes(format)), /*ascending*/true);
+                if (arrayContains(actualCapabilities,
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE)) {
+                    supportedSizes.addAll(
+                        Arrays.asList(config.getHighResolutionOutputSizes(format)));
+                    supportedSizes = CameraTestUtils.getAscendingOrderSizes(
+                        supportedSizes, /*ascending*/true);
+                }
+                assertTrue("Supported format " + format + " has no sizes listed",
+                        supportedSizes.size() > 0);
+                for (int i = 0; i < supportedSizes.size(); i++) {
+                    Size size = supportedSizes.get(i);
+                    if (VERBOSE) {
+                        Log.v(TAG,
+                                String.format("Testing camera %s, format %d, size %s",
+                                        mIds[counter], format, size.toString()));
+                    }
+
+                    long stallDuration = config.getOutputStallDuration(format, size);
+                    switch(format) {
+                        case ImageFormat.YUV_420_888:
+                            assertTrue("YUV_420_888 may not have a non-zero stall duration",
+                                    stallDuration == 0);
+                            break;
+                        case ImageFormat.JPEG:
+                        case ImageFormat.RAW_SENSOR:
+                            final float TOLERANCE_FACTOR = 2.0f;
+                            long prevDuration = 0;
+                            if (i > 0) {
+                                prevDuration = config.getOutputStallDuration(
+                                        format, supportedSizes.get(i - 1));
+                            }
+                            long nextDuration = Long.MAX_VALUE;
+                            if (i < (supportedSizes.size() - 1)) {
+                                nextDuration = config.getOutputStallDuration(
+                                        format, supportedSizes.get(i + 1));
+                            }
+                            long curStallDuration = config.getOutputStallDuration(format, size);
+                            // Stall duration should be in a reasonable range: larger size should
+                            // normally have larger stall duration.
+                            mCollector.expectInRange("Stall duration (format " + format +
+                                    " and size " + size + ") is not in the right range",
+                                    curStallDuration,
+                                    (long) (prevDuration / TOLERANCE_FACTOR),
+                                    (long) (nextDuration * TOLERANCE_FACTOR));
+                            break;
+                        default:
+                            assertTrue("Negative stall duration for format " + format,
+                                    stallDuration >= 0);
+                            break;
+                    }
+                    long minDuration = config.getOutputMinFrameDuration(format, size);
+                    if (arrayContains(actualCapabilities,
+                            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                        assertTrue("MANUAL_SENSOR capability, need positive min frame duration for"
+                                + "format " + format + " for size " + size + " minDuration " +
+                                minDuration,
+                                minDuration > 0);
+                    } else {
+                        assertTrue("Need non-negative min frame duration for format " + format,
+                                minDuration >= 0);
+                    }
+
+                    // todo: test opaque image reader when it's supported.
+                    if (format != ImageFormat.PRIVATE) {
+                        ImageReader testReader = ImageReader.newInstance(
+                            size.getWidth(),
+                            size.getHeight(),
+                            format,
+                            1);
+                        Surface testSurface = testReader.getSurface();
+
+                        assertTrue(
+                            String.format("isOutputSupportedFor fails for config %s, format %d",
+                                    size.toString(), format),
+                            config.isOutputSupportedFor(testSurface));
+
+                        testReader.close();
+                    }
+                } // sizes
+
+                // Try an invalid size in this format, should round
+                Size invalidSize = findInvalidSize(supportedSizes);
+                int MAX_ROUNDING_WIDTH = 1920;
+                // todo: test opaque image reader when it's supported.
+                if (format != ImageFormat.PRIVATE &&
+                        invalidSize.getWidth() <= MAX_ROUNDING_WIDTH) {
+                    ImageReader testReader = ImageReader.newInstance(
+                                                                     invalidSize.getWidth(),
+                                                                     invalidSize.getHeight(),
+                                                                     format,
+                                                                     1);
+                    Surface testSurface = testReader.getSurface();
+
+                    assertTrue(
+                               String.format("isOutputSupportedFor fails for config %s, %d",
+                                       invalidSize.toString(), format),
+                               config.isOutputSupportedFor(testSurface));
+
+                    testReader.close();
+                }
+            } // formats
+
+            // Cross-check opaque format and sizes
+            if (arrayContains(actualCapabilities, BC)) {
+                SurfaceTexture st = new SurfaceTexture(1);
+                Surface surf = new Surface(st);
+
+                Size[] opaqueSizes = CameraTestUtils.getSupportedSizeForClass(SurfaceTexture.class,
+                        mIds[counter], mCameraManager);
+                assertTrue("Opaque format has no sizes listed",
+                        opaqueSizes.length > 0);
+                for (Size size : opaqueSizes) {
+                    long stallDuration = config.getOutputStallDuration(SurfaceTexture.class, size);
+                    assertTrue("Opaque output may not have a non-zero stall duration",
+                            stallDuration == 0);
+
+                    long minDuration = config.getOutputMinFrameDuration(SurfaceTexture.class, size);
+                    if (arrayContains(actualCapabilities,
+                                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                        assertTrue("MANUAL_SENSOR capability, need positive min frame duration for"
+                                + "opaque format",
+                                minDuration > 0);
+                    } else {
+                        assertTrue("Need non-negative min frame duration for opaque format ",
+                                minDuration >= 0);
+                    }
+                    st.setDefaultBufferSize(size.getWidth(), size.getHeight());
+
+                    assertTrue(
+                            String.format("isOutputSupportedFor fails for SurfaceTexture config %s",
+                                    size.toString()),
+                            config.isOutputSupportedFor(surf));
+
+                } // opaque sizes
+
+                // Try invalid opaque size, should get rounded
+                Size invalidSize = findInvalidSize(opaqueSizes);
+                st.setDefaultBufferSize(invalidSize.getWidth(), invalidSize.getHeight());
+                assertTrue(
+                        String.format("isOutputSupportedFor fails for SurfaceTexture config %s",
+                                invalidSize.toString()),
+                        config.isOutputSupportedFor(surf));
+
+                counter++;
+            }
+
+        } // mCharacteristics
+    }
+
+    /**
+     * Test high speed capability and cross-check the high speed sizes and fps ranges from
+     * the StreamConfigurationMap.
+     */
+    public void testConstrainedHighSpeedCapability() throws Exception {
+        int counter = 0;
+        for (CameraCharacteristics c : mCharacteristics) {
+            int[] capabilities = CameraTestUtils.getValueNotNull(
+                    c, CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+            boolean supportHighSpeed = arrayContains(capabilities, CONSTRAINED_HIGH_SPEED);
+            if (supportHighSpeed) {
+                StreamConfigurationMap config =
+                        CameraTestUtils.getValueNotNull(
+                                c, CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+                List<Size> highSpeedSizes = Arrays.asList(config.getHighSpeedVideoSizes());
+                assertTrue("High speed sizes shouldn't be empty", highSpeedSizes.size() > 0);
+                Size[] allSizes = CameraTestUtils.getSupportedSizeForFormat(ImageFormat.PRIVATE,
+                        mIds[counter], mCameraManager);
+                assertTrue("Normal size for PRIVATE format shouldn't be null or empty",
+                        allSizes != null && allSizes.length > 0);
+                for (Size size: highSpeedSizes) {
+                    // The sizes must be a subset of the normal sizes
+                    assertTrue("High speed size " + size +
+                            " must be part of normal sizes " + Arrays.toString(allSizes),
+                            Arrays.asList(allSizes).contains(size));
+
+                    // Sanitize the high speed FPS ranges for each size
+                    List<Range<Integer>> ranges =
+                            Arrays.asList(config.getHighSpeedVideoFpsRangesFor(size));
+                    for (Range<Integer> range : ranges) {
+                        assertTrue("The range " + range + " doesn't satisfy the"
+                                + " min/max boundary requirements.",
+                                range.getLower() >= HIGH_SPEED_FPS_LOWER_MIN &&
+                                range.getUpper() >= HIGH_SPEED_FPS_UPPER_MIN);
+                        assertTrue("The range " + range + " should be multiple of 30fps",
+                                range.getLower() % 30 == 0 && range.getUpper() % 30 == 0);
+                        // If the range is fixed high speed range, it should contain the
+                        // [30, fps_max] in the high speed range list; if it's variable FPS range,
+                        // the corresponding fixed FPS Range must be included in the range list.
+                        if (range.getLower() == range.getUpper()) {
+                            Range<Integer> variableRange = new Range<Integer>(30, range.getUpper());
+                            assertTrue("The variable FPS range " + variableRange +
+                                    " shoould be included in the high speed ranges for size " +
+                                    size, ranges.contains(variableRange));
+                        } else {
+                            Range<Integer> fixedRange =
+                                    new Range<Integer>(range.getUpper(), range.getUpper());
+                            assertTrue("The fixed FPS range " + fixedRange +
+                                    " shoould be included in the high speed ranges for size " +
+                                    size, ranges.contains(fixedRange));
+                        }
+                    }
+                }
+                // If the device advertise some high speed profiles, the sizes and FPS ranges
+                // should be advertise by the camera.
+                for (int quality = CamcorderProfile.QUALITY_HIGH_SPEED_480P;
+                        quality <= CamcorderProfile.QUALITY_HIGH_SPEED_2160P; quality++) {
+                    if (CamcorderProfile.hasProfile(quality)) {
+                        CamcorderProfile profile = CamcorderProfile.get(quality);
+                        Size camcorderProfileSize =
+                                new Size(profile.videoFrameWidth, profile.videoFrameHeight);
+                        assertTrue("CamcorderPrfile size " + camcorderProfileSize +
+                                " must be included in the high speed sizes " +
+                                Arrays.toString(highSpeedSizes.toArray()),
+                                highSpeedSizes.contains(camcorderProfileSize));
+                        Range<Integer> camcorderFpsRange =
+                                new Range<Integer>(profile.videoFrameRate, profile.videoFrameRate);
+                        List<Range<Integer>> allRanges =
+                                Arrays.asList(config.getHighSpeedVideoFpsRangesFor(
+                                        camcorderProfileSize));
+                        assertTrue("Camcorder fps range " + camcorderFpsRange +
+                                " should be included by high speed fps ranges " +
+                                Arrays.toString(allRanges.toArray()),
+                                allRanges.contains(camcorderFpsRange));
+                    }
+                }
+            }
+            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) {
+        return findInvalidSize(Arrays.asList(goodSizes));
+    }
+
+    /**
+     * Create an invalid size that's close to one of the good sizes in the list, but not one of them
+     */
+    private Size findInvalidSize(List<Size> goodSizes) {
+        Size invalidSize = new Size(goodSizes.get(0).getWidth() + 1, goodSizes.get(0).getHeight());
+        while(goodSizes.contains(invalidSize)) {
+            invalidSize = new Size(invalidSize.getWidth() + 1, invalidSize.getHeight());
+        }
+        return invalidSize;
+    }
+
+    /**
+     * Check key is present in characteristics if the hardware level is at least {@code hwLevel};
+     * check that the key is present if the actual capabilities are one of {@code capabilities}.
+     *
+     * @return value of the {@code key} from {@code c}
+     */
+    private <T> T expectKeyAvailable(CameraCharacteristics c, CameraCharacteristics.Key<T> key,
+            int hwLevel, int... capabilities) {
+
+        Integer actualHwLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+        assertNotNull("android.info.supportedHardwareLevel must never be null", actualHwLevel);
+
+        int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
+        assertNotNull("android.request.availableCapabilities must never be null",
+                actualCapabilities);
+
+        List<Key<?>> allKeys = c.getKeys();
+
+        T value = c.get(key);
+
+        // For LIMITED-level targeted keys, rely on capability check, not level
+        if ((compareHardwareLevel(actualHwLevel, hwLevel) >= 0) && (hwLevel != LIMITED)) {
+            mCollector.expectTrue(
+                    String.format("Key (%s) must be in characteristics for this hardware level " +
+                            "(required minimal HW level %s, actual HW level %s)",
+                            key.getName(), toStringHardwareLevel(hwLevel),
+                            toStringHardwareLevel(actualHwLevel)),
+                    value != null);
+            mCollector.expectTrue(
+                    String.format("Key (%s) must be in characteristics list of keys for this " +
+                            "hardware level (required minimal HW level %s, actual HW level %s)",
+                            key.getName(), toStringHardwareLevel(hwLevel),
+                            toStringHardwareLevel(actualHwLevel)),
+                    allKeys.contains(key));
+        } else if (arrayContainsAnyOf(actualCapabilities, capabilities)) {
+            if (!(hwLevel == LIMITED && compareHardwareLevel(actualHwLevel, hwLevel) < 0)) {
+                // Don't enforce LIMITED-starting keys on LEGACY level, even if cap is defined
+                mCollector.expectTrue(
+                    String.format("Key (%s) must be in characteristics for these capabilities " +
+                            "(required capabilities %s, actual capabilities %s)",
+                            key.getName(), Arrays.toString(capabilities),
+                            Arrays.toString(actualCapabilities)),
+                    value != null);
+                mCollector.expectTrue(
+                    String.format("Key (%s) must be in characteristics list of keys for " +
+                            "these capabilities (required capabilities %s, actual capabilities %s)",
+                            key.getName(), Arrays.toString(capabilities),
+                            Arrays.toString(actualCapabilities)),
+                    allKeys.contains(key));
+            }
+        } else {
+            if (actualHwLevel == LEGACY && hwLevel != OPT) {
+                if (value != null || allKeys.contains(key)) {
+                    Log.w(TAG, String.format(
+                            "Key (%s) is not required for LEGACY devices but still appears",
+                            key.getName()));
+                }
+            }
+            // OK: Key may or may not be present.
+        }
+        return value;
+    }
+
+    private static boolean arrayContains(int[] arr, int needle) {
+        if (arr == null) {
+            return false;
+        }
+
+        for (int elem : arr) {
+            if (elem == needle) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private static <T> boolean arrayContains(T[] arr, T needle) {
+        if (arr == null) {
+            return false;
+        }
+
+        for (T elem : arr) {
+            if (elem.equals(needle)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    private static boolean arrayContainsAnyOf(int[] arr, int[] needles) {
+        for (int needle : needles) {
+            if (arrayContains(arr, needle)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * The key name has a prefix of either "android." or "com."; other prefixes are not valid.
+     */
+    private static void assertKeyPrefixValid(String keyName) {
+        assertStartsWithAnyOf(
+                "All metadata keys must start with 'android.' (built-in keys) " +
+                "or 'com.' (vendor-extended keys)", new String[] {
+                        PREFIX_ANDROID + ".",
+                        PREFIX_VENDOR + ".",
+                }, keyName);
+    }
+
+    private static void assertTrueForKey(String msg, CameraCharacteristics.Key<?> key,
+            boolean actual) {
+        assertTrue(msg + " (key = '" + key.getName() + "')", actual);
+    }
+
+    private static <T> void assertOneOf(String msg, T[] expected, T actual) {
+        for (int i = 0; i < expected.length; ++i) {
+            if (Objects.equals(expected[i], actual)) {
+                return;
+            }
+        }
+
+        fail(String.format("%s: (expected one of %s, actual %s)",
+                msg, Arrays.toString(expected), actual));
+    }
+
+    private static <T> void assertStartsWithAnyOf(String msg, String[] expected, String actual) {
+        for (int i = 0; i < expected.length; ++i) {
+            if (actual.startsWith(expected[i])) {
+                return;
+            }
+        }
+
+        fail(String.format("%s: (expected to start with any of %s, but value was %s)",
+                msg, Arrays.toString(expected), actual));
+    }
+
+    /** Return a positive int if left > right, 0 if left==right, negative int if left < right */
+    private static int compareHardwareLevel(int left, int right) {
+        return remapHardwareLevel(left) - remapHardwareLevel(right);
+    }
+
+    /** Remap HW levels worst<->best, 0 = worst, 2 = best */
+    private static int remapHardwareLevel(int level) {
+        switch (level) {
+            case OPT:
+                return Integer.MAX_VALUE;
+            case LEGACY:
+                return 0; // lowest
+            case LIMITED:
+                return 1; // second lowest
+            case FULL:
+                return 2; // best
+        }
+
+        fail("Unknown HW level: " + level);
+        return -1;
+    }
+
+    private static String toStringHardwareLevel(int level) {
+        switch (level) {
+            case LEGACY:
+                return "LEGACY";
+            case LIMITED:
+                return "LIMITED";
+            case FULL:
+                return "FULL";
+        }
+
+        // unknown
+        Log.w(TAG, "Unknown hardware level " + level);
+        return Integer.toString(level);
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/FlashlightTest.java b/tests/camera/src/android/hardware/camera2/cts/FlashlightTest.java
new file mode 100644
index 0000000..44b13c3
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/FlashlightTest.java
@@ -0,0 +1,386 @@
+/*
+ * 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.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
+import android.util.Log;
+import android.os.SystemClock;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+import static org.mockito.Mockito.*;
+
+/**
+ * <p>Tests for flashlight API.</p>
+ */
+public class FlashlightTest extends Camera2AndroidTestCase {
+    private static final String TAG = "FlashlightTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final int TORCH_DURATION_MS = 1000;
+    private static final int TORCH_TIMEOUT_MS = 3000;
+    private static final int NUM_REGISTERS = 10;
+
+    private ArrayList<String> mFlashCameraIdList;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // initialize the list of cameras that have a flash unit so it won't interfere with
+        // flash tests.
+        mFlashCameraIdList = new ArrayList<String>();
+        for (String id : mCameraIds) {
+            StaticMetadata info =
+                    new StaticMetadata(mCameraManager.getCameraCharacteristics(id),
+                                       CheckLevel.ASSERT, /*collector*/ null);
+            if (info.hasFlash()) {
+                mFlashCameraIdList.add(id);
+            }
+        }
+    }
+
+    public void testSetTorchModeOnOff() throws Exception {
+        if (mFlashCameraIdList.size() == 0)
+            return;
+
+        // reset flash status for all devices with a flash unit
+        for (String id : mFlashCameraIdList) {
+            resetTorchModeStatus(id);
+        }
+
+        // turn on and off torch mode one by one
+        for (String id : mFlashCameraIdList) {
+            CameraManager.TorchCallback torchListener = mock(CameraManager.TorchCallback.class);
+            mCameraManager.registerTorchCallback(torchListener, mHandler); // should get OFF
+
+            mCameraManager.setTorchMode(id, true); // should get ON
+            SystemClock.sleep(TORCH_DURATION_MS);
+            mCameraManager.setTorchMode(id, false); // should get OFF
+
+            // verify corrected numbers of callbacks
+            verify(torchListener, timeout(TORCH_TIMEOUT_MS).
+                    times(2)).onTorchModeChanged(id, false);
+            verify(torchListener, timeout(TORCH_TIMEOUT_MS).
+                    times(mFlashCameraIdList.size() + 1)).
+                    onTorchModeChanged(anyString(), eq(false));
+            verify(torchListener, timeout(TORCH_TIMEOUT_MS).
+                    times(1)).onTorchModeChanged(id, true);
+            verify(torchListener, timeout(TORCH_TIMEOUT_MS).
+                    times(1)).onTorchModeChanged(anyString(), eq(true));
+            verify(torchListener, timeout(TORCH_TIMEOUT_MS).never()).
+                    onTorchModeUnavailable(anyString());
+
+            mCameraManager.unregisterTorchCallback(torchListener);
+        }
+
+        // turn on all torch modes at once
+        if (mFlashCameraIdList.size() >= 2) {
+            CameraManager.TorchCallback torchListener = mock(CameraManager.TorchCallback.class);
+            mCameraManager.registerTorchCallback(torchListener, mHandler); // should get OFF.
+
+            for (String id : mFlashCameraIdList) {
+                // should get ON for this ID.
+                // may get OFF for previously-on IDs.
+                mCameraManager.setTorchMode(id, true);
+            }
+
+            SystemClock.sleep(TORCH_DURATION_MS);
+
+            for (String id : mFlashCameraIdList) {
+                // should get OFF if not turned off previously.
+                mCameraManager.setTorchMode(id, false);
+            }
+
+            verify(torchListener, timeout(TORCH_TIMEOUT_MS).times(mFlashCameraIdList.size())).
+                    onTorchModeChanged(anyString(), eq(true));
+            // one more off for each id due to callback registeration.
+            verify(torchListener, timeout(TORCH_TIMEOUT_MS).
+                    times(mFlashCameraIdList.size() * 2)).
+                    onTorchModeChanged(anyString(), eq(false));
+
+            mCameraManager.unregisterTorchCallback(torchListener);
+        }
+    }
+
+    public void testTorchCallback() throws Exception {
+        if (mFlashCameraIdList.size() == 0)
+            return;
+
+        // reset torch mode status
+        for (String id : mFlashCameraIdList) {
+            resetTorchModeStatus(id);
+        }
+
+        CameraManager.TorchCallback torchListener = mock(CameraManager.TorchCallback.class);
+
+        for (int i = 0; i < NUM_REGISTERS; i++) {
+            // should get OFF for all cameras with a flash unit.
+            mCameraManager.registerTorchCallback(torchListener, mHandler);
+            mCameraManager.unregisterTorchCallback(torchListener);
+        }
+
+        verify(torchListener, timeout(TORCH_TIMEOUT_MS).
+                times(NUM_REGISTERS * mFlashCameraIdList.size())).
+                onTorchModeChanged(anyString(), eq(false));
+        verify(torchListener, timeout(TORCH_TIMEOUT_MS).never()).
+                onTorchModeChanged(anyString(), eq(true));
+        verify(torchListener, timeout(TORCH_TIMEOUT_MS).never()).
+                onTorchModeUnavailable(anyString());
+
+        // verify passing a null handler will raise IllegalArgumentException
+        try {
+            mCameraManager.registerTorchCallback(torchListener, null);
+            mCameraManager.unregisterTorchCallback(torchListener);
+            fail("should get IllegalArgumentException due to no handler");
+        } catch (IllegalArgumentException e) {
+            // expected exception
+        }
+    }
+
+    public void testCameraDeviceOpenAfterTorchOn() throws Exception {
+        if (mFlashCameraIdList.size() == 0)
+            return;
+
+        for (String id : mFlashCameraIdList) {
+            for (String idToOpen : mCameraIds) {
+                resetTorchModeStatus(id);
+
+                CameraManager.TorchCallback torchListener =
+                        mock(CameraManager.TorchCallback.class);
+
+                // this will trigger OFF for each id in mFlashCameraIdList
+                mCameraManager.registerTorchCallback(torchListener, mHandler);
+
+                // this will trigger ON for id
+                mCameraManager.setTorchMode(id, true);
+                SystemClock.sleep(TORCH_DURATION_MS);
+
+                // if id == idToOpen, this will trigger UNAVAILABLE and may trigger OFF.
+                // this may trigger UNAVAILABLE for any other id in mFlashCameraIdList
+                openDevice(idToOpen);
+
+                // if id == idToOpen, this will trigger OFF.
+                // this may trigger OFF for any other id in mFlashCameraIdList.
+                closeDevice(idToOpen);
+
+                // this may trigger OFF for id if not received previously.
+                mCameraManager.setTorchMode(id, false);
+
+                verify(torchListener, timeout(TORCH_TIMEOUT_MS).times(1)).
+                        onTorchModeChanged(id, true);
+                verify(torchListener, timeout(TORCH_TIMEOUT_MS).times(1)).
+                        onTorchModeChanged(anyString(), eq(true));
+
+                verify(torchListener, timeout(TORCH_TIMEOUT_MS).atLeast(2)).
+                        onTorchModeChanged(id, false);
+                verify(torchListener, atMost(3)).onTorchModeChanged(id, false);
+
+                verify(torchListener, timeout(TORCH_TIMEOUT_MS).
+                        atLeast(mFlashCameraIdList.size())).
+                        onTorchModeChanged(anyString(), eq(false));
+                verify(torchListener, atMost(mFlashCameraIdList.size() * 2 + 1)).
+                        onTorchModeChanged(anyString(), eq(false));
+
+                if (hasFlash(idToOpen)) {
+                    verify(torchListener, timeout(TORCH_TIMEOUT_MS).times(1)).
+                            onTorchModeUnavailable(idToOpen);
+                }
+                verify(torchListener, atMost(mFlashCameraIdList.size())).
+                            onTorchModeUnavailable(anyString());
+
+                mCameraManager.unregisterTorchCallback(torchListener);
+            }
+        }
+    }
+
+    public void testTorchModeExceptions() throws Exception {
+        // cameraIdsToTestTorch = all available camera ID + non-existing camera id +
+        //                        non-existing numeric camera id + null
+        String[] cameraIdsToTestTorch = new String[mCameraIds.length + 3];
+        System.arraycopy(mCameraIds, 0, cameraIdsToTestTorch, 0, mCameraIds.length);
+        cameraIdsToTestTorch[mCameraIds.length] = generateNonexistingCameraId();
+        cameraIdsToTestTorch[mCameraIds.length + 1] = generateNonexistingNumericCameraId();
+
+        for (String idToOpen : mCameraIds) {
+            openDevice(idToOpen);
+            try {
+                for (String id : cameraIdsToTestTorch) {
+                    try {
+                        mCameraManager.setTorchMode(id, true);
+                        SystemClock.sleep(TORCH_DURATION_MS);
+                        mCameraManager.setTorchMode(id, false);
+                        if (!hasFlash(id)) {
+                            fail("exception should be thrown when turning on torch mode of a " +
+                                    "camera without a flash");
+                        } else if (id.equals(idToOpen)) {
+                            fail("exception should be thrown when turning on torch mode of an " +
+                                    "opened camera");
+                        }
+                    } catch (CameraAccessException e) {
+                        if ((hasFlash(id) &&  id.equals(idToOpen) &&
+                                    e.getReason() == CameraAccessException.CAMERA_IN_USE) ||
+                            (hasFlash(id) && !id.equals(idToOpen) &&
+                                    e.getReason() == CameraAccessException.MAX_CAMERAS_IN_USE)) {
+                            continue;
+                        }
+                        fail("(" + id + ") not expecting: " + e.getMessage());
+                    } catch (IllegalArgumentException e) {
+                        if (hasFlash(id)) {
+                            fail("not expecting IllegalArgumentException");
+                        }
+                    }
+                }
+            } finally {
+                closeDevice(idToOpen);
+            }
+        }
+    }
+
+    private boolean hasFlash(String cameraId) {
+        return mFlashCameraIdList.contains(cameraId);
+    }
+
+    // make sure the torch status is off.
+    private void resetTorchModeStatus(String cameraId) throws Exception {
+        TorchCallbackListener torchListener = new TorchCallbackListener(cameraId);
+
+        mCameraManager.registerTorchCallback(torchListener, mHandler);
+        mCameraManager.setTorchMode(cameraId, true);
+        mCameraManager.setTorchMode(cameraId, false);
+
+        torchListener.waitOnStatusChange(TorchCallbackListener.STATUS_ON);
+        torchListener.waitOnStatusChange(TorchCallbackListener.STATUS_OFF);
+
+        mCameraManager.unregisterTorchCallback(torchListener);
+    }
+
+    private String generateNonexistingCameraId() {
+        String nonExisting = "none_existing_camera";
+        for (String id : mCameraIds) {
+            if (Arrays.asList(mCameraIds).contains(nonExisting)) {
+                nonExisting += id;
+            } else {
+                break;
+            }
+        }
+        return nonExisting;
+    }
+
+    // return a non-existing and non-negative numeric camera id.
+    private String generateNonexistingNumericCameraId() {
+        int[] numericCameraIds = new int[mCameraIds.length];
+        int size = 0;
+
+        for (String cameraId : mCameraIds) {
+            try {
+                int value = Integer.parseInt(cameraId);
+                if (value >= 0) {
+                    numericCameraIds[size++] = value;
+                }
+            } catch (Throwable e) {
+                // do nothing if camera id isn't an integer
+            }
+        }
+
+        if (size == 0) {
+            return "0";
+        }
+
+        Arrays.sort(numericCameraIds, 0, size);
+        if (numericCameraIds[0] != 0) {
+            return "0";
+        }
+
+        for (int i = 0; i < size - 1; i++) {
+            if (numericCameraIds[i] + 1 < numericCameraIds[i + 1]) {
+                return String.valueOf(numericCameraIds[i] + 1);
+            }
+        }
+
+        if (numericCameraIds[size - 1] != Integer.MAX_VALUE) {
+            return String.valueOf(numericCameraIds[size - 1] + 1);
+        }
+
+        fail("cannot find a non-existing and non-negative numeric camera id");
+        return null;
+    }
+
+    private final class TorchCallbackListener extends CameraManager.TorchCallback {
+        private static final String TAG = "TorchCallbackListener";
+        private static final int STATUS_WAIT_TIMEOUT_MS = 3000;
+        private static final int QUEUE_CAPACITY = 100;
+
+        private String mCameraId;
+        private ArrayBlockingQueue<Integer> mStatusQueue =
+                new ArrayBlockingQueue<Integer>(QUEUE_CAPACITY);
+
+        public static final int STATUS_UNAVAILABLE = 0;
+        public static final int STATUS_OFF = 1;
+        public static final int STATUS_ON = 2;
+
+        public TorchCallbackListener(String cameraId) {
+            // only care about events for this camera id.
+            mCameraId = cameraId;
+        }
+
+        public void waitOnStatusChange(int status) throws Exception {
+            while (true) {
+                Integer s = mStatusQueue.poll(STATUS_WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+                if (s == null) {
+                    fail("waiting for status " + status + " timed out");
+                } else if (s.intValue() == status) {
+                    return;
+                }
+            }
+        }
+
+        @Override
+        public void onTorchModeUnavailable(String cameraId) {
+            if (cameraId.equals(mCameraId)) {
+                Integer s = new Integer(STATUS_UNAVAILABLE);
+                try {
+                    mStatusQueue.put(s);
+                } catch (Throwable e) {
+                    fail(e.getMessage());
+                }
+            }
+        }
+
+        @Override
+        public void onTorchModeChanged(String cameraId, boolean enabled) {
+            if (cameraId.equals(mCameraId)) {
+                Integer s;
+                if (enabled) {
+                    s = new Integer(STATUS_ON);
+                } else {
+                    s = new Integer(STATUS_OFF);
+                }
+                try {
+                    mStatusQueue.put(s);
+                } catch (Throwable e) {
+                    fail(e.getMessage());
+                }
+            }
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
new file mode 100644
index 0000000..9c783e0
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageReaderTest.java
@@ -0,0 +1,954 @@
+/*
+ * 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 android.hardware.camera2.cts;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Color;
+import android.graphics.ImageFormat;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.rs.BitmapUtils;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.Image;
+import android.media.Image.Plane;
+import android.media.ImageReader;
+import android.os.ConditionVariable;
+import android.util.Log;
+import android.util.Size;
+import android.view.Surface;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static android.hardware.camera2.cts.CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS;
+import static android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import static android.hardware.camera2.cts.CameraTestUtils.SimpleImageReaderListener;
+import static android.hardware.camera2.cts.CameraTestUtils.dumpFile;
+import static android.hardware.camera2.cts.CameraTestUtils.getValueNotNull;
+
+/**
+ * <p>Basic test for ImageReader APIs. It uses CameraDevice as producer, camera
+ * sends the data to the surface provided by imageReader. Below image formats
+ * are tested:</p>
+ *
+ * <p>YUV_420_888: flexible YUV420, it is mandatory format for camera. </p>
+ * <p>JPEG: used for JPEG still capture, also mandatory format. </p>
+ * <p>Some invalid access test. </p>
+ * <p>TODO: Add more format tests? </p>
+ */
+public class ImageReaderTest extends Camera2AndroidTestCase {
+    private static final String TAG = "ImageReaderTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    // Number of frame (for streaming requests) to be verified.
+    private static final int NUM_FRAME_VERIFIED = 2;
+    // Number of frame (for streaming requests) to be verified with log processing time.
+    private static final int NUM_LONG_PROCESS_TIME_FRAME_VERIFIED = 10;
+    // The time to hold each image for to simulate long processing time.
+    private static final int LONG_PROCESS_TIME_MS = 300;
+    // Max number of images can be accessed simultaneously from ImageReader.
+    private static final int MAX_NUM_IMAGES = 5;
+    // Max difference allowed between YUV and JPEG patches. This tolerance is intentionally very
+    // generous to avoid false positives due to punch/saturation operations vendors apply to the
+    // JPEG outputs.
+    private static final double IMAGE_DIFFERENCE_TOLERANCE = 30;
+
+    private SimpleImageListener mListener;
+
+    @Override
+    public void setContext(Context context) {
+        super.setContext(context);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    public void testFlexibleYuv() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Camera " + id);
+                openDevice(id);
+                bufferFormatTestByCamera(ImageFormat.YUV_420_888, /*repeating*/true);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testDepth16() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Camera " + id);
+                openDevice(id);
+                bufferFormatTestByCamera(ImageFormat.DEPTH16, /*repeating*/true);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testDepthPointCloud() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Camera " + id);
+                openDevice(id);
+                bufferFormatTestByCamera(ImageFormat.DEPTH_POINT_CLOUD, /*repeating*/true);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testJpeg() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing jpeg capture for Camera " + id);
+                openDevice(id);
+                bufferFormatTestByCamera(ImageFormat.JPEG, /*repeating*/false);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testRaw() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing raw capture for camera " + id);
+                openDevice(id);
+
+                bufferFormatTestByCamera(ImageFormat.RAW_SENSOR, /*repeating*/false);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testRepeatingJpeg() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing repeating jpeg capture for Camera " + id);
+                openDevice(id);
+                bufferFormatTestByCamera(ImageFormat.JPEG, /*repeating*/true);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testRepeatingRaw() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing repeating raw capture for camera " + id);
+                openDevice(id);
+
+                bufferFormatTestByCamera(ImageFormat.RAW_SENSOR, /*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);
+                bufferFormatLongProcessingTimeTestByCamera(ImageFormat.RAW_SENSOR);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testLongProcessingRepeatingFlexibleYuv() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing long processing on repeating YUV for camera " + id);
+                openDevice(id);
+                bufferFormatLongProcessingTimeTestByCamera(ImageFormat.YUV_420_888);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
+     * Test invalid access of image after an image is closed, further access
+     * of the image will get an IllegalStateException. The basic assumption of
+     * this test is that the ImageReader always gives direct byte buffer, which is always true
+     * for camera case. For if the produced image byte buffer is not direct byte buffer, there
+     * is no guarantee to get an ISE for this invalid access case.
+     */
+    public void testInvalidAccessTest() throws Exception {
+        // Test byte buffer access after an image is released, it should throw ISE.
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing invalid image access for Camera " + id);
+                openDevice(id);
+                invalidAccessTestAfterClose();
+            } finally {
+                closeDevice(id);
+                closeDefaultImageReader();
+            }
+        }
+    }
+
+    /**
+     * Test two image stream (YUV420_888 and JPEG) capture by using ImageReader.
+     *
+     * <p>Both stream formats are mandatory for Camera2 API</p>
+     */
+    public void testYuvAndJpeg() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "YUV and JPEG testing for camera " + id);
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                bufferFormatWithYuvTestByCamera(ImageFormat.JPEG);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
+     * Test two image stream (YUV420_888 and RAW_SENSOR) capture by using ImageReader.
+     *
+     */
+    public void testImageReaderYuvAndRaw() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "YUV and RAW testing for camera " + id);
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                bufferFormatWithYuvTestByCamera(ImageFormat.RAW_SENSOR);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
+     * Check that the center patches for YUV and JPEG outputs for the same frame match for each YUV
+     * resolution and format supported.
+     */
+    public void testAllOutputYUVResolutions() throws Exception {
+        Integer[] sessionStates = {BlockingSessionCallback.SESSION_READY,
+                BlockingSessionCallback.SESSION_CONFIGURE_FAILED};
+        for (String id : mCameraIds) {
+            try {
+                Log.v(TAG, "Testing all YUV image resolutions for camera " + id);
+                openDevice(id);
+
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+
+                // Skip warmup on FULL mode devices.
+                int warmupCaptureNumber = (mStaticInfo.isHardwareLevelLegacy()) ?
+                        MAX_NUM_IMAGES - 1 : 0;
+
+                // NV21 isn't supported by ImageReader.
+                final int[] YUVFormats = new int[] {ImageFormat.YUV_420_888, ImageFormat.YV12};
+
+                CameraCharacteristics.Key<StreamConfigurationMap> key =
+                        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
+                StreamConfigurationMap config = mStaticInfo.getValueFromKeyNonNull(key);
+                int[] supportedFormats = config.getOutputFormats();
+                List<Integer> supportedYUVFormats = new ArrayList<>();
+                for (int format : YUVFormats) {
+                    if (CameraTestUtils.contains(supportedFormats, format)) {
+                        supportedYUVFormats.add(format);
+                    }
+                }
+
+                Size[] jpegSizes = mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.JPEG,
+                        StaticMetadata.StreamDirection.Output);
+                assertFalse("JPEG output not supported for camera " + id +
+                        ", at least one JPEG output is required.", jpegSizes.length == 0);
+
+                Size maxJpegSize = CameraTestUtils.getMaxSize(jpegSizes);
+                Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+
+                for (int format : supportedYUVFormats) {
+                    Size[] targetCaptureSizes =
+                            mStaticInfo.getAvailableSizesForFormatChecked(format,
+                            StaticMetadata.StreamDirection.Output);
+
+                    for (Size captureSz : targetCaptureSizes) {
+                        if (VERBOSE) {
+                            Log.v(TAG, "Testing yuv size " + captureSz + " and jpeg size "
+                                    + maxJpegSize + " for camera " + mCamera.getId());
+                        }
+
+                        ImageReader jpegReader = null;
+                        ImageReader yuvReader = null;
+                        try {
+                            // Create YUV image reader
+                            SimpleImageReaderListener yuvListener = new SimpleImageReaderListener();
+                            yuvReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
+                                    yuvListener);
+                            Surface yuvSurface = yuvReader.getSurface();
+
+                            // Create JPEG image reader
+                            SimpleImageReaderListener jpegListener =
+                                    new SimpleImageReaderListener();
+                            jpegReader = createImageReader(maxJpegSize,
+                                    ImageFormat.JPEG, MAX_NUM_IMAGES, jpegListener);
+                            Surface jpegSurface = jpegReader.getSurface();
+
+                            // Setup session
+                            List<Surface> outputSurfaces = new ArrayList<Surface>();
+                            outputSurfaces.add(yuvSurface);
+                            outputSurfaces.add(jpegSurface);
+                            createSession(outputSurfaces);
+
+                            int state = mCameraSessionListener.getStateWaiter().waitForAnyOfStates(
+                                        Arrays.asList(sessionStates),
+                                        CameraTestUtils.SESSION_CONFIGURE_TIMEOUT_MS);
+
+                            if (state == BlockingSessionCallback.SESSION_CONFIGURE_FAILED) {
+                                if (captureSz.getWidth() > maxPreviewSize.getWidth() ||
+                                        captureSz.getHeight() > maxPreviewSize.getHeight()) {
+                                    Log.v(TAG, "Skip testing {yuv:" + captureSz
+                                            + " ,jpeg:" + maxJpegSize + "} for camera "
+                                            + mCamera.getId() +
+                                            " because full size jpeg + yuv larger than "
+                                            + "max preview size (" + maxPreviewSize
+                                            + ") is not supported");
+                                    continue;
+                                } else {
+                                    fail("Camera " + mCamera.getId() +
+                                            ":session configuration failed for {jpeg: " +
+                                            maxJpegSize + ", yuv: " + captureSz + "}");
+                                }
+                            }
+
+                            // Warm up camera preview (mainly to give legacy devices time to do 3A).
+                            CaptureRequest.Builder warmupRequest =
+                                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                            warmupRequest.addTarget(yuvSurface);
+                            assertNotNull("Fail to get CaptureRequest.Builder", warmupRequest);
+                            SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+
+                            for (int i = 0; i < warmupCaptureNumber; i++) {
+                                startCapture(warmupRequest.build(), /*repeating*/false,
+                                        resultListener, mHandler);
+                            }
+                            for (int i = 0; i < warmupCaptureNumber; i++) {
+                                resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
+                                Image image = yuvListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
+                                image.close();
+                            }
+
+                            // Capture image.
+                            CaptureRequest.Builder mainRequest =
+                                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                            for (Surface s : outputSurfaces) {
+                                mainRequest.addTarget(s);
+                            }
+
+                            startCapture(mainRequest.build(), /*repeating*/false, resultListener,
+                                    mHandler);
+
+                            // Verify capture result and images
+                            resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
+
+                            Image yuvImage = yuvListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
+                            Image jpegImage = jpegListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
+
+                            //Validate captured images.
+                            CameraTestUtils.validateImage(yuvImage, captureSz.getWidth(),
+                                    captureSz.getHeight(), format, /*filePath*/null);
+                            CameraTestUtils.validateImage(jpegImage, maxJpegSize.getWidth(),
+                                    maxJpegSize.getHeight(), ImageFormat.JPEG, /*filePath*/null);
+
+                            // Compare the image centers.
+                            RectF jpegDimens = new RectF(0, 0, jpegImage.getWidth(),
+                                    jpegImage.getHeight());
+                            RectF yuvDimens = new RectF(0, 0, yuvImage.getWidth(),
+                                    yuvImage.getHeight());
+
+                            // Find scale difference between YUV and JPEG output
+                            Matrix m = new Matrix();
+                            m.setRectToRect(yuvDimens, jpegDimens, Matrix.ScaleToFit.START);
+                            RectF scaledYuv = new RectF();
+                            m.mapRect(scaledYuv, yuvDimens);
+                            float scale = scaledYuv.width() / yuvDimens.width();
+
+                            final int PATCH_DIMEN = 40; // pixels in YUV
+
+                            // Find matching square patch of pixels in YUV and JPEG output
+                            RectF tempPatch = new RectF(0, 0, PATCH_DIMEN, PATCH_DIMEN);
+                            tempPatch.offset(yuvDimens.centerX() - tempPatch.centerX(),
+                                    yuvDimens.centerY() - tempPatch.centerY());
+                            Rect yuvPatch = new Rect();
+                            tempPatch.roundOut(yuvPatch);
+
+                            tempPatch.set(0, 0, PATCH_DIMEN * scale, PATCH_DIMEN * scale);
+                            tempPatch.offset(jpegDimens.centerX() - tempPatch.centerX(),
+                                    jpegDimens.centerY() - tempPatch.centerY());
+                            Rect jpegPatch = new Rect();
+                            tempPatch.roundOut(jpegPatch);
+
+                            // Decode center patches
+                            int[] yuvColors = convertPixelYuvToRgba(yuvPatch.width(),
+                                    yuvPatch.height(), yuvPatch.left, yuvPatch.top, yuvImage);
+                            Bitmap yuvBmap = Bitmap.createBitmap(yuvColors, yuvPatch.width(),
+                                    yuvPatch.height(), Bitmap.Config.ARGB_8888);
+
+                            byte[] compressedJpegData = CameraTestUtils.getDataFromImage(jpegImage);
+                            BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(
+                                    compressedJpegData, /*offset*/0, compressedJpegData.length,
+                                    /*isShareable*/true);
+                            BitmapFactory.Options opt = new BitmapFactory.Options();
+                            opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
+                            Bitmap fullSizeJpegBmap = decoder.decodeRegion(jpegPatch, opt);
+                            Bitmap jpegBmap = Bitmap.createScaledBitmap(fullSizeJpegBmap,
+                                    yuvPatch.width(), yuvPatch.height(), /*filter*/true);
+
+                            // Compare two patches using average of per-pixel differences
+                            double difference = BitmapUtils.calcDifferenceMetric(yuvBmap, jpegBmap);
+
+                            Log.i(TAG, "Difference for resolution " + captureSz + " is: " +
+                                    difference);
+                            if (difference > IMAGE_DIFFERENCE_TOLERANCE) {
+                                // Dump files if running in verbose mode
+                                if (DEBUG) {
+                                    String jpegFileName = DEBUG_FILE_NAME_BASE + "/" + captureSz +
+                                            "_jpeg.jpg";
+                                    dumpFile(jpegFileName, jpegBmap);
+                                    String fullSizeJpegFileName = DEBUG_FILE_NAME_BASE + "/" +
+                                            captureSz + "_full_jpeg.jpg";
+                                    dumpFile(fullSizeJpegFileName, compressedJpegData);
+                                    String yuvFileName = DEBUG_FILE_NAME_BASE + "/" + captureSz +
+                                            "_yuv.jpg";
+                                    dumpFile(yuvFileName, yuvBmap);
+                                    String fullSizeYuvFileName = DEBUG_FILE_NAME_BASE + "/" +
+                                            captureSz + "_full_yuv.jpg";
+                                    int[] fullYUVColors = convertPixelYuvToRgba(yuvImage.getWidth(),
+                                            yuvImage.getHeight(), 0, 0, yuvImage);
+                                    Bitmap fullYUVBmap = Bitmap.createBitmap(fullYUVColors,
+                                            yuvImage.getWidth(), yuvImage.getHeight(),
+                                            Bitmap.Config.ARGB_8888);
+                                    dumpFile(fullSizeYuvFileName, fullYUVBmap);
+                                }
+                                fail("Camera " + mCamera.getId() + ": YUV and JPEG image at " +
+                                        "capture size " + captureSz + " for the same frame are " +
+                                        "not similar, center patches have difference metric of " +
+                                        difference);
+                            }
+
+                            // Stop capture, delete the streams.
+                            stopCapture(/*fast*/false);
+                            yuvImage.close();
+                            jpegImage.close();
+                            yuvListener.drain();
+                            jpegListener.drain();
+                        } finally {
+                            closeImageReader(jpegReader);
+                            jpegReader = null;
+                            closeImageReader(yuvReader);
+                            yuvReader = null;
+                        }
+                    }
+                }
+
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
+     * Convert a rectangular patch in a YUV image to an ARGB color array.
+     *
+     * @param w width of the patch.
+     * @param h height of the patch.
+     * @param wOffset offset of the left side of the patch.
+     * @param hOffset offset of the top of the patch.
+     * @param yuvImage a YUV image to select a patch from.
+     * @return the image patch converted to RGB as an ARGB color array.
+     */
+    private static int[] convertPixelYuvToRgba(int w, int h, int wOffset, int hOffset,
+                                               Image yuvImage) {
+        final int CHANNELS = 3; // yuv
+        final float COLOR_RANGE = 255f;
+
+        assertTrue("Invalid argument to convertPixelYuvToRgba",
+                w > 0 && h > 0 && wOffset >= 0 && hOffset >= 0);
+        assertNotNull(yuvImage);
+
+        int imageFormat = yuvImage.getFormat();
+        assertTrue("YUV image must have YUV-type format",
+                imageFormat == ImageFormat.YUV_420_888 || imageFormat == ImageFormat.YV12 ||
+                        imageFormat == ImageFormat.NV21);
+
+        int height = yuvImage.getHeight();
+        int width = yuvImage.getWidth();
+
+        Rect imageBounds = new Rect(/*left*/0, /*top*/0, /*right*/width, /*bottom*/height);
+        Rect crop = new Rect(/*left*/wOffset, /*top*/hOffset, /*right*/wOffset + w,
+                /*bottom*/hOffset + h);
+        assertTrue("Output rectangle" + crop + " must lie within image bounds " + imageBounds,
+                imageBounds.contains(crop));
+        Image.Plane[] planes = yuvImage.getPlanes();
+
+        Image.Plane yPlane = planes[0];
+        Image.Plane cbPlane = planes[1];
+        Image.Plane crPlane = planes[2];
+
+        ByteBuffer yBuf = yPlane.getBuffer();
+        int yPixStride = yPlane.getPixelStride();
+        int yRowStride = yPlane.getRowStride();
+        ByteBuffer cbBuf = cbPlane.getBuffer();
+        int cbPixStride = cbPlane.getPixelStride();
+        int cbRowStride = cbPlane.getRowStride();
+        ByteBuffer crBuf = crPlane.getBuffer();
+        int crPixStride = crPlane.getPixelStride();
+        int crRowStride = crPlane.getRowStride();
+
+        int[] output = new int[w * h];
+
+        // TODO: Optimize this with renderscript intrinsics
+        byte[] yRow = new byte[yPixStride * w];
+        byte[] cbRow = new byte[cbPixStride * w / 2];
+        byte[] crRow = new byte[crPixStride * w / 2];
+        yBuf.mark();
+        cbBuf.mark();
+        crBuf.mark();
+        int initialYPos = yBuf.position();
+        int initialCbPos = cbBuf.position();
+        int initialCrPos = crBuf.position();
+        int outputPos = 0;
+        for (int i = hOffset; i < hOffset + h; i++) {
+            yBuf.position(initialYPos + i * yRowStride + wOffset * yPixStride);
+            yBuf.get(yRow);
+            if ((i & 1) == (hOffset & 1)) {
+                cbBuf.position(initialCbPos + (i / 2) * cbRowStride + wOffset * cbPixStride / 2);
+                cbBuf.get(cbRow);
+                crBuf.position(initialCrPos + (i / 2) * crRowStride + wOffset * crPixStride / 2);
+                crBuf.get(crRow);
+            }
+            for (int j = 0, yPix = 0, crPix = 0, cbPix = 0; j < w; j++, yPix += yPixStride) {
+                float y = yRow[yPix] & 0xFF;
+                float cb = cbRow[cbPix] & 0xFF;
+                float cr = crRow[crPix] & 0xFF;
+
+                // convert YUV -> RGB (from JFIF's "Conversion to and from RGB" section)
+                int r = (int) Math.max(0.0f, Math.min(COLOR_RANGE, y + 1.402f * (cr - 128)));
+                int g = (int) Math.max(0.0f,
+                        Math.min(COLOR_RANGE, y - 0.34414f * (cb - 128) - 0.71414f * (cr - 128)));
+                int b = (int) Math.max(0.0f, Math.min(COLOR_RANGE, y + 1.772f * (cb - 128)));
+
+                // Convert to ARGB pixel color (use opaque alpha)
+                output[outputPos++] = Color.rgb(r, g, b);
+
+                if ((j & 1) == 1) {
+                    crPix += crPixStride;
+                    cbPix += cbPixStride;
+                }
+            }
+        }
+        yBuf.rewind();
+        cbBuf.rewind();
+        crBuf.rewind();
+
+        return output;
+    }
+
+    /**
+     * Test capture a given format stream with yuv stream simultaneously.
+     *
+     * <p>Use fixed yuv size, varies targeted format capture size. Single capture is tested.</p>
+     *
+     * @param format The capture format to be tested along with yuv format.
+     */
+    private void bufferFormatWithYuvTestByCamera(int format) throws Exception {
+        if (format != ImageFormat.JPEG && format != ImageFormat.RAW_SENSOR
+                && format != ImageFormat.YUV_420_888) {
+            throw new IllegalArgumentException("Unsupported format: " + format);
+        }
+
+        final int NUM_SINGLE_CAPTURE_TESTED = MAX_NUM_IMAGES - 1;
+        Size maxYuvSz = mOrderedPreviewSizes.get(0);
+        Size[] targetCaptureSizes = mStaticInfo.getAvailableSizesForFormatChecked(format,
+                StaticMetadata.StreamDirection.Output);
+
+        for (Size captureSz : targetCaptureSizes) {
+            if (VERBOSE) {
+                Log.v(TAG, "Testing yuv size " + maxYuvSz.toString() + " and capture size "
+                        + captureSz.toString() + " for camera " + mCamera.getId());
+            }
+
+            ImageReader captureReader = null;
+            ImageReader yuvReader = null;
+            try {
+                // Create YUV image reader
+                SimpleImageReaderListener yuvListener  = new SimpleImageReaderListener();
+                yuvReader = createImageReader(maxYuvSz, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
+                        yuvListener);
+                Surface yuvSurface = yuvReader.getSurface();
+
+                // Create capture image reader
+                SimpleImageReaderListener captureListener = new SimpleImageReaderListener();
+                captureReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
+                        captureListener);
+                Surface captureSurface = captureReader.getSurface();
+
+                // Capture images.
+                List<Surface> outputSurfaces = new ArrayList<Surface>();
+                outputSurfaces.add(yuvSurface);
+                outputSurfaces.add(captureSurface);
+                CaptureRequest.Builder request = prepareCaptureRequestForSurfaces(outputSurfaces,
+                        CameraDevice.TEMPLATE_PREVIEW);
+                SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+
+                for (int i = 0; i < NUM_SINGLE_CAPTURE_TESTED; i++) {
+                    startCapture(request.build(), /*repeating*/false, resultListener, mHandler);
+                }
+
+                // Verify capture result and images
+                for (int i = 0; i < NUM_SINGLE_CAPTURE_TESTED; i++) {
+                    resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
+                    if (VERBOSE) {
+                        Log.v(TAG, " Got the capture result back for " + i + "th capture");
+                    }
+
+                    Image yuvImage = yuvListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
+                    if (VERBOSE) {
+                        Log.v(TAG, " Got the yuv image back for " + i + "th capture");
+                    }
+
+                    Image captureImage = captureListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
+                    if (VERBOSE) {
+                        Log.v(TAG, " Got the capture image back for " + i + "th capture");
+                    }
+
+                    //Validate captured images.
+                    CameraTestUtils.validateImage(yuvImage, maxYuvSz.getWidth(),
+                            maxYuvSz.getHeight(), ImageFormat.YUV_420_888, /*filePath*/null);
+                    CameraTestUtils.validateImage(captureImage, captureSz.getWidth(),
+                            captureSz.getHeight(), format, /*filePath*/null);
+                    yuvImage.close();
+                    captureImage.close();
+                }
+
+                // Stop capture, delete the streams.
+                stopCapture(/*fast*/false);
+            } finally {
+                closeImageReader(captureReader);
+                captureReader = null;
+                closeImageReader(yuvReader);
+                yuvReader = null;
+            }
+        }
+    }
+
+    private void invalidAccessTestAfterClose() throws Exception {
+        final int FORMAT = mStaticInfo.isColorOutputSupported() ?
+            ImageFormat.YUV_420_888 : ImageFormat.DEPTH16;
+
+        Size[] availableSizes = mStaticInfo.getAvailableSizesForFormatChecked(FORMAT,
+                StaticMetadata.StreamDirection.Output);
+        Image img = null;
+        // Create ImageReader.
+        mListener = new SimpleImageListener();
+        createDefaultImageReader(availableSizes[0], FORMAT, MAX_NUM_IMAGES, mListener);
+
+        // Start capture.
+        CaptureRequest request = prepareCaptureRequest();
+        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+        startCapture(request, /* repeating */false, listener, mHandler);
+
+        mListener.waitForAnyImageAvailable(CAPTURE_WAIT_TIMEOUT_MS);
+        img = mReader.acquireNextImage();
+        Plane firstPlane = img.getPlanes()[0];
+        ByteBuffer buffer = firstPlane.getBuffer();
+        img.close();
+
+        imageInvalidAccessTestAfterClose(img, firstPlane, buffer);
+    }
+
+    private void bufferFormatTestByCamera(int format, boolean repeating) throws Exception {
+
+        Size[] availableSizes = mStaticInfo.getAvailableSizesForFormatChecked(format,
+                StaticMetadata.StreamDirection.Output);
+
+        // for each resolution, test imageReader:
+        for (Size sz : availableSizes) {
+            try {
+                if (VERBOSE) {
+                    Log.v(TAG, "Testing size " + sz.toString() + " format " + format
+                            + " for camera " + mCamera.getId());
+                }
+
+                // Create ImageReader.
+                mListener  = new SimpleImageListener();
+                createDefaultImageReader(sz, format, MAX_NUM_IMAGES, mListener);
+
+                // Start capture.
+                CaptureRequest request = prepareCaptureRequest();
+                SimpleCaptureCallback listener = new SimpleCaptureCallback();
+                startCapture(request, repeating, listener, mHandler);
+
+                int numFrameVerified = repeating ? NUM_FRAME_VERIFIED : 1;
+
+                // Validate images.
+                validateImage(sz, format, numFrameVerified, repeating);
+
+                // Validate capture result.
+                validateCaptureResult(format, sz, listener, numFrameVerified);
+
+                // stop capture.
+                stopCapture(/*fast*/false);
+            } finally {
+                closeDefaultImageReader();
+            }
+
+        }
+    }
+
+    private void bufferFormatLongProcessingTimeTestByCamera(int format)
+            throws Exception {
+
+        final int TEST_SENSITIVITY_VALUE = mStaticInfo.getSensitivityClampToRange(204);
+        final long TEST_EXPOSURE_TIME_NS = mStaticInfo.getExposureClampToRange(28000000);
+        final long EXPOSURE_TIME_ERROR_MARGIN_NS = 100000;
+
+        Size[] availableSizes = mStaticInfo.getAvailableSizesForFormatChecked(format,
+                StaticMetadata.StreamDirection.Output);
+
+        // for each resolution, test imageReader:
+        for (Size sz : availableSizes) {
+            Log.v(TAG, "testing size " + sz.toString());
+            try {
+                if (VERBOSE) {
+                    Log.v(TAG, "Testing long processing time: size " + sz.toString() + " format " +
+                            format + " for camera " + mCamera.getId());
+                }
+
+                // Create ImageReader.
+                mListener  = new SimpleImageListener();
+                createDefaultImageReader(sz, format, MAX_NUM_IMAGES, mListener);
+
+                // Setting manual controls
+                List<Surface> outputSurfaces = new ArrayList<Surface>();
+                outputSurfaces.add(mReader.getSurface());
+                CaptureRequest.Builder requestBuilder = prepareCaptureRequestForSurfaces(
+                        outputSurfaces, CameraDevice.TEMPLATE_STILL_CAPTURE);
+
+                requestBuilder.set(
+                        CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
+                requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
+                requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
+                requestBuilder.set(CaptureRequest.CONTROL_AE_MODE,
+                        CaptureRequest.CONTROL_AE_MODE_OFF);
+                requestBuilder.set(CaptureRequest.CONTROL_AWB_MODE,
+                        CaptureRequest.CONTROL_AWB_MODE_OFF);
+                requestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, TEST_SENSITIVITY_VALUE);
+                requestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, TEST_EXPOSURE_TIME_NS);
+
+                SimpleCaptureCallback listener = new SimpleCaptureCallback();
+                startCapture(requestBuilder.build(), /*repeating*/true, listener, mHandler);
+
+                for (int i = 0; i < NUM_LONG_PROCESS_TIME_FRAME_VERIFIED; i++) {
+                    mListener.waitForAnyImageAvailable(CAPTURE_WAIT_TIMEOUT_MS);
+
+                    // Verify image.
+                    Image img = mReader.acquireNextImage();
+                    assertNotNull("Unable to acquire next image", img);
+                    CameraTestUtils.validateImage(img, sz.getWidth(), sz.getHeight(), format,
+                            DEBUG_FILE_NAME_BASE);
+
+                    // Verify the exposure time and iso match the requested values.
+                    CaptureResult result = listener.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
+
+                    long exposureTimeDiff = TEST_EXPOSURE_TIME_NS -
+                            getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
+                    int sensitivityDiff = TEST_SENSITIVITY_VALUE -
+                            getValueNotNull(result, CaptureResult.SENSOR_SENSITIVITY);
+
+                    mCollector.expectTrue(
+                            String.format("Long processing frame %d format %d size %s " +
+                                    "exposure time was %d expecting %d.", i, format, sz.toString(),
+                                    getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME),
+                                    TEST_EXPOSURE_TIME_NS),
+                            exposureTimeDiff < EXPOSURE_TIME_ERROR_MARGIN_NS &&
+                            exposureTimeDiff >= 0);
+
+                    mCollector.expectTrue(
+                            String.format("Long processing frame %d format %d size %s " +
+                                    "sensitivity was %d expecting %d.", i, format, sz.toString(),
+                                    getValueNotNull(result, CaptureResult.SENSOR_SENSITIVITY),
+                                    TEST_SENSITIVITY_VALUE),
+                            sensitivityDiff == 0);
+
+
+                    // Sleep to Simulate long porcessing before closing the image.
+                    Thread.sleep(LONG_PROCESS_TIME_MS);
+                    img.close();
+                }
+                // stop capture.
+                stopCapture(/*fast*/false);
+            } finally {
+                closeDefaultImageReader();
+            }
+        }
+    }
+
+    /**
+     * Validate capture results.
+     *
+     * @param format The format of this capture.
+     * @param size The capture size.
+     * @param listener The capture listener to get capture result callbacks.
+     */
+    private void validateCaptureResult(int format, Size size, SimpleCaptureCallback listener,
+            int numFrameVerified) {
+        for (int i = 0; i < numFrameVerified; i++) {
+            CaptureResult result = listener.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
+
+            // TODO: Update this to use availableResultKeys once shim supports this.
+            if (mStaticInfo.isCapabilitySupported(
+                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS)) {
+                Long exposureTime = getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
+                Integer sensitivity = getValueNotNull(result, CaptureResult.SENSOR_SENSITIVITY);
+                mCollector.expectInRange(
+                        String.format(
+                                "Capture for format %d, size %s exposure time is invalid.",
+                                format, size.toString()),
+                        exposureTime,
+                        mStaticInfo.getExposureMinimumOrDefault(),
+                        mStaticInfo.getExposureMaximumOrDefault()
+                );
+                mCollector.expectInRange(
+                        String.format("Capture for format %d, size %s sensitivity is invalid.",
+                                format, size.toString()),
+                        sensitivity,
+                        mStaticInfo.getSensitivityMinimumOrDefault(),
+                        mStaticInfo.getSensitivityMaximumOrDefault()
+                );
+            }
+            // TODO: add more key validations.
+        }
+    }
+
+    private final class SimpleImageListener implements ImageReader.OnImageAvailableListener {
+        private final ConditionVariable imageAvailable = new ConditionVariable();
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            if (mReader != reader) {
+                return;
+            }
+
+            if (VERBOSE) Log.v(TAG, "new image available");
+            imageAvailable.open();
+        }
+
+        public void waitForAnyImageAvailable(long timeout) {
+            if (imageAvailable.block(timeout)) {
+                imageAvailable.close();
+            } else {
+                fail("wait for image available timed out after " + timeout + "ms");
+            }
+        }
+
+        public void closePendingImages() {
+            Image image = mReader.acquireLatestImage();
+            if (image != null) {
+                image.close();
+            }
+        }
+    }
+
+    private void validateImage(Size sz, int format, int captureCount,  boolean repeating)
+            throws Exception {
+        // TODO: Add more format here, and wrap each one as a function.
+        Image img;
+        final int MAX_RETRY_COUNT = 20;
+        int numImageVerified = 0;
+        int reTryCount = 0;
+        while (numImageVerified < captureCount) {
+            assertNotNull("Image listener is null", mListener);
+            if (VERBOSE) Log.v(TAG, "Waiting for an Image");
+            mListener.waitForAnyImageAvailable(CAPTURE_WAIT_TIMEOUT_MS);
+            if (repeating) {
+                /**
+                 * Acquire the latest image in case the validation is slower than
+                 * the image producing rate.
+                 */
+                img = mReader.acquireLatestImage();
+                /**
+                 * Sometimes if multiple onImageAvailable callbacks being queued,
+                 * acquireLatestImage will clear all buffer before corresponding callback is
+                 * executed. Wait for a new frame in that case.
+                 */
+                if (img == null && reTryCount < MAX_RETRY_COUNT) {
+                    reTryCount++;
+                    continue;
+                }
+            } else {
+                img = mReader.acquireNextImage();
+            }
+            assertNotNull("Unable to acquire the latest image", img);
+            if (VERBOSE) Log.v(TAG, "Got the latest image");
+            CameraTestUtils.validateImage(img, sz.getWidth(), sz.getHeight(), format,
+                    DEBUG_FILE_NAME_BASE);
+            if (VERBOSE) Log.v(TAG, "finish validation of image " + numImageVerified);
+            img.close();
+            numImageVerified++;
+            reTryCount = 0;
+        }
+
+        // Return all pending images to the ImageReader as the validateImage may
+        // take a while to return and there could be many images pending.
+        mListener.closePendingImages();
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
new file mode 100644
index 0000000..167e637
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/ImageWriterTest.java
@@ -0,0 +1,366 @@
+/*
+ * 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 static android.hardware.camera2.cts.CameraTestUtils.*;
+
+import android.graphics.ImageFormat;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.media.Image;
+import android.media.Image.Plane;
+import android.media.ImageReader;
+import android.media.ImageWriter;
+import android.util.Log;
+import android.util.Size;
+import android.view.Surface;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * <p>
+ * Basic test for ImageWriter APIs. ImageWriter takes the images produced by
+ * camera (via ImageReader), then the data is consumed by either camera input
+ * interface or ImageReader.
+ * </p>
+ */
+public class ImageWriterTest extends Camera2AndroidTestCase {
+    private static final String TAG = "ImageWriterTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    // Max number of images can be accessed simultaneously from ImageReader.
+    private static final int MAX_NUM_IMAGES = 3;
+    private static final int CAMERA_PRIVATE_FORMAT = ImageFormat.PRIVATE;
+    private ImageReader mReaderForWriter;
+    private ImageWriter mWriter;
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            closeImageReader(mReaderForWriter);
+        } finally {
+            mReaderForWriter = null;
+            if (mWriter != null) {
+                mWriter.close();
+                mWriter = null;
+            }
+        }
+
+        super.tearDown();
+    }
+
+    /**
+     * `
+     * <p>
+     * Basic YUV420_888 format ImageWriter ImageReader test that checks the
+     * images produced by camera can be passed correctly by ImageWriter.
+     * </p>
+     * <p>
+     * {@link ImageReader} reads the images produced by {@link CameraDevice}.
+     * The images are then passed to ImageWriter, which produces new images that
+     * are consumed by the second image reader. The images from first
+     * ImageReader should be identical with the images from the second
+     * ImageReader. This validates the basic image input interface of the
+     * ImageWriter. Below is the data path tested:
+     * <li>Explicit data copy: Dequeue an image from ImageWriter, copy the image
+     * data from first ImageReader into this image, then queue this image back
+     * to ImageWriter. This validates the ImageWriter explicit buffer copy
+     * interface.</li>
+     * </p>
+     */
+    public void testYuvImageWriterReaderOperation() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Camera " + id);
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                readerWriterFormatTestByCamera(ImageFormat.YUV_420_888);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * Basic Opaque format ImageWriter ImageReader test that checks the images
+     * produced by camera can be passed correctly by ImageWriter.
+     * </p>
+     * <p>
+     * {@link ImageReader} reads the images produced by {@link CameraDevice}.
+     * The images are then passed to ImageWriter, which produces new images that
+     * are consumed by the second image reader. The images from first
+     * ImageReader should be identical with the images from the second
+     * ImageReader. This validates the basic image input interface of the
+     * ImageWriter. Because opaque image is inaccessible by client, this test
+     * only covers below path, and only the image info is validated.
+     * <li>Direct image input to ImageWriter. The image from first ImageReader
+     * is directly injected into ImageWriter without needing to dequeue an input
+     * image. ImageWriter will migrate this opaque image into the destination
+     * surface without any data copy.</li>
+     * </p>
+     */
+    public void testOpaqueImageWriterReaderOperation() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Camera " + id);
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                readerWriterFormatTestByCamera(CAMERA_PRIVATE_FORMAT);
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testAbandonedSurfaceExceptions() throws Exception {
+        final int READER_WIDTH = 1920;
+        final int READER_HEIGHT = 1080;
+        final int READER_FORMAT = ImageFormat.YUV_420_888;
+
+        // Verify that if the image writer's input surface is abandoned, dequeueing an image
+        // throws IllegalStateException
+        ImageReader reader = ImageReader.newInstance(READER_WIDTH, READER_HEIGHT, READER_FORMAT,
+                MAX_NUM_IMAGES);
+        ImageWriter writer = ImageWriter.newInstance(reader.getSurface(), MAX_NUM_IMAGES);
+
+        // Close image reader to abandon the input surface.
+        reader.close();
+
+        Image image;
+        try {
+            image = writer.dequeueInputImage();
+            fail("Should get an IllegalStateException");
+        } catch (IllegalStateException e) {
+            // Expected
+        } finally {
+            writer.close();
+        }
+
+        // Verify that if the image writer's input surface is abandoned, queueing an image
+        // throws IllegalStateException
+        reader = ImageReader.newInstance(READER_WIDTH, READER_HEIGHT, READER_FORMAT,
+                MAX_NUM_IMAGES);
+        writer = ImageWriter.newInstance(reader.getSurface(), MAX_NUM_IMAGES);
+        image = writer.dequeueInputImage();
+
+        // Close image reader to abandon the input surface.
+        reader.close();
+
+        try {
+            writer.queueInputImage(image);
+            fail("Should get an IllegalStateException");
+        } catch (IllegalStateException e) {
+            // Expected
+        } finally {
+            writer.close();
+        }
+    }
+
+    private void readerWriterFormatTestByCamera(int format)  throws Exception {
+        List<Size> sizes = getSortedSizesForFormat(mCamera.getId(), mCameraManager, format, null);
+        Size maxSize = sizes.get(0);
+        if (VERBOSE) {
+            Log.v(TAG, "Testing size " + maxSize);
+        }
+
+        // Create ImageReader for camera output.
+        SimpleImageReaderListener listenerForCamera  = new SimpleImageReaderListener();
+        createDefaultImageReader(maxSize, format, MAX_NUM_IMAGES, listenerForCamera);
+        if (VERBOSE) {
+            Log.v(TAG, "Created camera output ImageReader");
+        }
+
+        // Create ImageReader for ImageWriter output
+        SimpleImageReaderListener listenerForWriter  = new SimpleImageReaderListener();
+        mReaderForWriter = createImageReader(maxSize, format, MAX_NUM_IMAGES, listenerForWriter);
+        if (VERBOSE) {
+            Log.v(TAG, "Created ImageWriter output ImageReader");
+        }
+
+        // Create ImageWriter
+        Surface surface = mReaderForWriter.getSurface();
+        assertNotNull("Surface from ImageReader shouldn't be null", surface);
+        mWriter = ImageWriter.newInstance(surface, MAX_NUM_IMAGES);
+        SimpleImageWriterListener writerImageListener = new SimpleImageWriterListener(mWriter);
+        mWriter.setOnImageReleasedListener(writerImageListener, mHandler);
+
+        // Start capture: capture 2 images.
+        List<Surface> outputSurfaces = new ArrayList<Surface>();
+        outputSurfaces.add(mReader.getSurface());
+        CaptureRequest.Builder requestBuilder = prepareCaptureRequestForSurfaces(outputSurfaces,
+                CameraDevice.TEMPLATE_PREVIEW);
+        SimpleCaptureCallback captureListener = new SimpleCaptureCallback();
+        // Capture 1st image.
+        startCapture(requestBuilder.build(), /*repeating*/false, captureListener, mHandler);
+        // Capture 2nd image.
+        startCapture(requestBuilder.build(), /*repeating*/false, captureListener, mHandler);
+        if (VERBOSE) {
+            Log.v(TAG, "Submitted 2 captures");
+        }
+
+        // Image from the first ImageReader.
+        Image cameraImage = null;
+        // ImageWriter input image.
+        Image inputImage = null;
+        // Image from the second ImageReader.
+        Image outputImage = null;
+        assertTrue("ImageWriter max images should be " + MAX_NUM_IMAGES,
+                mWriter.getMaxImages() == MAX_NUM_IMAGES);
+        if (format == CAMERA_PRIVATE_FORMAT) {
+            assertTrue("First ImageReader format should be PRIVATE",
+                    mReader.getImageFormat() == CAMERA_PRIVATE_FORMAT);
+            assertTrue("Second ImageReader should be PRIVATE",
+                    mReaderForWriter.getImageFormat() == CAMERA_PRIVATE_FORMAT);
+            assertTrue("Format of first ImageReader should be PRIVATE",
+                    mReader.getImageFormat() == CAMERA_PRIVATE_FORMAT);
+            assertTrue(" Format of second ImageReader should be PRIVATE",
+                    mReaderForWriter.getImageFormat() == CAMERA_PRIVATE_FORMAT);
+            assertTrue(" Format of ImageWriter should be PRIVATE",
+                    mWriter.getFormat() == CAMERA_PRIVATE_FORMAT);
+
+            // Validate 2 images
+            validateOpaqueImages(maxSize, listenerForCamera, listenerForWriter, captureListener,
+                    /*numImages*/2, writerImageListener);
+        } else {
+            // Test case 1: Explicit data copy, only applicable for explicit formats.
+
+            // Get 1st image from first ImageReader, and copy the data to ImageWrtier input image
+            cameraImage = listenerForCamera.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            inputImage = mWriter.dequeueInputImage();
+            inputImage.setTimestamp(cameraImage.getTimestamp());
+            if (VERBOSE) {
+                Log.v(TAG, "Image is being copied");
+            }
+            imageCopy(cameraImage, inputImage);
+            if (VERBOSE) {
+                Log.v(TAG, "Image copy is done");
+            }
+            mCollector.expectTrue(
+                    "ImageWriter 1st input image should match camera 1st output image",
+                    isImageStronglyEqual(inputImage, cameraImage));
+
+            // Image should be closed after queueInputImage call
+            Plane closedPlane = inputImage.getPlanes()[0];
+            ByteBuffer closedBuffer = closedPlane.getBuffer();
+            mWriter.queueInputImage(inputImage);
+            imageInvalidAccessTestAfterClose(inputImage, closedPlane, closedBuffer);
+
+            outputImage = listenerForWriter.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            mCollector.expectTrue("ImageWriter 1st output image should match 1st input image",
+                    isImageStronglyEqual(cameraImage, outputImage));
+            if (DEBUG) {
+                String img1FileName = DEBUG_FILE_NAME_BASE + "/" + maxSize + "_image1_copy.yuv";
+                String outputImg1FileName = DEBUG_FILE_NAME_BASE + "/" + maxSize
+                        + "_outputImage2_copy.yuv";
+                dumpFile(img1FileName, getDataFromImage(cameraImage));
+                dumpFile(outputImg1FileName, getDataFromImage(outputImage));
+            }
+            // No need to close inputImage, as it is sent to the surface after queueInputImage;
+            cameraImage.close();
+            outputImage.close();
+
+            // Make sure ImageWriter listener callback is fired.
+            writerImageListener.waitForImageReleased(CAPTURE_IMAGE_TIMEOUT_MS);
+
+            // Test case 2: Directly inject the image into ImageWriter: works for all formats.
+
+            // Get 2nd image and queue it directly to ImageWrier
+            cameraImage = listenerForCamera.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            // make a copy of image1 data, as it will be closed after queueInputImage;
+            byte[] img1Data = getDataFromImage(cameraImage);
+            if (DEBUG) {
+                String img2FileName = DEBUG_FILE_NAME_BASE + "/" + maxSize + "_image2.yuv";
+                dumpFile(img2FileName, img1Data);
+            }
+
+            // Image should be closed after queueInputImage call
+            closedPlane = cameraImage.getPlanes()[0];
+            closedBuffer = closedPlane.getBuffer();
+            mWriter.queueInputImage(cameraImage);
+            imageInvalidAccessTestAfterClose(cameraImage, closedPlane, closedBuffer);
+
+            outputImage = listenerForWriter.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            byte[] outputImageData = getDataFromImage(outputImage);
+
+            mCollector.expectTrue("ImageWriter 2nd output image should match camera "
+                    + "2nd output image", Arrays.equals(img1Data, outputImageData));
+
+            if (DEBUG) {
+                String outputImgFileName = DEBUG_FILE_NAME_BASE + "/" + maxSize +
+                        "_outputImage2.yuv";
+                dumpFile(outputImgFileName, outputImageData);
+            }
+            // No need to close inputImage, as it is sent to the surface after queueInputImage;
+            outputImage.close();
+
+            // Make sure ImageWriter listener callback is fired.
+            writerImageListener.waitForImageReleased(CAPTURE_IMAGE_TIMEOUT_MS);
+        }
+
+        stopCapture(/*fast*/false);
+        mReader.close();
+        mReader = null;
+        mReaderForWriter.close();
+        mReaderForWriter = null;
+        mWriter.close();
+        mWriter = null;
+    }
+
+    private void validateOpaqueImages(Size maxSize, SimpleImageReaderListener listenerForCamera,
+            SimpleImageReaderListener listenerForWriter, SimpleCaptureCallback captureListener,
+            int numImages, SimpleImageWriterListener writerListener) throws Exception {
+        Image cameraImage;
+        Image outputImage;
+        for (int i = 0; i < numImages; i++) {
+            cameraImage = listenerForCamera.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            CaptureResult result = captureListener.getCaptureResult(CAPTURE_IMAGE_TIMEOUT_MS);
+            validateOpaqueImage(cameraImage, "Opaque image " + i + "from camera: ", maxSize,
+                    result);
+            mWriter.queueInputImage(cameraImage);
+            // Image should be closed after queueInputImage
+            imageInvalidAccessTestAfterClose(cameraImage,
+                    /*closedPlane*/null, /*closedBuffer*/null);
+            outputImage = listenerForWriter.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            validateOpaqueImage(outputImage, "First Opaque image output by ImageWriter: ",
+                    maxSize, result);
+            outputImage.close();
+            writerListener.waitForImageReleased(CAPTURE_IMAGE_TIMEOUT_MS);
+        }
+    }
+
+    private void validateOpaqueImage(Image image, String msg, Size imageSize,
+            CaptureResult result) {
+        assertNotNull("Opaque image Capture result should not be null", result != null);
+        mCollector.expectImageProperties(msg + "Opaque ", image, CAMERA_PRIVATE_FORMAT,
+                imageSize, result.get(CaptureResult.SENSOR_TIMESTAMP));
+        mCollector.expectTrue(msg + "Opaque image number planes should be zero",
+                image.getPlanes().length == 0);
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/MultiViewTest.java b/tests/camera/src/android/hardware/camera2/cts/MultiViewTest.java
new file mode 100644
index 0000000..2795bde
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/MultiViewTest.java
@@ -0,0 +1,287 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+
+import android.graphics.ImageFormat;
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.cts.CameraTestUtils.ImageVerifierListener;
+import android.hardware.camera2.cts.testcases.Camera2MultiViewTestCase;
+import android.hardware.camera2.cts.testcases.Camera2MultiViewTestCase.CameraPreviewListener;
+import android.media.ImageReader;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.Size;
+import android.view.Surface;
+import android.view.TextureView;
+
+import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * CameraDevice test by using combination of SurfaceView, TextureView and ImageReader
+ */
+public class MultiViewTest extends Camera2MultiViewTestCase {
+    private static final String TAG = "MultiViewTest";
+    private final static long WAIT_FOR_COMMAND_TO_COMPLETE = 2000;
+    private final static long PREVIEW_TIME_MS = 2000;
+
+    public void testTextureViewPreview() throws Exception {
+        for (String cameraId : mCameraIds) {
+            Exception prior = null;
+
+            try {
+                openCamera(cameraId);
+                if (!getStaticInfo(cameraId).isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + cameraId + " does not support color outputs, skipping");
+                    continue;
+                }
+                List<TextureView> views = Arrays.asList(mTextureView[0]);
+                textureViewPreview(cameraId, views, /*ImageReader*/null);
+            } catch (Exception e) {
+                prior = e;
+            } finally {
+                try {
+                    closeCamera(cameraId);
+                } catch (Exception e) {
+                    if (prior != null) {
+                        Log.e(TAG, "Prior exception received: " + prior);
+                    }
+                    prior = e;
+                }
+                if (prior != null) throw prior; // Rethrow last exception.
+            }
+        }
+    }
+
+    public void testTextureViewPreviewWithImageReader() throws Exception {
+        for (String cameraId : mCameraIds) {
+            Exception prior = null;
+
+            ImageVerifierListener yuvListener;
+            ImageReader yuvReader = null;
+
+            try {
+                openCamera(cameraId);
+                if (!getStaticInfo(cameraId).isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + cameraId + " does not support color outputs, skipping");
+                    continue;
+                }
+                Size previewSize = getOrderedPreviewSizes(cameraId).get(0);
+                yuvListener =
+                        new ImageVerifierListener(previewSize, ImageFormat.YUV_420_888);
+                yuvReader = makeImageReader(previewSize,
+                        ImageFormat.YUV_420_888, MAX_READER_IMAGES, yuvListener, mHandler);
+                int maxNumStreamsProc =
+                        getStaticInfo(cameraId).getMaxNumOutputStreamsProcessedChecked();
+                if (maxNumStreamsProc < 2) {
+                    continue;
+                }
+                List<TextureView> views = Arrays.asList(mTextureView[0]);
+                textureViewPreview(cameraId, views, yuvReader);
+            } catch (Exception e) {
+                prior = e;
+            } finally {
+                try {
+                    if (yuvReader != null) {
+                        yuvReader.close();
+                    }
+                    closeCamera(cameraId);
+                } catch (Exception e) {
+                    if (prior != null) {
+                        Log.e(TAG, "Prior exception received: " + prior);
+                    }
+                    prior = e;
+                }
+                if (prior != null) throw prior; // Rethrow last exception.
+            }
+        }
+    }
+
+    public void testDualTextureViewPreview() throws Exception {
+        for (String cameraId : mCameraIds) {
+            Exception prior = null;
+            try {
+                openCamera(cameraId);
+                if (!getStaticInfo(cameraId).isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + cameraId + " does not support color outputs, skipping");
+                    continue;
+                }
+                int maxNumStreamsProc =
+                        getStaticInfo(cameraId).getMaxNumOutputStreamsProcessedChecked();
+                if (maxNumStreamsProc < 2) {
+                    continue;
+                }
+                List<TextureView> views = Arrays.asList(mTextureView[0], mTextureView[1]);
+                textureViewPreview(cameraId, views, /*ImageReader*/null);
+            } catch (Exception e) {
+                prior = e;
+            } finally {
+                try {
+                    closeCamera(cameraId);
+                } catch (Exception e) {
+                    if (prior != null) {
+                        Log.e(TAG, "Prior exception received: " + prior);
+                    }
+                    prior = e;
+                }
+                if (prior != null) throw prior; // Rethrow last exception.
+            }
+        }
+    }
+
+    public void testDualTextureViewAndImageReaderPreview() throws Exception {
+        for (String cameraId : mCameraIds) {
+            Exception prior = null;
+
+            ImageVerifierListener yuvListener;
+            ImageReader yuvReader = null;
+
+            try {
+                openCamera(cameraId);
+                if (!getStaticInfo(cameraId).isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + cameraId + " does not support color outputs, skipping");
+                    continue;
+                }
+                Size previewSize = getOrderedPreviewSizes(cameraId).get(0);
+                yuvListener =
+                        new ImageVerifierListener(previewSize, ImageFormat.YUV_420_888);
+                yuvReader = makeImageReader(previewSize,
+                        ImageFormat.YUV_420_888, MAX_READER_IMAGES, yuvListener, mHandler);
+                int maxNumStreamsProc =
+                        getStaticInfo(cameraId).getMaxNumOutputStreamsProcessedChecked();
+                if (maxNumStreamsProc < 3) {
+                    continue;
+                }
+                List<TextureView> views = Arrays.asList(mTextureView[0], mTextureView[1]);
+                textureViewPreview(cameraId, views, yuvReader);
+            } catch (Exception e) {
+                prior = e;
+            } finally {
+                try {
+                    if (yuvReader != null) {
+                        yuvReader.close();
+                    }
+                    closeCamera(cameraId);
+                } catch (Exception e) {
+                    if (prior != null) {
+                        Log.e(TAG, "Prior exception received: " + prior);
+                    }
+                    prior = e;
+                }
+                if (prior != null) throw prior; // Rethrow last exception.
+            }
+        }
+    }
+
+    public void testDualCameraPreview() throws Exception {
+        final int NUM_CAMERAS_TESTED = 2;
+        if (mCameraIds.length < NUM_CAMERAS_TESTED) {
+            return;
+        }
+
+        try {
+            for (int i = 0; i < NUM_CAMERAS_TESTED; i++) {
+                openCamera(mCameraIds[i]);
+                if (!getStaticInfo(mCameraIds[i]).isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                List<TextureView> views = Arrays.asList(mTextureView[i]);
+
+                startTextureViewPreview(mCameraIds[i], views, /*ImageReader*/null);
+            }
+            // TODO: check the framerate is correct
+            SystemClock.sleep(PREVIEW_TIME_MS);
+            for (int i = 0; i < NUM_CAMERAS_TESTED; i++) {
+                stopPreview(mCameraIds[i]);
+            }
+        } catch (BlockingOpenException e) {
+            // The only error accepted is ERROR_MAX_CAMERAS_IN_USE, which means HAL doesn't support
+            // concurrent camera streaming
+            assertEquals("Camera device open failed",
+                    CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE, e.getCode());
+            Log.i(TAG, "Camera HAL does not support dual camera preview. Skip the test");
+        } finally {
+            for (int i = 0; i < NUM_CAMERAS_TESTED; i++) {
+                closeCamera(mCameraIds[i]);
+            }
+        }
+    }
+
+    /**
+     * Start camera preview using input texture views and/or one image reader
+     */
+    private void startTextureViewPreview(
+            String cameraId, List<TextureView> views, ImageReader imageReader)
+            throws Exception {
+        int numPreview = views.size();
+        Size previewSize = getOrderedPreviewSizes(cameraId).get(0);
+        CameraPreviewListener[] previewListener =
+                new CameraPreviewListener[numPreview];
+        SurfaceTexture[] previewTexture = new SurfaceTexture[numPreview];
+        List<Surface> surfaces = new ArrayList<Surface>();
+
+        // Prepare preview surface.
+        int i = 0;
+        for (TextureView view : views) {
+            previewListener[i] = new CameraPreviewListener();
+            view.setSurfaceTextureListener(previewListener[i]);
+            previewTexture[i] = getAvailableSurfaceTexture(WAIT_FOR_COMMAND_TO_COMPLETE, view);
+            assertNotNull("Unable to get preview surface texture", previewTexture[i]);
+            previewTexture[i].setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
+            // Correct the preview display rotation.
+            updatePreviewDisplayRotation(previewSize, view);
+            surfaces.add(new Surface(previewTexture[i]));
+            i++;
+        }
+        if (imageReader != null) {
+            surfaces.add(imageReader.getSurface());
+        }
+
+        startPreview(cameraId, surfaces, null);
+
+        i = 0;
+        for (TextureView view : views) {
+            boolean previewDone =
+                    previewListener[i].waitForPreviewDone(WAIT_FOR_COMMAND_TO_COMPLETE);
+            assertTrue("Unable to start preview " + i, previewDone);
+            view.setSurfaceTextureListener(null);
+            i++;
+        }
+    }
+
+    /**
+     * Test camera preview using input texture views and/or one image reader
+     */
+    private void textureViewPreview(
+            String cameraId, List<TextureView> views, ImageReader testImagerReader)
+            throws Exception {
+        startTextureViewPreview(cameraId, views, testImagerReader);
+
+        // TODO: check the framerate is correct
+        SystemClock.sleep(PREVIEW_TIME_MS);
+
+        stopPreview(cameraId);
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
new file mode 100644
index 0000000..39eb1dc
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/PerformanceTest.java
@@ -0,0 +1,894 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
+
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleImageReaderListener;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+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 com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+import com.android.cts.util.Stat;
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test camera2 API use case performance KPIs, such as camera open time, session creation time,
+ * shutter lag etc. The KPI data will be reported in cts results.
+ */
+public class PerformanceTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "PerformanceTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final int NUM_TEST_LOOPS = 5;
+    private static final int NUM_MAX_IMAGES = 4;
+    private static final int NUM_RESULTS_WAIT = 30;
+    private static final int[] REPROCESS_FORMATS = {ImageFormat.YUV_420_888, ImageFormat.PRIVATE};
+    private final int MAX_REPROCESS_IMAGES = 6;
+    private final int MAX_JPEG_IMAGES = MAX_REPROCESS_IMAGES;
+    private final int MAX_INPUT_IMAGES = MAX_REPROCESS_IMAGES;
+    // ZSL queue depth should be bigger than the max simultaneous reprocessing capture request
+    // count to maintain reasonable number of candidate image for the worse-case.
+    private final int MAX_ZSL_IMAGES = MAX_REPROCESS_IMAGES * 3 / 2;
+    private final double REPROCESS_STALL_MARGIN = 0.1;
+
+    private DeviceReportLog mReportLog;
+
+    // Used for reading camera output buffers.
+    private ImageReader mCameraZslReader;
+    private SimpleImageReaderListener mCameraZslImageListener;
+    // Used for reprocessing (jpeg) output.
+    private ImageReader mJpegReader;
+    private SimpleImageReaderListener mJpegListener;
+    // Used for reprocessing input.
+    private ImageWriter mWriter;
+    private SimpleCaptureCallback mZslResultListener;
+
+    @Override
+    protected void setUp() throws Exception {
+        mReportLog = new DeviceReportLog();
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Deliver the report to host will automatically clear the report log.
+        mReportLog.deliverReportToHost(getInstrumentation());
+        super.tearDown();
+    }
+
+    /**
+     * Test camera launch KPI: the time duration between a camera device is
+     * being opened and first preview frame is available.
+     * <p>
+     * It includes camera open time, session creation time, and sending first
+     * preview request processing latency etc. For the SurfaceView based preview use
+     * case, there is no way for client to know the exact preview frame
+     * arrival time. To approximate this time, a companion YUV420_888 stream is
+     * created. The first YUV420_888 Image coming out of the ImageReader is treated
+     * as the first preview arrival time.</p>
+     * <p>
+     * For depth-only devices, timing is done with the DEPTH16 format instead.
+     * </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) {
+            try {
+                mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(id));
+                if (mStaticInfo.isColorOutputSupported()) {
+                    initializeImageReader(id, ImageFormat.YUV_420_888);
+                } else {
+                    assertTrue("Depth output must be supported if regular output isn't!",
+                            mStaticInfo.isDepthOutputSupported());
+                    initializeImageReader(id, ImageFormat.DEPTH16);
+                }
+
+                SimpleImageListener imageListener = null;
+                long startTimeMs, openTimeMs, configureTimeMs, previewStartedTimeMs;
+                for (int i = 0; i < NUM_TEST_LOOPS; i++) {
+                    try {
+                        // Need create a new listener every iteration to be able to wait
+                        // for the first image comes out.
+                        imageListener = new SimpleImageListener();
+                        mReader.setOnImageAvailableListener(imageListener, mHandler);
+                        startTimeMs = SystemClock.elapsedRealtime();
+
+                        // Blocking open camera
+                        simpleOpenCamera(id);
+                        openTimeMs = SystemClock.elapsedRealtime();
+                        cameraOpenTimes[i] = openTimeMs - startTimeMs;
+
+                        // Blocking configure outputs.
+                        configureReaderAndPreviewOutputs();
+                        configureTimeMs = SystemClock.elapsedRealtime();
+                        configureStreamTimes[i] = configureTimeMs - openTimeMs;
+
+                        // Blocking start preview (start preview to first image arrives)
+                        SimpleCaptureCallback resultListener =
+                                new SimpleCaptureCallback();
+                        blockingStartPreview(resultListener, imageListener);
+                        previewStartedTimeMs = SystemClock.elapsedRealtime();
+                        startPreviewTimes[i] = previewStartedTimeMs - configureTimeMs;
+                        cameraLaunchTimes[i] = previewStartedTimeMs - startTimeMs;
+
+                        // Let preview on for a couple of frames
+                        waitForNumResults(resultListener, NUM_RESULTS_WAIT);
+
+                        // Blocking stop preview
+                        startTimeMs = SystemClock.elapsedRealtime();
+                        blockingStopPreview();
+                        stopPreviewTimes[i] = SystemClock.elapsedRealtime() - startTimeMs;
+                    }
+                    finally {
+                        // Blocking camera close
+                        startTimeMs = SystemClock.elapsedRealtime();
+                        closeDevice();
+                        cameraCloseTimes[i] = SystemClock.elapsedRealtime() - startTimeMs;
+                    }
+                }
+
+                avgCameraLaunchTimes[counter] = Stat.getAverage(cameraLaunchTimes);
+                // Finish the data collection, report the KPIs.
+                mReportLog.printArray("Camera " + id
+                        + ": Camera open time", cameraOpenTimes,
+                        ResultType.LOWER_BETTER, ResultUnit.MS);
+                mReportLog.printArray("Camera " + id
+                        + ": Camera configure stream time", configureStreamTimes,
+                        ResultType.LOWER_BETTER, ResultUnit.MS);
+                mReportLog.printArray("Camera " + id
+                        + ": Camera start preview time", startPreviewTimes,
+                        ResultType.LOWER_BETTER, ResultUnit.MS);
+                mReportLog.printArray("Camera " + id
+                        + ": Camera stop preview", stopPreviewTimes,
+                        ResultType.LOWER_BETTER, ResultUnit.MS);
+                mReportLog.printArray("Camera " + id
+                        + ": Camera close time", cameraCloseTimes,
+                        ResultType.LOWER_BETTER, ResultUnit.MS);
+                mReportLog.printArray("Camera " + id
+                        + ": Camera launch time", cameraLaunchTimes,
+                        ResultType.LOWER_BETTER, ResultUnit.MS);
+            }
+            finally {
+                closeImageReader();
+            }
+            counter++;
+        }
+        if (mCameraIds.length != 0) {
+            mReportLog.printSummary("Camera launch average time for all cameras ",
+                    Stat.getAverage(avgCameraLaunchTimes), ResultType.LOWER_BETTER, ResultUnit.MS);
+        }
+    }
+
+    /**
+     * Test camera capture KPI for YUV_420_888 format: the time duration between
+     * sending out a single image capture request and receiving image data and
+     * capture result.
+     * <p>
+     * It enumerates the following metrics: capture latency, computed by
+     * measuring the time between sending out the capture request and getting
+     * the image data; partial result latency, computed by measuring the time
+     * between sending out the capture request and getting the partial result;
+     * capture result latency, computed by measuring the time between sending
+     * out the capture request and getting the full capture result.
+     * </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) {
+            try {
+                openDevice(id);
+
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+
+
+                boolean partialsExpected = mStaticInfo.getPartialResultCount() > 1;
+                long startTimeMs;
+                boolean isPartialTimingValid = partialsExpected;
+                for (int i = 0; i < NUM_TEST_LOOPS; i++) {
+
+                    // setup builders and listeners
+                    CaptureRequest.Builder previewBuilder =
+                            mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                    CaptureRequest.Builder captureBuilder =
+                            mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+                    SimpleCaptureCallback previewResultListener =
+                            new SimpleCaptureCallback();
+                    SimpleTimingResultListener captureResultListener =
+                            new SimpleTimingResultListener();
+                    SimpleImageListener imageListener = new SimpleImageListener();
+
+                    Size maxYuvSize = CameraTestUtils.getSortedSizesForFormat(
+                        id, mCameraManager, ImageFormat.YUV_420_888, /*bound*/null).get(0);
+
+                    prepareCaptureAndStartPreview(previewBuilder, captureBuilder,
+                            mOrderedPreviewSizes.get(0), maxYuvSize,
+                            ImageFormat.YUV_420_888, previewResultListener,
+                            NUM_MAX_IMAGES, imageListener);
+
+                    // Capture an image and get image data
+                    startTimeMs = SystemClock.elapsedRealtime();
+                    CaptureRequest request = captureBuilder.build();
+                    mSession.capture(request, captureResultListener, mHandler);
+
+                    Pair<CaptureResult, Long> partialResultNTime = null;
+                    if (partialsExpected) {
+                        partialResultNTime = captureResultListener.getPartialResultNTimeForRequest(
+                            request, NUM_RESULTS_WAIT);
+                        // Even if maxPartials > 1, may not see partials for some devices
+                        if (partialResultNTime == null) {
+                            partialsExpected = false;
+                            isPartialTimingValid = false;
+                        }
+                    }
+                    Pair<CaptureResult, Long> captureResultNTime =
+                            captureResultListener.getCaptureResultNTimeForRequest(
+                                    request, NUM_RESULTS_WAIT);
+                    imageListener.waitForImageAvailable(
+                            CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
+
+                    captureTimes[i] = imageListener.getTimeReceivedImage() - startTimeMs;
+                    if (partialsExpected) {
+                        getPartialTimes[i] = partialResultNTime.second - startTimeMs;
+                        if (getPartialTimes[i] < 0) {
+                            isPartialTimingValid = false;
+                        }
+                    }
+                    getResultTimes[i] = captureResultNTime.second - startTimeMs;
+
+                    // simulate real scenario (preview runs a bit)
+                    waitForNumResults(previewResultListener, NUM_RESULTS_WAIT);
+
+                    blockingStopPreview();
+
+                }
+                mReportLog.printArray("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
+                            + ": Camera partial result latency", getPartialTimes,
+                            ResultType.LOWER_BETTER, ResultUnit.MS);
+                }
+                mReportLog.printArray("Camera " + id
+                        + ": Camera capture result latency", getResultTimes,
+                        ResultType.LOWER_BETTER, ResultUnit.MS);
+
+                avgResultTimes[counter] = Stat.getAverage(getResultTimes);
+            }
+            finally {
+                closeImageReader();
+                closeDevice();
+            }
+            counter++;
+        }
+
+        // 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 ",
+                    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.
+     *
+     */
+    public void testReprocessingLatency() throws Exception {
+        for (String id : mCameraIds) {
+            for (int format : REPROCESS_FORMATS) {
+                if (!isReprocessSupported(id, format)) {
+                    continue;
+                }
+
+                try {
+                    openDevice(id);
+
+                    reprocessingPerformanceTestByCamera(format, /*asyncMode*/false);
+                } finally {
+                    closeReaderWriters();
+                    closeDevice();
+                }
+            }
+        }
+    }
+
+    /**
+     * Test reprocessing throughput, i.e., how many frames can be reprocessed
+     * during a given amount of time.
+     *
+     */
+    public void testReprocessingThroughput() throws Exception {
+        for (String id : mCameraIds) {
+            for (int format : REPROCESS_FORMATS) {
+                if (!isReprocessSupported(id, format)) {
+                    continue;
+                }
+
+                try {
+                    openDevice(id);
+
+                    reprocessingPerformanceTestByCamera(format, /*asyncMode*/true);
+                } finally {
+                    closeReaderWriters();
+                    closeDevice();
+                }
+            }
+        }
+    }
+
+    /**
+     * Testing reprocessing caused preview stall (frame drops)
+     */
+    public void testReprocessingCaptureStall() throws Exception {
+        for (String id : mCameraIds) {
+            for (int format : REPROCESS_FORMATS) {
+                if (!isReprocessSupported(id, format)) {
+                    continue;
+                }
+
+                try {
+                    openDevice(id);
+
+                    reprocessingCaptureStallTestByCamera(format);
+                } finally {
+                    closeReaderWriters();
+                    closeDevice();
+                }
+            }
+        }
+    }
+
+    private void reprocessingCaptureStallTestByCamera(int reprocessInputFormat) throws Exception {
+        prepareReprocessCapture(reprocessInputFormat);
+
+        // Let it stream for a while before reprocessing
+        startZslStreaming();
+        waitForFrames(NUM_RESULTS_WAIT);
+
+        final int NUM_REPROCESS_TESTED = MAX_REPROCESS_IMAGES / 2;
+        // Prepare several reprocessing request
+        Image[] inputImages = new Image[NUM_REPROCESS_TESTED];
+        CaptureRequest.Builder[] reprocessReqs = new CaptureRequest.Builder[MAX_REPROCESS_IMAGES];
+        for (int i = 0; i < NUM_REPROCESS_TESTED; i++) {
+            inputImages[i] =
+                    mCameraZslImageListener.getImage(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
+            TotalCaptureResult zslResult =
+                    mZslResultListener.getCaptureResult(
+                            WAIT_FOR_RESULT_TIMEOUT_MS, inputImages[i].getTimestamp());
+            reprocessReqs[i] = mCamera.createReprocessCaptureRequest(zslResult);
+            reprocessReqs[i].addTarget(mJpegReader.getSurface());
+            mWriter.queueInputImage(inputImages[i]);
+        }
+
+        double[] maxCaptureGapsMs = new double[NUM_REPROCESS_TESTED];
+        double[] averageFrameDurationMs = new double[NUM_REPROCESS_TESTED];
+        Arrays.fill(averageFrameDurationMs, 0.0);
+        final int MAX_REPROCESS_RETURN_FRAME_COUNT = 20;
+        SimpleCaptureCallback reprocessResultListener = new SimpleCaptureCallback();
+        for (int i = 0; i < NUM_REPROCESS_TESTED; i++) {
+            mZslResultListener.drain();
+            CaptureRequest reprocessRequest = reprocessReqs[i].build();
+            mSession.capture(reprocessRequest, reprocessResultListener, mHandler);
+            // Wait for reprocess output jpeg and result come back.
+            reprocessResultListener.getCaptureResultForRequest(reprocessRequest,
+                    CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+            mJpegListener.getImage(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS).close();
+            long numFramesMaybeStalled = mZslResultListener.getTotalNumFrames();
+            assertTrue("Reprocess capture result should be returned in "
+                    + MAX_REPROCESS_RETURN_FRAME_COUNT + " frames",
+                    numFramesMaybeStalled <= MAX_REPROCESS_RETURN_FRAME_COUNT);
+
+            // Need look longer time, as the stutter could happen after the reprocessing
+            // output frame is received.
+            long[] timestampGap = new long[MAX_REPROCESS_RETURN_FRAME_COUNT + 1];
+            Arrays.fill(timestampGap, 0);
+            CaptureResult[] results = new CaptureResult[timestampGap.length];
+            long[] frameDurationsNs = new long[timestampGap.length];
+            for (int j = 0; j < results.length; j++) {
+                results[j] = mZslResultListener.getCaptureResult(
+                        CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
+                if (j > 0) {
+                    timestampGap[j] = results[j].get(CaptureResult.SENSOR_TIMESTAMP) -
+                            results[j - 1].get(CaptureResult.SENSOR_TIMESTAMP);
+                    assertTrue("Time stamp should be monotonically increasing",
+                            timestampGap[j] > 0);
+                }
+                frameDurationsNs[j] = results[j].get(CaptureResult.SENSOR_FRAME_DURATION);
+            }
+
+            if (VERBOSE) {
+                Log.i(TAG, "timestampGap: " + Arrays.toString(timestampGap));
+                Log.i(TAG, "frameDurationsNs: " + Arrays.toString(frameDurationsNs));
+            }
+
+            // Get the number of candidate results, calculate the average frame duration
+            // and max timestamp gap.
+            Arrays.sort(timestampGap);
+            double maxTimestampGapMs = timestampGap[timestampGap.length - 1] / 1000000.0;
+            for (int m = 0; m < frameDurationsNs.length; m++) {
+                averageFrameDurationMs[i] += (frameDurationsNs[m] / 1000000.0);
+            }
+            averageFrameDurationMs[i] /= frameDurationsNs.length;
+
+            maxCaptureGapsMs[i] = maxTimestampGapMs;
+        }
+
+        stopZslStreaming();
+
+        String reprocessType = " YUV reprocessing ";
+        if (reprocessInputFormat == ImageFormat.PRIVATE) {
+            reprocessType = " opaque reprocessing ";
+        }
+
+        mReportLog.printArray("Camera " + mCamera.getId()
+                + ":" + reprocessType + " max capture timestamp gaps", maxCaptureGapsMs,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        mReportLog.printArray("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 "
+                + mCamera.getId(), Stat.getAverage(maxCaptureGapsMs), ResultType.LOWER_BETTER,
+                ResultUnit.MS);
+
+        // The max timestamp gap should be less than (captureStall + 1) x average frame
+        // duration * (1 + error margin).
+        int maxCaptureStallFrames = mStaticInfo.getMaxCaptureStallOrDefault();
+        for (int i = 0; i < maxCaptureGapsMs.length; i++) {
+            double stallDurationBound = averageFrameDurationMs[i] *
+                    (maxCaptureStallFrames + 1) * (1 + REPROCESS_STALL_MARGIN);
+            assertTrue("max capture stall duration should be no larger than " + stallDurationBound,
+                    maxCaptureGapsMs[i] <= stallDurationBound);
+        }
+    }
+
+    private void reprocessingPerformanceTestByCamera(int reprocessInputFormat, boolean asyncMode)
+            throws Exception {
+        // Prepare the reprocessing capture
+        prepareReprocessCapture(reprocessInputFormat);
+
+        // Start ZSL streaming
+        startZslStreaming();
+        waitForFrames(NUM_RESULTS_WAIT);
+
+        CaptureRequest.Builder[] reprocessReqs = new CaptureRequest.Builder[MAX_REPROCESS_IMAGES];
+        Image[] inputImages = new Image[MAX_REPROCESS_IMAGES];
+        double[] getImageLatenciesMs = new double[MAX_REPROCESS_IMAGES];
+        long startTimeMs;
+        for (int i = 0; i < MAX_REPROCESS_IMAGES; i++) {
+            inputImages[i] =
+                    mCameraZslImageListener.getImage(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
+            TotalCaptureResult zslResult =
+                    mZslResultListener.getCaptureResult(
+                            WAIT_FOR_RESULT_TIMEOUT_MS, inputImages[i].getTimestamp());
+            reprocessReqs[i] = mCamera.createReprocessCaptureRequest(zslResult);
+            reprocessReqs[i].addTarget(mJpegReader.getSurface());
+        }
+
+        if (asyncMode) {
+            // async capture: issue all the reprocess requests as quick as possible, then
+            // check the throughput of the output jpegs.
+            for (int i = 0; i < MAX_REPROCESS_IMAGES; i++) {
+                // Could be slow for YUV reprocessing, do it in advance.
+                mWriter.queueInputImage(inputImages[i]);
+            }
+
+            // Submit the requests
+            for (int i = 0; i < MAX_REPROCESS_IMAGES; i++) {
+                mSession.capture(reprocessReqs[i].build(), null, null);
+            }
+
+            // Get images
+            startTimeMs = SystemClock.elapsedRealtime();
+            Image jpegImages[] = new Image[MAX_REPROCESS_IMAGES];
+            for (int i = 0; i < MAX_REPROCESS_IMAGES; i++) {
+                jpegImages[i] = mJpegListener.getImage(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
+                getImageLatenciesMs[i] = SystemClock.elapsedRealtime() - startTimeMs;
+                startTimeMs = SystemClock.elapsedRealtime();
+            }
+            for (Image i : jpegImages) {
+                i.close();
+            }
+        } else {
+            // sync capture: issue reprocess request one by one, only submit next one when
+            // the previous capture image is returned. This is to test the back to back capture
+            // performance.
+            Image jpegImages[] = new Image[MAX_REPROCESS_IMAGES];
+            for (int i = 0; i < MAX_REPROCESS_IMAGES; i++) {
+                startTimeMs = SystemClock.elapsedRealtime();
+                mWriter.queueInputImage(inputImages[i]);
+                mSession.capture(reprocessReqs[i].build(), null, null);
+                jpegImages[i] = mJpegListener.getImage(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
+                getImageLatenciesMs[i] = SystemClock.elapsedRealtime() - startTimeMs;
+            }
+            for (Image i : jpegImages) {
+                i.close();
+            }
+        }
+
+        stopZslStreaming();
+
+        String reprocessType = " YUV reprocessing ";
+        if (reprocessInputFormat == ImageFormat.PRIVATE) {
+            reprocessType = " opaque reprocessing ";
+        }
+
+        // Report the performance data
+        if (asyncMode) {
+            mReportLog.printArray("Camera " + mCamera.getId()
+                    + ":" + reprocessType + "capture latency", getImageLatenciesMs,
+                    ResultType.LOWER_BETTER, ResultUnit.MS);
+            mReportLog.printSummary("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,
+                    ResultType.LOWER_BETTER, ResultUnit.MS);
+            mReportLog.printSummary("Camera reprocessing shot to shot average latency for Camera " +
+                    mCamera.getId(), Stat.getAverage(getImageLatenciesMs), ResultType.LOWER_BETTER,
+                    ResultUnit.MS);
+        }
+    }
+
+    /**
+     * Start preview and ZSL streaming
+     */
+    private void startZslStreaming() throws Exception {
+        CaptureRequest.Builder zslBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
+        zslBuilder.addTarget(mPreviewSurface);
+        zslBuilder.addTarget(mCameraZslReader.getSurface());
+        mSession.setRepeatingRequest(zslBuilder.build(), mZslResultListener, mHandler);
+    }
+
+    private void stopZslStreaming() throws Exception {
+        mSession.stopRepeating();
+        mSessionListener.getStateWaiter().waitForState(
+            BlockingSessionCallback.SESSION_READY, CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
+    }
+
+    /**
+     * Wait for a certain number of frames, the images and results will be drained from the
+     * listeners to make sure that next reprocessing can get matched results and images.
+     *
+     * @param numFrameWait The number of frames to wait before return, 0 means that
+     *      this call returns immediately after streaming on.
+     */
+    private void waitForFrames(int numFrameWait) throws Exception {
+        if (numFrameWait < 0) {
+            throw new IllegalArgumentException("numFrameWait " + numFrameWait +
+                    " should be non-negative");
+        }
+
+        for (int i = 0; i < numFrameWait; i++) {
+            mCameraZslImageListener.getImage(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS).close();
+        }
+    }
+
+    private void closeReaderWriters() {
+        mCameraZslImageListener.drain();
+        CameraTestUtils.closeImageReader(mCameraZslReader);
+        mCameraZslReader = null;
+        mJpegListener.drain();
+        CameraTestUtils.closeImageReader(mJpegReader);
+        mJpegReader = null;
+        CameraTestUtils.closeImageWriter(mWriter);
+        mWriter = null;
+    }
+
+    private void prepareReprocessCapture(int inputFormat)
+                    throws CameraAccessException {
+        // 1. Find the right preview and capture sizes.
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        Size[] supportedInputSizes =
+                mStaticInfo.getAvailableSizesForFormatChecked(inputFormat,
+                StaticMetadata.StreamDirection.Input);
+        Size maxInputSize = CameraTestUtils.getMaxSize(supportedInputSizes);
+        Size maxJpegSize = mOrderedStillSizes.get(0);
+        updatePreviewSurface(maxPreviewSize);
+        mZslResultListener = new SimpleCaptureCallback();
+
+        // 2. Create camera output ImageReaders.
+        // YUV/Opaque output, camera should support output with input size/format
+        mCameraZslImageListener = new SimpleImageReaderListener(
+                /*asyncMode*/true, MAX_ZSL_IMAGES / 2);
+        mCameraZslReader = CameraTestUtils.makeImageReader(
+                maxInputSize, inputFormat, MAX_ZSL_IMAGES, mCameraZslImageListener, mHandler);
+        // Jpeg reprocess output
+        mJpegListener = new SimpleImageReaderListener();
+        mJpegReader = CameraTestUtils.makeImageReader(
+                maxJpegSize, ImageFormat.JPEG, MAX_JPEG_IMAGES, mJpegListener, mHandler);
+
+        // create camera reprocess session
+        List<Surface> outSurfaces = new ArrayList<Surface>();
+        outSurfaces.add(mPreviewSurface);
+        outSurfaces.add(mCameraZslReader.getSurface());
+        outSurfaces.add(mJpegReader.getSurface());
+        InputConfiguration inputConfig = new InputConfiguration(maxInputSize.getWidth(),
+                maxInputSize.getHeight(), inputFormat);
+        mSessionListener = new BlockingSessionCallback();
+        mSession = CameraTestUtils.configureReprocessableCameraSession(
+                mCamera, inputConfig, outSurfaces, mSessionListener, mHandler);
+
+        // 3. Create ImageWriter for input
+        mWriter = CameraTestUtils.makeImageWriter(
+                mSession.getInputSurface(), MAX_INPUT_IMAGES, /*listener*/null, /*handler*/null);
+
+    }
+
+    private void blockingStopPreview() throws Exception {
+        stopPreview();
+        mSessionListener.getStateWaiter().waitForState(SESSION_CLOSED,
+                CameraTestUtils.SESSION_CLOSE_TIMEOUT_MS);
+    }
+
+    private void blockingStartPreview(CaptureCallback listener, SimpleImageListener imageListener)
+            throws Exception {
+        if (mPreviewSurface == null || mReaderSurface == null) {
+            throw new IllegalStateException("preview and reader surface must be initilized first");
+        }
+
+        CaptureRequest.Builder previewBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        if (mStaticInfo.isColorOutputSupported()) {
+            previewBuilder.addTarget(mPreviewSurface);
+        }
+        previewBuilder.addTarget(mReaderSurface);
+        mSession.setRepeatingRequest(previewBuilder.build(), listener, mHandler);
+        imageListener.waitForImageAvailable(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
+    }
+
+    /**
+     * Configure reader and preview outputs and wait until done.
+     */
+    private void configureReaderAndPreviewOutputs() throws Exception {
+        if (mPreviewSurface == null || mReaderSurface == null) {
+            throw new IllegalStateException("preview and reader surface must be initilized first");
+        }
+        mSessionListener = new BlockingSessionCallback();
+        List<Surface> outputSurfaces = new ArrayList<>();
+        if (mStaticInfo.isColorOutputSupported()) {
+            outputSurfaces.add(mPreviewSurface);
+        }
+        outputSurfaces.add(mReaderSurface);
+        mSession = CameraTestUtils.configureCameraSession(mCamera, outputSurfaces,
+                mSessionListener, mHandler);
+    }
+
+    /**
+     * Initialize the ImageReader instance and preview surface.
+     * @param cameraId The camera to be opened.
+     * @param format The format used to create ImageReader instance.
+     */
+    private void initializeImageReader(String cameraId, int format) throws Exception {
+        mOrderedPreviewSizes = CameraTestUtils.getSortedSizesForFormat(
+                cameraId, mCameraManager, format,
+                CameraTestUtils.getPreviewSizeBound(mWindowManager,
+                    CameraTestUtils.PREVIEW_SIZE_BOUND));
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        createImageReader(maxPreviewSize, format, NUM_MAX_IMAGES, /*listener*/null);
+        updatePreviewSurface(maxPreviewSize);
+    }
+
+    private void simpleOpenCamera(String cameraId) throws Exception {
+        mCamera = CameraTestUtils.openCamera(
+                mCameraManager, cameraId, mCameraListener, mHandler);
+        mCollector.setCameraId(cameraId);
+        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
+                CheckLevel.ASSERT, /*collector*/null);
+        mMinPreviewFrameDurationMap =
+                mStaticInfo.getAvailableMinFrameDurationsForFormatChecked(ImageFormat.YUV_420_888);
+    }
+
+    /**
+     * Simple image listener that can be used to time the availability of first image.
+     *
+     */
+    private static class SimpleImageListener implements ImageReader.OnImageAvailableListener {
+        private ConditionVariable imageAvailable = new ConditionVariable();
+        private boolean imageReceived = false;
+        private long mTimeReceivedImage = 0;
+
+        @Override
+        public void onImageAvailable(ImageReader reader) {
+            Image image = null;
+            if (!imageReceived) {
+                if (VERBOSE) {
+                    Log.v(TAG, "First image arrives");
+                }
+                imageReceived = true;
+                mTimeReceivedImage = SystemClock.elapsedRealtime();
+                imageAvailable.open();
+            }
+            image = reader.acquireNextImage();
+            if (image != null) {
+                image.close();
+            }
+        }
+
+        /**
+         * Wait for image available, return immediately if the image was already
+         * received, otherwise wait until an image arrives.
+         */
+        public void waitForImageAvailable(long timeout) {
+            if (imageReceived) {
+                imageReceived = false;
+                return;
+            }
+
+            if (imageAvailable.block(timeout)) {
+                imageAvailable.close();
+                imageReceived = false;
+            } else {
+                throw new TimeoutRuntimeException("Unable to get the first image after "
+                        + CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS + "ms");
+            }
+        }
+
+        public long getTimeReceivedImage() {
+            return mTimeReceivedImage;
+        }
+    }
+
+    private static class SimpleTimingResultListener
+            extends CameraCaptureSession.CaptureCallback {
+        private final LinkedBlockingQueue<Pair<CaptureResult, Long> > mPartialResultQueue =
+                new LinkedBlockingQueue<Pair<CaptureResult, Long> >();
+        private final LinkedBlockingQueue<Pair<CaptureResult, Long> > mResultQueue =
+                new LinkedBlockingQueue<Pair<CaptureResult, Long> > ();
+
+        @Override
+        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
+                TotalCaptureResult result) {
+            try {
+                Long time = SystemClock.elapsedRealtime();
+                mResultQueue.put(new Pair<CaptureResult, Long>(result, time));
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onCaptureCompleted");
+            }
+        }
+
+        @Override
+        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
+                CaptureResult partialResult) {
+            try {
+                // check if AE and AF state exists
+                Long time = -1L;
+                if (partialResult.get(CaptureResult.CONTROL_AE_STATE) != null &&
+                        partialResult.get(CaptureResult.CONTROL_AF_STATE) != null) {
+                    time = SystemClock.elapsedRealtime();
+                }
+                mPartialResultQueue.put(new Pair<CaptureResult, Long>(partialResult, time));
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException(
+                        "Can't handle InterruptedException in onCaptureProgressed");
+            }
+        }
+
+        public Pair<CaptureResult, Long> getPartialResultNTime(long timeout) {
+            try {
+                Pair<CaptureResult, Long> result =
+                        mPartialResultQueue.poll(timeout, TimeUnit.MILLISECONDS);
+                return result;
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
+            }
+        }
+
+        public Pair<CaptureResult, Long> getCaptureResultNTime(long timeout) {
+            try {
+                Pair<CaptureResult, Long> result =
+                        mResultQueue.poll(timeout, TimeUnit.MILLISECONDS);
+                assertNotNull("Wait for a capture result timed out in " + timeout + "ms", result);
+                return result;
+            } catch (InterruptedException e) {
+                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
+            }
+        }
+
+        public Pair<CaptureResult, Long> getPartialResultNTimeForRequest(CaptureRequest myRequest,
+                int numResultsWait) {
+            if (numResultsWait < 0) {
+                throw new IllegalArgumentException("numResultsWait must be no less than 0");
+            }
+
+            Pair<CaptureResult, Long> result;
+            int i = 0;
+            do {
+                result = getPartialResultNTime(CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+                // The result may be null if no partials are produced on this particular path, so
+                // stop trying
+                if (result == null) break;
+                if (result.first.getRequest().equals(myRequest)) {
+                    return result;
+                }
+            } while (i++ < numResultsWait);
+
+            // No partials produced - this may not be an error, since a given device may not
+            // produce any partials on this testing path
+            return null;
+        }
+
+        public Pair<CaptureResult, Long> getCaptureResultNTimeForRequest(CaptureRequest myRequest,
+                int numResultsWait) {
+            if (numResultsWait < 0) {
+                throw new IllegalArgumentException("numResultsWait must be no less than 0");
+            }
+
+            Pair<CaptureResult, Long> result;
+            int i = 0;
+            do {
+                result = getCaptureResultNTime(CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+                if (result.first.getRequest().equals(myRequest)) {
+                    return result;
+                }
+            } while (i++ < numResultsWait);
+
+            throw new TimeoutRuntimeException("Unable to get the expected capture result after "
+                    + "waiting for " + numResultsWait + " results");
+        }
+
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
new file mode 100644
index 0000000..feade79
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/RecordingTest.java
@@ -0,0 +1,1414 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
+
+import android.cts.util.MediaUtils;
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraConstrainedHighSpeedCaptureSession;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.util.Size;
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.media.CamcorderProfile;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.CodecProfileLevel;
+import android.media.Image;
+import android.media.ImageReader;
+import android.media.MediaCodecList;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.media.MediaRecorder;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.util.Range;
+import android.view.Surface;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+
+import junit.framework.AssertionFailedError;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.HashMap;
+
+/**
+ * CameraDevice video recording use case tests by using MediaRecorder and
+ * MediaCodec.
+ */
+@LargeTest
+public class RecordingTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "RecordingTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final boolean DEBUG_DUMP = Log.isLoggable(TAG, Log.DEBUG);
+    private static final int RECORDING_DURATION_MS = 3000;
+    private static final float DURATION_MARGIN = 0.2f;
+    private static final double FRAME_DURATION_ERROR_TOLERANCE_MS = 3.0;
+    private static final int BIT_RATE_1080P = 16000000;
+    private static final int BIT_RATE_MIN = 64000;
+    private static final int BIT_RATE_MAX = 40000000;
+    private static final int VIDEO_FRAME_RATE = 30;
+    private final String VIDEO_FILE_PATH = Environment.getExternalStorageDirectory().getPath();
+    private static final int[] mCamcorderProfileList = {
+            CamcorderProfile.QUALITY_HIGH,
+            CamcorderProfile.QUALITY_2160P,
+            CamcorderProfile.QUALITY_1080P,
+            CamcorderProfile.QUALITY_720P,
+            CamcorderProfile.QUALITY_480P,
+            CamcorderProfile.QUALITY_CIF,
+            CamcorderProfile.QUALITY_QCIF,
+            CamcorderProfile.QUALITY_QVGA,
+            CamcorderProfile.QUALITY_LOW,
+    };
+    private static final int MAX_VIDEO_SNAPSHOT_IMAGES = 5;
+    private static final int BURST_VIDEO_SNAPSHOT_NUM = 3;
+    private static final int SLOWMO_SLOW_FACTOR = 4;
+    private static final int MAX_NUM_FRAME_DROP_INTERVAL_ALLOWED = 4;
+    private List<Size> mSupportedVideoSizes;
+    private Surface mRecordingSurface;
+    private Surface mPersistentSurface;
+    private MediaRecorder mMediaRecorder;
+    private String mOutMediaFileName;
+    private int mVideoFrameRate;
+    private Size mVideoSize;
+    private long mRecordingStartTime;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    private void doBasicRecording() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                Log.i(TAG, "Testing basic recording for camera " + mCameraIds[i]);
+                // Re-use the MediaRecorder object for the same camera device.
+                mMediaRecorder = new MediaRecorder();
+                openDevice(mCameraIds[i]);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                initSupportedVideoSize(mCameraIds[i]);
+
+                basicRecordingTestByCamera(mCamcorderProfileList);
+            } finally {
+                closeDevice();
+                releaseRecorder();
+            }
+        }
+    }
+
+    /**
+     * <p>
+     * Test basic camera recording.
+     * </p>
+     * <p>
+     * This test covers the typical basic use case of camera recording.
+     * 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 testBasicRecording() throws Exception {
+        doBasicRecording();
+    }
+
+    /**
+     * <p>
+     * Test basic camera recording from a persistent input surface.
+     * </p>
+     * <p>
+     * This test is similar to testBasicRecording except that MediaRecorder records
+     * from a persistent input surface that's used across multiple recording sessions.
+     * </p>
+     */
+    public void testRecordingFromPersistentSurface() throws Exception {
+        if (!MediaUtils.checkCodecForDomain(true /* encoder */, "video")) {
+            return; // skipped
+        }
+        mPersistentSurface = MediaCodec.createPersistentInputSurface();
+        assertNotNull("Failed to create persistent input surface!", mPersistentSurface);
+
+        try {
+            doBasicRecording();
+        } finally {
+            mPersistentSurface.release();
+            mPersistentSurface = null;
+        }
+    }
+
+    /**
+     * <p>
+     * Test camera recording for all supported sizes by using MediaRecorder.
+     * </p>
+     * <p>
+     * This test covers camera recording for all supported sizes by camera. MediaRecorder
+     * is used to encode the video. Preview is set to the video size. Recorded videos are
+     * validated according to the recording configuration.
+     * </p>
+     */
+    public void testSupportedVideoSizes() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                Log.i(TAG, "Testing supported video size recording for camera " + mCameraIds[i]);
+                // Re-use the MediaRecorder object for the same camera device.
+                mMediaRecorder = new MediaRecorder();
+                openDevice(mCameraIds[i]);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                initSupportedVideoSize(mCameraIds[i]);
+
+                recordingSizeTestByCamera();
+            } finally {
+                closeDevice();
+                releaseRecorder();
+            }
+        }
+    }
+
+    /**
+     * Test different start/stop orders of Camera and Recorder.
+     *
+     * <p>The recording should be working fine for any kind of start/stop orders.</p>
+     */
+    public void testCameraRecorderOrdering() {
+        // TODO: need implement
+    }
+
+    /**
+     * <p>
+     * Test camera recording for all supported sizes by using MediaCodec.
+     * </p>
+     * <p>
+     * This test covers video only recording for all supported sizes (camera and
+     * encoder). MediaCodec is used to encode the video. The recorded videos are
+     * validated according to the recording configuration.
+     * </p>
+     */
+    public void testMediaCodecRecording() throws Exception {
+        // TODO. Need implement.
+    }
+
+    /**
+     * <p>
+     * Test video snapshot for each camera.
+     * </p>
+     * <p>
+     * This test covers video snapshot typical use case. The MediaRecorder is used to record the
+     * video for each available video size. The largest still capture size is selected to
+     * capture the JPEG image. The still capture images are validated according to the capture
+     * configuration. The timestamp of capture result before and after video snapshot is also
+     * checked to make sure no frame drop caused by video snapshot.
+     * </p>
+     */
+    public void testVideoSnapshot() throws Exception {
+        videoSnapshotHelper(/*burstTest*/false);
+    }
+
+    /**
+     * <p>
+     * Test burst video snapshot for each camera.
+     * </p>
+     * <p>
+     * This test covers burst video snapshot capture. The MediaRecorder is used to record the
+     * video for each available video size. The largest still capture size is selected to
+     * capture the JPEG image. {@value #BURST_VIDEO_SNAPSHOT_NUM} video snapshot requests will be
+     * sent during the test. The still capture images are validated according to the capture
+     * configuration.
+     * </p>
+     */
+    public void testBurstVideoSnapshot() throws Exception {
+        videoSnapshotHelper(/*burstTest*/true);
+    }
+
+    /**
+     * Test timelapse recording, where capture rate is slower than video (playback) frame rate.
+     */
+    public void testTimelapseRecording() throws Exception {
+        // TODO. Need implement.
+    }
+
+    public void testSlowMotionRecording() throws Exception {
+        slowMotionRecording();
+    }
+
+    public void testConstrainedHighSpeedRecording() throws Exception {
+        constrainedHighSpeedRecording();
+    }
+
+    /**
+     * <p>
+     * Test recording framerate accuracy when switching from low FPS to high FPS.
+     * </p>
+     * <p>
+     * This test first record a video with profile of lowest framerate then record a video with
+     * profile of highest framerate. Make sure that the video framerate are still accurate.
+     * </p>
+     */
+    public void testRecordingFramerateLowToHigh() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                Log.i(TAG, "Testing basic recording for camera " + mCameraIds[i]);
+                // Re-use the MediaRecorder object for the same camera device.
+                mMediaRecorder = new MediaRecorder();
+                openDevice(mCameraIds[i]);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                initSupportedVideoSize(mCameraIds[i]);
+
+                int minFpsProfileId = -1, minFps = 1000;
+                int maxFpsProfileId = -1, maxFps = 0;
+                int cameraId = Integer.valueOf(mCamera.getId());
+
+                for (int profileId : mCamcorderProfileList) {
+                    if (!CamcorderProfile.hasProfile(cameraId, profileId)) {
+                        continue;
+                    }
+                    CamcorderProfile profile = CamcorderProfile.get(cameraId, profileId);
+                    if (profile.videoFrameRate < minFps) {
+                        minFpsProfileId = profileId;
+                        minFps = profile.videoFrameRate;
+                    }
+                    if (profile.videoFrameRate > maxFps) {
+                        maxFpsProfileId = profileId;
+                        maxFps = profile.videoFrameRate;
+                    }
+                }
+
+                int camcorderProfileList[] = new int[] {minFpsProfileId, maxFpsProfileId};
+                basicRecordingTestByCamera(camcorderProfileList);
+            } finally {
+                closeDevice();
+                releaseRecorder();
+            }
+        }
+    }
+
+    /**
+     * Test slow motion recording where capture rate (camera output) is different with
+     * video (playback) frame rate for each camera if high speed recording is supported
+     * by both camera and encoder.
+     *
+     * <p>
+     * Normal recording use cases make the capture rate (camera output frame
+     * rate) the same as the video (playback) frame rate. This guarantees that
+     * the motions in the scene play at the normal speed. If the capture rate is
+     * faster than video frame rate, for a given time duration, more number of
+     * frames are captured than it can be played in the same time duration. This
+     * generates "slow motion" effect during playback.
+     * </p>
+     */
+    private void slowMotionRecording() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing slow motion recording for camera " + id);
+                // Re-use the MediaRecorder object for the same camera device.
+                mMediaRecorder = new MediaRecorder();
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                if (!mStaticInfo.isHighSpeedVideoSupported()) {
+                    continue;
+                }
+
+                StreamConfigurationMap config =
+                        mStaticInfo.getValueFromKeyNonNull(
+                                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+                Size[] highSpeedVideoSizes = config.getHighSpeedVideoSizes();
+                for (Size size : highSpeedVideoSizes) {
+                    Range<Integer> fpsRange = getHighestHighSpeedFixedFpsRangeForSize(config, size);
+                    mCollector.expectNotNull("Unable to find the fixed frame rate fps range for " +
+                            "size " + size, fpsRange);
+                    if (fpsRange == null) {
+                        continue;
+                    }
+
+                    int captureRate = fpsRange.getLower();
+                    int videoFramerate = captureRate / SLOWMO_SLOW_FACTOR;
+                    // Skip the test if the highest recording FPS supported by CamcorderProfile
+                    if (fpsRange.getUpper() > getFpsFromHighSpeedProfileForSize(size)) {
+                        Log.w(TAG, "high speed recording " + size + "@" + captureRate + "fps"
+                                + " is not supported by CamcorderProfile");
+                        continue;
+                    }
+
+                    mOutMediaFileName = VIDEO_FILE_PATH + "/test_slowMo_video.mp4";
+                    if (DEBUG_DUMP) {
+                        mOutMediaFileName = VIDEO_FILE_PATH + "/test_slowMo_video_" + id + "_"
+                                + size.toString() + ".mp4";
+                    }
+
+                    prepareRecording(size, videoFramerate, captureRate);
+
+                    // prepare preview surface by using video size.
+                    updatePreviewSurfaceWithVideo(size, captureRate);
+
+                    // Start recording
+                    SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+                    startSlowMotionRecording(/*useMediaRecorder*/true, videoFramerate, captureRate,
+                            fpsRange, resultListener, /*useHighSpeedSession*/false);
+
+                    // Record certain duration.
+                    SystemClock.sleep(RECORDING_DURATION_MS);
+
+                    // Stop recording and preview
+                    stopRecording(/*useMediaRecorder*/true);
+                    // Convert number of frames camera produced into the duration in unit of ms.
+                    int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
+                                    videoFramerate);
+
+                    // Validation.
+                    validateRecording(size, durationMs);
+                }
+
+            } finally {
+                closeDevice();
+                releaseRecorder();
+            }
+        }
+    }
+
+    private void constrainedHighSpeedRecording() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing constrained high speed recording for camera " + id);
+                // Re-use the MediaRecorder object for the same camera device.
+                mMediaRecorder = new MediaRecorder();
+                openDevice(id);
+
+                if (!mStaticInfo.isConstrainedHighSpeedVideoSupported()) {
+                    continue;
+                }
+
+                StreamConfigurationMap config =
+                        mStaticInfo.getValueFromKeyNonNull(
+                                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+                Size[] highSpeedVideoSizes = config.getHighSpeedVideoSizes();
+                for (Size size : highSpeedVideoSizes) {
+                    List<Range<Integer>> fixedFpsRanges =
+                            getHighSpeedFixedFpsRangeForSize(config, size);
+                    mCollector.expectTrue("Unable to find the fixed frame rate fps range for " +
+                            "size " + size, fixedFpsRanges.size() > 0);
+                    // Test recording for each FPS range
+                    for (Range<Integer> fpsRange : fixedFpsRanges) {
+                        int captureRate = fpsRange.getLower();
+                        final int VIDEO_FRAME_RATE = 30;
+                        // Skip the test if the highest recording FPS supported by CamcorderProfile
+                        if (fpsRange.getUpper() > getFpsFromHighSpeedProfileForSize(size)) {
+                            Log.w(TAG, "high speed recording " + size + "@" + captureRate + "fps"
+                                    + " is not supported by CamcorderProfile");
+                            continue;
+                        }
+
+                        mOutMediaFileName = VIDEO_FILE_PATH + "/test_cslowMo_video_" + captureRate +
+                                "fps_" + id + "_" + size.toString() + ".mp4";
+
+                        prepareRecording(size, VIDEO_FRAME_RATE, captureRate);
+
+                        // prepare preview surface by using video size.
+                        updatePreviewSurfaceWithVideo(size, captureRate);
+
+                        // Start recording
+                        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+                        startSlowMotionRecording(/*useMediaRecorder*/true, VIDEO_FRAME_RATE,
+                                captureRate, fpsRange, resultListener,
+                                /*useHighSpeedSession*/true);
+
+                        // Record certain duration.
+                        SystemClock.sleep(RECORDING_DURATION_MS);
+
+                        // Stop recording and preview
+                        stopRecording(/*useMediaRecorder*/true);
+                        // Convert number of frames camera produced into the duration in unit of ms.
+                        int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
+                                        VIDEO_FRAME_RATE);
+
+                        // Validation.
+                        validateRecording(size, durationMs);
+                    }
+                }
+
+            } finally {
+                closeDevice();
+                releaseRecorder();
+            }
+        }
+    }
+
+    /**
+     * Get high speed FPS from CamcorderProfiles for a given size.
+     *
+     * @param size The size used to search the CamcorderProfiles for the FPS.
+     * @return high speed video FPS, 0 if the given size is not supported by the CamcorderProfiles.
+     */
+    private int getFpsFromHighSpeedProfileForSize(Size size) {
+        for (int quality = CamcorderProfile.QUALITY_HIGH_SPEED_480P;
+                quality <= CamcorderProfile.QUALITY_HIGH_SPEED_2160P; quality++) {
+            if (CamcorderProfile.hasProfile(quality)) {
+                CamcorderProfile profile = CamcorderProfile.get(quality);
+                if (size.equals(new Size(profile.videoFrameWidth, profile.videoFrameHeight))){
+                    return profile.videoFrameRate;
+                }
+            }
+        }
+
+        return 0;
+    }
+
+    private Range<Integer> getHighestHighSpeedFixedFpsRangeForSize(StreamConfigurationMap config,
+            Size size) {
+        Range<Integer>[] availableFpsRanges = config.getHighSpeedVideoFpsRangesFor(size);
+        Range<Integer> maxRange = availableFpsRanges[0];
+        boolean foundRange = false;
+        for (Range<Integer> range : availableFpsRanges) {
+            if (range.getLower().equals(range.getUpper()) && range.getLower() >= maxRange.getLower()) {
+                foundRange = true;
+                maxRange = range;
+            }
+        }
+
+        if (!foundRange) {
+            return null;
+        }
+        return maxRange;
+    }
+
+    private List<Range<Integer>> getHighSpeedFixedFpsRangeForSize(StreamConfigurationMap config,
+            Size size) {
+        Range<Integer>[] availableFpsRanges = config.getHighSpeedVideoFpsRangesFor(size);
+        List<Range<Integer>> fixedRanges = new ArrayList<Range<Integer>>();
+        for (Range<Integer> range : availableFpsRanges) {
+            if (range.getLower().equals(range.getUpper())) {
+                fixedRanges.add(range);
+            }
+        }
+        return fixedRanges;
+    }
+
+    private void startSlowMotionRecording(boolean useMediaRecorder, int videoFrameRate,
+            int captureRate, Range<Integer> fpsRange,
+            CameraCaptureSession.CaptureCallback listener, boolean useHighSpeedSession) throws Exception {
+        List<Surface> outputSurfaces = new ArrayList<Surface>(2);
+        assertTrue("Both preview and recording surfaces should be valid",
+                mPreviewSurface.isValid() && mRecordingSurface.isValid());
+        outputSurfaces.add(mPreviewSurface);
+        outputSurfaces.add(mRecordingSurface);
+        // Video snapshot surface
+        if (mReaderSurface != null) {
+            outputSurfaces.add(mReaderSurface);
+        }
+        mSessionListener = new BlockingSessionCallback();
+        mSession = configureCameraSession(mCamera, outputSurfaces, useHighSpeedSession,
+                mSessionListener, mHandler);
+
+        // Create slow motion request list
+        List<CaptureRequest> slowMoRequests = null;
+        if (useHighSpeedSession) {
+            CaptureRequest.Builder requestBuilder =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
+            requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
+            requestBuilder.addTarget(mPreviewSurface);
+            requestBuilder.addTarget(mRecordingSurface);
+            slowMoRequests = ((CameraConstrainedHighSpeedCaptureSession) mSession).
+                    createHighSpeedRequestList(requestBuilder.build());
+        } else {
+            CaptureRequest.Builder recordingRequestBuilder =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
+            recordingRequestBuilder.set(CaptureRequest.CONTROL_MODE,
+                    CaptureRequest.CONTROL_MODE_USE_SCENE_MODE);
+            recordingRequestBuilder.set(CaptureRequest.CONTROL_SCENE_MODE,
+                    CaptureRequest.CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO);
+
+            CaptureRequest.Builder recordingOnlyBuilder =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
+            recordingOnlyBuilder.set(CaptureRequest.CONTROL_MODE,
+                    CaptureRequest.CONTROL_MODE_USE_SCENE_MODE);
+            recordingOnlyBuilder.set(CaptureRequest.CONTROL_SCENE_MODE,
+                    CaptureRequest.CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO);
+            int slowMotionFactor = captureRate / videoFrameRate;
+
+            // Make sure camera output frame rate is set to correct value.
+            recordingRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
+            recordingRequestBuilder.addTarget(mRecordingSurface);
+            recordingRequestBuilder.addTarget(mPreviewSurface);
+            recordingOnlyBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
+            recordingOnlyBuilder.addTarget(mRecordingSurface);
+
+            slowMoRequests = new ArrayList<CaptureRequest>();
+            slowMoRequests.add(recordingRequestBuilder.build());// Preview + recording.
+
+            for (int i = 0; i < slowMotionFactor - 1; i++) {
+                slowMoRequests.add(recordingOnlyBuilder.build()); // Recording only.
+            }
+        }
+
+        mSession.setRepeatingBurst(slowMoRequests, listener, mHandler);
+
+        if (useMediaRecorder) {
+            mMediaRecorder.start();
+        } else {
+            // TODO: need implement MediaCodec path.
+        }
+
+    }
+
+    /**
+     * 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 {
+        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)) {
+                continue;
+            }
+
+            CamcorderProfile profile = CamcorderProfile.get(cameraId, profileId);
+            Size videoSz = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
+            Range<Integer> fpsRange = new Range(profile.videoFrameRate, profile.videoFrameRate);
+            if (maxVideoFrameRate < profile.videoFrameRate) {
+                maxVideoFrameRate = profile.videoFrameRate;
+            }
+            if (mStaticInfo.isHardwareLevelLegacy() &&
+                    (videoSz.getWidth() > maxPreviewSize.getWidth() ||
+                     videoSz.getHeight() > maxPreviewSize.getHeight())) {
+                // Skip. Legacy mode can only do recording up to max preview size
+                continue;
+            }
+            assertTrue("Video size " + videoSz.toString() + " for profile ID " + profileId +
+                            " must be one of the camera device supported video size!",
+                            mSupportedVideoSizes.contains(videoSz));
+            assertTrue("Frame rate range " + fpsRange + " (for profile ID " + profileId +
+                    ") must be one of the camera device available FPS range!",
+                    fpsRanges.contains(fpsRange));
+
+            if (VERBOSE) {
+                Log.v(TAG, "Testing camera recording with video size " + videoSz.toString());
+            }
+
+            // Configure preview and recording surfaces.
+            mOutMediaFileName = VIDEO_FILE_PATH + "/test_video.mp4";
+            if (DEBUG_DUMP) {
+                mOutMediaFileName = VIDEO_FILE_PATH + "/test_video_" + cameraId + "_"
+                        + videoSz.toString() + ".mp4";
+            }
+
+            prepareRecordingWithProfile(profile);
+
+            // prepare preview surface by using video size.
+            updatePreviewSurfaceWithVideo(videoSz, profile.videoFrameRate);
+
+            // Start recording
+            SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+            startRecording(/* useMediaRecorder */true, resultListener);
+
+            // Record certain duration.
+            SystemClock.sleep(RECORDING_DURATION_MS);
+
+            // Stop recording and preview
+            stopRecording(/* useMediaRecorder */true);
+            // Convert number of frames camera produced into the duration in unit of ms.
+            int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
+                            profile.videoFrameRate);
+
+            if (VERBOSE) {
+                Log.v(TAG, "video frame rate: " + profile.videoFrameRate +
+                                ", num of frames produced: " + resultListener.getTotalNumFrames());
+            }
+
+            // Validation.
+            validateRecording(videoSz, durationMs);
+        }
+        if (maxVideoFrameRate != -1) {
+            // At least one CamcorderProfile is present, check FPS
+            assertTrue("At least one CamcorderProfile must support >= 24 FPS",
+                    maxVideoFrameRate >= 24);
+        }
+    }
+
+    /**
+     * Test camera recording for each supported video size by camera, preview
+     * size is set to the video size.
+     */
+    private void recordingSizeTestByCamera() throws Exception {
+        for (Size sz : mSupportedVideoSizes) {
+            if (!isSupported(sz, VIDEO_FRAME_RATE, VIDEO_FRAME_RATE)) {
+                continue;
+            }
+
+            if (VERBOSE) {
+                Log.v(TAG, "Testing camera recording with video size " + sz.toString());
+            }
+
+            // Configure preview and recording surfaces.
+            mOutMediaFileName = VIDEO_FILE_PATH + "/test_video.mp4";
+            if (DEBUG_DUMP) {
+                mOutMediaFileName = VIDEO_FILE_PATH + "/test_video_" + mCamera.getId() + "_"
+                        + sz.toString() + ".mp4";
+            }
+
+            // Use AVC and AAC a/v compression format.
+            prepareRecording(sz, VIDEO_FRAME_RATE, VIDEO_FRAME_RATE);
+
+            // prepare preview surface by using video size.
+            updatePreviewSurfaceWithVideo(sz, VIDEO_FRAME_RATE);
+
+            // Start recording
+            SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+            startRecording(/* useMediaRecorder */true, resultListener);
+
+            // Record certain duration.
+            SystemClock.sleep(RECORDING_DURATION_MS);
+
+            // Stop recording and preview
+            stopRecording(/* useMediaRecorder */true);
+            // Convert number of frames camera produced into the duration in unit of ms.
+            int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
+                            VIDEO_FRAME_RATE);
+
+            // Validation.
+            validateRecording(sz, durationMs);
+        }
+    }
+
+    /**
+     * Initialize the supported video sizes.
+     */
+    private void initSupportedVideoSize(String cameraId)  throws Exception {
+        Size maxVideoSize = SIZE_BOUND_1080P;
+        if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P)) {
+            maxVideoSize = SIZE_BOUND_2160P;
+        }
+        mSupportedVideoSizes =
+                getSupportedVideoSizes(cameraId, mCameraManager, maxVideoSize);
+    }
+
+    /**
+     * Simple wrapper to wrap normal/burst video snapshot tests
+     */
+    private void videoSnapshotHelper(boolean burstTest) throws Exception {
+            for (String id : mCameraIds) {
+                try {
+                    Log.i(TAG, "Testing video snapshot for camera " + id);
+                    // Re-use the MediaRecorder object for the same camera device.
+                    mMediaRecorder = new MediaRecorder();
+
+                    openDevice(id);
+
+                    if (!mStaticInfo.isColorOutputSupported()) {
+                        Log.i(TAG, "Camera " + id +
+                                " does not support color outputs, skipping");
+                        continue;
+                    }
+
+                    initSupportedVideoSize(id);
+
+                    videoSnapshotTestByCamera(burstTest);
+                } finally {
+                    closeDevice();
+                    releaseRecorder();
+                }
+            }
+    }
+
+    /**
+     * Returns {@code true} if the {@link CamcorderProfile} ID is allowed to be unsupported.
+     *
+     * <p>This only allows unsupported profiles when using the LEGACY mode of the Camera API.</p>
+     *
+     * @param profileId a {@link CamcorderProfile} ID to check.
+     * @return {@code true} if supported.
+     */
+    private boolean allowedUnsupported(int cameraId, int profileId) {
+        if (!mStaticInfo.isHardwareLevelLegacy()) {
+            return false;
+        }
+
+        switch(profileId) {
+            case CamcorderProfile.QUALITY_2160P:
+            case CamcorderProfile.QUALITY_1080P:
+            case CamcorderProfile.QUALITY_HIGH:
+                return !CamcorderProfile.hasProfile(cameraId, profileId) ||
+                        CamcorderProfile.get(cameraId, profileId).videoFrameWidth >= 1080;
+        }
+        return false;
+    }
+
+    /**
+     * Test video snapshot for each  available CamcorderProfile for a given camera.
+     *
+     * <p>
+     * Preview size is set to the video size. For the burst test, frame drop and jittering
+     * is not checked.
+     * </p>
+     *
+     * @param burstTest Perform burst capture or single capture. For burst capture
+     *                  {@value #BURST_VIDEO_SNAPSHOT_NUM} capture requests will be sent.
+     */
+    private void videoSnapshotTestByCamera(boolean burstTest)
+            throws Exception {
+        final int NUM_SINGLE_SHOT_TEST = 5;
+        final int FRAMEDROP_TOLERANCE = 8;
+        final int FRAME_SIZE_15M = 15000000;
+        final float FRAME_DROP_TOLERENCE_FACTOR = 1.5f;
+        int kFrameDrop_Tolerence = FRAMEDROP_TOLERANCE;
+
+        for (int profileId : mCamcorderProfileList) {
+            int cameraId = Integer.valueOf(mCamera.getId());
+            if (!CamcorderProfile.hasProfile(cameraId, profileId) ||
+                    allowedUnsupported(cameraId, profileId)) {
+                continue;
+            }
+
+            CamcorderProfile profile = CamcorderProfile.get(cameraId, profileId);
+            Size videoSz = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
+            Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+
+            if (mStaticInfo.isHardwareLevelLegacy() &&
+                    (videoSz.getWidth() > maxPreviewSize.getWidth() ||
+                     videoSz.getHeight() > maxPreviewSize.getHeight())) {
+                // Skip. Legacy mode can only do recording up to max preview size
+                continue;
+            }
+
+            if (!mSupportedVideoSizes.contains(videoSz)) {
+                mCollector.addMessage("Video size " + videoSz.toString() + " for profile ID " +
+                        profileId + " must be one of the camera device supported video size!");
+                continue;
+            }
+
+            // For LEGACY, find closest supported smaller or equal JPEG size to the current video
+            // size; if no size is smaller than the video, pick the smallest JPEG size.  The assert
+            // for video size above guarantees that for LIMITED or FULL, we select videoSz here.
+            // Also check for minFrameDuration here to make sure jpeg stream won't slow down
+            // video capture
+            Size videoSnapshotSz = mOrderedStillSizes.get(mOrderedStillSizes.size() - 1);
+            // Allow a bit tolerance so we don't fail for a few nano seconds of difference
+            final float FRAME_DURATION_TOLERANCE = 0.01f;
+            long videoFrameDuration = (long) (1e9 / profile.videoFrameRate *
+                    (1.0 + FRAME_DURATION_TOLERANCE));
+            HashMap<Size, Long> minFrameDurationMap = mStaticInfo.
+                    getAvailableMinFrameDurationsForFormatChecked(ImageFormat.JPEG);
+            for (int i = mOrderedStillSizes.size() - 2; i >= 0; i--) {
+                Size candidateSize = mOrderedStillSizes.get(i);
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    // Legacy level doesn't report min frame duration
+                    if (candidateSize.getWidth() <= videoSz.getWidth() &&
+                            candidateSize.getHeight() <= videoSz.getHeight()) {
+                        videoSnapshotSz = candidateSize;
+                    }
+                } else {
+                    Long jpegFrameDuration = minFrameDurationMap.get(candidateSize);
+                    assertTrue("Cannot find minimum frame duration for jpeg size " + candidateSize,
+                            jpegFrameDuration != null);
+                    if (candidateSize.getWidth() <= videoSz.getWidth() &&
+                            candidateSize.getHeight() <= videoSz.getHeight() &&
+                            jpegFrameDuration <= videoFrameDuration) {
+                        videoSnapshotSz = candidateSize;
+                    }
+                }
+            }
+
+            /**
+             * Only test full res snapshot when below conditions are all true.
+             * 1. Camera is a FULL 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() &&
+                    videoSz.getWidth() <= maxPreviewSize.getWidth() &&
+                    videoSz.getHeight() <= maxPreviewSize.getHeight()) {
+                for (Size jpegSize : mOrderedStillSizes) {
+                    Long jpegFrameDuration = minFrameDurationMap.get(jpegSize);
+                    assertTrue("Cannot find minimum frame duration for jpeg size " + jpegSize,
+                            jpegFrameDuration != null);
+                    if (jpegFrameDuration <= videoFrameDuration) {
+                        videoSnapshotSz = jpegSize;
+                        break;
+                    }
+                    if (jpegSize.equals(videoSz)) {
+                        throw new AssertionFailedError(
+                                "Cannot find adequate video snapshot size for video size" +
+                                        videoSz);
+                    }
+                }
+            }
+
+            Log.i(TAG, "Testing video snapshot size " + videoSnapshotSz +
+                    " for video size " + videoSz);
+            if (videoSnapshotSz.getWidth() * videoSnapshotSz.getHeight() > FRAME_SIZE_15M)
+                kFrameDrop_Tolerence = (int)(FRAMEDROP_TOLERANCE * FRAME_DROP_TOLERENCE_FACTOR);
+
+            createImageReader(
+                    videoSnapshotSz, ImageFormat.JPEG,
+                    MAX_VIDEO_SNAPSHOT_IMAGES, /*listener*/null);
+
+            if (VERBOSE) {
+                Log.v(TAG, "Testing camera recording with video size " + videoSz.toString());
+            }
+
+            // Configure preview and recording surfaces.
+            mOutMediaFileName = VIDEO_FILE_PATH + "/test_video.mp4";
+            if (DEBUG_DUMP) {
+                mOutMediaFileName = VIDEO_FILE_PATH + "/test_video_" + cameraId + "_"
+                        + videoSz.toString() + ".mp4";
+            }
+
+            int numTestIterations = burstTest ? 1 : NUM_SINGLE_SHOT_TEST;
+            int totalDroppedFrames = 0;
+
+            for (int numTested = 0; numTested < numTestIterations; numTested++) {
+                prepareRecordingWithProfile(profile);
+
+                // prepare video snapshot
+                SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+                SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+                CaptureRequest.Builder videoSnapshotRequestBuilder =
+                        mCamera.createCaptureRequest((mStaticInfo.isHardwareLevelLegacy()) ?
+                                CameraDevice.TEMPLATE_RECORD :
+                                CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
+
+                // prepare preview surface by using video size.
+                updatePreviewSurfaceWithVideo(videoSz, profile.videoFrameRate);
+
+                prepareVideoSnapshot(videoSnapshotRequestBuilder, imageListener);
+                CaptureRequest request = videoSnapshotRequestBuilder.build();
+
+                // Start recording
+                startRecording(/* useMediaRecorder */true, resultListener);
+                long startTime = SystemClock.elapsedRealtime();
+
+                // Record certain duration.
+                SystemClock.sleep(RECORDING_DURATION_MS / 2);
+
+                // take video snapshot
+                if (burstTest) {
+                    List<CaptureRequest> requests =
+                            new ArrayList<CaptureRequest>(BURST_VIDEO_SNAPSHOT_NUM);
+                    for (int i = 0; i < BURST_VIDEO_SNAPSHOT_NUM; i++) {
+                        requests.add(request);
+                    }
+                    mSession.captureBurst(requests, resultListener, mHandler);
+                } else {
+                    mSession.capture(request, resultListener, mHandler);
+                }
+
+                // make sure recording is still going after video snapshot
+                SystemClock.sleep(RECORDING_DURATION_MS / 2);
+
+                // Stop recording and preview
+                int durationMs = stopRecording(/* useMediaRecorder */true);
+                // For non-burst test, use number of frames to also double check video frame rate.
+                // Burst video snapshot is allowed to cause frame rate drop, so do not use number
+                // of frames to estimate duration
+                if (!burstTest) {
+                    durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
+                        profile.videoFrameRate);
+                }
+
+                // Validation recorded video
+                validateRecording(videoSz, durationMs);
+
+                if (burstTest) {
+                    for (int i = 0; i < BURST_VIDEO_SNAPSHOT_NUM; i++) {
+                        Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+                        validateVideoSnapshotCapture(image, videoSnapshotSz);
+                        image.close();
+                    }
+                } else {
+                    // validate video snapshot image
+                    Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+                    validateVideoSnapshotCapture(image, videoSnapshotSz);
+
+                    // validate if there is framedrop around video snapshot
+                    totalDroppedFrames +=  validateFrameDropAroundVideoSnapshot(
+                            resultListener, image.getTimestamp());
+
+                    //TODO: validate jittering. Should move to PTS
+                    //validateJittering(resultListener);
+
+                    image.close();
+                }
+            }
+
+            if (!burstTest) {
+                Log.w(TAG, String.format("Camera %d Video size %s: Number of dropped frames " +
+                        "detected in %d trials is %d frames.", cameraId, videoSz.toString(),
+                        numTestIterations, totalDroppedFrames));
+                mCollector.expectLessOrEqual(
+                        String.format(
+                                "Camera %d Video size %s: Number of dropped frames %d must not"
+                                + " be larger than %d",
+                                cameraId, videoSz.toString(), totalDroppedFrames,
+                                kFrameDrop_Tolerence),
+                        kFrameDrop_Tolerence, totalDroppedFrames);
+            }
+            closeImageReader();
+        }
+    }
+
+    /**
+     * Configure video snapshot request according to the still capture size
+     */
+    private void prepareVideoSnapshot(
+            CaptureRequest.Builder requestBuilder,
+            ImageReader.OnImageAvailableListener imageListener)
+            throws Exception {
+        mReader.setOnImageAvailableListener(imageListener, mHandler);
+        assertNotNull("Recording surface must be non-null!", mRecordingSurface);
+        requestBuilder.addTarget(mRecordingSurface);
+        assertNotNull("Preview surface must be non-null!", mPreviewSurface);
+        requestBuilder.addTarget(mPreviewSurface);
+        assertNotNull("Reader surface must be non-null!", mReaderSurface);
+        requestBuilder.addTarget(mReaderSurface);
+    }
+
+    /**
+     * Update preview size with video size.
+     *
+     * <p>Preview size will be capped with max preview size.</p>
+     *
+     * @param videoSize The video size used for preview.
+     * @param videoFrameRate The video frame rate
+     *
+     */
+    private void updatePreviewSurfaceWithVideo(Size videoSize, int videoFrameRate) {
+        if (mOrderedPreviewSizes == null) {
+            throw new IllegalStateException("supported preview size list is not initialized yet");
+        }
+        final float FRAME_DURATION_TOLERANCE = 0.01f;
+        long videoFrameDuration = (long) (1e9 / videoFrameRate *
+                (1.0 + FRAME_DURATION_TOLERANCE));
+        HashMap<Size, Long> minFrameDurationMap = mStaticInfo.
+                getAvailableMinFrameDurationsForFormatChecked(ImageFormat.PRIVATE);
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        Size previewSize = null;
+        if (videoSize.getWidth() > maxPreviewSize.getWidth() ||
+                videoSize.getHeight() > maxPreviewSize.getHeight()) {
+            for (Size s : mOrderedPreviewSizes) {
+                Long frameDuration = minFrameDurationMap.get(s);
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    // Legacy doesn't report min frame duration
+                    frameDuration = new Long(0);
+                }
+                assertTrue("Cannot find minimum frame duration for private size" + s,
+                        frameDuration != null);
+                if (frameDuration <= videoFrameDuration &&
+                        s.getWidth() <= videoSize.getWidth() &&
+                        s.getHeight() <= videoSize.getHeight()) {
+                    Log.w(TAG, "Overwrite preview size from " + videoSize.toString() +
+                            " to " + s.toString());
+                    previewSize = s;
+                    break;
+                    // If all preview size doesn't work then we fallback to video size
+                }
+            }
+        }
+        if (previewSize == null) {
+            previewSize = videoSize;
+        }
+        updatePreviewSurface(previewSize);
+    }
+
+    /**
+     * Configure MediaRecorder recording session with CamcorderProfile, prepare
+     * the recording surface.
+     */
+    private void prepareRecordingWithProfile(CamcorderProfile profile)
+            throws Exception {
+        // Prepare MediaRecorder.
+        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
+        mMediaRecorder.setProfile(profile);
+        mMediaRecorder.setOutputFile(mOutMediaFileName);
+        if (mPersistentSurface != null) {
+            mMediaRecorder.setInputSurface(mPersistentSurface);
+            mRecordingSurface = mPersistentSurface;
+        }
+        mMediaRecorder.prepare();
+        if (mPersistentSurface == null) {
+            mRecordingSurface = mMediaRecorder.getSurface();
+        }
+        assertNotNull("Recording surface must be non-null!", mRecordingSurface);
+        mVideoFrameRate = profile.videoFrameRate;
+        mVideoSize = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
+    }
+
+    /**
+     * Configure MediaRecorder recording session with CamcorderProfile, prepare
+     * the recording surface. Use AVC for video compression, AAC for audio compression.
+     * Both are required for android devices by android CDD.
+     */
+    private void prepareRecording(Size sz, int videoFrameRate, int captureRate)
+            throws Exception {
+        // Prepare MediaRecorder.
+        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
+        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+        mMediaRecorder.setOutputFile(mOutMediaFileName);
+        mMediaRecorder.setVideoEncodingBitRate(getVideoBitRate(sz));
+        mMediaRecorder.setVideoFrameRate(videoFrameRate);
+        mMediaRecorder.setCaptureRate(captureRate);
+        mMediaRecorder.setVideoSize(sz.getWidth(), sz.getHeight());
+        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
+        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
+        if (mPersistentSurface != null) {
+            mMediaRecorder.setInputSurface(mPersistentSurface);
+            mRecordingSurface = mPersistentSurface;
+        }
+        mMediaRecorder.prepare();
+        if (mPersistentSurface == null) {
+            mRecordingSurface = mMediaRecorder.getSurface();
+        }
+        assertNotNull("Recording surface must be non-null!", mRecordingSurface);
+        mVideoFrameRate = videoFrameRate;
+        mVideoSize = sz;
+    }
+
+    private void startRecording(boolean useMediaRecorder,
+            CameraCaptureSession.CaptureCallback listener) throws Exception {
+        List<Surface> outputSurfaces = new ArrayList<Surface>(2);
+        assertTrue("Both preview and recording surfaces should be valid",
+                mPreviewSurface.isValid() && mRecordingSurface.isValid());
+        outputSurfaces.add(mPreviewSurface);
+        outputSurfaces.add(mRecordingSurface);
+        // Video snapshot surface
+        if (mReaderSurface != null) {
+            outputSurfaces.add(mReaderSurface);
+        }
+        mSessionListener = new BlockingSessionCallback();
+        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
+
+        CaptureRequest.Builder recordingRequestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
+        // 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);
+        recordingRequestBuilder.addTarget(mRecordingSurface);
+        recordingRequestBuilder.addTarget(mPreviewSurface);
+        mSession.setRepeatingRequest(recordingRequestBuilder.build(), listener, mHandler);
+
+        if (useMediaRecorder) {
+            mMediaRecorder.start();
+        } else {
+            // TODO: need implement MediaCodec path.
+        }
+        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");
+        }
+        // Stop repeating, wait for captures to complete, and disconnect from
+        // surfaces
+        mSession.close();
+        mSessionListener.getStateWaiter().waitForState(SESSION_CLOSED, SESSION_CLOSE_TIMEOUT_MS);
+    }
+
+    // Stop recording and return the estimated video duration in milliseconds.
+    private int stopRecording(boolean useMediaRecorder) throws Exception {
+        long stopRecordingTime = SystemClock.elapsedRealtime();
+        if (useMediaRecorder) {
+            stopCameraStreaming();
+
+            mMediaRecorder.stop();
+            // Can reuse the MediaRecorder object after reset.
+            mMediaRecorder.reset();
+        } else {
+            // TODO: need implement MediaCodec path.
+        }
+        if (mPersistentSurface == null && mRecordingSurface != null) {
+            mRecordingSurface.release();
+            mRecordingSurface = null;
+        }
+        return (int) (stopRecordingTime - mRecordingStartTime);
+    }
+
+    private void releaseRecorder() {
+        if (mMediaRecorder != null) {
+            mMediaRecorder.release();
+            mMediaRecorder = null;
+        }
+    }
+
+    private void validateRecording(Size sz, int expectedDurationMs) throws Exception {
+        File outFile = new File(mOutMediaFileName);
+        assertTrue("No video is recorded", outFile.exists());
+
+        MediaExtractor extractor = new MediaExtractor();
+        try {
+            extractor.setDataSource(mOutMediaFileName);
+            long durationUs = 0;
+            int width = -1, height = -1;
+            int numTracks = extractor.getTrackCount();
+            final String VIDEO_MIME_TYPE = "video";
+            for (int i = 0; i < numTracks; i++) {
+                MediaFormat format = extractor.getTrackFormat(i);
+                String mime = format.getString(MediaFormat.KEY_MIME);
+                if (mime.contains(VIDEO_MIME_TYPE)) {
+                    Log.i(TAG, "video format is: " + format.toString());
+                    durationUs = format.getLong(MediaFormat.KEY_DURATION);
+                    width = format.getInteger(MediaFormat.KEY_WIDTH);
+                    height = format.getInteger(MediaFormat.KEY_HEIGHT);
+                    break;
+                }
+            }
+            Size videoSz = new Size(width, height);
+            assertTrue("Video size doesn't match, expected " + sz.toString() +
+                    " got " + videoSz.toString(), videoSz.equals(sz));
+            int duration = (int) (durationUs / 1000);
+            if (VERBOSE) {
+                Log.v(TAG, String.format("Video duration: recorded %dms, expected %dms",
+                                         duration, expectedDurationMs));
+            }
+
+            // TODO: Don't skip this for video snapshot
+            if (!mStaticInfo.isHardwareLevelLegacy()) {
+                assertTrue(String.format(
+                        "Camera %s: Video duration doesn't match: recorded %dms, expected %dms.",
+                        mCamera.getId(), duration, expectedDurationMs),
+                        Math.abs(duration - expectedDurationMs) <
+                        DURATION_MARGIN * expectedDurationMs);
+            }
+        } finally {
+            extractor.release();
+            if (!DEBUG_DUMP) {
+                outFile.delete();
+            }
+        }
+    }
+
+    /**
+     * Validate video snapshot capture image object sanity and test.
+     *
+     * <p> Check for size, format and jpeg decoding</p>
+     *
+     * @param image The JPEG image to be verified.
+     * @param size The JPEG capture size to be verified against.
+     */
+    private void validateVideoSnapshotCapture(Image image, Size size) {
+        CameraTestUtils.validateImage(image, size.getWidth(), size.getHeight(),
+                ImageFormat.JPEG, /*filePath*/null);
+    }
+
+    /**
+     * Validate if video snapshot causes frame drop.
+     * Here frame drop is defined as frame duration >= 2 * expected frame duration.
+     * Return the estimated number of frames dropped during video snapshot
+     */
+    private int validateFrameDropAroundVideoSnapshot(
+            SimpleCaptureCallback resultListener, long imageTimeStamp) {
+        double expectedDurationMs = 1000.0 / mVideoFrameRate;
+        CaptureResult prevResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        long prevTS = getValueNotNull(prevResult, CaptureResult.SENSOR_TIMESTAMP);
+        while (!resultListener.hasMoreResults()) {
+            CaptureResult currentResult =
+                    resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            long currentTS = getValueNotNull(currentResult, CaptureResult.SENSOR_TIMESTAMP);
+            if (currentTS == imageTimeStamp) {
+                // validate the timestamp before and after, then return
+                CaptureResult nextResult =
+                        resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+                long nextTS = getValueNotNull(nextResult, CaptureResult.SENSOR_TIMESTAMP);
+                double durationMs = (currentTS - prevTS) / 1000000.0;
+                int totalFramesDropped = 0;
+
+                // Snapshots in legacy mode pause the preview briefly.  Skip the duration
+                // requirements for legacy mode unless this is fixed.
+                if (!mStaticInfo.isHardwareLevelLegacy()) {
+                    mCollector.expectTrue(
+                            String.format(
+                                    "Video %dx%d Frame drop detected before video snapshot: " +
+                                            "duration %.2fms (expected %.2fms)",
+                                    mVideoSize.getWidth(), mVideoSize.getHeight(),
+                                    durationMs, expectedDurationMs
+                            ),
+                            durationMs <= (expectedDurationMs * MAX_NUM_FRAME_DROP_INTERVAL_ALLOWED)
+                    );
+                    // Log a warning is there is any frame drop detected.
+                    if (durationMs >= expectedDurationMs * 2) {
+                        Log.w(TAG, String.format(
+                                "Video %dx%d Frame drop detected before video snapshot: " +
+                                        "duration %.2fms (expected %.2fms)",
+                                mVideoSize.getWidth(), mVideoSize.getHeight(),
+                                durationMs, expectedDurationMs
+                        ));
+                    }
+
+                    durationMs = (nextTS - currentTS) / 1000000.0;
+                    mCollector.expectTrue(
+                            String.format(
+                                    "Video %dx%d Frame drop detected after video snapshot: " +
+                                            "duration %.2fms (expected %.2fms)",
+                                    mVideoSize.getWidth(), mVideoSize.getHeight(),
+                                    durationMs, expectedDurationMs
+                            ),
+                            durationMs <= (expectedDurationMs * MAX_NUM_FRAME_DROP_INTERVAL_ALLOWED)
+                    );
+                    // Log a warning is there is any frame drop detected.
+                    if (durationMs >= expectedDurationMs * 2) {
+                        Log.w(TAG, String.format(
+                                "Video %dx%d Frame drop detected after video snapshot: " +
+                                        "duration %fms (expected %fms)",
+                                mVideoSize.getWidth(), mVideoSize.getHeight(),
+                                durationMs, expectedDurationMs
+                        ));
+                    }
+
+                    double totalDurationMs = (nextTS - prevTS) / 1000000.0;
+                    // Minus 2 for the expected 2 frames interval
+                    totalFramesDropped = (int) (totalDurationMs / expectedDurationMs) - 2;
+                    if (totalFramesDropped < 0) {
+                        Log.w(TAG, "totalFrameDropped is " + totalFramesDropped +
+                                ". Video frame rate might be too fast.");
+                    }
+                    totalFramesDropped = Math.max(0, totalFramesDropped);
+                }
+                return totalFramesDropped;
+            }
+            prevTS = currentTS;
+        }
+        throw new AssertionFailedError(
+                "Video snapshot timestamp does not match any of capture results!");
+    }
+
+    /**
+     * Validate frame jittering from the input simple listener's buffered results
+     */
+    private void validateJittering(SimpleCaptureCallback resultListener) {
+        double expectedDurationMs = 1000.0 / mVideoFrameRate;
+        CaptureResult prevResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        long prevTS = getValueNotNull(prevResult, CaptureResult.SENSOR_TIMESTAMP);
+        while (!resultListener.hasMoreResults()) {
+            CaptureResult currentResult =
+                    resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            long currentTS = getValueNotNull(currentResult, CaptureResult.SENSOR_TIMESTAMP);
+            double durationMs = (currentTS - prevTS) / 1000000.0;
+            double durationError = Math.abs(durationMs - expectedDurationMs);
+            long frameNumber = currentResult.getFrameNumber();
+            mCollector.expectTrue(
+                    String.format(
+                            "Resolution %dx%d Frame %d: jittering (%.2fms) exceeds bound [%.2fms,%.2fms]",
+                            mVideoSize.getWidth(), mVideoSize.getHeight(),
+                            frameNumber, durationMs,
+                            expectedDurationMs - FRAME_DURATION_ERROR_TOLERANCE_MS,
+                            expectedDurationMs + FRAME_DURATION_ERROR_TOLERANCE_MS),
+                    durationError <= FRAME_DURATION_ERROR_TOLERANCE_MS);
+            prevTS = currentTS;
+        }
+    }
+
+    /**
+     * Calculate a video bit rate based on the size. The bit rate is scaled
+     * based on ratio of video size to 1080p size.
+     */
+    private int getVideoBitRate(Size sz) {
+        int rate = BIT_RATE_1080P;
+        float scaleFactor = sz.getHeight() * sz.getWidth() / (float)(1920 * 1080);
+        rate = (int)(rate * scaleFactor);
+
+        // Clamp to the MIN, MAX range.
+        return Math.max(BIT_RATE_MIN, Math.min(BIT_RATE_MAX, rate));
+    }
+
+    /**
+     * Check if the encoder and camera are able to support this size and frame rate.
+     * Assume the video compression format is AVC.
+     */
+    private boolean isSupported(Size sz, int captureRate, int encodingRate) throws Exception {
+        // Check camera capability.
+        if (!isSupportedByCamera(sz, captureRate)) {
+            return false;
+        }
+
+        // Check encode capability.
+        if (!isSupportedByAVCEncoder(sz, encodingRate)){
+            return false;
+        }
+
+        if(VERBOSE) {
+            Log.v(TAG, "Both encoder and camera support " + sz.toString() + "@" + encodingRate + "@"
+                    + getVideoBitRate(sz) / 1000 + "Kbps");
+        }
+
+        return true;
+    }
+
+    private boolean isSupportedByCamera(Size sz, int frameRate) {
+        // Check if camera can support this sz and frame rate combination.
+        StreamConfigurationMap config = mStaticInfo.
+                getValueFromKeyNonNull(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+
+        long minDuration = config.getOutputMinFrameDuration(MediaRecorder.class, sz);
+        if (minDuration == 0) {
+            return false;
+        }
+
+        int maxFrameRate = (int) (1e9f / minDuration);
+        return maxFrameRate >= frameRate;
+    }
+
+    /**
+     * Check if encoder can support this size and frame rate combination by querying
+     * MediaCodec capability. Check is based on size and frame rate. Ignore the bit rate
+     * as the bit rates targeted in this test are well below the bit rate max value specified
+     * by AVC specification for certain level.
+     */
+    private static boolean isSupportedByAVCEncoder(Size sz, int frameRate) {
+        MediaFormat format = MediaFormat.createVideoFormat(
+                MediaFormat.MIMETYPE_VIDEO_AVC, sz.getWidth(), sz.getHeight());
+        format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        return mcl.findEncoderForFormat(format) != null;
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/ReprocessCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/ReprocessCaptureTest.java
new file mode 100644
index 0000000..dd49c8d
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/ReprocessCaptureTest.java
@@ -0,0 +1,1411 @@
+/*
+ * 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 static android.hardware.camera2.cts.CameraTestUtils.*;
+
+import android.graphics.ImageFormat;
+import android.media.Image;
+import android.media.ImageReader;
+import android.media.ImageWriter;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+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.Size;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>Tests for Reprocess API.</p>
+ */
+public class ReprocessCaptureTest extends Camera2SurfaceViewTestCase  {
+    private static final String TAG = "ReprocessCaptureTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final int CAPTURE_TIMEOUT_FRAMES = 100;
+    private static final int CAPTURE_TIMEOUT_MS = 3000;
+    private static final int WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS = 1000;
+    private static final int CAPTURE_TEMPLATE = CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG;
+    private static final int ZSL_TEMPLATE = CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG;
+    private static final int NUM_REPROCESS_TEST_LOOP = 3;
+    private static final int NUM_REPROCESS_CAPTURES = 3;
+    private static final int NUM_REPROCESS_BURST = 3;
+    private int mDumpFrameCount = 0;
+
+    // The image reader for the first regular capture
+    private ImageReader mFirstImageReader;
+    // The image reader for the reprocess capture
+    private ImageReader mSecondImageReader;
+    // A flag indicating whether the regular capture and the reprocess capture share the same image
+    // reader. If it's true, mFirstImageReader should be used for regular and reprocess outputs.
+    private boolean mShareOneImageReader;
+    private SimpleImageReaderListener mFirstImageReaderListener;
+    private SimpleImageReaderListener mSecondImageReaderListener;
+    private Surface mInputSurface;
+    private ImageWriter mImageWriter;
+    private SimpleImageWriterListener mImageWriterListener;
+
+    private enum CaptureTestCase {
+        SINGLE_SHOT,
+        BURST,
+        MIXED_BURST,
+        ABORT_CAPTURE,
+        TIMESTAMPS,
+        JPEG_EXIF,
+        REQUEST_KEYS,
+    }
+
+    /**
+     * Test YUV_420_888 -> YUV_420_888 with maximal supported sizes
+     */
+    public void testBasicYuvToYuvReprocessing() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id)) {
+                continue;
+            }
+
+            // YUV_420_888 -> YUV_420_888 must be supported.
+            testBasicReprocessing(id, ImageFormat.YUV_420_888, ImageFormat.YUV_420_888);
+        }
+    }
+
+    /**
+     * Test YUV_420_888 -> JPEG with maximal supported sizes
+     */
+    public void testBasicYuvToJpegReprocessing() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id)) {
+                continue;
+            }
+
+            // YUV_420_888 -> JPEG must be supported.
+            testBasicReprocessing(id, ImageFormat.YUV_420_888, ImageFormat.JPEG);
+        }
+    }
+
+    /**
+     * Test OPAQUE -> YUV_420_888 with maximal supported sizes
+     */
+    public void testBasicOpaqueToYuvReprocessing() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            // Opaque -> YUV_420_888 must be supported.
+            testBasicReprocessing(id, ImageFormat.PRIVATE, ImageFormat.YUV_420_888);
+        }
+    }
+
+    /**
+     * Test OPAQUE -> JPEG with maximal supported sizes
+     */
+    public void testBasicOpaqueToJpegReprocessing() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            // OPAQUE -> JPEG must be supported.
+            testBasicReprocessing(id, ImageFormat.PRIVATE, ImageFormat.JPEG);
+        }
+    }
+
+    /**
+     * Test all supported size and format combinations.
+     */
+    public void testReprocessingSizeFormat() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            try {
+                // open Camera device
+                openDevice(id);
+                // no preview
+                testReprocessingAllCombinations(id, /*previewSize*/null,
+                        CaptureTestCase.SINGLE_SHOT);
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test all supported size and format combinations with preview.
+     */
+    public void testReprocessingSizeFormatWithPreview() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            try {
+                // open Camera device
+                openDevice(id);
+                testReprocessingAllCombinations(id, mOrderedPreviewSizes.get(0),
+                        CaptureTestCase.SINGLE_SHOT);
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test recreating reprocessing sessions.
+     */
+    public void testRecreateReprocessingSessions() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            try {
+                openDevice(id);
+
+                // Test supported input/output formats with the largest sizes.
+                int[] inputFormats =
+                        mStaticInfo.getAvailableFormats(StaticMetadata.StreamDirection.Input);
+                for (int inputFormat : inputFormats) {
+                    int[] reprocessOutputFormats =
+                            mStaticInfo.getValidOutputFormatsForInput(inputFormat);
+                    for (int reprocessOutputFormat : reprocessOutputFormats) {
+                        Size maxInputSize =
+                                getMaxSize(inputFormat, StaticMetadata.StreamDirection.Input);
+                        Size maxReprocessOutputSize = getMaxSize(reprocessOutputFormat,
+                                StaticMetadata.StreamDirection.Output);
+
+                        for (int i = 0; i < NUM_REPROCESS_TEST_LOOP; i++) {
+                            testReprocess(id, maxInputSize, inputFormat, maxReprocessOutputSize,
+                                    reprocessOutputFormat,
+                                    /* previewSize */null, NUM_REPROCESS_CAPTURES);
+                        }
+                    }
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Verify issuing cross session capture requests is invalid.
+     */
+    public void testCrossSessionCaptureException() throws Exception {
+        for (String id : mCameraIds) {
+            // Test one supported input format -> JPEG
+            int inputFormat;
+            int reprocessOutputFormat = ImageFormat.JPEG;
+
+            if (isOpaqueReprocessSupported(id)) {
+                inputFormat = ImageFormat.PRIVATE;
+            } else if (isYuvReprocessSupported(id)) {
+                inputFormat = ImageFormat.YUV_420_888;
+            } else {
+                continue;
+            }
+
+            openDevice(id);
+
+            // Test the largest sizes
+            Size inputSize =
+                    getMaxSize(inputFormat, StaticMetadata.StreamDirection.Input);
+            Size reprocessOutputSize =
+                    getMaxSize(reprocessOutputFormat, StaticMetadata.StreamDirection.Output);
+
+            try {
+                if (VERBOSE) {
+                    Log.v(TAG, "testCrossSessionCaptureException: cameraId: " + id +
+                            " inputSize: " + inputSize + " inputFormat: " + inputFormat +
+                            " reprocessOutputSize: " + reprocessOutputSize +
+                            " reprocessOutputFormat: " + reprocessOutputFormat);
+                }
+
+                setupImageReaders(inputSize, inputFormat, reprocessOutputSize,
+                        reprocessOutputFormat, /*maxImages*/1);
+                setupReprocessableSession(/*previewSurface*/null, /*numImageWriterImages*/1);
+
+                TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(),
+                        /*inputResult*/null);
+                Image image = mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS);
+
+                // queue the image to image writer
+                mImageWriter.queueInputImage(image);
+
+                // recreate the session
+                closeReprossibleSession();
+                setupReprocessableSession(/*previewSurface*/null, /*numImageWriterImages*/1);
+                try {
+                    TotalCaptureResult reprocessResult;
+                    // issue and wait on reprocess capture request
+                    reprocessResult = submitCaptureRequest(
+                            getReprocessOutputImageReader().getSurface(), result);
+                    fail("Camera " + id + ": should get IllegalArgumentException for cross " +
+                            "session reprocess captrue.");
+                } catch (IllegalArgumentException e) {
+                    // expected
+                    if (DEBUG) {
+                        Log.d(TAG, "Camera " + id + ": get IllegalArgumentException for cross " +
+                                "session reprocess capture as expected: " + e.getMessage());
+                    }
+                }
+            } finally {
+                closeReprossibleSession();
+                closeImageReaders();
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test burst reprocessing captures with and without preview.
+     */
+    public void testBurstReprocessing() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            try {
+                // open Camera device
+                openDevice(id);
+                // no preview
+                testReprocessingAllCombinations(id, /*previewSize*/null, CaptureTestCase.BURST);
+                // with preview
+                testReprocessingAllCombinations(id, mOrderedPreviewSizes.get(0),
+                        CaptureTestCase.BURST);
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test burst captures mixed with regular and reprocess captures with and without preview.
+     */
+    public void testMixedBurstReprocessing() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            try {
+                // open Camera device
+                openDevice(id);
+                // no preview
+                testReprocessingAllCombinations(id, /*previewSize*/null,
+                        CaptureTestCase.MIXED_BURST);
+                // with preview
+                testReprocessingAllCombinations(id, mOrderedPreviewSizes.get(0),
+                        CaptureTestCase.MIXED_BURST);
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test aborting reprocess capture requests of the largest input and output sizes for each
+     * supported format.
+     */
+    public void testReprocessAbort() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            try {
+                // open Camera device
+                openDevice(id);
+
+                int[] supportedInputFormats =
+                    mStaticInfo.getAvailableFormats(StaticMetadata.StreamDirection.Input);
+                for (int inputFormat : supportedInputFormats) {
+                    int[] supportedReprocessOutputFormats =
+                            mStaticInfo.getValidOutputFormatsForInput(inputFormat);
+                    for (int reprocessOutputFormat : supportedReprocessOutputFormats) {
+                        testReprocessingMaxSizes(id, inputFormat, reprocessOutputFormat,
+                                /*previewSize*/null, CaptureTestCase.ABORT_CAPTURE);
+                    }
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test reprocess timestamps for the largest input and output sizes for each supported format.
+     */
+    public void testReprocessTimestamps() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            try {
+                // open Camera device
+                openDevice(id);
+
+                int[] supportedInputFormats =
+                    mStaticInfo.getAvailableFormats(StaticMetadata.StreamDirection.Input);
+                for (int inputFormat : supportedInputFormats) {
+                    int[] supportedReprocessOutputFormats =
+                            mStaticInfo.getValidOutputFormatsForInput(inputFormat);
+                    for (int reprocessOutputFormat : supportedReprocessOutputFormats) {
+                        testReprocessingMaxSizes(id, inputFormat, reprocessOutputFormat,
+                                /*previewSize*/null, CaptureTestCase.TIMESTAMPS);
+                    }
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test reprocess jpeg output's exif data for the largest input and output sizes for each
+     * supported format.
+     */
+    public void testReprocessJpegExif() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            try {
+                // open Camera device
+                openDevice(id);
+
+                int[] supportedInputFormats =
+                    mStaticInfo.getAvailableFormats(StaticMetadata.StreamDirection.Input);
+
+                for (int inputFormat : supportedInputFormats) {
+                    int[] supportedReprocessOutputFormats =
+                            mStaticInfo.getValidOutputFormatsForInput(inputFormat);
+
+                    for (int reprocessOutputFormat : supportedReprocessOutputFormats) {
+                        if (reprocessOutputFormat == ImageFormat.JPEG) {
+                            testReprocessingMaxSizes(id, inputFormat, ImageFormat.JPEG,
+                                    /*previewSize*/null, CaptureTestCase.JPEG_EXIF);
+                        }
+                    }
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    public void testReprocessRequestKeys() throws Exception {
+        for (String id : mCameraIds) {
+            if (!isYuvReprocessSupported(id) && !isOpaqueReprocessSupported(id)) {
+                continue;
+            }
+
+            try {
+                // open Camera device
+                openDevice(id);
+
+                int[] supportedInputFormats =
+                    mStaticInfo.getAvailableFormats(StaticMetadata.StreamDirection.Input);
+                for (int inputFormat : supportedInputFormats) {
+                    int[] supportedReprocessOutputFormats =
+                            mStaticInfo.getValidOutputFormatsForInput(inputFormat);
+                    for (int reprocessOutputFormat : supportedReprocessOutputFormats) {
+                        testReprocessingMaxSizes(id, inputFormat, reprocessOutputFormat,
+                                /*previewSize*/null, CaptureTestCase.REQUEST_KEYS);
+                    }
+                }
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test the input format and output format with the largest input and output sizes.
+     */
+    private void testBasicReprocessing(String cameraId, int inputFormat,
+            int reprocessOutputFormat) throws Exception {
+        try {
+            openDevice(cameraId);
+
+            testReprocessingMaxSizes(cameraId, inputFormat, reprocessOutputFormat,
+                    /* previewSize */null, CaptureTestCase.SINGLE_SHOT);
+        } finally {
+            closeDevice();
+        }
+    }
+
+    /**
+     * Test the input format and output format with the largest input and output sizes for a
+     * certain test case.
+     */
+    private void testReprocessingMaxSizes(String cameraId, int inputFormat,
+            int reprocessOutputFormat, Size previewSize, CaptureTestCase captureTestCase)
+            throws Exception {
+        Size maxInputSize = getMaxSize(inputFormat, StaticMetadata.StreamDirection.Input);
+        Size maxReprocessOutputSize =
+                getMaxSize(reprocessOutputFormat, StaticMetadata.StreamDirection.Output);
+
+        switch (captureTestCase) {
+            case SINGLE_SHOT:
+                testReprocess(cameraId, maxInputSize, inputFormat, maxReprocessOutputSize,
+                        reprocessOutputFormat, previewSize, NUM_REPROCESS_CAPTURES);
+                break;
+            case ABORT_CAPTURE:
+                testReprocessAbort(cameraId, maxInputSize, inputFormat, maxReprocessOutputSize,
+                        reprocessOutputFormat);
+                break;
+            case TIMESTAMPS:
+                testReprocessTimestamps(cameraId, maxInputSize, inputFormat, maxReprocessOutputSize,
+                        reprocessOutputFormat);
+                break;
+            case JPEG_EXIF:
+                testReprocessJpegExif(cameraId, maxInputSize, inputFormat, maxReprocessOutputSize);
+                break;
+            case REQUEST_KEYS:
+                testReprocessRequestKeys(cameraId, maxInputSize, inputFormat,
+                        maxReprocessOutputSize, reprocessOutputFormat);
+                break;
+            default:
+                throw new IllegalArgumentException("Invalid test case");
+        }
+    }
+
+    /**
+     * Test all input format, input size, output format, and output size combinations.
+     */
+    private void testReprocessingAllCombinations(String cameraId, Size previewSize,
+            CaptureTestCase captureTestCase) throws Exception {
+
+        int[] supportedInputFormats =
+                mStaticInfo.getAvailableFormats(StaticMetadata.StreamDirection.Input);
+        for (int inputFormat : supportedInputFormats) {
+            Size[] supportedInputSizes =
+                    mStaticInfo.getAvailableSizesForFormatChecked(inputFormat,
+                    StaticMetadata.StreamDirection.Input);
+
+            for (Size inputSize : supportedInputSizes) {
+                int[] supportedReprocessOutputFormats =
+                        mStaticInfo.getValidOutputFormatsForInput(inputFormat);
+
+                for (int reprocessOutputFormat : supportedReprocessOutputFormats) {
+                    Size[] supportedReprocessOutputSizes =
+                            mStaticInfo.getAvailableSizesForFormatChecked(reprocessOutputFormat,
+                            StaticMetadata.StreamDirection.Output);
+
+                    for (Size reprocessOutputSize : supportedReprocessOutputSizes) {
+                        switch (captureTestCase) {
+                            case SINGLE_SHOT:
+                                testReprocess(cameraId, inputSize, inputFormat,
+                                        reprocessOutputSize, reprocessOutputFormat, previewSize,
+                                        NUM_REPROCESS_CAPTURES);
+                                break;
+                            case BURST:
+                                testReprocessBurst(cameraId, inputSize, inputFormat,
+                                        reprocessOutputSize, reprocessOutputFormat, previewSize,
+                                        NUM_REPROCESS_BURST);
+                                break;
+                            case MIXED_BURST:
+                                testReprocessMixedBurst(cameraId, inputSize, inputFormat,
+                                        reprocessOutputSize, reprocessOutputFormat, previewSize,
+                                        NUM_REPROCESS_BURST);
+                                break;
+                            default:
+                                throw new IllegalArgumentException("Invalid test case");
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Test burst that is mixed with regular and reprocess capture requests.
+     */
+    private void testReprocessMixedBurst(String cameraId, Size inputSize, int inputFormat,
+            Size reprocessOutputSize, int reprocessOutputFormat, Size previewSize,
+            int numBurst) throws Exception {
+        if (VERBOSE) {
+            Log.v(TAG, "testReprocessMixedBurst: cameraId: " + cameraId + " inputSize: " +
+                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
+                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat +
+                    " previewSize: " + previewSize + " numBurst: " + numBurst);
+        }
+
+        boolean enablePreview = (previewSize != null);
+        ImageResultHolder[] imageResultHolders = new ImageResultHolder[0];
+
+        try {
+            // totalNumBurst = number of regular burst + number of reprocess burst.
+            int totalNumBurst = numBurst * 2;
+
+            if (enablePreview) {
+                updatePreviewSurface(previewSize);
+            } else {
+                mPreviewSurface = null;
+            }
+
+            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
+                totalNumBurst);
+            setupReprocessableSession(mPreviewSurface, /*numImageWriterImages*/numBurst);
+
+            if (enablePreview) {
+                startPreview(mPreviewSurface);
+            }
+
+            // Prepare an array of booleans indicating each capture's type (regular or reprocess)
+            boolean[] isReprocessCaptures = new boolean[totalNumBurst];
+            for (int i = 0; i < totalNumBurst; i++) {
+                if ((i & 1) == 0) {
+                    isReprocessCaptures[i] = true;
+                } else {
+                    isReprocessCaptures[i] = false;
+                }
+            }
+
+            imageResultHolders = doMixedReprocessBurstCapture(isReprocessCaptures);
+            for (ImageResultHolder holder : imageResultHolders) {
+                Image reprocessedImage = holder.getImage();
+                TotalCaptureResult result = holder.getTotalCaptureResult();
+
+                mCollector.expectImageProperties("testReprocessMixedBurst", reprocessedImage,
+                            reprocessOutputFormat, reprocessOutputSize,
+                            result.get(CaptureResult.SENSOR_TIMESTAMP));
+
+                if (DEBUG) {
+                    Log.d(TAG, String.format("camera %s in %dx%d %d out %dx%d %d",
+                            cameraId, inputSize.getWidth(), inputSize.getHeight(), inputFormat,
+                            reprocessOutputSize.getWidth(), reprocessOutputSize.getHeight(),
+                            reprocessOutputFormat));
+                    dumpImage(reprocessedImage,
+                            "/testReprocessMixedBurst_camera" + cameraId + "_" + mDumpFrameCount);
+                    mDumpFrameCount++;
+                }
+            }
+        } finally {
+            for (ImageResultHolder holder : imageResultHolders) {
+                holder.getImage().close();
+            }
+            closeReprossibleSession();
+            closeImageReaders();
+        }
+    }
+
+    /**
+     * Test burst of reprocess capture requests.
+     */
+    private void testReprocessBurst(String cameraId, Size inputSize, int inputFormat,
+            Size reprocessOutputSize, int reprocessOutputFormat, Size previewSize,
+            int numBurst) throws Exception {
+        if (VERBOSE) {
+            Log.v(TAG, "testReprocessBurst: cameraId: " + cameraId + " inputSize: " +
+                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
+                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat +
+                    " previewSize: " + previewSize + " numBurst: " + numBurst);
+        }
+
+        boolean enablePreview = (previewSize != null);
+        ImageResultHolder[] imageResultHolders = new ImageResultHolder[0];
+
+        try {
+            if (enablePreview) {
+                updatePreviewSurface(previewSize);
+            } else {
+                mPreviewSurface = null;
+            }
+
+            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
+                numBurst);
+            setupReprocessableSession(mPreviewSurface, numBurst);
+
+            if (enablePreview) {
+                startPreview(mPreviewSurface);
+            }
+
+            imageResultHolders = doReprocessBurstCapture(numBurst);
+            for (ImageResultHolder holder : imageResultHolders) {
+                Image reprocessedImage = holder.getImage();
+                TotalCaptureResult result = holder.getTotalCaptureResult();
+
+                mCollector.expectImageProperties("testReprocessBurst", reprocessedImage,
+                            reprocessOutputFormat, reprocessOutputSize,
+                            result.get(CaptureResult.SENSOR_TIMESTAMP));
+
+                if (DEBUG) {
+                    Log.d(TAG, String.format("camera %s in %dx%d %d out %dx%d %d",
+                            cameraId, inputSize.getWidth(), inputSize.getHeight(), inputFormat,
+                            reprocessOutputSize.getWidth(), reprocessOutputSize.getHeight(),
+                            reprocessOutputFormat));
+                    dumpImage(reprocessedImage,
+                            "/testReprocessBurst_camera" + cameraId + "_" + mDumpFrameCount);
+                    mDumpFrameCount++;
+                }
+            }
+        } finally {
+            for (ImageResultHolder holder : imageResultHolders) {
+                holder.getImage().close();
+            }
+            closeReprossibleSession();
+            closeImageReaders();
+        }
+    }
+
+    /**
+     * Test a sequences of reprocess capture requests.
+     */
+    private void testReprocess(String cameraId, Size inputSize, int inputFormat,
+            Size reprocessOutputSize, int reprocessOutputFormat, Size previewSize,
+            int numReprocessCaptures) throws Exception {
+        if (VERBOSE) {
+            Log.v(TAG, "testReprocess: cameraId: " + cameraId + " inputSize: " +
+                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
+                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat +
+                    " previewSize: " + previewSize);
+        }
+
+        boolean enablePreview = (previewSize != null);
+
+        try {
+            if (enablePreview) {
+                updatePreviewSurface(previewSize);
+            } else {
+                mPreviewSurface = null;
+            }
+
+            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
+                    /*maxImages*/1);
+            setupReprocessableSession(mPreviewSurface, /*numImageWriterImages*/1);
+
+            if (enablePreview) {
+                startPreview(mPreviewSurface);
+            }
+
+            for (int i = 0; i < numReprocessCaptures; i++) {
+                ImageResultHolder imageResultHolder = null;
+
+                try {
+                    imageResultHolder = doReprocessCapture();
+                    Image reprocessedImage = imageResultHolder.getImage();
+                    TotalCaptureResult result = imageResultHolder.getTotalCaptureResult();
+
+                    mCollector.expectImageProperties("testReprocess", reprocessedImage,
+                            reprocessOutputFormat, reprocessOutputSize,
+                            result.get(CaptureResult.SENSOR_TIMESTAMP));
+
+                    if (DEBUG) {
+                        Log.d(TAG, String.format("camera %s in %dx%d %d out %dx%d %d",
+                                cameraId, inputSize.getWidth(), inputSize.getHeight(), inputFormat,
+                                reprocessOutputSize.getWidth(), reprocessOutputSize.getHeight(),
+                                reprocessOutputFormat));
+
+                        dumpImage(reprocessedImage,
+                                "/testReprocess_camera" + cameraId + "_" + mDumpFrameCount);
+                        mDumpFrameCount++;
+                    }
+                } finally {
+                    if (imageResultHolder != null) {
+                        imageResultHolder.getImage().close();
+                    }
+                }
+            }
+        } finally {
+            closeReprossibleSession();
+            closeImageReaders();
+        }
+    }
+
+    /**
+     * Test aborting a burst reprocess capture and multiple single reprocess captures.
+     */
+    private void testReprocessAbort(String cameraId, Size inputSize, int inputFormat,
+            Size reprocessOutputSize, int reprocessOutputFormat) throws Exception {
+        if (VERBOSE) {
+            Log.v(TAG, "testReprocessAbort: cameraId: " + cameraId + " inputSize: " +
+                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
+                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat);
+        }
+
+        try {
+            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
+                    NUM_REPROCESS_CAPTURES);
+            setupReprocessableSession(/*previewSurface*/null, NUM_REPROCESS_CAPTURES);
+
+            // Test two cases: submitting reprocess requests one by one and in a burst.
+            boolean submitInBursts[] = {false, true};
+            for (boolean submitInBurst : submitInBursts) {
+                // Prepare reprocess capture requests.
+                ArrayList<CaptureRequest> reprocessRequests =
+                        new ArrayList<>(NUM_REPROCESS_CAPTURES);
+
+                for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
+                    TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(),
+                            /*inputResult*/null);
+
+                    mImageWriter.queueInputImage(
+                            mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
+                    CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
+                    builder.addTarget(getReprocessOutputImageReader().getSurface());
+                    reprocessRequests.add(builder.build());
+                }
+
+                SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
+
+                // Submit reprocess capture requests.
+                if (submitInBurst) {
+                    mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
+                } else {
+                    for (CaptureRequest request : reprocessRequests) {
+                        mSession.capture(request, captureCallback, mHandler);
+                    }
+                }
+
+                // Abort after getting the first result
+                TotalCaptureResult reprocessResult =
+                        captureCallback.getTotalCaptureResultForRequest(reprocessRequests.get(0),
+                        CAPTURE_TIMEOUT_FRAMES);
+                mSession.abortCaptures();
+
+                // Wait until the session is ready again.
+                mSessionListener.getStateWaiter().waitForState(
+                        BlockingSessionCallback.SESSION_READY, SESSION_CLOSE_TIMEOUT_MS);
+
+                // Gather all failed requests.
+                ArrayList<CaptureFailure> failures =
+                        captureCallback.getCaptureFailures(NUM_REPROCESS_CAPTURES - 1);
+                ArrayList<CaptureRequest> failedRequests = new ArrayList<>();
+                for (CaptureFailure failure : failures) {
+                    failedRequests.add(failure.getRequest());
+                }
+
+                // For each request that didn't fail must have a valid result.
+                for (int i = 1; i < reprocessRequests.size(); i++) {
+                    CaptureRequest request = reprocessRequests.get(i);
+                    if (!failedRequests.contains(request)) {
+                        captureCallback.getTotalCaptureResultForRequest(request,
+                                CAPTURE_TIMEOUT_FRAMES);
+                    }
+                }
+
+                // Drain the image reader listeners.
+                mFirstImageReaderListener.drain();
+                if (!mShareOneImageReader) {
+                    mSecondImageReaderListener.drain();
+                }
+
+                // Make sure all input surfaces are released.
+                for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
+                    mImageWriterListener.waitForImageReleased(CAPTURE_TIMEOUT_MS);
+                }
+            }
+        } finally {
+            closeReprossibleSession();
+            closeImageReaders();
+        }
+    }
+
+    /**
+     * Test timestamps for reprocess requests. Reprocess request's shutter timestamp, result's
+     * sensor timestamp, and output image's timestamp should match the reprocess input's timestamp.
+     */
+    private void testReprocessTimestamps(String cameraId, Size inputSize, int inputFormat,
+            Size reprocessOutputSize, int reprocessOutputFormat) throws Exception {
+        if (VERBOSE) {
+            Log.v(TAG, "testReprocessTimestamps: cameraId: " + cameraId + " inputSize: " +
+                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
+                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat);
+        }
+
+        try {
+            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
+                    NUM_REPROCESS_CAPTURES);
+            setupReprocessableSession(/*previewSurface*/null, NUM_REPROCESS_CAPTURES);
+
+            // Prepare reprocess capture requests.
+            ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(NUM_REPROCESS_CAPTURES);
+            ArrayList<Long> expectedTimestamps = new ArrayList<>(NUM_REPROCESS_CAPTURES);
+
+            for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
+                TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(),
+                        /*inputResult*/null);
+
+                mImageWriter.queueInputImage(
+                        mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
+                CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
+                builder.addTarget(getReprocessOutputImageReader().getSurface());
+                reprocessRequests.add(builder.build());
+                // Reprocess result's timestamp should match input image's timestamp.
+                expectedTimestamps.add(result.get(CaptureResult.SENSOR_TIMESTAMP));
+            }
+
+            // Submit reprocess requests.
+            SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
+            mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
+
+            // Verify we get the expected timestamps.
+            for (int i = 0; i < reprocessRequests.size(); i++) {
+                captureCallback.waitForCaptureStart(reprocessRequests.get(i),
+                        expectedTimestamps.get(i), CAPTURE_TIMEOUT_FRAMES);
+            }
+
+            TotalCaptureResult[] reprocessResults =
+                    captureCallback.getTotalCaptureResultsForRequests(reprocessRequests,
+                    CAPTURE_TIMEOUT_FRAMES);
+
+            for (int i = 0; i < expectedTimestamps.size(); i++) {
+                // Verify the result timestamps match the input image's timestamps.
+                long expected = expectedTimestamps.get(i);
+                long timestamp = reprocessResults[i].get(CaptureResult.SENSOR_TIMESTAMP);
+                assertEquals("Reprocess result timestamp (" + timestamp + ") doesn't match input " +
+                        "image's timestamp (" + expected + ")", expected, timestamp);
+
+                // Verify the reprocess output image timestamps match the input image's timestamps.
+                Image image = getReprocessOutputImageReaderListener().getImage(CAPTURE_TIMEOUT_MS);
+                timestamp = image.getTimestamp();
+                image.close();
+
+                assertEquals("Reprocess output timestamp (" + timestamp + ") doesn't match input " +
+                        "image's timestamp (" + expected + ")", expected, timestamp);
+            }
+
+            // Make sure all input surfaces are released.
+            for (int i = 0; i < NUM_REPROCESS_CAPTURES; i++) {
+                mImageWriterListener.waitForImageReleased(CAPTURE_TIMEOUT_MS);
+            }
+        } finally {
+            closeReprossibleSession();
+            closeImageReaders();
+        }
+    }
+
+    /**
+     * Test JPEG tags for reprocess requests. Reprocess result's JPEG tags and JPEG image's tags
+     * match reprocess request's JPEG tags.
+     */
+    private void testReprocessJpegExif(String cameraId, Size inputSize, int inputFormat,
+            Size reprocessOutputSize) throws Exception {
+        if (VERBOSE) {
+            Log.v(TAG, "testReprocessJpegExif: cameraId: " + cameraId + " inputSize: " +
+                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
+                    reprocessOutputSize);
+        }
+
+        Size[] thumbnailSizes = mStaticInfo.getAvailableThumbnailSizesChecked();
+        Size[] testThumbnailSizes = new Size[EXIF_TEST_DATA.length];
+        Arrays.fill(testThumbnailSizes, thumbnailSizes[thumbnailSizes.length - 1]);
+        // Make sure thumbnail size (0, 0) is covered.
+        testThumbnailSizes[0] = new Size(0, 0);
+
+        try {
+            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, ImageFormat.JPEG,
+                    EXIF_TEST_DATA.length);
+            setupReprocessableSession(/*previewSurface*/null, EXIF_TEST_DATA.length);
+
+            // Prepare reprocess capture requests.
+            ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(EXIF_TEST_DATA.length);
+
+            for (int i = 0; i < EXIF_TEST_DATA.length; i++) {
+                TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(),
+                        /*inputResult*/null);
+                mImageWriter.queueInputImage(
+                        mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
+
+                CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
+                builder.addTarget(getReprocessOutputImageReader().getSurface());
+
+                // set jpeg keys
+                setJpegKeys(builder, EXIF_TEST_DATA[i], testThumbnailSizes[i], mCollector);
+                reprocessRequests.add(builder.build());
+            }
+
+            // Submit reprocess requests.
+            SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
+            mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
+
+            TotalCaptureResult[] reprocessResults =
+                    captureCallback.getTotalCaptureResultsForRequests(reprocessRequests,
+                    CAPTURE_TIMEOUT_FRAMES);
+
+            for (int i = 0; i < EXIF_TEST_DATA.length; i++) {
+                // Verify output image's and result's JPEG EXIF data.
+                Image image = getReprocessOutputImageReaderListener().getImage(CAPTURE_TIMEOUT_MS);
+                verifyJpegKeys(image, reprocessResults[i], reprocessOutputSize,
+                        testThumbnailSizes[i], EXIF_TEST_DATA[i], mStaticInfo, mCollector);
+                image.close();
+
+            }
+        } finally {
+            closeReprossibleSession();
+            closeImageReaders();
+        }
+    }
+
+
+
+    /**
+     * Test the following keys in reprocess results match the keys in reprocess requests:
+     *   1. EDGE_MODE
+     *   2. NOISE_REDUCTION_MODE
+     *   3. REPROCESS_EFFECTIVE_EXPOSURE_FACTOR (only for YUV reprocess)
+     */
+    private void testReprocessRequestKeys(String cameraId, Size inputSize, int inputFormat,
+            Size reprocessOutputSize, int reprocessOutputFormat) throws Exception {
+        if (VERBOSE) {
+            Log.v(TAG, "testReprocessRequestKeys: cameraId: " + cameraId + " inputSize: " +
+                    inputSize + " inputFormat: " + inputFormat + " reprocessOutputSize: " +
+                    reprocessOutputSize + " reprocessOutputFormat: " + reprocessOutputFormat);
+        }
+
+        final Integer[] EDGE_MODES = {CaptureRequest.EDGE_MODE_FAST,
+                CaptureRequest.EDGE_MODE_HIGH_QUALITY, CaptureRequest.EDGE_MODE_OFF,
+                CaptureRequest.EDGE_MODE_ZERO_SHUTTER_LAG};
+        final Integer[] NR_MODES = {CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY,
+                CaptureRequest.NOISE_REDUCTION_MODE_OFF,
+                CaptureRequest.NOISE_REDUCTION_MODE_ZERO_SHUTTER_LAG,
+                CaptureRequest.NOISE_REDUCTION_MODE_FAST};
+        final Float[] EFFECTIVE_EXP_FACTORS = {null, 1.0f, 2.5f, 4.0f};
+        int numFrames = EDGE_MODES.length;
+
+        try {
+            setupImageReaders(inputSize, inputFormat, reprocessOutputSize, reprocessOutputFormat,
+                    numFrames);
+            setupReprocessableSession(/*previewSurface*/null, numFrames);
+
+            // Prepare reprocess capture requests.
+            ArrayList<CaptureRequest> reprocessRequests = new ArrayList<>(numFrames);
+
+            for (int i = 0; i < numFrames; i++) {
+                TotalCaptureResult result = submitCaptureRequest(mFirstImageReader.getSurface(),
+                        /*inputResult*/null);
+                mImageWriter.queueInputImage(
+                        mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
+
+                CaptureRequest.Builder builder = mCamera.createReprocessCaptureRequest(result);
+                builder.addTarget(getReprocessOutputImageReader().getSurface());
+
+                // Set reprocess request keys
+                builder.set(CaptureRequest.EDGE_MODE, EDGE_MODES[i]);
+                builder.set(CaptureRequest.NOISE_REDUCTION_MODE, NR_MODES[i]);
+                if (inputFormat == ImageFormat.YUV_420_888) {
+                    builder.set(CaptureRequest.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR,
+                            EFFECTIVE_EXP_FACTORS[i]);
+                }
+                reprocessRequests.add(builder.build());
+            }
+
+            // Submit reprocess requests.
+            SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
+            mSession.captureBurst(reprocessRequests, captureCallback, mHandler);
+
+            TotalCaptureResult[] reprocessResults =
+                    captureCallback.getTotalCaptureResultsForRequests(reprocessRequests,
+                    CAPTURE_TIMEOUT_FRAMES);
+
+            for (int i = 0; i < numFrames; i++) {
+                // Verify result's keys
+                Integer resultEdgeMode = reprocessResults[i].get(CaptureResult.EDGE_MODE);
+                Integer resultNoiseReductionMode =
+                        reprocessResults[i].get(CaptureResult.NOISE_REDUCTION_MODE);
+
+                assertEquals("Reprocess result edge mode (" + resultEdgeMode +
+                        ") doesn't match requested edge mode (" + EDGE_MODES[i] + ")",
+                        resultEdgeMode, EDGE_MODES[i]);
+                assertEquals("Reprocess result noise reduction mode (" + resultNoiseReductionMode +
+                        ") doesn't match requested noise reduction mode (" +
+                        NR_MODES[i] + ")", resultNoiseReductionMode,
+                        NR_MODES[i]);
+
+                if (inputFormat == ImageFormat.YUV_420_888) {
+                    Float resultEffectiveExposureFactor = reprocessResults[i].get(
+                            CaptureResult.REPROCESS_EFFECTIVE_EXPOSURE_FACTOR);
+                    assertEquals("Reprocess effective exposure factor (" +
+                            resultEffectiveExposureFactor + ") doesn't match requested " +
+                            "effective exposure factor (" + EFFECTIVE_EXP_FACTORS[i] + ")",
+                            resultEffectiveExposureFactor, EFFECTIVE_EXP_FACTORS[i]);
+                }
+            }
+        } finally {
+            closeReprossibleSession();
+            closeImageReaders();
+        }
+    }
+
+    /**
+     * Set up two image readers: one for regular capture (used for reprocess input) and one for
+     * reprocess capture.
+     */
+    private void setupImageReaders(Size inputSize, int inputFormat, Size reprocessOutputSize,
+            int reprocessOutputFormat, int maxImages) {
+
+        mShareOneImageReader = false;
+        // If the regular output and reprocess output have the same size and format,
+        // they can share one image reader.
+        if (inputFormat == reprocessOutputFormat &&
+                inputSize.equals(reprocessOutputSize)) {
+            maxImages *= 2;
+            mShareOneImageReader = true;
+        }
+        // create an ImageReader for the regular capture
+        mFirstImageReaderListener = new SimpleImageReaderListener();
+        mFirstImageReader = makeImageReader(inputSize, inputFormat, maxImages,
+                mFirstImageReaderListener, mHandler);
+
+        if (!mShareOneImageReader) {
+            // create an ImageReader for the reprocess capture
+            mSecondImageReaderListener = new SimpleImageReaderListener();
+            mSecondImageReader = makeImageReader(reprocessOutputSize, reprocessOutputFormat,
+                    maxImages, mSecondImageReaderListener, mHandler);
+        }
+    }
+
+    /**
+     * Close two image readers.
+     */
+    private void closeImageReaders() {
+        CameraTestUtils.closeImageReader(mFirstImageReader);
+        mFirstImageReader = null;
+        CameraTestUtils.closeImageReader(mSecondImageReader);
+        mSecondImageReader = null;
+    }
+
+    /**
+     * Get the ImageReader for reprocess output.
+     */
+    private ImageReader getReprocessOutputImageReader() {
+        if (mShareOneImageReader) {
+            return mFirstImageReader;
+        } else {
+            return mSecondImageReader;
+        }
+    }
+
+    private SimpleImageReaderListener getReprocessOutputImageReaderListener() {
+        if (mShareOneImageReader) {
+            return mFirstImageReaderListener;
+        } else {
+            return mSecondImageReaderListener;
+        }
+    }
+
+    /**
+     * Set up a reprocessable session and create an ImageWriter with the sessoin's input surface.
+     */
+    private void setupReprocessableSession(Surface previewSurface, int numImageWriterImages)
+            throws Exception {
+        // create a reprocessable capture session
+        List<Surface> outSurfaces = new ArrayList<Surface>();
+        outSurfaces.add(mFirstImageReader.getSurface());
+        if (!mShareOneImageReader) {
+            outSurfaces.add(mSecondImageReader.getSurface());
+        }
+        if (previewSurface != null) {
+            outSurfaces.add(previewSurface);
+        }
+
+        InputConfiguration inputConfig = new InputConfiguration(mFirstImageReader.getWidth(),
+                mFirstImageReader.getHeight(), mFirstImageReader.getImageFormat());
+        String inputConfigString = inputConfig.toString();
+        if (VERBOSE) {
+            Log.v(TAG, "InputConfiguration: " + inputConfigString);
+        }
+        assertTrue(String.format("inputConfig is wrong: %dx%d format %d. Expect %dx%d format %d",
+                inputConfig.getWidth(), inputConfig.getHeight(), inputConfig.getFormat(),
+                mFirstImageReader.getWidth(), mFirstImageReader.getHeight(),
+                mFirstImageReader.getImageFormat()),
+                inputConfig.getWidth() == mFirstImageReader.getWidth() &&
+                inputConfig.getHeight() == mFirstImageReader.getHeight() &&
+                inputConfig.getFormat() == mFirstImageReader.getImageFormat());
+
+        mSessionListener = new BlockingSessionCallback();
+        mSession = configureReprocessableCameraSession(mCamera, inputConfig, outSurfaces,
+                mSessionListener, mHandler);
+
+        // create an ImageWriter
+        mInputSurface = mSession.getInputSurface();
+        mImageWriter = ImageWriter.newInstance(mInputSurface,
+                numImageWriterImages);
+
+        mImageWriterListener = new SimpleImageWriterListener(mImageWriter);
+        mImageWriter.setOnImageReleasedListener(mImageWriterListener, mHandler);
+    }
+
+    /**
+     * Close the reprocessable session and ImageWriter.
+     */
+    private void closeReprossibleSession() {
+        mInputSurface = null;
+
+        if (mSession != null) {
+            mSession.close();
+            mSession = null;
+        }
+
+        if (mImageWriter != null) {
+            mImageWriter.close();
+            mImageWriter = null;
+        }
+    }
+
+    /**
+     * Do one reprocess capture.
+     */
+    private ImageResultHolder doReprocessCapture() throws Exception {
+        return doReprocessBurstCapture(/*numBurst*/1)[0];
+    }
+
+    /**
+     * Do a burst of reprocess captures.
+     */
+    private ImageResultHolder[] doReprocessBurstCapture(int numBurst) throws Exception {
+        boolean[] isReprocessCaptures = new boolean[numBurst];
+        for (int i = 0; i < numBurst; i++) {
+            isReprocessCaptures[i] = true;
+        }
+
+        return doMixedReprocessBurstCapture(isReprocessCaptures);
+    }
+
+    /**
+     * Do a burst of captures that are mixed with regular and reprocess captures.
+     *
+     * @param isReprocessCaptures An array whose elements indicate whether it's a reprocess capture
+     *                            request. If the element is true, it represents a reprocess capture
+     *                            request. If the element is false, it represents a regular capture
+     *                            request. The size of the array is the number of capture requests
+     *                            in the burst.
+     */
+    private ImageResultHolder[] doMixedReprocessBurstCapture(boolean[] isReprocessCaptures)
+            throws Exception {
+        if (isReprocessCaptures == null || isReprocessCaptures.length <= 0) {
+            throw new IllegalArgumentException("isReprocessCaptures must have at least 1 capture.");
+        }
+
+        boolean hasReprocessRequest = false;
+        boolean hasRegularRequest = false;
+
+        TotalCaptureResult[] results = new TotalCaptureResult[isReprocessCaptures.length];
+        for (int i = 0; i < isReprocessCaptures.length; i++) {
+            // submit a capture and get the result if this entry is a reprocess capture.
+            if (isReprocessCaptures[i]) {
+                results[i] = submitCaptureRequest(mFirstImageReader.getSurface(),
+                        /*inputResult*/null);
+                mImageWriter.queueInputImage(
+                        mFirstImageReaderListener.getImage(CAPTURE_TIMEOUT_MS));
+                hasReprocessRequest = true;
+            } else {
+                hasRegularRequest = true;
+            }
+        }
+
+        Surface[] outputSurfaces = new Surface[isReprocessCaptures.length];
+        for (int i = 0; i < isReprocessCaptures.length; i++) {
+            outputSurfaces[i] = getReprocessOutputImageReader().getSurface();
+        }
+
+        TotalCaptureResult[] finalResults = submitMixedCaptureBurstRequest(outputSurfaces, results);
+
+        ImageResultHolder[] holders = new ImageResultHolder[isReprocessCaptures.length];
+        for (int i = 0; i < isReprocessCaptures.length; i++) {
+            Image image = getReprocessOutputImageReaderListener().getImage(CAPTURE_TIMEOUT_MS);
+            if (hasReprocessRequest && hasRegularRequest) {
+                // If there are mixed requests, images and results may not be in the same order.
+                for (int j = 0; j < finalResults.length; j++) {
+                    if (finalResults[j] != null &&
+                            finalResults[j].get(CaptureResult.SENSOR_TIMESTAMP) ==
+                            image.getTimestamp()) {
+                        holders[i] = new ImageResultHolder(image, finalResults[j]);
+                        finalResults[j] = null;
+                        break;
+                    }
+                }
+
+                assertNotNull("Cannot find a result matching output image's timestamp: " +
+                        image.getTimestamp(), holders[i]);
+            } else {
+                // If no mixed requests, images and results should be in the same order.
+                holders[i] = new ImageResultHolder(image, finalResults[i]);
+            }
+        }
+
+        return holders;
+    }
+
+    /**
+     * Start preview without a listener.
+     */
+    private void startPreview(Surface previewSurface) throws Exception {
+        CaptureRequest.Builder builder = mCamera.createCaptureRequest(ZSL_TEMPLATE);
+        builder.addTarget(previewSurface);
+        mSession.setRepeatingRequest(builder.build(), null, mHandler);
+    }
+
+    /**
+     * Issue a capture request and return the result. If inputResult is null, it's a regular
+     * request. Otherwise, it's a reprocess request.
+     */
+    private TotalCaptureResult submitCaptureRequest(Surface output,
+            TotalCaptureResult inputResult) throws Exception {
+        Surface[] outputs = new Surface[1];
+        outputs[0] = output;
+        TotalCaptureResult[] inputResults = new TotalCaptureResult[1];
+        inputResults[0] = inputResult;
+
+        return submitMixedCaptureBurstRequest(outputs, inputResults)[0];
+    }
+
+    /**
+     * Submit a burst request mixed with regular and reprocess requests.
+     *
+     * @param outputs An array of output surfaces. One output surface will be used in one request
+     *                so the length of the array is the number of requests in a burst request.
+     * @param inputResults An array of input results. If it's null, all requests are regular
+     *                     requests. If an element is null, that element represents a regular
+     *                     request. If an element if not null, that element represents a reprocess
+     *                     request.
+     *
+     */
+    private TotalCaptureResult[] submitMixedCaptureBurstRequest(Surface[] outputs,
+            TotalCaptureResult[] inputResults) throws Exception {
+        if (outputs == null || outputs.length <= 0) {
+            throw new IllegalArgumentException("outputs must have at least 1 surface");
+        } else if (inputResults != null && inputResults.length != outputs.length) {
+            throw new IllegalArgumentException("The lengths of outputs and inputResults " +
+                    "don't match");
+        }
+
+        int numReprocessCaptures = 0;
+        SimpleCaptureCallback captureCallback = new SimpleCaptureCallback();
+        ArrayList<CaptureRequest> captureRequests = new ArrayList<>(outputs.length);
+
+        // Prepare a list of capture requests. Whether it's a regular or reprocess capture request
+        // is based on inputResults array.
+        for (int i = 0; i < outputs.length; i++) {
+            CaptureRequest.Builder builder;
+            boolean isReprocess = (inputResults != null && inputResults[i] != null);
+            if (isReprocess) {
+                builder = mCamera.createReprocessCaptureRequest(inputResults[i]);
+                numReprocessCaptures++;
+            } else {
+                builder = mCamera.createCaptureRequest(CAPTURE_TEMPLATE);
+            }
+            builder.addTarget(outputs[i]);
+            CaptureRequest request = builder.build();
+            assertTrue("Capture request reprocess type " + request.isReprocess() + " is wrong.",
+                request.isReprocess() == isReprocess);
+
+            captureRequests.add(request);
+        }
+
+        if (captureRequests.size() == 1) {
+            mSession.capture(captureRequests.get(0), captureCallback, mHandler);
+        } else {
+            mSession.captureBurst(captureRequests, captureCallback, mHandler);
+        }
+
+        TotalCaptureResult[] results;
+        if (numReprocessCaptures == 0 || numReprocessCaptures == outputs.length) {
+            results = new TotalCaptureResult[outputs.length];
+            // If the requests are not mixed, they should come in order.
+            for (int i = 0; i < results.length; i++){
+                results[i] = captureCallback.getTotalCaptureResultForRequest(
+                        captureRequests.get(i), CAPTURE_TIMEOUT_FRAMES);
+            }
+        } else {
+            // If the requests are mixed, they may not come in order.
+            results = captureCallback.getTotalCaptureResultsForRequests(
+                    captureRequests, CAPTURE_TIMEOUT_FRAMES * captureRequests.size());
+        }
+
+        // make sure all input surfaces are released.
+        for (int i = 0; i < numReprocessCaptures; i++) {
+            mImageWriterListener.waitForImageReleased(CAPTURE_TIMEOUT_MS);
+        }
+
+        return results;
+    }
+
+    private Size getMaxSize(int format, StaticMetadata.StreamDirection direction) {
+        Size[] sizes = mStaticInfo.getAvailableSizesForFormatChecked(format, direction);
+        return getAscendingOrderSizes(Arrays.asList(sizes), /*ascending*/false).get(0);
+    }
+
+    private boolean isYuvReprocessSupported(String cameraId) throws Exception {
+        return isReprocessSupported(cameraId, ImageFormat.YUV_420_888);
+    }
+
+    private boolean isOpaqueReprocessSupported(String cameraId) throws Exception {
+        return isReprocessSupported(cameraId, ImageFormat.PRIVATE);
+    }
+
+    private void dumpImage(Image image, String name) {
+        String filename = DEBUG_FILE_NAME_BASE + name;
+        switch(image.getFormat()) {
+            case ImageFormat.JPEG:
+                filename += ".jpg";
+                break;
+            case ImageFormat.NV16:
+            case ImageFormat.NV21:
+            case ImageFormat.YUV_420_888:
+                filename += ".yuv";
+                break;
+            default:
+                filename += "." + image.getFormat();
+                break;
+        }
+
+        Log.d(TAG, "dumping an image to " + filename);
+        dumpFile(filename , getDataFromImage(image));
+    }
+
+    /**
+     * A class that holds an Image and a TotalCaptureResult.
+     */
+    private static class ImageResultHolder {
+        private final Image mImage;
+        private final TotalCaptureResult mResult;
+
+        public ImageResultHolder(Image image, TotalCaptureResult result) {
+            mImage = image;
+            mResult = result;
+        }
+
+        public Image getImage() {
+            return mImage;
+        }
+
+        public TotalCaptureResult getTotalCaptureResult() {
+            return mResult;
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
new file mode 100644
index 0000000..ddae8eb
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/RobustnessTest.java
@@ -0,0 +1,1568 @@
+/*
+ * Copyright 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static android.hardware.camera2.cts.RobustnessTest.MaxStreamSizes.*;
+
+import android.content.Context;
+import android.graphics.ImageFormat;
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.params.InputConfiguration;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+import android.media.CamcorderProfile;
+import android.media.Image;
+import android.media.ImageReader;
+import android.media.ImageWriter;
+import android.util.Log;
+import android.util.Size;
+import android.view.Display;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.Assert.assertTrue;
+import static org.mockito.Mockito.*;
+
+/**
+ * Tests exercising edge cases in camera setup, configuration, and usage.
+ */
+public class RobustnessTest extends Camera2AndroidTestCase {
+    private static final String TAG = "RobustnessTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    private static final int CONFIGURE_TIMEOUT = 5000; //ms
+    private static final int CAPTURE_TIMEOUT = 1000; //ms
+
+    // For testTriggerInteractions
+    private static final int PREVIEW_WARMUP_FRAMES = 60;
+    private static final int MAX_RESULT_STATE_CHANGE_WAIT_FRAMES = 100;
+    private static final int MAX_TRIGGER_SEQUENCE_FRAMES = 180; // 6 sec at 30 fps
+    private static final int MAX_RESULT_STATE_POSTCHANGE_WAIT_FRAMES = 10;
+
+    /**
+     * Test that a {@link CameraCaptureSession} can be configured with a {@link Surface} containing
+     * a dimension other than one of the supported output dimensions.  The buffers produced into
+     * this surface are expected have the dimensions of the closest possible buffer size in the
+     * available stream configurations for a surface with this format.
+     */
+    public void testBadSurfaceDimensions() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Camera " + id);
+                openDevice(id);
+
+                List<Size> testSizes = null;
+                int format = mStaticInfo.isColorOutputSupported() ?
+                    ImageFormat.YUV_420_888 : ImageFormat.DEPTH16;
+
+                testSizes = CameraTestUtils.getSortedSizesForFormat(id, mCameraManager,
+                        format, null);
+
+                // Find some size not supported by the camera
+                Size weirdSize = new Size(643, 577);
+                int count = 0;
+                while(testSizes.contains(weirdSize)) {
+                    // Really, they can't all be supported...
+                    weirdSize = new Size(weirdSize.getWidth() + 1, weirdSize.getHeight() + 1);
+                    count++;
+                    assertTrue("Too many exotic YUV_420_888 resolutions supported.", count < 100);
+                }
+
+                // Setup imageReader with invalid dimension
+                ImageReader imageReader = ImageReader.newInstance(weirdSize.getWidth(),
+                        weirdSize.getHeight(), format, 3);
+
+                // Setup ImageReaderListener
+                SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+                imageReader.setOnImageAvailableListener(imageListener, mHandler);
+
+                Surface surface = imageReader.getSurface();
+                List<Surface> surfaces = new ArrayList<>();
+                surfaces.add(surface);
+
+                // Setup a capture request and listener
+                CaptureRequest.Builder request =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                request.addTarget(surface);
+
+                // Check that correct session callback is hit.
+                CameraCaptureSession.StateCallback sessionListener =
+                        mock(CameraCaptureSession.StateCallback.class);
+                CameraCaptureSession session = CameraTestUtils.configureCameraSession(mCamera,
+                        surfaces, sessionListener, mHandler);
+
+                verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()).
+                        onConfigured(any(CameraCaptureSession.class));
+                verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()).
+                        onReady(any(CameraCaptureSession.class));
+                verify(sessionListener, never()).onConfigureFailed(any(CameraCaptureSession.class));
+                verify(sessionListener, never()).onActive(any(CameraCaptureSession.class));
+                verify(sessionListener, never()).onClosed(any(CameraCaptureSession.class));
+
+                CameraCaptureSession.CaptureCallback captureListener =
+                        mock(CameraCaptureSession.CaptureCallback.class);
+                session.capture(request.build(), captureListener, mHandler);
+
+                verify(captureListener, timeout(CAPTURE_TIMEOUT).atLeastOnce()).
+                        onCaptureCompleted(any(CameraCaptureSession.class),
+                                any(CaptureRequest.class), any(TotalCaptureResult.class));
+                verify(captureListener, never()).onCaptureFailed(any(CameraCaptureSession.class),
+                        any(CaptureRequest.class), any(CaptureFailure.class));
+
+                Image image = imageListener.getImage(CAPTURE_TIMEOUT);
+                int imageWidth = image.getWidth();
+                int imageHeight = image.getHeight();
+                Size actualSize = new Size(imageWidth, imageHeight);
+
+                assertTrue("Camera does not contain outputted image resolution " + actualSize,
+                        testSizes.contains(actualSize));
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    /**
+     * Test for making sure the required output combinations for each hardware level and capability
+     * work as expected.
+     */
+    public void testMandatoryOutputCombinations() throws Exception {
+        /**
+         * Tables for maximum sizes to try for each hardware level and capability.
+         *
+         * Keep in sync with the tables in
+         * frameworks/base/core/java/android/hardware/camera2/CameraDevice.java#createCaptureSession
+         *
+         * Each row of the table is a set of (format, max resolution) pairs, using the below consts
+         */
+
+        // 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.
+        };
+
+        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.
+        };
+
+        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.
+        };
+
+        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.
+        };
+
+        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.
+        };
+
+        final int[][][] TABLES =
+            { LEGACY_COMBINATIONS, LIMITED_COMBINATIONS, BURST_COMBINATIONS, FULL_COMBINATIONS, RAW_COMBINATIONS };
+
+        sanityCheckConfigurationTables(TABLES);
+
+        for (String id : mCameraIds) {
+            openDevice(id);
+
+            // Find the concrete max sizes for each format/resolution combination
+            MaxStreamSizes maxSizes = new MaxStreamSizes(mStaticInfo, id, getContext());
+
+            String streamConfigurationMapString =
+                    mStaticInfo.getCharacteristics().get(
+                            CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP).toString();
+            if (VERBOSE) {
+                Log.v(TAG, "StreamConfigurationMap: " + streamConfigurationMapString);
+            }
+
+            // Always run legacy-level tests for color-supporting devices
+
+            if (mStaticInfo.isColorOutputSupported()) {
+                for (int[] config : LEGACY_COMBINATIONS) {
+                    testOutputCombination(id, config, maxSizes);
+                }
+            }
+
+            // Then run higher-level tests if applicable
+
+            if (!mStaticInfo.isHardwareLevelLegacy()) {
+
+                // If not legacy, at least limited, so run limited-level tests
+
+                if (mStaticInfo.isColorOutputSupported()) {
+                    for (int[] config : LIMITED_COMBINATIONS) {
+                        testOutputCombination(id, config, maxSizes);
+                    }
+                }
+
+                // Check for BURST_CAPTURE, FULL and RAW and run those if appropriate
+
+                if (mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE)) {
+                    for (int[] config : BURST_COMBINATIONS) {
+                        testOutputCombination(id, config, maxSizes);
+                    }
+                }
+
+                if (mStaticInfo.isHardwareLevelFull()) {
+                    for (int[] config : FULL_COMBINATIONS) {
+                        testOutputCombination(id, config, maxSizes);
+                    }
+                }
+
+                if (mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                    for (int[] config : RAW_COMBINATIONS) {
+                        testOutputCombination(id, config, maxSizes);
+                    }
+                }
+            }
+
+            closeDevice(id);
+        }
+    }
+
+    /**
+     * Test for making sure the required reprocess input/output combinations for each hardware
+     * level and capability work as expected.
+     */
+    public void testMandatoryReprocessConfigurations() throws Exception {
+
+        /**
+         * For each stream combination, verify that
+         *    1. A reprocessable session can be created using the stream combination.
+         *    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},
+        };
+
+        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},
+        };
+
+        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},
+        };
+
+        final int[][][] TABLES =
+                { LIMITED_COMBINATIONS, FULL_COMBINATIONS, RAW_COMBINATIONS };
+
+        sanityCheckConfigurationTables(TABLES);
+
+        for (String id : mCameraIds) {
+            CameraCharacteristics cc = mCameraManager.getCameraCharacteristics(id);
+            StaticMetadata staticInfo = new StaticMetadata(cc);
+            MaxStreamSizes maxSizes = new MaxStreamSizes(staticInfo, id, getContext());
+
+            // Skip the test for legacy devices.
+            if (staticInfo.isHardwareLevelLegacy()) {
+                continue;
+            }
+
+            openDevice(id);
+
+            try {
+                for (int[] config : LIMITED_COMBINATIONS) {
+                    testReprocessStreamCombination(id, config, maxSizes, staticInfo);
+                }
+
+                // Check FULL devices
+                if (staticInfo.isHardwareLevelFull()) {
+                    for (int[] config : FULL_COMBINATIONS) {
+                        testReprocessStreamCombination(id, config, maxSizes, staticInfo);
+                    }
+                }
+
+                // Check devices with RAW capability.
+                if (staticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                    for (int[] config : RAW_COMBINATIONS) {
+                        testReprocessStreamCombination(id, config, maxSizes, staticInfo);
+                    }
+                }
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testBasicTriggerSequence() throws Exception {
+
+        for (String id : mCameraIds) {
+            Log.i(TAG, String.format("Testing Camera %s", id));
+
+            openDevice(id);
+            try {
+                // Legacy devices do not support precapture trigger; don't test devices that
+                // can't focus
+                if (mStaticInfo.isHardwareLevelLegacy() || !mStaticInfo.hasFocuser()) {
+                    continue;
+                }
+                // Depth-only devices won't support AE
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+
+                int[] availableAfModes = mStaticInfo.getCharacteristics().get(
+                    CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
+                int[] availableAeModes = mStaticInfo.getCharacteristics().get(
+                    CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES);
+
+                for (int afMode : availableAfModes) {
+
+                    if (afMode == CameraCharacteristics.CONTROL_AF_MODE_OFF ||
+                            afMode == CameraCharacteristics.CONTROL_AF_MODE_EDOF) {
+                        // Only test AF modes that have meaningful trigger behavior
+                        continue;
+                    }
+
+                    for (int aeMode : availableAeModes) {
+                        if (aeMode ==  CameraCharacteristics.CONTROL_AE_MODE_OFF) {
+                            // Only test AE modes that have meaningful trigger behavior
+                            continue;
+                        }
+
+                        SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1);
+
+                        CaptureRequest.Builder previewRequest =
+                                prepareTriggerTestSession(preview, aeMode, afMode);
+
+                        SimpleCaptureCallback captureListener =
+                                new CameraTestUtils.SimpleCaptureCallback();
+
+                        mCameraSession.setRepeatingRequest(previewRequest.build(), captureListener,
+                                mHandler);
+
+                        // Cancel triggers
+
+                        cancelTriggersAndWait(previewRequest, captureListener, afMode);
+
+                        //
+                        // Standard sequence - AF trigger then AE trigger
+
+                        if (VERBOSE) {
+                            Log.v(TAG, String.format("Triggering AF"));
+                        }
+
+                        previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                                CaptureRequest.CONTROL_AF_TRIGGER_START);
+                        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
+
+                        CaptureRequest triggerRequest = previewRequest.build();
+                        mCameraSession.capture(triggerRequest, captureListener, mHandler);
+
+                        CaptureResult triggerResult = captureListener.getCaptureResultForRequest(
+                                triggerRequest, MAX_RESULT_STATE_CHANGE_WAIT_FRAMES);
+                        int afState = triggerResult.get(CaptureResult.CONTROL_AF_STATE);
+                        boolean focusComplete = false;
+
+                        for (int i = 0;
+                             i < MAX_TRIGGER_SEQUENCE_FRAMES && !focusComplete;
+                             i++) {
+
+                            focusComplete = verifyAfSequence(afMode, afState, focusComplete);
+
+                            CaptureResult focusResult = captureListener.getCaptureResult(
+                                    CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+                            afState = focusResult.get(CaptureResult.CONTROL_AF_STATE);
+                        }
+
+                        assertTrue("Focusing never completed!", focusComplete);
+
+                        // Standard sequence - Part 2 AE trigger
+
+                        if (VERBOSE) {
+                            Log.v(TAG, String.format("Triggering AE"));
+                        }
+
+                        previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                                CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
+                        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+
+                        triggerRequest = previewRequest.build();
+                        mCameraSession.capture(triggerRequest, captureListener, mHandler);
+
+                        triggerResult = captureListener.getCaptureResultForRequest(
+                                triggerRequest, MAX_RESULT_STATE_CHANGE_WAIT_FRAMES);
+
+                        int aeState = triggerResult.get(CaptureResult.CONTROL_AE_STATE);
+
+                        boolean precaptureComplete = false;
+
+                        for (int i = 0;
+                             i < MAX_TRIGGER_SEQUENCE_FRAMES && !precaptureComplete;
+                             i++) {
+
+                            precaptureComplete = verifyAeSequence(aeState, precaptureComplete);
+
+                            CaptureResult precaptureResult = captureListener.getCaptureResult(
+                                CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+                            aeState = precaptureResult.get(CaptureResult.CONTROL_AE_STATE);
+                        }
+
+                        assertTrue("Precapture sequence never completed!", precaptureComplete);
+
+                        for (int i = 0; i < MAX_RESULT_STATE_POSTCHANGE_WAIT_FRAMES; i++) {
+                            CaptureResult postPrecaptureResult = captureListener.getCaptureResult(
+                                CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+                            aeState = postPrecaptureResult.get(CaptureResult.CONTROL_AE_STATE);
+                            assertTrue("Late transition to PRECAPTURE state seen",
+                                    aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE);
+                        }
+
+                        // Done
+
+                        stopCapture(/*fast*/ false);
+                        preview.release();
+                    }
+
+                }
+
+            } finally {
+                closeDevice(id);
+            }
+        }
+
+    }
+
+    public void testSimultaneousTriggers() throws Exception {
+        for (String id : mCameraIds) {
+            Log.i(TAG, String.format("Testing Camera %s", id));
+
+            openDevice(id);
+            try {
+                // Legacy devices do not support precapture trigger; don't test devices that
+                // can't focus
+                if (mStaticInfo.isHardwareLevelLegacy() || !mStaticInfo.hasFocuser()) {
+                    continue;
+                }
+                // Depth-only devices won't support AE
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+
+                int[] availableAfModes = mStaticInfo.getCharacteristics().get(
+                    CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
+                int[] availableAeModes = mStaticInfo.getCharacteristics().get(
+                    CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES);
+
+                for (int afMode : availableAfModes) {
+
+                    if (afMode == CameraCharacteristics.CONTROL_AF_MODE_OFF ||
+                            afMode == CameraCharacteristics.CONTROL_AF_MODE_EDOF) {
+                        // Only test AF modes that have meaningful trigger behavior
+                        continue;
+                    }
+
+                    for (int aeMode : availableAeModes) {
+                        if (aeMode ==  CameraCharacteristics.CONTROL_AE_MODE_OFF) {
+                            // Only test AE modes that have meaningful trigger behavior
+                            continue;
+                        }
+
+                        SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1);
+
+                        CaptureRequest.Builder previewRequest =
+                                prepareTriggerTestSession(preview, aeMode, afMode);
+
+                        SimpleCaptureCallback captureListener =
+                                new CameraTestUtils.SimpleCaptureCallback();
+
+                        mCameraSession.setRepeatingRequest(previewRequest.build(), captureListener,
+                                mHandler);
+
+                        // Cancel triggers
+
+                        cancelTriggersAndWait(previewRequest, captureListener, afMode);
+
+                        //
+                        // Trigger AF and AE together
+
+                        if (VERBOSE) {
+                            Log.v(TAG, String.format("Triggering AF and AE together"));
+                        }
+
+                        previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                                CaptureRequest.CONTROL_AF_TRIGGER_START);
+                        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+
+                        CaptureRequest triggerRequest = previewRequest.build();
+                        mCameraSession.capture(triggerRequest, captureListener, mHandler);
+
+                        CaptureResult triggerResult = captureListener.getCaptureResultForRequest(
+                                triggerRequest, MAX_RESULT_STATE_CHANGE_WAIT_FRAMES);
+                        int aeState = triggerResult.get(CaptureResult.CONTROL_AE_STATE);
+                        int afState = triggerResult.get(CaptureResult.CONTROL_AF_STATE);
+
+                        boolean precaptureComplete = false;
+                        boolean focusComplete = false;
+
+                        for (int i = 0;
+                             i < MAX_TRIGGER_SEQUENCE_FRAMES &&
+                                     !(focusComplete && precaptureComplete);
+                             i++) {
+
+                            focusComplete = verifyAfSequence(afMode, afState, focusComplete);
+                            precaptureComplete = verifyAeSequence(aeState, precaptureComplete);
+
+                            CaptureResult sequenceResult = captureListener.getCaptureResult(
+                                    CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+                            afState = sequenceResult.get(CaptureResult.CONTROL_AF_STATE);
+                            aeState = sequenceResult.get(CaptureResult.CONTROL_AE_STATE);
+                        }
+
+                        assertTrue("Precapture sequence never completed!", precaptureComplete);
+                        assertTrue("Focus sequence never completed!", focusComplete);
+
+                        // Done
+
+                        stopCapture(/*fast*/ false);
+                        preview.release();
+
+                    }
+                }
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testAfThenAeTrigger() throws Exception {
+        for (String id : mCameraIds) {
+            Log.i(TAG, String.format("Testing Camera %s", id));
+
+            openDevice(id);
+            try {
+                // Legacy devices do not support precapture trigger; don't test devices that
+                // can't focus
+                if (mStaticInfo.isHardwareLevelLegacy() || !mStaticInfo.hasFocuser()) {
+                    continue;
+                }
+                // Depth-only devices won't support AE
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+
+                int[] availableAfModes = mStaticInfo.getCharacteristics().get(
+                    CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
+                int[] availableAeModes = mStaticInfo.getCharacteristics().get(
+                    CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES);
+
+                for (int afMode : availableAfModes) {
+
+                    if (afMode == CameraCharacteristics.CONTROL_AF_MODE_OFF ||
+                            afMode == CameraCharacteristics.CONTROL_AF_MODE_EDOF) {
+                        // Only test AF modes that have meaningful trigger behavior
+                        continue;
+                    }
+
+                    for (int aeMode : availableAeModes) {
+                        if (aeMode ==  CameraCharacteristics.CONTROL_AE_MODE_OFF) {
+                            // Only test AE modes that have meaningful trigger behavior
+                            continue;
+                        }
+
+                        SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1);
+
+                        CaptureRequest.Builder previewRequest =
+                                prepareTriggerTestSession(preview, aeMode, afMode);
+
+                        SimpleCaptureCallback captureListener =
+                                new CameraTestUtils.SimpleCaptureCallback();
+
+                        mCameraSession.setRepeatingRequest(previewRequest.build(), captureListener,
+                                mHandler);
+
+                        // Cancel triggers
+
+                        cancelTriggersAndWait(previewRequest, captureListener, afMode);
+
+                        //
+                        // AF with AE a request later
+
+                        if (VERBOSE) {
+                            Log.v(TAG, "Trigger AF, then AE trigger on next request");
+                        }
+
+                        previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                                CaptureRequest.CONTROL_AF_TRIGGER_START);
+                        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
+
+                        CaptureRequest triggerRequest = previewRequest.build();
+                        mCameraSession.capture(triggerRequest, captureListener, mHandler);
+
+                        previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                                CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
+                        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+
+                        CaptureRequest triggerRequest2 = previewRequest.build();
+                        mCameraSession.capture(triggerRequest2, captureListener, mHandler);
+
+                        CaptureResult triggerResult = captureListener.getCaptureResultForRequest(
+                                triggerRequest, MAX_RESULT_STATE_CHANGE_WAIT_FRAMES);
+                        int afState = triggerResult.get(CaptureResult.CONTROL_AF_STATE);
+
+                        boolean precaptureComplete = false;
+                        boolean focusComplete = false;
+
+                        focusComplete = verifyAfSequence(afMode, afState, focusComplete);
+
+                        triggerResult = captureListener.getCaptureResultForRequest(
+                                triggerRequest2, MAX_RESULT_STATE_CHANGE_WAIT_FRAMES);
+                        afState = triggerResult.get(CaptureResult.CONTROL_AF_STATE);
+                        int aeState = triggerResult.get(CaptureResult.CONTROL_AE_STATE);
+
+                        for (int i = 0;
+                             i < MAX_TRIGGER_SEQUENCE_FRAMES &&
+                                     !(focusComplete && precaptureComplete);
+                             i++) {
+
+                            focusComplete = verifyAfSequence(afMode, afState, focusComplete);
+                            precaptureComplete = verifyAeSequence(aeState, precaptureComplete);
+
+                            CaptureResult sequenceResult = captureListener.getCaptureResult(
+                                    CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+                            afState = sequenceResult.get(CaptureResult.CONTROL_AF_STATE);
+                            aeState = sequenceResult.get(CaptureResult.CONTROL_AE_STATE);
+                        }
+
+                        assertTrue("Precapture sequence never completed!", precaptureComplete);
+                        assertTrue("Focus sequence never completed!", focusComplete);
+
+                        // Done
+
+                        stopCapture(/*fast*/ false);
+                        preview.release();
+
+                    }
+                }
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    public void testAeThenAfTrigger() throws Exception {
+        for (String id : mCameraIds) {
+            Log.i(TAG, String.format("Testing Camera %s", id));
+
+            openDevice(id);
+            try {
+                // Legacy devices do not support precapture trigger; don't test devices that
+                // can't focus
+                if (mStaticInfo.isHardwareLevelLegacy() || !mStaticInfo.hasFocuser()) {
+                    continue;
+                }
+                // Depth-only devices won't support AE
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+
+                int[] availableAfModes = mStaticInfo.getCharacteristics().get(
+                    CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
+                int[] availableAeModes = mStaticInfo.getCharacteristics().get(
+                    CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES);
+
+                for (int afMode : availableAfModes) {
+
+                    if (afMode == CameraCharacteristics.CONTROL_AF_MODE_OFF ||
+                            afMode == CameraCharacteristics.CONTROL_AF_MODE_EDOF) {
+                        // Only test AF modes that have meaningful trigger behavior
+                        continue;
+                    }
+
+                    for (int aeMode : availableAeModes) {
+                        if (aeMode ==  CameraCharacteristics.CONTROL_AE_MODE_OFF) {
+                            // Only test AE modes that have meaningful trigger behavior
+                            continue;
+                        }
+
+                        SurfaceTexture preview = new SurfaceTexture(/*random int*/ 1);
+
+                        CaptureRequest.Builder previewRequest =
+                                prepareTriggerTestSession(preview, aeMode, afMode);
+
+                        SimpleCaptureCallback captureListener =
+                                new CameraTestUtils.SimpleCaptureCallback();
+
+                        mCameraSession.setRepeatingRequest(previewRequest.build(), captureListener,
+                                mHandler);
+
+                        // Cancel triggers
+
+                        cancelTriggersAndWait(previewRequest, captureListener, afMode);
+
+                        //
+                        // AE with AF a request later
+
+                        if (VERBOSE) {
+                            Log.v(TAG, "Trigger AE, then AF trigger on next request");
+                        }
+
+                        previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                                CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
+                        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+
+                        CaptureRequest triggerRequest = previewRequest.build();
+                        mCameraSession.capture(triggerRequest, captureListener, mHandler);
+
+                        previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                                CaptureRequest.CONTROL_AF_TRIGGER_START);
+                        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
+
+                        CaptureRequest triggerRequest2 = previewRequest.build();
+                        mCameraSession.capture(triggerRequest2, captureListener, mHandler);
+
+                        CaptureResult triggerResult = captureListener.getCaptureResultForRequest(
+                                triggerRequest, MAX_RESULT_STATE_CHANGE_WAIT_FRAMES);
+                        int aeState = triggerResult.get(CaptureResult.CONTROL_AE_STATE);
+
+                        boolean precaptureComplete = false;
+                        boolean focusComplete = false;
+
+                        precaptureComplete = verifyAeSequence(aeState, precaptureComplete);
+
+                        triggerResult = captureListener.getCaptureResultForRequest(
+                                triggerRequest2, MAX_RESULT_STATE_CHANGE_WAIT_FRAMES);
+                        int afState = triggerResult.get(CaptureResult.CONTROL_AF_STATE);
+                        aeState = triggerResult.get(CaptureResult.CONTROL_AE_STATE);
+
+                        for (int i = 0;
+                             i < MAX_TRIGGER_SEQUENCE_FRAMES &&
+                                     !(focusComplete && precaptureComplete);
+                             i++) {
+
+                            focusComplete = verifyAfSequence(afMode, afState, focusComplete);
+                            precaptureComplete = verifyAeSequence(aeState, precaptureComplete);
+
+                            CaptureResult sequenceResult = captureListener.getCaptureResult(
+                                    CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+                            afState = sequenceResult.get(CaptureResult.CONTROL_AF_STATE);
+                            aeState = sequenceResult.get(CaptureResult.CONTROL_AE_STATE);
+                        }
+
+                        assertTrue("Precapture sequence never completed!", precaptureComplete);
+                        assertTrue("Focus sequence never completed!", focusComplete);
+
+                        // Done
+
+                        stopCapture(/*fast*/ false);
+                        preview.release();
+
+                    }
+                }
+            } finally {
+                closeDevice(id);
+            }
+        }
+    }
+
+    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]));
+
+
+        Surface previewSurface = new Surface(preview);
+
+        preview.setDefaultBufferSize(640, 480);
+
+        ArrayList<Surface> sessionOutputs = new ArrayList<>();
+        sessionOutputs.add(previewSurface);
+
+        createSession(sessionOutputs);
+
+        CaptureRequest.Builder previewRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+        previewRequest.addTarget(previewSurface);
+
+        previewRequest.set(CaptureRequest.CONTROL_AE_MODE, aeMode);
+        previewRequest.set(CaptureRequest.CONTROL_AF_MODE, afMode);
+
+        return previewRequest;
+    }
+
+    private void cancelTriggersAndWait(CaptureRequest.Builder previewRequest,
+            SimpleCaptureCallback captureListener, int afMode) throws Exception {
+        previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER,
+                CaptureRequest.CONTROL_AF_TRIGGER_CANCEL);
+        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
+
+        CaptureRequest triggerRequest = previewRequest.build();
+        mCameraSession.capture(triggerRequest, captureListener, mHandler);
+
+        // Wait for a few frames to initialize 3A
+
+        CaptureResult previewResult = null;
+        int afState;
+        int aeState;
+
+        for (int i = 0; i < PREVIEW_WARMUP_FRAMES; i++) {
+            previewResult = captureListener.getCaptureResult(
+                    CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
+            if (VERBOSE) {
+                afState = previewResult.get(CaptureResult.CONTROL_AF_STATE);
+                aeState = previewResult.get(CaptureResult.CONTROL_AE_STATE);
+                Log.v(TAG, String.format("AF state: %s, AE state: %s",
+                                StaticMetadata.AF_STATE_NAMES[afState],
+                                StaticMetadata.AE_STATE_NAMES[aeState]));
+            }
+        }
+
+        // Verify starting states
+
+        afState = previewResult.get(CaptureResult.CONTROL_AF_STATE);
+        aeState = previewResult.get(CaptureResult.CONTROL_AE_STATE);
+
+        switch (afMode) {
+            case CaptureResult.CONTROL_AF_MODE_AUTO:
+            case CaptureResult.CONTROL_AF_MODE_MACRO:
+                assertTrue(String.format("AF state not INACTIVE, is %s",
+                                StaticMetadata.AF_STATE_NAMES[afState]),
+                        afState == CaptureResult.CONTROL_AF_STATE_INACTIVE);
+                break;
+            case CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+            case CaptureResult.CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+                // After several frames, AF must no longer be in INACTIVE state
+                assertTrue(String.format("In AF mode %s, AF state not PASSIVE_SCAN" +
+                                ", PASSIVE_FOCUSED, or PASSIVE_UNFOCUSED, is %s",
+                                StaticMetadata.AF_MODE_NAMES[afMode],
+                                StaticMetadata.AF_STATE_NAMES[afState]),
+                        afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN ||
+                        afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED ||
+                        afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED);
+                break;
+            default:
+                fail("unexpected af mode");
+        }
+
+        // After several frames, AE must no longer be in INACTIVE state
+        assertTrue(String.format("AE state must be SEARCHING, CONVERGED, " +
+                        "or FLASH_REQUIRED, is %s", StaticMetadata.AE_STATE_NAMES[aeState]),
+                aeState == CaptureResult.CONTROL_AE_STATE_SEARCHING ||
+                aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED ||
+                aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED);
+    }
+
+    private boolean verifyAfSequence(int afMode, int afState, boolean focusComplete) {
+        if (focusComplete) {
+            assertTrue(String.format("AF Mode %s: Focus lock lost after convergence: AF state: %s",
+                            StaticMetadata.AF_MODE_NAMES[afMode],
+                            StaticMetadata.AF_STATE_NAMES[afState]),
+                    afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
+                    afState ==CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+            return focusComplete;
+        }
+        if (VERBOSE) {
+            Log.v(TAG, String.format("AF mode: %s, AF state: %s",
+                            StaticMetadata.AF_MODE_NAMES[afMode],
+                            StaticMetadata.AF_STATE_NAMES[afState]));
+        }
+        switch (afMode) {
+            case CaptureResult.CONTROL_AF_MODE_AUTO:
+            case CaptureResult.CONTROL_AF_MODE_MACRO:
+                assertTrue(String.format("AF mode %s: Unexpected AF state %s",
+                                StaticMetadata.AF_MODE_NAMES[afMode],
+                                StaticMetadata.AF_STATE_NAMES[afState]),
+                        afState == CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN ||
+                        afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
+                        afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+                focusComplete =
+                        (afState != CaptureResult.CONTROL_AF_STATE_ACTIVE_SCAN);
+                break;
+            case CaptureResult.CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+                assertTrue(String.format("AF mode %s: Unexpected AF state %s",
+                                StaticMetadata.AF_MODE_NAMES[afMode],
+                                StaticMetadata.AF_STATE_NAMES[afState]),
+                        afState == CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN ||
+                        afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
+                        afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+                focusComplete =
+                        (afState != CaptureResult.CONTROL_AF_STATE_PASSIVE_SCAN);
+                break;
+            case CaptureResult.CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+                assertTrue(String.format("AF mode %s: Unexpected AF state %s",
+                                StaticMetadata.AF_MODE_NAMES[afMode],
+                                StaticMetadata.AF_STATE_NAMES[afState]),
+                        afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
+                        afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED);
+                focusComplete = true;
+                break;
+            default:
+                fail("Unexpected AF mode: " + StaticMetadata.AF_MODE_NAMES[afMode]);
+        }
+        return focusComplete;
+    }
+
+    private boolean verifyAeSequence(int aeState, boolean precaptureComplete) {
+        if (precaptureComplete) {
+            assertTrue("Precapture state seen after convergence",
+                    aeState != CaptureResult.CONTROL_AE_STATE_PRECAPTURE);
+            return precaptureComplete;
+        }
+        if (VERBOSE) {
+            Log.v(TAG, String.format("AE state: %s", StaticMetadata.AE_STATE_NAMES[aeState]));
+        }
+        switch (aeState) {
+            case CaptureResult.CONTROL_AE_STATE_PRECAPTURE:
+                // scan still continuing
+                break;
+            case CaptureResult.CONTROL_AE_STATE_CONVERGED:
+            case CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED:
+                // completed
+                precaptureComplete = true;
+                break;
+            default:
+                fail(String.format("Precapture sequence transitioned to "
+                                + "state %s incorrectly!", StaticMetadata.AE_STATE_NAMES[aeState]));
+                break;
+        }
+        return precaptureComplete;
+    }
+
+    /**
+     * Sanity check the configuration tables.
+     */
+    private void sanityCheckConfigurationTables(final int[][][] tables) throws Exception {
+        int tableIdx = 0;
+        for (int[][] table : tables) {
+            int rowIdx = 0;
+            for (int[] row : table) {
+                assertTrue(String.format("Odd number of entries for table %d row %d: %s ",
+                                tableIdx, rowIdx, Arrays.toString(row)),
+                        (row.length % 2) == 0);
+                for (int i = 0; i < row.length; i += 2) {
+                    int format = row[i];
+                    int maxSize = row[i + 1];
+                    assertTrue(String.format("table %d row %d index %d format not valid: %d",
+                                    tableIdx, rowIdx, i, format),
+                            format == PRIV || format == JPEG || format == YUV || format == RAW);
+                    assertTrue(String.format("table %d row %d index %d max size not valid: %d",
+                                    tableIdx, rowIdx, i + 1, maxSize),
+                            maxSize == PREVIEW || maxSize == RECORD ||
+                            maxSize == MAXIMUM || maxSize == VGA);
+                }
+                rowIdx++;
+            }
+            tableIdx++;
+        }
+    }
+
+    /**
+     * Simple holder for resolutions to use for different camera outputs and size limits.
+     */
+    static class MaxStreamSizes {
+        // Format shorthands
+        static final int PRIV = ImageFormat.PRIVATE;
+        static final int JPEG = ImageFormat.JPEG;
+        static final int YUV  = ImageFormat.YUV_420_888;
+        static final int RAW  = ImageFormat.RAW_SENSOR;
+
+        // Max resolution indices
+        static final int PREVIEW = 0;
+        static final int RECORD  = 1;
+        static final int MAXIMUM = 2;
+        static final int VGA = 3;
+        static final int RESOLUTION_COUNT = 4;
+
+        public MaxStreamSizes(StaticMetadata sm, String cameraId, Context context) {
+            Size[] privSizes = sm.getAvailableSizesForFormatChecked(ImageFormat.PRIVATE,
+                    StaticMetadata.StreamDirection.Output);
+            Size[] yuvSizes = sm.getAvailableSizesForFormatChecked(ImageFormat.YUV_420_888,
+                    StaticMetadata.StreamDirection.Output);
+            Size[] jpegSizes = sm.getJpegOutputSizesChecked();
+            Size[] rawSizes = sm.getRawOutputSizesChecked();
+
+            Size maxPreviewSize = getMaxPreviewSize(context, cameraId);
+
+            maxRawSize = (rawSizes.length != 0) ? CameraTestUtils.getMaxSize(rawSizes) : null;
+
+            if (sm.isColorOutputSupported()) {
+                maxPrivSizes[PREVIEW] = getMaxSize(privSizes, maxPreviewSize);
+                maxYuvSizes[PREVIEW]  = getMaxSize(yuvSizes, maxPreviewSize);
+                maxJpegSizes[PREVIEW] = getMaxSize(jpegSizes, maxPreviewSize);
+
+                maxPrivSizes[RECORD] = getMaxRecordingSize(cameraId);
+                maxYuvSizes[RECORD]  = getMaxRecordingSize(cameraId);
+                maxJpegSizes[RECORD] = getMaxRecordingSize(cameraId);
+
+                maxPrivSizes[MAXIMUM] = CameraTestUtils.getMaxSize(privSizes);
+                maxYuvSizes[MAXIMUM] = CameraTestUtils.getMaxSize(yuvSizes);
+                maxJpegSizes[MAXIMUM] = CameraTestUtils.getMaxSize(jpegSizes);
+
+                // Must always be supported, add unconditionally
+                final Size vgaSize = new Size(640, 480);
+                maxPrivSizes[VGA] = vgaSize;
+                maxYuvSizes[VGA] = vgaSize;
+                maxJpegSizes[VGA] = vgaSize;
+            }
+
+            StreamConfigurationMap configs = sm.getCharacteristics().get(
+                    CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+            Size[] privInputSizes = configs.getInputSizes(ImageFormat.PRIVATE);
+            maxInputPrivSize = privInputSizes != null ?
+                    CameraTestUtils.getMaxSize(privInputSizes) : null;
+            Size[] yuvInputSizes = configs.getInputSizes(ImageFormat.YUV_420_888);
+            maxInputYuvSize = yuvInputSizes != null ?
+                    CameraTestUtils.getMaxSize(yuvInputSizes) : null;
+
+        }
+
+        public final Size[] maxPrivSizes = new Size[RESOLUTION_COUNT];
+        public final Size[] maxJpegSizes = new Size[RESOLUTION_COUNT];
+        public final Size[] maxYuvSizes = new Size[RESOLUTION_COUNT];
+        public final Size maxRawSize;
+        // TODO: support non maximum reprocess input.
+        public final Size maxInputPrivSize;
+        public final Size maxInputYuvSize;
+
+        static public String configToString(int[] config) {
+            StringBuilder b = new StringBuilder("{ ");
+            for (int i = 0; i < config.length; i += 2) {
+                int format = config[i];
+                int sizeLimit = config[i + 1];
+
+                appendFormatSize(b, format, sizeLimit);
+                b.append(" ");
+            }
+            b.append("}");
+            return b.toString();
+        }
+
+        static public String reprocessConfigToString(int[] reprocessConfig) {
+            // reprocessConfig[0..1] is the input configuration
+            StringBuilder b = new StringBuilder("Input: ");
+            appendFormatSize(b, reprocessConfig[0], reprocessConfig[1]);
+
+            // reprocessConfig[0..1] is also output configuration to be captured as reprocess input.
+            b.append(", Outputs: { ");
+            for (int i = 0; i < reprocessConfig.length; i += 2) {
+                int format = reprocessConfig[i];
+                int sizeLimit = reprocessConfig[i + 1];
+
+                appendFormatSize(b, format, sizeLimit);
+                b.append(" ");
+            }
+            b.append("}");
+            return b.toString();
+        }
+
+        static private void appendFormatSize(StringBuilder b, int format, int Size) {
+            switch (format) {
+                case PRIV:
+                    b.append("[PRIV, ");
+                    break;
+                case JPEG:
+                    b.append("[JPEG, ");
+                    break;
+                case YUV:
+                    b.append("[YUV, ");
+                    break;
+                case RAW:
+                    b.append("[RAW, ");
+                    break;
+                default:
+                    b.append("[UNK, ");
+                    break;
+            }
+
+            switch (Size) {
+                case PREVIEW:
+                    b.append("PREVIEW]");
+                    break;
+                case RECORD:
+                    b.append("RECORD]");
+                    break;
+                case MAXIMUM:
+                    b.append("MAXIMUM]");
+                    break;
+                case VGA:
+                    b.append("VGA]");
+                    break;
+                default:
+                    b.append("UNK]");
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Return an InputConfiguration for a given reprocess configuration.
+     */
+    private InputConfiguration getInputConfig(int[] reprocessConfig, MaxStreamSizes maxSizes) {
+        int format;
+        Size size;
+
+        if (reprocessConfig[1] != MAXIMUM) {
+            throw new IllegalArgumentException("Test only supports MAXIMUM input");
+        }
+
+        switch (reprocessConfig[0]) {
+            case PRIV:
+                format = ImageFormat.PRIVATE;
+                size = maxSizes.maxInputPrivSize;
+                break;
+            case YUV:
+                format = ImageFormat.YUV_420_888;
+                size = maxSizes.maxInputYuvSize;
+                break;
+            default:
+                throw new IllegalArgumentException("Input format not supported: " +
+                        reprocessConfig[0]);
+        }
+
+        return new InputConfiguration(size.getWidth(), size.getHeight(), format);
+    }
+
+    private void testReprocessStreamCombination(String cameraId, int[] reprocessConfig,
+            MaxStreamSizes maxSizes, StaticMetadata staticInfo) throws Exception {
+
+        Log.i(TAG, String.format("Testing Camera %s, reprocess config: %s", cameraId,
+                MaxStreamSizes.reprocessConfigToString(reprocessConfig)));
+
+        final int TIMEOUT_FOR_RESULT_MS = 3000;
+        final int NUM_REPROCESS_CAPTURES_PER_CONFIG = 3;
+
+        List<SurfaceTexture> privTargets = new ArrayList<>();
+        List<ImageReader> jpegTargets = new ArrayList<>();
+        List<ImageReader> yuvTargets = new ArrayList<>();
+        List<ImageReader> rawTargets = new ArrayList<>();
+        List<Surface> outputSurfaces = new ArrayList<>();
+        ImageReader inputReader = null;
+        ImageWriter inputWriter = null;
+        SimpleImageReaderListener inputReaderListener = new SimpleImageReaderListener();
+        SimpleCaptureCallback inputCaptureListener = new SimpleCaptureCallback();
+        SimpleCaptureCallback reprocessOutputCaptureListener = new SimpleCaptureCallback();
+
+        boolean supportYuvReprocess = staticInfo.isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING);
+        boolean supportOpaqueReprocess = staticInfo.isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING);
+
+        // Skip the configuration if the format is not supported for reprocessing.
+        if ((reprocessConfig[0] == YUV && !supportYuvReprocess) ||
+                (reprocessConfig[0] == PRIV && !supportOpaqueReprocess)) {
+            return;
+        }
+
+        try {
+            // reprocessConfig[2..] are additional outputs
+            setupConfigurationTargets(
+                    Arrays.copyOfRange(reprocessConfig, 2, reprocessConfig.length),
+                    maxSizes, privTargets, jpegTargets, yuvTargets, rawTargets, outputSurfaces,
+                    NUM_REPROCESS_CAPTURES_PER_CONFIG);
+
+            // reprocessConfig[0:1] is input
+            InputConfiguration inputConfig = getInputConfig(
+                    Arrays.copyOfRange(reprocessConfig, 0, 2), maxSizes);
+
+            // For each config, YUV and JPEG outputs will be tested. (For YUV reprocessing,
+            // the YUV ImageReader for input is also used for output.)
+            final int totalNumReprocessCaptures =  NUM_REPROCESS_CAPTURES_PER_CONFIG * (
+                    (inputConfig.getFormat() == ImageFormat.YUV_420_888 ? 1 : 0) +
+                    jpegTargets.size() + yuvTargets.size());
+
+            // It needs 1 input buffer for each reprocess capture + the number of buffers
+            // that will be used as outputs.
+            inputReader = ImageReader.newInstance(inputConfig.getWidth(), inputConfig.getHeight(),
+                    inputConfig.getFormat(),
+                    totalNumReprocessCaptures + NUM_REPROCESS_CAPTURES_PER_CONFIG);
+            inputReader.setOnImageAvailableListener(inputReaderListener, mHandler);
+            outputSurfaces.add(inputReader.getSurface());
+
+            // Verify we can create a reprocessable session with the input and all outputs.
+            BlockingSessionCallback sessionListener = new BlockingSessionCallback();
+            CameraCaptureSession session = configureReprocessableCameraSession(mCamera,
+                    inputConfig, outputSurfaces, sessionListener, mHandler);
+            inputWriter = ImageWriter.newInstance(session.getInputSurface(),
+                    totalNumReprocessCaptures);
+
+            // Prepare a request for reprocess input
+            CaptureRequest.Builder builder = mCamera.createCaptureRequest(
+                    CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
+            builder.addTarget(inputReader.getSurface());
+
+            for (int i = 0; i < totalNumReprocessCaptures; i++) {
+                session.capture(builder.build(), inputCaptureListener, mHandler);
+            }
+
+            List<CaptureRequest> reprocessRequests = new ArrayList<>();
+            List<Surface> reprocessOutputs = new ArrayList<>();
+            if (inputConfig.getFormat() == ImageFormat.YUV_420_888) {
+                reprocessOutputs.add(inputReader.getSurface());
+            }
+
+            for (ImageReader reader : jpegTargets) {
+                reprocessOutputs.add(reader.getSurface());
+            }
+
+            for (ImageReader reader : yuvTargets) {
+                reprocessOutputs.add(reader.getSurface());
+            }
+
+            for (int i = 0; i < NUM_REPROCESS_CAPTURES_PER_CONFIG; i++) {
+                for (Surface output : reprocessOutputs) {
+                    TotalCaptureResult result = inputCaptureListener.getTotalCaptureResult(
+                            TIMEOUT_FOR_RESULT_MS);
+                    builder =  mCamera.createReprocessCaptureRequest(result);
+                    inputWriter.queueInputImage(
+                            inputReaderListener.getImage(TIMEOUT_FOR_RESULT_MS));
+                    builder.addTarget(output);
+                    reprocessRequests.add(builder.build());
+                }
+            }
+
+            session.captureBurst(reprocessRequests, reprocessOutputCaptureListener, mHandler);
+
+            for (int i = 0; i < reprocessOutputs.size() * NUM_REPROCESS_CAPTURES_PER_CONFIG; i++) {
+                TotalCaptureResult result = reprocessOutputCaptureListener.getTotalCaptureResult(
+                        TIMEOUT_FOR_RESULT_MS);
+            }
+        } catch (Throwable e) {
+            mCollector.addMessage(String.format("Reprocess stream combination %s failed due to: %s",
+                    MaxStreamSizes.reprocessConfigToString(reprocessConfig), e.getMessage()));
+        } finally {
+            inputReaderListener.drain();
+            reprocessOutputCaptureListener.drain();
+
+            for (SurfaceTexture target : privTargets) {
+                target.release();
+            }
+
+            for (ImageReader target : jpegTargets) {
+                target.close();
+            }
+
+            for (ImageReader target : yuvTargets) {
+                target.close();
+            }
+
+            for (ImageReader target : rawTargets) {
+                target.close();
+            }
+
+            if (inputReader != null) {
+                inputReader.close();
+            }
+
+            if (inputWriter != null) {
+                inputWriter.close();
+            }
+        }
+    }
+
+    private void testOutputCombination(String cameraId, int[] config, MaxStreamSizes maxSizes)
+            throws Exception {
+
+        Log.i(TAG, String.format("Testing Camera %s, config %s",
+                        cameraId, MaxStreamSizes.configToString(config)));
+
+        // Timeout is relaxed by 1 second for LEGACY devices to reduce false positive rate in CTS
+        final int TIMEOUT_FOR_RESULT_MS = (mStaticInfo.isHardwareLevelLegacy()) ? 2000 : 1000;
+        final int MIN_RESULT_COUNT = 3;
+
+        // Set up outputs
+        List<Surface> outputSurfaces = new ArrayList<Surface>();
+        List<SurfaceTexture> privTargets = new ArrayList<SurfaceTexture>();
+        List<ImageReader> jpegTargets = new ArrayList<ImageReader>();
+        List<ImageReader> yuvTargets = new ArrayList<ImageReader>();
+        List<ImageReader> rawTargets = new ArrayList<ImageReader>();
+
+        setupConfigurationTargets(config, maxSizes, privTargets, jpegTargets, yuvTargets,
+                rawTargets, outputSurfaces, MIN_RESULT_COUNT);
+
+        boolean haveSession = false;
+        try {
+            CaptureRequest.Builder requestBuilder =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+            for (Surface s : outputSurfaces) {
+                requestBuilder.addTarget(s);
+            }
+
+            CameraCaptureSession.CaptureCallback mockCaptureCallback =
+                    mock(CameraCaptureSession.CaptureCallback.class);
+
+            createSession(outputSurfaces);
+            haveSession = true;
+            CaptureRequest request = requestBuilder.build();
+            mCameraSession.setRepeatingRequest(request, mockCaptureCallback, mHandler);
+
+            verify(mockCaptureCallback,
+                    timeout(TIMEOUT_FOR_RESULT_MS * MIN_RESULT_COUNT).atLeast(MIN_RESULT_COUNT))
+                    .onCaptureCompleted(
+                        eq(mCameraSession),
+                        eq(request),
+                        isA(TotalCaptureResult.class));
+            verify(mockCaptureCallback, never()).
+                    onCaptureFailed(
+                        eq(mCameraSession),
+                        eq(request),
+                        isA(CaptureFailure.class));
+
+        } catch (Throwable e) {
+            mCollector.addMessage(String.format("Output combination %s failed due to: %s",
+                    MaxStreamSizes.configToString(config), e.getMessage()));
+        }
+        if (haveSession) {
+            try {
+                Log.i(TAG, String.format("Done with camera %s, config %s, closing session",
+                                cameraId, MaxStreamSizes.configToString(config)));
+                stopCapture(/*fast*/false);
+            } catch (Throwable e) {
+                mCollector.addMessage(
+                    String.format("Closing down for output combination %s failed due to: %s",
+                            MaxStreamSizes.configToString(config), e.getMessage()));
+            }
+        }
+
+        for (SurfaceTexture target : privTargets) {
+            target.release();
+        }
+        for (ImageReader target : jpegTargets) {
+            target.close();
+        }
+        for (ImageReader target : yuvTargets) {
+            target.close();
+        }
+        for (ImageReader target : rawTargets) {
+            target.close();
+        }
+    }
+
+    private void setupConfigurationTargets(int[] outputConfigs, MaxStreamSizes maxSizes,
+            List<SurfaceTexture> privTargets, List<ImageReader> jpegTargets,
+            List<ImageReader> yuvTargets, List<ImageReader> rawTargets,
+            List<Surface> outputSurfaces, int numBuffers) {
+
+        ImageDropperListener imageDropperListener = new ImageDropperListener();
+
+        for (int i = 0; i < outputConfigs.length; i += 2) {
+            int format = outputConfigs[i];
+            int sizeLimit = outputConfigs[i + 1];
+
+            switch (format) {
+                case PRIV: {
+                    Size targetSize = maxSizes.maxPrivSizes[sizeLimit];
+                    SurfaceTexture target = new SurfaceTexture(/*random int*/1);
+                    target.setDefaultBufferSize(targetSize.getWidth(), targetSize.getHeight());
+                    outputSurfaces.add(new Surface(target));
+                    privTargets.add(target);
+                    break;
+                }
+                case JPEG: {
+                    Size targetSize = maxSizes.maxJpegSizes[sizeLimit];
+                    ImageReader target = ImageReader.newInstance(
+                        targetSize.getWidth(), targetSize.getHeight(), JPEG, numBuffers);
+                    target.setOnImageAvailableListener(imageDropperListener, mHandler);
+                    outputSurfaces.add(target.getSurface());
+                    jpegTargets.add(target);
+                    break;
+                }
+                case YUV: {
+                    Size targetSize = maxSizes.maxYuvSizes[sizeLimit];
+                    ImageReader target = ImageReader.newInstance(
+                        targetSize.getWidth(), targetSize.getHeight(), YUV, numBuffers);
+                    target.setOnImageAvailableListener(imageDropperListener, mHandler);
+                    outputSurfaces.add(target.getSurface());
+                    yuvTargets.add(target);
+                    break;
+                }
+                case RAW: {
+                    Size targetSize = maxSizes.maxRawSize;
+                    ImageReader target = ImageReader.newInstance(
+                        targetSize.getWidth(), targetSize.getHeight(), RAW, numBuffers);
+                    target.setOnImageAvailableListener(imageDropperListener, mHandler);
+                    outputSurfaces.add(target.getSurface());
+                    rawTargets.add(target);
+                    break;
+                }
+                default:
+                    fail("Unknown output format " + format);
+            }
+        }
+    }
+
+    private static Size getMaxRecordingSize(String cameraId) {
+        int id = Integer.valueOf(cameraId);
+
+        int quality =
+                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_2160P) ?
+                    CamcorderProfile.QUALITY_2160P :
+                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_1080P) ?
+                    CamcorderProfile.QUALITY_1080P :
+                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_720P) ?
+                    CamcorderProfile.QUALITY_720P :
+                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_480P) ?
+                    CamcorderProfile.QUALITY_480P :
+                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_QVGA) ?
+                    CamcorderProfile.QUALITY_QVGA :
+                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_CIF) ?
+                    CamcorderProfile.QUALITY_CIF :
+                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_QCIF) ?
+                    CamcorderProfile.QUALITY_QCIF :
+                    -1;
+
+        assertTrue("No recording supported for camera id " + cameraId, quality != -1);
+
+        CamcorderProfile maxProfile = CamcorderProfile.get(id, quality);
+        return new Size(maxProfile.videoFrameWidth, maxProfile.videoFrameHeight);
+    }
+
+    /**
+     * Get maximum size in list that's equal or smaller to than the bound.
+     * Returns null if no size is smaller than or equal to the bound.
+     */
+    private static Size getMaxSize(Size[] sizes, Size bound) {
+        if (sizes == null || sizes.length == 0) {
+            throw new IllegalArgumentException("sizes was empty");
+        }
+
+        Size sz = null;
+        for (Size size : sizes) {
+            if (size.getWidth() <= bound.getWidth() && size.getHeight() <= bound.getHeight()) {
+
+                if (sz == null) {
+                    sz = size;
+                } else {
+                    long curArea = sz.getWidth() * (long) sz.getHeight();
+                    long newArea = size.getWidth() * (long) size.getHeight();
+                    if ( newArea > curArea ) {
+                        sz = size;
+                    }
+                }
+            }
+        }
+
+        assertTrue("No size under bound found: " + Arrays.toString(sizes) + " bound " + bound,
+                sz != null);
+
+        return sz;
+    }
+
+    private static Size getMaxPreviewSize(Context context, String cameraId) {
+        try {
+            WindowManager windowManager =
+                (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+            Display display = windowManager.getDefaultDisplay();
+
+            int width = display.getWidth();
+            int height = display.getHeight();
+
+            if (height > width) {
+                height = width;
+                width = display.getHeight();
+            }
+
+            CameraManager camMgr =
+                (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+            List<Size> orderedPreviewSizes = CameraTestUtils.getSupportedPreviewSizes(
+                cameraId, camMgr, PREVIEW_SIZE_BOUND);
+
+            if (orderedPreviewSizes != null) {
+                for (Size size : orderedPreviewSizes) {
+                    if (width >= size.getWidth() &&
+                        height >= size.getHeight())
+                        return size;
+                }
+            }
+        } catch (Exception e) {
+            Log.e(TAG, "getMaxPreviewSize Failed. "+e.toString());
+        }
+        return PREVIEW_SIZE_BOUND;
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/StaticMetadataCollectionTest.java b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataCollectionTest.java
new file mode 100644
index 0000000..145c2d1
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataCollectionTest.java
@@ -0,0 +1,181 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import android.content.pm.PackageManager;
+import android.cts.util.DeviceReportLog;
+import android.hardware.camera2.cts.helpers.CameraMetadataGetter;
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.util.Log;
+
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.util.Iterator;
+
+/**
+ * This test collects camera2 API static metadata and reports to device report.
+ *
+ */
+public class StaticMetadataCollectionTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "StaticMetadataCollectionTest";
+
+    private DeviceReportLog mReportLog;
+
+    @Override
+    protected void setUp() throws Exception {
+        mReportLog = new DeviceReportLog();
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Deliver the report to host will automatically clear the report log.
+        mReportLog.deliverReportToHost(getInstrumentation());
+        super.tearDown();
+    }
+
+    public void testDataCollection() {
+        if (hasCameraFeature()) {
+            CameraMetadataGetter cameraInfoGetter = new CameraMetadataGetter(mCameraManager);
+            for (String id : mCameraIds) {
+                // Gather camera info
+                JSONObject cameraInfo = cameraInfoGetter.getCameraInfo(id);
+                dumpJsonObjectAsCtsResult(String.format("camera2_id%s_static_info", id), cameraInfo);
+                dumpDoubleAsCtsResult(String.format("camera2_id%s_static_info:", id)
+                        + cameraInfo.toString(), 0);
+
+                JSONObject[] templates = cameraInfoGetter.getCaptureRequestTemplates(id);
+                for (int i = 0; i < templates.length; i++) {
+                    dumpJsonObjectAsCtsResult(String.format("camera2_id%s_capture_template%d",
+                            id, CameraMetadataGetter.TEMPLATE_IDS[i]), templates[i]);
+                    if (templates[i] != null) {
+                        dumpDoubleAsCtsResult(String.format("camera2_id%s_capture_template%d:",
+                                id, CameraMetadataGetter.TEMPLATE_IDS[i])
+                                + templates[i].toString(), 0);
+                    }
+                }
+            }
+
+            try {
+                cameraInfoGetter.close();
+            } catch (Exception e) {
+                Log.e(TAG, "Unable to close camera info getter " + e.getMessage());
+            }
+
+            mReportLog.printSummary("Camera data collection for static info and capture request"
+                    + " templates",
+                    0.0, ResultType.NEUTRAL, ResultUnit.NONE);
+        }
+
+    }
+
+    private void dumpDoubleAsCtsResult(String name, double value) {
+        mReportLog.printValue(name, value, ResultType.NEUTRAL, ResultUnit.NONE);
+    }
+
+    public void dumpDoubleArrayAsCtsResult(String name, double[] values) {
+        mReportLog.printArray(name, values, ResultType.NEUTRAL, ResultUnit.NONE);
+    }
+
+    private double getJsonValueAsDouble(String name, Object obj) throws Exception {
+        if (obj == null) {
+            Log.e(TAG, "Null value: " + name);
+            throw new Exception();
+        } else if (obj instanceof Double) {
+            return ((Double)obj).doubleValue();
+        } else if (obj instanceof Float) {
+            return ((Float)obj).floatValue();
+        } else if (obj instanceof Long) {
+            return ((Long)obj).longValue();
+        } else if (obj instanceof Integer) {
+            return ((Integer)obj).intValue();
+        } else if (obj instanceof Byte) {
+            return ((Byte)obj).intValue();
+        } else if (obj instanceof Short) {
+            return ((Short)obj).intValue();
+        } else if (obj instanceof Boolean) {
+            return ((Boolean)obj) ? 1 : 0;
+        } else {
+            Log.e(TAG, "Unsupported value type: " + name);
+            throw new Exception();
+        }
+    }
+
+    private void dumpJsonArrayAsCtsResult(String name, JSONArray arr) throws Exception {
+        if (arr == null || arr.length() == 0) {
+            dumpDoubleAsCtsResult(name + "[]", 0);
+        } else if (arr.get(0) instanceof JSONObject) {
+            for (int i = 0; i < arr.length(); i++) {
+                dumpJsonObjectAsCtsResult(name+String.format("[%04d]",i),(JSONObject)arr.get(i));
+            }
+        } else if (arr.get(0) instanceof JSONArray) {
+            for (int i = 0; i < arr.length(); i++) {
+                dumpJsonArrayAsCtsResult(name+String.format("[%04d]",i),(JSONArray)arr.get(i));
+            }
+        } else if (!(arr.get(0) instanceof String)) {
+            double[] values = new double[arr.length()];
+            for (int i = 0; i < arr.length(); i++) {
+                values[i] = getJsonValueAsDouble(name + "[]", arr.get(i));
+            }
+            dumpDoubleArrayAsCtsResult(name + "[]", values);
+        } else if (arr.get(0) instanceof String) {
+            for (int i = 0; i < arr.length(); i++) {
+                dumpDoubleAsCtsResult(
+                        name+String.format("[%04d]",i)+" = "+(String)arr.get(i), 0);
+            }
+        } else {
+            Log.e(TAG, "Unsupported array value type: " + name);
+            throw new Exception();
+        }
+    }
+
+    private void dumpJsonObjectAsCtsResult(String name, JSONObject obj) {
+        if (obj == null) {
+            dumpDoubleAsCtsResult(name + "{}", 0);
+            return;
+        }
+        Iterator<?> keys = obj.keys();
+        while (keys.hasNext()) {
+            try {
+                String key = (String)keys.next();
+                if (obj.get(key) instanceof JSONObject) {
+                    dumpJsonObjectAsCtsResult(name+"."+key, (JSONObject)obj.get(key));
+                } else if (obj.get(key) instanceof JSONArray) {
+                    dumpJsonArrayAsCtsResult(name+"."+key, (JSONArray)obj.get(key));
+                } else if (!(obj.get(key) instanceof String)) {
+                    dumpDoubleAsCtsResult(name+"."+key,
+                            getJsonValueAsDouble(name+"."+key, obj.get(key)));
+                } else if (obj.get(key) instanceof String) {
+                    dumpDoubleAsCtsResult(name+"."+key + " = " + (String)obj.get(key), 0);
+                } else {
+                    Log.e(TAG, "Unsupported object field type: " + name + "." + key);
+                }
+            } catch (Exception e) {
+                // Swallow
+            }
+        }
+    }
+
+    private boolean hasCameraFeature() {
+        PackageManager packageManager = getActivity().getPackageManager();
+        return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
new file mode 100644
index 0000000..3e3e81e
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/StaticMetadataTest.java
@@ -0,0 +1,545 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.CameraCharacteristics.*;
+
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.CameraCharacteristics.Key;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
+import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Size;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * <p>
+ * This class covers the {@link CameraCharacteristics} tests that are not
+ * covered by {@link CaptureRequestTest} and {@link ExtendedCameraCharacteristicsTest}
+ * </p>
+ * <p>
+ * Note that most of the tests in this class don't require camera open.
+ * </p>
+ */
+public class StaticMetadataTest extends Camera2AndroidTestCase {
+    private static final String TAG = "StaticMetadataTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final float MIN_FPS_FOR_FULL_DEVICE = 20.0f;
+    private String mCameraId;
+
+    // Last defined capability enum, for iterating over all of them
+    private static final int LAST_CAPABILITY_ENUM = REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE;
+
+    /**
+     * Test the available capability for different hardware support level devices.
+     */
+    public void testHwSupportedLevel() throws Exception {
+        Key<StreamConfigurationMap> key =
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
+        final float SIZE_ERROR_MARGIN = 0.03f;
+        for (String id : mCameraIds) {
+            initStaticMetadata(id);
+            StreamConfigurationMap configs = mStaticInfo.getValueFromKeyNonNull(key);
+            Rect activeRect = mStaticInfo.getActiveArraySizeChecked();
+            Size sensorSize = new Size(activeRect.width(), activeRect.height());
+            List<Integer> availableCaps = mStaticInfo.getAvailableCapabilitiesChecked();
+
+            mCollector.expectTrue("All devices must contains BACKWARD_COMPATIBLE capability or " +
+                    "DEPTH_OUTPUT capabillity" ,
+                    availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE) ||
+                    availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT) );
+
+            if (mStaticInfo.isHardwareLevelFull()) {
+                // Capability advertisement must be right.
+                mCollector.expectTrue("Full device must contain MANUAL_SENSOR capability",
+                        availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR));
+                mCollector.expectTrue("Full device must contain MANUAL_POST_PROCESSING capability",
+                        availableCaps.contains(
+                                REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING));
+                mCollector.expectTrue("Full device must contain BURST_CAPTURE capability",
+                        availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE));
+
+                // Need support per frame control
+                mCollector.expectTrue("Full device must support per frame control",
+                        mStaticInfo.isPerFrameControlSupported());
+            }
+
+            if (mStaticInfo.isHardwareLevelLegacy()) {
+                mCollector.expectTrue("Legacy devices must contain BACKWARD_COMPATIBLE capability",
+                        availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE));
+            }
+
+            if (availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                mCollector.expectTrue("MANUAL_SENSOR capability always requires " +
+                        "READ_SENSOR_SETTINGS capability as well",
+                        availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS));
+            }
+
+            if (mStaticInfo.isColorOutputSupported()) {
+                // Max jpeg resolution must be very close to  sensor resolution
+                Size[] jpegSizes = mStaticInfo.getJpegOutputSizesChecked();
+                Size maxJpegSize = CameraTestUtils.getMaxSize(jpegSizes);
+                mCollector.expectSizesAreSimilar(
+                    "Active array size and max JPEG size should be similar",
+                    sensorSize, maxJpegSize, SIZE_ERROR_MARGIN);
+            }
+
+            // TODO: test all the keys mandatory for all capability devices.
+        }
+    }
+
+    /**
+     * Test max number of output stream reported by device
+     */
+    public void testMaxNumOutputStreams() throws Exception {
+        for (String id : mCameraIds) {
+            initStaticMetadata(id);
+            int maxNumStreamsRaw = mStaticInfo.getMaxNumOutputStreamsRawChecked();
+            int maxNumStreamsProc = mStaticInfo.getMaxNumOutputStreamsProcessedChecked();
+            int maxNumStreamsProcStall = mStaticInfo.getMaxNumOutputStreamsProcessedStallChecked();
+
+            mCollector.expectTrue("max number of raw output streams must be a non negative number",
+                    maxNumStreamsRaw >= 0);
+            mCollector.expectTrue("max number of processed (stalling) output streams must be >= 1",
+                    maxNumStreamsProcStall >= 1);
+
+            if (mStaticInfo.isHardwareLevelFull()) {
+                mCollector.expectTrue("max number of processed (non-stalling) output streams" +
+                        "must be >= 3 for FULL device",
+                        maxNumStreamsProc >= 3);
+            } else if (mStaticInfo.isColorOutputSupported()) {
+                mCollector.expectTrue("max number of processed (non-stalling) output streams" +
+                        "must be >= 2 for devices that support color output",
+                        maxNumStreamsProc >= 2);
+            }
+        }
+
+    }
+
+    /**
+     * Test advertised capability does match available keys and vice versa
+     */
+    public void testCapabilities() throws Exception {
+        for (String id : mCameraIds) {
+            initStaticMetadata(id);
+            List<Integer> availableCaps = mStaticInfo.getAvailableCapabilitiesChecked();
+
+            for (Integer capability = REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE;
+                    capability <= LAST_CAPABILITY_ENUM; capability++) {
+                boolean isCapabilityAvailable = availableCaps.contains(capability);
+                validateCapability(capability, isCapabilityAvailable);
+            }
+            // Note: Static metadata for capabilities is tested in ExtendedCameraCharacteristicsTest
+        }
+    }
+
+    /**
+     * Check if request keys' presence match expectation.
+     *
+     * @param capabilityName The name string of capability being tested. Used for output messages.
+     * @param requestKeys The capture request keys to be checked
+     * @param expectedPresence Expected presence of {@code requestKeys}. {@code true} for expecting
+     *        all keys are available. Otherwise {@code false}
+     * @return {@code true} if request keys' presence match expectation. Otherwise {@code false}
+     */
+    private boolean validateRequestKeysPresence(String capabilityName,
+            Collection<CaptureRequest.Key<?>> requestKeys, boolean expectedPresence) {
+        boolean actualPresence = mStaticInfo.areRequestKeysAvailable(requestKeys);
+        if (expectedPresence != actualPresence) {
+            if (expectedPresence) {
+                for (CaptureRequest.Key<?> key : requestKeys) {
+                    if (!mStaticInfo.areKeysAvailable(key)) {
+                        mCollector.addMessage(String.format(
+                                "Camera %s list capability %s but doesn't contain request key %s",
+                                mCameraId, capabilityName, key.getName()));
+                    }
+                }
+            } else {
+                Log.w(TAG, String.format(
+                        "Camera %s doesn't list capability %s but contain all required keys",
+                        mCameraId, capabilityName));
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Check if result keys' presence match expectation.
+     *
+     * @param capabilityName The name string of capability being tested. Used for output messages.
+     * @param resultKeys The capture result keys to be checked
+     * @param expectedPresence Expected presence of {@code resultKeys}. {@code true} for expecting
+     *        all keys are available. Otherwise {@code false}
+     * @return {@code true} if result keys' presence match expectation. Otherwise {@code false}
+     */
+    private boolean validateResultKeysPresence(String capabilityName,
+            Collection<CaptureResult.Key<?>> resultKeys, boolean expectedPresence) {
+        boolean actualPresence = mStaticInfo.areResultKeysAvailable(resultKeys);
+        if (expectedPresence != actualPresence) {
+            if (expectedPresence) {
+                for (CaptureResult.Key<?> key : resultKeys) {
+                    if (!mStaticInfo.areKeysAvailable(key)) {
+                        mCollector.addMessage(String.format(
+                                "Camera %s list capability %s but doesn't contain result key %s",
+                                mCameraId, capabilityName, key.getName()));
+                    }
+                }
+            } else {
+                Log.w(TAG, String.format(
+                        "Camera %s doesn't list capability %s but contain all required keys",
+                        mCameraId, capabilityName));
+            }
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Check if characteristics keys' presence match expectation.
+     *
+     * @param capabilityName The name string of capability being tested. Used for output messages.
+     * @param characteristicsKeys The characteristics keys to be checked
+     * @param expectedPresence Expected presence of {@code characteristicsKeys}. {@code true} for
+     *        expecting all keys are available. Otherwise {@code false}
+     * @return {@code true} if characteristics keys' presence match expectation.
+     *         Otherwise {@code false}
+     */
+    private boolean validateCharacteristicsKeysPresence(String capabilityName,
+            Collection<CameraCharacteristics.Key<?>> characteristicsKeys,
+            boolean expectedPresence) {
+        boolean actualPresence = mStaticInfo.areCharacteristicsKeysAvailable(characteristicsKeys);
+        if (expectedPresence != actualPresence) {
+            if (expectedPresence) {
+                for (CameraCharacteristics.Key<?> key : characteristicsKeys) {
+                    if (!mStaticInfo.areKeysAvailable(key)) {
+                        mCollector.addMessage(String.format(
+                                "Camera %s list capability %s but doesn't contain" +
+                                "characteristics key %s",
+                                mCameraId, capabilityName, key.getName()));
+                    }
+                }
+            } else {
+                Log.w(TAG, String.format(
+                        "Camera %s doesn't list capability %s but contain all required keys",
+                        mCameraId, capabilityName));
+            }
+            return false;
+        }
+        return true;
+    }
+
+    private void validateCapability(Integer capability, boolean isCapabilityAvailable) {
+        List<CaptureRequest.Key<?>> requestKeys = new ArrayList<>();
+        Set<CaptureResult.Key<?>> resultKeys = new HashSet<>();
+        // Capability requirements other than key presences
+        List<Pair<String, Boolean>> additionalRequirements = new ArrayList<>();
+
+        /* For available capabilities, only check request keys in this test
+           Characteristics keys are tested in ExtendedCameraCharacteristicsTest
+           Result keys are tested in CaptureResultTest */
+        String capabilityName;
+        switch (capability) {
+            case REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE:
+                capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE";
+                requestKeys.add(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE);
+                requestKeys.add(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION);
+                requestKeys.add(CaptureRequest.CONTROL_AE_MODE);
+                requestKeys.add(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
+                requestKeys.add(CaptureRequest.CONTROL_AF_MODE);
+                requestKeys.add(CaptureRequest.CONTROL_AF_TRIGGER);
+                requestKeys.add(CaptureRequest.CONTROL_AWB_MODE);
+                requestKeys.add(CaptureRequest.CONTROL_CAPTURE_INTENT);
+                requestKeys.add(CaptureRequest.CONTROL_EFFECT_MODE);
+                requestKeys.add(CaptureRequest.CONTROL_MODE);
+                requestKeys.add(CaptureRequest.CONTROL_SCENE_MODE);
+                requestKeys.add(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE);
+                requestKeys.add(CaptureRequest.FLASH_MODE);
+                requestKeys.add(CaptureRequest.JPEG_GPS_LOCATION);
+                requestKeys.add(CaptureRequest.JPEG_ORIENTATION);
+                requestKeys.add(CaptureRequest.JPEG_QUALITY);
+                requestKeys.add(CaptureRequest.JPEG_THUMBNAIL_QUALITY);
+                requestKeys.add(CaptureRequest.JPEG_THUMBNAIL_SIZE);
+                requestKeys.add(CaptureRequest.SCALER_CROP_REGION);
+                requestKeys.add(CaptureRequest.STATISTICS_FACE_DETECT_MODE);
+                if (mStaticInfo.getAeMaxRegionsChecked() > 0) {
+                    requestKeys.add(CaptureRequest.CONTROL_AE_REGIONS);
+                } else {
+                    mCollector.expectTrue(
+                            "CONTROL_AE_REGIONS is available but aeMaxRegion is 0",
+                            !mStaticInfo.areKeysAvailable(CaptureRequest.CONTROL_AE_REGIONS));
+                }
+                if (mStaticInfo.getAwbMaxRegionsChecked() > 0) {
+                    requestKeys.add(CaptureRequest.CONTROL_AWB_REGIONS);
+                } else {
+                    mCollector.expectTrue(
+                            "CONTROL_AWB_REGIONS is available but awbMaxRegion is 0",
+                            !mStaticInfo.areKeysAvailable(CaptureRequest.CONTROL_AWB_REGIONS));
+                }
+                if (mStaticInfo.getAfMaxRegionsChecked() > 0) {
+                    requestKeys.add(CaptureRequest.CONTROL_AF_REGIONS);
+                } else {
+                    mCollector.expectTrue(
+                            "CONTROL_AF_REGIONS is available but afMaxRegion is 0",
+                            !mStaticInfo.areKeysAvailable(CaptureRequest.CONTROL_AF_REGIONS));
+                }
+                break;
+            case REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING:
+                capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING";
+                requestKeys.add(CaptureRequest.TONEMAP_MODE);
+                requestKeys.add(CaptureRequest.COLOR_CORRECTION_GAINS);
+                requestKeys.add(CaptureRequest.COLOR_CORRECTION_TRANSFORM);
+                requestKeys.add(CaptureRequest.SHADING_MODE);
+                requestKeys.add(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE);
+                requestKeys.add(CaptureRequest.TONEMAP_CURVE);
+                requestKeys.add(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE);
+                requestKeys.add(CaptureRequest.CONTROL_AWB_LOCK);
+
+                // Legacy mode always doesn't support these requirements
+                Boolean contrastCurveModeSupported = false;
+                Boolean gammaAndPresetModeSupported = false;
+                Boolean offColorAberrationModeSupported = false;
+                if (mStaticInfo.isHardwareLevelLimitedOrBetter() && mStaticInfo.isColorOutputSupported()) {
+                    int[] tonemapModes = mStaticInfo.getAvailableToneMapModesChecked();
+                    List<Integer> modeList = (tonemapModes.length == 0) ?
+                            new ArrayList<Integer>() :
+                            Arrays.asList(CameraTestUtils.toObject(tonemapModes));
+                    contrastCurveModeSupported =
+                            modeList.contains(CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE);
+                    gammaAndPresetModeSupported =
+                            modeList.contains(CameraMetadata.TONEMAP_MODE_GAMMA_VALUE) &&
+                            modeList.contains(CameraMetadata.TONEMAP_MODE_PRESET_CURVE);
+
+                    int[] colorAberrationModes =
+                            mStaticInfo.getAvailableColorAberrationModesChecked();
+                    modeList = (colorAberrationModes.length == 0) ?
+                            new ArrayList<Integer>() :
+                            Arrays.asList(CameraTestUtils.toObject(colorAberrationModes));
+                    offColorAberrationModeSupported =
+                            modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF);
+                }
+                Boolean tonemapModeQualified =
+                        contrastCurveModeSupported || gammaAndPresetModeSupported;
+                additionalRequirements.add(new Pair<String, Boolean>(
+                        "Tonemap mode must include {CONTRAST_CURVE} and/or " +
+                        "{GAMMA_VALUE, PRESET_CURVE}",
+                        tonemapModeQualified));
+                additionalRequirements.add(new Pair<String, Boolean>(
+                        "Color aberration mode must include OFF", offColorAberrationModeSupported));
+                additionalRequirements.add(new Pair<String, Boolean>(
+                        "Must support AWB lock", mStaticInfo.isAwbLockSupported()));
+                break;
+            case REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR:
+                capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR";
+                requestKeys.add(CaptureRequest.CONTROL_AE_LOCK);
+                requestKeys.add(CaptureRequest.SENSOR_FRAME_DURATION);
+                requestKeys.add(CaptureRequest.SENSOR_EXPOSURE_TIME);
+                requestKeys.add(CaptureRequest.SENSOR_SENSITIVITY);
+                if (mStaticInfo.hasFocuser()) {
+                    requestKeys.add(CaptureRequest.LENS_APERTURE);
+                    requestKeys.add(CaptureRequest.LENS_FOCUS_DISTANCE);
+                    requestKeys.add(CaptureRequest.LENS_FILTER_DENSITY);
+                    requestKeys.add(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE);
+                }
+                requestKeys.add(CaptureRequest.BLACK_LEVEL_LOCK);
+                additionalRequirements.add(new Pair<String, Boolean>(
+                        "Must support AE lock", mStaticInfo.isAeLockSupported()));
+                break;
+            case REQUEST_AVAILABLE_CAPABILITIES_RAW:
+                // RAW_CAPABILITY needs to check for not just capture request keys
+                validateRawCapability(isCapabilityAvailable);
+                return;
+            case REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE:
+                // Tested in ExtendedCameraCharacteristicsTest
+                return;
+            case REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS:
+                capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS";
+                resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION);
+                resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME);
+                resultKeys.add(CaptureResult.SENSOR_SENSITIVITY);
+                if (mStaticInfo.hasFocuser()) {
+                    resultKeys.add(CaptureResult.LENS_APERTURE);
+                    resultKeys.add(CaptureResult.LENS_FOCUS_DISTANCE);
+                    resultKeys.add(CaptureResult.LENS_FILTER_DENSITY);
+                }
+                break;
+
+            case REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING:
+            case REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING:
+                // Tested in ExtendedCameraCharacteristicsTest
+                return;
+            case REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT:
+                // Tested in ExtendedCameracharacteristicsTest
+                return;
+            default:
+                capabilityName = "Unknown";
+                assertTrue(String.format("Unknown capability set: %d", capability),
+                           !isCapabilityAvailable);
+                return;
+        }
+
+        // Check additional requirements and exit early if possible
+        if (!isCapabilityAvailable) {
+            for (Pair<String, Boolean> p : additionalRequirements) {
+                String requirement = p.first;
+                Boolean meetRequirement = p.second;
+                // No further check is needed if we've found why capability cannot be advertised
+                if (!meetRequirement) {
+                    Log.v(TAG, String.format(
+                            "Camera %s doesn't list capability %s because of requirement: %s",
+                            mCameraId, capabilityName, requirement));
+                    return;
+                }
+            }
+        }
+
+        boolean matchExpectation = true;
+        if (!requestKeys.isEmpty()) {
+            matchExpectation &= validateRequestKeysPresence(
+                    capabilityName, requestKeys, isCapabilityAvailable);
+        }
+        if(!resultKeys.isEmpty()) {
+            matchExpectation &= validateResultKeysPresence(
+                    capabilityName, resultKeys, isCapabilityAvailable);
+        }
+
+        // Check additional requirements
+        for (Pair<String, Boolean> p : additionalRequirements) {
+            String requirement = p.first;
+            Boolean meetRequirement = p.second;
+            if (isCapabilityAvailable && !meetRequirement) {
+                mCollector.addMessage(String.format(
+                        "Camera %s list capability %s but does not meet the requirement: %s",
+                        mCameraId, capabilityName, requirement));
+            }
+        }
+
+        // In case of isCapabilityAvailable == true, error has been filed in
+        // validateRequest/ResultKeysPresence
+        if (!matchExpectation && !isCapabilityAvailable) {
+            mCollector.addMessage(String.format(
+                    "Camera %s doesn't list capability %s but meets all requirements",
+                    mCameraId, capabilityName));
+        }
+    }
+
+    private void validateRawCapability(boolean isCapabilityAvailable) {
+        String capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_RAW";
+
+        Set<CaptureRequest.Key<?>> requestKeys = new HashSet<>();
+        requestKeys.add(CaptureRequest.HOT_PIXEL_MODE);
+        requestKeys.add(CaptureRequest.STATISTICS_HOT_PIXEL_MAP_MODE);
+
+        Set<CameraCharacteristics.Key<?>> characteristicsKeys = new HashSet<>();
+        characteristicsKeys.add(HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES);
+        characteristicsKeys.add(SENSOR_BLACK_LEVEL_PATTERN);
+        characteristicsKeys.add(SENSOR_CALIBRATION_TRANSFORM1);
+        characteristicsKeys.add(SENSOR_CALIBRATION_TRANSFORM2);
+        characteristicsKeys.add(SENSOR_COLOR_TRANSFORM1);
+        characteristicsKeys.add(SENSOR_COLOR_TRANSFORM2);
+        characteristicsKeys.add(SENSOR_FORWARD_MATRIX1);
+        characteristicsKeys.add(SENSOR_FORWARD_MATRIX2);
+        characteristicsKeys.add(SENSOR_INFO_ACTIVE_ARRAY_SIZE);
+        characteristicsKeys.add(SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
+        characteristicsKeys.add(SENSOR_INFO_WHITE_LEVEL);
+        characteristicsKeys.add(SENSOR_REFERENCE_ILLUMINANT1);
+        characteristicsKeys.add(SENSOR_REFERENCE_ILLUMINANT2);
+        characteristicsKeys.add(STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES);
+
+        Set<CaptureResult.Key<?>> resultKeys = new HashSet<>();
+        resultKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
+        resultKeys.add(CaptureResult.SENSOR_GREEN_SPLIT);
+        resultKeys.add(CaptureResult.SENSOR_NOISE_PROFILE);
+
+        boolean rawOutputSupported = mStaticInfo.getRawOutputSizesChecked().length > 0;
+        boolean requestKeysPresent = mStaticInfo.areRequestKeysAvailable(requestKeys);
+        boolean characteristicsKeysPresent =
+                mStaticInfo.areCharacteristicsKeysAvailable(characteristicsKeys);
+        boolean resultKeysPresent = mStaticInfo.areResultKeysAvailable(resultKeys);
+        boolean expectCapabilityPresent = rawOutputSupported && requestKeysPresent &&
+                characteristicsKeysPresent && resultKeysPresent;
+
+        if (isCapabilityAvailable != expectCapabilityPresent) {
+            if (isCapabilityAvailable) {
+                mCollector.expectTrue(
+                        "REQUEST_AVAILABLE_CAPABILITIES_RAW should support RAW_SENSOR output",
+                        rawOutputSupported);
+                validateRequestKeysPresence(capabilityName, requestKeys, isCapabilityAvailable);
+                validateResultKeysPresence(capabilityName, resultKeys, isCapabilityAvailable);
+                validateCharacteristicsKeysPresence(capabilityName, characteristicsKeys,
+                        isCapabilityAvailable);
+            } else {
+                mCollector.addMessage(String.format(
+                        "Camera %s doesn't list capability %s but contain all required keys" +
+                        " and RAW format output",
+                        mCameraId, capabilityName));
+            }
+        }
+    }
+
+    /**
+     * Test lens facing.
+     */
+    public void testLensFacing() throws Exception {
+        for (String id : mCameraIds) {
+            initStaticMetadata(id);
+            mStaticInfo.getLensFacingChecked();
+        }
+    }
+
+    private float getFpsForMaxSize(String cameraId) throws Exception {
+        HashMap<Size, Long> minFrameDurationMap =
+                mStaticInfo.getAvailableMinFrameDurationsForFormatChecked(ImageFormat.YUV_420_888);
+
+        Size[] sizes = CameraTestUtils.getSupportedSizeForFormat(ImageFormat.YUV_420_888,
+                cameraId, mCameraManager);
+        Size maxSize = CameraTestUtils.getMaxSize(sizes);
+        Long minDuration = minFrameDurationMap.get(maxSize);
+        if (VERBOSE) {
+            Log.v(TAG, "min frame duration for size " + maxSize + " is " + minDuration);
+        }
+        assertTrue("min duration for max size must be postive number",
+                minDuration != null && minDuration > 0);
+
+        return 1e9f / minDuration;
+    }
+
+    /**
+     * Initialize static metadata for a given camera id.
+     */
+    private void initStaticMetadata(String cameraId) throws Exception {
+        mCameraId = cameraId;
+        mCollector.setCameraId(cameraId);
+        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
+                CheckLevel.COLLECT, /* collector */mCollector);
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
new file mode 100644
index 0000000..e7978c6
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/StillCaptureTest.java
@@ -0,0 +1,1294 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static android.hardware.camera2.cts.helpers.AssertHelpers.assertArrayContains;
+
+import android.graphics.ImageFormat;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.DngCreator;
+import android.media.ImageReader;
+import android.util.Pair;
+import android.util.Size;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleImageReaderListener;
+import android.hardware.camera2.cts.helpers.Camera2Focuser;
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.media.Image;
+import android.os.ConditionVariable;
+import android.util.Log;
+import android.util.Range;
+import android.util.Rational;
+import android.view.Surface;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
+
+import java.io.ByteArrayOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class StillCaptureTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "StillCaptureTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    // 60 second to accommodate the possible long exposure time.
+    private static final int RELAXED_CAPTURE_IMAGE_TIMEOUT_MS = CAPTURE_IMAGE_TIMEOUT_MS + 1000;
+    private static final int MAX_REGIONS_AE_INDEX = 0;
+    private static final int MAX_REGIONS_AWB_INDEX = 1;
+    private static final int MAX_REGIONS_AF_INDEX = 2;
+    private static final int WAIT_FOR_FOCUS_DONE_TIMEOUT_MS = 6000;
+    private static final double AE_COMPENSATION_ERROR_TOLERANCE = 0.2;
+    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;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Test JPEG capture exif fields for each camera.
+     */
+    public void testJpegExif() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                Log.i(TAG, "Testing JPEG exif for Camera " + mCameraIds[i]);
+                openDevice(mCameraIds[i]);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                jpegExifTestByCamera();
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    /**
+     * Test normal still capture sequence.
+     * <p>
+     * Preview and and jpeg output streams are configured. Max still capture
+     * size is used for jpeg capture. The sequence of still capture being test
+     * is: start preview, auto focus, precapture metering (if AE is not
+     * converged), then capture jpeg. The AWB and AE are in auto modes. AF mode
+     * is CONTINUOUS_PICTURE.
+     * </p>
+     */
+    public void testTakePicture() throws Exception{
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing basic take picture 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);
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    /**
+     * Test basic Raw capture. Raw buffer avaiablility is checked, but raw buffer data is not.
+     */
+    public void testBasicRawCapture()  throws Exception {
+       for (int i = 0; i < mCameraIds.length; i++) {
+           try {
+               Log.i(TAG, "Testing raw capture for Camera " + mCameraIds[i]);
+               openDevice(mCameraIds[i]);
+
+               if (!mStaticInfo.isCapabilitySupported(
+                       CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                   Log.i(TAG, "RAW capability is not supported in camera " + mCameraIds[i] +
+                           ". Skip the test.");
+                   continue;
+               }
+
+               rawCaptureTestByCamera();
+           } finally {
+               closeDevice();
+               closeImageReader();
+           }
+       }
+    }
+
+
+    /**
+     * Test the full raw capture use case.
+     *
+     * This includes:
+     * - Configuring the camera with a preview, jpeg, and raw output stream.
+     * - Running preview until AE/AF can settle.
+     * - Capturing with a request targeting all three output streams.
+     */
+    public void testFullRawCapture() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                Log.i(TAG, "Testing raw capture for Camera " + mCameraIds[i]);
+                openDevice(mCameraIds[i]);
+                if (!mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+                    Log.i(TAG, "RAW capability is not supported in camera " + mCameraIds[i] +
+                            ". Skip the test.");
+                    continue;
+                }
+
+                fullRawCaptureTestByCamera();
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+    /**
+     * Test touch for focus.
+     * <p>
+     * AF is in CAF mode when preview is started, test uses several pre-selected
+     * regions to simulate touches. Active scan is triggered to make sure the AF
+     * converges in reasonable time.
+     * </p>
+     */
+    public void testTouchForFocus() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing touch for focus for Camera " + id);
+                openDevice(id);
+                int maxAfRegions = mStaticInfo.getAfMaxRegionsChecked();
+                if (!(mStaticInfo.hasFocuser() && maxAfRegions > 0)) {
+                    continue;
+                }
+                // TODO: Relax test to use non-SurfaceView output for depth cases
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                touchForFocusTestByCamera();
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    /**
+     * Test all combination of available preview sizes and still sizes.
+     * <p>
+     * For each still capture, Only the jpeg buffer is validated, capture
+     * result validation is covered by {@link #jpegExifTestByCamera} test.
+     * </p>
+     */
+    public void testStillPreviewCombination() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing Still preview capture combination for Camera " + id);
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                previewStillCombinationTestByCamera();
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    /**
+     * Test AE compensation.
+     * <p>
+     * For each integer EV compensation setting: retrieve the exposure value (exposure time *
+     * sensitivity) with or without compensation, verify if the exposure value is legal (conformed
+     * to what static info has) and the ratio between two exposure values matches EV compensation
+     * setting. Also test for the behavior that exposure settings should be changed when AE
+     * compensation settings is changed, even when AE lock is ON.
+     * </p>
+     */
+    public void testAeCompensation() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing AE compensation for Camera " + id);
+                openDevice(id);
+
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    Log.i(TAG, "Skipping test on legacy devices");
+                    continue;
+                }
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                aeCompensationTestByCamera();
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    /**
+     * Test Ae region for still capture.
+     */
+    public void testAeRegions() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing AE regions for Camera " + id);
+                openDevice(id);
+
+                boolean aeRegionsSupported = isRegionsSupportedFor3A(MAX_REGIONS_AE_INDEX);
+                if (!aeRegionsSupported) {
+                    continue;
+                }
+
+                ArrayList<MeteringRectangle[]> aeRegionTestCases = get3ARegionTestCasesForCamera();
+                for (MeteringRectangle[] aeRegions : aeRegionTestCases) {
+                    takePictureTestByCamera(aeRegions, /*awbRegions*/null, /*afRegions*/null);
+                }
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    /**
+     * Test AWB region for still capture.
+     */
+    public void testAwbRegions() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing AE regions for Camera " + id);
+                openDevice(id);
+
+                boolean awbRegionsSupported = isRegionsSupportedFor3A(MAX_REGIONS_AWB_INDEX);
+                if (!awbRegionsSupported) {
+                    continue;
+                }
+
+                ArrayList<MeteringRectangle[]> awbRegionTestCases = get3ARegionTestCasesForCamera();
+                for (MeteringRectangle[] awbRegions : awbRegionTestCases) {
+                    takePictureTestByCamera(/*aeRegions*/null, awbRegions, /*afRegions*/null);
+                }
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    /**
+     * Test Af region for still capture.
+     */
+    public void testAfRegions() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing AF regions for Camera " + id);
+                openDevice(id);
+
+                boolean afRegionsSupported = isRegionsSupportedFor3A(MAX_REGIONS_AF_INDEX);
+                if (!afRegionsSupported) {
+                    continue;
+                }
+
+                ArrayList<MeteringRectangle[]> afRegionTestCases = get3ARegionTestCasesForCamera();
+                for (MeteringRectangle[] afRegions : afRegionTestCases) {
+                    takePictureTestByCamera(/*aeRegions*/null, /*awbRegions*/null, afRegions);
+                }
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    /**
+     * Test preview is still running after a still request
+     */
+    public void testPreviewPersistence() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing preview persistence for Camera " + id);
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                previewPersistenceTestByCamera();
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    public void testAePrecaptureTriggerCancelJpegCapture() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                Log.i(TAG, "Testing AE precapture cancel for jpeg capture for Camera " + id);
+                openDevice(id);
+
+                // Legacy device doesn't support AE precapture trigger
+                if (mStaticInfo.isHardwareLevelLegacy()) {
+                    Log.i(TAG, "Skipping AE precapture trigger cancel test on legacy devices");
+                    continue;
+                }
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                takePictureTestByCamera(/*aeRegions*/null, /*awbRegions*/null, /*afRegions*/null,
+                        /*addAeTriggerCancel*/true);
+            } finally {
+                closeDevice();
+                closeImageReader();
+            }
+        }
+    }
+
+    /**
+     * Start preview,take a picture and test preview is still running after snapshot
+     */
+    private void previewPersistenceTestByCamera() throws Exception {
+        Size maxStillSz = mOrderedStillSizes.get(0);
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        SimpleCaptureCallback stillResultListener = new SimpleCaptureCallback();
+        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+        CaptureRequest.Builder previewRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder stillRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+        prepareStillCaptureAndStartPreview(previewRequest, stillRequest, maxPreviewSz,
+                maxStillSz, resultListener, imageListener);
+
+        // make sure preview is actually running
+        waitForNumResults(resultListener, NUM_FRAMES_WAITED);
+
+        // take a picture
+        CaptureRequest request = stillRequest.build();
+        mSession.capture(request, stillResultListener, mHandler);
+        stillResultListener.getCaptureResultForRequest(request,
+                WAIT_FOR_RESULT_TIMEOUT_MS);
+
+        // validate image
+        Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+        validateJpegCapture(image, maxStillSz);
+
+        // make sure preview is still running after still capture
+        waitForNumResults(resultListener, NUM_FRAMES_WAITED);
+
+        stopPreview();
+
+        // Free image resources
+        image.close();
+        closeImageReader();
+        return;
+    }
+
+    /**
+     * Take a picture for a given set of 3A regions for a particular camera.
+     * <p>
+     * Before take a still capture, it triggers an auto focus and lock it first,
+     * then wait for AWB to converge and lock it, then trigger a precapture
+     * metering sequence and wait for AE converged. After capture is received, the
+     * capture result and image are validated.
+     * </p>
+     *
+     * @param aeRegions AE regions for this capture
+     * @param awbRegions AWB regions for this capture
+     * @param afRegions AF regions for this capture
+     */
+    private void takePictureTestByCamera(
+            MeteringRectangle[] aeRegions, MeteringRectangle[] awbRegions,
+            MeteringRectangle[] afRegions) throws Exception {
+        takePictureTestByCamera(aeRegions, awbRegions, afRegions,
+                /*addAeTriggerCancel*/false);
+    }
+
+    /**
+     * Take a picture for a given set of 3A regions for a particular camera.
+     * <p>
+     * Before take a still capture, it triggers an auto focus and lock it first,
+     * then wait for AWB to converge and lock it, then trigger a precapture
+     * metering sequence and wait for AE converged. After capture is received, the
+     * capture result and image are validated. If {@code addAeTriggerCancel} is true,
+     * a precapture trigger cancel will be inserted between two adjacent triggers, which
+     * should effective cancel the first trigger.
+     * </p>
+     *
+     * @param aeRegions AE regions for this capture
+     * @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.
+     */
+    private void takePictureTestByCamera(
+            MeteringRectangle[] aeRegions, MeteringRectangle[] awbRegions,
+            MeteringRectangle[] afRegions, boolean addAeTriggerCancel) throws Exception {
+
+        boolean hasFocuser = mStaticInfo.hasFocuser();
+
+        Size maxStillSz = mOrderedStillSizes.get(0);
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+        CaptureResult result;
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+        CaptureRequest.Builder previewRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder stillRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+        prepareStillCaptureAndStartPreview(previewRequest, stillRequest, maxPreviewSz,
+                maxStillSz, resultListener, imageListener);
+
+        // Set AE mode to ON_AUTO_FLASH if flash is available.
+        if (mStaticInfo.hasFlash()) {
+            previewRequest.set(CaptureRequest.CONTROL_AE_MODE,
+                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
+            stillRequest.set(CaptureRequest.CONTROL_AE_MODE,
+                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
+        }
+
+        Camera2Focuser focuser = null;
+        /**
+         * Step 1: trigger an auto focus run, and wait for AF locked.
+         */
+        boolean canSetAfRegion = hasFocuser && (afRegions != null) &&
+                isRegionsSupportedFor3A(MAX_REGIONS_AF_INDEX);
+        if (hasFocuser) {
+            SimpleAutoFocusListener afListener = new SimpleAutoFocusListener();
+            focuser = new Camera2Focuser(mCamera, mSession, mPreviewSurface, afListener,
+                    mStaticInfo.getCharacteristics(), mHandler);
+            if (canSetAfRegion) {
+                stillRequest.set(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
+            }
+            focuser.startAutoFocus(afRegions);
+            afListener.waitForAutoFocusDone(WAIT_FOR_FOCUS_DONE_TIMEOUT_MS);
+        }
+
+        /**
+         * Have to get the current AF mode to be used for other 3A repeating
+         * request, otherwise, the new AF mode in AE/AWB request could be
+         * different with existing repeating requests being sent by focuser,
+         * then it could make AF unlocked too early. Beside that, for still
+         * capture, AF mode must not be different with the one in current
+         * repeating request, otherwise, the still capture itself would trigger
+         * an AF mode change, and the AF lock would be lost for this capture.
+         */
+        int currentAfMode = CaptureRequest.CONTROL_AF_MODE_OFF;
+        if (hasFocuser) {
+            currentAfMode = focuser.getCurrentAfMode();
+        }
+        previewRequest.set(CaptureRequest.CONTROL_AF_MODE, currentAfMode);
+        stillRequest.set(CaptureRequest.CONTROL_AF_MODE, currentAfMode);
+
+        /**
+         * Step 2: AF is already locked, wait for AWB converged, then lock it.
+         */
+        resultListener = new SimpleCaptureCallback();
+        boolean canSetAwbRegion =
+                (awbRegions != null) && isRegionsSupportedFor3A(MAX_REGIONS_AWB_INDEX);
+        if (canSetAwbRegion) {
+            previewRequest.set(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
+            stillRequest.set(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
+        }
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+        if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            waitForResultValue(resultListener, CaptureResult.CONTROL_AWB_STATE,
+                    CaptureResult.CONTROL_AWB_STATE_CONVERGED, NUM_RESULTS_WAIT_TIMEOUT);
+        } else {
+            // LEGACY Devices don't have the AWB_STATE reported in results, so just wait
+            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+        }
+        boolean canSetAwbLock = mStaticInfo.isAwbLockSupported();
+        if (canSetAwbLock) {
+            previewRequest.set(CaptureRequest.CONTROL_AWB_LOCK, true);
+        }
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+        // Validate the next result immediately for region and mode.
+        result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        mCollector.expectEquals("AWB mode in result and request should be same",
+                previewRequest.get(CaptureRequest.CONTROL_AWB_MODE),
+                result.get(CaptureResult.CONTROL_AWB_MODE));
+        if (canSetAwbRegion) {
+            MeteringRectangle[] resultAwbRegions =
+                    getValueNotNull(result, CaptureResult.CONTROL_AWB_REGIONS);
+            mCollector.expectEquals("AWB regions in result and request should be same",
+                    awbRegions, resultAwbRegions);
+        }
+
+        /**
+         * Step 3: trigger an AE precapture metering sequence and wait for AE converged.
+         */
+        resultListener = new SimpleCaptureCallback();
+        boolean canSetAeRegion =
+                (aeRegions != null) && isRegionsSupportedFor3A(MAX_REGIONS_AE_INDEX);
+        if (canSetAeRegion) {
+            previewRequest.set(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
+            stillRequest.set(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
+        }
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+        mSession.capture(previewRequest.build(), resultListener, mHandler);
+        if (addAeTriggerCancel) {
+            // Cancel the current precapture trigger, then send another trigger.
+            // The camera device should behave as if the first trigger is not sent.
+            // Wait one request to make the trigger start doing something before cancel.
+            waitForNumResults(resultListener, /*numResultsWait*/ 1);
+            previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
+            mSession.capture(previewRequest.build(), resultListener, mHandler);
+            waitForResultValue(resultListener, CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER,
+                    CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL,
+                    NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+            // Issue another trigger
+            previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
+                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
+            mSession.capture(previewRequest.build(), resultListener, mHandler);
+        }
+        waitForAeStable(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+
+        // Validate the next result immediately for region and mode.
+        result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        mCollector.expectEquals("AE mode in result and request should be same",
+                previewRequest.get(CaptureRequest.CONTROL_AE_MODE),
+                result.get(CaptureResult.CONTROL_AE_MODE));
+        if (canSetAeRegion) {
+            MeteringRectangle[] resultAeRegions =
+                    getValueNotNull(result, CaptureResult.CONTROL_AE_REGIONS);
+
+            mCollector.expectMeteringRegionsAreSimilar(
+                    "AE regions in result and request should be similar",
+                    aeRegions,
+                    resultAeRegions,
+                    METERING_REGION_ERROR_PERCENT_DELTA);
+        }
+
+        /**
+         * Step 4: take a picture when all 3A are in good state.
+         */
+        resultListener = new SimpleCaptureCallback();
+        CaptureRequest request = stillRequest.build();
+        mSession.capture(request, resultListener, mHandler);
+        // Validate the next result immediately for region and mode.
+        result = resultListener.getCaptureResultForRequest(request, WAIT_FOR_RESULT_TIMEOUT_MS);
+        mCollector.expectEquals("AF mode in result and request should be same",
+                stillRequest.get(CaptureRequest.CONTROL_AF_MODE),
+                result.get(CaptureResult.CONTROL_AF_MODE));
+        if (canSetAfRegion) {
+            MeteringRectangle[] resultAfRegions =
+                    getValueNotNull(result, CaptureResult.CONTROL_AF_REGIONS);
+            mCollector.expectMeteringRegionsAreSimilar(
+                    "AF regions in result and request should be similar",
+                    afRegions,
+                    resultAfRegions,
+                    METERING_REGION_ERROR_PERCENT_DELTA);
+        }
+
+        if (hasFocuser) {
+            // Unlock auto focus.
+            focuser.cancelAutoFocus();
+        }
+
+        // validate image
+        Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+        validateJpegCapture(image, maxStillSz);
+
+        // Free image resources
+        image.close();
+
+        stopPreview();
+    }
+
+    /**
+     * Test touch region for focus by camera.
+     */
+    private void touchForFocusTestByCamera() throws Exception {
+        SimpleCaptureCallback listener = new SimpleCaptureCallback();
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+        startPreview(requestBuilder, maxPreviewSz, listener);
+
+        SimpleAutoFocusListener afListener = new SimpleAutoFocusListener();
+        Camera2Focuser focuser = new Camera2Focuser(mCamera, mSession, mPreviewSurface, afListener,
+                mStaticInfo.getCharacteristics(), mHandler);
+        ArrayList<MeteringRectangle[]> testAfRegions = get3ARegionTestCasesForCamera();
+
+        for (MeteringRectangle[] afRegions : testAfRegions) {
+            focuser.touchForAutoFocus(afRegions);
+            afListener.waitForAutoFocusDone(WAIT_FOR_FOCUS_DONE_TIMEOUT_MS);
+            focuser.cancelAutoFocus();
+        }
+    }
+
+    private void previewStillCombinationTestByCamera() throws Exception {
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+
+        for (Size stillSz : mOrderedStillSizes)
+            for (Size previewSz : mOrderedPreviewSizes) {
+                if (VERBOSE) {
+                    Log.v(TAG, "Testing JPEG capture size " + stillSz.toString()
+                            + " with preview size " + previewSz.toString() + " for camera "
+                            + mCamera.getId());
+                }
+                CaptureRequest.Builder previewRequest =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+                CaptureRequest.Builder stillRequest =
+                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+                prepareStillCaptureAndStartPreview(previewRequest, stillRequest, previewSz,
+                        stillSz, resultListener, imageListener);
+                mSession.capture(stillRequest.build(), resultListener, mHandler);
+                Image image = imageListener.getImage((mStaticInfo.isHardwareLevelLegacy()) ?
+                        RELAXED_CAPTURE_IMAGE_TIMEOUT_MS : CAPTURE_IMAGE_TIMEOUT_MS);
+                validateJpegCapture(image, stillSz);
+
+                // Free image resources
+                image.close();
+
+                // stopPreview must be called here to make sure next time a preview stream
+                // is created with new size.
+                stopPreview();
+            }
+    }
+
+    /**
+     * Basic raw capture test for each camera.
+     */
+    private void rawCaptureTestByCamera() throws Exception {
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+        Size size = mStaticInfo.getRawDimensChecked();
+
+        // Prepare raw capture and start preview.
+        CaptureRequest.Builder previewBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder rawBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+        prepareRawCaptureAndStartPreview(previewBuilder, rawBuilder, maxPreviewSz, size,
+                resultListener, imageListener);
+
+        if (VERBOSE) {
+            Log.v(TAG, "Testing Raw capture with size " + size.toString()
+                    + ", preview size " + maxPreviewSz);
+        }
+
+        CaptureRequest rawRequest = rawBuilder.build();
+        mSession.capture(rawRequest, resultListener, mHandler);
+
+        Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+        validateRaw16Image(image, size);
+        if (DEBUG) {
+            byte[] rawBuffer = getDataFromImage(image);
+            String rawFileName = DEBUG_FILE_NAME_BASE + "/test" + "_" + size.toString() + "_cam" +
+                    mCamera.getId() + ".raw16";
+            Log.d(TAG, "Dump raw file into " + rawFileName);
+            dumpFile(rawFileName, rawBuffer);
+        }
+
+        // Free image resources
+        image.close();
+
+        stopPreview();
+    }
+
+    private void fullRawCaptureTestByCamera() throws Exception {
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+        Size maxStillSz = mOrderedStillSizes.get(0);
+
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        SimpleImageReaderListener jpegListener = new SimpleImageReaderListener();
+        SimpleImageReaderListener rawListener = new SimpleImageReaderListener();
+
+        Size size = mStaticInfo.getRawDimensChecked();
+
+        if (VERBOSE) {
+            Log.v(TAG, "Testing multi capture with size " + size.toString()
+                    + ", preview size " + maxPreviewSz);
+        }
+
+        // Prepare raw capture and start preview.
+        CaptureRequest.Builder previewBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder multiBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+
+        ImageReader rawReader = null;
+        ImageReader jpegReader = null;
+
+        try {
+            // Create ImageReaders.
+            rawReader = makeImageReader(size,
+                    ImageFormat.RAW_SENSOR, MAX_READER_IMAGES, rawListener, mHandler);
+            jpegReader = makeImageReader(maxStillSz,
+                    ImageFormat.JPEG, MAX_READER_IMAGES, jpegListener, mHandler);
+            updatePreviewSurface(maxPreviewSz);
+
+            // Configure output streams with preview and jpeg streams.
+            List<Surface> outputSurfaces = new ArrayList<Surface>();
+            outputSurfaces.add(rawReader.getSurface());
+            outputSurfaces.add(jpegReader.getSurface());
+            outputSurfaces.add(mPreviewSurface);
+            mSessionListener = new BlockingSessionCallback();
+            mSession = configureCameraSession(mCamera, outputSurfaces,
+                    mSessionListener, mHandler);
+
+            // Configure the requests.
+            previewBuilder.addTarget(mPreviewSurface);
+            multiBuilder.addTarget(mPreviewSurface);
+            multiBuilder.addTarget(rawReader.getSurface());
+            multiBuilder.addTarget(jpegReader.getSurface());
+
+            // Start preview.
+            mSession.setRepeatingRequest(previewBuilder.build(), null, mHandler);
+
+            // Poor man's 3A, wait 2 seconds for AE/AF (if any) to settle.
+            // TODO: Do proper 3A trigger and lock (see testTakePictureTest).
+            Thread.sleep(3000);
+
+            multiBuilder.set(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE,
+                    CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE_ON);
+            CaptureRequest multiRequest = multiBuilder.build();
+
+            mSession.capture(multiRequest, resultListener, mHandler);
+
+            CaptureResult result = resultListener.getCaptureResultForRequest(multiRequest,
+                    NUM_RESULTS_WAIT_TIMEOUT);
+            Image jpegImage = jpegListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            basicValidateJpegImage(jpegImage, maxStillSz);
+            Image rawImage = rawListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            validateRaw16Image(rawImage, size);
+            verifyRawCaptureResult(multiRequest, result);
+
+
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            try (DngCreator dngCreator = new DngCreator(mStaticInfo.getCharacteristics(), result)) {
+                dngCreator.writeImage(outputStream, rawImage);
+            }
+
+            if (DEBUG) {
+                byte[] rawBuffer = outputStream.toByteArray();
+                String rawFileName = DEBUG_FILE_NAME_BASE + "/raw16_" + TAG + size.toString() +
+                        "_cam_" + mCamera.getId() + ".dng";
+                Log.d(TAG, "Dump raw file into " + rawFileName);
+                dumpFile(rawFileName, rawBuffer);
+
+                byte[] jpegBuffer = getDataFromImage(jpegImage);
+                String jpegFileName = DEBUG_FILE_NAME_BASE + "/jpeg_" + TAG + size.toString() +
+                        "_cam_" + mCamera.getId() + ".jpg";
+                Log.d(TAG, "Dump jpeg file into " + rawFileName);
+                dumpFile(jpegFileName, jpegBuffer);
+            }
+
+            stopPreview();
+        } finally {
+            CameraTestUtils.closeImageReader(rawReader);
+            CameraTestUtils.closeImageReader(jpegReader);
+            rawReader = null;
+            jpegReader = null;
+        }
+    }
+
+    /**
+     * Validate that raw {@link CaptureResult}.
+     *
+     * @param rawRequest a {@link CaptureRequest} use to capture a RAW16 image.
+     * @param rawResult the {@link CaptureResult} corresponding to the given request.
+     */
+    private void verifyRawCaptureResult(CaptureRequest rawRequest, CaptureResult rawResult) {
+        assertNotNull(rawRequest);
+        assertNotNull(rawResult);
+
+        Rational[] empty = new Rational[] { Rational.ZERO, Rational.ZERO, Rational.ZERO};
+        Rational[] neutralColorPoint = mCollector.expectKeyValueNotNull("NeutralColorPoint",
+                rawResult, CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
+        if (neutralColorPoint != null) {
+            mCollector.expectEquals("NeutralColorPoint length", empty.length,
+                    neutralColorPoint.length);
+            mCollector.expectNotEquals("NeutralColorPoint cannot be all zeroes, ", empty,
+                    neutralColorPoint);
+            mCollector.expectValuesGreaterOrEqual("NeutralColorPoint", neutralColorPoint,
+                    Rational.ZERO);
+        }
+
+        mCollector.expectKeyValueGreaterOrEqual(rawResult, CaptureResult.SENSOR_GREEN_SPLIT, 0.0f);
+
+        Pair<Double, Double>[] noiseProfile = mCollector.expectKeyValueNotNull("NoiseProfile",
+                rawResult, CaptureResult.SENSOR_NOISE_PROFILE);
+        if (noiseProfile != null) {
+            mCollector.expectEquals("NoiseProfile length", noiseProfile.length,
+                /*Num CFA channels*/4);
+            for (Pair<Double, Double> p : noiseProfile) {
+                mCollector.expectTrue("NoiseProfile coefficients " + p +
+                        " must have: S > 0, O >= 0", p.first > 0 && p.second >= 0);
+            }
+        }
+
+        Integer hotPixelMode = mCollector.expectKeyValueNotNull("HotPixelMode", rawResult,
+                CaptureResult.HOT_PIXEL_MODE);
+        Boolean hotPixelMapMode = mCollector.expectKeyValueNotNull("HotPixelMapMode", rawResult,
+                CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE);
+        Point[] hotPixelMap = rawResult.get(CaptureResult.STATISTICS_HOT_PIXEL_MAP);
+
+        Size pixelArraySize = mStaticInfo.getPixelArraySizeChecked();
+        boolean[] availableHotPixelMapModes = mStaticInfo.getValueFromKeyNonNull(
+                        CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES);
+
+        if (hotPixelMode != null) {
+            Integer requestMode = mCollector.expectKeyValueNotNull(rawRequest,
+                    CaptureRequest.HOT_PIXEL_MODE);
+            if (requestMode != null) {
+                mCollector.expectKeyValueEquals(rawResult, CaptureResult.HOT_PIXEL_MODE,
+                        requestMode);
+            }
+        }
+
+        if (hotPixelMapMode != null) {
+            Boolean requestMapMode = mCollector.expectKeyValueNotNull(rawRequest,
+                    CaptureRequest.STATISTICS_HOT_PIXEL_MAP_MODE);
+            if (requestMapMode != null) {
+                mCollector.expectKeyValueEquals(rawResult,
+                        CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE, requestMapMode);
+            }
+
+            if (!hotPixelMapMode) {
+                mCollector.expectTrue("HotPixelMap must be empty", hotPixelMap == null ||
+                        hotPixelMap.length == 0);
+            } else {
+                mCollector.expectTrue("HotPixelMap must not be empty", hotPixelMap != null);
+                mCollector.expectNotNull("AvailableHotPixelMapModes must not be null",
+                        availableHotPixelMapModes);
+                if (availableHotPixelMapModes != null) {
+                    mCollector.expectContains("HotPixelMapMode", availableHotPixelMapModes, true);
+                }
+
+                int height = pixelArraySize.getHeight();
+                int width = pixelArraySize.getWidth();
+                for (Point p : hotPixelMap) {
+                    mCollector.expectTrue("Hotpixel " + p + " must be in pixelArray " +
+                            pixelArraySize, p.x >= 0 && p.x < width && p.y >= 0 && p.y < height);
+                }
+            }
+        }
+        // TODO: profileHueSatMap, and profileToneCurve aren't supported yet.
+
+    }
+
+    /**
+     * Issue a Jpeg capture and validate the exif information.
+     * <p>
+     * TODO: Differentiate full and limited device, some of the checks rely on
+     * per frame control and synchronization, most of them don't.
+     * </p>
+     */
+    private void jpegExifTestByCamera() throws Exception {
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+        Size maxStillSz = mOrderedStillSizes.get(0);
+        if (VERBOSE) {
+            Log.v(TAG, "Testing JPEG exif with jpeg size " + maxStillSz.toString()
+                    + ", preview size " + maxPreviewSz);
+        }
+
+        // prepare capture and start preview.
+        CaptureRequest.Builder previewBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder stillBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+        prepareStillCaptureAndStartPreview(previewBuilder, stillBuilder, maxPreviewSz, maxStillSz,
+                resultListener, imageListener);
+
+        // Set the jpeg keys, then issue a capture
+        Size[] thumbnailSizes = mStaticInfo.getAvailableThumbnailSizesChecked();
+        Size maxThumbnailSize = thumbnailSizes[thumbnailSizes.length - 1];
+        Size[] testThumbnailSizes = new Size[EXIF_TEST_DATA.length];
+        Arrays.fill(testThumbnailSizes, maxThumbnailSize);
+        // Make sure thumbnail size (0, 0) is covered.
+        testThumbnailSizes[0] = new Size(0, 0);
+
+        for (int i = 0; i < EXIF_TEST_DATA.length; i++) {
+            setJpegKeys(stillBuilder, EXIF_TEST_DATA[i], testThumbnailSizes[i], mCollector);
+
+            // Capture a jpeg image.
+            CaptureRequest request = stillBuilder.build();
+            mSession.capture(request, resultListener, mHandler);
+            CaptureResult stillResult =
+                    resultListener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
+            Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+
+            verifyJpegKeys(image, stillResult, maxStillSz, testThumbnailSizes[i], EXIF_TEST_DATA[i],
+                    mStaticInfo, mCollector);
+
+            // Free image resources
+            image.close();
+        }
+    }
+
+    private void aeCompensationTestByCamera() throws Exception {
+        Range<Integer> compensationRange = mStaticInfo.getAeCompensationRangeChecked();
+        // Skip the test if exposure compensation is not supported.
+        if (compensationRange.equals(Range.create(0, 0))) {
+            return;
+        }
+
+        Rational step = mStaticInfo.getAeCompensationStepChecked();
+        float stepF = (float) step.getNumerator() / step.getDenominator();
+        int stepsPerEv = (int) Math.round(1.0 / stepF);
+        int numSteps = (compensationRange.getUpper() - compensationRange.getLower()) / stepsPerEv;
+
+        Size maxStillSz = mOrderedStillSizes.get(0);
+        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
+        CaptureRequest.Builder previewRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureRequest.Builder stillRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
+        boolean canSetAeLock = mStaticInfo.isAeLockSupported();
+        boolean canReadSensorSettings = mStaticInfo.isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS);
+
+        if (canSetAeLock) {
+            stillRequest.set(CaptureRequest.CONTROL_AE_LOCK, true);
+        }
+
+        CaptureResult normalResult;
+        CaptureResult compensatedResult;
+
+        boolean canReadExposureValueRange = mStaticInfo.areKeysAvailable(
+                CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE,
+                CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
+        boolean canVerifyExposureValue = canReadSensorSettings && canReadExposureValueRange;
+        long minExposureValue = -1;
+        long maxExposureValuePreview = -1;
+        long maxExposureValueStill = -1;
+        if (canReadExposureValueRange) {
+            // Minimum exposure settings is mostly static while maximum exposure setting depends on
+            // frame rate range which in term depends on capture request.
+            minExposureValue = mStaticInfo.getSensitivityMinimumOrDefault() *
+                    mStaticInfo.getExposureMinimumOrDefault() / 1000;
+            long maxSensitivity = mStaticInfo.getSensitivityMaximumOrDefault();
+            long maxExposureTimeUs = mStaticInfo.getExposureMaximumOrDefault() / 1000;
+            maxExposureValuePreview = getMaxExposureValue(previewRequest, maxExposureTimeUs,
+                    maxSensitivity);
+            maxExposureValueStill = getMaxExposureValue(stillRequest, maxExposureTimeUs,
+                    maxSensitivity);
+        }
+
+        // Set the max number of images to be same as the burst count, as the verification
+        // could be much slower than producing rate, and we don't want to starve producer.
+        prepareStillCaptureAndStartPreview(previewRequest, stillRequest, maxPreviewSz,
+                maxStillSz, resultListener, numSteps, imageListener);
+
+        for (int i = 0; i <= numSteps; i++) {
+            int exposureCompensation = i * stepsPerEv + compensationRange.getLower();
+            double expectedRatio = Math.pow(2.0, exposureCompensation / stepsPerEv);
+
+            // Wait for AE to be stabilized before capture: CONVERGED or FLASH_REQUIRED.
+            waitForAeStable(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+            normalResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+
+            long normalExposureValue = -1;
+            if (canVerifyExposureValue) {
+                // get and check if current exposure value is valid
+                normalExposureValue = getExposureValue(normalResult);
+                mCollector.expectInRange("Exposure setting out of bound", normalExposureValue,
+                        minExposureValue, maxExposureValuePreview);
+
+                // Only run the test if expectedExposureValue is within valid range
+                long expectedExposureValue = (long) (normalExposureValue * expectedRatio);
+                if (expectedExposureValue < minExposureValue ||
+                    expectedExposureValue > maxExposureValueStill) {
+                    continue;
+                }
+                Log.v(TAG, "Expect ratio: " + expectedRatio +
+                        " normalExposureValue: " + normalExposureValue +
+                        " expectedExposureValue: " + expectedExposureValue +
+                        " minExposureValue: " + minExposureValue +
+                        " maxExposureValuePreview: " + maxExposureValuePreview +
+                        " maxExposureValueStill: " + maxExposureValueStill);
+            }
+
+            // Now issue exposure compensation and wait for AE locked. AE could take a few
+            // frames to go back to locked state
+            previewRequest.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
+                    exposureCompensation);
+            if (canSetAeLock) {
+                previewRequest.set(CaptureRequest.CONTROL_AE_LOCK, true);
+            }
+            mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+            if (canSetAeLock) {
+                waitForAeLocked(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+            } else {
+                waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
+            }
+
+            // Issue still capture
+            if (VERBOSE) {
+                Log.v(TAG, "Verifying capture result for ae compensation value "
+                        + exposureCompensation);
+            }
+
+            stillRequest.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposureCompensation);
+            CaptureRequest request = stillRequest.build();
+            mSession.capture(request, resultListener, mHandler);
+
+            compensatedResult = resultListener.getCaptureResultForRequest(
+                    request, WAIT_FOR_RESULT_TIMEOUT_MS);
+
+            if (canVerifyExposureValue) {
+                // Verify the exposure value compensates as requested
+                long compensatedExposureValue = getExposureValue(compensatedResult);
+                mCollector.expectInRange("Exposure setting out of bound", compensatedExposureValue,
+                        minExposureValue, maxExposureValueStill);
+                double observedRatio = (double) compensatedExposureValue / normalExposureValue;
+                double error = observedRatio / expectedRatio;
+                String errorString = String.format(
+                        "Exposure compensation ratio exceeds error tolerence:" +
+                        " expected(%f) observed(%f)." +
+                        " Normal exposure time %d us, sensitivity %d." +
+                        " Compensated exposure time %d us, sensitivity %d",
+                        expectedRatio, observedRatio,
+                        (int) (getValueNotNull(
+                                normalResult, CaptureResult.SENSOR_EXPOSURE_TIME) / 1000),
+                        getValueNotNull(normalResult, CaptureResult.SENSOR_SENSITIVITY),
+                        (int) (getValueNotNull(
+                                compensatedResult, CaptureResult.SENSOR_EXPOSURE_TIME) / 1000),
+                        getValueNotNull(compensatedResult, CaptureResult.SENSOR_SENSITIVITY));
+                mCollector.expectInRange(errorString, error,
+                        1.0 - AE_COMPENSATION_ERROR_TOLERANCE,
+                        1.0 + AE_COMPENSATION_ERROR_TOLERANCE);
+            }
+
+            mCollector.expectEquals("Exposure compensation result should match requested value.",
+                    exposureCompensation,
+                    compensatedResult.get(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION));
+            if (canSetAeLock) {
+                mCollector.expectTrue("Exposure lock should be set",
+                        compensatedResult.get(CaptureResult.CONTROL_AE_LOCK));
+            }
+
+            Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
+            validateJpegCapture(image, maxStillSz);
+            image.close();
+
+            // Recover AE compensation and lock
+            previewRequest.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
+            if (canSetAeLock) {
+                previewRequest.set(CaptureRequest.CONTROL_AE_LOCK, false);
+            }
+            mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+        }
+    }
+
+    private long getExposureValue(CaptureResult result) throws Exception {
+        int expTimeUs = (int) (getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME) / 1000);
+        int sensitivity = getValueNotNull(result, CaptureResult.SENSOR_SENSITIVITY);
+        return expTimeUs * sensitivity;
+    }
+
+    private long getMaxExposureValue(CaptureRequest.Builder request, long maxExposureTimeUs,
+                long maxSensitivity)  throws Exception {
+        Range<Integer> fpsRange = request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
+        long maxFrameDurationUs = Math.round(1000000.0 / fpsRange.getLower());
+        long currentMaxExposureTimeUs = Math.min(maxFrameDurationUs, maxExposureTimeUs);
+        return currentMaxExposureTimeUs * maxSensitivity;
+    }
+
+
+    //----------------------------------------------------------------
+    //---------Below are common functions for all tests.--------------
+    //----------------------------------------------------------------
+    /**
+     * Validate standard raw (RAW16) capture image.
+     *
+     * @param image The raw16 format image captured
+     * @param rawSize The expected raw size
+     */
+    private static void validateRaw16Image(Image image, Size rawSize) {
+        CameraTestUtils.validateImage(image, rawSize.getWidth(), rawSize.getHeight(),
+                ImageFormat.RAW_SENSOR, /*filePath*/null);
+    }
+
+    /**
+     * Validate JPEG capture image object sanity and test.
+     * <p>
+     * In addition to image object sanity, this function also does the decoding
+     * test, which is slower.
+     * </p>
+     *
+     * @param image The JPEG image to be verified.
+     * @param jpegSize The JPEG capture size to be verified against.
+     */
+    private static void validateJpegCapture(Image image, Size jpegSize) {
+        CameraTestUtils.validateImage(image, jpegSize.getWidth(), jpegSize.getHeight(),
+                ImageFormat.JPEG, /*filePath*/null);
+    }
+
+    private static class SimpleAutoFocusListener implements Camera2Focuser.AutoFocusListener {
+        final ConditionVariable focusDone = new ConditionVariable();
+        @Override
+        public void onAutoFocusLocked(boolean success) {
+            focusDone.open();
+        }
+
+        public void waitForAutoFocusDone(long timeoutMs) {
+            if (focusDone.block(timeoutMs)) {
+                focusDone.close();
+            } else {
+                throw new TimeoutRuntimeException("Wait for auto focus done timed out after "
+                        + timeoutMs + "ms");
+            }
+        }
+    }
+
+    /**
+     * Get 5 3A region test cases, each with one square region in it.
+     * The first one is at center, the other four are at corners of
+     * active array rectangle.
+     *
+     * @return array of test 3A regions
+     */
+    private ArrayList<MeteringRectangle[]> get3ARegionTestCasesForCamera() {
+        final int TEST_3A_REGION_NUM = 5;
+        final int DEFAULT_REGION_WEIGHT = 30;
+        final int DEFAULT_REGION_SCALE_RATIO = 8;
+        ArrayList<MeteringRectangle[]> testCases =
+                new ArrayList<MeteringRectangle[]>(TEST_3A_REGION_NUM);
+        final Rect activeArraySize = mStaticInfo.getActiveArraySizeChecked();
+        int regionWidth = activeArraySize.width() / DEFAULT_REGION_SCALE_RATIO - 1;
+        int regionHeight = activeArraySize.height() / DEFAULT_REGION_SCALE_RATIO - 1;
+        int centerX = activeArraySize.width() / 2;
+        int centerY = activeArraySize.height() / 2;
+        int bottomRightX = activeArraySize.width() - 1;
+        int bottomRightY = activeArraySize.height() - 1;
+
+        // Center region
+        testCases.add(
+                new MeteringRectangle[] {
+                    new MeteringRectangle(
+                            centerX - regionWidth / 2,  // x
+                            centerY - regionHeight / 2, // y
+                            regionWidth,                // width
+                            regionHeight,               // height
+                            DEFAULT_REGION_WEIGHT)});
+
+        // Upper left corner
+        testCases.add(
+                new MeteringRectangle[] {
+                    new MeteringRectangle(
+                            0,                // x
+                            0,                // y
+                            regionWidth,      // width
+                            regionHeight,     // height
+                            DEFAULT_REGION_WEIGHT)});
+
+        // Upper right corner
+        testCases.add(
+                new MeteringRectangle[] {
+                    new MeteringRectangle(
+                            bottomRightX - regionWidth, // x
+                            0,                          // y
+                            regionWidth,                // width
+                            regionHeight,               // height
+                            DEFAULT_REGION_WEIGHT)});
+
+        // Bottom left corner
+        testCases.add(
+                new MeteringRectangle[] {
+                    new MeteringRectangle(
+                            0,                           // x
+                            bottomRightY - regionHeight, // y
+                            regionWidth,                 // width
+                            regionHeight,                // height
+                            DEFAULT_REGION_WEIGHT)});
+
+        // Bottom right corner
+        testCases.add(
+                new MeteringRectangle[] {
+                    new MeteringRectangle(
+                            bottomRightX - regionWidth,  // x
+                            bottomRightY - regionHeight, // y
+                            regionWidth,                 // width
+                            regionHeight,                // height
+                            DEFAULT_REGION_WEIGHT)});
+
+        if (VERBOSE) {
+            StringBuilder sb = new StringBuilder();
+            for (MeteringRectangle[] mr : testCases) {
+                sb.append("{");
+                sb.append(Arrays.toString(mr));
+                sb.append("}, ");
+            }
+            if (sb.length() > 1)
+                sb.setLength(sb.length() - 2); // Remove the redundant comma and space at the end
+            Log.v(TAG, "Generated test regions are: " + sb.toString());
+        }
+
+        return testCases;
+    }
+
+    private boolean isRegionsSupportedFor3A(int index) {
+        int maxRegions = 0;
+        switch (index) {
+            case MAX_REGIONS_AE_INDEX:
+                maxRegions = mStaticInfo.getAeMaxRegionsChecked();
+                break;
+            case MAX_REGIONS_AWB_INDEX:
+                maxRegions = mStaticInfo.getAwbMaxRegionsChecked();
+                break;
+            case  MAX_REGIONS_AF_INDEX:
+                maxRegions = mStaticInfo.getAfMaxRegionsChecked();
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown algorithm index");
+        }
+        boolean isRegionsSupported = maxRegions > 0;
+        if (index == MAX_REGIONS_AF_INDEX && isRegionsSupported) {
+            mCollector.expectTrue(
+                    "Device reports non-zero max AF region count for a camera without focuser!",
+                    mStaticInfo.hasFocuser());
+            isRegionsSupported = isRegionsSupported && mStaticInfo.hasFocuser();
+        }
+
+        return isRegionsSupported;
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
new file mode 100644
index 0000000..06daa51
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
@@ -0,0 +1,514 @@
+/*
+ * 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.hardware.camera2.cts;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+
+import android.graphics.ImageFormat;
+import android.view.Surface;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CaptureFailure;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.TotalCaptureResult;
+import android.util.Size;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Range;
+
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+
+import static org.mockito.Mockito.*;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * CameraDevice preview test by using SurfaceView.
+ */
+public class SurfaceViewPreviewTest extends Camera2SurfaceViewTestCase {
+    private static final String TAG = "SurfaceViewPreviewTest";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final int FRAME_TIMEOUT_MS = 1000;
+    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.
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Test all supported preview sizes for each camera device.
+     * <p>
+     * For the first  {@link #NUM_FRAMES_VERIFIED}  of capture results,
+     * the {@link CaptureCallback} callback availability and the capture timestamp
+     * (monotonically increasing) ordering are verified.
+     * </p>
+     */
+    public void testCameraPreview() throws Exception {
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                Log.i(TAG, "Testing preview for Camera " + mCameraIds[i]);
+                openDevice(mCameraIds[i]);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                previewTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Basic test pattern mode preview.
+     * <p>
+     * Only test the test pattern preview and capture result, the image buffer
+     * is not validated.
+     * </p>
+     */
+    public void testBasicTestPatternPreview() throws Exception{
+        for (int i = 0; i < mCameraIds.length; i++) {
+            try {
+                Log.i(TAG, "Testing preview for Camera " + mCameraIds[i]);
+                openDevice(mCameraIds[i]);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + mCameraIds[i] +
+                            " does not support color outputs, skipping");
+                    continue;
+                }
+                previewTestPatternTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE} for preview, validate the preview
+     * frame duration and exposure time.
+     */
+    public void testPreviewFpsRange() throws Exception {
+        for (String id : mCameraIds) {
+            try {
+                openDevice(id);
+                if (!mStaticInfo.isColorOutputSupported()) {
+                    Log.i(TAG, "Camera " + id + " does not support color outputs, skipping");
+                    continue;
+                }
+                previewFpsRangeTestByCamera();
+            } finally {
+                closeDevice();
+            }
+        }
+    }
+
+    /**
+     * Test to verify the {@link CameraCaptureSession#prepare} method works correctly, and has the
+     * expected effects on performance.
+     *
+     * - Ensure that prepare() results in onSurfacePrepared() being invoked
+     * - Ensure that prepare() does not cause preview glitches while operating
+     * - Ensure that starting to use a newly-prepared output does not cause additional
+     *   preview glitches to occur
+     */
+    public void testPreparePerformance() throws Throwable {
+        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;
+                }
+                preparePerformanceTestByCamera(mCameraIds[i]);
+            }
+            finally {
+                closeDevice();
+            }
+        }
+    }
+
+    private void preparePerformanceTestByCamera(String cameraId) throws Exception {
+        final int MAX_IMAGES_TO_PREPARE = 10;
+        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
+
+        Size maxYuvSize = getSupportedPreviewSizes(cameraId, mCameraManager, null).get(0);
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+
+        // Don't need image data, just drop it right away to minimize overhead
+        ImageDropperListener imageListener = new ImageDropperListener();
+
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+
+        CaptureRequest.Builder previewRequest =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+        // Configure outputs and session
+
+        updatePreviewSurface(maxPreviewSize);
+
+        createImageReader(maxYuvSize, ImageFormat.YUV_420_888, MAX_IMAGES_TO_PREPARE, imageListener);
+
+        List<Surface> outputSurfaces = new ArrayList<Surface>();
+        outputSurfaces.add(mPreviewSurface);
+        outputSurfaces.add(mReaderSurface);
+
+        CameraCaptureSession.StateCallback mockSessionListener =
+                mock(CameraCaptureSession.StateCallback.class);
+
+        mSession = configureCameraSession(mCamera, outputSurfaces, mockSessionListener, mHandler);
+
+        previewRequest.addTarget(mPreviewSurface);
+        Range<Integer> maxFpsTarget = mStaticInfo.getAeMaxTargetFpsRange();
+        previewRequest.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, maxFpsTarget);
+
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+
+        // Converge AE
+        waitForAeStable(resultListener, UNKNOWN_LATENCY_RESULT_WAIT);
+
+        if (mStaticInfo.isAeLockSupported()) {
+            // Lock AE if possible to improve stability
+            previewRequest.set(CaptureRequest.CONTROL_AE_LOCK, true);
+            mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                // Legacy mode doesn't output AE state
+                waitForResultValue(resultListener, CaptureResult.CONTROL_AE_STATE,
+                        CaptureResult.CONTROL_AE_STATE_LOCKED, MAX_RESULTS_TO_WAIT);
+            }
+        }
+
+        // Measure frame rate for a bit
+        Pair<Long, Long> frameDurationStats =
+                measureMeanFrameInterval(resultListener, FRAMES_FOR_AVERAGING, /*prevTimestamp*/ 0);
+
+        Log.i(TAG, String.format("Frame interval avg during normal preview: %f ms, peak %f ms",
+                        frameDurationStats.first / 1e6, frameDurationStats.second / 1e6));
+
+        // Drain results, do prepare
+        resultListener.drain();
+
+        mSession.prepare(mReaderSurface);
+
+        verify(mockSessionListener,
+                timeout(PREPARE_TIMEOUT_MS).times(1)).
+                onSurfacePrepared(eq(mSession), eq(mReaderSurface));
+
+        // Calculate frame rate during prepare
+
+        int resultsReceived = (int) resultListener.getTotalNumFrames();
+        if (resultsReceived > 2) {
+            // Only verify frame rate if there are a couple of results
+            Pair<Long, Long> whilePreparingFrameDurationStats =
+                    measureMeanFrameInterval(resultListener, resultsReceived, /*prevTimestamp*/ 0);
+
+            Log.i(TAG, String.format("Frame interval during prepare avg: %f ms, peak %f ms",
+                            whilePreparingFrameDurationStats.first / 1e6,
+                            whilePreparingFrameDurationStats.second / 1e6));
+
+            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+                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",
+                            cameraId,
+                            frameDurationStats.first / 1e6,
+                            whilePreparingFrameDurationStats.second / 1e6),
+                    (whilePreparingFrameDurationStats.second <=
+                            frameDurationStats.first * (1 + PREPARE_PEAK_RATE_BOUNDS)));
+                mCollector.expectTrue(
+                    String.format("Camera %s: Preview average frame interval affected by prepare " +
+                            "call: preview avg frame duration: %f ms, during prepare: %f ms",
+                            cameraId,
+                            frameDurationStats.first / 1e6,
+                            whilePreparingFrameDurationStats.first / 1e6),
+                    (whilePreparingFrameDurationStats.first <=
+                            frameDurationStats.first * (1 + PREPARE_FRAME_RATE_BOUNDS)));
+            }
+        }
+
+        resultListener.drain();
+
+        // Get at least one more preview result without prepared target
+        CaptureResult result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        long prevTimestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
+
+        // Now use the prepared stream and ensure there are no hiccups from using it
+        previewRequest.addTarget(mReaderSurface);
+
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+
+        Pair<Long, Long> preparedFrameDurationStats =
+                measureMeanFrameInterval(resultListener, MAX_IMAGES_TO_PREPARE*2, prevTimestamp);
+
+        Log.i(TAG, String.format("Frame interval with prepared stream added avg: %f ms, peak %f ms",
+                        preparedFrameDurationStats.first / 1e6,
+                        preparedFrameDurationStats.second / 1e6));
+
+        if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            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",
+                        cameraId,
+                        frameDurationStats.first / 1e6, preparedFrameDurationStats.second / 1e6),
+                (preparedFrameDurationStats.second <=
+                        frameDurationStats.first * (1 + PREPARE_PEAK_RATE_BOUNDS)));
+            mCollector.expectTrue(
+                String.format("Camera %s: Preview average frame interval affected by use of new " +
+                        "stream: preview avg frame duration: %f ms, with new stream: %f ms",
+                        cameraId,
+                        frameDurationStats.first / 1e6, preparedFrameDurationStats.first / 1e6),
+                (preparedFrameDurationStats.first <=
+                        frameDurationStats.first * (1 + PREPARE_FRAME_RATE_BOUNDS)));
+        }
+    }
+
+    /**
+     * 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.
+     *
+     * Returns the mean interval in the first pair entry, and the largest interval in the second
+     * pair entry
+     */
+    Pair<Long, Long> measureMeanFrameInterval(SimpleCaptureCallback resultListener, int frameCount,
+            long prevTimestamp) throws Exception {
+        long summedIntervals = 0;
+        long maxInterval = 0;
+        int measurementCount = frameCount - ((prevTimestamp > 0) ? 0 : 1);
+
+        for (int i = 0; i < frameCount; i++) {
+            CaptureResult result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            long timestamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
+            if (prevTimestamp > 0) {
+                long interval = timestamp - prevTimestamp;
+                if (interval > maxInterval) maxInterval = interval;
+                summedIntervals += interval;
+            }
+            prevTimestamp = timestamp;
+        }
+        return new Pair<Long, Long>(summedIntervals / measurementCount, maxInterval);
+    }
+
+
+    /**
+     * Test preview fps range for all supported ranges. The exposure time are frame duration are
+     * 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();
+        Range<Integer> fpsRange;
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
+        startPreview(requestBuilder, maxPreviewSz, resultListener);
+
+        for (int i = 0; i < fpsRanges.length; i += 1) {
+            fpsRange = fpsRanges[i];
+
+            requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
+            // Turn off auto antibanding to avoid exposure time and frame duration interference
+            // from antibanding algorithm.
+            if (antiBandingOffIsSupported) {
+                requestBuilder.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
+                        CaptureRequest.CONTROL_AE_ANTIBANDING_MODE_OFF);
+            } else {
+                // The device doesn't implement the OFF mode, test continues. It need make sure
+                // that the antibanding algorithm doesn't interfere with the fps range control.
+                Log.i(TAG, "OFF antibanding mode is not supported, the camera device output must" +
+                        " satisfy the specified fps range regardless of its current antibanding" +
+                        " mode");
+            }
+
+            resultListener = new SimpleCaptureCallback();
+            mSession.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
+
+            verifyPreviewTargetFpsRange(resultListener, NUM_FRAMES_VERIFIED, fpsRange,
+                    maxPreviewSz);
+        }
+
+        stopPreview();
+    }
+
+    private void verifyPreviewTargetFpsRange(SimpleCaptureCallback resultListener,
+            int numFramesVerified, Range<Integer> fpsRange, Size previewSz) {
+        CaptureResult result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        List<Integer> capabilities = mStaticInfo.getAvailableCapabilitiesChecked();
+
+        if (capabilities.contains(CaptureRequest.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+            long frameDuration = getValueNotNull(result, CaptureResult.SENSOR_FRAME_DURATION);
+            long[] frameDurationRange =
+                    new long[]{(long) (1e9 / fpsRange.getUpper()), (long) (1e9 / fpsRange.getLower())};
+            mCollector.expectInRange(
+                    "Frame duration must be in the range of " + Arrays.toString(frameDurationRange),
+                    frameDuration, (long) (frameDurationRange[0] * (1 - FRAME_DURATION_ERROR_MARGIN)),
+                    (long) (frameDurationRange[1] * (1 + FRAME_DURATION_ERROR_MARGIN)));
+            long expTime = getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
+            mCollector.expectTrue(String.format("Exposure time %d must be no larger than frame"
+                    + "duration %d", expTime, frameDuration), expTime <= frameDuration);
+
+            Long minFrameDuration = mMinPreviewFrameDurationMap.get(previewSz);
+            boolean findDuration = mCollector.expectTrue("Unable to find minFrameDuration for size "
+                    + previewSz.toString(), minFrameDuration != null);
+            if (findDuration) {
+                mCollector.expectTrue("Frame duration " + frameDuration + " must be no smaller than"
+                        + " minFrameDuration " + minFrameDuration, frameDuration >= minFrameDuration);
+            }
+        } else {
+            Log.i(TAG, "verifyPreviewTargetFpsRange - MANUAL_SENSOR control is not supported," +
+                    " skipping duration and exposure time check.");
+        }
+    }
+
+    /**
+     * Test all supported preview sizes for a camera device
+     *
+     * @throws Exception
+     */
+    private void previewTestByCamera() throws Exception {
+        List<Size> previewSizes = getSupportedPreviewSizes(
+                mCamera.getId(), mCameraManager, PREVIEW_SIZE_BOUND);
+
+        for (final Size sz : previewSizes) {
+            if (VERBOSE) {
+                Log.v(TAG, "Testing camera preview size: " + sz.toString());
+            }
+
+            // TODO: vary the different settings like crop region to cover more cases.
+            CaptureRequest.Builder requestBuilder =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+            CaptureCallback mockCaptureCallback =
+                    mock(CameraCaptureSession.CaptureCallback.class);
+
+            startPreview(requestBuilder, sz, mockCaptureCallback);
+            verifyCaptureResults(mSession, mockCaptureCallback, NUM_FRAMES_VERIFIED,
+                    NUM_FRAMES_VERIFIED * FRAME_TIMEOUT_MS);
+            stopPreview();
+        }
+    }
+
+    private void previewTestPatternTestByCamera() throws Exception {
+        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
+        int[] testPatternModes = mStaticInfo.getAvailableTestPatternModesChecked();
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        CaptureCallback mockCaptureCallback;
+
+        final int[] TEST_PATTERN_DATA = {0, 0xFFFFFFFF, 0xFFFFFFFF, 0}; // G:100%, RB:0.
+        for (int mode : testPatternModes) {
+            if (VERBOSE) {
+                Log.v(TAG, "Test pattern mode: " + mode);
+            }
+            requestBuilder.set(CaptureRequest.SENSOR_TEST_PATTERN_MODE, mode);
+            if (mode == CaptureRequest.SENSOR_TEST_PATTERN_MODE_SOLID_COLOR) {
+                // Assign color pattern to SENSOR_TEST_PATTERN_MODE_DATA
+                requestBuilder.set(CaptureRequest.SENSOR_TEST_PATTERN_DATA, TEST_PATTERN_DATA);
+            }
+            mockCaptureCallback = mock(CaptureCallback.class);
+            startPreview(requestBuilder, maxPreviewSize, mockCaptureCallback);
+            verifyCaptureResults(mSession, mockCaptureCallback, NUM_TEST_PATTERN_FRAMES_VERIFIED,
+                    NUM_TEST_PATTERN_FRAMES_VERIFIED * FRAME_TIMEOUT_MS);
+        }
+
+        stopPreview();
+    }
+
+    private class IsCaptureResultValid extends ArgumentMatcher<TotalCaptureResult> {
+        @Override
+        public boolean matches(Object obj) {
+            TotalCaptureResult result = (TotalCaptureResult)obj;
+            Long timeStamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
+            if (timeStamp != null && timeStamp.longValue() > 0L) {
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private void verifyCaptureResults(
+            CameraCaptureSession session,
+            CaptureCallback mockListener,
+            int expectResultCount,
+            int timeOutMs) {
+        // Should receive expected number of onCaptureStarted callbacks.
+        ArgumentCaptor<Long> timestamps = ArgumentCaptor.forClass(Long.class);
+        ArgumentCaptor<Long> frameNumbers = ArgumentCaptor.forClass(Long.class);
+        verify(mockListener,
+                timeout(timeOutMs).atLeast(expectResultCount))
+                        .onCaptureStarted(
+                                eq(session),
+                                isA(CaptureRequest.class),
+                                timestamps.capture(),
+                                frameNumbers.capture());
+
+        // Validate timestamps: all timestamps should be larger than 0 and monotonically increase.
+        long timestamp = 0;
+        for (Long nextTimestamp : timestamps.getAllValues()) {
+            assertNotNull("Next timestamp is null!", nextTimestamp);
+            assertTrue("Captures are out of order", timestamp < nextTimestamp);
+            timestamp = nextTimestamp;
+        }
+
+        // Validate framenumbers: all framenumbers should be consecutive and positive
+        long frameNumber = -1;
+        for (Long nextFrameNumber : frameNumbers.getAllValues()) {
+            assertNotNull("Next frame number is null!", nextFrameNumber);
+            assertTrue("Captures are out of order",
+                    (frameNumber == -1) || (frameNumber + 1 == nextFrameNumber));
+            frameNumber = nextFrameNumber;
+        }
+
+        // Should receive expected number of capture results.
+        verify(mockListener,
+                timeout(timeOutMs).atLeast(expectResultCount))
+                        .onCaptureCompleted(
+                                eq(session),
+                                isA(CaptureRequest.class),
+                                argThat(new IsCaptureResultValid()));
+
+        // Should not receive any capture failed callbacks.
+        verify(mockListener, never())
+                        .onCaptureFailed(
+                                eq(session),
+                                isA(CaptureRequest.class),
+                                isA(CaptureFailure.class));
+    }
+
+}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/common.rs b/tests/camera/src/android/hardware/camera2/cts/common.rs
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/common.rs
rename to tests/camera/src/android/hardware/camera2/cts/common.rs
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/crop_yuvf_420_to_yuvx_444.rs b/tests/camera/src/android/hardware/camera2/cts/crop_yuvf_420_to_yuvx_444.rs
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/crop_yuvf_420_to_yuvx_444.rs
rename to tests/camera/src/android/hardware/camera2/cts/crop_yuvf_420_to_yuvx_444.rs
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/AssertHelpers.java b/tests/camera/src/android/hardware/camera2/cts/helpers/AssertHelpers.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/helpers/AssertHelpers.java
rename to tests/camera/src/android/hardware/camera2/cts/helpers/AssertHelpers.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/Camera2Focuser.java b/tests/camera/src/android/hardware/camera2/cts/helpers/Camera2Focuser.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/helpers/Camera2Focuser.java
rename to tests/camera/src/android/hardware/camera2/cts/helpers/Camera2Focuser.java
diff --git a/tests/camera/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java b/tests/camera/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java
new file mode 100644
index 0000000..9f0c012
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java
@@ -0,0 +1,1062 @@
+/*
+ * Copyright 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.hardware.camera2.cts.helpers;
+
+import android.graphics.Rect;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureRequest.Builder;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.params.MeteringRectangle;
+import android.media.Image;
+import android.util.Log;
+import android.util.Size;
+
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matcher;
+import org.junit.rules.ErrorCollector;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A camera test ErrorCollector class to gather the test failures during a test,
+ * instead of failing the test immediately for each failure.
+ */
+public class CameraErrorCollector extends ErrorCollector {
+
+    private static final String TAG = "CameraErrorCollector";
+    private static final boolean LOG_ERRORS = Log.isLoggable(TAG, Log.ERROR);
+
+    private String mCameraMsg = "";
+
+    @Override
+    public void verify() throws Throwable {
+        // Do not remove if using JUnit 3 test runners. super.verify() is protected.
+        super.verify();
+    }
+
+    /**
+     * Adds an unconditional error to the table.
+     *
+     * <p>Execution continues, but test will fail at the end.</p>
+     *
+     * @param message A string containing the failure reason.
+     */
+    public void addMessage(String message) {
+        addErrorSuper(new Throwable(mCameraMsg + message));
+    }
+
+    /**
+     * Adds a Throwable to the table. <p>Execution continues, but the test will fail at the end.</p>
+     */
+    @Override
+    public void addError(Throwable error) {
+        addErrorSuper(new Throwable(mCameraMsg + error.getMessage(), error));
+    }
+
+    private void addErrorSuper(Throwable error) {
+        if (LOG_ERRORS) Log.e(TAG, error.getMessage());
+        super.addError(error);
+    }
+
+    /**
+     * Adds a failure to the table if {@code matcher} does not match {@code value}.
+     * Execution continues, but the test will fail at the end if the match fails.
+     * The camera id is included into the failure log.
+     */
+    @Override
+    public <T> void checkThat(final T value, final Matcher<T> matcher) {
+        super.checkThat(mCameraMsg, value, matcher);
+    }
+
+    /**
+     * Adds a failure with the given {@code reason} to the table if
+     * {@code matcher} does not match {@code value}. Execution continues, but
+     * the test will fail at the end if the match fails. The camera id is
+     * included into the failure log.
+     */
+    @Override
+    public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
+        super.checkThat(mCameraMsg + reason, value, matcher);
+    }
+
+    /**
+     * Set the camera id to this error collector object for logging purpose.
+     *
+     * @param id The camera id to be set.
+     */
+    public void setCameraId(String id) {
+        if (id != null) {
+            mCameraMsg = "Test failed for camera " + id + ": ";
+        } else {
+            mCameraMsg = "";
+        }
+    }
+
+    /**
+     * Adds a failure to the table if {@code condition} is not {@code true}.
+     * <p>
+     * Execution continues, but the test will fail at the end if the condition
+     * failed.
+     * </p>
+     *
+     * @param msg Message to be logged when check fails.
+     * @param condition Log the failure if it is not true.
+     */
+    public boolean expectTrue(String msg, boolean condition) {
+        if (!condition) {
+            addMessage(msg);
+        }
+
+        return condition;
+    }
+
+    /**
+     * Check if the two values are equal.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected Expected value to be checked against.
+     * @param actual Actual value to be checked.
+     * @return {@code true} if the two values are equal, {@code false} otherwise.
+     *
+     * @throws IllegalArgumentException if {@code expected} was {@code null}
+     */
+    public <T> boolean expectEquals(String msg, T expected, T actual) {
+        if (expected == null) {
+            throw new IllegalArgumentException("expected value shouldn't be null");
+        }
+
+        if (!Objects.equals(expected, actual)) {
+            addMessage(String.format("%s (expected = %s, actual = %s) ", msg, expected,
+                    actual));
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Check if the two values are not equal.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected Expected value to be checked against.
+     * @param actual Actual value to be checked.
+     * @return {@code true} if the two values are not equal, {@code false} otherwise.
+     */
+    public <T> boolean expectNotEquals(String msg, T expected, T actual) {
+        if (Objects.equals(expected, actual)) {
+            addMessage(String.format("%s (expected = %s, actual = %s) ", msg, expected,
+                    actual));
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Check if the two arrays of values are deeply equal.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected Expected array of values to be checked against.
+     * @param actual Actual array of values to be checked.
+     * @return {@code true} if the two arrays of values are deeply equal, {@code false} otherwise.
+     *
+     * @throws IllegalArgumentException if {@code expected} was {@code null}
+     */
+    public <T> boolean expectEquals(String msg, T[] expected, T[] actual) {
+        if (expected == null) {
+            throw new IllegalArgumentException("expected value shouldn't be null");
+        }
+
+        if (!Arrays.deepEquals(expected, actual)) {
+            addMessage(String.format("%s (expected = %s, actual = %s) ", msg,
+                    Arrays.deepToString(expected), Arrays.deepToString(actual)));
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Check if the two arrays of values are not deeply equal.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected Expected array of values to be checked against.
+     * @param actual Actual array of values to be checked.
+     * @return {@code true} if the two arrays of values are not deeply equal, {@code false}
+     *          otherwise.
+     *
+     * @throws IllegalArgumentException if {@code expected} was {@code null}
+     */
+    public <T> boolean expectNotEquals(String msg, T[] expected, T[] actual) {
+        if (expected == null) {
+            throw new IllegalArgumentException("expected value shouldn't be null");
+        }
+
+        if (Arrays.deepEquals(expected, actual)) {
+            addMessage(String.format("%s (expected = %s, actual = %s) ", msg,
+                    Arrays.deepToString(expected), Arrays.deepToString(actual)));
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Check that the {@code actual} value is greater than the {@code expected} value.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected The expected value to check that the actual value is larger than.
+     * @param actual Actual value to check.
+     * @return {@code true} if {@code actual} is greater than {@code expected}.
+     */
+    public <T extends Comparable<? super T>> boolean expectGreater(String msg, T expected,
+            T actual) {
+        return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
+                msg, expected, actual), actual.compareTo(expected) > 0);
+    }
+
+    /**
+     * Check that the {@code actual} value is greater than or equal to the {@code expected} value.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected The expected value to check that the actual value is larger than or equal to.
+     * @param actual Actual value to check.
+     * @return {@code true} if {@code actual} is greater than or equal to {@code expected}.
+     */
+    public <T extends Comparable<? super T>> boolean expectGreaterOrEqual(String msg, T expected,
+                                                                       T actual) {
+        return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
+                msg, expected, actual), actual.compareTo(expected) >= 0);
+    }
+
+    /**
+     * Check that the {@code actual} value is less than the {@code expected} value.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected The expected value to check that the actual value is less than.
+     * @param actual Actual value to check.
+     * @return {@code true} if {@code actual} is less than {@code expected}.
+     */
+    public <T extends Comparable<? super T>> boolean expectLess(String msg, T expected,
+            T actual) {
+        return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
+                msg, expected, actual), actual.compareTo(expected) < 0);
+    }
+
+    /**
+     * Check that the {@code actual} value is less than or equal to the {@code expected} value.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected The expected value to check that the actual value is less than or equal to.
+     * @param actual Actual value to check.
+     * @return {@code true} if {@code actual} is less than or equal to {@code expected}.
+     */
+    public <T extends Comparable<? super T>> boolean expectLessOrEqual(String msg, T expected,
+            T actual) {
+        return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
+                msg, expected, actual), actual.compareTo(expected) <= 0);
+    }
+
+    /**
+     * Check if the two float values are equal with given error tolerance.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected Expected value to be checked against.
+     * @param actual Actual value to be checked.
+     * @param tolerance The error margin for the equality check.
+     * @return {@code true} if the two values are equal, {@code false} otherwise.
+     */
+    public <T> boolean expectEquals(String msg, float expected, float actual, float tolerance) {
+        if (expected == actual) {
+            return true;
+        }
+
+        if (!(Math.abs(expected - actual) <= tolerance)) {
+            addMessage(String.format("%s (expected = %s, actual = %s, tolerance = %s) ", msg,
+                    expected, actual, tolerance));
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Check if the two double values are equal with given error tolerance.
+     *
+     * @param msg Message to be logged when check fails.
+     * @param expected Expected value to be checked against.
+     * @param actual Actual value to be checked.
+     * @param tolerance The error margin for the equality check
+     * @return {@code true} if the two values are equal, {@code false} otherwise.
+     */
+    public <T> boolean expectEquals(String msg, double expected, double actual, double tolerance) {
+        if (expected == actual) {
+            return true;
+        }
+
+        if (!(Math.abs(expected - actual) <= tolerance)) {
+            addMessage(String.format("%s (expected = %s, actual = %s, tolerance = %s) ", msg,
+                    expected, actual, tolerance));
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Check that all values in the list are greater than or equal to the min value.
+     *
+     * @param msg Message to be logged when check fails
+     * @param list The list of values to be checked
+     * @param min The smallest allowed value
+     */
+    public <T extends Comparable<? super T>> void expectValuesGreaterOrEqual(String msg,
+            List<T> list, T min) {
+        for (T value : list) {
+            expectTrue(msg + String.format(", array value " + value.toString() +
+                                    " is less than %s",
+                            min.toString()), value.compareTo(min) >= 0);
+        }
+    }
+
+    /**
+     * Check that all values in the array are greater than or equal to the min value.
+     *
+     * @param msg Message to be logged when check fails
+     * @param array The array of values to be checked
+     * @param min The smallest allowed value
+     */
+    public <T extends Comparable<? super T>> void expectValuesGreaterOrEqual(String msg,
+                                                                             T[] array, T min) {
+        expectValuesGreaterOrEqual(msg, Arrays.asList(array), min);
+    }
+
+    /**
+     * Expect the list of values are in the range.
+     *
+     * @param msg Message to be logged
+     * @param list The list of values to be checked
+     * @param min The min value of the range
+     * @param max The max value of the range
+     */
+    public <T extends Comparable<? super T>> void expectValuesInRange(String msg, List<T> list,
+            T min, T max) {
+        for (T value : list) {
+            expectTrue(msg + String.format(", array value " + value.toString() +
+                    " is out of range [%s, %s]",
+                    min.toString(), max.toString()),
+                    value.compareTo(max)<= 0 && value.compareTo(min) >= 0);
+        }
+    }
+
+    /**
+     * Expect the array of values are in the range.
+     *
+     * @param msg Message to be logged
+     * @param array The array of values to be checked
+     * @param min The min value of the range
+     * @param max The max value of the range
+     */
+    public <T extends Comparable<? super T>> void expectValuesInRange(String msg, T[] array,
+            T min, T max) {
+        expectValuesInRange(msg, Arrays.asList(array), min, max);
+    }
+
+    /**
+     * Expect the array of values are in the range.
+     *
+     * @param msg Message to be logged
+     * @param array The array of values to be checked
+     * @param min The min value of the range
+     * @param max The max value of the range
+     */
+    public void expectValuesInRange(String msg, int[] array, int min, int max) {
+        ArrayList<Integer> l = new ArrayList<>(array.length);
+        for (int i : array) {
+            l.add(i);
+        }
+        expectValuesInRange(msg, l, min, max);
+    }
+
+    /**
+     * Expect the value is in the range.
+     *
+     * @param msg Message to be logged
+     * @param value The value to be checked
+     * @param min The min value of the range
+     * @param max The max value of the range
+     *
+     * @return {@code true} if the value was in range, {@code false} otherwise
+     */
+    public <T extends Comparable<? super T>> boolean expectInRange(String msg, T value,
+            T min, T max) {
+        return expectTrue(msg + String.format(", value " + value.toString()
+                + " is out of range [%s, %s]",
+                min.toString(), max.toString()),
+                value.compareTo(max)<= 0 && value.compareTo(min) >= 0);
+    }
+
+
+    /**
+     * Check that two metering region arrays are similar enough by ensuring that each of their width,
+     * height, and all corners are within {@code errorPercent} of each other.
+     *
+     * <p>Note that the length of the arrays must be the same, and each weight must be the same
+     * as well. We assume the order is also equivalent.</p>
+     *
+     * <p>At most 1 error per each dissimilar metering region is collected.</p>
+     *
+     * @param msg Message to be logged
+     * @param expected The reference 'expected' values to be used to check against
+     * @param actual The actual values that were received
+     * @param errorPercent Within how many percent the components should be
+     *
+     * @return {@code true} if all expects passed, {@code false} otherwise
+     */
+    public boolean expectMeteringRegionsAreSimilar(String msg,
+            MeteringRectangle[] expected, MeteringRectangle[] actual,
+            float errorPercent) {
+        String expectedActualMsg = String.format("expected (%s), actual (%s)",
+                Arrays.deepToString(expected), Arrays.deepToString(actual));
+
+        String differentSizesMsg = String.format(
+                "%s: rect lists are different sizes; %s",
+                msg, expectedActualMsg);
+
+        String differentWeightsMsg = String.format(
+                "%s: rect weights are different; %s",
+                msg, expectedActualMsg);
+
+        if (!expectTrue(differentSizesMsg, actual != null)) {
+            return false;
+        }
+
+        if (!expectEquals(differentSizesMsg, expected.length, actual.length)) return false;
+
+        boolean succ = true;
+        for (int i = 0; i < expected.length; ++i) {
+            if (i < actual.length) {
+                // Avoid printing multiple errors for the same rectangle
+                if (!expectRectsAreSimilar(
+                        msg, expected[i].getRect(), actual[i].getRect(), errorPercent)) {
+                    succ = false;
+                    continue;
+                }
+                if (!expectEquals(differentWeightsMsg,
+                        expected[i].getMeteringWeight(), actual[i].getMeteringWeight())) {
+                    succ = false;
+                    continue;
+                }
+            }
+        }
+
+        return succ;
+    }
+
+    /**
+     * Check that two rectangles are similar enough by ensuring that their width, height,
+     * and all corners are within {@code errorPercent} of each other.
+     *
+     * <p>Only the first error is collected, to avoid spamming several error messages when
+     * the rectangle is hugely dissimilar.</p>
+     *
+     * @param msg Message to be logged
+     * @param expected The reference 'expected' value to be used to check against
+     * @param actual The actual value that was received
+     * @param errorPercent Within how many percent the components should be
+     *
+     * @return {@code true} if all expects passed, {@code false} otherwise
+     */
+    public boolean expectRectsAreSimilar(String msg, Rect expected, Rect actual,
+            float errorPercent) {
+        String formattedMsg = String.format("%s: rects are not similar enough; expected (%s), " +
+                "actual (%s), error percent (%s), reason: ",
+                msg, expected, actual, errorPercent);
+
+        if (!expectSimilarValues(
+                formattedMsg, "too wide", "too narrow", actual.width(), expected.width(),
+                errorPercent)) return false;
+
+        if (!expectSimilarValues(
+                formattedMsg, "too tall", "too short", actual.height(), expected.height(),
+                errorPercent)) return false;
+
+        if (!expectSimilarValues(
+                formattedMsg, "left pt too right", "left pt too left", actual.left, expected.left,
+                errorPercent)) return false;
+
+        if (!expectSimilarValues(
+                formattedMsg, "right pt too right", "right pt too left",
+                actual.right, expected.right, errorPercent)) return false;
+
+        if (!expectSimilarValues(
+                formattedMsg, "top pt too low", "top pt too high", actual.top, expected.top,
+                errorPercent)) return false;
+
+        if (!expectSimilarValues(
+                formattedMsg, "bottom pt too low", "bottom pt too high", actual.top, expected.top,
+                errorPercent)) return false;
+
+        return true;
+    }
+
+    /**
+     * Check that two sizes are similar enough by ensuring that their width and height
+     * are within {@code errorPercent} of each other.
+     *
+     * <p>Only the first error is collected, to avoid spamming several error messages when
+     * the rectangle is hugely dissimilar.</p>
+     *
+     * @param msg Message to be logged
+     * @param expected The reference 'expected' value to be used to check against
+     * @param actual The actual value that was received
+     * @param errorPercent Within how many percent the components should be
+     *
+     * @return {@code true} if all expects passed, {@code false} otherwise
+     */
+    public boolean expectSizesAreSimilar(String msg, Size expected, Size actual,
+            float errorPercent) {
+        String formattedMsg = String.format("%s: rects are not similar enough; expected (%s), " +
+                "actual (%s), error percent (%s), reason: ",
+                msg, expected, actual, errorPercent);
+
+        if (!expectSimilarValues(
+                formattedMsg, "too wide", "too narrow", actual.getWidth(), expected.getWidth(),
+                errorPercent)) return false;
+
+        if (!expectSimilarValues(
+                formattedMsg, "too tall", "too short", actual.getHeight(), expected.getHeight(),
+                errorPercent)) return false;
+
+        return true;
+    }
+
+    /**
+     * Check that the rectangle is centered within a certain tolerance of {@code errorPercent},
+     * with respect to the {@code bounds} bounding rectangle.
+     *
+     * @param msg Message to be logged
+     * @param expectedBounds The width/height of the bounding rectangle
+     * @param actual The actual value that was received
+     * @param errorPercent Within how many percent the centering should be
+     */
+    public void expectRectCentered(String msg, Size expectedBounds, Rect actual,
+            float errorPercent) {
+        String formattedMsg = String.format("%s: rect should be centered; expected bounds (%s), " +
+                "actual (%s), error percent (%s), reason: ",
+                msg, expectedBounds, actual, errorPercent);
+
+        int centerBoundX = expectedBounds.getWidth() / 2;
+        int centerBoundY = expectedBounds.getHeight() / 2;
+
+        expectSimilarValues(
+                formattedMsg, "too low", "too high", actual.centerY(), centerBoundY,
+                errorPercent);
+
+        expectSimilarValues(
+                formattedMsg, "too right", "too left", actual.centerX(), centerBoundX,
+                errorPercent);
+    }
+
+    private boolean expectSimilarValues(
+            String formattedMsg, String tooSmall, String tooLarge, int actualValue,
+            int expectedValue, float errorPercent) {
+        boolean succ = true;
+        succ = expectTrue(formattedMsg + tooLarge,
+                actualValue <= (expectedValue * (1.0f + errorPercent))) && succ;
+        succ = expectTrue(formattedMsg + tooSmall,
+                actualValue >= (expectedValue * (1.0f - errorPercent))) && succ;
+
+        return succ;
+    }
+
+    public void expectNotNull(String msg, Object obj) {
+        checkThat(msg, obj, CoreMatchers.notNullValue());
+    }
+
+    public void expectNull(String msg, Object obj) {
+        if (obj != null) {
+            addMessage(msg);
+        }
+    }
+
+    /**
+     * Check if the values in the array are monotonically increasing (decreasing) and not all
+     * equal.
+     *
+     * @param array The array of values to be checked
+     * @param ascendingOrder The monotonicity ordering to be checked with
+     */
+    public <T extends Comparable<? super T>>  void checkArrayMonotonicityAndNotAllEqual(T[] array,
+            boolean ascendingOrder) {
+        String orderMsg = ascendingOrder ? ("increasing order") : ("decreasing order");
+        for (int i = 0; i < array.length - 1; i++) {
+            int compareResult = array[i + 1].compareTo(array[i]);
+            boolean condition = compareResult >= 0;
+            if (!ascendingOrder) {
+                condition = compareResult <= 0;
+            }
+
+            expectTrue(String.format("Adjacent values (%s and %s) %s monotonicity is broken",
+                    array[i].toString(), array[i + 1].toString(), orderMsg), condition);
+        }
+
+        expectTrue("All values of this array are equal: " + array[0].toString(),
+                array[0].compareTo(array[array.length - 1]) != 0);
+    }
+
+    /**
+     * Check if the key value is not null and return the value.
+     *
+     * @param characteristics The {@link CameraCharacteristics} to get the key from.
+     * @param key The {@link CameraCharacteristics} key to be checked.
+     *
+     * @return The value of the key.
+     */
+    public <T> T expectKeyValueNotNull(CameraCharacteristics characteristics,
+            CameraCharacteristics.Key<T> key) {
+
+        T value = characteristics.get(key);
+        if (value == null) {
+            addMessage("Key " + key.getName() + " shouldn't be null");
+        }
+
+        return value;
+    }
+
+    /**
+     * Check if the key value is not null and return the value.
+     *
+     * @param request The {@link CaptureRequest} to get the key from.
+     * @param key The {@link CaptureRequest} key to be checked.
+     *
+     * @return The value of the key.
+     */
+    public <T> T expectKeyValueNotNull(CaptureRequest request,
+                                       CaptureRequest.Key<T> key) {
+
+        T value = request.get(key);
+        if (value == null) {
+            addMessage("Key " + key.getName() + " shouldn't be null");
+        }
+
+        return value;
+    }
+
+    /**
+     * Check if the key value is not null and return the value.
+     *
+     * @param request The {@link CaptureRequest#Builder} to get the key from.
+     * @param key The {@link CaptureRequest} key to be checked.
+     * @return The value of the key.
+     */
+    public <T> T expectKeyValueNotNull(Builder request, CaptureRequest.Key<T> key) {
+
+        T value = request.get(key);
+        if (value == null) {
+            addMessage("Key " + key.getName() + " shouldn't be null");
+        }
+
+        return value;
+    }
+
+    /**
+     * Check if the key value is not null and return the value.
+     *
+     * @param result The {@link CaptureResult} to get the key from.
+     * @param key The {@link CaptureResult} key to be checked.
+     * @return The value of the key.
+     */
+    public <T> T expectKeyValueNotNull(CaptureResult result, CaptureResult.Key<T> key) {
+        return expectKeyValueNotNull("", result, key);
+    }
+
+    /**
+     * Check if the key value is not null and return the value.
+     *
+     * @param msg The message to be logged.
+     * @param result The {@link CaptureResult} to get the key from.
+     * @param key The {@link CaptureResult} key to be checked.
+     * @return The value of the key.
+     */
+    public <T> T expectKeyValueNotNull(String msg, CaptureResult result, CaptureResult.Key<T> key) {
+
+        T value = result.get(key);
+        if (value == null) {
+            addMessage(msg + " Key " + key.getName() + " shouldn't be null");
+        }
+
+        return value;
+    }
+
+    /**
+     * Check if the key is non-null and the value is not equal to target.
+     *
+     * @param request The The {@link CaptureRequest#Builder} to get the key from.
+     * @param key The {@link CaptureRequest} key to be checked.
+     * @param expected The expected value of the CaptureRequest key.
+     */
+    public <T> void expectKeyValueNotEquals(
+            Builder request, CaptureRequest.Key<T> key, T expected) {
+        if (request == null || key == null || expected == null) {
+            throw new IllegalArgumentException("request, key and expected shouldn't be null");
+        }
+
+        T value;
+        if ((value = expectKeyValueNotNull(request, key)) == null) {
+            return;
+        }
+
+        String reason = "Key " + key.getName() + " shouldn't have value " + value.toString();
+        checkThat(reason, value, CoreMatchers.not(expected));
+    }
+
+    /**
+     * Check if the key is non-null and the value is not equal to target.
+     *
+     * @param result The {@link CaptureResult} to get the key from.
+     * @param key The {@link CaptureResult} key to be checked.
+     * @param expected The expected value of the CaptureResult key.
+     */
+    public <T> void expectKeyValueNotEquals(
+            CaptureResult result, CaptureResult.Key<T> key, T expected) {
+        if (result == null || key == null || expected == null) {
+            throw new IllegalArgumentException("result, key and expected shouldn't be null");
+        }
+
+        T value;
+        if ((value = expectKeyValueNotNull(result, key)) == null) {
+            return;
+        }
+
+        String reason = "Key " + key.getName() + " shouldn't have value " + value.toString();
+        checkThat(reason, value, CoreMatchers.not(expected));
+    }
+
+    /**
+     * Check if the value is non-null and the value is equal to target.
+     *
+     * @param result The  {@link CaptureResult} to lookup the value in.
+     * @param key The {@link CaptureResult} key to be checked.
+     * @param expected The expected value of the {@link CaptureResult} key.
+     */
+    public <T> void expectKeyValueEquals(CaptureResult result, CaptureResult.Key<T> key,
+            T expected) {
+        if (result == null || key == null || expected == null) {
+            throw new IllegalArgumentException("request, key and expected shouldn't be null");
+        }
+
+        T value;
+        if ((value = expectKeyValueNotNull(result, key)) == null) {
+            return;
+        }
+
+        String reason = "Key " + key.getName() + " value " + value.toString()
+                + " doesn't match the expected value " + expected.toString();
+        checkThat(reason, value, CoreMatchers.equalTo(expected));
+    }
+
+    /**
+     * Check if the key is non-null and the value is equal to target.
+     *
+     * <p>Only check non-null if the target is null.</p>
+     *
+     * @param request The The {@link CaptureRequest#Builder} to get the key from.
+     * @param key The {@link CaptureRequest} key to be checked.
+     * @param expected The expected value of the CaptureRequest key.
+     */
+    public <T> void expectKeyValueEquals(Builder request, CaptureRequest.Key<T> key, T expected) {
+        if (request == null || key == null || expected == null) {
+            throw new IllegalArgumentException("request, key and expected shouldn't be null");
+        }
+
+        T value;
+        if ((value = expectKeyValueNotNull(request, key)) == null) {
+            return;
+        }
+
+        String reason = "Key " + key.getName() + " value " + value.toString()
+                + " doesn't match the expected value " + expected.toString();
+        checkThat(reason, value, CoreMatchers.equalTo(expected));
+    }
+
+    /**
+     * Check if the key is non-null, and the key value is greater than the expected value.
+     *
+     * @param result {@link CaptureResult} to check.
+     * @param key The {@link CaptureResult} key to be checked.
+     * @param expected The expected to be compared to the value for the given key.
+     */
+    public <T extends Comparable<? super T>> void expectKeyValueGreaterOrEqual(
+            CaptureResult result, CaptureResult.Key<T> key, T expected) {
+        T value;
+        if ((value = expectKeyValueNotNull(result, key)) == null) {
+            return;
+        }
+
+        expectGreaterOrEqual(key.getName(), expected, value);
+    }
+
+    /**
+     * Check if the key is non-null, and the key value is greater than the expected value.
+     *
+     * @param characteristics {@link CameraCharacteristics} to check.
+     * @param key The {@link CameraCharacteristics} key to be checked.
+     * @param expected The expected to be compared to the value for the given key.
+     */
+    public <T extends Comparable<? super T>> void expectKeyValueGreaterThan(
+            CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T expected) {
+        T value;
+        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
+            return;
+        }
+
+        expectGreater(key.getName(), expected, value);
+    }
+
+    /**
+     * Check if the key is non-null, and the key value is in the expected range.
+     *
+     * @param characteristics {@link CameraCharacteristics} to check.
+     * @param key The {@link CameraCharacteristics} key to be checked.
+     * @param min The min value of the range
+     * @param max The max value of the range
+     */
+    public <T extends Comparable<? super T>> void expectKeyValueInRange(
+            CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T min, T max) {
+        T value;
+        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
+            return;
+        }
+        expectInRange(key.getName(), value, min, max);
+    }
+
+    /**
+     * Check if the key is non-null, and the key value is one of the expected values.
+     *
+     * @param characteristics {@link CameraCharacteristics} to check.
+     * @param key The {@link CameraCharacteristics} key to be checked.
+     * @param expected The expected values for the given key.
+     */
+    public <T> void expectKeyValueIsIn(CameraCharacteristics characteristics,
+                                       CameraCharacteristics.Key<T> key, T... expected) {
+        T value = expectKeyValueNotNull(characteristics, key);
+        if (value == null) {
+            return;
+        }
+        String reason = "Key " + key.getName() + " value " + value
+                + " isn't one of the expected values " + Arrays.deepToString(expected);
+        expectContains(reason, expected, value);
+    }
+
+    /**
+     * Check if the key is non-null, and the key value is one of the expected values.
+     *
+     * @param request The The {@link CaptureRequest#Builder} to get the key from.
+     * @param key The {@link CaptureRequest} key to be checked.
+     * @param expected The expected values of the CaptureRequest key.
+     */
+    public <T> void expectKeyValueIsIn(Builder request, CaptureRequest.Key<T> key, T... expected) {
+        T value = expectKeyValueNotNull(request, key);
+        if (value == null) {
+            return;
+        }
+        String reason = "Key " + key.getName() + " value " + value
+                + " isn't one of the expected values " + Arrays.deepToString(expected);
+        expectContains(reason, expected, value);
+    }
+
+    /**
+     * Check if the key is non-null, and the key value contains the expected element.
+     *
+     * @param characteristics {@link CameraCharacteristics} to check.
+     * @param key The {@link CameraCharacteristics} key to be checked.
+     * @param expected The expected element to be contained in the value for the given key.
+     */
+    public <T> void expectKeyValueContains(CameraCharacteristics characteristics,
+                                           CameraCharacteristics.Key<T[]> key, T expected) {
+        T[] value;
+        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
+            return;
+        }
+        String reason = "Key " + key.getName() + " value " + value
+                + " doesn't contain the expected value " + expected;
+        expectContains(reason, value, expected);
+    }
+
+    /**
+     * Check if the key is non-null, and the key value contains the expected element.
+     *
+     * @param characteristics {@link CameraCharacteristics} to check.
+     * @param key The {@link CameraCharacteristics} key to be checked.
+     * @param expected The expected element to be contained in the value for the given key.
+     */
+    public void expectKeyValueContains(CameraCharacteristics characteristics,
+                                           CameraCharacteristics.Key<int[]> key, int expected) {
+        int[] value;
+        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
+            return;
+        }
+        String reason = "Key " + key.getName() + " value " + value
+                + " doesn't contain the expected value " + expected;
+        expectContains(reason, value, expected);
+    }
+
+    /**
+     * Check if the key is non-null, and the key value contains the expected element.
+     *
+     * @param characteristics {@link CameraCharacteristics} to check.
+     * @param key The {@link CameraCharacteristics} key to be checked.
+     * @param expected The expected element to be contained in the value for the given key.
+     */
+    public void expectKeyValueContains(CameraCharacteristics characteristics,
+                                       CameraCharacteristics.Key<boolean[]> key, boolean expected) {
+        boolean[] value;
+        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
+            return;
+        }
+        String reason = "Key " + key.getName() + " value " + value
+                + " doesn't contain the expected value " + expected;
+        expectContains(reason, value, expected);
+    }
+
+    /**
+     * Check if the {@code values} array contains the expected element.
+     *
+     * @param reason reason to print for failure.
+     * @param values array to check for membership in.
+     * @param expected the value to check.
+     */
+    public <T> void expectContains(String reason, T[] values, T expected) {
+        if (values == null) {
+            throw new NullPointerException();
+        }
+        checkThat(reason, expected, InMatcher.in(values));
+    }
+
+    public <T> void expectContains(T[] values, T expected) {
+        String reason = "Expected value " + expected
+                + " is not contained in the given values " + values;
+        expectContains(reason, values, expected);
+    }
+
+    /**
+     * Specialize {@link InMatcher} class for integer primitive array.
+     */
+    private static class IntInMatcher extends InMatcher<Integer> {
+        public IntInMatcher(int[] values) {
+            Preconditions.checkNotNull("values", values);
+            mValues = new ArrayList<>(values.length);
+            for (int i : values) {
+                mValues.add(i);
+            }
+        }
+    }
+
+    /**
+     * Check if the {@code values} array contains the expected element.
+     *
+     * <p>Specialized for primitive int arrays</p>
+     *
+     * @param reason reason to print for failure.
+     * @param values array to check for membership in.
+     * @param expected the value to check.
+     */
+    public void expectContains(String reason, int[] values, int expected) {
+        if (values == null) {
+            throw new NullPointerException();
+        }
+
+        checkThat(reason, expected, new IntInMatcher(values));
+    }
+
+    public void expectContains(int[] values, int expected) {
+        String reason = "Expected value " + expected
+                + " is not contained in the given values " + values;
+        expectContains(reason, values, expected);
+    }
+
+    /**
+     * Specialize {@link BooleanInMatcher} class for boolean primitive array.
+     */
+    private static class BooleanInMatcher extends InMatcher<Boolean> {
+        public BooleanInMatcher(boolean[] values) {
+            Preconditions.checkNotNull("values", values);
+            mValues = new ArrayList<>(values.length);
+            for (boolean i : values) {
+                mValues.add(i);
+            }
+        }
+    }
+
+    /**
+     * Check if the {@code values} array contains the expected element.
+     *
+     * <p>Specialized for primitive boolean arrays</p>
+     *
+     * @param reason reason to print for failure.
+     * @param values array to check for membership in.
+     * @param expected the value to check.
+     */
+    public void expectContains(String reason, boolean[] values, boolean expected) {
+        if (values == null) {
+            throw new NullPointerException();
+        }
+
+        checkThat(reason, expected, new BooleanInMatcher(values));
+    }
+
+    /**
+     * Check if the {@code values} array contains the expected element.
+     *
+     * <p>Specialized for primitive boolean arrays</p>
+     *
+     * @param values array to check for membership in.
+     * @param expected the value to check.
+     */
+    public void expectContains(boolean[] values, boolean expected) {
+        String reason = "Expected value " + expected
+                + " is not contained in the given values " + values;
+        expectContains(reason, values, expected);
+    }
+
+    /**
+     * Check if the element inside of the list are unique.
+     *
+     * @param msg The message to be logged
+     * @param list The list of values to be checked
+     */
+    public <T> void expectValuesUnique(String msg, List<T> list) {
+        Set<T> sizeSet = new HashSet<T>(list);
+        expectTrue(msg + " each element must be distinct", sizeSet.size() == list.size());
+    }
+
+    public void expectImageProperties(String msg, Image image, int format, Size size,
+            long timestampNs) {
+        expectEquals(msg + "Image format is wrong.", image.getFormat(), format);
+        expectEquals(msg + "Image width is wrong.", image.getWidth(), size.getWidth());
+        expectEquals(msg + "Image height is wrong.", image.getHeight(), size.getHeight());
+        expectEquals(msg + "Image timestamp is wrong.", image.getTimestamp(), timestampNs);
+    }
+
+}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraMetadataGetter.java b/tests/camera/src/android/hardware/camera2/cts/helpers/CameraMetadataGetter.java
old mode 100755
new mode 100644
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraMetadataGetter.java
rename to tests/camera/src/android/hardware/camera2/cts/helpers/CameraMetadataGetter.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraSessionUtils.java b/tests/camera/src/android/hardware/camera2/cts/helpers/CameraSessionUtils.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraSessionUtils.java
rename to tests/camera/src/android/hardware/camera2/cts/helpers/CameraSessionUtils.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/InMatcher.java b/tests/camera/src/android/hardware/camera2/cts/helpers/InMatcher.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/helpers/InMatcher.java
rename to tests/camera/src/android/hardware/camera2/cts/helpers/InMatcher.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/MaybeNull.java b/tests/camera/src/android/hardware/camera2/cts/helpers/MaybeNull.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/helpers/MaybeNull.java
rename to tests/camera/src/android/hardware/camera2/cts/helpers/MaybeNull.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/Preconditions.java b/tests/camera/src/android/hardware/camera2/cts/helpers/Preconditions.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/helpers/Preconditions.java
rename to tests/camera/src/android/hardware/camera2/cts/helpers/Preconditions.java
diff --git a/tests/camera/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/camera/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
new file mode 100644
index 0000000..e892e42
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
@@ -0,0 +1,2364 @@
+/*
+ * Copyright 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.hardware.camera2.cts.helpers;
+
+import android.graphics.Rect;
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraCharacteristics.Key;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.cts.CameraTestUtils;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.util.Range;
+import android.util.Size;
+import android.util.Log;
+import android.util.Rational;
+
+import junit.framework.Assert;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
+
+/**
+ * Helpers to get common static info out of the camera.
+ *
+ * <p>Avoid boiler plate by putting repetitive get/set patterns in this class.</p>
+ *
+ * <p>Attempt to be durable against the camera device having bad or missing metadata
+ * by providing reasonable defaults and logging warnings when that happens.</p>
+ */
+public class StaticMetadata {
+
+    private static final String TAG = "StaticMetadata";
+    private static final int IGNORE_SIZE_CHECK = -1;
+
+    private static final long SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST = 100000L; // 100us
+    private static final long SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST = 100000000; // 100ms
+    private static final int SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST = 100;
+    private static final int SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST = 800;
+    private static final int STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST = 4;
+    private static final int TONEMAP_MAX_CURVE_POINTS_AT_LEAST = 64;
+    private static final int CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MIN = -2;
+    private static final int CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MAX = 2;
+    private static final Rational CONTROL_AE_COMPENSATION_STEP_DEFAULT = new Rational(1, 2);
+    private static final byte REQUEST_PIPELINE_MAX_DEPTH_MAX = 8;
+    private static final int MAX_REPROCESS_MAX_CAPTURE_STALL = 4;
+
+    // TODO: Consider making this work across any metadata object, not just camera characteristics
+    private final CameraCharacteristics mCharacteristics;
+    private final CheckLevel mLevel;
+    private final CameraErrorCollector mCollector;
+
+    // Index with android.control.aeMode
+    public static final String[] AE_MODE_NAMES = new String[] {
+        "AE_MODE_OFF",
+        "AE_MODE_ON",
+        "AE_MODE_ON_AUTO_FLASH",
+        "AE_MODE_ON_ALWAYS_FLASH",
+        "AE_MODE_ON_AUTO_FLASH_REDEYE"
+    };
+
+    // Index with android.control.afMode
+    public static final String[] AF_MODE_NAMES = new String[] {
+        "AF_MODE_OFF",
+        "AF_MODE_AUTO",
+        "AF_MODE_MACRO",
+        "AF_MODE_CONTINUOUS_VIDEO",
+        "AF_MODE_CONTINUOUS_PICTURE",
+        "AF_MODE_EDOF"
+    };
+
+    // Index with android.control.aeState
+    public static final String[] AE_STATE_NAMES = new String[] {
+        "AE_STATE_INACTIVE",
+        "AE_STATE_SEARCHING",
+        "AE_STATE_CONVERGED",
+        "AE_STATE_LOCKED",
+        "AE_STATE_FLASH_REQUIRED",
+        "AE_STATE_PRECAPTURE"
+    };
+
+    // Index with android.control.afState
+    public static final String[] AF_STATE_NAMES = new String[] {
+        "AF_STATE_INACTIVE",
+        "AF_STATE_PASSIVE_SCAN",
+        "AF_STATE_PASSIVE_FOCUSED",
+        "AF_STATE_ACTIVE_SCAN",
+        "AF_STATE_FOCUSED_LOCKED",
+        "AF_STATE_NOT_FOCUSED_LOCKED",
+        "AF_STATE_PASSIVE_UNFOCUSED"
+    };
+
+    public enum CheckLevel {
+        /** Only log warnings for metadata check failures. Execution continues. */
+        WARN,
+        /**
+         * Use ErrorCollector to collect the metadata check failures, Execution
+         * continues.
+         */
+        COLLECT,
+        /** Assert the metadata check failures. Execution aborts. */
+        ASSERT
+    }
+
+    /**
+     * Construct a new StaticMetadata object.
+     *
+     *<p> Default constructor, only log warnings for the static metadata check failures</p>
+     *
+     * @param characteristics static info for a camera
+     * @throws IllegalArgumentException if characteristics was null
+     */
+    public StaticMetadata(CameraCharacteristics characteristics) {
+        this(characteristics, CheckLevel.WARN, /*collector*/null);
+    }
+
+    /**
+     * Construct a new StaticMetadata object with {@link CameraErrorCollector}.
+     * <p>
+     * When level is not {@link CheckLevel.COLLECT}, the {@link CameraErrorCollector} will be
+     * ignored, otherwise, it will be used to log the check failures.
+     * </p>
+     *
+     * @param characteristics static info for a camera
+     * @param collector The {@link CameraErrorCollector} used by this StaticMetadata
+     * @throws IllegalArgumentException if characteristics or collector was null.
+     */
+    public StaticMetadata(CameraCharacteristics characteristics, CameraErrorCollector collector) {
+        this(characteristics, CheckLevel.COLLECT, collector);
+    }
+
+    /**
+     * Construct a new StaticMetadata object with {@link CheckLevel} and
+     * {@link CameraErrorCollector}.
+     * <p>
+     * When level is not {@link CheckLevel.COLLECT}, the {@link CameraErrorCollector} will be
+     * ignored, otherwise, it will be used to log the check failures.
+     * </p>
+     *
+     * @param characteristics static info for a camera
+     * @param level The {@link CheckLevel} of this StaticMetadata
+     * @param collector The {@link CameraErrorCollector} used by this StaticMetadata
+     * @throws IllegalArgumentException if characteristics was null or level was
+     *         {@link CheckLevel.COLLECT} but collector was null.
+     */
+    public StaticMetadata(CameraCharacteristics characteristics, CheckLevel level,
+            CameraErrorCollector collector) {
+        if (characteristics == null) {
+            throw new IllegalArgumentException("characteristics was null");
+        }
+        if (level == CheckLevel.COLLECT && collector == null) {
+            throw new IllegalArgumentException("collector must valid when COLLECT level is set");
+        }
+
+        mCharacteristics = characteristics;
+        mLevel = level;
+        mCollector = collector;
+    }
+
+    /**
+     * Get the CameraCharacteristics associated with this StaticMetadata.
+     *
+     * @return A non-null CameraCharacteristics object
+     */
+    public CameraCharacteristics getCharacteristics() {
+        return mCharacteristics;
+    }
+
+    /**
+     * Whether or not the hardware level reported by android.info.supportedHardwareLevel
+     * is {@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;
+    }
+
+    /**
+     * Whether or not the hardware level reported by android.info.supportedHardwareLevel
+     * Return the supported hardware level of the device, or fail if no value is reported.
+     *
+     * @return the supported hardware level as a constant defined for
+     *      {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}.
+     */
+    public int getHardwareLevelChecked() {
+        Integer hwLevel = getValueFromKeyNonNull(
+                CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
+        if (hwLevel == null) {
+            Assert.fail("No supported hardware level reported.");
+        }
+        return hwLevel;
+    }
+
+    /**
+     * Whether or not the hardware level reported by android.info.supportedHardwareLevel
+     * is {@value CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}.
+     *
+     * <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 LEGACY}, {@code false} otherwise.
+     */
+    public boolean isHardwareLevelLegacy() {
+        return getHardwareLevelChecked() == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
+    }
+
+    /**
+     * Whether or not the per frame control is supported by the camera device.
+     *
+     * @return {@code true} if per frame control is supported, {@code false} otherwise.
+     */
+    public boolean isPerFrameControlSupported() {
+        return getSyncMaxLatency() == CameraMetadata.SYNC_MAX_LATENCY_PER_FRAME_CONTROL;
+    }
+
+    /**
+     * Get the maximum number of frames to wait for a request settings being applied
+     *
+     * @return CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN for unknown latency
+     *         CameraMetadata.SYNC_MAX_LATENCY_PER_FRAME_CONTROL for per frame control
+     *         a positive int otherwise
+     */
+    public int getSyncMaxLatency() {
+        Integer value = getValueFromKeyNonNull(CameraCharacteristics.SYNC_MAX_LATENCY);
+        if (value == null) {
+            return CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN;
+        }
+        return value;
+    }
+
+    /**
+     * Whether or not the hardware level reported by android.info.supportedHardwareLevel
+     * is {@value CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED}.
+     *
+     * <p>If the camera device is incorrectly reporting the hardwareLevel, this
+     * will always return {@code true}.</p>
+     *
+     * @return {@code true} if the device is {@code LIMITED}, {@code false} otherwise.
+     */
+    public boolean isHardwareLevelLimited() {
+        return getHardwareLevelChecked() == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
+    }
+
+    /**
+     * Whether or not the hardware level reported by {@code android.info.supportedHardwareLevel}
+     * is at least {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED}.
+     *
+     * <p>If the camera device is incorrectly reporting the hardwareLevel, this
+     * will always return {@code false}.</p>
+     *
+     * @return
+     *          {@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;
+    }
+
+    /**
+     * Get the maximum number of partial result a request can expect
+     *
+     * @return 1 if partial result is not supported.
+     *         a integer value larger than 1 if partial result is supported.
+     */
+    public int getPartialResultCount() {
+        Integer value = mCharacteristics.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT);
+        if (value == null) {
+            // Optional key. Default value is 1 if key is missing.
+            return 1;
+        }
+        return value;
+    }
+
+    /**
+     * Get the exposure time value and clamp to the range if needed.
+     *
+     * @param exposure Input exposure time value to check.
+     * @return Exposure value in the legal range.
+     */
+    public long getExposureClampToRange(long exposure) {
+        long minExposure = getExposureMinimumOrDefault(Long.MAX_VALUE);
+        long maxExposure = getExposureMaximumOrDefault(Long.MIN_VALUE);
+        if (minExposure > SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST) {
+            failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE,
+                    String.format(
+                    "Min value %d is too large, set to maximal legal value %d",
+                    minExposure, SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST));
+            minExposure = SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST;
+        }
+        if (maxExposure < SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST) {
+            failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE,
+                    String.format(
+                    "Max value %d is too small, set to minimal legal value %d",
+                    maxExposure, SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST));
+            maxExposure = SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST;
+        }
+
+        return Math.max(minExposure, Math.min(maxExposure, exposure));
+    }
+
+    /**
+     * Check if the camera device support focuser.
+     *
+     * @return true if camera device support focuser, false otherwise.
+     */
+    public boolean hasFocuser() {
+        if (areKeysAvailable(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)) {
+            // LEGACY devices don't have lens.info.minimumFocusDistance, so guard this query
+            return (getMinimumFocusDistanceChecked() > 0);
+        } else {
+            // Check available AF modes
+            int[] availableAfModes = mCharacteristics.get(
+                    CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
+
+            if (availableAfModes == null) {
+                return false;
+            }
+
+            // Assume that if we have an AF mode which doesn't ignore AF trigger, we have a focuser
+            boolean hasFocuser = false;
+            loop: for (int mode : availableAfModes) {
+                switch (mode) {
+                    case CameraMetadata.CONTROL_AF_MODE_AUTO:
+                    case CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE:
+                    case CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_VIDEO:
+                    case CameraMetadata.CONTROL_AF_MODE_MACRO:
+                        hasFocuser = true;
+                        break loop;
+                }
+            }
+
+            return hasFocuser;
+        }
+    }
+
+    /**
+     * Check if the camera device has flash unit.
+     * @return true if flash unit is available, false otherwise.
+     */
+    public boolean hasFlash() {
+        return getFlashInfoChecked();
+    }
+
+    /**
+     * Get minimum focus distance.
+     *
+     * @return minimum focus distance, 0 if minimum focus distance is invalid.
+     */
+    public float getMinimumFocusDistanceChecked() {
+        Key<Float> key = CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE;
+        Float minFocusDistance;
+
+        /**
+         * android.lens.info.minimumFocusDistance - required for FULL and MANUAL_SENSOR-capable
+         *   devices; optional for all other devices.
+         */
+        if (isHardwareLevelFull() || isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+            minFocusDistance = getValueFromKeyNonNull(key);
+        } else {
+            minFocusDistance = mCharacteristics.get(key);
+        }
+
+        if (minFocusDistance == null) {
+            return 0.0f;
+        }
+
+        checkTrueForKey(key, " minFocusDistance value shouldn't be negative",
+                minFocusDistance >= 0);
+        if (minFocusDistance < 0) {
+            minFocusDistance = 0.0f;
+        }
+
+        return minFocusDistance;
+    }
+
+    /**
+     * Get focusDistanceCalibration.
+     *
+     * @return focusDistanceCalibration, UNCALIBRATED if value is invalid.
+     */
+    public int getFocusDistanceCalibrationChecked() {
+        Key<Integer> key = CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION;
+        Integer calibration = getValueFromKeyNonNull(key);
+
+        if (calibration == null) {
+            return CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED;
+        }
+
+        checkTrueForKey(key, " value is out of range" ,
+                calibration >= CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED &&
+                calibration <= CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED);
+
+        return calibration;
+    }
+
+    /**
+     * Get max AE regions and do sanity check.
+     *
+     * @return AE max regions supported by the camera device
+     */
+    public int getAeMaxRegionsChecked() {
+        Integer regionCount = mCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AE);
+        if (regionCount == null) {
+            return 0;
+        }
+        return regionCount;
+    }
+
+    /**
+     * Get max AWB regions and do sanity check.
+     *
+     * @return AWB max regions supported by the camera device
+     */
+    public int getAwbMaxRegionsChecked() {
+        Integer regionCount = mCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB);
+        if (regionCount == null) {
+            return 0;
+        }
+        return regionCount;
+    }
+
+    /**
+     * Get max AF regions and do sanity check.
+     *
+     * @return AF max regions supported by the camera device
+     */
+    public int getAfMaxRegionsChecked() {
+        Integer regionCount = mCharacteristics.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF);
+        if (regionCount == null) {
+            return 0;
+        }
+        return regionCount;
+    }
+    /**
+     * Get the available anti-banding modes.
+     *
+     * @return The array contains available anti-banding modes.
+     */
+    public int[] getAeAvailableAntiBandingModesChecked() {
+        Key<int[]> key = CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        boolean foundAuto = false;
+        boolean found50Hz = false;
+        boolean found60Hz = false;
+        for (int mode : modes) {
+            checkTrueForKey(key, "mode value " + mode + " is out if range",
+                    mode >= CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_OFF ||
+                    mode <= CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO);
+            if (mode == CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO) {
+                foundAuto = true;
+            } else if (mode == CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_50HZ) {
+                found50Hz = true;
+            } else if (mode == CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_60HZ) {
+                found60Hz = true;
+            }
+        }
+        // Must contain AUTO mode or one of 50/60Hz mode.
+        checkTrueForKey(key, "Either AUTO mode or both 50HZ/60HZ mode should present",
+                foundAuto || (found50Hz && found60Hz));
+
+        return modes;
+    }
+
+    /**
+     * Check if the antibanding OFF mode is supported.
+     *
+     * @return true if antibanding OFF mode is supported, false otherwise.
+     */
+    public boolean isAntiBandingOffModeSupported() {
+        List<Integer> antiBandingModes =
+                Arrays.asList(CameraTestUtils.toObject(getAeAvailableAntiBandingModesChecked()));
+
+        return antiBandingModes.contains(CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_OFF);
+    }
+
+    public Boolean getFlashInfoChecked() {
+        Key<Boolean> key = CameraCharacteristics.FLASH_INFO_AVAILABLE;
+        Boolean hasFlash = getValueFromKeyNonNull(key);
+
+        // In case the failOnKey only gives warning.
+        if (hasFlash == null) {
+            return false;
+        }
+
+        return hasFlash;
+    }
+
+    public int[] getAvailableTestPatternModesChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        if (modes == null) {
+            return new int[0];
+        }
+
+        int expectValue = CameraCharacteristics.SENSOR_TEST_PATTERN_MODE_OFF;
+        Integer[] boxedModes = CameraTestUtils.toObject(modes);
+        checkTrueForKey(key, " value must contain OFF mode",
+                Arrays.asList(boxedModes).contains(expectValue));
+
+        return modes;
+    }
+
+    /**
+     * Get available thumbnail sizes and do the sanity check.
+     *
+     * @return The array of available thumbnail sizes
+     */
+    public Size[] getAvailableThumbnailSizesChecked() {
+        Key<Size[]> key = CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES;
+        Size[] sizes = getValueFromKeyNonNull(key);
+        final List<Size> sizeList = Arrays.asList(sizes);
+
+        // Size must contain (0, 0).
+        checkTrueForKey(key, "size should contain (0, 0)", sizeList.contains(new Size(0, 0)));
+
+        // Each size must be distinct.
+        checkElementDistinct(key, sizeList);
+
+        // Must be sorted in ascending order by area, by width if areas are same.
+        List<Size> orderedSizes =
+                CameraTestUtils.getAscendingOrderSizes(sizeList, /*ascending*/true);
+        checkTrueForKey(key, "Sizes should be in ascending order: Original " + sizeList.toString()
+                + ", Expected " + orderedSizes.toString(), orderedSizes.equals(sizeList));
+
+        // TODO: Aspect ratio match, need wait for android.scaler.availableStreamConfigurations
+        // implementation see b/12958122.
+
+        return sizes;
+    }
+
+    /**
+     * Get available focal lengths and do the sanity check.
+     *
+     * @return The array of available focal lengths
+     */
+    public float[] getAvailableFocalLengthsChecked() {
+        Key<float[]> key = CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS;
+        float[] focalLengths = getValueFromKeyNonNull(key);
+
+        checkTrueForKey(key, "Array should contain at least one element", focalLengths.length >= 1);
+
+        for (int i = 0; i < focalLengths.length; i++) {
+            checkTrueForKey(key,
+                    String.format("focalLength[%d] %f should be positive.", i, focalLengths[i]),
+                    focalLengths[i] > 0);
+        }
+        checkElementDistinct(key, Arrays.asList(CameraTestUtils.toObject(focalLengths)));
+
+        return focalLengths;
+    }
+
+    /**
+     * Get available apertures and do the sanity check.
+     *
+     * @return The non-null array of available apertures
+     */
+    public float[] getAvailableAperturesChecked() {
+        Key<float[]> key = CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES;
+        float[] apertures = getValueFromKeyNonNull(key);
+
+        checkTrueForKey(key, "Array should contain at least one element", apertures.length >= 1);
+
+        for (int i = 0; i < apertures.length; i++) {
+            checkTrueForKey(key,
+                    String.format("apertures[%d] %f should be positive.", i, apertures[i]),
+                    apertures[i] > 0);
+        }
+        checkElementDistinct(key, Arrays.asList(CameraTestUtils.toObject(apertures)));
+
+        return apertures;
+    }
+
+    /**
+     * Get and check the available hot pixel map modes.
+     *
+     * @return the available hot pixel map modes
+     */
+    public int[] getAvailableHotPixelModesChecked() {
+        Key<int[]> key = CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        if (modes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+        if (isHardwareLevelFull()) {
+            checkTrueForKey(key, "Full-capability camera devices must support FAST mode",
+                    modeList.contains(CameraMetadata.HOT_PIXEL_MODE_FAST));
+        }
+
+        if (isHardwareLevelLimitedOrBetter()) {
+            // 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,
+                    CameraMetadata.HOT_PIXEL_MODE_HIGH_QUALITY
+            });
+            checkTrueForKey(
+                    key, " FAST and HIGH_QUALITY mode must both present or both not present",
+                    containsAllOrNone(modeList, coupledModes));
+        }
+        checkElementDistinct(key, modeList);
+        checkArrayValuesInRange(key, modes, CameraMetadata.HOT_PIXEL_MODE_OFF,
+                CameraMetadata.HOT_PIXEL_MODE_HIGH_QUALITY);
+
+        return modes;
+    }
+
+    /**
+     * Get and check available face detection modes.
+     *
+     * @return The non-null array of available face detection modes
+     */
+    public int[] getAvailableFaceDetectModesChecked() {
+        Key<int[]> key = CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        if (modes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+        checkTrueForKey(key, "Array should contain OFF mode",
+                modeList.contains(CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF));
+        checkElementDistinct(key, modeList);
+        checkArrayValuesInRange(key, modes, CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF,
+                CameraMetadata.STATISTICS_FACE_DETECT_MODE_FULL);
+
+        return modes;
+    }
+
+    /**
+     * Get and check max face detected count.
+     *
+     * @return max number of faces that can be detected
+     */
+    public int getMaxFaceCountChecked() {
+        Key<Integer> key = CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT;
+        Integer count = getValueFromKeyNonNull(key);
+
+        if (count == null) {
+            return 0;
+        }
+
+        List<Integer> faceDetectModes =
+                Arrays.asList(CameraTestUtils.toObject(getAvailableFaceDetectModesChecked()));
+        if (faceDetectModes.contains(CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF) &&
+                faceDetectModes.size() == 1) {
+            checkTrueForKey(key, " value must be 0 if only OFF mode is supported in "
+                    + "availableFaceDetectionModes", count == 0);
+        } else {
+            int maxFaceCountAtLeast = STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST;
+
+            // Legacy mode may support fewer than STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST faces.
+            if (isHardwareLevelLegacy()) {
+                maxFaceCountAtLeast = 1;
+            }
+            checkTrueForKey(key, " value must be no less than " + maxFaceCountAtLeast + " if SIMPLE"
+                    + "or FULL is also supported in availableFaceDetectionModes",
+                    count >= maxFaceCountAtLeast);
+        }
+
+        return count;
+    }
+
+    /**
+     * Get and check the available tone map modes.
+     *
+     * @return the available tone map modes
+     */
+    public int[] getAvailableToneMapModesChecked() {
+        Key<int[]> key = CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        if (modes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+        checkTrueForKey(key, " Camera devices must always support FAST mode",
+                modeList.contains(CameraMetadata.TONEMAP_MODE_FAST));
+        // Qualification check for MANUAL_POSTPROCESSING capability is in
+        // StaticMetadataTest#testCapabilities
+
+        if (isHardwareLevelLimitedOrBetter()) {
+            // FAST and HIGH_QUALITY mode must be both present or both not present
+            List<Integer> coupledModes = Arrays.asList(new Integer[] {
+                    CameraMetadata.TONEMAP_MODE_FAST,
+                    CameraMetadata.TONEMAP_MODE_HIGH_QUALITY
+            });
+            checkTrueForKey(
+                    key, " FAST and HIGH_QUALITY mode must both present or both not present",
+                    containsAllOrNone(modeList, coupledModes));
+        }
+        checkElementDistinct(key, modeList);
+        checkArrayValuesInRange(key, modes, CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE,
+                CameraMetadata.TONEMAP_MODE_PRESET_CURVE);
+
+        return modes;
+    }
+
+    /**
+     * Get and check max tonemap curve point.
+     *
+     * @return Max tonemap curve points.
+     */
+    public int getMaxTonemapCurvePointChecked() {
+        Key<Integer> key = CameraCharacteristics.TONEMAP_MAX_CURVE_POINTS;
+        Integer count = getValueFromKeyNonNull(key);
+        List<Integer> modeList =
+                Arrays.asList(CameraTestUtils.toObject(getAvailableToneMapModesChecked()));
+        boolean tonemapCurveOutputSupported =
+                modeList.contains(CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE) ||
+                modeList.contains(CameraMetadata.TONEMAP_MODE_GAMMA_VALUE) ||
+                modeList.contains(CameraMetadata.TONEMAP_MODE_PRESET_CURVE);
+
+        if (count == null) {
+            if (tonemapCurveOutputSupported) {
+                Assert.fail("Tonemap curve output is supported but MAX_CURVE_POINTS is null");
+            }
+            return 0;
+        }
+
+        if (tonemapCurveOutputSupported) {
+            checkTrueForKey(key, "Tonemap curve output supported camera device must support "
+                    + "maxCurvePoints >= " + TONEMAP_MAX_CURVE_POINTS_AT_LEAST,
+                    count >= TONEMAP_MAX_CURVE_POINTS_AT_LEAST);
+        }
+
+        return count;
+    }
+
+    /**
+     * Get and check pixel array size.
+     */
+    public Size getPixelArraySizeChecked() {
+        Key<Size> key = CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE;
+        Size pixelArray = getValueFromKeyNonNull(key);
+        if (pixelArray == null) {
+            return new Size(0, 0);
+        }
+
+        return pixelArray;
+    }
+
+    /**
+     * Get and check pre-correction active array size.
+     */
+    public Rect getPreCorrectedActiveArraySizeChecked() {
+        Key<Rect> key = CameraCharacteristics.SENSOR_INFO_PRE_CORRECTION_ACTIVE_ARRAY_SIZE;
+        Rect activeArray = getValueFromKeyNonNull(key);
+
+        if (activeArray == null) {
+            return new Rect(0, 0, 0, 0);
+        }
+
+        Size pixelArraySize = getPixelArraySizeChecked();
+        checkTrueForKey(key, "values left/top are invalid", activeArray.left >= 0 && activeArray.top >= 0);
+        checkTrueForKey(key, "values width/height are invalid",
+                activeArray.width() <= pixelArraySize.getWidth() &&
+                activeArray.height() <= pixelArraySize.getHeight());
+
+        return activeArray;
+    }
+
+    /**
+     * Get and check active array size.
+     */
+    public Rect getActiveArraySizeChecked() {
+        Key<Rect> key = CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE;
+        Rect activeArray = getValueFromKeyNonNull(key);
+
+        if (activeArray == null) {
+            return new Rect(0, 0, 0, 0);
+        }
+
+        Size pixelArraySize = getPixelArraySizeChecked();
+        checkTrueForKey(key, "values left/top are invalid", activeArray.left >= 0 && activeArray.top >= 0);
+        checkTrueForKey(key, "values width/height are invalid",
+                activeArray.width() <= pixelArraySize.getWidth() &&
+                activeArray.height() <= pixelArraySize.getHeight());
+
+        return activeArray;
+    }
+
+    /**
+     * Get the dimensions to use for RAW16 buffers.
+     */
+    public Size getRawDimensChecked() throws Exception {
+        Size[] targetCaptureSizes = getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
+                        StaticMetadata.StreamDirection.Output);
+        Assert.assertTrue("No capture sizes available for RAW format!",
+                targetCaptureSizes.length != 0);
+        Rect activeArray = getPreCorrectedActiveArraySizeChecked();
+        Size preCorrectionActiveArraySize =
+                new Size(activeArray.width(), activeArray.height());
+        Size pixelArraySize = getPixelArraySizeChecked();
+        Assert.assertTrue("Missing pre-correction active array size", activeArray.width() > 0 &&
+                activeArray.height() > 0);
+        Assert.assertTrue("Missing pixel array size", pixelArraySize.getWidth() > 0 &&
+                pixelArraySize.getHeight() > 0);
+        Size[] allowedArraySizes = new Size[] { preCorrectionActiveArraySize,
+                pixelArraySize };
+        return assertArrayContainsAnyOf("Available sizes for RAW format" +
+                " must include either the pre-corrected active array size, or the full " +
+                "pixel array size", targetCaptureSizes, allowedArraySizes);
+    }
+
+    /**
+     * Get the sensitivity value and clamp to the range if needed.
+     *
+     * @param sensitivity Input sensitivity value to check.
+     * @return Sensitivity value in legal range.
+     */
+    public int getSensitivityClampToRange(int sensitivity) {
+        int minSensitivity = getSensitivityMinimumOrDefault(Integer.MAX_VALUE);
+        int maxSensitivity = getSensitivityMaximumOrDefault(Integer.MIN_VALUE);
+        if (minSensitivity > SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST) {
+            failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE,
+                    String.format(
+                    "Min value %d is too large, set to maximal legal value %d",
+                    minSensitivity, SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST));
+            minSensitivity = SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST;
+        }
+        if (maxSensitivity < SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST) {
+            failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE,
+                    String.format(
+                    "Max value %d is too small, set to minimal legal value %d",
+                    maxSensitivity, SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST));
+            maxSensitivity = SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST;
+        }
+
+        return Math.max(minSensitivity, Math.min(maxSensitivity, sensitivity));
+    }
+
+    /**
+     * Get maxAnalogSensitivity for a camera device.
+     * <p>
+     * This is only available for FULL capability device, return 0 if it is unavailable.
+     * </p>
+     *
+     * @return maxAnalogSensitivity, 0 if it is not available.
+     */
+    public int getMaxAnalogSensitivityChecked() {
+
+        Key<Integer> key = CameraCharacteristics.SENSOR_MAX_ANALOG_SENSITIVITY;
+        Integer maxAnalogsensitivity = mCharacteristics.get(key);
+        if (maxAnalogsensitivity == null) {
+            if (isHardwareLevelFull()) {
+                Assert.fail("Full device should report max analog sensitivity");
+            }
+            return 0;
+        }
+
+        int minSensitivity = getSensitivityMinimumOrDefault();
+        int maxSensitivity = getSensitivityMaximumOrDefault();
+        checkTrueForKey(key, " Max analog sensitivity " + maxAnalogsensitivity
+                + " should be no larger than max sensitivity " + maxSensitivity,
+                maxAnalogsensitivity <= maxSensitivity);
+        checkTrueForKey(key, " Max analog sensitivity " + maxAnalogsensitivity
+                + " should be larger than min sensitivity " + maxSensitivity,
+                maxAnalogsensitivity > minSensitivity);
+
+        return maxAnalogsensitivity;
+    }
+
+    /**
+     * Get hyperfocalDistance and do the sanity check.
+     * <p>
+     * Note that, this tag is optional, will return -1 if this tag is not
+     * available.
+     * </p>
+     *
+     * @return hyperfocalDistance of this device, -1 if this tag is not available.
+     */
+    public float getHyperfocalDistanceChecked() {
+        Key<Float> key = CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE;
+        Float hyperfocalDistance = getValueFromKeyNonNull(key);
+        if (hyperfocalDistance == null) {
+            return -1;
+        }
+
+        if (hasFocuser()) {
+            float minFocusDistance = getMinimumFocusDistanceChecked();
+            checkTrueForKey(key, String.format(" hyperfocal distance %f should be in the range of"
+                    + " should be in the range of (%f, %f]", hyperfocalDistance, 0.0f,
+                    minFocusDistance),
+                    hyperfocalDistance > 0 && hyperfocalDistance <= minFocusDistance);
+        }
+
+        return hyperfocalDistance;
+    }
+
+    /**
+     * Get the minimum value for a sensitivity range from android.sensor.info.sensitivityRange.
+     *
+     * <p>If the camera is incorrectly reporting values, log a warning and return
+     * the default value instead, which is the largest minimum value required to be supported
+     * by all camera devices.</p>
+     *
+     * @return The value reported by the camera device or the defaultValue otherwise.
+     */
+    public int getSensitivityMinimumOrDefault() {
+        return getSensitivityMinimumOrDefault(SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST);
+    }
+
+    /**
+     * Get the minimum value for a sensitivity range from android.sensor.info.sensitivityRange.
+     *
+     * <p>If the camera is incorrectly reporting values, log a warning and return
+     * the default value instead.</p>
+     *
+     * @param defaultValue Value to return if no legal value is available
+     * @return The value reported by the camera device or the defaultValue otherwise.
+     */
+    public int getSensitivityMinimumOrDefault(int defaultValue) {
+        Range<Integer> range = getValueFromKeyNonNull(
+                CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE);
+        if (range == null) {
+            failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE,
+                    "had no valid minimum value; using default of " + defaultValue);
+            return defaultValue;
+        }
+        return range.getLower();
+    }
+
+    /**
+     * Get the maximum value for a sensitivity range from android.sensor.info.sensitivityRange.
+     *
+     * <p>If the camera is incorrectly reporting values, log a warning and return
+     * the default value instead, which is the smallest maximum value required to be supported
+     * by all camera devices.</p>
+     *
+     * @return The value reported by the camera device or the defaultValue otherwise.
+     */
+    public int getSensitivityMaximumOrDefault() {
+        return getSensitivityMaximumOrDefault(SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST);
+    }
+
+    /**
+     * Get the maximum value for a sensitivity range from android.sensor.info.sensitivityRange.
+     *
+     * <p>If the camera is incorrectly reporting values, log a warning and return
+     * the default value instead.</p>
+     *
+     * @param defaultValue Value to return if no legal value is available
+     * @return The value reported by the camera device or the defaultValue otherwise.
+     */
+    public int getSensitivityMaximumOrDefault(int defaultValue) {
+        Range<Integer> range = getValueFromKeyNonNull(
+                CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE);
+        if (range == null) {
+            failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE,
+                    "had no valid maximum value; using default of " + defaultValue);
+            return defaultValue;
+        }
+        return range.getUpper();
+    }
+
+    /**
+     * Get the minimum value for an exposure range from android.sensor.info.exposureTimeRange.
+     *
+     * <p>If the camera is incorrectly reporting values, log a warning and return
+     * the default value instead.</p>
+     *
+     * @param defaultValue Value to return if no legal value is available
+     * @return The value reported by the camera device or the defaultValue otherwise.
+     */
+    public long getExposureMinimumOrDefault(long defaultValue) {
+        Range<Long> range = getValueFromKeyNonNull(
+                CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
+        if (range == null) {
+            failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE,
+                    "had no valid minimum value; using default of " + defaultValue);
+            return defaultValue;
+        }
+        return range.getLower();
+    }
+
+    /**
+     * Get the minimum value for an exposure range from android.sensor.info.exposureTimeRange.
+     *
+     * <p>If the camera is incorrectly reporting values, log a warning and return
+     * the default value instead, which is the largest minimum value required to be supported
+     * by all camera devices.</p>
+     *
+     * @return The value reported by the camera device or the defaultValue otherwise.
+     */
+    public long getExposureMinimumOrDefault() {
+        return getExposureMinimumOrDefault(SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST);
+    }
+
+    /**
+     * Get the maximum value for an exposure range from android.sensor.info.exposureTimeRange.
+     *
+     * <p>If the camera is incorrectly reporting values, log a warning and return
+     * the default value instead.</p>
+     *
+     * @param defaultValue Value to return if no legal value is available
+     * @return The value reported by the camera device or the defaultValue otherwise.
+     */
+    public long getExposureMaximumOrDefault(long defaultValue) {
+        Range<Long> range = getValueFromKeyNonNull(
+                CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
+        if (range == null) {
+            failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE,
+                    "had no valid maximum value; using default of " + defaultValue);
+            return defaultValue;
+        }
+        return range.getUpper();
+    }
+
+    /**
+     * Get the maximum value for an exposure range from android.sensor.info.exposureTimeRange.
+     *
+     * <p>If the camera is incorrectly reporting values, log a warning and return
+     * the default value instead, which is the smallest maximum value required to be supported
+     * by all camera devices.</p>
+     *
+     * @return The value reported by the camera device or the defaultValue otherwise.
+     */
+    public long getExposureMaximumOrDefault() {
+        return getExposureMaximumOrDefault(SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST);
+    }
+
+    /**
+     * get android.control.availableModes and do the sanity check.
+     *
+     * @return available control modes.
+     */
+    public int[] getAvailableControlModesChecked() {
+        Key<int[]> modesKey = CameraCharacteristics.CONTROL_AVAILABLE_MODES;
+        int[] modes = getValueFromKeyNonNull(modesKey);
+        if (modes == null) {
+            modes = new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+        checkTrueForKey(modesKey, "value is empty", !modeList.isEmpty());
+
+        // All camera device must support AUTO
+        checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain AUTO mode",
+                modeList.contains(CameraMetadata.CONTROL_MODE_AUTO));
+
+        boolean isAeOffSupported =  Arrays.asList(
+                CameraTestUtils.toObject(getAeAvailableModesChecked())).contains(
+                        CameraMetadata.CONTROL_AE_MODE_OFF);
+        boolean isAfOffSupported =  Arrays.asList(
+                CameraTestUtils.toObject(getAfAvailableModesChecked())).contains(
+                        CameraMetadata.CONTROL_AF_MODE_OFF);
+        boolean isAwbOffSupported =  Arrays.asList(
+                CameraTestUtils.toObject(getAwbAvailableModesChecked())).contains(
+                        CameraMetadata.CONTROL_AWB_MODE_OFF);
+        if (isAeOffSupported && isAfOffSupported && isAwbOffSupported) {
+            // 3A OFF controls are supported, OFF mode must be supported here.
+            checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain OFF mode",
+                    modeList.contains(CameraMetadata.CONTROL_MODE_OFF));
+        }
+
+        if (isSceneModeSupported()) {
+            checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain"
+                    + " USE_SCENE_MODE",
+                    modeList.contains(CameraMetadata.CONTROL_MODE_USE_SCENE_MODE));
+        }
+
+        return modes;
+    }
+
+    public boolean isSceneModeSupported() {
+        List<Integer> availableSceneModes = Arrays.asList(
+                CameraTestUtils.toObject(getAvailableSceneModesChecked()));
+
+        if (availableSceneModes.isEmpty()) {
+            return false;
+        }
+
+        // If sceneMode is not supported, camera device will contain single entry: DISABLED.
+        return availableSceneModes.size() > 1 ||
+                !availableSceneModes.contains(CameraMetadata.CONTROL_SCENE_MODE_DISABLED);
+    }
+
+    /**
+     * Get aeAvailableModes and do the sanity check.
+     *
+     * <p>Depending on the check level this class has, for WAR or COLLECT levels,
+     * If the aeMode list is invalid, return an empty mode array. The the caller doesn't
+     * have to abort the execution even the aeMode list is invalid.</p>
+     * @return AE available modes
+     */
+    public int[] getAeAvailableModesChecked() {
+        Key<int[]> modesKey = CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES;
+        int[] modes = getValueFromKeyNonNull(modesKey);
+        if (modes == null) {
+            modes = new int[0];
+        }
+        List<Integer> modeList = new ArrayList<Integer>();
+        for (int mode : modes) {
+            modeList.add(mode);
+        }
+        checkTrueForKey(modesKey, "value is empty", !modeList.isEmpty());
+
+        // All camera device must support ON
+        checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain ON mode",
+                modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON));
+
+        // All camera devices with flash units support ON_AUTO_FLASH and ON_ALWAYS_FLASH
+        Key<Boolean> flashKey= CameraCharacteristics.FLASH_INFO_AVAILABLE;
+        Boolean hasFlash = getValueFromKeyNonNull(flashKey);
+        if (hasFlash == null) {
+            hasFlash = false;
+        }
+        if (hasFlash) {
+            boolean flashModeConsistentWithFlash =
+                    modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH) &&
+                    modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
+            checkTrueForKey(modesKey,
+                    "value must contain ON_AUTO_FLASH and ON_ALWAYS_FLASH and  when flash is" +
+                    "available", flashModeConsistentWithFlash);
+        } else {
+            boolean flashModeConsistentWithoutFlash =
+                    !(modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH) ||
+                    modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH) ||
+                    modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE));
+            checkTrueForKey(modesKey,
+                    "value must not contain ON_AUTO_FLASH, ON_ALWAYS_FLASH and" +
+                    "ON_AUTO_FLASH_REDEYE when flash is unavailable",
+                    flashModeConsistentWithoutFlash);
+        }
+
+        // FULL mode camera devices always support OFF mode.
+        boolean condition =
+                !isHardwareLevelFull() || modeList.contains(CameraMetadata.CONTROL_AE_MODE_OFF);
+        checkTrueForKey(modesKey, "Full capability device must have OFF mode", condition);
+
+        // Boundary check.
+        for (int mode : modes) {
+            checkTrueForKey(modesKey, "Value " + mode + " is out of bound",
+                    mode >= CameraMetadata.CONTROL_AE_MODE_OFF
+                    && mode <= CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE);
+        }
+
+        return modes;
+    }
+
+    /**
+     * Get available AWB modes and do the sanity check.
+     *
+     * @return array that contains available AWB modes, empty array if awbAvailableModes is
+     * unavailable.
+     */
+    public int[] getAwbAvailableModesChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES;
+        int[] awbModes = getValueFromKeyNonNull(key);
+
+        if (awbModes == null) {
+            return new int[0];
+        }
+
+        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()) {
+            checkTrueForKey(key, " Full capability camera devices must support OFF mode",
+                    modesList.contains(CameraMetadata.CONTROL_AWB_MODE_OFF));
+        }
+
+        return awbModes;
+    }
+
+    /**
+     * Get available AF modes and do the sanity check.
+     *
+     * @return array that contains available AF modes, empty array if afAvailableModes is
+     * unavailable.
+     */
+    public int[] getAfAvailableModesChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES;
+        int[] afModes = getValueFromKeyNonNull(key);
+
+        if (afModes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modesList = Arrays.asList(CameraTestUtils.toObject(afModes));
+        if (isHardwareLevelLimitedOrBetter()) {
+            // 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));
+        }
+        if (hasFocuser()) {
+            checkTrueForKey(key, " Camera devices that have focuser units must support AUTO mode",
+                    modesList.contains(CameraMetadata.CONTROL_AF_MODE_AUTO));
+        }
+
+        return afModes;
+    }
+
+    /**
+     * Get supported raw output sizes and do the check.
+     *
+     * @return Empty size array if raw output is not supported
+     */
+    public Size[] getRawOutputSizesChecked() {
+        return getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
+                StreamDirection.Output);
+    }
+
+    /**
+     * Get supported jpeg output sizes and do the check.
+     *
+     * @return Empty size array if jpeg output is not supported
+     */
+    public Size[] getJpegOutputSizesChecked() {
+        return getAvailableSizesForFormatChecked(ImageFormat.JPEG,
+                StreamDirection.Output);
+    }
+
+    /**
+     * Used to determine the stream direction for various helpers that look up
+     * format or size information.
+     */
+    public enum StreamDirection {
+        /** Stream is used with {@link android.hardware.camera2.CameraDevice#configureOutputs} */
+        Output,
+        /** Stream is used with {@code CameraDevice#configureInputs} -- NOT YET PUBLIC */
+        Input
+    }
+
+    /**
+     * Get available formats for a given direction.
+     *
+     * @param direction The stream direction, input or output.
+     * @return The formats of the given direction, empty array if no available format is found.
+     */
+    public int[] getAvailableFormats(StreamDirection direction) {
+        Key<StreamConfigurationMap> key =
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
+        StreamConfigurationMap config = getValueFromKeyNonNull(key);
+
+        if (config == null) {
+            return new int[0];
+        }
+
+        switch (direction) {
+            case Output:
+                return config.getOutputFormats();
+            case Input:
+                return config.getInputFormats();
+            default:
+                throw new IllegalArgumentException("direction must be output or input");
+        }
+    }
+
+    /**
+     * Get valid output formats for a given input format.
+     *
+     * @param inputFormat The input format used to produce the output images.
+     * @return The output formats for the given input format, empty array if
+     *         no available format is found.
+     */
+    public int[] getValidOutputFormatsForInput(int inputFormat) {
+        Key<StreamConfigurationMap> key =
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
+        StreamConfigurationMap config = getValueFromKeyNonNull(key);
+
+        if (config == null) {
+            return new int[0];
+        }
+
+        return config.getValidOutputFormatsForInput(inputFormat);
+    }
+
+    /**
+     * Get available sizes for given format and direction.
+     *
+     * @param format The format for the requested size array.
+     * @param direction The stream direction, input or output.
+     * @return The sizes of the given format, empty array if no available size is found.
+     */
+    public Size[] getAvailableSizesForFormatChecked(int format, StreamDirection direction) {
+        return getAvailableSizesForFormatChecked(format, direction,
+                /*fastSizes*/true, /*slowSizes*/true);
+    }
+
+    /**
+     * Get available sizes for given format and direction, and whether to limit to slow or fast
+     * resolutions.
+     *
+     * @param format The format for the requested size array.
+     * @param direction The stream direction, input or output.
+     * @param fastSizes whether to include getOutputSizes() sizes (generally faster)
+     * @param slowSizes whether to include getHighResolutionOutputSizes() sizes (generally slower)
+     * @return The sizes of the given format, empty array if no available size is found.
+     */
+    public Size[] getAvailableSizesForFormatChecked(int format, StreamDirection direction,
+            boolean fastSizes, boolean slowSizes) {
+        Key<StreamConfigurationMap> key =
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
+        StreamConfigurationMap config = getValueFromKeyNonNull(key);
+
+        if (config == null) {
+            return new Size[0];
+        }
+
+        Size[] sizes = null;
+
+        switch (direction) {
+            case Output:
+                Size[] fastSizeList = null;
+                Size[] slowSizeList = null;
+                if (fastSizes) {
+                    fastSizeList = config.getOutputSizes(format);
+                }
+                if (slowSizes) {
+                    slowSizeList = config.getHighResolutionOutputSizes(format);
+                }
+                if (fastSizeList != null && slowSizeList != null) {
+                    sizes = new Size[slowSizeList.length + fastSizeList.length];
+                    System.arraycopy(fastSizeList, 0, sizes, 0, fastSizeList.length);
+                    System.arraycopy(slowSizeList, 0, sizes, fastSizeList.length, slowSizeList.length);
+                } else if (fastSizeList != null) {
+                    sizes = fastSizeList;
+                } else if (slowSizeList != null) {
+                    sizes = slowSizeList;
+                }
+                break;
+            case Input:
+                sizes = config.getInputSizes(format);
+                break;
+            default:
+                throw new IllegalArgumentException("direction must be output or input");
+        }
+
+        if (sizes == null) {
+            sizes = new Size[0];
+        }
+
+        return sizes;
+    }
+
+    /**
+     * Get available AE target fps ranges.
+     *
+     * @return Empty int array if aeAvailableTargetFpsRanges is invalid.
+     */
+    @SuppressWarnings("raw")
+    public Range<Integer>[] getAeAvailableTargetFpsRangesChecked() {
+        Key<Range<Integer>[]> key =
+                CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES;
+        Range<Integer>[] fpsRanges = getValueFromKeyNonNull(key);
+
+        if (fpsRanges == null) {
+            return new Range[0];
+        }
+
+        // Round down to 2 boundary if it is not integer times of 2, to avoid array out of bound
+        // in case the above check fails.
+        int fpsRangeLength = fpsRanges.length;
+        int minFps, maxFps;
+        long maxFrameDuration = getMaxFrameDurationChecked();
+        for (int i = 0; i < fpsRangeLength; i += 1) {
+            minFps = fpsRanges[i].getLower();
+            maxFps = fpsRanges[i].getUpper();
+            checkTrueForKey(key, " min fps must be no larger than max fps!",
+                    minFps > 0 && maxFps >= minFps);
+            long maxDuration = (long) (1e9 / minFps);
+            checkTrueForKey(key, String.format(
+                    " the frame duration %d for min fps %d must smaller than maxFrameDuration %d",
+                    maxDuration, minFps, maxFrameDuration), maxDuration <= maxFrameDuration);
+        }
+        return fpsRanges;
+    }
+
+    /**
+     * Get the highest supported target FPS range.
+     * Prioritizes maximizing the min FPS, then the max FPS without lowering min FPS.
+     */
+    public Range<Integer> getAeMaxTargetFpsRange() {
+        Range<Integer>[] fpsRanges = getAeAvailableTargetFpsRangesChecked();
+
+        Range<Integer> targetRange = fpsRanges[0];
+        // Assume unsorted list of target FPS ranges, so use two passes, first maximize min FPS
+        for (Range<Integer> candidateRange : fpsRanges) {
+            if (candidateRange.getLower() > targetRange.getLower()) {
+                targetRange = candidateRange;
+            }
+        }
+        // Then maximize max FPS while not lowering min FPS
+        for (Range<Integer> candidateRange : fpsRanges) {
+            if (candidateRange.getLower() >= targetRange.getLower() &&
+                    candidateRange.getUpper() > targetRange.getUpper()) {
+                targetRange = candidateRange;
+            }
+        }
+        return targetRange;
+    }
+
+    /**
+     * Get max frame duration.
+     *
+     * @return 0 if maxFrameDuration is null
+     */
+    public long getMaxFrameDurationChecked() {
+        Key<Long> key =
+                CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION;
+        Long maxDuration = getValueFromKeyNonNull(key);
+
+        if (maxDuration == null) {
+            return 0;
+        }
+
+        return maxDuration;
+    }
+
+    /**
+     * Get available minimal frame durations for a given format.
+     *
+     * @param format One of the format from {@link ImageFormat}.
+     * @return HashMap of minimal frame durations for different sizes, empty HashMap
+     *         if availableMinFrameDurations is null.
+     */
+    public HashMap<Size, Long> getAvailableMinFrameDurationsForFormatChecked(int format) {
+
+        HashMap<Size, Long> minDurationMap = new HashMap<Size, Long>();
+
+        Key<StreamConfigurationMap> key =
+                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
+        StreamConfigurationMap config = getValueFromKeyNonNull(key);
+
+        if (config == null) {
+            return minDurationMap;
+        }
+
+        for (android.util.Size size : getAvailableSizesForFormatChecked(format,
+                StreamDirection.Output)) {
+            long minFrameDuration = config.getOutputMinFrameDuration(format, size);
+
+            if (minFrameDuration != 0) {
+                minDurationMap.put(new Size(size.getWidth(), size.getHeight()), minFrameDuration);
+            }
+        }
+
+        return minDurationMap;
+    }
+
+    public int[] getAvailableEdgeModesChecked() {
+        Key<int[]> key = CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES;
+        int[] edgeModes = getValueFromKeyNonNull(key);
+
+        if (edgeModes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(edgeModes));
+        // Full device should always include OFF and FAST
+        if (isHardwareLevelFull()) {
+            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()) {
+            // FAST and HIGH_QUALITY mode must be both present or both not present
+            List<Integer> coupledModes = Arrays.asList(new Integer[] {
+                    CameraMetadata.EDGE_MODE_FAST,
+                    CameraMetadata.EDGE_MODE_HIGH_QUALITY
+            });
+            checkTrueForKey(
+                    key, " FAST and HIGH_QUALITY mode must both present or both not present",
+                    containsAllOrNone(modeList, coupledModes));
+        }
+
+        return edgeModes;
+    }
+
+    public int[] getAvailableNoiseReductionModesChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
+        int[] noiseReductionModes = getValueFromKeyNonNull(key);
+
+        if (noiseReductionModes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(noiseReductionModes));
+        // Full device should always include OFF and FAST
+        if (isHardwareLevelFull()) {
+
+            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()) {
+            // 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,
+                    CameraMetadata.NOISE_REDUCTION_MODE_HIGH_QUALITY
+            });
+            checkTrueForKey(
+                    key, " FAST and HIGH_QUALITY mode must both present or both not present",
+                    containsAllOrNone(modeList, coupledModes));
+        }
+        return noiseReductionModes;
+    }
+
+    /**
+     * Get value of key android.control.aeCompensationStep and do the sanity check.
+     *
+     * @return default value if the value is null.
+     */
+    public Rational getAeCompensationStepChecked() {
+        Key<Rational> key =
+                CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP;
+        Rational compensationStep = getValueFromKeyNonNull(key);
+
+        if (compensationStep == null) {
+            // Return default step.
+            return CONTROL_AE_COMPENSATION_STEP_DEFAULT;
+        }
+
+        // Legacy devices don't have a minimum step requirement
+        if (isHardwareLevelLimitedOrBetter()) {
+            float compensationStepF =
+                    (float) compensationStep.getNumerator() / compensationStep.getDenominator();
+            checkTrueForKey(key, " value must be no more than 1/2", compensationStepF <= 0.5f);
+        }
+
+        return compensationStep;
+    }
+
+    /**
+     * Get value of key android.control.aeCompensationRange and do the sanity check.
+     *
+     * @return default value if the value is null or malformed.
+     */
+    public Range<Integer> getAeCompensationRangeChecked() {
+        Key<Range<Integer>> key =
+                CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE;
+        Range<Integer> compensationRange = getValueFromKeyNonNull(key);
+        Rational compensationStep = getAeCompensationStepChecked();
+        float compensationStepF = compensationStep.floatValue();
+        final Range<Integer> DEFAULT_RANGE = Range.create(
+                (int)(CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MIN / compensationStepF),
+                (int)(CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MAX / compensationStepF));
+        final Range<Integer> ZERO_RANGE = Range.create(0, 0);
+        if (compensationRange == null) {
+            return ZERO_RANGE;
+        }
+
+        // Legacy devices don't have a minimum range requirement
+        if (isHardwareLevelLimitedOrBetter() && !compensationRange.equals(ZERO_RANGE)) {
+            checkTrueForKey(key, " range value must be at least " + DEFAULT_RANGE
+                    + ", actual " + compensationRange + ", compensation step " + compensationStep,
+                   compensationRange.getLower() <= DEFAULT_RANGE.getLower() &&
+                   compensationRange.getUpper() >= DEFAULT_RANGE.getUpper());
+        }
+
+        return compensationRange;
+    }
+
+    /**
+     * Get availableVideoStabilizationModes and do the sanity check.
+     *
+     * @return available video stabilization modes, empty array if it is unavailable.
+     */
+    public int[] getAvailableVideoStabilizationModesChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        if (modes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+        checkTrueForKey(key, " All device should support OFF mode",
+                modeList.contains(CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF));
+        checkArrayValuesInRange(key, modes,
+                CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF,
+                CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON);
+
+        return modes;
+    }
+
+    /**
+     * Get availableOpticalStabilization and do the sanity check.
+     *
+     * @return available optical stabilization modes, empty array if it is unavailable.
+     */
+    public int[] getAvailableOpticalStabilizationChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        if (modes == null) {
+            return new int[0];
+        }
+
+        checkArrayValuesInRange(key, modes,
+                CameraMetadata.LENS_OPTICAL_STABILIZATION_MODE_OFF,
+                CameraMetadata.LENS_OPTICAL_STABILIZATION_MODE_ON);
+
+        return modes;
+    }
+
+    /**
+     * Get the scaler's max digital zoom ({@code >= 1.0f}) ratio between crop and active array
+     * @return the max zoom ratio, or {@code 1.0f} if the value is unavailable
+     */
+    public float getAvailableMaxDigitalZoomChecked() {
+        Key<Float> key =
+                CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM;
+
+        Float maxZoom = getValueFromKeyNonNull(key);
+        if (maxZoom == null) {
+            return 1.0f;
+        }
+
+        checkTrueForKey(key, " max digital zoom should be no less than 1",
+                maxZoom >= 1.0f && !Float.isNaN(maxZoom) && !Float.isInfinite(maxZoom));
+
+        return maxZoom;
+    }
+
+    public int[] getAvailableSceneModesChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        if (modes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+        // FACE_PRIORITY must be included if face detection is supported.
+        if (areKeysAvailable(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT) &&
+                getMaxFaceCountChecked() > 0) {
+            checkTrueForKey(key, " FACE_PRIORITY must be included if face detection is supported",
+                    modeList.contains(CameraMetadata.CONTROL_SCENE_MODE_FACE_PRIORITY));
+        }
+
+        return modes;
+    }
+
+    public int[] getAvailableEffectModesChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        if (modes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+        // OFF must be included.
+        checkTrueForKey(key, " OFF must be included",
+                modeList.contains(CameraMetadata.CONTROL_EFFECT_MODE_OFF));
+
+        return modes;
+    }
+
+    /**
+     * Get and check the available color aberration modes
+     *
+     * @return the available color aberration modes
+     */
+    public int[] getAvailableColorAberrationModesChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
+        int[] modes = getValueFromKeyNonNull(key);
+
+        if (modes == null) {
+            return new int[0];
+        }
+
+        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+        checkTrueForKey(key, " Camera devices must always support either OFF or FAST mode",
+                modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF) ||
+                modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_FAST));
+
+        if (isHardwareLevelLimitedOrBetter()) {
+            // 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,
+                    CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY
+            });
+            checkTrueForKey(
+                    key, " FAST and HIGH_QUALITY mode must both present or both not present",
+                    containsAllOrNone(modeList, coupledModes));
+        }
+        checkElementDistinct(key, modeList);
+        checkArrayValuesInRange(key, modes,
+                CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF,
+                CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY);
+
+        return modes;
+    }
+
+    /**
+     * Get max pipeline depth and do the sanity check.
+     *
+     * @return max pipeline depth, default value if it is not available.
+     */
+    public byte getPipelineMaxDepthChecked() {
+        Key<Byte> key =
+                CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH;
+        Byte maxDepth = getValueFromKeyNonNull(key);
+
+        if (maxDepth == null) {
+            return REQUEST_PIPELINE_MAX_DEPTH_MAX;
+        }
+
+        checkTrueForKey(key, " max pipeline depth should be no larger than "
+                + REQUEST_PIPELINE_MAX_DEPTH_MAX, maxDepth <= REQUEST_PIPELINE_MAX_DEPTH_MAX);
+
+        return maxDepth;
+    }
+
+    /**
+     * Get available lens shading modes.
+     */
+     public int[] getAvailableLensShadingModesChecked() {
+         Key<int[]> key =
+                 CameraCharacteristics.SHADING_AVAILABLE_MODES;
+         int[] modes = getValueFromKeyNonNull(key);
+         if (modes == null) {
+             return new int[0];
+         }
+
+         List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+         // FAST must be included.
+         checkTrueForKey(key, " FAST must be included",
+                 modeList.contains(CameraMetadata.SHADING_MODE_FAST));
+
+         if (isCapabilitySupported(
+                 CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING)) {
+             checkTrueForKey(key, " OFF must be included for MANUAL_POST_PROCESSING devices",
+                     modeList.contains(CameraMetadata.SHADING_MODE_OFF));
+         }
+         return modes;
+     }
+
+     /**
+      * Get available lens shading map modes.
+      */
+      public int[] getAvailableLensShadingMapModesChecked() {
+          Key<int[]> key =
+                  CameraCharacteristics.STATISTICS_INFO_AVAILABLE_LENS_SHADING_MAP_MODES;
+          int[] modes = getValueFromKeyNonNull(key);
+          if (modes == null) {
+              return new int[0];
+          }
+
+          List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
+
+          if (isCapabilitySupported(
+                  CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
+              checkTrueForKey(key, " ON must be included for RAW capability devices",
+                      modeList.contains(CameraMetadata.STATISTICS_LENS_SHADING_MAP_MODE_ON));
+          }
+          return modes;
+      }
+
+
+    /**
+     * Get available capabilities and do the sanity check.
+     *
+     * @return reported available capabilities list, empty list if the value is unavailable.
+     */
+    public List<Integer> getAvailableCapabilitiesChecked() {
+        Key<int[]> key =
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES;
+        int[] availableCaps = getValueFromKeyNonNull(key);
+        List<Integer> capList;
+
+        if (availableCaps == null) {
+            return new ArrayList<Integer>();
+        }
+
+        checkArrayValuesInRange(key, availableCaps,
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO);
+        capList = Arrays.asList(CameraTestUtils.toObject(availableCaps));
+        return capList;
+    }
+
+    /**
+     * Determine whether the current device supports a capability or not.
+     *
+     * @param capability (non-negative)
+     *
+     * @return {@code true} if the capability is supported, {@code false} otherwise.
+     *
+     * @throws IllegalArgumentException if {@code capability} was negative
+     *
+     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
+     */
+    public boolean isCapabilitySupported(int capability) {
+        if (capability < 0) {
+            throw new IllegalArgumentException("capability must be non-negative");
+        }
+
+        List<Integer> availableCapabilities = getAvailableCapabilitiesChecked();
+
+        return availableCapabilities.contains(capability);
+    }
+
+    /**
+     * Determine whether or not all the {@code keys} are available characteristics keys
+     * (as in {@link CameraCharacteristics#getKeys}.
+     *
+     * <p>If this returns {@code true}, then querying for this key from a characteristics
+     * object will always return a non-{@code null} value.</p>
+     *
+     * @param keys collection of camera characteristics keys
+     * @return whether or not all characteristics keys are available
+     */
+    public final boolean areCharacteristicsKeysAvailable(
+            Collection<CameraCharacteristics.Key<?>> keys) {
+        return mCharacteristics.getKeys().containsAll(keys);
+    }
+
+    /**
+     * Determine whether or not all the {@code keys} are available result keys
+     * (as in {@link CameraCharacteristics#getAvailableCaptureResultKeys}.
+     *
+     * <p>If this returns {@code true}, then querying for this key from a result
+     * object will almost always return a non-{@code null} value.</p>
+     *
+     * <p>In some cases (e.g. lens shading map), the request must have additional settings
+     * configured in order for the key to correspond to a value.</p>
+     *
+     * @param keys collection of capture result keys
+     * @return whether or not all result keys are available
+     */
+    public final boolean areResultKeysAvailable(Collection<CaptureResult.Key<?>> keys) {
+        return mCharacteristics.getAvailableCaptureResultKeys().containsAll(keys);
+    }
+
+    /**
+     * Determine whether or not all the {@code keys} are available request keys
+     * (as in {@link CameraCharacteristics#getAvailableCaptureRequestKeys}.
+     *
+     * <p>If this returns {@code true}, then setting this key in the request builder
+     * may have some effect (and if it's {@code false}, then the camera device will
+     * definitely ignore it).</p>
+     *
+     * <p>In some cases (e.g. manual control of exposure), other keys must be also be set
+     * in order for a key to take effect (e.g. control.mode set to OFF).</p>
+     *
+     * @param keys collection of capture request keys
+     * @return whether or not all result keys are available
+     */
+    public final boolean areRequestKeysAvailable(Collection<CaptureRequest.Key<?>> keys) {
+        return mCharacteristics.getAvailableCaptureRequestKeys().containsAll(keys);
+    }
+
+    /**
+     * Determine whether or not all the {@code keys} are available characteristics keys
+     * (as in {@link CameraCharacteristics#getKeys}.
+     *
+     * <p>If this returns {@code true}, then querying for this key from a characteristics
+     * object will always return a non-{@code null} value.</p>
+     *
+     * @param keys one or more camera characteristic keys
+     * @return whether or not all characteristics keys are available
+     */
+    @SafeVarargs
+    public final boolean areKeysAvailable(CameraCharacteristics.Key<?>... keys) {
+        return areCharacteristicsKeysAvailable(Arrays.asList(keys));
+    }
+
+    /**
+     * Determine whether or not all the {@code keys} are available result keys
+     * (as in {@link CameraCharacteristics#getAvailableCaptureResultKeys}.
+     *
+     * <p>If this returns {@code true}, then querying for this key from a result
+     * object will almost always return a non-{@code null} value.</p>
+     *
+     * <p>In some cases (e.g. lens shading map), the request must have additional settings
+     * configured in order for the key to correspond to a value.</p>
+     *
+     * @param keys one or more capture result keys
+     * @return whether or not all result keys are available
+     */
+    @SafeVarargs
+    public final boolean areKeysAvailable(CaptureResult.Key<?>... keys) {
+        return areResultKeysAvailable(Arrays.asList(keys));
+    }
+
+    /**
+     * Determine whether or not all the {@code keys} are available request keys
+     * (as in {@link CameraCharacteristics#getAvailableCaptureRequestKeys}.
+     *
+     * <p>If this returns {@code true}, then setting this key in the request builder
+     * may have some effect (and if it's {@code false}, then the camera device will
+     * definitely ignore it).</p>
+     *
+     * <p>In some cases (e.g. manual control of exposure), other keys must be also be set
+     * in order for a key to take effect (e.g. control.mode set to OFF).</p>
+     *
+     * @param keys one or more capture request keys
+     * @return whether or not all result keys are available
+     */
+    @SafeVarargs
+    public final boolean areKeysAvailable(CaptureRequest.Key<?>... keys) {
+        return areRequestKeysAvailable(Arrays.asList(keys));
+    }
+
+    /*
+     * Determine if camera device support AE lock control
+     *
+     * @return {@code true} if AE lock control is supported
+     */
+    public boolean isAeLockSupported() {
+        return getValueFromKeyNonNull(CameraCharacteristics.CONTROL_AE_LOCK_AVAILABLE);
+    }
+
+    /*
+     * Determine if camera device support AWB lock control
+     *
+     * @return {@code true} if AWB lock control is supported
+     */
+    public boolean isAwbLockSupported() {
+        return getValueFromKeyNonNull(CameraCharacteristics.CONTROL_AWB_LOCK_AVAILABLE);
+    }
+
+
+    /*
+     * Determine if camera device support manual lens shading map control
+     *
+     * @return {@code true} if manual lens shading map control is supported
+     */
+    public boolean isManualLensShadingMapSupported() {
+        return areKeysAvailable(CaptureRequest.SHADING_MODE);
+    }
+
+    /**
+     * Determine if camera device support manual color correction control
+     *
+     * @return {@code true} if manual color correction control is supported
+     */
+    public boolean isColorCorrectionSupported() {
+        return areKeysAvailable(CaptureRequest.COLOR_CORRECTION_MODE);
+    }
+
+    /**
+     * Determine if camera device support manual tone mapping control
+     *
+     * @return {@code true} if manual tone mapping control is supported
+     */
+    public boolean isManualToneMapSupported() {
+        return areKeysAvailable(CaptureRequest.TONEMAP_MODE);
+    }
+
+    /**
+     * Determine if camera device support manual color aberration control
+     *
+     * @return {@code true} if manual color aberration control is supported
+     */
+    public boolean isManualColorAberrationControlSupported() {
+        return areKeysAvailable(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE);
+    }
+
+    /**
+     * Determine if camera device support edge mode control
+     *
+     * @return {@code true} if edge mode control is supported
+     */
+    public boolean isEdgeModeControlSupported() {
+        return areKeysAvailable(CaptureRequest.EDGE_MODE);
+    }
+
+    /**
+     * Determine if camera device support hot pixel mode control
+     *
+     * @return {@code true} if hot pixel mode control is supported
+     */
+    public boolean isHotPixelMapModeControlSupported() {
+        return areKeysAvailable(CaptureRequest.HOT_PIXEL_MODE);
+    }
+
+    /**
+     * Determine if camera device support noise reduction mode control
+     *
+     * @return {@code true} if noise reduction mode control is supported
+     */
+    public boolean isNoiseReductionModeControlSupported() {
+        return areKeysAvailable(CaptureRequest.NOISE_REDUCTION_MODE);
+    }
+
+    /**
+     * Get max number of output raw streams and do the basic sanity check.
+     *
+     * @return reported max number of raw output stream
+     */
+    public int getMaxNumOutputStreamsRawChecked() {
+        Integer maxNumStreams =
+                getValueFromKeyNonNull(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW);
+        if (maxNumStreams == null)
+            return 0;
+        return maxNumStreams;
+    }
+
+    /**
+     * Get max number of output processed streams and do the basic sanity check.
+     *
+     * @return reported max number of processed output stream
+     */
+    public int getMaxNumOutputStreamsProcessedChecked() {
+        Integer maxNumStreams =
+                getValueFromKeyNonNull(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC);
+        if (maxNumStreams == null)
+            return 0;
+        return maxNumStreams;
+    }
+
+    /**
+     * Get max number of output stalling processed streams and do the basic sanity check.
+     *
+     * @return reported max number of stalling processed output stream
+     */
+    public int getMaxNumOutputStreamsProcessedStallChecked() {
+        Integer maxNumStreams =
+                getValueFromKeyNonNull(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING);
+        if (maxNumStreams == null)
+            return 0;
+        return maxNumStreams;
+    }
+
+    /**
+     * Get lens facing and do the sanity check
+     * @return lens facing, return default value (BACK) if value is unavailable.
+     */
+    public int getLensFacingChecked() {
+        Key<Integer> key =
+                CameraCharacteristics.LENS_FACING;
+        Integer facing = getValueFromKeyNonNull(key);
+
+        if (facing == null) {
+            return CameraCharacteristics.LENS_FACING_BACK;
+        }
+
+        checkTrueForKey(key, " value is out of range ",
+                facing >= CameraCharacteristics.LENS_FACING_FRONT &&
+                facing <= CameraCharacteristics.LENS_FACING_BACK);
+        return facing;
+    }
+
+    /**
+     * Get maxCaptureStall frames or default value (if value doesn't exist)
+     * @return maxCaptureStall frames or default value.
+     */
+    public int getMaxCaptureStallOrDefault() {
+        Key<Integer> key =
+                CameraCharacteristics.REPROCESS_MAX_CAPTURE_STALL;
+        Integer value = getValueFromKeyNonNull(key);
+
+        if (value == null) {
+            return MAX_REPROCESS_MAX_CAPTURE_STALL;
+        }
+
+        checkTrueForKey(key, " value is out of range ",
+                value >= 0 &&
+                value <= MAX_REPROCESS_MAX_CAPTURE_STALL);
+
+        return value;
+    }
+
+    /**
+     * Get the scaler's cropping type (center only or freeform)
+     * @return cropping type, return default value (CENTER_ONLY) if value is unavailable
+     */
+    public int getScalerCroppingTypeChecked() {
+        Key<Integer> key =
+                CameraCharacteristics.SCALER_CROPPING_TYPE;
+        Integer value = getValueFromKeyNonNull(key);
+
+        if (value == null) {
+            return CameraCharacteristics.SCALER_CROPPING_TYPE_CENTER_ONLY;
+        }
+
+        checkTrueForKey(key, " value is out of range ",
+                value >= CameraCharacteristics.SCALER_CROPPING_TYPE_CENTER_ONLY &&
+                value <= CameraCharacteristics.SCALER_CROPPING_TYPE_FREEFORM);
+
+        return value;
+    }
+
+    /**
+     * Check if the constrained high speed video is supported by the camera device.
+     * The high speed FPS ranges and sizes are sanitized in
+     * ExtendedCameraCharacteristicsTest#testConstrainedHighSpeedCapability.
+     *
+     * @return true if the constrained high speed video is supported, false otherwise.
+     */
+    public boolean isConstrainedHighSpeedVideoSupported() {
+        List<Integer> availableCapabilities = getAvailableCapabilitiesChecked();
+        return (availableCapabilities.contains(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO));
+    }
+
+    /**
+     * Check if high speed video is supported (HIGH_SPEED_VIDEO scene mode is
+     * supported, supported high speed fps ranges and sizes are valid).
+     *
+     * @return true if high speed video is supported.
+     */
+    public boolean isHighSpeedVideoSupported() {
+        List<Integer> sceneModes =
+                Arrays.asList(CameraTestUtils.toObject(getAvailableSceneModesChecked()));
+        if (sceneModes.contains(CameraCharacteristics.CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO)) {
+            StreamConfigurationMap config =
+                    getValueFromKeyNonNull(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
+            if (config == null) {
+                return false;
+            }
+            Size[] availableSizes = config.getHighSpeedVideoSizes();
+            if (availableSizes.length == 0) {
+                return false;
+            }
+
+            for (Size size : availableSizes) {
+                Range<Integer>[] availableFpsRanges = config.getHighSpeedVideoFpsRangesFor(size);
+                if (availableFpsRanges.length == 0) {
+                    return false;
+                }
+            }
+
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Check if depth output is supported, based on the depth capability
+     */
+    public boolean isDepthOutputSupported() {
+        return isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT);
+    }
+
+    /**
+     * Check if standard outputs (PRIVATE, YUV, JPEG) outputs are supported, based on the
+     * backwards-compatible capability
+     */
+    public boolean isColorOutputSupported() {
+        return isCapabilitySupported(
+                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE);
+    }
+
+    /**
+     * 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
+     * the default value instead.</p>
+     *
+     * @param key Key to fetch
+     * @param defaultValue Default value to return if camera device uses invalid values
+     * @param name Human-readable name for the array index (logging only)
+     * @param index Array index of the subelement
+     * @param size Expected fixed size of the array
+     *
+     * @return The value reported by the camera device, or the defaultValue otherwise.
+     */
+    private <T> T getArrayElementOrDefault(Key<?> key, T defaultValue, String name, int index,
+            int size) {
+        T elementValue = getArrayElementCheckRangeNonNull(
+                key,
+                index,
+                size);
+
+        if (elementValue == null) {
+            failKeyCheck(key,
+                    "had no valid " + name + " value; using default of " + defaultValue);
+            elementValue = defaultValue;
+        }
+
+        return elementValue;
+    }
+
+    /**
+     * Fetch an array sub-element from an array value given by a key.
+     *
+     * <p>
+     * Prints a warning if the sub-element was null.
+     * </p>
+     *
+     * <p>Use for variable-size arrays since this does not check the array size.</p>
+     *
+     * @param key Metadata key to look up
+     * @param element A non-negative index value.
+     * @return The array sub-element, or null if the checking failed.
+     */
+    private <T> T getArrayElementNonNull(Key<?> key, int element) {
+        return getArrayElementCheckRangeNonNull(key, element, IGNORE_SIZE_CHECK);
+    }
+
+    /**
+     * Fetch an array sub-element from an array value given by a key.
+     *
+     * <p>
+     * Prints a warning if the array size does not match the size, or if the sub-element was null.
+     * </p>
+     *
+     * @param key Metadata key to look up
+     * @param element The index in [0,size)
+     * @param size A positive size value or otherwise {@value #IGNORE_SIZE_CHECK}
+     * @return The array sub-element, or null if the checking failed.
+     */
+    private <T> T getArrayElementCheckRangeNonNull(Key<?> key, int element, int size) {
+        Object array = getValueFromKeyNonNull(key);
+
+        if (array == null) {
+            // Warning already printed
+            return null;
+        }
+
+        if (size != IGNORE_SIZE_CHECK) {
+            int actualLength = Array.getLength(array);
+            if (actualLength != size) {
+                failKeyCheck(key,
+                        String.format("had the wrong number of elements (%d), expected (%d)",
+                                actualLength, size));
+                return null;
+            }
+        }
+
+        @SuppressWarnings("unchecked")
+        T val = (T) Array.get(array, element);
+
+        if (val == null) {
+            failKeyCheck(key, "had a null element at index" + element);
+            return null;
+        }
+
+        return val;
+    }
+
+    /**
+     * Gets the key, logging warnings for null values.
+     */
+    public <T> T getValueFromKeyNonNull(Key<T> key) {
+        if (key == null) {
+            throw new IllegalArgumentException("key was null");
+        }
+
+        T value = mCharacteristics.get(key);
+
+        if (value == null) {
+            failKeyCheck(key, "was null");
+        }
+
+        return value;
+    }
+
+    private void checkArrayValuesInRange(Key<int[]> key, int[] array, int min, int max) {
+        for (int value : array) {
+            checkTrueForKey(key, String.format(" value is out of range [%d, %d]", min, max),
+                    value <= max && value >= min);
+        }
+    }
+
+    private void checkArrayValuesInRange(Key<byte[]> key, byte[] array, byte min, byte max) {
+        for (byte value : array) {
+            checkTrueForKey(key, String.format(" value is out of range [%d, %d]", min, max),
+                    value <= max && value >= min);
+        }
+    }
+
+    /**
+     * Check the uniqueness of the values in a list.
+     *
+     * @param key The key to be checked
+     * @param list The list contains the value of the key
+     */
+    private <U, T> void checkElementDistinct(Key<U> key, List<T> list) {
+        // Each size must be distinct.
+        Set<T> sizeSet = new HashSet<T>(list);
+        checkTrueForKey(key, "Each size must be distinct", sizeSet.size() == list.size());
+    }
+
+    private <T> void checkTrueForKey(Key<T> key, String message, boolean condition) {
+        if (!condition) {
+            failKeyCheck(key, message);
+        }
+    }
+
+    /* Helper function to check if the coupled modes are either all present or all non-present */
+    private <T> boolean containsAllOrNone(Collection<T> observedModes, Collection<T> coupledModes) {
+        if (observedModes.containsAll(coupledModes)) {
+            return true;
+        }
+        for (T mode : coupledModes) {
+            if (observedModes.contains(mode)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private <T> void failKeyCheck(Key<T> key, String message) {
+        // TODO: Consider only warning once per key/message combination if it's too spammy.
+        // TODO: Consider offering other options such as throwing an assertion exception
+        String failureCause = String.format("The static info key '%s' %s", key.getName(), message);
+        switch (mLevel) {
+            case WARN:
+                Log.w(TAG, failureCause);
+                break;
+            case COLLECT:
+                mCollector.addMessage(failureCause);
+                break;
+            case ASSERT:
+                Assert.fail(failureCause);
+            default:
+                throw new UnsupportedOperationException("Unhandled level " + mLevel);
+        }
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/UncheckedCloseable.java b/tests/camera/src/android/hardware/camera2/cts/helpers/UncheckedCloseable.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/helpers/UncheckedCloseable.java
rename to tests/camera/src/android/hardware/camera2/cts/helpers/UncheckedCloseable.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/means_yuvx_444_1d_to_single.rs b/tests/camera/src/android/hardware/camera2/cts/means_yuvx_444_1d_to_single.rs
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/means_yuvx_444_1d_to_single.rs
rename to tests/camera/src/android/hardware/camera2/cts/means_yuvx_444_1d_to_single.rs
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/means_yuvx_444_2d_to_1d.rs b/tests/camera/src/android/hardware/camera2/cts/means_yuvx_444_2d_to_1d.rs
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/means_yuvx_444_2d_to_1d.rs
rename to tests/camera/src/android/hardware/camera2/cts/means_yuvx_444_2d_to_1d.rs
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/AllocationCache.java b/tests/camera/src/android/hardware/camera2/cts/rs/AllocationCache.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/AllocationCache.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/AllocationCache.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/AllocationInfo.java b/tests/camera/src/android/hardware/camera2/cts/rs/AllocationInfo.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/AllocationInfo.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/AllocationInfo.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/BitmapUtils.java b/tests/camera/src/android/hardware/camera2/cts/rs/BitmapUtils.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/BitmapUtils.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/BitmapUtils.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/BlockingInputAllocation.java b/tests/camera/src/android/hardware/camera2/cts/rs/BlockingInputAllocation.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/BlockingInputAllocation.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/BlockingInputAllocation.java
diff --git a/tests/camera/src/android/hardware/camera2/cts/rs/RawConverter.java b/tests/camera/src/android/hardware/camera2/cts/rs/RawConverter.java
new file mode 100644
index 0000000..818b6c0
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/rs/RawConverter.java
@@ -0,0 +1,796 @@
+/*
+ * 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.rs;
+
+import android.graphics.Bitmap;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureResult;
+import android.hardware.camera2.params.ColorSpaceTransform;
+import android.hardware.camera2.params.LensShadingMap;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.Float3;
+import android.renderscript.Float4;
+import android.renderscript.Int4;
+import android.renderscript.Matrix3f;
+import android.renderscript.RenderScript;
+import android.renderscript.Type;
+
+import android.hardware.camera2.cts.ScriptC_raw_converter;
+import android.util.Log;
+import android.util.Rational;
+import android.util.SparseIntArray;
+
+import java.util.Arrays;
+
+/**
+ * Utility class providing methods for rendering RAW16 images into other colorspaces.
+ */
+public class RawConverter {
+    private static final String TAG = "RawConverter";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    /**
+     * Matrix to convert from CIE XYZ colorspace to sRGB, Bradford-adapted to D65.
+     */
+    private static final float[] sXYZtoRGBBradford = new float[] {
+            3.1338561f, -1.6168667f, -0.4906146f,
+            -0.9787684f, 1.9161415f, 0.0334540f,
+            0.0719453f, -0.2289914f, 1.4052427f
+    };
+
+    /**
+     * Matrix to convert from the ProPhoto RGB colorspace to CIE XYZ colorspace.
+     */
+    private static final float[] sProPhotoToXYZ = new float[] {
+            0.797779f, 0.135213f, 0.031303f,
+            0.288000f, 0.711900f, 0.000100f,
+            0.000000f, 0.000000f, 0.825105f
+    };
+
+    /**
+     * Matrix to convert from CIE XYZ colorspace to ProPhoto RGB colorspace.
+     */
+    private static final float[] sXYZtoProPhoto = new float[] {
+            1.345753f, -0.255603f, -0.051025f,
+            -0.544426f, 1.508096f, 0.020472f,
+            0.000000f, 0.000000f, 1.211968f
+    };
+
+    /**
+     * Coefficients for a 3rd order polynomial, ordered from highest to lowest power.  This
+     * polynomial approximates the default tonemapping curve used for ACR3.
+     */
+    private static final float[] DEFAULT_ACR3_TONEMAP_CURVE_COEFFS = new float[] {
+            -0.7836f, 0.8469f, 0.943f, 0.0209f
+    };
+
+    /**
+     * The D50 whitepoint coordinates in CIE XYZ colorspace.
+     */
+    private static final float[] D50_XYZ = new float[] { 0.9642f, 1, 0.8249f };
+
+    /**
+     * An array containing the color temperatures for standard reference illuminants.
+     */
+    private static final SparseIntArray sStandardIlluminants = new SparseIntArray();
+    private static final int NO_ILLUMINANT = -1;
+    static {
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT, 6504);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D65, 6504);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D50, 5003);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D55, 5503);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D75, 7504);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A, 2856);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B, 4874);
+        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C, 6774);
+        sStandardIlluminants.append(
+                CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT, 6430);
+        sStandardIlluminants.append(
+                CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT, 4230);
+        sStandardIlluminants.append(
+                CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT, 3450);
+        // TODO: Add the rest of the illuminants included in the LightSource EXIF tag.
+    }
+
+    /**
+     * Convert a RAW16 buffer into an sRGB buffer, and write the result into a bitmap.
+     *
+     * <p> This function applies the operations roughly outlined in the Adobe DNG specification
+     * using the provided metadata about the image sensor.  Sensor data for Android devices is
+     * assumed to be relatively linear, and no extra linearization step is applied here.  The
+     * following operations are applied in the given order:</p>
+     *
+     * <ul>
+     *     <li>
+     *         Black level subtraction - the black levels given in the SENSOR_BLACK_LEVEL_PATTERN
+     *         tag are subtracted from the corresponding raw pixels.
+     *     </li>
+     *     <li>
+     *         Rescaling - each raw pixel is scaled by 1/(white level - black level).
+     *     </li>
+     *     <li>
+     *         Lens shading correction - the interpolated gains from the gain map defined in the
+     *         STATISTICS_LENS_SHADING_CORRECTION_MAP are applied to each raw pixel.
+     *     </li>
+     *     <li>
+     *         Clipping - each raw pixel is clipped to a range of [0.0, 1.0].
+     *     </li>
+     *     <li>
+     *         Demosaic - the RGB channels for each pixel are retrieved from the Bayer mosaic
+     *         of raw pixels using a simple bilinear-interpolation demosaicing algorithm.
+     *     </li>
+     *     <li>
+     *         Colorspace transform to wide-gamut RGB - each pixel is mapped into a
+     *         wide-gamut colorspace (in this case ProPhoto RGB is used) from the sensor
+     *         colorspace.
+     *     </li>
+     *     <li>
+     *         Tonemapping - A basic tonemapping curve using the default from ACR3 is applied
+     *         (no further exposure compensation is applied here, though this could be improved).
+     *     </li>
+     *     <li>
+     *         Colorspace transform to final RGB - each pixel is mapped into linear sRGB colorspace.
+     *     </li>
+     *     <li>
+     *         Gamma correction - each pixel is gamma corrected using γ=2.2 to map into sRGB
+     *         colorspace for viewing.
+     *     </li>
+     *     <li>
+     *         Packing - each pixel is scaled so that each color channel has a range of [0, 255],
+     *         and is packed into an Android bitmap.
+     *     </li>
+     * </ul>
+     *
+     * <p> Arguments given here are assumed to come from the values for the corresponding
+     * {@link CameraCharacteristics.Key}s defined for the camera that produced this RAW16 buffer.
+     * </p>
+     * @param rs a {@link RenderScript} context to use.
+     * @param inputWidth width of the input RAW16 image in pixels.
+     * @param inputHeight height of the input RAW16 image in pixels.
+     * @param inputStride stride of the input RAW16 image in bytes.
+     * @param rawImageInput a byte array containing a RAW16 image.
+     * @param staticMetadata the {@link CameraCharacteristics} for this RAW capture.
+     * @param dynamicMetadata the {@link CaptureResult} for this RAW capture.
+     * @param outputOffsetX the offset width into the raw image of the left side of the output
+     *                      rectangle.
+     * @param outputOffsetY the offset height into the raw image of the top side of the output
+     *                      rectangle.
+     * @param argbOutput a {@link Bitmap} to output the rendered RAW image into.  The height and
+     *                   width of this bitmap along with the output offsets are used to determine
+     *                   the dimensions and offset of the output rectangle contained in the RAW
+     *                   image to be rendered.
+     */
+    public static void convertToSRGB(RenderScript rs, int inputWidth, int inputHeight,
+            int inputStride, byte[] rawImageInput, CameraCharacteristics staticMetadata,
+            CaptureResult dynamicMetadata, int outputOffsetX, int outputOffsetY,
+            /*out*/Bitmap argbOutput) {
+        int cfa = staticMetadata.get(CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
+        int[] blackLevelPattern = new int[4];
+        staticMetadata.get(CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN).
+                copyTo(blackLevelPattern, /*offset*/0);
+        int whiteLevel = staticMetadata.get(CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL);
+        int ref1 = staticMetadata.get(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1);
+        int ref2 = staticMetadata.get(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2);
+        float[] calib1 = new float[9];
+        float[] calib2 = new float[9];
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1), calib1);
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2), calib2);
+        float[] color1 = new float[9];
+        float[] color2 = new float[9];
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM1), color1);
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM2), color2);
+        float[] forward1 = new float[9];
+        float[] forward2 = new float[9];
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX1), forward1);
+        convertColorspaceTransform(
+                staticMetadata.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX2), forward2);
+
+        Rational[] neutral = dynamicMetadata.get(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
+
+        LensShadingMap shadingMap = dynamicMetadata.get(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
+
+        convertToSRGB(rs, inputWidth, inputHeight, inputStride, cfa, blackLevelPattern, whiteLevel,
+                rawImageInput, ref1, ref2, calib1, calib2, color1, color2,
+                forward1, forward2, neutral, shadingMap, outputOffsetX, outputOffsetY, argbOutput);
+    }
+
+    /**
+     * Convert a RAW16 buffer into an sRGB buffer, and write the result into a bitmap.
+     *
+     * @see #convertToSRGB
+     */
+    private static void convertToSRGB(RenderScript rs, int inputWidth, int inputHeight,
+            int inputStride, int cfa, int[] blackLevelPattern, int whiteLevel, byte[] rawImageInput,
+            int referenceIlluminant1, int referenceIlluminant2, float[] calibrationTransform1,
+            float[] calibrationTransform2, float[] colorMatrix1, float[] colorMatrix2,
+            float[] forwardTransform1, float[] forwardTransform2, Rational[/*3*/] neutralColorPoint,
+            LensShadingMap lensShadingMap, int outputOffsetX, int outputOffsetY,
+            /*out*/Bitmap argbOutput) {
+
+        // Validate arguments
+        if (argbOutput == null || rs == null || rawImageInput == null) {
+            throw new IllegalArgumentException("Null argument to convertToSRGB");
+        }
+        if (argbOutput.getConfig() != Bitmap.Config.ARGB_8888) {
+            throw new IllegalArgumentException(
+                    "Output bitmap passed to convertToSRGB is not ARGB_8888 format");
+        }
+        if (outputOffsetX < 0 || outputOffsetY < 0) {
+            throw new IllegalArgumentException("Negative offset passed to convertToSRGB");
+        }
+        if ((inputStride / 2) < inputWidth) {
+            throw new IllegalArgumentException("Stride too small.");
+        }
+        if ((inputStride % 2) != 0) {
+            throw new IllegalArgumentException("Invalid stride for RAW16 format, see graphics.h.");
+        }
+        int outWidth = argbOutput.getWidth();
+        int outHeight = argbOutput.getHeight();
+        if (outWidth + outputOffsetX > inputWidth || outHeight + outputOffsetY > inputHeight) {
+            throw new IllegalArgumentException("Raw image with dimensions (w=" + inputWidth +
+                    ", h=" + inputHeight + "), cannot converted into sRGB image with dimensions (w="
+                    + outWidth + ", h=" + outHeight + ").");
+        }
+        if (cfa < 0 || cfa > 3) {
+            throw new IllegalArgumentException("Unsupported cfa pattern " + cfa + " used.");
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Metadata Used:");
+            Log.d(TAG, "Input width,height: " + inputWidth + "," + inputHeight);
+            Log.d(TAG, "Output offset x,y: " + outputOffsetX + "," + outputOffsetY);
+            Log.d(TAG, "Output width,height: " + outWidth + "," + outHeight);
+            Log.d(TAG, "CFA: " + cfa);
+            Log.d(TAG, "BlackLevelPattern: " + Arrays.toString(blackLevelPattern));
+            Log.d(TAG, "WhiteLevel: " + whiteLevel);
+            Log.d(TAG, "ReferenceIlluminant1: " + referenceIlluminant1);
+            Log.d(TAG, "ReferenceIlluminant2: " + referenceIlluminant2);
+            Log.d(TAG, "CalibrationTransform1: " + Arrays.toString(calibrationTransform1));
+            Log.d(TAG, "CalibrationTransform2: " + Arrays.toString(calibrationTransform2));
+            Log.d(TAG, "ColorMatrix1: " + Arrays.toString(colorMatrix1));
+            Log.d(TAG, "ColorMatrix2: " + Arrays.toString(colorMatrix2));
+            Log.d(TAG, "ForwardTransform1: " + Arrays.toString(forwardTransform1));
+            Log.d(TAG, "ForwardTransform2: " + Arrays.toString(forwardTransform2));
+            Log.d(TAG, "NeutralColorPoint: " + Arrays.toString(neutralColorPoint));
+        }
+
+        Allocation gainMap = null;
+        if (lensShadingMap != null) {
+            float[] lsm = new float[lensShadingMap.getGainFactorCount()];
+            lensShadingMap.copyGainFactors(/*inout*/lsm, /*offset*/0);
+            gainMap = createFloat4Allocation(rs, lsm, lensShadingMap.getColumnCount(),
+                    lensShadingMap.getRowCount());
+        }
+
+        float[] normalizedForwardTransform1 = Arrays.copyOf(forwardTransform1,
+                forwardTransform1.length);
+        normalizeFM(normalizedForwardTransform1);
+        float[] normalizedForwardTransform2 = Arrays.copyOf(forwardTransform2,
+                forwardTransform2.length);
+        normalizeFM(normalizedForwardTransform2);
+
+        float[] normalizedColorMatrix1 = Arrays.copyOf(colorMatrix1, colorMatrix1.length);
+        normalizeCM(normalizedColorMatrix1);
+        float[] normalizedColorMatrix2 = Arrays.copyOf(colorMatrix2, colorMatrix2.length);
+        normalizeCM(normalizedColorMatrix2);
+
+        if (DEBUG) {
+            Log.d(TAG, "Normalized ForwardTransform1: " + Arrays.toString(normalizedForwardTransform1));
+            Log.d(TAG, "Normalized ForwardTransform2: " + Arrays.toString(normalizedForwardTransform2));
+            Log.d(TAG, "Normalized ColorMatrix1: " + Arrays.toString(normalizedColorMatrix1));
+            Log.d(TAG, "Normalized ColorMatrix2: " + Arrays.toString(normalizedColorMatrix2));
+        }
+
+        // Calculate full sensor colorspace to sRGB colorspace transform.
+        double interpolationFactor = findDngInterpolationFactor(referenceIlluminant1,
+                referenceIlluminant2, calibrationTransform1, calibrationTransform2,
+                normalizedColorMatrix1, normalizedColorMatrix2, neutralColorPoint);
+        if (DEBUG) Log.d(TAG, "Interpolation factor used: " + interpolationFactor);
+        float[] sensorToXYZ = new float[9];
+        calculateCameraToXYZD50Transform(normalizedForwardTransform1, normalizedForwardTransform2,
+                calibrationTransform1, calibrationTransform2, neutralColorPoint,
+                interpolationFactor, /*out*/sensorToXYZ);
+        if (DEBUG) Log.d(TAG, "CameraToXYZ xform used: " + Arrays.toString(sensorToXYZ));
+        float[] sensorToProPhoto = new float[9];
+        multiply(sXYZtoProPhoto, sensorToXYZ, /*out*/sensorToProPhoto);
+        if (DEBUG) Log.d(TAG, "CameraToIntemediate xform used: " + Arrays.toString(sensorToProPhoto));
+        Allocation output = Allocation.createFromBitmap(rs, argbOutput);
+
+        float[] proPhotoToSRGB = new float[9];
+        multiply(sXYZtoRGBBradford, sProPhotoToXYZ, /*out*/proPhotoToSRGB);
+
+        // Setup input allocation (16-bit raw pixels)
+        Type.Builder typeBuilder = new Type.Builder(rs, Element.U16(rs));
+        typeBuilder.setX((inputStride / 2));
+        typeBuilder.setY(inputHeight);
+        Type inputType = typeBuilder.create();
+        Allocation input = Allocation.createTyped(rs, inputType);
+        input.copyFromUnchecked(rawImageInput);
+
+        // Setup RS kernel globals
+        ScriptC_raw_converter converterKernel = new ScriptC_raw_converter(rs);
+        converterKernel.set_inputRawBuffer(input);
+        converterKernel.set_whiteLevel(whiteLevel);
+        converterKernel.set_sensorToIntermediate(new Matrix3f(transpose(sensorToProPhoto)));
+        converterKernel.set_intermediateToSRGB(new Matrix3f(transpose(proPhotoToSRGB)));
+        converterKernel.set_offsetX(outputOffsetX);
+        converterKernel.set_offsetY(outputOffsetY);
+        converterKernel.set_rawHeight(inputHeight);
+        converterKernel.set_rawWidth(inputWidth);
+        converterKernel.set_neutralPoint(new Float3(neutralColorPoint[0].floatValue(),
+                neutralColorPoint[1].floatValue(), neutralColorPoint[2].floatValue()));
+        converterKernel.set_toneMapCoeffs(new Float4(DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[0],
+                DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[1], DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[2],
+                DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[3]));
+        converterKernel.set_hasGainMap(gainMap != null);
+        if (gainMap != null) {
+            converterKernel.set_gainMap(gainMap);
+            converterKernel.set_gainMapWidth(lensShadingMap.getColumnCount());
+            converterKernel.set_gainMapHeight(lensShadingMap.getRowCount());
+        }
+
+        converterKernel.set_cfaPattern(cfa);
+        converterKernel.set_blackLevelPattern(new Int4(blackLevelPattern[0],
+                blackLevelPattern[1], blackLevelPattern[2], blackLevelPattern[3]));
+        converterKernel.forEach_convert_RAW_To_ARGB(output);
+        output.copyTo(argbOutput);  // Force RS sync with bitmap (does not do an extra copy).
+    }
+
+    /**
+     * Create a float-backed renderscript {@link Allocation} with the given dimensions, containing
+     * the contents of the given float array.
+     *
+     * @param rs a {@link RenderScript} context to use.
+     * @param fArray the float array to copy into the {@link Allocation}.
+     * @param width the width of the {@link Allocation}.
+     * @param height the height of the {@link Allocation}.
+     * @return an {@link Allocation} containing the given floats.
+     */
+    private static Allocation createFloat4Allocation(RenderScript rs, float[] fArray,
+                                                    int width, int height) {
+        if (fArray.length != width * height * 4) {
+            throw new IllegalArgumentException("Invalid float array of length " + fArray.length +
+                    ", must be correct size for Allocation of dimensions " + width + "x" + height);
+        }
+        Type.Builder builder = new Type.Builder(rs, Element.F32_4(rs));
+        builder.setX(width);
+        builder.setY(height);
+        Allocation fAlloc = Allocation.createTyped(rs, builder.create());
+        fAlloc.copyFrom(fArray);
+        return fAlloc;
+    }
+
+    /**
+     * Calculate the correlated color temperature (CCT) for a given x,y chromaticity in CIE 1931 x,y
+     * chromaticity space using McCamy's cubic approximation algorithm given in:
+     *
+     * McCamy, Calvin S. (April 1992).
+     * "Correlated color temperature as an explicit function of chromaticity coordinates".
+     * Color Research & Application 17 (2): 142–144
+     *
+     * @param x x chromaticity component.
+     * @param y y chromaticity component.
+     *
+     * @return the CCT associated with this chromaticity coordinate.
+     */
+    private static double calculateColorTemperature(double x, double y) {
+        double n = (x - 0.332) / (y - 0.1858);
+        return -449 * Math.pow(n, 3) + 3525 * Math.pow(n, 2) - 6823.3 * n + 5520.33;
+    }
+
+    /**
+     * Calculate the x,y chromaticity coordinates in CIE 1931 x,y chromaticity space from the given
+     * CIE XYZ coordinates.
+     *
+     * @param X the CIE XYZ X coordinate.
+     * @param Y the CIE XYZ Y coordinate.
+     * @param Z the CIE XYZ Z coordinate.
+     *
+     * @return the [x, y] chromaticity coordinates as doubles.
+     */
+    private static double[] calculateCIExyCoordinates(double X, double Y, double Z) {
+        double[] ret = new double[] { 0, 0 };
+        ret[0] = X / (X + Y + Z);
+        ret[1] = Y / (X + Y + Z);
+        return ret;
+    }
+
+    /**
+     * Linearly interpolate between a and b given fraction f.
+     *
+     * @param a first term to interpolate between, a will be returned when f == 0.
+     * @param b second term to interpolate between, b will be returned when f == 1.
+     * @param f the fraction to interpolate by.
+     *
+     * @return interpolated result as double.
+     */
+    private static double lerp(double a, double b, double f) {
+        return (a * (1.0f - f)) + (b * f);
+    }
+
+    /**
+     * Linearly interpolate between 3x3 matrices a and b given fraction f.
+     *
+     * @param a first 3x3 matrix to interpolate between, a will be returned when f == 0.
+     * @param b second 3x3 matrix to interpolate between, b will be returned when f == 1.
+     * @param f the fraction to interpolate by.
+     * @param result will be set to contain the interpolated matrix.
+     */
+    private static void lerp(float[] a, float[] b, double f, /*out*/float[] result) {
+        for (int i = 0; i < 9; i++) {
+            result[i] = (float) lerp(a[i], b[i], f);
+        }
+    }
+
+    /**
+     * Convert a 9x9 {@link ColorSpaceTransform} to a matrix and write the matrix into the
+     * output.
+     *
+     * @param xform a {@link ColorSpaceTransform} to transform.
+     * @param output the 3x3 matrix to overwrite.
+     */
+    private static void convertColorspaceTransform(ColorSpaceTransform xform, /*out*/float[] output) {
+        for (int i = 0; i < 3; i++) {
+            for (int j = 0; j < 3; j++) {
+                output[i * 3 + j] = xform.getElement(j, i).floatValue();
+            }
+        }
+    }
+
+    /**
+     * Find the interpolation factor to use with the RAW matrices given a neutral color point.
+     *
+     * @param referenceIlluminant1 first reference illuminant.
+     * @param referenceIlluminant2 second reference illuminant.
+     * @param calibrationTransform1 calibration matrix corresponding to the first reference
+     *                              illuminant.
+     * @param calibrationTransform2 calibration matrix corresponding to the second reference
+     *                              illuminant.
+     * @param colorMatrix1 color matrix corresponding to the first reference illuminant.
+     * @param colorMatrix2 color matrix corresponding to the second reference illuminant.
+     * @param neutralColorPoint the neutral color point used to calculate the interpolation factor.
+     *
+     * @return the interpolation factor corresponding to the given neutral color point.
+     */
+    private static double findDngInterpolationFactor(int referenceIlluminant1,
+            int referenceIlluminant2, float[] calibrationTransform1, float[] calibrationTransform2,
+            float[] colorMatrix1, float[] colorMatrix2, Rational[/*3*/] neutralColorPoint) {
+
+        int colorTemperature1 = sStandardIlluminants.get(referenceIlluminant1, NO_ILLUMINANT);
+        if (colorTemperature1 == NO_ILLUMINANT) {
+            throw new IllegalArgumentException("No such illuminant for reference illuminant 1: " +
+                    referenceIlluminant1);
+        }
+
+        int colorTemperature2 = sStandardIlluminants.get(referenceIlluminant2, NO_ILLUMINANT);
+        if (colorTemperature2 == NO_ILLUMINANT) {
+            throw new IllegalArgumentException("No such illuminant for reference illuminant 2: " +
+                    referenceIlluminant2);
+        }
+
+        if (DEBUG) Log.d(TAG, "ColorTemperature1: " + colorTemperature1);
+        if (DEBUG) Log.d(TAG, "ColorTemperature2: " + colorTemperature2);
+
+        double interpFactor = 0.5; // Initial guess for interpolation factor
+        double oldInterpFactor = interpFactor;
+
+        double lastDiff = Double.MAX_VALUE;
+        double tolerance = 0.0001;
+        float[] XYZToCamera1 = new float[9];
+        float[] XYZToCamera2 = new float[9];
+        multiply(calibrationTransform1, colorMatrix1, /*out*/XYZToCamera1);
+        multiply(calibrationTransform2, colorMatrix2, /*out*/XYZToCamera2);
+
+        float[] cameraNeutral = new float[] { neutralColorPoint[0].floatValue(),
+                neutralColorPoint[1].floatValue(), neutralColorPoint[2].floatValue()};
+
+        float[] neutralGuess = new float[3];
+        float[] interpXYZToCamera = new float[9];
+        float[] interpXYZToCameraInverse = new float[9];
+
+
+        double lower = Math.min(colorTemperature1, colorTemperature2);
+        double upper = Math.max(colorTemperature1, colorTemperature2);
+
+        if(DEBUG) {
+            Log.d(TAG, "XYZtoCamera1: " + Arrays.toString(XYZToCamera1));
+            Log.d(TAG, "XYZtoCamera2: " + Arrays.toString(XYZToCamera2));
+            Log.d(TAG, "Finding interpolation factor, initial guess 0.5...");
+        }
+        // Iteratively guess xy value, find new CCT, and update interpolation factor.
+        int loopLimit = 30;
+        int count = 0;
+        while (lastDiff > tolerance && loopLimit > 0) {
+            if (DEBUG) Log.d(TAG, "Loop count " + count);
+            lerp(XYZToCamera1, XYZToCamera2, interpFactor, interpXYZToCamera);
+            if (!invert(interpXYZToCamera, /*out*/interpXYZToCameraInverse)) {
+                throw new IllegalArgumentException(
+                        "Cannot invert XYZ to Camera matrix, input matrices are invalid.");
+            }
+
+            map(interpXYZToCameraInverse, cameraNeutral, /*out*/neutralGuess);
+            double[] xy = calculateCIExyCoordinates(neutralGuess[0], neutralGuess[1],
+                    neutralGuess[2]);
+
+            double colorTemperature = calculateColorTemperature(xy[0], xy[1]);
+
+            if (colorTemperature <= lower) {
+                interpFactor = 1;
+            } else if (colorTemperature >= upper) {
+                interpFactor = 0;
+            } else {
+                double invCT = 1.0 / colorTemperature;
+                interpFactor = (invCT - 1.0 / upper) / ( 1.0 / lower - 1.0 / upper);
+            }
+
+            if (lower == colorTemperature1) {
+                interpFactor = 1.0 - interpFactor;
+            }
+
+            interpFactor = (interpFactor + oldInterpFactor) / 2;
+            lastDiff = Math.abs(oldInterpFactor - interpFactor);
+            oldInterpFactor = interpFactor;
+            loopLimit--;
+            count++;
+
+            if (DEBUG) {
+                Log.d(TAG, "CameraToXYZ chosen: " + Arrays.toString(interpXYZToCameraInverse));
+                Log.d(TAG, "XYZ neutral color guess: " + Arrays.toString(neutralGuess));
+                Log.d(TAG, "xy coordinate: " + Arrays.toString(xy));
+                Log.d(TAG, "xy color temperature: " + colorTemperature);
+                Log.d(TAG, "New interpolation factor: " + interpFactor);
+            }
+        }
+
+        if (loopLimit == 0) {
+            Log.w(TAG, "Could not converge on interpolation factor, using factor " + interpFactor +
+                    " with remaining error factor of " + lastDiff);
+        }
+        return interpFactor;
+    }
+
+    /**
+     * Calculate the transform from the raw camera sensor colorspace to CIE XYZ colorspace with a
+     * D50 whitepoint.
+     *
+     * @param forwardTransform1 forward transform matrix corresponding to the first reference
+     *                          illuminant.
+     * @param forwardTransform2 forward transform matrix corresponding to the second reference
+     *                          illuminant.
+     * @param calibrationTransform1 calibration transform matrix corresponding to the first
+     *                              reference illuminant.
+     * @param calibrationTransform2 calibration transform matrix corresponding to the second
+     *                              reference illuminant.
+     * @param neutralColorPoint the neutral color point used to calculate the interpolation factor.
+     * @param interpolationFactor the interpolation factor to use for the forward and
+     *                            calibration transforms.
+     * @param outputTransform set to the full sensor to XYZ colorspace transform.
+     */
+    private static void calculateCameraToXYZD50Transform(float[] forwardTransform1,
+            float[] forwardTransform2, float[] calibrationTransform1, float[] calibrationTransform2,
+            Rational[/*3*/] neutralColorPoint, double interpolationFactor,
+            /*out*/float[] outputTransform) {
+        float[] cameraNeutral = new float[] { neutralColorPoint[0].floatValue(),
+                neutralColorPoint[1].floatValue(), neutralColorPoint[2].floatValue()};
+        if (DEBUG) Log.d(TAG, "Camera neutral: " + Arrays.toString(cameraNeutral));
+
+        float[] interpolatedCC = new float[9];
+        lerp(calibrationTransform1, calibrationTransform2, interpolationFactor,
+                interpolatedCC);
+        float[] inverseInterpolatedCC = new float[9];
+        if (!invert(interpolatedCC, /*out*/inverseInterpolatedCC)) {
+            throw new IllegalArgumentException( "Cannot invert interpolated calibration transform" +
+                    ", input matrices are invalid.");
+        }
+        if (DEBUG) Log.d(TAG, "Inverted interpolated CalibrationTransform: " +
+                Arrays.toString(inverseInterpolatedCC));
+
+        float[] referenceNeutral = new float[3];
+        map(inverseInterpolatedCC, cameraNeutral, /*out*/referenceNeutral);
+        if (DEBUG) Log.d(TAG, "Reference neutral: " + Arrays.toString(referenceNeutral));
+        float maxNeutral = Math.max(Math.max(referenceNeutral[0], referenceNeutral[1]),
+                referenceNeutral[2]);
+        float[] D = new float[] { maxNeutral/referenceNeutral[0], 0, 0,
+                                  0, maxNeutral/referenceNeutral[1], 0,
+                                  0, 0, maxNeutral/referenceNeutral[2] };
+        if (DEBUG) Log.d(TAG, "Reference Neutral Diagonal: " + Arrays.toString(D));
+
+        float[] intermediate = new float[9];
+        float[] intermediate2 = new float[9];
+
+        lerp(forwardTransform1, forwardTransform2, interpolationFactor, /*out*/intermediate);
+        if (DEBUG) Log.d(TAG, "Interpolated ForwardTransform: " + Arrays.toString(intermediate));
+
+        multiply(D, inverseInterpolatedCC, /*out*/intermediate2);
+        multiply(intermediate, intermediate2, /*out*/outputTransform);
+    }
+
+    /**
+     * Map a 3d column vector using the given matrix.
+     *
+     * @param matrix float array containing 3x3 matrix to map vector by.
+     * @param input 3 dimensional vector to map.
+     * @param output 3 dimensional vector result.
+     */
+    private static void map(float[] matrix, float[] input, /*out*/float[] output) {
+        output[0] = input[0] * matrix[0] + input[1] * matrix[1] + input[2] * matrix[2];
+        output[1] = input[0] * matrix[3] + input[1] * matrix[4] + input[2] * matrix[5];
+        output[2] = input[0] * matrix[6] + input[1] * matrix[7] + input[2] * matrix[8];
+    }
+
+    /**
+     * Multiply two 3x3 matrices together: A * B
+     *
+     * @param a left matrix.
+     * @param b right matrix.
+     */
+    private static void multiply(float[] a, float[] b, /*out*/float[] output) {
+        output[0] = a[0] * b[0] + a[1] * b[3] + a[2] * b[6];
+        output[3] = a[3] * b[0] + a[4] * b[3] + a[5] * b[6];
+        output[6] = a[6] * b[0] + a[7] * b[3] + a[8] * b[6];
+        output[1] = a[0] * b[1] + a[1] * b[4] + a[2] * b[7];
+        output[4] = a[3] * b[1] + a[4] * b[4] + a[5] * b[7];
+        output[7] = a[6] * b[1] + a[7] * b[4] + a[8] * b[7];
+        output[2] = a[0] * b[2] + a[1] * b[5] + a[2] * b[8];
+        output[5] = a[3] * b[2] + a[4] * b[5] + a[5] * b[8];
+        output[8] = a[6] * b[2] + a[7] * b[5] + a[8] * b[8];
+    }
+
+    /**
+     * Transpose a 3x3 matrix in-place.
+     *
+     * @param m the matrix to transpose.
+     * @return the transposed matrix.
+     */
+    private static float[] transpose(/*inout*/float[/*9*/] m) {
+        float t = m[1];
+        m[1] = m[3];
+        m[3] = t;
+        t = m[2];
+        m[2] = m[6];
+        m[6] = t;
+        t = m[5];
+        m[5] = m[7];
+        m[7] = t;
+        return m;
+    }
+
+    /**
+     * Invert a 3x3 matrix, or return false if the matrix is singular.
+     *
+     * @param m matrix to invert.
+     * @param output set the output to be the inverse of m.
+     */
+    private static boolean invert(float[] m, /*out*/float[] output) {
+        double a00 = m[0];
+        double a01 = m[1];
+        double a02 = m[2];
+        double a10 = m[3];
+        double a11 = m[4];
+        double a12 = m[5];
+        double a20 = m[6];
+        double a21 = m[7];
+        double a22 = m[8];
+
+        double t00 = a11 * a22 - a21 * a12;
+        double t01 = a21 * a02 - a01 * a22;
+        double t02 = a01 * a12 - a11 * a02;
+        double t10 = a20 * a12 - a10 * a22;
+        double t11 = a00 * a22 - a20 * a02;
+        double t12 = a10 * a02 - a00 * a12;
+        double t20 = a10 * a21 - a20 * a11;
+        double t21 = a20 * a01 - a00 * a21;
+        double t22 = a00 * a11 - a10 * a01;
+
+        double det = a00 * t00 + a01 * t10 + a02 * t20;
+        if (Math.abs(det) < 1e-9) {
+            return false; // Inverse too close to zero, not invertible.
+        }
+
+        output[0] = (float) (t00 / det);
+        output[1] = (float) (t01 / det);
+        output[2] = (float) (t02 / det);
+        output[3] = (float) (t10 / det);
+        output[4] = (float) (t11 / det);
+        output[5] = (float) (t12 / det);
+        output[6] = (float) (t20 / det);
+        output[7] = (float) (t21 / det);
+        output[8] = (float) (t22 / det);
+        return true;
+    }
+
+    /**
+     * Scale each element in a matrix by the given scaling factor.
+     *
+     * @param factor factor to scale by.
+     * @param matrix the float array containing a 3x3 matrix to scale.
+     */
+    private static void scale(float factor, /*inout*/float[] matrix) {
+        for (int i = 0; i < 9; i++) {
+            matrix[i] *= factor;
+        }
+    }
+
+    /**
+     * Clamp a value to a given range.
+     *
+     * @param low lower bound to clamp to.
+     * @param high higher bound to clamp to.
+     * @param value the value to clamp.
+     * @return the clamped value.
+     */
+    private static double clamp(double low, double high, double value) {
+        return Math.max(low, Math.min(high, value));
+    }
+
+    /**
+     * Return the max float in the array.
+     *
+     * @param array array of floats to search.
+     * @return max float in the array.
+     */
+    private static float max(float[] array) {
+        float val = array[0];
+        for (float f : array) {
+            val = (f > val) ? f : val;
+        }
+        return val;
+    }
+
+    /**
+     * Normalize ColorMatrix to eliminate headroom for input space scaled to [0, 1] using
+     * the D50 whitepoint.  This maps the D50 whitepoint into the colorspace used by the
+     * ColorMatrix, then uses the resulting whitepoint to renormalize the ColorMatrix so
+     * that the channel values in the resulting whitepoint for this operation are clamped
+     * to the range [0, 1].
+     *
+     * @param colorMatrix a 3x3 matrix containing a DNG ColorMatrix to be normalized.
+     */
+    private static void normalizeCM(/*inout*/float[] colorMatrix) {
+        float[] tmp = new float[3];
+        map(colorMatrix, D50_XYZ, /*out*/tmp);
+        float maxVal = max(tmp);
+        if (maxVal > 0) {
+            scale(1.0f / maxVal, colorMatrix);
+        }
+    }
+
+    /**
+     * Normalize ForwardMatrix to ensure that sensor whitepoint [1, 1, 1] maps to D50 in CIE XYZ
+     * colorspace.
+     *
+     * @param forwardMatrix a 3x3 matrix containing a DNG ForwardTransform to be normalized.
+     */
+    private static void normalizeFM(/*inout*/float[] forwardMatrix) {
+        float[] tmp = new float[] {1, 1, 1};
+        float[] xyz = new float[3];
+        map(forwardMatrix, tmp, /*out*/xyz);
+
+        float[] intermediate = new float[9];
+        float[] m = new float[] {1.0f / xyz[0], 0, 0, 0, 1.0f / xyz[1], 0, 0, 0, 1.0f / xyz[2]};
+
+        multiply(m, forwardMatrix, /*out*/ intermediate);
+        float[] m2 = new float[] {D50_XYZ[0], 0, 0, 0, D50_XYZ[1], 0, 0, 0, D50_XYZ[2]};
+        multiply(m2, intermediate, /*out*/forwardMatrix);
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java b/tests/camera/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
new file mode 100644
index 0000000..211dd0d
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 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.hardware.camera2.cts.rs;
+
+import android.content.Context;
+import android.renderscript.RenderScript;
+import android.util.Log;
+
+// TODO : Replace with dependency injection
+/**
+ * Singleton to hold {@link RenderScript} and {@link AllocationCache} objects.
+ *
+ * <p>The test method must call {@link #setContext} before attempting to retrieve
+ * the underlying objects.</p> *
+ */
+public class RenderScriptSingleton {
+
+    private static final String TAG = "RenderScriptSingleton";
+
+    private static Context sContext;
+    private static RenderScript sRS;
+    private static AllocationCache sCache;
+
+    /**
+     * Initialize the singletons from the given context; the
+     * {@link RenderScript} and {@link AllocationCache} objects are instantiated.
+     *
+     * @param context a non-{@code null} Context.
+     *
+     * @throws IllegalStateException If this was called repeatedly without {@link #clearContext}
+     */
+    public static synchronized void setContext(Context context) {
+        if (context.equals(sContext)) {
+            return;
+        } else if (sContext != null) {
+            Log.v(TAG,
+                    "Trying to set new context " + context +
+                    ", before clearing previous "+ sContext);
+            throw new IllegalStateException(
+                    "Call #clearContext before trying to set a new context");
+        }
+
+        sRS = RenderScript.create(context);
+        sContext = context;
+        sCache = new AllocationCache(sRS);
+    }
+
+    /**
+     * Clean up the singletons from the given context; the
+     * {@link RenderScript} and {@link AllocationCache} objects are destroyed.
+     *
+     * <p>Safe to call multiple times; subsequent invocations have no effect.</p>
+     */
+    public static synchronized void clearContext() {
+        if (sContext != null) {
+            sCache.close();
+            sCache = null;
+
+            sRS.releaseAllContexts();
+            sRS = null;
+            sContext = null;
+        }
+    }
+
+    /**
+     * Get the current {@link RenderScript} singleton.
+     *
+     * @return A non-{@code null} {@link RenderScript} object.
+     *
+     * @throws IllegalStateException if {@link #setContext} was not called prior to this
+     */
+    public static synchronized RenderScript getRS() {
+        if (sRS == null) {
+            throw new IllegalStateException("Call #setContext before using #get");
+        }
+
+        return sRS;
+    }
+    /**
+     * Get the current {@link AllocationCache} singleton.
+     *
+     * @return A non-{@code null} {@link AllocationCache} object.
+     *
+     * @throws IllegalStateException if {@link #setContext} was not called prior to this
+     */
+    public static synchronized AllocationCache getCache() {
+        if (sCache == null) {
+            throw new IllegalStateException("Call #setContext before using #getCache");
+        }
+
+        return sCache;
+    }
+
+    // Suppress default constructor for noninstantiability
+    private RenderScriptSingleton() { throw new AssertionError(); }
+}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/Script.java b/tests/camera/src/android/hardware/camera2/cts/rs/Script.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/Script.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/Script.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptGraph.java b/tests/camera/src/android/hardware/camera2/cts/rs/ScriptGraph.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptGraph.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/ScriptGraph.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptYuvCrop.java b/tests/camera/src/android/hardware/camera2/cts/rs/ScriptYuvCrop.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptYuvCrop.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/ScriptYuvCrop.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptYuvMeans1d.java b/tests/camera/src/android/hardware/camera2/cts/rs/ScriptYuvMeans1d.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptYuvMeans1d.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/ScriptYuvMeans1d.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptYuvMeans2dTo1d.java b/tests/camera/src/android/hardware/camera2/cts/rs/ScriptYuvMeans2dTo1d.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptYuvMeans2dTo1d.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/ScriptYuvMeans2dTo1d.java
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptYuvToRgb.java b/tests/camera/src/android/hardware/camera2/cts/rs/ScriptYuvToRgb.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/camera2/cts/rs/ScriptYuvToRgb.java
rename to tests/camera/src/android/hardware/camera2/cts/rs/ScriptYuvToRgb.java
diff --git a/tests/camera/src/android/hardware/camera2/cts/rs/raw_converter.rs b/tests/camera/src/android/hardware/camera2/cts/rs/raw_converter.rs
new file mode 100644
index 0000000..fb467bb
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/rs/raw_converter.rs
@@ -0,0 +1,372 @@
+/*
+ * 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.
+ */
+
+#include "../common.rs"
+
+// This file includes a conversion kernel for RGGB, GRBG, GBRG, and BGGR Bayer patterns.
+// Applying this script also will apply black-level subtraction, rescaling, clipping, tonemapping,
+// and color space transforms along with the Bayer demosaic.  See RawConverter.java
+// for more information.
+
+// Input globals
+
+rs_allocation inputRawBuffer; // RAW16 buffer of dimensions (raw image stride) * (raw image height)
+rs_allocation gainMap; // Gainmap to apply to linearized raw sensor data.
+uint cfaPattern; // The Color Filter Arrangement pattern used
+uint gainMapWidth;  // The width of the gain map
+uint gainMapHeight;  // The height of the gain map
+bool hasGainMap; // Does gainmap exist?
+rs_matrix3x3 sensorToIntermediate; // Color transform from sensor to a wide-gamut colorspace
+rs_matrix3x3 intermediateToSRGB; // Color transform from wide-gamut colorspace to sRGB
+ushort4 blackLevelPattern; // Blacklevel to subtract for each channel, given in CFA order
+int whiteLevel;  // Whitelevel of sensor
+uint offsetX; // X offset into inputRawBuffer
+uint offsetY; // Y offset into inputRawBuffer
+uint rawWidth; // Width of raw buffer
+uint rawHeight; // Height of raw buffer
+float3 neutralPoint; // The camera neutral
+float4 toneMapCoeffs; // Coefficients for a polynomial tonemapping curve
+
+// Interpolate gain map to find per-channel gains at a given pixel
+static float4 getGain(uint x, uint y) {
+    float interpX = (((float) x) / rawWidth) * gainMapWidth;
+    float interpY = (((float) y) / rawHeight) * gainMapHeight;
+    uint gX = (uint) interpX;
+    uint gY = (uint) interpY;
+    uint gXNext = (gX + 1 < gainMapWidth) ? gX + 1 : gX;
+    uint gYNext = (gY + 1 < gainMapHeight) ? gY + 1 : gY;
+
+    float4 tl = *((float4 *) rsGetElementAt(gainMap, gX, gY));
+    float4 tr = *((float4 *) rsGetElementAt(gainMap, gXNext, gY));
+    float4 bl = *((float4 *) rsGetElementAt(gainMap, gX, gYNext));
+    float4 br = *((float4 *) rsGetElementAt(gainMap, gXNext, gYNext));
+
+    float fracX = interpX - (float) gX;
+    float fracY = interpY - (float) gY;
+    float invFracX = 1.f - fracX;
+    float invFracY = 1.f - fracY;
+
+    return tl * invFracX * invFracY + tr * fracX * invFracY +
+            bl * invFracX * fracY + br * fracX * fracY;
+}
+
+// Apply gamma correction using sRGB gamma curve
+static float gammaEncode(float x) {
+    return (x <= 0.0031308f) ? x * 12.92f : 1.055f * pow(x, 0.4166667f) - 0.055f;
+}
+
+// Apply gamma correction to each color channel in RGB pixel
+static float3 gammaCorrectPixel(float3 rgb) {
+    float3 ret;
+    ret.x = gammaEncode(rgb.x);
+    ret.y = gammaEncode(rgb.y);
+    ret.z = gammaEncode(rgb.z);
+    return ret;
+}
+
+// Apply polynomial tonemapping curve to each color channel in RGB pixel.
+// This attempts to apply tonemapping without changing the hue of each pixel,
+// i.e.:
+//
+// For some RGB values:
+// M = max(R, G, B)
+// m = min(R, G, B)
+// m' = mid(R, G, B)
+// chroma = M - m
+// H = m' - m / chroma
+//
+// The relationship H=H' should be preserved, where H and H' are calculated from
+// the RGB and RGB' value at this pixel before and after this tonemapping
+// operation has been applied, respectively.
+static float3 tonemap(float3 rgb) {
+    float3 sorted = clamp(rgb, 0.f, 1.f);
+    float tmp;
+    int permutation = 0;
+
+    // Sort the RGB channels by value
+    if (sorted.z < sorted.y) {
+        tmp = sorted.z;
+        sorted.z = sorted.y;
+        sorted.y = tmp;
+        permutation |= 1;
+    }
+    if (sorted.y < sorted.x) {
+        tmp = sorted.y;
+        sorted.y = sorted.x;
+        sorted.x = tmp;
+        permutation |= 2;
+    }
+    if (sorted.z < sorted.y) {
+        tmp = sorted.z;
+        sorted.z = sorted.y;
+        sorted.y = tmp;
+        permutation |= 4;
+    }
+
+    float2 minmax;
+    minmax.x = sorted.x;
+    minmax.y = sorted.z;
+
+    // Apply tonemapping curve to min, max RGB channel values
+    minmax = native_powr(minmax, 3.f) * toneMapCoeffs.x +
+            native_powr(minmax, 2.f) * toneMapCoeffs.y +
+            minmax * toneMapCoeffs.z + toneMapCoeffs.w;
+
+    // Rescale middle value
+    float newMid;
+    if (sorted.z == sorted.x) {
+        newMid = minmax.y;
+    } else {
+        newMid = minmax.x + ((minmax.y - minmax.x) * (sorted.y - sorted.x) /
+                (sorted.z - sorted.x));
+    }
+
+    float3 finalRGB;
+    switch (permutation) {
+        case 0: // b >= g >= r
+            finalRGB.x = minmax.x;
+            finalRGB.y = newMid;
+            finalRGB.z = minmax.y;
+            break;
+        case 1: // g >= b >= r
+            finalRGB.x = minmax.x;
+            finalRGB.z = newMid;
+            finalRGB.y = minmax.y;
+            break;
+        case 2: // b >= r >= g
+            finalRGB.y = minmax.x;
+            finalRGB.x = newMid;
+            finalRGB.z = minmax.y;
+            break;
+        case 3: // g >= r >= b
+            finalRGB.z = minmax.x;
+            finalRGB.x = newMid;
+            finalRGB.y = minmax.y;
+            break;
+        case 6: // r >= b >= g
+            finalRGB.y = minmax.x;
+            finalRGB.z = newMid;
+            finalRGB.x = minmax.y;
+            break;
+        case 7: // r >= g >= b
+            finalRGB.z = minmax.x;
+            finalRGB.y = newMid;
+            finalRGB.x = minmax.y;
+            break;
+        case 4: // impossible
+        case 5: // impossible
+        default:
+            finalRGB.x = 0.f;
+            finalRGB.y = 0.f;
+            finalRGB.z = 0.f;
+            LOGD("raw_converter.rs: Logic error in tonemap.", 0);
+            break;
+    }
+    return clamp(finalRGB, 0.f, 1.f);
+}
+
+// Apply a colorspace transform to the intermediate colorspace, apply
+// a tonemapping curve, apply a colorspace transform to a final colorspace,
+// and apply a gamma correction curve.
+static float3 applyColorspace(float3 pRGB) {
+    pRGB.x = clamp(pRGB.x, 0.f, neutralPoint.x);
+    pRGB.y = clamp(pRGB.y, 0.f, neutralPoint.y);
+    pRGB.z = clamp(pRGB.z, 0.f, neutralPoint.z);
+
+    float3 intermediate = rsMatrixMultiply(&sensorToIntermediate, pRGB);
+    intermediate = tonemap(intermediate);
+    return gammaCorrectPixel(clamp(rsMatrixMultiply(&intermediateToSRGB, intermediate), 0.f, 1.f));
+}
+
+// Load a 3x3 patch of pixels into the output.
+static void load3x3(uint x, uint y, rs_allocation buf, /*out*/float* outputArray) {
+    outputArray[0] = *((ushort *) rsGetElementAt(buf, x - 1, y - 1));
+    outputArray[1] = *((ushort *) rsGetElementAt(buf, x, y - 1));
+    outputArray[2] = *((ushort *) rsGetElementAt(buf, x + 1, y - 1));
+    outputArray[3] = *((ushort *) rsGetElementAt(buf, x - 1, y));
+    outputArray[4] = *((ushort *) rsGetElementAt(buf, x, y));
+    outputArray[5] = *((ushort *) rsGetElementAt(buf, x + 1, y));
+    outputArray[6] = *((ushort *) rsGetElementAt(buf, x - 1, y + 1));
+    outputArray[7] = *((ushort *) rsGetElementAt(buf, x, y + 1));
+    outputArray[8] = *((ushort *) rsGetElementAt(buf, x + 1, y + 1));
+}
+
+// Blacklevel subtract, and normalize each pixel in the outputArray, and apply the
+// gain map.
+static void linearizeAndGainmap(uint x, uint y, ushort4 blackLevel, int whiteLevel,
+        uint cfa, /*inout*/float* outputArray) {
+    uint kk = 0;
+    for (uint j = y - 1; j <= y + 1; j++) {
+        for (uint i = x - 1; i <= x + 1; i++) {
+            uint index = (i & 1) | ((j & 1) << 1);  // bits [0,1] are blacklevel offset
+            index |= (cfa << 2);  // bits [2,3] are cfa
+            float bl = 0.f;
+            float g = 1.f;
+            float4 gains = 1.f;
+            if (hasGainMap) {
+                gains = getGain(i, j);
+            }
+            switch (index) {
+                // RGGB
+                case 0:
+                    bl = blackLevel.x;
+                    g = gains.x;
+                    break;
+                case 1:
+                    bl = blackLevel.y;
+                    g = gains.y;
+                    break;
+                case 2:
+                    bl = blackLevel.z;
+                    g = gains.z;
+                    break;
+                case 3:
+                    bl = blackLevel.w;
+                    g = gains.w;
+                    break;
+                // GRBG
+                case 4:
+                    bl = blackLevel.x;
+                    g = gains.y;
+                    break;
+                case 5:
+                    bl = blackLevel.y;
+                    g = gains.x;
+                    break;
+                case 6:
+                    bl = blackLevel.z;
+                    g = gains.w;
+                    break;
+                case 7:
+                    bl = blackLevel.w;
+                    g = gains.z;
+                    break;
+                // GBRG
+                case 8:
+                    bl = blackLevel.x;
+                    g = gains.y;
+                    break;
+                case 9:
+                    bl = blackLevel.y;
+                    g = gains.w;
+                    break;
+                case 10:
+                    bl = blackLevel.z;
+                    g = gains.x;
+                    break;
+                case 11:
+                    bl = blackLevel.w;
+                    g = gains.z;
+                    break;
+                // BGGR
+                case 12:
+                    bl = blackLevel.x;
+                    g = gains.w;
+                    break;
+                case 13:
+                    bl = blackLevel.y;
+                    g = gains.y;
+                    break;
+                case 14:
+                    bl = blackLevel.z;
+                    g = gains.z;
+                    break;
+                case 15:
+                    bl = blackLevel.w;
+                    g = gains.x;
+                    break;
+            }
+            outputArray[kk] = clamp(g * (outputArray[kk] - bl) / (whiteLevel - bl), 0.f, 1.f);
+            kk++;
+        }
+    }
+}
+
+// Apply bilinear-interpolation to demosaic
+static float3 demosaic(uint x, uint y, uint cfa, float* inputArray) {
+    uint index = (x & 1) | ((y & 1) << 1);
+    index |= (cfa << 2);
+    float3 pRGB;
+    switch (index) {
+        case 0:
+        case 5:
+        case 10:
+        case 15:  // Red centered
+                  // B G B
+                  // G R G
+                  // B G B
+            pRGB.x = inputArray[4];
+            pRGB.y = (inputArray[1] + inputArray[3] + inputArray[5] + inputArray[7]) / 4;
+            pRGB.z = (inputArray[0] + inputArray[2] + inputArray[6] + inputArray[8]) / 4;
+            break;
+        case 1:
+        case 4:
+        case 11:
+        case 14: // Green centered w/ horizontally adjacent Red
+                 // G B G
+                 // R G R
+                 // G B G
+            pRGB.x = (inputArray[3] + inputArray[5]) / 2;
+            pRGB.y = inputArray[4];
+            pRGB.z = (inputArray[1] + inputArray[7]) / 2;
+            break;
+        case 2:
+        case 7:
+        case 8:
+        case 13: // Green centered w/ horizontally adjacent Blue
+                 // G R G
+                 // B G B
+                 // G R G
+            pRGB.x = (inputArray[1] + inputArray[7]) / 2;
+            pRGB.y = inputArray[4];
+            pRGB.z = (inputArray[3] + inputArray[5]) / 2;
+            break;
+        case 3:
+        case 6:
+        case 9:
+        case 12: // Blue centered
+                 // R G R
+                 // G B G
+                 // R G R
+            pRGB.x = (inputArray[0] + inputArray[2] + inputArray[6] + inputArray[8]) / 4;
+            pRGB.y = (inputArray[1] + inputArray[3] + inputArray[5] + inputArray[7]) / 4;
+            pRGB.z = inputArray[4];
+            break;
+    }
+
+    return pRGB;
+}
+
+// Full RAW->ARGB bitmap conversion kernel
+uchar4 RS_KERNEL convert_RAW_To_ARGB(uint x, uint y) {
+    float3 pRGB;
+    uint xP = x + offsetX;
+    uint yP = y + offsetY;
+    if (xP == 0) xP = 1;
+    if (yP == 0) yP = 1;
+    if (xP == rawWidth - 1) xP = rawWidth - 2;
+    if (yP == rawHeight - 1) yP = rawHeight  - 2;
+
+    float patch[9];
+    // TODO: Once ScriptGroup and RS kernels have been updated to allow for iteration over 3x3 pixel
+    // patches, this can be optimized to avoid re-applying the pre-demosaic steps for each pixel,
+    // potentially achieving a 9x speedup here.
+    load3x3(xP, yP, inputRawBuffer, /*out*/ patch);
+    linearizeAndGainmap(xP, yP, blackLevelPattern, whiteLevel, cfaPattern, /*inout*/patch);
+    pRGB = demosaic(xP, yP, cfaPattern, patch);
+
+    return rsPackColorTo8888(applyColorspace(pRGB));
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
new file mode 100644
index 0000000..0108ee6
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
@@ -0,0 +1,495 @@
+/*
+ * 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.hardware.camera2.cts.testcases;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static com.android.ex.camera2.blocking.BlockingStateCallback.*;
+
+import android.content.Context;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CaptureRequest;
+import android.util.Size;
+import android.hardware.camera2.cts.CameraTestUtils;
+import android.hardware.camera2.cts.helpers.CameraErrorCollector;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
+import android.media.Image;
+import android.media.Image.Plane;
+import android.media.ImageReader;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.test.AndroidTestCase;
+import android.util.Log;
+import android.view.Surface;
+import android.view.WindowManager;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.ex.camera2.blocking.BlockingStateCallback;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class Camera2AndroidTestCase extends AndroidTestCase {
+    private static final String TAG = "Camera2AndroidTestCase";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+    protected static final String DEBUG_FILE_NAME_BASE =
+            Environment.getExternalStorageDirectory().getPath();
+    // Default capture size: VGA size is required by CDD.
+    protected static final Size DEFAULT_CAPTURE_SIZE = new Size(640, 480);
+    protected static final int CAPTURE_WAIT_TIMEOUT_MS = 5000;
+
+    protected CameraManager mCameraManager;
+    protected CameraDevice mCamera;
+    protected CameraCaptureSession mCameraSession;
+    protected BlockingSessionCallback mCameraSessionListener;
+    protected BlockingStateCallback mCameraListener;
+    protected String[] mCameraIds;
+    protected ImageReader mReader;
+    protected Surface mReaderSurface;
+    protected Handler mHandler;
+    protected HandlerThread mHandlerThread;
+    protected StaticMetadata mStaticInfo;
+    protected CameraErrorCollector mCollector;
+    protected List<Size> mOrderedPreviewSizes; // In descending order.
+    protected List<Size> mOrderedVideoSizes; // In descending order.
+    protected List<Size> mOrderedStillSizes; // In descending order.
+
+    protected WindowManager mWindowManager;
+
+    @Override
+    public void setContext(Context context) {
+        super.setContext(context);
+        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
+        assertNotNull("Can't connect to camera manager!", mCameraManager);
+        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+    }
+
+    /**
+     * Set up the camera2 test case required environments, including CameraManager,
+     * HandlerThread, Camera IDs, and CameraStateCallback etc.
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        /**
+         * Workaround for mockito and JB-MR2 incompatibility
+         *
+         * Avoid java.lang.IllegalArgumentException: dexcache == null
+         * https://code.google.com/p/dexmaker/issues/detail?id=2
+         */
+        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
+
+        mCameraIds = mCameraManager.getCameraIdList();
+        assertNotNull("Camera ids shouldn't be null", mCameraIds);
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mCameraListener = new BlockingStateCallback();
+        mCollector = new CameraErrorCollector();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mHandlerThread.quitSafely();
+        mHandler = null;
+        closeDefaultImageReader();
+
+        try {
+            mCollector.verify();
+        } catch (Throwable e) {
+            // When new Exception(e) is used, exception info will be printed twice.
+            throw new Exception(e.getMessage());
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    /**
+     * Start capture with given {@link #CaptureRequest}.
+     *
+     * @param request The {@link #CaptureRequest} to be captured.
+     * @param repeating If the capture is single capture or repeating.
+     * @param listener The {@link #CaptureCallback} camera device used to notify callbacks.
+     * @param handler The handler camera device used to post callbacks.
+     */
+    protected void startCapture(CaptureRequest request, boolean repeating,
+            CaptureCallback listener, Handler handler) throws Exception {
+        if (VERBOSE) Log.v(TAG, "Starting capture from device");
+
+        if (repeating) {
+            mCameraSession.setRepeatingRequest(request, listener, handler);
+        } else {
+            mCameraSession.capture(request, listener, handler);
+        }
+    }
+
+    /**
+     * Stop the current active capture.
+     *
+     * @param fast When it is true, {@link CameraDevice#flush} is called, the stop capture
+     * could be faster.
+     */
+    protected void stopCapture(boolean fast) throws Exception {
+        if (VERBOSE) Log.v(TAG, "Stopping capture");
+
+        if (fast) {
+            /**
+             * Flush is useful for canceling long exposure single capture, it also could help
+             * to make the streaming capture stop sooner.
+             */
+            mCameraSession.abortCaptures();
+            mCameraSessionListener.getStateWaiter().
+                    waitForState(BlockingSessionCallback.SESSION_READY, CAMERA_IDLE_TIMEOUT_MS);
+        } else {
+            mCameraSession.close();
+            mCameraSessionListener.getStateWaiter().
+                    waitForState(BlockingSessionCallback.SESSION_CLOSED, CAMERA_IDLE_TIMEOUT_MS);
+        }
+    }
+
+    /**
+     * Open a {@link #CameraDevice camera device} and get the StaticMetadata for a given camera id.
+     * The default mCameraListener is used to wait for states.
+     *
+     * @param cameraId The id of the camera device to be opened.
+     */
+    protected void openDevice(String cameraId) throws Exception {
+        openDevice(cameraId, mCameraListener);
+    }
+
+    /**
+     * Open a {@link #CameraDevice} and get the StaticMetadata for a given camera id and listener.
+     *
+     * @param cameraId The id of the camera device to be opened.
+     * @param listener The {@link #BlockingStateCallback} used to wait for states.
+     */
+    protected void openDevice(String cameraId, BlockingStateCallback listener) throws Exception {
+        mCamera = CameraTestUtils.openCamera(
+                mCameraManager, cameraId, listener, mHandler);
+        mCollector.setCameraId(cameraId);
+        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
+                CheckLevel.ASSERT, /*collector*/null);
+        if (mStaticInfo.isColorOutputSupported()) {
+            mOrderedPreviewSizes = getSupportedPreviewSizes(
+                    cameraId, mCameraManager,
+                    getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
+            mOrderedVideoSizes = getSupportedVideoSizes(cameraId, mCameraManager, PREVIEW_SIZE_BOUND);
+            mOrderedStillSizes = getSupportedStillSizes(cameraId, mCameraManager, null);
+        }
+
+        if (VERBOSE) {
+            Log.v(TAG, "Camera " + cameraId + " is opened");
+        }
+    }
+
+    /**
+     * Create a {@link #CameraCaptureSession} using the currently open camera.
+     *
+     * @param outputSurfaces The set of output surfaces to configure for this session
+     */
+    protected void createSession(List<Surface> outputSurfaces) throws Exception {
+        mCameraSessionListener = new BlockingSessionCallback();
+        mCameraSession = CameraTestUtils.configureCameraSession(mCamera, outputSurfaces,
+                mCameraSessionListener, mHandler);
+    }
+
+    /**
+     * Close a {@link #CameraDevice camera device} and clear the associated StaticInfo field for a
+     * given camera id. The default mCameraListener is used to wait for states.
+     * <p>
+     * This function must be used along with the {@link #openDevice} for the
+     * same camera id.
+     * </p>
+     *
+     * @param cameraId The id of the {@link #CameraDevice camera device} to be closed.
+     */
+    protected void closeDevice(String cameraId) {
+        closeDevice(cameraId, mCameraListener);
+    }
+
+    /**
+     * Close a {@link #CameraDevice camera device} and clear the associated StaticInfo field for a
+     * given camera id and listener.
+     * <p>
+     * This function must be used along with the {@link #openDevice} for the
+     * same camera id.
+     * </p>
+     *
+     * @param cameraId The id of the camera device to be closed.
+     * @param listener The BlockingStateCallback used to wait for states.
+     */
+    protected void closeDevice(String cameraId, BlockingStateCallback listener) {
+        if (mCamera != null) {
+            if (!cameraId.equals(mCamera.getId())) {
+                throw new IllegalStateException("Try to close a device that is not opened yet");
+            }
+            mCamera.close();
+            listener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
+            mCamera = null;
+            mCameraSession = null;
+            mCameraSessionListener = null;
+            mStaticInfo = null;
+            mOrderedPreviewSizes = null;
+            mOrderedVideoSizes = null;
+            mOrderedStillSizes = null;
+
+            if (VERBOSE) {
+                Log.v(TAG, "Camera " + cameraId + " is closed");
+            }
+        }
+    }
+
+    /**
+     * Create an {@link ImageReader} object and get the surface.
+     * <p>
+     * This function creates {@link ImageReader} object and surface, then assign
+     * to the default {@link mReader} and {@link mReaderSurface}. It closes the
+     * current default active {@link ImageReader} if it exists.
+     * </p>
+     *
+     * @param size The size of this ImageReader to be created.
+     * @param format The format of this ImageReader to be created
+     * @param maxNumImages The max number of images that can be acquired
+     *            simultaneously.
+     * @param listener The listener used by this ImageReader to notify
+     *            callbacks.
+     */
+    protected void createDefaultImageReader(Size size, int format, int maxNumImages,
+            ImageReader.OnImageAvailableListener listener) throws Exception {
+        closeDefaultImageReader();
+
+        mReader = createImageReader(size, format, maxNumImages, listener);
+        mReaderSurface = mReader.getSurface();
+        if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString());
+    }
+
+    /**
+     * Create an {@link ImageReader} object.
+     *
+     * <p>This function creates image reader object for given format, maxImages, and size.</p>
+     *
+     * @param size The size of this ImageReader to be created.
+     * @param format The format of this ImageReader to be created
+     * @param maxNumImages The max number of images that can be acquired simultaneously.
+     * @param listener The listener used by this ImageReader to notify callbacks.
+     */
+
+    protected ImageReader createImageReader(Size size, int format, int maxNumImages,
+            ImageReader.OnImageAvailableListener listener) throws Exception {
+
+        ImageReader reader = null;
+        reader = ImageReader.newInstance(size.getWidth(), size.getHeight(),
+                format, maxNumImages);
+
+        reader.setOnImageAvailableListener(listener, mHandler);
+        if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString());
+        return reader;
+    }
+
+    /**
+     * Close the pending images then close current default {@link ImageReader} object.
+     */
+    protected void closeDefaultImageReader() {
+        closeImageReader(mReader);
+        mReader = null;
+        mReaderSurface = null;
+    }
+
+    /**
+     * Close an image reader instance.
+     *
+     * @param reader
+     */
+    protected void closeImageReader(ImageReader reader) {
+        if (reader != null) {
+            try {
+                // Close all possible pending images first.
+                Image image = reader.acquireLatestImage();
+                if (image != null) {
+                    image.close();
+                }
+            } finally {
+                reader.close();
+                reader = null;
+            }
+        }
+    }
+
+    protected CaptureRequest prepareCaptureRequest() throws Exception {
+        List<Surface> outputSurfaces = new ArrayList<Surface>();
+        Surface surface = mReader.getSurface();
+        assertNotNull("Fail to get surface from ImageReader", surface);
+        outputSurfaces.add(surface);
+        return prepareCaptureRequestForSurfaces(outputSurfaces, CameraDevice.TEMPLATE_PREVIEW)
+                .build();
+    }
+
+    protected CaptureRequest.Builder prepareCaptureRequestForSurfaces(List<Surface> surfaces,
+            int template)
+            throws Exception {
+        createSession(surfaces);
+
+        CaptureRequest.Builder captureBuilder =
+                mCamera.createCaptureRequest(template);
+        assertNotNull("Fail to get captureRequest", captureBuilder);
+        for (Surface surface : surfaces) {
+            captureBuilder.addTarget(surface);
+        }
+
+        return captureBuilder;
+    }
+
+    /**
+     * Test the invalid Image access: accessing a closed image must result in
+     * {@link IllegalStateException}.
+     *
+     * @param closedImage The closed image.
+     * @param closedBuffer The ByteBuffer from a closed Image. buffer invalid
+     *            access will be skipped if it is null.
+     */
+    protected void imageInvalidAccessTestAfterClose(Image closedImage,
+            Plane closedPlane, ByteBuffer closedBuffer) {
+        if (closedImage == null) {
+            throw new IllegalArgumentException(" closedImage must be non-null");
+        }
+        if (closedBuffer != null && !closedBuffer.isDirect()) {
+            throw new IllegalArgumentException("The input ByteBuffer should be direct ByteBuffer");
+        }
+
+        if (closedPlane != null) {
+            // Plane#getBuffer test
+            try {
+                closedPlane.getBuffer(); // An ISE should be thrown here.
+                fail("Image should throw IllegalStateException when calling getBuffer"
+                        + " after the image is closed");
+            } catch (IllegalStateException e) {
+                // Expected.
+            }
+
+            // Plane#getPixelStride test
+            try {
+                closedPlane.getPixelStride(); // An ISE should be thrown here.
+                fail("Image should throw IllegalStateException when calling getPixelStride"
+                        + " after the image is closed");
+            } catch (IllegalStateException e) {
+                // Expected.
+            }
+
+            // Plane#getRowStride test
+            try {
+                closedPlane.getRowStride(); // An ISE should be thrown here.
+                fail("Image should throw IllegalStateException when calling getRowStride"
+                        + " after the image is closed");
+            } catch (IllegalStateException e) {
+                // Expected.
+            }
+        }
+
+        // ByteBuffer access test
+        if (closedBuffer != null) {
+            try {
+                closedBuffer.get(); // An ISE should be thrown here.
+                fail("Image should throw IllegalStateException when accessing a byte buffer"
+                        + " after the image is closed");
+            } catch (IllegalStateException e) {
+                // Expected.
+            }
+        }
+
+        // Image#getFormat test
+        try {
+            closedImage.getFormat();
+            fail("Image should throw IllegalStateException when calling getFormat"
+                    + " after the image is closed");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+
+        // Image#getWidth test
+        try {
+            closedImage.getWidth();
+            fail("Image should throw IllegalStateException when calling getWidth"
+                    + " after the image is closed");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+
+        // Image#getHeight test
+        try {
+            closedImage.getHeight();
+            fail("Image should throw IllegalStateException when calling getHeight"
+                    + " after the image is closed");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+
+        // Image#getTimestamp test
+        try {
+            closedImage.getTimestamp();
+            fail("Image should throw IllegalStateException when calling getTimestamp"
+                    + " after the image is closed");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+
+        // Image#getTimestamp test
+        try {
+            closedImage.getTimestamp();
+            fail("Image should throw IllegalStateException when calling getTimestamp"
+                    + " after the image is closed");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+
+        // Image#getCropRect test
+        try {
+            closedImage.getCropRect();
+            fail("Image should throw IllegalStateException when calling getCropRect"
+                    + " after the image is closed");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+
+        // Image#setCropRect test
+        try {
+            Rect rect = new Rect();
+            closedImage.setCropRect(rect);
+            fail("Image should throw IllegalStateException when calling setCropRect"
+                    + " after the image is closed");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+
+        // Image#getPlanes test
+        try {
+            closedImage.getPlanes();
+            fail("Image should throw IllegalStateException when calling getPlanes"
+                    + " after the image is closed");
+        } catch (IllegalStateException e) {
+            // Expected.
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
new file mode 100644
index 0000000..39bf0a5
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
@@ -0,0 +1,418 @@
+/*
+ * 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.hardware.camera2.cts.testcases;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
+import static com.android.ex.camera2.blocking.BlockingStateCallback.*;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Matrix;
+import android.graphics.RectF;
+import android.graphics.SurfaceTexture;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.cts.Camera2MultiViewCtsActivity;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.util.Size;
+import android.view.Surface;
+import android.view.TextureView;
+import android.view.WindowManager;
+
+import com.android.ex.camera2.blocking.BlockingCameraManager;
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.ex.camera2.blocking.BlockingStateCallback;
+
+import junit.framework.Assert;
+
+import java.util.List;
+import java.util.HashMap;
+
+/**
+ * Camera2 test case base class by using mixed SurfaceView and TextureView as rendering target.
+ */
+public class Camera2MultiViewTestCase extends
+        ActivityInstrumentationTestCase2<Camera2MultiViewCtsActivity> {
+    private static final String TAG = "MultiViewTestCase";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+
+
+    private static final long SHORT_SLEEP_WAIT_TIME_MS = 100;
+
+    protected TextureView[] mTextureView = new TextureView[2];
+    protected String[] mCameraIds;
+    protected Handler mHandler;
+
+    private CameraManager mCameraManager;
+    private BlockingStateCallback mCameraListener;
+    private HandlerThread mHandlerThread;
+    private Context mContext;
+
+    private CameraHolder[] mCameraHolders;
+    private HashMap<String, Integer> mCameraIdMap;
+
+    protected WindowManager mWindowManager;
+
+    public Camera2MultiViewTestCase() {
+        super(Camera2MultiViewCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getActivity();
+        assertNotNull("Unable to get activity", mContext);
+        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
+        assertNotNull("Unable to get CameraManager", mCameraManager);
+        mCameraIds = mCameraManager.getCameraIdList();
+        assertNotNull("Unable to get camera ids", mCameraIds);
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mCameraListener = new BlockingStateCallback();
+        Camera2MultiViewCtsActivity activity = (Camera2MultiViewCtsActivity) mContext;
+        mTextureView[0] = activity.getTextureView(0);
+        mTextureView[1] = activity.getTextureView(1);
+        assertNotNull("Unable to get texture view", mTextureView);
+        mCameraIdMap = new HashMap<String, Integer>();
+        int numCameras = mCameraIds.length;
+        mCameraHolders = new CameraHolder[numCameras];
+        for (int i = 0; i < numCameras; i++) {
+            mCameraHolders[i] = new CameraHolder(mCameraIds[i]);
+            mCameraIdMap.put(mCameraIds[i], i);
+        }
+        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mHandlerThread.quitSafely();
+        mHandler = null;
+        mCameraListener = null;
+        for (CameraHolder camera : mCameraHolders) {
+            if (camera.isOpenned()) {
+                camera.close();
+                camera = null;
+            }
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Update preview TextureView rotation to accommodate discrepancy between preview
+     * buffer and the view window orientation.
+     *
+     * Assumptions:
+     * - Aspect ratio for the sensor buffers is in landscape orientation,
+     * - Dimensions of buffers received are rotated to the natural device orientation.
+     * - The contents of each buffer are rotated by the inverse of the display rotation.
+     * - Surface scales the buffer to fit the current view bounds.
+     * TODO: Make this method works for all orientations
+     *
+     */
+    protected void updatePreviewDisplayRotation(Size previewSize, TextureView textureView) {
+        int rotationDegrees = 0;
+        Camera2MultiViewCtsActivity activity = (Camera2MultiViewCtsActivity) mContext;
+        int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
+        Configuration config = activity.getResources().getConfiguration();
+
+        // Get UI display rotation
+        switch (displayRotation) {
+            case Surface.ROTATION_0:
+                rotationDegrees = 0;
+                break;
+            case Surface.ROTATION_90:
+                rotationDegrees = 90;
+            break;
+            case Surface.ROTATION_180:
+                rotationDegrees = 180;
+            break;
+            case Surface.ROTATION_270:
+                rotationDegrees = 270;
+            break;
+        }
+
+        // Get device natural orientation
+        int deviceOrientation = Configuration.ORIENTATION_PORTRAIT;
+        if ((rotationDegrees % 180 == 0 &&
+                config.orientation == Configuration.ORIENTATION_LANDSCAPE) ||
+                ((rotationDegrees % 180 != 0 &&
+                config.orientation == Configuration.ORIENTATION_PORTRAIT))) {
+            deviceOrientation = Configuration.ORIENTATION_LANDSCAPE;
+        }
+
+        // Rotate the buffer dimensions if device orientation is portrait.
+        int effectiveWidth = previewSize.getWidth();
+        int effectiveHeight = previewSize.getHeight();
+        if (deviceOrientation == Configuration.ORIENTATION_PORTRAIT) {
+            effectiveWidth = previewSize.getHeight();
+            effectiveHeight = previewSize.getWidth();
+        }
+
+        // Find and center view rect and buffer rect
+        Matrix transformMatrix =  textureView.getTransform(null);
+        int viewWidth = textureView.getWidth();
+        int viewHeight = textureView.getHeight();
+        RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
+        RectF bufRect = new RectF(0, 0, effectiveWidth, effectiveHeight);
+        float centerX = viewRect.centerX();
+        float centerY = viewRect.centerY();
+        bufRect.offset(centerX - bufRect.centerX(), centerY - bufRect.centerY());
+
+        // Undo ScaleToFit.FILL done by the surface
+        transformMatrix.setRectToRect(viewRect, bufRect, Matrix.ScaleToFit.FILL);
+
+        // Rotate buffer contents to proper orientation
+        transformMatrix.postRotate((360 - rotationDegrees) % 360, centerX, centerY);
+        if ((rotationDegrees % 180) == 90) {
+            int temp = effectiveWidth;
+            effectiveWidth = effectiveHeight;
+            effectiveHeight = temp;
+        }
+
+        // Scale to fit view, cropping the longest dimension
+        float scale =
+                Math.max(viewWidth / (float) effectiveWidth, viewHeight / (float) effectiveHeight);
+        transformMatrix.postScale(scale, scale, centerX, centerY);
+
+        Handler handler = new Handler(Looper.getMainLooper());
+        class TransformUpdater implements Runnable {
+            TextureView mView;
+            Matrix mTransformMatrix;
+            TransformUpdater(TextureView view, Matrix matrix) {
+                mView = view;
+                mTransformMatrix = matrix;
+            }
+
+            @Override
+            public void run() {
+                mView.setTransform(mTransformMatrix);
+            }
+        }
+        handler.post(new TransformUpdater(textureView, transformMatrix));
+    }
+
+    protected void openCamera(String cameraId) throws Exception {
+        CameraHolder camera = getCameraHolder(cameraId);
+        assertFalse("Camera has already opened", camera.isOpenned());
+        camera.open();
+        return;
+    }
+
+    protected void closeCamera(String cameraId) throws Exception {
+        CameraHolder camera = getCameraHolder(cameraId);
+        camera.close();
+    }
+
+    protected void startPreview(
+            String cameraId, List<Surface> outputSurfaces, CaptureCallback listener)
+            throws Exception {
+        CameraHolder camera = getCameraHolder(cameraId);
+        assertTrue("Camera " + cameraId + " is not openned", camera.isOpenned());
+        camera.startPreview(outputSurfaces, listener);
+    }
+
+    protected void stopPreview(String cameraId) throws Exception {
+        CameraHolder camera = getCameraHolder(cameraId);
+        assertTrue("Camera " + cameraId + " preview is not running", camera.isPreviewStarted());
+        camera.stopPreview();
+    }
+
+    protected StaticMetadata getStaticInfo(String cameraId) {
+        CameraHolder camera = getCameraHolder(cameraId);
+        assertTrue("Camera is not openned", camera.isOpenned());
+        return camera.getStaticInfo();
+    }
+
+    protected List<Size> getOrderedPreviewSizes(String cameraId) {
+        CameraHolder camera = getCameraHolder(cameraId);
+        assertTrue("Camera is not openned", camera.isOpenned());
+        return camera.getOrderedPreviewSizes();
+    }
+
+    /**
+     * Wait until the SurfaceTexture available from the TextureView, then return it.
+     * Return null if the wait times out.
+     *
+     * @param timeOutMs The timeout value for the wait
+     * @return The available SurfaceTexture, return null if the wait times out.
+     */
+    protected SurfaceTexture getAvailableSurfaceTexture(long timeOutMs, TextureView view) {
+        long waitTime = timeOutMs;
+
+        while (!view.isAvailable() && waitTime > 0) {
+            long startTimeMs = SystemClock.elapsedRealtime();
+            SystemClock.sleep(SHORT_SLEEP_WAIT_TIME_MS);
+            waitTime -= (SystemClock.elapsedRealtime() - startTimeMs);
+        }
+
+        if (view.isAvailable()) {
+            return view.getSurfaceTexture();
+        } else {
+            Log.w(TAG, "Wait for SurfaceTexture available timed out after " + timeOutMs + "ms");
+            return null;
+        }
+    }
+
+    public static class CameraPreviewListener implements TextureView.SurfaceTextureListener {
+        private boolean mFirstPreviewAvailable = false;
+        private final ConditionVariable mPreviewDone = new ConditionVariable();
+
+        @Override
+        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
+            // Ignored. The SurfaceTexture is polled by getAvailableSurfaceTexture.
+        }
+
+        @Override
+        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
+            // Ignored. The CameraDevice should already know the changed size.
+        }
+
+        @Override
+        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
+            /**
+             * Return true, assume that client detaches the surface before it is
+             * destroyed. For example, CameraDevice should detach this surface when
+             * stopping preview. No need to release the SurfaceTexture here as it
+             * is released by TextureView after onSurfaceTextureDestroyed is called.
+             */
+            Log.i(TAG, "onSurfaceTextureDestroyed called.");
+            return true;
+        }
+
+        @Override
+        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
+            // Invoked every time there's a new Camera preview frame
+            if (!mFirstPreviewAvailable) {
+                mFirstPreviewAvailable = true;
+                mPreviewDone.open();
+            }
+        }
+
+        /** Waits until the camera preview is up running */
+        public boolean waitForPreviewDone(long timeOutMs) {
+            if (!mPreviewDone.block(timeOutMs)) {
+                // timeout could be expected or unexpected. The caller will decide.
+                Log.w(TAG, "waitForPreviewDone timed out after " + timeOutMs + "ms");
+                return false;
+            }
+            mPreviewDone.close();
+            return true;
+        }
+    }
+
+    private CameraHolder getCameraHolder(String cameraId) {
+        Integer cameraIdx = mCameraIdMap.get(cameraId);
+        if (cameraIdx == null) {
+            Assert.fail("Unknown camera Id");
+        }
+        return mCameraHolders[cameraIdx];
+    }
+
+    // Per device fields
+    private class CameraHolder {
+        private String mCameraId;
+        private CameraCaptureSession mSession;
+        private CameraDevice mCamera;
+        private StaticMetadata mStaticInfo;
+        private List<Size> mOrderedPreviewSizes;
+        private BlockingSessionCallback mSessionListener;
+
+        public CameraHolder(String id){
+            mCameraId = id;
+        }
+
+        public StaticMetadata getStaticInfo() {
+            return mStaticInfo;
+        }
+
+        public List<Size> getOrderedPreviewSizes() {
+            return mOrderedPreviewSizes;
+        }
+
+        public void open() throws Exception {
+            assertNull("Camera is already opened", mCamera);
+            mCamera = (new BlockingCameraManager(mCameraManager)).openCamera(
+                    mCameraId, mCameraListener, mHandler);
+            mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(mCameraId),
+                    CheckLevel.ASSERT, /*collector*/null);
+            if (mStaticInfo.isColorOutputSupported()) {
+                mOrderedPreviewSizes = getSupportedPreviewSizes(
+                        mCameraId, mCameraManager,
+                        getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
+            }
+            assertNotNull(String.format("Failed to open camera device ID: %s", mCameraId), mCamera);
+        }
+
+        public boolean isOpenned() {
+            return (mCamera != null);
+        }
+
+        public void close() throws Exception {
+            if (!isOpenned()) {
+                return;
+            }
+            mCamera.close();
+            mCameraListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
+            mCamera = null;
+            mSession = null;
+            mStaticInfo = null;
+            mOrderedPreviewSizes = null;
+        }
+
+        public void startPreview(List<Surface> outputSurfaces, CaptureCallback listener)
+                throws Exception {
+            mSessionListener = new BlockingSessionCallback();
+            mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
+
+            // TODO: vary the different settings like crop region to cover more cases.
+            CaptureRequest.Builder captureBuilder =
+                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+
+            for (Surface surface : outputSurfaces) {
+                captureBuilder.addTarget(surface);
+            }
+            mSession.setRepeatingRequest(captureBuilder.build(), listener, mHandler);
+        }
+
+        public boolean isPreviewStarted() {
+            return (mSession != null);
+        }
+
+        public void stopPreview() throws Exception {
+            if (VERBOSE) Log.v(TAG,
+                    "Stopping camera " + mCameraId +" preview and waiting for idle");
+            // Stop repeat, wait for captures to complete, and disconnect from surfaces
+            mSession.close();
+            mSessionListener.getStateWaiter().waitForState(
+                    SESSION_CLOSED, SESSION_CLOSE_TIMEOUT_MS);
+            mSessionListener = null;
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
new file mode 100644
index 0000000..b7287ae
--- /dev/null
+++ b/tests/camera/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
@@ -0,0 +1,722 @@
+/*
+ * 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.hardware.camera2.cts.testcases;
+
+import static android.hardware.camera2.cts.CameraTestUtils.*;
+import static com.android.ex.camera2.blocking.BlockingStateCallback.STATE_CLOSED;
+
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.media.ImageReader;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.WindowManager;
+import android.content.Context;
+import android.graphics.ImageFormat;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCaptureSession;
+import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
+import android.hardware.camera2.CaptureRequest;
+import android.hardware.camera2.CaptureResult;
+import android.util.Size;
+import android.util.Range;
+import android.hardware.camera2.cts.Camera2SurfaceViewCtsActivity;
+import android.hardware.camera2.cts.CameraTestUtils;
+import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
+import android.hardware.camera2.cts.helpers.CameraErrorCollector;
+import android.hardware.camera2.cts.helpers.StaticMetadata;
+import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
+
+import com.android.ex.camera2.blocking.BlockingSessionCallback;
+import com.android.ex.camera2.blocking.BlockingStateCallback;
+import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Camera2 Preview test case base class by using SurfaceView as rendering target.
+ *
+ * <p>This class encapsulates the SurfaceView based preview common functionalities.
+ * The setup and teardown of CameraManager, test HandlerThread, Activity, Camera IDs
+ * and CameraStateCallback are handled in this class. Some basic preview related utility
+ * functions are provided to facilitate the derived preview-based test classes.
+ * </p>
+ */
+
+public class Camera2SurfaceViewTestCase extends
+        ActivityInstrumentationTestCase2<Camera2SurfaceViewCtsActivity> {
+    private static final String TAG = "SurfaceViewTestCase";
+    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private static final int WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS = 1000;
+
+    // TODO: Use internal storage for this to make sure the file is only visible to test.
+    protected static final String DEBUG_FILE_NAME_BASE =
+            Environment.getExternalStorageDirectory().getPath();
+    protected static final int WAIT_FOR_RESULT_TIMEOUT_MS = 3000;
+    protected static final float FRAME_DURATION_ERROR_MARGIN = 0.005f; // 0.5 percent error margin.
+    protected static final int NUM_RESULTS_WAIT_TIMEOUT = 100;
+    protected static final int NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY = 8;
+    protected static final int MIN_FRAME_DURATION_ERROR_MARGIN = 100; // ns
+
+    protected Context mContext;
+    protected CameraManager mCameraManager;
+    protected String[] mCameraIds;
+    protected HandlerThread mHandlerThread;
+    protected Handler mHandler;
+    protected BlockingStateCallback mCameraListener;
+    protected BlockingSessionCallback mSessionListener;
+    protected CameraErrorCollector mCollector;
+    // Per device fields:
+    protected StaticMetadata mStaticInfo;
+    protected CameraDevice mCamera;
+    protected CameraCaptureSession mSession;
+    protected ImageReader mReader;
+    protected Surface mReaderSurface;
+    protected Surface mPreviewSurface;
+    protected Size mPreviewSize;
+    protected List<Size> mOrderedPreviewSizes; // In descending order.
+    protected List<Size> mOrderedVideoSizes; // In descending order.
+    protected List<Size> mOrderedStillSizes; // In descending order.
+    protected HashMap<Size, Long> mMinPreviewFrameDurationMap;
+
+    protected WindowManager mWindowManager;
+
+    public Camera2SurfaceViewTestCase() {
+        super(Camera2SurfaceViewCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        /**
+         * Set up the camera preview required environments, including activity,
+         * CameraManager, HandlerThread, Camera IDs, and CameraStateCallback.
+         */
+        super.setUp();
+        mContext = getActivity();
+        /**
+         * Workaround for mockito and JB-MR2 incompatibility
+         *
+         * Avoid java.lang.IllegalArgumentException: dexcache == null
+         * https://code.google.com/p/dexmaker/issues/detail?id=2
+         */
+        System.setProperty("dexmaker.dexcache", mContext.getCacheDir().toString());
+        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
+        assertNotNull("Unable to get CameraManager", mCameraManager);
+        mCameraIds = mCameraManager.getCameraIdList();
+        assertNotNull("Unable to get camera ids", mCameraIds);
+        mHandlerThread = new HandlerThread(TAG);
+        mHandlerThread.start();
+        mHandler = new Handler(mHandlerThread.getLooper());
+        mCameraListener = new BlockingStateCallback();
+        mCollector = new CameraErrorCollector();
+
+        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Teardown the camera preview required environments.
+        mHandlerThread.quitSafely();
+        mHandler = null;
+        mCameraListener = null;
+
+        try {
+            mCollector.verify();
+        } catch (Throwable e) {
+            // When new Exception(e) is used, exception info will be printed twice.
+            throw new Exception(e.getMessage());
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    /**
+     * Start camera preview by using the given request, preview size and capture
+     * listener.
+     * <p>
+     * If preview is already started, calling this function will stop the
+     * current preview stream and start a new preview stream with given
+     * parameters. No need to call stopPreview between two startPreview calls.
+     * </p>
+     *
+     * @param request The request builder used to start the preview.
+     * @param previewSz The size of the camera device output preview stream.
+     * @param listener The callbacks the camera device will notify when preview
+     *            capture is available.
+     */
+    protected void startPreview(CaptureRequest.Builder request, Size previewSz,
+            CaptureCallback listener) throws Exception {
+        // Update preview size.
+        updatePreviewSurface(previewSz);
+        if (VERBOSE) {
+            Log.v(TAG, "start preview with size " + mPreviewSize.toString());
+        }
+
+        configurePreviewOutput(request);
+
+        mSession.setRepeatingRequest(request.build(), listener, mHandler);
+    }
+
+    /**
+     * Configure the preview output stream.
+     *
+     * @param request The request to be configured with preview surface
+     */
+    protected void configurePreviewOutput(CaptureRequest.Builder request)
+            throws CameraAccessException {
+        List<Surface> outputSurfaces = new ArrayList<Surface>(/*capacity*/1);
+        outputSurfaces.add(mPreviewSurface);
+        mSessionListener = new BlockingSessionCallback();
+        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
+
+        request.addTarget(mPreviewSurface);
+    }
+
+    /**
+     * Create a {@link CaptureRequest#Builder} and add the default preview surface.
+     *
+     * @return The {@link CaptureRequest#Builder} to be created
+     * @throws CameraAccessException When create capture request from camera fails
+     */
+    protected CaptureRequest.Builder createRequestForPreview() throws CameraAccessException {
+        if (mPreviewSurface == null) {
+            throw new IllegalStateException(
+                    "Preview surface is not set yet, call updatePreviewSurface or startPreview"
+                    + "first to set the preview surface properly.");
+        }
+        CaptureRequest.Builder requestBuilder =
+                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
+        requestBuilder.addTarget(mPreviewSurface);
+        return requestBuilder;
+    }
+
+    /**
+     * Stop preview for current camera device.
+     */
+    protected void stopPreview() 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();
+    }
+
+    /**
+     * Setup still (JPEG) capture configuration and start preview.
+     * <p>
+     * The default max number of image is set to image reader.
+     * </p>
+     *
+     * @param previewRequest The capture request to be used for preview
+     * @param stillRequest The capture request to be used for still capture
+     * @param previewSz Preview size
+     * @param stillSz The still capture size
+     * @param resultListener Capture result listener
+     * @param imageListener The still capture image listener
+     */
+    protected void prepareStillCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
+            CaptureRequest.Builder stillRequest, Size previewSz, Size stillSz,
+            CaptureCallback resultListener,
+            ImageReader.OnImageAvailableListener imageListener) throws Exception {
+        prepareCaptureAndStartPreview(previewRequest, stillRequest, previewSz, stillSz,
+                ImageFormat.JPEG, resultListener, MAX_READER_IMAGES, imageListener);
+    }
+
+    /**
+     * Setup still (JPEG) capture configuration and start preview.
+     *
+     * @param previewRequest The capture request to be used for preview
+     * @param stillRequest The capture request to be used for still capture
+     * @param previewSz Preview size
+     * @param stillSz The still capture size
+     * @param resultListener Capture result listener
+     * @param maxNumImages The max number of images set to the image reader
+     * @param imageListener The still capture image listener
+     */
+    protected void prepareStillCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
+            CaptureRequest.Builder stillRequest, Size previewSz, Size stillSz,
+            CaptureCallback resultListener, int maxNumImages,
+            ImageReader.OnImageAvailableListener imageListener) throws Exception {
+        prepareCaptureAndStartPreview(previewRequest, stillRequest, previewSz, stillSz,
+                ImageFormat.JPEG, resultListener, maxNumImages, imageListener);
+    }
+
+    /**
+     * Setup raw capture configuration and start preview.
+     *
+     * <p>
+     * The default max number of image is set to image reader.
+     * </p>
+     *
+     * @param previewRequest The capture request to be used for preview
+     * @param rawRequest The capture request to be used for raw capture
+     * @param previewSz Preview size
+     * @param rawSz The raw capture size
+     * @param resultListener Capture result listener
+     * @param imageListener The raw capture image listener
+     */
+    protected void prepareRawCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
+            CaptureRequest.Builder rawRequest, Size previewSz, Size rawSz,
+            CaptureCallback resultListener,
+            ImageReader.OnImageAvailableListener imageListener) throws Exception {
+        prepareCaptureAndStartPreview(previewRequest, rawRequest, previewSz, rawSz,
+                ImageFormat.RAW_SENSOR, resultListener, MAX_READER_IMAGES, imageListener);
+    }
+
+    /**
+     * Wait for expected result key value available in a certain number of results.
+     *
+     * <p>
+     * Check the result immediately if numFramesWait is 0.
+     * </p>
+     *
+     * @param listener The capture listener to get capture result
+     * @param resultKey The capture result key associated with the result value
+     * @param expectedValue The result value need to be waited for
+     * @param numResultsWait Number of frame to wait before times out
+     * @throws TimeoutRuntimeException If more than numResultsWait results are
+     * seen before the result matching myRequest arrives, or each individual wait
+     * for result times out after {@value #WAIT_FOR_RESULT_TIMEOUT_MS}ms.
+     */
+    protected static <T> void waitForResultValue(SimpleCaptureCallback listener,
+            CaptureResult.Key<T> resultKey,
+            T expectedValue, int numResultsWait) {
+        List<T> expectedValues = new ArrayList<T>();
+        expectedValues.add(expectedValue);
+        waitForAnyResultValue(listener, resultKey, expectedValues, numResultsWait);
+    }
+
+    /**
+     * Wait for any expected result key values available in a certain number of results.
+     *
+     * <p>
+     * Check the result immediately if numFramesWait is 0.
+     * </p>
+     *
+     * @param listener The capture listener to get capture result.
+     * @param resultKey The capture result key associated with the result value.
+     * @param expectedValues The list of result value need to be waited for,
+     * return immediately if the list is empty.
+     * @param numResultsWait Number of frame to wait before times out.
+     * @throws TimeoutRuntimeException If more than numResultsWait results are.
+     * seen before the result matching myRequest arrives, or each individual wait
+     * for result times out after {@value #WAIT_FOR_RESULT_TIMEOUT_MS}ms.
+     */
+    protected static <T> void waitForAnyResultValue(SimpleCaptureCallback listener,
+            CaptureResult.Key<T> resultKey,
+            List<T> expectedValues, int numResultsWait) {
+        if (numResultsWait < 0 || listener == null || expectedValues == null) {
+            throw new IllegalArgumentException(
+                    "Input must be non-negative number and listener/expectedValues "
+                    + "must be non-null");
+        }
+
+        int i = 0;
+        CaptureResult result;
+        do {
+            result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+            T value = result.get(resultKey);
+            for ( T expectedValue : expectedValues) {
+                if (VERBOSE) {
+                    Log.v(TAG, "Current result value for key " + resultKey.getName() + " is: "
+                            + value.toString());
+                }
+                if (value.equals(expectedValue)) {
+                    return;
+                }
+            }
+        } while (i++ < numResultsWait);
+
+        throw new TimeoutRuntimeException(
+                "Unable to get the expected result value " + expectedValues + " for key " +
+                        resultKey.getName() + " after waiting for " + numResultsWait + " results");
+    }
+
+    /**
+     * Submit a capture once, then submit additional captures in order to ensure that
+     * the camera will be synchronized.
+     *
+     * <p>
+     * The additional capture count is determined by android.sync.maxLatency (or
+     * a fixed {@value #NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY}) captures if maxLatency is unknown).
+     * </p>
+     *
+     * <p>Returns the number of captures that were submitted (at least 1), which is useful
+     * with {@link #waitForNumResults}.</p>
+     *
+     * @param request capture request to forward to {@link CameraDevice#capture}
+     * @param listener request listener to forward to {@link CameraDevice#capture}
+     * @param handler handler to forward to {@link CameraDevice#capture}
+     *
+     * @return the number of captures that were submitted
+     *
+     * @throws CameraAccessException if capturing failed
+     */
+    protected int captureRequestsSynchronized(
+            CaptureRequest request, CaptureCallback listener, Handler handler)
+                    throws CameraAccessException {
+        return captureRequestsSynchronized(request, /*count*/1, listener, handler);
+    }
+
+    /**
+     * Submit a capture {@code count} times, then submit additional captures in order to ensure that
+     * the camera will be synchronized.
+     *
+     * <p>
+     * The additional capture count is determined by android.sync.maxLatency (or
+     * a fixed {@value #NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY}) captures if maxLatency is unknown).
+     * </p>
+     *
+     * <p>Returns the number of captures that were submitted (at least 1), which is useful
+     * with {@link #waitForNumResults}.</p>
+     *
+     * @param request capture request to forward to {@link CameraDevice#capture}
+     * @param count the number of times to submit the request (minimally), must be at least 1
+     * @param listener request listener to forward to {@link CameraDevice#capture}
+     * @param handler handler to forward to {@link CameraDevice#capture}
+     *
+     * @return the number of captures that were submitted
+     *
+     * @throws IllegalArgumentException if {@code count} was not at least 1
+     * @throws CameraAccessException if capturing failed
+     */
+    protected int captureRequestsSynchronized(
+            CaptureRequest request, int count, CaptureCallback listener, Handler handler)
+                    throws CameraAccessException {
+        if (count < 1) {
+            throw new IllegalArgumentException("count must be positive");
+        }
+
+        int maxLatency = mStaticInfo.getSyncMaxLatency();
+        if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
+            maxLatency = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY;
+        }
+
+        assertTrue("maxLatency is non-negative", maxLatency >= 0);
+
+        int numCaptures = maxLatency + count;
+
+        for (int i = 0; i < numCaptures; ++i) {
+            mSession.capture(request, listener, handler);
+        }
+
+        return numCaptures;
+    }
+
+    /**
+     * Wait for numResultWait frames
+     *
+     * @param resultListener The capture listener to get capture result back.
+     * @param numResultsWait Number of frame to wait
+     *
+     * @return the last result, or {@code null} if there was none
+     */
+    protected static CaptureResult waitForNumResults(SimpleCaptureCallback resultListener,
+            int numResultsWait) {
+        if (numResultsWait < 0 || resultListener == null) {
+            throw new IllegalArgumentException(
+                    "Input must be positive number and listener must be non-null");
+        }
+
+        CaptureResult result = null;
+        for (int i = 0; i < numResultsWait; i++) {
+            result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
+        }
+
+        return result;
+    }
+
+    /**
+     * Wait for enough results for settings to be applied
+     *
+     * @param resultListener The capture listener to get capture result back.
+     * @param numResultWaitForUnknownLatency Number of frame to wait if camera device latency is
+     *                                       unknown.
+     */
+    protected void waitForSettingsApplied(SimpleCaptureCallback resultListener,
+            int numResultWaitForUnknownLatency) {
+        int maxLatency = mStaticInfo.getSyncMaxLatency();
+        if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
+            maxLatency = numResultWaitForUnknownLatency;
+        }
+        // Wait for settings to take effect
+        waitForNumResults(resultListener, maxLatency);
+    }
+
+
+    /**
+     * Wait for AE to be stabilized before capture: CONVERGED or FLASH_REQUIRED.
+     *
+     * <p>Waits for {@code android.sync.maxLatency} number of results first, to make sure
+     * that the result is synchronized (or {@code numResultWaitForUnknownLatency} if the latency
+     * is unknown.</p>
+     *
+     * <p>This is a no-op for {@code LEGACY} devices since they don't report
+     * the {@code aeState} result.</p>
+     *
+     * @param resultListener The capture listener to get capture result back.
+     * @param numResultWaitForUnknownLatency Number of frame to wait if camera device latency is
+     *                                       unknown.
+     */
+    protected void waitForAeStable(SimpleCaptureCallback resultListener,
+            int numResultWaitForUnknownLatency) {
+        waitForSettingsApplied(resultListener, numResultWaitForUnknownLatency);
+
+        if (!mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            // No-op for metadata
+            return;
+        }
+        List<Integer> expectedAeStates = new ArrayList<Integer>();
+        expectedAeStates.add(new Integer(CaptureResult.CONTROL_AE_STATE_CONVERGED));
+        expectedAeStates.add(new Integer(CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED));
+        waitForAnyResultValue(resultListener, CaptureResult.CONTROL_AE_STATE, expectedAeStates,
+                NUM_RESULTS_WAIT_TIMEOUT);
+    }
+
+    /**
+     * Wait for AE to be: LOCKED
+     *
+     * <p>Waits for {@code android.sync.maxLatency} number of results first, to make sure
+     * that the result is synchronized (or {@code numResultWaitForUnknownLatency} if the latency
+     * is unknown.</p>
+     *
+     * <p>This is a no-op for {@code LEGACY} devices since they don't report
+     * the {@code aeState} result.</p>
+     *
+     * @param resultListener The capture listener to get capture result back.
+     * @param numResultWaitForUnknownLatency Number of frame to wait if camera device latency is
+     *                                       unknown.
+     */
+    protected void waitForAeLocked(SimpleCaptureCallback resultListener,
+            int numResultWaitForUnknownLatency) {
+
+        waitForSettingsApplied(resultListener, numResultWaitForUnknownLatency);
+
+        if (!mStaticInfo.isHardwareLevelLimitedOrBetter()) {
+            // No-op for legacy devices
+            return;
+        }
+
+        List<Integer> expectedAeStates = new ArrayList<Integer>();
+        expectedAeStates.add(new Integer(CaptureResult.CONTROL_AE_STATE_LOCKED));
+        waitForAnyResultValue(resultListener, CaptureResult.CONTROL_AE_STATE, expectedAeStates,
+                NUM_RESULTS_WAIT_TIMEOUT);
+    }
+
+    /**
+     * Create an {@link ImageReader} object and get the surface.
+     *
+     * @param size The size of this ImageReader to be created.
+     * @param format The format of this ImageReader to be created
+     * @param maxNumImages The max number of images that can be acquired simultaneously.
+     * @param listener The listener used by this ImageReader to notify callbacks.
+     */
+    protected void createImageReader(Size size, int format, int maxNumImages,
+            ImageReader.OnImageAvailableListener listener) throws Exception {
+        closeImageReader();
+
+        ImageReader r = makeImageReader(size, format, maxNumImages, listener,
+                mHandler);
+        mReader = r;
+        mReaderSurface = r.getSurface();
+    }
+
+    /**
+     * Close the pending images then close current active {@link ImageReader} object.
+     */
+    protected void closeImageReader() {
+        CameraTestUtils.closeImageReader(mReader);
+        mReader = null;
+        mReaderSurface = null;
+    }
+
+    /**
+     * Open a camera device and get the StaticMetadata for a given camera id.
+     *
+     * @param cameraId The id of the camera device to be opened.
+     */
+    protected void openDevice(String cameraId) throws Exception {
+        mCamera = CameraTestUtils.openCamera(
+                mCameraManager, cameraId, mCameraListener, mHandler);
+        mCollector.setCameraId(cameraId);
+        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
+                CheckLevel.ASSERT, /*collector*/null);
+        if (mStaticInfo.isColorOutputSupported()) {
+            mOrderedPreviewSizes = getSupportedPreviewSizes(cameraId, mCameraManager,
+                    getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
+            mOrderedVideoSizes = getSupportedVideoSizes(cameraId, mCameraManager, PREVIEW_SIZE_BOUND);
+            mOrderedStillSizes = getSupportedStillSizes(cameraId, mCameraManager, null);
+            // Use ImageFormat.YUV_420_888 for now. TODO: need figure out what's format for preview
+            // in public API side.
+            mMinPreviewFrameDurationMap =
+                mStaticInfo.getAvailableMinFrameDurationsForFormatChecked(ImageFormat.YUV_420_888);
+        }
+    }
+
+    /**
+     * Close the current actively used camera device.
+     */
+    protected void closeDevice() {
+        if (mCamera != null) {
+            mCamera.close();
+            mCameraListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
+            mCamera = null;
+            mSession = null;
+            mSessionListener = null;
+            mStaticInfo = null;
+            mOrderedPreviewSizes = null;
+            mOrderedVideoSizes = null;
+            mOrderedStillSizes = null;
+        }
+    }
+
+    /**
+     * Update the preview surface size.
+     *
+     * @param size The preview size to be updated.
+     */
+    protected void updatePreviewSurface(Size size) {
+        if (size.equals(mPreviewSize) && mPreviewSurface != null) {
+            Log.w(TAG, "Skipping update preview surface size...");
+            return;
+        }
+
+        mPreviewSize = size;
+        Camera2SurfaceViewCtsActivity ctsActivity = getActivity();
+        final SurfaceHolder holder = ctsActivity.getSurfaceView().getHolder();
+        Handler handler = new Handler(Looper.getMainLooper());
+        handler.post(new Runnable() {
+            @Override
+            public void run() {
+                holder.setFixedSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
+            }
+        });
+
+        boolean res = ctsActivity.waitForSurfaceSizeChanged(
+                WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS, mPreviewSize.getWidth(),
+                mPreviewSize.getHeight());
+        assertTrue("wait for surface change to " + mPreviewSize.toString() + " timed out", res);
+        mPreviewSurface = holder.getSurface();
+        assertNotNull("Preview surface is null", mPreviewSurface);
+        assertTrue("Preview surface is invalid", mPreviewSurface.isValid());
+    }
+
+    /**
+     * Setup single capture configuration and start preview.
+     *
+     * @param previewRequest The capture request to be used for preview
+     * @param stillRequest The capture request to be used for still capture
+     * @param previewSz Preview size
+     * @param captureSz Still capture size
+     * @param format The single capture image format
+     * @param resultListener Capture result listener
+     * @param maxNumImages The max number of images set to the image reader
+     * @param imageListener The single capture capture image listener
+     */
+    protected void prepareCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
+            CaptureRequest.Builder stillRequest, Size previewSz, Size captureSz, int format,
+            CaptureCallback resultListener, int maxNumImages,
+            ImageReader.OnImageAvailableListener imageListener) throws Exception {
+        if (VERBOSE) {
+            Log.v(TAG, String.format("Prepare single capture (%s) and preview (%s)",
+                    captureSz.toString(), previewSz.toString()));
+        }
+
+        // Update preview size.
+        updatePreviewSurface(previewSz);
+
+        // Create ImageReader.
+        createImageReader(captureSz, format, maxNumImages, imageListener);
+
+        // Configure output streams with preview and jpeg streams.
+        List<Surface> outputSurfaces = new ArrayList<Surface>();
+        outputSurfaces.add(mPreviewSurface);
+        outputSurfaces.add(mReaderSurface);
+        mSessionListener = new BlockingSessionCallback();
+        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
+
+        // Configure the requests.
+        previewRequest.addTarget(mPreviewSurface);
+        stillRequest.addTarget(mPreviewSurface);
+        stillRequest.addTarget(mReaderSurface);
+
+        // Start preview.
+        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
+    }
+
+    /**
+     * Get the max preview size that supports the given fpsRange.
+     *
+     * @param fpsRange The fps range the returned size must support.
+     * @return max size that support the given fps range.
+     */
+    protected Size getMaxPreviewSizeForFpsRange(Range<Integer> fpsRange) {
+        if (fpsRange == null || fpsRange.getLower() <= 0 || fpsRange.getUpper() <= 0) {
+            throw new IllegalArgumentException("Invalid fps range argument");
+        }
+        if (mOrderedPreviewSizes == null || mMinPreviewFrameDurationMap == null) {
+            throw new IllegalStateException("mOrderedPreviewSizes and mMinPreviewFrameDurationMap"
+                    + " must be initialized");
+        }
+
+        long[] frameDurationRange =
+                new long[]{(long) (1e9 / fpsRange.getUpper()), (long) (1e9 / fpsRange.getLower())};
+        for (Size size : mOrderedPreviewSizes) {
+            Long minDuration = mMinPreviewFrameDurationMap.get(size);
+            if (minDuration == null ||
+                    minDuration == 0) {
+                if (mStaticInfo.isCapabilitySupported(
+                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
+                    throw new IllegalArgumentException(
+                            "No min frame duration available for the size " + size);
+                }
+                continue;
+            }
+            if (minDuration <= (frameDurationRange[0] + MIN_FRAME_DURATION_ERROR_MARGIN)) {
+                return size;
+            }
+        }
+
+        return null;
+    }
+
+    protected boolean isReprocessSupported(String cameraId, int format)
+            throws CameraAccessException {
+        if (format != ImageFormat.YUV_420_888 && format != ImageFormat.PRIVATE) {
+            throw new IllegalArgumentException(
+                    "format " + format + " is not supported for reprocessing");
+        }
+
+        StaticMetadata info =
+                new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
+                                   CheckLevel.ASSERT, /*collector*/ null);
+        int cap = CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING;
+        if (format == ImageFormat.PRIVATE) {
+            cap = CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_PRIVATE_REPROCESSING;
+        }
+        return info.isCapabilitySupported(cap);
+    }
+}
diff --git a/tests/camera/src/android/hardware/cts/CameraCtsActivity.java b/tests/camera/src/android/hardware/cts/CameraCtsActivity.java
new file mode 100644
index 0000000..61e283d
--- /dev/null
+++ b/tests/camera/src/android/hardware/cts/CameraCtsActivity.java
@@ -0,0 +1,48 @@
+/*
+ * 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.hardware.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.ViewGroup;
+import android.camera.cts.R;
+
+public class CameraCtsActivity extends Activity {
+    private SurfaceView mSurfaceView;
+    private final int LAYOUT_WIDTH = 480;
+    private final int LAYOUT_HEIGHT = 320;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.surface_view);
+        mSurfaceView = (SurfaceView)findViewById(R.id.surface_view);
+        ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
+        lp.width = LAYOUT_WIDTH;
+        lp.height = LAYOUT_HEIGHT;
+        mSurfaceView.setLayoutParams(lp);
+        mSurfaceView.getHolder().setFixedSize(LAYOUT_WIDTH, LAYOUT_HEIGHT);
+        mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+    }
+
+    public SurfaceView getSurfaceView() {
+        return mSurfaceView;
+    }
+}
diff --git a/tests/camera/src/android/hardware/cts/CameraGLTest.java b/tests/camera/src/android/hardware/cts/CameraGLTest.java
new file mode 100644
index 0000000..8b0756e
--- /dev/null
+++ b/tests/camera/src/android/hardware/cts/CameraGLTest.java
@@ -0,0 +1,906 @@
+/*
+ * 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.hardware.cts;
+
+import android.content.Context;
+import android.graphics.SurfaceTexture;
+import android.hardware.Camera;
+import android.hardware.Camera.Parameters;
+import android.hardware.Camera.Size;
+
+import android.opengl.GLES20;
+import android.opengl.GLSurfaceView;
+import android.opengl.Matrix;
+
+import android.os.ConditionVariable;
+import android.os.Environment;
+import android.os.Looper;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.MoreAsserts;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import com.android.cts.util.TimeoutReq;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+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.opengles.GL10;
+
+/**
+ * This test case must run with hardware. It can't be tested in emulator
+ */
+@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 boolean LOGV = false;
+    private static final boolean LOGVV = false;
+    private static final int EGL_OPENGL_ES2_BIT = 0x0004;
+
+    private boolean mSurfaceTextureCallbackResult = false;
+
+    private static final int WAIT_FOR_COMMAND_TO_COMPLETE = 5000;  // Milliseconds.
+    private static final int WAIT_FOR_FOCUS_TO_COMPLETE = 5000;
+    private static final int WAIT_FOR_SNAPSHOT_TO_COMPLETE = 5000;
+
+    private SurfaceTextureCallback mSurfaceTextureCallback = new SurfaceTextureCallback();
+    private SurfaceTextureBurstCallback mSurfaceTextureBurstCallback = new SurfaceTextureBurstCallback();
+    private PreviewCallback mPreviewCallback = new PreviewCallback();
+
+    private Looper mLooper = null;
+    private final ConditionVariable mSurfaceTextureDone = new ConditionVariable();
+    private final ConditionVariable mPreviewDone = new ConditionVariable();
+
+    Camera mCamera;
+    SurfaceTexture mSurfaceTexture;
+    private final Object mSurfaceTextureSyncLock = new Object();
+    Renderer mRenderer;
+    GLSurfaceView mGLView;
+
+    public CameraGLTest() {
+        super(PACKAGE, GLSurfaceViewCtsActivity.class);
+        if (LOGV) Log.v(TAG, "CameraGLTest Constructor");
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // Set up renderer instance
+        mRenderer = this.new Renderer();
+        GLSurfaceViewCtsActivity.setRenderer(mRenderer);
+        GLSurfaceViewCtsActivity.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+        GLSurfaceViewCtsActivity.setGlVersion(2);
+        // Start CameraCtsActivity.
+        GLSurfaceViewCtsActivity ctsActivity = getActivity();
+        // Store a link to the view so we can redraw it when needed
+        mGLView = ctsActivity.getView();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mCamera != null) {
+            terminateMessageLooper();
+        }
+        // Clean up static values in cts so it can be reused
+        GLSurfaceViewCtsActivity.resetRenderMode();
+        GLSurfaceViewCtsActivity.resetRenderer();
+        GLSurfaceViewCtsActivity.resetGlVersion();
+
+        super.tearDown();
+    }
+
+    /**
+     * Initializes the message looper so that the Camera object can
+     * receive the callback messages.
+     */
+    private void initializeMessageLooper(final int cameraId) {
+        final ConditionVariable startDone = new ConditionVariable();
+        new Thread() {
+            @Override
+            public void run() {
+                Log.v(TAG, "Start camera/surfacetexture thread");
+                // Set up a looper to be used by camera.
+                Looper.prepare();
+                // Save the looper so that we can terminate this thread
+                // after we are done with it.
+                mLooper = Looper.myLooper();
+                // These must be instantiated outside the UI thread, since the
+                // UI thread will be doing a lot of waiting, stopping callbacks.
+                mCamera = Camera.open(cameraId);
+                mSurfaceTexture = new SurfaceTexture(mRenderer.getTextureID());
+                Log.v(TAG, "Camera " + cameraId + " is opened.");
+                startDone.open();
+                Looper.loop(); // Blocks forever until Looper.quit() is called.
+                Log.v(TAG, "Stop camera/surfacetexture thread");
+            }
+        }.start();
+
+        Log.v(TAG, "start waiting for looper");
+        if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
+            fail("initializeMessageLooper: start timeout");
+        }
+    }
+
+    /**
+     * Terminates the message looper thread.
+     */
+    private void terminateMessageLooper() throws Exception {
+        if (LOGV) Log.v(TAG, "Shutting down camera");
+        mCamera.release();
+        mLooper.quit();
+        // Looper.quit() is asynchronous. The looper may still has some
+        // preview callbacks in the queue after quit is called. The preview
+        // callback still uses the camera object (setHasPreviewCallback).
+        // After camera is released, RuntimeException will be thrown from
+        // the method. So we need to join the looper thread here.
+        mLooper.getThread().join();
+        mCamera = null;
+        synchronized(mSurfaceTextureSyncLock) {
+            mSurfaceTexture = null;
+        }
+        if (LOGV) Log.v(TAG, "Shutdown of camera complete.");
+    }
+
+    /** The camera preview callback. */
+    private final class PreviewCallback
+            implements android.hardware.Camera.PreviewCallback {
+        public void onPreviewFrame(byte [] data, Camera camera) {
+            if (LOGV) Log.v(TAG, "PreviewCallback");
+            assertNotNull(data);
+            Size size = camera.getParameters().getPreviewSize();
+            assertEquals(size.width * size.height * 3 / 2, data.length);
+            mPreviewDone.open();
+        }
+    }
+
+    /** A simple SurfaceTexture listener callback, meant to be used together with the camera preview
+     * callback */
+    private final class SurfaceTextureCallback
+            implements android.graphics.SurfaceTexture.OnFrameAvailableListener {
+        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+            if (LOGV) Log.v(TAG, "SurfaceTextureCallback");
+            mSurfaceTextureDone.open();
+            // Assumes preview is stopped elsewhere
+        }
+    }
+
+    /** A burst SurfaceTexture listener callback, used for multiple-frame capture */
+    private final class SurfaceTextureBurstCallback
+            implements android.graphics.SurfaceTexture.OnFrameAvailableListener {
+
+        public void setBurstCount(int burstCount) {
+            mBurstCount = burstCount;
+        }
+
+        public int getBurstCount() {
+            return mBurstCount;
+        }
+
+        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
+            if (LOGVV) Log.v(TAG, "SurfaceTextureBurstCallback, frame #" + mBurstCount);
+            mBurstCount--;
+            if (!mSurfaceTextureCallbackResult) {
+                if (mBurstCount <= 0) {
+                    if (LOGV) Log.v(TAG, "SurfaceTextureBurstCallback stopping preview.");
+                    mCamera.stopPreview();
+                    if (LOGVV) Log.v(TAG, "SurfaceTextureBurstCallback preview stopped.");
+                    mSurfaceTextureCallbackResult = true;
+                }
+                mSurfaceTextureDone.open();
+            }
+        }
+
+        private int mBurstCount = 0;
+    }
+
+    /** Waits until surface texture callbacks have fired */
+    private boolean waitForSurfaceTextureDone() {
+        if (LOGVV) Log.v(TAG, "Wait for surface texture callback");
+        if (!mSurfaceTextureDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
+            // timeout could be expected or unexpected. The caller will decide.
+            Log.v(TAG, "waitForSurfaceTextureDone: timeout");
+            return false;
+        }
+        mSurfaceTextureDone.close();
+        return true;
+    }
+
+    /** Waits until the camera preview callback has fired */
+    private boolean waitForPreviewDone() {
+        if (LOGVV) Log.v(TAG, "Wait for preview callback");
+        if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
+            // timeout could be expected or unexpected. The caller will decide.
+            Log.v(TAG, "waitForPreviewDone: timeout");
+            return false;
+        }
+        mPreviewDone.close();
+        return true;
+    }
+
+    /** @return OpenGL ES major version 1 or 2 or some negative number for error */
+    private static int getDetectedVersion() {
+        /*
+         * Get all the device configurations and check if any of the attributes specify the
+         * the EGL_OPENGL_ES2_BIT to determine whether the device supports 2.0.
+         */
+        EGL10 egl = (EGL10) EGLContext.getEGL();
+        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
+        int[] numConfigs = new int[1];
+
+        if (egl.eglInitialize(display, null)) {
+            try {
+                if (egl.eglGetConfigs(display, null, 0, numConfigs)) {
+                    EGLConfig[] configs = new EGLConfig[numConfigs[0]];
+                    if (egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
+                        int[] value = new int[1];
+                        for (int i = 0; i < numConfigs[0]; i++) {
+                            if (egl.eglGetConfigAttrib(display, configs[i],
+                                    EGL10.EGL_RENDERABLE_TYPE, value)) {
+                                if ((value[0] & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT) {
+                                    return 2;
+                                }
+                            } else {
+                                Log.w(TAG, "Getting config attribute with "
+                                        + "EGL10#eglGetConfigAttrib failed "
+                                        + "(" + i + "/" + numConfigs[0] + "): "
+                                        + egl.eglGetError());
+                            }
+                        }
+                        return 1;
+                    } else {
+                        Log.e(TAG, "Getting configs with EGL10#eglGetConfigs failed: "
+                                + egl.eglGetError());
+                        return -1;
+                    }
+                } else {
+                    Log.e(TAG, "Getting number of configs with EGL10#eglGetConfigs failed: "
+                            + egl.eglGetError());
+                    return -2;
+                }
+              } finally {
+                  egl.eglTerminate(display);
+              }
+        } else {
+            Log.e(TAG, "Couldn't initialize EGL.");
+            return -3;
+        }
+    }
+
+    /** Generic per-camera test interface */
+    private interface RunPerCamera {
+        void run(int cameraId) throws Exception;
+    }
+
+    /** Generic camera test runner, to minimize boilerplace duplication */
+    private void runForAllCameras(RunPerCamera test) throws Exception {
+        /* Currently OpenGL ES 2.0 is supported for this test, so just skip it
+           if only 1.0 is available. */
+        int glVersion = getDetectedVersion();
+        assertTrue(glVersion > 0);
+        if (glVersion != 2) {
+            Log.w(TAG, "Skipping test because OpenGL ES 2 is not supported");
+            return;
+        }
+
+        /* Make sure the screen stays on while testing - otherwise the OpenGL context may disappear */
+        PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
+        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "CameraGLTest");
+        wl.acquire();
+        try {
+            /* Run the requested test per camera */
+            int nCameras = Camera.getNumberOfCameras();
+            for (int id = 0; id < nCameras; id++) {
+                Log.v(TAG, "Camera id=" + id);
+                test.run(id);
+            }
+        } finally {
+            wl.release();
+            // If an assert failed, camera might still be active. Clean up before next test.
+            if (mCamera != null) {
+                terminateMessageLooper();
+            }
+        }
+    }
+
+    /** Test Camera.setPreviewTexture in conjunction with the standard Camera preview callback */
+    @UiThreadTest
+    public void testSetPreviewTexturePreviewCallback() throws Exception {
+        runForAllCameras(testSetPreviewTexturePreviewCallbackByCamera);
+    }
+
+    private RunPerCamera testSetPreviewTexturePreviewCallbackByCamera = new RunPerCamera() {
+        public void run(int cameraId) throws Exception {
+            boolean noTimeout;
+            // Check the order: startPreview->setPreviewTexture, with a PreviewCallback as well
+            mPreviewDone.close();
+            initializeMessageLooper(cameraId);
+            mCamera.setOneShotPreviewCallback(mPreviewCallback);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            noTimeout = waitForPreviewDone();
+            assertTrue("Timeout waiting for new preview callback!", noTimeout);
+            mCamera.stopPreview();
+            terminateMessageLooper();
+
+            // Check the order: setPreviewTexture->startPreview.
+            initializeMessageLooper(cameraId);
+            mCamera.setOneShotPreviewCallback(mPreviewCallback);
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            mCamera.startPreview();
+            noTimeout = waitForPreviewDone();
+            assertTrue("Timeout waiting for new preview callback!", noTimeout);
+            mCamera.stopPreview();
+
+            // Check the order: setting preview display to null->startPreview->
+            // setPreviewTexture.
+            mCamera.setOneShotPreviewCallback(mPreviewCallback);
+            mCamera.setPreviewTexture(null);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            noTimeout = waitForPreviewDone();
+            assertTrue("Timeout waiting for new preview callback!", noTimeout);
+            mCamera.stopPreview();
+            terminateMessageLooper();
+        }
+    };
+
+    /** Test Camera.setPreviewTexture in conjunction with both the standard Camera preview callback,
+        and the SurfaceTexture onFrameAvailable callback */
+    @UiThreadTest
+    public void testSetPreviewTextureBothCallbacks() throws Exception {
+        runForAllCameras(testSetPreviewTextureBothCallbacksByCamera);
+    }
+
+    private RunPerCamera testSetPreviewTextureBothCallbacksByCamera = new RunPerCamera() {
+        public void run(int cameraId) throws Exception {
+            boolean noTimeout;
+            // Check SurfaceTexture callback together with preview callback
+            // Check the order: setPreviewTexture->startPreview
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.setOneShotPreviewCallback(mPreviewCallback);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            mCamera.startPreview();
+
+            noTimeout = waitForSurfaceTextureDone();
+            assertTrue("Timeout waiting for new frame from SurfaceTexture!", noTimeout);
+            noTimeout = waitForPreviewDone();
+            assertTrue("Timeout waiting for new preview callback!",noTimeout);
+            mCamera.stopPreview();
+
+            mGLView.requestRender();
+            terminateMessageLooper();
+
+            // Check the order: startPreview->setPreviewTexture
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.setOneShotPreviewCallback(mPreviewCallback);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+
+            noTimeout = waitForSurfaceTextureDone();
+            assertTrue("Timeout waiting for new frame from SurfaceTexture!", noTimeout);
+            noTimeout = waitForPreviewDone();
+            assertTrue("Timeout waiting for new preview callback!", noTimeout);
+            mCamera.stopPreview();
+
+            mGLView.requestRender();
+
+            // Check the order: setting preview to null->startPreview->setPreviewTexture
+            mCamera.setOneShotPreviewCallback(mPreviewCallback);
+            mCamera.setPreviewTexture(null);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            noTimeout = waitForPreviewDone();
+            assertTrue(noTimeout);
+            mCamera.stopPreview();
+            terminateMessageLooper();
+        }
+    };
+
+    /** Test Camera.setPreviewTexture in conjunction with just the SurfaceTexture onFrameAvailable callback */
+    @UiThreadTest
+    public void testSetPreviewTextureTextureCallback() throws Exception {
+        runForAllCameras(testSetPreviewTextureTextureCallbackByCamera);
+    }
+
+    private RunPerCamera testSetPreviewTextureTextureCallbackByCamera = new RunPerCamera() {
+        public void run(int cameraId) throws Exception {
+            boolean noTimeout;
+            // Check that SurfaceTexture callbacks work with no standard
+            // preview callback
+            mSurfaceTextureCallbackResult = false;
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mSurfaceTextureBurstCallback.setBurstCount(1);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
+            mCamera.setPreviewTexture(mSurfaceTexture);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.startPreview();
+
+            noTimeout = waitForSurfaceTextureDone();
+            mGLView.requestRender();
+            assertTrue(noTimeout);
+
+            terminateMessageLooper();
+            assertTrue(mSurfaceTextureCallbackResult);
+
+            // Check that SurfaceTexture callbacks also work with
+            // startPreview->setPreviewTexture
+            mSurfaceTextureCallbackResult = false;
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mSurfaceTextureBurstCallback.setBurstCount(1);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+
+            noTimeout = waitForSurfaceTextureDone();
+            assertTrue(noTimeout);
+
+            terminateMessageLooper();
+            assertTrue(mSurfaceTextureCallbackResult);
+
+            // Check that SurfaceTexture callbacks also work with
+            // null->startPreview->setPreviewTexture
+            mSurfaceTextureCallbackResult = false;
+            mSurfaceTextureDone.close();
+            initializeMessageLooper(cameraId);
+            mSurfaceTextureBurstCallback.setBurstCount(1);
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
+            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+            mCamera.setPreviewTexture(null);
+            mCamera.startPreview();
+            mCamera.setPreviewTexture(mSurfaceTexture);
+
+            noTimeout = waitForSurfaceTextureDone();
+            assertTrue(noTimeout);
+
+            terminateMessageLooper();
+            assertTrue(mSurfaceTextureCallbackResult);
+        }
+    };
+
+    /** Test all preview sizes and framerates along with SurfaceTexture-provided metadata (texture
+     * transforms and timestamps).
+     * TODO: This should be made stricter once SurfaceTexture timestamps are generated by the drivers.
+     */
+    @UiThreadTest
+    @TimeoutReq(minutes = 30)
+    public void testCameraToSurfaceTextureMetadata() throws Exception {
+        runForAllCameras(testCameraToSurfaceTextureMetadataByCamera);
+    }
+
+    private RunPerCamera testCameraToSurfaceTextureMetadataByCamera = new RunPerCamera() {
+        public void run(int cameraId) throws Exception {
+            // Number of frames to test over
+            int kLoopCount = 100;
+            // Number of frames that can be out of bounds before calling this a failure
+            int kMaxOutOfBoundsFrames = kLoopCount / 25; // 4% of frames
+            // Ignore timestamp issues before this frame
+            int kFirstTestedFrame = 10;
+            // Slop in timestamp testing, needed because timestamps are not
+            // currently being set by driver-level code so are subject to
+            // user-space timing variability
+            float kTestSlopMargin = 20; // ms
+
+            boolean noTimeout;
+            initializeMessageLooper(cameraId);
+            Parameters parameters = mCamera.getParameters();
+
+            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
+            mCamera.setPreviewTexture(mSurfaceTexture);
+
+            for (Size size: parameters.getSupportedPreviewSizes()) {
+                for (int[] fps: parameters.getSupportedPreviewFpsRange()) {
+                    if (LOGV) {
+                        Log.v(TAG, "Testing camera #" + cameraId +
+                              ", preview size:" + size.width + "x" + size.height +
+                              ", frame rate range: [" +
+                              (fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.) + "," +
+                              (fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.) + "]");
+                    }
+                    parameters.setPreviewSize(size.width, size.height);
+                    parameters.setPreviewFpsRange(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
+                                                  fps[Parameters.PREVIEW_FPS_MAX_INDEX]);
+                    mCamera.setParameters(parameters);
+
+                    assertEquals(size, mCamera.getParameters().getPreviewSize());
+
+                    int[] actualFps = new int[2];
+                    mCamera.getParameters().getPreviewFpsRange(actualFps);
+                    assertEquals(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
+                                 actualFps[Parameters.PREVIEW_FPS_MIN_INDEX]);
+                    assertEquals(fps[Parameters.PREVIEW_FPS_MAX_INDEX],
+                                 actualFps[Parameters.PREVIEW_FPS_MAX_INDEX]);
+
+                    mSurfaceTextureBurstCallback.
+                            setBurstCount(kLoopCount + kFirstTestedFrame);
+                    mSurfaceTextureCallbackResult = false;
+                    mSurfaceTextureDone.close();
+
+                    mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
+                    if (LOGV) Log.v(TAG, "Starting preview");
+                    mCamera.startPreview();
+                    if (LOGVV) Log.v(TAG, "Preview started");
+
+                    long[] timestamps = new long[kLoopCount];
+                    for (int i = 0; i < kLoopCount + kFirstTestedFrame; i++) {
+                        noTimeout = waitForSurfaceTextureDone();
+                        assertTrue("Timeout waiting for frame " + i +
+                                   " (burst callback thinks " +
+                                   (kLoopCount - mSurfaceTextureBurstCallback.getBurstCount()) +
+                                   ")! (Size " + size.width + "x" + size.height + ", fps [" +
+                                   (fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.) + ", " +
+                                   (fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.) + "])",
+                                   noTimeout);
+
+                        if (LOGVV) Log.v(TAG, "Frame #" + i + " completed");
+                        // Draw the frame (and update the SurfaceTexture)
+                        mGLView.requestRender();
+                        // Wait until frame is drawn, so that the SurfaceTexture has new
+                        // metadata
+                        noTimeout = mRenderer.waitForDrawDone();
+                        assertTrue(noTimeout);
+
+                        // Store timestamps for later
+                        if (i >= kFirstTestedFrame) {
+                            timestamps[i - kFirstTestedFrame] =
+                                    mSurfaceTexture.getTimestamp();
+                        }
+                        // Verify that the surfaceTexture transform has at least one non-zero
+                        // entry
+                        float[] transform = new float[16];
+                        mSurfaceTexture.getTransformMatrix(transform);
+                        boolean nonZero = false;
+                        for (int k = 0; k < 16; k++) {
+                            if (transform[k] != 0.f) {
+                                nonZero = true;
+                                break;
+                            }
+                        }
+                        assertTrue(nonZero);
+                    }
+                    assertTrue(mSurfaceTextureCallbackResult);
+
+                    float expectedMaxFrameDurationMs = 1000.f * 1000.f /
+                            fps[Parameters.PREVIEW_FPS_MIN_INDEX];
+                    float slopMaxFrameDurationMs = expectedMaxFrameDurationMs +
+                            kTestSlopMargin;
+                    float expectedMinFrameDurationMs = 1000.f * 1000.f /
+                            fps[Parameters.PREVIEW_FPS_MAX_INDEX];
+                    float slopMinFrameDurationMs = expectedMinFrameDurationMs  -
+                            kTestSlopMargin;
+
+                    int outOfBoundsCount = 0;
+                    for (int i = 1; i < kLoopCount; i++) {
+                        float frameDurationMs =
+                                (timestamps[i] - timestamps[i-1]) / 1000000.f;
+                        if (LOGVV) {
+                            Log.v(TAG, "Frame " + i + " duration: " + frameDurationMs +
+                                  " ms, expecting [" + expectedMinFrameDurationMs + "," +
+                                    expectedMaxFrameDurationMs + "], slop range [" +
+                                    slopMinFrameDurationMs + "," + slopMaxFrameDurationMs + "].");
+                        }
+                        if ( frameDurationMs > slopMaxFrameDurationMs ||
+                                frameDurationMs < slopMinFrameDurationMs ) {
+                            if (LOGVV) {
+                                Log.v(TAG, "  Out of bounds!!");
+                            }
+                            outOfBoundsCount++;
+                        }
+                    }
+                    assertTrue(
+                            "Too many frame intervals out of frame rate bounds: "
+                            + outOfBoundsCount +
+                            ", limit " + kMaxOutOfBoundsFrames,
+                            outOfBoundsCount <= kMaxOutOfBoundsFrames);
+                }
+            }
+            terminateMessageLooper();
+        } // void run(int cameraId)
+    };
+
+    /** Basic OpenGL ES 2.0 renderer to draw SurfaceTexture-sourced frames to the screen */
+    private class Renderer implements GLSurfaceView.Renderer {
+        public Renderer() {
+            mTriangleVertices =
+                    ByteBuffer.allocateDirect(mTriangleVerticesData.length * FLOAT_SIZE_BYTES).
+                    order(ByteOrder.nativeOrder()).asFloatBuffer();
+            mTriangleVertices.put(mTriangleVerticesData).position(0);
+
+            Matrix.setIdentityM(mSTMatrix, 0);
+            Matrix.setIdentityM(mMMatrix, 0);
+
+            mTextureID = 0;
+        }
+
+        public void setCameraSizing(Camera.Size previewSize) {
+            mCameraRatio = (float)previewSize.width/previewSize.height;
+        }
+
+        public boolean waitForDrawDone() {
+            if (!mDrawDone.block(WAIT_FOR_COMMAND_TO_COMPLETE) ) {
+                // timeout could be expected or unexpected. The caller will decide.
+                Log.e(TAG, "waitForDrawDone: timeout");
+                return false;
+            }
+            mDrawDone.close();
+            return true;
+        }
+
+        private final ConditionVariable mDrawDone = new ConditionVariable();
+
+        public void onDrawFrame(GL10 glUnused) {
+            if (LOGVV) Log.v(TAG, "onDrawFrame()");
+            synchronized(mSurfaceTextureSyncLock) {
+                if (CameraGLTest.this.mSurfaceTexture != null) {
+                    CameraGLTest.this.mSurfaceTexture.updateTexImage();
+                    CameraGLTest.this.mSurfaceTexture.getTransformMatrix(mSTMatrix);
+                    mDrawDone.open();
+                }
+            }
+
+            // Ignore the passed-in GL10 interface, and use the GLES20
+            // class's static methods instead.
+            GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
+            GLES20.glUseProgram(mProgram);
+            checkGlError("glUseProgram");
+
+            GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
+            GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
+
+            mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
+            GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
+                                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+            checkGlError("glVertexAttribPointer maPosition");
+            GLES20.glEnableVertexAttribArray(maPositionHandle);
+            checkGlError("glEnableVertexAttribArray maPositionHandle");
+
+            mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
+            GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false,
+                                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
+            checkGlError("glVertexAttribPointer maTextureHandle");
+            GLES20.glEnableVertexAttribArray(maTextureHandle);
+            checkGlError("glEnableVertexAttribArray maTextureHandle");
+
+            Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
+            Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
+
+            GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
+            GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
+            GLES20.glUniform1f(muCRatioHandle, mCameraRatio);
+
+            GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
+            checkGlError("glDrawArrays");
+        }
+
+        public void onSurfaceChanged(GL10 glUnused, int width, int height) {
+            if (LOGV) Log.v(TAG, "onSurfaceChanged()");
+            // Ignore the passed-in GL10 interface, and use the GLES20
+            // class's static methods instead.
+            GLES20.glViewport(0, 0, width, height);
+            mRatio = (float) width / height;
+            Matrix.frustumM(mProjMatrix, 0, -mRatio, mRatio, -1, 1, 3, 7);
+        }
+
+        public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
+            if (LOGV) Log.v(TAG, "onSurfaceCreated()");
+            // Ignore the passed-in GL10 interface, and use the GLES20
+            // class's static methods instead.
+
+            /* Set up shaders and handles to their variables */
+            mProgram = createProgram(mVertexShader, mFragmentShader);
+            if (mProgram == 0) {
+                return;
+            }
+            maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
+            checkGlError("glGetAttribLocation aPosition");
+            if (maPositionHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for aPosition");
+            }
+            maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
+            checkGlError("glGetAttribLocation aTextureCoord");
+            if (maTextureHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for aTextureCoord");
+            }
+
+            muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
+            checkGlError("glGetUniformLocation uMVPMatrix");
+            if (muMVPMatrixHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for uMVPMatrix");
+            }
+
+            muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
+            checkGlError("glGetUniformLocation uSTMatrix");
+            if (muMVPMatrixHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for uSTMatrix");
+            }
+
+            muCRatioHandle = GLES20.glGetUniformLocation(mProgram, "uCRatio");
+            checkGlError("glGetUniformLocation uCRatio");
+            if (muMVPMatrixHandle == -1) {
+                throw new RuntimeException("Could not get attrib location for uCRatio");
+            }
+
+            /*
+             * Create our texture. This has to be done each time the
+             * surface is created.
+             */
+
+            int[] textures = new int[1];
+            GLES20.glGenTextures(1, textures, 0);
+
+            mTextureID = textures[0];
+            GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
+            checkGlError("glBindTexture mTextureID");
+
+            // Can't do mipmapping with camera source
+            GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
+                                   GLES20.GL_NEAREST);
+            GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
+                                   GLES20.GL_LINEAR);
+            // Clamp to edge is the only option
+            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
+                                   GLES20.GL_CLAMP_TO_EDGE);
+            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
+                                   GLES20.GL_CLAMP_TO_EDGE);
+            checkGlError("glTexParameteri mTextureID");
+
+            Matrix.setLookAtM(mVMatrix, 0, 0, 0, 4f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
+        }
+
+        public int getTextureID() {
+            return mTextureID;
+        }
+
+        private int loadShader(int shaderType, String source) {
+            int shader = GLES20.glCreateShader(shaderType);
+            if (shader != 0) {
+                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) {
+                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 checkGlError(String op) {
+            int error;
+            while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
+                Log.e(TAG, op + ": glError " + error);
+                throw new RuntimeException(op + ": glError " + error);
+            }
+        }
+
+        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 final float[] mTriangleVerticesData = {
+            // 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 FloatBuffer mTriangleVertices;
+
+        private final String mVertexShader =
+                "uniform mat4 uMVPMatrix;\n" +
+                "uniform mat4 uSTMatrix;\n" +
+                "uniform float uCRatio;\n" +
+                "attribute vec4 aPosition;\n" +
+                "attribute vec4 aTextureCoord;\n" +
+                "varying vec2 vTextureCoord;\n" +
+                "void main() {\n" +
+                "  gl_Position = vec4(uCRatio,1,1,1) * uMVPMatrix * aPosition;\n" +
+                "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
+                "}\n";
+
+        private final String mFragmentShader =
+                "#extension GL_OES_EGL_image_external : require\n" +
+                "precision mediump float;\n" +
+                "varying vec2 vTextureCoord;\n" +
+                "uniform samplerExternalOES sTexture;\n" +
+                "void main() {\n" +
+                "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
+                "}\n";
+
+        private float[] mMVPMatrix = new float[16];
+        private float[] mProjMatrix = new float[16];
+        private float[] mMMatrix = new float[16];
+        private float[] mVMatrix = new float[16];
+        private float[] mSTMatrix = new float[16];
+
+        private int mProgram;
+        private int mTextureID;
+        private int muMVPMatrixHandle;
+        private int muSTMatrixHandle;
+        private int muCRatioHandle;
+        private int maPositionHandle;
+        private int maTextureHandle;
+
+        private float mRatio = 1.0f;
+        private float mCameraRatio = 1.0f;
+
+        private Context mContext;
+        private static final String TAG = "CameraGLTest.Renderer";
+
+        // Magic key
+        private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
+    }
+
+}
diff --git a/tests/camera/src/android/hardware/cts/CameraTest.java b/tests/camera/src/android/hardware/cts/CameraTest.java
new file mode 100644
index 0000000..6869ed1
--- /dev/null
+++ b/tests/camera/src/android/hardware/cts/CameraTest.java
@@ -0,0 +1,3185 @@
+/*
+ * 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.hardware.cts;
+
+import android.content.pm.PackageManager;
+import android.graphics.BitmapFactory;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.hardware.Camera;
+import android.hardware.Camera.Area;
+import android.hardware.Camera.CameraInfo;
+import android.hardware.Camera.ErrorCallback;
+import android.hardware.Camera.Face;
+import android.hardware.Camera.FaceDetectionListener;
+import android.hardware.Camera.Parameters;
+import android.hardware.Camera.PictureCallback;
+import android.hardware.Camera.ShutterCallback;
+import android.hardware.Camera.Size;
+import android.media.CamcorderProfile;
+import android.media.ExifInterface;
+import android.media.MediaRecorder;
+import android.os.Build;
+import android.os.ConditionVariable;
+import android.os.Environment;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.MoreAsserts;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+import android.view.SurfaceHolder;
+
+import com.android.cts.util.TimeoutReq;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TimeZone;
+
+import junit.framework.AssertionFailedError;
+
+/**
+ * This test case must run with hardware. It can't be tested in emulator
+ */
+@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 boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
+    private final String JPEG_PATH = Environment.getExternalStorageDirectory().getPath() +
+            "/test.jpg";
+    private byte[] mJpegData;
+
+    private static final int PREVIEW_CALLBACK_NOT_RECEIVED = 0;
+    private static final int PREVIEW_CALLBACK_RECEIVED = 1;
+    private static final int PREVIEW_CALLBACK_DATA_NULL = 2;
+    private static final int PREVIEW_CALLBACK_INVALID_FRAME_SIZE = 3;
+    private int mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
+
+    private boolean mShutterCallbackResult = false;
+    private boolean mRawPictureCallbackResult = false;
+    private boolean mJpegPictureCallbackResult = false;
+    private static final int NO_ERROR = -1;
+    private int mCameraErrorCode = NO_ERROR;
+    private boolean mAutoFocusSucceeded = false;
+
+    private static final int WAIT_FOR_COMMAND_TO_COMPLETE = 5000;  // Milliseconds.
+    private static final int WAIT_FOR_FOCUS_TO_COMPLETE = 5000;
+    private static final int WAIT_FOR_SNAPSHOT_TO_COMPLETE = 5000;
+
+    private static final int FOCUS_AREA = 0;
+    private static final int METERING_AREA = 1;
+
+    private static final int AUTOEXPOSURE_LOCK = 0;
+    private static final int AUTOWHITEBALANCE_LOCK = 1;
+
+    // Some exif tags that are not defined by ExifInterface but supported.
+    private static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
+    private static final String TAG_SUBSEC_TIME = "SubSecTime";
+    private static final String TAG_SUBSEC_TIME_ORIG = "SubSecTimeOriginal";
+    private static final String TAG_SUBSEC_TIME_DIG = "SubSecTimeDigitized";
+
+
+    private PreviewCallback mPreviewCallback = new PreviewCallback();
+    private TestShutterCallback mShutterCallback = new TestShutterCallback();
+    private RawPictureCallback mRawPictureCallback = new RawPictureCallback();
+    private JpegPictureCallback mJpegPictureCallback = new JpegPictureCallback();
+    private TestErrorCallback mErrorCallback = new TestErrorCallback();
+    private AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback();
+    private AutoFocusMoveCallback mAutoFocusMoveCallback = new AutoFocusMoveCallback();
+
+    private Looper mLooper = null;
+    private final ConditionVariable mPreviewDone = new ConditionVariable();
+    private final ConditionVariable mFocusDone = new ConditionVariable();
+    private final ConditionVariable mSnapshotDone = new ConditionVariable();
+
+    Camera mCamera;
+
+    public CameraTest() {
+        super(PACKAGE, CameraCtsActivity.class);
+        if (VERBOSE) Log.v(TAG, "Camera Constructor");
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        // to starCtsActivity.
+        getActivity();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mCamera != null) {
+            mCamera.release();
+            mCamera = null;
+        }
+        super.tearDown();
+    }
+
+    /*
+     * Initializes the message looper so that the Camera object can
+     * receive the callback messages.
+     */
+    private void initializeMessageLooper(final int cameraId) throws IOException {
+        final ConditionVariable startDone = new ConditionVariable();
+        new Thread() {
+            @Override
+            public void run() {
+                Log.v(TAG, "start loopRun");
+                // Set up a looper to be used by camera.
+                Looper.prepare();
+                // Save the looper so that we can terminate this thread
+                // after we are done with it.
+                mLooper = Looper.myLooper();
+                try {
+                    mCamera = Camera.open(cameraId);
+                    mCamera.setErrorCallback(mErrorCallback);
+                } catch (RuntimeException e) {
+                    Log.e(TAG, "Fail to open camera." + e);
+                }
+                Log.v(TAG, "camera is opened");
+                startDone.open();
+                Looper.loop(); // Blocks forever until Looper.quit() is called.
+                if (VERBOSE) Log.v(TAG, "initializeMessageLooper: quit.");
+            }
+        }.start();
+
+        Log.v(TAG, "start waiting for looper");
+        if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
+            Log.v(TAG, "initializeMessageLooper: start timeout");
+            fail("initializeMessageLooper: start timeout");
+        }
+        assertNotNull("Fail to open camera.", mCamera);
+        mCamera.setPreviewDisplay(getActivity().getSurfaceView().getHolder());
+    }
+
+    /*
+     * Terminates the message looper thread.
+     */
+    private void terminateMessageLooper() throws Exception {
+        mLooper.quit();
+        // Looper.quit() is asynchronous. The looper may still has some
+        // preview callbacks in the queue after quit is called. The preview
+        // callback still uses the camera object (setHasPreviewCallback).
+        // After camera is released, RuntimeException will be thrown from
+        // the method. So we need to join the looper thread here.
+        mLooper.getThread().join();
+        mCamera.release();
+        mCamera = null;
+        assertEquals("Got camera error callback.", NO_ERROR, mCameraErrorCode);
+    }
+
+    // Align 'x' to 'to', which should be a power of 2
+    private static int align(int x, int to) {
+        return (x + (to-1)) & ~(to - 1);
+    }
+    private static int calculateBufferSize(int width, int height,
+                                           int format, int bpp) {
+
+        if (VERBOSE) {
+            Log.v(TAG, "calculateBufferSize: w=" + width + ",h=" + height
+            + ",f=" + format + ",bpp=" + bpp);
+        }
+
+        if (format == ImageFormat.YV12) {
+            /*
+            http://developer.android.com/reference/android/graphics/ImageFormat.html#YV12
+            */
+
+            int stride = align(width, 16);
+
+            int y_size = stride * height;
+            int c_stride = align(stride/2, 16);
+            int c_size = c_stride * height/2;
+            int size = y_size + c_size * 2;
+
+            if (VERBOSE) {
+                Log.v(TAG, "calculateBufferSize: YV12 size= " + size);
+            }
+
+            return size;
+
+        }
+        else {
+            return width * height * bpp / 8;
+        }
+    }
+
+    //Implement the previewCallback
+    private final class PreviewCallback
+            implements android.hardware.Camera.PreviewCallback {
+        public void onPreviewFrame(byte [] data, Camera camera) {
+            if (data == null) {
+                mPreviewCallbackResult = PREVIEW_CALLBACK_DATA_NULL;
+                mPreviewDone.open();
+                return;
+            }
+            Size size = camera.getParameters().getPreviewSize();
+            int format = camera.getParameters().getPreviewFormat();
+            int bitsPerPixel = ImageFormat.getBitsPerPixel(format);
+            if (calculateBufferSize(size.width, size.height,
+                    format, bitsPerPixel) != data.length) {
+                Log.e(TAG, "Invalid frame size " + data.length + ". width=" + size.width
+                        + ". height=" + size.height + ". bitsPerPixel=" + bitsPerPixel);
+                mPreviewCallbackResult = PREVIEW_CALLBACK_INVALID_FRAME_SIZE;
+                mPreviewDone.open();
+                return;
+            }
+            mPreviewCallbackResult = PREVIEW_CALLBACK_RECEIVED;
+            mCamera.stopPreview();
+            if (VERBOSE) Log.v(TAG, "notify the preview callback");
+            mPreviewDone.open();
+            if (VERBOSE) Log.v(TAG, "Preview callback stop");
+        }
+    }
+
+    //Implement the shutterCallback
+    private final class TestShutterCallback implements ShutterCallback {
+        public void onShutter() {
+            mShutterCallbackResult = true;
+            if (VERBOSE) Log.v(TAG, "onShutter called");
+        }
+    }
+
+    //Implement the RawPictureCallback
+    private final class RawPictureCallback implements PictureCallback {
+        public void onPictureTaken(byte [] rawData, Camera camera) {
+            mRawPictureCallbackResult = true;
+            if (VERBOSE) Log.v(TAG, "RawPictureCallback callback");
+        }
+    }
+
+    // Implement the JpegPictureCallback
+    private final class JpegPictureCallback implements PictureCallback {
+        public void onPictureTaken(byte[] rawData, Camera camera) {
+            try {
+                mJpegData = rawData;
+                if (rawData != null) {
+                    // try to store the picture on the SD card
+                    File rawoutput = new File(JPEG_PATH);
+                    FileOutputStream outStream = new FileOutputStream(rawoutput);
+                    outStream.write(rawData);
+                    outStream.close();
+                    mJpegPictureCallbackResult = true;
+
+                    if (VERBOSE) {
+                        Log.v(TAG, "JpegPictureCallback rawDataLength = " + rawData.length);
+                    }
+                } else {
+                    mJpegPictureCallbackResult = false;
+                }
+                mSnapshotDone.open();
+                if (VERBOSE) Log.v(TAG, "Jpeg Picture callback");
+            } catch (IOException e) {
+                // no need to fail here; callback worked fine
+                Log.w(TAG, "Error writing picture to sd card.");
+            }
+        }
+    }
+
+    // Implement the ErrorCallback
+    private final class TestErrorCallback implements ErrorCallback {
+        public void onError(int error, Camera camera) {
+            Log.e(TAG, "Got camera error=" + error);
+            mCameraErrorCode = error;
+        }
+    }
+
+    private final class AutoFocusCallback
+            implements android.hardware.Camera.AutoFocusCallback {
+        public void onAutoFocus(boolean success, Camera camera) {
+            mAutoFocusSucceeded = success;
+            Log.v(TAG, "AutoFocusCallback success=" + success);
+            mFocusDone.open();
+        }
+    }
+
+    private final class AutoFocusMoveCallback
+            implements android.hardware.Camera.AutoFocusMoveCallback {
+        @Override
+        public void onAutoFocusMoving(boolean start, Camera camera) {
+        }
+    }
+
+    private void waitForPreviewDone() {
+        if (VERBOSE) Log.v(TAG, "Wait for preview callback");
+        if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
+            // timeout could be expected or unexpected. The caller will decide.
+            Log.v(TAG, "waitForPreviewDone: timeout");
+        }
+        mPreviewDone.close();
+    }
+
+    private boolean waitForFocusDone() {
+        boolean result = mFocusDone.block(WAIT_FOR_FOCUS_TO_COMPLETE);
+        if (!result) {
+            // timeout could be expected or unexpected. The caller will decide.
+            Log.v(TAG, "waitForFocusDone: timeout");
+        }
+        mFocusDone.close();
+        return result;
+    }
+
+    private void waitForSnapshotDone() {
+        if (!mSnapshotDone.block(WAIT_FOR_SNAPSHOT_TO_COMPLETE)) {
+            // timeout could be expected or unexpected. The caller will decide.
+            Log.v(TAG, "waitForSnapshotDone: timeout");
+        }
+        mSnapshotDone.close();
+    }
+
+    private void checkPreviewCallback() throws Exception {
+        if (VERBOSE) Log.v(TAG, "check preview callback");
+        mCamera.startPreview();
+        waitForPreviewDone();
+        mCamera.setPreviewCallback(null);
+    }
+
+    /**
+     * Start preview and wait for the first preview callback, which indicates the
+     * preview becomes active.
+     */
+    private void blockingStartPreview() {
+        mCamera.setPreviewCallback(new SimplePreviewStreamCb(/*Id*/0));
+        mCamera.startPreview();
+        waitForPreviewDone();
+        mCamera.setPreviewCallback(null);
+    }
+
+    /*
+     * Test case 1: Take a picture and verify all the callback
+     * functions are called properly.
+     */
+    @UiThreadTest
+    public void testTakePicture() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            initializeMessageLooper(id);
+            mCamera.startPreview();
+            subtestTakePictureByCamera(false, 0, 0);
+            terminateMessageLooper();
+        }
+    }
+
+    private void subtestTakePictureByCamera(boolean isVideoSnapshot,
+            int videoWidth, int videoHeight) throws Exception {
+        int videoSnapshotMinArea =
+                videoWidth * videoHeight; // Temporary until new API definitions
+
+        Size pictureSize = mCamera.getParameters().getPictureSize();
+        mCamera.autoFocus(mAutoFocusCallback);
+        assertTrue(waitForFocusDone());
+        mJpegData = null;
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+        waitForSnapshotDone();
+        assertTrue("Shutter callback not received", mShutterCallbackResult);
+        assertTrue("Raw picture callback not received", mRawPictureCallbackResult);
+        assertTrue("Jpeg picture callback not recieved", mJpegPictureCallbackResult);
+        assertNotNull(mJpegData);
+        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
+        bmpOptions.inJustDecodeBounds = true;
+        BitmapFactory.decodeByteArray(mJpegData, 0, mJpegData.length, bmpOptions);
+        if (!isVideoSnapshot) {
+            assertEquals(pictureSize.width, bmpOptions.outWidth);
+            assertEquals(pictureSize.height, bmpOptions.outHeight);
+        } else {
+            int realArea = bmpOptions.outWidth * bmpOptions.outHeight;
+            if (VERBOSE) Log.v(TAG, "Video snapshot is " +
+                    bmpOptions.outWidth + " x " + bmpOptions.outHeight +
+                    ", video size is " + videoWidth + " x " + videoHeight);
+            assertTrue ("Video snapshot too small! Expected at least " +
+                    videoWidth + " x " + videoHeight + " (" +
+                    videoSnapshotMinArea/1000000. + " MP)",
+                    realArea >= videoSnapshotMinArea);
+        }
+    }
+
+    @UiThreadTest
+    public void testPreviewCallback() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testPreviewCallbackByCamera(id);
+        }
+    }
+
+    private void testPreviewCallbackByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        mCamera.setPreviewCallback(mPreviewCallback);
+        checkPreviewCallback();
+        terminateMessageLooper();
+        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
+
+        mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
+        initializeMessageLooper(cameraId);
+        checkPreviewCallback();
+        terminateMessageLooper();
+        assertEquals(PREVIEW_CALLBACK_NOT_RECEIVED, mPreviewCallbackResult);
+
+        // Test all preview sizes.
+        initializeMessageLooper(cameraId);
+        Parameters parameters = mCamera.getParameters();
+        for (Size size: parameters.getSupportedPreviewSizes()) {
+            mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
+            mCamera.setPreviewCallback(mPreviewCallback);
+            parameters.setPreviewSize(size.width, size.height);
+            mCamera.setParameters(parameters);
+            assertEquals(size, mCamera.getParameters().getPreviewSize());
+            checkPreviewCallback();
+            assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
+            try {
+                // Wait for a while to throw away the remaining preview frames.
+                Thread.sleep(1000);
+            } catch(Exception e) {
+                // ignore
+            }
+            mPreviewDone.close();
+        }
+        terminateMessageLooper();
+    }
+
+    @UiThreadTest
+    public void testSetOneShotPreviewCallback() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testSetOneShotPreviewCallbackByCamera(id);
+        }
+    }
+
+    private void testSetOneShotPreviewCallbackByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        mCamera.setOneShotPreviewCallback(mPreviewCallback);
+        checkPreviewCallback();
+        terminateMessageLooper();
+        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
+
+        mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
+        initializeMessageLooper(cameraId);
+        checkPreviewCallback();
+        terminateMessageLooper();
+        assertEquals(PREVIEW_CALLBACK_NOT_RECEIVED, mPreviewCallbackResult);
+    }
+
+    @UiThreadTest
+    public void testSetPreviewDisplay() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testSetPreviewDisplayByCamera(id);
+        }
+    }
+
+    private void testSetPreviewDisplayByCamera(int cameraId) throws Exception {
+        SurfaceHolder holder = getActivity().getSurfaceView().getHolder();
+        initializeMessageLooper(cameraId);
+
+        // Check the order: startPreview->setPreviewDisplay.
+        mCamera.setOneShotPreviewCallback(mPreviewCallback);
+        mCamera.startPreview();
+        mCamera.setPreviewDisplay(holder);
+        waitForPreviewDone();
+        terminateMessageLooper();
+        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
+
+        // Check the order: setPreviewDisplay->startPreview.
+        initializeMessageLooper(cameraId);
+        mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
+        mCamera.setOneShotPreviewCallback(mPreviewCallback);
+        mCamera.setPreviewDisplay(holder);
+        mCamera.startPreview();
+        waitForPreviewDone();
+        mCamera.stopPreview();
+        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
+
+        // Check the order: setting preview display to null->startPreview->
+        // setPreviewDisplay.
+        mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
+        mCamera.setOneShotPreviewCallback(mPreviewCallback);
+        mCamera.setPreviewDisplay(null);
+        mCamera.startPreview();
+        mCamera.setPreviewDisplay(holder);
+        waitForPreviewDone();
+        terminateMessageLooper();
+        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
+    }
+
+    @UiThreadTest
+    public void testDisplayOrientation() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testDisplayOrientationByCamera(id);
+        }
+    }
+
+    private void testDisplayOrientationByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+
+        // Check valid arguments.
+        mCamera.setDisplayOrientation(0);
+        mCamera.setDisplayOrientation(90);
+        mCamera.setDisplayOrientation(180);
+        mCamera.setDisplayOrientation(270);
+
+        // Check invalid arguments.
+        try {
+            mCamera.setDisplayOrientation(45);
+            fail("Should throw exception for invalid arguments");
+        } catch (RuntimeException ex) {
+            // expected
+        }
+
+        // Start preview.
+        mCamera.startPreview();
+
+        // Check setting orientation during preview is allowed.
+        mCamera.setDisplayOrientation(90);
+        mCamera.setDisplayOrientation(180);
+        mCamera.setDisplayOrientation(270);
+        mCamera.setDisplayOrientation(00);
+
+        terminateMessageLooper();
+    }
+
+    @UiThreadTest
+    public void testParameters() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testParametersByCamera(id);
+        }
+    }
+
+    private void testParametersByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        // we can get parameters just by getxxx method due to the private constructor
+        Parameters pSet = mCamera.getParameters();
+        assertParameters(pSet);
+        terminateMessageLooper();
+    }
+
+    // Also test Camera.Parameters
+    private void assertParameters(Parameters parameters) {
+        // Parameters constants
+        final int PICTURE_FORMAT = ImageFormat.JPEG;
+        final int PREVIEW_FORMAT = ImageFormat.NV21;
+
+        // Before setting Parameters
+        final int origPictureFormat = parameters.getPictureFormat();
+        final int origPictureWidth = parameters.getPictureSize().width;
+        final int origPictureHeight = parameters.getPictureSize().height;
+        final int origPreviewFormat = parameters.getPreviewFormat();
+        final int origPreviewWidth = parameters.getPreviewSize().width;
+        final int origPreviewHeight = parameters.getPreviewSize().height;
+        final int origPreviewFrameRate = parameters.getPreviewFrameRate();
+
+        assertTrue(origPictureWidth > 0);
+        assertTrue(origPictureHeight > 0);
+        assertTrue(origPreviewWidth > 0);
+        assertTrue(origPreviewHeight > 0);
+        assertTrue(origPreviewFrameRate > 0);
+
+        // The default preview format must be yuv420 (NV21).
+        assertEquals(ImageFormat.NV21, origPreviewFormat);
+
+        // The default picture format must be Jpeg.
+        assertEquals(ImageFormat.JPEG, origPictureFormat);
+
+        // If camera supports flash, the default flash mode must be off.
+        String flashMode = parameters.getFlashMode();
+        assertTrue(flashMode == null || flashMode.equals(parameters.FLASH_MODE_OFF));
+        String wb = parameters.getWhiteBalance();
+        assertTrue(wb == null || wb.equals(parameters.WHITE_BALANCE_AUTO));
+        String effect = parameters.getColorEffect();
+        assertTrue(effect == null || effect.equals(parameters.EFFECT_NONE));
+
+        // Some parameters must be supported.
+        List<Size> previewSizes = parameters.getSupportedPreviewSizes();
+        List<Size> pictureSizes = parameters.getSupportedPictureSizes();
+        List<Integer> previewFormats = parameters.getSupportedPreviewFormats();
+        List<Integer> pictureFormats = parameters.getSupportedPictureFormats();
+        List<Integer> frameRates = parameters.getSupportedPreviewFrameRates();
+        List<String> focusModes = parameters.getSupportedFocusModes();
+        String focusMode = parameters.getFocusMode();
+        float focalLength = parameters.getFocalLength();
+        float horizontalViewAngle = parameters.getHorizontalViewAngle();
+        float verticalViewAngle = parameters.getVerticalViewAngle();
+        int jpegQuality = parameters.getJpegQuality();
+        int jpegThumnailQuality = parameters.getJpegThumbnailQuality();
+        assertTrue(previewSizes != null && previewSizes.size() != 0);
+        assertTrue(pictureSizes != null && pictureSizes.size() != 0);
+        assertTrue(previewFormats != null && previewFormats.size() >= 2);
+        assertTrue(previewFormats.contains(ImageFormat.NV21));
+        assertTrue(previewFormats.contains(ImageFormat.YV12));
+        assertTrue(pictureFormats != null && pictureFormats.size() != 0);
+        assertTrue(frameRates != null && frameRates.size() != 0);
+        assertTrue(focusModes != null && focusModes.size() != 0);
+        assertNotNull(focusMode);
+        // The default focus mode must be auto if it exists.
+        if (focusModes.contains(Parameters.FOCUS_MODE_AUTO)) {
+            assertEquals(Parameters.FOCUS_MODE_AUTO, focusMode);
+        }
+        assertTrue(focalLength > 0);
+        assertTrue(horizontalViewAngle > 0 && horizontalViewAngle <= 360);
+        assertTrue(verticalViewAngle > 0 && verticalViewAngle <= 360);
+        Size previewSize = previewSizes.get(0);
+        Size pictureSize = pictureSizes.get(0);
+        assertTrue(jpegQuality >= 1 && jpegQuality <= 100);
+        assertTrue(jpegThumnailQuality >= 1 && jpegThumnailQuality <= 100);
+
+        // If a parameter is supported, both getXXX and getSupportedXXX have to
+        // be non null.
+        if (parameters.getWhiteBalance() != null) {
+            assertNotNull(parameters.getSupportedWhiteBalance());
+        }
+        if (parameters.getSupportedWhiteBalance() != null) {
+            assertNotNull(parameters.getWhiteBalance());
+        }
+        if (parameters.getColorEffect() != null) {
+            assertNotNull(parameters.getSupportedColorEffects());
+        }
+        if (parameters.getSupportedColorEffects() != null) {
+            assertNotNull(parameters.getColorEffect());
+        }
+        if (parameters.getAntibanding() != null) {
+            assertNotNull(parameters.getSupportedAntibanding());
+        }
+        if (parameters.getSupportedAntibanding() != null) {
+            assertNotNull(parameters.getAntibanding());
+        }
+        if (parameters.getSceneMode() != null) {
+            assertNotNull(parameters.getSupportedSceneModes());
+        }
+        if (parameters.getSupportedSceneModes() != null) {
+            assertNotNull(parameters.getSceneMode());
+        }
+        if (parameters.getFlashMode() != null) {
+            assertNotNull(parameters.getSupportedFlashModes());
+        }
+        if (parameters.getSupportedFlashModes() != null) {
+            assertNotNull(parameters.getFlashMode());
+        }
+
+        // Check if the sizes value contain invalid characters.
+        assertNoLetters(parameters.get("preview-size-values"), "preview-size-values");
+        assertNoLetters(parameters.get("picture-size-values"), "picture-size-values");
+        assertNoLetters(parameters.get("jpeg-thumbnail-size-values"),
+                "jpeg-thumbnail-size-values");
+
+        // Set the parameters.
+        parameters.setPictureFormat(PICTURE_FORMAT);
+        assertEquals(PICTURE_FORMAT, parameters.getPictureFormat());
+        parameters.setPictureSize(pictureSize.width, pictureSize.height);
+        assertEquals(pictureSize.width, parameters.getPictureSize().width);
+        assertEquals(pictureSize.height, parameters.getPictureSize().height);
+        parameters.setPreviewFormat(PREVIEW_FORMAT);
+        assertEquals(PREVIEW_FORMAT, parameters.getPreviewFormat());
+        parameters.setPreviewFrameRate(frameRates.get(0));
+        assertEquals(frameRates.get(0).intValue(), parameters.getPreviewFrameRate());
+        parameters.setPreviewSize(previewSize.width, previewSize.height);
+        assertEquals(previewSize.width, parameters.getPreviewSize().width);
+        assertEquals(previewSize.height, parameters.getPreviewSize().height);
+
+        mCamera.setParameters(parameters);
+        Parameters paramActual = mCamera.getParameters();
+
+        assertTrue(isValidPixelFormat(paramActual.getPictureFormat()));
+        assertEquals(pictureSize.width, paramActual.getPictureSize().width);
+        assertEquals(pictureSize.height, paramActual.getPictureSize().height);
+        assertTrue(isValidPixelFormat(paramActual.getPreviewFormat()));
+        assertEquals(previewSize.width, paramActual.getPreviewSize().width);
+        assertEquals(previewSize.height, paramActual.getPreviewSize().height);
+        assertTrue(paramActual.getPreviewFrameRate() > 0);
+
+        checkExposureCompensation(parameters);
+        checkPreferredPreviewSizeForVideo(parameters);
+    }
+
+    private void checkPreferredPreviewSizeForVideo(Parameters parameters) {
+        List<Size> videoSizes = parameters.getSupportedVideoSizes();
+        Size preferredPreviewSize = parameters.getPreferredPreviewSizeForVideo();
+
+        // If getSupportedVideoSizes() returns null,
+        // getPreferredPreviewSizeForVideo() will return null;
+        // otherwise, if getSupportedVideoSizes() does not return null,
+        // getPreferredPreviewSizeForVideo() will not return null.
+        if (videoSizes == null) {
+            assertNull(preferredPreviewSize);
+        } else {
+            assertNotNull(preferredPreviewSize);
+        }
+
+        // If getPreferredPreviewSizeForVideo() returns null,
+        // getSupportedVideoSizes() will return null;
+        // otherwise, if getPreferredPreviewSizeForVideo() does not return null,
+        // getSupportedVideoSizes() will not return null.
+        if (preferredPreviewSize == null) {
+            assertNull(videoSizes);
+        } else {
+            assertNotNull(videoSizes);
+        }
+
+        if (videoSizes != null) {  // implies: preferredPreviewSize != null
+            // If getSupportedVideoSizes() does not return null,
+            // the returned list will contain at least one size.
+            assertTrue(videoSizes.size() > 0);
+
+            // In addition, getPreferredPreviewSizeForVideo() returns a size
+            // that is among the supported preview sizes.
+            List<Size> previewSizes = parameters.getSupportedPreviewSizes();
+            assertNotNull(previewSizes);
+            assertTrue(previewSizes.size() > 0);
+            assertTrue(previewSizes.contains(preferredPreviewSize));
+        }
+    }
+
+    private void checkExposureCompensation(Parameters parameters) {
+        assertEquals(0, parameters.getExposureCompensation());
+        int max = parameters.getMaxExposureCompensation();
+        int min = parameters.getMinExposureCompensation();
+        float step = parameters.getExposureCompensationStep();
+        if (max == 0 && min == 0) {
+            assertEquals(0f, step, 0.000001f);
+            return;
+        }
+        assertTrue(step > 0);
+        assertTrue(max >= 0);
+        assertTrue(min <= 0);
+    }
+
+    private boolean isValidPixelFormat(int format) {
+        return (format == ImageFormat.RGB_565) || (format == ImageFormat.NV21)
+                || (format == ImageFormat.JPEG) || (format == ImageFormat.YUY2);
+    }
+
+    @UiThreadTest
+    public void testJpegThumbnailSize() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            initializeMessageLooper(id);
+            testJpegThumbnailSizeByCamera(false, 0, 0);
+            terminateMessageLooper();
+        }
+    }
+
+    private void testJpegThumbnailSizeByCamera(boolean recording,
+            int recordingWidth, int recordingHeight) throws Exception {
+        // Thumbnail size parameters should have valid values.
+        Parameters p = mCamera.getParameters();
+        Size size = p.getJpegThumbnailSize();
+        assertTrue(size.width > 0 && size.height > 0);
+        List<Size> sizes = p.getSupportedJpegThumbnailSizes();
+        assertTrue(sizes.size() >= 2);
+        assertTrue(sizes.contains(size));
+        assertTrue(sizes.contains(mCamera.new Size(0, 0)));
+        Size pictureSize = p.getPictureSize();
+
+        // Test if the thumbnail size matches the setting.
+        if (!recording) mCamera.startPreview();
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+        waitForSnapshotDone();
+        assertTrue(mJpegPictureCallbackResult);
+        ExifInterface exif = new ExifInterface(JPEG_PATH);
+        assertTrue(exif.hasThumbnail());
+        byte[] thumb = exif.getThumbnail();
+        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
+        bmpOptions.inJustDecodeBounds = true;
+        BitmapFactory.decodeByteArray(thumb, 0, thumb.length, bmpOptions);
+        if (!recording) {
+            assertEquals(size.width, bmpOptions.outWidth);
+            assertEquals(size.height, bmpOptions.outHeight);
+        } else {
+            assertTrue(bmpOptions.outWidth >= recordingWidth ||
+                    bmpOptions.outWidth == size.width);
+            assertTrue(bmpOptions.outHeight >= recordingHeight ||
+                    bmpOptions.outHeight == size.height);
+        }
+
+        // Test no thumbnail case.
+        p.setJpegThumbnailSize(0, 0);
+        mCamera.setParameters(p);
+        Size actual = mCamera.getParameters().getJpegThumbnailSize();
+        assertEquals(0, actual.width);
+        assertEquals(0, actual.height);
+        if (!recording) mCamera.startPreview();
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+        waitForSnapshotDone();
+        assertTrue(mJpegPictureCallbackResult);
+        exif = new ExifInterface(JPEG_PATH);
+        assertFalse(exif.hasThumbnail());
+        // Primary image should still be valid for no thumbnail capture.
+        BitmapFactory.decodeFile(JPEG_PATH, bmpOptions);
+        if (!recording) {
+            assertTrue("Jpeg primary image size should match requested size",
+                    bmpOptions.outWidth == pictureSize.width &&
+                    bmpOptions.outHeight == pictureSize.height);
+        } else {
+            assertTrue(bmpOptions.outWidth >= recordingWidth ||
+                    bmpOptions.outWidth == size.width);
+            assertTrue(bmpOptions.outHeight >= recordingHeight ||
+                    bmpOptions.outHeight == size.height);
+        }
+
+        assertNotNull("Jpeg primary image data should be decodable",
+                BitmapFactory.decodeFile(JPEG_PATH));
+    }
+
+    @UiThreadTest
+    public void testJpegExif() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            initializeMessageLooper(id);
+            testJpegExifByCamera(false);
+            terminateMessageLooper();
+        }
+    }
+
+    private void testJpegExifByCamera(boolean recording) throws Exception {
+        if (!recording) mCamera.startPreview();
+        Date date = new Date(System.currentTimeMillis());
+        String localDatetime = new SimpleDateFormat("yyyy:MM:dd HH:").format(date);
+
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+        waitForSnapshotDone();
+
+        Camera.Parameters parameters = mCamera.getParameters();
+        double focalLength = parameters.getFocalLength();
+
+        // Test various exif tags.
+        ExifInterface exif = new ExifInterface(JPEG_PATH);
+        StringBuffer failedCause = new StringBuffer("Jpeg exif test failed:\n");
+        boolean extraExiftestPassed = checkExtraExifTagsSucceeds(failedCause, exif);
+
+        if (VERBOSE) Log.v(TAG, "Testing exif tag TAG_DATETIME");
+        String datetime = exif.getAttribute(ExifInterface.TAG_DATETIME);
+        assertNotNull(datetime);
+        // Datetime should be local time.
+        assertTrue(datetime.startsWith(localDatetime));
+        assertTrue(datetime.length() == 19); // EXIF spec is "YYYY:MM:DD HH:MM:SS".
+        checkGpsDataNull(exif);
+        double exifFocalLength = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, -1);
+        assertEquals(focalLength, exifFocalLength, 0.001);
+        // Test image width and height exif tags. They should match the jpeg.
+        assertBitmapAndJpegSizeEqual(mJpegData, exif);
+
+        // Test gps exif tags.
+        if (VERBOSE) Log.v(TAG, "Testing exif GPS tags");
+        testGpsExifValues(parameters, 37.736071, -122.441983, 21, 1199145600,
+            "GPS NETWORK HYBRID ARE ALL FINE.");
+        testGpsExifValues(parameters, 0.736071, 0.441983, 1, 1199145601, "GPS");
+        testGpsExifValues(parameters, -89.736071, -179.441983, 100000, 1199145602, "NETWORK");
+
+        // Test gps tags do not exist after calling removeGpsData. Also check if
+        // image width and height exif match the jpeg when jpeg rotation is set.
+        if (VERBOSE) Log.v(TAG, "Testing exif GPS tag removal");
+        if (!recording) mCamera.startPreview();
+        parameters.removeGpsData();
+        parameters.setRotation(90); // For testing image width and height exif.
+        mCamera.setParameters(parameters);
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+        waitForSnapshotDone();
+        exif = new ExifInterface(JPEG_PATH);
+        checkGpsDataNull(exif);
+        assertBitmapAndJpegSizeEqual(mJpegData, exif);
+        // Reset the rotation to prevent from affecting other tests.
+        parameters.setRotation(0);
+        mCamera.setParameters(parameters);
+    }
+
+    /**
+     * Sanity check of some extra exif tags.
+     * <p>
+     * Sanity check some extra exif tags without asserting the check failures
+     * immediately. When a failure is detected, the failure cause is logged,
+     * the rest of the tests are still executed. The caller can assert with the
+     * failure cause based on the returned test status.
+     * </p>
+     *
+     * @param logBuf Log failure cause to this StringBuffer if there is
+     * any failure.
+     * @param exif The exif data associated with a jpeg image being tested.
+     * @return true if no test failure is found, false if there is any failure.
+     */
+    private boolean checkExtraExifTagsSucceeds(StringBuffer logBuf, ExifInterface exif) {
+        if (logBuf == null || exif == null) {
+            throw new IllegalArgumentException("failureCause and exif shouldn't be null");
+        }
+
+        if (VERBOSE) Log.v(TAG, "Testing extra exif tags");
+        boolean allTestsPassed = true;
+        boolean passedSoFar = true;
+        String failureMsg;
+
+        // TAG_EXPOSURE_TIME
+        // ExifInterface API gives exposure time value in the form of float instead of rational
+        String exposureTime = exif.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
+        passedSoFar = expectNotNull("Exif TAG_EXPOSURE_TIME is null!", logBuf, exposureTime);
+        if (passedSoFar) {
+            double exposureTimeValue = Double.parseDouble(exposureTime);
+            failureMsg = "Exif exposure time " + exposureTime + " should be a positive value";
+            passedSoFar = expectTrue(failureMsg, logBuf, exposureTimeValue > 0);
+        }
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        // TAG_APERTURE
+        // ExifInterface API gives aperture value in the form of float instead of rational
+        String aperture = exif.getAttribute(ExifInterface.TAG_APERTURE);
+        passedSoFar = expectNotNull("Exif TAG_APERTURE is null!", logBuf, aperture);
+        if (passedSoFar) {
+            double apertureValue = Double.parseDouble(aperture);
+            passedSoFar = expectTrue("Exif TAG_APERTURE value " + aperture + " should be positive!",
+                    logBuf, apertureValue > 0);
+        }
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        // TAG_FLASH
+        String flash = exif.getAttribute(ExifInterface.TAG_FLASH);
+        passedSoFar = expectNotNull("Exif TAG_FLASH is null!", logBuf, flash);
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        // TAG_WHITE_BALANCE
+        String whiteBalance = exif.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
+        passedSoFar = expectNotNull("Exif TAG_WHITE_BALANCE is null!", logBuf, whiteBalance);
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        // TAG_MAKE
+        String make = exif.getAttribute(ExifInterface.TAG_MAKE);
+        passedSoFar = expectNotNull("Exif TAG_MAKE is null!", logBuf, make);
+        if (passedSoFar) {
+            passedSoFar = expectTrue("Exif TAG_MODEL value: " + make
+                    + " should match build manufacturer: " + Build.MANUFACTURER, logBuf,
+                    make.equals(Build.MANUFACTURER));
+        }
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        // TAG_MODEL
+        String model = exif.getAttribute(ExifInterface.TAG_MODEL);
+        passedSoFar = expectNotNull("Exif TAG_MODEL is null!", logBuf, model);
+        if (passedSoFar) {
+            passedSoFar = expectTrue("Exif TAG_MODEL value: " + model
+                    + " should match build manufacturer: " + Build.MODEL, logBuf,
+                    model.equals(Build.MODEL));
+        }
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        // TAG_ISO
+        int iso = exif.getAttributeInt(ExifInterface.TAG_ISO, -1);
+        passedSoFar = expectTrue("Exif ISO value " + iso + " is invalid", logBuf, iso > 0);
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        // TAG_DATETIME_DIGITIZED (a.k.a Create time for digital cameras).
+        String digitizedTime = exif.getAttribute(TAG_DATETIME_DIGITIZED);
+        passedSoFar = expectNotNull("Exif TAG_DATETIME_DIGITIZED is null!", logBuf, digitizedTime);
+        if (passedSoFar) {
+            String datetime = exif.getAttribute(ExifInterface.TAG_DATETIME);
+            passedSoFar = expectNotNull("Exif TAG_DATETIME is null!", logBuf, datetime);
+            if (passedSoFar) {
+                passedSoFar = expectTrue("dataTime should match digitizedTime", logBuf,
+                        digitizedTime.equals(datetime));
+            }
+        }
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        /**
+         * TAG_SUBSEC_TIME. Since the sub second tag strings are truncated to at
+         * most 9 digits in ExifInterface implementation, use getAttributeInt to
+         * sanitize it. When the default value -1 is returned, it means that
+         * this exif tag either doesn't exist or is a non-numerical invalid
+         * string. Same rule applies to the rest of sub second tags.
+         */
+        int subSecTime = exif.getAttributeInt(TAG_SUBSEC_TIME, -1);
+        passedSoFar = expectTrue(
+                "Exif TAG_SUBSEC_TIME value is null or invalid!", logBuf, subSecTime > 0);
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        // TAG_SUBSEC_TIME_ORIG
+        int subSecTimeOrig = exif.getAttributeInt(TAG_SUBSEC_TIME_ORIG, -1);
+        passedSoFar = expectTrue(
+                "Exif TAG_SUBSEC_TIME_ORIG value is null or invalid!", logBuf, subSecTimeOrig > 0);
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        // TAG_SUBSEC_TIME_DIG
+        int subSecTimeDig = exif.getAttributeInt(TAG_SUBSEC_TIME_DIG, -1);
+        passedSoFar = expectTrue(
+                "Exif TAG_SUBSEC_TIME_DIG value is null or invalid!", logBuf, subSecTimeDig > 0);
+        allTestsPassed = allTestsPassed && passedSoFar;
+
+        return allTestsPassed;
+    }
+
+    /**
+     * Check if object is null and log failure msg.
+     *
+     * @param msg Failure msg.
+     * @param logBuffer StringBuffer to log the failure msg.
+     * @param obj Object to test.
+     * @return true if object is not null, otherwise return false.
+     */
+    private boolean expectNotNull(String msg, StringBuffer logBuffer, Object obj)
+    {
+        if (obj == null) {
+            logBuffer.append(msg + "\n");
+        }
+        return (obj != null);
+    }
+
+    /**
+     * Check if condition is false and log failure msg.
+     *
+     * @param msg Failure msg.
+     * @param logBuffer StringBuffer to log the failure msg.
+     * @param condition Condition to test.
+     * @return The value of the condition.
+     */
+    private boolean expectTrue(String msg, StringBuffer logBuffer, boolean condition) {
+        if (!condition) {
+            logBuffer.append(msg + "\n");
+        }
+        return condition;
+    }
+
+    private void assertBitmapAndJpegSizeEqual(byte[] jpegData, ExifInterface exif) {
+        int exifWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
+        int exifHeight = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
+        assertTrue(exifWidth != 0 && exifHeight != 0);
+        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
+        bmpOptions.inJustDecodeBounds = true;
+        BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length, bmpOptions);
+        assertEquals(bmpOptions.outWidth, exifWidth);
+        assertEquals(bmpOptions.outHeight, exifHeight);
+    }
+
+    private void testGpsExifValues(Parameters parameters, double latitude,
+            double longitude, double altitude, long timestamp, String method)
+            throws IOException {
+        mCamera.startPreview();
+        parameters.setGpsLatitude(latitude);
+        parameters.setGpsLongitude(longitude);
+        parameters.setGpsAltitude(altitude);
+        parameters.setGpsTimestamp(timestamp);
+        parameters.setGpsProcessingMethod(method);
+        mCamera.setParameters(parameters);
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+        waitForSnapshotDone();
+        ExifInterface exif = new ExifInterface(JPEG_PATH);
+        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
+        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
+        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF));
+        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF));
+        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP));
+        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_DATESTAMP));
+        assertEquals(method, exif.getAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD));
+        float[] latLong = new float[2];
+        assertTrue(exif.getLatLong(latLong));
+        assertEquals((float)latitude, latLong[0], 0.0001f);
+        assertEquals((float)longitude, latLong[1], 0.0001f);
+        assertEquals(altitude, exif.getAltitude(-1), 1);
+        assertEquals(timestamp, getGpsDateTimeFromJpeg(exif) / 1000);
+    }
+
+    private long getGpsDateTimeFromJpeg(ExifInterface exif) {
+        String date = exif.getAttribute(ExifInterface.TAG_GPS_DATESTAMP);
+        String time = exif.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP);
+        if (date == null || time == null) return -1;
+
+        String dateTimeString = date + ' ' + time;
+        ParsePosition pos = new ParsePosition(0);
+        try {
+            SimpleDateFormat formatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
+            formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+            Date datetime = formatter.parse(dateTimeString, pos);
+            if (datetime == null) return -1;
+            return datetime.getTime();
+        } catch (IllegalArgumentException ex) {
+            return -1;
+        }
+    }
+
+    private void checkGpsDataNull(ExifInterface exif) {
+        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
+        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
+        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF));
+        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF));
+        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP));
+        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_DATESTAMP));
+        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD));
+    }
+
+    @UiThreadTest
+    public void testLockUnlock() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testLockUnlockByCamera(id);
+        }
+    }
+
+    private void testLockUnlockByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        Camera.Parameters parameters = mCamera.getParameters();
+        SurfaceHolder surfaceHolder;
+        surfaceHolder = getActivity().getSurfaceView().getHolder();
+        CamcorderProfile profile = CamcorderProfile.get(cameraId,
+                CamcorderProfile.QUALITY_LOW);
+
+        // Set the preview size.
+        setPreviewSizeByProfile(parameters, profile);
+
+        mCamera.setParameters(parameters);
+        mCamera.setPreviewDisplay(surfaceHolder);
+        mCamera.startPreview();
+        mCamera.lock();  // Locking again from the same process has no effect.
+        try {
+            recordVideo(profile, surfaceHolder);
+            fail("Recording should not succeed because camera is locked.");
+        } catch (Exception e) {
+            // expected
+        }
+
+        mCamera.unlock();  // Unlock the camera so media recorder can use it.
+        try {
+            mCamera.setParameters(parameters);
+            fail("setParameters should not succeed because camera is unlocked.");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        recordVideo(profile, surfaceHolder);  // should not throw exception
+        // Media recorder already releases the camera so the test application
+        // can lock and use the camera now.
+        mCamera.lock();  // should not fail
+        mCamera.setParameters(parameters);  // should not fail
+        terminateMessageLooper();
+    }
+
+    private void setPreviewSizeByProfile(Parameters parameters, CamcorderProfile profile) {
+        if (parameters.getSupportedVideoSizes() == null) {
+            parameters.setPreviewSize(profile.videoFrameWidth,
+                    profile.videoFrameHeight);
+        } else {  // Driver supports separates outputs for preview and video.
+            List<Size> sizes = parameters.getSupportedPreviewSizes();
+            Size preferred = parameters.getPreferredPreviewSizeForVideo();
+            int product = preferred.width * preferred.height;
+            for (Size size: sizes) {
+                if (size.width * size.height <= product) {
+                    parameters.setPreviewSize(size.width, size.height);
+                    break;
+                }
+            }
+        }
+    }
+
+    private void recordVideo(CamcorderProfile profile,
+            SurfaceHolder holder) throws Exception {
+        MediaRecorder recorder = new MediaRecorder();
+        try {
+            // Pass the camera from the test application to media recorder.
+            recorder.setCamera(mCamera);
+            recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+            recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+            recorder.setProfile(profile);
+            recorder.setOutputFile("/dev/null");
+            recorder.setPreviewDisplay(holder.getSurface());
+            recorder.prepare();
+            recorder.start();
+
+            // Apps can use the camera after start since API level 13.
+            Parameters parameters = mCamera.getParameters();
+            if (parameters.isZoomSupported()) {
+               if (parameters.getMaxZoom() > 0) {
+                   parameters.setZoom(1);
+                   mCamera.setParameters(parameters);
+                   parameters.setZoom(0);
+                   mCamera.setParameters(parameters);
+               }
+            }
+            if (parameters.isSmoothZoomSupported()) {
+                if (parameters.getMaxZoom() > 0) {
+                    ZoomListener zoomListener = new ZoomListener();
+                    mCamera.setZoomChangeListener(zoomListener);
+                    mCamera.startSmoothZoom(1);
+                    assertTrue(zoomListener.mZoomDone.block(1000));
+                }
+            }
+
+            try {
+                mCamera.unlock();
+                fail("unlock should not succeed during recording.");
+            } catch(RuntimeException e) {
+                // expected
+            }
+
+            Thread.sleep(2000);
+            recorder.stop();
+        } finally {
+            recorder.release();
+        }
+    }
+
+    @UiThreadTest
+    public void testPreviewCallbackWithBuffer() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testPreviewCallbackWithBufferByCamera(id);
+        }
+    }
+
+    private void testPreviewCallbackWithBufferByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        SurfaceHolder surfaceHolder;
+        surfaceHolder = getActivity().getSurfaceView().getHolder();
+        mCamera.setPreviewDisplay(surfaceHolder);
+        Parameters parameters = mCamera.getParameters();
+        PreviewCallbackWithBuffer callback = new PreviewCallbackWithBuffer();
+        // Test all preview sizes.
+        for (Size size: parameters.getSupportedPreviewSizes()) {
+            parameters.setPreviewSize(size.width, size.height);
+            mCamera.setParameters(parameters);
+            assertEquals(size, mCamera.getParameters().getPreviewSize());
+            callback.mNumCbWithBuffer1 = 0;
+            callback.mNumCbWithBuffer2 = 0;
+            callback.mNumCbWithBuffer3 = 0;
+            int format = mCamera.getParameters().getPreviewFormat();
+            int bitsPerPixel = ImageFormat.getBitsPerPixel(format);
+            callback.mBuffer1 = new byte[size.width * size.height * bitsPerPixel / 8];
+            callback.mBuffer2 = new byte[size.width * size.height * bitsPerPixel / 8];
+            callback.mBuffer3 = new byte[size.width * size.height * bitsPerPixel / 8];
+
+            // Test if we can get the preview callbacks with specified buffers.
+            mCamera.addCallbackBuffer(callback.mBuffer1);
+            mCamera.addCallbackBuffer(callback.mBuffer2);
+            mCamera.setPreviewCallbackWithBuffer(callback);
+            mCamera.startPreview();
+            waitForPreviewDone();
+            assertFalse(callback.mPreviewDataNull);
+            assertFalse(callback.mInvalidData);
+            assertEquals(1, callback.mNumCbWithBuffer1);
+            assertEquals(1, callback.mNumCbWithBuffer2);
+            assertEquals(0, callback.mNumCbWithBuffer3);
+
+            // Test if preview callback with buffer still works during preview.
+            mCamera.addCallbackBuffer(callback.mBuffer3);
+            waitForPreviewDone();
+            assertFalse(callback.mPreviewDataNull);
+            assertFalse(callback.mInvalidData);
+            assertEquals(1, callback.mNumCbWithBuffer1);
+            assertEquals(1, callback.mNumCbWithBuffer2);
+            assertEquals(1, callback.mNumCbWithBuffer3);
+            mCamera.setPreviewCallbackWithBuffer(null);
+            mCamera.stopPreview();
+        }
+        terminateMessageLooper();
+    }
+
+    private final class PreviewCallbackWithBuffer
+            implements android.hardware.Camera.PreviewCallback {
+        public int mNumCbWithBuffer1, mNumCbWithBuffer2, mNumCbWithBuffer3;
+        public byte[] mBuffer1, mBuffer2, mBuffer3;
+        public boolean mPreviewDataNull, mInvalidData;
+        public void onPreviewFrame(byte[] data, Camera camera) {
+            if (data == null) {
+                Log.e(TAG, "Preview data is null!");
+                mPreviewDataNull = true;
+                mPreviewDone.open();
+                return;
+            }
+            if (data == mBuffer1) {
+                mNumCbWithBuffer1++;
+            } else if (data == mBuffer2) {
+                mNumCbWithBuffer2++;
+            } else if (data == mBuffer3) {
+                mNumCbWithBuffer3++;
+            } else {
+                Log.e(TAG, "Invalid byte array.");
+                mInvalidData = true;
+                mPreviewDone.open();
+                return;
+            }
+
+            if ((mNumCbWithBuffer1 == 1 && mNumCbWithBuffer2 == 1)
+                    || mNumCbWithBuffer3 == 1) {
+                mPreviewDone.open();
+            }
+        }
+    }
+
+    @UiThreadTest
+    public void testImmediateZoom() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testImmediateZoomByCamera(id);
+        }
+    }
+
+    private void testImmediateZoomByCamera(int id) throws Exception {
+        initializeMessageLooper(id);
+
+        Parameters parameters = mCamera.getParameters();
+        if (!parameters.isZoomSupported()) {
+            terminateMessageLooper();
+            return;
+        }
+
+        // Test the zoom parameters.
+        assertEquals(0, parameters.getZoom());  // default zoom should be 0.
+        for (Size size: parameters.getSupportedPreviewSizes()) {
+            parameters = mCamera.getParameters();
+            parameters.setPreviewSize(size.width, size.height);
+            mCamera.setParameters(parameters);
+            parameters = mCamera.getParameters();
+            int maxZoom = parameters.getMaxZoom();
+            assertTrue(maxZoom >= 0);
+
+            // Zoom ratios should be sorted from small to large.
+            List<Integer> ratios = parameters.getZoomRatios();
+            assertEquals(maxZoom + 1, ratios.size());
+            assertEquals(100, ratios.get(0).intValue());
+            for (int i = 0; i < ratios.size() - 1; i++) {
+                assertTrue(ratios.get(i) < ratios.get(i + 1));
+            }
+            blockingStartPreview();
+
+            // Test each zoom step.
+            for (int i = 0; i <= maxZoom; i++) {
+                parameters.setZoom(i);
+                mCamera.setParameters(parameters);
+                assertEquals(i, mCamera.getParameters().getZoom());
+            }
+
+            // It should throw exception if an invalid value is passed.
+            try {
+                parameters.setZoom(maxZoom + 1);
+                mCamera.setParameters(parameters);
+                fail("setZoom should throw exception.");
+            } catch (RuntimeException e) {
+                // expected
+            }
+            assertEquals(maxZoom, mCamera.getParameters().getZoom());
+
+            mCamera.takePicture(mShutterCallback, mRawPictureCallback,
+                                mJpegPictureCallback);
+            waitForSnapshotDone();
+        }
+
+        terminateMessageLooper();
+    }
+
+    @UiThreadTest
+    public void testSmoothZoom() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testSmoothZoomByCamera(id);
+        }
+    }
+
+    private void testSmoothZoomByCamera(int id) throws Exception {
+        initializeMessageLooper(id);
+
+        Parameters parameters = mCamera.getParameters();
+        if (!parameters.isSmoothZoomSupported()) {
+            terminateMessageLooper();
+            return;
+        }
+        assertTrue(parameters.isZoomSupported());
+
+        ZoomListener zoomListener = new ZoomListener();
+        mCamera.setZoomChangeListener(zoomListener);
+        mCamera.startPreview();
+        waitForPreviewDone();
+
+        // Immediate zoom should not generate callbacks.
+        int maxZoom = parameters.getMaxZoom();
+        parameters.setZoom(maxZoom);
+        mCamera.setParameters(parameters);
+        assertEquals(maxZoom, mCamera.getParameters().getZoom());
+        parameters.setZoom(0);
+        mCamera.setParameters(parameters);
+        assertEquals(0, mCamera.getParameters().getZoom());
+        assertFalse(zoomListener.mZoomDone.block(500));
+
+        // Nothing will happen if zoom is not moving.
+        mCamera.stopSmoothZoom();
+
+        // It should not generate callbacks if zoom value is not changed.
+        mCamera.startSmoothZoom(0);
+        assertFalse(zoomListener.mZoomDone.block(500));
+        assertEquals(0, mCamera.getParameters().getZoom());
+
+        // Test startSmoothZoom.
+        mCamera.startSmoothZoom(maxZoom);
+        assertEquals(true, zoomListener.mZoomDone.block(5000));
+        assertEquals(maxZoom, mCamera.getParameters().getZoom());
+        assertEquals(maxZoom, zoomListener.mValues.size());
+        for(int i = 0; i < maxZoom; i++) {
+            int value = zoomListener.mValues.get(i);
+            boolean stopped = zoomListener.mStopped.get(i);
+            // Make sure we get all the zoom values in order.
+            assertEquals(i + 1, value);
+            // All "stopped" except the last should be false.
+            assertEquals(i == maxZoom - 1, stopped);
+        }
+
+        // Test startSmoothZoom. Make sure we get all the callbacks.
+        if (maxZoom > 1) {
+            zoomListener.mValues.clear();
+            zoomListener.mStopped.clear();
+            Log.e(TAG, "zoomListener.mStopped = " + zoomListener.mStopped);
+            zoomListener.mZoomDone.close();
+            mCamera.startSmoothZoom(maxZoom / 2);
+            assertTrue(zoomListener.mZoomDone.block(5000));
+            assertEquals(maxZoom / 2, mCamera.getParameters().getZoom());
+            assertEquals(maxZoom - (maxZoom / 2), zoomListener.mValues.size());
+            for(int i = 0; i < zoomListener.mValues.size(); i++) {
+                int value = zoomListener.mValues.get(i);
+                boolean stopped = zoomListener.mStopped.get(i);
+                // Make sure we get all the zoom values in order.
+                assertEquals(maxZoom - 1 - i, value);
+                // All "stopped" except the last should be false.
+                assertEquals(i == zoomListener.mValues.size() - 1, stopped);
+            }
+        }
+
+        // It should throw exception if an invalid value is passed.
+        try {
+            mCamera.startSmoothZoom(maxZoom + 1);
+            fail("startSmoothZoom should throw exception.");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        // Test stopSmoothZoom.
+        zoomListener.mValues.clear();
+        zoomListener.mStopped.clear();
+        zoomListener.mZoomDone.close();
+        parameters.setZoom(0);
+        mCamera.setParameters(parameters);
+        assertEquals(0, mCamera.getParameters().getZoom());
+        mCamera.startSmoothZoom(maxZoom);
+        mCamera.stopSmoothZoom();
+        assertTrue(zoomListener.mZoomDone.block(5000));
+        assertEquals(zoomListener.mValues.size(), mCamera.getParameters().getZoom());
+        for(int i = 0; i < zoomListener.mValues.size() - 1; i++) {
+            int value = zoomListener.mValues.get(i);
+            boolean stopped = zoomListener.mStopped.get(i);
+            // Make sure we get all the callbacks in order (except the last).
+            assertEquals(i + 1, value);
+            // All "stopped" except the last should be false. stopSmoothZoom has been called. So the
+            // last "stopped" can be true or false.
+            if (i != zoomListener.mValues.size() - 1) {
+                assertFalse(stopped);
+            }
+        }
+
+        terminateMessageLooper();
+    }
+
+    private final class ZoomListener
+            implements android.hardware.Camera.OnZoomChangeListener {
+        public ArrayList<Integer> mValues = new ArrayList<Integer>();
+        public ArrayList<Boolean> mStopped = new ArrayList<Boolean>();
+        public final ConditionVariable mZoomDone = new ConditionVariable();
+
+        public void onZoomChange(int value, boolean stopped, Camera camera) {
+            mValues.add(value);
+            mStopped.add(stopped);
+            if (stopped) {
+                mZoomDone.open();
+            }
+        }
+    }
+
+    @UiThreadTest
+    public void testFocusDistances() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testFocusDistancesByCamera(id);
+        }
+    }
+
+    private void testFocusDistancesByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        blockingStartPreview();
+
+        Parameters parameters = mCamera.getParameters();
+
+        // Test every supported focus mode.
+        for (String focusMode: parameters.getSupportedFocusModes()) {
+            parameters.setFocusMode(focusMode);
+            mCamera.setParameters(parameters);
+            parameters = mCamera.getParameters();
+            assertEquals(focusMode, parameters.getFocusMode());
+            checkFocusDistances(parameters);
+            if (Parameters.FOCUS_MODE_AUTO.equals(focusMode)
+                    || Parameters.FOCUS_MODE_MACRO.equals(focusMode)
+                    || Parameters.FOCUS_MODE_CONTINUOUS_VIDEO.equals(focusMode)
+                    || Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(focusMode)) {
+                Log.v(TAG, "Focus mode=" + focusMode);
+                mCamera.autoFocus(mAutoFocusCallback);
+                assertTrue(waitForFocusDone());
+                parameters = mCamera.getParameters();
+                checkFocusDistances(parameters);
+                float[] initialFocusDistances = new float[3];
+                parameters.getFocusDistances(initialFocusDistances);
+
+                // Focus position should not change after autoFocus call.
+                // Continuous autofocus should have stopped. Sleep some time and
+                // check. Make sure continuous autofocus is not working. If the
+                // focus mode is auto or macro, it is no harm to do the extra
+                // test.
+                Thread.sleep(500);
+                parameters = mCamera.getParameters();
+                float[] currentFocusDistances = new float[3];
+                parameters.getFocusDistances(currentFocusDistances);
+                assertEquals(initialFocusDistances, currentFocusDistances);
+
+                // Focus position should not change after stopping preview.
+                mCamera.stopPreview();
+                parameters = mCamera.getParameters();
+                parameters.getFocusDistances(currentFocusDistances);
+                assertEquals(initialFocusDistances, currentFocusDistances);
+
+                // Focus position should not change after taking a picture.
+                mCamera.startPreview();
+                mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+                waitForSnapshotDone();
+                parameters = mCamera.getParameters();
+                parameters.getFocusDistances(currentFocusDistances);
+                assertEquals(initialFocusDistances, currentFocusDistances);
+                mCamera.startPreview();
+            }
+        }
+
+        // Test if the method throws exception if the argument is invalid.
+        try {
+            parameters.getFocusDistances(null);
+            fail("getFocusDistances should not accept null.");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            parameters.getFocusDistances(new float[2]);
+            fail("getFocusDistances should not accept a float array with two elements.");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            parameters.getFocusDistances(new float[4]);
+            fail("getFocusDistances should not accept a float array with four elements.");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+        terminateMessageLooper();
+    }
+
+    private void checkFocusDistances(Parameters parameters) {
+        float[] distances = new float[3];
+        parameters.getFocusDistances(distances);
+
+        // Focus distances should be greater than 0.
+        assertTrue(distances[Parameters.FOCUS_DISTANCE_NEAR_INDEX] > 0);
+        assertTrue(distances[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX] > 0);
+        assertTrue(distances[Parameters.FOCUS_DISTANCE_FAR_INDEX] > 0);
+
+        // Make sure far focus distance >= optimal focus distance >= near focus distance.
+        assertTrue(distances[Parameters.FOCUS_DISTANCE_FAR_INDEX] >=
+                   distances[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX]);
+        assertTrue(distances[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX] >=
+                   distances[Parameters.FOCUS_DISTANCE_NEAR_INDEX]);
+
+        // Far focus distance should be infinity in infinity focus mode.
+        if (Parameters.FOCUS_MODE_INFINITY.equals(parameters.getFocusMode())) {
+            assertEquals(Float.POSITIVE_INFINITY,
+                         distances[Parameters.FOCUS_DISTANCE_FAR_INDEX]);
+        }
+    }
+
+    @UiThreadTest
+    public void testCancelAutofocus() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testCancelAutofocusByCamera(id);
+        }
+    }
+
+    private void testCancelAutofocusByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        Parameters parameters = mCamera.getParameters();
+        List<String> focusModes = parameters.getSupportedFocusModes();
+
+        if (focusModes.contains(Parameters.FOCUS_MODE_AUTO)) {
+            parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
+        } else if (focusModes.contains(Parameters.FOCUS_MODE_MACRO)) {
+            parameters.setFocusMode(Parameters.FOCUS_MODE_MACRO);
+        } else {
+            terminateMessageLooper();
+            return;
+        }
+
+        mCamera.setParameters(parameters);
+
+        // Valid to call outside of preview; should just reset lens or
+        // be a no-op.
+        mCamera.cancelAutoFocus();
+
+        mCamera.startPreview();
+
+        // No op if autofocus is not in progress.
+        mCamera.cancelAutoFocus();
+
+        // Try to cancel autofocus immediately.
+        mCamera.autoFocus(mAutoFocusCallback);
+        mCamera.cancelAutoFocus();
+        checkFocusDistanceNotChanging();
+
+        // Try to cancel autofocus after it starts for some time.
+        mCamera.autoFocus(mAutoFocusCallback);
+        Thread.sleep(500);
+        mCamera.cancelAutoFocus();
+        checkFocusDistanceNotChanging();
+
+        // Try to cancel autofocus after it completes. It should be no op.
+        mCamera.autoFocus(mAutoFocusCallback);
+        assertTrue(waitForFocusDone());
+        mCamera.cancelAutoFocus();
+
+        // Test the case calling cancelAutoFocus and release in a row.
+        mCamera.autoFocus(mAutoFocusCallback);
+        mCamera.cancelAutoFocus();
+        mCamera.release();
+
+        // Ensure the camera can be opened if release is called right after AF.
+        mCamera = Camera.open(cameraId);
+        mCamera.setPreviewDisplay(getActivity().getSurfaceView().getHolder());
+        mCamera.startPreview();
+        mCamera.autoFocus(mAutoFocusCallback);
+        mCamera.release();
+
+        terminateMessageLooper();
+    }
+
+    private void checkFocusDistanceNotChanging() throws Exception {
+        float[] distances1 = new float[3];
+        float[] distances2 = new float[3];
+        Parameters parameters = mCamera.getParameters();
+        parameters.getFocusDistances(distances1);
+        Thread.sleep(100);
+        parameters = mCamera.getParameters();
+        parameters.getFocusDistances(distances2);
+        assertEquals(distances1[Parameters.FOCUS_DISTANCE_NEAR_INDEX],
+                     distances2[Parameters.FOCUS_DISTANCE_NEAR_INDEX]);
+        assertEquals(distances1[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX],
+                     distances2[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX]);
+        assertEquals(distances1[Parameters.FOCUS_DISTANCE_FAR_INDEX],
+                     distances2[Parameters.FOCUS_DISTANCE_FAR_INDEX]);
+    }
+
+    @UiThreadTest
+    public void testMultipleCameras() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        Log.v(TAG, "total " + nCameras + " cameras");
+        assertTrue(nCameras >= 0);
+
+        boolean backCameraExist = false;
+        CameraInfo info = new CameraInfo();
+        for (int i = 0; i < nCameras; i++) {
+            Camera.getCameraInfo(i, info);
+            if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
+                backCameraExist = true;
+                break;
+            }
+        }
+        // Make sure original open still works. It must return a back-facing
+        // camera.
+        mCamera = Camera.open();
+        if (mCamera != null) {
+            mCamera.release();
+            assertTrue(backCameraExist);
+        } else {
+            assertFalse(backCameraExist);
+        }
+
+        for (int id = -1; id <= nCameras; id++) {
+            Log.v(TAG, "testing camera #" + id);
+
+            boolean isBadId = (id < 0 || id >= nCameras);
+
+            try {
+                Camera.getCameraInfo(id, info);
+                if (isBadId) {
+                    fail("getCameraInfo should not accept bad cameraId (" + id + ")");
+                }
+            } catch (RuntimeException e) {
+                if (!isBadId) throw e;
+            }
+
+            int facing = info.facing;
+            int orientation = info.orientation;
+            assertTrue(facing == CameraInfo.CAMERA_FACING_BACK ||
+                       facing == CameraInfo.CAMERA_FACING_FRONT);
+            assertTrue(orientation == 0 || orientation == 90 ||
+                       orientation == 180 || orientation == 270);
+
+            Camera camera = null;
+            try {
+                camera = Camera.open(id);
+                if (isBadId) {
+                    fail("open() should not accept bad cameraId (" + id + ")");
+                }
+            } catch (RuntimeException e) {
+                if (!isBadId) throw e;
+            } finally {
+                if (camera != null) {
+                    camera.release();
+                }
+            }
+        }
+    }
+
+    @UiThreadTest
+    @TimeoutReq(minutes = 30)
+    public void testPreviewPictureSizesCombination() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testPreviewPictureSizesCombinationByCamera(id);
+        }
+    }
+
+    private void testPreviewPictureSizesCombinationByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        Parameters parameters = mCamera.getParameters();
+        PreviewCbForPreviewPictureSizesCombination callback =
+            new PreviewCbForPreviewPictureSizesCombination();
+
+        // Test all combination of preview sizes and picture sizes.
+        for (Size previewSize: parameters.getSupportedPreviewSizes()) {
+            for (Size pictureSize: parameters.getSupportedPictureSizes()) {
+                Log.v(TAG, "Test previewSize=(" + previewSize.width + "," +
+                        previewSize.height + ") pictureSize=(" +
+                        pictureSize.width + "," + pictureSize.height + ")");
+                mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
+                mCamera.setPreviewCallback(callback);
+                callback.expectedPreviewSize = previewSize;
+                parameters.setPreviewSize(previewSize.width, previewSize.height);
+                parameters.setPictureSize(pictureSize.width, pictureSize.height);
+                mCamera.setParameters(parameters);
+                assertEquals(previewSize, mCamera.getParameters().getPreviewSize());
+                assertEquals(pictureSize, mCamera.getParameters().getPictureSize());
+
+                // Check if the preview size is the same as requested.
+                mCamera.startPreview();
+                waitForPreviewDone();
+                assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
+
+                // Check if the picture size is the same as requested.
+                mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+                waitForSnapshotDone();
+                assertTrue(mJpegPictureCallbackResult);
+                assertNotNull(mJpegData);
+                BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
+                bmpOptions.inJustDecodeBounds = true;
+                BitmapFactory.decodeByteArray(mJpegData, 0, mJpegData.length, bmpOptions);
+                assertEquals(pictureSize.width, bmpOptions.outWidth);
+                assertEquals(pictureSize.height, bmpOptions.outHeight);
+            }
+        }
+        terminateMessageLooper();
+    }
+
+    private final class PreviewCbForPreviewPictureSizesCombination
+            implements android.hardware.Camera.PreviewCallback {
+        public Size expectedPreviewSize;
+        public void onPreviewFrame(byte[] data, Camera camera) {
+            if (data == null) {
+                mPreviewCallbackResult = PREVIEW_CALLBACK_DATA_NULL;
+                mPreviewDone.open();
+                return;
+            }
+            Size size = camera.getParameters().getPreviewSize();
+            int format = camera.getParameters().getPreviewFormat();
+            int bitsPerPixel = ImageFormat.getBitsPerPixel(format);
+            if (!expectedPreviewSize.equals(size) ||
+                    calculateBufferSize(size.width, size.height,
+                        format, bitsPerPixel) != data.length) {
+                Log.e(TAG, "Expected preview width=" + expectedPreviewSize.width + ", height="
+                        + expectedPreviewSize.height + ". Actual width=" + size.width + ", height="
+                        + size.height);
+                Log.e(TAG, "Frame data length=" + data.length + ". bitsPerPixel=" + bitsPerPixel);
+                mPreviewCallbackResult = PREVIEW_CALLBACK_INVALID_FRAME_SIZE;
+                mPreviewDone.open();
+                return;
+            }
+            camera.setPreviewCallback(null);
+            mPreviewCallbackResult = PREVIEW_CALLBACK_RECEIVED;
+            mPreviewDone.open();
+        }
+    }
+
+    @UiThreadTest
+    public void testPreviewFpsRange() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testPreviewFpsRangeByCamera(id);
+        }
+    }
+
+    private void testPreviewFpsRangeByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+
+        // Test if the parameters exists and minimum fps <= maximum fps.
+        final int INTERVAL_ERROR_THRESHOLD = 10;
+        int[] defaultFps = new int[2];
+        Parameters parameters = mCamera.getParameters();
+        parameters.getPreviewFpsRange(defaultFps);
+        List<int[]> fpsList = parameters.getSupportedPreviewFpsRange();
+        assertTrue(fpsList.size() > 0);
+        boolean found = false;
+        for(int[] fps: fpsList) {
+            assertTrue(fps[Parameters.PREVIEW_FPS_MIN_INDEX] > 0);
+            assertTrue(fps[Parameters.PREVIEW_FPS_MIN_INDEX] <=
+                       fps[Parameters.PREVIEW_FPS_MAX_INDEX]);
+            if (!found && Arrays.equals(defaultFps, fps)) {
+                found = true;
+            }
+        }
+        assertTrue("Preview fps range must be in the supported list.", found);
+
+        // Test if the list is properly sorted.
+        for (int i = 0; i < fpsList.size() - 1; i++) {
+            int minFps1 = fpsList.get(i)[Parameters.PREVIEW_FPS_MIN_INDEX];
+            int maxFps1 = fpsList.get(i)[Parameters.PREVIEW_FPS_MAX_INDEX];
+            int minFps2 = fpsList.get(i + 1)[Parameters.PREVIEW_FPS_MIN_INDEX];
+            int maxFps2 = fpsList.get(i + 1)[Parameters.PREVIEW_FPS_MAX_INDEX];
+            assertTrue(maxFps1 < maxFps2
+                    || (maxFps1 == maxFps2 && minFps1 < minFps2));
+        }
+
+        // Test if the actual fps is within fps range.
+        Size size = parameters.getPreviewSize();
+        int format = mCamera.getParameters().getPreviewFormat();
+        int bitsPerPixel = ImageFormat.getBitsPerPixel(format);
+        byte[] buffer1 = new byte[size.width * size.height * bitsPerPixel / 8];
+        byte[] buffer2 = new byte[size.width * size.height * bitsPerPixel / 8];
+        byte[] buffer3 = new byte[size.width * size.height * bitsPerPixel / 8];
+        FpsRangePreviewCb callback = new FpsRangePreviewCb();
+        int[] readBackFps = new int[2];
+        for (int[] fps: fpsList) {
+            parameters = mCamera.getParameters();
+            parameters.setPreviewFpsRange(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
+                                          fps[Parameters.PREVIEW_FPS_MAX_INDEX]);
+            callback.reset(fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.0,
+                           fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.0);
+            mCamera.setParameters(parameters);
+            parameters = mCamera.getParameters();
+            parameters.getPreviewFpsRange(readBackFps);
+            MoreAsserts.assertEquals(fps, readBackFps);
+            mCamera.addCallbackBuffer(buffer1);
+            mCamera.addCallbackBuffer(buffer2);
+            mCamera.addCallbackBuffer(buffer3);
+            mCamera.setPreviewCallbackWithBuffer(callback);
+            mCamera.startPreview();
+            try {
+                // Test the frame rate for a while.
+                Thread.sleep(3000);
+            } catch(Exception e) {
+                // ignore
+            }
+            mCamera.stopPreview();
+            // See if any frame duration violations occurred during preview run
+            AssertionFailedError e = callback.getDurationException();
+            if (e != null) throw(e);
+            int numIntervalError = callback.getNumIntervalError();
+            if (numIntervalError > INTERVAL_ERROR_THRESHOLD) {
+                fail(String.format(
+                        "Too many preview callback frame intervals out of bounds: " +
+                                "Count is %d, limit is %d",
+                        numIntervalError, INTERVAL_ERROR_THRESHOLD));
+            }
+        }
+
+        // Test the invalid fps cases.
+        parameters = mCamera.getParameters();
+        parameters.setPreviewFpsRange(-1, -1);
+        try {
+            mCamera.setParameters(parameters);
+            fail("Should throw an exception if fps range is negative.");
+        } catch (RuntimeException e) {
+            // expected
+        }
+        parameters.setPreviewFpsRange(10, 5);
+        try {
+            mCamera.setParameters(parameters);
+            fail("Should throw an exception if fps range is invalid.");
+        } catch (RuntimeException e) {
+            // expected
+        }
+
+        terminateMessageLooper();
+    }
+
+    private final class FpsRangePreviewCb
+            implements android.hardware.Camera.PreviewCallback {
+        private double mMinFps, mMaxFps, mMaxFrameInterval, mMinFrameInterval;
+        // An array storing the arrival time of the frames in the last second.
+        private ArrayList<Long> mFrames = new ArrayList<Long>();
+        private long firstFrameArrivalTime;
+        private AssertionFailedError mDurationException = null;
+        private int numIntervalError;
+
+        public void reset(double minFps, double maxFps) {
+            this.mMinFps = minFps;
+            this.mMaxFps = maxFps;
+            mMaxFrameInterval = 1000.0 / mMinFps;
+            mMinFrameInterval = 1000.0 / mMaxFps;
+            Log.v(TAG, "Min fps=" + mMinFps + ". Max fps=" + mMaxFps
+                    + ". Min frame interval=" + mMinFrameInterval
+                    + ". Max frame interval=" + mMaxFrameInterval);
+            mFrames.clear();
+            firstFrameArrivalTime = 0;
+            mDurationException = null;
+            numIntervalError = 0;
+        }
+
+        // This method tests if the actual fps is between minimum and maximum.
+        // It also tests if the frame interval is too long.
+        public void onPreviewFrame(byte[] data, android.hardware.Camera camera) {
+            long arrivalTime = SystemClock.elapsedRealtime();
+            camera.addCallbackBuffer(data);
+            if (firstFrameArrivalTime == 0) firstFrameArrivalTime = arrivalTime;
+
+            // Remove the frames that arrived before the last second.
+            Iterator<Long> it = mFrames.iterator();
+            while(it.hasNext()) {
+                long time = it.next();
+                if (arrivalTime - time > 1000 && mFrames.size() > 2) {
+                    it.remove();
+                } else {
+                    break;
+                }
+            }
+
+            // Start the test after one second.
+            if (arrivalTime - firstFrameArrivalTime > 1000) {
+                assertTrue(mFrames.size() >= 2);
+
+                // Check the frame interval and fps. The interval check
+                // considers the time variance passing frames from the camera
+                // hardware to the callback. It should be a constant time, not a
+                // ratio. The fps check is more strict because individual
+                // variance is averaged out.
+
+                // Check if the frame interval is too large or too small.
+                // x100 = percent, intervalMargin should be bigger than
+                // fpsMargin considering that fps will be in the order of 10.
+                double intervalMargin = 0.9;
+                long lastArrivalTime = mFrames.get(mFrames.size() - 1);
+                double interval = arrivalTime - lastArrivalTime;
+                if (VERBOSE) Log.v(TAG, "Frame interval=" + interval);
+
+                try {
+                    if (interval > mMaxFrameInterval * (1.0 + intervalMargin) ||
+                            interval < mMinFrameInterval * (1.0 - intervalMargin)) {
+                        Log.i(TAG, "Bad frame interval=" + interval + "ms. Out out range " +
+                                mMinFrameInterval * (1.0 - intervalMargin) + "/" +
+                                mMaxFrameInterval * (1.0 + intervalMargin));
+                        numIntervalError++;
+                    }
+                    // Check if the fps is within range.
+                    double fpsMargin = 0.5; // x100 = percent
+                    double avgInterval = (double)(arrivalTime - mFrames.get(0))
+                            / mFrames.size();
+                    double fps = 1000.0 / avgInterval;
+                    assertTrue("Actual fps (" + fps + ") should be larger " +
+                            "than min fps (" + mMinFps + ")",
+                            fps >= mMinFps * (1.0 - fpsMargin));
+                    assertTrue("Actual fps (" + fps + ") should be smaller" +
+                            "than max fps (" + mMaxFps + ")",
+                            fps <= mMaxFps * (1.0 + fpsMargin));
+                } catch (AssertionFailedError e) {
+                    // Need to throw this only in the test body, instead of in
+                    // the callback
+                    if (mDurationException == null) {
+                        mDurationException = e;
+                    }
+                }
+            }
+            // Add the arrival time of this frame to the list.
+            mFrames.add(arrivalTime);
+        }
+
+        public AssertionFailedError getDurationException() {
+            return mDurationException;
+        }
+        public int getNumIntervalError() {
+            return numIntervalError;
+        }
+    }
+
+    private void assertEquals(Size expected, Size actual) {
+        assertEquals(expected.width, actual.width);
+        assertEquals(expected.height, actual.height);
+    }
+
+    private void assertEquals(float[] expected, float[] actual) {
+        assertEquals(expected.length, actual.length);
+        for (int i = 0; i < expected.length; i++) {
+            assertEquals(expected[i], actual[i], 0.000001f);
+        }
+    }
+
+    private void assertNoLetters(String value, String key) {
+        for (int i = 0; i < value.length(); i++) {
+            char c = value.charAt(i);
+            assertFalse("Parameter contains invalid characters. key,value=("
+                    + key + "," + value + ")",
+                    Character.isLetter(c) && c != 'x');
+        }
+    }
+
+    @UiThreadTest
+    public void testSceneMode() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testSceneModeByCamera(id);
+        }
+    }
+
+    private class SceneModeSettings {
+        public String mScene, mFlash, mFocus, mWhiteBalance;
+        public List<String> mSupportedFlash, mSupportedFocus, mSupportedWhiteBalance;
+
+        public SceneModeSettings(Parameters parameters) {
+            mScene = parameters.getSceneMode();
+            mFlash = parameters.getFlashMode();
+            mFocus = parameters.getFocusMode();
+            mWhiteBalance = parameters.getWhiteBalance();
+            mSupportedFlash = parameters.getSupportedFlashModes();
+            mSupportedFocus = parameters.getSupportedFocusModes();
+            mSupportedWhiteBalance = parameters.getSupportedWhiteBalance();
+        }
+    }
+
+    private void testSceneModeByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        Parameters parameters = mCamera.getParameters();
+        List<String> supportedSceneModes = parameters.getSupportedSceneModes();
+        if (supportedSceneModes != null) {
+            assertEquals(Parameters.SCENE_MODE_AUTO, parameters.getSceneMode());
+            SceneModeSettings autoSceneMode = new SceneModeSettings(parameters);
+
+            // Store all scene mode affected settings.
+            SceneModeSettings[] settings = new SceneModeSettings[supportedSceneModes.size()];
+            for (int i = 0; i < supportedSceneModes.size(); i++) {
+                parameters.setSceneMode(supportedSceneModes.get(i));
+                mCamera.setParameters(parameters);
+                parameters = mCamera.getParameters();
+                settings[i] = new SceneModeSettings(parameters);
+            }
+
+            // Make sure scene mode settings are consistent before preview and
+            // after preview.
+            blockingStartPreview();
+            for (int i = 0; i < supportedSceneModes.size(); i++) {
+                String sceneMode = supportedSceneModes.get(i);
+                parameters.setSceneMode(sceneMode);
+                mCamera.setParameters(parameters);
+                parameters = mCamera.getParameters();
+
+                // In auto scene mode, camera HAL will not remember the previous
+                // flash, focus, and white-balance. It will just take values set
+                // by parameters. But the supported flash, focus, and
+                // white-balance should still be restored in auto scene mode.
+                if (!Parameters.SCENE_MODE_AUTO.equals(sceneMode)) {
+                    assertEquals("Flash is inconsistent in scene mode " + sceneMode,
+                            settings[i].mFlash, parameters.getFlashMode());
+                    assertEquals("Focus is inconsistent in scene mode " + sceneMode,
+                            settings[i].mFocus, parameters.getFocusMode());
+                    assertEquals("White balance is inconsistent in scene mode " + sceneMode,
+                            settings[i].mWhiteBalance, parameters.getWhiteBalance());
+                }
+                assertEquals("Suppported flash modes are inconsistent in scene mode " + sceneMode,
+                        settings[i].mSupportedFlash, parameters.getSupportedFlashModes());
+                assertEquals("Suppported focus modes are inconsistent in scene mode " + sceneMode,
+                        settings[i].mSupportedFocus, parameters.getSupportedFocusModes());
+                assertEquals("Suppported white balance are inconsistent in scene mode " + sceneMode,
+                        settings[i].mSupportedWhiteBalance, parameters.getSupportedWhiteBalance());
+            }
+
+            for (int i = 0; i < settings.length; i++) {
+                if (Parameters.SCENE_MODE_AUTO.equals(settings[i].mScene)) continue;
+
+                // Both the setting and the supported settings may change. It is
+                // allowed to have more than one supported settings in scene
+                // modes. For example, in night scene mode, supported flash
+                // modes can have on and off.
+                if (autoSceneMode.mSupportedFlash != null) {
+                    assertTrue(settings[i].mSupportedFlash.contains(settings[i].mFlash));
+                    for (String mode: settings[i].mSupportedFlash) {
+                        assertTrue(autoSceneMode.mSupportedFlash.contains(mode));
+                    }
+                }
+                if (autoSceneMode.mSupportedFocus != null) {
+                    assertTrue(settings[i].mSupportedFocus.contains(settings[i].mFocus));
+                    for (String mode: settings[i].mSupportedFocus) {
+                        assertTrue(autoSceneMode.mSupportedFocus.contains(mode));
+                    }
+                }
+                if (autoSceneMode.mSupportedWhiteBalance != null) {
+                    assertTrue(settings[i].mSupportedWhiteBalance.contains(settings[i].mWhiteBalance));
+                    for (String mode: settings[i].mSupportedWhiteBalance) {
+                        assertTrue(autoSceneMode.mSupportedWhiteBalance.contains(mode));
+                    }
+                }
+            }
+        }
+        terminateMessageLooper();
+    }
+
+    @UiThreadTest
+    public void testInvalidParameters() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testInvalidParametersByCamera(id);
+        }
+    }
+
+    private void testInvalidParametersByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        // Test flash mode.
+        Parameters parameters = mCamera.getParameters();
+        List<String> list = parameters.getSupportedFlashModes();
+        if (list != null && list.size() > 0) {
+            String original = parameters.getFlashMode();
+            parameters.setFlashMode("invalid");
+            try {
+                mCamera.setParameters(parameters);
+                fail("Should throw exception for invalid parameters");
+            } catch (RuntimeException e) {
+                // expected
+            }
+            parameters = mCamera.getParameters();
+            assertEquals(original, parameters.getFlashMode());
+        }
+
+        // Test focus mode.
+        String originalFocus = parameters.getFocusMode();
+        parameters.setFocusMode("invalid");
+        try {
+            mCamera.setParameters(parameters);
+            fail("Should throw exception for invalid parameters");
+        } catch (RuntimeException e) {
+            // expected
+        }
+        parameters = mCamera.getParameters();
+        assertEquals(originalFocus, parameters.getFocusMode());
+
+        // Test preview size.
+        Size originalSize = parameters.getPreviewSize();
+        parameters.setPreviewSize(-1, -1);
+        try {
+            mCamera.setParameters(parameters);
+            fail("Should throw exception for invalid parameters");
+        } catch (RuntimeException e) {
+            // expected
+        }
+        parameters = mCamera.getParameters();
+        assertEquals(originalSize, parameters.getPreviewSize());
+
+        terminateMessageLooper();
+    }
+
+    @UiThreadTest
+    public void testGetParameterDuringFocus() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testGetParameterDuringFocusByCamera(id);
+        }
+    }
+
+    private void testGetParameterDuringFocusByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        mCamera.startPreview();
+        Parameters parameters = mCamera.getParameters();
+        for (String focusMode: parameters.getSupportedFocusModes()) {
+            if (focusMode.equals(parameters.FOCUS_MODE_AUTO)
+                    || focusMode.equals(parameters.FOCUS_MODE_MACRO)) {
+                parameters.setFocusMode(focusMode);
+                mCamera.setParameters(parameters);
+                mCamera.autoFocus(mAutoFocusCallback);
+                // This should not crash or throw exception.
+                mCamera.getParameters();
+                waitForFocusDone();
+
+
+                mCamera.autoFocus(mAutoFocusCallback);
+                // Add a small delay to make sure focus has started.
+                Thread.sleep(100);
+                // This should not crash or throw exception.
+                mCamera.getParameters();
+                waitForFocusDone();
+            }
+        }
+        terminateMessageLooper();
+    }
+
+    @UiThreadTest
+    public void testPreviewFormats() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testPreviewFormatsByCamera(id);
+        }
+    }
+
+    private void testPreviewFormatsByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        Parameters parameters = mCamera.getParameters();
+        for (int format: parameters.getSupportedPreviewFormats()) {
+            Log.v(TAG, "Test preview format " + format);
+            parameters.setPreviewFormat(format);
+            mCamera.setParameters(parameters);
+            mCamera.setOneShotPreviewCallback(mPreviewCallback);
+            mCamera.startPreview();
+            waitForPreviewDone();
+            assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
+        }
+        terminateMessageLooper();
+    }
+
+    @UiThreadTest
+    public void testMultiCameraRelease() throws Exception {
+        // Verify that multiple cameras exist, and that they can be opened at the same time
+        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Checking pre-conditions.");
+        int nCameras = Camera.getNumberOfCameras();
+        if (nCameras < 2) {
+            Log.i(TAG, "Test multi-camera release: Skipping test because only 1 camera available");
+            return;
+        }
+
+        Camera testCamera0 = Camera.open(0);
+        Camera testCamera1 = null;
+        try {
+            testCamera1 = Camera.open(1);
+        } catch (RuntimeException e) {
+            // Can't open two cameras at once
+            Log.i(TAG, "testMultiCameraRelease: Skipping test because only 1 camera "+
+                  "could be opened at once. Second open threw: " + e);
+            testCamera0.release();
+            return;
+        }
+        testCamera0.release();
+        testCamera1.release();
+
+        // Start first camera
+        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Opening camera 0");
+        initializeMessageLooper(0);
+        SimplePreviewStreamCb callback0 = new SimplePreviewStreamCb(0);
+        mCamera.setPreviewCallback(callback0);
+        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Starting preview on camera 0");
+        mCamera.startPreview();
+        // Run preview for a bit
+        for (int f = 0; f < 100; f++) {
+            mPreviewDone.close();
+            assertTrue("testMultiCameraRelease: First camera preview timed out on frame " + f + "!",
+                       mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE));
+        }
+        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Stopping preview on camera 0");
+        mCamera.stopPreview();
+        // Save message looper and camera to deterministically release them, instead
+        // of letting GC do it at some point.
+        Camera firstCamera = mCamera;
+        Looper firstLooper = mLooper;
+        //terminateMessageLooper(); // Intentionally not calling this
+        // Preview surface should be released though!
+        mCamera.setPreviewDisplay(null);
+
+        // Start second camera without releasing the first one (will
+        // set mCamera and mLooper to new objects)
+        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Opening camera 1");
+        initializeMessageLooper(1);
+        SimplePreviewStreamCb callback1 = new SimplePreviewStreamCb(1);
+        mCamera.setPreviewCallback(callback1);
+        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Starting preview on camera 1");
+        mCamera.startPreview();
+        // Run preview for a bit - GC of first camera instance should not impact the second's
+        // operation.
+        for (int f = 0; f < 100; f++) {
+            mPreviewDone.close();
+            assertTrue("testMultiCameraRelease: Second camera preview timed out on frame " + f + "!",
+                       mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE));
+            if (f == 50) {
+                // Release first camera mid-preview, should cause no problems
+                if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Releasing camera 0");
+                firstCamera.release();
+            }
+        }
+        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Stopping preview on camera 0");
+        mCamera.stopPreview();
+
+        firstLooper.quit();
+        terminateMessageLooper();
+    }
+
+    // This callback just signals on the condition variable, making it useful for checking that
+    // preview callbacks don't stop unexpectedly
+    private final class SimplePreviewStreamCb
+            implements android.hardware.Camera.PreviewCallback {
+        private int mId;
+        public SimplePreviewStreamCb(int id) {
+            mId = id;
+        }
+        public void onPreviewFrame(byte[] data, android.hardware.Camera camera) {
+            if (VERBOSE) Log.v(TAG, "Preview frame callback, id " + mId + ".");
+            mPreviewDone.open();
+        }
+    }
+
+    @UiThreadTest
+    public void testFocusAreas() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+
+            initializeMessageLooper(id);
+            Parameters parameters = mCamera.getParameters();
+            int maxNumFocusAreas = parameters.getMaxNumFocusAreas();
+            assertTrue(maxNumFocusAreas >= 0);
+            if (maxNumFocusAreas > 0) {
+                List<String> focusModes = parameters.getSupportedFocusModes();
+                assertTrue(focusModes.contains(Parameters.FOCUS_MODE_AUTO));
+                testAreas(FOCUS_AREA, maxNumFocusAreas);
+            }
+            terminateMessageLooper();
+        }
+    }
+
+    @UiThreadTest
+    public void testMeteringAreas() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            initializeMessageLooper(id);
+            Parameters parameters = mCamera.getParameters();
+            int maxNumMeteringAreas = parameters.getMaxNumMeteringAreas();
+            assertTrue(maxNumMeteringAreas >= 0);
+            if (maxNumMeteringAreas > 0) {
+                testAreas(METERING_AREA, maxNumMeteringAreas);
+            }
+            terminateMessageLooper();
+        }
+    }
+
+    private void testAreas(int type, int maxNumAreas) throws Exception {
+        mCamera.startPreview();
+
+        // Test various valid cases.
+        testValidAreas(type, null);                                  // the default area
+        testValidAreas(type, makeAreas(-1000, -1000, 1000, 1000, 1)); // biggest area
+        testValidAreas(type, makeAreas(-500, -500, 500, 500, 1000)); // medium area & biggest weight
+        testValidAreas(type, makeAreas(0, 0, 1, 1, 1));              // smallest area
+
+        ArrayList<Area> areas = new ArrayList();
+        if (maxNumAreas > 1) {
+            // Test overlapped areas.
+            testValidAreas(type, makeAreas(-250, -250, 250, 250, 1, 0, 0, 500, 500, 2));
+            // Test completely disjoint areas.
+            testValidAreas(type, makeAreas(-250, -250, 0, 0, 1, 900, 900, 1000, 1000, 1));
+            // Test the maximum number of areas.
+            testValidAreas(type, makeAreas(-1000, -1000, 1000, 1000, 1000, maxNumAreas));
+        }
+
+        // Test various invalid cases.
+        testInvalidAreas(type, makeAreas(-1001, -1000, 1000, 1000, 1));    // left should >= -1000
+        testInvalidAreas(type, makeAreas(-1000, -1001, 1000, 1000, 1));    // top should >= -1000
+        testInvalidAreas(type, makeAreas(-1000, -1000, 1001, 1000, 1));    // right should <= 1000
+        testInvalidAreas(type, makeAreas(-1000, -1000, 1000, 1001, 1));    // bottom should <= 1000
+        testInvalidAreas(type, makeAreas(-1000, -1000, 1000, 1000, 0));    // weight should >= 1
+        testInvalidAreas(type, makeAreas(-1000, -1000, 1000, 1001, 1001)); // weight should <= 1000
+        testInvalidAreas(type, makeAreas(500, -1000, 500, 1000, 1));       // left should < right
+        testInvalidAreas(type, makeAreas(-1000, 500, 1000, 500, 1));       // top should < bottom
+        testInvalidAreas(type, makeAreas(500, -1000, 499, 1000, 1));       // left should < right
+        testInvalidAreas(type, makeAreas(-1000, 500, 100, 499, 1));        // top should < bottom
+        testInvalidAreas(type, makeAreas(-250, -250, 250, 250, -1));       // weight should >= 1
+        // Test when the number of areas exceeds maximum.
+        testInvalidAreas(type, makeAreas(-1000, -1000, 1000, 1000, 1000, maxNumAreas + 1));
+    }
+
+    private static ArrayList<Area> makeAreas(int left, int top, int right, int bottom, int weight) {
+        ArrayList<Area> areas = new ArrayList<Area>();
+        areas.add(new Area(new Rect(left, top, right, bottom), weight));
+        return areas;
+    }
+
+    private static ArrayList<Area> makeAreas(int left, int top, int right, int bottom,
+            int weight, int number) {
+        ArrayList<Area> areas = new ArrayList<Area>();
+        for (int i = 0; i < number; i++) {
+            areas.add(new Area(new Rect(left, top, right, bottom), weight));
+        }
+        return areas;
+    }
+
+    private static ArrayList<Area> makeAreas(int left1, int top1, int right1,
+            int bottom1, int weight1, int left2, int top2, int right2,
+            int bottom2, int weight2) {
+        ArrayList<Area> areas = new ArrayList<Area>();
+        areas.add(new Area(new Rect(left1, top1, right1, bottom1), weight1));
+        areas.add(new Area(new Rect(left2, top2, right2, bottom2), weight2));
+        return areas;
+    }
+
+    private void testValidAreas(int areaType, ArrayList<Area> areas) {
+        if (areaType == FOCUS_AREA) {
+            testValidFocusAreas(areas);
+        } else {
+            testValidMeteringAreas(areas);
+        }
+    }
+
+    private void testInvalidAreas(int areaType, ArrayList<Area> areas) {
+        if (areaType == FOCUS_AREA) {
+            testInvalidFocusAreas(areas);
+        } else {
+            testInvalidMeteringAreas(areas);
+        }
+    }
+
+    private void testValidFocusAreas(ArrayList<Area> areas) {
+        Parameters parameters = mCamera.getParameters();
+        parameters.setFocusAreas(areas);
+        mCamera.setParameters(parameters);
+        parameters = mCamera.getParameters();
+        assertEquals(areas, parameters.getFocusAreas());
+        mCamera.autoFocus(mAutoFocusCallback);
+        waitForFocusDone();
+    }
+
+    private void testInvalidFocusAreas(ArrayList<Area> areas) {
+        Parameters parameters = mCamera.getParameters();
+        List<Area> originalAreas = parameters.getFocusAreas();
+        try {
+            parameters.setFocusAreas(areas);
+            mCamera.setParameters(parameters);
+            fail("Should throw exception when focus area is invalid.");
+        } catch (RuntimeException e) {
+            parameters = mCamera.getParameters();
+            assertEquals(originalAreas, parameters.getFocusAreas());
+        }
+    }
+
+    private void testValidMeteringAreas(ArrayList<Area> areas) {
+        Parameters parameters = mCamera.getParameters();
+        parameters.setMeteringAreas(areas);
+        mCamera.setParameters(parameters);
+        parameters = mCamera.getParameters();
+        assertEquals(areas, parameters.getMeteringAreas());
+    }
+
+    private void testInvalidMeteringAreas(ArrayList<Area> areas) {
+        Parameters parameters = mCamera.getParameters();
+        List<Area> originalAreas = parameters.getMeteringAreas();
+        try {
+            parameters.setMeteringAreas(areas);
+            mCamera.setParameters(parameters);
+            fail("Should throw exception when metering area is invalid.");
+        } catch (RuntimeException e) {
+            parameters = mCamera.getParameters();
+            assertEquals(originalAreas, parameters.getMeteringAreas());
+        }
+    }
+
+    // Apps should be able to call startPreview in jpeg callback.
+    @UiThreadTest
+    public void testJpegCallbackStartPreview() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testJpegCallbackStartPreviewByCamera(id);
+        }
+    }
+
+    private void testJpegCallbackStartPreviewByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        mCamera.startPreview();
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback, new JpegStartPreviewCallback());
+        waitForSnapshotDone();
+        terminateMessageLooper();
+        assertTrue(mJpegPictureCallbackResult);
+    }
+
+    private final class JpegStartPreviewCallback implements PictureCallback {
+        public void onPictureTaken(byte[] rawData, Camera camera) {
+            try {
+                camera.startPreview();
+                mJpegPictureCallbackResult = true;
+            } catch (Exception e) {
+            }
+            mSnapshotDone.open();
+        }
+    }
+
+    @UiThreadTest
+    public void testRecordingHint() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testRecordingHintByCamera(id);
+        }
+    }
+
+    private void testRecordingHintByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        Parameters parameters = mCamera.getParameters();
+
+        SurfaceHolder holder = getActivity().getSurfaceView().getHolder();
+        CamcorderProfile profile = CamcorderProfile.get(cameraId,
+                CamcorderProfile.QUALITY_LOW);
+
+        setPreviewSizeByProfile(parameters, profile);
+
+        // Test recording videos and taking pictures when the hint is off and on.
+        for (int i = 0; i < 2; i++) {
+            parameters.setRecordingHint(i == 0 ? false : true);
+            mCamera.setParameters(parameters);
+            mCamera.startPreview();
+            recordVideoSimple(profile, holder);
+            mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+            waitForSnapshotDone();
+            assertTrue(mJpegPictureCallbackResult);
+        }
+
+        // Can change recording hint when the preview is active.
+        mCamera.startPreview();
+        parameters.setRecordingHint(false);
+        mCamera.setParameters(parameters);
+        parameters.setRecordingHint(true);
+        mCamera.setParameters(parameters);
+        terminateMessageLooper();
+    }
+
+    private void recordVideoSimple(CamcorderProfile profile,
+            SurfaceHolder holder) throws Exception {
+        mCamera.unlock();
+        MediaRecorder recorder = new MediaRecorder();
+        try {
+            recorder.setCamera(mCamera);
+            recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+            recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+            recorder.setProfile(profile);
+            recorder.setOutputFile("/dev/null");
+            recorder.setPreviewDisplay(holder.getSurface());
+            recorder.prepare();
+            recorder.start();
+            Thread.sleep(2000);
+            recorder.stop();
+        } finally {
+            recorder.release();
+            mCamera.lock();
+        }
+    }
+
+    @UiThreadTest
+    public void testAutoExposureLock() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            initializeMessageLooper(id);
+            Parameters parameters = mCamera.getParameters();
+            boolean aeLockSupported = parameters.isAutoExposureLockSupported();
+            if (aeLockSupported) {
+                subtestLockCommon(AUTOEXPOSURE_LOCK);
+                subtestLockAdditionalAE();
+            }
+            terminateMessageLooper();
+        }
+    }
+
+    @UiThreadTest
+    public void testAutoWhiteBalanceLock() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            initializeMessageLooper(id);
+            Parameters parameters = mCamera.getParameters();
+            boolean awbLockSupported = parameters.isAutoWhiteBalanceLockSupported();
+            if (awbLockSupported) {
+                subtestLockCommon(AUTOWHITEBALANCE_LOCK);
+                subtestLockAdditionalAWB();
+            }
+            terminateMessageLooper();
+        }
+    }
+
+    @UiThreadTest
+    public void test3ALockInteraction() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            initializeMessageLooper(id);
+            Parameters parameters = mCamera.getParameters();
+            boolean locksSupported =
+                    parameters.isAutoWhiteBalanceLockSupported() &&
+                    parameters.isAutoExposureLockSupported();
+            if (locksSupported) {
+                subtestLockInteractions();
+            }
+            terminateMessageLooper();
+        }
+    }
+
+    private void subtestLockCommon(int type) {
+        // Verify lock is not set on open()
+        assert3ALockState("Lock not released after open()", type, false);
+
+        // Verify lock can be set, unset before preview
+        set3ALockState(true, type);
+        assert3ALockState("Lock could not be set before 1st preview!",
+                type, true);
+
+        set3ALockState(false, type);
+        assert3ALockState("Lock could not be unset before 1st preview!",
+                type, false);
+
+        // Verify preview start does not set lock
+        mCamera.startPreview();
+        assert3ALockState("Lock state changed by preview start!", type, false);
+
+        // Verify lock can be set, unset during preview
+        set3ALockState(true, type);
+        assert3ALockState("Lock could not be set during preview!", type, true);
+
+        set3ALockState(false, type);
+        assert3ALockState("Lock could not be unset during preview!",
+                type, false);
+
+        // Verify lock is not cleared by stop preview
+        set3ALockState(true, type);
+        mCamera.stopPreview();
+        assert3ALockState("Lock was cleared by stopPreview!", type, true);
+
+        // Verify that preview start does not clear lock
+        set3ALockState(true, type);
+        mCamera.startPreview();
+        assert3ALockState("Lock state changed by preview start!", type, true);
+
+        // Verify that taking a picture does not clear the lock
+        set3ALockState(true, type);
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback,
+                mJpegPictureCallback);
+        waitForSnapshotDone();
+        assert3ALockState("Lock state was cleared by takePicture!", type, true);
+
+        mCamera.startPreview();
+        Parameters parameters = mCamera.getParameters();
+        for (String focusMode: parameters.getSupportedFocusModes()) {
+            // TODO: Test this for other focus modes as well, once agreement is
+            // reached on which ones it should apply to
+            if (!Parameters.FOCUS_MODE_AUTO.equals(focusMode) ) {
+                continue;
+            }
+
+            parameters.setFocusMode(focusMode);
+            mCamera.setParameters(parameters);
+
+            // Verify that autoFocus does not change the lock
+            set3ALockState(false, type);
+            mCamera.autoFocus(mAutoFocusCallback);
+            assert3ALockState("Lock was set by autoFocus in mode: " + focusMode, type, false);
+            assertTrue(waitForFocusDone());
+            assert3ALockState("Lock was set by autoFocus in mode: " + focusMode, type, false);
+
+            // Verify that cancelAutoFocus does not change the lock
+            mCamera.cancelAutoFocus();
+            assert3ALockState("Lock was set by cancelAutoFocus!", type, false);
+
+            // Verify that autoFocus does not change the lock
+            set3ALockState(true, type);
+            mCamera.autoFocus(mAutoFocusCallback);
+            assert3ALockState("Lock was cleared by autoFocus in mode: " + focusMode, type, true);
+            assertTrue(waitForFocusDone());
+            assert3ALockState("Lock was cleared by autoFocus in mode: " + focusMode, type, true);
+
+            // Verify that cancelAutoFocus does not change the lock
+            mCamera.cancelAutoFocus();
+            assert3ALockState("Lock was cleared by cancelAutoFocus!", type, true);
+        }
+        mCamera.stopPreview();
+    }
+
+    private void subtestLockAdditionalAE() {
+        // Verify that exposure compensation can be used while
+        // AE lock is active
+        mCamera.startPreview();
+        Parameters parameters = mCamera.getParameters();
+        parameters.setAutoExposureLock(true);
+        mCamera.setParameters(parameters);
+        parameters.setExposureCompensation(parameters.getMaxExposureCompensation());
+        mCamera.setParameters(parameters);
+        parameters = mCamera.getParameters();
+        assertTrue("Could not adjust exposure compensation with AE locked!",
+                parameters.getExposureCompensation() ==
+                parameters.getMaxExposureCompensation() );
+
+        parameters.setExposureCompensation(parameters.getMinExposureCompensation());
+        mCamera.setParameters(parameters);
+        parameters = mCamera.getParameters();
+        assertTrue("Could not adjust exposure compensation with AE locked!",
+                parameters.getExposureCompensation() ==
+                parameters.getMinExposureCompensation() );
+        mCamera.stopPreview();
+    }
+
+    private void subtestLockAdditionalAWB() {
+        // Verify that switching AWB modes clears AWB lock
+        mCamera.startPreview();
+        Parameters parameters = mCamera.getParameters();
+        String firstWb = null;
+        for ( String wbMode: parameters.getSupportedWhiteBalance() ) {
+            if (firstWb == null) {
+                firstWb = wbMode;
+            }
+            parameters.setWhiteBalance(firstWb);
+            mCamera.setParameters(parameters);
+            parameters.setAutoWhiteBalanceLock(true);
+            mCamera.setParameters(parameters);
+
+            parameters.setWhiteBalance(wbMode);
+            mCamera.setParameters(parameters);
+
+            if (firstWb == wbMode) {
+                assert3ALockState("AWB lock was cleared when WB mode was unchanged!",
+                        AUTOWHITEBALANCE_LOCK, true);
+            } else {
+                assert3ALockState("Changing WB mode did not clear AWB lock!",
+                        AUTOWHITEBALANCE_LOCK, false);
+            }
+        }
+        mCamera.stopPreview();
+    }
+
+    private void subtestLockInteractions() {
+        // Verify that toggling AE does not change AWB lock state
+        set3ALockState(false, AUTOWHITEBALANCE_LOCK);
+        set3ALockState(false, AUTOEXPOSURE_LOCK);
+
+        set3ALockState(true, AUTOEXPOSURE_LOCK);
+        assert3ALockState("Changing AE lock affected AWB lock!",
+                AUTOWHITEBALANCE_LOCK, false);
+
+        set3ALockState(false, AUTOEXPOSURE_LOCK);
+        assert3ALockState("Changing AE lock affected AWB lock!",
+                AUTOWHITEBALANCE_LOCK, false);
+
+        set3ALockState(true, AUTOWHITEBALANCE_LOCK);
+
+        set3ALockState(true, AUTOEXPOSURE_LOCK);
+        assert3ALockState("Changing AE lock affected AWB lock!",
+                AUTOWHITEBALANCE_LOCK, true);
+
+        set3ALockState(false, AUTOEXPOSURE_LOCK);
+        assert3ALockState("Changing AE lock affected AWB lock!",
+                AUTOWHITEBALANCE_LOCK, true);
+
+        // Verify that toggling AWB does not change AE lock state
+        set3ALockState(false, AUTOWHITEBALANCE_LOCK);
+        set3ALockState(false, AUTOEXPOSURE_LOCK);
+
+        set3ALockState(true, AUTOWHITEBALANCE_LOCK);
+        assert3ALockState("Changing AWB lock affected AE lock!",
+                AUTOEXPOSURE_LOCK, false);
+
+        set3ALockState(false, AUTOWHITEBALANCE_LOCK);
+        assert3ALockState("Changing AWB lock affected AE lock!",
+                AUTOEXPOSURE_LOCK, false);
+
+        set3ALockState(true, AUTOEXPOSURE_LOCK);
+
+        set3ALockState(true, AUTOWHITEBALANCE_LOCK);
+        assert3ALockState("Changing AWB lock affected AE lock!",
+                AUTOEXPOSURE_LOCK, true);
+
+        set3ALockState(false, AUTOWHITEBALANCE_LOCK);
+        assert3ALockState("Changing AWB lock affected AE lock!",
+                AUTOEXPOSURE_LOCK, true);
+    }
+
+    private void assert3ALockState(String msg, int type, boolean state) {
+        Parameters parameters = mCamera.getParameters();
+        switch (type) {
+            case AUTOEXPOSURE_LOCK:
+                assertTrue(msg, state == parameters.getAutoExposureLock());
+                break;
+            case AUTOWHITEBALANCE_LOCK:
+                assertTrue(msg, state == parameters.getAutoWhiteBalanceLock());
+                break;
+            default:
+                assertTrue("Unknown lock type " + type, false);
+                break;
+        }
+    }
+
+    private void set3ALockState(boolean state, int type) {
+        Parameters parameters = mCamera.getParameters();
+        switch (type) {
+            case AUTOEXPOSURE_LOCK:
+                parameters.setAutoExposureLock(state);
+                break;
+            case AUTOWHITEBALANCE_LOCK:
+                parameters.setAutoWhiteBalanceLock(state);
+                break;
+            default:
+                assertTrue("Unknown lock type "+type, false);
+                break;
+        }
+        mCamera.setParameters(parameters);
+    }
+
+    @UiThreadTest
+    public void testFaceDetection() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testFaceDetectionByCamera(id);
+        }
+    }
+
+    private void testFaceDetectionByCamera(int cameraId) throws Exception {
+        final int FACE_DETECTION_TEST_DURATION = 3000;
+        initializeMessageLooper(cameraId);
+        mCamera.startPreview();
+        Parameters parameters = mCamera.getParameters();
+        int maxNumOfFaces = parameters.getMaxNumDetectedFaces();
+        assertTrue(maxNumOfFaces >= 0);
+        if (maxNumOfFaces == 0) {
+            try {
+                mCamera.startFaceDetection();
+                fail("Should throw an exception if face detection is not supported.");
+            } catch (IllegalArgumentException e) {
+                // expected
+            }
+            terminateMessageLooper();
+            return;
+        }
+
+        mCamera.startFaceDetection();
+        try {
+            mCamera.startFaceDetection();
+            fail("Starting face detection twice should throw an exception");
+        } catch (RuntimeException e) {
+            // expected
+        }
+        FaceListener listener = new FaceListener();
+        mCamera.setFaceDetectionListener(listener);
+        // Sleep some time so the camera has chances to detect faces.
+        Thread.sleep(FACE_DETECTION_TEST_DURATION);
+        // The face callback runs in another thread. Release the camera and stop
+        // the looper. So we do not access the face array from two threads at
+        // the same time.
+        terminateMessageLooper();
+
+        // Check if the optional fields are supported.
+        boolean optionalFieldSupported = false;
+        Face firstFace = null;
+        for (Face[] faces: listener.mFacesArray) {
+            for (Face face: faces) {
+                if (face != null) firstFace = face;
+            }
+        }
+        if (firstFace != null) {
+            if (firstFace.id != -1 || firstFace.leftEye != null
+                    || firstFace.rightEye != null || firstFace.mouth != null) {
+                optionalFieldSupported = true;
+            }
+        }
+
+        // Verify the faces array.
+        for (Face[] faces: listener.mFacesArray) {
+            testFaces(faces, maxNumOfFaces, optionalFieldSupported);
+        }
+
+        // After taking a picture, face detection should be started again.
+        // Also make sure autofocus move callback is supported.
+        initializeMessageLooper(cameraId);
+        mCamera.setAutoFocusMoveCallback(mAutoFocusMoveCallback);
+        mCamera.startPreview();
+        mCamera.startFaceDetection();
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
+        waitForSnapshotDone();
+        mCamera.startPreview();
+        mCamera.startFaceDetection();
+        terminateMessageLooper();
+    }
+
+    private class FaceListener implements FaceDetectionListener {
+        public ArrayList<Face[]> mFacesArray = new ArrayList<Face[]>();
+
+        @Override
+        public void onFaceDetection(Face[] faces, Camera camera) {
+            mFacesArray.add(faces);
+        }
+    }
+
+    private void testFaces(Face[] faces, int maxNumOfFaces,
+            boolean optionalFieldSupported) {
+        Rect bounds = new Rect(-1000, -1000, 1000, 1000);
+        assertNotNull(faces);
+        assertTrue(faces.length <= maxNumOfFaces);
+        for (int i = 0; i < faces.length; i++) {
+            Face face = faces[i];
+            Rect rect = face.rect;
+            // Check the bounds.
+            assertNotNull(rect);
+            assertTrue(rect.width() > 0);
+            assertTrue(rect.height() > 0);
+            assertTrue("Coordinates out of bounds. rect=" + rect,
+                    bounds.contains(rect) || Rect.intersects(bounds, rect));
+
+            // Check the score.
+            assertTrue(face.score >= 1 && face.score <= 100);
+
+            // Check id, left eye, right eye, and the mouth.
+            // Optional fields should be all valid or none of them.
+            if (!optionalFieldSupported) {
+                assertEquals(-1, face.id);
+                assertNull(face.leftEye);
+                assertNull(face.rightEye);
+                assertNull(face.mouth);
+            } else {
+                assertTrue(face.id != -1);
+                assertNotNull(face.leftEye);
+                assertNotNull(face.rightEye);
+                assertNotNull(face.mouth);
+                assertTrue(bounds.contains(face.leftEye.x, face.leftEye.y));
+                assertTrue(bounds.contains(face.rightEye.x, face.rightEye.y));
+                assertTrue(bounds.contains(face.mouth.x, face.mouth.y));
+                // ID should be unique.
+                if (i != faces.length - 1) {
+                    assertTrue(face.id != faces[i + 1].id);
+                }
+            }
+        }
+    }
+
+    @UiThreadTest
+    public void testVideoSnapshot() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testVideoSnapshotByCamera(id);
+        }
+    }
+
+    private static final int[] mCamcorderProfileList = {
+        CamcorderProfile.QUALITY_2160P,
+        CamcorderProfile.QUALITY_1080P,
+        CamcorderProfile.QUALITY_480P,
+        CamcorderProfile.QUALITY_720P,
+        CamcorderProfile.QUALITY_CIF,
+        CamcorderProfile.QUALITY_HIGH,
+        CamcorderProfile.QUALITY_LOW,
+        CamcorderProfile.QUALITY_QCIF,
+        CamcorderProfile.QUALITY_QVGA,
+    };
+
+    private void testVideoSnapshotByCamera(int cameraId) throws Exception {
+        initializeMessageLooper(cameraId);
+        Camera.Parameters parameters = mCamera.getParameters();
+        terminateMessageLooper();
+        if (!parameters.isVideoSnapshotSupported()) {
+            return;
+        }
+
+        SurfaceHolder holder = getActivity().getSurfaceView().getHolder();
+
+        for (int profileId: mCamcorderProfileList) {
+            if (!CamcorderProfile.hasProfile(cameraId, profileId)) {
+                continue;
+            }
+            initializeMessageLooper(cameraId);
+            // Set the preview size.
+            CamcorderProfile profile = CamcorderProfile.get(cameraId,
+                    profileId);
+            setPreviewSizeByProfile(parameters, profile);
+
+            // Set the biggest picture size.
+            Size biggestSize = mCamera.new Size(-1, -1);
+            for (Size size: parameters.getSupportedPictureSizes()) {
+                if (biggestSize.width < size.width) {
+                    biggestSize = size;
+                }
+            }
+            parameters.setPictureSize(biggestSize.width, biggestSize.height);
+
+            mCamera.setParameters(parameters);
+            mCamera.startPreview();
+            mCamera.unlock();
+            MediaRecorder recorder = new MediaRecorder();
+            try {
+                recorder.setCamera(mCamera);
+                recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
+                recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
+                recorder.setProfile(profile);
+                recorder.setOutputFile("/dev/null");
+                recorder.setPreviewDisplay(holder.getSurface());
+                recorder.prepare();
+                recorder.start();
+                subtestTakePictureByCamera(true,
+                        profile.videoFrameWidth, profile.videoFrameHeight);
+                testJpegExifByCamera(true);
+                testJpegThumbnailSizeByCamera(true,
+                        profile.videoFrameWidth, profile.videoFrameHeight);
+                Thread.sleep(2000);
+                recorder.stop();
+            } finally {
+                recorder.release();
+                mCamera.lock();
+            }
+            mCamera.stopPreview();
+            terminateMessageLooper();
+        }
+    }
+
+    public void testPreviewCallbackWithPicture() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testPreviewCallbackWithPictureByCamera(id);
+        }
+    }
+
+    private void testPreviewCallbackWithPictureByCamera(int cameraId)
+            throws Exception {
+        initializeMessageLooper(cameraId);
+
+        SimplePreviewStreamCb callback = new SimplePreviewStreamCb(1);
+        mCamera.setPreviewCallback(callback);
+
+        Log.v(TAG, "Starting preview");
+        mCamera.startPreview();
+
+        // Wait until callbacks are flowing
+        for (int i = 0; i < 30; i++) {
+            assertTrue("testPreviewCallbackWithPicture: Not receiving preview callbacks!",
+                    mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE ) );
+            mPreviewDone.close();
+        }
+
+        // Now take a picture
+        Log.v(TAG, "Taking picture now");
+
+        Size pictureSize = mCamera.getParameters().getPictureSize();
+        mCamera.takePicture(mShutterCallback, mRawPictureCallback,
+                mJpegPictureCallback);
+
+        waitForSnapshotDone();
+
+        assertTrue("Shutter callback not received", mShutterCallbackResult);
+        assertTrue("Raw picture callback not received", mRawPictureCallbackResult);
+        assertTrue("Jpeg picture callback not received", mJpegPictureCallbackResult);
+        assertNotNull(mJpegData);
+        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
+        bmpOptions.inJustDecodeBounds = true;
+        BitmapFactory.decodeByteArray(mJpegData, 0, mJpegData.length, bmpOptions);
+        assertEquals(pictureSize.width, bmpOptions.outWidth);
+        assertEquals(pictureSize.height, bmpOptions.outHeight);
+
+        // Restart preview, confirm callbacks still happen
+        Log.v(TAG, "Restarting preview");
+        mCamera.startPreview();
+
+        for (int i = 0; i < 30; i++) {
+            assertTrue("testPreviewCallbackWithPicture: Not receiving preview callbacks!",
+                    mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE ) );
+            mPreviewDone.close();
+        }
+
+        mCamera.stopPreview();
+
+        terminateMessageLooper();
+    }
+
+    public void testEnableShutterSound() throws Exception {
+        int nCameras = Camera.getNumberOfCameras();
+        for (int id = 0; id < nCameras; id++) {
+            Log.v(TAG, "Camera id=" + id);
+            testEnableShutterSoundByCamera(id);
+        }
+    }
+
+    private void testEnableShutterSoundByCamera(int id) throws Exception {
+        CameraInfo info = new CameraInfo();
+
+        Camera.getCameraInfo(id, info);
+
+        initializeMessageLooper(id);
+
+        boolean result;
+        Log.v(TAG, "testEnableShutterSoundByCamera: canDisableShutterSound: " +
+                info.canDisableShutterSound);
+        result = mCamera.enableShutterSound(false);
+        assertTrue(result == info.canDisableShutterSound);
+        result = mCamera.enableShutterSound(true);
+        assertTrue(result);
+
+        terminateMessageLooper();
+    }
+
+    public void testCameraExternalConnected() {
+        if (getActivity().getPackageManager().
+                hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL) ) {
+            int nCameras = Camera.getNumberOfCameras();
+            assertTrue("Devices with external camera support must have a camera connected for " +
+                    "testing",
+                    nCameras > 0);
+            for (int id = 0; id < nCameras; id++) {
+                try {
+                    Camera c = Camera.open(id);
+                    c.release();
+                } catch (Throwable e) {
+                    throw new AssertionError("Devices with external camera support must " +
+                            "have all listed cameras be connected and openable for testing", e);
+                }
+            }
+        }
+    }
+
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/Camera_ParametersTest.java b/tests/camera/src/android/hardware/cts/Camera_ParametersTest.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/cts/Camera_ParametersTest.java
rename to tests/camera/src/android/hardware/cts/Camera_ParametersTest.java
diff --git a/tests/tests/hardware/src/android/hardware/cts/Camera_SizeTest.java b/tests/camera/src/android/hardware/cts/Camera_SizeTest.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/cts/Camera_SizeTest.java
rename to tests/camera/src/android/hardware/cts/Camera_SizeTest.java
diff --git a/tests/tests/hardware/src/android/hardware/cts/GLSurfaceViewCtsActivity.java b/tests/camera/src/android/hardware/cts/GLSurfaceViewCtsActivity.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/cts/GLSurfaceViewCtsActivity.java
rename to tests/camera/src/android/hardware/cts/GLSurfaceViewCtsActivity.java
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/CameraUtils.java b/tests/camera/src/android/hardware/cts/helpers/CameraUtils.java
similarity index 100%
rename from tests/tests/hardware/src/android/hardware/cts/helpers/CameraUtils.java
rename to tests/camera/src/android/hardware/cts/helpers/CameraUtils.java
diff --git a/tests/camera/src/android/hardware/multiprocess/camera/cts/Camera1Activity.java b/tests/camera/src/android/hardware/multiprocess/camera/cts/Camera1Activity.java
new file mode 100644
index 0000000..3908334
--- /dev/null
+++ b/tests/camera/src/android/hardware/multiprocess/camera/cts/Camera1Activity.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.hardware.Camera;
+import android.os.Bundle;
+import android.util.Log;
+
+/**
+ * Activity implementing basic access of the Camera1 API.
+ *
+ * <p />
+ * This will log all errors to {@link android.hardware.multiprocess.camera.cts.ErrorLoggingService}.
+ */
+public class Camera1Activity extends Activity {
+    private static final String TAG = "Camera1Activity";
+
+    Camera mCamera;
+    ErrorLoggingService.ErrorServiceConnection mErrorServiceConnection;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        Log.i(TAG, "onCreate called.");
+        super.onCreate(savedInstanceState);
+        mErrorServiceConnection = new ErrorLoggingService.ErrorServiceConnection(this);
+        mErrorServiceConnection.start();
+    }
+
+    @Override
+    protected void onResume() {
+        Log.i(TAG, "onResume called.");
+        super.onResume();
+        try {
+            mCamera = Camera.open();
+            if (mCamera == null) {
+                mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_ERROR, TAG +
+                        " no cameras available.");
+            }
+            mCamera.setErrorCallback(new Camera.ErrorCallback() {
+                @Override
+                public void onError(int i, Camera camera) {
+                    if (i == Camera.CAMERA_ERROR_EVICTED) {
+                        mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_EVICTED,
+                                TAG + " camera evicted");
+                        Log.e(TAG, "onError called with event " + i + ", camera evicted");
+                    } else {
+                        mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_ERROR,
+                                TAG + " camera experienced error: " + i);
+                        Log.e(TAG, "onError called with event " + i + ", camera error");
+                    }
+                }
+            });
+            mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_CONNECT,
+                    TAG + " camera connected");
+        } catch (RuntimeException 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;
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/multiprocess/camera/cts/Camera2Activity.java b/tests/camera/src/android/hardware/multiprocess/camera/cts/Camera2Activity.java
new file mode 100644
index 0000000..418eb7c
--- /dev/null
+++ b/tests/camera/src/android/hardware/multiprocess/camera/cts/Camera2Activity.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.content.Context;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.util.Log;
+
+/**
+ * Activity implementing basic access of the Camera2 API.
+ *
+ * <p />
+ * This will log all errors to {@link android.hardware.multiprocess.camera.cts.ErrorLoggingService}.
+ */
+public class Camera2Activity extends Activity {
+    private static final String TAG = "Camera2Activity";
+
+    ErrorLoggingService.ErrorServiceConnection mErrorServiceConnection;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        Log.i(TAG, "onCreate called.");
+        super.onCreate(savedInstanceState);
+        mErrorServiceConnection = new ErrorLoggingService.ErrorServiceConnection(this);
+        mErrorServiceConnection.start();
+    }
+
+    @Override
+    protected void onPause() {
+        Log.i(TAG, "onPause called.");
+        super.onPause();
+    }
+
+    @Override
+    protected void onResume() {
+        Log.i(TAG, "onResume called.");
+        super.onResume();
+
+        try {
+            CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
+
+            if (manager == null) {
+                mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_ERROR, TAG +
+                        " could not connect camera service");
+                return;
+            }
+            String[] cameraIds = manager.getCameraIdList();
+
+            if (cameraIds == null || cameraIds.length == 0) {
+                mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_ERROR, TAG +
+                        " device reported having no cameras");
+                return;
+            }
+
+            manager.registerAvailabilityCallback(new CameraManager.AvailabilityCallback() {
+                @Override
+                public void onCameraAvailable(String cameraId) {
+                    super.onCameraAvailable(cameraId);
+                    mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_AVAILABLE,
+                            cameraId);
+                    Log.i(TAG, "Camera " + cameraId + " is available");
+                }
+
+                @Override
+                public void onCameraUnavailable(String cameraId) {
+                    super.onCameraUnavailable(cameraId);
+                    mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_UNAVAILABLE,
+                            cameraId);
+                    Log.i(TAG, "Camera " + cameraId + " is unavailable");
+                }
+            }, null);
+
+            final String chosen = cameraIds[0];
+
+            manager.openCamera(chosen, new CameraDevice.StateCallback() {
+                @Override
+                public void onOpened(CameraDevice cameraDevice) {
+                    mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_CONNECT,
+                            chosen);
+                    Log.i(TAG, "Camera " + chosen + " is opened");
+                }
+
+                @Override
+                public void onDisconnected(CameraDevice cameraDevice) {
+                    mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_EVICTED,
+                            chosen);
+                    Log.i(TAG, "Camera " + chosen + " is disconnected");
+                }
+
+                @Override
+                public void onError(CameraDevice cameraDevice, int i) {
+                    mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_ERROR, TAG +
+                            " Camera " + chosen + " experienced error " + i);
+                    Log.e(TAG, "Camera " + chosen + " onError called with error " + i);
+                }
+            }, null);
+        } catch (CameraAccessException e) {
+            mErrorServiceConnection.logAsync(TestConstants.EVENT_CAMERA_ERROR, TAG +
+                    " camera exception during connection: " + e);
+            Log.e(TAG, "Access exception: " + e);
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.i(TAG, "onDestroy called.");
+        super.onDestroy();
+        if (mErrorServiceConnection != null) {
+            mErrorServiceConnection.stop();
+            mErrorServiceConnection = null;
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java b/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
new file mode 100644
index 0000000..9f1ae03
--- /dev/null
+++ b/tests/camera/src/android/hardware/multiprocess/camera/cts/CameraEvictionTest.java
@@ -0,0 +1,514 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.app.ActivityManager;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.Camera;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraDevice;
+import android.hardware.camera2.CameraManager;
+import android.hardware.cts.CameraCtsActivity;
+import android.os.Handler;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.TimeoutException;
+
+import static org.mockito.Mockito.*;
+
+/**
+ * Tests for multi-process camera usage behavior.
+ */
+public class CameraEvictionTest extends ActivityInstrumentationTestCase2<CameraCtsActivity> {
+
+    public static final String TAG = "CameraEvictionTest";
+
+    private static final int OPEN_TIMEOUT = 2000; // Timeout for camera to open (ms).
+    private static final int SETUP_TIMEOUT = 5000; // Remote camera setup timeout (ms).
+    private static final int EVICTION_TIMEOUT = 1000; // Remote camera eviction timeout (ms).
+    private static final int WAIT_TIME = 2000; // Time to wait for process to launch (ms).
+    private static final int UI_TIMEOUT = 10000; // Time to wait for UI event before timeout (ms).
+    ErrorLoggingService.ErrorServiceConnection mErrorServiceConnection;
+
+    private ActivityManager mActivityManager;
+    private Context mContext;
+    private Camera mCamera;
+    private CameraDevice mCameraDevice;
+    private final Object mLock = new Object();
+    private boolean mCompleted = false;
+    private int mProcessPid = -1;
+
+    public CameraEvictionTest() {
+        super(CameraCtsActivity.class);
+    }
+
+    public static class StateCallbackImpl extends CameraDevice.StateCallback {
+        CameraDevice mCameraDevice;
+
+        public StateCallbackImpl() {
+            super();
+        }
+
+        @Override
+        public void onOpened(CameraDevice cameraDevice) {
+            synchronized(this) {
+                mCameraDevice = cameraDevice;
+            }
+            Log.i(TAG, "CameraDevice onOpened called for main CTS test process.");
+        }
+
+        @Override
+        public void onClosed(CameraDevice camera) {
+            super.onClosed(camera);
+            synchronized(this) {
+                mCameraDevice = null;
+            }
+            Log.i(TAG, "CameraDevice onClosed called for main CTS test process.");
+        }
+
+        @Override
+        public void onDisconnected(CameraDevice cameraDevice) {
+            synchronized(this) {
+                mCameraDevice = null;
+            }
+            Log.i(TAG, "CameraDevice onDisconnected called for main CTS test process.");
+
+        }
+
+        @Override
+        public void onError(CameraDevice cameraDevice, int i) {
+            Log.i(TAG, "CameraDevice onError called for main CTS test process with error " +
+                    "code: " + i);
+        }
+
+        public synchronized CameraDevice getCameraDevice() {
+            return mCameraDevice;
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mCompleted = false;
+        getActivity();
+        mContext = getInstrumentation().getTargetContext();
+        System.setProperty("dexmaker.dexcache", mContext.getCacheDir().toString());
+        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+        mErrorServiceConnection = new ErrorLoggingService.ErrorServiceConnection(mContext);
+        mErrorServiceConnection.start();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mProcessPid != -1) {
+            android.os.Process.killProcess(mProcessPid);
+            mProcessPid = -1;
+        }
+        if (mErrorServiceConnection != null) {
+            mErrorServiceConnection.stop();
+            mErrorServiceConnection = null;
+        }
+        if (mCamera != null) {
+            mCamera.release();
+            mCamera = null;
+        }
+        if (mCameraDevice != null) {
+            mCameraDevice.close();
+            mCameraDevice = null;
+        }
+        mContext = null;
+        mActivityManager = null;
+        super.tearDown();
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * Test basic eviction scenarios for the Camera2 API.
+     */
+    public void testBasicCamera2ActivityEviction() throws Throwable {
+        CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
+        assertNotNull(manager);
+        String[] cameraIds = manager.getCameraIdList();
+
+        if (cameraIds.length == 0) {
+            Log.i(TAG, "Skipping testBasicCamera2ActivityEviction, device has no cameras.");
+            return;
+        }
+
+        assertTrue(mContext.getMainLooper() != null);
+
+        // Setup camera manager
+        String chosenCamera = cameraIds[0];
+        Handler cameraHandler = new Handler(mContext.getMainLooper());
+        final CameraManager.AvailabilityCallback mockAvailCb =
+                mock(CameraManager.AvailabilityCallback.class);
+
+        manager.registerAvailabilityCallback(mockAvailCb, cameraHandler);
+
+        Thread.sleep(WAIT_TIME);
+
+        verify(mockAvailCb, times(1)).onCameraAvailable(chosenCamera);
+        verify(mockAvailCb, never()).onCameraUnavailable(chosenCamera);
+
+        // Setup camera device
+        final CameraDevice.StateCallback spyStateCb = spy(new StateCallbackImpl());
+        manager.openCamera(chosenCamera, spyStateCb, cameraHandler);
+
+        verify(spyStateCb, timeout(OPEN_TIMEOUT).times(1)).onOpened(any(CameraDevice.class));
+        verify(spyStateCb, never()).onClosed(any(CameraDevice.class));
+        verify(spyStateCb, never()).onDisconnected(any(CameraDevice.class));
+        verify(spyStateCb, never()).onError(any(CameraDevice.class), anyInt());
+
+        // Open camera from remote process
+        startRemoteProcess(Camera2Activity.class, "camera2ActivityProcess");
+
+        // Verify that the remote camera was opened correctly
+        List<ErrorLoggingService.LogEvent> allEvents  = mErrorServiceConnection.getLog(SETUP_TIMEOUT,
+                TestConstants.EVENT_CAMERA_CONNECT);
+        assertNotNull("Camera device not setup in remote process!", allEvents);
+
+        // Filter out relevant events for other camera devices
+        ArrayList<ErrorLoggingService.LogEvent> events = new ArrayList<>();
+        for (ErrorLoggingService.LogEvent e : allEvents) {
+            int eventTag = e.getEvent();
+            if (eventTag == TestConstants.EVENT_CAMERA_UNAVAILABLE ||
+                    eventTag == TestConstants.EVENT_CAMERA_CONNECT ||
+                    eventTag == TestConstants.EVENT_CAMERA_AVAILABLE) {
+                if (!Objects.equals(e.getLogText(), chosenCamera)) {
+                    continue;
+                }
+            }
+            events.add(e);
+        }
+        int[] eventList = new int[events.size()];
+        int eventIdx = 0;
+        for (ErrorLoggingService.LogEvent e : events) {
+            eventList[eventIdx++] = e.getEvent();
+        }
+        String[] actualEvents = TestConstants.convertToStringArray(eventList);
+        String[] expectedEvents = new String[] {TestConstants.EVENT_CAMERA_UNAVAILABLE_STR,
+                TestConstants.EVENT_CAMERA_CONNECT_STR};
+        String[] ignoredEvents = new String[] { TestConstants.EVENT_CAMERA_AVAILABLE_STR,
+                TestConstants.EVENT_CAMERA_UNAVAILABLE_STR };
+        assertOrderedEvents(actualEvents, expectedEvents, ignoredEvents);
+
+        // Verify that the local camera was evicted properly
+        verify(spyStateCb, times(1)).onDisconnected(any(CameraDevice.class));
+        verify(spyStateCb, never()).onClosed(any(CameraDevice.class));
+        verify(spyStateCb, never()).onError(any(CameraDevice.class), anyInt());
+        verify(spyStateCb, times(1)).onOpened(any(CameraDevice.class));
+
+        // Verify that we can no longer open the camera, as it is held by a higher priority process
+        boolean openException = false;
+        try {
+            manager.openCamera(chosenCamera, spyStateCb, cameraHandler);
+        } catch(CameraAccessException e) {
+            assertTrue("Received incorrect camera exception when opening camera: " + e,
+                    e.getReason() == CameraAccessException.CAMERA_IN_USE);
+            openException = true;
+        }
+
+        assertTrue("Didn't receive exception when trying to open camera held by higher priority " +
+                "process.", openException);
+
+        // 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.
+     */
+    private void forceCtsActivityToTop() throws InterruptedException {
+        Thread.sleep(WAIT_TIME);
+        Activity a = getActivity();
+        Intent activityIntent = new Intent(a, CameraCtsActivity.class);
+        activityIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        a.startActivity(activityIntent);
+        Thread.sleep(WAIT_TIME);
+    }
+
+    /**
+     * Block until UI thread calls {@link #notifyFromUI()}.
+     * @throws InterruptedException
+     */
+    private void waitForUI() throws InterruptedException {
+        synchronized(mLock) {
+            if (mCompleted) return;
+            while (!mCompleted) {
+                mLock.wait();
+            }
+            mCompleted = false;
+        }
+    }
+
+    /**
+     * Wake up any threads waiting in calls to {@link #waitForUI()}.
+     */
+    private void notifyFromUI() {
+        synchronized (mLock) {
+            mCompleted = true;
+            mLock.notifyAll();
+        }
+    }
+
+    /**
+     * Return the PID for the process with the given name in the given list of process info.
+     *
+     * @param processName the name of the process who's PID to return.
+     * @param list a list of {@link ActivityManager.RunningAppProcessInfo} to check.
+     * @return the PID of the given process, or -1 if it was not included in the list.
+     */
+    private static int getPid(String processName,
+                              List<ActivityManager.RunningAppProcessInfo> list) {
+        for (ActivityManager.RunningAppProcessInfo rai : list) {
+            if (processName.equals(rai.processName))
+                return rai.pid;
+        }
+        return -1;
+    }
+
+    /**
+     * Start an activity of the given class running in a remote process with the given name.
+     *
+     * @param klass the class of the {@link android.app.Activity} to start.
+     * @param processName the remote activity name.
+     * @throws InterruptedException
+     */
+    public void startRemoteProcess(java.lang.Class<?> klass, String processName)
+            throws InterruptedException {
+        // Ensure no running activity process with same name
+        Activity a = getActivity();
+        String cameraActivityName = a.getPackageName() + ":" + processName;
+        List<ActivityManager.RunningAppProcessInfo> list =
+                mActivityManager.getRunningAppProcesses();
+        assertEquals(-1, getPid(cameraActivityName, list));
+
+        // Start activity in a new top foreground process
+        Intent activityIntent = new Intent(a, klass);
+        a.startActivity(activityIntent);
+        Thread.sleep(WAIT_TIME);
+
+        // Fail if activity isn't running
+        list = mActivityManager.getRunningAppProcesses();
+        mProcessPid = getPid(cameraActivityName, list);
+        assertTrue(-1 != mProcessPid);
+    }
+
+    /**
+     * Assert that there is only one event of the given type in the event list.
+     *
+     * @param event event type to check for.
+     * @param events {@link List} of events.
+     */
+    public static void assertOnly(int event, List<ErrorLoggingService.LogEvent> events) {
+        assertTrue("Remote camera activity never received event: " + event, events != null);
+        for (ErrorLoggingService.LogEvent e : events) {
+            assertFalse("Remote camera activity received invalid event (" + e +
+                    ") while waiting for event: " + event,
+                    e.getEvent() < 0 || e.getEvent() != event);
+        }
+        assertTrue("Remote camera activity never received event: " + event, events.size() >= 1);
+        assertTrue("Remote camera activity received too many " + event + " events, received: " +
+                events.size(), events.size() == 1);
+    }
+
+    /**
+     * Assert there were no logEvents in the given list.
+     *
+     * @param msg message to show on assertion failure.
+     * @param events {@link List} of events.
+     */
+    public static void assertNone(String msg, List<ErrorLoggingService.LogEvent> events) {
+        if (events == null) return;
+        StringBuilder builder = new StringBuilder(msg + "\n");
+        for (ErrorLoggingService.LogEvent e : events) {
+            builder.append(e).append("\n");
+        }
+        assertTrue(builder.toString(), events.isEmpty());
+    }
+
+    /**
+     * Assert array is null or empty.
+     *
+     * @param array array to check.
+     */
+    public static <T> void assertNotEmpty(T[] array) {
+        assertNotNull(array);
+        assertFalse("Array is empty: " + Arrays.toString(array), array.length == 0);
+    }
+
+    /**
+     * Given an 'actual' array of objects, check that the objects given in the 'expected'
+     * array are also present in the 'actual' array in the same order.  Objects in the 'actual'
+     * array that are not in the 'expected' array are skipped and ignored if they are given
+     * in the 'ignored' array, otherwise this assertion will fail.
+     *
+     * @param actual the ordered array of objects to check.
+     * @param expected the ordered array of expected objects.
+     * @param ignored the array of objects that will be ignored if present in actual,
+     *                but not in expected (or are out of order).
+     * @param <T>
+     */
+    public static <T> void assertOrderedEvents(T[] actual, T[] expected, T[] ignored) {
+        assertNotNull(actual);
+        assertNotNull(expected);
+        assertNotNull(ignored);
+
+        int expIndex = 0;
+        int index = 0;
+        for (T i : actual) {
+            // If explicitly expected, move to next
+            if (expIndex < expected.length && Objects.equals(i, expected[expIndex])) {
+                expIndex++;
+                continue;
+            }
+
+            // Fail if not ignored
+            boolean canIgnore = false;
+            for (T j : ignored) {
+                if (Objects.equals(i, j)) {
+                    canIgnore = true;
+                    break;
+                }
+
+            }
+
+            // Fail if not ignored.
+            assertTrue("Event at index " + index + " in actual array " +
+                    Arrays.toString(actual) + " was unexpected: expected array was " +
+                    Arrays.toString(expected) + ", ignored array was: " +
+                    Arrays.toString(ignored), canIgnore);
+            index++;
+        }
+        assertTrue("Only had " + expIndex + " of " + expected.length +
+                " expected objects in array " + Arrays.toString(actual) + ", expected was " +
+                Arrays.toString(expected), expIndex == expected.length);
+    }
+}
diff --git a/tests/camera/src/android/hardware/multiprocess/camera/cts/ErrorLoggingService.java b/tests/camera/src/android/hardware/multiprocess/camera/cts/ErrorLoggingService.java
new file mode 100644
index 0000000..a45e024
--- /dev/null
+++ b/tests/camera/src/android/hardware/multiprocess/camera/cts/ErrorLoggingService.java
@@ -0,0 +1,611 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.ConditionVariable;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Pair;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * Service for collecting error messages from other processes.
+ *
+ * <p />
+ * Used by CTS for multi-process error logging.
+ */
+public class ErrorLoggingService extends Service {
+    public static final String TAG = "ErrorLoggingService";
+
+    /**
+     * Receive all currently logged error strings in replyTo Messenger.
+     */
+    public static final int MSG_GET_LOG = 0;
+
+    /**
+     * Append a new error string to the log maintained in this service.
+     */
+    public static final int MSG_LOG_EVENT = 1;
+
+    /**
+     * Logged errors being reported in a replyTo Messenger by this service.
+     */
+    public static final int MSG_LOG_REPORT = 2;
+
+    /**
+     * A list of strings containing all error messages reported to this service.
+     */
+    private final ArrayList<LogEvent> mLog = new ArrayList<>();
+
+    /**
+     * A list of Messengers waiting for logs for any event.
+     */
+    private final ArrayList<Pair<Integer, Messenger>> mEventWaiters = new ArrayList<>();
+
+    private static final int DO_EVENT_FILTER = 1;
+    private static final String LOG_EVENT = "log_event";
+    private static final String LOG_EVENT_ARRAY = "log_event_array";
+
+
+    /**
+     * The messenger binder used by clients of this service to report/retrieve errors.
+     */
+    private final Messenger mMessenger = new Messenger(new MainHandler(mLog, mEventWaiters));
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        mLog.clear();
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return mMessenger.getBinder();
+    }
+
+    /**
+     * Handler implementing the message interface for this service.
+     */
+    private static class MainHandler extends Handler {
+
+        ArrayList<LogEvent> mErrorLog;
+        ArrayList<Pair<Integer, Messenger>> mEventWaiters;
+
+        MainHandler(ArrayList<LogEvent> log, ArrayList<Pair<Integer, Messenger>> waiters) {
+            mErrorLog = log;
+            mEventWaiters = waiters;
+        }
+
+        private void sendMessages() {
+            if (mErrorLog.size() > 0) {
+                ListIterator<Pair<Integer, Messenger>> iter = mEventWaiters.listIterator();
+                boolean messagesHandled = false;
+                while (iter.hasNext()) {
+                    Pair<Integer, Messenger> elem = iter.next();
+                    for (LogEvent i : mErrorLog) {
+                        if (elem.first == null || elem.first == i.getEvent()) {
+                            Message m = Message.obtain(null, MSG_LOG_REPORT);
+                            Bundle b = m.getData();
+                            b.putParcelableArray(LOG_EVENT_ARRAY,
+                                    mErrorLog.toArray(new LogEvent[mErrorLog.size()]));
+                            m.setData(b);
+                            try {
+                                elem.second.send(m);
+                                messagesHandled = true;
+                            } catch (RemoteException e) {
+                                Log.e(TAG, "Could not report log message to remote, " +
+                                        "received exception from remote: " + e +
+                                        "\n  Original errors: " +
+                                        Arrays.toString(mErrorLog.toArray()));
+                            }
+                            iter.remove();
+                        }
+                    }
+                }
+                if (messagesHandled) {
+                    mErrorLog.clear();
+                }
+            }
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case MSG_GET_LOG:
+                    if (msg.replyTo == null) {
+                        break;
+                    }
+
+                    if (msg.arg1 == DO_EVENT_FILTER) {
+                        mEventWaiters.add(new Pair<Integer, Messenger>(msg.arg2, msg.replyTo));
+                    } else {
+                        mEventWaiters.add(new Pair<Integer, Messenger>(null, msg.replyTo));
+                    }
+
+                    sendMessages();
+
+                    break;
+                case MSG_LOG_EVENT:
+                    Bundle b = msg.getData();
+                    b.setClassLoader(LogEvent.class.getClassLoader());
+                    LogEvent error = b.getParcelable(LOG_EVENT);
+                    mErrorLog.add(error);
+
+                    sendMessages();
+
+                    break;
+                default:
+                    Log.e(TAG, "Unknown message type: " + msg.what);
+                    super.handleMessage(msg);
+            }
+        }
+    }
+
+    /**
+     * Parcelable object to use with logged events.
+     */
+    public static class LogEvent implements Parcelable {
+
+        private final int mEvent;
+        private final String mLogText;
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(mEvent);
+            out.writeString(mLogText);
+        }
+
+        public int getEvent() {
+            return mEvent;
+        }
+
+        public String getLogText() {
+            return mLogText;
+        }
+
+        public static final Parcelable.Creator<LogEvent> CREATOR
+                = new Parcelable.Creator<LogEvent>() {
+
+            public LogEvent createFromParcel(Parcel in) {
+                return new LogEvent(in);
+            }
+
+            public LogEvent[] newArray(int size) {
+                return new LogEvent[size];
+            }
+        };
+
+        private LogEvent(Parcel in) {
+            mEvent = in.readInt();
+            mLogText = in.readString();
+        }
+
+        public LogEvent(int id, String msg) {
+            mEvent = id;
+            mLogText = msg;
+        }
+
+        @Override
+        public String toString() {
+            return "LogEvent{" +
+                    "Event=" + mEvent +
+                    ", LogText='" + mLogText + '\'' +
+                    '}';
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            LogEvent logEvent = (LogEvent) o;
+
+            if (mEvent != logEvent.mEvent) return false;
+            if (mLogText != null ? !mLogText.equals(logEvent.mLogText) : logEvent.mLogText != null)
+                return false;
+
+            return true;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = mEvent;
+            result = 31 * result + (mLogText != null ? mLogText.hashCode() : 0);
+            return result;
+        }
+    }
+
+    /**
+     * Implementation of Future to use when retrieving error messages from service.
+     *
+     * <p />
+     * To use this, either pass a {@link Runnable} or {@link Callable} in the constructor,
+     * or use the default constructor and set the result externally with {@link #setResult(Object)}.
+     */
+    private static class SettableFuture<T> extends FutureTask<T> {
+
+        public SettableFuture() {
+            super(new Callable<T>() {
+                @Override
+                public T call() throws Exception {
+                    throw new IllegalStateException(
+                            "Empty task, use #setResult instead of calling run.");
+                }
+            });
+        }
+
+        public SettableFuture(Callable<T> callable) {
+            super(callable);
+        }
+
+        public SettableFuture(Runnable runnable, T result) {
+            super(runnable, result);
+        }
+
+        public void setResult(T result) {
+            set(result);
+        }
+    }
+
+    /**
+     * Helper class for setting up and using a connection to {@link ErrorLoggingService}.
+     */
+    public static class ErrorServiceConnection implements AutoCloseable {
+
+        private Messenger mService = null;
+        private boolean mBind = false;
+        private final Object mLock = new Object();
+        private final Context mContext;
+        private final HandlerThread mReplyThread;
+        private ReplyHandler mReplyHandler;
+        private Messenger mReplyMessenger;
+
+        /**
+         * Construct a connection to the {@link ErrorLoggingService} in the given {@link Context}.
+         *
+         * @param context the {@link Context} to bind the service in.
+         */
+        public ErrorServiceConnection(final Context context) {
+            mContext = context;
+            mReplyThread = new HandlerThread("ErrorServiceConnection");
+            mReplyThread.start();
+            mReplyHandler = new ReplyHandler(mReplyThread.getLooper());
+            mReplyMessenger = new Messenger(mReplyHandler);
+        }
+
+        @Override
+        public void close() {
+            stop();
+            mReplyThread.quit();
+            synchronized (mLock) {
+                mService = null;
+                mBind = false;
+                mReplyHandler.cancelAll();
+            }
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
+            close();
+            super.finalize();
+        }
+
+        private static final class ReplyHandler extends Handler {
+
+            private final LinkedBlockingQueue<SettableFuture<List<LogEvent>>> mFuturesQueue =
+                    new LinkedBlockingQueue<>();
+
+            private ReplyHandler(Looper looper) {
+                super(looper);
+            }
+
+            /**
+             * Cancel all pending futures for this handler.
+             */
+            public void cancelAll() {
+                List<SettableFuture<List<LogEvent>>> logFutures = new ArrayList<>();
+                mFuturesQueue.drainTo(logFutures);
+                for (SettableFuture<List<LogEvent>> i : logFutures) {
+                    i.cancel(true);
+                }
+            }
+
+            /**
+             * Cancel a given future, and remove from the pending futures for this handler.
+             *
+             * @param report future to remove.
+             */
+            public void cancel(SettableFuture<List<LogEvent>> report) {
+                mFuturesQueue.remove(report);
+                report.cancel(true);
+            }
+
+            /**
+             * Add future for the next received report from this service.
+             *
+             * @param report a future to get the next received event report from.
+             */
+            public void addFuture(SettableFuture<List<LogEvent>> report) {
+                if (!mFuturesQueue.offer(report)) {
+                    Log.e(TAG, "Could not request another error report, too many requests queued.");
+                }
+            }
+
+            @SuppressWarnings("unchecked")
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_LOG_REPORT:
+                        SettableFuture<List<LogEvent>> task = mFuturesQueue.poll();
+                        if (task == null) break;
+                        Bundle b = msg.getData();
+                        b.setClassLoader(LogEvent.class.getClassLoader());
+                        Parcelable[] array = b.getParcelableArray(LOG_EVENT_ARRAY);
+                        LogEvent[] events = Arrays.copyOf(array, array.length, LogEvent[].class);
+                        List<LogEvent> res = Arrays.asList(events);
+                        task.setResult(res);
+                        break;
+                    default:
+                        Log.e(TAG, "Unknown message type: " + msg.what);
+                        super.handleMessage(msg);
+                }
+            }
+        }
+
+        private ServiceConnection mConnection = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
+                Log.i(TAG, "Service connected.");
+                synchronized (mLock) {
+                    mService = new Messenger(iBinder);
+                    mBind = true;
+                    mLock.notifyAll();
+                }
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName componentName) {
+                Log.i(TAG, "Service disconnected.");
+                synchronized (mLock) {
+                    mService = null;
+                    mBind = false;
+                    mReplyHandler.cancelAll();
+                }
+            }
+        };
+
+        private Messenger blockingGetBoundService() {
+            synchronized (mLock) {
+                if (!mBind) {
+                    mContext.bindService(new Intent(mContext, ErrorLoggingService.class), mConnection,
+                            Context.BIND_AUTO_CREATE);
+                    mBind = true;
+                }
+                try {
+                    while (mService == null && mBind) {
+                        mLock.wait();
+                    }
+                } catch (InterruptedException e) {
+                    Log.e(TAG, "Waiting for error service interrupted: " + e);
+                }
+                if (!mBind) {
+                    Log.w(TAG, "Could not get service, service disconnected.");
+                }
+                return mService;
+            }
+        }
+
+        private Messenger getBoundService() {
+            synchronized (mLock) {
+                if (!mBind) {
+                    mContext.bindService(new Intent(mContext, ErrorLoggingService.class), mConnection,
+                            Context.BIND_AUTO_CREATE);
+                    mBind = true;
+                }
+                return mService;
+            }
+        }
+
+        /**
+         * If the {@link ErrorLoggingService} is not yet bound, begin service connection attempt.
+         *
+         * <p />
+         * Note: This will not block.
+         */
+        public void start() {
+            synchronized (mLock) {
+                if (!mBind) {
+                    mContext.bindService(new Intent(mContext, ErrorLoggingService.class), mConnection,
+                            Context.BIND_AUTO_CREATE);
+                    mBind = true;
+                }
+            }
+        }
+
+        /**
+         * Unbind from the {@link ErrorLoggingService} if it has been bound.
+         *
+         * <p />
+         * Note: This will not block.
+         */
+        public void stop() {
+            synchronized (mLock) {
+                if (mBind) {
+                    mContext.unbindService(mConnection);
+                    mBind = false;
+                }
+            }
+        }
+
+        /**
+         * Send an logged event to the bound {@link ErrorLoggingService}.
+         *
+         * <p />
+         * If the service is not yet bound, this will bind the service and wait until it has been
+         * connected.
+         *
+         * <p />
+         * This is not safe to call from the UI thread, as this will deadlock with the looper used
+         * when connecting the service.
+         *
+         * @param id an int indicating the ID of this event.
+         * @param msg a {@link String} message to send.
+         */
+        public void log(final int id, final String msg) {
+            Messenger service = blockingGetBoundService();
+            Message m = Message.obtain(null, MSG_LOG_EVENT);
+            m.getData().putParcelable(LOG_EVENT, new LogEvent(id, msg));
+            try {
+                service.send(m);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Received exception while logging error: " + e);
+            }
+        }
+
+        /**
+         * Send an logged event to the bound {@link ErrorLoggingService} when it becomes available.
+         *
+         * <p />
+         * If the service is not yet bound, this will bind the service.
+         *
+         * @param id an int indicating the ID of this event.
+         * @param msg a {@link String} message to send.
+         */
+        public void logAsync(final int id, final String msg) {
+            AsyncTask.SERIAL_EXECUTOR.execute(new Runnable() {
+                @Override
+                public void run() {
+                    log(id, msg);
+                }
+            });
+        }
+
+        /**
+         * Retrieve all events logged in the {@link ErrorLoggingService}.
+         *
+         * <p />
+         * If the service is not yet bound, this will bind the service and wait until it has been
+         * connected.  Likewise, after the service has been bound, this method will block until
+         * the given timeout passes or an event is logged in the service.  Passing a negative
+         * timeout is equivalent to using an infinite timeout value.
+         *
+         * <p />
+         * This is not safe to call from the UI thread, as this will deadlock with the looper used
+         * when connecting the service.
+         *
+         * <p />
+         * Note: This method clears the events stored in the bound {@link ErrorLoggingService}.
+         *
+         * @param timeoutMs the number of milliseconds to wait for a logging event.
+         * @return a list of {@link String} error messages reported to the bound
+         *          {@link ErrorLoggingService} since the last call to getLog.
+         *
+         * @throws TimeoutException if the given timeout elapsed with no events logged.
+         */
+        public List<LogEvent> getLog(long timeoutMs) throws TimeoutException {
+            return retrieveLog(false, 0, timeoutMs);
+        }
+
+        /**
+         * Retrieve all events logged in the {@link ErrorLoggingService}.
+         *
+         * <p />
+         * If the service is not yet bound, this will bind the service and wait until it has been
+         * connected.  Likewise, after the service has been bound, this method will block until
+         * the given timeout passes or an event with the given event ID is logged in the service.
+         * Passing a negative timeout is equivalent to using an infinite timeout value.
+         *
+         * <p />
+         * This is not safe to call from the UI thread, as this will deadlock with the looper used
+         * when connecting the service.
+         *
+         * <p />
+         * Note: This method clears the events stored in the bound {@link ErrorLoggingService}.
+         *
+         * @param timeoutMs the number of milliseconds to wait for a logging event.
+         * @param event the ID of the event to wait for.
+         * @return a list of {@link String} error messages reported to the bound
+         *          {@link ErrorLoggingService} since the last call to getLog.
+         *
+         * @throws TimeoutException if the given timeout elapsed with no events of the given type
+         *          logged.
+         */
+        public List<LogEvent> getLog(long timeoutMs, int event) throws TimeoutException {
+            return retrieveLog(true, event, timeoutMs);
+        }
+
+        private List<LogEvent> retrieveLog(boolean hasEvent, int event, long timeout)
+                throws TimeoutException {
+            Messenger service = blockingGetBoundService();
+
+            SettableFuture<List<LogEvent>> task = new SettableFuture<>();
+
+            Message m = (hasEvent) ?
+                    Message.obtain(null, MSG_GET_LOG, DO_EVENT_FILTER, event, null) :
+                    Message.obtain(null, MSG_GET_LOG);
+            m.replyTo = mReplyMessenger;
+
+            synchronized(this) {
+                mReplyHandler.addFuture(task);
+                try {
+                    service.send(m);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Received exception while retrieving errors: " + e);
+                    return null;
+                }
+            }
+
+            List<LogEvent> res = null;
+            try {
+                res = (timeout < 0) ? task.get() : task.get(timeout, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException|ExecutionException e) {
+                Log.e(TAG, "Received exception while retrieving errors: " + e);
+            }
+            return res;
+        }
+    }
+}
diff --git a/tests/camera/src/android/hardware/multiprocess/camera/cts/TestConstants.java b/tests/camera/src/android/hardware/multiprocess/camera/cts/TestConstants.java
new file mode 100644
index 0000000..2805e02
--- /dev/null
+++ b/tests/camera/src/android/hardware/multiprocess/camera/cts/TestConstants.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 android.hardware.multiprocess.camera.cts;
+
+/**
+ * Constants used throughout the multi-process unit tests.
+ */
+public class TestConstants {
+
+    public static final int EVENT_CAMERA_ERROR = -1;
+    public static final int EVENT_CAMERA_CONNECT = 1;
+    public static final int EVENT_CAMERA_EVICTED = 2;
+    public static final int EVENT_CAMERA_AVAILABLE = 3;
+    public static final int EVENT_CAMERA_UNAVAILABLE = 4;
+
+    public static final String EVENT_CAMERA_ERROR_STR = "error";
+    public static final String EVENT_CAMERA_CONNECT_STR = "connect";
+    public static final String EVENT_CAMERA_EVICTED_STR = "evicted";
+    public static final String EVENT_CAMERA_AVAILABLE_STR = "available";
+    public static final String EVENT_CAMERA_UNAVAILABLE_STR = "unavailable";
+
+    public static final String EVENT_CAMERA_UNKNOWN_STR = "unknown";
+
+    /**
+     * Convert the given error code to a string.
+     *
+     * @param err error code from {@link TestConstants}.
+     * @return string for this error code.
+     */
+    public static String errToStr(int err) {
+        switch(err) {
+            case EVENT_CAMERA_ERROR:
+                return EVENT_CAMERA_ERROR_STR;
+            case EVENT_CAMERA_CONNECT:
+                return EVENT_CAMERA_CONNECT_STR;
+            case EVENT_CAMERA_EVICTED:
+                return EVENT_CAMERA_EVICTED_STR;
+            case EVENT_CAMERA_AVAILABLE:
+                return EVENT_CAMERA_AVAILABLE_STR;
+            case EVENT_CAMERA_UNAVAILABLE:
+                return EVENT_CAMERA_UNAVAILABLE_STR;
+            default:
+                return EVENT_CAMERA_UNKNOWN_STR + " " + err;
+        }
+    }
+
+    /**
+     * Convert the given array of error codes to an array of strings.
+     *
+     * @param err array of error codes from {@link TestConstants}.
+     * @return string array for the given error codes.
+     */
+    public static String[] convertToStringArray(int[] err) {
+        if (err == null) return null;
+        String[] ret = new String[err.length];
+        for (int i = 0; i < err.length; i++) {
+            ret[i] = errToStr(err[i]);
+        }
+        return ret;
+    }
+
+}
diff --git a/tests/core/libcore/tzdata/Android.mk b/tests/core/libcore/tzdata/Android.mk
new file mode 100644
index 0000000..ecbd070
--- /dev/null
+++ b/tests/core/libcore/tzdata/Android.mk
@@ -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.
+
+LOCAL_PATH:= $(call my-dir)
+
+ifeq ($(BUILD_CTSCORE_PACKAGE),)
+    $(error BUILD_CTSCORE_PACKAGE must be defined)
+endif
+
+include $(CLEAR_VARS)
+LOCAL_PACKAGE_NAME := android.core.tests.libcore.package.tzdata
+LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update-tests
+include $(BUILD_CTSCORE_PACKAGE)
diff --git a/tests/core/libcore/tzdata/AndroidManifest.xml b/tests/core/libcore/tzdata/AndroidManifest.xml
new file mode 100644
index 0000000..8a4fad8
--- /dev/null
+++ b/tests/core/libcore/tzdata/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="android.core.tests.libcore.package.tzdata">
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.core.tests.runner"
+                     android:label="cts framework tests">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java b/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java
index 7564f32..57dc7c6 100644
--- a/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java
+++ b/tests/core/runner/src/com/android/cts/runner/CtsTestRunListener.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.support.test.internal.runner.listener.InstrumentationRunListener;
+import android.text.TextUtils;
 import android.util.Log;
 
 import junit.framework.TestCase;
@@ -28,6 +29,7 @@
 import org.junit.runner.Description;
 import org.junit.runner.notification.RunListener;
 
+import java.io.BufferedReader;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -119,6 +121,39 @@
         Log.d(TAG, "Total memory  : " + total);
         Log.d(TAG, "Used memory   : " + used);
         Log.d(TAG, "Free memory   : " + free);
+
+        String tempdir = System.getProperty("java.io.tmpdir", "");
+        // TODO: Remove these extra Logs added to debug a specific timeout problem.
+        Log.d(TAG, "java.io.tmpdir is:" + tempdir);
+
+        if (!TextUtils.isEmpty(tempdir)) {
+            String[] commands = {"df", tempdir};
+            BufferedReader in = null;
+            try {
+                Log.d(TAG, "About to .exec df");
+                Process proc = runtime.exec(commands);
+                Log.d(TAG, ".exec returned");
+                in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+                Log.d(TAG, "Stream reader created");
+                String line;
+                while ((line = in.readLine()) != null) {
+                    Log.d(TAG, line);
+                }
+            } catch (IOException e) {
+                Log.d(TAG, "Exception: " + e.toString());
+                // Well, we tried
+            } finally {
+                Log.d(TAG, "In finally");
+                if (in != null) {
+                    try {
+                        in.close();
+                    } catch (IOException e) {
+                        // Meh
+                    }
+                }
+            }
+        }
+
         Log.d(TAG, "Now executing : " + testClass.getName());
     }
 
@@ -177,8 +212,8 @@
             mSslSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
 
             mProperties.setProperty("user.home", "");
-            mProperties.setProperty("java.io.tmpdir", System.getProperty("java.io.tmpdir"));
-            // The CDD mandates that devices that support WiFi are the only ones that will have 
+            mProperties.setProperty("java.io.tmpdir", context.getCacheDir().getAbsolutePath());
+            // The CDD mandates that devices that support WiFi are the only ones that will have
             // multicast.
             PackageManager pm = context.getPackageManager();
             mProperties.setProperty("android.cts.device.multicast",
diff --git a/tests/deviceadmin/Android.mk b/tests/deviceadmin/Android.mk
index 9ab9cb8..2e89d34 100644
--- a/tests/deviceadmin/Android.mk
+++ b/tests/deviceadmin/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/deviceadmin/res/xml/device_admin.xml b/tests/deviceadmin/res/xml/device_admin.xml
index 263fda6..f7d394e 100644
--- a/tests/deviceadmin/res/xml/device_admin.xml
+++ b/tests/deviceadmin/res/xml/device_admin.xml
@@ -22,6 +22,7 @@
         <force-lock />
         <wipe-data />
         <expire-password />
+        <disable-keyguard-features />
     </uses-policies>
 </device-admin>
 
diff --git a/tests/expectations/knownfailures.txt b/tests/expectations/knownfailures.txt
index b120fc5..c025145 100644
--- a/tests/expectations/knownfailures.txt
+++ b/tests/expectations/knownfailures.txt
@@ -1,10 +1,12 @@
 [
 {
-  description: "testWindowContentFrameStats is flaky without 75b55d0846159543aafc1b7420915497fce9b3f1",
+  description: "some AlarmClockTests are not robust across different device types",
   names: [
-    "android.app.uiautomation.cts.UiAutomationTest#testWindowContentFrameStats"
+    "android.alarmclock.cts.DismissAlarmTest#testAll",
+    "android.alarmclock.cts.SetAlarmTest#testAll",
+    "android.alarmclock.cts.SnoozeAlarmTest#testAll"
   ],
-  bug: 18039218
+  bug: 23776083
 },
 {
   description: "the UsageStats is not yet stable enough",
@@ -14,13 +16,6 @@
   bug: 17536113
 },
 {
-  description: "the ConnectivityConstraintTest are not yet stable",
-  names: [
-    "android.jobscheduler.cts.ConnectivityConstraintTest"
-  ],
-  bug: 18117279
-},
-{
   description: "tests a fragile by nature as they rely on hardcoded behavior",
   names: [
     "android.accessibilityservice.cts.AccessibilityTextTraversalTest#testActionNextAndPreviousAtGranularityPageOverText",
@@ -29,6 +24,21 @@
   bug: 17595050
 },
 {
+  description: "test fails on devices with no telephony",
+  names: [
+    "android.calllog.cts.CallLogBackupTest#testSingleCallBackup"
+  ],
+  bug: 23776099
+},
+{
+  description: "test fails on some devices",
+  names: [
+    "android.dumpsys.cts.DumpsysHostTest#testBatterystatsOutput",
+    "android.dumpsys.cts.DumpsysHostTest#testGfxinfoFramestats"
+  ],
+  bug: 23776893
+},
+{
   description: "the SSLCertificateSocketFactoryTest often fails because of lack of live internet or short timeout, it should be refactored to do a local server testing",
   names: [
     "android.net.cts.SSLCertificateSocketFactoryTest#testCreateSocket",
@@ -53,6 +63,21 @@
   bug: 18461670
 },
 {
+  description: "test not robust",
+  names: [
+    "android.telecom.cts.ExtendedInCallServiceTest#testAddNewOutgoingCallAndThenDisconnect",
+    "android.telecom.cts.RemoteConferenceTest#testRemoteConferenceCallbacks_ConferenceableConnections"
+  ],
+  bug: 23604254
+},
+{
+  description: "tests too flaky",
+  names: [
+    "android.transition.cts.ChangeScrollTest#testChangeScroll"
+  ],
+  bug: 23779020
+},
+{
   description: "Not all jdwp features are currently supported. These tests will fail",
   names: [
     "org.apache.harmony.jpda.tests.jdwp.DebuggerOnDemand.OnthrowDebuggerLaunchTest#testDebuggerLaunch001",
@@ -83,18 +108,24 @@
   bug: 16720689
 },
 {
-  description: "Disable WebGL conformance tests in CTS",
+  description: "test can only run properly on a user build device when the bug is resolved",
   names: [
-    "android.webgl.cts.WebGLTest"
+    "android.appwidget.cts.AppWidgetTest#testAppWidgetProviderCallbacks",
+    "android.appwidget.cts.AppWidgetTest#testBindAppWidget",
+    "android.appwidget.cts.AppWidgetTest#testCollectionWidgets",
+    "android.appwidget.cts.AppWidgetTest#testDeleteHost",
+    "android.appwidget.cts.AppWidgetTest#testDeleteHosts",
+    "android.appwidget.cts.AppWidgetTest#testGetAppWidgetIds",
+    "android.appwidget.cts.AppWidgetTest#testGetAppWidgetInfo",
+    "android.appwidget.cts.AppWidgetTest#testGetAppWidgetOptions",
+    "android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetId",
+    "android.appwidget.cts.AppWidgetTest#testPartiallyUpdateAppWidgetViaWidgetIds",
+    "android.appwidget.cts.AppWidgetTest#testTwoAppWidgetProviderCallbacks",
+    "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaComponentName",
+    "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetId",
+    "android.appwidget.cts.AppWidgetTest#testUpdateAppWidgetViaWidgetIds"
   ],
-  bug: 20937460
-},
-{
-  description: "WebGL test uniformMatrixBadArgs is too strict. Disabled until it's fixed upstream.",
-  names: [
-    "android.webgl.cts.WebGLTest#test_conformance_more_functions_uniformMatrixBadArgs_html"
-  ],
-  bug: 18638404
+  bug: 17993121
 },
 {
   description: "permissions for the API previously used in the test has changed, making it impossible to pass",
@@ -120,13 +151,6 @@
   bug: 17530117
 },
 {
-  description: "The new image reader test is not yet passing on all devices",
-  names: [
-    "android.hardware.camera2.cts.ImageReaderTest#testAllOutputYUVResolutions"
-  ],
-  bug: 18689511
-},
-{
   description: "Current implementation of uninstallAllUserCaCerts does not throw expected security exception, wait for fix from framework",
   names: [
     "android.admin.cts.DevicePolicyManagerTest#testUninstallAllUserCaCerts_failIfNotProfileOwner"
@@ -134,6 +158,21 @@
   bug: 17508787
 },
 {
+  description: "This test should be outside of official CTS suite until it is verified for all Nexus devices",
+  names: [
+    "com.android.cts.devicepolicy.MixedDeviceOwnerTest#testPackageInstallUserRestrictions",
+    "com.android.cts.devicepolicy.MixedProfileOwnerTest#testPackageInstallUserRestrictions"
+  ],
+  bug: 18928535
+},
+{
+  description: "Test is not yet properly implemented",
+  names: [
+    "android.voicesettings.cts.ZenModeTest#testAll"
+  ],
+  bug: 23238984
+},
+{
   description: "These tests fail on some devices.",
   names: [
     "android.uirendering.cts.testclasses.ExactCanvasTests#testBlueRect",
@@ -154,172 +193,6 @@
   bug: 17605875
 },
 {
-  description: "Failures on these tests are known on several devices.",
-  names: [
-    "android.hardware.cts.SensorBatchingTests#testAccelerometer_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testAccelerometer_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testAccelerometer_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testAccelerometer_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testMagneticField_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testMagneticField_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testMagneticField_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testMagneticField_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testOrientation_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testOrientation_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testOrientation_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testOrientation_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testGyroscope_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testGyroscope_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testGyroscope_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testGyroscope_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testPressure_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testPressure_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testPressure_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testPressure_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testGravity_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testGravity_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testGravity_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testGravity_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testRotationVector_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testRotationVector_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testRotationVector_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testRotationVector_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testGameRotationVector_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testGameRotationVector_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testGameRotationVector_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testGameRotationVector_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testGyroscopeUncalibrated_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testGyroscopeUncalibrated_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testGyroscopeUncalibrated_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testGyroscopeUncalibrated_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testLinearAcceleration_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testLinearAcceleration_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testLinearAcceleration_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testLinearAcceleration_50hz_flush",
-    "android.hardware.cts.SensorBatchingTests#testGeomagneticRotationVector_fastest_batching",
-    "android.hardware.cts.SensorBatchingTests#testGeomagneticRotationVector_50hz_batching",
-    "android.hardware.cts.SensorBatchingTests#testGeomagneticRotationVector_fastest_flush",
-    "android.hardware.cts.SensorBatchingTests#testGeomagneticRotationVector_50hz_flush",
-    "android.hardware.cts.SensorIntegrationTests#testSensorsWithSeveralClients",
-    "android.hardware.cts.SensorIntegrationTests#testSensorsMovingRates",
-    "android.hardware.cts.SensorIntegrationTests#testAccelerometerAccelerometerStopping",
-    "android.hardware.cts.SensorIntegrationTests#testAccelerometerGyroscopeStopping",
-    "android.hardware.cts.SensorIntegrationTests#testAccelerometerMagneticFieldStopping",
-    "android.hardware.cts.SensorIntegrationTests#testGyroscopeAccelerometerStopping",
-    "android.hardware.cts.SensorIntegrationTests#testGyroscopeGyroscopeStopping",
-    "android.hardware.cts.SensorIntegrationTests#testGyroscopeMagneticFieldStopping",
-    "android.hardware.cts.SensorIntegrationTests#testMagneticFieldAccelerometerStopping",
-    "android.hardware.cts.SensorIntegrationTests#testMagneticFieldGyroscopeStopping",
-    "android.hardware.cts.SensorIntegrationTests#testMagneticFieldMagneticFieldStopping",
-    "android.hardware.cts.SingleSensorTests#testSensorProperties",
-    "android.hardware.cts.SingleSensorTests#testAccelerometer_fastest",
-    "android.hardware.cts.SingleSensorTests#testAccelerometer_100hz",
-    "android.hardware.cts.SingleSensorTests#testAccelerometer_200hz",
-    "android.hardware.cts.SingleSensorTests#testAccelerometer_50hz",
-    "android.hardware.cts.SingleSensorTests#testAccelerometer_25hz",
-    "android.hardware.cts.SingleSensorTests#testAccelerometer_15hz",
-    "android.hardware.cts.SingleSensorTests#testAccelerometer_10hz",
-    "android.hardware.cts.SingleSensorTests#testAccelerometer_5hz",
-    "android.hardware.cts.SingleSensorTests#testAccelerometer_1hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticField_fastest",
-    "android.hardware.cts.SingleSensorTests#testMagneticField_200hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticField_100hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticField_50hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticField_25hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticField_15hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticField_10hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticField_5hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticField_1hz",
-    "android.hardware.cts.SingleSensorTests#testOrientation_fastest",
-    "android.hardware.cts.SingleSensorTests#testOrientation_200hz",
-    "android.hardware.cts.SingleSensorTests#testOrientation_100hz",
-    "android.hardware.cts.SingleSensorTests#testOrientation_50hz",
-    "android.hardware.cts.SingleSensorTests#testOrientation_25hz",
-    "android.hardware.cts.SingleSensorTests#testOrientation_15hz",
-    "android.hardware.cts.SingleSensorTests#testOrientation_10hz",
-    "android.hardware.cts.SingleSensorTests#testOrientation_5hz",
-    "android.hardware.cts.SingleSensorTests#testOrientation_1hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscope_fastest",
-    "android.hardware.cts.SingleSensorTests#testGyroscope_200hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscope_100hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscope_50hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscope_25hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscope_15hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscope_10hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscope_5hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscope_1hz",
-    "android.hardware.cts.SingleSensorTests#testPressure_fastest",
-    "android.hardware.cts.SingleSensorTests#testPressure_200hz",
-    "android.hardware.cts.SingleSensorTests#testPressure_100hz",
-    "android.hardware.cts.SingleSensorTests#testPressure_50hz",
-    "android.hardware.cts.SingleSensorTests#testPressure_25hz",
-    "android.hardware.cts.SingleSensorTests#testPressure_15hz",
-    "android.hardware.cts.SingleSensorTests#testPressure_10hz",
-    "android.hardware.cts.SingleSensorTests#testPressure_5hz",
-    "android.hardware.cts.SingleSensorTests#testPressure_1hz",
-    "android.hardware.cts.SingleSensorTests#testGravity_fastest",
-    "android.hardware.cts.SingleSensorTests#testGravity_200hz",
-    "android.hardware.cts.SingleSensorTests#testGravity_100hz",
-    "android.hardware.cts.SingleSensorTests#testGravity_50hz",
-    "android.hardware.cts.SingleSensorTests#testGravity_25hz",
-    "android.hardware.cts.SingleSensorTests#testGravity_15hz",
-    "android.hardware.cts.SingleSensorTests#testGravity_10hz",
-    "android.hardware.cts.SingleSensorTests#testGravity_5hz",
-    "android.hardware.cts.SingleSensorTests#testGravity_1hz",
-    "android.hardware.cts.SingleSensorTests#testRotationVector_fastest",
-    "android.hardware.cts.SingleSensorTests#testRotationVector_200hz",
-    "android.hardware.cts.SingleSensorTests#testRotationVector_100hz",
-    "android.hardware.cts.SingleSensorTests#testRotationVector_50hz",
-    "android.hardware.cts.SingleSensorTests#testRotationVector_25hz",
-    "android.hardware.cts.SingleSensorTests#testRotationVector_15hz",
-    "android.hardware.cts.SingleSensorTests#testRotationVector_10hz",
-    "android.hardware.cts.SingleSensorTests#testRotationVector_5hz",
-    "android.hardware.cts.SingleSensorTests#testRotationVector_1hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_fastest",
-    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_200hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_100hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_50hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_25hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_15hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_10hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_5hz",
-    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_1hz",
-    "android.hardware.cts.SingleSensorTests#testGameRotationVector_fastest",
-    "android.hardware.cts.SingleSensorTests#testGameRotationVector_200hz",
-    "android.hardware.cts.SingleSensorTests#testGameRotationVector_100hz",
-    "android.hardware.cts.SingleSensorTests#testGameRotationVector_50hz",
-    "android.hardware.cts.SingleSensorTests#testGameRotationVector_25hz",
-    "android.hardware.cts.SingleSensorTests#testGameRotationVector_15hz",
-    "android.hardware.cts.SingleSensorTests#testGameRotationVector_10hz",
-    "android.hardware.cts.SingleSensorTests#testGameRotationVector_5hz",
-    "android.hardware.cts.SingleSensorTests#testGameRotationVector_1hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscopeUncalibrated_fastest",
-    "android.hardware.cts.SingleSensorTests#testGyroscopeUncalibrated_200hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscopeUncalibrated_100hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscopeUncalibrated_50hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscopeUncalibrated_25hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscopeUncalibrated_15hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscopeUncalibrated_10hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscopeUncalibrated_5hz",
-    "android.hardware.cts.SingleSensorTests#testGyroscopeUncalibrated_1hz",
-    "android.hardware.cts.SingleSensorTests#testGeomagneticRotationVector_fastest",
-    "android.hardware.cts.SingleSensorTests#testLinearAcceleration_200hz",
-    "android.hardware.cts.SingleSensorTests#testLinearAcceleration_100hz",
-    "android.hardware.cts.SingleSensorTests#testLinearAcceleration_50hz",
-    "android.hardware.cts.SingleSensorTests#testLinearAcceleration_25hz",
-    "android.hardware.cts.SingleSensorTests#testLinearAcceleration_15hz",
-    "android.hardware.cts.SingleSensorTests#testLinearAcceleration_10hz",
-    "android.hardware.cts.SingleSensorTests#testLinearAcceleration_5hz",
-    "android.hardware.cts.SingleSensorTests#testLinearAcceleration_1hz",
-    "android.hardware.cts.SensorTest#testSensorTimeStamps"
-  ],
-  bug: 17675466
-},
-{
   description: "This test failed on hw decoder that doesn't output frame with the configured format.",
   names: [
     "android.media.cts.ImageReaderDecoderTest#testHwAVCDecode360pForFlexibleYuv"
@@ -327,13 +200,6 @@
   bug: 17144778
 },
 {
-  description: "Roboto font tests are not yet known good on all devices",
-  names: [
-    "android.uirendering.cts.testclasses.FontRenderingTests"
-  ],
-  bug: 17109280
-},
-{
   description: "android.keystore tests will replace these tests",
   names: [
     "com.android.org.conscrypt.MacTest#test_getInstance_OpenSSL_ENGINE",
@@ -343,13 +209,6 @@
   bug: 18030049
 },
 {
-  description: "EventOrderingVerificationTest not working.",
-  names: [
-    "android.hardware.cts.helpers.sensorverification.EventOrderingVerificationTest#testSameTimestamp"
-  ],
-  bug: 23792027
-},
-{
   description: "The new recording test is not yet passing on all devices",
   names: [
     "android.hardware.camera2.cts.RecordingTest#testRecordingFramerateLowToHigh"
@@ -357,10 +216,163 @@
   bug: 18705837
 },
 {
-  description: "Encode Virtual Display is not working on all devices",
+  description: "The new image reader test is not yet passing on all devices",
   names: [
-    "android.media.cts.EncodeVirtualDisplayTest#testEncodeVirtualDisplay"
+    "android.hardware.camera2.cts.ImageReaderTest#testAllOutputYUVResolutions"
   ],
-  bug: 18705837
+  bug: 18689511
+},
+{
+  description: "The new prepare performance test is not yet passing on all devices",
+  names: [
+    "android.hardware.camera2.cts.SurfaceViewPreviewTest#testPreparePerformance"
+  ],
+  bug: 17989532
+},
+{
+  description: "The new AE/AF trigger tests are not yet passing on all devices",
+  names: [
+    "android.hardware.camera2.cts.RobustnessTest#testBasicTriggerSequence",
+    "android.hardware.camera2.cts.RobustnessTest#testSimultaneousTriggers",
+    "android.hardware.camera2.cts.RobustnessTest#testAfThenAeTrigger",
+    "android.hardware.camera2.cts.RobustnessTest#testAeThenAfTrigger"
+  ],
+  bug: 22180706
+},
+{
+  description: "The new create session test is not yet passing on all devices",
+  names: [
+    "android.hardware.camera2.cts.CameraDeviceTest#testCreateSessions"
+  ],
+  bug: 22092756
+},
+{
+  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"
+  ],
+  bug: 23008511
+},
+{
+  description: "Light status bar CTS coming in late",
+  names: [
+    "com.android.cts.systemui.LightStatusBarTests#testLightStatusBarIcons"
+  ],
+  bug: 23427621
+},
+{
+  description: "known failures",
+  names: [
+    "android.hardware.cts.SensorBatchingTests#testAccelerometer_50hz_batching",
+    "android.hardware.cts.SensorBatchingTests#testAccelerometer_fastest_batching",
+    "android.hardware.cts.SensorBatchingTests#testGyroscope_50hz_batching",
+    "android.hardware.cts.SensorBatchingTests#testGyroscope_50hz_flush",
+    "android.hardware.cts.SensorBatchingTests#testMagneticField_50hz_batching",
+    "android.hardware.cts.SensorBatchingTests#testMagneticField_fastest_batching",
+    "android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_50hz_batching",
+    "android.hardware.cts.SensorBatchingTests#testMagneticFieldUncalibrated_fastest_batching",
+    "android.hardware.cts.SensorBatchingTests#testPressure_50hz_batching",
+    "android.hardware.cts.SensorBatchingTests#testPressure_fastest_batching",
+    "android.hardware.cts.SensorBatchingTests#testRotationVector_50hz_flush",
+    "android.hardware.cts.SensorBatchingTests#testRotationVector_fastest_batching",
+    "android.hardware.cts.SensorIntegrationTests#testSensorsMovingRates",
+    "android.hardware.cts.SensorIntegrationTests#testSensorsWithSeveralClients",
+    "android.hardware.cts.SensorTest#testSensorTimeStamps",
+    "android.hardware.cts.SensorTest#testBatchAndFlush",
+    "android.hardware.cts.SingleSensorTests#testGyroscope_15hz",
+    "android.hardware.cts.SingleSensorTests#testGyroscope_1hz",
+    "android.hardware.cts.SingleSensorTests#testMagneticField_1hz",
+    "android.hardware.cts.SingleSensorTests#testMagneticField_50hz",
+    "android.hardware.cts.SingleSensorTests#testMagneticFieldUncalibrated_200hz",
+    "android.hardware.cts.SingleSensorTests#testOrientation_5hz"
+  ],
+  bug: 22922206
+},
+{
+  description: "tests are not yet ready",
+  names: [
+    "com.android.cts.app.os.OsHostTests#testNonExportedActivities"
+  ],
+  bug: 23779168
+},
+{
+  description: "New assist tests that do not yet have a track record.",
+  names: [
+    "android.assist.cts.AssistantContentViewTest",
+    "android.assist.cts.ExtraAssistDataTest",
+    "android.assist.cts.FocusChangeTest",
+    "android.assist.cts.LargeViewHierarchyTest",
+    "android.assist.cts.ScreenshotTest",
+    "android.assist.cts.TextViewTest",
+    "android.assist.cts.WebViewTest"
+  ],
+  bug: 21668302
+},
+{
+  description: "ConnectivityConstraintTest job scheduler not working.",
+  names: [
+     "android.jobscheduler.cts.ConnectivityConstraintTest#testConnectivityConstraintExecutes_withWifi",
+     "android.jobscheduler.cts.ConnectivityConstraintTest#testUnmeteredConstraintExecutes_withWifi",
+     "android.jobscheduler.cts.ConnectivityConstraintTest#testConnectivityConstraintExecutes_withMobile"
+  ],
+  bug: 21262226
+},
+{
+   description: "ConnectivityConstraintTest times out.",
+   names: [
+     "android.jobscheduler.cts.TimingConstraintsTest#testJobParameters_unexpiredDeadline"
+   ],
+   bug: 23144425
+},
+{
+   description: "Telephony returning wrong value.",
+   names: [
+     "android.telephony.cts.CellInfoTest#testCellInfo"
+   ],
+   bug: 23979591
+},
+{
+   description: "Video encoding tests are timing out.",
+   names: [
+     "android.media.cts.VideoEncoderTest#testGoogH264FlexArbitraryW",
+     "android.media.cts.VideoEncoderTest#testGoogH264SurfArbitraryW"
+   ],
+   bug: 23827982
+},
+{
+  description: "protected broadcast not working",
+  names: [
+   "android.permission2.cts.ProtectedBroadcastsTest#testSendProtectedBroadcasts"
+  ],
+  bug: 23192492
+},
+{
+  description: "restricted network is not working",
+  names: [
+    "android.net.cts.ConnectivityManagerTest#testRestrictedNetworks"
+  ],
+  bug: 25651805
+},
+{
+  description: "Read from invalid parcel not working",
+  names: [
+    "android.view.cts.MotionEventTest#testReadFromParcelWithInvalidSampleSize"
+  ],
+  bug: 25652250
+},
+{
+  description: "Wired headset tests are no longer a requirement per CDD",
+  names: [
+    "android.telecom.cts.WiredHeadsetTest"
+  ],
+  bug: 26149528
 }
 ]
diff --git a/tests/leanbackjank/Android.mk b/tests/leanbackjank/Android.mk
new file mode 100644
index 0000000..b3adfb1
--- /dev/null
+++ b/tests/leanbackjank/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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) \
+        ./app/src/android/cts/jank/leanback/IntentKeys.java
+
+LOCAL_PACKAGE_NAME := CtsLeanbackJankTestCases
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ub-uiautomator ub-janktesthelper android-support-v17-leanback
+
+include $(BUILD_CTS_PACKAGE)
+
+include $(call all-makefiles-under, $(LOCAL_PATH))
+
diff --git a/tests/leanbackjank/AndroidManifest.xml b/tests/leanbackjank/AndroidManifest.xml
new file mode 100644
index 0000000..1cd552d
--- /dev/null
+++ b/tests/leanbackjank/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="android.cts.leanbackjank">
+
+  <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">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/leanbackjank/AndroidTest.xml b/tests/leanbackjank/AndroidTest.xml
new file mode 100644
index 0000000..e61c58d
--- /dev/null
+++ b/tests/leanbackjank/AndroidTest.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 Jank test config">
+    <include name="common-config" />
+    <option name="cts-apk-installer:test-file-name" value="CtsLeanbackJank.apk" />
+</configuration>
diff --git a/tests/leanbackjank/app/Android.mk b/tests/leanbackjank/app/Android.mk
new file mode 100644
index 0000000..5abe1a7
--- /dev/null
+++ b/tests/leanbackjank/app/Android.mk
@@ -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.
+
+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 := CtsLeanbackJank
+
+LOCAL_RESOURCE_DIR := \
+    $(TOP)/frameworks/support/v17/leanback/res \
+    $(TOP)/frameworks/support/v7/recyclerview/res \
+    $(LOCAL_PATH)/res
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    ctsdeviceutil \
+    ctstestrunner \
+    ub-uiautomator \
+    ub-janktesthelper \
+    android-support-v4 \
+    android-support-v7-recyclerview \
+    android-support-v17-leanback \
+    glide
+
+LOCAL_AAPT_FLAGS := \
+        --auto-add-overlay \
+        --extra-packages android.support.v17.leanback \
+        --extra-packages android.support.v7.recyclerview
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/leanbackjank/app/AndroidManifest.xml b/tests/leanbackjank/app/AndroidManifest.xml
new file mode 100644
index 0000000..333399e
--- /dev/null
+++ b/tests/leanbackjank/app/AndroidManifest.xml
@@ -0,0 +1,55 @@
+<?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.leanback"
+    android:versionCode="1"
+    android:versionName="1.1" >
+
+    <uses-sdk
+        android:minSdkVersion="21"
+        android:targetSdkVersion="23" />
+
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
+
+    <uses-feature
+        android:name="android.hardware.touchscreen"
+        android:required="false" />
+
+    <uses-feature android:name="android.software.leanback"
+        android:required="true" />
+
+    <application
+        android:allowBackup="false"
+        android:icon="@drawable/videos_by_google_banner"
+        android:label="@string/app_name"
+        android:logo="@drawable/videos_by_google_banner"
+        android:theme="@style/Theme.Example.Leanback" >
+        <activity
+            android:name=".ui.MainActivity"
+            android:icon="@drawable/videos_by_google_banner"
+            android:label="@string/app_name"
+            android:logo="@drawable/videos_by_google_banner"
+            android:screenOrientation="landscape" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/leanbackjank/app/res/drawable-hdpi/app_icon_quantum.png b/tests/leanbackjank/app/res/drawable-hdpi/app_icon_quantum.png
new file mode 100644
index 0000000..fda9a74
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-hdpi/app_icon_quantum.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-hdpi/app_icon_quantum_card.png b/tests/leanbackjank/app/res/drawable-hdpi/app_icon_quantum_card.png
new file mode 100644
index 0000000..498cf66
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-hdpi/app_icon_quantum_card.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-hdpi/ic_launcher.png b/tests/leanbackjank/app/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..96a442e
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-hdpi/ic_main_icon.png b/tests/leanbackjank/app/res/drawable-hdpi/ic_main_icon.png
new file mode 100644
index 0000000..6f0c962
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-hdpi/ic_main_icon.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-hdpi/videos_by_google_banner.png b/tests/leanbackjank/app/res/drawable-hdpi/videos_by_google_banner.png
new file mode 100644
index 0000000..4cedb52
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-hdpi/videos_by_google_banner.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-hdpi/videos_by_google_icon.png b/tests/leanbackjank/app/res/drawable-hdpi/videos_by_google_icon.png
new file mode 100644
index 0000000..20fd898
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-hdpi/videos_by_google_icon.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-ldpi/ic_launcher.png b/tests/leanbackjank/app/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000..9923872
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-mdpi/app_icon_quantum.png b/tests/leanbackjank/app/res/drawable-mdpi/app_icon_quantum.png
new file mode 100644
index 0000000..6b62138
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-mdpi/app_icon_quantum.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-mdpi/app_icon_quantum_card.png b/tests/leanbackjank/app/res/drawable-mdpi/app_icon_quantum_card.png
new file mode 100644
index 0000000..ac9cc30
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-mdpi/app_icon_quantum_card.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-mdpi/ic_launcher.png b/tests/leanbackjank/app/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..359047d
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-mdpi/ic_main_icon.png b/tests/leanbackjank/app/res/drawable-mdpi/ic_main_icon.png
new file mode 100644
index 0000000..e9effc8
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-mdpi/ic_main_icon.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-mdpi/videos_by_google_banner.png b/tests/leanbackjank/app/res/drawable-mdpi/videos_by_google_banner.png
new file mode 100644
index 0000000..b191626
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-mdpi/videos_by_google_banner.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-mdpi/videos_by_google_icon.png b/tests/leanbackjank/app/res/drawable-mdpi/videos_by_google_icon.png
new file mode 100644
index 0000000..8a7c6dc
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-mdpi/videos_by_google_icon.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/app_icon_quantum.png b/tests/leanbackjank/app/res/drawable-xhdpi/app_icon_quantum.png
new file mode 100644
index 0000000..825ef63
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/app_icon_quantum.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/app_icon_quantum_card.png b/tests/leanbackjank/app/res/drawable-xhdpi/app_icon_quantum_card.png
new file mode 100644
index 0000000..9b1703d
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/app_icon_quantum_card.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/bg.png b/tests/leanbackjank/app/res/drawable-xhdpi/bg.png
new file mode 100644
index 0000000..476c698
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/bg.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/card_background_default.9.png b/tests/leanbackjank/app/res/drawable-xhdpi/card_background_default.9.png
new file mode 100644
index 0000000..29f4e01
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/card_background_default.9.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/default_background.xml b/tests/leanbackjank/app/res/drawable-xhdpi/default_background.xml
new file mode 100644
index 0000000..07b0589
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/default_background.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+       android:shape="rectangle">
+    <gradient
+            android:startColor="@color/background_gradient_start"
+            android:endColor="@color/background_gradient_end"
+            android:angle="-270" />
+</shape>
\ No newline at end of file
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/grid_bg.png b/tests/leanbackjank/app/res/drawable-xhdpi/grid_bg.png
new file mode 100644
index 0000000..476c698
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/grid_bg.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/ic_launcher.png b/tests/leanbackjank/app/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..71c6d76
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/ic_main_icon.png b/tests/leanbackjank/app/res/drawable-xhdpi/ic_main_icon.png
new file mode 100644
index 0000000..2e56516
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/ic_main_icon.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/shadow7.9.png b/tests/leanbackjank/app/res/drawable-xhdpi/shadow7.9.png
new file mode 100644
index 0000000..6d00d09
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/shadow7.9.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/videos_by_google_banner.png b/tests/leanbackjank/app/res/drawable-xhdpi/videos_by_google_banner.png
new file mode 100644
index 0000000..bdcf41e
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/videos_by_google_banner.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xhdpi/videos_by_google_icon.png b/tests/leanbackjank/app/res/drawable-xhdpi/videos_by_google_icon.png
new file mode 100644
index 0000000..9bc4836
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xhdpi/videos_by_google_icon.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xxhdpi/app_icon_quantum.png b/tests/leanbackjank/app/res/drawable-xxhdpi/app_icon_quantum.png
new file mode 100644
index 0000000..c82f94c
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xxhdpi/app_icon_quantum.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xxhdpi/app_icon_quantum_card.png b/tests/leanbackjank/app/res/drawable-xxhdpi/app_icon_quantum_card.png
new file mode 100644
index 0000000..6c50e8f
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xxhdpi/app_icon_quantum_card.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xxhdpi/videos_by_google_banner.png b/tests/leanbackjank/app/res/drawable-xxhdpi/videos_by_google_banner.png
new file mode 100644
index 0000000..6c121e61
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xxhdpi/videos_by_google_banner.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable-xxhdpi/videos_by_google_icon.png b/tests/leanbackjank/app/res/drawable-xxhdpi/videos_by_google_icon.png
new file mode 100644
index 0000000..4258160e
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable-xxhdpi/videos_by_google_icon.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/android_header.png b/tests/leanbackjank/app/res/drawable/android_header.png
new file mode 100644
index 0000000..56206ec
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/android_header.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/app_icon_quantum.png b/tests/leanbackjank/app/res/drawable/app_icon_quantum.png
new file mode 100644
index 0000000..fda9a74
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/app_icon_quantum.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/app_icon_quantum_card.png b/tests/leanbackjank/app/res/drawable/app_icon_quantum_card.png
new file mode 100644
index 0000000..498cf66
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/app_icon_quantum_card.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/gradation.png b/tests/leanbackjank/app/res/drawable/gradation.png
new file mode 100644
index 0000000..ba43a90
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/gradation.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/ic_action_a.png b/tests/leanbackjank/app/res/drawable/ic_action_a.png
new file mode 100644
index 0000000..3d555ef
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/ic_action_a.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/ic_title.png b/tests/leanbackjank/app/res/drawable/ic_title.png
new file mode 100644
index 0000000..1c62b2e
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/ic_title.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/movie.png b/tests/leanbackjank/app/res/drawable/movie.png
new file mode 100644
index 0000000..cb5cb6d
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/movie.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/player_bg_gradient_dark.xml b/tests/leanbackjank/app/res/drawable/player_bg_gradient_dark.xml
new file mode 100644
index 0000000..4450cb6
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/player_bg_gradient_dark.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape xmlns:android="http://schemas.android.com/apk/res/android" >
+
+    <gradient
+        android:angle="90"
+        android:centerColor="#00000000"
+        android:endColor="#B2000000"
+        android:startColor="#B2000000"
+        android:type="linear" />
+
+</shape>
\ No newline at end of file
diff --git a/tests/leanbackjank/app/res/drawable/shadow7.9.png b/tests/leanbackjank/app/res/drawable/shadow7.9.png
new file mode 100644
index 0000000..6d00d09
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/shadow7.9.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/text_bg.xml b/tests/leanbackjank/app/res/drawable/text_bg.xml
new file mode 100644
index 0000000..43fbeaf
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/text_bg.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.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <gradient
+        android:startColor="#FFFF0000"
+        android:endColor="#FFFF00FF"
+        android:angle="45" />
+    <padding
+        android:left="7dp"
+        android:top="7dp"
+        android:right="7dp"
+        android:bottom="7dp" />
+    <size
+        android:height="160dp"
+        android:width="100dp" />
+</shape>
diff --git a/tests/leanbackjank/app/res/drawable/videos_by_google_banner.png b/tests/leanbackjank/app/res/drawable/videos_by_google_banner.png
new file mode 100644
index 0000000..4cedb52
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/videos_by_google_banner.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/drawable/videos_by_google_icon.png b/tests/leanbackjank/app/res/drawable/videos_by_google_icon.png
new file mode 100644
index 0000000..20fd898
--- /dev/null
+++ b/tests/leanbackjank/app/res/drawable/videos_by_google_icon.png
Binary files differ
diff --git a/tests/leanbackjank/app/res/layout/icon_header_item.xml b/tests/leanbackjank/app/res/layout/icon_header_item.xml
new file mode 100644
index 0000000..586881d
--- /dev/null
+++ b/tests/leanbackjank/app/res/layout/icon_header_item.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.
+-->
+<android.support.v17.leanback.widget.NonOverlappingLinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <ImageView
+        android:id="@+id/header_icon"
+        android:layout_width="32dp"
+        android:layout_height="32dp" />
+
+    <TextView
+        android:id="@+id/header_label"
+        android:layout_marginTop="6dp"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+</android.support.v17.leanback.widget.NonOverlappingLinearLayout>
diff --git a/tests/leanbackjank/app/res/layout/main.xml b/tests/leanbackjank/app/res/layout/main.xml
new file mode 100644
index 0000000..7a83b69
--- /dev/null
+++ b/tests/leanbackjank/app/res/layout/main.xml
@@ -0,0 +1,30 @@
+<?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"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/main_frame"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <fragment
+        android:name="android.cts.jank.leanback.ui.MainFragment"
+        android:id="@+id/main_browse_fragment"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" />
+
+</FrameLayout>
diff --git a/tests/leanbackjank/app/res/layout/movie_card.xml b/tests/leanbackjank/app/res/layout/movie_card.xml
new file mode 100644
index 0000000..c63841d
--- /dev/null
+++ b/tests/leanbackjank/app/res/layout/movie_card.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<android.support.v17.leanback.widget.NonOverlappingLinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_height="wrap_content"
+              android:layout_width="wrap_content"
+              android:scaleType="centerCrop"
+              android:focusable="true"
+              android:focusableInTouchMode="true">
+    <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:id="@+id/poster" android:layout_gravity="center"/>
+    <TextView
+       android:id="@+id/poster_text"
+       android:layout_width="wrap_content"
+       android:layout_height="wrap_content"
+       android:paddingTop="10dp"
+       android:paddingRight="10dp"
+       android:paddingBottom="10dp"
+       android:paddingLeft="10dp" />
+</android.support.v17.leanback.widget.NonOverlappingLinearLayout>
\ No newline at end of file
diff --git a/tests/leanbackjank/app/res/values/colors.xml b/tests/leanbackjank/app/res/values/colors.xml
new file mode 100644
index 0000000..7e246ed
--- /dev/null
+++ b/tests/leanbackjank/app/res/values/colors.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="background_gradient_start">#000000</color>
+    <color name="background_gradient_end">#DDDDDD</color>
+    <color name="fastlane_background">#0096a6</color>
+    <color name="search_opaque">#ffaa3f</color>
+    <color name="selected_background">#ffaa3f</color>
+    <color name="soft_opaque">#30000000</color>
+    <color name="img_soft_opaque">#30FF0000</color>
+    <color name="img_full_opaque">#00000000</color>
+    <color name="black_opaque">#AA000000</color>
+    <color name="black">#59000000</color>
+    <color name="white">#FFFFFF</color>
+    <color name="orange_transparent">#AAFADCA7</color>
+    <color name="orange">#FADCA7</color>
+    <color name="yellow">#EEFF41</color>
+    <color name="default_background">#0096a6</color>
+    <color name="icon_background">#4A4F51</color>
+    <color name="icon_alt_background">#2A2F51</color>
+</resources>
\ No newline at end of file
diff --git a/tests/leanbackjank/app/res/values/strings.xml b/tests/leanbackjank/app/res/values/strings.xml
new file mode 100644
index 0000000..17edf95
--- /dev/null
+++ b/tests/leanbackjank/app/res/values/strings.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.
+-->
+
+<resources>
+    <string name="app_name"><![CDATA[Leanback launcher jank test application]]></string>
+    <string name="browse_title"><![CDATA[Leanback launcher jank test application]]></string>
+    <string name="error">Error</string>
+    <string name="ok">OK</string>
+    <string name="grid_item_template">Item %1$d</string>
+    <string name="settings">Settings</string>
+
+    <!-- Error messages -->
+    <string name="error_fragment_message">An error occurred</string>
+    <string name="dismiss_error">Dismiss</string>
+</resources>
diff --git a/tests/leanbackjank/app/res/values/themes.xml b/tests/leanbackjank/app/res/values/themes.xml
new file mode 100644
index 0000000..4a1e06d
--- /dev/null
+++ b/tests/leanbackjank/app/res/values/themes.xml
@@ -0,0 +1,15 @@
+<resources>
+    <style name="Theme.Example.Leanback" parent="Theme.Leanback">
+        <item name="android:colorPrimary">@color/search_opaque</item>
+        <item name="android:windowEnterTransition">@android:transition/fade</item>
+        <item name="android:windowExitTransition">@android:transition/fade</item>
+        <item name="android:windowSharedElementExitTransition">@android:transition/move</item>
+        <item name="android:windowSharedElementEnterTransition">@android:transition/move</item>
+        <!-- Set to display colorPrimary when apps launches -->
+        <item name="android:windowAllowReturnTransitionOverlap">true</item>
+        <item name="android:windowAllowEnterTransitionOverlap">false</item>
+        <item name="android:windowContentTransitions">true</item>
+    </style>
+    <style name="Widget.Example.Leanback.Title.Text" parent="Widget.Leanback.Title.Text" >
+    </style>
+</resources>
diff --git a/tests/leanbackjank/app/src/android/cts/jank/leanback/IntentKeys.java b/tests/leanbackjank/app/src/android/cts/jank/leanback/IntentKeys.java
new file mode 100644
index 0000000..e9c5e6e
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/cts/jank/leanback/IntentKeys.java
@@ -0,0 +1,10 @@
+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
new file mode 100644
index 0000000..de6d6af
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/cts/jank/leanback/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.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
new file mode 100644
index 0000000..fa317ed
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/cts/jank/leanback/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.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
new file mode 100644
index 0000000..874bb00
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/cts/jank/leanback/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.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
new file mode 100644
index 0000000..9f425ca
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/cts/jank/leanback/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.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
new file mode 100644
index 0000000..4084383
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/cts/jank/leanback/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.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
new file mode 100644
index 0000000..42e4c0c
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/cts/jank/leanback/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.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
new file mode 100644
index 0000000..fb27fa1
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/cts/jank/leanback/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.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
new file mode 100644
index 0000000..e645f6b
--- /dev/null
+++ b/tests/leanbackjank/app/src/android/cts/jank/leanback/ui/MainFragment.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.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;
+
+/**
+ * Main class to show BrowseFragment with header and rows of videos
+ */
+public class MainFragment extends BrowseFragment {
+    private static final int NUM_ROWS = 20;
+    private final Handler mHandler = new Handler();
+    private Timer mAutoScrollTimer;
+    private int mAutoScrollCount;
+
+    private ArrayObjectAdapter mRowsAdapter;
+    private DisplayMetrics mMetrics;
+    private BackgroundManager mBackgroundManager;
+
+    @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);
+            }
+        }
+    }
+
+    @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;
+                    }
+                    if (mAutoScrollCount % 2 == 0) {
+                      setSelectedPosition(NUM_ROWS - 1);
+                    } else {
+                      setSelectedPosition(0);
+                    }
+                    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
new file mode 100644
index 0000000..241535e
--- /dev/null
+++ b/tests/leanbackjank/src/android/cts/leanbackjank/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.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 = 3;
+    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 30 fps on average to pass the test.
+    @JankTest(expectedFrames = 30 * 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
new file mode 100644
index 0000000..4de0702
--- /dev/null
+++ b/tests/leanbackjank/src/android/cts/leanbackjank/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.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/netlegacy22.api/Android.mk b/tests/netlegacy22.api/Android.mk
new file mode 100644
index 0000000..68fd6f8
--- /dev/null
+++ b/tests/netlegacy22.api/Android.mk
@@ -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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# 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_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsNetTestCasesLegacyApi22
+
+LOCAL_SDK_VERSION := 22
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/netlegacy22.api/AndroidManifest.xml b/tests/netlegacy22.api/AndroidManifest.xml
new file mode 100644
index 0000000..f13805c
--- /dev/null
+++ b/tests/netlegacy22.api/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?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="com.android.cts.netlegacy22.api">
+
+    <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_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.netlegacy22.api"
+                     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" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/netlegacy22.api/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java b/tests/netlegacy22.api/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java
new file mode 100644
index 0000000..1836f06
--- /dev/null
+++ b/tests/netlegacy22.api/src/android/net/cts/legacy/api22/ConnectivityManagerLegacyTest.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.legacy.api22;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.LinkAddress;
+import android.net.LinkProperties;
+import android.net.Network;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
+import android.os.ConditionVariable;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.net.DatagramSocket;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
+import static android.net.ConnectivityManager.TYPE_MOBILE;
+import static android.net.ConnectivityManager.TYPE_MOBILE_HIPRI;
+import static android.net.ConnectivityManager.TYPE_VPN;
+import static android.net.ConnectivityManager.TYPE_WIFI;
+
+public class ConnectivityManagerLegacyTest extends AndroidTestCase {
+    private static final String TAG = ConnectivityManagerLegacyTest.class.getSimpleName();
+    private static final String FEATURE_ENABLE_HIPRI = "enableHIPRI";
+    private static final String HOST_ADDRESS1 = "192.0.2.1";
+    private static final String HOST_ADDRESS2 = "192.0.2.2";
+    private static final String HOST_ADDRESS3 = "192.0.2.3";
+
+    // These are correct as of API level 22, which is what we target here.
+    private static final int APN_REQUEST_FAILED = 3;
+    private static final int MAX_NETWORK_TYPE = TYPE_VPN;
+
+    private ConnectivityManager mCm;
+    private WifiManager mWifiManager;
+    private PackageManager mPackageManager;
+
+    private final List<Integer>mProtectedNetworks = new ArrayList<Integer>();
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+        mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
+        mPackageManager = getContext().getPackageManager();
+
+        // Get com.android.internal.R.array.config_protectedNetworks
+        int resId = getContext().getResources().getIdentifier("config_protectedNetworks", "array", "android");
+        int[] protectedNetworks = getContext().getResources().getIntArray(resId);
+        for (int p : protectedNetworks) {
+            mProtectedNetworks.add(p);
+        }
+    }
+
+    // true if only the system can turn it on
+    private boolean isNetworkProtected(int networkType) {
+        return mProtectedNetworks.contains(networkType);
+    }
+
+    private int ipv4AddrToInt(String addrString) throws Exception {
+        byte[] addr = ((Inet4Address) InetAddress.getByName(addrString)).getAddress();
+        return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) |
+                ((addr[1] & 0xff) << 8) | (addr[0] & 0xff);
+    }
+
+    // Returns a list of all the IP addresses for all the networks of a given legacy type. We can't
+    // just fetch the IP addresses for that type because there is no public getLinkProperties API
+    // that takes a legacy type.
+    private List<InetAddress> getIpAddresses(int type) {
+        ArrayList<InetAddress> addresses = new ArrayList<>();
+        Network[] networks = mCm.getAllNetworks();
+        for (int i = 0; i < networks.length; i++) {
+            NetworkInfo ni = mCm.getNetworkInfo(networks[i]);
+            if (ni != null && ni.getType() == type) {
+                // This does not include IP addresses on stacked interfaces (e.g., 464xlat), because
+                // there is no public API that will return them.
+                LinkProperties lp = mCm.getLinkProperties(networks[i]);
+                for (LinkAddress address : lp.getLinkAddresses()) {
+                    addresses.add(address.getAddress());
+                }
+            }
+        }
+        return addresses;
+    }
+
+    private boolean hasIPv4(int type) {
+        for (InetAddress address : getIpAddresses(type)) {
+            if (address instanceof Inet4Address) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void checkSourceAddress(String addrString, int type) throws Exception {
+        // The public requestRouteToHost API only supports IPv4, but it will not return failure if
+        // the network does not have an IPv4 address. So don't check that it's working unless we
+        // know that the network has an IPv4 address. Note that it's possible that the network will
+        // have an IPv4 address but we don't know about it, because the IPv4 address might be on a
+        // stacked interface and we wouldn't be able to see it.
+        if (!hasIPv4(type)) {
+            Log.d(TAG, "Not checking source address on network type " + type + ", no IPv4 address");
+            return;
+        }
+
+        DatagramSocket d = new DatagramSocket();
+        d.connect(InetAddress.getByName(addrString), 7);
+        InetAddress localAddress = d.getLocalAddress();
+        String localAddrString = localAddress.getHostAddress();
+
+        Log.d(TAG, "Got source address " + localAddrString + " for destination " + addrString);
+
+        assertTrue(
+                "Local address " + localAddress + " not assigned to any network of type " + type,
+                getIpAddresses(type).contains(localAddress));
+
+        Log.d(TAG, "Source address " + localAddress + " found on network type " + type);
+    }
+
+    /** Test that hipri can be brought up when Wifi is enabled. */
+    public void testStartUsingNetworkFeature_enableHipri() throws Exception {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
+                || !mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            // This test requires a mobile data connection and WiFi.
+            return;
+        }
+
+        // Make sure WiFi is connected to an access point.
+        connectToWifi();
+
+        expectNetworkBroadcast(TYPE_MOBILE_HIPRI, NetworkInfo.State.CONNECTED,
+                new Runnable() {
+                    public void run() {
+                        int ret = mCm.startUsingNetworkFeature(TYPE_MOBILE, FEATURE_ENABLE_HIPRI);
+                        assertTrue("Couldn't start using the HIPRI feature.", ret != -1);
+                    }
+                });
+
+        assertTrue("Couldn't requestRouteToHost using HIPRI.",
+                mCm.requestRouteToHost(TYPE_MOBILE_HIPRI, ipv4AddrToInt(HOST_ADDRESS1)));
+
+        checkSourceAddress(HOST_ADDRESS1, TYPE_MOBILE);
+        checkSourceAddress(HOST_ADDRESS2, TYPE_WIFI);
+
+        // TODO check dns selection
+
+        expectNetworkBroadcast(TYPE_MOBILE_HIPRI, NetworkInfo.State.DISCONNECTED,
+                new Runnable() {
+                    public void run() {
+                        int ret = mCm.stopUsingNetworkFeature(TYPE_MOBILE, FEATURE_ENABLE_HIPRI);
+                        assertTrue("Couldn't stop using the HIPRI feature.", ret != -1);
+                    }
+                });
+
+
+        // TODO check dns selection
+        disconnectFromWifi();
+    }
+
+    public void testStartUsingNetworkFeature() {
+
+        final String invalidFeature = "invalidFeature";
+        final String mmsFeature = "enableMMS";
+        final int failureCode = -1;
+        final int wifiOnlyStartFailureCode = APN_REQUEST_FAILED;
+        final int wifiOnlyStopFailureCode = -1;
+
+        NetworkInfo ni = mCm.getNetworkInfo(TYPE_MOBILE);
+        if (ni != null) {
+            assertEquals(APN_REQUEST_FAILED,
+                    mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidFeature));
+            assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE, invalidFeature));
+        } else {
+            assertEquals(wifiOnlyStartFailureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE,
+                    invalidFeature));
+            assertEquals(wifiOnlyStopFailureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE,
+                    invalidFeature));
+        }
+
+        ni = mCm.getNetworkInfo(TYPE_WIFI);
+        if (ni != null) {
+            // Should return failure because MMS is not supported on WIFI.
+            assertEquals(APN_REQUEST_FAILED, mCm.startUsingNetworkFeature(TYPE_WIFI,
+                    mmsFeature));
+            assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI,
+                    mmsFeature));
+        }
+    }
+
+    private void expectNetworkBroadcast(final int type, final NetworkInfo.State state,
+            Runnable afterWhat) {
+        final int TIMEOUT_MS = 30 * 1000;
+        final ConditionVariable var = new ConditionVariable();
+
+        Log.d(TAG, "Waiting for " + state + " broadcast for type " + type);
+        BroadcastReceiver receiver = new BroadcastReceiver() {
+            public void onReceive(Context context, Intent intent) {
+                NetworkInfo ni = intent.getExtras()
+                        .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO);
+                assertNotNull("CONNECTIVITY_ACTION with null EXTRA_NETWORK_INFO", ni);
+                if (ni.getType() == type && ni.getState().equals(state)) {
+                    Log.d(TAG, "Received expected " + state + " broadcast for type " + type);
+                    var.open();
+                }
+            }
+        };
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(CONNECTIVITY_ACTION);
+        mContext.registerReceiver(receiver, filter);
+
+        try {
+            afterWhat.run();
+            final String msg = "Did not receive expected " + state + " broadcast for type " + type +
+                    " after " + TIMEOUT_MS + " ms";
+            assertTrue(msg, var.block(TIMEOUT_MS));
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+    }
+
+    private boolean isWifiConnected() {
+        NetworkInfo ni = mCm.getNetworkInfo(TYPE_WIFI);
+        return ni != null && ni.isConnected();
+    }
+
+    private void setWifiState(final boolean enabled) {
+        if (enabled != isWifiConnected()) {
+            final NetworkInfo.State desiredState = enabled ?
+                    NetworkInfo.State.CONNECTED :
+                    NetworkInfo.State.DISCONNECTED;
+            expectNetworkBroadcast(TYPE_WIFI, desiredState, new Runnable() {
+                public void run() {
+                    mWifiManager.setWifiEnabled(enabled);
+                }
+            });
+        }
+    }
+
+    private void connectToWifi() {
+        setWifiState(true);
+    }
+
+    private void disconnectFromWifi() {
+        setWifiState(false);
+    }
+
+    private boolean isNetworkSupported(int networkType) {
+        return mCm.getNetworkInfo(networkType) != null;
+    }
+
+    public void testRequestRouteToHost() throws Exception {
+        for (int type = -1 ; type <= MAX_NETWORK_TYPE; type++) {
+            NetworkInfo ni = mCm.getNetworkInfo(type);
+            boolean expectToWork = isNetworkSupported(type) && !isNetworkProtected(type) &&
+                    ni != null && ni.isConnected();
+
+            try {
+                assertTrue("Network type " + type,
+                        mCm.requestRouteToHost(type, ipv4AddrToInt(HOST_ADDRESS3)) == expectToWork);
+            } catch (Exception e) {
+                Log.d(TAG, "got exception in requestRouteToHost for type " + type);
+                assertFalse("Exception received for type " + type, expectToWork);
+            }
+
+            //TODO verify route table
+        }
+
+        assertFalse(mCm.requestRouteToHost(-1, ipv4AddrToInt(HOST_ADDRESS1)));
+    }
+}
diff --git a/tests/netlegacy22.permission/Android.mk b/tests/netlegacy22.permission/Android.mk
new file mode 100644
index 0000000..fff9d85
--- /dev/null
+++ b/tests/netlegacy22.permission/Android.mk
@@ -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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# 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_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsNetTestCasesLegacyPermission22
+
+LOCAL_SDK_VERSION := 22
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/netlegacy22.permission/AndroidManifest.xml b/tests/netlegacy22.permission/AndroidManifest.xml
new file mode 100644
index 0000000..cd1d2ba
--- /dev/null
+++ b/tests/netlegacy22.permission/AndroidManifest.xml
@@ -0,0 +1,51 @@
+<?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.netlegacy22.permission">
+
+    <uses-permission android:name="android.permission.INJECT_EVENTS" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <activity android:name="android.permission.cts.PermissionStubActivity"
+                  android:label="PermissionStubActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN"/>
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST"/>
+            </intent-filter>
+        </activity>
+    </application>
+
+    <!--
+        The CTS stubs package cannot be used as the target application here,
+        since that requires many permissions to be set. Instead, specify this
+        package itself as the target and include any stub activities needed.
+
+        This test package uses the default InstrumentationTestRunner, because
+        the InstrumentationCtsTestRunner is only available in the stubs
+        package. That runner cannot be added to this package either, since it
+        relies on hidden APIs.
+    -->
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.netlegacy22.permission"
+                     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" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/ConnectivityManagerPermissionTest.java b/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/ConnectivityManagerPermissionTest.java
new file mode 100644
index 0000000..0e59288
--- /dev/null
+++ b/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/ConnectivityManagerPermissionTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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.net.cts.legacy.api22.permission;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+* Test that protected android.net.ConnectivityManager methods cannot be called without
+* permissions
+*/
+public class ConnectivityManagerPermissionTest extends AndroidTestCase {
+
+    private ConnectivityManager mConnectivityManager = null;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mConnectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+        assertNotNull(mConnectivityManager);
+    }
+
+    /**
+     * Verify that calling {@link ConnectivityManager#requestRouteToHost(int, int)}
+     * requires permissions.
+     * <p>Tests Permission:
+     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+     */
+    @SmallTest
+    public void testRequestRouteToHost() {
+        try {
+            mConnectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE, 1);
+            fail("Was able to call requestRouteToHost");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+}
diff --git a/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/NoNetworkStatePermissionTest.java b/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/NoNetworkStatePermissionTest.java
new file mode 100644
index 0000000..8547261
--- /dev/null
+++ b/tests/netlegacy22.permission/src/android/net/cts/legacy/api22/permission/NoNetworkStatePermissionTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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.net.cts.legacy.api22.permission;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+import java.net.InetAddress;
+
+/**
+ * Verify ConnectivityManager related methods without specific network state permissions.
+ */
+public class NoNetworkStatePermissionTest extends AndroidTestCase {
+    private ConnectivityManager mConnectivityManager;
+    private static final int TEST_NETWORK_TYPE = ConnectivityManager.TYPE_MOBILE;
+    private static final String TEST_FEATURE = "enableHIPRI";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mConnectivityManager = (ConnectivityManager) mContext.getSystemService(
+                Context.CONNECTIVITY_SERVICE);
+        assertNotNull(mConnectivityManager);
+    }
+
+    /**
+     * Verify that ConnectivityManager#startUsingNetworkFeature() requires permissions.
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+     */
+    @SmallTest
+    public void testStartUsingNetworkFeature() {
+        try {
+            mConnectivityManager.startUsingNetworkFeature(TEST_NETWORK_TYPE, TEST_FEATURE);
+            fail("ConnectivityManager.startUsingNetworkFeature didn't throw SecurityException as"
+                    + " expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+
+    /**
+     * Verify that ConnectivityManager#requestRouteToHost() requires permissions.
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
+     */
+    @SmallTest
+    public void testRequestRouteToHost() {
+        try {
+            mConnectivityManager.requestRouteToHost(TEST_NETWORK_TYPE, 0xffffffff);
+            fail("ConnectivityManager.requestRouteToHost didn't throw SecurityException as"
+                    + " expected");
+        } catch (SecurityException e) {
+            // expected
+        }
+    }
+}
diff --git a/tests/netsecpolicy/Android.mk b/tests/netsecpolicy/Android.mk
new file mode 100644
index 0000000..137672e
--- /dev/null
+++ b/tests/netsecpolicy/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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/netsecpolicy/usescleartexttraffic-false/Android.mk b/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
new file mode 100644
index 0000000..1af3b49
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
@@ -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.
+
+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, \
+    ../usescleartexttraffic-shared/src)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficFalse
+
+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
new file mode 100644
index 0000000..c87b800
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-false/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.netsecpolicy.usescleartext.false.cts">
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-library android:name="org.apache.http.legacy"/>
+
+    <application android:usesCleartextTraffic="false">
+    </application>
+</manifest>
diff --git a/tests/netsecpolicy/usescleartexttraffic-shared/src/Dummy.java b/tests/netsecpolicy/usescleartexttraffic-shared/src/Dummy.java
new file mode 100644
index 0000000..2705a5f
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-shared/src/Dummy.java
@@ -0,0 +1,2 @@
+public class Dummy {
+}
diff --git a/tests/netsecpolicy/usescleartexttraffic-true/Android.mk b/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
new file mode 100644
index 0000000..5effc57
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
@@ -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.
+
+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, \
+    ../usescleartexttraffic-shared/src)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficTrue
+
+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
new file mode 100644
index 0000000..da15ddd
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-true/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.netsecpolicy.usescleartext.true.cts">
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-library android:name="org.apache.http.legacy"/>
+
+    <application android:usesCleartextTraffic="true">
+    </application>
+</manifest>
diff --git a/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk b/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
new file mode 100644
index 0000000..685a16f
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
@@ -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.
+
+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, \
+    ../usescleartexttraffic-shared/src)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficUnspecified
+
+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
new file mode 100644
index 0000000..5b3a181
--- /dev/null
+++ b/tests/netsecpolicy/usescleartexttraffic-unspecified/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.netsecpolicy.usescleartext.unspecified.cts">
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+    <uses-library android:name="org.apache.http.legacy"/>
+
+    <application>
+    </application>
+</manifest>
diff --git a/tests/print/Android.mk b/tests/print/Android.mk
deleted file mode 100644
index fea7dc0..0000000
--- a/tests/print/Android.mk
+++ /dev/null
@@ -1,36 +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)
-
-##################################################
-# Build the print instrument library
-##################################################
-include $(CLEAR_VARS)
-LOCAL_MODULE := CtsPrintInstrument
-LOCAL_SRC_FILES := $(call all-subdir-java-files) \
-    src/android/print/cts/IPrivilegedOperations.aidl
-LOCAL_MODULE_TAGS := optional
-LOCAL_DEX_PREOPT := false
-
-include $(BUILD_JAVA_LIBRARY)
-
-# Copy the shell script to run the print instrument Jar to the CTS out folder.
-$(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar : $(LOCAL_BUILT_MODULE) | $(ACP) 
-	$(copy-file-to-target)
-
-# Copy the built print instrument library Jar to the CTS out folder.
-$(CTS_TESTCASES_OUT)/print-instrument : $(LOCAL_PATH)/print-instrument | $(ACP)
-	$(copy-file-to-target)
-
diff --git a/tests/print/print-instrument b/tests/print/print-instrument
deleted file mode 100755
index a79cb8a..0000000
--- a/tests/print/print-instrument
+++ /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.
-
-# Script to start "print-instrument" on the device
-#
-# The script sets up an alternative dalvik cache when running as
-# non-root. Jar files needs to be dexopt'd to run in Dalvik. For
-# plain jar files, this is done at first use. shell user does not
-# have write permission to default system Dalvik cache so we
-# redirect to an alternative cache.
-
-RUN_BASE=/data/local/tmp
-
-# If not running as root, use an alternative dex cache.
-if [ ${USER_ID} -ne 0 ]; then
-  tmp_cache=${RUN_BASE}/dalvik-cache
-  if [ ! -d ${tmp_cache} ]; then
-    mkdir -p ${tmp_cache}
-  fi
-  export ANDROID_DATA=${RUN_BASE}
-fi
-
-# Run print-instrument.
-export CLASSPATH=${RUN_BASE}/CtsPrintInstrument.jar
-
-exec app_process ${RUN_BASE} android.print.cts.PrintInstrument ${@}
diff --git a/tests/print/src/android/print/cts/IPrivilegedOperations.aidl b/tests/print/src/android/print/cts/IPrivilegedOperations.aidl
deleted file mode 100644
index 93c8c3e..0000000
--- a/tests/print/src/android/print/cts/IPrivilegedOperations.aidl
+++ /dev/null
@@ -1,21 +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.print.cts;
-
-interface IPrivilegedOperations {
-    boolean clearApplicationUserData(String packageName);
-}
diff --git a/tests/print/src/android/print/cts/PrintInstrument.java b/tests/print/src/android/print/cts/PrintInstrument.java
deleted file mode 100644
index 1c568a1..0000000
--- a/tests/print/src/android/print/cts/PrintInstrument.java
+++ /dev/null
@@ -1,279 +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.print.cts;
-
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.app.IInstrumentationWatcher;
-import android.app.Instrumentation;
-import android.app.UiAutomationConnection;
-import android.content.ComponentName;
-import android.content.pm.IPackageDataObserver;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.UserHandle;
-import android.util.AndroidException;
-import android.view.IWindowManager;
-
-import com.android.internal.os.BaseCommand;
-
-import java.io.PrintStream;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public final class PrintInstrument extends BaseCommand {
-
-    private static final String ARG_PRIVILEGED_OPS = "ARG_PRIVILEGED_OPS";
-
-    private IActivityManager mAm;
-
-    public static void main(String[] args) {
-        PrintInstrument instrumenter = new PrintInstrument();
-        instrumenter.run(args);
-    }
-
-    @Override
-    public void onRun() throws Exception {
-        mAm = ActivityManagerNative.getDefault();
-        if (mAm == null) {
-            System.err.println(NO_SYSTEM_ERROR_CODE);
-            throw new AndroidException("Can't connect to activity manager;"
-                    + " is the system running?");
-        }
-
-        String op = nextArgRequired();
-
-        if (op.equals("instrument")) {
-            runInstrument();
-        } else {
-            showError("Error: unknown command '" + op + "'");
-        }
-    }
-
-    @Override
-    public void onShowUsage(PrintStream out) {
-        /* do nothing */
-    }
-
-    @SuppressWarnings("deprecation")
-    private void runInstrument() throws Exception {
-        String profileFile = null;
-        boolean wait = false;
-        boolean rawMode = false;
-        boolean no_window_animation = false;
-        int userId = UserHandle.USER_CURRENT;
-        Bundle args = new Bundle();
-        String argKey = null, argValue = null;
-        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
-
-        String opt;
-        while ((opt=nextOption()) != null) {
-            if (opt.equals("-p")) {
-                profileFile = nextArgRequired();
-            } else if (opt.equals("-w")) {
-                wait = true;
-            } else if (opt.equals("-r")) {
-                rawMode = true;
-            } else if (opt.equals("-e")) {
-                argKey = nextArgRequired();
-                argValue = nextArgRequired();
-                args.putString(argKey, argValue);
-            } else if (opt.equals("--no_window_animation")
-                    || opt.equals("--no-window-animation")) {
-                no_window_animation = true;
-            } else if (opt.equals("--user")) {
-                userId = parseUserArg(nextArgRequired());
-            } else {
-                System.err.println("Error: Unknown option: " + opt);
-                return;
-            }
-        }
-
-        if (userId == UserHandle.USER_ALL) {
-            System.err.println("Error: Can't start instrumentation with user 'all'");
-            return;
-        }
-
-        String cnArg = nextArgRequired();
-        ComponentName cn = ComponentName.unflattenFromString(cnArg);
-        if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg);
-
-        InstrumentationWatcher watcher = null;
-        UiAutomationConnection connection = null;
-        if (wait) {
-            watcher = new InstrumentationWatcher();
-            watcher.setRawOutput(rawMode);
-            connection = new UiAutomationConnection();
-        }
-
-        float[] oldAnims = null;
-        if (no_window_animation) {
-            oldAnims = wm.getAnimationScales();
-            wm.setAnimationScale(0, 0.0f);
-            wm.setAnimationScale(1, 0.0f);
-        }
-
-        args.putIBinder(ARG_PRIVILEGED_OPS, new PrivilegedOperations(mAm));
-
-        if (!mAm.startInstrumentation(cn, profileFile, 0, args, watcher, connection, userId, null)) {
-            throw new AndroidException("INSTRUMENTATION_FAILED: " + cn.flattenToString());
-        }
-
-        if (watcher != null) {
-            if (!watcher.waitForFinish()) {
-                System.out.println("INSTRUMENTATION_ABORTED: System has crashed.");
-            }
-        }
-
-        if (oldAnims != null) {
-            wm.setAnimationScales(oldAnims);
-        }
-    }
-
-    private int parseUserArg(String arg) {
-        int userId;
-        if ("all".equals(arg)) {
-            userId = UserHandle.USER_ALL;
-        } else if ("current".equals(arg) || "cur".equals(arg)) {
-            userId = UserHandle.USER_CURRENT;
-        } else {
-            userId = Integer.parseInt(arg);
-        }
-        return userId;
-    }
-
-    private class InstrumentationWatcher extends IInstrumentationWatcher.Stub {
-        private boolean mFinished = false;
-        private boolean mRawMode = false;
-
-        /**
-         * Set or reset "raw mode".  In "raw mode", all bundles are dumped.  In "pretty mode",
-         * if a bundle includes Instrumentation.REPORT_KEY_STREAMRESULT, just print that.
-         * @param rawMode true for raw mode, false for pretty mode.
-         */
-        public void setRawOutput(boolean rawMode) {
-            mRawMode = rawMode;
-        }
-
-        @Override
-        public void instrumentationStatus(ComponentName name, int resultCode, Bundle results) {
-            synchronized (this) {
-                // pretty printer mode?
-                String pretty = null;
-                if (!mRawMode && results != null) {
-                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
-                }
-                if (pretty != null) {
-                    System.out.print(pretty);
-                } else {
-                    if (results != null) {
-                        for (String key : results.keySet()) {
-                            System.out.println(
-                                    "INSTRUMENTATION_STATUS: " + key + "=" + results.get(key));
-                        }
-                    }
-                    System.out.println("INSTRUMENTATION_STATUS_CODE: " + resultCode);
-                }
-                notifyAll();
-            }
-        }
-
-        @Override
-        public void instrumentationFinished(ComponentName name, int resultCode,
-                Bundle results) {
-            synchronized (this) {
-                // pretty printer mode?
-                String pretty = null;
-                if (!mRawMode && results != null) {
-                    pretty = results.getString(Instrumentation.REPORT_KEY_STREAMRESULT);
-                }
-                if (pretty != null) {
-                    System.out.println(pretty);
-                } else {
-                    if (results != null) {
-                        for (String key : results.keySet()) {
-                            System.out.println(
-                                    "INSTRUMENTATION_RESULT: " + key + "=" + results.get(key));
-                        }
-                    }
-                    System.out.println("INSTRUMENTATION_CODE: " + resultCode);
-                }
-                mFinished = true;
-                notifyAll();
-            }
-        }
-
-        public boolean waitForFinish() {
-            synchronized (this) {
-                while (!mFinished) {
-                    try {
-                        if (!mAm.asBinder().pingBinder()) {
-                            return false;
-                        }
-                        wait(1000);
-                    } catch (InterruptedException e) {
-                        throw new IllegalStateException(e);
-                    }
-                }
-            }
-            return true;
-        }
-    }
-
-    private static final class PrivilegedOperations extends IPrivilegedOperations.Stub {
-        private final IActivityManager mAm;
-
-        public PrivilegedOperations(IActivityManager am) {
-            mAm = am;
-        }
-
-        @Override
-        public boolean clearApplicationUserData(final String clearedPackageName)
-                throws RemoteException {
-            final long identity = Binder.clearCallingIdentity();
-            try {
-                final AtomicBoolean success = new AtomicBoolean();
-                final CountDownLatch completionLatch = new CountDownLatch(1);
-
-                mAm.clearApplicationUserData(clearedPackageName,
-                        new IPackageDataObserver.Stub() {
-                            @Override
-                            public void onRemoveCompleted(String packageName, boolean succeeded) {
-                                if (clearedPackageName.equals(packageName) && succeeded) {
-                                    success.set(true);
-                                } else {
-                                    success.set(false);
-                                }
-                                completionLatch.countDown();
-                            }
-                }, UserHandle.USER_CURRENT);
-
-                try {
-                    completionLatch.await();
-                } catch (InterruptedException ie) {
-                    /* ignore */
-                }
-
-                return success.get();
-            } finally {
-                Binder.restoreCallingIdentity(identity);
-            }
-        }
-    }
-}
diff --git a/tests/tests/accessibility/Android.mk b/tests/tests/accessibility/Android.mk
index 9f98b16..263c47b 100644
--- a/tests/tests/accessibility/Android.mk
+++ b/tests/tests/accessibility/Android.mk
@@ -26,7 +26,6 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
 
-# This test runner sets up/cleans up the device before/after running the tests.
-LOCAL_CTS_TEST_RUNNER := com.android.cts.tradefed.testtype.AccessibilityTestRunner
+LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/accessibility/AndroidManifest.xml b/tests/tests/accessibility/AndroidManifest.xml
index 319fb49..b3bcbc8 100644
--- a/tests/tests/accessibility/AndroidManifest.xml
+++ b/tests/tests/accessibility/AndroidManifest.xml
@@ -17,18 +17,19 @@
  -->
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="android.view.cts.accessibility">
+          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>
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
-  <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
-                   android:targetPackage="android.view.cts.accessibility"
-                   android:label="Tests for the accessibility APIs.">
+    <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" />
+                   android:value="com.android.cts.runner.CtsTestRunListener" />
     </instrumentation>
 
 </manifest>
diff --git a/tests/tests/accessibility/AndroidTest.xml b/tests/tests/accessibility/AndroidTest.xml
new file mode 100644
index 0000000..7832508
--- /dev/null
+++ b/tests/tests/accessibility/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="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/AccessibilityEventTest.java b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
index 8be2b99..db4e54b 100644
--- a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
+++ b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityEventTest.java
@@ -113,6 +113,8 @@
                 AccessibilityEvent.TYPE_VIEW_HOVER_EXIT));
         assertEquals("TYPE_VIEW_LONG_CLICKED", AccessibilityEvent.eventTypeToString(
                 AccessibilityEvent.TYPE_VIEW_LONG_CLICKED));
+        assertEquals("TYPE_VIEW_CONTEXT_CLICKED", AccessibilityEvent.eventTypeToString(
+                AccessibilityEvent.TYPE_VIEW_CONTEXT_CLICKED));
         assertEquals("TYPE_VIEW_SCROLLED", AccessibilityEvent.eventTypeToString(
                 AccessibilityEvent.TYPE_VIEW_SCROLLED));
         assertEquals("TYPE_VIEW_SELECTED", AccessibilityEvent.eventTypeToString(
diff --git a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
index f5e1d48..506c022 100644
--- a/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
+++ b/tests/tests/accessibility/src/android/view/accessibility/cts/AccessibilityNodeInfoTest.java
@@ -185,6 +185,7 @@
         info.setFocusable(true);
         info.setFocused(true);
         info.setLongClickable(true);
+        info.setContextClickable(true);
         info.setPassword(true);
         info.setScrollable(true);
         info.setSelected(true);
@@ -235,6 +236,8 @@
                 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(),
@@ -281,6 +284,7 @@
         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());
diff --git a/tests/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java b/tests/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.java
new file mode 100644
index 0000000..53eb215
--- /dev/null
+++ b/tests/tests/accessibility/src/android/view/accessibility/cts/CaptioningManagerTest.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 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/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
index b11248a..f5b29cf 100644
--- a/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
+++ b/tests/tests/accessibilityservice/src/android/accessibilityservice/cts/AccessibilityEndToEndTest.java
@@ -24,8 +24,10 @@
 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;
@@ -44,6 +46,8 @@
 public class AccessibilityEndToEndTest extends
         AccessibilityActivityTestCase<AccessibilityEndToEndActivity> {
 
+    private static final String LOG_TAG = "AccessibilityEndToEndTest";
+
     /**
      * Creates a new instance for testing {@link AccessibilityEndToEndActivity}.
      */
@@ -309,16 +313,29 @@
     @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();
-        notification.icon = android.R.drawable.stat_notify_call_mute;
-        notification.contentIntent = PendingIntent.getActivity(getActivity(), 0, new Intent(),
-                PendingIntent.FLAG_CANCEL_CURRENT);
-        notification.tickerText = message;
-        notification.setLatestEventInfo(getActivity(), "", "", notification.contentIntent);
+        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();
diff --git a/tests/tests/accounts/Android.mk b/tests/tests/accounts/Android.mk
index 1579822..6ed35c6 100644
--- a/tests/tests/accounts/Android.mk
+++ b/tests/tests/accounts/Android.mk
@@ -21,7 +21,7 @@
 # and 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 := CtsAccountTestsCommon ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -30,3 +30,4 @@
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/accounts/AndroidManifest.xml b/tests/tests/accounts/AndroidManifest.xml
index c671ff0..d882690 100644
--- a/tests/tests/accounts/AndroidManifest.xml
+++ b/tests/tests/accounts/AndroidManifest.xml
@@ -18,11 +18,9 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.accounts.cts">
 
-    <!-- Used for AccountManagerService test, don't delete this permission -->
-    <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" />
+    <!-- Don't need GET_ACCOUNTS because share a Uid with the relevant
+         authenticators -->
+
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
     <application>
@@ -43,10 +41,21 @@
             <intent-filter>
                 <action android:name="android.accounts.AccountAuthenticator" />
             </intent-filter>
-
             <meta-data android:name="android.accounts.AccountAuthenticator"
                        android:resource="@xml/authenticator" />
         </service>
+
+        <service android:name="MockCustomTokenAccountService" android:exported="true"
+                 android:process="android.accounts.cts">
+            <intent-filter>
+                <action android:name="android.accounts.AccountAuthenticator" />
+            </intent-filter>
+            <meta-data android:name="android.accounts.AccountAuthenticator"
+                       android:resource="@xml/custom_token_authenticator" />
+            <meta-data android:name="android.accounts.AccountAuthenticator.customTokens"
+                       android:value="1" />
+
+        </service>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/accounts/AndroidTest.xml b/tests/tests/accounts/AndroidTest.xml
new file mode 100644
index 0000000..3e29c9c
--- /dev/null
+++ b/tests/tests/accounts/AndroidTest.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/CtsUnaffiliatedAccountAuthenticators/Android.mk b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/Android.mk
new file mode 100644
index 0000000..cb504da
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+# LOCAL_MODULE_TAGS := tests
+
+# and when built explicitly put it in the data partition
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+        ctstestrunner \
+	CtsAccountTestsCommon
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_RESOURCE_DIR += $(LOCAL_PATH)/res
+
+LOCAL_PACKAGE_NAME := CtsUnaffiliatedAccountAuthenticators
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_CERTIFICATE := cts/hostsidetests/appsecurity/certs/cts-testkey2
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/AndroidManifest.xml b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/AndroidManifest.xml
new file mode 100644
index 0000000..c32f89f
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/AndroidManifest.xml
@@ -0,0 +1,56 @@
+<?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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.accounts.cts.unaffiliated">
+
+    <!-- Used for AccountManagerService test, don't delete this permission -->
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <application>
+
+        <activity
+                android:name="android.accounts.cts.common.TestAuthenticatorActivity"
+                android:exported="true" />
+
+        <provider
+                android:name="android.accounts.cts.common.AuthenticatorContentProvider"
+                android:authorities="android.accounts.cts.unaffiliated.authenticators.provider"
+                android:exported="true" />
+
+        <service
+                android:name=".StdAccountAuthService"
+                android:exported="false">
+            <intent-filter>
+                <action android:name="android.accounts.AccountAuthenticator" />
+            </intent-filter>
+            <meta-data android:name="android.accounts.AccountAuthenticator"
+                       android:resource="@xml/standard_authenticator" />
+        </service>
+<!--
+        <service android:name=".CustomAccountAuthService" android:exported="false">
+            <intent-filter>
+                <action android:name="android.accounts.AccountAuthenticator" />
+            </intent-filter>
+            <meta-data android:name="android.accounts.AccountAuthenticator"
+                       android:resource="@xml/custom_authenticator" />
+        </service>
+        -->
+
+    </application>
+</manifest>
+
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_minitab_selected.png b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_minitab_selected.png
new file mode 100644
index 0000000..c730050
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_minitab_selected.png
Binary files differ
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_minitab_selected_custom_account.png b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_minitab_selected_custom_account.png
new file mode 100644
index 0000000..3fbbc94
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_minitab_selected_custom_account.png
Binary files differ
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_selected.png b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_selected.png
new file mode 100644
index 0000000..72a065c
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_selected.png
Binary files differ
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_selected_custom_account.png b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_selected_custom_account.png
new file mode 100644
index 0000000..70e35c0
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/drawable/ic_cts_selected_custom_account.png
Binary files differ
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/values/strings.xml b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/values/strings.xml
new file mode 100644
index 0000000..442669b
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/values/strings.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.
+ */
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- Label for this package -->
+    <string name="label">Android CTS - Account</string>
+</resources>
\ No newline at end of file
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/xml/custom_authenticator.xml b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/xml/custom_authenticator.xml
new file mode 100644
index 0000000..3485f76
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/xml/custom_authenticator.xml
@@ -0,0 +1,29 @@
+<?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.
+ */
+-->
+
+<!-- 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="android.accounts.test.custom"
+    android:icon="@drawable/ic_cts_selected_custom_account"
+    android:smallIcon="@drawable/ic_cts_minitab_selected_custom_account"
+    android:customTokens="true"
+    android:label="@string/label"
+/>
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/xml/standard_authenticator.xml b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/xml/standard_authenticator.xml
new file mode 100644
index 0000000..0c843b9
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/res/xml/standard_authenticator.xml
@@ -0,0 +1,28 @@
+<?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.
+ */
+-->
+
+<!-- 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="android.accounts.test.standard.unaffiliated"
+    android:icon="@drawable/ic_cts_selected"
+    android:smallIcon="@drawable/ic_cts_minitab_selected"
+    android:label="@string/label"
+/>
diff --git a/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/src/android/accounts/cts/unaffiliated/StdAccountAuthService.java b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/src/android/accounts/cts/unaffiliated/StdAccountAuthService.java
new file mode 100644
index 0000000..de87ac7
--- /dev/null
+++ b/tests/tests/accounts/CtsUnaffiliatedAccountAuthenticators/src/android/accounts/cts/unaffiliated/StdAccountAuthService.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.accounts.cts.unaffiliated;
+
+import android.accounts.cts.common.Fixtures;
+import android.accounts.cts.common.TestAccountAuthenticator;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * a basic Mock Service for wrapping the MockAccountAuthenticator
+ */
+public class StdAccountAuthService extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        TestAccountAuthenticator auth =
+                new TestAccountAuthenticator(this, Fixtures.TYPE_STANDARD_UNAFFILIATED);
+        return auth.getIBinder();
+    }
+}
diff --git a/tests/tests/accounts/common/Android.mk b/tests/tests/accounts/common/Android.mk
new file mode 100644
index 0000000..cac9c5e
--- /dev/null
+++ b/tests/tests/accounts/common/Android.mk
@@ -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.
+
+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)
+
+# Includes all the java files, and explicitly declares any aidl files
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src) \
+    $(call all-Iaidl-files-under, src)
+
+LOCAL_AIDL_INCLUDES += $(LOCAL_PATH)/src
+
+LOCAL_MODULE:= CtsAccountTestsCommon
+
+LOCAL_SDK_VERSION := current
+
+# Build the actual static library
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/accounts/common/AndroidManifest.xml b/tests/tests/accounts/common/AndroidManifest.xml
new file mode 100644
index 0000000..6e6d107
--- /dev/null
+++ b/tests/tests/accounts/common/AndroidManifest.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.accounts.test.shared">
+    <uses-sdk
+        android:minSdkVersion="4" />
+    <application />
+</manifest>
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/AuthenticatorContentProvider.java b/tests/tests/accounts/common/src/android/accounts/cts/common/AuthenticatorContentProvider.java
new file mode 100644
index 0000000..b52dae3
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/AuthenticatorContentProvider.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accounts.cts.common;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AuthenticatorDescription;
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcelable;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+public class AuthenticatorContentProvider extends ContentProvider {
+
+    public static final String AUTHORITY =
+            "android.accounts.cts.unaffiliated.authenticators.provider";
+
+    public static final int RESULT_SUCCESS = 1;
+    public static final int RESULT_FAIL = 2;
+
+    public static final String METHOD_GET = "get";
+    public static final String METHOD_SETUP = "setup";
+    public static final String METHOD_TEARDOWN = "setup";
+
+    public static final int ACTION_GET = 1;
+    public static final int ACTION_SETUP = 2;
+    public static final int ACTION_TEARDOWN = 3;
+
+    public static final int ARG_UNAFFILIATED = 10;
+    public static final int ARG_AFFILIATED = 11;
+
+    public static final String KEY_CALLBACK = "callback";
+    public static final String KEY_TX = "tx";
+
+    public static final AtomicReference<Parcelable> sLastTx = new AtomicReference<>();
+
+    public static void setTx(Parcelable tx) {
+        sLastTx.set(tx);
+    }
+
+    @Override
+    // public void handleMessage(Message msg) {
+    public Bundle call(String method, String arg, Bundle extras) {
+        super.call(method, arg, extras);
+        Bundle result = new Bundle();
+        if (METHOD_GET.equals(method)) {
+            result.putParcelable(KEY_TX, sLastTx.get());
+            return result;
+        } else if (METHOD_SETUP.equals(method)) {
+            setup();
+            return result;
+        } else if (METHOD_TEARDOWN.equals(method)) {
+            teardown();
+            return result;
+        } else {
+            throw new IllegalArgumentException("Unrecognized method!");
+        }
+    }
+
+    public void setup() {
+        Context context = getContext();
+        AccountManager am = AccountManager.get(context);
+        AuthenticatorDescription[] authenticators = am.getAuthenticatorTypes();
+        for (AuthenticatorDescription a : authenticators) {
+            /*
+             * Populate relevant test information for authenticators in the
+             * same package as the TestAuthenticatorSupportHandler.
+             */
+            if (a.packageName.equals(context.getPackageName())) {
+                for (String name : Fixtures.getFixtureAccountNames()) {
+                    Account account = new Account(name, a.type);
+                    am.addAccountExplicitly(account, Fixtures.PREFIX_PASSWORD + name, null);
+                }
+            }
+        }
+    }
+
+    public void teardown() {
+        Context context = getContext();
+        AccountManager am = AccountManager.get(context);
+        AuthenticatorDescription[] authenticators = am.getAuthenticatorTypes();
+        for (AuthenticatorDescription a : authenticators) {
+            /*
+             * Populate relevant test information for authenticators in the
+             * same package as the TestAuthenticatorSupportHandler.
+             */
+            if (a.packageName.equals(context.getPackageName())) {
+                Account[] accountsToRemove = am.getAccountsByType(a.type);
+                for (Account account : accountsToRemove) {
+                    am.removeAccountExplicitly(account);
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreate() {
+        return true;   
+    }
+
+    @Override
+    public Cursor query(
+            Uri uri, 
+            String[] projection,
+            String selection,
+            String[] selectionArgs,
+            String sortOrder) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        throw new UnsupportedOperationException();
+    }
+}
+
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/Fixtures.java b/tests/tests/accounts/common/src/android/accounts/cts/common/Fixtures.java
new file mode 100644
index 0000000..f8636a0
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/Fixtures.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accounts.cts.common;
+
+import android.accounts.Account;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Constants shared amongst account hostside tests.
+ */
+public final class Fixtures {
+
+    public static final String TYPE_CUSTOM = "android.accounts.test.custom";
+    public static final String TYPE_STANDARD = "android.accounts.test.standard";
+
+    public static final String TYPE_STANDARD_UNAFFILIATED =
+            "android.accounts.test.standard.unaffiliated";
+
+    public static final String PREFIX_TOKEN = "token:";
+    public static final String PREFIX_PASSWORD = "password:";
+
+    public static final String SUFFIX_NAME_FIXTURE = "fixture.com";
+    public static final String SUFFIX_NAME_TEST = "test.com";
+
+    public static final String PREFIX_NAME_SUCCESS = "success_on_return";
+    public static final String PREFIX_NAME_ERROR = "error";
+    public static final String PREFIX_NAME_INTERVENE = "intervene";
+
+    private static final String[] accountNamePrefixes = new String[] {
+            PREFIX_NAME_SUCCESS,
+            PREFIX_NAME_ERROR,
+            PREFIX_NAME_INTERVENE
+    };
+
+    public static final Account ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS = new Account(
+            PREFIX_NAME_SUCCESS + "@" + SUFFIX_NAME_FIXTURE,
+            TYPE_STANDARD_UNAFFILIATED);
+
+    public static List<String> getFixtureAccountNames() {
+        List<String> accountNames = new ArrayList<>(accountNamePrefixes.length);
+        for (String prefix : accountNamePrefixes) {
+            accountNames.add(prefix + "@" + SUFFIX_NAME_FIXTURE);
+        }
+        return accountNames;
+    }
+
+    public static final int TEST_SUPPORT_RESULT_SUCCESS = 1;
+    public static final int TEST_SUPPORT_RESULT_FAIL = 2;
+
+    public static final String KEY_ACCOUNT_NAME = "test:account_name";
+
+    public static final String KEY_CALLBACK = "test:callback";
+    public static final String KEY_CALLBACK_REQUIRED = "test:callback_required";
+    public static final String KEY_RESULT = "test:result";
+    public static final String KEY_TOKEN_EXPIRY = "test:token_duration";
+
+    private Fixtures() {}
+}
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/TestAccountAuthenticator.java b/tests/tests/accounts/common/src/android/accounts/cts/common/TestAccountAuthenticator.java
new file mode 100644
index 0000000..1fac1ea
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/TestAccountAuthenticator.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accounts.cts.common;
+
+import android.accounts.AbstractAccountAuthenticator;
+import android.accounts.Account;
+import android.accounts.AccountAuthenticatorResponse;
+import android.accounts.AccountManager;
+import android.accounts.NetworkErrorException;
+import android.accounts.cts.common.tx.AddAccountTx;
+import android.accounts.cts.common.tx.ConfirmCredentialsTx;
+import android.accounts.cts.common.tx.GetAuthTokenLabelTx;
+import android.accounts.cts.common.tx.GetAuthTokenTx;
+import android.accounts.cts.common.tx.HasFeaturesTx;
+import android.accounts.cts.common.tx.UpdateCredentialsTx;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+
+import java.util.Arrays;
+
+public class TestAccountAuthenticator extends AbstractAccountAuthenticator {
+
+    private final String mAccountType;
+    private final Context mContext;
+    private volatile int mCounter = 0;
+
+    public TestAccountAuthenticator(Context context, String accountType) {
+        super(context);
+        mContext = context;
+        mAccountType = accountType;
+    }
+
+    @Override
+    public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
+        throw new UnsupportedOperationException(
+                "editProperties should be tested using the MockAuthenticator");
+    }
+
+    @Override
+    public Bundle addAccount(
+            AccountAuthenticatorResponse response,
+            String accountType,
+            String authTokenType,
+            String[] requiredFeatures,
+            Bundle options) throws NetworkErrorException {
+        if (!mAccountType.equals(accountType)) {
+            throw new IllegalArgumentException("Request to the wrong authenticator!");
+        }
+        String accountName = null;
+        boolean isCallbackRequired = false;
+        if (options != null) {
+            accountName = options.getString(Fixtures.KEY_ACCOUNT_NAME);
+            isCallbackRequired = options.getBoolean(Fixtures.KEY_CALLBACK_REQUIRED, false);
+        }
+        Bundle result = new Bundle();
+        AuthenticatorContentProvider.setTx(
+                new AddAccountTx(accountType, authTokenType, requiredFeatures, options, result));
+        if (accountName.startsWith(Fixtures.PREFIX_NAME_SUCCESS)) {
+            // fill bundle with a success result.
+            result.putString(AccountManager.KEY_ACCOUNT_NAME, accountName);
+            result.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccountType);
+        } else if (accountName.startsWith(Fixtures.PREFIX_NAME_INTERVENE)) {
+            // Specify data to be returned by the eventual activity.
+            Intent eventualActivityResultData = new Intent();
+            eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_NAME, accountName);
+            eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_TYPE, accountType);
+            // Fill result with Intent.
+            Intent intent = new Intent(mContext, TestAuthenticatorActivity.class);
+            intent.putExtra(Fixtures.KEY_RESULT, eventualActivityResultData);
+            intent.putExtra(Fixtures.KEY_CALLBACK, response);
+
+            result.putParcelable(AccountManager.KEY_INTENT, intent);
+        } else {
+            // fill with error
+            int errorCode = AccountManager.ERROR_CODE_INVALID_RESPONSE;
+            String errorMsg = "Default Error Message";
+            if (options != null) {
+                errorCode = options.getInt(AccountManager.KEY_ERROR_CODE);
+                errorMsg = options.getString(AccountManager.KEY_ERROR_MESSAGE);
+            }
+            result.putInt(AccountManager.KEY_ERROR_CODE, errorCode);
+            result.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
+        }
+
+        try {
+            return (isCallbackRequired) ? null : result;
+        } finally {
+            if (isCallbackRequired) {
+                response.onResult(result);
+            }
+        }
+    }
+
+    @Override
+    public Bundle confirmCredentials(
+            AccountAuthenticatorResponse response,
+            Account account,
+            Bundle options) throws NetworkErrorException {
+        if (!mAccountType.equals(account.type)) {
+            throw new IllegalArgumentException("Request to the wrong authenticator!");
+        }
+        Bundle result = new Bundle();
+        AuthenticatorContentProvider.setTx(
+                new ConfirmCredentialsTx(account, options, result));
+
+        boolean isCallbackRequired =
+                options != null && options.getBoolean(Fixtures.KEY_CALLBACK_REQUIRED);
+        if (account.name.startsWith(Fixtures.PREFIX_NAME_SUCCESS)) {
+            // fill bundle with a success result.
+            result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+            result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
+            result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
+        } else if (account.name.startsWith(Fixtures.PREFIX_NAME_INTERVENE)) {
+            // Specify data to be returned by the eventual activity.
+            Intent eventualActivityResultData = new Intent();
+            eventualActivityResultData.putExtra(AccountManager.KEY_BOOLEAN_RESULT, true);
+            eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
+            eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type);
+
+            // Fill result with Intent.
+            Intent intent = new Intent(mContext, TestAuthenticatorActivity.class);
+            intent.putExtra(Fixtures.KEY_RESULT, eventualActivityResultData);
+            intent.putExtra(Fixtures.KEY_CALLBACK, response);
+
+            result.putParcelable(AccountManager.KEY_INTENT, intent);
+        } else {
+            // fill with error
+            // fill with error
+            int errorCode = AccountManager.ERROR_CODE_INVALID_RESPONSE;
+            String errorMsg = "Default Error Message";
+            if (options != null) {
+                errorCode = options.getInt(AccountManager.KEY_ERROR_CODE);
+                errorMsg = options.getString(AccountManager.KEY_ERROR_MESSAGE);
+            }
+            result.putInt(AccountManager.KEY_ERROR_CODE, errorCode);
+            result.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
+        }
+
+        try {
+            return (isCallbackRequired) ? null : result;
+        } finally {
+            if (isCallbackRequired) {
+                response.onResult(result);
+            }
+        }
+    }
+
+    @Override
+    public Bundle getAuthToken(
+            AccountAuthenticatorResponse response,
+            Account account,
+            String authTokenType,
+            Bundle options) throws NetworkErrorException {
+        if (!mAccountType.equals(account.type)) {
+            throw new IllegalArgumentException("Request to the wrong authenticator!");
+        }
+        Bundle result = new Bundle();
+        AuthenticatorContentProvider.setTx(
+                new GetAuthTokenTx(account, authTokenType, options, result));
+        boolean isCallbackRequired =
+                options != null && options.getBoolean(Fixtures.KEY_CALLBACK_REQUIRED);
+        long expiryMillis = (options == null) ? 0 : options.getLong(Fixtures.KEY_TOKEN_EXPIRY);
+        if (account.name.startsWith(Fixtures.PREFIX_NAME_SUCCESS)) {
+            // fill bundle with a success result.
+            result.putString(
+                    AccountManager.KEY_AUTHTOKEN, Fixtures.PREFIX_TOKEN + mCounter++);
+            result.putLong(
+                    AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY,
+                    expiryMillis);
+            result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
+            result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
+        } else if (account.name.startsWith(Fixtures.PREFIX_NAME_INTERVENE)) {
+            // Specify data to be returned by the eventual activity.
+            Intent eventualActivityResultData = new Intent();
+            eventualActivityResultData.putExtra(
+                    AccountManager.KEY_AUTHTOKEN, Fixtures.PREFIX_TOKEN + mCounter++);
+            eventualActivityResultData.putExtra(
+                    AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY,
+                    expiryMillis);
+            eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
+            eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type);
+
+            // Fill result with Intent.
+            Intent intent = new Intent(mContext, TestAuthenticatorActivity.class);
+            intent.putExtra(Fixtures.KEY_RESULT, eventualActivityResultData);
+            intent.putExtra(Fixtures.KEY_CALLBACK, response);
+
+            result.putParcelable(AccountManager.KEY_INTENT, intent);
+
+        } else {
+            // fill with error
+            int errorCode = AccountManager.ERROR_CODE_INVALID_RESPONSE;
+            String errorMsg = "Default Error Message";
+            if (options != null) {
+                errorCode = options.getInt(AccountManager.KEY_ERROR_CODE);
+                errorMsg = options.getString(AccountManager.KEY_ERROR_MESSAGE);
+            }
+            result.putInt(AccountManager.KEY_ERROR_CODE, errorCode);
+            result.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
+        }
+
+        try {
+            return (isCallbackRequired) ? null : result;
+        } finally {
+            if (isCallbackRequired) {
+                response.onResult(result);
+            }
+        }
+    }
+
+    @Override
+    public String getAuthTokenLabel(String authTokenType) {
+        String result = "Label:" + authTokenType;
+        AuthenticatorContentProvider.setTx(
+                new GetAuthTokenLabelTx(authTokenType, result));
+        return result;
+    }
+
+    @Override
+    public Bundle updateCredentials(
+            AccountAuthenticatorResponse response,
+            Account account,
+            String authTokenType,
+            Bundle options) throws NetworkErrorException {
+        if (!mAccountType.equals(account.type)) {
+            throw new IllegalArgumentException("Request to the wrong authenticator!");
+        }
+        Bundle result = new Bundle();
+        AuthenticatorContentProvider.setTx(
+                new UpdateCredentialsTx(account, authTokenType, options, result));
+
+        boolean isCallbackRequired =
+                options != null && options.getBoolean(Fixtures.KEY_CALLBACK_REQUIRED);
+        if (account.name.startsWith(Fixtures.PREFIX_NAME_SUCCESS)) {
+            // fill bundle with a success result.
+            result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
+            result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
+        } else if (account.name.startsWith(Fixtures.PREFIX_NAME_INTERVENE)) {
+            // Specify data to be returned by the eventual activity.
+            Intent eventualActivityResultData = new Intent();
+            eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_NAME, account.name);
+            eventualActivityResultData.putExtra(AccountManager.KEY_ACCOUNT_TYPE, account.type);
+
+            // Fill result with Intent.
+            Intent intent = new Intent(mContext, TestAuthenticatorActivity.class);
+            intent.putExtra(Fixtures.KEY_RESULT, eventualActivityResultData);
+            intent.putExtra(Fixtures.KEY_CALLBACK, response);
+
+            result.putParcelable(AccountManager.KEY_INTENT, intent);
+        } else {
+            // fill with error
+            // fill with error
+            int errorCode = AccountManager.ERROR_CODE_INVALID_RESPONSE;
+            String errorMsg = "Default Error Message";
+            if (options != null) {
+                errorCode = options.getInt(AccountManager.KEY_ERROR_CODE);
+                errorMsg = options.getString(AccountManager.KEY_ERROR_MESSAGE);
+            }
+            result.putInt(AccountManager.KEY_ERROR_CODE, errorCode);
+            result.putString(AccountManager.KEY_ERROR_MESSAGE, errorMsg);
+        }
+
+        try {
+            return (isCallbackRequired) ? null : result;
+        } finally {
+            if (isCallbackRequired) {
+                response.onResult(result);
+            }
+        }
+    }
+
+    @Override
+    public Bundle hasFeatures(
+            AccountAuthenticatorResponse response,
+            Account account,
+            String[] features) throws NetworkErrorException {
+        if (!mAccountType.equals(account.type)) {
+            throw new IllegalArgumentException("Request to the wrong authenticator!");
+        }
+        Bundle result = new Bundle();
+        AuthenticatorContentProvider.setTx(
+                new HasFeaturesTx(account, features, result));
+        boolean isCallbackRequired =
+                Arrays.asList(features).contains(Fixtures.KEY_CALLBACK_REQUIRED);
+        if (account.name.startsWith(Fixtures.PREFIX_NAME_SUCCESS)) {
+            // fill bundle with a success result.
+            result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+        } else if (account.name.startsWith(Fixtures.PREFIX_NAME_INTERVENE)) {
+            // Specify data to be returned by the eventual activity.
+            Intent eventualActivityResultData = new Intent();
+            eventualActivityResultData.putExtra(AccountManager.KEY_BOOLEAN_RESULT, true);
+
+            Intent intent = new Intent(mContext, TestAuthenticatorActivity.class);
+            intent.putExtra(Fixtures.KEY_RESULT, eventualActivityResultData);
+            intent.putExtra(Fixtures.KEY_CALLBACK, response);
+
+            result.putParcelable(AccountManager.KEY_INTENT, intent);
+        } else {
+            // fill with error
+        }
+
+        try {
+            return (isCallbackRequired) ? null : result;
+        } finally {
+            if (isCallbackRequired) {
+                response.onResult(result);
+            }
+        }
+    }
+}
+
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/TestAuthenticatorActivity.java b/tests/tests/accounts/common/src/android/accounts/cts/common/TestAuthenticatorActivity.java
new file mode 100644
index 0000000..83c0533
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/TestAuthenticatorActivity.java
@@ -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.
+ */
+
+package android.accounts.cts.common;
+
+import android.accounts.AccountAuthenticatorResponse;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class TestAuthenticatorActivity extends Activity {
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        Intent intent = getIntent();
+        AccountAuthenticatorResponse response = intent.getParcelableExtra(Fixtures.KEY_CALLBACK);
+        Intent result = intent.getParcelableExtra(Fixtures.KEY_RESULT);
+        if (response != null) {
+            response.onResult(result.getExtras());
+        }
+        setResult(RESULT_OK, result);
+        finish();
+    }
+}
+
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/AddAccountTx.aidl b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/AddAccountTx.aidl
new file mode 100644
index 0000000..912322a
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/AddAccountTx.aidl
@@ -0,0 +1,3 @@
+package android.accounts.cts.common.tx;
+
+parcelable AddAccountTx;
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/AddAccountTx.java b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/AddAccountTx.java
new file mode 100644
index 0000000..3d829315
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/AddAccountTx.java
@@ -0,0 +1,70 @@
+package android.accounts.cts.common.tx;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AddAccountTx implements Parcelable {
+
+    public static final Parcelable.Creator<AddAccountTx> CREATOR =
+            new Parcelable.Creator<AddAccountTx>() {
+
+                @Override
+                public AddAccountTx createFromParcel(Parcel in) {
+                    return new AddAccountTx(in);
+                }
+
+                @Override
+                public AddAccountTx[] newArray(int size) {
+                    return new AddAccountTx[size];
+                }
+            };
+
+    public final String accountType;
+    public final String authTokenType;
+    public final List<String> requiredFeatures = new ArrayList<>();
+    public final Bundle options;
+    public final Bundle result;
+
+    private AddAccountTx(Parcel in) {
+        accountType = in.readString();
+        authTokenType = in.readString();
+        in.readStringList(requiredFeatures);
+        options = in.readBundle();
+        result = in.readBundle();
+    }
+
+    public AddAccountTx(
+            String accountType,
+            String authTokenType,
+            String[] requiredFeatures,
+            Bundle options,
+            Bundle result) {
+        this.accountType = accountType;
+        this.authTokenType = authTokenType;
+        if (requiredFeatures != null) {
+            for (String feature : requiredFeatures) {
+                this.requiredFeatures.add(feature);
+            }
+        }
+        this.options = options;
+        this.result = result;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(accountType);
+        out.writeString(authTokenType);
+        out.writeStringList(requiredFeatures);
+        out.writeBundle(options);
+        out.writeBundle(result);
+    }
+}
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/ConfirmCredentialsTx.aidl b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/ConfirmCredentialsTx.aidl
new file mode 100644
index 0000000..98a6367
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/ConfirmCredentialsTx.aidl
@@ -0,0 +1,3 @@
+package android.accounts.cts.common.tx;
+
+parcelable ConfirmCredentialsTx;
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/ConfirmCredentialsTx.java b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/ConfirmCredentialsTx.java
new file mode 100644
index 0000000..d73b0a5
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/ConfirmCredentialsTx.java
@@ -0,0 +1,54 @@
+package android.accounts.cts.common.tx;
+
+import android.accounts.Account;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class ConfirmCredentialsTx implements Parcelable {
+
+    public static final Parcelable.Creator<ConfirmCredentialsTx> CREATOR =
+            new Parcelable.Creator<ConfirmCredentialsTx>() {
+
+                @Override
+                public ConfirmCredentialsTx createFromParcel(Parcel in) {
+                    return new ConfirmCredentialsTx(in);
+                }
+
+                @Override
+                public ConfirmCredentialsTx[] newArray(int size) {
+                    return new ConfirmCredentialsTx[size];
+                }
+            };
+
+    public final Account account;
+    public final Bundle options;
+    public final Bundle result;
+
+    private ConfirmCredentialsTx(Parcel in) {
+        account = in.readParcelable(null);
+        options = in.readBundle();
+        result = in.readBundle();
+    }
+
+    public ConfirmCredentialsTx(
+            Account account,
+            Bundle options,
+            Bundle result) {
+        this.account = account;
+        this.options = options;
+        this.result = result;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(account, flags);
+        out.writeBundle(options);
+        out.writeBundle(result);
+    }
+}
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/EditPropertiesTx.aidl b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/EditPropertiesTx.aidl
new file mode 100644
index 0000000..d9e813f
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/EditPropertiesTx.aidl
@@ -0,0 +1,3 @@
+package android.accounts.cts.common.tx;
+
+parcelable EditPropertiesTx;
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/EditPropertiesTx.java b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/EditPropertiesTx.java
new file mode 100644
index 0000000..4eba64d
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/EditPropertiesTx.java
@@ -0,0 +1,48 @@
+package android.accounts.cts.common.tx;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class EditPropertiesTx implements Parcelable {
+
+    public static final Parcelable.Creator<EditPropertiesTx> CREATOR =
+            new Parcelable.Creator<EditPropertiesTx>() {
+
+                @Override
+                public EditPropertiesTx createFromParcel(Parcel in) {
+                    return new EditPropertiesTx(in);
+                }
+
+                @Override
+                public EditPropertiesTx[] newArray(int size) {
+                    return new EditPropertiesTx[size];
+                }
+            };
+
+    public final String accountType;
+    public final Bundle result;
+
+    private EditPropertiesTx(Parcel in) {
+        accountType = in.readString();
+        result = in.readBundle();
+    }
+
+    public EditPropertiesTx(
+            String accountType,
+            Bundle result) {
+        this.accountType = accountType;
+        this.result = result;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(accountType);
+        out.writeBundle(result);
+    }
+}
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAccountRemovalAllowedTx.aidl b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAccountRemovalAllowedTx.aidl
new file mode 100644
index 0000000..cbcd99d
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAccountRemovalAllowedTx.aidl
@@ -0,0 +1,3 @@
+package android.accounts.cts.common.tx;
+
+parcelable GetAccountRemovalAllowedTx;
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAccountRemovalAllowedTx.java b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAccountRemovalAllowedTx.java
new file mode 100644
index 0000000..0e456b0
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAccountRemovalAllowedTx.java
@@ -0,0 +1,49 @@
+package android.accounts.cts.common.tx;
+
+import android.accounts.Account;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class GetAccountRemovalAllowedTx implements Parcelable {
+
+    public static final Parcelable.Creator<GetAccountRemovalAllowedTx> CREATOR =
+            new Parcelable.Creator<GetAccountRemovalAllowedTx>() {
+
+                @Override
+                public GetAccountRemovalAllowedTx createFromParcel(Parcel in) {
+                    return new GetAccountRemovalAllowedTx(in);
+                }
+
+                @Override
+                public GetAccountRemovalAllowedTx[] newArray(int size) {
+                    return new GetAccountRemovalAllowedTx[size];
+                }
+            };
+
+    public final Account account;
+    public final Bundle result;
+
+    private GetAccountRemovalAllowedTx(Parcel in) {
+        account = in.readParcelable(null);
+        result = in.readBundle();
+    }
+
+    public GetAccountRemovalAllowedTx(
+            Account account,
+            Bundle result) {
+        this.account = account;
+        this.result = result;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(account, flags);
+        out.writeBundle(result);
+    }
+}
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenLabelTx.aidl b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenLabelTx.aidl
new file mode 100644
index 0000000..82aeb9e
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenLabelTx.aidl
@@ -0,0 +1,3 @@
+package android.accounts.cts.common.tx;
+
+parcelable GetAuthTokenLabelTx;
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenLabelTx.java b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenLabelTx.java
new file mode 100644
index 0000000..4a017dd
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenLabelTx.java
@@ -0,0 +1,47 @@
+package android.accounts.cts.common.tx;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class GetAuthTokenLabelTx implements Parcelable {
+
+    public static final Parcelable.Creator<GetAuthTokenLabelTx> CREATOR =
+            new Parcelable.Creator<GetAuthTokenLabelTx>() {
+
+                @Override
+                public GetAuthTokenLabelTx createFromParcel(Parcel in) {
+                    return new GetAuthTokenLabelTx(in);
+                }
+
+                @Override
+                public GetAuthTokenLabelTx[] newArray(int size) {
+                    return new GetAuthTokenLabelTx[size];
+                }
+            };
+
+    public final String authTokenType;
+    public final String result;
+
+    private GetAuthTokenLabelTx(Parcel in) {
+        authTokenType = in.readString();
+        result = in.readString();
+    }
+
+    public GetAuthTokenLabelTx(
+            String authTokenType,
+            String result) {
+        this.authTokenType = authTokenType;
+        this.result = result;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(authTokenType);
+        out.writeString(result);
+    }
+}
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenTx.aidl b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenTx.aidl
new file mode 100644
index 0000000..4ff5abb
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenTx.aidl
@@ -0,0 +1,3 @@
+package android.accounts.cts.common.tx;
+
+parcelable GetAuthTokenTx;
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenTx.java b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenTx.java
new file mode 100644
index 0000000..c328353
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/GetAuthTokenTx.java
@@ -0,0 +1,59 @@
+package android.accounts.cts.common.tx;
+
+import android.accounts.Account;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class GetAuthTokenTx implements Parcelable {
+
+    public static final Parcelable.Creator<GetAuthTokenTx> CREATOR =
+            new Parcelable.Creator<GetAuthTokenTx>() {
+
+                @Override
+                public GetAuthTokenTx createFromParcel(Parcel in) {
+                    return new GetAuthTokenTx(in);
+                }
+
+                @Override
+                public GetAuthTokenTx[] newArray(int size) {
+                    return new GetAuthTokenTx[size];
+                }
+            };
+
+    public final Account account;
+    public final String authTokenType;
+    public final Bundle options;
+    public final Bundle result;
+
+    private GetAuthTokenTx(Parcel in) {
+        account = in.readParcelable(null);
+        authTokenType = in.readString();
+        options = in.readBundle();
+        result = in.readBundle();
+    }
+
+    public GetAuthTokenTx(
+            Account account,
+            String authTokenType,
+            Bundle options,
+            Bundle result) {
+        this.account = account;
+        this.authTokenType = authTokenType;
+        this.options = options;
+        this.result = result;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(account, flags);
+        out.writeString(authTokenType);
+        out.writeBundle(options);
+        out.writeBundle(result);
+    }
+}
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/HasFeaturesTx.aidl b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/HasFeaturesTx.aidl
new file mode 100644
index 0000000..20b4a67
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/HasFeaturesTx.aidl
@@ -0,0 +1,3 @@
+package android.accounts.cts.common.tx;
+
+parcelable HasFeaturesTx;
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/HasFeaturesTx.java b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/HasFeaturesTx.java
new file mode 100644
index 0000000..81d3446
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/HasFeaturesTx.java
@@ -0,0 +1,61 @@
+package android.accounts.cts.common.tx;
+
+import android.accounts.Account;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class HasFeaturesTx implements Parcelable {
+
+    public static final Parcelable.Creator<HasFeaturesTx> CREATOR =
+            new Parcelable.Creator<HasFeaturesTx>() {
+
+                @Override
+                public HasFeaturesTx createFromParcel(Parcel in) {
+                    return new HasFeaturesTx(in);
+                }
+
+                @Override
+                public HasFeaturesTx[] newArray(int size) {
+                    return new HasFeaturesTx[size];
+                }
+            };
+
+    public final Account account;
+    public final List<String> features = new ArrayList<>();
+    public final Bundle result;
+
+    private HasFeaturesTx(Parcel in) {
+        account = in.readParcelable(null);
+        in.readStringList(features);
+        result = in.readBundle();
+    }
+
+    public HasFeaturesTx(
+            Account account,
+            String[] features,
+            Bundle result) {
+        this.account = account;
+        if (features != null) {
+            for (String feature : features) {
+                this.features.add(feature);
+            }
+        }
+        this.result = result;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(account, flags);
+        out.writeStringList(features);
+        out.writeBundle(result);
+    }
+}
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/UpdateCredentialsTx.aidl b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/UpdateCredentialsTx.aidl
new file mode 100644
index 0000000..8106242
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/UpdateCredentialsTx.aidl
@@ -0,0 +1,3 @@
+package android.accounts.cts.common.tx;
+
+parcelable UpdateCredentialsTx;
diff --git a/tests/tests/accounts/common/src/android/accounts/cts/common/tx/UpdateCredentialsTx.java b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/UpdateCredentialsTx.java
new file mode 100644
index 0000000..ed2e082
--- /dev/null
+++ b/tests/tests/accounts/common/src/android/accounts/cts/common/tx/UpdateCredentialsTx.java
@@ -0,0 +1,59 @@
+package android.accounts.cts.common.tx;
+
+import android.accounts.Account;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class UpdateCredentialsTx implements Parcelable {
+
+    public static final Parcelable.Creator<UpdateCredentialsTx> CREATOR =
+            new Parcelable.Creator<UpdateCredentialsTx>() {
+
+                @Override
+                public UpdateCredentialsTx createFromParcel(Parcel in) {
+                    return new UpdateCredentialsTx(in);
+                }
+
+                @Override
+                public UpdateCredentialsTx[] newArray(int size) {
+                    return new UpdateCredentialsTx[size];
+                }
+            };
+
+    public final Account account;
+    public final String authTokenType;
+    public final Bundle options;
+    public final Bundle result;
+
+    private UpdateCredentialsTx(Parcel in) {
+        account = in.readParcelable(null);
+        authTokenType = in.readString();
+        options = in.readBundle();
+        result = in.readBundle();
+    }
+
+    public UpdateCredentialsTx(
+            Account account,
+            String authTokenType,
+            Bundle options,
+            Bundle result) {
+        this.account = account;
+        this.authTokenType = authTokenType;
+        this.options = options;
+        this.result = result;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeParcelable(account, flags);
+        out.writeString(authTokenType);
+        out.writeBundle(options);
+        out.writeBundle(result);
+    }
+}
diff --git a/tests/tests/accounts/res/drawable/ic_cts_minitab_selected_custom_account.png b/tests/tests/accounts/res/drawable/ic_cts_minitab_selected_custom_account.png
new file mode 100644
index 0000000..3fbbc94
--- /dev/null
+++ b/tests/tests/accounts/res/drawable/ic_cts_minitab_selected_custom_account.png
Binary files differ
diff --git a/tests/tests/accounts/res/drawable/ic_cts_selected_custom_account.png b/tests/tests/accounts/res/drawable/ic_cts_selected_custom_account.png
new file mode 100644
index 0000000..70e35c0
--- /dev/null
+++ b/tests/tests/accounts/res/drawable/ic_cts_selected_custom_account.png
Binary files differ
diff --git a/tests/tests/accounts/res/xml/custom_token_authenticator.xml b/tests/tests/accounts/res/xml/custom_token_authenticator.xml
new file mode 100644
index 0000000..3337917
--- /dev/null
+++ b/tests/tests/accounts/res/xml/custom_token_authenticator.xml
@@ -0,0 +1,29 @@
+<?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.
+ */
+-->
+
+<!-- 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="android.accounts.cts.custom.account.type"
+    android:icon="@drawable/ic_cts_selected_custom_account"
+    android:smallIcon="@drawable/ic_cts_minitab_selected_custom_account"
+    android:customTokens="true"
+    android:label="@string/label"
+/>
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
index b2a48e6..4350191 100644
--- a/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountManagerTest.java
@@ -26,16 +26,19 @@
 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.test.ActivityInstrumentationTestCase2;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
 
 /**
  * You can run those unit tests with the following command line:
@@ -52,13 +55,15 @@
     public static final String ACCOUNT_NAME_OTHER = "android.accounts.cts.account.name.other";
 
     public static final String ACCOUNT_TYPE = "android.accounts.cts.account.type";
-    public static final String ACCOUNT_TYPE_OTHER = "android.accounts.cts.account.type.other";
+    public static final String ACCOUNT_TYPE_CUSTOM = "android.accounts.cts.custom.account.type";
+    public static final String ACCOUNT_TYPE_ABSENT = "android.accounts.cts.account.type.absent";
 
     public static final String ACCOUNT_PASSWORD = "android.accounts.cts.account.password";
 
-    public static final String AUTH_TOKEN = "mockAuthToken";
     public static final String AUTH_TOKEN_TYPE = "mockAuthTokenType";
+    public static final String AUTH_EXPIRING_TOKEN_TYPE = "mockAuthExpiringTokenType";
     public static final String AUTH_TOKEN_LABEL = "mockAuthTokenLabel";
+    public static final long AUTH_TOKEN_DURATION_MILLIS = 10000L; // Ten seconds.
 
     public static final String FEATURE_1 = "feature.1";
     public static final String FEATURE_2 = "feature.2";
@@ -86,6 +91,9 @@
             MockAccountAuthenticator.ACCOUNT_NAME_FOR_NEW_REMOVE_API, ACCOUNT_TYPE);
     public static final Account ACCOUNT_SAME_TYPE = new Account(ACCOUNT_NAME_OTHER, ACCOUNT_TYPE);
 
+    public static final Account CUSTOM_TOKEN_ACCOUNT =
+            new Account(ACCOUNT_NAME,ACCOUNT_TYPE_CUSTOM);
+
     private static MockAccountAuthenticator mockAuthenticator;
     private static final int LATCH_TIMEOUT_MS = 500;
     private static AccountManager am;
@@ -130,16 +138,101 @@
         assertTrue(removeAccount(am, ACCOUNT_SAME_TYPE, mActivity, null /* callback */).getBoolean(
                 AccountManager.KEY_BOOLEAN_RESULT));
 
+        // Clean out any other accounts added during the tests.
+        Account[] ctsAccounts = am.getAccountsByType(ACCOUNT_TYPE);
+        Account[] ctsCustomAccounts = am.getAccountsByType(ACCOUNT_TYPE_CUSTOM);
+        ArrayList<Account> accounts = new ArrayList<>(Arrays.asList(ctsAccounts));
+        accounts.addAll(Arrays.asList(ctsCustomAccounts));
+        for (Account ctsAccount : accounts) {
+            removeAccount(am, ctsAccount, mActivity, null /* callback */);
+        }
+
         // need to clean up the authenticator cached data
         mockAuthenticator.clearData();
 
         super.tearDown();
     }
 
-    private void validateAccountAndAuthTokenResult(Bundle result) {
-        assertEquals(ACCOUNT_NAME, result.get(AccountManager.KEY_ACCOUNT_NAME));
-        assertEquals(ACCOUNT_TYPE, result.get(AccountManager.KEY_ACCOUNT_TYPE));
-        assertEquals(AUTH_TOKEN, result.get(AccountManager.KEY_AUTHTOKEN));
+    interface TokenFetcher {
+        public Bundle fetch(String tokenType)
+                throws OperationCanceledException, AuthenticatorException, IOException;
+        public Account getAccount();
+    }
+
+    private void validateSuccessfulTokenFetchingLifecycle(TokenFetcher fetcher, String tokenType)
+            throws OperationCanceledException, AuthenticatorException, IOException {
+        Account account = fetcher.getAccount();
+        Bundle expected = new Bundle();
+        expected.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
+        expected.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
+
+        // First fetch.
+        Bundle actual = fetcher.fetch(tokenType);
+        assertTrue(mockAuthenticator.isRecentlyCalled());
+        validateAccountAndAuthTokenResult(expected, actual);
+
+        /*
+         * On the second fetch the cache will be populated if we are using a authenticator with
+         * customTokens=false or we are using a scope that will cause the authenticator to set an
+         * expiration time (and that expiration time hasn't been reached).
+         */
+        actual = fetcher.fetch(tokenType);
+
+        boolean isCachingExpected =
+                ACCOUNT_TYPE.equals(account.type) || AUTH_EXPIRING_TOKEN_TYPE.equals(tokenType);
+        assertEquals(isCachingExpected, !mockAuthenticator.isRecentlyCalled());
+        validateAccountAndAuthTokenResult(expected, actual);
+
+        try {
+            // Delay further execution until expiring tokens can actually expire.
+            Thread.sleep(mockAuthenticator.getTokenDurationMillis() + 1L);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+
+        /*
+         * With the time shift above, the third request will result in cache hits only from
+         * customToken=false authenticators.
+         */
+        actual = fetcher.fetch(tokenType);
+        isCachingExpected = ACCOUNT_TYPE.equals(account.type);
+        assertEquals(isCachingExpected, !mockAuthenticator.isRecentlyCalled());
+        validateAccountAndAuthTokenResult(expected, actual);
+
+        // invalidate token
+        String token = actual.getString(AccountManager.KEY_AUTHTOKEN);
+        am.invalidateAuthToken(account.type, token);
+
+        /*
+         * Upon invalidating the token, the cache should be clear regardless of authenticator.
+         */
+        actual = fetcher.fetch(tokenType);
+        assertTrue(mockAuthenticator.isRecentlyCalled());
+        validateAccountAndAuthTokenResult(expected, actual);
+    }
+
+    private void validateAccountAndAuthTokenResult(Bundle actual) {
+        assertEquals(
+                ACCOUNT.name,
+                actual.get(AccountManager.KEY_ACCOUNT_NAME));
+        assertEquals(
+                ACCOUNT.type,
+                actual.get(AccountManager.KEY_ACCOUNT_TYPE));
+        assertEquals(
+                mockAuthenticator.getLastTokenServed(),
+                actual.get(AccountManager.KEY_AUTHTOKEN));
+    }
+
+    private void validateAccountAndAuthTokenResult(Bundle expected, Bundle actual) {
+        assertEquals(
+                expected.get(AccountManager.KEY_ACCOUNT_NAME),
+                actual.get(AccountManager.KEY_ACCOUNT_NAME));
+        assertEquals(
+                expected.get(AccountManager.KEY_ACCOUNT_TYPE),
+                actual.get(AccountManager.KEY_ACCOUNT_TYPE));
+        assertEquals(
+                mockAuthenticator.getLastTokenServed(),
+                actual.get(AccountManager.KEY_AUTHTOKEN));
     }
 
     private void validateAccountAndNoAuthTokenResult(Bundle result) {
@@ -224,7 +317,6 @@
     private boolean removeAccount(AccountManager am, Account account,
             AccountManagerCallback<Boolean> callback) throws IOException, AuthenticatorException,
                 OperationCanceledException {
-
         AccountManagerFuture<Boolean> futureBoolean = am.removeAccount(account,
                 callback,
                 null /* handler */);
@@ -357,6 +449,7 @@
         final CountDownLatch latch = new CountDownLatch(1);
 
         AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            @Override
             public void run(AccountManagerFuture<Bundle> bundleFuture) {
                 Bundle resultBundle = null;
                 try {
@@ -483,9 +576,7 @@
     /**
      * Test addAccountExplicitly() and removeAccountExplictly().
      */
-    public void testAddAccountExplicitlyAndRemoveAccountExplicitly() throws IOException,
-            AuthenticatorException, OperationCanceledException {
-
+    public void testAddAccountExplicitlyAndRemoveAccountExplicitly() {
         final int expectedAccountsCount = getAccountsCount();
 
         addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
@@ -581,7 +672,7 @@
         assertEquals(2, accounts.length);
 
         // Check if we dont have any account from the other type
-        accounts = am.getAccountsByType(ACCOUNT_TYPE_OTHER);
+        accounts = am.getAccountsByType(ACCOUNT_TYPE_ABSENT);
         assertEquals(0, accounts.length);
     }
 
@@ -684,6 +775,7 @@
         final CountDownLatch latch1 = new CountDownLatch(1);
 
         AccountManagerCallback<Account[]> callback1 = new AccountManagerCallback<Account[]>() {
+            @Override
             public void run(AccountManagerFuture<Account[]> accountsFuture) {
                 try {
                     Account[] accounts = accountsFuture.getResult();
@@ -724,6 +816,7 @@
         final CountDownLatch latch2 = new CountDownLatch(1);
 
         AccountManagerCallback<Account[]> callback2 = new AccountManagerCallback<Account[]>() {
+            @Override
             public void run(AccountManagerFuture<Account[]> accountsFuture) {
                 try {
                     Account[] accounts = accountsFuture.getResult();
@@ -765,25 +858,24 @@
      */
     public void testSetAndPeekAndInvalidateAuthToken() {
         addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
-
-        am.setAuthToken(ACCOUNT, AUTH_TOKEN_TYPE, AUTH_TOKEN);
+        String expected = "x";
+        am.setAuthToken(ACCOUNT, AUTH_TOKEN_TYPE, expected);
 
         // Ask for the AuthToken
         String token = am.peekAuthToken(ACCOUNT, AUTH_TOKEN_TYPE);
         assertNotNull(token);
-        assertEquals(AUTH_TOKEN, token);
+        assertEquals(expected, token);
 
-        am.invalidateAuthToken(ACCOUNT_TYPE, AUTH_TOKEN);
+        am.invalidateAuthToken(ACCOUNT_TYPE, token);
         token = am.peekAuthToken(ACCOUNT, AUTH_TOKEN_TYPE);
         assertNull(token);
     }
 
     /**
-     * Test blockingGetAuthToken()
+     * Test successful blockingGetAuthToken() with customTokens=false authenticator.
      */
-    public void testBlockingGetAuthToken() throws IOException, AuthenticatorException,
-            OperationCanceledException {
-
+    public void testBlockingGetAuthToken_DefaultToken_Success()
+            throws IOException, AuthenticatorException, OperationCanceledException {
         addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null);
 
         String token = am.blockingGetAuthToken(ACCOUNT,
@@ -792,17 +884,61 @@
 
         // Ask for the AuthToken
         assertNotNull(token);
-        assertEquals(AUTH_TOKEN, token);
+        assertEquals(mockAuthenticator.getLastTokenServed(), token);
+    }
+
+    private static class BlockingGetAuthTokenFetcher implements TokenFetcher {
+        private final Account mAccount;
+
+        BlockingGetAuthTokenFetcher(Account account) {
+            mAccount = account;
+        }
+
+        @Override
+        public Bundle fetch(String tokenType)
+                throws OperationCanceledException, AuthenticatorException, IOException {
+            String token = am.blockingGetAuthToken(
+                    getAccount(),
+                    tokenType,
+                    false /* no failure notification */);
+            Bundle result = new Bundle();
+            result.putString(AccountManager.KEY_AUTHTOKEN, token);
+            result.putString(AccountManager.KEY_ACCOUNT_NAME, mAccount.name);
+            result.putString(AccountManager.KEY_ACCOUNT_TYPE, mAccount.type);
+            return result;
+        }
+        @Override
+        public Account getAccount() {
+            return CUSTOM_TOKEN_ACCOUNT;
+        }
     }
 
     /**
-     * Test getAuthToken()
+     * Test successful blockingGetAuthToken() with customTokens=true authenticator.
      */
-    public void testGetAuthToken() throws IOException, AuthenticatorException,
-            OperationCanceledException {
+    public void testBlockingGetAuthToken_CustomToken_NoCaching_Success()
+            throws IOException, AuthenticatorException, OperationCanceledException {
+        addAccountExplicitly(CUSTOM_TOKEN_ACCOUNT, ACCOUNT_PASSWORD, null);
+        TokenFetcher f = new BlockingGetAuthTokenFetcher(CUSTOM_TOKEN_ACCOUNT);
+        validateSuccessfulTokenFetchingLifecycle(f, AUTH_TOKEN_TYPE);
+    }
 
+    /**
+     * Test successful blockingGetAuthToken() with customTokens=true authenticator.
+     */
+    public void testBlockingGetAuthToken_CustomToken_ExpiringCache_Success()
+            throws IOException, AuthenticatorException, OperationCanceledException {
+        addAccountExplicitly(CUSTOM_TOKEN_ACCOUNT, ACCOUNT_PASSWORD, null);
+        TokenFetcher f = new BlockingGetAuthTokenFetcher(CUSTOM_TOKEN_ACCOUNT);
+        validateSuccessfulTokenFetchingLifecycle(f, AUTH_EXPIRING_TOKEN_TYPE);
+    }
+
+    /**
+     * Test successful getAuthToken() using a future with customTokens=false authenticator.
+     */
+    public void testDeprecatedGetAuthTokenWithFuture_NoOptions_DefaultToken_Success()
+            throws IOException, AuthenticatorException, OperationCanceledException {
         addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
-
         AccountManagerFuture<Bundle> futureBundle = am.getAuthToken(ACCOUNT,
                 AUTH_TOKEN_TYPE,
                 false /* no failure notification */,
@@ -820,6 +956,226 @@
     }
 
     /**
+     * Test successful getAuthToken() using a future with customTokens=false without
+     * expiring tokens.
+     */
+    public void testDeprecatedGetAuthTokenWithFuture_NoOptions_CustomToken_Success()
+            throws IOException, AuthenticatorException, OperationCanceledException {
+        addAccountExplicitly(CUSTOM_TOKEN_ACCOUNT, ACCOUNT_PASSWORD, null);
+        // validateSuccessfulTokenFetchingLifecycle(AccountManager am, TokenFetcher fetcher, String tokenType)
+        TokenFetcher f = new TokenFetcher() {
+            @Override
+            public Bundle fetch(String tokenType)
+                    throws OperationCanceledException, AuthenticatorException, IOException {
+                AccountManagerFuture<Bundle> futureBundle = am.getAuthToken(
+                        getAccount(),
+                        tokenType,
+                        false /* no failure notification */,
+                        null /* no callback */,
+                        null /* no handler */
+                );
+                Bundle actual = futureBundle.getResult();
+                assertTrue(futureBundle.isDone());
+                assertNotNull(actual);
+                return actual;
+            }
+
+            @Override
+            public Account getAccount() {
+                return CUSTOM_TOKEN_ACCOUNT;
+            }
+        };
+        validateSuccessfulTokenFetchingLifecycle(f, AUTH_EXPIRING_TOKEN_TYPE);
+        validateSuccessfulTokenFetchingLifecycle(f, AUTH_TOKEN_TYPE);
+    }
+
+    /**
+     * Test successful getAuthToken() using a future with customTokens=false without
+     * expiring tokens.
+     */
+    public void testGetAuthTokenWithFuture_Options_DefaultToken_Success()
+            throws IOException, AuthenticatorException, OperationCanceledException {
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
+
+        AccountManagerFuture<Bundle> futureBundle = am.getAuthToken(ACCOUNT,
+                AUTH_TOKEN_TYPE,
+                OPTIONS_BUNDLE,
+                mActivity,
+                null /* no callback */,
+                null /* no handler */
+        );
+
+        Bundle resultBundle = futureBundle.getResult();
+
+        assertTrue(futureBundle.isDone());
+        assertNotNull(resultBundle);
+
+        // Assert returned result
+        validateAccountAndAuthTokenResult(resultBundle);
+
+        validateOptions(null, mockAuthenticator.mOptionsAddAccount);
+        validateOptions(null, mockAuthenticator.mOptionsUpdateCredentials);
+        validateOptions(null, mockAuthenticator.mOptionsConfirmCredentials);
+        validateOptions(OPTIONS_BUNDLE, mockAuthenticator.mOptionsGetAuthToken);
+        validateSystemOptions(mockAuthenticator.mOptionsGetAuthToken);
+    }
+
+    /**
+     * Test successful getAuthToken() using a future with customTokens=false without
+     * expiring tokens.
+     */
+    public void testGetAuthTokenWithFuture_Options_CustomToken_Success()
+            throws IOException, AuthenticatorException, OperationCanceledException {
+        addAccountExplicitly(CUSTOM_TOKEN_ACCOUNT, ACCOUNT_PASSWORD, null);
+        TokenFetcher fetcherWithOptions = new TokenFetcher() {
+            @Override
+            public Bundle fetch(String tokenType)
+                    throws OperationCanceledException, AuthenticatorException, IOException {
+                AccountManagerFuture<Bundle> futureBundle = am.getAuthToken(
+                        getAccount(),
+                        tokenType,
+                        OPTIONS_BUNDLE,
+                        false /* no failure notification */,
+                        null /* no callback */,
+                        null /* no handler */
+                );
+                Bundle actual = futureBundle.getResult();
+                assertTrue(futureBundle.isDone());
+                assertNotNull(actual);
+                return actual;
+            }
+
+            @Override
+            public Account getAccount() {
+                return CUSTOM_TOKEN_ACCOUNT;
+            }
+        };
+        validateSuccessfulTokenFetchingLifecycle(fetcherWithOptions, AUTH_TOKEN_TYPE);
+        validateSuccessfulTokenFetchingLifecycle(fetcherWithOptions, AUTH_EXPIRING_TOKEN_TYPE);
+    }
+
+
+    /**
+     * Test successful getAuthToken() using a future with customTokens=false without
+     * expiring tokens.
+     */
+    public void testGetAuthTokenWithCallback_Options_Handler_DefaultToken_Success()
+            throws IOException, AuthenticatorException, OperationCanceledException {
+        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null);
+        final HandlerThread handlerThread = new HandlerThread("accounts.test");
+        handlerThread.start();
+        TokenFetcher fetcherWithOptions = new TokenFetcher() {
+            @Override
+            public Bundle fetch(String tokenType)
+                    throws OperationCanceledException, AuthenticatorException, IOException {
+                final AtomicReference<Bundle> actualRef = new AtomicReference<>();
+                final CountDownLatch latch = new CountDownLatch(1);
+
+                AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+                    @Override
+                    public void run(AccountManagerFuture<Bundle> bundleFuture) {
+                        Bundle resultBundle = null;
+                        try {
+                            resultBundle = bundleFuture.getResult();
+                            actualRef.set(resultBundle);
+                        } catch (OperationCanceledException e) {
+                            fail("should not throw an OperationCanceledException");
+                        } catch (IOException e) {
+                            fail("should not throw an IOException");
+                        } catch (AuthenticatorException e) {
+                            fail("should not throw an AuthenticatorException");
+                        } finally {
+                            latch.countDown();
+                        }
+                    }
+                };
+
+                am.getAuthToken(getAccount(),
+                        tokenType,
+                        OPTIONS_BUNDLE,
+                        false /* no failure notification */,
+                        callback,
+                        new Handler(handlerThread.getLooper()));
+
+                // Wait with timeout for the callback to do its work
+                try {
+                    latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+                } catch (InterruptedException e) {
+                    fail("should not throw an InterruptedException");
+                }
+                return actualRef.get();
+            }
+
+            @Override
+            public Account getAccount() {
+                return ACCOUNT;
+            }
+        };
+        validateSuccessfulTokenFetchingLifecycle(fetcherWithOptions, AUTH_TOKEN_TYPE);
+        validateSuccessfulTokenFetchingLifecycle(fetcherWithOptions, AUTH_EXPIRING_TOKEN_TYPE);
+    }
+
+    /**
+     * Test successful getAuthToken() using a future with customTokens=false without
+     * expiring tokens.
+     */
+    public void testGetAuthTokenWithCallback_Options_Handler_CustomToken_Success()
+            throws IOException, AuthenticatorException, OperationCanceledException {
+        addAccountExplicitly(CUSTOM_TOKEN_ACCOUNT, ACCOUNT_PASSWORD, null);
+        final HandlerThread handlerThread = new HandlerThread("accounts.test");
+        handlerThread.start();
+        TokenFetcher fetcherWithOptions = new TokenFetcher() {
+            @Override
+            public Bundle fetch(String tokenType)
+                    throws OperationCanceledException, AuthenticatorException, IOException {
+                final AtomicReference<Bundle> actualRef = new AtomicReference<>();
+                final CountDownLatch latch = new CountDownLatch(1);
+
+                AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+                    @Override
+                    public void run(AccountManagerFuture<Bundle> bundleFuture) {
+                        Bundle resultBundle = null;
+                        try {
+                            resultBundle = bundleFuture.getResult();
+                            actualRef.set(resultBundle);
+                        } catch (OperationCanceledException e) {
+                            fail("should not throw an OperationCanceledException");
+                        } catch (IOException e) {
+                            fail("should not throw an IOException");
+                        } catch (AuthenticatorException e) {
+                            fail("should not throw an AuthenticatorException");
+                        } finally {
+                            latch.countDown();
+                        }
+                    }
+                };
+
+                am.getAuthToken(getAccount(),
+                        tokenType,
+                        OPTIONS_BUNDLE,
+                        false /* no failure notification */,
+                        callback,
+                        new Handler(handlerThread.getLooper()));
+
+                // Wait with timeout for the callback to do its work
+                try {
+                    latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+                } catch (InterruptedException e) {
+                    fail("should not throw an InterruptedException");
+                }
+                return actualRef.get();
+            }
+
+            @Override
+            public Account getAccount() {
+                return CUSTOM_TOKEN_ACCOUNT;
+            }
+        };
+        validateSuccessfulTokenFetchingLifecycle(fetcherWithOptions, AUTH_TOKEN_TYPE);
+        validateSuccessfulTokenFetchingLifecycle(fetcherWithOptions, AUTH_EXPIRING_TOKEN_TYPE);
+    }
+
+    /**
      * Test getAuthToken() with callback and handler
      */
     public void testGetAuthTokenWithCallbackAndHandler() throws IOException, AuthenticatorException,
@@ -837,6 +1193,7 @@
         final CountDownLatch latch = new CountDownLatch(1);
 
         AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            @Override
             public void run(AccountManagerFuture<Bundle> bundleFuture) {
 
                 Bundle resultBundle = null;
@@ -880,37 +1237,6 @@
     }
 
     /**
-     * test getAuthToken() with options
-     */
-    public void testGetAuthTokenWithOptions() throws IOException, AuthenticatorException,
-            OperationCanceledException {
-
-        addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
-
-        AccountManagerFuture<Bundle> futureBundle = am.getAuthToken(ACCOUNT,
-                AUTH_TOKEN_TYPE,
-                OPTIONS_BUNDLE,
-                mActivity,
-                null /* no callback */,
-                null /* no handler */
-        );
-
-        Bundle resultBundle = futureBundle.getResult();
-
-        assertTrue(futureBundle.isDone());
-        assertNotNull(resultBundle);
-
-        // Assert returned result
-        validateAccountAndAuthTokenResult(resultBundle);
-
-        validateOptions(null, mockAuthenticator.mOptionsAddAccount);
-        validateOptions(null, mockAuthenticator.mOptionsUpdateCredentials);
-        validateOptions(null, mockAuthenticator.mOptionsConfirmCredentials);
-        validateOptions(OPTIONS_BUNDLE, mockAuthenticator.mOptionsGetAuthToken);
-        validateSystemOptions(mockAuthenticator.mOptionsGetAuthToken);
-    }
-
-    /**
      * test getAuthToken() with options and callback and handler
      */
     public void testGetAuthTokenWithOptionsAndCallback() throws IOException,
@@ -928,15 +1254,14 @@
         final CountDownLatch latch = new CountDownLatch(1);
 
         AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            @Override
             public void run(AccountManagerFuture<Bundle> bundleFuture) {
 
                 Bundle resultBundle = null;
                 try {
                     resultBundle = bundleFuture.getResult();
-
                     // Assert returned result
                     validateAccountAndAuthTokenResult(resultBundle);
-
                 } catch (OperationCanceledException e) {
                     fail("should not throw an OperationCanceledException");
                 } catch (IOException e) {
@@ -1039,7 +1364,6 @@
         validateOptions(null, mockAuthenticator.mOptionsUpdateCredentials);
         validateOptions(null, mockAuthenticator.mOptionsConfirmCredentials);
         validateOptions(null, mockAuthenticator.mOptionsGetAuthToken);
-
     }
 
     /**
@@ -1063,10 +1387,85 @@
     }
 
     /**
+     * Tests the setting of lastAuthenticatedTime on adding account
+     */
+    public void testLastAuthenticatedTimeAfterAddAccount() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+        assertTrue(addAccountAndReturnAccountAddedTime(ACCOUNT, ACCOUNT_PASSWORD) > 0);
+    }
+
+    /**
+     * Test confirmCredentials() for account not on device. Just that no error
+     * should be thrown.
+     */
+    public void testConfirmCredentialsAccountNotOnDevice() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        Account account = new Account("AccountNotOnThisDevice", ACCOUNT_TYPE);
+        AccountManagerFuture<Bundle> futureBundle = am.confirmCredentials(account,
+                OPTIONS_BUNDLE,
+                mActivity,
+                null /* callback */,
+                null /* handler */);
+
+        futureBundle.getResult();
+    }
+
+    /**
+     * Tests the setting of lastAuthenticatedTime on confirmCredentials being
+     * successful.
+     */
+    public void testLastAuthenticatedTimeAfterConfirmCredentialsSuccess() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        long accountAddTime = addAccountAndReturnAccountAddedTime(ACCOUNT, ACCOUNT_PASSWORD);
+
+        // Now this confirm credentials call returns true, which in turn
+        // should update the last authenticated timestamp.
+        Bundle result = am.confirmCredentials(ACCOUNT,
+                OPTIONS_BUNDLE, /* options */
+                null, /* activity */
+                null /* callback */,
+                null /* handler */).getResult();
+        long confirmedCredTime = result.getLong(
+                AccountManager.KEY_LAST_AUTHENTICATED_TIME, -1);
+        assertTrue(confirmedCredTime > accountAddTime);
+    }
+
+    /**
+     * Tests the setting of lastAuthenticatedTime on updateCredentials being
+     * successful.
+     */
+    public void testLastAuthenticatedTimeAfterUpdateCredentialsSuccess() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+
+        long accountAddTime = addAccountAndReturnAccountAddedTime(ACCOUNT, ACCOUNT_PASSWORD);
+
+        am.updateCredentials(ACCOUNT,
+                AUTH_TOKEN_TYPE,
+                OPTIONS_BUNDLE,
+                mActivity,
+                null /* callback */,
+                null /* handler */).getResult();
+        long updateCredTime = getLastAuthenticatedTime(ACCOUNT);
+        assertTrue(updateCredTime > accountAddTime);
+    }
+
+    /**
+     * LastAuthenticatedTime on setPassword should not be disturbed.
+     */
+    public void testLastAuthenticatedTimeAfterSetPassword() throws IOException,
+            AuthenticatorException, OperationCanceledException {
+        long accountAddTime = addAccountAndReturnAccountAddedTime(ACCOUNT, ACCOUNT_PASSWORD);
+        mockAuthenticator.callSetPassword();
+        long setPasswordTime = getLastAuthenticatedTime(ACCOUNT);
+        assertTrue(setPasswordTime == accountAddTime);
+    }
+
+    /**
      * Test confirmCredentials() with callback
      */
-    public void testConfirmCredentialsWithCallbackAndHandler() throws IOException,
-            AuthenticatorException, OperationCanceledException {
+    public void testConfirmCredentialsWithCallbackAndHandler() {
 
         addAccountExplicitly(ACCOUNT, ACCOUNT_PASSWORD, null /* userData */);
 
@@ -1074,12 +1473,10 @@
         testConfirmCredentialsWithCallbackAndHandler(new Handler(Looper.getMainLooper()));
     }
 
-    private void testConfirmCredentialsWithCallbackAndHandler(Handler handler) throws IOException,
-            AuthenticatorException, OperationCanceledException {
-
+    private void testConfirmCredentialsWithCallbackAndHandler(Handler handler) {
         final CountDownLatch latch = new CountDownLatch(1);
-
         AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            @Override
             public void run(AccountManagerFuture<Bundle> bundleFuture) {
 
                 Bundle resultBundle = null;
@@ -1102,18 +1499,14 @@
                 }
             }
         };
-
         AccountManagerFuture<Bundle> futureBundle = am.confirmCredentials(ACCOUNT,
                 OPTIONS_BUNDLE,
                 mActivity,
                 callback,
                 handler);
-
-        futureBundle.getResult();
-
         // Wait with timeout for the callback to do its work
         try {
-            latch.await(LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+            latch.await(3 * LATCH_TIMEOUT_MS, TimeUnit.MILLISECONDS);
         } catch (InterruptedException e) {
             fail("should not throw an InterruptedException");
         }
@@ -1160,6 +1553,7 @@
         final CountDownLatch latch = new CountDownLatch(1);
 
         AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            @Override
             public void run(AccountManagerFuture<Bundle> bundleFuture) {
 
                 Bundle resultBundle = null;
@@ -1231,6 +1625,7 @@
         final CountDownLatch latch = new CountDownLatch(1);
 
         AccountManagerCallback<Bundle> callback = new AccountManagerCallback<Bundle>() {
+            @Override
             public void run(AccountManagerFuture<Bundle> bundleFuture) {
                 try {
                     // Assert returned result
@@ -1292,6 +1687,7 @@
         final CountDownLatch latch = new CountDownLatch(1);
 
         OnAccountsUpdateListener listener = new OnAccountsUpdateListener() {
+            @Override
             public void onAccountsUpdated(Account[] accounts) {
                 latch.countDown();
             }
@@ -1334,6 +1730,7 @@
         final CountDownLatch latch = new CountDownLatch(1);
 
         OnAccountsUpdateListener listener = new OnAccountsUpdateListener() {
+            @Override
             public void onAccountsUpdated(Account[] accounts) {
                 fail("should not be called");
             }
@@ -1424,6 +1821,7 @@
 
     private AccountManagerCallback<Boolean> getAssertTrueCallback(final CountDownLatch latch) {
         return new AccountManagerCallback<Boolean>() {
+            @Override
             public void run(AccountManagerFuture<Boolean> booleanFuture) {
                 try {
                     // Assert returned result should be TRUE
@@ -1439,6 +1837,7 @@
 
     private AccountManagerCallback<Boolean> getAssertFalseCallback(final CountDownLatch latch) {
         return new AccountManagerCallback<Boolean>() {
+            @Override
             public void run(AccountManagerFuture<Boolean> booleanFuture) {
                 try {
                     // Assert returned result should be FALSE
@@ -1519,11 +1918,37 @@
         waitForLatch(latch);
     }
 
+    private long getLastAuthenticatedTime(Account account) throws OperationCanceledException,
+            AuthenticatorException, IOException {
+        Bundle options = new Bundle();
+        options.putBoolean(MockAccountAuthenticator.KEY_RETURN_INTENT, true);
+        // Not really confirming, but a way to get last authenticated timestamp
+        Bundle result = am.confirmCredentials(account,
+                options,// OPTIONS_BUNDLE,
+                null, /* activity */
+                null /* callback */,
+                null /* handler */).getResult();
+        return result.getLong(
+                AccountManager.KEY_LAST_AUTHENTICATED_TIME, -1);
+    }
+
+    private long addAccountAndReturnAccountAddedTime(Account account, String password)
+            throws OperationCanceledException, AuthenticatorException, IOException {
+        addAccount(am,
+                ACCOUNT_TYPE,
+                AUTH_TOKEN_TYPE,
+                REQUIRED_FEATURES,
+                OPTIONS_BUNDLE,
+                mActivity,
+                null /* callback */,
+                null /* handler */);
+        return getLastAuthenticatedTime(account);
+    }
+
     /**
      * Tests that AccountManagerService is properly caching data.
      */
-    public void testGetsAreCached() throws IOException, AuthenticatorException,
-            OperationCanceledException {
+    public void testGetsAreCached() {
 
         // Add an account,
         assertEquals(false, isAccountPresent(am.getAccounts(), ACCOUNT));
diff --git a/tests/tests/accounts/src/android/accounts/cts/AccountManagerUnaffiliatedAuthenticatorTests.java b/tests/tests/accounts/src/android/accounts/cts/AccountManagerUnaffiliatedAuthenticatorTests.java
new file mode 100644
index 0000000..2068f4c
--- /dev/null
+++ b/tests/tests/accounts/src/android/accounts/cts/AccountManagerUnaffiliatedAuthenticatorTests.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.accounts.cts;
+
+import android.accounts.Account;
+import android.accounts.AccountManager;
+import android.accounts.AccountManagerFuture;
+import android.accounts.AuthenticatorException;
+import android.accounts.OperationCanceledException;
+import android.accounts.cts.common.AuthenticatorContentProvider;
+import android.accounts.cts.common.Fixtures;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.os.RemoteException;
+import android.test.AndroidTestCase;
+
+import java.io.IOException;
+
+/**
+ * Tests for AccountManager and AbstractAccountAuthenticator related behavior using {@link
+ * android.accounts.cts.common.TestAccountAuthenticator} instances signed with different keys than
+ * the caller. This is important to test that portion of the {@link AccountManager} API intended
+ * for {@link android.accounts.AbstractAccountAuthenticator} implementers.
+ * <p>
+ * You can run those unit tests with the following command line:
+ * <p>
+ *  adb shell am instrument
+ *   -e debug false -w
+ *   -e class android.accounts.cts.AccountManagerUnaffiliatedAuthenticatorTests
+ * android.accounts.cts/android.support.test.runner.AndroidJUnitRunner
+ */
+public class AccountManagerUnaffiliatedAuthenticatorTests extends AndroidTestCase {
+
+    private AccountManager mAccountManager;
+    private ContentProviderClient mProviderClient;
+
+    @Override
+    public void setUp() throws Exception {
+        // bind to the diagnostic service and set it up.
+        mAccountManager = AccountManager.get(getContext());
+        ContentResolver resolver = getContext().getContentResolver();
+        mProviderClient = resolver.acquireContentProviderClient(
+                AuthenticatorContentProvider.AUTHORITY);
+        /*
+         * This will install a bunch of accounts on the device
+         * (see Fixtures.getFixtureAccountNames()).
+         */
+        mProviderClient.call(AuthenticatorContentProvider.METHOD_SETUP, null, null);
+    }
+
+    @Override
+    public void tearDown() throws RemoteException {
+        try {
+            mProviderClient.call(AuthenticatorContentProvider.METHOD_TEARDOWN, null, null);
+        } finally {
+            mProviderClient.release();
+        }
+    }
+
+    public void testNotifyAccountAuthenticated() {
+        try {
+            mAccountManager.notifyAccountAuthenticated(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS);
+            fail("Expected to just barf if the caller doesn't share a signature.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testEditProperties()  {
+        try {
+            mAccountManager.editProperties(
+                    Fixtures.TYPE_STANDARD_UNAFFILIATED,
+                    null, // activity
+                    null, // callback
+                    null); // handler
+            fail("Expecting a OperationCanceledException.");
+        } catch (SecurityException expected) {
+            
+        }
+    }
+
+    public void testAddAccountExplicitly() {
+        try {
+            mAccountManager.addAccountExplicitly(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS,
+                    "shouldn't matter", // password
+                    null); // bundle
+            fail("addAccountExplicitly should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testRemoveAccount_withBooleanResult() {
+        try {
+            mAccountManager.removeAccount(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS,
+                    null,
+                    null);
+            fail("removeAccount should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testRemoveAccount_withBundleResult() {
+        try {
+            mAccountManager.removeAccount(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS,
+                    null, // Activity
+                    null,
+                    null);
+            fail("removeAccount should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testRemoveAccountExplicitly() {
+        try {
+            mAccountManager.removeAccountExplicitly(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS);
+            fail("removeAccountExplicitly should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testGetPassword() {
+        try {
+            mAccountManager.getPassword(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS);
+            fail("getPassword should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testSetPassword() {
+        try {
+            mAccountManager.setPassword(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS,
+                    "Doesn't matter");
+            fail("setPassword should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testClearPassword() {
+        try {
+            mAccountManager.clearPassword(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS);
+            fail("clearPassword should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testGetUserData() {
+        try {
+            mAccountManager.getUserData(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS,
+                    "key");
+            fail("getUserData should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testSetUserData() {
+        try {
+            mAccountManager.setUserData(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS,
+                    "key",
+                    "value");
+            fail("setUserData should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void setAuthToken() {
+        try {
+            mAccountManager.setAuthToken(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS,
+                    "tokenType",
+                    "token");
+            fail("setAuthToken should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testPeekAuthToken() {
+        try {
+            mAccountManager.peekAuthToken(
+                    Fixtures.ACCOUNT_UNAFFILIATED_FIXTURE_SUCCESS,
+                    "tokenType");
+            fail("peekAuthToken should just barf if the caller isn't permitted.");
+        } catch (SecurityException expected) {}
+    }
+
+    public void testGetAccounts() {
+        Account[] accounts = mAccountManager.getAccounts();
+        assertEquals(0, accounts.length);
+    }
+
+    public void testGetAccountsByType() {
+        Account[] accounts = mAccountManager.getAccountsByType(
+                Fixtures.TYPE_STANDARD_UNAFFILIATED);
+        assertEquals(0, accounts.length);
+    }
+
+    public void testGetAccountsByTypeAndFeatures()
+            throws OperationCanceledException, AuthenticatorException, IOException {
+        AccountManagerFuture<Account[]> future = mAccountManager.getAccountsByTypeAndFeatures(
+                Fixtures.TYPE_STANDARD_UNAFFILIATED,
+                new String[] { "doesn't matter" },
+                null,  // Callback
+                null);  // Handler
+        Account[] accounts = future.getResult();
+        assertEquals(0, accounts.length);
+    }
+
+    public void testGetAccountsByTypeForPackage() {
+        Account[] accounts = mAccountManager.getAccountsByTypeForPackage(
+                Fixtures.TYPE_STANDARD_UNAFFILIATED,
+                getContext().getPackageName());
+        assertEquals(0, accounts.length);
+    }
+}
+
diff --git a/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java b/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
index b5804d9..c1b08de 100644
--- a/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
+++ b/tests/tests/accounts/src/android/accounts/cts/MockAccountAuthenticator.java
@@ -24,19 +24,29 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.Bundle;
+import android.util.Log;
 
 import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * A simple Mock Account Authenticator
  */
 public class MockAccountAuthenticator extends AbstractAccountAuthenticator {
+    private static String TAG = "AccountManagerTest";
 
     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";
+    // 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";
 
     private final Context mContext;
+    private final AtomicInteger mTokenCounter  = new AtomicInteger(0);
+    private final AtomicBoolean mIsRecentlyCalled = new AtomicBoolean(false);
+
     AccountAuthenticatorResponse mResponse;
     String mAccountType;
     String mAuthTokenType;
@@ -49,6 +59,7 @@
     String[] mFeatures;
 
     final ArrayList<String> mockFeatureList = new ArrayList<String>();
+    private final long mTokenDurationMillis = 1000; // 1 second
 
     public MockAccountAuthenticator(Context context) {
         super(context);
@@ -59,6 +70,18 @@
         mockFeatureList.add(AccountManagerTest.FEATURE_2);
     }
 
+    public long getTokenDurationMillis() {
+        return mTokenDurationMillis;
+    }
+
+    public boolean isRecentlyCalled() {
+        return mIsRecentlyCalled.getAndSet(false);
+    }
+
+    public String getLastTokenServed() {
+        return Integer.toString(mTokenCounter.get());
+    }
+
     public AccountAuthenticatorResponse getResponse() {
         return mResponse;
     }
@@ -96,12 +119,23 @@
         mFeatures = null;
     }
 
+    public void callAccountAuthenticated() {
+        AccountManager am = AccountManager.get(mContext);
+        am.notifyAccountAuthenticated(mAccount);
+    }
+
+    public void callSetPassword() {
+        AccountManager am = AccountManager.get(mContext);
+        am.setPassword(mAccount, "password");
+    }
+
     private Bundle createResultBundle() {
         Bundle result = new Bundle();
         result.putString(AccountManager.KEY_ACCOUNT_NAME, AccountManagerTest.ACCOUNT_NAME);
         result.putString(AccountManager.KEY_ACCOUNT_TYPE, AccountManagerTest.ACCOUNT_TYPE);
-        result.putString(AccountManager.KEY_AUTHTOKEN, AccountManagerTest.AUTH_TOKEN);
-
+        result.putString(
+                AccountManager.KEY_AUTHTOKEN,
+                Integer.toString(mTokenCounter.incrementAndGet()));
         return result;
     }
 
@@ -112,13 +146,13 @@
     public Bundle addAccount(AccountAuthenticatorResponse response, String accountType,
             String authTokenType, String[] requiredFeatures, Bundle options)
             throws NetworkErrorException {
-
         this.mResponse = response;
         this.mAccountType = accountType;
         this.mAuthTokenType = authTokenType;
         this.mRequiredFeatures = requiredFeatures;
         this.mOptionsAddAccount = options;
-
+        AccountManager am = AccountManager.get(mContext);
+        am.addAccountExplicitly(AccountManagerTest.ACCOUNT, "fakePassword", null);
         return createResultBundle();
     }
 
@@ -128,12 +162,10 @@
     @Override
     public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account,
             String authTokenType, Bundle options) throws NetworkErrorException {
-
         this.mResponse = response;
         this.mAccount = account;
         this.mAuthTokenType = authTokenType;
         this.mOptionsUpdateCredentials = options;
-
         return createResultBundle();
     }
 
@@ -144,10 +176,8 @@
      */
     @Override
     public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
-
         this.mResponse = response;
         this.mAccountType = accountType;
-
         return createResultBundle();
     }
 
@@ -157,13 +187,17 @@
     @Override
     public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account,
             Bundle options) throws NetworkErrorException {
-
         this.mResponse = response;
         this.mAccount = account;
         this.mOptionsConfirmCredentials = options;
-
         Bundle result = new Bundle();
-        result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+        if (options.containsKey(KEY_RETURN_INTENT)) {
+            Intent intent = new Intent();
+            intent.setClassName("android.accounts.cts", "android.accounts.cts.AccountDummyActivity");
+            result.putParcelable(AccountManager.KEY_INTENT, intent);
+        } else {
+            result.putBoolean(AccountManager.KEY_BOOLEAN_RESULT, true);
+        }
 
         return result;
     }
@@ -172,15 +206,35 @@
      * Gets the authtoken for an account.
      */
     @Override
-    public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account,
-            String authTokenType, Bundle options) throws NetworkErrorException {
-
+    public Bundle getAuthToken(
+            AccountAuthenticatorResponse response,
+            Account account,
+            String authTokenType,
+            Bundle options) throws NetworkErrorException {
+        Log.w(TAG, "MockAuth - getAuthToken@" + System.currentTimeMillis());
+        mIsRecentlyCalled.set(true);
         this.mResponse = response;
         this.mAccount = account;
         this.mAuthTokenType = authTokenType;
         this.mOptionsGetAuthToken = options;
+        Bundle result = new Bundle();
 
-        return createResultBundle();
+        result.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
+        result.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
+        String token;
+        if (AccountManagerTest.AUTH_EXPIRING_TOKEN_TYPE.equals(authTokenType)) {
+            /*
+             * The resultant token should simply be the expiration timestamp. E.g. the time after
+             * which getting a new AUTH_EXPIRING_TOKEN_TYPE typed token will return a different
+             * value.
+             */
+            long expiry = System.currentTimeMillis() + mTokenDurationMillis;
+            result.putLong(AbstractAccountAuthenticator.KEY_CUSTOM_TOKEN_EXPIRY, expiry);
+        }
+        result.putString(
+                AccountManager.KEY_AUTHTOKEN,
+                Integer.toString(mTokenCounter.incrementAndGet()));
+        return result;
     }
 
     /**
@@ -189,7 +243,6 @@
     @Override
     public String getAuthTokenLabel(String authTokenType) {
         this.mAuthTokenType = authTokenType;
-
         return AccountManagerTest.AUTH_TOKEN_LABEL;
     }
 
@@ -242,4 +295,4 @@
         }
         return result;
     }
-}
\ No newline at end of file
+}
diff --git a/tests/tests/accounts/src/android/accounts/cts/MockCustomTokenAccountService.java b/tests/tests/accounts/src/android/accounts/cts/MockCustomTokenAccountService.java
new file mode 100644
index 0000000..ea06a41
--- /dev/null
+++ b/tests/tests/accounts/src/android/accounts/cts/MockCustomTokenAccountService.java
@@ -0,0 +1,13 @@
+package android.accounts.cts;
+
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+public class MockCustomTokenAccountService extends Service {
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        return AccountManagerTest.getMockAuthenticator(this).getIBinder();
+    }
+}
diff --git a/tests/tests/admin/AndroidTest.xml b/tests/tests/admin/AndroidTest.xml
new file mode 100644
index 0000000..c29d404
--- /dev/null
+++ b/tests/tests/admin/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="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/DevicePolicyManagerTest.java b/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
index 513b67e..66e12c0 100644
--- a/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
+++ b/tests/tests/admin/src/android/admin/cts/DevicePolicyManagerTest.java
@@ -68,6 +68,8 @@
             "VcUyQ1/e7WQgOaBHi9TefUJi+4PSVSluOXon\n" +
             "-----END CERTIFICATE-----";
 
+    private static final String MANAGED_PROVISIONING_PKG = "com.android.managedprovisioning";
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -133,26 +135,29 @@
                 mDevicePolicyManager.getPasswordQuality(mComponent));
         assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
 
-        assertTrue(mDevicePolicyManager.resetPassword("123", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd123", 0));
-        assertTrue(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());
 
-        assertFalse(mDevicePolicyManager.resetPassword("123", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd123", 0));
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("abcd1234", caseDescription);
 
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumLength(mComponent));
+        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 4);
+        caseDescription = "minimum password length = 4";
+        assertEquals(4, mDevicePolicyManager.getPasswordMinimumLength(
+                mComponent));
         assertTrue(mDevicePolicyManager.isActivePasswordSufficient());
 
-        assertTrue(mDevicePolicyManager.resetPassword("123", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd123", 0));
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
     }
 
     public void testPasswordQuality_numeric() {
@@ -166,26 +171,29 @@
                 mDevicePolicyManager.getPasswordQuality(mComponent));
         assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
 
-        assertTrue(mDevicePolicyManager.resetPassword("123", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd123", 0));
-        assertTrue(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());
 
-        assertFalse(mDevicePolicyManager.resetPassword("123", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd123", 0));
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("abcd1234", caseDescription);
 
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumLength(mComponent));
+        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 4);
+        caseDescription = "minimum password length = 4";
+        assertEquals(4, mDevicePolicyManager.getPasswordMinimumLength(
+                mComponent));
         assertTrue(mDevicePolicyManager.isActivePasswordSufficient());
 
-        assertTrue(mDevicePolicyManager.resetPassword("123", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd123", 0));
+        assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
     }
 
     public void testPasswordQuality_alphabetic() {
@@ -199,26 +207,29 @@
                 mDevicePolicyManager.getPasswordQuality(mComponent));
         assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
 
-        assertFalse(mDevicePolicyManager.resetPassword("123", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd123", 0));
-        assertTrue(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());
 
-        assertFalse(mDevicePolicyManager.resetPassword("123", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd123", 0));
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("abcd1234", caseDescription);
 
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumLength(mComponent));
+        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 4);
+        caseDescription = "minimum password length = 4";
+        assertEquals(4, mDevicePolicyManager.getPasswordMinimumLength(
+                mComponent));
         assertTrue(mDevicePolicyManager.isActivePasswordSufficient());
 
-        assertFalse(mDevicePolicyManager.resetPassword("123", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd123", 0));
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
     }
 
     public void testPasswordQuality_alphanumeric() {
@@ -232,26 +243,29 @@
                 mDevicePolicyManager.getPasswordQuality(mComponent));
         assertFalse(mDevicePolicyManager.isActivePasswordSufficient());
 
-        assertFalse(mDevicePolicyManager.resetPassword("123", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd123", 0));
-        assertTrue(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());
 
-        assertFalse(mDevicePolicyManager.resetPassword("123", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd123", 0));
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordFails("abcd1234", caseDescription);
 
-        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 3);
-        assertEquals(3, mDevicePolicyManager.getPasswordMinimumLength(mComponent));
+        mDevicePolicyManager.setPasswordMinimumLength(mComponent, 4);
+        caseDescription = "minimum password length = 4";
+        assertEquals(4, mDevicePolicyManager.getPasswordMinimumLength(
+                mComponent));
         assertTrue(mDevicePolicyManager.isActivePasswordSufficient());
 
-        assertFalse(mDevicePolicyManager.resetPassword("123", 0));
-        assertFalse(mDevicePolicyManager.resetPassword("abcd", 0));
-        assertTrue(mDevicePolicyManager.resetPassword("abcd123", 0));
+        assertPasswordFails("1234", caseDescription);
+        assertPasswordFails("abcd", caseDescription);
+        assertPasswordSucceeds("abcd1234", caseDescription);
     }
 
     public void testPasswordQuality_complexUpperCase() {
@@ -265,26 +279,29 @@
         resetComplexPasswordRestrictions();
 
         String caseDescription = "minimum UpperCase=0";
-        assertPasswordSucceeds("abc", caseDescription);
-        assertPasswordSucceeds("aBc", caseDescription);
-        assertPasswordSucceeds("ABC", caseDescription);
+        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("abc", caseDescription);
-        assertPasswordSucceeds("aBc", caseDescription);
-        assertPasswordSucceeds("ABC", caseDescription);
+        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("abc", caseDescription);
-        assertPasswordFails("aBC", caseDescription);
-        assertPasswordSucceeds("ABC", caseDescription);
+        assertPasswordFails("abc1", caseDescription);
+        assertPasswordFails("aBC1", caseDescription);
+        assertPasswordSucceeds("ABC1", caseDescription);
         assertPasswordSucceeds("ABCD", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
     }
 
     public void testPasswordQuality_complexLowerCase() {
@@ -299,25 +316,28 @@
 
         String caseDescription = "minimum LowerCase=0";
         assertPasswordSucceeds("ABCD", caseDescription);
-        assertPasswordSucceeds("aBC", caseDescription);
-        assertPasswordSucceeds("abc", 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("aBC", caseDescription);
-        assertPasswordSucceeds("abc", 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("aBC", caseDescription);
-        assertPasswordSucceeds("abc", caseDescription);
+        assertPasswordFails("aBC1", caseDescription);
+        assertPasswordSucceeds("abc1", caseDescription);
         assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
     }
 
     public void testPasswordQuality_complexLetters() {
@@ -332,25 +352,28 @@
 
         String caseDescription = "minimum Letters=0";
         assertPasswordSucceeds("1234", caseDescription);
-        assertPasswordSucceeds("a23", caseDescription);
-        assertPasswordSucceeds("abc", 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("a23", caseDescription);
-        assertPasswordSucceeds("abc", 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("a23", caseDescription);
-        assertPasswordSucceeds("abc", caseDescription);
+        assertPasswordFails("a123", caseDescription);
+        assertPasswordSucceeds("abc1", caseDescription);
         assertPasswordSucceeds("abcd", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
     }
 
     public void testPasswordQuality_complexNumeric() {
@@ -365,25 +388,28 @@
 
         String caseDescription = "minimum Numeric=0";
         assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("1bc", caseDescription);
-        assertPasswordSucceeds("123", 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("1bc", caseDescription);
-        assertPasswordSucceeds("123", 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("1bc", caseDescription);
-        assertPasswordSucceeds("123", caseDescription);
+        assertPasswordFails("1abc", caseDescription);
+        assertPasswordSucceeds("123a", caseDescription);
         assertPasswordSucceeds("1234", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
     }
 
     public void testPasswordQuality_complexSymbols() {
@@ -398,25 +424,28 @@
 
         String caseDescription = "minimum Symbols=0";
         assertPasswordSucceeds("abcd", caseDescription);
-        assertPasswordSucceeds("_bc", caseDescription);
-        assertPasswordSucceeds("@#!", 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("_bc", caseDescription);
-        assertPasswordSucceeds("@#!", 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("_bc", caseDescription);
-        assertPasswordSucceeds("@#!", caseDescription);
+        assertPasswordFails("_bc1", caseDescription);
+        assertPasswordSucceeds("@#!1", caseDescription);
         assertPasswordSucceeds("_@#!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
     }
 
     public void testPasswordQuality_complexNonLetter() {
@@ -435,6 +464,7 @@
         assertPasswordSucceeds("3bcd", caseDescription);
         assertPasswordSucceeds("_@3c", caseDescription);
         assertPasswordSucceeds("_25!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
 
         mDevicePolicyManager.setPasswordMinimumNonLetter(mComponent, 1);
         assertEquals(1, mDevicePolicyManager.getPasswordMinimumNonLetter(mComponent));
@@ -444,6 +474,7 @@
         assertPasswordSucceeds("3bcd", caseDescription);
         assertPasswordSucceeds("_@3c", caseDescription);
         assertPasswordSucceeds("_25!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
 
         mDevicePolicyManager.setPasswordMinimumNonLetter(mComponent, 3);
         assertEquals(3, mDevicePolicyManager.getPasswordMinimumNonLetter(mComponent));
@@ -451,8 +482,9 @@
         assertPasswordFails("Abcd", caseDescription);
         assertPasswordFails("_bcd", caseDescription);
         assertPasswordFails("3bcd", caseDescription);
-        assertPasswordSucceeds("c_@3c", caseDescription);
+        assertPasswordSucceeds("_@3c", caseDescription);
         assertPasswordSucceeds("_25!", caseDescription);
+        assertPasswordFails("123", caseDescription); // too short
     }
 
     public void testPasswordHistoryLength() {
@@ -494,6 +526,23 @@
         }
     }
 
+    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");
@@ -679,6 +728,19 @@
         }
     }
 
+    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");
@@ -693,6 +755,19 @@
         }
     }
 
+    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");
@@ -706,6 +781,19 @@
         }
     }
 
+    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");
@@ -720,6 +808,19 @@
         }
     }
 
+    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");
@@ -733,6 +834,19 @@
         }
     }
 
+    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");
@@ -871,6 +985,19 @@
         }
     }
 
+    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");
@@ -910,6 +1037,14 @@
         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"));
@@ -938,9 +1073,13 @@
     }
 
     private void assertPasswordFails(String password, String restriction) {
-        boolean passwordResetResult = mDevicePolicyManager.resetPassword(password, /* flags= */0);
-        assertFalse("Password '" + password + "' should have failed on " + restriction,
-                passwordResetResult);
+        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) {
@@ -948,4 +1087,53 @@
         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
new file mode 100644
index 0000000..6c30bc7
--- /dev/null
+++ b/tests/tests/alarmclock/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 := CtsAlarmClockCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsAlarmClockTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/alarmclock/AndroidManifest.xml b/tests/tests/alarmclock/AndroidManifest.xml
new file mode 100644
index 0000000..c0193dd
--- /dev/null
+++ b/tests/tests/alarmclock/AndroidManifest.xml
@@ -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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.alarmclock.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <activity android:name="TestStartActivity"
+                  android:label="The Target Activity for AlarmClock CTS Test">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_START_ACTIVITY_DISMISS_ALARM" />
+                <action android:name="android.intent.action.TEST_START_ACTIVITY_SET_ALARM" />
+                <action android:name=
+                        "android.intent.action.TEST_START_ACTIVITY_SET_ALARM_FOR_DISMISSAL" />
+                <action android:name="android.intent.action.TEST_START_ACTIVITY_SNOOZE_ALARM" />
+                <category android:name="android.intent.category.LAUNCHER" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.alarmclock.cts"
+                     android:label="CTS tests of android.alarmclock">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/alarmclock/AndroidTest.xml b/tests/tests/alarmclock/AndroidTest.xml
new file mode 100644
index 0000000..aafdb61
--- /dev/null
+++ b/tests/tests/alarmclock/AndroidTest.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
new file mode 100644
index 0000000..d460ade
--- /dev/null
+++ b/tests/tests/alarmclock/common/Android.mk
@@ -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.
+
+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 := CtsAlarmClockCommon
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/alarmclock/common/src/android/alarmclock/common/Utils.java b/tests/tests/alarmclock/common/src/android/alarmclock/common/Utils.java
new file mode 100644
index 0000000..d469592
--- /dev/null
+++ b/tests/tests/alarmclock/common/src/android/alarmclock/common/Utils.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.alarmclock.common;
+
+import android.os.Bundle;
+
+public class Utils {
+    // private constructor - so it can't be instantiated.
+    private Utils() {
+    }
+
+    public enum TestcaseType {
+        DISMISS_ALARM,
+        SET_ALARM,
+        SET_ALARM_FOR_DISMISSAL,
+        SNOOZE_ALARM,
+    }
+    public static final String TESTCASE_TYPE = "Testcase_type";
+    public static final String BROADCAST_INTENT =
+            "android.intent.action.FROM_ALARMCLOCK_CTS_TEST_";
+    public static final String TEST_RESULT = "test_result";
+    public static final String COMPLETION_RESULT = "completion";
+    public static final String ABORT_RESULT = "abort";
+
+    public static final String toBundleString(Bundle bundle) {
+        if (bundle == null) {
+            return "*** Bundle is null ****";
+        }
+        StringBuilder buf = new StringBuilder();
+        if (bundle != null) {
+            buf.append("extras: ");
+            for (String s : bundle.keySet()) {
+                buf.append("(" + s + " = " + bundle.get(s) + "), ");
+            }
+        }
+        return buf.toString();
+    }
+}
diff --git a/tests/tests/alarmclock/res/xml/interaction_service.xml b/tests/tests/alarmclock/res/xml/interaction_service.xml
new file mode 100644
index 0000000..e37017c
--- /dev/null
+++ b/tests/tests/alarmclock/res/xml/interaction_service.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.
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:sessionService="android.alarmclock.service.MainInteractionSessionService"
+    android:recognitionService="android.alarmclock.service.MainRecognitionService"
+    android:settingsActivity="android.alarmclock.service.SettingsActivity"
+    android:supportsAssist="false" />
diff --git a/tests/tests/alarmclock/service/Android.mk b/tests/tests/alarmclock/service/Android.mk
new file mode 100644
index 0000000..53dc564
--- /dev/null
+++ b/tests/tests/alarmclock/service/Android.mk
@@ -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.
+
+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 := CtsAlarmClockCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsAlarmClockService
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/alarmclock/service/AndroidManifest.xml b/tests/tests/alarmclock/service/AndroidManifest.xml
new file mode 100644
index 0000000..074df26
--- /dev/null
+++ b/tests/tests/alarmclock/service/AndroidManifest.xml
@@ -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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.alarmclock.service">
+    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <service android:name=".MainInteractionService"
+                android:label="CTS test voice interaction service"
+                android:permission="android.permission.BIND_VOICE_INTERACTION"
+                android:process=":interactor"
+                android:exported="true">
+            <meta-data android:name="android.voice_interaction"
+                       android:resource="@xml/interaction_service" />
+            <intent-filter>
+                <action android:name="android.service.voice.VoiceInteractionService" />
+            </intent-filter>
+        </service>
+        <activity android:name=".VoiceInteractionMain" >
+            <intent-filter>
+                <action android:name="android.intent.action.VIMAIN_DISMISS_ALARM" />
+                <action android:name="android.intent.action.VIMAIN_SET_ALARM" />
+                <action android:name="android.intent.action.VIMAIN_SET_ALARM_FOR_DISMISSAL" />
+                <action android:name="android.intent.action.VIMAIN_SNOOZE_ALARM" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".SettingsActivity"
+                  android:label="Voice Interaction Settings">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <service android:name=".MainInteractionSessionService"
+                android:permission="android.permission.BIND_VOICE_INTERACTION"
+                android:process=":session">
+        </service>
+        <service android:name=".MainRecognitionService"
+                android:label="CTS Voice Recognition Service">
+            <intent-filter>
+                <action android:name="android.speech.RecognitionService" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="android.speech" android:resource="@xml/recognition_service" />
+        </service>
+    </application>
+</manifest>
+
diff --git a/tests/tests/alarmclock/service/res/xml/interaction_service.xml b/tests/tests/alarmclock/service/res/xml/interaction_service.xml
new file mode 100644
index 0000000..e37017c
--- /dev/null
+++ b/tests/tests/alarmclock/service/res/xml/interaction_service.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.
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:sessionService="android.alarmclock.service.MainInteractionSessionService"
+    android:recognitionService="android.alarmclock.service.MainRecognitionService"
+    android:settingsActivity="android.alarmclock.service.SettingsActivity"
+    android:supportsAssist="false" />
diff --git a/tests/tests/alarmclock/service/res/xml/recognition_service.xml b/tests/tests/alarmclock/service/res/xml/recognition_service.xml
new file mode 100644
index 0000000..132c987
--- /dev/null
+++ b/tests/tests/alarmclock/service/res/xml/recognition_service.xml
@@ -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.
+-->
+
+<recognition-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:settingsActivity="android.alarmclock.service.SettingsActivity" />
diff --git a/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionService.java b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionService.java
new file mode 100644
index 0000000..f96140e
--- /dev/null
+++ b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionService.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 android.alarmclock.service;
+
+import android.alarmclock.common.Utils;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionService;
+import android.util.Log;
+
+public class MainInteractionService extends VoiceInteractionService {
+    static final String TAG = "MainInteractionService";
+    private Intent mIntent;
+    private boolean mReady = false;
+
+    @Override
+    public void onReady() {
+        super.onReady();
+        mReady = true;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        Log.i(TAG, "onStartCommand received");
+        mIntent = intent;
+        Log.i(TAG, "received_testcasetype = " + mIntent.getStringExtra(Utils.TESTCASE_TYPE));
+        maybeStart();
+        return START_NOT_STICKY;
+    }
+
+    private void maybeStart() {
+       if (mIntent == null || !mReady) {
+            Log.wtf(TAG, "Can't start session because either intent is null or onReady() "
+                    + "is not called yet. mIntent = " + mIntent + ", mReady = " + mReady);
+        } else {
+            Log.i(TAG,
+                    "Yay! about to start MainInteractionSession as the voice_interaction_service");
+            if (isActiveService(this, new ComponentName(this, getClass()))) {
+                Bundle args = new Bundle();
+                args.putString(Utils.TESTCASE_TYPE, mIntent.getStringExtra(Utils.TESTCASE_TYPE));
+                Log.i(TAG, "xferring_testcasetype = " + args.getString(Utils.TESTCASE_TYPE));
+                showSession(args, 0);
+            } else {
+                Log.wtf(TAG, "**** Not starting MainInteractionService because" +
+                    " it is not set as the current voice_interaction_service");
+            }
+        }
+    }
+}
diff --git a/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSession.java b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSession.java
new file mode 100644
index 0000000..ede762a
--- /dev/null
+++ b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSession.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.alarmclock.service;
+
+import android.alarmclock.common.Utils;
+import android.alarmclock.common.Utils.TestcaseType;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.provider.AlarmClock;
+import android.service.voice.VoiceInteractionSession;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MainInteractionSession extends VoiceInteractionSession {
+    static final String TAG = "MainInteractionSession";
+
+    private List<MyTask> mUsedTasks = new ArrayList<MyTask>();
+    private Context mContext;
+    private TestcaseType mTestType;
+    private String mTestResult = "";
+
+    MainInteractionSession(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    @Override
+    public void onDestroy() {
+        Log.i(TAG, "Canceling the Asynctasks in onDestroy()");
+        for (MyTask t : mUsedTasks) {
+            t.cancel(true);
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    public void onShow(Bundle args, int showFlags) {
+        super.onShow(args, showFlags);
+        String testCaseType = args.getString(Utils.TESTCASE_TYPE);
+        Log.i(TAG, "received_testcasetype = " + testCaseType);
+        try {
+            mTestType = TestcaseType.valueOf(testCaseType);
+        } catch (IllegalArgumentException e) {
+            Log.wtf(TAG, e);
+            return;
+        } catch (NullPointerException e) {
+            Log.wtf(TAG, e);
+            return;
+        }
+        Intent intent;
+        switch(mTestType) {
+            case DISMISS_ALARM:
+                intent = new Intent(AlarmClock.ACTION_DISMISS_ALARM);
+                intent.putExtra(AlarmClock.EXTRA_ALARM_SEARCH_MODE,
+                        AlarmClock.ALARM_SEARCH_MODE_NEXT);
+                break;
+
+            case SET_ALARM_FOR_DISMISSAL:
+            case SET_ALARM:
+                intent = new Intent(AlarmClock.ACTION_SET_ALARM);
+                intent.putExtra(AlarmClock.EXTRA_HOUR, 14);
+                break;
+
+            case SNOOZE_ALARM:
+                intent = new Intent(AlarmClock.ACTION_SNOOZE_ALARM);
+                break;
+
+            default:
+                Log.e(TAG, "Unexpected value");
+                return;
+        }
+        Log.i(TAG, "starting_voiceactivity: " + intent.toString());
+        startVoiceActivity(intent);
+    }
+
+    @Override
+    public void onTaskFinished(Intent intent, int taskId) {
+        // extras contain the info on what the activity started above did.
+        // we probably could verify this also.
+        Bundle extras = intent.getExtras();
+        Log.i(TAG, "in onTaskFinished: testcasetype = " + mTestType + ", intent: " +
+                intent.toString() + Utils.toBundleString(extras));
+        Intent broadcastIntent = new Intent(Utils.BROADCAST_INTENT + mTestType.toString());
+        broadcastIntent.putExtra(Utils.TEST_RESULT, mTestResult);
+        broadcastIntent.putExtra(Utils.TESTCASE_TYPE, mTestType.toString());
+        Log.i(TAG, "sending_broadcast for testcase+type = " +
+                broadcastIntent.getStringExtra(Utils.TESTCASE_TYPE) +
+                ", test_result = " + broadcastIntent.getStringExtra(Utils.TEST_RESULT));
+        mContext.sendBroadcast(broadcastIntent);
+    }
+
+    synchronized MyTask newTask() {
+        MyTask t = new MyTask();
+        mUsedTasks.add(t);
+        return t;
+    }
+
+    @Override
+    public void onRequestCompleteVoice(CompleteVoiceRequest request) {
+        mTestResult = Utils.COMPLETION_RESULT;
+        CharSequence prompt = request.getVoicePrompt().getVoicePromptAt(0);
+        Log.i(TAG, "in Session testcasetype = " + mTestType +
+                ", onRequestCompleteVoice recvd. message = " + prompt);
+        AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setCompleteReq(true);
+        newTask().execute(asyncTaskArg);
+    }
+
+    @Override
+    public void onRequestAbortVoice(AbortVoiceRequest request) {
+        mTestResult = Utils.ABORT_RESULT;
+        AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setCompleteReq(false);
+        Log.i(TAG, "in Session sending sendAbortResult for testcasetype = " + mTestType);
+        newTask().execute(asyncTaskArg);
+    }
+
+    private class AsyncTaskArg {
+        CompleteVoiceRequest mCompReq;
+        AbortVoiceRequest mAbortReq;
+        boolean isCompleteRequest = true;
+
+        AsyncTaskArg setRequest(CompleteVoiceRequest r) {
+            mCompReq = r;
+            return this;
+        }
+
+        AsyncTaskArg setRequest(AbortVoiceRequest r) {
+            mAbortReq = r;
+            return this;
+        }
+
+        AsyncTaskArg setCompleteReq(boolean flag) {
+            isCompleteRequest = flag;
+            return this;
+        }
+    }
+
+    private class MyTask extends AsyncTask<AsyncTaskArg, Void, Void> {
+        @Override
+        protected Void doInBackground(AsyncTaskArg... params) {
+            AsyncTaskArg arg = params[0];
+            Log.i(TAG, "in MyTask - doInBackground: testType = " +
+                    MainInteractionSession.this.mTestType);
+            if (arg.isCompleteRequest) {
+                arg.mCompReq.sendCompleteResult(new Bundle());
+            } else {
+                arg.mAbortReq.sendAbortResult(new Bundle());
+            }
+            return null;
+        }
+    }
+}
diff --git a/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSessionService.java b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSessionService.java
new file mode 100644
index 0000000..a83c115
--- /dev/null
+++ b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainInteractionSessionService.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.alarmclock.service;
+
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.service.voice.VoiceInteractionSessionService;
+
+public class MainInteractionSessionService extends VoiceInteractionSessionService {
+    @Override
+    public VoiceInteractionSession onNewSession(Bundle args) {
+        return new MainInteractionSession(this);
+    }
+}
diff --git a/tests/tests/alarmclock/service/src/android/alarmclock/service/MainRecognitionService.java b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainRecognitionService.java
new file mode 100644
index 0000000..15a32d4
--- /dev/null
+++ b/tests/tests/alarmclock/service/src/android/alarmclock/service/MainRecognitionService.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.alarmclock.service;
+
+import android.content.Intent;
+import android.speech.RecognitionService;
+import android.util.Log;
+
+/**
+ * Stub recognition service needed to be a complete voice interactor.
+ */
+public class MainRecognitionService extends RecognitionService {
+    private static final String TAG = "MainRecognitionService";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, "onCreate");
+    }
+
+    @Override
+    protected void onStartListening(Intent recognizerIntent, Callback listener) {
+        Log.i(TAG, "onStartListening");
+    }
+
+    @Override
+    protected void onCancel(Callback listener) {
+        Log.i(TAG, "onCancel");
+    }
+
+    @Override
+    protected void onStopListening(Callback listener) {
+        Log.i(TAG, "onStopListening");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        Log.i(TAG, "onDestroy");
+    }
+}
diff --git a/tests/tests/alarmclock/service/src/android/alarmclock/service/SettingsActivity.java b/tests/tests/alarmclock/service/src/android/alarmclock/service/SettingsActivity.java
new file mode 100644
index 0000000..0c4d289
--- /dev/null
+++ b/tests/tests/alarmclock/service/src/android/alarmclock/service/SettingsActivity.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 android.alarmclock.service;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Stub activity to test out settings selection for voice interactor.
+ */
+public class SettingsActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/tests/tests/alarmclock/service/src/android/alarmclock/service/VoiceInteractionMain.java b/tests/tests/alarmclock/service/src/android/alarmclock/service/VoiceInteractionMain.java
new file mode 100644
index 0000000..c1f23a0
--- /dev/null
+++ b/tests/tests/alarmclock/service/src/android/alarmclock/service/VoiceInteractionMain.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 android.alarmclock.service;
+
+import android.alarmclock.common.Utils;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.util.Log;
+
+public class VoiceInteractionMain extends Activity {
+    static final String TAG = "VoiceInteractionMain";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = new Intent();
+        String testCaseType = getIntent().getStringExtra(Utils.TESTCASE_TYPE);
+        Log.i(TAG, "received_testcasetype = " + testCaseType);
+        intent.putExtra(Utils.TESTCASE_TYPE, testCaseType);
+        intent.setComponent(new ComponentName(this, MainInteractionService.class));
+        ComponentName serviceName = startService(intent);
+        Log.i(TAG, "Started service: " + serviceName);
+    }
+}
diff --git a/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java b/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java
new file mode 100644
index 0000000..f41100a
--- /dev/null
+++ b/tests/tests/alarmclock/src/android/alarmclock/cts/AlarmClockTestBase.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.alarmclock.cts;
+
+import android.alarmclock.common.Utils;
+import android.alarmclock.common.Utils.TestcaseType;
+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.provider.AlarmClock;
+import android.os.Bundle;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class AlarmClockTestBase extends ActivityInstrumentationTestCase2<TestStartActivity> {
+    static final String TAG = "AlarmClockTestBase";
+    protected static final int TIMEOUT_MS = 20 * 1000;
+
+    private Context mContext;
+    private String mTestResult;
+    private CountDownLatch mLatch;
+    private ActivityDoneReceiver mActivityDoneReceiver = null;
+    private TestStartActivity mActivity;
+    private TestcaseType mTestCaseType;
+
+    public AlarmClockTestBase() {
+        super(TestStartActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getTargetContext();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mActivityDoneReceiver != null) {
+            try {
+                mContext.unregisterReceiver(mActivityDoneReceiver);
+            } catch (IllegalArgumentException e) {
+                // This exception is thrown if mActivityDoneReceiver in
+                // the above call to unregisterReceiver is never registered.
+                // If so, no harm done by ignoring this exception.
+            }
+            mActivityDoneReceiver = null;
+        }
+        super.tearDown();
+    }
+
+    private void registerBroadcastReceiver(TestcaseType testCaseType) throws Exception {
+        mTestCaseType = testCaseType;
+        mLatch = new CountDownLatch(1);
+        mActivityDoneReceiver = new ActivityDoneReceiver();
+        mContext.registerReceiver(mActivityDoneReceiver,
+                new IntentFilter(Utils.BROADCAST_INTENT + testCaseType.toString()));
+    }
+
+    private boolean isIntentSupported(TestcaseType testCaseType) {
+        Intent intent;
+        switch (testCaseType) {
+          case DISMISS_ALARM:
+              intent = new Intent(AlarmClock.ACTION_DISMISS_ALARM);
+              break;
+
+          case SET_ALARM:
+          case SET_ALARM_FOR_DISMISSAL:
+              intent = new Intent(AlarmClock.ACTION_SET_ALARM);
+              break;
+
+          case SNOOZE_ALARM:
+              intent = new Intent(AlarmClock.ACTION_SNOOZE_ALARM);
+              break;
+
+          default:
+              // shouldn't happen
+              return false;
+        }
+        final PackageManager manager = mContext.getPackageManager();
+        assertNotNull(manager);
+        if (manager.resolveActivity(intent, 0) == null) {
+            Log.i(TAG, "No Voice Activity found for the intent: " + intent.getAction());
+            return false;
+        }
+        return true;
+    }
+
+    protected String runTest(TestcaseType testCaseType) throws Exception {
+        Log.i(TAG, "Begin Testing: " + testCaseType);
+        // Make sure the corresponding intent is supported by the platform, before testing.
+        if (!isIntentSupported(testCaseType)) return Utils.COMPLETION_RESULT;
+
+        if (!startTestActivity(testCaseType)) {
+            fail("test activity start failed for testcase = " + testCaseType);
+            return "";
+        }
+
+        registerBroadcastReceiver(testCaseType);
+        mActivity.startTest(testCaseType.toString());
+        if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Failed to receive broadcast in " + TIMEOUT_MS + "msec");
+            return "";
+        }
+        return mTestResult;
+    }
+
+    private boolean startTestActivity(TestcaseType testCaseType) {
+        Log.i(TAG, "Starting test activity for test: " + testCaseType);
+        Intent intent = new Intent();
+        intent.setAction("android.intent.action.TEST_START_ACTIVITY_" + testCaseType.toString());
+        intent.setComponent(new ComponentName(getInstrumentation().getContext(),
+                TestStartActivity.class));
+        setActivityIntent(intent);
+        mActivity = getActivity();
+        return mActivity != null;
+    }
+
+    class ActivityDoneReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(
+                    Utils.BROADCAST_INTENT + AlarmClockTestBase.this.mTestCaseType.toString())) {
+                AlarmClockTestBase.this.mTestResult = intent.getStringExtra(Utils.TEST_RESULT);
+                Log.i(TAG, "received_broadcast for testcase_type = " +
+                        Utils.BROADCAST_INTENT + AlarmClockTestBase.this.mTestCaseType +
+                        ", test_result = " + AlarmClockTestBase.this.mTestResult);
+                mLatch.countDown();
+            }
+        }
+    }
+}
diff --git a/tests/tests/alarmclock/src/android/alarmclock/cts/DismissAlarmTest.java b/tests/tests/alarmclock/src/android/alarmclock/cts/DismissAlarmTest.java
new file mode 100644
index 0000000..64ecf86
--- /dev/null
+++ b/tests/tests/alarmclock/src/android/alarmclock/cts/DismissAlarmTest.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 android.alarmclock.cts;
+
+import android.alarmclock.common.Utils;
+import android.alarmclock.common.Utils.TestcaseType;
+
+public class DismissAlarmTest extends AlarmClockTestBase {
+    public DismissAlarmTest() {
+        super();
+    }
+
+    public void testAll() throws Exception {
+        assertEquals(Utils.COMPLETION_RESULT, runTest(TestcaseType.SET_ALARM_FOR_DISMISSAL));
+        assertEquals(Utils.COMPLETION_RESULT, runTest(TestcaseType.DISMISS_ALARM));
+    }
+}
diff --git a/tests/tests/alarmclock/src/android/alarmclock/cts/SetAlarmTest.java b/tests/tests/alarmclock/src/android/alarmclock/cts/SetAlarmTest.java
new file mode 100644
index 0000000..a95a1dd
--- /dev/null
+++ b/tests/tests/alarmclock/src/android/alarmclock/cts/SetAlarmTest.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 android.alarmclock.cts;
+
+import android.alarmclock.common.Utils;
+import android.alarmclock.common.Utils.TestcaseType;
+
+public class SetAlarmTest extends AlarmClockTestBase {
+    public SetAlarmTest() {
+        super();
+    }
+
+    public void testAll() throws Exception {
+        assertEquals(Utils.COMPLETION_RESULT, runTest(TestcaseType.SET_ALARM));
+    }
+}
diff --git a/tests/tests/alarmclock/src/android/alarmclock/cts/SnoozeAlarmTest.java b/tests/tests/alarmclock/src/android/alarmclock/cts/SnoozeAlarmTest.java
new file mode 100644
index 0000000..b67a7cf
--- /dev/null
+++ b/tests/tests/alarmclock/src/android/alarmclock/cts/SnoozeAlarmTest.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 android.alarmclock.cts;
+
+import android.alarmclock.common.Utils;
+import android.alarmclock.common.Utils.TestcaseType;
+
+public class SnoozeAlarmTest extends AlarmClockTestBase {
+    public SnoozeAlarmTest() {
+        super();
+    }
+
+    public void testAll() throws Exception {
+        String result = runTest(TestcaseType.SNOOZE_ALARM);
+        // Since there is no way to figure out if there is a currently-firing alarm,
+        // we should expect either of the 2 results:
+        //      Utils.COMPLETION_RESULT
+        //      Utils.ABORT_RESULT
+        // For CTS test purposes, all we can do is to know that snooze-alarm intent
+        // was picked up and processed by the voice_interaction_service and the associated app.
+        // The above call to runTest() would have failed the test otherwise.
+        assertTrue(result.equals(Utils.ABORT_RESULT) || result.equals(Utils.COMPLETION_RESULT));
+    }
+}
diff --git a/tests/tests/alarmclock/src/android/alarmclock/cts/TestStartActivity.java b/tests/tests/alarmclock/src/android/alarmclock/cts/TestStartActivity.java
new file mode 100644
index 0000000..1a3c4eb
--- /dev/null
+++ b/tests/tests/alarmclock/src/android/alarmclock/cts/TestStartActivity.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 android.alarmclock.cts;
+
+import android.alarmclock.common.Utils;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.util.Log;
+
+public class TestStartActivity extends Activity {
+    static final String TAG = "TestStartActivity";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, " in onCreate");
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log.i(TAG, " in onResume");
+    }
+
+    void startTest(String testCaseType) {
+        Intent intent = new Intent();
+        Log.i(TAG, "received_testcasetype = " + testCaseType);
+        intent.putExtra(Utils.TESTCASE_TYPE, testCaseType);
+        intent.setAction("android.intent.action.VIMAIN_" + testCaseType);
+        intent.setComponent(new ComponentName("android.alarmclock.service",
+                "android.alarmclock.service.VoiceInteractionMain"));
+        startActivity(intent);
+    }
+
+    @Override
+    protected void onPause() {
+        Log.i(TAG, " in onPause");
+        super.onPause();
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        Log.i(TAG, " in onStart");
+    }
+
+    @Override
+    protected void onRestart() {
+        super.onRestart();
+        Log.i(TAG, " in onRestart");
+    }
+
+    @Override
+    protected void onStop() {
+        Log.i(TAG, " in onStop");
+        super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.i(TAG, " in onDestroy");
+        super.onDestroy();
+    }
+}
diff --git a/tests/tests/app.usage/AndroidManifest.xml b/tests/tests/app.usage/AndroidManifest.xml
index 11065d4..7869223 100644
--- a/tests/tests/app.usage/AndroidManifest.xml
+++ b/tests/tests/app.usage/AndroidManifest.xml
@@ -21,6 +21,10 @@
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
     <uses-permission android:name="android.permission.SET_TIME" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -29,6 +33,7 @@
         <activity android:name=".Activities$ActivityTwo" />
         <activity android:name=".Activities$ActivityThree" />
         <activity android:name=".Activities$ActivityFour" />
+        <activity android:name=".ActivityTransitionActivity" />
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/app.usage/res/layout/end.xml b/tests/tests/app.usage/res/layout/end.xml
new file mode 100644
index 0000000..2847249
--- /dev/null
+++ b/tests/tests/app.usage/res/layout/end.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.
+-->
+
+<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="#F00"
+          android:id="@+id/redSquare"/>
+    <TextView android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              android:transitionName="target"
+              android:text="@string/hello"/>
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#0F0"
+          android:id="@+id/greenSquare"/>
+</LinearLayout>
diff --git a/tests/tests/app.usage/res/layout/start.xml b/tests/tests/app.usage/res/layout/start.xml
new file mode 100644
index 0000000..793e9b5
--- /dev/null
+++ b/tests/tests/app.usage/res/layout/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/tests/app.usage/res/values/strings.xml b/tests/tests/app.usage/res/values/strings.xml
new file mode 100644
index 0000000..8ca6f73
--- /dev/null
+++ b/tests/tests/app.usage/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?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>
+    <string name="hello">Hello</string>
+</resources>
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
new file mode 100644
index 0000000..10ac4ea
--- /dev/null
+++ b/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionActivity.java
@@ -0,0 +1,172 @@
+/*
+ * 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.app.Activity;
+import android.app.SharedElementCallback;
+import android.app.usage.cts.R;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.os.SystemClock;
+import android.transition.ChangeBounds;
+import android.transition.Explode;
+import android.transition.Fade;
+import android.transition.Transition;
+import android.transition.Transition.TransitionListener;
+import android.view.View;
+
+import java.util.List;
+
+/**
+ * A simple activity containing the start state for an Activity Transition
+ */
+public class ActivityTransitionActivity extends Activity {
+    private static final long DURATION = 50;
+    private static final long SHARED_ELEMENT_READY_DELAY = 50;
+    public static final String LAYOUT_ID = "layoutId";
+    public static final String TEST = "test";
+    public static final String RESULT_RECEIVER = "resultReceiver";
+
+    public static final int NO_TEST = 0;
+    public static final int TEST_ARRIVE = 1;
+
+    public static final String ARRIVE_COUNT = "numArrived";
+    public static final String ARRIVE_ENTER_START_VISIBILITY = "arriveEnterStartVisibility";
+    public static final String ARRIVE_ENTER_DELAY_VISIBILITY = "arriveEnterDelayVisibility";
+    public static final String ARRIVE_ENTER_TIME_READY = "arriveEnterTimeReady";
+    public static final String ARRIVE_ENTER_TIME = "arriveEnterTime";
+    public static final String ARRIVE_RETURN_TIME_READY = "arriveReturnTimeReady";
+    public static final String ARRIVE_RETURN_TIME = "arriveReturnTime";
+
+    private int mLayoutId;
+    private int mTest;
+    private ResultReceiver mResultReceiver;
+    private int mNumSharedElementsArrivedCalled = 0;
+    private boolean mEntering = true;
+
+    public int resultCode = 0;
+    public Bundle result = new Bundle();
+
+    @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);
+        }
+
+        if (mLayoutId == 0) {
+            Intent intent = getIntent();
+            mLayoutId = intent.getIntExtra(LAYOUT_ID, R.layout.start);
+            mTest = intent.getIntExtra(TEST, 0);
+            mResultReceiver = intent.getParcelableExtra(RESULT_RECEIVER);
+        }
+
+        setContentView(mLayoutId);
+
+        startTest();
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        outState.putInt(LAYOUT_ID, mLayoutId);
+        outState.putInt(TEST, mTest);
+        outState.putParcelable(RESULT_RECEIVER, mResultReceiver);
+    }
+
+    private void startTest() {
+        if (mTest == TEST_ARRIVE) {
+            setEnterSharedElementCallback(new SharedElementCallback() {
+                @Override
+                public void onSharedElementsArrived(List<String> sharedElementNames,
+                        final List<View> sharedElements,
+                        final OnSharedElementsReadyListener listener) {
+                    mNumSharedElementsArrivedCalled++;
+                    result.putInt(ARRIVE_COUNT, mNumSharedElementsArrivedCalled);
+                    if (mEntering) {
+                        result.putInt(ARRIVE_ENTER_START_VISIBILITY, sharedElements.get(0).getVisibility());
+                        result.putLong(ARRIVE_ENTER_TIME, SystemClock.uptimeMillis());
+                    } else {
+                        result.putLong(ARRIVE_RETURN_TIME, SystemClock.uptimeMillis());
+                    }
+
+                    getWindow().getDecorView().postDelayed(new Runnable() {
+                        @Override
+                        public void run() {
+                            if (mEntering) {
+                                result.putInt(ARRIVE_ENTER_DELAY_VISIBILITY,
+                                        sharedElements.get(0).getVisibility());
+                                result.putLong(ARRIVE_ENTER_TIME_READY, SystemClock.uptimeMillis());
+                            } else {
+                                result.putLong(ARRIVE_RETURN_TIME_READY,
+                                        SystemClock.uptimeMillis());
+                                mResultReceiver.send(RESULT_OK, result);
+                            }
+                            listener.onSharedElementsReady();
+                        }
+                    }, 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) {
+                }
+            });
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        synchronized (this) {
+            super.onActivityResult(requestCode, resultCode, data);
+            this.resultCode = resultCode;
+            this.notifyAll();
+        }
+    }
+}
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
new file mode 100644
index 0000000..ef126fe
--- /dev/null
+++ b/tests/tests/app.usage/src/android/app/usage/cts/ActivityTransitionTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.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.view.View;
+
+import java.util.List;
+
+public class ActivityTransitionTest extends
+        ActivityInstrumentationTestCase2<ActivityTransitionActivity> {
+    protected ActivityTransitionActivity mActivity;
+
+    private int mNumArrivedCalls;
+    private PassInfo mReceiver;
+    private long mExitTime;
+    private long mExitTimeReady;
+    private long mReenterTime;
+    private long mReenterTimeReady;
+
+    public ActivityTransitionTest() {
+        super(ActivityTransitionActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setActivityInitialTouchMode(false);
+        mActivity = getActivity();
+        mNumArrivedCalls = 0;
+    }
+
+    public void testOnSharedElementsArrived() throws Throwable {
+        getInstrumentation().waitForIdleSync();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mReceiver = new PassInfo(new Handler());
+                mActivity.setExitSharedElementCallback(new SharedElementCallback() {
+                    @Override
+                    public void onSharedElementsArrived(List<String> sharedElementNames,
+                            List<View> sharedElements,
+                            final OnSharedElementsReadyListener listener) {
+                        mNumArrivedCalls++;
+                        final boolean isExiting = mExitTimeReady == 0;
+                        if (isExiting) {
+                            mExitTime = SystemClock.uptimeMillis();
+                        } else {
+                            mReenterTime = SystemClock.uptimeMillis();
+                        }
+                        mActivity.getWindow().getDecorView().postDelayed(new Runnable() {
+                            @Override
+                            public void run() {
+                                if (isExiting) {
+                                    mExitTimeReady = SystemClock.uptimeMillis();
+                                } else {
+                                    mReenterTimeReady = SystemClock.uptimeMillis();
+                                }
+                                listener.onSharedElementsReady();
+                            }
+                        }, 60);
+                    }
+                });
+
+                Bundle options = ActivityOptions.makeSceneTransitionAnimation(mActivity,
+                        mActivity.findViewById(R.id.hello), "target").toBundle();
+                Intent intent = new Intent(mActivity, ActivityTransitionActivity.class);
+                intent.putExtra(ActivityTransitionActivity.TEST,
+                        ActivityTransitionActivity.TEST_ARRIVE);
+                intent.putExtra(ActivityTransitionActivity.LAYOUT_ID, R.layout.end);
+                intent.putExtra(ActivityTransitionActivity.RESULT_RECEIVER, mReceiver);
+                mActivity.startActivityForResult(intent, 0, options);
+            }
+        });
+
+        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);
+            }
+        }
+        assertNotNull(mReceiver.resultData);
+        assertEquals(2, mReceiver.resultData.getInt(
+                ActivityTransitionActivity.ARRIVE_COUNT, -1));
+        assertEquals(2, mNumArrivedCalls);
+        assertNotSame(View.VISIBLE, mReceiver.resultData.getInt(
+                ActivityTransitionActivity.ARRIVE_ENTER_START_VISIBILITY));
+        assertNotSame(View.VISIBLE, mReceiver.resultData.getInt(
+                ActivityTransitionActivity.ARRIVE_ENTER_DELAY_VISIBILITY));
+        long enterTimeReady = mReceiver.resultData.getLong(
+                ActivityTransitionActivity.ARRIVE_ENTER_TIME_READY);
+        long returnTimeReady = mReceiver.resultData.getLong(
+                ActivityTransitionActivity.ARRIVE_RETURN_TIME_READY);
+        long enterTime = mReceiver.resultData.getLong(
+                ActivityTransitionActivity.ARRIVE_ENTER_TIME);
+        long returnTime = mReceiver.resultData.getLong(
+                ActivityTransitionActivity.ARRIVE_RETURN_TIME);
+
+        assertTrue(mExitTime < mExitTimeReady);
+        assertTrue(mExitTimeReady <= enterTime);
+        assertTrue(enterTime < enterTimeReady);
+        assertTrue(enterTimeReady <= returnTime);
+        assertTrue(returnTime < returnTimeReady);
+        assertTrue(returnTimeReady <= mReenterTime);
+        assertTrue(mReenterTime < mReenterTimeReady);
+    }
+
+    public static class PassInfo extends ResultReceiver {
+        public int resultCode;
+        public Bundle resultData;
+
+        public PassInfo(Handler handler) {
+            super(handler);
+        }
+
+        @Override
+        protected void onReceiveResult(int resultCode, Bundle resultData) {
+            this.resultCode = resultCode;
+            this.resultData = resultData;
+        }
+    }
+}
diff --git a/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
new file mode 100644
index 0000000..bd96d76
--- /dev/null
+++ b/tests/tests/app.usage/src/android/app/usage/cts/NetworkUsageStatsTest.java
@@ -0,0 +1,529 @@
+/**
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR 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.app.AppOpsManager;
+import android.app.usage.NetworkStatsManager;
+import android.app.usage.NetworkStats;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkInfo;
+import android.net.NetworkRequest;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.os.RemoteException;
+import android.telephony.TelephonyManager;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.text.MessageFormat;
+import java.util.Scanner;
+import java.net.HttpURLConnection;
+
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+
+public class NetworkUsageStatsTest extends InstrumentationTestCase {
+    private static final String LOG_TAG = "NetworkUsageStatsTest";
+    private static final String APPOPS_SET_SHELL_COMMAND = "appops set {0} {1} {2}";
+    private static final String APPOPS_GET_SHELL_COMMAND = "appops get {0} {1}";
+
+    private static final long MINUTE = 1000 * 60;
+    private static final int TIMEOUT_MILLIS = 15000;
+
+    private interface NetworkInterfaceToTest {
+        int getNetworkType();
+        int getTransportType();
+        String getSystemFeature();
+        String getErrorMessage();
+    }
+
+    private static final NetworkInterfaceToTest[] sNetworkInterfacesToTest =
+            new NetworkInterfaceToTest[] {
+                    new NetworkInterfaceToTest() {
+                        @Override
+                        public int getNetworkType() {
+                            return ConnectivityManager.TYPE_WIFI;
+                        }
+
+                        @Override
+                        public int getTransportType() {
+                            return NetworkCapabilities.TRANSPORT_WIFI;
+                        }
+
+                        @Override
+                        public String getSystemFeature() {
+                            return PackageManager.FEATURE_WIFI;
+                        }
+
+                        @Override
+                        public String getErrorMessage() {
+                            return " Please make sure you are connected to a WiFi access point.";
+                        }
+                    },
+                    new NetworkInterfaceToTest() {
+                        @Override
+                        public int getNetworkType() {
+                            return ConnectivityManager.TYPE_MOBILE;
+                        }
+
+                        @Override
+                        public int getTransportType() {
+                            return NetworkCapabilities.TRANSPORT_CELLULAR;
+                        }
+
+                        @Override
+                        public String getSystemFeature() {
+                            return PackageManager.FEATURE_TELEPHONY;
+                        }
+
+                        @Override
+                        public String getErrorMessage() {
+                            return " Please make sure you have added a SIM card with data plan to" +
+                                    " your phone, have enabled data over cellular and in case of" +
+                                    " dual SIM devices, have selected the right SIM " +
+                                    "for data connection.";
+                        }
+                    }
+    };
+
+    private NetworkStatsManager mNsm;
+    private ConnectivityManager mCm;
+    private PackageManager mPm;
+    private long mStartTime;
+    private long mEndTime;
+
+    private long mBytesRead;
+    private String mWriteSettingsMode;
+    private String mUsageStatsMode;
+
+    private void exerciseRemoteHost(Network network) throws Exception {
+        NetworkInfo networkInfo = mCm.getNetworkInfo(network);
+        if (networkInfo == null) {
+            Log.w(LOG_TAG, "Network info is null");
+        } else {
+            Log.w(LOG_TAG, "Network: " + networkInfo.toString());
+        }
+        InputStreamReader in = null;
+        HttpURLConnection urlc = null;
+        String originalKeepAlive = System.getProperty("http.keepAlive");
+        System.setProperty("http.keepAlive", "false");
+        try {
+            urlc = (HttpURLConnection) network.openConnection(new URL(
+                    "http://www.265.com/"));
+            urlc.setConnectTimeout(TIMEOUT_MILLIS);
+            urlc.setUseCaches(false);
+            urlc.connect();
+            boolean ping = urlc.getResponseCode() == 200;
+            if (ping) {
+                in = new InputStreamReader(
+                        (InputStream) urlc.getContent());
+
+                mBytesRead = 0;
+                while (in.read() != -1) ++mBytesRead;
+            }
+        } catch (Exception e) {
+            Log.i(LOG_TAG, "Badness during exercising remote server: " + e);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    // don't care
+                }
+            }
+            if (urlc != null) {
+                urlc.disconnect();
+            }
+            if (originalKeepAlive == null) {
+                System.clearProperty("http.keepAlive");
+            } else {
+                System.setProperty("http.keepAlive", originalKeepAlive);
+            }
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mNsm = (NetworkStatsManager) getInstrumentation().getContext()
+                .getSystemService(Context.NETWORK_STATS_SERVICE);
+
+        mCm = (ConnectivityManager) getInstrumentation().getContext()
+                .getSystemService(Context.CONNECTIVITY_SERVICE);
+
+        mPm = getInstrumentation().getContext().getPackageManager();
+
+        mWriteSettingsMode = getAppOpsMode(AppOpsManager.OPSTR_WRITE_SETTINGS);
+        setAppOpsMode(AppOpsManager.OPSTR_WRITE_SETTINGS, "allow");
+        mUsageStatsMode = getAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mWriteSettingsMode != null) {
+            setAppOpsMode(AppOpsManager.OPSTR_WRITE_SETTINGS, mWriteSettingsMode);
+        }
+        if (mUsageStatsMode != null) {
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, mUsageStatsMode);
+        }
+        super.tearDown();
+    }
+
+    private void setAppOpsMode(String appop, String mode) throws Exception {
+        final String command = MessageFormat.format(APPOPS_SET_SHELL_COMMAND,
+                getInstrumentation().getContext().getPackageName(), appop, mode);
+        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                .executeShellCommand(command);
+        try {
+            Streams.readFully(new FileInputStream(pfd.getFileDescriptor()));
+        } finally {
+            IoUtils.closeQuietly(pfd.getFileDescriptor());
+        }
+    }
+
+    private String getAppOpsMode(String appop) throws Exception {
+        String result;
+        final String command = MessageFormat.format(APPOPS_GET_SHELL_COMMAND,
+                getInstrumentation().getContext().getPackageName(), appop);
+        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                .executeShellCommand(command);
+        try {
+            result = convertStreamToString(new FileInputStream(pfd.getFileDescriptor()));
+        } finally {
+            IoUtils.closeQuietly(pfd.getFileDescriptor());
+        }
+        if (result == null) {
+            Log.w(LOG_TAG, "App op " + appop + " could not be read.");
+        }
+        return result;
+    }
+
+    private static String convertStreamToString(InputStream is) {
+        try (Scanner scanner = new Scanner(is).useDelimiter("\\A")) {
+            return scanner.hasNext() ? scanner.next() : null;
+        }
+    }
+
+    private class NetworkCallback extends ConnectivityManager.NetworkCallback {
+        private long mTolerance;
+        public boolean success;
+
+        NetworkCallback(long tolerance) {
+            mTolerance = tolerance;
+            success = false;
+        }
+
+        @Override
+        public void onAvailable(Network network) {
+            try {
+                mStartTime = System.currentTimeMillis() - mTolerance;
+                exerciseRemoteHost(network);
+                mEndTime = System.currentTimeMillis() + mTolerance;
+                success = true;
+                synchronized(NetworkUsageStatsTest.this) {
+                    NetworkUsageStatsTest.this.notify();
+                }
+            } catch (Exception e) {
+                Log.w(LOG_TAG, "exercising remote host failed.", e);
+                success = false;
+            }
+        }
+    }
+
+    private boolean shouldTestThisNetworkType(int networkTypeIndex, final long tolerance)
+            throws Exception {
+        boolean hasFeature = mPm.hasSystemFeature(
+                sNetworkInterfacesToTest[networkTypeIndex].getSystemFeature());
+        if (!hasFeature) {
+            return false;
+        }
+        NetworkCallback callback = new NetworkCallback(tolerance);
+        mCm.requestNetwork(new NetworkRequest.Builder()
+                .addTransportType(sNetworkInterfacesToTest[networkTypeIndex].getTransportType())
+                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                .build(), callback);
+        synchronized(this) {
+            try {
+                wait((int)(TIMEOUT_MILLIS * 1.2));
+            } catch (InterruptedException e) {
+            }
+        }
+        if (callback.success) {
+            return true;
+        }
+
+        // This will always fail at this point as we know 'hasFeature' is true.
+        assertFalse (sNetworkInterfacesToTest[networkTypeIndex].getSystemFeature() +
+                " is a reported system feature, " +
+                "however no corresponding connected network interface was found or the attempt " +
+                "to connect has timed out (timeout = " + TIMEOUT_MILLIS + "ms)." +
+                sNetworkInterfacesToTest[networkTypeIndex].getErrorMessage(), hasFeature);
+        return false;
+    }
+
+    private String getSubscriberId(int networkIndex) {
+        int networkType = sNetworkInterfacesToTest[networkIndex].getNetworkType();
+        if (ConnectivityManager.TYPE_MOBILE == networkType) {
+            TelephonyManager tm = (TelephonyManager) getInstrumentation().getContext()
+                    .getSystemService(Context.TELEPHONY_SERVICE);
+            return tm.getSubscriberId();
+        }
+        return "";
+    }
+
+    public void testDeviceSummary() throws Exception {
+        for (int i = 0; i < sNetworkInterfacesToTest.length; ++i) {
+            if (!shouldTestThisNetworkType(i, MINUTE/2)) {
+                continue;
+            }
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "allow");
+            NetworkStats.Bucket bucket = null;
+            try {
+                bucket = mNsm.querySummaryForDevice(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime);
+            } catch (RemoteException | SecurityException e) {
+                fail("testDeviceSummary fails with exception: " + e.toString());
+            }
+            assertNotNull(bucket);
+            assertTimestamps(bucket);
+            assertEquals(bucket.getState(), NetworkStats.Bucket.STATE_ALL);
+            assertEquals(bucket.getUid(), NetworkStats.Bucket.UID_ALL);
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "deny");
+            try {
+                bucket = mNsm.querySummaryForDevice(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime);
+                fail("negative testDeviceSummary fails: no exception thrown.");
+            } catch (RemoteException e) {
+                fail("testDeviceSummary fails with exception: " + e.toString());
+            } catch (SecurityException e) {
+                // expected outcome
+            }
+        }
+    }
+
+    public void testUserSummary() throws Exception {
+        for (int i = 0; i < sNetworkInterfacesToTest.length; ++i) {
+            if (!shouldTestThisNetworkType(i, MINUTE/2)) {
+                continue;
+            }
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "allow");
+            NetworkStats.Bucket bucket = null;
+            try {
+                bucket = mNsm.querySummaryForUser(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime);
+            } catch (RemoteException | SecurityException e) {
+                fail("testUserSummary fails with exception: " + e.toString());
+            }
+            assertNotNull(bucket);
+            assertTimestamps(bucket);
+            assertEquals(bucket.getState(), NetworkStats.Bucket.STATE_ALL);
+            assertEquals(bucket.getUid(), NetworkStats.Bucket.UID_ALL);
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "deny");
+            try {
+                bucket = mNsm.querySummaryForUser(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime);
+                fail("negative testUserSummary fails: no exception thrown.");
+            } catch (RemoteException e) {
+                fail("testUserSummary fails with exception: " + e.toString());
+            } catch (SecurityException e) {
+                // expected outcome
+            }
+        }
+    }
+
+    public void testAppSummary() throws Exception {
+        for (int i = 0; i < sNetworkInterfacesToTest.length; ++i) {
+            if (!shouldTestThisNetworkType(i, MINUTE/2)) {
+                continue;
+            }
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "allow");
+            NetworkStats result = null;
+            try {
+                result = mNsm.querySummary(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime);
+                assertTrue(result != null);
+                NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+                long totalTxPackets = 0;
+                long totalRxPackets = 0;
+                long totalTxBytes = 0;
+                long totalRxBytes = 0;
+                while (result.hasNextBucket()) {
+                    assertTrue(result.getNextBucket(bucket));
+                    assertTimestamps(bucket);
+                    if (bucket.getUid() == Process.myUid()) {
+                        totalTxPackets += bucket.getTxPackets();
+                        totalRxPackets += bucket.getRxPackets();
+                        totalTxBytes += bucket.getTxBytes();
+                        totalRxBytes += bucket.getRxBytes();
+                    }
+                }
+                assertFalse(result.getNextBucket(bucket));
+                assertTrue("No Rx bytes usage for uid " + Process.myUid(), totalRxBytes > 0);
+                assertTrue("No Rx packets usage for uid " + Process.myUid(), totalRxPackets > 0);
+                assertTrue("No Tx bytes usage for uid " + Process.myUid(), totalTxBytes > 0);
+                assertTrue("No Tx packets usage for uid " + Process.myUid(), totalTxPackets > 0);
+            } catch (RemoteException | SecurityException e) {
+                fail("testAppSummary fails with exception: " + e.toString());
+            } finally {
+                if (result != null) {
+                    result.close();
+                }
+            }
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "deny");
+            try {
+                result = mNsm.querySummary(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime);
+                fail("negative testAppSummary fails: no exception thrown.");
+            } catch (RemoteException e) {
+                fail("testAppSummary fails with exception: " + e.toString());
+            } catch (SecurityException e) {
+                // expected outcome
+            }
+        }
+    }
+
+    public void testAppDetails() throws Exception {
+        for (int i = 0; i < sNetworkInterfacesToTest.length; ++i) {
+            // Relatively large tolerance to accommodate for history bucket size.
+            if (!shouldTestThisNetworkType(i, MINUTE * 120)) {
+                continue;
+            }
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "allow");
+            NetworkStats result = null;
+            try {
+                result = mNsm.queryDetails(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime);
+                assertTrue(result != null);
+                NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+                long totalTxPackets = 0;
+                long totalRxPackets = 0;
+                long totalTxBytes = 0;
+                long totalRxBytes = 0;
+                while (result.hasNextBucket()) {
+                    assertTrue(result.getNextBucket(bucket));
+                    assertTimestamps(bucket);
+                    assertEquals(bucket.getState(), NetworkStats.Bucket.STATE_ALL);
+                    if (bucket.getUid() == Process.myUid()) {
+                        totalTxPackets += bucket.getTxPackets();
+                        totalRxPackets += bucket.getRxPackets();
+                        totalTxBytes += bucket.getTxBytes();
+                        totalRxBytes += bucket.getRxBytes();
+                    }
+                }
+                assertFalse(result.getNextBucket(bucket));
+                assertTrue("No Rx bytes usage for uid " + Process.myUid(), totalRxBytes > 0);
+                assertTrue("No Rx packets usage for uid " + Process.myUid(), totalRxPackets > 0);
+                assertTrue("No Tx bytes usage for uid " + Process.myUid(), totalTxBytes > 0);
+                assertTrue("No Tx packets usage for uid " + Process.myUid(), totalTxPackets > 0);
+            } catch (RemoteException | SecurityException e) {
+                fail("testAppDetails fails with exception: " + e.toString());
+            } finally {
+                if (result != null) {
+                    result.close();
+                }
+            }
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "deny");
+            try {
+                result = mNsm.queryDetails(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime);
+                fail("negative testAppDetails fails: no exception thrown.");
+            } catch (RemoteException e) {
+                fail("testAppDetails fails with exception: " + e.toString());
+            } catch (SecurityException e) {
+                // expected outcome
+            }
+        }
+    }
+
+    public void testUidDetails() throws Exception {
+        for (int i = 0; i < sNetworkInterfacesToTest.length; ++i) {
+            // Relatively large tolerance to accommodate for history bucket size.
+            if (!shouldTestThisNetworkType(i, MINUTE * 120)) {
+                continue;
+            }
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "allow");
+            NetworkStats result = null;
+            try {
+                result = mNsm.queryDetailsForUid(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime, Process.myUid());
+                assertTrue(result != null);
+                NetworkStats.Bucket bucket = new NetworkStats.Bucket();
+                long totalTxPackets = 0;
+                long totalRxPackets = 0;
+                long totalTxBytes = 0;
+                long totalRxBytes = 0;
+                while (result.hasNextBucket()) {
+                    assertTrue(result.getNextBucket(bucket));
+                    assertTimestamps(bucket);
+                    assertEquals(bucket.getState(), NetworkStats.Bucket.STATE_ALL);
+                    assertEquals(bucket.getUid(), Process.myUid());
+                    totalTxPackets += bucket.getTxPackets();
+                    totalRxPackets += bucket.getRxPackets();
+                    totalTxBytes += bucket.getTxBytes();
+                    totalRxBytes += bucket.getRxBytes();
+                }
+                assertFalse(result.getNextBucket(bucket));
+                assertTrue("No Rx bytes usage for uid " + Process.myUid(), totalRxBytes > 0);
+                assertTrue("No Rx packets usage for uid " + Process.myUid(), totalRxPackets > 0);
+                assertTrue("No Tx bytes usage for uid " + Process.myUid(), totalTxBytes > 0);
+                assertTrue("No Tx packets usage for uid " + Process.myUid(), totalTxPackets > 0);
+            } catch (RemoteException | SecurityException e) {
+                fail("testUidDetails fails with exception: " + e.toString());
+            } finally {
+                if (result != null) {
+                    result.close();
+                }
+            }
+            setAppOpsMode(AppOpsManager.OPSTR_GET_USAGE_STATS, "deny");
+            try {
+                result = mNsm.queryDetailsForUid(
+                        sNetworkInterfacesToTest[i].getNetworkType(), getSubscriberId(i),
+                        mStartTime, mEndTime, Process.myUid());
+                fail("negative testUidDetails fails: no exception thrown.");
+            } catch (RemoteException e) {
+                fail("testUidDetails fails with exception: " + e.toString());
+            } catch (SecurityException e) {
+                // expected outcome
+            }
+        }
+    }
+
+    private void assertTimestamps(final NetworkStats.Bucket bucket) {
+        assertTrue("Start timestamp " + bucket.getStartTimeStamp() + " is less than " +
+                mStartTime, bucket.getStartTimeStamp() >= mStartTime);
+        assertTrue("End timestamp " + bucket.getEndTimeStamp() + " is greater than " +
+                mEndTime, bucket.getEndTimeStamp() <= mEndTime);
+    }
+}
diff --git a/tests/tests/app/Android.mk b/tests/tests/app/Android.mk
index 39be0dc..301f931 100644
--- a/tests/tests/app/Android.mk
+++ b/tests/tests/app/Android.mk
@@ -21,7 +21,7 @@
 # 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
+LOCAL_JAVA_LIBRARIES := android.test.runner telephony-common voip-common org.apache.http.legacy
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner ctstestserver
 
@@ -31,4 +31,6 @@
 
 LOCAL_INSTRUMENTATION_FOR := CtsAppTestStubs
 
+LOCAL_SDK_VERSION := current
+
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/app/AndroidManifest.xml b/tests/tests/app/AndroidManifest.xml
index 7c09cd2..d05648c 100644
--- a/tests/tests/app/AndroidManifest.xml
+++ b/tests/tests/app/AndroidManifest.xml
@@ -18,10 +18,12 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.cts.app">
 
+    <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" />
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/app/AndroidTest.xml b/tests/tests/app/AndroidTest.xml
new file mode 100644
index 0000000..01ebbcb
--- /dev/null
+++ b/tests/tests/app/AndroidTest.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/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
index 5deff5a..639741d 100644
--- a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
+++ b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryClassTest.java
@@ -19,6 +19,7 @@
 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;
@@ -40,6 +41,8 @@
     }
 
     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
@@ -48,13 +51,30 @@
             =  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_XHIGH, 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);
@@ -65,9 +85,11 @@
             expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_MEDIUM, 64);
             expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_TV, 80);
             expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_HIGH, 80);
-            expectedMemorySizeForLargeScreen.put(DisplayMetrics.DENSITY_XHIGH, 128);
             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);
@@ -78,15 +100,25 @@
             expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_MEDIUM, 80);
             expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_TV, 96);
             expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_HIGH, 96);
-            expectedMemorySizeForXLargeScreen.put(DisplayMetrics.DENSITY_XHIGH, 192);
             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) {
+        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:
@@ -135,8 +167,11 @@
     }
 
     private void assertMemoryForScreenDensity(int memoryClass, int screenDensity, int screenSize) {
-        int expectedMinimumMemory = ExpectedMemorySizesClass.getExpectedMemorySize(screenSize,
-                                                                                   screenDensity);
+        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,
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryInfoTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryInfoTest.java
index 3248caa..8ac5afb 100644
--- a/tests/tests/app/src/android/app/cts/ActivityManagerMemoryInfoTest.java
+++ b/tests/tests/app/src/android/app/cts/ActivityManagerMemoryInfoTest.java
@@ -34,7 +34,7 @@
     }
 
     public void testWriteToParcel() throws Exception {
-        final long AVAILMEM = Process.getFreeMemory();
+        final long AVAILMEM = 1000l;
         mMemory.availMem = AVAILMEM;
         final long THRESHOLD = 500l;
         mMemory.threshold = THRESHOLD;
@@ -59,7 +59,7 @@
     }
 
     public void testReadFromParcel() throws Exception {
-        final long AVAILMEM = Process.getFreeMemory();
+        final long AVAILMEM = 1000l;
         mMemory.availMem = AVAILMEM;
         final long THRESHOLD = 500l;
         mMemory.threshold = THRESHOLD;
diff --git a/tests/tests/app/src/android/app/cts/ActivityManagerTest.java b/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
index 998a005..02d13ef 100644
--- a/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/ActivityManagerTest.java
@@ -16,21 +16,23 @@
 package android.app.cts;
 
 import java.util.ArrayList;
-import java.util.HashSet;
 import java.util.List;
 
 import android.app.Activity;
 import android.app.ActivityManager;
-import android.app.Instrumentation;
-import android.app.ActivityManager.ProcessErrorStateInfo;
 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;
 
@@ -39,6 +41,27 @@
     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;
@@ -119,6 +142,79 @@
         }
     }
 
+    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);
@@ -273,4 +369,158 @@
         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/AlertDialog_BuilderTest.java b/tests/tests/app/src/android/app/cts/AlertDialog_BuilderTest.java
index 9554438..58e69b8 100644
--- a/tests/tests/app/src/android/app/cts/AlertDialog_BuilderTest.java
+++ b/tests/tests/app/src/android/app/cts/AlertDialog_BuilderTest.java
@@ -577,26 +577,6 @@
         assertEquals(view, mView);
     }
 
-    public void testSetViewCustom() throws Throwable {
-        final int viewSpacingLeft = 10;
-        final int viewSpacingTop = 20;
-        final int viewSpacingRight = 30;
-        final int viewSpacingBottom = 40;
-        final View view = new View(mContext);
-        view.setId(100);
-        runTestOnUiThread(new Runnable() {
-            public void run() {
-                mBuilder = new AlertDialog.Builder(mContext);
-                mBuilder.setView(view, viewSpacingLeft, viewSpacingTop, viewSpacingRight,
-                        viewSpacingBottom);
-                mDialog = mBuilder.show();
-                mView = mDialog.getWindow().findViewById(100);
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-        assertEquals(view, mView);
-    }
-
     public void testSetInverseBackgroundForced() throws Throwable {
         runTestOnUiThread(new Runnable() {
             public void run() {
diff --git a/tests/tests/app/src/android/app/cts/DownloadManagerTest.java b/tests/tests/app/src/android/app/cts/DownloadManagerTest.java
index a68d860..21a227b 100644
--- a/tests/tests/app/src/android/app/cts/DownloadManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/DownloadManagerTest.java
@@ -22,6 +22,7 @@
 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;
@@ -30,17 +31,15 @@
 import android.os.SystemClock;
 import android.test.AndroidTestCase;
 import android.text.format.DateUtils;
+import android.util.Log;
 import android.webkit.cts.CtsTestServer;
 
-import com.google.android.collect.Sets;
-
 import java.io.File;
 import java.util.Arrays;
 import java.util.HashSet;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 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
@@ -96,6 +95,92 @@
         }
     }
 
+    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 {
@@ -233,7 +318,7 @@
     }
 
     private class DownloadCompleteReceiver extends BroadcastReceiver {
-        private HashSet<Long> mCompleteIds = Sets.newHashSet();
+        private HashSet<Long> mCompleteIds = new HashSet<>();
 
         public DownloadCompleteReceiver() {
         }
@@ -387,4 +472,11 @@
             }
         }
     }
+
+    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/FragmentTest.java b/tests/tests/app/src/android/app/cts/FragmentTest.java
index 006f0a9..5873ee0 100644
--- a/tests/tests/app/src/android/app/cts/FragmentTest.java
+++ b/tests/tests/app/src/android/app/cts/FragmentTest.java
@@ -17,15 +17,8 @@
 package android.app.cts;
 
 import android.app.Fragment;
-import android.content.Context;
 import android.test.AndroidTestCase;
-import dalvik.annotation.TestLevel;
-import dalvik.annotation.TestTargetClass;
-import dalvik.annotation.TestTargetNew;
-import dalvik.annotation.TestTargets;
-import dalvik.annotation.ToBeFixed;
 
-@TestTargetClass(Fragment.class)
 public class FragmentTest extends AndroidTestCase {
 
     public static class TestFragment extends Fragment {
diff --git a/tests/tests/app/src/android/app/cts/InstrumentationTest.java b/tests/tests/app/src/android/app/cts/InstrumentationTest.java
index b21148e..25403f3 100644
--- a/tests/tests/app/src/android/app/cts/InstrumentationTest.java
+++ b/tests/tests/app/src/android/app/cts/InstrumentationTest.java
@@ -540,7 +540,6 @@
             public void openPanel(int featureId, KeyEvent event) {
             }
 
-            @Override
             public void alwaysReadCloseOnTouchAttr() {
             }
 
diff --git a/tests/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
index 9a895ea..fbb3060 100644
--- a/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -22,12 +22,16 @@
 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;
 
@@ -36,6 +40,8 @@
         super.setUp();
         mNotificationManager = (NotificationManager) mContext.getSystemService(
                 Context.NOTIFICATION_SERVICE);
+        // clear the deck so that our getActiveNotifications results are predictable
+        mNotificationManager.cancelAll();
     }
 
     @Override
@@ -45,27 +51,54 @@
     }
 
     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 Notification notification = new Notification(
-                icon, "No intent", System.currentTimeMillis());
-
         final Intent intent = new Intent(Intent.ACTION_MAIN, Threads.CONTENT_URI);
 
         intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP
@@ -73,9 +106,40 @@
         intent.setAction(Intent.ACTION_MAIN);
 
         final PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
-        notification.setLatestEventInfo(mContext, "notify#" + id, "This is #" + id
-                + "notification  ", pendingIntent);
+        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;) {
+            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
index c2f62c3..6179922 100644
--- a/tests/tests/app/src/android/app/cts/NotificationTest.java
+++ b/tests/tests/app/src/android/app/cts/NotificationTest.java
@@ -77,7 +77,7 @@
         mNotification.tickerText = TICKER_TEXT;
 
         final RemoteViews contentView = new RemoteViews(mContext.getPackageName(),
-                com.android.internal.R.layout.status_bar_latest_event_content);
+                android.R.layout.simple_list_item_1);
         mNotification.contentView = contentView;
         mNotification.defaults = 0;
         mNotification.flags = 0;
@@ -150,13 +150,19 @@
         assertNull(result.sound);
     }
 
-    public void testSetLatestEventInfo() {
-        mNotification = new Notification();
-        mNotification.icon = 1;
+    public void testBuilder() {
         final Intent intent = new Intent();
         final PendingIntent contentIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
-        mNotification.setLatestEventInfo(mContext, CONTENT_TITLE, CONTENT_TEXT, contentIntent);
-        assertTrue(mNotification.contentView instanceof RemoteViews);
+        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);
     }
 
diff --git a/tests/tests/app/src/android/app/cts/ProgressDialogTest.java b/tests/tests/app/src/android/app/cts/ProgressDialogTest.java
index 7405240..b2037b6 100644
--- a/tests/tests/app/src/android/app/cts/ProgressDialogTest.java
+++ b/tests/tests/app/src/android/app/cts/ProgressDialogTest.java
@@ -97,8 +97,7 @@
 
     @UiThreadTest
     public void testShow2() {
-        ProgressDialog dialog = buildDialog();
-        dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, false);
+        ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, false);
 
         /*
          * note: the progress bar's style only supports indeterminate mode,
@@ -120,8 +119,7 @@
         // cancelable is false
         runTestOnUiThread(new Runnable() {
             public void run() {
-                ProgressDialog dialog = buildDialog();
-                dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, false);
+                ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, false);
 
                 dialog.setOnCancelListener(cL);
                 dialog.onBackPressed();
@@ -135,8 +133,7 @@
         // cancelable is true
         runTestOnUiThread(new Runnable() {
             public void run() {
-                ProgressDialog dialog = buildDialog();
-                dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, true);
+                ProgressDialog dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, true);
                 assertFalse(mCanceled);
                 dialog.setOnCancelListener(cL);
                 dialog.onBackPressed();
@@ -157,11 +154,11 @@
         // cancelable is false
         runTestOnUiThread(new Runnable() {
             public void run() {
-                ProgressDialog dialog = buildDialog();
-                dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, false, cL);
+                ProgressDialog dialog = ProgressDialog.show(
+                        mContext, TITLE, MESSAGE, true, false, cL);
 
                 dialog.onBackPressed();
-                dialog.dismiss();
+                dialog.dismiss();;
             }
         });
         mInstrumentation.waitForIdleSync();
@@ -171,8 +168,8 @@
         // cancelable is true
         runTestOnUiThread(new Runnable() {
             public void run() {
-                ProgressDialog dialog = buildDialog();
-                dialog = ProgressDialog.show(mContext, TITLE, MESSAGE, true, true, cL);
+                ProgressDialog dialog = ProgressDialog.show(
+                        mContext, TITLE, MESSAGE, true, true, cL);
 
                 assertFalse(mCanceled);
                 dialog.onBackPressed();
diff --git a/tests/tests/assist/Android.mk b/tests/tests/assist/Android.mk
new file mode 100644
index 0000000..89d2c49
--- /dev/null
+++ b/tests/tests/assist/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 := CtsAssistCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsAssistTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/assist/AndroidManifest.xml b/tests/tests/assist/AndroidManifest.xml
new file mode 100644
index 0000000..a81ced2
--- /dev/null
+++ b/tests/tests/assist/AndroidManifest.xml
@@ -0,0 +1,52 @@
+<?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.assist.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.BIND_VOICE_INTERACTION" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application>
+      <uses-library android:name="android.test.runner" />
+      <activity android:name="android.assist.cts.TestStartActivity"
+                android:label="Assist Test Start Activity">
+          <intent-filter>
+              <action android:name="android.intent.action.TEST_START_ACTIVITY_ASSIST_STRUCTURE" />
+              <action android:name="android.intent.action.TEST_START_ACTIVITY_DISABLE_CONTEXT" />
+              <action android:name="android.intent.action.TEST_START_ACTIVITY_FLAG_SECURE" />
+              <action android:name="android.intent.action.TEST_START_ACTIVITY_LIFECYCLE" />
+              <action android:name="android.intent.action.TEST_START_ACTIVITY_SCREENSHOT" />
+              <action android:name="android.intent.action.TEST_START_ACTIVITY_EXTRA_ASSIST" />
+              <action android:name="android.intent.action.TEST_START_ACTIVITY_TEXTVIEW" />
+              <action android:name="android.intent.action.TEST_START_ACTIVITY_LARGE_VIEW_HIERARCHY" />
+              <action android:name="android.intent.action.TEST_START_ACTIVITY_WEBVIEW" />
+              <category android:name="android.intent.category.LAUNCHER" />
+              <category android:name="android.intent.category.DEFAULT" />
+          </intent-filter>
+      </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.assist.cts"
+                     android:label="CTS tests of android.assist">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/assist/AndroidTest.xml b/tests/tests/assist/AndroidTest.xml
new file mode 100644
index 0000000..329692d
--- /dev/null
+++ b/tests/tests/assist/AndroidTest.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 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>
diff --git a/tests/tests/assist/common/Android.mk b/tests/tests/assist/common/Android.mk
new file mode 100644
index 0000000..88c90ee
--- /dev/null
+++ b/tests/tests/assist/common/Android.mk
@@ -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.
+
+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 := CtsAssistCommon
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/assist/common/src/android/assist/common/Utils.java b/tests/tests/assist/common/src/android/assist/common/Utils.java
new file mode 100644
index 0000000..54416b4
--- /dev/null
+++ b/tests/tests/assist/common/src/android/assist/common/Utils.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.assist.common;
+
+import android.R;
+import android.content.ComponentName;
+import android.os.Bundle;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+import java.util.ArrayList;
+
+public class Utils {
+    public static final String TESTCASE_TYPE = "testcase_type";
+    public static final String TESTINFO = "testinfo";
+    public static final String ACTION_PREFIX = "android.intent.action.";
+    public static final String BROADCAST_INTENT = ACTION_PREFIX + "ASSIST_TESTAPP";
+    public static final String BROADCAST_ASSIST_DATA_INTENT = ACTION_PREFIX + "ASSIST_DATA";
+    public static final String BROADCAST_INTENT_START_ASSIST = ACTION_PREFIX + "START_ASSIST";
+    public static final String ASSIST_RECEIVER_REGISTERED = ACTION_PREFIX + "ASSIST_READY";
+
+    public static final String ACTION_INVALIDATE = "invalidate_action";
+    public static final String GET_CONTENT_VIEW_HEIGHT = ACTION_PREFIX + "GET_CONTENT_VIEW_HEIGHT";
+    public static final String BROADCAST_CONTENT_VIEW_HEIGHT = ACTION_PREFIX + "VIEW_HEIGHT";
+    public static final String SCROLL_TEXTVIEW_ACTION = ACTION_PREFIX + "TEXTVIEW_SCROLL";
+    public static final String SCROLL_SCROLLVIEW_ACTION = ACTION_PREFIX + "SCROLLVIEW_SCROLL";
+    public static final String TEST_ERROR = "Error In Test:";
+
+    public static final String ASSIST_STRUCTURE_KEY = "assist_structure";
+    public static final String ASSIST_CONTENT_KEY = "assist_content";
+    public static final String ASSIST_BUNDLE_KEY = "assist_bundle";
+    public static final String ASSIST_SCREENSHOT_KEY = "assist_screenshot";
+    public static final String SCREENSHOT_COLOR_KEY = "set_screenshot_color";
+    public static final String COMPARE_SCREENSHOT_KEY = "compare_screenshot";
+    public static final String DISPLAY_WIDTH_KEY = "display_width";
+    public static final String DISPLAY_HEIGHT_KEY = "dislay_height";
+    public static final String SCROLL_X_POSITION = "scroll_x_position";
+    public static final String SCROLL_Y_POSITION = "scroll_y_position";
+
+    /** Lifecycle Test intent constants */
+    public static final String LIFECYCLE_PREFIX = ACTION_PREFIX + "lifecycle_";
+    public static final String LIFECYCLE_HASRESUMED = LIFECYCLE_PREFIX + "hasResumed";
+    public static final String LIFECYCLE_ONPAUSE = LIFECYCLE_PREFIX + "onpause";
+    public static final String LIFECYCLE_ONSTOP = LIFECYCLE_PREFIX + "onstop";
+    public static final String LIFECYCLE_ONDESTROY = LIFECYCLE_PREFIX + "ondestroy";
+
+    /** Focus Change Test intent constants */
+    public static final String GAINED_FOCUS = ACTION_PREFIX + "focus_changed";
+    public static final String LOST_FOCUS = ACTION_PREFIX + "lost_focus";
+
+    /** Flag Secure Test intent constants */
+    public static final String FLAG_SECURE_HASRESUMED = ACTION_PREFIX + "flag_secure_hasResumed";
+    public static final String APP_3P_HASRESUMED = ACTION_PREFIX + "app_3p_hasResumed";
+    public static final String TEST_ACTIVITY_LOADED = ACTION_PREFIX + "test_activity_hasResumed";
+
+    /** Two second timeout for getting back assist context */
+    public static final int TIMEOUT_MS = 2 * 1000;
+    /** Four second timeout for an activity to resume */
+    public static final int ACTIVITY_ONRESUME_TIMEOUT_MS = 4000;
+
+    public static final String EXTRA_REGISTER_RECEIVER = "register_receiver";
+
+    /** Extras for passing the Assistant's ContentView's dimensions*/
+    public static final String EXTRA_CONTENT_VIEW_HEIGHT = "extra_content_view_height";
+    public static final String EXTRA_CONTENT_VIEW_WIDTH = "extra_content_view_width";
+    public static final String EXTRA_DISPLAY_POINT = "extra_display_point";
+
+    /** Test name suffixes */
+    public static final String ASSIST_STRUCTURE = "ASSIST_STRUCTURE";
+    public static final String DISABLE_CONTEXT = "DISABLE_CONTEXT";
+    public static final String FLAG_SECURE = "FLAG_SECURE";
+    public static final String LIFECYCLE = "LIFECYCLE";
+    public static final String SCREENSHOT = "SCREENSHOT";
+    public static final String EXTRA_ASSIST = "EXTRA_ASSIST";
+    public static final String VERIFY_CONTENT_VIEW = "VERIFY_CONTENT_VIEW";
+    public static final String TEXTVIEW = "TEXTVIEW";
+    public static final String LARGE_VIEW_HIERARCHY = "LARGE_VIEW_HIERARCHY";
+    public static final String WEBVIEW = "WEBVIEW";
+    public static final String FOCUS_CHANGE = "FOCUS_CHANGE";
+
+    /** Session intent constants */
+    public static final String HIDE_SESSION = "android.intent.action.hide_session";
+
+    /** Stub html view to load into WebView */
+    public static final String WEBVIEW_HTML_GREETING = "Hello WebView!";
+    public static final String WEBVIEW_HTML = "<html><body><div><p>" + WEBVIEW_HTML_GREETING
+            + "</p></div></body></html>";
+
+    /** Extra data to add to assist data and assist content */
+    private static Bundle EXTRA_ASSIST_BUNDLE;
+    private static String STRUCTURED_JSON;
+
+    public static final String getStructuredJSON() throws Exception {
+        if (STRUCTURED_JSON == null) {
+            STRUCTURED_JSON = new JSONObject()
+                    .put("@type", "MusicRecording")
+                    .put("@id", "https://example/music/recording")
+                    .put("url", "android-app://com.example/https/music/album")
+                    .put("name", "Album Title")
+                    .put("hello", "hi there")
+                    .put("knownNull", null)
+                    .put("unicode value", "\ud800\udc35")
+                    .put("empty string", "")
+                    .put("LongString",
+                        "lkasdjfalsdkfjalsdjfalskj9i9234jl1w23j4o123j412l3j421l3kj412l3kj1l3k4j32")
+                    .put("\ud800\udc35", "any-value")
+                    .put("key with spaces", "any-value")
+                    .toString();
+        }
+        return STRUCTURED_JSON;
+    }
+
+    public static final Bundle getExtraAssistBundle() {
+        if (EXTRA_ASSIST_BUNDLE == null) {
+            EXTRA_ASSIST_BUNDLE = new Bundle();
+            addExtraAssistDataToBundle(EXTRA_ASSIST_BUNDLE);
+        }
+        return EXTRA_ASSIST_BUNDLE;
+    }
+
+    public static void addExtraAssistDataToBundle(Bundle data) {
+        data.putString("hello", "there");
+        data.putBoolean("isthis_true_or_false", true);
+        data.putInt("number", 123);
+    }
+
+    /** The shim activity that starts the service associated with each test. */
+    public static final String getTestActivity(String testCaseType) {
+        switch (testCaseType) {
+            case DISABLE_CONTEXT:
+                // doesn't need to wait for activity to resume
+                // can be activated on top of any non-secure activity.
+                return "service.DisableContextActivity";
+            case ASSIST_STRUCTURE:
+            case FLAG_SECURE:
+            case LIFECYCLE:
+            case SCREENSHOT:
+            case EXTRA_ASSIST:
+            case VERIFY_CONTENT_VIEW:
+            case TEXTVIEW:
+            case LARGE_VIEW_HIERARCHY:
+            case WEBVIEW:
+            case FOCUS_CHANGE:
+                return "service.DelayedAssistantActivity";
+            default:
+                return "";
+        }
+    }
+
+    /**
+     * The test app associated with each test.
+     */
+    public static final ComponentName getTestAppComponent(String testCaseType) {
+        switch (testCaseType) {
+            case ASSIST_STRUCTURE:
+            case LARGE_VIEW_HIERARCHY:
+                return new ComponentName(
+                        "android.assist.testapp", "android.assist.testapp.TestApp");
+            case DISABLE_CONTEXT:
+                return new ComponentName(
+                        "android.assist.testapp", "android.assist.testapp.TestApp");
+            case FLAG_SECURE:
+                return new ComponentName(
+                        "android.assist.testapp", "android.assist.testapp.SecureActivity");
+            case LIFECYCLE:
+                return new ComponentName(
+                        "android.assist.testapp", "android.assist.testapp.LifecycleActivity");
+            case SCREENSHOT:
+                return new ComponentName(
+                        "android.assist.testapp", "android.assist.testapp.ScreenshotActivity");
+            case EXTRA_ASSIST:
+                return new ComponentName(
+                        "android.assist.testapp", "android.assist.testapp.ExtraAssistDataActivity");
+            case TEXTVIEW:
+                return new ComponentName(
+                        "android.assist.testapp", "android.assist.testapp.TextViewActivity");
+            case WEBVIEW:
+                return new ComponentName(
+                        "android.assist.testapp", "android.assist.testapp.WebViewActivity");
+            case FOCUS_CHANGE:
+                return new ComponentName(
+                        "android.assist.testapp", "android.assist.testapp.FocusChangeActivity");
+            default:
+                return new ComponentName("","");
+        }
+    }
+
+    /**
+     * Returns the amount of time to wait for assist data.
+     */
+    public static final int getAssistDataTimeout(String testCaseType) {
+        switch (testCaseType) {
+            case SCREENSHOT:
+                // needs to wait for 3p activity to resume before receiving assist data.
+                return TIMEOUT_MS + ACTIVITY_ONRESUME_TIMEOUT_MS;
+            default:
+                return TIMEOUT_MS;
+        }
+    }
+
+    public static final String toBundleString(Bundle bundle) {
+        if (bundle == null) {
+            return "*** Bundle is null ****";
+        }
+        StringBuffer buf = new StringBuffer("Bundle is: ");
+        String testType = bundle.getString(TESTCASE_TYPE);
+        if (testType != null) {
+            buf.append("testcase type = " + testType);
+        }
+        ArrayList<String> info = bundle.getStringArrayList(TESTINFO);
+        if (info != null) {
+            for (String s : info) {
+                buf.append(s + "\n\t\t");
+            }
+        }
+        return buf.toString();
+    }
+
+    public static final void addErrorResult(final Bundle testinfo, final String msg) {
+        testinfo.getStringArrayList(testinfo.getString(Utils.TESTCASE_TYPE))
+            .add(TEST_ERROR + " " + msg);
+    }
+}
diff --git a/tests/tests/assist/res/layout/multiple_text_views.xml b/tests/tests/assist/res/layout/multiple_text_views.xml
new file mode 100644
index 0000000..455d5e3
--- /dev/null
+++ b/tests/tests/assist/res/layout/multiple_text_views.xml
@@ -0,0 +1,79 @@
+<?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:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <ScrollView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1">
+    <TextView
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:scrollbars="vertical"
+      android:text="@string/text_too_large_to_fit" />
+  </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/res/layout/screenshot_activity.xml b/tests/tests/assist/res/layout/screenshot_activity.xml
new file mode 100644
index 0000000..05051dc
--- /dev/null
+++ b/tests/tests/assist/res/layout/screenshot_activity.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.
+-->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/screenshot_activity"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/res/layout/test_app.xml b/tests/tests/assist/res/layout/test_app.xml
new file mode 100644
index 0000000..3fbfd6d
--- /dev/null
+++ b/tests/tests/assist/res/layout/test_app.xml
@@ -0,0 +1,47 @@
+<?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:orientation="vertical">
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/welcome" />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="350dp"
+        android:orientation="vertical"
+        android:layout_gravity="bottom">
+        <FrameLayout
+            android:id="@+id/card1"
+            android:layout_width="match_parent"
+            android:layout_height="150dp"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="8dp"
+            android:layout_marginTop="16dp"
+            android:elevation="3dp">
+        </FrameLayout>
+        <View
+            android:id="@+id/card2"
+            android:layout_width="match_parent"
+            android:layout_height="200dp"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="8dp"
+            android:layout_marginTop="16dp"
+            android:elevation="3dp"/>
+    </LinearLayout>
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/res/layout/text_view.xml b/tests/tests/assist/res/layout/text_view.xml
new file mode 100644
index 0000000..9964ab6
--- /dev/null
+++ b/tests/tests/assist/res/layout/text_view.xml
@@ -0,0 +1,42 @@
+<?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:id="@+id/text_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:scrollbars="vertical"
+        android:clickable="true"
+        android:text="@string/text_too_large_to_fit" />
+
+    <ScrollView
+        android:id="@+id/scroll_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:scrollbars="vertical"
+            android:text="@string/text_too_large_to_fit" />
+    </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/res/layout/webview.xml b/tests/tests/assist/res/layout/webview.xml
new file mode 100644
index 0000000..bdb8082
--- /dev/null
+++ b/tests/tests/assist/res/layout/webview.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.
+-->
+<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/webview"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    </WebView>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/res/values/strings.xml b/tests/tests/assist/res/values/strings.xml
new file mode 100644
index 0000000..8170d70
--- /dev/null
+++ b/tests/tests/assist/res/values/strings.xml
@@ -0,0 +1,284 @@
+<?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>
+    <string name="welcome">Hello there!</string>
+    <string name="testAppTitle">Assist Structure Test Activity</string>
+    <string name="screenshotActivityTitle">Screenshot Test Activity</string>
+    <string name="textViewActivityTitle">TextView Test Activity</string>
+    <string name="webViewActivityTitle">WebView Test Activity</string>
+    <string name="text_too_large_to_fit">❤ ☀ ☆ ☂ ☻ ♞ ☯ ☭ ☢ € →Hello هتاف للترحيب שלום
+        përshëndetje Добры дзень 您好 হ্যালো здравей მიესალმები Χαίρετε હેલો नमस्ते Nnọọ こんにちは ಹಲೋ
+        Сәлеметсіз бе ជំរាបសួរ 안녕하세요 ສະບາຍດີ ഹലോ हॅलो Сайн байна уу नमस्ते سلامהעלא ہیلو
+        မင်္ဂလာပါ ਸਤ ਸ੍ਰੀ ਅਕਾਲ Здравствуйте здраво ආයුබෝවන් ஹலோ హలో สวัสดี Pẹlẹ o
+        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+        convallis nunc et vestibulum. Sed et consequat quam, blandit varius tortor. Curabitur
+        accumsan nulla lectus, placerat condimentum odio elementum vel. Nulla erat ex, accumsan ut
+        enim sagittis, scelerisque efficitur ante. Nullam quis orci nec magna maximus malesuada ac
+        id sem. Nam sagittis erat risus, a accumsan neque congue sit amet. Nullam risus velit,
+        faucibus eget scelerisque et, maximus eget arcu. Sed porta sed libero ac imperdiet.
+
+        Nulla sem lectus, ullamcorper id dui vel, rutrum interdum augue. Proin aliquam nisi vitae
+        hendrerit tempor. Mauris porttitor velit et egestas feugiat. Vivamus eu dapibus libero,
+        quis fringilla urna. Suspendisse non turpis dui. Vivamus facilisis diam vitae est auctor
+        luctus. Etiam quis lectus viverra, interdum turpis eu, aliquam sem. Nulla vulputate lacinia
+        nisi a dictum. Cras faucibus vitae tortor at ullamcorper. Quisque sit amet sapien maximus,
+        ornare nisi non, imperdiet magna. Vestibulum tempor metus ac mi ultrices dapibus.
+
+        Suspendisse potenti. Mauris pellentesque lacinia tristique. Pellentesque vel dui quis sem
+        lacinia imperdiet feugiat vitae sem. Proin a arcu magna. Sed quis augue eu mi accumsan
+        pellentesque pretium in leo. Duis euismod purus mauris, ac tempor erat auctor non. Quisque
+        bibendum est pulvinar ex dapibus, ac tincidunt nibh tempus. Mauris sodales sem id purus
+        commodo iaculis. Pellentesque a quam dapibus, vehicula lectus at, tincidunt arcu. In
+        placerat porttitor urna quis consequat. Nullam feugiat nisl sed urna hendrerit, sed
+        elementum massa iaculis. Fusce sit amet turpis hendrerit, varius lorem sed, luctus mi.
+        Phasellus sit amet ex orci. Duis scelerisque nisl quis efficitur maximus. Curabitur vitae
+        accumsan nunc, eget varius nisi.
+
+        Fusce efficitur malesuada luctus. Aliquam dapibus tortor sit amet purus semper, sit amet
+        pretium lorem feugiat. Maecenas gravida sed arcu et placerat. Nulla facilisi. Cras placerat
+        rutrum mi, in rutrum mauris maximus at. Mauris eu suscipit ante. Nullam pharetra egestas
+        diam a viverra. Donec sem turpis, tempor malesuada est vel, blandit accumsan magna. In
+        iaculis velit in efficitur hendrerit. Nulla facilisi. Curabitur eget ligula lorem. Sed sit
+        amet dolor ut ligula malesuada condimentum. Phasellus molestie augue eget libero commodo,
+        vel blandit ex blandit.
+
+        Morbi cursus tortor ante, et tempus nisi tempus et. Suspendisse quis gravida diam. Aliquam
+        efficitur dolor sit amet sollicitudin varius. Etiam libero purus, ornare nec nulla vel,
+        ullamcorper blandit nisl. Sed vel consequat diam, id placerat sem. Donec quis elementum
+        urna. In posuere bibendum nunc, in condimentum justo blandit ac. Quisque enim lorem,
+        gravida at purus at, sollicitudin imperdiet erat. Ut consectetur rutrum ante, et pretium
+        odio iaculis a. Nullam a nibh vulputate, volutpat lectus eu, pellentesque felis. Nam
+        vehicula suscipit diam nec convallis. Quisque congue maximus sem, sit amet hendrerit leo
+        tempor et.
+
+        Nam eu consequat dui. Sed semper dignissim mattis. Integer tortor eros, tempor in lectus a,
+        lobortis aliquam dolor. Phasellus at sagittis magna. Nulla eleifend orci ac urna auctor,
+        sit amet luctus urna vulputate. Nulla venenatis venenatis erat ac finibus. Etiam
+        ullamcorper elementum suscipit. Morbi nec velit non mauris porta finibus. Nullam in
+        sagittis odio. Praesent eget nisl ut mauris vestibulum feugiat. Sed vulputate at elit et
+        cursus. Praesent viverra erat blandit nunc egestas, vel feugiat ex condimentum. Class
+        aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
+
+        Nulla fermentum mattis urna, non gravida eros vestibulum et. Fusce porttitor augue turpis,
+        sit amet aliquam augue sodales non. Nunc neque odio, sagittis sed gravida euismod, commodo
+        at libero. Donec porttitor pulvinar neque vitae lobortis. Aliquam accumsan velit nec sapien
+        placerat egestas. Aliquam at tincidunt massa, et dignissim justo. Donec sapien ante, rutrum
+        et tristique a, commodo a massa.
+
+        Nunc placerat lobortis magna, et molestie lacus semper porta. Lorem ipsum dolor sit amet,
+        consectetur adipiscing elit. Phasellus ac ligula dui. Duis ultrices viverra eros fermentum
+        finibus. Integer ultrices, felis in accumsan volutpat, mi ligula hendrerit nunc, nec
+        accumsan mauris tellus sit amet metus. Ut pharetra enim et sapien sollicitudin, nec
+        ultricies urna pharetra. Morbi non tortor nec dui feugiat rutrum. Aliquam malesuada sodales
+        risus, sed congue nunc accumsan vitae. Etiam nunc magna, tempus non suscipit eu, feugiat ut
+        nibh. Maecenas et libero ut nisl pellentesque tempor nec vel quam. Etiam sem ligula,
+        ullamcorper non dolor a, viverra placerat nulla. Nullam dictum commodo dui, sed ultrices
+        enim sagittis eget. Morbi non consectetur lectus. In gravida, augue vitae pulvinar
+        molestie, ligula orci vulputate ex, at bibendum urna felis nec nibh. Sed nisl nunc, iaculis
+        at augue venenatis, fringilla accumsan velit. Curabitur nec augue porttitor, rutrum nisi
+        vitae, elementum orci.
+
+        Vestibulum eu tortor iaculis, dignissim velit quis, rhoncus dolor. Donec et tincidunt
+        nulla. Duis faucibus auctor erat ac ultricies. In a fermentum mi. Fusce vitae mi id sem
+        interdum tincidunt. Nulla hendrerit orci turpis, in maximus elit mollis eget. Aliquam erat
+        volutpat. Phasellus mattis est nibh, ut scelerisque ligula egestas eu. Ut molestie orci a
+        malesuada tempor. Sed tempus arcu id orci gravida faucibus. Vivamus ac lacinia neque, at
+        vehicula magna.
+
+        Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
+        Nullam aliquam, justo scelerisque egestas sodales, purus odio posuere arcu, ac ultrices
+        nunc felis non massa. Aliquam vulputate ipsum sed aliquet auctor. In pulvinar, eros sit
+        amet ultricies tristique, lacus ipsum scelerisque eros, nec vestibulum est lectus quis
+        lorem. Pellentesque ac augue ut eros mattis viverra vitae ut lacus. Phasellus imperdiet
+        efficitur elit eget tincidunt. Donec sodales metus at dolor pulvinar, at gravida nibh
+        facilisis. Sed nec tellus luctus, cursus lacus sed, euismod orci. Maecenas sit amet leo
+        orci. Nulla non leo non mi eleifend consequat sit amet vitae dui. Sed gravida gravida
+        justo, tincidunt ultrices justo semper vitae. Fusce at nisi nisl. Morbi molestie quis justo
+        a convallis. Curabitur massa lacus, feugiat quis mauris ac, malesuada viverra est.
+
+        Phasellus bibendum faucibus velit, ac scelerisque velit tincidunt eu. Curabitur quis
+        suscipit erat, ac feugiat odio. Nullam et sapien et nibh maximus posuere. Vivamus faucibus
+        justo eget dictum sollicitudin. Etiam at leo eget elit facilisis lobortis. Maecenas
+        bibendum tortor non erat pretium dignissim. Fusce id imperdiet augue. Suspendisse dignissim
+        magna vel odio viverra varius. Maecenas suscipit ante et lorem sodales vehicula. Quisque
+        vel magna id sem suscipit iaculis. Etiam in elementum risus.
+
+        Suspendisse odio nisi, pharetra et purus sit amet, placerat lobortis diam. Phasellus enim
+        nunc, posuere sed porta in, ornare eu ipsum. Phasellus imperdiet porta neque, vitae dapibus
+        tellus feugiat eget. Nulla sodales leo ac efficitur luctus. Vivamus eget ipsum quis ante
+        pulvinar blandit. Vestibulum a justo convallis justo elementum viverra ut sit amet nisl.
+        Suspendisse eget augue fermentum, sagittis risus a, rhoncus elit. Vestibulum in maximus
+        tortor, non vestibulum libero. Nunc accumsan neque a nisl dapibus, id laoreet neque congue.
+        Pellentesque sapien odio, fringilla non nulla nec, varius placerat diam. Aliquam
+        consectetur neque eu ipsum posuere, nec dignissim sem faucibus. Donec sit amet tempor
+        sapien. Nam at libero vel lorem dapibus ultrices a vel augue. Nunc facilisis justo ante,
+        mollis tristique velit aliquet quis. Mauris consectetur odio at urna bibendum aliquam.
+
+           Nullam lectus orci, hendrerit ut ultrices in, dapibus pellentesque nibh. Aliquam arcu
+        metus, lobortis vel dignissim id, tempus ut ante. Integer vitae ante augue. In hac habitasse
+        platea dictumst. Vestibulum in tellus ante. Cras nisi tellus, congue ac velit quis, rhoncus
+        ornare ligula. Sed facilisis gravida pellentesque. Praesent id ultrices orci, ac ultricies
+        arcu. Donec at ante quis augue faucibus congue. Donec mattis quam dui, ut vestibulum orci
+        tempor mattis. Phasellus in quam id tortor varius ullamcorper ac ac ante. Proin cursus
+        accumsan sem, vel finibus lectus eleifend ut. Donec efficitur feugiat diam id ultricies. In
+        quis euismod nisi. Vestibulum eget viverra sapien. Donec scelerisque nec elit vel viverra.
+
+           Sed mi urna, rutrum quis augue vel, aliquet placerat diam. Proin faucibus in odio et
+        consequat. Proin ut ex in mauris eleifend efficitur. Praesent ullamcorper sollicitudin urna,
+        sed mollis elit hendrerit non. Duis leo lorem, efficitur eu auctor sit amet, scelerisque
+        scelerisque magna. Mauris eget massa auctor, viverra arcu a, elementum nibh. Sed
+        pellentesque, nulla sed condimentum posuere, tortor metus congue sem, nec placerat neque
+        magna vitae purus.
+
+           Etiam at risus vitae sapien aliquam condimentum. Vestibulum id libero placerat purus
+        vehicula consectetur. Pellentesque sapien sapien, posuere at pulvinar at, ultrices sed est.
+        Maecenas nec condimentum ante. Aenean volutpat, ex condimentum hendrerit hendrerit, quam
+        nisl  pharetra nibh, vitae bibendum nisl odio vel lacus. Morbi mi tellus, bibendum id mauris
+        eu,  facilisis volutpat turpis. Maecenas rutrum convallis felis. Quisque eget feugiat felis.
+        Duis pellentesque iaculis massa ut facilisis. Donec nec commodo magna. Integer aliquet orci
+        a odio eleifend elementum. Quisque molestie, urna ut molestie eleifend, odio neque maximus
+        enim, eget viverra metus lectus eget quam. Fusce nec urna ac neque bibendum aliquam vel quis
+        dui. Fusce ac quam consequat, feugiat leo vitae, auctor felis.
+
+           Sed ac metus mauris. Sed sed velit ut tortor aliquam vestibulum at eu arcu. Etiam eu
+        posuere lacus. Maecenas id lacus quis sem mollis sodales. Quisque justo sapien, vulputate ac
+        mi ut, congue vestibulum orci. Donec euismod erat rutrum, laoreet urna sed, accumsan purus.
+        Donec eu quam a sapien condimentum accumsan. Sed at tellus lorem. Curabitur bibendum, arcu
+        sit amet finibus sodales, mi sem finibus sem, eget scelerisque tellus neque vel urna.
+        Suspendisse eu augue nec erat suscipit luctus sed non metus.
+
+           Suspendisse porttitor ex ipsum. Pellentesque tristique eros sed pharetra porttitor.
+        Quisque ut elit vehicula, aliquet est nec, faucibus tellus. Donec ex augue, congue eu
+        dignissim  maximus, vestibulum at purus. Nulla quam enim, laoreet sit amet molestie vel,
+        dapibus nec tortor. Sed interdum massa ac orci gravida, vel viverra lacus lacinia. Donec
+        nisl lacus, fermentum at faucibus ac, consequat ut nibh. Praesent laoreet est augue, vitae
+        maximus dui efficitur sit amet. Cras ipsum tellus, tincidunt at volutpat non, tincidunt ut
+        elit. Morbi commodo sagittis gravida. Pellentesque sed ante massa. Phasellus a turpis non
+        turpis cursus consequat sed nec tortor. Proin et augue elit.
+
+           Duis finibus sem commodo rutrum pulvinar. In sollicitudin ante magna, vel facilisis
+        tellus fringilla vel. Nam purus ex, tincidunt eget varius at, euismod nec elit. Curabitur
+        consequat nulla vel nisi iaculis, ut mattis odio congue. Nulla et mollis tortor, a maximus
+        justo. Donec semper eros sed nunc rhoncus condimentum. Donec nibh purus, interdum non lectus
+        id, porta convallis eros.
+
+           Sed hendrerit, dui non sagittis sollicitudin, enim ex imperdiet sapien, et maximus lorem
+        dolor a enim. Nulla risus nisl, vestibulum at ornare posuere, congue in felis. Duis sagittis
+        id diam a varius. Donec viverra eu orci sodales commodo. Cras metus tortor, sodales vitae
+        auctor non, scelerisque a ante. Quisque sodales nisi libero, ut lobortis enim suscipit ut.
+        Cras mi ipsum, maximus non bibendum sit amet, pharetra quis ipsum. Vestibulum venenatis, odi
+        at hendrerit pretium, tellus diam auctor justo, non posuere quam mauris id nisl. Nam dolor
+        nibh, molestie et lectus et, scelerisque porta elit. Vestibulum viverra condimentum auctor.
+        In eros tortor, convallis sed quam eu, ultrices malesuada purus. Integer lorem quam,
+        ultricies at est consectetur, sagittis porttitor eros. Proin non risus vitae lacus
+        consectetur malesuada non pulvinar justo. Aliquam mollis nisi nunc, sit amet vulputate metus
+        sollicitudin vel.
+
+           Quisque auctor varius fermentum. Praesent mollis justo sit amet est consectetur, in
+        volutpat tellus mollis. Aenean at bibendum eros, at finibus nibh. Phasellus nec mi sem.
+        Mauris pellentesque dui sit amet lobortis aliquam. Ut nec massa at urna aliquam gravida vel
+        in magna. Donec consectetur sapien magna, a auctor sapien placerat eu.
+
+           Pellentesque aliquet ante sed lacus gravida rutrum. Maecenas euismod varius felis, nec
+        tempus metus tempus et. Nam convallis augue a massa scelerisque, vel pharetra dolor
+        scelerisque. Fusce porttitor mi a magna rutrum condimentum. Aliquam fermentum at turpis at
+        auctor. Nulla ut suscipit dui. Donec rutrum viverra aliquam. Donec elementum nisl sapien, ac
+        blandit risus porta facilisis. Proin tellus dolor, ornare vel magna sit amet, maximus
+        volutpat felis. Aenean euismod aliquet purus, at finibus nunc elementum eu. Ut faucibus
+        ullamcorper consectetur. Aenean egestas arcu id mauris elementum, at sollicitudin est
+        congue. Sed a odio mattis, sollicitudin erat ut, tristique dolor. Aliquam luctus risus quis
+        tellus semper, a vestibulum nulla viverra.
+
+           Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
+        himenaeos. Vestibulum sit amet nisi felis. Praesent condimentum consequat lacus pulvinar
+        imperdiet. Praesent vel condimentum quam. Maecenas eu aliquet odio. Vestibulum sed nulla
+        mattis lacus porta bibendum a ac eros. Nunc porttitor sagittis laoreet. Duis porta eros at
+        congue tristique. Pellentesque quis fringilla neque, a hendrerit tellus. Pellentesque ac
+        nibh ac tellus pulvinar porttitor et in est. Integer blandit lorem libero, eu pulvinar
+        tellus posuere eget. Vivamus pretium nulla ligula, ut dapibus massa fringilla in.
+        Suspendisse consectetur sem non elit porta, id pellentesque erat dapibus. Quisque ex mi,
+        tempus et hendrerit nec, gravida quis odio. Ut at mi in leo scelerisque venenatis.
+
+           Ut sed tellus in risus tincidunt tempor ut at arcu. Maecenas ut convallis justo. In
+        rutrum urna eu massa rhoncus, eget condimentum augue vehicula. Nullam eget placerat erat.
+        Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
+        Aenean at volutpat orci, a lobortis dolor. Sed consequat facilisis interdum. Fusce libero
+        neque, fringilla in congue a, vehicula rutrum ipsum. Nam ornare placerat vestibulum. Proin
+        nec orci velit. Pellentesque scelerisque gravida diam, ut tristique libero tempus eu. Nam
+        semper lacus nec nulla volutpat imperdiet non eget tortor. Sed et pellentesque ligula.
+
+           Aenean a dolor dolor. Curabitur ut placerat lacus, sit amet aliquet orci. Aliquam erat
+        volutpat. Cras mollis sit amet lectus ornare pretium. Vestibulum fringilla orci vel est
+        iaculis, at mattis quam condimentum. Vivamus semper elit consectetur lectus gravida, in
+        sollicitudin mi fringilla. Donec eget lorem in orci blandit aliquam. Pellentesque libero
+        tellus, dignissim id augue et, vulputate viverra nisl. Cum sociis natoque penatibus et
+        magnis dis parturient montes, nascetur ridiculus mus. Donec ac vulputate metus, eu suscipit
+        sem. Donec placerat, nulla at sodales hendrerit, orci tortor vestibulum purus, non pharetra
+        nulla purus posuere arcu.
+
+           Quisque feugiat elit sem, ac interdum diam pharetra nec. Curabitur sem libero, vulputate
+        eu libero vitae, volutpat facilisis ligula. Aenean maximus erat laoreet, interdum ante in,
+        ultrices nisi. Nullam nec efficitur sapien. Integer feugiat et tortor ac bibendum. Donec a
+        scelerisque tortor. Cras quis viverra diam, vitae viverra ipsum. Aliquam ultrices neque sem,
+        congue sodales elit tempus sit amet. Pellentesque habitant morbi tristique senectus et netus
+        et malesuada fames ac turpis egestas. Sed dignissim ipsum eget diam rhoncus, ut finibus
+        nulla pretium. Morbi suscipit nibh vel nisl posuere molestie. Maecenas posuere turpis et
+        rutrum consectetur. Morbi venenatis arcu non gravida vulputate. Vivamus auctor tellus
+        ullamcorper ligula vestibulum cursus. Nunc gravida sit amet nisl quis facilisis.
+
+           Praesent ut justo vestibulum, accumsan mi et, feugiat purus. Nullam pulvinar iaculis
+        pharetra. Aliquam pulvinar risus sit amet elit suscipit tincidunt. In hac habitasse platea
+        dictumst. Etiam eget velit ac magna lacinia efficitur. Vestibulum ante ipsum primis in
+        faucibus orci luctus et ultrices posuere cubilia Curae; Cras volutpat tempus sollicitudin.
+        Ut et ante elit.
+
+           Sed ac tortor justo. Fusce sed metus libero. Duis sagittis tortor ac ante sollicitudin,
+        nec efficitur nibh euismod. Donec porttitor cursus quam, in aliquam lorem feugiat ut.
+        Aliquam tempor lacus eu feugiat feugiat. Nunc pulvinar, libero at auctor commodo, metus diam
+        commodo lorem, in feugiat elit ex non ligula. Quisque at vestibulum sapien, nec facilisis
+        neque. Aenean luctus, arcu ut rhoncus luctus, est massa rhoncus mauris, nec luctus urna sem
+        quis massa. Nam elit felis, congue et ligula eget, ultricies tincidunt erat. Vivamus
+        eleifend no dui ac dictum. In nulla justo, pulvinar ut tristique sed, congue et orci.
+
+           Quisque imperdiet mi lectus, ac scelerisque augue posuere ut. Duis non pulvinar ipsum,
+        finibus risus. Donec ullamcorper nisl at sodales lobortis. Mauris neque leo, vestibulum sit
+        amet placerat vel, aliquet vel sapien. Morbi massa tellus, scelerisque quis nisl in, feugiat
+        posuere augue. Aenean congue sem ut ipsum vulputate rhoncus vitae at eros. Maecenas in velit
+        orci pellentesque lobortis ac at felis. Vestibulum odio quam, lacinia dapibus ornare eu,
+        vulputate a eros. Curabitur eleifend ornare tellus, non sollicitudin justo viverra in. Sed
+        sodales neque et lacus semper, in pharetra est consequat. Nunc vehicula volutpat lectus, sit
+        amet scelerisque nisi. Aenean sollicitudin, sem at ultricies efficitur, eros metus
+        nisl, et fringilla felis lacus non orci. Praesent eros libero, finibus in purus id,
+        tempor ipsum. Donec suscipit libero velit. Aliquam quis diam pharetra, cursus ipsum in,
+        gravida metus. Maecenas ultrices ligula a ullamcorper scelerisque.
+
+           Donec tincidunt felis turpis, id venenatis neque convallis in. Proin euismod ligula nec
+        urna vulputate, sed elementum mauris ultrices. Ut efficitur sem vel mi vestibulum placerat.
+        Sed fermentum lacus nec metus dictum, a commodo quam fermentum. Sed vel vulputate magna.
+        Integer convallis nisi sit amet mi lobortis pellentesque. In egestas porttitor elit eu
+        scelerisque. Suspendisse eleifend vel enim quis tincidunt. Sed placerat risus et pretium
+        porttitor. Nam justo mi, cursus eu pellentesque vel, bibendum ut nisl. Nulla condimentum
+        lorem, non sagittis lorem volutpat vitae. Mauris nec libero lorem. Vestibulum lacus ex,
+        vulputate non massa vitae, pellentesque vestibulum dolor.
+
+           Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
+        Suspendisse vitae erat nisl. Vestibulum elit ante, semper et semper sit amet, fringilla
+        sapien. Morbi ac nisi sit amet turpis tincidunt mattis ac eget nisl. Nunc a venenatis quam,
+        facilisis maximus odio. Aliquam erat volutpat. Maecenas leo enim, ornare a magna quis,
+        venenatis ornare nulla. Aliquam venenatis nibh et elit tincidunt, ut egestas lorem finibus.
+        Integer iaculis dolor sed enim blandit vestibulum. Nullam vel libero ultricies, sagittis
+        tortor non, molestie eros.</string>
+</resources>
diff --git a/tests/tests/assist/res/xml/interaction_service.xml b/tests/tests/assist/res/xml/interaction_service.xml
new file mode 100644
index 0000000..c968795
--- /dev/null
+++ b/tests/tests/assist/res/xml/interaction_service.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.
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:sessionService="android.assist.service.MainInteractionSessionService"
+    android:recognitionService="android.assist.service.MainRecognitionService"
+    android:settingsActivity="android.assist.service.SettingsActivity"
+    android:supportsAssist="false" />
diff --git a/tests/tests/assist/service/Android.mk b/tests/tests/assist/service/Android.mk
new file mode 100644
index 0000000..07dc228
--- /dev/null
+++ b/tests/tests/assist/service/Android.mk
@@ -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.
+
+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 := CtsAssistCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsAssistService
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/assist/service/AndroidManifest.xml b/tests/tests/assist/service/AndroidManifest.xml
new file mode 100644
index 0000000..354d771
--- /dev/null
+++ b/tests/tests/assist/service/AndroidManifest.xml
@@ -0,0 +1,69 @@
+<?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.assist.service">
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
+    <application>
+      <uses-library android:name="android.test.runner" />
+      <service android:name=".MainInteractionService"
+              android:label="CTS test voice interaction service"
+              android:permission="android.permission.BIND_VOICE_INTERACTION"
+              android:process=":interactor"
+              android:exported="true">
+          <meta-data android:name="android.voice_interaction"
+                     android:resource="@xml/interaction_service" />
+          <intent-filter>
+              <action android:name="android.service.voice.VoiceInteractionService" />
+          </intent-filter>
+      </service>
+      <activity android:name=".DisableContextActivity" >
+          <intent-filter>
+              <action android:name="android.intent.action.START_TEST_DISABLE_CONTEXT" />
+              <category android:name="android.intent.category.DEFAULT" />
+          </intent-filter>
+      </activity>
+      <activity android:name=".DelayedAssistantActivity"
+                android:label="Delay Assistant Start Activity">
+          <intent-filter>
+              <action android:name="android.intent.action.START_TEST_ASSIST_STRUCTURE" />
+              <action android:name="android.intent.action.START_TEST_LIFECYCLE" />
+              <action android:name="android.intent.action.START_TEST_FLAG_SECURE" />
+              <action android:name="android.intent.action.START_TEST_SCREENSHOT" />
+              <action android:name="android.intent.action.START_TEST_EXTRA_ASSIST" />
+              <action android:name="android.intent.action.START_TEST_TEXTVIEW" />
+              <action android:name="android.intent.action.START_TEST_LARGE_VIEW_HIERARCHY" />
+              <category android:name="android.intent.category.DEFAULT" />
+          </intent-filter>
+      </activity>
+      <service android:name=".MainInteractionSessionService"
+              android:permission="android.permission.BIND_VOICE_INTERACTION"
+              android:process=":session">
+      </service>
+      <service android:name=".MainRecognitionService"
+              android:label="CTS Voice Recognition Service">
+          <intent-filter>
+              <action android:name="android.speech.RecognitionService" />
+              <category android:name="android.intent.category.DEFAULT" />
+          </intent-filter>
+          <meta-data android:name="android.speech" android:resource="@xml/recognition_service" />
+      </service>
+    </application>
+</manifest>
+
diff --git a/tests/tests/assist/service/res/layout/assist_layer.xml b/tests/tests/assist/service/res/layout/assist_layer.xml
new file mode 100644
index 0000000..3677208
--- /dev/null
+++ b/tests/tests/assist/service/res/layout/assist_layer.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/assist_layer"
+    android:layout_width="match_parent"
+    android:background="@color/assist_layer_background"
+    android:layout_height="match_parent">
+    <TextView
+        android:layout_centerInParent="true"
+        android:text="@string/test_assistant_text"
+        android:textColor="@android:color/white"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+</RelativeLayout>
diff --git a/tests/tests/assist/service/res/values/colors.xml b/tests/tests/assist/service/res/values/colors.xml
new file mode 100644
index 0000000..4423140
--- /dev/null
+++ b/tests/tests/assist/service/res/values/colors.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="assist_layer_background">#aa000000</color>
+</resources>
diff --git a/tests/tests/assist/service/res/values/strings.xml b/tests/tests/assist/service/res/values/strings.xml
new file mode 100644
index 0000000..ea959e6
--- /dev/null
+++ b/tests/tests/assist/service/res/values/strings.xml
@@ -0,0 +1,18 @@
+<!--
+  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. -->
+
+<resources>
+    <string name="test_assistant_text">I am an Assistant</string>
+</resources>
diff --git a/tests/tests/assist/service/res/xml/interaction_service.xml b/tests/tests/assist/service/res/xml/interaction_service.xml
new file mode 100644
index 0000000..3ca7161
--- /dev/null
+++ b/tests/tests/assist/service/res/xml/interaction_service.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.
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:sessionService="android.assist.service.MainInteractionSessionService"
+    android:recognitionService="android.assist.service.MainRecognitionService"
+    android:settingsActivity="android.assist.service.SettingsActivity"
+    android:supportsAssist="true" />
diff --git a/tests/tests/assist/service/res/xml/recognition_service.xml b/tests/tests/assist/service/res/xml/recognition_service.xml
new file mode 100644
index 0000000..3f763b1
--- /dev/null
+++ b/tests/tests/assist/service/res/xml/recognition_service.xml
@@ -0,0 +1,18 @@
+<?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.
+-->
+
+<recognition-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:settingsActivity="android.assist.service.SettingsActivity" />
diff --git a/tests/tests/assist/service/src/android/voiceinteraction/service/DelayedAssistantActivity.java b/tests/tests/assist/service/src/android/voiceinteraction/service/DelayedAssistantActivity.java
new file mode 100644
index 0000000..ddf43bd
--- /dev/null
+++ b/tests/tests/assist/service/src/android/voiceinteraction/service/DelayedAssistantActivity.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.assist.service;
+
+import android.app.Activity;
+import android.assist.common.Utils;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.util.Log;
+
+public class DelayedAssistantActivity extends Activity {
+    static final String TAG = "DelayedAssistantActivity";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(this, MainInteractionService.class));
+        intent.putExtra(Utils.EXTRA_REGISTER_RECEIVER, true);
+        intent.putExtra(Utils.TESTCASE_TYPE, getIntent().getStringExtra(Utils.TESTCASE_TYPE));
+        intent.putExtra(Utils.DISPLAY_WIDTH_KEY,
+                getIntent().getIntExtra(Utils.DISPLAY_WIDTH_KEY, 0));
+        intent.putExtra(Utils.DISPLAY_HEIGHT_KEY,
+                getIntent().getIntExtra(Utils.DISPLAY_HEIGHT_KEY, 0));
+        finish();
+        ComponentName serviceName = startService(intent);
+        Log.i(TAG, "Started service: " + serviceName);
+    }
+}
diff --git a/tests/tests/assist/service/src/android/voiceinteraction/service/DisableContextActivity.java b/tests/tests/assist/service/src/android/voiceinteraction/service/DisableContextActivity.java
new file mode 100644
index 0000000..2fd540b
--- /dev/null
+++ b/tests/tests/assist/service/src/android/voiceinteraction/service/DisableContextActivity.java
@@ -0,0 +1,42 @@
+/*
+ * 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.assist.service;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.util.Log;
+
+public class DisableContextActivity extends Activity {
+    static final String TAG = "DisableContextActivity";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void onStart() {
+        super.onStart();
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(this, MainInteractionService.class));
+        Log.i(TAG, "Starting service.");
+        finish();
+        startService(intent);
+    }
+}
diff --git a/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionService.java b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionService.java
new file mode 100644
index 0000000..916d676
--- /dev/null
+++ b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionService.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.assist.service;
+
+import static android.service.voice.VoiceInteractionSession.SHOW_WITH_ASSIST;
+import static android.service.voice.VoiceInteractionSession.SHOW_WITH_SCREENSHOT;
+
+import android.assist.common.Utils;
+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.service.voice.VoiceInteractionService;
+import android.service.voice.VoiceInteractionSession;
+import android.util.Log;
+
+import java.lang.Exception;
+import java.lang.Override;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class MainInteractionService extends VoiceInteractionService {
+    static final String TAG = "MainInteractionService";
+    private Intent mIntent;
+    private boolean mReady = false;
+    private BroadcastReceiver mBroadcastReceiver, mResumeReceiver;
+    private CountDownLatch mResumeLatch;
+
+    @Override
+    public void onReady() {
+        super.onReady();
+        mReady = true;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        Log.i(TAG, "onStartCommand received - intent: " + intent);
+        mIntent = intent;
+        maybeStart();
+        return START_NOT_STICKY;
+    }
+
+    private void maybeStart() {
+        if (mIntent == null || !mReady) {
+            Log.wtf(TAG, "Can't start session because either intent is null or onReady() "
+                    + "has not been called yet. mIntent = " + mIntent + ", mReady = " + mReady);
+        } else {
+            if (isActiveService(this, new ComponentName(this, getClass()))) {
+                if (mIntent.getBooleanExtra(Utils.EXTRA_REGISTER_RECEIVER, false)) {
+                    mResumeLatch = new CountDownLatch(1);
+                    if (mBroadcastReceiver == null) {
+                        mBroadcastReceiver = new MainInteractionServiceBroadcastReceiver();
+                        IntentFilter filter = new IntentFilter();
+                        filter.addAction(Utils.BROADCAST_INTENT_START_ASSIST);
+                        registerReceiver(mBroadcastReceiver, filter);
+                        Log.i(TAG, "Registered receiver to start session later");
+
+                        IntentFilter resumeFilter = new IntentFilter(Utils.APP_3P_HASRESUMED);
+                        mResumeReceiver = new MainServiceAppResumeReceiver();
+                        registerReceiver(mResumeReceiver, resumeFilter);
+                        Log.i(TAG, "Registered receiver for resuming activity");
+                    }
+                    sendBroadcast(new Intent(Utils.ASSIST_RECEIVER_REGISTERED));
+              } else {
+                  Log.i(TAG, "Yay! about to start session");
+                  Bundle bundle = new Bundle();
+                  bundle.putString(Utils.TESTCASE_TYPE,
+                          mIntent.getStringExtra(Utils.TESTCASE_TYPE));
+                  showSession(bundle, VoiceInteractionSession.SHOW_WITH_ASSIST |
+                      VoiceInteractionSession.SHOW_WITH_SCREENSHOT);
+              }
+            } else {
+                Log.wtf(TAG, "**** Not starting MainInteractionService because" +
+                        " it is not set as the current voice interaction service");
+            }
+        }
+    }
+
+    private class MainInteractionServiceBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.i(MainInteractionService.TAG, "Recieved broadcast to start session now.");
+            if (intent.getAction().equals(Utils.BROADCAST_INTENT_START_ASSIST)) {
+                String testCaseName = intent.getStringExtra(Utils.TESTCASE_TYPE);
+                Log.i(MainInteractionService.TAG, "trying to start 3p activity: " + testCaseName);
+                Bundle extras = intent.getExtras();
+                if (extras == null) {
+                    extras = new Bundle();
+                }
+                if (testCaseName.equals(Utils.SCREENSHOT)) {
+                    try {
+                        // extra info to pass along to 3p activity.
+
+                        Intent intent3p = new Intent();
+                        Log.i(TAG, "starting the 3p app again");
+                        intent3p.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                        intent3p.setAction("android.intent.action.TEST_APP_" + testCaseName);
+                        intent3p.setComponent(Utils.getTestAppComponent(testCaseName));
+                        intent3p.putExtras(extras);
+                        startActivity(intent3p);
+                        if (!MainInteractionService.this.mResumeLatch
+                                .await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+                            Log.i(TAG, "waited for 3p activity to resume");
+                        }
+                    } catch (Exception e) {
+                        Log.i(TAG, "failed so reload 3p app: " + e.toString());
+                    }
+                }
+                extras.putString(Utils.TESTCASE_TYPE, mIntent.getStringExtra(Utils.TESTCASE_TYPE));
+                MainInteractionService.this.showSession(
+                        extras, SHOW_WITH_ASSIST | SHOW_WITH_SCREENSHOT);
+            }
+        }
+    }
+
+    private class MainServiceAppResumeReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(Utils.APP_3P_HASRESUMED)) {
+                Log.i(MainInteractionService.TAG,
+                    "3p activity has resumed in this new receiver");
+                if (MainInteractionService.this.mResumeLatch != null) {
+                    MainInteractionService.this.mResumeLatch.countDown();
+                } else {
+                    Log.i(TAG, "mResumeLatch was null");
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onDestroy() {
+        if (mBroadcastReceiver != null) {
+            unregisterReceiver(mBroadcastReceiver);
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSession.java b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSession.java
new file mode 100644
index 0000000..7bca9be
--- /dev/null
+++ b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSession.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 android.assist.service;
+
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.assist.service.R;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+
+import android.graphics.Point;
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Display;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.Display;
+import android.view.ViewTreeObserver;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Date;
+
+import android.assist.common.Utils;
+import android.view.WindowManager;
+
+public class MainInteractionSession extends VoiceInteractionSession {
+    static final String TAG = "MainInteractionSession";
+
+    Intent mStartIntent;
+    Context mContext;
+    Bundle mAssistData = new Bundle();
+
+    private boolean hasReceivedAssistData = false;
+    private boolean hasReceivedScreenshot = false;
+    private int mCurColor;
+    private int mDisplayHeight;
+    private int mDisplayWidth;
+    private Bitmap mScreenshot;
+    private BroadcastReceiver mReceiver;
+    private String mTestName;
+    private View mContentView;
+
+    MainInteractionSession(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                String action = intent.getAction();
+                if (action.equals(Utils.HIDE_SESSION)) {
+                    hide();
+                }
+            }
+        };
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.HIDE_SESSION);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    @Override
+    public void onDestroy() {
+        Log.i(TAG, "onDestroy()");
+        super.onDestroy();
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+    }
+
+    @Override
+    public void onShow(Bundle args, int showFlags) {
+        if ((showFlags & SHOW_WITH_ASSIST) == 0) {
+            return;
+        }
+        mTestName = args.getString(Utils.TESTCASE_TYPE, "");
+        mCurColor = args.getInt(Utils.SCREENSHOT_COLOR_KEY);
+        mDisplayHeight = args.getInt(Utils.DISPLAY_HEIGHT_KEY);
+        mDisplayWidth = args.getInt(Utils.DISPLAY_WIDTH_KEY);
+        super.onShow(args, showFlags);
+        mContentView.getViewTreeObserver().addOnPreDrawListener(
+                new ViewTreeObserver.OnPreDrawListener() {
+                @Override
+                public boolean onPreDraw() {
+                    mContentView.getViewTreeObserver().removeOnPreDrawListener(this);
+                    Display d = mContentView.getDisplay();
+                    Point displayPoint = new Point();
+                    d.getRealSize(displayPoint);
+                    Intent intent = new Intent(Utils.BROADCAST_CONTENT_VIEW_HEIGHT);
+                    intent.putExtra(Utils.EXTRA_CONTENT_VIEW_HEIGHT, mContentView.getHeight());
+                    intent.putExtra(Utils.EXTRA_CONTENT_VIEW_WIDTH, mContentView.getWidth());
+                    intent.putExtra(Utils.EXTRA_DISPLAY_POINT, displayPoint);
+                    mContext.sendBroadcast(intent);
+                    return true;
+                }
+            });
+    }
+
+    @Override
+    public void onHandleAssist(/*@Nullable */Bundle data, /*@Nullable*/ AssistStructure structure,
+        /*@Nullable*/ AssistContent content) {
+        Log.i(TAG, "onHandleAssist");
+        Log.i(TAG,
+                String.format("Bundle: %s, Structure: %s, Content: %s", data, structure, content));
+        super.onHandleAssist(data, structure, content);
+
+        // send to test to verify that this is accurate.
+        mAssistData.putParcelable(Utils.ASSIST_STRUCTURE_KEY, structure);
+        mAssistData.putParcelable(Utils.ASSIST_CONTENT_KEY, content);
+        mAssistData.putBundle(Utils.ASSIST_BUNDLE_KEY, data);
+        hasReceivedAssistData = true;
+        maybeBroadcastResults();
+    }
+
+    @Override
+    public void onHandleScreenshot(/*@Nullable*/ Bitmap screenshot) {
+        Log.i(TAG, String.format("onHandleScreenshot - Screenshot: %s", screenshot));
+        super.onHandleScreenshot(screenshot);
+
+        if (screenshot != null) {
+            mAssistData.putBoolean(Utils.ASSIST_SCREENSHOT_KEY, true);
+
+            if (mTestName.equals(Utils.SCREENSHOT)) {
+                boolean screenshotMatches = compareScreenshot(screenshot, mCurColor);
+                Log.i(TAG, "this is a screenshot test. Matches? " + screenshotMatches);
+                mAssistData.putBoolean(
+                    Utils.COMPARE_SCREENSHOT_KEY, screenshotMatches);
+            }
+        } else {
+            mAssistData.putBoolean(Utils.ASSIST_SCREENSHOT_KEY, false);
+        }
+        hasReceivedScreenshot = true;
+        maybeBroadcastResults();
+    }
+
+    private boolean compareScreenshot(Bitmap screenshot, int color) {
+        Point size = new Point(mDisplayWidth, mDisplayHeight);
+
+        if (screenshot.getWidth() != size.x || screenshot.getHeight() != size.y) {
+            Log.i(TAG, "width  or height didn't match: " + size + " vs " + screenshot.getWidth()
+                    + "," + screenshot.getHeight());
+            return false;
+        }
+        int[] pixels = new int[size.x * size.y];
+        screenshot.getPixels(pixels, 0, size.x, 0, 0, size.x, size.y);
+
+        int expectedColor = 0;
+        int wrongColor = 0;
+        for (int pixel : pixels) {
+            if (pixel == color) {
+                expectedColor += 1;
+            } else {
+                wrongColor += 1;
+            }
+        }
+
+        double colorRatio = (double) expectedColor / (expectedColor + wrongColor);
+        Log.i(TAG, "the ratio is " + colorRatio);
+        if (colorRatio < 0.6) {
+            return false;
+        }
+        return true;
+    }
+
+    private void maybeBroadcastResults() {
+        if (!hasReceivedAssistData) {
+            Log.i(TAG, "waiting for assist data before broadcasting results");
+        } else if (!hasReceivedScreenshot) {
+            Log.i(TAG, "waiting for screenshot before broadcasting results");
+        } else {
+            Intent intent = new Intent(Utils.BROADCAST_ASSIST_DATA_INTENT);
+            intent.putExtras(mAssistData);
+            Log.i(TAG,
+                    "broadcasting: " + intent.toString() + ", Bundle = " + mAssistData.toString());
+            mContext.sendBroadcast(intent);
+
+            hasReceivedAssistData = false;
+            hasReceivedScreenshot = false;
+        }
+    }
+
+    @Override
+    public View onCreateContentView() {
+        LayoutInflater f = getLayoutInflater();
+        if (f == null) {
+            Log.wtf(TAG, "layout inflater was null");
+        }
+        mContentView = f.inflate(R.layout.assist_layer,null);
+        return mContentView;
+    }
+}
diff --git a/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSessionService.java b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSessionService.java
new file mode 100644
index 0000000..ad356a6
--- /dev/null
+++ b/tests/tests/assist/service/src/android/voiceinteraction/service/MainInteractionSessionService.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.assist.service;
+
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.service.voice.VoiceInteractionSessionService;
+
+public class MainInteractionSessionService extends VoiceInteractionSessionService {
+    @Override
+    public VoiceInteractionSession onNewSession(Bundle args) {
+        return new MainInteractionSession(this);
+    }
+}
diff --git a/tests/tests/assist/service/src/android/voiceinteraction/service/MainRecognitionService.java b/tests/tests/assist/service/src/android/voiceinteraction/service/MainRecognitionService.java
new file mode 100644
index 0000000..520f913
--- /dev/null
+++ b/tests/tests/assist/service/src/android/voiceinteraction/service/MainRecognitionService.java
@@ -0,0 +1,55 @@
+/*
+ * 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.assist.service;
+
+import android.content.Intent;
+import android.speech.RecognitionService;
+import android.util.Log;
+
+/**
+ * Stub recognition service needed to be a complete voice interactor.
+ */
+public class MainRecognitionService extends RecognitionService {
+    private static final String TAG = "MainRecognitionService";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, "onCreate");
+    }
+
+    @Override
+    protected void onStartListening(Intent recognizerIntent, Callback listener) {
+        Log.i(TAG, "onStartListening");
+    }
+
+    @Override
+    protected void onCancel(Callback listener) {
+        Log.i(TAG, "onCancel");
+    }
+
+    @Override
+    protected void onStopListening(Callback listener) {
+        Log.i(TAG, "onStopListening");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        Log.i(TAG, "onDestroy");
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.java
new file mode 100644
index 0000000..c21bc9c
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/AssistStructureTest.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 android.assist.cts;
+
+import android.assist.common.Utils;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ *  Test that the AssistStructure returned is properly formatted.
+ */
+
+public class AssistStructureTest extends AssistTestBase {
+    private static final String TAG = "AssistStructureTest";
+    private static final String TEST_CASE_TYPE = Utils.ASSIST_STRUCTURE;
+
+    private BroadcastReceiver mReceiver;
+    private CountDownLatch mHasResumedLatch = new CountDownLatch(1);
+    private CountDownLatch mReadyLatch = new CountDownLatch(1);
+
+    public AssistStructureTest() {
+        super();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setUpAndRegisterReceiver();
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    private void setUpAndRegisterReceiver() {
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new AssistStructureTestBroadcastReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.APP_3P_HASRESUMED);
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    private void waitForOnResume() throws Exception {
+        Log.i(TAG, "waiting for onResume() before continuing");
+        if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+        }
+    }
+
+    public void testAssistStructure() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        mTestActivity.start3pApp(TEST_CASE_TYPE);
+        mTestActivity.startTest(TEST_CASE_TYPE);
+        waitForAssistantToBeReady(mReadyLatch);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        verifyAssistDataNullness(false, false, false, false);
+
+        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE),
+                false /*FLAG_SECURE set*/);
+    }
+
+    private class AssistStructureTestBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Utils.APP_3P_HASRESUMED)) {
+                if (mHasResumedLatch != null) {
+                    mHasResumedLatch.countDown();
+                }
+            } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) {
+                if (mReadyLatch != null) {
+                    mReadyLatch.countDown();
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/AssistTestBase.java b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
new file mode 100644
index 0000000..29b35c5
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/AssistTestBase.java
@@ -0,0 +1,485 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.assist.cts;
+
+import android.assist.cts.TestStartActivity;
+import android.assist.common.Utils;
+
+import android.app.ActivityManager;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.app.assist.AssistStructure.ViewNode;
+import android.app.assist.AssistStructure.WindowNode;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.cts.util.SystemUtil;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Color;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.view.Display;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.webkit.WebView;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import java.lang.Math;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class AssistTestBase extends ActivityInstrumentationTestCase2<TestStartActivity> {
+    private static final String TAG = "AssistTestBase";
+
+    protected ActivityManager mActivityManager;
+    protected TestStartActivity mTestActivity;
+    protected AssistContent mAssistContent;
+    protected AssistStructure mAssistStructure;
+    protected boolean mScreenshot;
+    protected Bitmap mAppScreenshot;
+    protected BroadcastReceiver mReceiver;
+    protected Bundle mAssistBundle;
+    protected Context mContext;
+    protected CountDownLatch mLatch, mScreenshotLatch, mHasResumedLatch;
+    protected boolean mScreenshotMatches;
+    private Point mDisplaySize;
+    private String mTestName;
+    private View mView;
+
+    public AssistTestBase() {
+        super(TestStartActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getTargetContext();
+        SystemUtil.runShellCommand(getInstrumentation(),
+                "settings put secure assist_structure_enabled 1");
+        SystemUtil.runShellCommand(getInstrumentation(),
+                "settings put secure assist_screenshot_enabled 1");
+        logContextAndScreenshotSetting();
+
+        // reset old values
+        mScreenshotMatches = false;
+        mScreenshot = false;
+        mAssistStructure = null;
+        mAssistContent = null;
+        mAssistBundle = null;
+
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new TestResultsReceiver();
+        mContext.registerReceiver(mReceiver,
+            new IntentFilter(Utils.BROADCAST_ASSIST_DATA_INTENT));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mTestActivity.finish();
+        mContext.sendBroadcast(new Intent(Utils.HIDE_SESSION));
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Starts the shim service activity
+     */
+    protected void startTestActivity(String testName) {
+        Intent intent = new Intent();
+        mTestName = testName;
+        intent.setAction("android.intent.action.TEST_START_ACTIVITY_" + testName);
+        intent.setComponent(new ComponentName(getInstrumentation().getContext(),
+                TestStartActivity.class));
+        intent.putExtra(Utils.TESTCASE_TYPE, testName);
+        setActivityIntent(intent);
+        mTestActivity = getActivity();
+        mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
+    }
+
+    /**
+     * Called when waiting for Assistant's Broadcast Receiver to be setup
+     */
+    public void waitForAssistantToBeReady(CountDownLatch latch) throws Exception {
+        Log.i(TAG, "waiting for assistant to be ready before continuing");
+        if (!latch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Assistant was not ready before timeout of: " + Utils.TIMEOUT_MS + "msec");
+        }
+    }
+
+    /**
+     * Send broadcast to MainInteractionService to start a session
+     */
+    protected void startSession() {
+        startSession(mTestName, new Bundle());
+    }
+
+    protected void startSession(String testName, Bundle extras) {
+        Intent intent = new Intent(Utils.BROADCAST_INTENT_START_ASSIST);
+        Log.i(TAG, "passed in class test name is: " + testName);
+        intent.putExtra(Utils.TESTCASE_TYPE, testName);
+        addDimensionsToIntent(intent);
+        intent.putExtras(extras);
+        mContext.sendBroadcast(intent);
+    }
+
+    /**
+     * Calculate display dimensions (including navbar) to pass along in the given intent.
+     */
+    private void addDimensionsToIntent(Intent intent) {
+        if (mDisplaySize == null) {
+            Display display = mTestActivity.getWindowManager().getDefaultDisplay();
+            mDisplaySize = new Point();
+            display.getRealSize(mDisplaySize);
+        }
+        intent.putExtra(Utils.DISPLAY_WIDTH_KEY, mDisplaySize.x);
+        intent.putExtra(Utils.DISPLAY_HEIGHT_KEY, mDisplaySize.y);
+    }
+
+    /**
+     * Called after startTestActivity. Includes check for receiving context.
+     */
+    protected boolean waitForBroadcast() throws Exception {
+        mTestActivity.start3pApp(mTestName);
+        mTestActivity.startTest(mTestName);
+        return waitForContext();
+    }
+
+    protected boolean waitForContext() throws Exception {
+        mLatch = new CountDownLatch(1);
+
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new TestResultsReceiver();
+        mContext.registerReceiver(mReceiver,
+                new IntentFilter(Utils.BROADCAST_ASSIST_DATA_INTENT));
+
+        if (!mLatch.await(Utils.getAssistDataTimeout(mTestName), TimeUnit.MILLISECONDS)) {
+            fail("Fail to receive broadcast in " + Utils.getAssistDataTimeout(mTestName) + "msec");
+        }
+        Log.i(TAG, "Received broadcast with all information.");
+        return true;
+    }
+
+    /**
+     * Checks that the nullness of values are what we expect.
+     *
+     * @param isBundleNull True if assistBundle should be null.
+     * @param isStructureNull True if assistStructure should be null.
+     * @param isContentNull True if assistContent should be null.
+     * @param isScreenshotNull True if screenshot should be null.
+     */
+    protected void verifyAssistDataNullness(boolean isBundleNull, boolean isStructureNull,
+            boolean isContentNull, boolean isScreenshotNull) {
+
+        if ((mAssistContent == null) != isContentNull) {
+            fail(String.format("Should %s have been null - AssistContent: %s",
+                    isContentNull ? "" : "not", mAssistContent));
+        }
+
+        if ((mAssistStructure == null) != isStructureNull) {
+            fail(String.format("Should %s have been null - AssistStructure: %s",
+                    isStructureNull ? "" : "not", mAssistStructure));
+        }
+
+        if ((mAssistBundle == null) != isBundleNull) {
+            fail(String.format("Should %s have been null - AssistBundle: %s",
+                    isBundleNull ? "" : "not", mAssistBundle));
+        }
+
+        if (mScreenshot == isScreenshotNull) {
+            fail(String.format("Should %s have been null - Screenshot: %s",
+                    isScreenshotNull ? "":"not", mScreenshot));
+        }
+    }
+
+    /**
+     * Sends a broadcast with the specified scroll positions to the test app.
+     */
+    protected void scrollTestApp(int scrollX, int scrollY, boolean scrollTextView,
+            boolean scrollScrollView) {
+        mTestActivity.scrollText(scrollX, scrollY, scrollTextView, scrollScrollView);
+        Intent intent = null;
+        if (scrollTextView) {
+            intent = new Intent(Utils.SCROLL_TEXTVIEW_ACTION);
+        } else if (scrollScrollView) {
+            intent = new Intent(Utils.SCROLL_SCROLLVIEW_ACTION);
+        }
+        intent.putExtra(Utils.SCROLL_X_POSITION, scrollX);
+        intent.putExtra(Utils.SCROLL_Y_POSITION, scrollY);
+        mContext.sendBroadcast(intent);
+    }
+
+    /**
+     * Verifies the view hierarchy of the backgroundApp matches the assist structure.
+     *
+     * @param backgroundApp ComponentName of app the assistant is invoked upon
+     * @param isSecureWindow Denotes whether the activity has FLAG_SECURE set
+     */
+    protected void verifyAssistStructure(ComponentName backgroundApp, boolean isSecureWindow) {
+        // Check component name matches
+        assertEquals(backgroundApp.flattenToString(),
+                mAssistStructure.getActivityComponent().flattenToString());
+
+        Log.i(TAG, "Traversing down structure for: " + backgroundApp.flattenToString());
+        mView = mTestActivity.findViewById(android.R.id.content).getRootView();
+        verifyHierarchy(mAssistStructure, isSecureWindow);
+    }
+
+    protected void logContextAndScreenshotSetting() {
+        Log.i(TAG, "Context is: " + Settings.Secure.getString(
+                mContext.getContentResolver(), "assist_structure_enabled"));
+        Log.i(TAG, "Screenshot is: " + Settings.Secure.getString(
+                mContext.getContentResolver(), "assist_screenshot_enabled"));
+    }
+
+    /**
+     * Recursively traverse and compare properties in the View hierarchy with the Assist Structure.
+     */
+    public void verifyHierarchy(AssistStructure structure, boolean isSecureWindow) {
+        Log.i(TAG, "verifyHierarchy");
+        Window mWindow = mTestActivity.getWindow();
+
+        int numWindows = structure.getWindowNodeCount();
+        // TODO: multiple windows?
+        assertEquals("Number of windows don't match", 1, numWindows);
+
+        for (int i = 0; i < numWindows; i++) {
+            AssistStructure.WindowNode windowNode = structure.getWindowNodeAt(i);
+            Log.i(TAG, "Title: " + windowNode.getTitle());
+            // verify top level window bounds are as big as the screen and pinned to 0,0
+            assertEquals("Window left position wrong: was " + windowNode.getLeft(),
+                    windowNode.getLeft(), 0);
+            assertEquals("Window top position wrong: was " + windowNode.getTop(),
+                    windowNode.getTop(), 0);
+
+            traverseViewAndStructure(
+                    mView,
+                    windowNode.getRootViewNode(),
+                    isSecureWindow);
+        }
+    }
+
+    private void traverseViewAndStructure(View parentView, ViewNode parentNode,
+            boolean isSecureWindow) {
+        ViewGroup parentGroup;
+
+        if (parentView == null && parentNode == null) {
+            Log.i(TAG, "Views are null, done traversing this branch.");
+            return;
+        } else if (parentNode == null || parentView == null) {
+            fail(String.format("Views don't match. View: %s, Node: %s", parentView, parentNode));
+        }
+
+        // Debugging
+        Log.i(TAG, "parentView is of type: " + parentView.getClass().getName());
+        if (parentView instanceof ViewGroup) {
+            for (int childInt = 0; childInt < ((ViewGroup) parentView).getChildCount();
+                    childInt++) {
+                Log.i(TAG,
+                        "viewchild" + childInt + " is of type: "
+                        + ((ViewGroup) parentView).getChildAt(childInt).getClass().getName());
+            }
+        }
+        String parentViewId = null;
+        if (parentView.getId() > 0) {
+            parentViewId = mTestActivity.getResources().getResourceEntryName(parentView.getId());
+            Log.i(TAG, "View ID: " + parentViewId);
+        }
+
+        Log.i(TAG, "parentNode is of type: " + parentNode.getClassName());
+        for (int nodeInt = 0; nodeInt < parentNode.getChildCount(); nodeInt++) {
+            Log.i(TAG,
+                    "nodechild" + nodeInt + " is of type: "
+                    + parentNode.getChildAt(nodeInt).getClassName());
+        }
+        Log.i(TAG, "Node ID: " + parentNode.getIdEntry());
+
+        assertEquals("IDs do not match", parentViewId, parentNode.getIdEntry());
+
+        int numViewChildren = 0;
+        int numNodeChildren = 0;
+        if (parentView instanceof ViewGroup) {
+            numViewChildren = ((ViewGroup) parentView).getChildCount();
+        }
+        numNodeChildren = parentNode.getChildCount();
+
+        if (isSecureWindow) {
+            assertTrue("ViewNode property isAssistBlocked is false", parentNode.isAssistBlocked());
+            assertEquals("Secure window should only traverse root node.", 0, numNodeChildren);
+            isSecureWindow = false;
+        } else if (parentNode.getClassName().equals("android.webkit.WebView")) {
+            // WebView will also appear to have no children while the node does, traverse node
+            assertTrue("AssistStructure returned a WebView where the view wasn't one",
+                    parentView instanceof WebView);
+
+            boolean textInWebView = false;
+
+            for (int i = numNodeChildren - 1; i >= 0; i--) {
+               textInWebView |= traverseWebViewForText(parentNode.getChildAt(i));
+            }
+            assertTrue("Did not find expected strings inside WebView", textInWebView);
+        } else {
+            assertEquals("Number of children did not match.", numViewChildren, numNodeChildren);
+
+            verifyViewProperties(parentView, parentNode);
+
+            if (parentView instanceof ViewGroup) {
+                parentGroup = (ViewGroup) parentView;
+
+                // TODO: set a max recursion level
+                for (int i = numNodeChildren - 1; i >= 0; i--) {
+                    View childView = parentGroup.getChildAt(i);
+                    ViewNode childNode = parentNode.getChildAt(i);
+
+                    // if isSecureWindow, should not have reached this point.
+                    assertFalse(isSecureWindow);
+                    traverseViewAndStructure(childView, childNode, isSecureWindow);
+                }
+            }
+        }
+    }
+
+    /** 
+     * Return true if the expected strings are found in the WebView, else fail.
+     */
+    private boolean traverseWebViewForText(ViewNode parentNode) {
+        boolean textFound = false;
+        if (parentNode.getText() != null 
+                && parentNode.getText().toString().equals(Utils.WEBVIEW_HTML_GREETING)) {
+            return true;
+        }
+        for (int i = parentNode.getChildCount() - 1; i >= 0; i--) {
+            textFound |= traverseWebViewForText(parentNode.getChildAt(i));
+        }
+        return textFound;
+    }
+
+    /**
+     * Compare view properties of the view hierarchy with that reported in the assist structure.
+     */
+    private void verifyViewProperties(View parentView, ViewNode parentNode) {
+        assertEquals("Left positions do not match.", parentView.getLeft(), parentNode.getLeft());
+        assertEquals("Top positions do not match.", parentView.getTop(), parentNode.getTop());
+
+        int viewId = parentView.getId();
+
+        if (viewId > 0) {
+            if (parentNode.getIdEntry() != null) {
+                assertEquals("View IDs do not match.",
+                        mTestActivity.getResources().getResourceEntryName(viewId),
+                        parentNode.getIdEntry());
+            }
+        } else {
+            assertNull("View Node should not have an ID.", parentNode.getIdEntry());
+        }
+
+        Log.i(TAG, "parent text: " + parentNode.getText());
+        if (parentView instanceof TextView) {
+            Log.i(TAG, "view text: " + ((TextView) parentView).getText());
+        }
+
+
+        assertEquals("Scroll X does not match.", parentView.getScrollX(), parentNode.getScrollX());
+        assertEquals("Scroll Y does not match.", parentView.getScrollY(), parentNode.getScrollY());
+        assertEquals("Heights do not match.", parentView.getHeight(), parentNode.getHeight());
+        assertEquals("Widths do not match.", parentView.getWidth(), parentNode.getWidth());
+
+        if (parentView instanceof TextView) {
+            if (parentView instanceof EditText) {
+                assertEquals("Text selection start does not match",
+                    ((EditText)parentView).getSelectionStart(), parentNode.getTextSelectionStart());
+                assertEquals("Text selection end does not match",
+                        ((EditText)parentView).getSelectionEnd(), parentNode.getTextSelectionEnd());
+            }
+            TextView textView = (TextView) parentView;
+            assertEquals(textView.getTextSize(), parentNode.getTextSize());
+            String viewString = textView.getText().toString();
+            String nodeString = parentNode.getText().toString();
+
+            if (parentNode.getScrollX() == 0 && parentNode.getScrollY() == 0) {
+                Log.i(TAG, "Verifying text within TextView at the beginning");
+                Log.i(TAG, "view string: " + viewString);
+                Log.i(TAG, "node string: " + nodeString);
+                assertTrue("String length is unexpected: original string - " + viewString.length() +
+                                ", string in AssistData - " + nodeString.length(),
+                        viewString.length() >= nodeString.length());
+                assertTrue("Expected a longer string to be shown. expected: "
+                                + Math.min(viewString.length(), 30) + " was: " + nodeString
+                                .length(),
+                        nodeString.length() >= Math.min(viewString.length(), 30));
+                for (int x = 0; x < parentNode.getText().length(); x++) {
+                    assertEquals("Char not equal at index: " + x,
+                            ((TextView) parentView).getText().toString().charAt(x),
+                            parentNode.getText().charAt(x));
+                }
+            } else if (parentNode.getScrollX() == parentView.getWidth()) {
+
+            }
+        } else {
+            assertNull(parentNode.getText());
+        }
+    }
+
+    class TestResultsReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equalsIgnoreCase(Utils.BROADCAST_ASSIST_DATA_INTENT)) {
+                Log.i(TAG, "Received broadcast with assist data.");
+                Bundle assistData = intent.getExtras();
+                AssistTestBase.this.mAssistBundle = assistData.getBundle(Utils.ASSIST_BUNDLE_KEY);
+                AssistTestBase.this.mAssistStructure = assistData.getParcelable(
+                        Utils.ASSIST_STRUCTURE_KEY);
+                AssistTestBase.this.mAssistContent = assistData.getParcelable(
+                        Utils.ASSIST_CONTENT_KEY);
+
+                AssistTestBase.this.mScreenshot =
+                        assistData.getBoolean(Utils.ASSIST_SCREENSHOT_KEY, false);
+
+                AssistTestBase.this.mScreenshotMatches = assistData.getBoolean(
+                        Utils.COMPARE_SCREENSHOT_KEY, false);
+
+                if (mLatch != null) {
+                    Log.i(AssistTestBase.TAG, "counting down latch. received assist data.");
+                    mLatch.countDown();
+                }
+            } else if (intent.getAction().equals(Utils.APP_3P_HASRESUMED)) {
+                if (mHasResumedLatch != null) {
+                    mHasResumedLatch.countDown();
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java b/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
new file mode 100644
index 0000000..c6ac3a6
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/AssistantContentViewTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.assist.cts;
+
+import android.assist.cts.TestStartActivity;
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.cts.util.SystemUtil;
+import android.graphics.Point;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.lang.Override;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/** Test verifying the Content View of the Assistant */
+public class AssistantContentViewTest extends AssistTestBase {
+    private static final String TAG = "ContentViewTest";
+    private BroadcastReceiver mReceiver;
+    private CountDownLatch mContentViewLatch, mReadyLatch;
+    private Intent mIntent;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mContentViewLatch = new CountDownLatch(1);
+        mReadyLatch = new CountDownLatch(1);
+        setUpAndRegisterReceiver();
+        startTestActivity(Utils.VERIFY_CONTENT_VIEW);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    private void setUpAndRegisterReceiver() {
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new AssistantContentViewReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.BROADCAST_CONTENT_VIEW_HEIGHT);
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        mContext.registerReceiver(mReceiver, filter);
+
+    }
+
+    private void waitForContentView() throws Exception {
+        Log.i(TAG, "waiting for the Assistant's Content View  before continuing");
+        if (!mContentViewLatch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("failed to receive content view in " + Utils.TIMEOUT_MS + "msec");
+        }
+    }
+
+    public void testAssistantContentViewDimens() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+          Log.d(TAG, "Not running assist tests on low-RAM device.");
+          return;
+        }
+        mTestActivity.startTest(Utils.VERIFY_CONTENT_VIEW);
+        waitForAssistantToBeReady(mReadyLatch);
+        startSession();
+        waitForContentView();
+        int height = mIntent.getIntExtra(Utils.EXTRA_CONTENT_VIEW_HEIGHT, 0);
+        int width = mIntent.getIntExtra(Utils.EXTRA_CONTENT_VIEW_WIDTH, 0);
+        Point displayPoint = (Point) mIntent.getParcelableExtra(Utils.EXTRA_DISPLAY_POINT);
+        assertEquals(displayPoint.y, height);
+        assertEquals(displayPoint.x, width);
+    }
+
+    private class AssistantContentViewReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Utils.BROADCAST_CONTENT_VIEW_HEIGHT)) {
+                mIntent = intent;
+                if (mContentViewLatch != null) {
+                    mContentViewLatch.countDown();
+                }
+            } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) {
+                if (mReadyLatch != null) {
+                    mReadyLatch.countDown();
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/DisableContextTest.java b/tests/tests/assist/src/android/assist/cts/DisableContextTest.java
new file mode 100644
index 0000000..ea4cd3d
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/DisableContextTest.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 android.assist.cts;
+
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.cts.util.SystemUtil;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.lang.Override;
+import java.util.concurrent.CountDownLatch;
+
+/** Test we receive proper assist data when context is disabled or enabled */
+
+public class DisableContextTest extends AssistTestBase {
+    static final String TAG = "DisableContextTest";
+
+    private static final String TEST_CASE_TYPE = Utils.DISABLE_CONTEXT;
+
+    public DisableContextTest() {
+        super();
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        SystemUtil.runShellCommand(getInstrumentation(),
+                "settings put secure assist_structure_enabled 1");
+        SystemUtil.runShellCommand(getInstrumentation(),
+            "settings put secure assist_screenshot_enabled 1");
+        logContextAndScreenshotSetting();
+        super.tearDown();
+    }
+
+    public void testContextAndScreenshotOff() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        // Both settings off
+        Log.i(TAG, "DisableContext: Screenshot OFF, Context OFF");
+        SystemUtil.runShellCommand(getInstrumentation(),
+            "settings put secure assist_structure_enabled 0");
+        SystemUtil.runShellCommand(getInstrumentation(),
+            "settings put secure assist_screenshot_enabled 0");
+        waitForBroadcast();
+
+        logContextAndScreenshotSetting();
+
+        verifyAssistDataNullness(true, true, true, true);
+
+        // Screenshot off, context on
+        Log.i(TAG, "DisableContext: Screenshot OFF, Context ON");
+        SystemUtil.runShellCommand(getInstrumentation(),
+            "settings put secure assist_structure_enabled 1");
+        SystemUtil.runShellCommand(getInstrumentation(),
+            "settings put secure assist_screenshot_enabled 0");
+        waitForBroadcast();
+
+        logContextAndScreenshotSetting();
+
+        verifyAssistDataNullness(false, false, false, true);
+
+        // Context off, screenshot on
+        Log.i(TAG, "DisableContext: Screenshot ON, Context OFF");
+        SystemUtil.runShellCommand(getInstrumentation(),
+            "settings put secure assist_structure_enabled 0");
+        SystemUtil.runShellCommand(getInstrumentation(),
+            "settings put secure assist_screenshot_enabled 1");
+        waitForBroadcast();
+
+        logContextAndScreenshotSetting();
+
+        verifyAssistDataNullness(true, true, true, true);
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
new file mode 100644
index 0000000..1154179
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/ExtraAssistDataTest.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.assist.cts;
+
+import android.assist.common.Utils;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class ExtraAssistDataTest extends AssistTestBase {
+    private static final String TAG = "ExtraAssistDataTest";
+    private static final String TEST_CASE_TYPE = Utils.EXTRA_ASSIST;
+
+    private BroadcastReceiver mReceiver;
+    private CountDownLatch mHasResumedLatch = new CountDownLatch(1);
+    private CountDownLatch mReadyLatch = new CountDownLatch(1);
+
+    public ExtraAssistDataTest() {
+        super();
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        setUpAndRegisterReceiver();
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    private void setUpAndRegisterReceiver() {
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new ExtraAssistDataReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.APP_3P_HASRESUMED);
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    public void testAssistContentAndAssistData() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        mTestActivity.startTest(TEST_CASE_TYPE);
+        waitForAssistantToBeReady(mReadyLatch);
+        mTestActivity.start3pApp(TEST_CASE_TYPE);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        verifyAssistDataNullness(false, false, false, false);
+
+        Log.i(TAG, "assist bundle is: " + Utils.toBundleString(mAssistBundle));
+
+        // tests that the assist content's structured data is the expected
+        assertEquals("AssistContent structured data did not match data in onProvideAssistContent",
+                Utils.getStructuredJSON(), mAssistContent.getStructuredData());
+        // tests the assist data. EXTRA_ASSIST_CONTEXT is what's expected.
+        Bundle extraExpectedBundle = Utils.getExtraAssistBundle();
+        Bundle extraAssistBundle = mAssistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
+        for (String key : extraExpectedBundle.keySet()) {
+            assertTrue("Assist bundle does not contain expected extra context key: " + key,
+                    extraAssistBundle.containsKey(key));
+            assertEquals("Extra assist context bundle values do not match for key: " + key,
+                    extraExpectedBundle.get(key), extraAssistBundle.get(key));
+        }
+    }
+
+    private void waitForOnResume() throws Exception {
+        Log.i(TAG, "waiting for onResume() before continuing");
+        if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+        }
+    }
+
+    private class ExtraAssistDataReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Utils.APP_3P_HASRESUMED)) {
+                if (mHasResumedLatch != null) {
+                    mHasResumedLatch.countDown();
+                }
+            } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) {
+                if (mReadyLatch != null) {
+                    mReadyLatch.countDown();
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.java
new file mode 100644
index 0000000..fc7c8fb3
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/FlagSecureTest.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.assist.cts;
+
+import android.assist.common.Utils;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test we receive proper assist data (root assistStructure with no children) when the assistant is
+ * invoked on an app with FLAG_SECURE set.
+ */
+public class FlagSecureTest extends AssistTestBase {
+    static final String TAG = "FlagSecureTest";
+
+    private static final String TEST_CASE_TYPE = Utils.FLAG_SECURE;
+
+    private BroadcastReceiver mReceiver;
+    private CountDownLatch mHasResumedLatch = new CountDownLatch(1);
+    private CountDownLatch mReadyLatch = new CountDownLatch(1);
+    public FlagSecureTest() {
+        super();
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        setUpAndRegisterReceiver();
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    private void setUpAndRegisterReceiver() {
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new FlagSecureTestBroadcastReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.FLAG_SECURE_HASRESUMED);
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    private void waitForOnResume() throws Exception {
+        Log.i(TAG, "waiting for onResume() before continuing");
+        if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+        }
+    }
+
+    public void testSecureActivity() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        mTestActivity.startTest(TEST_CASE_TYPE);
+        waitForAssistantToBeReady(mReadyLatch);
+        mTestActivity.start3pApp(TEST_CASE_TYPE);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        verifyAssistDataNullness(false, false, false, false);
+        // verify that we have only the root window and not its children.
+        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE), true);
+    }
+
+    private class FlagSecureTestBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Utils.FLAG_SECURE_HASRESUMED)) {
+                if (mHasResumedLatch != null) {
+                    mHasResumedLatch.countDown();
+                }
+            } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) {
+                if (mReadyLatch != null) {
+                    mReadyLatch.countDown();
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java b/tests/tests/assist/src/android/assist/cts/FocusChangeTest.java
new file mode 100644
index 0000000..621361e
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/FocusChangeTest.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.assist.cts;
+
+import android.assist.cts.TestStartActivity;
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.lang.Override;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/** Test that triggering the Assistant causes the underlying Activity to lose focus **/
+
+public class FocusChangeTest extends AssistTestBase {
+    private static final String TAG = "FocusChangeTest";
+    private static final String TEST_CASE_TYPE = Utils.FOCUS_CHANGE;
+
+    private BroadcastReceiver mReceiver;
+    private CountDownLatch mHasGainedFocusLatch = new CountDownLatch(1);
+    private CountDownLatch mHasLostFocusLatch = new CountDownLatch(1);
+    private CountDownLatch mReadyLatch = new CountDownLatch(1);
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        setUpAndRegisterReceiver();
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    private void setUpAndRegisterReceiver() {
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new FocusChangeTestReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.GAINED_FOCUS);
+        filter.addAction(Utils.LOST_FOCUS);
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    private void waitToGainFocus() throws Exception {
+        Log.i(TAG, "Waiting for the underlying activity to gain focus before continuing.");
+        if (!mHasGainedFocusLatch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Activity failed to gain focus in " + Utils.TIMEOUT_MS + "msec.");
+        }
+    }
+
+    private void waitToLoseFocus() throws Exception {
+        Log.i(TAG, "Waiting for the underlying activity to lose focus.");
+        if (!mHasLostFocusLatch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Activity maintained focus despite the Assistant Firing"
+                 + Utils.TIMEOUT_MS + "msec.");
+        }
+    }
+
+    public void testLayerCausesUnderlyingActivityToLoseFocus() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        mTestActivity.startTest(Utils.FOCUS_CHANGE);
+        waitForAssistantToBeReady(mReadyLatch);
+        mTestActivity.start3pApp(Utils.FOCUS_CHANGE);
+        waitToGainFocus();
+        startSession();
+        waitToLoseFocus();
+    }
+
+    private class FocusChangeTestReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Utils.GAINED_FOCUS) && mHasGainedFocusLatch != null) {
+                mHasGainedFocusLatch.countDown();
+            } else if (action.equals(Utils.LOST_FOCUS) && mHasLostFocusLatch != null) {
+                mHasLostFocusLatch.countDown();
+            } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) {
+                if (mReadyLatch != null) {
+                    mReadyLatch.countDown();
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java b/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java
new file mode 100644
index 0000000..25f36b7
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/LargeViewHierarchyTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.assist.cts;
+
+import android.assist.common.Utils;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ *  Test that the AssistStructure returned is properly formatted.
+ */
+
+public class LargeViewHierarchyTest extends AssistTestBase {
+    private static final String TAG = "LargeViewHierarchyTest";
+    private static final String TEST_CASE_TYPE = Utils.LARGE_VIEW_HIERARCHY;
+
+    private BroadcastReceiver mReceiver;
+    private CountDownLatch mHasResumedLatch = new CountDownLatch(1);
+    private CountDownLatch mReadyLatch = new CountDownLatch(1);
+
+    public LargeViewHierarchyTest() {
+        super();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setUpAndRegisterReceiver();
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    private void setUpAndRegisterReceiver() {
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new LargeViewTestBroadcastReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.APP_3P_HASRESUMED);
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    private void waitForOnResume() throws Exception {
+        Log.i(TAG, "waiting for onResume() before continuing");
+        if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+        }
+    }
+
+    public void testTextView() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        mTestActivity.start3pApp(TEST_CASE_TYPE);
+        mTestActivity.startTest(TEST_CASE_TYPE);
+        waitForAssistantToBeReady(mReadyLatch);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        verifyAssistDataNullness(false, false, false, false);
+
+        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE),
+                false /*FLAG_SECURE set*/);
+    }
+
+    private class LargeViewTestBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Utils.APP_3P_HASRESUMED) && mHasResumedLatch != null) {
+                mHasResumedLatch.countDown();
+            } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED) && mReadyLatch != null) {
+                mReadyLatch.countDown();
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/LifecycleTest.java b/tests/tests/assist/src/android/assist/cts/LifecycleTest.java
new file mode 100644
index 0000000..3ed26d1
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/LifecycleTest.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 android.assist.cts;
+
+import android.assist.cts.TestStartActivity;
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.app.assist.AssistContent;
+import android.app.assist.AssistStructure;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.cts.util.SystemUtil;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import java.lang.Override;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/** Test we receive proper assist data when context is disabled or enabled */
+
+public class LifecycleTest extends AssistTestBase {
+    private static final String TAG = "LifecycleTest";
+    private static final String action_hasResumed = Utils.LIFECYCLE_HASRESUMED;
+    private static final String action_onPause = Utils.LIFECYCLE_ONPAUSE;
+    private static final String action_onStop = Utils.LIFECYCLE_ONSTOP;
+    private static final String action_onDestroy = Utils.LIFECYCLE_ONDESTROY;
+
+    private static final String TEST_CASE_TYPE = Utils.LIFECYCLE;
+
+    private BroadcastReceiver mLifecycleTestBroadcastReceiver;
+    private CountDownLatch mHasResumedLatch = new CountDownLatch(1);
+    private CountDownLatch mActivityLifecycleLatch = new CountDownLatch(1);
+    private CountDownLatch mReadyLatch = new CountDownLatch(1);
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        setUpAndRegisterReceiver();
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (mLifecycleTestBroadcastReceiver != null) {
+            mContext.unregisterReceiver(mLifecycleTestBroadcastReceiver);
+            mLifecycleTestBroadcastReceiver = null;
+        }
+    }
+
+    private void setUpAndRegisterReceiver() {
+        if (mLifecycleTestBroadcastReceiver != null) {
+            mContext.unregisterReceiver(mLifecycleTestBroadcastReceiver);
+        }
+        mLifecycleTestBroadcastReceiver = new LifecycleTestReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(action_hasResumed);
+        filter.addAction(action_onPause);
+        filter.addAction(action_onStop);
+        filter.addAction(action_onDestroy);
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        mContext.registerReceiver(mLifecycleTestBroadcastReceiver, filter);
+
+    }
+
+    private void waitForOnResume() throws Exception {
+        Log.i(TAG, "waiting for onResume() before continuing");
+        if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+        }
+    }
+
+    private void waitAndSeeIfLifecycleMethodsAreTriggered() throws Exception {
+        if (mActivityLifecycleLatch.await(Utils.TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("One or more lifecycle methods were called after triggering assist");
+        }
+    }
+
+    public void testLayerDoesNotTriggerLifecycleMethods() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        mTestActivity.startTest(Utils.LIFECYCLE);
+        waitForAssistantToBeReady(mReadyLatch);
+        mTestActivity.start3pApp(Utils.LIFECYCLE);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        waitAndSeeIfLifecycleMethodsAreTriggered();
+    }
+
+    private class LifecycleTestReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(action_hasResumed) && mHasResumedLatch != null) {
+                mHasResumedLatch.countDown();
+            } else if (action.equals(action_onPause) && mActivityLifecycleLatch != null) {
+                mActivityLifecycleLatch.countDown();
+            } else if (action.equals(action_onStop) && mActivityLifecycleLatch != null) {
+                mActivityLifecycleLatch.countDown();
+            } else if (action.equals(action_onDestroy) && mActivityLifecycleLatch != null) {
+                mActivityLifecycleLatch.countDown();
+            } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) {
+                if (mReadyLatch != null) {
+                    mReadyLatch.countDown();
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java b/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
new file mode 100644
index 0000000..b84e334
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/ScreenshotTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.assist.cts;
+
+import android.assist.common.Utils;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.database.DatabaseUtils;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.util.Log;
+
+import junit.framework.Test;
+
+import java.lang.Exception;
+import java.lang.Override;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class ScreenshotTest extends AssistTestBase {
+    static final String TAG = "ScreenshotTest";
+
+    private static final String TEST_CASE_TYPE = Utils.SCREENSHOT;
+
+    private BroadcastReceiver mScreenshotActivityReceiver;
+    private CountDownLatch mHasResumedLatch, mReadyLatch;
+
+    public ScreenshotTest() {
+        super();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mReadyLatch = new CountDownLatch(1);
+        // set up receiver
+        mScreenshotActivityReceiver = new ScreenshotTestReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        filter.addAction(Utils.APP_3P_HASRESUMED);
+        mContext.registerReceiver(mScreenshotActivityReceiver, filter);
+
+        // start test start activity
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mScreenshotActivityReceiver != null) {
+            mContext.unregisterReceiver(mScreenshotActivityReceiver);
+        }
+        super.tearDown();
+    }
+
+    public void testRedScreenshot() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        Log.i(TAG, "Starting screenshot test");
+        mTestActivity.startTest(TEST_CASE_TYPE);
+        Log.i(TAG, "start waitForAssistantToBeReady()");
+        waitForAssistantToBeReady(mReadyLatch);
+
+        waitForActivityResumeAndAssist(Color.RED);
+        verifyAssistDataNullness(false, false, false, false);
+        assertTrue(mScreenshotMatches);
+    }
+
+    public void testGreenScreenshot() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        Log.i(TAG, "Starting screenshot test");
+        mTestActivity.startTest(TEST_CASE_TYPE);
+        Log.i(TAG, "start waitForAssistantToBeReady()");
+        waitForAssistantToBeReady(mReadyLatch);
+
+        waitForActivityResumeAndAssist(Color.GREEN);
+        verifyAssistDataNullness(false, false, false, false);
+        assertTrue(mScreenshotMatches);
+    }
+
+    public void testBlueScreenshot() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        Log.i(TAG, "Starting screenshot test");
+        mTestActivity.startTest(TEST_CASE_TYPE);
+        Log.i(TAG, "start waitForAssistantToBeReady()");
+        waitForAssistantToBeReady(mReadyLatch);
+
+        waitForActivityResumeAndAssist(Color.BLUE);
+        verifyAssistDataNullness(false, false, false, false);
+        assertTrue(mScreenshotMatches);
+    }
+
+    private void waitForActivityResumeAndAssist(int color) throws Exception {
+        mHasResumedLatch = new CountDownLatch(1);
+        Bundle extras = new Bundle();
+        extras.putInt(Utils.SCREENSHOT_COLOR_KEY, color);
+        startSession(TEST_CASE_TYPE, extras);
+        Log.i(TAG, "waiting for onResume() before continuing.");
+        if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+        }
+        waitForContext();
+    }
+
+    private class ScreenshotTestReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            Log.i(ScreenshotTest.TAG, "Got some broadcast: " + action);
+            if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED)) {
+                Log.i(ScreenshotTest.TAG, "Received assist receiver is registered.");
+                if (mReadyLatch != null) {
+                    mReadyLatch.countDown();
+                }
+            } else if (action.equals(Utils.APP_3P_HASRESUMED)) {
+                if (mHasResumedLatch != null) {
+                    mHasResumedLatch.countDown();
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/TestStartActivity.java b/tests/tests/assist/src/android/assist/cts/TestStartActivity.java
new file mode 100644
index 0000000..e54e774
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/TestStartActivity.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.assist.cts;
+
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.app.assist.AssistStructure;
+import android.app.assist.AssistStructure.ViewNode;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import java.lang.Override;
+
+public class TestStartActivity extends Activity {
+    static final String TAG = "TestStartActivity";
+
+    private ScrollView mScrollView;
+    private TextView mTextView;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, " in onCreate");
+        // Set the respective view we want compared with the test activity
+        String testName = getIntent().getStringExtra(Utils.TESTCASE_TYPE);
+        switch (testName) {
+            case Utils.ASSIST_STRUCTURE:
+                setContentView(R.layout.test_app);
+                setTitle(R.string.testAppTitle);
+                return;
+            case Utils.TEXTVIEW:
+                setContentView(R.layout.text_view);
+                mTextView =  (TextView) findViewById(R.id.text_view);
+                mScrollView = (ScrollView) findViewById(R.id.scroll_view);
+                setTitle(R.string.textViewActivityTitle);
+                return;
+            case Utils.LARGE_VIEW_HIERARCHY:
+                setContentView(R.layout.multiple_text_views);
+                setTitle(R.string.testAppTitle);
+                return;
+            case Utils.WEBVIEW:
+                if (getPackageManager().hasSystemFeature(
+                        PackageManager.FEATURE_WEBVIEW)) {
+                    setContentView(R.layout.webview);
+                    setTitle(R.string.webViewActivityTitle);
+                    WebView webview = (WebView) findViewById(R.id.webview);
+                    webview.setWebViewClient(new WebViewClient() {
+                        @Override
+                        public void onPageFinished(WebView view, String url) {
+                            sendBroadcast(new Intent(Utils.TEST_ACTIVITY_LOADED));
+                        }
+                    });
+                    webview.loadData(Utils.WEBVIEW_HTML, "text/html", "UTF-8");
+                }
+                return;
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log.i(TAG, " in onResume");
+    }
+
+    public void startTest(String testCaseName) {
+        Log.i(TAG, "Starting test activity for TestCaseType = " + testCaseName);
+        Intent intent = new Intent();
+        intent.putExtra(Utils.TESTCASE_TYPE, testCaseName);
+        intent.setAction("android.intent.action.START_TEST_" + testCaseName);
+        intent.setComponent(new ComponentName("android.assist.service",
+                "android.assist." + Utils.getTestActivity(testCaseName)));
+        startActivity(intent);
+    }
+
+    public void start3pApp(String testCaseName) {
+        Intent intent = new Intent();
+        intent.putExtra(Utils.TESTCASE_TYPE, testCaseName);
+        intent.setAction("android.intent.action.TEST_APP_" + testCaseName);
+        intent.setComponent(Utils.getTestAppComponent(testCaseName));
+        startActivity(intent);
+    }
+
+    public void start3pAppWithColor(String testCaseName, int color) {
+        Intent intent = new Intent();
+        intent.setAction("android.intent.action.TEST_APP_" + testCaseName);
+        intent.putExtra(Utils.SCREENSHOT_COLOR_KEY, color);
+        intent.setComponent(Utils.getTestAppComponent(testCaseName));
+        startActivity(intent);
+    }
+
+    @Override
+    protected void onPause() {
+        Log.i(TAG, " in onPause");
+        super.onPause();
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        Log.i(TAG, " in onStart");
+    }
+
+    @Override protected void onRestart() {
+        super.onRestart();
+        Log.i(TAG, " in onRestart");
+    }
+
+    @Override
+    protected void onStop() {
+        Log.i(TAG, " in onStop");
+        super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.i(TAG, " in onDestroy");
+        super.onDestroy();
+    }
+
+    public void scrollText(int scrollX, int scrollY, boolean scrollTextView,
+            boolean scrollScrollView) {
+        if (scrollTextView) {
+            if (scrollX < 0 || scrollY < 0) {
+                scrollX = mTextView.getWidth();
+                scrollY = mTextView.getLayout().getLineTop(mTextView.getLineCount()) - mTextView.getHeight();
+            }
+            Log.i(TAG, "Scrolling text view to " + scrollX + ", " + scrollY);
+            mTextView.scrollTo(scrollX, scrollY);
+        } else if (scrollScrollView) {
+            if (scrollX < 0 || scrollY < 0) {
+                Log.i(TAG, "Scrolling scroll view to bottom right");
+                mScrollView.fullScroll(View.FOCUS_DOWN);
+                mScrollView.fullScroll(View.FOCUS_RIGHT);
+            } else {
+                Log.i(TAG, "Scrolling scroll view to " + scrollX + ", " + scrollY);
+                mScrollView.scrollTo(scrollX, scrollY);
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/TextViewTest.java b/tests/tests/assist/src/android/assist/cts/TextViewTest.java
new file mode 100644
index 0000000..089993d
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/TextViewTest.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 android.assist.cts;
+
+import android.assist.common.Utils;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ *  Test that the AssistStructure returned is properly formatted.
+ */
+
+public class TextViewTest extends AssistTestBase {
+    private static final String TAG = "TextViewTest";
+    private static final String TEST_CASE_TYPE = Utils.TEXTVIEW;
+
+    private BroadcastReceiver mReceiver;
+    private CountDownLatch mHasResumedLatch = new CountDownLatch(1);
+    private CountDownLatch mReadyLatch = new CountDownLatch(1);
+
+    public TextViewTest() {
+        super();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setUpAndRegisterReceiver();
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    private void setUpAndRegisterReceiver() {
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new TextViewTestBroadcastReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.APP_3P_HASRESUMED);
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    private void waitForOnResume() throws Exception {
+        Log.i(TAG, "waiting for onResume() before continuing");
+        if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+        }
+    }
+
+    public void testTextView() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        mTestActivity.start3pApp(TEST_CASE_TYPE);
+        scrollTestApp(0, 0, true, false);
+
+        // Verify that the text view contains the right text
+        mTestActivity.startTest(TEST_CASE_TYPE);
+        waitForAssistantToBeReady(mReadyLatch);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        verifyAssistDataNullness(false, false, false, false);
+
+        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE),
+                false /*FLAG_SECURE set*/);
+
+        // Verify that the scroll position of the text view is accurate after scrolling.
+        scrollTestApp(10, 50, true /* scrollTextView */, false /* scrollScrollView */);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE), false);
+
+        scrollTestApp(-1, -1, true, false);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE), false);
+
+        scrollTestApp(0, 0, true, true);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE), false);
+
+        scrollTestApp(10, 50, false, true);
+        waitForOnResume();
+        startSession();
+        waitForContext();
+        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE), false);
+    }
+
+    private class TextViewTestBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Utils.APP_3P_HASRESUMED) && mHasResumedLatch != null) {
+                mHasResumedLatch.countDown();
+            } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED) &&  mReadyLatch != null) {
+                mReadyLatch.countDown();
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/src/android/assist/cts/WebViewTest.java b/tests/tests/assist/src/android/assist/cts/WebViewTest.java
new file mode 100644
index 0000000..4e05494
--- /dev/null
+++ b/tests/tests/assist/src/android/assist/cts/WebViewTest.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 android.assist.cts;
+
+import android.assist.common.Utils;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ *  Test that the AssistStructure returned is properly formatted.
+ */
+
+public class WebViewTest extends AssistTestBase {
+    private static final String TAG = "WebViewTest";
+    private static final String TEST_CASE_TYPE = Utils.WEBVIEW;
+
+    private boolean mWebViewSupported;
+    private BroadcastReceiver mReceiver;
+    private CountDownLatch mHasResumedLatch = new CountDownLatch(1);
+    private CountDownLatch mTestWebViewLatch = new CountDownLatch(1);
+    private CountDownLatch mReadyLatch = new CountDownLatch(1);
+
+    public WebViewTest() {
+        super();
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setUpAndRegisterReceiver();
+        startTestActivity(TEST_CASE_TYPE);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        super.tearDown();
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+            mReceiver = null;
+        }
+    }
+
+    private void setUpAndRegisterReceiver() {
+        if (mReceiver != null) {
+            mContext.unregisterReceiver(mReceiver);
+        }
+        mReceiver = new WebViewTestBroadcastReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.APP_3P_HASRESUMED);
+        filter.addAction(Utils.ASSIST_RECEIVER_REGISTERED);
+        filter.addAction(Utils.TEST_ACTIVITY_LOADED);
+        mContext.registerReceiver(mReceiver, filter);
+    }
+
+    private void waitForOnResume() throws Exception {
+        Log.i(TAG, "waiting for onResume() before continuing");
+        if (!mHasResumedLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Activity failed to resume in " + Utils.ACTIVITY_ONRESUME_TIMEOUT_MS + "msec");
+        }
+    }
+
+    private void waitForTestActivity() throws Exception {
+        Log.i(TAG, "waiting for webview in test activity to load");
+        if (!mTestWebViewLatch.await(Utils.ACTIVITY_ONRESUME_TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            // wait for webView to load completely.
+        }
+    }
+
+    public void testWebView() throws Exception {
+        if (mActivityManager.isLowRamDevice()) {
+            Log.d(TAG, "Not running assist tests on low-RAM device.");
+            return;
+        }
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) {
+            return;
+        }
+        mTestActivity.start3pApp(TEST_CASE_TYPE);
+        mTestActivity.startTest(TEST_CASE_TYPE);
+        waitForAssistantToBeReady(mReadyLatch);
+        waitForOnResume();
+        waitForTestActivity();
+        startSession();
+        waitForContext();
+        verifyAssistDataNullness(false, false, false, false);
+        verifyAssistStructure(Utils.getTestAppComponent(TEST_CASE_TYPE),
+                false /*FLAG_SECURE set*/);
+    }
+
+    private class WebViewTestBroadcastReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (action.equals(Utils.APP_3P_HASRESUMED) && mHasResumedLatch != null) {
+                mHasResumedLatch.countDown();
+            } else if (action.equals(Utils.ASSIST_RECEIVER_REGISTERED) && mReadyLatch != null) {
+                mReadyLatch.countDown();
+            } else if (action.equals(Utils.TEST_ACTIVITY_LOADED) && mTestWebViewLatch != null) {
+                mTestWebViewLatch.countDown();
+            }
+        }
+    }
+}
diff --git a/tests/tests/assist/testapp/Android.mk b/tests/tests/assist/testapp/Android.mk
new file mode 100644
index 0000000..68297ef
--- /dev/null
+++ b/tests/tests/assist/testapp/Android.mk
@@ -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.
+
+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 := CtsAssistCommon
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsAssistApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/assist/testapp/AndroidManifest.xml b/tests/tests/assist/testapp/AndroidManifest.xml
new file mode 100644
index 0000000..fa08f55
--- /dev/null
+++ b/tests/tests/assist/testapp/AndroidManifest.xml
@@ -0,0 +1,97 @@
+<?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.assist.testapp">
+
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <activity android:name=".TestApp"
+                android:label="Assist Structure Test Activity">
+          <intent-filter>
+              <action android:name="android.intent.action.TEST_APP_ASSIST_STRUCTURE" />
+              <action android:name="android.intent.action.TEST_APP_LARGE_VIEWHIERARCHY" />
+              <category android:name="android.intent.category.DEFAULT" />
+              <category android:name="android.intent.category.VOICE" />
+          </intent-filter>
+        </activity>
+        <activity android:name=".DisableContextActivity"
+            android:label="Disable Context Test Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_APP_DISABLE_CONTEXT" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".SecureActivity"
+                  android:label="Secure Test Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_APP_FLAG_SECURE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".LifecycleActivity"
+                  android:label="Life Cycle Check Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_APP_LIFECYCLE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".ScreenshotActivity"
+                  android:label="Screenshot Test Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_APP_SCREENSHOT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".ExtraAssistDataActivity"
+            android:label="Extra Assist Test Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_APP_EXTRA_ASSIST" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".TextViewActivity"
+            android:label="TextView Test Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_APP_TEXTVIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".WebViewActivity"
+            android:label="WebView Test Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_APP_WEBVIEW" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".FocusChangeActivity"
+            android:label="Focus Change Test Activity">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_APP_FOCUS_CHANGE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.VOICE" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/tests/tests/assist/testapp/res/layout/multiple_text_views.xml b/tests/tests/assist/testapp/res/layout/multiple_text_views.xml
new file mode 100644
index 0000000..455d5e3
--- /dev/null
+++ b/tests/tests/assist/testapp/res/layout/multiple_text_views.xml
@@ -0,0 +1,79 @@
+<?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:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <TextView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:scrollbars="vertical"
+    android:text="@string/text_too_large_to_fit" />
+
+  <ScrollView
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_weight="1">
+    <TextView
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:scrollbars="vertical"
+      android:text="@string/text_too_large_to_fit" />
+  </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/testapp/res/layout/screenshot_activity.xml b/tests/tests/assist/testapp/res/layout/screenshot_activity.xml
new file mode 100644
index 0000000..05051dc
--- /dev/null
+++ b/tests/tests/assist/testapp/res/layout/screenshot_activity.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.
+-->
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:id="@+id/screenshot_activity"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/testapp/res/layout/secure_app.xml b/tests/tests/assist/testapp/res/layout/secure_app.xml
new file mode 100644
index 0000000..3b72ad6
--- /dev/null
+++ b/tests/tests/assist/testapp/res/layout/secure_app.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.
+-->
+<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">
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/welcome" />
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/testapp/res/layout/test_app.xml b/tests/tests/assist/testapp/res/layout/test_app.xml
new file mode 100644
index 0000000..3fbfd6d
--- /dev/null
+++ b/tests/tests/assist/testapp/res/layout/test_app.xml
@@ -0,0 +1,47 @@
+<?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:orientation="vertical">
+    <TextView
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="@string/welcome" />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="350dp"
+        android:orientation="vertical"
+        android:layout_gravity="bottom">
+        <FrameLayout
+            android:id="@+id/card1"
+            android:layout_width="match_parent"
+            android:layout_height="150dp"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="8dp"
+            android:layout_marginTop="16dp"
+            android:elevation="3dp">
+        </FrameLayout>
+        <View
+            android:id="@+id/card2"
+            android:layout_width="match_parent"
+            android:layout_height="200dp"
+            android:layout_marginStart="8dp"
+            android:layout_marginEnd="8dp"
+            android:layout_marginTop="16dp"
+            android:elevation="3dp"/>
+    </LinearLayout>
+</RelativeLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/testapp/res/layout/text_view.xml b/tests/tests/assist/testapp/res/layout/text_view.xml
new file mode 100644
index 0000000..0f0f427
--- /dev/null
+++ b/tests/tests/assist/testapp/res/layout/text_view.xml
@@ -0,0 +1,42 @@
+<?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:id="@+id/text_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:focusable="false"
+        android:focusableInTouchMode="false"
+        android:scrollbars="vertical"
+        android:clickable="true"
+        android:text="@string/text_too_large_to_fit" />
+
+    <ScrollView
+        android:id="@+id/scroll_view"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="1">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:scrollbars="vertical"
+            android:text="@string/text_too_large_to_fit" />
+    </ScrollView>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/testapp/res/layout/webview.xml b/tests/tests/assist/testapp/res/layout/webview.xml
new file mode 100644
index 0000000..bdb8082
--- /dev/null
+++ b/tests/tests/assist/testapp/res/layout/webview.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.
+-->
+<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/webview"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+    </WebView>
+</LinearLayout>
\ No newline at end of file
diff --git a/tests/tests/assist/testapp/res/values/strings.xml b/tests/tests/assist/testapp/res/values/strings.xml
new file mode 100644
index 0000000..670024b
--- /dev/null
+++ b/tests/tests/assist/testapp/res/values/strings.xml
@@ -0,0 +1,284 @@
+<?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>
+
+    <string name="app_name">Memegen</string>
+    <string name="hello_world">Hello world!</string>
+    <string name="action_settings">Settings</string>
+    <string name="welcome">Hello there!</string>
+    <string name="text_too_large_to_fit">❤ ☀ ☆ ☂ ☻ ♞ ☯ ☭ ☢ € →Hello هتاف للترحيب שלום
+        përshëndetje Добры дзень 您好 হ্যালো здравей მიესალმები Χαίρετε હેલો नमस्ते Nnọọ こんにちは ಹಲೋ
+        Сәлеметсіз бе ជំរាបសួរ 안녕하세요 ສະບາຍດີ ഹലോ हॅलो Сайн байна уу नमस्ते سلامהעלא ہیلو
+        မင်္ဂလာပါ ਸਤ ਸ੍ਰੀ ਅਕਾਲ Здравствуйте здраво ආයුබෝවන් ஹலோ హలో สวัสดี Pẹlẹ o
+        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+        convallis nunc et vestibulum. Sed et consequat quam, blandit varius tortor. Curabitur
+        accumsan nulla lectus, placerat condimentum odio elementum vel. Nulla erat ex, accumsan ut
+        enim sagittis, scelerisque efficitur ante. Nullam quis orci nec magna maximus malesuada ac
+        id sem. Nam sagittis erat risus, a accumsan neque congue sit amet. Nullam risus velit,
+        faucibus eget scelerisque et, maximus eget arcu. Sed porta sed libero ac imperdiet.
+
+        Nulla sem lectus, ullamcorper id dui vel, rutrum interdum augue. Proin aliquam nisi vitae
+        hendrerit tempor. Mauris porttitor velit et egestas feugiat. Vivamus eu dapibus libero,
+        quis fringilla urna. Suspendisse non turpis dui. Vivamus facilisis diam vitae est auctor
+        luctus. Etiam quis lectus viverra, interdum turpis eu, aliquam sem. Nulla vulputate lacinia
+        nisi a dictum. Cras faucibus vitae tortor at ullamcorper. Quisque sit amet sapien maximus,
+        ornare nisi non, imperdiet magna. Vestibulum tempor metus ac mi ultrices dapibus.
+
+        Suspendisse potenti. Mauris pellentesque lacinia tristique. Pellentesque vel dui quis sem
+        lacinia imperdiet feugiat vitae sem. Proin a arcu magna. Sed quis augue eu mi accumsan
+        pellentesque pretium in leo. Duis euismod purus mauris, ac tempor erat auctor non. Quisque
+        bibendum est pulvinar ex dapibus, ac tincidunt nibh tempus. Mauris sodales sem id purus
+        commodo iaculis. Pellentesque a quam dapibus, vehicula lectus at, tincidunt arcu. In
+        placerat porttitor urna quis consequat. Nullam feugiat nisl sed urna hendrerit, sed
+        elementum massa iaculis. Fusce sit amet turpis hendrerit, varius lorem sed, luctus mi.
+        Phasellus sit amet ex orci. Duis scelerisque nisl quis efficitur maximus. Curabitur vitae
+        accumsan nunc, eget varius nisi.
+
+        Fusce efficitur malesuada luctus. Aliquam dapibus tortor sit amet purus semper, sit amet
+        pretium lorem feugiat. Maecenas gravida sed arcu et placerat. Nulla facilisi. Cras placerat
+        rutrum mi, in rutrum mauris maximus at. Mauris eu suscipit ante. Nullam pharetra egestas
+        diam a viverra. Donec sem turpis, tempor malesuada est vel, blandit accumsan magna. In
+        iaculis velit in efficitur hendrerit. Nulla facilisi. Curabitur eget ligula lorem. Sed sit
+        amet dolor ut ligula malesuada condimentum. Phasellus molestie augue eget libero commodo,
+        vel blandit ex blandit.
+
+        Morbi cursus tortor ante, et tempus nisi tempus et. Suspendisse quis gravida diam. Aliquam
+        efficitur dolor sit amet sollicitudin varius. Etiam libero purus, ornare nec nulla vel,
+        ullamcorper blandit nisl. Sed vel consequat diam, id placerat sem. Donec quis elementum
+        urna. In posuere bibendum nunc, in condimentum justo blandit ac. Quisque enim lorem,
+        gravida at purus at, sollicitudin imperdiet erat. Ut consectetur rutrum ante, et pretium
+        odio iaculis a. Nullam a nibh vulputate, volutpat lectus eu, pellentesque felis. Nam
+        vehicula suscipit diam nec convallis. Quisque congue maximus sem, sit amet hendrerit leo
+        tempor et.
+
+        Nam eu consequat dui. Sed semper dignissim mattis. Integer tortor eros, tempor in lectus a,
+        lobortis aliquam dolor. Phasellus at sagittis magna. Nulla eleifend orci ac urna auctor,
+        sit amet luctus urna vulputate. Nulla venenatis venenatis erat ac finibus. Etiam
+        ullamcorper elementum suscipit. Morbi nec velit non mauris porta finibus. Nullam in
+        sagittis odio. Praesent eget nisl ut mauris vestibulum feugiat. Sed vulputate at elit et
+        cursus. Praesent viverra erat blandit nunc egestas, vel feugiat ex condimentum. Class
+        aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
+
+        Nulla fermentum mattis urna, non gravida eros vestibulum et. Fusce porttitor augue turpis,
+        sit amet aliquam augue sodales non. Nunc neque odio, sagittis sed gravida euismod, commodo
+        at libero. Donec porttitor pulvinar neque vitae lobortis. Aliquam accumsan velit nec sapien
+        placerat egestas. Aliquam at tincidunt massa, et dignissim justo. Donec sapien ante, rutrum
+        et tristique a, commodo a massa.
+
+        Nunc placerat lobortis magna, et molestie lacus semper porta. Lorem ipsum dolor sit amet,
+        consectetur adipiscing elit. Phasellus ac ligula dui. Duis ultrices viverra eros fermentum
+        finibus. Integer ultrices, felis in accumsan volutpat, mi ligula hendrerit nunc, nec
+        accumsan mauris tellus sit amet metus. Ut pharetra enim et sapien sollicitudin, nec
+        ultricies urna pharetra. Morbi non tortor nec dui feugiat rutrum. Aliquam malesuada sodales
+        risus, sed congue nunc accumsan vitae. Etiam nunc magna, tempus non suscipit eu, feugiat ut
+        nibh. Maecenas et libero ut nisl pellentesque tempor nec vel quam. Etiam sem ligula,
+        ullamcorper non dolor a, viverra placerat nulla. Nullam dictum commodo dui, sed ultrices
+        enim sagittis eget. Morbi non consectetur lectus. In gravida, augue vitae pulvinar
+        molestie, ligula orci vulputate ex, at bibendum urna felis nec nibh. Sed nisl nunc, iaculis
+        at augue venenatis, fringilla accumsan velit. Curabitur nec augue porttitor, rutrum nisi
+        vitae, elementum orci.
+
+        Vestibulum eu tortor iaculis, dignissim velit quis, rhoncus dolor. Donec et tincidunt
+        nulla. Duis faucibus auctor erat ac ultricies. In a fermentum mi. Fusce vitae mi id sem
+        interdum tincidunt. Nulla hendrerit orci turpis, in maximus elit mollis eget. Aliquam erat
+        volutpat. Phasellus mattis est nibh, ut scelerisque ligula egestas eu. Ut molestie orci a
+        malesuada tempor. Sed tempus arcu id orci gravida faucibus. Vivamus ac lacinia neque, at
+        vehicula magna.
+
+        Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
+        Nullam aliquam, justo scelerisque egestas sodales, purus odio posuere arcu, ac ultrices
+        nunc felis non massa. Aliquam vulputate ipsum sed aliquet auctor. In pulvinar, eros sit
+        amet ultricies tristique, lacus ipsum scelerisque eros, nec vestibulum est lectus quis
+        lorem. Pellentesque ac augue ut eros mattis viverra vitae ut lacus. Phasellus imperdiet
+        efficitur elit eget tincidunt. Donec sodales metus at dolor pulvinar, at gravida nibh
+        facilisis. Sed nec tellus luctus, cursus lacus sed, euismod orci. Maecenas sit amet leo
+        orci. Nulla non leo non mi eleifend consequat sit amet vitae dui. Sed gravida gravida
+        justo, tincidunt ultrices justo semper vitae. Fusce at nisi nisl. Morbi molestie quis justo
+        a convallis. Curabitur massa lacus, feugiat quis mauris ac, malesuada viverra est.
+
+        Phasellus bibendum faucibus velit, ac scelerisque velit tincidunt eu. Curabitur quis
+        suscipit erat, ac feugiat odio. Nullam et sapien et nibh maximus posuere. Vivamus faucibus
+        justo eget dictum sollicitudin. Etiam at leo eget elit facilisis lobortis. Maecenas
+        bibendum tortor non erat pretium dignissim. Fusce id imperdiet augue. Suspendisse dignissim
+        magna vel odio viverra varius. Maecenas suscipit ante et lorem sodales vehicula. Quisque
+        vel magna id sem suscipit iaculis. Etiam in elementum risus.
+
+        Suspendisse odio nisi, pharetra et purus sit amet, placerat lobortis diam. Phasellus enim
+        nunc, posuere sed porta in, ornare eu ipsum. Phasellus imperdiet porta neque, vitae dapibus
+        tellus feugiat eget. Nulla sodales leo ac efficitur luctus. Vivamus eget ipsum quis ante
+        pulvinar blandit. Vestibulum a justo convallis justo elementum viverra ut sit amet nisl.
+        Suspendisse eget augue fermentum, sagittis risus a, rhoncus elit. Vestibulum in maximus
+        tortor, non vestibulum libero. Nunc accumsan neque a nisl dapibus, id laoreet neque congue.
+        Pellentesque sapien odio, fringilla non nulla nec, varius placerat diam. Aliquam
+        consectetur neque eu ipsum posuere, nec dignissim sem faucibus. Donec sit amet tempor
+        sapien. Nam at libero vel lorem dapibus ultrices a vel augue. Nunc facilisis justo ante,
+        mollis tristique velit aliquet quis. Mauris consectetur odio at urna bibendum aliquam.
+
+           Nullam lectus orci, hendrerit ut ultrices in, dapibus pellentesque nibh. Aliquam arcu
+        metus, lobortis vel dignissim id, tempus ut ante. Integer vitae ante augue. In hac habitasse
+        platea dictumst. Vestibulum in tellus ante. Cras nisi tellus, congue ac velit quis, rhoncus
+        ornare ligula. Sed facilisis gravida pellentesque. Praesent id ultrices orci, ac ultricies
+        arcu. Donec at ante quis augue faucibus congue. Donec mattis quam dui, ut vestibulum orci
+        tempor mattis. Phasellus in quam id tortor varius ullamcorper ac ac ante. Proin cursus
+        accumsan sem, vel finibus lectus eleifend ut. Donec efficitur feugiat diam id ultricies. In
+        quis euismod nisi. Vestibulum eget viverra sapien. Donec scelerisque nec elit vel viverra.
+
+           Sed mi urna, rutrum quis augue vel, aliquet placerat diam. Proin faucibus in odio et
+        consequat. Proin ut ex in mauris eleifend efficitur. Praesent ullamcorper sollicitudin urna,
+        sed mollis elit hendrerit non. Duis leo lorem, efficitur eu auctor sit amet, scelerisque
+        scelerisque magna. Mauris eget massa auctor, viverra arcu a, elementum nibh. Sed
+        pellentesque, nulla sed condimentum posuere, tortor metus congue sem, nec placerat neque
+        magna vitae purus.
+
+           Etiam at risus vitae sapien aliquam condimentum. Vestibulum id libero placerat purus
+        vehicula consectetur. Pellentesque sapien sapien, posuere at pulvinar at, ultrices sed est.
+        Maecenas nec condimentum ante. Aenean volutpat, ex condimentum hendrerit hendrerit, quam
+        nisl  pharetra nibh, vitae bibendum nisl odio vel lacus. Morbi mi tellus, bibendum id mauris
+        eu,  facilisis volutpat turpis. Maecenas rutrum convallis felis. Quisque eget feugiat felis.
+        Duis pellentesque iaculis massa ut facilisis. Donec nec commodo magna. Integer aliquet orci
+        a odio eleifend elementum. Quisque molestie, urna ut molestie eleifend, odio neque maximus
+        enim, eget viverra metus lectus eget quam. Fusce nec urna ac neque bibendum aliquam vel quis
+        dui. Fusce ac quam consequat, feugiat leo vitae, auctor felis.
+
+           Sed ac metus mauris. Sed sed velit ut tortor aliquam vestibulum at eu arcu. Etiam eu
+        posuere lacus. Maecenas id lacus quis sem mollis sodales. Quisque justo sapien, vulputate ac
+        mi ut, congue vestibulum orci. Donec euismod erat rutrum, laoreet urna sed, accumsan purus.
+        Donec eu quam a sapien condimentum accumsan. Sed at tellus lorem. Curabitur bibendum, arcu
+        sit amet finibus sodales, mi sem finibus sem, eget scelerisque tellus neque vel urna.
+        Suspendisse eu augue nec erat suscipit luctus sed non metus.
+
+           Suspendisse porttitor ex ipsum. Pellentesque tristique eros sed pharetra porttitor.
+        Quisque ut elit vehicula, aliquet est nec, faucibus tellus. Donec ex augue, congue eu
+        dignissim  maximus, vestibulum at purus. Nulla quam enim, laoreet sit amet molestie vel,
+        dapibus nec tortor. Sed interdum massa ac orci gravida, vel viverra lacus lacinia. Donec
+        nisl lacus, fermentum at faucibus ac, consequat ut nibh. Praesent laoreet est augue, vitae
+        maximus dui efficitur sit amet. Cras ipsum tellus, tincidunt at volutpat non, tincidunt ut
+        elit. Morbi commodo sagittis gravida. Pellentesque sed ante massa. Phasellus a turpis non
+        turpis cursus consequat sed nec tortor. Proin et augue elit.
+
+           Duis finibus sem commodo rutrum pulvinar. In sollicitudin ante magna, vel facilisis
+        tellus fringilla vel. Nam purus ex, tincidunt eget varius at, euismod nec elit. Curabitur
+        consequat nulla vel nisi iaculis, ut mattis odio congue. Nulla et mollis tortor, a maximus
+        justo. Donec semper eros sed nunc rhoncus condimentum. Donec nibh purus, interdum non lectus
+        id, porta convallis eros.
+
+           Sed hendrerit, dui non sagittis sollicitudin, enim ex imperdiet sapien, et maximus lorem
+        dolor a enim. Nulla risus nisl, vestibulum at ornare posuere, congue in felis. Duis sagittis
+        id diam a varius. Donec viverra eu orci sodales commodo. Cras metus tortor, sodales vitae
+        auctor non, scelerisque a ante. Quisque sodales nisi libero, ut lobortis enim suscipit ut.
+        Cras mi ipsum, maximus non bibendum sit amet, pharetra quis ipsum. Vestibulum venenatis, odi
+        at hendrerit pretium, tellus diam auctor justo, non posuere quam mauris id nisl. Nam dolor
+        nibh, molestie et lectus et, scelerisque porta elit. Vestibulum viverra condimentum auctor.
+        In eros tortor, convallis sed quam eu, ultrices malesuada purus. Integer lorem quam,
+        ultricies at est consectetur, sagittis porttitor eros. Proin non risus vitae lacus
+        consectetur malesuada non pulvinar justo. Aliquam mollis nisi nunc, sit amet vulputate metus
+        sollicitudin vel.
+
+           Quisque auctor varius fermentum. Praesent mollis justo sit amet est consectetur, in
+        volutpat tellus mollis. Aenean at bibendum eros, at finibus nibh. Phasellus nec mi sem.
+        Mauris pellentesque dui sit amet lobortis aliquam. Ut nec massa at urna aliquam gravida vel
+        in magna. Donec consectetur sapien magna, a auctor sapien placerat eu.
+
+           Pellentesque aliquet ante sed lacus gravida rutrum. Maecenas euismod varius felis, nec
+        tempus metus tempus et. Nam convallis augue a massa scelerisque, vel pharetra dolor
+        scelerisque. Fusce porttitor mi a magna rutrum condimentum. Aliquam fermentum at turpis at
+        auctor. Nulla ut suscipit dui. Donec rutrum viverra aliquam. Donec elementum nisl sapien, ac
+        blandit risus porta facilisis. Proin tellus dolor, ornare vel magna sit amet, maximus
+        volutpat felis. Aenean euismod aliquet purus, at finibus nunc elementum eu. Ut faucibus
+        ullamcorper consectetur. Aenean egestas arcu id mauris elementum, at sollicitudin est
+        congue. Sed a odio mattis, sollicitudin erat ut, tristique dolor. Aliquam luctus risus quis
+        tellus semper, a vestibulum nulla viverra.
+
+           Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos
+        himenaeos. Vestibulum sit amet nisi felis. Praesent condimentum consequat lacus pulvinar
+        imperdiet. Praesent vel condimentum quam. Maecenas eu aliquet odio. Vestibulum sed nulla
+        mattis lacus porta bibendum a ac eros. Nunc porttitor sagittis laoreet. Duis porta eros at
+        congue tristique. Pellentesque quis fringilla neque, a hendrerit tellus. Pellentesque ac
+        nibh ac tellus pulvinar porttitor et in est. Integer blandit lorem libero, eu pulvinar
+        tellus posuere eget. Vivamus pretium nulla ligula, ut dapibus massa fringilla in.
+        Suspendisse consectetur sem non elit porta, id pellentesque erat dapibus. Quisque ex mi,
+        tempus et hendrerit nec, gravida quis odio. Ut at mi in leo scelerisque venenatis.
+
+           Ut sed tellus in risus tincidunt tempor ut at arcu. Maecenas ut convallis justo. In
+        rutrum urna eu massa rhoncus, eget condimentum augue vehicula. Nullam eget placerat erat.
+        Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.
+        Aenean at volutpat orci, a lobortis dolor. Sed consequat facilisis interdum. Fusce libero
+        neque, fringilla in congue a, vehicula rutrum ipsum. Nam ornare placerat vestibulum. Proin
+        nec orci velit. Pellentesque scelerisque gravida diam, ut tristique libero tempus eu. Nam
+        semper lacus nec nulla volutpat imperdiet non eget tortor. Sed et pellentesque ligula.
+
+           Aenean a dolor dolor. Curabitur ut placerat lacus, sit amet aliquet orci. Aliquam erat
+        volutpat. Cras mollis sit amet lectus ornare pretium. Vestibulum fringilla orci vel est
+        iaculis, at mattis quam condimentum. Vivamus semper elit consectetur lectus gravida, in
+        sollicitudin mi fringilla. Donec eget lorem in orci blandit aliquam. Pellentesque libero
+        tellus, dignissim id augue et, vulputate viverra nisl. Cum sociis natoque penatibus et
+        magnis dis parturient montes, nascetur ridiculus mus. Donec ac vulputate metus, eu suscipit
+        sem. Donec placerat, nulla at sodales hendrerit, orci tortor vestibulum purus, non pharetra
+        nulla purus posuere arcu.
+
+           Quisque feugiat elit sem, ac interdum diam pharetra nec. Curabitur sem libero, vulputate
+        eu libero vitae, volutpat facilisis ligula. Aenean maximus erat laoreet, interdum ante in,
+        ultrices nisi. Nullam nec efficitur sapien. Integer feugiat et tortor ac bibendum. Donec a
+        scelerisque tortor. Cras quis viverra diam, vitae viverra ipsum. Aliquam ultrices neque sem,
+        congue sodales elit tempus sit amet. Pellentesque habitant morbi tristique senectus et netus
+        et malesuada fames ac turpis egestas. Sed dignissim ipsum eget diam rhoncus, ut finibus
+        nulla pretium. Morbi suscipit nibh vel nisl posuere molestie. Maecenas posuere turpis et
+        rutrum consectetur. Morbi venenatis arcu non gravida vulputate. Vivamus auctor tellus
+        ullamcorper ligula vestibulum cursus. Nunc gravida sit amet nisl quis facilisis.
+
+           Praesent ut justo vestibulum, accumsan mi et, feugiat purus. Nullam pulvinar iaculis
+        pharetra. Aliquam pulvinar risus sit amet elit suscipit tincidunt. In hac habitasse platea
+        dictumst. Etiam eget velit ac magna lacinia efficitur. Vestibulum ante ipsum primis in
+        faucibus orci luctus et ultrices posuere cubilia Curae; Cras volutpat tempus sollicitudin.
+        Ut et ante elit.
+
+           Sed ac tortor justo. Fusce sed metus libero. Duis sagittis tortor ac ante sollicitudin,
+        nec efficitur nibh euismod. Donec porttitor cursus quam, in aliquam lorem feugiat ut.
+        Aliquam tempor lacus eu feugiat feugiat. Nunc pulvinar, libero at auctor commodo, metus diam
+        commodo lorem, in feugiat elit ex non ligula. Quisque at vestibulum sapien, nec facilisis
+        neque. Aenean luctus, arcu ut rhoncus luctus, est massa rhoncus mauris, nec luctus urna sem
+        quis massa. Nam elit felis, congue et ligula eget, ultricies tincidunt erat. Vivamus
+        eleifend no dui ac dictum. In nulla justo, pulvinar ut tristique sed, congue et orci.
+
+           Quisque imperdiet mi lectus, ac scelerisque augue posuere ut. Duis non pulvinar ipsum,
+        finibus risus. Donec ullamcorper nisl at sodales lobortis. Mauris neque leo, vestibulum sit
+        amet placerat vel, aliquet vel sapien. Morbi massa tellus, scelerisque quis nisl in, feugiat
+        posuere augue. Aenean congue sem ut ipsum vulputate rhoncus vitae at eros. Maecenas in velit
+        orci pellentesque lobortis ac at felis. Vestibulum odio quam, lacinia dapibus ornare eu,
+        vulputate a eros. Curabitur eleifend ornare tellus, non sollicitudin justo viverra in. Sed
+        sodales neque et lacus semper, in pharetra est consequat. Nunc vehicula volutpat lectus, sit
+        amet scelerisque nisi. Aenean sollicitudin, sem at ultricies efficitur, eros metus
+        nisl, et fringilla felis lacus non orci. Praesent eros libero, finibus in purus id,
+        tempor ipsum. Donec suscipit libero velit. Aliquam quis diam pharetra, cursus ipsum in,
+        gravida metus. Maecenas ultrices ligula a ullamcorper scelerisque.
+
+           Donec tincidunt felis turpis, id venenatis neque convallis in. Proin euismod ligula nec
+        urna vulputate, sed elementum mauris ultrices. Ut efficitur sem vel mi vestibulum placerat.
+        Sed fermentum lacus nec metus dictum, a commodo quam fermentum. Sed vel vulputate magna.
+        Integer convallis nisi sit amet mi lobortis pellentesque. In egestas porttitor elit eu
+        scelerisque. Suspendisse eleifend vel enim quis tincidunt. Sed placerat risus et pretium
+        porttitor. Nam justo mi, cursus eu pellentesque vel, bibendum ut nisl. Nulla condimentum
+        lorem, non sagittis lorem volutpat vitae. Mauris nec libero lorem. Vestibulum lacus ex,
+        vulputate non massa vitae, pellentesque vestibulum dolor.
+
+           Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;
+        Suspendisse vitae erat nisl. Vestibulum elit ante, semper et semper sit amet, fringilla
+        sapien. Morbi ac nisi sit amet turpis tincidunt mattis ac eget nisl. Nunc a venenatis quam,
+        facilisis maximus odio. Aliquam erat volutpat. Maecenas leo enim, ornare a magna quis,
+        venenatis ornare nulla. Aliquam venenatis nibh et elit tincidunt, ut egestas lorem finibus.
+        Integer iaculis dolor sed enim blandit vestibulum. Nullam vel libero ultricies, sagittis
+        tortor non, molestie eros.</string>
+</resources>
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/ExtraAssistDataActivity.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/ExtraAssistDataActivity.java
new file mode 100644
index 0000000..57d34f8
--- /dev/null
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/ExtraAssistDataActivity.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 android.assist.testapp;
+
+import android.app.Activity;
+import android.app.assist.AssistContent;
+import android.assist.common.Utils;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.lang.Override;
+
+/**
+ * Test the onProvideAssistData and onProvideAssistContent methods activities may override to
+ * provide extra information to the assistant. Verify that the data passed from the activity matches
+ * the data received in {@link android.service.voice.VoiceInteractionSession}.
+ */
+public class ExtraAssistDataActivity extends Activity {
+    private static final String TAG = "ExtraAssistDataActivity";
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public void onProvideAssistData(Bundle data) {
+        super.onProvideAssistData(data);
+        Log.i(TAG, "onProvideAssistData");
+        Utils.addExtraAssistDataToBundle(data);
+    }
+
+    @Override
+    public void onProvideAssistContent(AssistContent outContent) {
+        super.onProvideAssistContent(outContent);
+        Log.i(TAG, "onProvideAssistContent");
+        try {
+            outContent.setStructuredData(Utils.getStructuredJSON());
+        } catch (Exception e) {
+            Log.i(TAG, "Failed to get Structured JSON to put into the AssistContent.");
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        sendBroadcast(new Intent(Utils.APP_3P_HASRESUMED));
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/FocusChangeActivity.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/FocusChangeActivity.java
new file mode 100644
index 0000000..4ab24ed
--- /dev/null
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/FocusChangeActivity.java
@@ -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.
+ */
+
+package android.assist.testapp;
+
+import android.app.Activity;
+import android.assist.common.Utils;
+import android.content.Intent;
+import android.util.Log;
+
+public class FocusChangeActivity extends Activity {
+    private static final String TAG = "FocusChangeActivity";
+    private boolean mGainedFocus = false;
+
+    @Override
+    public void onWindowFocusChanged(boolean hasFocus) {
+        if (hasFocus && !mGainedFocus) {
+            mGainedFocus = true;
+            Log.i(TAG, "gained focus");
+            sendBroadcast(new Intent(Utils.GAINED_FOCUS));
+        } else if (!hasFocus && mGainedFocus) {
+            Log.i(TAG, "lost focus");
+            sendBroadcast(new Intent(Utils.LOST_FOCUS));
+        }
+    }
+}
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/LifecycleActivity.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/LifecycleActivity.java
new file mode 100644
index 0000000..af10f99
--- /dev/null
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/LifecycleActivity.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.assist.testapp;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+public class LifecycleActivity extends Activity {
+    private static final String TAG = "LifecycleActivity";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "LifecycleActivity created");
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log.i(TAG, "Activity has resumed");
+        sendBroadcast(new Intent("android.intent.action.lifecycle_hasResumed"));
+    }
+
+    @Override
+    protected void onPause() {
+        Log.i(TAG, "activity was paused");
+        sendBroadcast(new Intent("android.intent.action.lifecycle_onpause"));
+        super.onPause();
+    }
+
+    @Override
+    protected void onStop() {
+        Log.i(TAG, "activity was stopped");
+        sendBroadcast(new Intent("android.intent.action.lifecycle_onstop"));
+        super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.i(TAG, "activity was destroyed");
+        sendBroadcast(new Intent("android.intent.action.lifecycle_ondestroy"));
+        super.onDestroy();
+    }
+}
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/ScreenshotActivity.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/ScreenshotActivity.java
new file mode 100644
index 0000000..581af2e
--- /dev/null
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/ScreenshotActivity.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.assist.testapp;
+
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+
+import java.lang.Override;
+
+public class ScreenshotActivity extends Activity {
+    static final String TAG = "ScreenshotActivity";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "ScreenshotActivity created");
+        setContentView(R.layout.screenshot_activity);
+    }
+
+    @Override
+    public void onResume() {
+        Log.i(TAG, " in onResume");
+        super.onResume();
+        int backgroundColor = getIntent().getIntExtra(Utils.SCREENSHOT_COLOR_KEY, Color.WHITE);
+        View view = findViewById(R.id.screenshot_activity);
+        view.setBackgroundColor(backgroundColor);
+        view.requestLayout();
+
+        // Tell service activity is in foreground.
+        Intent intent = new Intent(Utils.APP_3P_HASRESUMED);
+        sendBroadcast(intent);
+        Log.i(TAG, "Resumed broadcast sent.");
+    }
+
+    @Override
+    public void onPause() {
+        Log.i(TAG, "onPause");
+        finish();
+        super.onPause();
+    }
+}
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/SecureActivity.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/SecureActivity.java
new file mode 100644
index 0000000..708061e
--- /dev/null
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/SecureActivity.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.assist.testapp;
+
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.view.WindowManager;
+
+public class SecureActivity extends Activity {
+    static final String TAG = "SecureActivity";
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "SecureActivity created");
+        setContentView(R.layout.secure_app);
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
+            WindowManager.LayoutParams.FLAG_SECURE);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log.i(TAG, "Activity has resumed");
+        final View layout = findViewById(android.R.id.content);
+        ViewTreeObserver vto = layout.getViewTreeObserver();
+        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                sendBroadcast(new Intent(Utils.FLAG_SECURE_HASRESUMED));
+            }
+        });
+    }
+}
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/TestApp.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/TestApp.java
new file mode 100644
index 0000000..e0f83cc
--- /dev/null
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/TestApp.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.assist.testapp;
+
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.MeasureSpec;
+import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+
+import java.io.ByteArrayOutputStream;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+
+import java.lang.Override;
+
+public class TestApp extends Activity {
+    static final String TAG = "TestApp";
+
+    private String mTestCaseName;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "TestApp created");
+        mTestCaseName = getIntent().getStringExtra(Utils.TESTCASE_TYPE);
+        switch (mTestCaseName) {
+            case Utils.LARGE_VIEW_HIERARCHY:
+                setContentView(R.layout.multiple_text_views);
+                return;
+            default:
+                setContentView(R.layout.test_app);
+        }
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        Log.i(TAG, "TestApp has resumed");
+        final View layout = findViewById(android.R.id.content);
+        ViewTreeObserver vto = layout.getViewTreeObserver();
+        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                sendBroadcast(new Intent(Utils.APP_3P_HASRESUMED));
+            }
+        });
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/TextViewActivity.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/TextViewActivity.java
new file mode 100644
index 0000000..9e57e9b
--- /dev/null
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/TextViewActivity.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 android.assist.testapp;
+
+import android.assist.common.Utils;
+
+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.text.method.ScrollingMovementMethod;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import java.lang.Override;
+
+public class TextViewActivity extends Activity {
+    static final String TAG = "TextViewActivity";
+
+    private BroadcastReceiver mReceiver;
+    private TextView mTextView;
+    private ScrollView mScrollView;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "TextViewActivity created");
+        setContentView(R.layout.text_view);
+        mScrollView = (ScrollView) findViewById(R.id.scroll_view);
+        mTextView = (TextView) findViewById(R.id.text_view);
+        mTextView.setMovementMethod(new ScrollingMovementMethod());
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        Log.i(TAG, "TextViewActivity has resumed");
+
+        mReceiver = new ScrollReceiver();
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(Utils.SCROLL_TEXTVIEW_ACTION);
+        filter.addAction(Utils.SCROLL_SCROLLVIEW_ACTION);
+        registerReceiver(mReceiver, filter);
+
+        final View layout = findViewById(android.R.id.content);
+        ViewTreeObserver vto = layout.getViewTreeObserver();
+        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+            @Override
+            public void onGlobalLayout() {
+                layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+                sendBroadcast(new Intent(Utils.APP_3P_HASRESUMED));
+            }
+        });
+    }
+
+    @Override
+    public void onPause() {
+        if (mReceiver != null) {
+            unregisterReceiver(mReceiver);
+        }
+        super.onPause();
+    }
+
+    class ScrollReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            int scrollX, scrollY;
+            scrollX = intent.getIntExtra(Utils.SCROLL_X_POSITION, 0);
+            scrollY = intent.getIntExtra(Utils.SCROLL_Y_POSITION, 0);
+            if (intent.getAction().equals(Utils.SCROLL_TEXTVIEW_ACTION)) {
+                Log.i(TAG, "Scrolling textview to (" + scrollX + "," + scrollY + ")");
+                if (scrollX < 0 || scrollY < 0) {
+                    // Scroll to bottom as negative positions are not possible.
+                    scrollX = mTextView.getWidth();
+                    scrollY = mTextView.getLayout().getLineTop(mTextView.getLineCount())
+                            - mTextView.getHeight();
+                }
+                TextViewActivity.this.mTextView.scrollTo(scrollX, scrollY);
+            } else if (intent.getAction().equals(Utils.SCROLL_SCROLLVIEW_ACTION)) {
+                Log.i(TAG, "Scrolling scrollview to (" + scrollX + "," + scrollY + ")");
+                if (scrollX < 0 || scrollY < 0) {
+                    // Scroll to bottom
+                    TextViewActivity.this.mScrollView.fullScroll(View.FOCUS_DOWN);
+                    TextViewActivity.this.mScrollView.fullScroll(View.FOCUS_RIGHT);
+                } else {
+                    TextViewActivity.this.mScrollView.scrollTo(scrollX, scrollY);
+                }
+            }
+            Log.i(TAG, "the max height of this textview is: " + mTextView.getHeight());
+            Log.i(TAG, "the max line count of this text view is: " + mTextView.getMaxLines());
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/WebViewActivity.java b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/WebViewActivity.java
new file mode 100644
index 0000000..59f96cb
--- /dev/null
+++ b/tests/tests/assist/testapp/src/android/voiceinteraction/testapp/WebViewActivity.java
@@ -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.
+ */
+
+package android.assist.testapp;
+
+import android.assist.common.Utils;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import java.lang.Override;
+
+public class WebViewActivity extends Activity {
+    static final String TAG = "WebViewActivity";
+
+    private String mTestCaseName;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "TestApp created");
+        mTestCaseName = getIntent().getStringExtra(Utils.TESTCASE_TYPE);
+        setContentView(R.layout.webview);
+        WebView webview = (WebView) findViewById(R.id.webview);
+        webview.setWebViewClient(new WebViewClient() {
+            @Override
+            public void onPageFinished(WebView view, String url){
+                sendBroadcast(new Intent(Utils.APP_3P_HASRESUMED));
+            }
+        });
+        webview.loadData(Utils.WEBVIEW_HTML, "text/html", "UTF-8");
+        //webview.loadUrl(
+        //        "https://android-developers.blogspot.com/2015/08/m-developer-preview-3-final-sdk.html");
+    }
+}
diff --git a/tests/tests/bionic/Android.mk b/tests/tests/bionic/Android.mk
index e1afd50..06b7920 100644
--- a/tests/tests/bionic/Android.mk
+++ b/tests/tests/bionic/Android.mk
@@ -4,6 +4,7 @@
 list_executable := $(test_executable)_list
 
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_MODULE := $(test_executable)
 LOCAL_MODULE_TAGS := optional
@@ -12,25 +13,25 @@
 LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 
-LOCAL_ADDITION_DEPENDENCIES := \
-    $(LOCAL_PATH)/Android.mk \
-
 LOCAL_SHARED_LIBRARIES += \
-    libstlport \
     libdl \
 
 LOCAL_WHOLE_STATIC_LIBRARIES += \
     libBionicTests \
+    libBionicCtsGtestMain \
 
 LOCAL_STATIC_LIBRARIES += \
+    libbase \
+    libtinyxml2 \
+    liblog \
     libgtest \
-    libgtest_main \
 
 LOCAL_CTS_TEST_PACKAGE := android.bionic
 include $(BUILD_CTS_EXECUTABLE)
 
 ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := $(list_executable)
@@ -39,18 +40,19 @@
 LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 
-LOCAL_ADDITION_DEPENDENCIES := \
-    $(LOCAL_PATH)/Android.mk \
-
-# A main without the extra output from the gtest main.
-LOCAL_SRC_FILES := \
-    main.cpp \
-
 LOCAL_LDLIBS += \
-    -lrt \
+    -lrt -ldl -lutil \
 
 LOCAL_WHOLE_STATIC_LIBRARIES += \
     libBionicTests \
+    libBionicCtsGtestMain \
+
+LOCAL_STATIC_LIBRARIES += \
+    libbase \
+    liblog \
+    libcutils \
+
+LOCAL_CXX_STL := libc++
 
 include $(BUILD_HOST_NATIVE_TEST)
 endif  # ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
diff --git a/tests/tests/bionic/main.cpp b/tests/tests/bionic/main.cpp
deleted file mode 100644
index b661af4..0000000
--- a/tests/tests/bionic/main.cpp
+++ /dev/null
@@ -1,24 +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 <gtest/gtest.h>
-
-int main(int argc, char **argv) {
-  // Do not use gtest_main to avoid the Running main() ... output.
-  testing::InitGoogleTest(&argc, argv);
-
-  return RUN_ALL_TESTS();
-}
diff --git a/tests/tests/bluetooth/AndroidManifest.xml b/tests/tests/bluetooth/AndroidManifest.xml
index c9ad122..12838f3 100644
--- a/tests/tests/bluetooth/AndroidManifest.xml
+++ b/tests/tests/bluetooth/AndroidManifest.xml
@@ -19,6 +19,7 @@
 
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
 
     <application>
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/AdvertiseCallbackTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/AdvertiseCallbackTest.java
new file mode 100644
index 0000000..1c68022
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/AdvertiseCallbackTest.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 android.bluetooth.cts;
+
+import android.bluetooth.le.AdvertiseCallback;
+import android.bluetooth.le.AdvertiseSettings;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Test of {@link AdvertiseCallback}.
+ */
+public class AdvertiseCallbackTest extends AndroidTestCase {
+
+    private final static int ADVERTISE_TYPE_SUCCESS = 0;
+    private final static int ADVERTISE_TYPE_FAIL = 1;
+
+    private final MockAdvertiser mMockAdvertiser = new MockAdvertiser();
+    private final BleAdvertiseCallback mAdvertiseCallback = new BleAdvertiseCallback();
+
+    @SmallTest
+    public void testAdvertiseSuccess() {
+        mAdvertiseCallback.mAdvertiseType = ADVERTISE_TYPE_SUCCESS;
+        mMockAdvertiser.startAdvertise(mAdvertiseCallback);
+    }
+
+    @SmallTest
+    public void testAdvertiseFailure() {
+        mAdvertiseCallback.mAdvertiseType = ADVERTISE_TYPE_SUCCESS;
+        mMockAdvertiser.startAdvertise(mAdvertiseCallback);
+
+        // Second advertise with the same callback should fail.
+        mAdvertiseCallback.mAdvertiseType = ADVERTISE_TYPE_FAIL;
+        mMockAdvertiser.startAdvertise(mAdvertiseCallback);
+    }
+
+    // A mock advertiser which emulate BluetoothLeAdvertiser behavior.
+    private static class MockAdvertiser {
+        private Set<AdvertiseCallback> mCallbacks = new HashSet<>();
+
+        void startAdvertise(AdvertiseCallback callback) {
+            synchronized (mCallbacks) {
+                if (mCallbacks.contains(callback)) {
+                    callback.onStartFailure(AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
+                } else {
+                    callback.onStartSuccess(null);
+                    mCallbacks.add(callback);
+                }
+            }
+        }
+    }
+
+    private static class BleAdvertiseCallback extends AdvertiseCallback {
+        int mAdvertiseType = ADVERTISE_TYPE_SUCCESS;
+
+        @Override
+        public void onStartSuccess(AdvertiseSettings settings) {
+            if (mAdvertiseType == ADVERTISE_TYPE_FAIL) {
+                fail("advertise should fail");
+            }
+        }
+
+        @Override
+        public void onStartFailure(int error) {
+            if (mAdvertiseType == ADVERTISE_TYPE_SUCCESS) {
+                assertEquals(AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED, error);
+            }
+        }
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/AdvertiseDataTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/AdvertiseDataTest.java
new file mode 100644
index 0000000..3f2bf52
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/AdvertiseDataTest.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.bluetooth.cts;
+
+import android.bluetooth.le.AdvertiseData;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Unit test cases for {@link AdvertiseData}.
+ * <p>
+ * To run the test, use adb shell am instrument -e class 'android.bluetooth.le.AdvertiseDataTest' -w
+ * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
+ */
+public class AdvertiseDataTest extends AndroidTestCase {
+
+    private AdvertiseData.Builder mAdvertiseDataBuilder;
+
+    @Override
+    protected void setUp() {
+        mAdvertiseDataBuilder = new AdvertiseData.Builder();
+    }
+
+    @SmallTest
+    public void testEmptyData() {
+        Parcel parcel = Parcel.obtain();
+        AdvertiseData data = mAdvertiseDataBuilder.build();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AdvertiseData dataFromParcel =
+                AdvertiseData.CREATOR.createFromParcel(parcel);
+        assertEquals(data, dataFromParcel);
+        assertFalse(dataFromParcel.getIncludeDeviceName());
+        assertFalse(dataFromParcel.getIncludeTxPowerLevel());
+        assertEquals(0, dataFromParcel.getManufacturerSpecificData().size());
+        assertTrue(dataFromParcel.getServiceData().isEmpty());
+        assertTrue(dataFromParcel.getServiceUuids().isEmpty());
+    }
+
+    @SmallTest
+    public void testEmptyServiceUuid() {
+        Parcel parcel = Parcel.obtain();
+        AdvertiseData data = mAdvertiseDataBuilder.setIncludeDeviceName(true).build();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AdvertiseData dataFromParcel =
+                AdvertiseData.CREATOR.createFromParcel(parcel);
+        assertEquals(data, dataFromParcel);
+        assertTrue(dataFromParcel.getIncludeDeviceName());
+        assertTrue(dataFromParcel.getServiceUuids().isEmpty());
+    }
+
+    @SmallTest
+    public void testEmptyManufacturerData() {
+        Parcel parcel = Parcel.obtain();
+        int manufacturerId = 50;
+        byte[] manufacturerData = new byte[0];
+        AdvertiseData data =
+                mAdvertiseDataBuilder.setIncludeDeviceName(true)
+                        .addManufacturerData(manufacturerId, manufacturerData).build();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AdvertiseData dataFromParcel =
+                AdvertiseData.CREATOR.createFromParcel(parcel);
+        assertEquals(data, dataFromParcel);
+        TestUtils.assertArrayEquals(new byte[0], dataFromParcel.getManufacturerSpecificData().get(manufacturerId));
+    }
+
+    @SmallTest
+    public void testEmptyServiceData() {
+        Parcel parcel = Parcel.obtain();
+        ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+        byte[] serviceData = new byte[0];
+        AdvertiseData data =
+                mAdvertiseDataBuilder.setIncludeDeviceName(true)
+                        .addServiceData(uuid, serviceData).build();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AdvertiseData dataFromParcel =
+                AdvertiseData.CREATOR.createFromParcel(parcel);
+        assertEquals(data, dataFromParcel);
+        TestUtils.assertArrayEquals(new byte[0], dataFromParcel.getServiceData().get(uuid));
+    }
+
+    @SmallTest
+    public void testServiceUuid() {
+        Parcel parcel = Parcel.obtain();
+        ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+        ParcelUuid uuid2 = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+
+        AdvertiseData data =
+                mAdvertiseDataBuilder.setIncludeDeviceName(true)
+                        .addServiceUuid(uuid).addServiceUuid(uuid2).build();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AdvertiseData dataFromParcel =
+                AdvertiseData.CREATOR.createFromParcel(parcel);
+        assertEquals(data, dataFromParcel);
+        assertTrue(dataFromParcel.getServiceUuids().contains(uuid));
+        assertTrue(dataFromParcel.getServiceUuids().contains(uuid2));
+    }
+
+    @SmallTest
+    public void testManufacturerData() {
+        Parcel parcel = Parcel.obtain();
+        ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+        ParcelUuid uuid2 = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+
+        int manufacturerId = 50;
+        byte[] manufacturerData = new byte[] {
+                (byte) 0xF0, 0x00, 0x02, 0x15 };
+        AdvertiseData data =
+                mAdvertiseDataBuilder.setIncludeDeviceName(true)
+                        .addServiceUuid(uuid).addServiceUuid(uuid2)
+                        .addManufacturerData(manufacturerId, manufacturerData).build();
+
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AdvertiseData dataFromParcel =
+                AdvertiseData.CREATOR.createFromParcel(parcel);
+        assertEquals(data, dataFromParcel);
+        TestUtils.assertArrayEquals(manufacturerData,
+                dataFromParcel.getManufacturerSpecificData().get(manufacturerId));
+    }
+
+    @SmallTest
+    public void testServiceData() {
+        Parcel parcel = Parcel.obtain();
+        ParcelUuid uuid = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+        byte[] serviceData = new byte[] {
+                (byte) 0xF0, 0x00, 0x02, 0x15 };
+        AdvertiseData data =
+                mAdvertiseDataBuilder.setIncludeDeviceName(true)
+                        .addServiceData(uuid, serviceData).build();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AdvertiseData dataFromParcel =
+                AdvertiseData.CREATOR.createFromParcel(parcel);
+        assertEquals(data, dataFromParcel);
+        TestUtils.assertArrayEquals(serviceData, dataFromParcel.getServiceData().get(uuid));
+    }
+
+    @SmallTest
+    public void testIncludeTxPower() {
+        Parcel parcel = Parcel.obtain();
+        AdvertiseData data = mAdvertiseDataBuilder.setIncludeTxPowerLevel(true).build();
+        data.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AdvertiseData dataFromParcel =
+                AdvertiseData.CREATOR.createFromParcel(parcel);
+        assertEquals(dataFromParcel.getIncludeTxPowerLevel(), true);
+    }
+
+    @SmallTest
+    public void testDescribeContents() {
+        AdvertiseData data = new AdvertiseData.Builder().build();
+        assertEquals(0, data.describeContents());
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/AdvertiseSettingsTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/AdvertiseSettingsTest.java
new file mode 100644
index 0000000..19b7c29
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/AdvertiseSettingsTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.cts;
+
+import android.bluetooth.le.AdvertiseSettings;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Test for {@link AdvertiseSettings}.
+ */
+public class AdvertiseSettingsTest extends AndroidTestCase {
+
+    @SmallTest
+    public void testDefaultSettings() {
+        AdvertiseSettings settings = new AdvertiseSettings.Builder().build();
+        assertEquals(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER, settings.getMode());
+        assertEquals(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM, settings.getTxPowerLevel());
+        assertEquals(0, settings.getTimeout());
+        assertTrue(settings.isConnectable());
+    }
+
+    @SmallTest
+    public void testDescribeContents() {
+        AdvertiseSettings settings = new AdvertiseSettings.Builder().build();
+        assertEquals(0, settings.describeContents());
+    }
+
+    @SmallTest
+    public void testReadWriteParcel() {
+        final int timeoutMillis = 60 * 1000;
+        Parcel parcel = Parcel.obtain();
+        AdvertiseSettings settings = new AdvertiseSettings.Builder()
+                .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY)
+                .setConnectable(false)
+                .setTimeout(timeoutMillis)
+                .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
+                .build();
+        settings.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        AdvertiseSettings settingsFromParcel = AdvertiseSettings.CREATOR.createFromParcel(parcel);
+        assertEquals(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY, settingsFromParcel.getMode());
+        assertEquals(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM,
+                settingsFromParcel.getTxPowerLevel());
+        assertEquals(timeoutMillis, settingsFromParcel.getTimeout());
+        assertFalse(settings.isConnectable());
+    }
+
+    @SmallTest
+    public void testIllegalTimeout() {
+        AdvertiseSettings.Builder builder = new AdvertiseSettings.Builder();
+        builder.setTimeout(0).build();
+        builder.setTimeout(180 * 1000).build();
+        // Maximum timeout is 3 minutes.
+        try {
+            builder.setTimeout(180 * 1000 + 1).build();
+            fail("should not allow setting timeout to more than 3 minutes");
+        } catch (IllegalArgumentException e) {
+            // nothing to do.
+        }
+        // Negative time out is not allowed.
+        try {
+            builder.setTimeout(-1).build();
+            fail("should not allow setting timeout to more than 3 minutes");
+        } catch (IllegalArgumentException e) {
+            // nothing to do.
+        }
+
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
new file mode 100644
index 0000000..bc819c1
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/BluetoothLeScanTest.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.cts;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothManager;
+import android.bluetooth.le.BluetoothLeScanner;
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanRecord;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.ParcelUuid;
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test cases for Bluetooth LE scans.
+ * <p>
+ * To run the test, the device must be placed in an environment that has at least 3 beacons, all
+ * placed less than 5 meters away from the DUT.
+ * <p>
+ * Run 'run cts --class android.bluetooth.cts.BluetoothLeScanTest' in cts-tradefed to run the test
+ * cases.
+ */
+public class BluetoothLeScanTest extends AndroidTestCase {
+
+    private static final String TAG = "BluetoothLeScanTest";
+
+    private static final int SCAN_DURATION_MILLIS = 5000;
+    private static final int BATCH_SCAN_REPORT_DELAY_MILLIS = 20000;
+    private CountDownLatch mFlushBatchScanLatch;
+
+    private BluetoothAdapter mBluetoothAdapter;
+    private BluetoothLeScanner mScanner;
+
+    @Override
+    public void setUp() {
+        if (!isBleSupported())
+            return;
+        BluetoothManager manager = (BluetoothManager) mContext.getSystemService(
+                Context.BLUETOOTH_SERVICE);
+        mBluetoothAdapter = manager.getAdapter();
+        if (!mBluetoothAdapter.isEnabled()) {
+            // Note it's not reliable to listen for Adapter.ACTION_STATE_CHANGED broadcast and check
+            // bluetooth state.
+            mBluetoothAdapter.enable();
+            sleep(3000);
+        }
+        mScanner = mBluetoothAdapter.getBluetoothLeScanner();
+    }
+
+    /**
+     * Basic test case for BLE scans. Checks BLE scan timestamp is within correct range.
+     */
+    @MediumTest
+    public void testBasicBleScan() {
+        if (!isBleSupported())
+            return;
+        long scanStartMillis = SystemClock.elapsedRealtime();
+        Collection<ScanResult> scanResults = scan();
+        long scanEndMillis = SystemClock.elapsedRealtime();
+        assertTrue("Scan results shouldn't be empty", !scanResults.isEmpty());
+        verifyTimestamp(scanResults, scanStartMillis, scanEndMillis);
+    }
+
+    /**
+     * Test of scan filters. Ensures only beacons matching certain type of scan filters were
+     * reported.
+     */
+    @MediumTest
+    public void testScanFilter() {
+        if (!isBleSupported())
+            return;
+
+        List<ScanFilter> filters = new ArrayList<ScanFilter>();
+        ScanFilter filter = createScanFilter();
+        if (filter == null) {
+            Log.d(TAG, "no appropriate filter can be set");
+            return;
+        }
+        filters.add(filter);
+
+        BleScanCallback filterLeScanCallback = new BleScanCallback();
+        ScanSettings settings = new ScanSettings.Builder().setScanMode(
+                ScanSettings.SCAN_MODE_LOW_LATENCY).build();
+        mScanner.startScan(filters, settings, filterLeScanCallback);
+        sleep(SCAN_DURATION_MILLIS);
+        mScanner.stopScan(filterLeScanCallback);
+        sleep(1000);
+        Collection<ScanResult> scanResults = filterLeScanCallback.getScanResults();
+        for (ScanResult result : scanResults) {
+            assertTrue(filter.matches(result));
+        }
+    }
+
+    // Create a scan filter based on the nearby beacon with highest signal strength.
+    private ScanFilter createScanFilter() {
+        // Get a list of nearby beacons.
+        List<ScanResult> scanResults = new ArrayList<ScanResult>(scan());
+        assertTrue("Scan results shouldn't be empty", !scanResults.isEmpty());
+        // Find the beacon with strongest signal strength, which is the target device for filter
+        // scan.
+        Collections.sort(scanResults, new RssiComparator());
+        ScanResult result = scanResults.get(0);
+        ScanRecord record = result.getScanRecord();
+        if (record == null) {
+            return null;
+        }
+        Map<ParcelUuid, byte[]> serviceData = record.getServiceData();
+        if (serviceData != null && !serviceData.isEmpty()) {
+            ParcelUuid uuid = serviceData.keySet().iterator().next();
+            return new ScanFilter.Builder().setServiceData(uuid, new byte[] { 0 },
+                    new byte[] { 0 }).build();
+        }
+        SparseArray<byte[]> manufacturerSpecificData = record.getManufacturerSpecificData();
+        if (manufacturerSpecificData != null && manufacturerSpecificData.size() > 0) {
+            return new ScanFilter.Builder().setManufacturerData(manufacturerSpecificData.keyAt(0),
+                    new byte[] { 0 }, new byte[] { 0 }).build();
+        }
+        List<ParcelUuid> serviceUuids = record.getServiceUuids();
+        if (serviceUuids != null && !serviceUuids.isEmpty()) {
+            return new ScanFilter.Builder().setServiceUuid(serviceUuids.get(0)).build();
+        }
+        return null;
+    }
+
+    /**
+     * Test of opportunistic BLE scans.
+     */
+    @MediumTest
+    public void testOpportunisticScan() {
+        if (!isBleSupported())
+            return;
+        ScanSettings opportunisticScanSettings = new ScanSettings.Builder()
+                .setScanMode(ScanSettings.SCAN_MODE_OPPORTUNISTIC)
+                .build();
+        BleScanCallback emptyScanCallback = new BleScanCallback();
+
+        // No scans are really started with opportunistic scans only.
+        mScanner.startScan(Collections.<ScanFilter> emptyList(), opportunisticScanSettings,
+                emptyScanCallback);
+        sleep(SCAN_DURATION_MILLIS);
+        assertTrue(emptyScanCallback.getScanResults().isEmpty());
+
+        BleScanCallback regularScanCallback = new BleScanCallback();
+        ScanSettings regularScanSettings = new ScanSettings.Builder()
+                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
+        List<ScanFilter> filters = new ArrayList<>();
+        ScanFilter filter = createScanFilter();
+        if (filter != null) {
+            filters.add(filter);
+        } else {
+            Log.d(TAG, "no appropriate filter can be set");
+        }
+        mScanner.startScan(filters, regularScanSettings, regularScanCallback);
+        sleep(SCAN_DURATION_MILLIS);
+        // With normal BLE scan client, opportunistic scan client will get scan results.
+        assertTrue("opportunistic scan results shouldn't be empty",
+                !emptyScanCallback.getScanResults().isEmpty());
+
+        // No more scan results for opportunistic scan clients once the normal BLE scan clients
+        // stops.
+        mScanner.stopScan(regularScanCallback);
+        // In case we got scan results before scan was completely stopped.
+        sleep(1000);
+        emptyScanCallback.clear();
+        sleep(SCAN_DURATION_MILLIS);
+        assertTrue("opportunistic scan shouldn't have scan results",
+                emptyScanCallback.getScanResults().isEmpty());
+    }
+
+    /**
+     * Test case for BLE Batch scan.
+     */
+    @MediumTest
+    public void testBatchScan() {
+        if (!isBleSupported() || !isBleBatchScanSupported()) {
+            Log.d(TAG, "BLE or BLE batching not suppported");
+            return;
+        }
+        ScanSettings batchScanSettings = new ScanSettings.Builder()
+                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
+                .setReportDelay(BATCH_SCAN_REPORT_DELAY_MILLIS).build();
+        BleScanCallback batchScanCallback = new BleScanCallback();
+        mScanner.startScan(Collections.<ScanFilter> emptyList(), batchScanSettings,
+                batchScanCallback);
+        sleep(SCAN_DURATION_MILLIS);
+        mScanner.flushPendingScanResults(batchScanCallback);
+        mFlushBatchScanLatch = new CountDownLatch(1);
+        List<ScanResult> results = batchScanCallback.getBatchScanResults();
+        try {
+            mFlushBatchScanLatch.await(5, TimeUnit.SECONDS);
+        } catch (InterruptedException e) {
+            // Nothing to do.
+            Log.e(TAG, "interrupted!");
+        }
+        assertTrue(!results.isEmpty());
+        long scanEndMillis = SystemClock.elapsedRealtime();
+        mScanner.stopScan(batchScanCallback);
+        verifyTimestamp(results, 0, scanEndMillis);
+    }
+
+    // Verify timestamp of all scan results are within [scanStartMillis, scanEndMillis].
+    private void verifyTimestamp(Collection<ScanResult> results, long scanStartMillis,
+            long scanEndMillis) {
+        for (ScanResult result : results) {
+            long timestampMillis = TimeUnit.NANOSECONDS.toMillis(result.getTimestampNanos());
+            assertTrue("Invalid timestamp: " + timestampMillis + " should be >= " + scanStartMillis,
+                    timestampMillis >= scanStartMillis);
+            assertTrue("Invalid timestamp: " + timestampMillis + " should be <= " + scanEndMillis,
+                    timestampMillis <= scanEndMillis);
+        }
+    }
+
+    // Helper class for BLE scan callback.
+    private class BleScanCallback extends ScanCallback {
+        private Set<ScanResult> mResults = new HashSet<ScanResult>();
+        private List<ScanResult> mBatchScanResults = new ArrayList<ScanResult>();
+
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            if (callbackType == ScanSettings.CALLBACK_TYPE_ALL_MATCHES) {
+                mResults.add(result);
+            }
+        }
+
+        @Override
+        public void onBatchScanResults(List<ScanResult> results) {
+            // In case onBatchScanResults are called due to buffer full, we want to collect all
+            // scan results.
+            mBatchScanResults.addAll(results);
+            if (mFlushBatchScanLatch != null) {
+                mFlushBatchScanLatch.countDown();
+            }
+        }
+
+        // Clear regular and batch scan results.
+        synchronized public void clear() {
+            mResults.clear();
+            mBatchScanResults.clear();
+        }
+
+        // Return regular BLE scan results accumulated so far.
+        synchronized Set<ScanResult> getScanResults() {
+            return Collections.unmodifiableSet(mResults);
+        }
+
+        // Return batch scan results.
+        synchronized List<ScanResult> getBatchScanResults() {
+            return Collections.unmodifiableList(mBatchScanResults);
+        }
+    }
+
+    private class RssiComparator implements Comparator<ScanResult> {
+
+        @Override
+        public int compare(ScanResult lhs, ScanResult rhs) {
+            return rhs.getRssi() - lhs.getRssi();
+        }
+
+    }
+
+    // Perform a BLE scan to get results of nearby BLE devices.
+    private Set<ScanResult> scan() {
+        BleScanCallback regularLeScanCallback = new BleScanCallback();
+        mScanner.startScan(regularLeScanCallback);
+        sleep(SCAN_DURATION_MILLIS);
+        mScanner.stopScan(regularLeScanCallback);
+        sleep(1000);
+        return regularLeScanCallback.getScanResults();
+    }
+
+    // Put the current thread to sleep.
+    private void sleep(int sleepMillis) {
+        try {
+            Thread.sleep(sleepMillis);
+        } catch (InterruptedException e) {
+            Log.e(TAG, "interrupted", e);
+        }
+    }
+
+    // Check if Bluetooth LE feature is supported on DUT.
+    private boolean isBleSupported() {
+        return getContext().getPackageManager()
+                .hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
+    }
+
+    // Returns whether offloaded scan batching is supported.
+    private boolean isBleBatchScanSupported() {
+        return mBluetoothAdapter.isOffloadedScanBatchingSupported();
+    }
+
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanCallbackTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanCallbackTest.java
new file mode 100644
index 0000000..f447f10
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanCallbackTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.cts;
+
+import android.bluetooth.le.ScanCallback;
+import android.bluetooth.le.ScanResult;
+import android.bluetooth.le.ScanSettings;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Test cases for {@link ScanCallback}.
+ */
+public class ScanCallbackTest extends AndroidTestCase {
+
+    // Scan types are used to determine which callback method is expected.
+    private final static int SCAN_TYPE_SUCCESS = 0;
+    private final static int SCAN_TYPE_FAIL = 1;
+    private final static int SCAN_TYPE_BATCH = 2;
+
+    private MockScanner mMockScanner = new MockScanner();
+    private BleScanCallback mMockScanCallback = new BleScanCallback();
+
+    @SmallTest
+    public void testScanSuccess() {
+        mMockScanCallback.mScanType = SCAN_TYPE_SUCCESS;
+        mMockScanner.startScan(new ScanSettings.Builder().build(), mMockScanCallback);
+    }
+
+    @SmallTest
+    public void testBatchScans() {
+        ScanSettings settings = new ScanSettings.Builder().setReportDelay(1000).build();
+        mMockScanCallback.mScanType = SCAN_TYPE_BATCH;
+        mMockScanner.startScan(settings, mMockScanCallback);
+    }
+
+    @SmallTest
+    public void testScanFail() {
+        ScanSettings settings = new ScanSettings.Builder().build();
+        // The first scan is success.
+        mMockScanCallback.mScanType = SCAN_TYPE_SUCCESS;
+        mMockScanner.startScan(settings, mMockScanCallback);
+        // A second scan with the same callback should fail.
+        mMockScanCallback.mScanType = SCAN_TYPE_FAIL;
+        mMockScanner.startScan(settings, mMockScanCallback);
+    }
+
+    // A mock scanner for mocking BLE scanner functionalities.
+    private static class MockScanner {
+        private Set<ScanCallback> mCallbacks = new HashSet<>();
+
+        void startScan(ScanSettings settings, ScanCallback callback) {
+            synchronized (mCallbacks) {
+                if (mCallbacks.contains(callback)) {
+                    callback.onScanFailed(ScanCallback.SCAN_FAILED_ALREADY_STARTED);
+                    return;
+                }
+                mCallbacks.add(callback);
+                if (settings.getReportDelayMillis() == 0) {
+                    callback.onScanResult(0, null);
+                } else {
+                    callback.onBatchScanResults(null);
+                }
+            }
+        }
+    }
+
+    private static class BleScanCallback extends ScanCallback {
+        int mScanType = SCAN_TYPE_SUCCESS;
+
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            if (mScanType != SCAN_TYPE_SUCCESS) {
+                fail("scan should fail");
+            }
+        }
+
+        @Override
+        public void onBatchScanResults(List<ScanResult> results) {
+            if (mScanType != SCAN_TYPE_BATCH) {
+                fail("not a batch scan");
+            }
+        }
+
+        @Override
+        public void onScanFailed(int errorCode) {
+            if (mScanType != SCAN_TYPE_FAIL) {
+                fail("scan should not fail");
+            }
+        }
+
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java
new file mode 100644
index 0000000..16e1413
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanFilterTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.cts;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanFilter;
+import android.bluetooth.le.ScanResult;
+import android.os.Parcel;
+import android.os.ParcelUuid;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Unit test cases for Bluetooth LE scan filters.
+ * <p>
+ * To run this test, use adb shell am instrument -e class 'android.bluetooth.ScanFilterTest' -w
+ * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
+ */
+public class ScanFilterTest extends AndroidTestCase {
+
+    private static final String LOCAL_NAME = "Ped";
+    private static final String DEVICE_MAC = "01:02:03:04:05:AB";
+    private static final String UUID1 = "0000110a-0000-1000-8000-00805f9b34fb";
+    private static final String UUID2 = "0000110b-0000-1000-8000-00805f9b34fb";
+    private static final String UUID3 = "0000110c-0000-1000-8000-00805f9b34fb";
+
+    private ScanResult mScanResult;
+    private ScanFilter.Builder mFilterBuilder;
+
+    @Override
+    protected void setUp() {
+        byte[] scanRecord = new byte[] {
+                0x02, 0x01, 0x1a, // advertising flags
+                0x05, 0x02, 0x0b, 0x11, 0x0a, 0x11, // 16 bit service uuids
+                0x04, 0x09, 0x50, 0x65, 0x64, // setName
+                0x02, 0x0A, (byte) 0xec, // tx power level
+                0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data
+                0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data
+                0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble
+        };
+
+        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+        BluetoothDevice device = adapter.getRemoteDevice(DEVICE_MAC);
+        mScanResult = new ScanResult(device, TestUtils.parseScanRecord(scanRecord),
+                -10, 1397545200000000L);
+        mFilterBuilder = new ScanFilter.Builder();
+    }
+
+    @SmallTest
+    public void testsetNameFilter() {
+        ScanFilter filter = mFilterBuilder.setDeviceName(LOCAL_NAME).build();
+        assertEquals(LOCAL_NAME, filter.getDeviceName());
+        assertTrue("setName filter fails", filter.matches(mScanResult));
+
+        filter = mFilterBuilder.setDeviceName("Pem").build();
+        assertFalse("setName filter fails", filter.matches(mScanResult));
+    }
+
+    @SmallTest
+    public void testDeviceAddressFilter() {
+        ScanFilter filter = mFilterBuilder.setDeviceAddress(DEVICE_MAC).build();
+        assertEquals(DEVICE_MAC, filter.getDeviceAddress());
+        assertTrue("device filter fails", filter.matches(mScanResult));
+
+        filter = mFilterBuilder.setDeviceAddress("11:22:33:44:55:66").build();
+        assertFalse("device filter fails", filter.matches(mScanResult));
+    }
+
+    @SmallTest
+    public void testsetServiceUuidFilter() {
+        ScanFilter filter = mFilterBuilder.setServiceUuid(
+                ParcelUuid.fromString(UUID1)).build();
+        assertEquals(UUID1, filter.getServiceUuid().toString());
+        assertTrue("uuid filter fails", filter.matches(mScanResult));
+
+        filter = mFilterBuilder.setServiceUuid(
+                ParcelUuid.fromString(UUID3)).build();
+        assertEquals(UUID3, filter.getServiceUuid().toString());
+        assertFalse("uuid filter fails", filter.matches(mScanResult));
+
+        ParcelUuid mask = ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF");
+        filter = mFilterBuilder
+                .setServiceUuid(ParcelUuid.fromString(UUID3),
+                        mask)
+                .build();
+        assertEquals(mask.toString(), filter.getServiceUuidMask().toString());
+        assertTrue("uuid filter fails", filter.matches(mScanResult));
+    }
+
+    @SmallTest
+    public void testsetServiceDataFilter() {
+        byte[] setServiceData = new byte[] {
+                0x50, 0x64 };
+        ParcelUuid serviceDataUuid = ParcelUuid.fromString(UUID2);
+        ScanFilter filter = mFilterBuilder.setServiceData(serviceDataUuid, setServiceData).build();
+        assertEquals(serviceDataUuid, filter.getServiceDataUuid());
+        assertTrue("service data filter fails", filter.matches(mScanResult));
+
+        byte[] emptyData = new byte[0];
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, emptyData).build();
+        assertTrue("service data filter fails", filter.matches(mScanResult));
+
+        byte[] prefixData = new byte[] {
+                0x50 };
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, prefixData).build();
+        assertTrue("service data filter fails", filter.matches(mScanResult));
+
+        byte[] nonMatchData = new byte[] {
+                0x51, 0x64 };
+        byte[] mask = new byte[] {
+                (byte) 0x00, (byte) 0xFF };
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData, mask).build();
+        assertEquals(nonMatchData, filter.getServiceData());
+        assertEquals(mask, filter.getServiceDataMask());
+        assertTrue("partial service data filter fails", filter.matches(mScanResult));
+
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, nonMatchData).build();
+        assertFalse("service data filter fails", filter.matches(mScanResult));
+    }
+
+    @SmallTest
+    public void testManufacturerSpecificData() {
+        byte[] manufacturerData = new byte[] {
+                0x02, 0x15 };
+        int manufacturerId = 0xE0;
+        ScanFilter filter =
+                mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData).build();
+        assertEquals(manufacturerId, filter.getManufacturerId());
+        assertEquals(manufacturerData, filter.getManufacturerData());
+        assertTrue("manufacturer data filter fails", filter.matches(mScanResult));
+
+        byte[] emptyData = new byte[0];
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, emptyData).build();
+        assertTrue("manufacturer data filter fails", filter.matches(mScanResult));
+
+        byte[] prefixData = new byte[] {
+                0x02 };
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, prefixData).build();
+        assertTrue("manufacturer data filter fails", filter.matches(mScanResult));
+
+        // Test data mask
+        byte[] nonMatchData = new byte[] {
+                0x02, 0x14 };
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData).build();
+        assertFalse("manufacturer data filter fails", filter.matches(mScanResult));
+        byte[] mask = new byte[] {
+                (byte) 0xFF, (byte) 0x00
+        };
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, nonMatchData, mask).build();
+        assertEquals(manufacturerId, filter.getManufacturerId());
+        assertEquals(nonMatchData, filter.getManufacturerData());
+        assertEquals(mask, filter.getManufacturerDataMask());
+        assertTrue("partial setManufacturerData filter fails", filter.matches(mScanResult));
+    }
+
+    @SmallTest
+    public void testReadWriteParcel() {
+        ScanFilter filter = mFilterBuilder.build();
+        testReadWriteParcelForFilter(filter);
+
+        filter = mFilterBuilder.setDeviceName(LOCAL_NAME).build();
+        testReadWriteParcelForFilter(filter);
+
+        filter = mFilterBuilder.setDeviceAddress("11:22:33:44:55:66").build();
+        testReadWriteParcelForFilter(filter);
+
+        filter = mFilterBuilder.setServiceUuid(
+                ParcelUuid.fromString(UUID3)).build();
+        testReadWriteParcelForFilter(filter);
+
+        filter = mFilterBuilder.setServiceUuid(
+                ParcelUuid.fromString(UUID3),
+                ParcelUuid.fromString("FFFFFFF0-FFFF-FFFF-FFFF-FFFFFFFFFFFF")).build();
+        testReadWriteParcelForFilter(filter);
+
+        byte[] serviceData = new byte[] {
+                0x50, 0x64 };
+
+        ParcelUuid serviceDataUuid = ParcelUuid.fromString(UUID2);
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData).build();
+        testReadWriteParcelForFilter(filter);
+
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build();
+        testReadWriteParcelForFilter(filter);
+
+        byte[] serviceDataMask = new byte[] {
+                (byte) 0xFF, (byte) 0xFF };
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, serviceData, serviceDataMask)
+                .build();
+        testReadWriteParcelForFilter(filter);
+
+        byte[] manufacturerData = new byte[] {
+                0x02, 0x15 };
+        int manufacturerId = 0xE0;
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData).build();
+        testReadWriteParcelForFilter(filter);
+
+        filter = mFilterBuilder.setServiceData(serviceDataUuid, new byte[0]).build();
+        testReadWriteParcelForFilter(filter);
+
+        byte[] manufacturerDataMask = new byte[] {
+                (byte) 0xFF, (byte) 0xFF
+        };
+        filter = mFilterBuilder.setManufacturerData(manufacturerId, manufacturerData,
+                manufacturerDataMask).build();
+        testReadWriteParcelForFilter(filter);
+    }
+
+    @SmallTest
+    public void testDescribeContents() {
+        final int expected = 0;
+        assertEquals(expected, new ScanFilter.Builder().build().describeContents());
+    }
+
+    private void testReadWriteParcelForFilter(ScanFilter filter) {
+        Parcel parcel = Parcel.obtain();
+        filter.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ScanFilter filterFromParcel =
+                ScanFilter.CREATOR.createFromParcel(parcel);
+        assertEquals(filter, filterFromParcel);
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java
new file mode 100644
index 0000000..30ad06f
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanRecordTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.bluetooth.cts;
+
+import android.bluetooth.le.ScanRecord;
+import android.os.ParcelUuid;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Unit test cases for {@link ScanRecord}.
+ * <p>
+ * To run this test, use adb shell am instrument -e class 'android.bluetooth.ScanRecordTest' -w
+ * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
+ */
+public class ScanRecordTest extends AndroidTestCase {
+
+    @SmallTest
+    public void testParser() {
+        byte[] scanRecord = new byte[] {
+                0x02, 0x01, 0x1a, // advertising flags
+                0x05, 0x02, 0x0b, 0x11, 0x0a, 0x11, // 16 bit service uuids
+                0x04, 0x09, 0x50, 0x65, 0x64, // name
+                0x02, 0x0A, (byte) 0xec, // tx power level
+                0x05, 0x16, 0x0b, 0x11, 0x50, 0x64, // service data
+                0x05, (byte) 0xff, (byte) 0xe0, 0x00, 0x02, 0x15, // manufacturer specific data
+                0x03, 0x50, 0x01, 0x02, // an unknown data type won't cause trouble
+        };
+        ScanRecord data = TestUtils.parseScanRecord(scanRecord);
+        assertEquals(0x1a, data.getAdvertiseFlags());
+        ParcelUuid uuid1 = ParcelUuid.fromString("0000110A-0000-1000-8000-00805F9B34FB");
+        ParcelUuid uuid2 = ParcelUuid.fromString("0000110B-0000-1000-8000-00805F9B34FB");
+        assertTrue(data.getServiceUuids().contains(uuid1));
+        assertTrue(data.getServiceUuids().contains(uuid2));
+
+        assertEquals("Ped", data.getDeviceName());
+        assertEquals(-20, data.getTxPowerLevel());
+
+        assertTrue(data.getManufacturerSpecificData().get(0x00E0) != null);
+
+        final byte[] manufacturerData = new byte[] {
+                0x02, 0x15 };
+        TestUtils.assertArrayEquals(manufacturerData,
+                data.getManufacturerSpecificData().get(0x00E0));
+        TestUtils.assertArrayEquals(manufacturerData, data.getManufacturerSpecificData(0x00E0));
+
+        assertTrue(data.getServiceData().containsKey(uuid2));
+        final byte[] serviceData = new byte[] {
+                0x50, 0x64 };
+        TestUtils.assertArrayEquals(serviceData, data.getServiceData().get(uuid2));
+        TestUtils.assertArrayEquals(serviceData, data.getServiceData(uuid2));
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanResultTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanResultTest.java
new file mode 100644
index 0000000..91da8c3
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanResultTest.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.bluetooth.cts;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.le.ScanResult;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Unit test cases for Bluetooth LE scans.
+ * <p>
+ * To run this test, use adb shell am instrument -e class 'android.bluetooth.ScanResultTest' -w
+ * 'com.android.bluetooth.tests/android.bluetooth.BluetoothTestRunner'
+ */
+public class ScanResultTest extends AndroidTestCase {
+    private static final String DEVICE_ADDRESS = "01:02:03:04:05:06";
+    private static final byte[] SCAN_RECORD = new byte[] {
+            1, 2, 3 };
+    private static final int RSSI = -10;
+    private static final long TIMESTAMP_NANOS = 10000L;
+
+    /**
+     * Test read and write parcel of ScanResult
+     */
+    @SmallTest
+    public void testScanResultParceling() {
+        BluetoothDevice device =
+                BluetoothAdapter.getDefaultAdapter().getRemoteDevice(DEVICE_ADDRESS);
+        ScanResult result = new ScanResult(device, TestUtils.parseScanRecord(SCAN_RECORD), RSSI,
+                TIMESTAMP_NANOS);
+        Parcel parcel = Parcel.obtain();
+        result.writeToParcel(parcel, 0);
+        // Need to reset parcel data position to the beginning.
+        parcel.setDataPosition(0);
+        ScanResult resultFromParcel = ScanResult.CREATOR.createFromParcel(parcel);
+
+        assertEquals(RSSI, resultFromParcel.getRssi());
+        assertEquals(TIMESTAMP_NANOS, resultFromParcel.getTimestampNanos());
+        assertEquals(device, resultFromParcel.getDevice());
+        TestUtils.assertArrayEquals(SCAN_RECORD, resultFromParcel.getScanRecord().getBytes());
+    }
+
+    @SmallTest
+    public void testDescribeContents() {
+        BluetoothDevice device =
+                BluetoothAdapter.getDefaultAdapter().getRemoteDevice(DEVICE_ADDRESS);
+        ScanResult result = new ScanResult(device, TestUtils.parseScanRecord(SCAN_RECORD), RSSI,
+                TIMESTAMP_NANOS);
+        assertEquals(0, result.describeContents());
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/ScanSettingsTest.java b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanSettingsTest.java
new file mode 100644
index 0000000..7033c3c
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/ScanSettingsTest.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.bluetooth.cts;
+
+import android.bluetooth.le.ScanSettings;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Test for Bluetooth LE {@link ScanSettings}.
+ */
+public class ScanSettingsTest extends AndroidTestCase {
+
+    @SmallTest
+    public void testDefaultSettings() {
+        ScanSettings settings = new ScanSettings.Builder().build();
+        assertEquals(ScanSettings.CALLBACK_TYPE_ALL_MATCHES, settings.getCallbackType());
+        assertEquals(ScanSettings.SCAN_MODE_LOW_POWER, settings.getScanMode());
+        assertEquals(0, settings.getScanResultType());
+        assertEquals(0, settings.getReportDelayMillis());
+    }
+
+    @SmallTest
+    public void testDescribeContents() {
+        ScanSettings settings = new ScanSettings.Builder().build();
+        assertEquals(0, settings.describeContents());
+    }
+
+    @SmallTest
+    public void testReadWriteParcel() {
+        final long reportDelayMillis = 60 * 1000;
+        Parcel parcel = Parcel.obtain();
+        ScanSettings settings = new ScanSettings.Builder()
+                .setReportDelay(reportDelayMillis)
+                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
+                .setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
+                .setNumOfMatches(ScanSettings.MATCH_NUM_MAX_ADVERTISEMENT)
+                .build();
+        settings.writeToParcel(parcel, 0);
+        parcel.setDataPosition(0);
+        ScanSettings settingsFromParcel = ScanSettings.CREATOR.createFromParcel(parcel);
+        assertEquals(reportDelayMillis, settingsFromParcel.getReportDelayMillis());
+        assertEquals(ScanSettings.SCAN_MODE_LOW_LATENCY, settings.getScanMode());
+    }
+}
diff --git a/tests/tests/bluetooth/src/android/bluetooth/cts/TestUtils.java b/tests/tests/bluetooth/src/android/bluetooth/cts/TestUtils.java
new file mode 100644
index 0000000..7c5db9e
--- /dev/null
+++ b/tests/tests/bluetooth/src/android/bluetooth/cts/TestUtils.java
@@ -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.
+ */
+
+package android.bluetooth.cts;
+
+import android.bluetooth.le.ScanRecord;
+
+import junit.framework.Assert;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+
+/**
+ * Utility class for Bluetooth CTS test.
+ */
+class TestUtils {
+
+    /**
+     * Utility method to call hidden ScanRecord.parseFromBytes method.
+     */
+    static ScanRecord parseScanRecord(byte[] bytes) {
+        Class<?> scanRecordClass = ScanRecord.class;
+        try {
+            Method method = scanRecordClass.getDeclaredMethod("parseFromBytes", byte[].class);
+            return (ScanRecord)method.invoke(null, bytes);
+        } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException
+                | InvocationTargetException e) {
+            return null;
+        }
+    }
+
+    // Assert two byte arrays are equal.
+    static void assertArrayEquals(byte[] expected, byte[] actual) {
+        if (!Arrays.equals(expected, actual)) {
+            Assert.fail("expected:<" + Arrays.toString(expected) +
+                    "> but was:<" + Arrays.toString(actual) + ">");
+        }
+    }
+}
diff --git a/tests/tests/calllog/Android.mk b/tests/tests/calllog/Android.mk
new file mode 100644
index 0000000..6a7e96a
--- /dev/null
+++ b/tests/tests/calllog/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_PACKAGE_NAME := CtsCallLogTestCases
+
+# 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 := bouncycastle
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/calllog/AndroidManifest.xml b/tests/tests/calllog/AndroidManifest.xml
new file mode 100644
index 0000000..50fe115
--- /dev/null
+++ b/tests/tests/calllog/AndroidManifest.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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.android.cts.calllog">
+    <uses-sdk android:minSdkVersion="21" />
+
+    <uses-permission android:name="android.permission.READ_CALL_LOG" />
+    <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.calllog"
+                     android:label="CTS tests for android.calllog package">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java b/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java
new file mode 100644
index 0000000..5b0e0c7
--- /dev/null
+++ b/tests/tests/calllog/src/android/calllog/cts/CallLogBackupTest.java
@@ -0,0 +1,267 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.calllog.cts;
+
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.provider.CallLog;
+import android.provider.CallLog.Calls;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import com.android.org.bouncycastle.util.encoders.Base64;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Verifies the behavior of CallLogBackup.
+ *
+ * This tests three import things:
+ * 1. That call log gets backed up and restored using the standard BackupAgent implementation.
+ *     - To test we create call-log entries back them up, clear the call log, and restore them.
+ *     - We leverage the LocalTransport backup implementation to do this.
+ * 2. The call log backup is implemented by the expected package: {@link #CALLLOG_BACKUP_PACKAGE}.
+ *     - We always trigger the expected package for backup/restore within the tests.
+ * 3. The backup format for call log is as expected so that backup works across android devices
+ *    by different OEMs.
+ *     - We peek into the backup files saved by LocalTransport and verify their binary output is
+ *       as expected.
+ */
+public class CallLogBackupTest extends InstrumentationTestCase {
+    private static final String TAG = "CallLogBackupTest";
+
+    private static final String LOCAL_BACKUP_COMPONENT =
+            "android/com.android.internal.backup.LocalTransport";
+    private static final String CALLLOG_BACKUP_PACKAGE = "com.android.providers.calllogbackup";
+
+    private static final String TEST_NUMBER = "555-1234";
+    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 Pattern BMGR_ENABLED_PATTERN = Pattern.compile(
+            "^Backup Manager currently (enabled|disabled)$");
+
+    private static final String[] CALL_LOG_PROJECTION = new String[] {
+        CallLog.Calls._ID,
+        CallLog.Calls.DATE,
+        CallLog.Calls.DURATION,
+        CallLog.Calls.NUMBER,
+        CallLog.Calls.TYPE,
+        CallLog.Calls.COUNTRY_ISO,
+        CallLog.Calls.GEOCODED_LOCATION,
+        CallLog.Calls.NUMBER_PRESENTATION,
+        CallLog.Calls.PHONE_ACCOUNT_COMPONENT_NAME,
+        CallLog.Calls.PHONE_ACCOUNT_ID,
+        CallLog.Calls.DATA_USAGE,
+        CallLog.Calls.FEATURES
+    };
+
+    class Call {
+        int id;
+        long date;
+        long duration;
+        String number;
+        int type;
+        String phoneAccountComponent;
+        String phoneAccountId;
+        int presentation;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    /**
+     * Test:
+     *   1) Clear the call log
+     *   2) Add a single call
+     *   3) Run backup
+     *   4) clear the call log
+     *   5) Run restore
+     *   6) Verify that we the call from step (2)
+     */
+    public void testSingleCallBackup() throws Exception {
+        // This CTS test depends on the local transport and so if it is not present,
+        // skip the test with success.
+        if (!hasBackupTransport(LOCAL_BACKUP_COMPONENT)) {
+            Log.i(TAG, "skipping calllog tests");
+            return;
+        }
+
+        // Turn on backup and set to the local backup agent.
+        boolean previouslyEnabled = enableBackup(true /* enable */);
+        String oldTransport = setBackupTransport(LOCAL_BACKUP_COMPONENT);
+
+        // Clear the call log
+        Log.i(TAG, "Clearing the call log");
+        clearCallLog();
+
+        // Add a single call and verify it exists
+        Log.i(TAG, "Adding a call");
+        addCall();
+        verifyCall();
+
+        // Run backup for the call log (saves the single call).
+        Log.i(TAG, "Running backup");
+        runBackupFor(CALLLOG_BACKUP_PACKAGE);
+        Thread.sleep(TIMEOUT_BACKUP); // time for backup
+
+        // Clear the call log and verify that it is empty
+        Log.i(TAG, "Clearing the call log");
+        clearCallLog();
+        assertEquals(0, getCalls().size());
+
+        // Restore from the previous backup and verify we have the new call again.
+        Log.i(TAG, "Restoring the single call");
+        runRestoreFor(CALLLOG_BACKUP_PACKAGE);
+        Thread.sleep(TIMEOUT_BACKUP); // time for restore
+
+        verifyCall();
+
+        // Reset backup manager to original state.
+        Log.i(TAG, "Reseting backup");
+        setBackupTransport(oldTransport);
+        enableBackup(previouslyEnabled);
+    }
+
+    private Call verifyCall() {
+        List<Call> calls = getCalls();
+        assertEquals(1, calls.size());
+
+        Call call = calls.get(0);
+        assertEquals(TEST_NUMBER, call.number);
+        assertEquals(CALL_START_TIME, call.date);
+        assertEquals(CALL_DURATION, call.duration);
+        assertEquals(Calls.OUTGOING_TYPE, call.type);
+        return call;
+    }
+
+    private boolean enableBackup(boolean enable) throws Exception {
+        // Check to see the previous state of the backup service
+        boolean previouslyEnabled = false;
+        String output = exec("bmgr enabled");
+        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 + "'");
+        }
+
+        exec("bmgr enable " + enable);
+        return previouslyEnabled;
+    }
+
+    private void runBackupFor(String packageName) throws Exception {
+        exec("bmgr backup " + packageName);
+        exec("bmgr run");
+    }
+
+    private void runRestoreFor(String packageName) throws Exception {
+        exec("bmgr restore " + packageName);
+    }
+
+    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 Exception("non-parsable output setting bmgr transport: " + output);
+        }
+    }
+
+    /**
+     * Checks the list of supported transports and verifies that the specified transport
+     * is included.
+     */
+    private boolean hasBackupTransport(String transport) throws Exception {
+        String output = exec("bmgr list transports");
+        for (String t : output.split(" ")) {
+            if ("*".equals(t)) {
+                // skip the current selection marker.
+                continue;
+            } else if (Objects.equals(transport, t)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private void clearCallLog() {
+        ContentResolver resolver = getContext().getContentResolver();
+        resolver.delete(Calls.CONTENT_URI, null, null);
+    }
+
+    private void addCall() {
+        ContentValues values = new ContentValues(6);
+        values.put(Calls.NUMBER, TEST_NUMBER);
+        values.put(Calls.NUMBER_PRESENTATION, Calls.PRESENTATION_ALLOWED);
+        values.put(Calls.TYPE, Integer.valueOf(Calls.OUTGOING_TYPE));
+        values.put(Calls.DATE, Long.valueOf(CALL_START_TIME));
+        values.put(Calls.DURATION, Long.valueOf(CALL_DURATION));
+        values.put(Calls.NEW, Integer.valueOf(1));
+
+        getContext().getContentResolver().insert(Calls.CONTENT_URI, values);
+    }
+
+    private List<Call> getCalls() {
+        List<Call> calls = new LinkedList<>();
+
+        ContentResolver resolver = getContext().getContentResolver();
+        Cursor cursor = resolver.query(Calls.CONTENT_URI, CALL_LOG_PROJECTION, null, null, null);
+        if (cursor != null) {
+            try {
+                while (cursor.moveToNext()) {
+                    Call call = new Call();
+                    call.id = cursor.getInt(cursor.getColumnIndex(Calls._ID));
+                    call.number = cursor.getString(cursor.getColumnIndex(Calls.NUMBER));
+                    call.date = cursor.getLong(cursor.getColumnIndex(Calls.DATE));
+                    call.duration = cursor.getLong(cursor.getColumnIndex(Calls.DURATION));
+                    call.type = cursor.getInt(cursor.getColumnIndex(Calls.TYPE));
+                    call.phoneAccountComponent = cursor.getString(
+                            cursor.getColumnIndex(Calls.PHONE_ACCOUNT_COMPONENT_NAME));
+                    call.phoneAccountId = cursor.getString(
+                            cursor.getColumnIndex(Calls.PHONE_ACCOUNT_ID));
+                    call.presentation = cursor.getInt(
+                            cursor.getColumnIndex(Calls.NUMBER_PRESENTATION));
+                    calls.add(call);
+                }
+            } finally {
+                cursor.close();
+            }
+        }
+        return calls;
+    }
+
+    private Context getContext() {
+        return getInstrumentation().getContext();
+    }
+
+    private String exec(String command) throws Exception {
+        return TestUtils.executeShellCommand(getInstrumentation(), command);
+    }
+}
diff --git a/tests/tests/calllog/src/android/calllog/cts/TestUtils.java b/tests/tests/calllog/src/android/calllog/cts/TestUtils.java
new file mode 100644
index 0000000..d2c57a5
--- /dev/null
+++ b/tests/tests/calllog/src/android/calllog/cts/TestUtils.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.calllog.cts;
+
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+import android.telecom.PhoneAccountHandle;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+public class TestUtils {
+    /**
+     * Executes the given shell command and returns the output in a string. Note that even
+     * if we don't care about the output, we have to read the stream completely to make the
+     * command execute.
+     */
+    public static String executeShellCommand(Instrumentation instrumentation,
+            String command) throws Exception {
+        BufferedReader br = null;
+        try (InputStream in = executeStreamedShellCommand(instrumentation, 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);
+            }
+        }
+    }
+
+    public 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/tests/content/AndroidManifest.xml b/tests/tests/content/AndroidManifest.xml
index d54bc02..bffb1f7 100644
--- a/tests/tests/content/AndroidManifest.xml
+++ b/tests/tests/content/AndroidManifest.xml
@@ -39,7 +39,16 @@
                     android:label="Test Tree"/>
 
     <!-- Used for PackageManager test, don't delete this permission-group -->
-    <permission-group android:name="android.permission-group.COST_MONEY"/>
+    <permission-group android:name="android.permission-group.COST_MONEY"
+            android:label="@string/permlab_costMoney"
+            android:description="@string/permdesc_costMoney"/>
+
+    <permission android:name="com.android.cts.content.CALL_ABROAD_PERMISSION"
+                android:label="@string/permlab_callAbroad"
+                android:description="@string/permdesc_callAbroad"
+                android:protectionLevel="normal"
+                android:permissionGroup="android.permission-group.COST_MONEY" />
+
     <!-- Used for PackageManager test, don't delete! -->
     <uses-configuration/>
     <uses-feature android:name="android.hardware.camera" />
@@ -108,6 +117,14 @@
             </intent-filter>
         </receiver>
 
+        <!-- Receiver that will be explicitly disabled at runtime -->
+        <receiver android:name="android.content.cts.MockReceiverDisableable"
+                android:enabled="true">
+            <intent-filter android:priority="1">
+                <action android:name="android.content.cts.BroadcastReceiverTest.BROADCAST_DISABLED" />
+            </intent-filter>
+        </receiver>
+
         <activity android:name="android.content.cts.AvailableIntentsActivity"
             android:label="AvailableIntentsActivity">
             <intent-filter>
diff --git a/tests/tests/content/res/color/color2.xml b/tests/tests/content/res/color/color2.xml
new file mode 100644
index 0000000..154325f
--- /dev/null
+++ b/tests/tests/content/res/color/color2.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
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true" android:color="?attr/testcolor3"/>
+    <item android:color="?attr/testcolor4"/>
+</selector>
diff --git a/tests/tests/content/res/values-land/styles.xml b/tests/tests/content/res/values-land/styles.xml
new file mode 100644
index 0000000..7717f10
--- /dev/null
+++ b/tests/tests/content/res/values-land/styles.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.
+-->
+
+<resources>
+    <style name="Theme_OrientationDependent">
+        <item name="themeDimension">111px</item>
+    </style>
+</resources>
diff --git a/tests/tests/content/res/values-ldltr/styles.xml b/tests/tests/content/res/values-ldltr/styles.xml
new file mode 100644
index 0000000..063fc4f
--- /dev/null
+++ b/tests/tests/content/res/values-ldltr/styles.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.
+-->
+
+<resources>
+    <style name="Theme_LayoutDirectionDependent">
+        <item name="themeInteger">111</item>
+    </style>
+    <style name="Theme_LayoutIsRTL">
+        <item name="themeBoolean">false</item>
+    </style>
+</resources>
diff --git a/tests/tests/content/res/values-ldrtl/styles.xml b/tests/tests/content/res/values-ldrtl/styles.xml
new file mode 100644
index 0000000..c586192
--- /dev/null
+++ b/tests/tests/content/res/values-ldrtl/styles.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.
+-->
+
+<resources>
+    <style name="Theme_LayoutIsRTL">
+        <item name="themeBoolean">true</item>
+    </style>
+</resources>
diff --git a/tests/tests/content/res/values-v23/strings.xml b/tests/tests/content/res/values-v23/strings.xml
new file mode 100644
index 0000000..4ed1aaa
--- /dev/null
+++ b/tests/tests/content/res/values-v23/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">v23cur</string>
+</resources>
diff --git a/tests/tests/content/res/values/attrs.xml b/tests/tests/content/res/values/attrs.xml
index 4c3d9db..ac88ef6 100644
--- a/tests/tests/content/res/values/attrs.xml
+++ b/tests/tests/content/res/values/attrs.xml
@@ -125,6 +125,9 @@
         <attr name="textColorHint"/>
         <attr name="textColorLink"/>
     </declare-styleable>
+    <!-- colors referred by theme. -->
+    <attr name="testcolor3" format="color"/>
+    <attr name="testcolor4" format="color"/>
     <!-- Integer used to uniquely identify theme overrides. -->
     <attr name="themeType" format="integer"/>
     <!-- Theme reference used to override parent theme. -->
diff --git a/tests/tests/content/res/values/strings.xml b/tests/tests/content/res/values/strings.xml
index c167278..8ffb477 100644
--- a/tests/tests/content/res/values/strings.xml
+++ b/tests/tests/content/res/values/strings.xml
@@ -176,4 +176,10 @@
 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="permlab_costMoney">Cost money</string>
+    <string name="permdesc_costMoney">Do things that can cost you money.</string>
+    <string name="permlab_callAbroad">Call abroad</string>
+    <string name="permdesc_callAbroad">Make calls abroad</string>
+
 </resources>
diff --git a/tests/tests/content/res/values/styles.xml b/tests/tests/content/res/values/styles.xml
index 20c80f8..b27968d 100644
--- a/tests/tests/content/res/values/styles.xml
+++ b/tests/tests/content/res/values/styles.xml
@@ -136,6 +136,8 @@
         <item name="android:windowNoTitle">true</item>
         <item name="android:panelColorForeground">#ff000000</item>
         <item name="android:panelColorBackground">#ffffffff</item>
+        <item name="testcolor3">#ffff0000</item>
+        <item name="testcolor4">#ffffff00</item>
     </style>
 
     <style name="Theme_OverrideOuter">
@@ -169,4 +171,11 @@
         <item name="android:windowSwipeToDismiss">false</item>
     </style>
 
+    <style name="Theme_LayoutDirectionDependent">
+        <item name="themeInteger">999</item>
+    </style>
+
+    <style name="Theme_OrientationDependent">
+        <item name="themeDimension">999px</item>
+    </style>
 </resources>
diff --git a/tests/tests/content/src/android/content/cts/BroadcastReceiverTest.java b/tests/tests/content/src/android/content/cts/BroadcastReceiverTest.java
index 526087b..43d6cfe 100644
--- a/tests/tests/content/src/android/content/cts/BroadcastReceiverTest.java
+++ b/tests/tests/content/src/android/content/cts/BroadcastReceiverTest.java
@@ -24,6 +24,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.test.ActivityInstrumentationTestCase2;
@@ -45,10 +46,16 @@
             "android.content.cts.BroadcastReceiverTest.BROADCAST_MOCKTEST";
     private static final String ACTION_BROADCAST_TESTABORT =
             "android.content.cts.BroadcastReceiverTest.BROADCAST_TESTABORT";
+    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 START_SERVICE_TIMEOUT  = 3000;
 
+    private static final ComponentName DISABLEABLE_RECEIVER =
+            new ComponentName("com.android.cts.content",
+                    "android.content.cts.MockReceiverDisableable");
+
     public BroadcastReceiverTest() {
         super("com.android.cts.content", MockActivity.class);
     }
@@ -127,6 +134,26 @@
         }
     }
 
+    private class MockReceiverInternalVerifyUncalled extends MockReceiverInternal {
+        final int mExpectedInitialCode;
+
+        public MockReceiverInternalVerifyUncalled(int initialCode) {
+            mExpectedInitialCode = initialCode;
+        }
+
+        @Override
+        public synchronized void onReceive(Context context, Intent intent) {
+            // only update to the expected final values if we're still in the
+            // initial conditions.  The intermediate receiver would have
+            // updated the result code if it [inappropriately] ran.
+            if (getResultCode() == mExpectedInitialCode) {
+                setResultCode(RESULT_INTERNAL_FINAL_CODE);
+            }
+
+            super.onReceive(context, intent);
+        }
+    }
+
     public void testOnReceive () throws InterruptedException {
         final MockActivity activity = getActivity();
 
@@ -202,6 +229,26 @@
                 resultExtras.getString(MockReceiverAbort.RESULT_EXTRAS_ABORT_KEY));
     }
 
+    public void testDisabledBroadcastReceiver() throws Exception {
+        final Context context = getInstrumentation().getContext();
+        PackageManager pm = context.getPackageManager();
+
+        MockReceiverInternalVerifyUncalled lastReceiver =
+                new MockReceiverInternalVerifyUncalled(RESULT_INITIAL_CODE);
+        assertEquals(0, lastReceiver.getResultCode());
+
+        pm.setComponentEnabledSetting(DISABLEABLE_RECEIVER,
+                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                PackageManager.DONT_KILL_APP);
+
+        context.sendOrderedBroadcast(
+                new Intent(ACTION_BROADCAST_DISABLED), null, lastReceiver,
+                null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, new Bundle());
+        lastReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
+
+        assertEquals(RESULT_INTERNAL_FINAL_CODE, lastReceiver.getResultCode());
+    }
+
     public void testPeekService() throws InterruptedException {
         final MockActivity activity = getActivity();
 
diff --git a/tests/tests/content/src/android/content/cts/ContentProviderTest.java b/tests/tests/content/src/android/content/cts/ContentProviderTest.java
index 0b4d9aa..5fee379 100644
--- a/tests/tests/content/src/android/content/cts/ContentProviderTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentProviderTest.java
@@ -71,7 +71,7 @@
 
         ProviderInfo info1 = new ProviderInfo();
         info1.readPermission = "android.permission.READ_SMS";
-        info1.writePermission = "android.permission.WRITE_SMS";
+        info1.writePermission = null; // Guarded by an app op not a permission.
         mockContentProvider.attachInfo(getContext(), info1);
         assertSame(getContext(), mockContentProvider.getContext());
         assertEquals(info1.readPermission, mockContentProvider.getReadPermission());
@@ -156,10 +156,6 @@
         mockContentProvider.setWritePermissionWrapper(expected);
         assertEquals(expected, mockContentProvider.getWritePermission());
 
-        expected = "android.permission.WRITE_SMS";
-        mockContentProvider.setWritePermissionWrapper(expected);
-        assertEquals(expected, mockContentProvider.getWritePermission());
-
         mockContentProvider.setWritePermissionWrapper(null);
         assertNull(mockContentProvider.getWritePermission());
     }
diff --git a/tests/tests/content/src/android/content/cts/ContentResolverTest.java b/tests/tests/content/src/android/content/cts/ContentResolverTest.java
index 4176da3..628f956 100644
--- a/tests/tests/content/src/android/content/cts/ContentResolverTest.java
+++ b/tests/tests/content/src/android/content/cts/ContentResolverTest.java
@@ -58,6 +58,11 @@
     private static final Uri SELF_URI = Uri.parse("content://" + AUTHORITY + "/self/");
     private static final Uri CRASH_URI = Uri.parse("content://" + AUTHORITY + "/crash/");
 
+    private static final Uri LEVEL1_URI = Uri.parse("content://" + AUTHORITY + "/level/");
+    private static final Uri LEVEL2_URI = Uri.parse("content://" + AUTHORITY + "/level/child");
+    private static final Uri LEVEL3_URI = Uri.parse("content://" + AUTHORITY
+            + "/level/child/grandchild/");
+
     private static final String REMOTE_AUTHORITY = "remotectstest";
     private static final Uri REMOTE_TABLE1_URI = Uri.parse("content://"
                 + REMOTE_AUTHORITY + "/testtable1/");
@@ -88,7 +93,7 @@
         mContext = getContext();
         mContentResolver = mContext.getContentResolver();
 
-        android.provider.Settings.System.putInt(mContentResolver, "__cts_crash_on_launch", 0);
+        MockContentProvider.setCrashOnLaunch(mContext, false);
 
         // add three rows to database when every test case start.
         ContentValues values = new ContentValues();
@@ -151,13 +156,12 @@
             fail("Content provider process is not gone!");
         }
         try {
-            android.provider.Settings.System.putInt(mContentResolver, "__cts_crash_on_launch", 1);
+            MockContentProvider.setCrashOnLaunch(mContext, true);
             String type1 = mContentResolver.getType(REMOTE_TABLE1_URI);
-            assertEquals(android.provider.Settings.System.getInt(mContentResolver,
-                "__cts_crash_on_launch", 0), 0);
+            assertFalse(MockContentProvider.getCrashOnLaunch(mContext));
             assertTrue(type1.startsWith(ContentResolver.CURSOR_DIR_BASE_TYPE, 0));
         } finally {
-            android.provider.Settings.System.putInt(mContentResolver, "__cts_crash_on_launch", 0);
+            MockContentProvider.setCrashOnLaunch(mContext, false);
         }
     }
 
@@ -352,12 +356,11 @@
 
     public void testCrashingQuery() {
         try {
-            android.provider.Settings.System.putInt(mContentResolver, "__cts_crash_on_launch", 1);
+            MockContentProvider.setCrashOnLaunch(mContext, true);
             mCursor = mContentResolver.query(REMOTE_CRASH_URI, null, null, null, null);
-            assertEquals(android.provider.Settings.System.getInt(mContentResolver,
-                "__cts_crash_on_launch", 0), 0);
+            assertFalse(MockContentProvider.getCrashOnLaunch(mContext));
         } finally {
-            android.provider.Settings.System.putInt(mContentResolver, "__cts_crash_on_launch", 0);
+            MockContentProvider.setCrashOnLaunch(mContext, false);
         }
 
         assertNotNull(mCursor);
@@ -570,16 +573,15 @@
     public void testCrashingOpenAssetFileDescriptor() throws IOException {
         AssetFileDescriptor afd = null;
         try {
-            android.provider.Settings.System.putInt(mContentResolver, "__cts_crash_on_launch", 1);
+            MockContentProvider.setCrashOnLaunch(mContext, true);
             afd = mContentResolver.openAssetFileDescriptor(REMOTE_CRASH_URI, "rw");
-            assertEquals(android.provider.Settings.System.getInt(mContentResolver,
-                    "__cts_crash_on_launch", 0), 0);
+            assertFalse(MockContentProvider.getCrashOnLaunch(mContext));
             assertNotNull(afd);
             String str = consumeAssetFileDescriptor(afd);
             afd = null;
             assertEquals(str, "This is the openAssetFile test data!");
         } finally {
-            android.provider.Settings.System.putInt(mContentResolver, "__cts_crash_on_launch", 0);
+            MockContentProvider.setCrashOnLaunch(mContext, false);
             if (afd != null) {
                 afd.close();
             }
@@ -602,17 +604,16 @@
     public void testCrashingOpenTypedAssetFileDescriptor() throws IOException {
         AssetFileDescriptor afd = null;
         try {
-            android.provider.Settings.System.putInt(mContentResolver, "__cts_crash_on_launch", 1);
+            MockContentProvider.setCrashOnLaunch(mContext, true);
             afd = mContentResolver.openTypedAssetFileDescriptor(
                     REMOTE_CRASH_URI, "text/plain", null);
-            assertEquals(android.provider.Settings.System.getInt(mContentResolver,
-                    "__cts_crash_on_launch", 0), 0);
+            assertFalse(MockContentProvider.getCrashOnLaunch(mContext));
             assertNotNull(afd);
             String str = consumeAssetFileDescriptor(afd);
             afd = null;
             assertEquals(str, "This is the openTypedAssetFile test data!");
         } finally {
-            android.provider.Settings.System.putInt(mContentResolver, "__cts_crash_on_launch", 0);
+            MockContentProvider.setCrashOnLaunch(mContext, false);
             if (afd != null) {
                 afd.close();
             }
@@ -957,6 +958,53 @@
         }
     }
 
+    public void testRegisterContentObserverDescendantBehavior() throws Exception {
+        final MockContentObserver mco1 = new MockContentObserver();
+        final MockContentObserver mco2 = new MockContentObserver();
+
+        // Register one content observer with notifyDescendants set to false, and
+        // another with true.
+        mContentResolver.registerContentObserver(LEVEL2_URI, false, mco1);
+        mContentResolver.registerContentObserver(LEVEL2_URI, true, mco2);
+
+        // Initially nothing has happened.
+        assertFalse(mco1.hadOnChanged());
+        assertFalse(mco2.hadOnChanged());
+
+        // Fire a change with the exact URI.
+        // Should signal both observers due to exact match, notifyDescendants doesn't matter.
+        mContentResolver.notifyChange(LEVEL2_URI, null);
+        Thread.sleep(200);
+        assertTrue(mco1.hadOnChanged());
+        assertTrue(mco2.hadOnChanged());
+        mco1.reset();
+        mco2.reset();
+
+        // Fire a change with a descendant URI.
+        // Should only signal observer with notifyDescendants set to true.
+        mContentResolver.notifyChange(LEVEL3_URI, null);
+        Thread.sleep(200);
+        assertFalse(mco1.hadOnChanged());
+        assertTrue(mco2.hadOnChanged());
+        mco2.reset();
+
+        // Fire a change with an ancestor URI.
+        // Should signal both observers due to ancestry, notifyDescendants doesn't matter.
+        mContentResolver.notifyChange(LEVEL1_URI, null);
+        Thread.sleep(200);
+        assertTrue(mco1.hadOnChanged());
+        assertTrue(mco2.hadOnChanged());
+        mco1.reset();
+        mco2.reset();
+
+        // Fire a change with an unrelated URI.
+        // Should signal neither observer.
+        mContentResolver.notifyChange(TABLE1_URI, null);
+        Thread.sleep(200);
+        assertFalse(mco1.hadOnChanged());
+        assertFalse(mco2.hadOnChanged());
+    }
+
     public void testNotifyChange1() {
         final MockContentObserver mco = new MockContentObserver();
 
diff --git a/tests/tests/content/src/android/content/cts/ContextTest.java b/tests/tests/content/src/android/content/cts/ContextTest.java
index 7c5dc50..d77c1b1 100644
--- a/tests/tests/content/src/android/content/cts/ContextTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextTest.java
@@ -17,19 +17,20 @@
 package android.content.cts;
 
 import com.android.cts.content.R;
-import com.android.internal.util.XmlUtils;
-
 
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.Context;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
+import android.content.cts.util.XmlUtils;
+import android.content.res.ColorStateList;
 import android.content.res.Resources.NotFoundException;
 import android.content.res.Resources.Theme;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
 import android.util.Xml;
+import android.view.WindowManager;
 
 import java.io.IOException;
 
@@ -155,6 +156,50 @@
         testTypedArray.recycle();
     }
 
+    public void testGetSystemService() {
+        // Test invalid service name
+        assertNull(mContext.getSystemService("invalid"));
+
+        // Test valid service name
+        assertNotNull(mContext.getSystemService(Context.WINDOW_SERVICE));
+    }
+
+    public void testGetSystemServiceByClass() {
+        // Test invalid service class
+        assertNull(mContext.getSystemService(Object.class));
+
+        // Test valid service name
+        assertNotNull(mContext.getSystemService(WindowManager.class));
+        assertEquals(mContext.getSystemService(Context.WINDOW_SERVICE),
+                mContext.getSystemService(WindowManager.class));
+    }
+
+    public void testGetColorStateList() {
+        try {
+            mContext.getColorStateList(0);
+            fail("Failed at testGetColorStateList");
+        } catch (NotFoundException e) {
+            //expected
+        }
+
+        final ColorStateList colorStateList = mContext.getColorStateList(R.color.color2);
+        final int[] focusedState = {android.R.attr.state_focused};
+        final int focusColor = colorStateList.getColorForState(focusedState, R.color.failColor);
+        assertEquals(0xffff0000, focusColor);
+    }
+
+    public void testGetColor() {
+        try {
+            mContext.getColor(0);
+            fail("Failed at testGetColor");
+        } catch (NotFoundException e) {
+            //expected
+        }
+
+        final int color = mContext.getColor(R.color.color2);
+        assertEquals(0xffffff00, color);
+    }
+
     private AttributeSet getAttributeSet(int resourceId) {
         final XmlResourceParser parser = getContext().getResources().getXml(
                 resourceId);
diff --git a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
index 62fc83a..edc9538 100644
--- a/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
+++ b/tests/tests/content/src/android/content/cts/ContextWrapperTest.java
@@ -18,7 +18,6 @@
 
 import com.android.cts.content.R;
 
-
 import android.content.ActivityNotFoundException;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
@@ -44,6 +43,7 @@
 import android.os.IBinder;
 import android.preference.PreferenceManager;
 import android.test.AndroidTestCase;
+import android.view.WindowManager;
 
 import java.io.File;
 import java.io.IOException;
@@ -157,6 +157,7 @@
         registerBroadcastReceiver(lowPriorityReceiver, filterLowPriority);
 
         final Intent broadcastIntent = new Intent(ResultReceiver.MOCK_ACTION);
+        broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
         mContextWrapper.sendOrderedBroadcast(broadcastIntent, null);
         new PollingCheck(BROADCAST_TIMEOUT) {
             @Override
@@ -186,8 +187,10 @@
         Bundle bundle = new Bundle();
         bundle.putString(KEY_KEPT, VALUE_KEPT);
         bundle.putString(KEY_REMOVED, VALUE_REMOVED);
-        mContextWrapper.sendOrderedBroadcast(new Intent(ResultReceiver.MOCK_ACTION),
-                null, broadcastReceiver, null, 1, INTIAL_RESULT, bundle);
+        Intent intent = new Intent(ResultReceiver.MOCK_ACTION);
+        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+        mContextWrapper.sendOrderedBroadcast(intent, null, broadcastReceiver, null, 1,
+                INTIAL_RESULT, bundle);
 
         synchronized (mLockObj) {
             try {
@@ -216,13 +219,13 @@
 
         // Test unwanted intent(action = MOCK_ACTION2)
         broadcastReceiver.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION2);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
         assertFalse(broadcastReceiver.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver.hadReceivedBroadCast2());
 
         // Send wanted intent(action = MOCK_ACTION1)
         broadcastReceiver.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION1);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
         assertTrue(broadcastReceiver.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver.hadReceivedBroadCast2());
 
@@ -235,13 +238,13 @@
 
         // Test unwanted intent(action = MOCK_ACTION2)
         broadcastReceiver2.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver2, MOCK_ACTION2);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
         assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
 
         // Send wanted intent(action = MOCK_ACTION1), but the receiver is unregistered.
         broadcastReceiver2.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver2, MOCK_ACTION1);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
         assertFalse(broadcastReceiver2.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver2.hadReceivedBroadCast2());
     }
@@ -256,13 +259,13 @@
 
         // Test unwanted intent(action = MOCK_ACTION2)
         broadcastReceiver.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION2);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION2);
         assertFalse(broadcastReceiver.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver.hadReceivedBroadCast2());
 
         // Send wanted intent(action = MOCK_ACTION1)
         broadcastReceiver.reset();
-        waitForFilteredIntent(mContextWrapper, broadcastReceiver, MOCK_ACTION1);
+        waitForFilteredIntent(mContextWrapper, MOCK_ACTION1);
         assertTrue(broadcastReceiver.hadReceivedBroadCast1());
         assertFalse(broadcastReceiver.hadReceivedBroadCast2());
 
@@ -718,6 +721,16 @@
         assertNotNull(mContextWrapper.getSystemService(Context.WINDOW_SERVICE));
     }
 
+    public void testGetSystemServiceByClass() {
+        // Test invalid service class
+        assertNull(mContextWrapper.getSystemService(Object.class));
+
+        // Test valid service name
+        assertNotNull(mContextWrapper.getSystemService(WindowManager.class));
+        assertEquals(mContextWrapper.getSystemService(Context.WINDOW_SERVICE),
+                mContextWrapper.getSystemService(WindowManager.class));
+    }
+
     public void testGetAssets() {
         assertSame(mContext.getAssets(), mContextWrapper.getAssets());
     }
@@ -782,9 +795,9 @@
         waitForCondition(con);
     }
 
-    private void waitForFilteredIntent(ContextWrapper contextWrapper,
-            final FilteredReceiver receiver, final String action) throws InterruptedException {
-        contextWrapper.sendOrderedBroadcast(new Intent(action), null);
+    private void waitForFilteredIntent(ContextWrapper contextWrapper, final String action)
+            throws InterruptedException {
+        contextWrapper.sendBroadcast(new Intent(action), null);
 
         synchronized (mLockObj) {
             mLockObj.wait(BROADCAST_TIMEOUT);
@@ -839,7 +852,6 @@
 
     private class FilteredReceiver extends BroadcastReceiver {
         private boolean mHadReceivedBroadCast1 = false;
-
         private boolean mHadReceivedBroadCast2 = false;
 
         public void onReceive(Context context, Intent intent) {
diff --git a/tests/tests/content/src/android/content/cts/IntentTest.java b/tests/tests/content/src/android/content/cts/IntentTest.java
index 0f9a5cc..677b31f 100644
--- a/tests/tests/content/src/android/content/cts/IntentTest.java
+++ b/tests/tests/content/src/android/content/cts/IntentTest.java
@@ -16,9 +16,6 @@
 
 package android.content.cts;
 
-import com.android.internal.app.ResolverActivity;
-import com.android.internal.util.XmlUtils;
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -26,6 +23,7 @@
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.content.cts.util.XmlUtils;
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -38,7 +36,6 @@
 import android.provider.Contacts.People;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.util.Xml;
 
 import java.io.IOException;
diff --git a/tests/tests/content/src/android/content/cts/MockContentProvider.java b/tests/tests/content/src/android/content/cts/MockContentProvider.java
index de82c0d..bddc82d 100644
--- a/tests/tests/content/src/android/content/cts/MockContentProvider.java
+++ b/tests/tests/content/src/android/content/cts/MockContentProvider.java
@@ -16,6 +16,7 @@
 
 package android.content.cts;
 
+import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -28,6 +29,7 @@
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.content.UriMatcher;
 import android.content.ContentProvider.PipeDataWriter;
 import android.content.res.AssetFileDescriptor;
@@ -122,15 +124,7 @@
     @Override
     public boolean onCreate() {
         mOpenHelper = new DatabaseHelper(getContext(), mDbName);
-        if (android.provider.Settings.System.getInt(getContext().getContentResolver(),
-                "__cts_crash_on_launch", 0) != 0) {
-            // The test case wants us to crash our process on first launch.
-            // Well, okay then!
-            Log.i("MockContentProvider", "TEST IS CRASHING SELF, CROSS FINGERS!");
-            android.provider.Settings.System.putInt(getContext().getContentResolver(),
-                    "__cts_crash_on_launch", 0);
-            android.os.Process.killProcess(android.os.Process.myPid());
-        }
+        crashOnLaunchIfNeeded();
         return true;
     }
 
@@ -277,15 +271,7 @@
             break;
 
         case CRASH_ID:
-            if (android.provider.Settings.System.getInt(getContext().getContentResolver(),
-                    "__cts_crash_on_launch", 0) != 0) {
-                // The test case wants us to crash while querying.
-                // Well, okay then!
-                Log.i("MockContentProvider", "TEST IS CRASHING SELF, CROSS FINGERS!");
-                android.provider.Settings.System.putInt(getContext().getContentResolver(),
-                        "__cts_crash_on_launch", 0);
-                android.os.Process.killProcess(android.os.Process.myPid());
-            }
+            crashOnLaunchIfNeeded();
             qb.setTables("TestTable1");
             qb.setProjectionMap(CTSDBTABLE1_LIST_PROJECTION_MAP);
             break;
@@ -351,15 +337,7 @@
     public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
         switch (URL_MATCHER.match(uri)) {
             case CRASH_ID:
-                if (android.provider.Settings.System.getInt(getContext().getContentResolver(),
-                        "__cts_crash_on_launch", 0) != 0) {
-                    // The test case wants us to crash while querying.
-                    // Well, okay then!
-                    Log.i("MockContentProvider", "TEST IS CRASHING SELF, CROSS FINGERS!");
-                    android.provider.Settings.System.putInt(getContext().getContentResolver(),
-                            "__cts_crash_on_launch", 0);
-                    android.os.Process.killProcess(android.os.Process.myPid());
-                }
+                crashOnLaunchIfNeeded();
                 return new AssetFileDescriptor(
                         openPipeHelper(uri, null, null,
                                 "This is the openAssetFile test data!", this), 0,
@@ -375,15 +353,7 @@
             throws FileNotFoundException {
         switch (URL_MATCHER.match(uri)) {
             case CRASH_ID:
-                if (android.provider.Settings.System.getInt(getContext().getContentResolver(),
-                        "__cts_crash_on_launch", 0) != 0) {
-                    // The test case wants us to crash while querying.
-                    // Well, okay then!
-                    Log.i("MockContentProvider", "TEST IS CRASHING SELF, CROSS FINGERS!");
-                    android.provider.Settings.System.putInt(getContext().getContentResolver(),
-                            "__cts_crash_on_launch", 0);
-                    android.os.Process.killProcess(android.os.Process.myPid());
-                }
+                crashOnLaunchIfNeeded();
                 return new AssetFileDescriptor(
                         openPipeHelper(uri, null, null,
                                 "This is the openTypedAssetFile test data!", this), 0,
@@ -414,4 +384,36 @@
             }
         }
     }
+
+    private void crashOnLaunchIfNeeded() {
+        if (getCrashOnLaunch(getContext())) {
+            // The test case wants us to crash our process on first launch.
+            // Well, okay then!
+            Log.i("MockContentProvider", "TEST IS CRASHING SELF, CROSS FINGERS!");
+            setCrashOnLaunch(getContext(), false);
+            android.os.Process.killProcess(android.os.Process.myPid());
+        }
+    }
+
+    public static boolean getCrashOnLaunch(Context context) {
+        File file = getCrashOnLaunchFile(context);
+        return file.exists();
+    }
+
+    public static void setCrashOnLaunch(Context context, boolean value) {
+        File file = getCrashOnLaunchFile(context);
+        if (value) {
+            try {
+                file.createNewFile();
+            } catch (IOException ex) {
+                throw new RuntimeException("Could not create crash on launch file.", ex);
+            }
+        } else {
+            file.delete();
+        }
+    }
+
+    private static File getCrashOnLaunchFile(Context context) {
+        return context.getFileStreamPath("MockContentProvider.crashonlaunch");
+    }
 }
diff --git a/tests/tests/content/src/android/content/cts/MockReceiverDisableable.java b/tests/tests/content/src/android/content/cts/MockReceiverDisableable.java
new file mode 100644
index 0000000..9ee73ed
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/MockReceiverDisableable.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 android.content.cts;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class MockReceiverDisableable extends BroadcastReceiver {
+    public static final int RESULT_CODE = 99;
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        setResultCode(RESULT_CODE);
+    }
+}
diff --git a/tests/tests/content/src/android/content/cts/util/XmlUtils.java b/tests/tests/content/src/android/content/cts/util/XmlUtils.java
new file mode 100644
index 0000000..0354da8
--- /dev/null
+++ b/tests/tests/content/src/android/content/cts/util/XmlUtils.java
@@ -0,0 +1,1694 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.cts.util;
+
+import com.android.internal.util.FastXmlSerializer;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.util.ArrayMap;
+import android.util.Base64;
+import android.util.Xml;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ProtocolException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/** {@hide} */
+public class XmlUtils {
+
+    public static void skipCurrentTag(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+               && (type != XmlPullParser.END_TAG
+                       || parser.getDepth() > outerDepth)) {
+        }
+    }
+
+    public static final int
+    convertValueToList(CharSequence value, String[] options, int defaultValue)
+    {
+        if (null != value) {
+            for (int i = 0; i < options.length; i++) {
+                if (value.equals(options[i]))
+                    return i;
+            }
+        }
+
+        return defaultValue;
+    }
+
+    public static final boolean
+    convertValueToBoolean(CharSequence value, boolean defaultValue)
+    {
+        boolean result = false;
+
+        if (null == value)
+            return defaultValue;
+
+        if (value.equals("1")
+        ||  value.equals("true")
+        ||  value.equals("TRUE"))
+            result = true;
+
+        return result;
+    }
+
+    public static final int
+    convertValueToInt(CharSequence charSeq, int defaultValue)
+    {
+        if (null == charSeq)
+            return defaultValue;
+
+        String nm = charSeq.toString();
+
+        // XXX This code is copied from Integer.decode() so we don't
+        // have to instantiate an Integer!
+
+        int value;
+        int sign = 1;
+        int index = 0;
+        int len = nm.length();
+        int base = 10;
+
+        if ('-' == nm.charAt(0)) {
+            sign = -1;
+            index++;
+        }
+
+        if ('0' == nm.charAt(index)) {
+            //  Quick check for a zero by itself
+            if (index == (len - 1))
+                return 0;
+
+            char    c = nm.charAt(index + 1);
+
+            if ('x' == c || 'X' == c) {
+                index += 2;
+                base = 16;
+            } else {
+                index++;
+                base = 8;
+            }
+        }
+        else if ('#' == nm.charAt(index))
+        {
+            index++;
+            base = 16;
+        }
+
+        return Integer.parseInt(nm.substring(index), base) * sign;
+    }
+
+    public static int convertValueToUnsignedInt(String value, int defaultValue) {
+        if (null == value) {
+            return defaultValue;
+        }
+
+        return parseUnsignedIntAttribute(value);
+    }
+
+    public static int parseUnsignedIntAttribute(CharSequence charSeq) {
+        String  value = charSeq.toString();
+
+        long    bits;
+        int     index = 0;
+        int     len = value.length();
+        int     base = 10;
+
+        if ('0' == value.charAt(index)) {
+            //  Quick check for zero by itself
+            if (index == (len - 1))
+                return 0;
+
+            char    c = value.charAt(index + 1);
+
+            if ('x' == c || 'X' == c) {     //  check for hex
+                index += 2;
+                base = 16;
+            } else {                        //  check for octal
+                index++;
+                base = 8;
+            }
+        } else if ('#' == value.charAt(index)) {
+            index++;
+            base = 16;
+        }
+
+        return (int) Long.parseLong(value.substring(index), base);
+    }
+
+    /**
+     * Flatten a Map into an output stream as XML.  The map can later be
+     * read back with readMapXml().
+     *
+     * @param val The map to be flattened.
+     * @param out Where to write the XML data.
+     *
+     * @see #writeMapXml(Map, String, XmlSerializer)
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     */
+    public static final void writeMapXml(Map val, OutputStream out)
+            throws XmlPullParserException, IOException {
+        XmlSerializer serializer = new FastXmlSerializer();
+        serializer.setOutput(out, StandardCharsets.UTF_8.name());
+        serializer.startDocument(null, true);
+        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+        writeMapXml(val, null, serializer);
+        serializer.endDocument();
+    }
+
+    /**
+     * Flatten a List into an output stream as XML.  The list can later be
+     * read back with readListXml().
+     *
+     * @param val The list to be flattened.
+     * @param out Where to write the XML data.
+     *
+     * @see #writeListXml(List, String, XmlSerializer)
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readListXml
+     */
+    public static final void writeListXml(List val, OutputStream out)
+    throws XmlPullParserException, IOException
+    {
+        XmlSerializer serializer = Xml.newSerializer();
+        serializer.setOutput(out, StandardCharsets.UTF_8.name());
+        serializer.startDocument(null, true);
+        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+        writeListXml(val, null, serializer);
+        serializer.endDocument();
+    }
+
+    /**
+     * Flatten a Map into an XmlSerializer.  The map can later be read back
+     * with readThisMapXml().
+     *
+     * @param val The map to be flattened.
+     * @param name Name attribute to include with this list's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the map into.
+     *
+     * @see #writeMapXml(Map, OutputStream)
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     */
+    public static final void writeMapXml(Map val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        writeMapXml(val, name, out, null);
+    }
+
+    /**
+     * Flatten a Map into an XmlSerializer.  The map can later be read back
+     * with readThisMapXml().
+     *
+     * @param val The map to be flattened.
+     * @param name Name attribute to include with this list's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the map into.
+     * @param callback Method to call when an Object type is not recognized.
+     *
+     * @see #writeMapXml(Map, OutputStream)
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     *
+     * @hide
+     */
+    public static final void writeMapXml(Map val, String name, XmlSerializer out,
+            WriteMapCallback callback) throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "map");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        writeMapXml(val, out, callback);
+
+        out.endTag(null, "map");
+    }
+
+    /**
+     * Flatten a Map into an XmlSerializer.  The map can later be read back
+     * with readThisMapXml(). This method presumes that the start tag and
+     * name attribute have already been written and does not write an end tag.
+     *
+     * @param val The map to be flattened.
+     * @param out XmlSerializer to write the map into.
+     *
+     * @see #writeMapXml(Map, OutputStream)
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     *
+     * @hide
+     */
+    public static final void writeMapXml(Map val, XmlSerializer out,
+            WriteMapCallback callback) throws XmlPullParserException, IOException {
+        if (val == null) {
+            return;
+        }
+
+        Set s = val.entrySet();
+        Iterator i = s.iterator();
+
+        while (i.hasNext()) {
+            Map.Entry e = (Map.Entry)i.next();
+            writeValueXml(e.getValue(), (String)e.getKey(), out, callback);
+        }
+    }
+
+    /**
+     * Flatten a List into an XmlSerializer.  The list can later be read back
+     * with readThisListXml().
+     *
+     * @param val The list to be flattened.
+     * @param name Name attribute to include with this list's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the list into.
+     *
+     * @see #writeListXml(List, OutputStream)
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readListXml
+     */
+    public static final void writeListXml(List val, String name, XmlSerializer out)
+    throws XmlPullParserException, IOException
+    {
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "list");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        int N = val.size();
+        int i=0;
+        while (i < N) {
+            writeValueXml(val.get(i), null, out);
+            i++;
+        }
+
+        out.endTag(null, "list");
+    }
+
+    public static final void writeSetXml(Set val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "set");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        for (Object v : val) {
+            writeValueXml(v, null, out);
+        }
+
+        out.endTag(null, "set");
+    }
+
+    /**
+     * Flatten a byte[] into an XmlSerializer.  The list can later be read back
+     * with readThisByteArrayXml().
+     *
+     * @param val The byte array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     */
+    public static final void writeByteArrayXml(byte[] val, String name,
+            XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "byte-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        StringBuilder sb = new StringBuilder(val.length*2);
+        for (int i=0; i<N; i++) {
+            int b = val[i];
+            int h = b>>4;
+            sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
+            h = b&0xff;
+            sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
+        }
+
+        out.text(sb.toString());
+
+        out.endTag(null, "byte-array");
+    }
+
+    /**
+     * Flatten an int[] into an XmlSerializer.  The list can later be read back
+     * with readThisIntArrayXml().
+     *
+     * @param val The int array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeIntArrayXml(int[] val, String name,
+            XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "int-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Integer.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "int-array");
+    }
+
+    /**
+     * Flatten a long[] into an XmlSerializer.  The list can later be read back
+     * with readThisLongArrayXml().
+     *
+     * @param val The long array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeLongArrayXml(long[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "long-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Long.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "long-array");
+    }
+
+    /**
+     * Flatten a double[] into an XmlSerializer.  The list can later be read back
+     * with readThisDoubleArrayXml().
+     *
+     * @param val The double array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeDoubleArrayXml(double[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "double-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Double.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "double-array");
+    }
+
+    /**
+     * Flatten a String[] into an XmlSerializer.  The list can later be read back
+     * with readThisStringArrayXml().
+     *
+     * @param val The String array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeStringArrayXml(String[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "string-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", val[i]);
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "string-array");
+    }
+
+    /**
+     * Flatten a boolean[] into an XmlSerializer.  The list can later be read back
+     * with readThisBooleanArrayXml().
+     *
+     * @param val The boolean array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeBooleanArrayXml(boolean[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "boolean-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Boolean.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "boolean-array");
+    }
+
+    /**
+     * Flatten an object's value into an XmlSerializer.  The value can later
+     * be read back with readThisValueXml().
+     *
+     * Currently supported value types are: null, String, Integer, Long,
+     * Float, Double Boolean, Map, List.
+     *
+     * @param v The object to be flattened.
+     * @param name Name attribute to include with this value's tag, or null
+     *             for none.
+     * @param out XmlSerializer to write the object into.
+     *
+     * @see #writeMapXml
+     * @see #writeListXml
+     * @see #readValueXml
+     */
+    public static final void writeValueXml(Object v, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        writeValueXml(v, name, out, null);
+    }
+
+    /**
+     * Flatten an object's value into an XmlSerializer.  The value can later
+     * be read back with readThisValueXml().
+     *
+     * Currently supported value types are: null, String, Integer, Long,
+     * Float, Double Boolean, Map, List.
+     *
+     * @param v The object to be flattened.
+     * @param name Name attribute to include with this value's tag, or null
+     *             for none.
+     * @param out XmlSerializer to write the object into.
+     * @param callback Handler for Object types not recognized.
+     *
+     * @see #writeMapXml
+     * @see #writeListXml
+     * @see #readValueXml
+     */
+    private static final void writeValueXml(Object v, String name, XmlSerializer out,
+            WriteMapCallback callback)  throws XmlPullParserException, IOException {
+        String typeStr;
+        if (v == null) {
+            out.startTag(null, "null");
+            if (name != null) {
+                out.attribute(null, "name", name);
+            }
+            out.endTag(null, "null");
+            return;
+        } else if (v instanceof String) {
+            out.startTag(null, "string");
+            if (name != null) {
+                out.attribute(null, "name", name);
+            }
+            out.text(v.toString());
+            out.endTag(null, "string");
+            return;
+        } else if (v instanceof Integer) {
+            typeStr = "int";
+        } else if (v instanceof Long) {
+            typeStr = "long";
+        } else if (v instanceof Float) {
+            typeStr = "float";
+        } else if (v instanceof Double) {
+            typeStr = "double";
+        } else if (v instanceof Boolean) {
+            typeStr = "boolean";
+        } else if (v instanceof byte[]) {
+            writeByteArrayXml((byte[])v, name, out);
+            return;
+        } else if (v instanceof int[]) {
+            writeIntArrayXml((int[])v, name, out);
+            return;
+        } else if (v instanceof long[]) {
+            writeLongArrayXml((long[])v, name, out);
+            return;
+        } else if (v instanceof double[]) {
+            writeDoubleArrayXml((double[])v, name, out);
+            return;
+        } else if (v instanceof String[]) {
+            writeStringArrayXml((String[])v, name, out);
+            return;
+        } else if (v instanceof boolean[]) {
+            writeBooleanArrayXml((boolean[])v, name, out);
+            return;
+        } else if (v instanceof Map) {
+            writeMapXml((Map)v, name, out);
+            return;
+        } else if (v instanceof List) {
+            writeListXml((List) v, name, out);
+            return;
+        } else if (v instanceof Set) {
+            writeSetXml((Set) v, name, out);
+            return;
+        } else if (v instanceof CharSequence) {
+            // XXX This is to allow us to at least write something if
+            // we encounter styled text...  but it means we will drop all
+            // of the styling information. :(
+            out.startTag(null, "string");
+            if (name != null) {
+                out.attribute(null, "name", name);
+            }
+            out.text(v.toString());
+            out.endTag(null, "string");
+            return;
+        } else if (callback != null) {
+            callback.writeUnknownObject(v, name, out);
+            return;
+        } else {
+            throw new RuntimeException("writeValueXml: unable to write value " + v);
+        }
+
+        out.startTag(null, typeStr);
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+        out.attribute(null, "value", v.toString());
+        out.endTag(null, typeStr);
+    }
+
+    /**
+     * Read a HashMap from an InputStream containing XML.  The stream can
+     * previously have been written by writeMapXml().
+     *
+     * @param in The InputStream from which to read.
+     *
+     * @return HashMap The resulting map.
+     *
+     * @see #readListXml
+     * @see #readValueXml
+     * @see #readThisMapXml
+     * #see #writeMapXml
+     */
+    @SuppressWarnings("unchecked")
+    public static final HashMap<String, ?> readMapXml(InputStream in)
+    throws XmlPullParserException, IOException
+    {
+        XmlPullParser   parser = Xml.newPullParser();
+        parser.setInput(in, StandardCharsets.UTF_8.name());
+        return (HashMap<String, ?>) readValueXml(parser, new String[1]);
+    }
+
+    /**
+     * Read an ArrayList from an InputStream containing XML.  The stream can
+     * previously have been written by writeListXml().
+     *
+     * @param in The InputStream from which to read.
+     *
+     * @return ArrayList The resulting list.
+     *
+     * @see #readMapXml
+     * @see #readValueXml
+     * @see #readThisListXml
+     * @see #writeListXml
+     */
+    public static final ArrayList readListXml(InputStream in)
+    throws XmlPullParserException, IOException
+    {
+        XmlPullParser   parser = Xml.newPullParser();
+        parser.setInput(in, StandardCharsets.UTF_8.name());
+        return (ArrayList)readValueXml(parser, new String[1]);
+    }
+
+
+    /**
+     * Read a HashSet from an InputStream containing XML. The stream can
+     * previously have been written by writeSetXml().
+     *
+     * @param in The InputStream from which to read.
+     *
+     * @return HashSet The resulting set.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     *
+     * @see #readValueXml
+     * @see #readThisSetXml
+     * @see #writeSetXml
+     */
+    public static final HashSet readSetXml(InputStream in)
+            throws XmlPullParserException, IOException {
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(in, null);
+        return (HashSet) readValueXml(parser, new String[1]);
+    }
+
+    /**
+     * Read a HashMap object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeMapXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the map.
+     *
+     * @param parser The XmlPullParser from which to read the map data.
+     * @param endTag Name of the tag that will end the map, usually "map".
+     * @param name An array of one string, used to return the name attribute
+     *             of the map's tag.
+     *
+     * @return HashMap The newly generated map.
+     *
+     * @see #readMapXml
+     */
+    public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+        return readThisMapXml(parser, endTag, name, null);
+    }
+
+    /**
+     * Read a HashMap object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeMapXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the map.
+     *
+     * @param parser The XmlPullParser from which to read the map data.
+     * @param endTag Name of the tag that will end the map, usually "map".
+     * @param name An array of one string, used to return the name attribute
+     *             of the map's tag.
+     *
+     * @return HashMap The newly generated map.
+     *
+     * @see #readMapXml
+     * @hide
+     */
+    public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag,
+            String[] name, ReadMapCallback callback)
+            throws XmlPullParserException, IOException
+    {
+        HashMap<String, Object> map = new HashMap<String, Object>();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, false);
+                map.put(name[0], val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return map;
+                }
+                throw new XmlPullParserException(
+                    "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Like {@link #readThisMapXml}, but returns an ArrayMap instead of HashMap.
+     * @hide
+     */
+    public static final ArrayMap<String, ?> readThisArrayMapXml(XmlPullParser parser, String endTag,
+            String[] name, ReadMapCallback callback)
+            throws XmlPullParserException, IOException
+    {
+        ArrayMap<String, Object> map = new ArrayMap<>();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, true);
+                map.put(name[0], val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return map;
+                }
+                throw new XmlPullParserException(
+                    "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read an ArrayList object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeListXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return HashMap The newly generated list.
+     *
+     * @see #readListXml
+     */
+    public static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+        return readThisListXml(parser, endTag, name, null, false);
+    }
+
+    /**
+     * Read an ArrayList object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeListXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return HashMap The newly generated list.
+     *
+     * @see #readListXml
+     */
+    private static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
+            String[] name, ReadMapCallback callback, boolean arrayMap)
+            throws XmlPullParserException, IOException {
+        ArrayList list = new ArrayList();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, arrayMap);
+                list.add(val);
+                //System.out.println("Adding to list: " + val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return list;
+                }
+                throw new XmlPullParserException(
+                    "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a HashSet object from an XmlPullParser. The XML data could previously
+     * have been generated by writeSetXml(). The XmlPullParser must be positioned
+     * <em>after</em> the tag that begins the set.
+     *
+     * @param parser The XmlPullParser from which to read the set data.
+     * @param endTag Name of the tag that will end the set, usually "set".
+     * @param name An array of one string, used to return the name attribute
+     *             of the set's tag.
+     *
+     * @return HashSet The newly generated set.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     *
+     * @see #readSetXml
+     */
+    public static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name)
+            throws XmlPullParserException, IOException {
+        return readThisSetXml(parser, endTag, name, null, false);
+    }
+
+    /**
+     * Read a HashSet object from an XmlPullParser. The XML data could previously
+     * have been generated by writeSetXml(). The XmlPullParser must be positioned
+     * <em>after</em> the tag that begins the set.
+     *
+     * @param parser The XmlPullParser from which to read the set data.
+     * @param endTag Name of the tag that will end the set, usually "set".
+     * @param name An array of one string, used to return the name attribute
+     *             of the set's tag.
+     *
+     * @return HashSet The newly generated set.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     *
+     * @see #readSetXml
+     * @hide
+     */
+    private static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name,
+            ReadMapCallback callback, boolean arrayMap)
+            throws XmlPullParserException, IOException {
+        HashSet set = new HashSet();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, arrayMap);
+                set.add(val);
+                //System.out.println("Adding to set: " + val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return set;
+                }
+                throw new XmlPullParserException(
+                        "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+                "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read an int[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeIntArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated int[].
+     *
+     * @see #readListXml
+     */
+    public static final int[] readThisIntArrayXml(XmlPullParser parser,
+            String endTag, String[] name)
+            throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException(
+                    "Need num attribute in byte-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException(
+                    "Not a number in num attribute in byte-array");
+        }
+        parser.next();
+
+        int[] array = new int[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Integer.parseInt(
+                                parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException(
+                                "Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException(
+                                "Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException(
+                            "Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException(
+                        "Expected " + endTag + " end tag at: "
+                        + parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a long[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeLongArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated long[].
+     *
+     * @see #readListXml
+     */
+    public static final long[] readThisLongArrayXml(XmlPullParser parser,
+            String endTag, String[] name)
+            throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in long-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in long-array");
+        }
+        parser.next();
+
+        long[] array = new long[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Long.parseLong(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a double[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeDoubleArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "double-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated double[].
+     *
+     * @see #readListXml
+     */
+    public static final double[] readThisDoubleArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in double-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in double-array");
+        }
+        parser.next();
+
+        double[] array = new double[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Double.parseDouble(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a String[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeStringArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "string-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated String[].
+     *
+     * @see #readListXml
+     */
+    public static final String[] readThisStringArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in string-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in string-array");
+        }
+        parser.next();
+
+        String[] array = new String[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = parser.getAttributeValue(null, "value");
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a boolean[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeBooleanArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "string-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated boolean[].
+     *
+     * @see #readListXml
+     */
+    public static final boolean[] readThisBooleanArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in string-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in string-array");
+        }
+        parser.next();
+
+        boolean[] array = new boolean[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Boolean.valueOf(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a flattened object from an XmlPullParser.  The XML data could
+     * previously have been written with writeMapXml(), writeListXml(), or
+     * writeValueXml().  The XmlPullParser must be positioned <em>at</em> the
+     * tag that defines the value.
+     *
+     * @param parser The XmlPullParser from which to read the object.
+     * @param name An array of one string, used to return the name attribute
+     *             of the value's tag.
+     *
+     * @return Object The newly generated value object.
+     *
+     * @see #readMapXml
+     * @see #readListXml
+     * @see #writeValueXml
+     */
+    public static final Object readValueXml(XmlPullParser parser, String[] name)
+    throws XmlPullParserException, IOException
+    {
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                return readThisValueXml(parser, name, null, false);
+            } else if (eventType == parser.END_TAG) {
+                throw new XmlPullParserException(
+                    "Unexpected end tag at: " + parser.getName());
+            } else if (eventType == parser.TEXT) {
+                throw new XmlPullParserException(
+                    "Unexpected text: " + parser.getText());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Unexpected end of document");
+    }
+
+    private static final Object readThisValueXml(XmlPullParser parser, String[] name,
+            ReadMapCallback callback, boolean arrayMap)
+            throws XmlPullParserException, IOException {
+        final String valueName = parser.getAttributeValue(null, "name");
+        final String tagName = parser.getName();
+
+        //System.out.println("Reading this value tag: " + tagName + ", name=" + valueName);
+
+        Object res;
+
+        if (tagName.equals("null")) {
+            res = null;
+        } else if (tagName.equals("string")) {
+            String value = "";
+            int eventType;
+            while ((eventType = parser.next()) != parser.END_DOCUMENT) {
+                if (eventType == parser.END_TAG) {
+                    if (parser.getName().equals("string")) {
+                        name[0] = valueName;
+                        //System.out.println("Returning value for " + valueName + ": " + value);
+                        return value;
+                    }
+                    throw new XmlPullParserException(
+                        "Unexpected end tag in <string>: " + parser.getName());
+                } else if (eventType == parser.TEXT) {
+                    value += parser.getText();
+                } else if (eventType == parser.START_TAG) {
+                    throw new XmlPullParserException(
+                        "Unexpected start tag in <string>: " + parser.getName());
+                }
+            }
+            throw new XmlPullParserException(
+                "Unexpected end of document in <string>");
+        } else if ((res = readThisPrimitiveValueXml(parser, tagName)) != null) {
+            // all work already done by readThisPrimitiveValueXml
+        } else if (tagName.equals("int-array")) {
+            res = readThisIntArrayXml(parser, "int-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("long-array")) {
+            res = readThisLongArrayXml(parser, "long-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("double-array")) {
+            res = readThisDoubleArrayXml(parser, "double-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("string-array")) {
+            res = readThisStringArrayXml(parser, "string-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("boolean-array")) {
+            res = readThisBooleanArrayXml(parser, "boolean-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("map")) {
+            parser.next();
+            res = arrayMap
+                    ? readThisArrayMapXml(parser, "map", name, callback)
+                    : readThisMapXml(parser, "map", name, callback);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("list")) {
+            parser.next();
+            res = readThisListXml(parser, "list", name, callback, arrayMap);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("set")) {
+            parser.next();
+            res = readThisSetXml(parser, "set", name, callback, arrayMap);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (callback != null) {
+            res = callback.readThisUnknownObjectXml(parser, tagName);
+            name[0] = valueName;
+            return res;
+        } else {
+            throw new XmlPullParserException("Unknown tag: " + tagName);
+        }
+
+        // Skip through to end tag.
+        int eventType;
+        while ((eventType = parser.next()) != parser.END_DOCUMENT) {
+            if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(tagName)) {
+                    name[0] = valueName;
+                    //System.out.println("Returning value for " + valueName + ": " + res);
+                    return res;
+                }
+                throw new XmlPullParserException(
+                    "Unexpected end tag in <" + tagName + ">: " + parser.getName());
+            } else if (eventType == parser.TEXT) {
+                throw new XmlPullParserException(
+                "Unexpected text in <" + tagName + ">: " + parser.getName());
+            } else if (eventType == parser.START_TAG) {
+                throw new XmlPullParserException(
+                    "Unexpected start tag in <" + tagName + ">: " + parser.getName());
+            }
+        }
+        throw new XmlPullParserException(
+            "Unexpected end of document in <" + tagName + ">");
+    }
+
+    private static final Object readThisPrimitiveValueXml(XmlPullParser parser, String tagName)
+    throws XmlPullParserException, IOException
+    {
+        try {
+            if (tagName.equals("int")) {
+                return Integer.parseInt(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("long")) {
+                return Long.valueOf(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("float")) {
+                return new Float(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("double")) {
+                return new Double(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("boolean")) {
+                return Boolean.valueOf(parser.getAttributeValue(null, "value"));
+            } else {
+                return null;
+            }
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need value attribute in <" + tagName + ">");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException(
+                    "Not a number in value attribute in <" + tagName + ">");
+        }
+    }
+
+    public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException
+    {
+        int type;
+        while ((type=parser.next()) != parser.START_TAG
+                   && type != parser.END_DOCUMENT) {
+            ;
+        }
+
+        if (type != parser.START_TAG) {
+            throw new XmlPullParserException("No start tag found");
+        }
+
+        if (!parser.getName().equals(firstElementName)) {
+            throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
+                    ", expected " + firstElementName);
+        }
+    }
+
+    public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException
+    {
+        int type;
+        while ((type=parser.next()) != parser.START_TAG
+                   && type != parser.END_DOCUMENT) {
+            ;
+        }
+    }
+
+    public static boolean nextElementWithin(XmlPullParser parser, int outerDepth)
+            throws IOException, XmlPullParserException {
+        for (;;) {
+            int type = parser.next();
+            if (type == XmlPullParser.END_DOCUMENT
+                    || (type == XmlPullParser.END_TAG && parser.getDepth() == outerDepth)) {
+                return false;
+            }
+            if (type == XmlPullParser.START_TAG
+                    && parser.getDepth() == outerDepth + 1) {
+                return true;
+            }
+        }
+    }
+
+    public static int readIntAttribute(XmlPullParser in, String name, int defaultValue) {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    public static int readIntAttribute(XmlPullParser in, String name) throws IOException {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            throw new ProtocolException("problem parsing " + name + "=" + value + " as int");
+        }
+    }
+
+    public static void writeIntAttribute(XmlSerializer out, String name, int value)
+            throws IOException {
+        out.attribute(null, name, Integer.toString(value));
+    }
+
+    public static long readLongAttribute(XmlPullParser in, String name, long defaultValue) {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Long.parseLong(value);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    public static long readLongAttribute(XmlPullParser in, String name) throws IOException {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Long.parseLong(value);
+        } catch (NumberFormatException e) {
+            throw new ProtocolException("problem parsing " + name + "=" + value + " as long");
+        }
+    }
+
+    public static void writeLongAttribute(XmlSerializer out, String name, long value)
+            throws IOException {
+        out.attribute(null, name, Long.toString(value));
+    }
+
+    public static float readFloatAttribute(XmlPullParser in, String name) throws IOException {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Float.parseFloat(value);
+        } catch (NumberFormatException e) {
+            throw new ProtocolException("problem parsing " + name + "=" + value + " as long");
+        }
+    }
+
+    public static void writeFloatAttribute(XmlSerializer out, String name, float value)
+            throws IOException {
+        out.attribute(null, name, Float.toString(value));
+    }
+
+    public static boolean readBooleanAttribute(XmlPullParser in, String name) {
+        final String value = in.getAttributeValue(null, name);
+        return Boolean.parseBoolean(value);
+    }
+
+    public static boolean readBooleanAttribute(XmlPullParser in, String name,
+            boolean defaultValue) {
+        final String value = in.getAttributeValue(null, name);
+        if (value == null) {
+            return defaultValue;
+        } else {
+            return Boolean.parseBoolean(value);
+        }
+    }
+
+    public static void writeBooleanAttribute(XmlSerializer out, String name, boolean value)
+            throws IOException {
+        out.attribute(null, name, Boolean.toString(value));
+    }
+
+    public static Uri readUriAttribute(XmlPullParser in, String name) {
+        final String value = in.getAttributeValue(null, name);
+        return (value != null) ? Uri.parse(value) : null;
+    }
+
+    public static void writeUriAttribute(XmlSerializer out, String name, Uri value)
+            throws IOException {
+        if (value != null) {
+            out.attribute(null, name, value.toString());
+        }
+    }
+
+    public static String readStringAttribute(XmlPullParser in, String name) {
+        return in.getAttributeValue(null, name);
+    }
+
+    public static void writeStringAttribute(XmlSerializer out, String name, String value)
+            throws IOException {
+        if (value != null) {
+            out.attribute(null, name, value);
+        }
+    }
+
+    public static byte[] readByteArrayAttribute(XmlPullParser in, String name) {
+        final String value = in.getAttributeValue(null, name);
+        if (value != null) {
+            return Base64.decode(value, Base64.DEFAULT);
+        } else {
+            return null;
+        }
+    }
+
+    public static void writeByteArrayAttribute(XmlSerializer out, String name, byte[] value)
+            throws IOException {
+        if (value != null) {
+            out.attribute(null, name, Base64.encodeToString(value, Base64.DEFAULT));
+        }
+    }
+
+    public static Bitmap readBitmapAttribute(XmlPullParser in, String name) {
+        final byte[] value = readByteArrayAttribute(in, name);
+        if (value != null) {
+            return BitmapFactory.decodeByteArray(value, 0, value.length);
+        } else {
+            return null;
+        }
+    }
+
+    @Deprecated
+    public static void writeBitmapAttribute(XmlSerializer out, String name, Bitmap value)
+            throws IOException {
+        if (value != null) {
+            final ByteArrayOutputStream os = new ByteArrayOutputStream();
+            value.compress(CompressFormat.PNG, 90, os);
+            writeByteArrayAttribute(out, name, os.toByteArray());
+        }
+    }
+
+    /** @hide */
+    public interface WriteMapCallback {
+        /**
+         * Called from writeMapXml when an Object type is not recognized. The implementer
+         * must write out the entire element including start and end tags.
+         *
+         * @param v The object to be written out
+         * @param name The mapping key for v. Must be written into the "name" attribute of the
+         *             start tag.
+         * @param out The XML output stream.
+         * @throws XmlPullParserException on unrecognized Object type.
+         * @throws IOException on XmlSerializer serialization errors.
+         * @hide
+         */
+         public void writeUnknownObject(Object v, String name, XmlSerializer out)
+                 throws XmlPullParserException, IOException;
+    }
+
+    /** @hide */
+    public interface ReadMapCallback {
+        /**
+         * Called from readThisMapXml when a START_TAG is not recognized. The input stream
+         * is positioned within the start tag so that attributes can be read using in.getAttribute.
+         *
+         * @param in the XML input stream
+         * @param tag the START_TAG that was not recognized.
+         * @return the Object parsed from the stream which will be put into the map.
+         * @throws XmlPullParserException if the START_TAG is not recognized.
+         * @throws IOException on XmlPullParser serialization errors.
+         * @hide
+         */
+        public Object readThisUnknownObjectXml(XmlPullParser in, String tag)
+                throws XmlPullParserException, IOException;
+    }
+}
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 aaab8c4..cb3de2a 100644
--- a/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PackageManagerTest.java
@@ -107,10 +107,10 @@
         checkActivityInfoName(RECEIVER_NAME, broadcastReceivers);
 
         // Test queryPermissionsByGroup, queryContentProviders
-        String testPermissionsGroup = "android.permission-group.NETWORK";
+        String testPermissionsGroup = "android.permission-group.COST_MONEY";
         List<PermissionInfo> permissions = mPackageManager.queryPermissionsByGroup(
                 testPermissionsGroup, PackageManager.GET_META_DATA);
-        checkPermissionInfoName(PERMISSION_NAME, permissions);
+        checkPermissionInfoName("com.android.cts.content.CALL_ABROAD_PERMISSION", permissions);
 
         ApplicationInfo appInfo = mPackageManager.getApplicationInfo(PACKAGE_NAME, 0);
         List<ProviderInfo> providers = mPackageManager.queryContentProviders(PACKAGE_NAME,
@@ -148,17 +148,12 @@
     }
 
     private void checkPermissionInfoName(String expectedName, List<PermissionInfo> permissions) {
-        boolean isContained = false;
-        Iterator<PermissionInfo> infoIterator = permissions.iterator();
-        String current;
-        while (infoIterator.hasNext()) {
-            current = infoIterator.next().name;
-            if (current.equals(expectedName)) {
-                isContained = true;
-                break;
-            }
+        List<String> names = new ArrayList<String>();
+        for (PermissionInfo permission : permissions) {
+            names.add(permission.name);
         }
-        assertTrue(isContained);
+        boolean isContained = names.contains(expectedName);
+        assertTrue("Permission " + expectedName + " not present in " + names, isContained);
     }
 
     private void checkProviderInfoName(String expectedName, List<ProviderInfo> providers) {
diff --git a/tests/tests/content/src/android/content/pm/cts/PermissionGroupInfoTest.java b/tests/tests/content/src/android/content/pm/cts/PermissionGroupInfoTest.java
index fc8d9b8..8b00624 100644
--- a/tests/tests/content/src/android/content/pm/cts/PermissionGroupInfoTest.java
+++ b/tests/tests/content/src/android/content/pm/cts/PermissionGroupInfoTest.java
@@ -24,8 +24,9 @@
 import android.test.AndroidTestCase;
 
 public class PermissionGroupInfoTest extends AndroidTestCase {
-    private static final String PERMISSIONGROUP_NAME = "android.permission-group.COST_MONEY";
-    private static final String DEFAULT_DISCRIPTION = "Do things that can cost you money.";
+    private static final String GROUP = "android.permission-group.COST_MONEY";
+    private static final String GROUP_NAME = "Cost money";
+    private static final String GROUP_DESCRIPTION = "Do things that can cost you money.";
 
     public void testPermissionGroupInfo() throws NameNotFoundException {
         PackageManager pm = getContext().getPackageManager();
@@ -33,14 +34,15 @@
         // Test constructors
         new PermissionGroupInfo();
         PermissionGroupInfo permissionGroupInfo = pm
-                .getPermissionGroupInfo(PERMISSIONGROUP_NAME, 0);
+                .getPermissionGroupInfo(GROUP, 0);
         PermissionGroupInfo infoFromExisted = new PermissionGroupInfo(permissionGroupInfo);
         checkInfoSame(permissionGroupInfo, infoFromExisted);
 
         // Test toString, describeContents, loadDescription
         assertNotNull(permissionGroupInfo.toString());
         assertEquals(0, permissionGroupInfo.describeContents());
-        assertEquals(DEFAULT_DISCRIPTION, permissionGroupInfo.loadDescription(pm));
+        assertEquals(GROUP_NAME, permissionGroupInfo.loadLabel(pm));
+        assertEquals(GROUP_DESCRIPTION, permissionGroupInfo.loadDescription(pm));
 
         // Test writeToParcel
         permissionGroupInfo.writeToParcel(p, 0);
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 2870fee..e8d363b 100644
--- a/tests/tests/content/src/android/content/res/cts/AssetManagerTest.java
+++ b/tests/tests/content/src/android/content/res/cts/AssetManagerTest.java
@@ -15,14 +15,12 @@
  */
 package android.content.res.cts;
 
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
+import com.android.cts.content.R;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.cts.util.XmlUtils;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.AssetManager;
 import android.content.res.Resources;
@@ -30,8 +28,10 @@
 import android.test.AndroidTestCase;
 import android.util.TypedValue;
 
-import com.android.cts.content.R;
-import com.android.internal.util.XmlUtils;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 
 
 public class AssetManagerTest extends AndroidTestCase{
diff --git a/tests/tests/content/src/android/content/res/cts/PrivateAttributeTest.java b/tests/tests/content/src/android/content/res/cts/PrivateAttributeTest.java
index 35466be..3024896 100644
--- a/tests/tests/content/src/android/content/res/cts/PrivateAttributeTest.java
+++ b/tests/tests/content/src/android/content/res/cts/PrivateAttributeTest.java
@@ -26,7 +26,7 @@
  */
 public class PrivateAttributeTest extends AndroidTestCase {
 
-    private static final int sLastPublicAttr = 0x010104d5;
+    private static final int sLastPublicAttr = 0x010104f1;
 
     public void testNoAttributesAfterLastPublicAttribute() throws Exception {
         final Resources res = getContext().getResources();
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 88caa6f..4e2d60a 100644
--- a/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
+++ b/tests/tests/content/src/android/content/res/cts/ResourcesTest.java
@@ -17,20 +17,19 @@
 package android.content.res.cts;
 
 import com.android.cts.content.R;
-import com.android.internal.util.XmlUtils;
-
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.Context;
+import android.content.cts.util.XmlUtils;
 import android.content.res.AssetManager;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.content.res.Resources.NotFoundException;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
-import android.content.res.Resources.NotFoundException;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.test.AndroidTestCase;
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 349cb47..6d1c2e4 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
@@ -18,6 +18,8 @@
 
 import org.xmlpull.v1.XmlPullParser;
 
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.Resources.Theme;
@@ -25,9 +27,12 @@
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.util.Xml;
+import android.view.View;
 
 import com.android.cts.content.R;
 
+import java.util.Locale;
+
 
 public class Resources_ThemeTest extends AndroidTestCase {
 
@@ -78,4 +83,51 @@
         assertFalse(mResTheme.resolveAttribute(R.raw.testmp3, value, false));
     }
 
+    public void testGetChangingConfigurations() {
+        Resources.Theme theme = getContext().getResources().newTheme();
+        assertEquals("Initial changing configuration mask is empty",
+                0, theme.getChangingConfigurations());
+
+        theme.applyStyle(R.style.Theme_OrientationDependent, true);
+        assertEquals("First call to Theme.applyStyle() sets changing configuration",
+                ActivityInfo.CONFIG_ORIENTATION, theme.getChangingConfigurations());
+
+        theme.applyStyle(R.style.Theme_LayoutDirectionDependent, true);
+        assertEquals("Multiple calls to Theme.applyStyle() update changing configuration",
+                ActivityInfo.CONFIG_ORIENTATION | ActivityInfo.CONFIG_LAYOUT_DIRECTION,
+                theme.getChangingConfigurations());
+
+        Resources.Theme other = getContext().getResources().newTheme();
+        other.setTo(theme);
+        assertEquals("Theme.setTheme() copies changing confguration",
+                ActivityInfo.CONFIG_ORIENTATION | ActivityInfo.CONFIG_LAYOUT_DIRECTION,
+                theme.getChangingConfigurations());
+    }
+
+    public void testRebase() {
+        Resources res = getContext().getResources();
+        Configuration config = res.getConfiguration();
+        config.setLocale(Locale.ENGLISH);
+        assertEquals("Theme will be created in LTR config",
+                View.LAYOUT_DIRECTION_LTR, config.getLayoutDirection());
+
+        Resources.Theme theme = res.newTheme();
+        theme.applyStyle(R.style.Theme_LayoutIsRTL, true);
+
+        TypedArray t = theme.obtainStyledAttributes(new int[] { R.attr.themeBoolean });
+        assertEquals("Theme was created in LTR config", false, t.getBoolean(0, true));
+        t.recycle();
+
+        config.setLocale(new Locale("iw"));
+        res.updateConfiguration(config, null);
+
+        assertEquals("Theme will be rebased in RTL config",
+                View.LAYOUT_DIRECTION_RTL, config.getLayoutDirection());
+
+        theme.rebase();
+
+        t = theme.obtainStyledAttributes(new int[] { R.attr.themeBoolean });
+        assertEquals("Theme was rebased in RTL config", true, t.getBoolean(0, false));
+        t.recycle();
+    }
 }
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 cc6c5ec..346bb9b 100644
--- a/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
+++ b/tests/tests/content/src/android/content/res/cts/TypedArrayTest.java
@@ -16,10 +16,11 @@
 
 package android.content.res.cts;
 
-import java.io.IOException;
+import com.android.cts.content.R;
 
 import org.xmlpull.v1.XmlPullParserException;
 
+import android.content.cts.util.XmlUtils;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.test.AndroidTestCase;
@@ -27,8 +28,7 @@
 import android.util.TypedValue;
 import android.view.ContextThemeWrapper;
 
-import com.android.cts.content.R;
-import com.android.internal.util.XmlUtils;
+import java.io.IOException;
 
 
 public class TypedArrayTest extends AndroidTestCase{
diff --git a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
index 078c2dd..14cd6d5 100644
--- a/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
+++ b/tests/tests/database/src/android/database/cts/AbstractCursorTest.java
@@ -376,6 +376,12 @@
         }
     }
 
+    public void testSetExtras() {
+        Bundle b = new Bundle();
+        mTestAbstractCursor.setExtras(b);
+        assertSame(b, mTestAbstractCursor.getExtras());
+    }
+
     @SuppressWarnings("unchecked")
     private static ArrayList<ArrayList> createTestList(int rows, int cols) {
         ArrayList<ArrayList> list = new ArrayList<ArrayList>();
@@ -431,7 +437,6 @@
         public TestAbstractCursor(String[] columnNames, ArrayList<ArrayList> rows) {
             int colCount = columnNames.length;
             boolean foundID = false;
-            mRowIdColumnIndex = 0;
 
             // Add an _id column if not in columnNames
             for (int i = 0; i < colCount; ++i) {
diff --git a/tests/tests/database/src/android/database/cts/CursorWrapperTest.java b/tests/tests/database/src/android/database/cts/CursorWrapperTest.java
index 9d517dc..7c0ce56 100644
--- a/tests/tests/database/src/android/database/cts/CursorWrapperTest.java
+++ b/tests/tests/database/src/android/database/cts/CursorWrapperTest.java
@@ -402,7 +402,7 @@
         cursorWrapper.close();
     }
 
-    public void testContentObsererOperations() throws IllegalStateException {
+    public void testContentObserverOperations() throws IllegalStateException {
         CursorWrapper cursorWrapper = new CursorWrapper(getCursor());
         MockContentObserver observer = new MockContentObserver(null);
 
@@ -437,6 +437,18 @@
         cursorWrapper.close();
     }
 
+    public void testSetExtras() {
+        Cursor cursor = getCursor();
+        CursorWrapper cursorWrapper = new CursorWrapper(cursor);
+        try {
+            Bundle b = new Bundle();
+            cursorWrapper.setExtras(b);
+            assertSame(b, cursor.getExtras());
+        } finally {
+            cursorWrapper.close();
+        }
+    }
+
     private class MockContentObserver extends ContentObserver {
 
         public MockContentObserver(Handler handler) {
diff --git a/tests/tests/deqp/Android.mk b/tests/tests/deqp/Android.mk
index d8a4dda..ce8678b 100644
--- a/tests/tests/deqp/Android.mk
+++ b/tests/tests/deqp/Android.mk
@@ -21,6 +21,13 @@
 # All APIs share the same package
 LOCAL_PACKAGE_NAME := com.drawelements.deqp
 
+include $(LOCAL_PATH)/deqp_egl.mk
 include $(LOCAL_PATH)/deqp_gles2.mk
 include $(LOCAL_PATH)/deqp_gles3.mk
 include $(LOCAL_PATH)/deqp_gles31.mk
+
+# Make the deqp app and copy it to CTS out dir.
+cts_deqp_name := com.drawelements.deqp
+cts_deqp_apk := $(CTS_TESTCASES_OUT)/$(cts_deqp_name).apk
+$(cts_deqp_apk): $(call intermediates-dir-for,APPS,$(cts_deqp_name))/package.apk
+	$(call copy-file-to-target)
diff --git a/tests/tests/deqp/deqp_egl.mk b/tests/tests/deqp/deqp_egl.mk
new file mode 100644
index 0000000..6b4eed6
--- /dev/null
+++ b/tests/tests/deqp/deqp_egl.mk
@@ -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.
+
+# Dummy target to make dEQP EGL test list generation consistent with other
+# tests.
+
+DEQP_API := egl
+DEQP_TEST_NAME := dEQP-EGL
+
+include $(BUILD_CTS_DEQP_PACKAGE)
diff --git a/tests/tests/display/Android.mk b/tests/tests/display/Android.mk
index a48a8e3..f17f580 100644
--- a/tests/tests/display/Android.mk
+++ b/tests/tests/display/Android.mk
@@ -29,7 +29,4 @@
 
 LOCAL_SDK_VERSION := current
 
-# This test runner sets up/cleans up the device before/after running the tests.
-LOCAL_CTS_TEST_RUNNER := com.android.cts.tradefed.testtype.DisplayTestRunner
-
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/display/AndroidManifest.xml b/tests/tests/display/AndroidManifest.xml
index 0b24754..bf84219 100644
--- a/tests/tests/display/AndroidManifest.xml
+++ b/tests/tests/display/AndroidManifest.xml
@@ -19,6 +19,8 @@
     package="com.android.cts.display">
 
     <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" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/tests/display/AndroidTest.xml b/tests/tests/display/AndroidTest.xml
new file mode 100644
index 0000000..dd42984
--- /dev/null
+++ b/tests/tests/display/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="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 bea99ed..1f9f8d1 100644
--- a/tests/tests/display/src/android/display/cts/DisplayTest.java
+++ b/tests/tests/display/src/android/display/cts/DisplayTest.java
@@ -16,18 +16,34 @@
 
 package android.display.cts;
 
+import android.app.Presentation;
+import android.app.UiAutomation;
 import android.content.Context;
+import android.graphics.Color;
 import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.hardware.display.DisplayManager;
-import android.test.AndroidTestCase;
+import android.hardware.display.DisplayManager.DisplayListener;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+import android.test.InstrumentationTestCase;
 import android.util.DisplayMetrics;
 import android.view.Display;
+import android.view.View;
+import android.view.ViewGroup;
 import android.view.WindowManager;
 
-public class DisplayTest extends AndroidTestCase {
-    // This test is called from DisplayTestRunner which brings up an overlay display on the target
-    // device. The overlay display parameters must match the ones defined there which are
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Scanner;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class DisplayTest extends InstrumentationTestCase {
+    // The CTS package brings up an overlay display on the target device (see AndroidTest.xml).
+    // The overlay display parameters must match the ones defined there which are
     // 181x161/214 (wxh/dpi).  It only matters that these values are different from any real
     // display.
 
@@ -43,14 +59,47 @@
 
     private DisplayManager mDisplayManager;
     private WindowManager mWindowManager;
+    private Context mContext;
+
+    // To test display mode switches.
+    private TestPresentation mPresentation;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        mContext = getInstrumentation().getContext();
         mDisplayManager = (DisplayManager)mContext.getSystemService(Context.DISPLAY_SERVICE);
         mWindowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
     }
 
+    private void enableAppOps() {
+        StringBuilder cmd = new StringBuilder();
+        cmd.append("appops set ");
+        cmd.append(getInstrumentation().getContext().getPackageName());
+        cmd.append(" android:system_alert_window allow");
+        getInstrumentation().getUiAutomation().executeShellCommand(cmd.toString());
+
+        StringBuilder query = new StringBuilder();
+        query.append("appops get ");
+        query.append(getInstrumentation().getContext().getPackageName());
+        query.append(" android:system_alert_window");
+        String queryStr = query.toString();
+
+        String result = "No operations.";
+        while (result.contains("No operations")) {
+            ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation().executeShellCommand(
+                    queryStr);
+            InputStream inputStream = new FileInputStream(pfd.getFileDescriptor());
+            result = convertStreamToString(inputStream);
+        }
+    }
+
+    private String convertStreamToString(InputStream is) {
+        try (java.util.Scanner s = new Scanner(is).useDelimiter("\\A")) {
+            return s.hasNext() ? s.next() : "";
+        }
+    }
+
     private boolean isSecondarySize(Display display) {
         final Point p = new Point();
         display.getSize(p);
@@ -177,4 +226,106 @@
 
         assertEquals(Display.FLAG_PRESENTATION, display.getFlags());
     }
+
+    /**
+     * Tests that the mode-related attributes and methods work as expected.
+     */
+    public void testMode() {
+        Display display = getSecondaryDisplay(mDisplayManager.getDisplays());
+        assertEquals(2, display.getSupportedModes().length);
+        Display.Mode mode = display.getMode();
+        assertEquals(display.getSupportedModes()[0], mode);
+        assertEquals(SECONDARY_DISPLAY_WIDTH, mode.getPhysicalWidth());
+        assertEquals(SECONDARY_DISPLAY_HEIGHT, mode.getPhysicalHeight());
+        assertEquals(display.getRefreshRate(), mode.getRefreshRate());
+    }
+
+    /**
+     * Tests that mode switch requests are correctly executed.
+     */
+    public void testModeSwitch() throws Exception {
+        enableAppOps();
+        final Display display = getSecondaryDisplay(mDisplayManager.getDisplays());
+        Display.Mode[] modes = display.getSupportedModes();
+        assertEquals(2, modes.length);
+        Display.Mode mode = display.getMode();
+        assertEquals(modes[0], mode);
+        final Display.Mode newMode = modes[1];
+
+        Handler handler = new Handler(Looper.getMainLooper());
+
+        // Register for display events.
+        final CountDownLatch changeSignal = new CountDownLatch(1);
+        mDisplayManager.registerDisplayListener(new DisplayListener() {
+            @Override
+            public void onDisplayAdded(int displayId) {}
+
+            @Override
+            public void onDisplayChanged(int displayId) {
+                if (displayId == display.getDisplayId()) {
+                    changeSignal.countDown();
+                }
+            }
+
+            @Override
+            public void onDisplayRemoved(int displayId) {}
+        }, handler);
+
+        // Show the presentation.
+        final CountDownLatch presentationSignal = new CountDownLatch(1);
+        handler.post(new Runnable() {
+            @Override
+            public void run() {
+                mPresentation = new TestPresentation(
+                        getInstrumentation().getContext(), display, newMode.getModeId());
+                mPresentation.show();
+                presentationSignal.countDown();
+            }
+        });
+        assertTrue(presentationSignal.await(5, TimeUnit.SECONDS));
+
+        // Wait until the display change is effective.
+        assertTrue(changeSignal.await(5, TimeUnit.SECONDS));
+
+        assertEquals(newMode, display.getMode());
+        handler.post(new Runnable() {
+            @Override
+            public void run() {
+                mPresentation.dismiss();
+            }
+        });
+    }
+
+    /**
+     * Used to force mode changes on a display.
+     * <p>
+     * Note that due to limitations of the Presentation class, the modes must have the same size
+     * otherwise the presentation will be automatically dismissed.
+     */
+    private static final class TestPresentation extends Presentation {
+
+        private final int mModeId;
+
+        public TestPresentation(Context context, Display display, int modeId) {
+            super(context, display);
+            mModeId = modeId;
+        }
+
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            View content = new View(getContext());
+            content.setLayoutParams(new ViewGroup.LayoutParams(
+                    ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+            content.setBackgroundColor(Color.RED);
+            setContentView(content);
+
+            WindowManager.LayoutParams params = getWindow().getAttributes();
+            params.preferredDisplayModeId = mModeId;
+            params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+            params.setTitle("CtsTestPresentation");
+            getWindow().setAttributes(params);
+        }
+    }
 }
diff --git a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
index 238abec..e722646 100644
--- a/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
+++ b/tests/tests/dpi/src/android/dpi/cts/ConfigurationTest.java
@@ -59,7 +59,9 @@
         allowedDensities.add(DisplayMetrics.DENSITY_HIGH);
         allowedDensities.add(DisplayMetrics.DENSITY_280);
         allowedDensities.add(DisplayMetrics.DENSITY_XHIGH);
+        allowedDensities.add(DisplayMetrics.DENSITY_360);
         allowedDensities.add(DisplayMetrics.DENSITY_400);
+        allowedDensities.add(DisplayMetrics.DENSITY_420);
         allowedDensities.add(DisplayMetrics.DENSITY_XXHIGH);
         allowedDensities.add(DisplayMetrics.DENSITY_560);
         allowedDensities.add(DisplayMetrics.DENSITY_XXXHIGH);
diff --git a/tests/tests/dreams/Android.mk b/tests/tests/dreams/Android.mk
index eca3d83..87bd357 100644
--- a/tests/tests/dreams/Android.mk
+++ b/tests/tests/dreams/Android.mk
@@ -26,6 +26,8 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
 
+LOCAL_JAVA_LIBRARIES :=  android.test.runner
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 # Need access to ServiceManager - see b/13307221
diff --git a/tests/tests/dreams/src/android/service/dreams/cts/DreamServiceTest.java b/tests/tests/dreams/src/android/service/dreams/cts/DreamServiceTest.java
new file mode 100644
index 0000000..fcf6558
--- /dev/null
+++ b/tests/tests/dreams/src/android/service/dreams/cts/DreamServiceTest.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 android.service.dreams.cts;
+
+import android.service.dreams.DreamService;
+import android.test.InstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.view.ActionMode;
+
+public class DreamServiceTest extends InstrumentationTestCase {
+    @UiThreadTest
+    public void testOnWindowStartingActionMode() {
+        DreamService dreamService = new DreamService();
+
+        ActionMode actionMode = dreamService.onWindowStartingActionMode(null);
+
+        assertNull(actionMode);
+    }
+
+    @UiThreadTest
+    public void testOnWindowStartingActionModeTyped() {
+        DreamService dreamService = new DreamService();
+
+        ActionMode actionMode = dreamService.onWindowStartingActionMode(
+                null, ActionMode.TYPE_FLOATING);
+
+        assertNull(actionMode);
+    }
+}
diff --git a/tests/tests/drm/jni/android_drm_cts_NativeCodeTest.cpp b/tests/tests/drm/jni/android_drm_cts_NativeCodeTest.cpp
index 398a44e..e5c9f960 100644
--- a/tests/tests/drm/jni/android_drm_cts_NativeCodeTest.cpp
+++ b/tests/tests/drm/jni/android_drm_cts_NativeCodeTest.cpp
@@ -16,6 +16,7 @@
 
 #include <jni.h>
 #include <sys/types.h>
+#include <string.h>
 #include <unistd.h>
 #include <sys/syscall.h>
 #include <utils/Log.h>
diff --git a/tests/tests/graphics/AndroidManifest.xml b/tests/tests/graphics/AndroidManifest.xml
index 0006634..4249bb3 100644
--- a/tests/tests/graphics/AndroidManifest.xml
+++ b/tests/tests/graphics/AndroidManifest.xml
@@ -50,6 +50,7 @@
 
         <activity android:name="android.opengl.cts.OpenGlEsVersionCtsActivity"/>
 
+        <activity android:name="android.graphics.drawable.cts.DrawableStubActivity"/>
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/graphics/res/anim/animation_grouping_1_01.xml b/tests/tests/graphics/res/anim/animation_grouping_1_01.xml
index 8cc9f92..c1f2904 100644
--- a/tests/tests/graphics/res/anim/animation_grouping_1_01.xml
+++ b/tests/tests/graphics/res/anim/animation_grouping_1_01.xml
@@ -18,9 +18,9 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android" >
 
     <objectAnimator
-        android:duration="3300"
+        android:duration="50"
         android:propertyName="rotation"
         android:valueFrom="0"
         android:valueTo="180"
-        android:repeatCount="-1" />
+        android:repeatCount="2" />
 </set>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_1_golden.png
index 91776a9..67f5746 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_random_path_1_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 9af40a3..c60dfba 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 b3acfe7..e7cc4d1 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 bbc84b9..c7c049b 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_repeated_cq_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_cq_golden.png
index 8d73cfd..5880467 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_cq_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_cq_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_st_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_st_golden.png
index 6094a9a..93fb1d0 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_st_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_repeated_st_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_1_golden.png
new file mode 100644
index 0000000..899a235
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_2_golden.png
new file mode 100644
index 0000000..ba6d8c7
--- /dev/null
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_scale_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_2_golden.png
index aee8ff5..4141d6f 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_stroke_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_1_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_1_golden.png
index baf418d..1703878 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_1_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_1_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_2_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_2_golden.png
index e0e14f3..5308c7b 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_2_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_2_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_3_golden.png b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_3_golden.png
index b6798c2..e507b53 100644
--- a/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_3_golden.png
+++ b/tests/tests/graphics/res/drawable-nodpi/vector_icon_transformation_3_golden.png
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/inset_mutate.xml b/tests/tests/graphics/res/drawable/inset_mutate.xml
new file mode 100644
index 0000000..ba613e9
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/inset_mutate.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.
+ -->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+       android:drawable="@drawable/inset_mutate_testimage" />
diff --git a/tests/tests/graphics/res/drawable/inset_mutate_testimage.jpg b/tests/tests/graphics/res/drawable/inset_mutate_testimage.jpg
new file mode 100644
index 0000000..754df0c
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/inset_mutate_testimage.jpg
Binary files differ
diff --git a/tests/tests/graphics/res/drawable/rippledrawable_radius.xml b/tests/tests/graphics/res/drawable/rippledrawable_radius.xml
new file mode 100644
index 0000000..4701ef7
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/rippledrawable_radius.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
+  -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+        android:radius="10px"/>
diff --git a/tests/tests/graphics/res/drawable/vector_icon_clip_path_1.xml b/tests/tests/graphics/res/drawable/vector_icon_clip_path_1.xml
index c2ab429..53a9660 100644
--- a/tests/tests/graphics/res/drawable/vector_icon_clip_path_1.xml
+++ b/tests/tests/graphics/res/drawable/vector_icon_clip_path_1.xml
@@ -14,10 +14,10 @@
      limitations under the License.
 -->
 <vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:height="64dp"
-        android:width="64dp"
-        android:viewportHeight="12.25"
-        android:viewportWidth="7.30625" >
+    android:height="64dp"
+    android:viewportHeight="12.25"
+    android:viewportWidth="7.30625"
+    android:width="64dp" >
 
     <group
         android:pivotX="3.65"
@@ -31,14 +31,18 @@
                 l 0, 12.25
                 l -7.3, 0
                 z" />
-    </group>
-    <group>
-        <path
-            android:name="one"
-            android:fillColor="#ff88ff"
-            android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875 -2.109375,0.421875 0.0-1.078125
+
+        <group
+            android:pivotX="3.65"
+            android:pivotY="6.125"
+            android:rotation="30" >
+            <path
+                android:name="one"
+                android:fillColor="#ff88ff"
+                android:pathData="M 1.215625,9.5l 1.9375,0.0 0.0-6.671875 -2.109375,0.421875 0.0-1.078125
                 l 2.09375-0.421875 1.1874998,0.0 0.0,7.75 1.9375,0.0 0.0,1.0
                 l -5.046875,0.0 0.0-1.0Z" />
+        </group>
     </group>
     <group
         android:pivotX="3.65"
@@ -52,12 +56,15 @@
                 l 0, 6.125
                 l -7.3, 0
                 z" />
-    </group>
-    <group>
-        <path
-            android:name="two"
-            android:fillColor="#ff88ff"
-            android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375
+
+        <group
+            android:pivotX="3.65"
+            android:pivotY="6.125"
+            android:rotation="30" >
+            <path
+                android:name="two"
+                android:fillColor="#ff88ff"
+                android:pathData="M 2.534375,9.6875l 4.140625,0.0 0.0,1.0 -5.5625,0.0 0.0-1.0q 0.671875-0.6875 1.828125-1.859375
                         q 1.1718752-1.1875 1.4687502-1.53125 0.578125-0.625 0.796875-1.0625
                         q 0.234375-0.453125 0.234375-0.875 0.0-0.703125 -0.5-1.140625
                         q -0.484375-0.4375 -1.2656252-0.4375 -0.5625,0.0 -1.1875,0.1875
@@ -66,6 +73,7 @@
                         q 0.8125,0.671875 0.8125,1.8125 0.0,0.53125 -0.203125,1.015625
                         q -0.203125,0.484375 -0.734375,1.140625 -0.15625,0.171875 -0.9375,0.984375
                         q -0.78125024,0.8125 -2.2187502,2.265625Z" />
+        </group>
     </group>
 
 </vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_delete.xml b/tests/tests/graphics/res/drawable/vector_icon_delete.xml
index 8d9c21c..7b8f2aa 100644
--- a/tests/tests/graphics/res/drawable/vector_icon_delete.xml
+++ b/tests/tests/graphics/res/drawable/vector_icon_delete.xml
@@ -24,6 +24,6 @@
 
     <path
         android:fillColor="#FF000000"
-        android:pathData="M6.0,19.0c0.0,1.104 0.896,2.0 2.0,2.0l8.0,0.0c1.104,0.0 2.0-0.896 2.0-2.0l0.0-12.0L6.0,7.0L6.0,19.0zM18.0,4.0l-2.5,0.0l-1.0-1.0l-5.0,0.0l-1.0,1.0L6.0,4.0C5.4469986,4.0 5.0,4.4469986 5.0,5.0l0.0,1.0l14.0,0.0l0.0-1.0C19.0,4.4469986 18.552002,4.0 18.0,4.0z" />
+        android:pathData="M6.0,19.0c0.0,1.104 896e-3,2.0 2.0,2.0l8.0,0.0c1.104,0.0 2.0-896e-3 2.0-2.0l0.0-12.0L6.0,7.0L6.0,19.0zM18.0,4.0l-2.5,0.0l-1.0-1.0l-5.0,0.0l-1.0,1.0L6.0,4.0C5.4469986,4.0 5.0,4.4469986 5.0,5.0l0.0,1.0l14.0,0.0l0.0-1.0C19.0,4.4469986 18.552002,4.0 18.0,4.0z" />
 
 </vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_heart.xml b/tests/tests/graphics/res/drawable/vector_icon_heart.xml
index ff55fe5..ad991c9 100644
--- a/tests/tests/graphics/res/drawable/vector_icon_heart.xml
+++ b/tests/tests/graphics/res/drawable/vector_icon_heart.xml
@@ -24,6 +24,6 @@
 
     <path
         android:fillColor="#FF000000"
-        android:pathData="M16.0,5.0c-1.955,0.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" />
+        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_scale_1.xml b/tests/tests/graphics/res/drawable/vector_icon_scale_1.xml
new file mode 100644
index 0000000..530c73b
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_scale_1.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="64dp"
+    android:viewportHeight="200"
+    android:viewportWidth="200"
+    android:width="64dp" >
+
+    <group>
+        <path
+            android:name="background1"
+            android:fillColor="#FF000000"
+            android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+        <path
+            android:name="background2"
+            android:fillColor="#FF000000"
+            android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+    </group>
+    <group
+        android:scaleX="-1"
+        android:scaleY="-1" >
+        <group
+            android:scaleX="-1"
+            android:scaleY="-1" >
+            <group
+                android:pivotX="100"
+                android:pivotY="100"
+                android:rotation="45" >
+                <path
+                    android:name="twoLines"
+                    android:fillColor="#FFFF0000"
+                    android:pathData="M 100, 0 l 0, 100, -100, 0 z"
+                    android:strokeColor="#FF00FF00"
+                    android:strokeWidth="10" />
+            </group>
+        </group>
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/drawable/vector_icon_scale_2.xml b/tests/tests/graphics/res/drawable/vector_icon_scale_2.xml
new file mode 100644
index 0000000..200eb61
--- /dev/null
+++ b/tests/tests/graphics/res/drawable/vector_icon_scale_2.xml
@@ -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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="64dp"
+    android:viewportHeight="200"
+    android:viewportWidth="200"
+    android:width="64dp" >
+
+    <group>
+        <path
+            android:name="background1"
+            android:fillColor="#FF000000"
+            android:pathData="M 0,0 l 100,0 l 0, 100 l -100, 0 z" />
+        <path
+            android:name="background2"
+            android:fillColor="#FF000000"
+            android:pathData="M 100,100 l 100,0 l 0, 100 l -100, 0 z" />
+    </group>
+    <group
+        android:scaleX="2"
+        android:scaleY="0.5" >
+        <group
+            android:pivotX="100"
+            android:pivotY="100"
+            android:rotation="45" >
+            <path
+                android:name="twoLines"
+                android:fillColor="#FFFF0000"
+                android:pathData="M 100, 0 l 0, 100, -100, 0 z"
+                android:strokeColor="#FF00FF00"
+                android:strokeWidth="10" />
+        </group>
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/tests/tests/graphics/res/values/styles.xml b/tests/tests/graphics/res/values/styles.xml
index 20c80f8..31ed175 100644
--- a/tests/tests/graphics/res/values/styles.xml
+++ b/tests/tests/graphics/res/values/styles.xml
@@ -163,6 +163,7 @@
         <item name="themeNinePatch">@drawable/ninepatch_0</item>
         <item name="themeGravity">48</item>
         <item name="themeTileMode">2</item>
+        <item name="themeType">0</item>
     </style>
 
     <style name="Theme_NoSwipeDismiss">
diff --git a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
index f58b871..07e65d2 100644
--- a/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/BitmapTest.java
@@ -359,8 +359,10 @@
         mBitmap = BitmapFactory.decodeResource(mRes, R.drawable.start, mOptions);
         Bitmap ret = mBitmap.extractAlpha();
         assertNotNull(ret);
-        int color = ret.getPixel(10, 20);
-        assertEquals(0x00, Color.alpha(color));
+        int source = mBitmap.getPixel(10, 20);
+        int result = ret.getPixel(10, 20);
+        assertEquals(Color.alpha(source), Color.alpha(result));
+        assertEquals(0xFF, Color.alpha(result));
     }
 
     public void testExtractAlpha2(){
@@ -377,8 +379,10 @@
         mBitmap = BitmapFactory.decodeResource(mRes, R.drawable.start, mOptions);
         Bitmap ret = mBitmap.extractAlpha(new Paint(), new int[]{0, 1});
         assertNotNull(ret);
-        int color = ret.getPixel(10, 20);
-        assertEquals(0x00, Color.alpha(color));
+        int source = mBitmap.getPixel(10, 20);
+        int result = ret.getPixel(10, 20);
+        assertEquals(Color.alpha(source), Color.alpha(result));
+        assertEquals(0xFF, Color.alpha(result));
     }
 
     public void testGetAllocationByteCount() {
@@ -446,9 +450,22 @@
         }catch(IllegalArgumentException e){
         }
 
-        // normal case
+        // normal case 565
         mBitmap.setPixel(10, 16, 0xFF << 24);
         assertEquals(0xFF << 24, mBitmap.getPixel(10, 16));
+
+        // normal case A_8
+        mBitmap = Bitmap.createBitmap(10, 10, Config.ALPHA_8);
+        mBitmap.setPixel(5, 5, 0xFFFFFFFF);
+        assertEquals(0xFFFFFFFF, mBitmap.getPixel(5, 5));
+        mBitmap.setPixel(5, 5, 0xA8A8A8A8);
+        assertEquals(0xA8A8A8A8, mBitmap.getPixel(5, 5));
+        mBitmap.setPixel(5, 5, 0x00000000);
+        assertEquals(0x00000000, mBitmap.getPixel(5, 5));
+
+        // test reconstructing color channels
+        mBitmap.setPixel(5, 5, 0x1F000000);
+        assertEquals(0x1F1F1F1F, mBitmap.getPixel(5, 5));
     }
 
     public void testGetRowBytes(){
diff --git a/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java b/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
index d5391a3..1dd6777 100644
--- a/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/CanvasTest.java
@@ -1681,6 +1681,115 @@
         mCanvas.drawText(t5, 0, 7, 10, 30, mPaint);
     }
 
+    public void testDrawTextRun() {
+        final String text = "android";
+        final Paint paint = new Paint();
+
+        mCanvas.drawTextRun(text, 0, 0, 0, 0, 0.0f, 0.0f, false, paint);
+        mCanvas.drawTextRun(text, 0, text.length(), 0, text.length(), 0.0f, 0.0f, false, paint);
+        mCanvas.drawTextRun(text, text.length(), text.length(), text.length(), text.length(),
+                0.0f, 0.0f, false, paint);
+
+        try {
+            mCanvas.drawTextRun((char[])null, 0, 0, 0, 0, 0.0f, 0.0f, false, paint);
+            fail("should throw out NullPointerException because text is null");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun((CharSequence)null, 0, 0, 0, 0, 0.0f, 0.0f, false, paint);
+            fail("should throw out NullPointerException because text is null");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text.toCharArray(), 0, 0, 0, 0, 0.0f, 0.0f, false, null);
+            fail("should throw out NullPointerException because paint is null");
+        } catch (NullPointerException e) {
+        }
+        try {
+            mCanvas.drawTextRun(text, 0, 0, 0, 0, 0.0f, 0.0f, false, null);
+            fail("should throw out NullPointerException because paint is null");
+        } catch (NullPointerException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text.toCharArray(), -1, text.length(), 0, text.length(), 0.0f, 0.0f,
+                    false, paint);
+            fail("should throw out IndexOutOfBoundsException because index is less than 0");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text.toCharArray(), 0, -1, 0, text.length(), 0.0f, 0.0f, false,
+                    paint);
+            fail("should throw out IndexOutOfBoundsException because count is less than 0");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text.toCharArray(), 0, text.length(), 1, text.length(), 0.0f, 0.0f,
+                    false, paint);
+            fail("should throw out IndexOutOfBoundsException because contextIndex is bigger than "
+                    + "index");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+
+        try {
+            mCanvas.drawTextRun(text, 0, text.length(), 0, text.length() - 1, 0.0f, 0.0f, false,
+                    paint);
+            fail("should throw out IndexOutOfBoundsException because contexIndex + contextCount "
+                    + "is less than index + count");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text.toCharArray(), 0, text.length() + 1, 0, text.length() + 1,
+                    0.0f, 0.0f, false, paint);
+            fail("should throw out IndexOutOfBoundsException because index + count is bigger than "
+                    + "text length");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text, 0, text.length(), -1, text.length(), 0.0f, 0.0f, false,
+                    paint);
+            fail("should throw out IndexOutOfBoundsException because contextStart is less than 0");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text, 0, text.length(), 1, text.length(), 0.0f, 0.0f, false,
+                    paint);
+            fail("should throw out IndexOutOfBoundsException because start is less than "
+                    + "contextStart");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text, 1, 0, 0, text.length(), 0.0f, 0.0f, false,
+                    paint);
+            fail("should throw out IndexOutOfBoundsException because end is less than start");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text, 0, text.length(), 0, text.length() - 1, 0.0f, 0.0f, false,
+                    paint);
+            fail("should throw out IndexOutOfBoundsException because contextEnd is less than end");
+        } catch (IndexOutOfBoundsException e) {
+        }
+
+        try {
+            mCanvas.drawTextRun(text, 0, text.length(), 0, text.length() + 1, 0.0f, 0.0f, false,
+                    paint);
+            fail("should throw out IndexOutOfBoundsException because contextEnd is bigger than "
+                    + "text length");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
     public void testDrawPosText1() {
         final char[] text = {
                 'a', 'n', 'd', 'r', 'o', 'i', 'd'
diff --git a/tests/tests/graphics/src/android/graphics/cts/ColorMatrixColorFilterTest.java b/tests/tests/graphics/src/android/graphics/cts/ColorMatrixColorFilterTest.java
index fdef54c..2657d15 100644
--- a/tests/tests/graphics/src/android/graphics/cts/ColorMatrixColorFilterTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/ColorMatrixColorFilterTest.java
@@ -70,7 +70,10 @@
         paint.setColor(Color.RED);
         bitmap.eraseColor(Color.TRANSPARENT);
         canvas.drawPoint(0, 0, paint);
-        assertColor(Color.argb(128, 255, 0, 64), bitmap.getPixel(0, 0));
+        // the bitmap stores the result in premul colors and we read out an
+        // unpremultiplied result, which causes us to need a bigger tolerance in
+        // this case (due to the fact that scaling by 1/255 is not exact).
+        assertColor(Color.argb(128, 255, 0, 64), bitmap.getPixel(0, 0), 2);
         paint.setColor(Color.CYAN);
         canvas.drawPoint(0, 0, paint);
         // blue gets clipped
@@ -89,9 +92,13 @@
     }
 
     private void assertColor(int expected, int actual) {
-        assertEquals(Color.red(expected), Color.red(actual), TOLERANCE);
-        assertEquals(Color.green(expected), Color.green(actual), TOLERANCE);
-        assertEquals(Color.blue(expected), Color.blue(actual), TOLERANCE);
-        assertEquals(Color.alpha(expected), Color.alpha(actual), TOLERANCE);
+        assertColor(expected, actual, TOLERANCE);
+    }
+    
+    private void assertColor(int expected, int actual, int tolerance) {
+        assertEquals(Color.red(expected), Color.red(actual), tolerance);
+        assertEquals(Color.green(expected), Color.green(actual), tolerance);
+        assertEquals(Color.blue(expected), Color.blue(actual), tolerance);
+        assertEquals(Color.alpha(expected), Color.alpha(actual), tolerance);
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/CornerPathEffectTest.java b/tests/tests/graphics/src/android/graphics/cts/CornerPathEffectTest.java
index 125a6b0..553d05d 100644
--- a/tests/tests/graphics/src/android/graphics/cts/CornerPathEffectTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/CornerPathEffectTest.java
@@ -93,7 +93,6 @@
         // rounded corner must have less pixels than a sharp corner
         assertTrue(cornerPixels < 2 * RADIUS);
         // ... but not as few as a diagonal
-        // ToBeFixed: The following should be assertTrue (see bug 2037365)
-        assertFalse(cornerPixels > RADIUS);
+        assertTrue(cornerPixels > Math.sqrt(2 * Math.pow(RADIUS, 2)));
     }
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
index 1f709d3..80e0253 100644
--- a/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
+++ b/tests/tests/graphics/src/android/graphics/cts/PaintTest.java
@@ -19,6 +19,7 @@
 
 import android.graphics.ColorFilter;
 import android.graphics.MaskFilter;
+import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Paint.Align;
 import android.graphics.Paint.Cap;
@@ -28,11 +29,14 @@
 import android.graphics.PathEffect;
 import android.graphics.Rasterizer;
 import android.graphics.Shader;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
 import android.graphics.Typeface;
 import android.graphics.Xfermode;
 import android.os.Build;
 import android.test.AndroidTestCase;
 import android.text.SpannedString;
+import android.util.Log;
 
 import java.util.Locale;
 
@@ -190,7 +194,7 @@
         assertEquals(m, p2.getMaskFilter());
         assertEquals(e, p2.getPathEffect());
         assertEquals(r, p2.getRasterizer());
-        assertNotSame(s, p2.getShader());
+        assertEquals(s, p2.getShader());
         assertEquals(t, p2.getTypeface());
         assertEquals(x, p2.getXfermode());
 
@@ -199,7 +203,7 @@
         assertEquals(m, p2.getMaskFilter());
         assertEquals(e, p2.getPathEffect());
         assertEquals(r, p2.getRasterizer());
-        assertNotSame(s, p2.getShader());
+        assertEquals(s, p2.getShader());
         assertEquals(t, p2.getTypeface());
         assertEquals(x, p2.getXfermode());
 
@@ -271,6 +275,35 @@
         assertNull(p.getShader());
     }
 
+    public void testShaderLocalMatrix() {
+        int width = 80;
+        int height = 120;
+        int[] color = new int[width * height];
+        Bitmap bitmap = Bitmap.createBitmap(color, width, height, Bitmap.Config.RGB_565);
+
+        Paint p = new Paint();
+        Matrix m = new Matrix();
+        Shader s = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
+
+        // set the shaders matrix to a non identity value and attach to paint
+        m.setScale(10, 0);
+        s.setLocalMatrix(m);
+        p.setShader(s);
+
+        Matrix m2 = new Matrix();
+        assertTrue(p.getShader().getLocalMatrix(m2));
+        assertEquals(m, m2);
+
+        // updated the matrix again and set it on the shader but NOT the paint
+        m.setScale(0, 10);
+        s.setLocalMatrix(m);
+
+        // assert that the matrix on the paint's shader also changed
+        Matrix m3 = new Matrix();
+        assertTrue(p.getShader().getLocalMatrix(m3));
+        assertEquals(m, m3);
+    }
+
     public void testSetAntiAlias() {
         Paint p = new Paint();
 
@@ -776,7 +809,6 @@
     }
 
     public void testReset() {
-
         Paint p  = new Paint();
         ColorFilter c = new ColorFilter();
         MaskFilter m  = new MaskFilter();
@@ -812,7 +844,6 @@
         assertEquals(null, p.getShader());
         assertEquals(null, p.getTypeface());
         assertEquals(null, p.getXfermode());
-
     }
 
     public void testSetLinearText() {
@@ -897,6 +928,20 @@
         assertMeasureText(text, textChars, textSpan, 4, 7, widths[4] + widths[5] + widths[6]);
     }
 
+    public void testMeasureTextContext() {
+       Paint p = new Paint();
+       // Arabic LAM, which is different width depending on context
+       String shortString = "\u0644";
+       String longString = "\u0644\u0644\u0644";
+       char[] longChars = longString.toCharArray();
+       SpannedString longSpanned = new SpannedString(longString);
+       float width = p.measureText(shortString);
+       // Verify that measurement of substring is consistent no matter what surrounds it.
+       assertMeasureText(longString, longChars, longSpanned, 0, 1, width);
+       assertMeasureText(longString, longChars, longSpanned, 1, 2, width);
+       assertMeasureText(longString, longChars, longSpanned, 2, 3, width);
+    }
+
     public void testMeasureTextWithLongText() {
         // This test is not compatible with 4.0.3
         if ("4.0.3".equals(Build.VERSION.RELEASE)) {
@@ -1001,4 +1046,376 @@
         }
     }
 
+    public void testHasGlyph() {
+        Paint p = new Paint();
+
+        // This method tests both the logic of hasGlyph and the sanity of fonts present
+        // on the device.
+        assertTrue(p.hasGlyph("A"));
+        assertFalse(p.hasGlyph("\uFFFE"));  // U+FFFE is guaranteed to be a noncharacter
+
+        // Roboto 2 (the default typeface) does have an "fi" glyph and is mandated by CDD
+        assertTrue(p.hasGlyph("fi"));
+        assertFalse(p.hasGlyph("ab"));  // but it does not contain an "ab" glyph
+        assertTrue(p.hasGlyph("\u02E5\u02E9"));  // IPA tone mark ligature
+
+        // variation selectors
+        assertFalse(p.hasGlyph("a\uFE0F"));
+        assertFalse(p.hasGlyph("a\uDB40\uDDEF"));  // UTF-16 encoding of U+E01EF
+        assertFalse(p.hasGlyph("\u2229\uFE0F"));  // base character is in mathematical symbol font
+        // Note: U+FE0F is variation selection, unofficially reserved for emoji
+
+        // regional indicator symbols
+        assertTrue(p.hasGlyph("\uD83C\uDDEF\uD83C\uDDF5"));   // "JP" U+1F1EF U+1F1F5
+        assertFalse(p.hasGlyph("\uD83C\uDDFF\uD83C\uDDFF"));  // "ZZ" U+1F1FF U+1F1FF
+
+        // Mongolian, which is an optional font, but if present, should support FVS
+        if (p.hasGlyph("\u182D")) {
+            assertTrue(p.hasGlyph("\u182D\u180B"));
+        }
+
+        // TODO: when we support variation selectors, add positive tests
+    }
+
+    public void testGetRunAdvance() {
+        Paint p = new Paint();
+        {
+            // LTR
+            String string = "abcdef";
+            {
+                final float width = p.getRunAdvance(string, 0, string.length(), 0,
+                        string.length(), false, 0);
+                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,
+                        string.length(), false, string.length());
+                assertTrue(widthToMid > 0.0f);
+                assertTrue(widthToTail > widthToMid);
+            }
+            {
+                final float widthFromHead = p.getRunAdvance(string, 0, string.length(), 0,
+                        string.length(), false, string.length());
+                final float widthFromSecond = p.getRunAdvance(string, 1, string.length(), 0,
+                        string.length(), false, string.length());
+                assertTrue(widthFromHead > widthFromSecond);
+            }
+        }
+        {
+            // RTL
+            String string = "\u0644\u063A\u0629 \u0639\u0631\u0628\u064A\u0629"; // Arabic
+            {
+                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,
+                        string.length(), true, string.length());
+                assertTrue(widthToMid > 0.0f);
+                assertTrue(widthToTail > widthToMid);
+            }
+            {
+                final float widthFromHead = p.getRunAdvance(string, 0, string.length(), 0,
+                        string.length(), true, string.length());
+                final float widthFromSecond = p.getRunAdvance(string, 1, string.length(), 0,
+                        string.length(), true, string.length());
+                assertTrue(widthFromHead > widthFromSecond);
+            }
+        }
+    }
+
+    public void testGetRunAdvance_invalidArguments() {
+        Paint p = new Paint();
+        try {
+            p.getRunAdvance((CharSequence)null, 0, 0, 0, 0, false, 0);
+            fail("Should throw an IllegalArgumentException.");
+        } catch (IllegalArgumentException e) {
+        } catch (Exception e) {
+            fail("Should throw an IllegalArgumentException.");
+        }
+
+        try {
+            p.getRunAdvance((char[])null, 0, 0, 0, 0, false, 0);
+            fail("Should throw an IllegalArgumentException.");
+        } catch (IllegalArgumentException e) {
+        } catch (Exception e) {
+            fail("Should throw an IllegalArgumentException.");
+        }
+
+        final String string = "abcde";
+
+        try {
+            // text length < context end
+            p.getRunAdvance(string, 0, string.length(), 0, string.length() + 1, false,
+                    string.length());
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+        try {
+            // context end < end
+            p.getRunAdvance(string, 0, string.length(), 0, string.length() - 1, false, 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+        try {
+            // end < offset
+            p.getRunAdvance(string, 0, string.length() - 1, 0, string.length() - 1, false,
+                    string.length());
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+        try {
+            // offset < start
+            p.getRunAdvance(string, 1, string.length(), 1, string.length(), false, 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+        try {
+            // start < context start
+            p.getRunAdvance(string, 0, string.length(), 1, string.length(), false, 1);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+        try {
+            // context start < 0
+            p.getRunAdvance(string, 0, string.length(), -1, string.length(), false, 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+    }
+
+    public void testGetRunAdvance_nonzeroIndex() {
+        Paint p = new Paint();
+        final String text = "Android powers hundreds of millions of mobile " +
+                "devices in more than 190 countries around the world. It's" +
+                "the largest installed base of any mobile platform and" +
+                "growing fast—every day another million users power up their" +
+                "Android devices for the first time and start looking for" +
+                "apps, games, and other digital content.";
+        // Test offset index does not affect width.
+        final float widthAndroidFirst = p.getRunAdvance(
+                text, 0, 7, 0, text.length(), false, 7);
+        final float widthAndroidSecond = p.getRunAdvance(
+                text, 215, 222, 0, text.length(), false, 222);
+        assertTrue(Math.abs(widthAndroidFirst - widthAndroidSecond) < 1);
+    }
+
+    public void testGetRunAdvance_glyphDependingContext() {
+        Paint p = new Paint();
+        // Test the context change the character shape.
+        // First character should be isolated form because the context ends at index 1.
+        final float isolatedFormWidth = p.getRunAdvance("\u0644\u0644", 0, 1, 0, 1, true, 1);
+        // First character should be initial form because the context ends at index 2.
+        final float initialFormWidth = p.getRunAdvance("\u0644\u0644", 0, 1, 0, 2, true, 1);
+        assertTrue(isolatedFormWidth > initialFormWidth);
+    }
+
+    public void testGetRunAdvance_arabic() {
+        Paint p = new Paint();
+        // Test total width is equals to sum of each character's width.
+        // "What is Unicode?" in Arabic.
+        final String text =
+                "\u0645\u0627\u0020\u0647\u064A\u0020\u0627\u0644\u0634" +
+                "\u0641\u0631\u0629\u0020\u0627\u0644\u0645\u0648\u062D" +
+                "\u062F\u0629\u0020\u064A\u0648\u0646\u064A\u0643\u0648" +
+                "\u062F\u061F";
+        final float totalWidth = p.getRunAdvance(
+                text, 0, text.length(), 0, text.length(), true, text.length());
+        float sumOfCharactersWidth = 0;
+        for (int i = 0; i < text.length(); i++) {
+            sumOfCharactersWidth += p.getRunAdvance(
+                    text, i, i + 1, 0, text.length(), true, i + 1);
+        }
+        assertTrue(Math.abs(totalWidth - sumOfCharactersWidth) < 1);
+    }
+
+    public void testGetOffsetForAdvance() {
+        Paint p = new Paint();
+        {
+            // LTR
+            String string = "abcdef";
+            {
+                for (int offset = 0; offset <= string.length(); ++offset) {
+                    final float widthToOffset = p.getRunAdvance(string, 0,
+                            string.length(), 0, string.length(), false, offset);
+                    final int restoredOffset = p.getOffsetForAdvance(string, 0,
+                            string.length(), 0, string.length(), false, widthToOffset);
+                    assertEquals(offset, restoredOffset);
+                }
+            }
+            {
+                final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0,
+                        string.length(), false, -10.0f);
+                assertEquals(0, offset);
+            }
+            {
+                final float widthToEnd = p.getRunAdvance(string, 0, string.length(), 0,
+                        string.length(), true, string.length());
+                final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0,
+                        string.length(), true, widthToEnd + 10.0f);
+                assertEquals(string.length(), offset);
+            }
+        }
+        {
+            // RTL
+            String string = "\u0639\u0631\u0628\u0649"; // Arabic
+            {
+                for (int offset = 0; offset <= string.length(); ++offset) {
+                    final float widthToOffset = p.getRunAdvance(string, 0,
+                            string.length(), 0, string.length(), true, offset);
+                    final int restoredOffset = p.getOffsetForAdvance(string, 0,
+                            string.length(), 0, string.length(), true, widthToOffset);
+                    assertEquals(offset, restoredOffset);
+                }
+            }
+            {
+                final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0,
+                        string.length(), true, -10.0f);
+                assertEquals(0, offset);
+            }
+            {
+                final float widthToEnd = p.getRunAdvance(string, 0, string.length(), 0,
+                        string.length(), true, string.length());
+                final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0,
+                        string.length(), true, widthToEnd + 10.0f);
+                assertEquals(string.length(), offset);
+            }
+        }
+    }
+
+    public void testGetOffsetForAdvance_invalidArguments() {
+        Paint p = new Paint();
+        try {
+            p.getOffsetForAdvance((CharSequence)null, 0, 0, 0, 0, false, 0.0f);
+            fail("Should throw an IllegalArgumentException.");
+        } catch (IllegalArgumentException e) {
+        } catch (Exception e) {
+            fail("Should throw an IllegalArgumentException.");
+        }
+        try {
+            p.getOffsetForAdvance((char[])null, 0, 0, 0, 0, false, 0.0f);
+            fail("Should throw an IllegalArgumentException.");
+        } catch (IllegalArgumentException e) {
+        } catch (Exception e) {
+            fail("Should throw an IllegalArgumentException.");
+        }
+
+        final String string = "abcde";
+
+        try {
+            // context start < 0
+            p.getOffsetForAdvance(string, -1, string.length(), 0, string.length(), false, 0.0f);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+
+        try {
+            // start < context start
+            p.getOffsetForAdvance(string, 0, string.length(), 1, string.length(), false, 0.0f);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+
+        try {
+            // end < start
+            p.getOffsetForAdvance(string, 1, 0, 0, 0, false, 0);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+
+        try {
+            // context end < end
+            p.getOffsetForAdvance(string, 0, string.length(), 0, string.length() - 1, false, 0.0f);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+
+        try {
+            // text length < context end
+            p.getOffsetForAdvance(string, 0, string.length(), 0, string.length() + 1, false, 0.0f);
+            fail("Should throw an IndexOutOfBoundsException.");
+        } catch (IndexOutOfBoundsException e) {
+        } catch (Exception e) {
+            fail("Should throw an IndexOutOfBoundsException.");
+        }
+    }
+
+    public void testGetOffsetForAdvance_grahpemeCluster() {
+        Paint p = new Paint();
+        {
+            String string = "\uD83C\uDF37"; // U+1F337: TULIP
+            {
+                final float widthToOffset = p.getRunAdvance(string, 0,
+                        string.length(), 0, string.length(), false, 1);
+                final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0,
+                        string.length(), false, widthToOffset);
+                assertFalse(1 == offset);
+                assertTrue(0 == offset || string.length() == offset);
+            }
+        }
+        {
+            String string = "\uD83C\uDDFA\uD83C\uDDF8"; // US flag
+            {
+                final float widthToOffset = p.getRunAdvance(string, 0,
+                        string.length(), 0, string.length(), false, 2);
+                final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0,
+                        string.length(), false, widthToOffset);
+                assertFalse(2 == offset);
+                assertTrue(0 == offset || string.length() == offset);
+            }
+            {
+                final float widthToOffset = p.getRunAdvance(string, 0, 2, 0, 2, false, 2);
+                final int offset = p.getOffsetForAdvance(string, 0, 2,
+                        0, 2, false, widthToOffset);
+                assertEquals(2, offset);
+            }
+        }
+        {
+            // HANGUL CHOSEONG KIYEOK, HANGUL JUNGSEONG A, HANDUL JONGSEONG KIYEOK
+            String string = "\u1100\u1161\u11A8";
+            {
+                for (int offset = 0; offset <= string.length(); ++offset) {
+                    final float widthToOffset = p.getRunAdvance(string, 0,
+                            string.length(), 0, string.length(), false, offset);
+                    final int offsetForAdvance = p.getOffsetForAdvance(string, 0, string.length(),
+                            0, string.length(), false, widthToOffset);
+                    assertTrue(0 == offsetForAdvance || string.length() == offsetForAdvance);
+                }
+                for (int offset = 0; offset <= string.length(); ++offset) {
+                    final float widthToOffset = p.getRunAdvance(string, 0, offset, 0, offset,
+                            false, offset);
+                    final int offsetForAdvance = p.getOffsetForAdvance(string, 0, string.length(),
+                            0, string.length(), false, widthToOffset);
+                    assertTrue(0 == offsetForAdvance || string.length() == offsetForAdvance);
+                }
+                for (int offset = 0; offset <= string.length(); ++offset) {
+                    final float widthToOffset = p.getRunAdvance(string, 0, offset, 0, offset,
+                            false, offset);
+                    final int offsetForAdvance = p.getOffsetForAdvance(string, 0, offset, 0,
+                            offset, false, widthToOffset);
+                    assertEquals(offset, offsetForAdvance);
+                }
+            }
+        }
+    }
 }
diff --git a/tests/tests/graphics/src/android/graphics/cts/VulkanReservedTest.java b/tests/tests/graphics/src/android/graphics/cts/VulkanReservedTest.java
new file mode 100644
index 0000000..bfd520e
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/cts/VulkanReservedTest.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 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/drawable/cts/AnimatedVectorDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
index b4c64e2..769e110 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/AnimatedVectorDrawableTest.java
@@ -19,9 +19,11 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
+import android.graphics.drawable.Animatable2;
 import android.graphics.drawable.AnimatedVectorDrawable;
+import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Drawable.ConstantState;
-import android.test.AndroidTestCase;
+import android.test.ActivityInstrumentationTestCase2;
 import android.util.AttributeSet;
 import android.util.Log;
 import android.util.Xml;
@@ -35,12 +37,13 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 
-public class AnimatedVectorDrawableTest extends AndroidTestCase {
+public class AnimatedVectorDrawableTest extends ActivityInstrumentationTestCase2<DrawableStubActivity> {
     private static final String LOGTAG = AnimatedVectorDrawableTest.class.getSimpleName();
 
     private static final int IMAGE_WIDTH = 64;
     private static final int IMAGE_HEIGHT = 64;
 
+    private DrawableStubActivity mActivity;
     private Resources mResources;
     private AnimatedVectorDrawable mAnimatedVectorDrawable;
     private Bitmap mBitmap;
@@ -48,6 +51,10 @@
     private static final boolean DBG_DUMP_PNG = false;
     private int mResId = R.drawable.animation_vector_drawable_grouping_1;
 
+    public AnimatedVectorDrawableTest() {
+        super(DrawableStubActivity.class);
+    }
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -56,7 +63,8 @@
         mCanvas = new Canvas(mBitmap);
         mAnimatedVectorDrawable = new AnimatedVectorDrawable();
 
-        mResources = mContext.getResources();
+        mActivity = getActivity();
+        mResources = mActivity.getResources();
     }
 
     // This is only for debugging or golden image (re)generation purpose.
@@ -156,11 +164,9 @@
     }
 
     public void testMutate() {
-        Resources resources = mContext.getResources();
-
-        AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) resources.getDrawable(mResId);
-        AnimatedVectorDrawable d2 = (AnimatedVectorDrawable) resources.getDrawable(mResId);
-        AnimatedVectorDrawable d3 = (AnimatedVectorDrawable) resources.getDrawable(mResId);
+        AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
+        AnimatedVectorDrawable d2 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
+        AnimatedVectorDrawable d3 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
         int originalAlpha = d2.getAlpha();
         int newAlpha = (originalAlpha + 1) % 255;
 
@@ -183,4 +189,91 @@
         assertEquals(0x20, d2.getAlpha());
         assertEquals(originalAlpha, d3.getAlpha());
     }
+
+    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.reset();
+                assertFalse(d1.isRunning());
+            }
+        });
+
+    }
+
+    public void testAddCallback() throws InterruptedException {
+        MyCallback callback = new MyCallback();
+        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();
+            }
+        });
+
+        Thread.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));
+        // The AVD has a duration as 100ms.
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                d1.start();
+            }
+        });
+
+        Thread.sleep(200);
+
+        assertFalse(callback.mStart);
+        assertFalse(callback.mEnd);
+    }
+
+    public void testClearCallback() throws InterruptedException {
+        MyCallback callback = new MyCallback();
+        final AnimatedVectorDrawable d1 = (AnimatedVectorDrawable) mResources.getDrawable(mResId);
+
+        d1.registerAnimationCallback(callback);
+        d1.clearAnimationCallbacks();
+        // The AVD has a duration as 100ms.
+        mActivity.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                d1.start();
+            }
+        });
+
+        Thread.sleep(200);
+
+        assertFalse(callback.mStart);
+        assertFalse(callback.mEnd);
+    }
+
+    class MyCallback extends Animatable2.AnimationCallback {
+        boolean mStart = false;
+        boolean mEnd = false;
+
+        @Override
+        public void onAnimationStart(Drawable drawable) {
+            mStart = true;
+        }
+
+        @Override
+        public void onAnimationEnd(Drawable drawable) {
+            mEnd = true;
+        }
+    }
 }
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 c895d0d..88e7acb 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/BitmapDrawableTest.java
@@ -21,7 +21,6 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.Context;
-import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
@@ -135,6 +134,22 @@
         assertTrue(bitmapDrawable.getPaint().isFilterBitmap());
     }
 
+    public void testIsFilterBitmap() {
+        InputStream source = mContext.getResources().openRawResource(R.raw.testimage);
+        BitmapDrawable bitmapDrawable = new BitmapDrawable(source);
+
+        assertTrue(bitmapDrawable.isFilterBitmap());
+
+        bitmapDrawable.setFilterBitmap(false);
+        assertFalse(bitmapDrawable.isFilterBitmap());
+        assertEquals(bitmapDrawable.isFilterBitmap(), bitmapDrawable.getPaint().isFilterBitmap());
+
+
+        bitmapDrawable.setFilterBitmap(true);
+        assertTrue(bitmapDrawable.isFilterBitmap());
+        assertEquals(bitmapDrawable.isFilterBitmap(), bitmapDrawable.getPaint().isFilterBitmap());
+    }
+
     public void testSetDither() {
         InputStream source = mContext.getResources().openRawResource(R.raw.testimage);
         BitmapDrawable bitmapDrawable = new BitmapDrawable(source);
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 7e3294d..e727350 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ClipDrawableTest.java
@@ -22,6 +22,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.util.Arrays;
 
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
@@ -67,19 +68,21 @@
     }
 
     public void testGetChangingConfigurations() {
+        final int SUPER_CONFIG = 1;
+        final int CONTAINED_DRAWABLE_CONFIG = 2;
+
         MockDrawable mockDrawable = new MockDrawable();
         ClipDrawable clipDrawable = new ClipDrawable(mockDrawable,
                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
+
         assertEquals(0, clipDrawable.getChangingConfigurations());
 
-        clipDrawable.setChangingConfigurations(1);
-        assertEquals(1, clipDrawable.getChangingConfigurations());
+        mockDrawable.setChangingConfigurations(CONTAINED_DRAWABLE_CONFIG);
+        assertEquals(CONTAINED_DRAWABLE_CONFIG, clipDrawable.getChangingConfigurations());
 
-        mockDrawable.setChangingConfigurations(2);
-        clipDrawable = new ClipDrawable(mockDrawable,
-                Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
-        clipDrawable.setChangingConfigurations(1);
-        assertEquals(3, clipDrawable.getChangingConfigurations());
+        clipDrawable.setChangingConfigurations(SUPER_CONFIG);
+        assertEquals(SUPER_CONFIG | CONTAINED_DRAWABLE_CONFIG,
+                clipDrawable.getChangingConfigurations());
     }
 
     public void testGetConstantState() {
@@ -125,16 +128,28 @@
 
     @SuppressWarnings("deprecation")
     public void testGetOpacity() {
-        BitmapDrawable bmpDrawable =
-            new BitmapDrawable(Bitmap.createBitmap(100, 50, Config.RGB_565));
-        ClipDrawable clipDrawable = new ClipDrawable(bmpDrawable,
-                Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
-        assertEquals(PixelFormat.OPAQUE, clipDrawable.getOpacity());
+        MockDrawable dr;
+        ClipDrawable clipDrawable;
 
-        bmpDrawable = new BitmapDrawable(Bitmap.createBitmap(100, 50, Config.RGB_565));
-        bmpDrawable.setGravity(Gravity.CENTER);
-        clipDrawable = new ClipDrawable(bmpDrawable, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
-        assertEquals(PixelFormat.TRANSLUCENT, clipDrawable.getOpacity());
+        dr = new MockDrawable();
+        dr.setOpacity(PixelFormat.OPAQUE);
+        clipDrawable = new ClipDrawable(dr, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
+        clipDrawable.setLevel(0);
+        assertEquals("Fully-clipped opaque drawable is transparent",
+                PixelFormat.TRANSPARENT, clipDrawable.getOpacity());
+        clipDrawable.setLevel(5000);
+        assertEquals("Partially-clipped opaque drawable is translucent",
+                PixelFormat.TRANSLUCENT, clipDrawable.getOpacity());
+        clipDrawable.setLevel(10000);
+        assertEquals("Unclipped opaque drawable is opaque",
+                PixelFormat.OPAQUE, clipDrawable.getOpacity());
+
+        dr = new MockDrawable();
+        dr.setOpacity(PixelFormat.TRANSLUCENT);
+        clipDrawable = new ClipDrawable(dr, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
+        clipDrawable.setLevel(10000);
+        assertEquals("Unclipped translucent drawable is translucent",
+                PixelFormat.TRANSLUCENT, clipDrawable.getOpacity());
     }
 
     public void testGetPadding() {
@@ -219,7 +234,7 @@
         MockCallback callback = new MockCallback();
         mockClipDrawable.setCallback(callback);
 
-        assertEquals(0, mockDrawable.getLevel());
+        assertEquals("Default level is 0", 0, mockDrawable.getLevel());
         mockClipDrawable.onLevelChange(1000);
         assertEquals(1000, mockDrawable.getLevel());
         assertSame(mockClipDrawable, callback.getInvalidateDrawable());
@@ -232,16 +247,24 @@
     }
 
     public void testOnStateChange() {
-        MockDrawable mockDrawable = new MockDrawable();
-        MockClipDrawable mockClipDrawable = new MockClipDrawable(mockDrawable,
+        Drawable d = mContext.getDrawable(R.drawable.pass);
+        MockClipDrawable clipDrawable = new MockClipDrawable(d,
                 Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
-        assertEquals(StateSet.WILD_CARD, mockDrawable.getState());
+        assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
 
-        int[] states = new int[] {1, 2, 3};
-        assertFalse(mockClipDrawable.onStateChange(states));
-        assertEquals(states, mockDrawable.getState());
+        int[] state = new int[] {1, 2, 3};
+        assertFalse("child did not change", clipDrawable.onStateChange(state));
+        assertEquals("child state did not change", d.getState(), StateSet.WILD_CARD);
 
-        mockClipDrawable.onStateChange(null);
+        d = mContext.getDrawable(R.drawable.statelistdrawable);
+        clipDrawable = new MockClipDrawable(d, Gravity.BOTTOM, ClipDrawable.HORIZONTAL);
+        assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
+        clipDrawable.onStateChange(state);
+        assertTrue("child state changed", Arrays.equals(state, d.getState()));
+
+        // input null as param
+        clipDrawable.onStateChange(null);
+        // expected, no Exception thrown out, test success
     }
 
     public void testScheduleDrawable() {
@@ -335,6 +358,7 @@
     private class MockDrawable extends Drawable {
         private ColorFilter mColorFilter;
         private ConstantState mConstantState;
+        private int mOpacity;
         private boolean mCalledDraw = false;
         private int mAlpha;
 
@@ -363,7 +387,11 @@
         }
 
         public int getOpacity() {
-            return 0;
+            return mOpacity;
+        }
+
+        public void setOpacity(int opacity) {
+            mOpacity = opacity;
         }
 
         protected void onBoundsChange(Rect bounds) {
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 036c756..79d2a1d 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableContainerTest.java
@@ -20,7 +20,6 @@
 
 import java.util.Arrays;
 
-import android.content.res.ColorStateList;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.ColorFilter;
@@ -185,6 +184,44 @@
         assertTrue(dr.hasSetDitherCalled());
     }
 
+    public void testSetHotspotBounds() {
+        Rect bounds = new Rect(10, 15, 100, 150);
+        assertConstantStateNotSet();
+        assertNull(mDrawableContainer.getCurrent());
+
+        mDrawableContainer.setConstantState(mDrawableContainerState);
+
+        MockDrawable dr = new MockDrawable();
+        addAndSelectDrawable(dr);
+
+        dr.reset();
+        mDrawableContainer.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
+        Rect outRect = new Rect();
+        mDrawableContainer.getHotspotBounds(outRect);
+        assertEquals(bounds, outRect);
+
+        dr.reset();
+    }
+
+    public void testGetHotspotBounds() {
+        Rect bounds = new Rect(10, 15, 100, 150);
+        assertConstantStateNotSet();
+        assertNull(mDrawableContainer.getCurrent());
+
+        mDrawableContainer.setConstantState(mDrawableContainerState);
+
+        MockDrawable dr = new MockDrawable();
+        addAndSelectDrawable(dr);
+
+        dr.reset();
+        mDrawableContainer.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
+        Rect outRect = new Rect();
+        mDrawableContainer.getHotspotBounds(outRect);
+        assertEquals(bounds, outRect);
+
+        dr.reset();
+    }
+
     public void testSetColorFilter() {
         assertConstantStateNotSet();
         assertNull(mDrawableContainer.getCurrent());
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableStubActivity.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableStubActivity.java
new file mode 100644
index 0000000..a7b27b3
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableStubActivity.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.graphics.drawable.cts;
+
+import android.app.Activity;
+
+public class DrawableStubActivity extends Activity {
+}
+
+
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 a48372e..a91353f 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableTest.java
@@ -16,6 +16,7 @@
 
 package android.graphics.drawable.cts;
 
+import android.view.View;
 import com.android.cts.graphics.R;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -545,6 +546,47 @@
         mockDrawable.setDither(false);
     }
 
+    public void testSetHotspotBounds() {
+        MockDrawable mockDrawable = new MockDrawable();
+
+        // setHotspotBounds is a non-operation function.
+        mockDrawable.setHotspotBounds(10, 15, 100, 150);
+    }
+
+    public void testGetHotspotBounds() {
+        MockDrawable mockDrawable = new MockDrawable();
+
+        // getHotspotBounds doesn't do anything interesting 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();
+
+        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 testOnLayoutDirectionChanged() {
+        MockDrawable mockDrawable = new MockDrawable();
+
+        // onLayoutDirectionChanged is a non-operation function.
+        mockDrawable.onLayoutDirectionChanged(View.LAYOUT_DIRECTION_LTR);
+    }
+
     public void testSetFilterBitmap() {
         MockDrawable mockDrawable = new MockDrawable();
 
@@ -552,6 +594,13 @@
         mockDrawable.setFilterBitmap(false);
     }
 
+    public void testIsFilterBitmap() {
+        MockDrawable mockDrawable = new MockDrawable();
+
+        // setFilterBitmap is a non-operation function.
+        mockDrawable.isFilterBitmap();
+    }
+
     public void testUnscheduleSelf() {
         MockDrawable mockDrawable = new MockDrawable();
         MockCallback mockCallback = new MockCallback();
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableWrapperTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableWrapperTest.java
new file mode 100644
index 0000000..40680c1
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/DrawableWrapperTest.java
@@ -0,0 +1,549 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.drawable.DrawableWrapper;
+import com.android.cts.graphics.R;
+
+
+import java.util.Arrays;
+
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Rect;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Drawable.ConstantState;
+import android.test.AndroidTestCase;
+import android.util.StateSet;
+
+public class DrawableWrapperTest extends AndroidTestCase {
+
+    static class MyWrapper extends DrawableWrapper {
+        public MyWrapper(Drawable dr) {
+            super(dr);
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testConstructor() {
+        Drawable d = new BitmapDrawable();
+        MyWrapper wrapper = new MyWrapper(d);
+        assertSame(d, wrapper.getDrawable());
+
+        new MyWrapper(null);
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetDrawable() {
+        Drawable d = new BitmapDrawable();
+        MyWrapper wrapper = new MyWrapper(d);
+        assertSame(d, wrapper.getDrawable());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetDrawable() {
+        Drawable d = new BitmapDrawable();
+        MyWrapper wrapper = new MyWrapper(null);
+        assertSame(null, wrapper.getDrawable());
+
+        wrapper.setDrawable(d);
+        assertSame(d, wrapper.getDrawable());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testInvalidateDrawable() {
+        MyWrapper wrapper = new MyWrapper(new BitmapDrawable());
+
+        MockCallback cb = new MockCallback();
+        wrapper.setCallback(cb);
+        wrapper.invalidateDrawable(null);
+        assertTrue(cb.hasCalledInvalidate());
+
+        cb.reset();
+        wrapper.invalidateDrawable(new BitmapDrawable());
+        assertTrue(cb.hasCalledInvalidate());
+
+        cb.reset();
+        wrapper.setCallback(null);
+        wrapper.invalidateDrawable(null);
+        assertFalse(cb.hasCalledInvalidate());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testScheduleDrawable() {
+        MyWrapper wrapper = new MyWrapper(new BitmapDrawable());
+
+        MockCallback cb = new MockCallback();
+        wrapper.setCallback(cb);
+        wrapper.scheduleDrawable(null, null, 0);
+        assertTrue(cb.hasCalledSchedule());
+
+        cb.reset();
+        wrapper.scheduleDrawable(new BitmapDrawable(), new Runnable() {
+            public void run() {
+            }
+        }, 1000L);
+        assertTrue(cb.hasCalledSchedule());
+
+        cb.reset();
+        wrapper.setCallback(null);
+        wrapper.scheduleDrawable(null, null, 0);
+        assertFalse(cb.hasCalledSchedule());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testUnscheduleDrawable() {
+        MyWrapper wrapper = new MyWrapper(new BitmapDrawable());
+
+        MockCallback cb = new MockCallback();
+        wrapper.setCallback(cb);
+        wrapper.unscheduleDrawable(null, null);
+        assertTrue(cb.hasCalledUnschedule());
+
+        cb.reset();
+        wrapper.unscheduleDrawable(new BitmapDrawable(), new Runnable() {
+            public void run() {
+            }
+        });
+        assertTrue(cb.hasCalledUnschedule());
+
+        cb.reset();
+        wrapper.setCallback(null);
+        wrapper.unscheduleDrawable(null, null);
+        assertFalse(cb.hasCalledUnschedule());
+    }
+
+    private static class MockCallback implements Drawable.Callback {
+        private boolean mCalledInvalidate;
+        private boolean mCalledSchedule;
+        private boolean mCalledUnschedule;
+
+        public void invalidateDrawable(Drawable who) {
+            mCalledInvalidate = true;
+        }
+
+        public void scheduleDrawable(Drawable who, Runnable what, long when) {
+            mCalledSchedule = true;
+        }
+
+        public void unscheduleDrawable(Drawable who, Runnable what) {
+            mCalledUnschedule = true;
+        }
+
+        public boolean hasCalledInvalidate() {
+            return mCalledInvalidate;
+        }
+
+        public boolean hasCalledSchedule() {
+            return mCalledSchedule;
+        }
+
+        public boolean hasCalledUnschedule() {
+            return mCalledUnschedule;
+        }
+
+        public int getResolvedLayoutDirection(Drawable who) {
+            return 0;
+        }
+
+        public void reset() {
+            mCalledInvalidate = false;
+            mCalledSchedule = false;
+            mCalledUnschedule = false;
+        }
+    }
+
+    public void testDraw() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MyWrapper wrapper = new MyWrapper(mockDrawable);
+
+        wrapper.draw(new Canvas());
+        assertTrue(mockDrawable.hasCalledDraw());
+
+        mockDrawable.reset();
+        wrapper.draw(null);
+        assertTrue(mockDrawable.hasCalledDraw());
+    }
+
+    public void testGetChangingConfigurations() {
+        final int SUPER_CONFIG = 1;
+        final int CONTAINED_DRAWABLE_CONFIG = 2;
+
+        MockDrawable mockDrawable = new MockDrawable();
+        MyWrapper wrapper = new MyWrapper(mockDrawable);
+
+        assertEquals(0, wrapper.getChangingConfigurations());
+
+        mockDrawable.setChangingConfigurations(CONTAINED_DRAWABLE_CONFIG);
+        assertEquals(CONTAINED_DRAWABLE_CONFIG, wrapper.getChangingConfigurations());
+
+        wrapper.setChangingConfigurations(SUPER_CONFIG);
+        assertEquals(SUPER_CONFIG | CONTAINED_DRAWABLE_CONFIG,
+                wrapper.getChangingConfigurations());
+    }
+
+    public void testGetPadding() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MyWrapper wrapper = new MyWrapper(mockDrawable);
+
+        // this method will call contained drawable's getPadding method.
+        wrapper.getPadding(new Rect());
+        assertTrue(mockDrawable.hasCalledGetPadding());
+
+        // input null as param
+        try {
+            wrapper.getPadding(null);
+            fail("Should throw NullPointerException");
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void testSetVisible() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MyWrapper wrapper = new MyWrapper(mockDrawable);
+        assertTrue(wrapper.isVisible());
+
+        assertTrue(wrapper.setVisible(false, false));
+        assertFalse(wrapper.isVisible());
+        assertTrue(mockDrawable.hasCalledSetVisible());
+
+        mockDrawable.reset();
+        assertFalse(wrapper.setVisible(false, false));
+        assertFalse(wrapper.isVisible());
+        assertTrue(mockDrawable.hasCalledSetVisible());
+
+        mockDrawable.reset();
+        assertTrue(wrapper.setVisible(true, false));
+        assertTrue(wrapper.isVisible());
+        assertTrue(mockDrawable.hasCalledSetVisible());
+    }
+
+    public void testSetAlpha() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MyWrapper wrapper = new MyWrapper(mockDrawable);
+
+        // this method will call contained drawable's setAlpha method.
+        wrapper.setAlpha(100);
+        assertTrue(mockDrawable.hasCalledSetAlpha());
+
+        mockDrawable.reset();
+        wrapper.setAlpha(Integer.MAX_VALUE);
+        assertTrue(mockDrawable.hasCalledSetAlpha());
+
+        mockDrawable.reset();
+        wrapper.setAlpha(-1);
+        assertTrue(mockDrawable.hasCalledSetAlpha());
+    }
+
+    public void testSetColorFilter() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MyWrapper wrapper = new MyWrapper(mockDrawable);
+
+        // this method will call contained drawable's setColorFilter method.
+        wrapper.setColorFilter(new ColorFilter());
+        assertTrue(mockDrawable.hasCalledSetColorFilter());
+
+        mockDrawable.reset();
+        wrapper.setColorFilter(null);
+        assertTrue(mockDrawable.hasCalledSetColorFilter());
+    }
+
+    public void testGetOpacity() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MyWrapper wrapper = new MyWrapper(mockDrawable);
+
+        // This method will call contained drawable's getOpacity method.
+        wrapper.setLevel(1);
+        wrapper.getOpacity();
+        assertTrue(mockDrawable.hasCalledGetOpacity());
+    }
+
+    public void testIsStateful() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MyWrapper wrapper = new MyWrapper(mockDrawable);
+
+        // this method will call contained drawable's isStateful method.
+        wrapper.isStateful();
+        assertTrue(mockDrawable.hasCalledIsStateful());
+    }
+
+    public void testOnStateChange() {
+        Drawable d = new MockDrawable();
+        MockDrawableWrapper wrapper = new MockDrawableWrapper(d);
+        assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
+
+        int[] state = new int[] {1, 2, 3};
+        assertFalse("child did not change", wrapper.onStateChange(state));
+        assertEquals("child state did not change", d.getState(), StateSet.WILD_CARD);
+
+        d = mContext.getDrawable(R.drawable.statelistdrawable);
+        wrapper = new MockDrawableWrapper(d);
+        assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
+        wrapper.onStateChange(state);
+        assertTrue("child state changed", Arrays.equals(state, d.getState()));
+
+        // input null as param
+        wrapper.onStateChange(null);
+        // expected, no Exception thrown out, test success
+    }
+
+    public void testOnLevelChange() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MockDrawableWrapper mockDrawableWrapper = new MockDrawableWrapper(mockDrawable);
+
+        assertEquals(0, mockDrawable.getLevel());
+        assertFalse(mockDrawableWrapper.onLevelChange(0));
+        assertFalse(mockDrawable.hasCalledOnLevelChange());
+
+        assertFalse(mockDrawableWrapper.onLevelChange(1000));
+        assertTrue(mockDrawable.hasCalledOnLevelChange());
+        assertEquals(1000, mockDrawable.getLevel());
+
+        mockDrawable.reset();
+        mockDrawableWrapper.reset();
+        assertFalse(mockDrawableWrapper.onLevelChange(Integer.MIN_VALUE));
+        assertTrue(mockDrawable.hasCalledOnLevelChange());
+    }
+
+    public void testOnBoundsChange() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MockDrawableWrapper mockDrawableWrapper = new MockDrawableWrapper(mockDrawable);
+        Rect bounds = new Rect(2, 2, 26, 32);
+        mockDrawable.setBounds(bounds);
+        mockDrawableWrapper.onBoundsChange(bounds);
+
+        mockDrawableWrapper = new MockDrawableWrapper(mockDrawable);
+        mockDrawable.setBounds(bounds);
+        mockDrawableWrapper.onBoundsChange(bounds);
+        assertEquals(bounds.left, mockDrawable.getBounds().left);
+        assertEquals(bounds.top, mockDrawable.getBounds().top);
+        assertEquals(bounds.right, mockDrawable.getBounds().right);
+        assertEquals(bounds.bottom, mockDrawable.getBounds().bottom);
+
+        bounds = mockDrawable.getBounds();
+        assertEquals(2, bounds.left);
+        assertEquals(2, bounds.top);
+        assertEquals(26, bounds.right);
+        assertEquals(32, bounds.bottom);
+
+        // input null as param
+        try {
+            mockDrawableWrapper.onBoundsChange(null);
+            fail("There should be a NullPointerException thrown out.");
+        } catch (NullPointerException e) {
+            // expected, test success
+        }
+
+    }
+
+    public void testGetIntrinsicWidth() {
+        MockDrawable mockDrawable = new MockDrawable();
+        MyWrapper wrapper = new MyWrapper(mockDrawable);
+
+        // this method will call contained drawable's getIntrinsicWidth method.
+        wrapper.getIntrinsicWidth();
+        assertTrue(mockDrawable.hasCalledGetIntrinsicWidth());
+    }
+
+    public void testGetIntrinsicHeight() {
+        MockDrawable mockDrawable = new MockDrawable();
+        DrawableWrapper wrapper = new MyWrapper(mockDrawable);
+
+        // this method will call contained drawable's getIntrinsicHeight method.
+        wrapper.getIntrinsicHeight();
+        assertTrue(mockDrawable.hasCalledGetIntrinsicHeight());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetConstantState() {
+        DrawableWrapper wrapper = new MyWrapper(new BitmapDrawable());
+        ConstantState constantState = wrapper.getConstantState();
+    }
+
+    private static class MockDrawable extends Drawable {
+        private boolean mCalledDraw = false;
+        private boolean mCalledGetPadding = false;
+        private boolean mCalledSetVisible = false;
+        private boolean mCalledSetAlpha = false;
+        private boolean mCalledGetOpacity = false;
+        private boolean mCalledSetColorFilter = false;
+        private boolean mCalledIsStateful = false;
+        private boolean mCalledGetIntrinsicWidth = false;
+        private boolean mCalledGetIntrinsicHeight = false;
+        private boolean mCalledSetState = false;
+        private boolean mCalledOnLevelChange = false;
+
+        @Override
+        public void draw(Canvas canvas) {
+            mCalledDraw = true;
+        }
+
+        @Override
+        public int getOpacity() {
+            mCalledGetOpacity = true;
+            return 0;
+        }
+
+        @Override
+        public void setAlpha(int alpha) {
+            mCalledSetAlpha = true;
+        }
+
+        @Override
+        public void setColorFilter(ColorFilter cf) {
+            mCalledSetColorFilter = true;
+        }
+
+        @Override
+        public boolean getPadding(Rect padding) {
+            mCalledGetPadding = true;
+            return super.getPadding(padding);
+        }
+
+        @Override
+        public boolean setVisible(boolean visible, boolean restart) {
+            mCalledSetVisible = true;
+            return super.setVisible(visible, restart);
+        }
+
+        @Override
+        public boolean isStateful() {
+            mCalledIsStateful = true;
+            return super.isStateful();
+        }
+
+        @Override
+        public int getIntrinsicWidth() {
+            mCalledGetIntrinsicWidth = true;
+            return super.getIntrinsicWidth();
+        }
+
+        @Override
+        public int getIntrinsicHeight() {
+            mCalledGetIntrinsicHeight = true;
+            return super.getIntrinsicHeight();
+
+        }
+
+        @Override
+        public boolean setState(final int[] stateSet) {
+            mCalledSetState = true;
+            return super.setState(stateSet);
+        }
+
+        @Override
+        protected boolean onLevelChange(int level) {
+            mCalledOnLevelChange = true;
+            return super.onLevelChange(level);
+        }
+
+        public boolean hasCalledDraw() {
+            return mCalledDraw;
+        }
+
+        public boolean hasCalledGetPadding() {
+            return mCalledGetPadding;
+        }
+
+        public boolean hasCalledSetVisible() {
+            return mCalledSetVisible;
+        }
+
+        public boolean hasCalledSetAlpha() {
+            return mCalledSetAlpha;
+        }
+
+        public boolean hasCalledGetOpacity() {
+            return mCalledGetOpacity;
+        }
+
+        public boolean hasCalledSetColorFilter() {
+            return mCalledSetColorFilter;
+        }
+
+        public boolean hasCalledIsStateful() {
+            return mCalledIsStateful;
+        }
+
+        public boolean hasCalledGetIntrinsicWidth() {
+            return mCalledGetIntrinsicWidth;
+        }
+
+        public boolean hasCalledGetIntrinsicHeight() {
+            return mCalledGetIntrinsicHeight;
+        }
+
+        public boolean hasCalledSetState() {
+            return mCalledSetState;
+        }
+
+        public boolean hasCalledOnLevelChange() {
+            return mCalledOnLevelChange;
+        }
+
+        public void reset() {
+            mCalledDraw = false;
+            mCalledGetPadding = false;
+            mCalledSetVisible = false;
+            mCalledSetAlpha = false;
+            mCalledGetOpacity = false;
+            mCalledSetColorFilter = false;
+            mCalledIsStateful = false;
+            mCalledGetIntrinsicWidth = false;
+            mCalledGetIntrinsicHeight = false;
+            mCalledSetState = false;
+            mCalledOnLevelChange = false;
+        }
+    }
+
+    private static class MockDrawableWrapper extends DrawableWrapper {
+        private boolean mCalledOnBoundsChange = false;
+
+        MockDrawableWrapper() {
+            super(null);
+        }
+
+        public MockDrawableWrapper(Drawable drawable) {
+            super(drawable);
+        }
+
+        @Override
+        protected boolean onStateChange(int[] state) {
+            return super.onStateChange(state);
+        }
+
+        @Override
+        protected boolean onLevelChange(int level) {
+            return super.onLevelChange(level);
+        }
+
+        @Override
+        protected void onBoundsChange(Rect bounds) {
+            mCalledOnBoundsChange = true;
+            super.onBoundsChange(bounds);
+        }
+
+        public boolean hasCalledOnBoundsChange() {
+            return mCalledOnBoundsChange;
+        }
+
+        public void reset() {
+            mCalledOnBoundsChange = 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 e7a38c5..eeda22c 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/GradientDrawableTest.java
@@ -22,10 +22,8 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.content.res.Resources;
-import android.content.res.Resources.Theme;
 import android.graphics.Canvas;
 import android.graphics.ColorFilter;
-import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.GradientDrawable;
 import android.graphics.drawable.Drawable.ConstantState;
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/IconTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/IconTest.java
new file mode 100644
index 0000000..d89ce7c
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/IconTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 com.android.cts.graphics.R;
+
+import android.app.Activity;
+import android.app.Instrumentation;
+import android.content.res.ColorStateList;
+import android.graphics.Bitmap;
+import android.graphics.cts.ImageViewCtsActivity;
+import android.graphics.drawable.Icon;
+import android.graphics.drawable.Drawable;
+import android.graphics.Color;
+import android.graphics.PorterDuff;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcel;
+import android.test.ActivityInstrumentationTestCase2;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class IconTest extends ActivityInstrumentationTestCase2<ImageViewCtsActivity> {
+    static final long TIMEOUT = 1000;
+
+    Activity mActivity;
+    Instrumentation mInstrumentation;
+    Icon mIcon;
+
+    MockOnDrawableLoadedListener mListener;
+    MockRunner mRunner;
+
+    public IconTest() {
+        super("com.android.cts.graphics", ImageViewCtsActivity.class);
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mInstrumentation = getInstrumentation();
+    }
+
+    public void testBitmapIcon() {
+        checkIconValidity(
+                Icon.createWithBitmap(Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888)));
+    }
+
+    public void testDataIcon() {
+        byte[] data = new byte[4];
+        data[0] = data[1] = data[2] = data[3] = (byte)255;
+        checkIconValidity(Icon.createWithData(data, 0, 4));
+    }
+
+    public void testFileIcon() throws IOException {
+        File file = new File(mActivity.getFilesDir(), "testimage.jpg");
+        try {
+            writeSampleImage(file);
+            assertTrue(file.exists());
+
+            checkIconValidity(Icon.createWithFilePath(file.getPath()));
+
+            checkIconValidity(Icon.createWithContentUri(Uri.fromFile(file)));
+
+            checkIconValidity(Icon.createWithContentUri(file.toURI().toString()));
+        } finally {
+            file.delete();
+        }
+    }
+
+    public void testResourceIcon() {
+        checkIconValidity(Icon.createWithResource(mActivity, R.drawable.bmp_test));
+
+        checkIconValidity(Icon.createWithResource(mActivity.getPackageName(), R.drawable.bmp_test));
+    }
+
+    public void testLoadDrawableAsync() {
+        mIcon = Icon.createWithBitmap(Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888));
+
+        mListener = new MockOnDrawableLoadedListener();
+        mInstrumentation.runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mIcon.loadDrawableAsync(mActivity, mListener, new Handler());
+            }
+        });
+        sleep(TIMEOUT);
+
+        assertEquals(1, mListener.getLoadedCount());
+    }
+
+    public void testLoadDrawableAsyncWithMessage() {
+        mIcon = Icon.createWithBitmap(Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888));
+
+        mRunner = new MockRunner();
+        mInstrumentation.runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                mIcon.loadDrawableAsync(mActivity, Message.obtain(new Handler(), mRunner));
+            }
+        });
+        sleep(TIMEOUT);
+
+        assertEquals(1, mRunner.getRunCount());
+    }
+
+    class MockOnDrawableLoadedListener implements Icon.OnDrawableLoadedListener {
+        int mLoadedCount;
+
+        @Override
+        public void onDrawableLoaded(Drawable d) {
+            assertNotNull(d);
+            ++mLoadedCount;
+        }
+
+        int getLoadedCount() { return mLoadedCount; }
+    }
+
+    class MockRunner implements Runnable {
+        int mRun;
+
+        @Override
+        public void run() {
+            ++mRun;
+        }
+
+        int getRunCount() { return mRun; }
+    };
+
+    private void sleep(long time) {
+        try {
+            Thread.sleep(time);
+        } catch (InterruptedException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    private void writeSampleImage(File imagefile) throws IOException {
+        InputStream source = null;
+        OutputStream target = null;
+
+        try {
+            source = mActivity.getResources().openRawResource(R.drawable.testimage);
+            target = new FileOutputStream(imagefile);
+
+            byte[] buffer = new byte[1024];
+            for (int len = source.read(buffer); len >= 0; len = source.read(buffer)) {
+                target.write(buffer, 0, len);
+            }
+        } finally {
+            if (target != null) {
+                target.close();
+            }
+
+            if (source != null) {
+                source.close();
+            }
+        }
+    }
+
+    // Check if the created icon is valid and doesn't cause crashes for the public methods.
+    private void checkIconValidity(Icon icon) {
+        assertNotNull(icon);
+
+        // tint properties.
+        icon.setTint(Color.BLUE);
+        icon.setTintList(ColorStateList.valueOf(Color.RED));
+        icon.setTintMode(PorterDuff.Mode.XOR);
+
+        // Parcelable methods.
+        icon.describeContents();
+        Parcel parcel = Parcel.obtain();
+        icon.writeToParcel(parcel, 0);
+
+        parcel.setDataPosition(0);
+        assertNotNull(Icon.CREATOR.createFromParcel(parcel));
+
+        // loading drawable synchronously.
+        assertNotNull(icon.loadDrawable(mActivity));
+    }
+}
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 1edd36e..9c5f063 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/InsetDrawableTest.java
@@ -18,7 +18,6 @@
 
 import com.android.cts.graphics.R;
 
-
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -32,13 +31,16 @@
 import android.graphics.drawable.Drawable.ConstantState;
 import android.test.AndroidTestCase;
 import android.util.AttributeSet;
+import android.util.StateSet;
 import android.util.Xml;
 
 import java.io.IOException;
+import java.util.Arrays;
 
 public class InsetDrawableTest extends AndroidTestCase {
+
     public void testConstructor() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         new InsetDrawable(d, 1);
         new InsetDrawable(d, 1, 1, 1, 1);
 
@@ -47,8 +49,7 @@
     }
 
     public void testInflate() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
-        InsetDrawable insetDrawable = new InsetDrawable(d, 0);
+        InsetDrawable insetDrawable = new InsetDrawable(null, 0);
 
         Resources r = mContext.getResources();
         XmlPullParser parser = r.getXml(R.layout.framelayout_layout);
@@ -77,14 +78,14 @@
     }
 
     public void testInvalidateDrawable() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         insetDrawable.invalidateDrawable(d);
     }
 
     public void testScheduleDrawable() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         Runnable runnable = new Runnable() {
@@ -99,7 +100,7 @@
     }
 
     public void testUnscheduleDrawable() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         Runnable runnable = new Runnable() {
@@ -114,7 +115,7 @@
     }
 
     public void testDraw() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         Canvas c = new Canvas();
@@ -130,7 +131,7 @@
     }
 
     public void testGetChangingConfigurations() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         insetDrawable.setChangingConfigurations(11);
@@ -141,7 +142,7 @@
     }
 
     public void testGetPadding() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 1, 2, 3, 4);
 
         Rect r = new Rect();
@@ -183,7 +184,7 @@
     }
 
     public void testSetVisible() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         assertFalse(insetDrawable.setVisible(true, true)); /* unchanged */
@@ -192,7 +193,7 @@
     }
 
     public void testSetAlpha() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         insetDrawable.setAlpha(1);
@@ -204,7 +205,7 @@
     }
 
     public void testSetColorFilter() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         ColorFilter cf = new ColorFilter();
@@ -216,7 +217,7 @@
     }
 
     public void testGetOpacity() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.testimage);
+        Drawable d = mContext.getDrawable(R.drawable.testimage);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
         insetDrawable.setAlpha(255);
         assertEquals(PixelFormat.OPAQUE, insetDrawable.getOpacity());
@@ -226,28 +227,25 @@
     }
 
     public void testIsStateful() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
         assertFalse(insetDrawable.isStateful());
     }
 
     public void testOnStateChange() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         MockInsetDrawable insetDrawable = new MockInsetDrawable(d, 10);
-
-        Rect bounds = d.getBounds();
-        assertEquals(0, bounds.left);
-        assertEquals(0, bounds.top);
-        assertEquals(0, bounds.right);
-        assertEquals(0, bounds.bottom);
+        assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
 
         int[] state = new int[] {1, 2, 3};
-        assertFalse(insetDrawable.onStateChange(state));
+        assertFalse("child did not change", insetDrawable.onStateChange(state));
+        assertEquals("child state did not change", d.getState(), StateSet.WILD_CARD);
 
-        assertEquals(10, bounds.left);
-        assertEquals(10, bounds.top);
-        assertEquals(-10, bounds.right);
-        assertEquals(-10, bounds.bottom);
+        d = mContext.getDrawable(R.drawable.statelistdrawable);
+        insetDrawable = new MockInsetDrawable(d, 10);
+        assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
+        insetDrawable.onStateChange(state);
+        assertTrue("child state changed", Arrays.equals(state, d.getState()));
 
         // input null as param
         insetDrawable.onStateChange(null);
@@ -255,7 +253,7 @@
     }
 
     public void testOnBoundsChange() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         MockInsetDrawable insetDrawable = new MockInsetDrawable(d, 5);
 
         Rect bounds = d.getBounds();
@@ -282,13 +280,13 @@
     }
 
     public void testGetIntrinsicWidth() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         int expected = d.getIntrinsicWidth(); /* 31 */
         assertEquals(expected, insetDrawable.getIntrinsicWidth());
 
-        d = mContext.getResources().getDrawable(R.drawable.scenery);
+        d = mContext.getDrawable(R.drawable.scenery);
         insetDrawable = new InsetDrawable(d, 0);
 
         expected = d.getIntrinsicWidth(); /* 170 */
@@ -296,13 +294,13 @@
     }
 
     public void testGetIntrinsicHeight() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         int expected = d.getIntrinsicHeight(); /* 31 */
         assertEquals(expected, insetDrawable.getIntrinsicHeight());
 
-        d = mContext.getResources().getDrawable(R.drawable.scenery);
+        d = mContext.getDrawable(R.drawable.scenery);
         insetDrawable = new InsetDrawable(d, 0);
 
         expected = d.getIntrinsicHeight(); /* 107 */
@@ -310,13 +308,31 @@
     }
 
     public void testGetConstantState() {
-        Drawable d = mContext.getResources().getDrawable(R.drawable.pass);
+        Drawable d = mContext.getDrawable(R.drawable.pass);
         InsetDrawable insetDrawable = new InsetDrawable(d, 0);
 
         ConstantState constantState = insetDrawable.getConstantState();
         assertNotNull(constantState);
     }
 
+    public void testMutate() {
+        // Obtain the first instance, then mutate and modify a property held by
+        // constant state. If mutate() works correctly, the property should not
+        // be modified on the second or third instances.
+        Resources res = mContext.getResources();
+        InsetDrawable first = (InsetDrawable) res.getDrawable(R.drawable.inset_mutate, null);
+        InsetDrawable pre = (InsetDrawable) res.getDrawable(R.drawable.inset_mutate, null);
+
+        first.mutate().setAlpha(128);
+
+        assertEquals("Modified first loaded instance", 128, first.getDrawable().getAlpha());
+        assertEquals("Did not modify pre-mutate() instance", 255, pre.getDrawable().getAlpha());
+
+        InsetDrawable post = (InsetDrawable) res.getDrawable(R.drawable.inset_mutate, null);
+
+        assertEquals("Did not modify post-mutate() instance", 255, post.getDrawable().getAlpha());
+    }
+
     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 5aa3083..a2f9ddf 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/LayerDrawableTest.java
@@ -16,14 +16,13 @@
 
 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.R.attr;
-import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -45,6 +44,7 @@
 import android.view.View;
 
 public class LayerDrawableTest extends AndroidTestCase {
+
     @SuppressWarnings("deprecation")
     public void testConstructor() {
         Drawable bitmapDrawable = new BitmapDrawable();
@@ -60,9 +60,9 @@
         assertEquals(0, layerDrawable.getNumberOfLayers());
 
         try {
-            new LayerDrawable((Drawable[]) null);
-            fail("Should throw NullPointerException");
-        } catch (NullPointerException e) {
+            new LayerDrawable(null);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
         }
     }
 
@@ -77,7 +77,7 @@
 
         assertEquals(4, layerDrawable.getNumberOfLayers());
         assertEquals(ColorDrawable.class, layerDrawable.getDrawable(0).getClass());
-        assertEquals(0x88, (((ColorDrawable) layerDrawable.getDrawable(0)).getAlpha()));
+        assertEquals(0x88, layerDrawable.getDrawable(0).getAlpha());
         assertEquals(View.NO_ID, layerDrawable.getId(0));
         assertEquals(BitmapDrawable.class, layerDrawable.getDrawable(1).getClass());
         assertEquals(View.NO_ID, layerDrawable.getId(1));
@@ -236,6 +236,27 @@
     }
 
     @SuppressWarnings("deprecation")
+    public void testSetDrawableByLayerId() {
+        Drawable layer1A  = new ColorDrawable(Color.RED);
+        Drawable layer2A  = new ColorDrawable(Color.BLUE);
+        LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] { layer1A, layer2A });
+        layerDrawable.setId(0, 10);
+        layerDrawable.setId(1, 20);
+
+        Drawable layer1B = new ColorDrawable(Color.GREEN);
+        layer1B.setLevel(10000);
+        Drawable layer2B = new ColorDrawable(Color.YELLOW);
+        layer2B.setLevel(5000);
+        layerDrawable.setDrawableByLayerId(10, layer1B);
+        layerDrawable.setDrawableByLayerId(20, layer2B);
+
+        assertEquals("Level is unchanged after setDrawableByLayerId()",
+                10000, layerDrawable.findDrawableByLayerId(10).getLevel());
+        assertEquals("Level is unchanged after setDrawableByLayerId()",
+                5000, layerDrawable.findDrawableByLayerId(20).getLevel());
+    }
+
+    @SuppressWarnings("deprecation")
     public void testSetLayerInset() {
         Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
         LayerDrawable layerDrawable = new LayerDrawable(array);
@@ -481,6 +502,32 @@
         assertTrue(mockDrawable2.hasCalledSetDither());
     }
 
+    public void testSetHotspotBounds() {
+        Rect bounds = new Rect(10, 15, 100, 150);
+        MockDrawable mockDrawable1 = new MockDrawable();
+        MockDrawable mockDrawable2 = new MockDrawable();
+        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
+        Rect outRect = new Rect();
+        layerDrawable.getHotspotBounds(outRect);
+        assertTrue(bounds.equals(outRect));
+    }
+
+    public void testGetHotspotBounds() {
+        Rect bounds = new Rect(10, 15, 100, 150);
+        MockDrawable mockDrawable1 = new MockDrawable();
+        MockDrawable mockDrawable2 = new MockDrawable();
+        Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setHotspotBounds(bounds.left, bounds.top, bounds.right, bounds.bottom);
+        Rect outRect = new Rect();
+        layerDrawable.getHotspotBounds(outRect);
+        assertTrue(bounds.equals(outRect));
+    }
+
     public void testSetAlpha() {
         MockDrawable mockDrawable1 = new MockDrawable();
         MockDrawable mockDrawable2 = new MockDrawable();
@@ -556,70 +603,85 @@
         assertTrue(layerDrawable.isStateful());
     }
 
-    public void testOnStateChange() {
+    public void testSetState() {
         MockDrawable mockDrawable1 = new MockDrawable(true);
         MockDrawable mockDrawable2 = new MockDrawable(true);
         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
-        MockLayerDrawable layerDrawable = new MockLayerDrawable(array);
+        LayerDrawable layerDrawable = new LayerDrawable(array);
 
-        // this method will call each child's setState().
-        assertFalse(layerDrawable.onStateChange(StateSet.WILD_CARD));
-        assertTrue(mockDrawable1.hasCalledSetState());
-        assertTrue(mockDrawable2.hasCalledSetState());
-        assertTrue(layerDrawable.hasCalledOnBoundsChange());
+        // Call onStateChange() without actually changing the state.
+        assertFalse(layerDrawable.setState(StateSet.WILD_CARD));
+        assertFalse(mockDrawable1.hasCalledSetState());
+        assertFalse(mockDrawable2.hasCalledSetState());
+        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
+        assertFalse(mockDrawable2.hasCalledOnBoundsChange());
 
+        // Call onStateChange() to change the state from WILD_CARD to null.
+        // This alters the padding of both layers, which forces a bounds change
+        // for the second layer due to the default "nest" padding mode.
         mockDrawable1.reset();
         mockDrawable2.reset();
-        layerDrawable.reset();
-        assertTrue(layerDrawable.onStateChange(null));
+        assertTrue(layerDrawable.setState(null));
         assertTrue(mockDrawable1.hasCalledSetState());
         assertTrue(mockDrawable2.hasCalledSetState());
-        assertTrue(layerDrawable.hasCalledOnBoundsChange());
+        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
+        assertTrue(mockDrawable2.hasCalledOnBoundsChange());
 
+        // Call onStateChange() to change the state from null to valid state
+        // set. This alters the padding of both layers, which forces a bounds
+        // change for the second layer due to the default "nest" padding mode.
         mockDrawable1.reset();
         mockDrawable2.reset();
-        layerDrawable.reset();
-        assertTrue(layerDrawable.onStateChange(new int[] { attr.state_checked, attr.state_empty }));
+        assertTrue(layerDrawable.setState(new int[]{
+                android.R.attr.state_checked, android.R.attr.state_empty}));
         assertTrue(mockDrawable1.hasCalledSetState());
         assertTrue(mockDrawable2.hasCalledSetState());
-        assertTrue(layerDrawable.hasCalledOnBoundsChange());
+        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
+        assertTrue(mockDrawable2.hasCalledOnBoundsChange());
     }
 
-    public void testOnLevelChange() {
+    public void testSetLevel() {
         MockDrawable mockDrawable1 = new MockDrawable();
         MockDrawable mockDrawable2 = new MockDrawable();
         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
-        MockLayerDrawable layerDrawable = new MockLayerDrawable(array);
+        LayerDrawable layerDrawable = new LayerDrawable(array);
 
-        // this method will call each child's setLevel(),
-        // but just when set a different level the child's onLevelChange will be called.
-        assertFalse(layerDrawable.onLevelChange(0));
+        // Call onLevelChange() without actually changing the level.
+        assertFalse(layerDrawable.setLevel(0));
         assertFalse(mockDrawable1.hasCalledOnLevelChange());
         assertFalse(mockDrawable2.hasCalledOnLevelChange());
-        assertFalse(layerDrawable.hasCalledOnBoundsChange());
+        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
+        assertFalse(mockDrawable2.hasCalledOnBoundsChange());
 
+        // Call onLevelChange() to change the level from 0 to MAX_VALUE. This
+        // alters the padding of both layers, which forces a bounds change for
+        // the second layer due to the default "nest" padding mode.
         mockDrawable1.reset();
         mockDrawable2.reset();
-        layerDrawable.reset();
-        assertTrue(layerDrawable.onLevelChange(Integer.MAX_VALUE));
+        assertTrue(layerDrawable.setLevel(Integer.MAX_VALUE));
         assertTrue(mockDrawable1.hasCalledOnLevelChange());
         assertTrue(mockDrawable2.hasCalledOnLevelChange());
-        assertTrue(layerDrawable.hasCalledOnBoundsChange());
+        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
+        assertTrue(mockDrawable2.hasCalledOnBoundsChange());
 
+        // Call onLevelChange() to change the level from MAX_VALUE to
+        // MIN_VALUE. This alters the padding of both layers, which forces a
+        // bounds change for the second layer due to the default "nest" padding
+        // mode.
         mockDrawable1.reset();
         mockDrawable2.reset();
-        layerDrawable.reset();
-        assertTrue(layerDrawable.onLevelChange(Integer.MIN_VALUE));
+        assertTrue(layerDrawable.setLevel(Integer.MIN_VALUE));
         assertTrue(mockDrawable1.hasCalledOnLevelChange());
         assertTrue(mockDrawable2.hasCalledOnLevelChange());
-        assertTrue(layerDrawable.hasCalledOnBoundsChange());
+        assertFalse(mockDrawable1.hasCalledOnBoundsChange());
+        assertTrue(mockDrawable2.hasCalledOnBoundsChange());
     }
 
-    public void testOnBoundsChange() {
+    public void testSetBounds() {
         MockDrawable mockDrawable1 = new MockDrawable();
         MockDrawable mockDrawable2 = new MockDrawable();
         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
-        MockLayerDrawable layerDrawable = new MockLayerDrawable(array);
+        LayerDrawable layerDrawable = new LayerDrawable(array);
 
         Rect inset1 = new Rect(1, 2, 3, 4);
         Rect inset2 = new Rect(2, 4, 6, 7);
@@ -642,7 +704,7 @@
         assertEquals(0, mockDrawable2.getBounds().bottom);
 
         Rect bounds = new Rect(10, 20, 30, 40);
-        layerDrawable.onBoundsChange(bounds);
+        layerDrawable.setBounds(bounds);
 
         // all children's bounds will be changed after call onBoundsChange
         assertEquals(bounds.left + inset1.left, mockDrawable1.getBounds().left);
@@ -661,7 +723,7 @@
         MockDrawable mockDrawable1 = new MockDrawable();
         MockDrawable mockDrawable2 = new MockDrawable();
         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
-        MockLayerDrawable layerDrawable = new MockLayerDrawable(array);
+        LayerDrawable layerDrawable = new LayerDrawable(array);
         assertEquals(mockDrawable1.getIntrinsicWidth(), layerDrawable.getIntrinsicWidth());
 
         Rect inset1 = new Rect(1, 2, 3, 4);
@@ -688,7 +750,7 @@
         MockDrawable mockDrawable1 = new MockDrawable();
         MockDrawable mockDrawable2 = new MockDrawable();
         Drawable[] array = new Drawable[] { mockDrawable1, mockDrawable2 };
-        MockLayerDrawable layerDrawable = new MockLayerDrawable(array);
+        LayerDrawable layerDrawable = new LayerDrawable(array);
         assertEquals(mockDrawable1.getIntrinsicHeight(), layerDrawable.getIntrinsicHeight());
 
         Rect inset1 = new Rect(1, 2, 3, 4);
@@ -725,6 +787,611 @@
         assertEquals(1, constantState.getChangingConfigurations());
     }
 
+    @SuppressWarnings("deprecation")
+    public void testAddLayer() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        BitmapDrawable newDrawable = new BitmapDrawable();
+        int index = layerDrawable.addLayer(newDrawable);
+
+        final int numLayers = layerDrawable.getNumberOfLayers();
+        assertEquals(index, numLayers - 1);
+        assertEquals(newDrawable, layerDrawable.getDrawable(index));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetDrawable() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        final int numLayers = layerDrawable.getNumberOfLayers();
+        assertEquals(array[0], layerDrawable.getDrawable(0));
+        assertEquals(array[1], layerDrawable.getDrawable(1));
+        try {
+            assertEquals(null, layerDrawable.getDrawable(2));
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testFindIndexByLayerId() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setId(0, 10);
+        layerDrawable.setId(1, 20);
+
+        assertEquals(0, layerDrawable.findIndexByLayerId(10));
+        assertEquals(1, layerDrawable.findIndexByLayerId(20));
+        assertEquals(-1, layerDrawable.findIndexByLayerId(30));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetDrawable() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        BitmapDrawable newBitmapDrawable = new BitmapDrawable();
+        ColorDrawable newColorDrawable = new ColorDrawable(Color.GREEN);
+        layerDrawable.setDrawable(0, newColorDrawable);
+        layerDrawable.setDrawable(1, newBitmapDrawable);
+
+        final int numLayers = layerDrawable.getNumberOfLayers();
+        assertEquals(2, numLayers);
+        assertEquals(newColorDrawable, layerDrawable.getDrawable(0));
+        assertEquals(newBitmapDrawable, layerDrawable.getDrawable(1));
+        try {
+            assertEquals(null, layerDrawable.getDrawable(2));
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLeftPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(10, layerDrawable.getLeftPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetTopPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(11, layerDrawable.getTopPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetRightPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(20, layerDrawable.getRightPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetBottomPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(21, layerDrawable.getBottomPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetStartPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(-1, layerDrawable.getStartPadding());
+        layerDrawable.setPaddingRelative(10, 11, 20, 21);
+        assertEquals(10, layerDrawable.getStartPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetEndPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(-1, layerDrawable.getEndPadding());
+        layerDrawable.setPaddingRelative(10, 11, 20, 21);
+        assertEquals(20, layerDrawable.getEndPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetPadding() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPadding(10, 11, 20, 21);
+
+        assertEquals(10, layerDrawable.getLeftPadding());
+        assertEquals(11, layerDrawable.getTopPadding());
+        assertEquals(20, layerDrawable.getRightPadding());
+        assertEquals(21, layerDrawable.getBottomPadding());
+        assertEquals(-1, layerDrawable.getStartPadding());
+        assertEquals(-1, layerDrawable.getEndPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetPaddingRelative() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable()};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+        layerDrawable.setPaddingRelative(10, 11, 20, 21);
+
+        assertEquals(10, layerDrawable.getStartPadding());
+        assertEquals(11, layerDrawable.getTopPadding());
+        assertEquals(20, layerDrawable.getEndPadding());
+        assertEquals(21, layerDrawable.getBottomPadding());
+        assertEquals(-1, layerDrawable.getLeftPadding());
+        assertEquals(-1, layerDrawable.getRightPadding());
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerGravity() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerGravity(0, Gravity.CENTER);
+        layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY);
+
+        try {
+            layerDrawable.setLayerGravity(2, Gravity.TOP);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0));
+        assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerGravity() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerGravity(0, Gravity.CENTER);
+        layerDrawable.setLayerGravity(1, Gravity.NO_GRAVITY);
+
+        assertEquals(Gravity.CENTER, layerDrawable.getLayerGravity(0));
+        assertEquals(Gravity.NO_GRAVITY, layerDrawable.getLayerGravity(1));
+        try {
+            layerDrawable.getLayerGravity(2);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerWidth() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerWidth(0, 100);
+        layerDrawable.setLayerWidth(1, 200);
+
+        try {
+            layerDrawable.setLayerWidth(2, 300);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        assertEquals(100, layerDrawable.getLayerWidth(0));
+        assertEquals(200, layerDrawable.getLayerWidth(1));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerWidth() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerWidth(0, 100);
+        layerDrawable.setLayerWidth(1, 200);
+
+        assertEquals(100, layerDrawable.getLayerWidth(0));
+        assertEquals(200, layerDrawable.getLayerWidth(1));
+        try {
+            layerDrawable.getLayerWidth(2);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerHeight() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerHeight(0, 100);
+        layerDrawable.setLayerHeight(1, 200);
+
+        try {
+            layerDrawable.setLayerHeight(2, 300);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        assertEquals(100, layerDrawable.getLayerHeight(0));
+        assertEquals(200, layerDrawable.getLayerHeight(1));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerHeight() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerHeight(0, 100);
+        layerDrawable.setLayerHeight(1, 200);
+
+        assertEquals(100, layerDrawable.getLayerHeight(0));
+        assertEquals(200, layerDrawable.getLayerHeight(1));
+        try {
+            layerDrawable.getLayerHeight(2);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerSize() {
+        Drawable[] array = new Drawable[]{new BitmapDrawable(), new ColorDrawable(Color.BLUE)};
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        layerDrawable.setLayerSize(0, 100, 200);
+        layerDrawable.setLayerSize(1, 300, 400);
+
+        try {
+            layerDrawable.setLayerSize(2, 500, 600);
+            fail("Should throw ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException e) {
+        }
+        assertEquals(100, layerDrawable.getLayerWidth(0));
+        assertEquals(200, layerDrawable.getLayerHeight(0));
+        assertEquals(300, layerDrawable.getLayerWidth(1));
+        assertEquals(400, layerDrawable.getLayerHeight(1));
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetRelative() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable(), new ColorDrawable(Color.BLUE) };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                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(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,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(layerDrawable.getDrawable(1).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+
+
+        try {
+            layerDrawable.setLayerInsetRelative(-1, start, top, end, bottom);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetLeft() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
+                layerDrawable.getIntrinsicWidth());
+        left += 5;
+        layerDrawable.setLayerInsetLeft(0, left);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(left, layerDrawable.getLayerInsetLeft(0));
+
+        try {
+            layerDrawable.setLayerInsetLeft(1, left);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetLeft() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(left, layerDrawable.getLayerInsetLeft(0));
+        left += 5;
+        layerDrawable.setLayerInsetLeft(0, left);
+        assertEquals(left, layerDrawable.getLayerInsetLeft(0));
+
+        try {
+            layerDrawable.getLayerInsetLeft(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetTop() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+        top += 5;
+        layerDrawable.setLayerInsetTop(0, top);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+        assertEquals(top, layerDrawable.getLayerInsetTop(0));
+
+        try {
+            layerDrawable.setLayerInsetTop(1, top);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetTop() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(top, layerDrawable.getLayerInsetTop(0));
+        top += 5;
+        layerDrawable.setLayerInsetTop(0, top);
+        assertEquals(top, layerDrawable.getLayerInsetTop(0));
+
+        try {
+            layerDrawable.getLayerInsetTop(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetRight() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
+                layerDrawable.getIntrinsicWidth());
+        right += 5;
+        layerDrawable.setLayerInsetRight(0, right);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + left + right,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(right, layerDrawable.getLayerInsetRight(0));
+
+        try {
+            layerDrawable.setLayerInsetRight(1, right);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetRight() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(right, layerDrawable.getLayerInsetRight(0));
+        right += 5;
+        layerDrawable.setLayerInsetRight(0, right);
+        assertEquals(right, layerDrawable.getLayerInsetRight(0));
+
+        try {
+            layerDrawable.getLayerInsetRight(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetBottom() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+        bottom += 5;
+        layerDrawable.setLayerInsetBottom(0, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicHeight() + top + bottom,
+                layerDrawable.getIntrinsicHeight());
+        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
+
+        try {
+            layerDrawable.setLayerInsetBottom(1, bottom);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetBottom() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int left = 10;
+        int top = 20;
+        int right = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInset(0, left, top, right, bottom);
+        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
+        bottom += 5;
+        layerDrawable.setLayerInsetBottom(0, bottom);
+        assertEquals(bottom, layerDrawable.getLayerInsetBottom(0));
+
+        try {
+            layerDrawable.getLayerInsetBottom(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetStart() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        start += 5;
+        layerDrawable.setLayerInsetStart(0, start);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(start, layerDrawable.getLayerInsetStart(0));
+
+        try {
+            layerDrawable.setLayerInset(1, start, top, end, bottom);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetStart() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(start, layerDrawable.getLayerInsetStart(0));
+        start += 5;
+        layerDrawable.setLayerInsetStart(0, start);
+        assertEquals(start, layerDrawable.getLayerInsetStart(0));
+
+        try {
+            layerDrawable.getLayerInsetStart(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testSetLayerInsetEnd() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        end += 5;
+        layerDrawable.setLayerInsetEnd(0, end);
+        assertEquals(layerDrawable.getDrawable(0).getIntrinsicWidth() + start + end,
+                layerDrawable.getIntrinsicWidth());
+        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
+
+        try {
+            layerDrawable.setLayerInsetEnd(1, end);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGetLayerInsetEnd() {
+        Drawable[] array = new Drawable[] { new BitmapDrawable() };
+        LayerDrawable layerDrawable = new LayerDrawable(array);
+
+        // set inset for layer 0
+        int start = 10;
+        int top = 20;
+        int end = 30;
+        int bottom = 40;
+        layerDrawable.setLayerInsetRelative(0, start, top, end, bottom);
+        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
+        end += 5;
+        layerDrawable.setLayerInsetEnd(0, end);
+        assertEquals(end, layerDrawable.getLayerInsetEnd(0));
+
+        try {
+            layerDrawable.getLayerInsetEnd(1);
+            fail("Should throw IndexOutOfBoundsException");
+        } catch (IndexOutOfBoundsException e) {
+        }
+    }
+
+
+
     private static class MockDrawable extends Drawable {
         private boolean mCalledSetDither = false;
         private boolean mCalledSetAlpha = false;
@@ -732,6 +1399,8 @@
 
         private boolean mCalledSetState = false;
         private boolean mCalledOnLevelChange = false;
+        private boolean mCalledOnBoundsChange = false;
+
 
         private boolean mCalledDraw = false;
 
@@ -739,6 +1408,8 @@
 
         private int mOpacity = PixelFormat.OPAQUE;
 
+        private boolean mDither = false;
+
         Rect mPadding = null;
 
         public MockDrawable() {
@@ -779,6 +1450,7 @@
 
         @Override
         public void setDither(boolean dither) {
+            mDither = dither;
             mCalledSetDither = true;
         }
 
@@ -801,13 +1473,15 @@
 
             mCalledSetState = false;
             mCalledOnLevelChange = false;
+            mCalledOnBoundsChange = false;
 
             mCalledDraw = false;
         }
 
         @Override
         protected boolean onStateChange(int[] state) {
-            return true;
+            increasePadding();
+            return mIsStateful;
         }
 
         private void increasePadding() {
@@ -829,6 +1503,16 @@
         }
 
         @Override
+        protected void onBoundsChange(Rect bounds) {
+            mCalledOnBoundsChange = true;
+            super.onBoundsChange(bounds);
+        }
+
+        public boolean hasCalledOnBoundsChange() {
+            return mCalledOnBoundsChange;
+        }
+
+        @Override
         public boolean isStateful() {
             return mIsStateful;
         }
@@ -839,7 +1523,6 @@
 
         @Override
         public boolean setState(final int[] stateSet) {
-            increasePadding();
             mCalledSetState = true;
             return super.setState(stateSet);
         }
@@ -870,44 +1553,10 @@
         }
     }
 
-    private static class MockLayerDrawable extends LayerDrawable {
-        private boolean mCalledOnBoundsChange = false;
-
-        public MockLayerDrawable(Drawable[] array) {
-            super(array);
-        }
-
-        // override protected methods
-        @Override
-        protected boolean onStateChange(int[] state) {
-            return super.onStateChange(state);
-        }
-
-        @Override
-        protected boolean onLevelChange(int level) {
-            return super.onLevelChange(level);
-        }
-
-        @Override
-        protected void onBoundsChange(Rect bounds) {
-            mCalledOnBoundsChange = true;
-            super.onBoundsChange(bounds);
-        }
-
-        public boolean hasCalledOnBoundsChange() {
-            return mCalledOnBoundsChange;
-        }
-
-        public void reset() {
-            mCalledOnBoundsChange = false;
-        }
-    }
-
     public void testMutate() {
-        Resources resources = mContext.getResources();
-        LayerDrawable d1 = (LayerDrawable) resources.getDrawable(R.drawable.layerdrawable);
-        LayerDrawable d2 = (LayerDrawable) resources.getDrawable(R.drawable.layerdrawable);
-        LayerDrawable d3 = (LayerDrawable) resources.getDrawable(R.drawable.layerdrawable);
+        LayerDrawable d1 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable);
+        LayerDrawable d2 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable);
+        LayerDrawable d3 = (LayerDrawable) mContext.getDrawable(R.drawable.layerdrawable);
 
         d1.setAlpha(100);
         assertEquals(100, ((BitmapDrawable) d1.getDrawable(0)).getPaint().getAlpha());
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 39ed55c..720397c 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/NinePatchDrawableTest.java
@@ -21,7 +21,6 @@
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
-import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
@@ -37,9 +36,7 @@
 import android.graphics.Bitmap.Config;
 import android.graphics.PorterDuff.Mode;
 import android.graphics.drawable.NinePatchDrawable;
-import android.graphics.drawable.ShapeDrawable;
 import android.graphics.drawable.Drawable.ConstantState;
-import android.graphics.drawable.shapes.RectShape;
 import android.test.InstrumentationTestCase;
 import android.util.AttributeSet;
 import android.util.Xml;
@@ -200,6 +197,27 @@
         assertTrue(mNinePatchDrawable.getPaint().isDither());
     }
 
+    public void testSetFilterBitmap() {
+        mNinePatchDrawable.setFilterBitmap(false);
+        assertFalse(mNinePatchDrawable.getPaint().isFilterBitmap());
+
+        mNinePatchDrawable.setFilterBitmap(true);
+        assertTrue(mNinePatchDrawable.getPaint().isFilterBitmap());
+    }
+
+    public void testIsFilterBitmap() {
+        mNinePatchDrawable.setFilterBitmap(false);
+        assertFalse(mNinePatchDrawable.isFilterBitmap());
+        assertEquals(mNinePatchDrawable.isFilterBitmap(),
+                mNinePatchDrawable.getPaint().isFilterBitmap());
+
+
+        mNinePatchDrawable.setFilterBitmap(true);
+        assertTrue(mNinePatchDrawable.isFilterBitmap());
+        assertEquals(mNinePatchDrawable.isFilterBitmap(),
+                mNinePatchDrawable.getPaint().isFilterBitmap());
+    }
+
     public void testGetPaint() {
         Paint paint = mNinePatchDrawable.getPaint();
         assertNotNull(paint);
diff --git a/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.java b/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.java
new file mode 100644
index 0000000..b04433c
--- /dev/null
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/RippleDrawableTest.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.graphics.drawable.cts;
+
+import com.android.cts.graphics.R;
+
+import android.content.res.ColorStateList;
+import android.graphics.drawable.RippleDrawable;
+import android.graphics.Color;
+import android.test.AndroidTestCase;
+
+public class RippleDrawableTest extends AndroidTestCase {
+    public void testConstructor() {
+        new RippleDrawable(ColorStateList.valueOf(Color.RED), null, null);
+    }
+
+    public void testAccessRadius() {
+        RippleDrawable drawable =
+            new RippleDrawable(ColorStateList.valueOf(Color.RED), null, null);
+        assertEquals(RippleDrawable.RADIUS_AUTO, drawable.getRadius());
+        drawable.setRadius(10);
+        assertEquals(10, drawable.getRadius());
+    }
+
+    public void testRadiusAttr() {
+        RippleDrawable drawable =
+                (RippleDrawable) getContext().getDrawable(R.drawable.rippledrawable_radius);
+        assertEquals(10, drawable.getRadius());
+    }
+}
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 6281582..b58e40f 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ScaleDrawableTest.java
@@ -21,6 +21,7 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.util.Arrays;
 
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
@@ -28,6 +29,7 @@
 import android.graphics.ColorFilter;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ClipDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.Drawable.ConstantState;
 import android.graphics.drawable.ScaleDrawable;
@@ -259,7 +261,8 @@
         MockDrawable mockDrawable = new MockDrawable();
         ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
 
-        // this method will call contained drawable's getOpacity method.
+        // This method will call contained drawable's getOpacity method.
+        scaleDrawable.setLevel(1);
         scaleDrawable.getOpacity();
         assertTrue(mockDrawable.hasCalledGetOpacity());
     }
@@ -274,19 +277,23 @@
     }
 
     public void testOnStateChange() {
-        MockDrawable mockDrawable = new MockDrawable();
-        MockScaleDrawable mockScaleDrawable = new MockScaleDrawable(
-                mockDrawable, Gravity.CENTER, 100, 200);
+        Drawable d = new MockDrawable();
+        MockScaleDrawable scaleDrawable = new MockScaleDrawable(d, Gravity.CENTER, 100, 200);
+        assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
 
-        assertFalse(mockScaleDrawable.onStateChange(StateSet.WILD_CARD));
-        assertTrue(mockDrawable.hasCalledSetState());
-        assertTrue(mockScaleDrawable.hasCalledOnBoundsChange());
+        int[] state = new int[] {1, 2, 3};
+        assertFalse("child did not change", scaleDrawable.onStateChange(state));
+        assertEquals("child state did not change", d.getState(), StateSet.WILD_CARD);
 
-        mockDrawable.reset();
-        mockScaleDrawable.reset();
-        assertFalse(mockScaleDrawable.onStateChange(null));
-        assertTrue(mockDrawable.hasCalledSetState());
-        assertTrue(mockScaleDrawable.hasCalledOnBoundsChange());
+        d = mContext.getDrawable(R.drawable.statelistdrawable);
+        scaleDrawable = new MockScaleDrawable(d, Gravity.CENTER, 100, 200);
+        assertEquals("initial child state is empty", d.getState(), StateSet.WILD_CARD);
+        scaleDrawable.onStateChange(state);
+        assertTrue("child state changed", Arrays.equals(state, d.getState()));
+
+        // input null as param
+        scaleDrawable.onStateChange(null);
+        // expected, no Exception thrown out, test success
     }
 
     public void testOnLevelChange() {
@@ -412,35 +419,34 @@
         parser = res.getXml(R.xml.scaledrawable);
         attrs = DrawableTestUtils.getAttributeSet(parser, "scale_nodrawable");
         try {
-            scaleDrawable.inflate(res, parser, attrs);
-            fail("Should throw XmlPullParserException");
+            Drawable.createFromXmlInner(res, parser, attrs);
+            fail("Should throw XmlPullParserException if missing drawable");
         } catch (XmlPullParserException e) {
         }
 
         try {
-            scaleDrawable.inflate(null, parser, attrs);
+            Drawable.createFromXmlInner(null, parser, attrs);
             fail("Should throw NullPointerException if resource is null");
         } catch (NullPointerException e) {
         }
 
         try {
-            scaleDrawable.inflate(res, null, attrs);
+            Drawable.createFromXmlInner(res, null, attrs);
             fail("Should throw NullPointerException if parser is null");
         } catch (NullPointerException e) {
         }
 
         try {
-            scaleDrawable.inflate(res, parser, null);
+            Drawable.createFromXmlInner(res, parser, null);
             fail("Should throw NullPointerException if attribute set is null");
         } catch (NullPointerException e) {
         }
     }
 
     public void testMutate() {
-        Resources resources = mContext.getResources();
-        ScaleDrawable d1 = (ScaleDrawable) resources.getDrawable(R.drawable.scaledrawable);
-        ScaleDrawable d2 = (ScaleDrawable) resources.getDrawable(R.drawable.scaledrawable);
-        ScaleDrawable d3 = (ScaleDrawable) resources.getDrawable(R.drawable.scaledrawable);
+        ScaleDrawable d1 = (ScaleDrawable) mContext.getDrawable(R.drawable.scaledrawable);
+        ScaleDrawable d2 = (ScaleDrawable) mContext.getDrawable(R.drawable.scaledrawable);
+        ScaleDrawable d3 = (ScaleDrawable) mContext.getDrawable(R.drawable.scaledrawable);
 
         d1.setAlpha(100);
         assertEquals(100, ((BitmapDrawable) d1.getDrawable()).getPaint().getAlpha());
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 b77139a..5b3234e 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ShapeDrawableTest.java
@@ -16,7 +16,6 @@
 
 package android.graphics.drawable.cts;
 
-import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.graphics.Canvas;
 import android.graphics.Color;
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 8cee91e..d7becc6 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/ThemedDrawableTest.java
@@ -17,7 +17,7 @@
 package android.graphics.drawable.cts;
 
 import android.annotation.TargetApi;
-import android.content.res.Resources;
+import android.content.res.Resources.Theme;
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.Rect;
@@ -28,21 +28,30 @@
 import android.graphics.drawable.LayerDrawable;
 import android.graphics.drawable.NinePatchDrawable;
 import android.graphics.drawable.RippleDrawable;
+import android.os.Debug;
 import android.test.AndroidTestCase;
-import android.util.SparseIntArray;
-import android.view.ContextThemeWrapper;
 import android.view.Gravity;
 
 import com.android.cts.graphics.R;
 
-@TargetApi(19)
+@TargetApi(21)
 public class ThemedDrawableTest extends AndroidTestCase {
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
 
-        mContext.setTheme(R.style.Theme_ThemedDrawableTest);
+        // Workaround for ContextImpl.setTheme() being broken.
+        final Theme theme = mContext.getResources().newTheme();
+        theme.applyStyle(R.style.Theme_ThemedDrawableTest, true);
+        final Theme ctxTheme = mContext.getTheme();
+        ctxTheme.setTo(theme);
+    }
+
+    @Override
+    public void testAndroidTestCaseSetupProperly() {
+        final TypedArray t = mContext.obtainStyledAttributes(new int[]{R.attr.themeType});
+        assertTrue("Theme was applied correctly", t.getInt(0, -1) == 0);
     }
 
     public void testBitmapDrawable() {
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 3578d3c..fdc7b7a 100644
--- a/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
+++ b/tests/tests/graphics/src/android/graphics/drawable/cts/VectorDrawableTest.java
@@ -21,6 +21,9 @@
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuffColorFilter;
 import android.graphics.drawable.VectorDrawable;
 import android.graphics.drawable.Drawable.ConstantState;
 import android.test.AndroidTestCase;
@@ -63,6 +66,8 @@
             R.drawable.vector_icon_stroke_1,
             R.drawable.vector_icon_stroke_2,
             R.drawable.vector_icon_stroke_3,
+            R.drawable.vector_icon_scale_1,
+            R.drawable.vector_icon_scale_2,
     };
 
     private int[] mGoldenImages = new int[] {
@@ -89,6 +94,8 @@
             R.drawable.vector_icon_stroke_1_golden,
             R.drawable.vector_icon_stroke_2_golden,
             R.drawable.vector_icon_stroke_3_golden,
+            R.drawable.vector_icon_scale_1_golden,
+            R.drawable.vector_icon_scale_2_golden,
     };
 
     private static final int IMAGE_WIDTH = 64;
@@ -97,7 +104,8 @@
     // 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.00001f;
+    private static final float PIXEL_ERROR_THRESHOLD = 0.02f;
+    private static final float PIXEL_ERROR_COUNT_THRESHOLD = 0.005f;
 
     private static final boolean DBG_DUMP_PNG = false;
 
@@ -216,7 +224,7 @@
                 totalDiffPixelCount++;
             }
         }
-        if ((totalDiffPixelCount / totalPixelCount) >= PIXEL_ERROR_THRESHOLD) {
+        if ((totalDiffPixelCount / totalPixelCount) >= PIXEL_ERROR_COUNT_THRESHOLD) {
             fail((filename +": totalDiffPixelCount is " + totalDiffPixelCount));
         }
 
@@ -283,4 +291,12 @@
 
         d2.setAlpha(originalAlpha);
     }
+
+    public void testColorFilter() {
+        PorterDuffColorFilter filter = new PorterDuffColorFilter(Color.RED, Mode.SRC_IN);
+        VectorDrawable vectorDrawable = new VectorDrawable();
+        vectorDrawable.setColorFilter(filter);
+
+        assertEquals(filter, vectorDrawable.getColorFilter());
+    }
 }
diff --git a/tests/tests/graphics/src/android/opengl/cts/EglConfigGLSurfaceView.java b/tests/tests/graphics/src/android/opengl/cts/EglConfigGLSurfaceView.java
index 03e8d94..eb36166 100644
--- a/tests/tests/graphics/src/android/opengl/cts/EglConfigGLSurfaceView.java
+++ b/tests/tests/graphics/src/android/opengl/cts/EglConfigGLSurfaceView.java
@@ -101,7 +101,7 @@
             gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
             gl.glColor4f(1.0f, 0, 0, 0);
             gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mFloatBuffer);
-            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 9);
+            gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
 
             if (++mNumFrames == 10) {
                 post(mCallback);
diff --git a/tests/tests/hardware/Android.mk b/tests/tests/hardware/Android.mk
index e5203e5..07d5de9 100644
--- a/tests/tests/hardware/Android.mk
+++ b/tests/tests/hardware/Android.mk
@@ -19,8 +19,11 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE := cts-sensors-tests
+
 LOCAL_MODULE_TAGS := tests
 
+LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil
+
 LOCAL_SDK_VERSION := current
 
 # TODO: sensors need to be refactored out into their own namespace: android.hardware.sensors.cts
@@ -31,6 +34,7 @@
     src/android/hardware/cts/SensorIntegrationTests.java \
     src/android/hardware/cts/SensorBatchingTests.java \
     src/android/hardware/cts/SensorTest.java \
+    src/android/hardware/cts/SensorManagerStaticTest.java
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil
 
@@ -49,11 +53,10 @@
 
 LOCAL_PACKAGE_NAME := CtsHardwareTestCases
 
-# uncomment when b/13281332 is fixed
-# please also uncomment the equivalent code in
-# cts/apps/CtsVerifiers/Android.mk
-#
-# LOCAL_SDK_VERSION := current
+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 ab81162..031b19e 100644
--- a/tests/tests/hardware/AndroidManifest.xml
+++ b/tests/tests/hardware/AndroidManifest.xml
@@ -25,6 +25,8 @@
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.BODY_SENSORS" />
     <uses-permission android:name="android.permission.TRANSMIT_IR" />
+    <uses-permission android:name="android.permission.REORDER_TASKS" />
+    <uses-permission android:name="android.permission.USE_FINGERPRINT" />
 
     <application>
         <uses-library android:name="android.test.runner" />
@@ -50,6 +52,30 @@
         <activity android:name="android.hardware.cts.GLSurfaceViewCtsActivity"
             android:label="GLSurfaceViewCtsActivity"/>
 
+        <service android:name="android.hardware.multiprocess.ErrorLoggingService"
+            android:label="ErrorLoggingService"
+            android:process=":errorLoggingServiceProcess"
+            android:exported="false">
+        </service>
+
+        <activity android:name="android.hardware.multiprocess.camera.cts.Camera1Activity"
+            android:label="RemoteCamera1Activity"
+            android:screenOrientation="landscape"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:process=":camera1ActivityProcess">
+        </activity>
+
+        <activity android:name="android.hardware.multiprocess.camera.cts.Camera2Activity"
+            android:label="RemoteCamera2Activity"
+            android:screenOrientation="landscape"
+            android:configChanges="keyboardHidden|orientation|screenSize"
+            android:process=":camera2ActivityProcess">
+        </activity>
+
+        <activity android:name="android.hardware.cts.FingerprintTestActivity"
+            android:label="FingerprintTestActivity">
+        </activity>
+
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/hardware/AndroidTest.xml b/tests/tests/hardware/AndroidTest.xml
new file mode 100644
index 0000000..4ddf28c
--- /dev/null
+++ b/tests/tests/hardware/AndroidTest.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/src/android/hardware/camera2/cts/AllocationTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
deleted file mode 100644
index d4fb235..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/AllocationTest.java
+++ /dev/null
@@ -1,860 +0,0 @@
-/*
- * Copyright 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.hardware.camera2.cts;
-
-import static android.graphics.ImageFormat.YUV_420_888;
-import static android.hardware.camera2.cts.helpers.Preconditions.*;
-import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static com.android.ex.camera2.blocking.BlockingStateCallback.*;
-
-import android.content.Context;
-import android.graphics.ImageFormat;
-import android.graphics.RectF;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.params.ColorSpaceTransform;
-import android.hardware.camera2.params.RggbChannelVector;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.util.Size;
-import android.hardware.camera2.cts.helpers.MaybeNull;
-import android.hardware.camera2.cts.helpers.StaticMetadata;
-import android.hardware.camera2.cts.rs.RenderScriptSingleton;
-import android.hardware.camera2.cts.rs.ScriptGraph;
-import android.hardware.camera2.cts.rs.ScriptYuvCrop;
-import android.hardware.camera2.cts.rs.ScriptYuvMeans1d;
-import android.hardware.camera2.cts.rs.ScriptYuvMeans2dTo1d;
-import android.hardware.camera2.cts.rs.ScriptYuvToRgb;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.renderscript.Allocation;
-import android.renderscript.Script.LaunchOptions;
-import android.test.AndroidTestCase;
-import android.util.Log;
-import android.util.Rational;
-import android.view.Surface;
-
-import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * Suite of tests for camera2 -> RenderScript APIs.
- *
- * <p>It uses CameraDevice as producer, camera sends the data to the surface provided by
- * Allocation. Only the below format is tested:</p>
- *
- * <p>YUV_420_888: flexible YUV420, it is a mandatory format for camera.</p>
- */
-public class AllocationTest extends AndroidTestCase {
-    private static final String TAG = "AllocationTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-
-    private CameraManager mCameraManager;
-    private CameraDevice mCamera;
-    private CameraCaptureSession mSession;
-    private BlockingStateCallback mCameraListener;
-    private BlockingSessionCallback mSessionListener;
-
-    private String[] mCameraIds;
-
-    private Handler mHandler;
-    private HandlerThread mHandlerThread;
-
-    private CameraIterable mCameraIterable;
-    private SizeIterable mSizeIterable;
-    private ResultIterable mResultIterable;
-
-    @Override
-    public synchronized void setContext(Context context) {
-        super.setContext(context);
-        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
-        assertNotNull("Can't connect to camera manager!", mCameraManager);
-
-        RenderScriptSingleton.setContext(context);
-        // TODO: call clearContext
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mCameraIds = mCameraManager.getCameraIdList();
-        mHandlerThread = new HandlerThread("AllocationTest");
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-        mCameraListener = new BlockingStateCallback();
-
-        mCameraIterable = new CameraIterable();
-        mSizeIterable = new SizeIterable();
-        mResultIterable = new ResultIterable();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        MaybeNull.close(mCamera);
-
-        // TODO: Clean up RenderScript context in a static test run finished method.
-        // Or alternatively count the # of test methods that are in this test,
-        // once we reach that count, it's time to call the last tear down
-
-        mHandlerThread.quitSafely();
-        mHandler = null;
-        super.tearDown();
-    }
-
-    /**
-     * Update the request with a default manual request template.
-     *
-     * @param request A builder for a CaptureRequest
-     * @param sensitivity ISO gain units (e.g. 100)
-     * @param expTimeNs Exposure time in nanoseconds
-     */
-    private static void setManualCaptureRequest(CaptureRequest.Builder request, int sensitivity,
-            long expTimeNs) {
-        final Rational ONE = new Rational(1, 1);
-        final Rational ZERO = new Rational(0, 1);
-
-        if (VERBOSE) {
-            Log.v(TAG, String.format("Create manual capture request, sensitivity = %d, expTime = %f",
-                    sensitivity, expTimeNs / (1000.0 * 1000)));
-        }
-
-        request.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
-        request.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
-        request.set(CaptureRequest.CONTROL_AWB_MODE, CaptureRequest.CONTROL_AWB_MODE_OFF);
-        request.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
-        request.set(CaptureRequest.CONTROL_EFFECT_MODE, CaptureRequest.CONTROL_EFFECT_MODE_OFF);
-        request.set(CaptureRequest.SENSOR_FRAME_DURATION, 0L);
-        request.set(CaptureRequest.SENSOR_SENSITIVITY, sensitivity);
-        request.set(CaptureRequest.SENSOR_EXPOSURE_TIME, expTimeNs);
-        request.set(CaptureRequest.COLOR_CORRECTION_MODE,
-                CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
-
-        // Identity transform
-        request.set(CaptureRequest.COLOR_CORRECTION_TRANSFORM,
-            new ColorSpaceTransform(new Rational[] {
-                ONE, ZERO, ZERO,
-                ZERO, ONE, ZERO,
-                ZERO, ZERO, ONE
-            }));
-
-        // Identity gains
-        request.set(CaptureRequest.COLOR_CORRECTION_GAINS,
-                new RggbChannelVector(1.0f, 1.0f, 1.0f, 1.0f ));
-        request.set(CaptureRequest.TONEMAP_MODE, CaptureRequest.TONEMAP_MODE_FAST);
-    }
-
-    /**
-     * Calculate the absolute crop window from a {@link Size},
-     * and configure {@link LaunchOptions} for it.
-     */
-    // TODO: split patch crop window and the application against a particular size into 2 classes
-    public static class Patch {
-        /**
-         * Create a new {@link Patch} from relative crop coordinates.
-         *
-         * <p>All float values must be normalized coordinates between [0, 1].</p>
-         *
-         * @param size Size of the original rectangle that is being cropped.
-         * @param xNorm The X coordinate defining the left side of the rectangle (in [0, 1]).
-         * @param yNorm The Y coordinate defining the top side of the rectangle (in [0, 1]).
-         * @param wNorm The width of the crop rectangle (normalized between [0, 1]).
-         * @param hNorm The height of the crop rectangle (normalized between [0, 1]).
-         *
-         * @throws NullPointerException if size was {@code null}.
-         * @throws AssertionError if any of the normalized coordinates were out of range
-         */
-        public Patch(Size size, float xNorm, float yNorm, float wNorm, float hNorm) {
-            checkNotNull("size", size);
-
-            assertInRange(xNorm, 0.0f, 1.0f);
-            assertInRange(yNorm, 0.0f, 1.0f);
-            assertInRange(wNorm, 0.0f, 1.0f);
-            assertInRange(hNorm, 0.0f, 1.0f);
-
-            wFull = size.getWidth();
-            hFull = size.getWidth();
-
-            xTile = (int)Math.ceil(xNorm * wFull);
-            yTile = (int)Math.ceil(yNorm * hFull);
-
-            wTile = (int)Math.ceil(wNorm * wFull);
-            hTile = (int)Math.ceil(hNorm * hFull);
-
-            mSourceSize = size;
-        }
-
-        /**
-         * Get the original size used to create this {@link Patch}.
-         *
-         * @return source size
-         */
-        public Size getSourceSize() {
-            return mSourceSize;
-        }
-
-        /**
-         * Get the cropped size after applying the normalized crop window.
-         *
-         * @return cropped size
-         */
-        public Size getSize() {
-            return new Size(wFull, hFull);
-        }
-
-        /**
-         * Get the {@link LaunchOptions} that can be used with a {@link android.renderscript.Script}
-         * to apply a kernel over a subset of an {@link Allocation}.
-         *
-         * @return launch options
-         */
-        public LaunchOptions getLaunchOptions() {
-            return (new LaunchOptions())
-                    .setX(xTile, xTile + wTile)
-                    .setY(yTile, yTile + hTile);
-        }
-
-        /**
-         * Get the cropped width after applying the normalized crop window.
-         *
-         * @return cropped width
-         */
-        public int getWidth() {
-            return wTile;
-        }
-
-        /**
-         * Get the cropped height after applying the normalized crop window.
-         *
-         * @return cropped height
-         */
-        public int getHeight() {
-            return hTile;
-        }
-
-        /**
-         * Convert to a {@link RectF} where each corner is represented by a
-         * normalized coordinate in between [0.0, 1.0] inclusive.
-         *
-         * @return a new rectangle
-         */
-        public RectF toRectF() {
-            return new RectF(
-                    xTile * 1.0f / wFull,
-                    yTile * 1.0f / hFull,
-                    (xTile + wTile) * 1.0f / wFull,
-                    (yTile + hTile) * 1.0f / hFull);
-        }
-
-        private final Size mSourceSize;
-        private final int wFull;
-        private final int hFull;
-        private final int xTile;
-        private final int yTile;
-        private final int wTile;
-        private final int hTile;
-    }
-
-    /**
-     * Convert a single YUV pixel (3 byte elements) to an RGB pixel.
-     *
-     * <p>The color channels must be in the following order:
-     * <ul><li>Y - 0th channel
-     * <li>U - 1st channel
-     * <li>V - 2nd channel
-     * </ul></p>
-     *
-     * <p>Each channel has data in the range 0-255.</p>
-     *
-     * <p>Output data is a 3-element pixel with each channel in the range of [0,1].
-     * Each channel is saturated to avoid over/underflow.</p>
-     *
-     * <p>The conversion is done using JFIF File Interchange Format's "Conversion to and from RGB":
-     * <ul>
-     * <li>R = Y + 1.042 (Cr - 128)
-     * <li>G = Y - 0.34414 (Cb - 128) - 0.71414 (Cr - 128)
-     * <li>B = Y + 1.772 (Cb - 128)
-     * </ul>
-     *
-     * Where Cr and Cb are aliases of V and U respectively.
-     * </p>
-     *
-     * @param yuvData An array of a YUV pixel (at least 3 bytes large)
-     *
-     * @return an RGB888 pixel with each channel in the range of [0,1]
-     */
-    private static float[] convertPixelYuvToRgb(byte[] yuvData) {
-        final int CHANNELS = 3; // yuv
-        final float COLOR_RANGE = 255f;
-
-        assertTrue("YUV pixel must be at least 3 bytes large", CHANNELS <= yuvData.length);
-
-        float[] rgb = new float[CHANNELS];
-
-        float y = yuvData[0] & 0xFF;  // Y channel
-        float cb = yuvData[1] & 0xFF; // U channel
-        float cr = yuvData[2] & 0xFF; // V channel
-
-        // convert YUV -> RGB (from JFIF's "Conversion to and from RGB" section)
-        float r = y + 1.402f * (cr - 128);
-        float g = y - 0.34414f * (cb - 128) - 0.71414f * (cr - 128);
-        float b = y + 1.772f * (cb - 128);
-
-        // normalize [0,255] -> [0,1]
-        rgb[0] = r / COLOR_RANGE;
-        rgb[1] = g / COLOR_RANGE;
-        rgb[2] = b / COLOR_RANGE;
-
-        // Clamp to range [0,1]
-        for (int i = 0; i < CHANNELS; ++i) {
-            rgb[i] = Math.max(0.0f, Math.min(1.0f, rgb[i]));
-        }
-
-        if (VERBOSE) {
-            Log.v(TAG, String.format("RGB calculated (r,g,b) = (%f, %f, %f)", rgb[0], rgb[1],
-                    rgb[2]));
-        }
-
-        return rgb;
-    }
-
-    /**
-     * Configure the camera with the target surface;
-     * create a capture request builder with {@code cameraTarget} as the sole surface target.
-     *
-     * <p>Outputs are configured with the new surface targets, and this function blocks until
-     * the camera has finished configuring.</p>
-     *
-     * <p>The capture request is created from the {@link CameraDevice#TEMPLATE_PREVIEW} template.
-     * No other keys are set.
-     * </p>
-     */
-    private CaptureRequest.Builder configureAndCreateRequestForSurface(Surface cameraTarget)
-            throws CameraAccessException {
-        List<Surface> outputSurfaces = new ArrayList<Surface>(/*capacity*/1);
-        assertNotNull("Failed to get Surface", cameraTarget);
-        outputSurfaces.add(cameraTarget);
-
-        mSessionListener = new BlockingSessionCallback();
-        mCamera.createCaptureSession(outputSurfaces, mSessionListener, mHandler);
-        mSession = mSessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
-        CaptureRequest.Builder captureBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        assertNotNull("Fail to create captureRequest", captureBuilder);
-        captureBuilder.addTarget(cameraTarget);
-
-        if (VERBOSE) Log.v(TAG, "configureAndCreateRequestForSurface - done");
-
-        return captureBuilder;
-    }
-
-    /**
-     * Submit a single request to the camera, block until the buffer is available.
-     *
-     * <p>Upon return from this function, script has been executed against the latest buffer.
-     * </p>
-     */
-    private void captureSingleShotAndExecute(CaptureRequest request, ScriptGraph graph)
-            throws CameraAccessException {
-        checkNotNull("request", request);
-        checkNotNull("graph", graph);
-
-        mSession.capture(request, new CameraCaptureSession.CaptureCallback() {
-            @Override
-            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
-                    TotalCaptureResult result) {
-                if (VERBOSE) Log.v(TAG, "Capture completed");
-            }
-        }, mHandler);
-
-        if (VERBOSE) Log.v(TAG, "Waiting for single shot buffer");
-        graph.advanceInputWaiting();
-        if (VERBOSE) Log.v(TAG, "Got the buffer");
-        graph.execute();
-    }
-
-    private void stopCapture() throws CameraAccessException {
-        if (VERBOSE) Log.v(TAG, "Stopping capture and waiting for idle");
-        // Stop repeat, wait for captures to complete, and disconnect from surfaces
-        mSession.close();
-        mSessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_CLOSED,
-                SESSION_CLOSE_TIMEOUT_MS);
-        mSession = null;
-        mSessionListener = null;
-    }
-
-    /**
-     * Extremely dumb validator. Makes sure there is at least one non-zero RGB pixel value.
-     */
-    private void validateInputOutputNotZeroes(ScriptGraph scriptGraph, Size size) {
-        final int BPP = 8; // bits per pixel
-
-        int width = size.getWidth();
-        int height = size.getHeight();
-        /**
-         * Check the input allocation is sane.
-         * - Byte size matches what we expect.
-         * - The input is not all zeroes.
-         */
-
-        // Check that input data was updated first. If it wasn't, the rest of the test will fail.
-        byte[] data = scriptGraph.getInputData();
-        assertArrayNotAllZeroes("Input allocation data was not updated", data);
-
-        // Minimal required size to represent YUV 4:2:0 image
-        int packedSize =
-                width * height * ImageFormat.getBitsPerPixel(YUV_420_888) / BPP;
-        if (VERBOSE) Log.v(TAG, "Expected image size = " + packedSize);
-        int actualSize = data.length;
-        // Actual size may be larger due to strides or planes being non-contiguous
-        assertTrue(
-                String.format(
-                        "YUV 420 packed size (%d) should be at least as large as the actual size " +
-                        "(%d)", packedSize, actualSize), packedSize <= actualSize);
-        /**
-         * Check the output allocation by converting to RGBA.
-         * - Byte size matches what we expect
-         * - The output is not all zeroes
-         */
-        final int RGBA_CHANNELS = 4;
-
-        int actualSizeOut = scriptGraph.getOutputAllocation().getBytesSize();
-        int packedSizeOut = width * height * RGBA_CHANNELS;
-
-        byte[] dataOut = scriptGraph.getOutputData();
-        assertEquals("RGB mismatched byte[] and expected size",
-                packedSizeOut, dataOut.length);
-
-        if (VERBOSE) {
-            Log.v(TAG, "checkAllocationByConvertingToRgba - RGB data size " + dataOut.length);
-        }
-
-        assertArrayNotAllZeroes("RGBA data was not updated", dataOut);
-        // RGBA8888 stride should be equal to the width
-        assertEquals("RGBA 8888 mismatched byte[] and expected size", packedSizeOut, actualSizeOut);
-
-        if (VERBOSE) Log.v(TAG, "validating Buffer , size = " + actualSize);
-    }
-
-    public void testAllocationFromCameraFlexibleYuv() throws Exception {
-
-        /** number of frame (for streaming requests) to be verified. */
-        final int NUM_FRAME_VERIFIED = 1;
-
-        mCameraIterable.forEachCamera(new CameraBlock() {
-            @Override
-            public void run(CameraDevice camera) throws CameraAccessException {
-
-                // Iterate over each size in the camera
-                mSizeIterable.forEachSize(YUV_420_888, new SizeBlock() {
-                    @Override
-                    public void run(final Size size) throws CameraAccessException {
-                        // Create a script graph that converts YUV to RGB
-                        final ScriptGraph scriptGraph = ScriptGraph.create()
-                                .configureInputWithSurface(size, YUV_420_888)
-                                .chainScript(ScriptYuvToRgb.class)
-                                .buildGraph();
-
-                        if (VERBOSE) Log.v(TAG, "Prepared ScriptYuvToRgb for size " + size);
-
-                        // Run the graph against camera input and validate we get some input
-                        try {
-                            CaptureRequest request =
-                                    configureAndCreateRequestForSurface(scriptGraph.getInputSurface()).build();
-
-                            // Block until we get 1 result, then iterate over the result
-                            mResultIterable.forEachResultRepeating(
-                                    request, NUM_FRAME_VERIFIED, new ResultBlock() {
-                                @Override
-                                public void run(CaptureResult result) throws CameraAccessException {
-                                    scriptGraph.advanceInputWaiting();
-                                    scriptGraph.execute();
-                                    validateInputOutputNotZeroes(scriptGraph, size);
-                                    scriptGraph.advanceInputAndDrop();
-                                }
-                            });
-
-                            stopCapture();
-                        } finally {
-                            scriptGraph.close();
-                        }
-                    }
-                });
-            }
-        });
-    }
-
-    /**
-     * Take two shots and ensure per-frame-control with exposure/gain is working correctly.
-     *
-     * <p>Takes a shot with very low ISO and exposure time. Expect it to be black.</p>
-     *
-     * <p>Take a shot with very high ISO and exposure time. Expect it to be white.</p>
-     *
-     * @throws Exception
-     */
-    public void testBlackWhite() throws CameraAccessException {
-
-        /** low iso + low exposure (first shot) */
-        final float THRESHOLD_LOW = 0.025f;
-        /** high iso + high exposure (second shot) */
-        final float THRESHOLD_HIGH = 0.975f;
-
-        mCameraIterable.forEachCamera(/*fullHwLevel*/false, new CameraBlock() {
-            @Override
-            public void run(CameraDevice camera) throws CameraAccessException {
-                final StaticMetadata staticInfo =
-                        new StaticMetadata(mCameraManager.getCameraCharacteristics(camera.getId()));
-
-                // This test requires PFC and manual sensor control
-                if (!staticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR) ||
-                        !staticInfo.isPerFrameControlSupported()) {
-                    return;
-                }
-
-                final Size maxSize = getMaxSize(
-                        getSupportedSizeForFormat(YUV_420_888, camera.getId(), mCameraManager));
-
-                ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize);
-
-                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);
-
-                CaptureRequest lowIsoExposureShot = req.build();
-                captureSingleShotAndExecute(lowIsoExposureShot, scriptGraph);
-
-                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);
-
-                CaptureRequest highIsoExposureShot = req.build();
-                captureSingleShotAndExecute(highIsoExposureShot, scriptGraph);
-
-                float[] whiteMeans = convertPixelYuvToRgb(scriptGraph.getOutputData());
-
-                // 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);
-            }
-        });
-    }
-
-    /**
-     * Test that the android.sensitivity.parameter is applied.
-     */
-    public void testParamSensitivity() throws CameraAccessException {
-        final float THRESHOLD_MAX_MIN_DIFF = 0.3f;
-        final float THRESHOLD_MAX_MIN_RATIO = 2.0f;
-        final int NUM_STEPS = 5;
-        final long EXPOSURE_TIME_NS = 2000000; // 2 seconds
-        final int RGB_CHANNELS = 3;
-
-        mCameraIterable.forEachCamera(/*fullHwLevel*/false, new CameraBlock() {
-
-
-            @Override
-            public void run(CameraDevice camera) throws CameraAccessException {
-                final StaticMetadata staticInfo =
-                        new StaticMetadata(mCameraManager.getCameraCharacteristics(camera.getId()));
-                // This test requires PFC and manual sensor control
-                if (!staticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR) ||
-                        !staticInfo.isPerFrameControlSupported()) {
-                    return;
-                }
-
-                final List<float[]> rgbMeans = new ArrayList<float[]>();
-                final Size maxSize = getMaxSize(
-                        getSupportedSizeForFormat(YUV_420_888, camera.getId(), mCameraManager));
-
-                final int sensitivityMin = staticInfo.getSensitivityMinimumOrDefault();
-                final int sensitivityMax = staticInfo.getSensitivityMaximumOrDefault();
-
-                // List each sensitivity from min-max in NUM_STEPS increments
-                int[] sensitivities = new int[NUM_STEPS];
-                for (int i = 0; i < NUM_STEPS; ++i) {
-                    int delta = (sensitivityMax - sensitivityMin) / (NUM_STEPS - 1);
-                    sensitivities[i] = sensitivityMin + delta * i;
-                }
-
-                ScriptGraph scriptGraph = createGraphForYuvCroppedMeans(maxSize);
-
-                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);
-
-                    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);
-
-                    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);
-                }
-            }
-        });
-
-    }
-
-    /**
-     * Common script graph for manual-capture based tests that determine the average pixel
-     * values of a cropped sub-region.
-     *
-     * <p>Processing chain:
-     *
-     * <pre>
-     * input:  YUV_420_888 surface
-     * output: mean YUV value of a central section of the image,
-     *         YUV 4:4:4 encoded as U8_3
-     * steps:
-     *      1) crop [0.45,0.45] - [0.55, 0.55]
-     *      2) average columns
-     *      3) average rows
-     * </pre>
-     * </p>
-     */
-    private static ScriptGraph createGraphForYuvCroppedMeans(final Size size) {
-        ScriptGraph scriptGraph = ScriptGraph.create()
-                .configureInputWithSurface(size, YUV_420_888)
-                .configureScript(ScriptYuvCrop.class)
-                    .set(ScriptYuvCrop.CROP_WINDOW,
-                            new Patch(size, /*x*/0.45f, /*y*/0.45f, /*w*/0.1f, /*h*/0.1f).toRectF())
-                    .buildScript()
-                .chainScript(ScriptYuvMeans2dTo1d.class)
-                .chainScript(ScriptYuvMeans1d.class)
-                // TODO: Make a script for YUV 444 -> RGB 888 conversion
-                .buildGraph();
-        return scriptGraph;
-    }
-
-    /*
-     * TODO: Refactor below code into separate classes and to not depend on AllocationTest
-     * inner variables.
-     *
-     * TODO: add javadocs to below methods
-     *
-     * TODO: Figure out if there's some elegant way to compose these forEaches together, so that
-     * the callers don't have to do a ton of nesting
-     */
-
-    interface CameraBlock {
-        void run(CameraDevice camera) throws CameraAccessException;
-    }
-
-    class CameraIterable {
-        public void forEachCamera(CameraBlock runnable)
-                throws CameraAccessException {
-            forEachCamera(/*fullHwLevel*/false, runnable);
-        }
-
-        public void forEachCamera(boolean fullHwLevel, CameraBlock runnable)
-                throws CameraAccessException {
-            assertNotNull("No camera manager", mCameraManager);
-            assertNotNull("No camera IDs", mCameraIds);
-
-            for (int i = 0; i < mCameraIds.length; i++) {
-                // Don't execute the runnable against non-FULL cameras if FULL is required
-                CameraCharacteristics properties =
-                        mCameraManager.getCameraCharacteristics(mCameraIds[i]);
-                StaticMetadata staticInfo = new StaticMetadata(properties);
-                if (fullHwLevel && !staticInfo.isHardwareLevelFull()) {
-                    Log.i(TAG, String.format(
-                            "Skipping this test for camera %s, needs FULL hw level",
-                            mCameraIds[i]));
-                    continue;
-                }
-
-                // Open camera and execute test
-                Log.i(TAG, "Testing Camera " + mCameraIds[i]);
-                try {
-                    openDevice(mCameraIds[i]);
-
-                    runnable.run(mCamera);
-                } finally {
-                    closeDevice(mCameraIds[i]);
-                }
-            }
-        }
-
-        private void openDevice(String cameraId) {
-            if (mCamera != null) {
-                throw new IllegalStateException("Already have open camera device");
-            }
-            try {
-                mCamera = openCamera(
-                    mCameraManager, cameraId, mCameraListener, mHandler);
-            } catch (CameraAccessException e) {
-                fail("Fail to open camera synchronously, " + Log.getStackTraceString(e));
-            } catch (BlockingOpenException e) {
-                fail("Fail to open camera asynchronously, " + Log.getStackTraceString(e));
-            }
-            mCameraListener.waitForState(STATE_OPENED, CAMERA_OPEN_TIMEOUT_MS);
-        }
-
-        private void closeDevice(String cameraId) {
-            if (mCamera != null) {
-                mCamera.close();
-                mCameraListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
-                mCamera = null;
-            }
-        }
-    }
-
-    interface SizeBlock {
-        void run(Size size) throws CameraAccessException;
-    }
-
-    class SizeIterable {
-        public void forEachSize(int format, SizeBlock runnable) throws CameraAccessException {
-            assertNotNull("No camera opened", mCamera);
-            assertNotNull("No camera manager", mCameraManager);
-
-            CameraCharacteristics properties =
-                    mCameraManager.getCameraCharacteristics(mCamera.getId());
-
-            assertNotNull("Can't get camera properties!", properties);
-
-            StreamConfigurationMap config =
-                    properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-            int[] availableOutputFormats = config.getOutputFormats();
-            assertArrayNotEmpty(availableOutputFormats,
-                    "availableOutputFormats should not be empty");
-            Arrays.sort(availableOutputFormats);
-            assertTrue("Can't find the format " + format + " in supported formats " +
-                    Arrays.toString(availableOutputFormats),
-                    Arrays.binarySearch(availableOutputFormats, format) >= 0);
-
-            Size[] availableSizes = getSupportedSizeForFormat(format, mCamera.getId(),
-                    mCameraManager);
-            assertArrayNotEmpty(availableSizes, "availableSizes should not be empty");
-
-            for (Size size : availableSizes) {
-
-                if (VERBOSE) {
-                    Log.v(TAG, "Testing size " + size.toString() +
-                            " for camera " + mCamera.getId());
-                }
-                runnable.run(size);
-            }
-        }
-    }
-
-    interface ResultBlock {
-        void run(CaptureResult result) throws CameraAccessException;
-    }
-
-    class ResultIterable {
-        public void forEachResultOnce(CaptureRequest request, ResultBlock block)
-                throws CameraAccessException {
-            forEachResult(request, /*count*/1, /*repeating*/false, block);
-        }
-
-        public void forEachResultRepeating(CaptureRequest request, int count, ResultBlock block)
-                throws CameraAccessException {
-            forEachResult(request, count, /*repeating*/true, block);
-        }
-
-        public void forEachResult(CaptureRequest request, int count, boolean repeating,
-                ResultBlock block) throws CameraAccessException {
-
-            // TODO: start capture, i.e. configureOutputs
-
-            SimpleCaptureCallback listener = new SimpleCaptureCallback();
-
-            if (!repeating) {
-                for (int i = 0; i < count; ++i) {
-                    mSession.capture(request, listener, mHandler);
-                }
-            } else {
-                mSession.setRepeatingRequest(request, listener, mHandler);
-            }
-
-            // Assume that the device is already IDLE.
-            mSessionListener.getStateWaiter().waitForState(BlockingSessionCallback.SESSION_ACTIVE,
-                    CAMERA_ACTIVE_TIMEOUT_MS);
-
-            for (int i = 0; i < count; ++i) {
-                if (VERBOSE) {
-                    Log.v(TAG, String.format("Testing with result %d of %d for camera %s",
-                            i, count, mCamera.getId()));
-                }
-
-                CaptureResult result = listener.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
-                block.run(result);
-            }
-
-            if (repeating) {
-                mSession.stopRepeating();
-                mSessionListener.getStateWaiter().waitForState(
-                    BlockingSessionCallback.SESSION_READY, CAMERA_IDLE_TIMEOUT_MS);
-            }
-
-            // TODO: Make a Configure decorator or some such for configureOutputs
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/BurstCaptureTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/BurstCaptureTest.java
deleted file mode 100644
index 5d0841e..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/BurstCaptureTest.java
+++ /dev/null
@@ -1,353 +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.hardware.camera2.cts;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-
-import android.graphics.ImageFormat;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.util.Log;
-import android.util.Range;
-import android.util.Size;
-
-import java.util.List;
-import java.util.ArrayList;
-
-public class BurstCaptureTest extends Camera2SurfaceViewTestCase {
-    private static final String TAG = "BurstCaptureTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    /**
-     * Test YUV burst capture with full-AUTO control.
-     * Also verifies sensor settings operation if READ_SENSOR_SETTINGS is available.
-     */
-    public void testYuvBurst() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                String id = mCameraIds[i];
-                Log.i(TAG, "Testing YUV Burst for camera " + id);
-                openDevice(id);
-
-                if (mStaticInfo.isHardwareLevelLegacy()) {
-                    Log.i(TAG, "Skip burst test on legacy devices.");
-                    continue;
-                }
-
-                yuvBurstTestByCamera(id);
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    private void yuvBurstTestByCamera(String cameraId) throws Exception {
-        // Parameters
-        final int MAX_CONVERGENCE_FRAMES = 150; // 5 sec at 30fps
-        final long MAX_PREVIEW_RESULT_TIMEOUT_MS = 1000;
-        final int BURST_SIZE = 100;
-        final float FRAME_DURATION_MARGIN_FRACTION = 0.1f;
-
-        // Find a good preview size (bound to 1080p)
-        final Size previewSize = mOrderedPreviewSizes.get(0);
-
-        // Get maximum YUV_420_888 size
-        final Size stillSize = getMaxPreviewSize(cameraId, mCameraManager);
-
-        // Find max pipeline depth and sync latency
-        final int maxPipelineDepth = mStaticInfo.getCharacteristics().get(
-            CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH);
-        final int maxSyncLatency = mStaticInfo.getCharacteristics().get(
-            CameraCharacteristics.SYNC_MAX_LATENCY);
-
-        // Find minimum frame duration for full-res YUV_420_888
-        StreamConfigurationMap config = mStaticInfo.getCharacteristics().get(
-            CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-        final long minStillFrameDuration =
-                config.getOutputMinFrameDuration(ImageFormat.YUV_420_888, stillSize);
-
-        // Find suitable target FPS range - as high as possible
-        Range<Integer>[] fpsRanges = mStaticInfo.getAeAvailableTargetFpsRangesChecked();
-        int minBurstFps = (int) Math.floor(1e9 / minStillFrameDuration);
-        Range<Integer> targetRange = null;
-        for (Range<Integer> candidateRange : fpsRanges) {
-            if (candidateRange.getLower() >= minBurstFps) {
-                if (targetRange == null) {
-                    targetRange = candidateRange;
-                } else if (candidateRange.getLower() > targetRange.getLower()) {
-                    targetRange = candidateRange;
-                } else if (candidateRange.getUpper() > targetRange.getUpper()) {
-                    targetRange = candidateRange;
-                }
-            }
-        }
-        assertTrue(String.format("Cam %s: No target FPS range found with minimum FPS above " +
-                        " 1/minFrameDuration (%d fps, duration %d ns) for full-resolution YUV",
-                cameraId, minBurstFps, minStillFrameDuration),
-            targetRange != null);
-
-        Log.i(TAG, String.format("Selected frame rate range %d - %d for YUV burst",
-                        targetRange.getLower(), targetRange.getUpper()));
-
-        // Check if READ_SENSOR_SETTINGS is supported
-        final boolean checkSensorSettings = mStaticInfo.isCapabilitySupported(
-            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS);
-
-        // Configure basic preview and burst settings
-
-        CaptureRequest.Builder previewBuilder =
-            mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        CaptureRequest.Builder burstBuilder =
-            mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-        previewBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
-                targetRange);
-        burstBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE,
-                targetRange);
-        burstBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
-        burstBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
-
-        // Create session and start up preview
-
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        ImageDropperListener imageDropper = new ImageDropperListener();
-
-        prepareCaptureAndStartPreview(
-            previewBuilder, burstBuilder,
-            previewSize, stillSize,
-            ImageFormat.YUV_420_888, resultListener,
-            /*maxNumImages*/ 3, imageDropper);
-
-        // Create burst
-
-        List<CaptureRequest> burst = new ArrayList<>();
-        for (int i = 0; i < BURST_SIZE; i++) {
-            burst.add(burstBuilder.build());
-        }
-
-        // Converge AE/AWB
-
-        int frameCount = 0;
-        while (true) {
-            CaptureResult result = resultListener.getCaptureResult(MAX_PREVIEW_RESULT_TIMEOUT_MS);
-            int aeState = result.get(CaptureResult.CONTROL_AE_STATE);
-            int awbState = result.get(CaptureResult.CONTROL_AWB_STATE);
-
-            if (DEBUG) {
-                Log.d(TAG, "aeState: " + aeState + ". awbState: " + awbState);
-            }
-
-            if ((aeState == CaptureResult.CONTROL_AE_STATE_CONVERGED ||
-                    aeState == CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED) &&
-                    awbState == CaptureResult.CONTROL_AWB_STATE_CONVERGED) {
-                break;
-            }
-            frameCount++;
-            assertTrue(String.format("Cam %s: Can not converge AE and AWB within %d frames",
-                    cameraId, MAX_CONVERGENCE_FRAMES),
-                frameCount < MAX_CONVERGENCE_FRAMES);
-        }
-
-        // Lock AF if there's a focuser
-
-        if (mStaticInfo.hasFocuser()) {
-            previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
-                CaptureRequest.CONTROL_AF_TRIGGER_START);
-            mSession.capture(previewBuilder.build(), resultListener, mHandler);
-            previewBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER,
-                CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
-
-            frameCount = 0;
-            while (true) {
-                CaptureResult result = resultListener.getCaptureResult(MAX_PREVIEW_RESULT_TIMEOUT_MS);
-                int afState = result.get(CaptureResult.CONTROL_AF_STATE);
-
-                if (DEBUG) {
-                    Log.d(TAG, "afState: " + afState);
-                }
-
-                if (afState == CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED ||
-                    afState == CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED) {
-                    break;
-                }
-                frameCount++;
-                assertTrue(String.format("Cam %s: Cannot lock AF within %d frames", cameraId,
-                        MAX_CONVERGENCE_FRAMES),
-                    frameCount < MAX_CONVERGENCE_FRAMES);
-            }
-        }
-
-        // Lock AE/AWB
-
-        previewBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
-        previewBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
-
-        CaptureRequest lockedRequest = previewBuilder.build();
-        mSession.setRepeatingRequest(lockedRequest, resultListener, mHandler);
-
-        // Wait for first result with locking
-
-        CaptureResult lockedResult =
-                resultListener.getCaptureResultForRequest(lockedRequest, maxPipelineDepth);
-
-        int pipelineDepth = lockedResult.get(CaptureResult.REQUEST_PIPELINE_DEPTH);
-
-        // Then start waiting on results to get the first result that should be synced
-        // up, and also fire the burst as soon as possible
-
-        if (maxSyncLatency == CameraCharacteristics.SYNC_MAX_LATENCY_PER_FRAME_CONTROL) {
-            // The locked result we have is already synchronized so start the burst
-            mSession.captureBurst(burst, resultListener, mHandler);
-        } else {
-            // Need to get a synchronized result, and may need to start burst later to
-            // be synchronized correctly
-
-            boolean burstSent = false;
-
-            // Calculate how many requests we need to still send down to camera before we
-            // know the settings have settled for the burst
-
-            int numFramesWaited = maxSyncLatency;
-            if (numFramesWaited == CameraCharacteristics.SYNC_MAX_LATENCY_UNKNOWN) {
-                numFramesWaited = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY;
-            }
-
-            int requestsNeededToSync = numFramesWaited - pipelineDepth;
-            for (int i = 0; i < numFramesWaited; i++) {
-                if (!burstSent && requestsNeededToSync <= 0) {
-                    mSession.captureBurst(burst, resultListener, mHandler);
-                    burstSent = true;
-                }
-                lockedResult = resultListener.getCaptureResult(MAX_PREVIEW_RESULT_TIMEOUT_MS);
-                requestsNeededToSync--;
-            }
-
-            assertTrue("Cam " + cameraId + ": Burst failed to fire!", burstSent);
-        }
-
-        // Read in locked settings if supported
-
-        long burstExposure = 0;
-        long burstFrameDuration = 0;
-        int burstSensitivity = 0;
-        if (checkSensorSettings) {
-            burstExposure = lockedResult.get(CaptureResult.SENSOR_EXPOSURE_TIME);
-            burstFrameDuration = lockedResult.get(CaptureResult.SENSOR_FRAME_DURATION);
-            burstSensitivity = lockedResult.get(CaptureResult.SENSOR_SENSITIVITY);
-
-            assertTrue(String.format("Cam %s: Frame duration %d ns too short compared to " +
-                    "exposure time %d ns", cameraId, burstFrameDuration, burstExposure),
-                burstFrameDuration >= burstExposure);
-
-            assertTrue(String.format("Cam %s: Exposure time is not valid: %d",
-                    cameraId, burstExposure),
-                burstExposure > 0);
-            assertTrue(String.format("Cam %s: Frame duration is not valid: %d",
-                    cameraId, burstFrameDuration),
-                burstFrameDuration > 0);
-            assertTrue(String.format("Cam %s: Sensitivity is not valid: %d",
-                    cameraId, burstSensitivity),
-                burstSensitivity > 0);
-        }
-
-        // Process burst results
-        int burstIndex = 0;
-        CaptureResult burstResult =
-                resultListener.getCaptureResultForRequest(burst.get(burstIndex),
-                    maxPipelineDepth + 1);
-        long prevTimestamp = -1;
-        final long frameDurationBound = (long)
-                (minStillFrameDuration * (1 + FRAME_DURATION_MARGIN_FRACTION) );
-
-        List<Long> frameDurations = new ArrayList<>();
-
-        while(true) {
-            // Verify the result
-            assertTrue("Cam " + cameraId + ": Result doesn't match expected request",
-                    burstResult.getRequest() == burst.get(burstIndex));
-
-            // Verify locked settings
-            if (checkSensorSettings) {
-                long exposure = burstResult.get(CaptureResult.SENSOR_EXPOSURE_TIME);
-                int sensitivity = burstResult.get(CaptureResult.SENSOR_SENSITIVITY);
-                assertTrue("Cam " + cameraId + ": Exposure not locked!",
-                    exposure == burstExposure);
-                assertTrue("Cam " + cameraId + ": Sensitivity not locked!",
-                    sensitivity == burstSensitivity);
-            }
-
-            // Collect inter-frame durations
-            long timestamp = burstResult.get(CaptureResult.SENSOR_TIMESTAMP);
-            if (prevTimestamp != -1) {
-                long frameDuration = timestamp - prevTimestamp;
-                frameDurations.add(frameDuration);
-                if (DEBUG) {
-                    Log.i(TAG, String.format("Frame %03d    Duration %.2f ms", burstIndex,
-                            frameDuration/1e6));
-                }
-            }
-            prevTimestamp = timestamp;
-
-            // Get next result
-            burstIndex++;
-            if (burstIndex == BURST_SIZE) break;
-            burstResult = resultListener.getCaptureResult(MAX_PREVIEW_RESULT_TIMEOUT_MS);
-        }
-
-        // Verify inter-frame durations
-
-        long meanFrameSum = 0;
-        for (Long duration : frameDurations) {
-            meanFrameSum += duration;
-        }
-        float meanFrameDuration = (float) meanFrameSum / frameDurations.size();
-
-        float stddevSum = 0;
-        for (Long duration : frameDurations) {
-            stddevSum += (duration - meanFrameDuration) * (duration - meanFrameDuration);
-        }
-        float stddevFrameDuration = (float)
-                Math.sqrt(1.f / (frameDurations.size() - 1 ) * stddevSum);
-
-        Log.i(TAG, String.format("Cam %s: Burst frame duration mean: %.1f, stddev: %.1f", cameraId,
-                meanFrameDuration, stddevFrameDuration));
-
-        assertTrue(
-            String.format("Cam %s: Burst frame duration mean %.1f ns is larger than acceptable, " +
-                "expecting below %d ns, allowing below %d", cameraId,
-                meanFrameDuration, minStillFrameDuration, frameDurationBound),
-            meanFrameDuration <= frameDurationBound);
-
-        // Calculate upper 97.5% bound (assuming durations are normally distributed...)
-        float limit95FrameDuration = meanFrameDuration + 2 * stddevFrameDuration;
-
-        // Don't enforce this yet, but warn
-        if (limit95FrameDuration > frameDurationBound) {
-            Log.w(TAG,
-                String.format("Cam %s: Standard deviation is too large compared to limit: " +
-                    "mean: %.1f ms, stddev: %.1f ms: 95%% bound: %f ms", cameraId,
-                    meanFrameDuration/1e6, stddevFrameDuration/1e6,
-                    limit95FrameDuration/1e6));
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2MultiViewCtsActivity.java b/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2MultiViewCtsActivity.java
deleted file mode 100644
index 16d2301..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2MultiViewCtsActivity.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright 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.hardware.camera2.cts;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.SurfaceView;
-import android.view.TextureView;
-import android.view.WindowManager;
-
-import com.android.cts.hardware.R;
-
-public class Camera2MultiViewCtsActivity extends Activity {
-    private final static String TAG = "Camera2MultiViewCtsActivity";
-    private TextureView[] mTextureView = new TextureView[2];
-    private SurfaceView[] mSurfaceView = new SurfaceView[2];
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.multi_view);
-        mTextureView[0] = (TextureView) findViewById(R.id.texture_view_1);
-        mTextureView[1] = (TextureView) findViewById(R.id.texture_view_2);
-        mSurfaceView[0] = (SurfaceView) findViewById(R.id.surface_view_1);
-        mSurfaceView[1] = (SurfaceView) findViewById(R.id.surface_view_2);
-
-        //Make sure screen is on when this activity window is visible to the user.
-        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
-    }
-
-    public TextureView getTextureView(int index) {
-        if (index < 0 || index > 1) {
-            throw new IllegalArgumentException("Texture view index must be 0 or 1");
-        }
-        return mTextureView[index];
-    }
-
-    public SurfaceView getSurfaceView(int index) {
-        if (index < 0 || index > 1) {
-            throw new IllegalArgumentException("Surface view index must be 0 or 1");
-        }
-        return mSurfaceView[index];
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java b/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
deleted file mode 100644
index 8a217fd..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/Camera2SurfaceViewCtsActivity.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright 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.hardware.camera2.cts;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.ConditionVariable;
-import android.os.SystemClock;
-import android.util.Log;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import com.android.cts.hardware.R;
-
-public class Camera2SurfaceViewCtsActivity extends Activity implements SurfaceHolder.Callback {
-    private final static String TAG = "Camera2SurfaceViewCtsActivity";
-    private final ConditionVariable surfaceChangedDone = new ConditionVariable();
-
-    private SurfaceView mSurfaceView;
-    private int currentWidth = 0;
-    private int currentHeight = 0;
-    private final Object sizeLock = new Object();
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(R.layout.surface_view_2);
-        mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
-        mSurfaceView.getHolder().addCallback(this);
-    }
-
-    public SurfaceView getSurfaceView() {
-        return mSurfaceView;
-    }
-
-    public boolean waitForSurfaceSizeChanged(int timeOutMs, int expectWidth, int expectHeight) {
-        if (timeOutMs <= 0 || expectWidth <= 0 || expectHeight <= 0) {
-            throw new IllegalArgumentException(
-                    String.format(
-                            "timeout(%d), expectWidth(%d), and expectHeight(%d) " +
-                            "should all be positive numbers",
-                            timeOutMs, expectWidth, expectHeight));
-        }
-
-        synchronized(sizeLock) {
-            if (expectWidth == currentWidth && expectHeight == currentHeight) {
-                return true;
-            }
-        }
-
-        int waitTimeMs = timeOutMs;
-        boolean changeSucceeded = false;
-        while (!changeSucceeded && waitTimeMs > 0) {
-            long startTimeMs = SystemClock.elapsedRealtime();
-            changeSucceeded = surfaceChangedDone.block(waitTimeMs);
-            if (!changeSucceeded) {
-                Log.e(TAG, "Wait for surface change timed out after " + timeOutMs + " ms");
-                return changeSucceeded;
-            } else {
-                // Get a surface change callback, need to check if the size is expected.
-                surfaceChangedDone.close();
-                if (currentWidth == expectWidth && currentHeight == expectHeight) {
-                    return changeSucceeded;
-                }
-                // Do a further iteration surface change check as surfaceChanged could be called
-                // again.
-                changeSucceeded = false;
-            }
-            waitTimeMs -= (SystemClock.elapsedRealtime() - startTimeMs);
-        }
-
-        // Couldn't get expected surface size change.
-        return false;
-     }
-
-    @Override
-    public void surfaceCreated(SurfaceHolder holder) {
-    }
-
-    @Override
-    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
-        Log.i(TAG, "Surface Changed to: " + width + "x" + height);
-        synchronized (sizeLock) {
-            currentWidth = width;
-            currentHeight = height;
-        }
-        surfaceChangedDone.open();
-    }
-
-    @Override
-    public void surfaceDestroyed(SurfaceHolder holder) {
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraDeviceTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraDeviceTest.java
deleted file mode 100644
index 29c7362..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraDeviceTest.java
+++ /dev/null
@@ -1,1381 +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 android.hardware.camera2.cts;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static com.android.ex.camera2.blocking.BlockingStateCallback.*;
-import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
-import static org.mockito.Mockito.*;
-import static android.hardware.camera2.CaptureRequest.*;
-
-import android.content.Context;
-import android.graphics.ImageFormat;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureFailure;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.os.Handler;
-import android.os.SystemClock;
-import android.util.Log;
-import android.util.Range;
-import android.view.Surface;
-
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-import com.android.ex.camera2.utils.StateWaiter;
-
-import org.mockito.ArgumentMatcher;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * <p>Basic test for CameraDevice APIs.</p>
- */
-public class CameraDeviceTest extends Camera2AndroidTestCase {
-    private static final String TAG = "CameraDeviceTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final int ERROR_LISTENER_WAIT_TIMEOUT_MS = 1000;
-    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 CameraCaptureSession mSession;
-
-    private BlockingStateCallback mCameraMockListener;
-    private int mLatestDeviceState = STATE_UNINITIALIZED;
-    private BlockingSessionCallback mSessionMockListener;
-    private StateWaiter mSessionWaiter;
-    private int mLatestSessionState = -1; // uninitialized
-
-    private static int[] sTemplates = new int[] {
-            CameraDevice.TEMPLATE_PREVIEW,
-            CameraDevice.TEMPLATE_RECORD,
-            CameraDevice.TEMPLATE_STILL_CAPTURE,
-            CameraDevice.TEMPLATE_VIDEO_SNAPSHOT
-    };
-
-    // Request templates that are unsupported by LEGACY mode.
-    private static Set<Integer> sLegacySkipTemplates = new HashSet<>();
-    static {
-        sLegacySkipTemplates.add(CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
-        sLegacySkipTemplates.add(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
-        sLegacySkipTemplates.add(CameraDevice.TEMPLATE_MANUAL);
-    }
-
-    @Override
-    public void setContext(Context context) {
-        super.setContext(context);
-
-        /**
-         * Workaround for mockito and JB-MR2 incompatibility
-         *
-         * Avoid java.lang.IllegalArgumentException: dexcache == null
-         * https://code.google.com/p/dexmaker/issues/detail?id=2
-         */
-        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
-
-        /**
-         * Create error listener in context scope, to catch asynchronous device error.
-         * Use spy object here since we want to use the SimpleDeviceListener callback
-         * implementation (spy doesn't stub the functions unless we ask it to do so).
-         */
-        mCameraMockListener = spy(new BlockingStateCallback());
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        /**
-         * Due to the asynchronous nature of camera device error callback, we
-         * have to make sure device doesn't run into error state before. If so,
-         * fail the rest of the tests. This is especially needed when error
-         * callback is fired too late.
-         */
-        verify(mCameraMockListener, never())
-                .onError(
-                    any(CameraDevice.class),
-                    anyInt());
-        verify(mCameraMockListener, never())
-                .onDisconnected(
-                    any(CameraDevice.class));
-
-        mCameraListener = mCameraMockListener;
-        createDefaultImageReader(DEFAULT_CAPTURE_SIZE, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
-                new ImageDropperListener());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * <p>
-     * Test camera capture request preview capture template.
-     * </p>
-     *
-     * <p>
-     * The request template returned by the camera device must include a
-     * necessary set of metadata keys, and their values must be set correctly.
-     * It mainly requires below settings:
-     * </p>
-     * <ul>
-     * <li>All 3A settings are auto.</li>
-     * <li>All sensor settings are not null.</li>
-     * <li>All ISP processing settings should be non-manual, and the camera
-     * device should make sure the stable frame rate is guaranteed for the given
-     * settings.</li>
-     * </ul>
-     */
-    public void testCameraDevicePreviewTemplate() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_PREVIEW);
-        }
-
-        // TODO: test the frame rate sustainability in preview use case test.
-    }
-
-    /**
-     * <p>
-     * Test camera capture request still capture template.
-     * </p>
-     *
-     * <p>
-     * The request template returned by the camera device must include a
-     * necessary set of metadata keys, and their values must be set correctly.
-     * It mainly requires below settings:
-     * </p>
-     * <ul>
-     * <li>All 3A settings are auto.</li>
-     * <li>All sensor settings are not null.</li>
-     * <li>All ISP processing settings should be non-manual, and the camera
-     * device should make sure the high quality takes priority to the stable
-     * frame rate for the given settings.</li>
-     * </ul>
-     */
-    public void testCameraDeviceStillTemplate() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_STILL_CAPTURE);
-        }
-    }
-
-    /**
-     * <p>
-     * Test camera capture video recording template.
-     * </p>
-     *
-     * <p>
-     * The request template returned by the camera device must include a
-     * necessary set of metadata keys, and their values must be set correctly.
-     * It has the similar requirement as preview, with one difference:
-     * </p>
-     * <ul>
-     * <li>Frame rate should be stable, for example, wide fps range like [7, 30]
-     * is a bad setting.</li>
-     */
-    public void testCameraDeviceRecordingTemplate() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_RECORD);
-        }
-
-        // TODO: test the frame rate sustainability in recording use case test.
-    }
-
-    /**
-     *<p>Test camera capture video snapshot template.</p>
-     *
-     * <p>The request template returned by the camera device must include a necessary set of
-     * metadata keys, and their values must be set correctly. It has the similar requirement
-     * as recording, with an additional requirement: the settings should maximize image quality
-     * without compromising stable frame rate.</p>
-     */
-    public void testCameraDeviceVideoSnapShotTemplate() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
-        }
-
-        // TODO: test the frame rate sustainability in video snapshot use case test.
-    }
-
-    /**
-     *<p>Test camera capture request zero shutter lag template.</p>
-     *
-     * <p>The request template returned by the camera device must include a necessary set of
-     * metadata keys, and their values must be set correctly. It has the similar requirement
-     * as preview, with an additional requirement: </p>
-     */
-    public void testCameraDeviceZSLTemplate() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
-        }
-    }
-
-    /**
-     * <p>
-     * Test camera capture request manual template.
-     * </p>
-     *
-     * <p>
-     * The request template returned by the camera device must include a
-     * necessary set of metadata keys, and their values must be set correctly. It
-     * mainly requires below settings:
-     * </p>
-     * <ul>
-     * <li>All 3A settings are manual.</li>
-     * <li>ISP processing parameters are set to preview quality.</li>
-     * <li>The manual capture parameters (exposure, sensitivity, and so on) are
-     * set to reasonable defaults.</li>
-     * </ul>
-     */
-    public void testCameraDeviceManualTemplate() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            captureTemplateTestByCamera(mCameraIds[i], CameraDevice.TEMPLATE_MANUAL);
-        }
-    }
-
-    public void testCameraDeviceCreateCaptureBuilder() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i], mCameraMockListener);
-                /**
-                 * Test: that each template type is supported, and that its required fields are
-                 * present.
-                 */
-                for (int j = 0; j < sTemplates.length; j++) {
-                    // Skip video snapshots for LEGACY mode
-                    if (mStaticInfo.isHardwareLevelLegacy() &&
-                            sTemplates[j] == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) {
-                        continue;
-                    }
-                    CaptureRequest.Builder capReq = mCamera.createCaptureRequest(sTemplates[j]);
-                    assertNotNull("Failed to create capture request", capReq);
-                    if (mStaticInfo.areKeysAvailable(CaptureRequest.SENSOR_EXPOSURE_TIME)) {
-                        assertNotNull("Missing field: SENSOR_EXPOSURE_TIME",
-                                capReq.get(CaptureRequest.SENSOR_EXPOSURE_TIME));
-                    }
-                    if (mStaticInfo.areKeysAvailable(CaptureRequest.SENSOR_SENSITIVITY)) {
-                        assertNotNull("Missing field: SENSOR_SENSITIVITY",
-                                capReq.get(CaptureRequest.SENSOR_SENSITIVITY));
-                    }
-                }
-            }
-            finally {
-                try {
-                    closeSession();
-                } finally {
-                    closeDevice(mCameraIds[i], mCameraMockListener);
-                }
-            }
-        }
-    }
-
-    public void testCameraDeviceSetErrorListener() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i], mCameraMockListener);
-                /**
-                 * Test: that the error listener can be set without problems.
-                 * Also, wait some time to check if device doesn't run into error.
-                 */
-                SystemClock.sleep(ERROR_LISTENER_WAIT_TIMEOUT_MS);
-                verify(mCameraMockListener, never())
-                        .onError(
-                                any(CameraDevice.class),
-                                anyInt());
-            }
-            finally {
-                try {
-                    closeSession();
-                } finally {
-                    closeDevice(mCameraIds[i], mCameraMockListener);
-                }
-            }
-        }
-    }
-
-    public void testCameraDeviceCapture() throws Exception {
-        runCaptureTest(/*burst*/false, /*repeating*/false, /*abort*/false);
-    }
-
-    public void testCameraDeviceCaptureBurst() throws Exception {
-        runCaptureTest(/*burst*/true, /*repeating*/false, /*abort*/false);
-    }
-
-    public void testCameraDeviceRepeatingRequest() throws Exception {
-        runCaptureTest(/*burst*/false, /*repeating*/true, /*abort*/false);
-    }
-
-    public void testCameraDeviceRepeatingBurst() throws Exception {
-        runCaptureTest(/*burst*/true, /*repeating*/true, /*abort*/false);
-    }
-
-    /**
-     * Test {@link android.hardware.camera2.CameraCaptureSession#abortCaptures} API.
-     *
-     * <p>Abort is the fastest way to idle the camera device for reconfiguration with
-     * {@link android.hardware.camera2.CameraCaptureSession#abortCaptures}, at the cost of
-     * discarding in-progress work. Once the abort is complete, the idle callback will be called.
-     * </p>
-     */
-    public void testCameraDeviceAbort() throws Exception {
-        runCaptureTest(/*burst*/false, /*repeating*/true, /*abort*/true);
-        runCaptureTest(/*burst*/true, /*repeating*/true, /*abort*/true);
-        /**
-         * TODO: this is only basic test of abort. we probably should also test below cases:
-         *
-         * 1. Performance. Make sure abort is faster than stopRepeating, we can test each one a
-         * couple of times, then compare the average. Also, for abortCaptures() alone, we should
-         * make sure it doesn't take too long time (e.g. <100ms for full devices, <500ms for limited
-         * devices), after the abort, we should be able to get all results back very quickly.  This
-         * can be done in performance test.
-         *
-         * 2. Make sure all in-flight request comes back after abort, e.g. submit a couple of
-         * long exposure single captures, then abort, then check if we can get the pending
-         * request back quickly.
-         *
-         * 3. Also need check onCaptureSequenceCompleted for repeating burst after abortCaptures().
-         */
-    }
-
-    /**
-     * Test invalid capture (e.g. null or empty capture request).
-     */
-    public void testInvalidCapture() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i], mCameraMockListener);
-                waitForDeviceState(STATE_OPENED, CAMERA_OPEN_TIMEOUT_MS);
-
-                prepareCapture();
-
-                invalidRequestCaptureTestByCamera();
-
-                closeSession();
-            }
-            finally {
-                try {
-
-                } finally {
-                    closeDevice(mCameraIds[i], mCameraMockListener);
-                }
-            }
-        }
-    }
-
-    /**
-     * Test to ensure that we can call camera2 API methods inside callbacks.
-     *
-     * Tests:
-     *  onOpened -> createCaptureSession, createCaptureRequest
-     *  onConfigured -> getDevice, abortCaptures,
-     *     createCaptureRequest, capture, setRepeatingRequest, stopRepeating
-     *  onCaptureCompleted -> createCaptureRequest, getDevice, abortCaptures,
-     *     capture, setRepeatingRequest, stopRepeating, session+device.close
-     */
-    public void testChainedOperation() throws Throwable {
-
-        // Set up single dummy target
-        createDefaultImageReader(DEFAULT_CAPTURE_SIZE, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
-                /*listener*/ null);
-        final ArrayList<Surface> outputs = new ArrayList<>();
-        outputs.add(mReaderSurface);
-
-        // A queue for the chained listeners to push results to
-        // A success Throwable indicates no errors; other Throwables detail a test failure;
-        // nulls indicate timeouts.
-        final Throwable success = new Throwable("Success");
-        final LinkedBlockingQueue<Throwable> results = new LinkedBlockingQueue<>();
-
-        // Define listeners
-        // A cascade of Device->Session->Capture listeners, each of which invokes at least one
-        // method on the camera device or session.
-
-        class ChainedCaptureCallback extends CameraCaptureSession.CaptureCallback {
-            public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
-                    TotalCaptureResult result) {
-                try {
-                    CaptureRequest.Builder request2 =
-                            session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                    request2.addTarget(mReaderSurface);
-
-                    // Some calls to the camera for coverage
-                    session.abortCaptures();
-                    session.capture(request2.build(),
-                            /*listener*/ null, /*handler*/ null);
-                    session.setRepeatingRequest(request2.build(),
-                            /*listener*/ null, /*handler*/ null);
-                    session.stopRepeating();
-
-                    CameraDevice camera = session.getDevice();
-                    session.close();
-                    camera.close();
-
-                    results.offer(success);
-                } catch (Throwable t) {
-                    results.offer(t);
-                }
-            }
-
-            public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
-                    CaptureFailure failure) {
-                try {
-                    CameraDevice camera = session.getDevice();
-                    session.close();
-                    camera.close();
-                    fail("onCaptureFailed invoked with failure reason: " + failure.getReason());
-                } catch (Throwable t) {
-                    results.offer(t);
-                }
-            }
-        }
-
-        class ChainedSessionListener extends CameraCaptureSession.StateCallback {
-            private final ChainedCaptureCallback mCaptureCallback = new ChainedCaptureCallback();
-
-            public void onConfigured(CameraCaptureSession session) {
-                try {
-                    CaptureRequest.Builder request =
-                            session.getDevice().createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                    request.addTarget(mReaderSurface);
-                    // Some calls to the camera for coverage
-                    session.getDevice();
-                    session.abortCaptures();
-                    // The important call for the next level of chaining
-                    session.capture(request.build(), mCaptureCallback, mHandler);
-                    // Some more calls
-                    session.setRepeatingRequest(request.build(),
-                            /*listener*/ null, /*handler*/ null);
-                    session.stopRepeating();
-                    results.offer(success);
-                } catch (Throwable t) {
-                    results.offer(t);
-                }
-            }
-
-            public void onConfigureFailed(CameraCaptureSession session) {
-                try {
-                    CameraDevice camera = session.getDevice();
-                    session.close();
-                    camera.close();
-                    fail("onConfigureFailed was invoked");
-                } catch (Throwable t) {
-                    results.offer(t);
-                }
-            }
-        }
-
-        class ChainedCameraListener extends CameraDevice.StateCallback {
-            private final ChainedSessionListener mSessionListener = new ChainedSessionListener();
-
-            public CameraDevice cameraDevice;
-
-            public void onOpened(CameraDevice camera) {
-
-                cameraDevice = camera;
-                try {
-                    // Some calls for coverage
-                    camera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                    // The important call for next level of chaining
-                    camera.createCaptureSession(outputs, mSessionListener, mHandler);
-                    results.offer(success);
-                } catch (Throwable t) {
-                    try {
-                        camera.close();
-                        results.offer(t);
-                    } catch (Throwable t2) {
-                        Log.e(TAG,
-                                "Second failure reached; discarding first exception with trace " +
-                                Log.getStackTraceString(t));
-                        results.offer(t2);
-                    }
-                }
-            }
-
-            public void onDisconnected(CameraDevice camera) {
-                try {
-                    camera.close();
-                    fail("onDisconnected invoked");
-                } catch (Throwable t) {
-                    results.offer(t);
-                }
-            }
-
-            public void onError(CameraDevice camera, int error) {
-                try {
-                    camera.close();
-                    fail("onError invoked with error code: " + error);
-                } catch (Throwable t) {
-                    results.offer(t);
-                }
-            }
-        }
-
-        // Actual test code
-
-        for (int i = 0; i < mCameraIds.length; i++) {
-            Throwable result;
-
-            // Start chained cascade
-            ChainedCameraListener cameraListener = new ChainedCameraListener();
-            mCameraManager.openCamera(mCameraIds[i], cameraListener, mHandler);
-
-            // Check if open succeeded
-            result = results.poll(CAMERA_OPEN_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-            if (result != success) {
-                if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
-                if (result == null) {
-                    fail("Timeout waiting for camera open");
-                } else {
-                    throw result;
-                }
-            }
-
-            // Check if configure succeeded
-            result = results.poll(SESSION_CONFIGURE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-            if (result != success) {
-                if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
-                if (result == null) {
-                    fail("Timeout waiting for session configure");
-                } else {
-                    throw result;
-                }
-            }
-
-            // Check if capture succeeded
-            result = results.poll(CAPTURE_RESULT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
-            if (result != success) {
-                if (cameraListener.cameraDevice != null) cameraListener.cameraDevice.close();
-                if (result == null) {
-                    fail("Timeout waiting for capture completion");
-                } else {
-                    throw result;
-                }
-            }
-        }
-    }
-
-    private void invalidRequestCaptureTestByCamera() throws Exception {
-        if (VERBOSE) Log.v(TAG, "invalidRequestCaptureTestByCamera");
-
-        List<CaptureRequest> emptyRequests = new ArrayList<CaptureRequest>();
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        CaptureRequest unConfiguredRequest = requestBuilder.build();
-        List<CaptureRequest> unConfiguredRequests = new ArrayList<CaptureRequest>();
-        unConfiguredRequests.add(unConfiguredRequest);
-
-        try {
-            // Test: CameraCaptureSession capture should throw IAE for null request.
-            mSession.capture(/*request*/null, /*listener*/null, mHandler);
-            mCollector.addMessage(
-                    "Session capture should throw IllegalArgumentException for null request");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-
-        try {
-            // Test: CameraCaptureSession capture should throw IAE for request
-            // without surface configured.
-            mSession.capture(unConfiguredRequest, /*listener*/null, mHandler);
-            mCollector.addMessage("Session capture should throw " +
-                    "IllegalArgumentException for request without surface configured");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-
-        try {
-            // Test: CameraCaptureSession setRepeatingRequest should throw IAE for null request.
-            mSession.setRepeatingRequest(/*request*/null, /*listener*/null, mHandler);
-            mCollector.addMessage("Session setRepeatingRequest should throw " +
-                    "IllegalArgumentException for null request");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-
-        try {
-            // Test: CameraCaptureSession setRepeatingRequest should throw IAE for for request
-            // without surface configured.
-            mSession.setRepeatingRequest(unConfiguredRequest, /*listener*/null, mHandler);
-            mCollector.addMessage("Capture zero burst should throw IllegalArgumentException " +
-                    "for request without surface configured");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-
-        try {
-            // Test: CameraCaptureSession captureBurst should throw IAE for null request list.
-            mSession.captureBurst(/*requests*/null, /*listener*/null, mHandler);
-            mCollector.addMessage("Session captureBurst should throw " +
-                    "IllegalArgumentException for null request list");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-
-        try {
-            // Test: CameraCaptureSession captureBurst should throw IAE for empty request list.
-            mSession.captureBurst(emptyRequests, /*listener*/null, mHandler);
-            mCollector.addMessage("Session captureBurst should throw " +
-                    " IllegalArgumentException for empty request list");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-
-        try {
-            // Test: CameraCaptureSession captureBurst should throw IAE for request
-            // without surface configured.
-            mSession.captureBurst(unConfiguredRequests, /*listener*/null, mHandler);
-            fail("Session captureBurst should throw IllegalArgumentException " +
-                    "for null request list");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-
-        try {
-            // Test: CameraCaptureSession setRepeatingBurst should throw IAE for null request list.
-            mSession.setRepeatingBurst(/*requests*/null, /*listener*/null, mHandler);
-            mCollector.addMessage("Session setRepeatingBurst should throw " +
-                    "IllegalArgumentException for null request list");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-
-        try {
-            // Test: CameraCaptureSession setRepeatingBurst should throw IAE for empty request list.
-            mSession.setRepeatingBurst(emptyRequests, /*listener*/null, mHandler);
-            mCollector.addMessage("Session setRepeatingBurst should throw " +
-                    "IllegalArgumentException for empty request list");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-
-        try {
-            // Test: CameraCaptureSession setRepeatingBurst should throw IAE for request
-            // without surface configured.
-            mSession.setRepeatingBurst(unConfiguredRequests, /*listener*/null, mHandler);
-            mCollector.addMessage("Session setRepeatingBurst should throw " +
-                    "IllegalArgumentException for request without surface configured");
-        } catch (IllegalArgumentException e) {
-            // Pass.
-        }
-    }
-
-    private class IsCaptureResultNotEmpty
-            extends ArgumentMatcher<TotalCaptureResult> {
-        @Override
-        public boolean matches(Object obj) {
-            /**
-             * Do the simple verification here. Only verify the timestamp for now.
-             * TODO: verify more required capture result metadata fields.
-             */
-            TotalCaptureResult result = (TotalCaptureResult) obj;
-            Long timeStamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
-            if (timeStamp != null && timeStamp.longValue() > 0L) {
-                return true;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Run capture test with different test configurations.
-     *
-     * @param burst If the test uses {@link CameraCaptureSession#captureBurst} or
-     * {@link CameraCaptureSession#setRepeatingBurst} to capture the burst.
-     * @param repeating If the test uses {@link CameraCaptureSession#setRepeatingBurst} or
-     * {@link CameraCaptureSession#setRepeatingRequest} for repeating capture.
-     * @param abort If the test uses {@link CameraCaptureSession#abortCaptures} to stop the
-     * repeating capture.  It has no effect if repeating is false.
-     */
-    private void runCaptureTest(boolean burst, boolean repeating, boolean abort) throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i], mCameraMockListener);
-                waitForDeviceState(STATE_OPENED, CAMERA_OPEN_TIMEOUT_MS);
-
-                prepareCapture();
-
-                if (!burst) {
-                    // Test: that a single capture of each template type succeeds.
-                    for (int j = 0; j < sTemplates.length; j++) {
-                        // Skip video snapshots for LEGACY mode
-                        if (mStaticInfo.isHardwareLevelLegacy() &&
-                                sTemplates[j] == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) {
-                            continue;
-                        }
-                        captureSingleShot(mCameraIds[i], sTemplates[j], repeating, abort);
-                    }
-                }
-                else {
-                    // Test: burst of one shot
-                    captureBurstShot(mCameraIds[i], sTemplates, 1, repeating, abort);
-
-                    int[] templates = new int[] {
-                            CameraDevice.TEMPLATE_STILL_CAPTURE,
-                            CameraDevice.TEMPLATE_STILL_CAPTURE,
-                            CameraDevice.TEMPLATE_STILL_CAPTURE,
-                            CameraDevice.TEMPLATE_STILL_CAPTURE,
-                            CameraDevice.TEMPLATE_STILL_CAPTURE
-                            };
-
-                    // Test: burst of 5 shots of the same template type
-                    captureBurstShot(mCameraIds[i], templates, templates.length, repeating, abort);
-
-                    // Test: burst of 5 shots of different template types
-                    captureBurstShot(
-                            mCameraIds[i], sTemplates, sTemplates.length, repeating, abort);
-                }
-                verify(mCameraMockListener, never())
-                        .onError(
-                                any(CameraDevice.class),
-                                anyInt());
-            } catch (Exception e) {
-                mCollector.addError(e);
-            } finally {
-                try {
-                    closeSession();
-                } catch (Exception e) {
-                    mCollector.addError(e);
-                }finally {
-                    closeDevice(mCameraIds[i], mCameraMockListener);
-                }
-            }
-        }
-    }
-
-    private void captureSingleShot(
-            String id,
-            int template,
-            boolean repeating, boolean abort) throws Exception {
-
-        assertEquals("Bad initial state for preparing to capture",
-                mLatestSessionState, SESSION_READY);
-
-        CaptureRequest.Builder requestBuilder = mCamera.createCaptureRequest(template);
-        assertNotNull("Failed to create capture request", requestBuilder);
-        requestBuilder.addTarget(mReaderSurface);
-        CameraCaptureSession.CaptureCallback mockCaptureCallback =
-                mock(CameraCaptureSession.CaptureCallback.class);
-
-        if (VERBOSE) {
-            Log.v(TAG, String.format("Capturing shot for device %s, template %d",
-                    id, template));
-        }
-
-        startCapture(requestBuilder.build(), repeating, mockCaptureCallback, mHandler);
-        waitForSessionState(SESSION_ACTIVE, SESSION_ACTIVE_TIMEOUT_MS);
-
-        int expectedCaptureResultCount = repeating ? REPEATING_CAPTURE_EXPECTED_RESULT_COUNT : 1;
-        verifyCaptureResults(mockCaptureCallback, expectedCaptureResultCount);
-
-        if (repeating) {
-            if (abort) {
-                mSession.abortCaptures();
-            } else {
-                mSession.stopRepeating();
-            }
-        }
-        waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
-    }
-
-    private void captureBurstShot(
-            String id,
-            int[] templates,
-            int len,
-            boolean repeating,
-            boolean abort) throws Exception {
-
-        assertEquals("Bad initial state for preparing to capture",
-                mLatestSessionState, SESSION_READY);
-
-        assertTrue("Invalid args to capture function", len <= templates.length);
-        List<CaptureRequest> requests = new ArrayList<CaptureRequest>();
-        for (int i = 0; i < len; i++) {
-            // Skip video snapshots for LEGACY mode
-            if (mStaticInfo.isHardwareLevelLegacy() &&
-                    templates[i] == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) {
-                continue;
-            }
-            CaptureRequest.Builder requestBuilder = mCamera.createCaptureRequest(templates[i]);
-            assertNotNull("Failed to create capture request", requestBuilder);
-            requestBuilder.addTarget(mReaderSurface);
-            requests.add(requestBuilder.build());
-        }
-        CameraCaptureSession.CaptureCallback mockCaptureCallback =
-                mock(CameraCaptureSession.CaptureCallback.class);
-
-        if (VERBOSE) {
-            Log.v(TAG, String.format("Capturing burst shot for device %s", id));
-        }
-
-        if (!repeating) {
-            mSession.captureBurst(requests, mockCaptureCallback, mHandler);
-        }
-        else {
-            mSession.setRepeatingBurst(requests, mockCaptureCallback, mHandler);
-        }
-        waitForSessionState(SESSION_ACTIVE, SESSION_READY_TIMEOUT_MS);
-
-        int expectedResultCount = requests.size();
-        if (repeating) {
-            expectedResultCount *= REPEATING_CAPTURE_EXPECTED_RESULT_COUNT;
-        }
-
-        verifyCaptureResults(mockCaptureCallback, expectedResultCount);
-
-        if (repeating) {
-            if (abort) {
-                mSession.abortCaptures();
-            } else {
-                mSession.stopRepeating();
-            }
-        }
-        waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
-    }
-
-    /**
-     * Precondition: Device must be in known OPENED state (has been waited for).
-     *
-     * <p>Creates a new capture session and waits until it is in the {@code SESSION_READY} state.
-     * </p>
-     *
-     * <p>Any existing capture session will be closed as a result of calling this.</p>
-     * */
-    private void prepareCapture() throws Exception {
-        if (VERBOSE) Log.v(TAG, "prepareCapture");
-
-        assertTrue("Bad initial state for preparing to capture",
-                mLatestDeviceState == STATE_OPENED);
-
-        if (mSession != null) {
-            if (VERBOSE) Log.v(TAG, "prepareCapture - closing existing session");
-            closeSession();
-        }
-
-        // Create a new session listener each time, it's not reusable across cameras
-        mSessionMockListener = spy(new BlockingSessionCallback());
-        mSessionWaiter = mSessionMockListener.getStateWaiter();
-
-        List<Surface> outputSurfaces = new ArrayList<>(Arrays.asList(mReaderSurface));
-        mCamera.createCaptureSession(outputSurfaces, mSessionMockListener, mHandler);
-
-        mSession = mSessionMockListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
-        waitForSessionState(SESSION_CONFIGURED, SESSION_CONFIGURE_TIMEOUT_MS);
-        waitForSessionState(SESSION_READY, SESSION_READY_TIMEOUT_MS);
-}
-
-    private void waitForDeviceState(int state, long timeoutMs) {
-        mCameraMockListener.waitForState(state, timeoutMs);
-        mLatestDeviceState = state;
-    }
-
-    private void waitForSessionState(int state, long timeoutMs) {
-        mSessionWaiter.waitForState(state, timeoutMs);
-        mLatestSessionState = state;
-    }
-
-    private void verifyCaptureResults(
-            CameraCaptureSession.CaptureCallback mockListener,
-            int expectResultCount) {
-        final int TIMEOUT_PER_RESULT_MS = 2000;
-        // Should receive expected number of capture results.
-        verify(mockListener,
-                timeout(TIMEOUT_PER_RESULT_MS * expectResultCount).atLeast(expectResultCount))
-                        .onCaptureCompleted(
-                                eq(mSession),
-                                isA(CaptureRequest.class),
-                                argThat(new IsCaptureResultNotEmpty()));
-        // Should not receive any capture failed callbacks.
-        verify(mockListener, never())
-                        .onCaptureFailed(
-                                eq(mSession),
-                                isA(CaptureRequest.class),
-                                isA(CaptureFailure.class));
-        // Should receive expected number of capture shutter calls
-        verify(mockListener,
-                atLeast(expectResultCount))
-                        .onCaptureStarted(
-                               eq(mSession),
-                               isA(CaptureRequest.class),
-                               anyLong(),
-                               anyLong());
-    }
-
-    private void checkFpsRange(CaptureRequest.Builder request, int template,
-            CameraCharacteristics props) {
-        CaptureRequest.Key<Range<Integer>> fpsRangeKey = CONTROL_AE_TARGET_FPS_RANGE;
-        Range<Integer> fpsRange;
-        if ((fpsRange = mCollector.expectKeyValueNotNull(request, fpsRangeKey)) == null) {
-            return;
-        }
-
-        int minFps = fpsRange.getLower();
-        int maxFps = fpsRange.getUpper();
-        Range<Integer>[] availableFpsRange = props
-                .get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
-        boolean foundRange = false;
-        for (int i = 0; i < availableFpsRange.length; i += 1) {
-            if (minFps == availableFpsRange[i].getLower()
-                    && maxFps == availableFpsRange[i].getUpper()) {
-                foundRange = true;
-                break;
-            }
-        }
-        if (!foundRange) {
-            mCollector.addMessage(String.format("Unable to find the fps range (%d, %d)",
-                    minFps, maxFps));
-            return;
-        }
-
-
-        if (template != CameraDevice.TEMPLATE_MANUAL &&
-                template != CameraDevice.TEMPLATE_STILL_CAPTURE) {
-            if (maxFps < MIN_FPS_REQUIRED_FOR_STREAMING) {
-                mCollector.addMessage("Max fps should be at least "
-                        + MIN_FPS_REQUIRED_FOR_STREAMING);
-                return;
-            }
-
-            // Relax framerate constraints on legacy mode
-            if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
-                // Need give fixed frame rate for video recording template.
-                if (template == CameraDevice.TEMPLATE_RECORD) {
-                    if (maxFps != minFps) {
-                        mCollector.addMessage("Video recording frame rate should be fixed");
-                    }
-                }
-            }
-        }
-    }
-
-    private void checkAfMode(CaptureRequest.Builder request, int template,
-            CameraCharacteristics props) {
-        boolean hasFocuser = !props.getKeys().contains(CameraCharacteristics.
-                LENS_INFO_MINIMUM_FOCUS_DISTANCE) ||
-                props.get(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE) > 0f;
-
-        if (!hasFocuser) {
-            return;
-        }
-
-        int targetAfMode = CaptureRequest.CONTROL_AF_MODE_AUTO;
-        int[] availableAfMode = props.get(CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
-        if (template == CameraDevice.TEMPLATE_PREVIEW ||
-                template == CameraDevice.TEMPLATE_STILL_CAPTURE ||
-                template == CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG) {
-            // Default to CONTINUOUS_PICTURE if it is available, otherwise AUTO.
-            for (int i = 0; i < availableAfMode.length; i++) {
-                if (availableAfMode[i] == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE) {
-                    targetAfMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE;
-                    break;
-                }
-            }
-        } else if (template == CameraDevice.TEMPLATE_RECORD ||
-                template == CameraDevice.TEMPLATE_VIDEO_SNAPSHOT) {
-            // Default to CONTINUOUS_VIDEO if it is available, otherwise AUTO.
-            for (int i = 0; i < availableAfMode.length; i++) {
-                if (availableAfMode[i] == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO) {
-                    targetAfMode = CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO;
-                    break;
-                }
-            }
-        } else if (template == CameraDevice.TEMPLATE_MANUAL) {
-            targetAfMode = CaptureRequest.CONTROL_AF_MODE_OFF;
-        }
-
-        mCollector.expectKeyValueEquals(request, CONTROL_AF_MODE, targetAfMode);
-        if (mStaticInfo.areKeysAvailable(CaptureRequest.LENS_FOCUS_DISTANCE)) {
-            mCollector.expectKeyValueNotNull(request, LENS_FOCUS_DISTANCE);
-        }
-    }
-
-    private void checkAntiBandingMode(CaptureRequest.Builder request, int template) {
-        if (template == CameraDevice.TEMPLATE_MANUAL) {
-            return;
-        }
-
-        List<Integer> availableAntiBandingModes =
-                Arrays.asList(toObject(mStaticInfo.getAeAvailableAntiBandingModesChecked()));
-
-        if (availableAntiBandingModes.contains(CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO)) {
-            mCollector.expectKeyValueEquals(request, CONTROL_AE_ANTIBANDING_MODE,
-                    CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO);
-        } else {
-            mCollector.expectKeyValueIsIn(request, CONTROL_AE_ANTIBANDING_MODE,
-                    CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_50HZ,
-                    CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_60HZ);
-        }
-    }
-
-    /**
-     * <p>Check if 3A metering settings are "up to HAL" in request template</p>
-     *
-     * <p>This function doesn't fail the test immediately, it updates the
-     * test pass/fail status and appends the failure message to the error collector each key.</p>
-     *
-     * @param regions The metering rectangles to be checked
-     */
-    private void checkMeteringRect(MeteringRectangle[] regions) {
-        if (regions == null) {
-            return;
-        }
-        mCollector.expectNotEquals("Number of metering region should not be 0", 0, regions.length);
-        for (int i = 0; i < regions.length; i++) {
-            mCollector.expectEquals("Default metering regions should have all zero weight",
-                    0, regions[i].getMeteringWeight());
-        }
-    }
-
-    /**
-     * <p>Check if the request settings are suitable for a given request template.</p>
-     *
-     * <p>This function doesn't fail the test immediately, it updates the
-     * test pass/fail status and appends the failure message to the error collector each key.</p>
-     *
-     * @param request The request to be checked.
-     * @param template The capture template targeted by this request.
-     * @param props The CameraCharacteristics this request is checked against with.
-     */
-    private void checkRequestForTemplate(CaptureRequest.Builder request, int template,
-            CameraCharacteristics props) {
-        // 3A settings--control.mode.
-        if (template != CameraDevice.TEMPLATE_MANUAL) {
-            mCollector.expectKeyValueEquals(request, CONTROL_MODE,
-                    CaptureRequest.CONTROL_MODE_AUTO);
-        }
-
-        // 3A settings--AE/AWB/AF.
-        int maxRegionsAe = props.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AE);
-        int maxRegionsAwb = props.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB);
-        int maxRegionsAf = props.get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF);
-
-        checkAfMode(request, template, props);
-        checkFpsRange(request, template, props);
-        checkAntiBandingMode(request, template);
-
-        if (template == CameraDevice.TEMPLATE_MANUAL) {
-            mCollector.expectKeyValueEquals(request, CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
-            mCollector.expectKeyValueEquals(request, CONTROL_AE_MODE,
-                    CaptureRequest.CONTROL_AE_MODE_OFF);
-            mCollector.expectKeyValueEquals(request, CONTROL_AWB_MODE,
-                    CaptureRequest.CONTROL_AWB_MODE_OFF);
-        } else {
-            mCollector.expectKeyValueEquals(request, CONTROL_AE_MODE,
-                    CaptureRequest.CONTROL_AE_MODE_ON);
-            mCollector.expectKeyValueEquals(request, CONTROL_AE_EXPOSURE_COMPENSATION, 0);
-            mCollector.expectKeyValueEquals(request, CONTROL_AE_LOCK, false);
-            mCollector.expectKeyValueEquals(request, CONTROL_AE_PRECAPTURE_TRIGGER,
-                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
-
-            mCollector.expectKeyValueEquals(request, CONTROL_AF_TRIGGER,
-                    CaptureRequest.CONTROL_AF_TRIGGER_IDLE);
-
-            mCollector.expectKeyValueEquals(request, CONTROL_AWB_MODE,
-                    CaptureRequest.CONTROL_AWB_MODE_AUTO);
-            mCollector.expectKeyValueEquals(request, CONTROL_AWB_LOCK, false);
-
-            // Check 3A regions.
-            if (VERBOSE) {
-                Log.v(TAG, String.format("maxRegions is: {AE: %s, AWB: %s, AF: %s}",
-                        maxRegionsAe, maxRegionsAwb, maxRegionsAf));
-            }
-            if (maxRegionsAe > 0) {
-                mCollector.expectKeyValueNotNull(request, CONTROL_AE_REGIONS);
-                MeteringRectangle[] aeRegions = request.get(CONTROL_AE_REGIONS);
-                checkMeteringRect(aeRegions);
-            }
-            if (maxRegionsAwb > 0) {
-                mCollector.expectKeyValueNotNull(request, CONTROL_AWB_REGIONS);
-                MeteringRectangle[] awbRegions = request.get(CONTROL_AWB_REGIONS);
-                checkMeteringRect(awbRegions);
-            }
-            if (maxRegionsAf > 0) {
-                mCollector.expectKeyValueNotNull(request, CONTROL_AF_REGIONS);
-                MeteringRectangle[] afRegions = request.get(CONTROL_AF_REGIONS);
-                checkMeteringRect(afRegions);
-            }
-        }
-
-        // Sensor settings.
-
-        mCollector.expectEquals("Lens aperture must be present in request if available apertures " +
-                        "are present in metadata, and vice-versa.",
-                mStaticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES),
-                mStaticInfo.areKeysAvailable(CaptureRequest.LENS_APERTURE));
-        if (mStaticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES)) {
-            float[] availableApertures =
-                    props.get(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES);
-            if (availableApertures.length > 1) {
-                mCollector.expectKeyValueNotNull(request, LENS_APERTURE);
-            }
-        }
-
-        mCollector.expectEquals("Lens filter density must be present in request if available " +
-                        "filter densities are present in metadata, and vice-versa.",
-                mStaticInfo.areKeysAvailable(CameraCharacteristics.
-                        LENS_INFO_AVAILABLE_FILTER_DENSITIES),
-                mStaticInfo.areKeysAvailable(CaptureRequest.LENS_FILTER_DENSITY));
-        if (mStaticInfo.areKeysAvailable(CameraCharacteristics.
-                LENS_INFO_AVAILABLE_FILTER_DENSITIES)) {
-            float[] availableFilters =
-                    props.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FILTER_DENSITIES);
-            if (availableFilters.length > 1) {
-                mCollector.expectKeyValueNotNull(request, LENS_FILTER_DENSITY);
-            }
-        }
-
-        float[] availableFocalLen =
-                props.get(CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS);
-        if (availableFocalLen.length > 1) {
-            mCollector.expectKeyValueNotNull(request, LENS_FOCAL_LENGTH);
-        }
-
-        mCollector.expectEquals("Lens optical stabilization must be present in request if " +
-                        "available optical stabilizations are present in metadata, and vice-versa.",
-                mStaticInfo.areKeysAvailable(CameraCharacteristics.
-                        LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION),
-                mStaticInfo.areKeysAvailable(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE));
-        if (mStaticInfo.areKeysAvailable(CameraCharacteristics.
-                LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION)) {
-            int[] availableOIS =
-                    props.get(CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION);
-            if (availableOIS.length > 1) {
-                mCollector.expectKeyValueNotNull(request, LENS_OPTICAL_STABILIZATION_MODE);
-            }
-        }
-
-        if (mStaticInfo.areKeysAvailable(BLACK_LEVEL_LOCK)) {
-            mCollector.expectKeyValueEquals(request, BLACK_LEVEL_LOCK, false);
-        }
-
-        if (mStaticInfo.areKeysAvailable(SENSOR_FRAME_DURATION)) {
-            mCollector.expectKeyValueNotNull(request, SENSOR_FRAME_DURATION);
-        }
-
-        if (mStaticInfo.areKeysAvailable(SENSOR_EXPOSURE_TIME)) {
-            mCollector.expectKeyValueNotNull(request, SENSOR_EXPOSURE_TIME);
-        }
-
-        if (mStaticInfo.areKeysAvailable(SENSOR_SENSITIVITY)) {
-            mCollector.expectKeyValueNotNull(request, SENSOR_SENSITIVITY);
-        }
-
-        // ISP-processing settings.
-        mCollector.expectKeyValueEquals(
-                request, STATISTICS_FACE_DETECT_MODE,
-                CaptureRequest.STATISTICS_FACE_DETECT_MODE_OFF);
-        mCollector.expectKeyValueEquals(request, FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
-
-        List<Integer> availableCaps = mStaticInfo.getAvailableCapabilitiesChecked();
-        if (mStaticInfo.areKeysAvailable(STATISTICS_LENS_SHADING_MAP_MODE)) {
-            // If the device doesn't support RAW, all template should have OFF as default.
-            if (!availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
-                mCollector.expectKeyValueEquals(
-                        request, STATISTICS_LENS_SHADING_MAP_MODE,
-                        CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE_OFF);
-            }
-        }
-
-        if (template == CameraDevice.TEMPLATE_STILL_CAPTURE) {
-            // Not enforce high quality here, as some devices may not effectively have high quality
-            // mode.
-            if (mStaticInfo.areKeysAvailable(COLOR_CORRECTION_MODE)) {
-                mCollector.expectKeyValueNotEquals(
-                        request, COLOR_CORRECTION_MODE,
-                        CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX);
-            }
-
-            mCollector.expectEquals("Edge mode must be present in request if " +
-                            "available edge modes are present in metadata, and vice-versa.",
-                    mStaticInfo.areKeysAvailable(CameraCharacteristics.
-                            EDGE_AVAILABLE_EDGE_MODES),
-                    mStaticInfo.areKeysAvailable(CaptureRequest.EDGE_MODE));
-            if (mStaticInfo.areKeysAvailable(EDGE_MODE)) {
-                List<Integer> availableEdgeModes =
-                        Arrays.asList(toObject(mStaticInfo.getAvailableEdgeModesChecked()));
-                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);
-                }
-            }
-
-            mCollector.expectEquals("Noise reduction mode must be present in request if " +
-                            "available noise reductions are present in metadata, and vice-versa.",
-                    mStaticInfo.areKeysAvailable(CameraCharacteristics.
-                            NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES),
-                    mStaticInfo.areKeysAvailable(CaptureRequest.NOISE_REDUCTION_MODE));
-            if (mStaticInfo.areKeysAvailable(
-                    CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES)) {
-                List<Integer> availableNoiseReductionModes =
-                        Arrays.asList(toObject(mStaticInfo.getAvailableNoiseReductionModesChecked()));
-                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);
-                }
-            }
-
-            mCollector.expectEquals("Tonemap mode must be present in request if " +
-                            "available tonemap modes are present in metadata, and vice-versa.",
-                    mStaticInfo.areKeysAvailable(CameraCharacteristics.
-                            TONEMAP_AVAILABLE_TONE_MAP_MODES),
-                    mStaticInfo.areKeysAvailable(CaptureRequest.TONEMAP_MODE));
-            if (mStaticInfo.areKeysAvailable(
-                    CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES)) {
-                List<Integer> availableToneMapModes =
-                        Arrays.asList(toObject(mStaticInfo.getAvailableToneMapModesChecked()));
-                if (availableToneMapModes.contains(CaptureRequest.TONEMAP_MODE_HIGH_QUALITY)) {
-                    mCollector.expectKeyValueEquals(request, TONEMAP_MODE,
-                            CaptureRequest.TONEMAP_MODE_HIGH_QUALITY);
-                } else {
-                    mCollector.expectKeyValueEquals(request, TONEMAP_MODE,
-                            CaptureRequest.TONEMAP_MODE_FAST);
-                }
-            }
-
-            // Still capture template should have android.statistics.lensShadingMapMode ON when
-            // RAW capability is supported.
-            if (mStaticInfo.areKeysAvailable(STATISTICS_LENS_SHADING_MAP_MODE) &&
-                    availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
-                    mCollector.expectKeyValueEquals(request, STATISTICS_LENS_SHADING_MAP_MODE,
-                            STATISTICS_LENS_SHADING_MAP_MODE_ON);
-            }
-        } else {
-            if (mStaticInfo.areKeysAvailable(EDGE_MODE)) {
-                mCollector.expectKeyValueNotNull(request, EDGE_MODE);
-            }
-
-            if (mStaticInfo.areKeysAvailable(NOISE_REDUCTION_MODE)) {
-                mCollector.expectKeyValueNotNull(request, NOISE_REDUCTION_MODE);
-            }
-
-            if (mStaticInfo.areKeysAvailable(TONEMAP_MODE)) {
-                mCollector.expectKeyValueNotEquals(request, TONEMAP_MODE,
-                        CaptureRequest.TONEMAP_MODE_CONTRAST_CURVE);
-            }
-            if (mStaticInfo.areKeysAvailable(STATISTICS_LENS_SHADING_MAP_MODE)) {
-                mCollector.expectKeyValueNotNull(request, STATISTICS_LENS_SHADING_MAP_MODE);
-            }
-        }
-
-        mCollector.expectKeyValueEquals(request, CONTROL_CAPTURE_INTENT, template);
-
-        // TODO: use the list of keys from CameraCharacteristics to avoid expecting
-        //       keys which are not available by this CameraDevice.
-    }
-
-    private void captureTemplateTestByCamera(String cameraId, int template) throws Exception {
-        try {
-            openDevice(cameraId, mCameraMockListener);
-
-            assertTrue("Camera template " + template + " is out of range!",
-                    template >= CameraDevice.TEMPLATE_PREVIEW
-                            && template <= CameraDevice.TEMPLATE_MANUAL);
-
-            mCollector.setCameraId(cameraId);
-
-            try {
-                CaptureRequest.Builder request = mCamera.createCaptureRequest(template);
-                assertNotNull("Failed to create capture request for template " + template, request);
-
-                CameraCharacteristics props = mStaticInfo.getCharacteristics();
-                checkRequestForTemplate(request, template, props);
-            } catch (IllegalArgumentException e) {
-                if (template == CameraDevice.TEMPLATE_MANUAL &&
-                        !mStaticInfo.isCapabilitySupported(CameraCharacteristics.
-                                REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                    // OK
-                } else if (sLegacySkipTemplates.contains(template) &&
-                        mStaticInfo.isHardwareLevelLegacy()) {
-                    // OK
-                } else {
-                    throw e; // rethrow
-                }
-            }
-        }
-        finally {
-            try {
-                closeSession();
-            } finally {
-                closeDevice(cameraId, mCameraMockListener);
-            }
-        }
-    }
-
-    /**
-     * Start capture with given {@link #CaptureRequest}.
-     *
-     * @param request The {@link #CaptureRequest} to be captured.
-     * @param repeating If the capture is single capture or repeating.
-     * @param listener The {@link #CaptureCallback} camera device used to notify callbacks.
-     * @param handler The handler camera device used to post callbacks.
-     */
-    protected void startCapture(CaptureRequest request, boolean repeating,
-            CameraCaptureSession.CaptureCallback listener, Handler handler)
-                    throws CameraAccessException {
-        if (VERBOSE) Log.v(TAG, "Starting capture from session");
-
-        if (repeating) {
-            mSession.setRepeatingRequest(request, listener, handler);
-        } else {
-            mSession.capture(request, listener, handler);
-        }
-    }
-
-    /**
-     * Close a {@link #CameraCaptureSession capture session}; blocking until
-     * the close finishes with a transition to {@link CameraCaptureSession.StateCallback#onClosed}.
-     */
-    protected void closeSession() {
-        if (mSession == null) {
-            return;
-        }
-
-        mSession.close();
-        waitForSessionState(SESSION_CLOSED, SESSION_CLOSE_TIMEOUT_MS);
-        mSession = null;
-
-        mSessionMockListener = null;
-        mSessionWaiter = null;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
deleted file mode 100644
index c428043..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraManagerTest.java
+++ /dev/null
@@ -1,619 +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 android.hardware.camera2.cts;
-
-import static org.mockito.Mockito.*;
-import static org.mockito.AdditionalMatchers.not;
-import static org.mockito.AdditionalMatchers.and;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraDevice.StateCallback;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.cts.CameraTestUtils.MockStateCallback;
-import android.hardware.camera2.cts.helpers.CameraErrorCollector;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.test.AndroidTestCase;
-import android.util.Log;
-
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
-
-/**
- * <p>Basic test for CameraManager class.</p>
- */
-public class CameraManagerTest extends AndroidTestCase {
-    private static final String TAG = "CameraManagerTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final int NUM_CAMERA_REOPENS = 10;
-
-    private PackageManager mPackageManager;
-    private CameraManager mCameraManager;
-    private NoopCameraListener mListener;
-    private HandlerThread mHandlerThread;
-    private Handler mHandler;
-    private BlockingStateCallback mCameraListener;
-    private CameraErrorCollector mCollector;
-
-    @Override
-    public void setContext(Context context) {
-        super.setContext(context);
-        mCameraManager = (CameraManager)context.getSystemService(Context.CAMERA_SERVICE);
-        assertNotNull("Can't connect to camera manager", mCameraManager);
-        mPackageManager = context.getPackageManager();
-        assertNotNull("Can't get package manager", mPackageManager);
-        mListener = new NoopCameraListener();
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        /**
-         * Workaround for mockito and JB-MR2 incompatibility
-         *
-         * Avoid java.lang.IllegalArgumentException: dexcache == null
-         * https://code.google.com/p/dexmaker/issues/detail?id=2
-         */
-        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
-
-        mCameraListener = spy(new BlockingStateCallback());
-
-        mHandlerThread = new HandlerThread(TAG);
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-        mCollector = new CameraErrorCollector();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mHandlerThread.quitSafely();
-        mHandler = null;
-
-        try {
-            mCollector.verify();
-        } catch (Throwable e) {
-            // When new Exception(e) is used, exception info will be printed twice.
-            throw new Exception(e.getMessage());
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    /**
-     * Verifies that the reason is in the range of public-only codes.
-     */
-    private static int checkCameraAccessExceptionReason(CameraAccessException e) {
-        int reason = e.getReason();
-
-        switch (reason) {
-            case CameraAccessException.CAMERA_DISABLED:
-            case CameraAccessException.CAMERA_DISCONNECTED:
-            case CameraAccessException.CAMERA_ERROR:
-                return reason;
-        }
-
-        fail("Invalid CameraAccessException code: " + reason);
-
-        return -1; // unreachable
-    }
-
-    public void testCameraManagerGetDeviceIdList() throws Exception {
-
-        // Test: that the getCameraIdList method runs without exceptions.
-        String[] ids = mCameraManager.getCameraIdList();
-        if (VERBOSE) Log.v(TAG, "CameraManager ids: " + Arrays.toString(ids));
-
-        /**
-         * Test: that if there is at least one reported id, then the system must have
-         * the FEATURE_CAMERA_ANY feature.
-         */
-        assertTrue("System camera feature and camera id list don't match",
-                ids.length == 0 ||
-                mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY));
-
-        /**
-         * Test: that if the device has front or rear facing cameras, then there
-         * must be matched system features.
-         */
-        for (int i = 0; i < ids.length; i++) {
-            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
-            assertNotNull("Can't get camera characteristics for camera " + ids[i], props);
-            Integer lensFacing = props.get(CameraCharacteristics.LENS_FACING);
-            assertNotNull("Can't get lens facing info", lensFacing);
-            if (lensFacing == CameraCharacteristics.LENS_FACING_FRONT) {
-                assertTrue("System doesn't have front camera feature",
-                        mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) ||
-                        mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL));
-            } else if (lensFacing == CameraCharacteristics.LENS_FACING_BACK) {
-                assertTrue("System doesn't have back camera feature",
-                        mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA));
-            } else {
-                fail("Unknown camera lens facing " + lensFacing.toString());
-            }
-        }
-
-        /**
-         * Test: that if there is one camera device, then the system must have some
-         * specific features.
-         */
-        assertTrue("Missing system feature: FEATURE_CAMERA_ANY",
-               ids.length == 0
-            || mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY));
-        assertTrue("Missing system feature: FEATURE_CAMERA or FEATURE_CAMERA_FRONT",
-               ids.length == 0
-            || mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
-            || mPackageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT));
-    }
-
-    // Test: that properties can be queried from each device, without exceptions.
-    public void testCameraManagerGetCameraCharacteristics() throws Exception {
-        String[] ids = mCameraManager.getCameraIdList();
-        for (int i = 0; i < ids.length; i++) {
-            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(ids[i]);
-            assertNotNull(
-                    String.format("Can't get camera characteristics from: ID %s", ids[i]), props);
-        }
-    }
-
-    // Test: that an exception is thrown if an invalid device id is passed down.
-    public void testCameraManagerInvalidDevice() throws Exception {
-        String[] ids = mCameraManager.getCameraIdList();
-        // Create an invalid id by concatenating all the valid ids together.
-        StringBuilder invalidId = new StringBuilder();
-        invalidId.append("INVALID");
-        for (int i = 0; i < ids.length; i++) {
-            invalidId.append(ids[i]);
-        }
-
-        try {
-            mCameraManager.getCameraCharacteristics(
-                invalidId.toString());
-            fail(String.format("Accepted invalid camera ID: %s", invalidId.toString()));
-        } catch (IllegalArgumentException e) {
-            // This is the exception that should be thrown in this case.
-        }
-    }
-
-    // Test: that each camera device can be opened one at a time, several times.
-    public void testCameraManagerOpenCamerasSerially() throws Exception {
-        String[] ids = mCameraManager.getCameraIdList();
-        for (int i = 0; i < ids.length; i++) {
-            for (int j = 0; j < NUM_CAMERA_REOPENS; j++) {
-                CameraDevice camera = null;
-                try {
-                    MockStateCallback mockListener = MockStateCallback.mock();
-                    mCameraListener = new BlockingStateCallback(mockListener);
-
-                    mCameraManager.openCamera(ids[i], mCameraListener, mHandler);
-
-                    // Block until unConfigured
-                    mCameraListener.waitForState(BlockingStateCallback.STATE_OPENED,
-                            CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
-
-                    // Ensure state transitions are in right order:
-                    // -- 1) Opened
-                    // Ensure no other state transitions have occurred:
-                    camera = verifyCameraStateOpened(ids[i], mockListener);
-                } finally {
-                    if (camera != null) {
-                        camera.close();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Test: one or more camera devices can be open at the same time, or the right error state
-     * is set if this can't be done.
-     */
-    public void testCameraManagerOpenAllCameras() throws Exception {
-        String[] ids = mCameraManager.getCameraIdList();
-        assertNotNull("Camera ids shouldn't be null", ids);
-
-        // Skip test if the device doesn't have multiple cameras.
-        if (ids.length <= 1) {
-            return;
-        }
-
-        List<CameraDevice> cameraList = new ArrayList<CameraDevice>();
-        List<MockStateCallback> listenerList = new ArrayList<MockStateCallback>();
-        List<BlockingStateCallback> blockingListenerList = new ArrayList<BlockingStateCallback>();
-        try {
-            for (int i = 0; i < ids.length; i++) {
-                // Ignore state changes from other cameras
-                MockStateCallback mockListener = MockStateCallback.mock();
-                mCameraListener = new BlockingStateCallback(mockListener);
-
-                /**
-                 * Track whether or not we got a synchronous error from openCamera.
-                 *
-                 * A synchronous error must also be accompanied by an asynchronous
-                 * StateCallback#onError callback.
-                 */
-                boolean expectingError = false;
-
-                String cameraId = ids[i];
-                try {
-                    mCameraManager.openCamera(cameraId, mCameraListener,
-                            mHandler);
-                } catch (CameraAccessException e) {
-                    if (checkCameraAccessExceptionReason(e) == CameraAccessException.CAMERA_ERROR) {
-                        expectingError = true;
-                    } else {
-                        // TODO: We should handle a Disabled camera by passing here and elsewhere
-                        fail("Camera must not be disconnected or disabled for this test" + ids[i]);
-                    }
-                }
-
-                List<Integer> expectedStates = new ArrayList<Integer>();
-                expectedStates.add(BlockingStateCallback.STATE_OPENED);
-                expectedStates.add(BlockingStateCallback.STATE_ERROR);
-                int state = mCameraListener.waitForAnyOfStates(
-                        expectedStates, CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
-
-                // It's possible that we got an asynchronous error transition only. This is ok.
-                if (expectingError) {
-                    assertEquals("Throwing a CAMERA_ERROR exception must be accompanied with a " +
-                            "StateCallback#onError callback",
-                            BlockingStateCallback.STATE_ERROR, state);
-                }
-
-                /**
-                 * Two situations are considered passing:
-                 * 1) The camera opened successfully.
-                 *     => No error must be set.
-                 * 2) The camera did not open because there were too many other cameras opened.
-                 *     => Only MAX_CAMERAS_IN_USE error must be set.
-                 *
-                 * Any other situation is considered a failure.
-                 *
-                 * For simplicity we treat disconnecting asynchronously as a failure, so
-                 * camera devices should not be physically unplugged during this test.
-                 */
-
-                CameraDevice camera;
-                if (state == BlockingStateCallback.STATE_ERROR) {
-                    // Camera did not open because too many other cameras were opened
-                    // => onError called exactly once with a non-null camera
-                    assertTrue("At least one camera must be opened successfully",
-                            cameraList.size() > 0);
-
-                    ArgumentCaptor<CameraDevice> argument =
-                            ArgumentCaptor.forClass(CameraDevice.class);
-
-                    verify(mockListener)
-                            .onError(
-                                    argument.capture(),
-                                    eq(CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE));
-                    verifyNoMoreInteractions(mockListener);
-
-                    camera = argument.getValue();
-                    assertNotNull("Expected a non-null camera for the error transition for ID: "
-                            + ids[i], camera);
-                } else if (state == BlockingStateCallback.STATE_OPENED) {
-                    // Camera opened successfully.
-                    // => onOpened called exactly once
-                    camera = verifyCameraStateOpened(cameraId,
-                            mockListener);
-                } else {
-                    fail("Unexpected state " + state);
-                    camera = null; // unreachable. but need this for java compiler
-                }
-
-                // Keep track of cameras so we can close it later
-                cameraList.add(camera);
-                listenerList.add(mockListener);
-                blockingListenerList.add(mCameraListener);
-            }
-        } finally {
-            for (CameraDevice camera : cameraList) {
-                camera.close();
-            }
-            for (BlockingStateCallback blockingListener : blockingListenerList) {
-                blockingListener.waitForState(
-                        BlockingStateCallback.STATE_CLOSED,
-                        CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
-            }
-        }
-
-        /*
-         * Ensure that no state transitions have bled through from one camera to another
-         * after closing the cameras.
-         */
-        int i = 0;
-        for (MockStateCallback listener : listenerList) {
-            CameraDevice camera = cameraList.get(i);
-
-            verify(listener).onClosed(eq(camera));
-            verifyNoMoreInteractions(listener);
-            i++;
-            // Only a #close can happen on the camera since we were done with it.
-            // Also nothing else should've happened between the close and the open.
-        }
-    }
-
-    /**
-     * Verifies the camera in this listener was opened and then unconfigured exactly once.
-     *
-     * <p>This assumes that no other action to the camera has been done (e.g.
-     * it hasn't been configured, or closed, or disconnected). Verification is
-     * performed immediately without any timeouts.</p>
-     *
-     * <p>This checks that the state has previously changed first for opened and then unconfigured.
-     * Any other state transitions will fail. A test failure is thrown if verification fails.</p>
-     *
-     * @param cameraId Camera identifier
-     * @param listener Listener which was passed to {@link CameraManager#openCamera}
-     *
-     * @return The camera device (non-{@code null}).
-     */
-    private static CameraDevice verifyCameraStateOpened(String cameraId,
-            MockStateCallback listener) {
-        ArgumentCaptor<CameraDevice> argument =
-                ArgumentCaptor.forClass(CameraDevice.class);
-        InOrder inOrder = inOrder(listener);
-
-        /**
-         * State transitions (in that order):
-         *  1) onOpened
-         *
-         * No other transitions must occur for successful #openCamera
-         */
-        inOrder.verify(listener)
-                .onOpened(argument.capture());
-
-        CameraDevice camera = argument.getValue();
-        assertNotNull(
-                String.format("Failed to open camera device ID: %s", cameraId),
-                camera);
-
-        // Do not use inOrder here since that would skip anything called before onOpened
-        verifyNoMoreInteractions(listener);
-
-        return camera;
-    }
-
-    /**
-     * Test: that opening the same device multiple times and make sure the right
-     * error state is set.
-     */
-    public void testCameraManagerOpenCameraTwice() throws Exception {
-        String[] ids = mCameraManager.getCameraIdList();
-
-        // Test across every camera device.
-        for (int i = 0; i < ids.length; ++i) {
-            CameraDevice successCamera = null;
-            mCollector.setCameraId(ids[i]);
-
-            try {
-                MockStateCallback mockSuccessListener = MockStateCallback.mock();
-                MockStateCallback mockFailListener = MockStateCallback.mock();
-
-                BlockingStateCallback successListener =
-                        new BlockingStateCallback(mockSuccessListener);
-                BlockingStateCallback failListener =
-                        new BlockingStateCallback(mockFailListener);
-
-                mCameraManager.openCamera(ids[i], successListener, mHandler);
-
-                try {
-                    mCameraManager.openCamera(ids[i], failListener,
-                            mHandler);
-                } catch (CameraAccessException e) {
-                    // Optional (but common). Camera might fail asynchronously only.
-                    // Don't assert here, otherwise, all subsequent tests will fail because the
-                    // opened camera is never closed.
-                    mCollector.expectEquals(
-                            "If second camera open fails immediately, must be due to"
-                            + "camera being busy for ID: " + ids[i],
-                            CameraAccessException.CAMERA_ERROR, e.getReason());
-                }
-
-                successListener.waitForState(BlockingStateCallback.STATE_OPENED,
-                        CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
-                // Have to get the successCamera here, otherwise, it won't be
-                // closed if STATE_ERROR timeout exception occurs.
-                ArgumentCaptor<CameraDevice> argument =
-                        ArgumentCaptor.forClass(CameraDevice.class);
-                verify(mockSuccessListener, atLeastOnce()).onOpened(argument.capture());
-
-                failListener.waitForState(BlockingStateCallback.STATE_ERROR,
-                        CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
-
-                successCamera = verifyCameraStateOpened(
-                        ids[i], mockSuccessListener);
-
-                verify(mockFailListener)
-                        .onError(
-                                and(notNull(CameraDevice.class), not(eq(successCamera))),
-                                eq(StateCallback.ERROR_CAMERA_IN_USE));
-                verifyNoMoreInteractions(mockFailListener);
-            } finally {
-                if (successCamera != null) {
-                    successCamera.close();
-                }
-            }
-        }
-    }
-
-    private class NoopCameraListener extends CameraManager.AvailabilityCallback {
-        @Override
-        public void onCameraAvailable(String cameraId) {
-            // No-op
-        }
-
-        @Override
-        public void onCameraUnavailable(String cameraId) {
-            // No-op
-        }
-    }
-
-    /**
-     * Test: that the APIs to register and unregister a listener run successfully;
-     * doesn't test that the listener actually gets invoked at the right time.
-     * Registering a listener multiple times should have no effect, and unregistering
-     * a listener that isn't registered should have no effect.
-     */
-    public void testCameraManagerListener() throws Exception {
-        mCameraManager.unregisterAvailabilityCallback(mListener);
-        mCameraManager.registerAvailabilityCallback(mListener, mHandler);
-        mCameraManager.registerAvailabilityCallback(mListener, mHandler);
-        mCameraManager.unregisterAvailabilityCallback(mListener);
-        mCameraManager.unregisterAvailabilityCallback(mListener);
-    }
-
-    /**
-     * Test that the availability callbacks fire when expected
-     */
-    public void testCameraManagerListenerCallbacks() throws Exception {
-        final int AVAILABILITY_TIMEOUT_MS = 10;
-
-        final LinkedBlockingQueue<String> availableEventQueue = new LinkedBlockingQueue<>();
-        final LinkedBlockingQueue<String> unavailableEventQueue = new LinkedBlockingQueue<>();
-
-        CameraManager.AvailabilityCallback ac = new CameraManager.AvailabilityCallback() {
-            @Override
-            public void onCameraAvailable(String cameraId) {
-                availableEventQueue.offer(cameraId);
-            }
-
-            @Override
-            public void onCameraUnavailable(String cameraId) {
-                unavailableEventQueue.offer(cameraId);
-            }
-        };
-
-        mCameraManager.registerAvailabilityCallback(ac, mHandler);
-        String[] cameras = mCameraManager.getCameraIdList();
-
-        if (cameras.length == 0) {
-            Log.i(TAG, "No cameras present, skipping test");
-            return;
-        }
-
-        // Verify we received available for all cameras' initial state in a reasonable amount of time
-        HashSet<String> expectedAvailableCameras = new HashSet<String>(Arrays.asList(cameras));
-        while (expectedAvailableCameras.size() > 0) {
-            String id = availableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
-                    java.util.concurrent.TimeUnit.MILLISECONDS);
-            assertTrue("Did not receive initial availability notices for some cameras",
-                       id != null);
-            expectedAvailableCameras.remove(id);
-        }
-        // Verify no unavailable cameras were reported
-        assertTrue("Some camera devices are initially unavailable",
-                unavailableEventQueue.size() == 0);
-
-        // Verify transitions for individual cameras
-        for (String id : cameras) {
-            MockStateCallback mockListener = MockStateCallback.mock();
-            mCameraListener = new BlockingStateCallback(mockListener);
-
-            mCameraManager.openCamera(id, mCameraListener, mHandler);
-
-            // Block until opened
-            mCameraListener.waitForState(BlockingStateCallback.STATE_OPENED,
-                    CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
-            // Then verify only open happened, and get the camera handle
-            CameraDevice camera = verifyCameraStateOpened(id, mockListener);
-
-            // Verify that we see the expected 'unavailable' event.
-            String candidateId = unavailableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
-                    java.util.concurrent.TimeUnit.MILLISECONDS);
-            assertTrue(String.format("Received unavailability notice for wrong ID " +
-                            "(expected %s, got %s)", id, candidateId),
-                    id == candidateId);
-            assertTrue("Availability events received unexpectedly",
-                    availableEventQueue.size() == 0);
-
-            // Verify that we see the expected 'available' event after closing the camera
-
-            camera.close();
-
-            mCameraListener.waitForState(BlockingStateCallback.STATE_CLOSED,
-                    CameraTestUtils.CAMERA_CLOSE_TIMEOUT_MS);
-
-            candidateId = availableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
-                    java.util.concurrent.TimeUnit.MILLISECONDS);
-            assertTrue(String.format("Received availability notice for wrong ID " +
-                            "(expected %s, got %s)", id, candidateId),
-                    id == candidateId);
-            assertTrue("Unavailability events received unexpectedly",
-                    unavailableEventQueue.size() == 0);
-
-        }
-
-        // Verify that we can unregister the listener and see no more events
-        assertTrue("Availability events received unexpectedly",
-                availableEventQueue.size() == 0);
-        assertTrue("Unavailability events received unexpectedly",
-                    unavailableEventQueue.size() == 0);
-
-        mCameraManager.unregisterAvailabilityCallback(ac);
-
-        {
-            // Open an arbitrary camera and make sure we don't hear about it
-
-            MockStateCallback mockListener = MockStateCallback.mock();
-            mCameraListener = new BlockingStateCallback(mockListener);
-
-            mCameraManager.openCamera(cameras[0], mCameraListener, mHandler);
-
-            // Block until opened
-            mCameraListener.waitForState(BlockingStateCallback.STATE_OPENED,
-                    CameraTestUtils.CAMERA_IDLE_TIMEOUT_MS);
-            // Then verify only open happened, and close the camera
-            CameraDevice camera = verifyCameraStateOpened(cameras[0], mockListener);
-
-            camera.close();
-
-            mCameraListener.waitForState(BlockingStateCallback.STATE_CLOSED,
-                    CameraTestUtils.CAMERA_CLOSE_TIMEOUT_MS);
-
-            // No unavailability or availability callback should have occured
-            String candidateId = unavailableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
-                    java.util.concurrent.TimeUnit.MILLISECONDS);
-            assertTrue(String.format("Received unavailability notice for ID %s unexpectedly ",
-                            candidateId),
-                    candidateId == null);
-
-            candidateId = availableEventQueue.poll(AVAILABILITY_TIMEOUT_MS,
-                    java.util.concurrent.TimeUnit.MILLISECONDS);
-            assertTrue(String.format("Received availability notice for ID %s unexpectedly ",
-                            candidateId),
-                    candidateId == null);
-
-
-        }
-
-    } // testCameraManagerListenerCallbacks
-
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
deleted file mode 100644
index a17041d..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CameraTestUtils.java
+++ /dev/null
@@ -1,1081 +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 android.hardware.camera2.cts;
-
-import static com.android.ex.camera2.blocking.BlockingStateCallback.*;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.ImageFormat;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureFailure;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.cts.helpers.CameraUtils;
-import android.util.Size;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.media.Image;
-import android.media.ImageReader;
-import android.media.Image.Plane;
-import android.os.Handler;
-import android.util.Log;
-import android.view.Display;
-import android.view.Surface;
-import android.view.WindowManager;
-
-import com.android.ex.camera2.blocking.BlockingCameraManager;
-import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
-
-import junit.framework.Assert;
-
-import org.mockito.Mockito;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.reflect.Array;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * A package private utility class for wrapping up the camera2 cts test common utility functions
- */
-public class CameraTestUtils extends Assert {
-    private static final String TAG = "CameraTestUtils";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    public static final Size SIZE_BOUND_1080P = new Size(1920, 1088);
-    public static final Size SIZE_BOUND_2160P = new Size(3840, 2160);
-    // Only test the preview size that is no larger than 1080p.
-    public static final Size PREVIEW_SIZE_BOUND = SIZE_BOUND_1080P;
-    // Default timeouts for reaching various states
-    public static final int CAMERA_OPEN_TIMEOUT_MS = 3000;
-    public static final int CAMERA_CLOSE_TIMEOUT_MS = 3000;
-    public static final int CAMERA_IDLE_TIMEOUT_MS = 3000;
-    public static final int CAMERA_ACTIVE_TIMEOUT_MS = 1000;
-    public static final int CAMERA_BUSY_TIMEOUT_MS = 1000;
-    public static final int CAMERA_UNCONFIGURED_TIMEOUT_MS = 1000;
-    public static final int CAMERA_CONFIGURE_TIMEOUT_MS = 3000;
-    public static final int CAPTURE_RESULT_TIMEOUT_MS = 3000;
-    public static final int CAPTURE_IMAGE_TIMEOUT_MS = 3000;
-
-    public static final int SESSION_CONFIGURE_TIMEOUT_MS = 3000;
-    public static final int SESSION_CLOSE_TIMEOUT_MS = 3000;
-    public static final int SESSION_READY_TIMEOUT_MS = 3000;
-    public static final int SESSION_ACTIVE_TIMEOUT_MS = 1000;
-
-    public static final int MAX_READER_IMAGES = 5;
-
-    /**
-     * Create an {@link android.media.ImageReader} object and get the surface.
-     *
-     * @param size The size of this ImageReader to be created.
-     * @param format The format of this ImageReader to be created
-     * @param maxNumImages The max number of images that can be acquired simultaneously.
-     * @param listener The listener used by this ImageReader to notify callbacks.
-     * @param handler The handler to use for any listener callbacks.
-     */
-    public static ImageReader makeImageReader(Size size, int format, int maxNumImages,
-            ImageReader.OnImageAvailableListener listener, Handler handler) {
-        ImageReader reader =  ImageReader.newInstance(size.getWidth(), size.getHeight(), format,
-                maxNumImages);
-        reader.setOnImageAvailableListener(listener, handler);
-        if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size);
-        return reader;
-    }
-
-    /**
-     * Close pending images and clean up an {@link android.media.ImageReader} object.
-     * @param reader an {@link android.media.ImageReader} to close.
-     */
-    public static void closeImageReader(ImageReader reader) {
-        if (reader != null) {
-            reader.close();
-        }
-    }
-
-    /**
-     * Dummy listener that release the image immediately once it is available.
-     *
-     * <p>
-     * It can be used for the case where we don't care the image data at all.
-     * </p>
-     */
-    public static class ImageDropperListener implements ImageReader.OnImageAvailableListener {
-        @Override
-        public void onImageAvailable(ImageReader reader) {
-            Image image = null;
-            try {
-                image = reader.acquireNextImage();
-            } finally {
-                if (image != null) {
-                    image.close();
-                }
-            }
-        }
-    }
-
-    /**
-     * Image listener that release the image immediately after validating the image
-     */
-    public static class ImageVerifierListener implements ImageReader.OnImageAvailableListener {
-        private Size mSize;
-        private int mFormat;
-
-        public ImageVerifierListener(Size sz, int format) {
-            mSize = sz;
-            mFormat = format;
-        }
-
-        @Override
-        public void onImageAvailable(ImageReader reader) {
-            Image image = null;
-            try {
-                image = reader.acquireNextImage();
-            } finally {
-                if (image != null) {
-                    validateImage(image, mSize.getWidth(), mSize.getHeight(), mFormat, null);
-                    image.close();
-                }
-            }
-        }
-    }
-
-    public static class SimpleImageReaderListener
-            implements ImageReader.OnImageAvailableListener {
-        private final LinkedBlockingQueue<Image> mQueue =
-                new LinkedBlockingQueue<Image>();
-
-        @Override
-        public void onImageAvailable(ImageReader reader) {
-            try {
-                mQueue.put(reader.acquireNextImage());
-            } catch (InterruptedException e) {
-                throw new UnsupportedOperationException(
-                        "Can't handle InterruptedException in onImageAvailable");
-            }
-        }
-
-        /**
-         * Get an image from the image reader.
-         *
-         * @param timeout Timeout value for the wait.
-         * @return The image from the image reader.
-         */
-        public Image getImage(long timeout) throws InterruptedException {
-            Image image = mQueue.poll(timeout, TimeUnit.MILLISECONDS);
-            assertNotNull("Wait for an image timed out in " + timeout + "ms", image);
-            return image;
-        }
-    }
-
-    public static class SimpleCaptureCallback extends CameraCaptureSession.CaptureCallback {
-        private final LinkedBlockingQueue<CaptureResult> mQueue =
-                new LinkedBlockingQueue<CaptureResult>();
-        private AtomicLong mNumFramesArrived = new AtomicLong(0);
-
-        @Override
-        public void onCaptureStarted(CameraCaptureSession session, CaptureRequest request,
-                long timestamp, long frameNumber)
-        {
-        }
-
-        @Override
-        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
-                TotalCaptureResult result) {
-            try {
-                mNumFramesArrived.incrementAndGet();
-                mQueue.put(result);
-            } catch (InterruptedException e) {
-                throw new UnsupportedOperationException(
-                        "Can't handle InterruptedException in onCaptureCompleted");
-            }
-        }
-
-        @Override
-        public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request,
-                CaptureFailure failure) {
-        }
-
-        @Override
-        public void onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId,
-                long frameNumber) {
-        }
-
-        public long getTotalNumFrames() {
-            return mNumFramesArrived.get();
-        }
-
-        public CaptureResult getCaptureResult(long timeout) {
-            try {
-                CaptureResult result = mQueue.poll(timeout, TimeUnit.MILLISECONDS);
-                assertNotNull("Wait for a capture result timed out in " + timeout + "ms", result);
-                return result;
-            } catch (InterruptedException e) {
-                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
-            }
-        }
-
-        /**
-         * Get the {@link #CaptureResult capture result} for a given
-         * {@link #CaptureRequest capture request}.
-         *
-         * @param myRequest The {@link #CaptureRequest capture request} whose
-         *            corresponding {@link #CaptureResult capture result} was
-         *            being waited for
-         * @param numResultsWait Number of frames to wait for the capture result
-         *            before timeout.
-         * @throws TimeoutRuntimeException If more than numResultsWait results are
-         *            seen before the result matching myRequest arrives, or each
-         *            individual wait for result times out after
-         *            {@value #CAPTURE_RESULT_TIMEOUT_MS}ms.
-         */
-        public CaptureResult getCaptureResultForRequest(CaptureRequest myRequest,
-                int numResultsWait) {
-            if (numResultsWait < 0) {
-                throw new IllegalArgumentException("numResultsWait must be no less than 0");
-            }
-
-            CaptureResult result;
-            int i = 0;
-            do {
-                result = getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
-                if (result.getRequest().equals(myRequest)) {
-                    return result;
-                }
-            } while (i++ < numResultsWait);
-
-            throw new TimeoutRuntimeException("Unable to get the expected capture result after "
-                    + "waiting for " + numResultsWait + " results");
-        }
-
-        public boolean hasMoreResults()
-        {
-            return mQueue.isEmpty();
-        }
-    }
-
-    /**
-     * Block until the camera is opened.
-     *
-     * <p>Don't use this to test #onDisconnected/#onError since this will throw
-     * an AssertionError if it fails to open the camera device.</p>
-     *
-     * @return CameraDevice opened camera device
-     *
-     * @throws IllegalArgumentException
-     *            If the handler is null, or if the handler's looper is current.
-     * @throws CameraAccessException
-     *            If open fails immediately.
-     * @throws BlockingOpenException
-     *            If open fails after blocking for some amount of time.
-     * @throws TimeoutRuntimeException
-     *            If opening times out. Typically unrecoverable.
-     */
-    public static CameraDevice openCamera(CameraManager manager, String cameraId,
-            CameraDevice.StateCallback listener, Handler handler) throws CameraAccessException,
-            BlockingOpenException {
-
-        /**
-         * Although camera2 API allows 'null' Handler (it will just use the current
-         * thread's Looper), this is not what we want for CTS.
-         *
-         * In CTS the default looper is used only to process events in between test runs,
-         * so anything sent there would not be executed inside a test and the test would fail.
-         *
-         * In this case, BlockingCameraManager#openCamera performs the check for us.
-         */
-        return (new BlockingCameraManager(manager)).openCamera(cameraId, listener, handler);
-    }
-
-
-    /**
-     * Block until the camera is opened.
-     *
-     * <p>Don't use this to test #onDisconnected/#onError since this will throw
-     * an AssertionError if it fails to open the camera device.</p>
-     *
-     * @throws IllegalArgumentException
-     *            If the handler is null, or if the handler's looper is current.
-     * @throws CameraAccessException
-     *            If open fails immediately.
-     * @throws BlockingOpenException
-     *            If open fails after blocking for some amount of time.
-     * @throws TimeoutRuntimeException
-     *            If opening times out. Typically unrecoverable.
-     */
-    public static CameraDevice openCamera(CameraManager manager, String cameraId, Handler handler)
-            throws CameraAccessException,
-            BlockingOpenException {
-        return openCamera(manager, cameraId, /*listener*/null, handler);
-    }
-
-    /**
-     * Configure a new camera session with output surfaces.
-     *
-     * @param camera The CameraDevice to be configured.
-     * @param outputSurfaces The surface list that used for camera output.
-     * @param listener The callback CameraDevice will notify when capture results are available.
-     */
-    public static CameraCaptureSession configureCameraSession(CameraDevice camera,
-            List<Surface> outputSurfaces,
-            CameraCaptureSession.StateCallback listener, Handler handler)
-            throws CameraAccessException {
-        BlockingSessionCallback sessionListener = new BlockingSessionCallback(listener);
-        camera.createCaptureSession(outputSurfaces, sessionListener, handler);
-
-        return sessionListener.waitAndGetSession(SESSION_CONFIGURE_TIMEOUT_MS);
-    }
-
-    public static <T> void assertArrayNotEmpty(T arr, String message) {
-        assertTrue(message, arr != null && Array.getLength(arr) > 0);
-    }
-
-    /**
-     * Check if the format is a legal YUV format camera supported.
-     */
-    public static void checkYuvFormat(int format) {
-        if ((format != ImageFormat.YUV_420_888) &&
-                (format != ImageFormat.NV21) &&
-                (format != ImageFormat.YV12)) {
-            fail("Wrong formats: " + format);
-        }
-    }
-
-    /**
-     * Check if image size and format match given size and format.
-     */
-    public static void checkImage(Image image, int width, int height, int format) {
-        assertNotNull("Input image is invalid", image);
-        assertEquals("Format doesn't match", format, image.getFormat());
-        assertEquals("Width doesn't match", width, image.getWidth());
-        assertEquals("Height doesn't match", height, image.getHeight());
-    }
-
-    /**
-     * <p>Read data from all planes of an Image into a contiguous unpadded, unpacked
-     * 1-D linear byte array, such that it can be write into disk, or accessed by
-     * software conveniently. It supports YUV_420_888/NV21/YV12 and JPEG input
-     * Image format.</p>
-     *
-     * <p>For YUV_420_888/NV21/YV12/Y8/Y16, it returns a byte array that contains
-     * the Y plane data first, followed by U(Cb), V(Cr) planes if there is any
-     * (xstride = width, ystride = height for chroma and luma components).</p>
-     *
-     * <p>For JPEG, it returns a 1-D byte array contains a complete JPEG image.</p>
-     */
-    public static byte[] getDataFromImage(Image image) {
-        assertNotNull("Invalid image:", image);
-        int format = image.getFormat();
-        int width = image.getWidth();
-        int height = image.getHeight();
-        int rowStride, pixelStride;
-        byte[] data = null;
-
-        // Read image data
-        Plane[] planes = image.getPlanes();
-        assertTrue("Fail to get image planes", planes != null && planes.length > 0);
-
-        // Check image validity
-        checkAndroidImageFormat(image);
-
-        ByteBuffer buffer = null;
-        // JPEG doesn't have pixelstride and rowstride, treat it as 1D buffer.
-        if (format == ImageFormat.JPEG) {
-            buffer = planes[0].getBuffer();
-            assertNotNull("Fail to get jpeg ByteBuffer", buffer);
-            data = new byte[buffer.remaining()];
-            buffer.get(data);
-            buffer.rewind();
-            return data;
-        }
-
-        int offset = 0;
-        data = new byte[width * height * ImageFormat.getBitsPerPixel(format) / 8];
-        int maxRowSize = planes[0].getRowStride();
-        for (int i = 0; i < planes.length; i++) {
-            if (maxRowSize < planes[i].getRowStride()) {
-                maxRowSize = planes[i].getRowStride();
-            }
-        }
-        byte[] rowData = new byte[maxRowSize];
-        if(VERBOSE) Log.v(TAG, "get data from " + planes.length + " planes");
-        for (int i = 0; i < planes.length; i++) {
-            buffer = planes[i].getBuffer();
-            assertNotNull("Fail to get bytebuffer from plane", buffer);
-            rowStride = planes[i].getRowStride();
-            pixelStride = planes[i].getPixelStride();
-            assertTrue("pixel stride " + pixelStride + " is invalid", pixelStride > 0);
-            if (VERBOSE) {
-                Log.v(TAG, "pixelStride " + pixelStride);
-                Log.v(TAG, "rowStride " + rowStride);
-                Log.v(TAG, "width " + width);
-                Log.v(TAG, "height " + height);
-            }
-            // For multi-planar yuv images, assuming yuv420 with 2x2 chroma subsampling.
-            int w = (i == 0) ? width : width / 2;
-            int h = (i == 0) ? height : height / 2;
-            assertTrue("rowStride " + rowStride + " should be >= width " + w , rowStride >= w);
-            for (int row = 0; row < h; row++) {
-                int bytesPerPixel = ImageFormat.getBitsPerPixel(format) / 8;
-                int length;
-                if (pixelStride == bytesPerPixel) {
-                    // Special case: optimized read of the entire row
-                    length = w * bytesPerPixel;
-                    buffer.get(data, offset, length);
-                    offset += length;
-                } else {
-                    // Generic case: should work for any pixelStride but slower.
-                    // Use intermediate buffer to avoid read byte-by-byte from
-                    // DirectByteBuffer, which is very bad for performance
-                    length = (w - 1) * pixelStride + bytesPerPixel;
-                    buffer.get(rowData, 0, length);
-                    for (int col = 0; col < w; col++) {
-                        data[offset++] = rowData[col * pixelStride];
-                    }
-                }
-                // Advance buffer the remainder of the row stride
-                if (row < h - 1) {
-                    buffer.position(buffer.position() + rowStride - length);
-                }
-            }
-            if (VERBOSE) Log.v(TAG, "Finished reading data from plane " + i);
-            buffer.rewind();
-        }
-        return data;
-    }
-
-    /**
-     * <p>Check android image format validity for an image, only support below formats:</p>
-     *
-     * <p>YUV_420_888/NV21/YV12, can add more for future</p>
-     */
-    public static void checkAndroidImageFormat(Image image) {
-        int format = image.getFormat();
-        Plane[] planes = image.getPlanes();
-        switch (format) {
-            case ImageFormat.YUV_420_888:
-            case ImageFormat.NV21:
-            case ImageFormat.YV12:
-                assertEquals("YUV420 format Images should have 3 planes", 3, planes.length);
-                break;
-            case ImageFormat.JPEG:
-            case ImageFormat.RAW_SENSOR:
-                assertEquals("Jpeg Image should have one plane", 1, planes.length);
-                break;
-            default:
-                fail("Unsupported Image Format: " + format);
-        }
-    }
-
-    public static void dumpFile(String fileName, Bitmap data) {
-        FileOutputStream outStream;
-        try {
-            Log.v(TAG, "output will be saved as " + fileName);
-            outStream = new FileOutputStream(fileName);
-        } catch (IOException ioe) {
-            throw new RuntimeException("Unable to create debug output file " + fileName, ioe);
-        }
-
-        try {
-            data.compress(Bitmap.CompressFormat.JPEG, /*quality*/90, outStream);
-            outStream.close();
-        } catch (IOException ioe) {
-            throw new RuntimeException("failed writing data to file " + fileName, ioe);
-        }
-    }
-
-    public static void dumpFile(String fileName, byte[] data) {
-        FileOutputStream outStream;
-        try {
-            Log.v(TAG, "output will be saved as " + fileName);
-            outStream = new FileOutputStream(fileName);
-        } catch (IOException ioe) {
-            throw new RuntimeException("Unable to create debug output file " + fileName, ioe);
-        }
-
-        try {
-            outStream.write(data);
-            outStream.close();
-        } catch (IOException ioe) {
-            throw new RuntimeException("failed writing data to file " + fileName, ioe);
-        }
-    }
-
-    /**
-     * Get the available output sizes for the user-defined {@code format}.
-     *
-     * <p>Note that implementation-defined/hidden formats are not supported.</p>
-     */
-    public static Size[] getSupportedSizeForFormat(int format, String cameraId,
-            CameraManager cameraManager) throws CameraAccessException {
-        CameraCharacteristics properties = cameraManager.getCameraCharacteristics(cameraId);
-        assertNotNull("Can't get camera characteristics!", properties);
-        if (VERBOSE) {
-            Log.v(TAG, "get camera characteristics for camera: " + cameraId);
-        }
-        StreamConfigurationMap configMap =
-                properties.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-        Size[] availableSizes = configMap.getOutputSizes(format);
-        assertArrayNotEmpty(availableSizes, "availableSizes should not be empty");
-        if (VERBOSE) Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(availableSizes));
-        return availableSizes;
-    }
-
-    /**
-     * Size comparator that compares the number of pixels it covers.
-     *
-     * <p>If two the areas of two sizes are same, compare the widths.</p>
-     */
-    public static class SizeComparator implements Comparator<Size> {
-        @Override
-        public int compare(Size lhs, Size rhs) {
-            return CameraUtils
-                    .compareSizes(lhs.getWidth(), lhs.getHeight(), rhs.getWidth(), rhs.getHeight());
-        }
-    }
-
-    /**
-     * Get sorted size list in descending order. Remove the sizes larger than
-     * the bound. If the bound is null, don't do the size bound filtering.
-     */
-    static public List<Size> getSupportedPreviewSizes(String cameraId,
-            CameraManager cameraManager, Size bound) throws CameraAccessException {
-        CameraCharacteristics props = cameraManager.getCameraCharacteristics(cameraId);
-        StreamConfigurationMap config =
-                props.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-        Size[] rawSizes = config.getOutputSizes(android.view.SurfaceHolder.class);
-        assertArrayNotEmpty(rawSizes,
-                "Available sizes for SurfaceHolder class should not be empty");
-        if (VERBOSE) {
-            Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(rawSizes));
-        }
-
-        if (bound == null) {
-            return getAscendingOrderSizes(Arrays.asList(rawSizes), /*ascending*/false);
-        }
-
-        List<Size> sizes = new ArrayList<Size>();
-        for (Size sz: rawSizes) {
-            if (sz.getWidth() <= bound.getWidth() && sz.getHeight() <= bound.getHeight()) {
-                sizes.add(sz);
-            }
-        }
-        return getAscendingOrderSizes(sizes, /*ascending*/false);
-    }
-
-    /**
-     * Get a sorted list of sizes from a given size list.
-     *
-     * <p>
-     * The size is compare by area it covers, if the areas are same, then
-     * compare the widths.
-     * </p>
-     *
-     * @param sizeList The input size list to be sorted
-     * @param ascending True if the order is ascending, otherwise descending order
-     * @return The ordered list of sizes
-     */
-    static public List<Size> getAscendingOrderSizes(final List<Size> sizeList, boolean ascending) {
-        if (sizeList == null) {
-            throw new IllegalArgumentException("sizeList shouldn't be null");
-        }
-
-        Comparator<Size> comparator = new SizeComparator();
-        List<Size> sortedSizes = new ArrayList<Size>();
-        sortedSizes.addAll(sizeList);
-        Collections.sort(sortedSizes, comparator);
-        if (!ascending) {
-            Collections.reverse(sortedSizes);
-        }
-
-        return sortedSizes;
-    }
-
-    /**
-     * Get sorted (descending order) size list for given format. Remove the sizes larger than
-     * the bound. If the bound is null, don't do the size bound filtering.
-     */
-    static public List<Size> getSortedSizesForFormat(String cameraId,
-            CameraManager cameraManager, int format, Size bound) throws CameraAccessException {
-        Comparator<Size> comparator = new SizeComparator();
-        Size[] sizes = getSupportedSizeForFormat(format, cameraId, cameraManager);
-        List<Size> sortedSizes = null;
-        if (bound != null) {
-            sortedSizes = new ArrayList<Size>(/*capacity*/1);
-            for (Size sz : sizes) {
-                if (comparator.compare(sz, bound) <= 0) {
-                    sortedSizes.add(sz);
-                }
-            }
-        } else {
-            sortedSizes = Arrays.asList(sizes);
-        }
-        assertTrue("Supported size list should have at least one element",
-                sortedSizes.size() > 0);
-
-        Collections.sort(sortedSizes, comparator);
-        // Make it in descending order.
-        Collections.reverse(sortedSizes);
-        return sortedSizes;
-    }
-
-    /**
-     * Get supported video size list for a given camera device.
-     *
-     * <p>
-     * Filter out the sizes that are larger than the bound. If the bound is
-     * null, don't do the size bound filtering.
-     * </p>
-     */
-    static public List<Size> getSupportedVideoSizes(String cameraId,
-            CameraManager cameraManager, Size bound) throws CameraAccessException {
-        CameraCharacteristics props = cameraManager.getCameraCharacteristics(cameraId);
-        StreamConfigurationMap config =
-                props.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-        Size[] rawSizes = config.getOutputSizes(android.media.MediaRecorder.class);
-        assertArrayNotEmpty(rawSizes,
-                "Available sizes for MediaRecorder class should not be empty");
-        if (VERBOSE) {
-            Log.v(TAG, "Supported sizes are: " + Arrays.deepToString(rawSizes));
-        }
-
-        if (bound == null) {
-            return getAscendingOrderSizes(Arrays.asList(rawSizes), /*ascending*/false);
-        }
-
-        List<Size> sizes = new ArrayList<Size>();
-        for (Size sz: rawSizes) {
-            if (sz.getWidth() <= bound.getWidth() && sz.getHeight() <= bound.getHeight()) {
-                sizes.add(sz);
-            }
-        }
-        return getAscendingOrderSizes(sizes, /*ascending*/false);
-    }
-
-    /**
-     * Get supported video size list (descending order) for a given camera device.
-     *
-     * <p>
-     * Filter out the sizes that are larger than the bound. If the bound is
-     * null, don't do the size bound filtering.
-     * </p>
-     */
-    static public List<Size> getSupportedStillSizes(String cameraId,
-            CameraManager cameraManager, Size bound) throws CameraAccessException {
-        return getSortedSizesForFormat(cameraId, cameraManager, ImageFormat.JPEG, bound);
-    }
-
-    static public Size getMinPreviewSize(String cameraId, CameraManager cameraManager)
-            throws CameraAccessException {
-        List<Size> sizes = getSupportedPreviewSizes(cameraId, cameraManager, null);
-        return sizes.get(sizes.size() - 1);
-    }
-
-    /**
-     * Get max supported preview size for a camera device.
-     */
-    static public Size getMaxPreviewSize(String cameraId, CameraManager cameraManager)
-            throws CameraAccessException {
-        return getMaxPreviewSize(cameraId, cameraManager, /*bound*/null);
-    }
-
-    /**
-     * Get max preview size for a camera device in the supported sizes that are no larger
-     * than the bound.
-     */
-    static public Size getMaxPreviewSize(String cameraId, CameraManager cameraManager, Size bound)
-            throws CameraAccessException {
-        List<Size> sizes = getSupportedPreviewSizes(cameraId, cameraManager, bound);
-        return sizes.get(0);
-    }
-
-    /**
-     * Get the largest size by area.
-     *
-     * @param sizes an array of sizes, must have at least 1 element
-     *
-     * @return Largest Size
-     *
-     * @throws IllegalArgumentException if sizes was null or had 0 elements
-     */
-    public static Size getMaxSize(Size[] sizes) {
-        if (sizes == null || sizes.length == 0) {
-            throw new IllegalArgumentException("sizes was empty");
-        }
-
-        Size sz = sizes[0];
-        for (Size size : sizes) {
-            if (size.getWidth() * size.getHeight() > sz.getWidth() * sz.getHeight()) {
-                sz = size;
-            }
-        }
-
-        return sz;
-    }
-
-    /**
-     * Returns true if the given {@code array} contains the given element.
-     *
-     * @param array {@code array} to check for {@code elem}
-     * @param elem {@code elem} to test for
-     * @return {@code true} if the given element is contained
-     */
-    public static boolean contains(int[] array, int elem) {
-        if (array == null) return false;
-        for (int i = 0; i < array.length; i++) {
-            if (elem == array[i]) return true;
-        }
-        return false;
-    }
-
-    /**
-     * Get object array from byte array.
-     *
-     * @param array Input byte array to be converted
-     * @return Byte object array converted from input byte array
-     */
-    public static Byte[] toObject(byte[] array) {
-        return convertPrimitiveArrayToObjectArray(array, Byte.class);
-    }
-
-    /**
-     * Get object array from int array.
-     *
-     * @param array Input int array to be converted
-     * @return Integer object array converted from input int array
-     */
-    public static Integer[] toObject(int[] array) {
-        return convertPrimitiveArrayToObjectArray(array, Integer.class);
-    }
-
-    /**
-     * Get object array from float array.
-     *
-     * @param array Input float array to be converted
-     * @return Float object array converted from input float array
-     */
-    public static Float[] toObject(float[] array) {
-        return convertPrimitiveArrayToObjectArray(array, Float.class);
-    }
-
-    /**
-     * Get object array from double array.
-     *
-     * @param array Input double array to be converted
-     * @return Double object array converted from input double array
-     */
-    public static Double[] toObject(double[] array) {
-        return convertPrimitiveArrayToObjectArray(array, Double.class);
-    }
-
-    /**
-     * Convert a primitive input array into its object array version (e.g. from int[] to Integer[]).
-     *
-     * @param array Input array object
-     * @param wrapperClass The boxed class it converts to
-     * @return Boxed version of primitive array
-     */
-    private static <T> T[] convertPrimitiveArrayToObjectArray(final Object array,
-            final Class<T> wrapperClass) {
-        // getLength does the null check and isArray check already.
-        int arrayLength = Array.getLength(array);
-        if (arrayLength == 0) {
-            throw new IllegalArgumentException("Input array shouldn't be empty");
-        }
-
-        @SuppressWarnings("unchecked")
-        final T[] result = (T[]) Array.newInstance(wrapperClass, arrayLength);
-        for (int i = 0; i < arrayLength; i++) {
-            Array.set(result, i, Array.get(array, i));
-        }
-        return result;
-    }
-
-    /**
-     * Validate image based on format and size.
-     * <p>
-     * Only RAW_SENSOR, YUV420_888 and JPEG formats are supported. Calling this
-     * method with other formats will cause a UnsupportedOperationException.
-     * </p>
-     *
-     * @param image The image to be validated.
-     * @param width The image width.
-     * @param height The image height.
-     * @param format The image format.
-     * @param filePath The debug dump file path, null if don't want to dump to
-     *            file.
-     * @throws UnsupportedOperationException if calling with format other than
-     *             RAW_SENSOR, YUV420_888 or JPEG.
-     */
-    public static void validateImage(Image image, int width, int height, int format,
-            String filePath) {
-        checkImage(image, width, height, format);
-
-        /**
-         * TODO: validate timestamp:
-         * 1. capture result timestamp against the image timestamp (need
-         * consider frame drops)
-         * 2. timestamps should be monotonically increasing for different requests
-         */
-        if(VERBOSE) Log.v(TAG, "validating Image");
-        byte[] data = getDataFromImage(image);
-        assertTrue("Invalid image data", data != null && data.length > 0);
-
-        switch (format) {
-            case ImageFormat.JPEG:
-                validateJpegData(data, width, height, filePath);
-                break;
-            case ImageFormat.YUV_420_888:
-            case ImageFormat.YV12:
-                validateYuvData(data, width, height, format, image.getTimestamp(), filePath);
-                break;
-            case ImageFormat.RAW_SENSOR:
-                validateRaw16Data(data, width, height, format, image.getTimestamp(), filePath);
-                break;
-            default:
-                throw new UnsupportedOperationException("Unsupported format for validation: "
-                        + format);
-        }
-    }
-
-    /**
-     * Provide a mock for {@link CameraDevice.StateCallback}.
-     *
-     * <p>Only useful because mockito can't mock {@link CameraDevice.StateCallback} which is an
-     * abstract class.</p>
-     *
-     * <p>
-     * Use this instead of other classes when needing to verify interactions, since
-     * trying to spy on {@link BlockingStateCallback} (or others) will cause unnecessary extra
-     * interactions which will cause false test failures.
-     * </p>
-     *
-     */
-    public static class MockStateCallback extends CameraDevice.StateCallback {
-
-        @Override
-        public void onOpened(CameraDevice camera) {
-        }
-
-        @Override
-        public void onDisconnected(CameraDevice camera) {
-        }
-
-        @Override
-        public void onError(CameraDevice camera, int error) {
-        }
-
-        private MockStateCallback() {}
-
-        /**
-         * Create a Mockito-ready mocked StateCallback.
-         */
-        public static MockStateCallback mock() {
-            return Mockito.spy(new MockStateCallback());
-        }
-    }
-
-    private static void validateJpegData(byte[] jpegData, int width, int height, String filePath) {
-        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
-        // DecodeBound mode: only parse the frame header to get width/height.
-        // it doesn't decode the pixel.
-        bmpOptions.inJustDecodeBounds = true;
-        BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length, bmpOptions);
-        assertEquals(width, bmpOptions.outWidth);
-        assertEquals(height, bmpOptions.outHeight);
-
-        // Pixel decoding mode: decode whole image. check if the image data
-        // is decodable here.
-        assertNotNull("Decoding jpeg failed",
-                BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length));
-        if (DEBUG && filePath != null) {
-            String fileName =
-                    filePath + "/" + width + "x" + height + ".jpeg";
-            dumpFile(fileName, jpegData);
-        }
-    }
-
-    private static void validateYuvData(byte[] yuvData, int width, int height, int format,
-            long ts, String filePath) {
-        checkYuvFormat(format);
-        if (VERBOSE) Log.v(TAG, "Validating YUV data");
-        int expectedSize = width * height * ImageFormat.getBitsPerPixel(format) / 8;
-        assertEquals("Yuv data doesn't match", expectedSize, yuvData.length);
-
-        // TODO: Can add data validation for test pattern.
-
-        if (DEBUG && filePath != null) {
-            String fileName =
-                    filePath + "/" + width + "x" + height + "_" + ts / 1e6 + ".yuv";
-            dumpFile(fileName, yuvData);
-        }
-    }
-
-    private static void validateRaw16Data(byte[] rawData, int width, int height, int format,
-            long ts, String filePath) {
-        if (VERBOSE) Log.v(TAG, "Validating raw data");
-        int expectedSize = width * height * ImageFormat.getBitsPerPixel(format) / 8;
-        assertEquals("Yuv data doesn't match", expectedSize, rawData.length);
-
-        // TODO: Can add data validation for test pattern.
-
-        if (DEBUG && filePath != null) {
-            String fileName =
-                    filePath + "/" + width + "x" + height + "_" + ts / 1e6 + ".raw16";
-            dumpFile(fileName, rawData);
-        }
-
-        return;
-    }
-
-    public static <T> T getValueNotNull(CaptureResult result, CaptureResult.Key<T> key) {
-        if (result == null) {
-            throw new IllegalArgumentException("Result must not be null");
-        }
-
-        T value = result.get(key);
-        assertNotNull("Value of Key " + key.getName() + "shouldn't be null", value);
-        return value;
-    }
-
-    /**
-     * Get a crop region for a given zoom factor and center position.
-     * <p>
-     * The center position is normalized position in range of [0, 1.0], where
-     * (0, 0) represents top left corner, (1.0. 1.0) represents bottom right
-     * corner. The center position could limit the effective minimal zoom
-     * factor, for example, if the center position is (0.75, 0.75), the
-     * effective minimal zoom position becomes 2.0. If the requested zoom factor
-     * is smaller than 2.0, a crop region with 2.0 zoom factor will be returned.
-     * </p>
-     * <p>
-     * The aspect ratio of the crop region is maintained the same as the aspect
-     * ratio of active array.
-     * </p>
-     *
-     * @param zoomFactor The zoom factor to generate the crop region, it must be
-     *            >= 1.0
-     * @param center The normalized zoom center point that is in the range of [0, 1].
-     * @param maxZoom The max zoom factor supported by this device.
-     * @param activeArray The active array size of this device.
-     * @return crop region for the given normalized center and zoom factor.
-     */
-    public static Rect getCropRegionForZoom(float zoomFactor, final PointF center,
-            final float maxZoom, final Rect activeArray) {
-        if (zoomFactor < 1.0) {
-            throw new IllegalArgumentException("zoom factor " + zoomFactor + " should be >= 1.0");
-        }
-        if (center.x > 1.0 || center.x < 0) {
-            throw new IllegalArgumentException("center.x " + center.x
-                    + " should be in range of [0, 1.0]");
-        }
-        if (center.y > 1.0 || center.y < 0) {
-            throw new IllegalArgumentException("center.y " + center.y
-                    + " should be in range of [0, 1.0]");
-        }
-        if (maxZoom < 1.0) {
-            throw new IllegalArgumentException("max zoom factor " + maxZoom + " should be >= 1.0");
-        }
-        if (activeArray == null) {
-            throw new IllegalArgumentException("activeArray must not be null");
-        }
-
-        float minCenterLength = Math.min(Math.min(center.x, 1.0f - center.x),
-                Math.min(center.y, 1.0f - center.y));
-        float minEffectiveZoom =  0.5f / minCenterLength;
-        if (minEffectiveZoom > maxZoom) {
-            throw new IllegalArgumentException("Requested center " + center.toString() +
-                    " has minimal zoomable factor " + minEffectiveZoom + ", which exceeds max"
-                            + " zoom factor " + maxZoom);
-        }
-
-        if (zoomFactor < minEffectiveZoom) {
-            Log.w(TAG, "Requested zoomFactor " + zoomFactor + " > minimal zoomable factor "
-                    + minEffectiveZoom + ". It will be overwritten by " + minEffectiveZoom);
-            zoomFactor = minEffectiveZoom;
-        }
-
-        int cropCenterX = (int)(activeArray.width() * center.x);
-        int cropCenterY = (int)(activeArray.height() * center.y);
-        int cropWidth = (int) (activeArray.width() / zoomFactor);
-        int cropHeight = (int) (activeArray.height() / zoomFactor);
-
-        return new Rect(
-                /*left*/cropCenterX - cropWidth / 2,
-                /*top*/cropCenterY - cropHeight / 2,
-                /*right*/ cropCenterX + cropWidth / 2 - 1,
-                /*bottom*/cropCenterY + cropHeight / 2 - 1);
-    }
-
-    /**
-     * Calculate output 3A region from the intersection of input 3A region and cropped region.
-     *
-     * @param requestRegions The input 3A regions
-     * @param cropRect The cropped region
-     * @return expected 3A regions output in capture result
-     */
-    public static MeteringRectangle[] getExpectedOutputRegion(
-            MeteringRectangle[] requestRegions, Rect cropRect){
-        MeteringRectangle[] resultRegions = new MeteringRectangle[requestRegions.length];
-        for (int i = 0; i < requestRegions.length; i++) {
-            Rect requestRect = requestRegions[i].getRect();
-            Rect resultRect = new Rect();
-            assertTrue("Input 3A region must intersect cropped region",
-                        resultRect.setIntersect(requestRect, cropRect));
-            resultRegions[i] = new MeteringRectangle(
-                    resultRect,
-                    requestRegions[i].getMeteringWeight());
-        }
-        return resultRegions;
-    }
-
-    public static Size getPreviewSizeBound(WindowManager windowManager, Size bound) {
-        Display display = windowManager.getDefaultDisplay();
-
-        int width = display.getWidth();
-        int height = display.getHeight();
-
-        if (height > width) {
-            height = width;
-            width = display.getHeight();
-        }
-
-        if (bound.getWidth() <= width &&
-            bound.getHeight() <= height)
-            return bound;
-        else
-            return new Size(width, height);
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
deleted file mode 100644
index 92eef80..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureRequestTest.java
+++ /dev/null
@@ -1,2288 +0,0 @@
-/*
- * Copyright 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.hardware.camera2.cts;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static android.hardware.camera2.CameraCharacteristics.*;
-
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
-import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
-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.util.Log;
-import android.util.Range;
-import android.util.Rational;
-import android.util.Size;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * <p>
- * Basic test for camera CaptureRequest key controls.
- * </p>
- * <p>
- * Several test categories are covered: manual sensor control, 3A control,
- * manual ISP control and other per-frame control and synchronization.
- * </p>
- */
-public class CaptureRequestTest extends Camera2SurfaceViewTestCase {
-    private static final String TAG = "CaptureRequestTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final int NUM_FRAMES_VERIFIED = 15;
-    private static final int NUM_FACE_DETECTION_FRAMES_VERIFIED = 60;
-    /** 30ms exposure time must be supported by full capability devices. */
-    private static final long DEFAULT_EXP_TIME_NS = 30000000L;
-    private static final int DEFAULT_SENSITIVITY = 100;
-    private static final int RGGB_COLOR_CHANNEL_COUNT = 4;
-    private static final int MAX_SHADING_MAP_SIZE = 64 * 64 * RGGB_COLOR_CHANNEL_COUNT;
-    private static final int MIN_SHADING_MAP_SIZE = 1 * 1 * RGGB_COLOR_CHANNEL_COUNT;
-    private static final long IGNORE_REQUESTED_EXPOSURE_TIME_CHECK = -1L;
-    private static final long EXPOSURE_TIME_BOUNDARY_50HZ_NS = 10000000L; // 10ms
-    private static final long EXPOSURE_TIME_BOUNDARY_60HZ_NS = 8333333L; // 8.3ms, Approximation.
-    private static final long EXPOSURE_TIME_ERROR_MARGIN_NS = 100000L; // 100us, Approximation.
-    private static final int SENSITIVITY_ERROR_MARGIN = 10; // 10
-    private static final int DEFAULT_NUM_EXPOSURE_TIME_STEPS = 3;
-    private static final int DEFAULT_NUM_SENSITIVITY_STEPS = 16;
-    private static final int DEFAULT_SENSITIVITY_STEP_SIZE = 100;
-    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;
-    // 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
-    private static final float FOCUS_DISTANCE_ERROR_PERCENT_UNCALIBRATED = 0.25f;
-    // 10 percent error margin for approximate device
-    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;
-
-    // Linear tone mapping curve example.
-    private static final float[] TONEMAP_CURVE_LINEAR = {0, 0, 1.0f, 1.0f};
-    // Standard sRGB tone mapping, per IEC 61966-2-1:1999, with 16 control points.
-    private static final float[] TONEMAP_CURVE_SRGB = {
-            0.0000f, 0.0000f, 0.0667f, 0.2864f, 0.1333f, 0.4007f, 0.2000f, 0.4845f,
-            0.2667f, 0.5532f, 0.3333f, 0.6125f, 0.4000f, 0.6652f, 0.4667f, 0.7130f,
-            0.5333f, 0.7569f, 0.6000f, 0.7977f, 0.6667f, 0.8360f, 0.7333f, 0.8721f,
-            0.8000f, 0.9063f, 0.8667f, 0.9389f, 0.9333f, 0.9701f, 1.0000f, 1.0000f
-    };
-    private final Rational ZERO_R = new Rational(0, 1);
-    private final Rational ONE_R = new Rational(1, 1);
-
-    private final int NUM_ALGORITHMS = 3; // AE, AWB and AF
-    private final int INDEX_ALGORITHM_AE = 0;
-    private final int INDEX_ALGORITHM_AWB = 1;
-    private final int INDEX_ALGORITHM_AF = 2;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * Test black level lock when exposure value change.
-     * <p>
-     * When {@link CaptureRequest#BLACK_LEVEL_LOCK} is true in a request, the
-     * camera device should lock the black level. When the exposure values are changed,
-     * the camera may require reset black level Since changes to certain capture
-     * parameters (such as exposure time) may require resetting of black level
-     * compensation. However, the black level must remain locked after exposure
-     * value changes (when requests have lock ON).
-     * </p>
-     */
-    public void testBlackLevelLock() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i]);
-
-                if (!mStaticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                    continue;
-                }
-
-                SimpleCaptureCallback listener = new SimpleCaptureCallback();
-                CaptureRequest.Builder requestBuilder =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-                // Start with default manual exposure time, with black level being locked.
-                requestBuilder.set(CaptureRequest.BLACK_LEVEL_LOCK, true);
-                changeExposure(requestBuilder, DEFAULT_EXP_TIME_NS, DEFAULT_SENSITIVITY);
-
-                Size previewSz =
-                        getMaxPreviewSize(mCamera.getId(), mCameraManager,
-                        getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
-
-                startPreview(requestBuilder, previewSz, listener);
-                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-                // No lock OFF state is allowed as the exposure is not changed.
-                verifyBlackLevelLockResults(listener, NUM_FRAMES_VERIFIED, /*maxLockOffCnt*/0);
-
-                // Double the exposure time and gain, with black level still being locked.
-                changeExposure(requestBuilder, DEFAULT_EXP_TIME_NS * 2, DEFAULT_SENSITIVITY * 2);
-                listener = new SimpleCaptureCallback();
-                startPreview(requestBuilder, previewSz, listener);
-                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-                // Allow at most one lock OFF state as the exposure is changed once.
-                verifyBlackLevelLockResults(listener, NUM_FRAMES_VERIFIED, /*maxLockOffCnt*/1);
-
-                stopPreview();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Basic lens shading map request test.
-     * <p>
-     * When {@link CaptureRequest#SHADING_MODE} is set to OFF, no lens shading correction will
-     * be applied by the camera device, and an identity lens shading map data
-     * will be provided if {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE} is ON.
-     * </p>
-     * <p>
-     * When {@link CaptureRequest#SHADING_MODE} is set to other modes, lens shading correction
-     * will be applied by the camera device. The lens shading map data can be
-     * requested by setting {@link CaptureRequest#STATISTICS_LENS_SHADING_MAP_MODE} to ON.
-     * </p>
-     */
-    public void testLensShadingMap() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i]);
-
-                if (!mStaticInfo.isManualLensShadingMapSupported()) {
-                    continue;
-                }
-
-                SimpleCaptureCallback listener = new SimpleCaptureCallback();
-                CaptureRequest.Builder requestBuilder =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-                // Shading map mode OFF, lensShadingMapMode ON, camera device
-                // should output unity maps.
-                requestBuilder.set(CaptureRequest.SHADING_MODE, SHADING_MODE_OFF);
-                requestBuilder.set(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE,
-                        STATISTICS_LENS_SHADING_MAP_MODE_ON);
-
-                Size previewSz =
-                        getMaxPreviewSize(mCamera.getId(), mCameraManager,
-                        getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
-
-                listener = new SimpleCaptureCallback();
-                startPreview(requestBuilder, previewSz, listener);
-                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-                verifyShadingMap(listener, NUM_FRAMES_VERIFIED, SHADING_MODE_OFF);
-
-                // Shading map mode FAST, lensShadingMapMode ON, camera device
-                // should output valid maps.
-                requestBuilder.set(CaptureRequest.SHADING_MODE, SHADING_MODE_FAST);
-
-                listener = new SimpleCaptureCallback();
-                startPreview(requestBuilder, previewSz, listener);
-                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-                // Allow at most one lock OFF state as the exposure is changed once.
-                verifyShadingMap(listener, NUM_FRAMES_VERIFIED, SHADING_MODE_FAST);
-
-                // Shading map mode HIGH_QUALITY, lensShadingMapMode ON, camera device
-                // should output valid maps.
-                requestBuilder.set(CaptureRequest.SHADING_MODE, SHADING_MODE_HIGH_QUALITY);
-
-                listener = new SimpleCaptureCallback();
-                startPreview(requestBuilder, previewSz, listener);
-                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-                verifyShadingMap(listener, NUM_FRAMES_VERIFIED, SHADING_MODE_HIGH_QUALITY);
-
-                stopPreview();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test {@link CaptureRequest#CONTROL_AE_ANTIBANDING_MODE} control.
-     * <p>
-     * Test all available anti-banding modes, check if the exposure time adjustment is
-     * correct.
-     * </p>
-     */
-    public void testAntiBandingModes() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i]);
-
-                // Without manual sensor control, exposure time cannot be verified
-                if (!mStaticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                    return;
-                }
-
-                int[] modes = mStaticInfo.getAeAvailableAntiBandingModesChecked();
-
-                Size previewSz =
-                        getMaxPreviewSize(mCamera.getId(), mCameraManager,
-                        getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
-
-                for (int mode : modes) {
-                    antiBandingTestByMode(previewSz, mode);
-                }
-            } finally {
-                closeDevice();
-            }
-        }
-
-    }
-
-    /**
-     * Test AE mode and lock.
-     *
-     * <p>
-     * For AE lock, when it is locked, exposure parameters shouldn't be changed.
-     * For AE modes, each mode should satisfy the per frame controls defined in
-     * API specifications.
-     * </p>
-     */
-    public void testAeModeAndLock() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i]);
-
-                if (mStaticInfo.isHardwareLevelLegacy()) {
-                    Log.i(TAG, "Skipping test on legacy devices");
-                    continue;
-                }
-
-                Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
-
-                // Update preview surface with given size for all sub-tests.
-                updatePreviewSurface(maxPreviewSz);
-
-                // Test aeMode and lock
-                int[] aeModes = mStaticInfo.getAeAvailableModesChecked();
-                for (int mode : aeModes) {
-                    aeModeAndLockTestByMode(mode);
-                }
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /** Test {@link CaptureRequest#FLASH_MODE} control.
-     * <p>
-     * For each {@link CaptureRequest#FLASH_MODE} mode, test the flash control
-     * and {@link CaptureResult#FLASH_STATE} result.
-     * </p>
-     */
-    public void testFlashControl() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i]);
-
-                SimpleCaptureCallback listener = new SimpleCaptureCallback();
-                CaptureRequest.Builder requestBuilder =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-                Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
-
-                startPreview(requestBuilder, maxPreviewSz, listener);
-
-                // Flash control can only be used when the AE mode is ON or OFF.
-                flashTestByAeMode(listener, CaptureRequest.CONTROL_AE_MODE_ON);
-
-                // LEGACY won't support AE mode OFF
-                boolean aeOffModeSupported = false;
-                for (int aeMode : mStaticInfo.getAeAvailableModesChecked()) {
-                    if (aeMode == CaptureRequest.CONTROL_AE_MODE_OFF) {
-                        aeOffModeSupported = true;
-                    }
-                }
-                if (aeOffModeSupported) {
-                    flashTestByAeMode(listener, CaptureRequest.CONTROL_AE_MODE_OFF);
-                }
-
-                stopPreview();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test face detection modes and results.
-     */
-    public void testFaceDetection() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                openDevice(mCameraIds[i]);
-
-                faceDetectionTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test tone map modes and controls.
-     */
-    public void testToneMapControl() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-                if (!mStaticInfo.isManualToneMapSupported()) {
-                    Log.i(TAG, "Camera " + id +
-                            " doesn't support tone mapping controls, skipping test");
-                    continue;
-                }
-                toneMapTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test color correction modes and controls.
-     */
-    public void testColorCorrectionControl() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-                if (!mStaticInfo.isManualColorCorrectionSupported()) {
-                    Log.i(TAG, "Camera " + id +
-                            " doesn't support color correction controls, skipping test");
-                    continue;
-                }
-                colorCorrectionTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    public void testEdgeModeControl() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-                if (!mStaticInfo.isEdgeModeControlSupported()) {
-                    Log.i(TAG, "Camera " + id +
-                            " doesn't support EDGE_MODE controls, skipping test");
-                    continue;
-                }
-
-                edgeModesTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test focus distance control.
-     */
-    public void testFocusDistanceControl() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-                if (!mStaticInfo.hasFocuser()) {
-                    Log.i(TAG, "Camera " + id + " has no focuser, skipping test");
-                    continue;
-                }
-
-                if (!mStaticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                    Log.i(TAG, "Camera " + id +
-                            " does not support MANUAL_SENSOR, skipping test");
-                    continue;
-                }
-
-                focusDistanceTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    public void testNoiseReductionModeControl() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-                if (!mStaticInfo.isNoiseReductionModeControlSupported()) {
-                    Log.i(TAG, "Camera " + id +
-                            " doesn't support noise reduction mode, skipping test");
-                    continue;
-                }
-
-                noiseReductionModeTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test AWB lock control.
-     *
-     * <p>The color correction gain and transform shouldn't be changed when AWB is locked.</p>
-     */
-    public void testAwbModeAndLock() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-
-                if (mStaticInfo.isHardwareLevelLegacy()) {
-                    Log.i(TAG, "Skipping test on legacy devices");
-                    continue;
-                }
-
-                awbModeAndLockTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test different AF modes.
-     */
-    public void testAfModes() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-
-                afModeTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test video and optical stabilizations.
-     */
-    public void testCameraStabilizations() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-                List<Key<?>> keys = mStaticInfo.getCharacteristics().getKeys();
-                if (!(keys.contains(
-                        CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES) ||
-                        keys.contains(
-                                CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION))) {
-                    Log.i(TAG, "Camera " + id + " doesn't support any stabilization modes");
-                    continue;
-                }
-
-                stabilizationTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test digitalZoom (center wise and non-center wise), validate the returned crop regions.
-     * The max preview size is used for each camera.
-     */
-    public void testDigitalZoom() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-
-                Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-                digitalZoomTestByCamera(maxPreviewSize);
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test digital zoom and all preview size combinations.
-     * TODO: this and above test should all be moved to preview test class.
-     */
-    public void testDigitalZoomPreviewCombinations() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-
-                digitalZoomPreviewCombinationTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test scene mode controls.
-     */
-    public void testSceneModes() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-
-                sceneModeTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test effect mode controls.
-     */
-    public void testEffectModes() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-
-                effectModeTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    // TODO: add 3A state machine test.
-
-    private void noiseReductionModeTestByCamera() throws Exception {
-        Size maxPrevSize = mOrderedPreviewSizes.get(0);
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        int[] availableModes = mStaticInfo.getAvailableNoiseReductionModesChecked();
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, maxPrevSize, resultListener);
-
-        for (int mode : availableModes) {
-            requestBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, mode);
-            resultListener = new SimpleCaptureCallback();
-            mSession.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
-            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-            verifyCaptureResultForKey(CaptureResult.NOISE_REDUCTION_MODE, mode,
-                    resultListener, NUM_FRAMES_VERIFIED);
-
-            // Test that OFF and FAST mode should not slow down the frame rate.
-            if (mode == CaptureRequest.NOISE_REDUCTION_MODE_OFF ||
-                    mode == CaptureRequest.NOISE_REDUCTION_MODE_FAST) {
-                verifyFpsNotSlowDown(requestBuilder, NUM_FRAMES_VERIFIED);
-            }
-        }
-
-        stopPreview();
-    }
-
-    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);
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, maxPrevSize, resultListener);
-
-        CaptureRequest request;
-        float[] resultDistances = new float[testDistances.length];
-        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);
-            if (VERBOSE) {
-                Log.v(TAG, "Capture request focus distance: " + testDistances[i] + " result: "
-                        + resultDistances[i]);
-            }
-        }
-
-        // Verify the monotonicity
-        mCollector.checkArrayMonotonicityAndNotAllEqual(CameraTestUtils.toObject(resultDistances),
-                /*ascendingOrder*/true);
-
-        if (mStaticInfo.getCharacteristics().getKeys().
-                contains(CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE)) {
-
-            // Test hyperfocal distance optionally
-            float hyperFocalDistance = mStaticInfo.getHyperfocalDistanceChecked();
-            if (hyperFocalDistance > 0) {
-                requestBuilder.set(CaptureRequest.LENS_FOCUS_DISTANCE, hyperFocalDistance);
-                request = requestBuilder.build();
-                resultListener = new SimpleCaptureCallback();
-                mSession.setRepeatingRequest(request, resultListener, mHandler);
-                waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-                // 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,
-                        hyperFocalDistance * (1.0f - errorMargin),
-                        hyperFocalDistance * (1.0f + 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
-     */
-    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?
-        }
-
-        float minValue = 0;
-        float maxValue = mStaticInfo.getMinimumFocusDistanceChecked();
-        mCollector.expectInRange("Result focus distance is out of range",
-                resultDistance, minValue, maxValue);
-
-        return resultDistance;
-    }
-
-    /**
-     * Verify edge mode control results.
-     */
-    private void edgeModesTestByCamera() throws Exception {
-        Size maxPrevSize = mOrderedPreviewSizes.get(0);
-        int[] edgeModes = mStaticInfo.getAvailableEdgeModesChecked();
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, maxPrevSize, resultListener);
-
-        for (int mode : edgeModes) {
-            requestBuilder.set(CaptureRequest.EDGE_MODE, mode);
-            resultListener = new SimpleCaptureCallback();
-            mSession.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
-            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-            verifyCaptureResultForKey(CaptureResult.EDGE_MODE, mode, resultListener,
-                    NUM_FRAMES_VERIFIED);
-
-            // Test that OFF and FAST mode should not slow down the frame rate.
-            if (mode == CaptureRequest.EDGE_MODE_OFF ||
-                    mode == CaptureRequest.EDGE_MODE_FAST) {
-                verifyFpsNotSlowDown(requestBuilder, NUM_FRAMES_VERIFIED);
-            }
-        }
-
-        stopPreview();
-    }
-
-    /**
-     * Test color correction controls.
-     *
-     * <p>Test different color correction modes. For TRANSFORM_MATRIX, only test
-     * the unit gain and identity transform.</p>
-     */
-    private void colorCorrectionTestByCamera() throws Exception {
-        CaptureRequest request;
-        CaptureResult result;
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
-        updatePreviewSurface(maxPreviewSz);
-        CaptureRequest.Builder manualRequestBuilder = createRequestForPreview();
-        CaptureRequest.Builder previewRequestBuilder = createRequestForPreview();
-        SimpleCaptureCallback listener = new SimpleCaptureCallback();
-
-        startPreview(previewRequestBuilder, maxPreviewSz, listener);
-
-        // Default preview result should give valid color correction metadata.
-        result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        validateColorCorrectionResult(result,
-                previewRequestBuilder.get(CaptureRequest.COLOR_CORRECTION_MODE));
-
-        // TRANSFORM_MATRIX mode
-        // Only test unit gain and identity transform
-        RggbChannelVector UNIT_GAIN = new RggbChannelVector(1.0f, 1.0f, 1.0f, 1.0f);
-
-        ColorSpaceTransform IDENTITY_TRANSFORM = new ColorSpaceTransform(
-            new Rational[] {
-                ONE_R, ZERO_R, ZERO_R,
-                ZERO_R, ONE_R, ZERO_R,
-                ZERO_R, ZERO_R, ONE_R
-            });
-
-        int colorCorrectionMode = CaptureRequest.COLOR_CORRECTION_MODE_TRANSFORM_MATRIX;
-        manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_OFF);
-        manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, colorCorrectionMode);
-        manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_GAINS, UNIT_GAIN);
-        manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_TRANSFORM, IDENTITY_TRANSFORM);
-        request = manualRequestBuilder.build();
-        mSession.capture(request, listener, mHandler);
-        result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
-        RggbChannelVector gains = result.get(CaptureResult.COLOR_CORRECTION_GAINS);
-        ColorSpaceTransform transform = result.get(CaptureResult.COLOR_CORRECTION_TRANSFORM);
-        validateColorCorrectionResult(result, colorCorrectionMode);
-        mCollector.expectEquals("control mode result/request mismatch",
-                CaptureResult.CONTROL_MODE_OFF, result.get(CaptureResult.CONTROL_MODE));
-        mCollector.expectEquals("Color correction gain result/request mismatch",
-                UNIT_GAIN, gains);
-        mCollector.expectEquals("Color correction gain result/request mismatch",
-                IDENTITY_TRANSFORM, transform);
-
-        // FAST mode
-        colorCorrectionMode = CaptureRequest.COLOR_CORRECTION_MODE_FAST;
-        manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
-        manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, colorCorrectionMode);
-        request = manualRequestBuilder.build();
-        mSession.capture(request, listener, mHandler);
-        result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
-        validateColorCorrectionResult(result, colorCorrectionMode);
-        mCollector.expectEquals("control mode result/request mismatch",
-                CaptureResult.CONTROL_MODE_AUTO, result.get(CaptureResult.CONTROL_MODE));
-
-        // HIGH_QUALITY mode
-        colorCorrectionMode = CaptureRequest.COLOR_CORRECTION_MODE_HIGH_QUALITY;
-        manualRequestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
-        manualRequestBuilder.set(CaptureRequest.COLOR_CORRECTION_MODE, colorCorrectionMode);
-        request = manualRequestBuilder.build();
-        mSession.capture(request, listener, mHandler);
-        result = listener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
-        validateColorCorrectionResult(result, colorCorrectionMode);
-        mCollector.expectEquals("control mode result/request mismatch",
-                CaptureResult.CONTROL_MODE_AUTO, result.get(CaptureResult.CONTROL_MODE));
-    }
-
-    private void validateColorCorrectionResult(CaptureResult result, int colorCorrectionMode) {
-        final RggbChannelVector ZERO_GAINS = new RggbChannelVector(0, 0, 0, 0);
-        final int TRANSFORM_SIZE = 9;
-        Rational[] zeroTransform = new Rational[TRANSFORM_SIZE];
-        Arrays.fill(zeroTransform, ZERO_R);
-        final ColorSpaceTransform ZERO_TRANSFORM = new ColorSpaceTransform(zeroTransform);
-
-        RggbChannelVector resultGain;
-        if ((resultGain = mCollector.expectKeyValueNotNull(result,
-                CaptureResult.COLOR_CORRECTION_GAINS)) != null) {
-            mCollector.expectKeyValueNotEquals(result,
-                    CaptureResult.COLOR_CORRECTION_GAINS, ZERO_GAINS);
-        }
-
-        ColorSpaceTransform resultTransform;
-        if ((resultTransform = mCollector.expectKeyValueNotNull(result,
-                CaptureResult.COLOR_CORRECTION_TRANSFORM)) != null) {
-            mCollector.expectKeyValueNotEquals(result,
-                    CaptureResult.COLOR_CORRECTION_TRANSFORM, ZERO_TRANSFORM);
-        }
-
-        mCollector.expectEquals("color correction mode result/request mismatch",
-                colorCorrectionMode, result.get(CaptureResult.COLOR_CORRECTION_MODE));
-    }
-
-    /**
-     * Test flash mode control by AE mode.
-     * <p>
-     * Only allow AE mode ON or OFF, because other AE mode could run into conflict with
-     * flash manual control. This function expects the camera to already have an active
-     * repeating request and be sending results to the listener.
-     * </p>
-     *
-     * @param listener The Capture listener that is used to wait for capture result
-     * @param aeMode The AE mode for flash to test with
-     */
-    private void flashTestByAeMode(SimpleCaptureCallback listener, int aeMode) throws Exception {
-        CaptureResult result;
-        final int NUM_FLASH_REQUESTS_TESTED = 10;
-        CaptureRequest.Builder requestBuilder = createRequestForPreview();
-
-        if (aeMode == CaptureRequest.CONTROL_AE_MODE_ON) {
-            requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, aeMode);
-        } else if (aeMode == CaptureRequest.CONTROL_AE_MODE_OFF) {
-            changeExposure(requestBuilder, DEFAULT_EXP_TIME_NS, DEFAULT_SENSITIVITY);
-        } else {
-            throw new IllegalArgumentException("This test only works when AE mode is ON or OFF");
-        }
-
-        mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
-        waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-        // For camera that doesn't have flash unit, flash state should always be UNAVAILABLE.
-        if (mStaticInfo.getFlashInfoChecked() == false) {
-            for (int i = 0; i < NUM_FLASH_REQUESTS_TESTED; i++) {
-                result = listener.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
-                mCollector.expectEquals("No flash unit available, flash state must be UNAVAILABLE"
-                        + "for AE mode " + aeMode, CaptureResult.FLASH_STATE_UNAVAILABLE,
-                        result.get(CaptureResult.FLASH_STATE));
-            }
-
-            return;
-        }
-
-        // Test flash SINGLE mode control. Wait for flash state to be READY first.
-        if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
-            waitForResultValue(listener, CaptureResult.FLASH_STATE, CaptureResult.FLASH_STATE_READY,
-                    NUM_RESULTS_WAIT_TIMEOUT);
-        } // else the settings were already waited on earlier
-
-        requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_SINGLE);
-        CaptureRequest flashSinglerequest = requestBuilder.build();
-
-        int flashModeSingleRequests = captureRequestsSynchronized(
-                flashSinglerequest, listener, mHandler);
-        waitForNumResults(listener, flashModeSingleRequests - 1);
-        result = listener.getCaptureResultForRequest(flashSinglerequest, NUM_RESULTS_WAIT_TIMEOUT);
-        // Result mode must be SINGLE, state must be FIRED.
-        mCollector.expectEquals("Flash mode result must be SINGLE",
-                CaptureResult.FLASH_MODE_SINGLE, result.get(CaptureResult.FLASH_MODE));
-        mCollector.expectEquals("Flash state result must be FIRED",
-                CaptureResult.FLASH_STATE_FIRED, result.get(CaptureResult.FLASH_STATE));
-
-        // Test flash TORCH mode control.
-        requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_TORCH);
-        CaptureRequest torchRequest = requestBuilder.build();
-
-        int flashModeTorchRequests = captureRequestsSynchronized(torchRequest,
-                NUM_FLASH_REQUESTS_TESTED, listener, mHandler);
-        waitForNumResults(listener, flashModeTorchRequests - NUM_FLASH_REQUESTS_TESTED);
-
-        // Verify the results
-        for (int i = 0; i < NUM_FLASH_REQUESTS_TESTED; i++) {
-            result = listener.getCaptureResultForRequest(torchRequest,
-                    NUM_RESULTS_WAIT_TIMEOUT);
-
-            // Result mode must be TORCH, state must be FIRED
-            mCollector.expectEquals("Flash mode result must be TORCH",
-                    CaptureResult.FLASH_MODE_TORCH, result.get(CaptureResult.FLASH_MODE));
-            mCollector.expectEquals("Flash state result must be FIRED",
-                    CaptureResult.FLASH_STATE_FIRED, result.get(CaptureResult.FLASH_STATE));
-        }
-
-        // Test flash OFF mode control
-        requestBuilder.set(CaptureRequest.FLASH_MODE, CaptureRequest.FLASH_MODE_OFF);
-        CaptureRequest flashOffrequest = requestBuilder.build();
-
-        int flashModeOffRequests = captureRequestsSynchronized(flashOffrequest, listener, mHandler);
-        waitForNumResults(listener, flashModeOffRequests - 1);
-        result = listener.getCaptureResultForRequest(flashOffrequest, NUM_RESULTS_WAIT_TIMEOUT);
-        mCollector.expectEquals("Flash mode result must be OFF", CaptureResult.FLASH_MODE_OFF,
-                result.get(CaptureResult.FLASH_MODE));
-    }
-
-    private void verifyAntiBandingMode(SimpleCaptureCallback listener, int numFramesVerified,
-            int mode, boolean isAeManual, long requestExpTime) throws Exception {
-        // Skip the first a couple of frames as antibanding may not be fully up yet.
-        final int NUM_FRAMES_SKIPPED = 5;
-        for (int i = 0; i < NUM_FRAMES_SKIPPED; i++) {
-            listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        }
-
-        for (int i = 0; i < numFramesVerified; i++) {
-            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            Long resultExpTime = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
-            assertNotNull("Exposure time shouldn't be null", resultExpTime);
-            Integer flicker = result.get(CaptureResult.STATISTICS_SCENE_FLICKER);
-            // Scene flicker result should be always available.
-            assertNotNull("Scene flicker must not be null", flicker);
-            assertTrue("Scene flicker is invalid", flicker >= STATISTICS_SCENE_FLICKER_NONE &&
-                    flicker <= STATISTICS_SCENE_FLICKER_60HZ);
-
-            if (isAeManual) {
-                // First, round down not up, second, need close enough.
-                validateExposureTime(requestExpTime, resultExpTime);
-                return;
-            }
-
-            long expectedExpTime = resultExpTime; // Default, no exposure adjustment.
-            if (mode == CONTROL_AE_ANTIBANDING_MODE_50HZ) {
-                // result exposure time must be adjusted by 50Hz illuminant source.
-                expectedExpTime =
-                        getAntiFlickeringExposureTime(ANTI_FLICKERING_50HZ, resultExpTime);
-            } else if (mode == CONTROL_AE_ANTIBANDING_MODE_60HZ) {
-                // result exposure time must be adjusted by 60Hz illuminant source.
-                expectedExpTime =
-                        getAntiFlickeringExposureTime(ANTI_FLICKERING_60HZ, resultExpTime);
-            } else if (mode == CONTROL_AE_ANTIBANDING_MODE_AUTO){
-                /**
-                 * Use STATISTICS_SCENE_FLICKER to tell the illuminant source
-                 * and do the exposure adjustment.
-                 */
-                expectedExpTime = resultExpTime;
-                if (flicker == STATISTICS_SCENE_FLICKER_60HZ) {
-                    expectedExpTime =
-                            getAntiFlickeringExposureTime(ANTI_FLICKERING_60HZ, resultExpTime);
-                } else if (flicker == STATISTICS_SCENE_FLICKER_50HZ) {
-                    expectedExpTime =
-                            getAntiFlickeringExposureTime(ANTI_FLICKERING_50HZ, resultExpTime);
-                }
-            }
-
-            if (Math.abs(resultExpTime - expectedExpTime) > EXPOSURE_TIME_ERROR_MARGIN_NS) {
-                mCollector.addMessage(String.format("Result exposure time %dns diverges too much"
-                        + " from expected exposure time %dns for mode %d when AE is auto",
-                        resultExpTime, expectedExpTime, mode));
-            }
-        }
-    }
-
-    private void antiBandingTestByMode(Size size, int mode)
-            throws Exception {
-        if(VERBOSE) {
-            Log.v(TAG, "Anti-banding test for mode " + mode + " for camera " + mCamera.getId());
-        }
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-        requestBuilder.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE, mode);
-
-        // Test auto AE mode anti-banding behavior
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, size, resultListener);
-        waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-        verifyAntiBandingMode(resultListener, NUM_FRAMES_VERIFIED, mode, /*isAeManual*/false,
-                IGNORE_REQUESTED_EXPOSURE_TIME_CHECK);
-
-        // Test manual AE mode anti-banding behavior
-        // 65ms, must be supported by full capability devices.
-        final long TEST_MANUAL_EXP_TIME_NS = 65000000L;
-        long manualExpTime = mStaticInfo.getExposureClampToRange(TEST_MANUAL_EXP_TIME_NS);
-        changeExposure(requestBuilder, manualExpTime);
-        resultListener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, size, resultListener);
-        waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-        verifyAntiBandingMode(resultListener, NUM_FRAMES_VERIFIED, mode, /*isAeManual*/true,
-                manualExpTime);
-
-        stopPreview();
-    }
-
-    /**
-     * Test the all available AE modes and AE lock.
-     * <p>
-     * For manual AE mode, test iterates through different sensitivities and
-     * exposure times, validate the result exposure time correctness. For
-     * CONTROL_AE_MODE_ON_ALWAYS_FLASH mode, the AE lock and flash are tested.
-     * For the rest of the AUTO mode, AE lock is tested.
-     * </p>
-     *
-     * @param mode
-     */
-    private void aeModeAndLockTestByMode(int mode)
-            throws Exception {
-        switch (mode) {
-            case CONTROL_AE_MODE_OFF:
-                if (mStaticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                    // Test manual exposure control.
-                    aeManualControlTest();
-                } else {
-                    Log.w(TAG,
-                            "aeModeAndLockTestByMode - can't test AE mode OFF without " +
-                            "manual sensor control");
-                }
-                break;
-            case CONTROL_AE_MODE_ON:
-            case CONTROL_AE_MODE_ON_AUTO_FLASH:
-            case CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE:
-            case CONTROL_AE_MODE_ON_ALWAYS_FLASH:
-                // Test AE lock for above AUTO modes.
-                aeAutoModeTestLock(mode);
-                break;
-            default:
-                throw new UnsupportedOperationException("Unhandled AE mode " + mode);
-        }
-    }
-
-    /**
-     * Test AE auto modes.
-     * <p>
-     * Use single request rather than repeating request to test AE lock per frame control.
-     * </p>
-     */
-    private void aeAutoModeTestLock(int mode) throws Exception {
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
-        requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, mode);
-        configurePreviewOutput(requestBuilder);
-
-        final int MAX_NUM_CAPTURES_DURING_LOCK = 5;
-        for (int i = 1; i <= MAX_NUM_CAPTURES_DURING_LOCK; i++) {
-            autoAeMultipleCapturesThenTestLock(requestBuilder, mode, i);
-        }
-    }
-
-    /**
-     * Issue multiple auto AE captures, then lock AE, validate the AE lock vs.
-     * the first capture result after the AE lock. The right AE lock behavior is:
-     * When it is locked, it locks to the current exposure value, and all subsequent
-     * request with lock ON will have the same exposure value locked.
-     */
-    private void autoAeMultipleCapturesThenTestLock(
-            CaptureRequest.Builder requestBuilder, int aeMode, int numCapturesDuringLock)
-            throws Exception {
-        if (numCapturesDuringLock < 1) {
-            throw new IllegalArgumentException("numCapturesBeforeLock must be no less than 1");
-        }
-        if (VERBOSE) {
-            Log.v(TAG, "Camera " + mCamera.getId() + ": Testing auto AE mode and lock for mode "
-                    + aeMode + " with " + numCapturesDuringLock + " captures before lock");
-        }
-
-        final int NUM_CAPTURES_BEFORE_LOCK = 2;
-        SimpleCaptureCallback listener =  new SimpleCaptureCallback();
-
-        CaptureResult[] resultsDuringLock = new CaptureResult[numCapturesDuringLock];
-
-        // Reset the AE lock to OFF, since we are reusing this builder many times
-        requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
-
-        // Just send several captures with auto AE, lock off.
-        CaptureRequest request = requestBuilder.build();
-        for (int i = 0; i < NUM_CAPTURES_BEFORE_LOCK; i++) {
-            mSession.capture(request, listener, mHandler);
-        }
-        waitForNumResults(listener, NUM_CAPTURES_BEFORE_LOCK);
-
-        // Then fire several capture to lock the AE.
-        requestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
-
-        int requestCount = captureRequestsSynchronized(
-                requestBuilder.build(), numCapturesDuringLock, listener, mHandler);
-
-        int[] sensitivities = new int[numCapturesDuringLock];
-        long[] expTimes = new long[numCapturesDuringLock];
-        Arrays.fill(sensitivities, -1);
-        Arrays.fill(expTimes, -1L);
-
-        // Get the AE lock on result and validate the exposure values.
-        waitForNumResults(listener, requestCount - numCapturesDuringLock);
-        for (int i = 0; i < resultsDuringLock.length; i++) {
-            resultsDuringLock[i] = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        }
-
-        for (int i = 0; i < numCapturesDuringLock; i++) {
-            mCollector.expectKeyValueEquals(
-                    resultsDuringLock[i], CaptureResult.CONTROL_AE_LOCK, true);
-        }
-
-        // Can't read manual sensor/exposure settings without manual sensor
-        if (mStaticInfo.isCapabilitySupported(
-                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-            int sensitivityLocked =
-                    getValueNotNull(resultsDuringLock[0], CaptureResult.SENSOR_SENSITIVITY);
-            long expTimeLocked =
-                    getValueNotNull(resultsDuringLock[0], CaptureResult.SENSOR_EXPOSURE_TIME);
-            for (int i = 1; i < resultsDuringLock.length; i++) {
-                mCollector.expectKeyValueEquals(
-                        resultsDuringLock[i], CaptureResult.SENSOR_EXPOSURE_TIME, expTimeLocked);
-                mCollector.expectKeyValueEquals(
-                        resultsDuringLock[i], CaptureResult.SENSOR_SENSITIVITY, sensitivityLocked);
-            }
-        }
-    }
-
-    /**
-     * Iterate through exposure times and sensitivities for manual AE control.
-     * <p>
-     * Use single request rather than repeating request to test manual exposure
-     * value change per frame control.
-     * </p>
-     */
-    private void aeManualControlTest()
-            throws Exception {
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-        requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF);
-        configurePreviewOutput(requestBuilder);
-        SimpleCaptureCallback listener =  new SimpleCaptureCallback();
-
-        long[] expTimes = getExposureTimeTestValues();
-        int[] sensitivities = getSensitivityTestValues();
-        // Submit single request at a time, then verify the result.
-        for (int i = 0; i < expTimes.length; i++) {
-            for (int j = 0; j < sensitivities.length; j++) {
-                if (VERBOSE) {
-                    Log.v(TAG, "Camera " + mCamera.getId() + ": Testing sensitivity "
-                            + sensitivities[j] + ", exposure time " + expTimes[i] + "ns");
-                }
-
-                changeExposure(requestBuilder, expTimes[i], sensitivities[j]);
-                mSession.capture(requestBuilder.build(), listener, mHandler);
-
-                // make sure timeout is long enough for long exposure time
-                long timeout = WAIT_FOR_RESULT_TIMEOUT_MS + expTimes[i];
-                CaptureResult result = listener.getCaptureResult(timeout);
-                long resultExpTime = getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
-                int resultSensitivity = getValueNotNull(result, CaptureResult.SENSOR_SENSITIVITY);
-                validateExposureTime(expTimes[i], resultExpTime);
-                validateSensitivity(sensitivities[j], resultSensitivity);
-                validateFrameDurationForCapture(result);
-            }
-        }
-        // TODO: Add another case to test where we can submit all requests, then wait for
-        // results, which will hide the pipeline latency. this is not only faster, but also
-        // test high speed per frame control and synchronization.
-    }
-
-
-    /**
-     * Verify black level lock control.
-     */
-    private void verifyBlackLevelLockResults(SimpleCaptureCallback listener, int numFramesVerified,
-            int maxLockOffCnt) throws Exception {
-        int noLockCnt = 0;
-        for (int i = 0; i < numFramesVerified; i++) {
-            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            Boolean blackLevelLock = result.get(CaptureResult.BLACK_LEVEL_LOCK);
-            assertNotNull("Black level lock result shouldn't be null", blackLevelLock);
-
-            // Count the lock == false result, which could possibly occur at most once.
-            if (blackLevelLock == false) {
-                noLockCnt++;
-            }
-
-            if(VERBOSE) {
-                Log.v(TAG, "Black level lock result: " + blackLevelLock);
-            }
-        }
-        assertTrue("Black level lock OFF occurs " + noLockCnt + " times,  expect at most "
-                + maxLockOffCnt + " for camera " + mCamera.getId(), noLockCnt <= maxLockOffCnt);
-    }
-
-    /**
-     * Verify shading map for different shading modes.
-     */
-    private void verifyShadingMap(SimpleCaptureCallback listener, int numFramesVerified,
-            int shadingMode) throws Exception {
-
-        for (int i = 0; i < numFramesVerified; i++) {
-            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            mCollector.expectEquals("Shading mode result doesn't match request",
-                    shadingMode, result.get(CaptureResult.SHADING_MODE));
-            LensShadingMap mapObj = result.get(
-                    CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
-            assertNotNull("Map object must not be null", mapObj);
-            int numElementsInMap = mapObj.getGainFactorCount();
-            float[] map = new float[numElementsInMap];
-            mapObj.copyGainFactors(map, /*offset*/0);
-            assertNotNull("Map must not be null", map);
-            assertFalse(String.format(
-                    "Map size %d should be less than %d", numElementsInMap, MAX_SHADING_MAP_SIZE),
-                    numElementsInMap >= MAX_SHADING_MAP_SIZE);
-            assertFalse(String.format("Map size %d should be no less than %d", numElementsInMap,
-                    MIN_SHADING_MAP_SIZE), numElementsInMap < MIN_SHADING_MAP_SIZE);
-
-            if (shadingMode == CaptureRequest.SHADING_MODE_FAST ||
-                    shadingMode == CaptureRequest.SHADING_MODE_HIGH_QUALITY) {
-                // shading mode is FAST or HIGH_QUALITY, expect to receive a map with all
-                // elements >= 1.0f
-
-                int badValueCnt = 0;
-                // Detect the bad values of the map data.
-                for (int j = 0; j < numElementsInMap; j++) {
-                    if (Float.isNaN(map[j]) || map[j] < 1.0f) {
-                        badValueCnt++;
-                    }
-                }
-                assertEquals("Number of value in the map is " + badValueCnt + " out of "
-                        + numElementsInMap, /*expected*/0, /*actual*/badValueCnt);
-            } else if (shadingMode == CaptureRequest.SHADING_MODE_OFF) {
-                float[] unityMap = new float[numElementsInMap];
-                Arrays.fill(unityMap, 1.0f);
-                // shading mode is OFF, expect to receive a unity map.
-                assertTrue("Result map " + Arrays.toString(map) + " must be an unity map",
-                        Arrays.equals(unityMap, map));
-            }
-        }
-    }
-
-    /**
-     * Test face detection for a camera.
-     */
-    private void faceDetectionTestByCamera() throws Exception {
-        int[] faceDetectModes = mStaticInfo.getAvailableFaceDetectModesChecked();
-
-        SimpleCaptureCallback listener;
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
-        for (int mode : faceDetectModes) {
-            requestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, mode);
-            if (VERBOSE) {
-                Log.v(TAG, "Start testing face detection mode " + mode);
-            }
-
-            // Create a new listener for each run to avoid the results from one run spill
-            // into another run.
-            listener = new SimpleCaptureCallback();
-            startPreview(requestBuilder, maxPreviewSz, listener);
-            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-            verifyFaceDetectionResults(listener, NUM_FACE_DETECTION_FRAMES_VERIFIED, mode);
-        }
-
-        stopPreview();
-    }
-
-    /**
-     * Verify face detection results for different face detection modes.
-     *
-     * @param listener The listener to get capture result
-     * @param numFramesVerified Number of results to be verified
-     * @param faceDetectionMode Face detection mode to be verified against
-     */
-    private void verifyFaceDetectionResults(SimpleCaptureCallback listener, int numFramesVerified,
-            int faceDetectionMode) {
-        for (int i = 0; i < numFramesVerified; i++) {
-            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            mCollector.expectEquals("Result face detection mode should match the request",
-                    faceDetectionMode, result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE));
-
-            Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
-            List<Integer> faceIds = new ArrayList<Integer>(faces.length);
-            List<Integer> faceScores = new ArrayList<Integer>(faces.length);
-            if (faceDetectionMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_OFF) {
-                mCollector.expectEquals("Number of detection faces should always 0 for OFF mode",
-                        0, faces.length);
-            } else if (faceDetectionMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_SIMPLE) {
-                for (Face face : faces) {
-                    mCollector.expectNotNull("Face rectangle shouldn't be null", face.getBounds());
-                    faceScores.add(face.getScore());
-                    mCollector.expectTrue("Face id is expected to be -1 for SIMPLE mode",
-                            face.getId() == Face.ID_UNSUPPORTED);
-                }
-            } else if (faceDetectionMode == CaptureResult.STATISTICS_FACE_DETECT_MODE_FULL) {
-                if (VERBOSE) {
-                    Log.v(TAG, "Number of faces detected: " + faces.length);
-                }
-
-                for (Face face : faces) {
-                    Rect faceBound;
-                    boolean faceRectAvailable =  mCollector.expectTrue("Face rectangle "
-                            + "shouldn't be null", face.getBounds() != null);
-                    if (!faceRectAvailable) {
-                        continue;
-                    }
-                    faceBound = face.getBounds();
-
-                    faceScores.add(face.getScore());
-                    faceIds.add(face.getId());
-
-                    mCollector.expectTrue("Face id is shouldn't be -1 for FULL mode",
-                            face.getId() != Face.ID_UNSUPPORTED);
-                    boolean leftEyeAvailable =
-                            mCollector.expectTrue("Left eye position shouldn't be null",
-                                    face.getLeftEyePosition() != null);
-                    boolean rightEyeAvailable =
-                            mCollector.expectTrue("Right eye position shouldn't be null",
-                                    face.getRightEyePosition() != null);
-                    boolean mouthAvailable =
-                            mCollector.expectTrue("Mouth position shouldn't be null",
-                            face.getMouthPosition() != null);
-                    // Eyes/mouth position should be inside of the face rect.
-                    if (leftEyeAvailable) {
-                        Point leftEye = face.getLeftEyePosition();
-                        mCollector.expectTrue("Left eye " + leftEye + "should be"
-                                + "inside of face rect " + faceBound,
-                                faceBound.contains(leftEye.x, leftEye.y));
-                    }
-                    if (rightEyeAvailable) {
-                        Point rightEye = face.getRightEyePosition();
-                        mCollector.expectTrue("Right eye " + rightEye + "should be"
-                                + "inside of face rect " + faceBound,
-                                faceBound.contains(rightEye.x, rightEye.y));
-                    }
-                    if (mouthAvailable) {
-                        Point mouth = face.getMouthPosition();
-                        mCollector.expectTrue("Mouth " + mouth +  " should be inside of"
-                                + " face rect " + faceBound,
-                                faceBound.contains(mouth.x, mouth.y));
-                    }
-                }
-            }
-            mCollector.expectValuesInRange("Face scores are invalid", faceIds,
-                    Face.SCORE_MIN, Face.SCORE_MAX);
-            mCollector.expectValuesUnique("Face ids are invalid", faceIds);
-        }
-    }
-
-    /**
-     * Test tone map mode and result by camera
-     */
-    private void toneMapTestByCamera() throws Exception {
-        if (!mStaticInfo.isManualToneMapSupported()) {
-            return;
-        }
-
-        SimpleCaptureCallback listener;
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0); // Max preview size.
-
-        int[] toneMapModes = mStaticInfo.getAvailableToneMapModesChecked();
-        for (int mode : toneMapModes) {
-            requestBuilder.set(CaptureRequest.TONEMAP_MODE, mode);
-            if (VERBOSE) {
-                Log.v(TAG, "Testing tonemap mode " + mode);
-            }
-
-            if (mode == CaptureRequest.TONEMAP_MODE_CONTRAST_CURVE) {
-                TonemapCurve tcLinear = new TonemapCurve(
-                        TONEMAP_CURVE_LINEAR, TONEMAP_CURVE_LINEAR, TONEMAP_CURVE_LINEAR);
-                requestBuilder.set(CaptureRequest.TONEMAP_CURVE, tcLinear);
-                // Create a new listener for each run to avoid the results from one run spill
-                // into another run.
-                listener = new SimpleCaptureCallback();
-                startPreview(requestBuilder, maxPreviewSz, listener);
-                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-                verifyToneMapModeResults(listener, NUM_FRAMES_VERIFIED, mode,
-                        TONEMAP_CURVE_LINEAR);
-
-                TonemapCurve tcSrgb = new TonemapCurve(
-                        TONEMAP_CURVE_SRGB, TONEMAP_CURVE_SRGB, TONEMAP_CURVE_SRGB);
-                requestBuilder.set(CaptureRequest.TONEMAP_CURVE, tcSrgb);
-                // Create a new listener for each run to avoid the results from one run spill
-                // into another run.
-                listener = new SimpleCaptureCallback();
-                startPreview(requestBuilder, maxPreviewSz, listener);
-                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-                verifyToneMapModeResults(listener, NUM_FRAMES_VERIFIED, mode,
-                        TONEMAP_CURVE_SRGB);
-            } else {
-                // Create a new listener for each run to avoid the results from one run spill
-                // into another run.
-                listener = new SimpleCaptureCallback();
-                startPreview(requestBuilder, maxPreviewSz, listener);
-                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-                verifyToneMapModeResults(listener, NUM_FRAMES_VERIFIED, mode,
-                        /*inputToneCurve*/null);
-            }
-        }
-
-        stopPreview();
-    }
-
-    /**
-     * Verify tonemap results.
-     * <p>
-     * Assumes R,G,B channels use the same tone curve
-     * </p>
-     *
-     * @param listener The capture listener used to get the capture results
-     * @param numFramesVerified Number of results to be verified
-     * @param tonemapMode Tonemap mode to verify
-     * @param inputToneCurve Tonemap curve used by all 3 channels, ignored when
-     * map mode is not CONTRAST_CURVE.
-     */
-    private void verifyToneMapModeResults(SimpleCaptureCallback listener, int numFramesVerified,
-            int tonemapMode, float[] inputToneCurve) {
-        final int MIN_TONEMAP_CURVE_POINTS = 2;
-        final Float ZERO = new Float(0);
-        final Float ONE = new Float(1.0f);
-
-        int maxCurvePoints = mStaticInfo.getMaxTonemapCurvePointChecked();
-        for (int i = 0; i < numFramesVerified; i++) {
-            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            mCollector.expectEquals("Capture result tonemap mode should match request", tonemapMode,
-                    result.get(CaptureResult.TONEMAP_MODE));
-            TonemapCurve tc = getValueNotNull(result, CaptureResult.TONEMAP_CURVE);
-            int pointCount = tc.getPointCount(TonemapCurve.CHANNEL_RED);
-            float[] mapRed = new float[pointCount * TonemapCurve.POINT_SIZE];
-            pointCount = tc.getPointCount(TonemapCurve.CHANNEL_GREEN);
-            float[] mapGreen = new float[pointCount * TonemapCurve.POINT_SIZE];
-            pointCount = tc.getPointCount(TonemapCurve.CHANNEL_BLUE);
-            float[] mapBlue = new float[pointCount * TonemapCurve.POINT_SIZE];
-            tc.copyColorCurve(TonemapCurve.CHANNEL_RED, mapRed, 0);
-            tc.copyColorCurve(TonemapCurve.CHANNEL_GREEN, mapGreen, 0);
-            tc.copyColorCurve(TonemapCurve.CHANNEL_BLUE, mapBlue, 0);
-            if (tonemapMode == CaptureResult.TONEMAP_MODE_CONTRAST_CURVE) {
-                /**
-                 * TODO: need figure out a good way to measure the difference
-                 * between request and result, as they may have different array
-                 * size.
-                 */
-            }
-
-            // Tonemap curve result availability and basic sanity check for all modes.
-            mCollector.expectValuesInRange("Tonemap curve red values are out of range",
-                    CameraTestUtils.toObject(mapRed), /*min*/ZERO, /*max*/ONE);
-            mCollector.expectInRange("Tonemap curve red length is out of range",
-                    mapRed.length, MIN_TONEMAP_CURVE_POINTS, maxCurvePoints * 2);
-            mCollector.expectValuesInRange("Tonemap curve green values are out of range",
-                    CameraTestUtils.toObject(mapGreen), /*min*/ZERO, /*max*/ONE);
-            mCollector.expectInRange("Tonemap curve green length is out of range",
-                    mapGreen.length, MIN_TONEMAP_CURVE_POINTS, maxCurvePoints * 2);
-            mCollector.expectValuesInRange("Tonemap curve blue values are out of range",
-                    CameraTestUtils.toObject(mapBlue), /*min*/ZERO, /*max*/ONE);
-            mCollector.expectInRange("Tonemap curve blue length is out of range",
-                    mapBlue.length, MIN_TONEMAP_CURVE_POINTS, maxCurvePoints * 2);
-        }
-    }
-
-    /**
-     * Test awb mode control.
-     * <p>
-     * Test each supported AWB mode, verify the AWB mode in capture result
-     * matches request. When AWB is locked, the color correction gains and
-     * transform should remain unchanged.
-     * </p>
-     */
-    private void awbModeAndLockTestByCamera() throws Exception {
-        int[] awbModes = mStaticInfo.getAwbAvailableModesChecked();
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        startPreview(requestBuilder, maxPreviewSize, /*listener*/null);
-
-        for (int mode : awbModes) {
-            SimpleCaptureCallback listener;
-            requestBuilder.set(CaptureRequest.CONTROL_AWB_MODE, mode);
-            listener = new SimpleCaptureCallback();
-            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
-            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-            // Verify AWB mode in capture result.
-            verifyCaptureResultForKey(CaptureResult.CONTROL_AWB_MODE, mode, listener,
-                    NUM_FRAMES_VERIFIED);
-
-            if (mode == CameraMetadata.CONTROL_AWB_MODE_AUTO) {
-                // Verify color correction transform and gains stay unchanged after a lock.
-                requestBuilder.set(CaptureRequest.CONTROL_AWB_LOCK, true);
-                listener = new SimpleCaptureCallback();
-                mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
-                waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-                if (mStaticInfo.areKeysAvailable(CaptureResult.CONTROL_AWB_STATE)) {
-                    waitForResultValue(listener, CaptureResult.CONTROL_AWB_STATE,
-                            CaptureResult.CONTROL_AWB_STATE_LOCKED, NUM_RESULTS_WAIT_TIMEOUT);
-                }
-
-            }
-            verifyAwbCaptureResultUnchanged(listener, NUM_FRAMES_VERIFIED);
-        }
-    }
-
-    private void verifyAwbCaptureResultUnchanged(SimpleCaptureCallback listener,
-            int numFramesVerified) {
-        // Skip check if cc gains/transform/mode are not available
-        if (!mStaticInfo.areKeysAvailable(
-                CaptureResult.COLOR_CORRECTION_GAINS,
-                CaptureResult.COLOR_CORRECTION_TRANSFORM,
-                CaptureResult.COLOR_CORRECTION_MODE)) {
-            return;
-        }
-
-        CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        RggbChannelVector lockedGains =
-                getValueNotNull(result, CaptureResult.COLOR_CORRECTION_GAINS);
-        ColorSpaceTransform lockedTransform =
-                getValueNotNull(result, CaptureResult.COLOR_CORRECTION_TRANSFORM);
-
-        for (int i = 0; i < numFramesVerified; i++) {
-            result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            // Color correction mode check is skipped here, as it is checked in colorCorrectionTest.
-            validateColorCorrectionResult(result, result.get(CaptureResult.COLOR_CORRECTION_MODE));
-
-            RggbChannelVector gains = getValueNotNull(result, CaptureResult.COLOR_CORRECTION_GAINS);
-            ColorSpaceTransform transform =
-                    getValueNotNull(result, CaptureResult.COLOR_CORRECTION_TRANSFORM);
-            mCollector.expectEquals("Color correction gains should remain unchanged after awb lock",
-                    lockedGains, gains);
-            mCollector.expectEquals("Color correction transform should remain unchanged after"
-                    + " awb lock", lockedTransform, transform);
-        }
-    }
-
-    /**
-     * Test AF mode control.
-     * <p>
-     * Test all supported AF modes, verify the AF mode in capture result matches
-     * request. When AF mode is one of the CONTROL_AF_MODE_CONTINUOUS_* mode,
-     * verify if the AF can converge to PASSIVE_FOCUSED or PASSIVE_UNFOCUSED
-     * state within certain amount of frames.
-     * </p>
-     */
-    private void afModeTestByCamera() throws Exception {
-        int[] afModes = mStaticInfo.getAfAvailableModesChecked();
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        startPreview(requestBuilder, maxPreviewSize, /*listener*/null);
-
-        for (int mode : afModes) {
-            SimpleCaptureCallback listener;
-            requestBuilder.set(CaptureRequest.CONTROL_AF_MODE, mode);
-            listener = new SimpleCaptureCallback();
-            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
-            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-            // Verify AF mode in capture result.
-            verifyCaptureResultForKey(CaptureResult.CONTROL_AF_MODE, mode, listener,
-                    NUM_FRAMES_VERIFIED);
-
-            // Verify AF can finish a scan for CONTROL_AF_MODE_CONTINUOUS_* modes.
-            // 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() &&
-                    (mode == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE ||
-                    mode == CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_VIDEO)) {
-                List<Integer> afStateList = new ArrayList<Integer>();
-                afStateList.add(CaptureResult.CONTROL_AF_STATE_PASSIVE_FOCUSED);
-                afStateList.add(CaptureResult.CONTROL_AF_STATE_PASSIVE_UNFOCUSED);
-                waitForAnyResultValue(listener, CaptureResult.CONTROL_AF_STATE, afStateList,
-                        NUM_RESULTS_WAIT_TIMEOUT);
-            }
-        }
-    }
-
-    /**
-     * Test video and optical stabilizations if they are supported by a given camera.
-     */
-    private void stabilizationTestByCamera() throws Exception {
-        // video stabilization test.
-        List<Key<?>> keys = mStaticInfo.getCharacteristics().getKeys();
-
-        int[] videoStabModes = (keys.contains(CameraCharacteristics.
-                CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES)) ?
-                mStaticInfo.getAvailableVideoStabilizationModesChecked() : new int[0];
-        int[] opticalStabModes = (keys.contains(
-                CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION)) ?
-                mStaticInfo.getAvailableOpticalStabilizationChecked() : new int[0];
-
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        SimpleCaptureCallback listener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, maxPreviewSize, listener);
-
-        for (int mode : videoStabModes) {
-            listener = new SimpleCaptureCallback();
-            requestBuilder.set(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE, mode);
-            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
-            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-            verifyCaptureResultForKey(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE, mode,
-                    listener, NUM_FRAMES_VERIFIED);
-        }
-
-        for (int mode : opticalStabModes) {
-            listener = new SimpleCaptureCallback();
-            requestBuilder.set(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE, mode);
-            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
-            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-            verifyCaptureResultForKey(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE, mode,
-                    listener, NUM_FRAMES_VERIFIED);
-        }
-
-        stopPreview();
-    }
-
-    private void digitalZoomTestByCamera(Size previewSize) throws Exception {
-        final int ZOOM_STEPS = 15;
-        final PointF[] TEST_ZOOM_CENTERS;
-
-        final int croppingType = mStaticInfo.getScalerCroppingTypeChecked();
-        if (croppingType ==
-                CameraCharacteristics.SCALER_CROPPING_TYPE_FREEFORM) {
-            TEST_ZOOM_CENTERS = new PointF[] {
-                new PointF(0.5f, 0.5f),   // Center point
-                new PointF(0.25f, 0.25f), // top left corner zoom, minimal zoom: 2x
-                new PointF(0.75f, 0.25f), // top right corner zoom, minimal zoom: 2x
-                new PointF(0.25f, 0.75f), // bottom left corner zoom, minimal zoom: 2x
-                new PointF(0.75f, 0.75f), // bottom right corner zoom, minimal zoom: 2x
-            };
-
-            if (VERBOSE) {
-                Log.v(TAG, "Testing zoom with CROPPING_TYPE = FREEFORM");
-            }
-        } else {
-            // CENTER_ONLY
-            TEST_ZOOM_CENTERS = new PointF[] {
-                    new PointF(0.5f, 0.5f),   // Center point
-            };
-
-            if (VERBOSE) {
-                Log.v(TAG, "Testing zoom with CROPPING_TYPE = CENTER_ONLY");
-            }
-        }
-
-        final float maxZoom = mStaticInfo.getAvailableMaxDigitalZoomChecked();
-        final Rect activeArraySize = mStaticInfo.getActiveArraySizeChecked();
-        Rect[] cropRegions = new Rect[ZOOM_STEPS];
-        MeteringRectangle[][] expectRegions = new MeteringRectangle[ZOOM_STEPS][];
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        SimpleCaptureCallback listener = new SimpleCaptureCallback();
-
-        updatePreviewSurface(previewSize);
-        configurePreviewOutput(requestBuilder);
-
-        CaptureRequest[] requests = new CaptureRequest[ZOOM_STEPS];
-
-        // Set algorithm regions to full active region
-        // TODO: test more different 3A regions
-        final MeteringRectangle[] defaultMeteringRect = new MeteringRectangle[] {
-                new MeteringRectangle (
-                        /*x*/0, /*y*/0, activeArraySize.width(), activeArraySize.height(),
-                        /*meteringWeight*/1)
-        };
-
-        for (int algo = 0; algo < NUM_ALGORITHMS; algo++) {
-            update3aRegion(requestBuilder, algo,  defaultMeteringRect);
-        }
-
-        final int CAPTURE_SUBMIT_REPEAT;
-        {
-            int maxLatency = mStaticInfo.getSyncMaxLatency();
-            if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
-                CAPTURE_SUBMIT_REPEAT = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY + 1;
-            } else {
-                CAPTURE_SUBMIT_REPEAT = maxLatency + 1;
-            }
-        }
-
-        if (VERBOSE) {
-            Log.v(TAG, "Testing zoom with CAPTURE_SUBMIT_REPEAT = " + CAPTURE_SUBMIT_REPEAT);
-        }
-
-        for (PointF center : TEST_ZOOM_CENTERS) {
-            Rect previousCrop = null;
-
-            for (int i = 0; i < ZOOM_STEPS; i++) {
-                /*
-                 * Submit capture request
-                 */
-                float zoomFactor = (float) (1.0f + (maxZoom - 1.0) * i / ZOOM_STEPS);
-                cropRegions[i] = getCropRegionForZoom(zoomFactor, center, maxZoom, activeArraySize);
-                if (VERBOSE) {
-                    Log.v(TAG, "Testing Zoom for factor " + zoomFactor + " and center " +
-                            center + " The cropRegion is " + cropRegions[i] +
-                            " Preview size is " + previewSize);
-                }
-                requestBuilder.set(CaptureRequest.SCALER_CROP_REGION, cropRegions[i]);
-                requests[i] = requestBuilder.build();
-                for (int j = 0; j < CAPTURE_SUBMIT_REPEAT; ++j) {
-                    if (VERBOSE) {
-                        Log.v(TAG, "submit crop region " + cropRegions[i]);
-                    }
-                    mSession.capture(requests[i], listener, mHandler);
-                }
-
-                /*
-                 * Validate capture result
-                 */
-                waitForNumResults(listener, CAPTURE_SUBMIT_REPEAT - 1); // Drop first few frames
-                CaptureResult result = listener.getCaptureResultForRequest(
-                        requests[i], NUM_RESULTS_WAIT_TIMEOUT);
-                Rect cropRegion = getValueNotNull(result, CaptureResult.SCALER_CROP_REGION);
-
-                /*
-                 * Validate resulting crop regions
-                 */
-                if (previousCrop != null) {
-                    Rect currentCrop = cropRegion;
-                    mCollector.expectTrue(String.format(
-                            "Crop region should shrink or stay the same " +
-                                    "(previous = %s, current = %s)",
-                                    previousCrop, currentCrop),
-                            previousCrop.equals(currentCrop) ||
-                                (previousCrop.width() > currentCrop.width() &&
-                                 previousCrop.height() > currentCrop.height()));
-                }
-
-                if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
-                    mCollector.expectRectsAreSimilar(
-                            "Request and result crop region should be similar",
-                            cropRegions[i], cropRegion, CROP_REGION_ERROR_PERCENT_DELTA);
-                }
-
-                if (croppingType == SCALER_CROPPING_TYPE_CENTER_ONLY) {
-                    mCollector.expectRectCentered(
-                            "Result crop region should be centered inside the active array",
-                            new Size(activeArraySize.width(), activeArraySize.height()),
-                            cropRegion, CROP_REGION_ERROR_PERCENT_CENTERED);
-                }
-
-                /*
-                 * Validate resulting metering regions
-                 */
-
-                // Use the actual reported crop region to calculate the resulting metering region
-                expectRegions[i] = getExpectedOutputRegion(
-                        /*requestRegion*/defaultMeteringRect,
-                        /*cropRect*/     cropRegion);
-
-                // Verify Output 3A region is intersection of input 3A region and crop region
-                for (int algo = 0; algo < NUM_ALGORITHMS; algo++) {
-                    validate3aRegion(result, algo, expectRegions[i]);
-                }
-
-                previousCrop = cropRegion;
-            }
-
-            if (maxZoom > 1.0f) {
-                mCollector.expectTrue(
-                        String.format("Most zoomed-in crop region should be smaller" +
-                                        "than active array w/h" +
-                                        "(last crop = %s, active array = %s)",
-                                        previousCrop, activeArraySize),
-                            (previousCrop.width() < activeArraySize.width() &&
-                             previousCrop.height() < activeArraySize.height()));
-            }
-        }
-    }
-
-    private void digitalZoomPreviewCombinationTestByCamera() throws Exception {
-        final double ASPECT_RATIO_THRESHOLD = 0.001;
-        List<Double> aspectRatiosTested = new ArrayList<Double>();
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        aspectRatiosTested.add((double)(maxPreviewSize.getWidth()) / maxPreviewSize.getHeight());
-
-        for (Size size : mOrderedPreviewSizes) {
-            // Max preview size was already tested in testDigitalZoom test. skip it.
-            if (size.equals(maxPreviewSize)) {
-                continue;
-            }
-
-            // Only test the largest size for each aspect ratio.
-            double aspectRatio = (double)(size.getWidth()) / size.getHeight();
-            if (isAspectRatioContained(aspectRatiosTested, aspectRatio, ASPECT_RATIO_THRESHOLD)) {
-                continue;
-            }
-
-            if (VERBOSE) {
-                Log.v(TAG, "Test preview size " + size.toString() + " digital zoom");
-            }
-
-            aspectRatiosTested.add(aspectRatio);
-            digitalZoomTestByCamera(size);
-        }
-    }
-
-    private static boolean isAspectRatioContained(List<Double> aspectRatioList,
-            double aspectRatio, double delta) {
-        for (Double ratio : aspectRatioList) {
-            if (Math.abs(ratio - aspectRatio) < delta) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private void sceneModeTestByCamera() throws Exception {
-        int[] sceneModes = mStaticInfo.getAvailableSceneModesChecked();
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        SimpleCaptureCallback listener = new SimpleCaptureCallback();
-        requestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_USE_SCENE_MODE);
-        startPreview(requestBuilder, maxPreviewSize, listener);
-
-        for(int mode : sceneModes) {
-            requestBuilder.set(CaptureRequest.CONTROL_SCENE_MODE, mode);
-            listener = new SimpleCaptureCallback();
-            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
-            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-            verifyCaptureResultForKey(CaptureResult.CONTROL_SCENE_MODE,
-                    mode, listener, NUM_FRAMES_VERIFIED);
-            // This also serves as purpose of showing preview for NUM_FRAMES_VERIFIED
-            verifyCaptureResultForKey(CaptureResult.CONTROL_MODE,
-                    CaptureRequest.CONTROL_MODE_USE_SCENE_MODE, listener, NUM_FRAMES_VERIFIED);
-        }
-    }
-
-    private void effectModeTestByCamera() throws Exception {
-        int[] effectModes = mStaticInfo.getAvailableEffectModesChecked();
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        requestBuilder.set(CaptureRequest.CONTROL_MODE, CaptureRequest.CONTROL_MODE_AUTO);
-        SimpleCaptureCallback listener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, maxPreviewSize, listener);
-
-        for(int mode : effectModes) {
-            requestBuilder.set(CaptureRequest.CONTROL_EFFECT_MODE, mode);
-            listener = new SimpleCaptureCallback();
-            mSession.setRepeatingRequest(requestBuilder.build(), listener, mHandler);
-            waitForSettingsApplied(listener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-            verifyCaptureResultForKey(CaptureResult.CONTROL_EFFECT_MODE,
-                    mode, listener, NUM_FRAMES_VERIFIED);
-            // This also serves as purpose of showing preview for NUM_FRAMES_VERIFIED
-            verifyCaptureResultForKey(CaptureResult.CONTROL_MODE,
-                    CaptureRequest.CONTROL_MODE_AUTO, listener, NUM_FRAMES_VERIFIED);
-        }
-    }
-
-    //----------------------------------------------------------------
-    //---------Below are common functions for all tests.--------------
-    //----------------------------------------------------------------
-
-    /**
-     * Enable exposure manual control and change exposure and sensitivity and
-     * clamp the value into the supported range.
-     */
-    private void changeExposure(CaptureRequest.Builder requestBuilder,
-            long expTime, int sensitivity) {
-        // Check if the max analog sensitivity is available and no larger than max sensitivity.
-        // The max analog sensitivity is not actually used here. This is only an extra sanity check.
-        mStaticInfo.getMaxAnalogSensitivityChecked();
-
-        expTime = mStaticInfo.getExposureClampToRange(expTime);
-        sensitivity = mStaticInfo.getSensitivityClampToRange(sensitivity);
-
-        requestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CONTROL_AE_MODE_OFF);
-        requestBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, expTime);
-        requestBuilder.set(CaptureRequest.SENSOR_SENSITIVITY, sensitivity);
-    }
-    /**
-     * Enable exposure manual control and change exposure time and
-     * clamp the value into the supported range.
-     *
-     * <p>The sensitivity is set to default value.</p>
-     */
-    private void changeExposure(CaptureRequest.Builder requestBuilder, long expTime) {
-        changeExposure(requestBuilder, expTime, DEFAULT_SENSITIVITY);
-    }
-
-    /**
-     * Get the exposure time array that contains multiple exposure time steps in
-     * the exposure time range.
-     */
-    private long[] getExposureTimeTestValues() {
-        long[] testValues = new long[DEFAULT_NUM_EXPOSURE_TIME_STEPS + 1];
-        long maxExpTime = mStaticInfo.getExposureMaximumOrDefault(DEFAULT_EXP_TIME_NS);
-        long minxExpTime = mStaticInfo.getExposureMinimumOrDefault(DEFAULT_EXP_TIME_NS);
-
-        long range = maxExpTime - minxExpTime;
-        double stepSize = range / (double)DEFAULT_NUM_EXPOSURE_TIME_STEPS;
-        for (int i = 0; i < testValues.length; i++) {
-            testValues[i] = minxExpTime + (long)(stepSize * i);
-            testValues[i] = mStaticInfo.getExposureClampToRange(testValues[i]);
-        }
-
-        return testValues;
-    }
-
-    /**
-     * Generate test focus distances in range of [0, minFocusDistance] in increasing order.
-     */
-    private float[] getFocusDistanceTestValuesInOrder() {
-        float[] testValues = new float[NUM_TEST_FOCUS_DISTANCES + 1];
-        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;
-        }
-
-        return testValues;
-    }
-
-    /**
-     * Get the sensitivity array that contains multiple sensitivity steps in the
-     * sensitivity range.
-     * <p>
-     * Sensitivity number of test values is determined by
-     * {@value #DEFAULT_SENSITIVITY_STEP_SIZE} and sensitivity range, and
-     * bounded by {@value #DEFAULT_NUM_SENSITIVITY_STEPS}.
-     * </p>
-     */
-    private int[] getSensitivityTestValues() {
-        int maxSensitivity = mStaticInfo.getSensitivityMaximumOrDefault(
-                DEFAULT_SENSITIVITY);
-        int minSensitivity = mStaticInfo.getSensitivityMinimumOrDefault(
-                DEFAULT_SENSITIVITY);
-
-        int range = maxSensitivity - minSensitivity;
-        int stepSize = DEFAULT_SENSITIVITY_STEP_SIZE;
-        int numSteps = range / stepSize;
-        // Bound the test steps to avoid supper long test.
-        if (numSteps > DEFAULT_NUM_SENSITIVITY_STEPS) {
-            numSteps = DEFAULT_NUM_SENSITIVITY_STEPS;
-            stepSize = range / numSteps;
-        }
-        int[] testValues = new int[numSteps + 1];
-        for (int i = 0; i < testValues.length; i++) {
-            testValues[i] = minSensitivity + stepSize * i;
-            testValues[i] = mStaticInfo.getSensitivityClampToRange(testValues[i]);
-        }
-
-        return testValues;
-    }
-
-    /**
-     * Validate the AE manual control exposure time.
-     *
-     * <p>Exposure should be close enough, and only round down if they are not equal.</p>
-     *
-     * @param request Request exposure time
-     * @param result Result exposure time
-     */
-    private void validateExposureTime(long request, long result) {
-        long expTimeDelta = request - result;
-        // First, round down not up, second, need close enough.
-        mCollector.expectTrue("Exposture time is invalid for AE manaul control test, request: "
-                + request + " result: " + result,
-                expTimeDelta < EXPOSURE_TIME_ERROR_MARGIN_NS && expTimeDelta >= 0);
-    }
-
-    /**
-     * Validate AE manual control sensitivity.
-     *
-     * @param request Request sensitivity
-     * @param result Result sensitivity
-     */
-    private void validateSensitivity(int request, int result) {
-        int sensitivityDelta = request - result;
-        // First, round down not up, second, need close enough.
-        mCollector.expectTrue("Sensitivity is invalid for AE manaul control test, request: "
-                + request + " result: " + result,
-                sensitivityDelta < SENSITIVITY_ERROR_MARGIN && sensitivityDelta >= 0);
-    }
-
-    /**
-     * Validate frame duration for a given capture.
-     *
-     * <p>Frame duration should be longer than exposure time.</p>
-     *
-     * @param result The capture result for a given capture
-     */
-    private void validateFrameDurationForCapture(CaptureResult result) {
-        long expTime = getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
-        long frameDuration = getValueNotNull(result, CaptureResult.SENSOR_FRAME_DURATION);
-        if (VERBOSE) {
-            Log.v(TAG, "frame duration: " + frameDuration + " Exposure time: " + expTime);
-        }
-
-        mCollector.expectTrue(String.format("Frame duration (%d) should be longer than exposure"
-                + " time (%d) for a given capture", frameDuration, expTime),
-                frameDuration >= expTime);
-
-        validatePipelineDepth(result);
-    }
-
-    private <T> T getValueNotNull(CaptureResult result, CaptureResult.Key<T> key) {
-        T value = result.get(key);
-        assertNotNull("Value of Key " + key.getName() + " shouldn't be null", value);
-        return value;
-    }
-
-    /**
-     * Basic verification for the control mode capture result.
-     *
-     * @param key The capture result key to be verified against
-     * @param requestMode The request mode for this result
-     * @param listener The capture listener to get capture results
-     * @param numFramesVerified The number of capture results to be verified
-     */
-    private <T> void verifyCaptureResultForKey(CaptureResult.Key<T> key, T requestMode,
-            SimpleCaptureCallback listener, int numFramesVerified) {
-        for (int i = 0; i < numFramesVerified; i++) {
-            CaptureResult result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            validatePipelineDepth(result);
-            T resultMode = getValueNotNull(result, key);
-            if (VERBOSE) {
-                Log.v(TAG, "Expect value: " + requestMode.toString() + " result value: "
-                        + resultMode.toString());
-            }
-            mCollector.expectEquals("Key " + key.getName() + " result should match request",
-                    requestMode, resultMode);
-        }
-    }
-
-    /**
-     * Verify if the fps is slow down for given input request with certain
-     * controls inside.
-     * <p>
-     * This method selects a max preview size for each fps range, and then
-     * configure the preview stream. Preview is started with the max preview
-     * size, and then verify if the result frame duration is in the frame
-     * duration range.
-     * </p>
-     *
-     * @param requestBuilder The request builder that contains post-processing
-     *            controls that could impact the output frame rate, such as
-     *            {@link CaptureRequest.NOISE_REDUCTION_MODE}. The value of
-     *            these controls must be set to some values such that the frame
-     *            rate is not slow down.
-     * @param numFramesVerified The number of frames to be verified
-     */
-    private void verifyFpsNotSlowDown(CaptureRequest.Builder requestBuilder,
-            int numFramesVerified)  throws Exception {
-        boolean frameDurationAvailable = true;
-        // Allow a few frames for AE to settle on target FPS range
-        final int NUM_FRAME_TO_SKIP = 6;
-        float frameDurationErrorMargin = FRAME_DURATION_ERROR_MARGIN;
-        if (!mStaticInfo.areKeysAvailable(CaptureResult.SENSOR_FRAME_DURATION)) {
-            frameDurationAvailable = false;
-            // Allow a larger error margin (1.5%) for timestamps
-            frameDurationErrorMargin = 0.015f;
-        }
-
-        Range<Integer>[] fpsRanges = mStaticInfo.getAeAvailableTargetFpsRangesChecked();
-        boolean antiBandingOffIsSupported = mStaticInfo.isAntiBandingOffModeSupported();
-        Range<Integer> fpsRange;
-        SimpleCaptureCallback resultListener;
-
-        for (int i = 0; i < fpsRanges.length; i += 1) {
-            fpsRange = fpsRanges[i];
-            Size previewSz = getMaxPreviewSizeForFpsRange(fpsRange);
-            // If unable to find a preview size, then log the failure, and skip this run.
-            if (previewSz == null) {
-                if (mStaticInfo.isCapabilitySupported(
-                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                    mCollector.addMessage(String.format(
-                            "Unable to find a preview size supporting given fps range %s",
-                            fpsRange));
-                }
-                continue;
-            }
-
-            if (VERBOSE) {
-                Log.v(TAG, String.format("Test fps range %s for preview size %s",
-                        fpsRange, previewSz.toString()));
-            }
-            requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
-            // Turn off auto antibanding to avoid exposure time and frame duration interference
-            // from antibanding algorithm.
-            if (antiBandingOffIsSupported) {
-                requestBuilder.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
-                        CaptureRequest.CONTROL_AE_ANTIBANDING_MODE_OFF);
-            } else {
-                // The device doesn't implement the OFF mode, test continues. It need make sure
-                // that the antibanding algorithm doesn't slow down the fps.
-                Log.i(TAG, "OFF antibanding mode is not supported, the camera device output must" +
-                        " not slow down the frame rate regardless of its current antibanding" +
-                        " mode");
-            }
-
-            resultListener = new SimpleCaptureCallback();
-            startPreview(requestBuilder, previewSz, resultListener);
-            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-            // Wait several more frames for AE to settle on target FPS range
-            waitForNumResults(resultListener, NUM_FRAME_TO_SKIP);
-
-            long[] frameDurationRange = new long[]{
-                    (long) (1e9 / fpsRange.getUpper()), (long) (1e9 / fpsRange.getLower())};
-            long captureTime = 0, prevCaptureTime = 0;
-            for (int j = 0; j < numFramesVerified; j++) {
-                long frameDuration = frameDurationRange[0];
-                CaptureResult result =
-                        resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-                validatePipelineDepth(result);
-                if (frameDurationAvailable) {
-                    frameDuration = getValueNotNull(result, CaptureResult.SENSOR_FRAME_DURATION);
-                } else {
-                    // if frame duration is not available, check timestamp instead
-                    captureTime = getValueNotNull(result, CaptureResult.SENSOR_TIMESTAMP);
-                    if (j > 0) {
-                        frameDuration = captureTime - prevCaptureTime;
-                    }
-                    prevCaptureTime = captureTime;
-                }
-                mCollector.expectInRange(
-                        "Frame duration must be in the range of " +
-                                Arrays.toString(frameDurationRange),
-                        frameDuration,
-                        (long) (frameDurationRange[0] * (1 - frameDurationErrorMargin)),
-                        (long) (frameDurationRange[1] * (1 + frameDurationErrorMargin)));
-            }
-        }
-
-        mSession.stopRepeating();
-    }
-
-    /**
-     * Validate the pipeline depth result.
-     *
-     * @param result The capture result to get pipeline depth data
-     */
-    private void validatePipelineDepth(CaptureResult result) {
-        final byte MIN_PIPELINE_DEPTH = 1;
-        byte maxPipelineDepth = mStaticInfo.getPipelineMaxDepthChecked();
-        Byte pipelineDepth = getValueNotNull(result, CaptureResult.REQUEST_PIPELINE_DEPTH);
-        mCollector.expectInRange(String.format("Pipeline depth must be in the range of [%d, %d]",
-                MIN_PIPELINE_DEPTH, maxPipelineDepth), pipelineDepth, MIN_PIPELINE_DEPTH,
-                maxPipelineDepth);
-    }
-
-    /**
-     * Calculate the anti-flickering corrected exposure time.
-     * <p>
-     * If the input exposure time is very short (shorter than flickering
-     * boundary), which indicate the scene is bright and very likely at outdoor
-     * environment, skip the correction, as it doesn't make much sense by doing so.
-     * </p>
-     * <p>
-     * For long exposure time (larger than the flickering boundary), find the
-     * exposure time that is closest to the flickering boundary.
-     * </p>
-     *
-     * @param flickeringMode The flickering mode
-     * @param exposureTime The input exposureTime to be corrected
-     * @return anti-flickering corrected exposure time
-     */
-    private long getAntiFlickeringExposureTime(int flickeringMode, long exposureTime) {
-        if (flickeringMode != ANTI_FLICKERING_50HZ && flickeringMode != ANTI_FLICKERING_60HZ) {
-            throw new IllegalArgumentException("Input anti-flickering mode must be 50 or 60Hz");
-        }
-        long flickeringBoundary = EXPOSURE_TIME_BOUNDARY_50HZ_NS;
-        if (flickeringMode == ANTI_FLICKERING_60HZ) {
-            flickeringBoundary = EXPOSURE_TIME_BOUNDARY_60HZ_NS;
-        }
-
-        if (exposureTime <= flickeringBoundary) {
-            return exposureTime;
-        }
-
-        // Find the closest anti-flickering corrected exposure time
-        long correctedExpTime = exposureTime + (flickeringBoundary / 2);
-        correctedExpTime = correctedExpTime - (correctedExpTime % flickeringBoundary);
-        return correctedExpTime;
-    }
-
-    /**
-     * Update one 3A region in capture request builder if that region is supported. Do nothing
-     * if the specified 3A region is not supported by camera device.
-     * @param requestBuilder The request to be updated
-     * @param algoIdx The index to the algorithm. (AE: 0, AWB: 1, AF: 2)
-     * @param regions The 3A regions to be set
-     */
-    private void update3aRegion(
-            CaptureRequest.Builder requestBuilder, int algoIdx, MeteringRectangle[] regions)
-    {
-        int maxRegions;
-        CaptureRequest.Key<MeteringRectangle[]> key;
-
-        if (regions == null || regions.length == 0) {
-            throw new IllegalArgumentException("Invalid input 3A region!");
-        }
-
-        switch (algoIdx) {
-            case INDEX_ALGORITHM_AE:
-                maxRegions = mStaticInfo.getAeMaxRegionsChecked();
-                key = CaptureRequest.CONTROL_AE_REGIONS;
-                break;
-            case INDEX_ALGORITHM_AWB:
-                maxRegions = mStaticInfo.getAwbMaxRegionsChecked();
-                key = CaptureRequest.CONTROL_AWB_REGIONS;
-                break;
-            case INDEX_ALGORITHM_AF:
-                maxRegions = mStaticInfo.getAfMaxRegionsChecked();
-                key = CaptureRequest.CONTROL_AF_REGIONS;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown 3A Algorithm!");
-        }
-
-        if (maxRegions >= regions.length) {
-            requestBuilder.set(key, regions);
-        }
-    }
-
-    /**
-     * Validate one 3A region in capture result equals to expected region if that region is
-     * supported. Do nothing if the specified 3A region is not supported by camera device.
-     * @param result The capture result to be validated
-     * @param algoIdx The index to the algorithm. (AE: 0, AWB: 1, AF: 2)
-     * @param expectRegions The 3A regions expected in capture result
-     */
-    private void validate3aRegion(
-            CaptureResult result, int algoIdx, MeteringRectangle[] expectRegions)
-    {
-        int maxRegions;
-        CaptureResult.Key<MeteringRectangle[]> key;
-        MeteringRectangle[] actualRegion;
-
-        switch (algoIdx) {
-            case INDEX_ALGORITHM_AE:
-                maxRegions = mStaticInfo.getAeMaxRegionsChecked();
-                key = CaptureResult.CONTROL_AE_REGIONS;
-                break;
-            case INDEX_ALGORITHM_AWB:
-                maxRegions = mStaticInfo.getAwbMaxRegionsChecked();
-                key = CaptureResult.CONTROL_AWB_REGIONS;
-                break;
-            case INDEX_ALGORITHM_AF:
-                maxRegions = mStaticInfo.getAfMaxRegionsChecked();
-                key = CaptureResult.CONTROL_AF_REGIONS;
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown 3A Algorithm!");
-        }
-
-        if (maxRegions > 0)
-        {
-            actualRegion = getValueNotNull(result, key);
-            mCollector.expectEquals(
-                    "Expected 3A regions: " + Arrays.toString(expectRegions) +
-                    " does not match actual one: " + Arrays.toString(actualRegion),
-                    expectRegions, actualRegion);
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureResultTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureResultTest.java
deleted file mode 100644
index 61bf36c..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/CaptureResultTest.java
+++ /dev/null
@@ -1,723 +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 android.hardware.camera2.cts;
-
-import android.content.Context;
-import android.graphics.ImageFormat;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.TotalCaptureResult;
-import android.media.Image;
-import android.media.ImageReader;
-import android.os.SystemClock;
-import android.util.Pair;
-import android.util.Size;
-import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static android.hardware.camera2.cts.helpers.CameraSessionUtils.*;
-
-import android.util.Log;
-import android.view.Surface;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-public class CaptureResultTest extends Camera2AndroidTestCase {
-    private static final String TAG = "CaptureResultTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final int MAX_NUM_IMAGES = MAX_READER_IMAGES;
-    private static final int NUM_FRAMES_VERIFIED = 30;
-    private static final long WAIT_FOR_RESULT_TIMEOUT_MS = 3000;
-
-    // List that includes all public keys from CaptureResult
-    List<CaptureResult.Key<?>> mAllKeys;
-
-    // List tracking the failed test keys.
-
-    @Override
-    public void setContext(Context context) {
-        mAllKeys = getAllCaptureResultKeys();
-        super.setContext(context);
-
-        /**
-         * Workaround for mockito and JB-MR2 incompatibility
-         *
-         * Avoid java.lang.IllegalArgumentException: dexcache == null
-         * https://code.google.com/p/dexmaker/issues/detail?id=2
-         */
-        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * <p>
-     * Basic non-null check test for multiple capture results.
-     * </p>
-     * <p>
-     * When capturing many frames, some camera devices may return some results that have null keys
-     * randomly, which is an API violation and could cause application crash randomly. This test
-     * runs a typical flexible yuv capture many times, and checks if there is any null entries in
-     * a capture result.
-     * </p>
-     */
-    public void testCameraCaptureResultAllKeys() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-                // Create image reader and surface.
-                Size size = mOrderedPreviewSizes.get(0);
-                createDefaultImageReader(size, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
-                        new ImageDropperListener());
-
-                // Configure output streams.
-                List<Surface> outputSurfaces = new ArrayList<Surface>(1);
-                outputSurfaces.add(mReaderSurface);
-                createSession(outputSurfaces);
-
-                CaptureRequest.Builder requestBuilder =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                assertNotNull("Failed to create capture request", requestBuilder);
-                requestBuilder.addTarget(mReaderSurface);
-
-                // Start capture
-                SimpleCaptureCallback captureListener = new SimpleCaptureCallback();
-                startCapture(requestBuilder.build(), /*repeating*/true, captureListener, mHandler);
-
-                // Get the waived keys for current camera device
-                List<CaptureResult.Key<?>> waiverkeys = getWaiverKeysForCamera();
-
-                // Verify results
-                validateCaptureResult(captureListener, waiverkeys, requestBuilder,
-                        NUM_FRAMES_VERIFIED);
-
-                stopCapture(/*fast*/false);
-            } finally {
-                closeDevice(id);
-                closeDefaultImageReader();
-            }
-        }
-    }
-
-    /**
-     * Check partial results conform to its specification.
-     * <p>
-     * The test is skipped if partial result is not supported on device. </p>
-     * <p>Test summary:<ul>
-     * <li>1. Number of partial results is less than or equal to
-     * {@link CameraCharacteristics#REQUEST_PARTIAL_RESULT_COUNT}.
-     * <li>2. Each key appeared in partial results must be unique across all partial results.
-     * <li>3. All keys appeared in partial results must be present in TotalCaptureResult
-     * <li>4. Also test onCaptureComplete callback always happen after onCaptureStart or
-     * onCaptureProgressed callbacks.
-     * </ul></p>
-     */
-    public void testPartialResult() throws Exception {
-        final int NUM_FRAMES_TESTED = 30;
-        final int WAIT_FOR_RESULT_TIMOUT_MS = 2000;
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-
-                // Skip the test if partial result is not supported
-                int partialResultCount = mStaticInfo.getPartialResultCount();
-                if (partialResultCount == 1) {
-                    continue;
-                }
-
-                // Create image reader and surface.
-                Size size = mOrderedPreviewSizes.get(0);
-                createDefaultImageReader(size, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
-                        new ImageDropperListener());
-
-                // Configure output streams.
-                List<Surface> outputSurfaces = new ArrayList<Surface>(1);
-                outputSurfaces.add(mReaderSurface);
-                createSession(outputSurfaces);
-
-                CaptureRequest.Builder requestBuilder =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                assertNotNull("Failed to create capture request", requestBuilder);
-                requestBuilder.addTarget(mReaderSurface);
-                TotalAndPartialResultListener listener =
-                        new TotalAndPartialResultListener();
-
-                // Start capture
-                for (Integer frame = 0; frame < NUM_FRAMES_TESTED; frame++) {
-                    // Set a different tag for each request so the listener can group
-                    // partial results by each request
-                    requestBuilder.setTag(frame);
-                    startCapture(
-                            requestBuilder.build(), /*repeating*/false,
-                            listener, mHandler);
-                }
-
-                // Verify capture results
-                for (int frame = 0; frame < NUM_FRAMES_TESTED; frame++) {
-                    Pair<TotalCaptureResult, List<CaptureResult>> resultPair =
-                            listener.getCaptureResultPairs(WAIT_FOR_RESULT_TIMOUT_MS);
-
-                    List<CaptureResult> partialResults = resultPair.second;
-
-                    if (partialResults == null) {
-                        // HAL only sends total result is legal
-                        partialResults = new ArrayList<>();
-                    }
-
-                    TotalCaptureResult totalResult = resultPair.first;
-
-                    mCollector.expectLessOrEqual("Too many partial results",
-                            partialResultCount, partialResults.size());
-                    Set<CaptureResult.Key<?>> appearedPartialKeys =
-                            new HashSet<CaptureResult.Key<?>>();
-                    for (CaptureResult partialResult : partialResults) {
-                        List<CaptureResult.Key<?>> partialKeys = partialResult.getKeys();
-                        mCollector.expectValuesUnique("Partial result keys: ", partialKeys);
-                        for (CaptureResult.Key<?> key : partialKeys) {
-                            mCollector.expectTrue(
-                                    String.format("Key %s appears in multiple partial results",
-                                            key.getName()),
-                                    !appearedPartialKeys.contains(key));
-                        }
-                        appearedPartialKeys.addAll(partialKeys);
-                    }
-
-                    // Test total result against the partial results
-                    List<CaptureResult.Key<?>> totalResultKeys = totalResult.getKeys();
-                    mCollector.expectTrue(
-                            "TotalCaptureResult must be a super set of partial capture results",
-                            totalResultKeys.containsAll(appearedPartialKeys));
-
-                    List<CaptureResult> totalResultPartials = totalResult.getPartialResults();
-                    mCollector.expectEquals("TotalCaptureResult's partial results must match " +
-                            "the ones observed by #onCaptureProgressed",
-                            partialResults, totalResultPartials);
-
-                    if (VERBOSE) {
-                        Log.v(TAG, "testPartialResult - Observed " +
-                                partialResults.size() + "; queried for " +
-                                totalResultPartials.size());
-                    }
-                }
-
-                int errorCode = listener.getErrorCode();
-                if ((errorCode & TotalAndPartialResultListener.ERROR_DUPLICATED_REQUEST) != 0) {
-                    mCollector.addMessage("Listener received multiple onCaptureComplete" +
-                            " callback for the same request");
-                }
-                if ((errorCode & TotalAndPartialResultListener.ERROR_WRONG_CALLBACK_ORDER) != 0) {
-                    mCollector.addMessage("Listener received onCaptureStart or" +
-                            " onCaptureProgressed after onCaptureComplete");
-                }
-
-                stopCapture(/*fast*/false);
-            } finally {
-                closeDevice(id);
-                closeDefaultImageReader();
-            }
-        }
-    }
-
-    /**
-     * Check that the timestamps passed in the results, buffers, and capture callbacks match for
-     * a single request, and increase monotonically
-     */
-    public void testResultTimestamps() throws Exception {
-        for (String id : mCameraIds) {
-            ImageReader previewReader = null;
-            ImageReader jpegReader = null;
-
-            SimpleImageReaderListener jpegListener = new SimpleImageReaderListener();
-            SimpleImageReaderListener prevListener = new SimpleImageReaderListener();
-            try {
-                openDevice(id);
-
-                CaptureRequest.Builder previewBuilder =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                CaptureRequest.Builder multiBuilder =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-
-                // Create image reader and surface.
-                Size previewSize = mOrderedPreviewSizes.get(0);
-                Size jpegSize = mOrderedStillSizes.get(0);
-
-                // Create ImageReaders.
-                previewReader = makeImageReader(previewSize, ImageFormat.YUV_420_888,
-                        MAX_NUM_IMAGES, prevListener, mHandler);
-                jpegReader = makeImageReader(jpegSize, ImageFormat.JPEG,
-                        MAX_NUM_IMAGES, jpegListener, mHandler);
-
-                // Configure output streams with preview and jpeg streams.
-                List<Surface> outputSurfaces = new ArrayList<>(Arrays.asList(
-                        previewReader.getSurface(), jpegReader.getSurface()));
-
-                SessionListener mockSessionListener = getMockSessionListener();
-
-                CameraCaptureSession session = configureAndVerifySession(mockSessionListener,
-                        mCamera, outputSurfaces, mHandler);
-
-                // Configure the requests.
-                previewBuilder.addTarget(previewReader.getSurface());
-                multiBuilder.addTarget(previewReader.getSurface());
-                multiBuilder.addTarget(jpegReader.getSurface());
-
-                CaptureCallback mockCaptureCallback = getMockCaptureListener();
-
-                // Capture targeting only preview
-                Pair<TotalCaptureResult, Long> result = captureAndVerifyResult(mockCaptureCallback,
-                        session, previewBuilder.build(), mHandler);
-
-                // Check if all timestamps are the same
-                validateTimestamps("Result 1", result.first,
-                        prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS), result.second);
-
-                // Capture targeting both jpeg and preview
-                Pair<TotalCaptureResult, Long> result2 = captureAndVerifyResult(mockCaptureCallback,
-                        session, multiBuilder.build(), mHandler);
-
-                // Check if all timestamps are the same
-                validateTimestamps("Result 2 Preview", result2.first,
-                        prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS), result2.second);
-                validateTimestamps("Result 2 Jpeg", result2.first,
-                        jpegListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS), result2.second);
-
-                // Check if timestamps are increasing
-                mCollector.expectGreater("Timestamps must be increasing.", result.second,
-                        result2.second);
-
-                // Capture two preview frames
-                long startTime = SystemClock.elapsedRealtimeNanos();
-                Pair<TotalCaptureResult, Long> result3 = captureAndVerifyResult(mockCaptureCallback,
-                        session, previewBuilder.build(), mHandler);
-                Pair<TotalCaptureResult, Long> result4 = captureAndVerifyResult(mockCaptureCallback,
-                        session, previewBuilder.build(), mHandler);
-                long clockDiff = SystemClock.elapsedRealtimeNanos() - startTime;
-                long resultDiff = result4.second - result3.second;
-
-                // Check if all timestamps are the same
-                validateTimestamps("Result 3", result3.first,
-                        prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS), result3.second);
-                validateTimestamps("Result 4", result4.first,
-                        prevListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS), result4.second);
-
-                // Check that the timestamps monotonically increase at a reasonable rate
-                mCollector.expectGreaterOrEqual("Timestamps increase faster than system clock.",
-                        resultDiff, clockDiff);
-                mCollector.expectGreater("Timestamps must be increasing.", result3.second,
-                        result4.second);
-            } finally {
-                closeDevice(id);
-                closeImageReader(previewReader);
-                closeImageReader(jpegReader);
-            }
-        }
-    }
-
-    private void validateTimestamps(String msg, TotalCaptureResult result, Image resultImage,
-                                    long captureTime) {
-        mCollector.expectKeyValueEquals(result, CaptureResult.SENSOR_TIMESTAMP, captureTime);
-        mCollector.expectEquals(msg + ": Capture timestamp must be same as resultImage timestamp",
-                resultImage.getTimestamp(), captureTime);
-    }
-
-    private void validateCaptureResult(SimpleCaptureCallback captureListener,
-            List<CaptureResult.Key<?>> skippedKeys, CaptureRequest.Builder requestBuilder,
-            int numFramesVerified) throws Exception {
-        CaptureResult result = null;
-        for (int i = 0; i < numFramesVerified; i++) {
-            String failMsg = "Failed capture result " + i + " test ";
-            result = captureListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-
-            for (CaptureResult.Key<?> key : mAllKeys) {
-                if (!skippedKeys.contains(key)) {
-                    /**
-                     * Check the critical tags here.
-                     * TODO: Can use the same key for request and result when request/result
-                     * becomes symmetric (b/14059883). Then below check can be wrapped into
-                     * a generic function.
-                     */
-                    String msg = failMsg + "for key " + key.getName();
-                    if (key.equals(CaptureResult.CONTROL_AE_MODE)) {
-                        mCollector.expectEquals(msg,
-                                requestBuilder.get(CaptureRequest.CONTROL_AE_MODE),
-                                result.get(CaptureResult.CONTROL_AE_MODE));
-                    } else if (key.equals(CaptureResult.CONTROL_AF_MODE)) {
-                        mCollector.expectEquals(msg,
-                                requestBuilder.get(CaptureRequest.CONTROL_AF_MODE),
-                                result.get(CaptureResult.CONTROL_AF_MODE));
-                    } else if (key.equals(CaptureResult.CONTROL_AWB_MODE)) {
-                        mCollector.expectEquals(msg,
-                                requestBuilder.get(CaptureRequest.CONTROL_AWB_MODE),
-                                result.get(CaptureResult.CONTROL_AWB_MODE));
-                    } else if (key.equals(CaptureResult.CONTROL_MODE)) {
-                        mCollector.expectEquals(msg,
-                                requestBuilder.get(CaptureRequest.CONTROL_MODE),
-                                result.get(CaptureResult.CONTROL_MODE));
-                    } else if (key.equals(CaptureResult.STATISTICS_FACE_DETECT_MODE)) {
-                        mCollector.expectEquals(msg,
-                                requestBuilder.get(CaptureRequest.STATISTICS_FACE_DETECT_MODE),
-                                result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE));
-                    } else if (key.equals(CaptureResult.NOISE_REDUCTION_MODE)) {
-                        mCollector.expectEquals(msg,
-                                requestBuilder.get(CaptureRequest.NOISE_REDUCTION_MODE),
-                                result.get(CaptureResult.NOISE_REDUCTION_MODE));
-                    } else if (key.equals(CaptureResult.NOISE_REDUCTION_MODE)) {
-                        mCollector.expectEquals(msg,
-                                requestBuilder.get(CaptureRequest.NOISE_REDUCTION_MODE),
-                                result.get(CaptureResult.NOISE_REDUCTION_MODE));
-                    } else if (key.equals(CaptureResult.REQUEST_PIPELINE_DEPTH)) {
-
-                    } else {
-                        // Only do non-null check for the rest of keys.
-                        mCollector.expectKeyValueNotNull(failMsg, result, key);
-                    }
-                } else {
-                    // These keys should always be null
-                    if (key.equals(CaptureResult.CONTROL_AE_REGIONS)) {
-                        mCollector.expectNull(
-                                "Capture result contains AE regions but aeMaxRegions is 0",
-                                result.get(CaptureResult.CONTROL_AE_REGIONS));
-                    } else if (key.equals(CaptureResult.CONTROL_AWB_REGIONS)) {
-                        mCollector.expectNull(
-                                "Capture result contains AWB regions but awbMaxRegions is 0",
-                                result.get(CaptureResult.CONTROL_AWB_REGIONS));
-                    } else if (key.equals(CaptureResult.CONTROL_AF_REGIONS)) {
-                        mCollector.expectNull(
-                                "Capture result contains AF regions but afMaxRegions is 0",
-                                result.get(CaptureResult.CONTROL_AF_REGIONS));
-                    }
-                }
-            }
-        }
-    }
-
-    /*
-     * Add waiver keys per camera device hardware level and capability.
-     *
-     * Must be called after camera device is opened.
-     */
-    private List<CaptureResult.Key<?>> getWaiverKeysForCamera() {
-        List<CaptureResult.Key<?>> waiverKeys = new ArrayList<>();
-
-        // Global waiver keys
-        waiverKeys.add(CaptureResult.JPEG_GPS_LOCATION);
-        waiverKeys.add(CaptureResult.JPEG_ORIENTATION);
-        waiverKeys.add(CaptureResult.JPEG_QUALITY);
-        waiverKeys.add(CaptureResult.JPEG_THUMBNAIL_QUALITY);
-        waiverKeys.add(CaptureResult.JPEG_THUMBNAIL_SIZE);
-
-        // Keys only present when corresponding control is on are being
-        // verified in its own functional test
-        // Only present when tone mapping mode is CONTRAST_CURVE
-        waiverKeys.add(CaptureResult.TONEMAP_CURVE);
-        // Only present when test pattern mode is SOLID_COLOR.
-        // TODO: verify this key in test pattern test later
-        waiverKeys.add(CaptureResult.SENSOR_TEST_PATTERN_DATA);
-        // Only present when STATISTICS_LENS_SHADING_MAP_MODE is ON
-        waiverKeys.add(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
-        //  Only present when STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES is ON
-        waiverKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP);
-        //  Only present when face detection is on
-        waiverKeys.add(CaptureResult.STATISTICS_FACES);
-
-        //Keys not required if RAW is not supported
-        if (!mStaticInfo.isCapabilitySupported(
-                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
-            waiverKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
-            waiverKeys.add(CaptureResult.SENSOR_GREEN_SPLIT);
-            waiverKeys.add(CaptureResult.SENSOR_NOISE_PROFILE);
-        }
-
-        if (mStaticInfo.getAeMaxRegionsChecked() == 0) {
-            waiverKeys.add(CaptureResult.CONTROL_AE_REGIONS);
-        }
-        if (mStaticInfo.getAwbMaxRegionsChecked() == 0) {
-            waiverKeys.add(CaptureResult.CONTROL_AWB_REGIONS);
-        }
-        if (mStaticInfo.getAfMaxRegionsChecked() == 0) {
-            waiverKeys.add(CaptureResult.CONTROL_AF_REGIONS);
-        }
-
-        if (mStaticInfo.isHardwareLevelFull()) {
-            return waiverKeys;
-        }
-
-        /*
-         * Hardware Level = LIMITED or LEGACY
-         */
-        // Key not present if certain control is not supported
-        if (!mStaticInfo.isManualColorCorrectionSupported()) {
-            waiverKeys.add(CaptureResult.COLOR_CORRECTION_GAINS);
-            waiverKeys.add(CaptureResult.COLOR_CORRECTION_MODE);
-            waiverKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM);
-        }
-
-        if (!mStaticInfo.isManualColorAberrationControlSupported()) {
-            waiverKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE);
-        }
-
-        if (!mStaticInfo.isManualToneMapSupported()) {
-            waiverKeys.add(CaptureResult.TONEMAP_MODE);
-        }
-
-        if (!mStaticInfo.isEdgeModeControlSupported()) {
-            waiverKeys.add(CaptureResult.EDGE_MODE);
-        }
-
-        if (!mStaticInfo.isHotPixelMapModeControlSupported()) {
-            waiverKeys.add(CaptureResult.HOT_PIXEL_MODE);
-        }
-
-        if (!mStaticInfo.isNoiseReductionModeControlSupported()) {
-            waiverKeys.add(CaptureResult.NOISE_REDUCTION_MODE);
-        }
-
-        if (!mStaticInfo.isManualLensShadingMapSupported()) {
-            waiverKeys.add(CaptureResult.SHADING_MODE);
-        }
-
-        //Keys not required if manual sensor control is not supported
-        if (!mStaticInfo.isCapabilitySupported(
-                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-            waiverKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME);
-            waiverKeys.add(CaptureResult.SENSOR_FRAME_DURATION);
-            waiverKeys.add(CaptureResult.SENSOR_SENSITIVITY);
-            waiverKeys.add(CaptureResult.BLACK_LEVEL_LOCK);
-            waiverKeys.add(CaptureResult.LENS_FOCUS_RANGE);
-            waiverKeys.add(CaptureResult.LENS_FOCUS_DISTANCE);
-            waiverKeys.add(CaptureResult.LENS_STATE);
-            waiverKeys.add(CaptureResult.LENS_APERTURE);
-            waiverKeys.add(CaptureResult.LENS_FILTER_DENSITY);
-        }
-
-        if (mStaticInfo.isHardwareLevelLimited()) {
-            return waiverKeys;
-        }
-
-        /*
-         * Hardware Level = LEGACY
-         */
-        waiverKeys.add(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER);
-        waiverKeys.add(CaptureResult.CONTROL_AE_STATE);
-        waiverKeys.add(CaptureResult.CONTROL_AWB_STATE);
-        waiverKeys.add(CaptureResult.FLASH_STATE);
-        waiverKeys.add(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE);
-        waiverKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW);
-        waiverKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP_MODE);
-        waiverKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER);
-        waiverKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE);
-        waiverKeys.add(CaptureResult.CONTROL_AE_TARGET_FPS_RANGE);
-        waiverKeys.add(CaptureResult.CONTROL_AF_TRIGGER);
-
-        return waiverKeys;
-    }
-
-    /**
-     * A capture listener implementation for collecting both partial and total results.
-     *
-     * <p> This is not a full-blown class and has some implicit assumptions. The class groups
-     * capture results by capture request, so the user must guarantee each request this listener
-     * is listening is unique. This class is not thread safe, so don't attach an instance object
-     * with multiple handlers.</p>
-     * */
-    private static class TotalAndPartialResultListener
-            extends CameraCaptureSession.CaptureCallback {
-        static final int ERROR_DUPLICATED_REQUEST = 1 << 0;
-        static final int ERROR_WRONG_CALLBACK_ORDER = 1 << 1;
-
-        private final LinkedBlockingQueue<Pair<TotalCaptureResult, List<CaptureResult>> > mQueue =
-                new LinkedBlockingQueue<>();
-        private final HashMap<CaptureRequest, List<CaptureResult>> mPartialResultsMap =
-                new HashMap<CaptureRequest, List<CaptureResult>>();
-        private final HashSet<CaptureRequest> completedRequests = new HashSet<>();
-        private int errorCode = 0;
-
-        @Override
-        public void onCaptureStarted(
-            CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber)
-        {
-            checkCallbackOrder(request);
-            createMapEntryIfNecessary(request);
-        }
-
-        @Override
-        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
-                TotalCaptureResult result) {
-            try {
-                List<CaptureResult> partialResultsList = mPartialResultsMap.get(request);
-                if (partialResultsList == null) {
-                    Log.w(TAG, "onCaptureCompleted: unknown request");
-                }
-                mQueue.put(new Pair<TotalCaptureResult, List<CaptureResult>>(
-                        result, partialResultsList));
-                mPartialResultsMap.remove(request);
-                boolean newEntryAdded = completedRequests.add(request);
-                if (!newEntryAdded) {
-                    Integer frame = (Integer) request.getTag();
-                    Log.e(TAG, "Frame " + frame + "ERROR_DUPLICATED_REQUEST");
-                    errorCode |= ERROR_DUPLICATED_REQUEST;
-                }
-            } catch (InterruptedException e) {
-                throw new UnsupportedOperationException(
-                        "Can't handle InterruptedException in onCaptureCompleted");
-            }
-        }
-
-        @Override
-        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
-                CaptureResult partialResult) {
-            createMapEntryIfNecessary(request);
-            List<CaptureResult> partialResultsList = mPartialResultsMap.get(request);
-            partialResultsList.add(partialResult);
-        }
-
-        private void createMapEntryIfNecessary(CaptureRequest request) {
-            if (!mPartialResultsMap.containsKey(request)) {
-                // create a new entry in the map
-                mPartialResultsMap.put(request, new ArrayList<CaptureResult>());
-            }
-        }
-
-        private void checkCallbackOrder(CaptureRequest request) {
-            if (completedRequests.contains(request)) {
-                Integer frame = (Integer) request.getTag();
-                Log.e(TAG, "Frame " + frame + "ERROR_WRONG_CALLBACK_ORDER");
-                errorCode |= ERROR_WRONG_CALLBACK_ORDER;
-            }
-        }
-
-        public Pair<TotalCaptureResult, List<CaptureResult>> getCaptureResultPairs(long timeout) {
-            try {
-                Pair<TotalCaptureResult, List<CaptureResult>> result =
-                        mQueue.poll(timeout, TimeUnit.MILLISECONDS);
-                assertNotNull("Wait for a capture result timed out in " + timeout + "ms", result);
-                return result;
-            } catch (InterruptedException e) {
-                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
-            }
-        }
-
-        public int getErrorCode() {
-            return errorCode;
-        }
-    }
-
-    /**
-     * TODO: Use CameraCharacteristics.getAvailableCaptureResultKeys() once we can filter out
-     * @hide keys.
-     *
-     */
-
-    /*@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 List<CaptureResult.Key<?>> getAllCaptureResultKeys() {
-        ArrayList<CaptureResult.Key<?>> resultKeys = new ArrayList<CaptureResult.Key<?>>();
-        resultKeys.add(CaptureResult.COLOR_CORRECTION_MODE);
-        resultKeys.add(CaptureResult.COLOR_CORRECTION_TRANSFORM);
-        resultKeys.add(CaptureResult.COLOR_CORRECTION_GAINS);
-        resultKeys.add(CaptureResult.COLOR_CORRECTION_ABERRATION_MODE);
-        resultKeys.add(CaptureResult.CONTROL_AE_ANTIBANDING_MODE);
-        resultKeys.add(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION);
-        resultKeys.add(CaptureResult.CONTROL_AE_LOCK);
-        resultKeys.add(CaptureResult.CONTROL_AE_MODE);
-        resultKeys.add(CaptureResult.CONTROL_AE_REGIONS);
-        resultKeys.add(CaptureResult.CONTROL_AE_TARGET_FPS_RANGE);
-        resultKeys.add(CaptureResult.CONTROL_AE_PRECAPTURE_TRIGGER);
-        resultKeys.add(CaptureResult.CONTROL_AF_MODE);
-        resultKeys.add(CaptureResult.CONTROL_AF_REGIONS);
-        resultKeys.add(CaptureResult.CONTROL_AF_TRIGGER);
-        resultKeys.add(CaptureResult.CONTROL_AWB_LOCK);
-        resultKeys.add(CaptureResult.CONTROL_AWB_MODE);
-        resultKeys.add(CaptureResult.CONTROL_AWB_REGIONS);
-        resultKeys.add(CaptureResult.CONTROL_CAPTURE_INTENT);
-        resultKeys.add(CaptureResult.CONTROL_EFFECT_MODE);
-        resultKeys.add(CaptureResult.CONTROL_MODE);
-        resultKeys.add(CaptureResult.CONTROL_SCENE_MODE);
-        resultKeys.add(CaptureResult.CONTROL_VIDEO_STABILIZATION_MODE);
-        resultKeys.add(CaptureResult.CONTROL_AE_STATE);
-        resultKeys.add(CaptureResult.CONTROL_AF_STATE);
-        resultKeys.add(CaptureResult.CONTROL_AWB_STATE);
-        resultKeys.add(CaptureResult.EDGE_MODE);
-        resultKeys.add(CaptureResult.FLASH_MODE);
-        resultKeys.add(CaptureResult.FLASH_STATE);
-        resultKeys.add(CaptureResult.HOT_PIXEL_MODE);
-        resultKeys.add(CaptureResult.JPEG_GPS_LOCATION);
-        resultKeys.add(CaptureResult.JPEG_ORIENTATION);
-        resultKeys.add(CaptureResult.JPEG_QUALITY);
-        resultKeys.add(CaptureResult.JPEG_THUMBNAIL_QUALITY);
-        resultKeys.add(CaptureResult.JPEG_THUMBNAIL_SIZE);
-        resultKeys.add(CaptureResult.LENS_APERTURE);
-        resultKeys.add(CaptureResult.LENS_FILTER_DENSITY);
-        resultKeys.add(CaptureResult.LENS_FOCAL_LENGTH);
-        resultKeys.add(CaptureResult.LENS_FOCUS_DISTANCE);
-        resultKeys.add(CaptureResult.LENS_OPTICAL_STABILIZATION_MODE);
-        resultKeys.add(CaptureResult.LENS_FOCUS_RANGE);
-        resultKeys.add(CaptureResult.LENS_STATE);
-        resultKeys.add(CaptureResult.NOISE_REDUCTION_MODE);
-        resultKeys.add(CaptureResult.REQUEST_PIPELINE_DEPTH);
-        resultKeys.add(CaptureResult.SCALER_CROP_REGION);
-        resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME);
-        resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION);
-        resultKeys.add(CaptureResult.SENSOR_SENSITIVITY);
-        resultKeys.add(CaptureResult.SENSOR_TIMESTAMP);
-        resultKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
-        resultKeys.add(CaptureResult.SENSOR_NOISE_PROFILE);
-        resultKeys.add(CaptureResult.SENSOR_GREEN_SPLIT);
-        resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_DATA);
-        resultKeys.add(CaptureResult.SENSOR_TEST_PATTERN_MODE);
-        resultKeys.add(CaptureResult.SENSOR_ROLLING_SHUTTER_SKEW);
-        resultKeys.add(CaptureResult.SHADING_MODE);
-        resultKeys.add(CaptureResult.STATISTICS_FACE_DETECT_MODE);
-        resultKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE);
-        resultKeys.add(CaptureResult.STATISTICS_FACES);
-        resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
-        resultKeys.add(CaptureResult.STATISTICS_SCENE_FLICKER);
-        resultKeys.add(CaptureResult.STATISTICS_HOT_PIXEL_MAP);
-        resultKeys.add(CaptureResult.STATISTICS_LENS_SHADING_MAP_MODE);
-        resultKeys.add(CaptureResult.TONEMAP_CURVE);
-        resultKeys.add(CaptureResult.TONEMAP_MODE);
-        resultKeys.add(CaptureResult.BLACK_LEVEL_LOCK);
-
-        return resultKeys;
-    }
-
-    /*~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~
-     * End generated code
-     *~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~@~O@*/
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
deleted file mode 100644
index 67fad4e..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/DngCreatorTest.java
+++ /dev/null
@@ -1,662 +0,0 @@
-/*
- * Copyright 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.hardware.camera2.cts;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.ImageFormat;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.DngCreator;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.cts.helpers.StaticMetadata;
-import android.hardware.camera2.cts.rs.BitmapUtils;
-import android.hardware.camera2.cts.rs.RawConverter;
-import android.hardware.camera2.cts.rs.RenderScriptSingleton;
-import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
-import android.location.Location;
-import android.media.ExifInterface;
-import android.media.Image;
-import android.media.ImageReader;
-import android.os.ConditionVariable;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Size;
-import android.view.Surface;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-import java.nio.channels.FileChannel;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-
-import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
-
-/**
- * Tests for the DngCreator API.
- */
-public class DngCreatorTest extends Camera2AndroidTestCase {
-    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 double IMAGE_DIFFERENCE_TOLERANCE = 65;
-    private static final int DEFAULT_PATCH_DIMEN = 512;
-    private static final int AE_TIMEOUT_MS = 2000;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    @Override
-    public synchronized void setContext(Context context) {
-        super.setContext(context);
-
-        RenderScriptSingleton.setContext(context);
-    }
-
-    /**
-     * Test basic raw capture and DNG saving functionality for each of the available cameras.
-     *
-     * <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.
-     * </p>
-     *
-     * <p>
-     * Note: Enabling adb shell setprop log.tag.DngCreatorTest VERBOSE will also cause the
-     * raw image captured for the first reported camera device to be saved to an output file.
-     * </p>
-     */
-    public void testSingleImageBasic() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            String deviceId = mCameraIds[i];
-            ImageReader captureReader = null;
-            FileOutputStream fileStream = null;
-            ByteArrayOutputStream outputStream = 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.");
-                    continue;
-                }
-
-                Size[] targetCaptureSizes =
-                        mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
-                                StaticMetadata.StreamDirection.Output);
-
-                assertTrue("No capture sizes available for RAW format!",
-                        targetCaptureSizes.length != 0);
-                Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
-                Size activeArraySize = new Size(activeArray.width(), activeArray.height());
-                assertTrue("Missing ActiveArraySize", activeArray.width() > 0 &&
-                        activeArray.height() > 0);
-                // TODO: Allow PixelArraySize also.
-                assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
-                        targetCaptureSizes, activeArraySize);
-
-                // Create capture image reader
-                CameraTestUtils.SimpleImageReaderListener captureListener
-                        = new CameraTestUtils.SimpleImageReaderListener();
-                captureReader = createImageReader(activeArraySize, ImageFormat.RAW_SENSOR, 2,
-                        captureListener);
-                Pair<Image, CaptureResult> resultPair = captureSingleRawShot(activeArraySize,
-                        /*waitForAe*/false, captureReader, captureListener);
-                CameraCharacteristics characteristics = mStaticInfo.getCharacteristics();
-
-                // Test simple writeImage, no header checks
-                DngCreator dngCreator = new DngCreator(characteristics, resultPair.second);
-                outputStream = new ByteArrayOutputStream();
-                dngCreator.writeImage(outputStream, resultPair.first);
-
-                if (VERBOSE) {
-                    // Write DNG to file
-                    String dngFilePath = DEBUG_FILE_NAME_BASE + "/camera_basic_" + deviceId + "_" +
-                            DEBUG_DNG_FILE;
-                    // Write out captured DNG file for the first camera device if setprop is enabled
-                    fileStream = new FileOutputStream(dngFilePath);
-                    fileStream.write(outputStream.toByteArray());
-                    fileStream.flush();
-                    fileStream.close();
-                    Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + dngFilePath);
-                }
-            } finally {
-                closeDevice(deviceId);
-                closeImageReader(captureReader);
-
-                if (outputStream != null) {
-                    outputStream.close();
-                }
-
-                if (fileStream != null) {
-                    fileStream.close();
-                }
-            }
-        }
-    }
-
-    /**
-     * Test basic raw capture and DNG saving with a thumbnail, rotation, usercomment, and GPS tags
-     * set.
-     *
-     * <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.
-     * </p>
-     *
-     * <p>
-     * Note: Enabling adb shell setprop log.tag.DngCreatorTest VERBOSE will also cause the
-     * raw image captured for the first reported camera device to be saved to an output file.
-     * </p>
-     */
-    public void testSingleImageThumbnail() 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>();
-            FileOutputStream fileStream = null;
-            ByteArrayOutputStream outputStream = 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.");
-                    continue;
-                }
-
-                Size[] targetCaptureSizes =
-                        mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
-                                StaticMetadata.StreamDirection.Output);
-
-                assertTrue("No capture sizes available for RAW format!",
-                        targetCaptureSizes.length != 0);
-                Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
-                Size activeArraySize = new Size(activeArray.width(), activeArray.height());
-                assertTrue("Missing ActiveArraySize", activeArray.width() > 0 &&
-                        activeArray.height() > 0);
-                // TODO: Allow PixelArraySize also.
-                assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
-                        targetCaptureSizes, activeArraySize);
-
-                Size[] targetPreviewSizes =
-                        mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.YUV_420_888,
-                                StaticMetadata.StreamDirection.Output);
-                // Get smallest preview size
-                Size previewSize = mOrderedPreviewSizes.get(mOrderedPreviewSizes.size() - 1);
-
-                // Create capture image reader
-                CameraTestUtils.SimpleImageReaderListener captureListener
-                        = new CameraTestUtils.SimpleImageReaderListener();
-                captureReaders.add(createImageReader(activeArraySize, ImageFormat.RAW_SENSOR, 2,
-                        captureListener));
-                captureListeners.add(captureListener);
-
-                CameraTestUtils.SimpleImageReaderListener previewListener
-                        = new CameraTestUtils.SimpleImageReaderListener();
-
-                captureReaders.add(createImageReader(previewSize, ImageFormat.YUV_420_888, 2,
-                        previewListener));
-                captureListeners.add(previewListener);
-
-                Pair<List<Image>, CaptureResult> resultPair = captureSingleRawShot(activeArraySize,
-                        captureReaders, /*waitForAe*/false, captureListeners);
-                CameraCharacteristics characteristics = mStaticInfo.getCharacteristics();
-
-                // Test simple writeImage, no header checks
-                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());
-                dngCreator.setLocation(l);
-
-                dngCreator.setDescription("helloworld");
-                dngCreator.setOrientation(ExifInterface.ORIENTATION_FLIP_VERTICAL);
-                dngCreator.setThumbnail(resultPair.first.get(1));
-                outputStream = new ByteArrayOutputStream();
-                dngCreator.writeImage(outputStream, resultPair.first.get(0));
-
-                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);
-                }
-            } finally {
-                closeDevice(deviceId);
-                for (ImageReader r : captureReaders) {
-                    closeImageReader(r);
-                }
-
-                if (outputStream != null) {
-                    outputStream.close();
-                }
-
-                if (fileStream != null) {
-                    fileStream.close();
-                }
-            }
-        }
-    }
-
-    /**
-     * Test basic RAW capture, and ensure that the rendered RAW output is similar to the JPEG
-     * created for the same frame.
-     *
-     * <p>
-     * This test renders the RAW buffer into an RGB bitmap using a rendering pipeline
-     * similar to one in the Adobe DNG validation tool.  JPEGs produced by the vendor hardware may
-     * have different tonemapping and saturation applied than the RGB bitmaps produced
-     * from this DNG rendering pipeline, and this test allows for fairly wide variations
-     * between the histograms for the RAW and JPEG buffers to avoid false positives.
-     * </p>
-     *
-     * <p>
-     * To ensure more subtle errors in the colorspace transforms returned for the HAL's RAW
-     * metadata, the DNGs and JPEGs produced here should also be manually compared using external
-     * DNG rendering tools.  The DNG, rendered RGB bitmap, and JPEG buffer for this test can be
-     * dumped to the SD card for further examination by enabling the 'verbose' mode for this test
-     * using:
-     * adb shell setprop log.tag.DngCreatorTest VERBOSE
-     * </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>();
-            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.");
-                    continue;
-                }
-
-                Size[] targetCaptureSizes =
-                        mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
-                                StaticMetadata.StreamDirection.Output);
-
-                assertTrue("No capture sizes available for RAW format!",
-                        targetCaptureSizes.length != 0);
-                Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
-                Size activeArraySize = new Size(activeArray.width(), activeArray.height());
-                assertTrue("Active array has invalid size!", activeArray.width() > 0 &&
-                        activeArray.height() > 0);
-                // TODO: Allow PixelArraySize also.
-                assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
-                        targetCaptureSizes, activeArraySize);
-
-                // 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);
-
-                Bitmap rawBitmap = Bitmap.createBitmap(raw.getWidth(), raw.getHeight(),
-                        Bitmap.Config.ARGB_8888);
-                byte[] rawPlane = new byte[raw.getPlanes()[0].getRowStride() * raw.getHeight()];
-
-                // Render RAW image to a bitmap
-                raw.getPlanes()[0].getBuffer().get(rawPlane);
-                raw.getPlanes()[0].getBuffer().rewind();
-                RawConverter.convertToSRGB(RenderScriptSingleton.getRS(), raw.getWidth(),
-                        raw.getHeight(), raw.getPlanes()[0].getRowStride(), rawPlane,
-                        characteristics, resultPair.second, /*offsetX*/0, /*offsetY*/0,
-                        /*out*/rawBitmap);
-
-                // Decompress JPEG image to a bitmap
-                byte[] compressedJpegData = CameraTestUtils.getDataFromImage(jpeg);
-
-                BitmapFactory.Options opt = new BitmapFactory.Options();
-                opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
-                Bitmap fullSizeJpegBmap = BitmapFactory.decodeByteArray(compressedJpegData,
-                        /*offset*/0, compressedJpegData.length, /*inout*/opt);
-                Rect jpegDimens = new Rect(0, 0, fullSizeJpegBmap.getWidth(),
-                        fullSizeJpegBmap.getHeight());
-
-                if (VERBOSE) {
-                    // Generate DNG file
-                    DngCreator dngCreator = new DngCreator(characteristics, resultPair.second);
-                    outputStream = new ByteArrayOutputStream();
-                    dngCreator.writeImage(outputStream, raw);
-
-                    // Write DNG to file
-                    String dngFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_" +
-                            DEBUG_DNG_FILE;
-                    // Write out captured DNG file for the first camera device if setprop is enabled
-                    fileStream = new FileOutputStream(dngFilePath);
-                    fileStream.write(outputStream.toByteArray());
-                    fileStream.flush();
-                    fileStream.close();
-                    Log.v(TAG, "Test DNG file for camera " + deviceId + " saved to " + dngFilePath);
-
-                    // Write JPEG to file
-                    String jpegFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_jpeg.jpg";
-                    // Write out captured DNG file for the first camera device if setprop is enabled
-                    fileChannel = new FileOutputStream(jpegFilePath).getChannel();
-                    fileChannel.write(jpeg.getPlanes()[0].getBuffer());
-                    fileChannel.close();
-                    Log.v(TAG, "Test JPEG file for camera " + deviceId + " saved to " +
-                            jpegFilePath);
-
-                    // Write jpeg generated from demosaiced RAW frame to file
-                    String rawFilePath = DEBUG_FILE_NAME_BASE + "/camera_" + deviceId + "_raw.jpg";
-                    // Write out captured DNG file for the first camera device if setprop is enabled
-                    fileStream = new FileOutputStream(rawFilePath);
-                    rawBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fileStream);
-                    fileStream.flush();
-                    fileStream.close();
-                    Log.v(TAG, "Test converted RAW file for camera " + deviceId + " saved to " +
-                            rawFilePath);
-                }
-
-                Size rawBitmapSize = new Size(rawBitmap.getWidth(), rawBitmap.getHeight());
-                assertTrue("Raw bitmap size must be equal to active array size.",
-                        rawBitmapSize.equals(activeArraySize));
-
-                // Get 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);
-
-                Bitmap jpegPatch = Bitmap.createBitmap(fullSizeJpegBmap, jpegFinal.left,
-                        jpegFinal.top, jpegFinal.width(), jpegFinal.height());
-                Bitmap rawPatch = Bitmap.createBitmap(rawBitmap, rawFinal.left, rawFinal.top,
-                        rawFinal.width(), rawFinal.height());
-
-                // 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);
-                }
-
-            } finally {
-                closeDevice(deviceId);
-                for (ImageReader r : captureReaders) {
-                    closeImageReader(r);
-                }
-
-                if (fileChannel != null) {
-                    fileChannel.close();
-                }
-
-                if (outputStream != null) {
-                    outputStream.close();
-                }
-
-                if (fileStream != null) {
-                    fileStream.close();
-                }
-            }
-        }
-    }
-
-    private Pair<Image, CaptureResult> captureSingleRawShot(Size s, boolean waitForAe,
-            ImageReader captureReader,
-            CameraTestUtils.SimpleImageReaderListener captureListener) throws Exception {
-        List<ImageReader> readers = new ArrayList<ImageReader>();
-        readers.add(captureReader);
-        List<CameraTestUtils.SimpleImageReaderListener> listeners =
-                new ArrayList<CameraTestUtils.SimpleImageReaderListener>();
-        listeners.add(captureListener);
-        Pair<List<Image>, CaptureResult> res = captureSingleRawShot(s, readers, waitForAe,
-                listeners);
-        return new Pair<Image, CaptureResult>(res.first.get(0), res.second);
-    }
-
-    private Pair<List<Image>, CaptureResult> captureSingleRawShot(Size s,
-            List<ImageReader> captureReaders, boolean waitForAe,
-            List<CameraTestUtils.SimpleImageReaderListener> captureListeners) throws Exception {
-        return captureRawShots(s, captureReaders, waitForAe, captureListeners, 1).get(0);
-    }
-
-    /**
-     * Capture raw images.
-     *
-     * <p>Capture raw images for a given size.</p>
-     *
-     * @param s The size of the raw image to capture.  Must be one of the available sizes for this
-     *          device.
-     * @return a list of pairs containing a {@link Image} and {@link CaptureResult} used for
-     *          each capture.
-     */
-    private List<Pair<List<Image>, CaptureResult>> captureRawShots(Size s,
-            List<ImageReader> captureReaders, boolean waitForAe,
-            List<CameraTestUtils.SimpleImageReaderListener> captureListeners,
-            int numShots) throws Exception {
-        if (VERBOSE) {
-            Log.v(TAG, "captureSingleRawShot - Capturing raw image.");
-        }
-
-        Size[] targetCaptureSizes =
-                mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
-                        StaticMetadata.StreamDirection.Output);
-
-        // Validate size
-        boolean validSize = false;
-        for (int i = 0; i < targetCaptureSizes.length; ++i) {
-            if (targetCaptureSizes[i].equals(s)) {
-                validSize = true;
-                break;
-            }
-        }
-        assertTrue("Capture size is supported.", validSize);
-
-        // Capture images.
-        final List<Surface> outputSurfaces = new ArrayList<Surface>();
-        for (ImageReader captureReader : captureReaders) {
-            Surface captureSurface = captureReader.getSurface();
-            outputSurfaces.add(captureSurface);
-        }
-
-        // Set up still capture template targeting JPEG/RAW outputs
-        CaptureRequest.Builder request =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-        assertNotNull("Fail to get captureRequest", request);
-        for (Surface surface : outputSurfaces) {
-            request.addTarget(surface);
-        }
-
-        ImageReader previewReader = null;
-        if (waitForAe) {
-            // Also setup a small YUV output for AE metering if needed
-            Size yuvSize = (mOrderedPreviewSizes.size() == 0) ? null :
-                    mOrderedPreviewSizes.get(mOrderedPreviewSizes.size() - 1);
-            assertNotNull("Must support at least one small YUV size.", yuvSize);
-            previewReader = createImageReader(yuvSize, ImageFormat.YUV_420_888,
-                        /*maxNumImages*/2, new CameraTestUtils.ImageDropperListener());
-            outputSurfaces.add(previewReader.getSurface());
-        }
-
-        createSession(outputSurfaces);
-
-        if (waitForAe) {
-            CaptureRequest.Builder precaptureRequest =
-                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-            assertNotNull("Fail to get captureRequest", precaptureRequest);
-            precaptureRequest.addTarget(previewReader.getSurface());
-            precaptureRequest.set(CaptureRequest.CONTROL_MODE,
-                    CaptureRequest.CONTROL_MODE_AUTO);
-            precaptureRequest.set(CaptureRequest.CONTROL_AE_MODE,
-                    CaptureRequest.CONTROL_AE_MODE_ON);
-
-            final ConditionVariable waitForAeCondition = new ConditionVariable(/*isOpen*/false);
-            CameraCaptureSession.CaptureCallback captureCallback =
-                    new CameraCaptureSession.CaptureCallback() {
-                @Override
-                public void onCaptureProgressed(CameraCaptureSession session,
-                        CaptureRequest request, CaptureResult partialResult) {
-                    if (partialResult.get(CaptureResult.CONTROL_AE_STATE) ==
-                            CaptureRequest.CONTROL_AE_STATE_CONVERGED) {
-                        waitForAeCondition.open();
-                    }
-                }
-
-                @Override
-                public void onCaptureCompleted(CameraCaptureSession session,
-                        CaptureRequest request, TotalCaptureResult result) {
-                    if (result.get(CaptureResult.CONTROL_AE_STATE) ==
-                            CaptureRequest.CONTROL_AE_STATE_CONVERGED) {
-                        waitForAeCondition.open();
-                    }
-                }
-            };
-            startCapture(precaptureRequest.build(), /*repeating*/true, captureCallback, mHandler);
-
-            precaptureRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
-                    CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
-            startCapture(precaptureRequest.build(), /*repeating*/false, captureCallback, mHandler);
-            assertTrue("Timeout out waiting for AE to converge",
-                    waitForAeCondition.block(AE_TIMEOUT_MS));
-        }
-
-        request.set(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE,
-                CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE_ON);
-        CameraTestUtils.SimpleCaptureCallback resultListener =
-                new CameraTestUtils.SimpleCaptureCallback();
-
-        CaptureRequest request1 = request.build();
-        for (int i = 0; i < numShots; i++) {
-            startCapture(request1, /*repeating*/false, resultListener, mHandler);
-        }
-        List<Pair<List<Image>, CaptureResult>> ret = new ArrayList<>();
-        for (int i = 0; i < numShots; i++) {
-            // Verify capture result and images
-            CaptureResult result = resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
-
-            List<Image> resultImages = new ArrayList<Image>();
-            for (CameraTestUtils.SimpleImageReaderListener captureListener : captureListeners) {
-                Image captureImage = captureListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
-
-            /*CameraTestUtils.validateImage(captureImage, s.getWidth(), s.getHeight(),
-                    ImageFormat.RAW_SENSOR, null);*/
-                resultImages.add(captureImage);
-            }
-            ret.add(new Pair<List<Image>, CaptureResult>(resultImages, result));
-        }
-        // Stop capture, delete the streams.
-        stopCapture(/*fast*/false);
-
-        return ret;
-    }
-
-    private CaptureRequest.Builder prepareCaptureRequestForSurfaces(List<Surface> surfaces)
-            throws Exception {
-        createSession(surfaces);
-
-        CaptureRequest.Builder captureBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-        assertNotNull("Fail to get captureRequest", captureBuilder);
-        for (Surface surface : surfaces) {
-            captureBuilder.addTarget(surface);
-        }
-
-        return captureBuilder;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
deleted file mode 100644
index 8619f73..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ExtendedCameraCharacteristicsTest.java
+++ /dev/null
@@ -1,803 +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.hardware.camera2.cts;
-
-import android.content.Context;
-import android.graphics.ImageFormat;
-import android.graphics.Rect;
-import android.graphics.SurfaceTexture;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraCharacteristics.Key;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.cts.helpers.CameraErrorCollector;
-import android.hardware.camera2.params.BlackLevelPattern;
-import android.hardware.camera2.params.ColorSpaceTransform;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.media.ImageReader;
-import android.test.AndroidTestCase;
-import android.util.Log;
-import android.util.Rational;
-import android.util.Range;
-import android.util.Size;
-import android.view.Surface;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-
-import static android.hardware.camera2.cts.helpers.AssertHelpers.*;
-
-/**
- * Extended tests for static camera characteristics.
- */
-public class ExtendedCameraCharacteristicsTest extends AndroidTestCase {
-    private static final String TAG = "ExChrsTest"; // must be short so next line doesn't throw
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-
-    private static final String PREFIX_ANDROID = "android";
-    private static final String PREFIX_VENDOR = "com";
-
-    /*
-     * Constants for static RAW metadata.
-     */
-    private static final int MIN_ALLOWABLE_WHITELEVEL = 32; // must have sensor bit depth > 5
-
-    private CameraManager mCameraManager;
-    private List<CameraCharacteristics> mCharacteristics;
-    private String[] mIds;
-    private CameraErrorCollector mCollector;
-
-    private static final Size VGA = new Size(640, 480);
-
-    /*
-     * HW Levels short hand
-     */
-    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 OPT = Integer.MAX_VALUE;  // For keys that are optional on all hardware levels.
-
-    /*
-     * Capabilities short hand
-     */
-    private static final int NONE = -1;
-    private static final int BC =
-            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE;
-    private static final int MANUAL_SENSOR =
-            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR;
-    private static final int MANUAL_POSTPROC =
-            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING;
-    private static final int RAW =
-            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW;
-
-    @Override
-    public void setContext(Context context) {
-        super.setContext(context);
-        mCameraManager = (CameraManager)context.getSystemService(Context.CAMERA_SERVICE);
-        assertNotNull("Can't connect to camera manager", mCameraManager);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mIds = mCameraManager.getCameraIdList();
-        mCharacteristics = new ArrayList<>();
-        mCollector = new CameraErrorCollector();
-        for (int i = 0; i < mIds.length; i++) {
-            CameraCharacteristics props = mCameraManager.getCameraCharacteristics(mIds[i]);
-            assertNotNull(String.format("Can't get camera characteristics from: ID %s", mIds[i]),
-                    props);
-            mCharacteristics.add(props);
-        }
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mCharacteristics = null;
-
-        try {
-            mCollector.verify();
-        } catch (Throwable e) {
-            // When new Exception(e) is used, exception info will be printed twice.
-            throw new Exception(e.getMessage());
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    /**
-     * Test that the available stream configurations contain a few required formats and sizes.
-     */
-    public void testAvailableStreamConfigs() {
-        int counter = 0;
-        for (CameraCharacteristics c : mCharacteristics) {
-            StreamConfigurationMap config =
-                    c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-            assertNotNull(String.format("No stream configuration map found for: ID %s",
-                    mIds[counter]), config);
-            int[] outputFormats = config.getOutputFormats();
-
-            // Check required formats exist (JPEG, and YUV_420_888).
-            assertArrayContains(
-                    String.format("No valid YUV_420_888 preview formats found for: ID %s",
-                            mIds[counter]), outputFormats, ImageFormat.YUV_420_888);
-            assertArrayContains(String.format("No JPEG image format for: ID %s",
-                    mIds[counter]), outputFormats, ImageFormat.JPEG);
-
-            Size[] sizes = config.getOutputSizes(ImageFormat.YUV_420_888);
-            CameraTestUtils.assertArrayNotEmpty(sizes,
-                    String.format("No sizes for preview format %x for: ID %s",
-                            ImageFormat.YUV_420_888, mIds[counter]));
-
-            assertArrayContains(String.format(
-                            "Required VGA size not found for format %x for: ID %s",
-                            ImageFormat.YUV_420_888, mIds[counter]), sizes, VGA);
-
-            counter++;
-        }
-    }
-
-    /**
-     * Test {@link CameraCharacteristics#getKeys}
-     */
-    public void testKeys() {
-        int counter = 0;
-        for (CameraCharacteristics c : mCharacteristics) {
-            mCollector.setCameraId(mIds[counter]);
-
-            if (VERBOSE) {
-                Log.v(TAG, "testKeys - testing characteristics for camera " + mIds[counter]);
-            }
-
-            List<CameraCharacteristics.Key<?>> allKeys = c.getKeys();
-            assertNotNull("Camera characteristics keys must not be null", allKeys);
-            assertFalse("Camera characteristics keys must have at least 1 key",
-                    allKeys.isEmpty());
-
-            for (CameraCharacteristics.Key<?> key : allKeys) {
-                assertKeyPrefixValid(key.getName());
-
-                // All characteristics keys listed must never be null
-                mCollector.expectKeyValueNotNull(c, key);
-
-                // TODO: add a check that key must not be @hide
-            }
-
-            /*
-             * List of keys that must be present in camera characteristics (not null).
-             *
-             * Keys for LIMITED, FULL devices might be available despite lacking either
-             * the hardware level or the capability. This is *OK*. This only lists the
-             * *minimal* requirements for a key to be listed.
-             *
-             * LEGACY devices are a bit special since they map to api1 devices, so we know
-             * for a fact most keys are going to be illegal there so they should never be
-             * available.
-             *
-             * (TODO: Codegen this)
-             */
-            {
-                //                                           (Key Name)                                     (HW Level)  (Capabilities <Var-Arg>)
-                expectKeyAvailable(c, CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES     , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES          , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES                      , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES          , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE                   , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP                    , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES                      , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS                       , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES                   , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES     , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES                     , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_MAX_REGIONS_AE                          , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_MAX_REGIONS_AF                          , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.CONTROL_MAX_REGIONS_AWB                         , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES                       , FULL     ,   NONE                 );
-                expectKeyAvailable(c, CameraCharacteristics.FLASH_INFO_AVAILABLE                            , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES             , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL                   , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES                  , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.LENS_FACING                                     , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES                   , FULL     ,   MANUAL_SENSOR        );
-                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_AVAILABLE_FILTER_DENSITIES            , FULL     ,   MANUAL_SENSOR        );
-                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS               , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION       , LIMITED  ,   MANUAL_SENSOR        );
-                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION            , LIMITED  ,   MANUAL_SENSOR        );
-                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE                   , LIMITED  ,   MANUAL_SENSOR        );
-                expectKeyAvailable(c, CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE                , LIMITED  ,   NONE                 );
-                expectKeyAvailable(c, CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES                  , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC                     , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING            , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW                      , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT                    , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH                      , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM               , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP                 , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.SCALER_CROPPING_TYPE                            , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES             , LEGACY   ,   NONE                 );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN                      , FULL     ,   MANUAL_SENSOR, RAW   );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1                   , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2                   , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_COLOR_TRANSFORM1                         , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_COLOR_TRANSFORM2                         , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_FORWARD_MATRIX1                          , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_FORWARD_MATRIX2                          , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE                   , LEGACY   ,   BC, RAW              );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT            , FULL     ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE                 , FULL     ,   MANUAL_SENSOR        );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION                  , FULL     ,   MANUAL_SENSOR        );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_PHYSICAL_SIZE                       , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE                    , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE                   , FULL     ,   MANUAL_SENSOR        );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL                         , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_INFO_TIMESTAMP_SOURCE                    , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_MAX_ANALOG_SENSITIVITY                   , FULL     ,   MANUAL_SENSOR        );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_ORIENTATION                              , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1                    , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2                    , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES     , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES   , OPT      ,   RAW                  );
-                expectKeyAvailable(c, CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT                  , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.SYNC_MAX_LATENCY                                , LEGACY   ,   BC                   );
-                expectKeyAvailable(c, CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES                , FULL     ,   MANUAL_POSTPROC      );
-                expectKeyAvailable(c, CameraCharacteristics.TONEMAP_MAX_CURVE_POINTS                        , FULL     ,   MANUAL_POSTPROC      );
-
-                // Future: Use column editors for modifying above, ignore line length to keep 1 key per line
-
-                // TODO: check that no other 'android' keys are listed in #getKeys if they aren't in the above list
-            }
-
-            counter++;
-        }
-    }
-
-    /**
-     * Test values for static metadata used by the RAW capability.
-     */
-    public void testStaticRawCharacteristics() {
-        int counter = 0;
-        for (CameraCharacteristics c : mCharacteristics) {
-            int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
-            assertNotNull("android.request.availableCapabilities must never be null",
-                    actualCapabilities);
-            if (!arrayContains(actualCapabilities,
-                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
-                Log.i(TAG, "RAW capability is not supported in camera " + counter++ +
-                        ". Skip the test.");
-                continue;
-            }
-
-            Integer actualHwLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
-            if (actualHwLevel != null && actualHwLevel == FULL) {
-                mCollector.expectKeyValueContains(c,
-                        CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES,
-                        CameraCharacteristics.HOT_PIXEL_MODE_FAST);
-            }
-            mCollector.expectKeyValueContains(c,
-                    CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES, false);
-            mCollector.expectKeyValueGreaterThan(c, CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL,
-                    MIN_ALLOWABLE_WHITELEVEL);
-
-            mCollector.expectKeyValueIsIn(c,
-                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT,
-                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB,
-                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GRBG,
-                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_GBRG,
-                    CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_BGGR);
-            // TODO: SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGB isn't supported yet.
-
-            mCollector.expectKeyValueInRange(c, CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1,
-                    CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT,
-                    CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN);
-            mCollector.expectKeyValueInRange(c, CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2,
-                    (byte) CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT,
-                    (byte) CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1_ISO_STUDIO_TUNGSTEN);
-
-            Rational[] zeroes = new Rational[9];
-            Arrays.fill(zeroes, Rational.ZERO);
-
-            ColorSpaceTransform zeroed = new ColorSpaceTransform(zeroes);
-            mCollector.expectNotEquals("Forward Matrix1 should not contain all zeroes.", zeroed,
-                    c.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX1));
-            mCollector.expectNotEquals("Forward Matrix2 should not contain all zeroes.", zeroed,
-                    c.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX2));
-            mCollector.expectNotEquals("Calibration Transform1 should not contain all zeroes.",
-                    zeroed, c.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1));
-            mCollector.expectNotEquals("Calibration Transform2 should not contain all zeroes.",
-                    zeroed, c.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2));
-            mCollector.expectNotEquals("Color Transform1 should not contain all zeroes.",
-                    zeroed, c.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM1));
-            mCollector.expectNotEquals("Color Transform2 should not contain all zeroes.",
-                    zeroed, c.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM2));
-
-            BlackLevelPattern blackLevel = mCollector.expectKeyValueNotNull(c,
-                    CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN);
-            if (blackLevel != null) {
-                int[] blackLevelPattern = new int[BlackLevelPattern.COUNT];
-                blackLevel.copyTo(blackLevelPattern, /*offset*/0);
-                Integer whitelevel = c.get(CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL);
-                if (whitelevel != null) {
-                    mCollector.expectValuesInRange("BlackLevelPattern", blackLevelPattern, 0,
-                            whitelevel);
-                } else {
-                    mCollector.addMessage(
-                            "No WhiteLevel available, cannot check BlackLevelPattern range.");
-                }
-            }
-
-            // TODO: profileHueSatMap, and profileToneCurve aren't supported yet.
-            counter++;
-        }
-    }
-
-    /**
-     * Test values for static metadata used by the BURST capability.
-     */
-    public void testStaticBurstCharacteristics() {
-        int counter = 0;
-        final float SIZE_ERROR_MARGIN = 0.03f;
-        for (CameraCharacteristics c : mCharacteristics) {
-            int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
-            assertNotNull("android.request.availableCapabilities must never be null",
-                    actualCapabilities);
-
-            // Check if the burst capability is defined
-            boolean haveBurstCapability = arrayContains(actualCapabilities,
-                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
-
-            StreamConfigurationMap config =
-                    c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-            assertNotNull(String.format("No stream configuration map found for: ID %s",
-                    mIds[counter]), config);
-            Rect activeRect = c.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
-            Size sensorSize = new Size(activeRect.width(), activeRect.height());
-
-            // Ensure that max YUV size matches max JPEG size
-            Size maxYuvSize = CameraTestUtils.getMaxSize(
-                    config.getOutputSizes(ImageFormat.YUV_420_888));
-            Size maxJpegSize = CameraTestUtils.getMaxSize(config.getOutputSizes(ImageFormat.JPEG));
-
-            boolean haveMaxYuv = maxYuvSize != null ?
-                (maxJpegSize.getWidth() <= maxYuvSize.getWidth() &&
-                        maxJpegSize.getHeight() <= maxYuvSize.getHeight()) : false;
-
-            boolean maxYuvMatchSensor =
-                    (maxYuvSize.getWidth() <= sensorSize.getWidth() * (1.0 + SIZE_ERROR_MARGIN) &&
-                     maxYuvSize.getWidth() >= sensorSize.getWidth() * (1.0 - SIZE_ERROR_MARGIN) &&
-                     maxYuvSize.getHeight() <= sensorSize.getHeight() * (1.0 + SIZE_ERROR_MARGIN) &&
-                     maxYuvSize.getHeight() >= sensorSize.getHeight() * (1.0 - SIZE_ERROR_MARGIN));
-
-            // Ensure that YUV output is fast enough - needs to be at least 20 fps
-
-            long maxYuvRate =
-                config.getOutputMinFrameDuration(ImageFormat.YUV_420_888, maxYuvSize);
-            final long MIN_DURATION_BOUND_NS = 50000000; // 50 ms, 20 fps
-
-            boolean haveMaxYuvRate = maxYuvRate <= MIN_DURATION_BOUND_NS;
-
-            // Ensure that there's an FPS range that's fast enough to capture at above
-            // minFrameDuration, for full-auto bursts
-            Range[] fpsRanges = c.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
-            float minYuvFps = 1.f / maxYuvRate;
-
-            boolean haveFastAeTargetFps = false;
-            for (Range<Integer> r : fpsRanges) {
-                if (r.getLower() >= minYuvFps) {
-                    haveFastAeTargetFps = true;
-                    break;
-                }
-            }
-
-            // Ensure that maximum sync latency is small enough for fast setting changes, even if
-            // it's not quite per-frame
-
-            Integer maxSyncLatencyValue = c.get(CameraCharacteristics.SYNC_MAX_LATENCY);
-            assertNotNull(String.format("No sync latency declared for ID %s", mIds[counter]),
-                    maxSyncLatencyValue);
-
-            int maxSyncLatency = maxSyncLatencyValue;
-            final long MAX_LATENCY_BOUND = 4;
-            boolean haveFastSyncLatency =
-                (maxSyncLatency <= MAX_LATENCY_BOUND) && (maxSyncLatency >= 0);
-
-            if (haveBurstCapability) {
-                assertTrue(
-                        String.format("BURST-capable camera device %s does not have maximum YUV " +
-                                "size that is at least max JPEG size",
-                                mIds[counter]),
-                        haveMaxYuv);
-                assertTrue(
-                        String.format("BURST-capable camera device %s YUV frame rate is too slow" +
-                                "(%d ns min frame duration reported, less than %d ns expected)",
-                                mIds[counter], maxYuvRate, MIN_DURATION_BOUND_NS),
-                        haveMaxYuvRate);
-                assertTrue(
-                        String.format("BURST-capable camera device %s does not list an AE target " +
-                                " FPS range with min FPS >= %f, for full-AUTO bursts",
-                                mIds[counter], minYuvFps),
-                        haveFastAeTargetFps);
-                assertTrue(
-                        String.format("BURST-capable camera device %s YUV sync latency is too long" +
-                                "(%d frames reported, [0, %d] frames expected)",
-                                mIds[counter], maxSyncLatency, MAX_LATENCY_BOUND),
-                        haveFastSyncLatency);
-                assertTrue(
-                        "Active array size and max YUV size should be similar",
-                        maxYuvMatchSensor);
-            } else {
-                assertTrue(
-                        String.format("Camera device %s has all the requirements for BURST" +
-                                " capability but does not report it!", mIds[counter]),
-                        !(haveMaxYuv && haveMaxYuvRate && haveFastAeTargetFps &&
-                                haveFastSyncLatency && maxYuvMatchSensor));
-            }
-
-            counter++;
-        }
-    }
-
-    /**
-     * Cross-check StreamConfigurationMap output
-     */
-    public void testStreamConfigurationMap() {
-        int counter = 0;
-        for (CameraCharacteristics c : mCharacteristics) {
-            Log.i(TAG, "testStreamConfigurationMap: Testing camera ID " + mIds[counter]);
-            StreamConfigurationMap config =
-                    c.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-            assertNotNull(String.format("No stream configuration map found for: ID %s",
-                            mIds[counter]), config);
-
-            assertTrue("ImageReader must be supported",
-                    config.isOutputSupportedFor(android.media.ImageReader.class));
-            assertTrue("MediaRecorder must be supported",
-                    config.isOutputSupportedFor(android.media.MediaRecorder.class));
-            assertTrue("MediaCodec must be supported",
-                    config.isOutputSupportedFor(android.media.MediaCodec.class));
-            assertTrue("Allocation must be supported",
-                    config.isOutputSupportedFor(android.renderscript.Allocation.class));
-            assertTrue("SurfaceHolder must be supported",
-                    config.isOutputSupportedFor(android.view.SurfaceHolder.class));
-            assertTrue("SurfaceTexture must be supported",
-                    config.isOutputSupportedFor(android.graphics.SurfaceTexture.class));
-
-            assertTrue("YUV_420_888 must be supported",
-                    config.isOutputSupportedFor(ImageFormat.YUV_420_888));
-            assertTrue("JPEG must be supported",
-                    config.isOutputSupportedFor(ImageFormat.JPEG));
-
-            // Legacy YUV formats should not be listed
-            assertTrue("NV21 must not be supported",
-                    !config.isOutputSupportedFor(ImageFormat.NV21));
-
-            int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
-            assertNotNull("android.request.availableCapabilities must never be null",
-                    actualCapabilities);
-            if (arrayContains(actualCapabilities,
-                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
-                assertTrue("RAW_SENSOR must be supported if RAW capability is advertised",
-                    config.isOutputSupportedFor(ImageFormat.RAW_SENSOR));
-            }
-
-            // Cross check public formats and sizes
-
-            int[] supportedFormats = config.getOutputFormats();
-            for (int format : supportedFormats) {
-                assertTrue("Format " + format + " fails cross check",
-                        config.isOutputSupportedFor(format));
-                Size[] supportedSizes = config.getOutputSizes(format);
-                assertTrue("Supported format " + format + " has no sizes listed",
-                        supportedSizes.length > 0);
-                for (Size size : supportedSizes) {
-                    if (VERBOSE) {
-                        Log.v(TAG,
-                                String.format("Testing camera %s, format %d, size %s",
-                                        mIds[counter], format, size.toString()));
-                    }
-
-                    long stallDuration = config.getOutputStallDuration(format, size);
-                    switch(format) {
-                        case ImageFormat.YUV_420_888:
-                            assertTrue("YUV_420_888 may not have a non-zero stall duration",
-                                    stallDuration == 0);
-                            break;
-                        default:
-                            assertTrue("Negative stall duration for format " + format,
-                                    stallDuration >= 0);
-                            break;
-                    }
-                    long minDuration = config.getOutputMinFrameDuration(format, size);
-                    if (arrayContains(actualCapabilities,
-                            CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                        assertTrue("MANUAL_SENSOR capability, need positive min frame duration for"
-                                + "format " + format + " for size " + size + " minDuration " +
-                                minDuration,
-                                minDuration > 0);
-                    } else {
-                        assertTrue("Need non-negative min frame duration for format " + format,
-                                minDuration >= 0);
-                    }
-
-                    ImageReader testReader = ImageReader.newInstance(
-                        size.getWidth(),
-                        size.getHeight(),
-                        format,
-                        1);
-                    Surface testSurface = testReader.getSurface();
-
-                    assertTrue(
-                        String.format("isOutputSupportedFor fails for config %s, format %d",
-                                size.toString(), format),
-                        config.isOutputSupportedFor(testSurface));
-
-                    testReader.close();
-
-                } // sizes
-
-                // Try an invalid size in this format, should round
-                Size invalidSize = findInvalidSize(supportedSizes);
-                // WAR: the intended threshold is 1920, but to counter the bug
-                // in Lollipop framework, we need to set it to 1080 here.
-                // The threshold will be changed back to 1920 in next Android release.
-                int MAX_ROUNDING_WIDTH = 1080;
-                if (invalidSize.getWidth() <= MAX_ROUNDING_WIDTH) {
-                    ImageReader testReader = ImageReader.newInstance(
-                                                                     invalidSize.getWidth(),
-                                                                     invalidSize.getHeight(),
-                                                                     format,
-                                                                     1);
-                    Surface testSurface = testReader.getSurface();
-
-                    assertTrue(
-                               String.format("isOutputSupportedFor fails for config %s, %d",
-                                       invalidSize.toString(), format),
-                               config.isOutputSupportedFor(testSurface));
-
-                    testReader.close();
-                }
-            } // formats
-
-            // Cross-check opaque format and sizes
-
-            SurfaceTexture st = new SurfaceTexture(1);
-            Surface surf = new Surface(st);
-
-            Size[] opaqueSizes = config.getOutputSizes(SurfaceTexture.class);
-            assertTrue("Opaque format has no sizes listed",
-                    opaqueSizes.length > 0);
-            for (Size size : opaqueSizes) {
-                long stallDuration = config.getOutputStallDuration(SurfaceTexture.class, size);
-                assertTrue("Opaque output may not have a non-zero stall duration",
-                        stallDuration == 0);
-
-                long minDuration = config.getOutputMinFrameDuration(SurfaceTexture.class, size);
-                if (arrayContains(actualCapabilities,
-                                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                    assertTrue("MANUAL_SENSOR capability, need positive min frame duration for"
-                            + "opaque format",
-                            minDuration > 0);
-                } else {
-                    assertTrue("Need non-negative min frame duration for opaque format ",
-                            minDuration >= 0);
-                }
-                st.setDefaultBufferSize(size.getWidth(), size.getHeight());
-
-                assertTrue(
-                    String.format("isOutputSupportedFor fails for SurfaceTexture config %s",
-                            size.toString()),
-                    config.isOutputSupportedFor(surf));
-
-            } // opaque sizes
-
-            // Try invalid opaque size, should get rounded
-            Size invalidSize = findInvalidSize(opaqueSizes);
-            st.setDefaultBufferSize(invalidSize.getWidth(), invalidSize.getHeight());
-            assertTrue(
-                String.format("isOutputSupportedFor fails for SurfaceTexture config %s",
-                        invalidSize.toString()),
-                config.isOutputSupportedFor(surf));
-
-            counter++;
-        } // mCharacteristics
-
-    }
-
-    /**
-     * 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) {
-        Size invalidSize = new Size(goodSizes[0].getWidth() + 1, goodSizes[0].getHeight());
-        while(arrayContains(goodSizes, invalidSize)) {
-            invalidSize = new Size(invalidSize.getWidth() + 1, invalidSize.getHeight());
-        }
-        return invalidSize;
-    }
-
-    /**
-     * Check key is present in characteristics if the hardware level is at least {@code hwLevel};
-     * check that the key is present if the actual capabilities are one of {@code capabilities}.
-     *
-     * @return value of the {@code key} from {@code c}
-     */
-    private <T> T expectKeyAvailable(CameraCharacteristics c, CameraCharacteristics.Key<T> key,
-            int hwLevel, int... capabilities) {
-
-        Integer actualHwLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
-        assertNotNull("android.info.supportedHardwareLevel must never be null", actualHwLevel);
-
-        int[] actualCapabilities = c.get(CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES);
-        assertNotNull("android.request.availableCapabilities must never be null",
-                actualCapabilities);
-
-        List<Key<?>> allKeys = c.getKeys();
-
-        T value = c.get(key);
-
-        if (compareHardwareLevel(actualHwLevel, hwLevel) >= 0) {
-            mCollector.expectTrue(
-                    String.format("Key (%s) must be in characteristics for this hardware level " +
-                            "(required minimal HW level %s, actual HW level %s)",
-                            key.getName(), toStringHardwareLevel(hwLevel),
-                            toStringHardwareLevel(actualHwLevel)),
-                    value != null);
-            mCollector.expectTrue(
-                    String.format("Key (%s) must be in characteristics list of keys for this " +
-                            "hardware level (required minimal HW level %s, actual HW level %s)",
-                            key.getName(), toStringHardwareLevel(hwLevel),
-                            toStringHardwareLevel(actualHwLevel)),
-                    allKeys.contains(key));
-        } else if (arrayContainsAnyOf(actualCapabilities, capabilities)) {
-            mCollector.expectTrue(
-                    String.format("Key (%s) must be in characteristics for these capabilities " +
-                            "(required capabilities %s, actual capabilities %s)",
-                            key.getName(), Arrays.toString(capabilities),
-                            Arrays.toString(actualCapabilities)),
-                    value != null);
-            mCollector.expectTrue(
-                    String.format("Key (%s) must be in characteristics list of keys for " +
-                            "these capabilities (required capabilities %s, actual capabilities %s)",
-                            key.getName(), Arrays.toString(capabilities),
-                            Arrays.toString(actualCapabilities)),
-                    allKeys.contains(key));
-        } else {
-            if (actualHwLevel == LEGACY && hwLevel != OPT) {
-                if (value != null || allKeys.contains(key)) {
-                    Log.w(TAG, String.format(
-                            "Key (%s) is not required for LEGACY devices but still appears",
-                            key.getName()));
-                }
-            }
-            // OK: Key may or may not be present.
-        }
-        return value;
-    }
-
-    private static boolean arrayContains(int[] arr, int needle) {
-        if (arr == null) {
-            return false;
-        }
-
-        for (int elem : arr) {
-            if (elem == needle) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static <T> boolean arrayContains(T[] arr, T needle) {
-        if (arr == null) {
-            return false;
-        }
-
-        for (T elem : arr) {
-            if (elem.equals(needle)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private static boolean arrayContainsAnyOf(int[] arr, int[] needles) {
-        for (int needle : needles) {
-            if (arrayContains(arr, needle)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * The key name has a prefix of either "android." or "com."; other prefixes are not valid.
-     */
-    private static void assertKeyPrefixValid(String keyName) {
-        assertStartsWithAnyOf(
-                "All metadata keys must start with 'android.' (built-in keys) " +
-                "or 'com.' (vendor-extended keys)", new String[] {
-                        PREFIX_ANDROID + ".",
-                        PREFIX_VENDOR + ".",
-                }, keyName);
-    }
-
-    private static void assertTrueForKey(String msg, CameraCharacteristics.Key<?> key,
-            boolean actual) {
-        assertTrue(msg + " (key = '" + key.getName() + "')", actual);
-    }
-
-    private static <T> void assertOneOf(String msg, T[] expected, T actual) {
-        for (int i = 0; i < expected.length; ++i) {
-            if (Objects.equals(expected[i], actual)) {
-                return;
-            }
-        }
-
-        fail(String.format("%s: (expected one of %s, actual %s)",
-                msg, Arrays.toString(expected), actual));
-    }
-
-    private static <T> void assertStartsWithAnyOf(String msg, String[] expected, String actual) {
-        for (int i = 0; i < expected.length; ++i) {
-            if (actual.startsWith(expected[i])) {
-                return;
-            }
-        }
-
-        fail(String.format("%s: (expected to start with any of %s, but value was %s)",
-                msg, Arrays.toString(expected), actual));
-    }
-
-    /** Return a positive int if left > right, 0 if left==right, negative int if left < right */
-    private static int compareHardwareLevel(int left, int right) {
-        return remapHardwareLevel(left) - remapHardwareLevel(right);
-    }
-
-    /** Remap HW levels worst<->best, 0 = worst, 2 = best */
-    private static int remapHardwareLevel(int level) {
-        switch (level) {
-            case OPT:
-                return Integer.MAX_VALUE;
-            case LEGACY:
-                return 0; // lowest
-            case LIMITED:
-                return 1; // second lowest
-            case FULL:
-                return 2; // best
-        }
-
-        fail("Unknown HW level: " + level);
-        return -1;
-    }
-
-    private static String toStringHardwareLevel(int level) {
-        switch (level) {
-            case LEGACY:
-                return "LEGACY";
-            case LIMITED:
-                return "LIMITED";
-            case FULL:
-                return "FULL";
-        }
-
-        // unknown
-        Log.w(TAG, "Unknown hardware level " + level);
-        return Integer.toString(level);
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
deleted file mode 100644
index a410775..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/ImageReaderTest.java
+++ /dev/null
@@ -1,797 +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 android.hardware.camera2.cts;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.BitmapRegionDecoder;
-import android.graphics.Color;
-import android.graphics.ImageFormat;
-import android.graphics.Matrix;
-import android.graphics.Rect;
-import android.graphics.RectF;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.cts.helpers.StaticMetadata;
-import android.hardware.camera2.cts.rs.BitmapUtils;
-import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.media.Image;
-import android.media.ImageReader;
-import android.os.ConditionVariable;
-import android.util.Log;
-import android.util.Size;
-import android.view.Surface;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.List;
-
-import static android.hardware.camera2.cts.CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS;
-import static android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
-import static android.hardware.camera2.cts.CameraTestUtils.SimpleImageReaderListener;
-import static android.hardware.camera2.cts.CameraTestUtils.dumpFile;
-import static android.hardware.camera2.cts.CameraTestUtils.getValueNotNull;
-
-/**
- * <p>Basic test for ImageReader APIs. It uses CameraDevice as producer, camera
- * sends the data to the surface provided by imageReader. Below image formats
- * are tested:</p>
- *
- * <p>YUV_420_888: flexible YUV420, it is mandatory format for camera. </p>
- * <p>JPEG: used for JPEG still capture, also mandatory format. </p>
- * <p>Some invalid access test. </p>
- * <p>TODO: Add more format tests? </p>
- */
-public class ImageReaderTest extends Camera2AndroidTestCase {
-    private static final String TAG = "ImageReaderTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    // number of frame (for streaming requests) to be verified.
-    private static final int NUM_FRAME_VERIFIED = 2;
-    // Max number of images can be accessed simultaneously from ImageReader.
-    private static final int MAX_NUM_IMAGES = 5;
-    // Max difference allowed between YUV and JPEG patches. This tolerance is intentionally very
-    // generous to avoid false positives due to punch/saturation operations vendors apply to the
-    // JPEG outputs.
-    private static final double IMAGE_DIFFERENCE_TOLERANCE = 30;
-
-    private SimpleImageListener mListener;
-
-    @Override
-    public void setContext(Context context) {
-        super.setContext(context);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testFlexibleYuv() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing Camera " + id);
-                openDevice(id);
-                bufferFormatTestByCamera(ImageFormat.YUV_420_888, /*repeating*/true);
-            } finally {
-                closeDevice(id);
-            }
-        }
-    }
-
-    public void testJpeg() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.v(TAG, "Testing jpeg capture for Camera " + id);
-                openDevice(id);
-                bufferFormatTestByCamera(ImageFormat.JPEG, /*repeating*/false);
-            } finally {
-                closeDevice(id);
-            }
-        }
-    }
-
-    public void testRaw() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.v(TAG, "Testing raw capture for camera " + id);
-                openDevice(id);
-
-                bufferFormatTestByCamera(ImageFormat.RAW_SENSOR, /*repeating*/false);
-            } finally {
-                closeDevice(id);
-            }
-        }
-    }
-
-    public void testRepeatingJpeg() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.v(TAG, "Testing repeating jpeg capture for Camera " + id);
-                openDevice(id);
-                bufferFormatTestByCamera(ImageFormat.JPEG, /*repeating*/true);
-            } finally {
-                closeDevice(id);
-            }
-        }
-    }
-
-    public void testRepeatingRaw() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.v(TAG, "Testing repeating raw capture for camera " + id);
-                openDevice(id);
-
-                bufferFormatTestByCamera(ImageFormat.RAW_SENSOR, /*repeating*/true);
-            } finally {
-                closeDevice(id);
-            }
-        }
-    }
-
-    /**
-     * Test invalid access of image byte buffers: when an image is closed, further access
-     * of the image byte buffers will get an IllegalStateException. The basic assumption of
-     * this test is that the ImageReader always gives direct byte buffer, which is always true
-     * for camera case. For if the produced image byte buffer is not direct byte buffer, there
-     * is no guarantee to get an ISE for this invalid access case.
-     */
-    public void testInvalidAccessTest() throws Exception {
-        // Test byte buffer access after an image is released, it should throw ISE.
-        for (String id : mCameraIds) {
-            try {
-                Log.v(TAG, "Testing invalid image access for Camera " + id);
-                openDevice(id);
-                bufferAccessAfterRelease();
-                fail("ImageReader should throw IllegalStateException when accessing a byte buffer"
-                        + " after the image is closed");
-            } catch (IllegalStateException e) {
-                // Expected.
-            } finally {
-                closeDevice(id);
-            }
-        }
-
-    }
-
-    /**
-     * Test two image stream (YUV420_888 and JPEG) capture by using ImageReader.
-     *
-     * <p>Both stream formats are mandatory for Camera2 API</p>
-     */
-    public void testYuvAndJpeg() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.v(TAG, "YUV and JPEG testing for camera " + id);
-                openDevice(id);
-
-                bufferFormatWithYuvTestByCamera(ImageFormat.JPEG);
-            } finally {
-                closeDevice(id);
-            }
-        }
-    }
-
-    /**
-     * Test two image stream (YUV420_888 and RAW_SENSOR) capture by using ImageReader.
-     *
-     */
-    public void testImageReaderYuvAndRaw() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.v(TAG, "YUV and RAW testing for camera " + id);
-                openDevice(id);
-
-                bufferFormatWithYuvTestByCamera(ImageFormat.RAW_SENSOR);
-            } finally {
-                closeDevice(id);
-            }
-        }
-    }
-
-    /**
-     * Check that the center patches for YUV and JPEG outputs for the same frame match for each YUV
-     * resolution and format supported.
-     */
-    public void testAllOutputYUVResolutions() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.v(TAG, "Testing all YUV image resolutions for camera " + id);
-                openDevice(id);
-
-                // Skip warmup on FULL mode devices.
-                int warmupCaptureNumber = (mStaticInfo.isHardwareLevelLegacy()) ?
-                        MAX_NUM_IMAGES - 1 : 0;
-
-                // NV21 isn't supported by ImageReader.
-                final int[] YUVFormats = new int[] {ImageFormat.YUV_420_888, ImageFormat.YV12};
-
-                CameraCharacteristics.Key<StreamConfigurationMap> key =
-                        CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
-                StreamConfigurationMap config = mStaticInfo.getValueFromKeyNonNull(key);
-                int[] supportedFormats = config.getOutputFormats();
-                List<Integer> supportedYUVFormats = new ArrayList<>();
-                for (int format : YUVFormats) {
-                    if (CameraTestUtils.contains(supportedFormats, format)) {
-                        supportedYUVFormats.add(format);
-                    }
-                }
-
-                Size[] jpegSizes = mStaticInfo.getAvailableSizesForFormatChecked(ImageFormat.JPEG,
-                        StaticMetadata.StreamDirection.Output);
-                assertFalse("JPEG output not supported for camera " + id +
-                        ", at least one JPEG output is required.", jpegSizes.length == 0);
-
-                Size maxJpegSize = CameraTestUtils.getMaxSize(jpegSizes);
-
-                for (int format : supportedYUVFormats) {
-                    Size[] targetCaptureSizes =
-                            mStaticInfo.getAvailableSizesForFormatChecked(format,
-                            StaticMetadata.StreamDirection.Output);
-
-                    for (Size captureSz : targetCaptureSizes) {
-                        if (VERBOSE) {
-                            Log.v(TAG, "Testing yuv size " + captureSz + " and jpeg size "
-                                    + maxJpegSize + " for camera " + mCamera.getId());
-                        }
-
-                        ImageReader jpegReader = null;
-                        ImageReader yuvReader = null;
-                        try {
-                            // Create YUV image reader
-                            SimpleImageReaderListener yuvListener = new SimpleImageReaderListener();
-                            yuvReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
-                                    yuvListener);
-                            Surface yuvSurface = yuvReader.getSurface();
-
-                            // Create JPEG image reader
-                            SimpleImageReaderListener jpegListener =
-                                    new SimpleImageReaderListener();
-                            jpegReader = createImageReader(maxJpegSize,
-                                    ImageFormat.JPEG, MAX_NUM_IMAGES, jpegListener);
-                            Surface jpegSurface = jpegReader.getSurface();
-
-                            // Setup session
-                            List<Surface> outputSurfaces = new ArrayList<Surface>();
-                            outputSurfaces.add(yuvSurface);
-                            outputSurfaces.add(jpegSurface);
-                            createSession(outputSurfaces);
-
-                            // Warm up camera preview (mainly to give legacy devices time to do 3A).
-                            CaptureRequest.Builder warmupRequest =
-                                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                            warmupRequest.addTarget(yuvSurface);
-                            assertNotNull("Fail to get CaptureRequest.Builder", warmupRequest);
-                            SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-
-                            for (int i = 0; i < warmupCaptureNumber; i++) {
-                                startCapture(warmupRequest.build(), /*repeating*/false,
-                                        resultListener, mHandler);
-                            }
-                            for (int i = 0; i < warmupCaptureNumber; i++) {
-                                resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
-                                Image image = yuvListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
-                                image.close();
-                            }
-
-                            // Capture image.
-                            CaptureRequest.Builder mainRequest =
-                                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                            for (Surface s : outputSurfaces) {
-                                mainRequest.addTarget(s);
-                            }
-
-                            startCapture(mainRequest.build(), /*repeating*/false, resultListener,
-                                    mHandler);
-
-                            // Verify capture result and images
-                            resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
-
-                            Image yuvImage = yuvListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
-                            Image jpegImage = jpegListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
-
-                            //Validate captured images.
-                            CameraTestUtils.validateImage(yuvImage, captureSz.getWidth(),
-                                    captureSz.getHeight(), format, /*filePath*/null);
-                            CameraTestUtils.validateImage(jpegImage, maxJpegSize.getWidth(),
-                                    maxJpegSize.getHeight(), ImageFormat.JPEG, /*filePath*/null);
-
-                            // Compare the image centers.
-                            RectF jpegDimens = new RectF(0, 0, jpegImage.getWidth(),
-                                    jpegImage.getHeight());
-                            RectF yuvDimens = new RectF(0, 0, yuvImage.getWidth(),
-                                    yuvImage.getHeight());
-
-                            // Find scale difference between YUV and JPEG output
-                            Matrix m = new Matrix();
-                            m.setRectToRect(yuvDimens, jpegDimens, Matrix.ScaleToFit.START);
-                            RectF scaledYuv = new RectF();
-                            m.mapRect(scaledYuv, yuvDimens);
-                            float scale = scaledYuv.width() / yuvDimens.width();
-
-                            final int PATCH_DIMEN = 40; // pixels in YUV
-
-                            // Find matching square patch of pixels in YUV and JPEG output
-                            RectF tempPatch = new RectF(0, 0, PATCH_DIMEN, PATCH_DIMEN);
-                            tempPatch.offset(yuvDimens.centerX() - tempPatch.centerX(),
-                                    yuvDimens.centerY() - tempPatch.centerY());
-                            Rect yuvPatch = new Rect();
-                            tempPatch.roundOut(yuvPatch);
-
-                            tempPatch.set(0, 0, PATCH_DIMEN * scale, PATCH_DIMEN * scale);
-                            tempPatch.offset(jpegDimens.centerX() - tempPatch.centerX(),
-                                    jpegDimens.centerY() - tempPatch.centerY());
-                            Rect jpegPatch = new Rect();
-                            tempPatch.roundOut(jpegPatch);
-
-                            // Decode center patches
-                            int[] yuvColors = convertPixelYuvToRgba(yuvPatch.width(),
-                                    yuvPatch.height(), yuvPatch.left, yuvPatch.top, yuvImage);
-                            Bitmap yuvBmap = Bitmap.createBitmap(yuvColors, yuvPatch.width(),
-                                    yuvPatch.height(), Bitmap.Config.ARGB_8888);
-
-                            byte[] compressedJpegData = CameraTestUtils.getDataFromImage(jpegImage);
-                            BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(
-                                    compressedJpegData, /*offset*/0, compressedJpegData.length,
-                                    /*isShareable*/true);
-                            BitmapFactory.Options opt = new BitmapFactory.Options();
-                            opt.inPreferredConfig = Bitmap.Config.ARGB_8888;
-                            Bitmap fullSizeJpegBmap = decoder.decodeRegion(jpegPatch, opt);
-                            Bitmap jpegBmap = Bitmap.createScaledBitmap(fullSizeJpegBmap,
-                                    yuvPatch.width(), yuvPatch.height(), /*filter*/true);
-
-                            // Compare two patches using average of per-pixel differences
-                            double difference = BitmapUtils.calcDifferenceMetric(yuvBmap, jpegBmap);
-
-                            Log.i(TAG, "Difference for resolution " + captureSz + " is: " +
-                                    difference);
-                            if (difference > IMAGE_DIFFERENCE_TOLERANCE) {
-                                // Dump files if running in verbose mode
-                                if (DEBUG) {
-                                    String jpegFileName = DEBUG_FILE_NAME_BASE + "/" + captureSz +
-                                            "_jpeg.jpg";
-                                    dumpFile(jpegFileName, jpegBmap);
-                                    String fullSizeJpegFileName = DEBUG_FILE_NAME_BASE + "/" +
-                                            captureSz + "_full_jpeg.jpg";
-                                    dumpFile(fullSizeJpegFileName, compressedJpegData);
-                                    String yuvFileName = DEBUG_FILE_NAME_BASE + "/" + captureSz +
-                                            "_yuv.jpg";
-                                    dumpFile(yuvFileName, yuvBmap);
-                                    String fullSizeYuvFileName = DEBUG_FILE_NAME_BASE + "/" +
-                                            captureSz + "_full_yuv.jpg";
-                                    int[] fullYUVColors = convertPixelYuvToRgba(yuvImage.getWidth(),
-                                            yuvImage.getHeight(), 0, 0, yuvImage);
-                                    Bitmap fullYUVBmap = Bitmap.createBitmap(fullYUVColors,
-                                            yuvImage.getWidth(), yuvImage.getHeight(),
-                                            Bitmap.Config.ARGB_8888);
-                                    dumpFile(fullSizeYuvFileName, fullYUVBmap);
-                                }
-                                fail("Camera " + mCamera.getId() + ": YUV and JPEG image at " +
-                                        "capture size " + captureSz + " for the same frame are " +
-                                        "not similar, center patches have difference metric of " +
-                                        difference);
-                            }
-
-                            // Stop capture, delete the streams.
-                            stopCapture(/*fast*/false);
-                        } finally {
-                            closeImageReader(jpegReader);
-                            jpegReader = null;
-                            closeImageReader(yuvReader);
-                            yuvReader = null;
-                        }
-                    }
-                }
-
-            } finally {
-                closeDevice(id);
-            }
-        }
-    }
-
-    /**
-     * Convert a rectangular patch in a YUV image to an ARGB color array.
-     *
-     * @param w width of the patch.
-     * @param h height of the patch.
-     * @param wOffset offset of the left side of the patch.
-     * @param hOffset offset of the top of the patch.
-     * @param yuvImage a YUV image to select a patch from.
-     * @return the image patch converted to RGB as an ARGB color array.
-     */
-    private static int[] convertPixelYuvToRgba(int w, int h, int wOffset, int hOffset,
-                                               Image yuvImage) {
-        final int CHANNELS = 3; // yuv
-        final float COLOR_RANGE = 255f;
-
-        assertTrue("Invalid argument to convertPixelYuvToRgba",
-                w > 0 && h > 0 && wOffset >= 0 && hOffset >= 0);
-        assertNotNull(yuvImage);
-
-        int imageFormat = yuvImage.getFormat();
-        assertTrue("YUV image must have YUV-type format",
-                imageFormat == ImageFormat.YUV_420_888 || imageFormat == ImageFormat.YV12 ||
-                        imageFormat == ImageFormat.NV21);
-
-        int height = yuvImage.getHeight();
-        int width = yuvImage.getWidth();
-
-        Rect imageBounds = new Rect(/*left*/0, /*top*/0, /*right*/width, /*bottom*/height);
-        Rect crop = new Rect(/*left*/wOffset, /*top*/hOffset, /*right*/wOffset + w,
-                /*bottom*/hOffset + h);
-        assertTrue("Output rectangle" + crop + " must lie within image bounds " + imageBounds,
-                imageBounds.contains(crop));
-        Image.Plane[] planes = yuvImage.getPlanes();
-
-        Image.Plane yPlane = planes[0];
-        Image.Plane cbPlane = planes[1];
-        Image.Plane crPlane = planes[2];
-
-        ByteBuffer yBuf = yPlane.getBuffer();
-        int yPixStride = yPlane.getPixelStride();
-        int yRowStride = yPlane.getRowStride();
-        ByteBuffer cbBuf = cbPlane.getBuffer();
-        int cbPixStride = cbPlane.getPixelStride();
-        int cbRowStride = cbPlane.getRowStride();
-        ByteBuffer crBuf = crPlane.getBuffer();
-        int crPixStride = crPlane.getPixelStride();
-        int crRowStride = crPlane.getRowStride();
-
-        int[] output = new int[w * h];
-
-        // TODO: Optimize this with renderscript intrinsics
-        byte[] yRow = new byte[yPixStride * w];
-        byte[] cbRow = new byte[cbPixStride * w / 2];
-        byte[] crRow = new byte[crPixStride * w / 2];
-        yBuf.mark();
-        cbBuf.mark();
-        crBuf.mark();
-        int initialYPos = yBuf.position();
-        int initialCbPos = cbBuf.position();
-        int initialCrPos = crBuf.position();
-        int outputPos = 0;
-        for (int i = hOffset; i < hOffset + h; i++) {
-            yBuf.position(initialYPos + i * yRowStride + wOffset * yPixStride);
-            yBuf.get(yRow);
-            if ((i & 1) == (hOffset & 1)) {
-                cbBuf.position(initialCbPos + (i / 2) * cbRowStride + wOffset * cbPixStride / 2);
-                cbBuf.get(cbRow);
-                crBuf.position(initialCrPos + (i / 2) * crRowStride + wOffset * crPixStride / 2);
-                crBuf.get(crRow);
-            }
-            for (int j = 0, yPix = 0, crPix = 0, cbPix = 0; j < w; j++, yPix += yPixStride) {
-                float y = yRow[yPix] & 0xFF;
-                float cb = cbRow[cbPix] & 0xFF;
-                float cr = crRow[crPix] & 0xFF;
-
-                // convert YUV -> RGB (from JFIF's "Conversion to and from RGB" section)
-                int r = (int) Math.max(0.0f, Math.min(COLOR_RANGE, y + 1.402f * (cr - 128)));
-                int g = (int) Math.max(0.0f,
-                        Math.min(COLOR_RANGE, y - 0.34414f * (cb - 128) - 0.71414f * (cr - 128)));
-                int b = (int) Math.max(0.0f, Math.min(COLOR_RANGE, y + 1.772f * (cb - 128)));
-
-                // Convert to ARGB pixel color (use opaque alpha)
-                output[outputPos++] = Color.rgb(r, g, b);
-
-                if ((j & 1) == 1) {
-                    crPix += crPixStride;
-                    cbPix += cbPixStride;
-                }
-            }
-        }
-        yBuf.rewind();
-        cbBuf.rewind();
-        crBuf.rewind();
-
-        return output;
-    }
-
-    /**
-     * Test capture a given format stream with yuv stream simultaneously.
-     *
-     * <p>Use fixed yuv size, varies targeted format capture size. Single capture is tested.</p>
-     *
-     * @param format The capture format to be tested along with yuv format.
-     */
-    private void bufferFormatWithYuvTestByCamera(int format) throws Exception {
-        if (format != ImageFormat.JPEG && format != ImageFormat.RAW_SENSOR
-                && format != ImageFormat.YUV_420_888) {
-            throw new IllegalArgumentException("Unsupported format: " + format);
-        }
-
-        final int NUM_SINGLE_CAPTURE_TESTED = MAX_NUM_IMAGES - 1;
-        Size maxYuvSz = mOrderedPreviewSizes.get(0);
-        Size[] targetCaptureSizes = mStaticInfo.getAvailableSizesForFormatChecked(format,
-                StaticMetadata.StreamDirection.Output);
-
-        for (Size captureSz : targetCaptureSizes) {
-            if (VERBOSE) {
-                Log.v(TAG, "Testing yuv size " + maxYuvSz.toString() + " and capture size "
-                        + captureSz.toString() + " for camera " + mCamera.getId());
-            }
-
-            ImageReader captureReader = null;
-            ImageReader yuvReader = null;
-            try {
-                // Create YUV image reader
-                SimpleImageReaderListener yuvListener  = new SimpleImageReaderListener();
-                yuvReader = createImageReader(maxYuvSz, ImageFormat.YUV_420_888, MAX_NUM_IMAGES,
-                        yuvListener);
-                Surface yuvSurface = yuvReader.getSurface();
-
-                // Create capture image reader
-                SimpleImageReaderListener captureListener = new SimpleImageReaderListener();
-                captureReader = createImageReader(captureSz, format, MAX_NUM_IMAGES,
-                        captureListener);
-                Surface captureSurface = captureReader.getSurface();
-
-                // Capture images.
-                List<Surface> outputSurfaces = new ArrayList<Surface>();
-                outputSurfaces.add(yuvSurface);
-                outputSurfaces.add(captureSurface);
-                CaptureRequest.Builder request = prepareCaptureRequestForSurfaces(outputSurfaces);
-                SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-
-                for (int i = 0; i < NUM_SINGLE_CAPTURE_TESTED; i++) {
-                    startCapture(request.build(), /*repeating*/false, resultListener, mHandler);
-                }
-
-                // Verify capture result and images
-                for (int i = 0; i < NUM_SINGLE_CAPTURE_TESTED; i++) {
-                    resultListener.getCaptureResult(CAPTURE_WAIT_TIMEOUT_MS);
-                    if (VERBOSE) {
-                        Log.v(TAG, " Got the capture result back for " + i + "th capture");
-                    }
-
-                    Image yuvImage = yuvListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
-                    if (VERBOSE) {
-                        Log.v(TAG, " Got the yuv image back for " + i + "th capture");
-                    }
-
-                    Image captureImage = captureListener.getImage(CAPTURE_WAIT_TIMEOUT_MS);
-                    if (VERBOSE) {
-                        Log.v(TAG, " Got the capture image back for " + i + "th capture");
-                    }
-
-                    //Validate captured images.
-                    CameraTestUtils.validateImage(yuvImage, maxYuvSz.getWidth(),
-                            maxYuvSz.getHeight(), ImageFormat.YUV_420_888, /*filePath*/null);
-                    CameraTestUtils.validateImage(captureImage, captureSz.getWidth(),
-                            captureSz.getHeight(), format, /*filePath*/null);
-                }
-
-                // Stop capture, delete the streams.
-                stopCapture(/*fast*/false);
-            } finally {
-                closeImageReader(captureReader);
-                captureReader = null;
-                closeImageReader(yuvReader);
-                yuvReader = null;
-            }
-        }
-    }
-
-    /**
-     * Test buffer access after release, YUV420_888 single capture is tested. This method
-     * should throw ISE.
-     */
-    private void bufferAccessAfterRelease() throws Exception {
-        final int FORMAT = ImageFormat.YUV_420_888;
-        Size[] availableSizes = mStaticInfo.getAvailableSizesForFormatChecked(FORMAT,
-                StaticMetadata.StreamDirection.Output);
-
-        try {
-            // Create ImageReader.
-            mListener = new SimpleImageListener();
-            createDefaultImageReader(availableSizes[0], FORMAT, MAX_NUM_IMAGES, mListener);
-
-            // Start capture.
-            CaptureRequest request = prepareCaptureRequest();
-            SimpleCaptureCallback listener = new SimpleCaptureCallback();
-            startCapture(request, /* repeating */false, listener, mHandler);
-
-            mListener.waitForAnyImageAvailable(CAPTURE_WAIT_TIMEOUT_MS);
-            Image img = mReader.acquireNextImage();
-            ByteBuffer buffer = img.getPlanes()[0].getBuffer();
-            img.close();
-
-            byte data = buffer.get(); // An ISE should be thrown here.
-        } finally {
-            closeDefaultImageReader();
-        }
-    }
-
-    private void bufferFormatTestByCamera(int format, boolean repeating) throws Exception {
-
-        Size[] availableSizes = mStaticInfo.getAvailableSizesForFormatChecked(format,
-                StaticMetadata.StreamDirection.Output);
-
-        // for each resolution, test imageReader:
-        for (Size sz : availableSizes) {
-            try {
-                if (VERBOSE) {
-                    Log.v(TAG, "Testing size " + sz.toString() + " format " + format
-                            + " for camera " + mCamera.getId());
-                }
-
-                // Create ImageReader.
-                mListener  = new SimpleImageListener();
-                createDefaultImageReader(sz, format, MAX_NUM_IMAGES, mListener);
-
-                // Start capture.
-                CaptureRequest request = prepareCaptureRequest();
-                SimpleCaptureCallback listener = new SimpleCaptureCallback();
-                startCapture(request, repeating, listener, mHandler);
-
-                int numFrameVerified = repeating ? NUM_FRAME_VERIFIED : 1;
-
-                // Validate images.
-                validateImage(sz, format, numFrameVerified, repeating);
-
-                // Validate capture result.
-                validateCaptureResult(format, sz, listener, numFrameVerified);
-
-                // stop capture.
-                stopCapture(/*fast*/false);
-            } finally {
-                closeDefaultImageReader();
-            }
-
-        }
-    }
-
-    /**
-     * Validate capture results.
-     *
-     * @param format The format of this capture.
-     * @param size The capture size.
-     * @param listener The capture listener to get capture result callbacks.
-     */
-    private void validateCaptureResult(int format, Size size, SimpleCaptureCallback listener,
-            int numFrameVerified) {
-        for (int i = 0; i < numFrameVerified; i++) {
-            CaptureResult result = listener.getCaptureResult(CAPTURE_RESULT_TIMEOUT_MS);
-
-            // TODO: Update this to use availableResultKeys once shim supports this.
-            if (mStaticInfo.isCapabilitySupported(
-                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                Long exposureTime = getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
-                Integer sensitivity = getValueNotNull(result, CaptureResult.SENSOR_SENSITIVITY);
-                mCollector.expectInRange(
-                        String.format(
-                                "Capture for format %d, size %s exposure time is invalid.",
-                                format, size.toString()),
-                        exposureTime,
-                        mStaticInfo.getExposureMinimumOrDefault(),
-                        mStaticInfo.getExposureMaximumOrDefault()
-                );
-                mCollector.expectInRange(
-                        String.format("Capture for format %d, size %s sensitivity is invalid.",
-                                format, size.toString()),
-                        sensitivity,
-                        mStaticInfo.getSensitivityMinimumOrDefault(),
-                        mStaticInfo.getSensitivityMaximumOrDefault()
-                );
-            }
-            // TODO: add more key validations.
-        }
-    }
-
-    private final class SimpleImageListener implements ImageReader.OnImageAvailableListener {
-        private final ConditionVariable imageAvailable = new ConditionVariable();
-        @Override
-        public void onImageAvailable(ImageReader reader) {
-            if (mReader != reader) {
-                return;
-            }
-
-            if (VERBOSE) Log.v(TAG, "new image available");
-            imageAvailable.open();
-        }
-
-        public void waitForAnyImageAvailable(long timeout) {
-            if (imageAvailable.block(timeout)) {
-                imageAvailable.close();
-            } else {
-                fail("wait for image available timed out after " + timeout + "ms");
-            }
-        }
-
-        public void closePendingImages() {
-            Image image = mReader.acquireLatestImage();
-            if (image != null) {
-                image.close();
-            }
-        }
-    }
-
-    private CaptureRequest prepareCaptureRequest() throws Exception {
-        List<Surface> outputSurfaces = new ArrayList<Surface>();
-        Surface surface = mReader.getSurface();
-        assertNotNull("Fail to get surface from ImageReader", surface);
-        outputSurfaces.add(surface);
-        return prepareCaptureRequestForSurfaces(outputSurfaces).build();
-    }
-
-    private CaptureRequest.Builder prepareCaptureRequestForSurfaces(List<Surface> surfaces)
-            throws Exception {
-        createSession(surfaces);
-
-        CaptureRequest.Builder captureBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        assertNotNull("Fail to get captureRequest", captureBuilder);
-        for (Surface surface : surfaces) {
-            captureBuilder.addTarget(surface);
-        }
-
-        return captureBuilder;
-    }
-
-    private void validateImage(Size sz, int format, int captureCount,  boolean repeating)
-            throws Exception {
-        // TODO: Add more format here, and wrap each one as a function.
-        Image img;
-        final int MAX_RETRY_COUNT = 20;
-        int numImageVerified = 0;
-        int reTryCount = 0;
-        while (numImageVerified < captureCount) {
-            assertNotNull("Image listener is null", mListener);
-            if (VERBOSE) Log.v(TAG, "Waiting for an Image");
-            mListener.waitForAnyImageAvailable(CAPTURE_WAIT_TIMEOUT_MS);
-            if (repeating) {
-                /**
-                 * Acquire the latest image in case the validation is slower than
-                 * the image producing rate.
-                 */
-                img = mReader.acquireLatestImage();
-                /**
-                 * Sometimes if multiple onImageAvailable callbacks being queued,
-                 * acquireLatestImage will clear all buffer before corresponding callback is
-                 * executed. Wait for a new frame in that case.
-                 */
-                if (img == null && reTryCount < MAX_RETRY_COUNT) {
-                    reTryCount++;
-                    continue;
-                }
-            } else {
-                img = mReader.acquireNextImage();
-            }
-            assertNotNull("Unable to acquire the latest image", img);
-            if (VERBOSE) Log.v(TAG, "Got the latest image");
-            CameraTestUtils.validateImage(img, sz.getWidth(), sz.getHeight(), format,
-                    DEBUG_FILE_NAME_BASE);
-            if (VERBOSE) Log.v(TAG, "finish vaildation of image " + numImageVerified);
-            img.close();
-            numImageVerified++;
-            reTryCount = 0;
-        }
-
-        // Return all pending images to the ImageReader as the validateImage may
-        // take a while to return and there could be many images pending.
-        mListener.closePendingImages();
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/MultiViewTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/MultiViewTest.java
deleted file mode 100644
index 0d0ecb4..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/MultiViewTest.java
+++ /dev/null
@@ -1,245 +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.hardware.camera2.cts;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-
-import android.graphics.ImageFormat;
-import android.graphics.SurfaceTexture;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.cts.CameraTestUtils.ImageVerifierListener;
-import android.hardware.camera2.cts.testcases.Camera2MultiViewTestCase;
-import android.hardware.camera2.cts.testcases.Camera2MultiViewTestCase.CameraPreviewListener;
-import android.media.ImageReader;
-import android.os.SystemClock;
-import android.util.Log;
-import android.util.Size;
-import android.view.Surface;
-import android.view.TextureView;
-
-import com.android.ex.camera2.blocking.BlockingCameraManager.BlockingOpenException;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * CameraDevice test by using combination of SurfaceView, TextureView and ImageReader
- */
-public class MultiViewTest extends Camera2MultiViewTestCase {
-    private static final String TAG = "MultiViewTest";
-    private final static long WAIT_FOR_COMMAND_TO_COMPLETE = 2000;
-    private final static long PREVIEW_TIME_MS = 2000;
-
-    public void testTextureViewPreview() throws Exception {
-        for (String cameraId : mCameraIds) {
-            openCamera(cameraId);
-            List<TextureView> views = Arrays.asList(mTextureView[0]);
-            textureViewPreview(cameraId, views, /*ImageReader*/null);
-            closeCamera(cameraId);
-        }
-    }
-
-    public void testTextureViewPreviewWithImageReader() throws Exception {
-        for (String cameraId : mCameraIds) {
-            Exception prior = null;
-
-            ImageVerifierListener yuvListener;
-            ImageReader yuvReader;
-
-            try {
-                openCamera(cameraId);
-                Size previewSize = getOrderedPreviewSizes(cameraId).get(0);
-                yuvListener =
-                        new ImageVerifierListener(previewSize, ImageFormat.YUV_420_888);
-                yuvReader = makeImageReader(previewSize,
-                        ImageFormat.YUV_420_888, MAX_READER_IMAGES, yuvListener, mHandler);
-                int maxNumStreamsProc =
-                        getStaticInfo(cameraId).getMaxNumOutputStreamsProcessedChecked();
-                if (maxNumStreamsProc < 2) {
-                    continue;
-                }
-                List<TextureView> views = Arrays.asList(mTextureView[0]);
-                textureViewPreview(cameraId, views, yuvReader);
-            } catch (Exception e) {
-                prior = e;
-            } finally {
-                try {
-                    closeCamera(cameraId);
-                } catch (Exception e) {
-                    if (prior != null) {
-                        Log.e(TAG, "Prior exception received: " + prior);
-                    }
-                    prior = e;
-                }
-                if (prior != null) throw prior; // Rethrow last exception.
-            }
-        }
-    }
-
-    public void testDualTextureViewPreview() throws Exception {
-        for (String cameraId : mCameraIds) {
-            Exception prior = null;
-            try {
-                openCamera(cameraId);
-                int maxNumStreamsProc =
-                        getStaticInfo(cameraId).getMaxNumOutputStreamsProcessedChecked();
-                if (maxNumStreamsProc < 2) {
-                    continue;
-                }
-                List<TextureView> views = Arrays.asList(mTextureView[0], mTextureView[1]);
-                textureViewPreview(cameraId, views, /*ImageReader*/null);
-            } catch (Exception e) {
-                prior = e;
-            } finally {
-                try {
-                    closeCamera(cameraId);
-                } catch (Exception e) {
-                    if (prior != null) {
-                        Log.e(TAG, "Prior exception received: " + prior);
-                    }
-                    prior = e;
-                }
-                if (prior != null) throw prior; // Rethrow last exception.
-            }
-        }
-    }
-
-    public void testDualTextureViewAndImageReaderPreview() throws Exception {
-        for (String cameraId : mCameraIds) {
-            Exception prior = null;
-
-            ImageVerifierListener yuvListener;
-            ImageReader yuvReader;
-
-            try {
-                openCamera(cameraId);
-                Size previewSize = getOrderedPreviewSizes(cameraId).get(0);
-                yuvListener =
-                        new ImageVerifierListener(previewSize, ImageFormat.YUV_420_888);
-                yuvReader = makeImageReader(previewSize,
-                        ImageFormat.YUV_420_888, MAX_READER_IMAGES, yuvListener, mHandler);
-                int maxNumStreamsProc =
-                        getStaticInfo(cameraId).getMaxNumOutputStreamsProcessedChecked();
-                if (maxNumStreamsProc < 3) {
-                    continue;
-                }
-                List<TextureView> views = Arrays.asList(mTextureView[0], mTextureView[1]);
-                textureViewPreview(cameraId, views, yuvReader);
-            } catch (Exception e) {
-                prior = e;
-            } finally {
-                try {
-                    closeCamera(cameraId);
-                } catch (Exception e) {
-                    if (prior != null) {
-                        Log.e(TAG, "Prior exception received: " + prior);
-                    }
-                    prior = e;
-                }
-                if (prior != null) throw prior; // Rethrow last exception.
-            }
-        }
-    }
-
-    public void testDualCameraPreview() throws Exception {
-        final int NUM_CAMERAS_TESTED = 2;
-        if (mCameraIds.length < NUM_CAMERAS_TESTED) {
-            return;
-        }
-
-        try {
-            for (int i = 0; i < NUM_CAMERAS_TESTED; i++) {
-                openCamera(mCameraIds[i]);
-                List<TextureView> views = Arrays.asList(mTextureView[i]);
-
-                startTextureViewPreview(mCameraIds[i], views, /*ImageReader*/null);
-            }
-            // TODO: check the framerate is correct
-            SystemClock.sleep(PREVIEW_TIME_MS);
-            for (int i = 0; i < NUM_CAMERAS_TESTED; i++) {
-                stopPreview(mCameraIds[i]);
-            }
-        } catch (BlockingOpenException e) {
-            // The only error accepted is ERROR_MAX_CAMERAS_IN_USE, which means HAL doesn't support
-            // concurrent camera streaming
-            assertEquals("Camera device open failed",
-                    CameraDevice.StateCallback.ERROR_MAX_CAMERAS_IN_USE, e.getCode());
-            Log.i(TAG, "Camera HAL does not support dual camera preview. Skip the test");
-        } finally {
-            for (int i = 0; i < NUM_CAMERAS_TESTED; i++) {
-                closeCamera(mCameraIds[i]);
-            }
-        }
-    }
-
-    /**
-     * Start camera preview using input texture views and/or one image reader
-     */
-    private void startTextureViewPreview(
-            String cameraId, List<TextureView> views, ImageReader imageReader)
-            throws Exception {
-        int numPreview = views.size();
-        Size previewSize = getOrderedPreviewSizes(cameraId).get(0);
-        CameraPreviewListener[] previewListener =
-                new CameraPreviewListener[numPreview];
-        SurfaceTexture[] previewTexture = new SurfaceTexture[numPreview];
-        List<Surface> surfaces = new ArrayList<Surface>();
-
-        // Prepare preview surface.
-        int i = 0;
-        for (TextureView view : views) {
-            previewListener[i] = new CameraPreviewListener();
-            view.setSurfaceTextureListener(previewListener[i]);
-            previewTexture[i] = getAvailableSurfaceTexture(WAIT_FOR_COMMAND_TO_COMPLETE, view);
-            assertNotNull("Unable to get preview surface texture", previewTexture[i]);
-            previewTexture[i].setDefaultBufferSize(previewSize.getWidth(), previewSize.getHeight());
-            // Correct the preview display rotation.
-            updatePreviewDisplayRotation(previewSize, view);
-            surfaces.add(new Surface(previewTexture[i]));
-            i++;
-        }
-        if (imageReader != null) {
-            surfaces.add(imageReader.getSurface());
-        }
-
-        startPreview(cameraId, surfaces, null);
-
-        i = 0;
-        for (TextureView view : views) {
-            boolean previewDone =
-                    previewListener[i].waitForPreviewDone(WAIT_FOR_COMMAND_TO_COMPLETE);
-            assertTrue("Unable to start preview " + i, previewDone);
-            view.setSurfaceTextureListener(null);
-            i++;
-        }
-    }
-
-    /**
-     * Test camera preview using input texture views and/or one image reader
-     */
-    private void textureViewPreview(
-            String cameraId, List<TextureView> views, ImageReader testImagerReader)
-            throws Exception {
-        startTextureViewPreview(cameraId, views, testImagerReader);
-
-        // TODO: check the framerate is correct
-        SystemClock.sleep(PREVIEW_TIME_MS);
-
-        stopPreview(cameraId);
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java
deleted file mode 100644
index e669007..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/PerformanceTest.java
+++ /dev/null
@@ -1,501 +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.hardware.camera2.cts;
-
-import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
-
-import android.graphics.ImageFormat;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.cts.CameraTestUtils.SimpleImageReaderListener;
-import android.hardware.camera2.cts.helpers.StaticMetadata;
-import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
-import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
-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.os.ConditionVariable;
-import android.os.SystemClock;
-
-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 com.android.ex.camera2.blocking.BlockingSessionCallback;
-import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Test camera2 API use case performance KPIs, such as camera open time, session creation time,
- * shutter lag etc. The KPI data will be reported in cts results.
- */
-public class PerformanceTest extends Camera2SurfaceViewTestCase {
-    private static final String TAG = "PerformanceTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final int NUM_TEST_LOOPS = 5;
-    private static final int NUM_MAX_IMAGES = 4;
-    private static final int NUM_RESULTS_WAIT = 30;
-
-    private DeviceReportLog mReportLog;
-
-    @Override
-    protected void setUp() throws Exception {
-        mReportLog = new DeviceReportLog();
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Deliver the report to host will automatically clear the report log.
-        mReportLog.deliverReportToHost(getInstrumentation());
-        super.tearDown();
-    }
-
-    /**
-     * Test camera launch KPI: the time duration between a camera device is
-     * being opened and first preview frame is available.
-     * <p>
-     * It includes camera open time, session creation time, and sending first
-     * preview request processing latency etc. For the SurfaceView based preview use
-     * case, there is no way for client to know the exact preview frame
-     * arrival time. To approximate this time, a companion YUV420_888 stream is
-     * created. The first YUV420_888 Image coming out of the ImageReader is treated
-     * as the first preview arrival time.
-     * </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];
-
-        for (String id : mCameraIds) {
-            try {
-                initializeImageReader(id, ImageFormat.YUV_420_888);
-                SimpleImageListener imageListener = null;
-                long startTimeMs, openTimeMs, configureTimeMs, previewStartedTimeMs;
-                for (int i = 0; i < NUM_TEST_LOOPS; i++) {
-                    try {
-                        // Need create a new listener every iteration to be able to wait
-                        // for the first image comes out.
-                        imageListener = new SimpleImageListener();
-                        mReader.setOnImageAvailableListener(imageListener, mHandler);
-                        startTimeMs = SystemClock.elapsedRealtime();
-
-                        // Blocking open camera
-                        simpleOpenCamera(id);
-                        openTimeMs = SystemClock.elapsedRealtime();
-                        cameraOpenTimes[i] = openTimeMs - startTimeMs;
-
-                        // Blocking configure outputs.
-                        configureReaderAndPreviewOutputs();
-                        configureTimeMs = SystemClock.elapsedRealtime();
-                        configureStreamTimes[i] = configureTimeMs - openTimeMs;
-
-                        // Blocking start preview (start preview to first image arrives)
-                        CameraTestUtils.SimpleCaptureCallback resultListener =
-                                new CameraTestUtils.SimpleCaptureCallback();
-                        blockingStartPreview(resultListener, imageListener);
-                        previewStartedTimeMs = SystemClock.elapsedRealtime();
-                        startPreviewTimes[i] = previewStartedTimeMs - configureTimeMs;
-                        cameraLaunchTimes[i] = previewStartedTimeMs - startTimeMs;
-
-                        // Let preview on for a couple of frames
-                        waitForNumResults(resultListener, NUM_RESULTS_WAIT);
-
-                        // Blocking stop preview
-                        startTimeMs = SystemClock.elapsedRealtime();
-                        blockingStopPreview();
-                        stopPreviewTimes[i] = SystemClock.elapsedRealtime() - startTimeMs;
-                    }
-                    finally {
-                        // Blocking camera close
-                        startTimeMs = SystemClock.elapsedRealtime();
-                        closeDevice();
-                        cameraCloseTimes[i] = SystemClock.elapsedRealtime() - startTimeMs;
-                    }
-                }
-
-                // Finish the data collection, report the KPIs.
-                mReportLog.printArray("Camera " + id
-                        + ": Camera open time", cameraOpenTimes,
-                        ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
-                        + ": Camera configure stream time", configureStreamTimes,
-                        ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
-                        + ": Camera start preview time", startPreviewTimes,
-                        ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
-                        + ": Camera stop preview", stopPreviewTimes,
-                        ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
-                        + ": Camera close time", cameraCloseTimes,
-                        ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printArray("Camera " + id
-                        + ": Camera launch time", cameraLaunchTimes,
-                        ResultType.LOWER_BETTER, ResultUnit.MS);
-                mReportLog.printSummary("Camera launch average time for Camera " + id,
-                        Stat.getAverage(cameraLaunchTimes),
-                        ResultType.LOWER_BETTER, ResultUnit.MS);
-            }
-            finally {
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Test camera capture KPI for YUV_420_888 format: the time duration between
-     * sending out a single image capture request and receiving image data and
-     * capture result.
-     * <p>
-     * It enumerates the following metrics: capture latency, computed by
-     * measuring the time between sending out the capture request and getting
-     * the image data; partial result latency, computed by measuring the time
-     * between sending out the capture request and getting the partial result;
-     * capture result latency, computed by measuring the time between sending
-     * out the capture request and getting the full capture result.
-     * </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];
-
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-
-                boolean partialsExpected = mStaticInfo.getPartialResultCount() > 1;
-                long startTimeMs;
-                boolean isPartialTimingValid = partialsExpected;
-                for (int i = 0; i < NUM_TEST_LOOPS; i++) {
-
-                    // setup builders and listeners
-                    CaptureRequest.Builder previewBuilder =
-                            mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                    CaptureRequest.Builder captureBuilder =
-                            mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-                    CameraTestUtils.SimpleCaptureCallback previewResultListener =
-                            new CameraTestUtils.SimpleCaptureCallback();
-                    SimpleTimingResultListener captureResultListener =
-                            new SimpleTimingResultListener();
-                    SimpleImageListener imageListener = new SimpleImageListener();
-
-                    Size maxYuvSize = CameraTestUtils.getSortedSizesForFormat(
-                        id, mCameraManager, ImageFormat.YUV_420_888, /*bound*/null).get(0);
-
-                    prepareCaptureAndStartPreview(previewBuilder, captureBuilder,
-                            mOrderedPreviewSizes.get(0), maxYuvSize,
-                            ImageFormat.YUV_420_888, previewResultListener,
-                            NUM_MAX_IMAGES, imageListener);
-
-                    // Capture an image and get image data
-                    startTimeMs = SystemClock.elapsedRealtime();
-                    CaptureRequest request = captureBuilder.build();
-                    mSession.capture(request, captureResultListener, mHandler);
-
-                    Pair<CaptureResult, Long> partialResultNTime = null;
-                    if (partialsExpected) {
-                        partialResultNTime = captureResultListener.getPartialResultNTimeForRequest(
-                            request, NUM_RESULTS_WAIT);
-                        // Even if maxPartials > 1, may not see partials for some devices
-                        if (partialResultNTime == null) {
-                            partialsExpected = false;
-                            isPartialTimingValid = false;
-                        }
-                    }
-                    Pair<CaptureResult, Long> captureResultNTime =
-                            captureResultListener.getCaptureResultNTimeForRequest(
-                                    request, NUM_RESULTS_WAIT);
-                    imageListener.waitForImageAvailable(
-                            CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
-
-                    captureTimes[i] = imageListener.getTimeReceivedImage() - startTimeMs;
-                    if (partialsExpected) {
-                        getPartialTimes[i] = partialResultNTime.second - startTimeMs;
-                        if (getPartialTimes[i] < 0) {
-                            isPartialTimingValid = false;
-                        }
-                    }
-                    getResultTimes[i] = captureResultNTime.second - startTimeMs;
-
-                    // simulate real scenario (preview runs a bit)
-                    waitForNumResults(previewResultListener, NUM_RESULTS_WAIT);
-
-                    blockingStopPreview();
-
-                }
-                mReportLog.printArray("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
-                            + ": Camera partial result latency", getPartialTimes,
-                            ResultType.LOWER_BETTER, ResultUnit.MS);
-                }
-                mReportLog.printArray("Camera " + id
-                        + ": Camera capture result latency", getResultTimes,
-                        ResultType.LOWER_BETTER, ResultUnit.MS);
-            }
-            finally {
-                closeImageReader();
-                closeDevice();
-            }
-        }
-    }
-
-    private void blockingStopPreview() throws Exception {
-        stopPreview();
-        mSessionListener.getStateWaiter().waitForState(SESSION_CLOSED,
-                CameraTestUtils.SESSION_CLOSE_TIMEOUT_MS);
-    }
-
-    private void blockingStartPreview(CaptureCallback listener, SimpleImageListener imageListener)
-            throws Exception {
-        if (mPreviewSurface == null || mReaderSurface == null) {
-            throw new IllegalStateException("preview and reader surface must be initilized first");
-        }
-
-        CaptureRequest.Builder previewBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        previewBuilder.addTarget(mPreviewSurface);
-        previewBuilder.addTarget(mReaderSurface);
-        mSession.setRepeatingRequest(previewBuilder.build(), listener, mHandler);
-        imageListener.waitForImageAvailable(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
-    }
-
-    private void blockingCaptureImage(CaptureCallback listener,
-            SimpleImageListener imageListener) throws Exception {
-        if (mReaderSurface == null) {
-            throw new IllegalStateException("reader surface must be initialized first");
-        }
-
-        CaptureRequest.Builder captureBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-        captureBuilder.addTarget(mReaderSurface);
-        mSession.capture(captureBuilder.build(), listener, mHandler);
-        imageListener.waitForImageAvailable(CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS);
-    }
-
-    /**
-     * Configure reader and preview outputs and wait until done.
-     */
-    private void configureReaderAndPreviewOutputs() throws Exception {
-        if (mPreviewSurface == null || mReaderSurface == null) {
-            throw new IllegalStateException("preview and reader surface must be initilized first");
-        }
-        mSessionListener = new BlockingSessionCallback();
-        List<Surface> outputSurfaces = new ArrayList<>();
-        outputSurfaces.add(mPreviewSurface);
-        outputSurfaces.add(mReaderSurface);
-        mSession = CameraTestUtils.configureCameraSession(mCamera, outputSurfaces,
-                mSessionListener, mHandler);
-    }
-
-    /**
-     * Initialize the ImageReader instance and preview surface.
-     * @param cameraId The camera to be opened.
-     * @param format The format used to create ImageReader instance.
-     */
-    private void initializeImageReader(String cameraId, int format) throws Exception {
-        mOrderedPreviewSizes = CameraTestUtils.getSupportedPreviewSizes(
-                cameraId, mCameraManager,
-                CameraTestUtils.getPreviewSizeBound(mWindowManager,
-                    CameraTestUtils.PREVIEW_SIZE_BOUND));
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        createImageReader(maxPreviewSize, format, NUM_MAX_IMAGES, /*listener*/null);
-        updatePreviewSurface(maxPreviewSize);
-    }
-
-    private void simpleOpenCamera(String cameraId) throws Exception {
-        mCamera = CameraTestUtils.openCamera(
-                mCameraManager, cameraId, mCameraListener, mHandler);
-        mCollector.setCameraId(cameraId);
-        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
-                CheckLevel.ASSERT, /*collector*/null);
-        mMinPreviewFrameDurationMap =
-                mStaticInfo.getAvailableMinFrameDurationsForFormatChecked(ImageFormat.YUV_420_888);
-    }
-
-    /**
-     * Simple image listener that can be used to time the availability of first image.
-     *
-     */
-    private static class SimpleImageListener implements ImageReader.OnImageAvailableListener {
-        private ConditionVariable imageAvailable = new ConditionVariable();
-        private boolean imageReceived = false;
-        private long mTimeReceivedImage = 0;
-
-        @Override
-        public void onImageAvailable(ImageReader reader) {
-            Image image = null;
-            if (!imageReceived) {
-                if (VERBOSE) {
-                    Log.v(TAG, "First image arrives");
-                }
-                imageReceived = true;
-                mTimeReceivedImage = SystemClock.elapsedRealtime();
-                imageAvailable.open();
-            }
-            image = reader.acquireNextImage();
-            if (image != null) {
-                image.close();
-            }
-        }
-
-        /**
-         * Wait for image available, return immediately if the image was already
-         * received, otherwise wait until an image arrives.
-         */
-        public void waitForImageAvailable(long timeout) {
-            if (imageReceived) {
-                imageReceived = false;
-                return;
-            }
-
-            if (imageAvailable.block(timeout)) {
-                imageAvailable.close();
-                imageReceived = false;
-            } else {
-                throw new TimeoutRuntimeException("Unable to get the first image after "
-                        + CameraTestUtils.CAPTURE_IMAGE_TIMEOUT_MS + "ms");
-            }
-        }
-
-        public long getTimeReceivedImage() {
-            return mTimeReceivedImage;
-        }
-    }
-
-    private static class SimpleTimingResultListener
-            extends CameraCaptureSession.CaptureCallback {
-        private final LinkedBlockingQueue<Pair<CaptureResult, Long> > mPartialResultQueue =
-                new LinkedBlockingQueue<Pair<CaptureResult, Long> >();
-        private final LinkedBlockingQueue<Pair<CaptureResult, Long> > mResultQueue =
-                new LinkedBlockingQueue<Pair<CaptureResult, Long> > ();
-
-        @Override
-        public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
-                TotalCaptureResult result) {
-            try {
-                Long time = SystemClock.elapsedRealtime();
-                mResultQueue.put(new Pair<CaptureResult, Long>(result, time));
-            } catch (InterruptedException e) {
-                throw new UnsupportedOperationException(
-                        "Can't handle InterruptedException in onCaptureCompleted");
-            }
-        }
-
-        @Override
-        public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
-                CaptureResult partialResult) {
-            try {
-                // check if AE and AF state exists
-                Long time = -1L;
-                if (partialResult.get(CaptureResult.CONTROL_AE_STATE) != null &&
-                        partialResult.get(CaptureResult.CONTROL_AF_STATE) != null) {
-                    time = SystemClock.elapsedRealtime();
-                }
-                mPartialResultQueue.put(new Pair<CaptureResult, Long>(partialResult, time));
-            } catch (InterruptedException e) {
-                throw new UnsupportedOperationException(
-                        "Can't handle InterruptedException in onCaptureProgressed");
-            }
-        }
-
-        public Pair<CaptureResult, Long> getPartialResultNTime(long timeout) {
-            try {
-                Pair<CaptureResult, Long> result =
-                        mPartialResultQueue.poll(timeout, TimeUnit.MILLISECONDS);
-                return result;
-            } catch (InterruptedException e) {
-                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
-            }
-        }
-
-        public Pair<CaptureResult, Long> getCaptureResultNTime(long timeout) {
-            try {
-                Pair<CaptureResult, Long> result =
-                        mResultQueue.poll(timeout, TimeUnit.MILLISECONDS);
-                assertNotNull("Wait for a capture result timed out in " + timeout + "ms", result);
-                return result;
-            } catch (InterruptedException e) {
-                throw new UnsupportedOperationException("Unhandled interrupted exception", e);
-            }
-        }
-
-        public Pair<CaptureResult, Long> getPartialResultNTimeForRequest(CaptureRequest myRequest,
-                int numResultsWait) {
-            if (numResultsWait < 0) {
-                throw new IllegalArgumentException("numResultsWait must be no less than 0");
-            }
-
-            Pair<CaptureResult, Long> result;
-            int i = 0;
-            do {
-                result = getPartialResultNTime(CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
-                // The result may be null if no partials are produced on this particular path, so
-                // stop trying
-                if (result == null) break;
-                if (result.first.getRequest().equals(myRequest)) {
-                    return result;
-                }
-            } while (i++ < numResultsWait);
-
-            // No partials produced - this may not be an error, since a given device may not
-            // produce any partials on this testing path
-            return null;
-        }
-
-        public Pair<CaptureResult, Long> getCaptureResultNTimeForRequest(CaptureRequest myRequest,
-                int numResultsWait) {
-            if (numResultsWait < 0) {
-                throw new IllegalArgumentException("numResultsWait must be no less than 0");
-            }
-
-            Pair<CaptureResult, Long> result;
-            int i = 0;
-            do {
-                result = getCaptureResultNTime(CameraTestUtils.CAPTURE_RESULT_TIMEOUT_MS);
-                if (result.first.getRequest().equals(myRequest)) {
-                    return result;
-                }
-            } while (i++ < numResultsWait);
-
-            throw new TimeoutRuntimeException("Unable to get the expected capture result after "
-                    + "waiting for " + numResultsWait + " results");
-        }
-
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
deleted file mode 100644
index 20a7834..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RecordingTest.java
+++ /dev/null
@@ -1,1160 +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.hardware.camera2.cts;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
-
-import android.graphics.ImageFormat;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.util.Size;
-import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
-import android.media.CamcorderProfile;
-import android.media.MediaCodecInfo;
-import android.media.MediaCodecInfo.CodecCapabilities;
-import android.media.MediaCodecInfo.CodecProfileLevel;
-import android.media.Image;
-import android.media.ImageReader;
-import android.media.MediaCodecList;
-import android.media.MediaExtractor;
-import android.media.MediaFormat;
-import android.media.MediaRecorder;
-import android.os.Environment;
-import android.os.SystemClock;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.util.Range;
-import android.view.Surface;
-
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-
-import junit.framework.AssertionFailedError;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * CameraDevice video recording use case tests by using MediaRecorder and
- * MediaCodec.
- */
-@LargeTest
-public class RecordingTest extends Camera2SurfaceViewTestCase {
-    private static final String TAG = "RecordingTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final boolean DEBUG_DUMP = Log.isLoggable(TAG, Log.DEBUG);
-    private static final int RECORDING_DURATION_MS = 3000;
-    private static final int DURATION_MARGIN_MS = 600;
-    private static final double FRAME_DURATION_ERROR_TOLERANCE_MS = 3.0;
-    private static final int BIT_RATE_1080P = 16000000;
-    private static final int BIT_RATE_MIN = 64000;
-    private static final int BIT_RATE_MAX = 40000000;
-    private static final int VIDEO_FRAME_RATE = 30;
-    private final String VIDEO_FILE_PATH = Environment.getExternalStorageDirectory().getPath();
-    private static final int[] mCamcorderProfileList = {
-            CamcorderProfile.QUALITY_HIGH,
-            CamcorderProfile.QUALITY_2160P,
-            CamcorderProfile.QUALITY_1080P,
-            CamcorderProfile.QUALITY_720P,
-            CamcorderProfile.QUALITY_480P,
-            CamcorderProfile.QUALITY_CIF,
-            CamcorderProfile.QUALITY_QCIF,
-            CamcorderProfile.QUALITY_QVGA,
-            CamcorderProfile.QUALITY_LOW,
-    };
-    private static final int MAX_VIDEO_SNAPSHOT_IMAGES = 5;
-    private static final int BURST_VIDEO_SNAPSHOT_NUM = 3;
-    private static final int SLOWMO_SLOW_FACTOR = 4;
-    private static final int MAX_NUM_FRAME_DROP_INTERVAL_ALLOWED = 4;
-    private List<Size> mSupportedVideoSizes;
-    private Surface mRecordingSurface;
-    private MediaRecorder mMediaRecorder;
-    private String mOutMediaFileName;
-    private int mVideoFrameRate;
-    private Size mVideoSize;
-    private long mRecordingStartTime;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * <p>
-     * Test basic camera recording.
-     * </p>
-     * <p>
-     * This test covers the typical basic use case of camera recording.
-     * 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 testBasicRecording() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                Log.i(TAG, "Testing basic recording for camera " + mCameraIds[i]);
-                // Re-use the MediaRecorder object for the same camera device.
-                mMediaRecorder = new MediaRecorder();
-                openDevice(mCameraIds[i]);
-
-                initSupportedVideoSize(mCameraIds[i]);
-
-                basicRecordingTestByCamera(mCamcorderProfileList);
-            } finally {
-                closeDevice();
-                releaseRecorder();
-            }
-        }
-    }
-
-    /**
-     * <p>
-     * Test camera recording for all supported sizes by using MediaRecorder.
-     * </p>
-     * <p>
-     * This test covers camera recording for all supported sizes by camera. MediaRecorder
-     * is used to encode the video. Preview is set to the video size. Recorded videos are
-     * validated according to the recording configuration.
-     * </p>
-     */
-    public void testSupportedVideoSizes() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                Log.i(TAG, "Testing supported video size recording for camera " + mCameraIds[i]);
-                // Re-use the MediaRecorder object for the same camera device.
-                mMediaRecorder = new MediaRecorder();
-                openDevice(mCameraIds[i]);
-
-                initSupportedVideoSize(mCameraIds[i]);
-
-                recordingSizeTestByCamera();
-            } finally {
-                closeDevice();
-                releaseRecorder();
-            }
-        }
-    }
-
-    /**
-     * Test different start/stop orders of Camera and Recorder.
-     *
-     * <p>The recording should be working fine for any kind of start/stop orders.</p>
-     */
-    public void testCameraRecorderOrdering() {
-        // TODO: need implement
-    }
-
-    /**
-     * <p>
-     * Test camera recording for all supported sizes by using MediaCodec.
-     * </p>
-     * <p>
-     * This test covers video only recording for all supported sizes (camera and
-     * encoder). MediaCodec is used to encode the video. The recorded videos are
-     * validated according to the recording configuration.
-     * </p>
-     */
-    public void testMediaCodecRecording() throws Exception {
-        // TODO. Need implement.
-    }
-
-    /**
-     * <p>
-     * Test video snapshot for each camera.
-     * </p>
-     * <p>
-     * This test covers video snapshot typical use case. The MediaRecorder is used to record the
-     * video for each available video size. The largest still capture size is selected to
-     * capture the JPEG image. The still capture images are validated according to the capture
-     * configuration. The timestamp of capture result before and after video snapshot is also
-     * checked to make sure no frame drop caused by video snapshot.
-     * </p>
-     */
-    public void testVideoSnapshot() throws Exception {
-        videoSnapshotHelper(/*burstTest*/false);
-    }
-
-    /**
-     * <p>
-     * Test burst video snapshot for each camera.
-     * </p>
-     * <p>
-     * This test covers burst video snapshot capture. The MediaRecorder is used to record the
-     * video for each available video size. The largest still capture size is selected to
-     * capture the JPEG image. {@value #BURST_VIDEO_SNAPSHOT_NUM} video snapshot requests will be
-     * sent during the test. The still capture images are validated according to the capture
-     * configuration.
-     * </p>
-     */
-    public void testBurstVideoSnapshot() throws Exception {
-        videoSnapshotHelper(/*burstTest*/true);
-    }
-
-    /**
-     * Test timelapse recording, where capture rate is slower than video (playback) frame rate.
-     */
-    public void testTimelapseRecording() throws Exception {
-        // TODO. Need implement.
-    }
-
-    public void testSlowMotionRecording() throws Exception {
-        slowMotionRecording();
-    }
-
-    /**
-     * <p>
-     * Test recording framerate accuracy when switching from low FPS to high FPS.
-     * </p>
-     * <p>
-     * This test first record a video with profile of lowest framerate then record a video with
-     * profile of highest framerate. Make sure that the video framerate are still accurate.
-     * </p>
-     */
-    public void testRecordingFramerateLowToHigh() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                Log.i(TAG, "Testing basic recording for camera " + mCameraIds[i]);
-                // Re-use the MediaRecorder object for the same camera device.
-                mMediaRecorder = new MediaRecorder();
-                openDevice(mCameraIds[i]);
-
-                initSupportedVideoSize(mCameraIds[i]);
-
-                int minFpsProfileId = -1, minFps = 1000;
-                int maxFpsProfileId = -1, maxFps = 0;
-                int cameraId = Integer.valueOf(mCamera.getId());
-
-                for (int profileId : mCamcorderProfileList) {
-                    if (!CamcorderProfile.hasProfile(cameraId, profileId)) {
-                        continue;
-                    }
-                    CamcorderProfile profile = CamcorderProfile.get(cameraId, profileId);
-                    if (profile.videoFrameRate < minFps) {
-                        minFpsProfileId = profileId;
-                        minFps = profile.videoFrameRate;
-                    }
-                    if (profile.videoFrameRate > maxFps) {
-                        maxFpsProfileId = profileId;
-                        maxFps = profile.videoFrameRate;
-                    }
-                }
-
-                int camcorderProfileList[] = new int[] {minFpsProfileId, maxFpsProfileId};
-                basicRecordingTestByCamera(camcorderProfileList);
-            } finally {
-                closeDevice();
-                releaseRecorder();
-            }
-        }
-    }
-
-    /**
-     * Test slow motion recording where capture rate (camera output) is different with
-     * video (playback) frame rate for each camera if high speed recording is supported
-     * by both camera and encoder.
-     *
-     * <p>
-     * Normal recording use cases make the capture rate (camera output frame
-     * rate) the same as the video (playback) frame rate. This guarantees that
-     * the motions in the scene play at the normal speed. If the capture rate is
-     * faster than video frame rate, for a given time duration, more number of
-     * frames are captured than it can be played in the same time duration. This
-     * generates "slow motion" effect during playback.
-     * </p>
-     */
-    private void slowMotionRecording() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing slow motion recording for camera " + id);
-                // Re-use the MediaRecorder object for the same camera device.
-                mMediaRecorder = new MediaRecorder();
-                openDevice(id);
-
-                if (!mStaticInfo.isHighSpeedVideoSupported()) {
-                    continue;
-                }
-
-                StreamConfigurationMap config =
-                        mStaticInfo.getValueFromKeyNonNull(
-                                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-                Size[] highSpeedVideoSizes = config.getHighSpeedVideoSizes();
-                for (Size size : highSpeedVideoSizes) {
-                    Range<Integer> fpsRange = getHighestHighSpeedFixedFpsRangeForSize(config, size);
-                    mCollector.expectNotNull("Unable to find the fixed frame rate fps range for " +
-                            "size " + size, fpsRange);
-                    if (fpsRange == null) {
-                        continue;
-                    }
-
-                    int captureRate = fpsRange.getLower();
-                    int videoFramerate = captureRate / SLOWMO_SLOW_FACTOR;
-                    /**
-                     * Check if encoder support this. TODO: use HIGH_SPEED_720p
-                     * CamCorderProfile to get the performance guarantee. Also
-                     * add the test in StaticMetadataTest to check: 1. Camera
-                     * high speed recording metadata is correctly reported 2.
-                     * Encoder profile/level info is correctly reported. After
-                     * that, we only need check the CamcorderProfile before
-                     * skipping the test.
-                     */
-                    if (!isSupportedByAVCEncoder(size, captureRate)) {
-                        Log.i(TAG, "high speed recording " + size + "@" + captureRate + "fps"
-                                + " is not supported by AVC encoder");
-                        continue;
-                    }
-
-                    mOutMediaFileName = VIDEO_FILE_PATH + "/test_slowMo_video.mp4";
-                    if (DEBUG_DUMP) {
-                        mOutMediaFileName = VIDEO_FILE_PATH + "/test_slowMo_video_" + id + "_"
-                                + size.toString() + ".mp4";
-                    }
-
-                    prepareRecording(size, videoFramerate, captureRate);
-
-                    // prepare preview surface by using video size.
-                    updatePreviewSurfaceWithVideoSize(size);
-
-                    // Start recording
-                    SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-                    startSlowMotionRecording(/*useMediaRecorder*/true, videoFramerate, captureRate,
-                            fpsRange, resultListener);
-                    long startTime = SystemClock.elapsedRealtime();
-
-                    // Record certain duration.
-                    SystemClock.sleep(RECORDING_DURATION_MS);
-
-                    // Stop recording and preview
-                    stopRecording(/*useMediaRecorder*/true);
-                    // Convert number of frames camera produced into the duration in unit of ms.
-                    int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
-                                    videoFramerate);
-
-                    // Validation.
-                    validateRecording(size, durationMs);
-
-                }
-
-            } finally {
-                closeDevice();
-                releaseRecorder();
-            }
-        }
-    }
-
-    private Range<Integer> getHighestHighSpeedFixedFpsRangeForSize(StreamConfigurationMap config,
-            Size size) {
-        Range<Integer>[] availableFpsRanges = config.getHighSpeedVideoFpsRangesFor(size);
-        Range<Integer> maxRange = availableFpsRanges[0];
-        boolean foundRange = false;
-        for (Range<Integer> range : availableFpsRanges) {
-            if (range.getLower().equals(range.getUpper()) && range.getLower() >= maxRange.getLower()) {
-                foundRange = true;
-                maxRange = range;
-            }
-        }
-
-        if (!foundRange) {
-            return null;
-        }
-        return maxRange;
-    }
-
-    private void startSlowMotionRecording(boolean useMediaRecorder, int videoFrameRate,
-            int captureRate, Range<Integer> fpsRange,
-            CameraCaptureSession.CaptureCallback listener) throws Exception {
-        List<Surface> outputSurfaces = new ArrayList<Surface>(2);
-        assertTrue("Both preview and recording surfaces should be valid",
-                mPreviewSurface.isValid() && mRecordingSurface.isValid());
-        outputSurfaces.add(mPreviewSurface);
-        outputSurfaces.add(mRecordingSurface);
-        // Video snapshot surface
-        if (mReaderSurface != null) {
-            outputSurfaces.add(mReaderSurface);
-        }
-        mSessionListener = new BlockingSessionCallback();
-        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
-
-        CaptureRequest.Builder recordingRequestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
-        recordingRequestBuilder.set(CaptureRequest.CONTROL_MODE,
-                CaptureRequest.CONTROL_MODE_USE_SCENE_MODE);
-        recordingRequestBuilder.set(CaptureRequest.CONTROL_SCENE_MODE,
-                CaptureRequest.CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO);
-
-        CaptureRequest.Builder recordingOnlyBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
-        recordingOnlyBuilder.set(CaptureRequest.CONTROL_MODE,
-                CaptureRequest.CONTROL_MODE_USE_SCENE_MODE);
-        recordingOnlyBuilder.set(CaptureRequest.CONTROL_SCENE_MODE,
-                CaptureRequest.CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO);
-        int slowMotionFactor = captureRate / videoFrameRate;
-
-        // Make sure camera output frame rate is set to correct value.
-        recordingRequestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
-        recordingRequestBuilder.addTarget(mRecordingSurface);
-        recordingRequestBuilder.addTarget(mPreviewSurface);
-        recordingOnlyBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
-        recordingOnlyBuilder.addTarget(mRecordingSurface);
-
-        List<CaptureRequest> slowMoRequests = new ArrayList<CaptureRequest>();
-        slowMoRequests.add(recordingRequestBuilder.build());// Preview + recording.
-
-        for (int i = 0; i < slowMotionFactor - 1; i++) {
-            slowMoRequests.add(recordingOnlyBuilder.build()); // Recording only.
-        }
-        mSession.setRepeatingBurst(slowMoRequests, listener, mHandler);
-
-        if (useMediaRecorder) {
-            mMediaRecorder.start();
-        } else {
-            // TODO: need implement MediaCodec path.
-        }
-
-    }
-
-    /**
-     * 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 {
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        for (int profileId : camcorderProfileList) {
-            int cameraId = Integer.valueOf(mCamera.getId());
-            if (!CamcorderProfile.hasProfile(cameraId, profileId) ||
-                    allowedUnsupported(cameraId, profileId)) {
-                continue;
-            }
-
-            CamcorderProfile profile = CamcorderProfile.get(cameraId, profileId);
-            Size videoSz = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
-            if (mStaticInfo.isHardwareLevelLegacy() &&
-                    (videoSz.getWidth() > maxPreviewSize.getWidth() ||
-                     videoSz.getHeight() > maxPreviewSize.getHeight())) {
-                // Skip. Legacy mode can only do recording up to max preview size
-                continue;
-            }
-            assertTrue("Video size " + videoSz.toString() + " for profile ID " + profileId +
-                            " must be one of the camera device supported video size!",
-                            mSupportedVideoSizes.contains(videoSz));
-
-            if (VERBOSE) {
-                Log.v(TAG, "Testing camera recording with video size " + videoSz.toString());
-            }
-
-            // Configure preview and recording surfaces.
-            mOutMediaFileName = VIDEO_FILE_PATH + "/test_video.mp4";
-            if (DEBUG_DUMP) {
-                mOutMediaFileName = VIDEO_FILE_PATH + "/test_video_" + cameraId + "_"
-                        + videoSz.toString() + ".mp4";
-            }
-
-            prepareRecordingWithProfile(profile);
-
-            // prepare preview surface by using video size.
-            updatePreviewSurfaceWithVideoSize(videoSz);
-
-            // Start recording
-            SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-            startRecording(/* useMediaRecorder */true, resultListener);
-
-            // Record certain duration.
-            SystemClock.sleep(RECORDING_DURATION_MS);
-
-            // Stop recording and preview
-            stopRecording(/* useMediaRecorder */true);
-            // Convert number of frames camera produced into the duration in unit of ms.
-            int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
-                            profile.videoFrameRate);
-
-            if (VERBOSE) {
-                Log.v(TAG, "video frame rate: " + profile.videoFrameRate +
-                                ", num of frames produced: " + resultListener.getTotalNumFrames());
-            }
-
-            // Validation.
-            validateRecording(videoSz, durationMs);
-        }
-    }
-
-    /**
-     * Test camera recording for each supported video size by camera, preview
-     * size is set to the video size.
-     */
-    private void recordingSizeTestByCamera() throws Exception {
-        for (Size sz : mSupportedVideoSizes) {
-            if (!isSupported(sz, VIDEO_FRAME_RATE, VIDEO_FRAME_RATE)) {
-                continue;
-            }
-
-            if (VERBOSE) {
-                Log.v(TAG, "Testing camera recording with video size " + sz.toString());
-            }
-
-            // Configure preview and recording surfaces.
-            mOutMediaFileName = VIDEO_FILE_PATH + "/test_video.mp4";
-            if (DEBUG_DUMP) {
-                mOutMediaFileName = VIDEO_FILE_PATH + "/test_video_" + mCamera.getId() + "_"
-                        + sz.toString() + ".mp4";
-            }
-
-            // Use AVC and AAC a/v compression format.
-            prepareRecording(sz, VIDEO_FRAME_RATE, VIDEO_FRAME_RATE);
-
-            // prepare preview surface by using video size.
-            updatePreviewSurfaceWithVideoSize(sz);
-
-            // Start recording
-            SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-            startRecording(/* useMediaRecorder */true, resultListener);
-
-            // Record certain duration.
-            SystemClock.sleep(RECORDING_DURATION_MS);
-
-            // Stop recording and preview
-            stopRecording(/* useMediaRecorder */true);
-            // Convert number of frames camera produced into the duration in unit of ms.
-            int durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
-                            VIDEO_FRAME_RATE);
-
-            // Validation.
-            validateRecording(sz, durationMs);
-        }
-    }
-
-    /**
-     * Initialize the supported video sizes.
-     */
-    private void initSupportedVideoSize(String cameraId)  throws Exception {
-        Size maxVideoSize = SIZE_BOUND_1080P;
-        if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P)) {
-            maxVideoSize = SIZE_BOUND_2160P;
-        }
-        mSupportedVideoSizes =
-                getSupportedVideoSizes(cameraId, mCameraManager, maxVideoSize);
-    }
-
-    /**
-     * Simple wrapper to wrap normal/burst video snapshot tests
-     */
-    private void videoSnapshotHelper(boolean burstTest) throws Exception {
-            for (String id : mCameraIds) {
-                try {
-                    Log.i(TAG, "Testing video snapshot for camera " + id);
-                    // Re-use the MediaRecorder object for the same camera device.
-                    mMediaRecorder = new MediaRecorder();
-
-                    openDevice(id);
-
-                    initSupportedVideoSize(id);
-
-                    videoSnapshotTestByCamera(burstTest);
-                } finally {
-                    closeDevice();
-                    releaseRecorder();
-                }
-            }
-    }
-
-    /**
-     * Returns {@code true} if the {@link CamcorderProfile} ID is allowed to be unsupported.
-     *
-     * <p>This only allows unsupported profiles when using the LEGACY mode of the Camera API.</p>
-     *
-     * @param profileId a {@link CamcorderProfile} ID to check.
-     * @return {@code true} if supported.
-     */
-    private boolean allowedUnsupported(int cameraId, int profileId) {
-        if (!mStaticInfo.isHardwareLevelLegacy()) {
-            return false;
-        }
-
-        switch(profileId) {
-            case CamcorderProfile.QUALITY_2160P:
-            case CamcorderProfile.QUALITY_1080P:
-            case CamcorderProfile.QUALITY_HIGH:
-                return !CamcorderProfile.hasProfile(cameraId, profileId) ||
-                        CamcorderProfile.get(cameraId, profileId).videoFrameWidth >= 1080;
-        }
-        return false;
-    }
-
-    /**
-     * Test video snapshot for each  available CamcorderProfile for a given camera.
-     *
-     * <p>
-     * Preview size is set to the video size. For the burst test, frame drop and jittering
-     * is not checked.
-     * </p>
-     *
-     * @param burstTest Perform burst capture or single capture. For burst capture
-     *                  {@value #BURST_VIDEO_SNAPSHOT_NUM} capture requests will be sent.
-     */
-    private void videoSnapshotTestByCamera(boolean burstTest)
-            throws Exception {
-        final int NUM_SINGLE_SHOT_TEST = 5;
-        final int FRAMEDROP_TOLERANCE = 8;
-        final int FRAME_SIZE_15M = 15000000;
-        final float FRAME_DROP_TOLERENCE_FACTOR = 1.5f;
-        int kFrameDrop_Tolerence = FRAMEDROP_TOLERANCE;
-
-        for (int profileId : mCamcorderProfileList) {
-            int cameraId = Integer.valueOf(mCamera.getId());
-            if (!CamcorderProfile.hasProfile(cameraId, profileId) ||
-                    allowedUnsupported(cameraId, profileId)) {
-                continue;
-            }
-
-            CamcorderProfile profile = CamcorderProfile.get(cameraId, profileId);
-            Size videoSz = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
-            Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-
-            if (mStaticInfo.isHardwareLevelLegacy() &&
-                    (videoSz.getWidth() > maxPreviewSize.getWidth() ||
-                     videoSz.getHeight() > maxPreviewSize.getHeight())) {
-                // Skip. Legacy mode can only do recording up to max preview size
-                continue;
-            }
-
-            if (!mSupportedVideoSizes.contains(videoSz)) {
-                mCollector.addMessage("Video size " + videoSz.toString() + " for profile ID " +
-                        profileId + " must be one of the camera device supported video size!");
-                continue;
-            }
-
-            // For LEGACY, find closest supported smaller or equal JPEG size to the current video
-            // size; if no size is smaller than the video, pick the smallest JPEG size.  The assert
-            // for video size above guarantees that for LIMITED or FULL, we select videoSz here.
-            Size videoSnapshotSz = mOrderedStillSizes.get(mOrderedStillSizes.size() - 1);
-            for (int i = mOrderedStillSizes.size() - 2; i >= 0; i--) {
-                Size candidateSize = mOrderedStillSizes.get(i);
-                if (candidateSize.getWidth() <= videoSz.getWidth() &&
-                        candidateSize.getHeight() <= videoSz.getHeight()) {
-                    videoSnapshotSz = candidateSize;
-                }
-            }
-            if (videoSnapshotSz.getWidth() * videoSnapshotSz.getHeight() > FRAME_SIZE_15M)
-                kFrameDrop_Tolerence = (int)(FRAMEDROP_TOLERANCE * FRAME_DROP_TOLERENCE_FACTOR);
-
-            /**
-             * Only test full res snapshot when below conditions are all true.
-             * 1. Camera is a FULL device
-             * 2. video size is up to max preview size, which will be bounded by 1080p.
-             */
-            if (mStaticInfo.isHardwareLevelFull() &&
-                    videoSz.getWidth() <= maxPreviewSize.getWidth() &&
-                    videoSz.getHeight() <= maxPreviewSize.getHeight()) {
-                videoSnapshotSz = mOrderedStillSizes.get(0);
-            }
-
-            createImageReader(
-                    videoSnapshotSz, ImageFormat.JPEG,
-                    MAX_VIDEO_SNAPSHOT_IMAGES, /*listener*/null);
-
-            if (VERBOSE) {
-                Log.v(TAG, "Testing camera recording with video size " + videoSz.toString());
-            }
-
-            // Configure preview and recording surfaces.
-            mOutMediaFileName = VIDEO_FILE_PATH + "/test_video.mp4";
-            if (DEBUG_DUMP) {
-                mOutMediaFileName = VIDEO_FILE_PATH + "/test_video_" + cameraId + "_"
-                        + videoSz.toString() + ".mp4";
-            }
-
-            int numTestIterations = burstTest ? 1 : NUM_SINGLE_SHOT_TEST;
-            int totalDroppedFrames = 0;
-
-            for (int numTested = 0; numTested < numTestIterations; numTested++) {
-                prepareRecordingWithProfile(profile);
-
-                // prepare video snapshot
-                SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-                SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
-                CaptureRequest.Builder videoSnapshotRequestBuilder =
-                        mCamera.createCaptureRequest((mStaticInfo.isHardwareLevelLegacy()) ?
-                                CameraDevice.TEMPLATE_RECORD :
-                                CameraDevice.TEMPLATE_VIDEO_SNAPSHOT);
-
-                // prepare preview surface by using video size.
-                updatePreviewSurfaceWithVideoSize(videoSz);
-
-                prepareVideoSnapshot(videoSnapshotRequestBuilder, imageListener);
-                CaptureRequest request = videoSnapshotRequestBuilder.build();
-
-                // Start recording
-                startRecording(/* useMediaRecorder */true, resultListener);
-                long startTime = SystemClock.elapsedRealtime();
-
-                // Record certain duration.
-                SystemClock.sleep(RECORDING_DURATION_MS / 2);
-
-                // take video snapshot
-                if (burstTest) {
-                    List<CaptureRequest> requests =
-                            new ArrayList<CaptureRequest>(BURST_VIDEO_SNAPSHOT_NUM);
-                    for (int i = 0; i < BURST_VIDEO_SNAPSHOT_NUM; i++) {
-                        requests.add(request);
-                    }
-                    mSession.captureBurst(requests, resultListener, mHandler);
-                } else {
-                    mSession.capture(request, resultListener, mHandler);
-                }
-
-                // make sure recording is still going after video snapshot
-                SystemClock.sleep(RECORDING_DURATION_MS / 2);
-
-                // Stop recording and preview
-                int durationMs = stopRecording(/* useMediaRecorder */true);
-                // For non-burst test, use number of frames to also double check video frame rate.
-                // Burst video snapshot is allowed to cause frame rate drop, so do not use number
-                // of frames to estimate duration
-                if (!burstTest) {
-                    durationMs = (int) (resultListener.getTotalNumFrames() * 1000.0f /
-                        profile.videoFrameRate);
-                }
-
-                // Validation recorded video
-                validateRecording(videoSz, durationMs);
-
-                if (burstTest) {
-                    for (int i = 0; i < BURST_VIDEO_SNAPSHOT_NUM; i++) {
-                        Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
-                        validateVideoSnapshotCapture(image, videoSnapshotSz);
-                        image.close();
-                    }
-                } else {
-                    // validate video snapshot image
-                    Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
-                    validateVideoSnapshotCapture(image, videoSnapshotSz);
-
-                    // validate if there is framedrop around video snapshot
-                    totalDroppedFrames +=  validateFrameDropAroundVideoSnapshot(
-                            resultListener, image.getTimestamp());
-
-                    //TODO: validate jittering. Should move to PTS
-                    //validateJittering(resultListener);
-
-                    image.close();
-                }
-            }
-
-            if (!burstTest) {
-                Log.w(TAG, String.format("Camera %d Video size %s: Number of dropped frames " +
-                        "detected in %d trials is %d frames.", cameraId, videoSz.toString(),
-                        numTestIterations, totalDroppedFrames));
-                mCollector.expectLessOrEqual(
-                        String.format(
-                                "Camera %d Video size %s: Number of dropped frames %d must not"
-                                + " be larger than %d",
-                                cameraId, videoSz.toString(), totalDroppedFrames,
-                                kFrameDrop_Tolerence),
-                        kFrameDrop_Tolerence, totalDroppedFrames);
-            }
-            closeImageReader();
-        }
-    }
-
-    /**
-     * Configure video snapshot request according to the still capture size
-     */
-    private void prepareVideoSnapshot(
-            CaptureRequest.Builder requestBuilder,
-            ImageReader.OnImageAvailableListener imageListener)
-            throws Exception {
-        mReader.setOnImageAvailableListener(imageListener, mHandler);
-        assertNotNull("Recording surface must be non-null!", mRecordingSurface);
-        requestBuilder.addTarget(mRecordingSurface);
-        assertNotNull("Preview surface must be non-null!", mPreviewSurface);
-        requestBuilder.addTarget(mPreviewSurface);
-        assertNotNull("Reader surface must be non-null!", mReaderSurface);
-        requestBuilder.addTarget(mReaderSurface);
-    }
-
-    /**
-     * Update preview size with video size.
-     *
-     * <p>Preview size will be capped with max preview size.</p>
-     *
-     * @param videoSize The video size used for preview.
-     */
-    private void updatePreviewSurfaceWithVideoSize(Size videoSize) {
-        if (mOrderedPreviewSizes == null) {
-            throw new IllegalStateException("supported preview size list is not initialized yet");
-        }
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        Size previewSize = videoSize;
-        if (videoSize.getWidth() > maxPreviewSize.getWidth() ||
-                videoSize.getHeight() > maxPreviewSize.getHeight()) {
-            Log.w(TAG, "Overwrite preview size from " + videoSize.toString() +
-                    " to " + maxPreviewSize.toString());
-            previewSize = maxPreviewSize;
-        }
-
-        updatePreviewSurface(previewSize);
-    }
-
-    /**
-     * Configure MediaRecorder recording session with CamcorderProfile, prepare
-     * the recording surface.
-     */
-    private void prepareRecordingWithProfile(CamcorderProfile profile)
-            throws Exception {
-        // Prepare MediaRecorder.
-        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
-        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
-        mMediaRecorder.setProfile(profile);
-        mMediaRecorder.setOutputFile(mOutMediaFileName);
-        mMediaRecorder.prepare();
-        mRecordingSurface = mMediaRecorder.getSurface();
-        assertNotNull("Recording surface must be non-null!", mRecordingSurface);
-        mVideoFrameRate = profile.videoFrameRate;
-        mVideoSize = new Size(profile.videoFrameWidth, profile.videoFrameHeight);
-    }
-
-    /**
-     * Configure MediaRecorder recording session with CamcorderProfile, prepare
-     * the recording surface. Use AVC for video compression, AAC for audio compression.
-     * Both are required for android devices by android CDD.
-     */
-    private void prepareRecording(Size sz, int videoFrameRate, int captureRate)
-            throws Exception {
-        // Prepare MediaRecorder.
-        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
-        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
-        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
-        mMediaRecorder.setOutputFile(mOutMediaFileName);
-        mMediaRecorder.setVideoEncodingBitRate(getVideoBitRate(sz));
-        mMediaRecorder.setVideoFrameRate(videoFrameRate);
-        mMediaRecorder.setCaptureRate(captureRate);
-        mMediaRecorder.setVideoSize(sz.getWidth(), sz.getHeight());
-        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
-        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
-        mMediaRecorder.prepare();
-        mRecordingSurface = mMediaRecorder.getSurface();
-        assertNotNull("Recording surface must be non-null!", mRecordingSurface);
-        mVideoFrameRate = videoFrameRate;
-        mVideoSize = sz;
-    }
-
-    private void startRecording(boolean useMediaRecorder,
-            CameraCaptureSession.CaptureCallback listener) throws Exception {
-        List<Surface> outputSurfaces = new ArrayList<Surface>(2);
-        assertTrue("Both preview and recording surfaces should be valid",
-                mPreviewSurface.isValid() && mRecordingSurface.isValid());
-        outputSurfaces.add(mPreviewSurface);
-        outputSurfaces.add(mRecordingSurface);
-        // Video snapshot surface
-        if (mReaderSurface != null) {
-            outputSurfaces.add(mReaderSurface);
-        }
-        mSessionListener = new BlockingSessionCallback();
-        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
-
-        CaptureRequest.Builder recordingRequestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_RECORD);
-        // 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);
-        recordingRequestBuilder.addTarget(mRecordingSurface);
-        recordingRequestBuilder.addTarget(mPreviewSurface);
-        mSession.setRepeatingRequest(recordingRequestBuilder.build(), listener, mHandler);
-
-        if (useMediaRecorder) {
-            mMediaRecorder.start();
-        } else {
-            // TODO: need implement MediaCodec path.
-        }
-        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");
-        }
-        // Stop repeating, wait for captures to complete, and disconnect from
-        // surfaces
-        mSession.close();
-        mSessionListener.getStateWaiter().waitForState(SESSION_CLOSED, SESSION_CLOSE_TIMEOUT_MS);
-    }
-
-    // Stop recording and return the estimated video duration in milliseconds.
-    private int stopRecording(boolean useMediaRecorder) throws Exception {
-        long stopRecordingTime = SystemClock.elapsedRealtime();
-        if (useMediaRecorder) {
-            stopCameraStreaming();
-
-            mMediaRecorder.stop();
-            // Can reuse the MediaRecorder object after reset.
-            mMediaRecorder.reset();
-        } else {
-            // TODO: need implement MediaCodec path.
-        }
-        if (mRecordingSurface != null) {
-            mRecordingSurface.release();
-            mRecordingSurface = null;
-        }
-        return (int) (stopRecordingTime - mRecordingStartTime);
-    }
-
-    private void releaseRecorder() {
-        if (mMediaRecorder != null) {
-            mMediaRecorder.release();
-            mMediaRecorder = null;
-        }
-    }
-
-    private void validateRecording(Size sz, int durationMs) throws Exception {
-        File outFile = new File(mOutMediaFileName);
-        assertTrue("No video is recorded", outFile.exists());
-
-        MediaExtractor extractor = new MediaExtractor();
-        try {
-            extractor.setDataSource(mOutMediaFileName);
-            long durationUs = 0;
-            int width = -1, height = -1;
-            int numTracks = extractor.getTrackCount();
-            final String VIDEO_MIME_TYPE = "video";
-            for (int i = 0; i < numTracks; i++) {
-                MediaFormat format = extractor.getTrackFormat(i);
-                String mime = format.getString(MediaFormat.KEY_MIME);
-                if (mime.contains(VIDEO_MIME_TYPE)) {
-                    Log.i(TAG, "video format is: " + format.toString());
-                    durationUs = format.getLong(MediaFormat.KEY_DURATION);
-                    width = format.getInteger(MediaFormat.KEY_WIDTH);
-                    height = format.getInteger(MediaFormat.KEY_HEIGHT);
-                    break;
-                }
-            }
-            Size videoSz = new Size(width, height);
-            assertTrue("Video size doesn't match, expected " + sz.toString() +
-                    " got " + videoSz.toString(), videoSz.equals(sz));
-            int duration = (int) (durationUs / 1000);
-            if (VERBOSE) {
-                Log.v(TAG, String.format("Video duration: recorded %dms, expected %dms",
-                                         duration, durationMs));
-            }
-
-            // TODO: Don't skip this for video snapshot
-            if (!mStaticInfo.isHardwareLevelLegacy()) {
-                assertTrue(String.format(
-                        "Camera %s: Video duration doesn't match: recorded %dms, expected %dms.",
-                        mCamera.getId(), duration, durationMs),
-                        Math.abs(duration - durationMs) < DURATION_MARGIN_MS);
-            }
-        } finally {
-            extractor.release();
-            if (!DEBUG_DUMP) {
-                outFile.delete();
-            }
-        }
-    }
-
-    /**
-     * Validate video snapshot capture image object sanity and test.
-     *
-     * <p> Check for size, format and jpeg decoding</p>
-     *
-     * @param image The JPEG image to be verified.
-     * @param size The JPEG capture size to be verified against.
-     */
-    private void validateVideoSnapshotCapture(Image image, Size size) {
-        CameraTestUtils.validateImage(image, size.getWidth(), size.getHeight(),
-                ImageFormat.JPEG, /*filePath*/null);
-    }
-
-    /**
-     * Validate if video snapshot causes frame drop.
-     * Here frame drop is defined as frame duration >= 2 * expected frame duration.
-     * Return the estimated number of frames dropped during video snapshot
-     */
-    private int validateFrameDropAroundVideoSnapshot(
-            SimpleCaptureCallback resultListener, long imageTimeStamp) {
-        double expectedDurationMs = 1000.0 / mVideoFrameRate;
-        CaptureResult prevResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        long prevTS = getValueNotNull(prevResult, CaptureResult.SENSOR_TIMESTAMP);
-        while (!resultListener.hasMoreResults()) {
-            CaptureResult currentResult =
-                    resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            long currentTS = getValueNotNull(currentResult, CaptureResult.SENSOR_TIMESTAMP);
-            if (currentTS == imageTimeStamp) {
-                // validate the timestamp before and after, then return
-                CaptureResult nextResult =
-                        resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-                long nextTS = getValueNotNull(nextResult, CaptureResult.SENSOR_TIMESTAMP);
-                double durationMs = (currentTS - prevTS) / 1000000.0;
-                int totalFramesDropped = 0;
-
-                // Snapshots in legacy mode pause the preview briefly.  Skip the duration
-                // requirements for legacy mode unless this is fixed.
-                if (!mStaticInfo.isHardwareLevelLegacy()) {
-                    mCollector.expectTrue(
-                            String.format(
-                                    "Video %dx%d Frame drop detected before video snapshot: " +
-                                            "duration %.2fms (expected %.2fms)",
-                                    mVideoSize.getWidth(), mVideoSize.getHeight(),
-                                    durationMs, expectedDurationMs
-                            ),
-                            durationMs <= (expectedDurationMs * MAX_NUM_FRAME_DROP_INTERVAL_ALLOWED)
-                    );
-                    // Log a warning is there is any frame drop detected.
-                    if (durationMs >= expectedDurationMs * 2) {
-                        Log.w(TAG, String.format(
-                                "Video %dx%d Frame drop detected before video snapshot: " +
-                                        "duration %.2fms (expected %.2fms)",
-                                mVideoSize.getWidth(), mVideoSize.getHeight(),
-                                durationMs, expectedDurationMs
-                        ));
-                    }
-
-                    durationMs = (nextTS - currentTS) / 1000000.0;
-                    mCollector.expectTrue(
-                            String.format(
-                                    "Video %dx%d Frame drop detected after video snapshot: " +
-                                            "duration %.2fms (expected %.2fms)",
-                                    mVideoSize.getWidth(), mVideoSize.getHeight(),
-                                    durationMs, expectedDurationMs
-                            ),
-                            durationMs <= (expectedDurationMs * MAX_NUM_FRAME_DROP_INTERVAL_ALLOWED)
-                    );
-                    // Log a warning is there is any frame drop detected.
-                    if (durationMs >= expectedDurationMs * 2) {
-                        Log.w(TAG, String.format(
-                                "Video %dx%d Frame drop detected after video snapshot: " +
-                                        "duration %fms (expected %fms)",
-                                mVideoSize.getWidth(), mVideoSize.getHeight(),
-                                durationMs, expectedDurationMs
-                        ));
-                    }
-
-                    double totalDurationMs = (nextTS - prevTS) / 1000000.0;
-                    // Minus 2 for the expected 2 frames interval
-                    totalFramesDropped = (int) (totalDurationMs / expectedDurationMs) - 2;
-                    if (totalFramesDropped < 0) {
-                        Log.w(TAG, "totalFrameDropped is " + totalFramesDropped +
-                                ". Video frame rate might be too fast.");
-                    }
-                    totalFramesDropped = Math.max(0, totalFramesDropped);
-                }
-                return totalFramesDropped;
-            }
-            prevTS = currentTS;
-        }
-        throw new AssertionFailedError(
-                "Video snapshot timestamp does not match any of capture results!");
-    }
-
-    /**
-     * Validate frame jittering from the input simple listener's buffered results
-     */
-    private void validateJittering(SimpleCaptureCallback resultListener) {
-        double expectedDurationMs = 1000.0 / mVideoFrameRate;
-        CaptureResult prevResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        long prevTS = getValueNotNull(prevResult, CaptureResult.SENSOR_TIMESTAMP);
-        while (!resultListener.hasMoreResults()) {
-            CaptureResult currentResult =
-                    resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            long currentTS = getValueNotNull(currentResult, CaptureResult.SENSOR_TIMESTAMP);
-            double durationMs = (currentTS - prevTS) / 1000000.0;
-            double durationError = Math.abs(durationMs - expectedDurationMs);
-            long frameNumber = currentResult.getFrameNumber();
-            mCollector.expectTrue(
-                    String.format(
-                            "Resolution %dx%d Frame %d: jittering (%.2fms) exceeds bound [%.2fms,%.2fms]",
-                            mVideoSize.getWidth(), mVideoSize.getHeight(),
-                            frameNumber, durationMs,
-                            expectedDurationMs - FRAME_DURATION_ERROR_TOLERANCE_MS,
-                            expectedDurationMs + FRAME_DURATION_ERROR_TOLERANCE_MS),
-                    durationError <= FRAME_DURATION_ERROR_TOLERANCE_MS);
-            prevTS = currentTS;
-        }
-    }
-
-    /**
-     * Calculate a video bit rate based on the size. The bit rate is scaled
-     * based on ratio of video size to 1080p size.
-     */
-    private int getVideoBitRate(Size sz) {
-        int rate = BIT_RATE_1080P;
-        float scaleFactor = sz.getHeight() * sz.getWidth() / (float)(1920 * 1080);
-        rate = (int)(rate * scaleFactor);
-
-        // Clamp to the MIN, MAX range.
-        return Math.max(BIT_RATE_MIN, Math.min(BIT_RATE_MAX, rate));
-    }
-
-    /**
-     * Check if the encoder and camera are able to support this size and frame rate.
-     * Assume the video compression format is AVC.
-     */
-    private boolean isSupported(Size sz, int captureRate, int encodingRate) throws Exception {
-        // Check camera capability.
-        if (!isSupportedByCamera(sz, captureRate)) {
-            return false;
-        }
-
-        // Check encode capability.
-        if (!isSupportedByAVCEncoder(sz, encodingRate)){
-            return false;
-        }
-
-        if(VERBOSE) {
-            Log.v(TAG, "Both encoder and camera support " + sz.toString() + "@" + encodingRate + "@"
-                    + getVideoBitRate(sz) / 1000 + "Kbps");
-        }
-
-        return true;
-    }
-
-    private boolean isSupportedByCamera(Size sz, int frameRate) {
-        // Check if camera can support this sz and frame rate combination.
-        StreamConfigurationMap config = mStaticInfo.
-                getValueFromKeyNonNull(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-
-        long minDuration = config.getOutputMinFrameDuration(MediaRecorder.class, sz);
-        if (minDuration == 0) {
-            return false;
-        }
-
-        int maxFrameRate = (int) (1e9f / minDuration);
-        return maxFrameRate >= frameRate;
-    }
-
-    /**
-     * Check if encoder can support this size and frame rate combination by querying
-     * MediaCodec capability. Check is based on size and frame rate. Ignore the bit rate
-     * as the bit rates targeted in this test are well below the bit rate max value specified
-     * by AVC specification for certain level.
-     */
-    private static boolean isSupportedByAVCEncoder(Size sz, int frameRate) {
-        MediaFormat format = MediaFormat.createVideoFormat(
-                MediaFormat.MIMETYPE_VIDEO_AVC, sz.getWidth(), sz.getHeight());
-        format.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
-        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
-        return mcl.findEncoderForFormat(format) != null;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
deleted file mode 100644
index d953a876..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/RobustnessTest.java
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * Copyright 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.hardware.camera2.cts;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static android.hardware.camera2.cts.RobustnessTest.MaxOutputSizes.*;
-
-import android.content.Context;
-import android.graphics.ImageFormat;
-import android.graphics.SurfaceTexture;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.TotalCaptureResult;
-import android.hardware.camera2.CaptureFailure;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.hardware.camera2.cts.helpers.StaticMetadata;
-import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
-import android.media.CamcorderProfile;
-import android.media.Image;
-import android.media.ImageReader;
-import android.util.Log;
-import android.util.Size;
-import android.view.Display;
-import android.view.Surface;
-import android.view.WindowManager;
-
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.List;
-
-import static junit.framework.Assert.assertTrue;
-import static org.mockito.Mockito.*;
-
-/**
- * Tests exercising edge cases in camera setup, configuration, and usage.
- */
-public class RobustnessTest extends Camera2AndroidTestCase {
-    private static final String TAG = "RobustnessTest";
-
-    private static final int CONFIGURE_TIMEOUT = 5000; //ms
-    private static final int CAPTURE_TIMEOUT = 1000; //ms
-
-    /**
-     * Test that a {@link CameraCaptureSession} can be configured with a {@link Surface} containing
-     * a dimension other than one of the supported output dimensions.  The buffers produced into
-     * this surface are expected have the dimensions of the closest possible buffer size in the
-     * available stream configurations for a surface with this format.
-     */
-    public void testBadSurfaceDimensions() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing Camera " + id);
-                openDevice(id);
-
-                List<Size> testSizes = CameraTestUtils.getSortedSizesForFormat(id, mCameraManager,
-                        ImageFormat.YUV_420_888, null);
-
-                // Find some size not supported by the camera
-                Size weirdSize = new Size(643, 577);
-                int count = 0;
-                while(testSizes.contains(weirdSize)) {
-                    // Really, they can't all be supported...
-                    weirdSize = new Size(weirdSize.getWidth() + 1, weirdSize.getHeight() + 1);
-                    count++;
-                    assertTrue("Too many exotic YUV_420_888 resolutions supported.", count < 100);
-                }
-
-                // Setup imageReader with invalid dimension
-                ImageReader imageReader = ImageReader.newInstance(weirdSize.getWidth(),
-                        weirdSize.getHeight(), ImageFormat.YUV_420_888, 3);
-
-                // Setup ImageReaderListener
-                SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
-                imageReader.setOnImageAvailableListener(imageListener, mHandler);
-
-                Surface surface = imageReader.getSurface();
-                List<Surface> surfaces = new ArrayList<>();
-                surfaces.add(surface);
-
-                // Setup a capture request and listener
-                CaptureRequest.Builder request =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                request.addTarget(surface);
-
-                // Check that correct session callback is hit.
-                CameraCaptureSession.StateCallback sessionListener =
-                        mock(CameraCaptureSession.StateCallback.class);
-                CameraCaptureSession session = CameraTestUtils.configureCameraSession(mCamera,
-                        surfaces, sessionListener, mHandler);
-
-                verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()).
-                        onConfigured(any(CameraCaptureSession.class));
-                verify(sessionListener, timeout(CONFIGURE_TIMEOUT).atLeastOnce()).
-                        onReady(any(CameraCaptureSession.class));
-                verify(sessionListener, never()).onConfigureFailed(any(CameraCaptureSession.class));
-                verify(sessionListener, never()).onActive(any(CameraCaptureSession.class));
-                verify(sessionListener, never()).onClosed(any(CameraCaptureSession.class));
-
-                CameraCaptureSession.CaptureCallback captureListener =
-                        mock(CameraCaptureSession.CaptureCallback.class);
-                session.capture(request.build(), captureListener, mHandler);
-
-                verify(captureListener, timeout(CAPTURE_TIMEOUT).atLeastOnce()).
-                        onCaptureCompleted(any(CameraCaptureSession.class),
-                                any(CaptureRequest.class), any(TotalCaptureResult.class));
-                verify(captureListener, never()).onCaptureFailed(any(CameraCaptureSession.class),
-                        any(CaptureRequest.class), any(CaptureFailure.class));
-
-                Image image = imageListener.getImage(CAPTURE_TIMEOUT);
-                int imageWidth = image.getWidth();
-                int imageHeight = image.getHeight();
-                Size actualSize = new Size(imageWidth, imageHeight);
-
-                assertTrue("Camera does not contain outputted image resolution " + actualSize,
-                        testSizes.contains(actualSize));
-            } finally {
-                closeDevice(id);
-            }
-        }
-    }
-
-    /**
-     * Test for making sure the required output combinations for each hardware level and capability
-     * work as expected.
-     */
-    public void testMandatoryOutputCombinations() throws Exception {
-        /**
-         * Tables for maximum sizes to try for each hardware level and capability.
-         *
-         * Keep in sync with the tables in
-         * frameworks/base/core/java/android/hardware/camera2/CameraDevice.java#createCaptureSession
-         *
-         * Each row of the table is a set of (format, max resolution) pairs, using the below consts
-         */
-
-        // Enum values are defined in MaxOutputSizes
-        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.
-        };
-
-        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.
-        };
-
-        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.
-        };
-
-        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.
-        };
-
-        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.
-        };
-
-        final int[][][] TABLES =
-            { LEGACY_COMBINATIONS, LIMITED_COMBINATIONS, BURST_COMBINATIONS, FULL_COMBINATIONS, RAW_COMBINATIONS };
-
-        // Sanity check the tables
-        int tableIdx = 0;
-        for (int[][] table : TABLES) {
-            int rowIdx = 0;
-            for (int[] row : table) {
-                assertTrue(String.format("Odd number of entries for table %d row %d: %s ",
-                                tableIdx, rowIdx, Arrays.toString(row)),
-                        (row.length % 2) == 0);
-                for (int i = 0; i < row.length; i += 2) {
-                    int format = row[i];
-                    int maxSize = row[i + 1];
-                    assertTrue(String.format("table %d row %d index %d format not valid: %d",
-                                    tableIdx, rowIdx, i, format),
-                            format == PRIV || format == JPEG || format == YUV || format == RAW);
-                    assertTrue(String.format("table %d row %d index %d max size not valid: %d",
-                                    tableIdx, rowIdx, i + 1, maxSize),
-                            maxSize == PREVIEW || maxSize == RECORD ||
-                            maxSize == MAXIMUM || maxSize == VGA);
-                }
-                rowIdx++;
-            }
-            tableIdx++;
-        }
-
-        for (String id : mCameraIds) {
-
-            // Find the concrete max sizes for each format/resolution combination
-
-            CameraCharacteristics cc = mCameraManager.getCameraCharacteristics(id);
-
-            MaxOutputSizes maxSizes = new MaxOutputSizes(cc, id, getContext());
-
-            final StaticMetadata staticInfo = new StaticMetadata(cc);
-
-            openDevice(id);
-
-            // Always run legacy-level tests
-
-            for (int[] config : LEGACY_COMBINATIONS) {
-                testOutputCombination(id, config, maxSizes);
-            }
-
-            // Then run higher-level tests if applicable
-
-            if (!staticInfo.isHardwareLevelLegacy()) {
-
-                // If not legacy, at least limited, so run limited-level tests
-
-                for (int[] config : LIMITED_COMBINATIONS) {
-                    testOutputCombination(id, config, maxSizes);
-                }
-
-                // Check for BURST_CAPTURE, FULL and RAW and run those if appropriate
-
-                if (staticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE)) {
-                    for (int[] config : BURST_COMBINATIONS) {
-                        testOutputCombination(id, config, maxSizes);
-                    }
-                }
-
-                if (staticInfo.isHardwareLevelFull()) {
-                    for (int[] config : FULL_COMBINATIONS) {
-                        testOutputCombination(id, config, maxSizes);
-                    }
-                }
-
-                if (staticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
-                    for (int[] config : RAW_COMBINATIONS) {
-                        testOutputCombination(id, config, maxSizes);
-                    }
-                }
-            }
-
-            closeDevice(id);
-        }
-    }
-
-    /**
-     * Simple holder for resolutions to use for different camera outputs and size limits.
-     */
-    static class MaxOutputSizes {
-        // Format shorthands
-        static final int PRIV = -1;
-        static final int JPEG = ImageFormat.JPEG;
-        static final int YUV  = ImageFormat.YUV_420_888;
-        static final int RAW  = ImageFormat.RAW_SENSOR;
-
-        // Max resolution indices
-        static final int PREVIEW = 0;
-        static final int RECORD  = 1;
-        static final int MAXIMUM = 2;
-        static final int VGA = 3;
-        static final int RESOLUTION_COUNT = 4;
-
-        public MaxOutputSizes(CameraCharacteristics cc, String cameraId, Context context) {
-            StreamConfigurationMap configs =
-                    cc.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-            Size[] privSizes = configs.getOutputSizes(SurfaceTexture.class);
-            Size[] yuvSizes = configs.getOutputSizes(ImageFormat.YUV_420_888);
-            Size[] jpegSizes = configs.getOutputSizes(ImageFormat.JPEG);
-            Size[] rawSizes = configs.getOutputSizes(ImageFormat.RAW_SENSOR);
-
-            Size maxPreviewSize = getMaxPreviewSize(context, cameraId);
-
-            maxRawSize = (rawSizes != null) ? CameraTestUtils.getMaxSize(rawSizes) : null;
-
-            maxPrivSizes[PREVIEW] = getMaxSize(privSizes, maxPreviewSize);
-            maxYuvSizes[PREVIEW]  = getMaxSize(yuvSizes, maxPreviewSize);
-            maxJpegSizes[PREVIEW] = getMaxSize(jpegSizes, maxPreviewSize);
-
-            maxPrivSizes[RECORD] = getMaxRecordingSize(cameraId);
-            maxYuvSizes[RECORD]  = getMaxRecordingSize(cameraId);
-            maxJpegSizes[RECORD] = getMaxRecordingSize(cameraId);
-
-            maxPrivSizes[MAXIMUM] = CameraTestUtils.getMaxSize(privSizes);
-            maxYuvSizes[MAXIMUM] = CameraTestUtils.getMaxSize(yuvSizes);
-            maxJpegSizes[MAXIMUM] = CameraTestUtils.getMaxSize(jpegSizes);
-
-            // Must always be supported, add unconditionally
-            final Size vgaSize = new Size(640, 480);
-            maxPrivSizes[VGA] = vgaSize;
-            maxJpegSizes[VGA] = vgaSize;
-            maxYuvSizes[VGA] = vgaSize;
-        }
-
-        public final Size[] maxPrivSizes = new Size[RESOLUTION_COUNT];
-        public final Size[] maxJpegSizes = new Size[RESOLUTION_COUNT];
-        public final Size[] maxYuvSizes = new Size[RESOLUTION_COUNT];
-        public final Size maxRawSize;
-
-        static public String configToString(int[] config) {
-            StringBuilder b = new StringBuilder("{ ");
-            for (int i = 0; i < config.length; i += 2) {
-                int format = config[i];
-                int sizeLimit = config[i + 1];
-                switch (format) {
-                    case PRIV:
-                        b.append("[PRIV, ");
-                        break;
-                    case JPEG:
-                        b.append("[JPEG, ");
-                        break;
-                    case YUV:
-                        b.append("[YUV, ");
-                        break;
-                    case RAW:
-                        b.append("[RAW, ");
-                        break;
-                    default:
-                        b.append("[UNK, ");
-                        break;
-                }
-                switch (sizeLimit) {
-                    case PREVIEW:
-                        b.append("PREVIEW] ");
-                        break;
-                    case RECORD:
-                        b.append("RECORD] ");
-                        break;
-                    case MAXIMUM:
-                        b.append("MAXIMUM] ");
-                        break;
-                    case VGA:
-                        b.append("VGA] ");
-                        break;
-                    default:
-                        b.append("UNK] ");
-                        break;
-                }
-            }
-            b.append("}");
-            return b.toString();
-        }
-    }
-
-    private void testOutputCombination(String cameraId, int[] config, MaxOutputSizes maxSizes)
-            throws Exception {
-
-        Log.i(TAG, String.format("Testing Camera %s, config %s",
-                        cameraId, MaxOutputSizes.configToString(config)));
-
-        // Timeout is relaxed by 1 second for LEGACY devices to reduce false positive rate in CTS
-        final int TIMEOUT_FOR_RESULT_MS = (mStaticInfo.isHardwareLevelLegacy()) ? 2000 : 1000;
-        final int MIN_RESULT_COUNT = 3;
-
-        ImageDropperListener imageDropperListener = new ImageDropperListener();
-        // Set up outputs
-        List<Object> outputTargets = new ArrayList<>();
-        List<Surface> outputSurfaces = new ArrayList<>();
-        List<SurfaceTexture> privTargets = new ArrayList<SurfaceTexture>();
-        List<ImageReader> jpegTargets = new ArrayList<ImageReader>();
-        List<ImageReader> yuvTargets = new ArrayList<ImageReader>();
-        List<ImageReader> rawTargets = new ArrayList<ImageReader>();
-        for (int i = 0; i < config.length; i += 2) {
-            int format = config[i];
-            int sizeLimit = config[i + 1];
-
-            switch (format) {
-                case PRIV: {
-                    Size targetSize = maxSizes.maxPrivSizes[sizeLimit];
-                    SurfaceTexture target = new SurfaceTexture(/*random int*/1);
-                    target.setDefaultBufferSize(targetSize.getWidth(), targetSize.getHeight());
-                    outputTargets.add(target);
-                    outputSurfaces.add(new Surface(target));
-                    privTargets.add(target);
-                    break;
-                }
-                case JPEG: {
-                    Size targetSize = maxSizes.maxJpegSizes[sizeLimit];
-                    ImageReader target = ImageReader.newInstance(
-                        targetSize.getWidth(), targetSize.getHeight(), JPEG, MIN_RESULT_COUNT);
-                    target.setOnImageAvailableListener(imageDropperListener, mHandler);
-                    outputTargets.add(target);
-                    outputSurfaces.add(target.getSurface());
-                    jpegTargets.add(target);
-                    break;
-                }
-                case YUV: {
-                    Size targetSize = maxSizes.maxYuvSizes[sizeLimit];
-                    ImageReader target = ImageReader.newInstance(
-                        targetSize.getWidth(), targetSize.getHeight(), YUV, MIN_RESULT_COUNT);
-                    target.setOnImageAvailableListener(imageDropperListener, mHandler);
-                    outputTargets.add(target);
-                    outputSurfaces.add(target.getSurface());
-                    yuvTargets.add(target);
-                    break;
-                }
-                case RAW: {
-                    Size targetSize = maxSizes.maxRawSize;
-                    ImageReader target = ImageReader.newInstance(
-                        targetSize.getWidth(), targetSize.getHeight(), RAW, MIN_RESULT_COUNT);
-                    target.setOnImageAvailableListener(imageDropperListener, mHandler);
-                    outputTargets.add(target);
-                    outputSurfaces.add(target.getSurface());
-                    rawTargets.add(target);
-                    break;
-                }
-                default:
-                    fail("Unknown output format " + format);
-            }
-        }
-
-        boolean haveSession = false;
-        try {
-            CaptureRequest.Builder requestBuilder =
-                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-            for (Surface s : outputSurfaces) {
-                requestBuilder.addTarget(s);
-            }
-
-            CameraCaptureSession.CaptureCallback mockCaptureCallback =
-                    mock(CameraCaptureSession.CaptureCallback.class);
-
-            createSession(outputSurfaces);
-            haveSession = true;
-            CaptureRequest request = requestBuilder.build();
-            mCameraSession.setRepeatingRequest(request, mockCaptureCallback, mHandler);
-
-            verify(mockCaptureCallback,
-                    timeout(TIMEOUT_FOR_RESULT_MS * MIN_RESULT_COUNT).atLeast(MIN_RESULT_COUNT))
-                    .onCaptureCompleted(
-                        eq(mCameraSession),
-                        eq(request),
-                        isA(TotalCaptureResult.class));
-            verify(mockCaptureCallback, never()).
-                    onCaptureFailed(
-                        eq(mCameraSession),
-                        eq(request),
-                        isA(CaptureFailure.class));
-
-        } catch (Throwable e) {
-            mCollector.addMessage(String.format("Output combination %s failed due to: %s",
-                    MaxOutputSizes.configToString(config), e.getMessage()));
-        }
-        if (haveSession) {
-            try {
-                Log.i(TAG, String.format("Done with camera %s, config %s, closing session",
-                                cameraId, MaxOutputSizes.configToString(config)));
-                stopCapture(/*fast*/false);
-            } catch (Throwable e) {
-                mCollector.addMessage(
-                    String.format("Closing down for output combination %s failed due to: %s",
-                            MaxOutputSizes.configToString(config), e.getMessage()));
-            }
-        }
-
-        for (SurfaceTexture target : privTargets) {
-            target.release();
-        }
-        for (ImageReader target : jpegTargets) {
-            target.close();
-        }
-        for (ImageReader target : yuvTargets) {
-            target.close();
-        }
-        for (ImageReader target : rawTargets) {
-            target.close();
-        }
-    }
-
-    private static Size getMaxRecordingSize(String cameraId) {
-        int id = Integer.valueOf(cameraId);
-
-        int quality =
-                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_2160P) ?
-                    CamcorderProfile.QUALITY_2160P :
-                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_1080P) ?
-                    CamcorderProfile.QUALITY_1080P :
-                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_720P) ?
-                    CamcorderProfile.QUALITY_720P :
-                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_480P) ?
-                    CamcorderProfile.QUALITY_480P :
-                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_QVGA) ?
-                    CamcorderProfile.QUALITY_QVGA :
-                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_CIF) ?
-                    CamcorderProfile.QUALITY_CIF :
-                CamcorderProfile.hasProfile(id, CamcorderProfile.QUALITY_QCIF) ?
-                    CamcorderProfile.QUALITY_QCIF :
-                    -1;
-
-        assertTrue("No recording supported for camera id " + cameraId, quality != -1);
-
-        CamcorderProfile maxProfile = CamcorderProfile.get(id, quality);
-        return new Size(maxProfile.videoFrameWidth, maxProfile.videoFrameHeight);
-    }
-
-    /**
-     * Get maximum size in list that's equal or smaller to than the bound.
-     * Returns null if no size is smaller than or equal to the bound.
-     */
-    private static Size getMaxSize(Size[] sizes, Size bound) {
-        if (sizes == null || sizes.length == 0) {
-            throw new IllegalArgumentException("sizes was empty");
-        }
-
-        Size sz = null;
-        for (Size size : sizes) {
-            if (size.getWidth() <= bound.getWidth() && size.getHeight() <= bound.getHeight()) {
-
-                if (sz == null) {
-                    sz = size;
-                } else {
-                    long curArea = sz.getWidth() * (long) sz.getHeight();
-                    long newArea = size.getWidth() * (long) size.getHeight();
-                    if ( newArea > curArea ) {
-                        sz = size;
-                    }
-                }
-            }
-        }
-
-        assertTrue("No size under bound found: " + Arrays.toString(sizes) + " bound " + bound,
-                sz != null);
-
-        return sz;
-    }
-
-    private static Size getMaxPreviewSize(Context context, String cameraId) {
-        try {
-            WindowManager windowManager =
-                (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
-            Display display = windowManager.getDefaultDisplay();
-
-            int width = display.getWidth();
-            int height = display.getHeight();
-
-            if (height > width) {
-                height = width;
-                width = display.getHeight();
-            }
-
-            CameraManager camMgr =
-                (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
-            List<Size> orderedPreviewSizes = CameraTestUtils.getSupportedPreviewSizes(
-                cameraId, camMgr, PREVIEW_SIZE_BOUND);
-
-            if (orderedPreviewSizes != null) {
-                for (Size size : orderedPreviewSizes) {
-                    if (width >= size.getWidth() &&
-                        height >= size.getHeight())
-                        return size;
-                }
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "getMaxPreviewSize Failed. "+e.toString());
-        }
-        return PREVIEW_SIZE_BOUND;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataCollectionTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataCollectionTest.java
deleted file mode 100644
index 283f09b..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataCollectionTest.java
+++ /dev/null
@@ -1,181 +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.hardware.camera2.cts;
-
-import android.content.pm.PackageManager;
-import android.cts.util.DeviceReportLog;
-import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
-import android.hardware.camera2.cts.helpers.CameraMetadataGetter;
-import android.util.Log;
-
-import com.android.cts.util.ResultType;
-import com.android.cts.util.ResultUnit;
-
-import org.json.JSONArray;
-import org.json.JSONObject;
-
-import java.util.Iterator;
-
-/**
- * This test collects camera2 API static metadata and reports to device report.
- *
- */
-public class StaticMetadataCollectionTest extends Camera2SurfaceViewTestCase {
-    private static final String TAG = "StaticMetadataCollectionTest";
-
-    private DeviceReportLog mReportLog;
-
-    @Override
-    protected void setUp() throws Exception {
-        mReportLog = new DeviceReportLog();
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Deliver the report to host will automatically clear the report log.
-        mReportLog.deliverReportToHost(getInstrumentation());
-        super.tearDown();
-    }
-
-    public void testDataCollection() {
-        if (hasCameraFeature()) {
-            CameraMetadataGetter cameraInfoGetter = new CameraMetadataGetter(mCameraManager);
-            for (String id : mCameraIds) {
-                // Gather camera info
-                JSONObject cameraInfo = cameraInfoGetter.getCameraInfo(id);
-                dumpJsonObjectAsCtsResult(String.format("camera2_id%s_static_info", id), cameraInfo);
-                dumpDoubleAsCtsResult(String.format("camera2_id%s_static_info:", id)
-                        + cameraInfo.toString(), 0);
-
-                JSONObject[] templates = cameraInfoGetter.getCaptureRequestTemplates(id);
-                for (int i = 0; i < templates.length; i++) {
-                    dumpJsonObjectAsCtsResult(String.format("camera2_id%s_capture_template%d",
-                            id, CameraMetadataGetter.TEMPLATE_IDS[i]), templates[i]);
-                    if (templates[i] != null) {
-                        dumpDoubleAsCtsResult(String.format("camera2_id%s_capture_template%d:",
-                                id, CameraMetadataGetter.TEMPLATE_IDS[i])
-                                + templates[i].toString(), 0);
-                    }
-                }
-            }
-
-            try {
-                cameraInfoGetter.close();
-            } catch (Exception e) {
-                Log.e(TAG, "Unable to close camera info getter " + e.getMessage());
-            }
-
-            mReportLog.printSummary("Camera data collection for static info and capture request"
-                    + " templates",
-                    0.0, ResultType.NEUTRAL, ResultUnit.NONE);
-        }
-
-    }
-
-    private void dumpDoubleAsCtsResult(String name, double value) {
-        mReportLog.printValue(name, value, ResultType.NEUTRAL, ResultUnit.NONE);
-    }
-
-    public void dumpDoubleArrayAsCtsResult(String name, double[] values) {
-        mReportLog.printArray(name, values, ResultType.NEUTRAL, ResultUnit.NONE);
-    }
-
-    private double getJsonValueAsDouble(String name, Object obj) throws Exception {
-        if (obj == null) {
-            Log.e(TAG, "Null value: " + name);
-            throw new Exception();
-        } else if (obj instanceof Double) {
-            return ((Double)obj).doubleValue();
-        } else if (obj instanceof Float) {
-            return ((Float)obj).floatValue();
-        } else if (obj instanceof Long) {
-            return ((Long)obj).longValue();
-        } else if (obj instanceof Integer) {
-            return ((Integer)obj).intValue();
-        } else if (obj instanceof Byte) {
-            return ((Byte)obj).intValue();
-        } else if (obj instanceof Short) {
-            return ((Short)obj).intValue();
-        } else if (obj instanceof Boolean) {
-            return ((Boolean)obj) ? 1 : 0;
-        } else {
-            Log.e(TAG, "Unsupported value type: " + name);
-            throw new Exception();
-        }
-    }
-
-    private void dumpJsonArrayAsCtsResult(String name, JSONArray arr) throws Exception {
-        if (arr == null || arr.length() == 0) {
-            dumpDoubleAsCtsResult(name + "[]", 0);
-        } else if (arr.get(0) instanceof JSONObject) {
-            for (int i = 0; i < arr.length(); i++) {
-                dumpJsonObjectAsCtsResult(name+String.format("[%04d]",i),(JSONObject)arr.get(i));
-            }
-        } else if (arr.get(0) instanceof JSONArray) {
-            for (int i = 0; i < arr.length(); i++) {
-                dumpJsonArrayAsCtsResult(name+String.format("[%04d]",i),(JSONArray)arr.get(i));
-            }
-        } else if (!(arr.get(0) instanceof String)) {
-            double[] values = new double[arr.length()];
-            for (int i = 0; i < arr.length(); i++) {
-                values[i] = getJsonValueAsDouble(name + "[]", arr.get(i));
-            }
-            dumpDoubleArrayAsCtsResult(name + "[]", values);
-        } else if (arr.get(0) instanceof String) {
-            for (int i = 0; i < arr.length(); i++) {
-                dumpDoubleAsCtsResult(
-                        name+String.format("[%04d]",i)+" = "+(String)arr.get(i), 0);
-            }
-        } else {
-            Log.e(TAG, "Unsupported array value type: " + name);
-            throw new Exception();
-        }
-    }
-
-    private void dumpJsonObjectAsCtsResult(String name, JSONObject obj) {
-        if (obj == null) {
-            dumpDoubleAsCtsResult(name + "{}", 0);
-            return;
-        }
-        Iterator<?> keys = obj.keys();
-        while (keys.hasNext()) {
-            try {
-                String key = (String)keys.next();
-                if (obj.get(key) instanceof JSONObject) {
-                    dumpJsonObjectAsCtsResult(name+"."+key, (JSONObject)obj.get(key));
-                } else if (obj.get(key) instanceof JSONArray) {
-                    dumpJsonArrayAsCtsResult(name+"."+key, (JSONArray)obj.get(key));
-                } else if (!(obj.get(key) instanceof String)) {
-                    dumpDoubleAsCtsResult(name+"."+key,
-                            getJsonValueAsDouble(name+"."+key, obj.get(key)));
-                } else if (obj.get(key) instanceof String) {
-                    dumpDoubleAsCtsResult(name+"."+key + " = " + (String)obj.get(key), 0);
-                } else {
-                    Log.e(TAG, "Unsupported object field type: " + name + "." + key);
-                }
-            } catch (Exception e) {
-                // Swallow
-            }
-        }
-    }
-
-    private boolean hasCameraFeature() {
-        PackageManager packageManager = getActivity().getPackageManager();
-        return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY);
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java
deleted file mode 100644
index b8c2f2e..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StaticMetadataTest.java
+++ /dev/null
@@ -1,519 +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.hardware.camera2.cts;
-
-import static android.hardware.camera2.CameraCharacteristics.*;
-
-import android.graphics.ImageFormat;
-import android.graphics.Rect;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.CameraCharacteristics.Key;
-import android.hardware.camera2.cts.helpers.StaticMetadata;
-import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
-import android.hardware.camera2.cts.testcases.Camera2AndroidTestCase;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.util.Log;
-import android.util.Pair;
-import android.util.Size;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * <p>
- * This class covers the {@link CameraCharacteristics} tests that are not
- * covered by {@link CaptureRequestTest} and {@link ExtendedCameraCharacteristicsTest}
- * </p>
- * <p>
- * Note that most of the tests in this class don't require camera open.
- * </p>
- */
-public class StaticMetadataTest extends Camera2AndroidTestCase {
-    private static final String TAG = "StaticMetadataTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final float MIN_FPS_FOR_FULL_DEVICE = 20.0f;
-    private String mCameraId;
-
-    // Last defined capability enum, for iterating over all of them
-    private static final int LAST_CAPABILITY_ENUM = REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE;
-
-    /**
-     * Test the available capability for different hardware support level devices.
-     */
-    public void testHwSupportedLevel() throws Exception {
-        Key<StreamConfigurationMap> key =
-                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
-        final float SIZE_ERROR_MARGIN = 0.03f;
-        for (String id : mCameraIds) {
-            initStaticMetadata(id);
-            StreamConfigurationMap configs = mStaticInfo.getValueFromKeyNonNull(key);
-            Rect activeRect = mStaticInfo.getActiveArraySizeChecked();
-            Size sensorSize = new Size(activeRect.width(), activeRect.height());
-            List<Integer> availableCaps = mStaticInfo.getAvailableCapabilitiesChecked();
-
-            mCollector.expectTrue("All device must contains BACKWARD_COMPATIBLE capability",
-                    availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE));
-
-            if (mStaticInfo.isHardwareLevelFull()) {
-                // Capability advertisement must be right.
-                mCollector.expectTrue("Full device must contain MANUAL_SENSOR capability",
-                        availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR));
-                mCollector.expectTrue("Full device must contain MANUAL_POST_PROCESSING capability",
-                        availableCaps.contains(
-                                REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING));
-                mCollector.expectTrue("Full device must contain BURST_CAPTURE capability",
-                        availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE));
-
-                // Max resolution fps must be >= 20.
-                mCollector.expectTrue("Full device must support at least 20fps for max resolution",
-                        getFpsForMaxSize(id) >= MIN_FPS_FOR_FULL_DEVICE);
-
-                // Need support per frame control
-                mCollector.expectTrue("Full device must support per frame control",
-                        mStaticInfo.isPerFrameControlSupported());
-            }
-
-            if (availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                mCollector.expectTrue("MANUAL_SENSOR capability always requires " +
-                        "READ_SENSOR_SETTINGS capability as well",
-                        availableCaps.contains(REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS));
-            }
-
-            // Max jpeg resolution must be very close to  sensor resolution
-            Size[] jpegSizes = configs.getOutputSizes(ImageFormat.JPEG);
-            Size maxJpegSize = CameraTestUtils.getMaxSize(jpegSizes);
-            mCollector.expectSizesAreSimilar(
-                    "Active array size and max JPEG size should be similar",
-                    sensorSize, maxJpegSize, SIZE_ERROR_MARGIN);
-
-            // TODO: test all the keys mandatory for all capability devices.
-        }
-    }
-
-    /**
-     * Test max number of output stream reported by device
-     */
-    public void testMaxNumOutputStreams() throws Exception {
-        for (String id : mCameraIds) {
-            initStaticMetadata(id);
-            int maxNumStreamsRaw = mStaticInfo.getMaxNumOutputStreamsRawChecked();
-            int maxNumStreamsProc = mStaticInfo.getMaxNumOutputStreamsProcessedChecked();
-            int maxNumStreamsProcStall = mStaticInfo.getMaxNumOutputStreamsProcessedStallChecked();
-
-            mCollector.expectTrue("max number of raw output streams must be a non negative number",
-                    maxNumStreamsRaw >= 0);
-            mCollector.expectTrue("max number of processed (stalling) output streams must be >= 1",
-                    maxNumStreamsProcStall >= 1);
-
-            if (mStaticInfo.isHardwareLevelFull()) {
-                mCollector.expectTrue("max number of processed (non-stalling) output streams" +
-                        "must be >= 3 for FULL device",
-                        maxNumStreamsProc >= 3);
-            } else {
-                mCollector.expectTrue("max number of processed (non-stalling) output streams" +
-                        "must be >= 2 for LIMITED device",
-                        maxNumStreamsProc >= 2);
-            }
-        }
-
-    }
-
-    /**
-     * Test advertised capability does match available keys and vice versa
-     */
-    public void testCapabilities() throws Exception {
-        for (String id : mCameraIds) {
-            initStaticMetadata(id);
-            List<Integer> availableCaps = mStaticInfo.getAvailableCapabilitiesChecked();
-
-            for (Integer capability = REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE;
-                    capability <= LAST_CAPABILITY_ENUM; capability++) {
-                boolean isCapabilityAvailable = availableCaps.contains(capability);
-                validateCapability(capability, isCapabilityAvailable);
-            }
-            // Note: Static metadata for capabilities is tested in ExtendedCameraCharacteristicsTest
-        }
-    }
-
-    /**
-     * Check if request keys' presence match expectation.
-     *
-     * @param capabilityName The name string of capability being tested. Used for output messages.
-     * @param requestKeys The capture request keys to be checked
-     * @param expectedPresence Expected presence of {@code requestKeys}. {@code true} for expecting
-     *        all keys are available. Otherwise {@code false}
-     * @return {@code true} if request keys' presence match expectation. Otherwise {@code false}
-     */
-    private boolean validateRequestKeysPresence(String capabilityName,
-            Collection<CaptureRequest.Key<?>> requestKeys, boolean expectedPresence) {
-        boolean actualPresence = mStaticInfo.areRequestKeysAvailable(requestKeys);
-        if (expectedPresence != actualPresence) {
-            if (expectedPresence) {
-                for (CaptureRequest.Key<?> key : requestKeys) {
-                    if (!mStaticInfo.areKeysAvailable(key)) {
-                        mCollector.addMessage(String.format(
-                                "Camera %s list capability %s but doesn't contain request key %s",
-                                mCameraId, capabilityName, key.getName()));
-                    }
-                }
-            } else {
-                Log.w(TAG, String.format(
-                        "Camera %s doesn't list capability %s but contain all required keys",
-                        mCameraId, capabilityName));
-            }
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Check if result keys' presence match expectation.
-     *
-     * @param capabilityName The name string of capability being tested. Used for output messages.
-     * @param resultKeys The capture result keys to be checked
-     * @param expectedPresence Expected presence of {@code resultKeys}. {@code true} for expecting
-     *        all keys are available. Otherwise {@code false}
-     * @return {@code true} if result keys' presence match expectation. Otherwise {@code false}
-     */
-    private boolean validateResultKeysPresence(String capabilityName,
-            Collection<CaptureResult.Key<?>> resultKeys, boolean expectedPresence) {
-        boolean actualPresence = mStaticInfo.areResultKeysAvailable(resultKeys);
-        if (expectedPresence != actualPresence) {
-            if (expectedPresence) {
-                for (CaptureResult.Key<?> key : resultKeys) {
-                    if (!mStaticInfo.areKeysAvailable(key)) {
-                        mCollector.addMessage(String.format(
-                                "Camera %s list capability %s but doesn't contain result key %s",
-                                mCameraId, capabilityName, key.getName()));
-                    }
-                }
-            } else {
-                Log.w(TAG, String.format(
-                        "Camera %s doesn't list capability %s but contain all required keys",
-                        mCameraId, capabilityName));
-            }
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Check if characteristics keys' presence match expectation.
-     *
-     * @param capabilityName The name string of capability being tested. Used for output messages.
-     * @param characteristicsKeys The characteristics keys to be checked
-     * @param expectedPresence Expected presence of {@code characteristicsKeys}. {@code true} for
-     *        expecting all keys are available. Otherwise {@code false}
-     * @return {@code true} if characteristics keys' presence match expectation.
-     *         Otherwise {@code false}
-     */
-    private boolean validateCharacteristicsKeysPresence(String capabilityName,
-            Collection<CameraCharacteristics.Key<?>> characteristicsKeys,
-            boolean expectedPresence) {
-        boolean actualPresence = mStaticInfo.areCharacteristicsKeysAvailable(characteristicsKeys);
-        if (expectedPresence != actualPresence) {
-            if (expectedPresence) {
-                for (CameraCharacteristics.Key<?> key : characteristicsKeys) {
-                    if (!mStaticInfo.areKeysAvailable(key)) {
-                        mCollector.addMessage(String.format(
-                                "Camera %s list capability %s but doesn't contain" +
-                                "characteristics key %s",
-                                mCameraId, capabilityName, key.getName()));
-                    }
-                }
-            } else {
-                Log.w(TAG, String.format(
-                        "Camera %s doesn't list capability %s but contain all required keys",
-                        mCameraId, capabilityName));
-            }
-            return false;
-        }
-        return true;
-    }
-
-    private void validateCapability(Integer capability, boolean isCapabilityAvailable) {
-        List<CaptureRequest.Key<?>> requestKeys = new ArrayList<>();
-        Set<CaptureResult.Key<?>> resultKeys = new HashSet<>();
-        // Capability requirements other than key presences
-        List<Pair<String, Boolean>> additionalRequirements = new ArrayList<>();
-
-        /* For available capabilities, only check request keys in this test
-           Characteristics keys are tested in ExtendedCameraCharacteristicsTest
-           Result keys are tested in CaptureResultTest */
-        String capabilityName;
-        switch (capability) {
-            case REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE:
-                capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE";
-                requestKeys.add(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE);
-                requestKeys.add(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION);
-                requestKeys.add(CaptureRequest.CONTROL_AE_LOCK);
-                requestKeys.add(CaptureRequest.CONTROL_AE_MODE);
-                requestKeys.add(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
-                requestKeys.add(CaptureRequest.CONTROL_AF_MODE);
-                requestKeys.add(CaptureRequest.CONTROL_AF_TRIGGER);
-                requestKeys.add(CaptureRequest.CONTROL_AWB_LOCK);
-                requestKeys.add(CaptureRequest.CONTROL_AWB_MODE);
-                requestKeys.add(CaptureRequest.CONTROL_CAPTURE_INTENT);
-                requestKeys.add(CaptureRequest.CONTROL_EFFECT_MODE);
-                requestKeys.add(CaptureRequest.CONTROL_MODE);
-                requestKeys.add(CaptureRequest.CONTROL_SCENE_MODE);
-                requestKeys.add(CaptureRequest.CONTROL_VIDEO_STABILIZATION_MODE);
-                requestKeys.add(CaptureRequest.FLASH_MODE);
-                requestKeys.add(CaptureRequest.JPEG_GPS_LOCATION);
-                requestKeys.add(CaptureRequest.JPEG_ORIENTATION);
-                requestKeys.add(CaptureRequest.JPEG_QUALITY);
-                requestKeys.add(CaptureRequest.JPEG_THUMBNAIL_QUALITY);
-                requestKeys.add(CaptureRequest.JPEG_THUMBNAIL_SIZE);
-                requestKeys.add(CaptureRequest.SCALER_CROP_REGION);
-                requestKeys.add(CaptureRequest.STATISTICS_FACE_DETECT_MODE);
-                if (mStaticInfo.getAeMaxRegionsChecked() > 0) {
-                    requestKeys.add(CaptureRequest.CONTROL_AE_REGIONS);
-                } else {
-                    mCollector.expectTrue(
-                            "CONTROL_AE_REGIONS is available but aeMaxRegion is 0",
-                            !mStaticInfo.areKeysAvailable(CaptureRequest.CONTROL_AE_REGIONS));
-                }
-                if (mStaticInfo.getAwbMaxRegionsChecked() > 0) {
-                    requestKeys.add(CaptureRequest.CONTROL_AWB_REGIONS);
-                } else {
-                    mCollector.expectTrue(
-                            "CONTROL_AWB_REGIONS is available but awbMaxRegion is 0",
-                            !mStaticInfo.areKeysAvailable(CaptureRequest.CONTROL_AWB_REGIONS));
-                }
-                if (mStaticInfo.getAfMaxRegionsChecked() > 0) {
-                    requestKeys.add(CaptureRequest.CONTROL_AF_REGIONS);
-                } else {
-                    mCollector.expectTrue(
-                            "CONTROL_AF_REGIONS is available but afMaxRegion is 0",
-                            !mStaticInfo.areKeysAvailable(CaptureRequest.CONTROL_AF_REGIONS));
-                }
-                break;
-            case REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING:
-                capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING";
-                requestKeys.add(CaptureRequest.TONEMAP_MODE);
-                requestKeys.add(CaptureRequest.COLOR_CORRECTION_GAINS);
-                requestKeys.add(CaptureRequest.COLOR_CORRECTION_TRANSFORM);
-                requestKeys.add(CaptureRequest.SHADING_MODE);
-                requestKeys.add(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE);
-                requestKeys.add(CaptureRequest.TONEMAP_CURVE);
-                requestKeys.add(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE);
-
-                // Legacy mode always doesn't support these requirements
-                Boolean contrastCurveModeSupported = false;
-                Boolean offColorAberrationModeSupported = false;
-                if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
-                    int[] tonemapModes = mStaticInfo.getAvailableToneMapModesChecked();
-                    List<Integer> modeList = (tonemapModes.length == 0) ?
-                            new ArrayList<Integer>() :
-                            Arrays.asList(CameraTestUtils.toObject(tonemapModes));
-                    contrastCurveModeSupported =
-                            modeList.contains(CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE);
-                    int[] colorAberrationModes =
-                            mStaticInfo.getAvailableColorAberrationModesChecked();
-                    modeList = (colorAberrationModes.length == 0) ?
-                            new ArrayList<Integer>() :
-                            Arrays.asList(CameraTestUtils.toObject(colorAberrationModes));
-                    offColorAberrationModeSupported =
-                            modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF);
-                }
-                additionalRequirements.add(new Pair<String, Boolean>(
-                        "Tonemap mode must include CONTRAST_CURVE", contrastCurveModeSupported));
-                additionalRequirements.add(new Pair<String, Boolean>(
-                        "Color aberration mode must include OFF", offColorAberrationModeSupported));
-                break;
-            case REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR:
-                capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR";
-                requestKeys.add(CaptureRequest.SENSOR_FRAME_DURATION);
-                requestKeys.add(CaptureRequest.SENSOR_EXPOSURE_TIME);
-                requestKeys.add(CaptureRequest.SENSOR_SENSITIVITY);
-                if (mStaticInfo.hasFocuser()) {
-                    requestKeys.add(CaptureRequest.LENS_APERTURE);
-                    requestKeys.add(CaptureRequest.LENS_FOCUS_DISTANCE);
-                    requestKeys.add(CaptureRequest.LENS_FILTER_DENSITY);
-                    requestKeys.add(CaptureRequest.LENS_OPTICAL_STABILIZATION_MODE);
-                }
-                requestKeys.add(CaptureRequest.BLACK_LEVEL_LOCK);
-                break;
-            case REQUEST_AVAILABLE_CAPABILITIES_RAW:
-                // RAW_CAPABILITY needs to check for not just capture request keys
-                validateRawCapability(isCapabilityAvailable);
-                return;
-            case REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE:
-                // Tested in ExtendedCameraCharacteristicsTest
-                return;
-            case REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS:
-                capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_READ_SENSOR_SETTINGS";
-                resultKeys.add(CaptureResult.SENSOR_FRAME_DURATION);
-                resultKeys.add(CaptureResult.SENSOR_EXPOSURE_TIME);
-                resultKeys.add(CaptureResult.SENSOR_SENSITIVITY);
-                if (mStaticInfo.hasFocuser()) {
-                    resultKeys.add(CaptureResult.LENS_APERTURE);
-                    resultKeys.add(CaptureResult.LENS_FOCUS_DISTANCE);
-                    resultKeys.add(CaptureResult.LENS_FILTER_DENSITY);
-                }
-                break;
-            default:
-                capabilityName = "Unknown";
-                assertTrue(String.format("Unknown capability set: %d", capability),
-                           !isCapabilityAvailable);
-                return;
-        }
-
-        // Check additional requirements and exit early if possible
-        if (!isCapabilityAvailable) {
-            for (Pair<String, Boolean> p : additionalRequirements) {
-                String requirement = p.first;
-                Boolean meetRequirement = p.second;
-                // No further check is needed if we've found why capability cannot be advertised
-                if (!meetRequirement) {
-                    Log.v(TAG, String.format(
-                            "Camera %s doesn't list capability %s because of requirement: %s",
-                            mCameraId, capabilityName, requirement));
-                    return;
-                }
-            }
-        }
-
-        boolean matchExpectation = true;
-        if (!requestKeys.isEmpty()) {
-            matchExpectation &= validateRequestKeysPresence(
-                    capabilityName, requestKeys, isCapabilityAvailable);
-        }
-        if(!resultKeys.isEmpty()) {
-            matchExpectation &= validateResultKeysPresence(
-                    capabilityName, resultKeys, isCapabilityAvailable);
-        }
-
-        // Check additional requirements
-        for (Pair<String, Boolean> p : additionalRequirements) {
-            String requirement = p.first;
-            Boolean meetRequirement = p.second;
-            if (isCapabilityAvailable && !meetRequirement) {
-                mCollector.addMessage(String.format(
-                        "Camera %s list capability %s but does not meet the requirement: %s",
-                        mCameraId, capabilityName, requirement));
-            }
-        }
-
-        // In case of isCapabilityAvailable == true, error has been filed in
-        // validateRequest/ResultKeysPresence
-        if (!matchExpectation && !isCapabilityAvailable) {
-            mCollector.addMessage(String.format(
-                    "Camera %s doesn't list capability %s but meets all requirements",
-                    mCameraId, capabilityName));
-        }
-    }
-
-    private void validateRawCapability(boolean isCapabilityAvailable) {
-        String capabilityName = "REQUEST_AVAILABLE_CAPABILITIES_RAW";
-
-        Set<CaptureRequest.Key<?>> requestKeys = new HashSet<>();
-        requestKeys.add(CaptureRequest.HOT_PIXEL_MODE);
-        requestKeys.add(CaptureRequest.STATISTICS_HOT_PIXEL_MAP_MODE);
-
-        Set<CameraCharacteristics.Key<?>> characteristicsKeys = new HashSet<>();
-        characteristicsKeys.add(HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES);
-        characteristicsKeys.add(SENSOR_BLACK_LEVEL_PATTERN);
-        characteristicsKeys.add(SENSOR_CALIBRATION_TRANSFORM1);
-        characteristicsKeys.add(SENSOR_CALIBRATION_TRANSFORM2);
-        characteristicsKeys.add(SENSOR_COLOR_TRANSFORM1);
-        characteristicsKeys.add(SENSOR_COLOR_TRANSFORM2);
-        characteristicsKeys.add(SENSOR_FORWARD_MATRIX1);
-        characteristicsKeys.add(SENSOR_FORWARD_MATRIX2);
-        characteristicsKeys.add(SENSOR_INFO_ACTIVE_ARRAY_SIZE);
-        characteristicsKeys.add(SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
-        characteristicsKeys.add(SENSOR_INFO_WHITE_LEVEL);
-        characteristicsKeys.add(SENSOR_REFERENCE_ILLUMINANT1);
-        characteristicsKeys.add(SENSOR_REFERENCE_ILLUMINANT2);
-        characteristicsKeys.add(STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES);
-
-        Set<CaptureResult.Key<?>> resultKeys = new HashSet<>();
-        resultKeys.add(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
-        resultKeys.add(CaptureResult.SENSOR_GREEN_SPLIT);
-        resultKeys.add(CaptureResult.SENSOR_NOISE_PROFILE);
-
-        boolean rawOutputSupported = mStaticInfo.getRawOutputSizesChecked().length > 0;
-        boolean requestKeysPresent = mStaticInfo.areRequestKeysAvailable(requestKeys);
-        boolean characteristicsKeysPresent =
-                mStaticInfo.areCharacteristicsKeysAvailable(characteristicsKeys);
-        boolean resultKeysPresent = mStaticInfo.areResultKeysAvailable(resultKeys);
-        boolean expectCapabilityPresent = rawOutputSupported && requestKeysPresent &&
-                characteristicsKeysPresent && resultKeysPresent;
-
-        if (isCapabilityAvailable != expectCapabilityPresent) {
-            if (isCapabilityAvailable) {
-                mCollector.expectTrue(
-                        "REQUEST_AVAILABLE_CAPABILITIES_RAW should support RAW_SENSOR output",
-                        rawOutputSupported);
-                validateRequestKeysPresence(capabilityName, requestKeys, isCapabilityAvailable);
-                validateResultKeysPresence(capabilityName, resultKeys, isCapabilityAvailable);
-                validateCharacteristicsKeysPresence(capabilityName, characteristicsKeys,
-                        isCapabilityAvailable);
-            } else {
-                mCollector.addMessage(String.format(
-                        "Camera %s doesn't list capability %s but contain all required keys" +
-                        " and RAW format output",
-                        mCameraId, capabilityName));
-            }
-        }
-    }
-
-    /**
-     * Test lens facing.
-     */
-    public void testLensFacing() throws Exception {
-        for (String id : mCameraIds) {
-            initStaticMetadata(id);
-            mStaticInfo.getLensFacingChecked();
-        }
-    }
-
-    private float getFpsForMaxSize(String cameraId) throws Exception {
-        HashMap<Size, Long> minFrameDurationMap =
-                mStaticInfo.getAvailableMinFrameDurationsForFormatChecked(ImageFormat.YUV_420_888);
-
-        Size[] sizes = CameraTestUtils.getSupportedSizeForFormat(ImageFormat.YUV_420_888,
-                cameraId, mCameraManager);
-        Size maxSize = CameraTestUtils.getMaxSize(sizes);
-        Long minDuration = minFrameDurationMap.get(maxSize);
-        if (VERBOSE) {
-            Log.v(TAG, "min frame duration for size " + maxSize + " is " + minDuration);
-        }
-        assertTrue("min duration for max size must be postive number",
-                minDuration != null && minDuration > 0);
-
-        return 1e9f / minDuration;
-    }
-
-    /**
-     * Initialize static metadata for a given camera id.
-     */
-    private void initStaticMetadata(String cameraId) throws Exception {
-        mCameraId = cameraId;
-        mCollector.setCameraId(cameraId);
-        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
-                CheckLevel.COLLECT, /* collector */mCollector);
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
deleted file mode 100644
index b4113e5..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/StillCaptureTest.java
+++ /dev/null
@@ -1,1641 +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.hardware.camera2.cts;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static android.hardware.camera2.cts.helpers.AssertHelpers.assertArrayContains;
-import static junit.framework.Assert.assertNotNull;
-
-import android.graphics.ImageFormat;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.location.Location;
-import android.location.LocationManager;
-import android.hardware.camera2.DngCreator;
-import android.media.ImageReader;
-import android.util.Pair;
-import android.util.Size;
-import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
-import android.hardware.camera2.cts.CameraTestUtils.SimpleImageReaderListener;
-import android.hardware.camera2.cts.helpers.Camera2Focuser;
-import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.media.ExifInterface;
-import android.media.Image;
-import android.os.Build;
-import android.os.ConditionVariable;
-import android.util.Log;
-import android.util.Range;
-import android.util.Rational;
-import android.view.Surface;
-
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
-
-import java.io.ByteArrayOutputStream;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
-public class StillCaptureTest extends Camera2SurfaceViewTestCase {
-    private static final String TAG = "StillCaptureTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-    // 60 second to accommodate the possible long exposure time.
-    private static final int EXIF_DATETIME_ERROR_MARGIN_SEC = 60;
-    private static final float EXIF_FOCAL_LENGTH_ERROR_MARGIN = 0.001f;
-    private static final float EXIF_EXPOSURE_TIME_ERROR_MARGIN_RATIO = 0.05f;
-    private static final float EXIF_EXPOSURE_TIME_MIN_ERROR_MARGIN_SEC = 0.002f;
-    private static final float EXIF_APERTURE_ERROR_MARGIN = 0.001f;
-    private static final Location sTestLocation0 = new Location(LocationManager.GPS_PROVIDER);
-    private static final Location sTestLocation1 = new Location(LocationManager.GPS_PROVIDER);
-    private static final Location sTestLocation2 = new Location(LocationManager.NETWORK_PROVIDER);
-    private static final int RELAXED_CAPTURE_IMAGE_TIMEOUT_MS = CAPTURE_IMAGE_TIMEOUT_MS + 1000;
-    static {
-        sTestLocation0.setTime(1199145600L);
-        sTestLocation0.setLatitude(37.736071);
-        sTestLocation0.setLongitude(-122.441983);
-        sTestLocation0.setAltitude(21.0);
-
-        sTestLocation1.setTime(1199145601L);
-        sTestLocation1.setLatitude(0.736071);
-        sTestLocation1.setLongitude(0.441983);
-        sTestLocation1.setAltitude(1.0);
-
-        sTestLocation2.setTime(1199145602L);
-        sTestLocation2.setLatitude(-89.736071);
-        sTestLocation2.setLongitude(-179.441983);
-        sTestLocation2.setAltitude(100000.0);
-    }
-    // Exif test data vectors.
-    private static final ExifTestData[] EXIF_TEST_DATA = {
-            new ExifTestData(
-                    /*gpsLocation*/ sTestLocation0,
-                    /* orientation */90,
-                    /* jpgQuality */(byte) 80,
-                    /* thumbQuality */(byte) 75),
-            new ExifTestData(
-                    /*gpsLocation*/ sTestLocation1,
-                    /* orientation */180,
-                    /* jpgQuality */(byte) 90,
-                    /* thumbQuality */(byte) 85),
-            new ExifTestData(
-                    /*gpsLocation*/ sTestLocation2,
-                    /* orientation */270,
-                    /* jpgQuality */(byte) 100,
-                    /* thumbQuality */(byte) 100)
-    };
-
-    // Some exif tags that are not defined by ExifInterface but supported.
-    private static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
-    private static final String TAG_SUBSEC_TIME = "SubSecTime";
-    private static final String TAG_SUBSEC_TIME_ORIG = "SubSecTimeOriginal";
-    private static final String TAG_SUBSEC_TIME_DIG = "SubSecTimeDigitized";
-    private static final int EXIF_DATETIME_LENGTH = 19;
-    private static final int MAX_REGIONS_AE_INDEX = 0;
-    private static final int MAX_REGIONS_AWB_INDEX = 1;
-    private static final int MAX_REGIONS_AF_INDEX = 2;
-    private static final int WAIT_FOR_FOCUS_DONE_TIMEOUT_MS = 3000;
-    private static final double AE_COMPENSATION_ERROR_TOLERANCE = 0.2;
-    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;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * Test JPEG capture exif fields for each camera.
-     */
-    public void testJpegExif() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                Log.i(TAG, "Testing JPEG exif for Camera " + mCameraIds[i]);
-                openDevice(mCameraIds[i]);
-
-                jpegExifTestByCamera();
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Test normal still capture sequence.
-     * <p>
-     * Preview and and jpeg output streams are configured. Max still capture
-     * size is used for jpeg capture. The sequence of still capture being test
-     * is: start preview, auto focus, precapture metering (if AE is not
-     * converged), then capture jpeg. The AWB and AE are in auto modes. AF mode
-     * is CONTINUOUS_PICTURE.
-     * </p>
-     */
-    public void testTakePicture() throws Exception{
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing touch for focus for Camera " + id);
-                openDevice(id);
-
-                takePictureTestByCamera(/*aeRegions*/null, /*awbRegions*/null, /*afRegions*/null);
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Test basic Raw capture. Raw buffer avaiablility is checked, but raw buffer data is not.
-     */
-    public void testBasicRawCapture()  throws Exception {
-       for (int i = 0; i < mCameraIds.length; i++) {
-           try {
-               Log.i(TAG, "Testing raw capture for Camera " + mCameraIds[i]);
-               openDevice(mCameraIds[i]);
-
-               if (!mStaticInfo.isCapabilitySupported(
-                       CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
-                   Log.i(TAG, "RAW capability is not supported in camera " + mCameraIds[i] +
-                           ". Skip the test.");
-                   continue;
-               }
-
-               rawCaptureTestByCamera();
-           } finally {
-               closeDevice();
-               closeImageReader();
-           }
-       }
-    }
-
-
-    /**
-     * Test the full raw capture use case.
-     *
-     * This includes:
-     * - Configuring the camera with a preview, jpeg, and raw output stream.
-     * - Running preview until AE/AF can settle.
-     * - Capturing with a request targeting all three output streams.
-     */
-    public void testFullRawCapture() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                Log.i(TAG, "Testing raw capture for Camera " + mCameraIds[i]);
-                openDevice(mCameraIds[i]);
-                if (!mStaticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_RAW)) {
-                    Log.i(TAG, "RAW capability is not supported in camera " + mCameraIds[i] +
-                            ". Skip the test.");
-                    continue;
-                }
-
-                fullRawCaptureTestByCamera();
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-    /**
-     * Test touch for focus.
-     * <p>
-     * AF is in CAF mode when preview is started, test uses several pre-selected
-     * regions to simulate touches. Active scan is triggered to make sure the AF
-     * converges in reasonable time.
-     * </p>
-     */
-    public void testTouchForFocus() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing touch for focus for Camera " + id);
-                openDevice(id);
-                int maxAfRegions = mStaticInfo.getAfMaxRegionsChecked();
-                if (!(mStaticInfo.hasFocuser() && maxAfRegions > 0)) {
-                    continue;
-                }
-
-                touchForFocusTestByCamera();
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Test all combination of available preview sizes and still sizes.
-     * <p>
-     * For each still capture, Only the jpeg buffer is validated, capture
-     * result validation is covered by {@link #jpegExifTestByCamera} test.
-     * </p>
-     */
-    public void testStillPreviewCombination() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing Still preview capture combination for Camera " + id);
-                openDevice(id);
-
-                previewStillCombinationTestByCamera();
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Test AE compensation.
-     * <p>
-     * For each integer EV compensation setting: retrieve the exposure value (exposure time *
-     * sensitivity) with or without compensation, verify if the exposure value is legal (conformed
-     * to what static info has) and the ratio between two exposure values matches EV compensation
-     * setting. Also test for the behavior that exposure settings should be changed when AE
-     * compensation settings is changed, even when AE lock is ON.
-     * </p>
-     */
-    public void testAeCompensation() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing AE compensation for Camera " + id);
-                openDevice(id);
-
-                if (mStaticInfo.isHardwareLevelLegacy()) {
-                    Log.i(TAG, "Skipping test on legacy devices");
-                    continue;
-                }
-
-                aeCompensationTestByCamera();
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Test Ae region for still capture.
-     */
-    public void testAeRegions() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing AE regions for Camera " + id);
-                openDevice(id);
-
-                boolean aeRegionsSupported = isRegionsSupportedFor3A(MAX_REGIONS_AE_INDEX);
-                if (!aeRegionsSupported) {
-                    continue;
-                }
-
-                ArrayList<MeteringRectangle[]> aeRegionTestCases = get3ARegionTestCasesForCamera();
-                for (MeteringRectangle[] aeRegions : aeRegionTestCases) {
-                    takePictureTestByCamera(aeRegions, /*awbRegions*/null, /*afRegions*/null);
-                }
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Test AWB region for still capture.
-     */
-    public void testAwbRegions() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing AE regions for Camera " + id);
-                openDevice(id);
-
-                boolean awbRegionsSupported = isRegionsSupportedFor3A(MAX_REGIONS_AWB_INDEX);
-                if (!awbRegionsSupported) {
-                    continue;
-                }
-
-                ArrayList<MeteringRectangle[]> awbRegionTestCases = get3ARegionTestCasesForCamera();
-                for (MeteringRectangle[] awbRegions : awbRegionTestCases) {
-                    takePictureTestByCamera(/*aeRegions*/null, awbRegions, /*afRegions*/null);
-                }
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Test Af region for still capture.
-     */
-    public void testAfRegions() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing AF regions for Camera " + id);
-                openDevice(id);
-
-                boolean afRegionsSupported = isRegionsSupportedFor3A(MAX_REGIONS_AF_INDEX);
-                if (!afRegionsSupported) {
-                    continue;
-                }
-
-                ArrayList<MeteringRectangle[]> afRegionTestCases = get3ARegionTestCasesForCamera();
-                for (MeteringRectangle[] afRegions : afRegionTestCases) {
-                    takePictureTestByCamera(/*aeRegions*/null, /*awbRegions*/null, afRegions);
-                }
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Test preview is still running after a still request
-     */
-    public void testPreviewPersistence() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                Log.i(TAG, "Testing preview persistence for Camera " + id);
-                openDevice(id);
-                previewPersistenceTestByCamera();
-            } finally {
-                closeDevice();
-                closeImageReader();
-            }
-        }
-    }
-
-    /**
-     * Start preview,take a picture and test preview is still running after snapshot
-     */
-    private void previewPersistenceTestByCamera() throws Exception {
-        Size maxStillSz = mOrderedStillSizes.get(0);
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
-
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        SimpleCaptureCallback stillResultListener = new SimpleCaptureCallback();
-        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
-        CaptureRequest.Builder previewRequest =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        CaptureRequest.Builder stillRequest =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-        prepareStillCaptureAndStartPreview(previewRequest, stillRequest, maxPreviewSz,
-                maxStillSz, resultListener, imageListener);
-
-        // make sure preview is actually running
-        waitForNumResults(resultListener, NUM_FRAMES_WAITED);
-
-        // take a picture
-        CaptureRequest request = stillRequest.build();
-        mSession.capture(request, stillResultListener, mHandler);
-        stillResultListener.getCaptureResultForRequest(request,
-                WAIT_FOR_RESULT_TIMEOUT_MS);
-
-        // validate image
-        Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
-        validateJpegCapture(image, maxStillSz);
-
-        // make sure preview is still running after still capture
-        waitForNumResults(resultListener, NUM_FRAMES_WAITED);
-
-        stopPreview();
-
-        // Free image resources
-        image.close();
-        closeImageReader();
-        return;
-    }
-
-    /**
-     * Take a picture for a given set of 3A regions for a particular camera.
-     * <p>
-     * Before take a still capture, it triggers an auto focus and lock it first,
-     * then wait for AWB to converge and lock it, then trigger a precapture
-     * metering sequence and wait for AE converged. After capture is received, the
-     * capture result and image are validated.
-     * </p>
-     *
-     * @param aeRegions AE regions for this capture
-     * @param awbRegions AWB regions for this capture
-     * @param afRegions AF regions for this capture
-     */
-    private void takePictureTestByCamera(
-            MeteringRectangle[] aeRegions, MeteringRectangle[] awbRegions,
-            MeteringRectangle[] afRegions) throws Exception {
-
-        boolean hasFocuser = mStaticInfo.hasFocuser();
-
-        Size maxStillSz = mOrderedStillSizes.get(0);
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
-        CaptureResult result;
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
-        CaptureRequest.Builder previewRequest =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        CaptureRequest.Builder stillRequest =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-        prepareStillCaptureAndStartPreview(previewRequest, stillRequest, maxPreviewSz,
-                maxStillSz, resultListener, imageListener);
-
-        // Set AE mode to ON_AUTO_FLASH if flash is available.
-        if (mStaticInfo.hasFlash()) {
-            previewRequest.set(CaptureRequest.CONTROL_AE_MODE,
-                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
-            stillRequest.set(CaptureRequest.CONTROL_AE_MODE,
-                    CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
-        }
-
-        Camera2Focuser focuser = null;
-        /**
-         * Step 1: trigger an auto focus run, and wait for AF locked.
-         */
-        boolean canSetAfRegion = hasFocuser && (afRegions != null) &&
-                isRegionsSupportedFor3A(MAX_REGIONS_AF_INDEX);
-        if (hasFocuser) {
-            SimpleAutoFocusListener afListener = new SimpleAutoFocusListener();
-            focuser = new Camera2Focuser(mCamera, mSession, mPreviewSurface, afListener,
-                    mStaticInfo.getCharacteristics(), mHandler);
-            if (canSetAfRegion) {
-                stillRequest.set(CaptureRequest.CONTROL_AF_REGIONS, afRegions);
-            }
-            focuser.startAutoFocus(afRegions);
-            afListener.waitForAutoFocusDone(WAIT_FOR_FOCUS_DONE_TIMEOUT_MS);
-        }
-
-        /**
-         * Have to get the current AF mode to be used for other 3A repeating
-         * request, otherwise, the new AF mode in AE/AWB request could be
-         * different with existing repeating requests being sent by focuser,
-         * then it could make AF unlocked too early. Beside that, for still
-         * capture, AF mode must not be different with the one in current
-         * repeating request, otherwise, the still capture itself would trigger
-         * an AF mode change, and the AF lock would be lost for this capture.
-         */
-        int currentAfMode = CaptureRequest.CONTROL_AF_MODE_OFF;
-        if (hasFocuser) {
-            currentAfMode = focuser.getCurrentAfMode();
-        }
-        previewRequest.set(CaptureRequest.CONTROL_AF_MODE, currentAfMode);
-        stillRequest.set(CaptureRequest.CONTROL_AF_MODE, currentAfMode);
-
-        /**
-         * Step 2: AF is already locked, wait for AWB converged, then lock it.
-         */
-        resultListener = new SimpleCaptureCallback();
-        boolean canSetAwbRegion =
-                (awbRegions != null) && isRegionsSupportedFor3A(MAX_REGIONS_AWB_INDEX);
-        if (canSetAwbRegion) {
-            previewRequest.set(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
-            stillRequest.set(CaptureRequest.CONTROL_AWB_REGIONS, awbRegions);
-        }
-        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
-        if (mStaticInfo.isHardwareLevelLimitedOrBetter()) {
-            waitForResultValue(resultListener, CaptureResult.CONTROL_AWB_STATE,
-                    CaptureResult.CONTROL_AWB_STATE_CONVERGED, NUM_RESULTS_WAIT_TIMEOUT);
-        } else {
-            // LEGACY Devices don't have the AWB_STATE reported in results, so just wait
-            waitForSettingsApplied(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-        }
-        previewRequest.set(CaptureRequest.CONTROL_AWB_LOCK, true);
-        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
-        // Validate the next result immediately for region and mode.
-        result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        mCollector.expectEquals("AWB mode in result and request should be same",
-                previewRequest.get(CaptureRequest.CONTROL_AWB_MODE),
-                result.get(CaptureResult.CONTROL_AWB_MODE));
-        if (canSetAwbRegion) {
-            MeteringRectangle[] resultAwbRegions =
-                    getValueNotNull(result, CaptureResult.CONTROL_AWB_REGIONS);
-            mCollector.expectEquals("AWB regions in result and request should be same",
-                    awbRegions, resultAwbRegions);
-        }
-
-        /**
-         * Step 3: trigger an AE precapture metering sequence and wait for AE converged.
-         */
-        resultListener = new SimpleCaptureCallback();
-        boolean canSetAeRegion =
-                (aeRegions != null) && isRegionsSupportedFor3A(MAX_REGIONS_AE_INDEX);
-        if (canSetAeRegion) {
-            previewRequest.set(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
-            stillRequest.set(CaptureRequest.CONTROL_AE_REGIONS, aeRegions);
-        }
-        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
-        previewRequest.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,
-                CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
-        mSession.capture(previewRequest.build(), resultListener, mHandler);
-        waitForAeStable(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-        // Validate the next result immediately for region and mode.
-        result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        mCollector.expectEquals("AE mode in result and request should be same",
-                previewRequest.get(CaptureRequest.CONTROL_AE_MODE),
-                result.get(CaptureResult.CONTROL_AE_MODE));
-        if (canSetAeRegion) {
-            MeteringRectangle[] resultAeRegions =
-                    getValueNotNull(result, CaptureResult.CONTROL_AE_REGIONS);
-
-            mCollector.expectMeteringRegionsAreSimilar(
-                    "AE regions in result and request should be similar",
-                    aeRegions,
-                    resultAeRegions,
-                    METERING_REGION_ERROR_PERCENT_DELTA);
-        }
-
-        /**
-         * Step 4: take a picture when all 3A are in good state.
-         */
-        resultListener = new SimpleCaptureCallback();
-        CaptureRequest request = stillRequest.build();
-        mSession.capture(request, resultListener, mHandler);
-        // Validate the next result immediately for region and mode.
-        result = resultListener.getCaptureResultForRequest(request, WAIT_FOR_RESULT_TIMEOUT_MS);
-        mCollector.expectEquals("AF mode in result and request should be same",
-                stillRequest.get(CaptureRequest.CONTROL_AF_MODE),
-                result.get(CaptureResult.CONTROL_AF_MODE));
-        if (canSetAfRegion) {
-            MeteringRectangle[] resultAfRegions =
-                    getValueNotNull(result, CaptureResult.CONTROL_AF_REGIONS);
-            mCollector.expectMeteringRegionsAreSimilar(
-                    "AF regions in result and request should be similar",
-                    afRegions,
-                    resultAfRegions,
-                    METERING_REGION_ERROR_PERCENT_DELTA);
-        }
-
-        if (hasFocuser) {
-            // Unlock auto focus.
-            focuser.cancelAutoFocus();
-        }
-
-        // validate image
-        Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
-        validateJpegCapture(image, maxStillSz);
-
-        // Free image resources
-        image.close();
-
-        stopPreview();
-    }
-
-    /**
-     * Test touch region for focus by camera.
-     */
-    private void touchForFocusTestByCamera() throws Exception {
-        SimpleCaptureCallback listener = new SimpleCaptureCallback();
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
-        startPreview(requestBuilder, maxPreviewSz, listener);
-
-        SimpleAutoFocusListener afListener = new SimpleAutoFocusListener();
-        Camera2Focuser focuser = new Camera2Focuser(mCamera, mSession, mPreviewSurface, afListener,
-                mStaticInfo.getCharacteristics(), mHandler);
-        ArrayList<MeteringRectangle[]> testAfRegions = get3ARegionTestCasesForCamera();
-
-        for (MeteringRectangle[] afRegions : testAfRegions) {
-            focuser.touchForAutoFocus(afRegions);
-            afListener.waitForAutoFocusDone(WAIT_FOR_FOCUS_DONE_TIMEOUT_MS);
-            focuser.cancelAutoFocus();
-        }
-    }
-
-    private void previewStillCombinationTestByCamera() throws Exception {
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
-
-        for (Size stillSz : mOrderedStillSizes)
-            for (Size previewSz : mOrderedPreviewSizes) {
-                if (VERBOSE) {
-                    Log.v(TAG, "Testing JPEG capture size " + stillSz.toString()
-                            + " with preview size " + previewSz.toString() + " for camera "
-                            + mCamera.getId());
-                }
-                CaptureRequest.Builder previewRequest =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-                CaptureRequest.Builder stillRequest =
-                        mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-                prepareStillCaptureAndStartPreview(previewRequest, stillRequest, previewSz,
-                        stillSz, resultListener, imageListener);
-                mSession.capture(stillRequest.build(), resultListener, mHandler);
-                Image image = imageListener.getImage((mStaticInfo.isHardwareLevelLegacy()) ?
-                        RELAXED_CAPTURE_IMAGE_TIMEOUT_MS : CAPTURE_IMAGE_TIMEOUT_MS);
-                validateJpegCapture(image, stillSz);
-
-                // Free image resources
-                image.close();
-
-                // stopPreview must be called here to make sure next time a preview stream
-                // is created with new size.
-                stopPreview();
-            }
-    }
-
-    /**
-     * Basic raw capture test for each camera.
-     */
-    private void rawCaptureTestByCamera() throws Exception {
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
-        Size[] rawSizes = mStaticInfo.getRawOutputSizesChecked();
-
-        assertTrue("No capture sizes available for RAW format!",
-                rawSizes.length != 0);
-        Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
-        Size size = new Size(activeArray.width(), activeArray.height());
-        assertTrue("Missing ActiveArraySize", activeArray.width() > 0 &&
-                activeArray.height() > 0);
-        assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
-                rawSizes, size);
-
-        // Prepare raw capture and start preview.
-        CaptureRequest.Builder previewBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        CaptureRequest.Builder rawBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
-        prepareRawCaptureAndStartPreview(previewBuilder, rawBuilder, maxPreviewSz, size,
-                resultListener, imageListener);
-
-        if (VERBOSE) {
-            Log.v(TAG, "Testing Raw capture with size " + size.toString()
-                    + ", preview size " + maxPreviewSz);
-        }
-
-        CaptureRequest rawRequest = rawBuilder.build();
-        mSession.capture(rawRequest, resultListener, mHandler);
-
-        Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
-        validateRaw16Image(image, size);
-        if (DEBUG) {
-            byte[] rawBuffer = getDataFromImage(image);
-            String rawFileName = DEBUG_FILE_NAME_BASE + "/test" + "_" + size.toString() + "_cam" +
-                    mCamera.getId() + ".raw16";
-            Log.d(TAG, "Dump raw file into " + rawFileName);
-            dumpFile(rawFileName, rawBuffer);
-        }
-
-        // Free image resources
-        image.close();
-
-        stopPreview();
-    }
-
-    private void fullRawCaptureTestByCamera() throws Exception {
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
-        Size maxStillSz = mOrderedStillSizes.get(0);
-        Size[] rawSizes = mStaticInfo.getRawOutputSizesChecked();
-
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        SimpleImageReaderListener jpegListener = new SimpleImageReaderListener();
-        SimpleImageReaderListener rawListener = new SimpleImageReaderListener();
-
-        assertTrue("No capture sizes available for RAW format!",
-                rawSizes.length != 0);
-        Rect activeArray = mStaticInfo.getActiveArraySizeChecked();
-        Size size = new Size(activeArray.width(), activeArray.height());
-        assertTrue("Missing ActiveArraySize", activeArray.width() > 0 &&
-                activeArray.height() > 0);
-        assertArrayContains("Available sizes for RAW format must include ActiveArraySize",
-                rawSizes, size);
-
-        if (VERBOSE) {
-            Log.v(TAG, "Testing multi capture with size " + size.toString()
-                    + ", preview size " + maxPreviewSz);
-        }
-
-        // Prepare raw capture and start preview.
-        CaptureRequest.Builder previewBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        CaptureRequest.Builder multiBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-
-        ImageReader rawReader = null;
-        ImageReader jpegReader = null;
-
-        try {
-            // Create ImageReaders.
-            rawReader = makeImageReader(size,
-                    ImageFormat.RAW_SENSOR, MAX_READER_IMAGES, rawListener, mHandler);
-            jpegReader = makeImageReader(maxStillSz,
-                    ImageFormat.JPEG, MAX_READER_IMAGES, jpegListener, mHandler);
-            updatePreviewSurface(maxPreviewSz);
-
-            // Configure output streams with preview and jpeg streams.
-            List<Surface> outputSurfaces = new ArrayList<Surface>();
-            outputSurfaces.add(rawReader.getSurface());
-            outputSurfaces.add(jpegReader.getSurface());
-            outputSurfaces.add(mPreviewSurface);
-            mSessionListener = new BlockingSessionCallback();
-            mSession = configureCameraSession(mCamera, outputSurfaces,
-                    mSessionListener, mHandler);
-
-            // Configure the requests.
-            previewBuilder.addTarget(mPreviewSurface);
-            multiBuilder.addTarget(mPreviewSurface);
-            multiBuilder.addTarget(rawReader.getSurface());
-            multiBuilder.addTarget(jpegReader.getSurface());
-
-            // Start preview.
-            mSession.setRepeatingRequest(previewBuilder.build(), null, mHandler);
-
-            // Poor man's 3A, wait 2 seconds for AE/AF (if any) to settle.
-            // TODO: Do proper 3A trigger and lock (see testTakePictureTest).
-            Thread.sleep(3000);
-
-            multiBuilder.set(CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE,
-                    CaptureRequest.STATISTICS_LENS_SHADING_MAP_MODE_ON);
-            CaptureRequest multiRequest = multiBuilder.build();
-
-            mSession.capture(multiRequest, resultListener, mHandler);
-
-            CaptureResult result = resultListener.getCaptureResultForRequest(multiRequest,
-                    NUM_RESULTS_WAIT_TIMEOUT);
-            Image jpegImage = jpegListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
-            basicValidateJpegImage(jpegImage, maxStillSz);
-            Image rawImage = rawListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
-            validateRaw16Image(rawImage, size);
-            verifyRawCaptureResult(multiRequest, result);
-
-
-            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-            try (DngCreator dngCreator = new DngCreator(mStaticInfo.getCharacteristics(), result)) {
-                dngCreator.writeImage(outputStream, rawImage);
-            }
-
-            if (DEBUG) {
-                byte[] rawBuffer = outputStream.toByteArray();
-                String rawFileName = DEBUG_FILE_NAME_BASE + "/raw16_" + TAG + size.toString() +
-                        "_cam_" + mCamera.getId() + ".dng";
-                Log.d(TAG, "Dump raw file into " + rawFileName);
-                dumpFile(rawFileName, rawBuffer);
-
-                byte[] jpegBuffer = getDataFromImage(jpegImage);
-                String jpegFileName = DEBUG_FILE_NAME_BASE + "/jpeg_" + TAG + size.toString() +
-                        "_cam_" + mCamera.getId() + ".jpg";
-                Log.d(TAG, "Dump jpeg file into " + rawFileName);
-                dumpFile(jpegFileName, jpegBuffer);
-            }
-
-            stopPreview();
-        } finally {
-            CameraTestUtils.closeImageReader(rawReader);
-            CameraTestUtils.closeImageReader(jpegReader);
-            rawReader = null;
-            jpegReader = null;
-        }
-    }
-
-    /**
-     * Validate that raw {@link CaptureResult}.
-     *
-     * @param rawRequest a {@link CaptureRequest} use to capture a RAW16 image.
-     * @param rawResult the {@link CaptureResult} corresponding to the given request.
-     */
-    private void verifyRawCaptureResult(CaptureRequest rawRequest, CaptureResult rawResult) {
-        assertNotNull(rawRequest);
-        assertNotNull(rawResult);
-
-        Rational[] empty = new Rational[] { Rational.ZERO, Rational.ZERO, Rational.ZERO};
-        Rational[] neutralColorPoint = mCollector.expectKeyValueNotNull("NeutralColorPoint",
-                rawResult, CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
-        if (neutralColorPoint != null) {
-            mCollector.expectEquals("NeutralColorPoint length", empty.length,
-                    neutralColorPoint.length);
-            mCollector.expectNotEquals("NeutralColorPoint cannot be all zeroes, ", empty,
-                    neutralColorPoint);
-            mCollector.expectValuesGreaterOrEqual("NeutralColorPoint", neutralColorPoint,
-                    Rational.ZERO);
-        }
-
-        mCollector.expectKeyValueGreaterOrEqual(rawResult, CaptureResult.SENSOR_GREEN_SPLIT, 0.0f);
-
-        Pair<Double, Double>[] noiseProfile = mCollector.expectKeyValueNotNull("NoiseProfile",
-                rawResult, CaptureResult.SENSOR_NOISE_PROFILE);
-        if (noiseProfile != null) {
-            mCollector.expectEquals("NoiseProfile length", noiseProfile.length,
-                /*Num CFA channels*/4);
-            for (Pair<Double, Double> p : noiseProfile) {
-                mCollector.expectTrue("NoiseProfile coefficients " + p +
-                        " must have: S > 0, O >= 0", p.first > 0 && p.second >= 0);
-            }
-        }
-
-        Integer hotPixelMode = mCollector.expectKeyValueNotNull("HotPixelMode", rawResult,
-                CaptureResult.HOT_PIXEL_MODE);
-        Boolean hotPixelMapMode = mCollector.expectKeyValueNotNull("HotPixelMapMode", rawResult,
-                CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE);
-        Point[] hotPixelMap = rawResult.get(CaptureResult.STATISTICS_HOT_PIXEL_MAP);
-
-        Size pixelArraySize = mStaticInfo.getPixelArraySizeChecked();
-        boolean[] availableHotPixelMapModes = mStaticInfo.getValueFromKeyNonNull(
-                        CameraCharacteristics.STATISTICS_INFO_AVAILABLE_HOT_PIXEL_MAP_MODES);
-
-        if (hotPixelMode != null) {
-            Integer requestMode = mCollector.expectKeyValueNotNull(rawRequest,
-                    CaptureRequest.HOT_PIXEL_MODE);
-            if (requestMode != null) {
-                mCollector.expectKeyValueEquals(rawResult, CaptureResult.HOT_PIXEL_MODE,
-                        requestMode);
-            }
-        }
-
-        if (hotPixelMapMode != null) {
-            Boolean requestMapMode = mCollector.expectKeyValueNotNull(rawRequest,
-                    CaptureRequest.STATISTICS_HOT_PIXEL_MAP_MODE);
-            if (requestMapMode != null) {
-                mCollector.expectKeyValueEquals(rawResult,
-                        CaptureResult.STATISTICS_HOT_PIXEL_MAP_MODE, requestMapMode);
-            }
-
-            if (!hotPixelMapMode) {
-                mCollector.expectTrue("HotPixelMap must be empty", hotPixelMap == null ||
-                        hotPixelMap.length == 0);
-            } else {
-                mCollector.expectTrue("HotPixelMap must not be empty", hotPixelMap != null);
-                mCollector.expectNotNull("AvailableHotPixelMapModes must not be null",
-                        availableHotPixelMapModes);
-                if (availableHotPixelMapModes != null) {
-                    mCollector.expectContains("HotPixelMapMode", availableHotPixelMapModes, true);
-                }
-
-                int height = pixelArraySize.getHeight();
-                int width = pixelArraySize.getWidth();
-                for (Point p : hotPixelMap) {
-                    mCollector.expectTrue("Hotpixel " + p + " must be in pixelArray " +
-                            pixelArraySize, p.x >= 0 && p.x < width && p.y >= 0 && p.y < height);
-                }
-            }
-        }
-        // TODO: profileHueSatMap, and profileToneCurve aren't supported yet.
-
-    }
-
-    private static boolean areGpsFieldsEqual(Location a, Location b) {
-        if (a == null || b == null) {
-            return false;
-        }
-
-        return a.getTime() == b.getTime() && a.getLatitude() == b.getLatitude() &&
-                a.getLongitude() == b.getLongitude() && a.getAltitude() == b.getAltitude() &&
-                a.getProvider() == b.getProvider();
-    }
-    /**
-     * Issue a Jpeg capture and validate the exif information.
-     * <p>
-     * TODO: Differentiate full and limited device, some of the checks rely on
-     * per frame control and synchronization, most of them don't.
-     * </p>
-     */
-    private void jpegExifTestByCamera() throws Exception {
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
-        Size maxStillSz = mOrderedStillSizes.get(0);
-        if (VERBOSE) {
-            Log.v(TAG, "Testing JPEG exif with jpeg size " + maxStillSz.toString()
-                    + ", preview size " + maxPreviewSz);
-        }
-
-        // prepare capture and start preview.
-        CaptureRequest.Builder previewBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        CaptureRequest.Builder stillBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
-        prepareStillCaptureAndStartPreview(previewBuilder, stillBuilder, maxPreviewSz, maxStillSz,
-                resultListener, imageListener);
-
-        // Set the jpeg keys, then issue a capture
-        Size[] thumbnailSizes = mStaticInfo.getAvailableThumbnailSizesChecked();
-        Size maxThumbnailSize = thumbnailSizes[thumbnailSizes.length - 1];
-        Size[] testThumbnailSizes = new Size[EXIF_TEST_DATA.length];
-        Arrays.fill(testThumbnailSizes, maxThumbnailSize);
-        // Make sure thumbnail size (0, 0) is covered.
-        testThumbnailSizes[0] = new Size(0, 0);
-
-        for (int i = 0; i < EXIF_TEST_DATA.length; i++) {
-            /**
-             * Capture multiple shots.
-             *
-             * Verify that:
-             * - Capture request get values are same as were set.
-             * - capture result's exif data is the same as was set by
-             *   the capture request.
-             * - new tags in the result set by the camera service are
-             *   present and semantically correct.
-             */
-            stillBuilder.set(CaptureRequest.JPEG_THUMBNAIL_SIZE, testThumbnailSizes[i]);
-            stillBuilder.set(CaptureRequest.JPEG_GPS_LOCATION, EXIF_TEST_DATA[i].gpsLocation);
-            stillBuilder.set(CaptureRequest.JPEG_ORIENTATION, EXIF_TEST_DATA[i].jpegOrientation);
-            stillBuilder.set(CaptureRequest.JPEG_QUALITY, EXIF_TEST_DATA[i].jpegQuality);
-            stillBuilder.set(CaptureRequest.JPEG_THUMBNAIL_QUALITY,
-                    EXIF_TEST_DATA[i].thumbnailQuality);
-
-            // Validate request set and get.
-            mCollector.expectEquals("JPEG thumbnail size request set and get should match",
-                    testThumbnailSizes[i],
-                    stillBuilder.get(CaptureRequest.JPEG_THUMBNAIL_SIZE));
-            mCollector.expectTrue("GPS locations request set and get should match.",
-                    areGpsFieldsEqual(EXIF_TEST_DATA[i].gpsLocation,
-                            stillBuilder.get(CaptureRequest.JPEG_GPS_LOCATION)));
-            mCollector.expectEquals("JPEG orientation request set and get should match",
-                    EXIF_TEST_DATA[i].jpegOrientation,
-                    stillBuilder.get(CaptureRequest.JPEG_ORIENTATION));
-            mCollector.expectEquals("JPEG quality request set and get should match",
-                    EXIF_TEST_DATA[i].jpegQuality, stillBuilder.get(CaptureRequest.JPEG_QUALITY));
-            mCollector.expectEquals("JPEG thumbnail quality request set and get should match",
-                    EXIF_TEST_DATA[i].thumbnailQuality,
-                    stillBuilder.get(CaptureRequest.JPEG_THUMBNAIL_QUALITY));
-
-            // Capture a jpeg image.
-            CaptureRequest request = stillBuilder.build();
-            mSession.capture(request, resultListener, mHandler);
-            CaptureResult stillResult =
-                    resultListener.getCaptureResultForRequest(request, NUM_RESULTS_WAIT_TIMEOUT);
-            Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
-            basicValidateJpegImage(image, maxStillSz);
-
-            byte[] jpegBuffer = getDataFromImage(image);
-            // Have to dump into a file to be able to use ExifInterface
-            String jpegFileName =
-                    DEBUG_FILE_NAME_BASE + "/Camera_" + mCamera.getId() + "_test.jpeg";
-            dumpFile(jpegFileName, jpegBuffer);
-            ExifInterface exif = new ExifInterface(jpegFileName);
-
-            if (testThumbnailSizes[i].equals(new Size(0,0))) {
-                mCollector.expectTrue(
-                        "Jpeg shouldn't have thumbnail when thumbnail size is (0, 0)",
-                        !exif.hasThumbnail());
-            } else {
-                mCollector.expectTrue(
-                        "Jpeg must have thumbnail for thumbnail size " + testThumbnailSizes[i],
-                        exif.hasThumbnail());
-            }
-
-            // Validate capture result vs. request
-            mCollector.expectEquals("JPEG thumbnail size result and request should match",
-                    testThumbnailSizes[i],
-                    stillResult.get(CaptureResult.JPEG_THUMBNAIL_SIZE));
-            if (mCollector.expectKeyValueNotNull(stillResult, CaptureResult.JPEG_GPS_LOCATION) !=
-                    null) {
-                mCollector.expectTrue("GPS location result and request should match.",
-                        areGpsFieldsEqual(EXIF_TEST_DATA[i].gpsLocation,
-                                stillResult.get(CaptureResult.JPEG_GPS_LOCATION)));
-            }
-            mCollector.expectEquals("JPEG orientation result and request should match",
-                    EXIF_TEST_DATA[i].jpegOrientation,
-                    stillResult.get(CaptureResult.JPEG_ORIENTATION));
-            mCollector.expectEquals("JPEG quality result and request should match",
-                    EXIF_TEST_DATA[i].jpegQuality, stillResult.get(CaptureResult.JPEG_QUALITY));
-            mCollector.expectEquals("JPEG thumbnail quality result and request should match",
-                    EXIF_TEST_DATA[i].thumbnailQuality,
-                    stillResult.get(CaptureResult.JPEG_THUMBNAIL_QUALITY));
-
-            // Validate other exif tags for all non-legacy devices
-            if (!mStaticInfo.isHardwareLevelLegacy()) {
-                jpegTestExifExtraTags(exif, maxStillSz, stillResult);
-            }
-
-            // Free image resources
-            image.close();
-        }
-    }
-
-    private void jpegTestExifExtraTags(ExifInterface exif, Size jpegSize, CaptureResult result)
-            throws ParseException {
-        /**
-         * TAG_IMAGE_WIDTH and TAG_IMAGE_LENGTH and TAG_ORIENTATION.
-         * Orientation and exif width/height need to be tested carefully, two cases:
-         *
-         * 1. Device rotate the image buffer physically, then exif width/height may not match
-         * the requested still capture size, we need swap them to check.
-         *
-         * 2. Device use the exif tag to record the image orientation, it doesn't rotate
-         * the jpeg image buffer itself. In this case, the exif width/height should always match
-         * the requested still capture size, and the exif orientation should always match the
-         * requested orientation.
-         *
-         */
-        int exifWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, /*defaultValue*/0);
-        int exifHeight = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, /*defaultValue*/0);
-        Size exifSize = new Size(exifWidth, exifHeight);
-        // Orientation could be missing, which is ok, default to 0.
-        int exifOrientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
-                /*defaultValue*/-1);
-        // Get requested orientation from result, because they should be same.
-        if (mCollector.expectKeyValueNotNull(result, CaptureResult.JPEG_ORIENTATION) != null) {
-            int requestedOrientation = result.get(CaptureResult.JPEG_ORIENTATION);
-            final int ORIENTATION_MIN = ExifInterface.ORIENTATION_UNDEFINED;
-            final int ORIENTATION_MAX = ExifInterface.ORIENTATION_ROTATE_270;
-            boolean orientationValid = mCollector.expectTrue(String.format(
-                    "Exif orientation must be in range of [%d, %d]",
-                    ORIENTATION_MIN, ORIENTATION_MAX),
-                    exifOrientation >= ORIENTATION_MIN && exifOrientation <= ORIENTATION_MAX);
-            if (orientationValid) {
-                /**
-                 * Device captured image doesn't respect the requested orientation,
-                 * which means it rotates the image buffer physically. Then we
-                 * should swap the exif width/height accordingly to compare.
-                 */
-                boolean deviceRotatedImage = exifOrientation == ExifInterface.ORIENTATION_UNDEFINED;
-
-                if (deviceRotatedImage) {
-                    // Case 1.
-                    boolean needSwap = (requestedOrientation % 180 == 90);
-                    if (needSwap) {
-                        exifSize = new Size(exifHeight, exifWidth);
-                    }
-                } else {
-                    // Case 2.
-                    mCollector.expectEquals("Exif orientaiton should match requested orientation",
-                            requestedOrientation, getExifOrientationInDegress(exifOrientation));
-                }
-            }
-        }
-
-        /**
-         * Ideally, need check exifSize == jpegSize == actual buffer size. But
-         * jpegSize == jpeg decode bounds size(from jpeg jpeg frame
-         * header, not exif) was validated in ImageReaderTest, no need to
-         * validate again here.
-         */
-        mCollector.expectEquals("Exif size should match jpeg capture size", jpegSize, exifSize);
-
-        // TAG_DATETIME, it should be local time
-        long currentTimeInMs = System.currentTimeMillis();
-        long currentTimeInSecond = currentTimeInMs / 1000;
-        Date date = new Date(currentTimeInMs);
-        String localDatetime = new SimpleDateFormat("yyyy:MM:dd HH:").format(date);
-        String dateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
-        if (mCollector.expectTrue("Exif TAG_DATETIME shouldn't be null", dateTime != null)) {
-            mCollector.expectTrue("Exif TAG_DATETIME is wrong",
-                    dateTime.length() == EXIF_DATETIME_LENGTH);
-            long exifTimeInSecond =
-                    new SimpleDateFormat("yyyy:MM:dd HH:mm:ss").parse(dateTime).getTime() / 1000;
-            long delta = currentTimeInSecond - exifTimeInSecond;
-            mCollector.expectTrue("Capture time deviates too much from the current time",
-                    Math.abs(delta) < EXIF_DATETIME_ERROR_MARGIN_SEC);
-            // It should be local time.
-            mCollector.expectTrue("Exif date time should be local time",
-                    dateTime.startsWith(localDatetime));
-        }
-
-        // TAG_FOCAL_LENGTH.
-        float[] focalLengths = mStaticInfo.getAvailableFocalLengthsChecked();
-        float exifFocalLength = (float)exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, -1);
-        mCollector.expectEquals("Focal length should match",
-                getClosestValueInArray(focalLengths, exifFocalLength),
-                exifFocalLength, EXIF_FOCAL_LENGTH_ERROR_MARGIN);
-        // More checks for focal length.
-        mCollector.expectEquals("Exif focal length should match capture result",
-                validateFocalLength(result), exifFocalLength);
-
-        // TAG_EXPOSURE_TIME
-        // ExifInterface API gives exposure time value in the form of float instead of rational
-        String exposureTime = exif.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
-        mCollector.expectNotNull("Exif TAG_EXPOSURE_TIME shouldn't be null", exposureTime);
-        if (mStaticInfo.areKeysAvailable(CaptureResult.SENSOR_EXPOSURE_TIME)) {
-            if (exposureTime != null) {
-                double exposureTimeValue = Double.parseDouble(exposureTime);
-                long expTimeResult = result.get(CaptureResult.SENSOR_EXPOSURE_TIME);
-                double expected = expTimeResult / 1e9;
-                double tolerance = expected * EXIF_EXPOSURE_TIME_ERROR_MARGIN_RATIO;
-                tolerance = Math.max(tolerance, EXIF_EXPOSURE_TIME_MIN_ERROR_MARGIN_SEC);
-                mCollector.expectEquals("Exif exposure time doesn't match", expected,
-                        exposureTimeValue, tolerance);
-            }
-        }
-
-        // TAG_APERTURE
-        // ExifInterface API gives aperture value in the form of float instead of rational
-        String exifAperture = exif.getAttribute(ExifInterface.TAG_APERTURE);
-        mCollector.expectNotNull("Exif TAG_APERTURE shouldn't be null", exifAperture);
-        if (mStaticInfo.areKeysAvailable(CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES)) {
-            float[] apertures = mStaticInfo.getAvailableAperturesChecked();
-            if (exifAperture != null) {
-                float apertureValue = Float.parseFloat(exifAperture);
-                mCollector.expectEquals("Aperture value should match",
-                        getClosestValueInArray(apertures, apertureValue),
-                        apertureValue, EXIF_APERTURE_ERROR_MARGIN);
-                // More checks for aperture.
-                mCollector.expectEquals("Exif aperture length should match capture result",
-                        validateAperture(result), apertureValue);
-            }
-        }
-
-        /**
-         * TAG_FLASH. TODO: For full devices, can check a lot more info
-         * (http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html#Flash)
-         */
-        String flash = exif.getAttribute(ExifInterface.TAG_FLASH);
-        mCollector.expectNotNull("Exif TAG_FLASH shouldn't be null", flash);
-
-        /**
-         * TAG_WHITE_BALANCE. TODO: For full devices, with the DNG tags, we
-         * should be able to cross-check android.sensor.referenceIlluminant.
-         */
-        String whiteBalance = exif.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
-        mCollector.expectNotNull("Exif TAG_WHITE_BALANCE shouldn't be null", whiteBalance);
-
-        // TAG_MAKE
-        String make = exif.getAttribute(ExifInterface.TAG_MAKE);
-        mCollector.expectEquals("Exif TAG_MAKE is incorrect", Build.MANUFACTURER, make);
-
-        // TAG_MODEL
-        String model = exif.getAttribute(ExifInterface.TAG_MODEL);
-        mCollector.expectEquals("Exif TAG_MODEL is incorrect", Build.MODEL, model);
-
-
-        // TAG_ISO
-        int iso = exif.getAttributeInt(ExifInterface.TAG_ISO, /*defaultValue*/-1);
-        if (mStaticInfo.areKeysAvailable(CaptureResult.SENSOR_SENSITIVITY)) {
-            int expectedIso = result.get(CaptureResult.SENSOR_SENSITIVITY);
-            mCollector.expectEquals("Exif TAG_ISO is incorrect", expectedIso, iso);
-        }
-
-        // TAG_DATETIME_DIGITIZED (a.k.a Create time for digital cameras).
-        String digitizedTime = exif.getAttribute(TAG_DATETIME_DIGITIZED);
-        mCollector.expectNotNull("Exif TAG_DATETIME_DIGITIZED shouldn't be null", digitizedTime);
-        if (digitizedTime != null) {
-            String expectedDateTime = exif.getAttribute(ExifInterface.TAG_DATETIME);
-            mCollector.expectNotNull("Exif TAG_DATETIME shouldn't be null", expectedDateTime);
-            if (expectedDateTime != null) {
-                mCollector.expectEquals("dataTime should match digitizedTime",
-                        expectedDateTime, digitizedTime);
-            }
-        }
-
-        /**
-         * TAG_SUBSEC_TIME. Since the sub second tag strings are truncated to at
-         * most 9 digits in ExifInterface implementation, use getAttributeInt to
-         * sanitize it. When the default value -1 is returned, it means that
-         * this exif tag either doesn't exist or is a non-numerical invalid
-         * string. Same rule applies to the rest of sub second tags.
-         */
-        int subSecTime = exif.getAttributeInt(TAG_SUBSEC_TIME, /*defaultValue*/-1);
-        mCollector.expectTrue("Exif TAG_SUBSEC_TIME value is null or invalid!", subSecTime > 0);
-
-        // TAG_SUBSEC_TIME_ORIG
-        int subSecTimeOrig = exif.getAttributeInt(TAG_SUBSEC_TIME_ORIG, /*defaultValue*/-1);
-        mCollector.expectTrue("Exif TAG_SUBSEC_TIME_ORIG value is null or invalid!",
-                subSecTimeOrig > 0);
-
-        // TAG_SUBSEC_TIME_DIG
-        int subSecTimeDig = exif.getAttributeInt(TAG_SUBSEC_TIME_DIG, /*defaultValue*/-1);
-        mCollector.expectTrue(
-                "Exif TAG_SUBSEC_TIME_DIG value is null or invalid!", subSecTimeDig > 0);
-    }
-
-    private int getExifOrientationInDegress(int exifOrientation) {
-        switch (exifOrientation) {
-            case ExifInterface.ORIENTATION_NORMAL:
-                return 0;
-            case ExifInterface.ORIENTATION_ROTATE_90:
-                return 90;
-            case ExifInterface.ORIENTATION_ROTATE_180:
-                return 180;
-            case ExifInterface.ORIENTATION_ROTATE_270:
-                return 270;
-            default:
-                mCollector.addMessage("It is impossible to get non 0, 90, 180, 270 degress exif" +
-                        "info based on the request orientation range");
-                return 0;
-        }
-    }
-    /**
-     * Immutable class wrapping the exif test data.
-     */
-    private static class ExifTestData {
-        public final Location gpsLocation;
-        public final int jpegOrientation;
-        public final byte jpegQuality;
-        public final byte thumbnailQuality;
-
-        public ExifTestData(Location location, int orientation,
-                byte jpgQuality, byte thumbQuality) {
-            gpsLocation = location;
-            jpegOrientation = orientation;
-            jpegQuality = jpgQuality;
-            thumbnailQuality = thumbQuality;
-        }
-    }
-
-    private void aeCompensationTestByCamera() throws Exception {
-        Range<Integer> compensationRange = mStaticInfo.getAeCompensationRangeChecked();
-        // Skip the test if exposure compensation is not supported.
-        if (compensationRange.equals(Range.create(0, 0))) {
-            return;
-        }
-
-        Rational step = mStaticInfo.getAeCompensationStepChecked();
-        float stepF = (float) step.getNumerator() / step.getDenominator();
-        int stepsPerEv = (int) Math.round(1.0 / stepF);
-        int numSteps = (compensationRange.getUpper() - compensationRange.getLower()) / stepsPerEv;
-
-        Size maxStillSz = mOrderedStillSizes.get(0);
-        Size maxPreviewSz = mOrderedPreviewSizes.get(0);
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        SimpleImageReaderListener imageListener = new SimpleImageReaderListener();
-        CaptureRequest.Builder previewRequest =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        CaptureRequest.Builder stillRequest =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
-        stillRequest.set(CaptureRequest.CONTROL_AE_LOCK, true);
-        CaptureResult normalResult;
-        CaptureResult compensatedResult;
-
-        // The following variables should only be read under the MANUAL_SENSOR capability guard:
-        long minExposureValue = -1;
-        long maxExposureTimeUs = -1;
-        long maxExposureValuePreview = -1;
-        long maxExposureValueStill = -1;
-        if (mStaticInfo.isCapabilitySupported(
-                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-            // Minimum exposure settings is mostly static while maximum exposure setting depends on
-            // frame rate range which in term depends on capture request.
-            minExposureValue = mStaticInfo.getSensitivityMinimumOrDefault() *
-                    mStaticInfo.getExposureMinimumOrDefault() / 1000;
-            long maxSensitivity = mStaticInfo.getSensitivityMaximumOrDefault();
-            maxExposureTimeUs = mStaticInfo.getExposureMaximumOrDefault() / 1000;
-            maxExposureValuePreview = getMaxExposureValue(previewRequest, maxExposureTimeUs,
-                    maxSensitivity);
-            maxExposureValueStill = getMaxExposureValue(stillRequest, maxExposureTimeUs,
-                    maxSensitivity);
-        }
-
-        // Set the max number of images to be same as the burst count, as the verification
-        // could be much slower than producing rate, and we don't want to starve producer.
-        prepareStillCaptureAndStartPreview(previewRequest, stillRequest, maxPreviewSz,
-                maxStillSz, resultListener, numSteps, imageListener);
-
-        for (int i = 0; i <= numSteps; i++) {
-            int exposureCompensation = i * stepsPerEv + compensationRange.getLower();
-            double expectedRatio = Math.pow(2.0, exposureCompensation / stepsPerEv);
-
-            // Wait for AE to be stabilized before capture: CONVERGED or FLASH_REQUIRED.
-            waitForAeStable(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-            normalResult = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-
-            long normalExposureValue = -1;
-            if (mStaticInfo.isCapabilitySupported(
-                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                // get and check if current exposure value is valid
-                normalExposureValue = getExposureValue(normalResult);
-                mCollector.expectInRange("Exposure setting out of bound", normalExposureValue,
-                        minExposureValue, maxExposureValuePreview);
-
-                // Only run the test if expectedExposureValue is within valid range
-                long expectedExposureValue = (long) (normalExposureValue * expectedRatio);
-                if (expectedExposureValue < minExposureValue ||
-                    expectedExposureValue > maxExposureValueStill) {
-                    continue;
-                }
-                Log.v(TAG, "Expect ratio: " + expectedRatio +
-                        " normalExposureValue: " + normalExposureValue +
-                        " expectedExposureValue: " + expectedExposureValue +
-                        " minExposureValue: " + minExposureValue +
-                        " maxExposureValuePreview: " + maxExposureValuePreview +
-                        " maxExposureValueStill: " + maxExposureValueStill);
-            }
-
-            // Now issue exposure compensation and wait for AE locked. AE could take a few
-            // frames to go back to locked state
-            previewRequest.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION,
-                    exposureCompensation);
-            previewRequest.set(CaptureRequest.CONTROL_AE_LOCK, true);
-            mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
-            waitForAeLocked(resultListener, NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY);
-
-            // Issue still capture
-            if (VERBOSE) {
-                Log.v(TAG, "Verifying capture result for ae compensation value "
-                        + exposureCompensation);
-            }
-
-            stillRequest.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, exposureCompensation);
-            CaptureRequest request = stillRequest.build();
-            mSession.capture(request, resultListener, mHandler);
-
-            compensatedResult = resultListener.getCaptureResultForRequest(
-                    request, WAIT_FOR_RESULT_TIMEOUT_MS);
-
-            if (mStaticInfo.isCapabilitySupported(
-                    CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                // Verify the exposure value compensates as requested
-                long compensatedExposureValue = getExposureValue(compensatedResult);
-                mCollector.expectInRange("Exposure setting out of bound", compensatedExposureValue,
-                        minExposureValue, maxExposureValueStill);
-                double observedRatio = (double) compensatedExposureValue / normalExposureValue;
-                double error = observedRatio / expectedRatio;
-                String errorString = String.format(
-                        "Exposure compensation ratio exceeds error tolerence:" +
-                        " expected(%f) observed(%f)." +
-                        " Normal exposure time %d us, sensitivity %d." +
-                        " Compensated exposure time %d us, sensitivity %d",
-                        expectedRatio, observedRatio,
-                        (int) (getValueNotNull(
-                                normalResult, CaptureResult.SENSOR_EXPOSURE_TIME) / 1000),
-                        getValueNotNull(normalResult, CaptureResult.SENSOR_SENSITIVITY),
-                        (int) (getValueNotNull(
-                                compensatedResult, CaptureResult.SENSOR_EXPOSURE_TIME) / 1000),
-                        getValueNotNull(compensatedResult, CaptureResult.SENSOR_SENSITIVITY));
-                mCollector.expectInRange(errorString, error,
-                        1.0 - AE_COMPENSATION_ERROR_TOLERANCE,
-                        1.0 + AE_COMPENSATION_ERROR_TOLERANCE);
-            }
-
-            mCollector.expectEquals("Exposure compensation result should match requested value.",
-                    exposureCompensation,
-                    compensatedResult.get(CaptureResult.CONTROL_AE_EXPOSURE_COMPENSATION));
-            mCollector.expectTrue("Exposure lock should be set",
-                    compensatedResult.get(CaptureResult.CONTROL_AE_LOCK));
-
-            Image image = imageListener.getImage(CAPTURE_IMAGE_TIMEOUT_MS);
-            validateJpegCapture(image, maxStillSz);
-            image.close();
-
-            // Recover AE compensation and lock
-            previewRequest.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
-            previewRequest.set(CaptureRequest.CONTROL_AE_LOCK, false);
-            mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
-        }
-    }
-
-    private long getExposureValue(CaptureResult result) throws Exception {
-        int expTimeUs = (int) (getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME) / 1000);
-        int sensitivity = getValueNotNull(result, CaptureResult.SENSOR_SENSITIVITY);
-        return expTimeUs * sensitivity;
-    }
-
-    private long getMaxExposureValue(CaptureRequest.Builder request, long maxExposureTimeUs,
-                long maxSensitivity)  throws Exception {
-        Range<Integer> fpsRange = request.get(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE);
-        long maxFrameDurationUs = Math.round(1000000.0 / fpsRange.getLower());
-        long currentMaxExposureTimeUs = Math.min(maxFrameDurationUs, maxExposureTimeUs);
-        return currentMaxExposureTimeUs * maxSensitivity;
-    }
-
-
-    //----------------------------------------------------------------
-    //---------Below are common functions for all tests.--------------
-    //----------------------------------------------------------------
-
-    /**
-     * Simple validation of JPEG image size and format.
-     * <p>
-     * Only validate the image object sanity. It is fast, but doesn't actually
-     * check the buffer data. Assert is used here as it make no sense to
-     * continue the test if the jpeg image captured has some serious failures.
-     * </p>
-     *
-     * @param image The captured jpeg image
-     * @param expectedSize Expected capture jpeg size
-     */
-    private static void basicValidateJpegImage(Image image, Size expectedSize) {
-        Size imageSz = new Size(image.getWidth(), image.getHeight());
-        assertTrue(
-                String.format("Image size doesn't match (expected %s, actual %s) ",
-                        expectedSize.toString(), imageSz.toString()), expectedSize.equals(imageSz));
-        assertEquals("Image format should be JPEG", ImageFormat.JPEG, image.getFormat());
-        assertNotNull("Image plane shouldn't be null", image.getPlanes());
-        assertEquals("Image plane number should be 1", 1, image.getPlanes().length);
-
-        // Jpeg decoding validate was done in ImageReaderTest, no need to duplicate the test here.
-    }
-
-    /**
-     * Validate standard raw (RAW16) capture image.
-     *
-     * @param image The raw16 format image captured
-     * @param rawSize The expected raw size
-     */
-    private static void validateRaw16Image(Image image, Size rawSize) {
-        CameraTestUtils.validateImage(image, rawSize.getWidth(), rawSize.getHeight(),
-                ImageFormat.RAW_SENSOR, /*filePath*/null);
-    }
-
-    /**
-     * Validate JPEG capture image object sanity and test.
-     * <p>
-     * In addition to image object sanity, this function also does the decoding
-     * test, which is slower.
-     * </p>
-     *
-     * @param image The JPEG image to be verified.
-     * @param jpegSize The JPEG capture size to be verified against.
-     */
-    private static void validateJpegCapture(Image image, Size jpegSize) {
-        CameraTestUtils.validateImage(image, jpegSize.getWidth(), jpegSize.getHeight(),
-                ImageFormat.JPEG, /*filePath*/null);
-    }
-
-    private static float getClosestValueInArray(float[] values, float target) {
-        int minIdx = 0;
-        float minDistance = Math.abs(values[0] - target);
-        for(int i = 0; i < values.length; i++) {
-            float distance = Math.abs(values[i] - target);
-            if (minDistance > distance) {
-                minDistance = distance;
-                minIdx = i;
-            }
-        }
-
-        return values[minIdx];
-    }
-
-    /**
-     * Validate and return the focal length.
-     *
-     * @param result Capture result to get the focal length
-     * @return Focal length from capture result or -1 if focal length is not available.
-     */
-    private float validateFocalLength(CaptureResult result) {
-        float[] focalLengths = mStaticInfo.getAvailableFocalLengthsChecked();
-        Float resultFocalLength = result.get(CaptureResult.LENS_FOCAL_LENGTH);
-        if (mCollector.expectTrue("Focal length is invalid",
-                resultFocalLength != null && resultFocalLength > 0)) {
-            List<Float> focalLengthList =
-                    Arrays.asList(CameraTestUtils.toObject(focalLengths));
-            mCollector.expectTrue("Focal length should be one of the available focal length",
-                    focalLengthList.contains(resultFocalLength));
-            return resultFocalLength;
-        }
-        return -1;
-    }
-
-    /**
-     * Validate and return the aperture.
-     *
-     * @param result Capture result to get the aperture
-     * @return Aperture from capture result or -1 if aperture is not available.
-     */
-    private float validateAperture(CaptureResult result) {
-        float[] apertures = mStaticInfo.getAvailableAperturesChecked();
-        Float resultAperture = result.get(CaptureResult.LENS_APERTURE);
-        if (mCollector.expectTrue("Capture result aperture is invalid",
-                resultAperture != null && resultAperture > 0)) {
-            List<Float> apertureList =
-                    Arrays.asList(CameraTestUtils.toObject(apertures));
-            mCollector.expectTrue("Aperture should be one of the available apertures",
-                    apertureList.contains(resultAperture));
-            return resultAperture;
-        }
-        return -1;
-    }
-
-    private static class SimpleAutoFocusListener implements Camera2Focuser.AutoFocusListener {
-        final ConditionVariable focusDone = new ConditionVariable();
-        @Override
-        public void onAutoFocusLocked(boolean success) {
-            focusDone.open();
-        }
-
-        public void waitForAutoFocusDone(long timeoutMs) {
-            if (focusDone.block(timeoutMs)) {
-                focusDone.close();
-            } else {
-                throw new TimeoutRuntimeException("Wait for auto focus done timed out after "
-                        + timeoutMs + "ms");
-            }
-        }
-    }
-
-    /**
-     * Get 5 3A region test cases, each with one square region in it.
-     * The first one is at center, the other four are at corners of
-     * active array rectangle.
-     *
-     * @return array of test 3A regions
-     */
-    private ArrayList<MeteringRectangle[]> get3ARegionTestCasesForCamera() {
-        final int TEST_3A_REGION_NUM = 5;
-        final int DEFAULT_REGION_WEIGHT = 30;
-        final int DEFAULT_REGION_SCALE_RATIO = 8;
-        ArrayList<MeteringRectangle[]> testCases =
-                new ArrayList<MeteringRectangle[]>(TEST_3A_REGION_NUM);
-        final Rect activeArraySize = mStaticInfo.getActiveArraySizeChecked();
-        int regionWidth = activeArraySize.width() / DEFAULT_REGION_SCALE_RATIO - 1;
-        int regionHeight = activeArraySize.height() / DEFAULT_REGION_SCALE_RATIO - 1;
-        int centerX = activeArraySize.width() / 2;
-        int centerY = activeArraySize.height() / 2;
-        int bottomRightX = activeArraySize.width() - 1;
-        int bottomRightY = activeArraySize.height() - 1;
-
-        // Center region
-        testCases.add(
-                new MeteringRectangle[] {
-                    new MeteringRectangle(
-                            centerX - regionWidth / 2,  // x
-                            centerY - regionHeight / 2, // y
-                            regionWidth,                // width
-                            regionHeight,               // height
-                            DEFAULT_REGION_WEIGHT)});
-
-        // Upper left corner
-        testCases.add(
-                new MeteringRectangle[] {
-                    new MeteringRectangle(
-                            0,                // x
-                            0,                // y
-                            regionWidth,      // width
-                            regionHeight,     // height
-                            DEFAULT_REGION_WEIGHT)});
-
-        // Upper right corner
-        testCases.add(
-                new MeteringRectangle[] {
-                    new MeteringRectangle(
-                            bottomRightX - regionWidth, // x
-                            0,                          // y
-                            regionWidth,                // width
-                            regionHeight,               // height
-                            DEFAULT_REGION_WEIGHT)});
-
-        // Bottom left corner
-        testCases.add(
-                new MeteringRectangle[] {
-                    new MeteringRectangle(
-                            0,                           // x
-                            bottomRightY - regionHeight, // y
-                            regionWidth,                 // width
-                            regionHeight,                // height
-                            DEFAULT_REGION_WEIGHT)});
-
-        // Bottom right corner
-        testCases.add(
-                new MeteringRectangle[] {
-                    new MeteringRectangle(
-                            bottomRightX - regionWidth,  // x
-                            bottomRightY - regionHeight, // y
-                            regionWidth,                 // width
-                            regionHeight,                // height
-                            DEFAULT_REGION_WEIGHT)});
-
-        if (VERBOSE) {
-            StringBuilder sb = new StringBuilder();
-            for (MeteringRectangle[] mr : testCases) {
-                sb.append("{");
-                sb.append(Arrays.toString(mr));
-                sb.append("}, ");
-            }
-            if (sb.length() > 1)
-                sb.setLength(sb.length() - 2); // Remove the redundant comma and space at the end
-            Log.v(TAG, "Generated test regions are: " + sb.toString());
-        }
-
-        return testCases;
-    }
-
-    private boolean isRegionsSupportedFor3A(int index) {
-        int maxRegions = 0;
-        switch (index) {
-            case MAX_REGIONS_AE_INDEX:
-                maxRegions = mStaticInfo.getAeMaxRegionsChecked();
-                break;
-            case MAX_REGIONS_AWB_INDEX:
-                maxRegions = mStaticInfo.getAwbMaxRegionsChecked();
-                break;
-            case  MAX_REGIONS_AF_INDEX:
-                maxRegions = mStaticInfo.getAfMaxRegionsChecked();
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown algorithm index");
-        }
-        boolean isRegionsSupported = maxRegions > 0;
-        if (index == MAX_REGIONS_AF_INDEX && isRegionsSupported) {
-            mCollector.expectTrue(
-                    "Device reports non-zero max AF region count for a camera without focuser!",
-                    mStaticInfo.hasFocuser());
-            isRegionsSupported = isRegionsSupported && mStaticInfo.hasFocuser();
-        }
-
-        return isRegionsSupported;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java b/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
deleted file mode 100644
index 01da4c8..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/SurfaceViewPreviewTest.java
+++ /dev/null
@@ -1,306 +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.hardware.camera2.cts;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CaptureFailure;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.TotalCaptureResult;
-import android.util.Size;
-import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
-import android.hardware.camera2.cts.testcases.Camera2SurfaceViewTestCase;
-import android.util.Log;
-import android.util.Range;
-
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-
-import static org.mockito.Mockito.*;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * CameraDevice preview test by using SurfaceView.
- */
-public class SurfaceViewPreviewTest extends Camera2SurfaceViewTestCase {
-    private static final String TAG = "SurfaceViewPreviewTest";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final int FRAME_TIMEOUT_MS = 1000;
-    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.
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * Test all supported preview sizes for each camera device.
-     * <p>
-     * For the first  {@link #NUM_FRAMES_VERIFIED}  of capture results,
-     * the {@link CaptureCallback} callback availability and the capture timestamp
-     * (monotonically increasing) ordering are verified.
-     * </p>
-     */
-    public void testCameraPreview() throws Exception {
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                Log.i(TAG, "Testing preview for Camera " + mCameraIds[i]);
-                openDevice(mCameraIds[i]);
-
-                previewTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Basic test pattern mode preview.
-     * <p>
-     * Only test the test pattern preview and capture result, the image buffer
-     * is not validated.
-     * </p>
-     */
-    public void testBasicTestPatternPreview() throws Exception{
-        for (int i = 0; i < mCameraIds.length; i++) {
-            try {
-                Log.i(TAG, "Testing preview for Camera " + mCameraIds[i]);
-                openDevice(mCameraIds[i]);
-
-                previewTestPatternTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE} for preview, validate the preview
-     * frame duration and exposure time.
-     */
-    public void testPreviewFpsRange() throws Exception {
-        for (String id : mCameraIds) {
-            try {
-                openDevice(id);
-
-                previewFpsRangeTestByCamera();
-            } finally {
-                closeDevice();
-            }
-        }
-    }
-
-    /**
-     * Test preview fps range for all supported ranges. The exposure time are frame duration are
-     * 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();
-        Range<Integer> fpsRange;
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        SimpleCaptureCallback resultListener = new SimpleCaptureCallback();
-        startPreview(requestBuilder, maxPreviewSz, resultListener);
-
-        for (int i = 0; i < fpsRanges.length; i += 1) {
-            fpsRange = fpsRanges[i];
-
-            requestBuilder.set(CaptureRequest.CONTROL_AE_TARGET_FPS_RANGE, fpsRange);
-            // Turn off auto antibanding to avoid exposure time and frame duration interference
-            // from antibanding algorithm.
-            if (antiBandingOffIsSupported) {
-                requestBuilder.set(CaptureRequest.CONTROL_AE_ANTIBANDING_MODE,
-                        CaptureRequest.CONTROL_AE_ANTIBANDING_MODE_OFF);
-            } else {
-                // The device doesn't implement the OFF mode, test continues. It need make sure
-                // that the antibanding algorithm doesn't interfere with the fps range control.
-                Log.i(TAG, "OFF antibanding mode is not supported, the camera device output must" +
-                        " satisfy the specified fps range regardless of its current antibanding" +
-                        " mode");
-            }
-
-            resultListener = new SimpleCaptureCallback();
-            mSession.setRepeatingRequest(requestBuilder.build(), resultListener, mHandler);
-
-            verifyPreviewTargetFpsRange(resultListener, NUM_FRAMES_VERIFIED, fpsRange,
-                    maxPreviewSz);
-        }
-
-        stopPreview();
-    }
-
-    private void verifyPreviewTargetFpsRange(SimpleCaptureCallback resultListener,
-            int numFramesVerified, Range<Integer> fpsRange, Size previewSz) {
-        CaptureResult result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        List<Integer> capabilities = mStaticInfo.getAvailableCapabilitiesChecked();
-
-        if (capabilities.contains(CaptureRequest.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-            long frameDuration = getValueNotNull(result, CaptureResult.SENSOR_FRAME_DURATION);
-            long[] frameDurationRange =
-                    new long[]{(long) (1e9 / fpsRange.getUpper()), (long) (1e9 / fpsRange.getLower())};
-            mCollector.expectInRange(
-                    "Frame duration must be in the range of " + Arrays.toString(frameDurationRange),
-                    frameDuration, (long) (frameDurationRange[0] * (1 - FRAME_DURATION_ERROR_MARGIN)),
-                    (long) (frameDurationRange[1] * (1 + FRAME_DURATION_ERROR_MARGIN)));
-            long expTime = getValueNotNull(result, CaptureResult.SENSOR_EXPOSURE_TIME);
-            mCollector.expectTrue(String.format("Exposure time %d must be no larger than frame"
-                    + "duration %d", expTime, frameDuration), expTime <= frameDuration);
-
-            Long minFrameDuration = mMinPreviewFrameDurationMap.get(previewSz);
-            boolean findDuration = mCollector.expectTrue("Unable to find minFrameDuration for size "
-                    + previewSz.toString(), minFrameDuration != null);
-            if (findDuration) {
-                mCollector.expectTrue("Frame duration " + frameDuration + " must be no smaller than"
-                        + " minFrameDuration " + minFrameDuration, frameDuration >= minFrameDuration);
-            }
-        } else {
-            Log.i(TAG, "verifyPreviewTargetFpsRange - MANUAL_SENSOR control is not supported," +
-                    " skipping duration and exposure time check.");
-        }
-    }
-
-    /**
-     * Test all supported preview sizes for a camera device
-     *
-     * @throws Exception
-     */
-    private void previewTestByCamera() throws Exception {
-        List<Size> previewSizes = getSupportedPreviewSizes(
-                mCamera.getId(), mCameraManager, PREVIEW_SIZE_BOUND);
-
-        for (final Size sz : previewSizes) {
-            if (VERBOSE) {
-                Log.v(TAG, "Testing camera preview size: " + sz.toString());
-            }
-
-            // TODO: vary the different settings like crop region to cover more cases.
-            CaptureRequest.Builder requestBuilder =
-                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-            CaptureCallback mockCaptureCallback =
-                    mock(CameraCaptureSession.CaptureCallback.class);
-
-            startPreview(requestBuilder, sz, mockCaptureCallback);
-            verifyCaptureResults(mSession, mockCaptureCallback, NUM_FRAMES_VERIFIED,
-                    NUM_FRAMES_VERIFIED * FRAME_TIMEOUT_MS);
-            stopPreview();
-        }
-    }
-
-    private void previewTestPatternTestByCamera() throws Exception {
-        Size maxPreviewSize = mOrderedPreviewSizes.get(0);
-        int[] testPatternModes = mStaticInfo.getAvailableTestPatternModesChecked();
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        CaptureCallback mockCaptureCallback;
-
-        final int[] TEST_PATTERN_DATA = {0, 0xFFFFFFFF, 0xFFFFFFFF, 0}; // G:100%, RB:0.
-        for (int mode : testPatternModes) {
-            if (VERBOSE) {
-                Log.v(TAG, "Test pattern mode: " + mode);
-            }
-            requestBuilder.set(CaptureRequest.SENSOR_TEST_PATTERN_MODE, mode);
-            if (mode == CaptureRequest.SENSOR_TEST_PATTERN_MODE_SOLID_COLOR) {
-                // Assign color pattern to SENSOR_TEST_PATTERN_MODE_DATA
-                requestBuilder.set(CaptureRequest.SENSOR_TEST_PATTERN_DATA, TEST_PATTERN_DATA);
-            }
-            mockCaptureCallback = mock(CaptureCallback.class);
-            startPreview(requestBuilder, maxPreviewSize, mockCaptureCallback);
-            verifyCaptureResults(mSession, mockCaptureCallback, NUM_TEST_PATTERN_FRAMES_VERIFIED,
-                    NUM_TEST_PATTERN_FRAMES_VERIFIED * FRAME_TIMEOUT_MS);
-        }
-
-        stopPreview();
-    }
-
-    private class IsCaptureResultValid extends ArgumentMatcher<TotalCaptureResult> {
-        @Override
-        public boolean matches(Object obj) {
-            TotalCaptureResult result = (TotalCaptureResult)obj;
-            Long timeStamp = result.get(CaptureResult.SENSOR_TIMESTAMP);
-            if (timeStamp != null && timeStamp.longValue() > 0L) {
-                return true;
-            }
-            return false;
-        }
-    }
-
-    private void verifyCaptureResults(
-            CameraCaptureSession session,
-            CaptureCallback mockListener,
-            int expectResultCount,
-            int timeOutMs) {
-        // Should receive expected number of onCaptureStarted callbacks.
-        ArgumentCaptor<Long> timestamps = ArgumentCaptor.forClass(Long.class);
-        ArgumentCaptor<Long> frameNumbers = ArgumentCaptor.forClass(Long.class);
-        verify(mockListener,
-                timeout(timeOutMs).atLeast(expectResultCount))
-                        .onCaptureStarted(
-                                eq(session),
-                                isA(CaptureRequest.class),
-                                timestamps.capture(),
-                                frameNumbers.capture());
-
-        // Validate timestamps: all timestamps should be larger than 0 and monotonically increase.
-        long timestamp = 0;
-        for (Long nextTimestamp : timestamps.getAllValues()) {
-            assertNotNull("Next timestamp is null!", nextTimestamp);
-            assertTrue("Captures are out of order", timestamp < nextTimestamp);
-            timestamp = nextTimestamp;
-        }
-
-        // Validate framenumbers: all framenumbers should be consecutive and positive
-        long frameNumber = -1;
-        for (Long nextFrameNumber : frameNumbers.getAllValues()) {
-            assertNotNull("Next frame number is null!", nextFrameNumber);
-            assertTrue("Captures are out of order",
-                    (frameNumber == -1) || (frameNumber + 1 == nextFrameNumber));
-            frameNumber = nextFrameNumber;
-        }
-
-        // Should receive expected number of capture results.
-        verify(mockListener,
-                timeout(timeOutMs).atLeast(expectResultCount))
-                        .onCaptureCompleted(
-                                eq(session),
-                                isA(CaptureRequest.class),
-                                argThat(new IsCaptureResultValid()));
-
-        // Should not receive any capture failed callbacks.
-        verify(mockListener, never())
-                        .onCaptureFailed(
-                                eq(session),
-                                isA(CaptureRequest.class),
-                                isA(CaptureFailure.class));
-    }
-
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java
deleted file mode 100644
index 0ee5ffc..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/CameraErrorCollector.java
+++ /dev/null
@@ -1,1052 +0,0 @@
-/*
- * Copyright 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.hardware.camera2.cts.helpers;
-
-import android.graphics.Rect;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureRequest.Builder;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.params.MeteringRectangle;
-import android.util.Log;
-import android.util.Size;
-
-import org.hamcrest.CoreMatchers;
-import org.hamcrest.Matcher;
-import org.junit.rules.ErrorCollector;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * A camera test ErrorCollector class to gather the test failures during a test,
- * instead of failing the test immediately for each failure.
- */
-public class CameraErrorCollector extends ErrorCollector {
-
-    private static final String TAG = "CameraErrorCollector";
-    private static final boolean LOG_ERRORS = Log.isLoggable(TAG, Log.ERROR);
-
-    private String mCameraMsg = "";
-
-    @Override
-    public void verify() throws Throwable {
-        // Do not remove if using JUnit 3 test runners. super.verify() is protected.
-        super.verify();
-    }
-
-    /**
-     * Adds an unconditional error to the table.
-     *
-     * <p>Execution continues, but test will fail at the end.</p>
-     *
-     * @param message A string containing the failure reason.
-     */
-    public void addMessage(String message) {
-        addErrorSuper(new Throwable(mCameraMsg + message));
-    }
-
-    /**
-     * Adds a Throwable to the table. <p>Execution continues, but the test will fail at the end.</p>
-     */
-    @Override
-    public void addError(Throwable error) {
-        addErrorSuper(new Throwable(mCameraMsg + error.getMessage(), error));
-    }
-
-    private void addErrorSuper(Throwable error) {
-        if (LOG_ERRORS) Log.e(TAG, error.getMessage());
-        super.addError(error);
-    }
-
-    /**
-     * Adds a failure to the table if {@code matcher} does not match {@code value}.
-     * Execution continues, but the test will fail at the end if the match fails.
-     * The camera id is included into the failure log.
-     */
-    @Override
-    public <T> void checkThat(final T value, final Matcher<T> matcher) {
-        super.checkThat(mCameraMsg, value, matcher);
-    }
-
-    /**
-     * Adds a failure with the given {@code reason} to the table if
-     * {@code matcher} does not match {@code value}. Execution continues, but
-     * the test will fail at the end if the match fails. The camera id is
-     * included into the failure log.
-     */
-    @Override
-    public <T> void checkThat(final String reason, final T value, final Matcher<T> matcher) {
-        super.checkThat(mCameraMsg + reason, value, matcher);
-    }
-
-    /**
-     * Set the camera id to this error collector object for logging purpose.
-     *
-     * @param id The camera id to be set.
-     */
-    public void setCameraId(String id) {
-        if (id != null) {
-            mCameraMsg = "Test failed for camera " + id + ": ";
-        } else {
-            mCameraMsg = "";
-        }
-    }
-
-    /**
-     * Adds a failure to the table if {@code condition} is not {@code true}.
-     * <p>
-     * Execution continues, but the test will fail at the end if the condition
-     * failed.
-     * </p>
-     *
-     * @param msg Message to be logged when check fails.
-     * @param condition Log the failure if it is not true.
-     */
-    public boolean expectTrue(String msg, boolean condition) {
-        if (!condition) {
-            addMessage(msg);
-        }
-
-        return condition;
-    }
-
-    /**
-     * Check if the two values are equal.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected Expected value to be checked against.
-     * @param actual Actual value to be checked.
-     * @return {@code true} if the two values are equal, {@code false} otherwise.
-     *
-     * @throws IllegalArgumentException if {@code expected} was {@code null}
-     */
-    public <T> boolean expectEquals(String msg, T expected, T actual) {
-        if (expected == null) {
-            throw new IllegalArgumentException("expected value shouldn't be null");
-        }
-
-        if (!Objects.equals(expected, actual)) {
-            addMessage(String.format("%s (expected = %s, actual = %s) ", msg, expected,
-                    actual));
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check if the two values are not equal.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected Expected value to be checked against.
-     * @param actual Actual value to be checked.
-     * @return {@code true} if the two values are not equal, {@code false} otherwise.
-     */
-    public <T> boolean expectNotEquals(String msg, T expected, T actual) {
-        if (Objects.equals(expected, actual)) {
-            addMessage(String.format("%s (expected = %s, actual = %s) ", msg, expected,
-                    actual));
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check if the two arrays of values are deeply equal.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected Expected array of values to be checked against.
-     * @param actual Actual array of values to be checked.
-     * @return {@code true} if the two arrays of values are deeply equal, {@code false} otherwise.
-     *
-     * @throws IllegalArgumentException if {@code expected} was {@code null}
-     */
-    public <T> boolean expectEquals(String msg, T[] expected, T[] actual) {
-        if (expected == null) {
-            throw new IllegalArgumentException("expected value shouldn't be null");
-        }
-
-        if (!Arrays.deepEquals(expected, actual)) {
-            addMessage(String.format("%s (expected = %s, actual = %s) ", msg,
-                    Arrays.deepToString(expected), Arrays.deepToString(actual)));
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check if the two arrays of values are not deeply equal.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected Expected array of values to be checked against.
-     * @param actual Actual array of values to be checked.
-     * @return {@code true} if the two arrays of values are not deeply equal, {@code false}
-     *          otherwise.
-     *
-     * @throws IllegalArgumentException if {@code expected} was {@code null}
-     */
-    public <T> boolean expectNotEquals(String msg, T[] expected, T[] actual) {
-        if (expected == null) {
-            throw new IllegalArgumentException("expected value shouldn't be null");
-        }
-
-        if (Arrays.deepEquals(expected, actual)) {
-            addMessage(String.format("%s (expected = %s, actual = %s) ", msg,
-                    Arrays.deepToString(expected), Arrays.deepToString(actual)));
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check that the {@code actual} value is greater than the {@code expected} value.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected The expected value to check that the actual value is larger than.
-     * @param actual Actual value to check.
-     * @return {@code true} if {@code actual} is greater than {@code expected}.
-     */
-    public <T extends Comparable<? super T>> boolean expectGreater(String msg, T expected,
-            T actual) {
-        return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
-                msg, expected, actual), actual.compareTo(expected) > 0);
-    }
-
-    /**
-     * Check that the {@code actual} value is greater than or equal to the {@code expected} value.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected The expected value to check that the actual value is larger than or equal to.
-     * @param actual Actual value to check.
-     * @return {@code true} if {@code actual} is greater than or equal to {@code expected}.
-     */
-    public <T extends Comparable<? super T>> boolean expectGreaterOrEqual(String msg, T expected,
-                                                                       T actual) {
-        return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
-                msg, expected, actual), actual.compareTo(expected) >= 0);
-    }
-
-    /**
-     * Check that the {@code actual} value is less than the {@code expected} value.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected The expected value to check that the actual value is less than.
-     * @param actual Actual value to check.
-     * @return {@code true} if {@code actual} is less than {@code expected}.
-     */
-    public <T extends Comparable<? super T>> boolean expectLess(String msg, T expected,
-            T actual) {
-        return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
-                msg, expected, actual), actual.compareTo(expected) < 0);
-    }
-
-    /**
-     * Check that the {@code actual} value is less than or equal to the {@code expected} value.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected The expected value to check that the actual value is less than or equal to.
-     * @param actual Actual value to check.
-     * @return {@code true} if {@code actual} is less than or equal to {@code expected}.
-     */
-    public <T extends Comparable<? super T>> boolean expectLessOrEqual(String msg, T expected,
-            T actual) {
-        return expectTrue(String.format("%s: (expected = %s was not greater than actual = %s) ",
-                msg, expected, actual), actual.compareTo(expected) <= 0);
-    }
-
-    /**
-     * Check if the two float values are equal with given error tolerance.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected Expected value to be checked against.
-     * @param actual Actual value to be checked.
-     * @param tolerance The error margin for the equality check.
-     * @return {@code true} if the two values are equal, {@code false} otherwise.
-     */
-    public <T> boolean expectEquals(String msg, float expected, float actual, float tolerance) {
-        if (expected == actual) {
-            return true;
-        }
-
-        if (!(Math.abs(expected - actual) <= tolerance)) {
-            addMessage(String.format("%s (expected = %s, actual = %s, tolerance = %s) ", msg,
-                    expected, actual, tolerance));
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check if the two double values are equal with given error tolerance.
-     *
-     * @param msg Message to be logged when check fails.
-     * @param expected Expected value to be checked against.
-     * @param actual Actual value to be checked.
-     * @param tolerance The error margin for the equality check
-     * @return {@code true} if the two values are equal, {@code false} otherwise.
-     */
-    public <T> boolean expectEquals(String msg, double expected, double actual, double tolerance) {
-        if (expected == actual) {
-            return true;
-        }
-
-        if (!(Math.abs(expected - actual) <= tolerance)) {
-            addMessage(String.format("%s (expected = %s, actual = %s, tolerance = %s) ", msg,
-                    expected, actual, tolerance));
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Check that all values in the list are greater than or equal to the min value.
-     *
-     * @param msg Message to be logged when check fails
-     * @param list The list of values to be checked
-     * @param min The smallest allowed value
-     */
-    public <T extends Comparable<? super T>> void expectValuesGreaterOrEqual(String msg,
-            List<T> list, T min) {
-        for (T value : list) {
-            expectTrue(msg + String.format(", array value " + value.toString() +
-                                    " is less than %s",
-                            min.toString()), value.compareTo(min) >= 0);
-        }
-    }
-
-    /**
-     * Check that all values in the array are greater than or equal to the min value.
-     *
-     * @param msg Message to be logged when check fails
-     * @param array The array of values to be checked
-     * @param min The smallest allowed value
-     */
-    public <T extends Comparable<? super T>> void expectValuesGreaterOrEqual(String msg,
-                                                                             T[] array, T min) {
-        expectValuesGreaterOrEqual(msg, Arrays.asList(array), min);
-    }
-
-    /**
-     * Expect the list of values are in the range.
-     *
-     * @param msg Message to be logged
-     * @param list The list of values to be checked
-     * @param min The min value of the range
-     * @param max The max value of the range
-     */
-    public <T extends Comparable<? super T>> void expectValuesInRange(String msg, List<T> list,
-            T min, T max) {
-        for (T value : list) {
-            expectTrue(msg + String.format(", array value " + value.toString() +
-                    " is out of range [%s, %s]",
-                    min.toString(), max.toString()),
-                    value.compareTo(max)<= 0 && value.compareTo(min) >= 0);
-        }
-    }
-
-    /**
-     * Expect the array of values are in the range.
-     *
-     * @param msg Message to be logged
-     * @param array The array of values to be checked
-     * @param min The min value of the range
-     * @param max The max value of the range
-     */
-    public <T extends Comparable<? super T>> void expectValuesInRange(String msg, T[] array,
-            T min, T max) {
-        expectValuesInRange(msg, Arrays.asList(array), min, max);
-    }
-
-    /**
-     * Expect the array of values are in the range.
-     *
-     * @param msg Message to be logged
-     * @param array The array of values to be checked
-     * @param min The min value of the range
-     * @param max The max value of the range
-     */
-    public void expectValuesInRange(String msg, int[] array, int min, int max) {
-        ArrayList<Integer> l = new ArrayList<>(array.length);
-        for (int i : array) {
-            l.add(i);
-        }
-        expectValuesInRange(msg, l, min, max);
-    }
-
-    /**
-     * Expect the value is in the range.
-     *
-     * @param msg Message to be logged
-     * @param value The value to be checked
-     * @param min The min value of the range
-     * @param max The max value of the range
-     *
-     * @return {@code true} if the value was in range, {@code false} otherwise
-     */
-    public <T extends Comparable<? super T>> boolean expectInRange(String msg, T value,
-            T min, T max) {
-        return expectTrue(msg + String.format(", value " + value.toString()
-                + " is out of range [%s, %s]",
-                min.toString(), max.toString()),
-                value.compareTo(max)<= 0 && value.compareTo(min) >= 0);
-    }
-
-
-    /**
-     * Check that two metering region arrays are similar enough by ensuring that each of their width,
-     * height, and all corners are within {@code errorPercent} of each other.
-     *
-     * <p>Note that the length of the arrays must be the same, and each weight must be the same
-     * as well. We assume the order is also equivalent.</p>
-     *
-     * <p>At most 1 error per each dissimilar metering region is collected.</p>
-     *
-     * @param msg Message to be logged
-     * @param expected The reference 'expected' values to be used to check against
-     * @param actual The actual values that were received
-     * @param errorPercent Within how many percent the components should be
-     *
-     * @return {@code true} if all expects passed, {@code false} otherwise
-     */
-    public boolean expectMeteringRegionsAreSimilar(String msg,
-            MeteringRectangle[] expected, MeteringRectangle[] actual,
-            float errorPercent) {
-        String expectedActualMsg = String.format("expected (%s), actual (%s)",
-                Arrays.deepToString(expected), Arrays.deepToString(actual));
-
-        String differentSizesMsg = String.format(
-                "%s: rect lists are different sizes; %s",
-                msg, expectedActualMsg);
-
-        String differentWeightsMsg = String.format(
-                "%s: rect weights are different; %s",
-                msg, expectedActualMsg);
-
-        if (!expectTrue(differentSizesMsg, actual != null)) {
-            return false;
-        }
-
-        if (!expectEquals(differentSizesMsg, expected.length, actual.length)) return false;
-
-        boolean succ = true;
-        for (int i = 0; i < expected.length; ++i) {
-            if (i < actual.length) {
-                // Avoid printing multiple errors for the same rectangle
-                if (!expectRectsAreSimilar(
-                        msg, expected[i].getRect(), actual[i].getRect(), errorPercent)) {
-                    succ = false;
-                    continue;
-                }
-                if (!expectEquals(differentWeightsMsg,
-                        expected[i].getMeteringWeight(), actual[i].getMeteringWeight())) {
-                    succ = false;
-                    continue;
-                }
-            }
-        }
-
-        return succ;
-    }
-
-    /**
-     * Check that two rectangles are similar enough by ensuring that their width, height,
-     * and all corners are within {@code errorPercent} of each other.
-     *
-     * <p>Only the first error is collected, to avoid spamming several error messages when
-     * the rectangle is hugely dissimilar.</p>
-     *
-     * @param msg Message to be logged
-     * @param expected The reference 'expected' value to be used to check against
-     * @param actual The actual value that was received
-     * @param errorPercent Within how many percent the components should be
-     *
-     * @return {@code true} if all expects passed, {@code false} otherwise
-     */
-    public boolean expectRectsAreSimilar(String msg, Rect expected, Rect actual,
-            float errorPercent) {
-        String formattedMsg = String.format("%s: rects are not similar enough; expected (%s), " +
-                "actual (%s), error percent (%s), reason: ",
-                msg, expected, actual, errorPercent);
-
-        if (!expectSimilarValues(
-                formattedMsg, "too wide", "too narrow", actual.width(), expected.width(),
-                errorPercent)) return false;
-
-        if (!expectSimilarValues(
-                formattedMsg, "too tall", "too short", actual.height(), expected.height(),
-                errorPercent)) return false;
-
-        if (!expectSimilarValues(
-                formattedMsg, "left pt too right", "left pt too left", actual.left, expected.left,
-                errorPercent)) return false;
-
-        if (!expectSimilarValues(
-                formattedMsg, "right pt too right", "right pt too left",
-                actual.right, expected.right, errorPercent)) return false;
-
-        if (!expectSimilarValues(
-                formattedMsg, "top pt too low", "top pt too high", actual.top, expected.top,
-                errorPercent)) return false;
-
-        if (!expectSimilarValues(
-                formattedMsg, "bottom pt too low", "bottom pt too high", actual.top, expected.top,
-                errorPercent)) return false;
-
-        return true;
-    }
-
-    /**
-     * Check that two sizes are similar enough by ensuring that their width and height
-     * are within {@code errorPercent} of each other.
-     *
-     * <p>Only the first error is collected, to avoid spamming several error messages when
-     * the rectangle is hugely dissimilar.</p>
-     *
-     * @param msg Message to be logged
-     * @param expected The reference 'expected' value to be used to check against
-     * @param actual The actual value that was received
-     * @param errorPercent Within how many percent the components should be
-     *
-     * @return {@code true} if all expects passed, {@code false} otherwise
-     */
-    public boolean expectSizesAreSimilar(String msg, Size expected, Size actual,
-            float errorPercent) {
-        String formattedMsg = String.format("%s: rects are not similar enough; expected (%s), " +
-                "actual (%s), error percent (%s), reason: ",
-                msg, expected, actual, errorPercent);
-
-        if (!expectSimilarValues(
-                formattedMsg, "too wide", "too narrow", actual.getWidth(), expected.getWidth(),
-                errorPercent)) return false;
-
-        if (!expectSimilarValues(
-                formattedMsg, "too tall", "too short", actual.getHeight(), expected.getHeight(),
-                errorPercent)) return false;
-
-        return true;
-    }
-
-    /**
-     * Check that the rectangle is centered within a certain tolerance of {@code errorPercent},
-     * with respect to the {@code bounds} bounding rectangle.
-     *
-     * @param msg Message to be logged
-     * @param expectedBounds The width/height of the bounding rectangle
-     * @param actual The actual value that was received
-     * @param errorPercent Within how many percent the centering should be
-     */
-    public void expectRectCentered(String msg, Size expectedBounds, Rect actual,
-            float errorPercent) {
-        String formattedMsg = String.format("%s: rect should be centered; expected bounds (%s), " +
-                "actual (%s), error percent (%s), reason: ",
-                msg, expectedBounds, actual, errorPercent);
-
-        int centerBoundX = expectedBounds.getWidth() / 2;
-        int centerBoundY = expectedBounds.getHeight() / 2;
-
-        expectSimilarValues(
-                formattedMsg, "too low", "too high", actual.centerY(), centerBoundY,
-                errorPercent);
-
-        expectSimilarValues(
-                formattedMsg, "too right", "too left", actual.centerX(), centerBoundX,
-                errorPercent);
-    }
-
-    private boolean expectSimilarValues(
-            String formattedMsg, String tooSmall, String tooLarge, int actualValue,
-            int expectedValue, float errorPercent) {
-        boolean succ = true;
-        succ = expectTrue(formattedMsg + tooLarge,
-                actualValue <= (expectedValue * (1.0f + errorPercent))) && succ;
-        succ = expectTrue(formattedMsg + tooSmall,
-                actualValue >= (expectedValue * (1.0f - errorPercent))) && succ;
-
-        return succ;
-    }
-
-    public void expectNotNull(String msg, Object obj) {
-        checkThat(msg, obj, CoreMatchers.notNullValue());
-    }
-
-    public void expectNull(String msg, Object obj) {
-        if (obj != null) {
-            addMessage(msg);
-        }
-    }
-
-    /**
-     * Check if the values in the array are monotonically increasing (decreasing) and not all
-     * equal.
-     *
-     * @param array The array of values to be checked
-     * @param ascendingOrder The monotonicity ordering to be checked with
-     */
-    public <T extends Comparable<? super T>>  void checkArrayMonotonicityAndNotAllEqual(T[] array,
-            boolean ascendingOrder) {
-        String orderMsg = ascendingOrder ? ("increasing order") : ("decreasing order");
-        for (int i = 0; i < array.length - 1; i++) {
-            int compareResult = array[i + 1].compareTo(array[i]);
-            boolean condition = compareResult >= 0;
-            if (!ascendingOrder) {
-                condition = compareResult <= 0;
-            }
-
-            expectTrue(String.format("Adjacent values (%s and %s) %s monotonicity is broken",
-                    array[i].toString(), array[i + 1].toString(), orderMsg), condition);
-        }
-
-        expectTrue("All values of this array are equal: " + array[0].toString(),
-                array[0].compareTo(array[array.length - 1]) != 0);
-    }
-
-    /**
-     * Check if the key value is not null and return the value.
-     *
-     * @param characteristics The {@link CameraCharacteristics} to get the key from.
-     * @param key The {@link CameraCharacteristics} key to be checked.
-     *
-     * @return The value of the key.
-     */
-    public <T> T expectKeyValueNotNull(CameraCharacteristics characteristics,
-            CameraCharacteristics.Key<T> key) {
-
-        T value = characteristics.get(key);
-        if (value == null) {
-            addMessage("Key " + key.getName() + " shouldn't be null");
-        }
-
-        return value;
-    }
-
-    /**
-     * Check if the key value is not null and return the value.
-     *
-     * @param request The {@link CaptureRequest} to get the key from.
-     * @param key The {@link CaptureRequest} key to be checked.
-     *
-     * @return The value of the key.
-     */
-    public <T> T expectKeyValueNotNull(CaptureRequest request,
-                                       CaptureRequest.Key<T> key) {
-
-        T value = request.get(key);
-        if (value == null) {
-            addMessage("Key " + key.getName() + " shouldn't be null");
-        }
-
-        return value;
-    }
-
-    /**
-     * Check if the key value is not null and return the value.
-     *
-     * @param request The {@link CaptureRequest#Builder} to get the key from.
-     * @param key The {@link CaptureRequest} key to be checked.
-     * @return The value of the key.
-     */
-    public <T> T expectKeyValueNotNull(Builder request, CaptureRequest.Key<T> key) {
-
-        T value = request.get(key);
-        if (value == null) {
-            addMessage("Key " + key.getName() + " shouldn't be null");
-        }
-
-        return value;
-    }
-
-    /**
-     * Check if the key value is not null and return the value.
-     *
-     * @param result The {@link CaptureResult} to get the key from.
-     * @param key The {@link CaptureResult} key to be checked.
-     * @return The value of the key.
-     */
-    public <T> T expectKeyValueNotNull(CaptureResult result, CaptureResult.Key<T> key) {
-        return expectKeyValueNotNull("", result, key);
-    }
-
-    /**
-     * Check if the key value is not null and return the value.
-     *
-     * @param msg The message to be logged.
-     * @param result The {@link CaptureResult} to get the key from.
-     * @param key The {@link CaptureResult} key to be checked.
-     * @return The value of the key.
-     */
-    public <T> T expectKeyValueNotNull(String msg, CaptureResult result, CaptureResult.Key<T> key) {
-
-        T value = result.get(key);
-        if (value == null) {
-            addMessage(msg + " Key " + key.getName() + " shouldn't be null");
-        }
-
-        return value;
-    }
-
-    /**
-     * Check if the key is non-null and the value is not equal to target.
-     *
-     * @param request The The {@link CaptureRequest#Builder} to get the key from.
-     * @param key The {@link CaptureRequest} key to be checked.
-     * @param expected The expected value of the CaptureRequest key.
-     */
-    public <T> void expectKeyValueNotEquals(
-            Builder request, CaptureRequest.Key<T> key, T expected) {
-        if (request == null || key == null || expected == null) {
-            throw new IllegalArgumentException("request, key and expected shouldn't be null");
-        }
-
-        T value;
-        if ((value = expectKeyValueNotNull(request, key)) == null) {
-            return;
-        }
-
-        String reason = "Key " + key.getName() + " shouldn't have value " + value.toString();
-        checkThat(reason, value, CoreMatchers.not(expected));
-    }
-
-    /**
-     * Check if the key is non-null and the value is not equal to target.
-     *
-     * @param result The {@link CaptureResult} to get the key from.
-     * @param key The {@link CaptureResult} key to be checked.
-     * @param expected The expected value of the CaptureResult key.
-     */
-    public <T> void expectKeyValueNotEquals(
-            CaptureResult result, CaptureResult.Key<T> key, T expected) {
-        if (result == null || key == null || expected == null) {
-            throw new IllegalArgumentException("result, key and expected shouldn't be null");
-        }
-
-        T value;
-        if ((value = expectKeyValueNotNull(result, key)) == null) {
-            return;
-        }
-
-        String reason = "Key " + key.getName() + " shouldn't have value " + value.toString();
-        checkThat(reason, value, CoreMatchers.not(expected));
-    }
-
-    /**
-     * Check if the value is non-null and the value is equal to target.
-     *
-     * @param result The  {@link CaptureResult} to lookup the value in.
-     * @param key The {@link CaptureResult} key to be checked.
-     * @param expected The expected value of the {@link CaptureResult} key.
-     */
-    public <T> void expectKeyValueEquals(CaptureResult result, CaptureResult.Key<T> key,
-            T expected) {
-        if (result == null || key == null || expected == null) {
-            throw new IllegalArgumentException("request, key and expected shouldn't be null");
-        }
-
-        T value;
-        if ((value = expectKeyValueNotNull(result, key)) == null) {
-            return;
-        }
-
-        String reason = "Key " + key.getName() + " value " + value.toString()
-                + " doesn't match the expected value " + expected.toString();
-        checkThat(reason, value, CoreMatchers.equalTo(expected));
-    }
-
-    /**
-     * Check if the key is non-null and the value is equal to target.
-     *
-     * <p>Only check non-null if the target is null.</p>
-     *
-     * @param request The The {@link CaptureRequest#Builder} to get the key from.
-     * @param key The {@link CaptureRequest} key to be checked.
-     * @param expected The expected value of the CaptureRequest key.
-     */
-    public <T> void expectKeyValueEquals(Builder request, CaptureRequest.Key<T> key, T expected) {
-        if (request == null || key == null || expected == null) {
-            throw new IllegalArgumentException("request, key and expected shouldn't be null");
-        }
-
-        T value;
-        if ((value = expectKeyValueNotNull(request, key)) == null) {
-            return;
-        }
-
-        String reason = "Key " + key.getName() + " value " + value.toString()
-                + " doesn't match the expected value " + expected.toString();
-        checkThat(reason, value, CoreMatchers.equalTo(expected));
-    }
-
-    /**
-     * Check if the key is non-null, and the key value is greater than the expected value.
-     *
-     * @param result {@link CaptureResult} to check.
-     * @param key The {@link CaptureResult} key to be checked.
-     * @param expected The expected to be compared to the value for the given key.
-     */
-    public <T extends Comparable<? super T>> void expectKeyValueGreaterOrEqual(
-            CaptureResult result, CaptureResult.Key<T> key, T expected) {
-        T value;
-        if ((value = expectKeyValueNotNull(result, key)) == null) {
-            return;
-        }
-
-        expectGreaterOrEqual(key.getName(), expected, value);
-    }
-
-    /**
-     * Check if the key is non-null, and the key value is greater than the expected value.
-     *
-     * @param characteristics {@link CameraCharacteristics} to check.
-     * @param key The {@link CameraCharacteristics} key to be checked.
-     * @param expected The expected to be compared to the value for the given key.
-     */
-    public <T extends Comparable<? super T>> void expectKeyValueGreaterThan(
-            CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T expected) {
-        T value;
-        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
-            return;
-        }
-
-        expectGreater(key.getName(), expected, value);
-    }
-
-    /**
-     * Check if the key is non-null, and the key value is in the expected range.
-     *
-     * @param characteristics {@link CameraCharacteristics} to check.
-     * @param key The {@link CameraCharacteristics} key to be checked.
-     * @param min The min value of the range
-     * @param max The max value of the range
-     */
-    public <T extends Comparable<? super T>> void expectKeyValueInRange(
-            CameraCharacteristics characteristics, CameraCharacteristics.Key<T> key, T min, T max) {
-        T value;
-        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
-            return;
-        }
-        expectInRange(key.getName(), value, min, max);
-    }
-
-    /**
-     * Check if the key is non-null, and the key value is one of the expected values.
-     *
-     * @param characteristics {@link CameraCharacteristics} to check.
-     * @param key The {@link CameraCharacteristics} key to be checked.
-     * @param expected The expected values for the given key.
-     */
-    public <T> void expectKeyValueIsIn(CameraCharacteristics characteristics,
-                                       CameraCharacteristics.Key<T> key, T... expected) {
-        T value = expectKeyValueNotNull(characteristics, key);
-        if (value == null) {
-            return;
-        }
-        String reason = "Key " + key.getName() + " value " + value
-                + " isn't one of the expected values " + Arrays.deepToString(expected);
-        expectContains(reason, expected, value);
-    }
-
-    /**
-     * Check if the key is non-null, and the key value is one of the expected values.
-     *
-     * @param request The The {@link CaptureRequest#Builder} to get the key from.
-     * @param key The {@link CaptureRequest} key to be checked.
-     * @param expected The expected values of the CaptureRequest key.
-     */
-    public <T> void expectKeyValueIsIn(Builder request, CaptureRequest.Key<T> key, T... expected) {
-        T value = expectKeyValueNotNull(request, key);
-        if (value == null) {
-            return;
-        }
-        String reason = "Key " + key.getName() + " value " + value
-                + " isn't one of the expected values " + Arrays.deepToString(expected);
-        expectContains(reason, expected, value);
-    }
-
-    /**
-     * Check if the key is non-null, and the key value contains the expected element.
-     *
-     * @param characteristics {@link CameraCharacteristics} to check.
-     * @param key The {@link CameraCharacteristics} key to be checked.
-     * @param expected The expected element to be contained in the value for the given key.
-     */
-    public <T> void expectKeyValueContains(CameraCharacteristics characteristics,
-                                           CameraCharacteristics.Key<T[]> key, T expected) {
-        T[] value;
-        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
-            return;
-        }
-        String reason = "Key " + key.getName() + " value " + value
-                + " doesn't contain the expected value " + expected;
-        expectContains(reason, value, expected);
-    }
-
-    /**
-     * Check if the key is non-null, and the key value contains the expected element.
-     *
-     * @param characteristics {@link CameraCharacteristics} to check.
-     * @param key The {@link CameraCharacteristics} key to be checked.
-     * @param expected The expected element to be contained in the value for the given key.
-     */
-    public void expectKeyValueContains(CameraCharacteristics characteristics,
-                                           CameraCharacteristics.Key<int[]> key, int expected) {
-        int[] value;
-        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
-            return;
-        }
-        String reason = "Key " + key.getName() + " value " + value
-                + " doesn't contain the expected value " + expected;
-        expectContains(reason, value, expected);
-    }
-
-    /**
-     * Check if the key is non-null, and the key value contains the expected element.
-     *
-     * @param characteristics {@link CameraCharacteristics} to check.
-     * @param key The {@link CameraCharacteristics} key to be checked.
-     * @param expected The expected element to be contained in the value for the given key.
-     */
-    public void expectKeyValueContains(CameraCharacteristics characteristics,
-                                       CameraCharacteristics.Key<boolean[]> key, boolean expected) {
-        boolean[] value;
-        if ((value = expectKeyValueNotNull(characteristics, key)) == null) {
-            return;
-        }
-        String reason = "Key " + key.getName() + " value " + value
-                + " doesn't contain the expected value " + expected;
-        expectContains(reason, value, expected);
-    }
-
-    /**
-     * Check if the {@code values} array contains the expected element.
-     *
-     * @param reason reason to print for failure.
-     * @param values array to check for membership in.
-     * @param expected the value to check.
-     */
-    public <T> void expectContains(String reason, T[] values, T expected) {
-        if (values == null) {
-            throw new NullPointerException();
-        }
-        checkThat(reason, expected, InMatcher.in(values));
-    }
-
-    public <T> void expectContains(T[] values, T expected) {
-        String reason = "Expected value " + expected
-                + " is not contained in the given values " + values;
-        expectContains(reason, values, expected);
-    }
-
-    /**
-     * Specialize {@link InMatcher} class for integer primitive array.
-     */
-    private static class IntInMatcher extends InMatcher<Integer> {
-        public IntInMatcher(int[] values) {
-            Preconditions.checkNotNull("values", values);
-            mValues = new ArrayList<>(values.length);
-            for (int i : values) {
-                mValues.add(i);
-            }
-        }
-    }
-
-    /**
-     * Check if the {@code values} array contains the expected element.
-     *
-     * <p>Specialized for primitive int arrays</p>
-     *
-     * @param reason reason to print for failure.
-     * @param values array to check for membership in.
-     * @param expected the value to check.
-     */
-    public void expectContains(String reason, int[] values, int expected) {
-        if (values == null) {
-            throw new NullPointerException();
-        }
-
-        checkThat(reason, expected, new IntInMatcher(values));
-    }
-
-    public void expectContains(int[] values, int expected) {
-        String reason = "Expected value " + expected
-                + " is not contained in the given values " + values;
-        expectContains(reason, values, expected);
-    }
-
-    /**
-     * Specialize {@link BooleanInMatcher} class for boolean primitive array.
-     */
-    private static class BooleanInMatcher extends InMatcher<Boolean> {
-        public BooleanInMatcher(boolean[] values) {
-            Preconditions.checkNotNull("values", values);
-            mValues = new ArrayList<>(values.length);
-            for (boolean i : values) {
-                mValues.add(i);
-            }
-        }
-    }
-
-    /**
-     * Check if the {@code values} array contains the expected element.
-     *
-     * <p>Specialized for primitive boolean arrays</p>
-     *
-     * @param reason reason to print for failure.
-     * @param values array to check for membership in.
-     * @param expected the value to check.
-     */
-    public void expectContains(String reason, boolean[] values, boolean expected) {
-        if (values == null) {
-            throw new NullPointerException();
-        }
-
-        checkThat(reason, expected, new BooleanInMatcher(values));
-    }
-
-    /**
-     * Check if the {@code values} array contains the expected element.
-     *
-     * <p>Specialized for primitive boolean arrays</p>
-     *
-     * @param values array to check for membership in.
-     * @param expected the value to check.
-     */
-    public void expectContains(boolean[] values, boolean expected) {
-        String reason = "Expected value " + expected
-                + " is not contained in the given values " + values;
-        expectContains(reason, values, expected);
-    }
-
-    /**
-     * Check if the element inside of the list are unique.
-     *
-     * @param msg The message to be logged
-     * @param list The list of values to be checked
-     */
-    public <T> void expectValuesUnique(String msg, List<T> list) {
-        Set<T> sizeSet = new HashSet<T>(list);
-        expectTrue(msg + " each element must be distinct", sizeSet.size() == list.size());
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java b/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
deleted file mode 100644
index 2a654db3..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/helpers/StaticMetadata.java
+++ /dev/null
@@ -1,1948 +0,0 @@
-/*
- * Copyright 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.hardware.camera2.cts.helpers;
-
-import android.graphics.Rect;
-import android.graphics.ImageFormat;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraCharacteristics.Key;
-import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.cts.CameraTestUtils;
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.util.Range;
-import android.util.Size;
-import android.util.Log;
-import android.util.Rational;
-
-import junit.framework.Assert;
-
-import java.lang.reflect.Array;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Helpers to get common static info out of the camera.
- *
- * <p>Avoid boiler plate by putting repetitive get/set patterns in this class.</p>
- *
- * <p>Attempt to be durable against the camera device having bad or missing metadata
- * by providing reasonable defaults and logging warnings when that happens.</p>
- */
-public class StaticMetadata {
-
-    private static final String TAG = "StaticMetadata";
-    private static final int IGNORE_SIZE_CHECK = -1;
-
-    private static final long SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST = 100000L; // 100us
-    private static final long SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST = 100000000; // 100ms
-    private static final int SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST = 100;
-    private static final int SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST = 800;
-    private static final int STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST = 4;
-    private static final int TONEMAP_MAX_CURVE_POINTS_AT_LEAST = 64;
-    private static final int CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MIN = -2;
-    private static final int CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MAX = 2;
-    private static final Rational CONTROL_AE_COMPENSATION_STEP_DEFAULT = new Rational(1, 2);
-    private static final byte REQUEST_PIPELINE_MAX_DEPTH_MAX = 8;
-
-    // TODO: Consider making this work across any metadata object, not just camera characteristics
-    private final CameraCharacteristics mCharacteristics;
-    private final CheckLevel mLevel;
-    private final CameraErrorCollector mCollector;
-
-    public enum CheckLevel {
-        /** Only log warnings for metadata check failures. Execution continues. */
-        WARN,
-        /**
-         * Use ErrorCollector to collect the metadata check failures, Execution
-         * continues.
-         */
-        COLLECT,
-        /** Assert the metadata check failures. Execution aborts. */
-        ASSERT
-    }
-
-    /**
-     * Construct a new StaticMetadata object.
-     *
-     *<p> Default constructor, only log warnings for the static metadata check failures</p>
-     *
-     * @param characteristics static info for a camera
-     * @throws IllegalArgumentException if characteristics was null
-     */
-    public StaticMetadata(CameraCharacteristics characteristics) {
-        this(characteristics, CheckLevel.WARN, /*collector*/null);
-    }
-
-    /**
-     * Construct a new StaticMetadata object with {@link CameraErrorCollector}.
-     * <p>
-     * When level is not {@link CheckLevel.COLLECT}, the {@link CameraErrorCollector} will be
-     * ignored, otherwise, it will be used to log the check failures.
-     * </p>
-     *
-     * @param characteristics static info for a camera
-     * @param collector The {@link CameraErrorCollector} used by this StaticMetadata
-     * @throws IllegalArgumentException if characteristics or collector was null.
-     */
-    public StaticMetadata(CameraCharacteristics characteristics, CameraErrorCollector collector) {
-        this(characteristics, CheckLevel.COLLECT, collector);
-    }
-
-    /**
-     * Construct a new StaticMetadata object with {@link CheckLevel} and
-     * {@link CameraErrorCollector}.
-     * <p>
-     * When level is not {@link CheckLevel.COLLECT}, the {@link CameraErrorCollector} will be
-     * ignored, otherwise, it will be used to log the check failures.
-     * </p>
-     *
-     * @param characteristics static info for a camera
-     * @param level The {@link CheckLevel} of this StaticMetadata
-     * @param collector The {@link CameraErrorCollector} used by this StaticMetadata
-     * @throws IllegalArgumentException if characteristics was null or level was
-     *         {@link CheckLevel.COLLECT} but collector was null.
-     */
-    public StaticMetadata(CameraCharacteristics characteristics, CheckLevel level,
-            CameraErrorCollector collector) {
-        if (characteristics == null) {
-            throw new IllegalArgumentException("characteristics was null");
-        }
-        if (level == CheckLevel.COLLECT && collector == null) {
-            throw new IllegalArgumentException("collector must valid when COLLECT level is set");
-        }
-
-        mCharacteristics = characteristics;
-        mLevel = level;
-        mCollector = collector;
-    }
-
-    /**
-     * Get the CameraCharacteristics associated with this StaticMetadata.
-     *
-     * @return A non-null CameraCharacteristics object
-     */
-    public CameraCharacteristics getCharacteristics() {
-        return mCharacteristics;
-    }
-
-    /**
-     * Whether or not the hardware level reported by android.info.supportedHardwareLevel
-     * is {@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;
-    }
-
-    /**
-     * Whether or not the hardware level reported by android.info.supportedHardwareLevel
-     * Return the supported hardware level of the device, or fail if no value is reported.
-     *
-     * @return the supported hardware level as a constant defined for
-     *      {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}.
-     */
-    public int getHardwareLevelChecked() {
-        Integer hwLevel = getValueFromKeyNonNull(
-                CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
-        if (hwLevel == null) {
-            Assert.fail("No supported hardware level reported.");
-        }
-        return hwLevel;
-    }
-
-    /**
-     * Whether or not the hardware level reported by android.info.supportedHardwareLevel
-     * is {@value CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}.
-     *
-     * <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 LEGACY}, {@code false} otherwise.
-     */
-    public boolean isHardwareLevelLegacy() {
-        return getHardwareLevelChecked() == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
-    }
-
-    /**
-     * Whether or not the per frame control is supported by the camera device.
-     *
-     * @return {@code true} if per frame control is supported, {@code false} otherwise.
-     */
-    public boolean isPerFrameControlSupported() {
-        return getSyncMaxLatency() == CameraMetadata.SYNC_MAX_LATENCY_PER_FRAME_CONTROL;
-    }
-
-    /**
-     * Get the maximum number of frames to wait for a request settings being applied
-     *
-     * @return CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN for unknown latency
-     *         CameraMetadata.SYNC_MAX_LATENCY_PER_FRAME_CONTROL for per frame control
-     *         a positive int otherwise
-     */
-    public int getSyncMaxLatency() {
-        Integer value = getValueFromKeyNonNull(CameraCharacteristics.SYNC_MAX_LATENCY);
-        if (value == null) {
-            return CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN;
-        }
-        return value;
-    }
-
-    /**
-     * Whether or not the hardware level reported by android.info.supportedHardwareLevel
-     * is {@value CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED}.
-     *
-     * <p>If the camera device is incorrectly reporting the hardwareLevel, this
-     * will always return {@code true}.</p>
-     *
-     * @return {@code true} if the device is {@code LIMITED}, {@code false} otherwise.
-     */
-    public boolean isHardwareLevelLimited() {
-        return getHardwareLevelChecked() == CameraMetadata.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED;
-    }
-
-    /**
-     * Whether or not the hardware level reported by {@code android.info.supportedHardwareLevel}
-     * is at least {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED}.
-     *
-     * <p>If the camera device is incorrectly reporting the hardwareLevel, this
-     * will always return {@code false}.</p>
-     *
-     * @return
-     *          {@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;
-    }
-
-    /**
-     * Get the maximum number of partial result a request can expect
-     *
-     * @return 1 if partial result is not supported.
-     *         a integer value larger than 1 if partial result is supported.
-     */
-    public int getPartialResultCount() {
-        Integer value = mCharacteristics.get(CameraCharacteristics.REQUEST_PARTIAL_RESULT_COUNT);
-        if (value == null) {
-            // Optional key. Default value is 1 if key is missing.
-            return 1;
-        }
-        return value;
-    }
-
-    /**
-     * Get the exposure time value and clamp to the range if needed.
-     *
-     * @param exposure Input exposure time value to check.
-     * @return Exposure value in the legal range.
-     */
-    public long getExposureClampToRange(long exposure) {
-        long minExposure = getExposureMinimumOrDefault(Long.MAX_VALUE);
-        long maxExposure = getExposureMaximumOrDefault(Long.MIN_VALUE);
-        if (minExposure > SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST) {
-            failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE,
-                    String.format(
-                    "Min value %d is too large, set to maximal legal value %d",
-                    minExposure, SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST));
-            minExposure = SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST;
-        }
-        if (maxExposure < SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST) {
-            failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE,
-                    String.format(
-                    "Max value %d is too small, set to minimal legal value %d",
-                    maxExposure, SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST));
-            maxExposure = SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST;
-        }
-
-        return Math.max(minExposure, Math.min(maxExposure, exposure));
-    }
-
-    /**
-     * Check if the camera device support focuser.
-     *
-     * @return true if camera device support focuser, false otherwise.
-     */
-    public boolean hasFocuser() {
-        if (areKeysAvailable(CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE)) {
-            // LEGACY devices don't have lens.info.minimumFocusDistance, so guard this query
-            return (getMinimumFocusDistanceChecked() > 0);
-        } else {
-            // Check available AF modes
-            int[] availableAfModes = mCharacteristics.get(
-                    CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES);
-
-            if (availableAfModes == null) {
-                return false;
-            }
-
-            // Assume that if we have an AF mode which doesn't ignore AF trigger, we have a focuser
-            boolean hasFocuser = false;
-            loop: for (int mode : availableAfModes) {
-                switch (mode) {
-                    case CameraMetadata.CONTROL_AF_MODE_AUTO:
-                    case CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_PICTURE:
-                    case CameraMetadata.CONTROL_AF_MODE_CONTINUOUS_VIDEO:
-                    case CameraMetadata.CONTROL_AF_MODE_MACRO:
-                        hasFocuser = true;
-                        break loop;
-                }
-            }
-
-            return hasFocuser;
-        }
-    }
-
-    /**
-     * Check if the camera device has flash unit.
-     * @return true if flash unit is available, false otherwise.
-     */
-    public boolean hasFlash() {
-        return getFlashInfoChecked();
-    }
-
-    /**
-     * Get minimum focus distance.
-     *
-     * @return minimum focus distance, 0 if minimum focus distance is invalid.
-     */
-    public float getMinimumFocusDistanceChecked() {
-        Key<Float> key = CameraCharacteristics.LENS_INFO_MINIMUM_FOCUS_DISTANCE;
-        Float minFocusDistance;
-
-        /**
-         * android.lens.info.minimumFocusDistance - required for FULL and MANUAL_SENSOR-capable
-         *   devices; optional for all other devices.
-         */
-        if (isHardwareLevelFull() || isCapabilitySupported(
-                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-            minFocusDistance = getValueFromKeyNonNull(key);
-        } else {
-            minFocusDistance = mCharacteristics.get(key);
-        }
-
-        if (minFocusDistance == null) {
-            return 0.0f;
-        }
-
-        checkTrueForKey(key, " minFocusDistance value shouldn't be negative",
-                minFocusDistance >= 0);
-        if (minFocusDistance < 0) {
-            minFocusDistance = 0.0f;
-        }
-
-        return minFocusDistance;
-    }
-
-    /**
-     * Get focusDistanceCalibration.
-     *
-     * @return focusDistanceCalibration, UNCALIBRATED if value is invalid.
-     */
-    public int getFocusDistanceCalibrationChecked() {
-        Key<Integer> key = CameraCharacteristics.LENS_INFO_FOCUS_DISTANCE_CALIBRATION;
-        Integer calibration = getValueFromKeyNonNull(key);
-
-        if (calibration == null) {
-            return CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED;
-        }
-
-        checkTrueForKey(key, " value is out of range" ,
-                calibration >= CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED &&
-                calibration <= CameraMetadata.LENS_INFO_FOCUS_DISTANCE_CALIBRATION_CALIBRATED);
-
-        return calibration;
-    }
-
-    /**
-     * Get max AE regions and do sanity check.
-     *
-     * @return AE max regions supported by the camera device
-     */
-    public int getAeMaxRegionsChecked() {
-        Integer regionCount = getValueFromKeyNonNull(CameraCharacteristics.CONTROL_MAX_REGIONS_AE);
-        if (regionCount == null) {
-            return 0;
-        }
-        return regionCount;
-    }
-
-    /**
-     * Get max AWB regions and do sanity check.
-     *
-     * @return AWB max regions supported by the camera device
-     */
-    public int getAwbMaxRegionsChecked() {
-        Integer regionCount = getValueFromKeyNonNull(CameraCharacteristics.CONTROL_MAX_REGIONS_AWB);
-        if (regionCount == null) {
-            return 0;
-        }
-        return regionCount;
-    }
-
-    /**
-     * Get max AF regions and do sanity check.
-     *
-     * @return AF max regions supported by the camera device
-     */
-    public int getAfMaxRegionsChecked() {
-        Integer regionCount = getValueFromKeyNonNull(CameraCharacteristics.CONTROL_MAX_REGIONS_AF);
-        if (regionCount == null) {
-            return 0;
-        }
-        return regionCount;
-    }
-    /**
-     * Get the available anti-banding modes.
-     *
-     * @return The array contains available anti-banding modes.
-     */
-    public int[] getAeAvailableAntiBandingModesChecked() {
-        Key<int[]> key = CameraCharacteristics.CONTROL_AE_AVAILABLE_ANTIBANDING_MODES;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        boolean foundAuto = false;
-        boolean found50Hz = false;
-        boolean found60Hz = false;
-        for (int mode : modes) {
-            checkTrueForKey(key, "mode value " + mode + " is out if range",
-                    mode >= CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_OFF ||
-                    mode <= CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO);
-            if (mode == CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_AUTO) {
-                foundAuto = true;
-            } else if (mode == CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_50HZ) {
-                found50Hz = true;
-            } else if (mode == CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_60HZ) {
-                found60Hz = true;
-            }
-        }
-        // Must contain AUTO mode or one of 50/60Hz mode.
-        checkTrueForKey(key, "Either AUTO mode or both 50HZ/60HZ mode should present",
-                foundAuto || (found50Hz && found60Hz));
-
-        return modes;
-    }
-
-    /**
-     * Check if the antibanding OFF mode is supported.
-     *
-     * @return true if antibanding OFF mode is supported, false otherwise.
-     */
-    public boolean isAntiBandingOffModeSupported() {
-        List<Integer> antiBandingModes =
-                Arrays.asList(CameraTestUtils.toObject(getAeAvailableAntiBandingModesChecked()));
-
-        return antiBandingModes.contains(CameraMetadata.CONTROL_AE_ANTIBANDING_MODE_OFF);
-    }
-
-    public Boolean getFlashInfoChecked() {
-        Key<Boolean> key = CameraCharacteristics.FLASH_INFO_AVAILABLE;
-        Boolean hasFlash = getValueFromKeyNonNull(key);
-
-        // In case the failOnKey only gives warning.
-        if (hasFlash == null) {
-            return false;
-        }
-
-        return hasFlash;
-    }
-
-    public int[] getAvailableTestPatternModesChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.SENSOR_AVAILABLE_TEST_PATTERN_MODES;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        if (modes == null) {
-            return new int[0];
-        }
-
-        int expectValue = CameraCharacteristics.SENSOR_TEST_PATTERN_MODE_OFF;
-        Integer[] boxedModes = CameraTestUtils.toObject(modes);
-        checkTrueForKey(key, " value must contain OFF mode",
-                Arrays.asList(boxedModes).contains(expectValue));
-
-        return modes;
-    }
-
-    /**
-     * Get available thumbnail sizes and do the sanity check.
-     *
-     * @return The array of available thumbnail sizes
-     */
-    public Size[] getAvailableThumbnailSizesChecked() {
-        Key<Size[]> key = CameraCharacteristics.JPEG_AVAILABLE_THUMBNAIL_SIZES;
-        Size[] sizes = getValueFromKeyNonNull(key);
-        final List<Size> sizeList = Arrays.asList(sizes);
-
-        // Size must contain (0, 0).
-        checkTrueForKey(key, "size should contain (0, 0)", sizeList.contains(new Size(0, 0)));
-
-        // Each size must be distinct.
-        checkElementDistinct(key, sizeList);
-
-        // Must be sorted in ascending order by area, by width if areas are same.
-        List<Size> orderedSizes =
-                CameraTestUtils.getAscendingOrderSizes(sizeList, /*ascending*/true);
-        checkTrueForKey(key, "Sizes should be in ascending order: Original " + sizeList.toString()
-                + ", Expected " + orderedSizes.toString(), orderedSizes.equals(sizeList));
-
-        // TODO: Aspect ratio match, need wait for android.scaler.availableStreamConfigurations
-        // implementation see b/12958122.
-
-        return sizes;
-    }
-
-    /**
-     * Get available focal lengths and do the sanity check.
-     *
-     * @return The array of available focal lengths
-     */
-    public float[] getAvailableFocalLengthsChecked() {
-        Key<float[]> key = CameraCharacteristics.LENS_INFO_AVAILABLE_FOCAL_LENGTHS;
-        float[] focalLengths = getValueFromKeyNonNull(key);
-
-        checkTrueForKey(key, "Array should contain at least one element", focalLengths.length >= 1);
-
-        for (int i = 0; i < focalLengths.length; i++) {
-            checkTrueForKey(key,
-                    String.format("focalLength[%d] %f should be positive.", i, focalLengths[i]),
-                    focalLengths[i] > 0);
-        }
-        checkElementDistinct(key, Arrays.asList(CameraTestUtils.toObject(focalLengths)));
-
-        return focalLengths;
-    }
-
-    /**
-     * Get available apertures and do the sanity check.
-     *
-     * @return The non-null array of available apertures
-     */
-    public float[] getAvailableAperturesChecked() {
-        Key<float[]> key = CameraCharacteristics.LENS_INFO_AVAILABLE_APERTURES;
-        float[] apertures = getValueFromKeyNonNull(key);
-
-        checkTrueForKey(key, "Array should contain at least one element", apertures.length >= 1);
-
-        for (int i = 0; i < apertures.length; i++) {
-            checkTrueForKey(key,
-                    String.format("apertures[%d] %f should be positive.", i, apertures[i]),
-                    apertures[i] > 0);
-        }
-        checkElementDistinct(key, Arrays.asList(CameraTestUtils.toObject(apertures)));
-
-        return apertures;
-    }
-
-    /**
-     * Get and check the available hot pixel map modes.
-     *
-     * @return the available hot pixel map modes
-     */
-    public int[] getAvailableHotPixelModesChecked() {
-        Key<int[]> key = CameraCharacteristics.HOT_PIXEL_AVAILABLE_HOT_PIXEL_MODES;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        if (modes == null) {
-            return new int[0];
-        }
-
-        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
-        if (isHardwareLevelFull()) {
-            checkTrueForKey(key, "Full-capability camera devices must support FAST mode",
-                    modeList.contains(CameraMetadata.HOT_PIXEL_MODE_FAST));
-        }
-        checkElementDistinct(key, modeList);
-        checkArrayValuesInRange(key, modes, CameraMetadata.HOT_PIXEL_MODE_OFF,
-                CameraMetadata.HOT_PIXEL_MODE_HIGH_QUALITY);
-
-        return modes;
-    }
-
-    /**
-     * Get and check available face detection modes.
-     *
-     * @return The non-null array of available face detection modes
-     */
-    public int[] getAvailableFaceDetectModesChecked() {
-        Key<int[]> key = CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        if (modes == null) {
-            return new int[0];
-        }
-
-        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
-        checkTrueForKey(key, "Array should contain OFF mode",
-                modeList.contains(CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF));
-        checkElementDistinct(key, modeList);
-        checkArrayValuesInRange(key, modes, CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF,
-                CameraMetadata.STATISTICS_FACE_DETECT_MODE_FULL);
-
-        return modes;
-    }
-
-    /**
-     * Get and check max face detected count.
-     *
-     * @return max number of faces that can be detected
-     */
-    public int getMaxFaceCountChecked() {
-        Key<Integer> key = CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT;
-        Integer count = getValueFromKeyNonNull(key);
-
-        if (count == null) {
-            return 0;
-        }
-
-        List<Integer> faceDetectModes =
-                Arrays.asList(CameraTestUtils.toObject(getAvailableFaceDetectModesChecked()));
-        if (faceDetectModes.contains(CameraMetadata.STATISTICS_FACE_DETECT_MODE_OFF) &&
-                faceDetectModes.size() == 1) {
-            checkTrueForKey(key, " value must be 0 if only OFF mode is supported in "
-                    + "availableFaceDetectionModes", count == 0);
-        } else {
-            int maxFaceCountAtLeast = STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST;
-
-            // Legacy mode may support fewer than STATISTICS_INFO_MAX_FACE_COUNT_MIN_AT_LEAST faces.
-            if (isHardwareLevelLegacy()) {
-                maxFaceCountAtLeast = 1;
-            }
-            checkTrueForKey(key, " value must be no less than " + maxFaceCountAtLeast + " if SIMPLE"
-                    + "or FULL is also supported in availableFaceDetectionModes",
-                    count >= maxFaceCountAtLeast);
-        }
-
-        return count;
-    }
-
-    /**
-     * Get and check the available tone map modes.
-     *
-     * @return the available tone map modes
-     */
-    public int[] getAvailableToneMapModesChecked() {
-        Key<int[]> key = CameraCharacteristics.TONEMAP_AVAILABLE_TONE_MAP_MODES;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        if (modes == null) {
-            return new int[0];
-        }
-
-        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
-        checkTrueForKey(key, " Camera devices must always support FAST mode",
-                modeList.contains(CameraMetadata.TONEMAP_MODE_FAST));
-        if (isCapabilitySupported(
-                CameraMetadata.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING)) {
-            checkTrueForKey(key, "MANUAL_POST_PROCESSING supported camera devices must support"
-                    + "CONTRAST_CURVE mode",
-                    modeList.contains(CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE) &&
-                    modeList.contains(CameraMetadata.TONEMAP_MODE_FAST));
-        }
-        checkElementDistinct(key, modeList);
-        checkArrayValuesInRange(key, modes, CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE,
-                CameraMetadata.TONEMAP_MODE_HIGH_QUALITY);
-
-        return modes;
-    }
-
-    /**
-     * Get and check max tonemap curve point.
-     *
-     * @return Max tonemap curve points.
-     */
-    public int getMaxTonemapCurvePointChecked() {
-        Key<Integer> key = CameraCharacteristics.TONEMAP_MAX_CURVE_POINTS;
-        Integer count = getValueFromKeyNonNull(key);
-
-        if (count == null) {
-            return 0;
-        }
-
-        List<Integer> modeList =
-                Arrays.asList(CameraTestUtils.toObject(getAvailableToneMapModesChecked()));
-        if (modeList.contains(CameraMetadata.TONEMAP_MODE_CONTRAST_CURVE)) {
-            checkTrueForKey(key, "Full-capability camera device must support maxCurvePoints "
-                    + ">= " + TONEMAP_MAX_CURVE_POINTS_AT_LEAST,
-                    count >= TONEMAP_MAX_CURVE_POINTS_AT_LEAST);
-        }
-
-        return count;
-    }
-
-    /**
-     * Get and check pixel array size.
-     */
-    public Size getPixelArraySizeChecked() {
-        Key<Size> key = CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE;
-        Size pixelArray = getValueFromKeyNonNull(key);
-        if (pixelArray == null) {
-            return new Size(0, 0);
-        }
-
-        return pixelArray;
-    }
-
-    /**
-     * Get and check active array size.
-     */
-    public Rect getActiveArraySizeChecked() {
-        Key<Rect> key = CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE;
-        Rect activeArray = getValueFromKeyNonNull(key);
-
-        if (activeArray == null) {
-            return new Rect(0, 0, 0, 0);
-        }
-
-        Size pixelArraySize = getPixelArraySizeChecked();
-        checkTrueForKey(key, "values left/top are invalid", activeArray.left >= 0 && activeArray.top >= 0);
-        checkTrueForKey(key, "values width/height are invalid",
-                activeArray.width() <= pixelArraySize.getWidth() &&
-                activeArray.height() <= pixelArraySize.getHeight());
-
-        return activeArray;
-    }
-
-    /**
-     * Get the sensitivity value and clamp to the range if needed.
-     *
-     * @param sensitivity Input sensitivity value to check.
-     * @return Sensitivity value in legal range.
-     */
-    public int getSensitivityClampToRange(int sensitivity) {
-        int minSensitivity = getSensitivityMinimumOrDefault(Integer.MAX_VALUE);
-        int maxSensitivity = getSensitivityMaximumOrDefault(Integer.MIN_VALUE);
-        if (minSensitivity > SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST) {
-            failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE,
-                    String.format(
-                    "Min value %d is too large, set to maximal legal value %d",
-                    minSensitivity, SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST));
-            minSensitivity = SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST;
-        }
-        if (maxSensitivity < SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST) {
-            failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE,
-                    String.format(
-                    "Max value %d is too small, set to minimal legal value %d",
-                    maxSensitivity, SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST));
-            maxSensitivity = SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST;
-        }
-
-        return Math.max(minSensitivity, Math.min(maxSensitivity, sensitivity));
-    }
-
-    /**
-     * Get maxAnalogSensitivity for a camera device.
-     * <p>
-     * This is only available for FULL capability device, return 0 if it is unavailable.
-     * </p>
-     *
-     * @return maxAnalogSensitivity, 0 if it is not available.
-     */
-    public int getMaxAnalogSensitivityChecked() {
-
-        Key<Integer> key = CameraCharacteristics.SENSOR_MAX_ANALOG_SENSITIVITY;
-        Integer maxAnalogsensitivity = mCharacteristics.get(key);
-        if (maxAnalogsensitivity == null) {
-            if (isHardwareLevelFull()) {
-                Assert.fail("Full device should report max analog sensitivity");
-            }
-            return 0;
-        }
-
-        int minSensitivity = getSensitivityMinimumOrDefault();
-        int maxSensitivity = getSensitivityMaximumOrDefault();
-        checkTrueForKey(key, " Max analog sensitivity " + maxAnalogsensitivity
-                + " should be no larger than max sensitivity " + maxSensitivity,
-                maxAnalogsensitivity <= maxSensitivity);
-        checkTrueForKey(key, " Max analog sensitivity " + maxAnalogsensitivity
-                + " should be larger than min sensitivity " + maxSensitivity,
-                maxAnalogsensitivity > minSensitivity);
-
-        return maxAnalogsensitivity;
-    }
-
-    /**
-     * Get hyperfocalDistance and do the sanity check.
-     * <p>
-     * Note that, this tag is optional, will return -1 if this tag is not
-     * available.
-     * </p>
-     *
-     * @return hyperfocalDistance of this device, -1 if this tag is not available.
-     */
-    public float getHyperfocalDistanceChecked() {
-        Key<Float> key = CameraCharacteristics.LENS_INFO_HYPERFOCAL_DISTANCE;
-        Float hyperfocalDistance = getValueFromKeyNonNull(key);
-        if (hyperfocalDistance == null) {
-            return -1;
-        }
-
-        if (hasFocuser()) {
-            float minFocusDistance = getMinimumFocusDistanceChecked();
-            checkTrueForKey(key, String.format(" hyperfocal distance %f should be in the range of"
-                    + " should be in the range of (%f, %f]", hyperfocalDistance, 0.0f,
-                    minFocusDistance),
-                    hyperfocalDistance > 0 && hyperfocalDistance <= minFocusDistance);
-        }
-
-        return hyperfocalDistance;
-    }
-
-    /**
-     * Get the minimum value for a sensitivity range from android.sensor.info.sensitivityRange.
-     *
-     * <p>If the camera is incorrectly reporting values, log a warning and return
-     * the default value instead, which is the largest minimum value required to be supported
-     * by all camera devices.</p>
-     *
-     * @return The value reported by the camera device or the defaultValue otherwise.
-     */
-    public int getSensitivityMinimumOrDefault() {
-        return getSensitivityMinimumOrDefault(SENSOR_INFO_SENSITIVITY_RANGE_MIN_AT_MOST);
-    }
-
-    /**
-     * Get the minimum value for a sensitivity range from android.sensor.info.sensitivityRange.
-     *
-     * <p>If the camera is incorrectly reporting values, log a warning and return
-     * the default value instead.</p>
-     *
-     * @param defaultValue Value to return if no legal value is available
-     * @return The value reported by the camera device or the defaultValue otherwise.
-     */
-    public int getSensitivityMinimumOrDefault(int defaultValue) {
-        Range<Integer> range = getValueFromKeyNonNull(
-                CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE);
-        if (range == null) {
-            failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE,
-                    "had no valid minimum value; using default of " + defaultValue);
-            return defaultValue;
-        }
-        return range.getLower();
-    }
-
-    /**
-     * Get the maximum value for a sensitivity range from android.sensor.info.sensitivityRange.
-     *
-     * <p>If the camera is incorrectly reporting values, log a warning and return
-     * the default value instead, which is the smallest maximum value required to be supported
-     * by all camera devices.</p>
-     *
-     * @return The value reported by the camera device or the defaultValue otherwise.
-     */
-    public int getSensitivityMaximumOrDefault() {
-        return getSensitivityMaximumOrDefault(SENSOR_INFO_SENSITIVITY_RANGE_MAX_AT_LEAST);
-    }
-
-    /**
-     * Get the maximum value for a sensitivity range from android.sensor.info.sensitivityRange.
-     *
-     * <p>If the camera is incorrectly reporting values, log a warning and return
-     * the default value instead.</p>
-     *
-     * @param defaultValue Value to return if no legal value is available
-     * @return The value reported by the camera device or the defaultValue otherwise.
-     */
-    public int getSensitivityMaximumOrDefault(int defaultValue) {
-        Range<Integer> range = getValueFromKeyNonNull(
-                CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE);
-        if (range == null) {
-            failKeyCheck(CameraCharacteristics.SENSOR_INFO_SENSITIVITY_RANGE,
-                    "had no valid maximum value; using default of " + defaultValue);
-            return defaultValue;
-        }
-        return range.getUpper();
-    }
-
-    /**
-     * Get the minimum value for an exposure range from android.sensor.info.exposureTimeRange.
-     *
-     * <p>If the camera is incorrectly reporting values, log a warning and return
-     * the default value instead.</p>
-     *
-     * @param defaultValue Value to return if no legal value is available
-     * @return The value reported by the camera device or the defaultValue otherwise.
-     */
-    public long getExposureMinimumOrDefault(long defaultValue) {
-        Range<Long> range = getValueFromKeyNonNull(
-                CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
-        if (range == null) {
-            failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE,
-                    "had no valid minimum value; using default of " + defaultValue);
-            return defaultValue;
-        }
-        return range.getLower();
-    }
-
-    /**
-     * Get the minimum value for an exposure range from android.sensor.info.exposureTimeRange.
-     *
-     * <p>If the camera is incorrectly reporting values, log a warning and return
-     * the default value instead, which is the largest minimum value required to be supported
-     * by all camera devices.</p>
-     *
-     * @return The value reported by the camera device or the defaultValue otherwise.
-     */
-    public long getExposureMinimumOrDefault() {
-        return getExposureMinimumOrDefault(SENSOR_INFO_EXPOSURE_TIME_RANGE_MIN_AT_MOST);
-    }
-
-    /**
-     * Get the maximum value for an exposure range from android.sensor.info.exposureTimeRange.
-     *
-     * <p>If the camera is incorrectly reporting values, log a warning and return
-     * the default value instead.</p>
-     *
-     * @param defaultValue Value to return if no legal value is available
-     * @return The value reported by the camera device or the defaultValue otherwise.
-     */
-    public long getExposureMaximumOrDefault(long defaultValue) {
-        Range<Long> range = getValueFromKeyNonNull(
-                CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE);
-        if (range == null) {
-            failKeyCheck(CameraCharacteristics.SENSOR_INFO_EXPOSURE_TIME_RANGE,
-                    "had no valid maximum value; using default of " + defaultValue);
-            return defaultValue;
-        }
-        return range.getUpper();
-    }
-
-    /**
-     * Get the maximum value for an exposure range from android.sensor.info.exposureTimeRange.
-     *
-     * <p>If the camera is incorrectly reporting values, log a warning and return
-     * the default value instead, which is the smallest maximum value required to be supported
-     * by all camera devices.</p>
-     *
-     * @return The value reported by the camera device or the defaultValue otherwise.
-     */
-    public long getExposureMaximumOrDefault() {
-        return getExposureMaximumOrDefault(SENSOR_INFO_EXPOSURE_TIME_RANGE_MAX_AT_LEAST);
-    }
-
-    /**
-     * Get aeAvailableModes and do the sanity check.
-     *
-     * <p>Depending on the check level this class has, for WAR or COLLECT levels,
-     * If the aeMode list is invalid, return an empty mode array. The the caller doesn't
-     * have to abort the execution even the aeMode list is invalid.</p>
-     * @return AE available modes
-     */
-    public int[] getAeAvailableModesChecked() {
-        Key<int[]> modesKey = CameraCharacteristics.CONTROL_AE_AVAILABLE_MODES;
-        int[] modes = getValueFromKeyNonNull(modesKey);
-        if (modes == null) {
-            modes = new int[0];
-        }
-        List<Integer> modeList = new ArrayList<Integer>();
-        for (int mode : modes) {
-            modeList.add(mode);
-        }
-        checkTrueForKey(modesKey, "value is empty", !modeList.isEmpty());
-
-        // All camera device must support ON
-        checkTrueForKey(modesKey, "values " + modeList.toString() + " must contain ON mode",
-                modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON));
-
-        // All camera devices with flash units support ON_AUTO_FLASH and ON_ALWAYS_FLASH
-        Key<Boolean> flashKey= CameraCharacteristics.FLASH_INFO_AVAILABLE;
-        Boolean hasFlash = getValueFromKeyNonNull(flashKey);
-        if (hasFlash == null) {
-            hasFlash = false;
-        }
-        if (hasFlash) {
-            boolean flashModeConsistentWithFlash =
-                    modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH) &&
-                    modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH);
-            checkTrueForKey(modesKey,
-                    "value must contain ON_AUTO_FLASH and ON_ALWAYS_FLASH and  when flash is" +
-                    "available", flashModeConsistentWithFlash);
-        } else {
-            boolean flashModeConsistentWithoutFlash =
-                    !(modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH) ||
-                    modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_ALWAYS_FLASH) ||
-                    modeList.contains(CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE));
-            checkTrueForKey(modesKey,
-                    "value must not contain ON_AUTO_FLASH, ON_ALWAYS_FLASH and" +
-                    "ON_AUTO_FLASH_REDEYE when flash is unavailable",
-                    flashModeConsistentWithoutFlash);
-        }
-
-        // FULL mode camera devices always support OFF mode.
-        boolean condition =
-                !isHardwareLevelFull() || modeList.contains(CameraMetadata.CONTROL_AE_MODE_OFF);
-        checkTrueForKey(modesKey, "Full capability device must have OFF mode", condition);
-
-        // Boundary check.
-        for (int mode : modes) {
-            checkTrueForKey(modesKey, "Value " + mode + " is out of bound",
-                    mode >= CameraMetadata.CONTROL_AE_MODE_OFF
-                    && mode <= CameraMetadata.CONTROL_AE_MODE_ON_AUTO_FLASH_REDEYE);
-        }
-
-        return modes;
-    }
-
-    /**
-     * Get available AWB modes and do the sanity check.
-     *
-     * @return array that contains available AWB modes, empty array if awbAvailableModes is
-     * unavailable.
-     */
-    public int[] getAwbAvailableModesChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.CONTROL_AWB_AVAILABLE_MODES;
-        int[] awbModes = getValueFromKeyNonNull(key);
-
-        if (awbModes == null) {
-            return new int[0];
-        }
-
-        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()) {
-            checkTrueForKey(key, " Full capability camera devices must support OFF mode",
-                    modesList.contains(CameraMetadata.CONTROL_AWB_MODE_OFF));
-        }
-
-        return awbModes;
-    }
-
-    /**
-     * Get available AF modes and do the sanity check.
-     *
-     * @return array that contains available AF modes, empty array if afAvailableModes is
-     * unavailable.
-     */
-    public int[] getAfAvailableModesChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.CONTROL_AF_AVAILABLE_MODES;
-        int[] afModes = getValueFromKeyNonNull(key);
-
-        if (afModes == null) {
-            return new int[0];
-        }
-
-        List<Integer> modesList = Arrays.asList(CameraTestUtils.toObject(afModes));
-        if (isHardwareLevelLimitedOrBetter()) {
-            // 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));
-        }
-        if (hasFocuser()) {
-            checkTrueForKey(key, " Camera devices that have focuser units must support AUTO mode",
-                    modesList.contains(CameraMetadata.CONTROL_AF_MODE_AUTO));
-        }
-
-        return afModes;
-    }
-
-    /**
-     * Get supported raw output sizes and do the check.
-     *
-     * @return Empty size array if raw output is not supported
-     */
-    public Size[] getRawOutputSizesChecked() {
-        return getAvailableSizesForFormatChecked(ImageFormat.RAW_SENSOR,
-                StreamDirection.Output);
-    }
-
-    /**
-     * Get supported jpeg output sizes and do the check.
-     *
-     * @return Empty size array if jpeg output is not supported
-     */
-    public Size[] getJpegOutputSizeChecked() {
-        return getAvailableSizesForFormatChecked(ImageFormat.JPEG,
-                StreamDirection.Output);
-    }
-
-    /**
-     * Used to determine the stream direction for various helpers that look up
-     * format or size information.
-     */
-    public enum StreamDirection {
-        /** Stream is used with {@link android.hardware.camera2.CameraDevice#configureOutputs} */
-        Output,
-        /** Stream is used with {@code CameraDevice#configureInputs} -- NOT YET PUBLIC */
-        Input
-    }
-
-    /**
-     * Get available sizes for given user-defined format.
-     *
-     * <p><strong>Does not</strong> work with implementation-defined format.</p>
-     *
-     * @param format The format for the requested size array.
-     * @param direction The stream direction, input or output.
-     * @return The sizes of the given format, empty array if no available size is found.
-     */
-    public Size[] getAvailableSizesForFormatChecked(int format, StreamDirection direction) {
-        Key<StreamConfigurationMap> key =
-                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
-        StreamConfigurationMap config = getValueFromKeyNonNull(key);
-
-        if (config == null) {
-            return new Size[0];
-        }
-
-        android.util.Size[] utilSizes;
-
-        switch (direction) {
-            case Output:
-                utilSizes = config.getOutputSizes(format);
-                break;
-            case Input:
-                utilSizes = null;
-                break;
-            default:
-                throw new IllegalArgumentException("direction must be output or input");
-        }
-
-        // TODO: Get rid of android.util.Size
-        if (utilSizes == null) {
-            Log.i(TAG, "This camera doesn't support format " + format + " for " + direction);
-            return new Size[0];
-        }
-
-        Size[] sizes = new Size[utilSizes.length];
-        for (int i = 0; i < utilSizes.length; ++i) {
-            sizes[i] = new Size(utilSizes[i].getWidth(), utilSizes[i].getHeight());
-        }
-
-        return sizes;
-    }
-
-    /**
-     * Get available AE target fps ranges.
-     *
-     * @return Empty int array if aeAvailableTargetFpsRanges is invalid.
-     */
-    @SuppressWarnings("raw")
-    public Range<Integer>[] getAeAvailableTargetFpsRangesChecked() {
-        Key<Range<Integer>[]> key =
-                CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES;
-        Range<Integer>[] fpsRanges = getValueFromKeyNonNull(key);
-
-        if (fpsRanges == null) {
-            return new Range[0];
-        }
-
-        // Round down to 2 boundary if it is not integer times of 2, to avoid array out of bound
-        // in case the above check fails.
-        int fpsRangeLength = fpsRanges.length;
-        int minFps, maxFps;
-        long maxFrameDuration = getMaxFrameDurationChecked();
-        for (int i = 0; i < fpsRangeLength; i += 1) {
-            minFps = fpsRanges[i].getLower();
-            maxFps = fpsRanges[i].getUpper();
-            checkTrueForKey(key, " min fps must be no larger than max fps!",
-                    minFps > 0 && maxFps >= minFps);
-            long maxDuration = (long) (1e9 / minFps);
-            checkTrueForKey(key, String.format(
-                    " the frame duration %d for min fps %d must smaller than maxFrameDuration %d",
-                    maxDuration, minFps, maxFrameDuration), maxDuration <= maxFrameDuration);
-        }
-
-        return fpsRanges;
-    }
-
-    /**
-     * Get max frame duration.
-     *
-     * @return 0 if maxFrameDuration is null
-     */
-    public long getMaxFrameDurationChecked() {
-        Key<Long> key =
-                CameraCharacteristics.SENSOR_INFO_MAX_FRAME_DURATION;
-        Long maxDuration = getValueFromKeyNonNull(key);
-
-        if (maxDuration == null) {
-            return 0;
-        }
-
-        return maxDuration;
-    }
-
-    /**
-     * Get available minimal frame durations for a given user-defined format.
-     *
-     * <p><strong>Does not</strong> work with implementation-defined format.</p>
-     *
-     * @param format One of the format from {@link ImageFormat}.
-     * @return HashMap of minimal frame durations for different sizes, empty HashMap
-     *         if availableMinFrameDurations is null.
-     */
-    public HashMap<Size, Long> getAvailableMinFrameDurationsForFormatChecked(int format) {
-
-        HashMap<Size, Long> minDurationMap = new HashMap<Size, Long>();
-
-        Key<StreamConfigurationMap> key =
-                CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP;
-        StreamConfigurationMap config = getValueFromKeyNonNull(key);
-
-        if (config == null) {
-            return minDurationMap;
-        }
-
-        for (android.util.Size size : config.getOutputSizes(format)) {
-            long minFrameDuration = config.getOutputMinFrameDuration(format, size);
-
-            if (minFrameDuration != 0) {
-                minDurationMap.put(new Size(size.getWidth(), size.getHeight()), minFrameDuration);
-            }
-        }
-
-        return minDurationMap;
-    }
-
-    public int[] getAvailableEdgeModesChecked() {
-        Key<int[]> key = CameraCharacteristics.EDGE_AVAILABLE_EDGE_MODES;
-        int[] edgeModes = getValueFromKeyNonNull(key);
-
-        if (edgeModes == null) {
-            return new int[0];
-        }
-
-        // Full device should always include OFF and FAST
-        if (isHardwareLevelFull()) {
-            List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(edgeModes));
-            checkTrueForKey(key, "Full device must contain OFF and FAST edge modes",
-                    modeList.contains(CameraMetadata.EDGE_MODE_OFF) &&
-                    modeList.contains(CameraMetadata.EDGE_MODE_FAST));
-        }
-
-        return edgeModes;
-    }
-
-    public int[] getAvailableNoiseReductionModesChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES;
-        int[] noiseReductionModes = getValueFromKeyNonNull(key);
-
-        if (noiseReductionModes == null) {
-            return new int[0];
-        }
-
-        // Full device should always include OFF and FAST
-        if (isHardwareLevelFull()) {
-            List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(noiseReductionModes));
-            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));
-        }
-
-        return noiseReductionModes;
-    }
-
-    /**
-     * Get value of key android.control.aeCompensationStep and do the sanity check.
-     *
-     * @return default value if the value is null.
-     */
-    public Rational getAeCompensationStepChecked() {
-        Key<Rational> key =
-                CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP;
-        Rational compensationStep = getValueFromKeyNonNull(key);
-
-        if (compensationStep == null) {
-            // Return default step.
-            return CONTROL_AE_COMPENSATION_STEP_DEFAULT;
-        }
-
-        // Legacy devices don't have a minimum step requirement
-        if (isHardwareLevelLimitedOrBetter()) {
-            float compensationStepF =
-                    (float) compensationStep.getNumerator() / compensationStep.getDenominator();
-            checkTrueForKey(key, " value must be no more than 1/2", compensationStepF <= 0.5f);
-        }
-
-        return compensationStep;
-    }
-
-    /**
-     * Get value of key android.control.aeCompensationRange and do the sanity check.
-     *
-     * @return default value if the value is null or malformed.
-     */
-    public Range<Integer> getAeCompensationRangeChecked() {
-        Key<Range<Integer>> key =
-                CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE;
-        Range<Integer> compensationRange = getValueFromKeyNonNull(key);
-        Rational compensationStep = getAeCompensationStepChecked();
-        float compensationStepF = compensationStep.floatValue();
-        final Range<Integer> DEFAULT_RANGE = Range.create(
-                (int)(CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MIN / compensationStepF),
-                (int)(CONTROL_AE_COMPENSATION_RANGE_DEFAULT_MAX / compensationStepF));
-        final Range<Integer> ZERO_RANGE = Range.create(0, 0);
-        if (compensationRange == null) {
-            return ZERO_RANGE;
-        }
-
-        // Legacy devices don't have a minimum range requirement
-        if (isHardwareLevelLimitedOrBetter() && !compensationRange.equals(ZERO_RANGE)) {
-            checkTrueForKey(key, " range value must be at least " + DEFAULT_RANGE
-                    + ", actual " + compensationRange + ", compensation step " + compensationStep,
-                   compensationRange.getLower() <= DEFAULT_RANGE.getLower() &&
-                   compensationRange.getUpper() >= DEFAULT_RANGE.getUpper());
-        }
-
-        return compensationRange;
-    }
-
-    /**
-     * Get availableVideoStabilizationModes and do the sanity check.
-     *
-     * @return available video stabilization modes, empty array if it is unavailable.
-     */
-    public int[] getAvailableVideoStabilizationModesChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        if (modes == null) {
-            return new int[0];
-        }
-
-        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
-        checkTrueForKey(key, " All device should support OFF mode",
-                modeList.contains(CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF));
-        checkArrayValuesInRange(key, modes,
-                CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_OFF,
-                CameraMetadata.CONTROL_VIDEO_STABILIZATION_MODE_ON);
-
-        return modes;
-    }
-
-    /**
-     * Get availableOpticalStabilization and do the sanity check.
-     *
-     * @return available optical stabilization modes, empty array if it is unavailable.
-     */
-    public int[] getAvailableOpticalStabilizationChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        if (modes == null) {
-            return new int[0];
-        }
-
-        checkArrayValuesInRange(key, modes,
-                CameraMetadata.LENS_OPTICAL_STABILIZATION_MODE_OFF,
-                CameraMetadata.LENS_OPTICAL_STABILIZATION_MODE_ON);
-
-        return modes;
-    }
-
-    /**
-     * Get the scaler's max digital zoom ({@code >= 1.0f}) ratio between crop and active array
-     * @return the max zoom ratio, or {@code 1.0f} if the value is unavailable
-     */
-    public float getAvailableMaxDigitalZoomChecked() {
-        Key<Float> key =
-                CameraCharacteristics.SCALER_AVAILABLE_MAX_DIGITAL_ZOOM;
-
-        Float maxZoom = getValueFromKeyNonNull(key);
-        if (maxZoom == null) {
-            return 1.0f;
-        }
-
-        checkTrueForKey(key, " max digital zoom should be no less than 1",
-                maxZoom >= 1.0f && !Float.isNaN(maxZoom) && !Float.isInfinite(maxZoom));
-
-        return maxZoom;
-    }
-
-    public int[] getAvailableSceneModesChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.CONTROL_AVAILABLE_SCENE_MODES;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        if (modes == null) {
-            return new int[0];
-        }
-
-        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
-        // FACE_PRIORITY must be included if face detection is supported.
-        if (areKeysAvailable(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT) &&
-                getMaxFaceCountChecked() > 0) {
-            checkTrueForKey(key, " FACE_PRIORITY must be included if face detection is supported",
-                    modeList.contains(CameraMetadata.CONTROL_SCENE_MODE_FACE_PRIORITY));
-        }
-
-        return modes;
-    }
-
-    public int[] getAvailableEffectModesChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        if (modes == null) {
-            return new int[0];
-        }
-
-        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
-        // OFF must be included.
-        checkTrueForKey(key, " OFF must be included",
-                modeList.contains(CameraMetadata.CONTROL_EFFECT_MODE_OFF));
-
-        return modes;
-    }
-
-    /**
-     * Get and check the available color aberration modes
-     *
-     * @return the available color aberration modes
-     */
-    public int[] getAvailableColorAberrationModesChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES;
-        int[] modes = getValueFromKeyNonNull(key);
-
-        if (modes == null) {
-            return new int[0];
-        }
-
-        List<Integer> modeList = Arrays.asList(CameraTestUtils.toObject(modes));
-        checkTrueForKey(key, " Camera devices must always support either OFF or FAST mode",
-                modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF) ||
-                modeList.contains(CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_FAST));
-        checkElementDistinct(key, modeList);
-        checkArrayValuesInRange(key, modes,
-                CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_OFF,
-                CameraMetadata.COLOR_CORRECTION_ABERRATION_MODE_HIGH_QUALITY);
-
-        return modes;
-    }
-
-    /**
-     * Get max pipeline depth and do the sanity check.
-     *
-     * @return max pipeline depth, default value if it is not available.
-     */
-    public byte getPipelineMaxDepthChecked() {
-        Key<Byte> key =
-                CameraCharacteristics.REQUEST_PIPELINE_MAX_DEPTH;
-        Byte maxDepth = getValueFromKeyNonNull(key);
-
-        if (maxDepth == null) {
-            return REQUEST_PIPELINE_MAX_DEPTH_MAX;
-        }
-
-        checkTrueForKey(key, " max pipeline depth should be no larger than "
-                + REQUEST_PIPELINE_MAX_DEPTH_MAX, maxDepth <= REQUEST_PIPELINE_MAX_DEPTH_MAX);
-
-        return maxDepth;
-    }
-
-    /**
-     * Get available capabilities and do the sanity check.
-     *
-     * @return reported available capabilities list, empty list if the value is unavailable.
-     */
-    public List<Integer> getAvailableCapabilitiesChecked() {
-        Key<int[]> key =
-                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES;
-        int[] availableCaps = getValueFromKeyNonNull(key);
-        List<Integer> capList;
-
-        if (availableCaps == null) {
-            return new ArrayList<Integer>();
-        }
-
-        checkArrayValuesInRange(key, availableCaps,
-                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE,
-                CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE);
-        capList = Arrays.asList(CameraTestUtils.toObject(availableCaps));
-        return capList;
-    }
-
-    /**
-     * Determine whether the current device supports a capability or not.
-     *
-     * @param capability (non-negative)
-     *
-     * @return {@code true} if the capability is supported, {@code false} otherwise.
-     *
-     * @throws IllegalArgumentException if {@code capability} was negative
-     *
-     * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
-     */
-    public boolean isCapabilitySupported(int capability) {
-        if (capability < 0) {
-            throw new IllegalArgumentException("capability must be non-negative");
-        }
-
-        List<Integer> availableCapabilities = getAvailableCapabilitiesChecked();
-
-        return availableCapabilities.contains(capability);
-    }
-
-    /**
-     * Determine whether or not all the {@code keys} are available characteristics keys
-     * (as in {@link CameraCharacteristics#getKeys}.
-     *
-     * <p>If this returns {@code true}, then querying for this key from a characteristics
-     * object will always return a non-{@code null} value.</p>
-     *
-     * @param keys collection of camera characteristics keys
-     * @return whether or not all characteristics keys are available
-     */
-    public final boolean areCharacteristicsKeysAvailable(
-            Collection<CameraCharacteristics.Key<?>> keys) {
-        return mCharacteristics.getKeys().containsAll(keys);
-    }
-
-    /**
-     * Determine whether or not all the {@code keys} are available result keys
-     * (as in {@link CameraCharacteristics#getAvailableCaptureResultKeys}.
-     *
-     * <p>If this returns {@code true}, then querying for this key from a result
-     * object will almost always return a non-{@code null} value.</p>
-     *
-     * <p>In some cases (e.g. lens shading map), the request must have additional settings
-     * configured in order for the key to correspond to a value.</p>
-     *
-     * @param keys collection of capture result keys
-     * @return whether or not all result keys are available
-     */
-    public final boolean areResultKeysAvailable(Collection<CaptureResult.Key<?>> keys) {
-        return mCharacteristics.getAvailableCaptureResultKeys().containsAll(keys);
-    }
-
-    /**
-     * Determine whether or not all the {@code keys} are available request keys
-     * (as in {@link CameraCharacteristics#getAvailableCaptureRequestKeys}.
-     *
-     * <p>If this returns {@code true}, then setting this key in the request builder
-     * may have some effect (and if it's {@code false}, then the camera device will
-     * definitely ignore it).</p>
-     *
-     * <p>In some cases (e.g. manual control of exposure), other keys must be also be set
-     * in order for a key to take effect (e.g. control.mode set to OFF).</p>
-     *
-     * @param keys collection of capture request keys
-     * @return whether or not all result keys are available
-     */
-    public final boolean areRequestKeysAvailable(Collection<CaptureRequest.Key<?>> keys) {
-        return mCharacteristics.getAvailableCaptureRequestKeys().containsAll(keys);
-    }
-
-    /**
-     * Determine whether or not all the {@code keys} are available characteristics keys
-     * (as in {@link CameraCharacteristics#getKeys}.
-     *
-     * <p>If this returns {@code true}, then querying for this key from a characteristics
-     * object will always return a non-{@code null} value.</p>
-     *
-     * @param keys one or more camera characteristic keys
-     * @return whether or not all characteristics keys are available
-     */
-    @SafeVarargs
-    public final boolean areKeysAvailable(CameraCharacteristics.Key<?>... keys) {
-        return areCharacteristicsKeysAvailable(Arrays.asList(keys));
-    }
-
-    /**
-     * Determine whether or not all the {@code keys} are available result keys
-     * (as in {@link CameraCharacteristics#getAvailableCaptureResultKeys}.
-     *
-     * <p>If this returns {@code true}, then querying for this key from a result
-     * object will almost always return a non-{@code null} value.</p>
-     *
-     * <p>In some cases (e.g. lens shading map), the request must have additional settings
-     * configured in order for the key to correspond to a value.</p>
-     *
-     * @param keys one or more capture result keys
-     * @return whether or not all result keys are available
-     */
-    @SafeVarargs
-    public final boolean areKeysAvailable(CaptureResult.Key<?>... keys) {
-        return areResultKeysAvailable(Arrays.asList(keys));
-    }
-
-    /**
-     * Determine whether or not all the {@code keys} are available request keys
-     * (as in {@link CameraCharacteristics#getAvailableCaptureRequestKeys}.
-     *
-     * <p>If this returns {@code true}, then setting this key in the request builder
-     * may have some effect (and if it's {@code false}, then the camera device will
-     * definitely ignore it).</p>
-     *
-     * <p>In some cases (e.g. manual control of exposure), other keys must be also be set
-     * in order for a key to take effect (e.g. control.mode set to OFF).</p>
-     *
-     * @param keys one or more capture request keys
-     * @return whether or not all result keys are available
-     */
-    @SafeVarargs
-    public final boolean areKeysAvailable(CaptureRequest.Key<?>... keys) {
-        return areRequestKeysAvailable(Arrays.asList(keys));
-    }
-
-    /*
-     * Determine if camera device support manual lens shading map control
-     *
-     * @return {@code true} if manual lens shading map control is supported
-     */
-    public boolean isManualLensShadingMapSupported() {
-        return areKeysAvailable(CaptureRequest.SHADING_MODE);
-    }
-
-    /**
-     * Determine if camera device support manual color correction control
-     *
-     * @return {@code true} if manual color correction control is supported
-     */
-    public boolean isManualColorCorrectionSupported() {
-        return areKeysAvailable(CaptureRequest.COLOR_CORRECTION_MODE);
-    }
-
-    /**
-     * Determine if camera device support manual tone mapping control
-     *
-     * @return {@code true} if manual tone mapping control is supported
-     */
-    public boolean isManualToneMapSupported() {
-        return areKeysAvailable(CaptureRequest.TONEMAP_MODE);
-    }
-
-    /**
-     * Determine if camera device support manual color aberration control
-     *
-     * @return {@code true} if manual color aberration control is supported
-     */
-    public boolean isManualColorAberrationControlSupported() {
-        return areKeysAvailable(CaptureRequest.COLOR_CORRECTION_ABERRATION_MODE);
-    }
-
-    /**
-     * Determine if camera device support edge mode control
-     *
-     * @return {@code true} if edge mode control is supported
-     */
-    public boolean isEdgeModeControlSupported() {
-        return areKeysAvailable(CaptureRequest.EDGE_MODE);
-    }
-
-    /**
-     * Determine if camera device support hot pixel mode control
-     *
-     * @return {@code true} if hot pixel mode control is supported
-     */
-    public boolean isHotPixelMapModeControlSupported() {
-        return areKeysAvailable(CaptureRequest.HOT_PIXEL_MODE);
-    }
-
-    /**
-     * Determine if camera device support noise reduction mode control
-     *
-     * @return {@code true} if noise reduction mode control is supported
-     */
-    public boolean isNoiseReductionModeControlSupported() {
-        return areKeysAvailable(CaptureRequest.NOISE_REDUCTION_MODE);
-    }
-
-    /**
-     * Get max number of output raw streams and do the basic sanity check.
-     *
-     * @return reported max number of raw output stream
-     */
-    public int getMaxNumOutputStreamsRawChecked() {
-        Integer maxNumStreams =
-                getValueFromKeyNonNull(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_RAW);
-        if (maxNumStreams == null)
-            return 0;
-        return maxNumStreams;
-    }
-
-    /**
-     * Get max number of output processed streams and do the basic sanity check.
-     *
-     * @return reported max number of processed output stream
-     */
-    public int getMaxNumOutputStreamsProcessedChecked() {
-        Integer maxNumStreams =
-                getValueFromKeyNonNull(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC);
-        if (maxNumStreams == null)
-            return 0;
-        return maxNumStreams;
-    }
-
-    /**
-     * Get max number of output stalling processed streams and do the basic sanity check.
-     *
-     * @return reported max number of stalling processed output stream
-     */
-    public int getMaxNumOutputStreamsProcessedStallChecked() {
-        Integer maxNumStreams =
-                getValueFromKeyNonNull(CameraCharacteristics.REQUEST_MAX_NUM_OUTPUT_PROC_STALLING);
-        if (maxNumStreams == null)
-            return 0;
-        return maxNumStreams;
-    }
-
-    /**
-     * Get lens facing and do the sanity check
-     * @return lens facing, return default value (BACK) if value is unavailable.
-     */
-    public int getLensFacingChecked() {
-        Key<Integer> key =
-                CameraCharacteristics.LENS_FACING;
-        Integer facing = getValueFromKeyNonNull(key);
-
-        if (facing == null) {
-            return CameraCharacteristics.LENS_FACING_BACK;
-        }
-
-        checkTrueForKey(key, " value is out of range ",
-                facing >= CameraCharacteristics.LENS_FACING_FRONT &&
-                facing <= CameraCharacteristics.LENS_FACING_BACK);
-        return facing;
-    }
-
-    /**
-     * Get the scaler's cropping type (center only or freeform)
-     * @return cropping type, return default value (CENTER_ONLY) if value is unavailable
-     */
-    public int getScalerCroppingTypeChecked() {
-        Key<Integer> key =
-                CameraCharacteristics.SCALER_CROPPING_TYPE;
-        Integer value = getValueFromKeyNonNull(key);
-
-        if (value == null) {
-            return CameraCharacteristics.SCALER_CROPPING_TYPE_CENTER_ONLY;
-        }
-
-        checkTrueForKey(key, " value is out of range ",
-                value >= CameraCharacteristics.SCALER_CROPPING_TYPE_CENTER_ONLY &&
-                value <= CameraCharacteristics.SCALER_CROPPING_TYPE_FREEFORM);
-
-        return value;
-    }
-
-    /**
-     * Check if high speed video is supported (HIGH_SPEED_VIDEO scene mode is
-     * supported, supported high speed fps ranges and sizes are valid).
-     *
-     * @return true if high speed video is supported.
-     */
-    public boolean isHighSpeedVideoSupported() {
-        List<Integer> sceneModes =
-                Arrays.asList(CameraTestUtils.toObject(getAvailableSceneModesChecked()));
-        if (sceneModes.contains(CameraCharacteristics.CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO)) {
-            StreamConfigurationMap config =
-                    getValueFromKeyNonNull(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
-            if (config == null) {
-                return false;
-            }
-            Size[] availableSizes = config.getHighSpeedVideoSizes();
-            if (availableSizes.length == 0) {
-                return false;
-            }
-
-            for (Size size : availableSizes) {
-                Range<Integer>[] availableFpsRanges = config.getHighSpeedVideoFpsRangesFor(size);
-                if (availableFpsRanges.length == 0) {
-                    return false;
-                }
-            }
-
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * 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
-     * the default value instead.</p>
-     *
-     * @param key Key to fetch
-     * @param defaultValue Default value to return if camera device uses invalid values
-     * @param name Human-readable name for the array index (logging only)
-     * @param index Array index of the subelement
-     * @param size Expected fixed size of the array
-     *
-     * @return The value reported by the camera device, or the defaultValue otherwise.
-     */
-    private <T> T getArrayElementOrDefault(Key<?> key, T defaultValue, String name, int index,
-            int size) {
-        T elementValue = getArrayElementCheckRangeNonNull(
-                key,
-                index,
-                size);
-
-        if (elementValue == null) {
-            failKeyCheck(key,
-                    "had no valid " + name + " value; using default of " + defaultValue);
-            elementValue = defaultValue;
-        }
-
-        return elementValue;
-    }
-
-    /**
-     * Fetch an array sub-element from an array value given by a key.
-     *
-     * <p>
-     * Prints a warning if the sub-element was null.
-     * </p>
-     *
-     * <p>Use for variable-size arrays since this does not check the array size.</p>
-     *
-     * @param key Metadata key to look up
-     * @param element A non-negative index value.
-     * @return The array sub-element, or null if the checking failed.
-     */
-    private <T> T getArrayElementNonNull(Key<?> key, int element) {
-        return getArrayElementCheckRangeNonNull(key, element, IGNORE_SIZE_CHECK);
-    }
-
-    /**
-     * Fetch an array sub-element from an array value given by a key.
-     *
-     * <p>
-     * Prints a warning if the array size does not match the size, or if the sub-element was null.
-     * </p>
-     *
-     * @param key Metadata key to look up
-     * @param element The index in [0,size)
-     * @param size A positive size value or otherwise {@value #IGNORE_SIZE_CHECK}
-     * @return The array sub-element, or null if the checking failed.
-     */
-    private <T> T getArrayElementCheckRangeNonNull(Key<?> key, int element, int size) {
-        Object array = getValueFromKeyNonNull(key);
-
-        if (array == null) {
-            // Warning already printed
-            return null;
-        }
-
-        if (size != IGNORE_SIZE_CHECK) {
-            int actualLength = Array.getLength(array);
-            if (actualLength != size) {
-                failKeyCheck(key,
-                        String.format("had the wrong number of elements (%d), expected (%d)",
-                                actualLength, size));
-                return null;
-            }
-        }
-
-        @SuppressWarnings("unchecked")
-        T val = (T) Array.get(array, element);
-
-        if (val == null) {
-            failKeyCheck(key, "had a null element at index" + element);
-            return null;
-        }
-
-        return val;
-    }
-
-    /**
-     * Gets the key, logging warnings for null values.
-     */
-    public <T> T getValueFromKeyNonNull(Key<T> key) {
-        if (key == null) {
-            throw new IllegalArgumentException("key was null");
-        }
-
-        T value = mCharacteristics.get(key);
-
-        if (value == null) {
-            failKeyCheck(key, "was null");
-        }
-
-        return value;
-    }
-
-    private void checkArrayValuesInRange(Key<int[]> key, int[] array, int min, int max) {
-        for (int value : array) {
-            checkTrueForKey(key, String.format(" value is out of range [%d, %d]", min, max),
-                    value <= max && value >= min);
-        }
-    }
-
-    private void checkArrayValuesInRange(Key<byte[]> key, byte[] array, byte min, byte max) {
-        for (byte value : array) {
-            checkTrueForKey(key, String.format(" value is out of range [%d, %d]", min, max),
-                    value <= max && value >= min);
-        }
-    }
-
-    /**
-     * Check the uniqueness of the values in a list.
-     *
-     * @param key The key to be checked
-     * @param list The list contains the value of the key
-     */
-    private <U, T> void checkElementDistinct(Key<U> key, List<T> list) {
-        // Each size must be distinct.
-        Set<T> sizeSet = new HashSet<T>(list);
-        checkTrueForKey(key, "Each size must be distinct", sizeSet.size() == list.size());
-    }
-
-    private <T> void checkTrueForKey(Key<T> key, String message, boolean condition) {
-        if (!condition) {
-            failKeyCheck(key, message);
-        }
-    }
-
-    private <T> void failKeyCheck(Key<T> key, String message) {
-        // TODO: Consider only warning once per key/message combination if it's too spammy.
-        // TODO: Consider offering other options such as throwing an assertion exception
-        String failureCause = String.format("The static info key '%s' %s", key.getName(), message);
-        switch (mLevel) {
-            case WARN:
-                Log.w(TAG, failureCause);
-                break;
-            case COLLECT:
-                mCollector.addMessage(failureCause);
-                break;
-            case ASSERT:
-                Assert.fail(failureCause);
-            default:
-                throw new UnsupportedOperationException("Unhandled level " + mLevel);
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RawConverter.java b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RawConverter.java
deleted file mode 100644
index 33c212a..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RawConverter.java
+++ /dev/null
@@ -1,796 +0,0 @@
-/*
- * 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.rs;
-
-import android.graphics.Bitmap;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureResult;
-import android.hardware.camera2.params.ColorSpaceTransform;
-import android.hardware.camera2.params.LensShadingMap;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.Float3;
-import android.renderscript.Float4;
-import android.renderscript.Int4;
-import android.renderscript.Matrix3f;
-import android.renderscript.RenderScript;
-import android.renderscript.Type;
-
-import android.hardware.camera2.cts.ScriptC_raw_converter;
-import android.util.Log;
-import android.util.Rational;
-import android.util.SparseIntArray;
-
-import java.util.Arrays;
-
-/**
- * Utility class providing methods for rendering RAW16 images into other colorspaces.
- */
-public class RawConverter {
-    private static final String TAG = "RawConverter";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    /**
-     * Matrix to convert from CIE XYZ colorspace to sRGB, Bradford-adapted to D65.
-     */
-    private static final float[] sXYZtoRGBBradford = new float[] {
-            3.1338561f, -1.6168667f, -0.4906146f,
-            -0.9787684f, 1.9161415f, 0.0334540f,
-            0.0719453f, -0.2289914f, 1.4052427f
-    };
-
-    /**
-     * Matrix to convert from the ProPhoto RGB colorspace to CIE XYZ colorspace.
-     */
-    private static final float[] sProPhotoToXYZ = new float[] {
-            0.797779f, 0.135213f, 0.031303f,
-            0.288000f, 0.711900f, 0.000100f,
-            0.000000f, 0.000000f, 0.825105f
-    };
-
-    /**
-     * Matrix to convert from CIE XYZ colorspace to ProPhoto RGB colorspace.
-     */
-    private static final float[] sXYZtoProPhoto = new float[] {
-            1.345753f, -0.255603f, -0.051025f,
-            -0.544426f, 1.508096f, 0.020472f,
-            0.000000f, 0.000000f, 1.211968f
-    };
-
-    /**
-     * Coefficients for a 3rd order polynomial, ordered from highest to lowest power.  This
-     * polynomial approximates the default tonemapping curve used for ACR3.
-     */
-    private static final float[] DEFAULT_ACR3_TONEMAP_CURVE_COEFFS = new float[] {
-            -1.087f,  1.643f,  0.443f, 0f
-    };
-
-    /**
-     * The D50 whitepoint coordinates in CIE XYZ colorspace.
-     */
-    private static final float[] D50_XYZ = new float[] { 0.9642f, 1, 0.8249f };
-
-    /**
-     * An array containing the color temperatures for standard reference illuminants.
-     */
-    private static final SparseIntArray sStandardIlluminants = new SparseIntArray();
-    private static final int NO_ILLUMINANT = -1;
-    static {
-        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT, 6504);
-        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D65, 6504);
-        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D50, 5003);
-        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D55, 5503);
-        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_D75, 7504);
-        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_STANDARD_A, 2856);
-        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_STANDARD_B, 4874);
-        sStandardIlluminants.append(CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_STANDARD_C, 6774);
-        sStandardIlluminants.append(
-                CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_DAYLIGHT_FLUORESCENT, 6430);
-        sStandardIlluminants.append(
-                CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_COOL_WHITE_FLUORESCENT, 4230);
-        sStandardIlluminants.append(
-                CameraMetadata.SENSOR_REFERENCE_ILLUMINANT1_WHITE_FLUORESCENT, 3450);
-        // TODO: Add the rest of the illuminants included in the LightSource EXIF tag.
-    }
-
-    /**
-     * Convert a RAW16 buffer into an sRGB buffer, and write the result into a bitmap.
-     *
-     * <p> This function applies the operations roughly outlined in the Adobe DNG specification
-     * using the provided metadata about the image sensor.  Sensor data for Android devices is
-     * assumed to be relatively linear, and no extra linearization step is applied here.  The
-     * following operations are applied in the given order:</p>
-     *
-     * <ul>
-     *     <li>
-     *         Black level subtraction - the black levels given in the SENSOR_BLACK_LEVEL_PATTERN
-     *         tag are subtracted from the corresponding raw pixels.
-     *     </li>
-     *     <li>
-     *         Rescaling - each raw pixel is scaled by 1/(white level - black level).
-     *     </li>
-     *     <li>
-     *         Lens shading correction - the interpolated gains from the gain map defined in the
-     *         STATISTICS_LENS_SHADING_CORRECTION_MAP are applied to each raw pixel.
-     *     </li>
-     *     <li>
-     *         Clipping - each raw pixel is clipped to a range of [0.0, 1.0].
-     *     </li>
-     *     <li>
-     *         Demosaic - the RGB channels for each pixel are retrieved from the Bayer mosaic
-     *         of raw pixels using a simple bilinear-interpolation demosaicing algorithm.
-     *     </li>
-     *     <li>
-     *         Colorspace transform to wide-gamut RGB - each pixel is mapped into a
-     *         wide-gamut colorspace (in this case ProPhoto RGB is used) from the sensor
-     *         colorspace.
-     *     </li>
-     *     <li>
-     *         Tonemapping - A basic tonemapping curve using the default from ACR3 is applied
-     *         (no further exposure compensation is applied here, though this could be improved).
-     *     </li>
-     *     <li>
-     *         Colorspace transform to final RGB - each pixel is mapped into linear sRGB colorspace.
-     *     </li>
-     *     <li>
-     *         Gamma correction - each pixel is gamma corrected using γ=2.2 to map into sRGB
-     *         colorspace for viewing.
-     *     </li>
-     *     <li>
-     *         Packing - each pixel is scaled so that each color channel has a range of [0, 255],
-     *         and is packed into an Android bitmap.
-     *     </li>
-     * </ul>
-     *
-     * <p> Arguments given here are assumed to come from the values for the corresponding
-     * {@link CameraCharacteristics.Key}s defined for the camera that produced this RAW16 buffer.
-     * </p>
-     * @param rs a {@link RenderScript} context to use.
-     * @param inputWidth width of the input RAW16 image in pixels.
-     * @param inputHeight height of the input RAW16 image in pixels.
-     * @param inputStride stride of the input RAW16 image in bytes.
-     * @param rawImageInput a byte array containing a RAW16 image.
-     * @param staticMetadata the {@link CameraCharacteristics} for this RAW capture.
-     * @param dynamicMetadata the {@link CaptureResult} for this RAW capture.
-     * @param outputOffsetX the offset width into the raw image of the left side of the output
-     *                      rectangle.
-     * @param outputOffsetY the offset height into the raw image of the top side of the output
-     *                      rectangle.
-     * @param argbOutput a {@link Bitmap} to output the rendered RAW image into.  The height and
-     *                   width of this bitmap along with the output offsets are used to determine
-     *                   the dimensions and offset of the output rectangle contained in the RAW
-     *                   image to be rendered.
-     */
-    public static void convertToSRGB(RenderScript rs, int inputWidth, int inputHeight,
-            int inputStride, byte[] rawImageInput, CameraCharacteristics staticMetadata,
-            CaptureResult dynamicMetadata, int outputOffsetX, int outputOffsetY,
-            /*out*/Bitmap argbOutput) {
-        int cfa = staticMetadata.get(CameraCharacteristics.SENSOR_INFO_COLOR_FILTER_ARRANGEMENT);
-        int[] blackLevelPattern = new int[4];
-        staticMetadata.get(CameraCharacteristics.SENSOR_BLACK_LEVEL_PATTERN).
-                copyTo(blackLevelPattern, /*offset*/0);
-        int whiteLevel = staticMetadata.get(CameraCharacteristics.SENSOR_INFO_WHITE_LEVEL);
-        int ref1 = staticMetadata.get(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT1);
-        int ref2 = staticMetadata.get(CameraCharacteristics.SENSOR_REFERENCE_ILLUMINANT2);
-        float[] calib1 = new float[9];
-        float[] calib2 = new float[9];
-        convertColorspaceTransform(
-                staticMetadata.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM1), calib1);
-        convertColorspaceTransform(
-                staticMetadata.get(CameraCharacteristics.SENSOR_CALIBRATION_TRANSFORM2), calib2);
-        float[] color1 = new float[9];
-        float[] color2 = new float[9];
-        convertColorspaceTransform(
-                staticMetadata.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM1), color1);
-        convertColorspaceTransform(
-                staticMetadata.get(CameraCharacteristics.SENSOR_COLOR_TRANSFORM2), color2);
-        float[] forward1 = new float[9];
-        float[] forward2 = new float[9];
-        convertColorspaceTransform(
-                staticMetadata.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX1), forward1);
-        convertColorspaceTransform(
-                staticMetadata.get(CameraCharacteristics.SENSOR_FORWARD_MATRIX2), forward2);
-
-        Rational[] neutral = dynamicMetadata.get(CaptureResult.SENSOR_NEUTRAL_COLOR_POINT);
-
-        LensShadingMap shadingMap = dynamicMetadata.get(CaptureResult.STATISTICS_LENS_SHADING_CORRECTION_MAP);
-
-        convertToSRGB(rs, inputWidth, inputHeight, inputStride, cfa, blackLevelPattern, whiteLevel,
-                rawImageInput, ref1, ref2, calib1, calib2, color1, color2,
-                forward1, forward2, neutral, shadingMap, outputOffsetX, outputOffsetY, argbOutput);
-    }
-
-    /**
-     * Convert a RAW16 buffer into an sRGB buffer, and write the result into a bitmap.
-     *
-     * @see #convertToSRGB
-     */
-    private static void convertToSRGB(RenderScript rs, int inputWidth, int inputHeight,
-            int inputStride, int cfa, int[] blackLevelPattern, int whiteLevel, byte[] rawImageInput,
-            int referenceIlluminant1, int referenceIlluminant2, float[] calibrationTransform1,
-            float[] calibrationTransform2, float[] colorMatrix1, float[] colorMatrix2,
-            float[] forwardTransform1, float[] forwardTransform2, Rational[/*3*/] neutralColorPoint,
-            LensShadingMap lensShadingMap, int outputOffsetX, int outputOffsetY,
-            /*out*/Bitmap argbOutput) {
-
-        // Validate arguments
-        if (argbOutput == null || rs == null || rawImageInput == null) {
-            throw new IllegalArgumentException("Null argument to convertToSRGB");
-        }
-        if (argbOutput.getConfig() != Bitmap.Config.ARGB_8888) {
-            throw new IllegalArgumentException(
-                    "Output bitmap passed to convertToSRGB is not ARGB_8888 format");
-        }
-        if (outputOffsetX < 0 || outputOffsetY < 0) {
-            throw new IllegalArgumentException("Negative offset passed to convertToSRGB");
-        }
-        if ((inputStride / 2) < inputWidth) {
-            throw new IllegalArgumentException("Stride too small.");
-        }
-        if ((inputStride % 2) != 0) {
-            throw new IllegalArgumentException("Invalid stride for RAW16 format, see graphics.h.");
-        }
-        int outWidth = argbOutput.getWidth();
-        int outHeight = argbOutput.getHeight();
-        if (outWidth + outputOffsetX > inputWidth || outHeight + outputOffsetY > inputHeight) {
-            throw new IllegalArgumentException("Raw image with dimensions (w=" + inputWidth +
-                    ", h=" + inputHeight + "), cannot converted into sRGB image with dimensions (w="
-                    + outWidth + ", h=" + outHeight + ").");
-        }
-        if (cfa < 0 || cfa > 3) {
-            throw new IllegalArgumentException("Unsupported cfa pattern " + cfa + " used.");
-        }
-        if (DEBUG) {
-            Log.d(TAG, "Metadata Used:");
-            Log.d(TAG, "Input width,height: " + inputWidth + "," + inputHeight);
-            Log.d(TAG, "Output offset x,y: " + outputOffsetX + "," + outputOffsetY);
-            Log.d(TAG, "Output width,height: " + outWidth + "," + outHeight);
-            Log.d(TAG, "CFA: " + cfa);
-            Log.d(TAG, "BlackLevelPattern: " + Arrays.toString(blackLevelPattern));
-            Log.d(TAG, "WhiteLevel: " + whiteLevel);
-            Log.d(TAG, "ReferenceIlluminant1: " + referenceIlluminant1);
-            Log.d(TAG, "ReferenceIlluminant2: " + referenceIlluminant2);
-            Log.d(TAG, "CalibrationTransform1: " + Arrays.toString(calibrationTransform1));
-            Log.d(TAG, "CalibrationTransform2: " + Arrays.toString(calibrationTransform2));
-            Log.d(TAG, "ColorMatrix1: " + Arrays.toString(colorMatrix1));
-            Log.d(TAG, "ColorMatrix2: " + Arrays.toString(colorMatrix2));
-            Log.d(TAG, "ForwardTransform1: " + Arrays.toString(forwardTransform1));
-            Log.d(TAG, "ForwardTransform2: " + Arrays.toString(forwardTransform2));
-            Log.d(TAG, "NeutralColorPoint: " + Arrays.toString(neutralColorPoint));
-        }
-
-        Allocation gainMap = null;
-        if (lensShadingMap != null) {
-            float[] lsm = new float[lensShadingMap.getGainFactorCount()];
-            lensShadingMap.copyGainFactors(/*inout*/lsm, /*offset*/0);
-            gainMap = createFloat4Allocation(rs, lsm, lensShadingMap.getColumnCount(),
-                    lensShadingMap.getRowCount());
-        }
-
-        float[] normalizedForwardTransform1 = Arrays.copyOf(forwardTransform1,
-                forwardTransform1.length);
-        normalizeFM(normalizedForwardTransform1);
-        float[] normalizedForwardTransform2 = Arrays.copyOf(forwardTransform2,
-                forwardTransform2.length);
-        normalizeFM(normalizedForwardTransform2);
-
-        float[] normalizedColorMatrix1 = Arrays.copyOf(colorMatrix1, colorMatrix1.length);
-        normalizeCM(normalizedColorMatrix1);
-        float[] normalizedColorMatrix2 = Arrays.copyOf(colorMatrix2, colorMatrix2.length);
-        normalizeCM(normalizedColorMatrix2);
-
-        if (DEBUG) {
-            Log.d(TAG, "Normalized ForwardTransform1: " + Arrays.toString(normalizedForwardTransform1));
-            Log.d(TAG, "Normalized ForwardTransform2: " + Arrays.toString(normalizedForwardTransform2));
-            Log.d(TAG, "Normalized ColorMatrix1: " + Arrays.toString(normalizedColorMatrix1));
-            Log.d(TAG, "Normalized ColorMatrix2: " + Arrays.toString(normalizedColorMatrix2));
-        }
-
-        // Calculate full sensor colorspace to sRGB colorspace transform.
-        double interpolationFactor = findDngInterpolationFactor(referenceIlluminant1,
-                referenceIlluminant2, calibrationTransform1, calibrationTransform2,
-                normalizedColorMatrix1, normalizedColorMatrix2, neutralColorPoint);
-        if (DEBUG) Log.d(TAG, "Interpolation factor used: " + interpolationFactor);
-        float[] sensorToXYZ = new float[9];
-        calculateCameraToXYZD50Transform(normalizedForwardTransform1, normalizedForwardTransform2,
-                calibrationTransform1, calibrationTransform2, neutralColorPoint,
-                interpolationFactor, /*out*/sensorToXYZ);
-        if (DEBUG) Log.d(TAG, "CameraToXYZ xform used: " + Arrays.toString(sensorToXYZ));
-        float[] sensorToProPhoto = new float[9];
-        multiply(sXYZtoProPhoto, sensorToXYZ, /*out*/sensorToProPhoto);
-        if (DEBUG) Log.d(TAG, "CameraToIntemediate xform used: " + Arrays.toString(sensorToProPhoto));
-        Allocation output = Allocation.createFromBitmap(rs, argbOutput);
-
-        float[] proPhotoToSRGB = new float[9];
-        multiply(sXYZtoRGBBradford, sProPhotoToXYZ, /*out*/proPhotoToSRGB);
-
-        // Setup input allocation (16-bit raw pixels)
-        Type.Builder typeBuilder = new Type.Builder(rs, Element.U16(rs));
-        typeBuilder.setX((inputStride / 2));
-        typeBuilder.setY(inputHeight);
-        Type inputType = typeBuilder.create();
-        Allocation input = Allocation.createTyped(rs, inputType);
-        input.copyFromUnchecked(rawImageInput);
-
-        // Setup RS kernel globals
-        ScriptC_raw_converter converterKernel = new ScriptC_raw_converter(rs);
-        converterKernel.set_inputRawBuffer(input);
-        converterKernel.set_whiteLevel(whiteLevel);
-        converterKernel.set_sensorToIntermediate(new Matrix3f(transpose(sensorToProPhoto)));
-        converterKernel.set_intermediateToSRGB(new Matrix3f(transpose(proPhotoToSRGB)));
-        converterKernel.set_offsetX(outputOffsetX);
-        converterKernel.set_offsetY(outputOffsetY);
-        converterKernel.set_rawHeight(inputHeight);
-        converterKernel.set_rawWidth(inputWidth);
-        converterKernel.set_neutralPoint(new Float3(neutralColorPoint[0].floatValue(),
-                neutralColorPoint[1].floatValue(), neutralColorPoint[2].floatValue()));
-        converterKernel.set_toneMapCoeffs(new Float4(DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[0],
-                DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[1], DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[2],
-                DEFAULT_ACR3_TONEMAP_CURVE_COEFFS[3]));
-        converterKernel.set_hasGainMap(gainMap != null);
-        if (gainMap != null) {
-            converterKernel.set_gainMap(gainMap);
-            converterKernel.set_gainMapWidth(lensShadingMap.getColumnCount());
-            converterKernel.set_gainMapHeight(lensShadingMap.getRowCount());
-        }
-
-        converterKernel.set_cfaPattern(cfa);
-        converterKernel.set_blackLevelPattern(new Int4(blackLevelPattern[0],
-                blackLevelPattern[1], blackLevelPattern[2], blackLevelPattern[3]));
-        converterKernel.forEach_convert_RAW_To_ARGB(output);
-        output.copyTo(argbOutput);  // Force RS sync with bitmap (does not do an extra copy).
-    }
-
-    /**
-     * Create a float-backed renderscript {@link Allocation} with the given dimensions, containing
-     * the contents of the given float array.
-     *
-     * @param rs a {@link RenderScript} context to use.
-     * @param fArray the float array to copy into the {@link Allocation}.
-     * @param width the width of the {@link Allocation}.
-     * @param height the height of the {@link Allocation}.
-     * @return an {@link Allocation} containing the given floats.
-     */
-    private static Allocation createFloat4Allocation(RenderScript rs, float[] fArray,
-                                                    int width, int height) {
-        if (fArray.length != width * height * 4) {
-            throw new IllegalArgumentException("Invalid float array of length " + fArray.length +
-                    ", must be correct size for Allocation of dimensions " + width + "x" + height);
-        }
-        Type.Builder builder = new Type.Builder(rs, Element.F32_4(rs));
-        builder.setX(width);
-        builder.setY(height);
-        Allocation fAlloc = Allocation.createTyped(rs, builder.create());
-        fAlloc.copyFrom(fArray);
-        return fAlloc;
-    }
-
-    /**
-     * Calculate the correlated color temperature (CCT) for a given x,y chromaticity in CIE 1931 x,y
-     * chromaticity space using McCamy's cubic approximation algorithm given in:
-     *
-     * McCamy, Calvin S. (April 1992).
-     * "Correlated color temperature as an explicit function of chromaticity coordinates".
-     * Color Research & Application 17 (2): 142–144
-     *
-     * @param x x chromaticity component.
-     * @param y y chromaticity component.
-     *
-     * @return the CCT associated with this chromaticity coordinate.
-     */
-    private static double calculateColorTemperature(double x, double y) {
-        double n = (x - 0.332) / (y - 0.1858);
-        return -449 * Math.pow(n, 3) + 3525 * Math.pow(n, 2) - 6823.3 * n + 5520.33;
-    }
-
-    /**
-     * Calculate the x,y chromaticity coordinates in CIE 1931 x,y chromaticity space from the given
-     * CIE XYZ coordinates.
-     *
-     * @param X the CIE XYZ X coordinate.
-     * @param Y the CIE XYZ Y coordinate.
-     * @param Z the CIE XYZ Z coordinate.
-     *
-     * @return the [x, y] chromaticity coordinates as doubles.
-     */
-    private static double[] calculateCIExyCoordinates(double X, double Y, double Z) {
-        double[] ret = new double[] { 0, 0 };
-        ret[0] = X / (X + Y + Z);
-        ret[1] = Y / (X + Y + Z);
-        return ret;
-    }
-
-    /**
-     * Linearly interpolate between a and b given fraction f.
-     *
-     * @param a first term to interpolate between, a will be returned when f == 0.
-     * @param b second term to interpolate between, b will be returned when f == 1.
-     * @param f the fraction to interpolate by.
-     *
-     * @return interpolated result as double.
-     */
-    private static double lerp(double a, double b, double f) {
-        return (a * (1.0f - f)) + (b * f);
-    }
-
-    /**
-     * Linearly interpolate between 3x3 matrices a and b given fraction f.
-     *
-     * @param a first 3x3 matrix to interpolate between, a will be returned when f == 0.
-     * @param b second 3x3 matrix to interpolate between, b will be returned when f == 1.
-     * @param f the fraction to interpolate by.
-     * @param result will be set to contain the interpolated matrix.
-     */
-    private static void lerp(float[] a, float[] b, double f, /*out*/float[] result) {
-        for (int i = 0; i < 9; i++) {
-            result[i] = (float) lerp(a[i], b[i], f);
-        }
-    }
-
-    /**
-     * Convert a 9x9 {@link ColorSpaceTransform} to a matrix and write the matrix into the
-     * output.
-     *
-     * @param xform a {@link ColorSpaceTransform} to transform.
-     * @param output the 3x3 matrix to overwrite.
-     */
-    private static void convertColorspaceTransform(ColorSpaceTransform xform, /*out*/float[] output) {
-        for (int i = 0; i < 3; i++) {
-            for (int j = 0; j < 3; j++) {
-                output[i * 3 + j] = xform.getElement(j, i).floatValue();
-            }
-        }
-    }
-
-    /**
-     * Find the interpolation factor to use with the RAW matrices given a neutral color point.
-     *
-     * @param referenceIlluminant1 first reference illuminant.
-     * @param referenceIlluminant2 second reference illuminant.
-     * @param calibrationTransform1 calibration matrix corresponding to the first reference
-     *                              illuminant.
-     * @param calibrationTransform2 calibration matrix corresponding to the second reference
-     *                              illuminant.
-     * @param colorMatrix1 color matrix corresponding to the first reference illuminant.
-     * @param colorMatrix2 color matrix corresponding to the second reference illuminant.
-     * @param neutralColorPoint the neutral color point used to calculate the interpolation factor.
-     *
-     * @return the interpolation factor corresponding to the given neutral color point.
-     */
-    private static double findDngInterpolationFactor(int referenceIlluminant1,
-            int referenceIlluminant2, float[] calibrationTransform1, float[] calibrationTransform2,
-            float[] colorMatrix1, float[] colorMatrix2, Rational[/*3*/] neutralColorPoint) {
-
-        int colorTemperature1 = sStandardIlluminants.get(referenceIlluminant1, NO_ILLUMINANT);
-        if (colorTemperature1 == NO_ILLUMINANT) {
-            throw new IllegalArgumentException("No such illuminant for reference illuminant 1: " +
-                    referenceIlluminant1);
-        }
-
-        int colorTemperature2 = sStandardIlluminants.get(referenceIlluminant2, NO_ILLUMINANT);
-        if (colorTemperature2 == NO_ILLUMINANT) {
-            throw new IllegalArgumentException("No such illuminant for reference illuminant 2: " +
-                    referenceIlluminant2);
-        }
-
-        if (DEBUG) Log.d(TAG, "ColorTemperature1: " + colorTemperature1);
-        if (DEBUG) Log.d(TAG, "ColorTemperature2: " + colorTemperature2);
-
-        double interpFactor = 0.5; // Initial guess for interpolation factor
-        double oldInterpFactor = interpFactor;
-
-        double lastDiff = Double.MAX_VALUE;
-        double tolerance = 0.0001;
-        float[] XYZToCamera1 = new float[9];
-        float[] XYZToCamera2 = new float[9];
-        multiply(calibrationTransform1, colorMatrix1, /*out*/XYZToCamera1);
-        multiply(calibrationTransform2, colorMatrix2, /*out*/XYZToCamera2);
-
-        float[] cameraNeutral = new float[] { neutralColorPoint[0].floatValue(),
-                neutralColorPoint[1].floatValue(), neutralColorPoint[2].floatValue()};
-
-        float[] neutralGuess = new float[3];
-        float[] interpXYZToCamera = new float[9];
-        float[] interpXYZToCameraInverse = new float[9];
-
-
-        double lower = Math.min(colorTemperature1, colorTemperature2);
-        double upper = Math.max(colorTemperature1, colorTemperature2);
-
-        if(DEBUG) {
-            Log.d(TAG, "XYZtoCamera1: " + Arrays.toString(XYZToCamera1));
-            Log.d(TAG, "XYZtoCamera2: " + Arrays.toString(XYZToCamera2));
-            Log.d(TAG, "Finding interpolation factor, initial guess 0.5...");
-        }
-        // Iteratively guess xy value, find new CCT, and update interpolation factor.
-        int loopLimit = 30;
-        int count = 0;
-        while (lastDiff > tolerance && loopLimit > 0) {
-            if (DEBUG) Log.d(TAG, "Loop count " + count);
-            lerp(XYZToCamera1, XYZToCamera2, interpFactor, interpXYZToCamera);
-            if (!invert(interpXYZToCamera, /*out*/interpXYZToCameraInverse)) {
-                throw new IllegalArgumentException(
-                        "Cannot invert XYZ to Camera matrix, input matrices are invalid.");
-            }
-
-            map(interpXYZToCameraInverse, cameraNeutral, /*out*/neutralGuess);
-            double[] xy = calculateCIExyCoordinates(neutralGuess[0], neutralGuess[1],
-                    neutralGuess[2]);
-
-            double colorTemperature = calculateColorTemperature(xy[0], xy[1]);
-
-            if (colorTemperature <= lower) {
-                interpFactor = 1;
-            } else if (colorTemperature >= upper) {
-                interpFactor = 0;
-            } else {
-                double invCT = 1.0 / colorTemperature;
-                interpFactor = (invCT - 1.0 / upper) / ( 1.0 / lower - 1.0 / upper);
-            }
-
-            if (lower == colorTemperature1) {
-                interpFactor = 1.0 - interpFactor;
-            }
-
-            interpFactor = (interpFactor + oldInterpFactor) / 2;
-            lastDiff = Math.abs(oldInterpFactor - interpFactor);
-            oldInterpFactor = interpFactor;
-            loopLimit--;
-            count++;
-
-            if (DEBUG) {
-                Log.d(TAG, "CameraToXYZ chosen: " + Arrays.toString(interpXYZToCameraInverse));
-                Log.d(TAG, "XYZ neutral color guess: " + Arrays.toString(neutralGuess));
-                Log.d(TAG, "xy coordinate: " + Arrays.toString(xy));
-                Log.d(TAG, "xy color temperature: " + colorTemperature);
-                Log.d(TAG, "New interpolation factor: " + interpFactor);
-            }
-        }
-
-        if (loopLimit == 0) {
-            Log.w(TAG, "Could not converge on interpolation factor, using factor " + interpFactor +
-                    " with remaining error factor of " + lastDiff);
-        }
-        return interpFactor;
-    }
-
-    /**
-     * Calculate the transform from the raw camera sensor colorspace to CIE XYZ colorspace with a
-     * D50 whitepoint.
-     *
-     * @param forwardTransform1 forward transform matrix corresponding to the first reference
-     *                          illuminant.
-     * @param forwardTransform2 forward transform matrix corresponding to the second reference
-     *                          illuminant.
-     * @param calibrationTransform1 calibration transform matrix corresponding to the first
-     *                              reference illuminant.
-     * @param calibrationTransform2 calibration transform matrix corresponding to the second
-     *                              reference illuminant.
-     * @param neutralColorPoint the neutral color point used to calculate the interpolation factor.
-     * @param interpolationFactor the interpolation factor to use for the forward and
-     *                            calibration transforms.
-     * @param outputTransform set to the full sensor to XYZ colorspace transform.
-     */
-    private static void calculateCameraToXYZD50Transform(float[] forwardTransform1,
-            float[] forwardTransform2, float[] calibrationTransform1, float[] calibrationTransform2,
-            Rational[/*3*/] neutralColorPoint, double interpolationFactor,
-            /*out*/float[] outputTransform) {
-        float[] cameraNeutral = new float[] { neutralColorPoint[0].floatValue(),
-                neutralColorPoint[1].floatValue(), neutralColorPoint[2].floatValue()};
-        if (DEBUG) Log.d(TAG, "Camera neutral: " + Arrays.toString(cameraNeutral));
-
-        float[] interpolatedCC = new float[9];
-        lerp(calibrationTransform1, calibrationTransform2, interpolationFactor,
-                interpolatedCC);
-        float[] inverseInterpolatedCC = new float[9];
-        if (!invert(interpolatedCC, /*out*/inverseInterpolatedCC)) {
-            throw new IllegalArgumentException( "Cannot invert interpolated calibration transform" +
-                    ", input matrices are invalid.");
-        }
-        if (DEBUG) Log.d(TAG, "Inverted interpolated CalibrationTransform: " +
-                Arrays.toString(inverseInterpolatedCC));
-
-        float[] referenceNeutral = new float[3];
-        map(inverseInterpolatedCC, cameraNeutral, /*out*/referenceNeutral);
-        if (DEBUG) Log.d(TAG, "Reference neutral: " + Arrays.toString(referenceNeutral));
-        float maxNeutral = Math.max(Math.max(referenceNeutral[0], referenceNeutral[1]),
-                referenceNeutral[2]);
-        float[] D = new float[] { maxNeutral/referenceNeutral[0], 0, 0,
-                                  0, maxNeutral/referenceNeutral[1], 0,
-                                  0, 0, maxNeutral/referenceNeutral[2] };
-        if (DEBUG) Log.d(TAG, "Reference Neutral Diagonal: " + Arrays.toString(D));
-
-        float[] intermediate = new float[9];
-        float[] intermediate2 = new float[9];
-
-        lerp(forwardTransform1, forwardTransform2, interpolationFactor, /*out*/intermediate);
-        if (DEBUG) Log.d(TAG, "Interpolated ForwardTransform: " + Arrays.toString(intermediate));
-
-        multiply(D, inverseInterpolatedCC, /*out*/intermediate2);
-        multiply(intermediate, intermediate2, /*out*/outputTransform);
-    }
-
-    /**
-     * Map a 3d column vector using the given matrix.
-     *
-     * @param matrix float array containing 3x3 matrix to map vector by.
-     * @param input 3 dimensional vector to map.
-     * @param output 3 dimensional vector result.
-     */
-    private static void map(float[] matrix, float[] input, /*out*/float[] output) {
-        output[0] = input[0] * matrix[0] + input[1] * matrix[1] + input[2] * matrix[2];
-        output[1] = input[0] * matrix[3] + input[1] * matrix[4] + input[2] * matrix[5];
-        output[2] = input[0] * matrix[6] + input[1] * matrix[7] + input[2] * matrix[8];
-    }
-
-    /**
-     * Multiply two 3x3 matrices together: A * B
-     *
-     * @param a left matrix.
-     * @param b right matrix.
-     */
-    private static void multiply(float[] a, float[] b, /*out*/float[] output) {
-        output[0] = a[0] * b[0] + a[1] * b[3] + a[2] * b[6];
-        output[3] = a[3] * b[0] + a[4] * b[3] + a[5] * b[6];
-        output[6] = a[6] * b[0] + a[7] * b[3] + a[8] * b[6];
-        output[1] = a[0] * b[1] + a[1] * b[4] + a[2] * b[7];
-        output[4] = a[3] * b[1] + a[4] * b[4] + a[5] * b[7];
-        output[7] = a[6] * b[1] + a[7] * b[4] + a[8] * b[7];
-        output[2] = a[0] * b[2] + a[1] * b[5] + a[2] * b[8];
-        output[5] = a[3] * b[2] + a[4] * b[5] + a[5] * b[8];
-        output[8] = a[6] * b[2] + a[7] * b[5] + a[8] * b[8];
-    }
-
-    /**
-     * Transpose a 3x3 matrix in-place.
-     *
-     * @param m the matrix to transpose.
-     * @return the transposed matrix.
-     */
-    private static float[] transpose(/*inout*/float[/*9*/] m) {
-        float t = m[1];
-        m[1] = m[3];
-        m[3] = t;
-        t = m[2];
-        m[2] = m[6];
-        m[6] = t;
-        t = m[5];
-        m[5] = m[7];
-        m[7] = t;
-        return m;
-    }
-
-    /**
-     * Invert a 3x3 matrix, or return false if the matrix is singular.
-     *
-     * @param m matrix to invert.
-     * @param output set the output to be the inverse of m.
-     */
-    private static boolean invert(float[] m, /*out*/float[] output) {
-        double a00 = m[0];
-        double a01 = m[1];
-        double a02 = m[2];
-        double a10 = m[3];
-        double a11 = m[4];
-        double a12 = m[5];
-        double a20 = m[6];
-        double a21 = m[7];
-        double a22 = m[8];
-
-        double t00 = a11 * a22 - a21 * a12;
-        double t01 = a21 * a02 - a01 * a22;
-        double t02 = a01 * a12 - a11 * a02;
-        double t10 = a20 * a12 - a10 * a22;
-        double t11 = a00 * a22 - a20 * a02;
-        double t12 = a10 * a02 - a00 * a12;
-        double t20 = a10 * a21 - a20 * a11;
-        double t21 = a20 * a01 - a00 * a21;
-        double t22 = a00 * a11 - a10 * a01;
-
-        double det = a00 * t00 + a01 * t10 + a02 * t20;
-        if (Math.abs(det) < 1e-9) {
-            return false; // Inverse too close to zero, not invertible.
-        }
-
-        output[0] = (float) (t00 / det);
-        output[1] = (float) (t01 / det);
-        output[2] = (float) (t02 / det);
-        output[3] = (float) (t10 / det);
-        output[4] = (float) (t11 / det);
-        output[5] = (float) (t12 / det);
-        output[6] = (float) (t20 / det);
-        output[7] = (float) (t21 / det);
-        output[8] = (float) (t22 / det);
-        return true;
-    }
-
-    /**
-     * Scale each element in a matrix by the given scaling factor.
-     *
-     * @param factor factor to scale by.
-     * @param matrix the float array containing a 3x3 matrix to scale.
-     */
-    private static void scale(float factor, /*inout*/float[] matrix) {
-        for (int i = 0; i < 9; i++) {
-            matrix[i] *= factor;
-        }
-    }
-
-    /**
-     * Clamp a value to a given range.
-     *
-     * @param low lower bound to clamp to.
-     * @param high higher bound to clamp to.
-     * @param value the value to clamp.
-     * @return the clamped value.
-     */
-    private static double clamp(double low, double high, double value) {
-        return Math.max(low, Math.min(high, value));
-    }
-
-    /**
-     * Return the max float in the array.
-     *
-     * @param array array of floats to search.
-     * @return max float in the array.
-     */
-    private static float max(float[] array) {
-        float val = array[0];
-        for (float f : array) {
-            val = (f > val) ? f : val;
-        }
-        return val;
-    }
-
-    /**
-     * Normalize ColorMatrix to eliminate headroom for input space scaled to [0, 1] using
-     * the D50 whitepoint.  This maps the D50 whitepoint into the colorspace used by the
-     * ColorMatrix, then uses the resulting whitepoint to renormalize the ColorMatrix so
-     * that the channel values in the resulting whitepoint for this operation are clamped
-     * to the range [0, 1].
-     *
-     * @param colorMatrix a 3x3 matrix containing a DNG ColorMatrix to be normalized.
-     */
-    private static void normalizeCM(/*inout*/float[] colorMatrix) {
-        float[] tmp = new float[3];
-        map(colorMatrix, D50_XYZ, /*out*/tmp);
-        float maxVal = max(tmp);
-        if (maxVal > 0) {
-            scale(1.0f / maxVal, colorMatrix);
-        }
-    }
-
-    /**
-     * Normalize ForwardMatrix to ensure that sensor whitepoint [1, 1, 1] maps to D50 in CIE XYZ
-     * colorspace.
-     *
-     * @param forwardMatrix a 3x3 matrix containing a DNG ForwardTransform to be normalized.
-     */
-    private static void normalizeFM(/*inout*/float[] forwardMatrix) {
-        float[] tmp = new float[] {1, 1, 1};
-        float[] xyz = new float[3];
-        map(forwardMatrix, tmp, /*out*/xyz);
-
-        float[] intermediate = new float[9];
-        float[] m = new float[] {1.0f / xyz[0], 0, 0, 0, 1.0f / xyz[1], 0, 0, 0, 1.0f / xyz[2]};
-
-        multiply(m, forwardMatrix, /*out*/ intermediate);
-        float[] m2 = new float[] {D50_XYZ[0], 0, 0, 0, D50_XYZ[1], 0, 0, 0, D50_XYZ[2]};
-        multiply(m2, intermediate, /*out*/forwardMatrix);
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
deleted file mode 100644
index 8e4c8e9..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/RenderScriptSingleton.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 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.hardware.camera2.cts.rs;
-
-import android.content.Context;
-import android.renderscript.RenderScript;
-import android.util.Log;
-
-// TODO : Replace with dependency injection
-/**
- * Singleton to hold {@link RenderScript} and {@link AllocationCache} objects.
- *
- * <p>The test method must call {@link #setContext} before attempting to retrieve
- * the underlying objects.</p> *
- */
-public class RenderScriptSingleton {
-
-    private static final String TAG = "RenderScriptSingleton";
-
-    private static Context sContext;
-    private static RenderScript sRS;
-    private static AllocationCache sCache;
-
-    /**
-     * Initialize the singletons from the given context; the
-     * {@link RenderScript} and {@link AllocationCache} objects are instantiated.
-     *
-     * @param context a non-{@code null} Context.
-     *
-     * @throws IllegalStateException If this was called repeatedly without {@link #clearContext}
-     */
-    public static synchronized void setContext(Context context) {
-        if (context.equals(sContext)) {
-            return;
-        } else if (sContext != null) {
-            Log.v(TAG,
-                    "Trying to set new context " + context +
-                    ", before clearing previous "+ sContext);
-            throw new IllegalStateException(
-                    "Call #clearContext before trying to set a new context");
-        }
-
-        sRS = RenderScript.create(context);
-        sContext = context;
-        sCache = new AllocationCache(sRS);
-    }
-
-    /**
-     * Clean up the singletons from the given context; the
-     * {@link RenderScript} and {@link AllocationCache} objects are destroyed.
-     *
-     * <p>Safe to call multiple times; subsequent invocations have no effect.</p>
-     */
-    public static synchronized void clearContext() {
-        if (sContext != null) {
-            sCache.close();
-            sCache = null;
-
-            sRS.destroy();
-            sRS = null;
-            sContext = null;
-        }
-    }
-
-    /**
-     * Get the current {@link RenderScript} singleton.
-     *
-     * @return A non-{@code null} {@link RenderScript} object.
-     *
-     * @throws IllegalStateException if {@link #setContext} was not called prior to this
-     */
-    public static synchronized RenderScript getRS() {
-        if (sRS == null) {
-            throw new IllegalStateException("Call #setContext before using #get");
-        }
-
-        return sRS;
-    }
-    /**
-     * Get the current {@link AllocationCache} singleton.
-     *
-     * @return A non-{@code null} {@link AllocationCache} object.
-     *
-     * @throws IllegalStateException if {@link #setContext} was not called prior to this
-     */
-    public static synchronized AllocationCache getCache() {
-        if (sCache == null) {
-            throw new IllegalStateException("Call #setContext before using #getCache");
-        }
-
-        return sCache;
-    }
-
-    // Suppress default constructor for noninstantiability
-    private RenderScriptSingleton() { throw new AssertionError(); }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/raw_converter.rs b/tests/tests/hardware/src/android/hardware/camera2/cts/rs/raw_converter.rs
deleted file mode 100644
index c8b353e..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/rs/raw_converter.rs
+++ /dev/null
@@ -1,369 +0,0 @@
-/*
- * 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.
- */
-
-#include "../common.rs"
-
-// This file includes a conversion kernel for RGGB, GRBG, GBRG, and BGGR Bayer patterns.
-// Applying this script also will apply black-level subtraction, rescaling, clipping, tonemapping,
-// and color space transforms along with the Bayer demosaic.  See RawConverter.java
-// for more information.
-
-// Input globals
-
-rs_allocation inputRawBuffer; // RAW16 buffer of dimensions (raw image stride) * (raw image height)
-rs_allocation gainMap; // Gainmap to apply to linearized raw sensor data.
-uint cfaPattern; // The Color Filter Arrangement pattern used
-uint gainMapWidth;  // The width of the gain map
-uint gainMapHeight;  // The height of the gain map
-bool hasGainMap; // Does gainmap exist?
-rs_matrix3x3 sensorToIntermediate; // Color transform from sensor to a wide-gamut colorspace
-rs_matrix3x3 intermediateToSRGB; // Color transform from wide-gamut colorspace to sRGB
-ushort4 blackLevelPattern; // Blacklevel to subtract for each channel, given in CFA order
-int whiteLevel;  // Whitelevel of sensor
-uint offsetX; // X offset into inputRawBuffer
-uint offsetY; // Y offset into inputRawBuffer
-uint rawWidth; // Width of raw buffer
-uint rawHeight; // Height of raw buffer
-float3 neutralPoint; // The camera neutral
-float4 toneMapCoeffs; // Coefficients for a polynomial tonemapping curve
-
-// Interpolate gain map to find per-channel gains at a given pixel
-static float4 getGain(uint x, uint y) {
-    float interpX = (((float) x) / rawWidth) * gainMapWidth;
-    float interpY = (((float) y) / rawHeight) * gainMapHeight;
-    uint gX = (uint) interpX;
-    uint gY = (uint) interpY;
-    uint gXNext = (gX + 1 < gainMapWidth) ? gX + 1 : gX;
-    uint gYNext = (gY + 1 < gainMapHeight) ? gY + 1 : gY;
-
-    float4 tl = *((float4 *) rsGetElementAt(gainMap, gX, gY));
-    float4 tr = *((float4 *) rsGetElementAt(gainMap, gXNext, gY));
-    float4 bl = *((float4 *) rsGetElementAt(gainMap, gX, gYNext));
-    float4 br = *((float4 *) rsGetElementAt(gainMap, gXNext, gYNext));
-
-    float fracX = interpX - (float) gX;
-    float fracY = interpY - (float) gY;
-    float invFracX = 1.f - fracX;
-    float invFracY = 1.f - fracY;
-
-    return tl * invFracX * invFracY + tr * fracX * invFracY +
-            bl * invFracX * fracY + br * fracX * fracY;
-}
-
-// Apply gamma correction using sRGB gamma curve
-static float gammaEncode(float x) {
-    return (x <= 0.0031308f) ? x * 12.92f : 1.055f * pow(x, 0.4166667f) - 0.055f;
-}
-
-// Apply gamma correction to each color channel in RGB pixel
-static float3 gammaCorrectPixel(float3 rgb) {
-    float3 ret;
-    ret.x = gammaEncode(rgb.x);
-    ret.y = gammaEncode(rgb.y);
-    ret.z = gammaEncode(rgb.z);
-    return ret;
-}
-
-// Apply polynomial tonemapping curve to each color channel in RGB pixel.
-// This attempts to apply tonemapping without changing the hue of each pixel,
-// i.e.:
-//
-// For some RGB values:
-// M = max(R, G, B)
-// m = min(R, G, B)
-// m' = mid(R, G, B)
-// chroma = M - m
-// H = m' - m / chroma
-//
-// The relationship H=H' should be preserved, where H and H' are calculated from
-// the RGB and RGB' value at this pixel before and after this tonemapping
-// operation has been applied, respectively.
-static float3 tonemap(float3 rgb) {
-    float3 sorted = clamp(rgb, 0.f, 1.f);
-    float tmp;
-    int permutation = 0;
-
-    // Sort the RGB channels by value
-    if (sorted.z < sorted.y) {
-        tmp = sorted.z;
-        sorted.z = sorted.y;
-        sorted.y = tmp;
-        permutation |= 1;
-    }
-    if (sorted.y < sorted.x) {
-        tmp = sorted.y;
-        sorted.y = sorted.x;
-        sorted.x = tmp;
-        permutation |= 2;
-    }
-    if (sorted.z < sorted.y) {
-        tmp = sorted.z;
-        sorted.z = sorted.y;
-        sorted.y = tmp;
-        permutation |= 4;
-    }
-
-    float2 minmax;
-    minmax.x = sorted.x;
-    minmax.y = sorted.z;
-
-    // Apply tonemapping curve to min, max RGB channel values
-    minmax = native_powr(minmax, 3.f) * toneMapCoeffs.x +
-            native_powr(minmax, 2.f) * toneMapCoeffs.y +
-            minmax * toneMapCoeffs.z + toneMapCoeffs.w;
-
-    // Rescale middle value
-    float newMid;
-    if (sorted.z == sorted.x) {
-        newMid = minmax.y;
-    } else {
-        newMid = minmax.x + ((minmax.y - minmax.x) * (sorted.y - sorted.x) /
-                (sorted.z - sorted.x));
-    }
-
-    float3 finalRGB;
-    switch (permutation) {
-        case 0: // b >= g >= r
-            finalRGB.x = minmax.x;
-            finalRGB.y = newMid;
-            finalRGB.z = minmax.y;
-            break;
-        case 1: // g >= b >= r
-            finalRGB.x = minmax.x;
-            finalRGB.z = newMid;
-            finalRGB.y = minmax.y;
-            break;
-        case 2: // b >= r >= g
-            finalRGB.y = minmax.x;
-            finalRGB.x = newMid;
-            finalRGB.z = minmax.y;
-            break;
-        case 3: // g >= r >= b
-            finalRGB.z = minmax.x;
-            finalRGB.x = newMid;
-            finalRGB.y = minmax.y;
-            break;
-        case 6: // r >= b >= g
-            finalRGB.y = minmax.x;
-            finalRGB.z = newMid;
-            finalRGB.x = minmax.y;
-            break;
-        case 7: // r >= g >= b
-            finalRGB.z = minmax.x;
-            finalRGB.y = newMid;
-            finalRGB.x = minmax.y;
-            break;
-        case 4: // impossible
-        case 5: // impossible
-        default:
-            LOGD("raw_converter.rs: Logic error in tonemap.", 0);
-            break;
-    }
-    return clamp(finalRGB, 0.f, 1.f);
-}
-
-// Apply a colorspace transform to the intermediate colorspace, apply
-// a tonemapping curve, apply a colorspace transform to a final colorspace,
-// and apply a gamma correction curve.
-static float3 applyColorspace(float3 pRGB) {
-    pRGB.x = clamp(pRGB.x, 0.f, neutralPoint.x);
-    pRGB.y = clamp(pRGB.y, 0.f, neutralPoint.y);
-    pRGB.z = clamp(pRGB.z, 0.f, neutralPoint.z);
-
-    float3 intermediate = rsMatrixMultiply(&sensorToIntermediate, pRGB);
-    intermediate = tonemap(intermediate);
-    return gammaCorrectPixel(clamp(rsMatrixMultiply(&intermediateToSRGB, intermediate), 0.f, 1.f));
-}
-
-// Load a 3x3 patch of pixels into the output.
-static void load3x3(uint x, uint y, rs_allocation buf, /*out*/float* outputArray) {
-    outputArray[0] = *((ushort *) rsGetElementAt(buf, x - 1, y - 1));
-    outputArray[1] = *((ushort *) rsGetElementAt(buf, x, y - 1));
-    outputArray[2] = *((ushort *) rsGetElementAt(buf, x + 1, y - 1));
-    outputArray[3] = *((ushort *) rsGetElementAt(buf, x - 1, y));
-    outputArray[4] = *((ushort *) rsGetElementAt(buf, x, y));
-    outputArray[5] = *((ushort *) rsGetElementAt(buf, x + 1, y));
-    outputArray[6] = *((ushort *) rsGetElementAt(buf, x - 1, y + 1));
-    outputArray[7] = *((ushort *) rsGetElementAt(buf, x, y + 1));
-    outputArray[8] = *((ushort *) rsGetElementAt(buf, x + 1, y + 1));
-}
-
-// Blacklevel subtract, and normalize each pixel in the outputArray, and apply the
-// gain map.
-static void linearizeAndGainmap(uint x, uint y, ushort4 blackLevel, int whiteLevel,
-        uint cfa, /*inout*/float* outputArray) {
-    uint kk = 0;
-    for (uint j = y - 1; j <= y + 1; j++) {
-        for (uint i = x - 1; i <= x + 1; i++) {
-            uint index = (i & 1) | ((j & 1) << 1);  // bits [0,1] are blacklevel offset
-            index |= (cfa << 2);  // bits [2,3] are cfa
-            float bl = 0.f;
-            float g = 1.f;
-            float4 gains = 1.f;
-            if (hasGainMap) {
-                gains = getGain(i, j);
-            }
-            switch (index) {
-                // RGGB
-                case 0:
-                    bl = blackLevel.x;
-                    g = gains.x;
-                    break;
-                case 1:
-                    bl = blackLevel.y;
-                    g = gains.y;
-                    break;
-                case 2:
-                    bl = blackLevel.z;
-                    g = gains.z;
-                    break;
-                case 3:
-                    bl = blackLevel.w;
-                    g = gains.w;
-                    break;
-                // GRBG
-                case 4:
-                    bl = blackLevel.x;
-                    g = gains.y;
-                    break;
-                case 5:
-                    bl = blackLevel.y;
-                    g = gains.x;
-                    break;
-                case 6:
-                    bl = blackLevel.z;
-                    g = gains.w;
-                    break;
-                case 7:
-                    bl = blackLevel.w;
-                    g = gains.z;
-                    break;
-                // GBRG
-                case 8:
-                    bl = blackLevel.x;
-                    g = gains.y;
-                    break;
-                case 9:
-                    bl = blackLevel.y;
-                    g = gains.w;
-                    break;
-                case 10:
-                    bl = blackLevel.z;
-                    g = gains.x;
-                    break;
-                case 11:
-                    bl = blackLevel.w;
-                    g = gains.z;
-                    break;
-                // BGGR
-                case 12:
-                    bl = blackLevel.x;
-                    g = gains.w;
-                    break;
-                case 13:
-                    bl = blackLevel.y;
-                    g = gains.y;
-                    break;
-                case 14:
-                    bl = blackLevel.z;
-                    g = gains.z;
-                    break;
-                case 15:
-                    bl = blackLevel.w;
-                    g = gains.x;
-                    break;
-            }
-            outputArray[kk] = clamp(g * (outputArray[kk] - bl) / (whiteLevel - bl), 0.f, 1.f);
-            kk++;
-        }
-    }
-}
-
-// Apply bilinear-interpolation to demosaic
-static float3 demosaic(uint x, uint y, uint cfa, float* inputArray) {
-    uint index = (x & 1) | ((y & 1) << 1);
-    index |= (cfa << 2);
-    float3 pRGB;
-    switch (index) {
-        case 0:
-        case 5:
-        case 10:
-        case 15:  // Red centered
-                  // B G B
-                  // G R G
-                  // B G B
-            pRGB.x = inputArray[4];
-            pRGB.y = (inputArray[1] + inputArray[3] + inputArray[5] + inputArray[7]) / 4;
-            pRGB.z = (inputArray[0] + inputArray[2] + inputArray[6] + inputArray[8]) / 4;
-            break;
-        case 1:
-        case 4:
-        case 11:
-        case 14: // Green centered w/ horizontally adjacent Red
-                 // G B G
-                 // R G R
-                 // G B G
-            pRGB.x = (inputArray[3] + inputArray[5]) / 2;
-            pRGB.y = inputArray[4];
-            pRGB.z = (inputArray[1] + inputArray[7]) / 2;
-            break;
-        case 2:
-        case 7:
-        case 8:
-        case 13: // Green centered w/ horizontally adjacent Blue
-                 // G R G
-                 // B G B
-                 // G R G
-            pRGB.x = (inputArray[1] + inputArray[7]) / 2;
-            pRGB.y = inputArray[4];
-            pRGB.z = (inputArray[3] + inputArray[5]) / 2;
-            break;
-        case 3:
-        case 6:
-        case 9:
-        case 12: // Blue centered
-                 // R G R
-                 // G B G
-                 // R G R
-            pRGB.x = (inputArray[0] + inputArray[2] + inputArray[6] + inputArray[8]) / 4;
-            pRGB.y = (inputArray[1] + inputArray[3] + inputArray[5] + inputArray[7]) / 4;
-            pRGB.z = inputArray[4];
-            break;
-    }
-
-    return pRGB;
-}
-
-// Full RAW->ARGB bitmap conversion kernel
-uchar4 RS_KERNEL convert_RAW_To_ARGB(uint x, uint y) {
-    float3 pRGB;
-    uint xP = x + offsetX;
-    uint yP = y + offsetY;
-    if (xP == 0) xP = 1;
-    if (yP == 0) yP = 1;
-    if (xP == rawWidth - 1) xP = rawWidth - 2;
-    if (yP == rawHeight - 1) yP = rawHeight  - 2;
-
-    float patch[9];
-    // TODO: Once ScriptGroup and RS kernels have been updated to allow for iteration over 3x3 pixel
-    // patches, this can be optimized to avoid re-applying the pre-demosaic steps for each pixel,
-    // potentially achieving a 9x speedup here.
-    load3x3(xP, yP, inputRawBuffer, /*out*/ patch);
-    linearizeAndGainmap(xP, yP, blackLevelPattern, whiteLevel, cfaPattern, /*inout*/patch);
-    pRGB = demosaic(xP, yP, cfaPattern, patch);
-
-    return rsPackColorTo8888(applyColorspace(pRGB));
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
deleted file mode 100644
index ff69581..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2AndroidTestCase.java
+++ /dev/null
@@ -1,331 +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.hardware.camera2.cts.testcases;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static com.android.ex.camera2.blocking.BlockingStateCallback.*;
-
-import android.content.Context;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.CaptureRequest;
-import android.util.Size;
-import android.hardware.camera2.cts.CameraTestUtils;
-import android.hardware.camera2.cts.helpers.CameraErrorCollector;
-import android.hardware.camera2.cts.helpers.StaticMetadata;
-import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
-import android.media.Image;
-import android.media.ImageReader;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.test.AndroidTestCase;
-import android.util.Log;
-import android.view.Surface;
-import android.view.WindowManager;
-
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-
-import java.util.List;
-
-public class Camera2AndroidTestCase extends AndroidTestCase {
-    private static final String TAG = "Camera2AndroidTestCase";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-
-    protected static final String DEBUG_FILE_NAME_BASE =
-            Environment.getExternalStorageDirectory().getPath();
-    // Default capture size: VGA size is required by CDD.
-    protected static final Size DEFAULT_CAPTURE_SIZE = new Size(640, 480);
-    protected static final int CAPTURE_WAIT_TIMEOUT_MS = 5000;
-
-    protected CameraManager mCameraManager;
-    protected CameraDevice mCamera;
-    protected CameraCaptureSession mCameraSession;
-    protected BlockingSessionCallback mCameraSessionListener;
-    protected BlockingStateCallback mCameraListener;
-    protected String[] mCameraIds;
-    protected ImageReader mReader;
-    protected Surface mReaderSurface;
-    protected Handler mHandler;
-    protected HandlerThread mHandlerThread;
-    protected StaticMetadata mStaticInfo;
-    protected CameraErrorCollector mCollector;
-    protected List<Size> mOrderedPreviewSizes; // In descending order.
-    protected List<Size> mOrderedVideoSizes; // In descending order.
-    protected List<Size> mOrderedStillSizes; // In descending order.
-
-    protected WindowManager mWindowManager;
-
-    @Override
-    public void setContext(Context context) {
-        super.setContext(context);
-        mCameraManager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
-        assertNotNull("Can't connect to camera manager!", mCameraManager);
-        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-    }
-
-    /**
-     * Set up the camera2 test case required environments, including CameraManager,
-     * HandlerThread, Camera IDs, and CameraStateCallback etc.
-     */
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        /**
-         * Workaround for mockito and JB-MR2 incompatibility
-         *
-         * Avoid java.lang.IllegalArgumentException: dexcache == null
-         * https://code.google.com/p/dexmaker/issues/detail?id=2
-         */
-        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
-
-        mCameraIds = mCameraManager.getCameraIdList();
-        assertNotNull("Camera ids shouldn't be null", mCameraIds);
-        mHandlerThread = new HandlerThread(TAG);
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-        mCameraListener = new BlockingStateCallback();
-        mCollector = new CameraErrorCollector();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mHandlerThread.quitSafely();
-        mHandler = null;
-        closeDefaultImageReader();
-
-        try {
-            mCollector.verify();
-        } catch (Throwable e) {
-            // When new Exception(e) is used, exception info will be printed twice.
-            throw new Exception(e.getMessage());
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    /**
-     * Start capture with given {@link #CaptureRequest}.
-     *
-     * @param request The {@link #CaptureRequest} to be captured.
-     * @param repeating If the capture is single capture or repeating.
-     * @param listener The {@link #CaptureCallback} camera device used to notify callbacks.
-     * @param handler The handler camera device used to post callbacks.
-     */
-    protected void startCapture(CaptureRequest request, boolean repeating,
-            CaptureCallback listener, Handler handler) throws Exception {
-        if (VERBOSE) Log.v(TAG, "Starting capture from device");
-
-        if (repeating) {
-            mCameraSession.setRepeatingRequest(request, listener, handler);
-        } else {
-            mCameraSession.capture(request, listener, handler);
-        }
-    }
-
-    /**
-     * Stop the current active capture.
-     *
-     * @param fast When it is true, {@link CameraDevice#flush} is called, the stop capture
-     * could be faster.
-     */
-    protected void stopCapture(boolean fast) throws Exception {
-        if (VERBOSE) Log.v(TAG, "Stopping capture");
-
-        if (fast) {
-            /**
-             * Flush is useful for canceling long exposure single capture, it also could help
-             * to make the streaming capture stop sooner.
-             */
-            mCameraSession.abortCaptures();
-            mCameraSessionListener.getStateWaiter().
-                    waitForState(BlockingSessionCallback.SESSION_READY, CAMERA_IDLE_TIMEOUT_MS);
-        } else {
-            mCameraSession.close();
-            mCameraSessionListener.getStateWaiter().
-                    waitForState(BlockingSessionCallback.SESSION_CLOSED, CAMERA_IDLE_TIMEOUT_MS);
-        }
-    }
-
-    /**
-     * Open a {@link #CameraDevice camera device} and get the StaticMetadata for a given camera id.
-     * The default mCameraListener is used to wait for states.
-     *
-     * @param cameraId The id of the camera device to be opened.
-     */
-    protected void openDevice(String cameraId) throws Exception {
-        openDevice(cameraId, mCameraListener);
-    }
-
-    /**
-     * Open a {@link #CameraDevice} and get the StaticMetadata for a given camera id and listener.
-     *
-     * @param cameraId The id of the camera device to be opened.
-     * @param listener The {@link #BlockingStateCallback} used to wait for states.
-     */
-    protected void openDevice(String cameraId, BlockingStateCallback listener) throws Exception {
-        mCamera = CameraTestUtils.openCamera(
-                mCameraManager, cameraId, listener, mHandler);
-        mCollector.setCameraId(cameraId);
-        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
-                CheckLevel.ASSERT, /*collector*/null);
-        mOrderedPreviewSizes = getSupportedPreviewSizes(
-                cameraId, mCameraManager,
-                getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
-        mOrderedVideoSizes = getSupportedVideoSizes(cameraId, mCameraManager, PREVIEW_SIZE_BOUND);
-        mOrderedStillSizes = getSupportedStillSizes(cameraId, mCameraManager, null);
-
-        if (VERBOSE) {
-            Log.v(TAG, "Camera " + cameraId + " is opened");
-        }
-    }
-
-    /**
-     * Create a {@link #CameraCaptureSession} using the currently open camera.
-     *
-     * @param outputSurfaces The set of output surfaces to configure for this session
-     */
-    protected void createSession(List<Surface> outputSurfaces) throws Exception {
-        mCameraSessionListener = new BlockingSessionCallback();
-        mCameraSession = CameraTestUtils.configureCameraSession(mCamera, outputSurfaces,
-                mCameraSessionListener, mHandler);
-    }
-
-    /**
-     * Close a {@link #CameraDevice camera device} and clear the associated StaticInfo field for a
-     * given camera id. The default mCameraListener is used to wait for states.
-     * <p>
-     * This function must be used along with the {@link #openDevice} for the
-     * same camera id.
-     * </p>
-     *
-     * @param cameraId The id of the {@link #CameraDevice camera device} to be closed.
-     */
-    protected void closeDevice(String cameraId) {
-        closeDevice(cameraId, mCameraListener);
-    }
-
-    /**
-     * Close a {@link #CameraDevice camera device} and clear the associated StaticInfo field for a
-     * given camera id and listener.
-     * <p>
-     * This function must be used along with the {@link #openDevice} for the
-     * same camera id.
-     * </p>
-     *
-     * @param cameraId The id of the camera device to be closed.
-     * @param listener The BlockingStateCallback used to wait for states.
-     */
-    protected void closeDevice(String cameraId, BlockingStateCallback listener) {
-        if (mCamera != null) {
-            if (!cameraId.equals(mCamera.getId())) {
-                throw new IllegalStateException("Try to close a device that is not opened yet");
-            }
-            mCamera.close();
-            listener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
-            mCamera = null;
-            mCameraSession = null;
-            mCameraSessionListener = null;
-            mStaticInfo = null;
-            mOrderedPreviewSizes = null;
-            mOrderedVideoSizes = null;
-            mOrderedStillSizes = null;
-
-            if (VERBOSE) {
-                Log.v(TAG, "Camera " + cameraId + " is closed");
-            }
-        }
-    }
-
-    /**
-     * Create an {@link ImageReader} object and get the surface.
-     * <p>
-     * This function creates {@link ImageReader} object and surface, then assign
-     * to the default {@link mReader} and {@link mReaderSurface}. It closes the
-     * current default active {@link ImageReader} if it exists.
-     * </p>
-     *
-     * @param size The size of this ImageReader to be created.
-     * @param format The format of this ImageReader to be created
-     * @param maxNumImages The max number of images that can be acquired
-     *            simultaneously.
-     * @param listener The listener used by this ImageReader to notify
-     *            callbacks.
-     */
-    protected void createDefaultImageReader(Size size, int format, int maxNumImages,
-            ImageReader.OnImageAvailableListener listener) throws Exception {
-        closeDefaultImageReader();
-
-        mReader = createImageReader(size, format, maxNumImages, listener);
-        mReaderSurface = mReader.getSurface();
-        if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString());
-    }
-
-    /**
-     * Create an {@link ImageReader} object.
-     *
-     * <p>This function creates image reader object for given format, maxImages, and size.</p>
-     *
-     * @param size The size of this ImageReader to be created.
-     * @param format The format of this ImageReader to be created
-     * @param maxNumImages The max number of images that can be acquired simultaneously.
-     * @param listener The listener used by this ImageReader to notify callbacks.
-     */
-
-    protected ImageReader createImageReader(Size size, int format, int maxNumImages,
-            ImageReader.OnImageAvailableListener listener) throws Exception {
-
-        ImageReader reader = ImageReader.newInstance(size.getWidth(), size.getHeight(),
-                format, maxNumImages);
-        reader.setOnImageAvailableListener(listener, mHandler);
-        if (VERBOSE) Log.v(TAG, "Created ImageReader size " + size.toString());
-        return reader;
-    }
-
-    /**
-     * Close the pending images then close current default {@link ImageReader} object.
-     */
-    protected void closeDefaultImageReader() {
-        closeImageReader(mReader);
-        mReader = null;
-        mReaderSurface = null;
-    }
-
-    /**
-     * Close an image reader instance.
-     *
-     * @param reader
-     */
-    protected void closeImageReader(ImageReader reader) {
-        if (reader != null) {
-            try {
-                // Close all possible pending images first.
-                Image image = reader.acquireLatestImage();
-                if (image != null) {
-                    image.close();
-                }
-            } finally {
-                reader.close();
-                reader = null;
-            }
-        }
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
deleted file mode 100644
index 5d832d6..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2MultiViewTestCase.java
+++ /dev/null
@@ -1,417 +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.hardware.camera2.cts.testcases;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static com.android.ex.camera2.blocking.BlockingSessionCallback.*;
-import static com.android.ex.camera2.blocking.BlockingStateCallback.*;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Matrix;
-import android.graphics.RectF;
-import android.graphics.SurfaceTexture;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.cts.Camera2MultiViewCtsActivity;
-import android.hardware.camera2.cts.helpers.StaticMetadata;
-import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
-import android.os.ConditionVariable;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-import android.util.Size;
-import android.view.Surface;
-import android.view.TextureView;
-import android.view.WindowManager;
-
-import com.android.ex.camera2.blocking.BlockingCameraManager;
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-
-import junit.framework.Assert;
-
-import java.util.List;
-import java.util.HashMap;
-
-/**
- * Camera2 test case base class by using mixed SurfaceView and TextureView as rendering target.
- */
-public class Camera2MultiViewTestCase extends
-        ActivityInstrumentationTestCase2<Camera2MultiViewCtsActivity> {
-    private static final String TAG = "MultiViewTestCase";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-
-
-    private static final long SHORT_SLEEP_WAIT_TIME_MS = 100;
-
-    protected TextureView[] mTextureView = new TextureView[2];
-    protected String[] mCameraIds;
-    protected Handler mHandler;
-
-    private CameraManager mCameraManager;
-    private BlockingStateCallback mCameraListener;
-    private HandlerThread mHandlerThread;
-    private Context mContext;
-
-    private CameraHolder[] mCameraHolders;
-    private HashMap<String, Integer> mCameraIdMap;
-
-    protected WindowManager mWindowManager;
-
-    public Camera2MultiViewTestCase() {
-        super(Camera2MultiViewCtsActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mContext = getActivity();
-        assertNotNull("Unable to get activity", mContext);
-        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
-        assertNotNull("Unable to get CameraManager", mCameraManager);
-        mCameraIds = mCameraManager.getCameraIdList();
-        assertNotNull("Unable to get camera ids", mCameraIds);
-        mHandlerThread = new HandlerThread(TAG);
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-        mCameraListener = new BlockingStateCallback();
-        Camera2MultiViewCtsActivity activity = (Camera2MultiViewCtsActivity) mContext;
-        mTextureView[0] = activity.getTextureView(0);
-        mTextureView[1] = activity.getTextureView(1);
-        assertNotNull("Unable to get texture view", mTextureView);
-        mCameraIdMap = new HashMap<String, Integer>();
-        int numCameras = mCameraIds.length;
-        mCameraHolders = new CameraHolder[numCameras];
-        for (int i = 0; i < numCameras; i++) {
-            mCameraHolders[i] = new CameraHolder(mCameraIds[i]);
-            mCameraIdMap.put(mCameraIds[i], i);
-        }
-        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mHandlerThread.quitSafely();
-        mHandler = null;
-        mCameraListener = null;
-        for (CameraHolder camera : mCameraHolders) {
-            if (camera.isOpenned()) {
-                camera.close();
-                camera = null;
-            }
-        }
-        super.tearDown();
-    }
-
-    /**
-     * Update preview TextureView rotation to accommodate discrepancy between preview
-     * buffer and the view window orientation.
-     *
-     * Assumptions:
-     * - Aspect ratio for the sensor buffers is in landscape orientation,
-     * - Dimensions of buffers received are rotated to the natural device orientation.
-     * - The contents of each buffer are rotated by the inverse of the display rotation.
-     * - Surface scales the buffer to fit the current view bounds.
-     * TODO: Make this method works for all orientations
-     *
-     */
-    protected void updatePreviewDisplayRotation(Size previewSize, TextureView textureView) {
-        int rotationDegrees = 0;
-        Camera2MultiViewCtsActivity activity = (Camera2MultiViewCtsActivity) mContext;
-        int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
-        Configuration config = activity.getResources().getConfiguration();
-
-        // Get UI display rotation
-        switch (displayRotation) {
-            case Surface.ROTATION_0:
-                rotationDegrees = 0;
-                break;
-            case Surface.ROTATION_90:
-                rotationDegrees = 90;
-            break;
-            case Surface.ROTATION_180:
-                rotationDegrees = 180;
-            break;
-            case Surface.ROTATION_270:
-                rotationDegrees = 270;
-            break;
-        }
-
-        // Get device natural orientation
-        int deviceOrientation = Configuration.ORIENTATION_PORTRAIT;
-        if ((rotationDegrees % 180 == 0 &&
-                config.orientation == Configuration.ORIENTATION_LANDSCAPE) ||
-                ((rotationDegrees % 180 != 0 &&
-                config.orientation == Configuration.ORIENTATION_PORTRAIT))) {
-            deviceOrientation = Configuration.ORIENTATION_LANDSCAPE;
-        }
-
-        // Rotate the buffer dimensions if device orientation is portrait.
-        int effectiveWidth = previewSize.getWidth();
-        int effectiveHeight = previewSize.getHeight();
-        if (deviceOrientation == Configuration.ORIENTATION_PORTRAIT) {
-            effectiveWidth = previewSize.getHeight();
-            effectiveHeight = previewSize.getWidth();
-        }
-
-        // Find and center view rect and buffer rect
-        Matrix transformMatrix =  textureView.getTransform(null);
-        int viewWidth = textureView.getWidth();
-        int viewHeight = textureView.getHeight();
-        RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
-        RectF bufRect = new RectF(0, 0, effectiveWidth, effectiveHeight);
-        float centerX = viewRect.centerX();
-        float centerY = viewRect.centerY();
-        bufRect.offset(centerX - bufRect.centerX(), centerY - bufRect.centerY());
-
-        // Undo ScaleToFit.FILL done by the surface
-        transformMatrix.setRectToRect(viewRect, bufRect, Matrix.ScaleToFit.FILL);
-
-        // Rotate buffer contents to proper orientation
-        transformMatrix.postRotate((360 - rotationDegrees) % 360, centerX, centerY);
-        if ((rotationDegrees % 180) == 90) {
-            int temp = effectiveWidth;
-            effectiveWidth = effectiveHeight;
-            effectiveHeight = temp;
-        }
-
-        // Scale to fit view, cropping the longest dimension
-        float scale =
-                Math.max(viewWidth / (float) effectiveWidth, viewHeight / (float) effectiveHeight);
-        transformMatrix.postScale(scale, scale, centerX, centerY);
-
-        Handler handler = new Handler(Looper.getMainLooper());
-        class TransformUpdater implements Runnable {
-            TextureView mView;
-            Matrix mTransformMatrix;
-            TransformUpdater(TextureView view, Matrix matrix) {
-                mView = view;
-                mTransformMatrix = matrix;
-            }
-
-            @Override
-            public void run() {
-                mView.setTransform(mTransformMatrix);
-            }
-        }
-        handler.post(new TransformUpdater(textureView, transformMatrix));
-    }
-
-    protected void openCamera(String cameraId) throws Exception {
-        CameraHolder camera = getCameraHolder(cameraId);
-        assertFalse("Camera has already opened", camera.isOpenned());
-        camera.open();
-        return;
-    }
-
-    protected void closeCamera(String cameraId) throws Exception {
-        CameraHolder camera = getCameraHolder(cameraId);
-        camera.close();
-    }
-
-    protected void startPreview(
-            String cameraId, List<Surface> outputSurfaces, CaptureCallback listener)
-            throws Exception {
-        CameraHolder camera = getCameraHolder(cameraId);
-        assertTrue("Camera " + cameraId + " is not openned", camera.isOpenned());
-        camera.startPreview(outputSurfaces, listener);
-    }
-
-    protected void stopPreview(String cameraId) throws Exception {
-        CameraHolder camera = getCameraHolder(cameraId);
-        assertTrue("Camera " + cameraId + " preview is not running", camera.isPreviewStarted());
-        camera.stopPreview();
-    }
-
-    protected StaticMetadata getStaticInfo(String cameraId) {
-        CameraHolder camera = getCameraHolder(cameraId);
-        assertTrue("Camera is not openned", camera.isOpenned());
-        return camera.getStaticInfo();
-    }
-
-    protected List<Size> getOrderedPreviewSizes(String cameraId) {
-        CameraHolder camera = getCameraHolder(cameraId);
-        assertTrue("Camera is not openned", camera.isOpenned());
-        return camera.getOrderedPreviewSizes();
-    }
-
-    /**
-     * Wait until the SurfaceTexture available from the TextureView, then return it.
-     * Return null if the wait times out.
-     *
-     * @param timeOutMs The timeout value for the wait
-     * @return The available SurfaceTexture, return null if the wait times out.
-     */
-    protected SurfaceTexture getAvailableSurfaceTexture(long timeOutMs, TextureView view) {
-        long waitTime = timeOutMs;
-
-        while (!view.isAvailable() && waitTime > 0) {
-            long startTimeMs = SystemClock.elapsedRealtime();
-            SystemClock.sleep(SHORT_SLEEP_WAIT_TIME_MS);
-            waitTime -= (SystemClock.elapsedRealtime() - startTimeMs);
-        }
-
-        if (view.isAvailable()) {
-            return view.getSurfaceTexture();
-        } else {
-            Log.w(TAG, "Wait for SurfaceTexture available timed out after " + timeOutMs + "ms");
-            return null;
-        }
-    }
-
-    public static class CameraPreviewListener implements TextureView.SurfaceTextureListener {
-        private boolean mFirstPreviewAvailable = false;
-        private final ConditionVariable mPreviewDone = new ConditionVariable();
-
-        @Override
-        public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
-            // Ignored. The SurfaceTexture is polled by getAvailableSurfaceTexture.
-        }
-
-        @Override
-        public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
-            // Ignored. The CameraDevice should already know the changed size.
-        }
-
-        @Override
-        public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
-            /**
-             * Return true, assume that client detaches the surface before it is
-             * destroyed. For example, CameraDevice should detach this surface when
-             * stopping preview. No need to release the SurfaceTexture here as it
-             * is released by TextureView after onSurfaceTextureDestroyed is called.
-             */
-            Log.i(TAG, "onSurfaceTextureDestroyed called.");
-            return true;
-        }
-
-        @Override
-        public void onSurfaceTextureUpdated(SurfaceTexture surface) {
-            // Invoked every time there's a new Camera preview frame
-            if (!mFirstPreviewAvailable) {
-                mFirstPreviewAvailable = true;
-                mPreviewDone.open();
-            }
-        }
-
-        /** Waits until the camera preview is up running */
-        public boolean waitForPreviewDone(long timeOutMs) {
-            if (!mPreviewDone.block(timeOutMs)) {
-                // timeout could be expected or unexpected. The caller will decide.
-                Log.w(TAG, "waitForPreviewDone timed out after " + timeOutMs + "ms");
-                return false;
-            }
-            mPreviewDone.close();
-            return true;
-        }
-    }
-
-    private CameraHolder getCameraHolder(String cameraId) {
-        Integer cameraIdx = mCameraIdMap.get(cameraId);
-        if (cameraIdx == null) {
-            Assert.fail("Unknown camera Id");
-        }
-        return mCameraHolders[cameraIdx];
-    }
-
-    // Per device fields
-    private class CameraHolder {
-        private String mCameraId;
-        private CameraCaptureSession mSession;
-        private CameraDevice mCamera;
-        private StaticMetadata mStaticInfo;
-        private List<Size> mOrderedPreviewSizes;
-        private BlockingSessionCallback mSessionListener;
-
-        public CameraHolder(String id){
-            mCameraId = id;
-        }
-
-        public StaticMetadata getStaticInfo() {
-            return mStaticInfo;
-        }
-
-        public List<Size> getOrderedPreviewSizes() {
-            return mOrderedPreviewSizes;
-        }
-
-        public void open() throws Exception {
-            assertNull("Camera is already opened", mCamera);
-            mCamera = (new BlockingCameraManager(mCameraManager)).openCamera(
-                    mCameraId, mCameraListener, mHandler);
-            mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(mCameraId),
-                    CheckLevel.ASSERT, /*collector*/null);
-            mOrderedPreviewSizes = getSupportedPreviewSizes(
-                    mCameraId, mCameraManager,
-                    getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
-            assertNotNull(String.format("Failed to open camera device ID: %s", mCameraId), mCamera);
-        }
-
-        public boolean isOpenned() {
-            return (mCamera != null);
-        }
-
-        public void close() throws Exception {
-            if (!isOpenned()) {
-                return;
-            }
-            mCamera.close();
-            mCameraListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
-            mCamera = null;
-            mSession = null;
-            mStaticInfo = null;
-            mOrderedPreviewSizes = null;
-        }
-
-        public void startPreview(List<Surface> outputSurfaces, CaptureCallback listener)
-                throws Exception {
-            mSessionListener = new BlockingSessionCallback();
-            mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
-
-            // TODO: vary the different settings like crop region to cover more cases.
-            CaptureRequest.Builder captureBuilder =
-                    mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-
-            for (Surface surface : outputSurfaces) {
-                captureBuilder.addTarget(surface);
-            }
-            mSession.setRepeatingRequest(captureBuilder.build(), listener, mHandler);
-        }
-
-        public boolean isPreviewStarted() {
-            return (mSession != null);
-        }
-
-        public void stopPreview() throws Exception {
-            if (VERBOSE) Log.v(TAG,
-                    "Stopping camera " + mCameraId +" preview and waiting for idle");
-            // Stop repeat, wait for captures to complete, and disconnect from surfaces
-            mSession.close();
-            mSessionListener.getStateWaiter().waitForState(
-                    SESSION_CLOSED, SESSION_CLOSE_TIMEOUT_MS);
-            mSessionListener = null;
-        }
-    }
-}
-
diff --git a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java b/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
deleted file mode 100755
index f2a9aee..0000000
--- a/tests/tests/hardware/src/android/hardware/camera2/cts/testcases/Camera2SurfaceViewTestCase.java
+++ /dev/null
@@ -1,709 +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.hardware.camera2.cts.testcases;
-
-import static android.hardware.camera2.cts.CameraTestUtils.*;
-import static com.android.ex.camera2.blocking.BlockingStateCallback.STATE_CLOSED;
-
-import android.hardware.camera2.params.StreamConfigurationMap;
-import android.media.ImageReader;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.test.ActivityInstrumentationTestCase2;
-import android.util.Log;
-import android.view.Surface;
-import android.view.SurfaceHolder;
-import android.view.WindowManager;
-import android.content.Context;
-import android.graphics.ImageFormat;
-import android.hardware.camera2.CameraAccessException;
-import android.hardware.camera2.CameraCaptureSession;
-import android.hardware.camera2.CameraCaptureSession.CaptureCallback;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraDevice;
-import android.hardware.camera2.CameraManager;
-import android.hardware.camera2.CameraMetadata;
-import android.hardware.camera2.CaptureRequest;
-import android.hardware.camera2.CaptureResult;
-import android.util.Size;
-import android.util.Range;
-import android.hardware.camera2.cts.Camera2SurfaceViewCtsActivity;
-import android.hardware.camera2.cts.CameraTestUtils;
-import android.hardware.camera2.cts.CameraTestUtils.SimpleCaptureCallback;
-import android.hardware.camera2.cts.helpers.CameraErrorCollector;
-import android.hardware.camera2.cts.helpers.StaticMetadata;
-import android.hardware.camera2.cts.helpers.StaticMetadata.CheckLevel;
-
-import com.android.ex.camera2.blocking.BlockingSessionCallback;
-import com.android.ex.camera2.blocking.BlockingStateCallback;
-import com.android.ex.camera2.exceptions.TimeoutRuntimeException;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- * Camera2 Preview test case base class by using SurfaceView as rendering target.
- *
- * <p>This class encapsulates the SurfaceView based preview common functionalities.
- * The setup and teardown of CameraManager, test HandlerThread, Activity, Camera IDs
- * and CameraStateCallback are handled in this class. Some basic preview related utility
- * functions are provided to facilitate the derived preview-based test classes.
- * </p>
- */
-
-public class Camera2SurfaceViewTestCase extends
-        ActivityInstrumentationTestCase2<Camera2SurfaceViewCtsActivity> {
-    private static final String TAG = "SurfaceViewTestCase";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private static final int WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS = 1000;
-
-    // TODO: Use internal storage for this to make sure the file is only visible to test.
-    protected static final String DEBUG_FILE_NAME_BASE =
-            Environment.getExternalStorageDirectory().getPath();
-    protected static final int WAIT_FOR_RESULT_TIMEOUT_MS = 3000;
-    protected static final float FRAME_DURATION_ERROR_MARGIN = 0.005f; // 0.5 percent error margin.
-    protected static final int NUM_RESULTS_WAIT_TIMEOUT = 100;
-    protected static final int NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY = 8;
-
-    protected Context mContext;
-    protected CameraManager mCameraManager;
-    protected String[] mCameraIds;
-    protected HandlerThread mHandlerThread;
-    protected Handler mHandler;
-    protected BlockingStateCallback mCameraListener;
-    protected BlockingSessionCallback mSessionListener;
-    protected CameraErrorCollector mCollector;
-    // Per device fields:
-    protected StaticMetadata mStaticInfo;
-    protected CameraDevice mCamera;
-    protected CameraCaptureSession mSession;
-    protected ImageReader mReader;
-    protected Surface mReaderSurface;
-    protected Surface mOldReaderSurface;
-    protected Surface mPreviewSurface;
-    protected Size mPreviewSize;
-    protected List<Size> mOrderedPreviewSizes; // In descending order.
-    protected List<Size> mOrderedVideoSizes; // In descending order.
-    protected List<Size> mOrderedStillSizes; // In descending order.
-    protected HashMap<Size, Long> mMinPreviewFrameDurationMap;
-
-    protected WindowManager mWindowManager;
-
-    public Camera2SurfaceViewTestCase() {
-        super(Camera2SurfaceViewCtsActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        /**
-         * Set up the camera preview required environments, including activity,
-         * CameraManager, HandlerThread, Camera IDs, and CameraStateCallback.
-         */
-        super.setUp();
-        mContext = getActivity();
-        /**
-         * Workaround for mockito and JB-MR2 incompatibility
-         *
-         * Avoid java.lang.IllegalArgumentException: dexcache == null
-         * https://code.google.com/p/dexmaker/issues/detail?id=2
-         */
-        System.setProperty("dexmaker.dexcache", mContext.getCacheDir().toString());
-        mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
-        assertNotNull("Unable to get CameraManager", mCameraManager);
-        mCameraIds = mCameraManager.getCameraIdList();
-        assertNotNull("Unable to get camera ids", mCameraIds);
-        mHandlerThread = new HandlerThread(TAG);
-        mHandlerThread.start();
-        mHandler = new Handler(mHandlerThread.getLooper());
-        mCameraListener = new BlockingStateCallback();
-        mCollector = new CameraErrorCollector();
-
-        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Teardown the camera preview required environments.
-        mHandlerThread.quitSafely();
-        mHandler = null;
-        mCameraListener = null;
-
-        try {
-            mCollector.verify();
-        } catch (Throwable e) {
-            // When new Exception(e) is used, exception info will be printed twice.
-            throw new Exception(e.getMessage());
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    /**
-     * Start camera preview by using the given request, preview size and capture
-     * listener.
-     * <p>
-     * If preview is already started, calling this function will stop the
-     * current preview stream and start a new preview stream with given
-     * parameters. No need to call stopPreview between two startPreview calls.
-     * </p>
-     *
-     * @param request The request builder used to start the preview.
-     * @param previewSz The size of the camera device output preview stream.
-     * @param listener The callbacks the camera device will notify when preview
-     *            capture is available.
-     */
-    protected void startPreview(CaptureRequest.Builder request, Size previewSz,
-            CaptureCallback listener) throws Exception {
-        // Update preview size.
-        updatePreviewSurface(previewSz);
-        if (VERBOSE) {
-            Log.v(TAG, "start preview with size " + mPreviewSize.toString());
-        }
-
-        configurePreviewOutput(request);
-
-        mSession.setRepeatingRequest(request.build(), listener, mHandler);
-    }
-
-    /**
-     * Configure the preview output stream.
-     *
-     * @param request The request to be configured with preview surface
-     */
-    protected void configurePreviewOutput(CaptureRequest.Builder request)
-            throws CameraAccessException {
-        List<Surface> outputSurfaces = new ArrayList<Surface>(/*capacity*/1);
-        outputSurfaces.add(mPreviewSurface);
-        mSessionListener = new BlockingSessionCallback();
-        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
-
-        request.addTarget(mPreviewSurface);
-    }
-
-    /**
-     * Create a {@link CaptureRequest#Builder} and add the default preview surface.
-     *
-     * @return The {@link CaptureRequest#Builder} to be created
-     * @throws CameraAccessException When create capture request from camera fails
-     */
-    protected CaptureRequest.Builder createRequestForPreview() throws CameraAccessException {
-        if (mPreviewSurface == null) {
-            throw new IllegalStateException(
-                    "Preview surface is not set yet, call updatePreviewSurface or startPreview"
-                    + "first to set the preview surface properly.");
-        }
-        CaptureRequest.Builder requestBuilder =
-                mCamera.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
-        requestBuilder.addTarget(mPreviewSurface);
-        return requestBuilder;
-    }
-
-    /**
-     * Stop preview for current camera device.
-     */
-    protected void stopPreview() 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();
-    }
-
-    /**
-     * Setup still (JPEG) capture configuration and start preview.
-     * <p>
-     * The default max number of image is set to image reader.
-     * </p>
-     *
-     * @param previewRequest The capture request to be used for preview
-     * @param stillRequest The capture request to be used for still capture
-     * @param previewSz Preview size
-     * @param stillSz The still capture size
-     * @param resultListener Capture result listener
-     * @param imageListener The still capture image listener
-     */
-    protected void prepareStillCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
-            CaptureRequest.Builder stillRequest, Size previewSz, Size stillSz,
-            CaptureCallback resultListener,
-            ImageReader.OnImageAvailableListener imageListener) throws Exception {
-        prepareCaptureAndStartPreview(previewRequest, stillRequest, previewSz, stillSz,
-                ImageFormat.JPEG, resultListener, MAX_READER_IMAGES, imageListener);
-    }
-
-    /**
-     * Setup still (JPEG) capture configuration and start preview.
-     *
-     * @param previewRequest The capture request to be used for preview
-     * @param stillRequest The capture request to be used for still capture
-     * @param previewSz Preview size
-     * @param stillSz The still capture size
-     * @param resultListener Capture result listener
-     * @param maxNumImages The max number of images set to the image reader
-     * @param imageListener The still capture image listener
-     */
-    protected void prepareStillCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
-            CaptureRequest.Builder stillRequest, Size previewSz, Size stillSz,
-            CaptureCallback resultListener, int maxNumImages,
-            ImageReader.OnImageAvailableListener imageListener) throws Exception {
-        prepareCaptureAndStartPreview(previewRequest, stillRequest, previewSz, stillSz,
-                ImageFormat.JPEG, resultListener, maxNumImages, imageListener);
-    }
-
-    /**
-     * Setup raw capture configuration and start preview.
-     *
-     * <p>
-     * The default max number of image is set to image reader.
-     * </p>
-     *
-     * @param previewRequest The capture request to be used for preview
-     * @param rawRequest The capture request to be used for raw capture
-     * @param previewSz Preview size
-     * @param rawSz The raw capture size
-     * @param resultListener Capture result listener
-     * @param imageListener The raw capture image listener
-     */
-    protected void prepareRawCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
-            CaptureRequest.Builder rawRequest, Size previewSz, Size rawSz,
-            CaptureCallback resultListener,
-            ImageReader.OnImageAvailableListener imageListener) throws Exception {
-        prepareCaptureAndStartPreview(previewRequest, rawRequest, previewSz, rawSz,
-                ImageFormat.RAW_SENSOR, resultListener, MAX_READER_IMAGES, imageListener);
-    }
-
-    /**
-     * Wait for expected result key value available in a certain number of results.
-     *
-     * <p>
-     * Check the result immediately if numFramesWait is 0.
-     * </p>
-     *
-     * @param listener The capture listener to get capture result
-     * @param resultKey The capture result key associated with the result value
-     * @param expectedValue The result value need to be waited for
-     * @param numResultsWait Number of frame to wait before times out
-     * @throws TimeoutRuntimeException If more than numResultsWait results are
-     * seen before the result matching myRequest arrives, or each individual wait
-     * for result times out after {@value #WAIT_FOR_RESULT_TIMEOUT_MS}ms.
-     */
-    protected static <T> void waitForResultValue(SimpleCaptureCallback listener,
-            CaptureResult.Key<T> resultKey,
-            T expectedValue, int numResultsWait) {
-        List<T> expectedValues = new ArrayList<T>();
-        expectedValues.add(expectedValue);
-        waitForAnyResultValue(listener, resultKey, expectedValues, numResultsWait);
-    }
-
-    /**
-     * Wait for any expected result key values available in a certain number of results.
-     *
-     * <p>
-     * Check the result immediately if numFramesWait is 0.
-     * </p>
-     *
-     * @param listener The capture listener to get capture result.
-     * @param resultKey The capture result key associated with the result value.
-     * @param expectedValues The list of result value need to be waited for,
-     * return immediately if the list is empty.
-     * @param numResultsWait Number of frame to wait before times out.
-     * @throws TimeoutRuntimeException If more than numResultsWait results are.
-     * seen before the result matching myRequest arrives, or each individual wait
-     * for result times out after {@value #WAIT_FOR_RESULT_TIMEOUT_MS}ms.
-     */
-    protected static <T> void waitForAnyResultValue(SimpleCaptureCallback listener,
-            CaptureResult.Key<T> resultKey,
-            List<T> expectedValues, int numResultsWait) {
-        if (numResultsWait < 0 || listener == null || expectedValues == null) {
-            throw new IllegalArgumentException(
-                    "Input must be non-negative number and listener/expectedValues "
-                    + "must be non-null");
-        }
-
-        int i = 0;
-        CaptureResult result;
-        do {
-            result = listener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-            T value = result.get(resultKey);
-            for ( T expectedValue : expectedValues) {
-                if (VERBOSE) {
-                    Log.v(TAG, "Current result value for key " + resultKey.getName() + " is: "
-                            + value.toString());
-                }
-                if (value.equals(expectedValue)) {
-                    return;
-                }
-            }
-        } while (i++ < numResultsWait);
-
-        throw new TimeoutRuntimeException(
-                "Unable to get the expected result value " + expectedValues + " for key " +
-                        resultKey.getName() + " after waiting for " + numResultsWait + " results");
-    }
-
-    /**
-     * Submit a capture once, then submit additional captures in order to ensure that
-     * the camera will be synchronized.
-     *
-     * <p>
-     * The additional capture count is determined by android.sync.maxLatency (or
-     * a fixed {@value #NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY}) captures if maxLatency is unknown).
-     * </p>
-     *
-     * <p>Returns the number of captures that were submitted (at least 1), which is useful
-     * with {@link #waitForNumResults}.</p>
-     *
-     * @param request capture request to forward to {@link CameraDevice#capture}
-     * @param listener request listener to forward to {@link CameraDevice#capture}
-     * @param handler handler to forward to {@link CameraDevice#capture}
-     *
-     * @return the number of captures that were submitted
-     *
-     * @throws CameraAccessException if capturing failed
-     */
-    protected int captureRequestsSynchronized(
-            CaptureRequest request, CaptureCallback listener, Handler handler)
-                    throws CameraAccessException {
-        return captureRequestsSynchronized(request, /*count*/1, listener, handler);
-    }
-
-    /**
-     * Submit a capture {@code count} times, then submit additional captures in order to ensure that
-     * the camera will be synchronized.
-     *
-     * <p>
-     * The additional capture count is determined by android.sync.maxLatency (or
-     * a fixed {@value #NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY}) captures if maxLatency is unknown).
-     * </p>
-     *
-     * <p>Returns the number of captures that were submitted (at least 1), which is useful
-     * with {@link #waitForNumResults}.</p>
-     *
-     * @param request capture request to forward to {@link CameraDevice#capture}
-     * @param count the number of times to submit the request (minimally), must be at least 1
-     * @param listener request listener to forward to {@link CameraDevice#capture}
-     * @param handler handler to forward to {@link CameraDevice#capture}
-     *
-     * @return the number of captures that were submitted
-     *
-     * @throws IllegalArgumentException if {@code count} was not at least 1
-     * @throws CameraAccessException if capturing failed
-     */
-    protected int captureRequestsSynchronized(
-            CaptureRequest request, int count, CaptureCallback listener, Handler handler)
-                    throws CameraAccessException {
-        if (count < 1) {
-            throw new IllegalArgumentException("count must be positive");
-        }
-
-        int maxLatency = mStaticInfo.getSyncMaxLatency();
-        if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
-            maxLatency = NUM_FRAMES_WAITED_FOR_UNKNOWN_LATENCY;
-        }
-
-        assertTrue("maxLatency is non-negative", maxLatency >= 0);
-
-        int numCaptures = maxLatency + count;
-
-        for (int i = 0; i < numCaptures; ++i) {
-            mSession.capture(request, listener, handler);
-        }
-
-        return numCaptures;
-    }
-
-    /**
-     * Wait for numResultWait frames
-     *
-     * @param resultListener The capture listener to get capture result back.
-     * @param numResultsWait Number of frame to wait
-     *
-     * @return the last result, or {@code null} if there was none
-     */
-    protected static CaptureResult waitForNumResults(SimpleCaptureCallback resultListener,
-            int numResultsWait) {
-        if (numResultsWait < 0 || resultListener == null) {
-            throw new IllegalArgumentException(
-                    "Input must be positive number and listener must be non-null");
-        }
-
-        CaptureResult result = null;
-        for (int i = 0; i < numResultsWait; i++) {
-            result = resultListener.getCaptureResult(WAIT_FOR_RESULT_TIMEOUT_MS);
-        }
-
-        return result;
-    }
-
-    /**
-     * Wait for enough results for settings to be applied
-     *
-     * @param resultListener The capture listener to get capture result back.
-     * @param numResultWaitForUnknownLatency Number of frame to wait if camera device latency is
-     *                                       unknown.
-     */
-    protected void waitForSettingsApplied(SimpleCaptureCallback resultListener,
-            int numResultWaitForUnknownLatency) {
-        int maxLatency = mStaticInfo.getSyncMaxLatency();
-        if (maxLatency == CameraMetadata.SYNC_MAX_LATENCY_UNKNOWN) {
-            maxLatency = numResultWaitForUnknownLatency;
-        }
-        // Wait for settings to take effect
-        waitForNumResults(resultListener, maxLatency);
-    }
-
-
-    /**
-     * Wait for AE to be stabilized before capture: CONVERGED or FLASH_REQUIRED.
-     *
-     * <p>Waits for {@code android.sync.maxLatency} number of results first, to make sure
-     * that the result is synchronized (or {@code numResultWaitForUnknownLatency} if the latency
-     * is unknown.</p>
-     *
-     * <p>This is a no-op for {@code LEGACY} devices since they don't report
-     * the {@code aeState} result.</p>
-     *
-     * @param resultListener The capture listener to get capture result back.
-     * @param numResultWaitForUnknownLatency Number of frame to wait if camera device latency is
-     *                                       unknown.
-     */
-    protected void waitForAeStable(SimpleCaptureCallback resultListener,
-            int numResultWaitForUnknownLatency) {
-        waitForSettingsApplied(resultListener, numResultWaitForUnknownLatency);
-
-        if (!mStaticInfo.isHardwareLevelLimitedOrBetter()) {
-            // No-op for metadata
-            return;
-        }
-        List<Integer> expectedAeStates = new ArrayList<Integer>();
-        expectedAeStates.add(new Integer(CaptureResult.CONTROL_AE_STATE_CONVERGED));
-        expectedAeStates.add(new Integer(CaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED));
-        waitForAnyResultValue(resultListener, CaptureResult.CONTROL_AE_STATE, expectedAeStates,
-                NUM_RESULTS_WAIT_TIMEOUT);
-    }
-
-    /**
-     * Wait for AE to be: LOCKED
-     *
-     * <p>Waits for {@code android.sync.maxLatency} number of results first, to make sure
-     * that the result is synchronized (or {@code numResultWaitForUnknownLatency} if the latency
-     * is unknown.</p>
-     *
-     * <p>This is a no-op for {@code LEGACY} devices since they don't report
-     * the {@code aeState} result.</p>
-     *
-     * @param resultListener The capture listener to get capture result back.
-     * @param numResultWaitForUnknownLatency Number of frame to wait if camera device latency is
-     *                                       unknown.
-     */
-    protected void waitForAeLocked(SimpleCaptureCallback resultListener,
-            int numResultWaitForUnknownLatency) {
-
-        waitForSettingsApplied(resultListener, numResultWaitForUnknownLatency);
-
-        if (!mStaticInfo.isHardwareLevelLimitedOrBetter()) {
-            // No-op for legacy devices
-            return;
-        }
-
-        List<Integer> expectedAeStates = new ArrayList<Integer>();
-        expectedAeStates.add(new Integer(CaptureResult.CONTROL_AE_STATE_LOCKED));
-        waitForAnyResultValue(resultListener, CaptureResult.CONTROL_AE_STATE, expectedAeStates,
-                NUM_RESULTS_WAIT_TIMEOUT);
-    }
-
-    /**
-     * Create an {@link ImageReader} object and get the surface.
-     *
-     * @param size The size of this ImageReader to be created.
-     * @param format The format of this ImageReader to be created
-     * @param maxNumImages The max number of images that can be acquired simultaneously.
-     * @param listener The listener used by this ImageReader to notify callbacks.
-     */
-    protected void createImageReader(Size size, int format, int maxNumImages,
-            ImageReader.OnImageAvailableListener listener) throws Exception {
-        closeImageReader();
-
-        ImageReader r = makeImageReader(size, format, maxNumImages, listener,
-                mHandler);
-        mReader = r;
-        mReaderSurface = r.getSurface();
-    }
-
-    /**
-     * Close the pending images then close current active {@link ImageReader} object.
-     */
-    protected void closeImageReader() {
-        CameraTestUtils.closeImageReader(mReader);
-        mReader = null;
-        Log.i(TAG,"mReaderSurface = " + mReaderSurface);
-        mOldReaderSurface = mReaderSurface;
-        mReaderSurface = null;
-    }
-
-    /**
-     * Open a camera device and get the StaticMetadata for a given camera id.
-     *
-     * @param cameraId The id of the camera device to be opened.
-     */
-    protected void openDevice(String cameraId) throws Exception {
-        mCamera = CameraTestUtils.openCamera(
-                mCameraManager, cameraId, mCameraListener, mHandler);
-        mCollector.setCameraId(cameraId);
-        mStaticInfo = new StaticMetadata(mCameraManager.getCameraCharacteristics(cameraId),
-                CheckLevel.ASSERT, /*collector*/null);
-        mOrderedPreviewSizes = getSupportedPreviewSizes(cameraId, mCameraManager,
-                getPreviewSizeBound(mWindowManager, PREVIEW_SIZE_BOUND));
-        mOrderedVideoSizes = getSupportedVideoSizes(cameraId, mCameraManager, PREVIEW_SIZE_BOUND);
-        mOrderedStillSizes = getSupportedStillSizes(cameraId, mCameraManager, null);
-        // Use ImageFormat.YUV_420_888 for now. TODO: need figure out what's format for preview
-        // in public API side.
-        mMinPreviewFrameDurationMap =
-                mStaticInfo.getAvailableMinFrameDurationsForFormatChecked(ImageFormat.YUV_420_888);
-    }
-
-    /**
-     * Close the current actively used camera device.
-     */
-    protected void closeDevice() {
-        if (mCamera != null) {
-            mCamera.close();
-            mCameraListener.waitForState(STATE_CLOSED, CAMERA_CLOSE_TIMEOUT_MS);
-            mCamera = null;
-            mSession = null;
-            mSessionListener = null;
-            mStaticInfo = null;
-            mOrderedPreviewSizes = null;
-            mOrderedVideoSizes = null;
-            mOrderedStillSizes = null;
-        }
-    }
-
-    /**
-     * Update the preview surface size.
-     *
-     * @param size The preview size to be updated.
-     */
-    protected void updatePreviewSurface(Size size) {
-        if (size.equals(mPreviewSize) && mPreviewSurface != null) {
-            Log.w(TAG, "Skipping update preview surface size...");
-            return;
-        }
-
-        mPreviewSize = size;
-        Camera2SurfaceViewCtsActivity ctsActivity = getActivity();
-        final SurfaceHolder holder = ctsActivity.getSurfaceView().getHolder();
-        Handler handler = new Handler(Looper.getMainLooper());
-        handler.post(new Runnable() {
-            @Override
-            public void run() {
-                holder.setFixedSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
-            }
-        });
-
-        boolean res = ctsActivity.waitForSurfaceSizeChanged(
-                WAIT_FOR_SURFACE_CHANGE_TIMEOUT_MS, mPreviewSize.getWidth(),
-                mPreviewSize.getHeight());
-        assertTrue("wait for surface change to " + mPreviewSize.toString() + " timed out", res);
-        mPreviewSurface = holder.getSurface();
-        assertNotNull("Preview surface is null", mPreviewSurface);
-        assertTrue("Preview surface is invalid", mPreviewSurface.isValid());
-    }
-
-    /**
-     * Setup single capture configuration and start preview.
-     *
-     * @param previewRequest The capture request to be used for preview
-     * @param stillRequest The capture request to be used for still capture
-     * @param previewSz Preview size
-     * @param captureSz Still capture size
-     * @param format The single capture image format
-     * @param resultListener Capture result listener
-     * @param maxNumImages The max number of images set to the image reader
-     * @param imageListener The single capture capture image listener
-     */
-    protected void prepareCaptureAndStartPreview(CaptureRequest.Builder previewRequest,
-            CaptureRequest.Builder stillRequest, Size previewSz, Size captureSz, int format,
-            CaptureCallback resultListener, int maxNumImages,
-            ImageReader.OnImageAvailableListener imageListener) throws Exception {
-        if (VERBOSE) {
-            Log.v(TAG, String.format("Prepare single capture (%s) and preview (%s)",
-                    captureSz.toString(), previewSz.toString()));
-        }
-
-        // Update preview size.
-        updatePreviewSurface(previewSz);
-
-        // Create ImageReader.
-        createImageReader(captureSz, format, maxNumImages, imageListener);
-
-        // Configure output streams with preview and jpeg streams.
-        List<Surface> outputSurfaces = new ArrayList<Surface>();
-        outputSurfaces.add(mPreviewSurface);
-        outputSurfaces.add(mReaderSurface);
-        mSessionListener = new BlockingSessionCallback();
-        mSession = configureCameraSession(mCamera, outputSurfaces, mSessionListener, mHandler);
-        if (mOldReaderSurface != null) {
-            Log.i(TAG,"release mOldReaderSurface = " + mOldReaderSurface);
-            mOldReaderSurface.release();
-            mOldReaderSurface = null;
-        }
-        // Configure the requests.
-        previewRequest.addTarget(mPreviewSurface);
-        stillRequest.addTarget(mPreviewSurface);
-        stillRequest.addTarget(mReaderSurface);
-
-        // Start preview.
-        mSession.setRepeatingRequest(previewRequest.build(), resultListener, mHandler);
-    }
-
-    /**
-     * Get the max preview size that supports the given fpsRange.
-     *
-     * @param fpsRange The fps range the returned size must support.
-     * @return max size that support the given fps range.
-     */
-    protected Size getMaxPreviewSizeForFpsRange(Range<Integer> fpsRange) {
-        if (fpsRange == null || fpsRange.getLower() <= 0 || fpsRange.getUpper() <= 0) {
-            throw new IllegalArgumentException("Invalid fps range argument");
-        }
-        if (mOrderedPreviewSizes == null || mMinPreviewFrameDurationMap == null) {
-            throw new IllegalStateException("mOrderedPreviewSizes and mMinPreviewFrameDurationMap"
-                    + " must be initialized");
-        }
-
-        long[] frameDurationRange =
-                new long[]{(long) (1e9 / fpsRange.getUpper()), (long) (1e9 / fpsRange.getLower())};
-        for (Size size : mOrderedPreviewSizes) {
-            Long minDuration = mMinPreviewFrameDurationMap.get(size);
-            if (minDuration == null ||
-                    minDuration == 0) {
-                if (mStaticInfo.isCapabilitySupported(
-                        CameraCharacteristics.REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR)) {
-                    throw new IllegalArgumentException(
-                            "No min frame duration available for the size " + size);
-                }
-                continue;
-            }
-            if (minDuration <= frameDurationRange[0]) {
-                return size;
-            }
-        }
-
-        return null;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraCtsActivity.java b/tests/tests/hardware/src/android/hardware/cts/CameraCtsActivity.java
deleted file mode 100644
index 1153cac..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/CameraCtsActivity.java
+++ /dev/null
@@ -1,48 +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.hardware.cts;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-import android.view.ViewGroup;
-import com.android.cts.hardware.R;
-
-public class CameraCtsActivity extends Activity {
-    private SurfaceView mSurfaceView;
-    private final int LAYOUT_WIDTH = 480;
-    private final int LAYOUT_HEIGHT = 320;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(R.layout.surface_view);
-        mSurfaceView = (SurfaceView)findViewById(R.id.surface_view);
-        ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
-        lp.width = LAYOUT_WIDTH;
-        lp.height = LAYOUT_HEIGHT;
-        mSurfaceView.setLayoutParams(lp);
-        mSurfaceView.getHolder().setFixedSize(LAYOUT_WIDTH, LAYOUT_HEIGHT);
-        mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
-    }
-
-    public SurfaceView getSurfaceView() {
-        return mSurfaceView;
-    }
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java
deleted file mode 100755
index 380e47d..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/CameraGLTest.java
+++ /dev/null
@@ -1,901 +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.hardware.cts;
-
-import android.content.Context;
-import android.graphics.SurfaceTexture;
-import android.hardware.Camera;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.Size;
-
-import android.opengl.GLES20;
-import android.opengl.GLSurfaceView;
-import android.opengl.Matrix;
-
-import android.os.ConditionVariable;
-import android.os.Environment;
-import android.os.Looper;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.MoreAsserts;
-import android.test.UiThreadTest;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-
-import com.android.cts.util.TimeoutReq;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-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.opengles.GL10;
-
-/**
- * This test case must run with hardware. It can't be tested in emulator
- */
-@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 boolean LOGV = false;
-    private static final boolean LOGVV = false;
-    private static final int EGL_OPENGL_ES2_BIT = 0x0004;
-
-    private boolean mSurfaceTextureCallbackResult = false;
-
-    private static final int WAIT_FOR_COMMAND_TO_COMPLETE = 5000;  // Milliseconds.
-    private static final int WAIT_FOR_FOCUS_TO_COMPLETE = 5000;
-    private static final int WAIT_FOR_SNAPSHOT_TO_COMPLETE = 5000;
-
-    private SurfaceTextureCallback mSurfaceTextureCallback = new SurfaceTextureCallback();
-    private SurfaceTextureBurstCallback mSurfaceTextureBurstCallback = new SurfaceTextureBurstCallback();
-    private PreviewCallback mPreviewCallback = new PreviewCallback();
-
-    private Looper mLooper = null;
-    private final ConditionVariable mSurfaceTextureDone = new ConditionVariable();
-    private final ConditionVariable mPreviewDone = new ConditionVariable();
-
-    Camera mCamera;
-    SurfaceTexture mSurfaceTexture;
-    private final Object mSurfaceTextureSyncLock = new Object();
-    Renderer mRenderer;
-    GLSurfaceView mGLView;
-
-    public CameraGLTest() {
-        super(PACKAGE, GLSurfaceViewCtsActivity.class);
-        if (LOGV) Log.v(TAG, "CameraGLTest Constructor");
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Set up renderer instance
-        mRenderer = this.new Renderer();
-        GLSurfaceViewCtsActivity.setRenderer(mRenderer);
-        GLSurfaceViewCtsActivity.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
-        GLSurfaceViewCtsActivity.setGlVersion(2);
-        // Start CameraCtsActivity.
-        GLSurfaceViewCtsActivity ctsActivity = getActivity();
-        // Store a link to the view so we can redraw it when needed
-        mGLView = ctsActivity.getView();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (mCamera != null) {
-            terminateMessageLooper();
-        }
-        // Clean up static values in cts so it can be reused
-        GLSurfaceViewCtsActivity.resetRenderMode();
-        GLSurfaceViewCtsActivity.resetRenderer();
-        GLSurfaceViewCtsActivity.resetGlVersion();
-
-        super.tearDown();
-    }
-
-    /**
-     * Initializes the message looper so that the Camera object can
-     * receive the callback messages.
-     */
-    private void initializeMessageLooper(final int cameraId) {
-        final ConditionVariable startDone = new ConditionVariable();
-        new Thread() {
-            @Override
-            public void run() {
-                Log.v(TAG, "Start camera/surfacetexture thread");
-                // Set up a looper to be used by camera.
-                Looper.prepare();
-                // Save the looper so that we can terminate this thread
-                // after we are done with it.
-                mLooper = Looper.myLooper();
-                // These must be instantiated outside the UI thread, since the
-                // UI thread will be doing a lot of waiting, stopping callbacks.
-                mCamera = Camera.open(cameraId);
-                mSurfaceTexture = new SurfaceTexture(mRenderer.getTextureID());
-                Log.v(TAG, "Camera " + cameraId + " is opened.");
-                startDone.open();
-                Looper.loop(); // Blocks forever until Looper.quit() is called.
-                Log.v(TAG, "Stop camera/surfacetexture thread");
-            }
-        }.start();
-
-        Log.v(TAG, "start waiting for looper");
-        if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
-            fail("initializeMessageLooper: start timeout");
-        }
-    }
-
-    /**
-     * Terminates the message looper thread.
-     */
-    private void terminateMessageLooper() throws Exception {
-        if (LOGV) Log.v(TAG, "Shutting down camera");
-        mCamera.release();
-        mLooper.quit();
-        // Looper.quit() is asynchronous. The looper may still has some
-        // preview callbacks in the queue after quit is called. The preview
-        // callback still uses the camera object (setHasPreviewCallback).
-        // After camera is released, RuntimeException will be thrown from
-        // the method. So we need to join the looper thread here.
-        mLooper.getThread().join();
-        mCamera = null;
-        synchronized(mSurfaceTextureSyncLock) {
-            mSurfaceTexture = null;
-        }
-        if (LOGV) Log.v(TAG, "Shutdown of camera complete.");
-    }
-
-    /** The camera preview callback. Stops capture after the first callback */
-    private final class PreviewCallback
-            implements android.hardware.Camera.PreviewCallback {
-        public void onPreviewFrame(byte [] data, Camera camera) {
-            if (LOGV) Log.v(TAG, "PreviewCallback");
-            assertNotNull(data);
-            Size size = camera.getParameters().getPreviewSize();
-            assertEquals(size.width * size.height * 3 / 2, data.length);
-            mCamera.stopPreview();
-            mPreviewDone.open();
-        }
-    }
-
-    /** A simple SurfaceTexture listener callback, meant to be used together with the camera preview
-     * callback */
-    private final class SurfaceTextureCallback
-            implements android.graphics.SurfaceTexture.OnFrameAvailableListener {
-        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
-            if (LOGV) Log.v(TAG, "SurfaceTextureCallback");
-            mSurfaceTextureDone.open();
-            // Assumes preview is stopped elsewhere
-        }
-    }
-
-    /** A burst SurfaceTexture listener callback, used for multiple-frame capture */
-    private final class SurfaceTextureBurstCallback
-            implements android.graphics.SurfaceTexture.OnFrameAvailableListener {
-
-        public void setBurstCount(int burstCount) {
-            mBurstCount = burstCount;
-        }
-
-        public int getBurstCount() {
-            return mBurstCount;
-        }
-
-        public void onFrameAvailable(SurfaceTexture surfaceTexture) {
-            if (LOGVV) Log.v(TAG, "SurfaceTextureBurstCallback, frame #" + mBurstCount);
-            mBurstCount--;
-            if (!mSurfaceTextureCallbackResult) {
-                if (mBurstCount <= 0) {
-                    if (LOGV) Log.v(TAG, "SurfaceTextureBurstCallback stopping preview.");
-                    mCamera.stopPreview();
-                    if (LOGVV) Log.v(TAG, "SurfaceTextureBurstCallback preview stopped.");
-                    mSurfaceTextureCallbackResult = true;
-                }
-                mSurfaceTextureDone.open();
-            }
-        }
-
-        private int mBurstCount = 0;
-    }
-
-    /** Waits until surface texture callbacks have fired */
-    private boolean waitForSurfaceTextureDone() {
-        if (LOGVV) Log.v(TAG, "Wait for surface texture callback");
-        if (!mSurfaceTextureDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
-            // timeout could be expected or unexpected. The caller will decide.
-            Log.v(TAG, "waitForSurfaceTextureDone: timeout");
-            return false;
-        }
-        mSurfaceTextureDone.close();
-        return true;
-    }
-
-    /** Waits until the camera preview callback has fired */
-    private boolean waitForPreviewDone() {
-        if (LOGVV) Log.v(TAG, "Wait for preview callback");
-        if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
-            // timeout could be expected or unexpected. The caller will decide.
-            Log.v(TAG, "waitForPreviewDone: timeout");
-            return false;
-        }
-        mPreviewDone.close();
-        return true;
-    }
-
-    /** @return OpenGL ES major version 1 or 2 or some negative number for error */
-    private static int getDetectedVersion() {
-        /*
-         * Get all the device configurations and check if any of the attributes specify the
-         * the EGL_OPENGL_ES2_BIT to determine whether the device supports 2.0.
-         */
-        EGL10 egl = (EGL10) EGLContext.getEGL();
-        EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
-        int[] numConfigs = new int[1];
-
-        if (egl.eglInitialize(display, null)) {
-            try {
-                if (egl.eglGetConfigs(display, null, 0, numConfigs)) {
-                    EGLConfig[] configs = new EGLConfig[numConfigs[0]];
-                    if (egl.eglGetConfigs(display, configs, numConfigs[0], numConfigs)) {
-                        int[] value = new int[1];
-                        for (int i = 0; i < numConfigs[0]; i++) {
-                            if (egl.eglGetConfigAttrib(display, configs[i],
-                                    EGL10.EGL_RENDERABLE_TYPE, value)) {
-                                if ((value[0] & EGL_OPENGL_ES2_BIT) == EGL_OPENGL_ES2_BIT) {
-                                    return 2;
-                                }
-                            } else {
-                                Log.w(TAG, "Getting config attribute with "
-                                        + "EGL10#eglGetConfigAttrib failed "
-                                        + "(" + i + "/" + numConfigs[0] + "): "
-                                        + egl.eglGetError());
-                            }
-                        }
-                        return 1;
-                    } else {
-                        Log.e(TAG, "Getting configs with EGL10#eglGetConfigs failed: "
-                                + egl.eglGetError());
-                        return -1;
-                    }
-                } else {
-                    Log.e(TAG, "Getting number of configs with EGL10#eglGetConfigs failed: "
-                            + egl.eglGetError());
-                    return -2;
-                }
-              } finally {
-                  egl.eglTerminate(display);
-              }
-        } else {
-            Log.e(TAG, "Couldn't initialize EGL.");
-            return -3;
-        }
-    }
-
-    /** Generic per-camera test interface */
-    private interface RunPerCamera {
-        void run(int cameraId) throws Exception;
-    }
-
-    /** Generic camera test runner, to minimize boilerplace duplication */
-    private void runForAllCameras(RunPerCamera test) throws Exception {
-        /* Currently OpenGL ES 2.0 is supported for this test, so just skip it
-           if only 1.0 is available. */
-        int glVersion = getDetectedVersion();
-        assertTrue(glVersion > 0);
-        if (glVersion != 2) {
-            Log.w(TAG, "Skipping test because OpenGL ES 2 is not supported");
-            return;
-        }
-
-        /* Make sure the screen stays on while testing - otherwise the OpenGL context may disappear */
-        PowerManager pm = (PowerManager) getActivity().getSystemService(Context.POWER_SERVICE);
-        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "CameraGLTest");
-        wl.acquire();
-        try {
-            /* Run the requested test per camera */
-            int nCameras = Camera.getNumberOfCameras();
-            for (int id = 0; id < nCameras; id++) {
-                Log.v(TAG, "Camera id=" + id);
-                test.run(id);
-            }
-        } finally {
-            wl.release();
-            // If an assert failed, camera might still be active. Clean up before next test.
-            if (mCamera != null) {
-                terminateMessageLooper();
-            }
-        }
-    }
-
-    /** Test Camera.setPreviewTexture in conjunction with the standard Camera preview callback */
-    @UiThreadTest
-    public void testSetPreviewTexturePreviewCallback() throws Exception {
-        runForAllCameras(testSetPreviewTexturePreviewCallbackByCamera);
-    }
-
-    private RunPerCamera testSetPreviewTexturePreviewCallbackByCamera = new RunPerCamera() {
-        public void run(int cameraId) throws Exception {
-            boolean noTimeout;
-            // Check the order: startPreview->setPreviewTexture, with a PreviewCallback as well
-            mPreviewDone.close();
-            initializeMessageLooper(cameraId);
-            mCamera.setOneShotPreviewCallback(mPreviewCallback);
-            mCamera.startPreview();
-            mCamera.setPreviewTexture(mSurfaceTexture);
-            noTimeout = waitForPreviewDone();
-            assertTrue("Timeout waiting for new preview callback!", noTimeout);
-            terminateMessageLooper();
-
-            // Check the order: setPreviewTexture->startPreview.
-            initializeMessageLooper(cameraId);
-            mCamera.setOneShotPreviewCallback(mPreviewCallback);
-            mCamera.setPreviewTexture(mSurfaceTexture);
-            mCamera.startPreview();
-            noTimeout = waitForPreviewDone();
-            assertTrue("Timeout waiting for new preview callback!", noTimeout);
-
-            // Check the order: setting preview display to null->startPreview->
-            // setPreviewTexture.
-            mCamera.setOneShotPreviewCallback(mPreviewCallback);
-            mCamera.setPreviewTexture(null);
-            mCamera.startPreview();
-            mCamera.setPreviewTexture(mSurfaceTexture);
-            noTimeout = waitForPreviewDone();
-            assertTrue("Timeout waiting for new preview callback!", noTimeout);
-            terminateMessageLooper();
-        }
-    };
-
-    /** Test Camera.setPreviewTexture in conjunction with both the standard Camera preview callback,
-        and the SurfaceTexture onFrameAvailable callback */
-    @UiThreadTest
-    public void testSetPreviewTextureBothCallbacks() throws Exception {
-        runForAllCameras(testSetPreviewTextureBothCallbacksByCamera);
-    }
-
-    private RunPerCamera testSetPreviewTextureBothCallbacksByCamera = new RunPerCamera() {
-        public void run(int cameraId) throws Exception {
-            boolean noTimeout;
-            // Check SurfaceTexture callback together with preview callback
-            // Check the order: setPreviewTexture->startPreview
-            mSurfaceTextureDone.close();
-            initializeMessageLooper(cameraId);
-            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
-            mCamera.setOneShotPreviewCallback(mPreviewCallback);
-            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
-            mCamera.setPreviewTexture(mSurfaceTexture);
-            mCamera.startPreview();
-
-            noTimeout = waitForSurfaceTextureDone();
-            assertTrue("Timeout waiting for new frame from SurfaceTexture!", noTimeout);
-            noTimeout = waitForPreviewDone();
-            assertTrue("Timeout waiting for new preview callback!",noTimeout);
-
-            mGLView.requestRender();
-            terminateMessageLooper();
-
-            // Check the order: startPreview->setPreviewTexture
-            mSurfaceTextureDone.close();
-            initializeMessageLooper(cameraId);
-            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
-            mCamera.setOneShotPreviewCallback(mPreviewCallback);
-            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
-            mCamera.startPreview();
-            mCamera.setPreviewTexture(mSurfaceTexture);
-
-            noTimeout = waitForSurfaceTextureDone();
-            assertTrue("Timeout waiting for new frame from SurfaceTexture!", noTimeout);
-            noTimeout = waitForPreviewDone();
-            assertTrue("Timeout waiting for new preview callback!", noTimeout);
-
-            mGLView.requestRender();
-
-            // Check the order: setting preview to null->startPreview->setPreviewTexture
-            mCamera.setOneShotPreviewCallback(mPreviewCallback);
-            mCamera.setPreviewTexture(null);
-            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureCallback);
-            mCamera.startPreview();
-            mCamera.setPreviewTexture(mSurfaceTexture);
-            noTimeout = waitForPreviewDone();
-            assertTrue(noTimeout);
-            terminateMessageLooper();
-        }
-    };
-
-    /** Test Camera.setPreviewTexture in conjunction with just the SurfaceTexture onFrameAvailable callback */
-    @UiThreadTest
-    public void testSetPreviewTextureTextureCallback() throws Exception {
-        runForAllCameras(testSetPreviewTextureTextureCallbackByCamera);
-    }
-
-    private RunPerCamera testSetPreviewTextureTextureCallbackByCamera = new RunPerCamera() {
-        public void run(int cameraId) throws Exception {
-            boolean noTimeout;
-            // Check that SurfaceTexture callbacks work with no standard
-            // preview callback
-            mSurfaceTextureCallbackResult = false;
-            mSurfaceTextureDone.close();
-            initializeMessageLooper(cameraId);
-            mSurfaceTextureBurstCallback.setBurstCount(1);
-            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
-            mCamera.setPreviewTexture(mSurfaceTexture);
-            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
-            mCamera.startPreview();
-
-            noTimeout = waitForSurfaceTextureDone();
-            mGLView.requestRender();
-            assertTrue(noTimeout);
-
-            terminateMessageLooper();
-            assertTrue(mSurfaceTextureCallbackResult);
-
-            // Check that SurfaceTexture callbacks also work with
-            // startPreview->setPreviewTexture
-            mSurfaceTextureCallbackResult = false;
-            mSurfaceTextureDone.close();
-            initializeMessageLooper(cameraId);
-            mSurfaceTextureBurstCallback.setBurstCount(1);
-            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
-            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
-            mCamera.startPreview();
-            mCamera.setPreviewTexture(mSurfaceTexture);
-
-            noTimeout = waitForSurfaceTextureDone();
-            assertTrue(noTimeout);
-
-            terminateMessageLooper();
-            assertTrue(mSurfaceTextureCallbackResult);
-
-            // Check that SurfaceTexture callbacks also work with
-            // null->startPreview->setPreviewTexture
-            mSurfaceTextureCallbackResult = false;
-            mSurfaceTextureDone.close();
-            initializeMessageLooper(cameraId);
-            mSurfaceTextureBurstCallback.setBurstCount(1);
-            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
-            mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
-            mCamera.setPreviewTexture(null);
-            mCamera.startPreview();
-            mCamera.setPreviewTexture(mSurfaceTexture);
-
-            noTimeout = waitForSurfaceTextureDone();
-            assertTrue(noTimeout);
-
-            terminateMessageLooper();
-            assertTrue(mSurfaceTextureCallbackResult);
-        }
-    };
-
-    /** Test all preview sizes and framerates along with SurfaceTexture-provided metadata (texture
-     * transforms and timestamps).
-     * TODO: This should be made stricter once SurfaceTexture timestamps are generated by the drivers.
-     */
-    @UiThreadTest
-    @TimeoutReq(minutes = 30)
-    public void testCameraToSurfaceTextureMetadata() throws Exception {
-        runForAllCameras(testCameraToSurfaceTextureMetadataByCamera);
-    }
-
-    private RunPerCamera testCameraToSurfaceTextureMetadataByCamera = new RunPerCamera() {
-        public void run(int cameraId) throws Exception {
-            // Number of frames to test over
-            int kLoopCount = 100;
-            // Number of frames that can be out of bounds before calling this a failure
-            int kMaxOutOfBoundsFrames = kLoopCount / 25; // 4% of frames
-            // Ignore timestamp issues before this frame
-            int kFirstTestedFrame = 10;
-            // Slop in timestamp testing, needed because timestamps are not
-            // currently being set by driver-level code so are subject to
-            // user-space timing variability
-            float kTestSlopMargin = 20; // ms
-
-            boolean noTimeout;
-            initializeMessageLooper(cameraId);
-            Parameters parameters = mCamera.getParameters();
-
-            mSurfaceTexture.setOnFrameAvailableListener(mSurfaceTextureBurstCallback);
-            mCamera.setPreviewTexture(mSurfaceTexture);
-
-            for (Size size: parameters.getSupportedPreviewSizes()) {
-                for (int[] fps: parameters.getSupportedPreviewFpsRange()) {
-                    if (LOGV) {
-                        Log.v(TAG, "Testing camera #" + cameraId +
-                              ", preview size:" + size.width + "x" + size.height +
-                              ", frame rate range: [" +
-                              (fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.) + "," +
-                              (fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.) + "]");
-                    }
-                    parameters.setPreviewSize(size.width, size.height);
-                    parameters.setPreviewFpsRange(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
-                                                  fps[Parameters.PREVIEW_FPS_MAX_INDEX]);
-                    mCamera.setParameters(parameters);
-
-                    assertEquals(size, mCamera.getParameters().getPreviewSize());
-
-                    int[] actualFps = new int[2];
-                    mCamera.getParameters().getPreviewFpsRange(actualFps);
-                    assertEquals(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
-                                 actualFps[Parameters.PREVIEW_FPS_MIN_INDEX]);
-                    assertEquals(fps[Parameters.PREVIEW_FPS_MAX_INDEX],
-                                 actualFps[Parameters.PREVIEW_FPS_MAX_INDEX]);
-
-                    mSurfaceTextureBurstCallback.
-                            setBurstCount(kLoopCount + kFirstTestedFrame);
-                    mSurfaceTextureCallbackResult = false;
-                    mSurfaceTextureDone.close();
-
-                    mRenderer.setCameraSizing(mCamera.getParameters().getPreviewSize());
-                    if (LOGV) Log.v(TAG, "Starting preview");
-                    mCamera.startPreview();
-                    if (LOGVV) Log.v(TAG, "Preview started");
-
-                    long[] timestamps = new long[kLoopCount];
-                    for (int i = 0; i < kLoopCount + kFirstTestedFrame; i++) {
-                        noTimeout = waitForSurfaceTextureDone();
-                        assertTrue("Timeout waiting for frame " + i +
-                                   " (burst callback thinks " +
-                                   (kLoopCount - mSurfaceTextureBurstCallback.getBurstCount()) +
-                                   ")! (Size " + size.width + "x" + size.height + ", fps [" +
-                                   (fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.) + ", " +
-                                   (fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.) + "])",
-                                   noTimeout);
-
-                        if (LOGVV) Log.v(TAG, "Frame #" + i + " completed");
-                        // Draw the frame (and update the SurfaceTexture)
-                        mGLView.requestRender();
-                        // Wait until frame is drawn, so that the SurfaceTexture has new
-                        // metadata
-                        noTimeout = mRenderer.waitForDrawDone();
-                        assertTrue(noTimeout);
-
-                        // Store timestamps for later
-                        if (i >= kFirstTestedFrame) {
-                            timestamps[i - kFirstTestedFrame] =
-                                    mSurfaceTexture.getTimestamp();
-                        }
-                        // Verify that the surfaceTexture transform has at least one non-zero
-                        // entry
-                        float[] transform = new float[16];
-                        mSurfaceTexture.getTransformMatrix(transform);
-                        boolean nonZero = false;
-                        for (int k = 0; k < 16; k++) {
-                            if (transform[k] != 0.f) {
-                                nonZero = true;
-                                break;
-                            }
-                        }
-                        assertTrue(nonZero);
-                    }
-                    assertTrue(mSurfaceTextureCallbackResult);
-
-                    float expectedMaxFrameDurationMs = 1000.f * 1000.f /
-                            fps[Parameters.PREVIEW_FPS_MIN_INDEX];
-                    float slopMaxFrameDurationMs = expectedMaxFrameDurationMs +
-                            kTestSlopMargin;
-                    float expectedMinFrameDurationMs = 1000.f * 1000.f /
-                            fps[Parameters.PREVIEW_FPS_MAX_INDEX];
-                    float slopMinFrameDurationMs = expectedMinFrameDurationMs  -
-                            kTestSlopMargin;
-
-                    int outOfBoundsCount = 0;
-                    for (int i = 1; i < kLoopCount; i++) {
-                        float frameDurationMs =
-                                (timestamps[i] - timestamps[i-1]) / 1000000.f;
-                        if (LOGVV) {
-                            Log.v(TAG, "Frame " + i + " duration: " + frameDurationMs +
-                                  " ms, expecting [" + expectedMinFrameDurationMs + "," +
-                                    expectedMaxFrameDurationMs + "], slop range [" +
-                                    slopMinFrameDurationMs + "," + slopMaxFrameDurationMs + "].");
-                        }
-                        if ( frameDurationMs > slopMaxFrameDurationMs ||
-                                frameDurationMs < slopMinFrameDurationMs ) {
-                            if (LOGVV) {
-                                Log.v(TAG, "  Out of bounds!!");
-                            }
-                            outOfBoundsCount++;
-                        }
-                    }
-                    assertTrue(
-                            "Too many frame intervals out of frame rate bounds: "
-                            + outOfBoundsCount +
-                            ", limit " + kMaxOutOfBoundsFrames,
-                            outOfBoundsCount <= kMaxOutOfBoundsFrames);
-                }
-            }
-            terminateMessageLooper();
-        } // void run(int cameraId)
-    };
-
-    /** Basic OpenGL ES 2.0 renderer to draw SurfaceTexture-sourced frames to the screen */
-    private class Renderer implements GLSurfaceView.Renderer {
-        public Renderer() {
-            mTriangleVertices =
-                    ByteBuffer.allocateDirect(mTriangleVerticesData.length * FLOAT_SIZE_BYTES).
-                    order(ByteOrder.nativeOrder()).asFloatBuffer();
-            mTriangleVertices.put(mTriangleVerticesData).position(0);
-
-            Matrix.setIdentityM(mSTMatrix, 0);
-            Matrix.setIdentityM(mMMatrix, 0);
-
-            mTextureID = 0;
-        }
-
-        public void setCameraSizing(Camera.Size previewSize) {
-            mCameraRatio = (float)previewSize.width/previewSize.height;
-        }
-
-        public boolean waitForDrawDone() {
-            if (!mDrawDone.block(WAIT_FOR_COMMAND_TO_COMPLETE) ) {
-                // timeout could be expected or unexpected. The caller will decide.
-                Log.e(TAG, "waitForDrawDone: timeout");
-                return false;
-            }
-            mDrawDone.close();
-            return true;
-        }
-
-        private final ConditionVariable mDrawDone = new ConditionVariable();
-
-        public void onDrawFrame(GL10 glUnused) {
-            if (LOGVV) Log.v(TAG, "onDrawFrame()");
-            synchronized(mSurfaceTextureSyncLock) {
-                if (CameraGLTest.this.mSurfaceTexture != null) {
-                    CameraGLTest.this.mSurfaceTexture.updateTexImage();
-                    CameraGLTest.this.mSurfaceTexture.getTransformMatrix(mSTMatrix);
-                    mDrawDone.open();
-                }
-            }
-
-            // Ignore the passed-in GL10 interface, and use the GLES20
-            // class's static methods instead.
-            GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
-            GLES20.glUseProgram(mProgram);
-            checkGlError("glUseProgram");
-
-            GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
-            GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
-
-            mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
-            GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
-                                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
-            checkGlError("glVertexAttribPointer maPosition");
-            GLES20.glEnableVertexAttribArray(maPositionHandle);
-            checkGlError("glEnableVertexAttribArray maPositionHandle");
-
-            mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
-            GLES20.glVertexAttribPointer(maTextureHandle, 2, GLES20.GL_FLOAT, false,
-                                         TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
-            checkGlError("glVertexAttribPointer maTextureHandle");
-            GLES20.glEnableVertexAttribArray(maTextureHandle);
-            checkGlError("glEnableVertexAttribArray maTextureHandle");
-
-            Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
-            Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);
-
-            GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
-            GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);
-            GLES20.glUniform1f(muCRatioHandle, mCameraRatio);
-
-            GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
-            checkGlError("glDrawArrays");
-        }
-
-        public void onSurfaceChanged(GL10 glUnused, int width, int height) {
-            if (LOGV) Log.v(TAG, "onSurfaceChanged()");
-            // Ignore the passed-in GL10 interface, and use the GLES20
-            // class's static methods instead.
-            GLES20.glViewport(0, 0, width, height);
-            mRatio = (float) width / height;
-            Matrix.frustumM(mProjMatrix, 0, -mRatio, mRatio, -1, 1, 3, 7);
-        }
-
-        public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {
-            if (LOGV) Log.v(TAG, "onSurfaceCreated()");
-            // Ignore the passed-in GL10 interface, and use the GLES20
-            // class's static methods instead.
-
-            /* Set up shaders and handles to their variables */
-            mProgram = createProgram(mVertexShader, mFragmentShader);
-            if (mProgram == 0) {
-                return;
-            }
-            maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
-            checkGlError("glGetAttribLocation aPosition");
-            if (maPositionHandle == -1) {
-                throw new RuntimeException("Could not get attrib location for aPosition");
-            }
-            maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
-            checkGlError("glGetAttribLocation aTextureCoord");
-            if (maTextureHandle == -1) {
-                throw new RuntimeException("Could not get attrib location for aTextureCoord");
-            }
-
-            muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
-            checkGlError("glGetUniformLocation uMVPMatrix");
-            if (muMVPMatrixHandle == -1) {
-                throw new RuntimeException("Could not get attrib location for uMVPMatrix");
-            }
-
-            muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix");
-            checkGlError("glGetUniformLocation uSTMatrix");
-            if (muMVPMatrixHandle == -1) {
-                throw new RuntimeException("Could not get attrib location for uSTMatrix");
-            }
-
-            muCRatioHandle = GLES20.glGetUniformLocation(mProgram, "uCRatio");
-            checkGlError("glGetUniformLocation uCRatio");
-            if (muMVPMatrixHandle == -1) {
-                throw new RuntimeException("Could not get attrib location for uCRatio");
-            }
-
-            /*
-             * Create our texture. This has to be done each time the
-             * surface is created.
-             */
-
-            int[] textures = new int[1];
-            GLES20.glGenTextures(1, textures, 0);
-
-            mTextureID = textures[0];
-            GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID);
-            checkGlError("glBindTexture mTextureID");
-
-            // Can't do mipmapping with camera source
-            GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER,
-                                   GLES20.GL_NEAREST);
-            GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER,
-                                   GLES20.GL_LINEAR);
-            // Clamp to edge is the only option
-            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S,
-                                   GLES20.GL_CLAMP_TO_EDGE);
-            GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T,
-                                   GLES20.GL_CLAMP_TO_EDGE);
-            checkGlError("glTexParameteri mTextureID");
-
-            Matrix.setLookAtM(mVMatrix, 0, 0, 0, 4f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
-        }
-
-        public int getTextureID() {
-            return mTextureID;
-        }
-
-        private int loadShader(int shaderType, String source) {
-            int shader = GLES20.glCreateShader(shaderType);
-            if (shader != 0) {
-                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) {
-                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 checkGlError(String op) {
-            int error;
-            while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
-                Log.e(TAG, op + ": glError " + error);
-                throw new RuntimeException(op + ": glError " + error);
-            }
-        }
-
-        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 final float[] mTriangleVerticesData = {
-            // 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 FloatBuffer mTriangleVertices;
-
-        private final String mVertexShader =
-                "uniform mat4 uMVPMatrix;\n" +
-                "uniform mat4 uSTMatrix;\n" +
-                "uniform float uCRatio;\n" +
-                "attribute vec4 aPosition;\n" +
-                "attribute vec4 aTextureCoord;\n" +
-                "varying vec2 vTextureCoord;\n" +
-                "void main() {\n" +
-                "  gl_Position = vec4(uCRatio,1,1,1) * uMVPMatrix * aPosition;\n" +
-                "  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
-                "}\n";
-
-        private final String mFragmentShader =
-                "#extension GL_OES_EGL_image_external : require\n" +
-                "precision mediump float;\n" +
-                "varying vec2 vTextureCoord;\n" +
-                "uniform samplerExternalOES sTexture;\n" +
-                "void main() {\n" +
-                "  gl_FragColor = texture2D(sTexture, vTextureCoord);\n" +
-                "}\n";
-
-        private float[] mMVPMatrix = new float[16];
-        private float[] mProjMatrix = new float[16];
-        private float[] mMMatrix = new float[16];
-        private float[] mVMatrix = new float[16];
-        private float[] mSTMatrix = new float[16];
-
-        private int mProgram;
-        private int mTextureID;
-        private int muMVPMatrixHandle;
-        private int muSTMatrixHandle;
-        private int muCRatioHandle;
-        private int maPositionHandle;
-        private int maTextureHandle;
-
-        private float mRatio = 1.0f;
-        private float mCameraRatio = 1.0f;
-
-        private Context mContext;
-        private static final String TAG = "CameraGLTest.Renderer";
-
-        // Magic key
-        private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;
-    }
-
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java b/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
deleted file mode 100644
index cf616b6..0000000
--- a/tests/tests/hardware/src/android/hardware/cts/CameraTest.java
+++ /dev/null
@@ -1,3185 +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.hardware.cts;
-
-import android.content.pm.PackageManager;
-import android.graphics.BitmapFactory;
-import android.graphics.ImageFormat;
-import android.graphics.Rect;
-import android.hardware.Camera;
-import android.hardware.Camera.Area;
-import android.hardware.Camera.CameraInfo;
-import android.hardware.Camera.ErrorCallback;
-import android.hardware.Camera.Face;
-import android.hardware.Camera.FaceDetectionListener;
-import android.hardware.Camera.Parameters;
-import android.hardware.Camera.PictureCallback;
-import android.hardware.Camera.ShutterCallback;
-import android.hardware.Camera.Size;
-import android.media.CamcorderProfile;
-import android.media.ExifInterface;
-import android.media.MediaRecorder;
-import android.os.Build;
-import android.os.ConditionVariable;
-import android.os.Environment;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.test.ActivityInstrumentationTestCase2;
-import android.test.MoreAsserts;
-import android.test.UiThreadTest;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.util.Log;
-import android.view.SurfaceHolder;
-
-import com.android.cts.util.TimeoutReq;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.text.ParsePosition;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.TimeZone;
-
-import junit.framework.AssertionFailedError;
-
-/**
- * This test case must run with hardware. It can't be tested in emulator
- */
-@LargeTest
-public class CameraTest extends ActivityInstrumentationTestCase2<CameraCtsActivity> {
-    private static String TAG = "CameraTest";
-    private static final String PACKAGE = "com.android.cts.hardware";
-    private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
-    private final String JPEG_PATH = Environment.getExternalStorageDirectory().getPath() +
-            "/test.jpg";
-    private byte[] mJpegData;
-
-    private static final int PREVIEW_CALLBACK_NOT_RECEIVED = 0;
-    private static final int PREVIEW_CALLBACK_RECEIVED = 1;
-    private static final int PREVIEW_CALLBACK_DATA_NULL = 2;
-    private static final int PREVIEW_CALLBACK_INVALID_FRAME_SIZE = 3;
-    private int mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
-
-    private boolean mShutterCallbackResult = false;
-    private boolean mRawPictureCallbackResult = false;
-    private boolean mJpegPictureCallbackResult = false;
-    private static final int NO_ERROR = -1;
-    private int mCameraErrorCode = NO_ERROR;
-    private boolean mAutoFocusSucceeded = false;
-
-    private static final int WAIT_FOR_COMMAND_TO_COMPLETE = 5000;  // Milliseconds.
-    private static final int WAIT_FOR_FOCUS_TO_COMPLETE = 5000;
-    private static final int WAIT_FOR_SNAPSHOT_TO_COMPLETE = 5000;
-
-    private static final int FOCUS_AREA = 0;
-    private static final int METERING_AREA = 1;
-
-    private static final int AUTOEXPOSURE_LOCK = 0;
-    private static final int AUTOWHITEBALANCE_LOCK = 1;
-
-    // Some exif tags that are not defined by ExifInterface but supported.
-    private static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
-    private static final String TAG_SUBSEC_TIME = "SubSecTime";
-    private static final String TAG_SUBSEC_TIME_ORIG = "SubSecTimeOriginal";
-    private static final String TAG_SUBSEC_TIME_DIG = "SubSecTimeDigitized";
-
-
-    private PreviewCallback mPreviewCallback = new PreviewCallback();
-    private TestShutterCallback mShutterCallback = new TestShutterCallback();
-    private RawPictureCallback mRawPictureCallback = new RawPictureCallback();
-    private JpegPictureCallback mJpegPictureCallback = new JpegPictureCallback();
-    private TestErrorCallback mErrorCallback = new TestErrorCallback();
-    private AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback();
-    private AutoFocusMoveCallback mAutoFocusMoveCallback = new AutoFocusMoveCallback();
-
-    private Looper mLooper = null;
-    private final ConditionVariable mPreviewDone = new ConditionVariable();
-    private final ConditionVariable mFocusDone = new ConditionVariable();
-    private final ConditionVariable mSnapshotDone = new ConditionVariable();
-
-    Camera mCamera;
-
-    public CameraTest() {
-        super(PACKAGE, CameraCtsActivity.class);
-        if (VERBOSE) Log.v(TAG, "Camera Constructor");
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // to starCtsActivity.
-        getActivity();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (mCamera != null) {
-            mCamera.release();
-            mCamera = null;
-        }
-        super.tearDown();
-    }
-
-    /*
-     * Initializes the message looper so that the Camera object can
-     * receive the callback messages.
-     */
-    private void initializeMessageLooper(final int cameraId) throws IOException {
-        final ConditionVariable startDone = new ConditionVariable();
-        new Thread() {
-            @Override
-            public void run() {
-                Log.v(TAG, "start loopRun");
-                // Set up a looper to be used by camera.
-                Looper.prepare();
-                // Save the looper so that we can terminate this thread
-                // after we are done with it.
-                mLooper = Looper.myLooper();
-                try {
-                    mCamera = Camera.open(cameraId);
-                    mCamera.setErrorCallback(mErrorCallback);
-                } catch (RuntimeException e) {
-                    Log.e(TAG, "Fail to open camera." + e);
-                }
-                Log.v(TAG, "camera is opened");
-                startDone.open();
-                Looper.loop(); // Blocks forever until Looper.quit() is called.
-                if (VERBOSE) Log.v(TAG, "initializeMessageLooper: quit.");
-            }
-        }.start();
-
-        Log.v(TAG, "start waiting for looper");
-        if (!startDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
-            Log.v(TAG, "initializeMessageLooper: start timeout");
-            fail("initializeMessageLooper: start timeout");
-        }
-        assertNotNull("Fail to open camera.", mCamera);
-        mCamera.setPreviewDisplay(getActivity().getSurfaceView().getHolder());
-    }
-
-    /*
-     * Terminates the message looper thread.
-     */
-    private void terminateMessageLooper() throws Exception {
-        mLooper.quit();
-        // Looper.quit() is asynchronous. The looper may still has some
-        // preview callbacks in the queue after quit is called. The preview
-        // callback still uses the camera object (setHasPreviewCallback).
-        // After camera is released, RuntimeException will be thrown from
-        // the method. So we need to join the looper thread here.
-        mLooper.getThread().join();
-        mCamera.release();
-        mCamera = null;
-        assertEquals("Got camera error callback.", NO_ERROR, mCameraErrorCode);
-    }
-
-    // Align 'x' to 'to', which should be a power of 2
-    private static int align(int x, int to) {
-        return (x + (to-1)) & ~(to - 1);
-    }
-    private static int calculateBufferSize(int width, int height,
-                                           int format, int bpp) {
-
-        if (VERBOSE) {
-            Log.v(TAG, "calculateBufferSize: w=" + width + ",h=" + height
-            + ",f=" + format + ",bpp=" + bpp);
-        }
-
-        if (format == ImageFormat.YV12) {
-            /*
-            http://developer.android.com/reference/android/graphics/ImageFormat.html#YV12
-            */
-
-            int stride = align(width, 16);
-
-            int y_size = stride * height;
-            int c_stride = align(stride/2, 16);
-            int c_size = c_stride * height/2;
-            int size = y_size + c_size * 2;
-
-            if (VERBOSE) {
-                Log.v(TAG, "calculateBufferSize: YV12 size= " + size);
-            }
-
-            return size;
-
-        }
-        else {
-            return width * height * bpp / 8;
-        }
-    }
-
-    //Implement the previewCallback
-    private final class PreviewCallback
-            implements android.hardware.Camera.PreviewCallback {
-        public void onPreviewFrame(byte [] data, Camera camera) {
-            if (data == null) {
-                mPreviewCallbackResult = PREVIEW_CALLBACK_DATA_NULL;
-                mPreviewDone.open();
-                return;
-            }
-            Size size = camera.getParameters().getPreviewSize();
-            int format = camera.getParameters().getPreviewFormat();
-            int bitsPerPixel = ImageFormat.getBitsPerPixel(format);
-            if (calculateBufferSize(size.width, size.height,
-                    format, bitsPerPixel) != data.length) {
-                Log.e(TAG, "Invalid frame size " + data.length + ". width=" + size.width
-                        + ". height=" + size.height + ". bitsPerPixel=" + bitsPerPixel);
-                mPreviewCallbackResult = PREVIEW_CALLBACK_INVALID_FRAME_SIZE;
-                mPreviewDone.open();
-                return;
-            }
-            mPreviewCallbackResult = PREVIEW_CALLBACK_RECEIVED;
-            mCamera.stopPreview();
-            if (VERBOSE) Log.v(TAG, "notify the preview callback");
-            mPreviewDone.open();
-            if (VERBOSE) Log.v(TAG, "Preview callback stop");
-        }
-    }
-
-    //Implement the shutterCallback
-    private final class TestShutterCallback implements ShutterCallback {
-        public void onShutter() {
-            mShutterCallbackResult = true;
-            if (VERBOSE) Log.v(TAG, "onShutter called");
-        }
-    }
-
-    //Implement the RawPictureCallback
-    private final class RawPictureCallback implements PictureCallback {
-        public void onPictureTaken(byte [] rawData, Camera camera) {
-            mRawPictureCallbackResult = true;
-            if (VERBOSE) Log.v(TAG, "RawPictureCallback callback");
-        }
-    }
-
-    // Implement the JpegPictureCallback
-    private final class JpegPictureCallback implements PictureCallback {
-        public void onPictureTaken(byte[] rawData, Camera camera) {
-            try {
-                mJpegData = rawData;
-                if (rawData != null) {
-                    // try to store the picture on the SD card
-                    File rawoutput = new File(JPEG_PATH);
-                    FileOutputStream outStream = new FileOutputStream(rawoutput);
-                    outStream.write(rawData);
-                    outStream.close();
-                    mJpegPictureCallbackResult = true;
-
-                    if (VERBOSE) {
-                        Log.v(TAG, "JpegPictureCallback rawDataLength = " + rawData.length);
-                    }
-                } else {
-                    mJpegPictureCallbackResult = false;
-                }
-                mSnapshotDone.open();
-                if (VERBOSE) Log.v(TAG, "Jpeg Picture callback");
-            } catch (IOException e) {
-                // no need to fail here; callback worked fine
-                Log.w(TAG, "Error writing picture to sd card.");
-            }
-        }
-    }
-
-    // Implement the ErrorCallback
-    private final class TestErrorCallback implements ErrorCallback {
-        public void onError(int error, Camera camera) {
-            Log.e(TAG, "Got camera error=" + error);
-            mCameraErrorCode = error;
-        }
-    }
-
-    private final class AutoFocusCallback
-            implements android.hardware.Camera.AutoFocusCallback {
-        public void onAutoFocus(boolean success, Camera camera) {
-            mAutoFocusSucceeded = success;
-            Log.v(TAG, "AutoFocusCallback success=" + success);
-            mFocusDone.open();
-        }
-    }
-
-    private final class AutoFocusMoveCallback
-            implements android.hardware.Camera.AutoFocusMoveCallback {
-        @Override
-        public void onAutoFocusMoving(boolean start, Camera camera) {
-        }
-    }
-
-    private void waitForPreviewDone() {
-        if (VERBOSE) Log.v(TAG, "Wait for preview callback");
-        if (!mPreviewDone.block(WAIT_FOR_COMMAND_TO_COMPLETE)) {
-            // timeout could be expected or unexpected. The caller will decide.
-            Log.v(TAG, "waitForPreviewDone: timeout");
-        }
-        mPreviewDone.close();
-    }
-
-    private boolean waitForFocusDone() {
-        boolean result = mFocusDone.block(WAIT_FOR_FOCUS_TO_COMPLETE);
-        if (!result) {
-            // timeout could be expected or unexpected. The caller will decide.
-            Log.v(TAG, "waitForFocusDone: timeout");
-        }
-        mFocusDone.close();
-        return result;
-    }
-
-    private void waitForSnapshotDone() {
-        if (!mSnapshotDone.block(WAIT_FOR_SNAPSHOT_TO_COMPLETE)) {
-            // timeout could be expected or unexpected. The caller will decide.
-            Log.v(TAG, "waitForSnapshotDone: timeout");
-        }
-        mSnapshotDone.close();
-    }
-
-    private void checkPreviewCallback() throws Exception {
-        if (VERBOSE) Log.v(TAG, "check preview callback");
-        mCamera.startPreview();
-        waitForPreviewDone();
-        mCamera.setPreviewCallback(null);
-    }
-
-    /**
-     * Start preview and wait for the first preview callback, which indicates the
-     * preview becomes active.
-     */
-    private void blockingStartPreview() {
-        mCamera.setPreviewCallback(new SimplePreviewStreamCb(/*Id*/0));
-        mCamera.startPreview();
-        waitForPreviewDone();
-        mCamera.setPreviewCallback(null);
-    }
-
-    /*
-     * Test case 1: Take a picture and verify all the callback
-     * functions are called properly.
-     */
-    @UiThreadTest
-    public void testTakePicture() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            initializeMessageLooper(id);
-            mCamera.startPreview();
-            subtestTakePictureByCamera(false, 0, 0);
-            terminateMessageLooper();
-        }
-    }
-
-    private void subtestTakePictureByCamera(boolean isVideoSnapshot,
-            int videoWidth, int videoHeight) throws Exception {
-        int videoSnapshotMinArea =
-                videoWidth * videoHeight; // Temporary until new API definitions
-
-        Size pictureSize = mCamera.getParameters().getPictureSize();
-        mCamera.autoFocus(mAutoFocusCallback);
-        assertTrue(waitForFocusDone());
-        mJpegData = null;
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-        waitForSnapshotDone();
-        assertTrue("Shutter callback not received", mShutterCallbackResult);
-        assertTrue("Raw picture callback not received", mRawPictureCallbackResult);
-        assertTrue("Jpeg picture callback not recieved", mJpegPictureCallbackResult);
-        assertNotNull(mJpegData);
-        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
-        bmpOptions.inJustDecodeBounds = true;
-        BitmapFactory.decodeByteArray(mJpegData, 0, mJpegData.length, bmpOptions);
-        if (!isVideoSnapshot) {
-            assertEquals(pictureSize.width, bmpOptions.outWidth);
-            assertEquals(pictureSize.height, bmpOptions.outHeight);
-        } else {
-            int realArea = bmpOptions.outWidth * bmpOptions.outHeight;
-            if (VERBOSE) Log.v(TAG, "Video snapshot is " +
-                    bmpOptions.outWidth + " x " + bmpOptions.outHeight +
-                    ", video size is " + videoWidth + " x " + videoHeight);
-            assertTrue ("Video snapshot too small! Expected at least " +
-                    videoWidth + " x " + videoHeight + " (" +
-                    videoSnapshotMinArea/1000000. + " MP)",
-                    realArea >= videoSnapshotMinArea);
-        }
-    }
-
-    @UiThreadTest
-    public void testPreviewCallback() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testPreviewCallbackByCamera(id);
-        }
-    }
-
-    private void testPreviewCallbackByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        mCamera.setPreviewCallback(mPreviewCallback);
-        checkPreviewCallback();
-        terminateMessageLooper();
-        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
-
-        mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
-        initializeMessageLooper(cameraId);
-        checkPreviewCallback();
-        terminateMessageLooper();
-        assertEquals(PREVIEW_CALLBACK_NOT_RECEIVED, mPreviewCallbackResult);
-
-        // Test all preview sizes.
-        initializeMessageLooper(cameraId);
-        Parameters parameters = mCamera.getParameters();
-        for (Size size: parameters.getSupportedPreviewSizes()) {
-            mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
-            mCamera.setPreviewCallback(mPreviewCallback);
-            parameters.setPreviewSize(size.width, size.height);
-            mCamera.setParameters(parameters);
-            assertEquals(size, mCamera.getParameters().getPreviewSize());
-            checkPreviewCallback();
-            assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
-            try {
-                // Wait for a while to throw away the remaining preview frames.
-                Thread.sleep(1000);
-            } catch(Exception e) {
-                // ignore
-            }
-            mPreviewDone.close();
-        }
-        terminateMessageLooper();
-    }
-
-    @UiThreadTest
-    public void testSetOneShotPreviewCallback() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testSetOneShotPreviewCallbackByCamera(id);
-        }
-    }
-
-    private void testSetOneShotPreviewCallbackByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        mCamera.setOneShotPreviewCallback(mPreviewCallback);
-        checkPreviewCallback();
-        terminateMessageLooper();
-        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
-
-        mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
-        initializeMessageLooper(cameraId);
-        checkPreviewCallback();
-        terminateMessageLooper();
-        assertEquals(PREVIEW_CALLBACK_NOT_RECEIVED, mPreviewCallbackResult);
-    }
-
-    @UiThreadTest
-    public void testSetPreviewDisplay() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testSetPreviewDisplayByCamera(id);
-        }
-    }
-
-    private void testSetPreviewDisplayByCamera(int cameraId) throws Exception {
-        SurfaceHolder holder = getActivity().getSurfaceView().getHolder();
-        initializeMessageLooper(cameraId);
-
-        // Check the order: startPreview->setPreviewDisplay.
-        mCamera.setOneShotPreviewCallback(mPreviewCallback);
-        mCamera.startPreview();
-        mCamera.setPreviewDisplay(holder);
-        waitForPreviewDone();
-        terminateMessageLooper();
-        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
-
-        // Check the order: setPreviewDisplay->startPreview.
-        initializeMessageLooper(cameraId);
-        mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
-        mCamera.setOneShotPreviewCallback(mPreviewCallback);
-        mCamera.setPreviewDisplay(holder);
-        mCamera.startPreview();
-        waitForPreviewDone();
-        mCamera.stopPreview();
-        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
-
-        // Check the order: setting preview display to null->startPreview->
-        // setPreviewDisplay.
-        mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
-        mCamera.setOneShotPreviewCallback(mPreviewCallback);
-        mCamera.setPreviewDisplay(null);
-        mCamera.startPreview();
-        mCamera.setPreviewDisplay(holder);
-        waitForPreviewDone();
-        terminateMessageLooper();
-        assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
-    }
-
-    @UiThreadTest
-    public void testDisplayOrientation() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testDisplayOrientationByCamera(id);
-        }
-    }
-
-    private void testDisplayOrientationByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-
-        // Check valid arguments.
-        mCamera.setDisplayOrientation(0);
-        mCamera.setDisplayOrientation(90);
-        mCamera.setDisplayOrientation(180);
-        mCamera.setDisplayOrientation(270);
-
-        // Check invalid arguments.
-        try {
-            mCamera.setDisplayOrientation(45);
-            fail("Should throw exception for invalid arguments");
-        } catch (RuntimeException ex) {
-            // expected
-        }
-
-        // Start preview.
-        mCamera.startPreview();
-
-        // Check setting orientation during preview is allowed.
-        mCamera.setDisplayOrientation(90);
-        mCamera.setDisplayOrientation(180);
-        mCamera.setDisplayOrientation(270);
-        mCamera.setDisplayOrientation(00);
-
-        terminateMessageLooper();
-    }
-
-    @UiThreadTest
-    public void testParameters() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testParametersByCamera(id);
-        }
-    }
-
-    private void testParametersByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        // we can get parameters just by getxxx method due to the private constructor
-        Parameters pSet = mCamera.getParameters();
-        assertParameters(pSet);
-        terminateMessageLooper();
-    }
-
-    // Also test Camera.Parameters
-    private void assertParameters(Parameters parameters) {
-        // Parameters constants
-        final int PICTURE_FORMAT = ImageFormat.JPEG;
-        final int PREVIEW_FORMAT = ImageFormat.NV21;
-
-        // Before setting Parameters
-        final int origPictureFormat = parameters.getPictureFormat();
-        final int origPictureWidth = parameters.getPictureSize().width;
-        final int origPictureHeight = parameters.getPictureSize().height;
-        final int origPreviewFormat = parameters.getPreviewFormat();
-        final int origPreviewWidth = parameters.getPreviewSize().width;
-        final int origPreviewHeight = parameters.getPreviewSize().height;
-        final int origPreviewFrameRate = parameters.getPreviewFrameRate();
-
-        assertTrue(origPictureWidth > 0);
-        assertTrue(origPictureHeight > 0);
-        assertTrue(origPreviewWidth > 0);
-        assertTrue(origPreviewHeight > 0);
-        assertTrue(origPreviewFrameRate > 0);
-
-        // The default preview format must be yuv420 (NV21).
-        assertEquals(ImageFormat.NV21, origPreviewFormat);
-
-        // The default picture format must be Jpeg.
-        assertEquals(ImageFormat.JPEG, origPictureFormat);
-
-        // If camera supports flash, the default flash mode must be off.
-        String flashMode = parameters.getFlashMode();
-        assertTrue(flashMode == null || flashMode.equals(parameters.FLASH_MODE_OFF));
-        String wb = parameters.getWhiteBalance();
-        assertTrue(wb == null || wb.equals(parameters.WHITE_BALANCE_AUTO));
-        String effect = parameters.getColorEffect();
-        assertTrue(effect == null || effect.equals(parameters.EFFECT_NONE));
-
-        // Some parameters must be supported.
-        List<Size> previewSizes = parameters.getSupportedPreviewSizes();
-        List<Size> pictureSizes = parameters.getSupportedPictureSizes();
-        List<Integer> previewFormats = parameters.getSupportedPreviewFormats();
-        List<Integer> pictureFormats = parameters.getSupportedPictureFormats();
-        List<Integer> frameRates = parameters.getSupportedPreviewFrameRates();
-        List<String> focusModes = parameters.getSupportedFocusModes();
-        String focusMode = parameters.getFocusMode();
-        float focalLength = parameters.getFocalLength();
-        float horizontalViewAngle = parameters.getHorizontalViewAngle();
-        float verticalViewAngle = parameters.getVerticalViewAngle();
-        int jpegQuality = parameters.getJpegQuality();
-        int jpegThumnailQuality = parameters.getJpegThumbnailQuality();
-        assertTrue(previewSizes != null && previewSizes.size() != 0);
-        assertTrue(pictureSizes != null && pictureSizes.size() != 0);
-        assertTrue(previewFormats != null && previewFormats.size() >= 2);
-        assertTrue(previewFormats.contains(ImageFormat.NV21));
-        assertTrue(previewFormats.contains(ImageFormat.YV12));
-        assertTrue(pictureFormats != null && pictureFormats.size() != 0);
-        assertTrue(frameRates != null && frameRates.size() != 0);
-        assertTrue(focusModes != null && focusModes.size() != 0);
-        assertNotNull(focusMode);
-        // The default focus mode must be auto if it exists.
-        if (focusModes.contains(Parameters.FOCUS_MODE_AUTO)) {
-            assertEquals(Parameters.FOCUS_MODE_AUTO, focusMode);
-        }
-        assertTrue(focalLength > 0);
-        assertTrue(horizontalViewAngle > 0 && horizontalViewAngle <= 360);
-        assertTrue(verticalViewAngle > 0 && verticalViewAngle <= 360);
-        Size previewSize = previewSizes.get(0);
-        Size pictureSize = pictureSizes.get(0);
-        assertTrue(jpegQuality >= 1 && jpegQuality <= 100);
-        assertTrue(jpegThumnailQuality >= 1 && jpegThumnailQuality <= 100);
-
-        // If a parameter is supported, both getXXX and getSupportedXXX have to
-        // be non null.
-        if (parameters.getWhiteBalance() != null) {
-            assertNotNull(parameters.getSupportedWhiteBalance());
-        }
-        if (parameters.getSupportedWhiteBalance() != null) {
-            assertNotNull(parameters.getWhiteBalance());
-        }
-        if (parameters.getColorEffect() != null) {
-            assertNotNull(parameters.getSupportedColorEffects());
-        }
-        if (parameters.getSupportedColorEffects() != null) {
-            assertNotNull(parameters.getColorEffect());
-        }
-        if (parameters.getAntibanding() != null) {
-            assertNotNull(parameters.getSupportedAntibanding());
-        }
-        if (parameters.getSupportedAntibanding() != null) {
-            assertNotNull(parameters.getAntibanding());
-        }
-        if (parameters.getSceneMode() != null) {
-            assertNotNull(parameters.getSupportedSceneModes());
-        }
-        if (parameters.getSupportedSceneModes() != null) {
-            assertNotNull(parameters.getSceneMode());
-        }
-        if (parameters.getFlashMode() != null) {
-            assertNotNull(parameters.getSupportedFlashModes());
-        }
-        if (parameters.getSupportedFlashModes() != null) {
-            assertNotNull(parameters.getFlashMode());
-        }
-
-        // Check if the sizes value contain invalid characters.
-        assertNoLetters(parameters.get("preview-size-values"), "preview-size-values");
-        assertNoLetters(parameters.get("picture-size-values"), "picture-size-values");
-        assertNoLetters(parameters.get("jpeg-thumbnail-size-values"),
-                "jpeg-thumbnail-size-values");
-
-        // Set the parameters.
-        parameters.setPictureFormat(PICTURE_FORMAT);
-        assertEquals(PICTURE_FORMAT, parameters.getPictureFormat());
-        parameters.setPictureSize(pictureSize.width, pictureSize.height);
-        assertEquals(pictureSize.width, parameters.getPictureSize().width);
-        assertEquals(pictureSize.height, parameters.getPictureSize().height);
-        parameters.setPreviewFormat(PREVIEW_FORMAT);
-        assertEquals(PREVIEW_FORMAT, parameters.getPreviewFormat());
-        parameters.setPreviewFrameRate(frameRates.get(0));
-        assertEquals(frameRates.get(0).intValue(), parameters.getPreviewFrameRate());
-        parameters.setPreviewSize(previewSize.width, previewSize.height);
-        assertEquals(previewSize.width, parameters.getPreviewSize().width);
-        assertEquals(previewSize.height, parameters.getPreviewSize().height);
-
-        mCamera.setParameters(parameters);
-        Parameters paramActual = mCamera.getParameters();
-
-        assertTrue(isValidPixelFormat(paramActual.getPictureFormat()));
-        assertEquals(pictureSize.width, paramActual.getPictureSize().width);
-        assertEquals(pictureSize.height, paramActual.getPictureSize().height);
-        assertTrue(isValidPixelFormat(paramActual.getPreviewFormat()));
-        assertEquals(previewSize.width, paramActual.getPreviewSize().width);
-        assertEquals(previewSize.height, paramActual.getPreviewSize().height);
-        assertTrue(paramActual.getPreviewFrameRate() > 0);
-
-        checkExposureCompensation(parameters);
-        checkPreferredPreviewSizeForVideo(parameters);
-    }
-
-    private void checkPreferredPreviewSizeForVideo(Parameters parameters) {
-        List<Size> videoSizes = parameters.getSupportedVideoSizes();
-        Size preferredPreviewSize = parameters.getPreferredPreviewSizeForVideo();
-
-        // If getSupportedVideoSizes() returns null,
-        // getPreferredPreviewSizeForVideo() will return null;
-        // otherwise, if getSupportedVideoSizes() does not return null,
-        // getPreferredPreviewSizeForVideo() will not return null.
-        if (videoSizes == null) {
-            assertNull(preferredPreviewSize);
-        } else {
-            assertNotNull(preferredPreviewSize);
-        }
-
-        // If getPreferredPreviewSizeForVideo() returns null,
-        // getSupportedVideoSizes() will return null;
-        // otherwise, if getPreferredPreviewSizeForVideo() does not return null,
-        // getSupportedVideoSizes() will not return null.
-        if (preferredPreviewSize == null) {
-            assertNull(videoSizes);
-        } else {
-            assertNotNull(videoSizes);
-        }
-
-        if (videoSizes != null) {  // implies: preferredPreviewSize != null
-            // If getSupportedVideoSizes() does not return null,
-            // the returned list will contain at least one size.
-            assertTrue(videoSizes.size() > 0);
-
-            // In addition, getPreferredPreviewSizeForVideo() returns a size
-            // that is among the supported preview sizes.
-            List<Size> previewSizes = parameters.getSupportedPreviewSizes();
-            assertNotNull(previewSizes);
-            assertTrue(previewSizes.size() > 0);
-            assertTrue(previewSizes.contains(preferredPreviewSize));
-        }
-    }
-
-    private void checkExposureCompensation(Parameters parameters) {
-        assertEquals(0, parameters.getExposureCompensation());
-        int max = parameters.getMaxExposureCompensation();
-        int min = parameters.getMinExposureCompensation();
-        float step = parameters.getExposureCompensationStep();
-        if (max == 0 && min == 0) {
-            assertEquals(0f, step, 0.000001f);
-            return;
-        }
-        assertTrue(step > 0);
-        assertTrue(max >= 0);
-        assertTrue(min <= 0);
-    }
-
-    private boolean isValidPixelFormat(int format) {
-        return (format == ImageFormat.RGB_565) || (format == ImageFormat.NV21)
-                || (format == ImageFormat.JPEG) || (format == ImageFormat.YUY2);
-    }
-
-    @UiThreadTest
-    public void testJpegThumbnailSize() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            initializeMessageLooper(id);
-            testJpegThumbnailSizeByCamera(false, 0, 0);
-            terminateMessageLooper();
-        }
-    }
-
-    private void testJpegThumbnailSizeByCamera(boolean recording,
-            int recordingWidth, int recordingHeight) throws Exception {
-        // Thumbnail size parameters should have valid values.
-        Parameters p = mCamera.getParameters();
-        Size size = p.getJpegThumbnailSize();
-        assertTrue(size.width > 0 && size.height > 0);
-        List<Size> sizes = p.getSupportedJpegThumbnailSizes();
-        assertTrue(sizes.size() >= 2);
-        assertTrue(sizes.contains(size));
-        assertTrue(sizes.contains(mCamera.new Size(0, 0)));
-        Size pictureSize = p.getPictureSize();
-
-        // Test if the thumbnail size matches the setting.
-        if (!recording) mCamera.startPreview();
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-        waitForSnapshotDone();
-        assertTrue(mJpegPictureCallbackResult);
-        ExifInterface exif = new ExifInterface(JPEG_PATH);
-        assertTrue(exif.hasThumbnail());
-        byte[] thumb = exif.getThumbnail();
-        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
-        bmpOptions.inJustDecodeBounds = true;
-        BitmapFactory.decodeByteArray(thumb, 0, thumb.length, bmpOptions);
-        if (!recording) {
-            assertEquals(size.width, bmpOptions.outWidth);
-            assertEquals(size.height, bmpOptions.outHeight);
-        } else {
-            assertTrue(bmpOptions.outWidth >= recordingWidth ||
-                    bmpOptions.outWidth == size.width);
-            assertTrue(bmpOptions.outHeight >= recordingHeight ||
-                    bmpOptions.outHeight == size.height);
-        }
-
-        // Test no thumbnail case.
-        p.setJpegThumbnailSize(0, 0);
-        mCamera.setParameters(p);
-        Size actual = mCamera.getParameters().getJpegThumbnailSize();
-        assertEquals(0, actual.width);
-        assertEquals(0, actual.height);
-        if (!recording) mCamera.startPreview();
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-        waitForSnapshotDone();
-        assertTrue(mJpegPictureCallbackResult);
-        exif = new ExifInterface(JPEG_PATH);
-        assertFalse(exif.hasThumbnail());
-        // Primary image should still be valid for no thumbnail capture.
-        BitmapFactory.decodeFile(JPEG_PATH, bmpOptions);
-        if (!recording) {
-            assertTrue("Jpeg primary image size should match requested size",
-                    bmpOptions.outWidth == pictureSize.width &&
-                    bmpOptions.outHeight == pictureSize.height);
-        } else {
-            assertTrue(bmpOptions.outWidth >= recordingWidth ||
-                    bmpOptions.outWidth == size.width);
-            assertTrue(bmpOptions.outHeight >= recordingHeight ||
-                    bmpOptions.outHeight == size.height);
-        }
-
-        assertNotNull("Jpeg primary image data should be decodable",
-                BitmapFactory.decodeFile(JPEG_PATH));
-    }
-
-    @UiThreadTest
-    public void testJpegExif() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            initializeMessageLooper(id);
-            testJpegExifByCamera(false);
-            terminateMessageLooper();
-        }
-    }
-
-    private void testJpegExifByCamera(boolean recording) throws Exception {
-        if (!recording) mCamera.startPreview();
-        Date date = new Date(System.currentTimeMillis());
-        String localDatetime = new SimpleDateFormat("yyyy:MM:dd HH:").format(date);
-
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-        waitForSnapshotDone();
-
-        Camera.Parameters parameters = mCamera.getParameters();
-        double focalLength = parameters.getFocalLength();
-
-        // Test various exif tags.
-        ExifInterface exif = new ExifInterface(JPEG_PATH);
-        StringBuffer failedCause = new StringBuffer("Jpeg exif test failed:\n");
-        boolean extraExiftestPassed = checkExtraExifTagsSucceeds(failedCause, exif);
-
-        if (VERBOSE) Log.v(TAG, "Testing exif tag TAG_DATETIME");
-        String datetime = exif.getAttribute(ExifInterface.TAG_DATETIME);
-        assertNotNull(datetime);
-        // Datetime should be local time.
-        assertTrue(datetime.startsWith(localDatetime));
-        assertTrue(datetime.length() == 19); // EXIF spec is "YYYY:MM:DD HH:MM:SS".
-        checkGpsDataNull(exif);
-        double exifFocalLength = exif.getAttributeDouble(ExifInterface.TAG_FOCAL_LENGTH, -1);
-        assertEquals(focalLength, exifFocalLength, 0.001);
-        // Test image width and height exif tags. They should match the jpeg.
-        assertBitmapAndJpegSizeEqual(mJpegData, exif);
-
-        // Test gps exif tags.
-        if (VERBOSE) Log.v(TAG, "Testing exif GPS tags");
-        testGpsExifValues(parameters, 37.736071, -122.441983, 21, 1199145600,
-            "GPS NETWORK HYBRID ARE ALL FINE.");
-        testGpsExifValues(parameters, 0.736071, 0.441983, 1, 1199145601, "GPS");
-        testGpsExifValues(parameters, -89.736071, -179.441983, 100000, 1199145602, "NETWORK");
-
-        // Test gps tags do not exist after calling removeGpsData. Also check if
-        // image width and height exif match the jpeg when jpeg rotation is set.
-        if (VERBOSE) Log.v(TAG, "Testing exif GPS tag removal");
-        if (!recording) mCamera.startPreview();
-        parameters.removeGpsData();
-        parameters.setRotation(90); // For testing image width and height exif.
-        mCamera.setParameters(parameters);
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-        waitForSnapshotDone();
-        exif = new ExifInterface(JPEG_PATH);
-        checkGpsDataNull(exif);
-        assertBitmapAndJpegSizeEqual(mJpegData, exif);
-        // Reset the rotation to prevent from affecting other tests.
-        parameters.setRotation(0);
-        mCamera.setParameters(parameters);
-    }
-
-    /**
-     * Sanity check of some extra exif tags.
-     * <p>
-     * Sanity check some extra exif tags without asserting the check failures
-     * immediately. When a failure is detected, the failure cause is logged,
-     * the rest of the tests are still executed. The caller can assert with the
-     * failure cause based on the returned test status.
-     * </p>
-     *
-     * @param logBuf Log failure cause to this StringBuffer if there is
-     * any failure.
-     * @param exif The exif data associated with a jpeg image being tested.
-     * @return true if no test failure is found, false if there is any failure.
-     */
-    private boolean checkExtraExifTagsSucceeds(StringBuffer logBuf, ExifInterface exif) {
-        if (logBuf == null || exif == null) {
-            throw new IllegalArgumentException("failureCause and exif shouldn't be null");
-        }
-
-        if (VERBOSE) Log.v(TAG, "Testing extra exif tags");
-        boolean allTestsPassed = true;
-        boolean passedSoFar = true;
-        String failureMsg;
-
-        // TAG_EXPOSURE_TIME
-        // ExifInterface API gives exposure time value in the form of float instead of rational
-        String exposureTime = exif.getAttribute(ExifInterface.TAG_EXPOSURE_TIME);
-        passedSoFar = expectNotNull("Exif TAG_EXPOSURE_TIME is null!", logBuf, exposureTime);
-        if (passedSoFar) {
-            double exposureTimeValue = Double.parseDouble(exposureTime);
-            failureMsg = "Exif exposure time " + exposureTime + " should be a positive value";
-            passedSoFar = expectTrue(failureMsg, logBuf, exposureTimeValue > 0);
-        }
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        // TAG_APERTURE
-        // ExifInterface API gives aperture value in the form of float instead of rational
-        String aperture = exif.getAttribute(ExifInterface.TAG_APERTURE);
-        passedSoFar = expectNotNull("Exif TAG_APERTURE is null!", logBuf, aperture);
-        if (passedSoFar) {
-            double apertureValue = Double.parseDouble(aperture);
-            passedSoFar = expectTrue("Exif TAG_APERTURE value " + aperture + " should be positive!",
-                    logBuf, apertureValue > 0);
-        }
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        // TAG_FLASH
-        String flash = exif.getAttribute(ExifInterface.TAG_FLASH);
-        passedSoFar = expectNotNull("Exif TAG_FLASH is null!", logBuf, flash);
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        // TAG_WHITE_BALANCE
-        String whiteBalance = exif.getAttribute(ExifInterface.TAG_WHITE_BALANCE);
-        passedSoFar = expectNotNull("Exif TAG_WHITE_BALANCE is null!", logBuf, whiteBalance);
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        // TAG_MAKE
-        String make = exif.getAttribute(ExifInterface.TAG_MAKE);
-        passedSoFar = expectNotNull("Exif TAG_MAKE is null!", logBuf, make);
-        if (passedSoFar) {
-            passedSoFar = expectTrue("Exif TAG_MODEL value: " + make
-                    + " should match build manufacturer: " + Build.MANUFACTURER, logBuf,
-                    make.equals(Build.MANUFACTURER));
-        }
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        // TAG_MODEL
-        String model = exif.getAttribute(ExifInterface.TAG_MODEL);
-        passedSoFar = expectNotNull("Exif TAG_MODEL is null!", logBuf, model);
-        if (passedSoFar) {
-            passedSoFar = expectTrue("Exif TAG_MODEL value: " + model
-                    + " should match build manufacturer: " + Build.MODEL, logBuf,
-                    model.equals(Build.MODEL));
-        }
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        // TAG_ISO
-        int iso = exif.getAttributeInt(ExifInterface.TAG_ISO, -1);
-        passedSoFar = expectTrue("Exif ISO value " + iso + " is invalid", logBuf, iso > 0);
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        // TAG_DATETIME_DIGITIZED (a.k.a Create time for digital cameras).
-        String digitizedTime = exif.getAttribute(TAG_DATETIME_DIGITIZED);
-        passedSoFar = expectNotNull("Exif TAG_DATETIME_DIGITIZED is null!", logBuf, digitizedTime);
-        if (passedSoFar) {
-            String datetime = exif.getAttribute(ExifInterface.TAG_DATETIME);
-            passedSoFar = expectNotNull("Exif TAG_DATETIME is null!", logBuf, datetime);
-            if (passedSoFar) {
-                passedSoFar = expectTrue("dataTime should match digitizedTime", logBuf,
-                        digitizedTime.equals(datetime));
-            }
-        }
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        /**
-         * TAG_SUBSEC_TIME. Since the sub second tag strings are truncated to at
-         * most 9 digits in ExifInterface implementation, use getAttributeInt to
-         * sanitize it. When the default value -1 is returned, it means that
-         * this exif tag either doesn't exist or is a non-numerical invalid
-         * string. Same rule applies to the rest of sub second tags.
-         */
-        int subSecTime = exif.getAttributeInt(TAG_SUBSEC_TIME, -1);
-        passedSoFar = expectTrue(
-                "Exif TAG_SUBSEC_TIME value is null or invalid!", logBuf, subSecTime > 0);
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        // TAG_SUBSEC_TIME_ORIG
-        int subSecTimeOrig = exif.getAttributeInt(TAG_SUBSEC_TIME_ORIG, -1);
-        passedSoFar = expectTrue(
-                "Exif TAG_SUBSEC_TIME_ORIG value is null or invalid!", logBuf, subSecTimeOrig > 0);
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        // TAG_SUBSEC_TIME_DIG
-        int subSecTimeDig = exif.getAttributeInt(TAG_SUBSEC_TIME_DIG, -1);
-        passedSoFar = expectTrue(
-                "Exif TAG_SUBSEC_TIME_DIG value is null or invalid!", logBuf, subSecTimeDig > 0);
-        allTestsPassed = allTestsPassed && passedSoFar;
-
-        return allTestsPassed;
-    }
-
-    /**
-     * Check if object is null and log failure msg.
-     *
-     * @param msg Failure msg.
-     * @param logBuffer StringBuffer to log the failure msg.
-     * @param obj Object to test.
-     * @return true if object is not null, otherwise return false.
-     */
-    private boolean expectNotNull(String msg, StringBuffer logBuffer, Object obj)
-    {
-        if (obj == null) {
-            logBuffer.append(msg + "\n");
-        }
-        return (obj != null);
-    }
-
-    /**
-     * Check if condition is false and log failure msg.
-     *
-     * @param msg Failure msg.
-     * @param logBuffer StringBuffer to log the failure msg.
-     * @param condition Condition to test.
-     * @return The value of the condition.
-     */
-    private boolean expectTrue(String msg, StringBuffer logBuffer, boolean condition) {
-        if (!condition) {
-            logBuffer.append(msg + "\n");
-        }
-        return condition;
-    }
-
-    private void assertBitmapAndJpegSizeEqual(byte[] jpegData, ExifInterface exif) {
-        int exifWidth = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
-        int exifHeight = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
-        assertTrue(exifWidth != 0 && exifHeight != 0);
-        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
-        bmpOptions.inJustDecodeBounds = true;
-        BitmapFactory.decodeByteArray(jpegData, 0, jpegData.length, bmpOptions);
-        assertEquals(bmpOptions.outWidth, exifWidth);
-        assertEquals(bmpOptions.outHeight, exifHeight);
-    }
-
-    private void testGpsExifValues(Parameters parameters, double latitude,
-            double longitude, double altitude, long timestamp, String method)
-            throws IOException {
-        mCamera.startPreview();
-        parameters.setGpsLatitude(latitude);
-        parameters.setGpsLongitude(longitude);
-        parameters.setGpsAltitude(altitude);
-        parameters.setGpsTimestamp(timestamp);
-        parameters.setGpsProcessingMethod(method);
-        mCamera.setParameters(parameters);
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-        waitForSnapshotDone();
-        ExifInterface exif = new ExifInterface(JPEG_PATH);
-        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
-        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
-        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF));
-        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF));
-        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP));
-        assertNotNull(exif.getAttribute(ExifInterface.TAG_GPS_DATESTAMP));
-        assertEquals(method, exif.getAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD));
-        float[] latLong = new float[2];
-        assertTrue(exif.getLatLong(latLong));
-        assertEquals((float)latitude, latLong[0], 0.0001f);
-        assertEquals((float)longitude, latLong[1], 0.0001f);
-        assertEquals(altitude, exif.getAltitude(-1), 1);
-        assertEquals(timestamp, getGpsDateTimeFromJpeg(exif) / 1000);
-    }
-
-    private long getGpsDateTimeFromJpeg(ExifInterface exif) {
-        String date = exif.getAttribute(ExifInterface.TAG_GPS_DATESTAMP);
-        String time = exif.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP);
-        if (date == null || time == null) return -1;
-
-        String dateTimeString = date + ' ' + time;
-        ParsePosition pos = new ParsePosition(0);
-        try {
-            SimpleDateFormat formatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
-            formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
-
-            Date datetime = formatter.parse(dateTimeString, pos);
-            if (datetime == null) return -1;
-            return datetime.getTime();
-        } catch (IllegalArgumentException ex) {
-            return -1;
-        }
-    }
-
-    private void checkGpsDataNull(ExifInterface exif) {
-        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE));
-        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE));
-        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF));
-        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF));
-        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_TIMESTAMP));
-        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_DATESTAMP));
-        assertNull(exif.getAttribute(ExifInterface.TAG_GPS_PROCESSING_METHOD));
-    }
-
-    @UiThreadTest
-    public void testLockUnlock() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testLockUnlockByCamera(id);
-        }
-    }
-
-    private void testLockUnlockByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        Camera.Parameters parameters = mCamera.getParameters();
-        SurfaceHolder surfaceHolder;
-        surfaceHolder = getActivity().getSurfaceView().getHolder();
-        CamcorderProfile profile = CamcorderProfile.get(cameraId,
-                CamcorderProfile.QUALITY_LOW);
-
-        // Set the preview size.
-        setPreviewSizeByProfile(parameters, profile);
-
-        mCamera.setParameters(parameters);
-        mCamera.setPreviewDisplay(surfaceHolder);
-        mCamera.startPreview();
-        mCamera.lock();  // Locking again from the same process has no effect.
-        try {
-            recordVideo(profile, surfaceHolder);
-            fail("Recording should not succeed because camera is locked.");
-        } catch (Exception e) {
-            // expected
-        }
-
-        mCamera.unlock();  // Unlock the camera so media recorder can use it.
-        try {
-            mCamera.setParameters(parameters);
-            fail("setParameters should not succeed because camera is unlocked.");
-        } catch (RuntimeException e) {
-            // expected
-        }
-
-        recordVideo(profile, surfaceHolder);  // should not throw exception
-        // Media recorder already releases the camera so the test application
-        // can lock and use the camera now.
-        mCamera.lock();  // should not fail
-        mCamera.setParameters(parameters);  // should not fail
-        terminateMessageLooper();
-    }
-
-    private void setPreviewSizeByProfile(Parameters parameters, CamcorderProfile profile) {
-        if (parameters.getSupportedVideoSizes() == null) {
-            parameters.setPreviewSize(profile.videoFrameWidth,
-                    profile.videoFrameHeight);
-        } else {  // Driver supports separates outputs for preview and video.
-            List<Size> sizes = parameters.getSupportedPreviewSizes();
-            Size preferred = parameters.getPreferredPreviewSizeForVideo();
-            int product = preferred.width * preferred.height;
-            for (Size size: sizes) {
-                if (size.width * size.height <= product) {
-                    parameters.setPreviewSize(size.width, size.height);
-                    break;
-                }
-            }
-        }
-    }
-
-    private void recordVideo(CamcorderProfile profile,
-            SurfaceHolder holder) throws Exception {
-        MediaRecorder recorder = new MediaRecorder();
-        try {
-            // Pass the camera from the test application to media recorder.
-            recorder.setCamera(mCamera);
-            recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
-            recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-            recorder.setProfile(profile);
-            recorder.setOutputFile("/dev/null");
-            recorder.setPreviewDisplay(holder.getSurface());
-            recorder.prepare();
-            recorder.start();
-
-            // Apps can use the camera after start since API level 13.
-            Parameters parameters = mCamera.getParameters();
-            if (parameters.isZoomSupported()) {
-               if (parameters.getMaxZoom() > 0) {
-                   parameters.setZoom(1);
-                   mCamera.setParameters(parameters);
-                   parameters.setZoom(0);
-                   mCamera.setParameters(parameters);
-               }
-            }
-            if (parameters.isSmoothZoomSupported()) {
-                if (parameters.getMaxZoom() > 0) {
-                    ZoomListener zoomListener = new ZoomListener();
-                    mCamera.setZoomChangeListener(zoomListener);
-                    mCamera.startSmoothZoom(1);
-                    assertTrue(zoomListener.mZoomDone.block(1000));
-                }
-            }
-
-            try {
-                mCamera.unlock();
-                fail("unlock should not succeed during recording.");
-            } catch(RuntimeException e) {
-                // expected
-            }
-
-            Thread.sleep(2000);
-            recorder.stop();
-        } finally {
-            recorder.release();
-        }
-    }
-
-    @UiThreadTest
-    public void testPreviewCallbackWithBuffer() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testPreviewCallbackWithBufferByCamera(id);
-        }
-    }
-
-    private void testPreviewCallbackWithBufferByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        SurfaceHolder surfaceHolder;
-        surfaceHolder = getActivity().getSurfaceView().getHolder();
-        mCamera.setPreviewDisplay(surfaceHolder);
-        Parameters parameters = mCamera.getParameters();
-        PreviewCallbackWithBuffer callback = new PreviewCallbackWithBuffer();
-        // Test all preview sizes.
-        for (Size size: parameters.getSupportedPreviewSizes()) {
-            parameters.setPreviewSize(size.width, size.height);
-            mCamera.setParameters(parameters);
-            assertEquals(size, mCamera.getParameters().getPreviewSize());
-            callback.mNumCbWithBuffer1 = 0;
-            callback.mNumCbWithBuffer2 = 0;
-            callback.mNumCbWithBuffer3 = 0;
-            int format = mCamera.getParameters().getPreviewFormat();
-            int bitsPerPixel = ImageFormat.getBitsPerPixel(format);
-            callback.mBuffer1 = new byte[size.width * size.height * bitsPerPixel / 8];
-            callback.mBuffer2 = new byte[size.width * size.height * bitsPerPixel / 8];
-            callback.mBuffer3 = new byte[size.width * size.height * bitsPerPixel / 8];
-
-            // Test if we can get the preview callbacks with specified buffers.
-            mCamera.addCallbackBuffer(callback.mBuffer1);
-            mCamera.addCallbackBuffer(callback.mBuffer2);
-            mCamera.setPreviewCallbackWithBuffer(callback);
-            mCamera.startPreview();
-            waitForPreviewDone();
-            assertFalse(callback.mPreviewDataNull);
-            assertFalse(callback.mInvalidData);
-            assertEquals(1, callback.mNumCbWithBuffer1);
-            assertEquals(1, callback.mNumCbWithBuffer2);
-            assertEquals(0, callback.mNumCbWithBuffer3);
-
-            // Test if preview callback with buffer still works during preview.
-            mCamera.addCallbackBuffer(callback.mBuffer3);
-            waitForPreviewDone();
-            assertFalse(callback.mPreviewDataNull);
-            assertFalse(callback.mInvalidData);
-            assertEquals(1, callback.mNumCbWithBuffer1);
-            assertEquals(1, callback.mNumCbWithBuffer2);
-            assertEquals(1, callback.mNumCbWithBuffer3);
-            mCamera.setPreviewCallbackWithBuffer(null);
-            mCamera.stopPreview();
-        }
-        terminateMessageLooper();
-    }
-
-    private final class PreviewCallbackWithBuffer
-            implements android.hardware.Camera.PreviewCallback {
-        public int mNumCbWithBuffer1, mNumCbWithBuffer2, mNumCbWithBuffer3;
-        public byte[] mBuffer1, mBuffer2, mBuffer3;
-        public boolean mPreviewDataNull, mInvalidData;
-        public void onPreviewFrame(byte[] data, Camera camera) {
-            if (data == null) {
-                Log.e(TAG, "Preview data is null!");
-                mPreviewDataNull = true;
-                mPreviewDone.open();
-                return;
-            }
-            if (data == mBuffer1) {
-                mNumCbWithBuffer1++;
-            } else if (data == mBuffer2) {
-                mNumCbWithBuffer2++;
-            } else if (data == mBuffer3) {
-                mNumCbWithBuffer3++;
-            } else {
-                Log.e(TAG, "Invalid byte array.");
-                mInvalidData = true;
-                mPreviewDone.open();
-                return;
-            }
-
-            if ((mNumCbWithBuffer1 == 1 && mNumCbWithBuffer2 == 1)
-                    || mNumCbWithBuffer3 == 1) {
-                mPreviewDone.open();
-            }
-        }
-    }
-
-    @UiThreadTest
-    public void testImmediateZoom() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testImmediateZoomByCamera(id);
-        }
-    }
-
-    private void testImmediateZoomByCamera(int id) throws Exception {
-        initializeMessageLooper(id);
-
-        Parameters parameters = mCamera.getParameters();
-        if (!parameters.isZoomSupported()) {
-            terminateMessageLooper();
-            return;
-        }
-
-        // Test the zoom parameters.
-        assertEquals(0, parameters.getZoom());  // default zoom should be 0.
-        for (Size size: parameters.getSupportedPreviewSizes()) {
-            parameters = mCamera.getParameters();
-            parameters.setPreviewSize(size.width, size.height);
-            mCamera.setParameters(parameters);
-            parameters = mCamera.getParameters();
-            int maxZoom = parameters.getMaxZoom();
-            assertTrue(maxZoom >= 0);
-
-            // Zoom ratios should be sorted from small to large.
-            List<Integer> ratios = parameters.getZoomRatios();
-            assertEquals(maxZoom + 1, ratios.size());
-            assertEquals(100, ratios.get(0).intValue());
-            for (int i = 0; i < ratios.size() - 1; i++) {
-                assertTrue(ratios.get(i) < ratios.get(i + 1));
-            }
-            blockingStartPreview();
-
-            // Test each zoom step.
-            for (int i = 0; i <= maxZoom; i++) {
-                parameters.setZoom(i);
-                mCamera.setParameters(parameters);
-                assertEquals(i, mCamera.getParameters().getZoom());
-            }
-
-            // It should throw exception if an invalid value is passed.
-            try {
-                parameters.setZoom(maxZoom + 1);
-                mCamera.setParameters(parameters);
-                fail("setZoom should throw exception.");
-            } catch (RuntimeException e) {
-                // expected
-            }
-            assertEquals(maxZoom, mCamera.getParameters().getZoom());
-
-            mCamera.takePicture(mShutterCallback, mRawPictureCallback,
-                                mJpegPictureCallback);
-            waitForSnapshotDone();
-        }
-
-        terminateMessageLooper();
-    }
-
-    @UiThreadTest
-    public void testSmoothZoom() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testSmoothZoomByCamera(id);
-        }
-    }
-
-    private void testSmoothZoomByCamera(int id) throws Exception {
-        initializeMessageLooper(id);
-
-        Parameters parameters = mCamera.getParameters();
-        if (!parameters.isSmoothZoomSupported()) {
-            terminateMessageLooper();
-            return;
-        }
-        assertTrue(parameters.isZoomSupported());
-
-        ZoomListener zoomListener = new ZoomListener();
-        mCamera.setZoomChangeListener(zoomListener);
-        mCamera.startPreview();
-        waitForPreviewDone();
-
-        // Immediate zoom should not generate callbacks.
-        int maxZoom = parameters.getMaxZoom();
-        parameters.setZoom(maxZoom);
-        mCamera.setParameters(parameters);
-        assertEquals(maxZoom, mCamera.getParameters().getZoom());
-        parameters.setZoom(0);
-        mCamera.setParameters(parameters);
-        assertEquals(0, mCamera.getParameters().getZoom());
-        assertFalse(zoomListener.mZoomDone.block(500));
-
-        // Nothing will happen if zoom is not moving.
-        mCamera.stopSmoothZoom();
-
-        // It should not generate callbacks if zoom value is not changed.
-        mCamera.startSmoothZoom(0);
-        assertFalse(zoomListener.mZoomDone.block(500));
-        assertEquals(0, mCamera.getParameters().getZoom());
-
-        // Test startSmoothZoom.
-        mCamera.startSmoothZoom(maxZoom);
-        assertEquals(true, zoomListener.mZoomDone.block(5000));
-        assertEquals(maxZoom, mCamera.getParameters().getZoom());
-        assertEquals(maxZoom, zoomListener.mValues.size());
-        for(int i = 0; i < maxZoom; i++) {
-            int value = zoomListener.mValues.get(i);
-            boolean stopped = zoomListener.mStopped.get(i);
-            // Make sure we get all the zoom values in order.
-            assertEquals(i + 1, value);
-            // All "stopped" except the last should be false.
-            assertEquals(i == maxZoom - 1, stopped);
-        }
-
-        // Test startSmoothZoom. Make sure we get all the callbacks.
-        if (maxZoom > 1) {
-            zoomListener.mValues.clear();
-            zoomListener.mStopped.clear();
-            Log.e(TAG, "zoomListener.mStopped = " + zoomListener.mStopped);
-            zoomListener.mZoomDone.close();
-            mCamera.startSmoothZoom(maxZoom / 2);
-            assertTrue(zoomListener.mZoomDone.block(5000));
-            assertEquals(maxZoom / 2, mCamera.getParameters().getZoom());
-            assertEquals(maxZoom - (maxZoom / 2), zoomListener.mValues.size());
-            for(int i = 0; i < zoomListener.mValues.size(); i++) {
-                int value = zoomListener.mValues.get(i);
-                boolean stopped = zoomListener.mStopped.get(i);
-                // Make sure we get all the zoom values in order.
-                assertEquals(maxZoom - 1 - i, value);
-                // All "stopped" except the last should be false.
-                assertEquals(i == zoomListener.mValues.size() - 1, stopped);
-            }
-        }
-
-        // It should throw exception if an invalid value is passed.
-        try {
-            mCamera.startSmoothZoom(maxZoom + 1);
-            fail("startSmoothZoom should throw exception.");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        // Test stopSmoothZoom.
-        zoomListener.mValues.clear();
-        zoomListener.mStopped.clear();
-        zoomListener.mZoomDone.close();
-        parameters.setZoom(0);
-        mCamera.setParameters(parameters);
-        assertEquals(0, mCamera.getParameters().getZoom());
-        mCamera.startSmoothZoom(maxZoom);
-        mCamera.stopSmoothZoom();
-        assertTrue(zoomListener.mZoomDone.block(5000));
-        assertEquals(zoomListener.mValues.size(), mCamera.getParameters().getZoom());
-        for(int i = 0; i < zoomListener.mValues.size() - 1; i++) {
-            int value = zoomListener.mValues.get(i);
-            boolean stopped = zoomListener.mStopped.get(i);
-            // Make sure we get all the callbacks in order (except the last).
-            assertEquals(i + 1, value);
-            // All "stopped" except the last should be false. stopSmoothZoom has been called. So the
-            // last "stopped" can be true or false.
-            if (i != zoomListener.mValues.size() - 1) {
-                assertFalse(stopped);
-            }
-        }
-
-        terminateMessageLooper();
-    }
-
-    private final class ZoomListener
-            implements android.hardware.Camera.OnZoomChangeListener {
-        public ArrayList<Integer> mValues = new ArrayList<Integer>();
-        public ArrayList<Boolean> mStopped = new ArrayList<Boolean>();
-        public final ConditionVariable mZoomDone = new ConditionVariable();
-
-        public void onZoomChange(int value, boolean stopped, Camera camera) {
-            mValues.add(value);
-            mStopped.add(stopped);
-            if (stopped) {
-                mZoomDone.open();
-            }
-        }
-    }
-
-    @UiThreadTest
-    public void testFocusDistances() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testFocusDistancesByCamera(id);
-        }
-    }
-
-    private void testFocusDistancesByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        blockingStartPreview();
-
-        Parameters parameters = mCamera.getParameters();
-
-        // Test every supported focus mode.
-        for (String focusMode: parameters.getSupportedFocusModes()) {
-            parameters.setFocusMode(focusMode);
-            mCamera.setParameters(parameters);
-            parameters = mCamera.getParameters();
-            assertEquals(focusMode, parameters.getFocusMode());
-            checkFocusDistances(parameters);
-            if (Parameters.FOCUS_MODE_AUTO.equals(focusMode)
-                    || Parameters.FOCUS_MODE_MACRO.equals(focusMode)
-                    || Parameters.FOCUS_MODE_CONTINUOUS_VIDEO.equals(focusMode)
-                    || Parameters.FOCUS_MODE_CONTINUOUS_PICTURE.equals(focusMode)) {
-                Log.v(TAG, "Focus mode=" + focusMode);
-                mCamera.autoFocus(mAutoFocusCallback);
-                assertTrue(waitForFocusDone());
-                parameters = mCamera.getParameters();
-                checkFocusDistances(parameters);
-                float[] initialFocusDistances = new float[3];
-                parameters.getFocusDistances(initialFocusDistances);
-
-                // Focus position should not change after autoFocus call.
-                // Continuous autofocus should have stopped. Sleep some time and
-                // check. Make sure continuous autofocus is not working. If the
-                // focus mode is auto or macro, it is no harm to do the extra
-                // test.
-                Thread.sleep(500);
-                parameters = mCamera.getParameters();
-                float[] currentFocusDistances = new float[3];
-                parameters.getFocusDistances(currentFocusDistances);
-                assertEquals(initialFocusDistances, currentFocusDistances);
-
-                // Focus position should not change after stopping preview.
-                mCamera.stopPreview();
-                parameters = mCamera.getParameters();
-                parameters.getFocusDistances(currentFocusDistances);
-                assertEquals(initialFocusDistances, currentFocusDistances);
-
-                // Focus position should not change after taking a picture.
-                mCamera.startPreview();
-                mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-                waitForSnapshotDone();
-                parameters = mCamera.getParameters();
-                parameters.getFocusDistances(currentFocusDistances);
-                assertEquals(initialFocusDistances, currentFocusDistances);
-                mCamera.startPreview();
-            }
-        }
-
-        // Test if the method throws exception if the argument is invalid.
-        try {
-            parameters.getFocusDistances(null);
-            fail("getFocusDistances should not accept null.");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            parameters.getFocusDistances(new float[2]);
-            fail("getFocusDistances should not accept a float array with two elements.");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-
-        try {
-            parameters.getFocusDistances(new float[4]);
-            fail("getFocusDistances should not accept a float array with four elements.");
-        } catch (IllegalArgumentException e) {
-            // expected
-        }
-        terminateMessageLooper();
-    }
-
-    private void checkFocusDistances(Parameters parameters) {
-        float[] distances = new float[3];
-        parameters.getFocusDistances(distances);
-
-        // Focus distances should be greater than 0.
-        assertTrue(distances[Parameters.FOCUS_DISTANCE_NEAR_INDEX] > 0);
-        assertTrue(distances[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX] > 0);
-        assertTrue(distances[Parameters.FOCUS_DISTANCE_FAR_INDEX] > 0);
-
-        // Make sure far focus distance >= optimal focus distance >= near focus distance.
-        assertTrue(distances[Parameters.FOCUS_DISTANCE_FAR_INDEX] >=
-                   distances[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX]);
-        assertTrue(distances[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX] >=
-                   distances[Parameters.FOCUS_DISTANCE_NEAR_INDEX]);
-
-        // Far focus distance should be infinity in infinity focus mode.
-        if (Parameters.FOCUS_MODE_INFINITY.equals(parameters.getFocusMode())) {
-            assertEquals(Float.POSITIVE_INFINITY,
-                         distances[Parameters.FOCUS_DISTANCE_FAR_INDEX]);
-        }
-    }
-
-    @UiThreadTest
-    public void testCancelAutofocus() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testCancelAutofocusByCamera(id);
-        }
-    }
-
-    private void testCancelAutofocusByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        Parameters parameters = mCamera.getParameters();
-        List<String> focusModes = parameters.getSupportedFocusModes();
-
-        if (focusModes.contains(Parameters.FOCUS_MODE_AUTO)) {
-            parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
-        } else if (focusModes.contains(Parameters.FOCUS_MODE_MACRO)) {
-            parameters.setFocusMode(Parameters.FOCUS_MODE_MACRO);
-        } else {
-            terminateMessageLooper();
-            return;
-        }
-
-        mCamera.setParameters(parameters);
-
-        // Valid to call outside of preview; should just reset lens or
-        // be a no-op.
-        mCamera.cancelAutoFocus();
-
-        mCamera.startPreview();
-
-        // No op if autofocus is not in progress.
-        mCamera.cancelAutoFocus();
-
-        // Try to cancel autofocus immediately.
-        mCamera.autoFocus(mAutoFocusCallback);
-        mCamera.cancelAutoFocus();
-        checkFocusDistanceNotChanging();
-
-        // Try to cancel autofocus after it starts for some time.
-        mCamera.autoFocus(mAutoFocusCallback);
-        Thread.sleep(500);
-        mCamera.cancelAutoFocus();
-        checkFocusDistanceNotChanging();
-
-        // Try to cancel autofocus after it completes. It should be no op.
-        mCamera.autoFocus(mAutoFocusCallback);
-        assertTrue(waitForFocusDone());
-        mCamera.cancelAutoFocus();
-
-        // Test the case calling cancelAutoFocus and release in a row.
-        mCamera.autoFocus(mAutoFocusCallback);
-        mCamera.cancelAutoFocus();
-        mCamera.release();
-
-        // Ensure the camera can be opened if release is called right after AF.
-        mCamera = Camera.open(cameraId);
-        mCamera.setPreviewDisplay(getActivity().getSurfaceView().getHolder());
-        mCamera.startPreview();
-        mCamera.autoFocus(mAutoFocusCallback);
-        mCamera.release();
-
-        terminateMessageLooper();
-    }
-
-    private void checkFocusDistanceNotChanging() throws Exception {
-        float[] distances1 = new float[3];
-        float[] distances2 = new float[3];
-        Parameters parameters = mCamera.getParameters();
-        parameters.getFocusDistances(distances1);
-        Thread.sleep(100);
-        parameters = mCamera.getParameters();
-        parameters.getFocusDistances(distances2);
-        assertEquals(distances1[Parameters.FOCUS_DISTANCE_NEAR_INDEX],
-                     distances2[Parameters.FOCUS_DISTANCE_NEAR_INDEX]);
-        assertEquals(distances1[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX],
-                     distances2[Parameters.FOCUS_DISTANCE_OPTIMAL_INDEX]);
-        assertEquals(distances1[Parameters.FOCUS_DISTANCE_FAR_INDEX],
-                     distances2[Parameters.FOCUS_DISTANCE_FAR_INDEX]);
-    }
-
-    @UiThreadTest
-    public void testMultipleCameras() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        Log.v(TAG, "total " + nCameras + " cameras");
-        assertTrue(nCameras >= 0);
-
-        boolean backCameraExist = false;
-        CameraInfo info = new CameraInfo();
-        for (int i = 0; i < nCameras; i++) {
-            Camera.getCameraInfo(i, info);
-            if (info.facing == CameraInfo.CAMERA_FACING_BACK) {
-                backCameraExist = true;
-                break;
-            }
-        }
-        // Make sure original open still works. It must return a back-facing
-        // camera.
-        mCamera = Camera.open();
-        if (mCamera != null) {
-            mCamera.release();
-            assertTrue(backCameraExist);
-        } else {
-            assertFalse(backCameraExist);
-        }
-
-        for (int id = -1; id <= nCameras; id++) {
-            Log.v(TAG, "testing camera #" + id);
-
-            boolean isBadId = (id < 0 || id >= nCameras);
-
-            try {
-                Camera.getCameraInfo(id, info);
-                if (isBadId) {
-                    fail("getCameraInfo should not accept bad cameraId (" + id + ")");
-                }
-            } catch (RuntimeException e) {
-                if (!isBadId) throw e;
-            }
-
-            int facing = info.facing;
-            int orientation = info.orientation;
-            assertTrue(facing == CameraInfo.CAMERA_FACING_BACK ||
-                       facing == CameraInfo.CAMERA_FACING_FRONT);
-            assertTrue(orientation == 0 || orientation == 90 ||
-                       orientation == 180 || orientation == 270);
-
-            Camera camera = null;
-            try {
-                camera = Camera.open(id);
-                if (isBadId) {
-                    fail("open() should not accept bad cameraId (" + id + ")");
-                }
-            } catch (RuntimeException e) {
-                if (!isBadId) throw e;
-            } finally {
-                if (camera != null) {
-                    camera.release();
-                }
-            }
-        }
-    }
-
-    @UiThreadTest
-    @TimeoutReq(minutes = 30)
-    public void testPreviewPictureSizesCombination() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testPreviewPictureSizesCombinationByCamera(id);
-        }
-    }
-
-    private void testPreviewPictureSizesCombinationByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        Parameters parameters = mCamera.getParameters();
-        PreviewCbForPreviewPictureSizesCombination callback =
-            new PreviewCbForPreviewPictureSizesCombination();
-
-        // Test all combination of preview sizes and picture sizes.
-        for (Size previewSize: parameters.getSupportedPreviewSizes()) {
-            for (Size pictureSize: parameters.getSupportedPictureSizes()) {
-                Log.v(TAG, "Test previewSize=(" + previewSize.width + "," +
-                        previewSize.height + ") pictureSize=(" +
-                        pictureSize.width + "," + pictureSize.height + ")");
-                mPreviewCallbackResult = PREVIEW_CALLBACK_NOT_RECEIVED;
-                mCamera.setPreviewCallback(callback);
-                callback.expectedPreviewSize = previewSize;
-                parameters.setPreviewSize(previewSize.width, previewSize.height);
-                parameters.setPictureSize(pictureSize.width, pictureSize.height);
-                mCamera.setParameters(parameters);
-                assertEquals(previewSize, mCamera.getParameters().getPreviewSize());
-                assertEquals(pictureSize, mCamera.getParameters().getPictureSize());
-
-                // Check if the preview size is the same as requested.
-                mCamera.startPreview();
-                waitForPreviewDone();
-                assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
-
-                // Check if the picture size is the same as requested.
-                mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-                waitForSnapshotDone();
-                assertTrue(mJpegPictureCallbackResult);
-                assertNotNull(mJpegData);
-                BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
-                bmpOptions.inJustDecodeBounds = true;
-                BitmapFactory.decodeByteArray(mJpegData, 0, mJpegData.length, bmpOptions);
-                assertEquals(pictureSize.width, bmpOptions.outWidth);
-                assertEquals(pictureSize.height, bmpOptions.outHeight);
-            }
-        }
-        terminateMessageLooper();
-    }
-
-    private final class PreviewCbForPreviewPictureSizesCombination
-            implements android.hardware.Camera.PreviewCallback {
-        public Size expectedPreviewSize;
-        public void onPreviewFrame(byte[] data, Camera camera) {
-            if (data == null) {
-                mPreviewCallbackResult = PREVIEW_CALLBACK_DATA_NULL;
-                mPreviewDone.open();
-                return;
-            }
-            Size size = camera.getParameters().getPreviewSize();
-            int format = camera.getParameters().getPreviewFormat();
-            int bitsPerPixel = ImageFormat.getBitsPerPixel(format);
-            if (!expectedPreviewSize.equals(size) ||
-                    calculateBufferSize(size.width, size.height,
-                        format, bitsPerPixel) != data.length) {
-                Log.e(TAG, "Expected preview width=" + expectedPreviewSize.width + ", height="
-                        + expectedPreviewSize.height + ". Actual width=" + size.width + ", height="
-                        + size.height);
-                Log.e(TAG, "Frame data length=" + data.length + ". bitsPerPixel=" + bitsPerPixel);
-                mPreviewCallbackResult = PREVIEW_CALLBACK_INVALID_FRAME_SIZE;
-                mPreviewDone.open();
-                return;
-            }
-            camera.setPreviewCallback(null);
-            mPreviewCallbackResult = PREVIEW_CALLBACK_RECEIVED;
-            mPreviewDone.open();
-        }
-    }
-
-    @UiThreadTest
-    public void testPreviewFpsRange() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testPreviewFpsRangeByCamera(id);
-        }
-    }
-
-    private void testPreviewFpsRangeByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-
-        // Test if the parameters exists and minimum fps <= maximum fps.
-        final int INTERVAL_ERROR_THRESHOLD = 10;
-        int[] defaultFps = new int[2];
-        Parameters parameters = mCamera.getParameters();
-        parameters.getPreviewFpsRange(defaultFps);
-        List<int[]> fpsList = parameters.getSupportedPreviewFpsRange();
-        assertTrue(fpsList.size() > 0);
-        boolean found = false;
-        for(int[] fps: fpsList) {
-            assertTrue(fps[Parameters.PREVIEW_FPS_MIN_INDEX] > 0);
-            assertTrue(fps[Parameters.PREVIEW_FPS_MIN_INDEX] <=
-                       fps[Parameters.PREVIEW_FPS_MAX_INDEX]);
-            if (!found && Arrays.equals(defaultFps, fps)) {
-                found = true;
-            }
-        }
-        assertTrue("Preview fps range must be in the supported list.", found);
-
-        // Test if the list is properly sorted.
-        for (int i = 0; i < fpsList.size() - 1; i++) {
-            int minFps1 = fpsList.get(i)[Parameters.PREVIEW_FPS_MIN_INDEX];
-            int maxFps1 = fpsList.get(i)[Parameters.PREVIEW_FPS_MAX_INDEX];
-            int minFps2 = fpsList.get(i + 1)[Parameters.PREVIEW_FPS_MIN_INDEX];
-            int maxFps2 = fpsList.get(i + 1)[Parameters.PREVIEW_FPS_MAX_INDEX];
-            assertTrue(maxFps1 < maxFps2
-                    || (maxFps1 == maxFps2 && minFps1 < minFps2));
-        }
-
-        // Test if the actual fps is within fps range.
-        Size size = parameters.getPreviewSize();
-        int format = mCamera.getParameters().getPreviewFormat();
-        int bitsPerPixel = ImageFormat.getBitsPerPixel(format);
-        byte[] buffer1 = new byte[size.width * size.height * bitsPerPixel / 8];
-        byte[] buffer2 = new byte[size.width * size.height * bitsPerPixel / 8];
-        byte[] buffer3 = new byte[size.width * size.height * bitsPerPixel / 8];
-        FpsRangePreviewCb callback = new FpsRangePreviewCb();
-        int[] readBackFps = new int[2];
-        for (int[] fps: fpsList) {
-            parameters = mCamera.getParameters();
-            parameters.setPreviewFpsRange(fps[Parameters.PREVIEW_FPS_MIN_INDEX],
-                                          fps[Parameters.PREVIEW_FPS_MAX_INDEX]);
-            callback.reset(fps[Parameters.PREVIEW_FPS_MIN_INDEX] / 1000.0,
-                           fps[Parameters.PREVIEW_FPS_MAX_INDEX] / 1000.0);
-            mCamera.setParameters(parameters);
-            parameters = mCamera.getParameters();
-            parameters.getPreviewFpsRange(readBackFps);
-            MoreAsserts.assertEquals(fps, readBackFps);
-            mCamera.addCallbackBuffer(buffer1);
-            mCamera.addCallbackBuffer(buffer2);
-            mCamera.addCallbackBuffer(buffer3);
-            mCamera.setPreviewCallbackWithBuffer(callback);
-            mCamera.startPreview();
-            try {
-                // Test the frame rate for a while.
-                Thread.sleep(3000);
-            } catch(Exception e) {
-                // ignore
-            }
-            mCamera.stopPreview();
-            // See if any frame duration violations occurred during preview run
-            AssertionFailedError e = callback.getDurationException();
-            if (e != null) throw(e);
-            int numIntervalError = callback.getNumIntervalError();
-            if (numIntervalError > INTERVAL_ERROR_THRESHOLD) {
-                fail(String.format(
-                        "Too many preview callback frame intervals out of bounds: " +
-                                "Count is %d, limit is %d",
-                        numIntervalError, INTERVAL_ERROR_THRESHOLD));
-            }
-        }
-
-        // Test the invalid fps cases.
-        parameters = mCamera.getParameters();
-        parameters.setPreviewFpsRange(-1, -1);
-        try {
-            mCamera.setParameters(parameters);
-            fail("Should throw an exception if fps range is negative.");
-        } catch (RuntimeException e) {
-            // expected
-        }
-        parameters.setPreviewFpsRange(10, 5);
-        try {
-            mCamera.setParameters(parameters);
-            fail("Should throw an exception if fps range is invalid.");
-        } catch (RuntimeException e) {
-            // expected
-        }
-
-        terminateMessageLooper();
-    }
-
-    private final class FpsRangePreviewCb
-            implements android.hardware.Camera.PreviewCallback {
-        private double mMinFps, mMaxFps, mMaxFrameInterval, mMinFrameInterval;
-        // An array storing the arrival time of the frames in the last second.
-        private ArrayList<Long> mFrames = new ArrayList<Long>();
-        private long firstFrameArrivalTime;
-        private AssertionFailedError mDurationException = null;
-        private int numIntervalError;
-
-        public void reset(double minFps, double maxFps) {
-            this.mMinFps = minFps;
-            this.mMaxFps = maxFps;
-            mMaxFrameInterval = 1000.0 / mMinFps;
-            mMinFrameInterval = 1000.0 / mMaxFps;
-            Log.v(TAG, "Min fps=" + mMinFps + ". Max fps=" + mMaxFps
-                    + ". Min frame interval=" + mMinFrameInterval
-                    + ". Max frame interval=" + mMaxFrameInterval);
-            mFrames.clear();
-            firstFrameArrivalTime = 0;
-            mDurationException = null;
-            numIntervalError = 0;
-        }
-
-        // This method tests if the actual fps is between minimum and maximum.
-        // It also tests if the frame interval is too long.
-        public void onPreviewFrame(byte[] data, android.hardware.Camera camera) {
-            long arrivalTime = SystemClock.elapsedRealtime();
-            camera.addCallbackBuffer(data);
-            if (firstFrameArrivalTime == 0) firstFrameArrivalTime = arrivalTime;
-
-            // Remove the frames that arrived before the last second.
-            Iterator<Long> it = mFrames.iterator();
-            while(it.hasNext()) {
-                long time = it.next();
-                if (arrivalTime - time > 1000 && mFrames.size() > 2) {
-                    it.remove();
-                } else {
-                    break;
-                }
-            }
-
-            // Start the test after one second.
-            if (arrivalTime - firstFrameArrivalTime > 1000) {
-                assertTrue(mFrames.size() >= 2);
-
-                // Check the frame interval and fps. The interval check
-                // considers the time variance passing frames from the camera
-                // hardware to the callback. It should be a constant time, not a
-                // ratio. The fps check is more strict because individual
-                // variance is averaged out.
-
-                // Check if the frame interval is too large or too small.
-                // x100 = percent, intervalMargin should be bigger than
-                // fpsMargin considering that fps will be in the order of 10.
-                double intervalMargin = 0.9;
-                long lastArrivalTime = mFrames.get(mFrames.size() - 1);
-                double interval = arrivalTime - lastArrivalTime;
-                if (VERBOSE) Log.v(TAG, "Frame interval=" + interval);
-
-                try {
-                    if (interval > mMaxFrameInterval * (1.0 + intervalMargin) ||
-                            interval < mMinFrameInterval * (1.0 - intervalMargin)) {
-                        Log.i(TAG, "Bad frame interval=" + interval + "ms. Out out range " +
-                                mMinFrameInterval * (1.0 - intervalMargin) + "/" +
-                                mMaxFrameInterval * (1.0 + intervalMargin));
-                        numIntervalError++;
-                    }
-                    // Check if the fps is within range.
-                    double fpsMargin = 0.5; // x100 = percent
-                    double avgInterval = (double)(arrivalTime - mFrames.get(0))
-                            / mFrames.size();
-                    double fps = 1000.0 / avgInterval;
-                    assertTrue("Actual fps (" + fps + ") should be larger " +
-                            "than min fps (" + mMinFps + ")",
-                            fps >= mMinFps * (1.0 - fpsMargin));
-                    assertTrue("Actual fps (" + fps + ") should be smaller" +
-                            "than max fps (" + mMaxFps + ")",
-                            fps <= mMaxFps * (1.0 + fpsMargin));
-                } catch (AssertionFailedError e) {
-                    // Need to throw this only in the test body, instead of in
-                    // the callback
-                    if (mDurationException == null) {
-                        mDurationException = e;
-                    }
-                }
-            }
-            // Add the arrival time of this frame to the list.
-            mFrames.add(arrivalTime);
-        }
-
-        public AssertionFailedError getDurationException() {
-            return mDurationException;
-        }
-        public int getNumIntervalError() {
-            return numIntervalError;
-        }
-    }
-
-    private void assertEquals(Size expected, Size actual) {
-        assertEquals(expected.width, actual.width);
-        assertEquals(expected.height, actual.height);
-    }
-
-    private void assertEquals(float[] expected, float[] actual) {
-        assertEquals(expected.length, actual.length);
-        for (int i = 0; i < expected.length; i++) {
-            assertEquals(expected[i], actual[i], 0.000001f);
-        }
-    }
-
-    private void assertNoLetters(String value, String key) {
-        for (int i = 0; i < value.length(); i++) {
-            char c = value.charAt(i);
-            assertFalse("Parameter contains invalid characters. key,value=("
-                    + key + "," + value + ")",
-                    Character.isLetter(c) && c != 'x');
-        }
-    }
-
-    @UiThreadTest
-    public void testSceneMode() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testSceneModeByCamera(id);
-        }
-    }
-
-    private class SceneModeSettings {
-        public String mScene, mFlash, mFocus, mWhiteBalance;
-        public List<String> mSupportedFlash, mSupportedFocus, mSupportedWhiteBalance;
-
-        public SceneModeSettings(Parameters parameters) {
-            mScene = parameters.getSceneMode();
-            mFlash = parameters.getFlashMode();
-            mFocus = parameters.getFocusMode();
-            mWhiteBalance = parameters.getWhiteBalance();
-            mSupportedFlash = parameters.getSupportedFlashModes();
-            mSupportedFocus = parameters.getSupportedFocusModes();
-            mSupportedWhiteBalance = parameters.getSupportedWhiteBalance();
-        }
-    }
-
-    private void testSceneModeByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        Parameters parameters = mCamera.getParameters();
-        List<String> supportedSceneModes = parameters.getSupportedSceneModes();
-        if (supportedSceneModes != null) {
-            assertEquals(Parameters.SCENE_MODE_AUTO, parameters.getSceneMode());
-            SceneModeSettings autoSceneMode = new SceneModeSettings(parameters);
-
-            // Store all scene mode affected settings.
-            SceneModeSettings[] settings = new SceneModeSettings[supportedSceneModes.size()];
-            for (int i = 0; i < supportedSceneModes.size(); i++) {
-                parameters.setSceneMode(supportedSceneModes.get(i));
-                mCamera.setParameters(parameters);
-                parameters = mCamera.getParameters();
-                settings[i] = new SceneModeSettings(parameters);
-            }
-
-            // Make sure scene mode settings are consistent before preview and
-            // after preview.
-            blockingStartPreview();
-            for (int i = 0; i < supportedSceneModes.size(); i++) {
-                String sceneMode = supportedSceneModes.get(i);
-                parameters.setSceneMode(sceneMode);
-                mCamera.setParameters(parameters);
-                parameters = mCamera.getParameters();
-
-                // In auto scene mode, camera HAL will not remember the previous
-                // flash, focus, and white-balance. It will just take values set
-                // by parameters. But the supported flash, focus, and
-                // white-balance should still be restored in auto scene mode.
-                if (!Parameters.SCENE_MODE_AUTO.equals(sceneMode)) {
-                    assertEquals("Flash is inconsistent in scene mode " + sceneMode,
-                            settings[i].mFlash, parameters.getFlashMode());
-                    assertEquals("Focus is inconsistent in scene mode " + sceneMode,
-                            settings[i].mFocus, parameters.getFocusMode());
-                    assertEquals("White balance is inconsistent in scene mode " + sceneMode,
-                            settings[i].mWhiteBalance, parameters.getWhiteBalance());
-                }
-                assertEquals("Suppported flash modes are inconsistent in scene mode " + sceneMode,
-                        settings[i].mSupportedFlash, parameters.getSupportedFlashModes());
-                assertEquals("Suppported focus modes are inconsistent in scene mode " + sceneMode,
-                        settings[i].mSupportedFocus, parameters.getSupportedFocusModes());
-                assertEquals("Suppported white balance are inconsistent in scene mode " + sceneMode,
-                        settings[i].mSupportedWhiteBalance, parameters.getSupportedWhiteBalance());
-            }
-
-            for (int i = 0; i < settings.length; i++) {
-                if (Parameters.SCENE_MODE_AUTO.equals(settings[i].mScene)) continue;
-
-                // Both the setting and the supported settings may change. It is
-                // allowed to have more than one supported settings in scene
-                // modes. For example, in night scene mode, supported flash
-                // modes can have on and off.
-                if (autoSceneMode.mSupportedFlash != null) {
-                    assertTrue(settings[i].mSupportedFlash.contains(settings[i].mFlash));
-                    for (String mode: settings[i].mSupportedFlash) {
-                        assertTrue(autoSceneMode.mSupportedFlash.contains(mode));
-                    }
-                }
-                if (autoSceneMode.mSupportedFocus != null) {
-                    assertTrue(settings[i].mSupportedFocus.contains(settings[i].mFocus));
-                    for (String mode: settings[i].mSupportedFocus) {
-                        assertTrue(autoSceneMode.mSupportedFocus.contains(mode));
-                    }
-                }
-                if (autoSceneMode.mSupportedWhiteBalance != null) {
-                    assertTrue(settings[i].mSupportedWhiteBalance.contains(settings[i].mWhiteBalance));
-                    for (String mode: settings[i].mSupportedWhiteBalance) {
-                        assertTrue(autoSceneMode.mSupportedWhiteBalance.contains(mode));
-                    }
-                }
-            }
-        }
-        terminateMessageLooper();
-    }
-
-    @UiThreadTest
-    public void testInvalidParameters() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testInvalidParametersByCamera(id);
-        }
-    }
-
-    private void testInvalidParametersByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        // Test flash mode.
-        Parameters parameters = mCamera.getParameters();
-        List<String> list = parameters.getSupportedFlashModes();
-        if (list != null && list.size() > 0) {
-            String original = parameters.getFlashMode();
-            parameters.setFlashMode("invalid");
-            try {
-                mCamera.setParameters(parameters);
-                fail("Should throw exception for invalid parameters");
-            } catch (RuntimeException e) {
-                // expected
-            }
-            parameters = mCamera.getParameters();
-            assertEquals(original, parameters.getFlashMode());
-        }
-
-        // Test focus mode.
-        String originalFocus = parameters.getFocusMode();
-        parameters.setFocusMode("invalid");
-        try {
-            mCamera.setParameters(parameters);
-            fail("Should throw exception for invalid parameters");
-        } catch (RuntimeException e) {
-            // expected
-        }
-        parameters = mCamera.getParameters();
-        assertEquals(originalFocus, parameters.getFocusMode());
-
-        // Test preview size.
-        Size originalSize = parameters.getPreviewSize();
-        parameters.setPreviewSize(-1, -1);
-        try {
-            mCamera.setParameters(parameters);
-            fail("Should throw exception for invalid parameters");
-        } catch (RuntimeException e) {
-            // expected
-        }
-        parameters = mCamera.getParameters();
-        assertEquals(originalSize, parameters.getPreviewSize());
-
-        terminateMessageLooper();
-    }
-
-    @UiThreadTest
-    public void testGetParameterDuringFocus() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testGetParameterDuringFocusByCamera(id);
-        }
-    }
-
-    private void testGetParameterDuringFocusByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        mCamera.startPreview();
-        Parameters parameters = mCamera.getParameters();
-        for (String focusMode: parameters.getSupportedFocusModes()) {
-            if (focusMode.equals(parameters.FOCUS_MODE_AUTO)
-                    || focusMode.equals(parameters.FOCUS_MODE_MACRO)) {
-                parameters.setFocusMode(focusMode);
-                mCamera.setParameters(parameters);
-                mCamera.autoFocus(mAutoFocusCallback);
-                // This should not crash or throw exception.
-                mCamera.getParameters();
-                waitForFocusDone();
-
-
-                mCamera.autoFocus(mAutoFocusCallback);
-                // Add a small delay to make sure focus has started.
-                Thread.sleep(100);
-                // This should not crash or throw exception.
-                mCamera.getParameters();
-                waitForFocusDone();
-            }
-        }
-        terminateMessageLooper();
-    }
-
-    @UiThreadTest
-    public void testPreviewFormats() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testPreviewFormatsByCamera(id);
-        }
-    }
-
-    private void testPreviewFormatsByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        Parameters parameters = mCamera.getParameters();
-        for (int format: parameters.getSupportedPreviewFormats()) {
-            Log.v(TAG, "Test preview format " + format);
-            parameters.setPreviewFormat(format);
-            mCamera.setParameters(parameters);
-            mCamera.setOneShotPreviewCallback(mPreviewCallback);
-            mCamera.startPreview();
-            waitForPreviewDone();
-            assertEquals(PREVIEW_CALLBACK_RECEIVED, mPreviewCallbackResult);
-        }
-        terminateMessageLooper();
-    }
-
-    @UiThreadTest
-    public void testMultiCameraRelease() throws Exception {
-        // Verify that multiple cameras exist, and that they can be opened at the same time
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Checking pre-conditions.");
-        int nCameras = Camera.getNumberOfCameras();
-        if (nCameras < 2) {
-            Log.i(TAG, "Test multi-camera release: Skipping test because only 1 camera available");
-            return;
-        }
-
-        Camera testCamera0 = Camera.open(0);
-        Camera testCamera1 = null;
-        try {
-            testCamera1 = Camera.open(1);
-        } catch (RuntimeException e) {
-            // Can't open two cameras at once
-            Log.i(TAG, "testMultiCameraRelease: Skipping test because only 1 camera "+
-                  "could be opened at once. Second open threw: " + e);
-            testCamera0.release();
-            return;
-        }
-        testCamera0.release();
-        testCamera1.release();
-
-        // Start first camera
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Opening camera 0");
-        initializeMessageLooper(0);
-        SimplePreviewStreamCb callback0 = new SimplePreviewStreamCb(0);
-        mCamera.setPreviewCallback(callback0);
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Starting preview on camera 0");
-        mCamera.startPreview();
-        // Run preview for a bit
-        for (int f = 0; f < 100; f++) {
-            mPreviewDone.close();
-            assertTrue("testMultiCameraRelease: First camera preview timed out on frame " + f + "!",
-                       mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE));
-        }
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Stopping preview on camera 0");
-        mCamera.stopPreview();
-        // Save message looper and camera to deterministically release them, instead
-        // of letting GC do it at some point.
-        Camera firstCamera = mCamera;
-        Looper firstLooper = mLooper;
-        //terminateMessageLooper(); // Intentionally not calling this
-        // Preview surface should be released though!
-        mCamera.setPreviewDisplay(null);
-
-        // Start second camera without releasing the first one (will
-        // set mCamera and mLooper to new objects)
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Opening camera 1");
-        initializeMessageLooper(1);
-        SimplePreviewStreamCb callback1 = new SimplePreviewStreamCb(1);
-        mCamera.setPreviewCallback(callback1);
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Starting preview on camera 1");
-        mCamera.startPreview();
-        // Run preview for a bit - GC of first camera instance should not impact the second's
-        // operation.
-        for (int f = 0; f < 100; f++) {
-            mPreviewDone.close();
-            assertTrue("testMultiCameraRelease: Second camera preview timed out on frame " + f + "!",
-                       mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE));
-            if (f == 50) {
-                // Release first camera mid-preview, should cause no problems
-                if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Releasing camera 0");
-                firstCamera.release();
-            }
-        }
-        if (VERBOSE) Log.v(TAG, "testMultiCameraRelease: Stopping preview on camera 0");
-        mCamera.stopPreview();
-
-        firstLooper.quit();
-        terminateMessageLooper();
-    }
-
-    // This callback just signals on the condition variable, making it useful for checking that
-    // preview callbacks don't stop unexpectedly
-    private final class SimplePreviewStreamCb
-            implements android.hardware.Camera.PreviewCallback {
-        private int mId;
-        public SimplePreviewStreamCb(int id) {
-            mId = id;
-        }
-        public void onPreviewFrame(byte[] data, android.hardware.Camera camera) {
-            if (VERBOSE) Log.v(TAG, "Preview frame callback, id " + mId + ".");
-            mPreviewDone.open();
-        }
-    }
-
-    @UiThreadTest
-    public void testFocusAreas() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-
-            initializeMessageLooper(id);
-            Parameters parameters = mCamera.getParameters();
-            int maxNumFocusAreas = parameters.getMaxNumFocusAreas();
-            assertTrue(maxNumFocusAreas >= 0);
-            if (maxNumFocusAreas > 0) {
-                List<String> focusModes = parameters.getSupportedFocusModes();
-                assertTrue(focusModes.contains(Parameters.FOCUS_MODE_AUTO));
-                testAreas(FOCUS_AREA, maxNumFocusAreas);
-            }
-            terminateMessageLooper();
-        }
-    }
-
-    @UiThreadTest
-    public void testMeteringAreas() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            initializeMessageLooper(id);
-            Parameters parameters = mCamera.getParameters();
-            int maxNumMeteringAreas = parameters.getMaxNumMeteringAreas();
-            assertTrue(maxNumMeteringAreas >= 0);
-            if (maxNumMeteringAreas > 0) {
-                testAreas(METERING_AREA, maxNumMeteringAreas);
-            }
-            terminateMessageLooper();
-        }
-    }
-
-    private void testAreas(int type, int maxNumAreas) throws Exception {
-        mCamera.startPreview();
-
-        // Test various valid cases.
-        testValidAreas(type, null);                                  // the default area
-        testValidAreas(type, makeAreas(-1000, -1000, 1000, 1000, 1)); // biggest area
-        testValidAreas(type, makeAreas(-500, -500, 500, 500, 1000)); // medium area & biggest weight
-        testValidAreas(type, makeAreas(0, 0, 1, 1, 1));              // smallest area
-
-        ArrayList<Area> areas = new ArrayList();
-        if (maxNumAreas > 1) {
-            // Test overlapped areas.
-            testValidAreas(type, makeAreas(-250, -250, 250, 250, 1, 0, 0, 500, 500, 2));
-            // Test completely disjoint areas.
-            testValidAreas(type, makeAreas(-250, -250, 0, 0, 1, 900, 900, 1000, 1000, 1));
-            // Test the maximum number of areas.
-            testValidAreas(type, makeAreas(-1000, -1000, 1000, 1000, 1000, maxNumAreas));
-        }
-
-        // Test various invalid cases.
-        testInvalidAreas(type, makeAreas(-1001, -1000, 1000, 1000, 1));    // left should >= -1000
-        testInvalidAreas(type, makeAreas(-1000, -1001, 1000, 1000, 1));    // top should >= -1000
-        testInvalidAreas(type, makeAreas(-1000, -1000, 1001, 1000, 1));    // right should <= 1000
-        testInvalidAreas(type, makeAreas(-1000, -1000, 1000, 1001, 1));    // bottom should <= 1000
-        testInvalidAreas(type, makeAreas(-1000, -1000, 1000, 1000, 0));    // weight should >= 1
-        testInvalidAreas(type, makeAreas(-1000, -1000, 1000, 1001, 1001)); // weight should <= 1000
-        testInvalidAreas(type, makeAreas(500, -1000, 500, 1000, 1));       // left should < right
-        testInvalidAreas(type, makeAreas(-1000, 500, 1000, 500, 1));       // top should < bottom
-        testInvalidAreas(type, makeAreas(500, -1000, 499, 1000, 1));       // left should < right
-        testInvalidAreas(type, makeAreas(-1000, 500, 100, 499, 1));        // top should < bottom
-        testInvalidAreas(type, makeAreas(-250, -250, 250, 250, -1));       // weight should >= 1
-        // Test when the number of areas exceeds maximum.
-        testInvalidAreas(type, makeAreas(-1000, -1000, 1000, 1000, 1000, maxNumAreas + 1));
-    }
-
-    private static ArrayList<Area> makeAreas(int left, int top, int right, int bottom, int weight) {
-        ArrayList<Area> areas = new ArrayList<Area>();
-        areas.add(new Area(new Rect(left, top, right, bottom), weight));
-        return areas;
-    }
-
-    private static ArrayList<Area> makeAreas(int left, int top, int right, int bottom,
-            int weight, int number) {
-        ArrayList<Area> areas = new ArrayList<Area>();
-        for (int i = 0; i < number; i++) {
-            areas.add(new Area(new Rect(left, top, right, bottom), weight));
-        }
-        return areas;
-    }
-
-    private static ArrayList<Area> makeAreas(int left1, int top1, int right1,
-            int bottom1, int weight1, int left2, int top2, int right2,
-            int bottom2, int weight2) {
-        ArrayList<Area> areas = new ArrayList<Area>();
-        areas.add(new Area(new Rect(left1, top1, right1, bottom1), weight1));
-        areas.add(new Area(new Rect(left2, top2, right2, bottom2), weight2));
-        return areas;
-    }
-
-    private void testValidAreas(int areaType, ArrayList<Area> areas) {
-        if (areaType == FOCUS_AREA) {
-            testValidFocusAreas(areas);
-        } else {
-            testValidMeteringAreas(areas);
-        }
-    }
-
-    private void testInvalidAreas(int areaType, ArrayList<Area> areas) {
-        if (areaType == FOCUS_AREA) {
-            testInvalidFocusAreas(areas);
-        } else {
-            testInvalidMeteringAreas(areas);
-        }
-    }
-
-    private void testValidFocusAreas(ArrayList<Area> areas) {
-        Parameters parameters = mCamera.getParameters();
-        parameters.setFocusAreas(areas);
-        mCamera.setParameters(parameters);
-        parameters = mCamera.getParameters();
-        assertEquals(areas, parameters.getFocusAreas());
-        mCamera.autoFocus(mAutoFocusCallback);
-        waitForFocusDone();
-    }
-
-    private void testInvalidFocusAreas(ArrayList<Area> areas) {
-        Parameters parameters = mCamera.getParameters();
-        List<Area> originalAreas = parameters.getFocusAreas();
-        try {
-            parameters.setFocusAreas(areas);
-            mCamera.setParameters(parameters);
-            fail("Should throw exception when focus area is invalid.");
-        } catch (RuntimeException e) {
-            parameters = mCamera.getParameters();
-            assertEquals(originalAreas, parameters.getFocusAreas());
-        }
-    }
-
-    private void testValidMeteringAreas(ArrayList<Area> areas) {
-        Parameters parameters = mCamera.getParameters();
-        parameters.setMeteringAreas(areas);
-        mCamera.setParameters(parameters);
-        parameters = mCamera.getParameters();
-        assertEquals(areas, parameters.getMeteringAreas());
-    }
-
-    private void testInvalidMeteringAreas(ArrayList<Area> areas) {
-        Parameters parameters = mCamera.getParameters();
-        List<Area> originalAreas = parameters.getMeteringAreas();
-        try {
-            parameters.setMeteringAreas(areas);
-            mCamera.setParameters(parameters);
-            fail("Should throw exception when metering area is invalid.");
-        } catch (RuntimeException e) {
-            parameters = mCamera.getParameters();
-            assertEquals(originalAreas, parameters.getMeteringAreas());
-        }
-    }
-
-    // Apps should be able to call startPreview in jpeg callback.
-    @UiThreadTest
-    public void testJpegCallbackStartPreview() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testJpegCallbackStartPreviewByCamera(id);
-        }
-    }
-
-    private void testJpegCallbackStartPreviewByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        mCamera.startPreview();
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback, new JpegStartPreviewCallback());
-        waitForSnapshotDone();
-        terminateMessageLooper();
-        assertTrue(mJpegPictureCallbackResult);
-    }
-
-    private final class JpegStartPreviewCallback implements PictureCallback {
-        public void onPictureTaken(byte[] rawData, Camera camera) {
-            try {
-                camera.startPreview();
-                mJpegPictureCallbackResult = true;
-            } catch (Exception e) {
-            }
-            mSnapshotDone.open();
-        }
-    }
-
-    @UiThreadTest
-    public void testRecordingHint() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testRecordingHintByCamera(id);
-        }
-    }
-
-    private void testRecordingHintByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        Parameters parameters = mCamera.getParameters();
-
-        SurfaceHolder holder = getActivity().getSurfaceView().getHolder();
-        CamcorderProfile profile = CamcorderProfile.get(cameraId,
-                CamcorderProfile.QUALITY_LOW);
-
-        setPreviewSizeByProfile(parameters, profile);
-
-        // Test recording videos and taking pictures when the hint is off and on.
-        for (int i = 0; i < 2; i++) {
-            parameters.setRecordingHint(i == 0 ? false : true);
-            mCamera.setParameters(parameters);
-            mCamera.startPreview();
-            recordVideoSimple(profile, holder);
-            mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-            waitForSnapshotDone();
-            assertTrue(mJpegPictureCallbackResult);
-        }
-
-        // Can change recording hint when the preview is active.
-        mCamera.startPreview();
-        parameters.setRecordingHint(false);
-        mCamera.setParameters(parameters);
-        parameters.setRecordingHint(true);
-        mCamera.setParameters(parameters);
-        terminateMessageLooper();
-    }
-
-    private void recordVideoSimple(CamcorderProfile profile,
-            SurfaceHolder holder) throws Exception {
-        mCamera.unlock();
-        MediaRecorder recorder = new MediaRecorder();
-        try {
-            recorder.setCamera(mCamera);
-            recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
-            recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-            recorder.setProfile(profile);
-            recorder.setOutputFile("/dev/null");
-            recorder.setPreviewDisplay(holder.getSurface());
-            recorder.prepare();
-            recorder.start();
-            Thread.sleep(2000);
-            recorder.stop();
-        } finally {
-            recorder.release();
-            mCamera.lock();
-        }
-    }
-
-    @UiThreadTest
-    public void testAutoExposureLock() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            initializeMessageLooper(id);
-            Parameters parameters = mCamera.getParameters();
-            boolean aeLockSupported = parameters.isAutoExposureLockSupported();
-            if (aeLockSupported) {
-                subtestLockCommon(AUTOEXPOSURE_LOCK);
-                subtestLockAdditionalAE();
-            }
-            terminateMessageLooper();
-        }
-    }
-
-    @UiThreadTest
-    public void testAutoWhiteBalanceLock() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            initializeMessageLooper(id);
-            Parameters parameters = mCamera.getParameters();
-            boolean awbLockSupported = parameters.isAutoWhiteBalanceLockSupported();
-            if (awbLockSupported) {
-                subtestLockCommon(AUTOWHITEBALANCE_LOCK);
-                subtestLockAdditionalAWB();
-            }
-            terminateMessageLooper();
-        }
-    }
-
-    @UiThreadTest
-    public void test3ALockInteraction() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            initializeMessageLooper(id);
-            Parameters parameters = mCamera.getParameters();
-            boolean locksSupported =
-                    parameters.isAutoWhiteBalanceLockSupported() &&
-                    parameters.isAutoExposureLockSupported();
-            if (locksSupported) {
-                subtestLockInteractions();
-            }
-            terminateMessageLooper();
-        }
-    }
-
-    private void subtestLockCommon(int type) {
-        // Verify lock is not set on open()
-        assert3ALockState("Lock not released after open()", type, false);
-
-        // Verify lock can be set, unset before preview
-        set3ALockState(true, type);
-        assert3ALockState("Lock could not be set before 1st preview!",
-                type, true);
-
-        set3ALockState(false, type);
-        assert3ALockState("Lock could not be unset before 1st preview!",
-                type, false);
-
-        // Verify preview start does not set lock
-        mCamera.startPreview();
-        assert3ALockState("Lock state changed by preview start!", type, false);
-
-        // Verify lock can be set, unset during preview
-        set3ALockState(true, type);
-        assert3ALockState("Lock could not be set during preview!", type, true);
-
-        set3ALockState(false, type);
-        assert3ALockState("Lock could not be unset during preview!",
-                type, false);
-
-        // Verify lock is not cleared by stop preview
-        set3ALockState(true, type);
-        mCamera.stopPreview();
-        assert3ALockState("Lock was cleared by stopPreview!", type, true);
-
-        // Verify that preview start does not clear lock
-        set3ALockState(true, type);
-        mCamera.startPreview();
-        assert3ALockState("Lock state changed by preview start!", type, true);
-
-        // Verify that taking a picture does not clear the lock
-        set3ALockState(true, type);
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback,
-                mJpegPictureCallback);
-        waitForSnapshotDone();
-        assert3ALockState("Lock state was cleared by takePicture!", type, true);
-
-        mCamera.startPreview();
-        Parameters parameters = mCamera.getParameters();
-        for (String focusMode: parameters.getSupportedFocusModes()) {
-            // TODO: Test this for other focus modes as well, once agreement is
-            // reached on which ones it should apply to
-            if (!Parameters.FOCUS_MODE_AUTO.equals(focusMode) ) {
-                continue;
-            }
-
-            parameters.setFocusMode(focusMode);
-            mCamera.setParameters(parameters);
-
-            // Verify that autoFocus does not change the lock
-            set3ALockState(false, type);
-            mCamera.autoFocus(mAutoFocusCallback);
-            assert3ALockState("Lock was set by autoFocus in mode: " + focusMode, type, false);
-            assertTrue(waitForFocusDone());
-            assert3ALockState("Lock was set by autoFocus in mode: " + focusMode, type, false);
-
-            // Verify that cancelAutoFocus does not change the lock
-            mCamera.cancelAutoFocus();
-            assert3ALockState("Lock was set by cancelAutoFocus!", type, false);
-
-            // Verify that autoFocus does not change the lock
-            set3ALockState(true, type);
-            mCamera.autoFocus(mAutoFocusCallback);
-            assert3ALockState("Lock was cleared by autoFocus in mode: " + focusMode, type, true);
-            assertTrue(waitForFocusDone());
-            assert3ALockState("Lock was cleared by autoFocus in mode: " + focusMode, type, true);
-
-            // Verify that cancelAutoFocus does not change the lock
-            mCamera.cancelAutoFocus();
-            assert3ALockState("Lock was cleared by cancelAutoFocus!", type, true);
-        }
-        mCamera.stopPreview();
-    }
-
-    private void subtestLockAdditionalAE() {
-        // Verify that exposure compensation can be used while
-        // AE lock is active
-        mCamera.startPreview();
-        Parameters parameters = mCamera.getParameters();
-        parameters.setAutoExposureLock(true);
-        mCamera.setParameters(parameters);
-        parameters.setExposureCompensation(parameters.getMaxExposureCompensation());
-        mCamera.setParameters(parameters);
-        parameters = mCamera.getParameters();
-        assertTrue("Could not adjust exposure compensation with AE locked!",
-                parameters.getExposureCompensation() ==
-                parameters.getMaxExposureCompensation() );
-
-        parameters.setExposureCompensation(parameters.getMinExposureCompensation());
-        mCamera.setParameters(parameters);
-        parameters = mCamera.getParameters();
-        assertTrue("Could not adjust exposure compensation with AE locked!",
-                parameters.getExposureCompensation() ==
-                parameters.getMinExposureCompensation() );
-        mCamera.stopPreview();
-    }
-
-    private void subtestLockAdditionalAWB() {
-        // Verify that switching AWB modes clears AWB lock
-        mCamera.startPreview();
-        Parameters parameters = mCamera.getParameters();
-        String firstWb = null;
-        for ( String wbMode: parameters.getSupportedWhiteBalance() ) {
-            if (firstWb == null) {
-                firstWb = wbMode;
-            }
-            parameters.setWhiteBalance(firstWb);
-            mCamera.setParameters(parameters);
-            parameters.setAutoWhiteBalanceLock(true);
-            mCamera.setParameters(parameters);
-
-            parameters.setWhiteBalance(wbMode);
-            mCamera.setParameters(parameters);
-
-            if (firstWb == wbMode) {
-                assert3ALockState("AWB lock was cleared when WB mode was unchanged!",
-                        AUTOWHITEBALANCE_LOCK, true);
-            } else {
-                assert3ALockState("Changing WB mode did not clear AWB lock!",
-                        AUTOWHITEBALANCE_LOCK, false);
-            }
-        }
-        mCamera.stopPreview();
-    }
-
-    private void subtestLockInteractions() {
-        // Verify that toggling AE does not change AWB lock state
-        set3ALockState(false, AUTOWHITEBALANCE_LOCK);
-        set3ALockState(false, AUTOEXPOSURE_LOCK);
-
-        set3ALockState(true, AUTOEXPOSURE_LOCK);
-        assert3ALockState("Changing AE lock affected AWB lock!",
-                AUTOWHITEBALANCE_LOCK, false);
-
-        set3ALockState(false, AUTOEXPOSURE_LOCK);
-        assert3ALockState("Changing AE lock affected AWB lock!",
-                AUTOWHITEBALANCE_LOCK, false);
-
-        set3ALockState(true, AUTOWHITEBALANCE_LOCK);
-
-        set3ALockState(true, AUTOEXPOSURE_LOCK);
-        assert3ALockState("Changing AE lock affected AWB lock!",
-                AUTOWHITEBALANCE_LOCK, true);
-
-        set3ALockState(false, AUTOEXPOSURE_LOCK);
-        assert3ALockState("Changing AE lock affected AWB lock!",
-                AUTOWHITEBALANCE_LOCK, true);
-
-        // Verify that toggling AWB does not change AE lock state
-        set3ALockState(false, AUTOWHITEBALANCE_LOCK);
-        set3ALockState(false, AUTOEXPOSURE_LOCK);
-
-        set3ALockState(true, AUTOWHITEBALANCE_LOCK);
-        assert3ALockState("Changing AWB lock affected AE lock!",
-                AUTOEXPOSURE_LOCK, false);
-
-        set3ALockState(false, AUTOWHITEBALANCE_LOCK);
-        assert3ALockState("Changing AWB lock affected AE lock!",
-                AUTOEXPOSURE_LOCK, false);
-
-        set3ALockState(true, AUTOEXPOSURE_LOCK);
-
-        set3ALockState(true, AUTOWHITEBALANCE_LOCK);
-        assert3ALockState("Changing AWB lock affected AE lock!",
-                AUTOEXPOSURE_LOCK, true);
-
-        set3ALockState(false, AUTOWHITEBALANCE_LOCK);
-        assert3ALockState("Changing AWB lock affected AE lock!",
-                AUTOEXPOSURE_LOCK, true);
-    }
-
-    private void assert3ALockState(String msg, int type, boolean state) {
-        Parameters parameters = mCamera.getParameters();
-        switch (type) {
-            case AUTOEXPOSURE_LOCK:
-                assertTrue(msg, state == parameters.getAutoExposureLock());
-                break;
-            case AUTOWHITEBALANCE_LOCK:
-                assertTrue(msg, state == parameters.getAutoWhiteBalanceLock());
-                break;
-            default:
-                assertTrue("Unknown lock type " + type, false);
-                break;
-        }
-    }
-
-    private void set3ALockState(boolean state, int type) {
-        Parameters parameters = mCamera.getParameters();
-        switch (type) {
-            case AUTOEXPOSURE_LOCK:
-                parameters.setAutoExposureLock(state);
-                break;
-            case AUTOWHITEBALANCE_LOCK:
-                parameters.setAutoWhiteBalanceLock(state);
-                break;
-            default:
-                assertTrue("Unknown lock type "+type, false);
-                break;
-        }
-        mCamera.setParameters(parameters);
-    }
-
-    @UiThreadTest
-    public void testFaceDetection() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testFaceDetectionByCamera(id);
-        }
-    }
-
-    private void testFaceDetectionByCamera(int cameraId) throws Exception {
-        final int FACE_DETECTION_TEST_DURATION = 3000;
-        initializeMessageLooper(cameraId);
-        mCamera.startPreview();
-        Parameters parameters = mCamera.getParameters();
-        int maxNumOfFaces = parameters.getMaxNumDetectedFaces();
-        assertTrue(maxNumOfFaces >= 0);
-        if (maxNumOfFaces == 0) {
-            try {
-                mCamera.startFaceDetection();
-                fail("Should throw an exception if face detection is not supported.");
-            } catch (IllegalArgumentException e) {
-                // expected
-            }
-            terminateMessageLooper();
-            return;
-        }
-
-        mCamera.startFaceDetection();
-        try {
-            mCamera.startFaceDetection();
-            fail("Starting face detection twice should throw an exception");
-        } catch (RuntimeException e) {
-            // expected
-        }
-        FaceListener listener = new FaceListener();
-        mCamera.setFaceDetectionListener(listener);
-        // Sleep some time so the camera has chances to detect faces.
-        Thread.sleep(FACE_DETECTION_TEST_DURATION);
-        // The face callback runs in another thread. Release the camera and stop
-        // the looper. So we do not access the face array from two threads at
-        // the same time.
-        terminateMessageLooper();
-
-        // Check if the optional fields are supported.
-        boolean optionalFieldSupported = false;
-        Face firstFace = null;
-        for (Face[] faces: listener.mFacesArray) {
-            for (Face face: faces) {
-                if (face != null) firstFace = face;
-            }
-        }
-        if (firstFace != null) {
-            if (firstFace.id != -1 || firstFace.leftEye != null
-                    || firstFace.rightEye != null || firstFace.mouth != null) {
-                optionalFieldSupported = true;
-            }
-        }
-
-        // Verify the faces array.
-        for (Face[] faces: listener.mFacesArray) {
-            testFaces(faces, maxNumOfFaces, optionalFieldSupported);
-        }
-
-        // After taking a picture, face detection should be started again.
-        // Also make sure autofocus move callback is supported.
-        initializeMessageLooper(cameraId);
-        mCamera.setAutoFocusMoveCallback(mAutoFocusMoveCallback);
-        mCamera.startPreview();
-        mCamera.startFaceDetection();
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback, mJpegPictureCallback);
-        waitForSnapshotDone();
-        mCamera.startPreview();
-        mCamera.startFaceDetection();
-        terminateMessageLooper();
-    }
-
-    private class FaceListener implements FaceDetectionListener {
-        public ArrayList<Face[]> mFacesArray = new ArrayList<Face[]>();
-
-        @Override
-        public void onFaceDetection(Face[] faces, Camera camera) {
-            mFacesArray.add(faces);
-        }
-    }
-
-    private void testFaces(Face[] faces, int maxNumOfFaces,
-            boolean optionalFieldSupported) {
-        Rect bounds = new Rect(-1000, -1000, 1000, 1000);
-        assertNotNull(faces);
-        assertTrue(faces.length <= maxNumOfFaces);
-        for (int i = 0; i < faces.length; i++) {
-            Face face = faces[i];
-            Rect rect = face.rect;
-            // Check the bounds.
-            assertNotNull(rect);
-            assertTrue(rect.width() > 0);
-            assertTrue(rect.height() > 0);
-            assertTrue("Coordinates out of bounds. rect=" + rect,
-                    bounds.contains(rect) || Rect.intersects(bounds, rect));
-
-            // Check the score.
-            assertTrue(face.score >= 1 && face.score <= 100);
-
-            // Check id, left eye, right eye, and the mouth.
-            // Optional fields should be all valid or none of them.
-            if (!optionalFieldSupported) {
-                assertEquals(-1, face.id);
-                assertNull(face.leftEye);
-                assertNull(face.rightEye);
-                assertNull(face.mouth);
-            } else {
-                assertTrue(face.id != -1);
-                assertNotNull(face.leftEye);
-                assertNotNull(face.rightEye);
-                assertNotNull(face.mouth);
-                assertTrue(bounds.contains(face.leftEye.x, face.leftEye.y));
-                assertTrue(bounds.contains(face.rightEye.x, face.rightEye.y));
-                assertTrue(bounds.contains(face.mouth.x, face.mouth.y));
-                // ID should be unique.
-                if (i != faces.length - 1) {
-                    assertTrue(face.id != faces[i + 1].id);
-                }
-            }
-        }
-    }
-
-    @UiThreadTest
-    public void testVideoSnapshot() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testVideoSnapshotByCamera(id);
-        }
-    }
-
-    private static final int[] mCamcorderProfileList = {
-        CamcorderProfile.QUALITY_2160P,
-        CamcorderProfile.QUALITY_1080P,
-        CamcorderProfile.QUALITY_480P,
-        CamcorderProfile.QUALITY_720P,
-        CamcorderProfile.QUALITY_CIF,
-        CamcorderProfile.QUALITY_HIGH,
-        CamcorderProfile.QUALITY_LOW,
-        CamcorderProfile.QUALITY_QCIF,
-        CamcorderProfile.QUALITY_QVGA,
-    };
-
-    private void testVideoSnapshotByCamera(int cameraId) throws Exception {
-        initializeMessageLooper(cameraId);
-        Camera.Parameters parameters = mCamera.getParameters();
-        terminateMessageLooper();
-        if (!parameters.isVideoSnapshotSupported()) {
-            return;
-        }
-
-        SurfaceHolder holder = getActivity().getSurfaceView().getHolder();
-
-        for (int profileId: mCamcorderProfileList) {
-            if (!CamcorderProfile.hasProfile(cameraId, profileId)) {
-                continue;
-            }
-            initializeMessageLooper(cameraId);
-            // Set the preview size.
-            CamcorderProfile profile = CamcorderProfile.get(cameraId,
-                    profileId);
-            setPreviewSizeByProfile(parameters, profile);
-
-            // Set the biggest picture size.
-            Size biggestSize = mCamera.new Size(-1, -1);
-            for (Size size: parameters.getSupportedPictureSizes()) {
-                if (biggestSize.width < size.width) {
-                    biggestSize = size;
-                }
-            }
-            parameters.setPictureSize(biggestSize.width, biggestSize.height);
-
-            mCamera.setParameters(parameters);
-            mCamera.startPreview();
-            mCamera.unlock();
-            MediaRecorder recorder = new MediaRecorder();
-            try {
-                recorder.setCamera(mCamera);
-                recorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
-                recorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
-                recorder.setProfile(profile);
-                recorder.setOutputFile("/dev/null");
-                recorder.setPreviewDisplay(holder.getSurface());
-                recorder.prepare();
-                recorder.start();
-                subtestTakePictureByCamera(true,
-                        profile.videoFrameWidth, profile.videoFrameHeight);
-                testJpegExifByCamera(true);
-                testJpegThumbnailSizeByCamera(true,
-                        profile.videoFrameWidth, profile.videoFrameHeight);
-                Thread.sleep(2000);
-                recorder.stop();
-            } finally {
-                recorder.release();
-                mCamera.lock();
-            }
-            mCamera.stopPreview();
-            terminateMessageLooper();
-        }
-    }
-
-    public void testPreviewCallbackWithPicture() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testPreviewCallbackWithPictureByCamera(id);
-        }
-    }
-
-    private void testPreviewCallbackWithPictureByCamera(int cameraId)
-            throws Exception {
-        initializeMessageLooper(cameraId);
-
-        SimplePreviewStreamCb callback = new SimplePreviewStreamCb(1);
-        mCamera.setPreviewCallback(callback);
-
-        Log.v(TAG, "Starting preview");
-        mCamera.startPreview();
-
-        // Wait until callbacks are flowing
-        for (int i = 0; i < 30; i++) {
-            assertTrue("testPreviewCallbackWithPicture: Not receiving preview callbacks!",
-                    mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE ) );
-            mPreviewDone.close();
-        }
-
-        // Now take a picture
-        Log.v(TAG, "Taking picture now");
-
-        Size pictureSize = mCamera.getParameters().getPictureSize();
-        mCamera.takePicture(mShutterCallback, mRawPictureCallback,
-                mJpegPictureCallback);
-
-        waitForSnapshotDone();
-
-        assertTrue("Shutter callback not received", mShutterCallbackResult);
-        assertTrue("Raw picture callback not received", mRawPictureCallbackResult);
-        assertTrue("Jpeg picture callback not received", mJpegPictureCallbackResult);
-        assertNotNull(mJpegData);
-        BitmapFactory.Options bmpOptions = new BitmapFactory.Options();
-        bmpOptions.inJustDecodeBounds = true;
-        BitmapFactory.decodeByteArray(mJpegData, 0, mJpegData.length, bmpOptions);
-        assertEquals(pictureSize.width, bmpOptions.outWidth);
-        assertEquals(pictureSize.height, bmpOptions.outHeight);
-
-        // Restart preview, confirm callbacks still happen
-        Log.v(TAG, "Restarting preview");
-        mCamera.startPreview();
-
-        for (int i = 0; i < 30; i++) {
-            assertTrue("testPreviewCallbackWithPicture: Not receiving preview callbacks!",
-                    mPreviewDone.block( WAIT_FOR_COMMAND_TO_COMPLETE ) );
-            mPreviewDone.close();
-        }
-
-        mCamera.stopPreview();
-
-        terminateMessageLooper();
-    }
-
-    public void testEnableShutterSound() throws Exception {
-        int nCameras = Camera.getNumberOfCameras();
-        for (int id = 0; id < nCameras; id++) {
-            Log.v(TAG, "Camera id=" + id);
-            testEnableShutterSoundByCamera(id);
-        }
-    }
-
-    private void testEnableShutterSoundByCamera(int id) throws Exception {
-        CameraInfo info = new CameraInfo();
-
-        Camera.getCameraInfo(id, info);
-
-        initializeMessageLooper(id);
-
-        boolean result;
-        Log.v(TAG, "testEnableShutterSoundByCamera: canDisableShutterSound: " +
-                info.canDisableShutterSound);
-        result = mCamera.enableShutterSound(false);
-        assertTrue(result == info.canDisableShutterSound);
-        result = mCamera.enableShutterSound(true);
-        assertTrue(result);
-
-        terminateMessageLooper();
-    }
-
-    public void testCameraExternalConnected() {
-        if (getActivity().getPackageManager().
-                hasSystemFeature(PackageManager.FEATURE_CAMERA_EXTERNAL) ) {
-            int nCameras = Camera.getNumberOfCameras();
-            assertTrue("Devices with external camera support must have a camera connected for " +
-                    "testing",
-                    nCameras > 0);
-            for (int id = 0; id < nCameras; id++) {
-                try {
-                    Camera c = Camera.open(id);
-                    c.release();
-                } catch (Throwable e) {
-                    throw new AssertionError("Devices with external camera support must " +
-                            "have all listed cameras be connected and openable for testing", e);
-                }
-            }
-        }
-    }
-
-}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.java
new file mode 100644
index 0000000..c5607a0
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingFifoTest.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.hardware.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.FifoLengthVerification;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Checks the minimum Hardware FIFO length for each of the Hardware sensor.
+ * Further verifies if the advertised FIFO (Sensor.getFifoMaxEventCount()) is actually allocated
+ * for the sensor.
+ *
+ */
+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";
+
+    private SensorManager mSensorManager;
+    private boolean mHasHifiSensors;
+    @Override
+    protected void setUp() throws Exception {
+        mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
+        mHasHifiSensors = getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_HIFI_SENSORS);
+    }
+
+    public void testAccelerometerFifoLength() throws Throwable {
+        if (!mHasHifiSensors) return;
+        runBatchingSensorFifoTest(
+                Sensor.TYPE_ACCELEROMETER,
+                checkMinFifoLength(Sensor.TYPE_ACCELEROMETER, ACCELEROMETER_MIN_FIFO_LENGTH));
+    }
+
+    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));
+    }
+
+    public void testPressureFifoLength() throws Throwable {
+        if (!mHasHifiSensors) return;
+        runBatchingSensorFifoTest(
+                Sensor.TYPE_PRESSURE,
+                checkMinFifoLength(Sensor.TYPE_PRESSURE, PRESSURE_MIN_FIFO_LENGTH));
+    }
+
+    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));
+    }
+
+    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) {
+        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;
+    }
+
+    private void runBatchingSensorFifoTest(int sensorType, int fifoLength) throws Throwable {
+        if (fifoLength == 0) {
+            return;
+        }
+        Sensor sensor = mSensorManager.getDefaultSensor(sensorType);
+        TestSensorEnvironment environment =  new TestSensorEnvironment(getContext(),
+                sensor,
+                false, /* sensorMightHaveMoreListeners */
+                sensor.getMinDelay(),
+                Integer.MAX_VALUE /*maxReportLatencyUs*/);
+
+        int preFlushMs = 2000;  // 2 sec to make sure there is sample at the time of flush
+        int postFlushMs = environment.getExpectedSamplingPeriodUs() * 100 /1000;
+        int testFlushMs =
+                environment.getSensor().getFifoReservedEventCount() *
+                environment.getExpectedSamplingPeriodUs() / (int)(1000 / 1.2); // 120%
+
+        TestSensorOperation op = TestSensorOperation.createFlushOperation(
+                environment, new int [] { preFlushMs, testFlushMs, postFlushMs }, -1);
+
+        op.addVerification(FifoLengthVerification.getDefault(environment));
+        op.execute(getCurrentTestNode());
+        op.getStats().log(TAG);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java
index 7640cd7..4d4f3d3 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorBatchingTests.java
@@ -18,9 +18,11 @@
 
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorCtsHelper;
 import android.hardware.cts.helpers.SensorStats;
 import android.hardware.cts.helpers.TestSensorEnvironment;
 import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
+import android.hardware.cts.helpers.sensorverification.EventBasicVerification;
 import android.hardware.cts.helpers.sensorverification.ISensorVerification;
 
 import java.util.concurrent.TimeUnit;
@@ -43,7 +45,7 @@
 public class SensorBatchingTests extends SensorTestCase {
     private static final String TAG = "SensorBatchingTests";
 
-    private static final int BATCHING_10S = 10;
+    private static final int BATCHING_PERIOD = 10;  // sec
     private static final int RATE_50HZ = 20000;
     private static final int RATE_FASTEST = SensorManager.SENSOR_DELAY_FASTEST;
 
@@ -51,202 +53,202 @@
      * An arbitrary 'padding' time slot to wait for events after batching latency expires.
      * This allows for the test to wait for event arrivals after batching was expected.
      */
-    private static final int BATCHING_PADDING_TIME_S = 2;
+    private static final int BATCHING_PADDING_TIME_S = (int) Math.ceil(BATCHING_PERIOD * 0.1f + 2);
 
     public void testAccelerometer_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testAccelerometer_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testAccelerometer_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testAccelerometer_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_ACCELEROMETER, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testMagneticField_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testMagneticField_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testMagneticField_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testMagneticField_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD, RATE_50HZ, BATCHING_PERIOD);
     }
 
     @SuppressWarnings("deprecation")
     public void testOrientation_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_ORIENTATION, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_ORIENTATION, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     @SuppressWarnings("deprecation")
     public void testOrientation_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_ORIENTATION, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_ORIENTATION, RATE_50HZ, BATCHING_PERIOD);
     }
 
     @SuppressWarnings("deprecation")
     public void testOrientation_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_ORIENTATION, RATE_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_ORIENTATION, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     @SuppressWarnings("deprecation")
     public void testOrientation_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_ORIENTATION, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_ORIENTATION, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGyroscope_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GYROSCOPE, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GYROSCOPE, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGyroscope_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GYROSCOPE, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GYROSCOPE, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGyroscope_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GYROSCOPE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GYROSCOPE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGyroscope_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GYROSCOPE, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GYROSCOPE, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testPressure_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_PRESSURE, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_PRESSURE, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testPressure_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_PRESSURE, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_PRESSURE, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testPressure_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_PRESSURE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_PRESSURE, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_PERIOD);
     }
 
     public void testPressure_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_PRESSURE, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_PRESSURE, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGravity_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GRAVITY, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GRAVITY, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGravity_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GRAVITY, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GRAVITY, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGravity_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GRAVITY, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GRAVITY, SensorManager.SENSOR_DELAY_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGravity_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GRAVITY, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GRAVITY, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testRotationVector_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testRotationVector_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testRotationVector_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testRotationVector_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testMagneticFieldUncalibrated_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testMagneticFieldUncalibrated_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testMagneticFieldUncalibrated_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testMagneticFieldUncalibrated_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGameRotationVector_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGameRotationVector_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGameRotationVector_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGameRotationVector_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GAME_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGyroscopeUncalibrated_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGyroscopeUncalibrated_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGyroscopeUncalibrated_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGyroscopeUncalibrated_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GYROSCOPE_UNCALIBRATED, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testLinearAcceleration_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testLinearAcceleration_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testLinearAcceleration_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testLinearAcceleration_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_LINEAR_ACCELERATION, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGeomagneticRotationVector_fastest_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_FASTEST, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGeomagneticRotationVector_50hz_batching() throws Throwable {
-        runBatchingSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_10S);
+        runBatchingSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
     }
 
     public void testGeomagneticRotationVector_fastest_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_FASTEST, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_FASTEST, BATCHING_PERIOD);
     }
 
     public void testGeomagneticRotationVector_50hz_flush() throws Throwable {
-        runFlushSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_10S);
+        runFlushSensorTest(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR, RATE_50HZ, BATCHING_PERIOD);
     }
 
     private void runBatchingSensorTest(int sensorType, int rateUs, int maxBatchReportLatencySec)
@@ -263,6 +265,12 @@
         TestSensorOperation operation =
                 TestSensorOperation.createOperation(environment, testDurationSec, TimeUnit.SECONDS);
 
+        operation.addVerification(
+                EventBasicVerification.getDefault(
+                        environment, TimeUnit.SECONDS.toMicros(testDurationSec)
+                )
+        );
+
         executeTest(environment, operation, false /* flushExpected */);
     }
 
@@ -287,6 +295,7 @@
             TestSensorEnvironment environment,
             TestSensorOperation operation,
             boolean flushExpected) throws Throwable {
+        SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
         operation.addDefaultVerifications();
 
         try {
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
index 8c3fb7a..9bf1fd6 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorIntegrationTests.java
@@ -18,6 +18,7 @@
 import android.content.Context;
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorCtsHelper;
 import android.hardware.cts.helpers.TestSensorEnvironment;
 import android.hardware.cts.helpers.sensoroperations.ParallelSensorOperation;
 import android.hardware.cts.helpers.sensoroperations.RepeatingSensorOperation;
@@ -62,6 +63,7 @@
      * of several clients can lead to the failing state.
      */
     public void testSensorsWithSeveralClients() throws Throwable {
+        SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
         final int ITERATIONS = 50;
         final int MAX_REPORTING_LATENCY_US = (int) TimeUnit.SECONDS.toMicros(5);
         final Context context = getContext();
@@ -121,6 +123,7 @@
      * of several clients can lead to the failing state.
      */
     public void testSensorsMovingRates() throws Throwable {
+        SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
         // use at least two instances to ensure more than one client of any given sensor is in play
         final int INSTANCES_TO_USE = 5;
         final int ITERATIONS_TO_EXECUTE = 100;
@@ -219,6 +222,7 @@
     public void verifySensorStoppingInteraction(
             int sensorTypeTestee,
             int sensorTypeTester) throws Throwable {
+        SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
         Context context = getContext();
 
         TestSensorEnvironment testerEnvironment = new TestSensorEnvironment(
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorManagerStaticTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorManagerStaticTest.java
new file mode 100644
index 0000000..11ac701
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorManagerStaticTest.java
@@ -0,0 +1,776 @@
+/*
+ * 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.hardware.cts;
+
+import junit.framework.Assert;
+
+import android.content.Context;
+import android.hardware.SensorManager;
+import android.os.PowerManager;
+
+import java.util.Random;
+
+public class SensorManagerStaticTest extends SensorTestCase {
+    private static final String TAG = "SensorManagerTest";
+
+    // local float version of PI
+    private static final float FLOAT_PI = (float) Math.PI;
+
+
+    private PowerManager.WakeLock mWakeLock;
+
+    @Override
+    protected void setUp() throws Exception {
+        Context context = getContext();
+        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
+
+        mWakeLock.acquire();
+    }
+
+    @Override
+    protected void tearDown(){
+        if (mWakeLock != null && mWakeLock.isHeld()) {
+            mWakeLock.release();
+        }
+    }
+
+    // SensorManager Tests
+    public void testGetAltitude() throws Exception {
+        float r, q;
+        float altitude;
+
+        // identity property
+        for (r = 0.5f; r < 1.3f; r += 0.1f) {
+
+            altitude = SensorManager.getAltitude(r * SensorManager.PRESSURE_STANDARD_ATMOSPHERE,
+                                                 r * SensorManager.PRESSURE_STANDARD_ATMOSPHERE);
+            assertRoughlyEqual("getAltitude identity property violated.", altitude, 0.0f, 0.1f);
+        }
+
+        // uniform increasing as pressure decreases property
+        float prevAltitude = 1e5f; // 100km ceiling
+        for (r = 0.5f; r < 1.3f; r += 0.01f) {
+            altitude = SensorManager.getAltitude(SensorManager.PRESSURE_STANDARD_ATMOSPHERE,
+                                                 r * SensorManager.PRESSURE_STANDARD_ATMOSPHERE);
+
+            assertTrue("getAltitude result has to decrease as p increase.", prevAltitude > altitude);
+            prevAltitude = altitude;
+        }
+
+        // compare to a reference algorithm
+        final float coef = 1.0f / 5.255f;
+        for (r = 0.8f; r < 1.3f; r += 0.1f) {
+            for (q = 1.1f * r; q > 0.5f * r; q -= 0.1f * r) {
+                float p0 = r * SensorManager.PRESSURE_STANDARD_ATMOSPHERE;
+                float p  = q * SensorManager.PRESSURE_STANDARD_ATMOSPHERE;
+
+                float t1 = SensorManager.getAltitude(p0, p);
+                float t2 = 44330.f*(1.0f- (float) Math.pow(p/p0, coef));
+
+                assertRoughlyEqual(
+                      String.format("getAltitude comparing to reference algorithm failed. " +
+                          "Detail: getAltitude(%f, %f) => %f, reference => %f",
+                          p0, p, t1, t2),
+                      t1, t2, 100.f);
+            }
+        }
+
+    }
+
+    public void testGetAngleChange() throws Exception {
+        TestDataGenerator data = new TestDataGenerator();
+
+        int i;
+        float [] rotv = new float[3];
+        float [] rotv2 = new float[3];
+
+        // test many instances
+        for (i=0; i<100; ++i) {
+            float [] R1, R12, R2;
+            // azimuth(yaw) pitch roll
+            data.nextRotationAngles(rotv);
+            R1 = mat9VRot(rotv); // random base
+
+            // azimuth(yaw) pitch roll
+            data.nextRotationAngles(rotv);
+            R12 = mat9VRot(rotv);
+            R2 = mat9Mul(R1, R12); // apply another random rotation
+
+            // test different variations of input matrix format
+            switch(i & 3) {
+                case 0:
+                    SensorManager.getAngleChange(rotv2, R2, R1);
+                    break;
+                case 1:
+                    SensorManager.getAngleChange(rotv2, mat9to16(R2), R1);
+                    break;
+                case 2:
+                    SensorManager.getAngleChange(rotv2, R2, mat9to16(R1));
+                    break;
+                case 3:
+                    SensorManager.getAngleChange(rotv2, mat9to16(R2), mat9to16(R1));
+                    break;
+            }
+
+            // check range
+            assertRotationAnglesValid("getAngleChange result out of range.", rotv2);
+
+            // avoid directly checking the rotation angles to avoid corner cases
+            float [] R12rt = mat9T(mat9VRot(rotv2));
+            float [] RI = mat9Mul(R12rt, R12);
+
+            assertRoughlyEqual(
+                String.format("getAngleChange result is incorrect. Details: case %d, " +
+                    "truth = [%f, %f, %f], result = [%f, %f, %f]", i, rotv[0], rotv[1], rotv[2],
+                    rotv2[0], rotv2[1], rotv2[2]),
+                RI[0] + RI[4] + RI[8], 3.f, 1e-4f);
+        }
+    }
+
+    public void testGetInclination() throws Exception {
+        TestDataGenerator data = new TestDataGenerator();
+
+        int i;
+        float [] rotv = new float[3];
+        float [] rotv2 = new float[3];
+        float [] rotv3;
+
+        // test many instances
+        for (i = 0; i < 100; ++i) {
+            float [] R;
+            float angle;
+            angle = (data.nextFloat()-0.5f) * FLOAT_PI;
+            R = mat9Rot(SensorManager.AXIS_X, -angle);
+
+            float angler = ((i&1) != 0) ?
+                    SensorManager.getInclination(mat9to16(R)) : SensorManager.getInclination(R);
+            assertRoughlyEqual(
+                String.format(
+                    "getInclination return incorrect result. Detail: case %d, truth %f, result %f.",
+                    i, angle, angler),
+                angle, angler, 1e-4f);
+        }
+    }
+
+    public void testGetOrientation() throws Exception {
+        TestDataGenerator data = new TestDataGenerator();
+
+        int i;
+        float [] rotv = new float[3];
+        float [] rotv2 = new float[3];
+        float [] rotv3;
+
+        // test many instances
+        for (i=0; i<100; ++i) {
+            float [] R;
+            // yaw pitch roll
+            data.nextRotationAngles(rotv);
+            R = mat9VRot(rotv);
+
+            rotv3 = SensorManager.getOrientation( ((i&1) != 0) ? R : mat9to16(R), rotv2);
+            assertTrue("getOrientaion has to return the array passed in argument", rotv3 == rotv2);
+
+            // check range
+            assertRotationAnglesValid("getOrientation result out of range.", rotv2);
+
+            // Avoid directly comparing rotation angles. Instead, compare the rotation matrix.
+            float [] Rr = mat9T(mat9VRot(rotv2));
+            float [] RI = mat9Mul(Rr, R);
+
+            assertRoughlyEqual(
+                String.format("getOrientation result is incorrect. Details: case %d, " +
+                    "truth = [%f, %f, %f], result = [%f, %f, %f]", i, rotv[0], rotv[1], rotv[2],
+                    rotv2[0], rotv2[1], rotv2[2]),
+                RI[0] + RI[4] + RI[8], 3.f, 1e-4f);
+        }
+    }
+
+    public void testGetQuaternionFromVector() throws Exception {
+        TestDataGenerator data = new TestDataGenerator();
+
+        int i;
+        float [] v;
+        float [] q = new float[4];
+        float [] q2 = new float[4];
+        float [] v3 = new float[3];
+        float [] v4 = new float[4];
+        float [] v5 = new float[5];
+        float [][] vs = new float[][] {v3, v4, v5};
+
+        float [] xyzth = new float[4];
+        for (i = 0; i < 100; ++i) {
+            float c, s;
+
+            data.nextRotationAxisAngle(xyzth);
+
+            c = (float) Math.cos(xyzth[3]);
+            s = (float) Math.sin(xyzth[3]);
+            if (c < 0.f) {
+                c = -c;
+                s = -s;
+            }
+
+            v = vs[i%3];
+            switch(i%3) {
+                case 2:
+                    v[4] = data.nextBoolean() ? data.nextFloat() : -1.f;
+                case 1:
+                    v[3] = c;
+                case 0:
+                    v[0] = s * xyzth[0];
+                    v[1] = s * xyzth[1];
+                    v[2] = s * xyzth[2];
+            }
+
+            q2[0] = c;
+            q2[1] = v[0];
+            q2[2] = v[1];
+            q2[3] = v[2];
+
+            SensorManager.getQuaternionFromVector(q, v);
+            assertVectorRoughlyEqual(
+                String.format("getQuaternionFromVector returns wrong results, Details: case %d, " +
+                    "truth = (%f, %f, %f, %f), result = (%f, %f, %f, %f).",
+                    i, q2[0], q2[1], q2[2], q2[3], q[0], q[1], q[2], q[3]),
+                q, q2, 1e-4f);
+        }
+    }
+
+    public void testGetRotationMatrix() throws Exception {
+        TestDataGenerator data = new TestDataGenerator();
+        final float gravity = 9.81f;
+        final float magStrength = 50.f;
+
+        int i;
+        float [] gm = new float[9];
+        float [] rotv = new float[3];
+        float [] gI = null;
+        float [] mI = null;
+        float [] Rr = new float[9];
+        float [] Ir = new float[9];
+
+        gm[6] = gravity; // m/s^2, first column gravity
+
+        // test many instances
+        for (i=0; i<100; ++i) {
+            float [] Rt;
+            float incline;
+            // yaw pitch roll
+            data.nextRotationAngles(rotv);
+            Rt = mat9T(mat9VRot(rotv)); // from world frame to phone frame
+            //Rt = mat9I();
+
+            incline = -0.9f * (data.nextFloat() - 0.5f) * FLOAT_PI; // ~ +-80 degrees
+            //incline = 0.f;
+            gm[4] = magStrength * (float) Math.cos(-incline); // positive means rotate downwards
+            gm[7] = magStrength * (float) Math.sin(-incline);
+
+            float [] gmb = mat9Mul(Rt, gm); // do not care about right most column
+            gI = mat9Axis(gmb, SensorManager.AXIS_X);
+            mI = mat9Axis(gmb, SensorManager.AXIS_Y);
+
+            assertTrue("getRotationMatrix returns false on valid inputs",
+                SensorManager.getRotationMatrix(Rr, Ir, gI, mI));
+
+            float [] n = mat9Mul(Rr, Rt);
+            assertRoughlyEqual(
+                String.format("getRotationMatrix returns incorrect R matrix. " +
+                    "Details: case %d, truth R = %s, result R = %s.",
+                    i, mat9ToStr(mat9T(Rt)), mat9ToStr(Rr)),
+                n[0] + n[4] + n[8], 3.f, 1e-4f);
+
+
+            // Magnetic incline is defined so that it means the magnetic field lines is formed
+            // by rotate local y axis around -x axis by incline angle. However, I matrix is
+            // defined as (according to document):
+            //     [0 m 0] = I * R * geomagnetic,
+            // which means,
+            //     I' * [0 m 0] = R * geomagnetic.
+            // Thus, I' = Rot(-x, incline) and I = Rot(-x, incline)' = Rot(x, incline)
+            float [] Ix = mat9Rot(SensorManager.AXIS_X, incline);
+            assertVectorRoughlyEqual(
+                String.format("getRotationMatrix returns incorrect I matrix. " +
+                    "Details: case %d, truth I = %s, result I = %s.",
+                    i, mat9ToStr(Ix), mat9ToStr(Ir)),
+                Ix, Ir, 1e-4f);
+        }
+
+        // test 16 element inputs
+        float [] Rr2 = new float[16];
+        float [] Ir2 = new float[16];
+
+        assertTrue("getRotationMatrix returns false on valid inputs",
+            SensorManager.getRotationMatrix(Rr2, Ir2, gI, mI));
+
+        assertVectorRoughlyEqual(
+            "getRotationMatrix acts inconsistent with 9- and 16- elements matrix buffer",
+            mat16to9(Rr2), Rr, 1e-4f);
+
+        assertVectorRoughlyEqual(
+            "getRotationMatrix acts inconsistent with 9- and 16- elements matrix buffer",
+            mat16to9(Ir2), Ir, 1e-4f);
+
+        // test null inputs
+        assertTrue("getRotationMatrix does not handle null inputs",
+            SensorManager.getRotationMatrix(Rr, null, gI, mI));
+
+        assertTrue("getRotationMatrix does not handle null inputs",
+            SensorManager.getRotationMatrix(null, Ir, gI, mI));
+
+        assertTrue("getRotationMatrix does not handle null inputs",
+            SensorManager.getRotationMatrix(null, null, gI, mI));
+
+        // test fail cases
+        // free fall, if the acc reading is less than 10% of gravity
+        gI[0] = gI[1] = gI[2] = data.nextFloat() * gravity * 0.05f; // sqrt(3) * 0.05 < 0.1
+         assertFalse("getRotationMatrix does not fail when it supposed to fail (gravity too small)",
+            SensorManager.getRotationMatrix(Rr, Ir, gI, mI));
+
+        // wrong input
+        assertFalse("getRotationMatrix does not fail when it supposed to fail (singular axis)",
+            SensorManager.getRotationMatrix(Rr, Ir, gI, gI));
+    }
+
+    public void testGetRotationMatrixFromVector() throws Exception {
+        TestDataGenerator data = new TestDataGenerator();
+
+        int i;
+        float [] v;
+        float [] q = new float[4];
+
+        float [] v3 = new float[3];
+        float [] v4 = new float[4];
+        float [] v5 = new float[5];
+        float [][] vs = new float[][]{v3, v4, v5};
+
+        float [] m9 = new float[9];
+        float [] m16 = new float[16];
+
+        // format: x y z theta/2
+        float [] xyzth = new float[4];
+        // test the orthogonal property of returned matrix
+        for (i=0; i<20; ++i) {
+            float c, s;
+            data.nextRotationAxisAngle(xyzth);
+
+            c = (float) Math.cos(xyzth[3]);
+            s = (float) Math.sin(xyzth[3]);
+            if (c < 0.f) {
+                c = -c;
+                s = -s;
+            }
+
+            v = vs[i%3];
+            switch(i%3) {
+                case 2:
+                    v[4] = data.nextBoolean() ? data.nextFloat() : -1.f;
+                case 1:
+                    v[3] = c;
+                case 0:
+                    v[0] = s * xyzth[0];
+                    v[1] = s * xyzth[1];
+                    v[2] = s * xyzth[2];
+            }
+
+            if ((i % 1) != 0) {
+                SensorManager.getRotationMatrixFromVector(m16, v);
+                m9 = mat16to9(m16);
+            }else {
+                SensorManager.getRotationMatrixFromVector(m9, v);
+            }
+
+            float [] n = mat9Mul(m9, mat9T(m9));
+            assertRoughlyEqual("getRotationMatrixFromVector do not return proper matrix",
+                    n[0]+ n[4] + n[8], 3.f, 1e-4f);
+        }
+
+        // test if multiple rotation (total 2pi) about an axis result in identity
+        v = v3;
+        float [] Rr = new float[9];
+
+        for (i=0; i<20; ++i) {
+            float j, halfTheta, residualHalfTheta = FLOAT_PI;
+            float [] R = mat9I();
+            float c, s;
+
+            data.nextRotationAxisAngle(xyzth);  // half theta is ignored
+
+            j = data.nextInt(5) + 2;  // 2 ~ 6 rotations
+
+            while(j-- > 0) {
+                if (j == 0) {
+                    halfTheta = residualHalfTheta;
+                } else {
+                    halfTheta = data.nextFloat() * FLOAT_PI;
+                }
+
+                c = (float) Math.cos(halfTheta);
+                s = (float) Math.sin(halfTheta);
+                if (c < 0.f) {
+                    c = -c;
+                    s = -s;
+                }
+
+                v[0] = s * xyzth[0];
+                v[1] = s * xyzth[1];
+                v[2] = s * xyzth[2];
+
+                SensorManager.getRotationMatrixFromVector(Rr, v);
+                R = mat9Mul(Rr, R);
+
+                residualHalfTheta -= halfTheta;
+            }
+
+            assertRoughlyEqual("getRotationMatrixFromVector returns incorrect matrix",
+                    R[0] + R[4] + R[8], 3.f, 1e-4f);
+        }
+
+        // test if rotation about trival axis works
+        v = v3;
+        for (i=0; i<20; ++i) {
+            int axis = (i % 3) + 1;
+            float theta = data.nextFloat() * 2.f * FLOAT_PI;
+            float [] R;
+
+            v[0] = v[1] = v[2] = 0.f;
+            v[axis - 1] = (float) Math.sin(theta / 2.f);
+            if ( (float) Math.cos(theta / 2.f) < 0.f) {
+                v[axis-1] = -v[axis-1];
+            }
+
+            SensorManager.getRotationMatrixFromVector(m9, v);
+            R = mat9Rot(axis, theta);
+
+            assertVectorRoughlyEqual(
+                String.format("getRotationMatrixFromVector returns incorrect matrix with "+
+                    "simple rotation. Details: case %d, truth R = %s, result R = %s.",
+                    i, mat9ToStr(R), mat9ToStr(m9)),
+                R, m9, 1e-4f);
+        }
+    }
+
+    public void testRemapCoordinateSystem() throws Exception {
+        TestDataGenerator data = new TestDataGenerator();
+
+        int i, j, k;
+        float [] rotv = new float[3];
+        float [] Rout = new float[9];
+        float [] Rout2 = new float[16];
+        int a1, a2; // AXIS_X/Y/Z
+        int b1, b2, b3; // AXIS_X/Y/Z w/ or w/o MINUS
+
+        // test a few instances
+        for (i=0; i<10; ++i) {
+            float [] R;
+            // yaw pitch roll
+            data.nextRotationAngles(rotv);
+            R = mat9VRot(rotv);
+
+            // total of 6*4 = 24 variations
+            // 6 = A(3,2)
+            for (j=0; j<9; ++j) {
+                // axis without minus
+                a1 = j/3 + 1;
+                a2 = j%3 + 1;
+
+                // skip cases when two axis are the same
+                if (a1 == a2) continue;
+
+                for (k=0; k<3; ++k) {
+                    // test all minus axis combination: ++, +-, -+, --
+                    b1 = a1 | (((k & 2) != 0) ? 0x80 : 0);
+                    b2 = a2 | (((k & 1) != 0) ? 0x80 : 0);
+                    // the third axis
+                    b3 = (6 - a1 -a2) |
+                         ( (((a2 + 3 - a1) % 3 == 2) ? 0x80 : 0) ^ (b1 & 0x80) ^ (b2 & 0x80));
+
+                    // test both input formats
+                    if ( (i & 1) != 0 ) {
+                      assertTrue(SensorManager.remapCoordinateSystem(R, b1, b2, Rout));
+                    } else {
+                      assertTrue(SensorManager.remapCoordinateSystem(mat9to16(R), b1, b2, Rout2));
+                      Rout = mat16to9(Rout2);
+                    }
+
+                    float [] v1, v2;
+
+                    String detail = String.format(
+                            "Details: case %d (%x %x %x), original R = %s, result R = %s.",
+                            i, b1, b2, b3, mat9ToStr(R), mat9ToStr(Rout));
+
+                    v1 = mat9Axis(R, SensorManager.AXIS_X);
+                    v2 = mat9Axis(Rout, b1);
+                    assertVectorRoughlyEqual(
+                        "remapCoordinateSystem gives incorrect result (x)." + detail,
+                        v1, v2, 1e-4f);
+
+                    v1 = mat9Axis(R, SensorManager.AXIS_Y);
+                    v2 = mat9Axis(Rout, b2);
+                    assertVectorRoughlyEqual(
+                        "remapCoordinateSystem gives incorrect result (y)." + detail,
+                        v1, v2, 1e-4f);
+
+                    v1 = mat9Axis(R, SensorManager.AXIS_Z);
+                    v2 = mat9Axis(Rout, b3);
+                    assertVectorRoughlyEqual(
+                        "remapCoordinateSystem gives incorrect result (z)." + detail,
+                        v1, v2, 1e-4f);
+                }
+            }
+
+        }
+
+        // test cases when false should be returned
+        assertTrue("remapCoordinateSystem should return false with mismatch size input and output",
+                   !SensorManager.remapCoordinateSystem(Rout,
+                     SensorManager.AXIS_Y, SensorManager.AXIS_Z, Rout2));
+        assertTrue("remapCoordinateSystem should return false with invalid axis setting",
+                   !SensorManager.remapCoordinateSystem(Rout,
+                     SensorManager.AXIS_X, SensorManager.AXIS_X, Rout));
+        assertTrue("remapCoordinateSystem should return false with invalid axis setting",
+                   !SensorManager.remapCoordinateSystem(Rout,
+                     SensorManager.AXIS_X, SensorManager.AXIS_MINUS_X, Rout));
+
+    }
+
+    // Utilities class & functions
+
+    private class TestDataGenerator {
+        // carry out test deterministically without manually picking numbers
+        private final long DEFAULT_SEED = 0xFEDCBA9876543210l;
+
+        private Random mRandom;
+
+        TestDataGenerator(long seed) {
+            mRandom = new Random(seed);
+        }
+
+        TestDataGenerator() {
+            mRandom = new Random(DEFAULT_SEED);
+        }
+
+        void nextRotationAngles(float [] rotv) {
+            assertTrue(rotv.length == 3);
+
+            rotv[0] = (mRandom.nextFloat()-0.5f) * 2.0f * FLOAT_PI; // azimuth(yaw) -pi ~ pi
+            rotv[1] = (mRandom.nextFloat()-0.5f) * FLOAT_PI; // pitch -pi/2 ~ +pi/2
+            rotv[2] = (mRandom.nextFloat()-0.5f) * 2.f * FLOAT_PI; // roll -pi ~ +pi
+        }
+
+        void nextRotationAxisAngle(float [] aa) {
+            assertTrue(aa.length == 4);
+
+            aa[0] = (mRandom.nextFloat() - 0.5f) * 2.f;
+            aa[1] = (mRandom.nextFloat() - 0.5f ) * 2.f * (float) Math.sqrt(1.f - aa[0] * aa[0]);
+            aa[2] = (mRandom.nextBoolean() ? 1.f : -1.f) *
+                        (float) Math.sqrt(1.f - aa[0] * aa[0] - aa[1] * aa[1]);
+            aa[3] = mRandom.nextFloat() * FLOAT_PI;
+        }
+
+        int nextInt(int i) {
+            return mRandom.nextInt(i);
+        }
+
+        float nextFloat() {
+            return mRandom.nextFloat();
+        }
+
+        boolean nextBoolean() {
+            return mRandom.nextBoolean();
+        }
+    }
+
+    private static void assertRotationAnglesValid(String message, float[] ra) {
+
+        assertTrue(message, ra.length == 3 &&
+            ra[0] >= -FLOAT_PI && ra[0] <= FLOAT_PI &&         // azimuth
+            ra[1] >= -FLOAT_PI / 2.f && ra[1] <= FLOAT_PI / 2.f && // pitch
+            ra[2] >= -FLOAT_PI && ra[2] <= FLOAT_PI);          // roll
+    }
+
+    private static void assertRoughlyEqual(String message, float a, float b, float bound) {
+        assertTrue(message, Math.abs(a-b) < bound);
+    }
+
+    private static void assertVectorRoughlyEqual(String message, float [] v1, float [] v2,
+                                                 float bound) {
+        assertTrue(message, v1.length == v2.length);
+        int i;
+        float sum = 0.f;
+        for (i=0; i<v1.length; ++i) {
+            sum += (v1[i] - v2[i]) * (v1[i] - v2[i]);
+        }
+        assertRoughlyEqual(message, (float)Math.sqrt(sum), 0.f, bound);
+    }
+
+    private static float [] mat9to16(float [] m) {
+        assertTrue(m.length == 9);
+
+        float [] n  = new float[16];
+        int i;
+        for (i=0; i<9; ++i) {
+            n[i+i/3] = m[i];
+        }
+        n[15] = 1.f;
+        return n;
+    }
+
+    private static float [] mat16to9(float [] m) {
+        assertTrue(m.length == 16);
+
+        float [] n = new float[9];
+        int i;
+        for (i=0; i<9; ++i) {
+            n[i] = m[i + i/3];
+        }
+        return n;
+    }
+
+    private static float [] mat9Mul(float [] m, float [] n) {
+        assertTrue(m.length == 9 && n.length == 9);
+
+        float [] r = new float[9];
+        int i, j, k;
+
+        for (i = 0; i < 3; ++i)
+            for (j = 0; j < 3; ++j)
+                for (k = 0; k < 3; ++k)
+                    r[i * 3 + j] += m[i * 3 + k] * n[k * 3 + j];
+
+        return r;
+    }
+
+    private static float [] mat9T(float [] m) {
+        assertTrue(m.length == 9);
+
+        int i, j;
+        float [] n = new float[9];
+
+        for (i = 0; i < 3; ++i)
+            for (j = 0; j < 3; ++j)
+                n[i * 3 + j] = m[j * 3 + i];
+
+        return n;
+    }
+
+    private static float [] mat9I() {
+        float [] m = new float[9];
+        m[0] = m[4] = m[8] = 1.f;
+        return m;
+    }
+
+    private static float [] mat9Rot(int axis, float angle) {
+        float [] m = new float[9];
+        switch (axis) {
+            case SensorManager.AXIS_X:
+                m[0] = 1.f;
+                m[4] = m[8] = (float) Math.cos(angle);
+                m[5] = - (m[7] = (float) Math.sin(angle));
+                break;
+            case SensorManager.AXIS_Y:
+                m[4] = 1.f;
+                m[0] = m[8] = (float) Math.cos(angle);
+                m[6] = - (m[2] = (float) Math.sin(angle));
+                break;
+            case SensorManager.AXIS_Z:
+                m[8] = 1.f;
+                m[0] = m[4] = (float) Math.cos(angle);
+                m[1] = - (m[3] = (float) Math.sin(angle));
+                break;
+            default:
+                // should never be here
+                assertTrue(false);
+        }
+        return m;
+    }
+
+    private static float [] mat9VRot(float [] angles) {
+        assertTrue(angles.length == 3);
+        // yaw, android yaw rotate to -z
+        float [] R = mat9Rot(SensorManager.AXIS_Z, -angles[0]);
+        // pitch, android pitch rotate to -x
+        R = mat9Mul(R, mat9Rot(SensorManager.AXIS_X, -angles[1]));
+        // roll
+        R = mat9Mul(R, mat9Rot(SensorManager.AXIS_Y, angles[2]));
+
+        return R;
+    }
+
+    private static float [] mat9Axis(float m[], int axis) {
+        assertTrue(m.length == 9);
+
+        boolean negative = (axis & 0x80) != 0;
+        float [] v = new float[3];
+        int offset;
+
+        offset = (axis & ~0x80) - 1;
+        v[0] = negative ? -m[offset]   : m[offset];
+        v[1] = negative ? -m[offset+3] : m[offset+3];
+        v[2] = negative ? -m[offset+6] : m[offset+6];
+        return v;
+    }
+
+    private static float vecInner(float u[], float v[]) {
+        assertTrue(u.length == v.length);
+
+        int i;
+        float sum = 0.f;
+
+        for (i=0; i < v.length; ++i) {
+            sum += u[i]*v[i];
+        }
+        return (float)Math.sqrt(sum);
+    }
+
+    private static String vecToStr(float u[]) {
+        int i;
+        String s;
+        switch (u.length) {
+            case 3:
+                return String.format("[%f, %f, %f]", u[0], u[1], u[2]);
+            case 4:
+                return String.format("(%f, %f, %f, %f)", u[0], u[1], u[2], u[3]);
+            default:
+                s = "[";
+                for (i = 0; i < u.length-1; ++i) {
+                    s += String.format("%f, ", u[i]);
+                }
+                s += String.format("%f]", u[i]);
+                return s;
+        }
+    }
+
+    private static String mat9ToStr(float m[]) {
+        assertTrue(m.length == 9);
+        return String.format("[%f, %f, %f; %f, %f, %f; %f, %f, %f]",
+            m[0], m[1], m[2],
+            m[3], m[4], m[5],
+            m[6], m[7], m[8]);
+    }
+
+    private static String mat16ToStr(float m[]) {
+        assertTrue(m.length == 16);
+        return String.format("[%f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f; %f, %f, %f, %f]",
+            m[0], m[1], m[2], m[3],
+            m[4], m[5], m[6], m[7],
+            m[8], m[9], m[10], m[11],
+            m[12], m[13], m[14], m[15]);
+    }
+
+}
+
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.java
new file mode 100644
index 0000000..22f092a
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorParameterRangeTest.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 android.hardware.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorCtsHelper;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test min-max frequency, max range parameters for sensors.
+ *
+ * <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
+ * </pre>
+ */
+public class SensorParameterRangeTest extends SensorTestCase {
+
+    private static final double ACCELEROMETER_MAX_RANGE = 8 * 9.80; // 8G minus a slop
+    private static final double ACCELEROMETER_MIN_FREQUENCY = 12.50;
+    private static final int ACCELEROMETER_MAX_FREQUENCY = 200;
+
+    private static final double GYRO_MAX_RANGE = 1000/57.295 - 1.0; // 1000 degrees per sec minus a slop
+    private static final double GYRO_MIN_FREQUENCY = 12.50;
+    private static final double GYRO_MAX_FREQUENCY = 200.0;
+
+    private static final int MAGNETOMETER_MAX_RANGE = 900;   // micro telsa
+    private static final double MAGNETOMETER_MIN_FREQUENCY = 5.0;
+    private static final double MAGNETOMETER_MAX_FREQUENCY = 50.0;
+
+    private static final double PRESSURE_MAX_RANGE = 1100.0;     // hecto-pascal
+    private static final double PRESSURE_MIN_FREQUENCY = 1.0;
+    private static final double PRESSURE_MAX_FREQUENCY = 10.0;
+
+    private boolean mHasHifiSensors;
+    private SensorManager mSensorManager;
+
+    @Override
+    public void setUp() {
+        mSensorManager = (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
+        mHasHifiSensors = getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_HIFI_SENSORS);
+    }
+
+    public void testAccelerometerRange() {
+        checkSensorRangeAndFrequency(
+                mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
+                ACCELEROMETER_MAX_RANGE,
+                ACCELEROMETER_MIN_FREQUENCY,
+                ACCELEROMETER_MAX_FREQUENCY);
+  }
+
+  public void testGyroscopeRange() {
+        checkSensorRangeAndFrequency(
+                mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
+                GYRO_MAX_RANGE,
+                GYRO_MIN_FREQUENCY,
+                GYRO_MAX_FREQUENCY);
+  }
+
+    public void testMagnetometerRange() {
+        checkSensorRangeAndFrequency(
+                mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
+                MAGNETOMETER_MAX_RANGE,
+                MAGNETOMETER_MIN_FREQUENCY,
+                MAGNETOMETER_MAX_FREQUENCY);
+    }
+
+    public void testPressureRange() {
+        checkSensorRangeAndFrequency(
+                mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE),
+                PRESSURE_MAX_RANGE,
+                PRESSURE_MIN_FREQUENCY,
+                PRESSURE_MAX_FREQUENCY);
+    }
+
+    private void checkSensorRangeAndFrequency(
+          Sensor sensor, double maxRange, double minFrequency, double maxFrequency) {
+        if (!mHasHifiSensors) return;
+        assertTrue(String.format("%s Range actual=%.2f expected=%.2f %s",
+                    sensor.getName(), sensor.getMaximumRange(), maxRange,
+                    SensorCtsHelper.getUnitsForSensor(sensor)),
+                sensor.getMaximumRange() >= maxRange);
+        double actualMinFrequency = SensorCtsHelper.getFrequency(sensor.getMaxDelay(),
+                TimeUnit.MICROSECONDS);
+        assertTrue(String.format("%s Min Frequency actual=%.2f expected=%.2fHz",
+                    sensor.getName(), actualMinFrequency, minFrequency), actualMinFrequency <=
+                minFrequency + 0.1);
+
+        double actualMaxFrequency = SensorCtsHelper.getFrequency(sensor.getMinDelay(),
+                TimeUnit.MICROSECONDS);
+        assertTrue(String.format("%s Max Frequency actual=%.2f expected=%.2fHz",
+                    sensor.getName(), actualMaxFrequency, maxFrequency), actualMaxFrequency >=
+                maxFrequency - 0.1);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorSupportTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorSupportTest.java
new file mode 100644
index 0000000..2f25c8d
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorSupportTest.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.hardware.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.test.AndroidTestCase;
+
+/**
+ * Checks if Hifi sensors are supported. When supported, checks individual support for
+ * Accelerometer, Gyroscope, Gyroscope_uncal, GeoMagneticField, MagneticField_uncal
+ * Pressure, RotationVector, SignificantMotion, StepDetector, StepCounter, TiltDetector.
+ *
+ * <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
+ * </pre>
+ */
+public class SensorSupportTest extends AndroidTestCase {
+    private SensorManager mSensorManager;
+    private boolean mAreHifiSensorsSupported;
+
+    @Override
+    public void setUp() {
+        // Tests will only run if HIFI_SENSORS are supported.
+        mAreHifiSensorsSupported = getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_HIFI_SENSORS);
+        if (mAreHifiSensorsSupported) {
+            mSensorManager =
+                    (SensorManager) getContext().getSystemService(Context.SENSOR_SERVICE);
+        }
+    }
+
+    public void testSupportsAccelerometer() {
+        checkSupportsSensor(Sensor.TYPE_ACCELEROMETER);
+    }
+
+    public void testSupportsGyroscope() {
+        checkSupportsSensor(Sensor.TYPE_GYROSCOPE);
+    }
+
+    public void testSupportsGyroscopeUncalibrated() {
+        checkSupportsSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED);
+    }
+
+    public void testSupportsGeoMagneticField() {
+        checkSupportsSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR);
+    }
+
+    public void testSupportsMagneticFieldUncalibrated() {
+        checkSupportsSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED);
+    }
+
+    public void testSupportsPressure() {
+        checkSupportsSensor(Sensor.TYPE_PRESSURE);
+    }
+
+    public void testSupportsRotationVector() {
+        checkSupportsSensor(Sensor.TYPE_ROTATION_VECTOR);
+    }
+
+    public void testSupportsSignificantMotion() {
+        checkSupportsSensor(Sensor.TYPE_SIGNIFICANT_MOTION);
+    }
+
+    public void testSupportsStepDetector() {
+        checkSupportsSensor(Sensor.TYPE_STEP_DETECTOR);
+    }
+
+    public void testSupportsStepCounter() {
+        checkSupportsSensor(Sensor.TYPE_STEP_COUNTER);
+    }
+
+    public void testSupportsTiltDetector() {
+        final int TYPE_TILT_DETECTOR = 22;
+        checkSupportsSensor(TYPE_TILT_DETECTOR);
+    }
+
+    private void checkSupportsSensor(int sensorType) {
+        if (mAreHifiSensorsSupported) {
+            assertTrue(mSensorManager.getDefaultSensor(sensorType) != null);
+        }
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
index 162474a..2bbf053 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTest.java
@@ -29,6 +29,7 @@
 import android.hardware.SensorManager;
 import android.hardware.TriggerEvent;
 import android.hardware.TriggerEventListener;
+import android.hardware.cts.helpers.SensorCtsHelper;
 import android.hardware.cts.helpers.SensorNotSupportedException;
 import android.hardware.cts.helpers.SensorTestStateNotSupportedException;
 import android.hardware.cts.helpers.TestSensorEnvironment;
@@ -47,6 +48,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Random;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -88,12 +90,12 @@
     @Override
     protected void tearDown() {
         if (mSensorManager != null) {
-           // SensorManager will check listener and status, so just unregister listener
-           mSensorManager.unregisterListener(mNullSensorEventListener);
-           if (mTriggerSensor != null) {
-               mSensorManager.cancelTriggerSensor(mNullTriggerEventListener, mTriggerSensor);
-               mTriggerSensor = null;
-           }
+            // SensorManager will check listener and status, so just unregister listener
+            mSensorManager.unregisterListener(mNullSensorEventListener);
+            if (mTriggerSensor != null) {
+                mSensorManager.cancelTriggerSensor(mNullTriggerEventListener, mTriggerSensor);
+                mTriggerSensor = null;
+            }
         }
 
         if (mTestSensorManager != null) {
@@ -166,8 +168,8 @@
         }
 
         sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
-        // orientation sensor is required if the device can physically implement it
-        if (hasCompass && hasAccelerometer) {
+        // Note: orientation sensor is deprecated.
+        if (sensor != null) {
             assertEquals(Sensor.TYPE_ORIENTATION, sensor.getType());
             assertSensorValues(sensor);
         }
@@ -312,6 +314,7 @@
     // TODO: remove when parameterized tests are supported (see SensorBatchingTests.java)
     @TimeoutReq(minutes=20)
     public void testBatchAndFlush() throws Exception {
+        SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
         ArrayList<Throwable> errorsFound = new ArrayList<>();
         for (Sensor sensor : mSensorList) {
             verifyRegisterListenerCallFlush(sensor, null /* handler */, errorsFound);
@@ -324,6 +327,7 @@
      */
     @TimeoutReq(minutes=10)
     public void testBatchAndFlushWithHandler() throws Exception {
+        SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
         Sensor sensor = null;
         for (Sensor s : mSensorList) {
             if (s.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) {
@@ -349,15 +353,51 @@
         TestSensorEventListener listener = new TestSensorEventListener(environment, handler);
 
         CountDownLatch eventLatch = mTestSensorManager.registerListener(listener, 1);
-        listener.waitForEvents(eventLatch, 1);
+        listener.waitForEvents(eventLatch, 1, true);
         CountDownLatch flushLatch = mTestSensorManager.requestFlush();
-        listener.waitForFlushComplete(flushLatch);
+        listener.waitForFlushComplete(flushLatch, true);
+        listener.assertEventsReceivedInHandler();
+    }
+
+    /**
+     *  Explicit testing the SensorManager.registerListener(SensorEventListener, Sensor, int, int).
+     */
+    @TimeoutReq(minutes=10)
+    public void testBatchAndFlushUseDefaultHandler() throws Exception {
+        SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
+        Sensor sensor = null;
+        for (Sensor s : mSensorList) {
+            if (s.getReportingMode() == Sensor.REPORTING_MODE_CONTINUOUS) {
+                sensor = s;
+                break;
+            }
+        }
+        if (sensor == null) {
+            throw new SensorTestStateNotSupportedException(
+                    "There are no Continuous sensors in the device.");
+        }
+
+        TestSensorEnvironment environment = new TestSensorEnvironment(
+                getContext(),
+                sensor,
+                SensorManager.SENSOR_DELAY_FASTEST,
+                (int) TimeUnit.SECONDS.toMicros(5));
+        mTestSensorManager = new TestSensorManager(environment);
+
+        TestSensorEventListener listener = new TestSensorEventListener(environment, null);
+
+        // specifyHandler <= false, use the SensorManager API without Handler parameter
+        CountDownLatch eventLatch = mTestSensorManager.registerListener(listener, 1, false);
+        listener.waitForEvents(eventLatch, 1, true);
+        CountDownLatch flushLatch = mTestSensorManager.requestFlush();
+        listener.waitForFlushComplete(flushLatch, true);
         listener.assertEventsReceivedInHandler();
     }
 
     // TODO: after L release move to SensorBatchingTests and run in all sensors with default
     //       verifications enabled
     public void testBatchAndFlushWithMultipleSensors() throws Exception {
+        SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
         final int maxSensors = 3;
         final int maxReportLatencyUs = (int) TimeUnit.SECONDS.toMicros(10);
         List<Sensor> sensorsToTest = new ArrayList<Sensor>();
@@ -548,10 +588,10 @@
             try {
                 CountDownLatch eventLatch = sensorManager.registerListener(listener, mEventCount);
                 if (sensorReportingMode == Sensor.REPORTING_MODE_CONTINUOUS) {
-                    listener.waitForEvents(eventLatch, mEventCount);
+                    listener.waitForEvents(eventLatch, mEventCount, true);
                 }
                 CountDownLatch flushLatch = sensorManager.requestFlush();
-                listener.waitForFlushComplete(flushLatch);
+                listener.waitForFlushComplete(flushLatch, true);
             } finally {
                 sensorManager.unregisterListener();
             }
@@ -570,4 +610,5 @@
         @Override
         public void onAccuracyChanged(Sensor sensor, int accuracy) {}
     }
+
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/SensorTestCase.java b/tests/tests/hardware/src/android/hardware/cts/SensorTestCase.java
index 42b8d33..10992c5 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SensorTestCase.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SensorTestCase.java
@@ -32,15 +32,12 @@
     protected static final String LOG_TAG = "TestRunner";
 
     /**
-     * By default tests need to run in a {@link TestSensorEnvironment} that assumes each sensor is
-     * running with a load of several listeners, requesting data at different rates.
-     *
-     * In a better world the component acting as builder of {@link SensorOperation} would compute
-     * this value based on the tests composed.
-     *
-     * Ideally, each {@link Sensor} object would expose this information to clients.
+     * Previously for L release, we had this flag to know if each sensor is running with multiple
+     * listeners each requesting different data rates. Now before running CTS tests all sensors
+     * are de-activated by putting SensorService in RESTRICTED mode. Only CTS tests can
+     * activate/deactivate sensors in this mode. So we can default this flag value to false.
      */
-    private volatile boolean mEmulateSensorUnderLoad = true;
+    private volatile boolean mEmulateSensorUnderLoad = false;
 
     /**
      * By default the test class is the root of the test hierarchy.
diff --git a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
index 0fbd8fa..73d61a5 100644
--- a/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
+++ b/tests/tests/hardware/src/android/hardware/cts/SingleSensorTests.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.hardware.Sensor;
 import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorCtsHelper;
 import android.hardware.cts.helpers.SensorStats;
 import android.hardware.cts.helpers.TestSensorEnvironment;
 import android.hardware.cts.helpers.sensoroperations.TestSensorOperation;
@@ -542,6 +543,7 @@
     }
 
     private void runSensorTest(int sensorType, int rateUs) throws Throwable {
+        SensorCtsHelper.sleep(3, TimeUnit.SECONDS);
         TestSensorEnvironment environment = new TestSensorEnvironment(
                 getContext(),
                 sensorType,
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
index 490e965..9cb3710 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelper.java
@@ -15,6 +15,7 @@
  */
 package android.hardware.cts.helpers;
 
+import android.hardware.Sensor;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -37,21 +38,32 @@
     private SensorCtsHelper() {}
 
     /**
-     * Get the value of the 95th percentile using nearest rank algorithm.
+     * Get percentiles using nearest rank algorithm.
      *
-     * @throws IllegalArgumentException if the collection is null or empty
+     * @param percentiles List of percentiles interested. Its range is 0 to 1, instead of in %.
+     *        The value will be internally bounded.
+     *
+     * @throws IllegalArgumentException if the collection or percentiles is null or empty
      */
-    public static <TValue extends Comparable<? super TValue>> TValue get95PercentileValue(
-            Collection<TValue> collection) {
+    public static <TValue extends Comparable<? super TValue>> List<TValue> getPercentileValue(
+            Collection<TValue> collection, float[] percentiles) {
         validateCollection(collection);
+        if(percentiles == null || percentiles.length == 0) {
+            throw new IllegalStateException("percentiles cannot be null or empty");
+        }
 
         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);
+        List<TValue> percentileValues = new ArrayList<TValue>();
+        for (float p : percentiles) {
+            // zero-based array index
+            int arrayIndex = (int) Math.round(arrayCopy.size() * p - .5f);
+            // bound the index to avoid out of range error
+            arrayIndex = Math.min(Math.max(arrayIndex, 0), arrayCopy.size() - 1);
+            percentileValues.add(arrayCopy.get(arrayIndex));
+        }
+        return percentileValues;
     }
 
     /**
@@ -259,4 +271,20 @@
             throw new IllegalStateException("Collection cannot be null or empty");
         }
     }
+
+    public static String getUnitsForSensor(Sensor sensor) {
+        switch(sensor.getType()) {
+            case Sensor.TYPE_ACCELEROMETER:
+                return "m/s^2";
+            case Sensor.TYPE_MAGNETIC_FIELD:
+            case Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:
+                return "uT";
+            case Sensor.TYPE_GYROSCOPE:
+            case Sensor.TYPE_GYROSCOPE_UNCALIBRATED:
+                return "radians/sec";
+            case Sensor.TYPE_PRESSURE:
+                return "hPa";
+        };
+        return "";
+    }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java
index 6f99692..daac8d1 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorCtsHelperTest.java
@@ -30,80 +30,6 @@
 public class SensorCtsHelperTest extends TestCase {
 
     /**
-     * Test {@link SensorCtsHelper#get95PercentileValue(Collection)}.
-     */
-    public void testGet95PercentileValue() {
-        Collection<Integer> values = new HashSet<Integer>();
-        for (int i = 0; i < 100; i++) {
-            values.add(i);
-        }
-        assertEquals(95, (int) SensorCtsHelper.get95PercentileValue(values));
-
-        values = new HashSet<Integer>();
-        for (int i = 0; i < 1000; i++) {
-            values.add(i);
-        }
-        assertEquals(950, (int) SensorCtsHelper.get95PercentileValue(values));
-
-        values = new HashSet<Integer>();
-        for (int i = 0; i < 100; i++) {
-            values.add(i * i);
-        }
-        assertEquals(95 * 95, (int) SensorCtsHelper.get95PercentileValue(values));
-    }
-
-    /**
-     * Test {@link SensorCtsHelper#getMean(Collection)}.
-     */
-    public void testGetMean() {
-        List<Integer> values = Arrays.asList(0, 1, 2, 3, 4);
-        double mean = SensorCtsHelper.getMean(values);
-        assertEquals(2.0, mean, 0.00001);
-
-        values = Arrays.asList(1, 2, 3, 4, 5);
-        mean = SensorCtsHelper.getMean(values);
-        assertEquals(3.0, mean, 0.00001);
-
-        values = Arrays.asList(0, 1, 4, 9, 16);
-        mean = SensorCtsHelper.getMean(values);
-        assertEquals(6.0, mean, 0.00001);
-    }
-
-    /**
-     * Test {@link SensorCtsHelper#getVariance(Collection)}.
-     */
-    public void testGetVariance() {
-        List<Integer> values = Arrays.asList(0, 1, 2, 3, 4);
-        double variance = SensorCtsHelper.getVariance(values);
-        assertEquals(2.5, variance, 0.00001);
-
-        values = Arrays.asList(1, 2, 3, 4, 5);
-        variance = SensorCtsHelper.getVariance(values);
-        assertEquals(2.5, variance, 0.00001);
-
-        values = Arrays.asList(0, 2, 4, 6, 8);
-        variance = SensorCtsHelper.getVariance(values);
-        assertEquals(10.0, variance, 0.00001);
-    }
-
-    /**
-     * Test {@link SensorCtsHelper#getStandardDeviation(Collection)}.
-     */
-    public void testGetStandardDeviation() {
-        List<Integer> values = Arrays.asList(0, 1, 2, 3, 4);
-        double stddev = SensorCtsHelper.getStandardDeviation(values);
-        assertEquals(Math.sqrt(2.5), stddev, 0.00001);
-
-        values = Arrays.asList(1, 2, 3, 4, 5);
-        stddev = SensorCtsHelper.getStandardDeviation(values);
-        assertEquals(Math.sqrt(2.5), stddev, 0.00001);
-
-        values = Arrays.asList(0, 2, 4, 6, 8);
-        stddev = SensorCtsHelper.getStandardDeviation(values);
-        assertEquals(Math.sqrt(10.0), stddev, 0.00001);
-    }
-
-    /**
      * Test {@link SensorCtsHelper#getFrequency(Number, TimeUnit)}.
      */
     public void testGetFrequency() {
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorNotSupportedException.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorNotSupportedException.java
index e727092..0d90957 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorNotSupportedException.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorNotSupportedException.java
@@ -26,6 +26,11 @@
         super("Sensor '%s' of type %d is not supported.", getSensorName(sensorType), sensorType);
     }
 
+    public SensorNotSupportedException(int sensorType, boolean wakeup) {
+        super("Sensor '%s' of type %d and %s is not supported.", getSensorName(sensorType),
+               sensorType, wakeup ? "wake-up" : "non wake-up");
+    }
+
     private static String getSensorName(int sensorType) {
         return String.format("%s (%d)", getSimpleSensorName(sensorType), sensorType);
     }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
index 8067aed..ad9b0cd 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SensorStats.java
@@ -41,6 +41,7 @@
     public static final String DELIMITER = "__";
 
     public static final String ERROR = "error";
+    public static final String EVENT_FIFO_LENGTH = "event_fifo_length_observed";
     public static final String EVENT_GAP_COUNT_KEY = "event_gap_count";
     public static final String EVENT_GAP_POSITIONS_KEY = "event_gap_positions";
     public static final String EVENT_OUT_OF_ORDER_COUNT_KEY = "event_out_of_order_count";
@@ -49,11 +50,14 @@
             "event_time_synchronization_count";
     public static final String EVENT_TIME_SYNCHRONIZATION_POSITIONS_KEY =
             "event_time_synchronization_positions";
+    public static final String EVENT_COUNT_KEY = "event_count";
+    public static final String WRONG_SENSOR_KEY = "wrong_sensor_observed";
     public static final String FREQUENCY_KEY = "frequency";
     public static final String JITTER_95_PERCENTILE_PERCENT_KEY = "jitter_95_percentile_percent";
     public static final String MEAN_KEY = "mean";
     public static final String STANDARD_DEVIATION_KEY = "standard_deviation";
     public static final String MAGNITUDE_KEY = "magnitude";
+    public static final String DELAYED_BATCH_DELIVERY = "delayed_batch_delivery";
 
     private final Map<String, Object> mValues = new HashMap<>();
     private final Map<String, SensorStats> mSensorStats = new HashMap<>();
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/SuspendStateMonitor.java b/tests/tests/hardware/src/android/hardware/cts/helpers/SuspendStateMonitor.java
new file mode 100644
index 0000000..627e876
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/SuspendStateMonitor.java
@@ -0,0 +1,83 @@
+package android.hardware.cts.helpers;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import android.hardware.Sensor;
+import android.hardware.TriggerEvent;
+import android.hardware.TriggerEventListener;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.util.Log;
+
+import junit.framework.Assert;
+
+public class SuspendStateMonitor extends TimerTask {
+    private final double firstRealTimeMillis;
+    private final double firstUpTimeMillis;
+    private double lastSleepTimeSeconds = 0;
+    private volatile long lastWakeUpTime = 0;
+    Timer sleepMonitoringTimer = new Timer();
+    private final List<CountDownLatch> mWaitForWakeUpLatch = new ArrayList<>();
+    private final String TAG = "SensorCTSDeviceSuspendMonitor";
+
+    /**
+     * Returns the time the device slept since the start of the application,
+     * in seconds.
+     */
+    public double getSleepTimeSeconds() {
+        double totalSinceStart = android.os.SystemClock.elapsedRealtime() - firstRealTimeMillis;
+        double upTimeSinceStart = android.os.SystemClock.uptimeMillis() - firstUpTimeMillis;
+        return (totalSinceStart - upTimeSinceStart) / 1000;
+    }
+
+    public long getLastWakeUpTime() {
+        return lastWakeUpTime;
+    }
+
+
+    public void waitForWakeUp(int numSeconds) throws InterruptedException {
+        CountDownLatch latch = new CountDownLatch(1);
+        synchronized(mWaitForWakeUpLatch) {
+            mWaitForWakeUpLatch.add(latch);
+        }
+        if (numSeconds == -1) {
+            // Wait indefinitely.
+            latch.await();
+        } else {
+            // Wait for the specified number of seconds.
+            boolean countZero = latch.await(numSeconds, TimeUnit.SECONDS);
+            if (!countZero) {
+               Log.e(TAG, "Device did not enter suspend state.");
+            }
+        }
+    }
+
+    /**
+     * Run every 100ms inside the TimerTask.
+     */
+    @Override
+    public void run() {
+        if (getSleepTimeSeconds() - lastSleepTimeSeconds > 0.1) {
+            lastSleepTimeSeconds = getSleepTimeSeconds();
+            lastWakeUpTime = SystemClock.elapsedRealtime();
+            // If any client is waiting for wake-up, call countDown to unblock it.
+            synchronized(mWaitForWakeUpLatch) {
+                for (CountDownLatch latch : mWaitForWakeUpLatch) {
+                    latch.countDown();
+                }
+            }
+        }
+    }
+
+    public SuspendStateMonitor() {
+        firstRealTimeMillis = android.os.SystemClock.elapsedRealtime();
+        firstUpTimeMillis = android.os.SystemClock.uptimeMillis();
+        // Every 100 miliseconds, check whether the device has slept.
+        sleepMonitoringTimer.schedule(this, 0, 100);
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
index 143f0a1..47c8313 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEnvironment.java
@@ -40,6 +40,7 @@
     private final boolean mSensorMightHaveMoreListeners;
     private final int mSamplingPeriodUs;
     private final int mMaxReportLatencyUs;
+    private final boolean mIsDeviceSuspendTest;
 
     /**
      * Constructs an environment for sensor testing.
@@ -163,11 +164,27 @@
             boolean sensorMightHaveMoreListeners,
             int samplingPeriodUs,
             int maxReportLatencyUs) {
+        this(context,
+                sensor,
+                sensorMightHaveMoreListeners,
+                samplingPeriodUs,
+                maxReportLatencyUs,
+                false /* isDeviceSuspendTest */);
+    }
+
+    public TestSensorEnvironment(
+            Context context,
+            Sensor sensor,
+            boolean sensorMightHaveMoreListeners,
+            int samplingPeriodUs,
+            int maxReportLatencyUs,
+            boolean isDeviceSuspendTest) {
         mContext = context;
         mSensor = sensor;
         mSensorMightHaveMoreListeners = sensorMightHaveMoreListeners;
         mSamplingPeriodUs = samplingPeriodUs;
         mMaxReportLatencyUs = maxReportLatencyUs;
+        mIsDeviceSuspendTest = isDeviceSuspendTest;
     }
 
     /**
@@ -206,7 +223,7 @@
         if (mSamplingPeriodUs == SensorManager.SENSOR_DELAY_FASTEST) {
             return "fastest";
         }
-        return String.format("%.0fhz", getFrequencyHz());
+        return String.format("%.2fhz", getFrequencyHz());
     }
 
     /**
@@ -357,4 +374,9 @@
                 && mSamplingPeriodUs != SensorManager.SENSOR_DELAY_UI
                 && mSamplingPeriodUs != SensorManager.SENSOR_DELAY_NORMAL);
     }
+
+    public boolean isDeviceSuspendTest() {
+        return mIsDeviceSuspendTest;
+    }
 }
+
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
index 6e25e86..e8df1ab 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorEventListener.java
@@ -18,12 +18,16 @@
 
 import junit.framework.Assert;
 
+import android.content.Context;
 import android.hardware.Sensor;
 import android.hardware.SensorEvent;
 import android.hardware.SensorEventListener2;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.SystemClock;
+import android.os.PowerManager;
+import android.os.PowerManager.WakeLock;
+import android.util.Log;
 
 import java.io.BufferedWriter;
 import java.io.File;
@@ -50,12 +54,14 @@
     private static final long FLUSH_TIMEOUT_US = TimeUnit.SECONDS.toMicros(10);
 
     private final ArrayList<TestSensorEvent> mCollectedEvents = new ArrayList<>();
+    private final ArrayList<Long> mTimeStampFlushCompleteEvents = new ArrayList<>();
     private final List<CountDownLatch> mEventLatches = new ArrayList<>();
     private final List<CountDownLatch> mFlushLatches = new ArrayList<>();
     private final AtomicInteger mEventsReceivedOutsideHandler = new AtomicInteger();
 
     private final Handler mHandler;
     private final TestSensorEnvironment mEnvironment;
+    private final PowerManager.WakeLock mTestSensorEventListenerWakeLock;
 
     /**
      * @deprecated Use {@link TestSensorEventListener(TestSensorEnvironment)}.
@@ -78,6 +84,10 @@
     public TestSensorEventListener(TestSensorEnvironment environment, Handler handler) {
         mEnvironment = environment;
         mHandler = handler;
+        PowerManager pm = (PowerManager) environment.getContext().getSystemService(
+                Context.POWER_SERVICE);
+        mTestSensorEventListenerWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
+                                                "TestSensorEventListenerWakeLock");
     }
 
     /**
@@ -93,6 +103,9 @@
         synchronized (mEventLatches) {
             for (CountDownLatch latch : mEventLatches) {
                 latch.countDown();
+                if (latch.getCount() == 0 && !mTestSensorEventListenerWakeLock.isHeld()) {
+                    mTestSensorEventListenerWakeLock.acquire();
+                }
             }
         }
     }
@@ -136,6 +149,10 @@
     @Override
     public void onFlushCompleted(Sensor sensor) {
         checkHandler();
+        long timestampNs = SystemClock.elapsedRealtimeNanos();
+        synchronized (mTimeStampFlushCompleteEvents) {
+           mTimeStampFlushCompleteEvents.add(timestampNs);
+        }
         synchronized (mFlushLatches) {
             for (CountDownLatch latch : mFlushLatches) {
                 latch.countDown();
@@ -174,7 +191,8 @@
      * It will overwrite the file if it already exists, the file is created in a relative directory
      * named 'events' under the sensor test directory (part of external storage).
      */
-    public void logCollectedEventsToFile(String fileName) throws IOException {
+    public void logCollectedEventsToFile(String fileName, long deviceWakeUpTimeMs)
+        throws IOException {
         StringBuilder builder = new StringBuilder();
         builder.append("Sensor='").append(mEnvironment.getSensor()).append("', ");
         builder.append("SamplingRateOverloaded=")
@@ -183,15 +201,54 @@
                 .append(mEnvironment.getRequestedSamplingPeriodUs()).append("us, ");
         builder.append("MaxReportLatency=")
                 .append(mEnvironment.getMaxReportLatencyUs()).append("us");
-
         synchronized (mCollectedEvents) {
-            for (TestSensorEvent event : mCollectedEvents) {
+            int i = 0, j = 0;
+            while (i < mCollectedEvents.size() && j < mTimeStampFlushCompleteEvents.size()) {
+                if (mCollectedEvents.get(i).receivedTimestamp <
+                        mTimeStampFlushCompleteEvents.get(j)) {
+                    TestSensorEvent event = mCollectedEvents.get(i);
+                    if (deviceWakeUpTimeMs != -1 && deviceWakeUpTimeMs <
+                            event.receivedTimestamp/1000000) {
+                        builder.append("\n");
+                        builder.append("AP wake-up time=").append(deviceWakeUpTimeMs).append("ms");
+                        deviceWakeUpTimeMs = -1;
+                    }
+                    builder.append("\n");
+                    builder.append("Timestamp=").append(event.timestamp/1000000).append("ms, ");
+                    builder.append("ReceivedTimestamp=").append(event.receivedTimestamp/1000000).
+                        append("ms, ");
+                    builder.append("Accuracy=").append(event.accuracy).append(", ");
+                    builder.append("Values=").append(Arrays.toString(event.values));
+                    ++i;
+                } else {
+                    builder.append("\n");
+                    builder.append("ReceivedTimestamp=")
+                    .append(mTimeStampFlushCompleteEvents.get(j)/1000000)
+                    .append("ms Flush complete Event");
+                    ++j;
+                }
+            }
+            for (;i < mCollectedEvents.size(); ++i) {
+                TestSensorEvent event = mCollectedEvents.get(i);
+                if (deviceWakeUpTimeMs != -1 && deviceWakeUpTimeMs <
+                        event.receivedTimestamp/1000000) {
+                    builder.append("\n");
+                    builder.append("AP wake-up time=").append(deviceWakeUpTimeMs).append("ms");
+                    deviceWakeUpTimeMs = -1;
+                }
                 builder.append("\n");
-                builder.append("Timestamp=").append(event.timestamp).append("ns, ");
-                builder.append("ReceivedTimestamp=").append(event.receivedTimestamp).append("ns, ");
+                builder.append("Timestamp=").append(event.timestamp/1000000).append("ms, ");
+                builder.append("ReceivedTimestamp=").append(event.receivedTimestamp/1000000).
+                    append("ms, ");
                 builder.append("Accuracy=").append(event.accuracy).append(", ");
                 builder.append("Values=").append(Arrays.toString(event.values));
             }
+            for (;j < mTimeStampFlushCompleteEvents.size(); ++j) {
+                builder.append("\n");
+                builder.append("ReceivedTimestamp=")
+                    .append(mTimeStampFlushCompleteEvents.get(j)/1000000)
+                    .append("ms Flush complete Event");
+            }
         }
 
         File eventsDirectory = SensorCtsHelper.getSensorTestDataDirectory("events/");
@@ -207,8 +264,11 @@
      *
      * @throws AssertionError if there was a timeout after {@link #FLUSH_TIMEOUT_US} &micro;s
      */
-    public void waitForFlushComplete(CountDownLatch latch) throws InterruptedException {
-        clearEvents();
+    public void waitForFlushComplete(CountDownLatch latch,
+                                      boolean clearCollectedEvents) throws InterruptedException {
+        if (clearCollectedEvents) {
+            clearEvents();
+        }
         try {
             String message = SensorCtsHelper.formatAssertionMessage(
                     "WaitForFlush",
@@ -228,8 +288,11 @@
      *
      * @throws AssertionError if there was a timeout after {@link #FLUSH_TIMEOUT_US} &micro;s
      */
-    public void waitForEvents(CountDownLatch latch, int eventCount) throws InterruptedException {
-        clearEvents();
+    public void waitForEvents(CountDownLatch latch, int eventCount,
+                               boolean clearCollectedEvents) throws InterruptedException {
+        if (clearCollectedEvents) {
+            clearEvents();
+        }
         try {
             long samplingPeriodUs = mEnvironment.getMaximumExpectedSamplingPeriodUs();
             // timeout is 2 * event count * expected period + batch timeout + default wait
@@ -278,6 +341,12 @@
         Assert.assertEquals(message, 0 /* expected */, eventsOutsideHandler);
     }
 
+    public void releaseWakeLock() {
+        if (mTestSensorEventListenerWakeLock.isHeld()) {
+            mTestSensorEventListenerWakeLock.release();
+        }
+    }
+
     /**
      * Keeps track of the number of events that arrived in a different {@link Looper} than the one
      * associated with the {@link TestSensorEventListener}.
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
index 2468bd1..23580de 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/TestSensorManager.java
@@ -77,6 +77,7 @@
 
         mTestSensorEventListener = listener;
         String message = SensorCtsHelper.formatAssertionMessage("registerListener", mEnvironment);
+
         boolean result = mSensorManager.registerListener(
                 mTestSensorEventListener,
                 mEnvironment.getSensor(),
@@ -94,7 +95,10 @@
      * @throws AssertionError if there was an error registering the listener with the
      * {@link SensorManager}
      */
-    public CountDownLatch registerListener(TestSensorEventListener listener, int eventCount) {
+    public CountDownLatch registerListener(
+            TestSensorEventListener listener,
+            int eventCount,
+            boolean specifyHandler) {
         if (mTestSensorEventListener != null) {
             Log.w(LOG_TAG, "Listener already registered, returning.");
             return null;
@@ -103,17 +107,41 @@
         CountDownLatch latch = listener.getLatchForSensorEvents(eventCount);
         mTestSensorEventListener = listener;
         String message = SensorCtsHelper.formatAssertionMessage("registerListener", mEnvironment);
-        boolean result = mSensorManager.registerListener(
-                mTestSensorEventListener,
-                mEnvironment.getSensor(),
-                mEnvironment.getRequestedSamplingPeriodUs(),
-                mEnvironment.getMaxReportLatencyUs(),
-                mTestSensorEventListener.getHandler());
+
+        boolean result;
+        if (specifyHandler) {
+            result = mSensorManager.registerListener(
+                    mTestSensorEventListener,
+                    mEnvironment.getSensor(),
+                    mEnvironment.getRequestedSamplingPeriodUs(),
+                    mEnvironment.getMaxReportLatencyUs(),
+                    mTestSensorEventListener.getHandler());
+        } else {
+            result = mSensorManager.registerListener(
+                    mTestSensorEventListener,
+                    mEnvironment.getSensor(),
+                    mEnvironment.getRequestedSamplingPeriodUs(),
+                    mEnvironment.getMaxReportLatencyUs());
+        }
         Assert.assertTrue(message, result);
         return latch;
     }
 
     /**
+     * Register the listener. This method will perform a no-op if the sensor is already registered.
+     *
+     * @return A CountDownLatch initialized with eventCount which is used to wait for sensor
+     * events.
+     * @throws AssertionError if there was an error registering the listener with the
+     * {@link SensorManager}
+     */
+    public CountDownLatch registerListener(
+            TestSensorEventListener listener,
+            int eventCount) {
+        return registerListener(listener, eventCount, true);
+    }
+
+    /**
      * Unregister the listener. This method will perform a no-op if the sensor is not registered.
      */
     public void unregisterListener() {
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
index 3b90b15..6d94d47 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensoroperations/TestSensorOperation.java
@@ -16,7 +16,11 @@
 
 package android.hardware.cts.helpers.sensoroperations;
 
-import junit.framework.Assert;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import android.hardware.cts.helpers.SensorCtsHelper;
 import android.hardware.cts.helpers.SensorStats;
@@ -25,7 +29,9 @@
 import android.hardware.cts.helpers.TestSensorEvent;
 import android.hardware.cts.helpers.TestSensorEventListener;
 import android.hardware.cts.helpers.TestSensorManager;
+import android.hardware.cts.helpers.SuspendStateMonitor;
 import android.hardware.cts.helpers.reporting.ISensorTestNode;
+import android.hardware.cts.helpers.sensorverification.EventBasicVerification;
 import android.hardware.cts.helpers.sensorverification.EventGapVerification;
 import android.hardware.cts.helpers.sensorverification.EventOrderingVerification;
 import android.hardware.cts.helpers.sensorverification.EventTimestampSynchronizationVerification;
@@ -36,13 +42,11 @@
 import android.hardware.cts.helpers.sensorverification.MeanVerification;
 import android.hardware.cts.helpers.sensorverification.StandardDeviationVerification;
 import android.os.Handler;
+import android.os.SystemClock;
+import android.os.PowerManager.WakeLock;
 import android.util.Log;
 
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
+import junit.framework.Assert;
 
 /**
  * A {@link SensorOperation} used to verify that sensor events and sensor values are correct.
@@ -61,6 +65,7 @@
     private final TestSensorEnvironment mEnvironment;
     private final Executor mExecutor;
     private final Handler mHandler;
+    private long mDeviceWakeUpTimeMs = -1;
 
     /**
      * An interface that defines an abstraction for operations to be performed by the
@@ -118,7 +123,22 @@
     public void execute(ISensorTestNode parent) throws InterruptedException {
         getStats().addValue("sensor_name", mEnvironment.getSensor().getName());
         TestSensorEventListener listener = new TestSensorEventListener(mEnvironment, mHandler);
-        mExecutor.execute(mSensorManager, listener);
+
+        if (mEnvironment.isDeviceSuspendTest()) {
+            SuspendStateMonitor suspendStateMonitor = new SuspendStateMonitor();
+            long startTimeMs = SystemClock.elapsedRealtime();
+            // Device should go into suspend here.
+            mExecutor.execute(mSensorManager, listener);
+            long endTimeMs = SystemClock.elapsedRealtime();
+            // Check if the device has gone into suspend during test execution.
+            mDeviceWakeUpTimeMs = suspendStateMonitor.getLastWakeUpTime();
+            suspendStateMonitor.cancel();
+            Assert.assertTrue("Device did not go into suspend during test execution",
+                                       startTimeMs < mDeviceWakeUpTimeMs &&
+                                       mDeviceWakeUpTimeMs < endTimeMs);
+        } else {
+            mExecutor.execute(mSensorManager, listener);
+        }
 
         boolean failed = false;
         StringBuilder sb = new StringBuilder();
@@ -129,7 +149,6 @@
 
         if (failed) {
             trySaveCollectedEvents(parent, listener);
-
             String msg = SensorCtsHelper
                     .formatAssertionMessage("VerifySensorOperation", mEnvironment, sb.toString());
             getStats().addValue(SensorStats.ERROR, msg);
@@ -193,7 +212,7 @@
         }
 
         try {
-            listener.logCollectedEventsToFile(sanitizedFileName);
+            listener.logCollectedEventsToFile(sanitizedFileName, mDeviceWakeUpTimeMs);
         } catch (IOException e) {
             Log.w(TAG, "Unable to save collected events to file: " + sanitizedFileName, e);
         }
@@ -214,7 +233,7 @@
                     throws InterruptedException {
                 try {
                     CountDownLatch latch = sensorManager.registerListener(listener, eventCount);
-                    listener.waitForEvents(latch, eventCount);
+                    listener.waitForEvents(latch, eventCount, true);
                 } finally {
                     sensorManager.unregisterListener();
                 }
@@ -224,6 +243,89 @@
     }
 
     /**
+     * Creates an operation that will wait for a given amount of events to arrive.
+     *
+     * @param environment The test environment.
+     * @param eventCount The number of events to wait for.
+     */
+    public static TestSensorOperation createOperation(
+            final TestSensorEnvironment environment,
+            final WakeLock wakeLock,
+            final boolean flushBeforeAfterSuspend) {
+        Executor executor = new Executor() {
+            @Override
+            public void execute(TestSensorManager sensorManager, TestSensorEventListener listener)
+                    throws InterruptedException {
+                try {
+                    sensorManager.registerListener(listener);
+                    if (flushBeforeAfterSuspend) {
+                        int initialNumEvents1 = listener.getCollectedEvents().size();
+                        SensorCtsHelper.sleep(2, TimeUnit.SECONDS);
+                        CountDownLatch flushLatch1 = sensorManager.requestFlush();
+                        listener.waitForFlushComplete(flushLatch1, false);
+                        Assert.assertTrue("1.No sensor events collected on calling flush " +
+                                environment.toString(),
+                                listener.getCollectedEvents().size() - initialNumEvents1 > 0);
+                    }
+
+                    Log.i(TAG, "Collected sensor events size1=" +
+                            listener.getCollectedEvents().size());
+                    int initialNumEvents2 = listener.getCollectedEvents().size();
+                    if (wakeLock.isHeld()) {
+                        wakeLock.release();
+                    }
+                    listener.releaseWakeLock();
+
+                    SuspendStateMonitor suspendMonitor = new SuspendStateMonitor();
+                    long approxStartTimeMs = SystemClock.elapsedRealtime();
+                    // Allow the device to go into suspend. Wait for wake-up.
+                    suspendMonitor.waitForWakeUp(15);
+                    suspendMonitor.cancel();
+
+                    if (!wakeLock.isHeld()) {
+                        wakeLock.acquire();
+                    }
+
+                    CountDownLatch flushLatch2 = sensorManager.requestFlush();
+                    listener.waitForFlushComplete(flushLatch2, false);
+
+                    Log.i(TAG, "Collected sensor events size2=" +
+                            listener.getCollectedEvents().size());
+
+                    if (listener.getCollectedEvents().size() - initialNumEvents2 <= 0 &&
+                            suspendMonitor.getLastWakeUpTime() > 0) {
+                        // Fail
+                        String str = String.format("No Sensor events collected by calling flush " +
+                                "after device wake up. Approx time after which device went into " +
+                                "suspend %dms ,approx AP wake-up time %dms %s",
+                                approxStartTimeMs, suspendMonitor.getLastWakeUpTime(),
+                                environment.toString());
+                        Assert.fail(str);
+                    }
+                    if (flushBeforeAfterSuspend) {
+                        int initialNumEvents3 = listener.getCollectedEvents().size();
+                        SensorCtsHelper.sleep(2, TimeUnit.SECONDS);
+                        CountDownLatch flushLatch3 = sensorManager.requestFlush();
+                        listener.waitForFlushComplete(flushLatch3, false);
+                        Assert.assertTrue("3.No sensor events collected on calling flush " +
+                                environment.toString(),
+                                listener.getCollectedEvents().size() - initialNumEvents3 > 0);
+                    }
+                    Log.i(TAG, "Collected sensor events size3=" +
+                            listener.getCollectedEvents().size());
+                } finally {
+                    if(!wakeLock.isHeld()) {
+                        wakeLock.acquire();
+                    }
+                    listener.releaseWakeLock();
+                    sensorManager.unregisterListener();
+                }
+            }
+        };
+        return new TestSensorOperation(environment, executor);
+    }
+
+    /**
      * Creates an operation that will wait for a given amount of time to collect events.
      *
      * @param environment The test environment.
@@ -261,15 +363,41 @@
             TestSensorEnvironment environment,
             final long duration,
             final TimeUnit timeUnit) {
+
+        return createFlushOperation(environment, new int[] {(int)timeUnit.toMillis(duration)}, 0);
+    }
+
+    /**
+     * Creates an operation that make a series of flush (by calling
+     * {@link TestSensorManager#requestFlush()}) with predefined interval after registerListener.
+     *
+     * @param environment The test environment.
+     * @param flushIntervalMs intervals between calls to {@link TestSensorManager#requestFlush()}.
+     * @param clearEventIndex the index of interval which
+     *        {@link TestSensorEventListerner#clearEvent} is called (-1 for never).
+     */
+    public static TestSensorOperation createFlushOperation(
+            TestSensorEnvironment environment,
+            final int [] flushIntervalMs,
+            final int    clearEventIndex) {
+
+        Assert.assertTrue(clearEventIndex >= -1 && flushIntervalMs.length > clearEventIndex);
+
         Executor executor = new Executor() {
             @Override
             public void execute(TestSensorManager sensorManager, TestSensorEventListener listener)
                     throws InterruptedException {
                 try {
                     sensorManager.registerListener(listener);
-                    SensorCtsHelper.sleep(duration, timeUnit);
-                    CountDownLatch latch = sensorManager.requestFlush();
-                    listener.waitForFlushComplete(latch);
+
+                    int i = 0;
+                    for (int interval: flushIntervalMs) {
+                        SensorCtsHelper.sleep(interval, TimeUnit.MILLISECONDS);
+                        listener.waitForFlushComplete(
+                                sensorManager.requestFlush(),
+                                i <= clearEventIndex);
+                        ++i;
+                    }
                 } finally {
                     sensorManager.unregisterListener();
                 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
index 1e775e3..4c449dd 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/AbstractSensorVerification.java
@@ -82,4 +82,8 @@
             this.previousEvent = previousEvent;
         }
     }
+
+    protected double nanosToMillis(long nanos) {
+        return nanos/(1000.0 * 1000.0);
+    }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/BatchArrivalVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/BatchArrivalVerification.java
new file mode 100644
index 0000000..db6dc72
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/BatchArrivalVerification.java
@@ -0,0 +1,142 @@
+
+package android.hardware.cts.helpers.sensorverification;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEvent;
+import android.hardware.cts.helpers.sensorverification.AbstractSensorVerification.IndexedEventPair;
+import android.os.SystemClock;
+import android.provider.Settings.System;
+
+import junit.framework.Assert;
+
+/**
+ * A {@link ISensorVerification} which verifies that there are no missing events. This is done by
+ * checking the last received sensor timestamp and checking that it is within 1.8 * the expected
+ * period.
+ */
+public class BatchArrivalVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "missing_event_passed";
+
+    // Batch arrival tolerance is 5 seconds.
+    private static final int BATCH_ARRIVAL_TOLERANCE_US = 5000000;
+
+    // Number of indices to print in assert message before truncating
+    private static final int TRUNCATE_MESSAGE_LENGTH = 3;
+
+    // Number of events to truncate (discard) from the initial events received
+    private static final int TRUNCATE_EVENTS_COUNT = 100;
+
+    private final long mExpectedBatchArrivalTimeUs;
+
+    private final List<IndexedEventPair> mFailures = new LinkedList<IndexedEventPair>();
+    private TestSensorEvent mFirstEvent = null;
+    private int mIndex = 0;
+    private final long mEstimatedTestStartTimeMs;
+
+    /**
+     * Construct a {@link EventGapVerification}
+     *
+     * @param expectedDelayUs the expected period in us.
+     */
+    public BatchArrivalVerification(long expectedBatchArrivalTimeUs) {
+         mExpectedBatchArrivalTimeUs = expectedBatchArrivalTimeUs;
+         mEstimatedTestStartTimeMs = SystemClock.elapsedRealtime();
+    }
+
+    /**
+     * Get the default {@link EventGapVerification}.
+     *
+     * @param environment the test environment
+     * @return the verification or null if the verification is not a continuous mode sensor.
+     */
+    public static BatchArrivalVerification getDefault(TestSensorEnvironment environment) {
+        if (environment.getSensor().getReportingMode() != Sensor.REPORTING_MODE_CONTINUOUS) {
+            return null;
+        }
+        long fifoMaxEventCount = environment.getSensor().getFifoMaxEventCount();
+        int maximumExpectedSamplingPeriodUs = environment.getMaximumExpectedSamplingPeriodUs();
+        long reportLatencyUs = environment.getMaxReportLatencyUs();
+        if (fifoMaxEventCount > 0 && maximumExpectedSamplingPeriodUs != Integer.MAX_VALUE) {
+            long fifoBasedReportLatencyUs =
+                    fifoMaxEventCount * maximumExpectedSamplingPeriodUs;
+            // If the device goes into suspend mode during the test and the sensor under test is
+            // a non wake-up sensor, the FIFO will keep overwriting itself and the reportLatency
+            // of each event will be equal to the time it takes to fill up the FIFO.
+            if (environment.isDeviceSuspendTest() && !environment.getSensor().isWakeUpSensor()) {
+                reportLatencyUs = fifoBasedReportLatencyUs;
+            } else {
+                // In this case the sensor under test is either a wake-up sensor OR it
+                // is a non wake-up sensor but the device does not go into suspend.
+                // So the expected delay of a sensor_event is the minimum of the
+                // fifoBasedReportLatencyUs and the requested latency by the application.
+                reportLatencyUs = Math.min(reportLatencyUs, fifoBasedReportLatencyUs);
+            }
+        }
+        long expectedBatchArrivalTimeUs = reportLatencyUs + SystemClock.elapsedRealtime() * 1000;
+        return new BatchArrivalVerification(expectedBatchArrivalTimeUs);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void verify(TestSensorEnvironment environment, SensorStats stats) {
+        final int count = mFailures.size();
+        stats.addValue(PASSED_KEY, count == 0);
+        stats.addValue(SensorStats.DELAYED_BATCH_DELIVERY, count);
+
+        if (count > 0) {
+            StringBuilder sb = new StringBuilder();
+            sb.append(count).append(" BatchArrivalDelayed: ");
+            for (int i = 0; i < Math.min(count, TRUNCATE_MESSAGE_LENGTH); i++) {
+                IndexedEventPair info = mFailures.get(i);
+                sb.append(String.format("expectedBatchArrival=%dms actualBatchArrivalTime=%dms "+
+                                        "estimedTestStartTime=%dms diff=%dms tolerance=%dms",
+                                         (mExpectedBatchArrivalTimeUs)/1000,
+                                         info.event.receivedTimestamp/(1000 * 1000),
+                                         mEstimatedTestStartTimeMs,
+                                         (mExpectedBatchArrivalTimeUs -
+                                          info.event.receivedTimestamp/1000)/1000,
+                                         BATCH_ARRIVAL_TOLERANCE_US/1000)
+
+                          );
+
+            }
+            if (count > TRUNCATE_MESSAGE_LENGTH) {
+                sb.append(count - TRUNCATE_MESSAGE_LENGTH).append(" more; ");
+            }
+            Assert.fail(sb.toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public BatchArrivalVerification clone() {
+        return new BatchArrivalVerification(mExpectedBatchArrivalTimeUs);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mFirstEvent == null) {
+            mFirstEvent = event;
+        }
+        if (mIndex == 1) {
+            if (Math.abs(mFirstEvent.receivedTimestamp/1000 - mExpectedBatchArrivalTimeUs) >
+                BATCH_ARRIVAL_TOLERANCE_US) {
+                mFailures.add(new IndexedEventPair(1, mFirstEvent, null));
+            }
+        }
+        ++mIndex;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerification.java
new file mode 100644
index 0000000..c27cba1
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerification.java
@@ -0,0 +1,138 @@
+/*
+ * 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.hardware.cts.helpers.sensorverification;
+
+import junit.framework.Assert;
+
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEvent;
+import android.os.SystemClock;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * A {@link ISensorVerification} which verifies if the collected sensor events have any obvious 
+ * problems, such as no sample, wrong sensor type, etc.
+ */
+public class EventBasicVerification extends AbstractSensorVerification {
+
+    public static final String PASSED_KEY = "event_basic_passed";
+    private static final long ALLOWED_SENSOR_DELIVERING_DELAY_US =
+            TimeUnit.MILLISECONDS.toMicros(1000);
+
+    private final long mExpectedMinNumEvent;
+    private final Object mSensor;
+    private long  mNumEvent;
+    private boolean mWrongSensorObserved;
+
+    /**
+     * Constructs an instance of {@link EventBasicVerification}.
+     *
+     * @param maximumSynchronizationErrorNs The valid threshold for timestamp synchronization.
+     * @param reportLatencyNs The latency on which batching events are received
+     */
+    public EventBasicVerification(
+            long expectedMinNumEvent,
+            Sensor sensor) {
+        mExpectedMinNumEvent = expectedMinNumEvent;
+        mSensor = sensor;
+
+        mNumEvent = 0;
+        mWrongSensorObserved = false;
+    }
+
+    /**
+     * Gets a default {@link EventBasicVerification}.
+     *
+     * @param environment The test environment
+     * @return The verification or null if the verification is not supported in the given
+     *         environment.
+     */
+    public static EventBasicVerification getDefault(
+            TestSensorEnvironment environment,
+            long testDurationUs) {
+
+        long minTestDurationUs;
+        long batchUs = environment.getMaxReportLatencyUs();
+        long sampleUs = environment.getExpectedSamplingPeriodUs();
+        if (batchUs > 0) {
+            // test duration deduct allowed delivering latency and portion of time to deliver batch
+            // (which will be 10% of the batching time)
+            long effectiveTime = testDurationUs - ALLOWED_SENSOR_DELIVERING_DELAY_US - batchUs/10;
+
+            // allow part of last batch to be partially delivered (>80%)
+            minTestDurationUs = Math.max(
+                    effectiveTime/batchUs * batchUs - batchUs/5,
+                    environment.getExpectedSamplingPeriodUs());
+        } else {
+            minTestDurationUs =
+                    Math.max(testDurationUs - ALLOWED_SENSOR_DELIVERING_DELAY_US,
+                             environment.getExpectedSamplingPeriodUs());
+        }
+
+        long expectedMinNumEvent = minTestDurationUs / environment.getExpectedSamplingPeriodUs();
+        return new EventBasicVerification(expectedMinNumEvent, environment.getSensor());
+    }
+
+    @Override
+    public void verify(TestSensorEnvironment environment, SensorStats stats) {
+        verify(stats);
+    }
+
+    /* visible to unit test */
+    void verify(SensorStats stats) {
+
+        stats.addValue(SensorStats.EVENT_COUNT_KEY, mNumEvent);
+        stats.addValue(SensorStats.WRONG_SENSOR_KEY, mWrongSensorObserved);
+
+        boolean enoughSample = mNumEvent >= mExpectedMinNumEvent;
+        boolean noWrongSensor = !mWrongSensorObserved;
+
+        boolean success = enoughSample && noWrongSensor;
+        stats.addValue(PASSED_KEY, success);
+
+        if (!success) {
+            Assert.fail(String.format("Failed due to (%s%s)",
+                        enoughSample?"":"insufficient events, ",
+                        noWrongSensor?"":"wrong sensor observed, "));
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public EventBasicVerification clone() {
+        return new EventBasicVerification( mExpectedMinNumEvent, (Sensor)mSensor );
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (event.sensor == mSensor) {
+            ++mNumEvent;
+        } else {
+            mWrongSensorObserved = true;
+        }
+    }
+
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerificationTest.java
new file mode 100644
index 0000000..34be3c4
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventBasicVerificationTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.hardware.cts.helpers.sensorverification;
+
+import junit.framework.TestCase;
+import android.content.Context;
+import android.hardware.Sensor;
+import android.hardware.SensorManager;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEvent;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Tests for {@link EventBasicVerification}.
+ */
+public class EventBasicVerificationTest extends AndroidTestCase {
+
+    /**
+     * Test {@link EventBasicVerification#verify(TestSensorEnvironment, SensorStats)}.
+     */
+    public void testVerify() {
+
+        /* Sensor contents is not used in this verification, use Object as mock */
+        SensorManager mgr = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
+
+        Sensor sensor1 = null;
+
+        // accelerometer is the most likely sensor to exist
+        Sensor sensor2 = mgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
+
+        SensorStats stats;
+
+        EventBasicVerification verification;
+
+        // case 1
+        verification = getVerification(10, sensor1, sensor1, new float[20][3]);
+        stats = new SensorStats();
+
+        verification.verify(stats);
+        assertEquals(true, stats.getValue(EventBasicVerification.PASSED_KEY));
+        assertEquals(20, (long) stats.getValue(SensorStats.EVENT_COUNT_KEY));
+        assertEquals(false, stats.getValue(SensorStats.WRONG_SENSOR_KEY));
+
+        // case 2
+        verification = getVerification(10, sensor1, sensor1, new float[5][3]);
+        stats = new SensorStats();
+
+        try {
+            verification.verify(stats);
+            fail("Expect an AssertionError due to insufficient samples");
+        } catch (AssertionError e) {
+            //Expected
+        }
+        assertEquals(false, stats.getValue(EventBasicVerification.PASSED_KEY));
+        assertEquals(5, (long) stats.getValue(SensorStats.EVENT_COUNT_KEY));
+        assertEquals(false, stats.getValue(SensorStats.WRONG_SENSOR_KEY));
+
+        // case 3
+        if (sensor1 != sensor2) {
+            // if we cannot even get a second sensor then do not bother this test.
+            verification = getVerification(10, sensor1, sensor2, new float[15][3]);
+            stats = new SensorStats();
+
+            try {
+                verification.verify(stats);
+                fail("Expect an AssertionError due to wrong sensor event");
+            } catch (AssertionError e) {
+                //Expected
+            }
+            assertEquals(false, stats.getValue(EventBasicVerification.PASSED_KEY));
+            // zero here because wrong sensor is used.
+            assertEquals(0, (long) stats.getValue(SensorStats.EVENT_COUNT_KEY));
+            assertEquals(true, stats.getValue(SensorStats.WRONG_SENSOR_KEY));
+        }
+    }
+
+    private static EventBasicVerification getVerification(
+            int expectedMinNumEvent, Sensor sensor, Sensor eventSensor, float[] ... values) {
+
+        Collection<TestSensorEvent> events = new ArrayList<>(values.length);
+        for (float[] value : values) {
+            events.add(new TestSensorEvent(eventSensor, 0, 0, value));
+        }
+        EventBasicVerification verification =
+                new EventBasicVerification(expectedMinNumEvent, sensor);
+        verification.addSensorEvents(events);
+        return verification;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
index b692f0f..c64810b 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerification.java
@@ -28,11 +28,16 @@
     // Number of events to truncate (discard) from the initial events received
     private static final int TRUNCATE_EVENTS_COUNT = 1;
 
+    // Number of event gaps to tolerate is 2% of total number of events received rounded up to next
+    // integer or 20, whichever is smaller.
+    private static final int EVENT_GAP_THRESHOLD_MAX = 20;
+    private static final double EVENT_GAP_TOLERANCE = 0.02;
+
     private final int mExpectedDelayUs;
 
     private final List<IndexedEventPair> mEventGaps = new LinkedList<IndexedEventPair>();
     private TestSensorEvent mPreviousEvent = null;
-    private int mIndex = 0;
+    private int mEventCount = 0;
 
     /**
      * Construct a {@link EventGapVerification}
@@ -68,24 +73,28 @@
         }
 
         final int count = mEventGaps.size();
-        stats.addValue(PASSED_KEY, count == 0);
+        // Ensure the threshold is rounded up.
+        double eventGapThreshold =
+                Math.ceil(Math.min(EVENT_GAP_THRESHOLD_MAX, mEventCount * EVENT_GAP_TOLERANCE));
+        boolean pass = count <= eventGapThreshold;
+
+        stats.addValue(PASSED_KEY, pass);
         stats.addValue(SensorStats.EVENT_GAP_COUNT_KEY, count);
         stats.addValue(SensorStats.EVENT_GAP_POSITIONS_KEY, getIndexArray(mEventGaps));
 
-        if (count > 0) {
+        if (!pass) {
             StringBuilder sb = new StringBuilder();
             sb.append(count).append(" events gaps: ");
             for (int i = 0; i < Math.min(count, TRUNCATE_MESSAGE_LENGTH); i++) {
                 IndexedEventPair info = mEventGaps.get(i);
-                sb.append(String.format("position=%d, delta_time=%dns; ", info.index,
-                        info.event.timestamp - info.previousEvent.timestamp));
+                sb.append(String.format("position=%d, delta_time=%.2fms; ", info.index,
+                        nanosToMillis(info.event.timestamp - info.previousEvent.timestamp)));
             }
             if (count > TRUNCATE_MESSAGE_LENGTH) {
                 sb.append(count - TRUNCATE_MESSAGE_LENGTH).append(" more; ");
             }
-            sb.append(String.format("(expected <%dns)",
-                    TimeUnit.NANOSECONDS.convert((int) (THRESHOLD * mExpectedDelayUs),
-                            TimeUnit.MICROSECONDS)));
+            sb.append(String.format("(expected <%.2fms)",
+                    (double)(THRESHOLD * mExpectedDelayUs)/1000.0));
             Assert.fail(sb.toString());
         }
     }
@@ -103,16 +112,16 @@
      */
     @Override
     protected void addSensorEventInternal(TestSensorEvent event) {
-        if (mIndex >= TRUNCATE_EVENTS_COUNT) {
+        if (mEventCount >= TRUNCATE_EVENTS_COUNT) {
             if (mPreviousEvent != null) {
                 long deltaNs = event.timestamp - mPreviousEvent.timestamp;
                 long deltaUs = TimeUnit.MICROSECONDS.convert(deltaNs, TimeUnit.NANOSECONDS);
                 if (deltaUs > mExpectedDelayUs * THRESHOLD) {
-                    mEventGaps.add(new IndexedEventPair(mIndex, event, mPreviousEvent));
+                    mEventGaps.add(new IndexedEventPair(mEventCount, event, mPreviousEvent));
                 }
             }
             mPreviousEvent = event;
         }
-        mIndex++;
+        mEventCount++;
     }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerificationTest.java
index 6f17e7b..687e63b 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerificationTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventGapVerificationTest.java
@@ -62,7 +62,7 @@
     public void testVerify_missing_events() {
         // Timestamps in ns, expected in us
         long[] timestamps = {1000000, 2000000, 3000000, 5000000, 6000000};
-        runVerification(1000, timestamps, false, new int[]{3});
+        runVerification(1000, timestamps, true, new int[]{3});
     }
 
     private void runVerification(int expected, long[] timestamps, boolean pass,
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
index d3b317b..5a176d5 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerification.java
@@ -82,8 +82,9 @@
             sb.append(count).append(" events out of order: ");
             for (int i = 0; i < Math.min(count, TRUNCATE_MESSAGE_LENGTH); i++) {
                 IndexedEventPair info = mOutOfOrderEvents.get(i);
-                sb.append(String.format("position=%d, previous=%d, timestamp=%d; ", info.index,
-                        info.previousEvent.timestamp, info.event.timestamp));
+                sb.append(String.format("position=%d, previous_ts=%.2fms, current_ts=%.2fms",
+                            info.index, nanosToMillis(info.previousEvent.timestamp),
+                            nanosToMillis(info.event.timestamp)));
             }
             if (count > TRUNCATE_MESSAGE_LENGTH) {
                 sb.append(count - TRUNCATE_MESSAGE_LENGTH).append(" more");
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java
index b9848fa..f1dc229c8 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventOrderingVerificationTest.java
@@ -41,16 +41,6 @@
     }
 
     /**
-     * Test that the verification passes when the timestamps are the same.
-     */
-    public void testSameTimestamp() {
-        SensorStats stats = new SensorStats();
-        EventOrderingVerification verification = getVerification(0, 0, 0, 0, 0);
-        verification.verify(stats);
-        verifyStats(stats, true, 0);
-    }
-
-    /**
      * Test that the verification passes when the timestamps are increasing.
      */
     public void testSequentialTimestamp() {
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventTimestampSynchronizationVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventTimestampSynchronizationVerification.java
index 2c1f196..65d6fa5 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventTimestampSynchronizationVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/EventTimestampSynchronizationVerification.java
@@ -38,12 +38,13 @@
     // number of indices to print in assertion message before truncating
     private static final int TRUNCATE_MESSAGE_LENGTH = 3;
 
-    private static final long DEFAULT_THRESHOLD_NS = TimeUnit.MILLISECONDS.toNanos(500);
+    private static final long DEFAULT_THRESHOLD_NS = TimeUnit.MILLISECONDS.toNanos(1000);
+    private static final float ALLOWED_LATENCY_ERROR = 0.1f; //10%
 
     private final ArrayList<TestSensorEvent> mCollectedEvents = new ArrayList<TestSensorEvent>();
 
     private final long mMaximumSynchronizationErrorNs;
-    private final long mReportLatencyNs;
+    private final long mExpectedSyncLatencyNs;
 
     /**
      * Constructs an instance of {@link EventTimestampSynchronizationVerification}.
@@ -53,9 +54,9 @@
      */
     public EventTimestampSynchronizationVerification(
             long maximumSynchronizationErrorNs,
-            long reportLatencyNs) {
+            long expectedSyncLatencyNs) {
         mMaximumSynchronizationErrorNs = maximumSynchronizationErrorNs;
-        mReportLatencyNs = reportLatencyNs;
+        mExpectedSyncLatencyNs = expectedSyncLatencyNs;
     }
 
     /**
@@ -72,10 +73,26 @@
         int maximumExpectedSamplingPeriodUs = environment.getMaximumExpectedSamplingPeriodUs();
         if (fifoMaxEventCount > 0 && maximumExpectedSamplingPeriodUs != Integer.MAX_VALUE) {
             long fifoBasedReportLatencyUs = fifoMaxEventCount * maximumExpectedSamplingPeriodUs;
-            reportLatencyUs = Math.min(reportLatencyUs, fifoBasedReportLatencyUs);
+            // If the device goes into suspend mode and the sensor is a non wake-up sensor, the
+            // FIFO will keep overwriting itself and the reportLatency will be equal to the time
+            // it takes to fill up the FIFO.
+            if (environment.isDeviceSuspendTest() && !environment.getSensor().isWakeUpSensor()) {
+                reportLatencyUs = fifoBasedReportLatencyUs;
+            } else {
+                // In this case the sensor under test is either a wake-up sensor OR it
+                // is a non wake-up sensor but the device does not go into suspend.
+                // So the expected delay of a sensor_event is the minimum of the
+                // fifoBasedReportLatencyUs and the requested latency by the application.
+                reportLatencyUs = Math.min(reportLatencyUs, fifoBasedReportLatencyUs);
+            }
         }
-        long reportLatencyNs = TimeUnit.MICROSECONDS.toNanos(reportLatencyUs);
-        return new EventTimestampSynchronizationVerification(DEFAULT_THRESHOLD_NS, reportLatencyNs);
+        // Add an additional filter delay which is a function of the samplingPeriod.
+        long filterDelayUs = (long)(2.5 * maximumExpectedSamplingPeriodUs);
+
+        long expectedSyncLatencyNs = TimeUnit.MICROSECONDS.toNanos(reportLatencyUs + filterDelayUs);
+        return new EventTimestampSynchronizationVerification(
+                (long) (DEFAULT_THRESHOLD_NS + ALLOWED_LATENCY_ERROR * reportLatencyUs * 1000),
+                expectedSyncLatencyNs);
     }
 
     @Override
@@ -83,7 +100,6 @@
         StringBuilder errorMessageBuilder =
                 new StringBuilder(" event timestamp synchronization failures: ");
         List<IndexedEvent> failures = verifyTimestampSynchronization(errorMessageBuilder);
-
         int failuresCount = failures.size();
         stats.addValue(SensorStats.EVENT_TIME_SYNCHRONIZATION_COUNT_KEY, failuresCount);
         stats.addValue(
@@ -103,7 +119,7 @@
     public EventTimestampSynchronizationVerification clone() {
         return new EventTimestampSynchronizationVerification(
                 mMaximumSynchronizationErrorNs,
-                mReportLatencyNs);
+                mExpectedSyncLatencyNs);
     }
 
     /**
@@ -132,14 +148,17 @@
             long receivedTimestampNs = event.receivedTimestamp;
             long upperThresholdNs = receivedTimestampNs;
             long lowerThresholdNs = receivedTimestampNs - mMaximumSynchronizationErrorNs
-                    - mReportLatencyNs;
+                    - mExpectedSyncLatencyNs;
 
             if (eventTimestampNs < lowerThresholdNs || eventTimestampNs > upperThresholdNs) {
                 if (failures.size() < TRUNCATE_MESSAGE_LENGTH) {
                     builder.append("position=").append(i);
-                    builder.append(", timestamp=").append(eventTimestampNs).append("ns");
-                    builder.append(", expected=[").append(lowerThresholdNs);
-                    builder.append(", ").append(upperThresholdNs).append("]ns; ");
+                    builder.append(", timestamp=").append(String.format("%.2fms",
+                                nanosToMillis(eventTimestampNs)));
+                    builder.append(", expected=[").append(String.format("%.2fms",
+                                nanosToMillis(lowerThresholdNs)));
+                    builder.append(", ").append(String.format("%.2f]ms; ",
+                                nanosToMillis(upperThresholdNs)));
                 }
                 failures.add(new IndexedEvent(i, event));
             }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.java
new file mode 100644
index 0000000..682cd0c
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FifoLengthVerification.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 android.hardware.cts.helpers.sensorverification;
+
+import junit.framework.Assert;
+
+import android.hardware.Sensor;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.hardware.cts.helpers.SensorStats;
+import android.hardware.cts.helpers.TestSensorEnvironment;
+import android.hardware.cts.helpers.TestSensorEvent;
+import android.util.Log;
+
+import java.util.LinkedList;
+
+/**
+ * A {@link ISensorVerification} which verifies that each batch of events has the FIFO
+ *  length within the 5% of the expected value.
+ */
+public class FifoLengthVerification extends AbstractSensorVerification {
+    public static final String PASSED_KEY = "fifo_length_passed";
+
+    private static double FIFO_LENGTH_TOLERANCE = 0.8;
+
+    private final int mExpectedFifoLength;
+
+    private int mIndex = 0;
+    private LinkedList<Long> mRecvdTimeStampDiffs = new LinkedList<>();
+    private long mPrevRecvdTimeStampMs = -1,  mExpectedReportLatencyUs;
+
+    /**
+     * Construct a {@link FifoLengthVerification}
+     *
+     * @param expectedLength the expected FIFO length for the batch.
+     */
+    public FifoLengthVerification(int expectedLength, long expectedReportLatencyUs) {
+        mExpectedFifoLength = expectedLength;
+        mExpectedReportLatencyUs = expectedReportLatencyUs;
+    }
+
+    /**
+     * Get the default {@link FifoLengthVerification}.
+     *
+     * @param environment the test environment
+     * @return the verification or null if the verification is not a continuous mode sensor.
+     */
+    public static FifoLengthVerification getDefault(
+            TestSensorEnvironment environment) {
+        if (environment.getSensor().getReportingMode() != Sensor.REPORTING_MODE_CONTINUOUS) {
+            return null;
+        }
+        long expectedReportLatencyUs = environment.getMaxReportLatencyUs();
+        long fifoReservedEventCount = environment.getSensor().getFifoReservedEventCount();
+        int maximumExpectedSamplingPeriodUs = environment.getMaximumExpectedSamplingPeriodUs();
+        if (fifoReservedEventCount > 0 && maximumExpectedSamplingPeriodUs != Integer.MAX_VALUE) {
+            long fifoBasedReportLatencyUs = fifoReservedEventCount * maximumExpectedSamplingPeriodUs;
+            // If the device goes into suspend mode and the sensor is a non wake-up sensor, the
+            // FIFO will keep overwriting itself and the reportLatency will be equal to the time
+            // it takes to fill up the FIFO.
+            if (environment.isDeviceSuspendTest() && !environment.getSensor().isWakeUpSensor()) {
+                expectedReportLatencyUs = fifoBasedReportLatencyUs;
+            } else {
+                // In this case the sensor under test is either a wake-up sensor OR it
+                // is a non wake-up sensor but the device does not go into suspend.
+                // So the expected delay of a sensor_event is the minimum of the
+                // fifoBasedReportLatencyUs and the requested latency by the application.
+                expectedReportLatencyUs = Math.min(expectedReportLatencyUs,
+                        fifoBasedReportLatencyUs);
+            }
+        }
+
+        return new FifoLengthVerification((int) fifoReservedEventCount, expectedReportLatencyUs);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void verify(TestSensorEnvironment environment, SensorStats stats) {
+        if (mExpectedFifoLength <= 0) {
+            // the expected length isn't defined.
+            stats.addValue(PASSED_KEY, "skipped (no fifo length requirements)");
+            return;
+        }
+        int batchCount = 0;
+        int maxBatchCount = 0;
+        boolean success, endofbatch = false;
+        long maxTsDiff = -1;
+        for (long timestampDiff : mRecvdTimeStampDiffs) {
+            if (maxTsDiff < timestampDiff) maxTsDiff = timestampDiff;
+            // Any event that arrives within before 0.5*expectedReportLatency is considered
+            // to be in the same batch of events, else it is considered as the beginning of a new
+            // batch.
+            if (timestampDiff < mExpectedReportLatencyUs/1000/2) {
+                batchCount++;
+            } else {
+                endofbatch = true;
+                maxBatchCount = (maxBatchCount >= batchCount) ? maxBatchCount : batchCount;
+                batchCount = 0;
+            }
+        }
+        Log.v("SensorFifoLengthVerification", "batchCount =" +batchCount + " mExpected=" +
+                mExpectedFifoLength + " maxTsDiff=" + maxTsDiff + " expectedReportLatency=" +
+                mExpectedReportLatencyUs/1000 + " recvdEventCount=" + mRecvdTimeStampDiffs.size());
+        // Fifo length must be at least 80% of the advertized FIFO length.
+        success = endofbatch && (batchCount >= mExpectedFifoLength * FIFO_LENGTH_TOLERANCE);
+
+        stats.addValue(PASSED_KEY, success);
+        stats.addValue(SensorStats.EVENT_FIFO_LENGTH, batchCount);
+
+        if (!success) {
+            StringBuilder sb = new StringBuilder();
+            if (endofbatch) {
+                sb.append(String.format("Fifo length verification error: Fifo length found=%d," +
+                            "expected fifo length ~%d, maxReportLatencyObserved=%dms, " +
+                            "expectedMaxReportLantency=%dms",
+                            batchCount, mExpectedFifoLength, maxTsDiff,
+                            mExpectedReportLatencyUs/1000));
+            } else {
+               sb.append(String.format("End of batch NOT observed maxReportLatencyObserved=%dms,"
+                            + " expectedMaxReportLantency=%dms", maxTsDiff,
+                            mExpectedReportLatencyUs/1000));
+            }
+            Assert.fail(sb.toString());
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public FifoLengthVerification clone() {
+        return new FifoLengthVerification(mExpectedFifoLength, mExpectedReportLatencyUs);
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void addSensorEventInternal(TestSensorEvent event) {
+        if (mPrevRecvdTimeStampMs == -1) {
+            mPrevRecvdTimeStampMs = (long)event.receivedTimestamp/(1000 * 1000);
+        } else {
+            long currRecvdTimeStampMs = (long) event.receivedTimestamp/(1000 * 1000);
+            mRecvdTimeStampDiffs.add(currRecvdTimeStampMs - mPrevRecvdTimeStampMs);
+            mPrevRecvdTimeStampMs = currRecvdTimeStampMs;
+        }
+        mIndex++;
+    }
+}
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
index cf34f28..2f4777b 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/FrequencyVerification.java
@@ -128,9 +128,9 @@
         stats.addValue(SensorStats.FREQUENCY_KEY, measuredFrequencyHz);
         stats.addValue(PASSED_KEY, !failed);
         String resultString = String.format(
-                "Requested \"%s\" at %.2fHz (expecting between %.2fHz and %.2fHz, measured %.2fHz)",
+                "Requested \"%s\" at %s (expecting between %.2fHz and %.2fHz, measured %.2fHz)",
                 environment.getSensor().getName(),
-                environment.getFrequencyHz(),
+                environment.getFrequencyString(),
                 mLowerThresholdHz,
                 mUpperThresholdHz,
                 measuredFrequencyHz);
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 f95ea0b..9d36f37 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
@@ -16,8 +16,10 @@
 
 package android.hardware.cts.helpers.sensorverification;
 
-import junit.framework.Assert;
+import android.content.Context;
+import android.content.pm.PackageManager;
 
+import android.util.Log;
 import android.hardware.Sensor;
 import android.hardware.cts.helpers.SensorCtsHelper;
 import android.hardware.cts.helpers.SensorStats;
@@ -25,9 +27,12 @@
 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;
+import junit.framework.Assert;
 
 /**
  * A {@link ISensorVerification} which verifies that the sensor jitter is in an acceptable range.
@@ -37,12 +42,22 @@
 
     // sensorType: threshold (% of expected period)
     private static final SparseIntArray DEFAULTS = new SparseIntArray(12);
+    // Max allowed jitter in +/- sense (in percentage).
+    private static final int GRACE_FACTOR = 2;
+    private static final int THRESHOLD_PERCENT_FOR_HIFI_SENSORS = 1 * GRACE_FACTOR;
+
+    // Margin sample intervals that considered outliers, lower and higher margin is discarded
+    // before verification
+    private static final float OUTLIER_MARGIN = 0.025f; //2.5%
+
     static {
         // Use a method so that the @deprecation warning can be set for that method only
         setDefaults();
     }
 
-    private final int mThresholdAsPercentage;
+    private final float     mOutlierMargin;
+    private final long      mThresholdNs;
+    private final long      mExpectedPeriodNs; // for error message only
     private final List<Long> mTimestamps = new LinkedList<Long>();
 
     /**
@@ -50,8 +65,10 @@
      *
      * @param thresholdAsPercentage the acceptable margin of error as a percentage
      */
-    public JitterVerification(int thresholdAsPercentage) {
-        mThresholdAsPercentage = thresholdAsPercentage;
+    public JitterVerification(float outlierMargin, long thresholdNs, long expectedPeriodNs) {
+        mExpectedPeriodNs = expectedPeriodNs;
+        mOutlierMargin = outlierMargin;
+        mThresholdNs = thresholdNs;
     }
 
     /**
@@ -62,11 +79,20 @@
      */
     public static JitterVerification getDefault(TestSensorEnvironment environment) {
         int sensorType = environment.getSensor().getType();
-        int threshold = DEFAULTS.get(sensorType, -1);
-        if (threshold == -1) {
+
+        int thresholdPercent = DEFAULTS.get(sensorType, -1);
+        if (thresholdPercent == -1) {
             return null;
         }
-        return new JitterVerification(threshold);
+        boolean hasHifiSensors = environment.getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_HIFI_SENSORS);
+        if (hasHifiSensors) {
+           thresholdPercent = THRESHOLD_PERCENT_FOR_HIFI_SENSORS;
+        }
+
+        long expectedPeriodNs = (long) environment.getExpectedSamplingPeriodUs() * 1000;
+        long jitterThresholdNs = expectedPeriodNs * thresholdPercent * 2 / 100; // *2 is for +/-
+        return new JitterVerification(OUTLIER_MARGIN, jitterThresholdNs, expectedPeriodNs);
     }
 
     /**
@@ -85,24 +111,33 @@
             return;
         }
 
-        List<Double> jitters = getJitterValues();
-        double jitter95PercentileNs = SensorCtsHelper.get95PercentileValue(jitters);
-        long firstTimestamp = mTimestamps.get(0);
-        long lastTimestamp = mTimestamps.get(timestampsCount - 1);
-        long measuredPeriodNs = (lastTimestamp - firstTimestamp) / (timestampsCount - 1);
-        double jitter95PercentilePercent = (jitter95PercentileNs * 100.0) / measuredPeriodNs;
-        stats.addValue(SensorStats.JITTER_95_PERCENTILE_PERCENT_KEY, jitter95PercentilePercent);
+        List<Long> deltas = getDeltaValues();
+        float percentiles[] = new float[2];
+        percentiles[0] = mOutlierMargin;
+        percentiles[1] = 1 - percentiles[0];
 
-        boolean success = (jitter95PercentilePercent < mThresholdAsPercentage);
+        List<Long> percentileValues = SensorCtsHelper.getPercentileValue(deltas, percentiles);
+        double normalizedRange =
+                (double)(percentileValues.get(1) - percentileValues.get(0)) / mThresholdNs;
+
+        double percentageJitter =
+                (double)(percentileValues.get(1) - percentileValues.get(0)) /
+                        mExpectedPeriodNs / 2 * 100; //one side variation comparing to sample time
+
+        stats.addValue(SensorStats.JITTER_95_PERCENTILE_PERCENT_KEY, percentageJitter);
+
+        boolean success = normalizedRange <= 1.0;
         stats.addValue(PASSED_KEY, success);
 
         if (!success) {
             String message = String.format(
-                    "Jitter out of range: measured period=%dns, jitter(95th percentile)=%.2f%%"
-                            + " (expected < %d%%)",
-                    measuredPeriodNs,
-                    jitter95PercentilePercent,
-                    mThresholdAsPercentage);
+                    "Jitter out of range: requested period = %dns, " +
+                    "jitter min, max, range (95th percentile) = (%dns, %dns, %dns), " +
+                    "jitter expected range <= %dns",
+                    mExpectedPeriodNs,
+                    percentileValues.get(0), percentileValues.get(1),
+                    percentileValues.get(1) - percentileValues.get(0),
+                    mThresholdNs);
             Assert.fail(message);
         }
     }
@@ -112,7 +147,7 @@
      */
     @Override
     public JitterVerification clone() {
-        return new JitterVerification(mThresholdAsPercentage);
+        return new JitterVerification(mOutlierMargin, mThresholdNs, mExpectedPeriodNs);
     }
 
     /**
@@ -124,19 +159,14 @@
     }
 
     /**
-     * Get the list of all jitter values. Exposed for unit testing.
+     * Get the list of delta values. Exposed for unit testing.
      */
-    List<Double> getJitterValues() {
+    List<Long> getDeltaValues() {
         List<Long> deltas = new ArrayList<Long>(mTimestamps.size() - 1);
         for (int i = 1; i < mTimestamps.size(); i++) {
             deltas.add(mTimestamps.get(i) - mTimestamps.get(i - 1));
         }
-        double deltaMean = SensorCtsHelper.getMean(deltas);
-        List<Double> jitters = new ArrayList<Double>(deltas.size());
-        for (long delta : deltas) {
-            jitters.add(Math.abs(delta - deltaMean));
-        }
-        return jitters;
+        return deltas;
     }
 
     @SuppressWarnings("deprecation")
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java
index 50e288c..d8e1586 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/JitterVerificationTest.java
@@ -27,11 +27,10 @@
 import java.util.List;
 
 /**
- * Tests for {@link EventOrderingVerification}.
+ * Tests for {@link JitterVerification}.
  */
 public class JitterVerificationTest extends TestCase {
 
-
     public void testVerify() {
         final int SAMPLE_SIZE = 100;
         // for unit testing the verification, only the parameter 'sensorMightHaveMoreListeners' is
@@ -67,54 +66,58 @@
         } catch (AssertionError e) {
             // Expected;
         }
-        verifyStats(stats, false, 47.34);
+        verifyStats(stats, false, 25); // 500 us range (250 us in single-sided sense)
+                                       // divide by 1ms requested sample time x 100%
     }
 
-    public void testCalculateJitter() {
+    public void testCalculateDelta() {
         long[] timestamps = new long[]{0, 1, 2, 3, 4};
         JitterVerification verification = getVerification(1, timestamps);
-        List<Double> jitterValues = verification.getJitterValues();
-        assertEquals(4, jitterValues.size());
-        assertEquals(0.0, jitterValues.get(0));
-        assertEquals(0.0, jitterValues.get(1));
-        assertEquals(0.0, jitterValues.get(2));
-        assertEquals(0.0, jitterValues.get(3));
+        List<Long> deltaValues = verification.getDeltaValues();
+        assertEquals(4, deltaValues.size());
+        assertEquals(1, deltaValues.get(0).longValue());
+        assertEquals(1, deltaValues.get(1).longValue());
+        assertEquals(1, deltaValues.get(2).longValue());
+        assertEquals(1, deltaValues.get(3).longValue());
 
         timestamps = new long[]{0, 0, 2, 4, 4};
         verification = getVerification(1, timestamps);
-        jitterValues = verification.getJitterValues();
-        assertEquals(4, jitterValues.size());
-        assertEquals(1.0, jitterValues.get(0));
-        assertEquals(1.0, jitterValues.get(1));
-        assertEquals(1.0, jitterValues.get(2));
-        assertEquals(1.0, jitterValues.get(3));
+        deltaValues = verification.getDeltaValues();
+        assertEquals(4, deltaValues.size());
+        assertEquals(0, deltaValues.get(0).longValue());
+        assertEquals(2, deltaValues.get(1).longValue());
+        assertEquals(2, deltaValues.get(2).longValue());
+        assertEquals(0, deltaValues.get(3).longValue());
 
         timestamps = new long[]{0, 1, 4, 9, 16};
         verification = getVerification(1, timestamps);
-        jitterValues = verification.getJitterValues();
-        assertEquals(4, jitterValues.size());
-        assertEquals(4, jitterValues.size());
-        assertEquals(3.0, jitterValues.get(0));
-        assertEquals(1.0, jitterValues.get(1));
-        assertEquals(1.0, jitterValues.get(2));
-        assertEquals(3.0, jitterValues.get(3));
+        deltaValues = verification.getDeltaValues();
+        assertEquals(4, deltaValues.size());
+        assertEquals(1, deltaValues.get(0).longValue());
+        assertEquals(3, deltaValues.get(1).longValue());
+        assertEquals(5, deltaValues.get(2).longValue());
+        assertEquals(7, deltaValues.get(3).longValue());
     }
 
-    private static JitterVerification getVerification(int threshold, long ... timestamps) {
+    private static JitterVerification getVerification(int marginPercent, long ... timestamps) {
         Collection<TestSensorEvent> events = new ArrayList<>(timestamps.length);
         for (long timestamp : timestamps) {
             events.add(new TestSensorEvent(null, timestamp, 0, null));
         }
-        JitterVerification verification = new JitterVerification(threshold);
+        long samplePeriodNs = 1000*1000; //1000Hz
+        long jitterThresholdNs = 20*1000; // 2% of that
+
+        JitterVerification verification =
+                new JitterVerification(marginPercent/100.0f, jitterThresholdNs, samplePeriodNs);
         verification.addSensorEvents(events);
         return verification;
     }
 
-    private void verifyStats(SensorStats stats, boolean passed, double jitter95) {
+    private void verifyStats(SensorStats stats, boolean passed, double percentageJitter) {
         assertEquals(passed, stats.getValue(JitterVerification.PASSED_KEY));
         assertEquals(
-                jitter95,
+                percentageJitter,
                 (Double) stats.getValue(SensorStats.JITTER_95_PERCENTILE_PERCENT_KEY),
-                0.1);
+                0.01);
     }
 }
diff --git a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
index f7c2c53..1b66e6a 100644
--- a/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
+++ b/tests/tests/hardware/src/android/hardware/cts/helpers/sensorverification/StandardDeviationVerification.java
@@ -18,11 +18,16 @@
 
 import junit.framework.Assert;
 
+import android.content.Context;
+import android.content.pm.PackageManager;
 import android.hardware.Sensor;
 import android.hardware.cts.helpers.SensorStats;
 import android.hardware.cts.helpers.TestSensorEnvironment;
 import android.hardware.cts.helpers.TestSensorEvent;
+import android.hardware.cts.helpers.SensorCtsHelper;
+import android.util.Log;
 
+import java.util.concurrent.TimeUnit;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -63,10 +68,51 @@
      */
     public static StandardDeviationVerification getDefault(TestSensorEnvironment environment) {
         int sensorType = environment.getSensor().getType();
+        float graceFactorAccelGyro = 2.0f;
+        float graceFactorMagPressure = 4.0f;
+        float currOperatingFreq = (float) environment.getFrequencyHz();
+        float maxBandWidth = (float)SensorCtsHelper.getFrequency(
+                environment.getSensor().getMinDelay(), TimeUnit.MICROSECONDS);
+        float minBandWidth = (float) SensorCtsHelper.getFrequency(
+                environment.getSensor().getMaxDelay(), TimeUnit.MICROSECONDS);
+
+        if (Float.isInfinite(currOperatingFreq)) {
+            currOperatingFreq = maxBandWidth;
+        }
+
+        if (currOperatingFreq > maxBandWidth && !Float.isInfinite(maxBandWidth)) {
+            currOperatingFreq = maxBandWidth;
+        }
+
+        if (currOperatingFreq < minBandWidth && !Float.isInfinite(minBandWidth)) {
+            currOperatingFreq = minBandWidth;
+        }
+
+        float mAccelNoise = (float)(graceFactorAccelGyro * Math.sqrt(currOperatingFreq) *
+                (9.81 * 0.0004));
+        float mGyroNoise = (float)(graceFactorAccelGyro * Math.sqrt(currOperatingFreq) *
+                (Math.PI/180.0 * 0.014));
+        float mMagNoise = (float)((graceFactorMagPressure) * 0.5); // Allow extra grace for mag
+        float mPressureNoise = (float)(graceFactorMagPressure * 0.02 *
+                (float)Math.sqrt(currOperatingFreq)); // Allow extra grace for pressure
+
         if (!DEFAULTS.containsKey(sensorType)) {
             return null;
         }
+        boolean hasHifiSensors = environment.getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_HIFI_SENSORS);
 
+        if (hasHifiSensors) {
+
+            DEFAULTS.put(Sensor.TYPE_ACCELEROMETER, new float[]{mAccelNoise, mAccelNoise, mAccelNoise});
+            // Max gyro deviation: 0.014°/s/√Hz
+            DEFAULTS.put(Sensor.TYPE_GYROSCOPE,
+                    new float[]{mGyroNoise, mGyroNoise, mGyroNoise});
+            // Max magnetometer deviation: 0.1uT/√Hz
+            DEFAULTS.put(Sensor.TYPE_MAGNETIC_FIELD, new float[]{mMagNoise, mMagNoise, mMagNoise});
+            // Max pressure deviation: 2Pa/√Hz
+            DEFAULTS.put(Sensor.TYPE_PRESSURE, new float[]{mPressureNoise,mPressureNoise,mPressureNoise});
+        }
         return new StandardDeviationVerification(DEFAULTS.get(sensorType));
     }
 
@@ -107,9 +153,9 @@
             if (stdDevs[i] > mThreshold[i]) {
                 failed = true;
             }
-            stddevSb.append(String.format("%.2f", stdDevs[i]));
+            stddevSb.append(String.format("%.6f", stdDevs[i]));
             if (i != stdDevs.length - 1) stddevSb.append(", ");
-            expectedSb.append(String.format("<%.2f", mThreshold[i]));
+            expectedSb.append(String.format("<%.6f", mThreshold[i]));
             if (i != stdDevs.length - 1) expectedSb.append(", ");
         }
         if (stdDevs.length > 1) {
diff --git a/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java b/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java
new file mode 100644
index 0000000..95704b9
--- /dev/null
+++ b/tests/tests/hardware/src/android/hardware/fingerprint/cts/FingerprintManagerTest.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.fingerprint.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.fingerprint.FingerprintManager;
+import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
+import android.os.CancellationSignal;
+import android.test.AndroidTestCase;
+
+/**
+ * Basic test cases for FingerprintManager
+ */
+public class FingerprintManagerTest extends AndroidTestCase {
+    private enum AuthState {
+        AUTH_UNKNOWN, AUTH_ERROR, AUTH_FAILED, AUTH_SUCCEEDED
+    }
+    private AuthState mAuthState = AuthState.AUTH_UNKNOWN;
+    private FingerprintManager mFingerprintManager;
+
+    boolean mHasFingerprintManager;
+    private AuthenticationCallback mAuthCallback = new AuthenticationCallback() {
+
+        @Override
+        public void onAuthenticationError(int errorCode, CharSequence errString) {
+        }
+
+        @Override
+        public void onAuthenticationFailed() {
+            mAuthState = AuthState.AUTH_SUCCEEDED;
+        }
+
+        @Override
+        public void onAuthenticationSucceeded(
+                android.hardware.fingerprint.FingerprintManager.AuthenticationResult result) {
+            mAuthState = AuthState.AUTH_SUCCEEDED;
+        }
+    };
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        mAuthState = AuthState.AUTH_UNKNOWN;
+
+        PackageManager pm = getContext().getPackageManager();
+        if (pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+            mHasFingerprintManager = true;
+            mFingerprintManager = (FingerprintManager)
+                    getContext().getSystemService(Context.FINGERPRINT_SERVICE);
+        }
+    }
+
+    public void test_hasFingerprintHardware() {
+        if (!mHasFingerprintManager) {
+            return; // skip test if no fingerprint feature
+        }
+        assertTrue(mFingerprintManager.isHardwareDetected());
+    }
+
+    public void test_hasEnrolledFingerprints() {
+        if (!mHasFingerprintManager) {
+            return; // skip test if no fingerprint feature
+        }
+        boolean hasEnrolledFingerprints = mFingerprintManager.hasEnrolledFingerprints();
+        assertTrue(!hasEnrolledFingerprints);
+    }
+
+    public void test_authenticateNullCallback() {
+        if (!mHasFingerprintManager) {
+            return; // skip test if no fingerprint feature
+        }
+        boolean exceptionTaken = false;
+        CancellationSignal cancelAuth = new CancellationSignal();
+        try {
+            mFingerprintManager.authenticate(null, cancelAuth, 0, null, null);
+        } catch (IllegalArgumentException e) {
+            exceptionTaken = true;
+        } finally {
+            assertTrue(mAuthState == AuthState.AUTH_UNKNOWN);
+            assertTrue(exceptionTaken);
+            cancelAuth.cancel();
+        }
+    }
+
+    public void test_authenticate() {
+        if (!mHasFingerprintManager) {
+            return; // skip test if no fingerprint feature
+        }
+        boolean exceptionTaken = false;
+        CancellationSignal cancelAuth = new CancellationSignal();
+        try {
+            mFingerprintManager.authenticate(null, cancelAuth, 0, mAuthCallback, null);
+        } catch (IllegalArgumentException e) {
+            exceptionTaken = true;
+        } finally {
+            assertFalse(exceptionTaken);
+            // We should never get out of this state without user interaction
+            assertTrue(mAuthState == AuthState.AUTH_UNKNOWN);
+            cancelAuth.cancel();
+        }
+    }
+}
diff --git a/tests/tests/keystore/Android.mk b/tests/tests/keystore/Android.mk
index 0f2cd03..e51bc04 100644
--- a/tests/tests/keystore/Android.mk
+++ b/tests/tests/keystore/Android.mk
@@ -16,7 +16,7 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner core-tests-support
 
@@ -26,6 +26,8 @@
 
 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/assets/nist_cavp_aes_kat.zip b/tests/tests/keystore/assets/nist_cavp_aes_kat.zip
new file mode 100644
index 0000000..90083c8
--- /dev/null
+++ b/tests/tests/keystore/assets/nist_cavp_aes_kat.zip
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key1_cert.der b/tests/tests/keystore/res/raw/ec_key1_cert.der
new file mode 100644
index 0000000..77293bb
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key1_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key1_pkcs8.der b/tests/tests/keystore/res/raw/ec_key1_pkcs8.der
new file mode 100644
index 0000000..0400ad6
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key1_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key2_cert.der b/tests/tests/keystore/res/raw/ec_key2_cert.der
new file mode 100644
index 0000000..576d8f9
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key2_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key2_pkcs8.der b/tests/tests/keystore/res/raw/ec_key2_pkcs8.der
new file mode 100644
index 0000000..26f4f05
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key2_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key3_secp224r1_cert.der b/tests/tests/keystore/res/raw/ec_key3_secp224r1_cert.der
new file mode 100644
index 0000000..454edb3
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key3_secp224r1_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key3_secp224r1_pkcs8.der b/tests/tests/keystore/res/raw/ec_key3_secp224r1_pkcs8.der
new file mode 100644
index 0000000..2b89ca3
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key3_secp224r1_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key4_secp256r1_cert.der b/tests/tests/keystore/res/raw/ec_key4_secp256r1_cert.der
new file mode 100644
index 0000000..1641a65
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key4_secp256r1_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key4_secp256r1_pkcs8.der b/tests/tests/keystore/res/raw/ec_key4_secp256r1_pkcs8.der
new file mode 100644
index 0000000..2631a6e
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key4_secp256r1_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key5_secp384r1_cert.der b/tests/tests/keystore/res/raw/ec_key5_secp384r1_cert.der
new file mode 100644
index 0000000..cf19be8
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key5_secp384r1_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key5_secp384r1_pkcs8.der b/tests/tests/keystore/res/raw/ec_key5_secp384r1_pkcs8.der
new file mode 100644
index 0000000..f864258
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key5_secp384r1_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key6_secp521r1_cert.der b/tests/tests/keystore/res/raw/ec_key6_secp521r1_cert.der
new file mode 100644
index 0000000..cc5d973
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key6_secp521r1_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/ec_key6_secp521r1_pkcs8.der b/tests/tests/keystore/res/raw/ec_key6_secp521r1_pkcs8.der
new file mode 100644
index 0000000..d21815f
--- /dev/null
+++ b/tests/tests/keystore/res/raw/ec_key6_secp521r1_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key1_cert.der b/tests/tests/keystore/res/raw/rsa_key1_cert.der
new file mode 100644
index 0000000..09e5a30
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key1_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key1_pkcs8.der b/tests/tests/keystore/res/raw/rsa_key1_pkcs8.der
new file mode 100644
index 0000000..b398ab1
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key1_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key2_cert.der b/tests/tests/keystore/res/raw/rsa_key2_cert.der
new file mode 100644
index 0000000..b00495c
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key2_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key2_pkcs8.der b/tests/tests/keystore/res/raw/rsa_key2_pkcs8.der
new file mode 100644
index 0000000..c687f7d
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key2_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key3_1024_cert.der b/tests/tests/keystore/res/raw/rsa_key3_1024_cert.der
new file mode 100644
index 0000000..36f6820
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key3_1024_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key3_1024_pkcs8.der b/tests/tests/keystore/res/raw/rsa_key3_1024_pkcs8.der
new file mode 100644
index 0000000..3b70b0d
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key3_1024_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key4_4096_cert.der b/tests/tests/keystore/res/raw/rsa_key4_4096_cert.der
new file mode 100644
index 0000000..24d9a52
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key4_4096_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key4_4096_pkcs8.der b/tests/tests/keystore/res/raw/rsa_key4_4096_pkcs8.der
new file mode 100644
index 0000000..d3d08ca
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key4_4096_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key5_512_cert.der b/tests/tests/keystore/res/raw/rsa_key5_512_cert.der
new file mode 100644
index 0000000..56079dc
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key5_512_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key5_512_pkcs8.der b/tests/tests/keystore/res/raw/rsa_key5_512_pkcs8.der
new file mode 100644
index 0000000..8f723d3
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key5_512_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key6_768_cert.der b/tests/tests/keystore/res/raw/rsa_key6_768_cert.der
new file mode 100644
index 0000000..8afc59b
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key6_768_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key6_768_pkcs8.der b/tests/tests/keystore/res/raw/rsa_key6_768_pkcs8.der
new file mode 100644
index 0000000..7d25fe7
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key6_768_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key7_3072_cert.der b/tests/tests/keystore/res/raw/rsa_key7_3072_cert.der
new file mode 100644
index 0000000..414c35d
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key7_3072_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key7_3072_pksc8.der b/tests/tests/keystore/res/raw/rsa_key7_3072_pksc8.der
new file mode 100644
index 0000000..32788d2
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key7_3072_pksc8.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key8_2048_cert.der b/tests/tests/keystore/res/raw/rsa_key8_2048_cert.der
new file mode 100644
index 0000000..bbbd81b
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key8_2048_cert.der
Binary files differ
diff --git a/tests/tests/keystore/res/raw/rsa_key8_2048_pkcs8.der b/tests/tests/keystore/res/raw/rsa_key8_2048_pkcs8.der
new file mode 100644
index 0000000..94211ad
--- /dev/null
+++ b/tests/tests/keystore/res/raw/rsa_key8_2048_pkcs8.der
Binary files differ
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128CBCNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128CBCNoPaddingCipherTest.java
new file mode 100644
index 0000000..e56049c
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128CBCNoPaddingCipherTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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;
+
+public class AES128CBCNoPaddingCipherTest extends AESCBCNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode("7E3D723C09A9852B24F584F9D916F6A8");
+    private static final byte[] KAT_IV = HexEncoding.decode("944AE274D983892EADE422274858A96A");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "044E15899A080AADEB6778F64323B64D2CBCBADB338DF93B9AC459D4F41029809FFF37081C22EF278F896A"
+            + "B213A2A631");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "B419293FCBD686F2913D1CF947E510D42FAFEDE5593C98AFD6AEE272596A56FE42C22F2A5E3B6A02BA9D8D"
+            + "0DE1E9A810");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128CBCPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128CBCPKCS7PaddingCipherTest.java
new file mode 100644
index 0000000..d8254c1
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128CBCPKCS7PaddingCipherTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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;
+
+public class AES128CBCPKCS7PaddingCipherTest extends AESCBCPKCS7PaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode("F16E698472578E919D92806262C5169F");
+    private static final byte[] KAT_IV = HexEncoding.decode("EF743540F8421ACA128A3247521F3E7D");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "5BEBF33569D90BF5E853814E12E7C7AA5758013F755773E29F4A25EC26EEB765F7F2DC251F7DC62AEFCA1E"
+            + "8A5A11A1DCD44F0BD8FB593A5AE3");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "3197CF6DB9466188B5FED375329324EE7D6092A8C0E41DFAF49E3724271427896D56A6243C0D59D6639722"
+            + "AF93CD53449BDDABF9C5F153EBDBFED9ED98C8CC37");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128CTRNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128CTRNoPaddingCipherTest.java
new file mode 100644
index 0000000..7ffca13
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128CTRNoPaddingCipherTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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;
+
+public class AES128CTRNoPaddingCipherTest extends AESCTRNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode("4713a7b2f93efe809b42ecc45213ef9f");
+    private static final byte[] KAT_IV = HexEncoding.decode("ebfa19b0ebf3d57feabd4c4bd04bea01");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "6d2c07e1fc86f99c6e2a8f6567828b4262a9c23d0f3ed8ab32482283c79796f0adba1bcd3736084996452a"
+            +"917fae98005aebe61f9e91c3");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "345deb1d67b95e600e05cad4c32ec381aadb3e2c1ec7e0fb956dc38e6860cf0553535566e1b12fa9f87d29"
+            + "266ca26df427233df035df28");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128ECBNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128ECBNoPaddingCipherTest.java
new file mode 100644
index 0000000..100700c
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128ECBNoPaddingCipherTest.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.keystore.cts;
+
+public class AES128ECBNoPaddingCipherTest extends AESECBNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode("7DA2467F068854B3CB36E5C333A16619");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "9A07C9575AD9CE209DF9F3953965CEBE8208587C7AE575A1904BF25048946D7B6168A9A27BCE554BEA94EF"
+            + "26E6C742A0");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "8C47E49420FC92AC4CA2C601BC3F8AC31D01B260B7B849F2B8EEDFFFED8F36C31CBDA0D22F95C9C2A48C34"
+            + "7E8C77AC82");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return null;
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128ECBPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128ECBPKCS7PaddingCipherTest.java
new file mode 100644
index 0000000..c834ddf
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128ECBPKCS7PaddingCipherTest.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.keystore.cts;
+
+public class AES128ECBPKCS7PaddingCipherTest extends AESECBPKCS7PaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode("C3BE04BCCB3D99B85290F113FE7AF194");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "348C213FD8DF3F990C20C5ACBF07B34B6264AE245784A5A6176DBFB1C2E7DD27E52CC92B8EEE40614F05B5"
+            + "07B355F6354A2705BD86");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "07CD05C41FEDEDDC5DB4B3E35E676153184A119AA4DFDDC290616F1FA600931DE6BEA9BDB90D1D73389994"
+            + "6F8C8E5C0C4383F99F5D88E27F3EBC0C6E52759ED3");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return null;
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES128GCMNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES128GCMNoPaddingCipherTest.java
new file mode 100644
index 0000000..ed9c2b1
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES128GCMNoPaddingCipherTest.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 android.keystore.cts;
+
+public class AES128GCMNoPaddingCipherTest extends AESGCMNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode("ba76354f0aed6e8d91f45c4ff5a062db");
+    private static final byte[] KAT_IV = HexEncoding.decode("b79437ae08ff355d7d8a4d0f");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "6d7596a8fd56ceaec61de7940984b7736fec44f572afc3c8952e4dc6541e2bc6a702c440a37610989543f6"
+            + "3fedb047ca2173bc18581944");
+    private static final byte[] KAT_CIPHERTEXT_WITHOUT_AAD = HexEncoding.decode(
+            "b3f6799e8f9326f2df1e80fcd2cb16d78c9dc7cc14bb677862dc6c639b3a6338d24b312d3989e5920b5dbf"
+            + "c976765efbfe57bb385940a7a43bdf05bddae3c9d6a2fbbdfcc0cba0");
+    private static final byte[] KAT_AAD = HexEncoding.decode(
+            "d3bc7458914f45d56d5fcfbb2eeff2dcc0e620c1229d90904e98930ea71aa43b6898f846f3244d");
+    private static final byte[] KAT_CIPHERTEXT_WITH_AAD = HexEncoding.decode(
+            "b3f6799e8f9326f2df1e80fcd2cb16d78c9dc7cc14bb677862dc6c639b3a6338d24b312d3989e5920b5dbf"
+            + "c976765efbfe57bb385940a70c106264d81506f8daf9cd6a1c70988c");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT_WITHOUT_AAD.clone();
+    }
+
+    @Override
+    protected byte[] getKatAad() {
+        return KAT_AAD.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertextWhenKatAadPresent() {
+        return KAT_CIPHERTEXT_WITH_AAD.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192CBCNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192CBCNoPaddingCipherTest.java
new file mode 100644
index 0000000..f49c7c3
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192CBCNoPaddingCipherTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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;
+
+public class AES192CBCNoPaddingCipherTest extends AESCBCNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "be8cc4e25cce46e5d55725e2391f7d3cf59ed60062f5a43b");
+    private static final byte[] KAT_IV = HexEncoding.decode("80a199aab0eee77e7762ddf3b3a32f40");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "064f9200e0df37d4711af4a69d11addf9e1c345d9d8195f9f1f715019ce96a167f2497c994bd496eb80bfb"
+            + "2ba2c9d5af");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "859b90becaa85e95a71e104efbd7a3b723bcbf4eb39865544a05d9e90b6fe572c134552f3a138e726fbe49"
+            + "3b3a839598");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192CBCPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192CBCPKCS7PaddingCipherTest.java
new file mode 100644
index 0000000..b17befc
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192CBCPKCS7PaddingCipherTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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;
+
+public class AES192CBCPKCS7PaddingCipherTest extends AESCBCPKCS7PaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "68969215ec41e4df7d23de0e806f458f52aff492bd7c5263");
+    private static final byte[] KAT_IV = HexEncoding.decode("e61d13dfbf0533289f0e7950209da418");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "8d4c1cac27511ee2d82409a7f378e7e402b0eb189c1eaa5c506eb72a9074b170");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "e70bcd62c595dc1b2b8c197bb91a7447e1be2cbcf3fdc69e7e991faf0f57cf4e3884138ff403a41fd99818"
+            + "708ada301c");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192CTRNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192CTRNoPaddingCipherTest.java
new file mode 100644
index 0000000..d4a4143
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192CTRNoPaddingCipherTest.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.keystore.cts;
+
+public class AES192CTRNoPaddingCipherTest extends AESCTRNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "5e2036e790d38815c90beb67a1c9e5aa0e167ef082927317");
+    private static final byte[] KAT_IV = HexEncoding.decode("df0694959b89054156962d68a226965c");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "6ed2781c99e03e45314d6019932220c2c98130c53f9f67ad10ac519adf50e928091e09cdbbd3b42b");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "e427b6666502e05b82d0b20ae50e862b1936d71266fc49178ac984e71571f22ae0f90f0c19f42b4a");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192ECBNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192ECBNoPaddingCipherTest.java
new file mode 100644
index 0000000..0557d03
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192ECBNoPaddingCipherTest.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.keystore.cts;
+
+public class AES192ECBNoPaddingCipherTest extends AESECBNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "3cab83fb338ba985fbfe74c5e9d2e900adb570b1d67faf92");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "2cc64c335a13fb838f3c6aad0a6b47297ca90bb886ddb059200f0b41740c44ab");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "9c5c825328f5ee0aa24947e374d3f9165f484b39dd808c790d7a129648102453");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return null;
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192ECBPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192ECBPKCS7PaddingCipherTest.java
new file mode 100644
index 0000000..1cf193c
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192ECBPKCS7PaddingCipherTest.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.keystore.cts;
+
+public class AES192ECBPKCS7PaddingCipherTest extends AESECBPKCS7PaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "d57f4e5446f736c16476ec4db5decc7b1bf3936e4f7e4618");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "b115777f1ee7a43a07daa6401e59c46b7a98213a8747eabfbe3ca4ec93524de2c7");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "1e92cd20da08bb5fa174a7a69879d4fc25a155e6af06d75b26c5b450d273c8bb7e3a889dd4a9589098b44a"
+            + "cf1056e7aa");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return null;
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES192GCMNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES192GCMNoPaddingCipherTest.java
new file mode 100644
index 0000000..66b37d3
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES192GCMNoPaddingCipherTest.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 android.keystore.cts;
+
+public class AES192GCMNoPaddingCipherTest extends AESGCMNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "21339fc1d011abca65d50ce2365230603fd47d07e8830f6e");
+    private static final byte[] KAT_IV = HexEncoding.decode("d5fb1469a8d81dd75286a418");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "cf776dedf53a828d51a0073db3ef0dd1ee19e2e9e243ce97e95841bb9ad4e3ff52");
+    private static final byte[] KAT_CIPHERTEXT_WITHOUT_AAD = HexEncoding.decode(
+            "3a0d48278111d3296bc663df8a5dbeb2474ea47fd85b608f8d9375d9dcf7de1413ad70fb0e1970669095ad"
+            + "77ebb5974ae8");
+    private static final byte[] KAT_AAD = HexEncoding.decode(
+            "04cdc1d840c17dcfccf78b3d792463740ce0bfdc167b98a632e144cafe9663");
+    private static final byte[] KAT_CIPHERTEXT_WITH_AAD = HexEncoding.decode(
+            "3a0d48278111d3296bc663df8a5dbeb2474ea47fd85b608f8d9375d9dcf7de141380718b9f6c023fb091c7"
+            + "6891a91683e2");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT_WITHOUT_AAD.clone();
+    }
+
+    @Override
+    protected byte[] getKatAad() {
+        return KAT_AAD.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertextWhenKatAadPresent() {
+        return KAT_CIPHERTEXT_WITH_AAD.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256CBCNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256CBCNoPaddingCipherTest.java
new file mode 100644
index 0000000..b6620ef
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256CBCNoPaddingCipherTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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;
+
+public class AES256CBCNoPaddingCipherTest extends AESCBCNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "dd2f20dc6b98c100bac919120ff95eb5d96003f8229987b283a1e777b0cd5c30");
+    private static final byte[] KAT_IV = HexEncoding.decode("23b4d85239fb90db93b07a981e90a170");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "2fbe5d46dca5cea433e550d8b291740ab9551c2a2d37680d7fb7b993225f58494cb53caca353e4b637ba05"
+            + "687be20f8d");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "5aba24fc316936c8369061ee8fe463e4faed04288e204456626b988c0e376b6047da1e4fd7c4e1cf265609"
+            + "7f75ae8685");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256CBCPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256CBCPKCS7PaddingCipherTest.java
new file mode 100644
index 0000000..6613463
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256CBCPKCS7PaddingCipherTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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;
+
+public class AES256CBCPKCS7PaddingCipherTest extends AESCBCPKCS7PaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "03ab2510520f5cfebfab0a17a7f8324c9634911f6fc59e586f85346bb38ac88a");
+    private static final byte[] KAT_IV = HexEncoding.decode("9af96967195bb0184f129beffa8241ae");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "2d6944653ac14988a772a2730b7c5bfa99a21732ae26f40cdc5b3a2874c7942545a82b73c48078b9dae622"
+            + "61c65909");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "26b308f7e1668b55705a79c8b3ad10e244655f705f027f390a5c34e4536f519403a71987b95124073d69f2"
+            + "a3cb95b0ab");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256CTRNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256CTRNoPaddingCipherTest.java
new file mode 100644
index 0000000..bdcff41
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256CTRNoPaddingCipherTest.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.keystore.cts;
+
+public class AES256CTRNoPaddingCipherTest extends AESCTRNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "928b380a8fed4b4b4cfeb56e0c66a4cb0f9ff58d61ac68bcfd0e3fbd910a684f");
+    private static final byte[] KAT_IV = HexEncoding.decode("0b678a5249e6eeda461dfb4776b6c58e");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "f358de57543b297e997cba46fb9100553d6abd65377e55b9aac3006400ead11f6db3c884");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "a07a35fbd1776ad81462e1935f542337add60962bf289249476817b6ddd532a7be30d4c3");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256ECBNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256ECBNoPaddingCipherTest.java
new file mode 100644
index 0000000..847a767
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256ECBNoPaddingCipherTest.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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;
+
+public class AES256ECBNoPaddingCipherTest extends AESECBNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "fa4622d9cf6485075daedd33d2c4fffdf859e2edb7f7df4f04603f7e647fae90");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "96ccabbe0c68970d8cdee2b30ab43c2d61cc50ee68271e77571e72478d713a31a476d6806b8116089c6ec5"
+            + "0bb543200f");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "0e81839e9dfbfe3b503d619e676abe5ac80fac3f245d8f09b9134b1b32a67dc83e377faf246288931136be"
+            + "f2a07c0be4");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return null;
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256ECBPKCS7PaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256ECBPKCS7PaddingCipherTest.java
new file mode 100644
index 0000000..0faffe9
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256ECBPKCS7PaddingCipherTest.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.keystore.cts;
+
+public class AES256ECBPKCS7PaddingCipherTest extends AESECBPKCS7PaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "bf3f07c68467fead0ca8e2754500ab514258abf02eb7e615a493bcaaa45d5ee1");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "af0757e49018dad628f16998628a407db5f28291bef3bc2e4d8a5a31fb238e6f");
+    private static final byte[] KAT_CIPHERTEXT = HexEncoding.decode(
+            "21ec3011074bf1ef140643d47130326c5e183f61237c69bc77551ca207d71fc2b90cfac6c8d2d125e5cd9f"
+            + "f353dee0df");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return null;
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AES256GCMNoPaddingCipherTest.java b/tests/tests/keystore/src/android/keystore/cts/AES256GCMNoPaddingCipherTest.java
new file mode 100644
index 0000000..971e610
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AES256GCMNoPaddingCipherTest.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 android.keystore.cts;
+
+public class AES256GCMNoPaddingCipherTest extends AESGCMNoPaddingCipherTestBase {
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "7972140d831eedac75d5ea515c9a4c3bb124499a90b5f317ac1a685e88fae395");
+    private static final byte[] KAT_IV = HexEncoding.decode("a66c5252808d823dd4151fed");
+    private static final byte[] KAT_PLAINTEXT = HexEncoding.decode(
+            "c2b9dabf3a55adaa94e8c0d1e77a84a3435aee23b2c3c4abb587b09a9c2afbf0");
+    private static final byte[] KAT_CIPHERTEXT_WITHOUT_AAD = HexEncoding.decode(
+            "a960619314657b2afb96b93bebb372bffd09e19d53e351f17d1ba2611f9dc33c9c92d563e8fd381254ac26"
+            + "2aa2a4ea0d");
+    private static final byte[] KAT_AAD = HexEncoding.decode(
+            "3727229db7a3ccda7283f628fb8a3cdf093ea1f4e8bd1bc40a830fc6df6fb0e249845dd7d449b2bc3b5ba4"
+            + "2258fb92c7");
+    private static final byte[] KAT_CIPHERTEXT_WITH_AAD = HexEncoding.decode(
+            "a960619314657b2afb96b93bebb372bffd09e19d53e351f17d1ba2611f9dc33c1501caa6cca0a281f42bc3"
+            + "10d1e4488f");
+
+    @Override
+    protected byte[] getKatKey() {
+        return KAT_KEY.clone();
+    }
+
+    @Override
+    protected byte[] getKatIv() {
+        return KAT_IV.clone();
+    }
+
+    @Override
+    protected byte[] getKatPlaintext() {
+        return KAT_PLAINTEXT.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertext() {
+        return KAT_CIPHERTEXT_WITHOUT_AAD.clone();
+    }
+
+    @Override
+    protected byte[] getKatAad() {
+        return KAT_AAD.clone();
+    }
+
+    @Override
+    protected byte[] getKatCiphertextWhenKatAadPresent() {
+        return KAT_CIPHERTEXT_WITH_AAD.clone();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESCBCCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESCBCCipherTestBase.java
new file mode 100644
index 0000000..8f1aed69
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESCBCCipherTestBase.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 android.keystore.cts;
+
+import java.security.AlgorithmParameters;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import javax.crypto.spec.IvParameterSpec;
+
+abstract class AESCBCCipherTestBase extends BlockCipherTestBase {
+
+    @Override
+    protected boolean isStreamCipher() {
+        return false;
+    }
+
+    @Override
+    protected boolean isAuthenticatedCipher() {
+        return false;
+    }
+
+    @Override
+    protected int getKatAuthenticationTagLengthBytes() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected int getBlockSize() {
+        return 16;
+    }
+
+    @Override
+    protected AlgorithmParameterSpec getKatAlgorithmParameterSpec() {
+        return new IvParameterSpec(getKatIv());
+    }
+
+    @Override
+    protected byte[] getIv(AlgorithmParameters params) throws InvalidParameterSpecException {
+        IvParameterSpec spec = params.getParameterSpec(IvParameterSpec.class);
+        return spec.getIV();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESCBCNoPaddingCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESCBCNoPaddingCipherTestBase.java
new file mode 100644
index 0000000..8e51d04
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESCBCNoPaddingCipherTestBase.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.keystore.cts;
+
+abstract class AESCBCNoPaddingCipherTestBase extends AESCBCCipherTestBase {
+
+    @Override
+    protected String getTransformation() {
+        return "AES/CBC/NoPadding";
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESCBCPKS7PaddingCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESCBCPKS7PaddingCipherTestBase.java
new file mode 100644
index 0000000..bd2c5bd
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESCBCPKS7PaddingCipherTestBase.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.keystore.cts;
+
+abstract class AESCBCPKCS7PaddingCipherTestBase extends AESCBCCipherTestBase {
+
+    @Override
+    protected String getTransformation() {
+        return "AES/CBC/PKCS7Padding";
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESCTRCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESCTRCipherTestBase.java
new file mode 100644
index 0000000..8bf6ac1
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESCTRCipherTestBase.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 android.keystore.cts;
+
+import java.security.AlgorithmParameters;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import javax.crypto.spec.IvParameterSpec;
+
+abstract class AESCTRCipherTestBase extends BlockCipherTestBase {
+
+    @Override
+    protected boolean isStreamCipher() {
+        return true;
+    }
+
+    @Override
+    protected boolean isAuthenticatedCipher() {
+        return false;
+    }
+
+    @Override
+    protected int getKatAuthenticationTagLengthBytes() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected int getBlockSize() {
+        return 16;
+    }
+
+    @Override
+    protected AlgorithmParameterSpec getKatAlgorithmParameterSpec() {
+        return new IvParameterSpec(getKatIv());
+    }
+
+    @Override
+    protected byte[] getIv(AlgorithmParameters params) throws InvalidParameterSpecException {
+        IvParameterSpec spec = params.getParameterSpec(IvParameterSpec.class);
+        return spec.getIV();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESCTRNoPaddingCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESCTRNoPaddingCipherTestBase.java
new file mode 100644
index 0000000..e504310
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESCTRNoPaddingCipherTestBase.java
@@ -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.
+ */
+
+package android.keystore.cts;
+
+abstract class AESCTRNoPaddingCipherTestBase extends AESCTRCipherTestBase {
+    @Override
+    protected String getTransformation() {
+        return "AES/CTR/NoPadding";
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESCipherNistCavpKatTest.java b/tests/tests/keystore/src/android/keystore/cts/AESCipherNistCavpKatTest.java
new file mode 100644
index 0000000..1f6ebd7
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESCipherNistCavpKatTest.java
@@ -0,0 +1,324 @@
+/*
+ * 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.keystore.cts;
+
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.test.AndroidTestCase;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.security.KeyStore;
+import java.util.Arrays;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class AESCipherNistCavpKatTest extends AndroidTestCase {
+
+    public void testECBVarKey128() throws Exception {
+        runTestsForKatFile("ECBVarKey128.rsp");
+    }
+
+    public void testECBVarKey192() throws Exception {
+        runTestsForKatFile("ECBVarKey192.rsp");
+    }
+    public void testECBVarKey256() throws Exception {
+        runTestsForKatFile("ECBVarKey256.rsp");
+    }
+
+    public void testECBVarTxt128() throws Exception {
+        runTestsForKatFile("ECBVarTxt128.rsp");
+    }
+
+    public void testECBVarTxt192() throws Exception {
+        runTestsForKatFile("ECBVarTxt192.rsp");
+    }
+
+    public void testECBVarTxt256() throws Exception {
+        runTestsForKatFile("ECBVarTxt256.rsp");
+    }
+
+    public void testECBGFSbox128() throws Exception {
+        runTestsForKatFile("ECBGFSbox128.rsp");
+    }
+
+    public void testECBGFSbox192() throws Exception {
+        runTestsForKatFile("ECBGFSbox192.rsp");
+    }
+
+    public void testECBGFSbox256() throws Exception {
+        runTestsForKatFile("ECBGFSbox256.rsp");
+    }
+
+    public void testECBKeySbox128() throws Exception {
+        runTestsForKatFile("ECBKeySbox128.rsp");
+    }
+
+    public void testECBKeySbox192() throws Exception {
+        runTestsForKatFile("ECBKeySbox192.rsp");
+    }
+
+    public void testECBKeySbox256() throws Exception {
+        runTestsForKatFile("ECBKeySbox256.rsp");
+    }
+
+    public void testCBCVarKey128() throws Exception {
+        runTestsForKatFile("CBCVarKey128.rsp");
+    }
+
+    public void testCBCVarKey192() throws Exception {
+        runTestsForKatFile("CBCVarKey192.rsp");
+    }
+    public void testCBCVarKey256() throws Exception {
+        runTestsForKatFile("CBCVarKey256.rsp");
+    }
+
+    public void testCBCVarTxt128() throws Exception {
+        runTestsForKatFile("CBCVarTxt128.rsp");
+    }
+
+    public void testCBCVarTxt192() throws Exception {
+        runTestsForKatFile("CBCVarTxt192.rsp");
+    }
+
+    public void testCBCVarTxt256() throws Exception {
+        runTestsForKatFile("CBCVarTxt256.rsp");
+    }
+
+    public void testCBCGFSbox128() throws Exception {
+        runTestsForKatFile("CBCGFSbox128.rsp");
+    }
+
+    public void testCBCGFSbox192() throws Exception {
+        runTestsForKatFile("CBCGFSbox192.rsp");
+    }
+
+    public void testCBCGFSbox256() throws Exception {
+        runTestsForKatFile("CBCGFSbox256.rsp");
+    }
+
+    public void testCBCKeySbox128() throws Exception {
+        runTestsForKatFile("CBCKeySbox128.rsp");
+    }
+
+    public void testCBCKeySbox192() throws Exception {
+        runTestsForKatFile("CBCKeySbox192.rsp");
+    }
+
+    public void testCBCKeySbox256() throws Exception {
+        runTestsForKatFile("CBCKeySbox256.rsp");
+    }
+
+    private void runTestsForKatFile(String fileName) throws Exception {
+        try (ZipInputStream zipIn = new ZipInputStream(
+                getContext().getResources().getAssets().open("nist_cavp_aes_kat.zip"))) {
+            ZipEntry zipEntry;
+            byte[] entryContents = null;
+            while ((zipEntry = zipIn.getNextEntry()) != null) {
+                String entryName = zipEntry.getName();
+
+                // We have to read the contents of all entries because there's no way to skip an
+                // entry without reading its contents.
+                entryContents = new byte[(int) zipEntry.getSize()];
+                readFully(zipIn, entryContents);
+
+                if (fileName.equals(entryName)) {
+                    break;
+                }
+            }
+
+            if (entryContents == null) {
+                fail(fileName + " not found");
+                return;
+            }
+
+            String blockMode = fileName.substring(0, 3);
+            if ("CFB".equals(blockMode)) {
+                blockMode = fileName.substring(0, 4);
+            }
+            runTestsForKatFile(blockMode, entryContents);
+        }
+    }
+
+    private void runTestsForKatFile(String blockMode, byte[] fileContents) throws Exception {
+        BufferedReader in = null;
+        int testNumber = 0;
+        try {
+            in = new BufferedReader(new InputStreamReader(
+                    new ByteArrayInputStream(fileContents), "ISO-8859-1"));
+            String line;
+            int lineNumber = 0;
+            String section = null; // ENCRYPT or DECRYPT
+
+            boolean insideTestDefinition = false;
+            TestVector testVector = null;
+
+            while ((line = in.readLine()) != null) {
+                lineNumber++;
+                line = line.trim();
+                if (line.startsWith("#")) {
+                    // Ignore comment lines
+                    continue;
+                }
+
+                if (!insideTestDefinition) {
+                    // Outside of a test definition
+                    if (line.length() == 0) {
+                        // Ignore empty lines
+                        continue;
+                    }
+                    if ((line.startsWith("[")) && (line.endsWith("]"))) {
+                        section = line.substring(1, line.length() - 1);
+                        if ((!"DECRYPT".equals(section)) && (!"ENCRYPT".equals(section))) {
+                            throw new IOException(lineNumber + ": Unexpected section: " + section);
+                        }
+                        continue;
+                    }
+
+                    // Check whether this is a NAME = VALUE line
+                    int delimiterIndex = line.indexOf('=');
+                    if (delimiterIndex == -1) {
+                        throw new IOException(lineNumber + ": Unexpected line outside of test"
+                                + " definition: " + line);
+                    }
+                    String name = line.substring(0, delimiterIndex).trim();
+                    String value = line.substring(delimiterIndex + 1).trim();
+
+                    if ("COUNT".equals(name)) {
+                        testNumber = Integer.parseInt(value);
+                        insideTestDefinition = true;
+                        testVector = new TestVector();
+                    } else {
+                        throw new IOException(lineNumber + ": Unexpected line outside of test"
+                                + " definition: " + line);
+                    }
+                } else {
+                    // Inside of a test definition
+                    if (line.length() == 0) {
+                        // End of test definition
+                        boolean encrypt;
+                        if ("ENCRYPT".equals(section)) {
+                            encrypt = true;
+                        } else if ("DECRYPT".equals(section)) {
+                            encrypt = false;
+                        } else {
+                            throw new IOException("Unexpected test operation: " + section);
+                        }
+                        runKatTest(blockMode, encrypt, testVector);
+                        insideTestDefinition = false;
+                        testVector = null;
+                    } else {
+                        // Check whether this is a NAME = VALUE line
+                        int delimiterIndex = line.indexOf('=');
+                        if (delimiterIndex == -1) {
+                            throw new IOException(lineNumber + ": Unexpected line inside test"
+                                    + " definition: " + line);
+                        }
+                        String name = line.substring(0, delimiterIndex).trim();
+                        String value = line.substring(delimiterIndex + 1).trim();
+
+                        if ("KEY".equals(name)) {
+                            testVector.key = HexEncoding.decode(value);
+                        } else if ("IV".equals(name)) {
+                            testVector.iv = HexEncoding.decode(value);
+                        } else if ("PLAINTEXT".equals(name)) {
+                            testVector.plaintext = HexEncoding.decode(value);
+                        } else if ("CIPHERTEXT".equals(name)) {
+                            testVector.ciphertext = HexEncoding.decode(value);
+                        } else {
+                            throw new IOException(lineNumber + ": Unexpected line inside test"
+                                    + " definition: " + line);
+                        }
+                    }
+                }
+            }
+        } catch (Throwable e) {
+            throw new RuntimeException("Test #" + testNumber + " failed", e);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (Exception ignored) {}
+            }
+        }
+    }
+
+    private void runKatTest(String mode, boolean encrypt, TestVector testVector) throws Exception {
+        String keyAlias = AESCipherNistCavpKatTest.class.getName();
+        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+        keyStore.load(null);
+        keyStore.setEntry(keyAlias,
+                new KeyStore.SecretKeyEntry(new SecretKeySpec(testVector.key, "AES")),
+                new KeyProtection.Builder(
+                        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                        .setBlockModes(mode)
+                        .setEncryptionPaddings("NoPadding")
+                        .setRandomizedEncryptionRequired(false)
+                        .build());
+        try {
+            SecretKey key = (SecretKey) keyStore.getKey(keyAlias, null);
+            assertNotNull(key);
+            Cipher cipher = Cipher.getInstance("AES/" + mode + "/NoPadding");
+
+            int opmode = (encrypt) ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
+            if (testVector.iv != null) {
+                cipher.init(opmode, key, new IvParameterSpec(testVector.iv));
+            } else {
+                cipher.init(opmode, key);
+            }
+
+            byte[] input = (encrypt) ? testVector.plaintext : testVector.ciphertext;
+            byte[] actualOutput = cipher.doFinal(input);
+            byte[] expectedOutput = (encrypt) ? testVector.ciphertext : testVector.plaintext;
+            if (!Arrays.equals(expectedOutput, actualOutput)) {
+                fail("Expected: " + HexEncoding.encode(expectedOutput)
+                        + ", actual: " + HexEncoding.encode(actualOutput));
+            }
+        } finally {
+            keyStore.deleteEntry(keyAlias);
+        }
+    }
+
+    private static void readFully(InputStream in, byte[] buf) throws IOException {
+        int offset = 0;
+        int remaining = buf.length;
+        while (remaining > 0) {
+            int chunkSize = in.read(buf, offset, remaining);
+            if (chunkSize == -1) {
+                throw new EOFException("Premature EOF. Remaining: " + remaining);
+            }
+            offset += chunkSize;
+            remaining -= chunkSize;
+        }
+    }
+
+    private static class TestVector {
+        public byte[] key;
+        public byte[] iv;
+        public byte[] plaintext;
+        public byte[] ciphertext;
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESECBCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESECBCipherTestBase.java
new file mode 100644
index 0000000..b2752dc
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESECBCipherTestBase.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.keystore.cts;
+
+import java.security.AlgorithmParameters;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+abstract class AESECBCipherTestBase extends BlockCipherTestBase {
+
+    @Override
+    protected boolean isStreamCipher() {
+        return false;
+    }
+
+    @Override
+    protected boolean isAuthenticatedCipher() {
+        return false;
+    }
+
+    @Override
+    protected int getKatAuthenticationTagLengthBytes() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    protected int getBlockSize() {
+        return 16;
+    }
+
+    @Override
+    protected AlgorithmParameterSpec getKatAlgorithmParameterSpec() {
+        return null;
+    }
+
+    @Override
+    protected byte[] getIv(AlgorithmParameters params) throws InvalidParameterSpecException {
+        if (params != null) {
+            fail("ECB does not use IV");
+        }
+        return null;
+    }
+
+    public void testInitRejectsIvParameterSpec() throws Exception {
+        assertInitRejectsIvParameterSpec(new byte[getBlockSize()]);
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESECBNoPaddingCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESECBNoPaddingCipherTestBase.java
new file mode 100644
index 0000000..8c38015
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESECBNoPaddingCipherTestBase.java
@@ -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.
+ */
+
+package android.keystore.cts;
+
+abstract class AESECBNoPaddingCipherTestBase extends AESECBCipherTestBase {
+    @Override
+    protected String getTransformation() {
+        return "AES/ECB/NoPadding";
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESECBPKCS7PaddingCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESECBPKCS7PaddingCipherTestBase.java
new file mode 100644
index 0000000..67e659c
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESECBPKCS7PaddingCipherTestBase.java
@@ -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.
+ */
+
+package android.keystore.cts;
+
+abstract class AESECBPKCS7PaddingCipherTestBase extends AESECBCipherTestBase {
+    @Override
+    protected String getTransformation() {
+        return "AES/ECB/PKCS7Padding";
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESGCMCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESGCMCipherTestBase.java
new file mode 100644
index 0000000..1c3404a
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESGCMCipherTestBase.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 java.nio.ByteBuffer;
+import java.security.AlgorithmParameters;
+import java.security.Key;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+
+import javax.crypto.AEADBadTagException;
+import javax.crypto.Cipher;
+import javax.crypto.spec.GCMParameterSpec;
+
+abstract class AESGCMCipherTestBase extends BlockCipherTestBase {
+
+    protected abstract byte[] getKatAad();
+    protected abstract byte[] getKatCiphertextWhenKatAadPresent();
+
+    @Override
+    protected boolean isStreamCipher() {
+        return true;
+    }
+
+    @Override
+    protected boolean isAuthenticatedCipher() {
+        return true;
+    }
+
+    @Override
+    protected int getKatAuthenticationTagLengthBytes() {
+        return getKatCiphertext().length - getKatPlaintext().length;
+    }
+
+    @Override
+    protected int getBlockSize() {
+        return 16;
+    }
+
+    @Override
+    protected AlgorithmParameterSpec getKatAlgorithmParameterSpec() {
+        return new GCMParameterSpec(getKatAuthenticationTagLengthBytes() * 8, getKatIv());
+    }
+
+    @Override
+    protected byte[] getIv(AlgorithmParameters params) throws InvalidParameterSpecException {
+        GCMParameterSpec spec = params.getParameterSpec(GCMParameterSpec.class);
+        return spec.getIV();
+    }
+
+    public void testKatEncryptWithAadProvidedInOneGo() throws Exception {
+        createCipher();
+        assertKatTransformWithAadProvidedInOneGo(
+                Cipher.ENCRYPT_MODE,
+                getKatAad(),
+                getKatPlaintext(),
+                getKatCiphertextWhenKatAadPresent());
+    }
+
+    public void testKatDecryptWithAadProvidedInOneGo() throws Exception {
+        createCipher();
+        assertKatTransformWithAadProvidedInOneGo(
+                Cipher.DECRYPT_MODE,
+                getKatAad(),
+                getKatCiphertextWhenKatAadPresent(),
+                getKatPlaintext());
+    }
+
+    public void testKatEncryptWithAadProvidedInChunks() throws Exception {
+        createCipher();
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.ENCRYPT_MODE,
+                getKatAad(),
+                getKatPlaintext(),
+                getKatCiphertextWhenKatAadPresent(),
+                1);
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.ENCRYPT_MODE,
+                getKatAad(),
+                getKatPlaintext(),
+                getKatCiphertextWhenKatAadPresent(),
+                8);
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.ENCRYPT_MODE,
+                getKatAad(),
+                getKatPlaintext(),
+                getKatCiphertextWhenKatAadPresent(),
+                3);
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.ENCRYPT_MODE,
+                getKatAad(),
+                getKatPlaintext(),
+                getKatCiphertextWhenKatAadPresent(),
+                7);
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.ENCRYPT_MODE,
+                getKatAad(),
+                getKatPlaintext(),
+                getKatCiphertextWhenKatAadPresent(),
+                23);
+    }
+
+    public void testKatDecryptWithAadProvidedInChunks() throws Exception {
+        createCipher();
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.DECRYPT_MODE,
+                getKatAad(),
+                getKatCiphertextWhenKatAadPresent(),
+                getKatPlaintext(),
+                1);
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.DECRYPT_MODE,
+                getKatAad(),
+                getKatCiphertextWhenKatAadPresent(),
+                getKatPlaintext(),
+                8);
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.DECRYPT_MODE,
+                getKatAad(),
+                getKatCiphertextWhenKatAadPresent(),
+                getKatPlaintext(),
+                3);
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.DECRYPT_MODE,
+                getKatAad(),
+                getKatCiphertextWhenKatAadPresent(),
+                getKatPlaintext(),
+                7);
+        assertKatTransformWithAadProvidedInChunks(
+                Cipher.DECRYPT_MODE,
+                getKatAad(),
+                getKatCiphertextWhenKatAadPresent(),
+                getKatPlaintext(),
+                23);
+    }
+
+    private void assertKatTransformWithAadProvidedInOneGo(int opmode,
+            byte[] aad, byte[] input, byte[] expectedOutput) throws Exception {
+        initKat(opmode);
+        updateAAD(aad);
+        assertEquals(expectedOutput, doFinal(input));
+
+        initKat(opmode);
+        updateAAD(aad, 0, aad.length);
+        assertEquals(expectedOutput, doFinal(input));
+
+        initKat(opmode);
+        updateAAD(ByteBuffer.wrap(aad));
+        assertEquals(expectedOutput, doFinal(input));
+    }
+
+    private void assertKatTransformWithAadProvidedInChunks(int opmode,
+            byte[] aad, byte[] input, byte[] expectedOutput, int maxChunkSize) throws Exception {
+        createCipher();
+        initKat(opmode);
+        int aadOffset = 0;
+        while (aadOffset < aad.length) {
+            int chunkSize = Math.min(aad.length - aadOffset, maxChunkSize);
+            updateAAD(aad, aadOffset, chunkSize);
+            aadOffset += chunkSize;
+        }
+        assertEquals(expectedOutput, doFinal(input));
+    }
+
+    public void testCiphertextBitflipDetectedWhenDecrypting() throws Exception {
+        createCipher();
+        Key key = importKey(getKatKey());
+        byte[] ciphertext = getKatCiphertext();
+        ciphertext[ciphertext.length / 2] ^= 0x40;
+        init(Cipher.DECRYPT_MODE, key, getKatAlgorithmParameterSpec());
+        try {
+            doFinal(ciphertext);
+            fail();
+        } catch (AEADBadTagException expected) {}
+    }
+
+    public void testAadBitflipDetectedWhenDecrypting() throws Exception {
+        createCipher();
+        Key key = importKey(getKatKey());
+        byte[] ciphertext = getKatCiphertextWhenKatAadPresent();
+        byte[] aad = getKatCiphertext();
+        aad[aad.length / 3] ^= 0x2;
+        init(Cipher.DECRYPT_MODE, key, getKatAlgorithmParameterSpec());
+        updateAAD(aad);
+        try {
+            doFinal(ciphertext);
+            fail();
+        } catch (AEADBadTagException expected) {}
+    }
+
+    public void testInitRejectsIvParameterSpec() throws Exception {
+        assertInitRejectsIvParameterSpec(getKatIv());
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AESGCMNoPaddingCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/AESGCMNoPaddingCipherTestBase.java
new file mode 100644
index 0000000..c29e644
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/AESGCMNoPaddingCipherTestBase.java
@@ -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.
+ */
+
+package android.keystore.cts;
+
+abstract class AESGCMNoPaddingCipherTestBase extends AESGCMCipherTestBase {
+    @Override
+    protected String getTransformation() {
+        return "AES/GCM/NoPadding";
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyPairGeneratorTest.java
deleted file mode 100644
index 284ac83..0000000
--- a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyPairGeneratorTest.java
+++ /dev/null
@@ -1,574 +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 android.keystore.cts;
-
-import android.security.KeyPairGeneratorSpec;
-import android.test.AndroidTestCase;
-
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.net.Socket;
-import java.security.KeyPair;
-import java.security.KeyPairGenerator;
-import java.security.KeyStore;
-import java.security.Principal;
-import java.security.PrivateKey;
-import java.security.PublicKey;
-import java.security.SecureRandom;
-import java.security.cert.Certificate;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.DSAParams;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPublicKey;
-import java.security.spec.AlgorithmParameterSpec;
-import java.security.spec.DSAParameterSpec;
-import java.security.spec.RSAKeyGenParameterSpec;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-
-import javax.net.ssl.KeyManager;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509ExtendedKeyManager;
-import javax.security.auth.x500.X500Principal;
-
-import libcore.java.security.TestKeyStore;
-import libcore.javax.net.ssl.TestKeyManager;
-import libcore.javax.net.ssl.TestSSLContext;
-
-public class AndroidKeyPairGeneratorTest extends AndroidTestCase {
-    private KeyPairGenerator mGenerator;
-
-    private KeyStore mKeyStore;
-
-    private static final String TEST_ALIAS_1 = "test1";
-
-    private static final String TEST_ALIAS_2 = "test2";
-
-    private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
-
-    private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");
-
-    private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;
-
-    private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);
-
-    private static final long NOW_MILLIS = System.currentTimeMillis();
-
-    /* We have to round this off because X509v3 doesn't store milliseconds. */
-    private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
-
-    @SuppressWarnings("deprecation")
-    private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
-
-    @Override
-    protected void setUp() throws Exception {
-        mKeyStore = KeyStore.getInstance("AndroidKeyStore");
-        mKeyStore.load(null, null);
-
-        mGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
-    }
-
-    public void testKeyPairGenerator_Initialize_Params_Unencrypted_Success() throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-    }
-
-    public void testKeyPairGenerator_Initialize_KeySize_Unencrypted_Failure() throws Exception {
-        try {
-            mGenerator.initialize(1024);
-            fail("KeyPairGenerator should not support setting the key size");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testKeyPairGenerator_Initialize_KeySizeAndSecureRandom_Unencrypted_Failure()
-            throws Exception {
-        try {
-            mGenerator.initialize(1024, new SecureRandom());
-            fail("KeyPairGenerator should not support setting the key size");
-        } catch (IllegalArgumentException success) {
-        }
-    }
-
-    public void testKeyPairGenerator_Initialize_ParamsAndSecureRandom_Unencrypted_Failure()
-            throws Exception {
-        mGenerator.initialize(
-                new KeyPairGeneratorSpec.Builder(getContext())
-                        .setAlias(TEST_ALIAS_1)
-                        .setSubject(TEST_DN_1)
-                        .setSerialNumber(TEST_SERIAL_1)
-                        .setStartDate(NOW)
-                        .setEndDate(NOW_PLUS_10_YEARS)
-                        .build(),
-                new SecureRandom());
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_DSA_Unencrypted_Success() throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("DSA")
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 1024, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_DSA_2048_Unencrypted_Success()
-            throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("DSA")
-                .setKeySize(2048)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_DSA_SpecifiedParams_Unencrypted_Success()
-            throws Exception {
-        /*
-         * generated using: openssl dsaparam -C 2048
-         */
-        BigInteger p = new BigInteger(1, new byte[] {
-                (byte) 0xC0, (byte) 0x3D, (byte) 0x86, (byte) 0x09, (byte) 0xCA, (byte) 0x8C,
-                (byte) 0x37, (byte) 0xCA, (byte) 0xCC, (byte) 0x4A, (byte) 0x81, (byte) 0xBD,
-                (byte) 0xD8, (byte) 0x50, (byte) 0x77, (byte) 0xCD, (byte) 0xDD, (byte) 0x32,
-                (byte) 0x0B, (byte) 0x43, (byte) 0xBF, (byte) 0x42, (byte) 0x06, (byte) 0x5A,
-                (byte) 0x3D, (byte) 0x18, (byte) 0x50, (byte) 0x47, (byte) 0x79, (byte) 0xE1,
-                (byte) 0x5B, (byte) 0x86, (byte) 0x03, (byte) 0xB9, (byte) 0x28, (byte) 0x9C,
-                (byte) 0x18, (byte) 0xA9, (byte) 0xF5, (byte) 0xD6, (byte) 0xF4, (byte) 0x94,
-                (byte) 0x5B, (byte) 0x87, (byte) 0x58, (byte) 0xCA, (byte) 0xB2, (byte) 0x1E,
-                (byte) 0xFC, (byte) 0xED, (byte) 0x37, (byte) 0xC3, (byte) 0x49, (byte) 0xAC,
-                (byte) 0xFA, (byte) 0x46, (byte) 0xDB, (byte) 0x7A, (byte) 0x50, (byte) 0x96,
-                (byte) 0xCF, (byte) 0x52, (byte) 0xD7, (byte) 0x4E, (byte) 0xEB, (byte) 0x26,
-                (byte) 0x41, (byte) 0xA2, (byte) 0x6F, (byte) 0x99, (byte) 0x80, (byte) 0x9F,
-                (byte) 0x0F, (byte) 0x0A, (byte) 0xA8, (byte) 0x0D, (byte) 0xAC, (byte) 0xAB,
-                (byte) 0xEF, (byte) 0x7D, (byte) 0xE7, (byte) 0x4C, (byte) 0xF1, (byte) 0x88,
-                (byte) 0x44, (byte) 0xC9, (byte) 0x17, (byte) 0xD0, (byte) 0xBB, (byte) 0xE2,
-                (byte) 0x01, (byte) 0x8C, (byte) 0xC1, (byte) 0x02, (byte) 0x1D, (byte) 0x3C,
-                (byte) 0x15, (byte) 0xB7, (byte) 0x41, (byte) 0x30, (byte) 0xD8, (byte) 0x11,
-                (byte) 0xBD, (byte) 0x6A, (byte) 0x2A, (byte) 0x0D, (byte) 0x36, (byte) 0x44,
-                (byte) 0x9C, (byte) 0x3F, (byte) 0x32, (byte) 0xE2, (byte) 0x1C, (byte) 0xFB,
-                (byte) 0xE3, (byte) 0xFF, (byte) 0xCC, (byte) 0x1A, (byte) 0x72, (byte) 0x38,
-                (byte) 0x37, (byte) 0x69, (byte) 0x5E, (byte) 0x35, (byte) 0x73, (byte) 0xE1,
-                (byte) 0x1E, (byte) 0x74, (byte) 0x35, (byte) 0x44, (byte) 0x07, (byte) 0xB5,
-                (byte) 0x2F, (byte) 0x0B, (byte) 0x60, (byte) 0xF4, (byte) 0xA9, (byte) 0xE0,
-                (byte) 0x81, (byte) 0xB2, (byte) 0xCD, (byte) 0x8B, (byte) 0x82, (byte) 0x76,
-                (byte) 0x7F, (byte) 0xD4, (byte) 0x17, (byte) 0x32, (byte) 0x86, (byte) 0x98,
-                (byte) 0x7C, (byte) 0x85, (byte) 0x66, (byte) 0xF6, (byte) 0x77, (byte) 0xED,
-                (byte) 0x8B, (byte) 0x1A, (byte) 0x52, (byte) 0x16, (byte) 0xDA, (byte) 0x1C,
-                (byte) 0xA7, (byte) 0x16, (byte) 0x79, (byte) 0x20, (byte) 0x1C, (byte) 0x99,
-                (byte) 0x5F, (byte) 0x12, (byte) 0x66, (byte) 0x15, (byte) 0x9F, (byte) 0xE5,
-                (byte) 0x73, (byte) 0xA9, (byte) 0x61, (byte) 0xBA, (byte) 0xA7, (byte) 0x23,
-                (byte) 0x93, (byte) 0x77, (byte) 0xB5, (byte) 0xF6, (byte) 0xEC, (byte) 0x13,
-                (byte) 0xBF, (byte) 0x95, (byte) 0x60, (byte) 0x78, (byte) 0x84, (byte) 0xE3,
-                (byte) 0x44, (byte) 0xEC, (byte) 0x74, (byte) 0xC2, (byte) 0xCB, (byte) 0xD4,
-                (byte) 0x70, (byte) 0xC5, (byte) 0x7B, (byte) 0xF8, (byte) 0x07, (byte) 0x3B,
-                (byte) 0xEB, (byte) 0x9F, (byte) 0xC9, (byte) 0x7D, (byte) 0xE0, (byte) 0xA5,
-                (byte) 0xBA, (byte) 0x68, (byte) 0x7B, (byte) 0xF4, (byte) 0x70, (byte) 0x40,
-                (byte) 0xAE, (byte) 0xE9, (byte) 0x65, (byte) 0xEE, (byte) 0x5B, (byte) 0x71,
-                (byte) 0x36, (byte) 0x0B, (byte) 0xB0, (byte) 0xA2, (byte) 0x98, (byte) 0x7D,
-                (byte) 0xE3, (byte) 0x24, (byte) 0x95, (byte) 0x2B, (byte) 0xC2, (byte) 0x0A,
-                (byte) 0x78, (byte) 0x3D, (byte) 0xCC, (byte) 0x3A, (byte) 0xEE, (byte) 0xED,
-                (byte) 0x48, (byte) 0xEB, (byte) 0xA3, (byte) 0x78, (byte) 0xA8, (byte) 0x9D,
-                (byte) 0x0A, (byte) 0x8F, (byte) 0x9E, (byte) 0x59, (byte) 0x2C, (byte) 0x44,
-                (byte) 0xB5, (byte) 0xF9, (byte) 0x53, (byte) 0x43,
-        });
-
-        BigInteger q = new BigInteger(1, new byte[] {
-                (byte) 0xA1, (byte) 0x9B, (byte) 0x1D, (byte) 0xC0, (byte) 0xE3, (byte) 0xF6,
-                (byte) 0x4A, (byte) 0x35, (byte) 0xE1, (byte) 0x8A, (byte) 0x43, (byte) 0xC2,
-                (byte) 0x9C, (byte) 0xF9, (byte) 0x52, (byte) 0x8F, (byte) 0x94, (byte) 0xA1,
-                (byte) 0x12, (byte) 0x11, (byte) 0xDB, (byte) 0x9A, (byte) 0xB6, (byte) 0x35,
-                (byte) 0x56, (byte) 0x26, (byte) 0x60, (byte) 0x89, (byte) 0x11, (byte) 0xAC,
-                (byte) 0xA8, (byte) 0xE5,
-        });
-
-        BigInteger g = new BigInteger(1, new byte[] {
-                (byte) 0xA1, (byte) 0x5C, (byte) 0x57, (byte) 0x15, (byte) 0xC3, (byte) 0xD9,
-                (byte) 0xD7, (byte) 0x41, (byte) 0x89, (byte) 0xD6, (byte) 0xB8, (byte) 0x7B,
-                (byte) 0xF3, (byte) 0xE0, (byte) 0xB3, (byte) 0xC5, (byte) 0xD1, (byte) 0xAA,
-                (byte) 0xF9, (byte) 0x55, (byte) 0x48, (byte) 0xF1, (byte) 0xDA, (byte) 0xE8,
-                (byte) 0x6F, (byte) 0x51, (byte) 0x05, (byte) 0xB2, (byte) 0xC9, (byte) 0x64,
-                (byte) 0xDA, (byte) 0x5F, (byte) 0xD4, (byte) 0xAA, (byte) 0xFD, (byte) 0x67,
-                (byte) 0xE0, (byte) 0x10, (byte) 0x2C, (byte) 0x1F, (byte) 0x03, (byte) 0x10,
-                (byte) 0xD4, (byte) 0x4B, (byte) 0x20, (byte) 0x82, (byte) 0x2B, (byte) 0x04,
-                (byte) 0xF9, (byte) 0x09, (byte) 0xAE, (byte) 0x28, (byte) 0x3D, (byte) 0x9B,
-                (byte) 0xFF, (byte) 0x87, (byte) 0x76, (byte) 0xCD, (byte) 0xF0, (byte) 0x11,
-                (byte) 0xB7, (byte) 0xEA, (byte) 0xE6, (byte) 0xCD, (byte) 0x60, (byte) 0xD3,
-                (byte) 0x8C, (byte) 0x74, (byte) 0xD3, (byte) 0x45, (byte) 0x63, (byte) 0x69,
-                (byte) 0x3F, (byte) 0x1D, (byte) 0x31, (byte) 0x25, (byte) 0x49, (byte) 0x97,
-                (byte) 0x4B, (byte) 0x73, (byte) 0x34, (byte) 0x12, (byte) 0x73, (byte) 0x27,
-                (byte) 0x4C, (byte) 0xDA, (byte) 0xF3, (byte) 0x08, (byte) 0xA8, (byte) 0xA9,
-                (byte) 0x27, (byte) 0xE4, (byte) 0xB8, (byte) 0xD6, (byte) 0xB5, (byte) 0xC4,
-                (byte) 0x18, (byte) 0xED, (byte) 0xBD, (byte) 0x6F, (byte) 0xA2, (byte) 0x36,
-                (byte) 0xA2, (byte) 0x9C, (byte) 0x27, (byte) 0x62, (byte) 0x7F, (byte) 0x93,
-                (byte) 0xD7, (byte) 0x52, (byte) 0xA9, (byte) 0x76, (byte) 0x55, (byte) 0x99,
-                (byte) 0x00, (byte) 0x5B, (byte) 0xC2, (byte) 0xB9, (byte) 0x18, (byte) 0xAC,
-                (byte) 0x6B, (byte) 0x83, (byte) 0x0D, (byte) 0xA1, (byte) 0xC5, (byte) 0x01,
-                (byte) 0x1A, (byte) 0xE5, (byte) 0x4D, (byte) 0x2F, (byte) 0xCF, (byte) 0x5D,
-                (byte) 0xB2, (byte) 0xE7, (byte) 0xC7, (byte) 0xCB, (byte) 0x2C, (byte) 0xFF,
-                (byte) 0x51, (byte) 0x1B, (byte) 0x9D, (byte) 0xA4, (byte) 0x05, (byte) 0xEB,
-                (byte) 0x17, (byte) 0xD8, (byte) 0x97, (byte) 0x9D, (byte) 0x0C, (byte) 0x59,
-                (byte) 0x92, (byte) 0x8A, (byte) 0x03, (byte) 0x34, (byte) 0xFD, (byte) 0x16,
-                (byte) 0x0F, (byte) 0x2A, (byte) 0xF9, (byte) 0x7D, (byte) 0xC3, (byte) 0x41,
-                (byte) 0x0D, (byte) 0x06, (byte) 0x5A, (byte) 0x4B, (byte) 0x34, (byte) 0xD5,
-                (byte) 0xF5, (byte) 0x09, (byte) 0x1C, (byte) 0xCE, (byte) 0xA7, (byte) 0x19,
-                (byte) 0x6D, (byte) 0x04, (byte) 0x53, (byte) 0x71, (byte) 0xCC, (byte) 0x84,
-                (byte) 0xA0, (byte) 0xB2, (byte) 0xA0, (byte) 0x68, (byte) 0xA3, (byte) 0x40,
-                (byte) 0xC0, (byte) 0x67, (byte) 0x38, (byte) 0x96, (byte) 0x73, (byte) 0x2E,
-                (byte) 0x8E, (byte) 0x2A, (byte) 0x9D, (byte) 0x56, (byte) 0xE9, (byte) 0xAC,
-                (byte) 0xC7, (byte) 0xEC, (byte) 0x84, (byte) 0x7F, (byte) 0xFC, (byte) 0xE0,
-                (byte) 0x69, (byte) 0x03, (byte) 0x8B, (byte) 0x48, (byte) 0x64, (byte) 0x76,
-                (byte) 0x85, (byte) 0xA5, (byte) 0x10, (byte) 0xD9, (byte) 0x31, (byte) 0xC3,
-                (byte) 0x8B, (byte) 0x07, (byte) 0x48, (byte) 0x62, (byte) 0xF6, (byte) 0x68,
-                (byte) 0xF2, (byte) 0x96, (byte) 0xB2, (byte) 0x18, (byte) 0x5B, (byte) 0xFF,
-                (byte) 0x6D, (byte) 0xD1, (byte) 0x6B, (byte) 0xF5, (byte) 0xFD, (byte) 0x81,
-                (byte) 0xF1, (byte) 0xFD, (byte) 0x04, (byte) 0xF0, (byte) 0x9F, (byte) 0xB7,
-                (byte) 0x08, (byte) 0x95, (byte) 0x57, (byte) 0x48, (byte) 0x07, (byte) 0x00,
-                (byte) 0x52, (byte) 0xEC, (byte) 0x75, (byte) 0x91, (byte) 0x02, (byte) 0x11,
-                (byte) 0xA3, (byte) 0x64, (byte) 0x26, (byte) 0xCA,
-        });
-
-        AlgorithmParameterSpec spec = new DSAParameterSpec(p, q, g);
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("DSA")
-                .setKeySize(2048)
-                .setAlgorithmParameterSpec(spec)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "DSA", 2048, spec, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_EC_Unencrypted_Success() throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("EC")
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 256, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_EC_P521_Unencrypted_Success() throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setKeyType("EC")
-                .setKeySize(521)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "EC", 521, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_RSA_Unencrypted_Success() throws Exception {
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-
-        final KeyPair pair = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair);
-
-        assertKeyPairCorrect(pair, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_Replaced_Unencrypted_Success()
-            throws Exception {
-        // Generate the first key
-        {
-            mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                    .setAlias(TEST_ALIAS_1).setSubject(TEST_DN_1).setSerialNumber(TEST_SERIAL_1)
-                    .setStartDate(NOW).setEndDate(NOW_PLUS_10_YEARS).build());
-            final KeyPair pair1 = mGenerator.generateKeyPair();
-            assertNotNull("The KeyPair returned should not be null", pair1);
-            assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1,
-                    NOW, NOW_PLUS_10_YEARS);
-        }
-
-        // Replace the original key
-        {
-            mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                    .setAlias(TEST_ALIAS_1).setSubject(TEST_DN_2).setSerialNumber(TEST_SERIAL_2)
-                    .setStartDate(NOW).setEndDate(NOW_PLUS_10_YEARS).build());
-            final KeyPair pair2 = mGenerator.generateKeyPair();
-            assertNotNull("The KeyPair returned should not be null", pair2);
-            assertKeyPairCorrect(pair2, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2,
-                    NOW, NOW_PLUS_10_YEARS);
-        }
-    }
-
-    public void testKeyPairGenerator_GenerateKeyPair_No_Collision_Unencrypted_Success()
-            throws Exception {
-        // Generate the first key
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_1)
-                .setSubject(TEST_DN_1)
-                .setSerialNumber(TEST_SERIAL_1)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-        final KeyPair pair1 = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair1);
-        assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-
-        // Generate the second key
-        mGenerator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
-                .setAlias(TEST_ALIAS_2)
-                .setSubject(TEST_DN_2)
-                .setSerialNumber(TEST_SERIAL_2)
-                .setStartDate(NOW)
-                .setEndDate(NOW_PLUS_10_YEARS)
-                .build());
-        final KeyPair pair2 = mGenerator.generateKeyPair();
-        assertNotNull("The KeyPair returned should not be null", pair2);
-        assertKeyPairCorrect(pair2, TEST_ALIAS_2, "RSA", 2048, null, TEST_DN_2, TEST_SERIAL_2, NOW,
-                NOW_PLUS_10_YEARS);
-
-        // Check the first key again
-        assertKeyPairCorrect(pair1, TEST_ALIAS_1, "RSA", 2048, null, TEST_DN_1, TEST_SERIAL_1, NOW,
-                NOW_PLUS_10_YEARS);
-    }
-
-    private void assertKeyPairCorrect(KeyPair pair, String alias, String keyType, int keySize,
-            AlgorithmParameterSpec spec, X500Principal dn, BigInteger serial, Date start, Date end)
-            throws Exception {
-        final PublicKey pubKey = pair.getPublic();
-        assertNotNull("The PublicKey for the KeyPair should be not null", pubKey);
-        assertEquals(keyType, pubKey.getAlgorithm());
-        assertEquals("Public keys should be in X.509 format", "X.509", pubKey.getFormat());
-        assertNotNull("Public keys should be encodable", pubKey.getEncoded());
-
-        if ("DSA".equalsIgnoreCase(keyType)) {
-            DSAPublicKey dsaPubKey = (DSAPublicKey) pubKey;
-            DSAParams actualParams = dsaPubKey.getParams();
-            assertEquals(keySize, (actualParams.getP().bitLength() + 7) & ~7);
-            if (spec != null) {
-                DSAParameterSpec expectedParams = (DSAParameterSpec) spec;
-                assertEquals(expectedParams.getP(), actualParams.getP());
-                assertEquals(expectedParams.getQ(), actualParams.getQ());
-                assertEquals(expectedParams.getG(), actualParams.getG());
-            }
-        } else if ("EC".equalsIgnoreCase(keyType)) {
-            assertEquals("Curve should be what was specified during initialization", keySize,
-                    ((ECPublicKey) pubKey).getParams().getCurve().getField().getFieldSize());
-        } else if ("RSA".equalsIgnoreCase(keyType)) {
-            RSAPublicKey rsaPubKey = (RSAPublicKey) pubKey;
-            assertEquals("Modulus size should be what is specified during initialization",
-                    (keySize + 7) & ~7, (rsaPubKey.getModulus().bitLength() + 7) & ~7);
-            if (spec != null) {
-                RSAKeyGenParameterSpec params = (RSAKeyGenParameterSpec) spec;
-                assertEquals((keySize + 7) & ~7, (params.getKeysize() + 7) & ~7);
-                assertEquals(params.getPublicExponent(), rsaPubKey.getPublicExponent());
-            }
-        }
-
-        final PrivateKey privKey = pair.getPrivate();
-        assertNotNull("The PrivateKey for the KeyPair should be not null", privKey);
-        assertEquals(keyType, privKey.getAlgorithm());
-        assertNull("getFormat() should return null", privKey.getFormat());
-        assertNull("getEncoded() should return null", privKey.getEncoded());
-
-        KeyStore.Entry entry = mKeyStore.getEntry(alias, null);
-        assertNotNull("Entry should exist", entry);
-
-        assertTrue("Entry should be a PrivateKeyEntry", entry instanceof KeyStore.PrivateKeyEntry);
-        KeyStore.PrivateKeyEntry privEntry = (KeyStore.PrivateKeyEntry) entry;
-
-        Certificate userCert = privEntry.getCertificate();
-        assertTrue("Certificate should be in X.509 format", userCert instanceof X509Certificate);
-
-        final X509Certificate x509userCert = (X509Certificate) userCert;
-
-        assertEquals("PublicKey used to sign certificate should match one returned in KeyPair",
-                pubKey, x509userCert.getPublicKey());
-
-        assertEquals("The Subject DN should be the one passed into the params", dn,
-                x509userCert.getSubjectDN());
-
-        assertEquals("The Issuer DN should be the same as the Subject DN", dn,
-                x509userCert.getIssuerDN());
-
-        assertEquals("The Serial should be the one passed into the params", serial,
-                x509userCert.getSerialNumber());
-
-        assertDateEquals("The notBefore date should be the one passed into the params", start,
-                x509userCert.getNotBefore());
-
-        assertDateEquals("The notAfter date should be the one passed into the params", end,
-                x509userCert.getNotAfter());
-
-        x509userCert.verify(pubKey);
-
-        Certificate[] chain = privEntry.getCertificateChain();
-        assertEquals("A list of CA certificates should not exist for the generated entry", 1,
-                chain.length);
-
-        assertUsableInSSLConnection(privKey, x509userCert);
-
-        assertEquals("Retrieved key and generated key should be equal", privKey,
-                privEntry.getPrivateKey());
-    }
-
-    private static void assertUsableInSSLConnection(final PrivateKey privKey,
-            final X509Certificate x509userCert) throws Exception {
-        // TODO this should probably be in something like:
-        // TestKeyStore.createForClientSelfSigned(...)
-        TrustManager[] clientTrustManagers = TestKeyStore.createTrustManagers(
-                TestKeyStore.getIntermediateCa().keyStore);
-        SSLContext clientContext = TestSSLContext.createSSLContext("TLS",
-                new KeyManager[] {
-                    TestKeyManager.wrap(new MyKeyManager(privKey, x509userCert))
-                }, clientTrustManagers);
-        TestKeyStore serverKeyStore = TestKeyStore.getServer();
-        serverKeyStore.keyStore.setCertificateEntry("client-selfSigned", x509userCert);
-        SSLContext serverContext = TestSSLContext.createSSLContext("TLS",
-                serverKeyStore.keyManagers,
-                TestKeyStore.createTrustManagers(serverKeyStore.keyStore));
-        SSLServerSocket serverSocket = (SSLServerSocket) serverContext.getServerSocketFactory()
-                .createServerSocket(0);
-        InetAddress host = InetAddress.getLocalHost();
-        int port = serverSocket.getLocalPort();
-
-        SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(host, port);
-        final SSLSocket server = (SSLSocket) serverSocket.accept();
-        ExecutorService executor = Executors.newSingleThreadExecutor();
-        Future<Void> future = executor.submit(new Callable<Void>() {
-            @Override
-            public Void call() throws Exception {
-                server.setNeedClientAuth(true);
-                server.setWantClientAuth(true);
-                server.startHandshake();
-                return null;
-            }
-        });
-        executor.shutdown();
-        client.startHandshake();
-        Certificate[] usedClientCerts = client.getSession().getLocalCertificates();
-        assertNotNull(usedClientCerts);
-        assertEquals(1, usedClientCerts.length);
-        assertEquals(x509userCert, usedClientCerts[0]);
-        future.get();
-        client.close();
-        server.close();
-    }
-
-    private static class MyKeyManager extends X509ExtendedKeyManager {
-        private final PrivateKey key;
-        private final X509Certificate[] chain;
-
-        public MyKeyManager(PrivateKey key, X509Certificate cert) {
-            this.key = key;
-            this.chain = new X509Certificate[] { cert };
-        }
-
-        @Override
-        public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
-            return "fake";
-        }
-
-        @Override
-        public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
-            throw new UnsupportedOperationException("Not implemented");
-        }
-
-        @Override
-        public X509Certificate[] getCertificateChain(String alias) {
-            return chain;
-        }
-
-        @Override
-        public String[] getClientAliases(String keyType, Principal[] issuers) {
-            return new String[] { "fake" };
-        }
-
-        @Override
-        public String[] getServerAliases(String keyType, Principal[] issuers) {
-            throw new UnsupportedOperationException("Not implemented");
-        }
-
-        @Override
-        public PrivateKey getPrivateKey(String alias) {
-            return key;
-        }
-    }
-
-    private static void assertDateEquals(String message, Date date1, Date date2) throws Exception {
-        SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
-
-        String result1 = formatter.format(date1);
-        String result2 = formatter.format(date2);
-
-        assertEquals(message, result1, result2);
-    }
-}
diff --git a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
index 2c926a8..5fe3505 100644
--- a/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/AndroidKeyStoreTest.java
@@ -16,14 +16,25 @@
 
 package android.keystore.cts;
 
+import android.security.KeyPairGeneratorSpec;
 import android.security.KeyStoreParameter;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
 import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.util.Log;
+
+import com.android.cts.keystore.R;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.OutputStream;
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
 import java.security.Key;
 import java.security.KeyFactory;
+import java.security.KeyPairGenerator;
 import java.security.KeyStore;
 import java.security.KeyStore.Entry;
 import java.security.KeyStore.PrivateKeyEntry;
@@ -31,16 +42,15 @@
 import java.security.KeyStoreException;
 import java.security.PrivateKey;
 import java.security.PublicKey;
+import java.security.Signature;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.DSAPublicKey;
-import java.security.interfaces.ECPrivateKey;
-import java.security.interfaces.ECPublicKey;
-import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.RSAKey;
 import java.security.spec.PKCS8EncodedKeySpec;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Calendar;
 import java.util.Collection;
 import java.util.Date;
 import java.util.Enumeration;
@@ -48,11 +58,15 @@
 import java.util.Iterator;
 import java.util.Set;
 
+import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
+import javax.crypto.Mac;
 import javax.crypto.SecretKey;
-import javax.crypto.spec.SecretKeySpec;
+import javax.security.auth.x500.X500Principal;
 
 public class AndroidKeyStoreTest extends AndroidTestCase {
+    private static final String TAG = AndroidKeyStoreTest.class.getSimpleName();
+
     private KeyStore mKeyStore;
 
     private static final String TEST_ALIAS_1 = "test1";
@@ -694,368 +708,6 @@
             (byte) 0x7e, (byte) 0xde, (byte) 0xb2
     };
 
-    /*
-     * The keys and certificates below are generated with:
-     *
-     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
-     * openssl dsaparam -out dsaparam.pem 1024
-     * openssl req -newkey dsa:dsaparam.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_DSA_CA_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x02, (byte) 0x8a, (byte) 0x30, (byte) 0x82,
-            (byte) 0x01, (byte) 0xf3, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x09, (byte) 0x00, (byte) 0x87, (byte) 0xc0,
-            (byte) 0x68, (byte) 0x7f, (byte) 0x42, (byte) 0x92, (byte) 0x0b, (byte) 0x7a,
-            (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86,
-            (byte) 0x48, (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-            (byte) 0x05, (byte) 0x05, (byte) 0x00, (byte) 0x30, (byte) 0x5e, (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) 0x21, (byte) 0x30,
-            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
-            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
-            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
-            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
-            (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17, (byte) 0x30, (byte) 0x15,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c,
-            (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e, (byte) 0x65, (byte) 0x78,
-            (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e,
-            (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17,
-            (byte) 0x0d, (byte) 0x31, (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32,
-            (byte) 0x37, (byte) 0x32, (byte) 0x33, (byte) 0x33, (byte) 0x31, (byte) 0x32,
-            (byte) 0x39, (byte) 0x5a, (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33,
-            (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x35, (byte) 0x32, (byte) 0x33,
-            (byte) 0x33, (byte) 0x31, (byte) 0x32, (byte) 0x39, (byte) 0x5a, (byte) 0x30,
-            (byte) 0x5e, (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) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e,
-            (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74,
-            (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69,
-            (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79,
-            (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x17,
-            (byte) 0x30, (byte) 0x15, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04,
-            (byte) 0x03, (byte) 0x0c, (byte) 0x0e, (byte) 0x63, (byte) 0x61, (byte) 0x2e,
-            (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d, (byte) 0x70, (byte) 0x6c,
-            (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f, (byte) 0x6d, (byte) 0x30,
-            (byte) 0x81, (byte) 0x9f, (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) 0x81, (byte) 0x8d, (byte) 0x00, (byte) 0x30, (byte) 0x81, (byte) 0x89,
-            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xa4, (byte) 0xc7,
-            (byte) 0x06, (byte) 0xba, (byte) 0xdf, (byte) 0x2b, (byte) 0xee, (byte) 0xd2,
-            (byte) 0xb9, (byte) 0xe4, (byte) 0x52, (byte) 0x21, (byte) 0x68, (byte) 0x2b,
-            (byte) 0x83, (byte) 0xdf, (byte) 0xe3, (byte) 0x9c, (byte) 0x08, (byte) 0x73,
-            (byte) 0xdd, (byte) 0x90, (byte) 0xea, (byte) 0x97, (byte) 0x0c, (byte) 0x96,
-            (byte) 0x20, (byte) 0xb1, (byte) 0xee, (byte) 0x11, (byte) 0xd5, (byte) 0xd4,
-            (byte) 0x7c, (byte) 0x44, (byte) 0x96, (byte) 0x2e, (byte) 0x6e, (byte) 0xa2,
-            (byte) 0xb2, (byte) 0xa3, (byte) 0x4b, (byte) 0x0f, (byte) 0x32, (byte) 0x90,
-            (byte) 0xaf, (byte) 0x5c, (byte) 0x6f, (byte) 0x00, (byte) 0x88, (byte) 0x45,
-            (byte) 0x4e, (byte) 0x9b, (byte) 0x26, (byte) 0xc1, (byte) 0x94, (byte) 0x3c,
-            (byte) 0xfe, (byte) 0x10, (byte) 0xbd, (byte) 0xda, (byte) 0xf2, (byte) 0x8d,
-            (byte) 0x03, (byte) 0x52, (byte) 0x32, (byte) 0x11, (byte) 0xff, (byte) 0xf6,
-            (byte) 0xf9, (byte) 0x6e, (byte) 0x8f, (byte) 0x0f, (byte) 0xc8, (byte) 0x0a,
-            (byte) 0x48, (byte) 0x39, (byte) 0x33, (byte) 0xb9, (byte) 0x0c, (byte) 0xb3,
-            (byte) 0x2b, (byte) 0xab, (byte) 0x7d, (byte) 0x79, (byte) 0x6f, (byte) 0x57,
-            (byte) 0x5b, (byte) 0xb8, (byte) 0x84, (byte) 0xb6, (byte) 0xcc, (byte) 0xe8,
-            (byte) 0x30, (byte) 0x78, (byte) 0xff, (byte) 0x92, (byte) 0xe5, (byte) 0x43,
-            (byte) 0x2e, (byte) 0xef, (byte) 0x66, (byte) 0x98, (byte) 0xb4, (byte) 0xfe,
-            (byte) 0xa2, (byte) 0x40, (byte) 0xf2, (byte) 0x1f, (byte) 0xd0, (byte) 0x86,
-            (byte) 0x16, (byte) 0xc8, (byte) 0x45, (byte) 0xc4, (byte) 0x52, (byte) 0xcb,
-            (byte) 0x31, (byte) 0x5c, (byte) 0x9f, (byte) 0x32, (byte) 0x3b, (byte) 0xf7,
-            (byte) 0x19, (byte) 0x08, (byte) 0xc7, (byte) 0x00, (byte) 0x21, (byte) 0x7d,
-            (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) 0x47, (byte) 0x82, (byte) 0xa3, (byte) 0xf1,
-            (byte) 0xc2, (byte) 0x7e, (byte) 0x3a, (byte) 0xde, (byte) 0x4f, (byte) 0x30,
-            (byte) 0x4c, (byte) 0x7f, (byte) 0x72, (byte) 0x81, (byte) 0x15, (byte) 0x32,
-            (byte) 0xda, (byte) 0x7f, (byte) 0x58, (byte) 0x18, (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) 0x47,
-            (byte) 0x82, (byte) 0xa3, (byte) 0xf1, (byte) 0xc2, (byte) 0x7e, (byte) 0x3a,
-            (byte) 0xde, (byte) 0x4f, (byte) 0x30, (byte) 0x4c, (byte) 0x7f, (byte) 0x72,
-            (byte) 0x81, (byte) 0x15, (byte) 0x32, (byte) 0xda, (byte) 0x7f, (byte) 0x58,
-            (byte) 0x18, (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) 0x05, (byte) 0x05, (byte) 0x00,
-            (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x08, (byte) 0x7f,
-            (byte) 0x6a, (byte) 0x48, (byte) 0x90, (byte) 0x7b, (byte) 0x9b, (byte) 0x72,
-            (byte) 0x13, (byte) 0xa7, (byte) 0xef, (byte) 0x6b, (byte) 0x0b, (byte) 0x59,
-            (byte) 0xe5, (byte) 0x49, (byte) 0x72, (byte) 0x3a, (byte) 0xc8, (byte) 0x84,
-            (byte) 0xcc, (byte) 0x23, (byte) 0x18, (byte) 0x4c, (byte) 0xec, (byte) 0xc7,
-            (byte) 0xef, (byte) 0xcb, (byte) 0xa7, (byte) 0xbe, (byte) 0xe4, (byte) 0xef,
-            (byte) 0x8f, (byte) 0xc6, (byte) 0x06, (byte) 0x8c, (byte) 0xc0, (byte) 0xe4,
-            (byte) 0x2f, (byte) 0x2a, (byte) 0xc0, (byte) 0x35, (byte) 0x7d, (byte) 0x5e,
-            (byte) 0x19, (byte) 0x29, (byte) 0x8c, (byte) 0xb9, (byte) 0xf1, (byte) 0x1e,
-            (byte) 0xaf, (byte) 0x82, (byte) 0xd8, (byte) 0xe3, (byte) 0x88, (byte) 0xe1,
-            (byte) 0x31, (byte) 0xc8, (byte) 0x82, (byte) 0x1f, (byte) 0x83, (byte) 0xa9,
-            (byte) 0xde, (byte) 0xfe, (byte) 0x4b, (byte) 0xe2, (byte) 0x78, (byte) 0x64,
-            (byte) 0xed, (byte) 0xa4, (byte) 0x7b, (byte) 0xee, (byte) 0x8d, (byte) 0x71,
-            (byte) 0x1b, (byte) 0x44, (byte) 0xe6, (byte) 0xb7, (byte) 0xe8, (byte) 0xc5,
-            (byte) 0x9a, (byte) 0x93, (byte) 0x92, (byte) 0x6f, (byte) 0x6f, (byte) 0xdb,
-            (byte) 0xbd, (byte) 0xd7, (byte) 0x03, (byte) 0x85, (byte) 0xa9, (byte) 0x5f,
-            (byte) 0x53, (byte) 0x5f, (byte) 0x5d, (byte) 0x30, (byte) 0xc6, (byte) 0xd9,
-            (byte) 0xce, (byte) 0x34, (byte) 0xa8, (byte) 0xbe, (byte) 0x31, (byte) 0x47,
-            (byte) 0x1c, (byte) 0xa4, (byte) 0x7f, (byte) 0xc0, (byte) 0x2c, (byte) 0xbc,
-            (byte) 0xfe, (byte) 0x1a, (byte) 0x31, (byte) 0xd8, (byte) 0x77, (byte) 0x4d,
-            (byte) 0xfc, (byte) 0x45, (byte) 0x84, (byte) 0xfc, (byte) 0x45, (byte) 0x12,
-            (byte) 0xab, (byte) 0x50, (byte) 0xe4, (byte) 0x45, (byte) 0xe5, (byte) 0x11
-    };
-
-    /**
-     * Generated from above and converted with: openssl pkcs8 -topk8 -outform d
-     * -in userkey.pem -nocrypt | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_DSA_KEY_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x4c, (byte) 0x02, (byte) 0x01,
-            (byte) 0x00, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x2c, (byte) 0x06,
-            (byte) 0x07, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38,
-            (byte) 0x04, (byte) 0x01, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1f,
-            (byte) 0x02, (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0xb3, (byte) 0x23,
-            (byte) 0xf7, (byte) 0x86, (byte) 0xbd, (byte) 0x3b, (byte) 0x86, (byte) 0xcc,
-            (byte) 0xc3, (byte) 0x91, (byte) 0xc0, (byte) 0x30, (byte) 0x32, (byte) 0x02,
-            (byte) 0x47, (byte) 0x35, (byte) 0x01, (byte) 0xef, (byte) 0xee, (byte) 0x98,
-            (byte) 0x13, (byte) 0x56, (byte) 0x49, (byte) 0x47, (byte) 0xb5, (byte) 0x20,
-            (byte) 0xa8, (byte) 0x60, (byte) 0xcb, (byte) 0xc0, (byte) 0xd5, (byte) 0x77,
-            (byte) 0xc1, (byte) 0x69, (byte) 0xcd, (byte) 0x18, (byte) 0x34, (byte) 0x92,
-            (byte) 0xf2, (byte) 0x6a, (byte) 0x2a, (byte) 0x10, (byte) 0x59, (byte) 0x1c,
-            (byte) 0x91, (byte) 0x20, (byte) 0x51, (byte) 0xca, (byte) 0x37, (byte) 0xb2,
-            (byte) 0x87, (byte) 0xa6, (byte) 0x8a, (byte) 0x02, (byte) 0xfd, (byte) 0x45,
-            (byte) 0x46, (byte) 0xf9, (byte) 0x76, (byte) 0xb1, (byte) 0x35, (byte) 0x38,
-            (byte) 0x8d, (byte) 0xff, (byte) 0x4c, (byte) 0x5d, (byte) 0x75, (byte) 0x8f,
-            (byte) 0x66, (byte) 0x15, (byte) 0x7d, (byte) 0x7b, (byte) 0xda, (byte) 0xdb,
-            (byte) 0x57, (byte) 0x39, (byte) 0xff, (byte) 0x91, (byte) 0x3f, (byte) 0xdd,
-            (byte) 0xe2, (byte) 0xb4, (byte) 0x22, (byte) 0x60, (byte) 0x4c, (byte) 0x32,
-            (byte) 0x3b, (byte) 0x9d, (byte) 0x34, (byte) 0x9f, (byte) 0xb9, (byte) 0x5d,
-            (byte) 0x75, (byte) 0xb9, (byte) 0xd3, (byte) 0x7f, (byte) 0x11, (byte) 0xba,
-            (byte) 0xb7, (byte) 0xc8, (byte) 0x32, (byte) 0xc6, (byte) 0xce, (byte) 0x71,
-            (byte) 0x91, (byte) 0xd3, (byte) 0x32, (byte) 0xaf, (byte) 0x4d, (byte) 0x7e,
-            (byte) 0x7c, (byte) 0x15, (byte) 0xf7, (byte) 0x71, (byte) 0x2c, (byte) 0x52,
-            (byte) 0x65, (byte) 0x4d, (byte) 0xa9, (byte) 0x81, (byte) 0x25, (byte) 0x35,
-            (byte) 0xce, (byte) 0x0b, (byte) 0x5b, (byte) 0x56, (byte) 0xfe, (byte) 0xf1,
-            (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xeb, (byte) 0x4e, (byte) 0x7f,
-            (byte) 0x7a, (byte) 0x31, (byte) 0xb3, (byte) 0x7d, (byte) 0x8d, (byte) 0xb2,
-            (byte) 0xf7, (byte) 0xaf, (byte) 0xad, (byte) 0xb1, (byte) 0x42, (byte) 0x92,
-            (byte) 0xf3, (byte) 0x6c, (byte) 0xe4, (byte) 0xed, (byte) 0x8b, (byte) 0x02,
-            (byte) 0x81, (byte) 0x81, (byte) 0x00, (byte) 0x81, (byte) 0xc8, (byte) 0x36,
-            (byte) 0x48, (byte) 0xdb, (byte) 0x71, (byte) 0x2b, (byte) 0x91, (byte) 0xce,
-            (byte) 0x6d, (byte) 0xbc, (byte) 0xb8, (byte) 0xf9, (byte) 0xcb, (byte) 0x50,
-            (byte) 0x91, (byte) 0x10, (byte) 0x8a, (byte) 0xf8, (byte) 0x37, (byte) 0x50,
-            (byte) 0xda, (byte) 0x4f, (byte) 0xc8, (byte) 0x4d, (byte) 0x73, (byte) 0xcb,
-            (byte) 0x4d, (byte) 0xb0, (byte) 0x19, (byte) 0x54, (byte) 0x5a, (byte) 0xf3,
-            (byte) 0x6c, (byte) 0xc9, (byte) 0xd8, (byte) 0x96, (byte) 0xd9, (byte) 0xb0,
-            (byte) 0x54, (byte) 0x7e, (byte) 0x7d, (byte) 0xe2, (byte) 0x58, (byte) 0x0e,
-            (byte) 0x5f, (byte) 0xc0, (byte) 0xce, (byte) 0xb9, (byte) 0x5c, (byte) 0xe3,
-            (byte) 0xd3, (byte) 0xdf, (byte) 0xcf, (byte) 0x45, (byte) 0x74, (byte) 0xfb,
-            (byte) 0xe6, (byte) 0x20, (byte) 0xe7, (byte) 0xfc, (byte) 0x0f, (byte) 0xca,
-            (byte) 0xdb, (byte) 0xc0, (byte) 0x0b, (byte) 0xe1, (byte) 0x5a, (byte) 0x16,
-            (byte) 0x1d, (byte) 0xb3, (byte) 0x2e, (byte) 0xe5, (byte) 0x5f, (byte) 0x89,
-            (byte) 0x17, (byte) 0x73, (byte) 0x50, (byte) 0xd1, (byte) 0x4a, (byte) 0x60,
-            (byte) 0xb7, (byte) 0xaa, (byte) 0xf0, (byte) 0xc7, (byte) 0xc5, (byte) 0x03,
-            (byte) 0x4e, (byte) 0x36, (byte) 0x51, (byte) 0x9e, (byte) 0x2f, (byte) 0xfa,
-            (byte) 0xf3, (byte) 0xd6, (byte) 0x58, (byte) 0x14, (byte) 0x02, (byte) 0xb4,
-            (byte) 0x41, (byte) 0xd6, (byte) 0x72, (byte) 0x6f, (byte) 0x58, (byte) 0x5b,
-            (byte) 0x2d, (byte) 0x23, (byte) 0xc0, (byte) 0x75, (byte) 0x4f, (byte) 0x39,
-            (byte) 0xa8, (byte) 0x6a, (byte) 0xdf, (byte) 0x79, (byte) 0x21, (byte) 0xf2,
-            (byte) 0x77, (byte) 0x91, (byte) 0x3f, (byte) 0x1c, (byte) 0x4d, (byte) 0x48,
-            (byte) 0x78, (byte) 0xcd, (byte) 0xed, (byte) 0x79, (byte) 0x23, (byte) 0x04,
-            (byte) 0x17, (byte) 0x02, (byte) 0x15, (byte) 0x00, (byte) 0xc7, (byte) 0xe7,
-            (byte) 0xe2, (byte) 0x6b, (byte) 0x14, (byte) 0xe6, (byte) 0x31, (byte) 0x12,
-            (byte) 0xb2, (byte) 0x1e, (byte) 0xd4, (byte) 0xf2, (byte) 0x9b, (byte) 0x2c,
-            (byte) 0xf6, (byte) 0x54, (byte) 0x4c, (byte) 0x12, (byte) 0xe8, (byte) 0x22
-    };
-
-    /**
-     * Generated from above and converted with: openssl x509 -outform d -in
-     * usercert.pem | xxd -i | sed 's/0x/(byte) 0x/g'
-     */
-    private static final byte[] FAKE_DSA_USER_1 = new byte[] {
-            (byte) 0x30, (byte) 0x82, (byte) 0x03, (byte) 0xca, (byte) 0x30, (byte) 0x82,
-            (byte) 0x03, (byte) 0x33, (byte) 0xa0, (byte) 0x03, (byte) 0x02, (byte) 0x01,
-            (byte) 0x02, (byte) 0x02, (byte) 0x01, (byte) 0x01, (byte) 0x30, (byte) 0x0d,
-            (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-            (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05, (byte) 0x05,
-            (byte) 0x00, (byte) 0x30, (byte) 0x5e, (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) 0x21, (byte) 0x30, (byte) 0x1f, (byte) 0x06,
-            (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a, (byte) 0x0c, (byte) 0x18,
-            (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x6e,
-            (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57, (byte) 0x69, (byte) 0x64,
-            (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73, (byte) 0x20, (byte) 0x50,
-            (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c, (byte) 0x74, (byte) 0x64,
-            (byte) 0x31, (byte) 0x17, (byte) 0x30, (byte) 0x15, (byte) 0x06, (byte) 0x03,
-            (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c, (byte) 0x0e, (byte) 0x63,
-            (byte) 0x61, (byte) 0x2e, (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d,
-            (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f,
-            (byte) 0x6d, (byte) 0x30, (byte) 0x1e, (byte) 0x17, (byte) 0x0d, (byte) 0x31,
-            (byte) 0x33, (byte) 0x30, (byte) 0x38, (byte) 0x32, (byte) 0x37, (byte) 0x32,
-            (byte) 0x33, (byte) 0x33, (byte) 0x34, (byte) 0x32, (byte) 0x32, (byte) 0x5a,
-            (byte) 0x17, (byte) 0x0d, (byte) 0x32, (byte) 0x33, (byte) 0x30, (byte) 0x38,
-            (byte) 0x32, (byte) 0x35, (byte) 0x32, (byte) 0x33, (byte) 0x33, (byte) 0x34,
-            (byte) 0x32, (byte) 0x32, (byte) 0x5a, (byte) 0x30, (byte) 0x62, (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) 0x21, (byte) 0x30,
-            (byte) 0x1f, (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x0a,
-            (byte) 0x0c, (byte) 0x18, (byte) 0x49, (byte) 0x6e, (byte) 0x74, (byte) 0x65,
-            (byte) 0x72, (byte) 0x6e, (byte) 0x65, (byte) 0x74, (byte) 0x20, (byte) 0x57,
-            (byte) 0x69, (byte) 0x64, (byte) 0x67, (byte) 0x69, (byte) 0x74, (byte) 0x73,
-            (byte) 0x20, (byte) 0x50, (byte) 0x74, (byte) 0x79, (byte) 0x20, (byte) 0x4c,
-            (byte) 0x74, (byte) 0x64, (byte) 0x31, (byte) 0x1b, (byte) 0x30, (byte) 0x19,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x04, (byte) 0x03, (byte) 0x0c,
-            (byte) 0x12, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65,
-            (byte) 0x72, (byte) 0x2e, (byte) 0x65, (byte) 0x78, (byte) 0x61, (byte) 0x6d,
-            (byte) 0x70, (byte) 0x6c, (byte) 0x65, (byte) 0x2e, (byte) 0x63, (byte) 0x6f,
-            (byte) 0x6d, (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0xb7, (byte) 0x30,
-            (byte) 0x82, (byte) 0x01, (byte) 0x2c, (byte) 0x06, (byte) 0x07, (byte) 0x2a,
-            (byte) 0x86, (byte) 0x48, (byte) 0xce, (byte) 0x38, (byte) 0x04, (byte) 0x01,
-            (byte) 0x30, (byte) 0x82, (byte) 0x01, (byte) 0x1f, (byte) 0x02, (byte) 0x81,
-            (byte) 0x81, (byte) 0x00, (byte) 0xb3, (byte) 0x23, (byte) 0xf7, (byte) 0x86,
-            (byte) 0xbd, (byte) 0x3b, (byte) 0x86, (byte) 0xcc, (byte) 0xc3, (byte) 0x91,
-            (byte) 0xc0, (byte) 0x30, (byte) 0x32, (byte) 0x02, (byte) 0x47, (byte) 0x35,
-            (byte) 0x01, (byte) 0xef, (byte) 0xee, (byte) 0x98, (byte) 0x13, (byte) 0x56,
-            (byte) 0x49, (byte) 0x47, (byte) 0xb5, (byte) 0x20, (byte) 0xa8, (byte) 0x60,
-            (byte) 0xcb, (byte) 0xc0, (byte) 0xd5, (byte) 0x77, (byte) 0xc1, (byte) 0x69,
-            (byte) 0xcd, (byte) 0x18, (byte) 0x34, (byte) 0x92, (byte) 0xf2, (byte) 0x6a,
-            (byte) 0x2a, (byte) 0x10, (byte) 0x59, (byte) 0x1c, (byte) 0x91, (byte) 0x20,
-            (byte) 0x51, (byte) 0xca, (byte) 0x37, (byte) 0xb2, (byte) 0x87, (byte) 0xa6,
-            (byte) 0x8a, (byte) 0x02, (byte) 0xfd, (byte) 0x45, (byte) 0x46, (byte) 0xf9,
-            (byte) 0x76, (byte) 0xb1, (byte) 0x35, (byte) 0x38, (byte) 0x8d, (byte) 0xff,
-            (byte) 0x4c, (byte) 0x5d, (byte) 0x75, (byte) 0x8f, (byte) 0x66, (byte) 0x15,
-            (byte) 0x7d, (byte) 0x7b, (byte) 0xda, (byte) 0xdb, (byte) 0x57, (byte) 0x39,
-            (byte) 0xff, (byte) 0x91, (byte) 0x3f, (byte) 0xdd, (byte) 0xe2, (byte) 0xb4,
-            (byte) 0x22, (byte) 0x60, (byte) 0x4c, (byte) 0x32, (byte) 0x3b, (byte) 0x9d,
-            (byte) 0x34, (byte) 0x9f, (byte) 0xb9, (byte) 0x5d, (byte) 0x75, (byte) 0xb9,
-            (byte) 0xd3, (byte) 0x7f, (byte) 0x11, (byte) 0xba, (byte) 0xb7, (byte) 0xc8,
-            (byte) 0x32, (byte) 0xc6, (byte) 0xce, (byte) 0x71, (byte) 0x91, (byte) 0xd3,
-            (byte) 0x32, (byte) 0xaf, (byte) 0x4d, (byte) 0x7e, (byte) 0x7c, (byte) 0x15,
-            (byte) 0xf7, (byte) 0x71, (byte) 0x2c, (byte) 0x52, (byte) 0x65, (byte) 0x4d,
-            (byte) 0xa9, (byte) 0x81, (byte) 0x25, (byte) 0x35, (byte) 0xce, (byte) 0x0b,
-            (byte) 0x5b, (byte) 0x56, (byte) 0xfe, (byte) 0xf1, (byte) 0x02, (byte) 0x15,
-            (byte) 0x00, (byte) 0xeb, (byte) 0x4e, (byte) 0x7f, (byte) 0x7a, (byte) 0x31,
-            (byte) 0xb3, (byte) 0x7d, (byte) 0x8d, (byte) 0xb2, (byte) 0xf7, (byte) 0xaf,
-            (byte) 0xad, (byte) 0xb1, (byte) 0x42, (byte) 0x92, (byte) 0xf3, (byte) 0x6c,
-            (byte) 0xe4, (byte) 0xed, (byte) 0x8b, (byte) 0x02, (byte) 0x81, (byte) 0x81,
-            (byte) 0x00, (byte) 0x81, (byte) 0xc8, (byte) 0x36, (byte) 0x48, (byte) 0xdb,
-            (byte) 0x71, (byte) 0x2b, (byte) 0x91, (byte) 0xce, (byte) 0x6d, (byte) 0xbc,
-            (byte) 0xb8, (byte) 0xf9, (byte) 0xcb, (byte) 0x50, (byte) 0x91, (byte) 0x10,
-            (byte) 0x8a, (byte) 0xf8, (byte) 0x37, (byte) 0x50, (byte) 0xda, (byte) 0x4f,
-            (byte) 0xc8, (byte) 0x4d, (byte) 0x73, (byte) 0xcb, (byte) 0x4d, (byte) 0xb0,
-            (byte) 0x19, (byte) 0x54, (byte) 0x5a, (byte) 0xf3, (byte) 0x6c, (byte) 0xc9,
-            (byte) 0xd8, (byte) 0x96, (byte) 0xd9, (byte) 0xb0, (byte) 0x54, (byte) 0x7e,
-            (byte) 0x7d, (byte) 0xe2, (byte) 0x58, (byte) 0x0e, (byte) 0x5f, (byte) 0xc0,
-            (byte) 0xce, (byte) 0xb9, (byte) 0x5c, (byte) 0xe3, (byte) 0xd3, (byte) 0xdf,
-            (byte) 0xcf, (byte) 0x45, (byte) 0x74, (byte) 0xfb, (byte) 0xe6, (byte) 0x20,
-            (byte) 0xe7, (byte) 0xfc, (byte) 0x0f, (byte) 0xca, (byte) 0xdb, (byte) 0xc0,
-            (byte) 0x0b, (byte) 0xe1, (byte) 0x5a, (byte) 0x16, (byte) 0x1d, (byte) 0xb3,
-            (byte) 0x2e, (byte) 0xe5, (byte) 0x5f, (byte) 0x89, (byte) 0x17, (byte) 0x73,
-            (byte) 0x50, (byte) 0xd1, (byte) 0x4a, (byte) 0x60, (byte) 0xb7, (byte) 0xaa,
-            (byte) 0xf0, (byte) 0xc7, (byte) 0xc5, (byte) 0x03, (byte) 0x4e, (byte) 0x36,
-            (byte) 0x51, (byte) 0x9e, (byte) 0x2f, (byte) 0xfa, (byte) 0xf3, (byte) 0xd6,
-            (byte) 0x58, (byte) 0x14, (byte) 0x02, (byte) 0xb4, (byte) 0x41, (byte) 0xd6,
-            (byte) 0x72, (byte) 0x6f, (byte) 0x58, (byte) 0x5b, (byte) 0x2d, (byte) 0x23,
-            (byte) 0xc0, (byte) 0x75, (byte) 0x4f, (byte) 0x39, (byte) 0xa8, (byte) 0x6a,
-            (byte) 0xdf, (byte) 0x79, (byte) 0x21, (byte) 0xf2, (byte) 0x77, (byte) 0x91,
-            (byte) 0x3f, (byte) 0x1c, (byte) 0x4d, (byte) 0x48, (byte) 0x78, (byte) 0xcd,
-            (byte) 0xed, (byte) 0x79, (byte) 0x23, (byte) 0x03, (byte) 0x81, (byte) 0x84,
-            (byte) 0x00, (byte) 0x02, (byte) 0x81, (byte) 0x80, (byte) 0x1a, (byte) 0x50,
-            (byte) 0x9d, (byte) 0x3e, (byte) 0xa1, (byte) 0x6c, (byte) 0x99, (byte) 0x35,
-            (byte) 0x36, (byte) 0x26, (byte) 0x22, (byte) 0x6b, (byte) 0x47, (byte) 0x45,
-            (byte) 0x80, (byte) 0x5b, (byte) 0xd5, (byte) 0xc1, (byte) 0xc5, (byte) 0x70,
-            (byte) 0x75, (byte) 0x55, (byte) 0x66, (byte) 0x33, (byte) 0x1d, (byte) 0xae,
-            (byte) 0xd0, (byte) 0x01, (byte) 0x64, (byte) 0x8b, (byte) 0xae, (byte) 0x9d,
-            (byte) 0x66, (byte) 0x58, (byte) 0xf9, (byte) 0x42, (byte) 0x74, (byte) 0x3a,
-            (byte) 0x32, (byte) 0xc7, (byte) 0x7f, (byte) 0x25, (byte) 0x64, (byte) 0x7d,
-            (byte) 0x08, (byte) 0x26, (byte) 0xbf, (byte) 0x21, (byte) 0x3a, (byte) 0x84,
-            (byte) 0xcc, (byte) 0x2c, (byte) 0x66, (byte) 0x7d, (byte) 0xc7, (byte) 0xd6,
-            (byte) 0xb1, (byte) 0x69, (byte) 0x57, (byte) 0x67, (byte) 0x52, (byte) 0x73,
-            (byte) 0x3f, (byte) 0x79, (byte) 0x60, (byte) 0xaa, (byte) 0xf4, (byte) 0x8a,
-            (byte) 0x48, (byte) 0x42, (byte) 0x46, (byte) 0x41, (byte) 0xd0, (byte) 0x50,
-            (byte) 0x9b, (byte) 0xa2, (byte) 0x4e, (byte) 0xa5, (byte) 0x88, (byte) 0x10,
-            (byte) 0xf7, (byte) 0x61, (byte) 0xa2, (byte) 0xfa, (byte) 0x8d, (byte) 0xa6,
-            (byte) 0x13, (byte) 0x9e, (byte) 0x36, (byte) 0x86, (byte) 0x62, (byte) 0xf0,
-            (byte) 0x97, (byte) 0xef, (byte) 0x11, (byte) 0xc6, (byte) 0x35, (byte) 0xd3,
-            (byte) 0x79, (byte) 0x30, (byte) 0xde, (byte) 0xf2, (byte) 0x7f, (byte) 0x7a,
-            (byte) 0x3c, (byte) 0x03, (byte) 0xa3, (byte) 0xc5, (byte) 0xbc, (byte) 0xb1,
-            (byte) 0xbc, (byte) 0x2f, (byte) 0x10, (byte) 0xf4, (byte) 0x51, (byte) 0x89,
-            (byte) 0xe2, (byte) 0xaf, (byte) 0xf7, (byte) 0x61, (byte) 0x1a, (byte) 0xf0,
-            (byte) 0x87, (byte) 0x5e, (byte) 0xa5, (byte) 0x02, (byte) 0xd2, (byte) 0xe4,
-            (byte) 0xa3, (byte) 0x7b, (byte) 0x30, (byte) 0x79, (byte) 0x30, (byte) 0x09,
-            (byte) 0x06, (byte) 0x03, (byte) 0x55, (byte) 0x1d, (byte) 0x13, (byte) 0x04,
-            (byte) 0x02, (byte) 0x30, (byte) 0x00, (byte) 0x30, (byte) 0x2c, (byte) 0x06,
-            (byte) 0x09, (byte) 0x60, (byte) 0x86, (byte) 0x48, (byte) 0x01, (byte) 0x86,
-            (byte) 0xf8, (byte) 0x42, (byte) 0x01, (byte) 0x0d, (byte) 0x04, (byte) 0x1f,
-            (byte) 0x16, (byte) 0x1d, (byte) 0x4f, (byte) 0x70, (byte) 0x65, (byte) 0x6e,
-            (byte) 0x53, (byte) 0x53, (byte) 0x4c, (byte) 0x20, (byte) 0x47, (byte) 0x65,
-            (byte) 0x6e, (byte) 0x65, (byte) 0x72, (byte) 0x61, (byte) 0x74, (byte) 0x65,
-            (byte) 0x64, (byte) 0x20, (byte) 0x43, (byte) 0x65, (byte) 0x72, (byte) 0x74,
-            (byte) 0x69, (byte) 0x66, (byte) 0x69, (byte) 0x63, (byte) 0x61, (byte) 0x74,
-            (byte) 0x65, (byte) 0x30, (byte) 0x1d, (byte) 0x06, (byte) 0x03, (byte) 0x55,
-            (byte) 0x1d, (byte) 0x0e, (byte) 0x04, (byte) 0x16, (byte) 0x04, (byte) 0x14,
-            (byte) 0xd1, (byte) 0x6c, (byte) 0x36, (byte) 0x36, (byte) 0x61, (byte) 0x6c,
-            (byte) 0xf6, (byte) 0x90, (byte) 0x82, (byte) 0x82, (byte) 0x87, (byte) 0x93,
-            (byte) 0xbe, (byte) 0x99, (byte) 0x60, (byte) 0x1b, (byte) 0x03, (byte) 0x58,
-            (byte) 0x36, (byte) 0x63, (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) 0x47, (byte) 0x82, (byte) 0xa3,
-            (byte) 0xf1, (byte) 0xc2, (byte) 0x7e, (byte) 0x3a, (byte) 0xde, (byte) 0x4f,
-            (byte) 0x30, (byte) 0x4c, (byte) 0x7f, (byte) 0x72, (byte) 0x81, (byte) 0x15,
-            (byte) 0x32, (byte) 0xda, (byte) 0x7f, (byte) 0x58, (byte) 0x18, (byte) 0x30,
-            (byte) 0x0d, (byte) 0x06, (byte) 0x09, (byte) 0x2a, (byte) 0x86, (byte) 0x48,
-            (byte) 0x86, (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01, (byte) 0x05,
-            (byte) 0x05, (byte) 0x00, (byte) 0x03, (byte) 0x81, (byte) 0x81, (byte) 0x00,
-            (byte) 0x81, (byte) 0xde, (byte) 0x20, (byte) 0xa1, (byte) 0xb2, (byte) 0x50,
-            (byte) 0x03, (byte) 0xcd, (byte) 0x90, (byte) 0x4f, (byte) 0x2b, (byte) 0x47,
-            (byte) 0x1d, (byte) 0xac, (byte) 0x6e, (byte) 0xb4, (byte) 0xc7, (byte) 0x14,
-            (byte) 0xc6, (byte) 0x4f, (byte) 0x45, (byte) 0xaf, (byte) 0x81, (byte) 0x5d,
-            (byte) 0x5a, (byte) 0x31, (byte) 0xff, (byte) 0x9c, (byte) 0x4d, (byte) 0xdc,
-            (byte) 0x9e, (byte) 0x36, (byte) 0x9f, (byte) 0x9b, (byte) 0xb1, (byte) 0xc9,
-            (byte) 0x50, (byte) 0xa3, (byte) 0xf6, (byte) 0x9c, (byte) 0x68, (byte) 0x6f,
-            (byte) 0x68, (byte) 0xd9, (byte) 0x56, (byte) 0x1b, (byte) 0xe5, (byte) 0x1b,
-            (byte) 0x41, (byte) 0xd4, (byte) 0xcc, (byte) 0xb6, (byte) 0x37, (byte) 0xd5,
-            (byte) 0x69, (byte) 0x6b, (byte) 0x39, (byte) 0xaf, (byte) 0xc6, (byte) 0xb8,
-            (byte) 0x39, (byte) 0x76, (byte) 0xe3, (byte) 0xf7, (byte) 0x97, (byte) 0x74,
-            (byte) 0x31, (byte) 0xc4, (byte) 0x2d, (byte) 0xb7, (byte) 0x9a, (byte) 0xa4,
-            (byte) 0xfa, (byte) 0x9f, (byte) 0xa8, (byte) 0xe3, (byte) 0x41, (byte) 0xda,
-            (byte) 0x2f, (byte) 0x0c, (byte) 0x9d, (byte) 0x83, (byte) 0xdc, (byte) 0x86,
-            (byte) 0x1f, (byte) 0x5c, (byte) 0x0f, (byte) 0x87, (byte) 0x05, (byte) 0xc9,
-            (byte) 0xb0, (byte) 0x63, (byte) 0xca, (byte) 0x9b, (byte) 0xdb, (byte) 0xe6,
-            (byte) 0x3c, (byte) 0xe9, (byte) 0x23, (byte) 0x9e, (byte) 0x23, (byte) 0x44,
-            (byte) 0x1d, (byte) 0x5b, (byte) 0x60, (byte) 0x66, (byte) 0xb6, (byte) 0x72,
-            (byte) 0x8c, (byte) 0x87, (byte) 0x86, (byte) 0xe8, (byte) 0xdb, (byte) 0x29,
-            (byte) 0x67, (byte) 0x9c, (byte) 0x33, (byte) 0x5c, (byte) 0x39, (byte) 0xf1,
-            (byte) 0xb5, (byte) 0x9b, (byte) 0xb8, (byte) 0xe1, (byte) 0x42, (byte) 0x51,
-            (byte) 0xed, (byte) 0x2c
-    };
-
     /**
      * The amount of time to allow before and after expected time for variance
      * in timing tests.
@@ -1064,6 +716,8 @@
 
     @Override
     protected void setUp() throws Exception {
+        super.setUp();
+
         // Wipe any existing entries in the KeyStore
         KeyStore ksTemp = KeyStore.getInstance("AndroidKeyStore");
         ksTemp.load(null, null);
@@ -1077,6 +731,21 @@
         mKeyStore = KeyStore.getInstance("AndroidKeyStore");
     }
 
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+            keyStore.load(null, null);
+            Enumeration<String> aliases = keyStore.aliases();
+            while (aliases.hasMoreElements()) {
+                String alias = aliases.nextElement();
+                keyStore.deleteEntry(alias);
+            }
+        } finally {
+            super.tearDown();
+        }
+    }
+
     private PrivateKey generatePrivateKey(String keyType, byte[] fakeKey1) throws Exception {
         KeyFactory kf = KeyFactory.getInstance(keyType);
         return kf.generatePrivate(new PKCS8EncodedKeySpec(fakeKey1));
@@ -1087,13 +756,6 @@
         return cf.generateCertificate(new ByteArrayInputStream(fakeUser1));
     }
 
-    private PrivateKeyEntry makeUserDsaKey1() throws Exception {
-        return new KeyStore.PrivateKeyEntry(generatePrivateKey("DSA", FAKE_DSA_KEY_1),
-                new Certificate[] {
-                generateCertificate(FAKE_DSA_USER_1), generateCertificate(FAKE_DSA_CA_1)
-        });
-    }
-
     private PrivateKeyEntry makeUserEcKey1() throws Exception {
         return new KeyStore.PrivateKeyEntry(generatePrivateKey("EC", FAKE_EC_KEY_1),
                 new Certificate[] {
@@ -1397,22 +1059,6 @@
         assertPrivateKeyEntryEquals(keyEntry, "RSA", FAKE_RSA_KEY_1, FAKE_RSA_USER_1, FAKE_RSA_CA_1);
     }
 
-    public void testKeyStore_GetEntry_DSA_NullParams_Unencrypted_Success() throws Exception {
-        mKeyStore.load(null, null);
-
-        // TEST_ALIAS_1
-        mKeyStore.setEntry(TEST_ALIAS_1, makeUserDsaKey1(), null);
-
-        Entry entry = mKeyStore.getEntry(TEST_ALIAS_1, null);
-        assertNotNull("Entry should exist", entry);
-
-        assertTrue("Should be a PrivateKeyEntry", entry instanceof PrivateKeyEntry);
-
-        PrivateKeyEntry keyEntry = (PrivateKeyEntry) entry;
-
-        assertPrivateKeyEntryEquals(keyEntry, "DSA", FAKE_DSA_KEY_1, FAKE_DSA_USER_1, FAKE_DSA_CA_1);
-    }
-
     public void testKeyStore_GetEntry_EC_NullParams_Unencrypted_Success() throws Exception {
         mKeyStore.load(null, null);
 
@@ -1471,18 +1117,18 @@
         final PrivateKey privKey = keyEntry.getPrivateKey();
         final PublicKey pubKey = keyEntry.getCertificate().getPublicKey();
 
-        if (expectedKey instanceof DSAPrivateKey) {
+        if (expectedKey instanceof ECKey) {
+            assertTrue("Returned PrivateKey " + privKey.getClass() + " should be instanceof ECKey",
+                    privKey instanceof ECKey);
             assertEquals("Returned PrivateKey should be what we inserted",
-                    ((DSAPrivateKey) expectedKey).getParams(),
-                    ((DSAPublicKey) pubKey).getParams());
-        } else if (expectedKey instanceof ECPrivateKey) {
+                    ((ECKey) expectedKey).getParams().getCurve(),
+                    ((ECKey) privKey).getParams().getCurve());
+        } else if (expectedKey instanceof RSAKey) {
+            assertTrue("Returned PrivateKey " + privKey.getClass() + " should be instanceof RSAKey",
+                    privKey instanceof RSAKey);
             assertEquals("Returned PrivateKey should be what we inserted",
-                    ((ECPrivateKey) expectedKey).getParams().getCurve(),
-                    ((ECPublicKey) pubKey).getParams().getCurve());
-        } else if (expectedKey instanceof RSAPrivateKey) {
-            assertEquals("Returned PrivateKey should be what we inserted",
-                    ((RSAPrivateKey) expectedKey).getModulus(),
-                    ((RSAPrivateKey) privKey).getModulus());
+                    ((RSAKey) expectedKey).getModulus(),
+                    ((RSAKey) privKey).getModulus());
         }
 
         assertNull("getFormat() should return null", privKey.getFormat());
@@ -1528,15 +1174,16 @@
         Key key = mKeyStore.getKey(TEST_ALIAS_1, null);
         assertNotNull("Key should exist", key);
 
-        assertTrue("Should be a RSAPrivateKey", key instanceof RSAPrivateKey);
+        assertTrue("Should be a PrivateKey", key instanceof PrivateKey);
+        assertTrue("Should be a RSAKey", key instanceof RSAKey);
 
-        RSAPrivateKey actualKey = (RSAPrivateKey) key;
+        RSAKey actualKey = (RSAKey) key;
 
         KeyFactory keyFact = KeyFactory.getInstance("RSA");
         PrivateKey expectedKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
 
         assertEquals("Inserted key should be same as retrieved key",
-                ((RSAPrivateKey) expectedKey).getModulus(), actualKey.getModulus());
+                ((RSAKey) expectedKey).getModulus(), actualKey.getModulus());
     }
 
     public void testKeyStore_GetKey_Certificate_Unencrypted_Failure() throws Exception {
@@ -2240,7 +1887,7 @@
                 0x00, 0x05, (byte) 0xAA, (byte) 0x0A5, (byte) 0xFF, 0x55, 0x0A
         };
 
-        SecretKey expectedSecret = new SecretKeySpec(expectedKey, "AES");
+        SecretKey expectedSecret = new TransparentSecretKey(expectedKey, "AES");
 
         byte[] wrappedExpected = c.wrap(expectedSecret);
 
@@ -2250,4 +1897,680 @@
         assertEquals(Arrays.toString(expectedSecret.getEncoded()),
                 Arrays.toString(actualSecret.getEncoded()));
     }
+
+    public void testKeyStore_Encrypting_RSA_NONE_NOPADDING() throws Exception {
+
+        String alias = "MyKey";
+        KeyStore ks = KeyStore.getInstance("AndroidKeyStore");
+        assertNotNull(ks);
+        ks.load(null);
+
+        Calendar cal = Calendar.getInstance();
+        cal.set(1944, 5, 6);
+        Date now = cal.getTime();
+        cal.clear();
+
+        cal.set(1945, 8, 2);
+        Date end = cal.getTime();
+
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
+        assertNotNull(kpg);
+        kpg.initialize(new KeyPairGeneratorSpec.Builder(mContext)
+                .setAlias(alias)
+                .setStartDate(now)
+                .setEndDate(end)
+                .setSerialNumber(BigInteger.valueOf(1))
+                .setSubject(new X500Principal("CN=test1"))
+                .build());
+
+        kpg.generateKeyPair();
+
+        PrivateKey privateKey = (PrivateKey) ks.getKey(alias, null);
+        assertNotNull(privateKey);
+        PublicKey publicKey = ks.getCertificate(alias).getPublicKey();
+        assertNotNull(publicKey);
+        String cipher = privateKey.getAlgorithm() + "/NONE/NOPADDING";
+        Cipher encrypt = Cipher.getInstance(cipher);
+        assertNotNull(encrypt);
+        encrypt.init(Cipher.ENCRYPT_MODE, privateKey);
+
+        int modulusSizeBytes = (((RSAKey) publicKey).getModulus().bitLength() + 7) / 8;
+        byte[] plainText = new byte[modulusSizeBytes];
+        Arrays.fill(plainText, (byte) 0xFF);
+
+        // We expect a BadPaddingException here as the message size (plaintext)
+        // is bigger than the modulus.
+        try {
+            encrypt.doFinal(plainText);
+            fail("Expected BadPaddingException");
+        } catch (BadPaddingException e) {
+            // pass on exception as it is expected
+        }
+    }
+
+    public void testKeyStore_PrivateKeyEntry_RSA_PublicKeyWorksWithCrypto()
+            throws Exception {
+        mKeyStore.load(null, null);
+        mKeyStore.setKeyEntry(TEST_ALIAS_2,
+                KeyFactory.getInstance("RSA").generatePrivate(
+                        new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1)),
+                null, // no password (it's not even supported)
+                new Certificate[] {generateCertificate(FAKE_RSA_USER_1)});
+        PublicKey publicKey = mKeyStore.getCertificate(TEST_ALIAS_2).getPublicKey();
+        assertNotNull(publicKey);
+
+        Signature.getInstance("SHA256withRSA").initVerify(publicKey);
+        Signature.getInstance("NONEwithRSA").initVerify(publicKey);
+        Signature.getInstance("SHA256withRSA/PSS").initVerify(publicKey);
+
+        Cipher.getInstance("RSA/ECB/PKCS1Padding").init(Cipher.ENCRYPT_MODE, publicKey);
+        Cipher.getInstance("RSA/ECB/NoPadding").init(Cipher.ENCRYPT_MODE, publicKey);
+        Cipher.getInstance("RSA/ECB/OAEPPadding").init(Cipher.ENCRYPT_MODE, publicKey);
+    }
+
+    public void testKeyStore_PrivateKeyEntry_EC_PublicKeyWorksWithCrypto()
+            throws Exception {
+        mKeyStore.load(null, null);
+        mKeyStore.setKeyEntry(TEST_ALIAS_1,
+                KeyFactory.getInstance("EC").generatePrivate(
+                        new PKCS8EncodedKeySpec(FAKE_EC_KEY_1)),
+                null, // no password (it's not even supported)
+                new Certificate[] {generateCertificate(FAKE_EC_USER_1)});
+        PublicKey publicKey = mKeyStore.getCertificate(TEST_ALIAS_1).getPublicKey();
+        assertNotNull(publicKey);
+
+        Signature.getInstance("SHA256withECDSA").initVerify(publicKey);
+        Signature.getInstance("NONEwithECDSA").initVerify(publicKey);
+    }
+
+    public void testKeyStore_TrustedCertificateEntry_RSA_PublicKeyWorksWithCrypto()
+            throws Exception {
+        mKeyStore.load(null, null);
+        mKeyStore.setCertificateEntry(TEST_ALIAS_2, generateCertificate(FAKE_RSA_USER_1));
+        PublicKey publicKey = mKeyStore.getCertificate(TEST_ALIAS_2).getPublicKey();
+        assertNotNull(publicKey);
+
+        Signature.getInstance("SHA256withRSA").initVerify(publicKey);
+        Signature.getInstance("NONEwithRSA").initVerify(publicKey);
+
+        Cipher.getInstance("RSA/ECB/PKCS1Padding").init(Cipher.ENCRYPT_MODE, publicKey);
+        Cipher.getInstance("RSA/ECB/NoPadding").init(Cipher.ENCRYPT_MODE, publicKey);
+    }
+
+    public void testKeyStore_TrustedCertificateEntry_EC_PublicKeyWorksWithCrypto()
+            throws Exception {
+        mKeyStore.load(null, null);
+        mKeyStore.setCertificateEntry(TEST_ALIAS_1, generateCertificate(FAKE_EC_USER_1));
+        PublicKey publicKey = mKeyStore.getCertificate(TEST_ALIAS_1).getPublicKey();
+        assertNotNull(publicKey);
+
+        Signature.getInstance("SHA256withECDSA").initVerify(publicKey);
+        Signature.getInstance("NONEwithECDSA").initVerify(publicKey);
+    }
+
+    private static final int MIN_SUPPORTED_KEY_COUNT = 1500;
+    private static final long MINUTE_IN_MILLIS = 1000 * 60;
+    private static final long LARGE_NUMBER_OF_KEYS_TEST_MAX_DURATION_MILLIS = 2 * MINUTE_IN_MILLIS;
+
+    private static boolean isDeadlineReached(long startTimeMillis, long durationMillis) {
+        long nowMillis = System.currentTimeMillis();
+        if (nowMillis < startTimeMillis) {
+            return true;
+        }
+        return nowMillis - startTimeMillis > durationMillis;
+    }
+
+    @LargeTest
+    public void testKeyStore_LargeNumberOfKeysSupported_RSA() throws Exception {
+        // This test imports key1, then lots of other keys, then key2, and then confirms that
+        // key1 and key2 backed by Android Keystore work fine. The assumption is that if the
+        // underlying implementation has a limit on the number of keys, it'll either delete the
+        // oldest key (key1), or will refuse to add keys (key2).
+        // The test imports as many keys as it can in a fixed amount of time instead of stopping
+        // at MIN_SUPPORTED_KEY_COUNT to balance the desire to support an unlimited number of keys
+        // with the constraints on how long the test can run and performance differences of hardware
+        // under test.
+
+        long testStartTimeMillis = System.currentTimeMillis();
+
+        Certificate cert1 = TestUtils.getRawResX509Certificate(getContext(), R.raw.rsa_key1_cert);
+        PrivateKey privateKey1 = TestUtils.getRawResPrivateKey(getContext(), R.raw.rsa_key1_pkcs8);
+        String entryName1 = "test0";
+
+        Certificate cert2 = TestUtils.getRawResX509Certificate(getContext(), R.raw.rsa_key2_cert);
+        PrivateKey privateKey2 = TestUtils.getRawResPrivateKey(getContext(), R.raw.rsa_key2_pkcs8);
+
+        Certificate cert3 = generateCertificate(FAKE_RSA_USER_1);
+        PrivateKey privateKey3 = generatePrivateKey("RSA", FAKE_RSA_KEY_1);
+
+        mKeyStore.load(null);
+        int latestImportedEntryNumber = 0;
+        try {
+            KeyProtection protectionParams = new KeyProtection.Builder(
+                    KeyProperties.PURPOSE_SIGN)
+                    .setDigests(KeyProperties.DIGEST_SHA256)
+                    .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                    .build();
+            mKeyStore.setEntry(entryName1,
+                    new KeyStore.PrivateKeyEntry(privateKey1, new Certificate[] {cert1}),
+                    protectionParams);
+
+            // Import key3 lots of times, under different aliases.
+            while (!isDeadlineReached(
+                    testStartTimeMillis, LARGE_NUMBER_OF_KEYS_TEST_MAX_DURATION_MILLIS)) {
+                latestImportedEntryNumber++;
+                if ((latestImportedEntryNumber % 1000) == 0) {
+                    Log.i(TAG, "Imported " + latestImportedEntryNumber + " keys");
+                }
+                String entryAlias = "test" + latestImportedEntryNumber;
+                try {
+                    mKeyStore.setEntry(entryAlias,
+                            new KeyStore.PrivateKeyEntry(privateKey3, new Certificate[] {cert3}),
+                            protectionParams);
+                } catch (Throwable e) {
+                    throw new RuntimeException("Entry " + entryAlias + " import failed", e);
+                }
+            }
+            Log.i(TAG, "Imported " + latestImportedEntryNumber + " keys");
+            if (latestImportedEntryNumber < MIN_SUPPORTED_KEY_COUNT) {
+                fail("Failed to import " + MIN_SUPPORTED_KEY_COUNT + " keys in "
+                        + (System.currentTimeMillis() - testStartTimeMillis)
+                        + " ms. Imported: " + latestImportedEntryNumber + " keys");
+            }
+
+            latestImportedEntryNumber++;
+            String entryName2 = "test" + latestImportedEntryNumber;
+            mKeyStore.setEntry(entryName2,
+                    new KeyStore.PrivateKeyEntry(privateKey2, new Certificate[] {cert2}),
+                    protectionParams);
+            PrivateKey keystorePrivateKey2 = (PrivateKey) mKeyStore.getKey(entryName2, null);
+            PrivateKey keystorePrivateKey1 = (PrivateKey) mKeyStore.getKey(entryName1, null);
+
+            byte[] message = "This is a test".getBytes("UTF-8");
+
+            Signature sig = Signature.getInstance("SHA256withRSA");
+            sig.initSign(keystorePrivateKey1);
+            sig.update(message);
+            byte[] signature = sig.sign();
+            sig = Signature.getInstance(sig.getAlgorithm());
+            sig.initVerify(cert1.getPublicKey());
+            sig.update(message);
+            assertTrue(sig.verify(signature));
+
+            sig = Signature.getInstance(sig.getAlgorithm());
+            sig.initSign(keystorePrivateKey2);
+            sig.update(message);
+            signature = sig.sign();
+            sig = Signature.getInstance(sig.getAlgorithm());
+            sig.initVerify(cert2.getPublicKey());
+            sig.update(message);
+            assertTrue(sig.verify(signature));
+        } finally {
+            // Clean up Keystore without using KeyStore.aliases() which can't handle this many
+            // entries.
+            Log.i(TAG, "Deleting imported keys");
+            for (int i = 0; i <= latestImportedEntryNumber; i++) {
+                if ((i > 0) && ((i % 1000) == 0)) {
+                    Log.i(TAG, "Deleted " + i + " keys");
+                }
+                mKeyStore.deleteEntry("test" + i);
+            }
+            Log.i(TAG, "Deleted " + (latestImportedEntryNumber + 1) + " keys");
+        }
+    }
+
+    @LargeTest
+    public void testKeyStore_LargeNumberOfKeysSupported_EC() throws Exception {
+        // This test imports key1, then lots of other keys, then key2, and then confirms that
+        // key1 and key2 backed by Android Keystore work fine. The assumption is that if the
+        // underlying implementation has a limit on the number of keys, it'll either delete the
+        // oldest key (key1), or will refuse to add keys (key2).
+        // The test imports as many keys as it can in a fixed amount of time instead of stopping
+        // at MIN_SUPPORTED_KEY_COUNT to balance the desire to support an unlimited number of keys
+        // with the constraints on how long the test can run and performance differences of hardware
+        // under test.
+
+        long testStartTimeMillis = System.currentTimeMillis();
+
+        Certificate cert1 = TestUtils.getRawResX509Certificate(getContext(), R.raw.ec_key1_cert);
+        PrivateKey privateKey1 = TestUtils.getRawResPrivateKey(getContext(), R.raw.ec_key1_pkcs8);
+        String entryName1 = "test0";
+
+        Certificate cert2 = TestUtils.getRawResX509Certificate(getContext(), R.raw.ec_key2_cert);
+        PrivateKey privateKey2 = TestUtils.getRawResPrivateKey(getContext(), R.raw.ec_key2_pkcs8);
+
+        Certificate cert3 = generateCertificate(FAKE_EC_USER_1);
+        PrivateKey privateKey3 = generatePrivateKey("EC", FAKE_EC_KEY_1);
+
+        mKeyStore.load(null);
+        int latestImportedEntryNumber = 0;
+        try {
+            KeyProtection protectionParams = new KeyProtection.Builder(
+                    KeyProperties.PURPOSE_SIGN)
+                    .setDigests(KeyProperties.DIGEST_SHA256)
+                    .build();
+            mKeyStore.setEntry(entryName1,
+                    new KeyStore.PrivateKeyEntry(privateKey1, new Certificate[] {cert1}),
+                    protectionParams);
+
+            // Import key3 lots of times, under different aliases.
+            while (!isDeadlineReached(
+                    testStartTimeMillis, LARGE_NUMBER_OF_KEYS_TEST_MAX_DURATION_MILLIS)) {
+                latestImportedEntryNumber++;
+                if ((latestImportedEntryNumber % 1000) == 0) {
+                    Log.i(TAG, "Imported " + latestImportedEntryNumber + " keys");
+                }
+                String entryAlias = "test" + latestImportedEntryNumber;
+                try {
+                    mKeyStore.setEntry(entryAlias,
+                            new KeyStore.PrivateKeyEntry(privateKey3, new Certificate[] {cert3}),
+                            protectionParams);
+                } catch (Throwable e) {
+                    throw new RuntimeException("Entry " + entryAlias + " import failed", e);
+                }
+            }
+            Log.i(TAG, "Imported " + latestImportedEntryNumber + " keys");
+            if (latestImportedEntryNumber < MIN_SUPPORTED_KEY_COUNT) {
+                fail("Failed to import " + MIN_SUPPORTED_KEY_COUNT + " keys in "
+                        + (System.currentTimeMillis() - testStartTimeMillis)
+                        + " ms. Imported: " + latestImportedEntryNumber + " keys");
+            }
+
+            latestImportedEntryNumber++;
+            String entryName2 = "test" + latestImportedEntryNumber;
+            mKeyStore.setEntry(entryName2,
+                    new KeyStore.PrivateKeyEntry(privateKey2, new Certificate[] {cert2}),
+                    protectionParams);
+            PrivateKey keystorePrivateKey2 = (PrivateKey) mKeyStore.getKey(entryName2, null);
+            PrivateKey keystorePrivateKey1 = (PrivateKey) mKeyStore.getKey(entryName1, null);
+
+            byte[] message = "This is a test".getBytes("UTF-8");
+
+            Signature sig = Signature.getInstance("SHA256withECDSA");
+            sig.initSign(keystorePrivateKey1);
+            sig.update(message);
+            byte[] signature = sig.sign();
+            sig = Signature.getInstance(sig.getAlgorithm());
+            sig.initVerify(cert1.getPublicKey());
+            sig.update(message);
+            assertTrue(sig.verify(signature));
+
+            sig = Signature.getInstance(sig.getAlgorithm());
+            sig.initSign(keystorePrivateKey2);
+            sig.update(message);
+            signature = sig.sign();
+            sig = Signature.getInstance(sig.getAlgorithm());
+            sig.initVerify(cert2.getPublicKey());
+            sig.update(message);
+            assertTrue(sig.verify(signature));
+        } finally {
+            // Clean up Keystore without using KeyStore.aliases() which can't handle this many
+            // entries.
+            Log.i(TAG, "Deleting imported keys");
+            for (int i = 0; i <= latestImportedEntryNumber; i++) {
+                if ((i > 0) && ((i % 1000) == 0)) {
+                    Log.i(TAG, "Deleted " + i + " keys");
+                }
+                mKeyStore.deleteEntry("test" + i);
+            }
+            Log.i(TAG, "Deleted " + (latestImportedEntryNumber + 1) + " keys");
+        }
+    }
+
+    @LargeTest
+    public void testKeyStore_LargeNumberOfKeysSupported_AES() throws Exception {
+        // This test imports key1, then lots of other keys, then key2, and then confirms that
+        // key1 and key2 backed by Android Keystore work fine. The assumption is that if the
+        // underlying implementation has a limit on the number of keys, it'll either delete the
+        // oldest key (key1), or will refuse to add keys (key2).
+        // The test imports as many keys as it can in a fixed amount of time instead of stopping
+        // at MIN_SUPPORTED_KEY_COUNT to balance the desire to support an unlimited number of keys
+        // with the constraints on how long the test can run and performance differences of hardware
+        // under test.
+
+        long testStartTimeMillis = System.currentTimeMillis();
+
+        SecretKey key1 = new TransparentSecretKey(
+                HexEncoding.decode("010203040506070809fafbfcfdfeffcc"), "AES");
+        String entryName1 = "test0";
+
+        SecretKey key2 = new TransparentSecretKey(
+                HexEncoding.decode("808182838485868788897a7b7c7d7e7f"), "AES");
+
+        SecretKey key3 = new TransparentSecretKey(
+                HexEncoding.decode("33333333333333333333777777777777"), "AES");
+
+        mKeyStore.load(null);
+        int latestImportedEntryNumber = 0;
+        try {
+            KeyProtection protectionParams = new KeyProtection.Builder(
+                    KeyProperties.PURPOSE_ENCRYPT)
+                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                    .build();
+            mKeyStore.setEntry(entryName1, new KeyStore.SecretKeyEntry(key1), protectionParams);
+
+            // Import key3 lots of times, under different aliases.
+            while (!isDeadlineReached(
+                    testStartTimeMillis, LARGE_NUMBER_OF_KEYS_TEST_MAX_DURATION_MILLIS)) {
+                latestImportedEntryNumber++;
+                if ((latestImportedEntryNumber % 1000) == 0) {
+                    Log.i(TAG, "Imported " + latestImportedEntryNumber + " keys");
+                }
+                String entryAlias = "test" + latestImportedEntryNumber;
+                try {
+                    mKeyStore.setEntry(entryAlias,
+                            new KeyStore.SecretKeyEntry(key3), protectionParams);
+                } catch (Throwable e) {
+                    throw new RuntimeException("Entry " + entryAlias + " import failed", e);
+                }
+            }
+            Log.i(TAG, "Imported " + latestImportedEntryNumber + " keys");
+            if (latestImportedEntryNumber < MIN_SUPPORTED_KEY_COUNT) {
+                fail("Failed to import " + MIN_SUPPORTED_KEY_COUNT + " keys in "
+                        + (System.currentTimeMillis() - testStartTimeMillis)
+                        + " ms. Imported: " + latestImportedEntryNumber + " keys");
+            }
+
+            latestImportedEntryNumber++;
+            String entryName2 = "test" + latestImportedEntryNumber;
+            mKeyStore.setEntry(entryName2, new KeyStore.SecretKeyEntry(key2), protectionParams);
+            SecretKey keystoreKey2 = (SecretKey) mKeyStore.getKey(entryName2, null);
+            SecretKey keystoreKey1 = (SecretKey) mKeyStore.getKey(entryName1, null);
+
+            byte[] plaintext = "This is a test".getBytes("UTF-8");
+            Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
+            cipher.init(Cipher.ENCRYPT_MODE, keystoreKey1);
+            byte[] ciphertext = cipher.doFinal(plaintext);
+            AlgorithmParameters cipherParams = cipher.getParameters();
+            cipher = Cipher.getInstance(cipher.getAlgorithm());
+            cipher.init(Cipher.DECRYPT_MODE, key1, cipherParams);
+            MoreAsserts.assertEquals(plaintext, cipher.doFinal(ciphertext));
+
+            cipher = Cipher.getInstance(cipher.getAlgorithm());
+            cipher.init(Cipher.ENCRYPT_MODE, keystoreKey2);
+            ciphertext = cipher.doFinal(plaintext);
+            cipherParams = cipher.getParameters();
+            cipher = Cipher.getInstance(cipher.getAlgorithm());
+            cipher.init(Cipher.DECRYPT_MODE, key2, cipherParams);
+            MoreAsserts.assertEquals(plaintext, cipher.doFinal(ciphertext));
+        } finally {
+            // Clean up Keystore without using KeyStore.aliases() which can't handle this many
+            // entries.
+            Log.i(TAG, "Deleting imported keys");
+            for (int i = 0; i <= latestImportedEntryNumber; i++) {
+                if ((i > 0) && ((i % 1000) == 0)) {
+                    Log.i(TAG, "Deleted " + i + " keys");
+                }
+                mKeyStore.deleteEntry("test" + i);
+            }
+            Log.i(TAG, "Deleted " + (latestImportedEntryNumber + 1) + " keys");
+        }
+    }
+
+    @LargeTest
+    public void testKeyStore_LargeNumberOfKeysSupported_HMAC() throws Exception {
+        // This test imports key1, then lots of other keys, then key2, and then confirms that
+        // key1 and key2 backed by Android Keystore work fine. The assumption is that if the
+        // underlying implementation has a limit on the number of keys, it'll either delete the
+        // oldest key (key1), or will refuse to add keys (key2).
+        // The test imports as many keys as it can in a fixed amount of time instead of stopping
+        // at MIN_SUPPORTED_KEY_COUNT to balance the desire to support an unlimited number of keys
+        // with the constraints on how long the test can run and performance differences of hardware
+        // under test.
+
+        long testStartTimeMillis = System.currentTimeMillis();
+
+        SecretKey key1 = new TransparentSecretKey(
+                HexEncoding.decode("010203040506070809fafbfcfdfeffcc"), "HmacSHA256");
+        String entryName1 = "test0";
+
+        SecretKey key2 = new TransparentSecretKey(
+                HexEncoding.decode("808182838485868788897a7b7c7d7e7f"), "HmacSHA256");
+
+        SecretKey key3 = new TransparentSecretKey(
+                HexEncoding.decode("33333333333333333333777777777777"), "HmacSHA256");
+
+        mKeyStore.load(null);
+        int latestImportedEntryNumber = 0;
+        try {
+            KeyProtection protectionParams = new KeyProtection.Builder(
+                    KeyProperties.PURPOSE_SIGN)
+                    .build();
+            mKeyStore.setEntry(entryName1, new KeyStore.SecretKeyEntry(key1), protectionParams);
+
+            // Import key3 lots of times, under different aliases.
+            while (!isDeadlineReached(
+                    testStartTimeMillis, LARGE_NUMBER_OF_KEYS_TEST_MAX_DURATION_MILLIS)) {
+                latestImportedEntryNumber++;
+                if ((latestImportedEntryNumber % 1000) == 0) {
+                    Log.i(TAG, "Imported " + latestImportedEntryNumber + " keys");
+                }
+                String entryAlias = "test" + latestImportedEntryNumber;
+                try {
+                    mKeyStore.setEntry(entryAlias,
+                            new KeyStore.SecretKeyEntry(key3), protectionParams);
+                } catch (Throwable e) {
+                    throw new RuntimeException("Entry " + entryAlias + " import failed", e);
+                }
+            }
+            Log.i(TAG, "Imported " + latestImportedEntryNumber + " keys");
+            if (latestImportedEntryNumber < MIN_SUPPORTED_KEY_COUNT) {
+                fail("Failed to import " + MIN_SUPPORTED_KEY_COUNT + " keys in "
+                        + (System.currentTimeMillis() - testStartTimeMillis)
+                        + " ms. Imported: " + latestImportedEntryNumber + " keys");
+            }
+
+            latestImportedEntryNumber++;
+            String entryName2 = "test" + latestImportedEntryNumber;
+            mKeyStore.setEntry(entryName2, new KeyStore.SecretKeyEntry(key2), protectionParams);
+            SecretKey keystoreKey2 = (SecretKey) mKeyStore.getKey(entryName2, null);
+            SecretKey keystoreKey1 = (SecretKey) mKeyStore.getKey(entryName1, null);
+
+            byte[] message = "This is a test".getBytes("UTF-8");
+            Mac mac = Mac.getInstance(key1.getAlgorithm());
+            mac.init(keystoreKey1);
+            MoreAsserts.assertEquals(
+                    HexEncoding.decode(
+                            "905e36f5a175f4ca54ad56b860b46f6502f883a90628dca2d33a953fb7224eaf"),
+                    mac.doFinal(message));
+
+            mac = Mac.getInstance(key2.getAlgorithm());
+            mac.init(keystoreKey2);
+            MoreAsserts.assertEquals(
+                    HexEncoding.decode(
+                            "59b57e77e4e2cb36b5c7b84af198ac004327bc549de6931a1b5505372dd8c957"),
+                    mac.doFinal(message));
+        } finally {
+            // Clean up Keystore without using KeyStore.aliases() which can't handle this many
+            // entries.
+            Log.i(TAG, "Deleting imported keys");
+            for (int i = 0; i <= latestImportedEntryNumber; i++) {
+                if ((i > 0) && ((i % 1000) == 0)) {
+                    Log.i(TAG, "Deleted " + i + " keys");
+                }
+                mKeyStore.deleteEntry("test" + i);
+            }
+            Log.i(TAG, "Deleted " + (latestImportedEntryNumber + 1) + " keys");
+        }
+    }
+
+    public void testKeyStore_OnlyOneDigestCanBeAuthorized_HMAC() throws Exception {
+        mKeyStore.load(null);
+
+        for (String algorithm : KeyGeneratorTest.EXPECTED_ALGORITHMS) {
+            if (!TestUtils.isHmacAlgorithm(algorithm)) {
+                continue;
+            }
+            try {
+                String digest = TestUtils.getHmacAlgorithmDigest(algorithm);
+                assertNotNull(digest);
+                SecretKey keyBeingImported = new TransparentSecretKey(new byte[16], algorithm);
+
+                KeyProtection.Builder goodSpec =
+                        new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN);
+
+                // Digests authorization not specified in import parameters
+                assertFalse(goodSpec.build().isDigestsSpecified());
+                mKeyStore.setEntry(TEST_ALIAS_1,
+                        new KeyStore.SecretKeyEntry(keyBeingImported),
+                        goodSpec.build());
+                SecretKey key = (SecretKey) mKeyStore.getKey(TEST_ALIAS_1, null);
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(TestUtils.getKeyInfo(key).getDigests()), digest);
+
+                // The same digest is specified in import parameters
+                mKeyStore.setEntry(TEST_ALIAS_1,
+                        new KeyStore.SecretKeyEntry(keyBeingImported),
+                        TestUtils.buildUpon(goodSpec).setDigests(digest).build());
+                key = (SecretKey) mKeyStore.getKey(TEST_ALIAS_1, null);
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(TestUtils.getKeyInfo(key).getDigests()), digest);
+
+                // Empty set of digests specified in import parameters
+                try {
+                    mKeyStore.setEntry(TEST_ALIAS_1,
+                            new KeyStore.SecretKeyEntry(keyBeingImported),
+                            TestUtils.buildUpon(goodSpec).setDigests().build());
+                    fail();
+                } catch (KeyStoreException expected) {}
+
+                // A different digest specified in import parameters
+                String anotherDigest = "SHA-256".equalsIgnoreCase(digest) ? "SHA-384" : "SHA-256";
+                try {
+                    mKeyStore.setEntry(TEST_ALIAS_1,
+                            new KeyStore.SecretKeyEntry(keyBeingImported),
+                            TestUtils.buildUpon(goodSpec).setDigests(anotherDigest).build());
+                    fail();
+                } catch (KeyStoreException expected) {}
+                try {
+                    mKeyStore.setEntry(TEST_ALIAS_1,
+                            new KeyStore.SecretKeyEntry(keyBeingImported),
+                            TestUtils.buildUpon(goodSpec)
+                                    .setDigests(digest, anotherDigest)
+                                    .build());
+                    fail();
+                } catch (KeyStoreException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testKeyStore_ImportSupportedSizes_AES() throws Exception {
+        mKeyStore.load(null);
+
+        KeyProtection params = new KeyProtection.Builder(
+                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                .build();
+        String alias = "test1";
+        mKeyStore.deleteEntry(alias);
+        assertFalse(mKeyStore.containsAlias(alias));
+        for (int keySizeBytes = 0; keySizeBytes <= 512 / 8; keySizeBytes++) {
+            int keySizeBits = keySizeBytes * 8;
+            try {
+                KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(
+                        new TransparentSecretKey(new byte[keySizeBytes], "AES"));
+                if (TestUtils.contains(KeyGeneratorTest.AES_SUPPORTED_KEY_SIZES, keySizeBits)) {
+                    mKeyStore.setEntry(alias, entry, params);
+                    SecretKey key = (SecretKey) mKeyStore.getKey(alias, null);
+                    assertEquals("AES", key.getAlgorithm());
+                    assertEquals(keySizeBits, TestUtils.getKeyInfo(key).getKeySize());
+                } else {
+                    mKeyStore.deleteEntry(alias);
+                    assertFalse(mKeyStore.containsAlias(alias));
+                    try {
+                        mKeyStore.setEntry(alias, entry, params);
+                        fail();
+                    } catch (KeyStoreException expected) {}
+                    assertFalse(mKeyStore.containsAlias(alias));
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for key size " + keySizeBits, e);
+            }
+        }
+    }
+
+    public void testKeyStore_ImportSupportedSizes_HMAC() throws Exception {
+        mKeyStore.load(null);
+
+        KeyProtection params = new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build();
+        String alias = "test1";
+        mKeyStore.deleteEntry(alias);
+        assertFalse(mKeyStore.containsAlias(alias));
+        for (String algorithm : KeyGeneratorTest.EXPECTED_ALGORITHMS) {
+            if (!TestUtils.isHmacAlgorithm(algorithm)) {
+                continue;
+            }
+            for (int keySizeBytes = 0; keySizeBytes <= 1024 / 8; keySizeBytes++) {
+                try {
+                    KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(
+                            new TransparentSecretKey(new byte[keySizeBytes], algorithm));
+                    if (keySizeBytes > 0) {
+                        mKeyStore.setEntry(alias, entry, params);
+                        SecretKey key = (SecretKey) mKeyStore.getKey(alias, null);
+                        assertEquals(algorithm, key.getAlgorithm());
+                        assertEquals(keySizeBytes * 8, TestUtils.getKeyInfo(key).getKeySize());
+                    } else {
+                        mKeyStore.deleteEntry(alias);
+                        assertFalse(mKeyStore.containsAlias(alias));
+                        try {
+                            mKeyStore.setEntry(alias, entry, params);
+                            fail();
+                        } catch (KeyStoreException expected) {}
+                    }
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key size " + (keySizeBytes * 8), e);
+                }
+            }
+        }
+    }
+
+    public void testKeyStore_ImportSupportedSizes_EC() throws Exception {
+        mKeyStore.load(null);
+        KeyProtection params =
+                TestUtils.getMinimalWorkingImportParametersForSigningingWith("SHA256withECDSA");
+        checkKeyPairImportSucceeds(
+                "secp224r1", R.raw.ec_key3_secp224r1_pkcs8, R.raw.ec_key3_secp224r1_cert, params);
+        checkKeyPairImportSucceeds(
+                "secp256r1", R.raw.ec_key4_secp256r1_pkcs8, R.raw.ec_key4_secp256r1_cert, params);
+        checkKeyPairImportSucceeds(
+                "secp384r1", R.raw.ec_key5_secp384r1_pkcs8, R.raw.ec_key5_secp384r1_cert, params);
+        checkKeyPairImportSucceeds(
+                "secp512r1", R.raw.ec_key6_secp521r1_pkcs8, R.raw.ec_key6_secp521r1_cert, params);
+    }
+
+    public void testKeyStore_ImportSupportedSizes_RSA() throws Exception {
+        mKeyStore.load(null);
+        KeyProtection params =
+                TestUtils.getMinimalWorkingImportParametersForSigningingWith("SHA256withRSA");
+        checkKeyPairImportSucceeds(
+                "512", R.raw.rsa_key5_512_pkcs8, R.raw.rsa_key5_512_cert, params);
+        checkKeyPairImportSucceeds(
+                "768", R.raw.rsa_key6_768_pkcs8, R.raw.rsa_key6_768_cert, params);
+        checkKeyPairImportSucceeds(
+                "1024", R.raw.rsa_key3_1024_pkcs8, R.raw.rsa_key3_1024_cert, params);
+        checkKeyPairImportSucceeds(
+                "2048", R.raw.rsa_key8_2048_pkcs8, R.raw.rsa_key8_2048_cert, params);
+        checkKeyPairImportSucceeds(
+                "3072", R.raw.rsa_key7_3072_pksc8, R.raw.rsa_key7_3072_cert, params);
+        checkKeyPairImportSucceeds(
+                "4096", R.raw.rsa_key4_4096_pkcs8, R.raw.rsa_key4_4096_cert, params);
+    }
+
+    private void checkKeyPairImportSucceeds(
+            String alias, int privateResId, int certResId, KeyProtection params) throws Exception {
+        try {
+            mKeyStore.deleteEntry(alias);
+            TestUtils.importIntoAndroidKeyStore(
+                    alias, getContext(), privateResId, certResId, params);
+        } catch (Throwable e) {
+            throw new RuntimeException("Failed for " + alias, e);
+        } finally {
+            try {
+                mKeyStore.deleteEntry(alias);
+            } catch (Exception ignored) {}
+        }
+    }
 }
diff --git a/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
new file mode 100644
index 0000000..66e8093
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/BlockCipherTestBase.java
@@ -0,0 +1,1648 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.test.AndroidTestCase;
+
+import junit.framework.AssertionFailedError;
+
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.security.AlgorithmParameters;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.InvalidParameterSpecException;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Locale;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKey;
+import javax.crypto.ShortBufferException;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+abstract class BlockCipherTestBase extends AndroidTestCase {
+
+    private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_CRYPTO_OP_PROVIDER_NAME;
+
+    private KeyStore mAndroidKeyStore;
+    private int mNextKeyId;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mAndroidKeyStore = KeyStore.getInstance("AndroidKeyStore");
+        mAndroidKeyStore.load(null);
+        for (Enumeration<String> e = mAndroidKeyStore.aliases(); e.hasMoreElements();) {
+            mAndroidKeyStore.deleteEntry(e.nextElement());
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            for (Enumeration<String> e = mAndroidKeyStore.aliases(); e.hasMoreElements();) {
+                mAndroidKeyStore.deleteEntry(e.nextElement());
+            }
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    protected abstract String getTransformation();
+    protected abstract int getBlockSize();
+
+    protected abstract byte[] getKatKey();
+    protected abstract byte[] getKatIv();
+    protected abstract AlgorithmParameterSpec getKatAlgorithmParameterSpec();
+    protected abstract byte[] getKatPlaintext();
+    protected abstract byte[] getKatCiphertext();
+    protected abstract int getKatAuthenticationTagLengthBytes();
+    protected abstract boolean isStreamCipher();
+    protected abstract boolean isAuthenticatedCipher();
+
+    protected abstract byte[] getIv(AlgorithmParameters params)
+            throws InvalidParameterSpecException;
+
+    private byte[] getKatInput(int opmode) {
+        switch (opmode) {
+            case Cipher.ENCRYPT_MODE:
+                return getKatPlaintext();
+            case Cipher.DECRYPT_MODE:
+                return getKatCiphertext();
+            default:
+                throw new IllegalArgumentException("Invalid opmode: " + opmode);
+        }
+    }
+
+    private byte[] getKatOutput(int opmode) {
+        switch (opmode) {
+            case Cipher.ENCRYPT_MODE:
+                return getKatCiphertext();
+            case Cipher.DECRYPT_MODE:
+                return getKatPlaintext();
+            default:
+                throw new IllegalArgumentException("Invalid opmode: " + opmode);
+        }
+    }
+
+    private Cipher mCipher;
+    private int mOpmode;
+
+    public void testGetAlgorithm() throws Exception {
+        createCipher();
+        assertEquals(getTransformation(), mCipher.getAlgorithm());
+    }
+
+    public void testGetProvider() throws Exception {
+        createCipher();
+        Provider expectedProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertSame(expectedProvider, mCipher.getProvider());
+    }
+
+    public void testGetBlockSize() throws Exception {
+        createCipher();
+        assertEquals(getBlockSize(), mCipher.getBlockSize());
+    }
+
+    public void testGetExemptionMechanism() throws Exception {
+        createCipher();
+        assertNull(mCipher.getExemptionMechanism());
+    }
+
+    public void testGetParameters() throws Exception {
+        createCipher();
+        assertAlgoritmParametersIv(null);
+
+        initKat(Cipher.ENCRYPT_MODE);
+        assertAlgoritmParametersIv(getKatIv());
+        doFinal(getKatPlaintext());
+        assertAlgoritmParametersIv(getKatIv());
+
+        initKat(Cipher.DECRYPT_MODE);
+        assertAlgoritmParametersIv(getKatIv());
+        doFinal(getKatCiphertext());
+        assertAlgoritmParametersIv(getKatIv());
+    }
+
+    private void assertAlgoritmParametersIv(byte[] expectedIv)
+            throws InvalidParameterSpecException {
+        AlgorithmParameters actualParameters = mCipher.getParameters();
+        if (expectedIv == null) {
+            assertNull(actualParameters);
+        } else {
+            byte[] actualIv = getIv(actualParameters);
+            assertEquals(expectedIv, actualIv);
+        }
+    }
+
+    public void testGetOutputSizeInEncryptionMode() throws Exception {
+        int blockSize = getBlockSize();
+        createCipher();
+        try {
+            mCipher.getOutputSize(blockSize);
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        initKat(Cipher.ENCRYPT_MODE);
+        if (isAuthenticatedCipher()) {
+            // Authenticated ciphers do not return any output when decrypting until doFinal where
+            // ciphertext is authenticated.
+            for (int input = 0; input <= blockSize * 2; input++) {
+                int actualOutputSize = mCipher.getOutputSize(input);
+                int expectedOutputSize = input + getKatAuthenticationTagLengthBytes();
+                if (actualOutputSize < expectedOutputSize) {
+                    fail("getOutputSize(" + expectedOutputSize + ") underestimated output size"
+                            + ". min expected: <" + expectedOutputSize
+                            + ">, actual: <" + actualOutputSize + ">");
+                }
+            }
+            return;
+        } else if (isStreamCipher()) {
+            // Unauthenticated stream ciphers do not buffer input or output.
+            for (int input = 0; input <= blockSize * 2; input++) {
+                int actualOutputSize = mCipher.getOutputSize(input);
+                if (actualOutputSize < input) {
+                    fail("getOutputSize(" + input + ") underestimated output size. min expected: <"
+                            + input + ">, actual: <" + actualOutputSize + ">");
+                }
+            }
+            return;
+        }
+        // Not a stream cipher -- input may be buffered.
+
+        for (int buffered = 0; buffered < blockSize; buffered++) {
+            // Assert that the output of getOutputSize is not lower than the minimum expected.
+            for (int input = 0; input <= blockSize * 2; input++) {
+                int inputInclBuffered = buffered + input;
+                // doFinal dominates the output size.
+                // One full plaintext block results in one ciphertext block.
+                int minExpectedOutputSize = inputInclBuffered - (inputInclBuffered % blockSize);
+                if (isPaddingEnabled()) {
+                    // Regardless of whether there is a partial input block, an additional block of
+                    // ciphertext should be output.
+                    minExpectedOutputSize += blockSize;
+                } else {
+                    // When no padding is enabled, any remaining partial block of plaintext will
+                    // cause an error. Thus, there's no need to account for its ciphertext.
+                }
+                int actualOutputSize = mCipher.getOutputSize(input);
+                if (actualOutputSize < minExpectedOutputSize) {
+                    fail("getOutputSize(" + input + ") underestimated output size when buffered == "
+                            + buffered + ". min expected: <"
+                            + minExpectedOutputSize + ">, actual: <" + actualOutputSize + ">");
+                }
+            }
+
+            if (buffered == blockSize - 1) {
+                break;
+            }
+            // Buffer one more byte of input.
+            assertNull("buffered: " + buffered, update(new byte[1]));
+        }
+    }
+
+    public void testGetOutputSizeInDecryptionMode() throws Exception {
+        int blockSize = getBlockSize();
+        createCipher();
+        try {
+            mCipher.getOutputSize(blockSize);
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        initKat(Cipher.DECRYPT_MODE);
+        if ((!isAuthenticatedCipher()) && (isStreamCipher())) {
+            // Unauthenticated stream ciphers do not buffer input or output.
+            for (int input = 0; input <= blockSize * 2; input++) {
+                int actualOutputSize = mCipher.getOutputSize(input);
+                int expectedOutputSize = input;
+                if (actualOutputSize < expectedOutputSize) {
+                    fail("getOutputSize(" + expectedOutputSize + ") underestimated output size"
+                            + ". min expected: <" + expectedOutputSize
+                            + ">, actual: <" + actualOutputSize + ">");
+                }
+            }
+            return;
+        }
+        // Input may be buffered.
+
+        for (int buffered = 0; buffered < blockSize; buffered++) {
+            // Assert that the output of getOutputSize is not lower than the minimum expected.
+            for (int input = 0; input <= blockSize * 2; input++) {
+                int inputInclBuffered = buffered + input;
+                // doFinal dominates the output size.
+                int minExpectedOutputSize;
+                if (isAuthenticatedCipher()) {
+                    // Non-stream authenticated ciphers not supported
+                    assertTrue(isStreamCipher());
+
+                    // Authenticated stream cipher
+                    minExpectedOutputSize =
+                            inputInclBuffered - getKatAuthenticationTagLengthBytes();
+                } else {
+                    // Unauthenticated block cipher.
+
+                    // One full ciphertext block results in one ciphertext block.
+                    minExpectedOutputSize = inputInclBuffered - (inputInclBuffered % blockSize);
+                    if (isPaddingEnabled()) {
+                        if ((inputInclBuffered % blockSize) == 0) {
+                            // No more ciphertext remaining. Thus, the last plaintext block is at
+                            // most blockSize - 1 bytes long.
+                            minExpectedOutputSize--;
+                        } else {
+                            // Partial ciphertext block cannot be decrypted. Thus, the last
+                            // plaintext block would not have been output.
+                            minExpectedOutputSize -= blockSize;
+                        }
+                    } else {
+                        // When no padding is enabled, any remaining ciphertext will cause a error
+                        // because only full blocks can be decrypted. Thus, there's no need to
+                        // account for its plaintext.
+                    }
+                }
+                if (minExpectedOutputSize < 0) {
+                    minExpectedOutputSize = 0;
+                }
+                int actualOutputSize = mCipher.getOutputSize(input);
+                if (actualOutputSize < minExpectedOutputSize) {
+                    fail("getOutputSize(" + input + ") underestimated output size when buffered == "
+                            + buffered + ". min expected: <"
+                            + minExpectedOutputSize + ">, actual: <" + actualOutputSize + ">");
+                }
+            }
+
+            if (buffered == blockSize - 1) {
+                break;
+            }
+            // Buffer one more byte of input.
+            assertNull("buffered: " + buffered, update(new byte[1]));
+        }
+    }
+
+    public void testInitRequiresIvInDecryptMode() throws Exception {
+        if (getKatIv() == null) {
+            // IV not used in this transformation.
+            return;
+        }
+
+        createCipher();
+        try {
+            init(Cipher.DECRYPT_MODE, getKey());
+            fail();
+        } catch (InvalidKeyException expected) {}
+
+        createCipher();
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (SecureRandom) null);
+            fail();
+        } catch (InvalidKeyException expected) {}
+
+        createCipher();
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (AlgorithmParameterSpec) null, null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        createCipher();
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (AlgorithmParameterSpec) null, null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        createCipher();
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (AlgorithmParameters) null, null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        createCipher();
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (AlgorithmParameters) null, null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+    }
+
+    public void testGetIV() throws Exception {
+        createCipher();
+        assertNull(mCipher.getIV());
+
+        initKat(Cipher.ENCRYPT_MODE);
+        assertEquals(getKatIv(), mCipher.getIV());
+
+        byte[] ciphertext = doFinal(new byte[getBlockSize()]);
+        assertEquals(getKatIv(), mCipher.getIV());
+
+        createCipher();
+        initKat(Cipher.DECRYPT_MODE);
+        assertEquals(getKatIv(), mCipher.getIV());
+
+        doFinal(ciphertext);
+        assertEquals(getKatIv(), mCipher.getIV());
+    }
+
+    public void testIvGeneratedAndUsedWhenEncryptingWithoutExplicitIv() throws Exception {
+        createCipher();
+        SecretKey key = getKey();
+        init(Cipher.ENCRYPT_MODE, key);
+        byte[] generatedIv = mCipher.getIV();
+        AlgorithmParameters generatedParams = mCipher.getParameters();
+        if (getKatIv() == null) {
+            // IV not needed by this transformation -- shouldn't have been generated by Cipher.init
+            assertNull(generatedIv);
+            assertNull(generatedParams);
+        } else {
+            // IV is needed by this transformation -- should've been generated by Cipher.init
+            assertNotNull(generatedIv);
+            assertEquals(getKatIv().length, generatedIv.length);
+            assertNotNull(generatedParams);
+            assertEquals(generatedIv, getIv(generatedParams));
+        }
+
+        // Assert that encrypting then decrypting using the above IV (or null) results in the
+        // original plaintext.
+        byte[] plaintext = new byte[getBlockSize()];
+        byte[] ciphertext = doFinal(plaintext);
+        createCipher();
+        init(Cipher.DECRYPT_MODE, key, generatedParams);
+        byte[] decryptedPlaintext = mCipher.doFinal(ciphertext);
+        assertEquals(plaintext, decryptedPlaintext);
+    }
+
+    public void testGeneratedIvSurvivesReset() throws Exception {
+        if (getKatIv() == null) {
+            // This transformation does not use an IV
+            return;
+        }
+
+        createCipher();
+        init(Cipher.ENCRYPT_MODE, getKey());
+        byte[] iv = mCipher.getIV();
+        AlgorithmParameters generatedParams = mCipher.getParameters();
+        byte[] ciphertext = mCipher.doFinal(getKatPlaintext());
+        // Assert that the IV is still there
+        assertEquals(iv, mCipher.getIV());
+        assertAlgoritmParametersIv(iv);
+
+        if (getKatIv() != null) {
+            // We try to prevent IV reuse by not letting the Cipher be reused.
+            return;
+        }
+
+        // Assert that encrypting the same input after the above reset produces the same ciphertext.
+        assertEquals(ciphertext, mCipher.doFinal(getKatPlaintext()));
+
+        assertEquals(iv, mCipher.getIV());
+        assertAlgoritmParametersIv(iv);
+
+        // Just in case, test with a new instance of Cipher with the same parameters
+        createCipher();
+        init(Cipher.ENCRYPT_MODE, getKey(), generatedParams);
+        assertEquals(ciphertext, mCipher.doFinal(getKatPlaintext()));
+    }
+
+    public void testGeneratedIvDoesNotSurviveReinitialization() throws Exception {
+        if (getKatIv() == null) {
+            // This transformation does not use an IV
+            return;
+        }
+
+        createCipher();
+        init(Cipher.ENCRYPT_MODE, getKey());
+        byte[] ivBeforeReinitialization = mCipher.getIV();
+
+        init(Cipher.ENCRYPT_MODE, getKey());
+        // A new IV should've been generated
+        if (Arrays.equals(ivBeforeReinitialization, mCipher.getIV())) {
+            fail("Same auto-generated IV after Cipher reinitialized."
+                    + " Broken implementation or you're very unlucky (p: 2^{-"
+                    + (ivBeforeReinitialization.length * 8) + "})");
+        }
+    }
+
+    public void testExplicitlySetIvDoesNotSurviveReinitialization() throws Exception {
+        if (getKatIv() == null) {
+            // This transformation does not use an IV
+            return;
+        }
+
+        createCipher();
+        initKat(Cipher.ENCRYPT_MODE);
+        init(Cipher.ENCRYPT_MODE, getKey());
+        // A new IV should've been generated
+        if (Arrays.equals(getKatIv(), mCipher.getIV())) {
+            fail("Auto-generated IV after Cipher reinitialized is the same as previous IV."
+                    + " Broken implementation or you're very unlucky (p: 2^{-"
+                    + (getKatIv().length * 8) + "})");
+        }
+    }
+
+    public void testReinitializingInDecryptModeDoesNotUsePreviouslyUsedIv() throws Exception {
+        if (getKatIv() == null) {
+            // This transformation does not use an IV
+            return;
+        }
+
+        createCipher();
+        // Initialize with explicitly provided IV
+        init(Cipher.ENCRYPT_MODE, getKey(), getKatAlgorithmParameterSpec());
+        // Make sure the IV has been used, just in case it's set/cached lazily.
+        mCipher.update(new byte[getBlockSize() * 2]);
+
+        // IV required but not provided
+        try {
+            init(Cipher.DECRYPT_MODE, getKey());
+            fail();
+        } catch (InvalidKeyException expected) {}
+
+        createCipher();
+        // Initialize with a generated IV
+        init(Cipher.ENCRYPT_MODE, getKey());
+        mCipher.doFinal(getKatPlaintext());
+
+        // IV required but not provided
+        try {
+            init(Cipher.DECRYPT_MODE, getKey());
+            fail();
+        } catch (InvalidKeyException expected) {}
+
+        // IV required but not provided
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (SecureRandom) null);
+            fail();
+        } catch (InvalidKeyException expected) {}
+
+        // IV required but not provided
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (AlgorithmParameterSpec) null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        // IV required but not provided
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (AlgorithmParameterSpec) null, null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        // IV required but not provided
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (AlgorithmParameters) null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        // IV required but not provided
+        try {
+            init(Cipher.DECRYPT_MODE, getKey(), (AlgorithmParameters) null, null);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+    }
+
+    public void testKeyDoesNotSurviveReinitialization() throws Exception {
+        assertKeyDoesNotSurviveReinitialization(Cipher.ENCRYPT_MODE);
+        assertKeyDoesNotSurviveReinitialization(Cipher.DECRYPT_MODE);
+    }
+
+    private void assertKeyDoesNotSurviveReinitialization(int opmode) throws Exception {
+        byte[] input = getKatInput(opmode);
+        createCipher();
+        byte[] katKeyBytes = getKatKey();
+        SecretKey key1 = importKey(katKeyBytes);
+        init(opmode, key1, getKatAlgorithmParameterSpec());
+        byte[] output1 = doFinal(input);
+
+        // Create a different key by flipping a bit in the KAT key.
+        katKeyBytes[0] ^= 1;
+        SecretKey key2 = importKey(katKeyBytes);
+
+        init(opmode, key2, getKatAlgorithmParameterSpec());
+        byte[] output2;
+        try {
+            output2 = doFinal(input);
+        } catch (BadPaddingException expected) {
+            // Padding doesn't decode probably because the new key is being used. This can only
+            // occur is padding is used.
+            return;
+        }
+
+        // Either padding wasn't used or the old key was used.
+        if (Arrays.equals(output1, output2)) {
+            fail("Same output when reinitialized with a different key. opmode: " + opmode);
+        }
+    }
+
+    public void testDoFinalResets() throws Exception {
+        assertDoFinalResetsCipher(Cipher.DECRYPT_MODE);
+        assertDoFinalResetsCipher(Cipher.ENCRYPT_MODE);
+    }
+
+    private void assertDoFinalResetsCipher(int opmode) throws Exception {
+        byte[] input = getKatInput(opmode);
+        byte[] expectedOutput = getKatOutput(opmode);
+
+        createCipher();
+        initKat(opmode);
+        assertEquals(expectedOutput, doFinal(input));
+
+        if ((opmode == Cipher.ENCRYPT_MODE) && (getKatIv() != null)) {
+            // Assert that this cipher cannot be reused (thus making IV reuse harder)
+            try {
+                doFinal(input);
+                fail();
+            } catch (IllegalStateException expected) {}
+            return;
+        }
+
+        // Assert that the same output is produced after the above reset
+        assertEquals(expectedOutput, doFinal(input));
+
+        // Assert that the same output is produced after the above reset. This time, make update()
+        // buffer half a block of input.
+        if (input.length < getBlockSize() * 2) {
+            fail("This test requires an input which is at least two blocks long");
+        }
+        assertEquals(expectedOutput, concat(
+                update(subarray(input, 0, getBlockSize() * 3 / 2)),
+                doFinal(subarray(input, getBlockSize() * 3 / 2, input.length))));
+
+        // Assert that the same output is produced after the above reset, despite half of the block
+        // having been buffered prior to the reset. This is in case the implementation does not
+        // empty that buffer when resetting.
+        assertEquals(expectedOutput, doFinal(input));
+
+        // Assert that the IV with which the cipher was initialized is still there after the resets.
+        assertEquals(getKatIv(), mCipher.getIV());
+        assertAlgoritmParametersIv(getKatIv());
+    }
+
+    public void testUpdateWithEmptyInputReturnsCorrectValue() throws Exception {
+        // Test encryption
+        createCipher();
+        initKat(Cipher.ENCRYPT_MODE);
+        assertUpdateWithEmptyInputReturnsNull();
+
+        // Test decryption
+        createCipher();
+        initKat(Cipher.DECRYPT_MODE);
+        assertUpdateWithEmptyInputReturnsNull();
+    }
+
+    private void assertUpdateWithEmptyInputReturnsNull() {
+        assertEquals(null, update(new byte[0]));
+        assertEquals(null, update(new byte[getBlockSize() * 2], getBlockSize(), 0));
+        assertEquals(null, update(new byte[getBlockSize()], 0, 0));
+
+        // Feed two blocks through the Cipher, so that it's in a state where a block of input
+        // produces a block of output.
+        // Two blocks are used instead of one because when decrypting with padding enabled, output
+        // lags behind input by a block because the Cipher doesn't know whether the most recent
+        // input block was supposed to contain padding.
+        update(new byte[getBlockSize() * 2]);
+
+        assertEquals(null, update(new byte[0]));
+        assertEquals(null, update(new byte[getBlockSize() * 2], getBlockSize(), 0));
+        assertEquals(null, update(new byte[getBlockSize()], 0, 0));
+    }
+
+    public void testUpdateDoesNotProduceOutputWhenInsufficientInput() throws Exception {
+        if (isStreamCipher()) {
+            // Stream ciphers always produce output for non-empty input.
+            return;
+        }
+
+        // Test encryption
+        createCipher();
+        initKat(Cipher.ENCRYPT_MODE);
+        assertUpdateDoesNotProduceOutputWhenInsufficientInput();
+
+        // Test decryption
+        createCipher();
+        initKat(Cipher.DECRYPT_MODE);
+        assertUpdateDoesNotProduceOutputWhenInsufficientInput();
+    }
+
+    private void assertUpdateDoesNotProduceOutputWhenInsufficientInput() throws Exception {
+        if (getBlockSize() < 8) {
+            fail("This test isn't designed for small block size: " + getBlockSize());
+        }
+
+        assertEquals(null, update(new byte[1]));
+        assertEquals(null, update(new byte[1], 0, 1));
+        assertEquals(0, update(new byte[1], 0, 1, new byte[getBlockSize()]));
+        assertEquals(0, update(new byte[1], 0, 1, new byte[getBlockSize()], 0));
+        assertEquals(0, update(ByteBuffer.allocate(1), ByteBuffer.allocate(getBlockSize())));
+
+        // Feed a block through the Cipher, so that it's potentially no longer in an initial state.
+        byte[] output = update(new byte[getBlockSize()]);
+        assertEquals(getBlockSize(), output.length);
+
+        assertEquals(null, update(new byte[1]));
+        assertEquals(null, update(new byte[1], 0, 1));
+        assertEquals(0, update(new byte[1], 0, 1, new byte[getBlockSize()]));
+        assertEquals(0, update(new byte[1], 0, 1, new byte[getBlockSize()], 0));
+        assertEquals(0, update(ByteBuffer.allocate(1), ByteBuffer.allocate(getBlockSize())));
+    }
+
+    public void testKatOneShotEncryptUsingDoFinal() throws Exception {
+        createCipher();
+        assertKatOneShotTransformUsingDoFinal(
+                Cipher.ENCRYPT_MODE, getKatPlaintext(), getKatCiphertext());
+    }
+
+    public void testKatOneShotDecryptUsingDoFinal() throws Exception {
+        createCipher();
+        assertKatOneShotTransformUsingDoFinal(
+                Cipher.DECRYPT_MODE, getKatCiphertext(), getKatPlaintext());
+    }
+
+    private void assertKatOneShotTransformUsingDoFinal(
+            int opmode, byte[] input, byte[] expectedOutput) throws Exception {
+        int bufferWithInputInTheMiddleCleartextOffset = 5;
+        byte[] bufferWithInputInTheMiddle = concat(
+                new byte[bufferWithInputInTheMiddleCleartextOffset],
+                input,
+                new byte[4]);
+
+        initKat(opmode);
+        assertEquals(expectedOutput, doFinal(input));
+        initKat(opmode);
+        assertEquals(expectedOutput, doFinal(input, 0, input.length));
+        initKat(opmode);
+        assertEquals(expectedOutput,
+                doFinal(bufferWithInputInTheMiddle,
+                        bufferWithInputInTheMiddleCleartextOffset,
+                        input.length));
+
+        ByteBuffer inputBuffer = ByteBuffer.wrap(
+                bufferWithInputInTheMiddle,
+                bufferWithInputInTheMiddleCleartextOffset,
+                input.length);
+        ByteBuffer actualOutputBuffer = ByteBuffer.allocate(expectedOutput.length);
+        initKat(opmode);
+        assertEquals(expectedOutput.length, doFinal(inputBuffer, actualOutputBuffer));
+        assertEquals(0, inputBuffer.remaining());
+        assertByteBufferEquals(
+                (ByteBuffer) ByteBuffer.wrap(expectedOutput).position(expectedOutput.length),
+                actualOutputBuffer);
+    }
+
+    public void testKatEncryptOneByteAtATime() throws Exception {
+        createCipher();
+        initKat(Cipher.ENCRYPT_MODE);
+        byte[] plaintext = getKatPlaintext();
+        byte[] expectedCiphertext = getKatCiphertext();
+        int blockSize = getBlockSize();
+        if (isStreamCipher()) {
+            // Stream cipher -- one byte in, one byte out
+            for (int plaintextIndex = 0; plaintextIndex < plaintext.length; plaintextIndex++) {
+                byte[] output = update(new byte[] {plaintext[plaintextIndex]});
+                assertEquals("plaintext index: " + plaintextIndex, 1, output.length);
+                assertEquals("plaintext index: " + plaintextIndex,
+                        expectedCiphertext[plaintextIndex], output[0]);
+            }
+            byte[] finalOutput = doFinal();
+            byte[] expectedFinalOutput;
+            if (isAuthenticatedCipher()) {
+                expectedFinalOutput =
+                        subarray(expectedCiphertext, plaintext.length, expectedCiphertext.length);
+            } else {
+                expectedFinalOutput = EmptyArray.BYTE;
+            }
+            assertEquals(expectedFinalOutput, finalOutput);
+        } else {
+            // Not a stream cipher -- operates on full blocks only.
+
+            // Assert that a block of output is produced once a full block of input is provided.
+            // Every input block produces an output block.
+            int ciphertextIndex = 0;
+            for (int plaintextIndex = 0; plaintextIndex < plaintext.length; plaintextIndex++) {
+                byte[] output = update(new byte[] {plaintext[plaintextIndex]});
+                if ((plaintextIndex % blockSize) == blockSize - 1) {
+                    // Cipher.update is expected to have output a new block
+                    assertEquals(
+                            "plaintext index: " + plaintextIndex,
+                            subarray(
+                                    expectedCiphertext,
+                                    ciphertextIndex,
+                                    ciphertextIndex + blockSize),
+                            output);
+                } else {
+                    // Cipher.update is expected to have produced no output
+                    assertEquals("plaintext index: " + plaintextIndex, null, output);
+                }
+                if (output != null) {
+                    ciphertextIndex += output.length;
+                }
+            }
+
+            byte[] actualFinalOutput = doFinal();
+            byte[] expectedFinalOutput =
+                    subarray(expectedCiphertext, ciphertextIndex, expectedCiphertext.length);
+            assertEquals(expectedFinalOutput, actualFinalOutput);
+        }
+    }
+
+    public void testKatDecryptOneByteAtATime() throws Exception {
+        createCipher();
+        initKat(Cipher.DECRYPT_MODE);
+        byte[] ciphertext = getKatCiphertext();
+        int plaintextIndex = 0;
+        int blockSize = getBlockSize();
+        byte[] expectedPlaintext = getKatPlaintext();
+        boolean paddingEnabled = isPaddingEnabled();
+        if (isAuthenticatedCipher()) {
+            // Authenticated cipher -- no output until doFinal where ciphertext is authenticated.
+            for (int ciphertextIndex = 0; ciphertextIndex < ciphertext.length; ciphertextIndex++) {
+                byte[] output = update(new byte[] {ciphertext[ciphertextIndex]});
+                assertEquals("ciphertext index: " + ciphertextIndex,
+                        0, (output != null) ? output.length : 0);
+            }
+            byte[] finalOutput = doFinal();
+            assertEquals(expectedPlaintext, finalOutput);
+        } else if (isStreamCipher()) {
+            // Unauthenticated stream cipher -- one byte in, one byte out
+            for (int ciphertextIndex = 0; ciphertextIndex < ciphertext.length; ciphertextIndex++) {
+                byte[] output = update(new byte[] {ciphertext[ciphertextIndex]});
+                assertEquals("ciphertext index: " + ciphertextIndex, 1, output.length);
+                assertEquals("ciphertext index: " + ciphertextIndex,
+                        expectedPlaintext[ciphertextIndex], output[0]);
+            }
+            byte[] finalOutput = doFinal();
+            assertEquals(0, finalOutput.length);
+        } else {
+            // Unauthenticated block cipher -- operates in full blocks only
+
+            // Assert that a block of output is produced once a full block of input is provided.
+            // When padding is used, output is produced one input byte later: once the first byte of the
+            // next input block is provided.
+            for (int ciphertextIndex = 0; ciphertextIndex < ciphertext.length; ciphertextIndex++) {
+                byte[] output = update(new byte[] {ciphertext[ciphertextIndex]});
+                boolean outputExpected =
+                        ((paddingEnabled)
+                                && (ciphertextIndex > 0) && ((ciphertextIndex % blockSize) == 0))
+                        || ((!paddingEnabled) && ((ciphertextIndex % blockSize) == blockSize - 1));
+
+                if (outputExpected) {
+                    assertEquals(
+                            "ciphertext index: " + ciphertextIndex,
+                            subarray(expectedPlaintext, plaintextIndex, plaintextIndex + blockSize),
+                            output);
+                } else {
+                    assertEquals("ciphertext index: " + ciphertextIndex, null, output);
+                }
+
+                if (output != null) {
+                    plaintextIndex += output.length;
+                }
+            }
+
+            byte[] actualFinalOutput = doFinal();
+            byte[] expectedFinalOutput =
+                    subarray(expectedPlaintext, plaintextIndex, expectedPlaintext.length);
+            assertEquals(expectedFinalOutput, actualFinalOutput);
+        }
+    }
+
+    public void testUpdateAADNotSupported() throws Exception {
+        if (isAuthenticatedCipher()) {
+            // Not applicable to authenticated ciphers where updateAAD is supported.
+            return;
+        }
+
+        createCipher();
+        initKat(Cipher.ENCRYPT_MODE);
+        assertUpdateAADNotSupported();
+
+        createCipher();
+        initKat(Cipher.DECRYPT_MODE);
+        assertUpdateAADNotSupported();
+    }
+
+    public void testUpdateAADSupported() throws Exception {
+        if (!isAuthenticatedCipher()) {
+            // Not applicable to unauthenticated ciphers where updateAAD is not supported.
+            return;
+        }
+
+        createCipher();
+        initKat(Cipher.ENCRYPT_MODE);
+        assertUpdateAADSupported();
+
+        createCipher();
+        initKat(Cipher.DECRYPT_MODE);
+        assertUpdateAADSupported();
+    }
+
+    private void assertUpdateAADNotSupported() throws Exception {
+        try {
+            mCipher.updateAAD(new byte[getBlockSize()]);
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        } catch (IllegalStateException expected) {}
+
+        try {
+            mCipher.updateAAD(new byte[getBlockSize()], 0, getBlockSize());
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        } catch (IllegalStateException expected) {}
+
+        try {
+            mCipher.updateAAD(ByteBuffer.allocate(getBlockSize()));
+            fail();
+        } catch (UnsupportedOperationException expected) {
+        } catch (IllegalStateException expected) {}
+    }
+
+    private void assertUpdateAADSupported() throws Exception {
+        mCipher.updateAAD(new byte[getBlockSize()]);
+        mCipher.updateAAD(new byte[getBlockSize()], 0, getBlockSize());
+        mCipher.updateAAD(ByteBuffer.allocate(getBlockSize()));
+    }
+
+    // TODO: Add tests for WRAP and UNWRAP
+
+    public void testUpdateAndDoFinalNotSupportedInWrapAndUnwrapModes() throws Exception {
+        createCipher();
+        assertUpdateAndDoFinalThrowIllegalStateExceprtion(
+                Cipher.WRAP_MODE, getKey(), getKatAlgorithmParameterSpec());
+
+        createCipher();
+        assertUpdateAndDoFinalThrowIllegalStateExceprtion(
+                Cipher.UNWRAP_MODE, getKey(), getKatAlgorithmParameterSpec());
+    }
+
+    private void assertUpdateAndDoFinalThrowIllegalStateExceprtion(
+            int opmode, SecretKey key, AlgorithmParameterSpec paramSpec)
+            throws Exception {
+        try {
+            init(opmode, key, paramSpec);
+        } catch (UnsupportedOperationException e) {
+            // Skip this test because wrap/unwrap is not supported by this Cipher
+            return;
+        }
+
+        try {
+            update(new byte[getBlockSize()]);
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            update(new byte[getBlockSize()], 0, getBlockSize());
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            update(new byte[getBlockSize()], 0, getBlockSize(), new byte[getBlockSize() * 2]);
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            update(new byte[getBlockSize()], 0, getBlockSize(), new byte[getBlockSize() * 2], 0);
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            update(ByteBuffer.allocate(getBlockSize()), ByteBuffer.allocate(getBlockSize() * 2));
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            doFinal();
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            doFinal(new byte[getBlockSize()]);
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            doFinal(new byte[getBlockSize()], 0, getBlockSize());
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            doFinal(new byte[getBlockSize() * 2], 0);
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            doFinal(new byte[getBlockSize()], 0, getBlockSize(), new byte[getBlockSize() * 2]);
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            doFinal(new byte[getBlockSize()], 0, getBlockSize(), new byte[getBlockSize() * 2], 0);
+            fail();
+        } catch (IllegalStateException expected) {}
+
+        init(opmode, key, paramSpec);
+        try {
+            doFinal(ByteBuffer.allocate(getBlockSize()), ByteBuffer.allocate(getBlockSize() * 2));
+            fail();
+        } catch (IllegalStateException expected) {}
+    }
+
+    public void testGeneratedPadding() throws Exception {
+        // Assert that the Cipher under test correctly handles plaintexts of various lengths.
+        if (isStreamCipher()) {
+            // Not applicable to stream ciphers
+            return;
+        }
+
+        // Encryption of basePlaintext and additional data should result in baseCiphertext and some
+        // data (some of which may be padding).
+        int blockSize = getBlockSize();
+        byte[] basePlaintext = subarray(getKatPlaintext(), 0, blockSize);
+        byte[] baseCiphertext = subarray(getKatCiphertext(), 0, blockSize);
+        boolean paddingEnabled = isPaddingEnabled();
+
+        for (int lastInputBlockUnusedByteCount = 0;
+                lastInputBlockUnusedByteCount < blockSize;
+                lastInputBlockUnusedByteCount++) {
+            byte[] plaintext = concat(basePlaintext, new byte[lastInputBlockUnusedByteCount]);
+            createCipher();
+            initKat(Cipher.ENCRYPT_MODE);
+
+            if ((!paddingEnabled) && ((lastInputBlockUnusedByteCount % blockSize) != 0)) {
+                // Without padding, plaintext which does not end with a full block should be
+                // rejected.
+                try {
+                    doFinal(plaintext);
+                    fail();
+                } catch (IllegalBlockSizeException expected) {}
+                continue;
+            }
+            byte[] ciphertext = doFinal(plaintext);
+
+            assertEquals(
+                    "lastInputBlockUnusedByteCount: " + lastInputBlockUnusedByteCount,
+                    baseCiphertext,
+                    subarray(ciphertext, 0, baseCiphertext.length));
+
+            int expectedCiphertextLength = getExpectedCiphertextLength(plaintext.length);
+            int expectedDecryptedPlaintextLength =
+                    (paddingEnabled) ? plaintext.length : expectedCiphertextLength;
+            assertEquals(
+                    "lastInputBlockUnusedByteCount: " + lastInputBlockUnusedByteCount,
+                    expectedCiphertextLength,
+                    ciphertext.length);
+            initKat(Cipher.DECRYPT_MODE);
+            byte[] decryptedPlaintext = doFinal(ciphertext);
+            assertEquals(
+                    "lastInputBlockUnusedByteCount: " + lastInputBlockUnusedByteCount,
+                    expectedDecryptedPlaintextLength,
+                    decryptedPlaintext.length);
+            assertEquals(
+                    "lastInputBlockUnusedByteCount: " + lastInputBlockUnusedByteCount,
+                    basePlaintext,
+                    subarray(decryptedPlaintext, 0, basePlaintext.length));
+        }
+    }
+
+    public void testDecryptWithMangledPadding() throws Exception {
+        if (!isPaddingEnabled()) {
+            // Test not applicable when padding not in use
+            return;
+        }
+
+        createCipher();
+        initKat(Cipher.DECRYPT_MODE);
+        byte[] ciphertext = getKatCiphertext();
+        // Flip a bit in the last byte of ciphertext -- this should result in the last plaintext
+        // block getting mangled. In turn, this should result in bad padding.
+        ciphertext[ciphertext.length - 1] ^= 1;
+        try {
+            doFinal(ciphertext);
+            fail();
+        } catch (BadPaddingException expected) {}
+    }
+
+    public void testDecryptWithMissingPadding() throws Exception {
+        if (!isPaddingEnabled()) {
+            // Test not applicable when padding not in use
+            return;
+        }
+
+        createCipher();
+        initKat(Cipher.DECRYPT_MODE);
+        byte[] ciphertext = subarray(getKatCiphertext(), 0, getBlockSize());
+        try {
+            doFinal(ciphertext);
+            fail();
+        } catch (BadPaddingException expected) {}
+    }
+
+    public void testUpdateCopySafe() throws Exception {
+        // Assert that when input and output buffers passed to Cipher.update reference the same
+        // byte array, then no input data is overwritten before it's consumed.
+        assertUpdateCopySafe(Cipher.ENCRYPT_MODE, 0, 0);
+        assertUpdateCopySafe(Cipher.ENCRYPT_MODE, 0, 1);
+        assertUpdateCopySafe(Cipher.ENCRYPT_MODE, 1, 0);
+        assertUpdateCopySafe(Cipher.ENCRYPT_MODE, 0, getBlockSize() - 1);
+        assertUpdateCopySafe(Cipher.ENCRYPT_MODE, 0, getBlockSize());
+        assertUpdateCopySafe(Cipher.ENCRYPT_MODE, 0, getBlockSize() + 1);
+        assertUpdateCopySafe(Cipher.ENCRYPT_MODE, getBlockSize() * 2 - 1, 0);
+        assertUpdateCopySafe(Cipher.ENCRYPT_MODE, getBlockSize() * 2, 0);
+        assertUpdateCopySafe(Cipher.ENCRYPT_MODE, getBlockSize() * 2 + 1, 0);
+
+        assertUpdateCopySafe(Cipher.DECRYPT_MODE, 0, 0);
+        assertUpdateCopySafe(Cipher.DECRYPT_MODE, 0, 1);
+        assertUpdateCopySafe(Cipher.DECRYPT_MODE, 1, 0);
+        assertUpdateCopySafe(Cipher.DECRYPT_MODE, 0, getBlockSize() - 1);
+        assertUpdateCopySafe(Cipher.DECRYPT_MODE, 0, getBlockSize());
+        assertUpdateCopySafe(Cipher.DECRYPT_MODE, 0, getBlockSize() + 1);
+        assertUpdateCopySafe(Cipher.DECRYPT_MODE, getBlockSize() * 2 - 1, 0);
+        assertUpdateCopySafe(Cipher.DECRYPT_MODE, getBlockSize() * 2, 0);
+        assertUpdateCopySafe(Cipher.DECRYPT_MODE, getBlockSize() * 2 + 1, 0);
+    }
+
+    private void assertUpdateCopySafe(
+            int opmode, int inputOffsetInBuffer, int outputOffsetInBuffer)
+            throws Exception {
+        int blockSize = getBlockSize();
+        byte[] input;
+        byte[] expectedOutput;
+        switch (opmode) {
+            case Cipher.ENCRYPT_MODE:
+                input = getKatPlaintext();
+                if (isStreamCipher()) {
+                    if (isAuthenticatedCipher()) {
+                        expectedOutput = subarray(getKatCiphertext(), 0, input.length);
+                    } else {
+                        expectedOutput = getKatCiphertext();
+                    }
+                } else {
+                    // Update outputs exactly one block of ciphertext for one block of plaintext,
+                    // excluding padding.
+                    expectedOutput = subarray(
+                            getKatCiphertext(), 0, (input.length / blockSize) * blockSize);
+                }
+                break;
+            case Cipher.DECRYPT_MODE:
+                input = getKatCiphertext();
+                if (isAuthenticatedCipher()) {
+                    expectedOutput = EmptyArray.BYTE;
+                } else if (isStreamCipher()) {
+                    expectedOutput = getKatPlaintext();
+                } else {
+                    expectedOutput = getKatPlaintext();
+                    if (isPaddingEnabled()) {
+                        // When padding is enabled, update will not output the last block of
+                        // plaintext because it doesn't know whether more ciphertext will be
+                        // provided.
+                        expectedOutput = subarray(
+                                expectedOutput, 0, ((input.length / blockSize) - 1) * blockSize);
+                    } else {
+                        // When no padding is used, one block of ciphertext results in one block of
+                        // plaintext.
+                        expectedOutput = subarray(
+                                expectedOutput, 0, (input.length - (input.length % blockSize)));
+                    }
+                }
+                break;
+            default:
+                throw new AssertionFailedError("Unsupported opmode: " + opmode);
+        }
+
+        int inputEndIndexInBuffer = inputOffsetInBuffer + input.length;
+        int outputEndIndexInBuffer = outputOffsetInBuffer + expectedOutput.length;
+
+        // Test the update(byte[], int, int, byte[], int) variant
+        byte[] buffer = new byte[Math.max(inputEndIndexInBuffer, outputEndIndexInBuffer)];
+        System.arraycopy(input, 0, buffer, inputOffsetInBuffer, input.length);
+        createCipher();
+        initKat(opmode);
+        assertEquals(expectedOutput.length,
+                update(buffer, inputOffsetInBuffer, input.length,
+                        buffer, outputOffsetInBuffer));
+        assertEquals(expectedOutput,
+                subarray(buffer, outputOffsetInBuffer, outputEndIndexInBuffer));
+
+        if (outputOffsetInBuffer == 0) {
+            // We can use the update variant which assumes that output offset is 0.
+            buffer = new byte[Math.max(inputEndIndexInBuffer, outputEndIndexInBuffer)];
+            System.arraycopy(input, 0, buffer, inputOffsetInBuffer, input.length);
+            createCipher();
+            initKat(opmode);
+            assertEquals(expectedOutput.length,
+                    update(buffer, inputOffsetInBuffer, input.length, buffer));
+            assertEquals(expectedOutput,
+                    subarray(buffer, outputOffsetInBuffer, outputEndIndexInBuffer));
+        }
+
+        // Test the update(ByteBuffer, ByteBuffer) variant
+        buffer = new byte[Math.max(inputEndIndexInBuffer, outputEndIndexInBuffer)];
+        System.arraycopy(input, 0, buffer, inputOffsetInBuffer, input.length);
+        ByteBuffer inputBuffer = ByteBuffer.wrap(buffer, inputOffsetInBuffer, input.length);
+        ByteBuffer outputBuffer =
+                ByteBuffer.wrap(buffer, outputOffsetInBuffer, expectedOutput.length);
+        createCipher();
+        initKat(opmode);
+        assertEquals(expectedOutput.length, update(inputBuffer, outputBuffer));
+        assertEquals(expectedOutput,
+                subarray(buffer, outputOffsetInBuffer, outputEndIndexInBuffer));
+    }
+
+    public void testDoFinalCopySafe() throws Exception {
+        // Assert that when input and output buffers passed to Cipher.doFinal reference the same
+        // byte array, then no input data is overwritten before it's consumed.
+        assertDoFinalCopySafe(Cipher.ENCRYPT_MODE, 0, 0);
+        assertDoFinalCopySafe(Cipher.ENCRYPT_MODE, 0, 1);
+        assertDoFinalCopySafe(Cipher.ENCRYPT_MODE, 1, 0);
+        assertDoFinalCopySafe(Cipher.ENCRYPT_MODE, 0, getBlockSize() - 1);
+        assertDoFinalCopySafe(Cipher.ENCRYPT_MODE, 0, getBlockSize());
+        assertDoFinalCopySafe(Cipher.ENCRYPT_MODE, 0, getBlockSize() + 1);
+        assertDoFinalCopySafe(Cipher.ENCRYPT_MODE, getBlockSize() * 2 - 1, 0);
+        assertDoFinalCopySafe(Cipher.ENCRYPT_MODE, getBlockSize() * 2, 0);
+        assertDoFinalCopySafe(Cipher.ENCRYPT_MODE, getBlockSize() * 2 + 1, 0);
+
+        assertDoFinalCopySafe(Cipher.DECRYPT_MODE, 0, 0);
+        assertDoFinalCopySafe(Cipher.DECRYPT_MODE, 0, 1);
+        assertDoFinalCopySafe(Cipher.DECRYPT_MODE, 1, 0);
+        assertDoFinalCopySafe(Cipher.DECRYPT_MODE, 0, getBlockSize() - 1);
+        assertDoFinalCopySafe(Cipher.DECRYPT_MODE, 0, getBlockSize());
+        assertDoFinalCopySafe(Cipher.DECRYPT_MODE, 0, getBlockSize() + 1);
+        assertDoFinalCopySafe(Cipher.DECRYPT_MODE, getBlockSize() * 2 - 1, 0);
+        assertDoFinalCopySafe(Cipher.DECRYPT_MODE, getBlockSize() * 2, 0);
+        assertDoFinalCopySafe(Cipher.DECRYPT_MODE, getBlockSize() * 2 + 1, 0);
+    }
+
+    private void assertDoFinalCopySafe(
+            int opmode, int inputOffsetInBuffer, int outputOffsetInBuffer)
+            throws Exception {
+        byte[] input = getKatInput(opmode);
+        byte[] expectedOutput = getKatOutput(opmode);
+
+        int inputEndIndexInBuffer = inputOffsetInBuffer + input.length;
+        int outputEndIndexInBuffer = outputOffsetInBuffer + expectedOutput.length;
+
+        // Test the doFinal(byte[], int, int, byte[], int) variant
+        byte[] buffer = new byte[Math.max(inputEndIndexInBuffer, outputEndIndexInBuffer)];
+        System.arraycopy(input, 0, buffer, inputOffsetInBuffer, input.length);
+        createCipher();
+        initKat(opmode);
+        assertEquals(expectedOutput.length,
+                doFinal(buffer, inputOffsetInBuffer, input.length,
+                        buffer, outputOffsetInBuffer));
+        assertEquals(expectedOutput,
+                subarray(buffer, outputOffsetInBuffer, outputEndIndexInBuffer));
+
+        if (outputOffsetInBuffer == 0) {
+            // We can use the doFinal variant which assumes that output offset is 0.
+            buffer = new byte[Math.max(inputEndIndexInBuffer, outputEndIndexInBuffer)];
+            System.arraycopy(input, 0, buffer, inputOffsetInBuffer, input.length);
+            createCipher();
+            initKat(opmode);
+            assertEquals(expectedOutput.length,
+                    doFinal(buffer, inputOffsetInBuffer, input.length, buffer));
+            assertEquals(expectedOutput,
+                    subarray(buffer, outputOffsetInBuffer, outputEndIndexInBuffer));
+        }
+
+        // Test the doFinal(ByteBuffer, ByteBuffer) variant
+        buffer = new byte[Math.max(inputEndIndexInBuffer, outputEndIndexInBuffer)];
+        System.arraycopy(input, 0, buffer, inputOffsetInBuffer, input.length);
+        ByteBuffer inputBuffer = ByteBuffer.wrap(buffer, inputOffsetInBuffer, input.length);
+        ByteBuffer outputBuffer =
+                ByteBuffer.wrap(buffer, outputOffsetInBuffer, expectedOutput.length);
+        createCipher();
+        initKat(opmode);
+        assertEquals(expectedOutput.length, doFinal(inputBuffer, outputBuffer));
+        assertEquals(expectedOutput,
+                subarray(buffer, outputOffsetInBuffer, outputEndIndexInBuffer));
+    }
+
+    protected void createCipher() throws NoSuchAlgorithmException,
+            NoSuchPaddingException, NoSuchProviderException  {
+        mCipher = Cipher.getInstance(getTransformation(), EXPECTED_PROVIDER_NAME);
+    }
+
+    private String getKeyAlgorithm() {
+        String transformation = getTransformation();
+        int delimiterIndex = transformation.indexOf('/');
+        if (delimiterIndex == -1) {
+            fail("Unexpected transformation: " + transformation);
+        }
+        return transformation.substring(0, delimiterIndex);
+    }
+
+    private String getBlockMode() {
+        String transformation = getTransformation();
+        int delimiterIndex = transformation.indexOf('/');
+        if (delimiterIndex == -1) {
+            fail("Unexpected transformation: " + transformation);
+        }
+        int nextDelimiterIndex = transformation.indexOf('/', delimiterIndex + 1);
+        if (nextDelimiterIndex == -1) {
+            fail("Unexpected transformation: " + transformation);
+        }
+        return transformation.substring(delimiterIndex + 1, nextDelimiterIndex);
+    }
+
+    private String getPadding() {
+        String transformation = getTransformation();
+        int delimiterIndex = transformation.indexOf('/');
+        if (delimiterIndex == -1) {
+            fail("Unexpected transformation: " + transformation);
+        }
+        int nextDelimiterIndex = transformation.indexOf('/', delimiterIndex + 1);
+        if (nextDelimiterIndex == -1) {
+            fail("Unexpected transformation: " + transformation);
+        }
+        return transformation.substring(nextDelimiterIndex + 1);
+    }
+
+    private SecretKey getKey() {
+        return importKey(getKatKey());
+    }
+
+    protected SecretKey importKey(byte[] keyMaterial) {
+        try {
+            int keyId = mNextKeyId++;
+            String keyAlias = "key" + keyId;
+            mAndroidKeyStore.setEntry(
+                    keyAlias,
+                    new KeyStore.SecretKeyEntry(new SecretKeySpec(keyMaterial, getKeyAlgorithm())),
+                    new KeyProtection.Builder(
+                            KeyProperties.PURPOSE_ENCRYPT
+                                    | KeyProperties.PURPOSE_DECRYPT)
+                            .setBlockModes(getBlockMode())
+                            .setEncryptionPaddings(getPadding())
+                            .setRandomizedEncryptionRequired(false)
+                            .build());
+            return (SecretKey) mAndroidKeyStore.getKey(keyAlias, null);
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to import key into AndroidKeyStore", e);
+        }
+    }
+
+    private boolean isPaddingEnabled() {
+        return !getTransformation().toLowerCase(Locale.US).endsWith("/nopadding");
+    }
+
+    private int getExpectedCiphertextLength(int plaintextLength) {
+        int blockSize = getBlockSize();
+        if (isStreamCipher()) {
+            // Padding not supported for stream ciphers
+            assertFalse(isPaddingEnabled());
+            return plaintextLength;
+        } else {
+            if (isPaddingEnabled()) {
+                return ((plaintextLength / blockSize) + 1) * blockSize;
+            } else {
+                return ((plaintextLength + blockSize - 1) / blockSize) * blockSize;
+            }
+        }
+    }
+
+    protected void initKat(int opmode)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        init(opmode, getKey(), getKatAlgorithmParameterSpec());
+    }
+
+    protected void init(int opmode, Key key, AlgorithmParameters spec)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        mCipher.init(opmode, key, spec);
+        mOpmode = opmode;
+    }
+
+    protected void init(int opmode, Key key, AlgorithmParameters spec, SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        mCipher.init(opmode, key, spec, random);
+        mOpmode = opmode;
+    }
+
+    protected void init(int opmode, Key key, AlgorithmParameterSpec spec)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        mCipher.init(opmode, key, spec);
+        mOpmode = opmode;
+    }
+
+    protected void init(int opmode, Key key, AlgorithmParameterSpec spec, SecureRandom random)
+            throws InvalidKeyException, InvalidAlgorithmParameterException {
+        mCipher.init(opmode, key, spec, random);
+        mOpmode = opmode;
+    }
+
+    protected void init(int opmode, Key key) throws InvalidKeyException {
+        mCipher.init(opmode, key);
+        mOpmode = opmode;
+    }
+
+    protected void init(int opmode, Key key, SecureRandom random) throws InvalidKeyException {
+        mCipher.init(opmode, key, random);
+        mOpmode = opmode;
+    }
+
+    protected byte[] doFinal() throws IllegalBlockSizeException, BadPaddingException {
+        return mCipher.doFinal();
+    }
+
+    protected byte[] doFinal(byte[] input) throws IllegalBlockSizeException, BadPaddingException {
+        return mCipher.doFinal(input);
+    }
+
+    protected byte[] doFinal(byte[] input, int inputOffset, int inputLen)
+            throws IllegalBlockSizeException, BadPaddingException {
+        return mCipher.doFinal(input, inputOffset, inputLen);
+    }
+
+    protected int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output)
+            throws ShortBufferException, IllegalBlockSizeException, BadPaddingException {
+        return mCipher.doFinal(input, inputOffset, inputLen, output);
+    }
+
+    protected int doFinal(byte[] input, int inputOffset, int inputLen, byte[] output,
+            int outputOffset) throws ShortBufferException, IllegalBlockSizeException,
+            BadPaddingException {
+        return mCipher.doFinal(input, inputOffset, inputLen, output, outputOffset);
+    }
+
+    protected int doFinal(byte[] output, int outputOffset) throws IllegalBlockSizeException,
+            ShortBufferException, BadPaddingException {
+        return mCipher.doFinal(output, outputOffset);
+    }
+
+    protected int doFinal(ByteBuffer input, ByteBuffer output) throws ShortBufferException,
+            IllegalBlockSizeException, BadPaddingException {
+        return mCipher.doFinal(input, output);
+    }
+
+    private boolean isEncrypting() {
+        return (mOpmode == Cipher.ENCRYPT_MODE) || (mOpmode == Cipher.WRAP_MODE);
+    }
+
+    private void assertUpdateOutputSize(int inputLength, int outputLength) {
+        if ((isAuthenticatedCipher()) && (!isEncrypting())) {
+            assertEquals("Output of update must be empty for authenticated cipher when decrypting",
+                    0, outputLength);
+            return;
+        }
+
+        if (isStreamCipher()) {
+            if (outputLength != inputLength) {
+                fail("Output of update (" + outputLength + ") not same size as input ("
+                        + inputLength + ")");
+            }
+        } else {
+            if ((outputLength % getBlockSize()) != 0) {
+                fail("Output of update (" + outputLength + ") not a multiple of block size ("
+                        + getBlockSize() + ")");
+            }
+        }
+    }
+
+    protected byte[] update(byte[] input) {
+        byte[] output = mCipher.update(input);
+        assertUpdateOutputSize(
+                (input != null) ? input.length : 0, (output != null) ? output.length : 0);
+        return output;
+    }
+
+    protected byte[] update(byte[] input, int offset, int len) {
+        byte[] output = mCipher.update(input, offset, len);
+        assertUpdateOutputSize(len, (output != null) ? output.length : 0);
+
+        return output;
+    }
+
+    protected int update(byte[] input, int offset, int len, byte[] output)
+            throws ShortBufferException {
+        int outputLen = mCipher.update(input, offset, len, output);
+        assertUpdateOutputSize(len, outputLen);
+
+        return outputLen;
+    }
+
+    protected int update(byte[] input, int offset, int len, byte[] output, int outputOffset)
+            throws ShortBufferException {
+        int outputLen = mCipher.update(input, offset, len, output, outputOffset);
+        assertUpdateOutputSize(len, outputLen);
+
+        return outputLen;
+    }
+
+    protected int update(ByteBuffer input, ByteBuffer output) throws ShortBufferException {
+        int inputLimitBefore = input.limit();
+        int outputLimitBefore = output.limit();
+        int inputLen = input.remaining();
+        int outputPosBefore = output.position();
+
+        int outputLen = mCipher.update(input, output);
+
+        assertUpdateOutputSize(inputLen, outputLen);
+        assertEquals(inputLimitBefore, input.limit());
+        assertEquals(input.limit(), input.position());
+
+        assertEquals(outputLimitBefore, output.limit());
+        assertEquals(outputPosBefore + outputLen, output.position());
+
+        return outputLen;
+    }
+
+    protected void updateAAD(byte[] input) {
+        mCipher.updateAAD(input);
+    }
+
+    protected void updateAAD(byte[] input, int offset, int len) {
+        mCipher.updateAAD(input, offset, len);
+    }
+
+    protected void updateAAD(ByteBuffer input) {
+        mCipher.updateAAD(input);
+    }
+
+    @SuppressWarnings("unused")
+    protected static void assertEquals(Buffer expected, Buffer actual) {
+        throw new RuntimeException(
+                "Comparing ByteBuffers using their .equals is probably not what you want"
+                + " -- use assertByteBufferEquals instead.");
+    }
+
+    /**
+     * Asserts that the position, limit, and capacity of the provided buffers are the same, and that
+     * their contents (from position {@code 0} to capacity) are the same.
+     */
+    protected static void assertByteBufferEquals(ByteBuffer expected, ByteBuffer actual) {
+        if (expected == null) {
+            if (actual == null) {
+                return;
+            } else {
+                fail("Expected: null, actual: " + bufferToString(actual));
+            }
+        } else {
+            if (actual == null) {
+                fail("Expected: " + bufferToString(expected) + ", actual: null");
+            } else {
+                if ((expected.capacity() != actual.capacity())
+                        || (expected.position() != actual.position())
+                        || (expected.limit() != actual.limit())
+                        || (!equals(expected.array(), expected.arrayOffset(), expected.capacity(),
+                                    actual.array(), actual.arrayOffset(), actual.capacity()))) {
+                    fail("Expected: " + bufferToString(expected)
+                            + ", actual: " + bufferToString(actual));
+                }
+            }
+        }
+    }
+
+    private static String bufferToString(ByteBuffer buffer) {
+        return "ByteBuffer[pos: " + buffer.position() + ", limit: " + buffer.limit()
+                + ", capacity: " + buffer.capacity()
+                + ", backing array: " + HexEncoding.encode(
+                        buffer.array(), buffer.arrayOffset(), buffer.capacity()) + "]";
+    }
+
+    protected static boolean equals(byte[] arr1, int offset1, int len1, byte[] arr2, int offset2,
+            int len2) {
+        if (arr1 == null) {
+            return (arr2 == null);
+        } else if (arr2 == null) {
+            return (arr1 == null);
+        } else {
+            if (len1 != len2) {
+                return false;
+            }
+            for (int i = 0; i < len1; i++) {
+                if (arr1[i + offset1] != arr2[i + offset2]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    protected static byte[] subarray(byte[] array, int beginIndex, int endIndex) {
+        byte[] result = new byte[endIndex - beginIndex];
+        System.arraycopy(array, beginIndex, result, 0, result.length);
+        return result;
+    }
+
+    protected static byte[] concat(byte[]... arrays) {
+        int resultLength = 0;
+        for (byte[] array : arrays) {
+            resultLength += (array != null) ? array.length : 0;
+        }
+
+        byte[] result = new byte[resultLength];
+        int resultOffset = 0;
+        for (byte[] array : arrays) {
+            if (array != null) {
+                System.arraycopy(array, 0, result, resultOffset, array.length);
+                resultOffset += array.length;
+            }
+        }
+        return result;
+    }
+
+    protected static void assertEquals(byte[] expected, byte[] actual) {
+        assertEquals(null, expected, actual);
+    }
+
+    protected static void assertEquals(String message, byte[] expected, byte[] actual) {
+        if (!Arrays.equals(expected, actual)) {
+            StringBuilder detail = new StringBuilder();
+            if (expected != null) {
+                detail.append("Expected (" + expected.length + " bytes): <"
+                        + HexEncoding.encode(expected) + ">");
+            } else {
+                detail.append("Expected: null");
+            }
+            if (actual != null) {
+                detail.append(", actual (" + actual.length + " bytes): <"
+                        + HexEncoding.encode(actual) + ">");
+            } else {
+                detail.append(", actual: null");
+            }
+            if (message != null) {
+                fail(message + ": " + detail);
+            } else {
+                fail(detail.toString());
+            }
+        }
+    }
+
+    protected final void assertInitRejectsIvParameterSpec(byte[] iv) throws Exception {
+        Key key = importKey(getKatKey());
+        createCipher();
+        IvParameterSpec spec = new IvParameterSpec(iv);
+        try {
+            init(Cipher.ENCRYPT_MODE, key, spec);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        try {
+            init(Cipher.WRAP_MODE, key, spec);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        try {
+            init(Cipher.DECRYPT_MODE, key, spec);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        try {
+            init(Cipher.UNWRAP_MODE, key, spec);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        AlgorithmParameters param = AlgorithmParameters.getInstance("AES");
+        param.init(new IvParameterSpec(iv));
+        try {
+            init(Cipher.ENCRYPT_MODE, key, param);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        try {
+            init(Cipher.WRAP_MODE, key, param);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        try {
+            init(Cipher.DECRYPT_MODE, key, param);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+
+        try {
+            init(Cipher.UNWRAP_MODE, key, param);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
new file mode 100644
index 0000000..e2c1d69
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -0,0 +1,1550 @@
+/*
+ * 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.keystore.cts;
+
+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 java.security.AlgorithmParameters;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.Provider;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.Provider.Service;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.OAEPParameterSpec;
+import javax.crypto.spec.PSource;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Tests for algorithm-agnostic functionality of {@code Cipher} implementations backed by Android
+ * Keystore.
+ */
+public class CipherTest extends AndroidTestCase {
+
+    private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_CRYPTO_OP_PROVIDER_NAME;
+
+    private static final String[] EXPECTED_ALGORITHMS = {
+        "AES/ECB/NoPadding",
+        "AES/ECB/PKCS7Padding",
+        "AES/CBC/NoPadding",
+        "AES/CBC/PKCS7Padding",
+        "AES/CTR/NoPadding",
+        "AES/GCM/NoPadding",
+        "RSA/ECB/NoPadding",
+        "RSA/ECB/PKCS1Padding",
+        "RSA/ECB/OAEPPadding",
+        "RSA/ECB/OAEPWithSHA-1AndMGF1Padding",
+        "RSA/ECB/OAEPWithSHA-224AndMGF1Padding",
+        "RSA/ECB/OAEPWithSHA-256AndMGF1Padding",
+        "RSA/ECB/OAEPWithSHA-384AndMGF1Padding",
+        "RSA/ECB/OAEPWithSHA-512AndMGF1Padding",
+    };
+
+    private static class KatVector {
+        private final byte[] plaintext;
+        private final byte[] ciphertext;
+        private final AlgorithmParameterSpec params;
+
+        private KatVector(String plaintextHex, String ciphertextHex) {
+            this(plaintextHex, null, ciphertextHex);
+        }
+
+        private KatVector(String plaintextHex, AlgorithmParameterSpec params,
+                String ciphertextHex) {
+            this(HexEncoding.decode(plaintextHex), params, HexEncoding.decode(ciphertextHex));
+        }
+
+        private KatVector(byte[] plaintext, byte[] ciphertext) {
+            this(plaintext, null, ciphertext);
+        }
+
+        private KatVector(byte[] plaintext, AlgorithmParameterSpec params, byte[] ciphertext) {
+            this.plaintext = plaintext;
+            this.ciphertext = ciphertext;
+            this.params = params;
+        }
+    }
+    private static final Map<String, KatVector> KAT_VECTORS =
+            new TreeMap<String, KatVector>(String.CASE_INSENSITIVE_ORDER);
+    static {
+        // From RI
+        KAT_VECTORS.put("AES/ECB/NoPadding", new KatVector(
+                "0383911bb1519d58e6656f3fd35639c502dbeb2196cea937fca272666cb4a80b",
+                "6574c5065283b89e0c930019e4655d8516b98170db6516cd83e589bd9c5e5adc"));
+        KAT_VECTORS.put("AES/ECB/PKCS7Padding", new KatVector(
+                "1ad3d73a3cfa66dac78a51a95c2cb2125ea701e6e9ecbca2415b436f0258e2ba7439b67545",
+                "920f873f2f9e91bac4c9c948d66496a21b8b2606850490dac7abecae83317488ee550b9973ac5cd142"
+                + "f387d7d2a12752"));
+        KAT_VECTORS.put("AES/CBC/NoPadding", new KatVector(
+                "1dffe21c8f18276c3a39ed0c53ab257b84efcedab60095c4cadd131143058cf7",
+                new IvParameterSpec(HexEncoding.decode("10b3eea6cc8a7d6f48337e9b6987d28c")),
+                "47ab115bfadca91eaebec73ab942a06f3121fdd5aa55d223bd2cbcc3855e1ef8"));
+        KAT_VECTORS.put("AES/CBC/PKCS7Padding", new KatVector(
+                "9d49fb970b23bfe742ae7c45a773ada9faad84708c8858a06e4a192e0a90e2f6083548e0bf3f67",
+                new IvParameterSpec(HexEncoding.decode("ecd87bf9c49f37dcd2294e309192289a")),
+                "aeb64f48ec18a086eda7ee080948651a50b6f582ab54aac5454c9ab0a4de5b4a4abac526a4307011d1"
+                + "2881f1849c32ae"));
+        KAT_VECTORS.put("AES/CTR/NoPadding", new KatVector(
+                "b4e786cab9df48d2fce0c7872651314db1318d1f31a1b10a2c334d2555b4117668",
+                new IvParameterSpec(HexEncoding.decode("94d9f7a6d16f58018819b668020b68cc")),
+                "022e74572a70be57a0b65b2fb5bc9b803ce48973b6163f528bbe1fd001e29d330a"));
+        KAT_VECTORS.put("AES/GCM/NoPadding", new KatVector(
+                "03889a6ca811e3fd7e78467e3dae587d2110e80e98edbc9dfe17afba238c4c493186",
+                new GCMParameterSpec(128, HexEncoding.decode("f67aaf97cdec65b12188315e")),
+                "159eb1ffc86589b38f18097c32db646c7de3525b603876c3ae671bc2ca52a5395a374b377a915c9ed1"
+                + "a349abf9fc54c9ca81"));
+        KAT_VECTORS.put("RSA/ECB/NoPadding", new KatVector(
+                "50c499d558c38fd48ea76832887db2abc76e4e153a98fd4323ccb8006d34f11724a5692fb101b0eb96"
+                + "060eb9d15222",
+                "349b1d5061e98d0ab3f2327680bbc0cbb1b8ef8ee26148d7c67cf535223e3f78d822d369592ede29b1"
+                + "654aab25e6ae5e098318e55c13dc405f5ba27e5cc69ced32778592a51e6293a03f95e14ed17099fb"
+                + "0ac585e41297b87c3432953df0d98be7e505dc7de7bfe9d9ec750f475afeba4cc2dd78838c0d4399"
+                + "d8de02b07f00b292dc3d32d2a2f98ea5a5dac1a0fec4d01e5c3aea8c56eeff264896fb6cf2144401"
+                + "278c6663417bc00aafbb9eb97c056573cdec88d6ac6fd6c333d131337b16031da229029e3b6fe6f8"
+                + "ee427f2e90041e9636d67cddac75845914ce4be56092eed7188fe7e2bb33769efdeed86a7acbe15d"
+                + "debf92d9fbaaddede206acfa650697"));
+        KAT_VECTORS.put("RSA/ECB/PKCS1Padding", new KatVector(
+                "aed8cd94f35b2a54cdd3ed771482bd87e256b995408558fb82e5d475d1ee54711472f899ad6cbb6847"
+                + "99e52ff1d57cbc39f4",
+                "64148dee294dd3ea31d2b595ea661318cf90c89f71393cf6559087d6e8993e73eb1e6b5f4d3cfde3cb"
+                + "267938c5eca522b95a2df02df9c703dbe3103c157af0d2ed5b70da51cb4caa49061319420d0ea433"
+                + "f24b727530c162226bc806b7f39079cd494a5c8a242737413d27063f9fb74aadd20f521211316719"
+                + "c628fd4351d0608928949b6f59f351d9ccec4c596514335010834fcabd53a2cbb2642e0f83c4f89c"
+                + "199ee2c68ace9182cf484d99e86b0b2213c1cc113d24891958e5a0774b7486abae1475e46a939a94"
+                + "5d6491b98ad7979fd6e752b47e43e960557a0c0589d7d0444b011d75c9f5b143da6e1dcf7b678a2e"
+                + "f82fbe37a74df3e20fb1a9dbfd5978"));
+        KAT_VECTORS.put("RSA/ECB/OAEPPadding", new KatVector(
+                "c219f4e3e37eae2315f0fa4ebc4b46ef0c6befbb43a51ceda07435fc88a9",
+                "7a9bcfd0d02b6434025bbf5ba09c2dad118a4a3bca7cced8b404bc0fc2f17ddee13de82c8324294bf2"
+                + "60ad6e5171c2c3728a0c0fab20dd60e4e56cfef3e66239439ed2eddcc83ac8eeaedfd970e9966de3"
+                + "94ad1df0df503a0a640a49e10885b3a4115c3e94e893fff87bf9a5808350f957d6bc556ca6b08f81"
+                + "bf697704a3eb3db774797f883af0dcdc9bd9196d7595bab5e87d3187eb45b5771abe4e4dc70c25fa"
+                + "b9e3cddb6ae453a1d8e517d000779472e1376e5848b1654a51a9e90be4a4a6d0f6b8723c6e93c471"
+                + "313ea94f24504ca377b502057331355965a7e0b9c3b1d1fbd24ab5a4167f721d1ddac4d3c094d5c9"
+                + "0d2e277e9b5617cbf2770186323e89"));
+        KAT_VECTORS.put("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", new KatVector(
+                "bb2854620bb0e361d1384703dda12acee1fefc22024bcfc40a86390d5342c693aab8c7ed6517d8da86"
+                + "04492c9d",
+                "77033c578f24ef0ed93bfe6dc6f7c3f9f0505e7562f67ce987a269cabaa8a3ae7dd5e567a8b37db42d"
+                + "a79aa86ea2e189af5b9560b39407ff86f2785cdaf660fc7c93649bc24a818de564cb0d03e7681fa8"
+                + "f3cd42b3bfc58c49d3f049e0c98b07aff95876f05ddc45ebaa7127a198f27ae0cfd161c5598ac795"
+                + "8ed386d98b13d45730e6dc16313fe012af27d7be0e45215040bbfb07f2d35e34291fe4335a68175a"
+                + "46be99a15c1ccf673659157e1f52105de5a0a6f8c9d946740216eefe2a01a37b0ab144a44ff0d800"
+                + "be713b5b44acf4fcb1a60d5db977af4d77fa77bdb8594032b2f5bbdd49346b08e0e98ab1051b462e"
+                + "160c1bff62b927cd26c936948b723a"));
+        KAT_VECTORS.put("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", new KatVector(
+                "1bae19434be6599d1987b1ed866dd6b684dcd908bd98d797250be545eafea46d05ebdf9018",
+                "0f18b4a1153c6f8821e18a4275e4b570d540c8ad86bfc99146e5475238a43ecbe63bc81368cd64b9a2"
+                + "ab3ccd586e6afaad054c9d7bdc986adf022ec86335d110c53ebd5f2f2bd49d48d6da9541312c9b1b"
+                + "cc299ca4f59475869e4ec2253c91b137eae274a245fc9ee6262f74754bbda55d8bd25bfa4c1698f3"
+                + "a22d2d8d7fc6e9fbb56d828e61912b3085d82cceaeb1d2da425871575e7ba31a3d47b1b7d7df0bda"
+                + "81d62c75a9887bbc528fc6bb51db09884bb513b4cc94ca4a5fe0b370ca548dcdf60eebbf61e7efe7"
+                + "630fc47256d6d617fc1c2c774405f385650898abea03502cfbdcb53579fd18d896490e67aecdb7c7"
+                + "b7b950dc7ddba5c64188494c1a177b"));
+        KAT_VECTORS.put("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", new KatVector(
+                "332c2f2fc066fb29ec0928a52b5111ce6965546ce73927340c42d33b56b6ba547b77ac361ac0d13316"
+                + "345ca953840023d892fa4ff1aa32cc66d5aa88b79867",
+                "942c0ba1c67a34a7e116d9281b1df5084c66bc1458faf1b26d4f0f63a57307a9addcd3e5d2f3320071"
+                + "5a3d95ae84fb40a8dfe4cb0a28873fd5883ff8ee6efbfe38c460c755577b34fcf05bb2077afec7b2"
+                + "203799022be6a0903915e01e94abc51efe9c5548eb86bbbb4fd7f3bfc7b86f388128b6df1e6ce651"
+                + "230c6bc18bbf55b029f1e31da880c27d947ff97519df66a57ead6db791c4978f1d62edec0d89bb16"
+                + "83d237213f3f24271ddb8c4b50a82527954f0e49ae44d3acd8ddd3a57cfbfa456dd40675d5d75542"
+                + "31c6b79c7fb3500b1631be1d100e67d85ce423845fdc7c7f45e346a8ba573f5d11de9009069468dd"
+                + "8d517ad4adb1509dd5173ee1862d74"));
+        KAT_VECTORS.put("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", new KatVector(
+                "f51f158cbad4dbab38403b839c724f09a480c49be29c0e72615539dbe57ec86143f31f19392f419b5b"
+                + "e4ba9e3c6f1e870d307a7cf1a9e2",
+                "944243f35f534e7a273e94986b6835a4f5cdc5bc4efb9970d4760986599a02f652a848fcae333ff25a"
+                + "64108c9b900aaf002688398ad9fc17c73be52726306af9c13540df9d1765336b6f09ba4cb8a54d72"
+                + "5a4e45854bfa3802cfb110a6d7f7054e6072440ec00da62828cb75fe2566ec5be79eb8a3d1fbe2c2"
+                + "4439c107e5018e445e201ad80725755543c00dec50bb464c6ca897600eb3cda51fcef8161ac13d75"
+                + "a3eb30d385a1e718a61ae1b5d47aadb966fc007becc84db397d0b3cd983121872f9975995153e869"
+                + "9e24554a3c5e885f0ed8cd03e916da5ed541f1598da9bd6209447301d00f086153da353deff9d045"
+                + "8976ff7570410f0bdcfb3f56b782f5"));
+        KAT_VECTORS.put("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", new KatVector(
+                "d45f6ccc7e663957f234c237c1f09bf7791f6f5c1b9ef4fefb16e55ded0d96112e590f1bb08a60f85c"
+                + "2d0d2533f1d69792dfd8d647d880b18f87cfe32488c73613a3d535da7d776d90d9a4ba6a0311f456"
+                + "8511da49107c",
+                "5a037df3e5d6f3f703541e2db2aef7c69985e513bdff67c8ade6a09f50e27267bfb444f6c69b40a77a"
+                + "9136a27b29876af9d2bf4e7099863445d35b188d31f376b89fbd196059667ca657e10b9454c2b25f"
+                + "046fc9f7b42506e382e6b6fd99409cf97e865e65f8dce5d14a06b8aa8833c4bc72c8764467758f2d"
+                + "7960243161dce4ca8231e91bfcd3c933a80bc703ceab976224c876b1f550f91a6c2a0332d4377bd8"
+                + "dfe4b1283ab114e517b7b9e4a6e0bf166d5b506e7a3b7328078e12cb23b1d938760767dc9b3c3eb0"
+                + "848ddda101792aca9273ad414314c13fc511ffa0358a8f4c5f38edded3a2dc111fa62c80e6032c32"
+                + "ae04aeac7729f16a6310f1f6785c27"));
+    }
+
+    private static final long DAY_IN_MILLIS = TestUtils.DAY_IN_MILLIS;
+
+    private static final byte[] AES128_KAT_KEY_BYTES =
+            HexEncoding.decode("7d9f11a0da111e9d8bdd14f04648ed91");
+
+    private static final byte[] AES192_KAT_KEY_BYTES =
+            HexEncoding.decode("69ef2c44a48d3dc4d5744a281f7ebb5ca976c2202f91e10c");
+
+    private static final byte[] AES256_KAT_KEY_BYTES =
+            HexEncoding.decode("cf601cc10aaf434d1f01747136aff222af7fb426d101901712214c3fea18125f");
+
+    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
+        // long as canonical names of transformation are accepted.
+        // If the Provider exposes extraneous algorithms, it'll be caught because it'll have to
+        // expose at least one Service for such an algorithm, and this Service's algorithm will
+        // not be in the expected set.
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        Set<Service> services = provider.getServices();
+        Set<String> actualAlgsLowerCase = new HashSet<String>();
+        Set<String> expectedAlgsLowerCase = new HashSet<String>(
+                Arrays.asList(TestUtils.toLowerCase(EXPECTED_ALGORITHMS)));
+        for (Service service : services) {
+            if ("Cipher".equalsIgnoreCase(service.getType())) {
+                String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US);
+                actualAlgsLowerCase.add(algLowerCase);
+            }
+        }
+
+        TestUtils.assertContentsInAnyOrder(actualAlgsLowerCase,
+                expectedAlgsLowerCase.toArray(new String[0]));
+    }
+
+    public void testAndroidKeyStoreKeysHandledByAndroidKeyStoreProviderWhenDecrypting()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                ImportedKey key = importDefaultKatKey(
+                        algorithm,
+                        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                        false);
+
+                // Decryption may need additional parameters. Initializing a Cipher for encryption
+                // forces it to generate any such parameters.
+                Cipher cipher = Cipher.getInstance(algorithm, provider);
+                cipher.init(Cipher.ENCRYPT_MODE, key.getKeystoreBackedEncryptionKey());
+                AlgorithmParameters params = cipher.getParameters();
+
+                // Test DECRYPT_MODE
+                cipher = Cipher.getInstance(algorithm);
+                Key decryptionKey = key.getKeystoreBackedDecryptionKey();
+                cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params);
+                assertSame(provider, cipher.getProvider());
+
+                // Test UNWRAP_MODE
+                cipher = Cipher.getInstance(algorithm);
+                if (params != null) {
+                    cipher.init(Cipher.UNWRAP_MODE, decryptionKey, params);
+                } else {
+                    cipher.init(Cipher.UNWRAP_MODE, decryptionKey);
+                }
+                assertSame(provider, cipher.getProvider());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testAndroidKeyStorePublicKeysAcceptedByHighestPriorityProviderWhenEncrypting()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            if (isSymmetric(algorithm)) {
+                continue;
+            }
+            try {
+                Key key = importDefaultKatKey(
+                        algorithm,
+                        KeyProperties.PURPOSE_ENCRYPT,
+                        false).getKeystoreBackedEncryptionKey();
+
+                Cipher cipher = Cipher.getInstance(algorithm);
+                cipher.init(Cipher.ENCRYPT_MODE, key);
+
+                cipher = Cipher.getInstance(algorithm);
+                cipher.init(Cipher.WRAP_MODE, key);
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for" + algorithm, e);
+            }
+        }
+    }
+
+    public void testEmptyPlaintextEncryptsAndDecrypts()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        final byte[] originalPlaintext = EmptyArray.BYTE;
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            for (ImportedKey key : importKatKeys(
+                    algorithm,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                    false)) {
+                try {
+                    Key encryptionKey = key.getKeystoreBackedEncryptionKey();
+                    byte[] plaintext = truncatePlaintextIfNecessary(
+                            algorithm, encryptionKey, originalPlaintext);
+                    if (plaintext == null) {
+                        // Key is too short to encrypt anything using this transformation
+                        continue;
+                    }
+                    Cipher cipher = Cipher.getInstance(algorithm, provider);
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
+                    AlgorithmParameters params = cipher.getParameters();
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    byte[] expectedPlaintext = plaintext;
+                    if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                        // RSA decryption without padding left-pads resulting plaintext with NUL
+                        // bytes to the length of RSA modulus.
+                        int modulusLengthBytes = (TestUtils.getKeySizeBits(encryptionKey) + 7) / 8;
+                        expectedPlaintext = TestUtils.leftPadWithZeroBytes(
+                                expectedPlaintext, modulusLengthBytes);
+                    }
+
+                    cipher = Cipher.getInstance(algorithm, provider);
+                    Key decryptionKey = key.getKeystoreBackedDecryptionKey();
+                    cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params);
+                    byte[] actualPlaintext = cipher.doFinal(ciphertext);
+                    MoreAsserts.assertEquals(expectedPlaintext, actualPlaintext);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key " + key.getAlias(),
+                            e);
+                }
+            }
+        }
+    }
+
+    public void testCiphertextGeneratedByAndroidKeyStoreDecryptsByAndroidKeyStore()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        final byte[] originalPlaintext = "Very secret message goes here...".getBytes("US-ASCII");
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            for (ImportedKey key : importKatKeys(
+                    algorithm,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                    false)) {
+                try {
+                    Key encryptionKey = key.getKeystoreBackedEncryptionKey();
+                    byte[] plaintext = truncatePlaintextIfNecessary(
+                            algorithm, encryptionKey, originalPlaintext);
+                    if (plaintext == null) {
+                        // Key is too short to encrypt anything using this transformation
+                        continue;
+                    }
+                    Cipher cipher = Cipher.getInstance(algorithm, provider);
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
+                    AlgorithmParameters params = cipher.getParameters();
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    byte[] expectedPlaintext = plaintext;
+                    if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                        // RSA decryption without padding left-pads resulting plaintext with NUL
+                        // bytes to the length of RSA modulus.
+                        int modulusLengthBytes = (TestUtils.getKeySizeBits(encryptionKey) + 7) / 8;
+                        expectedPlaintext = TestUtils.leftPadWithZeroBytes(
+                                expectedPlaintext, modulusLengthBytes);
+                    }
+
+                    cipher = Cipher.getInstance(algorithm, provider);
+                    Key decryptionKey = key.getKeystoreBackedDecryptionKey();
+                    cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params);
+                    byte[] actualPlaintext = cipher.doFinal(ciphertext);
+                    MoreAsserts.assertEquals(expectedPlaintext, actualPlaintext);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key " + key.getAlias(),
+                            e);
+                }
+            }
+        }
+    }
+
+    public void testCiphertextGeneratedByHighestPriorityProviderDecryptsByAndroidKeyStore()
+            throws Exception {
+        Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(keystoreProvider);
+        byte[] originalPlaintext = "Very secret message goes here...".getBytes("UTF-8");
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            for (ImportedKey key : importKatKeys(
+                    algorithm,
+                    KeyProperties.PURPOSE_DECRYPT,
+                    false)) {
+                Provider encryptionProvider = null;
+                try {
+                    Key encryptionKey = key.getOriginalEncryptionKey();
+                    byte[] plaintext = truncatePlaintextIfNecessary(
+                            algorithm, encryptionKey, originalPlaintext);
+                    if (plaintext == null) {
+                        // Key is too short to encrypt anything using this transformation
+                        continue;
+                    }
+
+                    Cipher cipher;
+                    try {
+                        cipher = Cipher.getInstance(algorithm);
+                        cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
+                    } catch (InvalidKeyException e) {
+                        // No providers support encrypting using this algorithm and key.
+                        continue;
+                    }
+                    encryptionProvider = cipher.getProvider();
+                    if (keystoreProvider == encryptionProvider) {
+                        // This is covered by another test.
+                        continue;
+                    }
+                    AlgorithmParameters params = cipher.getParameters();
+
+                    // TODO: Remove this workaround for Bug 22405492 once the issue is fixed. The
+                    // issue is that Bouncy Castle incorrectly defaults the MGF1 digest to the
+                    // digest specified in the transformation. RI and Android Keystore keep the MGF1
+                    // digest defaulted at SHA-1.
+                    if ((params != null) && ("OAEP".equalsIgnoreCase(params.getAlgorithm()))) {
+                        OAEPParameterSpec spec = params.getParameterSpec(OAEPParameterSpec.class);
+                        if (!"SHA-1".equalsIgnoreCase(
+                                ((MGF1ParameterSpec) spec.getMGFParameters())
+                                        .getDigestAlgorithm())) {
+                            cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, new OAEPParameterSpec(
+                                    spec.getDigestAlgorithm(),
+                                    "MGF1",
+                                    MGF1ParameterSpec.SHA1,
+                                    PSource.PSpecified.DEFAULT));
+                            params = cipher.getParameters();
+                        }
+                    }
+
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    byte[] expectedPlaintext = plaintext;
+                    if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                        // RSA decryption without padding left-pads resulting plaintext with NUL
+                        // bytes to the length of RSA modulus.
+                        int modulusLengthBytes = (TestUtils.getKeySizeBits(encryptionKey) + 7) / 8;
+                        expectedPlaintext = TestUtils.leftPadWithZeroBytes(
+                                expectedPlaintext, modulusLengthBytes);
+                    }
+
+                    // TODO: Remove this workaround once Android Keystore AES-GCM supports IVs of
+                    // sizes other than 12 bytes. For example, Bouncy Castle auto-generates 16-byte
+                    // long IVs.
+                    if ("AES/GCM/NoPadding".equalsIgnoreCase(algorithm)) {
+                        byte[] iv = cipher.getIV();
+                        if ((iv != null) && (iv.length != 12)) {
+                            // Android Keystore AES-GCM only supports 12-byte long IVs.
+                            continue;
+                        }
+                    }
+
+                    // TODO: Remove this workaround for Bug 22319986 once the issue is fixed. The issue
+                    // is that Conscrypt and Bouncy Castle's AES/GCM/NoPadding implementations return
+                    // AlgorithmParameters of algorithm "AES" from which it's impossible to obtain a
+                    // GCMParameterSpec. They should be returning AlgorithmParameters of algorithm
+                    // "GCM".
+                    if (("AES/GCM/NoPadding".equalsIgnoreCase(algorithm))
+                            && (!"GCM".equalsIgnoreCase(params.getAlgorithm()))) {
+                        params = AlgorithmParameters.getInstance("GCM");
+                        params.init(new GCMParameterSpec(128, cipher.getIV()));
+                    }
+
+                    cipher = Cipher.getInstance(algorithm, keystoreProvider);
+                    Key decryptionKey = key.getKeystoreBackedDecryptionKey();
+                    cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params);
+                    byte[] actualPlaintext = cipher.doFinal(ciphertext);
+                    MoreAsserts.assertEquals(expectedPlaintext, actualPlaintext);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key " + key.getAlias()
+                                    + ", encryption provider: " + encryptionProvider,
+                            e);
+                }
+            }
+        }
+    }
+
+    public void testCiphertextGeneratedByAndroidKeyStoreDecryptsByHighestPriorityProvider()
+            throws Exception {
+        Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(keystoreProvider);
+        byte[] originalPlaintext = "Very secret message goes here...".getBytes("UTF-8");
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            for (ImportedKey key : importKatKeys(
+                    algorithm,
+                    KeyProperties.PURPOSE_ENCRYPT,
+                    false)) {
+                Provider decryptionProvider = null;
+                try {
+                    Key encryptionKey = key.getKeystoreBackedEncryptionKey();
+                    byte[] plaintext = truncatePlaintextIfNecessary(
+                            algorithm, encryptionKey, originalPlaintext);
+                    if (plaintext == null) {
+                        // Key is too short to encrypt anything using this transformation
+                        continue;
+                    }
+                    Cipher cipher = Cipher.getInstance(algorithm, keystoreProvider);
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
+                    AlgorithmParameters params = cipher.getParameters();
+
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    byte[] expectedPlaintext = plaintext;
+                    if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                        // RSA decryption without padding left-pads resulting plaintext with NUL
+                        // bytes to the length of RSA modulus.
+                        int modulusLengthBytes = (TestUtils.getKeySizeBits(encryptionKey) + 7) / 8;
+                        expectedPlaintext = TestUtils.leftPadWithZeroBytes(
+                                expectedPlaintext, modulusLengthBytes);
+                    }
+
+                    Key decryptionKey = key.getOriginalDecryptionKey();
+                    try {
+                        cipher = Cipher.getInstance(algorithm);
+                        if (params != null) {
+                            cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params);
+                        } else {
+                            cipher.init(Cipher.DECRYPT_MODE, decryptionKey);
+                        }
+                    } catch (InvalidKeyException e) {
+                        // No providers support decrypting using this algorithm and key.
+                        continue;
+                    }
+                    decryptionProvider = cipher.getProvider();
+                    if (keystoreProvider == decryptionProvider) {
+                        // This is covered by another test.
+                        continue;
+                    }
+                    byte[] actualPlaintext = cipher.doFinal(ciphertext);
+                    MoreAsserts.assertEquals(expectedPlaintext, actualPlaintext);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key " + key.getAlias()
+                                    + ", decryption provider: " + decryptionProvider,
+                            e);
+                }
+            }
+        }
+    }
+
+    public void testMaxSizedPlaintextSupported() throws Exception {
+        Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(keystoreProvider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            if (isSymmetric(algorithm)) {
+                // No input length restrictions (except multiple of block size for some
+                // transformations).
+                continue;
+            }
+            for (ImportedKey key : importKatKeys(
+                    algorithm,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                    false)) {
+                int plaintextSizeBytes = -1;
+                Provider otherProvider = null;
+                try {
+                    Key encryptionKey = key.getKeystoreBackedEncryptionKey();
+                    int maxSupportedPlaintextSizeBytes =
+                            TestUtils.getMaxSupportedPlaintextInputSizeBytes(
+                                    algorithm, encryptionKey);
+                    if (maxSupportedPlaintextSizeBytes < 0) {
+                        // Key too short to encrypt anything using this transformation.
+                        continue;
+                    } else if (maxSupportedPlaintextSizeBytes == Integer.MAX_VALUE) {
+                        // No input length restrictions.
+                        continue;
+                    }
+                    byte[] plaintext = new byte[maxSupportedPlaintextSizeBytes];
+                    Arrays.fill(plaintext, (byte) 0xff);
+                    plaintextSizeBytes = plaintext.length;
+
+                    // Encrypt plaintext using Android Keystore Cipher
+                    Cipher cipher = Cipher.getInstance(algorithm, keystoreProvider);
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
+                    AlgorithmParameters params = cipher.getParameters();
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    byte[] expectedPlaintext = plaintext;
+                    if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                        // RSA decryption without padding left-pads resulting plaintext with NUL
+                        // bytes to the length of RSA modulus.
+                        int modulusLengthBytes = (TestUtils.getKeySizeBits(encryptionKey) + 7) / 8;
+                        expectedPlaintext = TestUtils.leftPadWithZeroBytes(
+                                expectedPlaintext, modulusLengthBytes);
+                    }
+
+                    // Check that ciphertext decrypts using Android Keystore Cipher
+                    cipher = Cipher.getInstance(algorithm, keystoreProvider);
+                    Key decryptionKey = key.getKeystoreBackedDecryptionKey();
+                    cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params);
+                    byte[] actualPlaintext = cipher.doFinal(ciphertext);
+                    MoreAsserts.assertEquals(expectedPlaintext, actualPlaintext);
+
+                    // Check that ciphertext decrypts using the highest-priority provider.
+                    cipher = Cipher.getInstance(algorithm);
+                    decryptionKey = key.getOriginalDecryptionKey();
+                    try {
+                        cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params);
+                    } catch (InvalidKeyException e) {
+                        // No other providers offer decryption using this transformation and key.
+                        continue;
+                    }
+                    otherProvider = cipher.getProvider();
+                    if (otherProvider == keystoreProvider) {
+                        // This has already been tested above.
+                        continue;
+                    }
+                    actualPlaintext = cipher.doFinal(ciphertext);
+                    MoreAsserts.assertEquals(expectedPlaintext, actualPlaintext);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key " + key.getAlias()
+                                    + " and " + plaintextSizeBytes + " long plaintext"
+                                    + ", other provider: " + otherProvider,
+                            e);
+                }
+            }
+        }
+    }
+
+    public void testLargerThanMaxSizedPlaintextRejected() throws Exception {
+        Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(keystoreProvider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            if (isSymmetric(algorithm)) {
+                // No input length restrictions (except multiple of block size for some
+                // transformations).
+                continue;
+            }
+            for (ImportedKey key : importKatKeys(
+                    algorithm,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                    false)) {
+                int plaintextSizeBytes = -1;
+                Provider otherProvider = null;
+                try {
+                    Key encryptionKey = key.getKeystoreBackedEncryptionKey();
+                    int maxSupportedPlaintextSizeBytes =
+                            TestUtils.getMaxSupportedPlaintextInputSizeBytes(
+                                    algorithm, encryptionKey);
+                    if (maxSupportedPlaintextSizeBytes < 0) {
+                        // Key too short to encrypt anything using this transformation.
+                        continue;
+                    } else if (maxSupportedPlaintextSizeBytes == Integer.MAX_VALUE) {
+                        // No input length restrictions.
+                        continue;
+                    }
+                    // Create plaintext which is one byte longer than maximum supported one.
+                    byte[] plaintext = new byte[maxSupportedPlaintextSizeBytes + 1];
+                    Arrays.fill(plaintext, (byte) 0xff);
+                    plaintextSizeBytes = plaintext.length;
+
+                    // Encrypting this plaintext using Android Keystore Cipher should fail.
+                    Cipher cipher = Cipher.getInstance(algorithm, keystoreProvider);
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
+                    if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                        // This transformation is special: it's supposed to throw a
+                        // BadPaddingException instead of an IllegalBlockSizeException.
+                        try {
+                            byte[] ciphertext = cipher.doFinal(plaintext);
+                            fail("Unexpectedly produced ciphertext (" + ciphertext.length
+                                    + " bytes): " + HexEncoding.encode(ciphertext) + " for "
+                                    + plaintext.length + " byte long plaintext");
+                        } catch (BadPaddingException expected) {}
+                    } else {
+                        try {
+                            byte[] ciphertext = cipher.doFinal(plaintext);
+                            fail("Unexpectedly produced ciphertext (" + ciphertext.length
+                                    + " bytes): " + HexEncoding.encode(ciphertext) + " for "
+                                    + plaintext.length + " byte long plaintext");
+                        } catch (IllegalBlockSizeException expected) {}
+                    }
+
+                    // Encrypting this plaintext using the highest-priority implementation should
+                    // fail.
+                    cipher = Cipher.getInstance(algorithm);
+                    encryptionKey = key.getOriginalEncryptionKey();
+                    try {
+                        cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
+                    } catch (InvalidKeyException e) {
+                        // No other providers support this transformation with this key.
+                        continue;
+                    }
+                    otherProvider = cipher.getProvider();
+                    if (otherProvider == keystoreProvider) {
+                        // This has already been tested above.
+                        continue;
+                    }
+                    if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                        // This transformation is special: it's supposed to throw a
+                        // BadPaddingException instead of an IllegalBlockSizeException.
+                        try {
+                            byte[] ciphertext = cipher.doFinal(plaintext);
+                            fail(otherProvider.getName() + " unexpectedly produced ciphertext ("
+                                    + ciphertext.length + " bytes): "
+                                    + HexEncoding.encode(ciphertext) + " for "
+                                    + plaintext.length + " byte long plaintext");
+                            // TODO: Remove this workaround once Conscrypt's RSA Cipher Bug 22567458
+                            // is fixed. Conscrypt's Cipher.doFinal throws a SignatureException.
+                            // This code is unreachable because of the fail() above. It's here only
+                            // so that the compiler does not complain about us catching
+                            // SignatureException.
+                            Signature sig = Signature.getInstance("SHA256withRSA");
+                            sig.sign();
+                        } catch (BadPaddingException | SignatureException expected) {}
+                    } else {
+                        try {
+                            byte[] ciphertext = cipher.doFinal(plaintext);
+                            fail(otherProvider.getName() + " unexpectedly produced ciphertext ("
+                                    + ciphertext.length + " bytes): "
+                                    + HexEncoding.encode(ciphertext) + " for "
+                                    + plaintext.length + " byte long plaintext");
+                            // TODO: Remove the catching of RuntimeException workaround once the
+                            // corresponding Bug 22567463 in Conscrypt is fixed.
+                        } catch (IllegalBlockSizeException | RuntimeException expected) {}
+                    }
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key " + key.getAlias()
+                            + " and " + plaintextSizeBytes + " byte long plaintext"
+                            + ", other provider: " + otherProvider,
+                            e);
+                }
+            }
+        }
+    }
+
+    public void testKat() throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                ImportedKey key = importDefaultKatKey(algorithm,
+                        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                        true);
+                KatVector testVector = KAT_VECTORS.get(algorithm);
+                assertNotNull(testVector);
+                Cipher cipher = Cipher.getInstance(algorithm, provider);
+                Key decryptionKey = key.getKeystoreBackedDecryptionKey();
+                cipher.init(Cipher.DECRYPT_MODE, decryptionKey, testVector.params);
+                byte[] actualPlaintext = cipher.doFinal(testVector.ciphertext);
+                byte[] expectedPlaintext = testVector.plaintext;
+                if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                    // RSA decryption without padding left-pads resulting plaintext with NUL bytes
+                    // to the length of RSA modulus.
+                    int modulusLengthBytes = (TestUtils.getKeySizeBits(decryptionKey) + 7) / 8;
+                    expectedPlaintext = TestUtils.leftPadWithZeroBytes(
+                            expectedPlaintext, modulusLengthBytes);
+                }
+                MoreAsserts.assertEquals(expectedPlaintext, actualPlaintext);
+                if (!isRandomizedEncryption(algorithm)) {
+                    // Deterministic encryption: ciphertext depends only on plaintext and input
+                    // parameters. Assert that encrypting the plaintext results in the same
+                    // ciphertext as in the test vector.
+                    Key encryptionKey = key.getKeystoreBackedEncryptionKey();
+                    cipher = Cipher.getInstance(algorithm, provider);
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, testVector.params);
+                    byte[] actualCiphertext = cipher.doFinal(testVector.plaintext);
+                    MoreAsserts.assertEquals(testVector.ciphertext, actualCiphertext);
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    private static boolean isRandomizedEncryption(String transformation) {
+        String transformationUpperCase = transformation.toUpperCase(Locale.US);
+        return (transformationUpperCase.endsWith("/PKCS1PADDING"))
+                || (transformationUpperCase.contains("OAEP"));
+    }
+
+    public void testInitDecryptFailsWhenNotAuthorizedToDecrypt() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_DECRYPT);
+                assertInitDecryptSucceeds(transformation, good);
+                assertInitDecryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good, KeyProperties.PURPOSE_ENCRYPT).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitEncryptSymmetricFailsWhenNotAuthorizedToEncrypt() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (!isSymmetric(transformation)) {
+                continue;
+            }
+
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good, KeyProperties.PURPOSE_DECRYPT).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitEncryptAsymmetricIgnoresAuthorizedPurposes() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (isSymmetric(transformation)) {
+                continue;
+            }
+
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptSucceeds(transformation,
+                        TestUtils.buildUpon(good, 0).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitDecryptFailsWhenBlockModeNotAuthorized() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(
+                    TestUtils.getCipherKeyAlgorithm(transformation))) {
+                // Block modes do not apply
+                continue;
+            }
+
+            String goodBlockMode = TestUtils.getCipherBlockMode(transformation);
+            String badBlockMode = KeyProperties.BLOCK_MODE_CBC.equalsIgnoreCase(goodBlockMode)
+                    ? KeyProperties.BLOCK_MODE_CTR : KeyProperties.BLOCK_MODE_CBC;
+
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_DECRYPT);
+                assertInitDecryptSucceeds(transformation, good);
+                assertInitDecryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good).setBlockModes(badBlockMode).build());
+            } catch (Throwable e) {
+                throw new RuntimeException(
+                        "Failed for " + transformation + " when authorized only for "
+                                + badBlockMode,
+                        e);
+            }
+        }
+    }
+
+    public void testInitEncryptSymmetricFailsWhenBlockModeNotAuthorized() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (!isSymmetric(transformation)) {
+                continue;
+            }
+
+            if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(
+                    TestUtils.getCipherKeyAlgorithm(transformation))) {
+                // Block modes do not apply
+                continue;
+            }
+
+            String goodBlockMode = TestUtils.getCipherBlockMode(transformation);
+            String badBlockMode = KeyProperties.BLOCK_MODE_CBC.equalsIgnoreCase(goodBlockMode)
+                    ? KeyProperties.BLOCK_MODE_CTR : KeyProperties.BLOCK_MODE_CBC;
+
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good).setBlockModes(badBlockMode).build());
+            } catch (Throwable e) {
+                throw new RuntimeException(
+                        "Failed for " + transformation + " when authorized only for "
+                                + badBlockMode,
+                        e);
+            }
+        }
+    }
+
+    public void testInitEncryptAsymmetricIgnoresAuthorizedBlockModes() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (isSymmetric(transformation)) {
+                continue;
+            }
+
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptSucceeds(transformation,
+                        TestUtils.buildUpon(good).setBlockModes().build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitDecryptFailsWhenDigestNotAuthorized() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            String impliedDigest = TestUtils.getCipherDigest(transformation);
+            if (impliedDigest == null) {
+                // No digest used by this transformation
+                continue;
+            }
+
+            String badDigest = KeyProperties.DIGEST_SHA256.equalsIgnoreCase(impliedDigest)
+                    ? KeyProperties.DIGEST_SHA512 : KeyProperties.DIGEST_SHA256;
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_DECRYPT);
+
+                assertInitDecryptSucceeds(transformation, good);
+                assertInitDecryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good).setDigests(badDigest).build());
+
+                if (!KeyProperties.DIGEST_NONE.equalsIgnoreCase(impliedDigest)) {
+                    // Check that authorized digest NONE does not mean ANY digest is authorized.
+                    badDigest = KeyProperties.DIGEST_NONE;
+                    assertInitDecryptThrowsInvalidKeyException(transformation,
+                            TestUtils.buildUpon(good).setDigests(badDigest).build());
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException(
+                        "Failed for " + transformation + " when authorized only for " + badDigest,
+                        e);
+            }
+        }
+    }
+
+    public void testInitEncryptSymmetricFailsWhenDigestNotAuthorized() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (!isSymmetric(transformation)) {
+                continue;
+            }
+
+            String impliedDigest = TestUtils.getCipherDigest(transformation);
+            if (impliedDigest == null) {
+                // No digest used by this transformation
+                continue;
+            }
+
+            String badDigest = KeyProperties.DIGEST_SHA256.equalsIgnoreCase(impliedDigest)
+                    ? KeyProperties.DIGEST_SHA512 : KeyProperties.DIGEST_SHA256;
+
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good).setDigests(badDigest).build());
+
+                if (!KeyProperties.DIGEST_NONE.equalsIgnoreCase(impliedDigest)) {
+                    // Check that authorized digest NONE does not mean ANY digest is authorized.
+                    badDigest = KeyProperties.DIGEST_NONE;
+                    assertInitEncryptThrowsInvalidKeyException(transformation,
+                            TestUtils.buildUpon(good).setDigests(badDigest).build());
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException(
+                        "Failed for " + transformation + " when authorized only for " + badDigest,
+                        e);
+            }
+        }
+    }
+
+    public void testInitEncryptAsymmetricIgnoresAuthorizedDigests() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (isSymmetric(transformation)) {
+                continue;
+            }
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptSucceeds(transformation,
+                        TestUtils.buildUpon(good).setDigests().build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitDecryptFailsWhenPaddingSchemeNotAuthorized() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            String impliedEncryptionPadding = TestUtils.getCipherEncryptionPadding(transformation);
+            String badEncryptionPadding;
+            if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(
+                    TestUtils.getCipherKeyAlgorithm(transformation))) {
+                badEncryptionPadding =
+                        KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1.equalsIgnoreCase(
+                                impliedEncryptionPadding)
+                        ? KeyProperties.ENCRYPTION_PADDING_RSA_OAEP
+                        : KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1;
+            } else {
+                badEncryptionPadding = KeyProperties.ENCRYPTION_PADDING_PKCS7.equalsIgnoreCase(
+                        impliedEncryptionPadding)
+                        ? KeyProperties.ENCRYPTION_PADDING_NONE
+                        : KeyProperties.ENCRYPTION_PADDING_PKCS7;
+            }
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_DECRYPT);
+
+                assertInitDecryptSucceeds(transformation, good);
+                assertInitDecryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good)
+                                .setEncryptionPaddings(badEncryptionPadding)
+                                .build());
+
+                if (!KeyProperties.ENCRYPTION_PADDING_NONE.equalsIgnoreCase(
+                        impliedEncryptionPadding)) {
+                    // Check that authorized padding NONE does not mean ANY padding is authorized.
+                    badEncryptionPadding = KeyProperties.ENCRYPTION_PADDING_NONE;
+                    assertInitDecryptThrowsInvalidKeyException(transformation,
+                            TestUtils.buildUpon(good)
+                                    .setEncryptionPaddings(badEncryptionPadding)
+                                    .build());
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException(
+                        "Failed for " + transformation + " when authorized only for "
+                                + badEncryptionPadding,
+                        e);
+            }
+        }
+    }
+
+    public void testInitEncryptSymmetricFailsWhenPaddingSchemeNotAuthorized() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (!isSymmetric(transformation)) {
+                continue;
+            }
+            String impliedEncryptionPadding = TestUtils.getCipherEncryptionPadding(transformation);
+            String badEncryptionPadding = KeyProperties.ENCRYPTION_PADDING_PKCS7.equalsIgnoreCase(
+                    impliedEncryptionPadding)
+                    ? KeyProperties.ENCRYPTION_PADDING_NONE
+                    : KeyProperties.ENCRYPTION_PADDING_PKCS7;
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good)
+                                .setEncryptionPaddings(badEncryptionPadding)
+                                .build());
+
+                if (!KeyProperties.ENCRYPTION_PADDING_NONE.equalsIgnoreCase(
+                        impliedEncryptionPadding)) {
+                    // Check that authorized padding NONE does not mean ANY padding is authorized.
+                    badEncryptionPadding = KeyProperties.ENCRYPTION_PADDING_NONE;
+                    assertInitEncryptThrowsInvalidKeyException(transformation,
+                            TestUtils.buildUpon(good)
+                                    .setEncryptionPaddings(badEncryptionPadding)
+                                    .build());
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException(
+                        "Failed for " + transformation + " when authorized only for "
+                                + badEncryptionPadding,
+                        e);
+            }
+        }
+    }
+
+    public void testInitEncryptAsymmetricIgnoresAuthorizedPaddingSchemes() throws Exception {
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (isSymmetric(transformation)) {
+                continue;
+            }
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptSucceeds(transformation,
+                        TestUtils.buildUpon(good)
+                                .setEncryptionPaddings()
+                                .setSignaturePaddings()
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitDecryptFailsWhenKeyNotYetValid() throws Exception {
+        Date badStartDate = new Date(System.currentTimeMillis() + DAY_IN_MILLIS);
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_DECRYPT);
+
+                assertInitDecryptSucceeds(transformation, good);
+                assertInitDecryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good).setKeyValidityStart(badStartDate).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitEncryptSymmetricFailsWhenKeyNotYetValid() throws Exception {
+        Date badStartDate = new Date(System.currentTimeMillis() + DAY_IN_MILLIS);
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (!isSymmetric(transformation)) {
+                continue;
+            }
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good).setKeyValidityStart(badStartDate).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitEncryptAsymmetricIgnoresThatKeyNotYetValid() throws Exception {
+        Date badStartDate = new Date(System.currentTimeMillis() + DAY_IN_MILLIS);
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (isSymmetric(transformation)) {
+                continue;
+            }
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptSucceeds(transformation,
+                        TestUtils.buildUpon(good).setKeyValidityStart(badStartDate).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitDecryptFailsWhenKeyNoLongerValidForConsumption() throws Exception {
+        Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_DECRYPT);
+
+                assertInitDecryptSucceeds(transformation, good);
+                assertInitDecryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForConsumptionEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitDecryptIgnoresThatKeyNoLongerValidForOrigination() throws Exception {
+        Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_DECRYPT);
+
+                assertInitDecryptSucceeds(transformation, good);
+                assertInitDecryptSucceeds(transformation,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForOriginationEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitEncryptSymmetricFailsWhenKeyNoLongerValidForOrigination() throws Exception {
+        Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (!isSymmetric(transformation)) {
+                continue;
+            }
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptThrowsInvalidKeyException(transformation,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForOriginationEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitEncryptSymmetricIgnoresThatKeyNoLongerValidForConsumption()
+            throws Exception {
+        Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (!isSymmetric(transformation)) {
+                continue;
+            }
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptSucceeds(transformation,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForConsumptionEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testInitEncryptAsymmetricIgnoresThatKeyNoLongerValid() throws Exception {
+        Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            if (isSymmetric(transformation)) {
+                continue;
+            }
+            try {
+                KeyProtection good = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        transformation,
+                        KeyProperties.PURPOSE_ENCRYPT);
+
+                assertInitEncryptSucceeds(transformation, good);
+                assertInitEncryptSucceeds(transformation,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForOriginationEnd(badEndDate)
+                                .build());
+                assertInitEncryptSucceeds(transformation,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForConsumptionEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + transformation, e);
+            }
+        }
+    }
+
+    public void testEntropyConsumption() throws Exception {
+        // Assert that encryption consumes the correct amount of entropy from the provided
+        // SecureRandom and that decryption consumes no entropy.
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        CountingSecureRandom rng = new CountingSecureRandom();
+        for (String transformation : EXPECTED_ALGORITHMS) {
+            for (ImportedKey key : importKatKeys(
+                    transformation,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                    true)) {
+                try {
+                    Cipher cipher = Cipher.getInstance(transformation, provider);
+                    Key encryptionKey = key.getKeystoreBackedEncryptionKey();
+                    byte[] plaintext = truncatePlaintextIfNecessary(
+                            transformation, encryptionKey, new byte[32]);
+                    if (plaintext == null) {
+                        // Key too short to encrypt anything using this transformation.
+                        continue;
+                    }
+                    Arrays.fill(plaintext, (byte) 0x1);
+
+                    // Cipher.init may only consume entropy for generating the IV.
+                    rng.resetCounters();
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, rng);
+                    int expectedEntropyBytesConsumedDuringInit;
+                    String keyAlgorithm = TestUtils.getCipherKeyAlgorithm(transformation);
+                    if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)) {
+                        String blockMode =
+                                TestUtils.getCipherBlockMode(transformation).toUpperCase(Locale.US);
+                        // Entropy should consumed for IV generation only.
+                        switch (blockMode) {
+                            case "ECB":
+                                expectedEntropyBytesConsumedDuringInit = 0;
+                                break;
+                            case "CBC":
+                            case "CTR":
+                                expectedEntropyBytesConsumedDuringInit = 16;
+                                break;
+                            case "GCM":
+                                expectedEntropyBytesConsumedDuringInit = 12;
+                                break;
+                            default:
+                                throw new RuntimeException("Unsupported block mode " + blockMode);
+                        }
+                    } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+                        expectedEntropyBytesConsumedDuringInit = 0;
+                    } else {
+                        throw new RuntimeException("Unsupported key algorithm: " + transformation);
+                    }
+                    assertEquals(expectedEntropyBytesConsumedDuringInit, rng.getOutputSizeBytes());
+                    AlgorithmParameters params = cipher.getParameters();
+
+                    // Cipher.update should not consume entropy.
+                    rng.resetCounters();
+                    byte[] ciphertext = cipher.update(plaintext);
+                    assertEquals(0, rng.getOutputSizeBytes());
+
+                    // Cipher.doFinal may consume entropy to pad the message (RSA only).
+                    rng.resetCounters();
+                    ciphertext = TestUtils.concat(ciphertext, cipher.doFinal());
+                    int expectedEntropyBytesConsumedDuringDoFinal;
+                    if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)) {
+                        expectedEntropyBytesConsumedDuringDoFinal = 0;
+                    } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+                        // Entropy should not be consumed during Cipher.init.
+                        String encryptionPadding =
+                                TestUtils.getCipherEncryptionPadding(transformation);
+                        if (KeyProperties.ENCRYPTION_PADDING_RSA_OAEP.equalsIgnoreCase(
+                                encryptionPadding)) {
+                            int digestOutputSizeBits =
+                                    TestUtils.getDigestOutputSizeBits(TestUtils.getCipherDigest(
+                                            transformation));
+                            expectedEntropyBytesConsumedDuringDoFinal =
+                                    (digestOutputSizeBits + 7) / 8;
+                        } else if (encryptionPadding.equalsIgnoreCase(
+                                KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)) {
+                            expectedEntropyBytesConsumedDuringDoFinal =
+                                    (TestUtils.getKeySizeBits(encryptionKey) + 7) / 8;
+                        } else if (encryptionPadding.equalsIgnoreCase(
+                                KeyProperties.ENCRYPTION_PADDING_NONE)) {
+                            expectedEntropyBytesConsumedDuringDoFinal = 0;
+                        } else {
+                            throw new RuntimeException(
+                                    "Unexpected encryption padding: " + encryptionPadding);
+                        }
+                    } else {
+                        throw new RuntimeException("Unsupported key algorithm: " + keyAlgorithm);
+                    }
+                    assertEquals(
+                            expectedEntropyBytesConsumedDuringDoFinal, rng.getOutputSizeBytes());
+
+                    // Assert that when initialization parameters are provided when encrypting, no
+                    // entropy is consumed by Cipher.init. This is because Cipher.init should only
+                    // use entropy for generating an IV which in this case no longer needs to be
+                    // generated because it's specified in the parameters.
+                    cipher = Cipher.getInstance(transformation, provider);
+                    rng.resetCounters();
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey, params, rng);
+                    assertEquals(0, rng.getOutputSizeBytes());
+                    Key decryptionKey = key.getKeystoreBackedDecryptionKey();
+                    rng.resetCounters();
+                    cipher = Cipher.getInstance(transformation, provider);
+                    cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params, rng);
+                    assertEquals(0, rng.getOutputSizeBytes());
+                    rng.resetCounters();
+                    cipher.update(ciphertext);
+                    assertEquals(0, rng.getOutputSizeBytes());
+                    rng.resetCounters();
+                    cipher.doFinal();
+                    assertEquals(0, rng.getOutputSizeBytes());
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + transformation + " with key " + key.getAlias(), e);
+                }
+            }
+        }
+    }
+
+    private AlgorithmParameterSpec getWorkingDecryptionParameterSpec(String transformation) {
+        String keyAlgorithm = TestUtils.getCipherKeyAlgorithm(transformation);
+        if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            return null;
+        } else if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)) {
+            String blockMode = TestUtils.getCipherBlockMode(transformation);
+            if (KeyProperties.BLOCK_MODE_ECB.equalsIgnoreCase(blockMode)) {
+                return null;
+            } else if ((KeyProperties.BLOCK_MODE_CBC.equalsIgnoreCase(blockMode))
+                    || (KeyProperties.BLOCK_MODE_CTR.equalsIgnoreCase(blockMode))) {
+                return new IvParameterSpec(
+                        new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16});
+            } else if (KeyProperties.BLOCK_MODE_GCM.equalsIgnoreCase(blockMode)) {
+                return new GCMParameterSpec(
+                        128,
+                        new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
+            } else {
+                throw new IllegalArgumentException("Unsupported block mode: " + blockMode);
+            }
+        } else {
+            throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    private void assertInitDecryptSucceeds(String transformation, KeyProtection importParams)
+            throws Exception {
+        Cipher cipher = Cipher.getInstance(transformation, EXPECTED_PROVIDER_NAME);
+        Key key =
+                importDefaultKatKey(transformation, importParams).getKeystoreBackedDecryptionKey();
+        AlgorithmParameterSpec params = getWorkingDecryptionParameterSpec(transformation);
+        cipher.init(Cipher.DECRYPT_MODE, key, params);
+    }
+
+    private void assertInitDecryptThrowsInvalidKeyException(
+            String transformation, KeyProtection importParams) throws Exception {
+        Cipher cipher = Cipher.getInstance(transformation, EXPECTED_PROVIDER_NAME);
+        Key key =
+                importDefaultKatKey(transformation, importParams).getKeystoreBackedDecryptionKey();
+        AlgorithmParameterSpec params = getWorkingDecryptionParameterSpec(transformation);
+        try {
+            cipher.init(Cipher.DECRYPT_MODE, key, params);
+            fail("InvalidKeyException should have been thrown");
+        } catch (InvalidKeyException expected) {}
+    }
+
+    private void assertInitEncryptSucceeds(String transformation, KeyProtection importParams)
+            throws Exception {
+        Cipher cipher = Cipher.getInstance(transformation, EXPECTED_PROVIDER_NAME);
+        Key key =
+                importDefaultKatKey(transformation, importParams).getKeystoreBackedEncryptionKey();
+        cipher.init(Cipher.ENCRYPT_MODE, key);
+    }
+
+    private void assertInitEncryptThrowsInvalidKeyException(
+            String transformation, KeyProtection importParams) throws Exception {
+        Cipher cipher = Cipher.getInstance(transformation, EXPECTED_PROVIDER_NAME);
+        Key key =
+                importDefaultKatKey(transformation, importParams).getKeystoreBackedEncryptionKey();
+        try {
+            cipher.init(Cipher.ENCRYPT_MODE, key);
+            fail("InvalidKeyException should have been thrown");
+        } catch (InvalidKeyException expected) {}
+    }
+
+    private ImportedKey importDefaultKatKey(
+            String transformation, KeyProtection importParams)
+            throws Exception {
+        String keyAlgorithm = TestUtils.getCipherKeyAlgorithm(transformation);
+        if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)) {
+            return TestUtils.importIntoAndroidKeyStore(
+                    "testAES",
+                    new SecretKeySpec(AES128_KAT_KEY_BYTES, "AES"),
+                    importParams);
+        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            return TestUtils.importIntoAndroidKeyStore(
+                    "testRSA",
+                    getContext(),
+                    R.raw.rsa_key2_pkcs8,
+                    R.raw.rsa_key2_cert,
+                    importParams);
+        } else {
+            throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    private ImportedKey importDefaultKatKey(
+            String transformation, int purposes, boolean ivProvidedWhenEncrypting)
+            throws Exception {
+        KeyProtection importParams = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                transformation, purposes, ivProvidedWhenEncrypting);
+        return importDefaultKatKey(transformation, importParams);
+    }
+
+    private Collection<ImportedKey> importKatKeys(
+            String transformation, int purposes, boolean ivProvidedWhenEncrypting)
+            throws Exception {
+        KeyProtection importParams = TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                transformation, purposes, ivProvidedWhenEncrypting);
+        String keyAlgorithm = TestUtils.getCipherKeyAlgorithm(transformation);
+        if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)) {
+            return Arrays.asList(
+                    TestUtils.importIntoAndroidKeyStore(
+                            "testAES128",
+                            new SecretKeySpec(AES128_KAT_KEY_BYTES, "AES"),
+                            importParams),
+                    TestUtils.importIntoAndroidKeyStore(
+                            "testAES192",
+                            new SecretKeySpec(AES192_KAT_KEY_BYTES, "AES"),
+                            importParams),
+                    TestUtils.importIntoAndroidKeyStore(
+                            "testAES256",
+                            new SecretKeySpec(AES256_KAT_KEY_BYTES, "AES"),
+                            importParams)
+                    );
+        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            return RSASignatureTest.importKatKeyPairs(getContext(), importParams);
+        } else {
+            throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    private static boolean isSymmetric(String transformation) {
+        return TestUtils.isCipherSymmetric(transformation);
+    }
+
+    private static byte[] truncatePlaintextIfNecessary(
+            String transformation, Key encryptionKey, byte[] plaintext) {
+        int maxSupportedPlaintextSizeBytes =
+                TestUtils.getMaxSupportedPlaintextInputSizeBytes(
+                        transformation, encryptionKey);
+        if (plaintext.length <= maxSupportedPlaintextSizeBytes) {
+            // No need to truncate
+            return plaintext;
+        } else if (maxSupportedPlaintextSizeBytes < 0) {
+            // Key too short to encrypt anything at all using this transformation
+            return null;
+        } else {
+            // Truncate plaintext to exercise this transformation with this key
+            return Arrays.copyOf(plaintext, maxSupportedPlaintextSizeBytes);
+        }
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/CountingSecureRandom.java b/tests/tests/keystore/src/android/keystore/cts/CountingSecureRandom.java
new file mode 100644
index 0000000..ea4d0d1
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/CountingSecureRandom.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 java.security.SecureRandom;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * {@link SecureRandom} which counts how many bytes it has output.
+ */
+public class CountingSecureRandom extends SecureRandom {
+
+    private final SecureRandom mDelegate = new SecureRandom();
+    private final AtomicLong mOutputSizeBytes = new AtomicLong();
+
+    public long getOutputSizeBytes() {
+        return mOutputSizeBytes.get();
+    }
+
+    public void resetCounters() {
+        mOutputSizeBytes.set(0);
+    }
+
+    @Override
+    public byte[] generateSeed(int numBytes) {
+        if (numBytes > 0) {
+            mOutputSizeBytes.addAndGet(numBytes);
+        }
+        return mDelegate.generateSeed(numBytes);
+    }
+
+    @Override
+    public String getAlgorithm() {
+        return mDelegate.getAlgorithm();
+    }
+
+    @Override
+    public synchronized void nextBytes(byte[] bytes) {
+        if ((bytes != null) && (bytes.length > 0)) {
+            mOutputSizeBytes.addAndGet(bytes.length);
+        }
+        mDelegate.nextBytes(bytes);
+    }
+
+    @Override
+    public synchronized void setSeed(byte[] seed) {
+        // Ignore seeding -- not needed in tests and may impact the quality of the output of the
+        // delegate SecureRandom by preventing it from self-seeding
+    }
+
+    @Override
+    public void setSeed(long seed) {
+        // Ignore seeding -- not needed in tests and may impact the quality of the output of the
+        // delegate SecureRandom by preventing it from self-seeding
+    }
+
+    @Override
+    public boolean nextBoolean() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public double nextDouble() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public float nextFloat() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public synchronized double nextGaussian() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int nextInt() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public int nextInt(int n) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public long nextLong() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/ECCurves.java b/tests/tests/keystore/src/android/keystore/cts/ECCurves.java
new file mode 100644
index 0000000..24184e6
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/ECCurves.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 android.keystore.cts;
+
+import java.math.BigInteger;
+import java.security.spec.ECField;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.EllipticCurve;
+
+abstract class ECCurves {
+    private ECCurves() {}
+
+    // NIST EC curve parameters copied from "Standards for Efficient Cryptography 2 (SEC 2)".
+
+    static ECParameterSpec NIST_P_192_SPEC = createNistPCurveSpec(
+            new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", 16),
+            new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", 16),
+            new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", 16),
+            new BigInteger("64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", 16),
+            new BigInteger("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", 16),
+            new BigInteger("07192B95FFC8DA78631011ED6B24CDD573F977A11E794811", 16),
+            1,
+            HexEncoding.decode("3045AE6FC8422F64ED579528D38120EAE12196D5"));
+
+    static ECParameterSpec NIST_P_224_SPEC = createNistPCurveSpec(
+            new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", 16),
+            new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", 16),
+            new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", 16),
+            new BigInteger("B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", 16),
+            new BigInteger("B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", 16),
+            new BigInteger("BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", 16),
+            1,
+            HexEncoding.decode("BD71344799D5C7FCDC45B59FA3B9AB8F6A948BC5"));
+
+    static ECParameterSpec NIST_P_256_SPEC = createNistPCurveSpec(
+            new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFF"
+                    + "FFFFFFFF", 16),
+            new BigInteger("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2"
+                    + "FC632551", 16),
+            new BigInteger("FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFF"
+                    + "FFFFFFFC", 16),
+            new BigInteger("5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E"
+                    + "27D2604B", 16),
+            new BigInteger("6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945"
+                    + "D898C296", 16),
+            new BigInteger("4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB64068"
+                    + "37BF51F5", 16),
+            1,
+            HexEncoding.decode("C49D360886E704936A6678E1139D26B7819F7E90"));
+
+    static ECParameterSpec NIST_P_384_SPEC = createNistPCurveSpec(
+            new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                    + "FFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", 16),
+            new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81"
+                    + "F4372DDF581A0DB248B0A77AECEC196ACCC52973", 16),
+            new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                    + "FFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", 16),
+            new BigInteger("B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F"
+                    + "5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", 16),
+            new BigInteger("AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E0"
+                    + "82542A385502F25DBF55296C3A545E3872760AB7", 16),
+            new BigInteger("3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113"
+                    + "B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", 16),
+            1,
+            HexEncoding.decode("A335926AA319A27A1D00896A6773A4827ACDAC73"));
+
+    static ECParameterSpec NIST_P_521_SPEC = createNistPCurveSpec(
+            new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                    + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                    + "FFFFFFFFFFFFFFFFFFFFFFFF", 16),
+            new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                    + "FFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8"
+                    + "899C47AEBB6FB71E91386409", 16),
+            new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                    + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                    + "FFFFFFFFFFFFFFFFFFFFFFFC", 16),
+            new BigInteger("0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3"
+                    + "B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF88"
+                    + "3D2C34F1EF451FD46B503F00", 16),
+            new BigInteger("00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521"
+                    + "F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1"
+                    + "856A429BF97E7E31C2E5BD66", 16),
+            new BigInteger("011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B4468"
+                    + "17AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086"
+                    + "A272C24088BE94769FD16650", 16),
+            1,
+            HexEncoding.decode("D09E8800291CB85396CC6717393284AAA0DA64BA"));
+
+    private static ECParameterSpec createNistPCurveSpec(
+            BigInteger p,
+            BigInteger order,
+            BigInteger a,
+            BigInteger b,
+            BigInteger gx,
+            BigInteger gy,
+            int cofactor,
+            byte[] seed) {
+        ECField field = new ECFieldFp(p);
+        EllipticCurve curve = new EllipticCurve(field, a, b, seed);
+        ECPoint generator = new ECPoint(gx, gy);
+        return new ECParameterSpec(
+                curve,
+                generator,
+                order,
+                cofactor);
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.java
new file mode 100644
index 0000000..ea3940d
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/ECDSASignatureTest.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 android.keystore.cts;
+
+import android.content.Context;
+import android.security.keystore.KeyProtection;
+import android.test.AndroidTestCase;
+
+import com.android.cts.keystore.R;
+
+import java.security.KeyPair;
+import java.security.Security;
+import java.security.Signature;
+import java.util.Arrays;
+import java.util.Collection;
+
+public class ECDSASignatureTest extends AndroidTestCase {
+
+    public void testNONEwithECDSATruncatesInputToFieldSize() throws Exception {
+        for (ImportedKey key : importKatKeyPairs("NONEwithECDSA")) {
+            try {
+                assertNONEwithECDSATruncatesInputToFieldSize(key.getKeystoreBackedKeyPair());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + key.getAlias(), e);
+            }
+        }
+    }
+
+    private void assertNONEwithECDSATruncatesInputToFieldSize(KeyPair keyPair)
+            throws Exception {
+        int keySizeBits = TestUtils.getKeySizeBits(keyPair.getPublic());
+        byte[] message = new byte[(keySizeBits * 3) / 8];
+        for (int i = 0; i < message.length; i++) {
+            message[i] = (byte) (i + 1);
+        }
+
+        Signature signature = Signature.getInstance("NONEwithECDSA");
+        signature.initSign(keyPair.getPrivate());
+        assertSame(Security.getProvider(SignatureTest.EXPECTED_PROVIDER_NAME),
+                signature.getProvider());
+        signature.update(message);
+        byte[] sigBytes = signature.sign();
+
+        signature = Signature.getInstance(signature.getAlgorithm(), signature.getProvider());
+        signature.initVerify(keyPair.getPublic());
+
+        // Verify the full-length message
+        signature.update(message);
+        assertTrue(signature.verify(sigBytes));
+
+        // Verify the message truncated to field size
+        signature.update(message, 0, (keySizeBits + 7) / 8);
+        assertTrue(signature.verify(sigBytes));
+
+        // Verify message truncated to one byte shorter than field size -- this should fail
+        signature.update(message, 0, (keySizeBits / 8) - 1);
+        assertFalse(signature.verify(sigBytes));
+    }
+
+    public void testNONEwithECDSASupportsMessagesShorterThanFieldSize() throws Exception {
+        for (ImportedKey key : importKatKeyPairs("NONEwithECDSA")) {
+            try {
+                assertNONEwithECDSASupportsMessagesShorterThanFieldSize(
+                        key.getKeystoreBackedKeyPair());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + key.getAlias(), e);
+            }
+        }
+    }
+
+    private void assertNONEwithECDSASupportsMessagesShorterThanFieldSize(KeyPair keyPair)
+            throws Exception {
+        int keySizeBits = TestUtils.getKeySizeBits(keyPair.getPublic());
+        byte[] message = new byte[(keySizeBits * 3 / 4) / 8];
+        for (int i = 0; i < message.length; i++) {
+            message[i] = (byte) (i + 1);
+        }
+
+        Signature signature = Signature.getInstance("NONEwithECDSA");
+        signature.initSign(keyPair.getPrivate());
+        assertSame(Security.getProvider(SignatureTest.EXPECTED_PROVIDER_NAME),
+                signature.getProvider());
+        signature.update(message);
+        byte[] sigBytes = signature.sign();
+
+        signature = Signature.getInstance(signature.getAlgorithm(), signature.getProvider());
+        signature.initVerify(keyPair.getPublic());
+
+        // Verify the message
+        signature.update(message);
+        assertTrue(signature.verify(sigBytes));
+
+        // Assert that the message is left-padded with zero bits
+        byte[] fullLengthMessage = TestUtils.leftPadWithZeroBytes(message, keySizeBits / 8);
+        signature.update(fullLengthMessage);
+        assertTrue(signature.verify(sigBytes));
+    }
+
+    private Collection<ImportedKey> importKatKeyPairs(String signatureAlgorithm)
+            throws Exception {
+        KeyProtection params =
+                TestUtils.getMinimalWorkingImportParametersForSigningingWith(signatureAlgorithm);
+        return importKatKeyPairs(getContext(), params);
+    }
+
+    static Collection<ImportedKey> importKatKeyPairs(
+            Context context, KeyProtection importParams) throws Exception {
+        return Arrays.asList(new ImportedKey[] {
+                TestUtils.importIntoAndroidKeyStore("testECsecp224r1", context,
+                        R.raw.ec_key3_secp224r1_pkcs8, R.raw.ec_key3_secp224r1_cert, importParams),
+                TestUtils.importIntoAndroidKeyStore("testECsecp256r1", context,
+                        R.raw.ec_key4_secp256r1_pkcs8, R.raw.ec_key4_secp256r1_cert, importParams),
+                TestUtils.importIntoAndroidKeyStore("testECsecp384r1", context,
+                        R.raw.ec_key5_secp384r1_pkcs8, R.raw.ec_key5_secp384r1_cert, importParams),
+                TestUtils.importIntoAndroidKeyStore("testECsecp521r1", context,
+                        R.raw.ec_key6_secp521r1_pkcs8, R.raw.ec_key6_secp521r1_cert, importParams),
+                });
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java b/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
new file mode 100644
index 0000000..bf08b73
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/EmptyArray.java
@@ -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.
+ */
+
+package android.keystore.cts;
+
+abstract class EmptyArray {
+    private EmptyArray() {}
+
+    public static final byte[] BYTE = new byte[0];
+    public static final String[] STRING = new String[0];
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/HexEncoding.java b/tests/tests/keystore/src/android/keystore/cts/HexEncoding.java
new file mode 100644
index 0000000..9346f2d
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/HexEncoding.java
@@ -0,0 +1,94 @@
+/*
+ * 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.keystore.cts;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Hexadecimal encoding where each byte is represented by two hexadecimal digits.
+ *
+ * @hide
+ */
+public class HexEncoding {
+
+  /** Hidden constructor to prevent instantiation. */
+  private HexEncoding() {}
+
+  private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
+
+  /**
+   * Encodes the provided data as a hexadecimal string.
+   */
+  public static String encode(byte[] data) {
+    return encode(data, 0, data.length);
+  }
+
+  /**
+   * Encodes the provided data as a hexadecimal string.
+   */
+  public static String encode(byte[] data, int offset, int len) {
+    StringBuilder result = new StringBuilder(len * 2);
+    for (int i = 0; i < len; i++) {
+      byte b = data[offset + i];
+      result.append(HEX_DIGITS[(b >>> 4) & 0x0f]);
+      result.append(HEX_DIGITS[b & 0x0f]);
+    }
+    return result.toString();
+  }
+
+  /**
+   * Encodes the provided data as a hexadecimal string.
+   */
+  public static String encode(ByteBuffer buf) {
+    return encode(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining());
+  }
+
+  /**
+   * Decodes the provided hexadecimal string into an array of bytes.
+   */
+  public static byte[] decode(String encoded) {
+    // IMPLEMENTATION NOTE: Special care is taken to permit odd number of hexadecimal digits.
+    int resultLengthBytes = (encoded.length() + 1) / 2;
+    byte[] result = new byte[resultLengthBytes];
+    int resultOffset = 0;
+    int encodedCharOffset = 0;
+    if ((encoded.length() % 2) != 0) {
+      // Odd number of digits -- the first digit is the lower 4 bits of the first result byte.
+      result[resultOffset++] = (byte) getHexadecimalDigitValue(encoded.charAt(encodedCharOffset));
+      encodedCharOffset++;
+    }
+    for (int len = encoded.length(); encodedCharOffset < len; encodedCharOffset += 2) {
+      result[resultOffset++] = (byte)
+          ((getHexadecimalDigitValue(encoded.charAt(encodedCharOffset)) << 4)
+          | getHexadecimalDigitValue(encoded.charAt(encodedCharOffset + 1)));
+    }
+    return result;
+  }
+
+  private static int getHexadecimalDigitValue(char c) {
+    if ((c >= 'a') && (c <= 'f')) {
+      return (c - 'a') + 0x0a;
+    } else if ((c >= 'A') && (c <= 'F')) {
+      return (c - 'A') + 0x0a;
+    } else if ((c >= '0') && (c <= '9')) {
+      return c - '0';
+    } else {
+      throw new IllegalArgumentException(
+          "Invalid hexadecimal digit at position : '" + c + "' (0x" + Integer.toHexString(c) + ")");
+    }
+  }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/ImportedKey.java b/tests/tests/keystore/src/android/keystore/cts/ImportedKey.java
new file mode 100644
index 0000000..b6c868f
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/ImportedKey.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 java.security.Key;
+import java.security.KeyPair;
+
+import javax.crypto.SecretKey;
+
+public class ImportedKey {
+    private final boolean mSymmetric;
+    private final String mAlias;
+    private final KeyPair mOriginalKeyPair;
+    private final KeyPair mKeystoreBackedKeyPair;
+    private final SecretKey mOriginalSecretKey;
+    private final SecretKey mKeystoreBackedSecretKey;
+
+    public ImportedKey(String alias, KeyPair original, KeyPair keystoreBacked) {
+        mAlias = alias;
+        mSymmetric = false;
+        mOriginalKeyPair = original;
+        mKeystoreBackedKeyPair = keystoreBacked;
+        mOriginalSecretKey = null;
+        mKeystoreBackedSecretKey = null;
+    }
+
+    public ImportedKey(String alias, SecretKey original, SecretKey keystoreBacked) {
+        mAlias = alias;
+        mSymmetric = true;
+        mOriginalKeyPair = null;
+        mKeystoreBackedKeyPair = null;
+        mOriginalSecretKey = original;
+        mKeystoreBackedSecretKey = keystoreBacked;
+    }
+
+    public String getAlias() {
+        return mAlias;
+    }
+
+    public Key getOriginalEncryptionKey() {
+        if (mSymmetric) {
+            return mOriginalSecretKey;
+        } else {
+            return mOriginalKeyPair.getPublic();
+        }
+    }
+
+    public Key getOriginalDecryptionKey() {
+        if (mSymmetric) {
+            return mOriginalSecretKey;
+        } else {
+            return mOriginalKeyPair.getPrivate();
+        }
+    }
+
+    public Key getOriginalSigningKey() {
+        if (mSymmetric) {
+            return mOriginalSecretKey;
+        } else {
+            return mOriginalKeyPair.getPrivate();
+        }
+    }
+
+    public Key getOriginalVerificationKey() {
+        if (mSymmetric) {
+            return mOriginalSecretKey;
+        } else {
+            return mOriginalKeyPair.getPublic();
+        }
+    }
+
+    public Key getKeystoreBackedEncryptionKey() {
+        if (mSymmetric) {
+            return mKeystoreBackedSecretKey;
+        } else {
+            return mKeystoreBackedKeyPair.getPublic();
+        }
+    }
+
+    public Key getKeystoreBackedDecryptionKey() {
+        if (mSymmetric) {
+            return mKeystoreBackedSecretKey;
+        } else {
+            return mKeystoreBackedKeyPair.getPrivate();
+        }
+    }
+
+    public Key getKeystoreBackedSigningKey() {
+        if (mSymmetric) {
+            return mKeystoreBackedSecretKey;
+        } else {
+            return mKeystoreBackedKeyPair.getPrivate();
+        }
+    }
+
+    public Key getKeystoreBackedVerificationKey() {
+        if (mSymmetric) {
+            return mKeystoreBackedSecretKey;
+        } else {
+            return mKeystoreBackedKeyPair.getPublic();
+        }
+    }
+
+
+    public KeyPair getOriginalKeyPair() {
+        checkIsKeyPair();
+        return mOriginalKeyPair;
+    }
+
+    public KeyPair getKeystoreBackedKeyPair() {
+        checkIsKeyPair();
+        return mKeystoreBackedKeyPair;
+    }
+
+    public SecretKey getOriginalSecretKey() {
+        checkIsSecretKey();
+        return mOriginalSecretKey;
+    }
+
+    public SecretKey getKeystoreBackedSecretKey() {
+        checkIsSecretKey();
+        return mKeystoreBackedSecretKey;
+    }
+
+    private void checkIsKeyPair() {
+        if (mSymmetric) {
+            throw new IllegalStateException("Not a KeyPair");
+        }
+    }
+
+    private void checkIsSecretKey() {
+        if (!mSymmetric) {
+            throw new IllegalStateException("Not a SecretKey");
+        }
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyChainTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyChainTest.java
index 7aa6a9d..caa6336 100644
--- a/tests/tests/keystore/src/android/keystore/cts/KeyChainTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyChainTest.java
@@ -17,16 +17,70 @@
 package android.keystore.cts;
 
 import android.content.pm.PackageManager;
+import android.os.Handler;
 import android.security.KeyChain;
+import android.security.KeyChainException;
 import android.test.AndroidTestCase;
 
+import java.util.concurrent.CountDownLatch;
+
 public class KeyChainTest extends AndroidTestCase {
     public void testIsKeyAlgorithmSupported_RequiredAlgorithmsSupported() throws Exception {
-        assertTrue("DSA must be supported", KeyChain.isKeyAlgorithmSupported("DSA"));
+        assertFalse("DSA must not be supported", KeyChain.isKeyAlgorithmSupported("DSA"));
         assertTrue("EC must be supported", KeyChain.isKeyAlgorithmSupported("EC"));
         assertTrue("RSA must be supported", KeyChain.isKeyAlgorithmSupported("RSA"));
     }
 
+    public void testNullPrivateKeyArgumentsFail()
+            throws KeyChainException, InterruptedException {
+        try {
+            KeyChain.getPrivateKey(null, null);
+            fail("NullPointerException was expected for null arguments to "
+                    + "KeyChain.getPrivateKey(Context, String)");
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testNullPrivateKeyAliasArgumentFails()
+            throws KeyChainException, InterruptedException {
+        try {
+            KeyChain.getPrivateKey(getContext(), null);
+            fail("NullPointerException was expected with null String argument to "
+                        + "KeyChain.getPrivateKey(Context, String).");
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testNullPrivateKeyContextArgumentFails()
+            throws KeyChainException, InterruptedException {
+        try {
+            KeyChain.getPrivateKey(null, "");
+            fail("NullPointerException was expected with null Context argument to "
+                    + "KeyChain.getPrivateKey(Context, String).");
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    public void testGetPrivateKeyOnMainThreadFails() throws InterruptedException {
+        final CountDownLatch waiter = new CountDownLatch(1);
+        new Handler(getContext().getMainLooper()).post(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    KeyChain.getPrivateKey(getContext(), "");
+                    fail("IllegalStateException was expected for calling "
+                            + "KeyChain.getPrivateKey(Context, String) on main thread");
+                } catch (IllegalStateException expected) {
+                } catch (Exception invalid) {
+                    fail("Expected IllegalStateException, received " + invalid);
+                } finally {
+                    waiter.countDown();
+                }
+            }
+        });
+        waiter.await();
+    }
+
     /**
      * Tests whether the required algorithms are backed by a Keymaster HAL that
      * binds the key material to the specific device it was created or imported
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
new file mode 100644
index 0000000..d552631
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyFactoryTest.java
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyInfo;
+import android.security.keystore.KeyProperties;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+import com.android.cts.keystore.R;
+
+import java.io.InputStream;
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Security;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECPrivateKeySpec;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.RSAPrivateKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.security.Provider.Service;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+public class KeyFactoryTest extends AndroidTestCase {
+    private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_PROVIDER_NAME;
+
+    private static final String[] EXPECTED_ALGORITHMS = {
+        "EC",
+        "RSA",
+    };
+
+    public void testAlgorithmList() {
+        // Assert that Android Keystore Provider exposes exactly the expected KeyFactory algorithms.
+        // We don't care whether the algorithms are exposed via aliases, as long as canonical names
+        // of algorithms are accepted. If the Provider exposes extraneous algorithms, it'll be
+        // caught because it'll have to expose at least one Service for such an algorithm, and this
+        // Service's algorithm will not be in the expected set.
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        Set<Service> services = provider.getServices();
+        Set<String> actualAlgsLowerCase = new HashSet<String>();
+        Set<String> expectedAlgsLowerCase = new HashSet<String>(
+                Arrays.asList(TestUtils.toLowerCase(EXPECTED_ALGORITHMS)));
+        for (Service service : services) {
+            if ("KeyFactory".equalsIgnoreCase(service.getType())) {
+                String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US);
+                actualAlgsLowerCase.add(algLowerCase);
+            }
+        }
+
+        TestUtils.assertContentsInAnyOrder(actualAlgsLowerCase,
+                expectedAlgsLowerCase.toArray(new String[0]));
+    }
+
+    public void testGetKeySpecWithKeystorePrivateKeyAndKeyInfoReflectsAllAuthorizations()
+            throws Exception {
+        Date keyValidityStart = new Date(System.currentTimeMillis() - TestUtils.DAY_IN_MILLIS);
+        Date keyValidityForOriginationEnd =
+                new Date(System.currentTimeMillis() + TestUtils.DAY_IN_MILLIS);
+        Date keyValidityForConsumptionEnd =
+                new Date(System.currentTimeMillis() + 3 * TestUtils.DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                String[] blockModes = new String[] {KeyProperties.BLOCK_MODE_ECB};
+                String[] encryptionPaddings =
+                        new String[] {KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
+                                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP};
+                String[] digests = new String[] {KeyProperties.DIGEST_SHA1,
+                        KeyProperties.DIGEST_SHA224,
+                        KeyProperties.DIGEST_SHA384,
+                        KeyProperties.DIGEST_SHA512};
+                int purposes = KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_SIGN;
+                KeyPairGenerator keyGenerator =
+                        KeyPairGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.initialize(new KeyGenParameterSpec.Builder("test1", purposes)
+                        .setBlockModes(blockModes)
+                        .setEncryptionPaddings(encryptionPaddings)
+                        .setDigests(digests)
+                        .setKeyValidityStart(keyValidityStart)
+                        .setKeyValidityForOriginationEnd(keyValidityForOriginationEnd)
+                        .setKeyValidityForConsumptionEnd(keyValidityForConsumptionEnd)
+                        .build());
+                KeyPair keyPair = keyGenerator.generateKeyPair();
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                KeyInfo keyInfo = keyFactory.getKeySpec(keyPair.getPrivate(), KeyInfo.class);
+                assertEquals("test1", keyInfo.getKeystoreAlias());
+                assertEquals(purposes, keyInfo.getPurposes());
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(keyInfo.getBlockModes()), blockModes);
+
+                List<String> actualEncryptionPaddings =
+                        new ArrayList<String>(Arrays.asList(keyInfo.getEncryptionPaddings()));
+                // Keystore may have added ENCRYPTION_PADDING_NONE to allow software padding.
+                actualEncryptionPaddings.remove(KeyProperties.ENCRYPTION_PADDING_NONE);
+                TestUtils.assertContentsInAnyOrder(
+                        actualEncryptionPaddings, encryptionPaddings);
+
+                List<String> actualDigests =
+                        new ArrayList<String>(Arrays.asList(keyInfo.getDigests()));
+                // Keystore may have added DIGEST_NONE to allow software digesting.
+                actualDigests.remove(KeyProperties.DIGEST_NONE);
+                TestUtils.assertContentsInAnyOrder(actualDigests, digests);
+
+                MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+                assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
+                assertEquals(keyValidityForOriginationEnd,
+                        keyInfo.getKeyValidityForOriginationEnd());
+                assertEquals(keyValidityForConsumptionEnd,
+                        keyInfo.getKeyValidityForConsumptionEnd());
+                assertFalse(keyInfo.isUserAuthenticationRequired());
+                assertFalse(keyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGetKeySpecWithKeystorePublicKeyRejectsKeyInfo()
+            throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator keyGenerator =
+                        KeyPairGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.initialize(new KeyGenParameterSpec.Builder("test1", 0).build());
+                KeyPair keyPair = keyGenerator.generateKeyPair();
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.getKeySpec(keyPair.getPublic(), KeyInfo.class);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGetKeySpecWithKeystorePrivateKeyRejectsTransparentKeySpecAndEncodedKeySpec()
+            throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                Class<? extends KeySpec> transparentKeySpecClass;
+                if ("EC".equalsIgnoreCase(algorithm)) {
+                    transparentKeySpecClass = ECPrivateKeySpec.class;
+                } else if ("RSA".equalsIgnoreCase(algorithm)) {
+                    transparentKeySpecClass = RSAPrivateKeySpec.class;
+                } else {
+                    throw new RuntimeException("Unsupported key algorithm: " + algorithm);
+                }
+
+                KeyPairGenerator keyGenerator =
+                        KeyPairGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.initialize(new KeyGenParameterSpec.Builder("test1", 0).build());
+                KeyPair keyPair = keyGenerator.generateKeyPair();
+
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.getKeySpec(keyPair.getPrivate(), transparentKeySpecClass);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+
+                try {
+                    keyFactory.getKeySpec(keyPair.getPrivate(), PKCS8EncodedKeySpec.class);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGetKeySpecWithKeystorePublicKeyAcceptsX509EncodedKeySpec()
+            throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator keyGenerator =
+                        KeyPairGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.initialize(new KeyGenParameterSpec.Builder("test1", 0).build());
+                KeyPair keyPair = keyGenerator.generateKeyPair();
+                PublicKey publicKey = keyPair.getPublic();
+
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                X509EncodedKeySpec x509EncodedSpec =
+                        keyFactory.getKeySpec(publicKey, X509EncodedKeySpec.class);
+                MoreAsserts.assertEquals(publicKey.getEncoded(), x509EncodedSpec.getEncoded());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGetKeySpecWithKeystorePublicKeyAcceptsTransparentKeySpec()
+            throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator keyGenerator =
+                        KeyPairGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.initialize(new KeyGenParameterSpec.Builder("test1", 0).build());
+                KeyPair keyPair = keyGenerator.generateKeyPair();
+                PublicKey publicKey = keyPair.getPublic();
+
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                if ("EC".equalsIgnoreCase(algorithm)) {
+                    ECPublicKey ecPublicKey = (ECPublicKey) publicKey;
+                    ECPublicKeySpec spec =
+                            keyFactory.getKeySpec(publicKey, ECPublicKeySpec.class);
+                    assertEquals(ecPublicKey.getW(), spec.getW());
+                    TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+                            ecPublicKey.getParams(), spec.getParams());
+                } else if ("RSA".equalsIgnoreCase(algorithm)) {
+                    RSAPublicKey rsaPublicKey = (RSAPublicKey) publicKey;
+                    RSAPublicKeySpec spec =
+                            keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);
+                    assertEquals(rsaPublicKey.getModulus(), spec.getModulus());
+                    assertEquals(rsaPublicKey.getPublicExponent(), spec.getPublicExponent());
+                } else {
+                    throw new RuntimeException("Unsupported key algorithm: " + algorithm);
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testTranslateKeyWithNullKeyThrowsInvalidKeyException() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.translateKey(null);
+                    fail();
+                } catch (InvalidKeyException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testTranslateKeyRejectsNonAndroidKeystoreKeys() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKey key = new SecretKeySpec(new byte[16], algorithm);
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.translateKey(key);
+                    fail();
+                } catch (InvalidKeyException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testTranslateKeyAcceptsAndroidKeystoreKeys() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator keyGenerator =
+                        KeyPairGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.initialize(new KeyGenParameterSpec.Builder("test1", 0).build());
+                KeyPair keyPair = keyGenerator.generateKeyPair();
+
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                assertSame(keyPair.getPrivate(), keyFactory.translateKey(keyPair.getPrivate()));
+                assertSame(keyPair.getPublic(), keyFactory.translateKey(keyPair.getPublic()));
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGeneratePrivateWithNullSpecThrowsInvalidKeySpecException() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generatePrivate(null);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGeneratePublicWithNullSpecThrowsInvalidKeySpecException() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generatePublic(null);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGeneratePrivateRejectsPKCS8EncodedKeySpec() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            int resId;
+            if ("EC".equalsIgnoreCase(algorithm)) {
+                resId = R.raw.ec_key1_pkcs8;
+            } else if ("RSA".equalsIgnoreCase(algorithm)) {
+                resId = R.raw.rsa_key2_pkcs8;
+            } else {
+                throw new RuntimeException("Unsupported key algorithm: " + algorithm);
+            }
+
+            byte[] pkcs8EncodedForm;
+            try (InputStream in = getContext().getResources().openRawResource(resId)) {
+                pkcs8EncodedForm = TestUtils.drain(in);
+            }
+            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(pkcs8EncodedForm);
+            try {
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generatePrivate(spec);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGeneratePublicRejectsX509EncodedKeySpec() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            int resId;
+            if ("EC".equalsIgnoreCase(algorithm)) {
+                resId = R.raw.ec_key2_cert;
+            } else if ("RSA".equalsIgnoreCase(algorithm)) {
+                resId = R.raw.rsa_key1_cert;
+            } else {
+                throw new RuntimeException("Unsupported key algorithm: " + algorithm);
+            }
+
+            byte[] x509EncodedForm;
+            try (InputStream in = getContext().getResources().openRawResource(resId)) {
+                x509EncodedForm = TestUtils.drain(in);
+            }
+            X509EncodedKeySpec spec = new X509EncodedKeySpec(x509EncodedForm);
+            try {
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generatePublic(spec);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGeneratePrivateRejectsTransparentKeySpec() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            int resId;
+            Class<? extends KeySpec> keySpecClass;
+            if ("EC".equalsIgnoreCase(algorithm)) {
+                resId = R.raw.ec_key2_pkcs8;
+                keySpecClass = ECPrivateKeySpec.class;
+            } else if ("RSA".equalsIgnoreCase(algorithm)) {
+                resId = R.raw.rsa_key2_pkcs8;
+                keySpecClass = RSAPrivateKeySpec.class;
+            } else {
+                throw new RuntimeException("Unsupported key algorithm: " + algorithm);
+            }
+            PrivateKey key = TestUtils.getRawResPrivateKey(getContext(), resId);
+            KeyFactory anotherKeyFactory = KeyFactory.getInstance(algorithm);
+            KeySpec spec = anotherKeyFactory.getKeySpec(key, keySpecClass);
+
+            try {
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generatePrivate(spec);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGeneratePublicRejectsTransparentKeySpec() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            int resId;
+            Class<? extends KeySpec> keySpecClass;
+            if ("EC".equalsIgnoreCase(algorithm)) {
+                resId = R.raw.ec_key2_cert;
+                keySpecClass = ECPublicKeySpec.class;
+            } else if ("RSA".equalsIgnoreCase(algorithm)) {
+                resId = R.raw.rsa_key2_cert;
+                keySpecClass = RSAPublicKeySpec.class;
+            } else {
+                throw new RuntimeException("Unsupported key algorithm: " + algorithm);
+            }
+            PublicKey key = TestUtils.getRawResX509Certificate(getContext(), resId).getPublicKey();
+            KeyFactory anotherKeyFactory = KeyFactory.getInstance(algorithm);
+            KeySpec spec = anotherKeyFactory.getKeySpec(key, keySpecClass);
+
+            try {
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generatePublic(spec);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGeneratePrivateAndPublicRejectKeyInfo() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator keyGenerator =
+                        KeyPairGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.initialize(new KeyGenParameterSpec.Builder("test1", 0).build());
+                KeyPair keyPair = keyGenerator.generateKeyPair();
+                KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+
+                KeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generatePrivate(keyInfo);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+
+                try {
+                    keyFactory.generatePublic(keyInfo);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    private KeyFactory getKeyFactory(String algorithm) throws NoSuchAlgorithmException,
+            NoSuchProviderException {
+        return KeyFactory.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGenParameterSpecTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGenParameterSpecTest.java
new file mode 100644
index 0000000..a3e5d96
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGenParameterSpecTest.java
@@ -0,0 +1,328 @@
+/*
+ * 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.keystore.cts;
+
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyProperties;
+import android.test.MoreAsserts;
+
+import junit.framework.TestCase;
+
+import java.math.BigInteger;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.util.Arrays;
+import java.util.Date;
+
+import javax.security.auth.x500.X500Principal;
+
+public class KeyGenParameterSpecTest extends TestCase {
+
+    private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
+    private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
+    private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
+    private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
+
+    public void testDefaults() {
+        // Set only the mandatory parameters and assert values returned by getters.
+
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "arbitrary", KeyProperties.PURPOSE_ENCRYPT)
+                .build();
+
+        assertEquals("arbitrary", spec.getKeystoreAlias());
+        assertEquals(KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
+        assertNull(null, spec.getAlgorithmParameterSpec());
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getBlockModes()));
+        assertEquals(DEFAULT_CERT_NOT_BEFORE, spec.getCertificateNotBefore());
+        assertEquals(DEFAULT_CERT_NOT_AFTER, spec.getCertificateNotAfter());
+        assertEquals(DEFAULT_CERT_SERIAL_NUMBER, spec.getCertificateSerialNumber());
+        assertEquals(DEFAULT_CERT_SUBJECT, spec.getCertificateSubject());
+        assertFalse(spec.isDigestsSpecified());
+        try {
+            spec.getDigests();
+            fail();
+        } catch (IllegalStateException expected) {}
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getEncryptionPaddings()));
+        assertEquals(-1, spec.getKeySize());
+        assertNull(spec.getKeyValidityStart());
+        assertNull(spec.getKeyValidityForOriginationEnd());
+        assertNull(spec.getKeyValidityForConsumptionEnd());
+        assertTrue(spec.isRandomizedEncryptionRequired());
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getSignaturePaddings()));
+        assertFalse(spec.isUserAuthenticationRequired());
+        assertEquals(-1, spec.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testSettersReflectedInGetters() {
+        // Set all parameters to non-default values and then assert that getters reflect that.
+
+        Date certNotBeforeDate = new Date(System.currentTimeMillis());
+        Date certNotAfterDate = new Date(System.currentTimeMillis() + 12345678);
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+        AlgorithmParameterSpec algSpecificParams = new ECGenParameterSpec("secp256r1");
+
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setAlgorithmParameterSpec(algSpecificParams)
+                .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
+                .setCertificateNotBefore(certNotBeforeDate)
+                .setCertificateNotAfter(certNotAfterDate)
+                .setCertificateSerialNumber(new BigInteger("13946146"))
+                .setCertificateSubject(new X500Principal("CN=test"))
+                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                        KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                .setKeySize(1234)
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setRandomizedEncryptionRequired(false)
+                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                .setUserAuthenticationRequired(true)
+                .setUserAuthenticationValidityDurationSeconds(12345)
+                .build();
+
+        assertEquals("arbitrary", spec.getKeystoreAlias());
+        assertEquals(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
+        assertSame(algSpecificParams, spec.getAlgorithmParameterSpec());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getBlockModes()),
+                KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC);
+        assertEquals(certNotBeforeDate, spec.getCertificateNotBefore());
+        assertEquals(certNotAfterDate, spec.getCertificateNotAfter());
+        assertEquals(new BigInteger("13946146"), spec.getCertificateSerialNumber());
+        assertEquals(new X500Principal("CN=test"), spec.getCertificateSubject());
+        assertTrue(spec.isDigestsSpecified());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getDigests()),
+                KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA384);
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getEncryptionPaddings()),
+                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7);
+        assertEquals(1234, spec.getKeySize());
+        assertEquals(keyValidityStartDate, spec.getKeyValidityStart());
+        assertEquals(keyValidityEndDateForOrigination, spec.getKeyValidityForOriginationEnd());
+        assertEquals(keyValidityEndDateForConsumption, spec.getKeyValidityForConsumptionEnd());
+        assertFalse(spec.isRandomizedEncryptionRequired());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getSignaturePaddings()),
+                KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
+        assertTrue(spec.isUserAuthenticationRequired());
+        assertEquals(12345, spec.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testNullAliasNotPermitted() {
+        try {
+            new KeyGenParameterSpec.Builder(null, KeyProperties.PURPOSE_ENCRYPT);
+            fail();
+        } catch (NullPointerException expected) {}
+    }
+
+    public void testEmptyAliasNotPermitted() {
+        try {
+            new KeyGenParameterSpec.Builder("", KeyProperties.PURPOSE_ENCRYPT);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    public void testSetKeyValidityEndDateAppliesToBothEndDates() {
+        Date date = new Date(System.currentTimeMillis() + 555555);
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "ignore", KeyProperties.PURPOSE_VERIFY)
+                .setKeyValidityEnd(date)
+                .build();
+        assertEquals(date, spec.getKeyValidityForOriginationEnd());
+        assertEquals(date, spec.getKeyValidityForConsumptionEnd());
+    }
+
+    public void testSetUserAuthenticationValidityDurationSecondsValidityCheck() {
+        KeyGenParameterSpec.Builder builder = new KeyGenParameterSpec.Builder("alias", 0);
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-2);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-100);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(Integer.MIN_VALUE);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        builder.setUserAuthenticationValidityDurationSeconds(-1);
+        builder.setUserAuthenticationValidityDurationSeconds(0);
+        builder.setUserAuthenticationValidityDurationSeconds(1);
+        builder.setUserAuthenticationValidityDurationSeconds(Integer.MAX_VALUE);
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-2);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    public void testImmutabilityViaSetterParams() {
+        // Assert that all mutable parameters provided to setters are copied to ensure that values
+        // returned by getters never change.
+        String[] blockModes =
+                new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
+        String[] originalBlockModes = blockModes.clone();
+        Date certNotBeforeDate = new Date(System.currentTimeMillis());
+        Date originalCertNotBeforeDate = new Date(certNotBeforeDate.getTime());
+        Date certNotAfterDate = new Date(System.currentTimeMillis() + 12345678);
+        Date originalCertNotAfterDate = new Date(certNotAfterDate.getTime());
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date originalKeyValidityStartDate = new Date(keyValidityStartDate.getTime());
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date originalKeyValidityEndDateForOrigination =
+                new Date(keyValidityEndDateForOrigination.getTime());
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+        Date originalKeyValidityEndDateForConsumption =
+                new Date(keyValidityEndDateForConsumption.getTime());
+        String[] digests = new String[] {KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512};
+        String[] originalDigests = digests.clone();
+        String[] encryptionPaddings = new String[] {
+                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7};
+        String[] originalEncryptionPaddings = encryptionPaddings.clone();
+        String[] signaturePaddings = new String[] {
+                KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1};
+        String[] originalSignaturePaddings = signaturePaddings.clone();
+
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setBlockModes(blockModes)
+                .setCertificateNotBefore(certNotBeforeDate)
+                .setCertificateNotAfter(certNotAfterDate)
+                .setDigests(digests)
+                .setEncryptionPaddings(encryptionPaddings)
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setSignaturePaddings(signaturePaddings)
+                .build();
+
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+        blockModes[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+        assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
+        certNotBeforeDate.setTime(1234567890L);
+        assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
+
+        assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
+        certNotAfterDate.setTime(1234567890L);
+        assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
+
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+        digests[1] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+        encryptionPaddings[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+        keyValidityStartDate.setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+        keyValidityEndDateForOrigination.setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+        keyValidityEndDateForConsumption.setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+        signaturePaddings[1] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+    }
+
+    public void testImmutabilityViaGetterReturnValues() {
+        // Assert that none of the mutable return values from getters modify the state of the spec.
+
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                "arbitrary", KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
+                .setCertificateNotBefore(new Date(System.currentTimeMillis()))
+                .setCertificateNotAfter(new Date(System.currentTimeMillis() + 12345678))
+                .setDigests(KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512)
+                .setEncryptionPaddings(
+                        KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                        KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                .setKeyValidityStart(new Date(System.currentTimeMillis() - 2222222))
+                .setKeyValidityForOriginationEnd(new Date(System.currentTimeMillis() + 11111111))
+                .setKeyValidityForConsumptionEnd(new Date(System.currentTimeMillis() + 33333333))
+                .setSignaturePaddings(
+                        KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                .build();
+
+        String[] originalBlockModes = spec.getBlockModes().clone();
+        spec.getBlockModes()[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+        Date originalCertNotBeforeDate = (Date) spec.getCertificateNotBefore().clone();
+        spec.getCertificateNotBefore().setTime(1234567890L);
+        assertEquals(originalCertNotBeforeDate, spec.getCertificateNotBefore());
+
+        Date originalCertNotAfterDate = (Date) spec.getCertificateNotAfter().clone();
+        spec.getCertificateNotAfter().setTime(1234567890L);
+        assertEquals(originalCertNotAfterDate, spec.getCertificateNotAfter());
+
+        String[] originalDigests = spec.getDigests().clone();
+        spec.getDigests()[0] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+        String[] originalEncryptionPaddings = spec.getEncryptionPaddings().clone();
+        spec.getEncryptionPaddings()[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+
+        Date originalKeyValidityStartDate = (Date) spec.getKeyValidityStart().clone();
+        spec.getKeyValidityStart().setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+        Date originalKeyValidityEndDateForOrigination =
+                (Date) spec.getKeyValidityForOriginationEnd().clone();
+        spec.getKeyValidityForOriginationEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+
+        Date originalKeyValidityEndDateForConsumption =
+                (Date) spec.getKeyValidityForConsumptionEnd().clone();
+        spec.getKeyValidityForConsumptionEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+
+        String[] originalSignaturePaddings = spec.getSignaturePaddings().clone();
+        spec.getSignaturePaddings()[0] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.java
new file mode 100644
index 0000000..6deaed4
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyGeneratorTest.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 android.keystore.cts;
+
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyInfo;
+import android.security.keystore.KeyProperties;
+import android.test.MoreAsserts;
+
+import junit.framework.TestCase;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.Provider.Service;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+
+public class KeyGeneratorTest extends TestCase {
+    private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_PROVIDER_NAME;
+
+    static final String[] EXPECTED_ALGORITHMS = {
+        "AES",
+        "HmacSHA1",
+        "HmacSHA224",
+        "HmacSHA256",
+        "HmacSHA384",
+        "HmacSHA512",
+    };
+
+    private static final Map<String, Integer> DEFAULT_KEY_SIZES =
+            new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+    static {
+        DEFAULT_KEY_SIZES.put("AES", 128);
+        DEFAULT_KEY_SIZES.put("HmacSHA1", 160);
+        DEFAULT_KEY_SIZES.put("HmacSHA224", 224);
+        DEFAULT_KEY_SIZES.put("HmacSHA256", 256);
+        DEFAULT_KEY_SIZES.put("HmacSHA384", 384);
+        DEFAULT_KEY_SIZES.put("HmacSHA512", 512);
+    }
+
+    static final int[] AES_SUPPORTED_KEY_SIZES = new int[] {128, 192, 256};
+
+    public void testAlgorithmList() {
+        // Assert that Android Keystore Provider exposes exactly the expected KeyGenerator
+        // algorithms. We don't care whether the algorithms are exposed via aliases, as long as
+        // canonical names of algorithms are accepted. If the Provider exposes extraneous
+        // algorithms, it'll be caught because it'll have to expose at least one Service for such an
+        // algorithm, and this Service's algorithm will not be in the expected set.
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        Set<Service> services = provider.getServices();
+        Set<String> actualAlgsLowerCase = new HashSet<String>();
+        Set<String> expectedAlgsLowerCase = new HashSet<String>(
+                Arrays.asList(TestUtils.toLowerCase(EXPECTED_ALGORITHMS)));
+        for (Service service : services) {
+            if ("KeyGenerator".equalsIgnoreCase(service.getType())) {
+                String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US);
+                actualAlgsLowerCase.add(algLowerCase);
+            }
+        }
+
+        TestUtils.assertContentsInAnyOrder(actualAlgsLowerCase,
+                expectedAlgsLowerCase.toArray(new String[0]));
+    }
+
+    public void testGenerateWithoutInitThrowsIllegalStateException() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                try {
+                    keyGenerator.generateKey();
+                    fail();
+                } catch (IllegalStateException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithKeySizeThrowsUnsupportedOperationException() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                int keySizeBits = DEFAULT_KEY_SIZES.get(algorithm);
+                try {
+                    keyGenerator.init(keySizeBits);
+                    fail();
+                } catch (UnsupportedOperationException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithKeySizeAndSecureRandomThrowsUnsupportedOperationException()
+            throws Exception {
+        SecureRandom rng = new SecureRandom();
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                int keySizeBits = DEFAULT_KEY_SIZES.get(algorithm);
+                try {
+                    keyGenerator.init(keySizeBits, rng);
+                    fail();
+                } catch (UnsupportedOperationException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithNullAlgParamsThrowsInvalidAlgorithmParameterException()
+            throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                try {
+                    keyGenerator.init((AlgorithmParameterSpec) null);
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithNullAlgParamsAndSecureRandomThrowsInvalidAlgorithmParameterException()
+            throws Exception {
+        SecureRandom rng = new SecureRandom();
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                try {
+                    keyGenerator.init((AlgorithmParameterSpec) null, rng);
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithAlgParamsAndNullSecureRandom()
+            throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                keyGenerator.init(getWorkingSpec().build(), (SecureRandom) null);
+                // Check that generateKey doesn't fail either, just in case null SecureRandom
+                // causes trouble there.
+                keyGenerator.generateKey();
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithUnsupportedAlgParamsTypeThrowsInvalidAlgorithmParameterException()
+            throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                try {
+                    keyGenerator.init(new ECGenParameterSpec("secp256r1"));
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testDefaultKeySize() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                int expectedSizeBits = DEFAULT_KEY_SIZES.get(algorithm);
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                keyGenerator.init(getWorkingSpec().build());
+                SecretKey key = keyGenerator.generateKey();
+                assertEquals(expectedSizeBits, TestUtils.getKeyInfo(key).getKeySize());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testAesKeySupportedSizes() throws Exception {
+        KeyGenerator keyGenerator = getKeyGenerator("AES");
+        KeyGenParameterSpec.Builder goodSpec = getWorkingSpec();
+        CountingSecureRandom rng = new CountingSecureRandom();
+        for (int i = -16; i <= 512; i++) {
+            try {
+                rng.resetCounters();
+                KeyGenParameterSpec spec;
+                if (i >= 0) {
+                    spec = TestUtils.buildUpon(goodSpec.setKeySize(i)).build();
+                } else {
+                    try {
+                        spec = TestUtils.buildUpon(goodSpec.setKeySize(i)).build();
+                        fail();
+                    } catch (IllegalArgumentException expected) {
+                        continue;
+                    }
+                }
+                rng.resetCounters();
+                if (TestUtils.contains(AES_SUPPORTED_KEY_SIZES, i)) {
+                    keyGenerator.init(spec, rng);
+                    SecretKey key = keyGenerator.generateKey();
+                    assertEquals(i, TestUtils.getKeyInfo(key).getKeySize());
+                    assertEquals((i + 7) / 8, rng.getOutputSizeBytes());
+                } else {
+                    try {
+                        keyGenerator.init(spec, rng);
+                        fail();
+                    } catch (InvalidAlgorithmParameterException expected) {}
+                    assertEquals(0, rng.getOutputSizeBytes());
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for key size " + i, e);
+            }
+        }
+    }
+
+    public void testHmacKeySupportedSizes() throws Exception {
+        CountingSecureRandom rng = new CountingSecureRandom();
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            if (!TestUtils.isHmacAlgorithm(algorithm)) {
+                continue;
+            }
+
+            for (int i = -16; i <= 1024; i++) {
+                try {
+                    rng.resetCounters();
+                    KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                    KeyGenParameterSpec spec;
+                    if (i >= 0) {
+                        spec = getWorkingSpec().setKeySize(i).build();
+                    } else {
+                        try {
+                            spec = getWorkingSpec().setKeySize(i).build();
+                            fail();
+                        } catch (IllegalArgumentException expected) {
+                            continue;
+                        }
+                    }
+                    if ((i > 0) && ((i % 8 ) == 0)) {
+                        keyGenerator.init(spec, rng);
+                        SecretKey key = keyGenerator.generateKey();
+                        assertEquals(i, TestUtils.getKeyInfo(key).getKeySize());
+                        assertEquals((i + 7) / 8, rng.getOutputSizeBytes());
+                    } else {
+                        try {
+                            keyGenerator.init(spec, rng);
+                            fail();
+                        } catch (InvalidAlgorithmParameterException expected) {}
+                        assertEquals(0, rng.getOutputSizeBytes());
+                    }
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key size " + i, e);
+                }
+            }
+        }
+    }
+
+    public void testHmacKeyOnlyOneDigestCanBeAuthorized() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            if (!TestUtils.isHmacAlgorithm(algorithm)) {
+                continue;
+            }
+
+            try {
+                String digest = TestUtils.getHmacAlgorithmDigest(algorithm);
+                assertNotNull(digest);
+
+                KeyGenParameterSpec.Builder goodSpec = new KeyGenParameterSpec.Builder(
+                        "test1", KeyProperties.PURPOSE_SIGN);
+
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+
+                // Digests authorization not specified in algorithm parameters
+                assertFalse(goodSpec.build().isDigestsSpecified());
+                keyGenerator.init(goodSpec.build());
+                SecretKey key = keyGenerator.generateKey();
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(TestUtils.getKeyInfo(key).getDigests()), digest);
+
+                // The same digest is specified in algorithm parameters
+                keyGenerator.init(TestUtils.buildUpon(goodSpec).setDigests(digest).build());
+                key = keyGenerator.generateKey();
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(TestUtils.getKeyInfo(key).getDigests()), digest);
+
+                // No digests specified in algorithm parameters
+                try {
+                    keyGenerator.init(TestUtils.buildUpon(goodSpec).setDigests().build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+
+                // A different digest specified in algorithm parameters
+                String anotherDigest = "SHA-256".equalsIgnoreCase(digest) ? "SHA-384" : "SHA-256";
+                try {
+                    keyGenerator.init(TestUtils.buildUpon(goodSpec)
+                            .setDigests(anotherDigest)
+                            .build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+                try {
+                    keyGenerator.init(TestUtils.buildUpon(goodSpec)
+                            .setDigests(digest, anotherDigest)
+                            .build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithUnknownBlockModeFails() {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                try {
+                    keyGenerator.init(getWorkingSpec().setBlockModes("weird").build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithUnknownEncryptionPaddingFails() {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                try {
+                    keyGenerator.init(getWorkingSpec().setEncryptionPaddings("weird").build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithSignaturePaddingFails() {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                try {
+                    keyGenerator.init(getWorkingSpec()
+                            .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                            .build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithUnknownDigestFails() {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                try {
+                    String[] digests;
+                    if (TestUtils.isHmacAlgorithm(algorithm)) {
+                        // The digest from HMAC key algorithm must be specified in the list of
+                        // authorized digests (if the list if provided).
+                        digests = new String[] {algorithm, "weird"};
+                    } else {
+                        digests = new String[] {"weird"};
+                    }
+                    keyGenerator.init(getWorkingSpec().setDigests(digests).build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithKeyAlgorithmDigestMissingFromAuthorizedDigestFails() {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            if (!TestUtils.isHmacAlgorithm(algorithm)) {
+                continue;
+            }
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+
+                // Authorized for digest(s) none of which is the one implied by key algorithm.
+                try {
+                    String digest = TestUtils.getHmacAlgorithmDigest(algorithm);
+                    String anotherDigest = KeyProperties.DIGEST_SHA256.equalsIgnoreCase(digest)
+                            ? KeyProperties.DIGEST_SHA512 : KeyProperties.DIGEST_SHA256;
+                    keyGenerator.init(getWorkingSpec().setDigests(anotherDigest).build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+
+                // Authorized for empty set of digests
+                try {
+                    keyGenerator.init(getWorkingSpec().setDigests().build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitRandomizedEncryptionRequiredButViolatedFails() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                try {
+                    keyGenerator.init(getWorkingSpec(
+                            KeyProperties.PURPOSE_ENCRYPT)
+                            .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
+                            .build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGenerateHonorsRequestedAuthorizations() throws Exception {
+        Date keyValidityStart = new Date(System.currentTimeMillis() - TestUtils.DAY_IN_MILLIS);
+        Date keyValidityForOriginationEnd =
+                new Date(System.currentTimeMillis() + TestUtils.DAY_IN_MILLIS);
+        Date keyValidityForConsumptionEnd =
+                new Date(System.currentTimeMillis() + 3 * TestUtils.DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                String[] blockModes =
+                        new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
+                String[] encryptionPaddings =
+                        new String[] {KeyProperties.ENCRYPTION_PADDING_PKCS7,
+                                KeyProperties.ENCRYPTION_PADDING_NONE};
+                String[] digests;
+                int purposes;
+                if (TestUtils.isHmacAlgorithm(algorithm)) {
+                    // HMAC key can only be authorized for one digest, the one implied by the key's
+                    // JCA algorithm name.
+                    digests = new String[] {TestUtils.getHmacAlgorithmDigest(algorithm)};
+                    purposes = KeyProperties.PURPOSE_SIGN;
+                } else {
+                    digests = new String[] {KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA1};
+                    purposes = KeyProperties.PURPOSE_DECRYPT;
+                }
+                KeyGenerator keyGenerator = getKeyGenerator(algorithm);
+                keyGenerator.init(getWorkingSpec(purposes)
+                        .setBlockModes(blockModes)
+                        .setEncryptionPaddings(encryptionPaddings)
+                        .setDigests(digests)
+                        .setKeyValidityStart(keyValidityStart)
+                        .setKeyValidityForOriginationEnd(keyValidityForOriginationEnd)
+                        .setKeyValidityForConsumptionEnd(keyValidityForConsumptionEnd)
+                        .build());
+                SecretKey key = keyGenerator.generateKey();
+                assertEquals(algorithm, key.getAlgorithm());
+
+                KeyInfo keyInfo = TestUtils.getKeyInfo(key);
+                assertEquals(purposes, keyInfo.getPurposes());
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(blockModes), keyInfo.getBlockModes());
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(encryptionPaddings), keyInfo.getEncryptionPaddings());
+                TestUtils.assertContentsInAnyOrder(Arrays.asList(digests), keyInfo.getDigests());
+                MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+                assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
+                assertEquals(keyValidityForOriginationEnd,
+                        keyInfo.getKeyValidityForOriginationEnd());
+                assertEquals(keyValidityForConsumptionEnd,
+                        keyInfo.getKeyValidityForConsumptionEnd());
+                assertFalse(keyInfo.isUserAuthenticationRequired());
+                assertFalse(keyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    private static KeyGenParameterSpec.Builder getWorkingSpec() {
+        return getWorkingSpec(0);
+    }
+
+    private static KeyGenParameterSpec.Builder getWorkingSpec(int purposes) {
+        return new KeyGenParameterSpec.Builder("test1", purposes);
+    }
+
+    private static KeyGenerator getKeyGenerator(String algorithm) throws NoSuchAlgorithmException,
+            NoSuchProviderException {
+        return KeyGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyInfoTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyInfoTest.java
new file mode 100644
index 0000000..2b1d6fc
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyInfoTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.keystore.cts;
+
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyInfo;
+import android.security.keystore.KeyProperties;
+
+import junit.framework.TestCase;
+
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.util.Arrays;
+import java.util.Date;
+
+public class KeyInfoTest extends TestCase {
+
+    public void testImmutabilityViaGetterReturnValues() throws Exception {
+        // Assert that none of the mutable return values from getters modify the state of the
+        // instance.
+
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+
+        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "AndroidKeyStore");
+        keyPairGenerator.initialize(new KeyGenParameterSpec.Builder(
+                KeyInfoTest.class.getSimpleName(),
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setKeySize(1024) // use smaller key size to speed the test up
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
+                        KeyProperties.ENCRYPTION_PADDING_RSA_OAEP)
+                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PSS)
+                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+                .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
+                .build());
+        KeyPair keyPair = keyPairGenerator.generateKeyPair();
+
+        PrivateKey key = keyPair.getPrivate();
+        KeyFactory keyFactory = KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore");
+        KeyInfo info = keyFactory.getKeySpec(key, KeyInfo.class);
+
+        Date originalKeyValidityStartDate = (Date) info.getKeyValidityStart().clone();
+        info.getKeyValidityStart().setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, info.getKeyValidityStart());
+
+        Date originalKeyValidityEndDateForOrigination =
+                (Date) info.getKeyValidityForOriginationEnd().clone();
+        info.getKeyValidityForOriginationEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                info.getKeyValidityForOriginationEnd());
+
+        Date originalKeyValidityEndDateForConsumption =
+                (Date) info.getKeyValidityForConsumptionEnd().clone();
+        info.getKeyValidityForConsumptionEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                info.getKeyValidityForConsumptionEnd());
+
+        String[] originalEncryptionPaddings = info.getEncryptionPaddings().clone();
+        info.getEncryptionPaddings()[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(info.getEncryptionPaddings()));
+
+        String[] originalSignaturePaddings = info.getSignaturePaddings().clone();
+        info.getSignaturePaddings()[0] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(info.getSignaturePaddings()));
+
+        String[] originalDigests = info.getDigests().clone();
+        info.getDigests()[0] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(info.getDigests()));
+
+        String[] originalBlockModes = info.getBlockModes().clone();
+        info.getBlockModes()[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(info.getBlockModes()));
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
new file mode 100644
index 0000000..4c59652
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyPairGeneratorTest.java
@@ -0,0 +1,1513 @@
+/*
+ * 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 android.keystore.cts;
+
+import android.security.KeyPairGeneratorSpec;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyInfo;
+import android.security.keystore.KeyProperties;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+import java.math.BigInteger;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.Provider.Service;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.RSAKeyGenParameterSpec;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.security.auth.x500.X500Principal;
+
+import libcore.java.security.TestKeyStore;
+import libcore.javax.net.ssl.TestKeyManager;
+import libcore.javax.net.ssl.TestSSLContext;
+
+public class KeyPairGeneratorTest extends AndroidTestCase {
+    private KeyStore mKeyStore;
+
+    private CountingSecureRandom mRng;
+
+    private static final String TEST_ALIAS_1 = "test1";
+
+    private static final String TEST_ALIAS_2 = "test2";
+
+    private static final String TEST_ALIAS_3 = "test3";
+
+    private static final X500Principal TEST_DN_1 = new X500Principal("CN=test1");
+
+    private static final X500Principal TEST_DN_2 = new X500Principal("CN=test2");
+
+    private static final BigInteger TEST_SERIAL_1 = BigInteger.ONE;
+
+    private static final BigInteger TEST_SERIAL_2 = BigInteger.valueOf(2L);
+
+    private static final long NOW_MILLIS = System.currentTimeMillis();
+
+    /* We have to round this off because X509v3 doesn't store milliseconds. */
+    private static final Date NOW = new Date(NOW_MILLIS - (NOW_MILLIS % 1000L));
+
+    @SuppressWarnings("deprecation")
+    private static final Date NOW_PLUS_10_YEARS = new Date(NOW.getYear() + 10, 0, 1);
+
+    private static final long DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
+
+    private static final X500Principal DEFAULT_CERT_SUBJECT = new X500Principal("CN=fake");
+    private static final BigInteger DEFAULT_CERT_SERIAL_NUMBER = new BigInteger("1");
+    private static final Date DEFAULT_CERT_NOT_BEFORE = new Date(0L); // Jan 1 1970
+    private static final Date DEFAULT_CERT_NOT_AFTER = new Date(2461449600000L); // Jan 1 2048
+
+    private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_PROVIDER_NAME;
+
+    private static final String[] EXPECTED_ALGORITHMS = {
+        "EC",
+        "RSA",
+    };
+
+    private static final Map<String, Integer> DEFAULT_KEY_SIZES =
+            new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+    static {
+        DEFAULT_KEY_SIZES.put("EC", 256);
+        DEFAULT_KEY_SIZES.put("RSA", 2048);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mRng = new CountingSecureRandom();
+        mKeyStore = KeyStore.getInstance("AndroidKeyStore");
+        mKeyStore.load(null, null);
+    }
+
+    public void testAlgorithmList() {
+        // Assert that Android Keystore Provider exposes exactly the expected KeyPairGenerator
+        // algorithms. We don't care whether the algorithms are exposed via aliases, as long as
+        // canonical names of algorithms are accepted. If the Provider exposes extraneous
+        // algorithms, it'll be caught because it'll have to expose at least one Service for such an
+        // algorithm, and this Service's algorithm will not be in the expected set.
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        Set<Service> services = provider.getServices();
+        Set<String> actualAlgsLowerCase = new HashSet<String>();
+        Set<String> expectedAlgsLowerCase = new HashSet<String>(
+                Arrays.asList(TestUtils.toLowerCase(EXPECTED_ALGORITHMS)));
+        for (Service service : services) {
+            if ("KeyPairGenerator".equalsIgnoreCase(service.getType())) {
+                String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US);
+                actualAlgsLowerCase.add(algLowerCase);
+            }
+        }
+
+        TestUtils.assertContentsInAnyOrder(actualAlgsLowerCase,
+                expectedAlgsLowerCase.toArray(new String[0]));
+    }
+
+    public void testInitialize_LegacySpec() throws Exception {
+        @SuppressWarnings("deprecation")
+        KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build();
+        getRsaGenerator().initialize(spec);
+        getRsaGenerator().initialize(spec, new SecureRandom());
+
+        getEcGenerator().initialize(spec);
+        getEcGenerator().initialize(spec, new SecureRandom());
+    }
+
+    public void testInitialize_ModernSpec() throws Exception {
+        KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                .build();
+        getRsaGenerator().initialize(spec);
+        getRsaGenerator().initialize(spec, new SecureRandom());
+
+        getEcGenerator().initialize(spec);
+        getEcGenerator().initialize(spec, new SecureRandom());
+    }
+
+    public void testInitialize_KeySizeOnly() throws Exception {
+        try {
+            getRsaGenerator().initialize(1024);
+            fail("KeyPairGenerator should not support setting the key size");
+        } catch (IllegalArgumentException success) {
+        }
+
+        try {
+            getEcGenerator().initialize(256);
+            fail("KeyPairGenerator should not support setting the key size");
+        } catch (IllegalArgumentException success) {
+        }
+    }
+
+    public void testInitialize_KeySizeAndSecureRandomOnly()
+            throws Exception {
+        try {
+            getRsaGenerator().initialize(1024, new SecureRandom());
+            fail("KeyPairGenerator should not support setting the key size");
+        } catch (IllegalArgumentException success) {
+        }
+
+        try {
+            getEcGenerator().initialize(1024, new SecureRandom());
+            fail("KeyPairGenerator should not support setting the key size");
+        } catch (IllegalArgumentException success) {
+        }
+    }
+
+    public void testDefaultKeySize() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                int expectedSizeBits = DEFAULT_KEY_SIZES.get(algorithm);
+                KeyPairGenerator generator = getGenerator(algorithm);
+                generator.initialize(getWorkingSpec().build());
+                KeyPair keyPair = generator.generateKeyPair();
+                assertEquals(expectedSizeBits,
+                        TestUtils.getKeyInfo(keyPair.getPrivate()).getKeySize());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithUnknownBlockModeFails() {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator generator = getGenerator(algorithm);
+                try {
+                    generator.initialize(getWorkingSpec().setBlockModes("weird").build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithUnknownEncryptionPaddingFails() {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator generator = getGenerator(algorithm);
+                try {
+                    generator.initialize(getWorkingSpec().setEncryptionPaddings("weird").build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithUnknownSignaturePaddingFails() {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator generator = getGenerator(algorithm);
+                try {
+                    generator.initialize(getWorkingSpec().setSignaturePaddings("weird").build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitWithUnknownDigestFails() {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator generator = getGenerator(algorithm);
+                try {
+                    generator.initialize(getWorkingSpec().setDigests("weird").build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitRandomizedEncryptionRequiredButViolatedFails() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyPairGenerator generator = getGenerator(algorithm);
+                try {
+                    generator.initialize(getWorkingSpec(
+                            KeyProperties.PURPOSE_ENCRYPT)
+                            .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                            .build());
+                    fail();
+                } catch (InvalidAlgorithmParameterException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGenerateHonorsRequestedAuthorizations() throws Exception {
+        Date keyValidityStart = new Date(System.currentTimeMillis() - TestUtils.DAY_IN_MILLIS);
+        Date keyValidityForOriginationEnd =
+                new Date(System.currentTimeMillis() + TestUtils.DAY_IN_MILLIS);
+        Date keyValidityForConsumptionEnd =
+                new Date(System.currentTimeMillis() + 3 * TestUtils.DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                String[] blockModes =
+                        new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
+                String[] encryptionPaddings =
+                        new String[] {KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                                KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1};
+                String[] digests =
+                        new String[] {KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA1};
+                int purposes = KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT;
+                KeyPairGenerator generator = getGenerator(algorithm);
+                generator.initialize(getWorkingSpec(purposes)
+                        .setBlockModes(blockModes)
+                        .setEncryptionPaddings(encryptionPaddings)
+                        .setDigests(digests)
+                        .setKeyValidityStart(keyValidityStart)
+                        .setKeyValidityForOriginationEnd(keyValidityForOriginationEnd)
+                        .setKeyValidityForConsumptionEnd(keyValidityForConsumptionEnd)
+                        .build());
+                KeyPair keyPair = generator.generateKeyPair();
+                assertEquals(algorithm, keyPair.getPrivate().getAlgorithm());
+
+                KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+                assertEquals(purposes, keyInfo.getPurposes());
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(keyInfo.getBlockModes()), blockModes);
+
+                List<String> actualEncryptionPaddings =
+                        new ArrayList<String>(Arrays.asList(keyInfo.getEncryptionPaddings()));
+                // Keystore may have added ENCRYPTION_PADDING_NONE to allow software OAEP
+                actualEncryptionPaddings.remove(KeyProperties.ENCRYPTION_PADDING_NONE);
+                TestUtils.assertContentsInAnyOrder(
+                        actualEncryptionPaddings, encryptionPaddings);
+
+                List<String> actualDigests =
+                        new ArrayList<String>(Arrays.asList(keyInfo.getDigests()));
+                // Keystore may have added DIGEST_NONE, to allow software digesting.
+                actualDigests.remove(KeyProperties.DIGEST_NONE);
+                TestUtils.assertContentsInAnyOrder(actualDigests, digests);
+
+                MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+                assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
+                assertEquals(keyValidityForOriginationEnd,
+                        keyInfo.getKeyValidityForOriginationEnd());
+                assertEquals(keyValidityForConsumptionEnd,
+                        keyInfo.getKeyValidityForConsumptionEnd());
+                assertFalse(keyInfo.isUserAuthenticationRequired());
+                assertFalse(keyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    @SuppressWarnings("deprecation")
+    public void testGenerate_EC_LegacySpec() throws Exception {
+        // There are three legacy ways to generate an EC key pair using Android Keystore
+        // KeyPairGenerator:
+        // 1. Use an RSA KeyPairGenerator and specify EC as key type,
+        // 2. Use an EC KeyPairGenerator and specify EC as key type,
+        // 3. Use an EC KeyPairGenerator and leave the key type unspecified.
+        //
+        // We test all three.
+
+        // 1. Use an RSA KeyPairGenerator and specify EC as key type.
+        KeyPairGenerator generator = getRsaGenerator();
+        generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setKeyType("EC")
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "EC",
+                256,
+                TEST_DN_1,
+                TEST_SERIAL_1, NOW,
+                NOW_PLUS_10_YEARS);
+        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
+        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
+        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+                ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams());
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(256, keyInfo.getKeySize());
+        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
+        assertOneOf(keyInfo.getOrigin(),
+                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
+        assertEquals(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY,
+                keyInfo.getPurposes());
+        assertFalse(keyInfo.isUserAuthenticationRequired());
+        assertEquals(null, keyInfo.getKeyValidityStart());
+        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
+        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
+                KeyProperties.DIGEST_NONE,
+                KeyProperties.DIGEST_SHA1,
+                KeyProperties.DIGEST_SHA224,
+                KeyProperties.DIGEST_SHA256,
+                KeyProperties.DIGEST_SHA384,
+                KeyProperties.DIGEST_SHA512);
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
+
+        // 2. Use an EC KeyPairGenerator and specify EC as key type.
+        generator = getEcGenerator();
+        generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_2)
+                .setKeyType("EC")
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+        keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_2,
+                "EC",
+                256,
+                TEST_DN_1,
+                TEST_SERIAL_1,
+                NOW,
+                NOW_PLUS_10_YEARS);
+        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_2);
+        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_2);
+        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+                ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams());
+        keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(256, keyInfo.getKeySize());
+        assertEquals(TEST_ALIAS_2, keyInfo.getKeystoreAlias());
+        assertOneOf(keyInfo.getOrigin(),
+                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
+        assertEquals(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY,
+                keyInfo.getPurposes());
+        assertFalse(keyInfo.isUserAuthenticationRequired());
+        assertEquals(null, keyInfo.getKeyValidityStart());
+        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
+        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
+                KeyProperties.DIGEST_NONE,
+                KeyProperties.DIGEST_SHA1,
+                KeyProperties.DIGEST_SHA224,
+                KeyProperties.DIGEST_SHA256,
+                KeyProperties.DIGEST_SHA384,
+                KeyProperties.DIGEST_SHA512);
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
+
+        // 3. Use an EC KeyPairGenerator and leave the key type unspecified.
+        generator = getEcGenerator();
+        generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_3)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+        keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_3,
+                "EC",
+                256,
+                TEST_DN_1,
+                TEST_SERIAL_1,
+                NOW,
+                NOW_PLUS_10_YEARS);
+        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_3);
+        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_3);
+        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+                ECCurves.NIST_P_256_SPEC, ((ECPublicKey) keyPair.getPublic()).getParams());
+        keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(256, keyInfo.getKeySize());
+        assertEquals(TEST_ALIAS_3, keyInfo.getKeystoreAlias());
+        assertOneOf(keyInfo.getOrigin(),
+                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
+        assertEquals(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY,
+                keyInfo.getPurposes());
+        assertFalse(keyInfo.isUserAuthenticationRequired());
+        assertEquals(null, keyInfo.getKeyValidityStart());
+        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
+        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
+                KeyProperties.DIGEST_NONE,
+                KeyProperties.DIGEST_SHA1,
+                KeyProperties.DIGEST_SHA224,
+                KeyProperties.DIGEST_SHA256,
+                KeyProperties.DIGEST_SHA384,
+                KeyProperties.DIGEST_SHA512);
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
+    }
+
+    public void testGenerate_RSA_LegacySpec() throws Exception {
+        KeyPairGenerator generator = getRsaGenerator();
+        generator.initialize(new KeyPairGeneratorSpec.Builder(getContext())
+                .setAlias(TEST_ALIAS_1)
+                .setSubject(TEST_DN_1)
+                .setSerialNumber(TEST_SERIAL_1)
+                .setStartDate(NOW)
+                .setEndDate(NOW_PLUS_10_YEARS)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "RSA",
+                2048,
+                TEST_DN_1,
+                TEST_SERIAL_1,
+                NOW,
+                NOW_PLUS_10_YEARS);
+        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
+        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
+        assertEquals(RSAKeyGenParameterSpec.F4,
+                ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(2048, keyInfo.getKeySize());
+        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
+        assertOneOf(keyInfo.getOrigin(),
+                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
+        assertEquals(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
+                        | KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                keyInfo.getPurposes());
+        assertFalse(keyInfo.isUserAuthenticationRequired());
+        assertEquals(null, keyInfo.getKeyValidityStart());
+        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
+        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
+                KeyProperties.DIGEST_NONE,
+                KeyProperties.DIGEST_MD5,
+                KeyProperties.DIGEST_SHA1,
+                KeyProperties.DIGEST_SHA224,
+                KeyProperties.DIGEST_SHA256,
+                KeyProperties.DIGEST_SHA384,
+                KeyProperties.DIGEST_SHA512);
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()),
+                KeyProperties.ENCRYPTION_PADDING_NONE,
+                KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
+                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP);
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()),
+                KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+                KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
+    }
+
+    public void testGenerate_ReplacesOldEntryWithSameAlias()
+            throws Exception {
+        // Generate the first key
+        {
+            KeyPairGenerator generator = getRsaGenerator();
+            generator.initialize(new KeyGenParameterSpec.Builder(
+                    TEST_ALIAS_1,
+                    KeyProperties.PURPOSE_SIGN
+                            | KeyProperties.PURPOSE_VERIFY
+                            | KeyProperties.PURPOSE_ENCRYPT
+                            | KeyProperties.PURPOSE_DECRYPT)
+                    .setDigests(KeyProperties.DIGEST_NONE)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
+                    .setCertificateSubject(TEST_DN_1)
+                    .setCertificateSerialNumber(TEST_SERIAL_1)
+                    .setCertificateNotBefore(NOW)
+                    .setCertificateNotAfter(NOW_PLUS_10_YEARS)
+                    .build());
+            assertGeneratedKeyPairAndSelfSignedCertificate(
+                    generator.generateKeyPair(),
+                    TEST_ALIAS_1,
+                    "RSA",
+                    2048,
+                    TEST_DN_1,
+                    TEST_SERIAL_1,
+                    NOW,
+                    NOW_PLUS_10_YEARS);
+        }
+
+        // Replace the original key
+        {
+            KeyPairGenerator generator = getRsaGenerator();
+            generator.initialize(new KeyGenParameterSpec.Builder(
+                    TEST_ALIAS_1,
+                    KeyProperties.PURPOSE_SIGN
+                            | KeyProperties.PURPOSE_VERIFY
+                            | KeyProperties.PURPOSE_ENCRYPT
+                            | KeyProperties.PURPOSE_DECRYPT)
+                    .setDigests(KeyProperties.DIGEST_NONE)
+                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
+                    .setCertificateSubject(TEST_DN_2)
+                    .setCertificateSerialNumber(TEST_SERIAL_2)
+                    .setCertificateNotBefore(NOW)
+                    .setCertificateNotAfter(NOW_PLUS_10_YEARS)
+                    .build());
+            assertGeneratedKeyPairAndSelfSignedCertificate(
+                    generator.generateKeyPair(),
+                    TEST_ALIAS_1,
+                    "RSA",
+                    2048,
+                    TEST_DN_2,
+                    TEST_SERIAL_2,
+                    NOW,
+                    NOW_PLUS_10_YEARS);
+        }
+    }
+
+    public void testGenerate_DoesNotReplaceOtherEntries()
+            throws Exception {
+        // Generate the first key
+        KeyPairGenerator generator = getRsaGenerator();
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN
+                        | KeyProperties.PURPOSE_VERIFY
+                        | KeyProperties.PURPOSE_ENCRYPT
+                        | KeyProperties.PURPOSE_DECRYPT)
+                .setDigests(KeyProperties.DIGEST_NONE)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
+                .setCertificateSubject(TEST_DN_1)
+                .setCertificateSerialNumber(TEST_SERIAL_1)
+                .setCertificateNotBefore(NOW)
+                .setCertificateNotAfter(NOW_PLUS_10_YEARS)
+                .build());
+        KeyPair keyPair1 = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair1,
+                TEST_ALIAS_1,
+                "RSA",
+                2048,
+                TEST_DN_1,
+                TEST_SERIAL_1,
+                NOW,
+                NOW_PLUS_10_YEARS);
+
+        // Generate the second key
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_2,
+                KeyProperties.PURPOSE_SIGN
+                        | KeyProperties.PURPOSE_VERIFY
+                        | KeyProperties.PURPOSE_ENCRYPT
+                        | KeyProperties.PURPOSE_DECRYPT)
+                .setDigests(KeyProperties.DIGEST_NONE)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
+                .setCertificateSubject(TEST_DN_2)
+                .setCertificateSerialNumber(TEST_SERIAL_2)
+                .setCertificateNotBefore(NOW)
+                .setCertificateNotAfter(NOW_PLUS_10_YEARS)
+                .build());
+        KeyPair keyPair2 = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair2,
+                TEST_ALIAS_2,
+                "RSA",
+                2048,
+                TEST_DN_2,
+                TEST_SERIAL_2,
+                NOW,
+                NOW_PLUS_10_YEARS);
+
+        // Check the first key pair again
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair1,
+                TEST_ALIAS_1,
+                "RSA",
+                2048,
+                TEST_DN_1,
+                TEST_SERIAL_1,
+                NOW,
+                NOW_PLUS_10_YEARS);
+    }
+
+    public void testGenerate_EC_ModernSpec_Defaults() throws Exception {
+        KeyPairGenerator generator = getEcGenerator();
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "EC",
+                256,
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+                ECCurves.NIST_P_256_SPEC, ((ECKey) keyPair.getPrivate()).getParams());
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(256, keyInfo.getKeySize());
+        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
+        assertOneOf(keyInfo.getOrigin(),
+                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
+        assertEquals(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY, keyInfo.getPurposes());
+        assertFalse(keyInfo.isUserAuthenticationRequired());
+        assertEquals(null, keyInfo.getKeyValidityStart());
+        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
+        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getDigests()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
+    }
+
+    public void testGenerate_RSA_ModernSpec_Defaults() throws Exception {
+        KeyPairGenerator generator = getRsaGenerator();
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "RSA",
+                2048,
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        assertEquals(RSAKeyGenParameterSpec.F4,
+                ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(2048, keyInfo.getKeySize());
+        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
+        assertOneOf(keyInfo.getOrigin(),
+                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
+        assertEquals(
+                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                keyInfo.getPurposes());
+        assertFalse(keyInfo.isUserAuthenticationRequired());
+        assertEquals(null, keyInfo.getKeyValidityStart());
+        assertEquals(null, keyInfo.getKeyValidityForOriginationEnd());
+        assertEquals(null, keyInfo.getKeyValidityForConsumptionEnd());
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getDigests()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
+    }
+
+    public void testGenerate_EC_ModernSpec_AsCustomAsPossible() throws Exception {
+        KeyPairGenerator generator = getEcGenerator();
+        Date keyValidityStart = new Date(System.currentTimeMillis());
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 1000000);
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 10000000);
+
+        Date certNotBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 7);
+        Date certNotAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 7);
+        BigInteger certSerialNumber = new BigInteger("12345678");
+        X500Principal certSubject = new X500Principal("cn=hello");
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
+                        | KeyProperties.PURPOSE_ENCRYPT)
+                .setKeySize(224)
+                .setDigests(KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512)
+                .setKeyValidityStart(keyValidityStart)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setCertificateSerialNumber(certSerialNumber)
+                .setCertificateSubject(certSubject)
+                .setCertificateNotBefore(certNotBefore)
+                .setCertificateNotAfter(certNotAfter)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "EC",
+                224,
+                certSubject,
+                certSerialNumber,
+                certNotBefore,
+                certNotAfter);
+        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+                ECCurves.NIST_P_224_SPEC, ((ECKey) keyPair.getPrivate()).getParams());
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(224, keyInfo.getKeySize());
+        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
+        assertOneOf(keyInfo.getOrigin(),
+                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
+        assertEquals(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
+                        | KeyProperties.PURPOSE_ENCRYPT,
+                keyInfo.getPurposes());
+        assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
+        assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd());
+        assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd());
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
+
+        List<String> actualDigests = new ArrayList<String>(Arrays.asList(keyInfo.getDigests()));
+        // Keystore may have added DIGEST_NONE, to allow software digesting.
+        actualDigests.remove(KeyProperties.DIGEST_NONE);
+        TestUtils.assertContentsInAnyOrder(
+                actualDigests, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512);
+
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
+        assertFalse(keyInfo.isUserAuthenticationRequired());
+        assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testGenerate_RSA_ModernSpec_AsCustomAsPossible() throws Exception {
+        KeyPairGenerator generator = getRsaGenerator();
+        Date keyValidityStart = new Date(System.currentTimeMillis());
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 1000000);
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 10000000);
+
+        Date certNotBefore = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24 * 210);
+        Date certNotAfter = new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 210);
+        BigInteger certSerialNumber = new BigInteger("1234567890");
+        X500Principal certSubject = new X500Principal("cn=hello2");
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
+                        | KeyProperties.PURPOSE_ENCRYPT)
+                .setAlgorithmParameterSpec(
+                        new RSAKeyGenParameterSpec(3072, RSAKeyGenParameterSpec.F0))
+                .setKeySize(3072)
+                .setDigests(KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512)
+                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                .setBlockModes(KeyProperties.BLOCK_MODE_ECB)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                        KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
+                .setKeyValidityStart(keyValidityStart)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setCertificateSerialNumber(certSerialNumber)
+                .setCertificateSubject(certSubject)
+                .setCertificateNotBefore(certNotBefore)
+                .setCertificateNotAfter(certNotAfter)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "RSA",
+                3072,
+                certSubject,
+                certSerialNumber,
+                certNotBefore,
+                certNotAfter);
+        assertEquals(RSAKeyGenParameterSpec.F0,
+                ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(3072, keyInfo.getKeySize());
+        assertEquals(TEST_ALIAS_1, keyInfo.getKeystoreAlias());
+        assertOneOf(keyInfo.getOrigin(),
+                KeyProperties.ORIGIN_GENERATED, KeyProperties.ORIGIN_UNKNOWN);
+        assertEquals(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY
+                        | KeyProperties.PURPOSE_ENCRYPT,
+                keyInfo.getPurposes());
+        assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
+        assertEquals(keyValidityEndDateForOrigination, keyInfo.getKeyValidityForOriginationEnd());
+        assertEquals(keyValidityEndDateForConsumption, keyInfo.getKeyValidityForConsumptionEnd());
+
+        List<String> actualDigests =
+	    new ArrayList<String>(Arrays.asList(keyInfo.getDigests()));
+        // Keystore may have added DIGEST_NONE, to allow software digesting.
+        actualDigests.remove(KeyProperties.DIGEST_NONE);
+        TestUtils.assertContentsInAnyOrder(
+                actualDigests, KeyProperties.DIGEST_SHA384, KeyProperties.DIGEST_SHA512);
+
+        TestUtils.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()),
+                KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
+                KeyProperties.SIGNATURE_PADDING_RSA_PSS);
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getBlockModes()),
+                KeyProperties.BLOCK_MODE_ECB);
+
+        List<String> actualEncryptionPaddings =
+                new ArrayList<String>(Arrays.asList(keyInfo.getEncryptionPaddings()));
+        // Keystore may have added ENCRYPTION_PADDING_NONE, to allow software padding.
+        actualEncryptionPaddings.remove(KeyProperties.ENCRYPTION_PADDING_NONE);
+        TestUtils.assertContentsInAnyOrder(actualEncryptionPaddings,
+                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
+
+        assertFalse(keyInfo.isUserAuthenticationRequired());
+        assertEquals(-1, keyInfo.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testGenerate_EC_ModernSpec_UsableForTLSPeerAuth() throws Exception {
+        KeyPairGenerator generator = getEcGenerator();
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                .setDigests(KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "EC",
+                256,
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
+                KeyProperties.DIGEST_NONE, KeyProperties.DIGEST_SHA384);
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getEncryptionPaddings()));
+        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
+        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
+    }
+
+    public void testGenerate_RSA_ModernSpec_UsableForTLSPeerAuth() throws Exception {
+        KeyPairGenerator generator = getRsaGenerator();
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN
+                        | KeyProperties.PURPOSE_VERIFY
+                        | KeyProperties.PURPOSE_DECRYPT)
+                .setDigests(KeyProperties.DIGEST_NONE,
+                        KeyProperties.DIGEST_SHA256,
+                        KeyProperties.DIGEST_SHA512)
+                .setEncryptionPaddings(
+                        KeyProperties.ENCRYPTION_PADDING_NONE,
+                        KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1)
+                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "RSA",
+                2048,
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getBlockModes()));
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getDigests()),
+                KeyProperties.DIGEST_NONE,
+                KeyProperties.DIGEST_SHA256,
+                KeyProperties.DIGEST_SHA512);
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getSignaturePaddings()),
+                KeyProperties.SIGNATURE_PADDING_RSA_PKCS1);
+        MoreAsserts.assertContentsInAnyOrder(Arrays.asList(keyInfo.getEncryptionPaddings()),
+                KeyProperties.ENCRYPTION_PADDING_NONE,
+                KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
+        assertSelfSignedCertificateSignatureVerifies(TEST_ALIAS_1);
+        assertKeyPairAndCertificateUsableForTLSPeerAuthentication(TEST_ALIAS_1);
+    }
+
+    // TODO: Test fingerprint-authorized and secure lock screen-authorized keys. These can't
+    // currently be tested here because CTS does not require that secure lock screen is set up and
+    // that at least one fingerprint is enrolled.
+
+    public void testGenerate_EC_ModernSpec_KeyNotYetValid() throws Exception {
+        KeyPairGenerator generator = getEcGenerator();
+        Date validityStart = new Date(System.currentTimeMillis() + DAY_IN_MILLIS);
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                .setKeySize(256)
+                .setDigests(KeyProperties.DIGEST_SHA256)
+                .setKeyValidityStart(validityStart)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "EC",
+                256,
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(validityStart, keyInfo.getKeyValidityStart());
+    }
+
+    public void testGenerate_RSA_ModernSpec_KeyExpiredForOrigination() throws Exception {
+        KeyPairGenerator generator = getRsaGenerator();
+        Date originationEnd = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                .setKeySize(1024)
+                .setDigests(KeyProperties.DIGEST_SHA256)
+                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                .setKeyValidityForOriginationEnd(originationEnd)
+                .build());
+        KeyPair keyPair = generator.generateKeyPair();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "RSA",
+                1024,
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(originationEnd, keyInfo.getKeyValidityForOriginationEnd());
+    }
+
+    public void testGenerate_EC_ModernSpec_SupportedSizes() throws Exception {
+        assertKeyGenUsingECSizeOnlyUsesCorrectCurve(224, ECCurves.NIST_P_224_SPEC);
+        assertKeyGenUsingECSizeOnlyUsesCorrectCurve(256, ECCurves.NIST_P_256_SPEC);
+        assertKeyGenUsingECSizeOnlyUsesCorrectCurve(384, ECCurves.NIST_P_384_SPEC);
+        assertKeyGenUsingECSizeOnlyUsesCorrectCurve(521, ECCurves.NIST_P_521_SPEC);
+    }
+
+    public void testGenerate_EC_ModernSpec_UnsupportedSizesRejected() throws Exception {
+        for (int keySizeBits = 0; keySizeBits <= 1024; keySizeBits++) {
+            if ((keySizeBits == 224) || (keySizeBits == 256) || (keySizeBits == 384)
+                    || (keySizeBits == 521)) {
+                // Skip supported sizes
+                continue;
+            }
+            KeyPairGenerator generator = getEcGenerator();
+
+            try {
+                generator.initialize(new KeyGenParameterSpec.Builder(
+                        TEST_ALIAS_1,
+                        KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                        .setKeySize(keySizeBits)
+                        .build());
+                fail("EC KeyPairGenerator initialized with unsupported key size: "
+                        + keySizeBits + " bits");
+            } catch (InvalidAlgorithmParameterException expected) {
+            }
+        }
+    }
+
+    public void testGenerate_EC_ModernSpec_SupportedNamedCurves() throws Exception {
+        assertKeyGenUsingECNamedCurveSupported("P-224", ECCurves.NIST_P_224_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("p-224", ECCurves.NIST_P_224_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("secp224r1", ECCurves.NIST_P_224_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("SECP224R1", ECCurves.NIST_P_224_SPEC);
+
+        assertKeyGenUsingECNamedCurveSupported("P-256", ECCurves.NIST_P_256_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("p-256", ECCurves.NIST_P_256_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("secp256r1", ECCurves.NIST_P_256_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("SECP256R1", ECCurves.NIST_P_256_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("prime256v1", ECCurves.NIST_P_256_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("PRIME256V1", ECCurves.NIST_P_256_SPEC);
+
+        assertKeyGenUsingECNamedCurveSupported("P-384", ECCurves.NIST_P_384_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("p-384", ECCurves.NIST_P_384_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("secp384r1", ECCurves.NIST_P_384_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("SECP384R1", ECCurves.NIST_P_384_SPEC);
+
+        assertKeyGenUsingECNamedCurveSupported("P-521", ECCurves.NIST_P_521_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("p-521", ECCurves.NIST_P_521_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("secp521r1", ECCurves.NIST_P_521_SPEC);
+        assertKeyGenUsingECNamedCurveSupported("SECP521R1", ECCurves.NIST_P_521_SPEC);
+    }
+
+    public void testGenerate_RSA_ModernSpec_SupportedSizes() throws Exception {
+        assertKeyGenUsingRSASizeOnlySupported(512);
+        assertKeyGenUsingRSASizeOnlySupported(768);
+        assertKeyGenUsingRSASizeOnlySupported(1024);
+        assertKeyGenUsingRSASizeOnlySupported(2048);
+        assertKeyGenUsingRSASizeOnlySupported(3072);
+        assertKeyGenUsingRSASizeOnlySupported(4096);
+
+        // The above use F4. Check that F0 is supported as well, just in case somebody is crazy
+        // enough.
+        assertKeyGenUsingRSAKeyGenParameterSpecSupported(new RSAKeyGenParameterSpec(
+                2048, RSAKeyGenParameterSpec.F0));
+    }
+
+    public void testGenerate_RSA_IndCpaEnforced() throws Exception {
+        KeyGenParameterSpec.Builder goodBuilder = new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1, KeyProperties.PURPOSE_ENCRYPT)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                        KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1);
+        assertKeyGenInitSucceeds("RSA", goodBuilder.build());
+
+        // Should be fine because IND-CPA restriction applies only to encryption keys
+        assertKeyGenInitSucceeds("RSA",
+                TestUtils.buildUpon(goodBuilder, KeyProperties.PURPOSE_DECRYPT)
+                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                        .build());
+
+        assertKeyGenInitThrowsInvalidAlgorithmParameterException("RSA",
+                TestUtils.buildUpon(goodBuilder)
+                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                        .build());
+
+        assertKeyGenInitSucceeds("RSA",
+                TestUtils.buildUpon(goodBuilder)
+                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                        .setRandomizedEncryptionRequired(false)
+                        .build());
+
+        // Should fail because PKCS#7 padding doesn't work with RSA
+        assertKeyGenInitThrowsInvalidAlgorithmParameterException("RSA",
+                TestUtils.buildUpon(goodBuilder)
+                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                        .build());
+    }
+
+    public void testGenerate_EC_IndCpaEnforced() throws Exception {
+        KeyGenParameterSpec.Builder goodBuilder = new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_2, KeyProperties.PURPOSE_ENCRYPT);
+        assertKeyGenInitSucceeds("EC", goodBuilder.build());
+
+        // Should be fine because IND-CPA restriction applies only to encryption keys
+        assertKeyGenInitSucceeds("EC",
+                TestUtils.buildUpon(goodBuilder, KeyProperties.PURPOSE_DECRYPT)
+                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                        .build());
+
+        assertKeyGenInitThrowsInvalidAlgorithmParameterException("EC",
+                TestUtils.buildUpon(goodBuilder)
+                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                        .build());
+
+        assertKeyGenInitSucceeds("EC",
+                TestUtils.buildUpon(goodBuilder)
+                        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+                        .setRandomizedEncryptionRequired(false)
+                        .build());
+    }
+
+    private void assertKeyGenInitSucceeds(String algorithm, AlgorithmParameterSpec params)
+            throws Exception {
+        KeyPairGenerator generator = getGenerator(algorithm);
+        generator.initialize(params);
+    }
+
+    private void assertKeyGenInitThrowsInvalidAlgorithmParameterException(
+            String algorithm, AlgorithmParameterSpec params) throws Exception {
+        KeyPairGenerator generator = getGenerator(algorithm);
+        try {
+            generator.initialize(params);
+            fail();
+        } catch (InvalidAlgorithmParameterException expected) {}
+    }
+
+    private void assertKeyGenUsingECSizeOnlyUsesCorrectCurve(
+            int keySizeBits, ECParameterSpec expectedParams) throws Exception {
+        KeyPairGenerator generator = getEcGenerator();
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                .setKeySize(keySizeBits)
+                .build(),
+                mRng);
+        mRng.resetCounters();
+        KeyPair keyPair = generator.generateKeyPair();
+        long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
+        int expectedKeySize = expectedParams.getCurve().getField().getFieldSize();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "EC",
+                expectedKeySize,
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(expectedKeySize, keyInfo.getKeySize());
+        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+                expectedParams,
+                ((ECKey) keyPair.getPublic()).getParams());
+        assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
+    }
+
+    private void assertKeyGenUsingECNamedCurveSupported(
+            String curveName, ECParameterSpec expectedParams) throws Exception {
+        KeyPairGenerator generator = getEcGenerator();
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                .setAlgorithmParameterSpec(new ECGenParameterSpec(curveName))
+                .build(),
+                mRng);
+        mRng.resetCounters();
+        KeyPair keyPair = generator.generateKeyPair();
+        long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
+        int expectedKeySize = expectedParams.getCurve().getField().getFieldSize();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "EC",
+                expectedKeySize,
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(expectedKeySize, keyInfo.getKeySize());
+        TestUtils.assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+                expectedParams,
+                ((ECKey) keyPair.getPublic()).getParams());
+        assertEquals(((expectedKeySize + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
+    }
+
+    private void assertKeyGenUsingRSASizeOnlySupported(int keySizeBits) throws Exception {
+        KeyPairGenerator generator = getRsaGenerator();
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                .setKeySize(keySizeBits)
+                .build(),
+                mRng);
+        mRng.resetCounters();
+        KeyPair keyPair = generator.generateKeyPair();
+        long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "RSA",
+                keySizeBits,
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(keySizeBits, keyInfo.getKeySize());
+        assertEquals(((keySizeBits + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
+    }
+
+    private void assertKeyGenUsingRSAKeyGenParameterSpecSupported(
+            RSAKeyGenParameterSpec spec) throws Exception {
+        KeyPairGenerator generator = getRsaGenerator();
+        generator.initialize(new KeyGenParameterSpec.Builder(
+                TEST_ALIAS_1,
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_VERIFY)
+                .setAlgorithmParameterSpec(spec)
+                .build(),
+                mRng);
+        mRng.resetCounters();
+        KeyPair keyPair = generator.generateKeyPair();
+        long consumedEntropyAmountBytes = mRng.getOutputSizeBytes();
+        assertGeneratedKeyPairAndSelfSignedCertificate(
+                keyPair,
+                TEST_ALIAS_1,
+                "RSA",
+                spec.getKeysize(),
+                DEFAULT_CERT_SUBJECT,
+                DEFAULT_CERT_SERIAL_NUMBER,
+                DEFAULT_CERT_NOT_BEFORE,
+                DEFAULT_CERT_NOT_AFTER);
+        assertEquals(spec.getPublicExponent(),
+                ((RSAPublicKey) keyPair.getPublic()).getPublicExponent());
+        KeyInfo keyInfo = TestUtils.getKeyInfo(keyPair.getPrivate());
+        assertEquals(spec.getKeysize(), keyInfo.getKeySize());
+        assertEquals(((spec.getKeysize() + 7) / 8) * 8, consumedEntropyAmountBytes * 8);
+    }
+
+    private static void assertSelfSignedCertificateSignatureVerifies(Certificate certificate) {
+        try {
+            certificate.verify(certificate.getPublicKey());
+        } catch (Exception e) {
+            throw new RuntimeException("Failed to verify self-signed certificate signature", e);
+        }
+    }
+
+    private void assertGeneratedKeyPairAndSelfSignedCertificate(
+            KeyPair keyPair, String alias,
+            String expectedKeyAlgorithm,
+            int expectedKeySize,
+            X500Principal expectedCertSubject,
+            BigInteger expectedCertSerialNumber,
+            Date expectedCertNotBefore,
+            Date expectedCertNotAfter)
+            throws Exception {
+        assertNotNull(keyPair);
+        TestUtils.assertKeyPairSelfConsistent(keyPair);
+        TestUtils.assertKeySize(expectedKeySize, keyPair);
+        assertEquals(expectedKeyAlgorithm, keyPair.getPublic().getAlgorithm());
+        TestUtils.assertKeyStoreKeyPair(mKeyStore, alias, keyPair);
+
+        X509Certificate cert = (X509Certificate) mKeyStore.getCertificate(alias);
+        assertEquals(keyPair.getPublic(), cert.getPublicKey());
+        assertX509CertificateParameters(cert,
+                expectedCertSubject,
+                expectedCertSerialNumber,
+                expectedCertNotBefore,
+                expectedCertNotAfter);
+        // Assert that the certificate chain consists only of the above certificate
+        MoreAsserts.assertContentsInOrder(
+                Arrays.asList(mKeyStore.getCertificateChain(alias)), cert);
+    }
+
+    private void assertSelfSignedCertificateSignatureVerifies(String alias) throws Exception {
+        assertSelfSignedCertificateSignatureVerifies(mKeyStore.getCertificate(alias));
+    }
+
+    private void assertKeyPairAndCertificateUsableForTLSPeerAuthentication(String alias)
+            throws Exception {
+        assertUsableForTLSPeerAuthentication(
+                (PrivateKey) mKeyStore.getKey(alias, null),
+                mKeyStore.getCertificateChain(alias));
+    }
+
+    private static void assertX509CertificateParameters(
+            X509Certificate actualCert,
+            X500Principal expectedSubject, BigInteger expectedSerialNumber,
+            Date expectedNotBefore, Date expectedNotAfter) {
+        assertEquals(expectedSubject, actualCert.getSubjectDN());
+        assertEquals(expectedSubject, actualCert.getIssuerDN());
+        assertEquals(expectedSerialNumber, actualCert.getSerialNumber());
+        assertDateEquals(expectedNotBefore, actualCert.getNotBefore());
+        assertDateEquals(expectedNotAfter, actualCert.getNotAfter());
+    }
+
+    private static void assertUsableForTLSPeerAuthentication(
+            PrivateKey privateKey,
+            Certificate[] certificateChain) throws Exception {
+        // Set up both client and server to use the same private key + cert, and to trust that cert
+        // when it's presented by peer. This exercises the use of the private key both in client
+        // and server scenarios.
+        X509Certificate[] x509CertificateChain = new X509Certificate[certificateChain.length];
+        for (int i = 0; i < certificateChain.length; i++) {
+            x509CertificateChain[i] = (X509Certificate) certificateChain[i];
+        }
+        TestKeyStore serverKeyStore = TestKeyStore.getServer();
+        // Make the peer trust the root certificate in the chain. As opposed to making the peer
+        // trust the leaf certificate, this will ensure that the whole chain verifies.
+        serverKeyStore.keyStore.setCertificateEntry(
+                "trusted", certificateChain[certificateChain.length - 1]);
+        SSLContext serverContext = TestSSLContext.createSSLContext("TLS",
+                new KeyManager[] {
+                    TestKeyManager.wrap(new MyKeyManager(privateKey, x509CertificateChain))
+                },
+                TestKeyStore.createTrustManagers(serverKeyStore.keyStore));
+        SSLContext clientContext = serverContext;
+
+        if ("EC".equalsIgnoreCase(privateKey.getAlgorithm())) {
+            // As opposed to RSA (see below) EC keys are used in the same way in all cipher suites.
+            // Assert that the key works with the default list of cipher suites.
+            assertSSLConnectionWithClientAuth(
+                    clientContext, serverContext, null, x509CertificateChain, x509CertificateChain);
+        } else if ("RSA".equalsIgnoreCase(privateKey.getAlgorithm())) {
+            // RSA keys are used differently between Forward Secure and non-Forward Secure cipher
+            // suites. For example, RSA key exchange requires the server to decrypt using its RSA
+            // private key, whereas ECDHE_RSA key exchange requires the server to sign usnig its
+            // RSA private key. We thus assert that the key works with Forward Secure cipher suites
+            // and that it works with non-Forward Secure cipher suites.
+            List<String> fsCipherSuites = new ArrayList<String>();
+            List<String> nonFsCipherSuites = new ArrayList<String>();
+            for (String cipherSuite : clientContext.getDefaultSSLParameters().getCipherSuites()) {
+                if (cipherSuite.contains("_ECDHE_RSA_") || cipherSuite.contains("_DHE_RSA_")) {
+                    fsCipherSuites.add(cipherSuite);
+                } else if (cipherSuite.contains("_RSA_WITH_")) {
+                    nonFsCipherSuites.add(cipherSuite);
+                }
+            }
+            assertFalse("No FS RSA cipher suites enabled by default", fsCipherSuites.isEmpty());
+            assertFalse("No non-FS RSA cipher suites enabled", nonFsCipherSuites.isEmpty());
+
+            // Assert that the key works with RSA Forward Secure cipher suites.
+            assertSSLConnectionWithClientAuth(
+                    clientContext, serverContext, fsCipherSuites.toArray(new String[0]),
+                    x509CertificateChain, x509CertificateChain);
+            // Assert that the key works with RSA non-Forward Secure cipher suites.
+            assertSSLConnectionWithClientAuth(
+                    clientContext, serverContext, nonFsCipherSuites.toArray(new String[0]),
+                    x509CertificateChain, x509CertificateChain);
+        } else {
+            fail("Unsupported key algorithm: " + privateKey.getAlgorithm());
+        }
+    }
+
+    private static void assertSSLConnectionWithClientAuth(
+            SSLContext clientContext, SSLContext serverContext, String[] enabledCipherSuites,
+            X509Certificate[] expectedClientCertChain, X509Certificate[] expectedServerCertChain)
+            throws Exception {
+        SSLServerSocket serverSocket = (SSLServerSocket) serverContext.getServerSocketFactory()
+                .createServerSocket(0);
+        InetAddress host = InetAddress.getLocalHost();
+        int port = serverSocket.getLocalPort();
+        SSLSocket client = (SSLSocket) clientContext.getSocketFactory().createSocket(host, port);
+
+        final SSLSocket server = (SSLSocket) serverSocket.accept();
+        ExecutorService executor = Executors.newSingleThreadExecutor();
+        Future<Certificate[]> future = executor.submit(new Callable<Certificate[]>() {
+            @Override
+            public Certificate[] call() throws Exception {
+                server.setNeedClientAuth(true);
+                server.setWantClientAuth(true);
+                server.startHandshake();
+                return server.getSession().getPeerCertificates();
+            }
+        });
+        executor.shutdown();
+        if (enabledCipherSuites != null) {
+            client.setEnabledCipherSuites(enabledCipherSuites);
+        }
+        client.startHandshake();
+        Certificate[] usedServerCerts = client.getSession().getPeerCertificates();
+        Certificate[] usedClientCerts = future.get();
+        client.close();
+        server.close();
+
+        assertNotNull(usedServerCerts);
+        assertEquals(Arrays.asList(expectedServerCertChain), Arrays.asList(usedServerCerts));
+
+        assertNotNull(usedClientCerts);
+        assertEquals(Arrays.asList(expectedClientCertChain), Arrays.asList(usedClientCerts));
+    }
+
+    private static class MyKeyManager extends X509ExtendedKeyManager {
+        private final PrivateKey key;
+        private final X509Certificate[] chain;
+
+        public MyKeyManager(PrivateKey key, X509Certificate[] certChain) {
+            this.key = key;
+            this.chain = certChain;
+        }
+
+        @Override
+        public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) {
+            return "fake";
+        }
+
+        @Override
+        public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) {
+            return "fake";
+        }
+
+        @Override
+        public X509Certificate[] getCertificateChain(String alias) {
+            return chain;
+        }
+
+        @Override
+        public String[] getClientAliases(String keyType, Principal[] issuers) {
+            return new String[] { "fake" };
+        }
+
+        @Override
+        public String[] getServerAliases(String keyType, Principal[] issuers) {
+            return new String[] { "fake" };
+        }
+
+        @Override
+        public PrivateKey getPrivateKey(String alias) {
+            return key;
+        }
+    }
+
+
+    private static void assertDateEquals(Date date1, Date date2) {
+        assertDateEquals(null, date1, date2);
+    }
+
+    private static void assertDateEquals(String message, Date date1, Date date2) {
+        SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy HH:mm:ss");
+
+        String result1 = formatter.format(date1);
+        String result2 = formatter.format(date2);
+
+        assertEquals(message, result1, result2);
+    }
+
+    private KeyPairGenerator getRsaGenerator()
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        return getGenerator("RSA");
+    }
+
+    private KeyPairGenerator getEcGenerator()
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        return getGenerator("EC");
+    }
+
+    private KeyPairGenerator getGenerator(String algorithm)
+            throws NoSuchAlgorithmException, NoSuchProviderException {
+        return KeyPairGenerator.getInstance(algorithm, "AndroidKeyStore");
+    }
+
+    private static void assertOneOf(int actual, int... expected) {
+        assertOneOf(null, actual, expected);
+    }
+
+    private static void assertOneOf(String message, int actual, int... expected) {
+        for (int expectedValue : expected) {
+            if (actual == expectedValue) {
+                return;
+            }
+        }
+        fail(((message != null) ? message + ". " : "")
+                + "Expected one of " + Arrays.asList(expected)
+                + ", actual: <" + actual + ">");
+    }
+
+    private KeyGenParameterSpec.Builder getWorkingSpec() {
+        return getWorkingSpec(0);
+    }
+
+    private KeyGenParameterSpec.Builder getWorkingSpec(int purposes) {
+        return new KeyGenParameterSpec.Builder(TEST_ALIAS_1, purposes);
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/KeyProtectionTest.java b/tests/tests/keystore/src/android/keystore/cts/KeyProtectionTest.java
new file mode 100644
index 0000000..ee24eed
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/KeyProtectionTest.java
@@ -0,0 +1,255 @@
+/*
+ * 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.keystore.cts;
+
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.test.MoreAsserts;
+
+import junit.framework.TestCase;
+
+import java.util.Arrays;
+import java.util.Date;
+
+public class KeyProtectionTest extends TestCase {
+    public void testDefaults() {
+        // Set only the mandatory parameters and assert values returned by getters.
+
+        KeyProtection spec = new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT)
+                .build();
+
+        assertEquals(KeyProperties.PURPOSE_ENCRYPT, spec.getPurposes());
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getBlockModes()));
+        assertFalse(spec.isDigestsSpecified());
+        try {
+            spec.getDigests();
+            fail();
+        } catch (IllegalStateException expected) {}
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getEncryptionPaddings()));
+        assertNull(spec.getKeyValidityStart());
+        assertNull(spec.getKeyValidityForOriginationEnd());
+        assertNull(spec.getKeyValidityForConsumptionEnd());
+        assertTrue(spec.isRandomizedEncryptionRequired());
+        MoreAsserts.assertEmpty(Arrays.asList(spec.getSignaturePaddings()));
+        assertFalse(spec.isUserAuthenticationRequired());
+        assertEquals(-1, spec.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testSettersReflectedInGetters() {
+        // Set all parameters to non-default values and then assert that getters reflect that.
+
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+
+        KeyProtection spec = new KeyProtection.Builder(
+                KeyProperties.PURPOSE_DECRYPT | KeyProperties.PURPOSE_VERIFY)
+                .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CTR)
+                .setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512)
+                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1,
+                        KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setRandomizedEncryptionRequired(false)
+                .setSignaturePaddings(KeyProperties.SIGNATURE_PADDING_RSA_PKCS1,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PSS)
+                .setUserAuthenticationRequired(true)
+                .setUserAuthenticationValidityDurationSeconds(123456)
+                .build();
+
+        assertEquals(
+                KeyProperties.PURPOSE_DECRYPT| KeyProperties.PURPOSE_VERIFY, spec.getPurposes());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getBlockModes()),
+                KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CTR);
+        assertTrue(spec.isDigestsSpecified());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getDigests()),
+                KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512);
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getEncryptionPaddings()),
+                KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1, KeyProperties.ENCRYPTION_PADDING_PKCS7);
+        assertEquals(keyValidityStartDate, spec.getKeyValidityStart());
+        assertEquals(keyValidityEndDateForOrigination, spec.getKeyValidityForOriginationEnd());
+        assertEquals(keyValidityEndDateForConsumption, spec.getKeyValidityForConsumptionEnd());
+        assertFalse(spec.isRandomizedEncryptionRequired());
+        MoreAsserts.assertContentsInOrder(Arrays.asList(spec.getSignaturePaddings()),
+                KeyProperties.SIGNATURE_PADDING_RSA_PKCS1, KeyProperties.SIGNATURE_PADDING_RSA_PSS);
+        assertTrue(spec.isUserAuthenticationRequired());
+        assertEquals(123456, spec.getUserAuthenticationValidityDurationSeconds());
+    }
+
+    public void testSetKeyValidityEndDateAppliesToBothEndDates() {
+        Date date = new Date(System.currentTimeMillis() + 555555);
+        KeyProtection spec = new KeyProtection.Builder(
+                KeyProperties.PURPOSE_SIGN)
+                .setKeyValidityEnd(date)
+                .build();
+        assertEquals(date, spec.getKeyValidityForOriginationEnd());
+        assertEquals(date, spec.getKeyValidityForConsumptionEnd());
+    }
+
+    public void testSetUserAuthenticationValidityDurationSecondsValidityCheck() {
+        KeyProtection.Builder builder = new KeyProtection.Builder(0);
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-2);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-100);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(Integer.MIN_VALUE);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+
+        builder.setUserAuthenticationValidityDurationSeconds(-1);
+        builder.setUserAuthenticationValidityDurationSeconds(0);
+        builder.setUserAuthenticationValidityDurationSeconds(1);
+        builder.setUserAuthenticationValidityDurationSeconds(Integer.MAX_VALUE);
+
+        try {
+            builder.setUserAuthenticationValidityDurationSeconds(-2);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    public void testImmutabilityViaSetterParams() {
+        // Assert that all mutable parameters provided to setters are copied to ensure that values
+        // returned by getters never change.
+        String[] blockModes =
+                new String[] {KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC};
+        String[] originalBlockModes = blockModes.clone();
+        Date keyValidityStartDate = new Date(System.currentTimeMillis() - 2222222);
+        Date originalKeyValidityStartDate = new Date(keyValidityStartDate.getTime());
+        Date keyValidityEndDateForOrigination = new Date(System.currentTimeMillis() + 11111111);
+        Date originalKeyValidityEndDateForOrigination =
+                new Date(keyValidityEndDateForOrigination.getTime());
+        Date keyValidityEndDateForConsumption = new Date(System.currentTimeMillis() + 33333333);
+        Date originalKeyValidityEndDateForConsumption =
+                new Date(keyValidityEndDateForConsumption.getTime());
+        String[] digests = new String[] {KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512};
+        String[] originalDigests = digests.clone();
+        String[] encryptionPaddings = new String[] {
+                KeyProperties.ENCRYPTION_PADDING_RSA_OAEP, KeyProperties.ENCRYPTION_PADDING_PKCS7};
+        String[] originalEncryptionPaddings = encryptionPaddings.clone();
+        String[] signaturePaddings = new String[] {
+                KeyProperties.SIGNATURE_PADDING_RSA_PSS, KeyProperties.SIGNATURE_PADDING_RSA_PKCS1};
+        String[] originalSignaturePaddings = signaturePaddings.clone();
+
+        KeyProtection spec = new KeyProtection.Builder(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setBlockModes(blockModes)
+                .setDigests(digests)
+                .setEncryptionPaddings(encryptionPaddings)
+                .setKeyValidityStart(keyValidityStartDate)
+                .setKeyValidityForOriginationEnd(keyValidityEndDateForOrigination)
+                .setKeyValidityForConsumptionEnd(keyValidityEndDateForConsumption)
+                .setSignaturePaddings(signaturePaddings)
+                .build();
+
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+        blockModes[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+        digests[1] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+        encryptionPaddings[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+        keyValidityStartDate.setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+        keyValidityEndDateForOrigination.setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+        keyValidityEndDateForConsumption.setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+        signaturePaddings[1] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+    }
+
+    public void testImmutabilityViaGetterReturnValues() {
+        // Assert that none of the mutable return values from getters modify the state of the spec.
+
+        KeyProtection spec = new KeyProtection.Builder(
+                KeyProperties.PURPOSE_SIGN | KeyProperties.PURPOSE_ENCRYPT)
+                .setBlockModes(KeyProperties.BLOCK_MODE_GCM, KeyProperties.BLOCK_MODE_CBC)
+                .setDigests(KeyProperties.DIGEST_MD5, KeyProperties.DIGEST_SHA512)
+                .setEncryptionPaddings(
+                        KeyProperties.ENCRYPTION_PADDING_RSA_OAEP,
+                        KeyProperties.ENCRYPTION_PADDING_PKCS7)
+                .setKeyValidityStart(new Date(System.currentTimeMillis() - 2222222))
+                .setKeyValidityForOriginationEnd(new Date(System.currentTimeMillis() + 11111111))
+                .setKeyValidityForConsumptionEnd(new Date(System.currentTimeMillis() + 33333333))
+                .setSignaturePaddings(
+                        KeyProperties.SIGNATURE_PADDING_RSA_PSS,
+                        KeyProperties.SIGNATURE_PADDING_RSA_PKCS1)
+                .build();
+
+        String[] originalBlockModes = spec.getBlockModes().clone();
+        spec.getBlockModes()[0] = null;
+        assertEquals(Arrays.asList(originalBlockModes), Arrays.asList(spec.getBlockModes()));
+
+        String[] originalDigests = spec.getDigests().clone();
+        spec.getDigests()[0] = null;
+        assertEquals(Arrays.asList(originalDigests), Arrays.asList(spec.getDigests()));
+
+        String[] originalEncryptionPaddings = spec.getEncryptionPaddings().clone();
+        spec.getEncryptionPaddings()[0] = null;
+        assertEquals(Arrays.asList(originalEncryptionPaddings),
+                Arrays.asList(spec.getEncryptionPaddings()));
+
+        Date originalKeyValidityStartDate = (Date) spec.getKeyValidityStart().clone();
+        spec.getKeyValidityStart().setTime(1234567890L);
+        assertEquals(originalKeyValidityStartDate, spec.getKeyValidityStart());
+
+        Date originalKeyValidityEndDateForOrigination =
+                (Date) spec.getKeyValidityForOriginationEnd().clone();
+        spec.getKeyValidityForOriginationEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForOrigination,
+                spec.getKeyValidityForOriginationEnd());
+
+        Date originalKeyValidityEndDateForConsumption =
+                (Date) spec.getKeyValidityForConsumptionEnd().clone();
+        spec.getKeyValidityForConsumptionEnd().setTime(1234567890L);
+        assertEquals(originalKeyValidityEndDateForConsumption,
+                spec.getKeyValidityForConsumptionEnd());
+
+        String[] originalSignaturePaddings = spec.getSignaturePaddings().clone();
+        spec.getSignaturePaddings()[0] = null;
+        assertEquals(Arrays.asList(originalSignaturePaddings),
+                Arrays.asList(spec.getSignaturePaddings()));
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/MacTest.java b/tests/tests/keystore/src/android/keystore/cts/MacTest.java
new file mode 100644
index 0000000..c41dcda
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/MacTest.java
@@ -0,0 +1,605 @@
+/*
+ * 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.keystore.cts;
+
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+
+import junit.framework.TestCase;
+
+import java.security.InvalidKeyException;
+import java.security.Provider;
+import java.security.Provider.Service;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * Tests for algorithm-agnostic functionality of MAC implementations backed by Android Keystore.
+ */
+public class MacTest extends TestCase {
+
+    private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_CRYPTO_OP_PROVIDER_NAME;
+
+    private static final String[] EXPECTED_ALGORITHMS = {
+        "HmacSHA1",
+        "HmacSHA224",
+        "HmacSHA256",
+        "HmacSHA384",
+        "HmacSHA512",
+    };
+
+    private static final byte[] KAT_KEY = HexEncoding.decode(
+            "227b212bebd775493929ef626729a587d3f81b8e18a3ed482d403910e184479b448cfa79b62bd90595efdd"
+            + "15f87bd7b2d2dac480c61e969ba90a7b8ceadd3284");
+
+    private static final byte[] SHORT_MSG_KAT_MESSAGE = HexEncoding.decode("a16037e3c901c9a1ab");
+
+    private static final Map<String, Collection<KatVector>> SHORT_MSG_KAT_MACS =
+            new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+    static {
+        // From RI
+        SHORT_MSG_KAT_MACS.put("HmacSHA1", Arrays.asList(
+                new KatVector(HexEncoding.decode("4818c5466a1d05bc8f6ad4"),
+                        HexEncoding.decode("aa178e4d174dc90d1ac3d22386c32d1af82396e7")),
+                new KatVector(HexEncoding.decode("8d07f59f63fc493711a2217d8603cbc4d9874c58"),
+                        HexEncoding.decode("002215de36f8836e966ff459af80c4b31fe0ca27")),
+                new KatVector(HexEncoding.decode("f85f1c94023968729e3b4a7f495bf31c283b710662"),
+                        HexEncoding.decode("f518db3015203606ea15145ad16b3d981db32a77"))));
+        SHORT_MSG_KAT_MACS.put("HmacSHA224", Arrays.asList(
+                new KatVector(
+                        HexEncoding.decode(
+                                "ed959815cc03f01e19ce93c1a3318ae87a905b7c27351d571ee858"),
+                        HexEncoding.decode(
+                                "abece4641458461f8b6a46f7daa61fc6119344c5c4bb5e7967da0e3e")),
+                new KatVector(
+                        HexEncoding.decode(
+                                "9150e1ad6a9d12370a2423a5d95e9bc2dd73b4ee9bc96b03c9cc2fba"),
+                        HexEncoding.decode(
+                                "523aa06730d1abe7da2ba94a966cd20db56c771f1899e2850c31158c")),
+                new KatVector(
+                        HexEncoding.decode(
+                                "424d5e7375c2040543f76b97451b1c074ee93b81ad24cef23800ebfe529a74ee2b"
+                                ),
+                        HexEncoding.decode(
+                                "7627a86d829f45e3295a25813219ed5291f80029b972192d32a845c3"))));
+        SHORT_MSG_KAT_MACS.put("HmacSHA256", Arrays.asList(
+                new KatVector(
+                        HexEncoding.decode(
+                                "74a7ec4c79419d76fa5d3bdbedc17e5bebf0ee011c609b9f4c9126091613"),
+                        HexEncoding.decode(
+                                "c17b62519155b0d7f005f465becf9a1610635ae46a2c4d2b255851f201689ba5"
+                                )),
+                new KatVector(
+                        HexEncoding.decode(
+                                "42b44e6a1600bed10ca6c6dc24df2871790f948e73f9457fa4889c340cf69496"),
+                        HexEncoding.decode(
+                                "e9082a5db98c8086ad306ac23a1da9478eb5733757af6b1148d25fa1459290de")
+                                ),
+                new KatVector(
+                        HexEncoding.decode(
+                                "20bfc407c62022fea95f046f8ade6ee4b232665a9e97f75d3e35f1a9447991651a"
+                                        ),
+                        HexEncoding.decode(
+                                "dbf10ca8c362aa665562065e76e42beb19444f61ab0828438714c82779b71a0d"
+                                ))));
+        SHORT_MSG_KAT_MACS.put("HmacSHA384", Arrays.asList(
+                new KatVector(
+                        HexEncoding.decode(
+                                "7d277b2ec95fca68fe6ce0b665b28b48e128762714c66ca2c3405b432f6ab835e3"
+                                ),
+                        HexEncoding.decode(
+                                "bf8555816d8fa058e1d0ed4be23abda522adfae629b6a8819dcc2416d00507782a"
+                                        + "c714fdbfc7a340da4e6cf646a619f1")),
+                new KatVector(
+                        HexEncoding.decode(
+                                "7b30abe948ceab9d94965f274fd2a21c966aa9bdf06476f94a0bcc6c20fd5d2bdc"
+                                        + "e21af7c6fdf6017bce342a701f55c3"),
+                        HexEncoding.decode(
+                                "0fe51798528407119a5884f65ad76409983e978e25ab8f82aa412c08e76c8065d2"
+                                        + "6dfdb1935de49036fb24262a532a29")),
+                new KatVector(
+                        HexEncoding.decode(
+                                "26f232a40ada35850a14edf8f23c9ca97898ac0fa18640e5a7835230fa68f630b1"
+                                        + "c4579bc059c318bb2c5da609db13f1567fa175a6439e1d729713d1fa"
+                                        + "1039a3db"),
+                        HexEncoding.decode(
+                                "a086c610a382c24bb05e8bdd12cffc01055ec98a8f071239360cf8135205ffee33"
+                                        + "2da2134bed2ec3efde8bf145d1d257"))));
+        SHORT_MSG_KAT_MACS.put("HmacSHA512", Arrays.asList(
+                new KatVector(
+                        HexEncoding.decode(
+                                "46fb12ef48d4e8162f0828a66c9f7124de"),
+                        HexEncoding.decode(
+                                "036320b51376f5840b03fdababac53c189d4d6b35f26f562a909f8ecac4a02c244"
+                                        + "bfddc8f4eb89e0d0909fd2d8a46b796175e619cff215a675ce309540"
+                                        + "42b1c9")),
+                new KatVector(
+                        HexEncoding.decode(
+                                "45b3f16b1a247dd76f72ab2d5019f87b94efeb9a2fc01da3ca347050302dbda9c1"
+                                        + "19cf991aaa30b747c808ec6bc19be7b5ae5e66176e38f222347a1659"
+                                        + "15d007"),
+                        HexEncoding.decode(
+                                "92817ce36858ccad20a903e15952565d241ebaa87e07655754470090f1c6b9252a"
+                                        + "cff9b873f36840fa8fdaaf91c6f9de3b82f46de0b1fdfa584eaf27de"
+                                        + "f52c65")),
+                new KatVector(
+                        HexEncoding.decode(
+                                "e91630c69c8c294755e27e5ccf01fe09e06de6c4e423c1c4ef0ac9b67f9af3cc6b"
+                                        + "bc6292d18cf6e76738888a948b49f9509b44eb3af6974ca7e61f5208"
+                                        + "b9f7dca3"),
+                        HexEncoding.decode(
+                                "6ff5616e9c38cef3d20076841c65b8747193eb8033ea61e8693715109e0e448966"
+                                        + "3d8abcb2b7cf0911e461202112819fb8650ba02bdce08aa0d24b3873"
+                                        + "30f18f"))));
+    }
+
+    private static final byte[] LONG_MSG_KAT_SEED = SHORT_MSG_KAT_MESSAGE;
+    private static final int LONG_MSG_KAT_SIZE_BYTES = 3 * 1024 * 1024 + 149;
+
+    private static final Map<String, byte[]> LONG_MSG_KAT_MACS =
+            new TreeMap<String, byte[]>(String.CASE_INSENSITIVE_ORDER);
+    static {
+        // From RI
+        LONG_MSG_KAT_MACS.put("HmacSHA1", HexEncoding.decode(
+                "2a89d12da79f541512db9c35c0a1e76750e01d48"));
+        LONG_MSG_KAT_MACS.put("HmacSHA224", HexEncoding.decode(
+                "5fef55c822f9b931c1b4ad7142e0a74ceaddf03f0a6533155cc06871"));
+        LONG_MSG_KAT_MACS.put("HmacSHA256", HexEncoding.decode(
+                "0bc25f22b8993d003a95a88c6cfa1c5a7b067a8aae1064ef897712418569bfe9"));
+        LONG_MSG_KAT_MACS.put("HmacSHA384", HexEncoding.decode(
+                "595a616295123966126102c06d69f8bb06c11090490186243420c2c4692877d75752b220c1b0447320"
+                + "959e28345523fc"));
+        LONG_MSG_KAT_MACS.put("HmacSHA512", HexEncoding.decode(
+                "aa97d594d799164d56e6652578f7884d1198bb2663641ad7903e3c0bda4c136e9f94ca0d16c3504302"
+                + "2944224e538e88a5410adb38eaa5169b3125738990e6d0"));
+    }
+
+
+    private static final long DAY_IN_MILLIS = TestUtils.DAY_IN_MILLIS;
+
+    public void testAlgorithmList() {
+        // Assert that Android Keystore Provider exposes exactly the expected MAC algorithms. We
+        // don't care whether the algorithms are exposed via aliases, as long as the canonical names
+        // of algorithms are accepted.
+        // If the Provider exposes extraneous algorithms, it'll be caught because it'll have to
+        // expose at least one Service for such an algorithm, and this Service's algorithm will
+        // not be in the expected set.
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        Set<Service> services = provider.getServices();
+        Set<String> actualAlgsLowerCase = new HashSet<String>();
+        Set<String> expectedAlgsLowerCase = new HashSet<String>(
+                Arrays.asList(TestUtils.toLowerCase(EXPECTED_ALGORITHMS)));
+        for (Service service : services) {
+            if ("Mac".equalsIgnoreCase(service.getType())) {
+                String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US);
+                actualAlgsLowerCase.add(algLowerCase);
+            }
+        }
+
+        TestUtils.assertContentsInAnyOrder(actualAlgsLowerCase,
+                expectedAlgsLowerCase.toArray(new String[0]));
+    }
+
+    public void testAndroidKeyStoreKeysHandledByAndroidKeyStoreProvider() throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKey key = importDefaultKatKey(algorithm);
+
+                // Generate a MAC
+                Mac mac = Mac.getInstance(algorithm);
+                mac.init(key);
+                assertSame(provider, mac.getProvider());
+            } catch (Throwable e) {
+                throw new RuntimeException(algorithm + " failed", e);
+            }
+        }
+    }
+
+    public void testMacGeneratedForEmptyMessage() throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKey key = importDefaultKatKey(algorithm);
+
+                // Generate a MAC
+                Mac mac = Mac.getInstance(algorithm, provider);
+                mac.init(key);
+                byte[] macBytes = mac.doFinal();
+                assertNotNull(macBytes);
+                if (macBytes.length == 0) {
+                    fail("Empty MAC");
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException(algorithm + " failed", e);
+            }
+        }
+    }
+
+    public void testMacGeneratedByAndroidKeyStoreVerifiesByAndroidKeyStore() throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKey key = importDefaultKatKey(algorithm);
+
+                // Generate a MAC
+                Mac mac = Mac.getInstance(algorithm, provider);
+                mac.init(key);
+                byte[] message = "This is a test".getBytes("UTF-8");
+                byte[] macBytes = mac.doFinal(message);
+
+                assertMacVerifiesOneShot(algorithm, provider, key, message, macBytes);
+            } catch (Throwable e) {
+                throw new RuntimeException(algorithm + " failed", e);
+            }
+        }
+    }
+
+    public void testMacGeneratedByAndroidKeyStoreVerifiesByHighestPriorityProvider()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKey key = getDefaultKatKey(algorithm);
+                SecretKey keystoreKey = importDefaultKatKey(algorithm);
+
+                // Generate a MAC
+                Mac mac = Mac.getInstance(algorithm, provider);
+                mac.init(keystoreKey);
+                byte[] message = "This is a test".getBytes("UTF-8");
+                byte[] macBytes = mac.doFinal(message);
+
+                assertMacVerifiesOneShot(algorithm, key, message, macBytes);
+            } catch (Throwable e) {
+                throw new RuntimeException(algorithm + " failed", e);
+            }
+        }
+    }
+
+    public void testMacGeneratedByHighestPriorityProviderVerifiesByAndroidKeyStore()
+            throws Exception {
+        Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(keystoreProvider);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            Provider signingProvider = null;
+            try {
+                SecretKey key = getDefaultKatKey(algorithm);
+                SecretKey keystoreKey = importDefaultKatKey(algorithm);
+
+                // Generate a MAC
+                Mac mac = Mac.getInstance(algorithm);
+                mac.init(key);
+                signingProvider = mac.getProvider();
+                byte[] message = "This is a test".getBytes("UTF-8");
+                byte[] macBytes = mac.doFinal(message);
+
+                assertMacVerifiesOneShot(
+                        algorithm, keystoreProvider, keystoreKey, message, macBytes);
+            } catch (Throwable e) {
+                throw new RuntimeException(
+                        algorithm + " failed, signing provider: " + signingProvider, e);
+            }
+        }
+    }
+
+    public void testSmallMsgKat() throws Exception {
+        byte[] message = SHORT_MSG_KAT_MESSAGE;
+
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            for (KatVector testVector : SHORT_MSG_KAT_MACS.get(algorithm)) {
+                byte[] keyBytes = testVector.key;
+                try {
+                    SecretKey key = TestUtils.importIntoAndroidKeyStore(
+                            "test",
+                            new SecretKeySpec(keyBytes, algorithm),
+                            getWorkingImportParams(algorithm)).getKeystoreBackedSecretKey();
+
+                    byte[] goodMacBytes = testVector.mac.clone();
+                    assertNotNull(goodMacBytes);
+                    assertMacVerifiesOneShot(algorithm, key, message, goodMacBytes);
+                    assertMacVerifiesFedOneByteAtATime(algorithm, key, message, goodMacBytes);
+                    assertMacVerifiesFedUsingFixedSizeChunks(
+                            algorithm, key, message, goodMacBytes, 3);
+
+                    byte[] messageWithBitFlip = message.clone();
+                    messageWithBitFlip[messageWithBitFlip.length / 2] ^= 1;
+                    assertMacDoesNotVerifyOneShot(algorithm, key, messageWithBitFlip, goodMacBytes);
+
+                    byte[] goodMacWithBitFlip = goodMacBytes.clone();
+                    goodMacWithBitFlip[goodMacWithBitFlip.length / 2] ^= 1;
+                    assertMacDoesNotVerifyOneShot(algorithm, key, message, goodMacWithBitFlip);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key " + HexEncoding.encode(keyBytes),
+                            e);
+                }
+            }
+        }
+    }
+
+    public void testLargeMsgKat() throws Exception {
+        byte[] message = TestUtils.generateLargeKatMsg(LONG_MSG_KAT_SEED, LONG_MSG_KAT_SIZE_BYTES);
+
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKey key = importDefaultKatKey(algorithm);
+
+                byte[] goodMacBytes = LONG_MSG_KAT_MACS.get(algorithm);
+                assertNotNull(goodMacBytes);
+                assertMacVerifiesOneShot(algorithm,  key, message, goodMacBytes);
+                assertMacVerifiesFedUsingFixedSizeChunks(
+                        algorithm, key, message, goodMacBytes, 20389);
+                assertMacVerifiesFedUsingFixedSizeChunks(
+                        algorithm, key, message, goodMacBytes, 393571);
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitFailsWhenNotAuthorizedToSign() throws Exception {
+        int badPurposes = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT
+                | KeyProperties.PURPOSE_VERIFY;
+
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyProtection good = getWorkingImportParams(algorithm);
+                assertInitSucceeds(algorithm, good);
+                assertInitThrowsInvalidKeyException(algorithm,
+                        TestUtils.buildUpon(good, badPurposes).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitFailsWhenDigestNotAuthorized() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyProtection good = getWorkingImportParams(algorithm);
+                assertInitSucceeds(algorithm, good);
+
+                String badKeyAlgorithm = ("HmacSHA256".equalsIgnoreCase(algorithm))
+                        ? "HmacSHA384" : "HmacSHA256";
+                assertInitThrowsInvalidKeyException(algorithm, badKeyAlgorithm, good);
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitFailsWhenKeyNotYetValid() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyProtection good = TestUtils.buildUpon(getWorkingImportParams(algorithm))
+                        .setKeyValidityStart(new Date(System.currentTimeMillis() - DAY_IN_MILLIS))
+                        .build();
+                assertInitSucceeds(algorithm, good);
+
+                Date badStartDate = new Date(System.currentTimeMillis() + DAY_IN_MILLIS);
+                assertInitThrowsInvalidKeyException(algorithm,
+                        TestUtils.buildUpon(good).setKeyValidityStart(badStartDate).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitFailsWhenKeyNoLongerValidForOrigination() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyProtection good = TestUtils.buildUpon(getWorkingImportParams(algorithm))
+                        .setKeyValidityForOriginationEnd(
+                                new Date(System.currentTimeMillis() + DAY_IN_MILLIS))
+                        .build();
+                assertInitSucceeds(algorithm, good);
+
+                Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+                assertInitThrowsInvalidKeyException(algorithm,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForOriginationEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitIgnoresThatKeyNoLongerValidForConsumption() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyProtection good = TestUtils.buildUpon(getWorkingImportParams(algorithm))
+                        .setKeyValidityForConsumptionEnd(
+                                new Date(System.currentTimeMillis() + DAY_IN_MILLIS))
+                        .build();
+                assertInitSucceeds(algorithm, good);
+
+                Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+                assertInitSucceeds(algorithm,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForConsumptionEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    private void assertMacVerifiesOneShot(
+            String algorithm,
+            SecretKey key,
+            byte[] message,
+            byte[] mac) throws Exception {
+        assertMacVerifiesOneShot(algorithm, null, key, message, mac);
+    }
+
+    private void assertMacVerifiesOneShot(
+            String algorithm,
+            Provider provider,
+            SecretKey key,
+            byte[] message,
+            byte[] mac) throws Exception {
+        Mac m = (provider != null)
+                ? Mac.getInstance(algorithm, provider) : Mac.getInstance(algorithm);
+        m.init(key);
+        byte[] mac2 = m.doFinal(message);
+        if (!Arrays.equals(mac, mac2)) {
+            fail("MAC did not verify. algorithm: " + algorithm
+                    + ", provider: " + m.getProvider().getName()
+                    + ", MAC (" + mac.length + " bytes): " + HexEncoding.encode(mac)
+                    + ", actual MAC (" + mac2.length + " bytes): " + HexEncoding.encode(mac2));
+        }
+    }
+
+    private void assertMacDoesNotVerifyOneShot(
+            String algorithm,
+            SecretKey key,
+            byte[] message,
+            byte[] mac) throws Exception {
+        Mac m = Mac.getInstance(algorithm);
+        m.init(key);
+        byte[] mac2 = m.doFinal(message);
+        if (Arrays.equals(mac, mac2)) {
+            fail("MAC verifies unexpectedly. algorithm: " + algorithm
+                    + ", provider: " + m.getProvider().getName()
+                    + ", MAC (" + mac.length + " bytes): " + HexEncoding.encode(mac));
+        }
+    }
+
+    private void assertMacVerifiesFedOneByteAtATime(
+            String algorithm,
+            SecretKey key,
+            byte[] message,
+            byte[] mac) throws Exception {
+        Mac m = Mac.getInstance(algorithm);
+        m.init(key);
+        for (int i = 0; i < message.length; i++) {
+            m.update(message[i]);
+        }
+        byte[] mac2 = m.doFinal();
+        if (!Arrays.equals(mac, mac2)) {
+            fail("MAC did not verify. algorithm: " + algorithm
+                    + ", provider: " + m.getProvider().getName()
+                    + ", MAC (" + mac.length + " bytes): " + HexEncoding.encode(mac)
+                    + ", actual MAC (" + mac2.length + " bytes): " + HexEncoding.encode(mac2));
+        }
+    }
+
+    private void assertMacVerifiesFedUsingFixedSizeChunks(
+            String algorithm,
+            SecretKey key,
+            byte[] message,
+            byte[] mac,
+            int chunkSizeBytes) throws Exception {
+        Mac m = Mac.getInstance(algorithm);
+        m.init(key);
+        int messageRemaining = message.length;
+        int messageOffset = 0;
+        while (messageRemaining > 0) {
+            int actualChunkSizeBytes =  Math.min(chunkSizeBytes, messageRemaining);
+            m.update(message, messageOffset, actualChunkSizeBytes);
+            messageOffset += actualChunkSizeBytes;
+            messageRemaining -= actualChunkSizeBytes;
+        }
+        byte[] mac2 = m.doFinal();
+        if (!Arrays.equals(mac, mac2)) {
+            fail("MAC did not verify. algorithm: " + algorithm
+                    + ", provider: " + m.getProvider().getName()
+                    + ", MAC (" + mac.length + " bytes): " + HexEncoding.encode(mac)
+                    + ", actual MAC (" + mac2.length + " bytes): " + HexEncoding.encode(mac2));
+        }
+    }
+
+    private void assertInitSucceeds(String algorithm, KeyProtection keyProtection)
+            throws Exception {
+        assertInitSucceeds(algorithm, algorithm, keyProtection);
+    }
+
+    private void assertInitSucceeds(
+            String macAlgorithm, String keyAlgorithm, KeyProtection keyProtection)
+                    throws Exception {
+        SecretKey key = importDefaultKatKey(keyAlgorithm, keyProtection);
+        Mac mac = Mac.getInstance(macAlgorithm);
+        mac.init(key);
+    }
+
+    private void assertInitThrowsInvalidKeyException(String algorithm, KeyProtection keyProtection)
+                    throws Exception {
+        assertInitThrowsInvalidKeyException(algorithm, algorithm, keyProtection);
+    }
+
+    private void assertInitThrowsInvalidKeyException(
+            String macAlgorithm, String keyAlgorithm, KeyProtection keyProtection)
+                    throws Exception {
+        SecretKey key = importDefaultKatKey(keyAlgorithm, keyProtection);
+        Mac mac = Mac.getInstance(macAlgorithm);
+        try {
+            mac.init(key);
+            fail("InvalidKeyException should have been thrown. MAC algorithm: " + macAlgorithm
+                    + ", key algorithm: " + keyAlgorithm);
+        } catch (InvalidKeyException expected) {}
+    }
+
+    private SecretKey getDefaultKatKey(String keyAlgorithm) {
+        return new SecretKeySpec(KAT_KEY, keyAlgorithm);
+    }
+
+    private SecretKey importDefaultKatKey(String keyAlgorithm) throws Exception {
+        return importDefaultKatKey(
+                keyAlgorithm,
+                new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build());
+    }
+
+    private SecretKey importDefaultKatKey(
+            String keyAlgorithm, KeyProtection keyProtection) throws Exception {
+        return TestUtils.importIntoAndroidKeyStore(
+                "test1",
+                getDefaultKatKey(keyAlgorithm),
+                keyProtection).getKeystoreBackedSecretKey();
+    }
+
+    private static KeyProtection getWorkingImportParams(
+            @SuppressWarnings("unused") String algorithm) {
+        return new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN).build();
+    }
+
+    private static class KatVector {
+        public byte[] key;
+        public byte[] mac;
+
+        public KatVector(byte[] key, byte[] mac) {
+            this.key = key;
+            this.mac = mac;
+        }
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/PutOverflowTest.java b/tests/tests/keystore/src/android/keystore/cts/PutOverflowTest.java
new file mode 100644
index 0000000..088af35
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/PutOverflowTest.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 android.keystore.cts;
+
+import android.test.AndroidTestCase;
+import java.lang.reflect.Method;
+
+public class PutOverflowTest extends AndroidTestCase {
+    public void testCrash() throws Exception {
+        try {
+            Class<?> keystoreClass = Class.forName("android.security.KeyStore");
+            Method getInstance = keystoreClass.getMethod("getInstance");
+            Method put = keystoreClass.getMethod("put",
+                    String.class, byte[].class, int.class, int.class);
+            Object keystore = getInstance.invoke(null);
+            byte[] buffer = new byte[65536];
+            Boolean result = (Boolean)put.invoke(keystore, "crashFile", buffer, -1, 0);
+            assertTrue("Fix for ANDROID-22802399 not present", result);
+        } catch (ReflectiveOperationException ignored) {
+            // Since this test requires reflection avoid causing undue failures if classes or
+            // methods were changed.
+        }
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/RSACipherTest.java b/tests/tests/keystore/src/android/keystore/cts/RSACipherTest.java
new file mode 100644
index 0000000..3403df3
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/RSACipherTest.java
@@ -0,0 +1,251 @@
+/*
+ * 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.keystore.cts;
+
+import java.math.BigInteger;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.interfaces.RSAKey;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+
+import android.security.keystore.KeyProperties;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+public class RSACipherTest extends AndroidTestCase {
+
+    private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_CRYPTO_OP_PROVIDER_NAME;
+
+    public void testNoPaddingEncryptionAndDecryptionSucceedsWithInputShorterThanModulus()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        for (ImportedKey key : RSASignatureTest.importKatKeyPairs(getContext(),
+                TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        "RSA/ECB/NoPadding",
+                        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                        false))) {
+            try {
+                PublicKey publicKey = key.getKeystoreBackedKeyPair().getPublic();
+                PrivateKey privateKey = key.getKeystoreBackedKeyPair().getPrivate();
+                BigInteger modulus = ((RSAKey) publicKey).getModulus();
+                int modulusSizeBytes = (modulus.bitLength() + 7) / 8;
+
+                // 1-byte long input for which we know the output
+                byte[] input = new byte[] {1};
+                // Because of how RSA works, the output is 1 (left-padded with zero bytes).
+                byte[] expectedOutput = TestUtils.leftPadWithZeroBytes(input, modulusSizeBytes);
+
+                Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+                MoreAsserts.assertEquals(expectedOutput, cipher.doFinal(input));
+
+                cipher.init(Cipher.DECRYPT_MODE, privateKey);
+                MoreAsserts.assertEquals(expectedOutput, cipher.doFinal(input));
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for key " + key.getAlias(), e);
+            }
+        }
+    }
+
+    public void testNoPaddingEncryptionSucceedsWithPlaintextOneSmallerThanModulus()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        for (ImportedKey key : RSASignatureTest.importKatKeyPairs(getContext(),
+                TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        "RSA/ECB/NoPadding",
+                        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                        false))) {
+            try {
+                PublicKey publicKey = key.getKeystoreBackedKeyPair().getPublic();
+                PrivateKey privateKey = key.getKeystoreBackedKeyPair().getPrivate();
+                BigInteger modulus = ((RSAKey) publicKey).getModulus();
+
+                // Plaintext is one smaller than the modulus
+                byte[] plaintext =
+                        TestUtils.getBigIntegerMagnitudeBytes(modulus.subtract(BigInteger.ONE));
+                Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+                byte[] ciphertext = cipher.doFinal(plaintext);
+                cipher.init(Cipher.DECRYPT_MODE, privateKey);
+                MoreAsserts.assertEquals(plaintext, cipher.doFinal(ciphertext));
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for key " + key.getAlias(), e);
+            }
+        }
+    }
+
+    public void testNoPaddingEncryptionFailsWithPlaintextEqualToModulus() throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        for (ImportedKey key : RSASignatureTest.importKatKeyPairs(getContext(),
+                TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        "RSA/ECB/NoPadding",
+                        KeyProperties.PURPOSE_ENCRYPT ,
+                        false))) {
+            try {
+                PublicKey publicKey = key.getKeystoreBackedKeyPair().getPublic();
+                BigInteger modulus = ((RSAKey) publicKey).getModulus();
+
+                // Plaintext is exactly the modulus
+                byte[] plaintext = TestUtils.getBigIntegerMagnitudeBytes(modulus);
+                Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+                try {
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    fail("Unexpectedly produced ciphertext (" + ciphertext.length + " bytes): "
+                            + HexEncoding.encode(ciphertext));
+                } catch (BadPaddingException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for key " + key.getAlias(), e);
+            }
+        }
+    }
+
+    public void testNoPaddingEncryptionFailsWithPlaintextOneLargerThanModulus() throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        for (ImportedKey key : RSASignatureTest.importKatKeyPairs(getContext(),
+                TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        "RSA/ECB/NoPadding",
+                        KeyProperties.PURPOSE_ENCRYPT,
+                        false))) {
+            try {
+                PublicKey publicKey = key.getKeystoreBackedKeyPair().getPublic();
+                BigInteger modulus = ((RSAKey) publicKey).getModulus();
+
+                // Plaintext is one larger than the modulus
+                byte[] plaintext =
+                        TestUtils.getBigIntegerMagnitudeBytes(modulus.add(BigInteger.ONE));
+                Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+                try {
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    fail("Unexpectedly produced ciphertext (" + ciphertext.length + " bytes): "
+                            + HexEncoding.encode(ciphertext));
+                } catch (BadPaddingException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for key " + key.getAlias(), e);
+            }
+        }
+    }
+
+    public void testNoPaddingEncryptionFailsWithPlaintextOneByteLongerThanModulus()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        for (ImportedKey key : RSASignatureTest.importKatKeyPairs(getContext(),
+                TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        "RSA/ECB/NoPadding",
+                        KeyProperties.PURPOSE_ENCRYPT,
+                        false))) {
+            try {
+                PublicKey publicKey = key.getKeystoreBackedKeyPair().getPublic();
+                BigInteger modulus = ((RSAKey) publicKey).getModulus();
+
+                // Plaintext is one byte longer than the modulus. The message is filled with zeros
+                // (thus being 0 if treated as a BigInteger). This is on purpose, to check that the
+                // Cipher implementation rejects such long message without comparing it to the value
+                // of the modulus.
+                byte[] plaintext = new byte[((modulus.bitLength() + 7) / 8) + 1];
+                Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding", provider);
+                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+                try {
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    fail("Unexpectedly produced ciphertext (" + ciphertext.length + " bytes): "
+                            + HexEncoding.encode(ciphertext));
+                } catch (IllegalBlockSizeException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for key " + key.getAlias(), e);
+            }
+        }
+    }
+
+    public void testNoPaddingDecryptionFailsWithCiphertextOneByteLongerThanModulus()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        for (ImportedKey key : RSASignatureTest.importKatKeyPairs(getContext(),
+                TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        "RSA/ECB/NoPadding",
+                        KeyProperties.PURPOSE_DECRYPT,
+                        false))) {
+            try {
+                PrivateKey privateKey = key.getKeystoreBackedKeyPair().getPrivate();
+                BigInteger modulus = ((RSAKey) privateKey).getModulus();
+
+                // Ciphertext is one byte longer than the modulus. The message is filled with zeros
+                // (thus being 0 if treated as a BigInteger). This is on purpose, to check that the
+                // Cipher implementation rejects such long message without comparing it to the value
+                // of the modulus.
+                byte[] ciphertext = new byte[((modulus.bitLength() + 7) / 8) + 1];
+                Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding", EXPECTED_PROVIDER_NAME);
+                cipher.init(Cipher.DECRYPT_MODE, privateKey);
+                try {
+                    byte[] plaintext = cipher.doFinal(ciphertext);
+                    fail("Unexpectedly produced plaintext (" + ciphertext.length + " bytes): "
+                            + HexEncoding.encode(plaintext));
+                } catch (IllegalBlockSizeException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for key " + key.getAlias(), e);
+            }
+        }
+    }
+
+    public void testNoPaddingWithZeroMessage() throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        for (ImportedKey key : RSASignatureTest.importKatKeyPairs(getContext(),
+                TestUtils.getMinimalWorkingImportParametersForCipheringWith(
+                        "RSA/ECB/NoPadding",
+                        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                        false))) {
+            try {
+                PublicKey publicKey = key.getKeystoreBackedKeyPair().getPublic();
+                PrivateKey privateKey = key.getKeystoreBackedKeyPair().getPrivate();
+
+                byte[] plaintext = EmptyArray.BYTE;
+                Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding", EXPECTED_PROVIDER_NAME);
+                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+                byte[] ciphertext = cipher.doFinal(plaintext);
+                // Ciphertext should be all zero bytes
+                byte[] expectedCiphertext = new byte[(TestUtils.getKeySizeBits(publicKey) + 7) / 8];
+                MoreAsserts.assertEquals(expectedCiphertext, ciphertext);
+
+                cipher.init(Cipher.DECRYPT_MODE, privateKey);
+                // Decrypted plaintext should also be all zero bytes
+                byte[] expectedPlaintext = new byte[expectedCiphertext.length];
+                MoreAsserts.assertEquals(expectedPlaintext, cipher.doFinal(ciphertext));
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for key " + key.getAlias(), e);
+            }
+        }
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java
new file mode 100644
index 0000000..9ae3043
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/RSASignatureTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 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 java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.interfaces.RSAKey;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import com.android.cts.keystore.R;
+
+import android.content.Context;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.test.AndroidTestCase;
+
+public class RSASignatureTest extends AndroidTestCase {
+
+    private static final String EXPECTED_PROVIDER_NAME = SignatureTest.EXPECTED_PROVIDER_NAME;
+
+    private static final String[] SIGNATURE_ALGORITHMS;
+
+    static {
+        List<String> sigAlgs = new ArrayList<>();
+        for (String algorithm : SignatureTest.EXPECTED_SIGNATURE_ALGORITHMS) {
+            String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(algorithm);
+            if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+                sigAlgs.add(algorithm);
+            }
+        }
+        SIGNATURE_ALGORITHMS = sigAlgs.toArray(new String[sigAlgs.size()]);
+    }
+
+    public void testMaxMessageSizeWhenNoDigestUsed() throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        for (ImportedKey keyPair : importKatKeyPairs("NONEwithRSA")) {
+            PublicKey publicKey = keyPair.getKeystoreBackedKeyPair().getPublic();
+            PrivateKey privateKey = keyPair.getKeystoreBackedKeyPair().getPrivate();
+            int modulusSizeBits = ((RSAKey) publicKey).getModulus().bitLength();
+            try {
+                int modulusSizeBytes = (modulusSizeBits + 7) / 8;
+                // PKCS#1 signature padding must be at least 11 bytes long (00 || 01 || PS || 00)
+                // where PS must be at least 8 bytes long).
+                int expectedMaxMessageSizeBytes = modulusSizeBytes - 11;
+                byte[] msg = new byte[expectedMaxMessageSizeBytes + 1];
+                Arrays.fill(msg, (byte) 0xf0);
+
+                // Assert that a message of expected maximum length is accepted
+                Signature signature = Signature.getInstance("NONEwithRSA", provider);
+                signature.initSign(privateKey);
+                signature.update(msg, 0, expectedMaxMessageSizeBytes);
+                byte[] sigBytes = signature.sign();
+
+                signature.initVerify(publicKey);
+                signature.update(msg, 0, expectedMaxMessageSizeBytes);
+                assertTrue(signature.verify(sigBytes));
+
+                // Assert that a message longer than expected maximum length is rejected
+                signature = Signature.getInstance(signature.getAlgorithm(), provider);
+                signature.initSign(privateKey);
+                try {
+                    signature.update(msg, 0, expectedMaxMessageSizeBytes + 1);
+                    signature.sign();
+                    fail();
+                } catch (SignatureException expected) {
+                }
+
+                signature.initVerify(publicKey);
+                try {
+                    signature.update(msg, 0, expectedMaxMessageSizeBytes + 1);
+                    signature.verify(sigBytes);
+                    fail();
+                } catch (SignatureException expected) {
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + modulusSizeBits + " bit key", e);
+            }
+        }
+    }
+
+    public void testSmallKeyRejected() throws Exception {
+        // Use a 512 bit key which should prevent the use of any digests larger than SHA-256
+        // because the padded form of the digested message will be larger than modulus size.
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        for (String algorithm : SIGNATURE_ALGORITHMS) {
+            try {
+                String digest = TestUtils.getSignatureAlgorithmDigest(algorithm);
+                if (KeyProperties.DIGEST_NONE.equalsIgnoreCase(digest)) {
+                    // Ignore signature algorithms without digest -- this is tested in a separate
+                    // test above.
+                    continue;
+                }
+                int digestOutputSizeBits = TestUtils.getDigestOutputSizeBits(digest);
+                if (digestOutputSizeBits <= 256) {
+                    // 256-bit and shorter digests are short enough to work with a 512 bit key.
+                    continue;
+                }
+
+                KeyPair keyPair = TestUtils.importIntoAndroidKeyStore("test1",
+                        getContext(),
+                        R.raw.rsa_key5_512_pkcs8,
+                        R.raw.rsa_key5_512_cert,
+                        TestUtils.getMinimalWorkingImportParametersForSigningingWith(algorithm))
+                        .getKeystoreBackedKeyPair();
+                assertEquals(512, ((RSAKey) keyPair.getPrivate()).getModulus().bitLength());
+                assertEquals(512, ((RSAKey) keyPair.getPublic()).getModulus().bitLength());
+
+                Signature signature = Signature.getInstance(algorithm, provider);
+                // Assert that either initSign or sign fails. We don't expect all keymaster
+                // implementations to fail early, during initSign.
+                try {
+                    signature.initSign(keyPair.getPrivate());
+                    signature.update("A message".getBytes("UTF-8"));
+                    byte[] sigBytes = signature.sign();
+                    fail("Unexpectedly generated a signature (" + sigBytes.length + " bytes): "
+                            + HexEncoding.encode(sigBytes));
+                } catch (InvalidKeyException | SignatureException expected) {
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    private Collection<ImportedKey> importKatKeyPairs(String signatureAlgorithm)
+            throws Exception {
+        KeyProtection params =
+                TestUtils.getMinimalWorkingImportParametersForSigningingWith(signatureAlgorithm);
+        return importKatKeyPairs(getContext(), params);
+    }
+
+    static Collection<ImportedKey> importKatKeyPairs(
+            Context context, KeyProtection importParams) throws Exception {
+        return Arrays.asList(new ImportedKey[] {
+                TestUtils.importIntoAndroidKeyStore("testRSA512", context,
+                        R.raw.rsa_key5_512_pkcs8, R.raw.rsa_key5_512_cert, importParams),
+                TestUtils.importIntoAndroidKeyStore("testRSA768", context,
+                        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,
+                        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),
+                TestUtils.importIntoAndroidKeyStore("testRSA4096", context,
+                        R.raw.rsa_key4_4096_pkcs8, R.raw.rsa_key4_4096_cert, importParams),
+                });
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java b/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java
new file mode 100644
index 0000000..17307f7
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/SecretKeyFactoryTest.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyInfo;
+import android.security.keystore.KeyProperties;
+import android.test.MoreAsserts;
+
+import junit.framework.TestCase;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.InvalidKeySpecException;
+import java.security.Provider.Service;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Set;
+
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.SecretKeySpec;
+
+public class SecretKeyFactoryTest extends TestCase {
+    private static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_PROVIDER_NAME;
+
+    private static final String[] EXPECTED_ALGORITHMS = {
+        "AES",
+        "HmacSHA1",
+        "HmacSHA224",
+        "HmacSHA256",
+        "HmacSHA384",
+        "HmacSHA512",
+    };
+
+    public void testAlgorithmList() {
+        // Assert that Android Keystore Provider exposes exactly the expected SecretKeyFactory
+        // algorithms. We don't care whether the algorithms are exposed via aliases, as long as
+        // canonical names of algorithms are accepted. If the Provider exposes extraneous
+        // algorithms, it'll be caught because it'll have to expose at least one Service for such an
+        // algorithm, and this Service's algorithm will not be in the expected set.
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        Set<Service> services = provider.getServices();
+        Set<String> actualAlgsLowerCase = new HashSet<String>();
+        Set<String> expectedAlgsLowerCase = new HashSet<String>(
+                Arrays.asList(TestUtils.toLowerCase(EXPECTED_ALGORITHMS)));
+        for (Service service : services) {
+            if ("SecretKeyFactory".equalsIgnoreCase(service.getType())) {
+                String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US);
+                actualAlgsLowerCase.add(algLowerCase);
+            }
+        }
+
+        TestUtils.assertContentsInAnyOrder(actualAlgsLowerCase,
+                expectedAlgsLowerCase.toArray(new String[0]));
+    }
+
+    public void testGetKeySpecWithKeystoreKeyAndKeyInfoReflectsAllAuthorizations()
+            throws Exception {
+        Date keyValidityStart = new Date(System.currentTimeMillis() - TestUtils.DAY_IN_MILLIS);
+        Date keyValidityForOriginationEnd =
+                new Date(System.currentTimeMillis() + TestUtils.DAY_IN_MILLIS);
+        Date keyValidityForConsumptionEnd =
+                new Date(System.currentTimeMillis() + 3 * TestUtils.DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                String[] blockModes =
+                        new String[] {KeyProperties.BLOCK_MODE_CTR, KeyProperties.BLOCK_MODE_ECB};
+                String[] encryptionPaddings =
+                        new String[] {KeyProperties.ENCRYPTION_PADDING_PKCS7,
+                                KeyProperties.ENCRYPTION_PADDING_NONE};
+                String[] digests;
+                int purposes;
+                if (TestUtils.isHmacAlgorithm(algorithm)) {
+                    String digest = TestUtils.getHmacAlgorithmDigest(algorithm);
+                    digests = new String[] {digest};
+                    purposes = KeyProperties.PURPOSE_SIGN;
+                } else {
+                    digests = new String[] {KeyProperties.DIGEST_SHA384};
+                    purposes = KeyProperties.PURPOSE_DECRYPT;
+                }
+                KeyGenerator keyGenerator =
+                        KeyGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.init(new KeyGenParameterSpec.Builder("test1", purposes)
+                        .setBlockModes(blockModes)
+                        .setEncryptionPaddings(encryptionPaddings)
+                        .setDigests(digests)
+                        .setKeyValidityStart(keyValidityStart)
+                        .setKeyValidityForOriginationEnd(keyValidityForOriginationEnd)
+                        .setKeyValidityForConsumptionEnd(keyValidityForConsumptionEnd)
+                        .build());
+                SecretKey key = keyGenerator.generateKey();
+                SecretKeyFactory keyFactory = getKeyFactory(algorithm);
+                KeyInfo keyInfo = (KeyInfo) keyFactory.getKeySpec(key, KeyInfo.class);
+                assertEquals("test1", keyInfo.getKeystoreAlias());
+                assertEquals(purposes, keyInfo.getPurposes());
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(blockModes), keyInfo.getBlockModes());
+                TestUtils.assertContentsInAnyOrder(
+                        Arrays.asList(encryptionPaddings), keyInfo.getEncryptionPaddings());
+                TestUtils.assertContentsInAnyOrder(Arrays.asList(digests), keyInfo.getDigests());
+                MoreAsserts.assertEmpty(Arrays.asList(keyInfo.getSignaturePaddings()));
+                assertEquals(keyValidityStart, keyInfo.getKeyValidityStart());
+                assertEquals(keyValidityForOriginationEnd,
+                        keyInfo.getKeyValidityForOriginationEnd());
+                assertEquals(keyValidityForConsumptionEnd,
+                        keyInfo.getKeyValidityForConsumptionEnd());
+                assertFalse(keyInfo.isUserAuthenticationRequired());
+                assertFalse(keyInfo.isUserAuthenticationRequirementEnforcedBySecureHardware());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testTranslateKeyWithNullKeyThrowsInvalidKeyException() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.translateKey(null);
+                    fail();
+                } catch (InvalidKeyException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testTranslateKeyRejectsNonAndroidKeystoreKeys() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKey key = new SecretKeySpec(new byte[16], algorithm);
+                SecretKeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.translateKey(key);
+                    fail();
+                } catch (InvalidKeyException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testTranslateKeyAcceptsAndroidKeystoreKeys() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator =
+                        KeyGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.init(new KeyGenParameterSpec.Builder("test1", 0).build());
+                SecretKey key = keyGenerator.generateKey();
+
+                SecretKeyFactory keyFactory = getKeyFactory(algorithm);
+                assertSame(key, keyFactory.translateKey(key));
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGenerateSecretWithNullSpecThrowsInvalidKeySpecException() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generateSecret(null);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGenerateSecretRejectsSecretKeySpec() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                SecretKeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generateSecret(new SecretKeySpec(new byte[16], algorithm));
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testGenerateSecretRejectsKeyInfo() throws Exception {
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            try {
+                KeyGenerator keyGenerator =
+                        KeyGenerator.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+                keyGenerator.init(new KeyGenParameterSpec.Builder("test1", 0).build());
+                SecretKey keystoreKey = keyGenerator.generateKey();
+                KeyInfo keyInfo = TestUtils.getKeyInfo(keystoreKey);
+
+                SecretKeyFactory keyFactory = getKeyFactory(algorithm);
+                try {
+                    keyFactory.generateSecret(keyInfo);
+                    fail();
+                } catch (InvalidKeySpecException expected) {}
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    private SecretKeyFactory getKeyFactory(String algorithm) throws NoSuchAlgorithmException,
+            NoSuchProviderException {
+        return SecretKeyFactory.getInstance(algorithm, EXPECTED_PROVIDER_NAME);
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java b/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
new file mode 100644
index 0000000..8451eb8
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/SignatureTest.java
@@ -0,0 +1,1317 @@
+/*
+ * 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.keystore.cts;
+
+import com.android.cts.keystore.R;
+
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.Provider.Service;
+import java.security.PublicKey;
+import java.security.Security;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import android.content.Context;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.test.AndroidTestCase;
+import android.test.MoreAsserts;
+
+/**
+ * Tests for algorithm-agnostic functionality of {@code Signature} implementations backed by Android
+ * Keystore.
+ */
+public class SignatureTest extends AndroidTestCase {
+
+    static final String EXPECTED_PROVIDER_NAME = TestUtils.EXPECTED_CRYPTO_OP_PROVIDER_NAME;
+
+    static final String[] EXPECTED_SIGNATURE_ALGORITHMS = {
+        "NONEwithRSA",
+        "MD5withRSA",
+        "SHA1withRSA",
+        "SHA224withRSA",
+        "SHA256withRSA",
+        "SHA384withRSA",
+        "SHA512withRSA",
+        "SHA1withRSA/PSS",
+        "SHA224withRSA/PSS",
+        "SHA256withRSA/PSS",
+        "SHA384withRSA/PSS",
+        "SHA512withRSA/PSS",
+        "NONEwithECDSA",
+        "SHA1withECDSA",
+        "SHA224withECDSA",
+        "SHA256withECDSA",
+        "SHA384withECDSA",
+        "SHA512withECDSA"
+    };
+
+    private static final Map<String, String> SIG_ALG_TO_CANONICAL_NAME_CASE_INSENSITIVE =
+            new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+    static {
+        // For an unknown legacy reason, libcore's ProviderTest#test_Provider_getServices insists
+        // that a Service with algorithm "ECDSA" be exposed, despite the RI not exposing any such
+        // services. Thus, our provider has to expose the "ECDSA" service whose actual proper
+        // name is SHA1withECDSA.
+        SIG_ALG_TO_CANONICAL_NAME_CASE_INSENSITIVE.put("ECDSA", "SHA1withECDSA");
+    }
+
+    private static final byte[] SHORT_MSG_KAT_MESSAGE =
+            HexEncoding.decode("ec174729c4f5c570ba0de4c424cdcbf0362a7718039464");
+    private static final byte[] LONG_MSG_KAT_SEED = SHORT_MSG_KAT_MESSAGE;
+    private static final int LONG_MSG_KAT_SIZE_BYTES = 3 * 1024 * 1024 + 123;
+
+    private static final Map<String, byte[]> SHORT_MSG_KAT_SIGNATURES =
+            new TreeMap<String, byte[]>(String.CASE_INSENSITIVE_ORDER);
+    static {
+        // From RI
+        SHORT_MSG_KAT_SIGNATURES.put("NONEwithECDSA", HexEncoding.decode(
+                "304402201ea57c2fb571991639d103bfec658ee7f359b60664e400a5834cfc20d28b588902202433f5"
+                + "eb07d2b03bf8d238ea256ea399d0913a6cfcae2c3b00e2efd50aebc967"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA1withECDSA", HexEncoding.decode(
+                "30440220742d71a013564ab196789322b9231ac5ff26460c2d6b1ab8ccb45eec254cc8ba0220780a86"
+                + "5ddc2334fae23d563e3142b04660c2ab1b875c4ff8c557a1d1accc43e1"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA224withECDSA", HexEncoding.decode(
+                "304502200f74966078b34317daa69e487c3163dbb4e0391cd74191cc3e95b33fc60966e3022100ebdc"
+                + "be19c516d550609f73fb37557a406e397bc1725a1baba50cdfc3537bd377"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA256withECDSA", HexEncoding.decode(
+                "304402204443b560d888beeae729155b0d9410fef2ec78607d9166af6144346fba8ce45d02205b0727"
+                + "bfa630050f1395c8bcf46c614c14eb15f2a6abbd3bc7c0e83b41819281"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA384withECDSA", HexEncoding.decode(
+                "3045022025ade03446ce95aa525a51aedd16baf12a2b8b9c1f4c87224c38e48c84cbbbf8022100ad21"
+                + "8424c3671bc1513e1da7e7186dbc6bf67bec434c95863a48e79f53684971"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA512withECDSA", HexEncoding.decode(
+                "3045022100969e8fed2dc4ddcdf341368e057efe4e3a00eda66bbb127dec31bb0144c5334602201087"
+                + "2b7f9ab9c06a07053e0641e6adc18a87a1d7807550a19e872e78e5c7f0dd"));
+
+        // From RI
+        SHORT_MSG_KAT_SIGNATURES.put("NONEwithRSA", HexEncoding.decode(
+                "257d0704e514ead29a5c45576adb2d5a7d7738e6a83b5d6463a5306788015d14580fee340e78e00d39"
+                + "f56ae616083ac929e5daf9eeab40b908eb05d0cd1036d9e92799587df0d4c5304c9b27f913e1c891"
+                + "919eff0df3b5d9c0d8cc4cd843795840799cc0353192c3868b3f8cad96d04bb566ca53e1146aa2a3"
+                + "4b890ce917680bbdea1dee417a89630224d2ee79d66d38c7c77e50b45e1dd1b8b63eb98ecd60426b"
+                + "c9fb30917e78ae4dd7cbfa9475f9be53bf45e7032add52681553679252f4f74de77831c95ea69f30"
+                + "2f0fd28867de058728455e3537680c86a001236e70c7680c78b4dc98942d233b968635a0debccb41"
+                + "fbc17ece7172631f5ab6d578d70eb0"));
+        SHORT_MSG_KAT_SIGNATURES.put("MD5withRSA", HexEncoding.decode(
+                "1e1edefc9a6a4e61fcef0d4b202cc2b53ab9043b1a0b21117d122d4c5399182998ec66608e1ab13513"
+                + "08fbb23f92d5d970f7fb1a0691f8d1e682ff4f5e394ef2dfcbdc2de5c2c33372aec9a0c7fba982c5"
+                + "c0f1a5f65677d9294d54a2e613cc0e5feb919135e883827da0e1c222bf31336afa63a837c57c0b70"
+                + "70ceb8a24492a42afa6750cc9fe3a9586aa15507a65410db973a4b26734624d323dc700928717789"
+                + "fb1f970d57326eef49e012fcebcfbbfd18fb4d6feff03587d0f2b0a556fe467437a44a2283ea5027"
+                + "6efda4fd427365687960e0c289c5853a7b300ff081511a2f52899e6f6a569b30e07adfd52e9d9d7e"
+                + "ab33999da0da1dd16d4e88bd980fcd"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA1withRSA", HexEncoding.decode(
+                "280977b4ee18cbe27d3e452c9b90174f5d81dd518018ce52ff1cd1e8d4d0626afca85be14a43fa3b76"
+                + "a80e818b4bc10abc62180fa15619d78be98ccd8fa642ea05355aa84f2924e041c2b594b1cf31d42b"
+                + "f11c78dd3cbb6cc2cbfe151792985e6e5cf73c2e600a38f31e26e84c3e4a434f67a625fefe712d17"
+                + "b34125ea91d333cfe1c4ac914b6c411b08e64700885325e07510c4f49ef3648252736f17d3ae7705"
+                + "0054ceb07ab04b5ecaa5fc4556328bad4f97eba37f9bf079506e0eb136c9eadf9e466ccb18d65b4d"
+                + "ef2ba3ca5c2f33354a2040dfb646423f96ba43d1d8f3dcf91c0c2c14e7958159d2ac3ebc0b6b87e6"
+                + "6efbdda046ce8a766fecc3f905d6ff"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA224withRSA", HexEncoding.decode(
+                "490af9e685ef44da9528d9271d00e09a3e688012bf3f63fd924a06cb4db747a28cdf924c2d51620165"
+                + "33985abf4b91d64c17ff7e2b4f0de5a28375dddf556cd9e5dcebd112f766f07cb867e8d5710ce79a"
+                + "1c3d5244cbd16618b0fedc2b9015d51a98d453747fb320b97995ea9579adbc8bf6042b2f4252cef1"
+                + "787207fefaf4b9c7212fe0ff8b22ae12ffc888f0a1e6923455577e82b58608dabc2acba05be693ff"
+                + "ae7da263d6c83cb13d59a083f177578d11030f8974bdb301f6135ecd5ec18dd68dc453c5963e94b6"
+                + "2d89bcda0ff63ac7394030f79b59139e1d51573f0d4a1e85d22502c9b0d29412f7eb277fb42fa4db"
+                + "18875baffa7719b700e4830edbcd6f"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA256withRSA", HexEncoding.decode(
+                "1f1adcd6edbf4c50777c932db6e99a577853fbc9c71c692e921291c5aa73eb0155e30c8d4f3aff828f"
+                + "2040c84e10b1ba729ccc23899650451022fcd3574df5454b01112adec5f01565b578bbc7c32810c9"
+                + "407106054ad8f4f640b589ddef264d028ad906536d61c8053ef0dba8e10ca2e30a9dd6ccc9a9ec3e"
+                + "76c10d36029820865b2d01095987af4a29369ffc6f70fa7e1de2b8e28f41894df4225cf966454096"
+                + "7fb7ecff443948c8a0ee6a1be51e0f8e8887ff512dbdc4fc81636e69ae698000ce3899c2ec999b68"
+                + "691adfb53092380264b27d91bd64561fee9d2e622919cf6b472fd764dc2065ae6a67df2c7b5ec855"
+                + "099bdb6bb104ee41fa129c9da99745"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA384withRSA", HexEncoding.decode(
+                "3b5e8baa62803569642fa8c3255249709c9f1d69bd31f7b531d5071c07cd9bac29273097666d96b2e3"
+                + "2db13529b6414be5aee0c8a90c3f3b2a5c815f37fac16a3527fa45903f847416ed218eee2fef5b87"
+                + "5f0c97576f58b3467e83497c1cdeea44d0ea151e9c4d27b85eef75d612b1fc16731859738e95bdf1"
+                + "2f2098ebd501d8493c66585e8545fb13d736f7dbbb530fb06f6f157cd10c332ca498b379336efdaf"
+                + "a8f940552da2dbb047c33e87f699068eaadd6d47c92a299f35483ba3ae09f7e52a205f202c1af997"
+                + "c9bdc40f423b3767292c7fcea3eaf338a76f9db07a53d7f8d084bf1ceac38ec0509e442b1283cd8f"
+                + "013c4c7a9189fe4ef9ab00c80cb470"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA512withRSA", HexEncoding.decode(
+                "23eb7577d2ffefed10780c2a26f79f64abe08203e900db2333413f30bbc81f800857857c8b0e02c3e8"
+                + "8fe3cf5514130d6216ef7c4a86b1012594c7cb07a293159b92bf40291224386a84e607e0a8389c8a"
+                + "a0c45cc553037517c52f61fe0ea51dba184e890db7d9517760724c038018330c0a9450c280430e6f"
+                + "9e4cdd4545c3f6684485cd6e27203735ff4be76420071920b18c54d98c0e3eb7ae7d1f01f5171ace"
+                + "87885c6185f66d947d51a441a756bc953458f7d3a1714226899562478ebf91ab18d8e7556a966661"
+                + "31de37bc2e399b366877f53c1d88f93c989aeb64a43f0f6cbc2a29587230f7e3e90ea18868d79584"
+                + "3e62b49f5df78e355b437ec2f882f9"));
+
+        // From Bouncy Castle
+        SHORT_MSG_KAT_SIGNATURES.put("SHA1withRSA/PSS", HexEncoding.decode(
+                "17e483781695067a25bc7cb204429a8754af36032038460e1938c28cd058025b14d2cffe5d3da39e76"
+                + "6542014e5419f1d4c4d7d8e3ebcd2221dde04d24bbbad657f6782b7a0fada3c3ea595bc21054b0ab"
+                + "d1eb1ada86276ed31dbcce58be7407cbbb924d595fbf44f2bb6e3eab92296076e291439107e67912"
+                + "b4fac3a27ff84af7cd2db1385a8340b2e49c7c2ec96a6b657a1641da80799cb88734cca35a2b3a2c"
+                + "4af832a34ac8d3134ccc8b61150dc1b64391888a3a84bdb5184b48e8509e8ba726ba8847e4ca0640"
+                + "ce615e3adf5248ce08adb6484f6f29caf6c65308ec6351d97369ae005a7c762f76f0ddc0becc3e45"
+                + "529aa9c8391473e392c9a60c2d0834"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA224withRSA/PSS", HexEncoding.decode(
+                "3b7641a49e7766ed879f2b0e33ceb3d935678a7deffbd855a97abf00a65c981814ac54a71150b2ffea"
+                + "d5db83aa96d0939267b3c5e2fcf958e9c6fdf7d90908e6139f7f330a16dc625d8268ffd324659f6c"
+                + "e36798ef3b71a92f1d2237e3ce1e281aacc1d5370ae63c9b75e7134ad15cca1410746bf259ac4519"
+                + "c407877503900ec8f3b71edce727e9d0275c9cd48385f89ce76ed17a2bf246578f183bb6577d6942"
+                + "2056c7d9145528fc8ca036926a9fafe819f37c1a4a0a69b17f3d4b0a116106f94a5d2a5f8ce6981c"
+                + "d6e5c2f858dcb0823e725fffe6be14ca882c81fa993bebda549fcf983eb7f8a87eccd545951dcdc9"
+                + "d8055ae4f4067de997cfd89952c905"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA256withRSA/PSS", HexEncoding.decode(
+                "6f0f744fa8e813b4c7caa0c395c1aa8aee0d61e621b4daae305c759b5b5972311ad691f8867821efba"
+                + "d57995cc8ff38f33393293e94e1c484e94de4816b0fd986f5710a02d80e62461cc6f87f1f3742268"
+                + "c28a54870f290d136aa629cbe00a1bf243fab1674c04cd5910a786b2ac5e71d9c6f4c41daa4c584d"
+                + "46ba7ee768d2d2559be587a7b2009f3b7497d556a0da8a8ae80ce91152c81ffba62720d36b699d1f"
+                + "157137ff7ee7239fc4baf611d01582346e201900f7a4f2617cdf574653e124fb895c6cb76d4ed5a8"
+                + "aca97d1e408e8011eba649d5617bae8b27c1b946dcff7b29151d8632ad128f22907e8b83b9149e16"
+                + "fbb9e9b87600a2f90c1fd6dc164c52"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA384withRSA/PSS", HexEncoding.decode(
+                "8e57992362ad4b0487a707b2f8811d953f5aaf800978859981e7dcddad6f9f411fb162859115577c53"
+                + "7a3524e26bf069508185848d6e29e7da1f9660a49771533e43853e02232314afd2928a1ff1824345"
+                + "a5a90309a59d213ff6a4d04520f95a976342e6ac529ec6a6821157f4fee3bdae30d836d3ab44386d"
+                + "3914e6aacd6a6a63e1d63b4d9bfb93b343b6c1f28d60042ffbe1e46fb692a381456e84b3328dbcae"
+                + "ed6fc577cb1c5f86a38c5c34d439eeee7e798edc9f2bcd4fc217b1630e45b8df67def2c2cdb9fea0"
+                + "5d67aa6cce6e9a72e9a114e2e620a54c05755e32685ffc7e50487c3cd00888c09492fad8c461c338"
+                + "e7d099b275deaf184b7d6689385f7c"));
+        SHORT_MSG_KAT_SIGNATURES.put("SHA512withRSA/PSS", HexEncoding.decode(
+                "7a40f9f2797beda0702df0520c7138269295a0f0328aab4eba123ebf178ea4abc745ed42d3b175dc70"
+                + "c8dcc98f46f2234b392dbb3e939f30888715c4fbb47fbb5bb7c0557c140c579f48226710e5b3da0d"
+                + "9511337cde5626df586b4004100dd45490e5f8ae23307b5d1054c97e9ef58f9c385ca55b6db4f58d"
+                + "2e19bc8ca9d8c2b4922fb3325b6fb61fc40a359e9196aa9388845b136d2790d71410e20371dcf0a7"
+                + "0425ee1854c5c3d7de976b28de0ee9b1048ed99b2a957edc97466cc4c87e36224fd323605228f61a"
+                + "1aad30253b0698f9a358491138027d325d46bdfdf72171c57a2dab0a9cddaad8e170b8275c172e42"
+                + "33b29ed81c0f4de9fe9f0670106aad"));
+    }
+
+    private static final Map<String, byte[]> LONG_MSG_KAT_SIGNATURES =
+            new TreeMap<String, byte[]>(String.CASE_INSENSITIVE_ORDER);
+    static {
+        // From RI
+        LONG_MSG_KAT_SIGNATURES.put("NONEwithECDSA", HexEncoding.decode(
+                "304502206e4039608a66ce118821eeca3e2af7f530f51d1ce8089685a13f49010e3cd58b02210083a5"
+                + "fe62a171f1b1d775fad712128a223d6b63336e0248783652474221cb3193"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA1withECDSA", HexEncoding.decode(
+                "3044022075f09bb5c87d883c088ca2ad263bbe1754ab614f727465bc43695d3521eaccf80220460e4e"
+                + "32421e6f4398cd9b7fbb31a1d1f2961f26b9783620f6413f0e6f7efb84"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA224withECDSA", HexEncoding.decode(
+                "3045022100d6b24250b7d3cbd329913705f4990cfd1000f338f7332a44f07d7731bd8e1ff602200565"
+                + "0951e14d0d21c4344a449843ef65ac3a3f831dc7f304c0fa068c996f7d34"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA256withECDSA", HexEncoding.decode(
+                "30440220501946a2c373e8da19b36e3c7718e3f2f2f16395d5026ac4fbbc7b2d53f9f21a0220347d7a"
+                + "46685282f308bacd5fb25ae92b351228ea39082784789696580f27eed1"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA384withECDSA", HexEncoding.decode(
+                "30450220576836de4ab94a869e867b2360a71dc5a0b3351ea1c896b163206db7c3507dc2022100c1a6"
+                + "719052a175e023bca7f3b9bb7a379fc6b51864cb28a195076d2f3c79ed2e"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA512withECDSA", HexEncoding.decode(
+                "304402204ca46bac4e43e8694d1af38854c96024a4e9bcc55c6904c1f8fea0d1927f69f7022054662e"
+                + "84b4d16b9f7e8164f4896212dec3c7c1e7fd108f69b0dff5bc15399eeb"));
+
+        // From RI
+        LONG_MSG_KAT_SIGNATURES.put("MD5withRSA", HexEncoding.decode(
+                "7040f3e0d95f4d22719d26e5e684dbcd5ed52ab4a7c5aa51b938b2c060c79eb600f9c9771c2fcda7e3"
+                + "55e7c7b5e2ba9fe9a2a3621881c0fe51702781ffcde6ce7013218c04bb05988346c2bed99afb97a8"
+                + "113fb50697adf93791c9129e938040f91178e35d6f323cfa515ea6d2112e8cce1302201b51333794"
+                + "4a5c425cecc8181842ace89163d84784599ea688060ad0d61ac92b673feabe01ae5e6b85d8b5e8f0"
+                + "519aea3c29781e82df9153404d027d75df8370658898ed348acf4e13fd8f79c8a545881fbbf585e1"
+                + "c666be3805e808819e2cc730379f35a207f9e0e646c7ab6d598c75b1901f0c5ca7099e34f7f01579"
+                + "3b57dfb5c2a32e8423bfed6215f9d0"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA1withRSA", HexEncoding.decode(
+                "187d7689206c9dd03861009c6cb62c7752fd2bbc354f0bea4e76059fe582744c80027175112a3df4b6"
+                + "3b4a5626ed3051192e3c9b6d906497472f6df81171064b59114ff5d7c60f66943549634461cfadd8"
+                + "a033cba2b8781fb7936ea1ca0043da119856a21e533afa999f095cf87604bb33a14e8f82fab01998"
+                + "9ef3133e8069708670645ddd5cdc86bbe19fbf672b409fb6d7cae2f913814cd3dc8d5ae8e4037ccf"
+                + "4a3ef97db8c8a08516716258c4b767607c51dfb289d90af014d3cfc64dbadb2135ed59728b78fda0"
+                + "823fe7e68e84280c283d21ab660364a9bf035afa9a7262bade87057a63aa1d7e2c09bb9dd037bcbd"
+                + "7b98356793bc32be81623833c6ab62"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA224withRSA", HexEncoding.decode(
+                "31ff68ddfafcf3ff6e651c93649bf9cc06f4138493317606d8676a8676f9d9f3a1d5e418358f79d143"
+                + "a922a3cfc5e1ad6765dc829b556c9019a6d9389144cc6a7571011c024c0514891970508dac5f0d26"
+                + "f26b536cf3e4511b5e72cd9f60590b387d8a351a9f28839a1c5be5272cb75a9062aa313f3d095074"
+                + "6d0a21d4f8c9a94d3bb4715c3ef0207cf1335653161a8f78972329f3ec2fa5cfe05318221cb1f535"
+                + "8151dde5410f6c36f32287a2d5e76bf36134d7103fc6810a1bb8627de37d6b9efde347242d08b0b6"
+                + "2b1d73bacd243ccc8546536080b42a82b7162afeb4151315746a14b64e45226c9f5b35cf1577fc6b"
+                + "f5c882b71deb7f0e375db5c0196446"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA256withRSA", HexEncoding.decode(
+                "529c70877dedf3eb1abda98a2f2b0fc899e1edece70da79f8f8bbceb98de5c85263bef2ef8a7322624"
+                + "5ed2767045ea6965f35cb53e6ac1d6c62e8007a79962507d3e01c77d4e96674344438519adae67d9"
+                + "6357da5c4527969c939fd86f3b8685338c2be4bf6f1f85527b11fcaa4708f925e8bb9b877bda179b"
+                + "d1b45153ef22834cf593ecc5b6eca3deddbe5d05894e4e5707d71bc35ea879ccb6e8ffc32e0cdc5e"
+                + "88a30eef7a608d9ea80b5cefec2aa493a3b1354ad20e88ab1f8bfda3bd9961e10f0736d1bc090d57"
+                + "b93fbce3e6e2fc99e67c7b466188d1615b4150c206472e48a9253b7549cebf6c7cbb558b54e10b73"
+                + "c8b1747c18d1890a24d0a835ee710a"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA384withRSA", HexEncoding.decode(
+                "5dd3553bc594c541937dac9a8ac119407712da7564816bcdc0ca4e14bc6059b9f9bd72e99be8a3df3e"
+                + "0a3c4e8ed643db9ed528b43a396dba470ad3307815bd7c75fa5b08775a378cc4203341379087dcb3"
+                + "62a5e9f5c979744e4498a6aafd1b1a8069caf4ef437f2743754861fcc96d67a0f1dd3397bb65ede3"
+                + "18d2b3628eb2c3ec5db8a3e21fbbe2629f1030641e420963abc4da99e24dd497337c8149a52d97da"
+                + "7176c0767d72e18f8c9a49e6808509837f719fd16ba27b19a2b32bd19b9b14818e0b9be81062be77"
+                + "4fb1b3105a1528170822391915a5cd12b8e79aaab7943c34094da4c4f8d56f52177db953d3bf7846"
+                + "f0e5f22f2311054a1daba4fec6b589"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA512withRSA", HexEncoding.decode(
+                "971d6350337866fbcb48c49446c50cac1995b822cfec8f2a3e2c8206158a2ddfc8fc7b38f5174b3288"
+                + "91489e7b379829bac5e48cd41e9713ea7e2dc9c61cf90d255387d31818d2f161ec5c3a977b4ce121"
+                + "62fb11ede30d1e63c0fbba8a4094e6ad39e64176a033e7130bbed71a67ff1713b45f0bedeb1ee532"
+                + "15690f169452c061cd7d15e71cc754a2f233f5647af8373d2b583e98e4242c0a0581e0ce2b22e15a"
+                + "443b0ff23d516ed39664f8b8ab5ca98a44af500407941fae97f37cb1becbcbff453608cb94a176d9"
+                + "e702947fff80bc8d1e9bcdef2b7bbe681e15327cee50a72649aed0d730df7b3c9c31b165416d9c9f"
+                + "1fcb04edbf96514f5758b9e90ebc0e"));
+
+        // From Bouncy Castle
+        LONG_MSG_KAT_SIGNATURES.put("SHA1withRSA/PSS", HexEncoding.decode(
+                "54a2050b22f6182b65d790da80ea16bfbc34b0c7e564d1a3ce4450e9b7785d9eaa14814dee8699977a"
+                + "e8da5cfb3c55c9a623ca55abcc0ef4b3b515ce31d49a78db442f9db270d35a179baf71057fe8d6d2"
+                + "d3f7e4fd5f5c80e11dc059c72a1a0373f527d88089c230525f895ee19e45f5547572083418c9e542"
+                + "5ff44e407500d1c49159484f38e4b00523c2fa45b7b9b38a2c1ad676b36f02a06db6fca52bd79ba1"
+                + "94d5062f5035a12a1f026ac216789844a5da0caa4d481386a12ca635c06b877515ce3782d9189d87"
+                + "d1ff5ec6ec7c39437071c8db7d1c2702205da4cfb01805ca7fec5595dba2234602ca5347d30538cb"
+                + "4b5286c151609afcca890a6276d5e8"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA224withRSA/PSS", HexEncoding.decode(
+                "7e95c1e4f700ceaf9ce72fd3f9f245ba80f2e1341341c49521779c8a79004f9c534297441330b9df36"
+                + "bb23467eb560e5e5538612cecc27953336a0d4d8044d5a80f6bcef5299830215258c574d271ea6cd"
+                + "7117c2723189385435b0f06951ff3d6a700b23bc7ed3298cfb6aa65e8f540717d57f8b55290a4862"
+                + "034d9f73e8d9cb6ae7fa55a8b4c127535b5690122d6405cb0c9a313808327cfd4fb763eae875acd1"
+                + "b60e1920ecf1116102cc5f7d776ed88e666962f759258d6f5454c29cb99b8f9ccad07d209671b607"
+                + "014d19009e392bfb08247acf7f354458dc51196d84b492798dd829b7300c7591d42c58f21bd2c3d1"
+                + "e5ce0a0d3e0aa8aa4b090b6a619fc6"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA256withRSA/PSS", HexEncoding.decode(
+                "5a8c0ae593a6714207b3ad83398b38b93da18cfda73139ea9f02c88a989368ae6901357194a873dd2e"
+                + "8cd1bb86d1f81fbc8bf725538dc2ad60759f8caab6a98a6baa6014874a92d4b92ed72e73f2721ba2"
+                + "86e545924860d27210b53f9308c4fec622fdfca7dd6d51a5b092184114e9dcf57636cdabaca17b49"
+                + "70cd5e93ce12c30af6d09d6964c5ad173095ea000529620d94a25b4cc977deefd25cc810a7b11cd5"
+                + "e5b71c9276b0bd33c53db01304b359a4a88f3fe8bc3335669f7609b0f6da17e49ad87f38468fa2c6"
+                + "8134ba6df407207559355b6e486a745009931796ab0567c9bd61788073aa00113b324fa25bd32b4d"
+                + "3521e98e0b4905c6dce30d70387a2e"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA384withRSA/PSS", HexEncoding.decode(
+                "7913f13dc399adb07cd96c1bb484f999d047efcd96501c92477d2234a1da94db9c6fd65a8031bd3040"
+                + "82d90ef4a4f388e670795d144ef72a160583d4a2c805415542fa16ffd8760d2f28bdc82f63db0900"
+                + "a3554bc9175dafa1899249abd49591216ba2965a4862d0f59d8b8c8d1042ed7ac43a3a15650d578a"
+                + "2ea53696e462f757b326b7f0f7610fb9934aee7d954a45ca03ef66464a5611433e1224d05f783cd1"
+                + "935eff90015140cb35e15f2bbf491a0d6342ccef57e453f3462412c5ff4dfdc44527ea76c6b05b1d"
+                + "1330869aec1b2f41e7d975eba6b056e7c2f75dd73b1eff6d853b9507f410279b02f9244b656a1aca"
+                + "befcc5e1167df3a49c4a7d8479c30f"));
+        LONG_MSG_KAT_SIGNATURES.put("SHA512withRSA/PSS", HexEncoding.decode(
+                "43ffefe9c96014312679a2e3803eb7c58a2a4ab8bb659c12fec7fb574c82aed673e21ed86ac309cf6c"
+                + "e567e47b7c6c83dcd72e3ee946067c2004689420528174d028e3d32b2b306bcbcb6a9c8e8b83918f"
+                + "7415d792f9d6417769def3316ed61898443d3ffa4dc160e5b5ecf4a11a9dfed6b4a7aa65f0f2c653"
+                + "4f7e514aed73be441609ffca29207b4ced249058543fd6e13a02ef42babe2cdf4aaba66b42e9d47f"
+                + "c79b4ed54fbc28d9d732f2e468d43f0ca1de6fd5312fad2c4e3eaf3e9586bca6a8bab24b4dfab8b3"
+                + "9a4057c8ed27024b61b425036bea5e23689cd9db2450be47ec2c30bb6707740c70a53b3e7a1c7ecf"
+                + "f04e3de1460e60e9be7a42b1ddff0c"));
+    }
+
+    private static final long DAY_IN_MILLIS = TestUtils.DAY_IN_MILLIS;
+
+    public void testAlgorithmList() {
+        // Assert that Android Keystore Provider exposes exactly the expected signature algorithms.
+        // We don't care whether the algorithms are exposed via aliases, as long as the canonical
+        // names of algorithms are accepted.
+        // If the Provider exposes extraneous algorithms, it'll be caught because it'll have to
+        // expose at least one Service for such an algorithm, and this Service's algorithm will
+        // not be in the expected set.
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        Set<Service> services = provider.getServices();
+        Set<String> actualSigAlgsLowerCase = new HashSet<String>();
+        Set<String> expectedSigAlgsLowerCase = new HashSet<String>(
+                Arrays.asList(TestUtils.toLowerCase(EXPECTED_SIGNATURE_ALGORITHMS)));
+        for (Service service : services) {
+            if ("Signature".equalsIgnoreCase(service.getType())) {
+                String algLowerCase = service.getAlgorithm().toLowerCase(Locale.US);
+                if (!expectedSigAlgsLowerCase.contains(algLowerCase)) {
+                    // Unexpected algorithm -- check whether it's an alias for an expected one
+                    String canonicalAlgorithm =
+                            SIG_ALG_TO_CANONICAL_NAME_CASE_INSENSITIVE.get(algLowerCase);
+                    if (canonicalAlgorithm != null) {
+                        // Use the canonical name instead
+                        algLowerCase = canonicalAlgorithm.toLowerCase();
+                    }
+                }
+                actualSigAlgsLowerCase.add(algLowerCase);
+            }
+        }
+
+        TestUtils.assertContentsInAnyOrder(actualSigAlgsLowerCase,
+                expectedSigAlgsLowerCase.toArray(new String[0]));
+    }
+
+    public void testAndroidKeyStoreKeysHandledByAndroidKeyStoreProviderWhenSigning()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyPair keyPair = importDefaultKatKeyPair(sigAlgorithm).getKeystoreBackedKeyPair();
+                Signature signature = Signature.getInstance(sigAlgorithm);
+                signature.initSign(keyPair.getPrivate());
+                assertSame(provider, signature.getProvider());
+            } catch (Throwable e) {
+                throw new RuntimeException(sigAlgorithm + " failed", e);
+            }
+        }
+    }
+
+    public void testAndroidKeyStorePublicKeysAcceptedByHighestPriorityProviderWhenVerifying()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyPair keyPair = importDefaultKatKeyPair(sigAlgorithm).getKeystoreBackedKeyPair();
+                Signature signature = Signature.getInstance(sigAlgorithm);
+                signature.initVerify(keyPair.getPublic());
+            } catch (Throwable e) {
+                throw new RuntimeException(sigAlgorithm + " failed", e);
+            }
+        }
+    }
+
+    public void testValidSignatureGeneratedForEmptyMessage()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) {
+                if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm(
+                        sigAlgorithm, key.getOriginalSigningKey())) {
+                    continue;
+                }
+                try {
+                    KeyPair keyPair = key.getKeystoreBackedKeyPair();
+
+                    // Generate a signature
+                    Signature signature = Signature.getInstance(sigAlgorithm, provider);
+                    signature.initSign(keyPair.getPrivate());
+                    byte[] sigBytes = signature.sign();
+
+                    // Assert that it verifies using our own Provider
+                    signature.initVerify(keyPair.getPublic());
+                    assertTrue(signature.verify(sigBytes));
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + sigAlgorithm + " with key " + key.getAlias(), e);
+                }
+            }
+        }
+    }
+
+    public void testEmptySignatureDoesNotVerify()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) {
+                if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm(
+                        sigAlgorithm, key.getOriginalSigningKey())) {
+                    continue;
+                }
+                try {
+                    KeyPair keyPair = key.getKeystoreBackedKeyPair();
+                    Signature signature = Signature.getInstance(sigAlgorithm, provider);
+                    signature.initVerify(keyPair.getPublic());
+                    assertFalse(signature.verify(EmptyArray.BYTE));
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + sigAlgorithm + " with key " + key.getAlias(), e);
+                }
+            }
+        }
+    }
+
+    public void testSignatureGeneratedByAndroidKeyStoreVerifiesByAndroidKeyStore()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) {
+                if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm(
+                        sigAlgorithm, key.getOriginalSigningKey())) {
+                    continue;
+                }
+                try {
+                    KeyPair keyPair = key.getKeystoreBackedKeyPair();
+
+                    // Generate a signature
+                    Signature signature = Signature.getInstance(sigAlgorithm, provider);
+                    signature.initSign(keyPair.getPrivate());
+                    byte[] message = "This is a test".getBytes("UTF-8");
+                    signature.update(message);
+                    byte[] sigBytes = signature.sign();
+
+                    // Assert that it verifies using our own Provider
+                    assertSignatureVerifiesOneShot(
+                            sigAlgorithm, provider, keyPair.getPublic(), message, sigBytes);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + sigAlgorithm + " with key " + key.getAlias(), e);
+                }
+            }
+        }
+    }
+
+    public void testSignatureGeneratedByAndroidKeyStoreVerifiesByHighestPriorityProvider()
+            throws Exception {
+        Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(keystoreProvider);
+        for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) {
+                if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm(
+                        sigAlgorithm, key.getOriginalSigningKey())) {
+                    continue;
+                }
+                Provider verificationProvider = null;
+                try {
+                    PrivateKey keystorePrivateKey = key.getKeystoreBackedKeyPair().getPrivate();
+
+                    // Generate a signature
+                    Signature signature = Signature.getInstance(sigAlgorithm, keystoreProvider);
+                    signature.initSign(keystorePrivateKey);
+                    byte[] message = "This is a test".getBytes("UTF-8");
+                    signature.update(message);
+                    byte[] sigBytes = signature.sign();
+
+                    // Assert that it verifies using whatever Provider is chosen by JCA by default
+                    // for this signature algorithm and public key.
+                    PublicKey publicKey = key.getOriginalKeyPair().getPublic();
+                    try {
+                        signature = Signature.getInstance(sigAlgorithm);
+                        signature.initVerify(publicKey);
+                        verificationProvider = signature.getProvider();
+                    } catch (InvalidKeyException e) {
+                        // No providers support verifying signatures using this algorithm and key.
+                        continue;
+                    }
+                    assertSignatureVerifiesOneShot(
+                            sigAlgorithm, verificationProvider, publicKey, message, sigBytes);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + sigAlgorithm + " with key " + key.getAlias()
+                                    + ", verification provider: " + verificationProvider,
+                            e);
+                }
+            }
+        }
+    }
+
+    public void testSignatureGeneratedByHighestPriorityProviderVerifiesByAndroidKeyStore()
+            throws Exception {
+
+        Provider keystoreProvider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(keystoreProvider);
+        for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) {
+                if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm(
+                        sigAlgorithm, key.getOriginalSigningKey())) {
+                    continue;
+                }
+                Provider signingProvider = null;
+                try {
+                    PrivateKey privateKey = key.getOriginalKeyPair().getPrivate();
+
+                    // Generate a signature
+                    Signature signature;
+                    try {
+                        signature = Signature.getInstance(sigAlgorithm);
+                        signature.initSign(privateKey);
+                        signingProvider = signature.getProvider();
+                    } catch (InvalidKeyException e) {
+                        // No providers support signing using this algorithm and key.
+                        continue;
+                    }
+                    byte[] message = "This is a test".getBytes("UTF-8");
+                    signature.update(message);
+                    byte[] sigBytes = signature.sign();
+
+                    // Assert that the signature verifies using the Android Keystore provider.
+                    PublicKey keystorePublicKey = key.getKeystoreBackedKeyPair().getPublic();
+                    assertSignatureVerifiesOneShot(
+                            sigAlgorithm, keystoreProvider, keystorePublicKey, message, sigBytes);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + sigAlgorithm + " with key " + key.getAlias()
+                                    + ", signing provider: " + signingProvider,
+                            e);
+                }
+            }
+        }
+    }
+
+    // TODO: Re-enable this test once Signature.initSign passes SecureRandom to SPI (Bug 22485587).
+    public void DISABLED_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.
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+
+        CountingSecureRandom rng = new CountingSecureRandom();
+        for (String sigAlgorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            for (ImportedKey key : importKatKeyPairsForSigning(getContext(), sigAlgorithm)) {
+                if (!TestUtils.isKeyLongEnoughForSignatureAlgorithm(
+                        sigAlgorithm, key.getOriginalSigningKey())) {
+                    continue;
+                }
+                try {
+                    KeyPair keyPair = key.getKeystoreBackedKeyPair();
+                    PrivateKey privateKey = keyPair.getPrivate();
+                    Signature signature = Signature.getInstance(sigAlgorithm, provider);
+
+                    // Signature.initSign should not consume entropy.
+                    rng.resetCounters();
+                    signature.initSign(privateKey, rng);
+                    assertEquals(0, rng.getOutputSizeBytes());
+
+                    // Signature.update should not consume entropy.
+                    byte[] message = "This is a test message".getBytes("UTF-8");
+                    rng.resetCounters();
+                    signature.update(message);
+                    assertEquals(0, rng.getOutputSizeBytes());
+
+                    // Signature.sign may consume entropy.
+                    rng.resetCounters();
+                    signature.sign();
+                    int expectedEntropyBytesConsumed;
+                    String algorithmUpperCase = sigAlgorithm.toUpperCase(Locale.US);
+                    if (algorithmUpperCase.endsWith("WITHECDSA")) {
+                        expectedEntropyBytesConsumed =
+                                (TestUtils.getKeySizeBits(privateKey) + 7) / 8;
+                    } else if (algorithmUpperCase.endsWith("WITHRSA")) {
+                        expectedEntropyBytesConsumed = 0;
+                    } else if (algorithmUpperCase.endsWith("WITHRSA/PSS")) {
+                        expectedEntropyBytesConsumed = 20; // salt length
+                    } else {
+                        throw new RuntimeException("Unsupported algorithm: " + sigAlgorithm);
+                    }
+                    assertEquals(expectedEntropyBytesConsumed, rng.getOutputSizeBytes());
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + sigAlgorithm + " with key " + key.getAlias(), e);
+                }
+            }
+        }
+    }
+
+    public void testSmallMsgKat() throws Exception {
+        byte[] message = SHORT_MSG_KAT_MESSAGE;
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                byte[] goodSigBytes = SHORT_MSG_KAT_SIGNATURES.get(algorithm);
+                assertNotNull(goodSigBytes);
+                KeyPair keyPair = importDefaultKatKeyPair(algorithm).getKeystoreBackedKeyPair();
+                // Assert that AndroidKeyStore provider can verify the known good signature.
+                assertSignatureVerifiesOneShot(
+                        algorithm, provider, keyPair.getPublic(), message, goodSigBytes);
+                assertSignatureVerifiesFedOneByteAtATime(
+                        algorithm, provider, keyPair.getPublic(), message, goodSigBytes);
+                assertSignatureVerifiesFedUsingFixedSizeChunks(
+                        algorithm, provider, keyPair.getPublic(), message, goodSigBytes, 3);
+
+                byte[] messageWithBitFlip = message.clone();
+                messageWithBitFlip[messageWithBitFlip.length / 2] ^= 1;
+                assertSignatureDoesNotVerifyOneShot(
+                        algorithm, provider, keyPair.getPublic(), messageWithBitFlip, goodSigBytes);
+
+                byte[] goodSigWithBitFlip = goodSigBytes.clone();
+                goodSigWithBitFlip[goodSigWithBitFlip.length / 2] ^= 1;
+                assertSignatureDoesNotVerifyOneShot(
+                        algorithm, provider, keyPair.getPublic(), message, goodSigWithBitFlip);
+
+                // Sign the message in one go
+                Signature signature = Signature.getInstance(algorithm, provider);
+                signature.initSign(keyPair.getPrivate());
+                signature.update(message);
+                byte[] generatedSigBytes = signature.sign();
+                boolean deterministicSignatureScheme =
+                        algorithm.toLowerCase().endsWith("withrsa");
+                if (deterministicSignatureScheme) {
+                    MoreAsserts.assertEquals(goodSigBytes, generatedSigBytes);
+                } else {
+                    if (Math.abs(goodSigBytes.length - generatedSigBytes.length) > 2) {
+                        fail("Generated signature expected to be between "
+                                + (goodSigBytes.length - 2) + " and "
+                                + (goodSigBytes.length + 2) + " bytes long, but was: "
+                                + generatedSigBytes.length + " bytes: "
+                                + HexEncoding.encode(generatedSigBytes));
+                    }
+
+                    // Assert that the signature verifies using our own Provider
+                    assertSignatureVerifiesOneShot(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes);
+                    assertSignatureVerifiesFedOneByteAtATime(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes);
+                    assertSignatureVerifiesFedUsingFixedSizeChunks(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes,
+                            3);
+
+                    // Assert that the signature verifies using whatever Provider is chosen by JCA
+                    // by default for this signature algorithm and public key.
+                    assertSignatureVerifiesOneShot(
+                            algorithm, keyPair.getPublic(), message, generatedSigBytes);
+                }
+
+                // Sign the message by feeding it into the Signature one byte at a time
+                signature = Signature.getInstance(signature.getAlgorithm(), provider);
+                signature.initSign(keyPair.getPrivate());
+                for (int i = 0; i < message.length; i++) {
+                    signature.update(message[i]);
+                }
+                generatedSigBytes = signature.sign();
+                if (deterministicSignatureScheme) {
+                    MoreAsserts.assertEquals(goodSigBytes, generatedSigBytes);
+                } else {
+                    if (Math.abs(goodSigBytes.length - generatedSigBytes.length) > 2) {
+                        fail("Generated signature expected to be between "
+                                + (goodSigBytes.length - 2) + " and "
+                                + (goodSigBytes.length + 2) + " bytes long, but was: "
+                                + generatedSigBytes.length + " bytes: "
+                                + HexEncoding.encode(generatedSigBytes));
+                    }
+                    // Assert that the signature verifies using our own Provider
+                    assertSignatureVerifiesOneShot(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes);
+                    assertSignatureVerifiesFedOneByteAtATime(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes);
+                    assertSignatureVerifiesFedUsingFixedSizeChunks(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes,
+                            3);
+
+                    // Assert that the signature verifies using whatever Provider is chosen by JCA
+                    // by default for this signature algorithm and public key.
+                    assertSignatureVerifiesOneShot(
+                            algorithm, keyPair.getPublic(), message, generatedSigBytes);
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testLongMsgKat() throws Exception {
+        byte[] message = TestUtils.generateLargeKatMsg(LONG_MSG_KAT_SEED, LONG_MSG_KAT_SIZE_BYTES);
+
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyPair keyPair = importDefaultKatKeyPair(algorithm).getKeystoreBackedKeyPair();
+                String digest = TestUtils.getSignatureAlgorithmDigest(algorithm);
+                String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(algorithm);
+                if ((KeyProperties.DIGEST_NONE.equalsIgnoreCase(digest))
+                        && (!KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm))) {
+                    // This algorithm does not accept large messages
+                    Signature signature = Signature.getInstance(algorithm, provider);
+                    signature.initSign(keyPair.getPrivate());
+                    try {
+                        signature.update(message);
+                        byte[] sigBytes = signature.sign();
+                        fail("Unexpectedly generated signature (" + sigBytes.length + "): "
+                                + HexEncoding.encode(sigBytes));
+                    } catch (SignatureException expected) {}
+
+                    // Bogus signature generated using SHA-256 digest -- shouldn't because the
+                    // message is too long (and should not be digested/hashed) and because the
+                    // signature uses the wrong digest/hash.
+                    byte[] sigBytes = SHORT_MSG_KAT_SIGNATURES.get(
+                            "SHA256" + algorithm.substring("NONE".length()));
+                    assertNotNull(sigBytes);
+                    signature = Signature.getInstance(algorithm, provider);
+                    signature.initVerify(keyPair.getPublic());
+                    try {
+                        signature.update(message);
+                        signature.verify(sigBytes);
+                        fail();
+                    } catch (SignatureException expected) {}
+                    continue;
+                }
+
+                byte[] goodSigBytes = LONG_MSG_KAT_SIGNATURES.get(algorithm);
+                assertNotNull(goodSigBytes);
+
+                // Assert that AndroidKeyStore provider can verify the known good signature.
+                assertSignatureVerifiesOneShot(
+                        algorithm, provider, keyPair.getPublic(), message, goodSigBytes);
+                assertSignatureVerifiesFedUsingFixedSizeChunks(
+                        algorithm, provider, keyPair.getPublic(), message, goodSigBytes, 718871);
+
+                // Sign the message in one go
+                Signature signature = Signature.getInstance(algorithm, provider);
+                signature.initSign(keyPair.getPrivate());
+                signature.update(message);
+                byte[] generatedSigBytes = signature.sign();
+                String paddingScheme = TestUtils.getSignatureAlgorithmPadding(algorithm);
+                boolean deterministicSignatureScheme =
+                        KeyProperties.SIGNATURE_PADDING_RSA_PKCS1.equalsIgnoreCase(paddingScheme);
+                if (deterministicSignatureScheme) {
+                    MoreAsserts.assertEquals(goodSigBytes, generatedSigBytes);
+                } else {
+                    if (Math.abs(goodSigBytes.length - generatedSigBytes.length) > 2) {
+                        fail("Generated signature expected to be between "
+                                + (goodSigBytes.length - 2) + " and "
+                                + (goodSigBytes.length + 2) + " bytes long, but was: "
+                                + generatedSigBytes.length + " bytes: "
+                                + HexEncoding.encode(generatedSigBytes));
+                    }
+
+                    // Assert that the signature verifies using our own Provider
+                    assertSignatureVerifiesOneShot(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes);
+                    assertSignatureVerifiesFedUsingFixedSizeChunks(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes,
+                            718871);
+
+                    // Assert that the signature verifies using whatever Provider is chosen by JCA
+                    // by default for this signature algorithm and public key.
+                    assertSignatureVerifiesOneShot(
+                            algorithm, keyPair.getPublic(), message, generatedSigBytes);
+                }
+
+                // Sign the message by feeding it into the Signature one byte at a time
+                generatedSigBytes = generateSignatureFedUsingFixedSizeChunks(
+                        algorithm, provider, keyPair.getPrivate(), message, 444307);
+                if (deterministicSignatureScheme) {
+                    MoreAsserts.assertEquals(goodSigBytes, generatedSigBytes);
+                } else {
+                    if (Math.abs(goodSigBytes.length - generatedSigBytes.length) > 2) {
+                        fail("Generated signature expected to be between "
+                                + (goodSigBytes.length - 2) + " and "
+                                + (goodSigBytes.length + 2) + " bytes long, but was: "
+                                + generatedSigBytes.length + " bytes: "
+                                + HexEncoding.encode(generatedSigBytes));
+                    }
+                    // Assert that the signature verifies using our own Provider
+                    assertSignatureVerifiesOneShot(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes);
+                    assertSignatureVerifiesFedUsingFixedSizeChunks(
+                            algorithm, provider, keyPair.getPublic(), message, generatedSigBytes,
+                            718871);
+
+                    // Assert that the signature verifies using whatever Provider is chosen by JCA
+                    // by default for this signature algorithm and public key.
+                    assertSignatureVerifiesOneShot(
+                            algorithm, keyPair.getPublic(), message, generatedSigBytes);
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitVerifySucceedsDespiteMissingAuthorizations() throws Exception {
+        KeyProtection spec = new KeyProtection.Builder(0).build();
+
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                assertInitVerifySucceeds(algorithm, spec);
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitSignFailsWhenNotAuthorizedToSign() throws Exception {
+        int badPurposes = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT
+                | KeyProperties.PURPOSE_VERIFY;
+
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm);
+                assertInitSignSucceeds(algorithm, good);
+                assertInitSignThrowsInvalidKeyException(algorithm,
+                        TestUtils.buildUpon(good, badPurposes).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitVerifyIgnoresThatNotAuthorizedToVerify() throws Exception {
+        int badPurposes = KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT
+                | KeyProperties.PURPOSE_SIGN;
+
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm);
+                assertInitVerifySucceeds(algorithm, good);
+                assertInitVerifySucceeds(algorithm,
+                        TestUtils.buildUpon(good, badPurposes).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitSignFailsWhenDigestNotAuthorized() throws Exception {
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm);
+                assertInitSignSucceeds(algorithm, good);
+
+                String digest = TestUtils.getSignatureAlgorithmDigest(algorithm);
+                String badDigest =
+                        (KeyProperties.DIGEST_SHA256.equalsIgnoreCase(digest))
+                        ? KeyProperties.DIGEST_SHA384 : KeyProperties.DIGEST_SHA256;
+                assertInitSignThrowsInvalidKeyException(algorithm,
+                        TestUtils.buildUpon(good).setDigests(badDigest).build());
+
+                // Check that digest NONE is not treated as ANY.
+                if (!KeyProperties.DIGEST_NONE.equalsIgnoreCase(digest)) {
+                    assertInitSignThrowsInvalidKeyException(algorithm,
+                            TestUtils.buildUpon(good)
+                                    .setDigests(KeyProperties.DIGEST_NONE)
+                                    .build());
+                }
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitVerifyIgnoresThatDigestNotAuthorized() throws Exception {
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm);
+                assertInitVerifySucceeds(algorithm, good);
+
+                String digest = TestUtils.getSignatureAlgorithmDigest(algorithm);
+                String badDigest =
+                        (KeyProperties.DIGEST_SHA256.equalsIgnoreCase(digest))
+                        ? KeyProperties.DIGEST_SHA384 : KeyProperties.DIGEST_SHA256;
+                assertInitVerifySucceeds(algorithm,
+                        TestUtils.buildUpon(good).setDigests(badDigest).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitSignFailsWhenPaddingNotAuthorized() throws Exception {
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                String paddingScheme = TestUtils.getSignatureAlgorithmPadding(algorithm);
+                String badPaddingScheme;
+                if (paddingScheme == null) {
+                    // No padding scheme used by this algorithm -- ignore.
+                    continue;
+                } else if (KeyProperties.SIGNATURE_PADDING_RSA_PKCS1.equalsIgnoreCase(
+                        paddingScheme)) {
+                    badPaddingScheme = KeyProperties.SIGNATURE_PADDING_RSA_PSS;
+                } else if (KeyProperties.SIGNATURE_PADDING_RSA_PSS.equalsIgnoreCase(
+                        paddingScheme)) {
+                    badPaddingScheme = KeyProperties.SIGNATURE_PADDING_RSA_PKCS1;
+                } else {
+                    throw new IllegalArgumentException("Unsupported algorithm: " + algorithm);
+                }
+
+                KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm);
+                assertInitSignSucceeds(algorithm, good);
+                assertInitSignThrowsInvalidKeyException(algorithm,
+                        TestUtils.buildUpon(good).setSignaturePaddings(badPaddingScheme).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitVerifyIgnoresThatPaddingNotAuthorized() throws Exception {
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                String paddingScheme = TestUtils.getSignatureAlgorithmPadding(algorithm);
+                String badPaddingScheme;
+                if (paddingScheme == null) {
+                    // No padding scheme used by this algorithm -- ignore.
+                    continue;
+                } else if (KeyProperties.SIGNATURE_PADDING_RSA_PKCS1.equalsIgnoreCase(
+                        paddingScheme)) {
+                    badPaddingScheme = KeyProperties.SIGNATURE_PADDING_RSA_PSS;
+                } else if (KeyProperties.SIGNATURE_PADDING_RSA_PSS.equalsIgnoreCase(
+                        paddingScheme)) {
+                    badPaddingScheme = KeyProperties.SIGNATURE_PADDING_RSA_PKCS1;
+                } else {
+                    throw new IllegalArgumentException("Unsupported algorithm: " + algorithm);
+                }
+
+                KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm);
+                assertInitVerifySucceeds(algorithm, good);
+                assertInitVerifySucceeds(algorithm,
+                        TestUtils.buildUpon(good).setSignaturePaddings(badPaddingScheme).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitSignFailsWhenKeyNotYetValid() throws Exception {
+        Date badStartDate = new Date(System.currentTimeMillis() + DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm);
+                assertInitSignSucceeds(algorithm, good);
+                assertInitSignThrowsInvalidKeyException(algorithm,
+                        TestUtils.buildUpon(good).setKeyValidityStart(badStartDate).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitVerifyIgnoresThatKeyNotYetValid() throws Exception {
+        Date badStartDate = new Date(System.currentTimeMillis() + DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm);
+                assertInitVerifySucceeds(algorithm, good);
+                assertInitVerifySucceeds(algorithm,
+                        TestUtils.buildUpon(good).setKeyValidityStart(badStartDate).build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitSignFailsWhenKeyNoLongerValidForOrigination() throws Exception {
+        Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm);
+                assertInitSignSucceeds(algorithm, good);
+                assertInitSignThrowsInvalidKeyException(algorithm,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForOriginationEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitVerifyIgnoresThatKeyNoLongerValidForOrigination() throws Exception {
+        Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm);
+                assertInitVerifySucceeds(algorithm, good);
+                assertInitVerifySucceeds(algorithm,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForOriginationEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitSignIgnoresThatKeyNoLongerValidForConsumption() throws Exception {
+        Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForSigning(algorithm);
+                assertInitSignSucceeds(algorithm, good);
+                assertInitSignSucceeds(algorithm,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForConsumptionEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    public void testInitVerifyIgnoresThatKeyNoLongerValidForConsumption() throws Exception {
+        Date badEndDate = new Date(System.currentTimeMillis() - DAY_IN_MILLIS);
+        for (String algorithm : EXPECTED_SIGNATURE_ALGORITHMS) {
+            try {
+                KeyProtection good = getMinimalWorkingImportParamsForVerifying(algorithm);
+                assertInitVerifySucceeds(algorithm, good);
+                assertInitVerifySucceeds(algorithm,
+                        TestUtils.buildUpon(good)
+                                .setKeyValidityForConsumptionEnd(badEndDate)
+                                .build());
+            } catch (Throwable e) {
+                throw new RuntimeException("Failed for " + algorithm, e);
+            }
+        }
+    }
+
+    private void assertInitVerifySucceeds(
+            String signatureAlgorithm,
+            KeyProtection keyProtection) throws Exception {
+        int[] resIds = getDefaultKeyAndCertResIds(signatureAlgorithm);
+        assertInitVerifySucceeds(
+                signatureAlgorithm,
+                resIds[0],
+                resIds[1],
+                keyProtection);
+    }
+
+    private void assertInitVerifySucceeds(
+            String signatureAlgorithm,
+            int privateKeyResId,
+            int certResId,
+            KeyProtection keyProtection) throws Exception {
+        PublicKey publicKey = TestUtils.importIntoAndroidKeyStore(
+                "test1", getContext(), privateKeyResId, certResId, keyProtection)
+                .getKeystoreBackedKeyPair()
+                .getPublic();
+        Signature signature = Signature.getInstance(signatureAlgorithm, EXPECTED_PROVIDER_NAME);
+        signature.initVerify(publicKey);
+    }
+
+    private void assertInitSignSucceeds(
+            String signatureAlgorithm,
+            KeyProtection keyProtection) throws Exception {
+        int[] resIds = getDefaultKeyAndCertResIds(signatureAlgorithm);
+        assertInitSignSucceeds(
+                signatureAlgorithm,
+                resIds[0],
+                resIds[1],
+                keyProtection);
+    }
+
+    private void assertInitSignSucceeds(
+            String signatureAlgorithm,
+            int privateKeyResId,
+            int certResId,
+            KeyProtection keyProtection) throws Exception {
+        PrivateKey privateKey = TestUtils.importIntoAndroidKeyStore(
+                "test1", getContext(), privateKeyResId, certResId, keyProtection)
+                .getKeystoreBackedKeyPair()
+                .getPrivate();
+        Signature signature = Signature.getInstance(signatureAlgorithm, EXPECTED_PROVIDER_NAME);
+        signature.initSign(privateKey);
+    }
+
+    private void assertInitSignThrowsInvalidKeyException(
+            String signatureAlgorithm,
+            KeyProtection keyProtection) throws Exception {
+        assertInitSignThrowsInvalidKeyException(null, signatureAlgorithm, keyProtection);
+    }
+
+    private void assertInitSignThrowsInvalidKeyException(
+            String message,
+            String signatureAlgorithm,
+            KeyProtection keyProtection) throws Exception {
+        int[] resIds = getDefaultKeyAndCertResIds(signatureAlgorithm);
+        assertInitSignThrowsInvalidKeyException(
+                message,
+                signatureAlgorithm,
+                resIds[0],
+                resIds[1],
+                keyProtection);
+    }
+
+    private void assertInitSignThrowsInvalidKeyException(
+            String message,
+            String signatureAlgorithm,
+            int privateKeyResId,
+            int certResId,
+            KeyProtection keyProtection) throws Exception {
+        PrivateKey privateKey = TestUtils.importIntoAndroidKeyStore(
+                "test1", getContext(), privateKeyResId, certResId, keyProtection)
+                .getKeystoreBackedKeyPair()
+                .getPrivate();
+        Signature signature = Signature.getInstance(signatureAlgorithm, EXPECTED_PROVIDER_NAME);
+        try {
+            signature.initSign(privateKey);
+            fail(message);
+        } catch (InvalidKeyException expected) {}
+    }
+
+    static int[] getDefaultKeyAndCertResIds(String signatureAlgorithm) {
+        String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm);
+        if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
+            return new int[] {R.raw.ec_key1_pkcs8, R.raw.ec_key1_cert};
+        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            return new int[] {R.raw.rsa_key1_pkcs8, R.raw.rsa_key1_cert};
+        } else {
+            throw new IllegalArgumentException("Unknown key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    private ImportedKey importDefaultKatKeyPair(String signatureAlgorithm) throws Exception {
+        String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm);
+        KeyProtection importParams =
+                TestUtils.getMinimalWorkingImportParametersForSigningingWith(signatureAlgorithm);
+        if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
+            return TestUtils.importIntoAndroidKeyStore(
+                    "testEc",
+                    getContext(),
+                    R.raw.ec_key1_pkcs8,
+                    R.raw.ec_key1_cert,
+                    importParams);
+        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            return TestUtils.importIntoAndroidKeyStore(
+                    "testRsa",
+                    getContext(),
+                    R.raw.rsa_key1_pkcs8,
+                    R.raw.rsa_key1_cert,
+                    importParams);
+        } else {
+            throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    private void assertSignatureVerifiesOneShot(
+            String algorithm,
+            PublicKey publicKey,
+            byte[] message,
+            byte[] signature) throws Exception {
+        assertSignatureVerifiesOneShot(algorithm, null, publicKey, message, signature);
+    }
+
+    private void assertSignatureVerifiesOneShot(
+            String algorithm,
+            Provider provider,
+            PublicKey publicKey,
+            byte[] message,
+            byte[] signature) throws Exception {
+        Signature sig = (provider != null)
+                ? Signature.getInstance(algorithm, provider) : Signature.getInstance(algorithm);
+        sig.initVerify(publicKey);
+        sig.update(message);
+        if (!sig.verify(signature)) {
+            fail("Signature did not verify. algorithm: " + algorithm
+                    + ", provider: " + sig.getProvider().getName()
+                    + ", signature (" + signature.length + " bytes): "
+                    + HexEncoding.encode(signature));
+        }
+    }
+
+    private void assertSignatureDoesNotVerifyOneShot(
+            String algorithm,
+            Provider provider,
+            PublicKey publicKey,
+            byte[] message,
+            byte[] signature) throws Exception {
+        Signature sig = (provider != null)
+                ? Signature.getInstance(algorithm, provider) : Signature.getInstance(algorithm);
+        sig.initVerify(publicKey);
+        sig.update(message);
+        if (sig.verify(signature)) {
+            fail("Signature verified unexpectedly. algorithm: " + algorithm
+                    + ", provider: " + sig.getProvider().getName()
+                    + ", signature (" + signature.length + " bytes): "
+                    + HexEncoding.encode(signature));
+        }
+    }
+
+    private void assertSignatureVerifiesFedOneByteAtATime(
+            String algorithm,
+            Provider provider,
+            PublicKey publicKey,
+            byte[] message,
+            byte[] signature) throws Exception {
+        Signature sig = (provider != null)
+                ? Signature.getInstance(algorithm, provider) : Signature.getInstance(algorithm);
+        sig.initVerify(publicKey);
+        for (int i = 0; i < message.length; i++) {
+            sig.update(message[i]);
+        }
+        if (!sig.verify(signature)) {
+            fail("Signature did not verify. algorithm: " + algorithm
+                    + ", provider: " + sig.getProvider().getName()
+                    + ", signature (" + signature.length + " bytes): "
+                    + HexEncoding.encode(signature));
+        }
+    }
+
+    private byte[] generateSignatureFedUsingFixedSizeChunks(
+            String algorithm,
+            Provider expectedProvider,
+            PrivateKey privateKey,
+            byte[] message,
+            int chunkSizeBytes) throws Exception {
+        Signature signature = Signature.getInstance(algorithm);
+        signature.initSign(privateKey);
+        assertSame(expectedProvider, signature.getProvider());
+        int messageRemaining = message.length;
+        int messageOffset = 0;
+        while (messageRemaining > 0) {
+            int actualChunkSizeBytes =  Math.min(chunkSizeBytes, messageRemaining);
+            signature.update(message, messageOffset, actualChunkSizeBytes);
+            messageOffset += actualChunkSizeBytes;
+            messageRemaining -= actualChunkSizeBytes;
+        }
+        return signature.sign();
+    }
+
+    private void assertSignatureVerifiesFedUsingFixedSizeChunks(
+            String algorithm,
+            Provider provider,
+            PublicKey publicKey,
+            byte[] message,
+            byte[] signature,
+            int chunkSizeBytes) throws Exception {
+        Signature sig = (provider != null)
+                ? Signature.getInstance(algorithm, provider) : Signature.getInstance(algorithm);
+        sig.initVerify(publicKey);
+        int messageRemaining = message.length;
+        int messageOffset = 0;
+        while (messageRemaining > 0) {
+            int actualChunkSizeBytes =  Math.min(chunkSizeBytes, messageRemaining);
+            sig.update(message, messageOffset, actualChunkSizeBytes);
+            messageOffset += actualChunkSizeBytes;
+            messageRemaining -= actualChunkSizeBytes;
+        }
+        if (!sig.verify(signature)) {
+            fail("Signature did not verify. algorithm: " + algorithm
+                    + ", provider: " + sig.getProvider().getName()
+                    + ", signature (" + signature.length + " bytes): "
+                    + HexEncoding.encode(signature));
+        }
+    }
+
+    private static KeyProtection getMinimalWorkingImportParamsForSigning(String algorithm) {
+        return TestUtils.getMinimalWorkingImportParametersForSigningingWith(algorithm);
+    }
+
+    private static KeyProtection getMinimalWorkingImportParamsForVerifying(
+            @SuppressWarnings("unused") String algorithm) {
+        // No need to authorize anything because verification does not use the private key.
+        // Operations using public keys do not need authorization.
+        return new KeyProtection.Builder(0).build();
+    }
+
+    static Collection<ImportedKey> importKatKeyPairsForSigning(
+            Context context, String signatureAlgorithm) throws Exception {
+        String keyAlgorithm = TestUtils.getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm);
+        KeyProtection importParams =
+                TestUtils.getMinimalWorkingImportParametersForSigningingWith(signatureAlgorithm);
+        if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
+            return ECDSASignatureTest.importKatKeyPairs(context, importParams);
+        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            return RSASignatureTest.importKatKeyPairs(context, importParams);
+        } else {
+            throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/TestUtils.java b/tests/tests/keystore/src/android/keystore/cts/TestUtils.java
new file mode 100644
index 0000000..85b8869
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/TestUtils.java
@@ -0,0 +1,910 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 android.content.Context;
+import android.security.keystore.KeyGenParameterSpec;
+import android.security.keystore.KeyInfo;
+import android.security.keystore.KeyProperties;
+import android.security.keystore.KeyProtection;
+import android.test.MoreAsserts;
+import junit.framework.Assert;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.Key;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.UnrecoverableEntryException;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECKey;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.interfaces.RSAKey;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.EllipticCurve;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.SecretKeySpec;
+
+abstract class TestUtils extends Assert {
+
+    static final String EXPECTED_CRYPTO_OP_PROVIDER_NAME = "AndroidKeyStoreBCWorkaround";
+    static final String EXPECTED_PROVIDER_NAME = "AndroidKeyStore";
+
+    static final long DAY_IN_MILLIS = 1000 * 60 * 60 * 24;
+
+
+    private TestUtils() {}
+
+    /**
+     * Asserts the the key algorithm and algorithm-specific parameters of the two keys in the
+     * provided pair match.
+     */
+    static void assertKeyPairSelfConsistent(KeyPair keyPair) {
+        assertKeyPairSelfConsistent(keyPair.getPublic(), keyPair.getPrivate());
+    }
+
+    /**
+     * Asserts the the key algorithm and public algorithm-specific parameters of the two provided
+     * keys match.
+     */
+    static void assertKeyPairSelfConsistent(PublicKey publicKey, PrivateKey privateKey) {
+        assertNotNull(publicKey);
+        assertNotNull(privateKey);
+        assertEquals(publicKey.getAlgorithm(), privateKey.getAlgorithm());
+        String keyAlgorithm = publicKey.getAlgorithm();
+        if ("EC".equalsIgnoreCase(keyAlgorithm)) {
+            assertTrue("EC public key must be instanceof ECKey: "
+                    + publicKey.getClass().getName(),
+                    publicKey instanceof ECKey);
+            assertTrue("EC private key must be instanceof ECKey: "
+                    + privateKey.getClass().getName(),
+                    privateKey instanceof ECKey);
+            assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+                    "Private key must have the same EC parameters as public key",
+                    ((ECKey) publicKey).getParams(), ((ECKey) privateKey).getParams());
+        } else if ("RSA".equalsIgnoreCase(keyAlgorithm)) {
+            assertTrue("RSA public key must be instance of RSAKey: "
+                    + publicKey.getClass().getName(),
+                    publicKey instanceof RSAKey);
+            assertTrue("RSA private key must be instance of RSAKey: "
+                    + privateKey.getClass().getName(),
+                    privateKey instanceof RSAKey);
+            assertEquals("Private and public key must have the same RSA modulus",
+                    ((RSAKey) publicKey).getModulus(), ((RSAKey) privateKey).getModulus());
+        } else {
+            fail("Unsuported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    static int getKeySizeBits(Key key) {
+        if (key instanceof ECKey) {
+            return ((ECKey) key).getParams().getCurve().getField().getFieldSize();
+        } else if (key instanceof RSAKey) {
+            return ((RSAKey) key).getModulus().bitLength();
+        } else {
+            throw new IllegalArgumentException("Unsupported key type: " + key.getClass());
+        }
+    }
+
+    static void assertKeySize(int expectedSizeBits, KeyPair keyPair) {
+        assertEquals(expectedSizeBits, getKeySizeBits(keyPair.getPrivate()));
+        assertEquals(expectedSizeBits, getKeySizeBits(keyPair.getPublic()));
+    }
+
+    /**
+     * Asserts that the provided key pair is an Android Keystore key pair stored under the provided
+     * alias.
+     */
+    static void assertKeyStoreKeyPair(KeyStore keyStore, String alias, KeyPair keyPair) {
+        assertKeyMaterialExportable(keyPair.getPublic());
+        assertKeyMaterialNotExportable(keyPair.getPrivate());
+        assertTransparentKey(keyPair.getPublic());
+        assertOpaqueKey(keyPair.getPrivate());
+
+        KeyStore.Entry entry;
+        Certificate cert;
+        try {
+            entry = keyStore.getEntry(alias, null);
+            cert = keyStore.getCertificate(alias);
+        } catch (KeyStoreException | UnrecoverableEntryException | NoSuchAlgorithmException e) {
+            throw new RuntimeException("Failed to load entry: " + alias, e);
+        }
+        assertNotNull(entry);
+
+        assertTrue(entry instanceof KeyStore.PrivateKeyEntry);
+        KeyStore.PrivateKeyEntry privEntry = (KeyStore.PrivateKeyEntry) entry;
+        assertEquals(cert, privEntry.getCertificate());
+        assertTrue("Certificate must be an X.509 certificate: " + cert.getClass(),
+                cert instanceof X509Certificate);
+        final X509Certificate x509Cert = (X509Certificate) cert;
+
+        PrivateKey keystorePrivateKey = privEntry.getPrivateKey();
+        PublicKey keystorePublicKey = cert.getPublicKey();
+        assertEquals(keyPair.getPrivate(), keystorePrivateKey);
+        assertEquals(keyPair.getPublic(), keystorePublicKey);
+
+        assertEquals(
+                "Public key used to sign certificate should have the same algorithm as in KeyPair",
+                keystorePublicKey.getAlgorithm(), x509Cert.getPublicKey().getAlgorithm());
+
+        Certificate[] chain = privEntry.getCertificateChain();
+        if (chain.length == 0) {
+            fail("Empty certificate chain");
+            return;
+        }
+        assertEquals(cert, chain[0]);
+    }
+
+
+    private static void assertKeyMaterialExportable(Key key) {
+        if (key instanceof PublicKey) {
+            assertEquals("X.509", key.getFormat());
+        } else if (key instanceof PrivateKey) {
+            assertEquals("PKCS#8", key.getFormat());
+        } else if (key instanceof SecretKey) {
+            assertEquals("RAW", key.getFormat());
+        } else {
+            fail("Unsupported key type: " + key.getClass().getName());
+        }
+        byte[] encodedForm = key.getEncoded();
+        assertNotNull(encodedForm);
+        if (encodedForm.length == 0) {
+            fail("Empty encoded form");
+        }
+    }
+
+    private static void assertKeyMaterialNotExportable(Key key) {
+        assertEquals(null, key.getFormat());
+        assertEquals(null, key.getEncoded());
+    }
+
+    private static void assertOpaqueKey(Key key) {
+        assertFalse(key.getClass().getName() + " is a transparent key", isTransparentKey(key));
+    }
+
+    private static void assertTransparentKey(Key key) {
+        assertTrue(key.getClass().getName() + " is not a transparent key", isTransparentKey(key));
+    }
+
+    private static boolean isTransparentKey(Key key) {
+        if (key instanceof PrivateKey) {
+            return (key instanceof ECPrivateKey) || (key instanceof RSAPrivateKey);
+        } else if (key instanceof PublicKey) {
+            return (key instanceof ECPublicKey) || (key instanceof RSAPublicKey);
+        } else if (key instanceof SecretKey) {
+            return (key instanceof SecretKeySpec);
+        } else {
+            throw new IllegalArgumentException("Unsupported key type: " + key.getClass().getName());
+        }
+    }
+
+    static void assertECParameterSpecEqualsIgnoreSeedIfNotPresent(
+            ECParameterSpec expected, ECParameterSpec actual) {
+        assertECParameterSpecEqualsIgnoreSeedIfNotPresent(null, expected, actual);
+    }
+
+    static void assertECParameterSpecEqualsIgnoreSeedIfNotPresent(String message,
+            ECParameterSpec expected, ECParameterSpec actual) {
+        EllipticCurve expectedCurve = expected.getCurve();
+        EllipticCurve actualCurve = actual.getCurve();
+        String msgPrefix = (message != null) ? message + ": " : "";
+        assertEquals(msgPrefix + "curve field", expectedCurve.getField(), actualCurve.getField());
+        assertEquals(msgPrefix + "curve A", expectedCurve.getA(), actualCurve.getA());
+        assertEquals(msgPrefix + "curve B", expectedCurve.getB(), actualCurve.getB());
+        assertEquals(msgPrefix + "order", expected.getOrder(), actual.getOrder());
+        assertEquals(msgPrefix + "generator",
+                expected.getGenerator(), actual.getGenerator());
+        assertEquals(msgPrefix + "cofactor", expected.getCofactor(), actual.getCofactor());
+
+        // If present, the seed must be the same
+        byte[] expectedSeed = expectedCurve.getSeed();
+        byte[] actualSeed = expectedCurve.getSeed();
+        if ((expectedSeed != null) && (actualSeed != null)) {
+            MoreAsserts.assertEquals(expectedSeed, actualSeed);
+        }
+    }
+
+    static KeyInfo getKeyInfo(Key key) throws InvalidKeySpecException, NoSuchAlgorithmException,
+            NoSuchProviderException {
+        if ((key instanceof PrivateKey) || (key instanceof PublicKey)) {
+            return KeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore")
+                    .getKeySpec(key, KeyInfo.class);
+        } else if (key instanceof SecretKey) {
+            return (KeyInfo) SecretKeyFactory.getInstance(key.getAlgorithm(), "AndroidKeyStore")
+                    .getKeySpec((SecretKey) key, KeyInfo.class);
+        } else {
+            throw new IllegalArgumentException("Unexpected key type: " + key.getClass());
+        }
+    }
+
+    static <T> void assertContentsInAnyOrder(Iterable<T> actual, T... expected) {
+        assertContentsInAnyOrder(null, actual, expected);
+    }
+
+    static <T> void assertContentsInAnyOrder(String message, Iterable<T> actual, T... expected) {
+        Map<T, Integer> actualFreq = getFrequencyTable(actual);
+        Map<T, Integer> expectedFreq = getFrequencyTable(expected);
+        if (actualFreq.equals(expectedFreq)) {
+            return;
+        }
+
+        Map<T, Integer> extraneousFreq = new HashMap<T, Integer>();
+        for (Map.Entry<T, Integer> actualEntry : actualFreq.entrySet()) {
+            int actualCount = actualEntry.getValue();
+            Integer expectedCount = expectedFreq.get(actualEntry.getKey());
+            int diff = actualCount - ((expectedCount != null) ? expectedCount : 0);
+            if (diff > 0) {
+                extraneousFreq.put(actualEntry.getKey(), diff);
+            }
+        }
+
+        Map<T, Integer> missingFreq = new HashMap<T, Integer>();
+        for (Map.Entry<T, Integer> expectedEntry : expectedFreq.entrySet()) {
+            int expectedCount = expectedEntry.getValue();
+            Integer actualCount = actualFreq.get(expectedEntry.getKey());
+            int diff = expectedCount - ((actualCount != null) ? actualCount : 0);
+            if (diff > 0) {
+                missingFreq.put(expectedEntry.getKey(), diff);
+            }
+        }
+
+        List<T> extraneous = frequencyTableToValues(extraneousFreq);
+        List<T> missing = frequencyTableToValues(missingFreq);
+        StringBuilder result = new StringBuilder();
+        String delimiter = "";
+        if (message != null) {
+            result.append(message).append(".");
+            delimiter = " ";
+        }
+        if (!missing.isEmpty()) {
+            result.append(delimiter).append("missing: " + missing);
+            delimiter = ", ";
+        }
+        if (!extraneous.isEmpty()) {
+            result.append(delimiter).append("extraneous: " + extraneous);
+        }
+        fail(result.toString());
+    }
+
+    private static <T> Map<T, Integer> getFrequencyTable(Iterable<T> values) {
+        Map<T, Integer> result = new HashMap<T, Integer>();
+        for (T value : values) {
+            Integer count = result.get(value);
+            if (count == null) {
+                count = 1;
+            } else {
+                count++;
+            }
+            result.put(value, count);
+        }
+        return result;
+    }
+
+    private static <T> Map<T, Integer> getFrequencyTable(T... values) {
+        Map<T, Integer> result = new HashMap<T, Integer>();
+        for (T value : values) {
+            Integer count = result.get(value);
+            if (count == null) {
+                count = 1;
+            } else {
+                count++;
+            }
+            result.put(value, count);
+        }
+        return result;
+    }
+
+    @SuppressWarnings("rawtypes")
+    private static <T> List<T> frequencyTableToValues(Map<T, Integer> table) {
+        if (table.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        List<T> result = new ArrayList<T>();
+        boolean comparableValues = true;
+        for (Map.Entry<T, Integer> entry : table.entrySet()) {
+            T value = entry.getKey();
+            if (!(value instanceof Comparable)) {
+                comparableValues = false;
+            }
+            int frequency = entry.getValue();
+            for (int i = 0; i < frequency; i++) {
+                result.add(value);
+            }
+        }
+
+        if (comparableValues) {
+            sortAssumingComparable(result);
+        }
+        return result;
+    }
+
+    @SuppressWarnings({"rawtypes", "unchecked"})
+    private static void sortAssumingComparable(List<?> values) {
+        Collections.sort((List<Comparable>)values);
+    }
+
+    static String[] toLowerCase(String... values) {
+        if (values == null) {
+            return null;
+        }
+        String[] result = new String[values.length];
+        for (int i = 0; i < values.length; i++) {
+            String value = values[i];
+            result[i] = (value != null) ? value.toLowerCase() : null;
+        }
+        return result;
+    }
+
+    static PrivateKey getRawResPrivateKey(Context context, int resId) throws Exception {
+        byte[] pkcs8EncodedForm;
+        try (InputStream in = context.getResources().openRawResource(resId)) {
+            pkcs8EncodedForm = drain(in);
+        }
+        PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pkcs8EncodedForm);
+
+        try {
+            return KeyFactory.getInstance("EC").generatePrivate(privateKeySpec);
+        } catch (InvalidKeySpecException e) {
+            try {
+                return KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec);
+            } catch (InvalidKeySpecException e2) {
+                throw new InvalidKeySpecException("The key is neither EC nor RSA", e);
+            }
+        }
+    }
+
+    static X509Certificate getRawResX509Certificate(Context context, int resId) throws Exception {
+        try (InputStream in = context.getResources().openRawResource(resId)) {
+            return (X509Certificate) CertificateFactory.getInstance("X.509")
+                    .generateCertificate(in);
+        }
+    }
+
+    static KeyPair importIntoAndroidKeyStore(
+            String alias,
+            PrivateKey privateKey,
+            Certificate certificate,
+            KeyProtection keyProtection) throws Exception {
+        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+        keyStore.load(null);
+        keyStore.setEntry(alias,
+                new KeyStore.PrivateKeyEntry(privateKey, new Certificate[] {certificate}),
+                keyProtection);
+        return new KeyPair(
+                keyStore.getCertificate(alias).getPublicKey(),
+                (PrivateKey) keyStore.getKey(alias, null));
+    }
+
+    static ImportedKey importIntoAndroidKeyStore(
+            String alias,
+            SecretKey key,
+            KeyProtection keyProtection) throws Exception {
+        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+        keyStore.load(null);
+        keyStore.setEntry(alias,
+                new KeyStore.SecretKeyEntry(key),
+                keyProtection);
+        return new ImportedKey(alias, key, (SecretKey) keyStore.getKey(alias, null));
+    }
+
+    static ImportedKey importIntoAndroidKeyStore(
+            String alias, Context context, int privateResId, int certResId, KeyProtection params)
+                    throws Exception {
+        Certificate originalCert = TestUtils.getRawResX509Certificate(context, certResId);
+        PublicKey originalPublicKey = originalCert.getPublicKey();
+        PrivateKey originalPrivateKey = TestUtils.getRawResPrivateKey(context, privateResId);
+
+        // Check that the domain parameters match between the private key and the public key. This
+        // is to catch accidental errors where a test provides the wrong resource ID as one of the
+        // parameters.
+        if (!originalPublicKey.getAlgorithm().equalsIgnoreCase(originalPrivateKey.getAlgorithm())) {
+            throw new IllegalArgumentException("Key algorithm mismatch."
+                    + " Public: " + originalPublicKey.getAlgorithm()
+                    + ", private: " + originalPrivateKey.getAlgorithm());
+        }
+        assertKeyPairSelfConsistent(originalPublicKey, originalPrivateKey);
+
+        KeyPair keystoreBacked = TestUtils.importIntoAndroidKeyStore(
+                alias, originalPrivateKey, originalCert,
+                params);
+        assertKeyPairSelfConsistent(keystoreBacked);
+        assertKeyPairSelfConsistent(keystoreBacked.getPublic(), originalPrivateKey);
+        return new ImportedKey(
+                alias,
+                new KeyPair(originalCert.getPublicKey(), originalPrivateKey),
+                keystoreBacked);
+    }
+
+    static byte[] drain(InputStream in) throws IOException {
+        ByteArrayOutputStream result = new ByteArrayOutputStream();
+        byte[] buffer = new byte[16 * 1024];
+        int chunkSize;
+        while ((chunkSize = in.read(buffer)) != -1) {
+            result.write(buffer, 0, chunkSize);
+        }
+        return result.toByteArray();
+    }
+
+    static KeyProtection.Builder buildUpon(KeyProtection params) {
+        return buildUponInternal(params, null);
+    }
+
+    static KeyProtection.Builder buildUpon(KeyProtection params, int newPurposes) {
+        return buildUponInternal(params, newPurposes);
+    }
+
+    static KeyProtection.Builder buildUpon(
+            KeyProtection.Builder builder) {
+        return buildUponInternal(builder.build(), null);
+    }
+
+    static KeyProtection.Builder buildUpon(
+            KeyProtection.Builder builder, int newPurposes) {
+        return buildUponInternal(builder.build(), newPurposes);
+    }
+
+    private static KeyProtection.Builder buildUponInternal(
+            KeyProtection spec, Integer newPurposes) {
+        int purposes = (newPurposes == null) ? spec.getPurposes() : newPurposes;
+        KeyProtection.Builder result = new KeyProtection.Builder(purposes);
+        result.setBlockModes(spec.getBlockModes());
+        if (spec.isDigestsSpecified()) {
+            result.setDigests(spec.getDigests());
+        }
+        result.setEncryptionPaddings(spec.getEncryptionPaddings());
+        result.setSignaturePaddings(spec.getSignaturePaddings());
+        result.setKeyValidityStart(spec.getKeyValidityStart());
+        result.setKeyValidityForOriginationEnd(spec.getKeyValidityForOriginationEnd());
+        result.setKeyValidityForConsumptionEnd(spec.getKeyValidityForConsumptionEnd());
+        result.setRandomizedEncryptionRequired(spec.isRandomizedEncryptionRequired());
+        result.setUserAuthenticationRequired(spec.isUserAuthenticationRequired());
+        result.setUserAuthenticationValidityDurationSeconds(
+                spec.getUserAuthenticationValidityDurationSeconds());
+        return result;
+    }
+
+    static KeyGenParameterSpec.Builder buildUpon(KeyGenParameterSpec spec) {
+        return buildUponInternal(spec, null);
+    }
+
+    static KeyGenParameterSpec.Builder buildUpon(KeyGenParameterSpec spec, int newPurposes) {
+        return buildUponInternal(spec, newPurposes);
+    }
+
+    static KeyGenParameterSpec.Builder buildUpon(
+            KeyGenParameterSpec.Builder builder) {
+        return buildUponInternal(builder.build(), null);
+    }
+
+    static KeyGenParameterSpec.Builder buildUpon(
+            KeyGenParameterSpec.Builder builder, int newPurposes) {
+        return buildUponInternal(builder.build(), newPurposes);
+    }
+
+    private static KeyGenParameterSpec.Builder buildUponInternal(
+            KeyGenParameterSpec spec, Integer newPurposes) {
+        int purposes = (newPurposes == null) ? spec.getPurposes() : newPurposes;
+        KeyGenParameterSpec.Builder result =
+                new KeyGenParameterSpec.Builder(spec.getKeystoreAlias(), purposes);
+        if (spec.getKeySize() >= 0) {
+            result.setKeySize(spec.getKeySize());
+        }
+        if (spec.getAlgorithmParameterSpec() != null) {
+            result.setAlgorithmParameterSpec(spec.getAlgorithmParameterSpec());
+        }
+        result.setCertificateNotBefore(spec.getCertificateNotBefore());
+        result.setCertificateNotAfter(spec.getCertificateNotAfter());
+        result.setCertificateSerialNumber(spec.getCertificateSerialNumber());
+        result.setCertificateSubject(spec.getCertificateSubject());
+        result.setBlockModes(spec.getBlockModes());
+        if (spec.isDigestsSpecified()) {
+            result.setDigests(spec.getDigests());
+        }
+        result.setEncryptionPaddings(spec.getEncryptionPaddings());
+        result.setSignaturePaddings(spec.getSignaturePaddings());
+        result.setKeyValidityStart(spec.getKeyValidityStart());
+        result.setKeyValidityForOriginationEnd(spec.getKeyValidityForOriginationEnd());
+        result.setKeyValidityForConsumptionEnd(spec.getKeyValidityForConsumptionEnd());
+        result.setRandomizedEncryptionRequired(spec.isRandomizedEncryptionRequired());
+        result.setUserAuthenticationRequired(spec.isUserAuthenticationRequired());
+        result.setUserAuthenticationValidityDurationSeconds(
+                spec.getUserAuthenticationValidityDurationSeconds());
+        return result;
+    }
+
+    static KeyPair getKeyPairForKeyAlgorithm(String keyAlgorithm, Iterable<KeyPair> keyPairs) {
+        for (KeyPair keyPair : keyPairs) {
+            if (keyAlgorithm.equalsIgnoreCase(keyPair.getPublic().getAlgorithm())) {
+                return keyPair;
+            }
+        }
+        throw new IllegalArgumentException("No KeyPair for key algorithm " + keyAlgorithm);
+    }
+
+    static Key getKeyForKeyAlgorithm(String keyAlgorithm, Iterable<? extends Key> keys) {
+        for (Key key : keys) {
+            if (keyAlgorithm.equalsIgnoreCase(key.getAlgorithm())) {
+                return key;
+            }
+        }
+        throw new IllegalArgumentException("No Key for key algorithm " + keyAlgorithm);
+    }
+
+    static byte[] generateLargeKatMsg(byte[] seed, int msgSizeBytes) throws Exception {
+        byte[] result = new byte[msgSizeBytes];
+        MessageDigest digest = MessageDigest.getInstance("SHA-512");
+        int resultOffset = 0;
+        int resultRemaining = msgSizeBytes;
+        while (resultRemaining > 0) {
+            seed = digest.digest(seed);
+            int chunkSize = Math.min(seed.length, resultRemaining);
+            System.arraycopy(seed, 0, result, resultOffset, chunkSize);
+            resultOffset += chunkSize;
+            resultRemaining -= chunkSize;
+        }
+        return result;
+    }
+
+    static byte[] leftPadWithZeroBytes(byte[] array, int length) {
+        if (array.length >= length) {
+            return array;
+        }
+        byte[] result = new byte[length];
+        System.arraycopy(array, 0, result, result.length - array.length, array.length);
+        return result;
+    }
+
+    static boolean contains(int[] array, int value) {
+        for (int element : array) {
+            if (element == value) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static boolean isHmacAlgorithm(String algorithm) {
+        return algorithm.toUpperCase(Locale.US).startsWith("HMAC");
+    }
+
+    static String getHmacAlgorithmDigest(String algorithm) {
+        String algorithmUpperCase = algorithm.toUpperCase(Locale.US);
+        if (!algorithmUpperCase.startsWith("HMAC")) {
+            return null;
+        }
+        String result = algorithmUpperCase.substring("HMAC".length());
+        if (result.startsWith("SHA")) {
+            result = "SHA-" + result.substring("SHA".length());
+        }
+        return result;
+    }
+
+    static String getCipherKeyAlgorithm(String transformation) {
+        String transformationUpperCase = transformation.toUpperCase(Locale.US);
+        if (transformationUpperCase.startsWith("AES/")) {
+            return KeyProperties.KEY_ALGORITHM_AES;
+        } else if (transformationUpperCase.startsWith("RSA/")) {
+            return KeyProperties.KEY_ALGORITHM_RSA;
+        } else {
+            throw new IllegalArgumentException("Unsupported transformation: " + transformation);
+        }
+    }
+
+    static boolean isCipherSymmetric(String transformation) {
+        String transformationUpperCase = transformation.toUpperCase(Locale.US);
+        if (transformationUpperCase.startsWith("AES/")) {
+            return true;
+        } else if (transformationUpperCase.startsWith("RSA/")) {
+            return false;
+        } else {
+            throw new IllegalArgumentException("Unsupported transformation: " + transformation);
+        }
+    }
+
+    static String getCipherDigest(String transformation) {
+        String transformationUpperCase = transformation.toUpperCase(Locale.US);
+        if (transformationUpperCase.contains("/OAEP")) {
+            if (transformationUpperCase.endsWith("/OAEPPADDING")) {
+                return KeyProperties.DIGEST_SHA1;
+            } else if (transformationUpperCase.endsWith(
+                    "/OAEPWITHSHA-1ANDMGF1PADDING")) {
+                return KeyProperties.DIGEST_SHA1;
+            } else if (transformationUpperCase.endsWith(
+                    "/OAEPWITHSHA-224ANDMGF1PADDING")) {
+                return KeyProperties.DIGEST_SHA224;
+            } else if (transformationUpperCase.endsWith(
+                    "/OAEPWITHSHA-256ANDMGF1PADDING")) {
+                return KeyProperties.DIGEST_SHA256;
+            } else if (transformationUpperCase.endsWith(
+                    "/OAEPWITHSHA-384ANDMGF1PADDING")) {
+                return KeyProperties.DIGEST_SHA384;
+            } else if (transformationUpperCase.endsWith(
+                    "/OAEPWITHSHA-512ANDMGF1PADDING")) {
+                return KeyProperties.DIGEST_SHA512;
+            } else {
+                throw new RuntimeException("Unsupported OAEP padding scheme: "
+                        + transformation);
+            }
+        } else {
+            return null;
+        }
+    }
+
+    static String getCipherEncryptionPadding(String transformation) {
+        String transformationUpperCase = transformation.toUpperCase(Locale.US);
+        if (transformationUpperCase.endsWith("/NOPADDING")) {
+            return KeyProperties.ENCRYPTION_PADDING_NONE;
+        } else if (transformationUpperCase.endsWith("/PKCS7PADDING")) {
+            return KeyProperties.ENCRYPTION_PADDING_PKCS7;
+        } else if (transformationUpperCase.endsWith("/PKCS1PADDING")) {
+            return KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1;
+        } else if (transformationUpperCase.split("/")[2].startsWith("OAEP")) {
+            return KeyProperties.ENCRYPTION_PADDING_RSA_OAEP;
+        } else {
+            throw new IllegalArgumentException("Unsupported transformation: " + transformation);
+        }
+    }
+
+    static String getCipherBlockMode(String transformation) {
+        return transformation.split("/")[1].toUpperCase(Locale.US);
+    }
+
+    static String getSignatureAlgorithmDigest(String algorithm) {
+        String algorithmUpperCase = algorithm.toUpperCase(Locale.US);
+        int withIndex = algorithmUpperCase.indexOf("WITH");
+        if (withIndex == -1) {
+            throw new IllegalArgumentException("Unsupported algorithm: " + algorithm);
+        }
+        String digest = algorithmUpperCase.substring(0, withIndex);
+        if (digest.startsWith("SHA")) {
+            digest = "SHA-" + digest.substring("SHA".length());
+        }
+        return digest;
+    }
+
+    static String getSignatureAlgorithmPadding(String algorithm) {
+        String algorithmUpperCase = algorithm.toUpperCase(Locale.US);
+        if (algorithmUpperCase.endsWith("WITHECDSA")) {
+            return null;
+        } else if (algorithmUpperCase.endsWith("WITHRSA")) {
+            return KeyProperties.SIGNATURE_PADDING_RSA_PKCS1;
+        } else if (algorithmUpperCase.endsWith("WITHRSA/PSS")) {
+            return KeyProperties.SIGNATURE_PADDING_RSA_PSS;
+        } else {
+            throw new IllegalArgumentException("Unsupported algorithm: " + algorithm);
+        }
+    }
+
+    static String getSignatureAlgorithmKeyAlgorithm(String algorithm) {
+        String algorithmUpperCase = algorithm.toUpperCase(Locale.US);
+        if (algorithmUpperCase.endsWith("WITHECDSA")) {
+            return KeyProperties.KEY_ALGORITHM_EC;
+        } else if ((algorithmUpperCase.endsWith("WITHRSA"))
+                || (algorithmUpperCase.endsWith("WITHRSA/PSS"))) {
+            return KeyProperties.KEY_ALGORITHM_RSA;
+        } else {
+            throw new IllegalArgumentException("Unsupported algorithm: " + algorithm);
+        }
+    }
+
+    static boolean isKeyLongEnoughForSignatureAlgorithm(String algorithm, Key key) {
+        String keyAlgorithm = key.getAlgorithm();
+        if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
+            // No length restrictions for ECDSA
+            return true;
+        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            // No length restrictions for RSA
+            String digest = getSignatureAlgorithmDigest(algorithm);
+            int digestOutputSizeBits = getDigestOutputSizeBits(digest);
+            if (digestOutputSizeBits == -1) {
+                // No digesting -- assume the key is long enough for the message
+                return true;
+            }
+            String paddingScheme = getSignatureAlgorithmPadding(algorithm);
+            int paddingOverheadBytes;
+            if (KeyProperties.SIGNATURE_PADDING_RSA_PKCS1.equalsIgnoreCase(paddingScheme)) {
+                paddingOverheadBytes = 30;
+            } else if (KeyProperties.SIGNATURE_PADDING_RSA_PSS.equalsIgnoreCase(paddingScheme)) {
+                paddingOverheadBytes = 22;
+            } else {
+                throw new IllegalArgumentException(
+                        "Unsupported signature padding scheme: " + paddingScheme);
+            }
+            int minKeySizeBytes = paddingOverheadBytes + (digestOutputSizeBits + 7) / 8 + 1;
+            int keySizeBytes = ((RSAKey) key).getModulus().bitLength() / 8;
+            return keySizeBytes >= minKeySizeBytes;
+        } else {
+            throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    static int getMaxSupportedPlaintextInputSizeBytes(String transformation, Key key) {
+        String keyAlgorithm = getCipherKeyAlgorithm(transformation);
+        if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)) {
+            return Integer.MAX_VALUE;
+        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            String encryptionPadding = getCipherEncryptionPadding(transformation);
+            int modulusSizeBytes = (getKeySizeBits(key) + 7) / 8;
+            if (KeyProperties.ENCRYPTION_PADDING_NONE.equalsIgnoreCase(encryptionPadding)) {
+                return modulusSizeBytes - 1;
+            } else if (KeyProperties.ENCRYPTION_PADDING_RSA_PKCS1.equalsIgnoreCase(
+                    encryptionPadding)) {
+                return modulusSizeBytes - 11;
+            } else if (KeyProperties.ENCRYPTION_PADDING_RSA_OAEP.equalsIgnoreCase(
+                    encryptionPadding)) {
+                String digest = getCipherDigest(transformation);
+                int digestOutputSizeBytes = (getDigestOutputSizeBits(digest) + 7) / 8;
+                return modulusSizeBytes - 2 * digestOutputSizeBytes - 2;
+            } else {
+                throw new IllegalArgumentException(
+                        "Unsupported encryption padding scheme: " + encryptionPadding);
+            }
+        } else {
+            throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    static int getDigestOutputSizeBits(String digest) {
+        if (KeyProperties.DIGEST_NONE.equals(digest)) {
+            return -1;
+        } else if (KeyProperties.DIGEST_MD5.equals(digest)) {
+            return 128;
+        } else if (KeyProperties.DIGEST_SHA1.equals(digest)) {
+            return 160;
+        } else if (KeyProperties.DIGEST_SHA224.equals(digest)) {
+            return 224;
+        } else if (KeyProperties.DIGEST_SHA256.equals(digest)) {
+            return 256;
+        } else if (KeyProperties.DIGEST_SHA384.equals(digest)) {
+            return 384;
+        } else if (KeyProperties.DIGEST_SHA512.equals(digest)) {
+            return 512;
+        } else {
+            throw new IllegalArgumentException("Unsupported digest: " + digest);
+        }
+    }
+
+    static byte[] concat(byte[] arr1, byte[] arr2) {
+        return concat(arr1, 0, (arr1 != null) ? arr1.length : 0,
+                arr2, 0, (arr2 != null) ? arr2.length : 0);
+    }
+
+    static byte[] concat(byte[] arr1, int offset1, int len1,
+            byte[] arr2, int offset2, int len2) {
+        if (len1 == 0) {
+            return subarray(arr2, offset2, len2);
+        } else if (len2 == 0) {
+            return subarray(arr1, offset1, len1);
+        }
+        byte[] result = new byte[len1 + len2];
+        if (len1 > 0) {
+            System.arraycopy(arr1, offset1, result, 0, len1);
+        }
+        if (len2 > 0) {
+            System.arraycopy(arr2, offset2, result, len1, len2);
+        }
+        return result;
+    }
+
+    static byte[] subarray(byte[] arr, int offset, int len) {
+        if (len == 0) {
+            return EmptyArray.BYTE;
+        }
+        if ((offset == 0) && (arr.length == len)) {
+            return arr;
+        }
+        byte[] result = new byte[len];
+        System.arraycopy(arr, offset, result, 0, len);
+        return result;
+    }
+
+    static KeyProtection getMinimalWorkingImportParametersForSigningingWith(
+            String signatureAlgorithm) {
+        String keyAlgorithm = getSignatureAlgorithmKeyAlgorithm(signatureAlgorithm);
+        String digest = getSignatureAlgorithmDigest(signatureAlgorithm);
+        if (KeyProperties.KEY_ALGORITHM_EC.equalsIgnoreCase(keyAlgorithm)) {
+            return new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
+                    .setDigests(digest)
+                    .build();
+        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            String padding = getSignatureAlgorithmPadding(signatureAlgorithm);
+            return new KeyProtection.Builder(KeyProperties.PURPOSE_SIGN)
+                    .setDigests(digest)
+                    .setSignaturePaddings(padding)
+                    .build();
+        } else {
+            throw new IllegalArgumentException(
+                    "Unsupported signature algorithm: " + signatureAlgorithm);
+        }
+    }
+
+    static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
+            String transformation, int purposes) {
+        return getMinimalWorkingImportParametersForCipheringWith(transformation, purposes, false);
+    }
+
+    static KeyProtection getMinimalWorkingImportParametersForCipheringWith(
+            String transformation, int purposes, boolean ivProvidedWhenEncrypting) {
+        String keyAlgorithm = TestUtils.getCipherKeyAlgorithm(transformation);
+        if (KeyProperties.KEY_ALGORITHM_AES.equalsIgnoreCase(keyAlgorithm)) {
+            String encryptionPadding = TestUtils.getCipherEncryptionPadding(transformation);
+            String blockMode = TestUtils.getCipherBlockMode(transformation);
+            boolean randomizedEncryptionRequired = true;
+            if (KeyProperties.BLOCK_MODE_ECB.equalsIgnoreCase(blockMode)) {
+                randomizedEncryptionRequired = false;
+            } else if ((ivProvidedWhenEncrypting)
+                    && ((purposes & KeyProperties.PURPOSE_ENCRYPT) != 0)) {
+                randomizedEncryptionRequired = false;
+            }
+            return new KeyProtection.Builder(
+                    purposes)
+                    .setBlockModes(blockMode)
+                    .setEncryptionPaddings(encryptionPadding)
+                    .setRandomizedEncryptionRequired(randomizedEncryptionRequired)
+                    .build();
+        } else if (KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(keyAlgorithm)) {
+            String digest = TestUtils.getCipherDigest(transformation);
+            String encryptionPadding = TestUtils.getCipherEncryptionPadding(transformation);
+            boolean randomizedEncryptionRequired =
+                    !KeyProperties.ENCRYPTION_PADDING_NONE.equalsIgnoreCase(encryptionPadding);
+            return new KeyProtection.Builder(
+                    purposes)
+                    .setDigests((digest != null) ? new String[] {digest} : EmptyArray.STRING)
+                    .setEncryptionPaddings(encryptionPadding)
+                    .setRandomizedEncryptionRequired(randomizedEncryptionRequired)
+                    .build();
+        } else {
+            throw new IllegalArgumentException("Unsupported key algorithm: " + keyAlgorithm);
+        }
+    }
+
+    static byte[] getBigIntegerMagnitudeBytes(BigInteger value) {
+        return removeLeadingZeroByteIfPresent(value.toByteArray());
+    }
+
+    private static byte[] removeLeadingZeroByteIfPresent(byte[] value) {
+        if ((value.length < 1) || (value[0] != 0)) {
+            return value;
+        }
+        return TestUtils.subarray(value, 1, value.length - 1);
+    }
+}
diff --git a/tests/tests/keystore/src/android/keystore/cts/TransparentSecretKey.java b/tests/tests/keystore/src/android/keystore/cts/TransparentSecretKey.java
new file mode 100644
index 0000000..6e74dc0
--- /dev/null
+++ b/tests/tests/keystore/src/android/keystore/cts/TransparentSecretKey.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 javax.crypto.SecretKey;
+
+/**
+ * {@link SecretKey} which exposes its key material. The two reasons for the existence of this class
+ * are: (1) to help test that classes under test don't assume that all transparent secret keys are
+ * instances of {@link SecretKeySpec}, and (2) because {@code SecretKeySpec} rejects zero-length
+ * key material which is needed in some tests.
+ */
+public class TransparentSecretKey implements SecretKey {
+    private final String mAlgorithm;
+    private final byte[] mKeyMaterial;
+
+    public TransparentSecretKey(byte[] keyMaterial, String algorithm) {
+        mAlgorithm = algorithm;
+        mKeyMaterial = keyMaterial.clone();
+    }
+
+    @Override
+    public String getAlgorithm() {
+        return mAlgorithm;
+    }
+
+    @Override
+    public byte[] getEncoded() {
+        return mKeyMaterial;
+    }
+
+    @Override
+    public String getFormat() {
+        return "RAW";
+    }
+}
diff --git a/tests/tests/libcorelegacy22/Android.mk b/tests/tests/libcorelegacy22/Android.mk
new file mode 100644
index 0000000..fb3c503
--- /dev/null
+++ b/tests/tests/libcorelegacy22/Android.mk
@@ -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.
+
+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
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsLibcoreLegacy22TestCases
+
+LOCAL_SDK_VERSION := 22
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/libcorelegacy22/AndroidManifest.xml b/tests/tests/libcorelegacy22/AndroidManifest.xml
new file mode 100644
index 0000000..4ff9ec2
--- /dev/null
+++ b/tests/tests/libcorelegacy22/AndroidManifest.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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.libcorelegacy22">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.READ_LOGS" />
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.libcorelegacy22"
+                     android:label="CTS tests of android APIs last available in API 22">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/libcorelegacy22/src/android/util/cts/FloatMathTest.java b/tests/tests/libcorelegacy22/src/android/util/cts/FloatMathTest.java
new file mode 100644
index 0000000..6b775fc
--- /dev/null
+++ b/tests/tests/libcorelegacy22/src/android/util/cts/FloatMathTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.util.cts;
+
+import junit.framework.TestCase;
+import android.util.FloatMath;
+
+public class FloatMathTest extends TestCase {
+
+    public void testSqrt() {
+        assertEquals(5.0f, FloatMath.sqrt(25));
+        assertEquals(7, FloatMath.sqrt(49), 0);
+        assertEquals(10, FloatMath.sqrt(100), 0);
+        assertEquals(0, FloatMath.sqrt(0), 0);
+        assertEquals(1, FloatMath.sqrt(1), 0);
+    }
+
+    public void testFloor() {
+        assertEquals(78, FloatMath.floor(78.89f), 0);
+        assertEquals(-79, FloatMath.floor(-78.89f), 0);
+        assertEquals(7.0f, FloatMath.floor(7.2f));
+        assertEquals(-7.0f, FloatMath.floor(-6.3f));
+    }
+
+    public void testCeil() {
+        assertEquals(79, FloatMath.ceil(78.89f), 0);
+        assertEquals(-78, FloatMath.ceil(-78.89f), 0);
+        assertEquals(8.0f, FloatMath.ceil(7.2f));
+        assertEquals(-6.0f, FloatMath.ceil(-6.3f));
+    }
+
+    public void testCos() {
+        assertEquals(1.0f, FloatMath.cos(0), 0);
+        assertEquals(0.5403023058681398f, FloatMath.cos(1), 0);
+        assertEquals(0.964966f, FloatMath.cos(50));
+        assertEquals(0.69925081f, FloatMath.cos(150));
+        assertEquals(0.964966f, FloatMath.cos(-50));
+    }
+
+    public void testSin() {
+        assertEquals(0.0, FloatMath.sin(0), 0);
+        assertEquals(0.8414709848078965f, FloatMath.sin(1), 0);
+        assertEquals(-0.26237485f, FloatMath.sin(50));
+        assertEquals(-0.71487643f, FloatMath.sin(150));
+        assertEquals(0.26237485f, FloatMath.sin(-50));
+
+    }
+}
+
diff --git a/tests/tests/location/Android.mk b/tests/tests/location/Android.mk
index 02de2f2..62d0d5d 100644
--- a/tests/tests/location/Android.mk
+++ b/tests/tests/location/Android.mk
@@ -21,7 +21,7 @@
 # and 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 := ctsdeviceutil ctstestrunner
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/tests/tests/location/src/android/location/cts/BaseMockLocationTest.java b/tests/tests/location/src/android/location/cts/BaseMockLocationTest.java
new file mode 100644
index 0000000..14019be
--- /dev/null
+++ b/tests/tests/location/src/android/location/cts/BaseMockLocationTest.java
@@ -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
+ *
+ */
+
+package android.location.cts;
+
+import android.cts.util.LocationUtils;
+import android.test.InstrumentationTestCase;
+
+/**
+ * Base class for instrumentations tests that use mock location.
+ */
+public abstract class BaseMockLocationTest extends InstrumentationTestCase {
+    private static final String LOG_TAG = "BaseMockLocationTest";
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        LocationUtils.registerMockLocationProvider(getInstrumentation(), true);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        LocationUtils.registerMockLocationProvider(getInstrumentation(), false);
+        super.tearDown();
+    }
+}
diff --git a/tests/tests/location/src/android/location/cts/CriteriaTest.java b/tests/tests/location/src/android/location/cts/CriteriaTest.java
index d812965f..422f561 100644
--- a/tests/tests/location/src/android/location/cts/CriteriaTest.java
+++ b/tests/tests/location/src/android/location/cts/CriteriaTest.java
@@ -113,6 +113,19 @@
         assertTrue(criteria.isAltitudeRequired());
     }
 
+    public void testAccessBearingAccuracy() {
+        Criteria criteria = new Criteria();
+
+        criteria.setBearingAccuracy(Criteria.ACCURACY_LOW);
+        assertEquals(Criteria.ACCURACY_LOW, criteria.getBearingAccuracy());
+
+        criteria.setBearingAccuracy(Criteria.ACCURACY_HIGH);
+        assertEquals(Criteria.ACCURACY_HIGH, criteria.getBearingAccuracy());
+
+        criteria.setBearingAccuracy(Criteria.NO_REQUIREMENT);
+        assertEquals(Criteria.NO_REQUIREMENT, criteria.getBearingAccuracy());
+      }
+
     public void testAccessBearingRequired() {
         Criteria criteria = new Criteria();
 
@@ -133,6 +146,35 @@
         assertTrue(criteria.isCostAllowed());
     }
 
+    public void testAccessHorizontalAccuracy() {
+        Criteria criteria = new Criteria();
+
+        criteria.setHorizontalAccuracy(Criteria.ACCURACY_LOW);
+        assertEquals(Criteria.ACCURACY_LOW, criteria.getHorizontalAccuracy());
+
+        criteria.setHorizontalAccuracy(Criteria.ACCURACY_MEDIUM);
+        assertEquals(Criteria.ACCURACY_MEDIUM, criteria.getHorizontalAccuracy());
+
+        criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
+        assertEquals(Criteria.ACCURACY_HIGH, criteria.getHorizontalAccuracy());
+
+        criteria.setHorizontalAccuracy(Criteria.NO_REQUIREMENT);
+        assertEquals(Criteria.NO_REQUIREMENT, criteria.getHorizontalAccuracy());
+    }
+
+    public void testAccessSpeedAccuracy() {
+        Criteria criteria = new Criteria();
+
+        criteria.setSpeedAccuracy(Criteria.ACCURACY_LOW);
+        assertEquals(Criteria.ACCURACY_LOW, criteria.getSpeedAccuracy());
+
+        criteria.setSpeedAccuracy(Criteria.ACCURACY_HIGH);
+        assertEquals(Criteria.ACCURACY_HIGH, criteria.getSpeedAccuracy());
+
+        criteria.setSpeedAccuracy(Criteria.NO_REQUIREMENT);
+        assertEquals(Criteria.NO_REQUIREMENT, criteria.getSpeedAccuracy());
+    }
+
     public void testAccessSpeedRequired() {
         Criteria criteria = new Criteria();
 
@@ -143,6 +185,19 @@
         assertTrue(criteria.isSpeedRequired());
     }
 
+    public void testAccessVerticalAccuracy() {
+        Criteria criteria = new Criteria();
+
+        criteria.setVerticalAccuracy(Criteria.ACCURACY_LOW);
+        assertEquals(Criteria.ACCURACY_LOW, criteria.getVerticalAccuracy());
+
+       criteria.setVerticalAccuracy(Criteria.ACCURACY_HIGH);
+        assertEquals(Criteria.ACCURACY_HIGH, criteria.getVerticalAccuracy());
+
+        criteria.setVerticalAccuracy(Criteria.NO_REQUIREMENT);
+        assertEquals(Criteria.NO_REQUIREMENT, criteria.getVerticalAccuracy());
+    }
+
     public void testWriteToParcel() {
         Criteria criteria = new Criteria();
         criteria.setAltitudeRequired(true);
diff --git a/tests/tests/location/src/android/location/cts/LocationManagerTest.java b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
index 118b8f9..8ac56ae 100644
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -16,7 +16,6 @@
 
 package android.location.cts;
 
-
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.ContentResolver;
@@ -27,6 +26,7 @@
 import android.location.Criteria;
 import android.location.GpsStatus;
 import android.location.GpsStatus.Listener;
+import android.location.GpsStatus.NmeaListener;
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
@@ -36,7 +36,6 @@
 import android.os.Looper;
 import android.os.SystemClock;
 import android.provider.Settings;
-import android.test.InstrumentationTestCase;
 import android.test.UiThreadTest;
 
 import java.util.List;
@@ -48,8 +47,8 @@
  * android.permission.ACCESS_FINE_LOCATION to access GPS provider
  * android.permission.ACCESS_LOCATION_EXTRA_COMMANDS to send extra commands to GPS provider
  */
-public class LocationManagerTest extends InstrumentationTestCase {
-    private static final long TEST_TIME_OUT = 10000;
+public class LocationManagerTest extends BaseMockLocationTest {
+    private static final long TEST_TIME_OUT = 5000;
 
     private static final String TEST_MOCK_PROVIDER_NAME = "test_provider";
 
@@ -72,13 +71,6 @@
 
         mManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
 
-        // test that mock locations are allowed so a more descriptive error message can be logged
-        if (Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 0) {
-            fail("Mock locations are currently disabled in Settings - this test requires "
-                    + "mock locations");
-        }
-
         // remove test provider if left over from an aborted run
         LocationProvider lp = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
         if (lp != null) {
@@ -537,6 +529,358 @@
         }
     }
 
+    public void testSingleUpdateWithLocationListenerAndLooper() throws InterruptedException {
+        double latitude1 = 60;
+        double longitude1 = 20;
+        double latitude2 = 40;
+        double longitude2 = 30;
+        double latitude3 = 10;
+        double longitude3 = 50;
+        final MockLocationListener listener = new MockLocationListener();
+
+        // update location and notify listener
+        HandlerThread handlerThread = new HandlerThread("testLocationUpdates4");
+        handlerThread.start();
+        mManager.requestSingleUpdate(TEST_MOCK_PROVIDER_NAME, listener, handlerThread.getLooper());
+
+        updateLocation(latitude1, longitude1);
+        assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
+        Location location = listener.getLocation();
+        assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+        assertEquals(true, location.isFromMockProvider());
+
+        // Any further location change doesn't trigger an update.
+        updateLocation(latitude2, longitude2);
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+
+        // update location without notifying listener
+        mManager.removeUpdates(listener);
+        listener.reset();
+        updateLocation(latitude3, longitude3);
+        assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
+
+        try {
+            mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, (LocationListener) null,
+                    Looper.myLooper());
+            fail("Should throw IllegalArgumentException if param listener is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.requestSingleUpdate((String) null, listener, Looper.myLooper());
+            fail("Should throw IllegalArgumentException if param provider is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.removeUpdates( (LocationListener) null );
+            fail("Should throw IllegalArgumentException if listener is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    public void testLocationUpdatesWithCriteriaAndPendingIntent() throws InterruptedException {
+        double latitude1 = 10;
+        double longitude1 = 20;
+        double latitude2 = 30;
+        double longitude2 = 40;
+
+        registerIntentReceiver();
+        mockFusedLocation();
+
+        // Update location and receive broadcast.
+        Criteria criteria = createLocationCriteria();
+        mManager.requestLocationUpdates(0, 0 , criteria, mPendingIntent);
+        updateFusedLocation(latitude1, longitude1);
+        waitForReceiveBroadcast();
+
+        assertNotNull(mIntentReceiver.getLastReceivedIntent());
+        Location location = (Location) mIntentReceiver.getLastReceivedIntent().getExtras()
+                .get(LocationManager.KEY_LOCATION_CHANGED);
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+        assertTrue(location.hasAccuracy());
+        assertEquals(1.0f, location.getAccuracy());
+        assertEquals(true, location.isFromMockProvider());
+
+        // Update location without receiving broadcast.
+        mManager.removeUpdates(mPendingIntent);
+        mIntentReceiver.clearReceivedIntents();
+        updateFusedLocation(latitude2, longitude2);
+        waitForReceiveBroadcast();
+        assertNull(mIntentReceiver.getLastReceivedIntent());
+
+        // Missing arguments throw exceptions.
+        try {
+            mManager.requestLocationUpdates(0, 0, criteria, (PendingIntent) null);
+            fail("Should throw IllegalArgumentException if param intent is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.requestLocationUpdates(0, 0, null, mPendingIntent);
+            fail("Should throw IllegalArgumentException if param criteria is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.removeUpdates( (PendingIntent) null );
+            fail("Should throw IllegalArgumentException if param PendingIntent is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        unmockFusedLocation();
+    }
+
+    public void testSingleUpdateWithCriteriaAndPendingIntent() throws InterruptedException {
+        double latitude1 = 10;
+        double longitude1 = 20;
+        double latitude2 = 30;
+        double longitude2 = 40;
+        double latitude3 = 50;
+        double longitude3 = 60;
+
+        registerIntentReceiver();
+        mockFusedLocation();
+
+        // Update location and receive broadcast.
+        Criteria criteria = createLocationCriteria();
+        mManager.requestSingleUpdate(criteria, mPendingIntent);
+        updateFusedLocation(latitude1, longitude1);
+        waitForReceiveBroadcast();
+
+        assertNotNull(mIntentReceiver.getLastReceivedIntent());
+        Location location = (Location) mIntentReceiver.getLastReceivedIntent().getExtras()
+                .get(LocationManager.KEY_LOCATION_CHANGED);
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+        assertTrue(location.hasAccuracy());
+        assertEquals(1.0f, location.getAccuracy());
+        assertEquals(true, location.isFromMockProvider());
+
+        // Any further location change doesn't trigger an update.
+        updateFusedLocation(latitude2, longitude2);
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+
+        // Update location without receiving broadcast.
+        mManager.removeUpdates(mPendingIntent);
+        mIntentReceiver.clearReceivedIntents();
+        updateFusedLocation(latitude3, longitude3);
+        waitForReceiveBroadcast();
+        assertNull(mIntentReceiver.getLastReceivedIntent());
+
+        // Missing arguments throw exceptions.
+        try {
+            mManager.requestSingleUpdate(criteria, (PendingIntent) null);
+            fail("Should throw IllegalArgumentException if param intent is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.requestSingleUpdate((Criteria) null, mPendingIntent);
+            fail("Should throw IllegalArgumentException if param criteria is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.removeUpdates( (PendingIntent) null );
+            fail("Should throw IllegalArgumentException if param PendingIntent is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        unmockFusedLocation();
+    }
+
+    public void testLocationUpdatesWithCriteriaAndLocationListenerAndLooper()
+            throws InterruptedException {
+        double latitude1 = 40;
+        double longitude1 = 10;
+        double latitude2 = 20;
+        double longitude2 = 30;
+       final MockLocationListener listener = new MockLocationListener();
+        mockFusedLocation();
+
+        // update location and notify listener
+        HandlerThread handlerThread = new HandlerThread("testLocationUpdates1");
+        handlerThread.start();
+        Criteria criteria = createLocationCriteria();
+        mManager.requestLocationUpdates(0, 0, criteria, listener, handlerThread.getLooper());
+
+        updateFusedLocation(latitude1, longitude1);
+        assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
+        Location location = listener.getLocation();
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+        assertTrue(location.hasAccuracy());
+        assertEquals(1.0f, location.getAccuracy());
+        assertEquals(true, location.isFromMockProvider());
+
+        // update location without notifying listener
+        mManager.removeUpdates(listener);
+        listener.reset();
+        updateFusedLocation(latitude2, longitude2);
+        assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
+
+        // Missing arguments throw exceptions.
+        try {
+            mManager.requestLocationUpdates(0, 0, criteria, (LocationListener) null,
+                    Looper.myLooper());
+            fail("Should throw IllegalArgumentException if param listener is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.requestLocationUpdates(0, 0, null, listener, Looper.myLooper());
+            fail("Should throw IllegalArgumentException if param criteria is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.removeUpdates( (LocationListener) null );
+            fail("Should throw IllegalArgumentException if listener is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        unmockFusedLocation();
+    }
+
+    public void testSingleUpdateWithCriteriaAndLocationListenerAndLooper()
+            throws InterruptedException {
+        double latitude1 = 40;
+        double longitude1 = 10;
+        double latitude2 = 20;
+        double longitude2 = 30;
+        double latitude3 = 60;
+        double longitude3 = 50;
+        final MockLocationListener listener = new MockLocationListener();
+        mockFusedLocation();
+
+        // update location and notify listener
+        HandlerThread handlerThread = new HandlerThread("testLocationUpdates2");
+        handlerThread.start();
+        Criteria criteria = createLocationCriteria();
+        mManager.requestSingleUpdate(criteria, listener, handlerThread.getLooper());
+
+        updateFusedLocation(latitude1, longitude1);
+        assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
+        Location location = listener.getLocation();
+        assertEquals(FUSED_PROVIDER_NAME, location.getProvider());
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+        assertTrue(location.hasAccuracy());
+        assertEquals(1.0f, location.getAccuracy());
+        assertEquals(true, location.isFromMockProvider());
+
+        // Any further location change doesn't trigger an update.
+        updateFusedLocation(latitude2, longitude2);
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+
+        // update location without notifying listener
+        mManager.removeUpdates(listener);
+        listener.reset();
+        updateFusedLocation(latitude3, longitude3);
+        assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
+
+        // Missing arguments throw exceptions.
+        try {
+            mManager.requestLocationUpdates(0, 0, criteria, (LocationListener) null,
+                    Looper.myLooper());
+            fail("Should throw IllegalArgumentException if param listener is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.requestLocationUpdates(0, 0, null, listener, Looper.myLooper());
+            fail("Should throw IllegalArgumentException if param criteria is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.removeUpdates( (LocationListener) null );
+            fail("Should throw IllegalArgumentException if listener is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        unmockFusedLocation();
+    }
+
+    public void testSingleUpdateWithPendingIntent() throws InterruptedException {
+        double latitude1 = 20;
+        double longitude1 = 40;
+        double latitude2 = 30;
+        double longitude2 = 50;
+        double latitude3 = 10;
+        double longitude3 = 60;
+
+        // update location and receive broadcast.
+        registerIntentReceiver();
+        mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent);
+        updateLocation(latitude1, longitude1);
+        waitForReceiveBroadcast();
+
+        assertNotNull(mIntentReceiver.getLastReceivedIntent());
+        Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME);
+        assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+        assertEquals(true, location.isFromMockProvider());
+
+        // Any further location change doesn't trigger an update.
+        updateLocation(latitude2, longitude2);
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+
+        // update location without receiving broadcast.
+        mManager.removeUpdates(mPendingIntent);
+        mIntentReceiver.clearReceivedIntents();
+        updateLocation(latitude3, longitude3);
+        waitForReceiveBroadcast();
+        assertEquals(latitude1, location.getLatitude());
+        assertEquals(longitude1, location.getLongitude());
+
+        try {
+            mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
+                    (PendingIntent) null);
+            fail("Should throw IllegalArgumentException if param intent is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.requestLocationUpdates(null, 0, 0, mPendingIntent);
+            fail("Should throw IllegalArgumentException if param provider is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+
+        try {
+            mManager.removeUpdates( (PendingIntent) null );
+            fail("Should throw IllegalArgumentException if intent is null!");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
     public void testAddProximityAlert() {
         Intent i = new Intent();
         i.setAction("android.location.cts.TEST_GET_GPS_STATUS_ACTION");
@@ -546,6 +890,17 @@
         mManager.removeProximityAlert(pi);
     }
 
+
+    @UiThreadTest
+    public void testNmeaListener() {
+        MockNmeaListener listener = new MockNmeaListener();
+        mManager.addNmeaListener(listener);
+        mManager.removeNmeaListener(listener);
+
+        mManager.addNmeaListener(null);
+        mManager.removeNmeaListener(null);
+    }
+
     public void testIsProviderEnabled() {
         // this test assumes enabled TEST_MOCK_PROVIDER_NAME was created in setUp.
         assertNotNull(mManager.getProvider(TEST_MOCK_PROVIDER_NAME));
@@ -840,6 +1195,21 @@
         updateLocation(TEST_MOCK_PROVIDER_NAME, latitude, longitude);
     }
 
+    private void updateFusedLocation(final double latitude, final double longitude) {
+      updateLocation(FUSED_PROVIDER_NAME, latitude, longitude);
+ }
+
+    private Criteria createLocationCriteria() {
+        Criteria criteria = new Criteria();
+        criteria.setAccuracy(Criteria.ACCURACY_FINE);
+        criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
+        criteria.setAltitudeRequired(false);
+        criteria.setBearingRequired(false);
+        criteria.setCostAllowed(false);
+        criteria.setSpeedRequired(false);
+        return criteria;
+     }
+
     private void mockFusedLocation() {
         addTestProvider(FUSED_PROVIDER_NAME);
     }
@@ -1003,6 +1373,23 @@
         }
     }
 
+    private static class MockNmeaListener implements NmeaListener {
+        private boolean mIsNmeaReceived;
+
+        @Override
+        public void onNmeaReceived(long timestamp, String nmea) {
+            mIsNmeaReceived = true;
+        }
+
+        public boolean isNmeaRecevied() {
+            return mIsNmeaReceived;
+        }
+
+        public void reset() {
+            mIsNmeaReceived = false;
+        }
+    }
+
     private static class MockGpsStatusListener implements Listener {
         private boolean mHasCallOnGpsStatusChanged;
 
diff --git a/tests/tests/location/src/android/location/cts/LocationProviderTest.java b/tests/tests/location/src/android/location/cts/LocationProviderTest.java
index 716801d..1e6feda 100644
--- a/tests/tests/location/src/android/location/cts/LocationProviderTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationProviderTest.java
@@ -16,14 +16,11 @@
 
 package android.location.cts;
 
-
-import android.content.Context;
 import android.location.Criteria;
 import android.location.LocationManager;
 import android.location.LocationProvider;
-import android.test.AndroidTestCase;
 
-public class LocationProviderTest extends AndroidTestCase {
+public class LocationProviderTest extends BaseMockLocationTest {
     private static final String PROVIDER_NAME = "location_provider_test";
 
     private LocationManager mLocationManager;
@@ -31,8 +28,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mLocationManager =
-            (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
+        mLocationManager = getInstrumentation().getContext().getSystemService(
+                LocationManager.class);
         addTestProvider(PROVIDER_NAME);
     }
 
diff --git a/tests/tests/location/src/android/location/cts/LocationTest.java b/tests/tests/location/src/android/location/cts/LocationTest.java
index f037109..db2820c 100644
--- a/tests/tests/location/src/android/location/cts/LocationTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationTest.java
@@ -16,8 +16,15 @@
 
 package android.location.cts;
 
-
+import android.content.Context;
+import android.content.Intent;
 import android.location.Location;
+import android.location.SettingInjectorService;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
@@ -41,6 +48,9 @@
     private final boolean TEST_KEY1VALUE = false;
     private final byte TEST_KEY2VALUE = 10;
 
+    private static final String ENABLED_KEY = "enabled";
+    private static final String MESSENGER_KEY = "messenger";
+
     public void testConstructor() {
         new Location("LocationProvider");
 
@@ -407,6 +417,56 @@
         assertTestLocation(newLocation);
     }
 
+    public void testSettingInjectorService() {
+        Context c = getContext();
+        SettingInjectorServiceDerived service = new SettingInjectorServiceDerived();
+
+        assertNotNull(c);
+
+        Intent intent =
+            new Intent(c, android.location.SettingInjectorService.class);
+
+        assertNotNull(c.getMainLooper());
+        SettingInjectorResultHandler resultHandler =
+            new SettingInjectorResultHandler(c.getMainLooper());
+
+        Messenger m = new Messenger(resultHandler);
+        intent.putExtra(MESSENGER_KEY, m);
+
+        int ret;
+        final long timeout = 500;
+
+        // should refuse binding
+        IBinder binder = service.callOnBind(intent);
+        assertNull("onBind should always fail.", binder);
+
+        // test if result consistent with the truth
+        // enabled == false case
+        service.setEnabled(false);
+        resultHandler.expectEnabled(false);
+        resultHandler.expectMessage(true);
+        ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0);
+        assertEquals("onStartCommand return value invalid in (enabled == false) case.",
+            ret, SettingInjectorService.START_NOT_STICKY);
+        assertTrue("Message time out in (enabled == false case).",
+            resultHandler.waitForMessage(timeout));
+
+        // enabled == true case
+        service.setEnabled(true);
+        resultHandler.expectEnabled(true);
+        resultHandler.expectMessage(true);
+        ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0);
+        assertEquals("onStartCommand return value invalid in (enabled == true) case.",
+            ret, SettingInjectorService.START_NOT_STICKY);
+        assertTrue("Message time out in (enabled == true) case.",
+            resultHandler.waitForMessage(timeout));
+
+        // should not respond to the deprecated method
+        resultHandler.expectMessage(false);
+        service.callOnStart(intent, 0);
+        resultHandler.waitForMessage(timeout);
+    }
+
     private void assertTestLocation(Location l) {
         assertNotNull(l);
         assertEquals(TEST_PROVIDER, l.getProvider());
@@ -441,4 +501,93 @@
         assertFalse(bundle.getBoolean(TEST_KEY1NAME));
         assertEquals(TEST_KEY2VALUE, bundle.getByte(TEST_KEY2NAME));
     }
+
+    private class SettingInjectorResultHandler extends Handler {
+        private boolean mEnabledShouldBe;
+        private boolean mExpectingMessage;
+        private boolean mMessageArrived;
+
+        SettingInjectorResultHandler(Looper l) {
+            super(l);
+        }
+
+        @Override
+        public void handleMessage(Message m) {
+
+            assertTrue("Unexpected message.", mExpectingMessage);
+
+            boolean enabled = m.getData().getBoolean(ENABLED_KEY);
+
+            assertEquals(String.format(
+                    "Message value (%s) inconsistent with service state (%s).",
+                    String.valueOf(enabled), String.valueOf(mEnabledShouldBe) ),
+                    mEnabledShouldBe, enabled);
+
+            synchronized (this) {
+                mMessageArrived = true;
+                notify();
+            }
+        }
+
+        public void expectEnabled(boolean enabled) {
+            mEnabledShouldBe = enabled;
+        }
+
+        public void expectMessage(boolean expecting) {
+            mMessageArrived = false;
+            mExpectingMessage = expecting;
+        }
+
+        public synchronized boolean waitForMessage(long millis) {
+            synchronized (this) {
+                try {
+                    wait(millis);
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+                return mMessageArrived;
+            }
+        }
+    }
+
+
+    private class SettingInjectorServiceDerived extends SettingInjectorService {
+
+        private boolean mEnabled;
+
+        SettingInjectorServiceDerived() {
+            super("SettingInjectorServiceDerived");
+            setEnabled(false);
+        }
+
+        @Override
+        // Deprecated API
+        protected String onGetSummary() {
+            return "";
+        }
+
+        @Override
+        protected boolean onGetEnabled() {
+            return mEnabled;
+        }
+
+        public void setEnabled(boolean enabled) {
+            mEnabled = enabled;
+        }
+
+        // API coverage dashboard will not cound 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);
+        }
+
+        public void callOnStart(Intent intent, int startId) {
+            super.onStart(intent, startId);
+        }
+
+        public int callOnStartCommand(Intent intent, int flags, int startId) {
+            return super.onStartCommand(intent, flags, startId);
+        }
+    }
+
 }
diff --git a/tests/tests/location2/AndroidManifest.xml b/tests/tests/location2/AndroidManifest.xml
index ad77b7e..b2e0802 100644
--- a/tests/tests/location2/AndroidManifest.xml
+++ b/tests/tests/location2/AndroidManifest.xml
@@ -23,7 +23,6 @@
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
 
diff --git a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
index b298b97..6764223 100644
--- a/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
+++ b/tests/tests/location2/src/android/location2/cts/LocationManagerTest.java
@@ -16,31 +16,29 @@
 
 package android.location2.cts;
 
-
 import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.PackageManager;
 import android.location.Criteria;
-import android.location.GpsStatus;
 import android.location.GpsStatus.Listener;
 import android.location.GpsStatus.NmeaListener;
 import android.location.Location;
 import android.location.LocationListener;
 import android.location.LocationManager;
-import android.location.LocationProvider;
 import android.os.Bundle;
 import android.os.HandlerThread;
-import android.os.Looper;
+import android.os.ParcelFileDescriptor;
 import android.os.SystemClock;
-import android.provider.Settings;
 import android.test.InstrumentationTestCase;
 import android.test.UiThreadTest;
+import android.util.Log;
 
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.List;
-import java.lang.Thread;
 
 /**
  * Requires the permissions
@@ -50,6 +48,8 @@
  */
 public class LocationManagerTest extends InstrumentationTestCase {
 
+    public static final String LOG_TAG = "LocationManagerTest";
+
     private static final long TEST_TIME_OUT_MS = 10 * 1000;
 
     private static final double LAT = 10.0;
@@ -71,12 +71,13 @@
 
         mManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
 
-        // test that mock locations are allowed so a more descriptive error message can be logged
-        if (Settings.Secure.getInt(mContext.getContentResolver(),
-                Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 0) {
-            fail("Mock locations are currently disabled in Settings - this test requires "
-                    + "mock locations");
-        }
+        setAsMoskLocationProvider(true);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        setAsMoskLocationProvider(false);
+        super.tearDown();
     }
 
     public void testGetGpsProvider_notAllowed() {
@@ -319,6 +320,25 @@
         mManager.setTestProviderLocation(providerName, location);
     }
 
+    private void setAsMoskLocationProvider(boolean enable) {
+        StringBuilder command = new StringBuilder();
+        command.append("appops set ");
+        command.append(getInstrumentation().getContext().getPackageName());
+        command.append(" android:mock_location ");
+        command.append(enable ? "allow" : "deny");
+
+        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                .executeShellCommand(command.toString());
+
+        InputStream is = new FileInputStream(pfd.getFileDescriptor());
+        try {
+            final byte[] buffer = new byte[8192];
+            while ((is.read(buffer)) != -1);
+        } catch (IOException e) {
+            Log.e(LOG_TAG, "Error managing mock locaiton app", e);
+        }
+    }
+
     /**
      * Helper class that receives a proximity intent and notifies the main class
      * when received
diff --git a/tests/tests/media/Android.mk b/tests/tests/media/Android.mk
index 77d4bb7f..ea7256d 100644
--- a/tests/tests/media/Android.mk
+++ b/tests/tests/media/Android.mk
@@ -41,7 +41,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     ctsmediautil ctsdeviceutil ctstestserver ctstestrunner
 
-LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni
+LOCAL_JNI_SHARED_LIBRARIES := libctsmediacodec_jni libaudio_jni
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
@@ -49,7 +49,9 @@
 
 # uncomment when b/13249737 is fixed
 #LOCAL_SDK_VERSION := current
-LOCAL_JAVA_LIBRARIES += android.test.runner
+LOCAL_JAVA_LIBRARIES += android.test.runner org.apache.http.legacy
+
+cts_runtime_hint := 265
 
 include $(BUILD_CTS_PACKAGE)
 
diff --git a/tests/tests/media/AndroidManifest.xml b/tests/tests/media/AndroidManifest.xml
index 32df531..cdc0e60 100644
--- a/tests/tests/media/AndroidManifest.xml
+++ b/tests/tests/media/AndroidManifest.xml
@@ -28,6 +28,7 @@
 
     <application>
         <uses-library android:name="android.test.runner" />
+        <uses-library android:name="org.apache.http.legacy" android:required="false" />
 
         <activity android:name="android.media.cts.AudioManagerStub"
             android:label="AudioManagerStub"/>
@@ -51,6 +52,21 @@
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
             </intent-filter>
         </activity>
+        <activity android:name="android.media.cts.ResourceManagerStubActivity"
+            android:label="ResourceManagerStubActivity">
+            <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.ResourceManagerTestActivity1"
+            android:label="ResourceManagerTestActivity1"
+            android:process=":mediaCodecTestProcess1">
+        </activity>
+        <activity android:name="android.media.cts.ResourceManagerTestActivity2"
+            android:label="ResourceManagerTestActivity2"
+            android:process=":mediaCodecTestProcess2">
+        </activity>
         <activity android:name="android.media.cts.RingtonePickerActivity"
             android:label="RingtonePickerActivity">
             <intent-filter>
diff --git a/tests/tests/media/assets/fileSequence0.ts b/tests/tests/media/assets/fileSequence0.ts
new file mode 100644
index 0000000..48f2bcd
--- /dev/null
+++ b/tests/tests/media/assets/fileSequence0.ts
Binary files differ
diff --git a/tests/tests/media/assets/fileSequence1.ts b/tests/tests/media/assets/fileSequence1.ts
new file mode 100644
index 0000000..737fbd0
--- /dev/null
+++ b/tests/tests/media/assets/fileSequence1.ts
Binary files differ
diff --git a/tests/tests/media/assets/prog_index.m3u8 b/tests/tests/media/assets/prog_index.m3u8
new file mode 100644
index 0000000..88f99d3
--- /dev/null
+++ b/tests/tests/media/assets/prog_index.m3u8
@@ -0,0 +1,10 @@
+#EXTM3U
+#EXT-X-TARGETDURATION:10
+#EXT-X-VERSION:3
+#EXT-X-MEDIA-SEQUENCE:0
+#EXT-X-PLAYLIST-TYPE:VOD
+#EXTINF:9.90000,
+fileSequence0.ts
+#EXTINF:10.00000,
+fileSequence1.ts
+#EXT-X-ENDLIST
diff --git a/tests/tests/media/libaudiojni/Android.mk b/tests/tests/media/libaudiojni/Android.mk
new file mode 100644
index 0000000..a6c1bfc
--- /dev/null
+++ b/tests/tests/media/libaudiojni/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)
+
+LOCAL_MODULE    := libaudio_jni
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+	appendix-b-1-1-buffer-queue.cpp \
+	appendix-b-1-2-recording.cpp \
+	audio-record-native.cpp \
+	audio-track-native.cpp \
+	sl-utils.cpp
+
+LOCAL_C_INCLUDES := \
+	$(JNI_H_INCLUDE) \
+	system/core/include
+
+LOCAL_C_INCLUDES += $(call include-path-for, libaudiojni) \
+	$(call include-path-for, wilhelm)
+
+LOCAL_SHARED_LIBRARIES := libandroid liblog libnativehelper libOpenSLES libutils
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/media/libaudiojni/Blob.h b/tests/tests/media/libaudiojni/Blob.h
new file mode 100644
index 0000000..134232c
--- /dev/null
+++ b/tests/tests/media/libaudiojni/Blob.h
@@ -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.
+ */
+
+#ifndef ANDROID_BLOB_H
+#define ANDROID_BLOB_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace android {
+
+// read only byte buffer like object
+
+class BlobReadOnly {
+public:
+    BlobReadOnly(const void *data, size_t size, bool byReference) :
+        mMem(byReference ? NULL : malloc(size)),
+        mData(byReference ? data : mMem),
+        mSize(size) {
+        if (!byReference) {
+            memcpy(mMem, data, size);
+        }
+    }
+    ~BlobReadOnly() {
+        free(mMem);
+    }
+
+private:
+          void * const mMem;
+
+public:
+    const void * const mData;
+          const size_t mSize;
+};
+
+// read/write byte buffer like object
+
+class Blob {
+public:
+    Blob(size_t size) :
+        mData(malloc(size)),
+        mOffset(0),
+        mSize(size),
+        mMem(mData) { }
+
+    // by reference
+    Blob(void *data, size_t size) :
+        mData(data),
+        mOffset(0),
+        mSize(size),
+        mMem(NULL) { }
+
+    ~Blob() {
+        free(mMem);
+    }
+
+    void * const mData;
+          size_t mOffset;
+    const size_t mSize;
+
+private:
+    void * const mMem;
+};
+
+} // namespace android
+
+#endif // ANDROID_BLOB_H
diff --git a/tests/tests/media/libaudiojni/Gate.h b/tests/tests/media/libaudiojni/Gate.h
new file mode 100644
index 0000000..dfc15b7
--- /dev/null
+++ b/tests/tests/media/libaudiojni/Gate.h
@@ -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.
+ */
+
+#ifndef ANDROID_GATE_H
+#define ANDROID_GATE_H
+
+#include <stdint.h>
+#include <mutex>
+
+namespace android {
+
+// Gate is a synchronization object.
+//
+// Threads will pass if it is open.
+// Threads will block (wait) if it is closed.
+//
+// When a gate is opened, all waiting threads will pass through.
+//
+// Since gate holds no external locks, consistency with external
+// state needs to be handled elsewhere.
+//
+// We use mWaitCount to indicate the number of threads that have
+// arrived at the gate via wait().  Each thread entering
+// wait obtains a unique waitId (which is the current mWaitCount).
+// This can be viewed as a sequence number.
+//
+// We use mPassCount to indicate the number of threads that have
+// passed the gate.  If the waitId is less than or equal to the mPassCount
+// then that thread has passed the gate.  An open gate sets mPassedCount
+// to the current mWaitCount, allowing all prior threads to pass.
+//
+// See sync_timeline, sync_pt, etc. for graphics.
+
+class Gate {
+public:
+    Gate(bool open = false) :
+        mOpen(open),
+        mExit(false),
+        mWaitCount(0),
+        mPassCount(0)
+    { }
+
+    // waits for the gate to open, returns immediately if gate is already open.
+    //
+    // Do not hold a monitor lock while calling this.
+    //
+    // returns true if we passed the gate normally
+    //         false if gate is terminated and we didn't pass the gate.
+    bool wait() {
+        std::unique_lock<std::mutex> l(mLock);
+        size_t waitId = ++mWaitCount;
+        if (mOpen) {
+            mPassCount = waitId; // let me through
+        }
+        while (!passedGate_l(waitId) && !mExit) {
+            mCondition.wait(l);
+        }
+        return passedGate_l(waitId);
+    }
+
+    // close the gate.
+    void closeGate() {
+        std::lock_guard<std::mutex> l(mLock);
+        mOpen = false;
+        mExit = false;
+    }
+
+    // open the gate.
+    // signal to all waiters it is okay to go.
+    void openGate() {
+        std::lock_guard<std::mutex> l(mLock);
+        mOpen = true;
+        mExit = false;
+        if (waiters_l() > 0) {
+            mPassCount = mWaitCount;  // allow waiting threads to go through
+            // unoptimized pthreads will wake thread to find we still hold lock.
+            mCondition.notify_all();
+        }
+    }
+
+    // terminate (term has expired).
+    // all threads allowed to pass regardless of whether the gate is open or closed.
+    void terminate() {
+        std::lock_guard<std::mutex> l(mLock);
+        mExit = true;
+        if (waiters_l() > 0) {
+            // unoptimized pthreads will wake thread to find we still hold lock.
+            mCondition.notify_all();
+        }
+    }
+
+    bool isOpen() {
+        std::lock_guard<std::mutex> l(mLock);
+        return mOpen;
+    }
+
+    // return how many waiters are at the gate.
+    size_t waiters() {
+        std::lock_guard<std::mutex> l(mLock);
+        return waiters_l();
+    }
+
+private:
+    bool                    mOpen;
+    bool                    mExit;
+    size_t                  mWaitCount;  // total number of threads that have called wait()
+    size_t                  mPassCount;  // total number of threads passed the gate.
+    std::condition_variable mCondition;
+    std::mutex              mLock;
+
+    // return how many waiters are at the gate.
+    inline size_t waiters_l() {
+        return mWaitCount - mPassCount;
+    }
+
+    // return whether the waitId (from mWaitCount) has passed through the gate
+    inline bool passedGate_l(size_t waitId) {
+        return (ssize_t)(waitId - mPassCount) <= 0;
+    }
+};
+
+} // namespace android
+
+#endif // ANDROID_GATE_H
diff --git a/tests/tests/media/libaudiojni/appendix-b-1-1-buffer-queue.cpp b/tests/tests/media/libaudiojni/appendix-b-1-1-buffer-queue.cpp
new file mode 100644
index 0000000..5bb88a7
--- /dev/null
+++ b/tests/tests/media/libaudiojni/appendix-b-1-1-buffer-queue.cpp
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "OpenSL-ES-Test-B-1-1-Buffer-Queue"
+
+#include "sl-utils.h"
+
+/*
+ * See https://www.khronos.org/registry/sles/specs/OpenSL_ES_Specification_1.0.1.pdf
+ * Appendix B.1.1 sample code.
+ *
+ * Minor edits made to conform to Android coding style.
+ *
+ * Correction to code: SL_IID_VOLUME is now made optional for the mixer.
+ * It isn't supported on the standard Android mixer, but it is supported on the player.
+ */
+
+#define MAX_NUMBER_INTERFACES 3
+
+/* Local storage for Audio data in 16 bit words */
+#define AUDIO_DATA_STORAGE_SIZE 4096
+
+#define AUDIO_DATA_SEGMENTS 8
+
+/* Audio data buffer size in 16 bit words. 8 data segments are used in
+   this simple example */
+#define AUDIO_DATA_BUFFER_SIZE (AUDIO_DATA_STORAGE_SIZE / AUDIO_DATA_SEGMENTS)
+
+/* Structure for passing information to callback function */
+typedef struct  {
+    SLPlayItf playItf;
+    SLint16  *pDataBase; // Base address of local audio data storage
+    SLint16  *pData;     // Current address of local audio data storage
+    SLuint32  size;
+} CallbackCntxt;
+
+/* Local storage for Audio data */
+static SLint16 pcmData[AUDIO_DATA_STORAGE_SIZE];
+
+/* Callback for Buffer Queue events */
+static void BufferQueueCallback(
+        SLBufferQueueItf queueItf,
+        void *pContext)
+{
+    SLresult res;
+    CallbackCntxt *pCntxt = (CallbackCntxt*)pContext;
+    if (pCntxt->pData < (pCntxt->pDataBase + pCntxt->size)) {
+        res = (*queueItf)->Enqueue(queueItf, (void *)pCntxt->pData,
+                sizeof(SLint16) * AUDIO_DATA_BUFFER_SIZE); /* Size given in bytes. */
+        ALOGE_IF(res != SL_RESULT_SUCCESS, "error: %s", android::getSLErrStr(res));
+        /* Increase data pointer by buffer size */
+        pCntxt->pData += AUDIO_DATA_BUFFER_SIZE;
+    }
+}
+
+/* Play some music from a buffer queue */
+static void TestPlayMusicBufferQueue(SLObjectItf sl)
+{
+    SLEngineItf EngineItf;
+
+    SLresult res;
+
+    SLDataSource audioSource;
+    SLDataLocator_BufferQueue bufferQueue;
+    SLDataFormat_PCM pcm;
+
+    SLDataSink audioSink;
+    SLDataLocator_OutputMix locator_outputmix;
+
+    SLObjectItf player;
+    SLPlayItf playItf;
+    SLBufferQueueItf bufferQueueItf;
+    SLBufferQueueState state;
+
+    SLObjectItf OutputMix;
+    SLVolumeItf volumeItf;
+
+    int i;
+
+    SLboolean required[MAX_NUMBER_INTERFACES];
+    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
+
+    /* Callback context for the buffer queue callback function */
+    CallbackCntxt cntxt;
+
+    /* Get the SL Engine Interface which is implicit */
+    res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void *)&EngineItf);
+    CheckErr(res);
+
+    /* Initialize arrays required[] and iidArray[] */
+    for (i = 0; i < MAX_NUMBER_INTERFACES; i++) {
+        required[i] = SL_BOOLEAN_FALSE;
+        iidArray[i] = SL_IID_NULL;
+    }
+
+    // Set arrays required[] and iidArray[] for VOLUME interface
+    required[0] = SL_BOOLEAN_FALSE; // ANDROID: we don't require this interface
+    iidArray[0] = SL_IID_VOLUME;
+
+#if 0
+    const unsigned interfaces = 1;
+#else
+
+    /* FIXME: Android doesn't properly support optional interfaces (required == false).
+    [3.1.6] When an application requests explicit interfaces during object creation,
+    it can flag any interface as required. If an implementation is unable to satisfy
+    the request for an interface that is not flagged as required (i.e. it is not required),
+    this will not cause the object to fail creation. On the other hand, if the interface
+    is flagged as required and the implementation is unable to satisfy the request
+    for the interface, the object will not be created.
+    */
+    const unsigned interfaces = 0;
+#endif
+    // Create Output Mix object to be used by player
+    res = (*EngineItf)->CreateOutputMix(EngineItf, &OutputMix, interfaces,
+            iidArray, required);
+    CheckErr(res);
+
+    // Realizing the Output Mix object in synchronous mode.
+    res = (*OutputMix)->Realize(OutputMix, SL_BOOLEAN_FALSE);
+    CheckErr(res);
+
+    volumeItf = NULL; // ANDROID: Volume interface on mix object may not be supported
+    res = (*OutputMix)->GetInterface(OutputMix, SL_IID_VOLUME,
+            (void *)&volumeItf);
+
+    /* Setup the data source structure for the buffer queue */
+    bufferQueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
+    bufferQueue.numBuffers = 4; /* Four buffers in our buffer queue */
+
+    /* Setup the format of the content in the buffer queue */
+    pcm.formatType = SL_DATAFORMAT_PCM;
+    pcm.numChannels = 2;
+    pcm.samplesPerSec = SL_SAMPLINGRATE_44_1;
+    pcm.bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16;
+    pcm.containerSize = 16;
+    pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
+    pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
+    audioSource.pFormat = (void *)&pcm;
+    audioSource.pLocator = (void *)&bufferQueue;
+
+    /* Setup the data sink structure */
+    locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
+    locator_outputmix.outputMix = OutputMix;
+    audioSink.pLocator = (void *)&locator_outputmix;
+    audioSink.pFormat = NULL;
+
+    /* Initialize the context for Buffer queue callbacks */
+    cntxt.pDataBase = pcmData;
+    cntxt.pData = cntxt.pDataBase;
+    cntxt.size = sizeof(pcmData) / sizeof(pcmData[0]); // ANDROID: Bug
+
+    /* Set arrays required[] and iidArray[] for SEEK interface
+       (PlayItf is implicit) */
+    required[0] = SL_BOOLEAN_TRUE;
+    iidArray[0] = SL_IID_BUFFERQUEUE;
+
+    /* Create the music player */
+
+    res = (*EngineItf)->CreateAudioPlayer(EngineItf, &player,
+            &audioSource, &audioSink, 1, iidArray, required);
+    CheckErr(res);
+
+    /* Realizing the player in synchronous mode. */
+    res = (*player)->Realize(player, SL_BOOLEAN_FALSE);
+    CheckErr(res);
+
+    /* Get seek and play interfaces */
+    res = (*player)->GetInterface(player, SL_IID_PLAY, (void *)&playItf);
+    CheckErr(res);
+    res = (*player)->GetInterface(player, SL_IID_BUFFERQUEUE,
+            (void *)&bufferQueueItf);
+    CheckErr(res);
+
+    /* Setup to receive buffer queue event callbacks */
+    res = (*bufferQueueItf)->RegisterCallback(bufferQueueItf,
+            BufferQueueCallback, &cntxt /* BUG, was NULL */);
+    CheckErr(res);
+
+    /* Before we start set volume to -3dB (-300mB) */
+    if (volumeItf != NULL) { // ANDROID: Volume interface may not be supported.
+        res = (*volumeItf)->SetVolumeLevel(volumeItf, -300);
+        CheckErr(res);
+    }
+
+    /* Enqueue a few buffers to get the ball rolling */
+    res = (*bufferQueueItf)->Enqueue(bufferQueueItf, cntxt.pData,
+            sizeof(SLint16) * AUDIO_DATA_BUFFER_SIZE); /* Size given in bytes. */
+    CheckErr(res);
+    cntxt.pData += AUDIO_DATA_BUFFER_SIZE;
+    res = (*bufferQueueItf)->Enqueue(bufferQueueItf, cntxt.pData,
+            sizeof(SLint16) * AUDIO_DATA_BUFFER_SIZE); /* Size given in bytes. */
+    CheckErr(res);
+    cntxt.pData += AUDIO_DATA_BUFFER_SIZE;
+    res = (*bufferQueueItf)->Enqueue(bufferQueueItf, cntxt.pData,
+            sizeof(SLint16) * AUDIO_DATA_BUFFER_SIZE); /* Size given in bytes. */
+    CheckErr(res);
+    cntxt.pData += AUDIO_DATA_BUFFER_SIZE;
+
+    /* Play the PCM samples using a buffer queue */
+    res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
+    CheckErr(res);
+
+    /* Wait until the PCM data is done playing, the buffer queue callback
+       will continue to queue buffers until the entire PCM data has been
+       played. This is indicated by waiting for the count member of the
+       SLBufferQueueState to go to zero.
+     */
+    res = (*bufferQueueItf)->GetState(bufferQueueItf, &state);
+    CheckErr(res);
+
+    while (state.count) {
+        usleep(5 * 1000 /* usec */); // ANDROID: avoid busy waiting
+        (*bufferQueueItf)->GetState(bufferQueueItf, &state);
+    }
+
+    /* Make sure player is stopped */
+    res = (*playItf)->SetPlayState(playItf, SL_PLAYSTATE_STOPPED);
+    CheckErr(res);
+
+    /* Destroy the player */
+    (*player)->Destroy(player);
+
+    /* Destroy Output Mix object */
+    (*OutputMix)->Destroy(OutputMix);
+}
+
+extern "C" void Java_android_media_cts_AudioNativeTest_nativeAppendixBBufferQueue(
+        JNIEnv * /* env */, jclass /* clazz */)
+{
+    SLObjectItf engineObject = android::OpenSLEngine();
+    LOG_ALWAYS_FATAL_IF(engineObject == NULL, "cannot open OpenSL ES engine");
+
+    TestPlayMusicBufferQueue(engineObject);
+    android::CloseSLEngine(engineObject);
+}
diff --git a/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp b/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp
new file mode 100644
index 0000000..5f6f3aa
--- /dev/null
+++ b/tests/tests/media/libaudiojni/appendix-b-1-2-recording.cpp
@@ -0,0 +1,221 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "OpenSL-ES-Test-B-1-2-Recording"
+
+#include "sl-utils.h"
+
+/*
+ * See https://www.khronos.org/registry/sles/specs/OpenSL_ES_Specification_1.0.1.pdf
+ * Appendix B.1.2 sample code.
+ *
+ * Minor edits made to conform to Android coding style.
+ *
+ * Correction to code: SL_IID_AUDIOIODEVICECAPABILITIES is not supported.
+ * Detection of microphone should be made in Java layer.
+ */
+
+#define MAX_NUMBER_INTERFACES 5
+#define MAX_NUMBER_INPUT_DEVICES 3
+#define POSITION_UPDATE_PERIOD 1000 /* 1 sec */
+
+static void RecordEventCallback(SLRecordItf caller __unused,
+        void *pContext __unused,
+        SLuint32 recordevent __unused)
+{
+    /* Callback code goes here */
+}
+
+/*
+ * Test recording of audio from a microphone into a specified file
+ */
+static void TestAudioRecording(SLObjectItf sl)
+{
+    SLObjectItf recorder;
+    SLRecordItf recordItf;
+    SLEngineItf EngineItf;
+    SLAudioIODeviceCapabilitiesItf AudioIODeviceCapabilitiesItf;
+    SLAudioInputDescriptor AudioInputDescriptor;
+    SLresult res;
+
+    SLDataSource audioSource;
+    SLDataLocator_IODevice locator_mic;
+    SLDeviceVolumeItf devicevolumeItf;
+    SLDataSink audioSink;
+    SLDataLocator_URI uri;
+    SLDataFormat_MIME mime;
+
+    int i;
+    SLboolean required[MAX_NUMBER_INTERFACES];
+    SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
+
+    SLuint32 InputDeviceIDs[MAX_NUMBER_INPUT_DEVICES];
+    SLint32 numInputs = 0;
+    SLboolean mic_available = SL_BOOLEAN_FALSE;
+    SLuint32 mic_deviceID = 0;
+
+    /* Get the SL Engine Interface which is implicit */
+    res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void *)&EngineItf);
+    CheckErr(res);
+
+    AudioIODeviceCapabilitiesItf = NULL;
+    /* Get the Audio IO DEVICE CAPABILITIES interface, which is also
+       implicit */
+    res = (*sl)->GetInterface(sl, SL_IID_AUDIOIODEVICECAPABILITIES,
+            (void *)&AudioIODeviceCapabilitiesItf);
+    // ANDROID: obtaining SL_IID_AUDIOIODEVICECAPABILITIES may fail
+    if (AudioIODeviceCapabilitiesItf != NULL ) {
+        numInputs = MAX_NUMBER_INPUT_DEVICES;
+        res = (*AudioIODeviceCapabilitiesItf)->GetAvailableAudioInputs(
+                AudioIODeviceCapabilitiesItf, &numInputs, InputDeviceIDs);
+        CheckErr(res);
+        /* Search for either earpiece microphone or headset microphone input
+           device - with a preference for the latter */
+        for (i = 0; i < numInputs; i++) {
+            res = (*AudioIODeviceCapabilitiesItf)->QueryAudioInputCapabilities(
+                    AudioIODeviceCapabilitiesItf, InputDeviceIDs[i], &AudioInputDescriptor);
+            CheckErr(res);
+            if ((AudioInputDescriptor.deviceConnection == SL_DEVCONNECTION_ATTACHED_WIRED)
+                    && (AudioInputDescriptor.deviceScope == SL_DEVSCOPE_USER)
+                    && (AudioInputDescriptor.deviceLocation == SL_DEVLOCATION_HEADSET)) {
+                mic_deviceID = InputDeviceIDs[i];
+                mic_available = SL_BOOLEAN_TRUE;
+                break;
+            }
+            else if ((AudioInputDescriptor.deviceConnection == SL_DEVCONNECTION_INTEGRATED)
+                    && (AudioInputDescriptor.deviceScope == SL_DEVSCOPE_USER)
+                    && (AudioInputDescriptor.deviceLocation == SL_DEVLOCATION_HANDSET)) {
+                mic_deviceID = InputDeviceIDs[i];
+                mic_available = SL_BOOLEAN_TRUE;
+                break;
+            }
+        }
+    } else {
+        mic_deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
+        mic_available = true;
+    }
+
+    /* If neither of the preferred input audio devices is available, no
+       point in continuing */
+    if (!mic_available) {
+        /* Appropriate error message here */
+        ALOGW("No microphone available");
+        return;
+    }
+
+    /* Initialize arrays required[] and iidArray[] */
+    for (i = 0; i < MAX_NUMBER_INTERFACES; i++) {
+        required[i] = SL_BOOLEAN_FALSE;
+        iidArray[i] = SL_IID_NULL;
+    }
+
+    // ANDROID: the following may fail for volume
+    devicevolumeItf = NULL;
+    /* Get the optional DEVICE VOLUME interface from the engine */
+    res = (*sl)->GetInterface(sl, SL_IID_DEVICEVOLUME,
+            (void *)&devicevolumeItf);
+
+    /* Set recording volume of the microphone to -3 dB */
+    if (devicevolumeItf != NULL) { // ANDROID: Volume may not be supported
+        res = (*devicevolumeItf)->SetVolume(devicevolumeItf, mic_deviceID, -300);
+        CheckErr(res);
+    }
+
+    /* Setup the data source structure */
+    locator_mic.locatorType = SL_DATALOCATOR_IODEVICE;
+    locator_mic.deviceType = SL_IODEVICE_AUDIOINPUT;
+    locator_mic.deviceID = mic_deviceID;
+    locator_mic.device= NULL;
+
+    audioSource.pLocator = (void *)&locator_mic;
+    audioSource.pFormat = NULL;
+
+#if 0
+    /* Setup the data sink structure */
+    uri.locatorType = SL_DATALOCATOR_URI;
+    uri.URI = (SLchar *) "file:///recordsample.wav";
+    mime.formatType = SL_DATAFORMAT_MIME;
+    mime.mimeType = (SLchar *) "audio/x-wav";
+    mime.containerType = SL_CONTAINERTYPE_WAV;
+    audioSink.pLocator = (void *)&uri;
+    audioSink.pFormat = (void *)&mime;
+#else
+    // FIXME: Android requires SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
+    // because the recorder makes the distinction from SL_DATALOCATOR_BUFFERQUEUE
+    // which the player does not.
+    SLDataLocator_AndroidSimpleBufferQueue loc_bq = {
+            SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2
+    };
+    SLDataFormat_PCM format_pcm = {
+            SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_16,
+            SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
+            SL_SPEAKER_FRONT_LEFT, SL_BYTEORDER_LITTLEENDIAN
+    };
+    audioSink = { &loc_bq, &format_pcm };
+#endif
+
+    /* Create audio recorder */
+    res = (*EngineItf)->CreateAudioRecorder(EngineItf, &recorder,
+            &audioSource, &audioSink, 0, iidArray, required);
+    CheckErr(res);
+
+    /* Realizing the recorder in synchronous mode. */
+    res = (*recorder)->Realize(recorder, SL_BOOLEAN_FALSE);
+    CheckErr(res);
+
+    /* Get the RECORD interface - it is an implicit interface */
+    res = (*recorder)->GetInterface(recorder, SL_IID_RECORD, (void *)&recordItf);
+    CheckErr(res);
+
+    // ANDROID: Should register SL_IID_ANDROIDSIMPLEBUFFERQUEUE interface for callback.
+    // but does original SL_DATALOCATOR_BUFFERQUEUE variant work just as well ?
+
+    /* Setup to receive position event callbacks */
+    res = (*recordItf)->RegisterCallback(recordItf, RecordEventCallback, NULL);
+    CheckErr(res);
+
+    /* Set notifications to occur after every second - may be useful in
+       updating a recording progress bar */
+    res = (*recordItf)->SetPositionUpdatePeriod(recordItf, POSITION_UPDATE_PERIOD);
+    CheckErr(res);
+    res = (*recordItf)->SetCallbackEventsMask(recordItf, SL_RECORDEVENT_HEADATNEWPOS);
+    CheckErr(res);
+
+    /* Set the duration of the recording - 30 seconds (30,000
+       milliseconds) */
+    res = (*recordItf)->SetDurationLimit(recordItf, 30000);
+    CheckErr(res);
+
+    /* Record the audio */
+    res = (*recordItf)->SetRecordState(recordItf, SL_RECORDSTATE_RECORDING);
+    CheckErr(res);
+
+    // ANDROID: BUG - we don't wait for anything to record!
+
+    /* Destroy the recorder object */
+    (*recorder)->Destroy(recorder);
+}
+
+extern "C" void Java_android_media_cts_AudioNativeTest_nativeAppendixBRecording(
+        JNIEnv * /* env */, jclass /* clazz */)
+{
+    SLObjectItf engineObject = android::OpenSLEngine();
+    LOG_ALWAYS_FATAL_IF(engineObject == NULL, "cannot open OpenSL ES engine");
+
+    TestAudioRecording(engineObject);
+    android::CloseSLEngine(engineObject);
+}
diff --git a/tests/tests/media/libaudiojni/audio-record-native.cpp b/tests/tests/media/libaudiojni/audio-record-native.cpp
new file mode 100644
index 0000000..9103cdc
--- /dev/null
+++ b/tests/tests/media/libaudiojni/audio-record-native.cpp
@@ -0,0 +1,631 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "audio-record-native"
+
+#include "Blob.h"
+#include "Gate.h"
+#include "sl-utils.h"
+
+#include <deque>
+#include <utils/Errors.h>
+
+// Select whether to use STL shared pointer or to use Android strong pointer.
+// We really don't promote any sharing of this object for its lifetime, but nevertheless could
+// change the shared pointer value on the fly if desired.
+#define USE_SHARED_POINTER
+
+#ifdef USE_SHARED_POINTER
+#include <memory>
+template <typename T> using shared_pointer = std::shared_ptr<T>;
+#else
+#include <utils/RefBase.h>
+template <typename T> using shared_pointer = android::sp<T>;
+#endif
+
+using namespace android;
+
+// Must be kept in sync with Java android.media.cts.AudioRecordNative.ReadFlags
+enum {
+    READ_FLAG_BLOCKING = (1 << 0),
+};
+
+// buffer queue buffers on the OpenSL ES side.
+// The choice can be >= 1.  There is also internal buffering by AudioRecord.
+
+static const size_t BUFFER_SIZE_MSEC = 20;
+
+// TODO: Add a single buffer blocking read mode which does not require additional memory.
+// TODO: Add internal buffer memory (e.g. use circular buffer, right now mallocs on heap).
+
+class AudioRecordNative
+#ifndef USE_SHARED_POINTER
+        : public RefBase // android strong pointers require RefBase
+#endif
+{
+public:
+    AudioRecordNative() :
+        mEngineObj(NULL),
+        mEngine(NULL),
+        mRecordObj(NULL),
+        mRecord(NULL),
+        mBufferQueue(NULL),
+        mRecordState(SL_RECORDSTATE_STOPPED),
+        mBufferSize(0),
+        mNumBuffers(0)
+    { }
+
+    ~AudioRecordNative() {
+        close();
+    }
+
+    typedef std::lock_guard<std::recursive_mutex> auto_lock;
+
+    status_t open(uint32_t numChannels, uint32_t sampleRate, bool useFloat, uint32_t numBuffers) {
+        close();
+        auto_lock l(mLock);
+        mEngineObj = OpenSLEngine();
+        if (mEngineObj == NULL) {
+            ALOGW("cannot create OpenSL ES engine");
+            return INVALID_OPERATION;
+        }
+
+        SLresult res;
+        for (;;) {
+            /* Get the SL Engine Interface which is implicit */
+            res = (*mEngineObj)->GetInterface(mEngineObj, SL_IID_ENGINE, (void *)&mEngine);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            SLDataLocator_IODevice locator_mic;
+            /* Setup the data source structure */
+            locator_mic.locatorType = SL_DATALOCATOR_IODEVICE;
+            locator_mic.deviceType = SL_IODEVICE_AUDIOINPUT;
+            locator_mic.deviceID = SL_DEFAULTDEVICEID_AUDIOINPUT;
+            locator_mic.device= NULL;
+            SLDataSource audioSource;
+            audioSource.pLocator = (void *)&locator_mic;
+            audioSource.pFormat = NULL;
+
+            // FIXME: Android requires SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE
+            // because the recorder makes the distinction from SL_DATALOCATOR_BUFFERQUEUE
+            // which the player does not.
+            SLDataLocator_AndroidSimpleBufferQueue loc_bq = {
+                    SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, numBuffers
+            };
+#if 0
+            SLDataFormat_PCM pcm = {
+                    SL_DATAFORMAT_PCM, 1, SL_SAMPLINGRATE_16,
+                    SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
+                    SL_SPEAKER_FRONT_LEFT, SL_BYTEORDER_LITTLEENDIAN
+            };
+#else
+            SLAndroidDataFormat_PCM_EX pcm;
+            pcm.formatType = useFloat ? SL_ANDROID_DATAFORMAT_PCM_EX : SL_DATAFORMAT_PCM;
+            pcm.numChannels = numChannels;
+            pcm.sampleRate = sampleRate * 1000;
+            pcm.bitsPerSample = useFloat ?
+                    SL_PCMSAMPLEFORMAT_FIXED_32 : SL_PCMSAMPLEFORMAT_FIXED_16;
+            pcm.containerSize = pcm.bitsPerSample;
+            pcm.channelMask = channelCountToMask(numChannels);
+            pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
+            // additional
+            pcm.representation = useFloat ? SL_ANDROID_PCM_REPRESENTATION_FLOAT
+                                    : SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
+#endif
+            SLDataSink audioSink;
+            audioSink = { &loc_bq, &pcm };
+
+            SLboolean required[2];
+            SLInterfaceID iidArray[2];
+            /* Request the AndroidSimpleBufferQueue and AndroidConfiguration interfaces */
+            required[0] = SL_BOOLEAN_TRUE;
+            iidArray[0] = SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
+            required[1] = SL_BOOLEAN_TRUE;
+            iidArray[1] = SL_IID_ANDROIDCONFIGURATION;
+
+            ALOGV("creating recorder");
+            /* Create audio recorder */
+            res = (*mEngine)->CreateAudioRecorder(mEngine, &mRecordObj,
+                    &audioSource, &audioSink, 2, iidArray, required);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            ALOGV("realizing recorder");
+            /* Realizing the recorder in synchronous mode. */
+            res = (*mRecordObj)->Realize(mRecordObj, SL_BOOLEAN_FALSE /* async */);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            ALOGV("geting record interface");
+            /* Get the RECORD interface - it is an implicit interface */
+            res = (*mRecordObj)->GetInterface(mRecordObj, SL_IID_RECORD, (void *)&mRecord);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            ALOGV("geting buffer queue interface");
+            /* Get the buffer queue interface which was explicitly requested */
+            res = (*mRecordObj)->GetInterface(mRecordObj, SL_IID_ANDROIDSIMPLEBUFFERQUEUE,
+                    (void *)&mBufferQueue);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            ALOGV("registering buffer queue interface");
+            /* Setup to receive buffer queue event callbacks */
+            res = (*mBufferQueue)->RegisterCallback(mBufferQueue, BufferQueueCallback, this);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            mBufferSize = (BUFFER_SIZE_MSEC * sampleRate / 1000)
+                    * numChannels * (useFloat ? sizeof(float) : sizeof(int16_t));
+            mNumBuffers = numBuffers;
+            // success
+            break;
+        }
+        if (res != SL_RESULT_SUCCESS) {
+            close(); // should be safe to close even with lock held
+            ALOGW("open error %s", android::getSLErrStr(res));
+            return INVALID_OPERATION;
+        }
+        return OK;
+    }
+
+    void close() {
+        SLObjectItf engineObj;
+        SLObjectItf recordObj;
+        {
+            auto_lock l(mLock);
+            (void)stop();
+            // once stopped, we can unregister the callback
+            if (mBufferQueue != NULL) {
+                (void)(*mBufferQueue)->RegisterCallback(
+                        mBufferQueue, NULL /* callback */, NULL /* *pContext */);
+            }
+            (void)flush();
+            engineObj = mEngineObj;
+            recordObj = mRecordObj;
+            // clear out interfaces and objects
+            mRecord = NULL;
+            mBufferQueue = NULL;
+            mEngine = NULL;
+            mRecordObj = NULL;
+            mEngineObj = NULL;
+            mRecordState = SL_RECORDSTATE_STOPPED;
+            mBufferSize = 0;
+            mNumBuffers = 0;
+        }
+        // destroy without lock
+        if (recordObj != NULL) {
+            (*recordObj)->Destroy(recordObj);
+        }
+        if (engineObj) {
+            CloseSLEngine(engineObj);
+        }
+    }
+
+    status_t setRecordState(SLuint32 recordState) {
+        auto_lock l(mLock);
+        if (mRecord == NULL) {
+            return INVALID_OPERATION;
+        }
+        if (recordState == SL_RECORDSTATE_RECORDING) {
+            queueBuffers();
+        }
+        SLresult res = (*mRecord)->SetRecordState(mRecord, recordState);
+        if (res != SL_RESULT_SUCCESS) {
+            ALOGW("setRecordState %d error %s", recordState, android::getSLErrStr(res));
+            return INVALID_OPERATION;
+        }
+        mRecordState = recordState;
+        return OK;
+    }
+
+    SLuint32 getRecordState() {
+        auto_lock l(mLock);
+        if (mRecord == NULL) {
+            return SL_RECORDSTATE_STOPPED;
+        }
+        SLuint32 recordState;
+        SLresult res = (*mRecord)->GetRecordState(mRecord, &recordState);
+        if (res != SL_RESULT_SUCCESS) {
+            ALOGW("getRecordState error %s", android::getSLErrStr(res));
+            return SL_RECORDSTATE_STOPPED;
+        }
+        return recordState;
+    }
+
+    status_t getPositionInMsec(int64_t *position) {
+        auto_lock l(mLock);
+        if (mRecord == NULL) {
+            return INVALID_OPERATION;
+        }
+        if (position == NULL) {
+            return BAD_VALUE;
+        }
+        SLuint32 pos;
+        SLresult res = (*mRecord)->GetPosition(mRecord, &pos);
+        if (res != SL_RESULT_SUCCESS) {
+            ALOGW("getPosition error %s", android::getSLErrStr(res));
+            return INVALID_OPERATION;
+        }
+        // only lower 32 bits valid
+        *position = pos;
+        return OK;
+    }
+
+    status_t start() {
+        return setRecordState(SL_RECORDSTATE_RECORDING);
+    }
+
+    status_t pause() {
+        return setRecordState(SL_RECORDSTATE_PAUSED);
+    }
+
+    status_t stop() {
+        return setRecordState(SL_RECORDSTATE_STOPPED);
+    }
+
+    status_t flush() {
+        auto_lock l(mLock);
+        status_t result = OK;
+        if (mBufferQueue != NULL) {
+            SLresult res = (*mBufferQueue)->Clear(mBufferQueue);
+            if (res != SL_RESULT_SUCCESS) {
+                return INVALID_OPERATION;
+            }
+        }
+        mReadyQueue.clear();
+        // possible race if the engine is in the callback
+        // safety is only achieved if the recorder is paused or stopped.
+        mDeliveredQueue.clear();
+        mReadBlob = NULL;
+        mReadReady.terminate();
+        return result;
+    }
+
+    ssize_t read(void *buffer, size_t size, bool blocking = false) {
+        std::lock_guard<std::mutex> rl(mReadLock);
+        // not needed if we assume that a single thread is doing the reading
+        // or we always operate in non-blocking mode.
+
+        ALOGV("reading:%p  %zu", buffer, size);
+        size_t copied;
+        std::shared_ptr<Blob> blob;
+        {
+            auto_lock l(mLock);
+            if (mEngine == NULL) {
+                return INVALID_OPERATION;
+            }
+            size_t osize = size;
+            while (!mReadyQueue.empty() && size > 0) {
+                auto b = mReadyQueue.front();
+                size_t tocopy = min(size, b->mSize - b->mOffset);
+                // ALOGD("buffer:%p  size:%zu  b->mSize:%zu  b->mOffset:%zu tocopy:%zu ",
+                //        buffer, size, b->mSize, b->mOffset, tocopy);
+                memcpy(buffer, (char *)b->mData + b->mOffset, tocopy);
+                buffer = (char *)buffer + tocopy;
+                size -= tocopy;
+                b->mOffset += tocopy;
+                if (b->mOffset == b->mSize) {
+                    mReadyQueue.pop_front();
+                }
+            }
+            copied = osize - size;
+            if (!blocking || size == 0 || mReadBlob.get() != NULL) {
+                return copied;
+            }
+            blob = std::make_shared<Blob>(buffer, size);
+            mReadBlob = blob;
+            mReadReady.closeGate(); // the callback will open gate when read is completed.
+        }
+        if (mReadReady.wait()) {
+            // success then the blob is ours with valid data otherwise a flush has occurred
+            // and we return a short count.
+            copied += blob->mOffset;
+        }
+        return copied;
+    }
+
+    void logBufferState() {
+        auto_lock l(mLock);
+        SLBufferQueueState state;
+        SLresult res = (*mBufferQueue)->GetState(mBufferQueue, &state);
+        CheckErr(res);
+        ALOGD("logBufferState state.count:%d  state.playIndex:%d", state.count, state.playIndex);
+    }
+
+    size_t getBuffersPending() {
+        auto_lock l(mLock);
+        return mReadyQueue.size();
+    }
+
+private:
+    status_t queueBuffers() {
+        if (mBufferQueue == NULL) {
+            return INVALID_OPERATION;
+        }
+        if (mReadyQueue.size() + mDeliveredQueue.size() < mNumBuffers) {
+            // add new empty buffer
+            auto b = std::make_shared<Blob>(mBufferSize);
+            mDeliveredQueue.emplace_back(b);
+            (*mBufferQueue)->Enqueue(mBufferQueue, b->mData, b->mSize);
+        }
+        return OK;
+    }
+
+    void bufferQueueCallback(SLBufferQueueItf queueItf) {
+        auto_lock l(mLock);
+        if (queueItf != mBufferQueue) {
+            ALOGW("invalid buffer queue interface, ignoring");
+            return;
+        }
+        // logBufferState();
+
+        // remove from delivered queue
+        if (mDeliveredQueue.size()) {
+            auto b = mDeliveredQueue.front();
+            mDeliveredQueue.pop_front();
+            if (mReadBlob.get() != NULL) {
+                size_t tocopy = min(mReadBlob->mSize - mReadBlob->mOffset, b->mSize - b->mOffset);
+                memcpy((char *)mReadBlob->mData + mReadBlob->mOffset,
+                        (char *)b->mData + b->mOffset, tocopy);
+                b->mOffset += tocopy;
+                mReadBlob->mOffset += tocopy;
+                if (mReadBlob->mOffset == mReadBlob->mSize) {
+                    mReadBlob = NULL;      // we're done, clear our reference.
+                    mReadReady.openGate(); // allow read to continue.
+                }
+                if (b->mOffset == b->mSize) {
+                    b = NULL;
+                }
+            }
+            if (b.get() != NULL) {
+                if (mReadyQueue.size() + mDeliveredQueue.size() < mNumBuffers) {
+                    mReadyQueue.emplace_back(b); // save onto ready queue for future reads
+                } else {
+                    ALOGW("dropping data");
+                }
+            }
+        } else {
+            ALOGW("no delivered data!");
+        }
+        queueBuffers();
+    }
+
+    static void BufferQueueCallback(SLBufferQueueItf queueItf, void *pContext) {
+        SLresult res;
+        // naked native record
+        AudioRecordNative *record = (AudioRecordNative *)pContext;
+        record->bufferQueueCallback(queueItf);
+    }
+
+    SLObjectItf           mEngineObj;
+    SLEngineItf           mEngine;
+    SLObjectItf           mRecordObj;
+    SLRecordItf           mRecord;
+    SLBufferQueueItf      mBufferQueue;
+    SLuint32              mRecordState;
+    size_t                mBufferSize;
+    size_t                mNumBuffers;
+    std::recursive_mutex  mLock;          // monitor lock - locks public API methods and callback.
+                                          // recursive since it may call itself through API.
+    std::mutex            mReadLock;      // read lock - for blocking mode, prevents multiple
+                                          // reader threads from overlapping reads.  this is
+                                          // generally unnecessary as reads occur from
+                                          // one thread only.  acquire this before mLock.
+    std::shared_ptr<Blob> mReadBlob;
+    Gate                  mReadReady;
+    std::deque<std::shared_ptr<Blob>> mReadyQueue;     // ready for read.
+    std::deque<std::shared_ptr<Blob>> mDeliveredQueue; // delivered to BufferQueue
+};
+
+/* Java static methods.
+ *
+ * These are not directly exposed to the user, so we can assume a valid "jrecord" handle
+ * to be passed in.
+ */
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeTest(
+    JNIEnv * /* env */, jclass /* clazz */,
+    jint numChannels, 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;
+
+    status_t res;
+    void *buffer = calloc(framesPerBuffer * numBuffers, frameSize);
+    for (;;) {
+        res = record.open(numChannels, sampleRate, useFloat, numBuffers);
+        if (res != OK) break;
+
+        record.logBufferState();
+        res = record.start();
+        if (res != OK) break;
+
+        size_t size = framesPerBuffer * numBuffers * frameSize;
+        for (size_t offset = 0; size - offset > 0; ) {
+            ssize_t amount = record.read((char *)buffer + offset, size -offset);
+            // ALOGD("read amount: %zd", amount);
+            if (amount < 0) break;
+            offset += amount;
+            usleep(5 * 1000 /* usec */);
+        }
+
+        res = record.stop();
+        break;
+    }
+    record.close();
+    free(buffer);
+    return res;
+}
+
+extern "C" jlong Java_android_media_cts_AudioRecordNative_nativeCreateRecord(
+    JNIEnv * /* env */, jclass /* clazz */)
+{
+    return (jlong)(new shared_pointer<AudioRecordNative>(new AudioRecordNative()));
+}
+
+extern "C" void Java_android_media_cts_AudioRecordNative_nativeDestroyRecord(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jrecord)
+{
+    delete (shared_pointer<AudioRecordNative> *)jrecord;
+}
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeOpen(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jrecord,
+    jint numChannels, 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,
+            numBuffers);
+}
+
+extern "C" void Java_android_media_cts_AudioRecordNative_nativeClose(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jrecord)
+{
+    auto record = *(shared_pointer<AudioRecordNative> *)jrecord;
+    if (record.get() != NULL) {
+        record->close();
+    }
+}
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeStart(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jrecord)
+{
+    auto record = *(shared_pointer<AudioRecordNative> *)jrecord;
+    if (record.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    return (jint)record->start();
+}
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeStop(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jrecord)
+{
+    auto record = *(shared_pointer<AudioRecordNative> *)jrecord;
+    if (record.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    return (jint)record->stop();
+}
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativePause(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jrecord)
+{
+    auto record = *(shared_pointer<AudioRecordNative> *)jrecord;
+    if (record.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    return (jint)record->pause();
+}
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeFlush(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jrecord)
+{
+    auto record = *(shared_pointer<AudioRecordNative> *)jrecord;
+    if (record.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    return (jint)record->flush();
+}
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeGetPositionInMsec(
+    JNIEnv *env, jclass /* clazz */, jlong jrecord, jlongArray jPosition)
+{
+    auto record = *(shared_pointer<AudioRecordNative> *)jrecord;
+    if (record.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    int64_t pos;
+    status_t res = record->getPositionInMsec(&pos);
+    if (res != OK) {
+        return res;
+    }
+    jlong *nPostition = (jlong *) env->GetPrimitiveArrayCritical(jPosition, NULL /* isCopy */);
+    if (nPostition == NULL) {
+        ALOGE("Unable to get array for nativeGetPositionInMsec()");
+        return BAD_VALUE;
+    }
+    nPostition[0] = (jlong)pos;
+    env->ReleasePrimitiveArrayCritical(jPosition, nPostition, 0 /* mode */);
+    return OK;
+}
+
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeGetBuffersPending(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jrecord)
+{
+    auto record = *(shared_pointer<AudioRecordNative> *)jrecord;
+    if (record.get() == NULL) {
+        return (jint)0;
+    }
+    return (jint)record->getBuffersPending();
+}
+
+template <typename T>
+static inline jint readFromRecord(jlong jrecord, T *data,
+    jint offsetInSamples, jint sizeInSamples, jint readFlags)
+{
+    auto record = *(shared_pointer<AudioRecordNative> *)jrecord;
+    if (record.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+
+    const bool isBlocking = readFlags & READ_FLAG_BLOCKING;
+    const size_t sizeInBytes = sizeInSamples * sizeof(T);
+    ssize_t ret = record->read(data + offsetInSamples, sizeInBytes, isBlocking == JNI_TRUE);
+    return (jint)(ret > 0 ? ret / sizeof(T) : ret);
+}
+
+template <typename T>
+static inline jint readArray(JNIEnv *env, jclass /* clazz */, jlong jrecord,
+        T javaAudioData, jint offsetInSamples, jint sizeInSamples, jint readFlags)
+{
+    if (javaAudioData == NULL) {
+        return (jint)BAD_VALUE;
+    }
+
+    auto cAudioData = envGetArrayElements(env, javaAudioData, NULL /* isCopy */);
+    if (cAudioData == NULL) {
+        ALOGE("Error retrieving destination of audio data to record");
+        return (jint)BAD_VALUE;
+    }
+
+    jint ret = readFromRecord(jrecord, cAudioData, offsetInSamples, sizeInSamples, readFlags);
+    envReleaseArrayElements(env, javaAudioData, cAudioData, 0 /* mode */);
+    return ret;
+}
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeReadByteArray(
+    JNIEnv *env, jclass clazz, jlong jrecord,
+    jbyteArray byteArray, jint offsetInSamples, jint sizeInSamples, jint readFlags)
+{
+    return readArray(env, clazz, jrecord, byteArray, offsetInSamples, sizeInSamples, readFlags);
+}
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeReadShortArray(
+    JNIEnv *env, jclass clazz, jlong jrecord,
+    jshortArray shortArray, jint offsetInSamples, jint sizeInSamples, jint readFlags)
+{
+    return readArray(env, clazz, jrecord, shortArray, offsetInSamples, sizeInSamples, readFlags);
+}
+
+extern "C" jint Java_android_media_cts_AudioRecordNative_nativeReadFloatArray(
+    JNIEnv *env, jclass clazz, jlong jrecord,
+    jfloatArray floatArray, jint offsetInSamples, jint sizeInSamples, jint readFlags)
+{
+    return readArray(env, clazz, jrecord, floatArray, offsetInSamples, sizeInSamples, readFlags);
+}
diff --git a/tests/tests/media/libaudiojni/audio-track-native.cpp b/tests/tests/media/libaudiojni/audio-track-native.cpp
new file mode 100644
index 0000000..d51a751
--- /dev/null
+++ b/tests/tests/media/libaudiojni/audio-track-native.cpp
@@ -0,0 +1,579 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "audio-track-native"
+
+#include "Blob.h"
+#include "Gate.h"
+#include "sl-utils.h"
+
+#include <deque>
+#include <utils/Errors.h>
+
+// Select whether to use STL shared pointer or to use Android strong pointer.
+// We really don't promote any sharing of this object for its lifetime, but nevertheless could
+// change the shared pointer value on the fly if desired.
+#define USE_SHARED_POINTER
+
+#ifdef USE_SHARED_POINTER
+#include <memory>
+template <typename T> using shared_pointer = std::shared_ptr<T>;
+#else
+#include <utils/RefBase.h>
+template <typename T> using shared_pointer = android::sp<T>;
+#endif
+
+using namespace android;
+
+// Must be kept in sync with Java android.media.cts.AudioTrackNative.WriteFlags
+enum {
+    WRITE_FLAG_BLOCKING = (1 << 0),
+};
+
+// TODO: Add a single buffer blocking write mode which does not require additional memory.
+// TODO: Add internal buffer memory (e.g. use circular buffer, right now mallocs on heap).
+
+class AudioTrackNative
+#ifndef USE_SHARED_POINTER
+        : public RefBase // android strong pointers require RefBase
+#endif
+{
+public:
+    AudioTrackNative() :
+        mEngineObj(NULL),
+        mEngine(NULL),
+        mOutputMixObj(NULL),
+        mPlayerObj(NULL),
+        mPlay(NULL),
+        mBufferQueue(NULL),
+        mPlayState(SL_PLAYSTATE_STOPPED),
+        mNumBuffers(0)
+    { }
+
+    ~AudioTrackNative() {
+        close();
+    }
+
+    typedef std::lock_guard<std::recursive_mutex> auto_lock;
+
+    status_t open(uint32_t numChannels, uint32_t sampleRate, bool useFloat,
+            uint32_t numBuffers) {
+        close();
+        auto_lock l(mLock);
+        mEngineObj = OpenSLEngine();
+        if (mEngineObj == NULL) {
+            ALOGW("cannot create OpenSL ES engine");
+            return INVALID_OPERATION;
+        }
+
+        SLresult res;
+        for (;;) {
+            /* Get the SL Engine Interface which is implicit */
+            res = (*mEngineObj)->GetInterface(mEngineObj, SL_IID_ENGINE, (void *)&mEngine);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            // Create Output Mix object to be used by player
+            res = (*mEngine)->CreateOutputMix(
+                    mEngine, &mOutputMixObj, 0 /* numInterfaces */,
+                    NULL /* pInterfaceIds */, NULL /* pInterfaceRequired */);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            // Realizing the Output Mix object in synchronous mode.
+            res = (*mOutputMixObj)->Realize(mOutputMixObj, SL_BOOLEAN_FALSE /* async */);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            /* Setup the data source structure for the buffer queue */
+            SLDataLocator_BufferQueue bufferQueue;
+            bufferQueue.locatorType = SL_DATALOCATOR_BUFFERQUEUE;
+            bufferQueue.numBuffers = numBuffers;
+            mNumBuffers = numBuffers;
+
+            /* Setup the format of the content in the buffer queue */
+
+            SLAndroidDataFormat_PCM_EX pcm;
+            pcm.formatType = useFloat ? SL_ANDROID_DATAFORMAT_PCM_EX : SL_DATAFORMAT_PCM;
+            pcm.numChannels = numChannels;
+            pcm.sampleRate = sampleRate * 1000;
+            pcm.bitsPerSample = useFloat ?
+                    SL_PCMSAMPLEFORMAT_FIXED_32 : SL_PCMSAMPLEFORMAT_FIXED_16;
+            pcm.containerSize = pcm.bitsPerSample;
+            pcm.channelMask = channelCountToMask(numChannels);
+            pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
+            // additional
+            pcm.representation = useFloat ? SL_ANDROID_PCM_REPRESENTATION_FLOAT
+                                    : SL_ANDROID_PCM_REPRESENTATION_SIGNED_INT;
+            SLDataSource audioSource;
+            audioSource.pFormat = (void *)&pcm;
+            audioSource.pLocator = (void *)&bufferQueue;
+
+            /* Setup the data sink structure */
+            SLDataLocator_OutputMix locator_outputmix;
+            locator_outputmix.locatorType = SL_DATALOCATOR_OUTPUTMIX;
+            locator_outputmix.outputMix = mOutputMixObj;
+
+            SLDataSink audioSink;
+            audioSink.pLocator = (void *)&locator_outputmix;
+            audioSink.pFormat = NULL;
+
+            SLboolean required[1];
+            SLInterfaceID iidArray[1];
+            required[0] = SL_BOOLEAN_TRUE;
+            iidArray[0] = SL_IID_BUFFERQUEUE;
+
+            res = (*mEngine)->CreateAudioPlayer(mEngine, &mPlayerObj,
+                    &audioSource, &audioSink, 1 /* numInterfaces */, iidArray, required);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            res = (*mPlayerObj)->Realize(mPlayerObj, SL_BOOLEAN_FALSE /* async */);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            res = (*mPlayerObj)->GetInterface(mPlayerObj, SL_IID_PLAY, (void*)&mPlay);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            res = (*mPlayerObj)->GetInterface(
+                    mPlayerObj, SL_IID_BUFFERQUEUE, (void*)&mBufferQueue);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            /* Setup to receive buffer queue event callbacks */
+            res = (*mBufferQueue)->RegisterCallback(mBufferQueue, BufferQueueCallback, this);
+            if (res != SL_RESULT_SUCCESS) break;
+
+            // success
+            break;
+        }
+        if (res != SL_RESULT_SUCCESS) {
+            close(); // should be safe to close even with lock held
+            ALOGW("open error %s", android::getSLErrStr(res));
+            return INVALID_OPERATION;
+        }
+        return OK;
+    }
+
+    void close() {
+        SLObjectItf engineObj;
+        SLObjectItf outputMixObj;
+        SLObjectItf playerObj;
+        {
+            auto_lock l(mLock);
+            if (mPlay != NULL && mPlayState != SL_PLAYSTATE_STOPPED) {
+                (void)stop();
+            }
+            // once stopped, we can unregister the callback
+            if (mBufferQueue != NULL) {
+                (void)(*mBufferQueue)->RegisterCallback(
+                        mBufferQueue, NULL /* callback */, NULL /* *pContext */);
+            }
+            (void)flush();
+            engineObj = mEngineObj;
+            outputMixObj = mOutputMixObj;
+            playerObj = mPlayerObj;
+            // clear out interfaces and objects
+            mPlay = NULL;
+            mBufferQueue = NULL;
+            mEngine = NULL;
+            mPlayerObj = NULL;
+            mOutputMixObj = NULL;
+            mEngineObj = NULL;
+            mPlayState = SL_PLAYSTATE_STOPPED;
+        }
+        // destroy without lock
+        if (playerObj != NULL) {
+            (*playerObj)->Destroy(playerObj);
+        }
+        if (outputMixObj != NULL) {
+            (*outputMixObj)->Destroy(outputMixObj);
+        }
+        if (engineObj != NULL) {
+            CloseSLEngine(engineObj);
+        }
+    }
+
+    status_t setPlayState(SLuint32 playState) {
+        auto_lock l(mLock);
+        if (mPlay == NULL) {
+            return INVALID_OPERATION;
+        }
+        SLresult res = (*mPlay)->SetPlayState(mPlay, playState);
+        if (res != SL_RESULT_SUCCESS) {
+            ALOGW("setPlayState %d error %s", playState, android::getSLErrStr(res));
+            return INVALID_OPERATION;
+        }
+        mPlayState = playState;
+        return OK;
+    }
+
+    SLuint32 getPlayState() {
+        auto_lock l(mLock);
+        if (mPlay == NULL) {
+            return SL_PLAYSTATE_STOPPED;
+        }
+        SLuint32 playState;
+        SLresult res = (*mPlay)->GetPlayState(mPlay, &playState);
+        if (res != SL_RESULT_SUCCESS) {
+            ALOGW("getPlayState error %s", android::getSLErrStr(res));
+            return SL_PLAYSTATE_STOPPED;
+        }
+        return playState;
+    }
+
+    status_t getPositionInMsec(int64_t *position) {
+        auto_lock l(mLock);
+        if (mPlay == NULL) {
+            return INVALID_OPERATION;
+        }
+        if (position == NULL) {
+            return BAD_VALUE;
+        }
+        SLuint32 pos;
+        SLresult res = (*mPlay)->GetPosition(mPlay, &pos);
+        if (res != SL_RESULT_SUCCESS) {
+            ALOGW("getPosition error %s", android::getSLErrStr(res));
+            return INVALID_OPERATION;
+        }
+        // only lower 32 bits valid
+        *position = pos;
+        return OK;
+    }
+
+    status_t start() {
+        return setPlayState(SL_PLAYSTATE_PLAYING);
+    }
+
+    status_t pause() {
+        return setPlayState(SL_PLAYSTATE_PAUSED);
+    }
+
+    status_t stop() {
+        return setPlayState(SL_PLAYSTATE_STOPPED);
+    }
+
+    status_t flush() {
+        auto_lock l(mLock);
+        status_t result = OK;
+        if (mBufferQueue != NULL) {
+            SLresult res = (*mBufferQueue)->Clear(mBufferQueue);
+            if (res != SL_RESULT_SUCCESS) {
+                return INVALID_OPERATION;
+            }
+        }
+
+        // possible race if the engine is in the callback
+        // safety is only achieved if the player is paused or stopped.
+        mDeliveredQueue.clear();
+        return result;
+    }
+
+    status_t write(const void *buffer, size_t size, bool isBlocking = false) {
+        std::lock_guard<std::mutex> rl(mWriteLock);
+        // not needed if we assume that a single thread is doing the reading
+        // or we always operate in non-blocking mode.
+
+        {
+            auto_lock l(mLock);
+            if (mBufferQueue == NULL) {
+                return INVALID_OPERATION;
+            }
+            if (mDeliveredQueue.size() < mNumBuffers) {
+                auto b = std::make_shared<BlobReadOnly>(buffer, size, false /* byReference */);
+                mDeliveredQueue.emplace_back(b);
+                (*mBufferQueue)->Enqueue(mBufferQueue, b->mData, b->mSize);
+                return size;
+            }
+            if (!isBlocking) {
+                return 0;
+            }
+            mWriteReady.closeGate(); // we're full.
+        }
+        if (mWriteReady.wait()) {
+            auto_lock l(mLock);
+            if (mDeliveredQueue.size() < mNumBuffers) {
+                auto b = std::make_shared<BlobReadOnly>(buffer, size, false /* byReference */);
+                mDeliveredQueue.emplace_back(b);
+                (*mBufferQueue)->Enqueue(mBufferQueue, b->mData, b->mSize);
+                return size;
+            }
+        }
+        ALOGW("unable to deliver write");
+        return 0;
+    }
+
+    void logBufferState() {
+        auto_lock l(mLock);
+        SLBufferQueueState state;
+        SLresult res = (*mBufferQueue)->GetState(mBufferQueue, &state);
+        CheckErr(res);
+        ALOGD("logBufferState state.count:%d  state.playIndex:%d", state.count, state.playIndex);
+    }
+
+    size_t getBuffersPending() {
+        auto_lock l(mLock);
+        return mDeliveredQueue.size();
+    }
+
+private:
+    void bufferQueueCallback(SLBufferQueueItf queueItf) {
+        auto_lock l(mLock);
+        if (queueItf != mBufferQueue) {
+            ALOGW("invalid buffer queue interface, ignoring");
+            return;
+        }
+        // logBufferState();
+
+        // remove from delivered queue
+        if (mDeliveredQueue.size()) {
+            mDeliveredQueue.pop_front();
+        } else {
+            ALOGW("no delivered data!");
+        }
+        if (!mWriteReady.isOpen()) {
+            mWriteReady.openGate();
+        }
+    }
+
+    static void BufferQueueCallback(SLBufferQueueItf queueItf, void *pContext) {
+        SLresult res;
+        // naked native track
+        AudioTrackNative *track = (AudioTrackNative *)pContext;
+        track->bufferQueueCallback(queueItf);
+    }
+
+    SLObjectItf          mEngineObj;
+    SLEngineItf          mEngine;
+    SLObjectItf          mOutputMixObj;
+    SLObjectItf          mPlayerObj;
+    SLPlayItf            mPlay;
+    SLBufferQueueItf     mBufferQueue;
+    SLuint32             mPlayState;
+    SLuint32             mNumBuffers;
+    std::recursive_mutex mLock;           // monitor lock - locks public API methods and callback.
+                                          // recursive since it may call itself through API.
+    std::mutex           mWriteLock;      // write lock - for blocking mode, prevents multiple
+                                          // writer threads from overlapping writes.  this is
+                                          // generally unnecessary as writes occur from
+                                          // one thread only.  acquire this before mLock.
+    Gate                 mWriteReady;
+    std::deque<std::shared_ptr<BlobReadOnly>> mDeliveredQueue; // delivered to mBufferQueue
+};
+
+/* Java static methods.
+ *
+ * These are not directly exposed to the user, so we can assume a valid "jtrack" handle
+ * to be passed in.
+ */
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeTest(
+    JNIEnv * /* env */, jclass /* clazz */,
+    jint numChannels, jint sampleRate, jboolean useFloat,
+    jint msecPerBuffer, jint numBuffers)
+{
+    AudioTrackNative track;
+    const size_t frameSize = numChannels * (useFloat ? sizeof(float) : sizeof(int16_t));
+    const size_t framesPerBuffer = msecPerBuffer * sampleRate / 1000;
+
+    status_t res;
+    void *buffer = calloc(framesPerBuffer * numBuffers, frameSize);
+    for (;;) {
+        res = track.open(numChannels, sampleRate, useFloat, numBuffers);
+        if (res != OK) break;
+
+        for (int i = 0; i < numBuffers; ++i) {
+            track.write((char *)buffer + i * (framesPerBuffer * frameSize),
+                    framesPerBuffer * frameSize);
+        }
+
+        track.logBufferState();
+        res = track.start();
+        if (res != OK) break;
+
+        size_t buffers;
+        while ((buffers = track.getBuffersPending()) > 0) {
+            // ALOGD("outstanding buffers: %zu", buffers);
+            usleep(5 * 1000 /* usec */);
+        }
+        res = track.stop();
+        break;
+    }
+    track.close();
+    free(buffer);
+    return res;
+}
+
+extern "C" jlong Java_android_media_cts_AudioTrackNative_nativeCreateTrack(
+    JNIEnv * /* env */, jclass /* clazz */)
+{
+    return (jlong)(new shared_pointer<AudioTrackNative>(new AudioTrackNative()));
+}
+
+extern "C" void Java_android_media_cts_AudioTrackNative_nativeDestroyTrack(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jtrack)
+{
+    delete (shared_pointer<AudioTrackNative> *)jtrack;
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeOpen(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jtrack,
+    jint numChannels, 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);
+}
+
+extern "C" void Java_android_media_cts_AudioTrackNative_nativeClose(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jtrack)
+{
+    auto track = *(shared_pointer<AudioTrackNative> *)jtrack;
+    if (track.get() != NULL) {
+        track->close();
+    }
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeStart(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jtrack)
+{
+    auto track = *(shared_pointer<AudioTrackNative> *)jtrack;
+    if (track.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    return (jint)track->start();
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeStop(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jtrack)
+{
+    auto track = *(shared_pointer<AudioTrackNative> *)jtrack;
+    if (track.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    return (jint)track->stop();
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativePause(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jtrack)
+{
+    auto track = *(shared_pointer<AudioTrackNative> *)jtrack;
+    if (track.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    return (jint)track->pause();
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeFlush(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jtrack)
+{
+    auto track = *(shared_pointer<AudioTrackNative> *)jtrack;
+    if (track.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    return (jint)track->flush();
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeGetPositionInMsec(
+    JNIEnv *env, jclass /* clazz */, jlong jtrack, jlongArray jPosition)
+{
+    auto track = *(shared_pointer<AudioTrackNative> *)jtrack;
+    if (track.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+    int64_t pos;
+    status_t res = track->getPositionInMsec(&pos);
+    if (res != OK) {
+        return res;
+    }
+    jlong *nPostition = (jlong *) env->GetPrimitiveArrayCritical(jPosition, NULL /* isCopy */);
+    if (nPostition == NULL) {
+        ALOGE("Unable to get array for nativeGetPositionInMsec()");
+        return BAD_VALUE;
+    }
+    nPostition[0] = (jlong)pos;
+    env->ReleasePrimitiveArrayCritical(jPosition, nPostition, 0 /* mode */);
+    return OK;
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeGetBuffersPending(
+    JNIEnv * /* env */, jclass /* clazz */, jlong jtrack)
+{
+    auto track = *(shared_pointer<AudioTrackNative> *)jtrack;
+    if (track.get() == NULL) {
+        return (jint)0;
+    }
+    return (jint)track->getBuffersPending();
+}
+
+template <typename T>
+static inline jint writeToTrack(jlong jtrack, const T *data,
+    jint offsetInSamples, jint sizeInSamples, jint writeFlags)
+{
+    auto track = *(shared_pointer<AudioTrackNative> *)jtrack;
+    if (track.get() == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+
+    const bool isBlocking = writeFlags & WRITE_FLAG_BLOCKING;
+    const size_t sizeInBytes = sizeInSamples * sizeof(T);
+    ssize_t ret = track->write(data + offsetInSamples, sizeInBytes, isBlocking);
+    return (jint)(ret > 0 ? ret / sizeof(T) : ret);
+}
+
+template <typename T>
+static inline jint writeArray(JNIEnv *env, jclass /* clazz */, jlong jtrack,
+        T javaAudioData, jint offsetInSamples, jint sizeInSamples, jint writeFlags)
+{
+    if (javaAudioData == NULL) {
+        return (jint)INVALID_OPERATION;
+    }
+
+    auto cAudioData = envGetArrayElements(env, javaAudioData, NULL /* isCopy */);
+    if (cAudioData == NULL) {
+        ALOGE("Error retrieving source of audio data to play");
+        return (jint)BAD_VALUE;
+    }
+
+    jint ret = writeToTrack(jtrack, cAudioData, offsetInSamples, sizeInSamples, writeFlags);
+    envReleaseArrayElements(env, javaAudioData, cAudioData, 0 /* mode */);
+    return ret;
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeWriteByteArray(
+    JNIEnv *env, jclass clazz, jlong jtrack,
+    jbyteArray byteArray, jint offsetInSamples, jint sizeInSamples, jint writeFlags)
+{
+    ALOGV("nativeWriteByteArray(%p, %d, %d, %d)",
+            byteArray, offsetInSamples, sizeInSamples, writeFlags);
+    return writeArray(env, clazz, jtrack, byteArray, offsetInSamples, sizeInSamples, writeFlags);
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeWriteShortArray(
+    JNIEnv *env, jclass clazz, jlong jtrack,
+    jshortArray shortArray, jint offsetInSamples, jint sizeInSamples, jint writeFlags)
+{
+    ALOGV("nativeWriteShortArray(%p, %d, %d, %d)",
+            shortArray, offsetInSamples, sizeInSamples, writeFlags);
+    return writeArray(env, clazz, jtrack, shortArray, offsetInSamples, sizeInSamples, writeFlags);
+}
+
+extern "C" jint Java_android_media_cts_AudioTrackNative_nativeWriteFloatArray(
+    JNIEnv *env, jclass clazz, jlong jtrack,
+    jfloatArray floatArray, jint offsetInSamples, jint sizeInSamples, jint writeFlags)
+{
+    ALOGV("nativeWriteFloatArray(%p, %d, %d, %d)",
+            floatArray, offsetInSamples, sizeInSamples, writeFlags);
+    return writeArray(env, clazz, jtrack, floatArray, offsetInSamples, sizeInSamples, writeFlags);
+}
diff --git a/tests/tests/media/libaudiojni/sl-utils.cpp b/tests/tests/media/libaudiojni/sl-utils.cpp
new file mode 100644
index 0000000..1aa89ba
--- /dev/null
+++ b/tests/tests/media/libaudiojni/sl-utils.cpp
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 "SL-Utils"
+
+#include "sl-utils.h"
+#include <utils/Mutex.h>
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+// 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)
+
+namespace android {
+
+static Mutex gLock;
+static SLObjectItf gEngineObject;
+static unsigned gRefCount;
+
+static const char *gErrorStrings[] = {
+    "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) {
+    if ((size_t)code >= ARRAY_SIZE(gErrorStrings)) {
+        return "SL_RESULT_UNKNOWN";
+    }
+    return gErrorStrings[code];
+}
+
+SLuint32 channelCountToMask(unsigned channelCount) {
+    switch (channelCount) {
+    case 1:
+        return SL_SPEAKER_FRONT_LEFT; // we prefer left over center
+    case 2:
+        return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
+    case 3:
+        return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER;
+    case 4:
+        return SL_ANDROID_SPEAKER_QUAD;
+    case 5:
+        return SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER;
+    case 6:
+        return SL_ANDROID_SPEAKER_5DOT1;
+    case 7:
+        return SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_BACK_CENTER;
+    case 8:
+        return SL_ANDROID_SPEAKER_7DOT1;
+    default:
+        return 0;
+    }
+}
+
+static SLObjectItf createEngine() {
+    static SLEngineOption EngineOption[] = {
+            (SLuint32) SL_ENGINEOPTION_THREADSAFE,
+            (SLuint32) SL_BOOLEAN_TRUE
+    };
+    // create engine in thread-safe mode
+    SLObjectItf engine;
+    SLresult result = slCreateEngine(&engine,
+            1 /* numOptions */, EngineOption /* pEngineOptions */,
+            0 /* numInterfaces */, NULL /* pInterfaceIds */, NULL /* pInterfaceRequired */);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("slCreateEngine() failed: %s", getSLErrStr(result));
+        return NULL;
+    }
+    // realize the engine
+    result = (*engine)->Realize(engine, SL_BOOLEAN_FALSE /* async */);
+    if (result != SL_RESULT_SUCCESS) {
+        ALOGE("Realize() failed: %s", getSLErrStr(result));
+        (*engine)->Destroy(engine);
+        return NULL;
+    }
+    return engine;
+}
+
+SLObjectItf OpenSLEngine(bool global) {
+
+    if (!global) {
+        return createEngine();
+    }
+    Mutex::Autolock l(gLock);
+    if (gRefCount == 0) {
+        gEngineObject = createEngine();
+    }
+    gRefCount++;
+    return gEngineObject;
+}
+
+void CloseSLEngine(SLObjectItf engine) {
+    Mutex::Autolock l(gLock);
+    if (engine == gEngineObject) {
+        if (gRefCount == 0) {
+            ALOGE("CloseSLEngine(%p): refcount already 0", engine);
+            return;
+        }
+        if (--gRefCount != 0) {
+            return;
+        }
+        gEngineObject = NULL;
+    }
+    (*engine)->Destroy(engine);
+}
+
+} // namespace android
+
diff --git a/tests/tests/media/libaudiojni/sl-utils.h b/tests/tests/media/libaudiojni/sl-utils.h
new file mode 100644
index 0000000..8582648
--- /dev/null
+++ b/tests/tests/media/libaudiojni/sl-utils.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SL_UTILS_H
+#define ANDROID_SL_UTILS_H
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+#include <jni.h>
+#include <mutex>
+#include <utils/Log.h>
+
+#define CheckErr(res) LOG_ALWAYS_FATAL_IF( \
+        (res) != SL_RESULT_SUCCESS, "result error %s", android::getSLErrStr(res));
+
+namespace android {
+
+// FIXME: Move to common file.
+template <typename T>
+static inline
+const T &min(const T &a, const T &b) {
+    return a < b ? a : b;
+}
+
+/* Returns the error string for the OpenSL ES error code
+ */
+const char *getSLErrStr(int code);
+
+/* Returns the OpenSL ES equivalent standard channel mask
+ * for a given channel count, 0 if no such mask is available.
+ */
+SLuint32 channelCountToMask(unsigned channelCount);
+
+/* Returns an OpenSL ES Engine object interface.
+ * The engine created will be thread safe [3.2]
+ * The underlying implementation may not support more than one engine. [4.1.1]
+ *
+ * @param global if true, return and open the global engine instance or make
+ *   a local engine instance if false.
+ * @return NULL if unsuccessful or the Engine SLObjectItf.
+ */
+SLObjectItf OpenSLEngine(bool global = true);
+
+/* Closes an OpenSL ES Engine object returned by OpenSLEngine().
+ */
+void CloseSLEngine(SLObjectItf engine);
+
+// overloaded JNI array helper functions (same as in android_media_AudioRecord)
+inline
+jbyte *envGetArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy) {
+    return env->GetByteArrayElements(array, isCopy);
+}
+
+inline
+void envReleaseArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems, jint mode) {
+    env->ReleaseByteArrayElements(array, elems, mode);
+}
+
+inline
+jshort *envGetArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy) {
+    return env->GetShortArrayElements(array, isCopy);
+}
+
+inline
+void envReleaseArrayElements(JNIEnv *env, jshortArray array, jshort *elems, jint mode) {
+    env->ReleaseShortArrayElements(array, elems, mode);
+}
+
+inline
+jfloat *envGetArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy) {
+    return env->GetFloatArrayElements(array, isCopy);
+}
+
+inline
+void envReleaseArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems, jint mode) {
+    env->ReleaseFloatArrayElements(array, elems, mode);
+}
+
+} // namespace android
+
+#endif // ANDROID_SL_UTILS_H
diff --git a/tests/tests/media/libmediandkjni/native-media-jni.cpp b/tests/tests/media/libmediandkjni/native-media-jni.cpp
index 9bca242..2624c25 100644
--- a/tests/tests/media/libmediandkjni/native-media-jni.cpp
+++ b/tests/tests/media/libmediandkjni/native-media-jni.cpp
@@ -234,7 +234,7 @@
     AMediaFormat **format = new AMediaFormat*[numtracks];
     bool *sawInputEOS = new bool[numtracks];
     bool *sawOutputEOS = new bool[numtracks];
-    simplevector<int> sizes[numtracks];
+    simplevector<int> *sizes = new simplevector<int>[numtracks];
 
     ALOGV("input has %d tracks", numtracks);
     for (int i = 0; i < numtracks; i++) {
@@ -354,6 +354,8 @@
     }
     env->ReleaseIntArrayElements(ret, org, 0);
 
+    delete[] sizes;
+    delete[] sawOutputEOS;
     delete[] sawInputEOS;
     for (int i = 0; i < numtracks; i++) {
         AMediaFormat_delete(format[i]);
diff --git a/tests/tests/media/res/raw/monotestgsm.wav b/tests/tests/media/res/raw/monotestgsm.wav
new file mode 100644
index 0000000..6062f36
--- /dev/null
+++ b/tests/tests/media/res/raw/monotestgsm.wav
Binary files differ
diff --git a/tests/tests/media/res/raw/on_input_buffer_filled_sigsegv.mp4 b/tests/tests/media/res/raw/on_input_buffer_filled_sigsegv.mp4
new file mode 100644
index 0000000..110c0d6
--- /dev/null
+++ b/tests/tests/media/res/raw/on_input_buffer_filled_sigsegv.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/test1m1shighstereo.mp3 b/tests/tests/media/res/raw/test1m1shighstereo.mp3
new file mode 100644
index 0000000..2a97077
--- /dev/null
+++ b/tests/tests/media/res/raw/test1m1shighstereo.mp3
Binary files differ
diff --git a/tests/tests/media/res/raw/video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4 b/tests/tests/media/res/raw/video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4
new file mode 100644
index 0000000..6b6040f
--- /dev/null
+++ b/tests/tests/media/res/raw/video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
index ba6df98..34469b79 100644
--- a/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
+++ b/tests/tests/media/src/android/media/cts/AdaptivePlaybackTest.java
@@ -35,11 +35,13 @@
 import javax.microedition.khronos.opengles.GL10;
 
 import java.io.IOException;
+import java.lang.System;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Locale;
+import java.util.Vector;
 import java.util.zip.CRC32;
 
 public class AdaptivePlaybackTest extends MediaPlayerTestBase {
@@ -325,20 +327,42 @@
      * Queue some frames with an EOS on the last one.  Test that we have decoded as many
      * frames as we queued.  This tests the EOS handling of the codec to see if all queued
      * (and out-of-order) frames are actually decoded and returned.
+     *
+     * Also test flushing prior to sending CSD, and immediately after sending CSD.
      */
     class EarlyEosTest extends ActivityTest {
+        // using bitfields to create a directed state graph that terminates at FLUSH_NEVER
+        static final int FLUSH_BEFORE_CSD = (1 << 1);
+        static final int FLUSH_AFTER_CSD = (1 << 0);
+        static final int FLUSH_NEVER = 0;
+
         public boolean isValid(Codec c) {
             return getFormat(c) != null;
         }
         public void addTests(TestList tests, final Codec c) {
-            for (int i = NUM_FRAMES / 2; i > 0; i--) {
+            int state = FLUSH_BEFORE_CSD;
+            for (int i = NUM_FRAMES / 2; i > 0; --i, state >>= 1) {
                 final int queuedFrames = i;
+                final int earlyFlushMode = state;
                 tests.add(
                     new Step("testing early EOS at " + queuedFrames, this, c) {
                         public void run() {
                             Decoder decoder = new Decoder(c.name);
                             try {
-                                decoder.configureAndStart(stepFormat(), stepSurface());
+                                MediaFormat fmt = stepFormat();
+                                MediaFormat configFmt = fmt;
+                                if (earlyFlushMode == FLUSH_BEFORE_CSD) {
+                                    // flush before CSD requires not submitting CSD with configure
+                                    configFmt = Media.removeCSD(fmt);
+                                }
+                                decoder.configureAndStart(configFmt, stepSurface());
+                                if (earlyFlushMode != FLUSH_NEVER) {
+                                    decoder.flush();
+                                    // We must always queue CSD after a flush that is potentially
+                                    // before we receive output format has changed.  This should
+                                    // work even after we receive the format change.
+                                    decoder.queueCSD(fmt);
+                                }
                                 int decodedFrames = -decoder.queueInputBufferRange(
                                         stepMedia(),
                                         0 /* startFrame */,
@@ -447,8 +471,7 @@
                             this, c, mediaIx) {
                         public void run() {
                             try {
-                                //mDecoder.configureAndStart(stepFormat(), stepSurface());
-                                if(mDecoder.configureAndStart(stepFormat(), stepSurface())){
+                                mDecoder.configureAndStart(stepFormat(), stepSurface());
                                 int decodedFrames = -mDecoder.queueInputBufferRange(
                                         stepMedia(),
                                         0 /* startFrame */,
@@ -462,7 +485,6 @@
                                 warn(mDecoder.getWarnings());
                                 mDecoder.clearWarnings();
                                 mDecoder.flush();
-                                }
                             } finally {
                                 mDecoder.stop();
                             }
@@ -814,9 +836,10 @@
         return items;
     }
 
-    class Decoder {
+    class Decoder implements MediaCodec.OnFrameRenderedListener {
         private final static String TAG = "AdaptiveDecoder";
         final long kTimeOutUs = 5000;
+        final long kCSDTimeOutUs = 1000000;
         MediaCodec mCodec;
         ByteBuffer[] mInputBuffers;
         ByteBuffer[] mOutputBuffers;
@@ -825,7 +848,9 @@
         boolean mQueuedEos;
         ArrayList<Long> mTimeStamps;
         ArrayList<String> mWarnings;
-        boolean mConfigured;
+        Vector<Long> mRenderedTimeStamps; // using Vector as it is implicitly synchronized
+        long mLastRenderNanoTime;
+        int mFramesNotifiedRendered;
 
         public Decoder(String codecName) {
             MediaCodec codec = null;
@@ -840,7 +865,23 @@
             mQueuedEos = false;
             mTimeStamps = new ArrayList<Long>();
             mWarnings = new ArrayList<String>();
-            mConfigured = false;
+            mRenderedTimeStamps = new Vector<Long>();
+            mLastRenderNanoTime = System.nanoTime();
+            mFramesNotifiedRendered = 0;
+
+            codec.setOnFrameRenderedListener(this, null);
+        }
+
+        public void onFrameRendered(MediaCodec codec, long presentationTimeUs, long nanoTime) {
+            final long NSECS_IN_1SEC = 1000000000;
+            if (!mRenderedTimeStamps.remove(presentationTimeUs)) {
+                warn("invalid timestamp " + presentationTimeUs + ", queued " +
+                        collectionString(mRenderedTimeStamps));
+            }
+            assert nanoTime > mLastRenderNanoTime;
+            mLastRenderNanoTime = nanoTime;
+            ++mFramesNotifiedRendered;
+            assert nanoTime > System.nanoTime() - NSECS_IN_1SEC;
         }
 
         public String getName() {
@@ -860,18 +901,21 @@
             mWarnings.clear();
         }
 
-        public boolean configureAndStart(MediaFormat format, TestSurface surface) {
+        public void configureAndStart(MediaFormat format, TestSurface surface) {
             mSurface = surface;
             Log.i(TAG, "configure(" + format + ", " + mSurface.getSurface() + ")");
-            try{
-			mCodec.configure(format, mSurface.getSurface(), null /* crypto */, 0 /* flags */);
-			}
-			catch (Exception e){
-				Log.i(TAG, "Unsupported Codec");
-				return false;
-			}
+            mCodec.configure(format, mSurface.getSurface(), null /* crypto */, 0 /* flags */);
             Log.i(TAG, "start");
             mCodec.start();
+
+            // inject some minimal setOutputSurface test
+            // TODO: change this test to also change the surface midstream
+            try {
+                mCodec.setOutputSurface(null);
+                fail("should not be able to set surface to NULL");
+            } catch (IllegalArgumentException e) {}
+            mCodec.setOutputSurface(mSurface.getSurface());
+
             mInputBuffers = mCodec.getInputBuffers();
             mOutputBuffers = mCodec.getOutputBuffers();
             Log.i(TAG, "configured " + mInputBuffers.length + " input[" +
@@ -879,15 +923,19 @@
                   mOutputBuffers.length + "output[" +
                   (mOutputBuffers[0] == null ? null : mOutputBuffers[0].capacity()) + "]");
             mQueuedEos = false;
-            mConfigured = true;
-            return true;
+            mRenderedTimeStamps.clear();
+            mLastRenderNanoTime = System.nanoTime();
+            mFramesNotifiedRendered = 0;
         }
 
         public void stop() {
-            if(mConfigured) {
-                Log.i(TAG, "stop");
-                mCodec.stop();
-                mConfigured = false;
+            Log.i(TAG, "stop");
+            mCodec.stop();
+            // if we have queued 32 frames or more, at least one should have been notified
+            // to have rendered.
+            if (mRenderedTimeStamps.size() > 32 && mFramesNotifiedRendered == 0) {
+                fail("rendered " + mRenderedTimeStamps.size() +
+                        " frames, but none have been notified.");
             }
         }
 
@@ -945,6 +993,7 @@
             }
 
             if (doRender) {
+                mRenderedTimeStamps.add(info.presentationTimeUs);
                 if (!mTimeStamps.remove(info.presentationTimeUs)) {
                     warn("invalid timestamp " + info.presentationTimeUs + ", queued " +
                             collectionString(mTimeStamps));
@@ -1003,6 +1052,31 @@
             return queueInputBufferRange(media,frameStartIx,frameEndIx,sendEosAtEnd,waitForEos,0);
         }
 
+        public void queueCSD(MediaFormat format) {
+            MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+            for (int csdIx = 0; ; ++csdIx) {
+                ByteBuffer csdBuf = format.getByteBuffer("csd-" + csdIx);
+                if (csdBuf == null) {
+                    break;
+                }
+
+                int ix = mCodec.dequeueInputBuffer(kCSDTimeOutUs);
+                if (ix < 0) {
+                    fail("Could not dequeue input buffer for CSD #" + csdIx);
+                    return;
+                }
+
+                ByteBuffer buf = mInputBuffers[ix];
+                buf.clear();
+                buf.put((ByteBuffer)csdBuf.clear());
+                Log.v(TAG, "queue-CSD { [" + buf.position() + "]=" +
+                        byteBufferToString(buf, 0, 16) + "} => #" + ix);
+                mCodec.queueInputBuffer(
+                        ix, 0 /* offset */, buf.position(), 0 /* timeUs */,
+                        MediaCodec.BUFFER_FLAG_CODEC_CONFIG);
+            }
+        }
+
         public int queueInputBufferRange(
                 Media media, int frameStartIx, int frameEndIx, boolean sendEosAtEnd,
                 boolean waitForEos, long adjustTimeUs) {
@@ -1148,6 +1222,31 @@
         return mFormat;
     }
 
+    public static MediaFormat removeCSD(MediaFormat orig) {
+        MediaFormat copy = MediaFormat.createVideoFormat(
+                orig.getString(orig.KEY_MIME),
+                orig.getInteger(orig.KEY_WIDTH), orig.getInteger(orig.KEY_HEIGHT));
+        for (String k : new String[] {
+                orig.KEY_FRAME_RATE, orig.KEY_MAX_WIDTH, orig.KEY_MAX_HEIGHT,
+                orig.KEY_MAX_INPUT_SIZE
+        }) {
+            if (orig.containsKey(k)) {
+                try {
+                    copy.setInteger(k, orig.getInteger(k));
+                } catch (ClassCastException e) {
+                    try {
+                        copy.setFloat(k, orig.getFloat(k));
+                    } catch (ClassCastException e2) {
+                        // Could not copy value. Don't fail here, as having non-standard
+                        // value types for defined keys is permissible by the media API
+                        // for optional keys.
+                    }
+                }
+            }
+        }
+        return copy;
+    }
+
     public MediaFormat getAdaptiveFormat(int width, int height) {
         mAdaptiveFormat.setInteger(MediaFormat.KEY_MAX_WIDTH, width);
         mAdaptiveFormat.setInteger(MediaFormat.KEY_MAX_HEIGHT, height);
@@ -1325,13 +1424,11 @@
 
             /* test if the explicitly named codec is present on the system */
             if (explicitCodecName != null) {
-                try {
-                    MediaCodec codec = MediaCodec.createByCodecName(explicitCodecName);
-                    if (codec != null) {
-                        codec.release();
-                        add(new Codec(explicitCodecName, null, mediaList));
-                    }
-                } catch (Exception e) {}
+                MediaCodec codec = MediaCodec.createByCodecName(explicitCodecName);
+                if (codec != null) {
+                    codec.release();
+                    add(new Codec(explicitCodecName, null, mediaList));
+                }
             }
         } catch (Throwable t) {
             Log.wtf("Constructor failed", t);
diff --git a/tests/tests/media/src/android/media/cts/AsyncPlayerTest.java b/tests/tests/media/src/android/media/cts/AsyncPlayerTest.java
index 08e1d67..9272d58 100644
--- a/tests/tests/media/src/android/media/cts/AsyncPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/AsyncPlayerTest.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.media.AsyncPlayer;
+import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.net.Uri;
 import android.provider.Settings;
@@ -34,4 +35,13 @@
         asyncPlayer.stop();
     }
 
+    public void testAsyncPlayerAudioAttributes() throws Exception {
+        final Uri PLAY_URI = Settings.System.DEFAULT_NOTIFICATION_URI;
+        AsyncPlayer asyncPlayer = new AsyncPlayer(null);
+        asyncPlayer.play(getContext(), PLAY_URI, true,
+                new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build());
+        final int PLAY_TIME = 3000;
+        Thread.sleep(PLAY_TIME);
+        asyncPlayer.stop();
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/AudioAttributesTest.java b/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
new file mode 100644
index 0000000..3e42b7e
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioAttributesTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.cts.util.CtsAndroidTestCase;
+import android.media.AudioAttributes;
+import android.os.Parcel;
+
+public class AudioAttributesTest extends CtsAndroidTestCase {
+
+    // -----------------------------------------------------------------
+    // AUDIOATTRIBUTES TESTS:
+    // ----------------------------------
+
+    // -----------------------------------------------------------------
+    // Parcelable tests
+    // ----------------------------------
+
+    // Test case 1: call describeContents(), not used yet, but needs to be exercised
+    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);
+    }
+
+    // Test case 2: create an instance, marshall it and create a new instance,
+    //      check for equality, both by comparing fields, and with the equals(Object) method
+    public void testParcelableWriteToParcelCreate() throws Exception {
+        final AudioAttributes srcAttr = new AudioAttributes.Builder()
+            .setUsage(AudioAttributes.USAGE_MEDIA)
+            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+            .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED).build();
+        final Parcel srcParcel = Parcel.obtain();
+        final Parcel dstParcel = Parcel.obtain();
+        final byte[] mbytes;
+
+        srcAttr.writeToParcel(srcParcel, 0 /*no public flags for marshalling*/);
+        mbytes = srcParcel.marshall();
+        dstParcel.unmarshall(mbytes, 0, mbytes.length);
+        dstParcel.setDataPosition(0);
+        final AudioAttributes targetAttr = AudioAttributes.CREATOR.createFromParcel(dstParcel);
+
+        assertEquals("Marshalled/restored usage doesn't match",
+                srcAttr.getUsage(), targetAttr.getUsage());
+        assertEquals("Marshalled/restored content type doesn't match",
+                srcAttr.getContentType(), targetAttr.getContentType());
+        assertEquals("Marshalled/restored flags don't match",
+                srcAttr.getFlags(), targetAttr.getFlags());
+        assertTrue("Source and target attributes are not considered equal",
+                srcAttr.equals(targetAttr));
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioEffectTest.java b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
index 1c96abd..dce7680 100644
--- a/tests/tests/media/src/android/media/cts/AudioEffectTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioEffectTest.java
@@ -65,9 +65,6 @@
 
     //Test case 0.0: test queryEffects() and platfrom at least provides an Equalizer
     public void test0_0QueryEffects() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
 
         AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
 
@@ -125,9 +122,6 @@
 
     //Test case 1.3: test getEnabled() failure when called on released effect
     public void test1_3GetEnabledAfterRelease() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         try {
             AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                     AudioEffect.EFFECT_TYPE_NULL,
@@ -150,9 +144,6 @@
 
     //Test case 1.4: test contructor on mediaPlayer audio session
     public void test1_4InsertOnMediaPlayer() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         MediaPlayer mp = new MediaPlayer();
         assertNotNull("could not create mediaplayer", mp);
         AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(R.raw.testmp3);
@@ -285,9 +276,6 @@
 
     //Test case 2.0: test setEnabled() and getEnabled() in valid state
     public void test2_0SetEnabledGetEnabled() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         try {
             AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                     AudioEffect.EFFECT_TYPE_NULL,
@@ -315,9 +303,6 @@
 
     //Test case 2.1: test setEnabled() throws exception after release
     public void test2_1SetEnabledAfterRelease() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         try {
             AudioEffect effect = new AudioEffect(AudioEffect.EFFECT_TYPE_EQUALIZER,
                     AudioEffect.EFFECT_TYPE_NULL,
@@ -649,9 +634,6 @@
 
     //Test case 4.0: test control passed to higher priority client
     public void test4_0setEnabledLowerPriority() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         AudioEffect effect1 = null;
         AudioEffect effect2 = null;
         try {
diff --git a/tests/tests/media/src/android/media/cts/AudioFormatTest.java b/tests/tests/media/src/android/media/cts/AudioFormatTest.java
new file mode 100644
index 0000000..3c6a312
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioFormatTest.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.media.cts;
+
+import android.cts.util.CtsAndroidTestCase;
+import android.media.AudioFormat;
+
+public class AudioFormatTest extends CtsAndroidTestCase {
+
+    // -----------------------------------------------------------------
+    // AUDIOFORMAT TESTS:
+    // ----------------------------------
+
+    // -----------------------------------------------------------------
+    // Builder tests
+    // ----------------------------------
+
+    // Test case 1: Use Builder to duplicate an AudioFormat with all fields supplied
+    public void testBuilderForCopy() 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 formatToCopy = 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 copy", formatToCopy);
+
+        final AudioFormat copiedFormat = new AudioFormat.Builder(formatToCopy).build();
+        assertNotNull("Failure to create AudioFormat copy with Builder", copiedFormat);
+        assertEquals("New AudioFormat has wrong sample rate",
+                TEST_SR, copiedFormat.getSampleRate());
+        assertEquals("New AudioFormat has wrong encoding",
+                TEST_ENCODING, copiedFormat.getEncoding());
+        assertEquals("New AudioFormat has wrong channel mask",
+                TEST_CONF_POS, copiedFormat.getChannelMask());
+        assertEquals("New AudioFormat has wrong channel index mask",
+                TEST_CONF_IDX, copiedFormat.getChannelIndexMask());
+    }
+
+    // Test case 2: Use Builder to duplicate an AudioFormat with only encoding supplied
+    public void testPartialFormatBuilderForCopyEncoding() throws Exception {
+        final int TEST_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
+
+        final AudioFormat formatToCopy = new AudioFormat.Builder()
+                .setEncoding(TEST_ENCODING).build();
+        assertNotNull("Failure to create the AudioFormat to copy", formatToCopy);
+
+        final AudioFormat copiedFormat = new AudioFormat.Builder(formatToCopy).build();
+        assertNotNull("Failure to create AudioFormat copy with Builder", copiedFormat);
+        assertEquals("New AudioFormat has wrong encoding",
+                TEST_ENCODING, copiedFormat.getEncoding());
+        // test expected values when none has been set
+        assertEquals("New AudioFormat doesn't report expected sample rate",
+                0, copiedFormat.getSampleRate());
+        assertEquals("New AudioFormat doesn't report expected channel mask",
+                AudioFormat.CHANNEL_INVALID, copiedFormat.getChannelMask());
+        assertEquals("New AudioFormat doesn't report expected channel index mask",
+                AudioFormat.CHANNEL_INVALID, copiedFormat.getChannelIndexMask());
+    }
+
+    // Test case 3: Use Builder to duplicate an AudioFormat with only sample rate supplied
+    public void testPartialFormatBuilderForCopyRate() throws Exception {
+        final int TEST_SR = 48000;
+
+        final AudioFormat formatToCopy = new AudioFormat.Builder()
+                .setSampleRate(TEST_SR).build();
+        assertNotNull("Failure to create the AudioFormat to copy", formatToCopy);
+
+        final AudioFormat copiedFormat = new AudioFormat.Builder(formatToCopy).build();
+        assertNotNull("Failure to create AudioFormat copy with Builder", copiedFormat);
+        assertEquals("New AudioFormat has wrong sample rate",
+                TEST_SR, copiedFormat.getSampleRate());
+        // test expected values when none has been set
+        assertEquals("New AudioFormat doesn't report expected encoding",
+                AudioFormat.ENCODING_INVALID, copiedFormat.getEncoding());
+        assertEquals("New AudioFormat doesn't report expected channel mask",
+                AudioFormat.CHANNEL_INVALID, copiedFormat.getChannelMask());
+        assertEquals("New AudioFormat doesn't report expected channel index mask",
+                AudioFormat.CHANNEL_INVALID, copiedFormat.getChannelIndexMask());
+    }
+
+    // Test case 4: Use Builder to duplicate an AudioFormat with only channel mask supplied
+    public void testPartialFormatBuilderForCopyChanMask() throws Exception {
+        final int TEST_CONF_POS = AudioFormat.CHANNEL_OUT_5POINT1;
+
+        final AudioFormat formatToCopy = new AudioFormat.Builder()
+                .setChannelMask(TEST_CONF_POS).build();
+        assertNotNull("Failure to create the AudioFormat to copy", formatToCopy);
+
+        final AudioFormat copiedFormat = new AudioFormat.Builder(formatToCopy).build();
+        assertNotNull("Failure to create AudioFormat copy with Builder", copiedFormat);
+        assertEquals("New AudioFormat has wrong channel mask",
+                TEST_CONF_POS, copiedFormat.getChannelMask());
+        // test expected values when none has been set
+        assertEquals("New AudioFormat doesn't report expected encoding",
+                AudioFormat.ENCODING_INVALID, copiedFormat.getEncoding());
+        assertEquals("New AudioFormat doesn't report expected sample rate",
+                0, copiedFormat.getSampleRate());
+        assertEquals("New AudioFormat doesn't report expected channel index mask",
+                AudioFormat.CHANNEL_INVALID, copiedFormat.getChannelIndexMask());
+    }
+
+
+    // Test case 5: Use Builder to duplicate an AudioFormat with only channel index mask supplied
+    public void testPartialFormatBuilderForCopyChanIdxMask() throws Exception {
+        final int TEST_CONF_IDX = 0x30;
+
+        final AudioFormat formatToCopy = new AudioFormat.Builder()
+                .setChannelIndexMask(TEST_CONF_IDX).build();
+        assertNotNull("Failure to create the AudioFormat to copy", formatToCopy);
+
+        final AudioFormat copiedFormat = new AudioFormat.Builder(formatToCopy).build();
+        assertNotNull("Failure to create AudioFormat copy with Builder", copiedFormat);
+        assertEquals("New AudioFormat has wrong channel mask",
+                TEST_CONF_IDX, copiedFormat.getChannelIndexMask());
+        // test expected values when none has been set
+        assertEquals("New AudioFormat doesn't report expected encoding",
+                AudioFormat.ENCODING_INVALID, copiedFormat.getEncoding());
+        assertEquals("New AudioFormat doesn't report expected sample rate",
+                0, copiedFormat.getSampleRate());
+        assertEquals("New AudioFormat doesn't report expected channel mask",
+                AudioFormat.CHANNEL_INVALID, copiedFormat.getChannelMask());
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioHelper.java b/tests/tests/media/src/android/media/cts/AudioHelper.java
new file mode 100644
index 0000000..6707ea6
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioHelper.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 android.media.cts;
+
+import java.nio.ByteBuffer;
+
+import org.junit.Assert;
+
+import android.media.AudioAttributes;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+import android.media.AudioTrack;
+import android.os.Looper;
+
+// Used for statistics and loopers in listener tests.
+// See AudioRecordTest.java and AudioTrack_ListenerTest.java.
+public class AudioHelper {
+
+    // create sine waves or chirps for data arrays
+    public static byte[] createSoundDataInByteArray(int bufferSamples, final int sampleRate,
+            final double frequency, double sweep) {
+        final double rad = 2 * Math.PI * frequency / sampleRate;
+        byte[] vai = new byte[bufferSamples];
+        sweep = Math.PI * sweep / ((double)sampleRate * vai.length);
+        for (int j = 0; j < vai.length; j++) {
+            int unsigned =  (int)(Math.sin(j * (rad + j * sweep)) * Byte.MAX_VALUE)
+                    + Byte.MAX_VALUE & 0xFF;
+            vai[j] = (byte) unsigned;
+        }
+        return vai;
+    }
+
+    public static short[] createSoundDataInShortArray(int bufferSamples, final int sampleRate,
+            final double frequency, double sweep) {
+        final double rad = 2 * Math.PI * frequency / sampleRate;
+        short[] vai = new short[bufferSamples];
+        sweep = Math.PI * sweep / ((double)sampleRate * vai.length);
+        for (int j = 0; j < vai.length; j++) {
+            vai[j] = (short)(Math.sin(j * (rad + j * sweep)) * Short.MAX_VALUE);
+        }
+        return vai;
+    }
+
+    public static float[] createSoundDataInFloatArray(int bufferSamples, final int sampleRate,
+            final double frequency, double sweep) {
+        final double rad = 2 * Math.PI * frequency / sampleRate;
+        float[] vaf = new float[bufferSamples];
+        sweep = Math.PI * sweep / ((double)sampleRate * vaf.length);
+        for (int j = 0; j < vaf.length; j++) {
+            vaf[j] = (float)(Math.sin(j * (rad + j * sweep)));
+        }
+        return vaf;
+    }
+
+    public static int frameSizeFromFormat(AudioFormat format) {
+        return format.getChannelCount()
+                * format.getBytesPerSample(format.getEncoding());
+    }
+
+    public static int frameCountFromMsec(int ms, AudioFormat format) {
+        return ms * format.getSampleRate() / 1000;
+    }
+
+    public static class Statistics {
+        public void add(double value) {
+            final double absValue = Math.abs(value);
+            mSum += value;
+            mSumAbs += absValue;
+            mMaxAbs = Math.max(mMaxAbs, absValue);
+            ++mCount;
+        }
+
+        public double getAvg() {
+            if (mCount == 0) {
+                return 0;
+            }
+            return mSum / mCount;
+        }
+
+        public double getAvgAbs() {
+            if (mCount == 0) {
+                return 0;
+            }
+            return mSumAbs / mCount;
+        }
+
+        public double getMaxAbs() {
+            return mMaxAbs;
+        }
+
+        private int mCount = 0;
+        private double mSum = 0;
+        private double mSumAbs = 0;
+        private double mMaxAbs = 0;
+    }
+
+    // for listener tests
+    // lightweight java.util.concurrent.Future*
+    public static class FutureLatch<T>
+    {
+        private T mValue;
+        private boolean mSet;
+        public void set(T value)
+        {
+            synchronized (this) {
+                assert !mSet;
+                mValue = value;
+                mSet = true;
+                notify();
+            }
+        }
+        public T get()
+        {
+            T value;
+            synchronized (this) {
+                while (!mSet) {
+                    try {
+                        wait();
+                    } catch (InterruptedException e) {
+                        ;
+                    }
+                }
+                value = mValue;
+            }
+            return value;
+        }
+    }
+
+    // for listener tests
+    // represents a factory for T
+    public interface MakesSomething<T>
+    {
+        T makeSomething();
+    }
+
+    // for listener tests
+    // used to construct an object in the context of an asynchronous thread with looper
+    public static class MakeSomethingAsynchronouslyAndLoop<T>
+    {
+        private Thread mThread;
+        volatile private Looper mLooper;
+        private final MakesSomething<T> mWhatToMake;
+
+        public MakeSomethingAsynchronouslyAndLoop(MakesSomething<T> whatToMake)
+        {
+            assert whatToMake != null;
+            mWhatToMake = whatToMake;
+        }
+
+        public T make()
+        {
+            final FutureLatch<T> futureLatch = new FutureLatch<T>();
+            mThread = new Thread()
+            {
+                @Override
+                public void run()
+                {
+                    Looper.prepare();
+                    mLooper = Looper.myLooper();
+                    T something = mWhatToMake.makeSomething();
+                    futureLatch.set(something);
+                    Looper.loop();
+                }
+            };
+            mThread.start();
+            return futureLatch.get();
+        }
+        public void join()
+        {
+            mLooper.quit();
+            try {
+                mThread.join();
+            } catch (InterruptedException e) {
+                ;
+            }
+            // avoid dangling references
+            mLooper = null;
+            mThread = null;
+        }
+    }
+
+    public static int outChannelMaskFromInChannelMask(int channelMask) {
+        switch (channelMask) {
+            case AudioFormat.CHANNEL_IN_MONO:
+                return AudioFormat.CHANNEL_OUT_MONO;
+            case AudioFormat.CHANNEL_IN_STEREO:
+                return AudioFormat.CHANNEL_OUT_STEREO;
+            default:
+                return AudioFormat.CHANNEL_INVALID;
+        }
+    }
+
+    /* AudioRecordAudit extends AudioRecord to allow concurrent playback
+     * of read content to an AudioTrack.  This is for testing only.
+     * For general applications, it is NOT recommended to extend AudioRecord.
+     * This affects AudioRecord timing.
+     */
+    public static class AudioRecordAudit extends AudioRecord {
+        public AudioRecordAudit(int audioSource, int sampleRate, int channelMask,
+                int format, int bufferSize, boolean isChannelIndex) {
+            this(audioSource, sampleRate, channelMask, format, bufferSize, isChannelIndex,
+                    AudioManager.STREAM_MUSIC, 500 /*delayMs*/);
+        }
+
+        public AudioRecordAudit(int audioSource, int sampleRate, int channelMask,
+                int format, int bufferSize,
+                boolean isChannelIndex, int auditStreamType, int delayMs) {
+            // without channel index masks, one could call:
+            // super(audioSource, sampleRate, channelMask, format, bufferSize);
+            super(new AudioAttributes.Builder()
+                            .setInternalCapturePreset(audioSource)
+                            .build(),
+                    (isChannelIndex
+                            ? new AudioFormat.Builder().setChannelIndexMask(channelMask)
+                                    : new AudioFormat.Builder().setChannelMask(channelMask))
+                            .setEncoding(format)
+                            .setSampleRate(sampleRate)
+                            .build(),
+                    bufferSize,
+                    AudioManager.AUDIO_SESSION_ID_GENERATE);
+
+            if (delayMs >= 0) { // create an AudioTrack
+                final int channelOutMask = isChannelIndex ? channelMask :
+                    outChannelMaskFromInChannelMask(channelMask);
+                final int bufferOutFrames = sampleRate * delayMs / 1000;
+                final int bufferOutSamples = bufferOutFrames
+                        * AudioFormat.channelCountFromOutChannelMask(channelOutMask);
+                final int bufferOutSize = bufferOutSamples
+                        * AudioFormat.getBytesPerSample(format);
+
+                // Caution: delayMs too large results in buffer sizes that cannot be created.
+                mTrack = new AudioTrack.Builder()
+                                .setAudioAttributes(new AudioAttributes.Builder()
+                                        .setLegacyStreamType(auditStreamType)
+                                        .build())
+                                .setAudioFormat((isChannelIndex ?
+                                  new AudioFormat.Builder().setChannelIndexMask(channelOutMask) :
+                                  new AudioFormat.Builder().setChannelMask(channelOutMask))
+                                        .setEncoding(format)
+                                        .setSampleRate(sampleRate)
+                                        .build())
+                                .setBufferSizeInBytes(bufferOutSize)
+                                .build();
+                Assert.assertEquals(AudioTrack.STATE_INITIALIZED, mTrack.getState());
+                mPosition = 0;
+                mFinishAtMs = 0;
+            }
+        }
+
+        @Override
+        public int read(byte[] audioData, int offsetInBytes, int sizeInBytes) {
+            // for byte array access we verify format is 8 bit PCM (typical use)
+            Assert.assertEquals(TAG + ": format mismatch",
+                    AudioFormat.ENCODING_PCM_8BIT, getAudioFormat());
+            int samples = super.read(audioData, offsetInBytes, sizeInBytes);
+            if (mTrack != null) {
+                Assert.assertEquals(samples, mTrack.write(audioData, offsetInBytes, samples));
+                mPosition += samples / mTrack.getChannelCount();
+            }
+            return samples;
+        }
+
+        @Override
+        public int read(byte[] audioData, int offsetInBytes, int sizeInBytes, int readMode) {
+            // for byte array access we verify format is 8 bit PCM (typical use)
+            Assert.assertEquals(TAG + ": format mismatch",
+                    AudioFormat.ENCODING_PCM_8BIT, getAudioFormat());
+            int samples = super.read(audioData, offsetInBytes, sizeInBytes, readMode);
+            if (mTrack != null) {
+                Assert.assertEquals(samples, mTrack.write(audioData, offsetInBytes, samples,
+                        AudioTrack.WRITE_BLOCKING));
+                mPosition += samples / mTrack.getChannelCount();
+            }
+            return samples;
+        }
+
+        @Override
+        public int read(short[] audioData, int offsetInShorts, int sizeInShorts) {
+            // for short array access we verify format is 16 bit PCM (typical use)
+            Assert.assertEquals(TAG + ": format mismatch",
+                    AudioFormat.ENCODING_PCM_16BIT, getAudioFormat());
+            int samples = super.read(audioData, offsetInShorts, sizeInShorts);
+            if (mTrack != null) {
+                Assert.assertEquals(samples, mTrack.write(audioData, offsetInShorts, samples));
+                mPosition += samples / mTrack.getChannelCount();
+            }
+            return samples;
+        }
+
+        @Override
+        public int read(short[] audioData, int offsetInShorts, int sizeInShorts, int readMode) {
+            // for short array access we verify format is 16 bit PCM (typical use)
+            Assert.assertEquals(TAG + ": format mismatch",
+                    AudioFormat.ENCODING_PCM_16BIT, getAudioFormat());
+            int samples = super.read(audioData, offsetInShorts, sizeInShorts, readMode);
+            if (mTrack != null) {
+                Assert.assertEquals(samples, mTrack.write(audioData, offsetInShorts, samples,
+                        AudioTrack.WRITE_BLOCKING));
+                mPosition += samples / mTrack.getChannelCount();
+            }
+            return samples;
+        }
+
+        @Override
+        public int read(float[] audioData, int offsetInFloats, int sizeInFloats, int readMode) {
+            // for float array access we verify format is float PCM (typical use)
+            Assert.assertEquals(TAG + ": format mismatch",
+                    AudioFormat.ENCODING_PCM_FLOAT, getAudioFormat());
+            int samples = super.read(audioData, offsetInFloats, sizeInFloats, readMode);
+            if (mTrack != null) {
+                Assert.assertEquals(samples, mTrack.write(audioData, offsetInFloats, samples,
+                        AudioTrack.WRITE_BLOCKING));
+                mPosition += samples / mTrack.getChannelCount();
+            }
+            return samples;
+        }
+
+        @Override
+        public int read(ByteBuffer audioBuffer, int sizeInBytes) {
+            int bytes = super.read(audioBuffer, sizeInBytes);
+            if (mTrack != null) {
+                // read does not affect position and limit of the audioBuffer.
+                // we make a duplicate to change that for writing to the output AudioTrack
+                // which does check position and limit.
+                ByteBuffer copy = audioBuffer.duplicate();
+                copy.position(0).limit(bytes);  // read places data at the start of the buffer.
+                Assert.assertEquals(bytes, mTrack.write(copy, bytes, AudioTrack.WRITE_BLOCKING));
+                mPosition += bytes /
+                        (mTrack.getChannelCount()
+                                * AudioFormat.getBytesPerSample(mTrack.getAudioFormat()));
+            }
+            return bytes;
+        }
+
+        @Override
+        public int read(ByteBuffer audioBuffer, int sizeInBytes, int readMode) {
+            int bytes = super.read(audioBuffer, sizeInBytes, readMode);
+            if (mTrack != null) {
+                // read does not affect position and limit of the audioBuffer.
+                // we make a duplicate to change that for writing to the output AudioTrack
+                // which does check position and limit.
+                ByteBuffer copy = audioBuffer.duplicate();
+                copy.position(0).limit(bytes);  // read places data at the start of the buffer.
+                Assert.assertEquals(bytes, mTrack.write(copy, bytes, AudioTrack.WRITE_BLOCKING));
+                mPosition += bytes /
+                        (mTrack.getChannelCount()
+                                * AudioFormat.getBytesPerSample(mTrack.getAudioFormat()));
+            }
+            return bytes;
+        }
+
+        @Override
+        public void startRecording() {
+            super.startRecording();
+            if (mTrack != null) {
+                mTrack.play();
+            }
+        }
+
+        @Override
+        public void stop() {
+            super.stop();
+            if (mTrack != null) {
+                if (mPosition > 0) { // stop may be called multiple times.
+                    final int remainingFrames = mPosition - mTrack.getPlaybackHeadPosition();
+                    mFinishAtMs = System.currentTimeMillis()
+                            + remainingFrames * 1000 / mTrack.getSampleRate();
+                    mPosition = 0;
+                }
+                mTrack.stop(); // allows remaining data to play out
+            }
+        }
+
+        @Override
+        public void release() {
+            super.release();
+            if (mTrack != null) {
+                final long remainingMs = mFinishAtMs - System.currentTimeMillis();
+                if (remainingMs > 0) {
+                    try {
+                        Thread.sleep(remainingMs);
+                    } catch (InterruptedException e) {
+                        ;
+                    }
+                }
+                mTrack.release();
+                mTrack = null;
+            }
+        }
+
+        public AudioTrack mTrack;
+        private final static String TAG = "AudioRecordAudit";
+        private int mPosition;
+        private long mFinishAtMs;
+    }
+
+    /* AudioRecordAudit extends AudioRecord to allow concurrent playback
+     * of read content to an AudioTrack.  This is for testing only.
+     * For general applications, it is NOT recommended to extend AudioRecord.
+     * This affects AudioRecord timing.
+     */
+    public static class AudioRecordAuditNative extends AudioRecordNative {
+        public AudioRecordAuditNative() {
+            super();
+            // Caution: delayMs too large results in buffer sizes that cannot be created.
+            mTrack = new AudioTrackNative();
+        }
+
+        @Override
+        public boolean open(int numChannels, int sampleRate, boolean useFloat, int numBuffers) {
+            if (super.open(numChannels, sampleRate, useFloat, numBuffers)) {
+                if (!mTrack.open(numChannels, sampleRate, useFloat, 2 /* numBuffers */)) {
+                    mTrack = null; // remove track
+                }
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void close() {
+            super.close();
+            if (mTrack != null) {
+                mTrack.close();
+            }
+        }
+
+        @Override
+        public boolean start() {
+            if (super.start()) {
+                if (mTrack != null) {
+                    mTrack.start();
+                }
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public boolean stop() {
+            if (super.stop()) {
+                if (mTrack != null) {
+                    mTrack.stop(); // doesn't allow remaining data to play out
+                }
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public int read(short[] audioData, int offsetInShorts, int sizeInShorts, int readFlags) {
+            int samples = super.read(audioData, offsetInShorts, sizeInShorts, readFlags);
+            if (mTrack != null) {
+                Assert.assertEquals(samples, mTrack.write(audioData, offsetInShorts, samples,
+                        AudioTrackNative.WRITE_FLAG_BLOCKING));
+                mPosition += samples / mTrack.getChannelCount();
+            }
+            return samples;
+        }
+
+        @Override
+        public int read(float[] audioData, int offsetInFloats, int sizeInFloats, int readFlags) {
+            int samples = super.read(audioData, offsetInFloats, sizeInFloats, readFlags);
+            if (mTrack != null) {
+                Assert.assertEquals(samples, mTrack.write(audioData, offsetInFloats, samples,
+                        AudioTrackNative.WRITE_FLAG_BLOCKING));
+                mPosition += samples / mTrack.getChannelCount();
+            }
+            return samples;
+        }
+
+        public AudioTrackNative mTrack;
+        private final static String TAG = "AudioRecordAuditNative";
+        private int mPosition;
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index f58e6ab..a0163e5 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -19,7 +19,6 @@
 import static android.media.AudioManager.ADJUST_LOWER;
 import static android.media.AudioManager.ADJUST_RAISE;
 import static android.media.AudioManager.ADJUST_SAME;
-import static android.media.AudioManager.FLAG_ALLOW_RINGER_MODES;
 import static android.media.AudioManager.MODE_IN_CALL;
 import static android.media.AudioManager.MODE_IN_COMMUNICATION;
 import static android.media.AudioManager.MODE_NORMAL;
@@ -45,40 +44,33 @@
 import android.media.MediaPlayer;
 import android.os.Vibrator;
 import android.provider.Settings;
-import android.telephony.TelephonyManager;
-import android.test.AndroidTestCase;
+import android.provider.Settings.System;
+import android.test.InstrumentationTestCase;
 import android.view.SoundEffectConstants;
 
 import java.util.TreeMap;
 
-public class AudioManagerTest extends AndroidTestCase {
+public class AudioManagerTest extends InstrumentationTestCase {
 
     private final static int MP3_TO_PLAY = R.raw.testmp3;
     private final static long TIME_TO_PLAY = 2000;
+    private final static String APPOPS_OP_STR = "android:write_settings";
     private AudioManager mAudioManager;
     private boolean mHasVibrator;
-    private boolean mUseMasterVolume;
     private boolean mUseFixedVolume;
-    private int[] mMasterVolumeRamp;
-    private TreeMap<Integer, Integer> mMasterVolumeMap = new TreeMap<Integer, Integer>();
     private boolean mIsTelevision;
+    private Context mContext;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        mContext = getInstrumentation().getContext();
+        Utils.enableAppOps(mContext.getPackageName(), APPOPS_OP_STR, getInstrumentation());
         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
         Vibrator vibrator = (Vibrator) mContext.getSystemService(Context.VIBRATOR_SERVICE);
         mHasVibrator = (vibrator != null) && vibrator.hasVibrator();
-        mUseMasterVolume = mContext.getResources().getBoolean(
-                Resources.getSystem().getIdentifier("config_useMasterVolume", "bool", "android"));
         mUseFixedVolume = mContext.getResources().getBoolean(
                 Resources.getSystem().getIdentifier("config_useFixedVolume", "bool", "android"));
-        mMasterVolumeRamp = mContext.getResources().getIntArray(
-                Resources.getSystem().getIdentifier("config_masterVolumeRamp", "array", "android"));
-        assertTrue((mMasterVolumeRamp.length > 0) && (mMasterVolumeRamp.length % 2 == 0));
-        for (int i = 0; i < mMasterVolumeRamp.length; i+=2) {
-            mMasterVolumeMap.put(mMasterVolumeRamp[i], mMasterVolumeRamp[i+1]);
-        }
         PackageManager packageManager = mContext.getPackageManager();
         mIsTelevision = packageManager != null
                 && (packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
@@ -350,6 +342,12 @@
             mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
 
             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);
 
             mAudioManager.setStreamVolume(streams[i], 1, 0);
             if (mUseFixedVolume) {
@@ -384,7 +382,7 @@
             // volume lower
             mAudioManager.setStreamVolume(streams[i], maxVolume, 0);
             volume = mAudioManager.getStreamVolume(streams[i]);
-            while (volume > 0) {
+            while (volume > minVolume) {
                 volumeDelta = getVolumeDelta(mAudioManager.getStreamVolume(streams[i]));
                 mAudioManager.adjustStreamVolume(streams[i], ADJUST_LOWER, 0);
                 assertEquals(Math.max(0, volume - volumeDelta),
@@ -457,6 +455,88 @@
         assertFalse(mAudioManager.isMusicActive());
     }
 
+    public void testMute() {
+        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)));
+        if (mUseFixedVolume) {
+            for (int i = 0; i < streams.length; i++) {
+                mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_MUTE, 0);
+                assertFalse("Muting should not affect a fixed volume device.",
+                        mAudioManager.isStreamMute(streams[i]));
+
+                mAudioManager.adjustStreamVolume(streams[i], AudioManager.ADJUST_TOGGLE_MUTE, 0);
+                assertFalse("Toggling mute should not affect a fixed volume device.",
+                        mAudioManager.isStreamMute(streams[i]));
+
+                mAudioManager.setStreamMute(streams[i], true);
+                assertFalse("Muting should not affect a fixed volume device.",
+                        mAudioManager.isStreamMute(streams[i]));
+            }
+            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) {
+                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);
+            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]));
+        }
+    }
+
     public void testSetInvalidRingerMode() {
         int ringerMode = mAudioManager.getRingerMode();
         mAudioManager.setRingerMode(-1337);
@@ -467,11 +547,6 @@
     }
 
     private int getVolumeDelta(int volume) {
-        if (!mUseMasterVolume) {
-            return 1;
-        }
-        int volumeDelta = mMasterVolumeMap.floorEntry(volume).getValue();
-        assertTrue(volumeDelta > 0);
-        return volumeDelta;
+        return 1;
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/AudioNativeTest.java b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
new file mode 100644
index 0000000..f52232f
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioNativeTest.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.util.Log;
+
+public class AudioNativeTest extends CtsAndroidTestCase {
+    public void testAppendixBBufferQueue() {
+        nativeAppendixBBufferQueue();
+    }
+
+    public void testAppendixBRecording() {
+        // better to detect presence of microphone here.
+        if (!hasMicrophone()) {
+            return;
+        }
+        nativeAppendixBRecording();
+    }
+
+    public void testStereo16Playback() {
+        assertTrue(AudioTrackNative.test(
+                2 /* numChannels */, 48000 /* sampleRate */, false /* useFloat */,
+                20 /* msecPerBuffer */, 8 /* numBuffers */));
+    }
+
+    public void testStereo16Record() {
+        if (!hasMicrophone()) {
+            return;
+        }
+        assertTrue(AudioRecordNative.test(
+                2 /* numChannels */, 48000 /* sampleRate */, false /* useFloat */,
+                20 /* msecPerBuffer */, 8 /* numBuffers */));
+    }
+
+    public void testPlayStreamData() throws Exception {
+        final String TEST_NAME = "testPlayStreamData";
+        final boolean TEST_FLOAT_ARRAY[] = {
+                false,
+                true,
+        };
+        // due to downmixer algorithmic latency, source channels greater than 2 may
+        // sound shorter in duration at 4kHz sampling rate.
+        final int TEST_SR_ARRAY[] = {
+                /* 4000, */ // below limit of OpenSL ES
+                12345, // irregular sampling rate
+                44100,
+                48000,
+                96000,
+                192000,
+        };
+        final int TEST_CHANNELS_ARRAY[] = {
+                1,
+                2,
+                3,
+                4,
+                5,
+                6,
+                7,
+                // 8  // can fail due to memory issues
+        };
+        final float TEST_SWEEP = 0; // sine wave only
+        final int TEST_TIME_IN_MSEC = 300;
+        final int TOLERANCE_MSEC = 20;
+
+        for (boolean TEST_FLOAT : TEST_FLOAT_ARRAY) {
+            double frequency = 400; // frequency changes for each test
+            for (int TEST_SR : TEST_SR_ARRAY) {
+                for (int TEST_CHANNELS : TEST_CHANNELS_ARRAY) {
+                    // OpenSL ES BUG: we run out of AudioTrack memory for this config on MNC
+                    // Log.d(TEST_NAME, "open channels:" + TEST_CHANNELS + " sr:" + TEST_SR);
+                    if (TEST_FLOAT == true && TEST_CHANNELS >= 6 && TEST_SR >= 192000) {
+                        continue;
+                    }
+                    AudioTrackNative track = new AudioTrackNative();
+                    assertTrue(TEST_NAME,
+                            track.open(TEST_CHANNELS, TEST_SR, TEST_FLOAT, 1 /* numBuffers */));
+                    assertTrue(TEST_NAME, track.start());
+
+                    final int sourceSamples =
+                            (int)((long)TEST_SR * TEST_TIME_IN_MSEC * TEST_CHANNELS / 1000);
+                    final double testFrequency = frequency / TEST_CHANNELS;
+                    if (TEST_FLOAT) {
+                        float data[] = AudioHelper.createSoundDataInFloatArray(
+                                sourceSamples, TEST_SR,
+                                testFrequency, TEST_SWEEP);
+                        assertEquals(sourceSamples,
+                                track.write(data, 0 /* offset */, sourceSamples,
+                                        AudioTrackNative.WRITE_FLAG_BLOCKING));
+                    } else {
+                        short data[] = AudioHelper.createSoundDataInShortArray(
+                                sourceSamples, TEST_SR,
+                                testFrequency, TEST_SWEEP);
+                        assertEquals(sourceSamples,
+                                track.write(data, 0 /* offset */, sourceSamples,
+                                        AudioTrackNative.WRITE_FLAG_BLOCKING));
+                    }
+
+                    while (true) {
+                        // OpenSL ES BUG: getPositionInMsec returns 0 after a data underrun.
+
+                        long position = track.getPositionInMsec();
+                        //Log.d(TEST_NAME, "position: " + position[0]);
+                        if (position >= (long)(TEST_TIME_IN_MSEC - TOLERANCE_MSEC)) {
+                            break;
+                        }
+
+                        // It is safer to use a buffer count of 0 to determine termination
+                        if (track.getBuffersPending() == 0) {
+                            break;
+                        }
+                        Thread.sleep(5 /* millis */);
+                    }
+                    track.stop();
+                    track.close();
+                    Thread.sleep(40 /* millis */);  // put a gap in the tone sequence
+                    frequency += 50; // increment test tone frequency
+                }
+            }
+        }
+    }
+
+    public void testRecordStreamData() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        final String TEST_NAME = "testRecordStreamData";
+        final boolean TEST_FLOAT_ARRAY[] = {
+                false,
+                true,
+        };
+        final int TEST_SR_ARRAY[] = {
+                //4000, // below limit of OpenSL ES
+                12345, // irregular sampling rate
+                44100,
+                48000,
+                96000,
+                192000,
+        };
+        final int TEST_CHANNELS_ARRAY[] = {
+                1,
+                2,
+                3,
+                4,
+                5,
+                6,
+                7,
+                8,
+        };
+        final int SEGMENT_DURATION_IN_MSEC = 20;
+        final int NUMBER_SEGMENTS = 10;
+
+        for (boolean TEST_FLOAT : TEST_FLOAT_ARRAY) {
+            for (int TEST_SR : TEST_SR_ARRAY) {
+                for (int TEST_CHANNELS : TEST_CHANNELS_ARRAY) {
+                    // OpenSL ES BUG: we run out of AudioTrack memory for this config on MNC
+                    if (TEST_FLOAT == true && TEST_CHANNELS >= 8 && TEST_SR >= 192000) {
+                        continue;
+                    }
+                    AudioRecordNative record = new AudioRecordNative();
+                    doRecordTest(record, TEST_CHANNELS, TEST_SR, TEST_FLOAT,
+                            SEGMENT_DURATION_IN_MSEC, NUMBER_SEGMENTS);
+                }
+            }
+        }
+    }
+
+    public void testRecordAudit() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        AudioRecordNative record = new AudioHelper.AudioRecordAuditNative();
+        doRecordTest(record, 4 /* numChannels */, 44100 /* sampleRate */, false /* useFloat */,
+                1000 /* segmentDurationMs */, 10 /* numSegments */);
+    }
+
+    static {
+        System.loadLibrary("audio_jni");
+    }
+
+    private static final String TAG = "AudioNativeTest";
+
+    private void doRecordTest(AudioRecordNative record,
+            int numChannels, int sampleRate, boolean useFloat,
+            int segmentDurationMs, int numSegments) {
+        final String TEST_NAME = "doRecordTest";
+        try {
+            // Log.d(TEST_NAME, "open numChannels:" + numChannels + " sampleRate:" + sampleRate);
+            assertTrue(TEST_NAME, record.open(numChannels, sampleRate, useFloat,
+                    numSegments /* numBuffers */));
+            assertTrue(TEST_NAME, record.start());
+
+            final int sourceSamples =
+                    (int)((long)sampleRate * segmentDurationMs * numChannels / 1000);
+
+            if (useFloat) {
+                float data[] = new float[sourceSamples];
+                for (int i = 0; i < numSegments; ++i) {
+                    assertEquals(sourceSamples,
+                            record.read(data, 0 /* offset */, sourceSamples,
+                                    AudioRecordNative.READ_FLAG_BLOCKING));
+                }
+            } else {
+                short data[] = new short[sourceSamples];
+                for (int i = 0; i < numSegments; ++i) {
+                    assertEquals(sourceSamples,
+                            record.read(data, 0 /* offset */, sourceSamples,
+                                    AudioRecordNative.READ_FLAG_BLOCKING));
+                }
+            }
+            assertTrue(TEST_NAME, record.stop());
+        } finally {
+            record.close();
+        }
+    }
+
+    private boolean hasMicrophone() {
+        return getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_MICROPHONE);
+    }
+
+    private static native void nativeAppendixBBufferQueue();
+    private static native void nativeAppendixBRecording();
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordNative.java b/tests/tests/media/src/android/media/cts/AudioRecordNative.java
new file mode 100644
index 0000000..18df8ee
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioRecordNative.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.cts.util.CtsAndroidTestCase;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class AudioRecordNative {
+    // Must be kept in sync with C++ JNI audio-record-native (AudioRecordNative) READ_FLAG_*
+    public static final int READ_FLAG_BLOCKING = 1 << 0;
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                    READ_FLAG_BLOCKING,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ReadFlags { }
+
+    public AudioRecordNative() {
+        mNativeRecordInJavaObj = nativeCreateRecord();
+    }
+
+    public boolean open(int numChannels, int sampleRate, boolean useFloat, int numBuffers) {
+        if (nativeOpen(mNativeRecordInJavaObj, numChannels, sampleRate, useFloat, numBuffers)
+                == STATUS_OK) {
+            mChannelCount = numChannels;
+            return true;
+        }
+        return false;
+    }
+
+    public void close() {
+        nativeClose(mNativeRecordInJavaObj);
+    }
+
+    public boolean start() {
+        return nativeStart(mNativeRecordInJavaObj) == STATUS_OK;
+    }
+
+    public boolean stop() {
+        return nativeStop(mNativeRecordInJavaObj) == STATUS_OK;
+    }
+
+    public boolean pause() {
+        return nativePause(mNativeRecordInJavaObj) == STATUS_OK;
+    }
+
+    public boolean flush() {
+        return nativeFlush(mNativeRecordInJavaObj) == STATUS_OK;
+    }
+
+    public long getPositionInMsec() {
+        long[] position = new long[1];
+        if (nativeGetPositionInMsec(mNativeRecordInJavaObj, position) != STATUS_OK) {
+            throw new IllegalStateException();
+        }
+        return position[0];
+    }
+
+    public int getBuffersPending() {
+        return nativeGetBuffersPending(mNativeRecordInJavaObj);
+    }
+
+    public int read(@NonNull byte[] byteArray,
+            int offsetInSamples, int sizeInSamples, @ReadFlags int readFlags) {
+        return nativeReadByteArray(
+                mNativeRecordInJavaObj, byteArray, offsetInSamples, sizeInSamples, readFlags);
+    }
+
+    public int read(@NonNull short[] shortArray,
+            int offsetInSamples, int sizeInSamples, @ReadFlags int readFlags) {
+        return nativeReadShortArray(
+                mNativeRecordInJavaObj, shortArray, offsetInSamples, sizeInSamples, readFlags);
+    }
+
+    public int read(@NonNull float[] floatArray,
+            int offsetInSamples, int sizeInSamples, @ReadFlags int readFlags) {
+        return nativeReadFloatArray(
+                mNativeRecordInJavaObj, floatArray, offsetInSamples, sizeInSamples, readFlags);
+    }
+
+    public int getChannelCount() {
+        return mChannelCount;
+    }
+
+    public static boolean test(int numChannels, int sampleRate, boolean useFloat,
+            int msecPerBuffer, int numBuffers) {
+        return nativeTest(numChannels, sampleRate, useFloat, msecPerBuffer, numBuffers)
+                == STATUS_OK;
+    }
+
+    @Override
+    protected void finalize() {
+        nativeClose(mNativeRecordInJavaObj);
+        nativeDestroyRecord(mNativeRecordInJavaObj);
+    }
+
+    static {
+        System.loadLibrary("audio_jni");
+    }
+
+    private static final String TAG = "AudioRecordNative";
+    private int mChannelCount;
+    private final long mNativeRecordInJavaObj;
+    private static final int STATUS_OK = 0;
+
+    // static native API.
+    // The native API uses a long "record handle" created by nativeCreateRecord.
+    // The handle must be destroyed after use by nativeDestroyRecord.
+    //
+    // Return codes from the native layer are status_t.
+    // Converted to Java booleans or exceptions at the public API layer.
+    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);
+    private static native void nativeClose(long record);
+    private static native int nativeStart(long record);
+    private static native int nativeStop(long record);
+    private static native int nativePause(long record);
+    private static native int nativeFlush(long record);
+    private static native int nativeGetPositionInMsec(long record, @NonNull long[] position);
+    private static native int nativeGetBuffersPending(long record);
+    private static native int nativeReadByteArray(long record, @NonNull byte[] byteArray,
+            int offsetInSamples, int sizeInSamples, @ReadFlags int readFlags);
+    private static native int nativeReadShortArray(long record, @NonNull short[] shortArray,
+            int offsetInSamples, int sizeInSamples, @ReadFlags int readFlags);
+    private static native int nativeReadFloatArray(long record, @NonNull float[] floatArray,
+            int offsetInSamples, int sizeInSamples, @ReadFlags int readFlags);
+
+    // 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);
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioRecordTest.java b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
index 7ff631f..41afab4 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecordTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecordTest.java
@@ -17,26 +17,46 @@
 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;
+import android.cts.util.CtsAndroidTestCase;
 import android.media.AudioFormat;
+import android.media.AudioManager;
 import android.media.AudioRecord;
-import android.media.MediaRecorder;
 import android.media.AudioRecord.OnRecordPositionUpdateListener;
+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.test.AndroidTestCase;
+import android.util.Log;
 
-public class AudioRecordTest extends AndroidTestCase {
+import com.android.cts.util.ReportLog;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
 
+public class AudioRecordTest extends CtsAndroidTestCase {
+    private final static String TAG = "AudioRecordTest";
     private AudioRecord mAudioRecord;
     private int mHz = 44100;
     private boolean mIsOnMarkerReachedCalled;
     private boolean mIsOnPeriodicNotificationCalled;
     private boolean mIsHandleMessageCalled;
     private Looper mLooper;
-    private int MAX_RECORD_START_TIME_MS = 100;
+    // For doTest
+    private int mMarkerPeriodInFrames;
+    private int mMarkerPosition;
+    private Handler mHandler = new Handler(Looper.getMainLooper()) {
+        @Override
+        public void handleMessage(Message msg) {
+            mIsHandleMessageCalled = true;
+            super.handleMessage(msg);
+        }
+    };
 
     @Override
     protected void setUp() throws Exception {
@@ -212,7 +232,863 @@
         assertEquals(AudioRecord.STATE_UNINITIALIZED, mAudioRecord.getState());
     }
 
+    public void testAudioRecordResamplerMono8Bit() throws Exception {
+        doTest("ResamplerResamplerMono8Bit", true /*localRecord*/, false /*customHandler*/,
+                1 /*periodsPerSecond*/, 1 /*markerPeriodsPerSecond*/,
+                false /*useByteBuffer*/,  false /*blocking*/,
+                false /*auditRecording*/, false /*isChannelIndex*/, 88200 /*TEST_SR*/,
+                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_8BIT);
+    }
+
+    public void testAudioRecordResamplerStereo8Bit() throws Exception {
+        doTest("ResamplerStereo8Bit", true /*localRecord*/, false /*customHandler*/,
+                0 /*periodsPerSecond*/, 3 /*markerPeriodsPerSecond*/,
+                true /*useByteBuffer*/,  true /*blocking*/,
+                false /*auditRecording*/, false /*isChannelIndex*/, 45000 /*TEST_SR*/,
+                AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_8BIT);
+    }
+
+    public void testAudioRecordLocalMono16Bit() throws Exception {
+        doTest("LocalMono16Bit", true /*localRecord*/, false /*customHandler*/,
+                30 /*periodsPerSecond*/, 2 /*markerPeriodsPerSecond*/,
+                false /*useByteBuffer*/, true /*blocking*/,
+                false /*auditRecording*/, false /*isChannelIndex*/, 8000 /*TEST_SR*/,
+                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
+    }
+
+    public void testAudioRecordStereo16Bit() throws Exception {
+        doTest("Stereo16Bit", false /*localRecord*/, false /*customHandler*/,
+                2 /*periodsPerSecond*/, 2 /*markerPeriodsPerSecond*/,
+                false /*useByteBuffer*/, false /*blocking*/,
+                false /*auditRecording*/, false /*isChannelIndex*/, 17000 /*TEST_SR*/,
+                AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT);
+    }
+
+    public void testAudioRecordMonoFloat() throws Exception {
+        doTest("MonoFloat", false /*localRecord*/, true /*customHandler*/,
+                30 /*periodsPerSecond*/, 2 /*markerPeriodsPerSecond*/,
+                false /*useByteBuffer*/, true /*blocking*/,
+                false /*auditRecording*/, false /*isChannelIndex*/, 32000 /*TEST_SR*/,
+                AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_FLOAT);
+    }
+
+    public void testAudioRecordLocalNonblockingStereoFloat() throws Exception {
+        doTest("LocalNonblockingStereoFloat", true /*localRecord*/, true /*customHandler*/,
+                2 /*periodsPerSecond*/, 0 /*markerPeriodsPerSecond*/,
+                false /*useByteBuffer*/, false /*blocking*/,
+                false /*auditRecording*/, false /*isChannelIndex*/, 48000 /*TEST_SR*/,
+                AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_FLOAT);
+    }
+
+    // Audit modes work best with non-blocking mode
+    public void testAudioRecordAuditByteBufferResamplerStereoFloat() throws Exception {
+        if (isLowRamDevice()) {
+            return; // skip. FIXME: reenable when AF memory allocation is updated.
+        }
+        doTest("AuditByteBufferResamplerStereoFloat",
+                false /*localRecord*/, true /*customHandler*/,
+                2 /*periodsPerSecond*/, 0 /*markerPeriodsPerSecond*/,
+                true /*useByteBuffer*/, false /*blocking*/,
+                true /*auditRecording*/, false /*isChannelIndex*/, 96000 /*TEST_SR*/,
+                AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_FLOAT);
+    }
+
+    public void testAudioRecordAuditChannelIndexMonoFloat() throws Exception {
+        doTest("AuditChannelIndexMonoFloat", true /*localRecord*/, true /*customHandler*/,
+                2 /*periodsPerSecond*/, 0 /*markerPeriodsPerSecond*/,
+                false /*useByteBuffer*/, false /*blocking*/,
+                true /*auditRecording*/, true /*isChannelIndex*/, 47000 /*TEST_SR*/,
+                (1 << 0) /* 1 channel */, AudioFormat.ENCODING_PCM_FLOAT);
+    }
+
+    // Audit buffers can run out of space with high sample rate,
+    // so keep the channels and pcm encoding low
+    public void testAudioRecordAuditChannelIndex2() throws Exception {
+        if (isLowRamDevice()) {
+            return; // skip. FIXME: reenable when AF memory allocation is updated.
+        }
+        doTest("AuditChannelIndex2", true /*localRecord*/, true /*customHandler*/,
+                2 /*periodsPerSecond*/, 0 /*markerPeriodsPerSecond*/,
+                false /*useByteBuffer*/, false /*blocking*/,
+                true /*auditRecording*/, true /*isChannelIndex*/, 192000 /*TEST_SR*/,
+                (1 << 0) | (1 << 2) /* 2 channels, gap in middle */,
+                AudioFormat.ENCODING_PCM_8BIT);
+    }
+
+    // Audit buffers can run out of space with high numbers of channels,
+    // so keep the sample rate low.
+    public void testAudioRecordAuditChannelIndex5() throws Exception {
+        doTest("AuditChannelIndex5", true /*localRecord*/, true /*customHandler*/,
+                2 /*periodsPerSecond*/, 0 /*markerPeriodsPerSecond*/,
+                false /*useByteBuffer*/, false /*blocking*/,
+                true /*auditRecording*/, true /*isChannelIndex*/, 16000 /*TEST_SR*/,
+                (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)  /* 5 channels */,
+                AudioFormat.ENCODING_PCM_16BIT);
+    }
+
+    // Test AudioRecord.Builder to verify the observed configuration of an AudioRecord built with
+    // an empty Builder matches the documentation / expected values
+    public void testAudioRecordBuilderDefault() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        // constants for test
+        final String TEST_NAME = "testAudioRecordBuilderDefault";
+        // expected values below match the AudioRecord.Builder documentation
+        final int expectedCapturePreset = MediaRecorder.AudioSource.DEFAULT;
+        final String rateStr = new AudioManager(getContext())
+                .getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE);
+        final int expectedRate = Integer.valueOf(rateStr).intValue();
+        final int expectedChannel = AudioFormat.CHANNEL_IN_MONO;
+        final int expectedEncoding = AudioFormat.ENCODING_PCM_16BIT;
+        final int expectedState = AudioRecord.STATE_INITIALIZED;
+        // use builder with default values
+        final AudioRecord rec = new AudioRecord.Builder().build();
+        // save results
+        final int observedRate = rec.getSampleRate();
+        final int observedSource = rec.getAudioSource();
+        final int observedChannel = rec.getChannelConfiguration();
+        final int observedEncoding = rec.getAudioFormat();
+        final int observedState = rec.getState();
+        // release recorder before the test exits (either successfully or with an exception)
+        rec.release();
+        // compare results
+        assertEquals(TEST_NAME + ": default capture preset", expectedCapturePreset, observedSource);
+        assertEquals(TEST_NAME + ": default rate", expectedRate, observedRate);
+        assertEquals(TEST_NAME + ": default channel config", expectedChannel, observedChannel);
+        assertEquals(TEST_NAME + ": default encoding", expectedEncoding, observedEncoding);
+        assertEquals(TEST_NAME + ": state", expectedState, observedState);
+    }
+
+    // Test AudioRecord.Builder to verify the observed configuration of an AudioRecord built with
+    // an incomplete AudioFormat matches the documentation / expected values
+    public void testAudioRecordBuilderPartialFormat() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        // constants for test
+        final String TEST_NAME = "testAudioRecordBuilderPartialFormat";
+        final int expectedRate = 16000;
+        final int expectedState = AudioRecord.STATE_INITIALIZED;
+        // expected values below match the AudioRecord.Builder documentation
+        final int expectedChannel = AudioFormat.CHANNEL_IN_MONO;
+        final int expectedEncoding = AudioFormat.ENCODING_PCM_16BIT;
+        // use builder with a partial audio format
+        final AudioRecord rec = new AudioRecord.Builder()
+                .setAudioFormat(new AudioFormat.Builder().setSampleRate(expectedRate).build())
+                .build();
+        // save results
+        final int observedRate = rec.getSampleRate();
+        final int observedChannel = rec.getChannelConfiguration();
+        final int observedEncoding = rec.getAudioFormat();
+        final int observedState = rec.getState();
+        // release recorder before the test exits (either successfully or with an exception)
+        rec.release();
+        // compare results
+        assertEquals(TEST_NAME + ": configured rate", expectedRate, observedRate);
+        assertEquals(TEST_NAME + ": default channel config", expectedChannel, observedChannel);
+        assertEquals(TEST_NAME + ": default encoding", expectedEncoding, observedEncoding);
+        assertEquals(TEST_NAME + ": state", expectedState, observedState);
+    }
+
+    // Test AudioRecord.Builder to verify the observed configuration of an AudioRecord matches
+    // the parameters used in the builder
+    public void testAudioRecordBuilderParams() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        // constants for test
+        final String TEST_NAME = "testAudioRecordBuilderParams";
+        final int expectedRate = 8000;
+        final int expectedChannel = AudioFormat.CHANNEL_IN_MONO;
+        final int expectedChannelCount = 1;
+        final int expectedEncoding = AudioFormat.ENCODING_PCM_16BIT;
+        final int expectedSource = MediaRecorder.AudioSource.VOICE_COMMUNICATION;
+        final int expectedState = AudioRecord.STATE_INITIALIZED;
+        // use builder with expected parameters
+        final AudioRecord rec = new AudioRecord.Builder()
+                .setAudioFormat(new AudioFormat.Builder()
+                        .setSampleRate(expectedRate)
+                        .setChannelMask(expectedChannel)
+                        .setEncoding(expectedEncoding)
+                        .build())
+                .setAudioSource(expectedSource)
+                .build();
+        // save results
+        final int observedRate = rec.getSampleRate();
+        final int observedChannel = rec.getChannelConfiguration();
+        final int observedChannelCount = rec.getChannelCount();
+        final int observedEncoding = rec.getAudioFormat();
+        final int observedSource = rec.getAudioSource();
+        final int observedState = rec.getState();
+        // release recorder before the test exits (either successfully or with an exception)
+        rec.release();
+        // compare results
+        assertEquals(TEST_NAME + ": configured rate", expectedRate, observedRate);
+        assertEquals(TEST_NAME + ": configured channel config", expectedChannel, observedChannel);
+        assertEquals(TEST_NAME + ": configured encoding", expectedEncoding, observedEncoding);
+        assertEquals(TEST_NAME + ": implicit channel count", expectedChannelCount,
+                observedChannelCount);
+        assertEquals(TEST_NAME + ": configured source", expectedSource, observedSource);
+        assertEquals(TEST_NAME + ": state", expectedState, observedState);
+    }
+
+    // Test AudioRecord to ensure we can build after a failure.
+    public void testAudioRecordBufferSize() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        // constants for test
+        final String TEST_NAME = "testAudioRecordBufferSize";
+
+        // use builder with parameters that should fail
+        final int superBigBufferSize = 1 << 28;
+        try {
+            final AudioRecord record = new AudioRecord.Builder()
+                .setBufferSizeInBytes(superBigBufferSize)
+                .build();
+            record.release();
+            fail(TEST_NAME + ": should throw exception on failure");
+        } catch (UnsupportedOperationException e) {
+            ;
+        }
+
+        // we should be able to create again with minimum buffer size
+        final int verySmallBufferSize = 2 * 3 * 4; // frame size multiples
+        final AudioRecord record2 = new AudioRecord.Builder()
+                .setBufferSizeInBytes(verySmallBufferSize)
+                .build();
+
+        final int observedState2 = record2.getState();
+        final int observedBufferSize2 = record2.getBufferSizeInFrames();
+        record2.release();
+
+        // succeeds for minimum buffer size
+        assertEquals(TEST_NAME + ": state", AudioRecord.STATE_INITIALIZED, observedState2);
+        // should force the minimum size buffer which is > 0
+        assertTrue(TEST_NAME + ": buffer frame count", observedBufferSize2 > 0);
+    }
+
+    public void testSynchronizedRecord() throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        final String TEST_NAME = "testSynchronizedRecord";
+        AudioTrack track = null;
+        AudioRecord record = null;
+
+        try {
+            // 1. create a static AudioTrack.
+            final int PLAYBACK_TIME_IN_MS = 2000; /* ms duration. */
+            final int PLAYBACK_SAMPLE_RATE = 8000; /* in hz */
+            AudioFormat format = new AudioFormat.Builder()
+                    .setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
+                    .setEncoding(AudioFormat.ENCODING_PCM_8BIT)
+                    .setSampleRate(PLAYBACK_SAMPLE_RATE)
+                    .build();
+            final int frameCount = AudioHelper.frameCountFromMsec(PLAYBACK_TIME_IN_MS, format);
+            final int frameSize = AudioHelper.frameSizeFromFormat(format);
+            track = new AudioTrack.Builder()
+                    .setAudioFormat(format)
+                    .setBufferSizeInBytes(frameCount * frameSize)
+                    .setTransferMode(AudioTrack.MODE_STATIC)
+                    .build();
+            // create float array and write it
+            final int sampleCount = frameCount * format.getChannelCount();
+            byte[] vab = AudioHelper.createSoundDataInByteArray(
+                    sampleCount, PLAYBACK_SAMPLE_RATE, 600 /* frequency */, 0 /* sweep */);
+            assertEquals(TEST_NAME, vab.length,
+                    track.write(vab, 0 /* offsetInBytes */, vab.length,
+                            AudioTrack.WRITE_NON_BLOCKING));
+            final int trackSessionId = track.getAudioSessionId();
+
+            // 2. create an AudioRecord to sync off of AudioTrack completion.
+            final int RECORD_TIME_IN_MS = 2000;
+            final int RECORD_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
+            final int RECORD_CHANNEL_MASK = AudioFormat.CHANNEL_IN_STEREO;
+            final int RECORD_SAMPLE_RATE = 44100;
+            record = new AudioRecord.Builder()
+                    .setAudioFormat(new AudioFormat.Builder()
+                            .setSampleRate(RECORD_SAMPLE_RATE)
+                            .setChannelMask(RECORD_CHANNEL_MASK)
+                            .setEncoding(RECORD_ENCODING)
+                            .build())
+                    .build();
+            // AudioRecord creation may have silently failed, check state now
+            assertEquals(TEST_NAME, AudioRecord.STATE_INITIALIZED, record.getState());
+
+            // 3. create a MediaSyncEvent
+            // This MediaSyncEvent checks playback completion of an AudioTrack
+            // (or MediaPlayer, or ToneGenerator) based on its audio session id.
+            //
+            // Note: when synchronizing record from a MediaSyncEvent
+            // (1) You need to be "close" to the end of the associated AudioTrack.
+            // If the track does not complete in 30 seconds, recording begins regardless.
+            // (actual delay limit may vary).
+            //
+            // (2) Track completion may be triggered by pause() as well as stop()
+            // or when a static AudioTrack completes playback.
+            //
+            final int eventType = MediaSyncEvent.SYNC_EVENT_PRESENTATION_COMPLETE;
+            MediaSyncEvent event = MediaSyncEvent.createEvent(eventType)
+                    .setAudioSessionId(trackSessionId);
+            assertEquals(TEST_NAME, trackSessionId, event.getAudioSessionId());
+            assertEquals(TEST_NAME, eventType, event.getType());
+
+            // 4. now set the AudioTrack playing and start the recording synchronized
+            track.play();
+            // start recording.  Recording state turns to RECORDSTATE_RECORDING immediately
+            // but the data read() only occurs after the AudioTrack completes.
+            record.startRecording(event);
+            assertEquals(TEST_NAME,
+                    AudioRecord.RECORDSTATE_RECORDING, record.getRecordingState());
+            long startTime = System.currentTimeMillis();
+
+            // 5. get record data.
+            // 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 targetSamples =
+                    (int)((long)RECORD_TIME_IN_MS * RECORD_SAMPLE_RATE * numChannels / 1000);
+            final int BUFFER_FRAMES = 512;
+            final int BUFFER_SAMPLES = BUFFER_FRAMES * numChannels;
+
+            // After starting, there is no guarantee when the first frame of data is read.
+            long firstSampleTime = 0;
+            int samplesRead = 0;
+
+            // For 16 bit data, use shorts
+            short[] shortData = new short[BUFFER_SAMPLES];
+            while (samplesRead < targetSamples) {
+                // the first time through, we read a single frame.
+                // this sets the recording anchor position.
+                int amount = samplesRead == 0 ? numChannels :
+                    Math.min(BUFFER_SAMPLES, targetSamples - samplesRead);
+                int ret = record.read(shortData, 0, amount);
+                assertEquals(TEST_NAME, amount, ret);
+                if (samplesRead == 0 && ret > 0) {
+                    firstSampleTime = System.currentTimeMillis();
+                }
+                samplesRead += ret;
+                // sanity check: elapsed time cannot be more than a second
+                // than what we expect.
+                assertTrue(System.currentTimeMillis() - startTime <=
+                        PLAYBACK_TIME_IN_MS + RECORD_TIME_IN_MS + 1000);
+            }
+
+            // 6. We've read all the frames, now check the timing.
+            final long endTime = System.currentTimeMillis();
+            //Log.d(TEST_NAME, "first sample time " + (firstSampleTime - startTime)
+            //        + " test time " + (endTime - firstSampleTime));
+            //
+            // Verify recording starts within 400 ms of AudioTrack completion (typical 180ms)
+            // Verify recording completes within 50 ms of expected test time (typical 20ms)
+            assertEquals(TEST_NAME, PLAYBACK_TIME_IN_MS, firstSampleTime - startTime, 400);
+            assertEquals(TEST_NAME, RECORD_TIME_IN_MS, endTime - firstSampleTime, 50);
+
+            record.stop();
+            assertEquals(TEST_NAME, AudioRecord.RECORDSTATE_STOPPED, record.getRecordingState());
+        } finally {
+            if (record != null) {
+                record.release();
+                record = null;
+            }
+            if (track != null) {
+                track.release();
+                track = null;
+            }
+        }
+    }
+
+    private AudioRecord createAudioRecord(
+            int audioSource, int sampleRateInHz,
+            int channelConfig, int audioFormat, int bufferSizeInBytes,
+            boolean auditRecording, boolean isChannelIndex) {
+        final AudioRecord record;
+        if (auditRecording) {
+            record = new AudioHelper.AudioRecordAudit(
+                    audioSource, sampleRateInHz, channelConfig,
+                    audioFormat, bufferSizeInBytes, isChannelIndex);
+        } else if (isChannelIndex) {
+            record = new AudioRecord.Builder()
+                    .setAudioFormat(new AudioFormat.Builder()
+                            .setChannelIndexMask(channelConfig)
+                            .setEncoding(audioFormat)
+                            .setSampleRate(sampleRateInHz)
+                            .build())
+                    .setBufferSizeInBytes(bufferSizeInBytes)
+                    .build();
+        } else {
+            record = new AudioRecord(audioSource, sampleRateInHz, channelConfig,
+                    audioFormat, bufferSizeInBytes);
+        }
+
+        // did we get the AudioRecord we expected?
+        final AudioFormat format = record.getFormat();
+        assertEquals(isChannelIndex ? channelConfig : AudioFormat.CHANNEL_INVALID,
+                format.getChannelIndexMask());
+        assertEquals(isChannelIndex ? AudioFormat.CHANNEL_INVALID : channelConfig,
+                format.getChannelMask());
+        assertEquals(audioFormat, format.getEncoding());
+        assertEquals(sampleRateInHz, format.getSampleRate());
+        final int frameSize =
+                format.getChannelCount() * AudioFormat.getBytesPerSample(audioFormat);
+        // our native frame count cannot be smaller than our minimum buffer size request.
+        assertTrue(record.getBufferSizeInFrames() * frameSize >= bufferSizeInBytes);
+        return record;
+    }
+
+    private void doTest(String reportName, boolean localRecord, boolean customHandler,
+            int periodsPerSecond, int markerPeriodsPerSecond,
+            boolean useByteBuffer, boolean blocking,
+            final boolean auditRecording, final boolean isChannelIndex,
+            final int TEST_SR, final int TEST_CONF, final int TEST_FORMAT) throws Exception {
+        if (!hasMicrophone()) {
+            return;
+        }
+        // audit recording plays back recorded audio, so use longer test timing
+        final int TEST_TIME_MS = auditRecording ? 10000 : 2000;
+        final int TEST_SOURCE = MediaRecorder.AudioSource.DEFAULT;
+        mIsHandleMessageCalled = false;
+
+        // For channelIndex use one frame in bytes for buffer size.
+        // This is adjusted to the minimum buffer size by native code.
+        final int bufferSizeInBytes = isChannelIndex ?
+                (AudioFormat.getBytesPerSample(TEST_FORMAT)
+                        * AudioFormat.channelCountFromInChannelMask(TEST_CONF)) :
+                AudioRecord.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
+        assertTrue(bufferSizeInBytes > 0);
+
+        final AudioRecord record;
+        final AudioHelper
+                .MakeSomethingAsynchronouslyAndLoop<AudioRecord> makeSomething;
+
+        if (localRecord) {
+            makeSomething = null;
+            record = createAudioRecord(TEST_SOURCE, TEST_SR, TEST_CONF,
+                    TEST_FORMAT, bufferSizeInBytes, auditRecording, isChannelIndex);
+        } else {
+            makeSomething =
+                    new AudioHelper.MakeSomethingAsynchronouslyAndLoop<AudioRecord>(
+                            new AudioHelper.MakesSomething<AudioRecord>() {
+                                @Override
+                                public AudioRecord makeSomething() {
+                                    return createAudioRecord(TEST_SOURCE, TEST_SR, TEST_CONF,
+                                            TEST_FORMAT, bufferSizeInBytes, auditRecording,
+                                            isChannelIndex);
+                                }
+                            }
+                            );
+           // create AudioRecord on different thread's looper.
+           record = makeSomething.make();
+        }
+
+        // AudioRecord creation may have silently failed, check state now
+        assertEquals(AudioRecord.STATE_INITIALIZED, record.getState());
+
+        final MockOnRecordPositionUpdateListener listener;
+        if (customHandler) {
+            listener = new MockOnRecordPositionUpdateListener(record, mHandler);
+        } else {
+            listener = new MockOnRecordPositionUpdateListener(record);
+        }
+
+        final int updatePeriodInFrames = (periodsPerSecond == 0)
+                ? 0 : TEST_SR / periodsPerSecond;
+        // After starting, there is no guarantee when the first frame of data is read.
+        long firstSampleTime = 0;
+
+        // blank final variables: all successful paths will initialize the times.
+        // this must be declared here for visibility as they are set within the try block.
+        final long endTime;
+        final long startTime;
+        final long stopRequestTime;
+        final long stopTime;
+        final long coldInputStartTime;
+
+        try {
+            if (markerPeriodsPerSecond != 0) {
+                mMarkerPeriodInFrames = TEST_SR / markerPeriodsPerSecond;
+                mMarkerPosition = mMarkerPeriodInFrames;
+                assertEquals(AudioRecord.SUCCESS,
+                        record.setNotificationMarkerPosition(mMarkerPosition));
+            } else {
+                mMarkerPeriodInFrames = 0;
+            }
+
+            assertEquals(AudioRecord.SUCCESS,
+                    record.setPositionNotificationPeriod(updatePeriodInFrames));
+
+            listener.start(TEST_SR);
+            record.startRecording();
+            assertEquals(AudioRecord.RECORDSTATE_RECORDING, record.getRecordingState());
+            startTime = System.currentTimeMillis();
+
+            // 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(TEST_CONF);
+            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 BUFFER_FRAMES = 512;
+            final int BUFFER_SAMPLES = BUFFER_FRAMES * numChannels;
+            // TODO: verify behavior when buffer size is not a multiple of frame size.
+
+            int samplesRead = 0;
+            if (useByteBuffer) {
+                ByteBuffer byteBuffer =
+                        ByteBuffer.allocateDirect(BUFFER_SAMPLES * bytesPerSample);
+                while (samplesRead < targetSamples) {
+                    // the first time through, we read a single frame.
+                    // this sets the recording anchor position.
+                    int amount = samplesRead == 0 ? numChannels :
+                        Math.min(BUFFER_SAMPLES, targetSamples - samplesRead);
+                    amount *= bytesPerSample;    // in bytes
+                    // read always places data at the start of the byte buffer with
+                    // position and limit are ignored.  test this by setting
+                    // position and limit to arbitrary values here.
+                    final int lastPosition = 7;
+                    final int lastLimit = 13;
+                    byteBuffer.position(lastPosition);
+                    byteBuffer.limit(lastLimit);
+                    int ret = blocking ? record.read(byteBuffer, amount) :
+                        record.read(byteBuffer, amount, AudioRecord.READ_NON_BLOCKING);
+                    // so long as amount requested in bytes is a multiple of the frame size
+                    // we expect the byte buffer request to be filled.  Caution: the
+                    // byte buffer data will be in native endian order, not Java order.
+                    if (blocking) {
+                        assertEquals(amount, ret);
+                    } else {
+                        assertTrue("0 <= " + ret + " <= " + amount,
+                                0 <= ret && ret <= amount);
+                    }
+                    // position, limit are not changed by read().
+                    assertEquals(lastPosition, byteBuffer.position());
+                    assertEquals(lastLimit, byteBuffer.limit());
+                    if (samplesRead == 0 && ret > 0) {
+                        firstSampleTime = System.currentTimeMillis();
+                    }
+                    samplesRead += ret / bytesPerSample;
+                }
+            } else {
+                switch (TEST_FORMAT) {
+                case AudioFormat.ENCODING_PCM_8BIT: {
+                    // For 8 bit data, use bytes
+                    byte[] byteData = new byte[BUFFER_SAMPLES];
+                    while (samplesRead < targetSamples) {
+                        // the first time through, we read a single frame.
+                        // this sets the recording anchor position.
+                        int amount = samplesRead == 0 ? numChannels :
+                            Math.min(BUFFER_SAMPLES, targetSamples - samplesRead);
+                        int ret = blocking ? record.read(byteData, 0, amount) :
+                            record.read(byteData, 0, amount, AudioRecord.READ_NON_BLOCKING);
+                        if (blocking) {
+                            assertEquals(amount, ret);
+                        } else {
+                            assertTrue("0 <= " + ret + " <= " + amount,
+                                    0 <= ret && ret <= amount);
+                        }
+                        if (samplesRead == 0 && ret > 0) {
+                            firstSampleTime = System.currentTimeMillis();
+                        }
+                        samplesRead += ret;
+                    }
+                } break;
+                case AudioFormat.ENCODING_PCM_16BIT: {
+                    // For 16 bit data, use shorts
+                    short[] shortData = new short[BUFFER_SAMPLES];
+                    while (samplesRead < targetSamples) {
+                        // the first time through, we read a single frame.
+                        // this sets the recording anchor position.
+                        int amount = samplesRead == 0 ? numChannels :
+                            Math.min(BUFFER_SAMPLES, targetSamples - samplesRead);
+                        int ret = blocking ? record.read(shortData, 0, amount) :
+                            record.read(shortData, 0, amount, AudioRecord.READ_NON_BLOCKING);
+                        if (blocking) {
+                            assertEquals(amount, ret);
+                        } else {
+                            assertTrue("0 <= " + ret + " <= " + amount,
+                                    0 <= ret && ret <= amount);
+                        }
+                        if (samplesRead == 0 && ret > 0) {
+                            firstSampleTime = System.currentTimeMillis();
+                        }
+                        samplesRead += ret;
+                    }
+                } break;
+                case AudioFormat.ENCODING_PCM_FLOAT: {
+                    float[] floatData = new float[BUFFER_SAMPLES];
+                    while (samplesRead < targetSamples) {
+                        // the first time through, we read a single frame.
+                        // this sets the recording anchor position.
+                        int amount = samplesRead == 0 ? numChannels :
+                            Math.min(BUFFER_SAMPLES, targetSamples - samplesRead);
+                        int ret = record.read(floatData, 0, amount, blocking ?
+                                AudioRecord.READ_BLOCKING : AudioRecord.READ_NON_BLOCKING);
+                        if (blocking) {
+                            assertEquals(amount, ret);
+                        } else {
+                            assertTrue("0 <= " + ret + " <= " + amount,
+                                    0 <= ret && ret <= amount);
+                        }
+                        if (samplesRead == 0 && ret > 0) {
+                            firstSampleTime = System.currentTimeMillis();
+                        }
+                        samplesRead += ret;
+                    }
+                } break;
+                }
+            }
+
+            // We've read all the frames, now check the record timing.
+            endTime = System.currentTimeMillis();
+
+            coldInputStartTime = firstSampleTime - startTime;
+            //Log.d(TAG, "first sample time " + coldInputStartTime
+            //        + " test time " + (endTime - firstSampleTime));
+
+            if (coldInputStartTime > 200) {
+                Log.w(TAG, "cold input start time way too long "
+                        + coldInputStartTime + " > 200ms");
+            } else if (coldInputStartTime > 100) {
+                Log.w(TAG, "cold input start time too long "
+                        + coldInputStartTime + " > 100ms");
+            }
+            assertTrue(coldInputStartTime < 5000); // must start within 5 seconds.
+
+            // Verify recording completes within 50 ms of expected test time (typical 20ms)
+            assertEquals(TEST_TIME_MS, endTime - firstSampleTime, auditRecording ? 1000 : 50);
+
+            // Even though we've read all the frames we want, the events may not be sent to
+            // the listeners (events are handled through a separate internal callback thread).
+            // One must sleep to make sure the last event(s) come in.
+            Thread.sleep(30);
+
+            stopRequestTime = System.currentTimeMillis();
+            record.stop();
+            assertEquals(AudioRecord.RECORDSTATE_STOPPED, record.getRecordingState());
+
+            stopTime = System.currentTimeMillis();
+
+            // stop listening - we should be done.
+            // Caution M behavior and likely much earlier:
+            // we assume no events can happen after stop(), but this may not
+            // always be true as stop can take 100ms to complete (as it may disable
+            // input recording on the hal); thus the event handler may be block with
+            // valid events, issuing right after stop completes. Except for those events,
+            // no other events should show up after stop.
+            // This behavior may change in the future but we account for it here in testing.
+            final long SLEEP_AFTER_STOP_FOR_EVENTS_MS = 30;
+            Thread.sleep(SLEEP_AFTER_STOP_FOR_EVENTS_MS);
+            listener.stop();
+
+            // clean up
+            if (makeSomething != null) {
+                makeSomething.join();
+            }
+
+        } finally {
+            listener.release();
+            // we must release the record immediately as it is a system-wide
+            // resource needed for other tests.
+            record.release();
+        }
+        if (auditRecording) { // don't check timing if auditing (messes up timing)
+            return;
+        }
+        final int markerPeriods = markerPeriodsPerSecond * TEST_TIME_MS / 1000;
+        final int updatePeriods = periodsPerSecond * TEST_TIME_MS / 1000;
+        final int markerPeriodsMax =
+                markerPeriodsPerSecond * (int)(stopTime - firstSampleTime) / 1000 + 1;
+        final int updatePeriodsMax =
+                periodsPerSecond * (int)(stopTime - firstSampleTime) / 1000 + 1;
+
+        // collect statistics
+        final ArrayList<Integer> markerList = listener.getMarkerList();
+        final ArrayList<Integer> periodicList = listener.getPeriodicList();
+        // verify count of markers and periodic notifications.
+        // there could be an extra notification since we don't stop() immediately
+        // rather wait for potential events to come in.
+        //Log.d(TAG, "markerPeriods " + markerPeriods +
+        //        " markerPeriodsReceived " + markerList.size());
+        //Log.d(TAG, "updatePeriods " + updatePeriods +
+        //        " updatePeriodsReceived " + periodicList.size());
+        assertTrue(TAG + ": markerPeriods " + markerPeriods +
+                " <= markerPeriodsReceived " + markerList.size() +
+                " <= markerPeriodsMax " + markerPeriodsMax,
+                markerPeriods <= markerList.size()
+                && markerList.size() <= markerPeriodsMax);
+        assertTrue(TAG + ": updatePeriods " + updatePeriods +
+               " <= updatePeriodsReceived " + periodicList.size() +
+               " <= updatePeriodsMax " + updatePeriodsMax,
+                updatePeriods <= periodicList.size()
+                && periodicList.size() <= updatePeriodsMax);
+
+        // Since we don't have accurate positioning of the start time of the recorder,
+        // and there is no record.getPosition(), we consider only differential timing
+        // from the first marker or periodic event.
+        final int toleranceInFrames = TEST_SR * 80 / 1000; // 80 ms
+        final int testTimeInFrames = (int)((long)TEST_TIME_MS * TEST_SR / 1000);
+
+        AudioHelper.Statistics markerStat = new AudioHelper.Statistics();
+        for (int i = 1; i < markerList.size(); ++i) {
+            final int expected = mMarkerPeriodInFrames * i;
+            if (markerList.get(i) > testTimeInFrames) {
+                break; // don't consider any notifications when we might be stopping.
+            }
+            final int actual = markerList.get(i) - markerList.get(0);
+            //Log.d(TAG, "Marker: " + i + " expected(" + expected + ")  actual(" + actual
+            //        + ")  diff(" + (actual - expected) + ")"
+            //        + " tolerance " + toleranceInFrames);
+            assertEquals(expected, actual, toleranceInFrames);
+            markerStat.add((double)(actual - expected) * 1000 / TEST_SR);
+        }
+
+        AudioHelper.Statistics periodicStat = new AudioHelper.Statistics();
+        for (int i = 1; i < periodicList.size(); ++i) {
+            final int expected = updatePeriodInFrames * i;
+            if (periodicList.get(i) > testTimeInFrames) {
+                break; // don't consider any notifications when we might be stopping.
+            }
+            final int actual = periodicList.get(i) - periodicList.get(0);
+            //Log.d(TAG, "Update: " + i + " expected(" + expected + ")  actual(" + actual
+            //        + ")  diff(" + (actual - expected) + ")"
+            //        + " tolerance " + toleranceInFrames);
+            assertEquals(expected, actual, toleranceInFrames);
+            periodicStat.add((double)(actual - expected) * 1000 / TEST_SR);
+        }
+
+        // report this
+        ReportLog log = getReportLog();
+        log.printValue(reportName + ": startRecording lag", coldInputStartTime,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": stop execution time", stopTime - stopRequestTime,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Total record time expected", TEST_TIME_MS,
+                ResultType.NEUTRAL, ResultUnit.MS);
+        log.printValue(reportName + ": Total record time actual", endTime - firstSampleTime,
+                ResultType.NEUTRAL, ResultUnit.MS);
+        log.printValue(reportName + ": Total markers expected", markerPeriods,
+                ResultType.NEUTRAL, ResultUnit.COUNT);
+        log.printValue(reportName + ": Total markers actual", markerList.size(),
+                ResultType.NEUTRAL, ResultUnit.COUNT);
+        log.printValue(reportName + ": Total periods expected", updatePeriods,
+                ResultType.NEUTRAL, ResultUnit.COUNT);
+        log.printValue(reportName + ": Total periods actual", periodicList.size(),
+                ResultType.NEUTRAL, ResultUnit.COUNT);
+        log.printValue(reportName + ": Average Marker diff", markerStat.getAvg(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Maximum Marker abs diff", markerStat.getMaxAbs(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Average Marker abs diff", markerStat.getAvgAbs(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Average Periodic diff", periodicStat.getAvg(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Maximum Periodic abs diff", periodicStat.getMaxAbs(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Average Periodic abs diff", periodicStat.getAvgAbs(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printSummary(reportName + ": Unified abs diff",
+                (periodicStat.getAvgAbs() + markerStat.getAvgAbs()) / 2,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+    }
+
+    private class MockOnRecordPositionUpdateListener
+                                        implements OnRecordPositionUpdateListener {
+        public MockOnRecordPositionUpdateListener(AudioRecord record) {
+            mAudioRecord = record;
+            record.setRecordPositionUpdateListener(this);
+        }
+
+        public MockOnRecordPositionUpdateListener(AudioRecord record, Handler handler) {
+            mAudioRecord = record;
+            record.setRecordPositionUpdateListener(this, handler);
+        }
+
+        public synchronized void onMarkerReached(AudioRecord record) {
+            if (mIsTestActive) {
+                int position = getPosition();
+                mOnMarkerReachedCalled.add(position);
+                mMarkerPosition += mMarkerPeriodInFrames;
+                assertEquals(AudioRecord.SUCCESS,
+                        mAudioRecord.setNotificationMarkerPosition(mMarkerPosition));
+            } else {
+                // see comment on stop()
+                final long delta = System.currentTimeMillis() - mStopTime;
+                Log.d(TAG, "onMarkerReached called " + delta + " ms after stop");
+                fail("onMarkerReached called when not active");
+            }
+        }
+
+        public synchronized void onPeriodicNotification(AudioRecord record) {
+            if (mIsTestActive) {
+                int position = getPosition();
+                mOnPeriodicNotificationCalled.add(position);
+            } else {
+                // see comment on stop()
+                final long delta = System.currentTimeMillis() - mStopTime;
+                Log.d(TAG, "onPeriodicNotification called " + delta + " ms after stop");
+                fail("onPeriodicNotification called when not active");
+            }
+        }
+
+        public synchronized void start(int sampleRate) {
+            mIsTestActive = true;
+            mSampleRate = sampleRate;
+            mStartTime = System.currentTimeMillis();
+        }
+
+        public synchronized void stop() {
+            // the listener should be stopped some time after AudioRecord is stopped
+            // as some messages may not yet be posted.
+            mIsTestActive = false;
+            mStopTime = System.currentTimeMillis();
+        }
+
+        public ArrayList<Integer> getMarkerList() {
+            return mOnMarkerReachedCalled;
+        }
+
+        public ArrayList<Integer> getPeriodicList() {
+            return mOnPeriodicNotificationCalled;
+        }
+
+        public synchronized void release() {
+            stop();
+            mAudioRecord.setRecordPositionUpdateListener(null);
+            mAudioRecord = null;
+        }
+
+        private int getPosition() {
+            // we don't have mAudioRecord.getRecordPosition();
+            // so we fake this by timing.
+            long delta = System.currentTimeMillis() - mStartTime;
+            return (int)(delta * mSampleRate / 1000);
+        }
+
+        private long mStartTime;
+        private long mStopTime;
+        private int mSampleRate;
+        private boolean mIsTestActive = true;
+        private AudioRecord mAudioRecord;
+        private ArrayList<Integer> mOnMarkerReachedCalled = new ArrayList<Integer>();
+        private ArrayList<Integer> mOnPeriodicNotificationCalled = new ArrayList<Integer>();
+    }
+
     private boolean hasMicrophone() {
-        return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE);
+        return getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_MICROPHONE);
+    }
+
+    private boolean isLowRamDevice() {
+        return ((ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE))
+                .isLowRamDevice();
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/AudioRecord_BufferSizeTest.java b/tests/tests/media/src/android/media/cts/AudioRecord_BufferSizeTest.java
index e597827..1de6302 100644
--- a/tests/tests/media/src/android/media/cts/AudioRecord_BufferSizeTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioRecord_BufferSizeTest.java
@@ -53,6 +53,11 @@
             } catch (Throwable e) {
                 Log.e(TAG, "Sample rate: " + SAMPLE_RATES_IN_HZ[i], e);
                 failedSampleRates.add(SAMPLE_RATES_IN_HZ[i]);
+                if (mAudioRecord != null) {
+                    // clean up.  AudioRecords are in scarce supply.
+                    mAudioRecord.release();
+                    mAudioRecord = null;
+                }
             }
         }
         assertTrue("Failed sample rates: " + failedSampleRates + " See log for more details.",
@@ -61,21 +66,26 @@
 
     private void record(int sampleRateInHz) {
         int bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz, CHANNEL_CONFIG, AUDIO_FORMAT);
-        byte[] buffer = new byte[bufferSize];
         assertTrue(bufferSize > 0);
 
         createAudioRecord(sampleRateInHz, bufferSize);
-        checkRecordingState(AudioRecord.STATE_INITIALIZED);
+        // RecordingState changes are reflected synchronously (no need to poll)
+        assertEquals(AudioRecord.RECORDSTATE_STOPPED, mAudioRecord.getRecordingState());
 
         mAudioRecord.startRecording();
-        checkRecordingState(AudioRecord.RECORDSTATE_RECORDING);
+        assertEquals(AudioRecord.RECORDSTATE_RECORDING, mAudioRecord.getRecordingState());
 
+        // it is preferred to use a short array to read AudioFormat.ENCODING_PCM_16BIT data
+        // but it's ok to read using using a byte array.  16 bit PCM data will be
+        // stored as two bytes, native endian.
+        byte[] buffer = new byte[bufferSize];
         assertTrue(mAudioRecord.read(buffer, 0, bufferSize) > 0);
 
         mAudioRecord.stop();
-        checkRecordingState(AudioRecord.RECORDSTATE_STOPPED);
+        assertEquals(AudioRecord.RECORDSTATE_STOPPED, mAudioRecord.getRecordingState());
 
         mAudioRecord.release();
+        mAudioRecord = null;
     }
 
     private void createAudioRecord(final int sampleRateInHz, final int bufferSize) {
@@ -84,15 +94,6 @@
         assertNotNull(mAudioRecord);
     }
 
-    private void checkRecordingState(final int state) {
-        new PollingCheck() {
-            @Override
-            protected boolean check() {
-                return mAudioRecord.getRecordingState() == state;
-            }
-        }.run();
-    }
-
     private boolean hasMicrophone() {
         return getContext().getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_MICROPHONE);
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackNative.java b/tests/tests/media/src/android/media/cts/AudioTrackNative.java
new file mode 100644
index 0000000..1ce44ef
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/AudioTrackNative.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.cts.util.CtsAndroidTestCase;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+public class AudioTrackNative {
+    // Must be kept in sync with C++ JNI audio-track-native (AudioTrackNative) WRITE_FLAG_*
+    public static final int WRITE_FLAG_BLOCKING = 1 << 0;
+    /** @hide */
+    @IntDef(flag = true,
+            value = {
+                    WRITE_FLAG_BLOCKING,
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteFlags { }
+
+    public AudioTrackNative() {
+        mNativeTrackInJavaObj = nativeCreateTrack();
+    }
+
+    // TODO: eventually accept AudioFormat
+    // 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) {
+            mChannelCount = numChannels;
+            return true;
+        }
+        return false;
+    }
+
+    public void close() {
+        nativeClose(mNativeTrackInJavaObj);
+    }
+
+    public boolean start() {
+        return nativeStart(mNativeTrackInJavaObj) == STATUS_OK;
+    }
+
+    public boolean stop() {
+        return nativeStop(mNativeTrackInJavaObj) == STATUS_OK;
+    }
+
+    public boolean pause() {
+        return nativePause(mNativeTrackInJavaObj) == STATUS_OK;
+    }
+
+    public boolean flush() {
+        return nativeFlush(mNativeTrackInJavaObj) == STATUS_OK;
+    }
+
+    public long getPositionInMsec() {
+        long[] position = new long[1];
+        if (nativeGetPositionInMsec(mNativeTrackInJavaObj, position) != STATUS_OK) {
+            throw new IllegalStateException();
+        }
+        return position[0];
+    }
+
+    public int getBuffersPending() {
+        return nativeGetBuffersPending(mNativeTrackInJavaObj);
+    }
+
+    /* returns number of samples written.
+     * 0 may be returned if !isBlocking.
+     * negative value indicates error.
+     */
+    public int write(@NonNull byte[] byteArray,
+            int offsetInSamples, int sizeInSamples, @WriteFlags int writeFlags) {
+        return nativeWriteByteArray(
+                mNativeTrackInJavaObj, byteArray, offsetInSamples, sizeInSamples, writeFlags);
+    }
+
+    public int write(@NonNull short[] shortArray,
+            int offsetInSamples, int sizeInSamples, @WriteFlags int writeFlags) {
+        return nativeWriteShortArray(
+                mNativeTrackInJavaObj, shortArray, offsetInSamples, sizeInSamples, writeFlags);
+    }
+
+    public int write(@NonNull float[] floatArray,
+            int offsetInSamples, int sizeInSamples, @WriteFlags int writeFlags) {
+        return nativeWriteFloatArray(
+                mNativeTrackInJavaObj, floatArray, offsetInSamples, sizeInSamples, writeFlags);
+    }
+
+    public int getChannelCount() {
+        return mChannelCount;
+    }
+
+    public static boolean test(int numChannels, int sampleRate, boolean useFloat,
+            int msecPerBuffer, int numBuffers) {
+        return nativeTest(numChannels, sampleRate, useFloat, msecPerBuffer, numBuffers)
+                == STATUS_OK;
+    }
+
+    @Override
+    protected void finalize() {
+        nativeClose(mNativeTrackInJavaObj);
+        nativeDestroyTrack(mNativeTrackInJavaObj);
+    }
+
+    static {
+        System.loadLibrary("audio_jni");
+    }
+
+    private static final String TAG = "AudioTrackNative";
+    private int mChannelCount;
+    private final long mNativeTrackInJavaObj;
+    private static final int STATUS_OK = 0;
+
+    // static native API.
+    // The native API uses a long "track handle" created by nativeCreateTrack.
+    // The handle must be destroyed after use by nativeDestroyTrack.
+    //
+    // Return codes from the native layer are status_t.
+    // Converted to Java booleans or exceptions at the public API layer.
+    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);
+    private static native void nativeClose(long track);
+    private static native int nativeStart(long track);
+    private static native int nativeStop(long track);
+    private static native int nativePause(long track);
+    private static native int nativeFlush(long track);
+    private static native int nativeGetPositionInMsec(long track, @NonNull long[] position);
+    private static native int nativeGetBuffersPending(long track);
+    private static native int nativeWriteByteArray(long track, @NonNull byte[] byteArray,
+            int offsetInSamples, int sizeInSamples, @WriteFlags int writeFlags);
+    private static native int nativeWriteShortArray(long track, @NonNull short[] shortArray,
+            int offsetInSamples, int sizeInSamples, @WriteFlags int writeFlags);
+    private static native int nativeWriteFloatArray(long track, @NonNull float[] floatArray,
+            int offsetInSamples, int sizeInSamples, @WriteFlags int writeFlags);
+
+    // 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);
+}
diff --git a/tests/tests/media/src/android/media/cts/AudioTrackTest.java b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
index be68756..1884493 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrackTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrackTest.java
@@ -16,13 +16,18 @@
 
 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.cts.util.ReportLog;
 import com.android.cts.util.ResultType;
 import com.android.cts.util.ResultUnit;
@@ -261,6 +266,116 @@
     }
 
     // -----------------------------------------------------------------
+    // AudioTrack construction with Builder
+    // ----------------------------------
+
+    // Test case 1: build AudioTrack with default parameters, test documented default params
+    public void testBuilderDefault() throws Exception {
+        // constants for test
+        final String TEST_NAME = "testBuilderDefault";
+        final int expectedDefaultEncoding = AudioFormat.ENCODING_PCM_16BIT;
+        final int expectedDefaultRate =
+                AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
+        final int expectedDefaultChannels = AudioFormat.CHANNEL_OUT_STEREO;
+        // use Builder
+        final int buffSizeInBytes = AudioTrack.getMinBufferSize(
+                expectedDefaultRate, expectedDefaultChannels, expectedDefaultEncoding);
+        final AudioTrack track = new AudioTrack.Builder()
+                .setBufferSizeInBytes(buffSizeInBytes)
+                .build();
+        // save results
+        final int observedState = track.getState();
+        final int observedFormat = track.getAudioFormat();
+        final int observedChannelConf = track.getChannelConfiguration();
+        final int observedRate = track.getSampleRate();
+        // release track before the test exits (either successfully or with an exception)
+        track.release();
+        // compare results
+        assertEquals(TEST_NAME + ": Track initialized", AudioTrack.STATE_INITIALIZED,
+                observedState);
+        assertEquals(TEST_NAME + ": Default track encoding", expectedDefaultEncoding,
+                observedFormat);
+        assertEquals(TEST_NAME + ": Default track channels", expectedDefaultChannels,
+                observedChannelConf);
+        assertEquals(TEST_NAME + ": Default track sample rate", expectedDefaultRate,
+                observedRate);
+    }
+
+    // Test case 2: build AudioTrack with AudioFormat, test it's used
+    public void testBuilderFormat() throws Exception {
+        // constants for test
+        final String TEST_NAME = "testBuilderFormat";
+        final int TEST_RATE = 32000;
+        final int TEST_CHANNELS = AudioFormat.CHANNEL_OUT_STEREO;
+        // use Builder
+        final int buffSizeInBytes = AudioTrack.getMinBufferSize(
+                TEST_RATE, TEST_CHANNELS, AudioFormat.ENCODING_PCM_16BIT);
+        final AudioTrack track = new AudioTrack.Builder()
+                .setAudioAttributes(new AudioAttributes.Builder().build())
+                .setBufferSizeInBytes(buffSizeInBytes)
+                .setAudioFormat(new AudioFormat.Builder()
+                        .setChannelMask(TEST_CHANNELS).setSampleRate(TEST_RATE).build())
+                .build();
+        // save results
+        final int observedState = track.getState();
+        final int observedChannelConf = track.getChannelConfiguration();
+        final int observedRate = track.getSampleRate();
+        // release track before the test exits (either successfully or with an exception)
+        track.release();
+        // compare results
+        assertEquals(TEST_NAME + ": Track initialized", AudioTrack.STATE_INITIALIZED,
+                observedState);
+        assertEquals(TEST_NAME + ": Track channels", TEST_CHANNELS, observedChannelConf);
+        assertEquals(TEST_NAME + ": Track sample rate", TEST_RATE, observedRate);
+    }
+
+    // Test case 3: build AudioTrack with session ID, test it's used
+    public void testBuilderSession() throws Exception {
+        // constants for test
+        final String TEST_NAME = "testBuilderSession";
+        // generate a session ID
+        final int expectedSessionId = new AudioManager(getContext()).generateAudioSessionId();
+        // use builder
+        final AudioTrack track = new AudioTrack.Builder()
+                .setSessionId(expectedSessionId)
+                .build();
+        // save results
+        final int observedSessionId = track.getAudioSessionId();
+        // release track before the test exits (either successfully or with an exception)
+        track.release();
+        // compare results
+        assertEquals(TEST_NAME + ": Assigned track session ID", expectedSessionId,
+                observedSessionId);
+    }
+
+    // Test case 4: build AudioTrack with AudioAttributes built from stream type, test it's used
+    public void testBuilderAttributesStream() throws Exception {
+        // constants for test
+        final String TEST_NAME = "testBuilderAttributesStream";
+        //     use a stream type documented in AudioAttributes.Builder.setLegacyStreamType(int)
+        final int expectedStreamType = AudioManager.STREAM_ALARM;
+        final int expectedContentType = AudioAttributes.CONTENT_TYPE_SPEECH;
+        final AudioAttributes aa = new AudioAttributes.Builder()
+                .setLegacyStreamType(expectedStreamType)
+                .setContentType(expectedContentType)
+                .build();
+        // use builder
+        final AudioTrack track = new AudioTrack.Builder()
+                .setAudioAttributes(aa)
+                .build();
+        // save results
+        final int observedStreamType = track.getStreamType();
+        // release track before the test exits (either successfully or with an exception)
+        track.release();
+        // compare results
+        assertEquals(TEST_NAME + ": track stream type", expectedStreamType, observedStreamType);
+        //    also test content type was preserved in the attributes even though they
+        //     were first configured with a legacy stream type
+        assertEquals(TEST_NAME + ": attributes content type", expectedContentType,
+                aa.getContentType());
+    }
+
+    // -----------------------------------------------------------------
     // Playback head position
     // ----------------------------------
 
@@ -1225,7 +1340,7 @@
         // constant for test
         final String TEST_NAME = "testGetMinBufferSizeTooHighSR";
         // FIXME need an API to retrieve AudioTrack.SAMPLE_RATE_HZ_MAX
-        final int TEST_SR = 96001;
+        final int TEST_SR = 192001;
         final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
         final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
 
@@ -1278,6 +1393,7 @@
             frameCount /= 2;
         }
         assertTrue(TEST_NAME, track.getNativeFrameCount() >= frameCount);
+        assertEquals(TEST_NAME, track.getNativeFrameCount(), track.getBufferSizeInFrames());
     }
 
     public void testReloadStaticData() throws Exception {
@@ -1291,7 +1407,8 @@
 
         // -------- initialization --------------
         int bufferSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
-        byte data[] = createSoundDataInByteArray(bufferSize, TEST_SR, 1024);
+        byte data[] = AudioHelper.createSoundDataInByteArray(
+                bufferSize, TEST_SR, 1024 /* frequency */, 0 /* sweep */);
         AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF, TEST_FORMAT,
                 bufferSize, TEST_MODE);
         // -------- test --------------
@@ -1309,58 +1426,10 @@
         track.release();
     }
 
-    public static byte[] createSoundDataInByteArray(int bufferSamples, final int sampleRate,
-            final double frequency, double sweep) {
-        final double rad = 2 * Math.PI * frequency / sampleRate;
-        byte[] vai = new byte[bufferSamples];
-        sweep = Math.PI * sweep / ((double)sampleRate * vai.length);
-        for (int j = 0; j < vai.length; j++) {
-            int unsigned =  (int)(Math.sin(j * (rad + j * sweep)) * Byte.MAX_VALUE)
-                    + Byte.MAX_VALUE & 0xFF;
-            vai[j] = (byte) unsigned;
-        }
-        return vai;
-    }
-
-    public static short[] createSoundDataInShortArray(int bufferSamples, final int sampleRate,
-            final double frequency, double sweep) {
-        final double rad = 2 * Math.PI * frequency / sampleRate;
-        short[] vai = new short[bufferSamples];
-        sweep = Math.PI * sweep / ((double)sampleRate * vai.length);
-        for (int j = 0; j < vai.length; j++) {
-            vai[j] = (short)(Math.sin(j * (rad + j * sweep)) * Short.MAX_VALUE);
-        }
-        return vai;
-    }
-
-    public static float[] createSoundDataInFloatArray(int bufferSamples, final int sampleRate,
-            final double frequency, double sweep) {
-        final double rad = 2 * Math.PI * frequency / sampleRate;
-        float[] vaf = new float[bufferSamples];
-        sweep = Math.PI * sweep / ((double)sampleRate * vaf.length);
-        for (int j = 0; j < vaf.length; j++) {
-            vaf[j] = (float)(Math.sin(j * (rad + j * sweep)));
-        }
-        return vaf;
-    }
-
-    public static byte[] createSoundDataInByteArray(int bufferSamples, final int sampleRate,
-            final double frequency) {
-        return createSoundDataInByteArray(bufferSamples, sampleRate, frequency, 0 /*sweep*/);
-    }
-
-    public static short[] createSoundDataInShortArray(int bufferSamples, final int sampleRate,
-            final double frequency) {
-        return createSoundDataInShortArray(bufferSamples, sampleRate, frequency, 0 /*sweep*/);
-    }
-
-    public static float[] createSoundDataInFloatArray(int bufferSamples, final int sampleRate,
-            final double frequency) {
-        return createSoundDataInFloatArray(bufferSamples, sampleRate, frequency, 0 /*sweep*/);
-    }
-
     public void testPlayStaticData() throws Exception {
         if (!hasAudioOutput()) {
+            Log.w(TAG,"AUDIO_OUTPUT feature not found. This system might not have a valid "
+                    + "audio output HAL");
             return;
         }
         // constants for test
@@ -1399,54 +1468,54 @@
                     final long MILLISECONDS_PER_SECOND = 1000;
                     AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR,
                             TEST_CONF, TEST_FORMAT, bufferSize, TEST_MODE);
-                    assertEquals(TEST_NAME, track.getState(), AudioTrack.STATE_NO_STATIC_DATA);
+                    assertEquals(TEST_NAME, AudioTrack.STATE_NO_STATIC_DATA, track.getState());
 
                     // -------- test --------------
 
                     // test setLoopPoints and setPosition can be called here.
                     assertEquals(TEST_NAME,
-                            track.setPlaybackHeadPosition(bufferFrames/2),
-                            android.media.AudioTrack.SUCCESS);
+                            android.media.AudioTrack.SUCCESS,
+                            track.setPlaybackHeadPosition(bufferFrames/2));
                     assertEquals(TEST_NAME,
+                            android.media.AudioTrack.SUCCESS,
                             track.setLoopPoints(
-                                    0 /*startInFrames*/, bufferFrames, 10 /*loopCount*/),
-                            android.media.AudioTrack.SUCCESS);
+                                    0 /*startInFrames*/, bufferFrames, 10 /*loopCount*/));
                     // only need to write once to the static track
                     switch (TEST_FORMAT) {
                     case AudioFormat.ENCODING_PCM_8BIT: {
-                        byte data[] = createSoundDataInByteArray(
+                        byte data[] = AudioHelper.createSoundDataInByteArray(
                                 bufferSamples, TEST_SR,
                                 testFrequency, TEST_SWEEP);
                         assertEquals(TEST_NAME,
-                                track.write(data, 0 /*offsetInBytes*/, data.length),
-                                bufferSamples);
+                                bufferSamples,
+                                track.write(data, 0 /*offsetInBytes*/, data.length));
                         } break;
                     case AudioFormat.ENCODING_PCM_16BIT: {
-                        short data[] = createSoundDataInShortArray(
+                        short data[] = AudioHelper.createSoundDataInShortArray(
                                 bufferSamples, TEST_SR,
                                 testFrequency, TEST_SWEEP);
                         assertEquals(TEST_NAME,
-                                track.write(data, 0 /*offsetInBytes*/, data.length),
-                                bufferSamples);
+                                bufferSamples,
+                                track.write(data, 0 /*offsetInBytes*/, data.length));
                         } break;
                     case AudioFormat.ENCODING_PCM_FLOAT: {
-                        float data[] = createSoundDataInFloatArray(
+                        float data[] = AudioHelper.createSoundDataInFloatArray(
                                 bufferSamples, TEST_SR,
                                 testFrequency, TEST_SWEEP);
                         assertEquals(TEST_NAME,
+                                bufferSamples,
                                 track.write(data, 0 /*offsetInBytes*/, data.length,
-                                        AudioTrack.WRITE_BLOCKING),
-                                bufferSamples);
+                                        AudioTrack.WRITE_BLOCKING));
                         } break;
                     }
-                    assertEquals(TEST_NAME, track.getState(), AudioTrack.STATE_INITIALIZED);
+                    assertEquals(TEST_NAME, AudioTrack.STATE_INITIALIZED, track.getState());
                     // test setLoopPoints and setPosition can be called here.
                     assertEquals(TEST_NAME,
-                            track.setPlaybackHeadPosition(0 /*positionInFrames*/),
-                            android.media.AudioTrack.SUCCESS);
+                            android.media.AudioTrack.SUCCESS,
+                            track.setPlaybackHeadPosition(0 /*positionInFrames*/));
                     assertEquals(TEST_NAME,
-                            track.setLoopPoints(0 /*startInFrames*/, bufferFrames, TEST_LOOPS),
-                            android.media.AudioTrack.SUCCESS);
+                            android.media.AudioTrack.SUCCESS,
+                            track.setLoopPoints(0 /*startInFrames*/, bufferFrames, TEST_LOOPS));
 
                     track.play();
                     Thread.sleep(seconds * MILLISECONDS_PER_SECOND * (TEST_LOOPS + 1));
@@ -1455,7 +1524,7 @@
                     // Check position after looping. AudioTrack.getPlaybackHeadPosition() returns
                     // the running count of frames played, not the actual static buffer position.
                     int position = track.getPlaybackHeadPosition();
-                    assertEquals(TEST_NAME, position, bufferFrames * (TEST_LOOPS + 1));
+                    assertEquals(TEST_NAME, bufferFrames * (TEST_LOOPS + 1), position);
 
                     track.stop();
                     Thread.sleep(WAIT_MSEC);
@@ -1475,12 +1544,14 @@
                 AudioFormat.ENCODING_PCM_16BIT,
                 AudioFormat.ENCODING_PCM_FLOAT,
         };
+        // due to downmixer algorithmic latency, source channels greater than 2 may
+        // sound shorter in duration at 4kHz sampling rate.
         final int TEST_SR_ARRAY[] = {
                 4000,
-                22050,
                 44100,
                 48000,
                 96000,
+                192000,
         };
         final int TEST_CONF_ARRAY[] = {
                 AudioFormat.CHANNEL_OUT_MONO,    // 1.0
@@ -1494,80 +1565,96 @@
         };
         final int TEST_MODE = AudioTrack.MODE_STREAM;
         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
+        final float TEST_SWEEP = 0; // sine wave only
+        final boolean TEST_IS_LOW_RAM_DEVICE = isLowRamDevice();
 
         for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
             double frequency = 400; // frequency changes for each test
             for (int TEST_SR : TEST_SR_ARRAY) {
                 for (int TEST_CONF : TEST_CONF_ARRAY) {
+                    final int channelCount = Integer.bitCount(TEST_CONF);
+                    if (TEST_IS_LOW_RAM_DEVICE
+                            && (TEST_SR > 96000 || channelCount > 4)) {
+                        continue; // ignore. FIXME: reenable when AF memory allocation is updated.
+                    }
                     // -------- initialization --------------
                     final int minBufferSize = AudioTrack.getMinBufferSize(TEST_SR,
                             TEST_CONF, TEST_FORMAT); // in bytes
-                    final int bufferSamples = 12 * minBufferSize
-                            / AudioFormat.getBytesPerSample(TEST_FORMAT);
-                    final int channelCount = Integer.bitCount(TEST_CONF);
-                    final double testFrequency = frequency / channelCount;
                     AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR,
                             TEST_CONF, TEST_FORMAT, minBufferSize, TEST_MODE);
                     assertTrue(TEST_NAME, track.getState() == AudioTrack.STATE_INITIALIZED);
-                    boolean hasPlayed = false;
-                    int written = 0;
 
+                    // compute parameters for the source signal data.
+                    AudioFormat format = track.getFormat();
+                    assertEquals(TEST_NAME, TEST_SR, format.getSampleRate());
+                    assertEquals(TEST_NAME, TEST_CONF, format.getChannelMask());
+                    assertEquals(TEST_NAME, channelCount, format.getChannelCount());
+                    assertEquals(TEST_NAME, TEST_FORMAT, format.getEncoding());
+                    final int sourceSamples = channelCount
+                            * AudioHelper.frameCountFromMsec(500,
+                                    format); // duration of test tones
+                    final double testFrequency = frequency / channelCount;
+
+                    int written = 0;
+                    // For streaming tracks, it's ok to issue the play() command
+                    // before any audio is written.
+                    track.play();
                     // -------- test --------------
+
+                    // samplesPerWrite can be any positive value.
+                    // We prefer this to be a multiple of channelCount so write()
+                    // does not return a short count.
+                    // If samplesPerWrite is very large, it is limited to the data length
+                    // and we simply write (blocking) the entire source data and not even loop.
+                    // We choose a value here which simulates double buffer writes.
+                    final int buffers = 2; // double buffering mode
+                    final int samplesPerWrite =
+                            (track.getBufferSizeInFrames() / buffers) * channelCount;
                     switch (TEST_FORMAT) {
                     case AudioFormat.ENCODING_PCM_8BIT: {
-                        byte data[] = createSoundDataInByteArray(
-                                bufferSamples, TEST_SR,
-                                testFrequency);
+                        byte data[] = AudioHelper.createSoundDataInByteArray(
+                                sourceSamples, TEST_SR,
+                                testFrequency, TEST_SWEEP);
                         while (written < data.length) {
-                            int ret = track.write(data, written,
-                                    Math.min(data.length - written, minBufferSize));
-                            assertTrue(TEST_NAME, ret >= 0);
+                            int samples = Math.min(data.length - written, samplesPerWrite);
+                            int ret = track.write(data, written, samples);
+                            assertEquals(TEST_NAME, samples, ret);
                             written += ret;
-                            if (!hasPlayed) {
-                                track.play();
-                                hasPlayed = true;
-                            }
                         }
                         } break;
                     case AudioFormat.ENCODING_PCM_16BIT: {
-                        short data[] = createSoundDataInShortArray(
-                                bufferSamples, TEST_SR,
-                                testFrequency);
+                        short data[] = AudioHelper.createSoundDataInShortArray(
+                                sourceSamples, TEST_SR,
+                                testFrequency, TEST_SWEEP);
                         while (written < data.length) {
-                            int ret = track.write(data, written,
-                                    Math.min(data.length - written, minBufferSize));
-                            assertTrue(TEST_NAME, ret >= 0);
+                            int samples = Math.min(data.length - written, samplesPerWrite);
+                            int ret = track.write(data, written, samples);
+                            assertEquals(TEST_NAME, samples, ret);
                             written += ret;
-                            if (!hasPlayed) {
-                                track.play();
-                                hasPlayed = true;
-                            }
                         }
                         } break;
                     case AudioFormat.ENCODING_PCM_FLOAT: {
-                        float data[] = createSoundDataInFloatArray(
-                                bufferSamples, TEST_SR,
-                                testFrequency);
+                        float data[] = AudioHelper.createSoundDataInFloatArray(
+                                sourceSamples, TEST_SR,
+                                testFrequency, TEST_SWEEP);
                         while (written < data.length) {
-                            int ret = track.write(data, written,
-                                    Math.min(data.length - written, minBufferSize),
+                            int samples = Math.min(data.length - written, samplesPerWrite);
+                            int ret = track.write(data, written, samples,
                                     AudioTrack.WRITE_BLOCKING);
-                            assertTrue(TEST_NAME, ret >= 0);
+                            assertEquals(TEST_NAME, samples, ret);
                             written += ret;
-                            if (!hasPlayed) {
-                                track.play();
-                                hasPlayed = true;
-                            }
                         }
                         } break;
                     }
 
-                    Thread.sleep(WAIT_MSEC);
+                    // For streaming tracks, AudioTrack.stop() doesn't immediately stop playback.
+                    // Rather, it allows the remaining data in the internal buffer to drain.
                     track.stop();
-                    Thread.sleep(WAIT_MSEC);
+                    Thread.sleep(WAIT_MSEC); // wait for the data to drain.
                     // -------- tear down --------------
                     track.release();
-                    frequency += 70; // increment test tone frequency
+                    Thread.sleep(WAIT_MSEC); // wait for release to complete
+                    frequency += 50; // increment test tone frequency
                 }
             }
         }
@@ -1593,6 +1680,7 @@
         };
         final int TEST_MODE = AudioTrack.MODE_STREAM;
         final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
+        final float TEST_SWEEP = 0; // sine wave only
 
         for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
             double frequency = 800; // frequency changes for each test
@@ -1606,12 +1694,19 @@
                             int bufferSize = 12 * minBufferSize;
                             int bufferSamples = bufferSize
                                     / AudioFormat.getBytesPerSample(TEST_FORMAT);
+
+                            // create audio track and confirm settings
                             AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR,
                                     TEST_CONF, TEST_FORMAT, minBufferSize, TEST_MODE);
-                            assertTrue(TEST_NAME,
-                                    track.getState() == AudioTrack.STATE_INITIALIZED);
-                            boolean hasPlayed = false;
-                            int written = 0;
+                            assertEquals(TEST_NAME + ": state",
+                                    AudioTrack.STATE_INITIALIZED, track.getState());
+                            assertEquals(TEST_NAME + ": sample rate",
+                                    TEST_SR, track.getSampleRate());
+                            assertEquals(TEST_NAME + ": channel mask",
+                                    TEST_CONF, track.getChannelConfiguration());
+                            assertEquals(TEST_NAME + ": encoding",
+                                    TEST_FORMAT, track.getAudioFormat());
+
                             ByteBuffer bb = (useDirect == 1)
                                     ? ByteBuffer.allocateDirect(bufferSize)
                                             : ByteBuffer.allocate(bufferSize);
@@ -1620,30 +1715,32 @@
                             // -------- test --------------
                             switch (TEST_FORMAT) {
                                 case AudioFormat.ENCODING_PCM_8BIT: {
-                                    byte data[] = createSoundDataInByteArray(
+                                    byte data[] = AudioHelper.createSoundDataInByteArray(
                                             bufferSamples, TEST_SR,
-                                            frequency);
+                                            frequency, TEST_SWEEP);
                                     bb.put(data);
                                     bb.flip();
                                 } break;
                                 case AudioFormat.ENCODING_PCM_16BIT: {
-                                    short data[] = createSoundDataInShortArray(
+                                    short data[] = AudioHelper.createSoundDataInShortArray(
                                             bufferSamples, TEST_SR,
-                                            frequency);
+                                            frequency, TEST_SWEEP);
                                     ShortBuffer sb = bb.asShortBuffer();
                                     sb.put(data);
                                     bb.limit(sb.limit() * 2);
                                 } break;
                                 case AudioFormat.ENCODING_PCM_FLOAT: {
-                                    float data[] = createSoundDataInFloatArray(
+                                    float data[] = AudioHelper.createSoundDataInFloatArray(
                                             bufferSamples, TEST_SR,
-                                            frequency);
+                                            frequency, TEST_SWEEP);
                                     FloatBuffer fb = bb.asFloatBuffer();
                                     fb.put(data);
                                     bb.limit(fb.limit() * 4);
                                 } break;
                             }
 
+                            boolean hasPlayed = false;
+                            int written = 0;
                             while (written < bufferSize) {
                                 int ret = track.write(bb,
                                         Math.min(bufferSize - written, minBufferSize),
@@ -1656,7 +1753,6 @@
                                 }
                             }
 
-                            Thread.sleep(WAIT_MSEC);
                             track.stop();
                             Thread.sleep(WAIT_MSEC);
                             // -------- tear down --------------
@@ -1669,16 +1765,153 @@
         }
     }
 
+    public void testPlayChannelIndexStreamBuffer() throws Exception {
+        // should hear 4 tones played 3 or 4 times depending
+        // on the device output capabilities (e.g. stereo or 5.1 or otherwise)
+        final String TEST_NAME = "testPlayChannelIndexStreamBuffer";
+        final int TEST_FORMAT_ARRAY[] = {
+                AudioFormat.ENCODING_PCM_8BIT,
+                //AudioFormat.ENCODING_PCM_16BIT,
+                //AudioFormat.ENCODING_PCM_FLOAT,
+        };
+        final int TEST_SR_ARRAY[] = {
+                48000,
+        };
+        // The following channel index masks are iterated over and route
+        // the AudioTrack channels to the output sink channels based on
+        // the set bits in counting order (lsb to msb).
+        //
+        // For a stereo output sink, the sound may come from L and R, L only, none, or R only.
+        // For a 5.1 output sink, the sound may come from a variety of outputs
+        // as commented below.
+        final int TEST_CONF_ARRAY[] = { // matches output sink channels:
+                (1 << 0) | (1 << 1), // Stereo(L, R) 5.1(FL, FR)
+                (1 << 0) | (1 << 2), // Stereo(L)    5.1(FL, FC)
+                (1 << 4) | (1 << 5), // Stereo(None) 5.1(BL, BR)
+                (1 << 1) | (1 << 2), // Stereo(R)    5.1(FR, FC)
+        };
+        final int TEST_WRITE_MODE_ARRAY[] = {
+                AudioTrack.WRITE_BLOCKING,
+                AudioTrack.WRITE_NON_BLOCKING,
+        };
+        final float TEST_SWEEP = 0;
+
+        for (int TEST_FORMAT : TEST_FORMAT_ARRAY) {
+            for (int TEST_CONF : TEST_CONF_ARRAY) {
+                double frequency = 800; // frequency changes for each test
+                for (int TEST_SR : TEST_SR_ARRAY) {
+                    for (int TEST_WRITE_MODE : TEST_WRITE_MODE_ARRAY) {
+                        for (int useDirect = 0; useDirect < 2; ++useDirect) {
+                            AudioFormat format = new AudioFormat.Builder()
+                                    .setEncoding(TEST_FORMAT)
+                                    .setSampleRate(TEST_SR)
+                                    .setChannelIndexMask(TEST_CONF)
+                                    .build();
+                            AudioTrack track = new AudioTrack.Builder()
+                                    .setAudioFormat(format)
+                                    .build();
+                            assertEquals(TEST_NAME,
+                                    AudioTrack.STATE_INITIALIZED, track.getState());
+
+                            // create the byte buffer and fill with test data
+                            final int frameSize = AudioHelper.frameSizeFromFormat(format);
+                            final int frameCount =
+                                    AudioHelper.frameCountFromMsec(300 /* ms */, format);
+                            final int bufferSize = frameCount * frameSize;
+                            final int bufferSamples = frameCount * format.getChannelCount();
+                            ByteBuffer bb = (useDirect == 1)
+                                    ? ByteBuffer.allocateDirect(bufferSize)
+                                            : ByteBuffer.allocate(bufferSize);
+                            bb.order(java.nio.ByteOrder.nativeOrder());
+
+                            switch (TEST_FORMAT) {
+                            case AudioFormat.ENCODING_PCM_8BIT: {
+                                byte data[] = AudioHelper.createSoundDataInByteArray(
+                                        bufferSamples, TEST_SR,
+                                        frequency, TEST_SWEEP);
+                                bb.put(data);
+                                bb.flip();
+                            } break;
+                            case AudioFormat.ENCODING_PCM_16BIT: {
+                                short data[] = AudioHelper.createSoundDataInShortArray(
+                                        bufferSamples, TEST_SR,
+                                        frequency, TEST_SWEEP);
+                                ShortBuffer sb = bb.asShortBuffer();
+                                sb.put(data);
+                                bb.limit(sb.limit() * 2);
+                            } break;
+                            case AudioFormat.ENCODING_PCM_FLOAT: {
+                                float data[] = AudioHelper.createSoundDataInFloatArray(
+                                        bufferSamples, TEST_SR,
+                                        frequency, TEST_SWEEP);
+                                FloatBuffer fb = bb.asFloatBuffer();
+                                fb.put(data);
+                                bb.limit(fb.limit() * 4);
+                            } break;
+                            }
+
+                            // start the AudioTrack
+                            // This can be done before or after the first write.
+                            // Current behavior for streaming tracks is that
+                            // actual playback does not begin before the internal
+                            // data buffer is completely full.
+                            track.play();
+
+                            // write data
+                            final long startTime = System.currentTimeMillis();
+                            final long maxDuration = frameCount * 1000 / TEST_SR + 1000;
+                            for (int written = 0; written < bufferSize; ) {
+                                // ret may return a short count if write
+                                // is non blocking or even if write is blocking
+                                // when a stop/pause/flush is issued from another thread.
+                                final int kBatchFrames = 1000;
+                                int ret = track.write(bb,
+                                        Math.min(bufferSize - written, frameSize * kBatchFrames),
+                                        TEST_WRITE_MODE);
+                                // for non-blocking mode, this loop may spin quickly
+                                assertTrue(TEST_NAME + ": write error " + ret, ret >= 0);
+                                assertTrue(TEST_NAME + ": write timeout",
+                                        (System.currentTimeMillis() - startTime) <= maxDuration);
+                                written += ret;
+                            }
+
+                            // for streaming tracks, stop will allow the rest of the data to
+                            // drain out, but we don't know how long to wait unless
+                            // we check the position before stop. if we check position
+                            // after we stop, we read 0.
+                            final int position = track.getPlaybackHeadPosition();
+                            final int remainingTimeMs = (int)((double)(frameCount - position)
+                                    * 1000 / TEST_SR);
+                            track.stop();
+                            Thread.sleep(remainingTimeMs);
+                            // tear down
+                            track.release();
+                            // add a gap to make tones distinct
+                            Thread.sleep(100 /* millis */);
+                            frequency += 200; // increment test tone frequency
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     private boolean hasAudioOutput() {
         return getContext().getPackageManager()
             .hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
     }
 
+    private boolean isLowRamDevice() {
+        return ((ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE))
+                .isLowRamDevice();
+    }
+
     public void testGetTimestamp() throws Exception {
         if (!hasAudioOutput()) {
+            Log.w(TAG,"AUDIO_OUTPUT feature not found. This system might not have a valid "
+                    + "audio output HAL");
             return;
         }
-        
         // constants for test
         final String TEST_NAME = "testGetTimestamp";
         final int TEST_SR = 22050;
@@ -1805,6 +2038,234 @@
         }
     }
 
+    public void testVariableRatePlayback() throws Exception {
+        final String TEST_NAME = "testVariableRatePlayback";
+        final int TEST_SR = 24000;
+        final int TEST_FINAL_SR = 96000;
+        final int TEST_CONF = AudioFormat.CHANNEL_OUT_MONO;
+        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT; // required for test
+        final int TEST_MODE = AudioTrack.MODE_STATIC; // required for test
+        final int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
+
+        final int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
+        final int bufferSizeInBytes = minBuffSize * 100;
+        final int numChannels =  AudioFormat.channelCountFromOutChannelMask(TEST_CONF);
+        final int bytesPerSample = AudioFormat.getBytesPerSample(TEST_FORMAT);
+        final int bytesPerFrame = numChannels * bytesPerSample;
+        final int frameCount = bufferSizeInBytes / bytesPerFrame;
+
+        AudioTrack track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF,
+                TEST_FORMAT, bufferSizeInBytes, TEST_MODE);
+
+        // create byte array and write it
+        byte[] vai = AudioHelper.createSoundDataInByteArray(bufferSizeInBytes, TEST_SR,
+                600 /* frequency */, 0 /* sweep */);
+        assertEquals(vai.length, track.write(vai, 0 /* offsetInBytes */, vai.length));
+
+        // sweep up test and sweep down test
+        int[] sampleRates = {TEST_SR, TEST_FINAL_SR};
+        int[] deltaMss = {10, 10};
+        int[] deltaFreqs = {200, -200};
+
+        for (int i = 0; i < 2; ++i) {
+            int remainingTime;
+            int sampleRate = sampleRates[i];
+            final int deltaMs = deltaMss[i];
+            final int deltaFreq = deltaFreqs[i];
+            final int lastCheckMs = 500; // check the last 500 ms
+
+            assertEquals(TEST_NAME, AudioTrack.SUCCESS, track.setPlaybackRate(sampleRate));
+            track.play();
+            do {
+                Thread.sleep(deltaMs);
+                final int position = track.getPlaybackHeadPosition();
+                sampleRate += deltaFreq;
+                sampleRate = Math.min(TEST_FINAL_SR, Math.max(TEST_SR, sampleRate));
+                assertEquals(TEST_NAME, AudioTrack.SUCCESS, track.setPlaybackRate(sampleRate));
+                remainingTime = (int)((double)(frameCount - position) * 1000
+                        / sampleRate / bytesPerFrame);
+            } while (remainingTime >= lastCheckMs + deltaMs);
+
+            // ensure the final frequency set is constant and plays frames as expected
+            final int position1 = track.getPlaybackHeadPosition();
+            Thread.sleep(lastCheckMs);
+            final int position2 = track.getPlaybackHeadPosition();
+
+            final int tolerance60MsInFrames = sampleRate * 60 / 1000;
+            final int expected = lastCheckMs * sampleRate / 1000;
+            final int actual = position2 - position1;
+
+            // Log.d(TAG, "Variable Playback: expected(" + expected + ")  actual(" + actual
+            //        + ")  diff(" + (expected - actual) + ")");
+            assertEquals(expected, actual, tolerance60MsInFrames);
+            track.stop();
+        }
+        track.release();
+    }
+
+    public void testVariableSpeedPlayback() throws Exception {
+        if (!hasAudioOutput()) {
+            Log.w(TAG,"AUDIO_OUTPUT feature not found. This system might not have a valid "
+                    + "audio output HAL");
+            return;
+        }
+
+        final String TEST_NAME = "testVariableSpeedPlayback";
+        final int TEST_FORMAT = AudioFormat.ENCODING_PCM_FLOAT; // required for test
+        final int TEST_MODE = AudioTrack.MODE_STATIC;           // required for test
+        final int TEST_SR = 48000;
+
+        AudioFormat format = new AudioFormat.Builder()
+                //.setChannelIndexMask((1 << 0))  // output to first channel, FL
+                .setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
+                .setEncoding(TEST_FORMAT)
+                .setSampleRate(TEST_SR)
+                .build();
+
+        // create track
+        final int frameCount = AudioHelper.frameCountFromMsec(100 /*ms*/, format);
+        final int frameSize = AudioHelper.frameSizeFromFormat(format);
+        AudioTrack track = new AudioTrack.Builder()
+                .setAudioFormat(format)
+                .setBufferSizeInBytes(frameCount * frameSize)
+                .setTransferMode(TEST_MODE)
+                .build();
+
+        // create float array and write it
+        final int sampleCount = frameCount * format.getChannelCount();
+        float[] vaf = AudioHelper.createSoundDataInFloatArray(
+                sampleCount, TEST_SR, 600 /* frequency */, 0 /* sweep */);
+        assertEquals(vaf.length, track.write(vaf, 0 /* offsetInFloats */, vaf.length,
+                AudioTrack.WRITE_NON_BLOCKING));
+
+        // sweep speed and pitch
+        final float[][][] speedAndPitch = {
+             // { {speedStart, pitchStart} {speedEnd, pitchEnd} }
+                { {0.5f, 0.5f}, {2.0f, 2.0f} },  // speed by SR conversion (chirp)
+                { {0.5f, 1.0f}, {2.0f, 1.0f} },  // speed by time stretch (constant pitch)
+                { {1.0f, 0.5f}, {1.0f, 2.0f} },  // pitch by SR conversion (chirp)
+        };
+
+        // sanity test that playback params works as expected
+        PlaybackParams params = new PlaybackParams().allowDefaults();
+        assertEquals(TEST_NAME, 1.0f, params.getSpeed());
+        assertEquals(TEST_NAME, 1.0f, params.getPitch());
+        assertEquals(TEST_NAME,
+                params.AUDIO_FALLBACK_MODE_DEFAULT,
+                params.getAudioFallbackMode());
+        track.setPlaybackParams(params); // OK
+        params.setAudioFallbackMode(params.AUDIO_FALLBACK_MODE_FAIL);
+        assertEquals(TEST_NAME,
+                params.AUDIO_FALLBACK_MODE_FAIL, params.getAudioFallbackMode());
+        params.setPitch(0.0f);
+        try {
+            track.setPlaybackParams(params);
+            fail("IllegalArgumentException should be thrown on out of range data");
+        } catch (IllegalArgumentException e) {
+            ; // expect this is invalid
+        }
+        // on failure, the AudioTrack params should not change.
+        PlaybackParams paramCheck = track.getPlaybackParams();
+        assertEquals(TEST_NAME,
+                paramCheck.AUDIO_FALLBACK_MODE_DEFAULT, paramCheck.getAudioFallbackMode());
+        assertEquals(TEST_NAME,
+                1.0f, paramCheck.getPitch());
+
+        // now try to see if we can do extreme pitch correction that should probably be muted.
+        params.setAudioFallbackMode(params.AUDIO_FALLBACK_MODE_MUTE);
+        assertEquals(TEST_NAME,
+                params.AUDIO_FALLBACK_MODE_MUTE, params.getAudioFallbackMode());
+        params.setPitch(0.1f);
+        track.setPlaybackParams(params); // OK
+
+        // now do our actual playback
+        final int TEST_TIME_MS = 2000;
+        final int TEST_DELTA_MS = 100;
+        final int testSteps = TEST_TIME_MS / TEST_DELTA_MS;
+
+        for (int i = 0; i < speedAndPitch.length; ++i) {
+            final float speedStart = speedAndPitch[i][0][0];
+            final float pitchStart = speedAndPitch[i][0][1];
+            final float speedEnd = speedAndPitch[i][1][0];
+            final float pitchEnd = speedAndPitch[i][1][1];
+            final float speedInc = (speedEnd - speedStart) / testSteps;
+            final float pitchInc = (pitchEnd - pitchStart) / testSteps;
+
+            PlaybackParams playbackParams = new PlaybackParams()
+                    .setPitch(pitchStart)
+                    .setSpeed(speedStart)
+                    .allowDefaults();
+
+            // set track in infinite loop to be a sine generator
+            track.setLoopPoints(0, frameCount, -1 /* loopCount */); // cleared by stop()
+            track.play();
+
+            Thread.sleep(300 /* millis */); // warm up track
+
+            int anticipatedPosition = track.getPlaybackHeadPosition();
+            for (int j = 0; j < testSteps; ++j) {
+                // set playback settings
+                final float pitch = playbackParams.getPitch();
+                final float speed = playbackParams.getSpeed();
+
+                track.setPlaybackParams(playbackParams);
+
+                // verify that settings have changed
+                PlaybackParams checkParams = track.getPlaybackParams();
+                assertEquals(TAG, pitch, checkParams.getPitch());
+                assertEquals(TAG, speed, checkParams.getSpeed());
+
+                // sleep for playback
+                Thread.sleep(TEST_DELTA_MS);
+                // Log.d(TAG, "position[" + j + "] " + track.getPlaybackHeadPosition());
+                anticipatedPosition +=
+                        playbackParams.getSpeed() * TEST_DELTA_MS * TEST_SR / 1000;
+                playbackParams.setPitch(playbackParams.getPitch() + pitchInc);
+                playbackParams.setSpeed(playbackParams.getSpeed() + speedInc);
+            }
+            final int endPosition = track.getPlaybackHeadPosition();
+            final int tolerance100MsInFrames = 100 * TEST_SR / 1000;
+            assertEquals(TAG, anticipatedPosition, endPosition, tolerance100MsInFrames);
+            track.stop();
+
+            Thread.sleep(100 /* millis */); // distinct pause between each test
+        }
+        track.release();
+    }
+
+    // Test AudioTrack to ensure we can build after a failure.
+    public void testAudioTrackBufferSize() throws Exception {
+        // constants for test
+        final String TEST_NAME = "testAudioTrackBufferSize";
+
+        // use builder with parameters that should fail
+        final int superBigBufferSize = 1 << 28;
+        try {
+            final AudioTrack track = new AudioTrack.Builder()
+                .setBufferSizeInBytes(superBigBufferSize)
+                .build();
+            track.release();
+            fail(TEST_NAME + ": should throw exception on failure");
+        } catch (UnsupportedOperationException e) {
+            ;
+        }
+
+        // we should be able to create again with minimum buffer size
+        final int verySmallBufferSize = 2 * 3 * 4; // frame size multiples
+        final AudioTrack track2 = new AudioTrack.Builder()
+                .setBufferSizeInBytes(verySmallBufferSize)
+                .build();
+
+        final int observedState2 = track2.getState();
+        final int observedBufferSize2 = track2.getBufferSizeInFrames();
+        track2.release();
+
+        // succeeds for minimum buffer size
+        assertEquals(TEST_NAME + ": state", AudioTrack.STATE_INITIALIZED, observedState2);
+        // should force the minimum size buffer which is > 0
+        assertTrue(TEST_NAME + ": buffer frame count", observedBufferSize2 > 0);
+    }
+
 /* Do not run in JB-MR1. will be re-opened in the next platform release.
     public void testResourceLeakage() throws Exception {
         final int BUFFER_SIZE = 600 * 1024;
@@ -1828,6 +2289,7 @@
     }
 */
 
+    /* MockAudioTrack allows testing of protected getNativeFrameCount() and setState(). */
     private class MockAudioTrack extends AudioTrack {
 
         public MockAudioTrack(int streamType, int sampleRateInHz, int channelConfig,
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 eb675fc..e059e36 100644
--- a/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioTrack_ListenerTest.java
@@ -16,25 +16,35 @@
 
 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.test.AndroidTestCase;
+import android.util.Log;
+import com.android.cts.util.ReportLog;
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
 
-public class AudioTrack_ListenerTest extends AndroidTestCase {
-    private boolean mOnMarkerReachedCalled;
-    private boolean mOnPeriodicNotificationCalled;
+public class AudioTrack_ListenerTest extends CtsAndroidTestCase {
+    private final static String TAG = "AudioTrack_ListenerTest";
+    private final static int TEST_SR = 11025;
+    private final static int TEST_CONF = AudioFormat.CHANNEL_OUT_MONO;
+    private final static int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
+    private final static int TEST_STREAM_TYPE = AudioManager.STREAM_MUSIC;
+    private final static int TEST_LOOP_FACTOR = 2; // # loops (>= 1) for static tracks
+                                                   // simulated for streaming.
+    private final static int TEST_BUFFER_FACTOR = 25;
     private boolean mIsHandleMessageCalled;
-    private final int TEST_SR = 11025;
-    private final int TEST_CONF = AudioFormat.CHANNEL_CONFIGURATION_MONO;
-    private final int TEST_FORMAT = AudioFormat.ENCODING_PCM_8BIT;
-    private final int TEST_MODE = AudioTrack.MODE_STREAM;
-    private final int TEST_STREAM_TYPE1 = AudioManager.STREAM_MUSIC;
+    private int mMarkerPeriodInFrames;
+    private int mMarkerPosition;
+    private int mFrameCount;
     private Handler mHandler = new Handler(Looper.getMainLooper()) {
         @Override
         public void handleMessage(Message msg) {
@@ -42,180 +52,232 @@
             super.handleMessage(msg);
         }
     };
-    private final int mMinBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
-    private AudioTrack mAudioTrack;
-    private OnPlaybackPositionUpdateListener mListener =
-                                new MockOnPlaybackPositionUpdateListener();
-    private MakeSomethingAsynchronouslyAndLoop<AudioTrack> mMakeSomething;
-
-    @Override
-    protected void setUp() throws Exception
-    {
-        super.setUp();
-        if (mAudioTrack == null) {
-            mMakeSomething = new MakeSomethingAsynchronouslyAndLoop<AudioTrack>(
-                new MakesSomething<AudioTrack>() {
-                    @Override
-                    public AudioTrack makeSomething()
-                    {
-                        return new AudioTrack(TEST_STREAM_TYPE1, TEST_SR, TEST_CONF,
-                            TEST_FORMAT, 2 * mMinBuffSize, TEST_MODE);
-                    }
-                }
-            );
-            mAudioTrack = mMakeSomething.make();
-        }
-    }
 
     public void testAudioTrackCallback() throws Exception {
-        mAudioTrack.setPlaybackPositionUpdateListener(mListener);
-        doTest(false /*customHandler*/);
+        doTest("Streaming Local Looper", true /*localTrack*/, false /*customHandler*/,
+                30 /*periodsPerSecond*/, 2 /*markerPeriodsPerSecond*/, AudioTrack.MODE_STREAM);
     }
 
     public void testAudioTrackCallbackWithHandler() throws Exception {
-        mAudioTrack.setPlaybackPositionUpdateListener(mListener, mHandler);
-        doTest(true /*customHandler*/);
-        // ToBeFixed: Handler#handleMessage() is never called
-        // FIXME possibly because the new Handler() is missing the Looper parameter
+        // with 100 periods per second, trigger back-to-back notifications.
+        doTest("Streaming Private Handler", false /*localTrack*/, true /*customHandler*/,
+                100 /*periodsPerSecond*/, 10 /*markerPeriodsPerSecond*/, AudioTrack.MODE_STREAM);
+        // verify mHandler is used only for accessing its associated Looper
         assertFalse(mIsHandleMessageCalled);
     }
 
-    private void doTest(boolean customHandler) throws Exception {
-        mOnMarkerReachedCalled = false;
-        mOnPeriodicNotificationCalled = false;
-        byte[] vai = AudioTrackTest.createSoundDataInByteArray(2 * mMinBuffSize, TEST_SR, 1024);
-        int markerInFrames = vai.length / 4;
-        assertEquals(AudioTrack.SUCCESS, mAudioTrack.setNotificationMarkerPosition(markerInFrames));
-        int periodInFrames = vai.length / 2;
-        assertEquals(AudioTrack.SUCCESS, mAudioTrack.setPositionNotificationPeriod(periodInFrames));
-
-        boolean hasPlayed = false;
-        int written = 0;
-        while (written < vai.length) {
-            written += mAudioTrack.write(vai, written, vai.length - written);
-            if (!hasPlayed) {
-                mAudioTrack.play();
-                hasPlayed = true;
-            }
-        }
-
-        final int numChannels = (TEST_CONF == AudioFormat.CHANNEL_CONFIGURATION_STEREO) ? 2 : 1;
-        final int bytesPerSample = (TEST_FORMAT == AudioFormat.ENCODING_PCM_16BIT) ? 2 : 1;
-        final int bytesPerFrame = numChannels * bytesPerSample;
-        final int sampleLengthMs = (int)(1000 * ((float)vai.length / TEST_SR / bytesPerFrame));
-        Thread.sleep(sampleLengthMs + 1000);
-        if (!customHandler) {
-            assertTrue(mOnMarkerReachedCalled);
-            assertTrue(mOnPeriodicNotificationCalled);
-        }
-        mAudioTrack.stop();
+    public void testStaticAudioTrackCallback() throws Exception {
+        doTest("Static", false /*localTrack*/, false /*customHandler*/,
+                100 /*periodsPerSecond*/, 10 /*markerPeriodsPerSecond*/, AudioTrack.MODE_STATIC);
     }
 
-    // lightweight java.util.concurrent.Future*
-    private static class FutureLatch<T>
-    {
-        private T mValue;
-        private boolean mSet;
-        public void set(T value)
-        {
-            synchronized (this) {
-                assert !mSet;
-                mValue = value;
-                mSet = true;
-                notify();
-            }
+    public void testStaticAudioTrackCallbackWithHandler() throws Exception {
+        doTest("Static Private Handler", false /*localTrack*/, true /*customHandler*/,
+                30 /*periodsPerSecond*/, 2 /*markerPeriodsPerSecond*/, AudioTrack.MODE_STATIC);
+        // verify mHandler is used only for accessing its associated Looper
+        assertFalse(mIsHandleMessageCalled);
+    }
+
+    private void doTest(String reportName, boolean localTrack, boolean customHandler,
+            int periodsPerSecond, int markerPeriodsPerSecond, final int mode) throws Exception {
+        mIsHandleMessageCalled = false;
+        final int minBuffSize = AudioTrack.getMinBufferSize(TEST_SR, TEST_CONF, TEST_FORMAT);
+        final int bufferSizeInBytes;
+        if (mode == AudioTrack.MODE_STATIC && TEST_LOOP_FACTOR > 1) {
+            // use setLoopPoints for static mode
+            bufferSizeInBytes = minBuffSize * TEST_BUFFER_FACTOR;
+            mFrameCount = bufferSizeInBytes * TEST_LOOP_FACTOR;
+        } else {
+            bufferSizeInBytes = minBuffSize * TEST_BUFFER_FACTOR * TEST_LOOP_FACTOR;
+            mFrameCount = bufferSizeInBytes;
         }
-        public T get()
-        {
-            T value;
-            synchronized (this) {
-                while (!mSet) {
-                    try {
-                        wait();
-                    } catch (InterruptedException e) {
-                        ;
+
+        final AudioTrack track;
+        final AudioHelper.MakeSomethingAsynchronouslyAndLoop<AudioTrack> makeSomething;
+        if (localTrack) {
+            makeSomething = null;
+            track = new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF,
+                    TEST_FORMAT, bufferSizeInBytes, mode);
+        } else {
+            makeSomething =
+                    new AudioHelper.MakeSomethingAsynchronouslyAndLoop<AudioTrack>(
+                    new AudioHelper.MakesSomething<AudioTrack>() {
+                        @Override
+                        public AudioTrack makeSomething() {
+                            return new AudioTrack(TEST_STREAM_TYPE, TEST_SR, TEST_CONF,
+                                TEST_FORMAT, bufferSizeInBytes, mode);
+                        }
                     }
-                }
-                value = mValue;
-            }
-            return value;
+                );
+           // create audiotrack on different thread's looper.
+           track = makeSomething.make();
         }
-    }
-
-    // represents a factory for T
-    private interface MakesSomething<T>
-    {
-        T makeSomething();
-    }
-
-    // used to construct an object in the context of an asynchronous thread with looper
-    private static class MakeSomethingAsynchronouslyAndLoop<T>
-    {
-        private Thread mThread;
-        volatile private Looper mLooper;
-        private final MakesSomething<T> mWhatToMake;
-
-        public MakeSomethingAsynchronouslyAndLoop(MakesSomething<T> whatToMake)
-        {
-            assert whatToMake != null;
-            mWhatToMake = whatToMake;
+        final MockOnPlaybackPositionUpdateListener listener;
+        if (customHandler) {
+            listener = new MockOnPlaybackPositionUpdateListener(track, mHandler);
+        } else {
+            listener = new MockOnPlaybackPositionUpdateListener(track);
         }
 
-        public T make()
-        {
-            final FutureLatch<T> futureLatch = new FutureLatch<T>();
-            mThread = new Thread()
-            {
-                @Override
-                public void run()
-                {
-                    Looper.prepare();
-                    mLooper = Looper.myLooper();
-                    T something = mWhatToMake.makeSomething();
-                    futureLatch.set(something);
-                    Looper.loop();
-                }
-            };
-            mThread.start();
-            return futureLatch.get();
+        byte[] vai = AudioHelper.createSoundDataInByteArray(
+                bufferSizeInBytes, TEST_SR, 1024 /* frequency */, 0 /* sweep */);
+        int markerPeriods = Math.max(3, mFrameCount * markerPeriodsPerSecond / TEST_SR);
+        mMarkerPeriodInFrames = mFrameCount / markerPeriods;
+        markerPeriods = mFrameCount / mMarkerPeriodInFrames; // recalculate due to round-down
+        mMarkerPosition = mMarkerPeriodInFrames;
+
+        // check that we can get and set notification marker position
+        assertEquals(0, track.getNotificationMarkerPosition());
+        assertEquals(AudioTrack.SUCCESS,
+                track.setNotificationMarkerPosition(mMarkerPosition));
+        assertEquals(mMarkerPosition, track.getNotificationMarkerPosition());
+
+        int updatePeriods = Math.max(3, mFrameCount * periodsPerSecond / TEST_SR);
+        final int updatePeriodInFrames = mFrameCount / updatePeriods;
+        updatePeriods = mFrameCount / updatePeriodInFrames; // recalculate due to round-down
+
+        // we set the notification period before running for better period positional accuracy.
+        // check that we can get and set notification periods
+        assertEquals(0, track.getPositionNotificationPeriod());
+        assertEquals(AudioTrack.SUCCESS,
+                track.setPositionNotificationPeriod(updatePeriodInFrames));
+        assertEquals(updatePeriodInFrames, track.getPositionNotificationPeriod());
+
+        if (mode == AudioTrack.MODE_STATIC && TEST_LOOP_FACTOR > 1) {
+            track.setLoopPoints(0, vai.length, TEST_LOOP_FACTOR - 1);
         }
-        public void join()
-        {
-            mLooper.quit();
-            try {
-                mThread.join();
-            } catch (InterruptedException e) {
-                ;
-            }
-            // avoid dangling references
-            mLooper = null;
-            mThread = null;
+        // write data with single blocking write, then play.
+        assertEquals(vai.length, track.write(vai, 0 /* offsetInBytes */, vai.length));
+        track.play();
+
+        // sleep until track completes playback - it must complete within 1 second
+        // of the expected length otherwise the periodic test should fail.
+        final int numChannels =  AudioFormat.channelCountFromOutChannelMask(TEST_CONF);
+        final int bytesPerSample = AudioFormat.getBytesPerSample(TEST_FORMAT);
+        final int bytesPerFrame = numChannels * bytesPerSample;
+        final int trackLengthMs = (int)((double)mFrameCount * 1000 / TEST_SR / bytesPerFrame);
+        Thread.sleep(trackLengthMs + 1000);
+
+        // stop listening - we should be done.
+        listener.stop();
+
+        // Beware: stop() resets the playback head position for both static and streaming
+        // audio tracks, so stop() cannot be called while we're still logging playback
+        // head positions. We could recycle the track after stop(), which isn't done here.
+        track.stop();
+
+        // clean up
+        if (makeSomething != null) {
+            makeSomething.join();
         }
+        listener.release();
+        track.release();
+
+        // collect statistics
+        final ArrayList<Integer> markerList = listener.getMarkerList();
+        final ArrayList<Integer> periodicList = listener.getPeriodicList();
+        // verify count of markers and periodic notifications.
+        assertEquals(markerPeriods, markerList.size());
+        assertEquals(updatePeriods, periodicList.size());
+        // verify actual playback head positions returned.
+        // the max diff should really be around 24 ms,
+        // but system load and stability will affect this test;
+        // we use 80ms limit here for failure.
+        final int tolerance80MsInFrames = TEST_SR * 80 / 1000;
+
+        AudioHelper.Statistics markerStat = new AudioHelper.Statistics();
+        for (int i = 0; i < markerPeriods; ++i) {
+            final int expected = mMarkerPeriodInFrames * (i + 1);
+            final int actual = markerList.get(i);
+            // Log.d(TAG, "Marker: expected(" + expected + ")  actual(" + actual
+            //        + ")  diff(" + (actual - expected) + ")");
+            assertEquals(expected, actual, tolerance80MsInFrames);
+            markerStat.add((double)(actual - expected) * 1000 / TEST_SR);
+        }
+
+        AudioHelper.Statistics periodicStat = new AudioHelper.Statistics();
+        for (int i = 0; i < updatePeriods; ++i) {
+            final int expected = updatePeriodInFrames * (i + 1);
+            final int actual = periodicList.get(i);
+            // Log.d(TAG, "Update: expected(" + expected + ")  actual(" + actual
+            //        + ")  diff(" + (actual - expected) + ")");
+            assertEquals(expected, actual, tolerance80MsInFrames);
+            periodicStat.add((double)(actual - expected) * 1000 / TEST_SR);
+        }
+
+        // report this
+        ReportLog log = getReportLog();
+        log.printValue(reportName + ": Average Marker diff", markerStat.getAvg(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Maximum Marker abs diff", markerStat.getMaxAbs(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Average Marker abs diff", markerStat.getAvgAbs(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Average Periodic diff", periodicStat.getAvg(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Maximum Periodic abs diff", periodicStat.getMaxAbs(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printValue(reportName + ": Average Periodic abs diff", periodicStat.getAvgAbs(),
+                ResultType.LOWER_BETTER, ResultUnit.MS);
+        log.printSummary(reportName + ": Unified abs diff",
+                (periodicStat.getAvgAbs() + markerStat.getAvgAbs()) / 2,
+                ResultType.LOWER_BETTER, ResultUnit.MS);
     }
 
     private class MockOnPlaybackPositionUpdateListener
                                         implements OnPlaybackPositionUpdateListener {
-
-        public void onMarkerReached(AudioTrack track) {
-            mOnMarkerReachedCalled = true;
+        public MockOnPlaybackPositionUpdateListener(AudioTrack track) {
+            mAudioTrack = track;
+            track.setPlaybackPositionUpdateListener(this);
         }
 
-        public void onPeriodicNotification(AudioTrack track) {
-            mOnPeriodicNotificationCalled = true;
+        public MockOnPlaybackPositionUpdateListener(AudioTrack track, Handler handler) {
+            mAudioTrack = track;
+            track.setPlaybackPositionUpdateListener(this, handler);
         }
 
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        if (mMakeSomething != null) {
-            mMakeSomething.join();
+        public synchronized void onMarkerReached(AudioTrack track) {
+            if (mIsTestActive) {
+                int position = mAudioTrack.getPlaybackHeadPosition();
+                mOnMarkerReachedCalled.add(position);
+                mMarkerPosition += mMarkerPeriodInFrames;
+                if (mMarkerPosition <= mFrameCount) {
+                    assertEquals(AudioTrack.SUCCESS,
+                            mAudioTrack.setNotificationMarkerPosition(mMarkerPosition));
+                }
+            } else {
+                fail("onMarkerReached called when not active");
+            }
         }
-        if (mAudioTrack != null) {
-            mAudioTrack.release();
+
+        public synchronized void onPeriodicNotification(AudioTrack track) {
+            if (mIsTestActive) {
+                mOnPeriodicNotificationCalled.add(mAudioTrack.getPlaybackHeadPosition());
+            } else {
+                fail("onPeriodicNotification called when not active");
+            }
+        }
+
+        public synchronized void stop() {
+            mIsTestActive = false;
+        }
+
+        public ArrayList<Integer> getMarkerList() {
+            return mOnMarkerReachedCalled;
+        }
+
+        public ArrayList<Integer> getPeriodicList() {
+            return mOnPeriodicNotificationCalled;
+        }
+
+        public synchronized void release() {
+            mAudioTrack.setPlaybackPositionUpdateListener(null);
             mAudioTrack = null;
         }
-        super.tearDown();
-    }
 
+        private boolean mIsTestActive = true;
+        private AudioTrack mAudioTrack;
+        private ArrayList<Integer> mOnMarkerReachedCalled = new ArrayList<Integer>();
+        private ArrayList<Integer> mOnPeriodicNotificationCalled = new ArrayList<Integer>();
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
index c837d0a..02276bc 100644
--- a/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
+++ b/tests/tests/media/src/android/media/cts/ClearKeySystemTest.java
@@ -320,9 +320,6 @@
      * Tests clear key system playback.
      */
     public void testClearKeyPlayback() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
 
         MediaDrm drm = startDrm();
         if (null == drm) {
diff --git a/tests/tests/media/src/android/media/cts/CodecState.java b/tests/tests/media/src/android/media/cts/CodecState.java
index db10cd1..de0bdf8 100644
--- a/tests/tests/media/src/android/media/cts/CodecState.java
+++ b/tests/tests/media/src/android/media/cts/CodecState.java
@@ -220,8 +220,12 @@
                 mSawInputEOS = true;
                 // FIX-ME: in tunneled mode we currently use input EOS as output EOS indicator
                 // we should stream duration
-                if (mTunneled && !mIsAudio) {
-                    mSawOutputEOS = true;
+                if (mTunneled) {
+                    if (!mIsAudio) {
+                        mSawOutputEOS = true;
+                    } else if (mAudioTrack != null) {
+                        mAudioTrack.stop();
+                    }
                 }
                 return false;
             }
@@ -255,14 +259,15 @@
             Log.d(TAG, "saw input EOS on track " + mTrackIndex);
 
             mSawInputEOS = true;
-            if (mTunneled && !mIsAudio) {
-                mSawOutputEOS = true;
-            }
 
             mCodec.queueInputBuffer(
                     index, 0 /* offset */, 0 /* sampleSize */,
                     0 /* sampleTime */, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
 
+            if (mTunneled && mAudioTrack != null) {
+                mAudioTrack.stop();
+            }
+
             mAvailableInputBufferIndices.removeFirst();
         }
 
@@ -274,7 +279,9 @@
         // b/9250789
         Log.d(TAG, "CodecState::onOutputFormatChanged " + mime);
 
+        mIsAudio = false;
         if (mime.startsWith("audio/")) {
+            mIsAudio = true;
             int sampleRate =
                 mOutputFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
 
@@ -318,6 +325,9 @@
 
             mSawOutputEOS = true;
 
+            if (mAudioTrack != null && !mTunneled) {
+                mAudioTrack.stop();
+            }
             return false;
         }
 
@@ -333,6 +343,7 @@
             buffer.clear();
             ByteBuffer audioBuffer = ByteBuffer.allocate(buffer.remaining());
             audioBuffer.put(buffer);
+            audioBuffer.clear();
 
             mAudioTrack.write(audioBuffer, info.size, info.presentationTimeUs*1000);
 
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 40e619b..6765051 100755
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -149,20 +149,29 @@
     }
 
     public void testDecodeMonoMp3() throws Exception {
-        monoTest(R.raw.monotestmp3);
+        monoTest(R.raw.monotestmp3, 44100);
         testTimeStampOrdering(R.raw.monotestmp3);
     }
 
     public void testDecodeMonoM4a() throws Exception {
-        monoTest(R.raw.monotestm4a);
+        monoTest(R.raw.monotestm4a, 44100);
         testTimeStampOrdering(R.raw.monotestm4a);
     }
 
     public void testDecodeMonoOgg() throws Exception {
-        monoTest(R.raw.monotestogg);
+        monoTest(R.raw.monotestogg, 44100);
         testTimeStampOrdering(R.raw.monotestogg);
     }
 
+    public void testDecodeMonoGsm() throws Exception {
+        if (MediaUtils.hasCodecsForResource(mContext, R.raw.monotestgsm)) {
+            monoTest(R.raw.monotestgsm, 8000);
+            testTimeStampOrdering(R.raw.monotestgsm);
+        } else {
+            MediaUtils.skipTest("not mandatory");
+        }
+    }
+
     public void testDecodeAacTs() throws Exception {
         testTimeStampOrdering(R.raw.sinesweeptsaac);
     }
@@ -498,11 +507,11 @@
     }
 
 
-    private void monoTest(int res) throws Exception {
+    private void monoTest(int res, int expectedLength) throws Exception {
         short [] mono = decodeToMemory(res, RESET_MODE_NONE, CONFIG_MODE_NONE, -1, null);
-        if (mono.length == 44100) {
+        if (mono.length == expectedLength) {
             // expected
-        } else if (mono.length == 88200) {
+        } else if (mono.length == expectedLength * 2) {
             // the decoder output 2 channels instead of 1, check that the left and right channel
             // are identical
             for (int i = 0; i < mono.length; i += 2) {
@@ -513,10 +522,18 @@
         }
 
         short [] mono2 = decodeToMemory(res, RESET_MODE_RECONFIGURE, CONFIG_MODE_NONE, -1, null);
-        assertTrue(Arrays.equals(mono, mono2));
+
+        assertEquals("count different after reconfigure: ", mono.length, mono2.length);
+        for (int i = 0; i < mono.length; i++) {
+            assertEquals("samples at " + i + " don't match", mono[i], mono2[i]);
+        }
 
         short [] mono3 = decodeToMemory(res, RESET_MODE_FLUSH, CONFIG_MODE_NONE, -1, null);
-        assertTrue(Arrays.equals(mono, mono3));
+
+        assertEquals("count different after flush: ", mono.length, mono3.length);
+        for (int i = 0; i < mono.length; i++) {
+            assertEquals("samples at " + i + " don't match", mono[i], mono3[i]);
+        }
     }
 
     /**
diff --git a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
index 4557e8e..99f9759 100644
--- a/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeDecodeTest.java
@@ -16,6 +16,9 @@
 
 package android.media.cts;
 
+import android.cts.util.MediaUtils;
+import android.graphics.ImageFormat;
+import android.media.Image;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
 import android.media.MediaCodecList;
@@ -207,15 +210,32 @@
      */
     public void testEncodeDecodeVideoFromSurfaceToSurfaceQCIF() throws Throwable {
         setParameters(176, 144, 1000000, MIME_TYPE_AVC, true, false);
-        SurfaceToSurfaceWrapper.runTest(this);
+        SurfaceToSurfaceWrapper.runTest(this, false);
     }
     public void testEncodeDecodeVideoFromSurfaceToSurfaceQVGA() throws Throwable {
         setParameters(320, 240, 2000000, MIME_TYPE_AVC, true, false);
-        SurfaceToSurfaceWrapper.runTest(this);
+        SurfaceToSurfaceWrapper.runTest(this, false);
     }
     public void testEncodeDecodeVideoFromSurfaceToSurface720p() throws Throwable {
         setParameters(1280, 720, 6000000, MIME_TYPE_AVC, true, false);
-        SurfaceToSurfaceWrapper.runTest(this);
+        SurfaceToSurfaceWrapper.runTest(this, false);
+    }
+
+    /**
+     * Tests streaming of AVC video through the encoder and decoder.  Data is provided through
+     * a PersistentSurface and decoded onto a Surface.  The output is checked for validity.
+     */
+    public void testEncodeDecodeVideoFromPersistentSurfaceToSurfaceQCIF() throws Throwable {
+        setParameters(176, 144, 1000000, MIME_TYPE_AVC, true, false);
+        SurfaceToSurfaceWrapper.runTest(this, true);
+    }
+    public void testEncodeDecodeVideoFromPersistentSurfaceToSurfaceQVGA() throws Throwable {
+        setParameters(320, 240, 2000000, MIME_TYPE_AVC, true, false);
+        SurfaceToSurfaceWrapper.runTest(this, true);
+    }
+    public void testEncodeDecodeVideoFromPersistentSurfaceToSurface720p() throws Throwable {
+        setParameters(1280, 720, 6000000, MIME_TYPE_AVC, true, false);
+        SurfaceToSurfaceWrapper.runTest(this, true);
     }
 
     /**
@@ -224,40 +244,81 @@
      */
     public void testVP8EncodeDecodeVideoFromSurfaceToSurfaceQCIF() throws Throwable {
         setParameters(176, 144, 1000000, MIME_TYPE_VP8, true, false);
-        SurfaceToSurfaceWrapper.runTest(this);
+        SurfaceToSurfaceWrapper.runTest(this, false);
     }
     public void testVP8EncodeDecodeVideoFromSurfaceToSurfaceQVGA() throws Throwable {
         setParameters(320, 240, 2000000, MIME_TYPE_VP8, true, false);
-        SurfaceToSurfaceWrapper.runTest(this);
+        SurfaceToSurfaceWrapper.runTest(this, false);
     }
     public void testVP8EncodeDecodeVideoFromSurfaceToSurface720p() throws Throwable {
         setParameters(1280, 720, 6000000, MIME_TYPE_VP8, true, false);
-        SurfaceToSurfaceWrapper.runTest(this);
+        SurfaceToSurfaceWrapper.runTest(this, false);
+    }
+
+    /**
+     * Tests streaming of VP8 video through the encoder and decoder.  Data is provided through
+     * a PersistentSurface and decoded onto a Surface.  The output is checked for validity.
+     */
+    public void testVP8EncodeDecodeVideoFromPersistentSurfaceToSurfaceQCIF() throws Throwable {
+        setParameters(176, 144, 1000000, MIME_TYPE_VP8, true, false);
+        SurfaceToSurfaceWrapper.runTest(this, true);
+    }
+    public void testVP8EncodeDecodeVideoFromPersistentSurfaceToSurfaceQVGA() throws Throwable {
+        setParameters(320, 240, 2000000, MIME_TYPE_VP8, true, false);
+        SurfaceToSurfaceWrapper.runTest(this, true);
+    }
+    public void testVP8EncodeDecodeVideoFromPersistentSurfaceToSurface720p() throws Throwable {
+        setParameters(1280, 720, 6000000, MIME_TYPE_VP8, true, false);
+        SurfaceToSurfaceWrapper.runTest(this, true);
     }
 
     /** Wraps testEncodeDecodeVideoFromSurfaceToSurface() */
     private static class SurfaceToSurfaceWrapper implements Runnable {
         private Throwable mThrowable;
         private EncodeDecodeTest mTest;
+        private boolean mUsePersistentInput;
 
-        private SurfaceToSurfaceWrapper(EncodeDecodeTest test) {
+        private SurfaceToSurfaceWrapper(EncodeDecodeTest test, boolean persistent) {
             mTest = test;
+            mUsePersistentInput = persistent;
         }
 
         @Override
         public void run() {
+            if (mTest.shouldSkip()) {
+                return;
+            }
+
+            InputSurface inputSurface = null;
             try {
-                mTest.encodeDecodeVideoFromSurfaceToSurface();
+                if (!mUsePersistentInput) {
+                    mTest.encodeDecodeVideoFromSurfaceToSurface(null);
+                } else {
+                    Log.d(TAG, "creating persistent surface");
+                    inputSurface = new InputSurface(
+                            MediaCodec.createPersistentInputSurface());
+
+                    for (int i = 0; i < 3; i++) {
+                        Log.d(TAG, "test persistent surface - round " + i);
+                        mTest.encodeDecodeVideoFromSurfaceToSurface(inputSurface);
+                    }
+                }
             } catch (Throwable th) {
                 mThrowable = th;
+            } finally {
+                if (inputSurface != null) {
+                    inputSurface.release();
+                }
             }
         }
 
         /**
          * Entry point.
          */
-        public static void runTest(EncodeDecodeTest obj) throws Throwable {
-            SurfaceToSurfaceWrapper wrapper = new SurfaceToSurfaceWrapper(obj);
+        public static void runTest(EncodeDecodeTest obj, boolean persisent)
+                throws Throwable {
+            SurfaceToSurfaceWrapper wrapper =
+                    new SurfaceToSurfaceWrapper(obj, persisent);
             Thread th = new Thread(wrapper, "codec test");
             th.start();
             th.join();
@@ -283,6 +344,22 @@
         mAllowBT709 = allowBT709;
     }
 
+    private boolean shouldSkip() {
+        if (!MediaUtils.hasEncoder(mMimeType)) {
+            return true;
+        }
+
+        MediaFormat format = MediaFormat.createVideoFormat(mMimeType, mWidth, mHeight);
+        format.setInteger(MediaFormat.KEY_BIT_RATE, mBitRate);
+        format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
+        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
+        if (!MediaUtils.checkEncoderForFormat(format)) {
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * Tests encoding and subsequently decoding video from frames generated into a buffer.
      * <p>
@@ -292,6 +369,10 @@
      * See http://b.android.com/37769 for a discussion of input format pitfalls.
      */
     private void encodeDecodeVideoFromBuffer(boolean toSurface) throws Exception {
+        if (shouldSkip()) {
+            return;
+        }
+
         MediaCodec encoder = null;
         MediaCodec decoder = null;
 
@@ -361,10 +442,10 @@
      * We encode several frames of a video test pattern using MediaCodec, then decode the
      * output with MediaCodec and do some simple checks.
      */
-    private void encodeDecodeVideoFromSurfaceToSurface() throws Exception {
+    private void encodeDecodeVideoFromSurfaceToSurface(InputSurface inSurf) throws Exception {
         MediaCodec encoder = null;
         MediaCodec decoder = null;
-        InputSurface inputSurface = null;
+        InputSurface inputSurface = inSurf;
         OutputSurface outputSurface = null;
 
         mLargestColorDelta = -1;
@@ -411,13 +492,19 @@
             // our desired properties.  Request a Surface to use for input.
             encoder = MediaCodec.createByCodecName(codec);
             encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
-            inputSurface = new InputSurface(encoder.createInputSurface());
+            if (inSurf != null) {
+                Log.d(TAG, "using persistent surface");
+                encoder.setInputSurface(inputSurface.getSurface());
+                inputSurface.updateSize(mWidth, mHeight);
+            } else {
+                inputSurface = new InputSurface(encoder.createInputSurface());
+            }
             encoder.start();
 
             doEncodeDecodeVideoFromSurfaceToSurface(encoder, inputSurface, decoder, outputSurface);
         } finally {
             if (VERBOSE) Log.d(TAG, "releasing codecs");
-            if (inputSurface != null) {
+            if (inSurf == null && inputSurface != null) {
                 inputSurface.release();
             }
             if (outputSurface != null) {
@@ -499,7 +586,8 @@
         ByteBuffer[] encoderOutputBuffers = encoder.getOutputBuffers();
         ByteBuffer[] decoderInputBuffers = null;
         ByteBuffer[] decoderOutputBuffers = null;
-        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+        MediaCodec.BufferInfo decoderInfo = new MediaCodec.BufferInfo();
+        MediaCodec.BufferInfo encoderInfo = new MediaCodec.BufferInfo();
         MediaFormat decoderOutputFormat = null;
         int generateIndex = 0;
         int checkIndex = 0;
@@ -538,9 +626,11 @@
         boolean inputDone = false;
         boolean encoderDone = false;
         boolean outputDone = false;
+        int encoderStatus = -1;
         while (!outputDone) {
             if (VERBOSE) Log.d(TAG, "loop");
 
+
             // If we're not done submitting frames, generate a new one and submit it.  By
             // doing this on every loop we're working to ensure that the encoder always has
             // work to do.
@@ -586,7 +676,10 @@
             //
             // Once we get EOS from the encoder, we don't need to do this anymore.
             if (!encoderDone) {
-                int encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
+                MediaCodec.BufferInfo info = encoderInfo;
+                if (encoderStatus < 0) {
+                    encoderStatus = encoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
+                }
                 if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                     // no output available yet
                     if (VERBOSE) Log.d(TAG, "no output from encoder available");
@@ -610,18 +703,7 @@
                     encodedData.position(info.offset);
                     encodedData.limit(info.offset + info.size);
 
-                    encodedSize += info.size;
-                    if (outputStream != null) {
-                        byte[] data = new byte[info.size];
-                        encodedData.get(data);
-                        encodedData.position(info.offset);
-                        try {
-                            outputStream.write(data);
-                        } catch (IOException ioe) {
-                            Log.w(TAG, "failed writing debug data to file");
-                            throw new RuntimeException(ioe);
-                        }
-                    }
+                    boolean releaseBuffer = false;
                     if (!decoderConfigured) {
                         // Codec config info.  Only expected on first packet.  One way to
                         // handle this is to manually stuff the data into the MediaFormat
@@ -643,21 +725,41 @@
                         if (VERBOSE) Log.d(TAG, "decoder configured (" + info.size + " bytes)");
                     }
                     if ((info.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
-                        // Get a decoder input buffer, blocking until it's available.
+                        // Get a decoder input buffer
                         assertTrue(decoderConfigured);
-                        int inputBufIndex = decoder.dequeueInputBuffer(-1);
-                        ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
-                        inputBuf.clear();
-                        inputBuf.put(encodedData);
-                        decoder.queueInputBuffer(inputBufIndex, 0, info.size,
-                                info.presentationTimeUs, info.flags);
+                        int inputBufIndex = decoder.dequeueInputBuffer(TIMEOUT_USEC);
+                        if (inputBufIndex >= 0) {
+                            ByteBuffer inputBuf = decoderInputBuffers[inputBufIndex];
+                            inputBuf.clear();
+                            inputBuf.put(encodedData);
+                            decoder.queueInputBuffer(inputBufIndex, 0, info.size,
+                                    info.presentationTimeUs, info.flags);
 
-                        encoderDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
-                        if (VERBOSE) Log.d(TAG, "passed " + info.size + " bytes to decoder"
-                                + (encoderDone ? " (EOS)" : ""));
+                            encoderDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
+                            if (VERBOSE) Log.d(TAG, "passed " + info.size + " bytes to decoder"
+                                    + (encoderDone ? " (EOS)" : ""));
+                            releaseBuffer = true;
+                        }
+                    } else {
+                        releaseBuffer = true;
+                    }
+                    if (releaseBuffer) {
+                        encodedSize += info.size;
+                        if (outputStream != null) {
+                            byte[] data = new byte[info.size];
+                            encodedData.position(info.offset);
+                            encodedData.get(data);
+                            try {
+                                outputStream.write(data);
+                            } catch (IOException ioe) {
+                                Log.w(TAG, "failed writing debug data to file");
+                                throw new RuntimeException(ioe);
+                            }
+                        }
+                        encoder.releaseOutputBuffer(encoderStatus, false);
+                        encoderStatus = -1;
                     }
 
-                    encoder.releaseOutputBuffer(encoderStatus, false);
                 }
             }
 
@@ -668,6 +770,7 @@
             // If we're decoding to a Surface, we'll get notified here as usual but the
             // ByteBuffer references will be null.  The data is sent to Surface instead.
             if (decoderConfigured) {
+                MediaCodec.BufferInfo info = decoderInfo;
                 int decoderStatus = decoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
                 if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                     // no output available yet
@@ -688,6 +791,7 @@
                 } else {  // decoderStatus >= 0
                     if (!toSurface) {
                         ByteBuffer outputFrame = decoderOutputBuffers[decoderStatus];
+                        Image outputImage = (checkIndex % 2 == 0) ? null : decoder.getOutputImage(decoderStatus);
 
                         outputFrame.position(info.offset);
                         outputFrame.limit(info.offset + info.size);
@@ -699,10 +803,13 @@
                             if (VERBOSE) Log.d(TAG, "decoded, checking frame " + checkIndex);
                             assertEquals("Wrong time stamp", computePresentationTime(checkIndex),
                                     info.presentationTimeUs);
-                            if (!checkFrame(checkIndex++, decoderOutputFormat, outputFrame)) {
+                            if (!checkFrame(checkIndex++, decoderOutputFormat, outputFrame, outputImage)) {
                                 badFrames++;
                             }
                         }
+                        if (outputImage != null) {
+                            outputImage.close();
+                        }
 
                         if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                             if (VERBOSE) Log.d(TAG, "output EOS");
@@ -1023,7 +1130,7 @@
      *
      * @return true if the frame looks good
      */
-    private boolean checkFrame(int frameIndex, MediaFormat format, ByteBuffer frameData) {
+    private boolean checkFrame(int frameIndex, MediaFormat format, ByteBuffer frameData, Image image) {
         // Check for color formats we don't understand.  There is no requirement for video
         // decoders to use a "mundane" format, so we just give a pass on proprietary formats.
         // e.g. Nexus 4 0x7FA30C03 OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka
@@ -1043,6 +1150,12 @@
         int cropRight = format.getInteger("crop-right");
         int cropTop = format.getInteger("crop-top");
         int cropBottom = format.getInteger("crop-bottom");
+        if (image != null) {
+            cropLeft = image.getCropRect().left;
+            cropRight = image.getCropRect().right - 1;
+            cropTop = image.getCropRect().top;
+            cropBottom = image.getCropRect().bottom - 1;
+        }
         int cropWidth = cropRight - cropLeft + 1;
         int cropHeight = cropBottom - cropTop + 1;
 
@@ -1063,18 +1176,29 @@
             x += cropLeft;
 
             int testY, testU, testV;
-            int off = frameData.position();
-            if (semiPlanar) {
-                // Galaxy Nexus uses OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
-                testY = frameData.get(off + y * width + x) & 0xff;
-                testU = frameData.get(off + width*height + 2*(y/2) * halfWidth + 2*(x/2)) & 0xff;
-                testV = frameData.get(off + width*height + 2*(y/2) * halfWidth + 2*(x/2) + 1) & 0xff;
+            if (image != null) {
+                Image.Plane[] planes = image.getPlanes();
+                if (planes.length == 3 && image.getFormat() == ImageFormat.YUV_420_888) {
+                    testY = planes[0].getBuffer().get(y * planes[0].getRowStride() + x * planes[0].getPixelStride()) & 0xff;
+                    testU = planes[1].getBuffer().get((y/2) * planes[1].getRowStride() + (x/2) * planes[1].getPixelStride()) & 0xff;
+                    testV = planes[2].getBuffer().get((y/2) * planes[2].getRowStride() + (x/2) * planes[2].getPixelStride()) & 0xff;
+                } else {
+                    testY = testU = testV = 0;
+                }
             } else {
-                // Nexus 10, Nexus 7 use COLOR_FormatYUV420Planar
-                testY = frameData.get(off + y * width + x) & 0xff;
-                testU = frameData.get(off + width*height + (y/2) * halfWidth + (x/2)) & 0xff;
-                testV = frameData.get(off + width*height + halfWidth * (height / 2) +
-                        (y/2) * halfWidth + (x/2)) & 0xff;
+                int off = frameData.position();
+                if (semiPlanar) {
+                    // Galaxy Nexus uses OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
+                    testY = frameData.get(off + y * width + x) & 0xff;
+                    testU = frameData.get(off + width*height + 2*(y/2) * halfWidth + 2*(x/2)) & 0xff;
+                    testV = frameData.get(off + width*height + 2*(y/2) * halfWidth + 2*(x/2) + 1) & 0xff;
+                } else {
+                    // Nexus 10, Nexus 7 use COLOR_FormatYUV420Planar
+                    testY = frameData.get(off + y * width + x) & 0xff;
+                    testU = frameData.get(off + width*height + (y/2) * halfWidth + (x/2)) & 0xff;
+                    testV = frameData.get(off + width*height + halfWidth * (height / 2) +
+                            (y/2) * halfWidth + (x/2)) & 0xff;
+                }
             }
 
             int expY, expU, expV;
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
index 36ec476..48fcb65 100755
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayTest.java
@@ -86,7 +86,8 @@
     // Encoder parameters.  We use the same width/height as the virtual display.
     private static final String MIME_TYPE = MediaFormat.MIMETYPE_VIDEO_AVC;
     private static int sFrameRate = 15;               // 15fps
-    private static final int IFRAME_INTERVAL = 60;
+    // 100 days between I-frames
+    private static final int IFRAME_INTERVAL = 60 * 60 * 24 * 100;
     private static int sBitRate = 6000000;            // 6Mbps
 
     // Colors to test (RGB).  These must convert cleanly to and from BT.601 YUV.
diff --git a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
index 89d6efa..a999135 100644
--- a/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
+++ b/tests/tests/media/src/android/media/cts/EncodeVirtualDisplayWithCompositionTest.java
@@ -801,12 +801,15 @@
             if (mTopPresentation != null) {
                 mTopPresentation.dismissPresentation();
                 mTopPresentation.destroyVirtualDisplay();
+                mTopPresentation = null;
             }
             if (mTopWindow != null) {
                 mTopWindow.cleanup();
+                mTopWindow = null;
             }
             if (mEglHelper != null) {
                 mEglHelper.release();
+                mEglHelper = null;
             }
         }
 
diff --git a/tests/tests/media/src/android/media/cts/EnumDevicesTest.java b/tests/tests/media/src/android/media/cts/EnumDevicesTest.java
new file mode 100644
index 0000000..94af087
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/EnumDevicesTest.java
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.content.pm.PackageManager;
+
+import android.media.AudioDeviceCallback;
+import android.media.AudioDeviceInfo;
+import android.media.AudioManager;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import android.test.AndroidTestCase;
+
+/**
+ * TODO: Insert description here. (generated by pmclean)
+ */
+public class EnumDevicesTest extends AndroidTestCase {
+    private AudioManager mAudioManager;
+
+    boolean mAddCallbackCalled = false;
+    boolean mRemoveCallbackCalled = false;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // get the AudioManager
+        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        assertNotNull(mAudioManager);
+    }
+
+    public void test_getDevices() {
+        AudioDeviceInfo[] deviceList;
+
+        // test an empty flags set
+        deviceList = mAudioManager.getDevices(0);
+        assertTrue(deviceList != null);
+        assertTrue(deviceList.length == 0);
+
+        int numOutputDevices = 0;
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
+            // test OUTPUTS
+            deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+            assertTrue(deviceList != null);
+            numOutputDevices = deviceList.length;
+            assertTrue(numOutputDevices != 0);
+
+            // all should be "sinks"
+            for(int index = 0; index < numOutputDevices; index++) {
+                assertTrue(deviceList[index].isSink());
+            }
+        }
+
+        int numInputDevices = 0;
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
+            // test INPUTS
+            deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
+            assertTrue(deviceList != null);
+            numInputDevices = deviceList.length;
+            assertTrue(numInputDevices != 0);
+
+            // all should be "sources"
+            for(int index = 0; index < numInputDevices; index++) {
+                assertTrue(deviceList[index].isSource());
+            }
+        }
+
+        // INPUTS & OUTPUTS
+        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT) &&
+                mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
+            deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL);
+            assertTrue(deviceList.length == (numOutputDevices + numInputDevices));
+        }
+    }
+
+    public void test_devicesInfoFields() {
+        AudioDeviceInfo[] deviceList;
+        deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_ALL);
+        for (int index = 0; index < deviceList.length; index++) {
+            AudioDeviceInfo deviceInfo = deviceList[index];
+
+            // we don't say anything about the returned value.
+            int id = deviceInfo.getId();
+
+            // Product Name
+            CharSequence productName = deviceInfo.getProductName();
+            assertNotNull(productName);
+            assertTrue(productName.length() != 0);
+
+            // Address
+            String address = deviceInfo.getAddress();
+            assertNotNull(address);
+            // address may be empty
+
+            // isSource() XOR isSink()
+            assertTrue(deviceInfo.isSource() != deviceInfo.isSink());
+
+            // Sample Rates
+            int[] sampleRates = deviceInfo.getSampleRates();
+            assertNotNull(sampleRates);
+            // Note: an empty array indicates that the device supports arbitrary sample rates.
+
+            // Channel Masks
+            int[] channelMasks = deviceInfo.getChannelMasks();
+            assertNotNull(channelMasks);
+            // Note: an empty array indicates that the device supports arbitrary channel masks.
+
+            // Channel Index Masks
+            int[] indexMasks = deviceInfo.getChannelIndexMasks();
+            assertNotNull(indexMasks);
+            // Note: an empty array indicates that the device supports arbitrary channel index
+            // masks.
+
+            // Channel Counts
+            int[] channelCounts = deviceInfo.getChannelCounts();
+            assertNotNull(channelCounts);
+            // Note: an empty array indicates that the device supports arbitrary channel counts.
+
+            // Encodings
+            int[] encodings = deviceInfo.getEncodings();
+            assertNotNull(encodings);
+            // Note: an empty array indicates that the device supports arbitrary encodings.
+
+            int type = deviceInfo.getType();
+            assertTrue(type != AudioDeviceInfo.TYPE_UNKNOWN);
+        }
+    }
+
+    private class EmptyDeviceCallback extends AudioDeviceCallback {
+        public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
+            mAddCallbackCalled = true;
+        }
+
+        public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {
+            mRemoveCallbackCalled = true;
+        }
+    }
+
+    /*
+     * tests if the Looper for the current thread has been prepared,
+     * If not, it makes one, prepares it and returns it.
+     * If this returns non-null, the caller is reponsible for calling quit()
+     * on the returned Looper.
+     */
+    private Looper prepareIfNeededLooper() {
+        // non-null Handler
+        Looper myLooper = null;
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+            myLooper = Looper.myLooper();
+            assertNotNull(myLooper);
+        }
+        return myLooper;
+    }
+
+    public void test_deviceCallback() {
+        // null callback?
+        mAudioManager.registerAudioDeviceCallback(null,null);
+
+        AudioDeviceCallback callback =  new EmptyDeviceCallback();
+        AudioDeviceCallback someOtherCallback =  new EmptyDeviceCallback();
+        // null Handler
+        mAudioManager.registerAudioDeviceCallback(callback, null);
+
+        // unregister null callback
+        mAudioManager.unregisterAudioDeviceCallback(null);
+        // unregister callback not registered
+        mAudioManager.unregisterAudioDeviceCallback(someOtherCallback);
+        // nominal case
+        mAudioManager.unregisterAudioDeviceCallback(callback);
+        // remove twice
+        mAudioManager.unregisterAudioDeviceCallback(callback);
+
+        Looper myLooper = prepareIfNeededLooper();
+
+        mAudioManager.registerAudioDeviceCallback(callback, new Handler());
+        // unregister null callback
+        mAudioManager.unregisterAudioDeviceCallback(null);
+        // unregister callback not registered
+        mAudioManager.unregisterAudioDeviceCallback(someOtherCallback);
+        // nominal case
+        mAudioManager.unregisterAudioDeviceCallback(callback);
+        // remove twice
+        mAudioManager.unregisterAudioDeviceCallback(callback);
+
+        if (myLooper != null) {
+            myLooper.quit();
+        }
+    }
+
+    //TODO - Need tests for device connect/disconnect callbacks
+}
diff --git a/tests/tests/media/src/android/media/cts/EqualizerTest.java b/tests/tests/media/src/android/media/cts/EqualizerTest.java
index 15f0c73..f07c99e 100644
--- a/tests/tests/media/src/android/media/cts/EqualizerTest.java
+++ b/tests/tests/media/src/android/media/cts/EqualizerTest.java
@@ -49,9 +49,6 @@
 
     //Test case 0.0: test constructor and release
     public void test0_0ConstructorAndRelease() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         Equalizer eq = null;
         try {
             eq = new Equalizer(0, 0);
@@ -78,9 +75,6 @@
 
     //Test case 1.0: test setBandLevel() and getBandLevel()
     public void test1_0BandLevel() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getEqualizer(0);
         try {
             short numBands = mEqualizer.getNumberOfBands();
@@ -110,9 +104,6 @@
 
     //Test case 1.1: test band frequency
     public void test1_1BandFrequency() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getEqualizer(0);
         try {
             short band = mEqualizer.getBand(TEST_FREQUENCY_MILLIHERTZ);
@@ -138,9 +129,6 @@
 
     //Test case 1.2: test presets
     public void test1_2Presets() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getEqualizer(0);
         try {
             short numPresets = mEqualizer.getNumberOfPresets();
@@ -166,9 +154,6 @@
 
     //Test case 1.3: test properties
     public void test1_3Properties() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getEqualizer(0);
         try {
             Equalizer.Settings settings = mEqualizer.getProperties();
@@ -200,9 +185,6 @@
 
     //Test case 1.4: test setBandLevel() throws exception after release
     public void test1_4SetBandLevelAfterRelease() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getEqualizer(0);
         mEqualizer.release();
         try {
@@ -220,9 +202,6 @@
 
     //Test case 2.0: test setEnabled() and getEnabled() in valid state
     public void test2_0SetEnabledGetEnabled() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getEqualizer(0);
         try {
             mEqualizer.setEnabled(true);
@@ -239,9 +218,6 @@
 
     //Test case 2.1: test setEnabled() throws exception after release
     public void test2_1SetEnabledAfterRelease() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getEqualizer(0);
         mEqualizer.release();
         try {
@@ -259,9 +235,6 @@
 
     //Test case 3.0: test control status listener
     public void test3_0ControlStatusListener() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         synchronized(mLock) {
             mHasControl = true;
             mInitialized = false;
@@ -284,9 +257,6 @@
 
     //Test case 3.1: test enable status listener
     public void test3_1EnableStatusListener() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         synchronized(mLock) {
             mInitialized = false;
             createListenerLooper(false, true, false);
@@ -311,9 +281,6 @@
 
     //Test case 3.2: test parameter changed listener
     public void test3_2ParameterChangedListener() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         synchronized(mLock) {
             mInitialized = false;
             createListenerLooper(false, false, true);
diff --git a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
index 029a632..8650d20 100644
--- a/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
+++ b/tests/tests/media/src/android/media/cts/ExtractDecodeEditEncodeMuxTest.java
@@ -20,6 +20,8 @@
 import android.content.res.AssetFileDescriptor;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.CodecProfileLevel;
 import android.media.MediaCodecList;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
@@ -29,6 +31,10 @@
 import android.util.Log;
 import android.view.Surface;
 
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.CodecProfileLevel;
+
 import com.android.cts.media.R;
 
 import java.io.File;
@@ -111,28 +117,28 @@
     private String mOutputFile;
 
     public void testExtractDecodeEditEncodeMuxQCIF() throws Throwable {
-        setSize(176, 144);
+        if(!setSize(176, 144)) return;
         setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
         setCopyVideo();
         TestWrapper.runTest(this);
     }
 
     public void testExtractDecodeEditEncodeMuxQVGA() throws Throwable {
-        setSize(320, 240);
+        if(!setSize(320, 240)) return;
         setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
         setCopyVideo();
         TestWrapper.runTest(this);
     }
 
     public void testExtractDecodeEditEncodeMux720p() throws Throwable {
-        setSize(1280, 720);
+        if(!setSize(1280, 720)) return;
         setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
         setCopyVideo();
         TestWrapper.runTest(this);
     }
 
     public void testExtractDecodeEditEncodeMuxAudio() throws Throwable {
-        setSize(1280, 720);
+        if(!setSize(1280, 720)) return;
         setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
         setCopyAudio();
         setVerifyAudioFormat();
@@ -140,7 +146,7 @@
     }
 
     public void testExtractDecodeEditEncodeMuxAudioVideo() throws Throwable {
-        setSize(1280, 720);
+        if(!setSize(1280, 720)) return;
         setSource(R.raw.video_480x360_mp4_h264_500kbps_30fps_aac_stereo_128kbps_44100hz);
         setCopyAudio();
         setCopyVideo();
@@ -203,14 +209,21 @@
     }
 
     /**
-     * Sets the desired frame size.
+     * Sets the desired frame size and returns whether the given resolution is
+     * supported.
+     *
+     * <p>If decoding/encoding using AVC as the codec, checks that the resolution
+     * is supported. For other codecs, always return {@code true}.
      */
-    private void setSize(int width, int height) {
+    private boolean setSize(int width, int height) {
         if ((width % 16) != 0 || (height % 16) != 0) {
             Log.w(TAG, "WARNING: width or height not multiple of 16");
         }
         mWidth = width;
         mHeight = height;
+
+	// TODO: remove this logic in setSize as it is now handled when configuring codecs
+        return true;
     }
 
     /**
@@ -1130,4 +1143,87 @@
     private static String getMimeTypeFor(MediaFormat format) {
         return format.getString(MediaFormat.KEY_MIME);
     }
+
+    /**
+     * Returns the first codec capable of encoding the specified MIME type, or null if no match was
+     * found.
+     */
+    private static MediaCodecInfo selectCodec(String mimeType) {
+        int numCodecs = MediaCodecList.getCodecCount();
+        for (int i = 0; i < numCodecs; i++) {
+            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
+
+            if (!codecInfo.isEncoder()) {
+                continue;
+            }
+
+            String[] types = codecInfo.getSupportedTypes();
+            for (int j = 0; j < types.length; j++) {
+                if (types[j].equalsIgnoreCase(mimeType)) {
+                    return codecInfo;
+                }
+            }
+        }
+        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/InputSurface.java b/tests/tests/media/src/android/media/cts/InputSurface.java
index 157ed88..37ca423 100644
--- a/tests/tests/media/src/android/media/cts/InputSurface.java
+++ b/tests/tests/media/src/android/media/cts/InputSurface.java
@@ -41,8 +41,11 @@
     private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY;
     private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT;
     private EGLSurface mEGLSurface = EGL14.EGL_NO_SURFACE;
+    private EGLConfig[] mConfigs = new EGLConfig[1];
 
     private Surface mSurface;
+    private int mWidth;
+    private int mHeight;
 
     /**
      * Creates an InputSurface from a Surface.
@@ -80,9 +83,8 @@
                 EGL_RECORDABLE_ANDROID, 1,
                 EGL14.EGL_NONE
         };
-        EGLConfig[] configs = new EGLConfig[1];
         int[] numConfigs = new int[1];
-        if (!EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, configs, 0, configs.length,
+        if (!EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, mConfigs, 0, mConfigs.length,
                 numConfigs, 0)) {
             throw new RuntimeException("unable to find RGB888+recordable ES2 EGL config");
         }
@@ -92,7 +94,7 @@
                 EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
                 EGL14.EGL_NONE
         };
-        mEGLContext = EGL14.eglCreateContext(mEGLDisplay, configs[0], EGL14.EGL_NO_CONTEXT,
+        mEGLContext = EGL14.eglCreateContext(mEGLDisplay, mConfigs[0], EGL14.EGL_NO_CONTEXT,
                 attrib_list, 0);
         checkEglError("eglCreateContext");
         if (mEGLContext == null) {
@@ -100,17 +102,40 @@
         }
 
         // Create a window surface, and attach it to the Surface we received.
+        createEGLSurface();
+
+        mWidth = getWidth();
+        mHeight = getHeight();
+    }
+
+    public void updateSize(int width, int height) {
+        if (width != mWidth || height != mHeight) {
+            Log.d(TAG, "re-create EGLSurface");
+            releaseEGLSurface();
+            createEGLSurface();
+            mWidth = getWidth();
+            mHeight = getHeight();
+        }
+    }
+
+    private void createEGLSurface() {
+        //EGLConfig[] configs = new EGLConfig[1];
         int[] surfaceAttribs = {
                 EGL14.EGL_NONE
         };
-        mEGLSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, configs[0], mSurface,
+        mEGLSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mConfigs[0], mSurface,
                 surfaceAttribs, 0);
         checkEglError("eglCreateWindowSurface");
         if (mEGLSurface == null) {
             throw new RuntimeException("surface was null");
         }
     }
-
+    private void releaseEGLSurface() {
+        if (mEGLDisplay != EGL14.EGL_NO_DISPLAY) {
+            EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface);
+            mEGLSurface = EGL14.EGL_NO_SURFACE;
+        }
+    }
     /**
      * Discard all resources held by this class, notably the EGL context.  Also releases the
      * Surface that was passed to our constructor.
diff --git a/tests/tests/media/src/android/media/cts/JetPlayerTest.java b/tests/tests/media/src/android/media/cts/JetPlayerTest.java
index fc03bcc..4df3555 100644
--- a/tests/tests/media/src/android/media/cts/JetPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/JetPlayerTest.java
@@ -55,6 +55,10 @@
 
     @Override
     protected void tearDown() throws Exception {
+        // Prevent tests from failing with EAS_ERROR_FILE_ALREADY_OPEN
+        // after a previous test fails.
+        mJetPlayer.closeJetFile();
+
         File jetFile = new File(mJetFile);
         if (jetFile.exists()) {
             jetFile.delete();
@@ -63,31 +67,32 @@
     }
 
     public void testLoadJetFromPath() throws Throwable {
-        mJetPlayer.clearQueue();
+        assertTrue(mJetPlayer.clearQueue());
         prepareFile();
         mJetPlayer.setEventListener(mOnJetEventListener);
-        mJetPlayer.loadJetFile(mJetFile);
+        assertTrue(mJetPlayer.loadJetFile(mJetFile));
         runJet();
     }
 
     public void testLoadJetFromFd() throws Throwable {
-        mJetPlayer.clearQueue();
+        assertTrue(mJetPlayer.clearQueue());
         mJetPlayer.setEventListener(mOnJetEventListener, mHandler);
-        mJetPlayer.loadJetFile(mContext.getResources().openRawResourceFd(R.raw.test_jet));
+        assertTrue(mJetPlayer.loadJetFile(mContext.getResources().openRawResourceFd(R.raw.test_jet)));
         runJet();
     }
 
     public void testQueueJetSegmentMuteArray() throws Throwable {
-        mJetPlayer.clearQueue();
+        assertTrue(mJetPlayer.clearQueue());
         mJetPlayer.setEventListener(mOnJetEventListener, mHandler);
-        mJetPlayer.loadJetFile(mContext.getResources().openRawResourceFd(R.raw.test_jet));
+        assertTrue(mJetPlayer.loadJetFile(mContext.getResources().openRawResourceFd(R.raw.test_jet)));
         byte userID = 0;
         int segmentNum = 3;
         int libNum = -1;
         int repeatCount = 0;
         int transpose = 0;
         boolean[] muteFlags = new boolean[32];
-        assertTrue(mJetPlayer.queueJetSegmentMuteArray(segmentNum, libNum, repeatCount, transpose,
+        assertTrue(mJetPlayer.queueJetSegmentMuteArray(segmentNum, libNum,
+                repeatCount, transpose,
                 muteFlags, userID));
         assertTrue(mJetPlayer.play());
         for (int i = 0; i < muteFlags.length; i++) {
@@ -96,7 +101,8 @@
         muteFlags[8] = false;
         muteFlags[9] = false;
         muteFlags[10] = false;
-        assertTrue(mJetPlayer.queueJetSegmentMuteArray(segmentNum, libNum, repeatCount, transpose,
+        assertTrue(mJetPlayer.queueJetSegmentMuteArray(segmentNum, libNum,
+                repeatCount, transpose,
                 muteFlags, userID));
         Thread.sleep(20000);
         assertTrue(mJetPlayer.pause());
@@ -112,16 +118,19 @@
         int repeatCount = 1;
         int transpose = 0;
         int muteFlags = 0;
-        mJetPlayer.queueJetSegment(segmentNum, libNum, repeatCount, transpose, muteFlags, userID);
+        assertTrue(mJetPlayer.queueJetSegment(segmentNum, libNum, repeatCount,
+                transpose, muteFlags, userID));
 
         segmentNum = 6;
         repeatCount = 1;
         transpose = -1;
-        mJetPlayer.queueJetSegment(segmentNum, libNum, repeatCount, transpose, muteFlags, userID);
+        assertTrue(mJetPlayer.queueJetSegment(segmentNum, libNum, repeatCount,
+                transpose, muteFlags, userID));
 
         segmentNum = 7;
         transpose = 0;
-        mJetPlayer.queueJetSegment(segmentNum, libNum, repeatCount, transpose, muteFlags, userID);
+        assertTrue(mJetPlayer.queueJetSegment(segmentNum, libNum, repeatCount,
+                transpose, muteFlags, userID));
 
         for (int i = 0; i < 7; i++) {
             assertTrue(mJetPlayer.triggerClip(i));
diff --git a/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
index be5099e..5b4d1aa 100644
--- a/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
+++ b/tests/tests/media/src/android/media/cts/LoudnessEnhancerTest.java
@@ -24,6 +24,9 @@
 import android.media.AudioManager;
 import android.media.MediaPlayer;
 import android.media.audiofx.LoudnessEnhancer;
+import java.util.UUID;
+import android.media.audiofx.Visualizer;
+import android.media.audiofx.Visualizer.MeasurementPeakRms;
 import android.os.Looper;
 import android.test.AndroidTestCase;
 import android.util.Log;
@@ -43,9 +46,6 @@
 
     //Test case 0.0: test constructor and release
     public void test0_0ConstructorAndRelease() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
         assertNotNull("null AudioManager", am);
         getLoudnessEnhancer(0);
@@ -63,9 +63,6 @@
 
     //Test case 1.0: test set/get target gain
     public void test1_0TargetGain() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getLoudnessEnhancer(0);
         try {
             mLE.setTargetGain(0);
@@ -83,6 +80,113 @@
         }
     }
 
+  //Test case 2.0: test loudness gain change in audio
+    public void test2_0MeasureGainChange() throws Exception {
+        if (!hasAudioOutput()) {
+            return;
+        }
+        AudioEffect vc = null;
+        Visualizer visualizer = null;
+        MediaPlayer mp = null;
+        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);
+            final int LOUDNESS_GAIN = 600;
+            final int MAX_MEASUREMENT_ERROR_MB = 200;
+            assertNotNull("null MediaPlayer", mp);
+
+            // 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(BUNDLE_VOLUME_EFFECT_UUID),
+                    0,
+                    mp.getAudioSessionId());
+            vc.setEnabled(true);
+
+            AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
+            assertNotNull("null AudioManager", am);
+            int originalVolume = am.getStreamVolume(AudioManager.STREAM_MUSIC);
+            am.setStreamVolume(AudioManager.STREAM_MUSIC,
+                    am.getStreamMaxVolume(AudioManager.STREAM_MUSIC), 0);
+            int sessionId = mp.getAudioSessionId();
+
+            getLoudnessEnhancer(sessionId);
+            visualizer = new Visualizer(sessionId);
+
+            mp.setLooping(true);
+            mp.start();
+
+            visualizer.setEnabled(true);
+            assertTrue("visualizer not enabled", visualizer.getEnabled());
+            Thread.sleep(100);
+            int status = visualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
+            assertEquals("setMeasurementMode() for PEAK_RMS doesn't report success",
+                    Visualizer.SUCCESS, status);
+            // make sure we're playing long enough so the measurement is valid
+            int currentPosition = mp.getCurrentPosition();
+            int maxTry = 100;
+            int tryCount = 0;
+            while (currentPosition < 200 && tryCount < maxTry) {
+                Thread.sleep(50);
+                currentPosition = mp.getCurrentPosition();
+                tryCount++;
+            }
+            assertTrue("MediaPlayer not ready", tryCount < maxTry);
+
+            MeasurementPeakRms measurement = new MeasurementPeakRms();
+            status = visualizer.getMeasurementPeakRms(measurement);
+
+            //run for a new set of 3 seconds, get new measurement
+            mLE.setTargetGain(LOUDNESS_GAIN);
+            assertEquals("target gain differs from value set", (float)LOUDNESS_GAIN,
+                    mLE.getTargetGain());
+
+            mLE.setEnabled(true);
+
+            visualizer.setMeasurementMode(Visualizer.MEASUREMENT_MODE_PEAK_RMS);
+            currentPosition = mp.getCurrentPosition();
+            maxTry = 5;
+            tryCount = 0;
+            while (tryCount < maxTry) {
+                Thread.sleep(50);
+                tryCount++;
+            }
+
+            MeasurementPeakRms measurement2 = new MeasurementPeakRms();
+            status = visualizer.getMeasurementPeakRms(measurement2);
+
+            //compare both measurements
+            am.setStreamVolume(AudioManager.STREAM_MUSIC, originalVolume, 0);
+            assertEquals("getMeasurementPeakRms() reports failure",
+                    Visualizer.SUCCESS, status);
+            Log.i("VisTest", "peak="+measurement.mPeak+"  rms="+measurement.mRms);
+            Log.i("VisTest", "peak2="+measurement2.mPeak+"  rms2="+measurement2.mRms);
+
+            int deltaPeak = Math.abs(measurement2.mPeak - (measurement.mPeak + LOUDNESS_GAIN) );
+            assertTrue("peak deviation in mB = "+deltaPeak, deltaPeak < MAX_MEASUREMENT_ERROR_MB);
+
+        } catch (IllegalStateException e) {
+            fail("method called in wrong state");
+        } catch (InterruptedException e) {
+            fail("sleep() interrupted");
+        } finally {
+            if (mp != null) {
+                mp.stop();
+                mp.release();
+            }
+
+            if (vc != null)
+                vc.release();
+
+            if (visualizer != null)
+                visualizer.release();
+
+            releaseLoudnessEnhancer();
+        }
+    }
+
     //-----------------------------------------------------------------
     // private methods
     //----------------------------------
diff --git a/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java b/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
index 996ddf7..02bdd7f 100644
--- a/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaBrowserServiceTest.java
@@ -35,31 +35,44 @@
     private static final ComponentName TEST_BROWSER_SERVICE = new ComponentName(
             "com.android.cts.media", "android.media.cts.StubMediaBrowserService");
     private final Object mWaitLock = new Object();
+
     private final MediaBrowser.ConnectionCallback mConnectionCallback =
             new MediaBrowser.ConnectionCallback() {
-                @Override
-                public void onConnected() {
-                    synchronized (mWaitLock) {
-                        mMediaBrowserService = StubMediaBrowserService.sInstance;
-                        mWaitLock.notify();
-                    }
-                }
-            };
+        @Override
+        public void onConnected() {
+            synchronized (mWaitLock) {
+                mMediaBrowserService = StubMediaBrowserService.sInstance;
+                mWaitLock.notify();
+            }
+        }
+    };
 
     private final MediaBrowser.SubscriptionCallback mSubscriptionCallback  =
             new MediaBrowser.SubscriptionCallback() {
-                @Override
-                public void onChildrenLoaded(String parentId, List<MediaItem> children) {
-                    synchronized (mWaitLock) {
-                        mOnChildrenLoaded = true;
-                        mWaitLock.notify();
-                    }
+            @Override
+            public void onChildrenLoaded(String parentId, List<MediaItem> children) {
+                synchronized (mWaitLock) {
+                    mOnChildrenLoaded = true;
+                    mWaitLock.notify();
                 }
-            };
+            }
+        };
+
+    private final MediaBrowser.ItemCallback mItemCallback  =
+            new MediaBrowser.ItemCallback() {
+        @Override
+        public void onItemLoaded(MediaItem item) {
+            synchronized (mWaitLock) {
+                mOnItemLoaded = true;
+                mWaitLock.notify();
+            }
+        }
+    };
 
     private MediaBrowser mMediaBrowser;
     private StubMediaBrowserService mMediaBrowserService;
     private boolean mOnChildrenLoaded;
+    private boolean mOnItemLoaded;
 
     @Override
     protected void setUp() throws Exception {
@@ -119,6 +132,20 @@
         }
     }
 
+    public void testDelayedItem() throws Exception {
+        synchronized (mWaitLock) {
+            mOnItemLoaded = false;
+            mMediaBrowser.getItem(StubMediaBrowserService.MEDIA_ID_CHILDREN_DELAYED,
+                    mItemCallback);
+            mWaitLock.wait(WAIT_TIME_FOR_NO_RESPONSE_MS);
+            assertFalse(mOnItemLoaded);
+
+            mMediaBrowserService.sendDelayedItemLoaded();
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mOnItemLoaded);
+        }
+    }
+
     public void testBrowserRoot() {
         final String id = "test-id";
         final String key = "test-key";
diff --git a/tests/tests/media/src/android/media/cts/MediaBrowserTest.java b/tests/tests/media/src/android/media/cts/MediaBrowserTest.java
index 51d43d9..7dd978f 100644
--- a/tests/tests/media/src/android/media/cts/MediaBrowserTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaBrowserTest.java
@@ -18,6 +18,7 @@
 import android.content.ComponentName;
 import android.cts.util.PollingCheck;
 import android.media.browse.MediaBrowser;
+import android.media.browse.MediaBrowser.MediaItem;
 import android.test.InstrumentationTestCase;
 
 import java.util.List;
@@ -34,6 +35,7 @@
             "invalid.package", "invalid.ServiceClassName");
     private final StubConnectionCallback mConnectionCallback = new StubConnectionCallback();
     private final StubSubscriptionCallback mSubscriptionCallback = new StubSubscriptionCallback();
+    private final StubItemCallback mItemCallback = new StubItemCallback();
 
     private MediaBrowser mMediaBrowser;
 
@@ -115,6 +117,37 @@
         }
     }
 
+    public void testGetItem() {
+        resetCallbacks();
+        createMediaBrowser(TEST_BROWSER_SERVICE);
+        connectMediaBrowserService();
+        mMediaBrowser.getItem(StubMediaBrowserService.MEDIA_ID_CHILDREN[0], mItemCallback);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mItemCallback.mLastMediaItem != null;
+            }
+        }.run();
+
+        assertEquals(StubMediaBrowserService.MEDIA_ID_CHILDREN[0],
+                mItemCallback.mLastMediaItem.getMediaId());
+    }
+
+    public void testGetItemFailure() {
+        resetCallbacks();
+        createMediaBrowser(TEST_BROWSER_SERVICE);
+        connectMediaBrowserService();
+        mMediaBrowser.getItem("does-not-exist", mItemCallback);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mItemCallback.mLastErrorId != null;
+            }
+        }.run();
+
+        assertEquals("does-not-exist", mItemCallback.mLastErrorId);
+    }
+
     private void createMediaBrowser(final ComponentName component) {
         getInstrumentation().runOnMainSync(new Runnable() {
             @Override
@@ -138,6 +171,7 @@
     private void resetCallbacks() {
         mConnectionCallback.reset();
         mSubscriptionCallback.reset();
+        mItemCallback.reset();
     }
 
     private static class StubConnectionCallback extends MediaBrowser.ConnectionCallback {
@@ -169,14 +203,12 @@
 
     private static class StubSubscriptionCallback extends MediaBrowser.SubscriptionCallback {
         private volatile int mChildrenLoadedCount;
-        private volatile int mErrorCount;
         private volatile String mLastErrorId;
         private volatile String mLastParentId;
         private volatile List<MediaBrowser.MediaItem> mLastChildMediaItems;
 
         public void reset() {
             mChildrenLoadedCount = 0;
-            mErrorCount = 0;
             mLastErrorId = null;
             mLastParentId = null;
             mLastChildMediaItems = null;
@@ -194,4 +226,24 @@
             mLastErrorId = id;
         }
     }
+
+    private static class StubItemCallback extends MediaBrowser.ItemCallback {
+        private volatile MediaBrowser.MediaItem mLastMediaItem;
+        private volatile String mLastErrorId;
+
+        public void reset() {
+            mLastMediaItem = null;
+            mLastErrorId = null;
+        }
+
+        @Override
+        public void onItemLoaded(MediaItem item) {
+            mLastMediaItem = item;
+        }
+
+        @Override
+        public void onError(String id) {
+            mLastErrorId = id;
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
index 159d13f..71cbd61 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCapabilitiesTest.java
@@ -19,6 +19,7 @@
 import android.cts.util.MediaUtils;
 import android.media.MediaCodec;
 import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.AudioCapabilities;
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaCodecInfo.CodecProfileLevel;
 import android.media.MediaCodecInfo.VideoCapabilities;
@@ -39,6 +40,7 @@
 import java.util.HashSet;
 import java.util.Set;
 import java.util.Arrays;
+import java.util.Vector;
 
 /**
  * Basic sanity test of data returned by MediaCodeCapabilities.
@@ -528,4 +530,140 @@
             MediaUtils.skipTest("no non-tunneled/non-secure video decoders found");
         }
     }
+
+    private static MediaFormat createMinFormat(String mime, CodecCapabilities caps) {
+        MediaFormat format;
+        if (caps.getVideoCapabilities() != null) {
+            VideoCapabilities vcaps = caps.getVideoCapabilities();
+            int minWidth = vcaps.getSupportedWidths().getLower();
+            int minHeight = vcaps.getSupportedHeightsFor(minWidth).getLower();
+            int minBitrate = vcaps.getBitrateRange().getLower();
+            format = MediaFormat.createVideoFormat(mime, minWidth, minHeight);
+            format.setInteger(MediaFormat.KEY_COLOR_FORMAT, caps.colorFormats[0]);
+            format.setInteger(MediaFormat.KEY_BIT_RATE, minBitrate);
+            format.setInteger(MediaFormat.KEY_FRAME_RATE, 10);
+            format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 10);
+        } else {
+            AudioCapabilities acaps = caps.getAudioCapabilities();
+            int minSampleRate = acaps.getSupportedSampleRateRanges()[0].getLower();
+            int minChannelCount = 1;
+            int minBitrate = acaps.getBitrateRange().getLower();
+            format = MediaFormat.createAudioFormat(mime, minSampleRate, minChannelCount);
+            format.setInteger(MediaFormat.KEY_BIT_RATE, minBitrate);
+        }
+
+        return format;
+    }
+
+    private static int getActualMax(
+            boolean isEncoder, String name, String mime, CodecCapabilities caps, int max) {
+        int flag = isEncoder ? MediaCodec.CONFIGURE_FLAG_ENCODE : 0;
+        MediaFormat format = createMinFormat(mime, caps);
+        Log.d(TAG, "Test format " + format);
+        Vector<MediaCodec> codecs = new Vector<MediaCodec>();
+        MediaCodec codec = null;
+        for (int i = 0; i < max; ++i) {
+            try {
+                Log.d(TAG, "Create codec " + name + " #" + i);
+                codec = MediaCodec.createByCodecName(name);
+                codec.configure(format, null, null, flag);
+                codec.start();
+                codecs.add(codec);
+                codec = null;
+            } catch (IllegalArgumentException e) {
+                fail("Got unexpected IllegalArgumentException " + e.getMessage());
+            } catch (IOException e) {
+                fail("Got unexpected IOException " + e.getMessage());
+            } catch (MediaCodec.CodecException e) {
+                // ERROR_INSUFFICIENT_RESOURCE is expected as the test keep creating codecs.
+                // But other exception should be treated as failure.
+                if (e.getErrorCode() == MediaCodec.CodecException.ERROR_INSUFFICIENT_RESOURCE) {
+                    Log.d(TAG, "Got CodecException with ERROR_INSUFFICIENT_RESOURCE.");
+                    break;
+                } else {
+                    fail("Unexpected CodecException " + e.getDiagnosticInfo());
+                }
+            } finally {
+                if (codec != null) {
+                    Log.d(TAG, "release codec");
+                    codec.release();
+                    codec = null;
+                }
+            }
+        }
+        int actualMax = codecs.size();
+        for (int i = 0; i < codecs.size(); ++i) {
+            Log.d(TAG, "release codec #" + i);
+            codecs.get(i).release();
+        }
+        codecs.clear();
+        return actualMax;
+    }
+
+    private boolean knownTypes(String type) {
+        return (type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC  ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AC3      ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB   ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB   ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_EAC3     ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC     ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MPEG     ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM    ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_OPUS     ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_RAW      ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_VORBIS   ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC      ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263     ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC     ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG2    ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4    ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8      ) ||
+            type.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9      ));
+    }
+
+    public void testGetMaxSupportedInstances() {
+        final int MAX_INSTANCES = 32;
+        StringBuilder xmlOverrides = new StringBuilder();
+        MediaCodecList allCodecs = new MediaCodecList(MediaCodecList.ALL_CODECS);
+        for (MediaCodecInfo info : allCodecs.getCodecInfos()) {
+            Log.d(TAG, "codec: " + info.getName());
+            Log.d(TAG, "  isEncoder = " + info.isEncoder());
+
+            String[] types = info.getSupportedTypes();
+            for (int j = 0; j < types.length; ++j) {
+                if (!knownTypes(types[j])) {
+                    Log.d(TAG, "skipping unknown type " + types[j]);
+                    continue;
+                }
+                Log.d(TAG, "calling getCapabilitiesForType " + types[j]);
+                CodecCapabilities caps = info.getCapabilitiesForType(types[j]);
+                int max = caps.getMaxSupportedInstances();
+                Log.d(TAG, "getMaxSupportedInstances returns " + max);
+                assertTrue(max > 0);
+
+                int actualMax = getActualMax(
+                        info.isEncoder(), info.getName(), types[j], caps, MAX_INSTANCES);
+                Log.d(TAG, "actualMax " + actualMax + " vs reported max " + max);
+                if (actualMax < (int)(max * 0.9) || actualMax > (int) Math.ceil(max * 1.1)) {
+                    String codec = "<MediaCodec name=\"" + info.getName() +
+                            "\" type=\"" + types[j] + "\" >";
+                    String limit = "    <Limit name=\"concurrent-instances\" max=\"" +
+                            actualMax + "\" />";
+                    xmlOverrides.append(codec);
+                    xmlOverrides.append("\n");
+                    xmlOverrides.append(limit);
+                    xmlOverrides.append("\n");
+                    xmlOverrides.append("</MediaCodec>\n");
+                }
+            }
+        }
+
+        if (xmlOverrides.length() > 0) {
+            String failMessage = "In order to pass the test, please publish following " +
+                    "codecs' concurrent instances limit in /etc/media_codecs.xml: \n";
+           fail(failMessage + xmlOverrides.toString());
+        }
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java b/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
index b96d38c..f5856ed 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecCencPlayer.java
@@ -54,7 +54,7 @@
 
     private boolean mEncryptedAudio;
     private boolean mEncryptedVideo;
-    private boolean mThreadStarted = false;
+    private volatile boolean mThreadStarted = false;
     private byte[] mSessionId;
     private CodecState mAudioTrackState;
     private int mMediaFormatHeight;
@@ -248,12 +248,14 @@
 
         if (null == mCrypto && (mEncryptedVideo || mEncryptedAudio)) {
             try {
-                mCrypto = new MediaCrypto(CLEARKEY_SCHEME_UUID, mSessionId);
+                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();
@@ -302,7 +304,7 @@
         CodecState state;
         if (isVideo) {
             state = new CodecState((MediaTimeProvider)this, mVideoExtractor,
-                            trackIndex, format, codec, true, false, 
+                            trackIndex, format, codec, true, false,
                             AudioManager.AUDIO_SESSION_ID_GENERATE);
             mVideoCodecStates.put(Integer.valueOf(trackIndex), state);
         } else {
diff --git a/tests/tests/media/src/android/media/cts/MediaCodecTest.java b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
index 494e823..d3ab54f 100644
--- a/tests/tests/media/src/android/media/cts/MediaCodecTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaCodecTest.java
@@ -21,6 +21,8 @@
 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.MediaCodecInfo;
 import android.media.MediaCodecList;
 import android.media.MediaExtractor;
@@ -28,13 +30,20 @@
 import android.media.MediaCodecInfo.CodecCapabilities;
 import android.media.MediaCodecInfo.CodecProfileLevel;
 import android.opengl.GLES20;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.test.AndroidTestCase;
 import android.util.Log;
 import android.view.Surface;
 
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * General MediaCodec tests.
@@ -457,6 +466,301 @@
         }
     }
 
+    public void testReleaseAfterFlush() throws IOException, InterruptedException {
+        String mimes[] = new String[] { MIME_TYPE, MIME_TYPE_AUDIO};
+        for (String mime : mimes) {
+            if (!MediaUtils.checkEncoder(mime)) {
+                continue;
+            }
+            testReleaseAfterFlush(mime);
+        }
+    }
+
+    private void testReleaseAfterFlush(String mime) throws IOException, InterruptedException {
+        CountDownLatch buffersExhausted = null;
+        CountDownLatch codecFlushed = null;
+        AtomicInteger numBuffers = null;
+
+        // sync flush from same thread
+        MediaCodec encoder = MediaCodec.createEncoderByType(mime);
+        runReleaseAfterFlush(mime, encoder, buffersExhausted, codecFlushed, numBuffers);
+
+        // sync flush from different thread
+        encoder = MediaCodec.createEncoderByType(mime);
+        buffersExhausted = new CountDownLatch(1);
+        codecFlushed = new CountDownLatch(1);
+        numBuffers = new AtomicInteger();
+        Thread flushThread = new FlushThread(encoder, buffersExhausted, codecFlushed);
+        flushThread.start();
+        runReleaseAfterFlush(mime, encoder, buffersExhausted, codecFlushed, numBuffers);
+        flushThread.join();
+
+        // async
+        // This value is calculated in getOutputBufferIndices by calling dequeueOutputBuffer
+        // with a fixed timeout until buffers are exhausted; it is possible that random timing
+        // in dequeueOutputBuffer can result in a smaller `nBuffs` than the max possible value.
+        int nBuffs = numBuffers.get();
+        HandlerThread callbackThread = new HandlerThread("ReleaseAfterFlushCallbackThread");
+        callbackThread.start();
+        Handler handler = new Handler(callbackThread.getLooper());
+
+        // async flush from same thread
+        encoder = MediaCodec.createEncoderByType(mime);
+        buffersExhausted = null;
+        codecFlushed = null;
+        ReleaseAfterFlushCallback callback =
+                new ReleaseAfterFlushCallback(mime, encoder, buffersExhausted, codecFlushed, nBuffs);
+        encoder.setCallback(callback, handler); // setCallback before configure, which is called in run
+        callback.run(); // drive input on main thread
+
+        // async flush from different thread
+        encoder = MediaCodec.createEncoderByType(mime);
+        buffersExhausted = new CountDownLatch(1);
+        codecFlushed = new CountDownLatch(1);
+        callback = new ReleaseAfterFlushCallback(mime, encoder, buffersExhausted, codecFlushed, nBuffs);
+        encoder.setCallback(callback, handler);
+        flushThread = new FlushThread(encoder, buffersExhausted, codecFlushed);
+        flushThread.start();
+        callback.run();
+        flushThread.join();
+
+        callbackThread.quitSafely();
+        callbackThread.join();
+    }
+
+    private static class FlushThread extends Thread {
+        final MediaCodec mEncoder;
+        final CountDownLatch mBuffersExhausted;
+        final CountDownLatch mCodecFlushed;
+
+        FlushThread(MediaCodec encoder, CountDownLatch buffersExhausted,
+                CountDownLatch codecFlushed) {
+            mEncoder = encoder;
+            mBuffersExhausted = buffersExhausted;
+            mCodecFlushed = codecFlushed;
+        }
+
+        @Override
+        public void run() {
+            try {
+                mBuffersExhausted.await();
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                Log.w(TAG, "buffersExhausted wait interrupted; flushing immediately.", e);
+            }
+            mEncoder.flush();
+            mCodecFlushed.countDown();
+        }
+    }
+
+    private static class ReleaseAfterFlushCallback extends MediaCodec.Callback implements Runnable {
+        final String mMime;
+        final MediaCodec mEncoder;
+        final CountDownLatch mBuffersExhausted, mCodecFlushed;
+        final int mNumBuffersBeforeFlush;
+
+        CountDownLatch mStopInput = new CountDownLatch(1);
+        List<Integer> mInputBufferIndices = new ArrayList<>();
+        List<Integer> mOutputBufferIndices = new ArrayList<>();
+
+        ReleaseAfterFlushCallback(String mime,
+                MediaCodec encoder,
+                CountDownLatch buffersExhausted,
+                CountDownLatch codecFlushed,
+                int numBuffersBeforeFlush) {
+            mMime = mime;
+            mEncoder = encoder;
+            mBuffersExhausted = buffersExhausted;
+            mCodecFlushed = codecFlushed;
+            mNumBuffersBeforeFlush = numBuffersBeforeFlush;
+        }
+
+        @Override
+        public void onInputBufferAvailable(MediaCodec codec, int index) {
+            assertTrue("video onInputBufferAvailable " + index, mMime.startsWith("audio/"));
+            synchronized (mInputBufferIndices) {
+                mInputBufferIndices.add(index);
+            };
+        }
+
+        @Override
+        public void onOutputBufferAvailable(MediaCodec codec, int index, BufferInfo info) {
+            mOutputBufferIndices.add(index);
+            if (mOutputBufferIndices.size() == mNumBuffersBeforeFlush) {
+                releaseAfterFlush(codec, mOutputBufferIndices, mBuffersExhausted, mCodecFlushed);
+                mStopInput.countDown();
+            }
+        }
+
+        @Override
+        public void onError(MediaCodec codec, CodecException e) {
+            Log.e(TAG, codec + " onError", e);
+            fail(codec + " onError " + e.getMessage());
+        }
+
+        @Override
+        public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
+            Log.v(TAG, codec + " onOutputFormatChanged " + format);
+        }
+
+        @Override
+        public void run() {
+            InputSurface inputSurface = null;
+            try {
+                inputSurface = initCodecAndSurface(mMime, mEncoder);
+                do {
+                    int inputIndex = -1;
+                    if (inputSurface == null) {
+                        // asynchronous audio codec
+                        synchronized (mInputBufferIndices) {
+                            if (mInputBufferIndices.isEmpty()) {
+                                continue;
+                            } else {
+                                inputIndex = mInputBufferIndices.remove(0);
+                            }
+                        }
+                    }
+                    feedEncoder(mEncoder, inputSurface, inputIndex);
+                } while (!mStopInput.await(TIMEOUT_USEC, TimeUnit.MICROSECONDS));
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                Log.w(TAG, "mEncoder input frames interrupted/stopped", e);
+            } finally {
+                cleanupCodecAndSurface(mEncoder, inputSurface);
+            }
+        }
+    }
+
+    private static void runReleaseAfterFlush(
+            String mime,
+            MediaCodec encoder,
+            CountDownLatch buffersExhausted,
+            CountDownLatch codecFlushed,
+            AtomicInteger numBuffers) {
+        InputSurface inputSurface = null;
+        try {
+            inputSurface = initCodecAndSurface(mime, encoder);
+            List<Integer> outputBufferIndices = getOutputBufferIndices(encoder, inputSurface);
+            if (numBuffers != null) {
+                numBuffers.set(outputBufferIndices.size());
+            }
+            releaseAfterFlush(encoder, outputBufferIndices, buffersExhausted, codecFlushed);
+        } finally {
+            cleanupCodecAndSurface(encoder, inputSurface);
+        }
+    }
+
+    private static InputSurface initCodecAndSurface(String mime, MediaCodec encoder) {
+        MediaFormat format;
+        InputSurface inputSurface = null;
+        if (mime.startsWith("audio/")) {
+            format = MediaFormat.createAudioFormat(mime, AUDIO_SAMPLE_RATE, AUDIO_CHANNEL_COUNT);
+            format.setInteger(MediaFormat.KEY_AAC_PROFILE, AUDIO_AAC_PROFILE);
+            format.setInteger(MediaFormat.KEY_BIT_RATE, AUDIO_BIT_RATE);
+            encoder.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+        } else if (MIME_TYPE.equals(mime)) {
+            CodecInfo info = getAvcSupportedFormatInfo();
+            format = MediaFormat.createVideoFormat(mime, info.mMaxW, info.mMaxH);
+            format.setInteger(MediaFormat.KEY_COLOR_FORMAT,
+                    MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
+            format.setInteger(MediaFormat.KEY_BIT_RATE, info.mBitRate);
+            format.setInteger(MediaFormat.KEY_FRAME_RATE, info.mFps);
+            format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
+            OutputSurface outputSurface = new OutputSurface(1, 1);
+            encoder.configure(format, outputSurface.getSurface(), null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+            inputSurface = new InputSurface(encoder.createInputSurface());
+            inputSurface.makeCurrent();
+        } else {
+            throw new IllegalArgumentException("unsupported mime type: " + mime);
+        }
+        encoder.start();
+        return inputSurface;
+    }
+
+    private static void cleanupCodecAndSurface(MediaCodec encoder, InputSurface inputSurface) {
+        if (encoder != null) {
+            encoder.stop();
+            encoder.release();
+        }
+
+        if (inputSurface != null) {
+            inputSurface.release();
+        }
+    }
+
+    private static List<Integer> getOutputBufferIndices(MediaCodec encoder, InputSurface inputSurface) {
+        boolean feedMoreFrames;
+        MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
+        List<Integer> indices = new ArrayList<>();
+        do {
+            feedMoreFrames = indices.isEmpty();
+            feedEncoder(encoder, inputSurface, -1);
+            // dequeue buffers until not available
+            int index = encoder.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC);
+            while (index >= 0) {
+                feedMoreFrames = true;
+                indices.add(index);
+                index = encoder.dequeueOutputBuffer(bufferInfo, TIMEOUT_USEC_SHORT);
+            }
+        } while (feedMoreFrames);
+        assertFalse(indices.isEmpty());
+        return indices;
+    }
+
+    /**
+     * @param encoder audio/video encoder
+     * @param inputSurface null for and only for audio encoders
+     * @param inputIndex only used for audio; if -1 the function would attempt to dequeue from encoder;
+     * do not use -1 for asynchronous encoders
+     */
+    private static void feedEncoder(MediaCodec encoder, InputSurface inputSurface, int inputIndex) {
+        if (inputSurface == null) {
+            // audio
+            while (inputIndex == -1) {
+                inputIndex = encoder.dequeueInputBuffer(TIMEOUT_USEC);
+            }
+            ByteBuffer inputBuffer = encoder.getInputBuffer(inputIndex);;
+            for (int i = 0; i < inputBuffer.capacity() / 2; i++) {
+                inputBuffer.putShort((short)i);
+            }
+            encoder.queueInputBuffer(inputIndex, 0, inputBuffer.limit(), 0, 0);
+        } else {
+            // video
+            GLES20.glClearColor(0.0f, 0.5f, 0.0f, 1.0f);
+            GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
+            inputSurface.swapBuffers();
+        }
+    }
+
+    private static void releaseAfterFlush(
+            MediaCodec encoder,
+            List<Integer> outputBufferIndices,
+            CountDownLatch buffersExhausted,
+            CountDownLatch codecFlushed) {
+        if (buffersExhausted == null) {
+            // flush from same thread
+            encoder.flush();
+        } else {
+            assertNotNull(codecFlushed);
+            buffersExhausted.countDown();
+            try {
+                codecFlushed.await();
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                Log.w(TAG, "codecFlushed wait interrupted; releasing buffers immediately.", e);
+            }
+        }
+
+        for (int index : outputBufferIndices) {
+            try {
+                encoder.releaseOutputBuffer(index, true);
+                fail("MediaCodec releaseOutputBuffer after flush() does not throw exception");
+            } catch (MediaCodec.CodecException e) {
+                // Expected
+            }
+        }
+    }
+
     /**
      * Tests:
      * <br> dequeueInputBuffer() fails when encoder configured with an input Surface
@@ -553,6 +857,130 @@
         }
     }
 
+    public void testDecodeAfterFlush() throws InterruptedException {
+        testDecodeAfterFlush(true /* audio */);
+        testDecodeAfterFlush(false /* audio */);
+    }
+
+    private void testDecodeAfterFlush(final boolean audio) throws InterruptedException {
+        final int INPUT_RESOURCE_ID =
+                R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
+
+        // The test should fail if the decoder never produces output frames for the input.
+        // Time out decoding, as we have no way to query whether the decoder will produce output.
+        final int DECODING_TIMEOUT_MS = 10000;
+
+        final AtomicBoolean completed = new AtomicBoolean(false);
+        Thread decodingThread = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                OutputSurface outputSurface = null;
+                MediaExtractor mediaExtractor = null;
+                MediaCodec mediaCodec = null;
+                try {
+                    String mimeTypePrefix  = audio ? "audio/" : "video/";
+                    if (!audio) {
+                        outputSurface = new OutputSurface(1, 1);
+                    }
+                    mediaExtractor = getMediaExtractorForMimeType(INPUT_RESOURCE_ID, mimeTypePrefix);
+                    MediaFormat mediaFormat =
+                            mediaExtractor.getTrackFormat(mediaExtractor.getSampleTrackIndex());
+                    if (!MediaUtils.checkDecoderForFormat(mediaFormat)) {
+                        completed.set(true);
+                        return; // skip
+                    }
+                    String mimeType = mediaFormat.getString(MediaFormat.KEY_MIME);
+                    mediaCodec = MediaCodec.createDecoderByType(mimeType);
+                    mediaCodec.configure(mediaFormat, outputSurface == null ? null : outputSurface.getSurface(),
+                            null /* crypto */, 0 /* flags */);
+                    mediaCodec.start();
+
+                    if (!runDecodeTillFirstOutput(mediaCodec, mediaExtractor)) {
+                        throw new RuntimeException("decoder does not generate non-empty output.");
+                    }
+
+                    // simulate application flush.
+                    mediaExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
+                    mediaCodec.flush();
+
+                    completed.set(runDecodeTillFirstOutput(mediaCodec, mediaExtractor));
+                } catch (IOException e) {
+                    throw new RuntimeException("error setting up decoding", e);
+                } finally {
+                    if (mediaCodec != null) {
+                        mediaCodec.stop();
+                        mediaCodec.release();
+                    }
+                    if (mediaExtractor != null) {
+                        mediaExtractor.release();
+                    }
+                    if (outputSurface != null) {
+                        outputSurface.release();
+                    }
+                }
+            }
+        });
+        decodingThread.start();
+        decodingThread.join(DECODING_TIMEOUT_MS);
+        // In case it's timed out, need to stop the thread and have all resources released.
+        decodingThread.interrupt();
+        if (!completed.get()) {
+            throw new RuntimeException("timed out decoding to end-of-stream");
+        }
+    }
+
+    // Run the decoder till it generates an output buffer.
+    // Return true when that output buffer is not empty, false otherwise.
+    private static boolean runDecodeTillFirstOutput(
+            MediaCodec mediaCodec, MediaExtractor mediaExtractor) {
+        final int TIME_OUT_US = 10000;
+
+        assertTrue("Wrong test stream which has no data.",
+                mediaExtractor.getSampleTrackIndex() != -1);
+        boolean signaledEos = false;
+        MediaCodec.BufferInfo outputBufferInfo = new MediaCodec.BufferInfo();
+        while (!Thread.interrupted()) {
+            // Try to feed more data into the codec.
+            if (!signaledEos) {
+                int bufferIndex = mediaCodec.dequeueInputBuffer(TIME_OUT_US /* timeoutUs */);
+                if (bufferIndex != -1) {
+                    ByteBuffer buffer = mediaCodec.getInputBuffer(bufferIndex);
+                    int size = mediaExtractor.readSampleData(buffer, 0 /* offset */);
+                    long timestampUs = mediaExtractor.getSampleTime();
+                    mediaExtractor.advance();
+                    signaledEos = mediaExtractor.getSampleTrackIndex() == -1;
+                    mediaCodec.queueInputBuffer(bufferIndex,
+                            0 /* offset */,
+                            size,
+                            timestampUs,
+                            signaledEos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+                    Log.i("DEBUG", "queue with " + signaledEos);
+                }
+            }
+
+            int outputBufferIndex = mediaCodec.dequeueOutputBuffer(
+                    outputBufferInfo, TIME_OUT_US /* timeoutUs */);
+
+            if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED
+                    || outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED
+                    || outputBufferIndex == MediaCodec.INFO_TRY_AGAIN_LATER) {
+                continue;
+            }
+            assertTrue("Wrong output buffer index", outputBufferIndex >= 0);
+
+            mediaCodec.releaseOutputBuffer(outputBufferIndex, false /* render */);
+            boolean eos = (outputBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
+            Log.i("DEBUG", "Got a frame with eos=" + eos);
+            if (eos && outputBufferInfo.size == 0) {
+                return false;
+            } else {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Tests whether decoding a short group-of-pictures succeeds. The test queues a few video frames
      * then signals end-of-stream. The test fails if the decoder doesn't output the queued frames.
diff --git a/tests/tests/media/src/android/media/cts/MediaControllerTest.java b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
index a153c4da..caf2a94 100644
--- a/tests/tests/media/src/android/media/cts/MediaControllerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaControllerTest.java
@@ -21,6 +21,7 @@
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
 import android.media.session.PlaybackState.CustomAction;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -182,6 +183,14 @@
             assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
 
             mCallback.reset();
+            final Uri uri = Uri.parse("content://test/popcorn.mod");
+            controls.playFromUri(uri, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+            assertTrue(mCallback.mOnPlayFromUriCalled);
+            assertEquals(uri, mCallback.mUri);
+            assertEquals(EXTRAS_VALUE, mCallback.mExtras.getString(EXTRAS_KEY));
+
+            mCallback.reset();
             final String action = "test-action";
             controls.sendCustomAction(action, extras);
             mWaitLock.wait(TIME_OUT_MS);
@@ -209,30 +218,32 @@
     }
 
     private class MediaSessionCallback extends MediaSession.Callback {
-        private volatile long mSeekPosition;
-        private volatile long mQueueItemId;
-        private volatile Rating mRating;
-        private volatile String mMediaId;
-        private volatile String mQuery;
-        private volatile String mAction;
-        private volatile String mCommand;
-        private volatile Bundle mExtras;
-        private volatile ResultReceiver mCommandCallback;
+        private long mSeekPosition;
+        private long mQueueItemId;
+        private Rating mRating;
+        private String mMediaId;
+        private String mQuery;
+        private Uri mUri;
+        private String mAction;
+        private String mCommand;
+        private Bundle mExtras;
+        private ResultReceiver mCommandCallback;
 
-        private volatile boolean mOnPlayCalled;
-        private volatile boolean mOnPauseCalled;
-        private volatile boolean mOnStopCalled;
-        private volatile boolean mOnFastForwardCalled;
-        private volatile boolean mOnRewindCalled;
-        private volatile boolean mOnSkipToPreviousCalled;
-        private volatile boolean mOnSkipToNextCalled;
-        private volatile boolean mOnSeekToCalled;
-        private volatile boolean mOnSkipToQueueItemCalled;
-        private volatile boolean mOnSetRatingCalled;
-        private volatile boolean mOnPlayFromMediaIdCalled;
-        private volatile boolean mOnPlayFromSearchCalled;
-        private volatile boolean mOnCustomActionCalled;
-        private volatile boolean mOnCommandCalled;
+        private boolean mOnPlayCalled;
+        private boolean mOnPauseCalled;
+        private boolean mOnStopCalled;
+        private boolean mOnFastForwardCalled;
+        private boolean mOnRewindCalled;
+        private boolean mOnSkipToPreviousCalled;
+        private boolean mOnSkipToNextCalled;
+        private boolean mOnSeekToCalled;
+        private boolean mOnSkipToQueueItemCalled;
+        private boolean mOnSetRatingCalled;
+        private boolean mOnPlayFromMediaIdCalled;
+        private boolean mOnPlayFromSearchCalled;
+        private boolean mOnPlayFromUriCalled;
+        private boolean mOnCustomActionCalled;
+        private boolean mOnCommandCalled;
 
         public void reset() {
             mSeekPosition = -1;
@@ -240,6 +251,7 @@
             mRating = null;
             mMediaId = null;
             mQuery = null;
+            mUri = null;
             mAction = null;
             mExtras = null;
             mCommand = null;
@@ -257,6 +269,7 @@
             mOnSetRatingCalled = false;
             mOnPlayFromMediaIdCalled = false;
             mOnPlayFromSearchCalled = false;
+            mOnPlayFromUriCalled = false;
             mOnCustomActionCalled = false;
             mOnCommandCalled = false;
         }
@@ -356,6 +369,16 @@
         }
 
         @Override
+        public void onPlayFromUri(Uri uri, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnPlayFromUriCalled = true;
+                mUri = uri;
+                mExtras = extras;
+                mWaitLock.notify();
+            }
+        }
+
+        @Override
         public void onCustomAction(String action, Bundle extras) {
             synchronized (mWaitLock) {
                 mOnCustomActionCalled= true;
diff --git a/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java b/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java
index 1a3184d..a197cca 100644
--- a/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaDrmMockTest.java
@@ -17,9 +17,10 @@
 package android.media.cts;
 
 import android.media.MediaDrm;
-import android.media.MediaDrm.ProvisionRequest;
-import android.media.MediaDrm.KeyRequest;
 import android.media.MediaDrm.CryptoSession;
+import android.media.MediaDrm.KeyRequest;
+import android.media.MediaDrm.KeyStatus;
+import android.media.MediaDrm.ProvisionRequest;
 import android.media.MediaDrmException;
 import android.media.NotProvisionedException;
 import android.media.ResourceBusyException;
@@ -231,6 +232,7 @@
         md.setPropertyByteArray("mock-request", testRequest);
         String testDefaultUrl = "http://1.2.3.4:8080/blah";
         md.setPropertyString("mock-defaultUrl", testDefaultUrl);
+        md.setPropertyString("mock-keyRequestType", "1" /*kKeyRequestType_Initial*/);
 
         byte[] initData = {0x0a, 0x0b, 0x0c, 0x0d};
         HashMap<String, String> optionalParameters = new HashMap<String, String>();
@@ -243,6 +245,7 @@
                                                       optionalParameters);
         assertTrue(Arrays.equals(request.getData(), testRequest));
         assertTrue(request.getDefaultUrl().equals(testDefaultUrl));
+        assertEquals(request.getRequestType(), MediaDrm.KeyRequest.REQUEST_TYPE_INITIAL);
 
         assertTrue(Arrays.equals(initData, md.getPropertyByteArray("mock-initdata")));
         assertTrue(mimeType.equals(md.getPropertyString("mock-mimetype")));
@@ -265,6 +268,7 @@
         md.setPropertyByteArray("mock-request", testRequest);
         String testDefaultUrl = "http://1.2.3.4:8080/blah";
         md.setPropertyString("mock-defaultUrl", testDefaultUrl);
+        md.setPropertyString("mock-keyRequestType", "1" /*kKeyRequestType_Initial*/);
 
         byte[] initData = {0x0a, 0x0b, 0x0c, 0x0d};
 
@@ -274,6 +278,7 @@
                                                       null);
         assertTrue(Arrays.equals(request.getData(), testRequest));
         assertTrue(request.getDefaultUrl().equals(testDefaultUrl));
+        assertEquals(request.getRequestType(), MediaDrm.KeyRequest.REQUEST_TYPE_INITIAL);
 
         assertTrue(Arrays.equals(initData, md.getPropertyByteArray("mock-initdata")));
         assertTrue(mimeType.equals(md.getPropertyString("mock-mimetype")));
@@ -295,6 +300,7 @@
         md.setPropertyByteArray("mock-request", testRequest);
         String testDefaultUrl = "http://1.2.3.4:8080/blah";
         md.setPropertyString("mock-defaultUrl", testDefaultUrl);
+        md.setPropertyString("mock-keyRequestType", "2" /*kKeyRequestType_Renewal*/);
 
         byte[] initData = {0x0a, 0x0b, 0x0c, 0x0d};
 
@@ -304,6 +310,7 @@
                                               null);
         assertTrue(Arrays.equals(request.getData(), testRequest));
         assertTrue(request.getDefaultUrl().equals(testDefaultUrl));
+        assertEquals(request.getRequestType(), MediaDrm.KeyRequest.REQUEST_TYPE_RENEWAL);
 
         assertTrue(Arrays.equals(initData, md.getPropertyByteArray("mock-initdata")));
         assertTrue(mimeType.equals(md.getPropertyString("mock-mimetype")));
@@ -325,6 +332,7 @@
         md.setPropertyByteArray("mock-request", testRequest);
         String testDefaultUrl = "http://1.2.3.4:8080/blah";
         md.setPropertyString("mock-defaultUrl", testDefaultUrl);
+        md.setPropertyString("mock-keyRequestType", "3" /*kKeyRequestType_Release*/);
 
         String mimeType = "video/iso.segment";
         KeyRequest request = md.getKeyRequest(sessionId, null, mimeType,
@@ -332,6 +340,7 @@
                                               null);
         assertTrue(Arrays.equals(request.getData(), testRequest));
         assertTrue(request.getDefaultUrl().equals(testDefaultUrl));
+        assertEquals(request.getRequestType(), MediaDrm.KeyRequest.REQUEST_TYPE_RELEASE);
 
         assertTrue(mimeType.equals(md.getPropertyString("mock-mimetype")));
         assertTrue(md.getPropertyString("mock-keytype").equals("2"));
@@ -780,6 +789,170 @@
         assertTrue(mGotEvent);
     }
 
+    public void testExpirationUpdate() throws Exception {
+        if (!isMockPluginInstalled()) {
+            return;
+        }
+
+
+        new Thread() {
+            @Override
+            public void run() {
+                // Set up a looper to be used by mMediaPlayer.
+                Looper.prepare();
+
+                // Save the looper so that we can terminate this thread
+                // after we are done with it.
+                mLooper = Looper.myLooper();
+
+                try {
+                    mMediaDrm = new MediaDrm(mockScheme);
+                } catch (MediaDrmException e) {
+                    e.printStackTrace();
+                    fail();
+                }
+
+
+                final byte[] expected_sessionId = openSession(mMediaDrm);
+
+                mMediaDrm.setPropertyByteArray("mock-event-session-id", expected_sessionId);
+
+                synchronized(mLock) {
+                    mLock.notify();
+
+                    mMediaDrm.setOnExpirationUpdateListener(new MediaDrm.OnExpirationUpdateListener() {
+                            @Override
+                            public void onExpirationUpdate(MediaDrm md, byte[] sessionId,
+                                    long expiryTimeMS) {
+                                synchronized(mLock) {
+                                    Log.d(TAG,"testExpirationUpdate.onExpirationUpdate");
+                                    assertTrue(md == mMediaDrm);
+                                    assertTrue(Arrays.equals(sessionId, expected_sessionId));
+                                    assertTrue(expiryTimeMS == 123456789012345L);
+                                    mGotEvent = true;
+                                    mLock.notify();
+                                }
+                            }
+                        }, null);
+                }
+                Looper.loop();  // Blocks forever until Looper.quit() is called.
+            }
+        }.start();
+
+        // wait for mMediaDrm to be created
+        synchronized(mLock) {
+            try {
+                mLock.wait(1000);
+            } catch (Exception e) {
+            }
+        }
+        assertTrue(mMediaDrm != null);
+
+        mGotEvent = false;
+        mMediaDrm.setPropertyString("mock-send-expiration-update", "123456789012345");
+
+        synchronized(mLock) {
+            try {
+                mLock.wait(1000);
+            } catch (Exception e) {
+            }
+        }
+
+        mLooper.quit();
+        assertTrue(mGotEvent);
+    }
+
+    public void testKeyStatusChange() throws Exception {
+        if (!isMockPluginInstalled()) {
+            return;
+        }
+
+
+        new Thread() {
+            @Override
+            public void run() {
+                // Set up a looper to be used by mMediaPlayer.
+                Looper.prepare();
+
+                // Save the looper so that we can terminate this thread
+                // after we are done with it.
+                mLooper = Looper.myLooper();
+
+                try {
+                    mMediaDrm = new MediaDrm(mockScheme);
+                } catch (MediaDrmException e) {
+                    e.printStackTrace();
+                    fail();
+                }
+
+
+                final byte[] expected_sessionId = openSession(mMediaDrm);
+
+                mMediaDrm.setPropertyByteArray("mock-event-session-id", expected_sessionId);
+
+                synchronized(mLock) {
+                    mLock.notify();
+
+                    mMediaDrm.setOnKeyStatusChangeListener(new MediaDrm.OnKeyStatusChangeListener() {
+                            @Override
+                            public void onKeyStatusChange(MediaDrm md, byte[] sessionId,
+                                    List<KeyStatus> keyInformation, boolean hasNewUsableKey) {
+                                synchronized(mLock) {
+                                    Log.d(TAG,"testKeyStatusChange.onKeyStatusChange");
+                                    assertTrue(md == mMediaDrm);
+                                    assertTrue(Arrays.equals(sessionId, expected_sessionId));
+                                    try {
+                                        KeyStatus keyStatus = keyInformation.get(0);
+                                        assertTrue(Arrays.equals(keyStatus.getKeyId(), "key1".getBytes()));
+                                        assertTrue(keyStatus.getStatusCode() == MediaDrm.KeyStatus.STATUS_USABLE);
+                                        keyStatus = keyInformation.get(1);
+                                        assertTrue(Arrays.equals(keyStatus.getKeyId(), "key2".getBytes()));
+                                        assertTrue(keyStatus.getStatusCode() == MediaDrm.KeyStatus.STATUS_EXPIRED);
+                                        keyStatus = keyInformation.get(2);
+                                        assertTrue(Arrays.equals(keyStatus.getKeyId(), "key3".getBytes()));
+                                        assertTrue(keyStatus.getStatusCode() == MediaDrm.KeyStatus.STATUS_OUTPUT_NOT_ALLOWED);
+                                        keyStatus = keyInformation.get(3);
+                                        assertTrue(Arrays.equals(keyStatus.getKeyId(), "key4".getBytes()));
+                                        assertTrue(keyStatus.getStatusCode() == MediaDrm.KeyStatus.STATUS_PENDING);
+                                        keyStatus = keyInformation.get(4);
+                                        assertTrue(Arrays.equals(keyStatus.getKeyId(), "key5".getBytes()));
+                                        assertTrue(keyStatus.getStatusCode() == MediaDrm.KeyStatus.STATUS_INTERNAL_ERROR);
+                                        assertTrue(hasNewUsableKey);
+                                        mGotEvent = true;
+                                    } catch (IndexOutOfBoundsException e) {
+                                    }
+                                    mLock.notify();
+                                }
+                            }
+                        }, null);
+                }
+                Looper.loop();  // Blocks forever until Looper.quit() is called.
+            }
+        }.start();
+
+        // wait for mMediaDrm to be created
+        synchronized(mLock) {
+            try {
+                mLock.wait(1000);
+            } catch (Exception e) {
+            }
+        }
+        assertTrue(mMediaDrm != null);
+
+        mGotEvent = false;
+        mMediaDrm.setPropertyString("mock-send-keys-change", "123456789012345");
+
+        synchronized(mLock) {
+            try {
+                mLock.wait(1000);
+            } catch (Exception e) {
+            }
+        }
+
+        mLooper.quit();
+        assertTrue(mGotEvent);
+    }
+
     private byte[] openSession(MediaDrm md) {
         byte[] sessionId = null;
         try {
diff --git a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
new file mode 100644
index 0000000..9db54ff
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
@@ -0,0 +1,111 @@
+/*
+ * 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.media.cts;
+
+import com.android.cts.media.R;
+
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.media.MediaDataSource;
+import android.media.MediaExtractor;
+import android.test.AndroidTestCase;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class MediaExtractorTest extends AndroidTestCase {
+    protected Resources mResources;
+    protected MediaExtractor mExtractor;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mResources = getContext().getResources();
+        mExtractor = new MediaExtractor();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mExtractor.release();
+    }
+
+    protected TestMediaDataSource getDataSourceFor(int resid) throws Exception {
+        AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+        return TestMediaDataSource.fromAssetFd(afd);
+    }
+
+    protected TestMediaDataSource setDataSource(int resid) throws Exception {
+        TestMediaDataSource ds = getDataSourceFor(resid);
+        mExtractor.setDataSource(ds);
+        return ds;
+    }
+
+    public void testNullMediaDataSourceIsRejected() throws Exception {
+        try {
+            mExtractor.setDataSource((MediaDataSource)null);
+            fail("Expected IllegalArgumentException.");
+        } catch (IllegalArgumentException ex) {
+            // Expected, test passed.
+        }
+    }
+
+    public void testMediaDataSourceIsClosedOnRelease() throws Exception {
+        TestMediaDataSource dataSource = setDataSource(R.raw.testvideo);
+        mExtractor.release();
+        assertTrue(dataSource.isClosed());
+    }
+
+    public void testExtractorFailsIfMediaDataSourceThrows() throws Exception {
+        TestMediaDataSource dataSource = getDataSourceFor(R.raw.testvideo);
+        dataSource.throwFromReadAt();
+        try {
+            mExtractor.setDataSource(dataSource);
+            fail("Expected IOException.");
+        } catch (IOException e) {
+            // Expected.
+        }
+    }
+
+    public void testExtractorFailsIfMediaDataSourceReturnsAnError() throws Exception {
+        TestMediaDataSource dataSource = getDataSourceFor(R.raw.testvideo);
+        dataSource.returnFromReadAt(-2);
+        try {
+            mExtractor.setDataSource(dataSource);
+            fail("Expected IOException.");
+        } catch (IOException e) {
+            // Expected.
+        }
+    }
+
+    // Smoke test MediaExtractor reading from a DataSource.
+    public void testExtractFromAMediaDataSource() throws Exception {
+        TestMediaDataSource dataSource = setDataSource(R.raw.testvideo);
+        // 1MB is enough for any sample.
+        final ByteBuffer buf = ByteBuffer.allocate(1024*1024);
+        final int trackCount = mExtractor.getTrackCount();
+
+        for (int i = 0; i < trackCount; i++) {
+            mExtractor.selectTrack(i);
+        }
+
+        for (int i = 0; i < trackCount; i++) {
+            assertTrue(mExtractor.readSampleData(buf, 0) > 0);
+            assertTrue(mExtractor.advance());
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
index 30c8370..54e6ef1 100644
--- a/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMetadataRetrieverTest.java
@@ -20,102 +20,181 @@
 
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
+import android.cts.util.MediaUtils;
+import android.media.MediaDataSource;
 import android.media.MediaMetadataRetriever;
 import android.test.AndroidTestCase;
 
+import java.io.IOException;
+
 public class MediaMetadataRetrieverTest extends AndroidTestCase {
+    protected Resources mResources;
+    protected MediaMetadataRetriever mRetriever;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        mResources = getContext().getResources();
+        mRetriever = new MediaMetadataRetriever();
     }
 
     @Override
     protected void tearDown() throws Exception {
         super.tearDown();
+        mRetriever.release();
     }
 
-    public void test3gppMetadata() {
-        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
-
+    protected void setDataSourceFd(int resid) {
         try {
-            Resources resources = getContext().getResources();
-            AssetFileDescriptor afd = resources.openRawResourceFd(R.raw.testvideo);
-
-            retriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
-
+            AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+            mRetriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
             afd.close();
         } catch (Exception e) {
             fail("Unable to open file");
         }
+    }
+
+    protected TestMediaDataSource setDataSourceCallback(int resid) {
+        TestMediaDataSource ds = null;
+        try {
+            AssetFileDescriptor afd = mResources.openRawResourceFd(resid);
+            ds = TestMediaDataSource.fromAssetFd(afd);
+            mRetriever.setDataSource(ds);
+        } catch (Exception e) {
+            fail("Unable to open file");
+        }
+        return ds;
+    }
+
+    public void test3gppMetadata() {
+        setDataSourceCallback(R.raw.testvideo);
 
         assertEquals("Title was other than expected",
-                "Title", retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
+                "Title", mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
 
         assertEquals("Artist was other than expected",
                 "UTF16LE エンディアン ",
-                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
 
         assertEquals("Album was other than expected",
                 "Test album",
-                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
 
         assertEquals("Track number was other than expected",
                 "10",
-                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER));
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER));
 
         assertEquals("Year was other than expected",
-                "2013", retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR));
+                "2013", mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR));
 
         assertNull("Writer was unexpected present",
-                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
     }
 
-    public void testSetDataSourceNull() {
-        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+    public void testID3v2Metadata() {
+        setDataSourceFd(R.raw.video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2);
 
+        assertEquals("Title was other than expected",
+                "Title", mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
+
+        assertEquals("Artist was other than expected",
+                "UTF16LE エンディアン ",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
+
+        assertEquals("Album was other than expected",
+                "Test album",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
+
+        assertEquals("Track number was other than expected",
+                "10",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER));
+
+        assertEquals("Year was other than expected",
+                "2013", mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR));
+
+        assertNull("Writer was unexpectedly present",
+                mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
+    }
+
+    public void testSetDataSourceNullPath() {
         try {
-            retriever.setDataSource((String)null);
+            mRetriever.setDataSource((String)null);
             fail("Expected IllegalArgumentException.");
         } catch (IllegalArgumentException ex) {
             // Expected, test passed.
         }
     }
 
-    public void testID3v2Metadata() {
+    public void testNullMediaDataSourceIsRejected() {
+        try {
+            mRetriever.setDataSource((MediaDataSource)null);
+            fail("Expected IllegalArgumentException.");
+        } catch (IllegalArgumentException ex) {
+            // Expected, test passed.
+        }
+    }
+
+    public void testMediaDataSourceIsClosedOnRelease() throws Exception {
+        TestMediaDataSource dataSource = setDataSourceCallback(R.raw.testvideo);
+        mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
+        mRetriever.release();
+        assertTrue(dataSource.isClosed());
+    }
+
+    public void testRetrieveFailsIfMediaDataSourceThrows() throws Exception {
+        TestMediaDataSource dataSource = setDataSourceCallback(R.raw.testvideo);
+        dataSource.throwFromReadAt();
+        assertTrue(mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) == null);
+    }
+
+    public void testRetrieveFailsIfMediaDataSourceReturnsAnError() throws Exception {
+        TestMediaDataSource dataSource = setDataSourceCallback(R.raw.testvideo);
+        dataSource.returnFromReadAt(-2);
+        assertTrue(mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) == null);
+    }
+
+    private void testThumbnail(int resId) {
+        if (!MediaUtils.hasCodecForResourceAndDomain(getContext(), resId, "video/")) {
+            MediaUtils.skipTest("no video codecs for resource");
+            return;
+        }
+
         MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+        Resources resources = getContext().getResources();
+        AssetFileDescriptor afd = resources.openRawResourceFd(resId);
+
+        retriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
 
         try {
-            Resources resources = getContext().getResources();
-            AssetFileDescriptor afd = resources.openRawResourceFd(
-                    R.raw.video_480x360_mp4_h264_500kbps_25fps_aac_stereo_128kbps_44100hz_id3v2);
-
-            retriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
-
             afd.close();
-        } catch (Exception e) {
+        } catch (IOException e) {
             fail("Unable to open file");
         }
 
-        assertEquals("Title was other than expected",
-                "Title", retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
+        assertNotNull(retriever.getFrameAtTime(-1 /* timeUs (any) */));
+    }
 
-        assertEquals("Artist was other than expected",
-                "UTF16LE エンディアン ",
-                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST));
+    public void testThumbnailH264() {
+        testThumbnail(R.raw.video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz);
+    }
 
-        assertEquals("Album was other than expected",
-                "Test album",
-                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM));
+    public void testThumbnailH263() {
+        testThumbnail(R.raw.video_176x144_3gp_h263_56kbps_12fps_aac_mono_24kbps_11025hz);
+    }
 
-        assertEquals("Track number was other than expected",
-                "10",
-                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER));
+    public void testThumbnailMPEG4() {
+        testThumbnail(R.raw.video_1280x720_mp4_mpeg4_1000kbps_25fps_aac_stereo_128kbps_44100hz);
+    }
 
-        assertEquals("Year was other than expected",
-                "2013", retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR));
+    public void testThumbnailVP8() {
+        testThumbnail(R.raw.video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_48000hz);
+    }
 
-        assertNull("Writer was unexpectedly present",
-                retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_WRITER));
+    public void testThumbnailVP9() {
+        testThumbnail(R.raw.video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_44100hz);
+    }
+
+    public void testThumbnailHEVC() {
+        testThumbnail(R.raw.video_1280x720_mp4_hevc_1150kbps_30fps_aac_stereo_128kbps_48000hz);
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
index 67eeca0..0f664a5 100644
--- a/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaMuxerTest.java
@@ -104,6 +104,8 @@
             fail("should throw IllegalStateException.");
         } catch (IllegalStateException e) {
             // expected
+        } finally {
+            muxer.release();
         }
 
         // Throws exception b/c 2 video tracks were added.
@@ -115,6 +117,8 @@
             fail("should throw IllegalStateException.");
         } catch (IllegalStateException e) {
             // expected
+        } finally {
+            muxer.release();
         }
 
         // Throws exception b/c 2 audio tracks were added.
@@ -125,6 +129,8 @@
             fail("should throw IllegalStateException.");
         } catch (IllegalStateException e) {
             // expected
+        } finally {
+            muxer.release();
         }
 
         // Throws exception b/c 3 tracks were added.
@@ -137,6 +143,8 @@
             fail("should throw IllegalStateException.");
         } catch (IllegalStateException e) {
             // expected
+        } finally {
+            muxer.release();
         }
 
         // Throws exception b/c no tracks was added.
@@ -146,6 +154,8 @@
             fail("should throw IllegalStateException.");
         } catch (IllegalStateException e) {
             // expected
+        } finally {
+            muxer.release();
         }
 
         // Throws exception b/c a wrong format.
@@ -155,6 +165,8 @@
             fail("should throw IllegalStateException.");
         } catch (IllegalStateException e) {
             // expected
+        } finally {
+            muxer.release();
         }
         new File(outputFile).delete();
     }
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
index 32fbfb5..640083f 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerFlakyNetworkTest.java
@@ -23,6 +23,8 @@
 import android.os.SystemClock;
 import android.webkit.cts.CtsTestServer;
 
+import com.android.cts.util.TimeoutReq;
+
 import org.apache.http.HttpServerConnection;
 
 import org.apache.http.impl.DefaultHttpServerConnection;
@@ -67,30 +69,37 @@
         super.tearDown();
     }
 
+    @TimeoutReq(minutes = 5)
     public void test_S0P0() throws Throwable {
         doPlayStreams(0, 0);
     }
 
+    @TimeoutReq(minutes = 10)
     public void test_S1P000005() throws Throwable {
         doPlayStreams(1, 0.000005f);
     }
 
+    @TimeoutReq(minutes = 10)
     public void test_S2P00001() throws Throwable {
         doPlayStreams(2, 0.00001f);
     }
 
+    @TimeoutReq(minutes = 10)
     public void test_S3P00001() throws Throwable {
         doPlayStreams(3, 0.00001f);
     }
 
+    @TimeoutReq(minutes = 10)
     public void test_S4P00001() throws Throwable {
         doPlayStreams(4, 0.00001f);
     }
 
+    @TimeoutReq(minutes = 10)
     public void test_S5P00001() throws Throwable {
         doPlayStreams(5, 0.00001f);
     }
 
+    @TimeoutReq(minutes = 10)
     public void test_S6P00002() throws Throwable {
         doPlayStreams(6, 0.00002f);
     }
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
index 2a696e0..75a5a13 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTest.java
@@ -21,14 +21,19 @@
 import android.content.pm.PackageManager;
 import android.content.res.AssetFileDescriptor;
 import android.cts.util.MediaUtils;
+import android.hardware.Camera;
 import android.media.AudioManager;
 import android.media.MediaCodec;
+import android.media.MediaDataSource;
 import android.media.MediaExtractor;
 import android.media.MediaFormat;
+import android.media.MediaMetadataRetriever;
 import android.media.MediaPlayer;
 import android.media.MediaPlayer.OnErrorListener;
 import android.media.MediaRecorder;
-import android.media.MediaMetadataRetriever;
+import android.media.MediaTimestamp;
+import android.media.PlaybackParams;
+import android.media.SyncParams;
 import android.media.TimedText;
 import android.media.audiofx.AudioEffect;
 import android.media.audiofx.Visualizer;
@@ -45,6 +50,7 @@
 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;
@@ -67,6 +73,8 @@
     private static final int  RECORDED_VIDEO_WIDTH  = 176;
     private static final int  RECORDED_VIDEO_HEIGHT = 144;
     private static final long RECORDED_DURATION_MS  = 3000;
+    private static final float FLOAT_TOLERANCE = .0001f;
+
     private Vector<Integer> mTimedTextTrackIndex = new Vector<Integer>();
     private int mSelectedTimedTextIndex;
     private Monitor mOnTimedTextCalled = new Monitor();
@@ -89,6 +97,10 @@
         }
     }
 
+    public void testonInputBufferFilledSigsegv() throws Exception {
+        testIfMediaServerDied(R.raw.on_input_buffer_filled_sigsegv);
+    }
+
     public void testFlacHeapOverflow() throws Exception {
         testIfMediaServerDied(R.raw.heap_oob_flac);
     }
@@ -115,12 +127,17 @@
         AssetFileDescriptor afd = mResources.openRawResourceFd(res);
         mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
         afd.close();
-        mMediaPlayer.prepare();
-        mMediaPlayer.start();
-        if (!mOnCompletionCalled.waitForSignal(5000)) {
-            Log.w(LOG_TAG, "testIfMediaServerDied: Timed out waiting for Error/Completion");
+        try {
+            mMediaPlayer.prepare();
+            mMediaPlayer.start();
+            if (!mOnCompletionCalled.waitForSignal(5000)) {
+                Log.w(LOG_TAG, "testIfMediaServerDied: Timed out waiting for Error/Completion");
+            }
+        } catch (Exception e) {
+            Log.w(LOG_TAG, "playback failed", e);
+        } finally {
+            mMediaPlayer.release();
         }
-        mMediaPlayer.release();
     }
 
     // Bug 13652927
@@ -151,10 +168,10 @@
         }
     }
 
-    public void testPlayNullSource() throws Exception {
+    public void testPlayNullSourcePath() throws Exception {
         try {
             mMediaPlayer.setDataSource((String) null);
-            fail("Null URI was accepted");
+            fail("Null path was accepted");
         } catch (RuntimeException e) {
             // expected
         }
@@ -382,10 +399,6 @@
     }
 
     public void testPlayAudioTwice() throws Exception {
-        if (!hasAudioOutput()) {
-            Log.i(LOG_TAG, "SKIPPING testPlayAudioTwice(). No audio output.");
-            return;
-        }
 
         final int resid = R.raw.camera_click;
 
@@ -633,10 +646,6 @@
     }
 
     private void testGapless(int resid1, int resid2) throws Exception {
-        if (!hasAudioOutput()) {
-            Log.i(LOG_TAG, "SKIPPING testPlayAudioTwice(). No audio output.");
-            return;
-        }
 
         MediaPlayer mp1 = new MediaPlayer();
         mp1.setAudioStreamType(AudioManager.STREAM_MUSIC);
@@ -736,7 +745,7 @@
     public void testVideoSurfaceResetting() throws Exception {
         final int tolerance = 150;
         final int audioLatencyTolerance = 1000;  /* covers audio path latency variability */
-        final int seekPos = 5000;
+        final int seekPos = 4760;  // This is the I-frame position
 
         final CountDownLatch seekDone = new CountDownLatch(1);
 
@@ -758,7 +767,12 @@
         mMediaPlayer.setDisplay(getActivity().getSurfaceHolder2());
         int posAfter = mMediaPlayer.getCurrentPosition();
 
-        assertEquals(posAfter, posBefore, tolerance);
+        /* temporarily disable timestamp checking because MediaPlayer now seeks to I-frame
+         * position, instead of requested position. setDisplay invovles a seek operation
+         * internally.
+         */
+        // TODO: uncomment out line below when MediaPlayer can seek to requested position.
+        // assertEquals(posAfter, posBefore, tolerance);
         assertTrue(mMediaPlayer.isPlaying());
 
         Thread.sleep(SLEEP_TIME);
@@ -772,7 +786,8 @@
         posBefore = mMediaPlayer.getCurrentPosition();
         mMediaPlayer.setDisplay(null);
         posAfter = mMediaPlayer.getCurrentPosition();
-        assertEquals(posAfter, posBefore, tolerance);
+        // TODO: uncomment out line below when MediaPlayer can seek to requested position.
+        // assertEquals(posAfter, posBefore, tolerance);
         assertTrue(mMediaPlayer.isPlaying());
 
         Thread.sleep(SLEEP_TIME);
@@ -781,7 +796,8 @@
         mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
         posAfter = mMediaPlayer.getCurrentPosition();
 
-        assertEquals(posAfter, posBefore, tolerance);
+        // TODO: uncomment out line below when MediaPlayer can seek to requested position.
+        // assertEquals(posAfter, posBefore, tolerance);
         assertTrue(mMediaPlayer.isPlaying());
 
         Thread.sleep(SLEEP_TIME);
@@ -807,15 +823,34 @@
         return getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
     }
 
+    private Camera mCamera;
     private void testRecordedVideoPlaybackWithAngle(int angle) throws Exception {
-        final int width = RECORDED_VIDEO_WIDTH;
-        final int height = RECORDED_VIDEO_HEIGHT;
+        int width = RECORDED_VIDEO_WIDTH;
+        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> previewSizes = parameters.getSupportedPreviewSizes();
+        for (Camera.Size size : previewSizes)
+        {
+            if (size.width == width && size.height == height) {
+                isSupported = true;
+                break;
+            }
+        }
+        mCamera.release();
+        mCamera = null;
+        if (!isSupported) {
+            width = previewSizes.get(0).width;
+            height = previewSizes.get(0).height;
+        }
         checkOrientation(angle);
         recordVideo(width, height, angle, file, durationMs);
         checkDisplayedVideoSize(width, height, angle, file);
@@ -872,6 +907,92 @@
         assertEquals(Integer.parseInt(rotation), angle);
     }
 
+    public void testPlaybackRate() throws Exception {
+        final int toleranceMs = 1000;
+        if (!checkLoadResource(
+                R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz)) {
+            return; // skip
+        }
+
+        mMediaPlayer.setDisplay(mActivity.getSurfaceHolder());
+        mMediaPlayer.prepare();
+        SyncParams sync = new SyncParams().allowDefaults();
+        mMediaPlayer.setSyncParams(sync);
+        sync = mMediaPlayer.getSyncParams();
+
+        float[] rates = { 0.25f, 0.5f, 1.0f, 2.0f };
+        for (float playbackRate : rates) {
+            mMediaPlayer.seekTo(0);
+            Thread.sleep(1000);
+            int playTime = 4000;  // The testing clip is about 10 second long.
+            mMediaPlayer.setPlaybackParams(new PlaybackParams().setSpeed(playbackRate));
+            mMediaPlayer.start();
+            Thread.sleep(playTime);
+            PlaybackParams pbp = mMediaPlayer.getPlaybackParams();
+            assertEquals(
+                    playbackRate, pbp.getSpeed(),
+                    FLOAT_TOLERANCE + playbackRate * sync.getTolerance());
+            assertTrue("MediaPlayer should still be playing", mMediaPlayer.isPlaying());
+
+            int playedMediaDurationMs = mMediaPlayer.getCurrentPosition();
+            int diff = Math.abs((int)(playedMediaDurationMs / playbackRate) - playTime);
+            if (diff > toleranceMs) {
+                fail("Media player had error in playback rate " + playbackRate
+                     + ", play time is " + playTime + " vs expected " + playedMediaDurationMs);
+            }
+            mMediaPlayer.pause();
+            pbp = mMediaPlayer.getPlaybackParams();
+            assertEquals(0.f, pbp.getSpeed(), FLOAT_TOLERANCE);
+        }
+        mMediaPlayer.stop();
+    }
+
+    public void testGetTimestamp() throws Exception {
+        final int toleranceUs = 100000;
+        final float playbackRate = 1.0f;
+        if (!checkLoadResource(
+                R.raw.video_480x360_mp4_h264_1000kbps_30fps_aac_stereo_128kbps_44100hz)) {
+            return; // skip
+        }
+
+        mMediaPlayer.setDisplay(mActivity.getSurfaceHolder());
+        mMediaPlayer.prepare();
+        mMediaPlayer.start();
+        mMediaPlayer.setPlaybackParams(new PlaybackParams().setSpeed(playbackRate));
+        Thread.sleep(SLEEP_TIME);  // let player get into stable state.
+        long nt1 = System.nanoTime();
+        MediaTimestamp ts1 = mMediaPlayer.getTimestamp();
+        long nt2 = System.nanoTime();
+        assertTrue("Media player should return a valid time stamp", ts1 != null);
+        assertEquals("MediaPlayer had error in clockRate " + ts1.getMediaClockRate(),
+                playbackRate, ts1.getMediaClockRate(), 0.001f);
+        assertTrue("The nanoTime of Media timestamp should be taken when getTimestamp is called.",
+                nt1 <= ts1.getAnchorSytemNanoTime() && ts1.getAnchorSytemNanoTime() <= nt2);
+
+        mMediaPlayer.pause();
+        ts1 = mMediaPlayer.getTimestamp();
+        assertTrue("Media player should return a valid time stamp", ts1 != null);
+        assertTrue("Media player should have play rate of 0.0f when paused",
+                ts1.getMediaClockRate() == 0.0f);
+
+        mMediaPlayer.seekTo(0);
+        mMediaPlayer.start();
+        Thread.sleep(SLEEP_TIME);  // let player get into stable state.
+        int playTime = 4000;  // The testing clip is about 10 second long.
+        ts1 = mMediaPlayer.getTimestamp();
+        assertTrue("Media player should return a valid time stamp", ts1 != null);
+        Thread.sleep(playTime);
+        MediaTimestamp ts2 = mMediaPlayer.getTimestamp();
+        assertTrue("Media player should return a valid time stamp", ts2 != null);
+        assertTrue("The clockRate should not be changed.",
+                ts1.getMediaClockRate() == ts2.getMediaClockRate());
+        assertEquals("MediaPlayer had error in timestamp.",
+                ts1.getAnchorMediaTimeUs() + (long)(playTime * ts1.getMediaClockRate() * 1000),
+                ts2.getAnchorMediaTimeUs(), toleranceUs);
+
+        mMediaPlayer.stop();
+    }
+
     public void testLocalVideo_MP4_H264_480x360_500kbps_25fps_AAC_Stereo_128kbps_44110Hz()
             throws Exception {
         playVideoTest(
@@ -1072,13 +1193,22 @@
         if (trackInfos == null || trackInfos.length == 0) {
             return;
         }
+
+        Vector<Integer> externalTrackIndex = new Vector<>();
         for (int i = 0; i < trackInfos.length; ++i) {
             assertTrue(trackInfos[i] != null);
-            if (trackInfos[i].getTrackType() ==
-                 MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
-                mTimedTextTrackIndex.add(i);
+            if (trackInfos[i].getTrackType() == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
+                MediaFormat format = trackInfos[i].getFormat();
+                String mime = format.getString(MediaFormat.KEY_MIME);
+                if (MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP.equals(mime)) {
+                    externalTrackIndex.add(i);
+                } else {
+                    mTimedTextTrackIndex.add(i);
+                }
             }
         }
+
+        mTimedTextTrackIndex.addAll(externalTrackIndex);
     }
 
     private int getTimedTextTrackCount() {
@@ -1344,6 +1474,42 @@
         return 1;
     }
 
+    public void testPositionAtEnd() throws Throwable {
+        testPositionAtEnd(R.raw.test1m1shighstereo);
+        testPositionAtEnd(R.raw.loudsoftmp3);
+        testPositionAtEnd(R.raw.loudsoftmp3);
+        testPositionAtEnd(R.raw.loudsoftwav);
+        testPositionAtEnd(R.raw.loudsoftogg);
+        testPositionAtEnd(R.raw.loudsoftitunes);
+        testPositionAtEnd(R.raw.loudsoftfaac);
+        testPositionAtEnd(R.raw.loudsoftaac);
+    }
+
+    private void testPositionAtEnd(int res) throws Throwable {
+
+        loadResource(res);
+        mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+        mMediaPlayer.prepare();
+        int duration = mMediaPlayer.getDuration();
+        assertTrue("resource too short", duration > 6000);
+        mOnCompletionCalled.reset();
+        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+            @Override
+            public void onCompletion(MediaPlayer mp) {
+                mOnCompletionCalled.signal();
+            }
+        });
+        mMediaPlayer.seekTo(duration - 5000);
+        mMediaPlayer.start();
+        while (mMediaPlayer.isPlaying()) {
+            Log.i("@@@@", "position: " + mMediaPlayer.getCurrentPosition());
+            Thread.sleep(500);
+        }
+        Log.i("@@@@", "final position: " + mMediaPlayer.getCurrentPosition());
+        assertTrue(mMediaPlayer.getCurrentPosition() > duration - 1000);
+        mMediaPlayer.reset();
+    }
+
     public void testCallback() throws Throwable {
         final int mp4Duration = 8484;
 
@@ -1504,4 +1670,94 @@
         return getActivity().getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_MICROPHONE);
     }
+
+    // Smoke test playback from a MediaDataSource.
+    public void testPlaybackFromAMediaDataSource() throws Exception {
+        final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
+        final int duration = 10000;
+
+        if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
+            return;
+        }
+
+        TestMediaDataSource dataSource =
+                TestMediaDataSource.fromAssetFd(mResources.openRawResourceFd(resid));
+        // Test returning -1 from getSize() to indicate unknown size.
+        dataSource.returnFromGetSize(-1);
+        mMediaPlayer.setDataSource(dataSource);
+        playLoadedVideo(null, null, -1);
+        assertTrue(mMediaPlayer.isPlaying());
+
+        // Test pause and restart.
+        mMediaPlayer.pause();
+        Thread.sleep(SLEEP_TIME);
+        assertFalse(mMediaPlayer.isPlaying());
+        mMediaPlayer.start();
+        assertTrue(mMediaPlayer.isPlaying());
+
+        // Test reset.
+        mMediaPlayer.stop();
+        mMediaPlayer.reset();
+        mMediaPlayer.setDataSource(dataSource);
+        mMediaPlayer.prepare();
+        mMediaPlayer.start();
+        assertTrue(mMediaPlayer.isPlaying());
+
+        // Test seek. Note: the seek position is cached and returned as the
+        // current position so there's no point in comparing them.
+        mMediaPlayer.seekTo(duration - SLEEP_TIME);
+        while (mMediaPlayer.isPlaying()) {
+            Thread.sleep(SLEEP_TIME);
+        }
+    }
+
+    public void testNullMediaDataSourceIsRejected() throws Exception {
+        try {
+            mMediaPlayer.setDataSource((MediaDataSource) null);
+            fail("Null MediaDataSource was accepted");
+        } catch (IllegalArgumentException e) {
+            // expected
+        }
+    }
+
+    public void testMediaDataSourceIsClosedOnReset() throws Exception {
+        TestMediaDataSource dataSource = new TestMediaDataSource(new byte[0]);
+        mMediaPlayer.setDataSource(dataSource);
+        mMediaPlayer.reset();
+        assertTrue(dataSource.isClosed());
+    }
+
+    public void testPlaybackFailsIfMediaDataSourceThrows() throws Exception {
+        final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
+        if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
+            return;
+        }
+
+        setOnErrorListener();
+        TestMediaDataSource dataSource =
+                TestMediaDataSource.fromAssetFd(mResources.openRawResourceFd(resid));
+        mMediaPlayer.setDataSource(dataSource);
+        mMediaPlayer.prepare();
+
+        dataSource.throwFromReadAt();
+        mMediaPlayer.start();
+        assertTrue(mOnErrorCalled.waitForSignal());
+    }
+
+    public void testPlaybackFailsIfMediaDataSourceReturnsAnError() throws Exception {
+        final int resid = R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
+        if (!MediaUtils.hasCodecsForResource(mContext, resid)) {
+            return;
+        }
+
+        setOnErrorListener();
+        TestMediaDataSource dataSource =
+                TestMediaDataSource.fromAssetFd(mResources.openRawResourceFd(resid));
+        mMediaPlayer.setDataSource(dataSource);
+        mMediaPlayer.prepare();
+
+        dataSource.returnFromReadAt(-2);
+        mMediaPlayer.start();
+        assertTrue(mOnErrorCalled.waitForSignal());
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
index d089658e..95cb43c 100644
--- a/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
+++ b/tests/tests/media/src/android/media/cts/MediaPlayerTestBase.java
@@ -294,11 +294,6 @@
 
     private static class PrepareFailedException extends Exception {}
 
-    public boolean hasAudioOutput() {
-        return getInstrumentation().getTargetContext().getPackageManager()
-            .hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
-    }
-
     public boolean isTv() {
         PackageManager pm = getInstrumentation().getTargetContext().getPackageManager();
         return pm.hasSystemFeature(pm.FEATURE_TELEVISION)
@@ -308,4 +303,14 @@
     public boolean checkTv() {
         return MediaUtils.check(isTv(), "not a TV");
     }
+
+    protected void setOnErrorListener() {
+        mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
+            @Override
+            public boolean onError(MediaPlayer mp, int what, int extra) {
+                mOnErrorCalled.signal();
+                return false;
+            }
+        });
+    }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaRandomTest.java b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
index 7b49a37..e928a8f 100644
--- a/tests/tests/media/src/android/media/cts/MediaRandomTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRandomTest.java
@@ -282,6 +282,11 @@
 
             final int[] width  = {176, 352, 320, 640, 1280, 1920};
             final int[] height = {144, 288, 240, 480,  720, 1080};
+            final int[] audioSource = {
+                    MediaRecorder.AudioSource.DEFAULT,
+                    MediaRecorder.AudioSource.MIC,
+                    MediaRecorder.AudioSource.CAMCORDER,
+            };
 
             watchdog.start();
             for (int i = 0; i < NUMBER_OF_RECORDER_RANDOM_ACTIONS; i++) {
@@ -292,9 +297,14 @@
                 mParam = (int)(r.nextInt(1000000));
                 try {
                     switch (mAction) {
-                    case 0:
-                        mRecorder.setAudioSource(mParam % 3);
+                    case 0: {
+                        // We restrict the audio sources because setting some sources
+                        // may cause 2+ second delays because the input device may
+                        // retry - loop (e.g. VOICE_UPLINK for voice call to be initiated).
+                        final int index = mParam % audioSource.length;
+                        mRecorder.setAudioSource(audioSource[index]);
                         break;
+                    }
                     case 1:
                         // XXX:
                         // Fix gralloc source and change
diff --git a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
index 6cdbbac..4c90e56 100644
--- a/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaRecorderTest.java
@@ -18,11 +18,17 @@
 
 import android.content.pm.PackageManager;
 import android.cts.util.MediaUtils;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
 import android.hardware.Camera;
-import android.media.MediaFormat;
 import android.media.CamcorderProfile;
+import android.media.EncoderCapabilities;
+import android.media.MediaCodec;
+import android.media.MediaFormat;
 import android.media.MediaMetadataRetriever;
 import android.media.MediaRecorder;
+import android.media.EncoderCapabilities.VideoEncoderCap;
 import android.media.MediaRecorder.OnErrorListener;
 import android.media.MediaRecorder.OnInfoListener;
 import android.media.MediaMetadataRetriever;
@@ -39,6 +45,7 @@
 import java.io.FileOutputStream;
 import java.lang.InterruptedException;
 import java.lang.Runnable;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -53,6 +60,8 @@
     private static final int RECORDED_DUR_TOLERANCE_MS = 1000;
     private static final int VIDEO_WIDTH = 176;
     private static final int VIDEO_HEIGHT = 144;
+    private static int mVideoWidth = VIDEO_WIDTH;
+    private static int mVideoHeight = VIDEO_HEIGHT;
     private static final int VIDEO_BIT_RATE_IN_BPS = 128000;
     private static final double VIDEO_TIMELAPSE_CAPTURE_RATE_FPS = 1.0;
     private static final int AUDIO_BIT_RATE_IN_BPS = 12200;
@@ -63,6 +72,12 @@
     private static final int MAX_DURATION_MSEC = 2000;
     private static final float LATITUDE = 0.0000f;
     private static final float LONGITUDE  = -180.0f;
+    private static final int NORMAL_FPS = 30;
+    private static final int TIME_LAPSE_FPS = 5;
+    private static final int SLOW_MOTION_FPS = 120;
+    private static final List<VideoEncoderCap> mVideoEncoders =
+            EncoderCapabilities.getVideoEncoders();
+
     private boolean mOnInfoCalled;
     private boolean mOnErrorCalled;
     private File mOutFile;
@@ -139,8 +154,10 @@
 
     @Override
     protected void tearDown() throws Exception {
-        mMediaRecorder.release();
-        mMediaRecorder = null;
+        if (mMediaRecorder != null) {
+            mMediaRecorder.release();
+            mMediaRecorder = null;
+        }
         if (mOutFile != null && mOutFile.exists()) {
             mOutFile.delete();
         }
@@ -204,6 +221,7 @@
         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);
             mCamera.release();
             mCamera = null;
@@ -211,6 +229,21 @@
         }
     }
 
+    private void setSupportedResolution(Camera camera) {
+        Camera.Parameters parameters = camera.getParameters();
+        List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
+        for (Camera.Size size : previewSizes)
+        {
+            if (size.width == VIDEO_WIDTH && size.height == VIDEO_HEIGHT) {
+                mVideoWidth = VIDEO_WIDTH;
+                mVideoHeight = VIDEO_HEIGHT;
+                return;
+            }
+        }
+        mVideoWidth = previewSizes.get(0).width;
+        mVideoHeight = previewSizes.get(0).height;
+    }
+
     private void recordVideoUsingCamera(
             Camera camera, String fileName, int durMs, boolean timelapse) throws Exception {
         // FIXME:
@@ -227,7 +260,7 @@
         mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
         mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
         mMediaRecorder.setVideoFrameRate(frameRate);
-        mMediaRecorder.setVideoSize(VIDEO_WIDTH, VIDEO_HEIGHT);
+        mMediaRecorder.setVideoSize(mVideoWidth, mVideoHeight);
         mMediaRecorder.setPreviewDisplay(mActivity.getSurfaceHolder().getSurface());
         mMediaRecorder.setOutputFile(fileName);
         mMediaRecorder.setLocation(LATITUDE, LONGITUDE);
@@ -492,6 +525,447 @@
         assertFalse(mOnErrorCalled);
     }
 
+    private void setupRecorder(String filename, boolean useSurface, boolean hasAudio)
+            throws Exception {
+        int codec = MediaRecorder.VideoEncoder.H264;
+        int frameRate = getMaxFrameRateForCodec(codec);
+        if (mMediaRecorder == null) {
+            mMediaRecorder = new MediaRecorder();
+        }
+
+        if (!useSurface) {
+            mCamera = Camera.open(0);
+            Camera.Parameters params = mCamera.getParameters();
+            frameRate = params.getPreviewFrameRate();
+            mCamera.unlock();
+            mMediaRecorder.setCamera(mCamera);
+            mMediaRecorder.setPreviewDisplay(mActivity.getSurfaceHolder().getSurface());
+        }
+
+        mMediaRecorder.setVideoSource(useSurface ?
+                MediaRecorder.VideoSource.SURFACE : MediaRecorder.VideoSource.CAMERA);
+
+        if (hasAudio) {
+            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+        }
+
+        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+        mMediaRecorder.setOutputFile(filename);
+
+        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
+        mMediaRecorder.setVideoFrameRate(frameRate);
+        mMediaRecorder.setVideoSize(VIDEO_WIDTH, VIDEO_HEIGHT);
+
+        if (hasAudio) {
+            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+        }
+    }
+
+    private Surface tryGetSurface(boolean shouldThrow) throws Exception {
+        Surface surface = null;
+        try {
+            surface = mMediaRecorder.getSurface();
+            assertFalse("failed to throw IllegalStateException", shouldThrow);
+        } catch (IllegalStateException e) {
+            assertTrue("threw unexpected exception: " + e, shouldThrow);
+        }
+        return surface;
+    }
+
+    private boolean validateGetSurface(boolean useSurface) {
+        Log.v(TAG,"validateGetSurface, useSurface=" + useSurface);
+        if (!useSurface && !hasCamera()) {
+            // pass if testing camera source but no hardware
+            return true;
+        }
+        Surface surface = null;
+        boolean success = true;
+        try {
+            setupRecorder(OUTPUT_PATH, useSurface, false /* hasAudio */);
+
+            /* Test: getSurface() before prepare()
+             * should throw IllegalStateException
+             */
+            surface = tryGetSurface(true /* shouldThow */);
+
+            mMediaRecorder.prepare();
+
+            /* Test: getSurface() after prepare()
+             * should succeed for surface source
+             * should fail for camera source
+             */
+            surface = tryGetSurface(!useSurface);
+
+            mMediaRecorder.start();
+
+            /* Test: getSurface() after start()
+             * should succeed for surface source
+             * should fail for camera source
+             */
+            surface = tryGetSurface(!useSurface);
+
+            try {
+                mMediaRecorder.stop();
+            } catch (Exception e) {
+                // stop() could fail if the recording is empty, as we didn't render anything.
+                // ignore any failure in stop, we just want it stopped.
+            }
+
+            /* Test: getSurface() after stop()
+             * should throw IllegalStateException
+             */
+            surface = tryGetSurface(true /* shouldThow */);
+        } catch (Exception e) {
+            Log.d(TAG, e.toString());
+            success = false;
+        } finally {
+            // reset to clear states, as stop() might have failed
+            mMediaRecorder.reset();
+
+            if (mCamera != null) {
+                mCamera.release();
+                mCamera = null;
+            }
+            if (surface != null) {
+                surface.release();
+                surface = null;
+            }
+        }
+
+        return success;
+    }
+
+    private void trySetInputSurface(Surface surface) throws Exception {
+        boolean testBadArgument = (surface == null);
+        try {
+            mMediaRecorder.setInputSurface(testBadArgument ? new Surface() : surface);
+            fail("failed to throw exception");
+        } catch (IllegalArgumentException e) {
+            // OK only if testing bad arg
+            assertTrue("threw unexpected exception: " + e, testBadArgument);
+        } catch (IllegalStateException e) {
+            // OK only if testing error case other than bad arg
+            assertFalse("threw unexpected exception: " + e, testBadArgument);
+        }
+    }
+
+    private boolean validatePersistentSurface(boolean errorCase) {
+        Log.v(TAG, "validatePersistentSurface, errorCase=" + errorCase);
+
+        Surface surface = MediaCodec.createPersistentInputSurface();
+        if (surface == null) {
+            return false;
+        }
+        Surface dummy = null;
+
+        boolean success = true;
+        try {
+            setupRecorder(OUTPUT_PATH, true /* useSurface */, false /* hasAudio */);
+
+            if (errorCase) {
+                /*
+                 * Test: should throw if called with non-persistent surface
+                 */
+                trySetInputSurface(null);
+            } else {
+                /*
+                 * Test: should succeed if called with a persistent surface before prepare()
+                 */
+                mMediaRecorder.setInputSurface(surface);
+            }
+
+            /*
+             * Test: getSurface() should fail before prepare
+             */
+            dummy = tryGetSurface(true /* shouldThow */);
+
+            mMediaRecorder.prepare();
+
+            /*
+             * Test: setInputSurface() should fail after prepare
+             */
+            trySetInputSurface(surface);
+
+            /*
+             * Test: getSurface() should fail if setInputSurface() succeeded
+             */
+            dummy = tryGetSurface(!errorCase /* shouldThow */);
+
+            mMediaRecorder.start();
+
+            /*
+             * Test: setInputSurface() should fail after start
+             */
+            trySetInputSurface(surface);
+
+            /*
+             * Test: getSurface() should fail if setInputSurface() succeeded
+             */
+            dummy = tryGetSurface(!errorCase /* shouldThow */);
+
+            try {
+                mMediaRecorder.stop();
+            } catch (Exception e) {
+                // stop() could fail if the recording is empty, as we didn't render anything.
+                // ignore any failure in stop, we just want it stopped.
+            }
+
+            /*
+             * Test: getSurface() should fail after stop
+             */
+            dummy = tryGetSurface(true /* shouldThow */);
+        } catch (Exception e) {
+            Log.d(TAG, e.toString());
+            success = false;
+        } finally {
+            // reset to clear states, as stop() might have failed
+            mMediaRecorder.reset();
+
+            if (mCamera != null) {
+                mCamera.release();
+                mCamera = null;
+            }
+            if (surface != null) {
+                surface.release();
+                surface = null;
+            }
+            if (dummy != null) {
+                dummy.release();
+                dummy = null;
+            }
+        }
+
+        return success;
+    }
+
+    public void testGetSurfaceApi() {
+        if (!hasH264()) {
+            MediaUtils.skipTest("no codecs");
+            return;
+        }
+
+        if (hasCamera()) {
+            // validate getSurface() with CAMERA source
+            assertTrue(validateGetSurface(false /* useSurface */));
+        }
+
+        // validate getSurface() with SURFACE source
+        assertTrue(validateGetSurface(true /* useSurface */));
+    }
+
+    public void testPersistentSurfaceApi() {
+        if (!hasH264()) {
+            MediaUtils.skipTest("no codecs");
+            return;
+        }
+
+        // test valid use case
+        assertTrue(validatePersistentSurface(false /* errorCase */));
+
+        // test invalid use case
+        assertTrue(validatePersistentSurface(true /* errorCase */));
+    }
+
+    private static int getMaxFrameRateForCodec(int codec) {
+        for (VideoEncoderCap cap : mVideoEncoders) {
+            if (cap.mCodec == codec) {
+                return cap.mMaxFrameRate < NORMAL_FPS ? cap.mMaxFrameRate : NORMAL_FPS;
+            }
+        }
+        fail("didn't find max FPS for codec");
+        return -1;
+    }
+
+    private boolean recordFromSurface(
+            String filename,
+            int captureRate,
+            boolean hasAudio,
+            Surface persistentSurface) {
+        Log.v(TAG, "recordFromSurface");
+        Surface surface = null;
+        try {
+            setupRecorder(filename, true /* useSurface */, hasAudio);
+
+            int sleepTimeMs;
+            if (captureRate > 0) {
+                mMediaRecorder.setCaptureRate(captureRate);
+                sleepTimeMs = 1000 / captureRate;
+            } else {
+                sleepTimeMs = 1000 / getMaxFrameRateForCodec(MediaRecorder.VideoEncoder.H264);
+            }
+
+            if (persistentSurface != null) {
+                Log.v(TAG, "using persistent surface");
+                surface = persistentSurface;
+                mMediaRecorder.setInputSurface(surface);
+            }
+
+            mMediaRecorder.prepare();
+
+            if (persistentSurface == null) {
+                surface = mMediaRecorder.getSurface();
+            }
+
+            Paint paint = new Paint();
+            paint.setTextSize(16);
+            paint.setColor(Color.RED);
+            int i;
+
+            /* Test: draw 10 frames at 30fps before start
+             * these should be dropped and not causing malformed stream.
+             */
+            for(i = 0; i < 10; i++) {
+                Canvas canvas = surface.lockCanvas(null);
+                int background = (i * 255 / 99);
+                canvas.drawARGB(255, background, background, background);
+                String text = "Frame #" + i;
+                canvas.drawText(text, 50, 50, paint);
+                surface.unlockCanvasAndPost(canvas);
+                Thread.sleep(sleepTimeMs);
+            }
+
+            Log.v(TAG, "start");
+            mMediaRecorder.start();
+
+            /* Test: draw another 90 frames at 30fps after start */
+            for(i = 10; i < 100; i++) {
+                Canvas canvas = surface.lockCanvas(null);
+                int background = (i * 255 / 99);
+                canvas.drawARGB(255, background, background, background);
+                String text = "Frame #" + i;
+                canvas.drawText(text, 50, 50, paint);
+                surface.unlockCanvasAndPost(canvas);
+                Thread.sleep(sleepTimeMs);
+            }
+
+            Log.v(TAG, "stop");
+            mMediaRecorder.stop();
+        } catch (Exception e) {
+            Log.v(TAG, "record video failed: " + e.toString());
+            return false;
+        } finally {
+            // We need to test persistent surface across multiple MediaRecorder
+            // instances, so must destroy mMediaRecorder here.
+            if (mMediaRecorder != null) {
+                mMediaRecorder.release();
+                mMediaRecorder = null;
+            }
+
+            // release surface if not using persistent surface
+            if (persistentSurface == null && surface != null) {
+                surface.release();
+                surface = null;
+            }
+        }
+        return true;
+    }
+
+    private boolean checkCaptureFps(String filename, int captureRate) {
+        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+
+        retriever.setDataSource(filename);
+
+        // verify capture rate meta key is present and correct
+        String captureFps = retriever.extractMetadata(
+                MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE);
+
+        if (captureFps == null) {
+            Log.d(TAG, "METADATA_KEY_CAPTURE_FRAMERATE is missing");
+            return false;
+        }
+
+        if (Math.abs(Float.parseFloat(captureFps) - captureRate) > 0.001) {
+            Log.d(TAG, "METADATA_KEY_CAPTURE_FRAMERATE is incorrect: "
+                    + captureFps + "vs. " + captureRate);
+            return false;
+        }
+
+        // verify other meta keys here if necessary
+        return true;
+    }
+
+    private boolean testRecordFromSurface(boolean persistent, boolean timelapse) {
+        Log.v(TAG, "testRecordFromSurface: " +
+                   "persistent=" + persistent + ", timelapse=" + timelapse);
+        boolean success = false;
+        Surface surface = null;
+        int noOfFailure = 0;
+
+        if (!hasH264()) {
+            MediaUtils.skipTest("no codecs");
+            return true;
+        }
+
+        try {
+            if (persistent) {
+                surface = MediaCodec.createPersistentInputSurface();
+            }
+
+            for (int k = 0; k < 2; k++) {
+                String filename = (k == 0) ? OUTPUT_PATH : OUTPUT_PATH2;
+                boolean hasAudio = false;
+                int captureRate = 0;
+
+                if (timelapse) {
+                    // if timelapse/slow-mo, k chooses between low/high capture fps
+                    captureRate = (k == 0) ? TIME_LAPSE_FPS : SLOW_MOTION_FPS;
+                } else {
+                    // otherwise k chooses between no-audio and audio
+                    hasAudio = (k == 0) ? false : true;
+                }
+
+                if (hasAudio && (!hasMicrophone() || !hasAmrNb())) {
+                    // audio test waived if no audio support
+                    continue;
+                }
+
+                Log.v(TAG, "testRecordFromSurface - round " + k);
+                success = recordFromSurface(filename, captureRate, hasAudio, surface);
+                if (success) {
+                    checkTracksAndDuration(0, true /* hasVideo */, hasAudio, filename);
+
+                    // verify capture fps meta key
+                    if (timelapse && !checkCaptureFps(filename, captureRate)) {
+                        noOfFailure++;
+                    }
+                }
+                if (!success) {
+                    noOfFailure++;
+                }
+            }
+        } catch (Exception e) {
+            Log.v(TAG, e.toString());
+            noOfFailure++;
+        } finally {
+            if (surface != null) {
+                Log.v(TAG, "releasing persistent surface");
+                surface.release();
+                surface = null;
+            }
+        }
+        return (noOfFailure == 0);
+    }
+
+    // Test recording from surface source with/without audio)
+    public void testSurfaceRecording() {
+        assertTrue(testRecordFromSurface(false /* persistent */, false /* timelapse */));
+    }
+
+    // Test recording from persistent surface source with/without audio
+    public void testPersistentSurfaceRecording() {
+        assertTrue(testRecordFromSurface(true /* persistent */, false /* timelapse */));
+    }
+
+    // Test timelapse recording from surface without audio
+    public void testSurfaceRecordingTimeLapse() {
+        assertTrue(testRecordFromSurface(false /* persistent */, true /* timelapse */));
+    }
+
+    // Test timelapse recording from persisent surface without audio
+    public void testPersistentSurfaceRecordingTimeLapse() {
+        assertTrue(testRecordFromSurface(true /* persistent */, true /* timelapse */));
+    }
+
     private void recordMedia(long maxFileSize, File outFile) throws Exception {
         mMediaRecorder.setMaxFileSize(maxFileSize);
         mMediaRecorder.prepare();
diff --git a/tests/tests/media/src/android/media/cts/MediaSessionTest.java b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
index f4a30e8..3ebe6e4 100644
--- a/tests/tests/media/src/android/media/cts/MediaSessionTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaSessionTest.java
@@ -26,10 +26,12 @@
 import android.media.VolumeProvider;
 import android.media.session.MediaController;
 import android.media.session.MediaSession;
+import android.media.session.MediaSession.QueueItem;
 import android.media.session.PlaybackState;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.Message;
 import android.os.Parcel;
 import android.test.AndroidTestCase;
 
@@ -44,6 +46,7 @@
     private static final String TEST_SESSION_TAG = "test-session-tag";
     private static final String TEST_KEY = "test-key";
     private static final String TEST_VALUE = "test-val";
+    private static final String TEST_SESSION_EVENT = "test-session-event";
     private static final int TEST_CURRENT_VOLUME = 10;
     private static final int TEST_MAX_VOLUME = 11;
     private static final long TEST_QUEUE_ID = 12L;
@@ -58,7 +61,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        mAudioManager = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
         mSession = new MediaSession(getContext(), TEST_SESSION_TAG);
     }
 
@@ -163,8 +166,8 @@
 
             // test setQueue and setQueueTitle
             mCallback.resetLocked();
-            List<MediaSession.QueueItem> queue = new ArrayList<MediaSession.QueueItem>();
-            MediaSession.QueueItem item = new MediaSession.QueueItem(new MediaDescription.Builder()
+            List<QueueItem> queue = new ArrayList<>();
+            QueueItem item = new QueueItem(new MediaDescription.Builder()
                     .setMediaId(TEST_VALUE).setTitle("title").build(), TEST_QUEUE_ID);
             queue.add(item);
             mSession.setQueue(queue);
@@ -209,6 +212,15 @@
             mSession.setActive(true);
             assertTrue(mSession.isActive());
 
+            // test sendSessionEvent
+            mCallback.resetLocked();
+            mSession.sendSessionEvent(TEST_SESSION_EVENT, extras);
+            mWaitLock.wait(TIME_OUT_MS);
+
+            assertTrue(mCallback.mOnSessionEventCalled);
+            assertEquals(TEST_SESSION_EVENT, mCallback.mEvent);
+            assertEquals(TEST_VALUE, mCallback.mExtras.getString(TEST_KEY));
+
             // test release
             mCallback.resetLocked();
             mSession.release();
@@ -246,8 +258,9 @@
                 info = mCallback.mPlaybackInfo;
                 if (info != null && info.getCurrentVolume() == TEST_CURRENT_VOLUME
                         && info.getMaxVolume() == TEST_MAX_VOLUME
-                        && info.getPlaybackType() == MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE
-                        && info.getVolumeControl() == VolumeProvider.VOLUME_CONTROL_FIXED) {
+                        && info.getVolumeControl() == VolumeProvider.VOLUME_CONTROL_FIXED
+                        && info.getPlaybackType()
+                                == MediaController.PlaybackInfo.PLAYBACK_TYPE_REMOTE) {
                     break;
                 }
             }
@@ -277,6 +290,23 @@
         }
     }
 
+    /**
+     * Tests MediaSession.QueueItem.
+     */
+    public void testQueueItem() {
+        QueueItem item = new QueueItem(new MediaDescription.Builder()
+                .setMediaId("media-id").setTitle("title").build(), TEST_QUEUE_ID);
+        assertEquals(TEST_QUEUE_ID, item.getQueueId());
+        assertEquals("media-id", item.getDescription().getMediaId());
+        assertEquals("title", item.getDescription().getTitle());
+
+        Parcel p = Parcel.obtain();
+        item.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        QueueItem other = QueueItem.CREATOR.createFromParcel(p);
+        assertEquals(item.toString(), other.toString());
+        p.recycle();
+    }
 
     /**
      * Verifies that a new session hasn't had any configuration bits set yet.
@@ -318,11 +348,13 @@
         private volatile boolean mOnExtraChangedCalled;
         private volatile boolean mOnAudioInfoChangedCalled;
         private volatile boolean mOnSessionDestroyedCalled;
+        private volatile boolean mOnSessionEventCalled;
 
         private volatile PlaybackState mPlaybackState;
         private volatile MediaMetadata mMediaMetadata;
-        private volatile List<MediaSession.QueueItem> mQueue;
+        private volatile List<QueueItem> mQueue;
         private volatile CharSequence mTitle;
+        private volatile String mEvent;
         private volatile Bundle mExtras;
         private volatile MediaController.PlaybackInfo mPlaybackInfo;
 
@@ -334,6 +366,7 @@
             mOnExtraChangedCalled = false;
             mOnAudioInfoChangedCalled = false;
             mOnSessionDestroyedCalled = false;
+            mOnSessionEventCalled = false;
 
             mPlaybackState = null;
             mMediaMetadata = null;
@@ -362,7 +395,7 @@
         }
 
         @Override
-        public void onQueueChanged(List<MediaSession.QueueItem> queue) {
+        public void onQueueChanged(List<QueueItem> queue) {
             synchronized (mWaitLock) {
                 mOnQueueChangedCalled = true;
                 mQueue = queue;
@@ -404,5 +437,15 @@
                 mWaitLock.notify();
             }
         }
+
+        @Override
+        public void onSessionEvent(String event, Bundle extras) {
+            synchronized (mWaitLock) {
+                mOnSessionEventCalled = true;
+                mEvent = event;
+                mExtras = (Bundle) extras.clone();
+                mWaitLock.notify();
+            }
+        }
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/MediaSyncTest.java b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
new file mode 100644
index 0000000..de5a5f5
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MediaSyncTest.java
@@ -0,0 +1,766 @@
+/*
+ * 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.media.cts;
+
+import com.android.cts.media.R;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.cts.util.MediaUtils;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioTrack;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecList;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.media.MediaSync;
+import android.media.MediaTimestamp;
+import android.media.PlaybackParams;
+import android.media.SyncParams;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+
+import java.io.IOException;
+import java.lang.Long;
+import java.nio.ByteBuffer;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.List;
+import java.util.LinkedList;
+
+/**
+ * Tests for the MediaSync API and local video/audio playback.
+ *
+ * <p>The file in res/raw used by all tests are (c) copyright 2008,
+ * Blender Foundation / www.bigbuckbunny.org, and are licensed under the Creative Commons
+ * Attribution 3.0 License at http://creativecommons.org/licenses/by/3.0/us/.
+ */
+public class MediaSyncTest extends ActivityInstrumentationTestCase2<MediaStubActivity> {
+    private static final String LOG_TAG = "MediaSyncTest";
+
+    private final long NO_TIMESTAMP = -1;
+    private final float FLOAT_PLAYBACK_RATE_TOLERANCE = .02f;
+    private final long TIME_MEASUREMENT_TOLERANCE_US = 20000;
+    final int INPUT_RESOURCE_ID =
+            R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_192kbps_44100hz;
+    private final int APPLICATION_AUDIO_PERIOD_MS = 200;
+    private final int TEST_MAX_SPEED = 2;
+    private static final float FLOAT_TOLERANCE = .00001f;
+
+    private Context mContext;
+    private Resources mResources;
+
+    private MediaStubActivity mActivity;
+
+    private MediaSync mMediaSync = null;
+    private Surface mSurface = null;
+    private AudioTrack mAudioTrack = null;
+
+    private Decoder mDecoderVideo = null;
+    private Decoder mDecoderAudio = null;
+    private boolean mHasAudio = false;
+    private boolean mHasVideo = false;
+    private boolean mEosAudio = false;
+    private boolean mEosVideo = false;
+    private final Object mConditionEos = new Object();
+    private final Object mConditionEosAudio = new Object();
+
+    private int mNumBuffersReturned = 0;
+
+    public MediaSyncTest() {
+        super(MediaStubActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        getInstrumentation().waitForIdleSync();
+        try {
+            runTestOnUiThread(new Runnable() {
+                public void run() {
+                    mMediaSync = new MediaSync();
+                }
+            });
+        } catch (Throwable e) {
+            e.printStackTrace();
+            fail();
+        }
+        mContext = getInstrumentation().getTargetContext();
+        mResources = mContext.getResources();
+        mDecoderVideo = new Decoder(this, mMediaSync, false);
+        mDecoderAudio = new Decoder(this, mMediaSync, true);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mMediaSync != null) {
+            mMediaSync.release();
+            mMediaSync = null;
+        }
+        if (mDecoderAudio != null) {
+            mDecoderAudio.release();
+            mDecoderAudio = null;
+        }
+        if (mDecoderVideo != null) {
+            mDecoderVideo.release();
+            mDecoderVideo = null;
+        }
+        if (mSurface != null) {
+            mSurface.release();
+            mSurface = null;
+        }
+        mActivity = null;
+        super.tearDown();
+    }
+
+    private boolean reachedEos_l() {
+        return ((!mHasVideo || mEosVideo) && (!mHasAudio || mEosAudio));
+    }
+
+    public void onEos(Decoder decoder) {
+        synchronized(mConditionEosAudio) {
+            if (decoder == mDecoderAudio) {
+                mEosAudio = true;
+                mConditionEosAudio.notify();
+            }
+        }
+
+        synchronized(mConditionEos) {
+            if (decoder == mDecoderVideo) {
+                mEosVideo = true;
+            }
+            if (reachedEos_l()) {
+                mConditionEos.notify();
+            }
+        }
+    }
+
+    private boolean hasAudioOutput() {
+        return mActivity.getPackageManager()
+            .hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
+    }
+
+    /**
+     * Tests setPlaybackParams is handled correctly for wrong rate.
+     */
+    public void testSetPlaybackParamsFail() throws InterruptedException {
+        final float rate = -1.0f;
+        try {
+            mMediaSync.setPlaybackParams(new PlaybackParams().setSpeed(rate));
+            fail("playback rate " + rate + " is not handled correctly");
+        } catch (IllegalArgumentException e) {
+        }
+
+        assertTrue("The stream in test file can not be decoded",
+                mDecoderAudio.setup(INPUT_RESOURCE_ID, null, Long.MAX_VALUE));
+
+        // get audio track.
+        mAudioTrack = mDecoderAudio.getAudioTrack();
+
+        mMediaSync.setAudioTrack(mAudioTrack);
+
+        try {
+            mMediaSync.setPlaybackParams(new PlaybackParams().setSpeed(rate));
+            fail("With audio track set, playback rate " + rate
+                    + " is not handled correctly");
+        } catch (IllegalArgumentException e) {
+        }
+    }
+
+    /**
+     * Tests setPlaybackParams is handled correctly for good rate without audio track set.
+     * The case for good rate with audio track set is tested in testPlaybackRate*.
+     */
+    public void testSetPlaybackParamsSucceed() throws InterruptedException {
+        final float rate = (float)TEST_MAX_SPEED;
+        try {
+            mMediaSync.setPlaybackParams(new PlaybackParams().setSpeed(rate));
+            PlaybackParams pbp = mMediaSync.getPlaybackParams();
+            assertEquals(rate, pbp.getSpeed(), FLOAT_TOLERANCE);
+        } catch (IllegalArgumentException e) {
+            fail("playback rate " + rate + " is not handled correctly");
+        }
+    }
+
+    /**
+     * Tests returning audio buffers correctly.
+     */
+    public void testAudioBufferReturn() throws InterruptedException {
+        final int timeOutMs = 10000;
+        boolean completed = runCheckAudioBuffer(INPUT_RESOURCE_ID, timeOutMs);
+        if (!completed) {
+            throw new RuntimeException("timed out waiting for audio buffer return");
+        }
+    }
+
+    private PlaybackParams PAUSED_RATE = new PlaybackParams().setSpeed(0.f);
+    private PlaybackParams NORMAL_RATE = new PlaybackParams().setSpeed(1.f);
+
+    private boolean runCheckAudioBuffer(int inputResourceId, int timeOutMs) {
+        final int NUM_LOOPS = 10;
+        final Object condition = new Object();
+
+        mHasAudio = true;
+        if (mDecoderAudio.setup(inputResourceId, null, Long.MAX_VALUE) == false) {
+            return true;
+        }
+
+        // get audio track.
+        mAudioTrack = mDecoderAudio.getAudioTrack();
+
+        mMediaSync.setAudioTrack(mAudioTrack);
+
+        mMediaSync.setCallback(new MediaSync.Callback() {
+            @Override
+            public void onAudioBufferConsumed(
+                    MediaSync sync, ByteBuffer byteBuffer, int bufferIndex) {
+                Decoder decoderAudio = mDecoderAudio;
+                if (decoderAudio != null) {
+                    decoderAudio.checkReturnedAudioBuffer(byteBuffer, bufferIndex);
+                    decoderAudio.releaseOutputBuffer(bufferIndex, NO_TIMESTAMP);
+                    synchronized (condition) {
+                        ++mNumBuffersReturned;
+                        if (mNumBuffersReturned >= NUM_LOOPS) {
+                            condition.notify();
+                        }
+                    }
+                }
+            }
+        }, null);
+
+        mMediaSync.setPlaybackParams(NORMAL_RATE);
+
+        synchronized (condition) {
+            mDecoderAudio.start();
+
+            try {
+                condition.wait(timeOutMs);
+            } catch (InterruptedException e) {
+            }
+            return (mNumBuffersReturned >= NUM_LOOPS);
+        }
+    }
+
+    /**
+     * Tests flush.
+     */
+    public void testFlush() throws InterruptedException {
+        final int timeOutMs = 5000;
+        boolean completed = runFlush(INPUT_RESOURCE_ID, timeOutMs);
+        if (!completed) {
+            throw new RuntimeException("timed out waiting for flush");
+        }
+    }
+
+    private boolean runFlush(int inputResourceId, int timeOutMs) {
+        final int INDEX_BEFORE_FLUSH = 1;
+        final int INDEX_AFTER_FLUSH = 2;
+        final int BUFFER_SIZE = 1024;
+        final int[] returnedIndex = new int[1];
+        final Object condition = new Object();
+
+        returnedIndex[0] = -1;
+
+        mHasAudio = true;
+        if (mDecoderAudio.setup(inputResourceId, null, Long.MAX_VALUE) == false) {
+            return true;
+        }
+
+        // get audio track.
+        mAudioTrack = mDecoderAudio.getAudioTrack();
+
+        mMediaSync.setAudioTrack(mAudioTrack);
+
+        mMediaSync.setCallback(new MediaSync.Callback() {
+            @Override
+            public void onAudioBufferConsumed(
+                    MediaSync sync, ByteBuffer byteBuffer, int bufferIndex) {
+                synchronized (condition) {
+                    if (returnedIndex[0] == -1) {
+                        returnedIndex[0] = bufferIndex;
+                        condition.notify();
+                    }
+                }
+            }
+        }, null);
+
+        mMediaSync.setOnErrorListener(new MediaSync.OnErrorListener() {
+            @Override
+            public void onError(MediaSync sync, int what, int extra) {
+                fail("got error from media sync (" + what + ", " + extra + ")");
+            }
+        }, null);
+
+        mMediaSync.setPlaybackParams(PAUSED_RATE);
+
+        ByteBuffer buffer1 = ByteBuffer.allocate(BUFFER_SIZE);
+        ByteBuffer buffer2 = ByteBuffer.allocate(BUFFER_SIZE);
+        mMediaSync.queueAudio(buffer1, INDEX_BEFORE_FLUSH, 0 /* presentationTimeUs */);
+        mMediaSync.flush();
+        mMediaSync.queueAudio(buffer2, INDEX_AFTER_FLUSH, 0 /* presentationTimeUs */);
+
+        synchronized (condition) {
+            mMediaSync.setPlaybackParams(NORMAL_RATE);
+
+            try {
+                condition.wait(timeOutMs);
+            } catch (InterruptedException e) {
+            }
+            return (returnedIndex[0] == INDEX_AFTER_FLUSH);
+        }
+    }
+
+    /**
+     * Tests playing back audio successfully.
+     */
+    public void testPlayVideo() throws InterruptedException {
+        playAV(INPUT_RESOURCE_ID, 5000 /* lastBufferTimestampMs */,
+               false /* audio */, true /* video */, 10000 /* timeOutMs */);
+    }
+
+    /**
+     * Tests playing back video successfully.
+     */
+    public void testPlayAudio() throws InterruptedException {
+        if (!hasAudioOutput()) {
+            Log.w(LOG_TAG,"AUDIO_OUTPUT feature not found. This system might not have a valid "
+                    + "audio output HAL");
+            return;
+        }
+
+        playAV(INPUT_RESOURCE_ID, 5000 /* lastBufferTimestampMs */,
+               true /* audio */, false /* video */, 10000 /* timeOutMs */);
+    }
+
+    /**
+     * Tests playing back audio and video successfully.
+     */
+    public void testPlayAudioAndVideo() throws InterruptedException {
+        playAV(INPUT_RESOURCE_ID, 5000 /* lastBufferTimestampMs */,
+               true /* audio */, true /* video */, 10000 /* timeOutMs */);
+    }
+
+    /**
+     * Tests playing at specified playback rate successfully.
+     */
+    public void testPlaybackRateQuarter() throws InterruptedException {
+        playAV(INPUT_RESOURCE_ID, 2000 /* lastBufferTimestampMs */,
+               true /* audio */, true /* video */, 10000 /* timeOutMs */,
+               0.25f /* playbackRate */);
+    }
+    public void testPlaybackRateHalf() throws InterruptedException {
+        playAV(INPUT_RESOURCE_ID, 4000 /* lastBufferTimestampMs */,
+               true /* audio */, true /* video */, 10000 /* timeOutMs */,
+               0.5f /* playbackRate */);
+    }
+    public void testPlaybackRateDouble() throws InterruptedException {
+        playAV(INPUT_RESOURCE_ID, 8000 /* lastBufferTimestampMs */,
+               true /* audio */, true /* video */, 10000 /* timeOutMs */,
+               (float)TEST_MAX_SPEED /* playbackRate */);
+    }
+
+    private void playAV(
+            final int inputResourceId,
+            final long lastBufferTimestampMs,
+            final boolean audio,
+            final boolean video,
+            int timeOutMs) throws InterruptedException {
+        playAV(inputResourceId, lastBufferTimestampMs, audio, video, timeOutMs, 1.0f);
+    }
+
+    private void playAV(
+            final int inputResourceId,
+            final long lastBufferTimestampMs,
+            final boolean audio,
+            final boolean video,
+            int timeOutMs,
+            final float playbackRate) throws InterruptedException {
+        final AtomicBoolean completed = new AtomicBoolean();
+        Thread decodingThread = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                completed.set(runPlayAV(inputResourceId, lastBufferTimestampMs * 1000,
+                        audio, video, playbackRate));
+            }
+        });
+        decodingThread.start();
+        decodingThread.join(timeOutMs);
+        if (!completed.get()) {
+            throw new RuntimeException("timed out decoding to end-of-stream");
+        }
+    }
+
+    private boolean runPlayAV(
+            int inputResourceId,
+            long lastBufferTimestampUs,
+            boolean audio,
+            boolean video,
+            float playbackRate) {
+        // allow 250ms for playback to get to stable state.
+        final int PLAYBACK_RAMP_UP_TIME_MS = 250;
+
+        final Object conditionFirstAudioBuffer = new Object();
+
+        if (video) {
+            mMediaSync.setSurface(mActivity.getSurfaceHolder().getSurface());
+            mSurface = mMediaSync.createInputSurface();
+
+            if (mDecoderVideo.setup(
+                    inputResourceId, mSurface, lastBufferTimestampUs) == false) {
+                return true;
+            }
+            mHasVideo = true;
+        }
+
+        if (audio) {
+            if (mDecoderAudio.setup(inputResourceId, null, lastBufferTimestampUs) == false) {
+                return true;
+            }
+
+            // get audio track.
+            mAudioTrack = mDecoderAudio.getAudioTrack();
+
+            mMediaSync.setAudioTrack(mAudioTrack);
+
+            mMediaSync.setCallback(new MediaSync.Callback() {
+                @Override
+                public void onAudioBufferConsumed(
+                        MediaSync sync, ByteBuffer byteBuffer, int bufferIndex) {
+                    Decoder decoderAudio = mDecoderAudio;
+                    if (decoderAudio != null) {
+                        decoderAudio.releaseOutputBuffer(bufferIndex, NO_TIMESTAMP);
+                    }
+                    synchronized (conditionFirstAudioBuffer) {
+                        conditionFirstAudioBuffer.notify();
+                    }
+                }
+            }, null);
+
+            mHasAudio = true;
+        }
+
+        SyncParams sync = new SyncParams().allowDefaults();
+        mMediaSync.setSyncParams(sync);
+        sync = mMediaSync.getSyncParams();
+
+        mMediaSync.setPlaybackParams(new PlaybackParams().setSpeed(playbackRate));
+
+        synchronized (conditionFirstAudioBuffer) {
+            if (video) {
+                mDecoderVideo.start();
+            }
+            if (audio) {
+                mDecoderAudio.start();
+
+                // wait for the first audio output buffer returned by media sync.
+                try {
+                    conditionFirstAudioBuffer.wait();
+                } catch (InterruptedException e) {
+                    Log.i(LOG_TAG, "worker thread is interrupted.");
+                    return true;
+                }
+            }
+        }
+
+        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;
+            long checkStartTimeMediaUs = mediaTimestamp.mediaTimeUs;
+
+            synchronized (mConditionEosAudio) {
+                if (!mEosAudio) {
+                    try {
+                        mConditionEosAudio.wait();
+                    } catch (InterruptedException e) {
+                        Log.i(LOG_TAG, "worker thread is interrupted when waiting for audio EOS.");
+                        return true;
+                    }
+                }
+            }
+            mediaTimestamp = mMediaSync.getTimestamp();
+            assertTrue("No timestamp available for ending", mediaTimestamp != null);
+            long playTimeUs = System.nanoTime() / 1000 - checkStartTimeRealUs;
+            long mediaDurationUs = mediaTimestamp.mediaTimeUs - checkStartTimeMediaUs;
+            assertEquals("Mediasync had error in playback rate " + playbackRate
+                    + ", play time is " + playTimeUs + " vs expected " + mediaDurationUs,
+                    mediaDurationUs,
+                    playTimeUs * playbackRate,
+                    // sync.getTolerance() is MediaSync's tolerance of the playback rate, whereas
+                    // FLOAT_PLAYBACK_RATE_TOLERANCE is our test's tolerance.
+                    // We need to add both to get an upperbound for allowable error.
+                    mediaDurationUs * (sync.getTolerance() + FLOAT_PLAYBACK_RATE_TOLERANCE)
+                            + TIME_MEASUREMENT_TOLERANCE_US);
+        }
+
+        boolean completed = false;
+        synchronized (mConditionEos) {
+            if (!reachedEos_l()) {
+                try {
+                    mConditionEos.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+            completed = reachedEos_l();
+        }
+        return completed;
+    }
+
+    private class Decoder extends MediaCodec.Callback {
+        private final int NO_SAMPLE_RATE = -1;
+        private final int NO_BUFFER_INDEX = -1;
+
+        private MediaSyncTest mMediaSyncTest = null;
+        private MediaSync mMediaSync = null;
+        private boolean mIsAudio = false;
+        private long mLastBufferTimestampUs = 0;
+
+        private Surface mSurface = null;
+
+        private AudioTrack mAudioTrack = null;
+
+        private final Object mConditionCallback = new Object();
+        private MediaExtractor mExtractor = null;
+        private MediaCodec mDecoder = null;
+
+        private final Object mAudioBufferLock = new Object();
+        private List<AudioBuffer> mAudioBuffers = new LinkedList<AudioBuffer>();
+
+        // accessed only on callback thread.
+        private boolean mEos = false;
+        private boolean mSignaledEos = false;
+
+        private class AudioBuffer {
+            public ByteBuffer mByteBuffer;
+            public int mBufferIndex;
+
+            public AudioBuffer(ByteBuffer byteBuffer, int bufferIndex) {
+                mByteBuffer = byteBuffer;
+                mBufferIndex = bufferIndex;
+            }
+        }
+
+        private HandlerThread mHandlerThread;
+        private Handler mHandler;
+
+        Decoder(MediaSyncTest test, MediaSync sync, boolean isAudio) {
+            mMediaSyncTest = test;
+            mMediaSync = sync;
+            mIsAudio = isAudio;
+        }
+
+        public boolean setup(int inputResourceId, Surface surface, long lastBufferTimestampUs) {
+            if (!mIsAudio) {
+                mSurface = surface;
+                // handle video callback in a separate thread as releaseOutputBuffer is blocking
+                mHandlerThread = new HandlerThread("SyncViewVidDec");
+                mHandlerThread.start();
+                mHandler = new Handler(mHandlerThread.getLooper());
+            }
+            mLastBufferTimestampUs = lastBufferTimestampUs;
+            try {
+                // get extrator.
+                String type = mIsAudio ? "audio/" : "video/";
+                mExtractor = MediaUtils.createMediaExtractorForMimeType(
+                        mContext, inputResourceId, type);
+
+                // get decoder.
+                MediaFormat mediaFormat =
+                    mExtractor.getTrackFormat(mExtractor.getSampleTrackIndex());
+                String mimeType = mediaFormat.getString(MediaFormat.KEY_MIME);
+                if (!MediaUtils.hasDecoder(mimeType)) {
+                    Log.i(LOG_TAG, "No decoder found for mimeType= " + mimeType);
+                    return false;
+                }
+                mDecoder = MediaCodec.createDecoderByType(mimeType);
+                mDecoder.configure(mediaFormat, mSurface, null, 0);
+                mDecoder.setCallback(this, mHandler);
+
+                return true;
+            } catch (IOException e) {
+                throw new RuntimeException("error reading input resource", e);
+            }
+        }
+
+        public void start() {
+            if (mDecoder != null) {
+                mDecoder.start();
+            }
+        }
+
+        public void release() {
+            synchronized (mConditionCallback) {
+                if (mDecoder != null) {
+                    try {
+                        mDecoder.stop();
+                    } catch (IllegalStateException e) {
+                    }
+                    mDecoder.release();
+                    mDecoder = null;
+                }
+                if (mExtractor != null) {
+                    mExtractor.release();
+                    mExtractor = null;
+                }
+            }
+
+            if (mAudioTrack != null) {
+                mAudioTrack.release();
+                mAudioTrack = null;
+            }
+        }
+
+        public AudioTrack getAudioTrack() {
+            if (!mIsAudio) {
+                throw new RuntimeException("can not create audio track for video");
+            }
+
+            if (mExtractor == null) {
+                throw new RuntimeException("extrator is null");
+            }
+
+            if (mAudioTrack == null) {
+                MediaFormat mediaFormat =
+                    mExtractor.getTrackFormat(mExtractor.getSampleTrackIndex());
+                int sampleRateInHz = mediaFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE);
+                int channelConfig = (mediaFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT) == 1 ?
+                        AudioFormat.CHANNEL_OUT_MONO : AudioFormat.CHANNEL_OUT_STEREO);
+                int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
+                int minBufferSizeInBytes = AudioTrack.getMinBufferSize(
+                        sampleRateInHz,
+                        channelConfig,
+                        audioFormat);
+                final int frameCount = APPLICATION_AUDIO_PERIOD_MS * sampleRateInHz / 1000;
+                final int frameSizeInBytes = Integer.bitCount(channelConfig)
+                        * AudioFormat.getBytesPerSample(audioFormat);
+                // ensure we consider application requirements for writing audio data
+                minBufferSizeInBytes = TEST_MAX_SPEED /* speed influences buffer size */
+                        * Math.max(minBufferSizeInBytes, frameCount * frameSizeInBytes);
+                mAudioTrack = new AudioTrack(
+                        AudioManager.STREAM_MUSIC,
+                        sampleRateInHz,
+                        channelConfig,
+                        audioFormat,
+                        minBufferSizeInBytes,
+                        AudioTrack.MODE_STREAM);
+            }
+
+            return mAudioTrack;
+        }
+
+        public void releaseOutputBuffer(int bufferIndex, long renderTimestampNs) {
+            synchronized (mConditionCallback) {
+                if (mDecoder != null) {
+                    if (renderTimestampNs == NO_TIMESTAMP) {
+                        mDecoder.releaseOutputBuffer(bufferIndex, false /* render */);
+                    } else {
+                        mDecoder.releaseOutputBuffer(bufferIndex, renderTimestampNs);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onError(MediaCodec codec, MediaCodec.CodecException e) {
+        }
+
+        @Override
+        public void onInputBufferAvailable(MediaCodec codec, int index) {
+            synchronized (mConditionCallback) {
+                if (mExtractor == null || mExtractor.getSampleTrackIndex() == -1
+                        || mSignaledEos || mDecoder != codec) {
+                    return;
+                }
+
+                ByteBuffer buffer = codec.getInputBuffer(index);
+                int size = mExtractor.readSampleData(buffer, 0);
+                long timestampUs = mExtractor.getSampleTime();
+                mExtractor.advance();
+                mSignaledEos = mExtractor.getSampleTrackIndex() == -1
+                        || timestampUs >= mLastBufferTimestampUs;
+                codec.queueInputBuffer(
+                        index,
+                        0,
+                        size,
+                        timestampUs,
+                        mSignaledEos ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+            }
+        }
+
+        @Override
+        public void onOutputBufferAvailable(
+                MediaCodec codec, int index, MediaCodec.BufferInfo info) {
+            synchronized (mConditionCallback) {
+                if (mEos || mDecoder != codec) {
+                    return;
+                }
+
+                mEos = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
+
+                if (info.size > 0) {
+                    if (mIsAudio) {
+                        ByteBuffer outputByteBuffer = codec.getOutputBuffer(index);
+                        synchronized(mAudioBufferLock) {
+                            mAudioBuffers.add(new AudioBuffer(outputByteBuffer, index));
+                        }
+                        mMediaSync.queueAudio(
+                                outputByteBuffer,
+                                index,
+                                info.presentationTimeUs);
+                    } else {
+                        codec.releaseOutputBuffer(index, info.presentationTimeUs * 1000);
+                    }
+                } else {
+                    codec.releaseOutputBuffer(index, false);
+                }
+            }
+
+            if (mEos) {
+                mMediaSyncTest.onEos(this);
+            }
+        }
+
+        @Override
+        public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
+        }
+
+        public void checkReturnedAudioBuffer(ByteBuffer byteBuffer, int bufferIndex) {
+            synchronized(mAudioBufferLock) {
+                AudioBuffer audioBuffer = mAudioBuffers.get(0);
+                if (audioBuffer.mByteBuffer != byteBuffer
+                        || audioBuffer.mBufferIndex != bufferIndex) {
+                    fail("returned buffer doesn't match what's sent");
+                }
+                mAudioBuffers.remove(0);
+            }
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/MidiSoloTest.java b/tests/tests/media/src/android/media/cts/MidiSoloTest.java
new file mode 100644
index 0000000..d198ee8
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/MidiSoloTest.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 java.io.IOException;
+
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.cts.util.CtsAndroidTestCase;
+import android.media.midi.MidiDevice;
+import android.media.midi.MidiDevice.MidiConnection;
+import android.media.midi.MidiDeviceInfo;
+import android.media.midi.MidiDeviceStatus;
+import android.media.midi.MidiInputPort;
+import android.media.midi.MidiManager;
+import android.media.midi.MidiReceiver;
+import android.media.midi.MidiSender;
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * Test MIDI when there may be no MIDI devices available. There is not much we
+ * can test without a device.
+ */
+public class MidiSoloTest extends CtsAndroidTestCase {
+    private static final String TAG = "MidiSoloTest";
+    private final static int LOCAL_STORAGE_SIZE = 256;
+
+    // Store received data so we can check it later.
+    class MyMidiReceiver extends MidiReceiver {
+        public int byteCount;
+        public byte[] data = new byte[LOCAL_STORAGE_SIZE];
+
+        public MyMidiReceiver(int maxMessageSize) {
+            super(maxMessageSize);
+        }
+
+        @Override
+        // Abstract method declared in MidiReceiver
+        public void onSend(byte[] msg, int offset, int count, long timestamp)
+                throws IOException {
+            assertTrue("Message too large.", (count <= getMaxMessageSize()));
+            try {
+                System.arraycopy(msg, offset, data, byteCount, count);
+            } catch (ArrayIndexOutOfBoundsException e) {
+                throw new IOException("Exceeded local storage.", e);
+            }
+            byteCount += count;
+        }
+
+        @Override
+        public void onFlush() {
+            byteCount = 0;
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        // setup for each test case.
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        // Test case clean up.
+        super.tearDown();
+    }
+
+    public void testMidiManager() throws Exception {
+        PackageManager pm = getContext().getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+            return; // Not supported so don't test it.
+        }
+
+        MidiManager midiManager = (MidiManager) getContext().getSystemService(
+                Context.MIDI_SERVICE);
+        assertTrue("MidiManager not supported.", midiManager != null);
+
+        MidiDeviceInfo[] infos = midiManager.getDevices();
+        assertTrue("Device list was null.", infos != null);
+
+        MidiManager.DeviceCallback callback = new MidiManager.DeviceCallback();
+
+        // These should not crash.
+        midiManager.unregisterDeviceCallback(callback);
+        midiManager.registerDeviceCallback(callback, null);
+        midiManager.unregisterDeviceCallback(callback);
+        midiManager.registerDeviceCallback(callback, new Handler(Looper.getMainLooper()));
+        midiManager.registerDeviceCallback(callback, new Handler(Looper.getMainLooper()));
+        midiManager.unregisterDeviceCallback(callback);
+        midiManager.unregisterDeviceCallback(callback);
+        midiManager.unregisterDeviceCallback(callback);
+    }
+
+    public void testMidiReceiver() throws Exception {
+        PackageManager pm = getContext().getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+            return; // Not supported so don't test it.
+        }
+
+        MidiReceiver receiver = new MidiReceiver() {
+                @Override
+            public void onSend(byte[] msg, int offset, int count,
+                    long timestamp) throws IOException {
+            }
+        };
+        assertEquals("MidiReceiver default size wrong.", Integer.MAX_VALUE,
+                receiver.getMaxMessageSize());
+
+        int maxSize = 11;
+        MyMidiReceiver myReceiver = new MyMidiReceiver(maxSize);
+        assertEquals("MidiReceiver set size wrong.", maxSize,
+                myReceiver.getMaxMessageSize());
+
+        // Fill array with predictable data.
+        byte[] bar = new byte[200];
+        for (int i = 0; i < bar.length; i++) {
+            bar[i] = (byte) (i ^ 15);
+        }
+        // Small message with no offset.
+        int offset = 0;
+        int count = 3;
+        checkReceivedData(myReceiver, bar, offset, count);
+
+        // Small with an offset.
+        offset = 50;
+        count = 3;
+        checkReceivedData(myReceiver, bar, offset, count);
+
+        // Entire array.
+        offset = 0;
+        count = bar.length;
+        checkReceivedData(myReceiver, bar, offset, count);
+
+        offset = 20;
+        count = 100;
+        checkReceivedData(myReceiver, bar, offset, count);
+    }
+
+    public void testMidiReceiverException() throws Exception {
+        PackageManager pm = getContext().getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+            return; // Not supported so don't test it.
+        }
+
+        int maxSize = 11;
+        MyMidiReceiver myReceiver = new MyMidiReceiver(maxSize);
+        assertEquals("MidiReceiver set size wrong.", maxSize,
+                myReceiver.getMaxMessageSize());
+
+        // Fill array with predictable data.
+        byte[] bar = new byte[200];
+        int offset = 0;
+        int count = bar.length;
+        myReceiver.flush(); // reset byte counter
+        IOException exception = null;
+        // Send too much data and intentionally cause an IOException.
+        try {
+            int sent = 0;
+            while (sent < LOCAL_STORAGE_SIZE) {
+                myReceiver.send(bar, offset, count);
+                sent += count;
+            }
+        } catch (IOException e) {
+            exception = e;
+        }
+        assertTrue("We should have caught an IOException", exception != null);
+    }
+
+    // Does the data we sent match the data received by the MidiReceiver?
+    private void checkReceivedData(MyMidiReceiver myReceiver, byte[] bar,
+            int offset, int count) throws IOException {
+        myReceiver.flush(); // reset byte counter
+        assertEquals("MidiReceiver flush ", 0, myReceiver.byteCount);
+        myReceiver.send(bar, offset, count);
+        // Did we get all the data
+        assertEquals("MidiReceiver count ", count, myReceiver.byteCount);
+        for (int i = 0; i < count; i++) {
+            assertEquals("MidiReceiver byte " + i + " + " + offset,
+                    bar[i + offset], myReceiver.data[i]);
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java b/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java
index 86bab41..4a4e807 100644
--- a/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java
+++ b/tests/tests/media/src/android/media/cts/NonBlockingAudioTrack.java
@@ -22,7 +22,6 @@
 import android.util.Log;
 
 import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
 import java.util.LinkedList;
 
 /**
@@ -37,12 +36,14 @@
     class QueueElement {
         ByteBuffer data;
         int size;
+        long pts;
     }
 
     private AudioTrack mAudioTrack;
     private int mSampleRate;
     private int mNumBytesQueued = 0;
     private LinkedList<QueueElement> mQueue = new LinkedList<QueueElement>();
+    private boolean mStopped;
 
     public NonBlockingAudioTrack(int sampleRate, int channelCount, boolean hwAvSync,
                     int audioSessionId) {
@@ -107,14 +108,17 @@
     }
 
     public void play() {
+        mStopped = false;
         mAudioTrack.play();
     }
 
     public void stop() {
-        mAudioTrack.stop();
-
-        mQueue.clear();
-        mNumBytesQueued = 0;
+        if (mQueue.isEmpty()) {
+            mAudioTrack.stop();
+            mNumBytesQueued = 0;
+        } else {
+            mStopped = true;
+        }
     }
 
     public void pause() {
@@ -128,6 +132,7 @@
         mAudioTrack.flush();
         mQueue.clear();
         mNumBytesQueued = 0;
+        mStopped = false;
     }
 
     public void release() {
@@ -135,13 +140,14 @@
         mNumBytesQueued = 0;
         mAudioTrack.release();
         mAudioTrack = null;
+        mStopped = false;
     }
 
     public void process() {
         while (!mQueue.isEmpty()) {
             QueueElement element = mQueue.peekFirst();
             int written = mAudioTrack.write(element.data, element.size,
-                                            AudioTrack.WRITE_NON_BLOCKING);
+                                            AudioTrack.WRITE_NON_BLOCKING, element.pts);
             if (written < 0) {
                 throw new RuntimeException("Audiotrack.write() failed.");
             }
@@ -153,6 +159,11 @@
             }
             mQueue.removeFirst();
         }
+        if (mStopped) {
+            mAudioTrack.stop();
+            mNumBytesQueued = 0;
+            mStopped = false;
+        }
     }
 
     public int getPlayState() {
@@ -160,29 +171,10 @@
     }
 
     public void write(ByteBuffer data, int size, long pts) {
-        // create timestamp header
-        final int headerSize = 16;
-        ByteBuffer avSyncHeader;
-        avSyncHeader = ByteBuffer.allocate(headerSize);
-        avSyncHeader.order(ByteOrder.BIG_ENDIAN);
-        avSyncHeader.putInt(0x55550001);
-        avSyncHeader.putInt(size);
-        avSyncHeader.putLong(pts);
-        avSyncHeader.position(0);
-
-        QueueElement headerElement = new QueueElement();
-        headerElement.data = avSyncHeader;
-        headerElement.size = headerSize;
-
-        // accumulate size written to queue
-        mNumBytesQueued += headerSize;
-        mQueue.add(headerElement);
-
-        // create payload element
         QueueElement element = new QueueElement();
         element.data = data;
         element.size = size;
-        data.position(0);
+        element.pts  = pts;
 
         // accumulate size written to queue
         mNumBytesQueued += size;
diff --git a/tests/tests/media/src/android/media/cts/ParamsTest.java b/tests/tests/media/src/android/media/cts/ParamsTest.java
new file mode 100644
index 0000000..5e32828
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ParamsTest.java
@@ -0,0 +1,374 @@
+/*
+ * 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.media.cts;
+
+import com.android.cts.media.R;
+
+import android.media.PlaybackParams;
+import android.media.SyncParams;
+import android.os.Parcel;
+import android.test.AndroidTestCase;
+
+/**
+ * General Params tests.
+ *
+ * In particular, check Params objects' behavior.
+ */
+public class ParamsTest extends AndroidTestCase {
+    private static final String TAG = "ParamsTest";
+    private static final float FLOAT_TOLERANCE = .00001f;
+    private static final float MAX_DEFAULT_TOLERANCE = 1/24.f;
+
+    public void testSyncParamsConstants() {
+        assertEquals(0, SyncParams.SYNC_SOURCE_DEFAULT);
+        assertEquals(1, SyncParams.SYNC_SOURCE_SYSTEM_CLOCK);
+        assertEquals(2, SyncParams.SYNC_SOURCE_AUDIO);
+        assertEquals(3, SyncParams.SYNC_SOURCE_VSYNC);
+
+        assertEquals(0, SyncParams.AUDIO_ADJUST_MODE_DEFAULT);
+        assertEquals(1, SyncParams.AUDIO_ADJUST_MODE_STRETCH);
+        assertEquals(2, SyncParams.AUDIO_ADJUST_MODE_RESAMPLE);
+    }
+
+    public void testSyncParamsDefaults() {
+        SyncParams p = new SyncParams();
+        try { fail("got " + p.getAudioAdjustMode()); } catch (IllegalStateException e) {}
+        try { fail("got " + p.getSyncSource());      } catch (IllegalStateException e) {}
+        try { fail("got " + p.getTolerance());       } catch (IllegalStateException e) {}
+        try { fail("got " + p.getFrameRate());       } catch (IllegalStateException e) {}
+
+        SyncParams q = p.allowDefaults();
+        assertSame(p, q);
+        assertEquals(p.AUDIO_ADJUST_MODE_DEFAULT, p.getAudioAdjustMode());
+        assertEquals(p.SYNC_SOURCE_DEFAULT,       p.getSyncSource());
+        assertTrue(p.getTolerance() >= 0.f
+                && p.getTolerance() < MAX_DEFAULT_TOLERANCE + FLOAT_TOLERANCE);
+        try { fail("got " + p.getFrameRate());       } catch (IllegalStateException e) {}
+    }
+
+    public void testSyncParamsAudioAdjustMode() {
+        // setting this cannot fail
+        SyncParams p = new SyncParams();
+        for (int i : new int[] {
+                SyncParams.AUDIO_ADJUST_MODE_STRETCH,
+                SyncParams.AUDIO_ADJUST_MODE_RESAMPLE,
+                -1 /* invalid */}) {
+            SyncParams q = p.setAudioAdjustMode(i); // verify both initial set and update
+            assertSame(p, q);
+            assertEquals(i, p.getAudioAdjustMode());
+            try { fail("got " + p.getSyncSource());      } catch (IllegalStateException e) {}
+            try { fail("got " + p.getTolerance());       } catch (IllegalStateException e) {}
+            try { fail("got " + p.getFrameRate());       } catch (IllegalStateException e) {}
+        }
+    }
+
+    public void testSyncParamsSyncSource() {
+        // setting this cannot fail
+        SyncParams p = new SyncParams();
+        for (int i : new int[] {
+                SyncParams.SYNC_SOURCE_SYSTEM_CLOCK,
+                SyncParams.SYNC_SOURCE_AUDIO,
+                -1 /* invalid */}) {
+            SyncParams q = p.setSyncSource(i); // verify both initial set and update
+            assertSame(p, q);
+            try { fail("got " + p.getAudioAdjustMode()); } catch (IllegalStateException e) {}
+            assertEquals(i, p.getSyncSource());
+            try { fail("got " + p.getTolerance());       } catch (IllegalStateException e) {}
+            try { fail("got " + p.getFrameRate());       } catch (IllegalStateException e) {}
+        }
+    }
+
+    public void testSyncParamsTolerance() {
+        // this can fail on values not in [0, 1)
+
+        // test good values
+        SyncParams p = new SyncParams();
+        float lastValue = 2.f; /* some initial value to avoid compile error */
+        for (float f : new float[] { 0.f, .1f, .9999f }) {
+            SyncParams q = p.setTolerance(f); // verify both initial set and update
+            assertSame(p, q);
+            try { fail("got " + p.getAudioAdjustMode()); } catch (IllegalStateException e) {}
+            try { fail("got " + p.getSyncSource());      } catch (IllegalStateException e) {}
+            assertEquals(f, p.getTolerance(), FLOAT_TOLERANCE);
+            try { fail("got " + p.getFrameRate());       } catch (IllegalStateException e) {}
+            lastValue = f;
+        }
+
+        // test bad values - these should have no effect
+        boolean update = true;
+        for (float f : new float[] { -.0001f, 1.f }) {
+            try {
+                p.setTolerance(f);
+                fail("set tolerance to " + f);
+            } catch (IllegalArgumentException e) {}
+            try { fail("got " + p.getAudioAdjustMode()); } catch (IllegalStateException e) {}
+            try { fail("got " + p.getSyncSource());      } catch (IllegalStateException e) {}
+            if (update) {
+                // if updating, last value should remain
+                assertEquals(lastValue, p.getTolerance(), FLOAT_TOLERANCE);
+            } else {
+                // otherwise, it should remain undefined
+                try { fail("got " + p.getTolerance());       } catch (IllegalStateException e) {}
+            }
+            try { fail("got " + p.getFrameRate());       } catch (IllegalStateException e) {}
+
+            // no longer updating in subsequent iterations
+            p = new SyncParams();
+            update = false;
+        }
+    }
+
+    public void testSyncParamsFrameRate() {
+        // setting this cannot fail, but negative values may be normalized to some negative value
+        SyncParams p = new SyncParams();
+        for (float f : new float[] { 0.f, .0001f, 30.f, 300.f, -.0001f, -1.f }) {
+            SyncParams q = p.setFrameRate(f);
+            assertSame(p, q);
+            try { fail("got " + p.getAudioAdjustMode()); } catch (IllegalStateException e) {}
+            try { fail("got " + p.getSyncSource());      } catch (IllegalStateException e) {}
+            try { fail("got " + p.getTolerance());       } catch (IllegalStateException e) {}
+            if (f >= 0) {
+                assertEquals(f, p.getFrameRate(), FLOAT_TOLERANCE);
+            } else {
+                assertTrue(p.getFrameRate() < 0.f);
+            }
+        }
+    }
+
+    public void testSyncParamsMultipleSettings() {
+        {
+            SyncParams p = new SyncParams();
+            p.setAudioAdjustMode(p.AUDIO_ADJUST_MODE_STRETCH);
+            SyncParams q = p.setTolerance(.5f);
+            assertSame(p, q);
+
+            assertEquals(p.AUDIO_ADJUST_MODE_STRETCH, p.getAudioAdjustMode());
+            try { fail("got " + p.getSyncSource());      } catch (IllegalStateException e) {}
+            assertEquals(.5f, p.getTolerance(), FLOAT_TOLERANCE);
+            try { fail("got " + p.getFrameRate());       } catch (IllegalStateException e) {}
+
+            // allowDefaults should not change set values
+            q = p.allowDefaults();
+            assertSame(p, q);
+
+            assertEquals(p.AUDIO_ADJUST_MODE_STRETCH, p.getAudioAdjustMode());
+            assertEquals(p.SYNC_SOURCE_DEFAULT, p.getSyncSource());
+            assertEquals(.5f, p.getTolerance(), FLOAT_TOLERANCE);
+            try { fail("got " + p.getFrameRate());       } catch (IllegalStateException e) {}
+        }
+
+        {
+            SyncParams p = new SyncParams();
+            p.setSyncSource(p.SYNC_SOURCE_VSYNC);
+            SyncParams q = p.setFrameRate(25.f);
+            assertSame(p, q);
+
+            try { fail("got " + p.getAudioAdjustMode()); } catch (IllegalStateException e) {}
+            assertEquals(p.SYNC_SOURCE_VSYNC, p.getSyncSource());
+            try { fail("got " + p.getTolerance());       } catch (IllegalStateException e) {}
+            assertEquals(25.f, p.getFrameRate(), FLOAT_TOLERANCE);
+
+            // allowDefaults should not change set values
+            q = p.allowDefaults();
+            assertSame(p, q);
+
+            assertEquals(p.AUDIO_ADJUST_MODE_DEFAULT, p.getAudioAdjustMode());
+            assertEquals(p.SYNC_SOURCE_VSYNC, p.getSyncSource());
+            assertTrue(p.getTolerance() >= 0.f
+                    && p.getTolerance() < MAX_DEFAULT_TOLERANCE + FLOAT_TOLERANCE);
+            assertEquals(25.f, p.getFrameRate(), FLOAT_TOLERANCE);
+        }
+    }
+
+    public void testPlaybackParamsConstants() {
+        assertEquals(0, PlaybackParams.AUDIO_STRETCH_MODE_DEFAULT);
+        assertEquals(1, PlaybackParams.AUDIO_STRETCH_MODE_VOICE);
+
+        assertEquals(0, PlaybackParams.AUDIO_FALLBACK_MODE_DEFAULT);
+        assertEquals(1, PlaybackParams.AUDIO_FALLBACK_MODE_MUTE);
+        assertEquals(2, PlaybackParams.AUDIO_FALLBACK_MODE_FAIL);
+    }
+
+    public void testPlaybackParamsDefaults() {
+        PlaybackParams p = new PlaybackParams();
+        try { fail("got " + p.getAudioFallbackMode()); } catch (IllegalStateException e) {}
+        try { fail("got " + p.getAudioStretchMode());  } catch (IllegalStateException e) {}
+        try { fail("got " + p.getPitch());             } catch (IllegalStateException e) {}
+        try { fail("got " + p.getSpeed());             } catch (IllegalStateException e) {}
+
+        PlaybackParams q = p.allowDefaults();
+        assertSame(p, q);
+        assertEquals(p.AUDIO_FALLBACK_MODE_DEFAULT, p.getAudioFallbackMode());
+        assertEquals(p.AUDIO_STRETCH_MODE_DEFAULT,  p.getAudioStretchMode());
+        assertEquals(1.f, p.getPitch(), FLOAT_TOLERANCE);
+        assertEquals(1.f, p.getSpeed(), FLOAT_TOLERANCE);
+    }
+
+    public void testPlaybackParamsAudioFallbackMode() {
+        // setting this cannot fail
+        PlaybackParams p = new PlaybackParams();
+        for (int i : new int[] {
+                PlaybackParams.AUDIO_FALLBACK_MODE_MUTE,
+                PlaybackParams.AUDIO_FALLBACK_MODE_FAIL,
+                -1 /* invalid */}) {
+            PlaybackParams q = p.setAudioFallbackMode(i); // verify both initial set and update
+            assertSame(p, q);
+            assertEquals(i, p.getAudioFallbackMode());
+            try { fail("got " + p.getAudioStretchMode());  } catch (IllegalStateException e) {}
+            try { fail("got " + p.getPitch());             } catch (IllegalStateException e) {}
+            try { fail("got " + p.getSpeed());             } catch (IllegalStateException e) {}
+        }
+    }
+
+    public void testPlaybackParamsAudioStretchMode() {
+        // setting this cannot fail
+        PlaybackParams p = new PlaybackParams();
+        for (int i : new int[] {
+                PlaybackParams.AUDIO_STRETCH_MODE_DEFAULT,
+                PlaybackParams.AUDIO_STRETCH_MODE_VOICE,
+                -1 /* invalid */}) {
+            PlaybackParams q = p.setAudioStretchMode(i); // verify both initial set and update
+            assertSame(p, q);
+            try { fail("got " + p.getAudioFallbackMode()); } catch (IllegalStateException e) {}
+            assertEquals(i, p.getAudioStretchMode());
+            try { fail("got " + p.getPitch());             } catch (IllegalStateException e) {}
+            try { fail("got " + p.getSpeed());             } catch (IllegalStateException e) {}
+        }
+    }
+
+    public void testPlaybackParamsPitch() {
+        // this can fail on values not in [0, Inf)
+
+        // test good values
+        PlaybackParams p = new PlaybackParams();
+        float lastValue = 2.f; /* some initial value to avoid compile error */
+        for (float f : new float[] { 0.f, .1f, 9999.f }) {
+            PlaybackParams q = p.setPitch(f); // verify both initial set and update
+            assertSame(p, q);
+            try { fail("got " + p.getAudioFallbackMode()); } catch (IllegalStateException e) {}
+            try { fail("got " + p.getAudioStretchMode());  } catch (IllegalStateException e) {}
+            assertEquals(f, p.getPitch(), FLOAT_TOLERANCE);
+            try { fail("got " + p.getSpeed());             } catch (IllegalStateException e) {}
+            lastValue = f;
+        }
+
+        // test bad values - these should have no effect
+        boolean update = true;
+        for (float f : new float[] { -.0001f, -1.f }) {
+            try {
+                p.setPitch(f);
+                fail("set tolerance to " + f);
+            } catch (IllegalArgumentException e) {}
+            try { fail("got " + p.getAudioFallbackMode()); } catch (IllegalStateException e) {}
+            try { fail("got " + p.getAudioStretchMode());  } catch (IllegalStateException e) {}
+            if (update) {
+                // if updating, last value should remain
+                assertEquals(lastValue, p.getPitch(), FLOAT_TOLERANCE);
+            } else {
+                // otherwise, it should remain undefined
+                try { fail("got " + p.getPitch());             } catch (IllegalStateException e) {}
+            }
+            try { fail("got " + p.getSpeed());             } catch (IllegalStateException e) {}
+
+            // no longer updating in subsequent iterations
+            p = new PlaybackParams();
+            update = false;
+        }
+    }
+
+    public void testPlaybackParamsSpeed() {
+        // setting this cannot fail
+        PlaybackParams p = new PlaybackParams();
+        for (float f : new float[] { 0.f, .0001f, 30.f, 300.f, -.0001f, -1.f, -300.f }) {
+            PlaybackParams q = p.setSpeed(f);
+            assertSame(p, q);
+            try { fail("got " + p.getAudioFallbackMode()); } catch (IllegalStateException e) {}
+            try { fail("got " + p.getAudioStretchMode());  } catch (IllegalStateException e) {}
+            try { fail("got " + p.getPitch());             } catch (IllegalStateException e) {}
+            assertEquals(f, p.getSpeed(), FLOAT_TOLERANCE);
+        }
+    }
+
+    public void testPlaybackParamsMultipleSettings() {
+        {
+            PlaybackParams p = new PlaybackParams();
+            p.setAudioFallbackMode(p.AUDIO_FALLBACK_MODE_MUTE);
+            PlaybackParams q = p.setPitch(.5f);
+            assertSame(p, q);
+
+            assertEquals(p.AUDIO_FALLBACK_MODE_MUTE, p.getAudioFallbackMode());
+            try { fail("got " + p.getAudioStretchMode());  } catch (IllegalStateException e) {}
+            assertEquals(.5f, p.getPitch(), FLOAT_TOLERANCE);
+            try { fail("got " + p.getSpeed());             } catch (IllegalStateException e) {}
+
+            // allowDefaults should not change set values
+            q = p.allowDefaults();
+            assertSame(p, q);
+
+            assertEquals(p.AUDIO_FALLBACK_MODE_MUTE, p.getAudioFallbackMode());
+            assertEquals(p.AUDIO_STRETCH_MODE_DEFAULT, p.getAudioStretchMode());
+            assertEquals(.5f, p.getPitch(), FLOAT_TOLERANCE);
+            assertEquals(1.f, p.getSpeed(), FLOAT_TOLERANCE);
+        }
+
+        {
+            PlaybackParams p = new PlaybackParams();
+            p.setAudioStretchMode(p.AUDIO_STRETCH_MODE_VOICE);
+            PlaybackParams q = p.setSpeed(25.f);
+            assertSame(p, q);
+
+            try { fail("got " + p.getAudioFallbackMode()); } catch (IllegalStateException e) {}
+            assertEquals(p.AUDIO_STRETCH_MODE_VOICE, p.getAudioStretchMode());
+            try { fail("got " + p.getPitch());             } catch (IllegalStateException e) {}
+            assertEquals(25.f, p.getSpeed(), FLOAT_TOLERANCE);
+
+            // allowDefaults should not change set values
+            q = p.allowDefaults();
+            assertSame(p, q);
+
+            assertEquals(p.AUDIO_FALLBACK_MODE_DEFAULT, p.getAudioFallbackMode());
+            assertEquals(p.AUDIO_STRETCH_MODE_VOICE, p.getAudioStretchMode());
+            assertEquals(1.f, p.getPitch(), FLOAT_TOLERANCE);
+            assertEquals(25.f, p.getSpeed(), FLOAT_TOLERANCE);
+        }
+    }
+
+    public void testPlaybackParamsDescribeContents() {
+        PlaybackParams p = new PlaybackParams();
+        assertEquals(0, p.describeContents());
+    }
+
+    public void testPlaybackParamsWriteToParcel() {
+        PlaybackParams p = new PlaybackParams();
+        p.setAudioFallbackMode(PlaybackParams.AUDIO_FALLBACK_MODE_FAIL);
+        p.setAudioStretchMode(PlaybackParams.AUDIO_STRETCH_MODE_VOICE);
+        p.setPitch(.5f);
+        p.setSpeed(.0001f);
+
+        Parcel parcel = Parcel.obtain();
+        p.writeToParcel(parcel, 0 /* flags */);
+        parcel.setDataPosition(0);
+        PlaybackParams q = PlaybackParams.CREATOR.createFromParcel(parcel);
+
+        assertEquals(p.getAudioFallbackMode(), q.getAudioFallbackMode());
+        assertEquals(p.getAudioStretchMode(), q.getAudioStretchMode());
+        assertEquals(p.getPitch(), q.getPitch());
+        assertEquals(p.getSpeed(), q.getSpeed());
+        parcel.recycle();
+    }
+
+}
diff --git a/tests/tests/media/src/android/media/cts/PostProcTestBase.java b/tests/tests/media/src/android/media/cts/PostProcTestBase.java
index ef87662..cefbbf4 100644
--- a/tests/tests/media/src/android/media/cts/PostProcTestBase.java
+++ b/tests/tests/media/src/android/media/cts/PostProcTestBase.java
@@ -40,30 +40,18 @@
     }
 
     protected boolean isBassBoostAvailable() {
-        if (!hasAudioOutput()) {
-            return false;
-        }
         return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_BASS_BOOST);
     }
 
     protected boolean isVirtualizerAvailable() {
-        if (!hasAudioOutput()) {
-            return false;
-        }
         return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_VIRTUALIZER);
     }
 
     protected boolean isPresetReverbAvailable() {
-        if (!hasAudioOutput()) {
-            return false;
-        }
         return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_PRESET_REVERB);
     }
 
     protected boolean isEnvReverbAvailable() {
-        if (!hasAudioOutput()) {
-            return false;
-        }
         return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_ENV_REVERB);
     }
 
diff --git a/tests/tests/media/src/android/media/cts/ResourceManagerStubActivity.java b/tests/tests/media/src/android/media/cts/ResourceManagerStubActivity.java
new file mode 100644
index 0000000..5595800
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ResourceManagerStubActivity.java
@@ -0,0 +1,128 @@
+/*
+ * 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.media.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+import junit.framework.Assert;
+
+public class ResourceManagerStubActivity extends Activity {
+    private static final String TAG = "ResourceManagerStubActivity";
+    private final Object mFinishEvent = new Object();
+    private int[] mRequestCodes = {0, 1};
+    private boolean[] mResults = {false, false};
+    private int mNumResults = 0;
+    private int mType1 = ResourceManagerTestActivityBase.TYPE_NONSECURE;
+    private int mType2 = ResourceManagerTestActivityBase.TYPE_NONSECURE;
+    private boolean mWaitForReclaim = true;
+
+    private static final String ERROR_INSUFFICIENT_RESOURCES =
+            "* Please check if the omx component is returning OMX_ErrorInsufficientResources " +
+            "properly when the codec failure is due to insufficient resource.\n";
+    private static final String ERROR_SUPPORTS_MULTIPLE_SECURE_CODECS =
+            "* Please check if this platform supports multiple concurrent secure codec " +
+            "instances. If not, please add below setting in /etc/media_codecs.xml in order " +
+            "to pass the test:\n" +
+            "    <Settings>\n" +
+            "       <Setting name=\"supports-multiple-secure-codecs\" value=\"false\" />\n" +
+            "    </Settings>\n";
+    private static final String ERROR_SUPPORTS_SECURE_WITH_NON_SECURE_CODEC =
+            "* Please check if this platform supports co-exist of secure and non-secure codec. " +
+            "If not, please add below setting in /etc/media_codecs.xml in order to pass the " +
+            "test:\n" +
+            "    <Settings>\n" +
+            "       <Setting name=\"supports-secure-with-non-secure-codec\" value=\"false\" />\n" +
+            "    </Settings>\n";
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+        Log.d(TAG, "Activity " + requestCode + " finished with resultCode " + resultCode);
+        mResults[requestCode] = (resultCode == RESULT_OK);
+        if (++mNumResults == mResults.length) {
+            synchronized (mFinishEvent) {
+                mFinishEvent.notify();
+            }
+        }
+    }
+
+    public void testReclaimResource(int type1, int type2) throws InterruptedException {
+        mType1 = type1;
+        mType2 = type2;
+        if (type1 != ResourceManagerTestActivityBase.TYPE_MIX && type1 != type2) {
+            // in this case, activity2 may not need to reclaim codec from activity1.
+            mWaitForReclaim = false;
+        } else {
+            mWaitForReclaim = true;
+        }
+        Thread thread = new Thread() {
+            @Override
+            public void run() {
+                try {
+                    Context context = getApplicationContext();
+                    Intent intent1 = new Intent(context, ResourceManagerTestActivity1.class);
+                    intent1.putExtra("test-type", mType1);
+                    intent1.putExtra("wait-for-reclaim", mWaitForReclaim);
+                    startActivityForResult(intent1, mRequestCodes[0]);
+                    Thread.sleep(5000);  // wait for process to launch and allocate all codecs.
+
+                    Intent intent2 = new Intent(context, ResourceManagerTestActivity2.class);
+                    intent2.putExtra("test-type", mType2);
+                    startActivityForResult(intent2, mRequestCodes[1]);
+
+                    synchronized (mFinishEvent) {
+                        mFinishEvent.wait();
+                    }
+                } catch(Exception e) {
+                    Log.d(TAG, "testReclaimResource got exception " + e.toString());
+                }
+            }
+        };
+        thread.start();
+        thread.join(20000 /* millis */);
+        System.gc();
+        Thread.sleep(5000);  // give the gc a chance to release test activities.
+
+        boolean result = true;
+        for (int i = 0; i < mResults.length; ++i) {
+            if (!mResults[i]) {
+                Log.e(TAG, "Result from activity " + i + " is a fail.");
+                result = false;
+                break;
+            }
+        }
+        if (!result) {
+            String failMessage = "The potential reasons for the failure:\n";
+            StringBuilder reasons = new StringBuilder();
+            reasons.append(ERROR_INSUFFICIENT_RESOURCES);
+            if (mType1 != mType2) {
+                reasons.append(ERROR_SUPPORTS_SECURE_WITH_NON_SECURE_CODEC);
+            }
+            if (mType1 == ResourceManagerTestActivityBase.TYPE_MIX &&
+                    mType2 == ResourceManagerTestActivityBase.TYPE_SECURE) {
+                reasons.append(ERROR_SUPPORTS_MULTIPLE_SECURE_CODECS);
+            }
+            Assert.assertTrue(failMessage + reasons.toString(), result);
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/ResourceManagerTest.java b/tests/tests/media/src/android/media/cts/ResourceManagerTest.java
new file mode 100644
index 0000000..7305651
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ResourceManagerTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.media.cts;
+
+import android.os.Bundle;
+import android.test.ActivityInstrumentationTestCase2;
+
+public class ResourceManagerTest
+        extends ActivityInstrumentationTestCase2<ResourceManagerStubActivity> {
+
+    public ResourceManagerTest() {
+        super("com.android.cts.media", 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);
+        activity.testReclaimResource(type1, type2);
+        activity.finish();
+    }
+
+    public void testReclaimResourceNonsecureVsNonsecure() throws Exception {
+        doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
+                ResourceManagerTestActivityBase.TYPE_NONSECURE);
+    }
+
+    public void testReclaimResourceNonsecureVsSecure() throws Exception {
+        doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_NONSECURE,
+                ResourceManagerTestActivityBase.TYPE_SECURE);
+    }
+
+    public void testReclaimResourceSecureVsNonsecure() throws Exception {
+        doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
+                ResourceManagerTestActivityBase.TYPE_NONSECURE);
+    }
+
+    public void testReclaimResourceSecureVsSecure() throws Exception {
+        doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_SECURE,
+                ResourceManagerTestActivityBase.TYPE_SECURE);
+    }
+
+    public void testReclaimResourceMixVsNonsecure() throws Exception {
+        doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
+                ResourceManagerTestActivityBase.TYPE_NONSECURE);
+    }
+
+    public void testReclaimResourceMixVsSecure() throws Exception {
+        doTestReclaimResource(ResourceManagerTestActivityBase.TYPE_MIX,
+                ResourceManagerTestActivityBase.TYPE_SECURE);
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/ResourceManagerTestActivity1.java b/tests/tests/media/src/android/media/cts/ResourceManagerTestActivity1.java
new file mode 100644
index 0000000..a11d773
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ResourceManagerTestActivity1.java
@@ -0,0 +1,46 @@
+/*
+ * 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.media.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+public class ResourceManagerTestActivity1 extends ResourceManagerTestActivityBase {
+    private static final int MAX_INSTANCES = 32;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        TAG = "ResourceManagerTestActivity1";
+
+        Log.d(TAG, "onCreate called.");
+        super.onCreate(savedInstanceState);
+        moveTaskToBack(true);
+
+        Bundle extras = getIntent().getExtras();
+        if (extras != null) {
+            mWaitForReclaim = extras.getBoolean("wait-for-reclaim", mWaitForReclaim);
+        }
+
+        if (allocateCodecs(MAX_INSTANCES) == MAX_INSTANCES) {
+            // haven't reached the limit with MAX_INSTANCES, no need to wait for reclaim exception.
+            mWaitForReclaim = false;
+        }
+
+        useCodecs();
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/ResourceManagerTestActivity2.java b/tests/tests/media/src/android/media/cts/ResourceManagerTestActivity2.java
new file mode 100644
index 0000000..79d0d2d
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ResourceManagerTestActivity2.java
@@ -0,0 +1,34 @@
+/*
+ * 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.media.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+
+public class ResourceManagerTestActivity2 extends ResourceManagerTestActivityBase {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        TAG = "ResourceManagerTestActivity2";
+
+        Log.d(TAG, "onCreate called.");
+        super.onCreate(savedInstanceState);
+
+        int result = (allocateCodecs(1 /* max */) == 1) ? RESULT_OK : RESULT_CANCELED;
+        finishWithResult(result);
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/ResourceManagerTestActivityBase.java b/tests/tests/media/src/android/media/cts/ResourceManagerTestActivityBase.java
new file mode 100644
index 0000000..689babb
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/ResourceManagerTestActivityBase.java
@@ -0,0 +1,257 @@
+/*
+ * 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.media.cts;
+
+import android.app.Activity;
+import android.media.MediaCodec;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.VideoCapabilities;
+import android.media.MediaCodecList;
+import android.media.MediaFormat;
+import android.os.Bundle;
+import android.util.Log;
+import java.io.IOException;
+import java.util.Vector;
+
+public class ResourceManagerTestActivityBase extends Activity {
+    public static final int TYPE_NONSECURE = 0;
+    public static final int TYPE_SECURE = 1;
+    public static final int TYPE_MIX = 2;
+
+    protected String TAG;
+    private static final int FRAME_RATE = 10;
+    private static final int IFRAME_INTERVAL = 10;  // 10 seconds between I-frames
+    private static final String MIME = MediaFormat.MIMETYPE_VIDEO_AVC;
+
+    private Vector<MediaCodec> mCodecs = new Vector<MediaCodec>();
+
+    private class TestCodecCallback extends MediaCodec.Callback {
+        @Override
+        public void onInputBufferAvailable(MediaCodec codec, int index) {
+            Log.d(TAG, "onInputBufferAvailable " + codec.toString());
+        }
+
+        @Override
+        public void onOutputBufferAvailable(
+                MediaCodec codec, int index, MediaCodec.BufferInfo info) {
+            Log.d(TAG, "onOutputBufferAvailable " + codec.toString());
+        }
+
+        @Override
+        public void onError(MediaCodec codec, MediaCodec.CodecException e) {
+            Log.d(TAG, "onError " + codec.toString() + " errorCode " + e.getErrorCode());
+        }
+
+        @Override
+        public void onOutputFormatChanged(MediaCodec codec, MediaFormat format) {
+            Log.d(TAG, "onOutputFormatChanged " + codec.toString());
+        }
+    }
+
+    private MediaCodec.Callback mCallback = new TestCodecCallback();
+
+    private MediaFormat getTestFormat(CodecCapabilities caps, boolean securePlayback) {
+        VideoCapabilities vcaps = caps.getVideoCapabilities();
+        int width = vcaps.getSupportedWidths().getLower();
+        int height = vcaps.getSupportedHeightsFor(width).getLower();
+        int bitrate = vcaps.getBitrateRange().getLower();
+
+        MediaFormat format = MediaFormat.createVideoFormat(MIME, width, height);
+        format.setInteger(MediaFormat.KEY_COLOR_FORMAT, caps.colorFormats[0]);
+        format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+        format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE);
+        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, IFRAME_INTERVAL);
+        format.setFeatureEnabled(CodecCapabilities.FEATURE_SecurePlayback, securePlayback);
+        return format;
+    }
+
+    private MediaCodecInfo getTestCodecInfo(boolean securePlayback) {
+        // Use avc decoder for testing.
+        boolean isEncoder = false;
+
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.ALL_CODECS);
+        for (MediaCodecInfo info : mcl.getCodecInfos()) {
+            if (info.isEncoder() != isEncoder) {
+                continue;
+            }
+            CodecCapabilities caps;
+            try {
+                caps = info.getCapabilitiesForType(MIME);
+                boolean securePlaybackSupported =
+                        caps.isFeatureSupported(CodecCapabilities.FEATURE_SecurePlayback);
+                boolean securePlaybackRequired =
+                        caps.isFeatureRequired(CodecCapabilities.FEATURE_SecurePlayback);
+                if ((securePlayback && securePlaybackSupported) ||
+                        (!securePlayback && !securePlaybackRequired) ) {
+                    Log.d(TAG, "securePlayback " + securePlayback + " will use " + info.getName());
+                } else {
+                    Log.d(TAG, "securePlayback " + securePlayback + " skip " + info.getName());
+                    continue;
+                }
+            } catch (IllegalArgumentException e) {
+                // mime is not supported
+                continue;
+            }
+            return info;
+        }
+
+        return null;
+    }
+
+    protected int allocateCodecs(int max) {
+        Bundle extras = getIntent().getExtras();
+        int type = TYPE_NONSECURE;
+        if (extras != null) {
+            type = extras.getInt("test-type", type);
+            Log.d(TAG, "type is: " + type);
+        }
+
+        boolean shouldSkip = false;
+        boolean securePlayback;
+        if (type == TYPE_NONSECURE || type == TYPE_MIX) {
+            securePlayback = false;
+            MediaCodecInfo info = getTestCodecInfo(securePlayback);
+            if (info != null) {
+                allocateCodecs(max, info, securePlayback);
+            } else {
+                shouldSkip = true;
+            }
+        }
+
+        if (!shouldSkip) {
+            if (type == TYPE_SECURE || type == TYPE_MIX) {
+                securePlayback = true;
+                MediaCodecInfo info = getTestCodecInfo(securePlayback);
+                if (info != null) {
+                    allocateCodecs(max, info, securePlayback);
+                } else {
+                    shouldSkip = true;
+                }
+            }
+        }
+
+        if (shouldSkip) {
+            Log.d(TAG, "test skipped as there's no supported codec.");
+            finishWithResult(RESULT_OK);
+        }
+
+        Log.d(TAG, "allocateCodecs returned " + mCodecs.size());
+        return mCodecs.size();
+    }
+
+    protected void allocateCodecs(int max, MediaCodecInfo info, boolean securePlayback) {
+        String name = info.getName();
+        CodecCapabilities caps = info.getCapabilitiesForType(MIME);
+        MediaFormat format = getTestFormat(caps, securePlayback);
+        MediaCodec codec = null;
+        for (int i = mCodecs.size(); i < max; ++i) {
+            try {
+                Log.d(TAG, "Create codec " + name + " #" + i);
+                codec = MediaCodec.createByCodecName(name);
+                codec.setCallback(mCallback);
+                Log.d(TAG, "Configure codec " + format);
+                codec.configure(format, null, null, 0);
+                Log.d(TAG, "Start codec " + format);
+                codec.start();
+                mCodecs.add(codec);
+                codec = null;
+            } catch (IllegalArgumentException e) {
+                Log.d(TAG, "IllegalArgumentException " + e.getMessage());
+                break;
+            } catch (IOException e) {
+                Log.d(TAG, "IOException " + e.getMessage());
+                break;
+            } catch (MediaCodec.CodecException e) {
+                Log.d(TAG, "CodecException 0x" + Integer.toHexString(e.getErrorCode()));
+                break;
+            } finally {
+                if (codec != null) {
+                    Log.d(TAG, "release codec");
+                    codec.release();
+                    codec = null;
+                }
+            }
+        }
+    }
+
+    protected void finishWithResult(int result) {
+        for (int i = 0; i < mCodecs.size(); ++i) {
+            Log.d(TAG, "release codec #" + i);
+            mCodecs.get(i).release();
+        }
+        mCodecs.clear();
+        setResult(result);
+        finish();
+        Log.d(TAG, "activity finished");
+    }
+
+    private void doUseCodecs() {
+        int current = 0;
+        try {
+            for (current = 0; current < mCodecs.size(); ++current) {
+                mCodecs.get(current).getName();
+            }
+        } catch (MediaCodec.CodecException e) {
+            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.remove(current);
+                mGotReclaimedException = true;
+                mUseCodecs = false;
+            }
+            return;
+        }
+    }
+
+    protected boolean mWaitForReclaim = true;
+    private Thread mWorkerThread;
+    private volatile boolean mUseCodecs = true;
+    private volatile boolean mGotReclaimedException = false;
+    protected void useCodecs() {
+        mWorkerThread = new Thread(new Runnable() {
+            @Override
+            public void run() {
+                long start = System.currentTimeMillis();
+                long timeSinceStartedMs = 0;
+                while (mUseCodecs && (timeSinceStartedMs < 15000)) {  // timeout in 15s
+                    doUseCodecs();
+                    try {
+                        Thread.sleep(50 /* millis */);
+                    } catch (InterruptedException e) {}
+                    timeSinceStartedMs = System.currentTimeMillis() - start;
+                }
+                if (mGotReclaimedException) {
+                    Log.d(TAG, "Got expected reclaim exception.");
+                    finishWithResult(RESULT_OK);
+                } else {
+                    Log.d(TAG, "Stopped without getting reclaim exception.");
+                    // if the test is supposed to wait for reclaim event then this is a failure,
+                    // otherwise this is a pass.
+                    finishWithResult(mWaitForReclaim ? RESULT_CANCELED : RESULT_OK);
+                }
+            }
+        });
+        mWorkerThread.start();
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.d(TAG, "onDestroy called.");
+        super.onDestroy();
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java b/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
index bf47a27..4693036 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneManagerTest.java
@@ -55,6 +55,7 @@
         mActivity = getActivity();
         mInstrumentation = getInstrumentation();
         mContext = mInstrumentation.getContext();
+        Utils.enableAppOps(mContext.getPackageName(), "android:write_settings", mInstrumentation);
         mRingtoneManager = new RingtoneManager(mActivity);
         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
         // backup ringer settings
@@ -74,6 +75,7 @@
         }
         RingtoneManager.setActualDefaultRingtoneUri(mContext, RingtoneManager.TYPE_RINGTONE,
                 mDefaultUri);
+        Utils.disableAppOps(mContext.getPackageName(), "android:write_settings", mInstrumentation);
         super.tearDown();
     }
 
diff --git a/tests/tests/media/src/android/media/cts/RingtoneTest.java b/tests/tests/media/src/android/media/cts/RingtoneTest.java
index f5218e3..3527b1a 100644
--- a/tests/tests/media/src/android/media/cts/RingtoneTest.java
+++ b/tests/tests/media/src/android/media/cts/RingtoneTest.java
@@ -16,6 +16,7 @@
 
 package android.media.cts;
 
+import android.app.UiAutomation;
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.media.AudioManager;
@@ -23,10 +24,10 @@
 import android.media.RingtoneManager;
 import android.net.Uri;
 import android.provider.Settings;
-import android.test.AndroidTestCase;
+import android.test.InstrumentationTestCase;
 import android.util.Log;
 
-public class RingtoneTest extends AndroidTestCase {
+public class RingtoneTest extends InstrumentationTestCase {
     private static final String TAG = "RingtoneTest";
 
     private Context mContext;
@@ -40,7 +41,8 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mContext = getContext();
+        enableAppOps();
+        mContext = getInstrumentation().getContext();
         mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
         mRingtone = RingtoneManager.getRingtone(mContext, Settings.System.DEFAULT_RINGTONE_URI);
         // backup ringer settings
@@ -58,6 +60,18 @@
                 RingtoneManager.TYPE_RINGTONE);
     }
 
+    private void enableAppOps() {
+        StringBuilder cmd = new StringBuilder();
+        cmd.append("appops set ");
+        cmd.append(getInstrumentation().getContext().getPackageName());
+        cmd.append(" android:write_settings allow");
+        getInstrumentation().getUiAutomation().executeShellCommand(cmd.toString());
+        try {
+            Thread.sleep(2200);
+        } catch (InterruptedException e) {
+        }
+    }
+
     @Override
     protected void tearDown() throws Exception {
         // restore original settings
@@ -76,7 +90,7 @@
     }
 
     private boolean hasAudioOutput() {
-        return getContext().getPackageManager()
+        return getInstrumentation().getContext().getPackageManager()
             .hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT);
     }
 
diff --git a/tests/tests/media/src/android/media/cts/RoutingTest.java b/tests/tests/media/src/android/media/cts/RoutingTest.java
new file mode 100644
index 0000000..c0e9a3e
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/RoutingTest.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.content.pm.PackageManager;
+
+import android.media.AudioDeviceInfo;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+import android.media.AudioTrack;
+import android.media.MediaRecorder;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import android.test.AndroidTestCase;
+
+import android.util.Log;
+
+import java.lang.Runnable;
+
+/**
+ * TODO: Insert description here. (generated by pmclean)
+ */
+public class RoutingTest extends AndroidTestCase {
+    private static final String TAG = "RoutingTest";
+
+    private AudioManager mAudioManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        // get the AudioManager
+        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        assertNotNull(mAudioManager);
+    }
+
+    private AudioTrack allocAudioTrack() {
+        int bufferSize =
+                AudioTrack.getMinBufferSize(
+                    41000,
+                    AudioFormat.CHANNEL_OUT_STEREO,
+                    AudioFormat.ENCODING_PCM_16BIT);
+        AudioTrack audioTrack =
+            new AudioTrack(
+                AudioManager.STREAM_MUSIC,
+                41000,
+                AudioFormat.CHANNEL_OUT_STEREO,
+                AudioFormat.ENCODING_PCM_16BIT,
+                bufferSize,
+                AudioTrack.MODE_STREAM);
+        return audioTrack;
+    }
+
+    public void test_audioTrack_preferredDevice() {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUDIO_OUTPUT)) {
+            // Can't do it so skip this test
+            return;
+        }
+
+        AudioTrack audioTrack = allocAudioTrack();
+        assertNotNull(audioTrack);
+
+        // None selected (new AudioTrack), so check for default
+        assertNull(audioTrack.getPreferredDevice());
+
+        // resets to default
+        assertTrue(audioTrack.setPreferredDevice(null));
+
+        // test each device
+        AudioDeviceInfo[] deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS);
+        for (int index = 0; index < deviceList.length; index++) {
+            assertTrue(audioTrack.setPreferredDevice(deviceList[index]));
+            assertTrue(audioTrack.getPreferredDevice() == deviceList[index]);
+        }
+
+        // Check defaults again
+        assertTrue(audioTrack.setPreferredDevice(null));
+        assertNull(audioTrack.getPreferredDevice());
+
+        audioTrack.release();
+    }
+
+    /*
+     * tests if the Looper for the current thread has been prepared,
+     * If not, it makes one, prepares it and returns it.
+     * If this returns non-null, the caller is reponsible for calling quit()
+     * on the returned Looper.
+     */
+    private Looper prepareIfNeededLooper() {
+        // non-null Handler
+        Looper myLooper = null;
+        if (Looper.myLooper() == null) {
+            Looper.prepare();
+            myLooper = Looper.myLooper();
+            assertNotNull(myLooper);
+        }
+        return myLooper;
+    }
+
+    private class AudioTrackRoutingListener implements AudioTrack.OnRoutingChangedListener {
+        public void onRoutingChanged(AudioTrack audioTrack) {}
+    }
+
+    public void test_audioTrack_RoutingListener() {
+        AudioTrack audioTrack = allocAudioTrack();
+
+        audioTrack.addOnRoutingChangedListener(null, null);
+
+        AudioTrackRoutingListener listener = new AudioTrackRoutingListener();
+        AudioTrackRoutingListener someOtherListener = new AudioTrackRoutingListener();
+
+        audioTrack.addOnRoutingChangedListener(listener, null);
+
+        // remove a listener we didn't add
+        audioTrack.removeOnRoutingChangedListener(someOtherListener);
+
+        audioTrack.removeOnRoutingChangedListener(listener);
+
+        Looper myLooper = prepareIfNeededLooper();
+        audioTrack.addOnRoutingChangedListener(listener, new Handler());
+
+        audioTrack.removeOnRoutingChangedListener(listener);
+
+        audioTrack.release();
+        if (myLooper != null) {
+            myLooper.quit();
+        }
+   }
+
+    private AudioRecord allocAudioRecord() {
+        int bufferSize =
+                AudioRecord.getMinBufferSize(
+                    41000,
+                    AudioFormat.CHANNEL_OUT_DEFAULT,
+                    AudioFormat.ENCODING_PCM_16BIT);
+        AudioRecord audioRecord =
+            new AudioRecord(
+                MediaRecorder.AudioSource.DEFAULT,
+                41000, AudioFormat.CHANNEL_OUT_DEFAULT,
+                AudioFormat.ENCODING_PCM_16BIT,
+                bufferSize);
+        return audioRecord;
+    }
+
+    private class AudioRecordRoutingListener implements AudioRecord.OnRoutingChangedListener {
+        public void onRoutingChanged(AudioRecord audioRecord) {}
+    }
+
+    public void test_audioRecord_RoutingListener() {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
+            // Can't do it so skip this test
+            return;
+        }
+        AudioRecord audioRecord = allocAudioRecord();
+
+        audioRecord.addOnRoutingChangedListener(null, null);
+
+        AudioRecordRoutingListener listener = new AudioRecordRoutingListener();
+        AudioRecordRoutingListener someOtherListener = new AudioRecordRoutingListener();
+
+        audioRecord.addOnRoutingChangedListener(listener, null);
+
+        // remove a listener we didn't add
+        audioRecord.removeOnRoutingChangedListener(someOtherListener);
+
+        audioRecord.removeOnRoutingChangedListener(listener);
+
+        Looper myLooper = prepareIfNeededLooper();
+        audioRecord.addOnRoutingChangedListener(listener, new Handler());
+
+        audioRecord.removeOnRoutingChangedListener(listener);
+
+        audioRecord.release();
+        if (myLooper != null) {
+            myLooper.quit();
+        }
+    }
+
+    public void test_audioRecord_preferredDevice() {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
+            // Can't do it so skip this test
+            return;
+        }
+
+        AudioRecord audioRecord = allocAudioRecord();
+        assertNotNull(audioRecord);
+
+        // None selected (new AudioRecord), so check for default
+        assertNull(audioRecord.getPreferredDevice());
+
+        // resets to default
+        assertTrue(audioRecord.setPreferredDevice(null));
+
+        // test each device
+        AudioDeviceInfo[] deviceList = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
+        for (int index = 0; index < deviceList.length; index++) {
+            assertTrue(audioRecord.setPreferredDevice(deviceList[index]));
+            assertTrue(audioRecord.getPreferredDevice() == deviceList[index]);
+        }
+
+        // Check defaults again
+        assertTrue(audioRecord.setPreferredDevice(null));
+        assertNull(audioRecord.getPreferredDevice());
+
+        audioRecord.release();
+    }
+
+    private class AudioTrackFiller implements Runnable {
+        AudioTrack mAudioTrack;
+        int mBufferSize;
+
+        boolean mPlaying;
+
+        short[] mAudioData;
+
+        public AudioTrackFiller(AudioTrack audioTrack, int bufferSize) {
+            mAudioTrack = audioTrack;
+            mBufferSize = bufferSize;
+            mPlaying = false;
+
+            // setup audio data (silence will suffice)
+            mAudioData = new short[mBufferSize];
+            for (int index = 0; index < mBufferSize; index++) {
+                mAudioData[index] = 0;
+            }
+        }
+
+        public void start() { mPlaying = true; }
+        public void stop() { mPlaying = false; }
+
+        @Override
+        public void run() {
+            while (mAudioTrack != null && mPlaying) {
+                mAudioTrack.write(mAudioData, 0, mBufferSize);
+            }
+        }
+    }
+
+    public void test_audioTrack_getRoutedDevice() {
+        int bufferSize =
+                AudioTrack.getMinBufferSize(
+                    41000,
+                    AudioFormat.CHANNEL_OUT_STEREO,
+                    AudioFormat.ENCODING_PCM_16BIT);
+        AudioTrack audioTrack =
+            new AudioTrack(
+                AudioManager.STREAM_MUSIC,
+                41000,
+                AudioFormat.CHANNEL_OUT_STEREO,
+                AudioFormat.ENCODING_PCM_16BIT,
+                bufferSize,
+                AudioTrack.MODE_STREAM);
+
+        AudioTrackFiller filler = new AudioTrackFiller(audioTrack, bufferSize);
+        filler.start();
+
+        audioTrack.play();
+
+        Thread fillerThread = new Thread(filler);
+        fillerThread.start();
+
+        try { Thread.sleep(1000); } catch (InterruptedException ex) {}
+
+        // No explicit route
+        AudioDeviceInfo routedDevice = audioTrack.getRoutedDevice();
+        assertNotNull(routedDevice); // we probably can't say anything more than this
+
+        filler.stop();
+        audioTrack.stop();
+        audioTrack.release();
+    }
+
+    private class AudioRecordPuller implements Runnable {
+        AudioRecord mAudioRecord;
+        int mBufferSize;
+
+        boolean mRecording;
+
+        short[] mAudioData;
+
+        public AudioRecordPuller(AudioRecord audioRecord, int bufferSize) {
+            mAudioRecord = audioRecord;
+            mBufferSize = bufferSize;
+            mRecording = false;
+        }
+
+        public void start() { mRecording = true; }
+        public void stop() { mRecording = false; }
+
+        @Override
+        public void run() {
+            while (mAudioRecord != null && mRecording) {
+                mAudioRecord.read(mAudioData, 0, mBufferSize);
+           }
+        }
+    }
+
+    public void test_audioRecord_getRoutedDevice() {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) {
+            return;
+        }
+
+        int bufferSize =
+                AudioRecord.getMinBufferSize(
+                    41000,
+                    AudioFormat.CHANNEL_OUT_DEFAULT,
+                    AudioFormat.ENCODING_PCM_16BIT);
+        AudioRecord audioRecord =
+            new AudioRecord(
+                MediaRecorder.AudioSource.DEFAULT,
+                41000, AudioFormat.CHANNEL_OUT_DEFAULT,
+                AudioFormat.ENCODING_PCM_16BIT,
+                bufferSize);
+
+        AudioRecordPuller puller = new AudioRecordPuller(audioRecord, bufferSize);
+        puller.start();
+
+        audioRecord.startRecording();
+
+        Thread pullerThread = new Thread(puller);
+        pullerThread.start();
+
+        try { Thread.sleep(1000); } catch (InterruptedException ex) {}
+
+        // No explicit route
+        AudioDeviceInfo routedDevice = audioRecord.getRoutedDevice();
+        assertNotNull(routedDevice); // we probably can't say anything more than this
+
+        puller.stop();
+        audioRecord.stop();
+        audioRecord.release();
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/SoundPoolTest.java b/tests/tests/media/src/android/media/cts/SoundPoolTest.java
index 15d18a0..23c4a7c 100644
--- a/tests/tests/media/src/android/media/cts/SoundPoolTest.java
+++ b/tests/tests/media/src/android/media/cts/SoundPoolTest.java
@@ -21,6 +21,7 @@
 
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
+import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.SoundPool;
 import android.test.AndroidTestCase;
@@ -29,6 +30,8 @@
 import java.io.FileDescriptor;
 import java.io.FileOutputStream;
 import java.io.InputStream;
+import java.util.Arrays;
+import java.util.concurrent.atomic.AtomicInteger;
 
 abstract class SoundPoolTest extends AndroidTestCase {
 
@@ -230,6 +233,104 @@
         mSoundPool.release();
     }
 
+    public void testAutoPauseResume() throws Exception {
+        // The number of possible SoundPool streams simultaneously active is limited by
+        // track resources. Generally this is no greater than 32, but the actual
+        // amount may be less depending on concurrently running applications.
+        // Here we attempt to create more streams than what is normally possible;
+        // SoundPool should gracefully degrade to play those streams it can.
+        //
+        // Try to keep the maxStreams less than the number required to be active
+        // and certainly less than 20 to be cooperative to other applications.
+        final int TEST_STREAMS = 40;
+        SoundPool soundPool = null;
+        try {
+            soundPool = new SoundPool.Builder()
+                    .setAudioAttributes(new AudioAttributes.Builder().build())
+                    .setMaxStreams(TEST_STREAMS)
+                    .build();
+
+            // get our sounds
+            final int[] sounds = getSounds();
+
+            // set our completion listener
+            final int[] loadIds = new int[TEST_STREAMS];
+            final Object done = new Object();
+            final int[] loaded = new int[1]; // used as a "pointer" to an integer
+            final SoundPool fpool = soundPool; // final reference in scope of try block
+            soundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() {
+                    @Override
+                    public void onLoadComplete(SoundPool pool, int sampleId, int status) {
+                        assertEquals(fpool, pool);
+                        assertEquals(0 /* success */, status);
+                        synchronized(done) {
+                            loadIds[loaded[0]++] = sampleId;
+                            if (loaded[0] == loadIds.length) {
+                                done.notify();
+                            }
+                        }
+                    }
+                });
+
+            // initiate loading
+            final int[] soundIds = new int[TEST_STREAMS];
+            for (int i = 0; i < soundIds.length; i++) {
+                soundIds[i] = soundPool.load(mContext, sounds[i % sounds.length], PRIORITY);
+            }
+
+            // wait for all sounds to load
+            final long LOAD_TIMEOUT_IN_MS = 10000;
+            final long startTime = System.currentTimeMillis();
+            synchronized(done) {
+                while (loaded[0] != soundIds.length) {
+                    final long waitTime =
+                            LOAD_TIMEOUT_IN_MS - (System.currentTimeMillis() - startTime);
+                    assertTrue(waitTime > 0);
+                    done.wait(waitTime);
+                }
+            }
+
+            // verify the Ids match (actually does sorting too)
+            Arrays.sort(loadIds);
+            Arrays.sort(soundIds);
+            assertTrue(Arrays.equals(loadIds, soundIds));
+
+            // play - should hear the following:
+            // 1 second of sound
+            // 1 second of silence
+            // 1 second of sound.
+            int[] streamIds = new int[soundIds.length];
+            for (int i = 0; i < soundIds.length; i++) {
+                streamIds[i] = soundPool.play(soundIds[i],
+                        0.5f /* leftVolume */, 0.5f /* rightVolume */, PRIORITY,
+                        -1 /* loop (infinite) */, 1.0f /* rate */);
+            }
+            Thread.sleep(1000 /* millis */);
+            soundPool.autoPause();
+            Thread.sleep(1000 /* millis */);
+            soundPool.autoResume();
+            Thread.sleep(1000 /* millis */);
+
+            // clean up
+            for (int stream : streamIds) {
+                assertTrue(stream != 0);
+                soundPool.stop(stream);
+            }
+            for (int sound : soundIds) {
+                assertEquals(true, soundPool.unload(sound));
+            }
+            // check to see we're really unloaded
+            for (int sound : soundIds) {
+                assertEquals(false, soundPool.unload(sound));
+            }
+        } finally {
+            if (soundPool != null) {
+                soundPool.release();
+                soundPool = null;
+            }
+        }
+    }
+
     /**
      * Load a sample and wait until it is ready to be played.
      * @return The sample ID.
diff --git a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
index dd7c1f6..ce61d76 100644
--- a/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
+++ b/tests/tests/media/src/android/media/cts/StreamingMediaPlayerTest.java
@@ -18,12 +18,16 @@
 import android.cts.util.MediaUtils;
 import android.media.MediaFormat;
 import android.media.MediaPlayer;
+import android.media.MediaPlayer.TrackInfo;
+import android.media.TimedMetaData;
 import android.os.Looper;
+import android.os.PowerManager;
 import android.os.SystemClock;
 import android.util.Log;
 import android.webkit.cts.CtsTestServer;
 
 import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * Tests of MediaPlayer streaming capabilities.
@@ -307,6 +311,99 @@
         localHlsTest("hls.m3u8", false, true);
     }
 
+    public void testPlayHlsStreamWithTimedId3() throws Throwable {
+        if (!MediaUtils.checkDecoder(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+            Log.d(TAG, "Device doesn't have video codec, skipping test");
+            return;
+        }
+
+        mServer = new CtsTestServer(mContext);
+        try {
+            // counter must be final if we want to access it inside onTimedMetaData;
+            // use AtomicInteger so we can have a final counter object with mutable integer value.
+            final AtomicInteger counter = new AtomicInteger();
+            String stream_url = mServer.getAssetUrl("prog_index.m3u8");
+            mMediaPlayer.setDataSource(stream_url);
+            mMediaPlayer.setDisplay(getActivity().getSurfaceHolder());
+            mMediaPlayer.setScreenOnWhilePlaying(true);
+            mMediaPlayer.setWakeMode(mContext, PowerManager.PARTIAL_WAKE_LOCK);
+            mMediaPlayer.setOnTimedMetaDataAvailableListener(new MediaPlayer.OnTimedMetaDataAvailableListener() {
+                @Override
+                public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData md) {
+                    counter.incrementAndGet();
+                    int pos = mp.getCurrentPosition();
+                    long timeUs = md.getTimestamp();
+                    byte[] rawData = md.getMetaData();
+                    // Raw data contains an id3 tag holding the decimal string representation of
+                    // the associated time stamp rounded to the closest half second.
+
+                    int offset = 0;
+                    offset += 3; // "ID3"
+                    offset += 2; // version
+                    offset += 1; // flags
+                    offset += 4; // size
+                    offset += 4; // "TXXX"
+                    offset += 4; // frame size
+                    offset += 2; // frame flags
+                    offset += 1; // "\x03" : UTF-8 encoded Unicode
+                    offset += 1; // "\x00" : null-terminated empty description
+
+                    int length = rawData.length;
+                    length -= offset;
+                    length -= 1; // "\x00" : terminating null
+
+                    String data = new String(rawData, offset, length);
+                    int dataTimeUs = Integer.parseInt(data);
+                    assertTrue("Timed ID3 timestamp does not match content",
+                            Math.abs(dataTimeUs - timeUs) < 500000);
+                    assertTrue("Timed ID3 arrives after timestamp", pos * 1000 < timeUs);
+                }
+            });
+
+            final Object completion = new Object();
+            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+                int run;
+                @Override
+                public void onCompletion(MediaPlayer mp) {
+                    if (run++ == 0) {
+                        mMediaPlayer.seekTo(0);
+                        mMediaPlayer.start();
+                    } else {
+                        mMediaPlayer.stop();
+                        synchronized (completion) {
+                            completion.notify();
+                        }
+                    }
+                }
+            });
+
+            mMediaPlayer.prepare();
+            mMediaPlayer.start();
+            assertTrue("MediaPlayer not playing", mMediaPlayer.isPlaying());
+
+            int i = -1;
+            TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo();
+            for (i = 0; i < trackInfos.length; i++) {
+                TrackInfo trackInfo = trackInfos[i];
+                if (trackInfo.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_METADATA) {
+                    break;
+                }
+            }
+            assertTrue("Stream has no timed ID3 track", i >= 0);
+            mMediaPlayer.selectTrack(i);
+
+            synchronized (completion) {
+                completion.wait();
+            }
+
+            // There are a total of 19 metadata access units in the test stream; every one of them
+            // should be received twice: once before the seek and once after.
+            assertTrue("Incorrect number of timed ID3s recieved", counter.get() == 38);
+        } finally {
+            mServer.shutdown();
+        }
+    }
+
     private static class WorkerWithPlayer implements Runnable {
         private final Object mLock = new Object();
         private Looper mLooper;
diff --git a/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java b/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java
index 35e88f0..b5ba715 100644
--- a/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java
+++ b/tests/tests/media/src/android/media/cts/StubMediaBrowserService.java
@@ -46,7 +46,8 @@
 
     /* package private */ static MediaSession sSession;
     private Bundle mExtras;
-    private Result<List<MediaItem>> mPendingResult;
+    private Result<List<MediaItem>> mPendingLoadChildrenResult;
+    private Result<MediaItem> mPendingLoadItemResult;
 
     @Override
     public void onCreate() {
@@ -73,16 +74,43 @@
             }
             result.sendResult(mediaItems);
         } else if (MEDIA_ID_CHILDREN_DELAYED.equals(parentMediaId)) {
-            Assert.assertNull(mPendingResult);
-            mPendingResult = result;
+            Assert.assertNull(mPendingLoadChildrenResult);
+            mPendingLoadChildrenResult = result;
             result.detach();
         }
     }
 
+    @Override
+    public void onLoadItem(String itemId, Result<MediaItem> result) {
+        if (MEDIA_ID_CHILDREN_DELAYED.equals(itemId)) {
+            mPendingLoadItemResult = result;
+            result.detach();
+            return;
+        }
+
+        for (String id : MEDIA_ID_CHILDREN) {
+            if (id.equals(itemId)) {
+                result.sendResult(new MediaItem(new MediaDescription.Builder()
+                        .setMediaId(id).build(), MediaItem.FLAG_BROWSABLE));
+                return;
+            }
+        }
+
+        super.onLoadItem(itemId, result);
+    }
+
     public void sendDelayedNotifyChildrenChanged() {
-        if (mPendingResult != null) {
-            mPendingResult.sendResult(Collections.<MediaItem>emptyList());
-            mPendingResult = null;
+        if (mPendingLoadChildrenResult != null) {
+            mPendingLoadChildrenResult.sendResult(Collections.<MediaItem>emptyList());
+            mPendingLoadChildrenResult = null;
+        }
+    }
+
+    public void sendDelayedItemLoaded() {
+        if (mPendingLoadItemResult != null) {
+            mPendingLoadItemResult.sendResult(new MediaItem(new MediaDescription.Builder()
+                    .setMediaId(MEDIA_ID_CHILDREN_DELAYED).build(), MediaItem.FLAG_BROWSABLE));
+            mPendingLoadItemResult = null;
         }
     }
 }
diff --git a/tests/tests/media/src/android/media/cts/TestMediaDataSource.java b/tests/tests/media/src/android/media/cts/TestMediaDataSource.java
new file mode 100644
index 0000000..a10840b
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/TestMediaDataSource.java
@@ -0,0 +1,126 @@
+/*
+ * 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.media.cts;
+
+import android.content.res.AssetFileDescriptor;
+import android.media.cts.MediaPlayerTestBase.Monitor;
+import android.media.MediaDataSource;
+import android.util.Log;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * A MediaDataSource that reads from a byte array for use in tests.
+ */
+public class TestMediaDataSource extends MediaDataSource {
+    private static final String TAG = "TestMediaDataSource";
+
+    private byte[] mData;
+
+    private boolean mThrowFromReadAt;
+    private boolean mThrowFromGetSize;
+    private Integer mReturnFromReadAt;
+    private Long mReturnFromGetSize;
+    private boolean mIsClosed;
+
+    // Read an asset fd into a new byte array data source. Closes afd.
+    public static TestMediaDataSource fromAssetFd(AssetFileDescriptor afd) throws IOException {
+        try {
+            InputStream in = afd.createInputStream();
+            final int size = (int) afd.getDeclaredLength();
+            byte[] data = new byte[(int) size];
+            int writeIndex = 0;
+            int numRead = 0;
+            do {
+                numRead = in.read(data, writeIndex, size - writeIndex);
+                writeIndex += numRead;
+            } while (numRead >= 0);
+            return new TestMediaDataSource(data);
+        } finally {
+            afd.close();
+        }
+    }
+
+    public TestMediaDataSource(byte[] data) {
+        mData = data;
+    }
+
+    @Override
+    public synchronized int readAt(long position, byte[] buffer, int offset, int size)
+            throws IOException {
+        if (mThrowFromReadAt) {
+            throw new IOException("Test exception from readAt()");
+        }
+        if (mReturnFromReadAt != null) {
+            return mReturnFromReadAt;
+        }
+
+        // Clamp reads past the end of the source.
+        if (position >= mData.length) {
+            return -1; // -1 indicates EOF
+        }
+        if (position + size > mData.length) {
+            size -= (position + size) - mData.length;
+        }
+        System.arraycopy(mData, (int)position, buffer, offset, size);
+        return size;
+    }
+
+    @Override
+    public synchronized long getSize() throws IOException {
+        if (mThrowFromGetSize) {
+            throw new IOException("Test exception from getSize()");
+        }
+        if (mReturnFromGetSize != null) {
+            return mReturnFromGetSize;
+        }
+
+        Log.v(TAG, "getSize: " + mData.length);
+        return mData.length;
+    }
+
+    // Note: it's fine to keep using this data source after closing it.
+    @Override
+    public synchronized void close() {
+        Log.v(TAG, "close()");
+        mIsClosed = true;
+    }
+
+    // Whether close() has been called.
+    public synchronized boolean isClosed() {
+        return mIsClosed;
+    }
+
+    public void throwFromReadAt() {
+        mThrowFromReadAt = true;
+    }
+
+    public void throwFromGetSize() {
+        mThrowFromGetSize = true;
+    }
+
+    public void returnFromReadAt(int numRead) {
+        mReturnFromReadAt = numRead;
+    }
+
+    public void returnFromGetSize(long size) {
+        mReturnFromGetSize = size;
+    }
+}
+
diff --git a/tests/tests/media/src/android/media/cts/Utils.java b/tests/tests/media/src/android/media/cts/Utils.java
new file mode 100644
index 0000000..bb9cf78
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/Utils.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.media.cts;
+
+import android.app.Instrumentation;
+import android.app.UiAutomation;
+import android.os.ParcelFileDescriptor;
+
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Scanner;
+
+public class Utils {
+    public static void enableAppOps(String packageName, String operation,
+            Instrumentation instrumentation) {
+        setAppOps(packageName, operation, instrumentation, true);
+    }
+
+    public static void disableAppOps(String packageName, String operation,
+            Instrumentation instrumentation) {
+        setAppOps(packageName, operation, instrumentation, false);
+    }
+
+    public static String convertStreamToString(InputStream is) {
+        try (Scanner scanner = new Scanner(is).useDelimiter("\\A")) {
+            return scanner.hasNext() ? scanner.next() : "";
+        }
+    }
+
+    private static void setAppOps(String packageName, String operation,
+            Instrumentation instrumentation, boolean enable) {
+        StringBuilder cmd = new StringBuilder();
+        cmd.append("appops set ");
+        cmd.append(packageName);
+        cmd.append(" ");
+        cmd.append(operation);
+        cmd.append(enable ? " allow" : " deny");
+        instrumentation.getUiAutomation().executeShellCommand(cmd.toString());
+
+        StringBuilder query = new StringBuilder();
+        query.append("appops get ");
+        query.append(packageName);
+        query.append(" ");
+        query.append(operation);
+        String queryStr = query.toString();
+
+        String expectedResult = enable ? "allow" : "deny";
+        String result = "";
+        while(!result.contains(expectedResult)) {
+            ParcelFileDescriptor pfd = instrumentation.getUiAutomation().executeShellCommand(
+                                                            queryStr);
+            InputStream inputStream = new FileInputStream(pfd.getFileDescriptor());
+            result = convertStreamToString(inputStream);
+        }
+    }
+}
diff --git a/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
new file mode 100644
index 0000000..8797b9b
--- /dev/null
+++ b/tests/tests/media/src/android/media/cts/VideoDecoderPerfTest.java
@@ -0,0 +1,588 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 com.android.cts.media.R;
+
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources;
+import android.cts.util.DeviceReportLog;
+import android.cts.util.MediaUtils;
+import android.media.MediaCodec;
+import android.media.MediaCodecList;
+import android.media.MediaCodecInfo;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.media.MediaCodecInfo.VideoCapabilities;
+import android.media.MediaExtractor;
+import android.media.MediaFormat;
+import android.util.Log;
+import android.util.Range;
+import android.view.Surface;
+
+import com.android.cts.util.ResultType;
+import com.android.cts.util.ResultUnit;
+import com.android.cts.util.Stat;
+
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.LinkedList;
+
+public class VideoDecoderPerfTest extends MediaPlayerTestBase {
+    private static final String TAG = "VideoDecoderPerfTest";
+    private static final int TOTAL_FRAMES = 3000;
+    private static final int MAX_TIME_MS = 120000;  // 2 minutes
+    private static final int NUMBER_OF_REPEAT = 2;
+    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_VP9 = MediaFormat.MIMETYPE_VIDEO_VP9;
+    private static final String VIDEO_HEVC = MediaFormat.MIMETYPE_VIDEO_HEVC;
+    private static final String VIDEO_H263 = MediaFormat.MIMETYPE_VIDEO_H263;
+    private static final String VIDEO_MPEG4 = MediaFormat.MIMETYPE_VIDEO_MPEG4;
+
+    private static final int MAX_SIZE_SAMPLES_IN_MEMORY_BYTES = 5 * 1024 * 1024;  // 5MB
+    LinkedList<ByteBuffer> mSamplesInMemory = new LinkedList<ByteBuffer>();
+    private static final int MOVING_AVERAGE_NUM = 10;
+    private MediaFormat mDecOutputFormat;
+    private double[] mMeasuredFps;
+    private String[] mResultRawData;
+    private boolean mVerifyResults;
+
+    private Resources mResources;
+    private DeviceReportLog mReportLog;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mVerifyResults = true;
+        mResources = mContext.getResources();
+        mReportLog = new DeviceReportLog();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mReportLog.deliverReportToHost(getInstrumentation());
+        super.tearDown();
+    }
+
+    private static String[] getDecoderName(String mime, boolean isGoog) {
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        ArrayList<String> result = new ArrayList<String>();
+        for (MediaCodecInfo info : mcl.getCodecInfos()) {
+            if (info.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()]);
+    }
+
+    private void decode(String mime, int video, int width, int height,
+            boolean isGoog) throws Exception {
+        String[] names = getDecoderName(mime, isGoog);
+        for (String name: names) {
+            if (!MediaUtils.supports(name, mime, width, height)) {
+                Log.i(TAG, "Codec " + name + " with " + width + "," + height + " not supported");
+                continue;
+            }
+
+            boolean pass = false;
+            mMeasuredFps = new double[NUMBER_OF_REPEAT];
+            mResultRawData = new String[NUMBER_OF_REPEAT];
+            Log.d(TAG, "testing " + name);
+            for (int i = 0; i < NUMBER_OF_REPEAT; ++i) {
+                // Decode to Surface.
+                Log.d(TAG, "round #" + i + " decode to surface");
+                Surface s = getActivity().getSurfaceHolder().getSurface();
+                // only verify the result for decode to surface case.
+                if (doDecode(name, video, width, height, s, i)) {
+                    pass = true;
+                }
+
+                // Decode to buffer.
+                Log.d(TAG, "round #" + i + " decode to buffer");
+                doDecode(name, video, width, height, null, i);
+            }
+
+            if (!pass) {
+                Range<Double> reportedRange =
+                    MediaUtils.getAchievableFrameRatesFor(name, mime, width, height);
+                String failMessage =
+                    MediaUtils.getErrorMessage(reportedRange, mMeasuredFps, mResultRawData);
+                fail(failMessage);
+            }
+            mMeasuredFps = null;
+            mResultRawData = null;
+        }
+        // use 0 for summary line, detail for each test config is in the report.
+        mReportLog.printSummary("average fps", 0, ResultType.HIGHER_BETTER, ResultUnit.FPS);
+        mSamplesInMemory.clear();
+    }
+
+    private boolean doDecode(String name, int video, int w, int h, Surface surface, int round)
+            throws Exception {
+        AssetFileDescriptor testFd = mResources.openRawResourceFd(video);
+        MediaExtractor extractor = new MediaExtractor();
+        extractor.setDataSource(testFd.getFileDescriptor(), testFd.getStartOffset(),
+                testFd.getLength());
+        extractor.selectTrack(0);
+        int trackIndex = extractor.getSampleTrackIndex();
+        MediaFormat format = extractor.getTrackFormat(trackIndex);
+        String mime = format.getString(MediaFormat.KEY_MIME);
+        ByteBuffer[] codecInputBuffers;
+        ByteBuffer[] codecOutputBuffers;
+
+        if (mSamplesInMemory.size() == 0) {
+            int totalMemory = 0;
+            ByteBuffer tmpBuf = ByteBuffer.allocate(w * h * 3 / 2);
+            int sampleSize = 0;
+            int index = 0;
+            while ((sampleSize = extractor.readSampleData(tmpBuf, 0 /* offset */)) > 0) {
+                if (totalMemory + sampleSize > MAX_SIZE_SAMPLES_IN_MEMORY_BYTES) {
+                    break;
+                }
+                ByteBuffer copied = ByteBuffer.allocate(sampleSize);
+                copied.put(tmpBuf);
+                mSamplesInMemory.addLast(copied);
+                totalMemory += sampleSize;
+                extractor.advance();
+            }
+            Log.d(TAG, mSamplesInMemory.size() + " samples in memory for " +
+                    (totalMemory / 1024) + " KB.");
+        }
+        int sampleIndex = 0;
+
+        extractor.release();
+        testFd.close();
+
+        MediaCodec codec = MediaCodec.createByCodecName(name);
+        VideoCapabilities cap = codec.getCodecInfo().getCapabilitiesForType(mime).getVideoCapabilities();
+        int frameRate = 120;
+        try {
+            frameRate = cap.getSupportedFrameRatesFor(w, h).getUpper().intValue();
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "unsupported size");
+            codec.release();
+            return false;
+        }
+        codec.configure(format, surface, null /* crypto */, 0 /* flags */);
+        codec.start();
+        codecInputBuffers = codec.getInputBuffers();
+        codecOutputBuffers = codec.getOutputBuffers();
+
+        // start decode loop
+        MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+
+        final long kTimeOutUs = 5000; // 5ms timeout
+        double[] frameTimeDiff = new double[TOTAL_FRAMES - 1];
+        long lastOutputTimeNs = 0;
+        boolean sawInputEOS = false;
+        boolean sawOutputEOS = false;
+        int inputNum = 0;
+        int outputNum = 0;
+        long start = System.currentTimeMillis();
+        while (!sawOutputEOS) {
+            // handle input
+            if (!sawInputEOS) {
+                int inputBufIndex = codec.dequeueInputBuffer(kTimeOutUs);
+
+                if (inputBufIndex >= 0) {
+                    ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];
+                    ByteBuffer sample =
+                            mSamplesInMemory.get(sampleIndex++ % mSamplesInMemory.size());
+                    sample.rewind();
+                    int sampleSize = sample.remaining();
+                    dstBuf.put(sample);
+                    // use 120fps to compute pts
+                    long presentationTimeUs = inputNum * 1000000L / frameRate;
+
+                    sawInputEOS = (++inputNum == TOTAL_FRAMES);
+                    if (!sawInputEOS &&
+                            ((System.currentTimeMillis() - start) > MAX_TIME_MS)) {
+                        sawInputEOS = true;
+                    }
+                    if (sawInputEOS) {
+                        Log.d(TAG, "saw input EOS (stop at sample).");
+                    }
+                    codec.queueInputBuffer(
+                            inputBufIndex,
+                            0 /* offset */,
+                            sampleSize,
+                            presentationTimeUs,
+                            sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
+                } else {
+                    assertEquals(
+                            "codec.dequeueInputBuffer() unrecognized return value: " + inputBufIndex,
+                            MediaCodec.INFO_TRY_AGAIN_LATER, inputBufIndex);
+                }
+            }
+
+            // handle output
+            int outputBufIndex = codec.dequeueOutputBuffer(info, kTimeOutUs);
+
+            if (outputBufIndex >= 0) {
+                if (info.size > 0) { // Disregard 0-sized buffers at the end.
+                    if (lastOutputTimeNs > 0) {
+                        frameTimeDiff[outputNum - 1] = System.nanoTime() - lastOutputTimeNs;
+                    }
+                    lastOutputTimeNs = System.nanoTime();
+                    outputNum++;
+                }
+                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 (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+                codecOutputBuffers = codec.getOutputBuffers();
+                Log.d(TAG, "output buffers have changed.");
+            } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+                mDecOutputFormat = codec.getOutputFormat();
+                int width = mDecOutputFormat.getInteger(MediaFormat.KEY_WIDTH);
+                int height = mDecOutputFormat.getInteger(MediaFormat.KEY_HEIGHT);
+                Log.d(TAG, "output resolution " + width + "x" + height);
+            } else {
+                assertEquals(
+                        "codec.dequeueOutputBuffer() unrecognized return index: "
+                                + outputBufIndex,
+                        MediaCodec.INFO_TRY_AGAIN_LATER, outputBufIndex);
+            }
+        }
+        long finish = System.currentTimeMillis();
+        int validDataNum = outputNum - 1;
+        frameTimeDiff = Arrays.copyOf(frameTimeDiff, validDataNum);
+        codec.stop();
+        codec.release();
+
+        Log.d(TAG, "input num " + inputNum + " vs output num " + outputNum);
+
+        String testConfig = "codec=" + name +
+                " decodeto=" + ((surface == null) ? "buffer" : "surface") +
+                " mime=" + mime + " round=" + round +
+                " DecOutputFormat=" + mDecOutputFormat;
+
+        String message = "average fps for " + testConfig;
+        double fps = (double)outputNum / ((finish - start) / 1000.0);
+        mReportLog.printValue(message, fps, ResultType.HIGHER_BETTER, ResultUnit.FPS);
+
+        double[] avgs = MediaUtils.calculateMovingAverage(frameTimeDiff, MOVING_AVERAGE_NUM);
+        double decMin = Stat.getMin(avgs);
+        double decMax = Stat.getMax(avgs);
+        double decAvg = Stat.getAverage(avgs);
+        double decStdev = MediaUtils.getStdev(avgs);
+        String result =
+                MediaUtils.logResults(mReportLog, testConfig, decMin, decMax, decAvg, decStdev);
+        fps = 1000000000 / decMin;
+        if (surface != null) {
+            mMeasuredFps[round] = fps;
+            mResultRawData[round] = result;
+        }
+
+        if (!mVerifyResults) {
+            return true;
+        }
+
+        return MediaUtils.verifyResults(name, mime, w, h, fps);
+    }
+
+    public void testH2640320x0240Other() throws Exception {
+        decode(VIDEO_AVC,
+               R.raw.video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz,
+               320, 240, false /* isGoog */);
+    }
+
+    public void testH2640320x0240Goog() throws Exception {
+        decode(VIDEO_AVC,
+               R.raw.video_320x240_mp4_h264_800kbps_30fps_aac_stereo_128kbps_44100hz,
+               320, 240, true /* isGoog */);
+    }
+
+    public void testH2640720x0480Other() throws Exception {
+        decode(VIDEO_AVC,
+               R.raw.video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz,
+               720, 480, false /* isGoog */);
+    }
+
+    public void testH2640720x0480Goog() throws Exception {
+        decode(VIDEO_AVC,
+               R.raw.video_720x480_mp4_h264_2048kbps_30fps_aac_stereo_128kbps_44100hz,
+               720, 480, true /* isGoog */);
+    }
+
+    public void testH2641280x0720Other() throws Exception {
+        decode(VIDEO_AVC,
+               R.raw.video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz,
+               1280, 720, false /* isGoog */);
+    }
+
+    public void testH2641280x0720Goog() throws Exception {
+        decode(VIDEO_AVC,
+               R.raw.video_1280x720_mp4_h264_8192kbps_30fps_aac_stereo_128kbps_44100hz,
+               1280, 720, true /* isGoog */);
+    }
+
+    public void testH2641920x1080Other() throws Exception {
+        decode(VIDEO_AVC,
+               R.raw.video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz,
+               1920, 1080, false /* isGoog */);
+    }
+
+    public void testH2641920x1080Goog() throws Exception {
+        decode(VIDEO_AVC,
+               R.raw.video_1920x1080_mp4_h264_20480kbps_30fps_aac_stereo_128kbps_44100hz,
+               1920, 1080, true /* isGoog */);
+    }
+
+    public void testVP80320x0240Other() throws Exception {
+        decode(VIDEO_VP8,
+               R.raw.video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz,
+               320, 240, false /* isGoog */);
+    }
+
+    public void testVP80320x0240Goog() throws Exception {
+        decode(VIDEO_VP8,
+               R.raw.video_320x240_webm_vp8_800kbps_30fps_vorbis_stereo_128kbps_44100hz,
+               320, 240, true /* isGoog */);
+    }
+
+    public void testVP80640x0360Other() throws Exception {
+        decode(VIDEO_VP8,
+               R.raw.video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               640, 360, false /* isGoog */);
+    }
+
+    public void testVP80640x0360Goog() throws Exception {
+        decode(VIDEO_VP8,
+               R.raw.video_640x360_webm_vp8_2048kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               640, 360, true /* isGoog */);
+    }
+
+    public void testVP81280x0720Other() throws Exception {
+        decode(VIDEO_VP8,
+               R.raw.video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               1280, 720, false /* isGoog */);
+    }
+
+    public void testVP81280x0720Goog() throws Exception {
+        decode(VIDEO_VP8,
+               R.raw.video_1280x720_webm_vp8_8192kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               1280, 720, true /* isGoog */);
+    }
+
+    public void testVP81920x1080Other() throws Exception {
+        decode(VIDEO_VP8,
+               R.raw.video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               1920, 1080, false /* isGoog */);
+    }
+
+    public void testVP81920x1080Goog() throws Exception {
+        decode(VIDEO_VP8,
+               R.raw.video_1920x1080_webm_vp8_20480kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               1920, 1080, true /* isGoog */);
+    }
+
+    public void testVP90320x0240Other() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               320, 240, false /* isGoog */);
+    }
+
+    public void testVP90320x0240Goog() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_320x240_webm_vp9_600kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               320, 240, true /* isGoog */);
+    }
+
+    public void testVP90640x0360Other() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_640x360_webm_vp9_1600kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               640, 360, false /* isGoog */);
+    }
+
+    public void testVP90640x0360Goog() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_640x360_webm_vp9_1600kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               640, 360, true /* isGoog */);
+    }
+
+    public void testVP91280x0720Other() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_44100hz,
+               1280, 720, false /* isGoog */);
+    }
+
+    public void testVP91280x0720Goog() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_1280x720_webm_vp9_4096kbps_30fps_vorbis_stereo_128kbps_44100hz,
+               1280, 720, true /* isGoog */);
+    }
+
+    public void testVP91920x1080Other() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               1920, 1080, false /* isGoog */);
+    }
+
+    public void testVP91920x1080Goog() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_1920x1080_webm_vp9_10240kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               1920, 1080, true /* isGoog */);
+    }
+
+    public void testVP93840x2160Other() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               3840, 2160, false /* isGoog */);
+    }
+
+    public void testVP93840x2160Goog() throws Exception {
+        decode(VIDEO_VP9,
+               R.raw.video_3840x2160_webm_vp9_20480kbps_30fps_vorbis_stereo_128kbps_48000hz,
+               3840, 2160, true /* isGoog */);
+    }
+
+    public void testHEVC0352x0288Other() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz,
+               352, 288, false /* isGoog */);
+    }
+
+    public void testHEVC0352x0288Goog() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_352x288_mp4_hevc_600kbps_30fps_aac_stereo_128kbps_44100hz,
+               352, 288, true /* isGoog */);
+    }
+
+    public void testHEVC0720x0480Other() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz,
+               720, 480, false /* isGoog */);
+    }
+
+    public void testHEVC0720x0480Goog() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_720x480_mp4_hevc_1638kbps_30fps_aac_stereo_128kbps_44100hz,
+               720, 480, true /* isGoog */);
+    }
+
+    public void testHEVC1280x0720Other() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz,
+               1280, 720, false /* isGoog */);
+    }
+
+    public void testHEVC1280x0720Goog() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_1280x720_mp4_hevc_4096kbps_30fps_aac_stereo_128kbps_44100hz,
+               1280, 720, true /* isGoog */);
+    }
+
+    public void testHEVC1920x1080Other() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz,
+               1920, 1080, false /* isGoog */);
+    }
+
+    public void testHEVC1920x1080Goog() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_1920x1080_mp4_hevc_10240kbps_30fps_aac_stereo_128kbps_44100hz,
+               1920, 1080, true /* isGoog */);
+    }
+
+    public void testHEVC3840x2160Other() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_3840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz,
+               3840, 2160, false /* isGoog */);
+    }
+
+    public void testHEVC3840x2160Goog() throws Exception {
+        decode(VIDEO_HEVC,
+               R.raw.video_3840x2160_mp4_hevc_20480kbps_30fps_aac_stereo_128kbps_44100hz,
+               3840, 2160, true /* isGoog */);
+    }
+
+    public void testH2630176x0144Other() throws Exception {
+        decode(VIDEO_H263,
+               R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
+               176, 144, false /* isGoog */);
+    }
+
+    public void testH2630176x0144Goog() throws Exception {
+        decode(VIDEO_H263,
+               R.raw.video_176x144_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
+               176, 144, true /* isGoog */);
+    }
+
+    public void testH2630352x0288Other() throws Exception {
+        decode(VIDEO_H263,
+               R.raw.video_352x288_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
+               352, 288, false /* isGoog */);
+    }
+
+    public void testH2630352x0288Goog() throws Exception {
+        decode(VIDEO_H263,
+               R.raw.video_352x288_3gp_h263_300kbps_12fps_aac_stereo_128kbps_22050hz,
+               352, 288, true /* isGoog */);
+    }
+
+    public void testMPEG40176x0144Other() throws Exception {
+        mVerifyResults = false;
+        decode(VIDEO_MPEG4,
+               R.raw.video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz,
+               176, 144, false /* isGoog */);
+    }
+
+    public void testMPEG40176x0144Goog() throws Exception {
+        mVerifyResults = false;
+        decode(VIDEO_MPEG4,
+               R.raw.video_176x144_mp4_mpeg4_300kbps_25fps_aac_stereo_128kbps_44100hz,
+               176, 144, true /* isGoog */);
+    }
+
+    public void testMPEG40480x0360Other() throws Exception {
+        decode(VIDEO_MPEG4,
+               R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
+               480, 360, false /* isGoog */);
+    }
+
+    public void testMPEG40480x0360Goog() throws Exception {
+        decode(VIDEO_MPEG4,
+               R.raw.video_480x360_mp4_mpeg4_860kbps_25fps_aac_stereo_128kbps_44100hz,
+               480, 360, true /* isGoog */);
+    }
+
+    public void testMPEG41280x0720Other() throws Exception {
+        decode(VIDEO_MPEG4,
+               R.raw.video_1280x720_mp4_mpeg4_1000kbps_25fps_aac_stereo_128kbps_44100hz,
+               1280, 720, false /* isGoog */);
+    }
+
+    public void testMPEG41280x0720Goog() throws Exception {
+        decode(VIDEO_MPEG4,
+               R.raw.video_1280x720_mp4_mpeg4_1000kbps_25fps_aac_stereo_128kbps_44100hz,
+               1280, 720, true /* isGoog */);
+    }
+}
+
diff --git a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
index 858e47c..fb1521d 100644
--- a/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
+++ b/tests/tests/media/src/android/media/cts/VideoEncoderTest.java
@@ -53,6 +53,8 @@
     private static final int MAX_SAMPLE_SIZE = 256 * 1024;
     private static final String TAG = "VideoEncoderTest";
     private static final long FRAME_TIMEOUT_MS = 1000;
+    // use larger delay before we get first frame, some encoders may need more time
+    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";
@@ -172,6 +174,8 @@
         private boolean mSignaledDecoderEOS;
 
         protected boolean mCompleted;
+        protected boolean mEncoderIsActive;
+        protected boolean mEncodeOutputFormatUpdated;
         protected final Object mCondition = new Object();
 
         protected MediaFormat mDecFormat;
@@ -319,6 +323,10 @@
                         mCompleted = true;
                         mCondition.notifyAll(); // condition is always satisfied
                     }
+                } else {
+                    synchronized(mCondition) {
+                        mEncoderIsActive = true;
+                    }
                 }
             }
         }
@@ -382,7 +390,8 @@
                             // wait for an encoder input buffer and a decoder output buffer
                             // Use a timeout to avoid stalling the test if it doesn't arrive.
                             if (!haveBuffers() && !mCompleted) {
-                                mCondition.wait(FRAME_TIMEOUT_MS);
+                                mCondition.wait(mEncodeOutputFormatUpdated ?
+                                        FRAME_TIMEOUT_MS : INIT_TIMEOUT_MS);
                             }
                         } catch (InterruptedException ie) {
                             fail("wait interrupted");  // shouldn't happen
@@ -391,6 +400,11 @@
                             break;
                         }
                         if (!haveBuffers()) {
+                            if (mEncoderIsActive) {
+                                mEncoderIsActive = false;
+                                Log.d(TAG, "No more input but still getting output from encoder.");
+                                continue;
+                            }
                             fail("timed out after " + mBuffersToRender.size()
                                     + " decoder output and " + mEncInputBuffers.size()
                                     + " encoder input buffers");
@@ -494,7 +508,7 @@
             if (mEncInputBufferSize < 0) {
                 mEncInputBufferSize = mEncoder.getInputBuffer(encBuffer).capacity();
             }
-            Log.d(TAG, "queuing output #" + encBuffer + " for encoder (sz="
+            Log.d(TAG, "queuing input #" + encBuffer + " for encoder (sz="
                     + mEncInputBufferSize + ", f=" + decBuffer.second.flags
                     + ", ts=" + decBuffer.second.presentationTimeUs + ")");
             mEncoder.queueInputBuffer(
@@ -515,6 +529,7 @@
         public void onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat) {
             Log.i(TAG, mediaCodec.getName() + " got new output format " + mediaFormat);
             if (mediaCodec == mEncoder) {
+                mEncodeOutputFormatUpdated = true;
                 saveEncoderFormat(mediaFormat);
             }
         }
@@ -552,7 +567,6 @@
             implements SurfaceTexture.OnFrameAvailableListener {
         private static final String TAG = "SurfaceVideoProcessor";
         private boolean mFrameAvailable;
-        private boolean mEncoderIsActive;
         private boolean mGotDecoderEOS;
         private boolean mSignaledEncoderEOS;
 
@@ -596,7 +610,8 @@
                             // wait for mFrameAvailable, which is set by onFrameAvailable().
                             // Use a timeout to avoid stalling the test if it doesn't arrive.
                             if (!mFrameAvailable && !mCompleted && !mEncoderIsActive) {
-                                mCondition.wait(FRAME_TIMEOUT_MS);
+                                mCondition.wait(mEncodeOutputFormatUpdated ?
+                                        FRAME_TIMEOUT_MS : INIT_TIMEOUT_MS);
                             }
                         } catch (InterruptedException ie) {
                             fail("wait interrupted");  // shouldn't happen
@@ -746,6 +761,7 @@
         public void onOutputFormatChanged(MediaCodec mediaCodec, MediaFormat mediaFormat) {
             Log.i(TAG, mediaCodec.getName() + " got new output format " + mediaFormat);
             if (mediaCodec == mEncoder) {
+                mEncodeOutputFormatUpdated = true;
                 saveEncoderFormat(mediaFormat);
             }
         }
diff --git a/tests/tests/media/src/android/media/cts/VisualizerTest.java b/tests/tests/media/src/android/media/cts/VisualizerTest.java
index 3c639a0..0d46ca7 100644
--- a/tests/tests/media/src/android/media/cts/VisualizerTest.java
+++ b/tests/tests/media/src/android/media/cts/VisualizerTest.java
@@ -55,9 +55,6 @@
 
     //Test case 0.0: test constructor and release
     public void test0_0ConstructorAndRelease() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         Visualizer visualizer = null;
         try {
             visualizer = new Visualizer(0);
@@ -79,9 +76,6 @@
 
     //Test case 1.0: capture rates
     public void test1_0CaptureRates() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getVisualizer(0);
         try {
             int captureRate = mVisualizer.getMaxCaptureRate();
@@ -101,9 +95,6 @@
 
     //Test case 1.1: test capture size
     public void test1_1CaptureSize() throws Exception {
-        if (!hasAudioOutput()) {
-            return;
-        }
         getVisualizer(0);
         try {
             int[] range = mVisualizer.getCaptureSizeRange();
@@ -135,6 +126,8 @@
     //Test case 2.0: test capture in polling mode
     public void test2_0PollingCapture() throws Exception {
         if (!hasAudioOutput()) {
+            Log.w(TAG,"AUDIO_OUTPUT feature not found. This system might not have a valid "
+                    + "audio output HAL");
             return;
         }
         try {
@@ -165,6 +158,8 @@
     //Test case 2.1: test capture with listener
     public void test2_1ListenerCapture() throws Exception {
         if (!hasAudioOutput()) {
+            Log.w(TAG,"AUDIO_OUTPUT feature not found. This system might not have a valid "
+                    + "audio output HAL");
             return;
         }
         try {
diff --git a/tests/tests/mediastress/Android.mk b/tests/tests/mediastress/Android.mk
index 5bb23d0..d78ddac 100644
--- a/tests/tests/mediastress/Android.mk
+++ b/tests/tests/mediastress/Android.mk
@@ -33,6 +33,8 @@
 
 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/src/android/mediastress/cts/MediaRecorderStressTest.java b/tests/tests/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java
index a6a06ea..17b79d0 100644
--- a/tests/tests/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java
+++ b/tests/tests/mediastress/src/android/mediastress/cts/MediaRecorderStressTest.java
@@ -38,7 +38,7 @@
 
 public class MediaRecorderStressTest extends ActivityInstrumentationTestCase2<MediaFrameworkTest> {
 
-    private static String TAG = "MediaRecorderStressTest";
+    private static final String TAG = "MediaRecorderStressTest";
     private static final int NUMBER_OF_CAMERA_STRESS_LOOPS = 50;
     private static final int NUMBER_OF_RECORDER_STRESS_LOOPS = 50;
     private static final int NUMBER_OF_RECORDERANDPLAY_STRESS_LOOPS = 25;
diff --git a/tests/tests/midi/Android.mk b/tests/tests/midi/Android.mk
new file mode 100755
index 0000000..f202933
--- /dev/null
+++ b/tests/tests/midi/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)
+
+# 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 := ctsdeviceutil ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+# Must match the package name in CtsTestCaseList.mk
+LOCAL_PACKAGE_NAME := CtsMidiTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/midi/AndroidManifest.xml b/tests/tests/midi/AndroidManifest.xml
new file mode 100755
index 0000000..971f4fb
--- /dev/null
+++ b/tests/tests/midi/AndroidManifest.xml
@@ -0,0 +1,48 @@
+<?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.midi.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+
+    <uses-feature android:name="android.software.midi" android:required="true"/>
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <service android:name="MidiEchoTestService"
+                android:permission="android.permission.BIND_MIDI_DEVICE_SERVICE">
+            <intent-filter>
+                <action android:name="android.media.midi.MidiDeviceService" />
+            </intent-filter>
+            <meta-data android:name="android.media.midi.MidiDeviceService"
+                android:resource="@xml/echo_device_info" />
+        </service>
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="CTS MIDI tests"
+        android:targetPackage="android.midi.cts" >
+        <meta-data
+            android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/midi/res/xml/echo_device_info.xml b/tests/tests/midi/res/xml/echo_device_info.xml
new file mode 100644
index 0000000..936216a
--- /dev/null
+++ b/tests/tests/midi/res/xml/echo_device_info.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.
+-->
+
+<devices>
+    <device manufacturer="AndroidCTS" product="MidiEcho" tags="echo,test">
+        <input-port name="input" />
+        <output-port name="output" />
+    </device>
+</devices>
diff --git a/tests/tests/midi/src/android/midi/cts/MidiEchoTest.java b/tests/tests/midi/src/android/midi/cts/MidiEchoTest.java
new file mode 100644
index 0000000..f9ef68f
--- /dev/null
+++ b/tests/tests/midi/src/android/midi/cts/MidiEchoTest.java
@@ -0,0 +1,485 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.midi.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.media.midi.MidiManager;
+import android.media.midi.MidiOutputPort;
+import android.media.midi.MidiDevice;
+import android.media.midi.MidiDevice.MidiConnection;
+import android.media.midi.MidiDeviceInfo;
+import android.media.midi.MidiDeviceInfo.PortInfo;
+import android.media.midi.MidiDeviceStatus;
+import android.media.midi.MidiInputPort;
+import android.media.midi.MidiReceiver;
+import android.media.midi.MidiSender;
+import android.os.Bundle;
+import android.test.AndroidTestCase;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Random;
+
+/**
+ * Test MIDI using a virtual MIDI device that echos input to output.
+ */
+public class MidiEchoTest extends AndroidTestCase {
+    public static final String TEST_MANUFACTURER = "AndroidCTS";
+    public static final String ECHO_PRODUCT = "MidiEcho";
+    // I am overloading the timestamp for some tests. It is passed
+    // directly through the Echo server unchanged.
+    // The high 32-bits has a recognizable value.
+    // The low 32-bits can contain data used to identify messages.
+    private static final long TIMESTAMP_MARKER = 0x1234567800000000L;
+    private static final long TIMESTAMP_MARKER_MASK = 0xFFFFFFFF00000000L;
+    private static final long TIMESTAMP_DATA_MASK = 0x00000000FFFFFFFFL;
+    private static final long NANOS_PER_MSEC = 1000L * 1000L;
+
+    // Store device and ports related to the Echo service.
+    static class MidiTestContext {
+        MidiDeviceInfo echoInfo;
+        MidiDevice     echoDevice;
+        MidiInputPort  echoInputPort;
+        MidiOutputPort echoOutputPort;
+    }
+
+    // Store complete MIDI message so it can be put in an array.
+    static class MidiMessage {
+        public final byte[] data;
+        public final long   timestamp;
+        public final long   timeReceived;
+
+        MidiMessage(byte[] buffer, int offset, int length, long timestamp) {
+            timeReceived = System.nanoTime();
+            data = new byte[length];
+            System.arraycopy(buffer, offset, data, 0, length);
+            this.timestamp = timestamp;
+        }
+    }
+
+    // Listens for an asynchronous device open and notifies waiting foreground
+    // test.
+    class MyTestOpenCallback implements MidiManager.OnDeviceOpenedListener {
+        MidiDevice mDevice;
+
+        @Override
+        public synchronized void onDeviceOpened(MidiDevice device) {
+            mDevice = device;
+            notifyAll();
+        }
+
+        public synchronized MidiDevice waitForOpen(int msec)
+                throws InterruptedException {
+            wait(msec);
+            return mDevice;
+        }
+    }
+
+    // Store received messages in an array.
+    class MyLoggingReceiver extends MidiReceiver {
+        ArrayList<MidiMessage> messages = new ArrayList<MidiMessage>();
+
+        @Override
+        public synchronized void onSend(byte[] data, int offset, int count,
+                long timestamp) {
+            messages.add(new MidiMessage(data, offset, count, timestamp));
+            notifyAll();
+        }
+
+        public synchronized int getMessageCount() {
+            return messages.size();
+        }
+
+        public synchronized MidiMessage getMessage(int index) {
+            return messages.get(index);
+        }
+
+        /**
+         * Wait until count messages have arrived.
+         * This is a cumulative total.
+         * @param count
+         * @param timeoutMs
+         * @throws InterruptedException
+         */
+        public synchronized void waitForMessages(int count, int timeoutMs)
+                throws InterruptedException {
+            long endTimeMs = System.currentTimeMillis() + timeoutMs + 1;
+            long timeToWait = timeoutMs + 1;
+            while ((getMessageCount() < count)
+                    && (timeToWait > 0)) {
+                wait(timeToWait);
+                timeToWait = endTimeMs - System.currentTimeMillis();
+            }
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    // Search through the available devices for the ECHO loop-back device.
+    protected MidiDeviceInfo findEchoDevice() {
+        MidiManager midiManager = (MidiManager) mContext.getSystemService(
+                Context.MIDI_SERVICE);
+        MidiDeviceInfo[] infos = midiManager.getDevices();
+        MidiDeviceInfo echoInfo = null;
+        for (MidiDeviceInfo info : infos) {
+            Bundle properties = info.getProperties();
+            String manufacturer = (String) properties.get(
+                    MidiDeviceInfo.PROPERTY_MANUFACTURER);
+
+            if (TEST_MANUFACTURER.equals(manufacturer)) {
+                String product = (String) properties.get(
+                        MidiDeviceInfo.PROPERTY_PRODUCT);
+                if (ECHO_PRODUCT.equals(product)) {
+                    echoInfo = info;
+                    break;
+                }
+            }
+        }
+        assertTrue("could not find " + ECHO_PRODUCT, echoInfo != null);
+        return echoInfo;
+    }
+
+    protected MidiTestContext setUpEchoServer() throws Exception {
+        MidiManager midiManager = (MidiManager) mContext.getSystemService(
+                Context.MIDI_SERVICE);
+
+        MidiDeviceInfo echoInfo = findEchoDevice();
+
+        // Open device.
+        MyTestOpenCallback callback = new MyTestOpenCallback();
+        midiManager.openDevice(echoInfo, callback, null);
+        int timeoutMs = 1000;
+        MidiDevice echoDevice = callback.waitForOpen(timeoutMs);
+        assertTrue("could not open " + ECHO_PRODUCT, echoDevice != null);
+
+        // Query echo service directly to see if it is getting status updates.
+        MidiEchoTestService echoService = MidiEchoTestService.getInstance();
+        assertEquals("virtual device status, input port before open", false,
+                echoService.inputOpened);
+        assertEquals("virtual device status, output port before open", 0,
+                echoService.outputOpenCount);
+
+        // Open input port.
+        MidiInputPort echoInputPort = echoDevice.openInputPort(0);
+        assertTrue("could not open input port", echoInputPort != null);
+        assertEquals("input port number", 0, echoInputPort.getPortNumber());
+        assertEquals("virtual device status, input port after open", true,
+                echoService.inputOpened);
+        assertEquals("virtual device status, output port before open", 0,
+                echoService.outputOpenCount);
+
+        // Open output port.
+        MidiOutputPort echoOutputPort = echoDevice.openOutputPort(0);
+        assertTrue("could not open output port", echoOutputPort != null);
+        assertEquals("output port number", 0, echoOutputPort.getPortNumber());
+        assertEquals("virtual device status, input port after open", true,
+                echoService.inputOpened);
+        assertEquals("virtual device status, output port after open", 1,
+                echoService.outputOpenCount);
+
+        MidiTestContext mc = new MidiTestContext();
+        mc.echoInfo = echoInfo;
+        mc.echoDevice = echoDevice;
+        mc.echoInputPort = echoInputPort;
+        mc.echoOutputPort = echoOutputPort;
+        return mc;
+    }
+
+    /**
+     * Close ports and check device status.
+     *
+     * @param mc
+     */
+    protected void tearDownEchoServer(MidiTestContext mc) throws IOException {
+        // Query echo service directly to see if it is getting status updates.
+        MidiEchoTestService echoService = MidiEchoTestService.getInstance();
+        assertEquals("virtual device status, input port before close", true,
+                echoService.inputOpened);
+        assertEquals("virtual device status, output port before close", 1,
+                echoService.outputOpenCount);
+
+        // Close output port.
+        mc.echoOutputPort.close();
+        assertEquals("virtual device status, input port before close", true,
+                echoService.inputOpened);
+        assertEquals("virtual device status, output port after close", 0,
+                echoService.outputOpenCount);
+        mc.echoOutputPort.close();
+        mc.echoOutputPort.close(); // should be safe to close twice
+
+        // Close input port.
+        mc.echoInputPort.close();
+        assertEquals("virtual device status, input port after close", false,
+                echoService.inputOpened);
+        assertEquals("virtual device status, output port after close", 0,
+                echoService.outputOpenCount);
+        mc.echoInputPort.close();
+        mc.echoInputPort.close(); // should be safe to close twice
+
+        mc.echoDevice.close();
+        mc.echoDevice.close(); // should be safe to close twice
+    }
+
+    /**
+     * @param mc
+     * @param echoInfo
+     */
+    protected void checkEchoDeviceInfo(MidiTestContext mc,
+            MidiDeviceInfo echoInfo) {
+        assertEquals("echo input port count wrong", 1,
+                echoInfo.getInputPortCount());
+        assertEquals("echo output port count wrong", 1,
+                echoInfo.getOutputPortCount());
+
+        Bundle properties = echoInfo.getProperties();
+        String tags = (String) properties.get("tags");
+        assertEquals("attributes from device XML", "echo,test", tags);
+
+        PortInfo[] ports = echoInfo.getPorts();
+        assertEquals("port info array size", 2, ports.length);
+
+        boolean foundInput = false;
+        boolean foundOutput = false;
+        for (PortInfo portInfo : ports) {
+            if (portInfo.getType() == PortInfo.TYPE_INPUT) {
+                foundInput = true;
+                assertEquals("input port name", "input", portInfo.getName());
+
+                assertEquals("info port number", portInfo.getPortNumber(),
+                        mc.echoInputPort.getPortNumber());
+            } else if (portInfo.getType() == PortInfo.TYPE_OUTPUT) {
+                foundOutput = true;
+                assertEquals("output port name", "output", portInfo.getName());
+                assertEquals("info port number", portInfo.getPortNumber(),
+                        mc.echoOutputPort.getPortNumber());
+            }
+        }
+        assertTrue("found input port info", foundInput);
+        assertTrue("found output port info", foundOutput);
+
+        assertEquals("MIDI device type", MidiDeviceInfo.TYPE_VIRTUAL,
+                echoInfo.getType());
+    }
+
+    // Is the MidiManager supported?
+    public void testMidiManager() throws Exception {
+        PackageManager pm = mContext.getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+            return; // Not supported so don't test it.
+        }
+
+        MidiManager midiManager = (MidiManager) mContext.getSystemService(
+                Context.MIDI_SERVICE);
+        assertTrue("MidiManager not supported.", midiManager != null);
+
+        // There should be at least one device for the Echo server.
+        MidiDeviceInfo[] infos = midiManager.getDevices();
+        assertTrue("device list was null", infos != null);
+        assertTrue("device list was empty", infos.length >= 1);
+    }
+
+    public void testDeviceInfo() throws Exception {
+        PackageManager pm = mContext.getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+            return; // Not supported so don't test it.
+        }
+
+        MidiTestContext mc = setUpEchoServer();
+        checkEchoDeviceInfo(mc, mc.echoInfo);
+        checkEchoDeviceInfo(mc, mc.echoDevice.getInfo());
+        assertTrue("device info equal",
+                mc.echoInfo.equals(mc.echoDevice.getInfo()));
+        tearDownEchoServer(mc);
+    }
+
+    public void testEchoSmallMessage() throws Exception {
+        PackageManager pm = mContext.getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+            return; // Not supported so don't test it.
+        }
+
+        MidiTestContext mc = setUpEchoServer();
+
+        MyLoggingReceiver receiver = new MyLoggingReceiver();
+        mc.echoOutputPort.connect(receiver);
+
+        final byte[] buffer = { (byte) 0x93, 0x47, 0x52 };
+        long timestamp = 0x0123765489ABFEDCL;
+
+        mc.echoInputPort.send(buffer, 0, 0, timestamp); // should be a NOOP
+        mc.echoInputPort.send(buffer, 0, buffer.length, timestamp);
+        mc.echoInputPort.send(buffer, 0, 0, timestamp); // should be a NOOP
+
+        // Wait for message to pass quickly through echo service.
+        final int numMessages = 1;
+        final int timeoutMs = 20;
+        synchronized (receiver) {
+            receiver.waitForMessages(numMessages, timeoutMs);
+        }
+        assertEquals("number of messages.", numMessages, receiver.getMessageCount());
+        MidiMessage message = receiver.getMessage(0);
+
+        assertEquals("byte count of message", buffer.length,
+                message.data.length);
+        assertEquals("timestamp in message", timestamp, message.timestamp);
+        for (int i = 0; i < buffer.length; i++) {
+            assertEquals("message byte[" + i + "]", buffer[i] & 0x0FF,
+                    message.data[i] & 0x0FF);
+        }
+
+        mc.echoOutputPort.disconnect(receiver);
+        tearDownEchoServer(mc);
+    }
+
+    public void testEchoLatency() throws Exception {
+        PackageManager pm = mContext.getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+            return; // Not supported so don't test it.
+        }
+
+        MidiTestContext mc = setUpEchoServer();
+        MyLoggingReceiver receiver = new MyLoggingReceiver();
+        mc.echoOutputPort.connect(receiver);
+
+        final int numMessages = 10;
+        final long maxLatencyNanos = 15 * NANOS_PER_MSEC; // generally < 3 msec on N6
+        byte[] buffer = { (byte) 0x93, 0, 64 };
+
+        // Send multiple messages in a burst.
+        for (int index = 0; index < numMessages; index++) {
+            buffer[1] = (byte) (60 + index);
+            mc.echoInputPort.send(buffer, 0, buffer.length, System.nanoTime());
+        }
+
+        // Wait for messages to pass quickly through echo service.
+        final int timeoutMs = 100;
+        synchronized (receiver) {
+            receiver.waitForMessages(numMessages, timeoutMs);
+        }
+        assertEquals("number of messages.", numMessages, receiver.getMessageCount());
+
+        for (int index = 0; index < numMessages; index++) {
+            MidiMessage message = receiver.getMessage(index);
+            assertEquals("message index", (byte) (60 + index), message.data[1]);
+            long elapsedNanos = message.timeReceived - message.timestamp;
+            // If this test fails then there may be a problem with the thread scheduler
+            // or there may be kernel activity that is blocking execution at the user level.
+            assertTrue("MIDI round trip latency[" + index + "] too large, " + elapsedNanos + " nanoseconds",
+                    (elapsedNanos < maxLatencyNanos));
+        }
+
+        mc.echoOutputPort.disconnect(receiver);
+        tearDownEchoServer(mc);
+    }
+
+    public void testEchoMultipleMessages() throws Exception {
+        PackageManager pm = mContext.getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+            return; // Not supported so don't test it.
+        }
+
+        MidiTestContext mc = setUpEchoServer();
+
+        MyLoggingReceiver receiver = new MyLoggingReceiver();
+        mc.echoOutputPort.connect(receiver);
+
+        final byte[] buffer = new byte[2048];
+
+        final int numMessages = 100;
+        Random random = new Random(1972941337);
+        int bytesSent = 0;
+        byte value = 0;
+
+        // Send various length messages with sequential bytes.
+        long timestamp = TIMESTAMP_MARKER;
+        for (int messageIndex = 0; messageIndex < numMessages;
+                messageIndex++) {
+            // Sweep numData across critical region of
+            // MidiPortImpl.MAX_PACKET_DATA_SIZE
+            int numData = 1000 + messageIndex;
+            for (int dataIndex = 0; dataIndex < numData; dataIndex++) {
+                buffer[dataIndex] = value;
+                value++;
+            }
+            // This may get split into multiple sends internally.
+            mc.echoInputPort.send(buffer, 0, numData, timestamp);
+            bytesSent += numData;
+            timestamp++;
+        }
+
+        // Check messages. Data must be sequential bytes.
+        value = 0;
+        int bytesReceived = 0;
+        int messageReceivedIndex = 0;
+        int messageSentIndex = 0;
+        int expectedMessageSentIndex = 0;
+        while (bytesReceived < bytesSent) {
+            final int timeoutMs = 500;
+            // Wait for next message.
+            synchronized (receiver) {
+                receiver.waitForMessages(messageReceivedIndex + 1, timeoutMs);
+            }
+            MidiMessage message = receiver.getMessage(messageReceivedIndex++);
+            // parse timestamp marker and data
+            long timestampMarker = message.timestamp & TIMESTAMP_MARKER_MASK;
+            assertEquals("timestamp marker corrupted", TIMESTAMP_MARKER, timestampMarker);
+            messageSentIndex = (int) (message.timestamp & TIMESTAMP_DATA_MASK);
+
+            int numData = message.data.length;
+            for (int dataIndex = 0; dataIndex < numData; dataIndex++) {
+                String msg = String.format("message[%d/%d].data[%d/%d]",
+                        messageReceivedIndex, messageSentIndex, dataIndex,
+                        numData);
+                assertEquals(msg, value, message.data[dataIndex]);
+                value++;
+            }
+            bytesReceived += numData;
+            // May not advance if message got split
+            if (messageSentIndex > expectedMessageSentIndex) {
+                expectedMessageSentIndex++; // only advance by one each message
+            }
+            assertEquals("timestamp in message", expectedMessageSentIndex,
+                    messageSentIndex);
+        }
+
+        mc.echoOutputPort.disconnect(receiver);
+        tearDownEchoServer(mc);
+    }
+
+    // What happens if the app does bad things.
+    public void testEchoBadBehavior() throws Exception {
+        PackageManager pm = mContext.getPackageManager();
+        if (!pm.hasSystemFeature(PackageManager.FEATURE_MIDI)) {
+            return; // Not supported so don't test it.
+        }
+        MidiTestContext mc = setUpEchoServer();
+
+        // This should fail because it is already open.
+        MidiInputPort echoInputPort2 = mc.echoDevice.openInputPort(0);
+        assertTrue("input port opened twice", echoInputPort2 == null);
+
+        tearDownEchoServer(mc);
+    }
+}
diff --git a/tests/tests/midi/src/android/midi/cts/MidiEchoTestService.java b/tests/tests/midi/src/android/midi/cts/MidiEchoTestService.java
new file mode 100644
index 0000000..ae5373e
--- /dev/null
+++ b/tests/tests/midi/src/android/midi/cts/MidiEchoTestService.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.midi.cts;
+
+import android.media.midi.MidiDeviceService;
+import android.media.midi.MidiDeviceStatus;
+import android.media.midi.MidiReceiver;
+
+import java.io.IOException;
+
+/**
+ * Virtual MIDI Device that copies its input to its output.
+ * This is used for loop-back testing of MIDI I/O.
+ */
+
+public class MidiEchoTestService extends MidiDeviceService {
+
+    // Other apps will write to this port.
+    private MidiReceiver mInputReceiver = new MyReceiver();
+    // This app will copy the data to this port.
+    private MidiReceiver mOutputReceiver;
+    private static MidiEchoTestService mInstance;
+
+    // These are public so we can easily read them from CTS test.
+    public int statusChangeCount;
+    public boolean inputOpened;
+    public int outputOpenCount;
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mInstance = this;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+    }
+
+    // For CTS testing, so I can read test fields.
+    public static MidiEchoTestService getInstance() {
+        return mInstance;
+    }
+
+    @Override
+    public MidiReceiver[] onGetInputPortReceivers() {
+        return new MidiReceiver[] { mInputReceiver };
+    }
+
+    class MyReceiver extends MidiReceiver {
+        @Override
+        public void onSend(byte[] data, int offset, int count, long timestamp)
+                throws IOException {
+            if (mOutputReceiver == null) {
+                mOutputReceiver = getOutputPortReceivers()[0];
+            }
+            // Copy input to output.
+            mOutputReceiver.send(data, offset, count, timestamp);
+        }
+    }
+
+    @Override
+    public void onDeviceStatusChanged(MidiDeviceStatus status) {
+        statusChangeCount++;
+        inputOpened = status.isInputPortOpen(0);
+        outputOpenCount = status.getOutputPortOpenCount(0);
+    }
+}
diff --git a/tests/tests/nativemedia/sl/Android.mk b/tests/tests/nativemedia/sl/Android.mk
index 48b816c..28dfeff 100644
--- a/tests/tests/nativemedia/sl/Android.mk
+++ b/tests/tests/nativemedia/sl/Android.mk
@@ -6,6 +6,7 @@
 list_executable := $(test_executable)_list
 
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_MODULE := $(test_executable)
 LOCAL_MODULE_TAGS := optional
@@ -15,11 +16,8 @@
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 
 LOCAL_C_INCLUDES := \
-    bionic \
-    bionic/libstdc++/include \
     external/gtest/include \
     $(call include-path-for, wilhelm) \
-    external/stlport/stlport \
     $(call include-path-for, wilhelm-ut)
 
 LOCAL_SRC_FILES := \
@@ -29,7 +27,6 @@
     libutils \
     liblog \
     libOpenSLES \
-    libstlport
 
 LOCAL_STATIC_LIBRARIES := \
     libOpenSLESUT \
@@ -39,6 +36,7 @@
 include $(BUILD_CTS_EXECUTABLE)
 
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_MODULE := $(list_executable)
 LOCAL_MODULE_TAGS := optional
diff --git a/tests/tests/nativemedia/xa/Android.mk b/tests/tests/nativemedia/xa/Android.mk
index ace315a..52126c3 100644
--- a/tests/tests/nativemedia/xa/Android.mk
+++ b/tests/tests/nativemedia/xa/Android.mk
@@ -6,6 +6,7 @@
 list_executable := $(test_executable)_list
 
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_MODULE:= $(test_executable)
 LOCAL_MODULE_TAGS := optional
@@ -15,11 +16,8 @@
 LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
 
 LOCAL_C_INCLUDES := \
-    bionic \
-    bionic/libstdc++/include \
     external/gtest/include \
     $(call include-path-for, wilhelm) \
-    external/stlport/stlport \
     $(call include-path-for, wilhelm-ut)
 
 LOCAL_SRC_FILES := \
@@ -29,15 +27,15 @@
   libutils \
   liblog \
   libOpenMAXAL \
-  libstlport
 
 LOCAL_STATIC_LIBRARIES := \
-    libgtest
+  libgtest \
 
 LOCAL_CTS_TEST_PACKAGE := android.nativemedia.xa
 include $(BUILD_CTS_EXECUTABLE)
 
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 LOCAL_MODULE := $(list_executable)
 LOCAL_MODULE_TAGS := optional
diff --git a/tests/tests/nativeopengl/libnativeopengltests/Android.mk b/tests/tests/nativeopengl/libnativeopengltests/Android.mk
index 5d7dd6e..62e28ec 100644
--- a/tests/tests/nativeopengl/libnativeopengltests/Android.mk
+++ b/tests/tests/nativeopengl/libnativeopengltests/Android.mk
@@ -16,9 +16,11 @@
 # This is the shared library included by the JNI test app.
 #
 
-LOCAL_PATH:= $(call my-dir)/../standalone/jni/
+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
 
@@ -26,10 +28,7 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE) \
-    bionic \
-    bionic/libstdc++/include \
     external/gtest/include \
-    external/stlport/stlport
 
 LOCAL_SRC_FILES := \
         register.cpp \
@@ -38,11 +37,11 @@
         tests/EGLCleanup_test.cpp \
         tests/EGLCreateContext_test.cpp
 
+LOCAL_CXX_STL := libc++
 LOCAL_SHARED_LIBRARIES := libEGL \
                           libGLESv2 \
-                          libstlport \
                           libandroid \
-                          liblog
+                          liblog \
 
 LOCAL_STATIC_LIBRARIES := libgtest
 
diff --git a/tests/tests/nativeopengl/standalone/jni/tests/EGLCleanup_test.cpp b/tests/tests/nativeopengl/standalone/jni/tests/EGLCleanup_test.cpp
index db39798..2daa2fe 100644
--- a/tests/tests/nativeopengl/standalone/jni/tests/EGLCleanup_test.cpp
+++ b/tests/tests/nativeopengl/standalone/jni/tests/EGLCleanup_test.cpp
@@ -109,7 +109,7 @@
     }
 
 private:
-    enum { MAX_ITERATIONS = 1000 };
+    enum { MAX_ITERATIONS = 450 };
 
     EGLDisplay mEglDisplay;
     EGLSurface mEglSurface;
diff --git a/tests/tests/net/Android.mk b/tests/tests/net/Android.mk
index 46d4d81..6524871 100644
--- a/tests/tests/net/Android.mk
+++ b/tests/tests/net/Android.mk
@@ -24,17 +24,18 @@
 # Include both the 32 and 64 bit versions
 LOCAL_MULTILIB := both
 
-LOCAL_JAVA_LIBRARIES := voip-common conscrypt
+LOCAL_JAVA_LIBRARIES := voip-common conscrypt org.apache.http.legacy
 
-LOCAL_JNI_SHARED_LIBRARIES := libnativedns_jni
+LOCAL_JNI_SHARED_LIBRARIES := libcts_jni libnativedns_jni \
+                              libnativemultinetwork_jni
 
 # include CtsTestServer as a temporary hack to free net.cts from cts.stub.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsNetTestCases
 
-LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctsdeviceutil ctstestrunner \
-                               core-tests-support
+LOCAL_STATIC_JAVA_LIBRARIES := core-tests-support  ctsdeviceutil \
+                               ctstestrunner ctstestserver mockwebserver
 
 # uncomment when b/13249961 is fixed
 #LOCAL_SDK_VERSION := current
diff --git a/tests/tests/net/AndroidManifest.xml b/tests/tests/net/AndroidManifest.xml
index 652262d..001e294 100644
--- a/tests/tests/net/AndroidManifest.xml
+++ b/tests/tests/net/AndroidManifest.xml
@@ -20,6 +20,7 @@
 
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
@@ -30,6 +31,7 @@
 
     <application>
         <uses-library android:name="android.test.runner" />
+        <uses-library android:name="org.apache.http.legacy" android:required="false" />
     </application>
 
     <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
diff --git a/tests/tests/net/jni/Android.mk b/tests/tests/net/jni/Android.mk
index 75982de..ca82b30 100644
--- a/tests/tests/net/jni/Android.mk
+++ b/tests/tests/net/jni/Android.mk
@@ -28,3 +28,12 @@
 LOCAL_SHARED_LIBRARIES := libnativehelper liblog
 
 include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libnativemultinetwork_jni
+# Don't include this package in any configuration by default.
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := NativeMultinetworkJni.c
+LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+LOCAL_SHARED_LIBRARIES := libandroid libnativehelper liblog
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/net/jni/NativeDnsJni.c b/tests/tests/net/jni/NativeDnsJni.c
index b975594..4eb3c7a 100644
--- a/tests/tests/net/jni/NativeDnsJni.c
+++ b/tests/tests/net/jni/NativeDnsJni.c
@@ -18,6 +18,7 @@
 #include <jni.h>
 #include <netdb.h>
 #include <stdio.h>
+#include <string.h>
 #include <utils/Log.h>
 
 const char *GoogleDNSIpV4Address="8.8.8.8";
diff --git a/tests/tests/net/jni/NativeMultinetworkJni.c b/tests/tests/net/jni/NativeMultinetworkJni.c
new file mode 100644
index 0000000..ad56b51
--- /dev/null
+++ b/tests/tests/net/jni/NativeMultinetworkJni.c
@@ -0,0 +1,235 @@
+/*
+ * 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.
+ */
+
+
+#define LOG_TAG "MultinetworkApiTest"
+#include <utils/Log.h>
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <inttypes.h>
+#include <jni.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <android/multinetwork.h>
+
+#define UNUSED(X) ((void) X)
+
+static const char kHostname[] = "connectivitycheck.android.com";
+
+
+JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runGetaddrinfoCheck(
+        JNIEnv* env, jclass class, jlong nethandle) {
+    UNUSED(env);
+    UNUSED(class);
+    net_handle_t handle = (net_handle_t) nethandle;
+    struct addrinfo *res = NULL;
+
+    errno = 0;
+    int rval = android_getaddrinfofornetwork(handle, kHostname, NULL, NULL, &res);
+    const int saved_errno = errno;
+    freeaddrinfo(res);
+
+    ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d",
+          handle, kHostname, rval, saved_errno);
+    return rval == 0 ? 0 : -saved_errno;
+}
+
+JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetprocnetwork(
+        JNIEnv* env, jclass class, jlong nethandle) {
+    UNUSED(env);
+    UNUSED(class);
+    net_handle_t handle = (net_handle_t) nethandle;
+
+    errno = 0;
+    int rval = android_setprocnetwork(handle);
+    const int saved_errno = errno;
+    ALOGD("android_setprocnetwork(%llu) returned rval=%d errno=%d",
+          handle, rval, saved_errno);
+    return rval == 0 ? 0 : -saved_errno;
+}
+
+JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runSetsocknetwork(
+        JNIEnv* env, jclass class, jlong nethandle) {
+    UNUSED(env);
+    UNUSED(class);
+    net_handle_t handle = (net_handle_t) nethandle;
+
+    errno = 0;
+    int fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+    if (fd < 0) {
+        ALOGD("socket() failed, errno=%d", errno);
+        return -errno;
+    }
+
+    errno = 0;
+    int rval = android_setsocknetwork(handle, fd);
+    const int saved_errno = errno;
+    ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d",
+          handle, fd, rval, saved_errno);
+    close(fd);
+    return rval == 0 ? 0 : -saved_errno;
+}
+
+static const int kSockaddrStrLen = INET6_ADDRSTRLEN + strlen("[]:65535");
+
+void sockaddr_ntop(const struct sockaddr *sa, socklen_t salen, char *dst, const size_t size) {
+    char addrstr[INET6_ADDRSTRLEN];
+    char portstr[sizeof("65535")];
+    char buf[kSockaddrStrLen+1];
+
+    int ret = getnameinfo(sa, salen,
+                          addrstr, sizeof(addrstr),
+                          portstr, sizeof(portstr),
+                          NI_NUMERICHOST | NI_NUMERICSERV);
+    if (ret == 0) {
+        snprintf(buf, sizeof(buf),
+                 (sa->sa_family == AF_INET6) ? "[%s]:%s" : "%s:%s",
+                 addrstr, portstr);
+    } else {
+        sprintf(buf, "???");
+    }
+
+    strlcpy(dst, buf, size);
+}
+
+JNIEXPORT jint Java_android_net_cts_MultinetworkApiTest_runDatagramCheck(
+        JNIEnv* env, jclass class, jlong nethandle) {
+    UNUSED(env);
+    UNUSED(class);
+    const struct addrinfo kHints = {
+        .ai_flags = AI_ADDRCONFIG,
+        .ai_family = AF_UNSPEC,
+        .ai_socktype = SOCK_DGRAM,
+        .ai_protocol = IPPROTO_UDP,
+    };
+    struct addrinfo *res = NULL;
+    net_handle_t handle = (net_handle_t) nethandle;
+
+    static const char kPort[] = "443";
+    int rval = android_getaddrinfofornetwork(handle, kHostname, kPort, &kHints, &res);
+    if (rval != 0) {
+        ALOGD("android_getaddrinfofornetwork(%llu, %s) returned rval=%d errno=%d",
+              handle, kHostname, rval, errno);
+        freeaddrinfo(res);
+        return -errno;
+    }
+
+    // Rely upon getaddrinfo sorting the best destination to the front.
+    int fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+    if (fd < 0) {
+        ALOGD("socket(%d, %d, %d) failed, errno=%d",
+              res->ai_family, res->ai_socktype, res->ai_protocol, errno);
+        freeaddrinfo(res);
+        return -errno;
+    }
+
+    rval = android_setsocknetwork(handle, fd);
+    ALOGD("android_setprocnetwork(%llu, %d) returned rval=%d errno=%d",
+          handle, fd, rval, errno);
+    if (rval != 0) {
+        close(fd);
+        freeaddrinfo(res);
+        return -errno;
+    }
+
+    char addrstr[kSockaddrStrLen+1];
+    sockaddr_ntop(res->ai_addr, res->ai_addrlen, addrstr, sizeof(addrstr));
+    ALOGD("Attempting connect() to %s ...", addrstr);
+
+    rval = connect(fd, res->ai_addr, res->ai_addrlen);
+    if (rval != 0) {
+        close(fd);
+        freeaddrinfo(res);
+        return -errno;
+    }
+    freeaddrinfo(res);
+
+    struct sockaddr_storage src_addr;
+    socklen_t src_addrlen = sizeof(src_addr);
+    if (getsockname(fd, (struct sockaddr *)&src_addr, &src_addrlen) != 0) {
+        close(fd);
+        return -errno;
+    }
+    sockaddr_ntop((const struct sockaddr *)&src_addr, sizeof(src_addr), addrstr, sizeof(addrstr));
+    ALOGD("... from %s", addrstr);
+
+    // Don't let reads or writes block indefinitely.
+    const struct timeval timeo = { 2, 0 };  // 2 seconds
+    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeo, sizeof(timeo));
+    setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &timeo, sizeof(timeo));
+
+    // For reference see:
+    //     https://tools.ietf.org/html/draft-tsvwg-quic-protocol-01#section-6.1
+    uint8_t quic_packet[] = {
+        0x0c,                    // public flags: 64bit conn ID, 8bit sequence number
+        0, 0, 0, 0, 0, 0, 0, 0,  // 64bit connection ID
+        0x01,                    // sequence number
+        0x00,                    // private flags
+        0x07,                    // type: regular frame type "PING"
+    };
+
+    arc4random_buf(quic_packet + 1, 8);  // random connection ID
+
+    uint8_t response[1500];
+    ssize_t sent, rcvd;
+    static const int MAX_RETRIES = 5;
+    int i, errnum = 0;
+
+    for (i = 0; i < MAX_RETRIES; i++) {
+        sent = send(fd, quic_packet, sizeof(quic_packet), 0);
+        if (sent < (ssize_t)sizeof(quic_packet)) {
+            errnum = errno;
+            ALOGD("send(QUIC packet) returned sent=%zd, errno=%d", sent, errnum);
+            close(fd);
+            return -errnum;
+        }
+
+        rcvd = recv(fd, response, sizeof(response), 0);
+        if (rcvd > 0) {
+            break;
+        } else {
+            errnum = errno;
+            ALOGD("[%d/%d] recv(QUIC response) returned rcvd=%zd, errno=%d",
+                  i + 1, MAX_RETRIES, rcvd, errnum);
+        }
+    }
+    if (rcvd < sent) {
+        ALOGD("QUIC UDP %s: sent=%zd but rcvd=%zd, errno=%d", kPort, sent, rcvd, errnum);
+        if (rcvd <= 0) {
+            ALOGD("Does this network block UDP port %s?", kPort);
+        }
+        close(fd);
+        return -EPROTO;
+    }
+
+    int conn_id_cmp = memcmp(quic_packet + 1, response + 1, 8);
+    if (conn_id_cmp != 0) {
+        ALOGD("sent and received connection IDs do not match");
+        close(fd);
+        return -EPROTO;
+    }
+
+    // TODO: log, and compare to the IP address encoded in the
+    // response, since this should be a public reset packet.
+
+    close(fd);
+    return 0;
+}
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index 9daf3c4..9a99c22 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -16,16 +16,24 @@
 
 package android.net.cts;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_IMS;
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+
+import android.app.PendingIntent;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
 import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.NetworkConfig;
 import android.net.NetworkInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkInfo.State;
+import android.net.NetworkRequest;
 import android.net.wifi.WifiManager;
 import android.test.AndroidTestCase;
 import android.util.Log;
@@ -51,6 +59,10 @@
     public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI;
     private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1
 
+    // Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent.
+    private static final String NETWORK_CALLBACK_ACTION =
+            "ConnectivityManagerTest.NetworkCallbackAction";
+
     // device could have only one interface: data, wifi.
     private static final int MIN_NUM_NETWORK_TYPES = 1;
 
@@ -59,7 +71,6 @@
     private PackageManager mPackageManager;
     private final HashMap<Integer, NetworkConfig> mNetworks =
             new HashMap<Integer, NetworkConfig>();
-    private final List<Integer>mProtectedNetworks = new ArrayList<Integer>();
 
     @Override
     protected void setUp() throws Exception {
@@ -82,13 +93,6 @@
                 mNetworks.put(n.type, n);
             } catch (Exception e) {}
         }
-
-        // Get com.android.internal.R.array.config_protectedNetworks
-        resId = getContext().getResources().getIdentifier("config_protectedNetworks", "array", "android");
-        int[] protectedNetworks = getContext().getResources().getIntArray(resId);
-        for (int p : protectedNetworks) {
-            mProtectedNetworks.add(p);
-        }
     }
 
     public void testIsNetworkTypeValid() {
@@ -129,7 +133,19 @@
     public void testGetActiveNetworkInfo() {
         NetworkInfo ni = mCm.getActiveNetworkInfo();
 
-        assertTrue("You must have an active network connection to complete CTS", ni != null);
+        assertNotNull("You must have an active network connection to complete CTS", ni);
+        assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType()));
+        assertTrue(ni.getState() == State.CONNECTED);
+    }
+
+    public void testGetActiveNetwork() {
+        Network network = mCm.getActiveNetwork();
+        assertNotNull("You must have an active network connection to complete CTS", network);
+
+        NetworkInfo ni = mCm.getNetworkInfo(network);
+        assertNotNull("Network returned from getActiveNetwork was invalid", ni);
+
+        // Similar to testGetActiveNetworkInfo above.
         assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType()));
         assertTrue(ni.getState() == State.CONNECTED);
     }
@@ -170,6 +186,27 @@
         }
     }
 
+    private void assertStartUsingNetworkFeatureUnsupported(int networkType, String feature) {
+        try {
+            mCm.startUsingNetworkFeature(networkType, feature);
+            fail("startUsingNetworkFeature is no longer supported in the current API version");
+        } catch (UnsupportedOperationException expected) {}
+    }
+
+    private void assertStopUsingNetworkFeatureUnsupported(int networkType, String feature) {
+        try {
+            mCm.startUsingNetworkFeature(networkType, feature);
+            fail("stopUsingNetworkFeature is no longer supported in the current API version");
+        } catch (UnsupportedOperationException expected) {}
+    }
+
+    private void assertRequestRouteToHostUnsupported(int networkType, int hostAddress) {
+        try {
+            mCm.requestRouteToHost(networkType, hostAddress);
+            fail("requestRouteToHost is no longer supported in the current API version");
+        } catch (UnsupportedOperationException expected) {}
+    }
+
     public void testStartUsingNetworkFeature() {
 
         final String invalidateFeature = "invalidateFeature";
@@ -178,27 +215,9 @@
         final int wifiOnlyStartFailureCode = PhoneConstants.APN_REQUEST_FAILED;
         final int wifiOnlyStopFailureCode = -1;
 
-        NetworkInfo ni = mCm.getNetworkInfo(TYPE_MOBILE);
-        if (ni != null) {
-            assertEquals(PhoneConstants.APN_REQUEST_FAILED,
-                    mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidateFeature));
-            assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE,
-                    invalidateFeature));
-        } else {
-            assertEquals(wifiOnlyStartFailureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE,
-                    invalidateFeature));
-            assertEquals(wifiOnlyStopFailureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE,
-                    invalidateFeature));
-        }
-
-        ni = mCm.getNetworkInfo(TYPE_WIFI);
-        if (ni != null) {
-            // Should return failure because MMS is not supported on WIFI.
-            assertEquals(PhoneConstants.APN_REQUEST_FAILED, mCm.startUsingNetworkFeature(TYPE_WIFI,
-                    mmsFeature));
-            assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI,
-                    mmsFeature));
-        }
+        assertStartUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
+        assertStopUsingNetworkFeatureUnsupported(TYPE_MOBILE, invalidateFeature);
+        assertStartUsingNetworkFeatureUnsupported(TYPE_WIFI, mmsFeature);
     }
 
     private boolean isSupported(int networkType) {
@@ -209,11 +228,6 @@
                (networkType == ConnectivityManager.TYPE_VPN);
     }
 
-    // true if only the system can turn it on
-    private boolean isNetworkProtected(int networkType) {
-        return mProtectedNetworks.contains(networkType);
-    }
-
     public void testIsNetworkSupported() {
         for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
             boolean supported = mCm.isNetworkSupported(type);
@@ -227,120 +241,253 @@
 
     public void testRequestRouteToHost() {
         for (int type = -1 ; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
-            NetworkInfo ni = mCm.getNetworkInfo(type);
-            boolean expectToWork = isSupported(type) && !isNetworkProtected(type) &&
-                    ni != null && ni.isConnected();
-
-            try {
-                assertTrue("Network type " + type,
-                        mCm.requestRouteToHost(type, HOST_ADDRESS) == expectToWork);
-            } catch (Exception e) {
-                Log.d(TAG, "got exception in requestRouteToHost for type " + type);
-                assertFalse("Exception received for type " + type, expectToWork);
-            }
-
-            //TODO verify route table
+            assertRequestRouteToHostUnsupported(type, HOST_ADDRESS);
         }
-
-        assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS));
     }
 
     public void testTest() {
         mCm.getBackgroundDataSetting();
     }
 
-    /** Test that hipri can be brought up when Wifi is enabled. */
-    public void testStartUsingNetworkFeature_enableHipri() throws Exception {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
-                || !mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
-            // This test requires a mobile data connection and WiFi.
+    /**
+     * Exercises both registerNetworkCallback and unregisterNetworkCallback. This checks to
+     * see if we get a callback for the TRANSPORT_WIFI transport type being available.
+     *
+     * <p>In order to test that a NetworkCallback occurs, we need some change in the network
+     * state (either a transport or capability is now available). The most straightforward is
+     * WiFi. We could add a version that uses the telephony data connection but it's not clear
+     * that it would increase test coverage by much (how many devices have 3G radio but not Wifi?).
+     */
+    public void testRegisterNetworkCallback() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
             return;
         }
 
-        boolean isWifiEnabled = mWifiManager.isWifiEnabled();
-        boolean isWifiConnected = false;
+        // We will register for a WIFI network being available or lost.
+        NetworkRequest request = new NetworkRequest.Builder()
+                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                .build();
+        TestNetworkCallback callback = new TestNetworkCallback();
+        mCm.registerNetworkCallback(request, callback);
 
-        NetworkInfo nwInfo = mCm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
-        if (nwInfo != null) {
-            isWifiConnected = nwInfo.isConnected();
-        }
+        boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
+
         try {
-            // Make sure WiFi is connected to an access point.
-            if (!isWifiConnected) {
+            // Make sure WiFi is connected to an access point to start with.
+            if (!previousWifiEnabledState) {
                 connectToWifi();
             }
 
-            // Register a receiver that will capture the connectivity change for hipri.
-            ConnectivityActionReceiver receiver =
-                    new ConnectivityActionReceiver(ConnectivityManager.TYPE_MOBILE_HIPRI);
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-            mContext.registerReceiver(receiver, filter);
-
-            // Try to start using the hipri feature...
-            int result = mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
-                    FEATURE_ENABLE_HIPRI);
-            assertTrue("Couldn't start using the HIPRI feature.", result != -1);
-
-            // Check that the ConnectivityManager reported that it connected using hipri...
-            assertTrue("Couldn't connect using hipri...", receiver.waitForConnection());
-
-            assertTrue("Couldn't requestRouteToHost using HIPRI.",
-                    mCm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, HOST_ADDRESS));
-            // TODO check dns selection
-            // TODO check routes
+            // Now we should expect to get a network callback about availability of the wifi
+            // network even if it was already connected as a state-based action when the callback
+            // is registered.
+            assertTrue("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI",
+                    callback.waitForAvailable());
         } catch (InterruptedException e) {
-            fail("Broadcast receiver waiting for ConnectivityManager interrupted.");
+            fail("Broadcast receiver or NetworkCallback wait was interrupted.");
         } finally {
-            mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
-                    FEATURE_ENABLE_HIPRI);
-            // TODO wait for HIPRI to go
-            // TODO check dns selection
-            // TODO check routes
-            if (!isWifiEnabled) {
-                mWifiManager.setWifiEnabled(false);
+            mCm.unregisterNetworkCallback(callback);
+
+            // Return WiFI to its original enabled/disabled state.
+            if (!previousWifiEnabledState) {
+                disconnectFromWifi();
             }
         }
     }
 
-    private void connectToWifi() throws InterruptedException {
-        ConnectivityActionReceiver receiver =
-                new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI);
+    /**
+     * Tests both registerNetworkCallback and unregisterNetworkCallback similarly to
+     * {@link #testRegisterNetworkCallback} except that a {@code PendingIntent} is used instead
+     * of a {@code NetworkCallback}.
+     */
+    public void testRegisterNetworkCallback_withPendingIntent() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
+            Log.i(TAG, "testRegisterNetworkCallback cannot execute unless device supports WiFi");
+            return;
+        }
+
+        // Create a ConnectivityActionReceiver that has an IntentFilter for our locally defined
+        // action, NETWORK_CALLBACK_ACTION.
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(NETWORK_CALLBACK_ACTION);
+
+        ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
+                ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED);
+        mContext.registerReceiver(receiver, filter);
+
+        // Create a broadcast PendingIntent for NETWORK_CALLBACK_ACTION.
+        Intent intent = new Intent(NETWORK_CALLBACK_ACTION);
+        PendingIntent pendingIntent = PendingIntent.getBroadcast(
+                mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+
+        // We will register for a WIFI network being available or lost.
+        NetworkRequest request = new NetworkRequest.Builder()
+                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                .build();
+        mCm.registerNetworkCallback(request, pendingIntent);
+
+        boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
+
+        try {
+            // Make sure WiFi is connected to an access point to start with.
+            if (!previousWifiEnabledState) {
+                connectToWifi();
+            }
+
+            // Now we expect to get the Intent delivered notifying of the availability of the wifi
+            // network even if it was already connected as a state-based action when the callback
+            // is registered.
+            assertTrue("Did not receive expected Intent " + intent + " for TRANSPORT_WIFI",
+                    receiver.waitForState());
+        } catch (InterruptedException e) {
+            fail("Broadcast receiver or NetworkCallback wait was interrupted.");
+        } finally {
+            mCm.unregisterNetworkCallback(pendingIntent);
+            pendingIntent.cancel();
+            mContext.unregisterReceiver(receiver);
+
+            // Return WiFI to its original enabled/disabled state.
+            if (!previousWifiEnabledState) {
+                disconnectFromWifi();
+            }
+        }
+    }
+
+    /** Enable WiFi and wait for it to become connected to a network. */
+    private void connectToWifi() {
+        ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
+                ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED);
         IntentFilter filter = new IntentFilter();
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         mContext.registerReceiver(receiver, filter);
 
-        assertTrue(mWifiManager.setWifiEnabled(true));
-        assertTrue("Wifi must be configured to connect to an access point for this test.",
-                receiver.waitForConnection());
+        boolean connected = false;
+        try {
+            assertTrue(mWifiManager.setWifiEnabled(true));
+            connected = receiver.waitForState();
+        } catch (InterruptedException ex) {
+            fail("connectToWifi was interrupted");
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
 
-        mContext.unregisterReceiver(receiver);
+        assertTrue("Wifi must be configured to connect to an access point for this test.",
+                connected);
     }
 
-    /** Receiver that captures the last connectivity change's network type and state. */
+    /** Disable WiFi and wait for it to become disconnected from the network. */
+    private void disconnectFromWifi() {
+        ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
+                ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED);
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        mContext.registerReceiver(receiver, filter);
+
+        boolean disconnected = false;
+        try {
+            assertTrue(mWifiManager.setWifiEnabled(false));
+            disconnected = receiver.waitForState();
+        } catch (InterruptedException ex) {
+            fail("disconnectFromWifi was interrupted");
+        } finally {
+            mContext.unregisterReceiver(receiver);
+        }
+
+        assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected);
+    }
+
+    /**
+     * Receiver that captures the last connectivity change's network type and state. Recognizes
+     * both {@code CONNECTIVITY_ACTION} and {@code NETWORK_CALLBACK_ACTION} intents.
+     */
     private class ConnectivityActionReceiver extends BroadcastReceiver {
 
         private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
 
         private final int mNetworkType;
+        private final NetworkInfo.State mNetState;
 
-        ConnectivityActionReceiver(int networkType) {
+        ConnectivityActionReceiver(int networkType, NetworkInfo.State netState) {
             mNetworkType = networkType;
+            mNetState = netState;
         }
 
         public void onReceive(Context context, Intent intent) {
-            NetworkInfo networkInfo = intent.getExtras()
-                    .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO);
+            String action = intent.getAction();
+            NetworkInfo networkInfo = null;
+
+            // When receiving ConnectivityManager.CONNECTIVITY_ACTION, the NetworkInfo parcelable
+            // is stored in EXTRA_NETWORK_INFO. With a NETWORK_CALLBACK_ACTION, the Network is
+            // sent in EXTRA_NETWORK and we need to ask the ConnectivityManager for the NetworkInfo.
+            if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
+                networkInfo = intent.getExtras()
+                        .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO);
+                assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK_INFO", networkInfo);
+            } else if (NETWORK_CALLBACK_ACTION.equals(action)) {
+                Network network = intent.getExtras()
+                        .getParcelable(ConnectivityManager.EXTRA_NETWORK);
+                assertNotNull("ConnectivityActionReceiver expected EXTRA_NETWORK", network);
+                networkInfo = mCm.getNetworkInfo(network);
+                if (networkInfo == null) {
+                    // When disconnecting, it seems like we get an intent sent with an invalid
+                    // Network; that is, by the time we call ConnectivityManager.getNetworkInfo(),
+                    // it is invalid. Ignore these.
+                    Log.i(TAG, "ConnectivityActionReceiver NETWORK_CALLBACK_ACTION ignoring "
+                            + "invalid network");
+                    return;
+                }
+            } else {
+                fail("ConnectivityActionReceiver received unxpected intent action: " + action);
+            }
+
+            assertNotNull("ConnectivityActionReceiver didn't find NetworkInfo", networkInfo);
             int networkType = networkInfo.getType();
             State networkState = networkInfo.getState();
             Log.i(TAG, "Network type: " + networkType + " state: " + networkState);
-            if (networkType == mNetworkType && networkInfo.getState() == State.CONNECTED) {
+            if (networkType == mNetworkType && networkInfo.getState() == mNetState) {
                 mReceiveLatch.countDown();
             }
         }
 
-        public boolean waitForConnection() throws InterruptedException {
+        public boolean waitForState() throws InterruptedException {
             return mReceiveLatch.await(30, TimeUnit.SECONDS);
         }
     }
+
+    /**
+     * Callback used in testRegisterNetworkCallback that allows caller to block on
+     * {@code onAvailable}.
+     */
+    private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
+        private final CountDownLatch mAvailableLatch = new CountDownLatch(1);
+
+        public boolean waitForAvailable() throws InterruptedException {
+            return mAvailableLatch.await(30, TimeUnit.SECONDS);
+        }
+
+        @Override
+        public void onAvailable(Network network) {
+            mAvailableLatch.countDown();
+        }
+    }
+
+    /** Verify restricted networks cannot be requested. */
+    public void testRestrictedNetworks() {
+        // Verify we can request unrestricted networks:
+        NetworkRequest request = new NetworkRequest.Builder()
+                .addCapability(NET_CAPABILITY_INTERNET).build();
+        NetworkCallback callback = new NetworkCallback();
+        mCm.requestNetwork(request, callback);
+        mCm.unregisterNetworkCallback(callback);
+        // Verify we cannot request restricted networks:
+        request = new NetworkRequest.Builder().addCapability(NET_CAPABILITY_IMS).build();
+        callback = new NetworkCallback();
+        try {
+            mCm.requestNetwork(request, callback);
+            fail("No exception thrown when restricted network requested.");
+        } catch (SecurityException e) {
+            // Expected.
+        }
+    }
 }
diff --git a/tests/tests/net/src/android/net/cts/LocalSocketTest.java b/tests/tests/net/src/android/net/cts/LocalSocketTest.java
index 70d69c8..865ec21 100644
--- a/tests/tests/net/src/android/net/cts/LocalSocketTest.java
+++ b/tests/tests/net/src/android/net/cts/LocalSocketTest.java
@@ -112,7 +112,6 @@
     }
 
     public void testAccessors() throws IOException{
-        final int INITIAL_SEND_BUFFER_SIZE = 1998;
         LocalSocket socket = new LocalSocket();
         LocalSocketAddress addr = new LocalSocketAddress("secondary");
 
@@ -127,14 +126,8 @@
         socket.setReceiveBufferSize(1999);
         assertEquals(1999 << 1, socket.getReceiveBufferSize());
 
-        socket.setSendBufferSize(INITIAL_SEND_BUFFER_SIZE);
-        int sendBufferSize = socket.getSendBufferSize();
-        if ((INITIAL_SEND_BUFFER_SIZE << 1) < sendBufferSize) {
-            socket.setSendBufferSize(sendBufferSize / 2);
-            assertEquals(sendBufferSize, socket.getSendBufferSize());
-        } else {
-            assertEquals(INITIAL_SEND_BUFFER_SIZE << 1, sendBufferSize);
-        }
+        socket.setSendBufferSize(3998);
+        assertEquals(3998 << 1, socket.getSendBufferSize());
 
         // Timeout is not support at present, so set is ignored
         socket.setSoTimeout(1996);
diff --git a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
new file mode 100644
index 0000000..51ee50e
--- /dev/null
+++ b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkUtils;
+import android.system.ErrnoException;
+import android.system.OsConstants;
+import android.test.AndroidTestCase;
+
+import java.util.ArrayList;
+
+
+public class MultinetworkApiTest extends AndroidTestCase {
+
+    static {
+        System.loadLibrary("nativemultinetwork_jni");
+    }
+
+    private static final String TAG = "MultinetworkNativeApiTest";
+
+    /**
+     * @return 0 on success
+     */
+    private static native int runGetaddrinfoCheck(long networkHandle);
+    private static native int runSetprocnetwork(long networkHandle);
+    private static native int runSetsocknetwork(long networkHandle);
+    private static native int runDatagramCheck(long networkHandle);
+
+    private ConnectivityManager mCM;
+
+    protected void setUp() throws Exception {
+        super.setUp();
+        mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+    }
+
+    private Network[] getTestableNetworks() {
+        final ArrayList<Network> testableNetworks = new ArrayList<Network>();
+        for (Network network : mCM.getAllNetworks()) {
+            final NetworkCapabilities nc = mCM.getNetworkCapabilities(network);
+            if (nc != null
+                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+                    && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+                testableNetworks.add(network);
+            }
+        }
+
+        assertTrue(
+                "This test requires that at least one network be connected. " +
+                "Please ensure that the device is connected to a network.",
+                testableNetworks.size() >= 1);
+        return testableNetworks.toArray(new Network[0]);
+    }
+
+    public void testGetaddrinfo() throws ErrnoException {
+        for (Network network : getTestableNetworks()) {
+            int errno = runGetaddrinfoCheck(network.getNetworkHandle());
+            if (errno != 0) {
+                throw new ErrnoException(
+                        "getaddrinfo on " + mCM.getNetworkInfo(network), -errno);
+            }
+        }
+    }
+
+    public void testSetprocnetwork() throws ErrnoException {
+        // Hopefully no prior test in this process space has set a default network.
+        assertNull(mCM.getProcessDefaultNetwork());
+        assertEquals(0, NetworkUtils.getBoundNetworkForProcess());
+
+        for (Network network : getTestableNetworks()) {
+            mCM.setProcessDefaultNetwork(null);
+            assertNull(mCM.getProcessDefaultNetwork());
+
+            int errno = runSetprocnetwork(network.getNetworkHandle());
+            if (errno != 0) {
+                throw new ErrnoException(
+                        "setprocnetwork on " + mCM.getNetworkInfo(network), -errno);
+            }
+            Network processDefault = mCM.getProcessDefaultNetwork();
+            assertNotNull(processDefault);
+            assertEquals(network, processDefault);
+            // TODO: open DatagramSockets, connect them to 192.0.2.1 and 2001:db8::,
+            // and ensure that the source address is in fact on this network as
+            // determined by mCM.getLinkProperties(network).
+
+            mCM.setProcessDefaultNetwork(null);
+        }
+
+        for (Network network : getTestableNetworks()) {
+            NetworkUtils.bindProcessToNetwork(0);
+            assertNull(mCM.getBoundNetworkForProcess());
+
+            int errno = runSetprocnetwork(network.getNetworkHandle());
+            if (errno != 0) {
+                throw new ErrnoException(
+                        "setprocnetwork on " + mCM.getNetworkInfo(network), -errno);
+            }
+            assertEquals(network, new Network(mCM.getBoundNetworkForProcess()));
+            // TODO: open DatagramSockets, connect them to 192.0.2.1 and 2001:db8::,
+            // and ensure that the source address is in fact on this network as
+            // determined by mCM.getLinkProperties(network).
+
+            NetworkUtils.bindProcessToNetwork(0);
+        }
+    }
+
+    public void testSetsocknetwork() throws ErrnoException {
+        for (Network network : getTestableNetworks()) {
+            int errno = runSetsocknetwork(network.getNetworkHandle());
+            if (errno != 0) {
+                throw new ErrnoException(
+                        "setsocknetwork on " + mCM.getNetworkInfo(network), -errno);
+            }
+        }
+    }
+
+    public void testNativeDatagramTransmission() throws ErrnoException {
+        for (Network network : getTestableNetworks()) {
+            int errno = runDatagramCheck(network.getNetworkHandle());
+            if (errno != 0) {
+                throw new ErrnoException(
+                        "DatagramCheck on " + mCM.getNetworkInfo(network), -errno);
+            }
+        }
+    }
+
+    public void testNoSuchNetwork() {
+        final Network eNoNet = new Network(54321);
+        assertNull(mCM.getNetworkInfo(eNoNet));
+
+        final long eNoNetHandle = eNoNet.getNetworkHandle();
+        assertEquals(-OsConstants.ENONET, runSetsocknetwork(eNoNetHandle));
+        assertEquals(-OsConstants.ENONET, runSetprocnetwork(eNoNetHandle));
+        // TODO: correct test permissions so this call is not silently re-mapped
+        // to query on the default network.
+        // assertEquals(-OsConstants.ENONET, runGetaddrinfoCheck(eNoNetHandle));
+    }
+}
diff --git a/tests/tests/net/src/android/net/cts/MultinetworkSysctlTest.java b/tests/tests/net/src/android/net/cts/MultinetworkSysctlTest.java
new file mode 100644
index 0000000..c091a13
--- /dev/null
+++ b/tests/tests/net/src/android/net/cts/MultinetworkSysctlTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.net.cts;
+
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
+import android.test.AndroidTestCase;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * Tests for multinetwork sysctl functionality.
+ */
+public class MultinetworkSysctlTest extends AndroidTestCase {
+
+    // Global sysctls. Must be present and set to 1.
+    private static final String[] GLOBAL_SYSCTLS = {
+        "/proc/sys/net/ipv4/fwmark_reflect",
+        "/proc/sys/net/ipv6/fwmark_reflect",
+        "/proc/sys/net/ipv4/tcp_fwmark_accept",
+    };
+
+    // Per-interface IPv6 autoconf sysctls.
+    private static final String IPV6_SYSCTL_DIR = "/proc/sys/net/ipv6/conf";
+    private static final String AUTOCONF_SYSCTL = "accept_ra_rt_table";
+
+    // Expected mode, UID, and GID of sysctl files.
+    private static final int SYSCTL_MODE = 0100644;
+    private static final int SYSCTL_UID = 0;
+    private static final int SYSCTL_GID = 0;
+
+    private void checkSysctlPermissions(String fileName) throws ErrnoException {
+        StructStat stat = Os.stat(fileName);
+        assertEquals("mode of " + fileName + ":", SYSCTL_MODE, stat.st_mode);
+        assertEquals("UID of " + fileName + ":", SYSCTL_UID, stat.st_uid);
+        assertEquals("GID of " + fileName + ":", SYSCTL_GID, stat.st_gid);
+    }
+
+    private void assertLess(String what, int a, int b) {
+        assertTrue(what + " expected < " + b + " but was: " + a, a < b);
+    }
+
+    private String readFile(String fileName) throws ErrnoException, IOException {
+        byte[] buf = new byte[1024];
+        FileDescriptor fd = Os.open(fileName, 0, OsConstants.O_RDONLY);
+        int bytesRead = Os.read(fd, buf, 0, buf.length);
+        assertLess("length of " + fileName + ":", bytesRead, buf.length);
+        return new String(buf);
+    }
+
+    /**
+     * Checks that the sysctls for multinetwork kernel features are present and
+     * enabled. The necessary kernel commits are:
+     *
+     * Mainline Linux:
+     *   e110861 net: add a sysctl to reflect the fwmark on replies
+     *   1b3c61d net: Use fwmark reflection in PMTU discovery.
+     *   84f39b0 net: support marking accepting TCP sockets
+     *
+     * Common Android tree (e.g., 3.10):
+     *   a03f539 net: ipv6: autoconf routes into per-device tables
+     */
+     public void testProcFiles() throws ErrnoException, IOException, NumberFormatException {
+         for (String sysctl : GLOBAL_SYSCTLS) {
+             checkSysctlPermissions(sysctl);
+             int value = Integer.parseInt(readFile(sysctl).trim());
+             assertEquals("value of " + sysctl + ":", 1, value);
+         }
+
+         File[] interfaceDirs = new File(IPV6_SYSCTL_DIR).listFiles();
+         for (File interfaceDir : interfaceDirs) {
+             if (interfaceDir.getName().equals("all") || interfaceDir.getName().equals("lo")) {
+                 continue;
+             }
+             String sysctl = new File(interfaceDir, AUTOCONF_SYSCTL).getAbsolutePath();
+             checkSysctlPermissions(sysctl);
+             int value = Integer.parseInt(readFile(sysctl).trim());
+             assertLess("value of " + sysctl + ":", value, 0);
+         }
+     }
+}
diff --git a/tests/tests/net/src/android/net/cts/MultinetworkTest.java b/tests/tests/net/src/android/net/cts/MultinetworkTest.java
deleted file mode 100644
index 256c030..0000000
--- a/tests/tests/net/src/android/net/cts/MultinetworkTest.java
+++ /dev/null
@@ -1,99 +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.net.cts;
-
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-import android.system.StructStat;
-import android.test.AndroidTestCase;
-
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-/**
- * Tests for multinetwork functionality.
- */
-public class MultinetworkTest extends AndroidTestCase {
-
-    // Global sysctls. Must be present and set to 1.
-    private static final String[] GLOBAL_SYSCTLS = {
-        "/proc/sys/net/ipv4/fwmark_reflect",
-        "/proc/sys/net/ipv6/fwmark_reflect",
-        "/proc/sys/net/ipv4/tcp_fwmark_accept",
-    };
-
-    // Per-interface IPv6 autoconf sysctls.
-    private static final String IPV6_SYSCTL_DIR = "/proc/sys/net/ipv6/conf";
-    private static final String AUTOCONF_SYSCTL = "accept_ra_rt_table";
-
-    // Expected mode, UID, and GID of sysctl files.
-    private static final int SYSCTL_MODE = 0100644;
-    private static final int SYSCTL_UID = 0;
-    private static final int SYSCTL_GID = 0;
-
-    private void checkSysctlPermissions(String fileName) throws ErrnoException {
-        StructStat stat = Os.stat(fileName);
-        assertEquals("mode of " + fileName + ":", SYSCTL_MODE, stat.st_mode);
-        assertEquals("UID of " + fileName + ":", SYSCTL_UID, stat.st_uid);
-        assertEquals("GID of " + fileName + ":", SYSCTL_GID, stat.st_gid);
-    }
-
-    private void assertLess(String what, int a, int b) {
-        assertTrue(what + " expected < " + b + " but was: " + a, a < b);
-    }
-
-    private String readFile(String fileName) throws ErrnoException, IOException {
-        byte[] buf = new byte[1024];
-        FileDescriptor fd = Os.open(fileName, 0, OsConstants.O_RDONLY);
-        int bytesRead = Os.read(fd, buf, 0, buf.length);
-        assertLess("length of " + fileName + ":", bytesRead, buf.length);
-        return new String(buf);
-    }
-
-    /**
-     * Checks that the sysctls for multinetwork kernel features are present and
-     * enabled. The necessary kernel commits are:
-     *
-     * Mainline Linux:
-     *   e110861 net: add a sysctl to reflect the fwmark on replies
-     *   1b3c61d net: Use fwmark reflection in PMTU discovery.
-     *   84f39b0 net: support marking accepting TCP sockets
-     *
-     * Common Android tree (e.g., 3.10):
-     *   a03f539 net: ipv6: autoconf routes into per-device tables
-     */
-     public void testProcFiles() throws ErrnoException, IOException, NumberFormatException {
-         for (String sysctl : GLOBAL_SYSCTLS) {
-             checkSysctlPermissions(sysctl);
-             int value = Integer.parseInt(readFile(sysctl).trim());
-             assertEquals("value of " + sysctl + ":", 1, value);
-         }
-
-         File[] interfaceDirs = new File(IPV6_SYSCTL_DIR).listFiles();
-         for (File interfaceDir : interfaceDirs) {
-             if (interfaceDir.getName().equals("all") || interfaceDir.getName().equals("lo")) {
-                 continue;
-             }
-             String sysctl = new File(interfaceDir, AUTOCONF_SYSCTL).getAbsolutePath();
-             checkSysctlPermissions(sysctl);
-             int value = Integer.parseInt(readFile(sysctl).trim());
-             assertLess("value of " + sysctl + ":", value, 0);
-         }
-     }
-}
diff --git a/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java b/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
index 6175923..60ac226 100644
--- a/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
+++ b/tests/tests/net/src/android/net/cts/SSLCertificateSocketFactoryTest.java
@@ -26,7 +26,7 @@
 import android.net.SSLCertificateSocketFactory;
 import android.test.AndroidTestCase;
 
-import libcore.javax.net.ssl.SSLDefaultConfigurationAsserts;
+import libcore.javax.net.ssl.SSLConfigurationAsserts;
 
 public class SSLCertificateSocketFactoryTest extends AndroidTestCase {
     private SSLCertificateSocketFactory mFactory;
@@ -40,7 +40,7 @@
     }
 
     public void testDefaultConfiguration() throws Exception {
-        SSLDefaultConfigurationAsserts.assertSSLSocketFactory(mFactory);
+        SSLConfigurationAsserts.assertSSLSocketFactoryDefaultConfiguration(mFactory);
     }
 
     public void testAccessProperties() throws Exception {
diff --git a/tests/tests/net/src/android/net/http/cts/ApacheHttpClientTest.java b/tests/tests/net/src/android/net/http/cts/ApacheHttpClientTest.java
index 7d9189f..2e5306d 100644
--- a/tests/tests/net/src/android/net/http/cts/ApacheHttpClientTest.java
+++ b/tests/tests/net/src/android/net/http/cts/ApacheHttpClientTest.java
@@ -21,56 +21,27 @@
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.impl.client.DefaultHttpClient;
 
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.PackageManager;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.NetworkInfo.State;
 import android.net.Uri;
-import android.net.wifi.WifiManager;
 import android.test.AndroidTestCase;
-import android.util.Log;
 import android.webkit.cts.CtsTestServer;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
 
 public class ApacheHttpClientTest extends AndroidTestCase {
 
-    private static final String TAG = ApacheHttpClientTest.class.getSimpleName();
-
     private static final int NUM_DOWNLOADS = 20;
 
     private static final int SMALL_DOWNLOAD_SIZE = 100 * 1024;
 
     private CtsTestServer mWebServer;
 
-    private WifiManager mWifiManager;
-
-    private ConnectivityManager mConnectivityManager;
-
-    private boolean mHasTelephony;
-
-    private boolean mHasWifi;
-
     @Override
     protected void setUp() throws Exception {
         super.setUp();
         mWebServer = new CtsTestServer(mContext);
-        mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
-        mConnectivityManager = (ConnectivityManager)
-                mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
-
-        PackageManager packageManager = mContext.getPackageManager();
-        mHasTelephony = packageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
-        mHasWifi = packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI);
     }
 
     @Override
@@ -79,25 +50,8 @@
         mWebServer.shutdown();
     }
 
-    public void testExecute_withMobile() throws Exception {
-        if (mHasTelephony) {
-            disconnectWifiToConnectToMobile();
-        }
-
+    public void testExecute() throws Exception {
         downloadMultipleFiles();
-
-        if (mHasWifi) {
-            connectToWifi();
-        }
-    }
-
-    public void testExecute_withWifi() throws Exception {
-        if (mHasWifi) {
-            if (!mWifiManager.isWifiEnabled()) {
-                connectToWifi();
-            }
-            downloadMultipleFiles();
-        }
     }
 
     private void downloadMultipleFiles() throws ClientProtocolException, IOException {
@@ -134,77 +88,6 @@
                 numBytes += bytesRead;
             }
         }
-        assertEquals(message, SMALL_DOWNLOAD_SIZE, numBytes);
-    }
-
-    private void connectToWifi() throws InterruptedException {
-        if (!mWifiManager.isWifiEnabled()) {
-            ConnectivityActionReceiver receiver =
-                    new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI, State.CONNECTED);
-            IntentFilter filter = new IntentFilter();
-            filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
-            mContext.registerReceiver(receiver, filter);
-
-            assertTrue(mWifiManager.setWifiEnabled(true));
-            assertTrue("Wifi must be configured to connect to an access point for this test.",
-                    receiver.waitForStateChange());
-
-            mContext.unregisterReceiver(receiver);
-        }
-    }
-
-    private void disconnectWifiToConnectToMobile() throws InterruptedException {
-        if (mHasWifi && mWifiManager.isWifiEnabled()) {
-            ConnectivityActionReceiver connectMobileReceiver =
-                    new ConnectivityActionReceiver(ConnectivityManager.TYPE_MOBILE,
-                            State.CONNECTED);
-            ConnectivityActionReceiver disconnectWifiReceiver =
-                    new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI,
-                            State.DISCONNECTED);
-            IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
-            mContext.registerReceiver(connectMobileReceiver, filter);
-            mContext.registerReceiver(disconnectWifiReceiver, filter);
-
-            assertTrue(mWifiManager.setWifiEnabled(false));
-            assertTrue(disconnectWifiReceiver.waitForStateChange());
-            assertTrue(connectMobileReceiver.waitForStateChange());
-
-            mContext.unregisterReceiver(connectMobileReceiver);
-            mContext.unregisterReceiver(disconnectWifiReceiver);
-        }
-    }
-
-    /** Receiver that captures the last connectivity change's network type and state. */
-    private class ConnectivityActionReceiver extends BroadcastReceiver {
-
-        private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
-
-        private final int mNetworkType;
-
-        private final State mExpectedState;
-
-        ConnectivityActionReceiver(int networkType, State expectedState) {
-            mNetworkType = networkType;
-            mExpectedState = expectedState;
-        }
-
-        public void onReceive(Context context, Intent intent) {
-            NetworkInfo networkInfo = intent.getExtras()
-                    .getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO);
-            int networkType = networkInfo.getType();
-            State networkState = networkInfo.getState();
-            Log.i(TAG, "Network type: " + networkType + " State: " + networkInfo.getState());
-            if (networkType == mNetworkType && networkInfo.getState() == mExpectedState) {
-                mReceiveLatch.countDown();
-            }
-        }
-
-        public boolean waitForStateChange() throws InterruptedException {
-            return mReceiveLatch.await(30, TimeUnit.SECONDS) || hasExpectedState();
-        }
-
-        private boolean hasExpectedState() {
-            return mExpectedState == mConnectivityManager.getNetworkInfo(mNetworkType).getState();
-        }
+        assertEquals(message, expectedNumBytes, numBytes);
     }
 }
diff --git a/tests/tests/net/src/android/net/http/cts/HttpResponseCacheTest.java b/tests/tests/net/src/android/net/http/cts/HttpResponseCacheTest.java
new file mode 100644
index 0000000..545541d6
--- /dev/null
+++ b/tests/tests/net/src/android/net/http/cts/HttpResponseCacheTest.java
@@ -0,0 +1,158 @@
+/*
+ * 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.net.http.cts;
+
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.MockWebServer;
+
+import junit.framework.TestCase;
+
+import android.cts.util.FileUtils;
+import android.net.http.HttpResponseCache;
+
+import java.io.File;
+import java.io.InputStream;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.ResponseCache;
+import java.net.URI;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+public final class HttpResponseCacheTest extends TestCase {
+
+    private File cacheDir;
+    private MockWebServer server = new MockWebServer();
+
+    @Override public void setUp() throws Exception {
+        super.setUp();
+        String tmp = System.getProperty("java.io.tmpdir");
+        cacheDir = new File(tmp, "HttpCache-" + UUID.randomUUID());
+        cacheDir.mkdirs();
+        // Make the cache directory read / writable.
+        FileUtils.setPermissions(cacheDir.getPath(), 0777);
+    }
+
+    @Override protected void tearDown() throws Exception {
+        ResponseCache.setDefault(null);
+        server.shutdown();
+        super.tearDown();
+    }
+
+    public void testInstall() throws Exception {
+        HttpResponseCache installed = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        assertNotNull(installed);
+        assertSame(installed, ResponseCache.getDefault());
+        assertSame(installed, HttpResponseCache.getDefault());
+    }
+
+    public void testSecondEquivalentInstallDoesNothing() throws Exception {
+        HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        HttpResponseCache another = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        assertSame(first, another);
+    }
+
+    public void testInstallClosesPreviouslyInstalled() throws Exception {
+        HttpResponseCache first = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        initializeCache(first);
+
+        HttpResponseCache another = HttpResponseCache.install(cacheDir, 8 * 1024 * 1024);
+        initializeCache(first);
+
+        assertNotSame(first, another);
+        try {
+            first.flush();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testGetInstalledWithWrongTypeInstalled() {
+        ResponseCache.setDefault(new ResponseCache() {
+            @Override public CacheResponse get(URI uri, String requestMethod,
+                    Map<String, List<String>> requestHeaders) {
+                return null;
+            }
+            @Override public CacheRequest put(URI uri, URLConnection connection) {
+                return null;
+            }
+        });
+        assertNull(HttpResponseCache.getInstalled());
+    }
+
+    public void testCloseCloses() throws Exception {
+        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        initializeCache(cache);
+
+        cache.close();
+        try {
+            cache.flush();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testCloseUninstalls() throws Exception {
+        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        cache.close();
+        assertNull(ResponseCache.getDefault());
+    }
+
+    public void testDeleteUninstalls() throws Exception {
+        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+        cache.delete();
+        assertNull(ResponseCache.getDefault());
+    }
+
+    /**
+     * Make sure that statistics tracking are wired all the way through the
+     * wrapper class. http://code.google.com/p/android/issues/detail?id=25418
+     */
+    public void testStatisticsTracking() throws Exception {
+        HttpResponseCache cache = HttpResponseCache.install(cacheDir, 10 * 1024 * 1024);
+
+        server.enqueue(new MockResponse()
+                .addHeader("Cache-Control: max-age=60")
+                .setBody("A"));
+        server.play();
+
+        URLConnection c1 = server.getUrl("/").openConnection();
+        InputStream inputStream1 = c1.getInputStream();
+        assertEquals('A', inputStream1.read());
+        inputStream1.close();
+
+        assertEquals(1, cache.getRequestCount());
+        assertEquals(1, cache.getNetworkCount());
+        assertEquals(0, cache.getHitCount());
+
+        URLConnection c2 = server.getUrl("/").openConnection();
+        assertEquals('A', c2.getInputStream().read());
+
+        URLConnection c3 = server.getUrl("/").openConnection();
+        assertEquals('A', c3.getInputStream().read());
+        assertEquals(3, cache.getRequestCount());
+        assertEquals(1, cache.getNetworkCount());
+        assertEquals(2, cache.getHitCount());
+    }
+
+    private void initializeCache(HttpResponseCache cache) {
+        // Ensure the cache is initialized, otherwise various methods are no-ops.
+        cache.size();
+    }
+}
diff --git a/tests/tests/net/src/android/net/ipv6/cts/PingTest.java b/tests/tests/net/src/android/net/ipv6/cts/PingTest.java
index eddb416..c23ad30 100644
--- a/tests/tests/net/src/android/net/ipv6/cts/PingTest.java
+++ b/tests/tests/net/src/android/net/ipv6/cts/PingTest.java
@@ -155,7 +155,7 @@
     public void testLoopbackPing() throws ErrnoException, IOException {
         // Generate a random ping packet and send it to localhost.
         InetAddress ipv6Loopback = InetAddress.getByName(null);
-        assertEquals("localhost/::1", ipv6Loopback.toString());
+        assertEquals("::1", ipv6Loopback.getHostAddress());
 
         for (int i = 0; i < NUM_PACKETS; i++) {
             byte[] packet = pingPacket((int) (Math.random() * (MAX_SIZE - ICMP_HEADER_SIZE)));
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 6e395aa..2cc5951 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiEnterpriseConfigTest.java
@@ -32,6 +32,10 @@
     private static final String IDENTITY = "identity";
     private static final String PASSWORD = "password";
     private static final String SUBJECT_MATCH = "subjectmatch";
+    private static final String ALT_SUBJECT_MATCH = "altsubjectmatch";
+    private static final String DOM_SUBJECT_MATCH = "domsubjectmatch";
+    private static final String PLMN = "plmn";
+    private static final String REALM = "realm";
     private static final String ANON_IDENTITY = "anonidentity";
     private static final int ENABLE_DELAY = 10000;
 
@@ -87,6 +91,15 @@
         config.setClientKeyEntry(null, null);
         config.setSubjectMatch(SUBJECT_MATCH);
         assertTrue(config.getSubjectMatch().equals(SUBJECT_MATCH));
+        // Hotspot 2.0 related attributes
+        config.setPlmn(PLMN);
+        assertTrue(config.getPlmn().equals(PLMN));
+        config.setRealm(REALM);
+        assertTrue(config.getRealm().equals(REALM));
+        config.setAltSubjectMatch(ALT_SUBJECT_MATCH);
+        assertTrue(config.getAltSubjectMatch().equals(ALT_SUBJECT_MATCH));
+        config.setDomainSuffixMatch(DOM_SUBJECT_MATCH);
+        assertTrue(config.getDomainSuffixMatch().equals(DOM_SUBJECT_MATCH));
     }
 
     public void testAddEapNetwork() {
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 152789c..4478bd4 100644
--- a/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
+++ b/tests/tests/net/src/android/net/wifi/cts/WifiManagerTest.java
@@ -21,6 +21,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.location.LocationManager;
 import android.net.NetworkInfo;
 import android.net.wifi.ScanResult;
 import android.net.wifi.WifiConfiguration;
@@ -29,6 +31,7 @@
 import android.net.wifi.WifiManager.TxPacketCountListener;
 import android.net.wifi.WifiManager.WifiLock;
 import android.os.SystemClock;
+import android.provider.Settings;
 import android.test.AndroidTestCase;
 import android.util.Log;
 
@@ -278,6 +281,14 @@
             Log.d(TAG, "Skipping test as WiFi is not supported");
             return;
         }
+        if (!hasLocationFeature()) {
+            Log.d(TAG, "Skipping test as location is not supported");
+            return;
+        }
+        if (!isLocationEnabled()) {
+            fail("Please enable location for this test - since Marshmallow WiFi scan results are"
+                    + " empty when location is disabled!");
+        }
         if (!mWifiManager.isWifiEnabled()) {
             setWifiEnabled(true);
         }
@@ -307,6 +318,18 @@
         }
     }
 
+    // Return true if location is enabled.
+    private boolean isLocationEnabled() {
+        return Settings.Secure.getInt(getContext().getContentResolver(),
+                Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_OFF) !=
+                Settings.Secure.LOCATION_MODE_OFF;
+    }
+
+    // Returns true if the device has location feature.
+    private boolean hasLocationFeature() {
+        return getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION);
+    }
+
     /**
      * test point of wifiManager NetWork:
      * 1.add NetWork
diff --git a/tests/tests/netsecpolicy/Android.mk b/tests/tests/netsecpolicy/Android.mk
new file mode 100644
index 0000000..137672e
--- /dev/null
+++ b/tests/tests/netsecpolicy/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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java b/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java
new file mode 100644
index 0000000..0ab07ae
--- /dev/null
+++ b/tests/tests/netsecpolicy/src/android/security/NetworkSecurityPolicyTestBase.java
@@ -0,0 +1,380 @@
+package android.security;
+
+import android.app.DownloadManager;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.database.Cursor;
+import android.media.MediaPlayer;
+import android.net.Uri;
+import android.net.http.AndroidHttpClient;
+import android.test.AndroidTestCase;
+import android.webkit.cts.CtsTestServer;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.client.methods.HttpGet;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.UnknownServiceException;
+import java.util.concurrent.CancellationException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+abstract class NetworkSecurityPolicyTestBase extends AndroidTestCase {
+    private CtsTestServer mHttpOnlyWebServer;
+
+    private final boolean mCleartextTrafficExpectedToBePermitted;
+
+    NetworkSecurityPolicyTestBase(boolean cleartextTrafficExpectedToBePermitted) {
+        mCleartextTrafficExpectedToBePermitted = cleartextTrafficExpectedToBePermitted;
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mHttpOnlyWebServer = new CtsTestServer(mContext, false);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        try {
+            mHttpOnlyWebServer.shutdown();
+        } finally {
+            super.tearDown();
+        }
+    }
+
+    public void testNetworkSecurityPolicy() {
+        assertEquals(mCleartextTrafficExpectedToBePermitted,
+                NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted());
+    }
+
+    public void testApplicationInfoFlag() {
+        ApplicationInfo appInfo = getContext().getApplicationInfo();
+        int expectedValue = (mCleartextTrafficExpectedToBePermitted)
+                ? ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC : 0;
+        assertEquals(expectedValue, appInfo.flags & ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC);
+    }
+
+    public void testDefaultHttpURLConnection() throws Exception {
+        if (mCleartextTrafficExpectedToBePermitted) {
+            assertCleartextHttpURLConnectionSucceeds();
+        } else {
+            assertCleartextHttpURLConnectionBlocked();
+        }
+    }
+
+    private void assertCleartextHttpURLConnectionSucceeds() throws Exception {
+        URL url = new URL(mHttpOnlyWebServer.getUserAgentUrl());
+        HttpURLConnection conn = null;
+        try {
+            mHttpOnlyWebServer.resetRequestState();
+            conn = (HttpURLConnection) url.openConnection();
+            conn.setConnectTimeout(5000);
+            conn.setReadTimeout(5000);
+            assertEquals(200, conn.getResponseCode());
+        } finally {
+            if (conn != null) {
+                conn.disconnect();
+            }
+        }
+        Uri uri = Uri.parse(url.toString()).buildUpon().scheme(null).authority(null).build();
+        assertTrue(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    private void assertCleartextHttpURLConnectionBlocked() throws Exception {
+        URL url = new URL(mHttpOnlyWebServer.getUserAgentUrl());
+        HttpURLConnection conn = null;
+        try {
+            mHttpOnlyWebServer.resetRequestState();
+            conn = (HttpURLConnection) url.openConnection();
+            conn.setConnectTimeout(5000);
+            conn.setReadTimeout(5000);
+            conn.getResponseCode();
+            fail();
+        } catch (UnknownServiceException e) {
+            if ((e.getMessage() == null) || (!e.getMessage().toLowerCase().contains("cleartext"))) {
+                fail("Exception with which request failed does not mention cleartext: " + e);
+            }
+        } finally {
+            if (conn != null) {
+                conn.disconnect();
+            }
+        }
+        Uri uri = Uri.parse(url.toString()).buildUpon().scheme(null).authority(null).build();
+        assertFalse(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    public void testAndroidHttpClient() throws Exception {
+        if (mCleartextTrafficExpectedToBePermitted) {
+            assertAndroidHttpClientCleartextRequestSucceeds();
+        } else {
+            assertAndroidHttpClientCleartextRequestBlocked();
+        }
+    }
+
+    private void assertAndroidHttpClientCleartextRequestSucceeds() throws Exception {
+        URL url = new URL(mHttpOnlyWebServer.getUserAgentUrl());
+        AndroidHttpClient httpClient = AndroidHttpClient.newInstance(null);
+        try {
+            HttpResponse response = httpClient.execute(new HttpGet(url.toString()));
+            assertEquals(200, response.getStatusLine().getStatusCode());
+        } finally {
+            httpClient.close();
+        }
+        Uri uri = Uri.parse(url.toString()).buildUpon().scheme(null).authority(null).build();
+        assertTrue(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    private void assertAndroidHttpClientCleartextRequestBlocked() throws Exception {
+        URL url = new URL(mHttpOnlyWebServer.getUserAgentUrl());
+        AndroidHttpClient httpClient = AndroidHttpClient.newInstance(null);
+        try {
+            HttpResponse response = httpClient.execute(new HttpGet(url.toString()));
+            fail();
+        } catch (IOException e) {
+            if ((e.getMessage() == null) || (!e.getMessage().toLowerCase().contains("cleartext"))) {
+                fail("Exception with which request failed does not mention cleartext: " + e);
+            }
+        } finally {
+            httpClient.close();
+        }
+        Uri uri = Uri.parse(url.toString()).buildUpon().scheme(null).authority(null).build();
+        assertFalse(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    public void testMediaPlayer() throws Exception {
+        if (mCleartextTrafficExpectedToBePermitted) {
+            assertMediaPlayerCleartextRequestSucceeds();
+        } else {
+            assertMediaPlayerCleartextRequestBlocked();
+        }
+    }
+
+    private void assertMediaPlayerCleartextRequestSucceeds() throws Exception {
+        MediaPlayer mediaPlayer = new MediaPlayer();
+        Uri uri = Uri.parse(mHttpOnlyWebServer.getUserAgentUrl());
+        mediaPlayer.setDataSource(getContext(), uri);
+
+        try {
+            mediaPlayer.prepare();
+        } catch (IOException expected) {
+        } finally {
+            try {
+                mediaPlayer.stop();
+            } catch (IllegalStateException ignored) {
+            }
+        }
+        uri = uri.buildUpon().scheme(null).authority(null).build();
+        assertTrue(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    private void assertMediaPlayerCleartextRequestBlocked() throws Exception {
+        MediaPlayer mediaPlayer = new MediaPlayer();
+        Uri uri = Uri.parse(mHttpOnlyWebServer.getUserAgentUrl());
+        mediaPlayer.setDataSource(getContext(), uri);
+
+        try {
+            mediaPlayer.prepare();
+        } catch (IOException expected) {
+        } finally {
+            try {
+                mediaPlayer.stop();
+            } catch (IllegalStateException ignored) {
+            }
+        }
+        uri = uri.buildUpon().scheme(null).authority(null).build();
+        assertFalse(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+    }
+
+    public void testDownloadManager() throws Exception {
+        Uri uri = Uri.parse(mHttpOnlyWebServer.getTestDownloadUrl("netsecpolicy", 0));
+        int[] result = downloadUsingDownloadManager(uri);
+        int status = result[0];
+        int reason = result[1];
+        uri = uri.buildUpon().scheme(null).authority(null).build();
+        if (mCleartextTrafficExpectedToBePermitted) {
+            assertEquals(DownloadManager.STATUS_SUCCESSFUL, status);
+            assertTrue(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+        } else {
+            assertEquals(DownloadManager.STATUS_FAILED, status);
+            assertEquals(400, reason);
+            assertFalse(mHttpOnlyWebServer.wasResourceRequested(uri.toString()));
+        }
+    }
+
+
+    private int[] downloadUsingDownloadManager(Uri uri) throws Exception {
+        DownloadManager downloadManager =
+                (DownloadManager) getContext().getSystemService(Context.DOWNLOAD_SERVICE);
+        removeAllDownloads(downloadManager);
+        BroadcastReceiver downloadCompleteReceiver = null;
+        try {
+            final SettableFuture<Intent> downloadCompleteIntentFuture = new SettableFuture<Intent>();
+            downloadCompleteReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    downloadCompleteIntentFuture.set(intent);
+                }
+            };
+            getContext().registerReceiver(
+                    downloadCompleteReceiver,
+                    new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
+
+            Intent downloadCompleteIntent;
+
+            long downloadId = downloadManager.enqueue(new DownloadManager.Request(uri));
+            downloadCompleteIntent = downloadCompleteIntentFuture.get(5, TimeUnit.SECONDS);
+
+            assertEquals(downloadId,
+                    downloadCompleteIntent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1));
+            Cursor c = downloadManager.query(
+                    new DownloadManager.Query().setFilterById(downloadId));
+            try {
+                if (!c.moveToNext()) {
+                    fail("Download not found");
+                    return null;
+                }
+                int status = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
+                int reason = c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_REASON));
+                return new int[] {status, reason};
+            } finally {
+                c.close();
+            }
+        } finally {
+            if (downloadCompleteReceiver != null) {
+                getContext().unregisterReceiver(downloadCompleteReceiver);
+            }
+            removeAllDownloads(downloadManager);
+        }
+    }
+
+    private static void removeAllDownloads(DownloadManager downloadManager) {
+        Cursor cursor = null;
+        try {
+            DownloadManager.Query query = new DownloadManager.Query();
+            cursor = downloadManager.query(query);
+            if (cursor.getCount() == 0) {
+                return;
+            }
+            long[] removeIds = new long[cursor.getCount()];
+            int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_ID);
+            for (int i = 0; cursor.moveToNext(); i++) {
+                removeIds[i] = cursor.getLong(columnIndex);
+            }
+            assertEquals(removeIds.length, downloadManager.remove(removeIds));
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+
+    private static class SettableFuture<T> implements Future<T> {
+
+        private final Object mLock = new Object();
+        private boolean mDone;
+        private boolean mCancelled;
+        private T mValue;
+        private Throwable mException;
+
+        public void set(T value) {
+            synchronized (mLock) {
+                if (!mDone) {
+                    mValue = value;
+                    mDone = true;
+                    mLock.notifyAll();
+                }
+            }
+        }
+
+        public void setException(Throwable exception) {
+            synchronized (mLock) {
+                if (!mDone) {
+                    mException = exception;
+                    mDone = true;
+                    mLock.notifyAll();
+                }
+            }
+        }
+
+        @Override
+        public boolean cancel(boolean mayInterruptIfRunning) {
+            synchronized (mLock) {
+                if (mDone) {
+                    return false;
+                }
+                mCancelled = true;
+                mDone = true;
+                mLock.notifyAll();
+                return true;
+            }
+        }
+
+        @Override
+        public T get() throws InterruptedException, ExecutionException {
+            synchronized (mLock) {
+                while (!mDone) {
+                    mLock.wait();
+                }
+                return getValue();
+            }
+        }
+
+        @Override
+        public T get(long timeout, TimeUnit timeUnit)
+                throws InterruptedException, ExecutionException, TimeoutException {
+            synchronized (mLock) {
+                if (mDone) {
+                    return getValue();
+                }
+                long timeoutMillis = timeUnit.toMillis(timeout);
+                long deadlineTimeMillis = System.currentTimeMillis() + timeoutMillis;
+
+                while (!mDone) {
+                    long millisTillDeadline = deadlineTimeMillis - System.currentTimeMillis();
+                    if ((millisTillDeadline <= 0) || (millisTillDeadline > timeoutMillis)) {
+                        throw new TimeoutException();
+                    }
+                    mLock.wait(millisTillDeadline);
+                }
+                return getValue();
+            }
+        }
+
+        private T getValue() throws ExecutionException {
+            synchronized (mLock) {
+                if (!mDone) {
+                    throw new IllegalStateException("Not yet done");
+                }
+                if (mCancelled) {
+                    throw new CancellationException();
+                }
+                if (mException != null) {
+                    throw new ExecutionException(mException);
+                }
+                return mValue;
+            }
+        }
+
+        @Override
+        public boolean isCancelled() {
+            synchronized (mLock) {
+                return mCancelled;
+            }
+        }
+
+        @Override
+        public boolean isDone() {
+            synchronized (mLock) {
+                return mDone;
+            }
+        }
+    }
+}
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-false/Android.mk b/tests/tests/netsecpolicy/usescleartexttraffic-false/Android.mk
new file mode 100644
index 0000000..01ea6b7
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-false/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_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner \
+    ctstestserver \
+    org.apache.http.legacy
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src common)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficFalseTestCases
+
+LOCAL_INSTRUMENTATION_FOR := CtsNetSecPolicyUsesCleartextTrafficFalse
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml b/tests/tests/netsecpolicy/usescleartexttraffic-false/AndroidManifest.xml
new file mode 100644
index 0000000..49385f8
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-false/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="com.android.cts.netsecpolicy.usescleartext.false">
+
+  <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.netsecpolicy.usescleartext.false.cts"
+                   android:label="Tests for NetworkSecurityPolicy cleartext traffic policy when it is set to denied.">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-false/common b/tests/tests/netsecpolicy/usescleartexttraffic-false/common
new file mode 120000
index 0000000..5cd551cf
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-false/common
@@ -0,0 +1 @@
+../src
\ No newline at end of file
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-false/src/android/security/NetworkSecurityPolicyCleartextDeniedTest.java b/tests/tests/netsecpolicy/usescleartexttraffic-false/src/android/security/NetworkSecurityPolicyCleartextDeniedTest.java
new file mode 100644
index 0000000..f5d9770
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-false/src/android/security/NetworkSecurityPolicyCleartextDeniedTest.java
@@ -0,0 +1,9 @@
+package android.security;
+
+public class NetworkSecurityPolicyCleartextDeniedTest extends NetworkSecurityPolicyTestBase {
+
+    public NetworkSecurityPolicyCleartextDeniedTest() {
+        super(false // expect cleartext traffic to be blocked
+                );
+    }
+}
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-true/Android.mk b/tests/tests/netsecpolicy/usescleartexttraffic-true/Android.mk
new file mode 100644
index 0000000..9f53f18
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-true/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_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner \
+    ctstestserver \
+    org.apache.http.legacy
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src common)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficTrueTestCases
+
+LOCAL_INSTRUMENTATION_FOR := CtsNetSecPolicyUsesCleartextTrafficTrue
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml b/tests/tests/netsecpolicy/usescleartexttraffic-true/AndroidManifest.xml
new file mode 100644
index 0000000..be698f2
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-true/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="com.android.cts.netsecpolicy.usescleartext.true">
+
+  <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.netsecpolicy.usescleartext.true.cts"
+                   android:label="Tests for NetworkSecurityPolicy cleartext traffic policy when it is set to permitted.">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-true/common b/tests/tests/netsecpolicy/usescleartexttraffic-true/common
new file mode 120000
index 0000000..5cd551cf
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-true/common
@@ -0,0 +1 @@
+../src
\ No newline at end of file
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-true/src/android/security/NetworkSecurityPolicyCleartextPermittedTest.java b/tests/tests/netsecpolicy/usescleartexttraffic-true/src/android/security/NetworkSecurityPolicyCleartextPermittedTest.java
new file mode 100644
index 0000000..83c1049
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-true/src/android/security/NetworkSecurityPolicyCleartextPermittedTest.java
@@ -0,0 +1,9 @@
+package android.security;
+
+public class NetworkSecurityPolicyCleartextPermittedTest extends NetworkSecurityPolicyTestBase {
+
+    public NetworkSecurityPolicyCleartextPermittedTest() {
+        super(true // expect cleartext traffic to be permitted
+                );
+    }
+}
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/Android.mk
new file mode 100644
index 0000000..fe7d36e
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/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_MODULE_TAGS := optional
+
+LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner \
+    ctstestserver \
+    org.apache.http.legacy
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src common)
+
+LOCAL_PACKAGE_NAME := CtsNetSecPolicyUsesCleartextTrafficUnspecifiedTestCases
+
+LOCAL_INSTRUMENTATION_FOR := CtsNetSecPolicyUsesCleartextTrafficUnspecified
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/AndroidManifest.xml
new file mode 100644
index 0000000..7bd8742
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/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="com.android.cts.netsecpolicy.usescleartext.unspecified">
+
+  <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.netsecpolicy.usescleartext.unspecified.cts"
+                   android:label="Tests for NetworkSecurityPolicy cleartext traffic policy when it is not specified.">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/common b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/common
new file mode 120000
index 0000000..5cd551cf
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/common
@@ -0,0 +1 @@
+../src
\ No newline at end of file
diff --git a/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/src/android/security/NetworkSecurityPolicyCleartextUnspecifiedTest.java b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/src/android/security/NetworkSecurityPolicyCleartextUnspecifiedTest.java
new file mode 100644
index 0000000..5690f31
--- /dev/null
+++ b/tests/tests/netsecpolicy/usescleartexttraffic-unspecified/src/android/security/NetworkSecurityPolicyCleartextUnspecifiedTest.java
@@ -0,0 +1,9 @@
+package android.security;
+
+public class NetworkSecurityPolicyCleartextUnspecifiedTest extends NetworkSecurityPolicyTestBase {
+
+    public NetworkSecurityPolicyCleartextUnspecifiedTest() {
+        super(true // expect cleartext traffic to be permitted
+                );
+    }
+}
diff --git a/tests/tests/openglperf/Android.mk b/tests/tests/openglperf/Android.mk
index 7be16e8..6b42ed0 100644
--- a/tests/tests/openglperf/Android.mk
+++ b/tests/tests/openglperf/Android.mk
@@ -38,4 +38,10 @@
 
 include $(BUILD_CTS_PACKAGE)
 
+# Make the replica island app and copy it to CTS out dir.
+cts_replica_name := com.replica.replicaisland
+cts_replica_apk := $(CTS_TESTCASES_OUT)/$(cts_replica_name).apk
+$(cts_replica_apk): $(call intermediates-dir-for,APPS,$(cts_replica_name))/package.apk
+	$(call copy-file-to-target)
+
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/os/Android.mk b/tests/tests/os/Android.mk
index 9dfb86e..f4b140e 100644
--- a/tests/tests/os/Android.mk
+++ b/tests/tests/os/Android.mk
@@ -31,6 +31,7 @@
 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
diff --git a/tests/tests/os/AndroidManifest.xml b/tests/tests/os/AndroidManifest.xml
index f225903..deb7045 100644
--- a/tests/tests/os/AndroidManifest.xml
+++ b/tests/tests/os/AndroidManifest.xml
@@ -120,6 +120,10 @@
             </intent-filter>
         </service>
 
+        <service android:name="android.os.cts.SeccompTest$IsolatedService"
+                android:isolatedProcess="true">
+        </service>
+
         <service android:name="android.os.cts.MessengerService"
                 android:process=":messengerService">
         </service>
diff --git a/tests/tests/os/jni/Android.mk b/tests/tests/os/jni/Android.mk
index 32a5a9c..c125f5c 100644
--- a/tests/tests/os/jni/Android.mk
+++ b/tests/tests/os/jni/Android.mk
@@ -25,12 +25,44 @@
 		CtsOsJniOnLoad.cpp \
 		android_os_cts_CpuInstructions.cpp.arm \
 		android_os_cts_TaggedPointer.cpp \
+		android_os_cts_HardwareName.cpp \
 		android_os_cts_OSFeatures.cpp \
-		android_os_cts_NoExecutePermissionTest.cpp
+		android_os_cts_NoExecutePermissionTest.cpp \
+		android_os_cts_SeccompTest.cpp
+
+# 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
+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
+endif
+
+ifeq ($(ARCH_SUPPORTS_SECCOMP),1)
+	LOCAL_SRC_FILES += seccomp-tests/tests/seccomp_bpf_tests.c \
+			seccomp_sample_program.cpp
+
+	# This define controls the behavior of OSFeatures.needsSeccompSupport().
+	LOCAL_CFLAGS += -DARCH_SUPPORTS_SECCOMP
+endif
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog libdl
+LOCAL_SHARED_LIBRARIES := libnativehelper liblog libdl libcutils
 
 LOCAL_SRC_FILES += android_os_cts_CpuFeatures.cpp
 LOCAL_C_INCLUDES += ndk/sources/cpufeatures
diff --git a/tests/tests/os/jni/CtsOsJniOnLoad.cpp b/tests/tests/os/jni/CtsOsJniOnLoad.cpp
index 3920915..cac750f 100644
--- a/tests/tests/os/jni/CtsOsJniOnLoad.cpp
+++ b/tests/tests/os/jni/CtsOsJniOnLoad.cpp
@@ -23,10 +23,14 @@
 
 extern int register_android_os_cts_TaggedPointer(JNIEnv*);
 
+extern int register_android_os_cts_HardwareName(JNIEnv*);
+
 extern int register_android_os_cts_OSFeatures(JNIEnv*);
 
 extern int register_android_os_cts_NoExecutePermissionTest(JNIEnv*);
 
+extern int register_android_os_cts_SeccompTest(JNIEnv*);
+
 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
     JNIEnv *env = NULL;
 
@@ -46,6 +50,10 @@
         return JNI_ERR;
     }
 
+    if (register_android_os_cts_HardwareName(env)) {
+        return JNI_ERR;
+    }
+
     if (register_android_os_cts_OSFeatures(env)) {
         return JNI_ERR;
     }
@@ -54,5 +62,9 @@
         return JNI_ERR;
     }
 
+    if (register_android_os_cts_SeccompTest(env)) {
+        return JNI_ERR;
+    }
+
     return JNI_VERSION_1_4;
 }
diff --git a/tests/tests/os/jni/android_os_cts_CpuInstructions.cpp b/tests/tests/os/jni/android_os_cts_CpuInstructions.cpp
index 3eea71b..15006f0 100644
--- a/tests/tests/os/jni/android_os_cts_CpuInstructions.cpp
+++ b/tests/tests/os/jni/android_os_cts_CpuInstructions.cpp
@@ -19,6 +19,7 @@
 #if defined(__arm__) || defined(__aarch64__)
 #include <setjmp.h>
 #include <signal.h>
+#include <string.h>
 
 static sigjmp_buf jmpenv;
 
diff --git a/tests/tests/os/jni/android_os_cts_HardwareName.cpp b/tests/tests/os/jni/android_os_cts_HardwareName.cpp
new file mode 100644
index 0000000..6752aa3
--- /dev/null
+++ b/tests/tests/os/jni/android_os_cts_HardwareName.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <cutils/properties.h>
+
+jstring android_os_cts_HardwareName_getName(JNIEnv* env, jobject thiz)
+{
+    char name[PROPERTY_VALUE_MAX];
+    int ret;
+
+    ret = property_get("ro.boot.hardware", name, NULL);
+    if (ret <= 0) {
+        return NULL;
+    }
+
+    return env->NewStringUTF(name);
+}
+
+static JNINativeMethod gMethods[] = {
+    {  "getName", "()Ljava/lang/String;",
+            (void *) android_os_cts_HardwareName_getName },
+};
+
+int register_android_os_cts_HardwareName(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("android/os/cts/HardwareName");
+
+    return env->RegisterNatives(clazz, gMethods,
+            sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/os/jni/android_os_cts_NoExecutePermissionTest.cpp b/tests/tests/os/jni/android_os_cts_NoExecutePermissionTest.cpp
index e30599c..5425fde 100644
--- a/tests/tests/os/jni/android_os_cts_NoExecutePermissionTest.cpp
+++ b/tests/tests/os/jni/android_os_cts_NoExecutePermissionTest.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  *
  */
+#include <errno.h>
 #include <jni.h>
 #include <string.h>
 #include <stdio.h>
diff --git a/tests/tests/os/jni/android_os_cts_OSFeatures.cpp b/tests/tests/os/jni/android_os_cts_OSFeatures.cpp
index 5f3ee4e..153fb27 100644
--- a/tests/tests/os/jni/android_os_cts_OSFeatures.cpp
+++ b/tests/tests/os/jni/android_os_cts_OSFeatures.cpp
@@ -14,18 +14,21 @@
  * limitations under the License.
  *
  */
-#include <jni.h>
-#include <sys/prctl.h>
-#include <string.h>
+
+#include "jni.h"
+
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <unistd.h>
 
 #include <linux/filter.h>
 #include <linux/seccomp.h>
 
-#include <sys/utsname.h>
+#include <sys/prctl.h>
 #include <sys/types.h>
+#include <sys/utsname.h>
 #include <sys/wait.h>
 
 jint android_os_cts_OSFeatures_getNoNewPrivs(JNIEnv* env, jobject thiz)
@@ -81,8 +84,9 @@
 
 jboolean android_os_cts_OSFeatures_needsSeccompSupport(JNIEnv*, jobject)
 {
-#if !defined(__arm__) && !defined(__i386__) && !defined(__x86_64__)
+#if !defined(ARCH_SUPPORTS_SECCOMP)
     // Seccomp support is only available for ARM, x86, x86_64.
+    // This define is controlled by the Android.mk.
     return false;
 #endif
 
diff --git a/tests/tests/os/jni/android_os_cts_SeccompTest.cpp b/tests/tests/os/jni/android_os_cts_SeccompTest.cpp
new file mode 100644
index 0000000..1ba8550
--- /dev/null
+++ b/tests/tests/os/jni/android_os_cts_SeccompTest.cpp
@@ -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.
+ */
+
+#include <android/log.h>
+#include <jni.h>
+#include <string.h>
+#include <time.h>
+
+#if defined(ARCH_SUPPORTS_SECCOMP)
+#include <linux/filter.h>
+#include <linux/seccomp.h>
+#include <sys/syscall.h>
+#endif
+
+#include "seccomp_sample_program.h"
+#include "seccomp-tests/tests/test_harness.h"
+
+// Forward declare from seccomp_bpf_tests.c.
+extern "C" {
+struct __test_metadata* get_seccomp_test_list();
+}
+
+static const char TAG[] = "SeccompBpfTest-Native";
+
+jboolean android_security_cts_SeccompBpfTest_runKernelUnitTest(
+      JNIEnv* env, jobject thiz __unused, jstring name) {
+#if defined(ARCH_SUPPORTS_SECCOMP)
+    const char* nameStr = env->GetStringUTFChars(name, nullptr);
+
+    for (struct __test_metadata* t = get_seccomp_test_list(); t; t = t->next) {
+        if (strcmp(t->name, nameStr) == 0) {
+            __android_log_print(ANDROID_LOG_INFO, TAG, "Start: %s", t->name);
+            __run_test(t);
+            __android_log_print(ANDROID_LOG_INFO, TAG, "%s: %s",
+                t->passed ? "PASS" : "FAIL", t->name);
+            return t->passed;
+        }
+    }
+#endif  // ARCH_SUPPORTS_SECCOMP
+
+    return false;
+}
+
+jboolean android_security_cts_SeccompBpfTest_installTestFilter(JNIEnv*, jclass) {
+#if !defined(ARCH_SUPPORTS_SECCOMP)
+  return false;
+#else
+  struct sock_fprog prog = GetTestSeccompFilterProgram();
+
+  if (prog.len == 0)
+    return false;
+
+  int rv = syscall(__NR_seccomp, SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, &prog);
+  return rv == 0;
+#endif
+}
+
+jint android_security_cts_SeccompBpfTest_getClockBootTime(JNIEnv*, jclass) {
+  struct timespec ts;
+  int rv = clock_gettime(CLOCK_BOOTTIME, &ts);
+  return rv;
+}
+
+static JNINativeMethod methods[] = {
+    { "runKernelUnitTest", "(Ljava/lang/String;)Z",
+        (void*)android_security_cts_SeccompBpfTest_runKernelUnitTest },
+    { "installTestFilter", "()Z",
+        (void*)android_security_cts_SeccompBpfTest_installTestFilter },
+    { "getClockBootTime", "()I",
+        (void*)android_security_cts_SeccompBpfTest_getClockBootTime },
+};
+
+int register_android_os_cts_SeccompTest(JNIEnv* env) {
+    jclass clazz = env->FindClass("android/os/cts/SeccompTest");
+    return env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/os/jni/android_os_cts_TaggedPointer.cpp b/tests/tests/os/jni/android_os_cts_TaggedPointer.cpp
index e8f83a3..f656f50 100644
--- a/tests/tests/os/jni/android_os_cts_TaggedPointer.cpp
+++ b/tests/tests/os/jni/android_os_cts_TaggedPointer.cpp
@@ -20,6 +20,7 @@
 #include <signal.h>
 #include <stdbool.h>
 #include <stdlib.h>
+#include <string.h>
 
 //mask the top 8 bits
 #define TAG_MASK ((0xFFULL) << 56)
diff --git a/tests/tests/os/jni/seccomp-tests/LICENSE b/tests/tests/os/jni/seccomp-tests/LICENSE
new file mode 100644
index 0000000..b9e779f
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/LICENSE
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium OS Authors. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//    * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//    * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//    * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tests/tests/os/jni/seccomp-tests/README b/tests/tests/os/jni/seccomp-tests/README
new file mode 100644
index 0000000..c8cd2ad
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/README
@@ -0,0 +1,4 @@
+seccomp
+-------
+
+Landing place for code relating to seccomp_filter work for the Linux kernel.
diff --git a/tests/tests/os/jni/seccomp-tests/README.android b/tests/tests/os/jni/seccomp-tests/README.android
new file mode 100644
index 0000000..8b1ac9a
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/README.android
@@ -0,0 +1,17 @@
+This is the kernel unittest for seccomp-bpf sandboxing.
+
+URL: https://github.com/redpig/seccomp
+Revision: e65c79a14dc2bbb6d8dbf12ebf71905e2253a4b2
+License: BSD
+
+Local modifications:
+- Remove usage of pthread_cancel()
+- Use __android_log_print() instead of fprintf()
+- Rename main() to seccomp_test_main()
+- Add get_seccomp_test_list()
+
+The diff of modifications can be found in local-modifications-android.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 file. The patch is located in local-modifications-strict-args-fd88d16.diff.
diff --git a/tests/tests/os/jni/seccomp-tests/local-modifications-android.diff b/tests/tests/os/jni/seccomp-tests/local-modifications-android.diff
new file mode 100644
index 0000000..288261a
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/local-modifications-android.diff
@@ -0,0 +1,59 @@
+diff --git a/tests/seccomp_bpf_tests.c b/tests/seccomp_bpf_tests.c
+index deb78d1..98b0231 100644
+--- a/tests/seccomp_bpf_tests.c
++++ b/tests/seccomp_bpf_tests.c
+@@ -1457,7 +1457,7 @@ FIXTURE_TEARDOWN(TSYNC) {
+ 		if (!s->tid)
+ 			continue;
+ 		if (pthread_kill(s->tid, 0)) {
+-			pthread_cancel(s->tid);
++			//pthread_cancel(s->tid);  // ANDROID
+ 			pthread_join(s->tid, &status);
+ 		}
+ 	}
+@@ -1940,4 +1940,10 @@ TEST(syscall_restart) {
+  * - ...
+  */
+ 
++// ANDROID:begin
++struct __test_metadata* get_seccomp_test_list() {
++  return __test_list;
++}
++// ANDROID:end
++
+ TEST_HARNESS_MAIN
+diff --git a/tests/test_harness.h b/tests/test_harness.h
+index 47ee027..597e40c 100644
+--- a/tests/test_harness.h
++++ b/tests/test_harness.h
+@@ -49,6 +49,8 @@
+ #include <sys/wait.h>
+ #include <unistd.h>
+ 
++#include <android/log.h>  // ANDROID
++
+ /* All exported functionality should be declared through this macro. */
+ #define TEST_API(x) _##x
+ 
+@@ -206,9 +208,11 @@
+ } while (0)
+ 
+ /* Unconditional logger for internal use. */
++// ANDROID:begin
+ #define __TH_LOG(fmt, ...) \
+-    fprintf(TH_LOG_STREAM, "%s:%d:%s:" fmt "\n", \
++    __android_log_print(ANDROID_LOG_ERROR, "SeccompBpfTest-KernelUnit", "%s:%d:%s:" fmt "\n", \
+             __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)
++// ANDROID:end
+ 
+ /* Defines the test function and creates the registration stub. */
+ #define _TEST(test_name) __TEST_IMPL(test_name, -1)
+@@ -292,7 +296,7 @@
+     if (!__constructor_order) \
+       __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \
+   } \
+-  int main(int argc, char **argv) { return test_harness_run(argc, argv); }
++  int seccomp_test_main(int argc, char **argv) { return test_harness_run(argc, argv); }  // ANDROID
+ 
+ #define _ASSERT_EQ(_expected, _seen) \
+   __EXPECT(_expected, _seen, ==, 1)
diff --git a/tests/tests/os/jni/seccomp-tests/local-modifications-strict-args-fd88d16.diff b/tests/tests/os/jni/seccomp-tests/local-modifications-strict-args-fd88d16.diff
new file mode 100644
index 0000000..a289147
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/local-modifications-strict-args-fd88d16.diff
@@ -0,0 +1,102 @@
+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 98b0231..3c238e6 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
+@@ -28,6 +28,9 @@
+ #include <string.h>
+ #include <linux/elf.h>
+ #include <sys/uio.h>
++#include <fcntl.h>  // ANDROID
++#include <sys/mman.h>
++#include <sys/times.h>
+ 
+ #define _GNU_SOURCE
+ #include <unistd.h>
+@@ -386,14 +389,16 @@ TEST_SIGNAL(KILL_one, SIGSYS) {
+ }
+ 
+ TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
++	void *fatal_address;
+ 	struct sock_filter filter[] = {
+ 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+ 			offsetof(struct seccomp_data, nr)),
+-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
++		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_times, 1, 0),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ 		/* Only both with lower 32-bit for now. */
+ 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)),
+-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1),
++		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K,
++			(unsigned long)&fatal_address, 0, 1),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ 	};
+@@ -403,23 +408,29 @@ TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
+ 	};
+ 	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ 	pid_t parent = getppid();
+-	pid_t pid = getpid();
++	struct tms timebuf;
++	clock_t clock = times(&timebuf);
+ 	ASSERT_EQ(0, ret);
+ 
+ 	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+ 	ASSERT_EQ(0, ret);
+ 
+ 	EXPECT_EQ(parent, syscall(__NR_getppid));
+-	EXPECT_EQ(pid, syscall(__NR_getpid));
+-	/* getpid() should never return. */
+-	EXPECT_EQ(0, syscall(__NR_getpid, 0x0C0FFEE));
++	EXPECT_LE(clock, syscall(__NR_times, &timebuf));
++	/* times() should never return. */
++	EXPECT_EQ(0, syscall(__NR_times, &fatal_address));
+ }
+ 
+ TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
++#ifndef __NR_mmap2
++	int sysno = __NR_mmap;
++#else
++	int sysno = __NR_mmap2;
++#endif
+ 	struct sock_filter filter[] = {
+ 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+ 			offsetof(struct seccomp_data, nr)),
+-		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
++		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, sysno, 1, 0),
+ 		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+ 		/* Only both with lower 32-bit for now. */
+ 		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)),
+@@ -433,16 +444,29 @@ TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
+ 	};
+ 	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+ 	pid_t parent = getppid();
+-	pid_t pid = getpid();
++	int fd;
++	void *map1, *map2;
+ 	ASSERT_EQ(0, ret);
+ 
+ 	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+ 	ASSERT_EQ(0, ret);
+ 
++	fd = open("/dev/zero", O_RDONLY);
++	ASSERT_NE(-1, fd);
++
+ 	EXPECT_EQ(parent, syscall(__NR_getppid));
+-	EXPECT_EQ(pid, syscall(__NR_getpid));
+-	/* getpid() should never return. */
+-	EXPECT_EQ(0, syscall(__NR_getpid, 1, 2, 3, 4, 5, 0x0C0FFEE));
++	map1 = (void *)syscall(sysno,
++		NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, PAGE_SIZE);
++	EXPECT_NE(MAP_FAILED, map1);
++	/* mmap2() should never return. */
++	map2 = (void *)syscall(sysno,
++		 NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);
++	EXPECT_EQ(MAP_FAILED, map2);
++
++	/* The test failed, so clean up the resources. */
++	munmap(map1, PAGE_SIZE);
++	munmap(map2, PAGE_SIZE);
++	close(fd);
+ }
+ 
+ /* TODO(wad) add 64-bit versus 32-bit arg tests. */
diff --git a/tests/tests/os/jni/seccomp-tests/tests/.gitignore b/tests/tests/os/jni/seccomp-tests/tests/.gitignore
new file mode 100644
index 0000000..cdfc7c6
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/tests/.gitignore
@@ -0,0 +1,3 @@
+sigsegv
+resumption
+seccomp_bpf_tests
diff --git a/tests/tests/os/jni/seccomp-tests/tests/Makefile b/tests/tests/os/jni/seccomp-tests/tests/Makefile
new file mode 100644
index 0000000..88994b3
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/tests/Makefile
@@ -0,0 +1,23 @@
+CFLAGS += -Wall
+EXEC=resumption seccomp_bpf_tests sigsegv
+
+all: $(EXEC)
+
+clean:
+	rm -f $(EXEC)
+
+seccomp_bpf_tests: seccomp_bpf_tests.c test_harness.h
+	$(CC) seccomp_bpf_tests.c -o seccomp_bpf_tests $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -pthread
+
+resumption: resumption.c test_harness.h
+	$(CC) $^ -o $@ $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -ggdb3
+
+sigsegv: sigsegv.c test_harness.h
+	$(CC) $^ -o $@ $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -ggdb3
+
+run_tests: $(EXEC)
+	./seccomp_bpf_tests
+	./resumption
+	./sigsegv
+
+.PHONY: clean run_tests
diff --git a/tests/tests/os/jni/seccomp-tests/tests/resumption.c b/tests/tests/os/jni/seccomp-tests/tests/resumption.c
new file mode 100644
index 0000000..41795c0
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/tests/resumption.c
@@ -0,0 +1,217 @@
+/* seccomp_bpf_tests.c
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Test code for seccomp bpf.
+ */
+
+#include <asm/siginfo.h>
+#define __have_siginfo_t 1
+#define __have_sigval_t 1
+#define __have_sigevent_t 1
+
+#include <linux/filter.h>
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+#include <linux/seccomp.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <syscall.h>
+#define __USE_GNU 1
+#include <sys/ucontext.h>
+#include <sys/mman.h>
+
+#include "test_harness.h"
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 38
+#define PR_GET_NO_NEW_PRIVS 39
+#endif
+
+#if defined(__i386__)
+#define REG_IP	REG_EIP
+#define REG_SP	REG_ESP
+#define REG_RESULT	REG_EAX
+#define REG_SYSCALL	REG_EAX
+#define REG_ARG0	REG_EBX
+#define REG_ARG1	REG_ECX
+#define REG_ARG2	REG_EDX
+#define REG_ARG3	REG_ESI
+#define REG_ARG4	REG_EDI
+#define REG_ARG5	REG_EBP
+#elif defined(__x86_64__)
+#define REG_IP	REG_RIP
+#define REG_SP	REG_RSP
+#define REG_RESULT	REG_RAX
+#define REG_SYSCALL	REG_RAX
+#define REG_ARG0	REG_RDI
+#define REG_ARG1	REG_RSI
+#define REG_ARG2	REG_RDX
+#define REG_ARG3	REG_R10
+#define REG_ARG4	REG_R8
+#define REG_ARG5	REG_R9
+#endif
+
+FIXTURE_DATA(TRAP) {
+	struct sock_fprog prog;
+};
+
+/* XXX: will need one per arch, etc.
+ *      thankfully _arch can tell us the calling convention!
+ */
+extern void *thunk_ip;	/* label for the instruction _after_ syscall */
+static void syscall_thunk(void)
+{
+	asm("syscall; thunk_ip:");
+}
+
+static time_t vsyscall_time(time_t *p)
+{
+	register time_t t asm ("rax");
+	__attribute__((unused)) register time_t *p1 asm ("rdi") = p;
+	__asm__("call 0xffffffffff600400 \n");
+	return t;
+}
+
+
+#if 0
+/* For instance, we could jump here instead. */
+static void compat_thunk(void)
+{
+	asm("int 0x80");
+}
+#endif
+
+FIXTURE_SETUP(TRAP) {
+	/* instruction after the syscall. Will be arch specific, of course. */
+	unsigned long thunk_addr = (unsigned long)&thunk_ip;
+	TH_LOG("Thunk: 0x%lX\n", thunk_addr);
+	{
+		struct sock_filter filter[] = {
+			BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+				offsetof(struct seccomp_data, nr)),
+			/* Whitelist anything you might need in the sigaction */
+#ifdef __NR_sigreturn
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_sigreturn, 3, 0),
+#endif
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit, 2, 0),
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_rt_sigreturn, 1, 0),
+			/* Allow __NR_write so easy logging. */
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_write, 0, 1),
+			BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+			/* Check if we're within the thunk. */
+			BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+				offsetof(struct seccomp_data, instruction_pointer)),
+			/* XXX: make this 32-bit friendly. */
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ((__u32*)&thunk_addr)[0], 0, 3),
+			BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+				offsetof(struct seccomp_data, instruction_pointer)+sizeof(int)),
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, ((__u32*)&thunk_addr)[1], 0, 1),
+			BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW),
+			BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP),
+		};
+		memset(&self->prog, 0, sizeof(self->prog));
+		self->prog.filter = malloc(sizeof(filter));
+		ASSERT_NE(NULL, self->prog.filter);
+		memcpy(self->prog.filter, filter, sizeof(filter));
+		self->prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0]));
+	}
+}
+
+FIXTURE_TEARDOWN(TRAP) {
+	if (self->prog.filter)
+		free(self->prog.filter);
+};
+
+struct arch_sigsys {
+		void *_call_addr; /* calling user insn */
+		int _syscall;	/* triggering system call number */
+		unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
+};
+
+static void TRAP_action(int nr, siginfo_t *info, void *void_context)
+{
+	ucontext_t *ctx = (ucontext_t *)void_context;
+	char buf[256];
+	int len;
+	int do_ret = 1;
+	struct arch_sigsys *sys = (struct arch_sigsys *)
+#ifdef si_syscall
+		&(info->si_call_addr);
+#else
+		&(info->si_pid);
+#endif
+
+	if (info->si_code != SYS_SECCOMP)
+		return;
+	if (!ctx)
+		return;
+	len = snprintf(buf, sizeof(buf),
+			"@0x%lX:%X:%d:0x%lX:0x%lX:0x%lX:0x%lX:0x%lX:0x%lX\n",
+			(unsigned long)sys->_call_addr,
+			sys->_arch,
+			sys->_syscall,
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG0],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG1],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG2],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG3],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG4],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG5]);
+	/* Send the soft-fail to our "listener" */
+	syscall(__NR_write, STDOUT_FILENO, buf, len);
+	if (ctx->uc_mcontext.gregs[REG_IP] >= 0xffffffffff600000ULL &&
+	    ctx->uc_mcontext.gregs[REG_IP] < 0xffffffffff601000ULL)
+		do_ret = 0;
+	if (do_ret) {
+		/* push [REG_IP] */
+		ctx->uc_mcontext.gregs[REG_SP] -= sizeof(unsigned long);
+		*((unsigned long *)ctx->uc_mcontext.gregs[REG_SP]) =
+		    ctx->uc_mcontext.gregs[REG_IP];
+	}
+	/* jmp syscall_thunk */
+	ctx->uc_mcontext.gregs[REG_IP] = (unsigned long)syscall_thunk;
+	return;
+}
+
+TEST_F(TRAP, handler) {
+	int ret;
+	struct sigaction act;
+	pid_t pid;
+	sigset_t mask;
+	memset(&act, 0, sizeof(act));
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGSYS);
+
+	act.sa_sigaction = &TRAP_action;
+	act.sa_flags = SA_SIGINFO;
+	ret = sigaction(SIGSYS, &act, NULL);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("sigaction failed");
+	}
+	ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("sigprocmask failed");
+	}
+
+	/* Get the pid to compare against. */
+	pid = getpid();
+
+	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
+	ASSERT_EQ(0, ret);
+
+	/* Call anything! */
+	ret = syscall(__NR_getpid);
+	ASSERT_EQ(pid, ret);
+	ret = syscall(__NR_close, 0);
+	ASSERT_EQ(0, ret);
+	ret = syscall(__NR_close, 0);
+	ASSERT_EQ(-1, ret);
+	printf("The time is %ld\n", vsyscall_time(NULL));
+	ASSERT_LT(0, vsyscall_time(NULL));
+}
+
+TEST_HARNESS_MAIN
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
new file mode 100644
index 0000000..3c238e6
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/tests/seccomp_bpf_tests.c
@@ -0,0 +1,1973 @@
+/* seccomp_bpf_tests.c
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Test code for seccomp bpf.
+ */
+
+#include <asm/siginfo.h>
+#define __have_siginfo_t 1
+#define __have_sigval_t 1
+#define __have_sigevent_t 1
+
+#include <errno.h>
+#include <linux/filter.h>
+#include <sys/prctl.h>
+#include <sys/ptrace.h>
+#include <sys/user.h>
+#include <linux/prctl.h>
+#include <linux/ptrace.h>
+#include <linux/seccomp.h>
+#include <poll.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <linux/elf.h>
+#include <sys/uio.h>
+#include <fcntl.h>  // ANDROID
+#include <sys/mman.h>
+#include <sys/times.h>
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+
+#include "test_harness.h"
+
+#ifndef PR_SET_PTRACER
+# define PR_SET_PTRACER 0x59616d61
+#endif
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 38
+#define PR_GET_NO_NEW_PRIVS 39
+#endif
+
+#ifndef PR_SECCOMP_EXT
+#define PR_SECCOMP_EXT 43
+#endif
+
+#ifndef SECCOMP_EXT_ACT
+#define SECCOMP_EXT_ACT 1
+#endif
+
+#ifndef SECCOMP_EXT_ACT_TSYNC
+#define SECCOMP_EXT_ACT_TSYNC 1
+#endif
+
+#ifndef SECCOMP_MODE_STRICT
+#define SECCOMP_MODE_STRICT 1
+#endif
+
+#ifndef SECCOMP_MODE_FILTER
+#define SECCOMP_MODE_FILTER 2
+#endif
+
+#ifndef SECCOMP_RET_KILL
+#define SECCOMP_RET_KILL        0x00000000U // kill the task immediately
+#define SECCOMP_RET_TRAP        0x00030000U // disallow and force a SIGSYS
+#define SECCOMP_RET_ERRNO       0x00050000U // returns an errno
+#define SECCOMP_RET_TRACE       0x7ff00000U // pass to a tracer or disallow
+#define SECCOMP_RET_ALLOW       0x7fff0000U // allow
+
+/* Masks for the return value sections. */
+#define SECCOMP_RET_ACTION      0x7fff0000U
+#define SECCOMP_RET_DATA        0x0000ffffU
+
+struct seccomp_data {
+	int nr;
+	__u32 arch;
+	__u64 instruction_pointer;
+	__u64 args[6];
+};
+#endif
+
+#define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n]))
+
+#define SIBLING_EXIT_UNKILLED	0xbadbeef
+#define SIBLING_EXIT_FAILURE	0xbadface
+#define SIBLING_EXIT_NEWPRIVS	0xbadfeed
+
+TEST(mode_strict_support) {
+	long ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, NULL, NULL);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Kernel does not support CONFIG_SECCOMP");
+	}
+	syscall(__NR_exit, 1);
+}
+
+TEST_SIGNAL(mode_strict_cannot_call_prctl, SIGKILL) {
+	long ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, NULL, NULL);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Kernel does not support CONFIG_SECCOMP");
+	}
+	syscall(__NR_prctl, PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, NULL, NULL);
+	EXPECT_FALSE(true) {
+		TH_LOG("Unreachable!");
+	}
+}
+
+/* Note! This doesn't test no new privs behavior */
+TEST(no_new_privs_support) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	EXPECT_EQ(0, ret) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+}
+
+/* Tests kernel support by checking for a copy_from_user() fault on * NULL. */
+TEST(mode_filter_support) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, NULL, NULL);
+	EXPECT_EQ(-1, ret);
+	EXPECT_EQ(EFAULT, errno) {
+		TH_LOG("Kernel does not support CONFIG_SECCOMP_FILTER!");
+	}
+}
+
+TEST(mode_filter_without_nnp) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_GET_NO_NEW_PRIVS, 0, NULL, 0, 0);
+	ASSERT_LE(0, ret) {
+		TH_LOG("Expected 0 or unsupported for NO_NEW_PRIVS");
+	}
+	errno = 0;
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
+	/* Succeeds with CAP_SYS_ADMIN, fails without */
+	/* TODO(wad) check caps not euid */
+	if (geteuid()) {
+		EXPECT_EQ(-1, ret);
+		EXPECT_EQ(EACCES, errno);
+	} else {
+		EXPECT_EQ(0, ret);
+	}
+}
+
+#define MAX_INSNS_PER_PATH 32768
+
+TEST(filter_size_limits) {
+	int i;
+	int count = BPF_MAXINSNS + 1;
+	struct sock_filter allow[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_filter *filter;
+	struct sock_fprog prog = { };
+
+	filter = calloc(count, sizeof(*filter));
+	ASSERT_NE(NULL, filter);
+
+	for (i = 0; i < count; i++) {
+		filter[i] = allow[0];
+	}
+
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	prog.filter = filter;
+	prog.len = count;
+
+	/* Too many filter instructions in a single filter. */
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
+	ASSERT_NE(0, ret) {
+		TH_LOG("Installing %d insn filter was allowed", prog.len);
+	}
+
+	/* One less is okay, though. */
+	prog.len -= 1;
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Installing %d insn filter wasn't allowed", prog.len);
+	}
+}
+
+TEST(filter_chain_limits) {
+	int i;
+	int count = BPF_MAXINSNS;
+	struct sock_filter allow[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_filter *filter;
+	struct sock_fprog prog = { };
+
+	filter = calloc(count, sizeof(*filter));
+	ASSERT_NE(NULL, filter);
+
+	for (i = 0; i < count; i++) {
+		filter[i] = allow[0];
+	}
+
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	prog.filter = filter;
+	prog.len = 1;
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	prog.len = count;
+
+	/* Too many total filter instructions. */
+	for (i = 0; i < MAX_INSNS_PER_PATH; i++) {
+		ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
+		if (ret != 0)
+			break;
+	}
+	ASSERT_NE(0, ret) {
+		TH_LOG("Allowed %d %d-insn filters (total with penalties:%d)",
+		       i, count, i * (count + 4));
+	}
+}
+
+TEST(mode_filter_cannot_move_to_strict) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, NULL, 0, 0);
+	EXPECT_EQ(-1, ret);
+	EXPECT_EQ(EINVAL, errno);
+}
+
+
+TEST(mode_filter_get_seccomp) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);
+	EXPECT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_GET_SECCOMP, 0, 0, 0, 0);
+	EXPECT_EQ(2, ret);
+}
+
+
+TEST(ALLOW_all) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	ASSERT_EQ(0, ret);
+}
+
+TEST(empty_prog) {
+	struct sock_filter filter[] = {
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	EXPECT_EQ(-1, ret);
+	EXPECT_EQ(EINVAL, errno);
+}
+
+TEST_SIGNAL(unknown_ret_is_kill_inside, SIGSYS) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, 0x10000000U),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	ASSERT_EQ(0, ret);
+	EXPECT_EQ(0, syscall(__NR_getpid)) {
+		TH_LOG("getpid() shouldn't ever return");
+	}
+}
+
+/* return code >= 0x80000000 is unused. */
+TEST_SIGNAL(unknown_ret_is_kill_above_allow, SIGSYS) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, 0x90000000U),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	ASSERT_EQ(0, ret);
+	EXPECT_EQ(0, syscall(__NR_getpid)) {
+		TH_LOG("getpid() shouldn't ever return");
+	}
+}
+
+TEST_SIGNAL(KILL_all, SIGSYS) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	ASSERT_EQ(0, ret);
+}
+
+TEST_SIGNAL(KILL_one, SIGSYS) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	ASSERT_EQ(0, ret);
+
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	/* getpid() should never return. */
+	EXPECT_EQ(0, syscall(__NR_getpid));
+}
+
+TEST_SIGNAL(KILL_one_arg_one, SIGSYS) {
+	void *fatal_address;
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_times, 1, 0),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+		/* Only both with lower 32-bit for now. */
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(0)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K,
+			(unsigned long)&fatal_address, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	struct tms timebuf;
+	clock_t clock = times(&timebuf);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	ASSERT_EQ(0, ret);
+
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	EXPECT_LE(clock, syscall(__NR_times, &timebuf));
+	/* times() should never return. */
+	EXPECT_EQ(0, syscall(__NR_times, &fatal_address));
+}
+
+TEST_SIGNAL(KILL_one_arg_six, SIGSYS) {
+#ifndef __NR_mmap2
+	int sysno = __NR_mmap;
+#else
+	int sysno = __NR_mmap2;
+#endif
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, sysno, 1, 0),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+		/* Only both with lower 32-bit for now. */
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(5)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, 0x0C0FFEE, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	int fd;
+	void *map1, *map2;
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	ASSERT_EQ(0, ret);
+
+	fd = open("/dev/zero", O_RDONLY);
+	ASSERT_NE(-1, fd);
+
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	map1 = (void *)syscall(sysno,
+		NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, PAGE_SIZE);
+	EXPECT_NE(MAP_FAILED, map1);
+	/* mmap2() should never return. */
+	map2 = (void *)syscall(sysno,
+		 NULL, PAGE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0x0C0FFEE);
+	EXPECT_EQ(MAP_FAILED, map2);
+
+	/* The test failed, so clean up the resources. */
+	munmap(map1, PAGE_SIZE);
+	munmap(map2, PAGE_SIZE);
+	close(fd);
+}
+
+/* TODO(wad) add 64-bit versus 32-bit arg tests. */
+
+TEST(arg_out_of_range) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_arg(6)),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	EXPECT_EQ(-1, ret);
+	EXPECT_EQ(EINVAL, errno);
+}
+
+TEST(ERRNO_one) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | E2BIG),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	ASSERT_EQ(0, ret);
+
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	EXPECT_EQ(-1, read(0, NULL, 0));
+	EXPECT_EQ(E2BIG, errno);
+}
+
+TEST(ERRNO_one_ok) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | 0),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog);
+	ASSERT_EQ(0, ret);
+
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	/* "errno" of 0 is ok. */
+	EXPECT_EQ(0, read(0, NULL, 0));
+}
+
+FIXTURE_DATA(TRAP) {
+	struct sock_fprog prog;
+};
+
+FIXTURE_SETUP(TRAP) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	memset(&self->prog, 0, sizeof(self->prog));
+	self->prog.filter = malloc(sizeof(filter));
+	ASSERT_NE(NULL, self->prog.filter);
+	memcpy(self->prog.filter, filter, sizeof(filter));
+	self->prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0]));
+}
+
+FIXTURE_TEARDOWN(TRAP) {
+	if (self->prog.filter)
+		free(self->prog.filter);
+};
+
+TEST_F_SIGNAL(TRAP, dfl, SIGSYS) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
+	ASSERT_EQ(0, ret);
+	syscall(__NR_getpid);
+}
+
+/* Ensure that SIGSYS overrides SIG_IGN */
+TEST_F_SIGNAL(TRAP, ign, SIGSYS) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	signal(SIGSYS, SIG_IGN);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
+	ASSERT_EQ(0, ret);
+	syscall(__NR_getpid);
+}
+
+static struct siginfo TRAP_info;
+static volatile int TRAP_nr;
+static void TRAP_action(int nr, siginfo_t *info, void *void_context)
+{
+	memcpy(&TRAP_info, info, sizeof(TRAP_info));
+	TRAP_nr = nr;
+	return;
+}
+
+TEST_F(TRAP, handler) {
+	int ret, test;
+	struct sigaction act;
+	sigset_t mask;
+	memset(&act, 0, sizeof(act));
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGSYS);
+
+	act.sa_sigaction = &TRAP_action;
+	act.sa_flags = SA_SIGINFO;
+	ret = sigaction(SIGSYS, &act, NULL);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("sigaction failed");
+	}
+	ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("sigprocmask failed");
+	}
+
+	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
+	ASSERT_EQ(0, ret);
+	TRAP_nr = 0;
+	memset(&TRAP_info, 0, sizeof(TRAP_info));
+	/* Expect the registers to be rolled back. (nr = error) may vary
+	 * based on arch. */
+	ret = syscall(__NR_getpid);
+	/* Silence gcc warning about volatile. */
+	test = TRAP_nr;
+	EXPECT_EQ(SIGSYS, test);
+	struct local_sigsys {
+			void *_call_addr; /* calling user insn */
+			int _syscall;	/* triggering system call number */
+			unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
+	} *sigsys = (struct local_sigsys *)
+#ifdef si_syscall
+		&(TRAP_info.si_call_addr);
+#else
+		&TRAP_info.si_pid;
+#endif
+	EXPECT_EQ(__NR_getpid, sigsys->_syscall);
+	/* Make sure arch is non-zero. */
+	EXPECT_NE(0, sigsys->_arch);
+	EXPECT_NE(0, (unsigned long)sigsys->_call_addr);
+}
+
+FIXTURE_DATA(precedence) {
+	struct sock_fprog allow;
+	struct sock_fprog trace;
+	struct sock_fprog error;
+	struct sock_fprog trap;
+	struct sock_fprog kill;
+};
+
+FIXTURE_SETUP(precedence) {
+	struct sock_filter allow_insns[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_filter trace_insns[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE),
+	};
+	struct sock_filter error_insns[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO),
+	};
+	struct sock_filter trap_insns[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRAP),
+	};
+	struct sock_filter kill_insns[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 1, 0),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+	};
+	memset(self, 0, sizeof(*self));
+#define FILTER_ALLOC(_x) \
+	self->_x.filter = malloc(sizeof(_x##_insns)); \
+	ASSERT_NE(NULL, self->_x.filter); \
+	memcpy(self->_x.filter, &_x##_insns, sizeof(_x##_insns)); \
+	self->_x.len = (unsigned short)(sizeof(_x##_insns)/sizeof(_x##_insns[0]))
+	FILTER_ALLOC(allow);
+	FILTER_ALLOC(trace);
+	FILTER_ALLOC(error);
+	FILTER_ALLOC(trap);
+	FILTER_ALLOC(kill);
+}
+
+FIXTURE_TEARDOWN(precedence) {
+#define FILTER_FREE(_x) if (self->_x.filter) free(self->_x.filter)
+	FILTER_FREE(allow);
+	FILTER_FREE(trace);
+	FILTER_FREE(error);
+	FILTER_FREE(trap);
+	FILTER_FREE(kill);
+}
+
+TEST_F(precedence, allow_ok) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	pid_t res = 0;
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);
+	ASSERT_EQ(0, ret);
+	/* Should work just fine. */
+	res = syscall(__NR_getppid);
+	EXPECT_EQ(parent, res);
+}
+
+TEST_F_SIGNAL(precedence, kill_is_highest, SIGSYS) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	pid_t res = 0;
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);
+	ASSERT_EQ(0, ret);
+	/* Should work just fine. */
+	res = syscall(__NR_getppid);
+	EXPECT_EQ(parent, res);
+	/* getpid() should never return. */
+	res = syscall(__NR_getpid);
+	EXPECT_EQ(0, res);
+}
+
+TEST_F_SIGNAL(precedence, kill_is_highest_in_any_order, SIGSYS) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->kill);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
+	ASSERT_EQ(0, ret);
+	/* Should work just fine. */
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	/* getpid() should never return. */
+	EXPECT_EQ(0, syscall(__NR_getpid));
+}
+
+TEST_F_SIGNAL(precedence, trap_is_second, SIGSYS) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
+	ASSERT_EQ(0, ret);
+	/* Should work just fine. */
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	/* getpid() should never return. */
+	EXPECT_EQ(0, syscall(__NR_getpid));
+}
+
+TEST_F_SIGNAL(precedence, trap_is_second_in_any_order, SIGSYS) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trap);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
+	ASSERT_EQ(0, ret);
+	/* Should work just fine. */
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	/* getpid() should never return. */
+	EXPECT_EQ(0, syscall(__NR_getpid));
+}
+
+TEST_F(precedence, errno_is_third) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
+	ASSERT_EQ(0, ret);
+	/* Should work just fine. */
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	EXPECT_EQ(0, syscall(__NR_getpid));
+}
+
+TEST_F(precedence, errno_is_third_in_any_order) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->error);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
+	ASSERT_EQ(0, ret);
+	/* Should work just fine. */
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	EXPECT_EQ(0, syscall(__NR_getpid));
+}
+
+TEST_F(precedence, trace_is_fourth) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
+	ASSERT_EQ(0, ret);
+	/* Should work just fine. */
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	/* No ptracer */
+	EXPECT_EQ(-1, syscall(__NR_getpid));
+}
+
+TEST_F(precedence, trace_is_fourth_in_any_order) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	pid_t parent = getppid();
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->trace);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->allow);
+	ASSERT_EQ(0, ret);
+	/* Should work just fine. */
+	EXPECT_EQ(parent, syscall(__NR_getppid));
+	/* No ptracer */
+	EXPECT_EQ(-1, syscall(__NR_getpid));
+}
+
+#ifndef PTRACE_O_TRACESECCOMP
+#define PTRACE_O_TRACESECCOMP	0x00000080
+#endif
+
+/* Catch the Ubuntu 12.04 value error. */
+#if PTRACE_EVENT_SECCOMP != 7
+#undef PTRACE_EVENT_SECCOMP
+#endif
+
+#ifndef PTRACE_EVENT_SECCOMP
+#define PTRACE_EVENT_SECCOMP 7
+#endif
+
+#define IS_SECCOMP_EVENT(status) ((status >> 16) == PTRACE_EVENT_SECCOMP)
+bool tracer_running;
+void tracer_stop(int sig)
+{
+	tracer_running = false;
+}
+
+typedef void tracer_func_t(struct __test_metadata *_metadata,
+			   pid_t tracee, int status, void *args);
+
+void tracer(struct __test_metadata *_metadata, int fd, pid_t tracee,
+	    tracer_func_t tracer_func, void *args) {
+	int ret = -1;
+	struct sigaction action = {
+		.sa_handler = tracer_stop,
+	};
+
+	/* Allow external shutdown. */
+	tracer_running = true;
+	ASSERT_EQ(0, sigaction(SIGUSR1, &action, NULL));
+
+	errno = 0;
+	while (ret == -1 && errno != EINVAL) {
+		ret = ptrace(PTRACE_ATTACH, tracee, NULL, 0);
+	}
+	ASSERT_EQ(0, ret) {
+		kill(tracee, SIGKILL);
+	}
+	/* Wait for attach stop */
+	wait(NULL);
+
+	ret = ptrace(PTRACE_SETOPTIONS, tracee, NULL, PTRACE_O_TRACESECCOMP);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Failed to set PTRACE_O_TRACESECCOMP");
+		kill(tracee, SIGKILL);
+	}
+	ptrace(PTRACE_CONT, tracee, NULL, 0);
+
+	/* Unblock the tracee */
+	ASSERT_EQ(1, write(fd, "A", 1));
+	ASSERT_EQ(0, close(fd));
+
+	/* Run until we're shut down. Must assert to stop execution. */
+	while (tracer_running) {
+		int status;
+		if (wait(&status) != tracee)
+			continue;
+		if (WIFSIGNALED(status) || WIFEXITED(status))
+			/* Child is dead. Time to go. */
+			return;
+
+		/* Make sure this is a seccomp event. */
+		ASSERT_EQ(true, IS_SECCOMP_EVENT(status));
+
+		tracer_func(_metadata, tracee, status, args);
+
+		ret = ptrace(PTRACE_CONT, tracee, NULL, NULL);
+		ASSERT_EQ(0, ret);
+	}
+	/* Directly report the status of our test harness results. */
+	syscall(__NR_exit, _metadata->passed ? EXIT_SUCCESS : EXIT_FAILURE);
+}
+
+/* Common tracer setup/teardown functions. */
+void cont_handler(int num) {
+}
+pid_t setup_trace_fixture(struct __test_metadata *_metadata,
+			  tracer_func_t func, void *args) {
+	char sync;
+	int pipefd[2];
+	pid_t tracer_pid;
+	pid_t tracee = getpid();
+
+	/* Setup a pipe for clean synchronization. */
+	ASSERT_EQ(0, pipe(pipefd));
+
+	/* Fork a child which we'll promote to tracer */
+	tracer_pid = fork();
+	ASSERT_LE(0, tracer_pid);
+	signal(SIGALRM, cont_handler);
+	if (tracer_pid == 0) {
+		close(pipefd[0]);
+		tracer(_metadata, pipefd[1], tracee, func, args);
+		syscall(__NR_exit, 0);
+	}
+	close(pipefd[1]);
+	prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0);
+	read(pipefd[0], &sync, 1);
+	close(pipefd[0]);
+
+	return tracer_pid;
+}
+void teardown_trace_fixture(struct __test_metadata *_metadata,
+			    pid_t tracer) {
+	if (tracer) {
+		int status;
+		/*
+		 * Extract the exit code from the other process and
+		 * adopt it for ourselves in case its asserts failed.
+		 */
+		ASSERT_EQ(0, kill(tracer, SIGUSR1));
+		ASSERT_EQ(tracer, waitpid(tracer, &status, 0));
+		if (WEXITSTATUS(status))
+			_metadata->passed = 0;
+	}
+}
+
+/* "poke" tracer arguments and function. */
+struct tracer_args_poke_t {
+	unsigned long poke_addr;
+};
+
+void tracer_poke(struct __test_metadata *_metadata, pid_t tracee, int status,
+		 void *args) {
+	int ret;
+	unsigned long msg;
+	struct tracer_args_poke_t *info = (struct tracer_args_poke_t *)args;
+
+	ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);
+	EXPECT_EQ(0, ret);
+	/* If this fails, don't try to recover. */
+	ASSERT_EQ(0x1001, msg) {
+		kill(tracee, SIGKILL);
+	}
+	/*
+	 * Poke in the message.
+	 * Registers are not touched to try to keep this relatively arch
+	 * agnostic.
+	 */
+	ret = ptrace(PTRACE_POKEDATA, tracee, info->poke_addr, 0x1001);
+	EXPECT_EQ(0, ret);
+}
+
+FIXTURE_DATA(TRACE_poke) {
+	struct sock_fprog prog;
+	pid_t tracer;
+	long poked;
+	struct tracer_args_poke_t tracer_args;
+};
+
+FIXTURE_SETUP(TRACE_poke) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1001),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+
+	self->poked = 0;
+	memset(&self->prog, 0, sizeof(self->prog));
+	self->prog.filter = malloc(sizeof(filter));
+	ASSERT_NE(NULL, self->prog.filter);
+	memcpy(self->prog.filter, filter, sizeof(filter));
+	self->prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0]));
+
+	/* Set up tracer args. */
+	self->tracer_args.poke_addr = (unsigned long)&self->poked;
+
+	/* Launch tracer. */
+	self->tracer = setup_trace_fixture(_metadata, tracer_poke,
+					   &self->tracer_args);
+}
+
+FIXTURE_TEARDOWN(TRACE_poke) {
+	teardown_trace_fixture(_metadata, self->tracer);
+	if (self->prog.filter)
+		free(self->prog.filter);
+};
+
+TEST_F(TRACE_poke, read_has_side_effects) {
+	ssize_t ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	EXPECT_EQ(0, self->poked);
+	ret = read(-1, NULL, 0);
+	EXPECT_EQ(-1, ret);
+	EXPECT_EQ(0x1001, self->poked);
+}
+
+TEST_F(TRACE_poke, getpid_runs_normally) {
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	EXPECT_EQ(0, self->poked);
+	EXPECT_NE(0, syscall(__NR_getpid));
+	EXPECT_EQ(0, self->poked);
+}
+
+#if defined(__x86_64__)
+# define ARCH_REGS	struct user_regs_struct
+# define SYSCALL_NUM	orig_rax
+# define SYSCALL_RET	rax
+#elif defined(__i386__)
+# define ARCH_REGS	struct user_regs_struct
+# define SYSCALL_NUM	orig_eax
+# define SYSCALL_RET	eax
+#elif defined(__arm__)
+# define ARCH_REGS	struct pt_regs
+# define SYSCALL_NUM	ARM_r7
+# define SYSCALL_RET	ARM_r0
+#elif defined(__aarch64__)
+# define ARCH_REGS	struct user_pt_regs
+# define SYSCALL_NUM	regs[8]
+# define SYSCALL_RET	regs[0]
+#else
+# error "Do not know how to find your architecture's registers and syscalls"
+#endif
+
+/* Architecture-specific syscall fetching routine. */
+int get_syscall(struct __test_metadata *_metadata, pid_t tracee) {
+	struct iovec iov;
+	ARCH_REGS regs;
+
+	iov.iov_base = &regs;
+	iov.iov_len = sizeof(regs);
+	EXPECT_EQ(0, ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov)) {
+		TH_LOG("PTRACE_GETREGSET failed");
+		return -1;
+	}
+
+	return regs.SYSCALL_NUM;
+}
+
+/* Architecture-specific syscall changing routine. */
+void change_syscall(struct __test_metadata *_metadata,
+		    pid_t tracee, int syscall) {
+	struct iovec iov;
+	int ret;
+	ARCH_REGS regs;
+
+	iov.iov_base = &regs;
+	iov.iov_len = sizeof(regs);
+	ret = ptrace(PTRACE_GETREGSET, tracee, NT_PRSTATUS, &iov);
+	EXPECT_EQ(0, ret);
+
+#if defined(__x86_64__) || defined(__i386__) || defined(__aarch64__)
+	{
+		regs.SYSCALL_NUM = syscall;
+	}
+
+#elif defined(__arm__)
+# ifndef PTRACE_SET_SYSCALL
+#  define PTRACE_SET_SYSCALL   23
+# endif
+	{
+		ret = ptrace(PTRACE_SET_SYSCALL, tracee, NULL, syscall);
+		EXPECT_EQ(0, ret);
+	}
+
+#else
+	ASSERT_EQ(1, 0) {
+		TH_LOG("How is the syscall changed on this architecture?");
+	}
+#endif
+
+	/* If syscall is skipped, change return value. */
+	if (syscall == -1)
+		regs.SYSCALL_RET = 1;
+
+	ret = ptrace(PTRACE_SETREGSET, tracee, NT_PRSTATUS, &iov);
+	EXPECT_EQ(0, ret);
+}
+
+void tracer_syscall(struct __test_metadata *_metadata, pid_t tracee,
+		    int status, void *args) {
+	int ret;
+	unsigned long msg;
+
+	/* Make sure we got the right message. */
+	ret = ptrace(PTRACE_GETEVENTMSG, tracee, NULL, &msg);
+	EXPECT_EQ(0, ret);
+
+	switch (msg) {
+	case 0x1002:
+		/* change getpid to getppid. */
+		change_syscall(_metadata, tracee, __NR_getppid);
+		break;
+	case 0x1003:
+		/* skip gettid. */
+		change_syscall(_metadata, tracee, -1);
+		break;
+	case 0x1004:
+		/* do nothing (allow getppid) */
+		break;
+	default:
+		EXPECT_EQ(0, msg) {
+			TH_LOG("Unknown PTRACE_GETEVENTMSG: 0x%lx", msg);
+			kill(tracee, SIGKILL);
+		}
+	}
+
+}
+
+FIXTURE_DATA(TRACE_syscall) {
+	struct sock_fprog prog;
+	pid_t tracer, mytid, mypid, parent;
+};
+
+FIXTURE_SETUP(TRACE_syscall) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getpid, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1002),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_gettid, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1003),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_getppid, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_TRACE | 0x1004),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+
+	memset(&self->prog, 0, sizeof(self->prog));
+	self->prog.filter = malloc(sizeof(filter));
+	ASSERT_NE(NULL, self->prog.filter);
+	memcpy(self->prog.filter, filter, sizeof(filter));
+	self->prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0]));
+
+	/* Prepare some testable syscall results. */
+	self->mytid = syscall(__NR_gettid);
+	ASSERT_GT(self->mytid, 0);
+	ASSERT_NE(self->mytid, 1) {
+		TH_LOG("Running this test as init is not supported. :)");
+	}
+
+	self->mypid = getpid();
+	ASSERT_GT(self->mypid, 0);
+	ASSERT_EQ(self->mytid, self->mypid);
+
+	self->parent = getppid();
+	ASSERT_GT(self->parent, 0);
+	ASSERT_NE(self->parent, self->mypid);
+
+	/* Launch tracer. */
+	self->tracer = setup_trace_fixture(_metadata, tracer_syscall, NULL);
+}
+
+FIXTURE_TEARDOWN(TRACE_syscall) {
+	teardown_trace_fixture(_metadata, self->tracer);
+	if (self->prog.filter)
+		free(self->prog.filter);
+};
+
+TEST_F(TRACE_syscall, syscall_allowed) {
+	long ret;
+
+	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	/* getppid works as expected (no changes). */
+	EXPECT_EQ(self->parent, syscall(__NR_getppid));
+	EXPECT_NE(self->mypid, syscall(__NR_getppid));
+}
+
+TEST_F(TRACE_syscall, syscall_redirected) {
+	long ret;
+
+	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	/* getpid has been redirected to getppid as expected. */
+	EXPECT_EQ(self->parent, syscall(__NR_getpid));
+	EXPECT_NE(self->mypid, syscall(__NR_getpid));
+}
+
+TEST_F(TRACE_syscall, syscall_dropped) {
+	long ret;
+
+	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog, 0, 0);
+	ASSERT_EQ(0, ret);
+
+	/* gettid has been skipped and an altered return value stored. */
+	EXPECT_EQ(1, syscall(__NR_gettid));
+	EXPECT_NE(self->mytid, syscall(__NR_gettid));
+}
+
+#ifndef __NR_seccomp
+# if defined(__i386__)
+#  define __NR_seccomp 354
+# elif defined(__x86_64__)
+#  define __NR_seccomp 317
+# elif defined(__arm__)
+#  define __NR_seccomp 383
+# elif defined(__aarch64__)
+#  define __NR_seccomp 277
+# else
+#  warning "seccomp syscall number unknown for this architecture"
+#  define __NR_seccomp 0xffff
+# endif
+#endif
+
+#ifndef SECCOMP_SET_MODE_STRICT
+#define SECCOMP_SET_MODE_STRICT 0
+#endif
+
+#ifndef SECCOMP_SET_MODE_FILTER
+#define SECCOMP_SET_MODE_FILTER 1
+#endif
+
+#ifndef SECCOMP_FLAG_FILTER_TSYNC
+#define SECCOMP_FLAG_FILTER_TSYNC 1
+#endif
+
+#ifndef seccomp
+int seccomp(unsigned int op, unsigned int flags, struct sock_fprog *filter)
+{
+	errno = 0;
+	return syscall(__NR_seccomp, op, flags, filter);
+}
+#endif
+
+TEST(seccomp_syscall) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+
+	/* Reject insane operation. */
+	ret = seccomp(-1, 0, &prog);
+	EXPECT_EQ(EINVAL, errno) {
+		TH_LOG("Did not reject crazy op value!");
+	}
+
+	/* Reject strict with flags or pointer. */
+	ret = seccomp(SECCOMP_SET_MODE_STRICT, -1, NULL);
+	EXPECT_EQ(EINVAL, errno) {
+		TH_LOG("Did not reject mode strict with flags!");
+	}
+	ret = seccomp(SECCOMP_SET_MODE_STRICT, 0, &prog);
+	EXPECT_EQ(EINVAL, errno) {
+		TH_LOG("Did not reject mode strict with uargs!");
+	}
+
+	/* Reject insane args for filter. */
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, -1, &prog);
+	EXPECT_EQ(EINVAL, errno) {
+		TH_LOG("Did not reject crazy filter flags!");
+	}
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, NULL);
+	EXPECT_EQ(EFAULT, errno) {
+		TH_LOG("Did not reject NULL filter!");
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
+	EXPECT_EQ(0, errno) {
+		TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER: %s",
+			strerror(errno));
+	}
+}
+
+TEST(seccomp_syscall_mode_lock) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
+	EXPECT_EQ(0, ret) {
+		TH_LOG("Could not install filter!");
+	}
+
+	/* Make sure neither entry point will switch to strict. */
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_STRICT, 0, 0, 0);
+	EXPECT_EQ(EINVAL, errno) {
+		TH_LOG("Switched to mode strict!");
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_STRICT, 0, NULL);
+	EXPECT_EQ(EINVAL, errno) {
+		TH_LOG("Switched to mode strict!");
+	}
+}
+
+TEST(TSYNC_first) {
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+	long ret = prctl(PR_SET_NO_NEW_PRIVS, 1, NULL, 0, 0);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
+		      &prog);
+	EXPECT_EQ(0, ret) {
+		TH_LOG("Could not install initial filter with TSYNC!");
+	}
+}
+
+#define TSYNC_SIBLINGS 2
+struct tsync_sibling {
+	pthread_t tid;
+	pid_t system_tid;
+	sem_t *started;
+	pthread_cond_t *cond;
+	pthread_mutex_t *mutex;
+	int diverge;
+	int num_waits;
+	struct sock_fprog *prog;
+	struct __test_metadata *metadata;
+};
+
+FIXTURE_DATA(TSYNC) {
+	struct sock_fprog root_prog, apply_prog;
+	struct tsync_sibling sibling[TSYNC_SIBLINGS];
+	sem_t started;
+	pthread_cond_t cond;
+	pthread_mutex_t mutex;
+	int sibling_count;
+};
+
+FIXTURE_SETUP(TSYNC) {
+	struct sock_filter root_filter[] = {
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_filter apply_filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_read, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_KILL),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	memset(&self->root_prog, 0, sizeof(self->root_prog));
+	memset(&self->apply_prog, 0, sizeof(self->apply_prog));
+	memset(&self->sibling, 0, sizeof(self->sibling));
+	self->root_prog.filter = malloc(sizeof(root_filter));
+	ASSERT_NE(NULL, self->root_prog.filter);
+	memcpy(self->root_prog.filter, &root_filter, sizeof(root_filter));
+	self->root_prog.len = (unsigned short)(sizeof(root_filter)/sizeof(root_filter[0]));
+
+	self->apply_prog.filter = malloc(sizeof(apply_filter));
+	ASSERT_NE(NULL, self->apply_prog.filter);
+	memcpy(self->apply_prog.filter, &apply_filter, sizeof(apply_filter));
+	self->apply_prog.len = (unsigned short)(sizeof(apply_filter)/sizeof(apply_filter[0]));
+
+	self->sibling_count = 0;
+	pthread_mutex_init(&self->mutex, NULL);
+	pthread_cond_init(&self->cond, NULL);
+	sem_init(&self->started, 0, 0);
+	self->sibling[0].tid = 0;
+	self->sibling[0].cond = &self->cond;
+	self->sibling[0].started = &self->started;
+	self->sibling[0].mutex = &self->mutex;
+	self->sibling[0].diverge = 0;
+	self->sibling[0].num_waits = 1;
+	self->sibling[0].prog = &self->root_prog;
+	self->sibling[0].metadata = _metadata;
+	self->sibling[1].tid = 0;
+	self->sibling[1].cond = &self->cond;
+	self->sibling[1].started = &self->started;
+	self->sibling[1].mutex = &self->mutex;
+	self->sibling[1].diverge = 0;
+	self->sibling[1].prog = &self->root_prog;
+	self->sibling[1].num_waits = 1;
+	self->sibling[1].metadata = _metadata;
+}
+
+FIXTURE_TEARDOWN(TSYNC) {
+	int sib = 0;
+	if (self->root_prog.filter)
+		free(self->root_prog.filter);
+	if (self->apply_prog.filter)
+		free(self->apply_prog.filter);
+
+	for ( ; sib < self->sibling_count; ++sib) {
+		struct tsync_sibling *s = &self->sibling[sib];
+		void *status;
+		if (!s->tid)
+			continue;
+		if (pthread_kill(s->tid, 0)) {
+			//pthread_cancel(s->tid);  // ANDROID
+			pthread_join(s->tid, &status);
+		}
+	}
+	pthread_mutex_destroy(&self->mutex);
+	pthread_cond_destroy(&self->cond);
+	sem_destroy(&self->started);
+};
+
+void *tsync_sibling(void *data)
+{
+	long ret = 0;
+	struct tsync_sibling *me = data;
+	me->system_tid = syscall(__NR_gettid);
+
+	pthread_mutex_lock(me->mutex);
+	if (me->diverge) {
+		/* Just re-apply the root prog to fork the tree */
+		ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER,
+				me->prog, 0, 0);
+	}
+	sem_post(me->started);
+	/* Return outside of started so parent notices failures. */
+	if (ret) {
+		pthread_mutex_unlock(me->mutex);
+		return (void *)SIBLING_EXIT_FAILURE;
+	}
+	do {
+		pthread_cond_wait(me->cond, me->mutex);
+		me->num_waits = me->num_waits - 1;
+	}
+	while (me->num_waits);
+	pthread_mutex_unlock(me->mutex);
+	long nnp = prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0);
+	if (!nnp)
+		return (void*)SIBLING_EXIT_NEWPRIVS;
+	read(0, NULL, 0);
+	return (void *)SIBLING_EXIT_UNKILLED;
+}
+
+void tsync_start_sibling(struct tsync_sibling *sibling)
+{
+	pthread_create(&sibling->tid, NULL, tsync_sibling, (void *)sibling);
+}
+
+TEST_F(TSYNC, siblings_fail_prctl) {
+	long ret;
+	void *status;
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			offsetof(struct seccomp_data, nr)),
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_prctl, 0, 1),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ERRNO | EINVAL),
+		BPF_STMT(BPF_RET|BPF_K, SECCOMP_RET_ALLOW),
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+
+	/* Check prctl failure detection by requesting sib 0 diverge. */
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("setting filter failed");
+	}
+
+	self->sibling[0].diverge = 1;
+	tsync_start_sibling(&self->sibling[0]);
+	tsync_start_sibling(&self->sibling[1]);
+
+	while (self->sibling_count < TSYNC_SIBLINGS) {
+		sem_wait(&self->started);
+		self->sibling_count++;
+	}
+
+	/* Signal the threads to clean up*/
+	pthread_mutex_lock(&self->mutex);
+	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
+		TH_LOG("cond broadcast non-zero");
+	}
+	pthread_mutex_unlock(&self->mutex);
+
+	/* Ensure diverging sibling failed to call prctl. */
+	pthread_join(self->sibling[0].tid, &status);
+	EXPECT_EQ(SIBLING_EXIT_FAILURE, (long)status);
+	pthread_join(self->sibling[1].tid, &status);
+	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
+}
+
+TEST_F(TSYNC, two_siblings_with_ancestor) {
+	long ret;
+	void *status;
+
+	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
+	}
+	tsync_start_sibling(&self->sibling[0]);
+	tsync_start_sibling(&self->sibling[1]);
+
+	while (self->sibling_count < TSYNC_SIBLINGS) {
+		sem_wait(&self->started);
+		self->sibling_count++;
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
+		      &self->apply_prog);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Could install filter on all threads!");
+	}
+	/* Tell the siblings to test the policy */
+	pthread_mutex_lock(&self->mutex);
+	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
+		TH_LOG("cond broadcast non-zero");
+	}
+	pthread_mutex_unlock(&self->mutex);
+	/* Ensure they are both killed and don't exit cleanly. */
+	pthread_join(self->sibling[0].tid, &status);
+	EXPECT_EQ(0x0, (long)status);
+	pthread_join(self->sibling[1].tid, &status);
+	EXPECT_EQ(0x0, (long)status);
+}
+
+TEST_F(TSYNC, two_sibling_want_nnp) {
+	void *status;
+
+	/* start siblings before any prctl() operations */
+	tsync_start_sibling(&self->sibling[0]);
+	tsync_start_sibling(&self->sibling[1]);
+	while (self->sibling_count < TSYNC_SIBLINGS) {
+		sem_wait(&self->started);
+		self->sibling_count++;
+	}
+
+	/* Tell the siblings to test no policy */
+	pthread_mutex_lock(&self->mutex);
+	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
+		TH_LOG("cond broadcast non-zero");
+	}
+	pthread_mutex_unlock(&self->mutex);
+
+	/* Ensure they are both upset about lacking nnp. */
+	pthread_join(self->sibling[0].tid, &status);
+	EXPECT_EQ(SIBLING_EXIT_NEWPRIVS, (long)status);
+	pthread_join(self->sibling[1].tid, &status);
+	EXPECT_EQ(SIBLING_EXIT_NEWPRIVS, (long)status);
+}
+
+TEST_F(TSYNC, two_siblings_with_no_filter) {
+	long ret;
+	void *status;
+
+	/* start siblings before any prctl() operations */
+	tsync_start_sibling(&self->sibling[0]);
+	tsync_start_sibling(&self->sibling[1]);
+	while (self->sibling_count < TSYNC_SIBLINGS) {
+		sem_wait(&self->started);
+		self->sibling_count++;
+	}
+
+	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
+		      &self->apply_prog);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Could install filter on all threads!");
+	}
+
+	/* Tell the siblings to test the policy */
+	pthread_mutex_lock(&self->mutex);
+	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
+		TH_LOG("cond broadcast non-zero");
+	}
+	pthread_mutex_unlock(&self->mutex);
+
+	/* Ensure they are both killed and don't exit cleanly. */
+	pthread_join(self->sibling[0].tid, &status);
+	EXPECT_EQ(0x0, (long)status);
+	pthread_join(self->sibling[1].tid, &status);
+	EXPECT_EQ(0x0, (long)status);
+}
+
+TEST_F(TSYNC, two_siblings_with_one_divergence) {
+	long ret;
+	void *status;
+
+	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
+	}
+	self->sibling[0].diverge = 1;
+	tsync_start_sibling(&self->sibling[0]);
+	tsync_start_sibling(&self->sibling[1]);
+
+	while (self->sibling_count < TSYNC_SIBLINGS) {
+		sem_wait(&self->started);
+		self->sibling_count++;
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
+		      &self->apply_prog);
+	ASSERT_EQ(self->sibling[0].system_tid, ret) {
+		TH_LOG("Did not fail on diverged sibling.");
+	}
+
+	/* Wake the threads */
+	pthread_mutex_lock(&self->mutex);
+	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
+		TH_LOG("cond broadcast non-zero");
+	}
+	pthread_mutex_unlock(&self->mutex);
+
+	/* Ensure they are both unkilled. */
+	pthread_join(self->sibling[0].tid, &status);
+	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
+	pthread_join(self->sibling[1].tid, &status);
+	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
+}
+
+TEST_F(TSYNC, two_siblings_not_under_filter) {
+	long ret, sib;
+	void *status;
+
+	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+		TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+	}
+
+	/*
+	 * Sibling 0 will have its own seccomp policy
+	 * and Sibling 1 will not be under seccomp at
+	 * all. Sibling 1 will enter seccomp and 0
+	 * will cause failure.
+	 */
+	self->sibling[0].diverge = 1;
+	tsync_start_sibling(&self->sibling[0]);
+	tsync_start_sibling(&self->sibling[1]);
+
+	while (self->sibling_count < TSYNC_SIBLINGS) {
+		sem_wait(&self->started);
+		self->sibling_count++;
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, 0, &self->root_prog);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Kernel does not support SECCOMP_SET_MODE_FILTER!");
+	}
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
+		      &self->apply_prog);
+	ASSERT_EQ(ret, self->sibling[0].system_tid) {
+		TH_LOG("Did not fail on diverged sibling.");
+	}
+	sib = 1;
+	if (ret == self->sibling[0].system_tid)
+		sib = 0;
+
+	pthread_mutex_lock(&self->mutex);
+
+	/* Increment the other siblings num_waits so we can clean up
+	 * the one we just saw.
+	 */
+	self->sibling[!sib].num_waits += 1;
+
+	/* Signal the thread to clean up*/
+	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
+		TH_LOG("cond broadcast non-zero");
+	}
+	pthread_mutex_unlock(&self->mutex);
+	pthread_join(self->sibling[sib].tid, &status);
+	EXPECT_EQ(SIBLING_EXIT_UNKILLED, (long)status);
+	/* Poll for actual task death. pthread_join doesn't guarantee it. */
+	while (!kill(self->sibling[sib].system_tid, 0)) sleep(0.1);
+	/* Switch to the remaining sibling */
+	sib = !sib;
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
+		      &self->apply_prog);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("Expected the remaining sibling to sync");
+	};
+
+	pthread_mutex_lock(&self->mutex);
+
+	/* If remaining sibling didn't have a chance to wake up during
+	 * the first broadcast, manually reduce the num_waits now.
+	 */
+	if (self->sibling[sib].num_waits > 1)
+		self->sibling[sib].num_waits = 1;
+	ASSERT_EQ(0, pthread_cond_broadcast(&self->cond)) {
+		TH_LOG("cond broadcast non-zero");
+	}
+	pthread_mutex_unlock(&self->mutex);
+	pthread_join(self->sibling[sib].tid, &status);
+	EXPECT_EQ(0, (long)status);
+	/* Poll for actual task death. pthread_join doesn't guarantee it. */
+	while (!kill(self->sibling[sib].system_tid, 0)) sleep(0.1);
+
+	ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FLAG_FILTER_TSYNC,
+		      &self->apply_prog);
+	ASSERT_EQ(0, ret);  /* just us chickens */
+}
+
+/* Make sure restarted syscalls are seen directly as "restart_syscall". */
+TEST(syscall_restart) {
+	long ret;
+	unsigned long msg;
+	pid_t child_pid;
+	int pipefd[2];
+	int status;
+	siginfo_t info = { };
+	struct sock_filter filter[] = {
+		BPF_STMT(BPF_LD|BPF_W|BPF_ABS,
+			 offsetof(struct seccomp_data, nr)),
+
+#ifdef __NR_sigreturn
+		BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, __NR_sigreturn, 6, 0),
+#endif
+		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_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 */
+	};
+	struct sock_fprog prog = {
+		.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
+		.filter = filter,
+	};
+
+	ASSERT_EQ(0, pipe(pipefd));
+
+	child_pid = fork();
+	ASSERT_LE(0, child_pid);
+	if (child_pid == 0) {
+		/* Child uses EXPECT not ASSERT to deliver status correctly. */
+		char buf = ' ';
+		struct pollfd fds = {
+			.fd = pipefd[0],
+			.events = POLLIN,
+		};
+
+		/* Attach parent as tracer and stop. */
+		EXPECT_EQ(0, ptrace(PTRACE_TRACEME));
+		EXPECT_EQ(0, raise(SIGSTOP));
+
+		EXPECT_EQ(0, close(pipefd[1]));
+
+		EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
+			TH_LOG("Kernel does not support PR_SET_NO_NEW_PRIVS!");
+		}
+
+		ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0);
+		EXPECT_EQ(0, ret) {
+			TH_LOG("Failed to install filter!");
+		}
+
+		EXPECT_EQ(1, read(pipefd[0], &buf, 1)) {
+			TH_LOG("Failed to read() sync from parent");
+		}
+		EXPECT_EQ('.', buf) {
+			TH_LOG("Failed to get sync data from read()");
+		}
+
+		/* Start poll to be interrupted. */
+		errno = 0;
+		EXPECT_EQ(1, poll(&fds, 1, -1)) {
+			TH_LOG("Call to poll() failed (errno %d)", errno);
+		}
+
+		/* Read final sync from parent. */
+		EXPECT_EQ(1, read(pipefd[0], &buf, 1)) {
+			TH_LOG("Failed final read() from parent");
+		}
+		EXPECT_EQ('!', buf) {
+			TH_LOG("Failed to get final data from read()");
+		}
+
+		/* Directly report the status of our test harness results. */
+		syscall(__NR_exit, _metadata->passed ? EXIT_SUCCESS
+						     : EXIT_FAILURE);
+	}
+	EXPECT_EQ(0, close(pipefd[0]));
+
+	/* Attach to child, setup options, and release. */
+	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
+	ASSERT_EQ(true, WIFSTOPPED(status));
+	ASSERT_EQ(0, ptrace(PTRACE_SETOPTIONS, child_pid, NULL,
+			    PTRACE_O_TRACESECCOMP));
+	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
+	ASSERT_EQ(1, write(pipefd[1], ".", 1));
+
+	/* Wait for poll() 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));
+
+	/* Might as well check siginfo for sanity while we're here. */
+	ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
+	ASSERT_EQ(SIGTRAP, info.si_signo);
+	ASSERT_EQ(SIGTRAP | (PTRACE_EVENT_SECCOMP << 8), info.si_code);
+	EXPECT_EQ(0, info.si_errno);
+	EXPECT_EQ(getuid(), info.si_uid);
+	/* 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). */
+	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));
+	ASSERT_EQ(true, WIFSTOPPED(status));
+	ASSERT_EQ(SIGSTOP, WSTOPSIG(status));
+	/* Verify signal delivery came from parent now. */
+	ASSERT_EQ(0, ptrace(PTRACE_GETSIGINFO, child_pid, NULL, &info));
+	EXPECT_EQ(getpid(), info.si_pid);
+
+	/* Restart poll 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));
+	ASSERT_EQ(true, WIFSTOPPED(status));
+	ASSERT_EQ(SIGCONT, WSTOPSIG(status));
+	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
+
+	/* Wait for restart_syscall() 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(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);
+#endif
+
+	/* Write again to end poll. */
+	ASSERT_EQ(0, ptrace(PTRACE_CONT, child_pid, NULL, 0));
+	ASSERT_EQ(1, write(pipefd[1], "!", 1));
+	EXPECT_EQ(0, close(pipefd[1]));
+
+	ASSERT_EQ(child_pid, waitpid(child_pid, &status, 0));
+	if (WIFSIGNALED(status) || WEXITSTATUS(status))
+		_metadata->passed = 0;
+}
+
+/*
+ * TODO:
+ * - add microbenchmarks
+ * - expand NNP testing
+ * - better arch-specific TRACE and TRAP handlers.
+ * - endianness checking when appropriate
+ * - 64-bit arg prodding
+ * - arch value testing (x86 modes especially)
+ * - ...
+ */
+
+// ANDROID:begin
+struct __test_metadata* get_seccomp_test_list() {
+  return __test_list;
+}
+// ANDROID:end
+
+TEST_HARNESS_MAIN
diff --git a/tests/tests/os/jni/seccomp-tests/tests/sigsegv.c b/tests/tests/os/jni/seccomp-tests/tests/sigsegv.c
new file mode 100644
index 0000000..a0d06e7
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/tests/sigsegv.c
@@ -0,0 +1,179 @@
+/* sigsegv.c
+ * Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Forces a denied system call to trigger a SIGSEGV at the instruction after
+ * the call using a SIGSYS handler.. This can be useful when debugging
+ * frameworks have trouble tracing through the SIGSYS handler.
+ * Proof of concept using amd64 registers and 'syscall'.
+ */
+
+#include <asm/siginfo.h>
+#define __have_siginfo_t 1
+#define __have_sigval_t 1
+#define __have_sigevent_t 1
+
+#include <linux/filter.h>
+#include <sys/prctl.h>
+#include <linux/prctl.h>
+#include <linux/seccomp.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <syscall.h>
+#define __USE_GNU 1
+#include <sys/ucontext.h>
+#include <sys/mman.h>
+
+#include "test_harness.h"
+
+#ifndef PR_SET_NO_NEW_PRIVS
+#define PR_SET_NO_NEW_PRIVS 38
+#define PR_GET_NO_NEW_PRIVS 39
+#endif
+
+#if defined(__i386__)
+#define REG_IP	REG_EIP
+#define REG_SP	REG_ESP
+#define REG_RESULT	REG_EAX
+#define REG_SYSCALL	REG_EAX
+#define REG_ARG0	REG_EBX
+#define REG_ARG1	REG_ECX
+#define REG_ARG2	REG_EDX
+#define REG_ARG3	REG_ESI
+#define REG_ARG4	REG_EDI
+#define REG_ARG5	REG_EBP
+#elif defined(__x86_64__)
+#define REG_IP	REG_RIP
+#define REG_SP	REG_RSP
+#define REG_RESULT	REG_RAX
+#define REG_SYSCALL	REG_RAX
+#define REG_ARG0	REG_RDI
+#define REG_ARG1	REG_RSI
+#define REG_ARG2	REG_RDX
+#define REG_ARG3	REG_R10
+#define REG_ARG4	REG_R8
+#define REG_ARG5	REG_R9
+#endif
+
+FIXTURE_DATA(TRAP) {
+	struct sock_fprog prog;
+};
+
+FIXTURE_SETUP(TRAP) {
+	/* instruction after the syscall. Will be arch specific, of course. */
+	{
+		struct sock_filter filter[] = {
+			BPF_STMT(BPF_LD+BPF_W+BPF_ABS,
+				offsetof(struct seccomp_data, nr)),
+			/* Whitelist anything you might need in the sigaction */
+#ifdef __NR_sigreturn
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_sigreturn, 4, 0),
+#endif
+			/* TODO: only allow PROT_NONE */
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_mprotect, 3, 0),
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_exit, 2, 0),
+			BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, __NR_rt_sigreturn, 1, 0),
+			/* Allow __NR_write so 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_TRAP),
+		};
+		memset(&self->prog, 0, sizeof(self->prog));
+		self->prog.filter = malloc(sizeof(filter));
+		ASSERT_NE(NULL, self->prog.filter);
+		memcpy(self->prog.filter, filter, sizeof(filter));
+		self->prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0]));
+	}
+}
+
+FIXTURE_TEARDOWN(TRAP) {
+	if (self->prog.filter)
+		free(self->prog.filter);
+};
+
+struct arch_sigsys {
+		void *_call_addr; /* calling user insn */
+		int _syscall;	/* triggering system call number */
+		unsigned int _arch;	/* AUDIT_ARCH_* of syscall */
+};
+
+#define _ALIGN(x,sz) (((x + ((sz)-1)) & ~((sz)-1)) - (sz))
+#define ALIGN(x,sz) ((typeof(x))_ALIGN((unsigned long)(x),(unsigned long)(sz)))
+static long local_mprotect(void *target, unsigned long sz)
+{
+	register unsigned long res asm ("rax") = __NR_mprotect;
+	__attribute__((unused)) register void *addr asm ("rdi") = ALIGN(target, sz);
+	__attribute__((unused)) register long len asm ("rsi") = sz;
+	__attribute__((unused)) register long num asm ("rdx") = PROT_NONE;
+	__asm__("syscall\n");
+	return res;
+}
+
+static void TRAP_action(int nr, siginfo_t *info, void *void_context)
+{
+	ucontext_t *ctx = (ucontext_t *)void_context;
+	char buf[256];
+	int len;
+	struct arch_sigsys *sys = (struct arch_sigsys *)
+#ifdef si_syscall
+		&(info->si_call_addr);
+#else
+		&(info->si_pid);
+#endif
+
+	if (info->si_code != SYS_SECCOMP)
+		return;
+	if (!ctx)
+		return;
+	len = snprintf(buf, sizeof(buf),
+			"@0x%lX:%X:%d:0x%lX:0x%lX:0x%lX:0x%lX:0x%lX:0x%lX [0x%lX]\n",
+			(unsigned long)sys->_call_addr,
+			sys->_arch,
+			sys->_syscall,
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG0],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG1],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG2],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG3],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG4],
+			(unsigned long)ctx->uc_mcontext.gregs[REG_ARG5],
+			(unsigned long)ALIGN(ctx->uc_mcontext.gregs[REG_IP],
+			4096));
+	/* Emit some useful logs or whatever. */
+	syscall(__NR_write, STDOUT_FILENO, buf, len);
+	/* Make the calling page non-exec */
+	/* Careful on how it is called since it may make the syscall() instructions non-exec. */
+	local_mprotect((void *)ctx->uc_mcontext.gregs[REG_IP], sysconf(_SC_PAGE_SIZE));
+}
+
+TEST_F_SIGNAL(TRAP, sigsegv, SIGSEGV) {
+	int ret;
+	struct sigaction act;
+	sigset_t mask;
+	memset(&act, 0, sizeof(act));
+	sigemptyset(&mask);
+	sigaddset(&mask, SIGSYS);
+
+	act.sa_sigaction = &TRAP_action;
+	act.sa_flags = SA_SIGINFO;
+	ret = sigaction(SIGSYS, &act, NULL);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("sigaction failed");
+	}
+	ret = sigprocmask(SIG_UNBLOCK, &mask, NULL);
+	ASSERT_EQ(0, ret) {
+		TH_LOG("sigprocmask failed");
+	}
+
+	ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
+	ASSERT_EQ(0, ret);
+	ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &self->prog);
+	ASSERT_EQ(0, ret);
+
+	/* Call anything! */
+	ret = syscall(__NR_getpid);
+}
+
+TEST_HARNESS_MAIN
diff --git a/tests/tests/os/jni/seccomp-tests/tests/test_harness.h b/tests/tests/os/jni/seccomp-tests/tests/test_harness.h
new file mode 100644
index 0000000..597e40c
--- /dev/null
+++ b/tests/tests/os/jni/seccomp-tests/tests/test_harness.h
@@ -0,0 +1,521 @@
+/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * test_harness.h: simple C unit test helper.
+ *
+ * Usage:
+ *   #include "test_harness.h"
+ *   TEST(standalone_test) {
+ *     do_some_stuff;
+ *     EXPECT_GT(10, stuff) {
+ *        stuff_state_t state;
+ *        enumerate_stuff_state(&state);
+ *        TH_LOG("expectation failed with state: %s", state.msg);
+ *     }
+ *     more_stuff;
+ *     ASSERT_NE(some_stuff, NULL) TH_LOG("how did it happen?!");
+ *     last_stuff;
+ *     EXPECT_EQ(0, last_stuff);
+ *   }
+ *
+ *   FIXTURE(my_fixture) {
+ *     mytype_t *data;
+ *     int awesomeness_level;
+ *   };
+ *   FIXTURE_SETUP(my_fixture) {
+ *     self->data = mytype_new();
+ *     ASSERT_NE(NULL, self->data);
+ *   }
+ *   FIXTURE_TEARDOWN(my_fixture) {
+ *     mytype_free(self->data);
+ *   }
+ *   TEST_F(my_fixture, data_is_good) {
+ *     EXPECT_EQ(1, is_my_data_good(self->data));
+ *   }
+ *
+ *   TEST_HARNESS_MAIN
+ *
+ * API inspired by code.google.com/p/googletest
+ */
+#ifndef TEST_HARNESS_H_
+#define TEST_HARNESS_H_
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <android/log.h>  // ANDROID
+
+/* All exported functionality should be declared through this macro. */
+#define TEST_API(x) _##x
+
+/*
+ * Exported APIs
+ */
+
+/* TEST(name) { implementation }
+ * Defines a test by name.
+ * Names must be unique and tests must not be run in parallel.  The
+ * implementation containing block is a function and scoping should be treated
+ * as such.  Returning early may be performed with a bare "return;" statement.
+ *
+ * EXPECT_* and ASSERT_* are valid in a TEST() { } context.
+ */
+#define TEST TEST_API(TEST)
+
+/* TEST_SIGNAL(name, signal) { implementation }
+ * Defines a test by name and the expected term signal.
+ * Names must be unique and tests must not be run in parallel.  The
+ * implementation containing block is a function and scoping should be treated
+ * as such.  Returning early may be performed with a bare "return;" statement.
+ *
+ * EXPECT_* and ASSERT_* are valid in a TEST() { } context.
+ */
+#define TEST_SIGNAL TEST_API(TEST_SIGNAL)
+
+/* FIXTURE(datatype name) {
+ *   type property1;
+ *   ...
+ * };
+ * Defines the data provided to TEST_F()-defined tests as |self|.  It should be
+ * populated and cleaned up using FIXTURE_SETUP and FIXTURE_TEARDOWN.
+ */
+#define FIXTURE TEST_API(FIXTURE)
+
+/* FIXTURE_DATA(datatype name)
+ * This call may be used when the type of the fixture data
+ * is needed.  In general, this should not be needed unless
+ * the |self| is being passed to a helper directly.
+ */
+#define FIXTURE_DATA TEST_API(FIXTURE_DATA)
+
+/* FIXTURE_SETUP(fixture name) { implementation }
+ * Populates the required "setup" function for a fixture.  An instance of the
+ * datatype defined with _FIXTURE_DATA will be exposed as |self| for the
+ * implementation.
+ *
+ * ASSERT_* are valid for use in this context and will prempt the execution
+ * of any dependent fixture tests.
+ *
+ * A bare "return;" statement may be used to return early.
+ */
+#define FIXTURE_SETUP TEST_API(FIXTURE_SETUP)
+
+/* FIXTURE_TEARDOWN(fixture name) { implementation }
+ * Populates the required "teardown" function for a fixture.  An instance of the
+ * datatype defined with _FIXTURE_DATA will be exposed as |self| for the
+ * implementation to clean up.
+ *
+ * A bare "return;" statement may be used to return early.
+ */
+#define FIXTURE_TEARDOWN TEST_API(FIXTURE_TEARDOWN)
+
+/* TEST_F(fixture, name) { implementation }
+ * Defines a test that depends on a fixture (e.g., is part of a test case).
+ * Very similar to TEST() except that |self| is the setup instance of fixture's
+ * datatype exposed for use by the implementation.
+ */
+#define TEST_F TEST_API(TEST_F)
+
+#define TEST_F_SIGNAL TEST_API(TEST_F_SIGNAL)
+
+/* Use once to append a main() to the test file. E.g.,
+ *   TEST_HARNESS_MAIN
+ */
+#define TEST_HARNESS_MAIN TEST_API(TEST_HARNESS_MAIN)
+
+/*
+ * Operators for use in TEST and TEST_F.
+ * ASSERT_* calls will stop test execution immediately.
+ * EXPECT_* calls will emit a failure warning, note it, and continue.
+ */
+
+/* ASSERT_EQ(expected, measured): expected == measured */
+#define ASSERT_EQ TEST_API(ASSERT_EQ)
+/* ASSERT_NE(expected, measured): expected != measured */
+#define ASSERT_NE TEST_API(ASSERT_NE)
+/* ASSERT_LT(expected, measured): expected < measured */
+#define ASSERT_LT TEST_API(ASSERT_LT)
+/* ASSERT_LE(expected, measured): expected <= measured */
+#define ASSERT_LE TEST_API(ASSERT_LE)
+/* ASSERT_GT(expected, measured): expected > measured */
+#define ASSERT_GT TEST_API(ASSERT_GT)
+/* ASSERT_GE(expected, measured): expected >= measured */
+#define ASSERT_GE TEST_API(ASSERT_GE)
+/* ASSERT_NULL(measured): NULL == measured */
+#define ASSERT_NULL TEST_API(ASSERT_NULL)
+/* ASSERT_TRUE(measured): measured != 0 */
+#define ASSERT_TRUE TEST_API(ASSERT_TRUE)
+/* ASSERT_FALSE(measured): measured == 0 */
+#define ASSERT_FALSE TEST_API(ASSERT_FALSE)
+/* ASSERT_STREQ(expected, measured): !strcmp(expected, measured) */
+#define ASSERT_STREQ TEST_API(ASSERT_STREQ)
+/* ASSERT_STRNE(expected, measured): strcmp(expected, measured) */
+#define ASSERT_STRNE TEST_API(ASSERT_STRNE)
+/* EXPECT_EQ(expected, measured): expected == measured */
+#define EXPECT_EQ TEST_API(EXPECT_EQ)
+/* EXPECT_NE(expected, measured): expected != measured */
+#define EXPECT_NE TEST_API(EXPECT_NE)
+/* EXPECT_LT(expected, measured): expected < measured */
+#define EXPECT_LT TEST_API(EXPECT_LT)
+/* EXPECT_LE(expected, measured): expected <= measured */
+#define EXPECT_LE TEST_API(EXPECT_LE)
+/* EXPECT_GT(expected, measured): expected > measured */
+#define EXPECT_GT TEST_API(EXPECT_GT)
+/* EXPECT_GE(expected, measured): expected >= measured */
+#define EXPECT_GE TEST_API(EXPECT_GE)
+/* EXPECT_NULL(measured): NULL == measured */
+#define EXPECT_NULL TEST_API(EXPECT_NULL)
+/* EXPECT_TRUE(measured): 0 != measured */
+#define EXPECT_TRUE TEST_API(EXPECT_TRUE)
+/* EXPECT_FALSE(measured): 0 == measured */
+#define EXPECT_FALSE TEST_API(EXPECT_FALSE)
+/* EXPECT_STREQ(expected, measured): !strcmp(expected, measured) */
+#define EXPECT_STREQ TEST_API(EXPECT_STREQ)
+/* EXPECT_STRNE(expected, measured): strcmp(expected, measured) */
+#define EXPECT_STRNE TEST_API(EXPECT_STRNE)
+
+/* TH_LOG(format, ...)
+ * Optional debug logging function available for use in tests.
+ * Logging may be enabled or disabled by defining TH_LOG_ENABLED.
+ * E.g., #define TH_LOG_ENABLED 1
+ * If no definition is provided, logging is enabled by default.
+ */
+#define TH_LOG  TEST_API(TH_LOG)
+
+/*
+ * Internal implementation.
+ *
+ */
+
+/* Utilities exposed to the test definitions */
+#ifndef TH_LOG_STREAM
+#  define TH_LOG_STREAM stderr
+#endif
+
+#ifndef TH_LOG_ENABLED
+#  define TH_LOG_ENABLED 1
+#endif
+
+#define _TH_LOG(fmt, ...) do { \
+  if (TH_LOG_ENABLED) \
+    __TH_LOG(fmt, ##__VA_ARGS__); \
+} while (0)
+
+/* Unconditional logger for internal use. */
+// ANDROID:begin
+#define __TH_LOG(fmt, ...) \
+    __android_log_print(ANDROID_LOG_ERROR, "SeccompBpfTest-KernelUnit", "%s:%d:%s:" fmt "\n", \
+            __FILE__, __LINE__, _metadata->name, ##__VA_ARGS__)
+// ANDROID:end
+
+/* Defines the test function and creates the registration stub. */
+#define _TEST(test_name) __TEST_IMPL(test_name, -1)
+
+#define _TEST_SIGNAL(test_name, signal) __TEST_IMPL(test_name, signal)
+
+#define __TEST_IMPL(test_name, _signal) \
+  static void test_name(struct __test_metadata *_metadata); \
+  static struct __test_metadata _##test_name##_object = \
+    { name: "global." #test_name, fn: &test_name, termsig: _signal }; \
+  static void __attribute__((constructor)) _register_##test_name(void) { \
+    __register_test(&_##test_name##_object); \
+  } \
+  static void test_name( \
+    struct __test_metadata __attribute__((unused)) *_metadata)
+
+/* Wraps the struct name so we have one less argument to pass around. */
+#define _FIXTURE_DATA(fixture_name) struct _test_data_##fixture_name
+
+/* Called once per fixture to setup the data and register. */
+#define _FIXTURE(fixture_name) \
+  static void __attribute__((constructor)) \
+      _register_##fixture_name##_data(void) { \
+    __fixture_count++; \
+  } \
+  _FIXTURE_DATA(fixture_name)
+
+/* Prepares the setup function for the fixture.  |_metadata| is included
+ * so that ASSERT_* work as a convenience.
+ */
+#define _FIXTURE_SETUP(fixture_name) \
+  void fixture_name##_setup( \
+    struct __test_metadata __attribute__((unused)) *_metadata, \
+    _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
+#define _FIXTURE_TEARDOWN(fixture_name) \
+  void fixture_name##_teardown( \
+    struct __test_metadata __attribute__((unused)) *_metadata, \
+    _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
+
+/* Emits test registration and helpers for fixture-based test
+ * cases.
+ * TODO(wad) register fixtures on dedicated test lists.
+ */
+#define _TEST_F(fixture_name, test_name) \
+  __TEST_F_IMPL(fixture_name, test_name, -1)
+
+#define _TEST_F_SIGNAL(fixture_name, test_name, signal) \
+  __TEST_F_IMPL(fixture_name, test_name, signal)
+
+#define __TEST_F_IMPL(fixture_name, test_name, signal) \
+  static void fixture_name##_##test_name( \
+    struct __test_metadata *_metadata, \
+    _FIXTURE_DATA(fixture_name) *self); \
+  static inline void wrapper_##fixture_name##_##test_name( \
+    struct __test_metadata *_metadata) { \
+    /* fixture data is allocated, setup, and torn down per call. */ \
+    _FIXTURE_DATA(fixture_name) self; \
+    memset(&self, 0, sizeof(_FIXTURE_DATA(fixture_name))); \
+    fixture_name##_setup(_metadata, &self); \
+    /* Let setup failure terminate early. */ \
+    if (!_metadata->passed) return; \
+    fixture_name##_##test_name(_metadata, &self); \
+    fixture_name##_teardown(_metadata, &self); \
+  } \
+  static struct __test_metadata _##fixture_name##_##test_name##_object = { \
+    name: #fixture_name "." #test_name, \
+    fn: &wrapper_##fixture_name##_##test_name, \
+    termsig: signal, \
+   }; \
+  static void __attribute__((constructor)) \
+      _register_##fixture_name##_##test_name(void) { \
+    __register_test(&_##fixture_name##_##test_name##_object); \
+  } \
+  static void fixture_name##_##test_name( \
+    struct __test_metadata __attribute__((unused)) *_metadata, \
+    _FIXTURE_DATA(fixture_name) __attribute__((unused)) *self)
+
+/* Exports a simple wrapper to run the test harness. */
+#define _TEST_HARNESS_MAIN \
+  static void __attribute__((constructor)) __constructor_order_last(void) { \
+    if (!__constructor_order) \
+      __constructor_order = _CONSTRUCTOR_ORDER_BACKWARD; \
+  } \
+  int seccomp_test_main(int argc, char **argv) { return test_harness_run(argc, argv); }  // ANDROID
+
+#define _ASSERT_EQ(_expected, _seen) \
+  __EXPECT(_expected, _seen, ==, 1)
+#define _ASSERT_NE(_expected, _seen) \
+  __EXPECT(_expected, _seen, !=, 1)
+#define _ASSERT_LT(_expected, _seen) \
+  __EXPECT(_expected, _seen, <, 1)
+#define _ASSERT_LE(_expected, _seen) \
+  __EXPECT(_expected, _seen, <=, 1)
+#define _ASSERT_GT(_expected, _seen) \
+  __EXPECT(_expected, _seen, >, 1)
+#define _ASSERT_GE(_expected, _seen) \
+  __EXPECT(_expected, _seen, >=, 1)
+#define _ASSERT_NULL(_seen) \
+  __EXPECT(NULL, _seen, ==, 1)
+
+#define _ASSERT_TRUE(_seen) \
+  _ASSERT_NE(0, _seen)
+#define _ASSERT_FALSE(_seen) \
+  _ASSERT_EQ(0, _seen)
+#define _ASSERT_STREQ(_expected, _seen) \
+  __EXPECT_STR(_expected, _seen, ==, 1)
+#define _ASSERT_STRNE(_expected, _seen) \
+  __EXPECT_STR(_expected, _seen, !=, 1)
+
+#define _EXPECT_EQ(_expected, _seen) \
+  __EXPECT(_expected, _seen, ==, 0)
+#define _EXPECT_NE(_expected, _seen) \
+  __EXPECT(_expected, _seen, !=, 0)
+#define _EXPECT_LT(_expected, _seen) \
+  __EXPECT(_expected, _seen, <, 0)
+#define _EXPECT_LE(_expected, _seen) \
+  __EXPECT(_expected, _seen, <=, 0)
+#define _EXPECT_GT(_expected, _seen) \
+  __EXPECT(_expected, _seen, >, 0)
+#define _EXPECT_GE(_expected, _seen) \
+  __EXPECT(_expected, _seen, >=, 0)
+
+#define _EXPECT_NULL(_seen) \
+  __EXPECT(NULL, _seen, ==, 0)
+#define _EXPECT_TRUE(_seen) \
+  _EXPECT_NE(0, _seen)
+#define _EXPECT_FALSE(_seen) \
+  _EXPECT_EQ(0, _seen)
+
+#define _EXPECT_STREQ(_expected, _seen) \
+  __EXPECT_STR(_expected, _seen, ==, 0)
+#define _EXPECT_STRNE(_expected, _seen) \
+  __EXPECT_STR(_expected, _seen, !=, 0)
+
+/* Support an optional handler after and ASSERT_* or EXPECT_*.  The approach is
+ * not thread-safe, but it should be fine in most sane test scenarios.
+ *
+ * Using __bail(), which optionally abort()s, is the easiest way to early
+ * return while still providing an optional block to the API consumer.
+ */
+#define OPTIONAL_HANDLER(_assert) \
+  for (; _metadata->trigger;  _metadata->trigger = __bail(_assert))
+
+#define __EXPECT(_expected, _seen, _t, _assert) do { \
+  /* Avoid multiple evaluation of the cases */ \
+  __typeof__(_expected) __exp = (_expected); \
+  __typeof__(_seen) __seen = (_seen); \
+  if (!(__exp _t __seen)) { \
+    unsigned long long __exp_print = 0; \
+    unsigned long long __seen_print = 0; \
+    /* Avoid casting complaints the scariest way we can. */ \
+    memcpy(&__exp_print, &__exp, sizeof(__exp)); \
+    memcpy(&__seen_print, &__seen, sizeof(__seen)); \
+    __TH_LOG("Expected %s (%llu) %s %s (%llu)", \
+            #_expected, __exp_print, #_t, \
+            #_seen, __seen_print); \
+    _metadata->passed = 0; \
+    /* Ensure the optional handler is triggered */ \
+    _metadata->trigger = 1; \
+  } \
+} while (0); OPTIONAL_HANDLER(_assert)
+
+#define __EXPECT_STR(_expected, _seen, _t, _assert) do { \
+  const char *__exp = (_expected); \
+  const char *__seen = (_seen); \
+  if (!(strcmp(__exp, __seen) _t 0))  { \
+    __TH_LOG("Expected '%s' %s '%s'.", __exp, #_t, __seen); \
+    _metadata->passed = 0; \
+    _metadata->trigger = 1; \
+  } \
+} while (0); OPTIONAL_HANDLER(_assert)
+
+/* Contains all the information for test execution and status checking. */
+struct __test_metadata {
+  const char *name;
+  void (*fn)(struct __test_metadata *);
+  int termsig;
+  int passed;
+  int trigger; /* extra handler after the evaluation */
+  struct __test_metadata *prev, *next;
+};
+
+/* Storage for the (global) tests to be run. */
+static struct __test_metadata *__test_list = NULL;
+static unsigned int __test_count = 0;
+static unsigned int __fixture_count = 0;
+static int __constructor_order = 0;
+
+#define _CONSTRUCTOR_ORDER_FORWARD   1
+#define _CONSTRUCTOR_ORDER_BACKWARD -1
+
+/*
+ * Since constructors are called in reverse order, reverse the test
+ * list so tests are run in source declaration order.
+ * https://gcc.gnu.org/onlinedocs/gccint/Initialization.html
+ * However, it seems not all toolchains do this correctly, so use
+ * __constructor_order to detect which direction is called first
+ * and adjust list building logic to get things running in the right
+ * direction.
+ */
+static inline void __register_test(struct __test_metadata *t) {
+  __test_count++;
+  /* Circular linked list where only prev is circular. */
+  if (__test_list == NULL) {
+    __test_list = t;
+    t->next = NULL;
+    t->prev = t;
+    return;
+  }
+  if (__constructor_order == _CONSTRUCTOR_ORDER_FORWARD) {
+    t->next = NULL;
+    t->prev = __test_list->prev;
+    t->prev->next = t;
+    __test_list->prev = t;
+  } else {
+    t->next = __test_list;
+    t->next->prev = t;
+    t->prev = t;
+    __test_list = t;
+  }
+}
+
+static inline int __bail(int for_realz) {
+  if (for_realz)
+    abort();
+  return 0;
+}
+
+void __run_test(struct __test_metadata *t) {
+  pid_t child_pid;
+  int status;
+  t->passed = 1;
+  t->trigger = 0;
+  printf("[ RUN      ] %s\n", t->name);
+  child_pid = fork();
+  if (child_pid < 0) {
+    printf("ERROR SPAWNING TEST CHILD\n");
+    t->passed = 0;
+  } else if (child_pid == 0) {
+    t->fn(t);
+    _exit(t->passed);
+  } else {
+    /* TODO(wad) add timeout support. */
+    waitpid(child_pid, &status, 0);
+    if (WIFEXITED(status)) {
+      t->passed = t->termsig == -1 ? WEXITSTATUS(status) : 0;
+      if (t->termsig != -1) {
+       fprintf(TH_LOG_STREAM,
+                "%s: Test exited normally instead of by signal (code: %d)\n",
+               t->name,
+               WEXITSTATUS(status));
+      }
+    } else if (WIFSIGNALED(status)) {
+      t->passed = 0;
+      if (WTERMSIG(status) == SIGABRT) {
+        fprintf(TH_LOG_STREAM,
+                "%s: Test terminated by assertion\n",
+               t->name);
+      } else if (WTERMSIG(status) == t->termsig) {
+        t->passed = 1;
+      } else {
+        fprintf(TH_LOG_STREAM,
+                "%s: Test terminated unexpectedly by signal %d\n",
+               t->name,
+               WTERMSIG(status));
+      }
+    } else {
+        fprintf(TH_LOG_STREAM,
+                "%s: Test ended in some other way [%u]\n",
+               t->name,
+               status);
+    }
+  }
+  printf("[     %4s ] %s\n", (t->passed ? "OK" : "FAIL"), t->name);
+}
+
+static int test_harness_run(int __attribute__((unused)) argc,
+                            char __attribute__((unused)) **argv) {
+  struct __test_metadata *t;
+  int ret = 0;
+  unsigned int count = 0;
+  unsigned int pass_count = 0;
+
+  /* TODO(wad) add optional arguments similar to gtest. */
+  printf("[==========] Running %u tests from %u test cases.\n",
+          __test_count, __fixture_count + 1);
+  for (t = __test_list; t; t = t->next) {
+    count++;
+    __run_test(t);
+    if (t->passed)
+      pass_count++;
+    else
+      ret = 1;
+  }
+  /* TODO(wad) organize by fixtures since ordering is not guaranteed now. */
+  printf("[==========] %u / %u tests passed.\n", pass_count, count);
+  printf("[  %s  ]\n", (ret ? "FAILED" : "PASSED"));
+  return ret;
+}
+
+static void __attribute__((constructor)) __constructor_order_first(void) {
+  if (!__constructor_order)
+    __constructor_order = _CONSTRUCTOR_ORDER_FORWARD;
+}
+
+#endif  /* TEST_HARNESS_H_ */
diff --git a/tests/tests/os/jni/seccomp_sample_program.cpp b/tests/tests/os/jni/seccomp_sample_program.cpp
new file mode 100644
index 0000000..3bc7da4
--- /dev/null
+++ b/tests/tests/os/jni/seccomp_sample_program.cpp
@@ -0,0 +1,1456 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <linux/filter.h>
+
+// This file defines a sample seccomp-bpf policy. It is taken from the
+// Chromium renderer process policy applied to isolatedProcess services.
+//
+// In the future, this policy should be further restricted to just the set
+// of system calls that an isolatedProcess should be allowed to make.
+
+#if defined(__arm__)
+struct sock_filter kTestSeccompFilter[] = {
+  {0x20, 0, 0, 0x4},
+  {0x15, 1, 0, 0x40000028},
+  {0x6, 0, 0, 0x30006},
+  {0x20, 0, 0, 0x0},
+  {0x35, 0, 90, 0xab},
+  {0x35, 0, 43, 0x108},
+  {0x35, 0, 21, 0x14f},
+  {0x35, 0, 10, 0x168},
+  {0x35, 0, 5, 0x181},
+  {0x35, 0, 2, 0xf0006},
+  {0x35, 0, 58, 0xffff0},
+  {0x35, 57, 55, 0xffff1},
+  {0x35, 0, 43, 0x182},
+  {0x35, 53, 55, 0xf0001},
+  {0x35, 0, 2, 0x16f},
+  {0x35, 0, 53, 0x17e},
+  {0x35, 52, 39, 0x180},
+  {0x35, 38, 51, 0x16e},
+  {0x35, 0, 5, 0x15b},
+  {0x35, 0, 2, 0x160},
+  {0x35, 0, 35, 0x161},
+  {0x35, 45, 47, 0x165},
+  {0x35, 0, 46, 0x15c},
+  {0x35, 45, 32, 0x15d},
+  {0x35, 0, 2, 0x152},
+  {0x35, 0, 30, 0x153},
+  {0x35, 40, 42, 0x15a},
+  {0x35, 41, 39, 0x151},
+  {0x35, 0, 10, 0x121},
+  {0x35, 0, 5, 0x138},
+  {0x35, 0, 2, 0x143},
+  {0x35, 0, 24, 0x147},
+  {0x35, 23, 34, 0x148},
+  {0x35, 0, 22, 0x139},
+  {0x35, 32, 34, 0x142},
+  {0x35, 0, 2, 0x127},
+  {0x35, 0, 30, 0x12a},
+  {0x35, 31, 18, 0x135},
+  {0x35, 30, 28, 0x126},
+  {0x35, 0, 4, 0x10e},
+  {0x35, 0, 2, 0x119},
+  {0x35, 0, 14, 0x11e},
+  {0x35, 137, 26, 0x120},
+  {0x35, 23, 25, 0x118},
+  {0x35, 0, 3, 0x10b},
+  {0x35, 0, 23, 0x10c},
+  {0x35, 9, 0, 0x10d},
+  {0x5, 0, 0, 0x110},
+  {0x35, 7, 20, 0x10a},
+  {0x35, 0, 25, 0xce},
+  {0x35, 0, 12, 0xee},
+  {0x35, 0, 6, 0xf9},
+  {0x35, 0, 2, 0x100},
+  {0x35, 0, 13, 0x101},
+  {0x35, 129, 14, 0x107},
+  {0x35, 1, 0, 0xfa},
+  {0x5, 0, 0, 0x10d},
+  {0x35, 11, 9, 0xfd},
+  {0x35, 0, 2, 0xf0},
+  {0x35, 0, 148, 0xf1},
+  {0x35, 6, 8, 0xf8},
+  {0x35, 7, 0, 0xef},
+  {0x5, 0, 0, 0x106},
+  {0x35, 0, 7, 0xda},
+  {0x35, 0, 3, 0xde},
+  {0x35, 0, 3, 0xe0},
+  {0x35, 2, 0, 0xe1},
+  {0x5, 0, 0, 0x103},
+  {0x35, 1, 0, 0xdc},
+  {0x5, 0, 0, 0x102},
+  {0x35, 209, 172, 0xdd},
+  {0x35, 0, 2, 0xd2},
+  {0x35, 0, 253, 0xd3},
+  {0x35, 252, 253, 0xd4},
+  {0x35, 252, 251, 0xd1},
+  {0x35, 0, 10, 0xb9},
+  {0x35, 0, 5, 0xc1},
+  {0x35, 0, 2, 0xc7},
+  {0x35, 0, 248, 0xcb},
+  {0x35, 247, 246, 0xcd},
+  {0x35, 0, 245, 0xc5},
+  {0x35, 244, 245, 0xc6},
+  {0x35, 0, 2, 0xbb},
+  {0x35, 0, 244, 0xbf},
+  {0x35, 162, 242, 0xc0},
+  {0x35, 241, 240, 0xba},
+  {0x35, 0, 4, 0xb2},
+  {0x35, 0, 2, 0xb5},
+  {0x35, 0, 239, 0xb6},
+  {0x35, 237, 236, 0xb8},
+  {0x35, 236, 237, 0xb4},
+  {0x35, 0, 2, 0xad},
+  {0x35, 0, 234, 0xb0},
+  {0x35, 233, 234, 0xb1},
+  {0x35, 156, 232, 0xac},
+  {0x35, 0, 42, 0x52},
+  {0x35, 0, 21, 0x7e},
+  {0x35, 0, 10, 0x96},
+  {0x35, 0, 5, 0xa4},
+  {0x35, 0, 2, 0xa8},
+  {0x35, 0, 226, 0xa9},
+  {0x35, 224, 226, 0xaa},
+  {0x35, 0, 223, 0xa5},
+  {0x35, 224, 223, 0xa6},
+  {0x35, 0, 2, 0x9e},
+  {0x35, 0, 221, 0x9f},
+  {0x35, 220, 221, 0xa2},
+  {0x35, 220, 219, 0x98},
+  {0x35, 0, 5, 0x8c},
+  {0x35, 0, 2, 0x90},
+  {0x35, 0, 217, 0x91},
+  {0x35, 216, 215, 0x94},
+  {0x35, 0, 214, 0x8d},
+  {0x35, 213, 212, 0x8e},
+  {0x35, 0, 2, 0x85},
+  {0x35, 0, 210, 0x86},
+  {0x35, 209, 211, 0x8a},
+  {0x35, 210, 209, 0x7f},
+  {0x35, 0, 10, 0x64},
+  {0x35, 0, 5, 0x73},
+  {0x35, 0, 2, 0x7a},
+  {0x35, 0, 205, 0x7b},
+  {0x35, 153, 205, 0x7d},
+  {0x35, 0, 204, 0x77},
+  {0x35, 203, 202, 0x79},
+  {0x35, 0, 2, 0x6c},
+  {0x35, 0, 200, 0x6d},
+  {0x35, 199, 200, 0x72},
+  {0x35, 197, 199, 0x6a},
+  {0x35, 0, 4, 0x5b},
+  {0x35, 0, 2, 0x60},
+  {0x35, 0, 195, 0x62},
+  {0x35, 193, 195, 0x63},
+  {0x35, 192, 193, 0x5c},
+  {0x35, 0, 2, 0x54},
+  {0x35, 0, 192, 0x55},
+  {0x35, 191, 189, 0x57},
+  {0x35, 188, 190, 0x53},
+  {0x35, 0, 21, 0x2d},
+  {0x35, 0, 10, 0x3e},
+  {0x35, 0, 5, 0x46},
+  {0x35, 0, 2, 0x4f},
+  {0x35, 0, 185, 0x50},
+  {0x35, 182, 183, 0x51},
+  {0x35, 0, 181, 0x48},
+  {0x35, 181, 182, 0x4e},
+  {0x35, 0, 2, 0x41},
+  {0x35, 0, 180, 0x43},
+  {0x35, 179, 178, 0x44},
+  {0x35, 177, 176, 0x3f},
+  {0x35, 0, 5, 0x33},
+  {0x35, 0, 2, 0x38},
+  {0x35, 0, 175, 0x3c},
+  {0x35, 174, 172, 0x3d},
+  {0x35, 0, 173, 0x36},
+  {0x35, 124, 171, 0x37},
+  {0x35, 0, 2, 0x2f},
+  {0x35, 0, 169, 0x30},
+  {0x35, 168, 169, 0x31},
+  {0x35, 166, 167, 0x2e},
+  {0x35, 0, 10, 0x17},
+  {0x35, 0, 5, 0x21},
+  {0x35, 0, 2, 0x26},
+  {0x35, 0, 162, 0x29},
+  {0x35, 163, 162, 0x2b},
+  {0x35, 0, 160, 0x22},
+  {0x35, 153, 161, 0x25},
+  {0x35, 0, 2, 0x19},
+  {0x35, 0, 159, 0x1d},
+  {0x35, 158, 157, 0x1e},
+  {0x35, 156, 155, 0x18},
+  {0x35, 0, 4, 0xd},
+  {0x35, 0, 2, 0x11},
+  {0x35, 0, 154, 0x13},
+  {0x35, 153, 152, 0x15},
+  {0x35, 150, 152, 0xe},
+  {0x35, 0, 2, 0x3},
+  {0x35, 0, 149, 0x7},
+  {0x35, 147, 149, 0x8},
+  {0x35, 146, 147, 0x2},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 140, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 143, 144, 0x1},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 136, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 139, 0, 0x1},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 132, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 135, 0, 0x6},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 128, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 131, 0, 0x2},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 124, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 127, 0, 0x0},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 120, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 123, 0, 0x5},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 116, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 119, 120, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 112, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 115, 0xfffffe7f},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 108, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 110, 0, 0x1},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 103, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 105, 0, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 98, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 100, 0, 0x4},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 93, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 95, 0, 0x5},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 88, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 90, 0, 0x9},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 83, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 85, 0, 0xa},
+  {0x6, 0, 0, 0x30005},
+  {0x20, 0, 0, 0x24},
+  {0x15, 0, 77, 0x0},
+  {0x20, 0, 0, 0x20},
+  {0x15, 80, 79, 0x4},
+  {0x20, 0, 0, 0x2c},
+  {0x15, 0, 73, 0x0},
+  {0x20, 0, 0, 0x28},
+  {0x45, 77, 76, 0xfffdb7cc},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 69, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 72, 0, 0x10},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 65, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 68, 0, 0xf},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 61, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 64, 0, 0x3},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 57, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 60, 0, 0x4},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 53, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 56, 0, 0x53564d41},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 49, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 52, 0, 0x29},
+  {0x6, 0, 0, 0x30004},
+  {0x20, 0, 0, 0x24},
+  {0x15, 0, 44, 0x0},
+  {0x20, 0, 0, 0x20},
+  {0x45, 48, 47, 0xfffffff8},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 40, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 43, 0, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 36, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 39, 0, 0x1},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 32, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 35, 0, 0x2},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 28, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 31, 0, 0x6},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 24, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 27, 0, 0x7},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 20, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 23, 0, 0x5},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 16, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 19, 0, 0x0},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 12, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 15, 0, 0x406},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 8, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 0, 12, 0x4},
+  {0x20, 0, 0, 0x24},
+  {0x15, 0, 4, 0x0},
+  {0x20, 0, 0, 0x20},
+  {0x45, 8, 7, 0xfff1e3fc},
+  {0x20, 0, 0, 0x14},
+  {0x15, 1, 0, 0x0},
+  {0x6, 0, 0, 0x30003},
+  {0x20, 0, 0, 0x10},
+  {0x15, 2, 0, 0x2da4},
+  {0x6, 0, 0, 0x30002},
+  {0x6, 0, 0, 0x50001},
+  {0x6, 0, 0, 0x7fff0000},
+  {0x6, 0, 0, 0x30001},
+};
+#elif defined(__aarch64__)
+struct sock_filter kTestSeccompFilter[] = {
+  {0x20, 0, 0, 0x4},
+  {0x15, 1, 0, 0xc00000b7},
+  {0x6, 0, 0, 0x30006},
+  {0x20, 0, 0, 0x0},
+  {0x35, 0, 51, 0x88},
+  {0x35, 0, 25, 0xba},
+  {0x35, 0, 12, 0xdf},
+  {0x35, 0, 6, 0xea},
+  {0x35, 0, 3, 0x104},
+  {0x35, 0, 1, 0x114},
+  {0x35, 86, 85, 0x116},
+  {0x35, 85, 81, 0x105},
+  {0x35, 0, 84, 0xf2},
+  {0x35, 83, 82, 0xf3},
+  {0x35, 0, 2, 0xe4},
+  {0x35, 0, 77, 0xe6},
+  {0x35, 92, 80, 0xe9},
+  {0x35, 0, 79, 0xe2},
+  {0x35, 78, 97, 0xe3},
+  {0x35, 0, 6, 0xd1},
+  {0x35, 0, 3, 0xd9},
+  {0x35, 0, 1, 0xdd},
+  {0x35, 100, 73, 0xde},
+  {0x35, 69, 73, 0xdc},
+  {0x35, 0, 68, 0xd5},
+  {0x35, 67, 71, 0xd6},
+  {0x35, 0, 2, 0xcc},
+  {0x35, 0, 69, 0xce},
+  {0x35, 68, 64, 0xd0},
+  {0x35, 0, 66, 0xc7},
+  {0x35, 65, 99, 0xc8},
+  {0x35, 0, 12, 0x9e},
+  {0x35, 0, 6, 0xa6},
+  {0x35, 0, 3, 0xa9},
+  {0x35, 0, 1, 0xac},
+  {0x35, 61, 57, 0xb3},
+  {0x35, 60, 56, 0xaa},
+  {0x35, 0, 58, 0xa7},
+  {0x35, 58, 98, 0xa8},
+  {0x35, 0, 2, 0xa1},
+  {0x35, 0, 56, 0xa3},
+  {0x35, 55, 51, 0xa4},
+  {0x35, 0, 50, 0x9f},
+  {0x35, 49, 52, 0xa0},
+  {0x35, 0, 6, 0x94},
+  {0x35, 0, 3, 0x97},
+  {0x35, 0, 1, 0x9c},
+  {0x35, 49, 45, 0x9d},
+  {0x35, 48, 47, 0x99},
+  {0x35, 0, 43, 0x95},
+  {0x35, 42, 45, 0x96},
+  {0x35, 0, 2, 0x8b},
+  {0x35, 0, 40, 0x8e},
+  {0x35, 42, 43, 0x8f},
+  {0x35, 0, 42, 0x89},
+  {0x35, 41, 37, 0x8a},
+  {0x35, 0, 25, 0x4e},
+  {0x35, 0, 12, 0x65},
+  {0x35, 0, 6, 0x80},
+  {0x35, 0, 3, 0x83},
+  {0x35, 0, 1, 0x85},
+  {0x35, 31, 35, 0x86},
+  {0x35, 30, 117, 0x84},
+  {0x35, 0, 29, 0x81},
+  {0x35, 122, 115, 0x82},
+  {0x35, 0, 2, 0x72},
+  {0x35, 0, 30, 0x7c},
+  {0x35, 29, 25, 0x7d},
+  {0x35, 0, 24, 0x66},
+  {0x35, 118, 27, 0x71},
+  {0x35, 0, 6, 0x5b},
+  {0x35, 0, 3, 0x61},
+  {0x35, 0, 1, 0x63},
+  {0x35, 23, 22, 0x64},
+  {0x35, 155, 22, 0x62},
+  {0x35, 0, 20, 0x5c},
+  {0x35, 16, 20, 0x5d},
+  {0x35, 0, 2, 0x58},
+  {0x35, 0, 17, 0x59},
+  {0x35, 13, 17, 0x5a},
+  {0x35, 0, 15, 0x4f},
+  {0x35, 15, 11, 0x51},
+  {0x35, 0, 15, 0x2c},
+  {0x35, 0, 6, 0x3b},
+  {0x35, 0, 3, 0x3e},
+  {0x35, 0, 1, 0x48},
+  {0x35, 10, 6, 0x4a},
+  {0x35, 9, 5, 0x44},
+  {0x35, 0, 4, 0x3c},
+  {0x35, 6, 7, 0x3d},
+  {0x35, 0, 3, 0x34},
+  {0x35, 0, 4, 0x38},
+  {0x35, 4, 0, 0x3a},
+  {0x5, 0, 0, 0x104},
+  {0x35, 0, 2, 0x2d},
+  {0x35, 1, 0, 0x33},
+  {0x5, 0, 0, 0x102},
+  {0x5, 0, 0, 0x102},
+  {0x35, 0, 5, 0x1d},
+  {0x35, 0, 2, 0x21},
+  {0x35, 0, 254, 0x27},
+  {0x35, 253, 254, 0x2b},
+  {0x35, 0, 251, 0x1e},
+  {0x35, 250, 252, 0x20},
+  {0x35, 0, 2, 0x14},
+  {0x35, 0, 248, 0x19},
+  {0x35, 249, 179, 0x1a},
+  {0x35, 0, 248, 0x11},
+  {0x35, 247, 246, 0x13},
+  {0x20, 0, 0, 0x24},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 235, 0xffffffff},
+  {0x20, 0, 0, 0x20},
+  {0x45, 0, 233, 0x80000000},
+  {0x20, 0, 0, 0x20},
+  {0x15, 238, 239, 0x4},
+  {0x20, 0, 0, 0x24},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 228, 0xffffffff},
+  {0x20, 0, 0, 0x20},
+  {0x45, 0, 226, 0x80000000},
+  {0x20, 0, 0, 0x20},
+  {0x45, 233, 231, 0xfffffff8},
+  {0x20, 0, 0, 0x2c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 221, 0xffffffff},
+  {0x20, 0, 0, 0x28},
+  {0x45, 0, 219, 0x80000000},
+  {0x20, 0, 0, 0x28},
+  {0x45, 226, 224, 0xfffdb7cc},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 214, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 212, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 217, 219, 0x1},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 207, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 205, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 210, 0, 0x10},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 200, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 198, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 203, 0, 0xf},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 193, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 191, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 196, 0, 0x3},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 186, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 184, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 189, 0, 0x4},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 179, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 177, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 182, 0, 0x53564d41},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 172, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 170, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 175, 0, 0x29},
+  {0x6, 0, 0, 0x30005},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 164, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 162, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 167, 0, 0x1393},
+  {0x6, 0, 0, 0x30004},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 156, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 154, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 159, 0, 0x1},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 149, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 147, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 152, 0, 0x6},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 142, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 140, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 145, 0, 0x2},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 135, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 133, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 138, 0, 0x0},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 128, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 126, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 131, 0, 0x5},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 121, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 119, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 124, 126, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 114, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 112, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 117, 0xfffffe7f},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 107, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 105, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 109, 0, 0x1},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 99, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 97, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 101, 0, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 91, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 89, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 93, 0, 0x4},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 83, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 81, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 85, 0, 0x5},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 75, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 73, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 77, 0, 0x9},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 67, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 65, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 69, 0, 0xa},
+  {0x6, 0, 0, 0x30003},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 58, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 56, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 61, 0, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 51, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 49, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 54, 0, 0x1},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 44, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 42, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 47, 0, 0x2},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 37, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 35, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 40, 0, 0x6},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 30, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 28, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 33, 0, 0x7},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 23, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 21, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 26, 0, 0x5},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 16, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 14, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 19, 0, 0x0},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 9, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 7, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 12, 0, 0x406},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 4, 0, 0x0},
+  {0x15, 0, 2, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 1, 0, 0x80000000},
+  {0x6, 0, 0, 0x30002},
+  {0x20, 0, 0, 0x18},
+  {0x15, 0, 6, 0x4},
+  {0x20, 0, 0, 0x24},
+  {0x15, 0, 4, 0x0},
+  {0x20, 0, 0, 0x20},
+  {0x45, 2, 0, 0xffe1e3fc},
+  {0x6, 0, 0, 0x7fff0000},
+  {0x6, 0, 0, 0x50001},
+  {0x6, 0, 0, 0x30001},
+};
+#elif defined(__i386__)
+struct sock_filter kTestSeccompFilter[] = {
+  {0x20, 0, 0, 0x4},
+  {0x15, 1, 0, 0x40000003},
+  {0x6, 0, 0, 0x30007},
+  {0x20, 0, 0, 0x0},
+  {0x45, 0, 1, 0x40000000},
+  {0x6, 0, 0, 0x30006},
+  {0x35, 0, 87, 0x94},
+  {0x35, 0, 43, 0xdd},
+  {0x35, 0, 20, 0x11c},
+  {0x35, 0, 10, 0x13f},
+  {0x35, 0, 5, 0x149},
+  {0x35, 0, 2, 0x163},
+  {0x35, 0, 79, 0x164},
+  {0x35, 78, 73, 0x165},
+  {0x35, 0, 78, 0x14c},
+  {0x35, 71, 76, 0x161},
+  {0x35, 0, 2, 0x141},
+  {0x35, 0, 74, 0x144},
+  {0x35, 73, 68, 0x145},
+  {0x35, 67, 73, 0x140},
+  {0x35, 0, 4, 0x12d},
+  {0x35, 0, 2, 0x136},
+  {0x35, 0, 69, 0x137},
+  {0x35, 68, 63, 0x138},
+  {0x35, 68, 62, 0x134},
+  {0x35, 0, 2, 0x127},
+  {0x35, 0, 66, 0x128},
+  {0x35, 65, 59, 0x12c},
+  {0x35, 63, 64, 0x11d},
+  {0x35, 0, 11, 0xfe},
+  {0x35, 0, 6, 0x10a},
+  {0x35, 0, 3, 0x10e},
+  {0x35, 1, 0, 0x10f},
+  {0x5, 0, 0, 0x135},
+  {0x35, 57, 52, 0x110},
+  {0x35, 0, 56, 0x10c},
+  {0x35, 55, 50, 0x10d},
+  {0x35, 0, 2, 0x102},
+  {0x35, 0, 54, 0x103},
+  {0x35, 135, 52, 0x109},
+  {0x35, 51, 52, 0x101},
+  {0x35, 0, 4, 0xef},
+  {0x35, 0, 2, 0xf1},
+  {0x35, 0, 48, 0xfc},
+  {0x35, 42, 48, 0xfd},
+  {0x35, 153, 46, 0xf0},
+  {0x35, 0, 3, 0xe0},
+  {0x35, 0, 45, 0xe1},
+  {0x35, 0, 43, 0xee},
+  {0x5, 0, 0, 0x12a},
+  {0x35, 41, 252, 0xde},
+  {0x35, 0, 20, 0xb6},
+  {0x35, 0, 10, 0xc7},
+  {0x35, 0, 5, 0xd2},
+  {0x35, 0, 2, 0xd9},
+  {0x35, 0, 36, 0xdb},
+  {0x35, 30, 177, 0xdc},
+  {0x35, 0, 29, 0xd3},
+  {0x35, 28, 34, 0xd4},
+  {0x35, 0, 2, 0xcd},
+  {0x35, 0, 32, 0xce},
+  {0x35, 31, 25, 0xd1},
+  {0x35, 24, 30, 0xcb},
+  {0x35, 0, 4, 0xbf},
+  {0x35, 0, 2, 0xc1},
+  {0x35, 0, 21, 0xc5},
+  {0x35, 20, 26, 0xc6},
+  {0x35, 231, 25, 0xc0},
+  {0x35, 0, 2, 0xb9},
+  {0x35, 0, 17, 0xba},
+  {0x35, 21, 22, 0xbb},
+  {0x35, 21, 15, 0xb8},
+  {0x35, 0, 9, 0xa9},
+  {0x35, 0, 4, 0xb0},
+  {0x35, 0, 2, 0xb2},
+  {0x35, 0, 16, 0xb4},
+  {0x35, 15, 16, 0xb5},
+  {0x35, 15, 14, 0xb1},
+  {0x35, 0, 2, 0xab},
+  {0x35, 0, 13, 0xac},
+  {0x35, 12, 157, 0xad},
+  {0x35, 5, 10, 0xaa},
+  {0x35, 0, 5, 0xa2},
+  {0x35, 0, 2, 0xa5},
+  {0x35, 0, 8, 0xa6},
+  {0x35, 7, 6, 0xa8},
+  {0x35, 0, 6, 0xa4},
+  {0x5, 0, 0, 0x105},
+  {0x35, 0, 2, 0x98},
+  {0x35, 0, 2, 0x9e},
+  {0x35, 1, 2, 0x9f},
+  {0x35, 1, 0, 0x96},
+  {0x5, 0, 0, 0x102},
+  {0x5, 0, 0, 0x100},
+  {0x35, 0, 40, 0x4f},
+  {0x35, 0, 20, 0x6e},
+  {0x35, 0, 10, 0x7d},
+  {0x35, 0, 5, 0x8a},
+  {0x35, 0, 2, 0x8e},
+  {0x35, 0, 250, 0x90},
+  {0x35, 249, 250, 0x91},
+  {0x35, 0, 247, 0x8c},
+  {0x35, 246, 247, 0x8d},
+  {0x35, 0, 2, 0x7f},
+  {0x35, 0, 246, 0x85},
+  {0x35, 245, 243, 0x86},
+  {0x35, 243, 156, 0x7e},
+  {0x35, 0, 4, 0x76},
+  {0x35, 0, 2, 0x79},
+  {0x35, 0, 241, 0x7a},
+  {0x35, 240, 239, 0x7c},
+  {0x35, 238, 239, 0x77},
+  {0x35, 0, 2, 0x72},
+  {0x35, 0, 236, 0x73},
+  {0x35, 234, 236, 0x75},
+  {0x35, 235, 233, 0x6f},
+  {0x35, 0, 9, 0x60},
+  {0x35, 0, 4, 0x66},
+  {0x35, 0, 2, 0x6a},
+  {0x35, 0, 229, 0x6c},
+  {0x35, 230, 229, 0x6d},
+  {0x35, 229, 145, 0x67},
+  {0x35, 0, 2, 0x63},
+  {0x35, 0, 225, 0x64},
+  {0x35, 224, 226, 0x65},
+  {0x35, 225, 224, 0x62},
+  {0x35, 0, 4, 0x57},
+  {0x35, 0, 2, 0x5a},
+  {0x35, 0, 170, 0x5b},
+  {0x35, 219, 220, 0x5c},
+  {0x35, 218, 220, 0x59},
+  {0x35, 0, 2, 0x51},
+  {0x35, 0, 216, 0x52},
+  {0x35, 215, 216, 0x53},
+  {0x35, 215, 216, 0x50},
+  {0x35, 0, 20, 0x29},
+  {0x35, 0, 10, 0x38},
+  {0x35, 0, 5, 0x41},
+  {0x35, 0, 2, 0x46},
+  {0x35, 0, 209, 0x48},
+  {0x35, 209, 210, 0x4e},
+  {0x35, 0, 209, 0x43},
+  {0x35, 208, 207, 0x44},
+  {0x35, 0, 2, 0x3d},
+  {0x35, 0, 206, 0x3e},
+  {0x35, 204, 203, 0x3f},
+  {0x35, 202, 204, 0x3c},
+  {0x35, 0, 4, 0x30},
+  {0x35, 0, 2, 0x33},
+  {0x35, 0, 201, 0x36},
+  {0x35, 152, 199, 0x37},
+  {0x35, 198, 199, 0x31},
+  {0x35, 0, 2, 0x2d},
+  {0x35, 0, 196, 0x2e},
+  {0x35, 195, 194, 0x2f},
+  {0x35, 195, 194, 0x2b},
+  {0x35, 0, 9, 0x17},
+  {0x35, 0, 4, 0x1f},
+  {0x35, 0, 2, 0x22},
+  {0x35, 0, 191, 0x25},
+  {0x35, 188, 182, 0x26},
+  {0x35, 187, 189, 0x21},
+  {0x35, 0, 2, 0x19},
+  {0x35, 0, 187, 0x1d},
+  {0x35, 184, 185, 0x1e},
+  {0x35, 184, 183, 0x18},
+  {0x35, 0, 4, 0xe},
+  {0x35, 0, 2, 0x12},
+  {0x35, 0, 180, 0x13},
+  {0x35, 181, 180, 0x15},
+  {0x35, 180, 178, 0x11},
+  {0x35, 0, 2, 0x3},
+  {0x35, 0, 177, 0x8},
+  {0x35, 176, 175, 0xd},
+  {0x35, 174, 175, 0x2},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 168, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 171, 0, 0x1},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 164, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 167, 0, 0x6},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 160, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 163, 0, 0x2},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 156, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 159, 0, 0x0},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 152, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 155, 0, 0x5},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 148, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 151, 152, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 144, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 147, 0xfffffe7f},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 140, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 142, 0, 0x1},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 135, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 137, 0, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 130, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 132, 0, 0x4},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 125, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 127, 0, 0x5},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 120, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 122, 0, 0x9},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 115, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 117, 0, 0xa},
+  {0x6, 0, 0, 0x30005},
+  {0x20, 0, 0, 0x24},
+  {0x15, 0, 109, 0x0},
+  {0x20, 0, 0, 0x20},
+  {0x15, 112, 111, 0x4},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 105, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 108, 0, 0x10},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 101, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 104, 0, 0xf},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 97, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 100, 0, 0x3},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 93, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 96, 0, 0x4},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 89, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 92, 0, 0x53564d41},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 85, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 88, 0, 0x29},
+  {0x6, 0, 0, 0x30004},
+  {0x20, 0, 0, 0x24},
+  {0x15, 0, 80, 0x0},
+  {0x20, 0, 0, 0x20},
+  {0x45, 84, 83, 0xfffffff8},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 76, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 79, 0, 0x8},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 72, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 75, 0, 0xd},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 68, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 71, 0, 0xa},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 64, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 67, 0, 0x9},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 60, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 63, 0, 0xc},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 56, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 59, 0, 0xb},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 52, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 55, 0, 0x11},
+  {0x20, 0, 0, 0x14},
+  {0x15, 0, 48, 0x0},
+  {0x20, 0, 0, 0x10},
+  {0x15, 51, 50, 0x10},
+  {0x20, 0, 0, 0x2c},
+  {0x15, 0, 44, 0x0},
+  {0x20, 0, 0, 0x28},
+  {0x45, 48, 47, 0xfffdb7cc},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 40, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 43, 0, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 36, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 39, 0, 0x1},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 32, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 35, 0, 0x2},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 28, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 31, 0, 0x6},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 24, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 27, 0, 0x7},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 20, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 23, 0, 0x5},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 16, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 19, 0, 0x0},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 12, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 15, 0, 0x406},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 0, 8, 0x0},
+  {0x20, 0, 0, 0x18},
+  {0x15, 0, 12, 0x4},
+  {0x20, 0, 0, 0x24},
+  {0x15, 0, 4, 0x0},
+  {0x20, 0, 0, 0x20},
+  {0x45, 8, 7, 0xfff363fc},
+  {0x20, 0, 0, 0x14},
+  {0x15, 1, 0, 0x0},
+  {0x6, 0, 0, 0x30003},
+  {0x20, 0, 0, 0x10},
+  {0x15, 2, 0, 0x9d0},
+  {0x6, 0, 0, 0x30002},
+  {0x6, 0, 0, 0x50001},
+  {0x6, 0, 0, 0x7fff0000},
+  {0x6, 0, 0, 0x30001},
+};
+#elif defined(__x86_64__)
+struct sock_filter kTestSeccompFilter[] = {
+  {0x20, 0, 0, 0x4},
+  {0x15, 1, 0, 0xc000003e},
+  {0x6, 0, 0, 0x30007},
+  {0x20, 0, 0, 0x0},
+  {0x45, 0, 1, 0x40000000},
+  {0x6, 0, 0, 0x30006},
+  {0x35, 0, 59, 0x7f},
+  {0x35, 0, 29, 0xe4},
+  {0x35, 0, 14, 0x111},
+  {0x35, 0, 7, 0x120},
+  {0x35, 0, 3, 0x13c},
+  {0x35, 0, 1, 0x13f},
+  {0x35, 102, 95, 0x140},
+  {0x35, 101, 94, 0x13e},
+  {0x35, 0, 1, 0x123},
+  {0x35, 99, 94, 0x126},
+  {0x35, 98, 91, 0x121},
+  {0x35, 0, 3, 0x119},
+  {0x35, 0, 1, 0x11d},
+  {0x35, 95, 88, 0x11e},
+  {0x35, 94, 89, 0x11a},
+  {0x35, 0, 86, 0x112},
+  {0x35, 85, 92, 0x118},
+  {0x35, 0, 6, 0xf8},
+  {0x35, 0, 3, 0x106},
+  {0x35, 0, 1, 0x10e},
+  {0x35, 88, 83, 0x110},
+  {0x35, 80, 82, 0x107},
+  {0x35, 0, 86, 0x101},
+  {0x35, 78, 80, 0x102},
+  {0x35, 0, 4, 0xea},
+  {0x35, 0, 1, 0xec},
+  {0x35, 77, 82, 0xf7},
+  {0x35, 74, 0, 0xeb},
+  {0x5, 0, 0, 0x12a},
+  {0x35, 0, 89, 0xe5},
+  {0x35, 73, 78, 0xe7},
+  {0x35, 0, 15, 0xac},
+  {0x35, 0, 7, 0xcb},
+  {0x35, 0, 3, 0xd9},
+  {0x35, 0, 1, 0xdc},
+  {0x35, 73, 66, 0xdd},
+  {0x35, 67, 65, 0xda},
+  {0x35, 0, 1, 0xd5},
+  {0x35, 70, 65, 0xd6},
+  {0x35, 62, 69, 0xd4},
+  {0x35, 0, 4, 0xbb},
+  {0x35, 0, 1, 0xc9},
+  {0x35, 118, 61, 0xca},
+  {0x35, 0, 65, 0xc8},
+  {0x5, 0, 0, 0x121},
+  {0x35, 0, 56, 0xae},
+  {0x35, 57, 62, 0xba},
+  {0x35, 0, 6, 0x8a},
+  {0x35, 0, 3, 0x95},
+  {0x35, 0, 1, 0x9d},
+  {0x35, 58, 166, 0x9e},
+  {0x35, 57, 52, 0x97},
+  {0x35, 0, 56, 0x8c},
+  {0x35, 55, 50, 0x8e},
+  {0x35, 0, 3, 0x83},
+  {0x35, 0, 1, 0x87},
+  {0x35, 45, 52, 0x88},
+  {0x35, 44, 46, 0x84},
+  {0x35, 0, 50, 0x80},
+  {0x35, 49, 44, 0x81},
+  {0x35, 0, 28, 0x3b},
+  {0x35, 0, 14, 0x69},
+  {0x35, 0, 7, 0x74},
+  {0x35, 0, 3, 0x79},
+  {0x35, 0, 1, 0x7c},
+  {0x35, 36, 38, 0x7e},
+  {0x35, 35, 42, 0x7a},
+  {0x35, 0, 1, 0x77},
+  {0x35, 35, 33, 0x78},
+  {0x35, 34, 32, 0x76},
+  {0x35, 0, 3, 0x6e},
+  {0x35, 0, 1, 0x71},
+  {0x35, 31, 29, 0x73},
+  {0x35, 35, 30, 0x6f},
+  {0x35, 0, 27, 0x6b},
+  {0x35, 33, 28, 0x6d},
+  {0x35, 0, 6, 0x4a},
+  {0x35, 0, 3, 0x62},
+  {0x35, 0, 1, 0x67},
+  {0x35, 24, 29, 0x68},
+  {0x35, 23, 28, 0x66},
+  {0x35, 0, 27, 0x4c},
+  {0x35, 21, 19, 0x60},
+  {0x35, 0, 3, 0x3f},
+  {0x35, 0, 1, 0x48},
+  {0x35, 18, 174, 0x49},
+  {0x35, 15, 17, 0x40},
+  {0x35, 0, 14, 0x3c},
+  {0x35, 238, 15, 0x3e},
+  {0x35, 0, 15, 0x1d},
+  {0x35, 0, 6, 0x31},
+  {0x35, 0, 3, 0x36},
+  {0x35, 0, 1, 0x39},
+  {0x35, 15, 8, 0x3a},
+  {0x35, 9, 14, 0x37},
+  {0x35, 0, 6, 0x33},
+  {0x35, 238, 12, 0x35},
+  {0x35, 0, 3, 0x27},
+  {0x35, 0, 1, 0x29},
+  {0x35, 4, 2, 0x2c},
+  {0x35, 8, 3, 0x28},
+  {0x35, 1, 0, 0x20},
+  {0x5, 0, 0, 0x105},
+  {0x35, 5, 0, 0x24},
+  {0x5, 0, 0, 0x104},
+  {0x35, 0, 7, 0xb},
+  {0x35, 0, 4, 0x15},
+  {0x35, 0, 2, 0x1a},
+  {0x35, 233, 0, 0x1c},
+  {0x5, 0, 0, 0x100},
+  {0x35, 254, 253, 0x16},
+  {0x35, 0, 253, 0x12},
+  {0x35, 252, 253, 0x13},
+  {0x35, 0, 3, 0x6},
+  {0x35, 0, 1, 0x9},
+  {0x35, 233, 240, 0xa},
+  {0x35, 248, 247, 0x7},
+  {0x35, 0, 247, 0x4},
+  {0x35, 246, 245, 0x5},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 239, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 237, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 239, 0, 0x1},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 232, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 230, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 232, 0, 0x6},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 225, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 223, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 225, 0, 0x2},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 218, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 216, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 218, 0, 0x0},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 211, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 209, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 211, 0, 0x5},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 204, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 202, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 204, 205, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 197, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 195, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 197, 0xfffffe7f},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 190, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 188, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 189, 0, 0x1},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 182, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 180, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 181, 0, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 174, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 172, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 173, 0, 0x4},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 166, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 164, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 165, 0, 0x5},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 158, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 156, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 157, 0, 0x9},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 150, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 148, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x54, 0, 0, 0xfffffe7f},
+  {0x15, 149, 0, 0xa},
+  {0x6, 0, 0, 0x30005},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 141, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 139, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 141, 0, 0x10},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 134, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 132, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 134, 0, 0xf},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 127, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 125, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 127, 0, 0x3},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 120, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 118, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 120, 0, 0x4},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 113, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 111, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 113, 0, 0x53564d41},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 106, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 104, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 106, 0, 0x29},
+  {0x6, 0, 0, 0x30004},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 98, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 96, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 98, 0, 0x3},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 91, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 89, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 91, 0, 0x1},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 84, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 82, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 84, 0, 0x2},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 77, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 75, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 77, 0, 0x6},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 70, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 68, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 70, 0, 0x7},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 63, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 61, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 63, 0, 0x5},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 56, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 54, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 56, 0, 0x0},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 49, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 47, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 49, 0, 0x406},
+  {0x20, 0, 0, 0x1c},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 42, 0xffffffff},
+  {0x20, 0, 0, 0x18},
+  {0x45, 0, 40, 0x80000000},
+  {0x20, 0, 0, 0x18},
+  {0x15, 0, 43, 0x4},
+  {0x20, 0, 0, 0x24},
+  {0x15, 0, 41, 0x0},
+  {0x20, 0, 0, 0x20},
+  {0x45, 39, 38, 0xffe363fc},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 31, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 29, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 31, 0, 0xa57},
+  {0x6, 0, 0, 0x30003},
+  {0x20, 0, 0, 0x14},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 23, 0xffffffff},
+  {0x20, 0, 0, 0x10},
+  {0x45, 0, 21, 0x80000000},
+  {0x20, 0, 0, 0x10},
+  {0x15, 23, 24, 0x1},
+  {0x20, 0, 0, 0x24},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 16, 0xffffffff},
+  {0x20, 0, 0, 0x20},
+  {0x45, 0, 14, 0x80000000},
+  {0x20, 0, 0, 0x20},
+  {0x15, 16, 15, 0x4},
+  {0x20, 0, 0, 0x24},
+  {0x15, 3, 0, 0x0},
+  {0x15, 0, 9, 0xffffffff},
+  {0x20, 0, 0, 0x20},
+  {0x45, 0, 7, 0x80000000},
+  {0x20, 0, 0, 0x20},
+  {0x45, 10, 9, 0xfffffff8},
+  {0x20, 0, 0, 0x2c},
+  {0x15, 4, 0, 0x0},
+  {0x15, 0, 2, 0xffffffff},
+  {0x20, 0, 0, 0x28},
+  {0x45, 1, 0, 0x80000000},
+  {0x6, 0, 0, 0x30002},
+  {0x20, 0, 0, 0x28},
+  {0x45, 2, 1, 0xfffdb7cc},
+  {0x6, 0, 0, 0x50001},
+  {0x6, 0, 0, 0x7fff0000},
+  {0x6, 0, 0, 0x30001},
+};
+#endif
+
+struct sock_fprog GetTestSeccompFilterProgram() {
+  struct sock_fprog prog = {
+    .len = sizeof(kTestSeccompFilter) / sizeof(struct sock_filter),
+    .filter = kTestSeccompFilter
+  };
+  return prog;
+}
diff --git a/tests/tests/os/jni/seccomp_sample_program.h b/tests/tests/os/jni/seccomp_sample_program.h
new file mode 100644
index 0000000..1293572
--- /dev/null
+++ b/tests/tests/os/jni/seccomp_sample_program.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <linux/filter.h>
+
+struct sock_fprog GetTestSeccompFilterProgram();
diff --git a/tests/tests/os/src/android/os/cts/BuildVersionTest.java b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
index 419f320..75ad865 100644
--- a/tests/tests/os/src/android/os/cts/BuildVersionTest.java
+++ b/tests/tests/os/src/android/os/cts/BuildVersionTest.java
@@ -29,8 +29,8 @@
 
     private static final String LOG_TAG = "BuildVersionTest";
     private static final Set<String> EXPECTED_RELEASES =
-            new HashSet<String>(Arrays.asList("5.1", "5.1.1"));
-    private static final int EXPECTED_SDK = 22;
+            new HashSet<String>(Arrays.asList("6.0.1", "6.0"));
+    private static final int EXPECTED_SDK = 23;
     private static final String EXPECTED_BUILD_VARIANT = "user";
     private static final String EXPECTED_TAG = "release-keys";
 
diff --git a/tests/tests/os/src/android/os/cts/CpuFeaturesTest.java b/tests/tests/os/src/android/os/cts/CpuFeaturesTest.java
index 0b389a4..d8e128b 100644
--- a/tests/tests/os/src/android/os/cts/CpuFeaturesTest.java
+++ b/tests/tests/os/src/android/os/cts/CpuFeaturesTest.java
@@ -82,8 +82,8 @@
     }
 
     private static final String[] armv8RequiredFeatures = {
-            "wp", "half", "thumb", "fastmult", "vfp", "edsp", "neon",
-            "vfpv3", "tlsi", "vfpv4", "idiva", "idivt" };
+            "half", "thumb", "fastmult", "vfp", "edsp", "neon",
+            "vfpv3", "vfpv4", "idiva", "idivt" };
 
     private static void assertInCpuinfo(List<String> features,
             String feature) {
diff --git a/tests/tests/os/src/android/os/cts/DebugTest.java b/tests/tests/os/src/android/os/cts/DebugTest.java
index c097240..8301cfc 100644
--- a/tests/tests/os/src/android/os/cts/DebugTest.java
+++ b/tests/tests/os/src/android/os/cts/DebugTest.java
@@ -20,6 +20,7 @@
 import java.io.IOException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.Map;
 
 import android.content.Context;
 import android.cts.util.TestThread;
@@ -219,4 +220,133 @@
         assertTrue(file.exists());
         assertTrue(file.length() > 0);
     }
+
+    private static void checkNumber(String s) throws Exception {
+        assertTrue(s != null);
+        long n = Long.valueOf(s);
+        assertTrue(n >= 0);
+    }
+
+    private static void checkHistogram(String s) throws Exception {
+        assertTrue(s != null);
+        assertTrue(s.length() > 0);
+        String[] buckets = s.split(",");
+        long last_key = 0;
+        for (int i = 0; i < buckets.length; ++i) {
+            String bucket = buckets[i];
+            assertTrue(bucket.length() > 0);
+            String[] kv = bucket.split(":");
+            assertTrue(kv.length == 2);
+            assertTrue(kv[0].length() > 0);
+            assertTrue(kv[1].length() > 0);
+            long key = Long.valueOf(kv[0]);
+            long value = Long.valueOf(kv[1]);
+            assertTrue(key >= 0);
+            assertTrue(value >= 0);
+            assertTrue(key >= last_key);
+            last_key = key;
+        }
+    }
+
+    public void testGetRuntimeStat() throws Exception {
+        // Invoke at least one GC and wait for 20 seconds or so so we get at
+        // least one bucket in the histograms.
+        for (int i = 0; i < 20; ++i) {
+            Runtime.getRuntime().gc();
+            Thread.sleep(1000L);
+        }
+        String gc_count = Debug.getRuntimeStat("art.gc.gc-count");
+        String gc_time = Debug.getRuntimeStat("art.gc.gc-time");
+        String bytes_allocated = Debug.getRuntimeStat("art.gc.bytes-allocated");
+        String bytes_freed = Debug.getRuntimeStat("art.gc.bytes-freed");
+        String blocking_gc_count = Debug.getRuntimeStat("art.gc.blocking-gc-count");
+        String blocking_gc_time = Debug.getRuntimeStat("art.gc.blocking-gc-time");
+        String gc_count_rate_histogram = Debug.getRuntimeStat("art.gc.gc-count-rate-histogram");
+        String blocking_gc_count_rate_histogram =
+            Debug.getRuntimeStat("art.gc.blocking-gc-count-rate-histogram");
+        checkNumber(gc_count);
+        checkNumber(gc_time);
+        checkNumber(bytes_allocated);
+        checkNumber(bytes_freed);
+        checkNumber(blocking_gc_count);
+        checkNumber(blocking_gc_time);
+        checkHistogram(gc_count_rate_histogram);
+        checkHistogram(blocking_gc_count_rate_histogram);
+    }
+
+    public void testGetRuntimeStats() throws Exception {
+        // Invoke at least one GC and wait for 20 seconds or so so we get at
+        // least one bucket in the histograms.
+        for (int i = 0; i < 20; ++i) {
+            Runtime.getRuntime().gc();
+            Thread.sleep(1000L);
+        }
+        Map<String, String> map = Debug.getRuntimeStats();
+        String gc_count = map.get("art.gc.gc-count");
+        String gc_time = map.get("art.gc.gc-time");
+        String bytes_allocated = map.get("art.gc.bytes-allocated");
+        String bytes_freed = map.get("art.gc.bytes-freed");
+        String blocking_gc_count = map.get("art.gc.blocking-gc-count");
+        String blocking_gc_time = map.get("art.gc.blocking-gc-time");
+        String gc_count_rate_histogram = map.get("art.gc.gc-count-rate-histogram");
+        String blocking_gc_count_rate_histogram =
+            map.get("art.gc.blocking-gc-count-rate-histogram");
+        checkNumber(gc_count);
+        checkNumber(gc_time);
+        checkNumber(bytes_allocated);
+        checkNumber(bytes_freed);
+        checkNumber(blocking_gc_count);
+        checkNumber(blocking_gc_time);
+        checkHistogram(gc_count_rate_histogram);
+        checkHistogram(blocking_gc_count_rate_histogram);
+    }
+
+    public void testGetMemoryStat() throws Exception {
+        Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
+        Debug.getMemoryInfo(memoryInfo);
+
+        String summary_java_heap = memoryInfo.getMemoryStat("summary.java-heap");
+        String summary_native_heap = memoryInfo.getMemoryStat("summary.native-heap");
+        String summary_code = memoryInfo.getMemoryStat("summary.code");
+        String summary_stack = memoryInfo.getMemoryStat("summary.stack");
+        String summary_graphics = memoryInfo.getMemoryStat("summary.graphics");
+        String summary_private_other = memoryInfo.getMemoryStat("summary.private-other");
+        String summary_system = memoryInfo.getMemoryStat("summary.system");
+        String summary_total_pss = memoryInfo.getMemoryStat("summary.total-pss");
+        String summary_total_swap = memoryInfo.getMemoryStat("summary.total-swap");
+        checkNumber(summary_java_heap);
+        checkNumber(summary_native_heap);
+        checkNumber(summary_code);
+        checkNumber(summary_stack);
+        checkNumber(summary_graphics);
+        checkNumber(summary_private_other);
+        checkNumber(summary_system);
+        checkNumber(summary_total_pss);
+        checkNumber(summary_total_swap);
+    }
+
+    public void testGetMemoryStats() throws Exception {
+        Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
+        Debug.getMemoryInfo(memoryInfo);
+
+        Map<String, String> map = memoryInfo.getMemoryStats();
+        String summary_java_heap = map.get("summary.java-heap");
+        String summary_native_heap = map.get("summary.native-heap");
+        String summary_code = map.get("summary.code");
+        String summary_stack = map.get("summary.stack");
+        String summary_graphics = map.get("summary.graphics");
+        String summary_private_other = map.get("summary.private-other");
+        String summary_system = map.get("summary.system");
+        String summary_total_pss = map.get("summary.total-pss");
+        String summary_total_swap = map.get("summary.total-swap");
+        checkNumber(summary_java_heap);
+        checkNumber(summary_native_heap);
+        checkNumber(summary_code);
+        checkNumber(summary_stack);
+        checkNumber(summary_graphics);
+        checkNumber(summary_private_other);
+        checkNumber(summary_system);
+        checkNumber(summary_total_pss);
+        checkNumber(summary_total_swap);
+    }
 }
diff --git a/tests/tests/os/src/android/os/cts/HardwareName.java b/tests/tests/os/src/android/os/cts/HardwareName.java
new file mode 100644
index 0000000..7ee80e6
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/HardwareName.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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;
+
+public class HardwareName {
+
+    static {
+        System.loadLibrary("ctsos_jni");
+    }
+
+    public static native String getName();
+}
diff --git a/tests/tests/os/src/android/os/cts/HardwareNameTest.java b/tests/tests/os/src/android/os/cts/HardwareNameTest.java
new file mode 100644
index 0000000..7a754d1
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/HardwareNameTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 android.test.AndroidTestCase;
+import android.os.cts.HardwareName;
+
+public class HardwareNameTest extends AndroidTestCase {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    public void testHardwareNameIsSet() {
+        String name = HardwareName.getName();
+        assertNotNull("androidboot.hardware must be passed on the kernel command line", name);
+    }
+}
diff --git a/tests/tests/os/src/android/os/cts/ISeccompIsolatedService.aidl b/tests/tests/os/src/android/os/cts/ISeccompIsolatedService.aidl
new file mode 100644
index 0000000..5234eff
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/ISeccompIsolatedService.aidl
@@ -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.os.cts;
+
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+
+interface ISeccompIsolatedService {
+    boolean installFilter();
+
+    boolean createThread();
+
+    boolean getSystemInfo();
+
+    boolean writeToFile(in ParcelFileDescriptor fd);
+
+    boolean openAshmem();
+
+    boolean openDevFile();
+
+    void violatePolicy();
+}
diff --git a/tests/tests/os/src/android/os/cts/LooperTest.java b/tests/tests/os/src/android/os/cts/LooperTest.java
index 79a55c6..6f7cb6d 100644
--- a/tests/tests/os/src/android/os/cts/LooperTest.java
+++ b/tests/tests/os/src/android/os/cts/LooperTest.java
@@ -78,6 +78,21 @@
         t.runTest(WAIT_TIME);
     }
 
+    public void testIsCurrentThread() throws Throwable {
+        final Looper[] looper = new Looper[1];
+        TestThread t = new TestThread(new Runnable() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                assertTrue(Looper.myLooper().isCurrentThread());
+                looper[0] = Looper.myLooper();
+            }
+        });
+
+        t.runTest(WAIT_TIME);
+        assertFalse(looper[0].isCurrentThread());
+    }
+
     public void testMyQueue() throws Throwable {
         TestThread t = new TestThread(new Runnable() {
             public void run() {
@@ -96,6 +111,18 @@
         t.runTest(WAIT_TIME);
     }
 
+    public void testGetQueue() throws Throwable {
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+                assertNotNull(Looper.myLooper().getQueue());
+                assertEquals(Looper.myLooper().getQueue(), Looper.myQueue());
+            }
+        });
+
+        t.runTest(WAIT_TIME);
+    }
+
     public void testPrepare() throws Throwable {
         TestThread t = new TestThread(new Runnable() {
             public void run() {
diff --git a/tests/tests/os/src/android/os/cts/MessageQueueTest.java b/tests/tests/os/src/android/os/cts/MessageQueueTest.java
index 5b5bf5c..0c051bf 100644
--- a/tests/tests/os/src/android/os/cts/MessageQueueTest.java
+++ b/tests/tests/os/src/android/os/cts/MessageQueueTest.java
@@ -16,16 +16,25 @@
 
 package android.os.cts;
 
-
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
 import android.os.MessageQueue;
+import android.os.MessageQueue.OnFileDescriptorEventListener;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.AutoCloseInputStream;
+import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
+import android.system.ErrnoException;
+import android.system.Os;
 import android.os.SystemClock;
 import android.os.MessageQueue.IdleHandler;
 import android.test.AndroidTestCase;
 
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -59,7 +68,7 @@
         }
     }
 
-    private enum Test {ADD_IDLE_HANDLER, REMOVE_IDLE_HANDLER};
+    private enum Test {ADD_IDLE_HANDLER, REMOVE_IDLE_HANDLER}
 
     /**
      * {@link HandlerThread} that adds or removes an idle handler depending on the {@link Test}
@@ -84,6 +93,7 @@
             super.onLooperPrepared();
 
             IdleHandler idleHandler = new IdleHandler() {
+                @Override
                 public boolean queueIdle() {
                     mIdleLatch.countDown();
                     return false;
@@ -113,12 +123,55 @@
         }
     }
 
+    public void testIsIdle() throws Exception {
+        HandlerThread thread = new HandlerThread("testIsIdle");
+        thread.start();
+        try {
+            // Queue should initially be idle.
+            assertTrue(thread.getLooper().getQueue().isIdle());
+
+            // Post two messages.  Block in the first one leaving the second one pending.
+            final CountDownLatch latch1 = new CountDownLatch(1);
+            final CountDownLatch latch2 = new CountDownLatch(1);
+            Handler handler = new Handler(thread.getLooper());
+            handler.post(new Runnable() {
+                @Override
+                public void run() {
+                    // Wait for latch1 released before returning.
+                    try {
+                        latch1.await(TIMEOUT, TimeUnit.MILLISECONDS);
+                    } catch (InterruptedException ex) { }
+                }
+            });
+            handler.post(new Runnable() {
+                @Override
+                public void run() {
+                    // Release latch2 when finished.
+                    latch2.countDown();
+                }
+            });
+
+            // The first message is blocked so the second should still be in the queue.
+            // At this point the queue will not be idle because there is a pending message.
+            assertFalse(thread.getLooper().getQueue().isIdle());
+
+            // Let the first message complete and wait for the second to leave the queue.
+            // At this point the queue will be idle because it is empty.
+            latch1.countDown();
+            latch2.await(TIMEOUT, TimeUnit.MILLISECONDS);
+            assertTrue(thread.getLooper().getQueue().isIdle());
+        } finally {
+            thread.quitSafely();
+        }
+    }
+
     /**
      * Use MessageQueue, send message by order
      */
     public void testMessageOrder() throws Exception {
 
         OrderTestHelper tester = new OrderTestHelper() {
+            @Override
             public void init() {
                 super.init();
                 long now = SystemClock.uptimeMillis() + 200;
@@ -142,6 +195,7 @@
 
         OrderTestHelper tester = new OrderTestHelper() {
 
+            @Override
             public void init() {
                 super.init();
                 long now = SystemClock.uptimeMillis() + 200;
@@ -151,6 +205,7 @@
                 mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(0));
             }
 
+            @Override
             public void handleMessage(Message msg) {
                 super.handleMessage(msg);
                 if (msg.what == 0) {
@@ -162,16 +217,515 @@
         tester.doTest(1000, 50);
     }
 
+    public void testRegisterFileDescriptorCallbackThrowsWhenFdIsNull() {
+        MessageQueue queue = Looper.getMainLooper().getQueue();
+        try {
+            queue.addOnFileDescriptorEventListener(null, 0,
+                    new OnFileDescriptorEventListener() {
+                @Override
+                public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                    return 0;
+                }
+            });
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException ex) {
+            // expected
+        }
+    }
+
+    public void testRegisterFileDescriptorCallbackThrowsWhenCallbackIsNull() throws Exception {
+        MessageQueue queue = Looper.getMainLooper().getQueue();
+        ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+        try (ParcelFileDescriptor reader = pipe[0];
+                ParcelFileDescriptor writer = pipe[1]) {
+            try {
+                queue.addOnFileDescriptorEventListener(reader.getFileDescriptor(), 0, null);
+                fail("Expected IllegalArgumentException");
+            } catch (IllegalArgumentException ex) {
+                // expected
+            }
+        }
+    }
+
+    public void testUnregisterFileDescriptorCallbackThrowsWhenFdIsNull() throws Exception {
+        MessageQueue queue = Looper.getMainLooper().getQueue();
+        try {
+            queue.removeOnFileDescriptorEventListener(null);
+            fail("Expected IllegalArgumentException");
+        } catch (IllegalArgumentException ex) {
+            // expected
+        }
+    }
+
+    public void testUnregisterFileDescriptorCallbackDoesNothingWhenFdNotRegistered()
+            throws Exception {
+        MessageQueue queue = Looper.getMainLooper().getQueue();
+        ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+        try (ParcelFileDescriptor reader = pipe[0];
+                ParcelFileDescriptor writer = pipe[1]) {
+            queue.removeOnFileDescriptorEventListener(reader.getFileDescriptor());
+        }
+    }
+
+    public void testFileDescriptorCallbacks() throws Throwable {
+        // Prepare a special looper that we can catch exceptions from.
+        AssertableHandlerThread thread = new AssertableHandlerThread();
+        thread.start();
+        try {
+            final CountDownLatch writerSawError = new CountDownLatch(1);
+            final CountDownLatch readerDone = new CountDownLatch(1);
+            final MessageQueue queue = thread.getLooper().getQueue();
+            final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+            try (final FileInputStream reader = new AutoCloseInputStream(pipe[0]);
+                    final FileOutputStream writer = new AutoCloseOutputStream(pipe[1])) {
+                final int size = 256 * 1024;
+
+                // Prepare to write a lot of data to the pipe asynchronously.
+                // We don't actually care about the content (assume pipes work correctly)
+                // so we just write lots of zeros.
+                OnFileDescriptorEventListener writerCallback = new OnFileDescriptorEventListener() {
+                    private byte[] mBuffer = new byte[4096];
+                    private int mRemaining = size;
+                    private boolean mDone;
+
+                    @Override
+                    public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                        assertEquals(pipe[1].getFileDescriptor(), fd);
+                        if (!mDone) {
+                            // When an error happens because the reader closed its end,
+                            // signal the test, and remove the callback.
+                            if ((events & OnFileDescriptorEventListener.EVENT_ERROR) != 0) {
+                                writerSawError.countDown();
+                                mDone = true;
+                                return 0;
+                            }
+
+                            // Write all output until an error is observed.
+                            if ((events & OnFileDescriptorEventListener.EVENT_OUTPUT) != 0) {
+                                int count = Math.min(mBuffer.length, mRemaining);
+                                try {
+                                    writer.write(mBuffer, 0, count);
+                                } catch (IOException ex) {
+                                    throw new RuntimeException(ex);
+                                }
+                                mRemaining -= count;
+                                return mRemaining != 0 ? EVENT_OUTPUT : EVENT_ERROR;
+                            }
+                        }
+
+                        // Should never see anything else.
+                        fail("Saw unexpected events: " + events + ", mDone=" + mDone);
+                        return 0;
+                    }
+                };
+
+                // Prepare to read all of that data.
+                OnFileDescriptorEventListener readerCallback = new OnFileDescriptorEventListener() {
+                    private byte[] mBuffer = new byte[4096];
+                    private int mRemaining = size;
+                    private boolean mDone;
+
+                    @Override
+                    public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                        assertEquals(pipe[0].getFileDescriptor(), fd);
+                        if (!mDone) {
+                            // Errors should not happen.
+                            if ((events & OnFileDescriptorEventListener.EVENT_ERROR) != 0) {
+                                fail("Saw unexpected error.");
+                                return 0;
+                            }
+
+                            // Read until everything is read, signal the test,
+                            // and remove the callback.
+                            if ((events & OnFileDescriptorEventListener.EVENT_INPUT) != 0) {
+                                try {
+                                    int count = reader.read(mBuffer, 0, mBuffer.length);
+                                    mRemaining -= count;
+                                } catch (IOException ex) {
+                                    throw new RuntimeException(ex);
+                                }
+                                if (mRemaining != 0) {
+                                    return EVENT_INPUT;
+                                }
+                                readerDone.countDown();
+                                mDone = true;
+                                return 0;
+                            }
+                        }
+
+                        // Should never see anything else.
+                        fail("Saw unexpected events: " + events + ", mDone=" + mDone);
+                        return 0;
+                    }
+                };
+
+                // Register the callbacks.
+                queue.addOnFileDescriptorEventListener(reader.getFD(),
+                        OnFileDescriptorEventListener.EVENT_INPUT, readerCallback);
+                queue.addOnFileDescriptorEventListener(writer.getFD(),
+                        OnFileDescriptorEventListener.EVENT_OUTPUT, writerCallback);
+
+                // Wait for the reader to see all of the data that the writer
+                // is prepared to send.
+                readerDone.await(TIMEOUT, TimeUnit.MILLISECONDS);
+
+                // At this point the reader's callback should be unregistered.
+                // Close the reader's file descriptor (pretend it crashed or something).
+                reader.close();
+
+                // Because the reader is gone, the writer should observe an error (EPIPE).
+                // Wait for this to happen.
+                writerSawError.await(TIMEOUT, TimeUnit.MILLISECONDS);
+
+                // The reader and writer should already be unregistered.
+                // Try to unregistered them again to ensure nothing bad happens.
+                queue.removeOnFileDescriptorEventListener(reader.getFD());
+                queue.removeOnFileDescriptorEventListener(writer.getFD());
+            }
+        } finally {
+            thread.quitAndRethrow();
+        }
+    }
+
+    /**
+     * Since file descriptor numbers may be reused, there are some interesting
+     * edge cases around closing file descriptors within the callback and adding
+     * new ones with the same number.
+     *
+     * Register a file descriptor, close it from within the callback, then return.
+     * Later, create a new file descriptor register it.  Ensure that we start getting
+     * events for the new file descriptor.
+     *
+     * This test exercises special logic in Looper.cpp for EPOLL_CTL_DEL handling EBADF.
+     */
+    public void testPathologicalFileDescriptorReuseCallbacks1() throws Throwable {
+        // Prepare a special looper that we can catch exceptions from.
+        AssertableHandlerThread thread = new AssertableHandlerThread();
+        thread.start();
+        try {
+            final MessageQueue queue = thread.getLooper().getQueue();
+            final Handler handler = new Handler(thread.getLooper());
+
+            final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+            try (final FileInputStream reader = new AutoCloseInputStream(pipe[0]);
+                    final FileOutputStream writer = new AutoCloseOutputStream(pipe[1])) {
+                // Register the callback.
+                final CountDownLatch awoke = new CountDownLatch(1);
+                queue.addOnFileDescriptorEventListener(reader.getFD(),
+                        OnFileDescriptorEventListener.EVENT_ERROR,
+                        new OnFileDescriptorEventListener() {
+                    @Override
+                    public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                        awoke.countDown();
+
+                        // Close the reader before we return.
+                        closeQuietly(reader);
+
+                        // Return 0 to unregister the callback.
+                        return 0;
+                    }
+                });
+
+                // Close the writer to wake up the callback (due to hangup).
+                writer.close();
+
+                // Wait for the looper to catch up and run the callback.
+                assertTrue("awoke", awoke.await(TIMEOUT, TimeUnit.MILLISECONDS));
+                syncWait(handler);
+            }
+
+            // At this point, the reader and writer are both closed.
+            // Make a new pipe and ensure that things still work as expected.
+            final ParcelFileDescriptor[] pipe2 = ParcelFileDescriptor.createPipe();
+            try (final FileInputStream reader2 = new AutoCloseInputStream(pipe2[0]);
+                    final FileOutputStream writer2 = new AutoCloseOutputStream(pipe2[1])) {
+                // Register the callback.
+                final CountDownLatch awoke = new CountDownLatch(1);
+                queue.addOnFileDescriptorEventListener(reader2.getFD(),
+                        OnFileDescriptorEventListener.EVENT_INPUT,
+                        new OnFileDescriptorEventListener() {
+                    @Override
+                    public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                        awoke.countDown();
+
+                        // Return 0 to unregister the callback.
+                        return 0;
+                    }
+                });
+
+                // Close the writer to wake up the callback (due to hangup).
+                writer2.close();
+
+                // Wait for the looper to catch up and run the callback.
+                assertTrue("awoke", awoke.await(TIMEOUT, TimeUnit.MILLISECONDS));
+                syncWait(handler);
+            }
+        } finally {
+            thread.quitAndRethrow();
+        }
+    }
+
+    /**
+     * Since file descriptor numbers may be reused, there are some interesting
+     * edge cases around closing file descriptors within the callback and adding
+     * new ones with the same number.
+     *
+     * Register a file descriptor, close it from within the callback, reassign its
+     * number to a different pipe, then return.  Later, register the same file descriptor
+     * again (now referring to a new pipe).  Ensure that we start getting
+     * events for the new file descriptor.
+     *
+     * This test exercises special logic in Looper.cpp for EPOLL_CTL_DEL handling ENOENT.
+     */
+    public void testPathologicalFileDescriptorReuseCallbacks2() throws Throwable {
+        // Prepare a special looper that we can catch exceptions from.
+        AssertableHandlerThread thread = new AssertableHandlerThread();
+        thread.start();
+        try {
+            final MessageQueue queue = thread.getLooper().getQueue();
+            final Handler handler = new Handler(thread.getLooper());
+
+            final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+            final ParcelFileDescriptor[] pipe2 = ParcelFileDescriptor.createPipe();
+            try {
+                final int oldReaderFd = pipe[0].getFd();
+                try (final FileInputStream reader = new AutoCloseInputStream(pipe[0]);
+                        final FileOutputStream writer = new AutoCloseOutputStream(pipe[1])) {
+                    // Register the callback.
+                    final CountDownLatch awoke = new CountDownLatch(1);
+                    queue.addOnFileDescriptorEventListener(reader.getFD(),
+                            OnFileDescriptorEventListener.EVENT_ERROR,
+                            new OnFileDescriptorEventListener() {
+                        @Override
+                        public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                            awoke.countDown();
+
+                            // Close the reader before we return and hijack its fd.
+                            hijackFd(pipe2, pipe);
+
+                            // Return 0 to unregister the callback.
+                            return 0;
+                        }
+                    });
+
+                    // Close the writer to wake up the callback (due to hangup).
+                    writer.close();
+
+                    // Wait for the looper to catch up and run the callback.
+                    assertTrue("awoke", awoke.await(TIMEOUT, TimeUnit.MILLISECONDS));
+                    syncWait(handler);
+                }
+
+                // Now we have a new pipe with the same file descriptor, make sure we can
+                // register it successfully.
+                assertEquals(oldReaderFd, pipe2[0].getFd());
+                try (final FileInputStream reader2 = new AutoCloseInputStream(pipe2[0]);
+                        final FileOutputStream writer2 = new AutoCloseOutputStream(pipe2[1])) {
+                    // Register the callback.
+                    final CountDownLatch awoke = new CountDownLatch(1);
+                    queue.addOnFileDescriptorEventListener(reader2.getFD(),
+                            OnFileDescriptorEventListener.EVENT_INPUT,
+                            new OnFileDescriptorEventListener() {
+                        @Override
+                        public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                            awoke.countDown();
+
+                            // Return 0 to unregister the callback.
+                            return 0;
+                        }
+                    });
+
+                    // Close the writer to wake up the callback (due to hangup).
+                    writer2.close();
+
+                    // Wait for the looper to catch up and run the callback.
+                    assertTrue("awoke", awoke.await(TIMEOUT, TimeUnit.MILLISECONDS));
+                    syncWait(handler);
+                }
+            } finally {
+                closeQuietly(pipe[0]);
+                closeQuietly(pipe[1]);
+                closeQuietly(pipe2[0]);
+                closeQuietly(pipe2[1]);
+            }
+        } finally {
+            thread.quitAndRethrow();
+        }
+    }
+
+    /**
+     * Since file descriptor numbers may be reused, there are some interesting
+     * edge cases around closing file descriptors within the callback and adding
+     * new ones with the same number.
+     *
+     * Register a file descriptor, close it from within the callback, reassign its
+     * number to a different pipe, register it, then return.
+     * Ensure that we start getting events for the new file descriptor.
+     *
+     * This test exercises special logic in Looper.cpp for EPOLL_CTL_MOD handling
+     * ENOENT and fallback to EPOLL_CTL_ADD as well as sequence number checks when removing
+     * the fd after the callback returns.
+     */
+    public void testPathologicalFileDescriptorReuseCallbacks3() throws Throwable {
+        // Prepare a special looper that we can catch exceptions from.
+        AssertableHandlerThread thread = new AssertableHandlerThread();
+        thread.start();
+        try {
+            final MessageQueue queue = thread.getLooper().getQueue();
+            final Handler handler = new Handler(thread.getLooper());
+
+            final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+            final ParcelFileDescriptor[] pipe2 = ParcelFileDescriptor.createPipe();
+            try {
+                final CountDownLatch awoke2 = new CountDownLatch(1);
+                final int oldReaderFd = pipe[0].getFd();
+                try (final FileInputStream reader = new AutoCloseInputStream(pipe[0]);
+                        final FileOutputStream writer = new AutoCloseOutputStream(pipe[1])) {
+                    // Register the callback.
+                    final CountDownLatch awoke = new CountDownLatch(1);
+                    queue.addOnFileDescriptorEventListener(reader.getFD(),
+                            OnFileDescriptorEventListener.EVENT_ERROR,
+                            new OnFileDescriptorEventListener() {
+                        @Override
+                        public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                            awoke.countDown();
+
+                            // Close the reader before we return and hijack its fd.
+                            hijackFd(pipe2, pipe);
+
+                            // Now we have a new pipe, make sure we can register it successfully.
+                            queue.addOnFileDescriptorEventListener(pipe2[0].getFileDescriptor(),
+                                    OnFileDescriptorEventListener.EVENT_INPUT,
+                                    new OnFileDescriptorEventListener() {
+                                @Override
+                                public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                                    awoke2.countDown();
+
+                                    // Return 0 to unregister the callback.
+                                    return 0;
+                                }
+                            });
+
+                            // Return 0 to unregister the callback.
+                            return 0;
+                        }
+                    });
+
+                    // Close the writer to wake up the callback (due to hangup).
+                    writer.close();
+
+                    // Wait for the looper to catch up and run the callback.
+                    assertTrue("awoke", awoke.await(TIMEOUT, TimeUnit.MILLISECONDS));
+                    syncWait(handler);
+                }
+
+                // Close the second writer to wake up the second callback (due to hangup).
+                pipe2[1].close();
+
+                // Wait for the looper to catch up and run the callback.
+                assertTrue("awoke2", awoke2.await(TIMEOUT, TimeUnit.MILLISECONDS));
+                syncWait(handler);
+
+                // Close the second reader now that we're done with the test.
+                assertEquals(oldReaderFd, pipe2[0].getFd());
+                pipe2[0].close();
+            } finally {
+                closeQuietly(pipe[0]);
+                closeQuietly(pipe[1]);
+                closeQuietly(pipe2[0]);
+                closeQuietly(pipe2[1]);
+            }
+        } finally {
+            thread.quitAndRethrow();
+        }
+    }
+
+    /**
+     * Since file descriptor numbers may be reused, there are some interesting
+     * edge cases around closing file descriptors within the callback and adding
+     * new ones with the same number.
+     *
+     * Register a file descriptor, make a duplicate of it, close it from within the
+     * callback, then return.  Look for signs that the Looper is spinning
+     * and never getting a chance to block.
+     *
+     * This test exercises special logic in Looper.cpp for rebuilding the epoll set
+     * in case it contains a file descriptor which has been closed and cannot be removed.
+     */
+    public void testPathologicalFileDescriptorReuseCallbacks4() throws Throwable {
+        // Prepare a special looper that we can catch exceptions from.
+        ParcelFileDescriptor dup = null;
+        AssertableHandlerThread thread = new AssertableHandlerThread();
+        thread.start();
+        try {
+            try {
+                final MessageQueue queue = thread.getLooper().getQueue();
+                final Handler handler = new Handler(thread.getLooper());
+
+                final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+                dup = pipe[0].dup();
+                try (final FileInputStream reader = new AutoCloseInputStream(pipe[0]);
+                        final FileOutputStream writer = new AutoCloseOutputStream(pipe[1])) {
+                    // Register the callback.
+                    final CountDownLatch awoke = new CountDownLatch(1);
+                    queue.addOnFileDescriptorEventListener(reader.getFD(),
+                            OnFileDescriptorEventListener.EVENT_ERROR, new OnFileDescriptorEventListener() {
+                        @Override
+                        public int onFileDescriptorEvents(FileDescriptor fd, int events) {
+                            awoke.countDown();
+
+                            // Close the file descriptor before we return.
+                            try {
+                                reader.close();
+                            } catch (IOException ex) {
+                                throw new RuntimeException(ex);
+                            }
+
+                            // Return 0 to unregister the callback.
+                            return 0;
+                        }
+                    });
+
+                    // Close the writer to wake up the callback (due to hangup).
+                    writer.close();
+
+                    // Wait for the looper to catch up and run the callback.
+                    assertTrue("awoke", awoke.await(TIMEOUT, TimeUnit.MILLISECONDS));
+                    syncWait(handler);
+                }
+
+                // Wait a little bit before we stop the thread.
+                Thread.sleep(2000);
+            } finally {
+                // Check for how long the thread was running.
+                // If the Looper behaved correctly, then it should have blocked for most of
+                // the duration of the test (including that sleep above) since not much else
+                // was happening.  If we failed to actually rebuild the epoll set then the
+                // Looper may have been spinning continuously due to an FD that was never
+                // properly removed from the epoll set so the thread runtime will be very high.
+                long runtime = thread.quitAndRethrow();
+                assertFalse("Looper thread spent most of its time spinning instead of blocked.",
+                        runtime > 1000);
+            }
+        } finally {
+            // Close the duplicate now that we are done with it.
+            if (dup != null) {
+                dup.close();
+            }
+        }
+    }
+
     public void testSyncBarriers() throws Exception {
         OrderTestHelper tester = new OrderTestHelper() {
             private int mBarrierToken1;
             private int mBarrierToken2;
 
+            @Override
             public void init() {
                 super.init();
                 mLastMessage = 10;
                 mHandler.sendEmptyMessage(0);
-                mBarrierToken1 = Looper.myLooper().postSyncBarrier();
+                mBarrierToken1 = Looper.myQueue().postSyncBarrier();
                 mHandler.sendEmptyMessage(5);
                 sendAsyncMessage(1);
                 sendAsyncMessage(2);
@@ -179,19 +733,20 @@
                 mHandler.sendEmptyMessage(6);
             }
 
+            @Override
             public void handleMessage(Message msg) {
                 super.handleMessage(msg);
                 if (msg.what == 3) {
                     mHandler.sendEmptyMessage(7);
-                    mBarrierToken2 = Looper.myLooper().postSyncBarrier();
+                    mBarrierToken2 = Looper.myQueue().postSyncBarrier();
                     sendAsyncMessage(4);
                     sendAsyncMessage(8);
                 } else if (msg.what == 4) {
-                    Looper.myLooper().removeSyncBarrier(mBarrierToken1);
+                    Looper.myQueue().removeSyncBarrier(mBarrierToken1);
                     sendAsyncMessage(9);
                     mHandler.sendEmptyMessage(10);
                 } else if (msg.what == 8) {
-                    Looper.myLooper().removeSyncBarrier(mBarrierToken2);
+                    Looper.myQueue().removeSyncBarrier(mBarrierToken2);
                 }
             }
 
@@ -206,25 +761,66 @@
     }
 
     public void testReleaseSyncBarrierThrowsIfTokenNotValid() throws Exception {
+        MessageQueue queue = Looper.getMainLooper().getQueue();
+
         // Invalid token
         try {
-            Looper.getMainLooper().removeSyncBarrier(-1);
+            queue.removeSyncBarrier(-1);
             fail("Should have thrown IllegalStateException");
         } catch (IllegalStateException ex) {
             // expected
         }
 
         // Token already removed.
-        int barrierToken = Looper.getMainLooper().postSyncBarrier();
-        Looper.getMainLooper().removeSyncBarrier(barrierToken);
+        int barrierToken = queue.postSyncBarrier();
+        queue.removeSyncBarrier(barrierToken);
         try {
-            Looper.getMainLooper().removeSyncBarrier(barrierToken);
+            queue.removeSyncBarrier(barrierToken);
             fail("Should have thrown IllegalStateException");
         } catch (IllegalStateException ex) {
             // expected
         }
     }
 
+    private void syncWait(Handler handler) throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(1);
+        handler.post(new Runnable() {
+            @Override
+            public void run() {
+                latch.countDown();
+            }
+        });
+        assertTrue("Handler got stuck.", latch.await(TIMEOUT, TimeUnit.MILLISECONDS));
+    }
+
+    private static void closeQuietly(AutoCloseable c) {
+        if (c != null) {
+            try {
+                c.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ex) {
+            }
+        }
+    }
+
+    private static void hijackFd(ParcelFileDescriptor[] newPipe, ParcelFileDescriptor[] oldPipe) {
+        // Detach the old pipe's first fd and get its number.
+        int fd = oldPipe[0].detachFd();
+
+        // Assign the new pipe's first fd to the same number as the old pipe's first fd.
+        // This causes the old pipe's first fd to be closed and reassigned.
+        try {
+            Os.dup2(newPipe[0].getFileDescriptor(), fd);
+        } catch (ErrnoException ex) {
+            throw new RuntimeException(ex);
+        }
+
+        // Fix up the new pipe's first fd object.
+        closeQuietly(newPipe[0]);
+        newPipe[0] = ParcelFileDescriptor.adoptFd(fd);
+    }
+
     /**
      * Helper class used to test sending message to message queue.
      */
@@ -239,6 +835,7 @@
 
         public void init() {
             mHandler = new Handler() {
+                @Override
                 public void handleMessage(Message msg) {
                     OrderTestHelper.this.handleMessage(msg);
                 }
@@ -288,6 +885,7 @@
                 super("MessengerLooperThread");
             }
 
+            @Override
             public void onLooperPrepared() {
                 init();
                 mLooper = getLooper();
@@ -328,4 +926,38 @@
             }
         }
     }
+
+    /**
+     * A HandlerThread that propagates exceptions out of the event loop
+     * instead of crashing the process.
+     */
+    private static class AssertableHandlerThread extends HandlerThread {
+        private Throwable mThrowable;
+        private long mRuntime;
+
+        public AssertableHandlerThread() {
+            super("AssertableHandlerThread");
+        }
+
+        @Override
+        public void run() {
+            final long startTime = SystemClock.currentThreadTimeMillis();
+            try {
+                super.run();
+            } catch (Throwable t) {
+                mThrowable = t;
+            } finally {
+                mRuntime = SystemClock.currentThreadTimeMillis() - startTime;
+            }
+        }
+
+        public long quitAndRethrow() throws Throwable {
+            quitSafely();
+            join(TIMEOUT);
+            if (mThrowable != null) {
+                throw mThrowable;
+            }
+            return mRuntime;
+        }
+    }
 }
diff --git a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
index 2287660..3bcc4b9 100644
--- a/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelFileDescriptorTest.java
@@ -358,6 +358,15 @@
         }
     }
 
+    // http://b/21578056
+    public void testFileNamesWithNonBmpChars() throws Exception {
+        final File file = File.createTempFile("treble_clef_\ud834\udd1e", ".tmp");
+        final ParcelFileDescriptor pfd = ParcelFileDescriptor.open(file,
+                ParcelFileDescriptor.MODE_READ_ONLY);
+        assertNotNull(pfd);
+        pfd.close();
+    }
+
     static ParcelFileDescriptor makeParcelFileDescriptor(Context con) throws Exception {
         final String fileName = "testParcelFileDescriptor";
 
diff --git a/tests/tests/os/src/android/os/cts/ParcelTest.java b/tests/tests/os/src/android/os/cts/ParcelTest.java
index 35e02ae..5b7b187 100644
--- a/tests/tests/os/src/android/os/cts/ParcelTest.java
+++ b/tests/tests/os/src/android/os/cts/ParcelTest.java
@@ -20,8 +20,6 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
 import android.content.pm.Signature;
 import android.os.BadParcelableException;
@@ -2970,4 +2968,121 @@
             return binder;
         }
     }
+
+    private static boolean parcelableWithBadCreatorInitializerHasRun;
+    private static boolean invalidCreatorIntializerHasRun;
+
+    /**
+     * A class that would be Parcelable except that it doesn't have a CREATOR field declared to be
+     * of the correct type.
+     */
+    @SuppressWarnings("unused") // Referenced via reflection only
+    private static class ParcelableWithBadCreator implements Parcelable {
+
+        static {
+            ParcelTest.parcelableWithBadCreatorInitializerHasRun = true;
+        }
+
+        private static class InvalidCreator
+                implements Parcelable.Creator<ParcelableWithBadCreator> {
+
+            static {
+                invalidCreatorIntializerHasRun = true;
+            }
+
+            @Override
+            public ParcelableWithBadCreator createFromParcel(Parcel source) {
+                return null;
+            }
+
+            @Override
+            public ParcelableWithBadCreator[] newArray(int size) {
+                return new ParcelableWithBadCreator[0];
+            }
+
+        }
+
+        // Invalid declaration: Must be declared as Parcelable.Creator or a subclass.
+        public static Object CREATOR = new InvalidCreator();
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+
+        }
+    }
+
+    // http://b/1171613
+    public void testBadStream_invalidCreator() {
+        Parcel parcel = Parcel.obtain();
+        // Create an invalid stream by manipulating the Parcel.
+        parcel.writeString(getClass().getName() + "$ParcelableWithBadCreator");
+        byte[] badData = parcel.marshall();
+        parcel.recycle();
+
+        // Now try to read the bad data.
+        parcel = Parcel.obtain();
+        parcel.unmarshall(badData, 0, badData.length);
+        parcel.setDataPosition(0);
+        try {
+            parcel.readParcelable(getClass().getClassLoader());
+            fail();
+        } catch (BadParcelableException expected) {
+        } finally {
+            parcel.recycle();
+        }
+
+        assertFalse(invalidCreatorIntializerHasRun);
+        assertFalse(parcelableWithBadCreatorInitializerHasRun);
+    }
+
+    private static boolean doesNotImplementParcelableInitializerHasRun;
+
+    /** A class that would be Parcelable except that it does not implement Parcelable. */
+    @SuppressWarnings("unused") // Referenced via reflection only
+    private static class DoesNotImplementParcelable {
+
+        static {
+            doesNotImplementParcelableInitializerHasRun = true;
+        }
+
+        public static Parcelable.Creator<Object> CREATOR = new Parcelable.Creator<Object>() {
+            @Override
+            public Object createFromParcel(Parcel source) {
+                return new DoesNotImplementParcelable();
+            }
+
+            @Override
+            public Object[] newArray(int size) {
+                return new Object[size];
+            }
+        };
+    }
+
+    // http://b/1171613
+    public void testBadStream_objectDoesNotImplementParcelable() {
+        Parcel parcel = Parcel.obtain();
+        // Create an invalid stream by manipulating the Parcel.
+        parcel.writeString(getClass().getName() + "$DoesNotImplementParcelable");
+        byte[] badData = parcel.marshall();
+        parcel.recycle();
+
+        // Now try to read the bad data.
+        parcel = Parcel.obtain();
+        parcel.unmarshall(badData, 0, badData.length);
+        parcel.setDataPosition(0);
+        try {
+            parcel.readParcelable(getClass().getClassLoader());
+            fail();
+        } catch (BadParcelableException expected) {
+        } finally {
+            parcel.recycle();
+        }
+
+        assertFalse(doesNotImplementParcelableInitializerHasRun);
+    }
 }
diff --git a/tests/tests/os/src/android/os/cts/SeccompTest.java b/tests/tests/os/src/android/os/cts/SeccompTest.java
index 6c49337..7376079 100644
--- a/tests/tests/os/src/android/os/cts/SeccompTest.java
+++ b/tests/tests/os/src/android/os/cts/SeccompTest.java
@@ -16,18 +16,397 @@
 
 package android.os.cts;
 
-import junit.framework.TestCase;
+import android.app.Service;
+import android.content.Context;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Environment;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.MemoryFile;
+import android.os.SystemClock;
+import android.os.Build;
+import android.util.Log;
+import android.test.AndroidTestCase;
 
-public class SeccompTest extends TestCase {
+import com.google.common.util.concurrent.AbstractFuture;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.Date;
+
+public class SeccompTest extends AndroidTestCase {
+    final static String TAG = "SeccompTest";
+
+    static {
+        System.loadLibrary("ctsos_jni");
+    }
+
+    // As this test validates a kernel system call interface, if the CTS tests
+    // were built for ARM but are running on an x86 CPU, the system call numbers
+    // will not be correct, so skip those tests.
+    private boolean isRunningUnderEmulatedAbi() {
+        final String primaryAbi = Build.SUPPORTED_ABIS[0];
+        return (CpuFeatures.isArmCpu() || CpuFeatures.isArm64Cpu()) &&
+               !(primaryAbi.equals("armeabi-v7a") || primaryAbi.equals("arm64-v8a"));
+    }
 
     public void testSeccomp() {
-        if (CpuFeatures.isArm64Cpu() || CpuFeatures.isArm64CpuIn32BitMode()) {
-            return; // seccomp not yet supported on arm64
-        }
         if (OSFeatures.needsSeccompSupport()) {
             assertTrue("Please enable seccomp support "
                        + "in your kernel (CONFIG_SECCOMP_FILTER=y)",
                        OSFeatures.hasSeccompSupport());
         }
     }
+
+    public void testKernelBasicTests() {
+        if (!OSFeatures.needsSeccompSupport())
+            return;
+
+        if (isRunningUnderEmulatedAbi()) {
+            Log.d(TAG, "Skipping test running under an emulated ABI");
+            return;
+        }
+
+        final String[] tests = {
+            "global.mode_strict_support",
+            "global.mode_strict_cannot_call_prctl",
+            "global.no_new_privs_support",
+            "global.mode_filter_support",
+            /* "global.mode_filter_without_nnp", // all Android processes already have nnp */
+            "global.filter_size_limits",
+            "global.filter_chain_limits",
+            "global.mode_filter_cannot_move_to_strict",
+            "global.mode_filter_get_seccomp",
+            "global.ALLOW_all",
+            "global.empty_prog",
+            "global.unknown_ret_is_kill_inside",
+            "global.unknown_ret_is_kill_above_allow",
+            "global.KILL_all",
+            "global.KILL_one",
+            "global.KILL_one_arg_one",
+            "global.KILL_one_arg_six",
+            "global.arg_out_of_range",
+            "global.ERRNO_one",
+            "global.ERRNO_one_ok",
+        };
+        runKernelUnitTestSuite(tests);
+    }
+
+    public void testKernelTrapTests() {
+        if (!OSFeatures.needsSeccompSupport())
+            return;
+
+        final String[] tests = {
+            "TRAP.dfl",
+            "TRAP.ign",
+            "TRAP.handler",
+        };
+        runKernelUnitTestSuite(tests);
+    }
+
+    public void testKernelPrecedenceTests() {
+        if (!OSFeatures.needsSeccompSupport())
+            return;
+
+        final String[] tests = {
+            "precedence.allow_ok",
+            "precedence.kill_is_highest",
+            "precedence.kill_is_highest_in_any_order",
+            "precedence.trap_is_second",
+            "precedence.trap_is_second_in_any_order",
+            "precedence.errno_is_third",
+            "precedence.errno_is_third_in_any_order",
+            "precedence.trace_is_fourth",
+            "precedence.trace_is_fourth_in_any_order",
+        };
+        runKernelUnitTestSuite(tests);
+    }
+
+    /* // The SECCOMP_RET_TRACE does not work under Android Arm32.
+    public void testKernelTraceTests() {
+        if (!OSFeatures.needsSeccompSupport())
+            return;
+
+        final String[] tests = {
+            "TRACE_poke.read_has_side_effects",
+            "TRACE_poke.getpid_runs_normally",
+            "TRACE_syscall.syscall_allowed",
+            "TRACE_syscall.syscall_redirected",
+            "TRACE_syscall.syscall_dropped",
+        };
+        runKernelUnitTestSuite(tests);
+    }
+    */
+
+    public void testKernelTSYNCTests() {
+        if (!OSFeatures.needsSeccompSupport())
+            return;
+
+        if (isRunningUnderEmulatedAbi()) {
+            Log.d(TAG, "Skipping test running under an emulated ABI");
+            return;
+        }
+
+        final String[] tests = {
+            "global.seccomp_syscall",
+            "global.seccomp_syscall_mode_lock",
+            "global.TSYNC_first",
+            "TSYNC.siblings_fail_prctl",
+            "TSYNC.two_siblings_with_ancestor",
+            /* "TSYNC.two_sibling_want_nnp", // all Android processes already have nnp */
+            "TSYNC.two_siblings_with_no_filter",
+            "TSYNC.two_siblings_with_one_divergence",
+            "TSYNC.two_siblings_not_under_filter",
+            /* "global.syscall_restart", // ptrace attach fails */
+        };
+        runKernelUnitTestSuite(tests);
+    }
+
+    /**
+     * Runs a kernel unit test suite (an array of kernel test names).
+     */
+    private void runKernelUnitTestSuite(final String[] tests) {
+        for (final String test : tests) {
+            // TODO: Replace the URL with the documentation when it's finished.
+            assertTrue(test + " failed. This test requires kernel functionality to pass. "
+                       + "Please go to http://XXXXX for instructions on how to enable or "
+                       + "backport the required functionality.",
+                       runKernelUnitTest(test));
+        }
+    }
+
+    /**
+     * Integration test for seccomp-bpf policy applied to an isolatedProcess=true
+     * service. This will perform various operations in an isolated process under a
+     * fairly restrictive seccomp policy.
+     */
+    public void testIsolatedServicePolicy() throws InterruptedException, ExecutionException,
+           RemoteException {
+        if (!OSFeatures.needsSeccompSupport())
+            return;
+
+        if (isRunningUnderEmulatedAbi()) {
+            Log.d(TAG, "Skipping test running under an emulated ABI");
+            return;
+        }
+
+        final IsolatedServiceConnection peer = new IsolatedServiceConnection();
+        final Intent intent = new Intent(getContext(), IsolatedService.class);
+        assertTrue(getContext().bindService(intent, peer, Context.BIND_AUTO_CREATE));
+
+        final ISeccompIsolatedService service = peer.get();
+
+        // installFilter() must be called first, to set the seccomp policy.
+        assertTrue(service.installFilter());
+        assertTrue(service.createThread());
+        assertTrue(service.getSystemInfo());
+        doFileWriteTest(service);
+        assertTrue(service.openAshmem());
+        assertTrue(service.openDevFile());
+
+        getContext().unbindService(peer);
+    }
+
+    /**
+     * Integration test for seccomp-bpf policy with isolatedProcess, where the
+     * process then violates the policy and gets killed by the kernel.
+     */
+    public void testViolateIsolatedServicePolicy() throws InterruptedException,
+           ExecutionException, RemoteException {
+        if (!OSFeatures.needsSeccompSupport())
+            return;
+
+        if (isRunningUnderEmulatedAbi()) {
+            Log.d(TAG, "Skipping test running under an emulated ABI");
+            return;
+        }
+
+        final IsolatedServiceConnection peer = new IsolatedServiceConnection();
+        final Intent intent = new Intent(getContext(), IsolatedService.class);
+        assertTrue(getContext().bindService(intent, peer, Context.BIND_AUTO_CREATE));
+
+        final ISeccompIsolatedService service = peer.get();
+
+        assertTrue(service.installFilter());
+        boolean gotRemoteException = false;
+        try {
+            service.violatePolicy();
+        } catch (RemoteException e) {
+            gotRemoteException = true;
+        }
+        assertTrue(gotRemoteException);
+
+        getContext().unbindService(peer);
+    }
+
+    private void doFileWriteTest(ISeccompIsolatedService service) throws RemoteException {
+        final String fileName = "seccomp_test";
+        ParcelFileDescriptor fd = null;
+        try {
+            FileOutputStream fOut = getContext().openFileOutput(fileName, 0);
+            fd = ParcelFileDescriptor.dup(fOut.getFD());
+            fOut.close();
+        } catch (FileNotFoundException e) {
+            fail(e.getMessage());
+            return;
+        } catch (IOException e) {
+            fail(e.getMessage());
+            return;
+        }
+
+        assertTrue(service.writeToFile(fd));
+
+        try {
+            FileInputStream fIn = getContext().openFileInput(fileName);
+            assertEquals('!', fIn.read());
+            fIn.close();
+        } catch (FileNotFoundException e) {
+            fail(e.getMessage());
+        } catch (IOException e) {
+            fail(e.getMessage());
+        }
+    }
+
+    class IsolatedServiceConnection extends AbstractFuture<ISeccompIsolatedService>
+            implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            set(ISeccompIsolatedService.Stub.asInterface(service));
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+        }
+
+        @Override
+        public ISeccompIsolatedService get() throws InterruptedException, ExecutionException {
+            try {
+                return get(10, TimeUnit.SECONDS);
+            } catch (TimeoutException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public static class IsolatedService extends Service {
+        private final ISeccompIsolatedService.Stub mService = new ISeccompIsolatedService.Stub() {
+            public boolean installFilter() {
+                return installTestFilter();
+            }
+
+            public boolean createThread() {
+                Thread thread = new Thread(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
+                            Thread.sleep(100);
+                        } catch (InterruptedException e) {
+                        }
+                    }
+                });
+                thread.run();
+                try {
+                    thread.join();
+                } catch (InterruptedException e) {
+                    return false;
+                }
+                return true;
+            }
+
+            public boolean getSystemInfo() {
+                long uptimeMillis = SystemClock.uptimeMillis();
+                if (uptimeMillis < 1) {
+                    Log.d(TAG, "SystemClock failed");
+                    return false;
+                }
+
+                String version = Build.VERSION.CODENAME;
+                if (version.length() == 0) {
+                    Log.d(TAG, "Build.VERSION failed");
+                    return false;
+                }
+
+                long time = (new Date()).getTime();
+                if (time < 100) {
+                    Log.d(TAG, "getTime failed");
+                    return false;
+                }
+
+                return true;
+            }
+
+            public boolean writeToFile(ParcelFileDescriptor fd) {
+                FileOutputStream fOut = new FileOutputStream(fd.getFileDescriptor());
+                try {
+                    fOut.write('!');
+                    fOut.close();
+                } catch (IOException e) {
+                    return false;
+                }
+                return true;
+            }
+
+            public boolean openAshmem() {
+                byte[] buffer = {'h', 'e', 'l', 'l', 'o'};
+                try {
+                    MemoryFile file = new MemoryFile("seccomp_isolated_test", 32);
+                    file.writeBytes(buffer, 0, 0, buffer.length);
+                    file.close();
+                    return true;
+                } catch (IOException e) {
+                    return false;
+                }
+            }
+
+            public boolean openDevFile() {
+                try {
+                    FileInputStream fIn = new FileInputStream("/dev/zero");
+                    boolean succeed = fIn.read() == 0;
+                    succeed &= fIn.read() == 0;
+                    succeed &= fIn.read() == 0;
+                    fIn.close();
+                    return succeed;
+                } catch (FileNotFoundException e) {
+                    return false;
+                } catch (IOException e) {
+                    return false;
+                }
+            }
+
+            public void violatePolicy() {
+                getClockBootTime();
+            }
+        };
+
+        @Override
+        public IBinder onBind(Intent intent) {
+            return mService;
+        }
+    }
+
+    /**
+     * Runs the seccomp_bpf_unittest of the given name.
+     */
+    private native boolean runKernelUnitTest(final String name);
+
+    /**
+     * Installs a test seccomp-bpf filter program that.
+     */
+    private native static boolean installTestFilter();
+
+    /**
+     * Attempts to get the CLOCK_BOOTTIME, which is a violation of the
+     * policy specified by installTestFilter().
+     */
+    private native static int getClockBootTime();
 }
diff --git a/tests/tests/os/src/android/os/cts/StrictModeTest.java b/tests/tests/os/src/android/os/cts/StrictModeTest.java
new file mode 100644
index 0000000..2407309
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/StrictModeTest.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.os.cts;
+
+import android.content.pm.PackageManager;
+import android.os.StrictMode;
+import android.os.SystemClock;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import libcore.io.Streams;
+
+import java.io.ByteArrayOutputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Tests for {@link StrictMode}
+ */
+public class StrictModeTest extends AndroidTestCase {
+    private static final String TAG = "StrictModeTest";
+
+    private StrictMode.VmPolicy mPolicy;
+
+    @Override
+    protected void setUp() {
+        mPolicy = StrictMode.getVmPolicy();
+    }
+
+    @Override
+    protected void tearDown() {
+        StrictMode.setVmPolicy(mPolicy);
+    }
+
+    public void testCleartextNetwork() throws Exception {
+        if (!hasInternetConnection()) {
+            Log.i(TAG, "testCleartextNetwork() ignored on device without Internet");
+            return;
+        }
+
+        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
+                .detectCleartextNetwork()
+                .penaltyLog()
+                .build());
+
+        final long millis = System.currentTimeMillis();
+        final String msg = "Detected cleartext network traffic from UID "
+                + android.os.Process.myUid();
+
+        // Insecure connection should be detected
+        ((HttpURLConnection) new URL("http://example.com/").openConnection()).getResponseCode();
+
+        // Give system enough time to finish logging
+        SystemClock.sleep(5000);
+        assertTrue("Expected cleartext to be caught", readLogSince(millis).contains(msg));
+    }
+
+    public void testEncryptedNetwork() throws Exception {
+        if (!hasInternetConnection()) {
+            Log.i(TAG, "testEncryptedNetwork() ignored on device without Internet");
+            return;
+        }
+
+        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
+                .detectCleartextNetwork()
+                .penaltyLog()
+                .build());
+
+        final long millis = System.currentTimeMillis();
+        final String msg = "Detected cleartext network traffic from UID "
+                + android.os.Process.myUid();
+
+        // Secure connection should be ignored
+        ((HttpURLConnection) new URL("https://example.com/").openConnection()).getResponseCode();
+
+        // Give system enough time to finish logging
+        SystemClock.sleep(5000);
+        assertFalse("Expected encrypted to be ignored", readLogSince(millis).contains(msg));
+    }
+
+    private String readLogSince(long millis) throws Exception {
+        final SimpleDateFormat format = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
+        final Process proc = new ProcessBuilder("logcat", "-t", format.format(new Date(millis)))
+                .redirectErrorStream(true).start();
+
+        final ByteArrayOutputStream buf = new ByteArrayOutputStream();
+        Streams.copy(proc.getInputStream(), buf);
+        final int res = proc.waitFor();
+
+        Log.d(TAG, "Log output was " + buf.size() + " bytes, exit code " + res);
+        return new String(buf.toByteArray());
+    }
+
+    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/permission/src/android/permission/cts/AccountManagerTest.java b/tests/tests/permission/src/android/permission/cts/AccountManagerTest.java
deleted file mode 100644
index 5d4378f..0000000
--- a/tests/tests/permission/src/android/permission/cts/AccountManagerTest.java
+++ /dev/null
@@ -1,85 +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.permission.cts;
-
-import android.content.Context;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.accounts.AccountManagerFuture;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * Verify GET_ACCOUNTS permissions are enforced.
- */
-public class AccountManagerTest extends AndroidTestCase {
-
-    private AccountManager mAccountManager;
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mAccountManager = AccountManager.get(getContext());
-        assertNotNull(mAccountManager);
-    }
-
-    /**
-     * Verifies that AccountManager.getAccounts() requires Permission.
-     * <p>
-     * Requires Permission: {@link android.Manifest.permission#GET_ACCOUNTS}.
-     */
-    @SmallTest
-    public void testGetAccounts() {
-        try {
-            mAccountManager.getAccounts();
-            fail("AccountManager.getAccounts() did not throw SecurityException as expected");
-        } catch (SecurityException se) {
-            // Expected Exception
-        }
-    }
-
-    /**
-     * Verifies that AccountManager.getAccountsByType() requires Permission.
-     * <p>
-     * Requires Permission: {@link android.Manifest.permission#GET_ACCOUNTS}.
-     */
-    @SmallTest
-    public void testGetAccountsByType() {
-        try {
-            mAccountManager.getAccountsByType(null);
-            fail("AccountManager.getAccountsByType() did not throw SecurityException as expected");
-        } catch (SecurityException se) {
-            // Expected Exception
-        }
-    }
-
-    /**
-     * Verifies that AccountManager.getAccountsByTypeAndFeatures() requires
-     * Permission.
-     * <p>
-     * Requires Permission: {@link android.Manifest.permission#GET_ACCOUNTS}.
-     */
-    @SmallTest
-    public void testGetAccountsByTypeAndFeatures() {
-        try {
-            mAccountManager.getAccountsByTypeAndFeatures("", null, null, null);
-            fail("AccountManager.getAccountsByTypeAndFeatures() did not throw SecurityException as expected");
-        } catch (SecurityException se) {
-            // Expected Exception
-        }
-    }
-}
diff --git a/tests/tests/permission/src/android/permission/cts/ConnectivityManagerPermissionTest.java b/tests/tests/permission/src/android/permission/cts/ConnectivityManagerPermissionTest.java
index 8714100..a95c96e 100644
--- a/tests/tests/permission/src/android/permission/cts/ConnectivityManagerPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ConnectivityManagerPermissionTest.java
@@ -53,21 +53,4 @@
             // expected
         }
     }
-
-    /**
-     * Verify that calling {@link ConnectivityManager#requestRouteToHost(int, int)}
-     * requires permissions.
-     * <p>Tests Permission:
-     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
-     */
-    @SmallTest
-    public void testRequestRouteToHost() {
-        try {
-            mConnectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE, 1);
-            fail("Was able to call requestRouteToHost");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
 }
-
diff --git a/tests/tests/permission/src/android/permission/cts/ContactsProviderTest.java b/tests/tests/permission/src/android/permission/cts/ContactsProviderTest.java
index 51e54df..984fd6c 100644
--- a/tests/tests/permission/src/android/permission/cts/ContactsProviderTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ContactsProviderTest.java
@@ -16,12 +16,7 @@
 
 package android.permission.cts;
 
-import android.os.RemoteException;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
 import android.content.ContentValues;
-import android.database.Cursor;
-import android.provider.Contacts;
 import android.provider.ContactsContract;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -71,7 +66,7 @@
      * Verifies that query(ContactsContract.Profile.CONTENT_URI) requires
      * Permission.
      * <p>
-     * Requires Permission: {@link android.Manifest.permission#READ_PROFILE}.
+     * Requires Permission: {@link android.Manifest.permission#READ_CONTACTS}.
      */
     @SmallTest
     public void testQueryProfile() {
@@ -91,7 +86,7 @@
      * permission, but trying to do it without the permission should throw a
      * SecurityException anyway.
      * <p>
-     * Requires Permission: {@link android.Manifest.permission#WRITE_PROFILE}.
+     * Requires Permission: {@link android.Manifest.permission#WRITE_CONTACTS}.
      */
     @SmallTest
     public void testInsertProfile() {
@@ -109,7 +104,7 @@
      * Verifies that update(ContactsContract.Profile.CONTENT_URI) requires
      * Permission.
      * <p>
-     * Requires Permission: {@link android.Manifest.permission#WRITE_PROFILE}.
+     * Requires Permission: {@link android.Manifest.permission#WRITE_CONTACTS}.
      */
     @SmallTest
     public void testUpdateProfile() {
@@ -122,4 +117,41 @@
             // Expected Exception
         }
     }
+
+    /**
+    * Verifies that query(ContactsContract.CommonDataKinds.Phone.ENTERPRISE_CONTENT_URI) requires
+    * Permission.
+    * <p>
+    * Requires Permission: {@link android.Manifest.permission#INTERACT_ACROSS_USERS}.
+    */
+    @SmallTest
+    public void testQueryPhoneEnterprise() {
+        try {
+            getContext().getContentResolver().query(
+                    ContactsContract.CommonDataKinds.Phone.ENTERPRISE_CONTENT_URI,
+                    null, null, null, null);
+            fail("query(ContactsContract.CommonDataKinds.Phone.ENTERPRISE_CONTENT_URI) did not"
+                    + " throw SecurityException as expected");
+        } catch (SecurityException se) {
+            // Expected Exception
+        }
+    }
+
+    /**
+    * Verifies that query(ContactsContract.RawContactsEntity.CORP_CONTENT_URI) requires
+    * Permission.
+    * <p>
+    * Requires Permission: {@link android.Manifest.permission#INTERACT_ACROSS_USERS}.
+    */
+    @SmallTest
+    public void testRawContactsEntityCorp() {
+        try {
+            getContext().getContentResolver().query(
+                    ContactsContract.RawContactsEntity.CORP_CONTENT_URI, null, null, null, null);
+            fail("query(ContactsContract.RawContactsEntity.CORP_CONTENT_URI) did not throw"
+                    + " SecurityException as expected");
+        } catch (SecurityException se) {
+            // Expected Exception
+        }
+    }
 }
diff --git a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
old mode 100755
new mode 100644
index babc93f..7ef725b
--- a/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/FileSystemPermissionTest.java
@@ -19,7 +19,10 @@
 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;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.LargeTest;
@@ -27,6 +30,7 @@
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileFilter;
+import java.io.FilenameFilter;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
@@ -161,17 +165,13 @@
     @MediumTest
     public void testDevMemSane() throws Exception {
         File f = new File("/dev/mem");
-        assertFalse(f.canRead());
-        assertFalse(f.canWrite());
-        assertFalse(f.canExecute());
+        assertFalse(f.exists());
     }
 
     @MediumTest
     public void testDevkmemSane() throws Exception {
         File f = new File("/dev/kmem");
-        assertFalse(f.canRead());
-        assertFalse(f.canWrite());
-        assertFalse(f.canExecute());
+        assertFalse(f.exists());
     }
 
     @MediumTest
@@ -249,6 +249,20 @@
     }
 
     @MediumTest
+    public void testProcSelfOomAdjSane() {
+        File f = new File("/proc/self/oom_adj");
+        assertFalse(f.canWrite());
+        assertFalse(f.canExecute());
+    }
+
+    @MediumTest
+    public void testProcSelfOomScoreAdjSane() {
+        File f = new File("/proc/self/oom_score_adj");
+        assertFalse(f.canWrite());
+        assertFalse(f.canExecute());
+    }
+
+    @MediumTest
     public void testTcpDefaultRwndSane() throws Exception {
         File f = new File("/proc/sys/net/ipv4/tcp_default_init_rwnd");
         assertTrue(f.canRead());
@@ -343,6 +357,36 @@
         assertFalse(f.canExecute());
     }
 
+    @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
+         * kernel version 3.10 and above.
+         */
+        if (!arch.contains("arm") ||
+            Integer.parseInt(osVersion[0]) < 2 ||
+            (Integer.parseInt(osVersion[0]) == 3 &&
+             Integer.parseInt(osVersion[1]) < 10))
+            return;
+        final File f = new File("/proc/device-tree/cpus");
+        if (!f.exists())
+            return;
+        String[] dir = f.list(new FilenameFilter() {
+            @Override
+            public boolean accept(File pathname, String name) {
+                return (pathname.isDirectory() && name.matches("cpu@[0-9]+"));
+            }
+        });
+
+        for(String cpuDir : dir) {
+            File fCpu = new File(cpuDir + "/current");
+            assertTrue(f.canRead());
+        }
+    }
+
     private static boolean isDirectoryWritable(File directory) {
         File toCreate = new File(directory, "hello");
         try {
@@ -711,48 +755,20 @@
         return retval;
     }
 
-    public void testSystemMountedRO() throws IOException {
-        ParsedMounts pm = new ParsedMounts("/proc/self/mounts");
-        String mountPoint = pm.findMountPointContaining(new File("/system"));
-        assertTrue(mountPoint + " is not mounted read-only", pm.isMountReadOnly(mountPoint));
+    public void testSystemMountedRO() throws Exception {
+        StructStatVfs vfs = Os.statvfs("/system");
+        assertTrue("/system is not mounted read-only", (vfs.f_flag & OsConstants.ST_RDONLY) != 0);
     }
 
-    /**
-     * Test that the /system directory, as mounted by init, is mounted read-only.
-     * Different processes can have different mount namespaces, so init
-     * may be in a different mount namespace than Zygote spawned processes.
-     *
-     * This test assumes that init's filesystem layout is roughly identical
-     * to Zygote's filesystem layout. If this assumption ever changes, we should
-     * delete this test.
-     */
-    public void testSystemMountedRO_init() throws IOException {
-        ParsedMounts pm = new ParsedMounts("/proc/1/mounts");
-        String mountPoint = pm.findMountPointContaining(new File("/system"));
-        assertTrue(mountPoint + " is not mounted read-only", pm.isMountReadOnly(mountPoint));
+    public void testRootMountedRO() throws Exception {
+        StructStatVfs vfs = Os.statvfs("/");
+        assertTrue("rootfs is not mounted read-only", (vfs.f_flag & OsConstants.ST_RDONLY) != 0);
     }
 
-    public void testRootMountedRO() throws IOException {
-        ParsedMounts pm = new ParsedMounts("/proc/self/mounts");
-        String mountPoint = pm.findMountPointContaining(new File("/"));
-        assertTrue("The root directory \"" + mountPoint + "\" is not mounted read-only",
-                   pm.isMountReadOnly(mountPoint));
-    }
-
-    /**
-     * Test that the root directory, as mounted by init, is mounted read-only.
-     * Different processes can have different mount namespaces, so init
-     * may be in a different mount namespace than Zygote spawned processes.
-     *
-     * This test assumes that init's filesystem layout is roughly identical
-     * to Zygote's filesystem layout. If this assumption ever changes, we should
-     * delete this test.
-     */
-    public void testRootMountedRO_init() throws IOException {
-        ParsedMounts pm = new ParsedMounts("/proc/1/mounts");
-        String mountPoint = pm.findMountPointContaining(new File("/"));
-        assertTrue("The root directory \"" + mountPoint + "\" is not mounted read-only",
-                   pm.isMountReadOnly(mountPoint));
+    public void testDataMountedNoSuidNoDev() throws Exception {
+        StructStatVfs vfs = Os.statvfs(getContext().getFilesDir().getAbsolutePath());
+        assertTrue("/data is not mounted NOSUID", (vfs.f_flag & OsConstants.ST_NOSUID) != 0);
+        assertTrue("/data is not mounted NODEV", (vfs.f_flag & OsConstants.ST_NODEV) != 0);
     }
 
     public void testAllBlockDevicesAreSecure() throws Exception {
@@ -769,7 +785,11 @@
                 new File("/dev/ashmem"),
                 new File("/dev/binder"),
                 new File("/dev/card0"),       // b/13159510
+                new File("/dev/renderD128"),
+                new File("/dev/renderD129"),  // b/23798677
                 new File("/dev/dri/card0"),   // b/13159510
+                new File("/dev/dri/renderD128"),
+                new File("/dev/dri/renderD129"), // b/23798677
                 new File("/dev/felica"),     // b/11142586
                 new File("/dev/felica_ant"), // b/11142586
                 new File("/dev/felica_cen"), // b/11142586
@@ -1049,48 +1069,4 @@
         return !f.getAbsolutePath().equals(f.getCanonicalPath());
     }
 
-    private static class ParsedMounts {
-        private HashMap<String, Boolean> mFileReadOnlyMap = new HashMap<String, Boolean>();
-
-        private ParsedMounts(String filename) throws IOException {
-            BufferedReader br = new BufferedReader(new FileReader(filename));
-            try {
-                String line;
-                while ((line = br.readLine()) != null) {
-                    String[] fields = line.split(" ");
-                    String mountPoint = fields[1];
-                    String all_options = fields[3];
-                    String[] options = all_options.split(",");
-                    boolean foundRo = false;
-                    for (String option : options) {
-                        if ("ro".equals(option)) {
-                            foundRo = true;
-                            break;
-                        }
-                    }
-                    mFileReadOnlyMap.put(mountPoint, foundRo);
-                }
-           } finally {
-               br.close();
-           }
-        }
-
-        private boolean isMountReadOnly(String s) {
-            return mFileReadOnlyMap.get(s).booleanValue();
-        }
-
-        private String findMountPointContaining(File f) throws IOException {
-            while (f != null) {
-                f = f.getCanonicalFile();
-                String path = f.getPath();
-                if (mFileReadOnlyMap.containsKey(path)) {
-                    return path;
-                }
-                f = f.getParentFile();
-            }
-            // This should NEVER be reached, as we'll eventually hit the
-            // root directory.
-            throw new AssertionError("Unable to find mount point");
-        }
-    }
 }
diff --git a/tests/tests/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java b/tests/tests/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java
index 0eae9cc..35ebdc1 100644
--- a/tests/tests/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/NoNetworkStatePermissionTest.java
@@ -86,38 +86,6 @@
         }
     }
 
-    /**
-     * Verify that ConnectivityManager#startUsingNetworkFeature() requires permissions.
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
-     */
-    @SmallTest
-    public void testStartUsingNetworkFeature() {
-        try {
-            mConnectivityManager.startUsingNetworkFeature(TEST_NETWORK_TYPE, TEST_FEATURE);
-            fail("ConnectivityManager.startUsingNetworkFeature didn't throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
-    /**
-     * Verify that ConnectivityManager#requestRouteToHost() requires permissions.
-     * <p>Requires Permission:
-     *   {@link android.Manifest.permission#CHANGE_NETWORK_STATE}.
-     */
-    @SmallTest
-    public void testRequestRouteToHost() {
-        try {
-            mConnectivityManager.requestRouteToHost(TEST_NETWORK_TYPE, 0xffffffff);
-            fail("ConnectivityManager.requestRouteToHost didn't throw SecurityException as"
-                    + " expected");
-        } catch (SecurityException e) {
-            // expected
-        }
-    }
-
     @SmallTest
     public void testSecurityExceptionFromDns() throws Exception {
         try {
diff --git a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
index 105fb81..6d55a69 100644
--- a/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/ProviderPermissionTest.java
@@ -16,9 +16,10 @@
 
 package android.permission.cts;
 
-import android.provider.Browser;
+import android.content.ContentValues;
 import android.provider.CallLog;
 import android.provider.Contacts;
+import android.provider.Settings;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
 
@@ -74,48 +75,19 @@
      *   {@link android.Manifest.permission#WRITE_SETTINGS}
      */
     public void testWriteSettings() {
-        assertWritingContentUriRequiresPermission(android.provider.Settings.System.CONTENT_URI,
-                android.Manifest.permission.WRITE_SETTINGS);
-    }
+        final String permission = android.Manifest.permission.WRITE_SETTINGS;
+        ContentValues value = new ContentValues();
+        value.put(Settings.System.NAME, "name");
+        value.put(Settings.System.VALUE, "value_insert");
 
-    /**
-     * Verify that read and write to browser bookmarks requires permissions.
-     * <p>Tests Permission:
-     *   {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
-     */
-    public void testReadBookmarks() {
-        assertReadingContentUriRequiresPermission(Browser.BOOKMARKS_URI,
-                android.Manifest.permission.READ_HISTORY_BOOKMARKS);
-    }
-
-    /**
-     * Verify that read and write to browser bookmarks requires permissions.
-     * <p>Tests Permission:
-         {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
-     */
-    public void testWriteBookmarks() {
-        assertWritingContentUriRequiresPermission(Browser.BOOKMARKS_URI,
-                android.Manifest.permission.WRITE_HISTORY_BOOKMARKS);
-    }
-
-    /**
-     * Verify that read and write to browser history requires permissions.
-     * <p>Tests Permission:
-     *   {@link android.Manifest.permission#READ_HISTORY_BOOKMARKS}
-     */
-    public void testReadBrowserHistory() {
-        assertReadingContentUriRequiresPermission(Browser.SEARCHES_URI,
-                android.Manifest.permission.READ_HISTORY_BOOKMARKS);
-    }
-
-    /**
-     * Verify that read and write to browser history requires permissions.
-     * <p>Tests Permission:
-         {@link android.Manifest.permission#WRITE_HISTORY_BOOKMARKS}
-     */
-    public void testWriteBrowserHistory() {
-        assertWritingContentUriRequiresPermission(Browser.SEARCHES_URI,
-                android.Manifest.permission.WRITE_HISTORY_BOOKMARKS);
+        try {
+            getContext().getContentResolver().insert(Settings.System.CONTENT_URI, value);
+            fail("expected SecurityException requiring " + permission);
+        } catch (SecurityException expected) {
+            assertNotNull("security exception's error message.", expected.getMessage());
+            assertTrue("error message should contain \"" + permission + "\". Got: \""
+                    + expected.getMessage() + "\".",
+                    expected.getMessage().contains(permission));
+        }
     }
 }
-
diff --git a/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java b/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java
index 0c648c5..4139059 100644
--- a/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java
+++ b/tests/tests/permission/src/android/permission/cts/TvPermissionTest.java
@@ -42,16 +42,6 @@
         super.tearDown();
     }
 
-    private void verifyQuery(Uri uri, final String[] projection,
-            String tableName) throws Exception {
-        try {
-            getContext().getContentResolver().query(uri, projection, null, null, null);
-            fail("Accessing " + tableName + " table should require READ_EPG_DATA permission.");
-        } catch (SecurityException e) {
-            // Expected exception
-        }
-    }
-
     public void verifyInsert(Uri uri, String tableName) throws Exception {
         try {
             ContentValues values = new ContentValues();
@@ -81,12 +71,6 @@
         }
     }
 
-    public void testQueryChannels() throws Exception {
-        if (!mHasTvInputFramework) return;
-        final String[] projection = { TvContract.Channels._ID };
-        verifyQuery(TvContract.Channels.CONTENT_URI, projection, "channels");
-    }
-
     public void testInsertChannels() throws Exception {
         if (!mHasTvInputFramework) return;
         verifyInsert(TvContract.Channels.CONTENT_URI, "channels");
@@ -102,12 +86,6 @@
         verifyDelete(TvContract.Channels.CONTENT_URI, "channels");
     }
 
-    public void testQueryPrograms() throws Exception {
-        if (!mHasTvInputFramework) return;
-        final String[] projection = { TvContract.Programs._ID };
-        verifyQuery(TvContract.Programs.CONTENT_URI, projection, "programs");
-    }
-
     public void testInsertPrograms() throws Exception {
         if (!mHasTvInputFramework) return;
         verifyInsert(TvContract.Programs.CONTENT_URI, "programs");
diff --git a/tests/tests/permission2/AndroidManifest.xml b/tests/tests/permission2/AndroidManifest.xml
index c0b78c4..984d124 100755
--- a/tests/tests/permission2/AndroidManifest.xml
+++ b/tests/tests/permission2/AndroidManifest.xml
@@ -45,6 +45,12 @@
     <!-- need app that has RECORD_AUDIO but not CAPTURE_AUDIO_OUTPUT -->
     <uses-permission android:name="android.permission.RECORD_AUDIO"/>
 
+    <!-- need app that has READ_CONTACTS but not READ_PROFILE -->
+    <uses-permission android:name="android.permission.READ_CONTACTS"/>
+
+    <!-- need app that has WRITE_CONTACTS but not WRITE_PROFILE -->
+    <uses-permission android:name="android.permission.WRITE_CONTACTS"/>
+
     <!-- need a permission that would ordinarily be granted, but has a maxSdkVersion that
          causes it to be withheld under the current API level -->
     <uses-permission
diff --git a/tests/tests/permission2/src/android/permission2/cts/ContactsProviderTest.java b/tests/tests/permission2/src/android/permission2/cts/ContactsProviderTest.java
new file mode 100644
index 0000000..5a04079
--- /dev/null
+++ b/tests/tests/permission2/src/android/permission2/cts/ContactsProviderTest.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package android.permission2.cts;
+
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+/**
+ * Verify that deprecated contacts permissions are not enforced.
+ */
+public class ContactsProviderTest extends AndroidTestCase {
+
+    /**
+     * Verifies that query(ContactsContract.Contacts.CONTENT_URI) only requires
+     * permission {@link android.Manifest.permission#READ_CONTACTS}.
+     */
+    @SmallTest
+    public void testQueryContacts() {
+        getContext().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI,
+                null, null, null, null);
+    }
+
+    /**
+     * Verifies that insert(ContactsContract.Contacts.CONTENT_URI) only requires
+     * permission {@link android.Manifest.permission#WRITE_CONTACTS}.
+     */
+    @SmallTest
+    public void testInsertContacts() {
+        try {
+            getContext().getContentResolver().insert(ContactsContract.Contacts.CONTENT_URI,
+                    new ContentValues());
+        } catch (SecurityException e) {
+            fail("insert(ContactsContract.Contacts.CONTENT_URI) threw SecurityException");
+        } catch (UnsupportedOperationException e) {
+            // It is okay for this fail in this manner.
+        }
+    }
+
+    /**
+     * Verifies that query(ContactsContract.Profile.CONTENT_URI) only requires
+     * permission {@link android.Manifest.permission#READ_CONTACTS}.
+     */
+    @SmallTest
+    public void testQueryProfile() {
+        getContext().getContentResolver().query(ContactsContract.Profile.CONTENT_URI,
+                null, null, null, null);
+    }
+
+    /**
+     * Verifies that insert(ContactsContract.Profile.CONTENT_URI) only requires
+     * permission {@link android.Manifest.permission#WRITE_CONTACTS}. The provider won't
+     * actually let us execute this. But at least it shouldn't throw a security exception.
+     */
+    @SmallTest
+    public void testInsertProfile() {
+     try {
+         getContext().getContentResolver().insert(ContactsContract.Profile.CONTENT_URI,
+                new ContentValues(0));
+        } catch (SecurityException e) {
+            fail("insert(ContactsContract.Profile.CONTENT_URI) threw SecurityException");
+        } catch (UnsupportedOperationException e) {
+            // It is okay for this fail in this manner.
+        }
+    }
+
+    /**
+     * Verifies that update(ContactsContract.Profile.CONTENT_URI) only requires
+     * permission {@link android.Manifest.permission#WRITE_CONTACTS}.
+     */
+    @SmallTest
+    public void testUpdateProfile() {
+        getContext().getContentResolver().update(ContactsContract.Profile.CONTENT_URI,
+                new ContentValues(0), null, null);
+    }
+}
diff --git a/tests/tests/permission2/src/android/permission2/cts/NoWriteSecureSettingsPermissionTest.java b/tests/tests/permission2/src/android/permission2/cts/NoWriteSecureSettingsPermissionTest.java
index eb476c7..b46c45d 100644
--- a/tests/tests/permission2/src/android/permission2/cts/NoWriteSecureSettingsPermissionTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/NoWriteSecureSettingsPermissionTest.java
@@ -16,6 +16,9 @@
 
 package android.permission2.cts;
 
+import android.Manifest;
+import android.content.ContentValues;
+import android.provider.Settings;
 import android.test.AndroidTestCase;
 
 /**
@@ -30,7 +33,15 @@
      *   {@link android.Manifest.permission#WRITE_SECURE_SETTINGS}
      */
     public void testWriteSecureSettings() {
-        assertWritingContentUriRequiresPermission(android.provider.Settings.Secure.CONTENT_URI,
-                android.Manifest.permission.WRITE_SECURE_SETTINGS);
+        try {
+            ContentValues values = new ContentValues();
+            values.put(Settings.Secure.NAME, Settings.Secure.ACCESSIBILITY_ENABLED);
+            values.put(Settings.Secure.VALUE, Boolean.TRUE);
+            getContext().getContentResolver().insert(Settings.Secure.CONTENT_URI, values);
+            fail("expected SecurityException requiring "
+                    + Manifest.permission.WRITE_SECURE_SETTINGS);
+        } catch (SecurityException expected) {
+           /* do nothing */
+        }
     }
 }
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
new file mode 100644
index 0000000..a4d68cb
--- /dev/null
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.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 android.permission2.cts;
+
+import android.Manifest;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
+import android.test.AndroidTestCase;
+import android.text.TextUtils;
+import android.util.ArraySet;
+
+import java.util.Set;
+
+/**
+ * Tests for permission policy on the platform.
+ */
+public class PermissionPolicyTest extends AndroidTestCase {
+    private static final String PLATFORM_PACKAGE_NAME = "android";
+
+    private static final Set<String> PERMISSION_GROUPS = new ArraySet<>();
+    static {
+        PERMISSION_GROUPS.add(Manifest.permission_group.CALENDAR);
+        PERMISSION_GROUPS.add(Manifest.permission_group.CAMERA);
+        PERMISSION_GROUPS.add(Manifest.permission_group.CONTACTS);
+        PERMISSION_GROUPS.add(Manifest.permission_group.LOCATION);
+        PERMISSION_GROUPS.add(Manifest.permission_group.MICROPHONE);
+        PERMISSION_GROUPS.add(Manifest.permission_group.PHONE);
+        PERMISSION_GROUPS.add(Manifest.permission_group.SENSORS);
+        PERMISSION_GROUPS.add(Manifest.permission_group.SMS);
+        PERMISSION_GROUPS.add(Manifest.permission_group.STORAGE);
+    }
+
+    public void testPlatformDefinedRuntimePermissionValid() throws Exception {
+        PackageManager packageManager = getContext().getPackageManager();
+        PackageInfo packageInfo = packageManager.getPackageInfo(PLATFORM_PACKAGE_NAME,
+                PackageManager.GET_PERMISSIONS);
+        for (PermissionInfo permission : packageInfo.permissions) {
+            if ((permission.protectionLevel & PermissionInfo.PROTECTION_DANGEROUS) == 0) {
+                continue;
+            }
+            assertTrue(permission.name + " must be in one of these groups: " + PERMISSION_GROUPS,
+                    PERMISSION_GROUPS.contains(permission.group));
+            assertFalse(permission.name + " must have non-empty label",
+                    TextUtils.isEmpty(permission.loadLabel(packageManager)));
+            assertFalse(permission.name + " must have non-empty description",
+                    TextUtils.isEmpty(permission.loadDescription(packageManager)));
+        }
+    }
+}
diff --git a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
index f7e5443..c260706 100644
--- a/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/ProtectedBroadcastsTest.java
@@ -98,4 +98,4 @@
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/tests/tests/permission2/src/android/permission2/cts/ReadSocialStreamPermissionTest.java b/tests/tests/permission2/src/android/permission2/cts/ReadSocialStreamPermissionTest.java
deleted file mode 100644
index eaf6fdf..0000000
--- a/tests/tests/permission2/src/android/permission2/cts/ReadSocialStreamPermissionTest.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 android.permission2.cts;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.net.Uri;
-import android.provider.ContactsContract.Contacts;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.StreamItems;
-import android.test.AndroidTestCase;
-
-public class ReadSocialStreamPermissionTest extends AndroidTestCase {
-
-    private ContentResolver mResolver;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mResolver = mContext.getContentResolver();
-    }
-
-    public void testReadSocialStreamPermission_byRawContactId() throws Exception {
-        try {
-            mResolver.query(Uri.withAppendedPath(
-                    ContentUris.withAppendedId(RawContacts.CONTENT_URI, 1337),
-                    Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
-            fail("Expected a READ_SOCIAL_STREAM exception");
-        } catch (SecurityException e) {
-            // Expect a READ_SOCIAL_STREAM exception.
-        }
-    }
-
-    public void testReadSocialStreamPermission_byContactId() throws Exception {
-        try {
-            mResolver.query(Uri.withAppendedPath(
-                    ContentUris.withAppendedId(Contacts.CONTENT_URI, 1337),
-                    Contacts.StreamItems.CONTENT_DIRECTORY), null, null, null, null);
-            fail("Expected a READ_SOCIAL_STREAM exception");
-        } catch (SecurityException e) {
-            // Expect a READ_SOCIAL_STREAM exception.
-        }
-    }
-
-    public void testReadSocialStreamPermission_byLookUpKey() throws Exception {
-        try {
-            mResolver.query(Contacts.CONTENT_LOOKUP_URI.buildUpon()
-                    .appendPath("lookDownKey")
-                    .appendPath(Contacts.StreamItems.CONTENT_DIRECTORY)
-                    .build(), null, null, null, null);
-            fail("Expected a READ_SOCIAL_STREAM exception");
-        } catch (SecurityException e) {
-            // Expect a READ_SOCIAL_STREAM exception.
-        }
-    }
-
-    public void testReadSocialStreamPermission_byStreamItemId() throws Exception {
-        try {
-            mResolver.query(ContentUris.withAppendedId(StreamItems.CONTENT_URI, 1337),
-                    null, null, null, null);
-            fail("Expected a READ_SOCIAL_STREAM exception");
-        } catch (SecurityException e) {
-            // Expect a READ_SOCIAL_STREAM exception.
-        }
-    }
-}
diff --git a/tests/tests/permission2/src/android/permission2/cts/WriteSocialStreamPermissionTest.java b/tests/tests/permission2/src/android/permission2/cts/WriteSocialStreamPermissionTest.java
deleted file mode 100644
index 262fcfa..0000000
--- a/tests/tests/permission2/src/android/permission2/cts/WriteSocialStreamPermissionTest.java
+++ /dev/null
@@ -1,58 +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.permission2.cts;
-
-import android.content.ContentResolver;
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.net.Uri;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.ContactsContract.StreamItems;
-import android.test.AndroidTestCase;
-
-public class WriteSocialStreamPermissionTest extends AndroidTestCase {
-
-    private ContentResolver mResolver;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mResolver = mContext.getContentResolver();
-    }
-
-    public void testWriteSocialStreamPermission_byContentDirectory() throws Exception {
-        try {
-            ContentValues values = new ContentValues();
-            mResolver.insert(Uri.withAppendedPath(
-                    ContentUris.withAppendedId(RawContacts.CONTENT_URI, 1337),
-                    RawContacts.StreamItems.CONTENT_DIRECTORY), values);
-            fail("Expected a WRITE_SOCIAL_STREAM exception");
-        } catch (SecurityException e) {
-            // Expect a WRITE_SOCIAL_STREAM exception.
-        }
-    }
-
-    public void testWriteSocialStreamPermission_byContentUri() throws Exception {
-        try {
-            ContentValues values = new ContentValues();
-            mResolver.insert(StreamItems.CONTENT_URI, values);
-            fail("Expected a WRITE_SOCIAL_STREAM exception");
-        } catch (SecurityException e) {
-            // Expect a WRITE_SOCIAL_STREAM exception.
-        }
-    }
-}
diff --git a/tests/tests/print/Android.mk b/tests/tests/print/Android.mk
index 516f6a0..2ece2cf 100644
--- a/tests/tests/print/Android.mk
+++ b/tests/tests/print/Android.mk
@@ -18,15 +18,11 @@
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
-    src/android/print/cts/IPrivilegedOperations.aidl
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsPrintTestCases
 
-LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ctstestrunner ub-uiautomator
-
-# This test runner sets up/cleans up the device before/after running the tests.
-LOCAL_CTS_TEST_RUNNER := com.android.cts.tradefed.testtype.PrintTestRunner
+LOCAL_STATIC_JAVA_LIBRARIES := mockito-target ctstestrunner ub-uiautomator ctsdeviceutil
 
 LOCAL_SDK_VERSION := current
 
diff --git a/tests/tests/print/src/android/print/cts/BasePrintTest.java b/tests/tests/print/src/android/print/cts/BasePrintTest.java
index 9d51e3b..e67943d 100755
--- a/tests/tests/print/src/android/print/cts/BasePrintTest.java
+++ b/tests/tests/print/src/android/print/cts/BasePrintTest.java
@@ -28,6 +28,7 @@
 import android.content.pm.PackageManager;
 import android.content.res.Configuration;
 import android.content.res.Resources;
+import android.cts.util.SystemUtil;
 import android.graphics.pdf.PdfDocument;
 import android.os.Bundle;
 import android.os.CancellationSignal;
@@ -60,9 +61,13 @@
 import org.mockito.InOrder;
 import org.mockito.stubbing.Answer;
 
+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.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
 import java.util.concurrent.TimeoutException;
@@ -74,12 +79,18 @@
 
     private static final long OPERATION_TIMEOUT = 100000000;
 
-    private static final String ARG_PRIVILEGED_OPS = "ARG_PRIVILEGED_OPS";
-
     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 PrintDocumentActivity mActivity;
 
     private Locale mOldLocale;
@@ -91,10 +102,62 @@
     private CallCounter mPrintJobQueuedCallCounter;
     private CallCounter mDestroySessionCallCounter;
 
+    private String[] mEnabledImes;
+
+    private String[] getEnabledImes() throws IOException {
+        List<String> imeList = new ArrayList<>();
+
+        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                .executeShellCommand(COMMAND_LIST_ENABLED_IME_COMPONENTS);
+        BufferedReader reader = new BufferedReader(
+                new InputStreamReader(new FileInputStream(pfd.getFileDescriptor())));
+
+        String line;
+        while ((line = reader.readLine()) != null) {
+            imeList.add(line);
+        }
+
+        String[] imeArray = new String[imeList.size()];
+        imeList.toArray(imeArray);
+
+        return imeArray;
+    }
+
+    private void disableImes() throws Exception {
+        mEnabledImes = getEnabledImes();
+        for (String ime : mEnabledImes) {
+            String disableImeCommand = COMMAND_PREFIX_DISABLE_IME + ime;
+            SystemUtil.runShellCommand(getInstrumentation(), disableImeCommand);
+        }
+    }
+
+    private void enableImes() throws Exception {
+        for (String ime : mEnabledImes) {
+            String enableImeCommand = COMMAND_PREFIX_ENABLE_IME + ime;
+            SystemUtil.runShellCommand(getInstrumentation(), enableImeCommand);
+        }
+        mEnabledImes = null;
+    }
+
+    @Override
+    protected void runTest() throws Throwable {
+        // Do nothing if the device does not support printing.
+        if (supportsPrinting()) {
+            super.runTest();
+        }
+    }
+
     @Override
     public void setUp() throws Exception {
+        super.setUp();
+        if (!supportsPrinting()) {
+            return;
+        }
+
         // 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
         // Dexmaker is used by mockito.
@@ -127,8 +190,13 @@
 
     @Override
     public void tearDown() throws Exception {
+        if (!supportsPrinting()) {
+            return;
+        }
+
         // Done with the activity.
         getActivity().finish();
+        enableImes();
 
         // Restore the locale if needed.
         if (mOldLocale != null) {
@@ -140,8 +208,11 @@
             resources.updateConfiguration(newConfiguration, displayMetrics);
         }
 
+        disablePrintServices();
         // Make sure the spooler is cleaned.
         clearPrintSpoolerData();
+
+        super.tearDown();
     }
 
     protected void print(final PrintDocumentAdapter adapter) {
@@ -279,6 +350,19 @@
         }
     }
 
+    protected void changeDuplex(String duplex) throws UiObjectNotFoundException {
+        try {
+            UiObject duplexSpinner = new UiObject(new UiSelector().resourceId(
+                    "com.android.printspooler:id/duplex_spinner"));
+            duplexSpinner.click();
+            UiObject duplexOption = new UiObject(new UiSelector().text(duplex));
+            duplexOption.click();
+        } catch (UiObjectNotFoundException e) {
+            dumpWindowHierarchy();
+            throw new UiObjectNotFoundException(e);
+        }
+    }
+
     protected void clickPrintButton() throws UiObjectNotFoundException {
         try {
             UiObject printButton = new UiObject(new UiSelector().resourceId(
@@ -313,9 +397,24 @@
     }
 
     protected void clearPrintSpoolerData() throws Exception {
-        IPrivilegedOperations privilegedOps = IPrivilegedOperations.Stub.asInterface(
-                getParams().getBinder(ARG_PRIVILEGED_OPS));
-        privilegedOps.clearApplicationUserData(PRINT_SPOOLER_PACKAGE_NAME);
+        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 \"\"");
     }
 
     protected void verifyLayoutCall(InOrder inOrder, PrintDocumentAdapter mock,
@@ -468,6 +567,7 @@
     }
 
     protected boolean supportsPrinting() {
-        return getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_PRINTING);
+        return getInstrumentation().getContext().getPackageManager().hasSystemFeature(
+                PackageManager.FEATURE_PRINTING);
     }
 }
diff --git a/tests/tests/print/src/android/print/cts/IPrivilegedOperations.aidl b/tests/tests/print/src/android/print/cts/IPrivilegedOperations.aidl
deleted file mode 100644
index 93c8c3e..0000000
--- a/tests/tests/print/src/android/print/cts/IPrivilegedOperations.aidl
+++ /dev/null
@@ -1,21 +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.print.cts;
-
-interface IPrivilegedOperations {
-    boolean clearApplicationUserData(String packageName);
-}
diff --git a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
index 538472e..9f1e3a5 100644
--- a/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
+++ b/tests/tests/print/src/android/print/cts/PrintDocumentAdapterContractTest.java
@@ -160,6 +160,7 @@
                 .setResolution(new Resolution("300x300", "300x300", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS)
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_LONG_EDGE)
                 .build();
         verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
 
@@ -353,6 +354,12 @@
         // Wait for layout.
         waitForLayoutAdapterCallbackCount(5);
 
+        // Change the duplex.
+        changeDuplex("Short edge");
+
+        // Wait for layout.
+        waitForLayoutAdapterCallbackCount(6);
+
         // Click the print button.
         clickPrintButton();
 
@@ -394,6 +401,7 @@
                 .setResolution(new Resolution("300x300", "300x300", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS)
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_LONG_EDGE)
                 .build();
         verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
 
@@ -406,6 +414,7 @@
                 .setResolution(new Resolution("300x300", "300x300", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS)
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_LONG_EDGE)
                 .build();
         verifyLayoutCall(inOrder, adapter, thirdOldAttributes, thirdNewAttributes, true);
 
@@ -418,6 +427,7 @@
                 .setResolution(new Resolution("300x300", "300x300", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS)
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_LONG_EDGE)
                 .build();
         verifyLayoutCall(inOrder, adapter, fourthOldAttributes, fourthNewAttributes, true);
 
@@ -430,11 +440,25 @@
                 .setResolution(new Resolution("300x300", "300x300", 300, 300))
                 .setMinMargins(Margins.NO_MARGINS)
                 .setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_LONG_EDGE)
                 .build();
         verifyLayoutCall(inOrder, adapter, fifthOldAttributes, fifthNewAttributes, true);
 
+        // We changed the duplex which triggers a layout. Since we passed
+        // false to the layout callback meaning that the content didn't change,
+        // there shouldn't be a next call to write.
+        PrintAttributes sixthOldAttributes = fifthNewAttributes;
+        PrintAttributes sixthNewAttributes = new PrintAttributes.Builder()
+                .setMediaSize(MediaSize.ISO_A4.asLandscape())
+                .setResolution(new Resolution("300x300", "300x300", 300, 300))
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_SHORT_EDGE)
+                .build();
+        verifyLayoutCall(inOrder, adapter, sixthOldAttributes, sixthNewAttributes, true);
+
         // When print is pressed we ask for a layout which is *not* for preview.
-        verifyLayoutCall(inOrder, adapter, fifthNewAttributes, fifthNewAttributes, false);
+        verifyLayoutCall(inOrder, adapter, sixthNewAttributes, sixthNewAttributes, false);
 
         // When print is pressed we ask for all selected pages but we got
         // them when asking for the ones for a preview, and the adapter does
@@ -565,6 +589,7 @@
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(new Margins(0, 0, 0, 0))
                 .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_LONG_EDGE)
                 .build();
         verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
 
@@ -575,6 +600,7 @@
                 .setResolution(new Resolution("PDF resolution", "PDF resolution", 300, 300))
                 .setMinMargins(new Margins(0, 0, 0, 0))
                 .setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_LONG_EDGE)
                 .build();
         verifyLayoutCall(inOrder, adapter, thirdOldAttributes, thirdNewAttributes, true);
 
@@ -706,7 +732,9 @@
         PrintAttributes secondNewAttributes = new PrintAttributes.Builder()
                 .setMediaSize(MediaSize.ISO_A3)
                 .setResolution(new Resolution("300x300", "300x300", 300, 300))
-                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_LONG_EDGE)
                 .build();
         verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
 
@@ -937,7 +965,9 @@
         PrintAttributes secondNewAttributes = new PrintAttributes.Builder()
                 .setMediaSize(MediaSize.ISO_A3)
                 .setResolution(new Resolution("300x300", "300x300", 300, 300))
-                .setMinMargins(Margins.NO_MARGINS).setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setMinMargins(Margins.NO_MARGINS)
+                .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
+                .setDuplexMode(PrintAttributes.DUPLEX_MODE_LONG_EDGE)
                 .build();
         verifyLayoutCall(inOrder, adapter, secondOldAttributes, secondNewAttributes, true);
 
@@ -1573,8 +1603,13 @@
                         .addResolution(new Resolution("200x200", "200x200", 200, 200), true)
                         .addResolution(new Resolution("300x300", "300x300", 300, 300), false)
                         .setColorModes(PrintAttributes.COLOR_MODE_COLOR
-                                | PrintAttributes.COLOR_MODE_MONOCHROME,
-                                PrintAttributes.COLOR_MODE_MONOCHROME)
+                                        | PrintAttributes.COLOR_MODE_MONOCHROME,
+                                PrintAttributes.COLOR_MODE_MONOCHROME
+                        )
+                        .setDuplexModes(PrintAttributes.DUPLEX_MODE_LONG_EDGE
+                                        | PrintAttributes.DUPLEX_MODE_SHORT_EDGE,
+                                PrintAttributes.DUPLEX_MODE_LONG_EDGE
+                        )
                         .build();
                     PrinterInfo secondPrinter = new PrinterInfo.Builder(secondPrinterId,
                             "Second printer", PrinterInfo.STATUS_IDLE)
diff --git a/tests/tests/provider/AndroidManifest.xml b/tests/tests/provider/AndroidManifest.xml
index abda46c..ed180f6 100644
--- a/tests/tests/provider/AndroidManifest.xml
+++ b/tests/tests/provider/AndroidManifest.xml
@@ -18,6 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
           package="com.android.cts.provider">
 
+    <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" />
@@ -25,22 +27,16 @@
     <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" />
-    <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS" />
-    <uses-permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS" />
     <uses-permission android:name="android.permission.WRITE_CALENDAR" />
     <uses-permission android:name="android.permission.READ_CALENDAR" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.WRITE_USER_DICTIONARY" />
-    <uses-permission android:name="android.permission.READ_USER_DICTIONARY" />
     <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
     <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
     <uses-permission android:name="android.permission.WRITE_CONTACTS" />
-    <uses-permission android:name="android.permission.WRITE_SOCIAL_STREAM" />
     <uses-permission android:name="android.permission.READ_CALL_LOG" />
     <uses-permission android:name="android.permission.READ_CONTACTS" />
-    <uses-permission android:name="android.permission.READ_SOCIAL_STREAM" />
 
     <application>
         <uses-library android:name="android.test.runner"/>
@@ -64,6 +60,15 @@
                        android:resource="@xml/contactprovider_authenticator"/>
         </service>
 
+        <service android:name=".MockInputMethodService"
+                 android:label="UserDictionaryInputMethodTestService"
+                 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"
diff --git a/tests/tests/provider/AndroidTest.xml b/tests/tests/provider/AndroidTest.xml
new file mode 100644
index 0000000..ae603a3
--- /dev/null
+++ b/tests/tests/provider/AndroidTest.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 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" />
+</configuration>
\ No newline at end of file
diff --git a/tests/tests/provider/res/xml/method.xml b/tests/tests/provider/res/xml/method.xml
new file mode 100644
index 0000000..5ac1b80
--- /dev/null
+++ b/tests/tests/provider/res/xml/method.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
+  -->
+
+<input-method xmlns:android="http://schemas.android.com/apk/res/android"
+              android:settingsActivity="android.provider.cts.NoSuchActivity"
+/>
diff --git a/tests/tests/provider/src/android/provider/cts/BrowserTest.java b/tests/tests/provider/src/android/provider/cts/BrowserTest.java
deleted file mode 100644
index 9f96412..0000000
--- a/tests/tests/provider/src/android/provider/cts/BrowserTest.java
+++ /dev/null
@@ -1,697 +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.provider.cts;
-
-import android.app.ActivityManager;
-import android.app.ActivityManager.RunningTaskInfo;
-import android.content.ContentProviderClient;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.provider.Browser;
-import android.provider.Browser.BookmarkColumns;
-import android.provider.Browser.SearchColumns;
-import android.test.ActivityInstrumentationTestCase2;
-
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-
-public class BrowserTest extends ActivityInstrumentationTestCase2<BrowserStubActivity> {
-    public BrowserTest() {
-        super("com.android.cts.provider", BrowserStubActivity.class);
-    }
-
-    private Context mContext;
-    private ContentResolver mContentResolver;
-    private ContentProviderClient mProvider;
-    private BrowserStubActivity mActivity;
-    private boolean mMasterSyncEnabled;
-
-    // the backup for the 2 tables which we will modify in test cases
-    private ArrayList<ContentValues> mBookmarksBackup;
-    private ArrayList<ContentValues> mSearchesBackup;
-
-    private static final String ADD_BOOKMARK_CLASS_NAME =
-            "com.android.browser.AddBookmarkPage";
-    private static final String COMPOSE_MESSAGE_CLASS_NAME =
-            "com.android.mms.ui.ComposeMessageActivity";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mContext = getInstrumentation().getTargetContext();
-        mContentResolver = mContext.getContentResolver();
-        mProvider = mContentResolver.acquireContentProviderClient(
-                Browser.BOOKMARKS_URI.getAuthority());
-        mBookmarksBackup = new ArrayList<ContentValues>();
-        mSearchesBackup = new ArrayList<ContentValues>();
-
-        // Disable sync
-        mMasterSyncEnabled = ContentResolver.getMasterSyncAutomatically();
-        ContentResolver.setMasterSyncAutomatically(false);
-
-        // backup the current contents in database
-        Cursor cursor = mProvider.query(Browser.BOOKMARKS_URI, null, null, null, null, null);
-        while (cursor.moveToNext()) {
-            String[] colNames = cursor.getColumnNames();
-            ContentValues value = new ContentValues();
-
-            for (int i = 0; i < colNames.length; i++) {
-                switch (cursor.getType(i)) {
-                case Cursor.FIELD_TYPE_BLOB:
-                    value.put(colNames[i], cursor.getBlob(i));
-                    break;
-                case Cursor.FIELD_TYPE_FLOAT:
-                    value.put(colNames[i], cursor.getFloat(i));
-                    break;
-                case Cursor.FIELD_TYPE_INTEGER:
-                    if (!"_ID".equalsIgnoreCase(colNames[i])) {
-                        value.put(colNames[i], cursor.getLong(i));
-                    }
-                    break;
-                case Cursor.FIELD_TYPE_STRING:
-                    value.put(colNames[i], cursor.getString(i));
-                    break;
-                }
-            }
-            mBookmarksBackup.add(value);
-        }
-
-        cursor.close();
-
-        cursor = mProvider.query(Browser.SEARCHES_URI, null, null, null, null, null);
-        if (cursor.moveToFirst()) {
-            while (!cursor.isAfterLast()) {
-                ContentValues value = new ContentValues();
-
-                value.put(SearchColumns._ID, cursor.getInt(0));
-                value.put(SearchColumns.SEARCH, cursor.getString(1));
-                value.put(SearchColumns.DATE, cursor.getLong(2));
-                mSearchesBackup.add(value);
-
-                cursor.moveToNext();
-            };
-        }
-        cursor.close();
-
-        mProvider.delete(Browser.BOOKMARKS_URI, null, null);
-        mProvider.delete(Browser.SEARCHES_URI, null, null);
-
-        mActivity = getActivity();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        try {
-            // clear all new contents added in test cases.
-            mProvider.delete(Browser.BOOKMARKS_URI, null, null);
-            mProvider.delete(Browser.SEARCHES_URI, null, null);
-
-            // recover the old backup contents
-            for (ContentValues value : mBookmarksBackup) {
-                mProvider.insert(Browser.BOOKMARKS_URI, value);
-            }
-
-            for (ContentValues value : mSearchesBackup) {
-                mProvider.insert(Browser.SEARCHES_URI, value);
-            }
-
-            // Re-enable sync
-            ContentResolver.setMasterSyncAutomatically(mMasterSyncEnabled);
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    public void testAccessSearches() {
-        final String searchString = "search string";
-        final String searchStringAnother = "another search string";
-        Cursor cursor;
-
-        try {
-            Browser.addSearchUrl(mContentResolver, searchString);
-            cursor = mProvider.query(
-                    Browser.SEARCHES_URI,
-                    Browser.SEARCHES_PROJECTION,
-                    null, null, null, null);
-            assertEquals(1, cursor.getCount());
-            cursor.moveToFirst();
-            assertEquals(searchString,
-                    cursor.getString(Browser.SEARCHES_PROJECTION_SEARCH_INDEX));
-            long oldDate = cursor.getLong(Browser.SEARCHES_PROJECTION_DATE_INDEX);
-            cursor.close();
-
-            Browser.addSearchUrl(mContentResolver, searchString);
-            cursor = mProvider.query(Browser.SEARCHES_URI,
-                    Browser.SEARCHES_PROJECTION,
-                    null, null, null, null);
-            assertEquals(1, cursor.getCount());
-            cursor.moveToFirst();
-            long date = cursor.getLong(Browser.SEARCHES_PROJECTION_DATE_INDEX);
-            assertTrue(date > oldDate);
-            assertEquals(searchString,
-                    cursor.getString(Browser.SEARCHES_PROJECTION_SEARCH_INDEX));
-            cursor.close();
-
-            Browser.addSearchUrl(mContentResolver, searchStringAnother);
-            cursor = mProvider.query(Browser.SEARCHES_URI,
-                    Browser.SEARCHES_PROJECTION,
-                    null, null, null, null);
-            assertEquals(2, cursor.getCount());
-            cursor.moveToFirst();
-            assertEquals(searchString,
-                    cursor.getString(Browser.SEARCHES_PROJECTION_SEARCH_INDEX));
-            cursor.moveToNext();
-            assertEquals(searchStringAnother,
-                    cursor.getString(Browser.SEARCHES_PROJECTION_SEARCH_INDEX));
-            cursor.close();
-
-            Browser.clearSearches(mContentResolver);
-            cursor = mProvider.query(
-                    Browser.SEARCHES_URI,
-                    Browser.SEARCHES_PROJECTION,
-                    null, null, null, null);
-            assertEquals(0, cursor.getCount());
-        } catch (RemoteException e) {
-            fail("Unexpected RemoteException");
-        }
-    }
-
-    public void testGetAllBookmarks() {
-        Cursor cursor;
-        final String bookmarkUrl1 = "www.bookmark1.com";
-        final String bookmarkUrl2 = "www.bookmark2.com";
-        final String historyUrl = "www.history.com";
-
-        try {
-            cursor = Browser.getAllBookmarks(mContentResolver);
-            assertEquals(0, cursor.getCount());
-            cursor.close();
-
-            ContentValues value = new ContentValues();
-            value.put(BookmarkColumns.URL, bookmarkUrl1);
-            value.put(BookmarkColumns.BOOKMARK, 1);
-            mProvider.insert(Browser.BOOKMARKS_URI, value);
-            value.put(BookmarkColumns.URL, bookmarkUrl2);
-            value.put(BookmarkColumns.BOOKMARK, 1);
-            mProvider.insert(Browser.BOOKMARKS_URI, value);
-            value.put(BookmarkColumns.URL, historyUrl);
-            value.put(BookmarkColumns.BOOKMARK, 0);
-            mProvider.insert(Browser.BOOKMARKS_URI, value);
-            cursor = Browser.getAllBookmarks(mContentResolver);
-            assertEquals(2, cursor.getCount());
-            cursor.moveToFirst();
-            assertEquals(bookmarkUrl1, cursor.getString(0));
-            cursor.moveToNext();
-            assertEquals(bookmarkUrl2, cursor.getString(0));
-        } catch (RemoteException e) {
-            fail("unexpected RemoteException");
-        }
-    }
-
-    public void testGetAllVisitedUrls() {
-        Cursor cursor;
-        final String visitedUrl1 = "www.visited1.com";
-        final String visitedUrl2 = "www.visited2.com";
-        final String visitedUrl3 = "www.visited3.com";
-
-        try {
-            cursor = Browser.getAllVisitedUrls(mContentResolver);
-            assertEquals(0, cursor.getCount());
-            cursor.close();
-
-            ContentValues value = new ContentValues();
-            value.put(BookmarkColumns.URL, visitedUrl1);
-            value.put(BookmarkColumns.BOOKMARK, 1);
-            value.put(BookmarkColumns.VISITS, 1);
-            mProvider.insert(Browser.BOOKMARKS_URI, value);
-            value.put(BookmarkColumns.URL, visitedUrl2);
-            value.put(BookmarkColumns.BOOKMARK, 0);
-            value.put(BookmarkColumns.VISITS, 5);
-            mProvider.insert(Browser.BOOKMARKS_URI, value);
-            value.put(BookmarkColumns.URL, visitedUrl3);
-            value.put(BookmarkColumns.BOOKMARK, 1);
-            value.put(BookmarkColumns.VISITS, 0);
-            mProvider.insert(Browser.BOOKMARKS_URI, value);
-            cursor = Browser.getAllVisitedUrls(mContentResolver);
-            assertEquals(3, cursor.getCount());
-            cursor.moveToFirst();
-            assertEquals(visitedUrl1, cursor.getString(0));
-            cursor.moveToNext();
-            assertEquals(visitedUrl2, cursor.getString(0));
-            cursor.moveToNext();
-            assertEquals(visitedUrl3, cursor.getString(0));
-        } catch (RemoteException e) {
-            fail("unexpected RemoteException");
-        }
-    }
-
-    public void testUpdateVisitedHistory() {
-        Cursor cursor;
-        final String visitedHistoryUrl = "www.visited-history.com";
-        long oldTime = 0;
-
-        try {
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    null, null, null, null);
-            assertEquals(0, cursor.getCount());
-            cursor.close();
-            Browser.updateVisitedHistory(mContentResolver, visitedHistoryUrl, true);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    null, null, null, null);
-            assertEquals(1, cursor.getCount());
-            cursor.moveToFirst();
-            assertEquals(visitedHistoryUrl, cursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX));
-            assertEquals(visitedHistoryUrl,
-                    cursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
-            assertEquals(0, cursor.getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX));
-            assertEquals(1, cursor.getInt(Browser.HISTORY_PROJECTION_VISITS_INDEX));
-            oldTime = cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX);
-            cursor.close();
-
-            Browser.updateVisitedHistory(mContentResolver, visitedHistoryUrl, true);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    null, null, null, null);
-            assertEquals(1, cursor.getCount());
-            cursor.moveToFirst();
-            assertEquals(visitedHistoryUrl, cursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX));
-            assertEquals(visitedHistoryUrl,
-                    cursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
-            assertEquals(0, cursor.getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX));
-            assertEquals(2, cursor.getInt(Browser.HISTORY_PROJECTION_VISITS_INDEX));
-            assertTrue(oldTime < cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX));
-            cursor.close();
-        } catch (RemoteException e1) {
-            fail("unexpected RemoteException");
-        }
-    }
-
-    public void testAccessHistory() {
-        Cursor cursor;
-        // NOTE: this value must keep same with the Browser.MAX_HISTORY_COUNT.
-        final int MAX_HISTORY_COUNT = 250;
-        final String bookmarkUrl = "www.visited-bookmark.com";
-        final String historyUrlPrefix = "www.visited-history";
-        final String historyUrlPostfix = ".com";
-        final long TIME_BASE = new Date().getTime() - 1000;
-            try {
-            assertFalse(Browser.canClearHistory(mContentResolver));
-            Browser.clearHistory(mContentResolver);
-            assertFalse(Browser.canClearHistory(mContentResolver));
-
-            // The total number of the history table's rows: MAX_HISTORY_COUNT,
-            // but there is 1 row is a bookmark.
-            // The date of the history is from 1 ~ (MAX_HISTORY_COUNT - 1).
-            ContentValues value = new ContentValues();
-            for (int i = 1; i <= MAX_HISTORY_COUNT - 1; i++) {
-                value.put(BookmarkColumns.URL, historyUrlPrefix + i + historyUrlPostfix);
-                value.put(BookmarkColumns.BOOKMARK, 0);
-                value.put(BookmarkColumns.DATE, i + TIME_BASE);
-                mProvider.insert(Browser.BOOKMARKS_URI, value);
-            }
-            value.put(BookmarkColumns.URL, bookmarkUrl);
-            value.put(BookmarkColumns.BOOKMARK, 1);
-            value.put(BookmarkColumns.VISITS, 5);
-            value.put(BookmarkColumns.DATE, new Date().getTime());
-            mProvider.insert(Browser.BOOKMARKS_URI, value);
-            value.clear();
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    null, null, null, null);
-            assertEquals(MAX_HISTORY_COUNT, cursor.getCount());
-            cursor.close();
-            Browser.truncateHistory(mContentResolver);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    null, null, null, null);
-            assertEquals(MAX_HISTORY_COUNT, cursor.getCount());
-            cursor.close();
-
-            // Add more one history which is not a bookmark,
-            // then the history rows except bookmark is MAX_HISTORY_COUNT.
-            value.put(BookmarkColumns.URL, historyUrlPrefix
-                    + MAX_HISTORY_COUNT + historyUrlPostfix);
-            value.put(BookmarkColumns.BOOKMARK, 0);
-            value.put(BookmarkColumns.DATE, MAX_HISTORY_COUNT + TIME_BASE);
-            mProvider.insert(Browser.BOOKMARKS_URI, value);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    null, null, null, null);
-            assertEquals(MAX_HISTORY_COUNT + 1, cursor.getCount());
-            cursor.close();
-            Browser.truncateHistory(mContentResolver);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    null, null, null, null);
-            assertEquals(MAX_HISTORY_COUNT + 1 - Browser.TRUNCATE_N_OLDEST, cursor.getCount());
-            cursor.moveToFirst();
-            assertEquals(Browser.TRUNCATE_N_OLDEST + 1 + TIME_BASE,
-                    cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX));
-            cursor.close();
-
-            // Delete specified history
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    BookmarkColumns.BOOKMARK + " = 0",
-                    null, BookmarkColumns.DATE, null);
-            int historyCountBeforeDelete = cursor.getCount();
-            cursor.moveToLast();
-            assertEquals(MAX_HISTORY_COUNT + TIME_BASE,
-                    cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX));
-            cursor.close();
-            Browser.deleteFromHistory(mContentResolver,
-                    historyUrlPrefix + MAX_HISTORY_COUNT + historyUrlPostfix);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    BookmarkColumns.BOOKMARK + " = 0",
-                    null, BookmarkColumns.DATE, null);
-            int historyCountAfterDelete = cursor.getCount();
-            assertEquals(historyCountBeforeDelete - 1, historyCountAfterDelete);
-            cursor.moveToLast();
-            assertEquals(MAX_HISTORY_COUNT - 1 + TIME_BASE,
-                    cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX));
-            cursor.close();
-
-            // Specify a url which is not existed in current table.
-            historyCountBeforeDelete = historyCountAfterDelete;
-            Browser.deleteFromHistory(mContentResolver, "delete a not-existed url");
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    BookmarkColumns.BOOKMARK + " = 0",
-                    null, BookmarkColumns.DATE, null);
-            historyCountAfterDelete = cursor.getCount();
-            assertEquals(historyCountBeforeDelete, historyCountAfterDelete);
-            cursor.close();
-
-            // Specify the history in a time frame to be deleted
-            historyCountBeforeDelete = historyCountAfterDelete;
-            long begin = 6 + TIME_BASE;
-            long end = 20 + TIME_BASE;
-            Browser.deleteHistoryTimeFrame(mContentResolver, begin, end);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    BookmarkColumns.BOOKMARK + " = 0",
-                    null, BookmarkColumns.DATE, null);
-            historyCountAfterDelete = cursor.getCount();
-            assertEquals(historyCountBeforeDelete - (end - begin), historyCountAfterDelete);
-            cursor.moveToFirst();
-            assertEquals(end, cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX));
-            cursor.close();
-
-            // Specify the history in a time frame (not specify begin) to be deleted.
-            historyCountBeforeDelete = historyCountAfterDelete;
-            long firstDate = end;
-            begin = -1;
-            end = 34 + TIME_BASE;
-            Browser.deleteHistoryTimeFrame(mContentResolver, begin, end);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    BookmarkColumns.BOOKMARK + " = 0",
-                    null, BookmarkColumns.DATE, null);
-            historyCountAfterDelete = cursor.getCount();
-            assertEquals(historyCountBeforeDelete - (end - firstDate), historyCountAfterDelete);
-            cursor.moveToFirst();
-            assertEquals(end, cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX));
-            cursor.moveToLast();
-            long lastDate = cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX);
-            cursor.close();
-
-            // Specify the history in a time frame (not specify end) to be deleted.
-            historyCountBeforeDelete = historyCountAfterDelete;
-            begin = MAX_HISTORY_COUNT - 10 + TIME_BASE;
-            end = -1;
-            Browser.deleteHistoryTimeFrame(mContentResolver, begin, end);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    BookmarkColumns.BOOKMARK + " = 0",
-                    null, BookmarkColumns.DATE, null);
-            historyCountAfterDelete = cursor.getCount();
-            assertEquals(historyCountBeforeDelete - (lastDate - begin + 1),
-                    historyCountAfterDelete);
-            cursor.moveToLast();
-            assertEquals(begin - 1, cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX));
-            cursor.close();
-
-            // Clear all history.
-            assertTrue(Browser.canClearHistory(mContentResolver));
-            Browser.clearHistory(mContentResolver);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    Browser.HISTORY_PROJECTION,
-                    null, null, BookmarkColumns.DATE, null);
-            assertEquals(1, cursor.getCount());
-            cursor.moveToFirst();
-            assertEquals(bookmarkUrl, cursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX));
-            assertEquals(0, cursor.getInt(Browser.HISTORY_PROJECTION_VISITS_INDEX));
-            assertEquals(0, cursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX));
-            cursor.close();
-            assertFalse(Browser.canClearHistory(mContentResolver));
-        } catch (RemoteException e) {
-            fail("unexpected RemoteException");
-        }
-    }
-
-    public void testRequestAllIcons() {
-        Browser.requestAllIcons(mContentResolver, null, null);
-    }
-
-    public void testSaveBookmark() {
-        // TODO: send KEYCODE_DPAD_CENTER to skip the resolve page, but no effect.
-//        assertFalse(isRunning(ADD_BOOKMARK_CLASS_NAME));
-//        Browser.saveBookmark(mActivity, "bookmark title", "www.bookmark.com");
-//        try {
-//            Thread.sleep(2000);
-//        } catch (InterruptedException e) {
-//            e.printStackTrace();
-//        }
-//        getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_DPAD_CENTER);
-//        assertStarted(ADD_BOOKMARK_CLASS_NAME, 6000);
-
-        // TODO: how to finish the activity.
-    }
-
-    public void testSendString() {
-        // assertFalse(isRunning(COMPOSE_MESSAGE_CLASS_NAME));
-        // Browser.sendString(mActivity, "string to be sent");
-        // assertStarted(COMPOSE_MESSAGE_CLASS_NAME, 5000);
-
-        // TODO: how to finish the activity.
-    }
-
-    private boolean isRunning(String className) {
-        ActivityManager activityManager = (ActivityManager) mActivity
-                .getSystemService(Context.ACTIVITY_SERVICE);
-        List<RunningTaskInfo> list = activityManager.getRunningTasks(1);
-        RunningTaskInfo info = list.get(0);
-        if (null == info || null == info.topActivity) {
-            return false;
-        }
-
-        if (className.equals(info.topActivity.getClassName())) {
-            return true;
-        }
-
-        return false;
-    }
-
-    private void assertStarted(String className, long timeout) {
-        final long timeSlice = 200;
-        while (timeout > 0) {
-            try {
-                Thread.sleep(timeSlice);
-            } catch (InterruptedException e) {
-                fail("unexpected InterruptedException");
-            }
-            if (isRunning(className)) {
-                return;
-            }
-            timeout -= timeSlice;
-        }
-        fail("has not started BrowserActivity yet");
-    }
-
-    /**
-     * Test case just for the actual content provider behavior on Bookmarks table.
-     * It does not test any APIs in android.provider.Browser.java, so we cannot add
-     * annotation for it.
-     */
-    public void testBookmarksTable() {
-        final String[] BOOKMARKS_PROJECTION = new String[] {
-                BookmarkColumns._ID, BookmarkColumns.URL, BookmarkColumns.VISITS,
-                BookmarkColumns.DATE, BookmarkColumns.CREATED, BookmarkColumns.BOOKMARK,
-                BookmarkColumns.TITLE, BookmarkColumns.FAVICON };
-        final int ID_INDEX = 0;
-        final int URL_INDEX = 1;
-        final int VISITS_INDEX = 2;
-        final int DATE_INDEX = 3;
-        final int CREATED_INDEX = 4;
-        final int BOOKMARK_INDEX = 5;
-        final int TITLE_INDEX = 6;
-        final int FAVICON_INDEX = 7;
-
-        String insertBookmarkTitle = "bookmark_insert";
-        String insertBookmarkUrl = "www.bookmark_insert.com";
-
-        String updateBookmarkTitle = "bookmark_update";
-        String updateBookmarkUrl = "www.bookmark_update.com";
-        try {
-            // Test: insert
-            ContentValues value = new ContentValues();
-            long createDate = new Date().getTime();
-            value.put(BookmarkColumns.TITLE, insertBookmarkTitle);
-            value.put(BookmarkColumns.URL, insertBookmarkUrl);
-            value.put(BookmarkColumns.VISITS, 0);
-            value.put(BookmarkColumns.DATE, createDate);
-            value.put(BookmarkColumns.CREATED, createDate);
-            value.put(BookmarkColumns.BOOKMARK, 0);
-
-            Uri insertUri = mProvider.insert(Browser.BOOKMARKS_URI, value);
-            Cursor cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    BOOKMARKS_PROJECTION,
-                    BookmarkColumns.TITLE + " = ?",
-                    new String[] {insertBookmarkTitle},
-                    BookmarkColumns.DATE, null);
-            assertTrue(cursor.moveToNext());
-            assertEquals(insertBookmarkTitle, cursor.getString(TITLE_INDEX));
-            assertEquals(insertBookmarkUrl,cursor.getString(URL_INDEX));
-            assertEquals(0,cursor.getInt(VISITS_INDEX));
-            assertEquals(createDate, cursor.getLong(DATE_INDEX));
-            assertEquals(createDate, cursor.getLong(CREATED_INDEX));
-            assertEquals(0, cursor.getInt(BOOKMARK_INDEX));
-            assertNull(cursor.getBlob(FAVICON_INDEX));
-            int Id = cursor.getInt(ID_INDEX);
-            cursor.close();
-
-            // Test: update
-            value.clear();
-            long updateDate = new Date().getTime();
-            value.put(BookmarkColumns.TITLE, updateBookmarkTitle);
-            value.put(BookmarkColumns.URL, updateBookmarkUrl);
-            value.put(BookmarkColumns.VISITS, 1);
-            value.put(BookmarkColumns.DATE, updateDate);
-
-            mProvider.update(Browser.BOOKMARKS_URI, value,
-                    BookmarkColumns.TITLE + " = ?",
-                    new String[] {insertBookmarkTitle});
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    BOOKMARKS_PROJECTION,
-                    BookmarkColumns._ID + " = " + Id,
-                    null, null, null);
-            assertTrue(cursor.moveToNext());
-            assertEquals(updateBookmarkTitle, cursor.getString(TITLE_INDEX));
-            assertEquals(updateBookmarkUrl,cursor.getString(URL_INDEX));
-            assertEquals(1,cursor.getInt(VISITS_INDEX));
-            assertEquals(updateDate, cursor.getLong(DATE_INDEX));
-            assertEquals(createDate, cursor.getLong(CREATED_INDEX));
-            assertEquals(0, cursor.getInt(BOOKMARK_INDEX));
-            assertNull(cursor.getBlob(FAVICON_INDEX));
-            assertEquals(Id, cursor.getInt(ID_INDEX));
-
-            // Test: delete
-            mProvider.delete(insertUri, null, null);
-            cursor = mProvider.query(
-                    Browser.BOOKMARKS_URI,
-                    BOOKMARKS_PROJECTION,
-                    BookmarkColumns._ID + " = " + Id,
-                    null, null, null);
-            assertEquals(0, cursor.getCount());
-        } catch (RemoteException e) {
-            fail("Unexpected RemoteException");
-        }
-    }
-
-    /**
-     * Test case just for the actual content provider behavior on Searches table.
-     * It does not test any APIs in android.provider.Browser.java, so we cannot add
-     * annotation for it.
-     */
-    public void testSearchesTable() {
-        final int ID_INDEX = 0;
-        String insertSearch = "search_insert";
-        String updateSearch = "search_update";
-
-        try {
-            // Test: insert
-            ContentValues value = new ContentValues();
-            long createDate = new Date().getTime();
-            value.put(SearchColumns.SEARCH, insertSearch);
-            value.put(SearchColumns.DATE, createDate);
-
-            Uri insertUri = mProvider.insert(Browser.SEARCHES_URI, value);
-            Cursor cursor = mProvider.query(Browser.SEARCHES_URI,
-                    Browser.SEARCHES_PROJECTION, SearchColumns.SEARCH + " = ?",
-                    new String[] {insertSearch}, null, null);
-            assertTrue(cursor.moveToNext());
-            assertEquals(insertSearch,
-                    cursor.getString(Browser.SEARCHES_PROJECTION_SEARCH_INDEX));
-            assertEquals(createDate,
-                    cursor.getLong(Browser.SEARCHES_PROJECTION_DATE_INDEX));
-            int Id = cursor.getInt(ID_INDEX);
-            cursor.close();
-
-            // Test: update
-            value.clear();
-            long updateDate = new Date().getTime();
-            value.put(SearchColumns.SEARCH, updateSearch);
-            value.put(SearchColumns.DATE, updateDate);
-
-            mProvider.update(Browser.SEARCHES_URI, value,
-                    SearchColumns._ID + " = " + Id, null);
-            cursor = mProvider.query(Browser.SEARCHES_URI,
-                    Browser.SEARCHES_PROJECTION,
-                    SearchColumns._ID + " = " + Id, null, null, null);
-            assertTrue(cursor.moveToNext());
-            assertEquals(updateSearch,
-                    cursor.getString(Browser.SEARCHES_PROJECTION_SEARCH_INDEX));
-            assertEquals(updateDate,
-                    cursor.getLong(Browser.SEARCHES_PROJECTION_DATE_INDEX));
-            assertEquals(Id, cursor.getInt(ID_INDEX));
-
-            // Test: delete
-            mProvider.delete(insertUri, null, null);
-            cursor = mProvider.query(Browser.SEARCHES_URI,
-                    Browser.SEARCHES_PROJECTION,
-                    SearchColumns._ID + " = " + Id, null, null, null);
-            assertEquals(0, cursor.getCount());
-        } catch (RemoteException e) {
-            fail("Unexpected RemoteException");
-        }
-    }
-}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_AggregationSuggestionsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_AggregationSuggestionsTest.java
new file mode 100644
index 0000000..64c1a66
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_AggregationSuggestionsTest.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.Contacts.AggregationSuggestions;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
+import android.provider.cts.contacts.DatabaseAsserts;
+import android.test.AndroidTestCase;
+
+/**
+ * CTS tests for {@link android.provider.ContactsContract.Contacts.AggregationSuggestions} APIs.
+ */
+public class ContactsContract_AggregationSuggestionsTest extends AndroidTestCase {
+    private static final String[] TEST_PROJECTION
+            = new String[] {Contacts.DISPLAY_NAME, Contacts._ID};
+
+    private ContentResolver mResolver;
+    private ContactsContract_TestDataBuilder mBuilder;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mResolver = getContext().getContentResolver();
+        ContentProviderClient provider =
+                mResolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
+        mBuilder = new ContactsContract_TestDataBuilder(provider);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mBuilder.cleanup();
+    }
+
+    // Copy of CP2's ContactAggregatorTest#testAggregationSuggestionsByName unit test.
+    public void testAggregationSuggestionsByNameReversed() throws Exception {
+        long [] contactIds = setupThreeContacts();
+
+        // Setup: create query with first and last name reversed.
+        Uri uri = AggregationSuggestions.builder()
+                .addNameParameter("last1 first1")
+                .build();
+
+        // Execute
+        Cursor cursor = mResolver.query(uri, TEST_PROJECTION, null, null, null);
+
+        // Verify: correct contact is returned.
+        assertEquals(1, cursor.getCount());
+        cursor.moveToFirst();
+        ContentValues values = new ContentValues();
+        values.put(Contacts._ID, contactIds[0]);
+        values.put(Contacts.DISPLAY_NAME, "first1 last1");
+        DatabaseAsserts.assertCursorValuesMatchExactly(cursor, values);
+        cursor.close();
+    }
+
+
+    public void testAggregationSuggestionsByName() throws Exception {
+        long [] contactIds = setupThreeContacts();
+
+        // Setup: create query with first and last name in same order as display name.
+        Uri uri = AggregationSuggestions.builder()
+                .addNameParameter("first1 last1")
+                .build();
+
+        // Execute
+        Cursor cursor = mResolver.query(uri, TEST_PROJECTION, null, null, null);
+
+        // Verify: correct contact is returned.
+        assertEquals(1, cursor.getCount());
+        cursor.moveToFirst();
+        ContentValues values = new ContentValues();
+        values.put(Contacts._ID, contactIds[0]);
+        values.put(Contacts.DISPLAY_NAME, "first1 last1");
+        DatabaseAsserts.assertCursorValuesMatchExactly(cursor, values);
+        cursor.close();
+    }
+
+    public void testAggregationSuggestionsByName_noMatch() throws Exception {
+        setupThreeContacts();
+
+        // Setup: query with name that is completely different than all the contacts.
+        Uri uri = AggregationSuggestions.builder()
+                .addNameParameter("unmatched name")
+                .build();
+
+        // Execute
+        Cursor cursor = mResolver.query(
+                uri, new String[] { Contacts._ID, Contacts.DISPLAY_NAME }, null, null, null);
+
+        // Verify: no matches.
+        assertEquals(0, cursor.getCount());
+    }
+
+    public void testAggregationSuggestionsByName_matchSecondNameParameter() throws Exception {
+        long [] contactIds = setupThreeContacts();
+
+        // Setup: query with two names. The first name is completely unlike all the contacts.
+        Uri uri = AggregationSuggestions.builder()
+                .addNameParameter("unmatched name")
+                .addNameParameter("first2 last2")
+                .build();
+
+        // Execute
+        Cursor cursor = mResolver.query(uri, TEST_PROJECTION, null, null, null);
+
+        // Verify: the second name parameter matches a contact.
+        assertEquals(1, cursor.getCount());
+        ContentValues values = new ContentValues();
+        values.put(Contacts._ID, contactIds[1]);
+        values.put(Contacts.DISPLAY_NAME, "first2 last2");
+        DatabaseAsserts.assertCursorValuesMatchExactly(cursor, values);
+        cursor.close();
+    }
+
+    public void testAggregationSuggestionsByName_matchFirstNameParameter() throws Exception {
+        long [] contactIds = setupThreeContacts();
+
+        // Setup: query with two names. The second name is completely unlike all the contacts.
+        Uri uri = AggregationSuggestions.builder()
+                .addNameParameter("first2 last2")
+                .addNameParameter("unmatched name")
+                .build();
+
+        // Execute
+        Cursor cursor = mResolver.query(uri, TEST_PROJECTION, null, null, null);
+
+        // Verify: the first name parameter matches a contact.
+        assertEquals(1, cursor.getCount());
+        ContentValues values = new ContentValues();
+        values.put(Contacts._ID, contactIds[1]);
+        values.put(Contacts.DISPLAY_NAME, "first2 last2");
+        DatabaseAsserts.assertCursorValuesMatchExactly(cursor, values);
+        cursor.close();
+    }
+
+    private long[] setupThreeContacts() throws Exception {
+        TestRawContact rawContact1 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "first1")
+                .with(StructuredName.FAMILY_NAME, "last1")
+                .insert();
+        rawContact1.load();
+
+        TestRawContact rawContact2 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        rawContact2.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "first2")
+                .with(StructuredName.FAMILY_NAME, "last2")
+                .insert();
+        rawContact2.load();
+
+        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.GIVEN_NAME, "completely")
+                .with(StructuredName.FAMILY_NAME, "different")
+                .insert();
+        rawContact3.load();
+
+        return new long[] {rawContact1.getContactId(),
+                rawContact2.getContactId(), rawContact3.getContactId()};
+    }
+
+    public void testAggregationSuggestionsQueryBuilderWithContactId() throws Exception {
+        Uri uri = new AggregationSuggestions.Builder().setContactId(12).setLimit(7).build();
+        assertEquals("content://com.android.contacts/contacts/12/suggestions?limit=7",
+                uri.toString());
+    }
+
+    public void testAggregationSuggestionsQueryBuilderWithValues() throws Exception {
+        Uri uri = new AggregationSuggestions.Builder()
+                .addNameParameter("name1")
+                .addNameParameter("name2")
+                .setLimit(7)
+                .build();
+        assertEquals("content://com.android.contacts/contacts/0/suggestions?"
+                + "limit=7"
+                + "&query=name%3Aname1"
+                + "&query=name%3Aname2", uri.toString());
+    }
+}
+
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java
index 006f4df..f8f610a 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_ContactsTest.java
@@ -27,6 +27,7 @@
 import android.net.Uri;
 import android.os.SystemClock;
 import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.Contacts;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
@@ -101,6 +102,12 @@
         assertEquals(ContentUris.withAppendedId(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,
                 lookupKey), contactId), lookupUri);
 
+        Uri nullLookupUri = Contacts.getLookupUri(contactId, null);
+        assertNull(nullLookupUri);
+
+        Uri emptyLookupUri = Contacts.getLookupUri(contactId, "");
+        assertNull(emptyLookupUri);
+
         Uri lookupUri2 = Contacts.getLookupUri(mResolver, contactUri);
         assertEquals(lookupUri, lookupUri2);
 
@@ -161,6 +168,74 @@
         RawContactUtil.delete(mResolver, ids.mRawContactId, true);
     }
 
+    public void testProjection() throws Exception {
+        final TestRawContact rawContact = mBuilder.newRawContact().insert().load();
+        rawContact.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "xxx")
+                .insert();
+
+        final TestContact contact = rawContact.getContact().load();
+        final long contactId = contact.getId();
+        final String lookupKey = contact.getString(Contacts.LOOKUP_KEY);
+
+        final String[] PROJECTION = new String[]{
+                Contacts._ID,
+                Contacts.DISPLAY_NAME,
+                Contacts.DISPLAY_NAME_PRIMARY,
+                Contacts.DISPLAY_NAME_ALTERNATIVE,
+                Contacts.DISPLAY_NAME_SOURCE,
+                Contacts.PHONETIC_NAME,
+                Contacts.PHONETIC_NAME_STYLE,
+                Contacts.SORT_KEY_PRIMARY,
+                Contacts.SORT_KEY_ALTERNATIVE,
+                Contacts.LAST_TIME_CONTACTED,
+                Contacts.TIMES_CONTACTED,
+                Contacts.STARRED,
+                Contacts.PINNED,
+                Contacts.IN_DEFAULT_DIRECTORY,
+                Contacts.IN_VISIBLE_GROUP,
+                Contacts.PHOTO_ID,
+                Contacts.PHOTO_FILE_ID,
+                Contacts.PHOTO_URI,
+                Contacts.PHOTO_THUMBNAIL_URI,
+                Contacts.CUSTOM_RINGTONE,
+                Contacts.HAS_PHONE_NUMBER,
+                Contacts.SEND_TO_VOICEMAIL,
+                Contacts.IS_USER_PROFILE,
+                Contacts.LOOKUP_KEY,
+                Contacts.NAME_RAW_CONTACT_ID,
+                Contacts.CONTACT_PRESENCE,
+                Contacts.CONTACT_CHAT_CAPABILITY,
+                Contacts.CONTACT_STATUS,
+                Contacts.CONTACT_STATUS_TIMESTAMP,
+                Contacts.CONTACT_STATUS_RES_PACKAGE,
+                Contacts.CONTACT_STATUS_LABEL,
+                Contacts.CONTACT_STATUS_ICON,
+                Contacts.CONTACT_LAST_UPDATED_TIMESTAMP
+        };
+
+        // Contacts.CONTENT_URI
+        DatabaseAsserts.checkProjection(mResolver,
+                Contacts.CONTENT_URI,
+                PROJECTION,
+                new long[]{contact.getId()}
+        );
+
+        // Contacts.CONTENT_FILTER_URI
+        DatabaseAsserts.checkProjection(mResolver,
+                Contacts.CONTENT_FILTER_URI.buildUpon().appendEncodedPath("xxx").build(),
+                PROJECTION,
+                new long[]{contact.getId()}
+        );
+
+        // Contacts.CONTENT_LOOKUP_URI
+        DatabaseAsserts.checkProjection(mResolver,
+                Contacts.getLookupUri(contactId, lookupKey),
+                PROJECTION,
+                new long[]{contact.getId()}
+        );
+    }
+
     /**
      * Create a contact.  Delete it.  And assert that the contact record is no longer present.
      *
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java
index 91436a3..33d3a28 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_DataTest.java
@@ -22,20 +22,22 @@
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentValues;
-import android.database.Cursor;
 import android.net.Uri;
 import android.os.SystemClock;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Callable;
 import android.provider.ContactsContract.CommonDataKinds.Contactables;
 import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.CommonDataKinds.Organization;
 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.Contacts.Entity;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
+import android.provider.ContactsContract.RawContactsEntity;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestData;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
@@ -51,6 +53,90 @@
     private ContentResolver mResolver;
     private ContactsContract_TestDataBuilder mBuilder;
 
+    static final String[] DATA_PROJECTION = new String[]{
+            Data._ID,
+            Data.RAW_CONTACT_ID,
+            Data.CONTACT_ID,
+            Data.NAME_RAW_CONTACT_ID,
+            RawContacts.RAW_CONTACT_IS_USER_PROFILE,
+            Data.DATA1,
+            Data.DATA2,
+            Data.DATA3,
+            Data.DATA4,
+            Data.DATA5,
+            Data.DATA6,
+            Data.DATA7,
+            Data.DATA8,
+            Data.DATA9,
+            Data.DATA10,
+            Data.DATA11,
+            Data.DATA12,
+            Data.DATA13,
+            Data.DATA14,
+            Data.DATA15,
+            Data.CARRIER_PRESENCE,
+            Data.DATA_VERSION,
+            Data.IS_PRIMARY,
+            Data.IS_SUPER_PRIMARY,
+            Data.MIMETYPE,
+            Data.RES_PACKAGE,
+            Data.SYNC1,
+            Data.SYNC2,
+            Data.SYNC3,
+            Data.SYNC4,
+            GroupMembership.GROUP_SOURCE_ID,
+            Data.PRESENCE,
+            Data.CHAT_CAPABILITY,
+            Data.STATUS,
+            Data.STATUS_TIMESTAMP,
+            Data.STATUS_RES_PACKAGE,
+            Data.STATUS_LABEL,
+            Data.STATUS_ICON,
+            RawContacts.ACCOUNT_NAME,
+            RawContacts.ACCOUNT_TYPE,
+            RawContacts.DATA_SET,
+            RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
+            RawContacts.DIRTY,
+            RawContacts.SOURCE_ID,
+            RawContacts.VERSION,
+            Contacts.CUSTOM_RINGTONE,
+            Contacts.DISPLAY_NAME,
+            Contacts.DISPLAY_NAME_ALTERNATIVE,
+            Contacts.DISPLAY_NAME_SOURCE,
+            Contacts.IN_DEFAULT_DIRECTORY,
+            Contacts.IN_VISIBLE_GROUP,
+            Contacts.LAST_TIME_CONTACTED,
+            Contacts.LOOKUP_KEY,
+            Contacts.PHONETIC_NAME,
+            Contacts.PHONETIC_NAME_STYLE,
+            Contacts.PHOTO_ID,
+            Contacts.PHOTO_FILE_ID,
+            Contacts.PHOTO_URI,
+            Contacts.PHOTO_THUMBNAIL_URI,
+            Contacts.SEND_TO_VOICEMAIL,
+            Contacts.SORT_KEY_ALTERNATIVE,
+            Contacts.SORT_KEY_PRIMARY,
+            Contacts.STARRED,
+            Contacts.PINNED,
+            Contacts.TIMES_CONTACTED,
+            Contacts.HAS_PHONE_NUMBER,
+            Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
+            Contacts.CONTACT_PRESENCE,
+            Contacts.CONTACT_CHAT_CAPABILITY,
+            Contacts.CONTACT_STATUS,
+            Contacts.CONTACT_STATUS_TIMESTAMP,
+            Contacts.CONTACT_STATUS_RES_PACKAGE,
+            Contacts.CONTACT_STATUS_LABEL,
+            Contacts.CONTACT_STATUS_ICON,
+            Data.TIMES_USED,
+            Data.LAST_TIME_USED};
+
+    static final String[] RAW_CONTACTS_ENTITY_PROJECTION = new String[]{
+    };
+
+    static final String[] NTITY_PROJECTION = new String[]{
+    };
+
     private static ContentValues[] sContentValues = new ContentValues[7];
     static {
         ContentValues cv1 = new ContentValues();
@@ -141,6 +227,184 @@
                 lookupContact.getId(), data.load().getRawContact().load().getContactId());
     }
 
+    public void testDataProjection() throws Exception {
+        TestRawContact rawContact = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_type")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .with(RawContacts.SOURCE_ID, "source_id")
+                .insert();
+        TestData data = rawContact.newDataRow(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
+                .with(CommonDataKinds.StructuredName.DISPLAY_NAME, "test name")
+                .insert();
+
+        DatabaseAsserts.checkProjection(mResolver, Data.CONTENT_URI,
+                DATA_PROJECTION,
+                new long[]{data.load().getId()}
+        );
+    }
+
+    public void testRawContactsEntityProjection() throws Exception {
+        TestRawContact rawContact = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_type")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .with(RawContacts.SOURCE_ID, "source_id")
+                .insert();
+        TestData data = rawContact.newDataRow(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
+                .with(CommonDataKinds.StructuredName.DISPLAY_NAME, "test name")
+                .insert();
+
+        DatabaseAsserts.checkProjection(mResolver, RawContactsEntity.CONTENT_URI,
+                new String[]{
+                        RawContacts._ID,
+                        RawContacts.CONTACT_ID,
+                        RawContacts.Entity.DATA_ID,
+                        RawContacts.DELETED,
+                        RawContacts.STARRED,
+                        RawContacts.RAW_CONTACT_IS_USER_PROFILE,
+                        RawContacts.ACCOUNT_NAME,
+                        RawContacts.ACCOUNT_TYPE,
+                        RawContacts.DATA_SET,
+                        RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
+                        RawContacts.DIRTY,
+                        RawContacts.SOURCE_ID,
+                        RawContacts.BACKUP_ID,
+                        RawContacts.VERSION,
+                        RawContacts.SYNC1,
+                        RawContacts.SYNC2,
+                        RawContacts.SYNC3,
+                        RawContacts.SYNC4,
+                        Data.DATA1,
+                        Data.DATA2,
+                        Data.DATA3,
+                        Data.DATA4,
+                        Data.DATA5,
+                        Data.DATA6,
+                        Data.DATA7,
+                        Data.DATA8,
+                        Data.DATA9,
+                        Data.DATA10,
+                        Data.DATA11,
+                        Data.DATA12,
+                        Data.DATA13,
+                        Data.DATA14,
+                        Data.DATA15,
+                        Data.CARRIER_PRESENCE,
+                        Data.DATA_VERSION,
+                        Data.IS_PRIMARY,
+                        Data.IS_SUPER_PRIMARY,
+                        Data.MIMETYPE,
+                        Data.RES_PACKAGE,
+                        Data.SYNC1,
+                        Data.SYNC2,
+                        Data.SYNC3,
+                        Data.SYNC4,
+                        GroupMembership.GROUP_SOURCE_ID},
+                new long[]{rawContact.getId()}
+        );
+    }
+
+    public void testEntityProjection() throws Exception {
+        TestRawContact rawContact = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_type")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .with(RawContacts.SOURCE_ID, "source_id")
+                .insert();
+        TestData data = rawContact.newDataRow(CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
+                .with(CommonDataKinds.StructuredName.DISPLAY_NAME, "test name")
+                .insert();
+        long contactId = rawContact.load().getContactId();
+
+        DatabaseAsserts.checkProjection(mResolver, Contacts.CONTENT_URI.buildUpon().appendPath(
+                        String.valueOf(contactId)).appendPath(
+                        Entity.CONTENT_DIRECTORY).build(),
+                new String[]{
+                        Contacts.Entity._ID,
+                        Contacts.Entity.CONTACT_ID,
+                        Contacts.Entity.RAW_CONTACT_ID,
+                        Contacts.Entity.DATA_ID,
+                        Contacts.Entity.NAME_RAW_CONTACT_ID,
+                        Contacts.Entity.DELETED,
+                        Contacts.IS_USER_PROFILE,
+                        Contacts.CUSTOM_RINGTONE,
+                        Contacts.DISPLAY_NAME,
+                        Contacts.DISPLAY_NAME_ALTERNATIVE,
+                        Contacts.DISPLAY_NAME_SOURCE,
+                        Contacts.IN_DEFAULT_DIRECTORY,
+                        Contacts.IN_VISIBLE_GROUP,
+                        Contacts.LAST_TIME_CONTACTED,
+                        Contacts.LOOKUP_KEY,
+                        Contacts.PHONETIC_NAME,
+                        Contacts.PHONETIC_NAME_STYLE,
+                        Contacts.PHOTO_ID,
+                        Contacts.PHOTO_FILE_ID,
+                        Contacts.PHOTO_URI,
+                        Contacts.PHOTO_THUMBNAIL_URI,
+                        Contacts.SEND_TO_VOICEMAIL,
+                        Contacts.SORT_KEY_ALTERNATIVE,
+                        Contacts.SORT_KEY_PRIMARY,
+                        Contacts.STARRED,
+                        Contacts.PINNED,
+                        Contacts.TIMES_CONTACTED,
+                        Contacts.HAS_PHONE_NUMBER,
+                        Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
+                        Contacts.CONTACT_PRESENCE,
+                        Contacts.CONTACT_CHAT_CAPABILITY,
+                        Contacts.CONTACT_STATUS,
+                        Contacts.CONTACT_STATUS_TIMESTAMP,
+                        Contacts.CONTACT_STATUS_RES_PACKAGE,
+                        Contacts.CONTACT_STATUS_LABEL,
+                        Contacts.CONTACT_STATUS_ICON,
+                        RawContacts.ACCOUNT_NAME,
+                        RawContacts.ACCOUNT_TYPE,
+                        RawContacts.DATA_SET,
+                        RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
+                        RawContacts.DIRTY,
+                        RawContacts.SOURCE_ID,
+                        RawContacts.BACKUP_ID,
+                        RawContacts.VERSION,
+                        RawContacts.SYNC1,
+                        RawContacts.SYNC2,
+                        RawContacts.SYNC3,
+                        RawContacts.SYNC4,
+                        Data.DATA1,
+                        Data.DATA2,
+                        Data.DATA3,
+                        Data.DATA4,
+                        Data.DATA5,
+                        Data.DATA6,
+                        Data.DATA7,
+                        Data.DATA8,
+                        Data.DATA9,
+                        Data.DATA10,
+                        Data.DATA11,
+                        Data.DATA12,
+                        Data.DATA13,
+                        Data.DATA14,
+                        Data.DATA15,
+                        Data.CARRIER_PRESENCE,
+                        Data.DATA_VERSION,
+                        Data.IS_PRIMARY,
+                        Data.IS_SUPER_PRIMARY,
+                        Data.MIMETYPE,
+                        Data.RES_PACKAGE,
+                        Data.SYNC1,
+                        Data.SYNC2,
+                        Data.SYNC3,
+                        Data.SYNC4,
+                        GroupMembership.GROUP_SOURCE_ID,
+                        Data.PRESENCE,
+                        Data.CHAT_CAPABILITY,
+                        Data.STATUS,
+                        Data.STATUS_TIMESTAMP,
+                        Data.STATUS_RES_PACKAGE,
+                        Data.STATUS_LABEL,
+                        Data.STATUS_ICON,
+                        Data.TIMES_USED,
+                        Data.LAST_TIME_USED},
+                new long[]{contactId}
+        );
+    }
+
     public void testGetLookupUriByDisplayName() throws Exception {
         TestRawContact rawContact = mBuilder.newRawContact()
                 .with(RawContacts.ACCOUNT_TYPE, "test_type")
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_FrequentsStrequentsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_FrequentsStrequentsTest.java
index b515550..b52915c 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_FrequentsStrequentsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_FrequentsStrequentsTest.java
@@ -48,6 +48,85 @@
     private ContentResolver mResolver;
     private ContactsContract_TestDataBuilder mBuilder;
 
+    private static final String[] STREQUENT_PROJECTION = new String[]{
+            Contacts._ID,
+            Contacts.HAS_PHONE_NUMBER,
+            Contacts.NAME_RAW_CONTACT_ID,
+            Contacts.IS_USER_PROFILE,
+            Contacts.CUSTOM_RINGTONE,
+            Contacts.DISPLAY_NAME,
+            Contacts.DISPLAY_NAME_ALTERNATIVE,
+            Contacts.DISPLAY_NAME_SOURCE,
+            Contacts.IN_DEFAULT_DIRECTORY,
+            Contacts.IN_VISIBLE_GROUP,
+            Contacts.LAST_TIME_CONTACTED,
+            Contacts.LOOKUP_KEY,
+            Contacts.PHONETIC_NAME,
+            Contacts.PHONETIC_NAME_STYLE,
+            Contacts.PHOTO_ID,
+            Contacts.PHOTO_FILE_ID,
+            Contacts.PHOTO_URI,
+            Contacts.PHOTO_THUMBNAIL_URI,
+            Contacts.SEND_TO_VOICEMAIL,
+            Contacts.SORT_KEY_ALTERNATIVE,
+            Contacts.SORT_KEY_PRIMARY,
+            Contacts.STARRED,
+            Contacts.PINNED,
+            Contacts.TIMES_CONTACTED,
+            Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
+            Contacts.CONTACT_PRESENCE,
+            Contacts.CONTACT_CHAT_CAPABILITY,
+            Contacts.CONTACT_STATUS,
+            Contacts.CONTACT_STATUS_TIMESTAMP,
+            Contacts.CONTACT_STATUS_RES_PACKAGE,
+            Contacts.CONTACT_STATUS_LABEL,
+            Contacts.CONTACT_STATUS_ICON,
+            Data.TIMES_USED,
+            Data.LAST_TIME_USED,
+    };
+
+    private static final String[] STREQUENT_PHONE_ONLY_PROJECTION = new String[]{
+            Data._ID,
+            Contacts.HAS_PHONE_NUMBER,
+            Contacts.NAME_RAW_CONTACT_ID,
+            Contacts.IS_USER_PROFILE,
+            Contacts.CUSTOM_RINGTONE,
+            Contacts.DISPLAY_NAME,
+            Contacts.DISPLAY_NAME_ALTERNATIVE,
+            Contacts.DISPLAY_NAME_SOURCE,
+            Contacts.IN_DEFAULT_DIRECTORY,
+            Contacts.IN_VISIBLE_GROUP,
+            Contacts.LAST_TIME_CONTACTED,
+            Contacts.LOOKUP_KEY,
+            Contacts.PHONETIC_NAME,
+            Contacts.PHONETIC_NAME_STYLE,
+            Contacts.PHOTO_ID,
+            Contacts.PHOTO_FILE_ID,
+            Contacts.PHOTO_URI,
+            Contacts.PHOTO_THUMBNAIL_URI,
+            Contacts.SEND_TO_VOICEMAIL,
+            Contacts.SORT_KEY_ALTERNATIVE,
+            Contacts.SORT_KEY_PRIMARY,
+            Contacts.STARRED,
+            Contacts.PINNED,
+            Contacts.TIMES_CONTACTED,
+            Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
+            Contacts.CONTACT_PRESENCE,
+            Contacts.CONTACT_CHAT_CAPABILITY,
+            Contacts.CONTACT_STATUS,
+            Contacts.CONTACT_STATUS_TIMESTAMP,
+            Contacts.CONTACT_STATUS_RES_PACKAGE,
+            Contacts.CONTACT_STATUS_LABEL,
+            Contacts.CONTACT_STATUS_ICON,
+            Data.TIMES_USED,
+            Data.LAST_TIME_USED,
+            Phone.NUMBER,
+            Phone.TYPE,
+            Phone.LABEL,
+            Phone.IS_SUPER_PRIMARY,
+            Phone.CONTACT_ID,
+    };
+
     public static ContentValues[] sContentValues = new ContentValues[3];
     static {
         ContentValues cv1 = new ContentValues();
@@ -182,48 +261,18 @@
         starContact(ids[0]);
         markDataAsUsed(mDataIds[2], 1);
 
-        // Construct a uri for phone only favorites.
-        Uri uri = Contacts.CONTENT_STREQUENT_URI;
-
-        DatabaseAsserts.checkProjection(mResolver, uri,
-                new String[]{
-                        Contacts._ID,
-                        Contacts.HAS_PHONE_NUMBER,
-                        Contacts.NAME_RAW_CONTACT_ID,
-                        Contacts.IS_USER_PROFILE,
-                        Contacts.CUSTOM_RINGTONE,
-                        Contacts.DISPLAY_NAME,
-                        Contacts.DISPLAY_NAME_ALTERNATIVE,
-                        Contacts.DISPLAY_NAME_SOURCE,
-                        Contacts.IN_DEFAULT_DIRECTORY,
-                        Contacts.IN_VISIBLE_GROUP,
-                        Contacts.LAST_TIME_CONTACTED,
-                        Contacts.LOOKUP_KEY,
-                        Contacts.PHONETIC_NAME,
-                        Contacts.PHONETIC_NAME_STYLE,
-                        Contacts.PHOTO_ID,
-                        Contacts.PHOTO_FILE_ID,
-                        Contacts.PHOTO_URI,
-                        Contacts.PHOTO_THUMBNAIL_URI,
-                        Contacts.SEND_TO_VOICEMAIL,
-                        Contacts.SORT_KEY_ALTERNATIVE,
-                        Contacts.SORT_KEY_PRIMARY,
-                        Contacts.STARRED,
-                        Contacts.PINNED,
-                        Contacts.TIMES_CONTACTED,
-                        Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
-                        Contacts.CONTACT_PRESENCE,
-                        Contacts.CONTACT_CHAT_CAPABILITY,
-                        Contacts.CONTACT_STATUS,
-                        Contacts.CONTACT_STATUS_TIMESTAMP,
-                        Contacts.CONTACT_STATUS_RES_PACKAGE,
-                        Contacts.CONTACT_STATUS_LABEL,
-                        Contacts.CONTACT_STATUS_ICON,
-                        Data.TIMES_USED,
-                        Data.LAST_TIME_USED,
-                },
+        DatabaseAsserts.checkProjection(mResolver, Contacts.CONTENT_STREQUENT_URI,
+                STREQUENT_PROJECTION,
                 new long[]{ids[0], ids[2]}
         );
+
+        // Strequent filter.
+        DatabaseAsserts.checkProjection(mResolver,
+                Contacts.CONTENT_STREQUENT_FILTER_URI.buildUpon()
+                        .appendEncodedPath("Hot Tamale").build(),
+                STREQUENT_PROJECTION,
+                new long[]{ids[0]}
+        );
     }
 
     public void testStrequents_phoneOnly() throws Exception {
@@ -277,48 +326,8 @@
                 appendQueryParameter(ContactsContract.STREQUENT_PHONE_ONLY, "true").build();
 
         DatabaseAsserts.checkProjection(mResolver, uri,
-                new String[] {
-                        Data._ID,
-                        Contacts.HAS_PHONE_NUMBER,
-                        Contacts.NAME_RAW_CONTACT_ID,
-                        Contacts.IS_USER_PROFILE,
-                        Contacts.CUSTOM_RINGTONE,
-                        Contacts.DISPLAY_NAME,
-                        Contacts.DISPLAY_NAME_ALTERNATIVE,
-                        Contacts.DISPLAY_NAME_SOURCE,
-                        Contacts.IN_DEFAULT_DIRECTORY,
-                        Contacts.IN_VISIBLE_GROUP,
-                        Contacts.LAST_TIME_CONTACTED,
-                        Contacts.LOOKUP_KEY,
-                        Contacts.PHONETIC_NAME,
-                        Contacts.PHONETIC_NAME_STYLE,
-                        Contacts.PHOTO_ID,
-                        Contacts.PHOTO_FILE_ID,
-                        Contacts.PHOTO_URI,
-                        Contacts.PHOTO_THUMBNAIL_URI,
-                        Contacts.SEND_TO_VOICEMAIL,
-                        Contacts.SORT_KEY_ALTERNATIVE,
-                        Contacts.SORT_KEY_PRIMARY,
-                        Contacts.STARRED,
-                        Contacts.PINNED,
-                        Contacts.TIMES_CONTACTED,
-                        Contacts.CONTACT_LAST_UPDATED_TIMESTAMP,
-                        Contacts.CONTACT_PRESENCE,
-                        Contacts.CONTACT_CHAT_CAPABILITY,
-                        Contacts.CONTACT_STATUS,
-                        Contacts.CONTACT_STATUS_TIMESTAMP,
-                        Contacts.CONTACT_STATUS_RES_PACKAGE,
-                        Contacts.CONTACT_STATUS_LABEL,
-                        Contacts.CONTACT_STATUS_ICON,
-                        Data.TIMES_USED,
-                        Data.LAST_TIME_USED,
-                        Phone.NUMBER,
-                        Phone.TYPE,
-                        Phone.LABEL,
-                        Phone.IS_SUPER_PRIMARY,
-                        Phone.CONTACT_ID,
-                },
-                new long[] {mDataIds[0], mDataIds[2]} // Note _id from phone_only is data._id
+                STREQUENT_PHONE_ONLY_PROJECTION,
+                new long[]{mDataIds[0], mDataIds[2]} // Note _id from phone_only is data._id
         );
     }
 
@@ -345,6 +354,17 @@
                 true /* inOrder */, sContentValues[1], sContentValues[2], sContentValues[0]);
     }
 
+    public void testFrequent_projection() throws Exception {
+        long[] ids = setupTestData();
+
+        markDataAsUsed(mDataIds[0], 10);
+
+        DatabaseAsserts.checkProjection(mResolver, Contacts.CONTENT_FREQUENT_URI,
+                STREQUENT_PROJECTION,
+                new long[]{ids[0]}
+        );
+    }
+
     /**
      * Given a uri, performs a query on the contacts provider for that uri and asserts that the
      * cursor returned from the query matches the expected results.
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_IsSuperPrimaryName.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_IsSuperPrimaryName.java
new file mode 100644
index 0000000..603cb619
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_IsSuperPrimaryName.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 junit.framework.Assert;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
+import android.provider.cts.ContactsContract_TestDataBuilder.TestData;
+import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
+import android.test.AndroidTestCase;
+
+/**
+ * CTS tests for the affect that {@link ContactsContract.Data#IS_SUPER_PRIMARY} has on names inside
+ * aggregated contacts. Additionally, this needs to test the affect that aggregating contacts
+ * together has on IS_SUPER_PRIMARY values in order to enforce the desired IS_SUPER_PRIMARY
+ * behavior.
+ */
+public class ContactsContract_IsSuperPrimaryName extends AndroidTestCase {
+
+    private ContentResolver mResolver;
+    private ContactsContract_TestDataBuilder mBuilder;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mResolver = getContext().getContentResolver();
+        ContentProviderClient provider =
+                mResolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
+        mBuilder = new ContactsContract_TestDataBuilder(provider);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mBuilder.cleanup();
+        super.tearDown();
+    }
+
+    public void testIsSuperPrimary_name1SuperPrimary() throws Exception {
+        testInner_displayNameFromIsSuperPrimary(/* isFirstNamePrimary = */ true, "name1", "name2");
+    }
+
+    public void testIsSuperPrimary_name2SuperPrimary() throws Exception {
+        testInner_displayNameFromIsSuperPrimary(/* isFirstNamePrimary = */ false, "name2", "name1");
+    }
+
+    private void testInner_displayNameFromIsSuperPrimary(boolean isFirstNamePrimary,
+            String expectedDisplayName, String otherDisplayName) throws Exception {
+
+        // Setup: two raw contacts. One with a super primary name. One without.
+        TestRawContact rawContact1 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        TestData name1 = rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "name1")
+                .with(StructuredName.IS_SUPER_PRIMARY, isFirstNamePrimary ? 1 : 0)
+                .insert();
+        rawContact1.load();
+        name1.load();
+
+        TestRawContact rawContact2 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        TestData name2 = rawContact2.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "name2")
+                .with(StructuredName.IS_SUPER_PRIMARY, !isFirstNamePrimary ? 1 : 0)
+                .insert();
+        rawContact2.load();
+        name2.load();
+
+        // Execute: aggregate the two raw contacts together
+        setAggregationException(rawContact1.getId(), rawContact2.getId());
+
+        // Sanity check: two contacts are aggregated
+        rawContact1.load();
+        rawContact2.load();
+        Assert.assertEquals(rawContact1.getContactId(), rawContact2.getContactId());
+
+        // Verify: the IS_SUPER_PRIMARY values are maintained after the merge
+        name1.assertColumn(StructuredName.IS_SUPER_PRIMARY, isFirstNamePrimary ? 1 : 0);
+        name2.assertColumn(StructuredName.IS_SUPER_PRIMARY, !isFirstNamePrimary ? 1 : 0);
+
+        // Verify: the display name is taken from the name with is_super_primary
+        TestContact contact = rawContact2.getContact().load();
+        contact.assertColumn(Contacts.DISPLAY_NAME, expectedDisplayName);
+
+        //
+        // Now test what happens when you change IS_SUPER_PRIMARY on an existing contact
+        //
+
+        // Execute: make the non primary name IS_SUPER_PRIMARY
+        TestData nonPrimaryName = !isFirstNamePrimary ? name1 : name2;
+        ContentValues values = new ContentValues();
+        values.put(StructuredName.IS_SUPER_PRIMARY, 1);
+        mResolver.update(nonPrimaryName.getUri(), values, null, null);
+
+        // Verify: the IS_SUPER_PRIMARY values swap
+        name1.load();
+        name2.load();
+        name1.assertColumn(StructuredName.IS_SUPER_PRIMARY, isFirstNamePrimary ? 0 : 1);
+        name2.assertColumn(StructuredName.IS_SUPER_PRIMARY, !isFirstNamePrimary ? 0 : 1);
+
+        // Verify: the display name is taken from the name with is_super_primary
+        contact.load();
+        contact.assertColumn(Contacts.DISPLAY_NAME, otherDisplayName);
+    }
+
+    public void testIsSuperPrimaryName_mergeBothSuperPrimary() throws Exception {
+        // Setup: two raw contacts. Both names are super primary.
+        TestRawContact rawContact1 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        TestData name1 = rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "name1")
+                .with(StructuredName.IS_SUPER_PRIMARY, 1)
+                .insert();
+        rawContact1.load();
+        name1.load();
+
+        TestRawContact rawContact2 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        TestData name2 = rawContact2.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "name2")
+                .with(StructuredName.IS_SUPER_PRIMARY, 1)
+                .insert();
+        rawContact2.load();
+        name2.load();
+
+        // Execute: aggregate the two contacts together
+        setAggregationException(rawContact1.getId(), rawContact2.getId());
+
+        // Sanity check: two contacts are aggregated
+        rawContact1.load();
+        rawContact2.load();
+        Assert.assertEquals(rawContact1.getContactId(), rawContact2.getContactId());
+
+        // Verify: both names are no longer super primary.
+        name1.load();
+        name2.load();
+        name1.assertColumn(StructuredName.IS_SUPER_PRIMARY, 0);
+        name2.assertColumn(StructuredName.IS_SUPER_PRIMARY, 0);
+    }
+
+    private void setAggregationException(long rawContactId1, long rawContactId2) {
+        ContentValues values = new ContentValues();
+        values.put(AggregationExceptions.RAW_CONTACT_ID1, rawContactId1);
+        values.put(AggregationExceptions.RAW_CONTACT_ID2, rawContactId2);
+        values.put(AggregationExceptions.TYPE, AggregationExceptions.TYPE_KEEP_TOGETHER);
+        mResolver.update(AggregationExceptions.CONTENT_URI, values, null, null);
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_PinnedPositionsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_PinnedPositionsTest.java
index 2558c36..e56127b 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_PinnedPositionsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_PinnedPositionsTest.java
@@ -203,9 +203,9 @@
         ContactUtil.setAggregationException(mResolver, AggregationExceptions.TYPE_KEEP_SEPARATE,
             i1.mRawContactId, i4.mRawContactId);
 
-        // Raw contacts should be unpinned after being split, but still starred.
+        // Raw contacts should keep the pinned position after re-grouping, and still starred.
         assertValuesForRawContact(i1.mRawContactId,
-                newContentValues(RawContacts.PINNED, PinnedPositions.UNPINNED, RawContacts.STARRED,
+                newContentValues(RawContacts.PINNED, 1, RawContacts.STARRED,
                         1));
         assertValuesForRawContact(i2.mRawContactId,
                 newContentValues(RawContacts.PINNED, 2, RawContacts.STARRED, 1));
@@ -229,7 +229,7 @@
         final long cId1 = RawContactUtil.queryContactIdByRawContactId(mResolver, i1.mRawContactId);
         final long cId4 = RawContactUtil.queryContactIdByRawContactId(mResolver, i4.mRawContactId);
 
-        assertValuesForContact(cId1, newContentValues(Contacts.PINNED, PinnedPositions.UNPINNED));
+        assertValuesForContact(cId1, newContentValues(Contacts.PINNED, 1));
         assertValuesForContact(i2.mContactId, newContentValues(Contacts.PINNED, 2));
         assertValuesForContact(cId4, newContentValues(Contacts.PINNED, PinnedPositions.UNPINNED));
         assertValuesForContact(i5.mContactId,
@@ -241,7 +241,7 @@
                 i5.mRawContactId, i6.mRawContactId);
 
         // The resulting contact should have a pinned value of 6.
-        assertValuesForContact(cId1, newContentValues(Contacts.PINNED, PinnedPositions.UNPINNED));
+        assertValuesForContact(cId1, newContentValues(Contacts.PINNED, 1));
         assertValuesForContact(i2.mContactId, newContentValues(Contacts.PINNED, 2));
         assertValuesForContact(cId4, newContentValues(Contacts.PINNED, PinnedPositions.UNPINNED));
         assertValuesForContact(i5.mContactId, newContentValues(Contacts.PINNED, 6));
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_ProviderStatus.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_ProviderStatus.java
new file mode 100644
index 0000000..9c38ec0
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_ProviderStatus.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 android.provider.cts;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.ProviderStatus;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
+import android.provider.cts.contacts.DatabaseAsserts;
+import android.test.AndroidTestCase;
+
+/**
+ * CTS tests for {@link android.provider.ContactsContract.ProviderStatus}.
+ *
+ * Unfortunately, we can't check that the value of ProviderStatus equals
+ * {@link ProviderStatus#STATUS_EMPTY} initially. Some carriers pre-install
+ * accounts. As a result, the value STATUS_EMPTY will never be achieved.
+ */
+public class ContactsContract_ProviderStatus extends AndroidTestCase {
+    private ContentResolver mResolver;
+    private ContactsContract_TestDataBuilder mBuilder;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mResolver = getContext().getContentResolver();
+        ContentProviderClient provider =
+                mResolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
+        mBuilder = new ContactsContract_TestDataBuilder(provider);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        mBuilder.cleanup();
+    }
+
+    public void testProviderStatus_addedContacts() throws Exception {
+        // Setup: add a contact to CP2.
+        TestRawContact rawContact1 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "first1")
+                .with(StructuredName.FAMILY_NAME, "last1")
+                .insert();
+
+        // Execute: fetch CP2 status
+        Cursor cursor = mResolver.query(ProviderStatus.CONTENT_URI, null, null, null, null);
+
+        // Verify: CP2 status is normal instead of STATUS_EMPTY.
+        try {
+            assertEquals(1, cursor.getCount());
+            cursor.moveToFirst();
+            ContentValues values = new ContentValues();
+            values.put(ProviderStatus.STATUS, ProviderStatus.STATUS_NORMAL);
+            DatabaseAsserts.assertCursorValuesMatchExactly(cursor, values);
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_QuickContactsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_QuickContactsTest.java
new file mode 100644
index 0000000..79633e7
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_QuickContactsTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.ContentUris;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.Contacts;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.QuickContact;
+import android.test.InstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.view.View;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class ContactsContract_QuickContactsTest extends InstrumentationTestCase {
+
+    final String EXCLUDED_MIME_TYPES[] = {"exclude1", "exclude2"};
+    final String PLAIN_MIME_TYPE = "text/plain";
+    final Uri FAKE_CONTACT_URI = ContentUris.withAppendedId(Contacts.CONTENT_URI, 0);
+
+    @UiThreadTest
+    public void testPrioritizedMimeTypeAndExcludedMimeTypes() throws InterruptedException {
+        final CountDownLatch latch = new CountDownLatch(2);
+        Context context = new ContextWrapper(getInstrumentation().getContext()) {
+            @Override
+            public void startActivity(Intent intent) {
+                testCallback(intent);
+            }
+
+            @Override
+            public void startActivityAsUser(Intent intent, UserHandle user) {
+                testCallback(intent);
+            }
+
+            @Override
+            public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
+                testCallback(intent);
+            }
+
+            private void testCallback(Intent intent) {
+                assertEquals(PLAIN_MIME_TYPE, intent.getStringExtra(
+                        QuickContact.EXTRA_PRIORITIZED_MIMETYPE));
+                String excludedMimeTypes[]
+                        = intent.getStringArrayExtra(QuickContact.EXTRA_EXCLUDE_MIMES);
+                assertTrue(Arrays.equals(excludedMimeTypes, EXCLUDED_MIME_TYPES));
+                latch.countDown();
+            }
+        };
+
+        // Execute
+        ContactsContract.QuickContact.showQuickContact(context, new View(context),
+                FAKE_CONTACT_URI, EXCLUDED_MIME_TYPES, PLAIN_MIME_TYPE);
+        ContactsContract.QuickContact.showQuickContact(context, (Rect) null,
+                FAKE_CONTACT_URI, EXCLUDED_MIME_TYPES, PLAIN_MIME_TYPE);
+
+        // Verify: the start activity call sets the prioritized mimetype and excludes mimetypes.
+        // We don't know which method will be used to start the activity, so we check all options.
+        assertTrue(latch.await(1, TimeUnit.SECONDS));
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_RawContactsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_RawContactsTest.java
index e1cea4a..49b3ff5 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsContract_RawContactsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_RawContactsTest.java
@@ -23,6 +23,7 @@
 import android.net.Uri;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
 import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
@@ -38,6 +39,39 @@
     private ContentResolver mResolver;
     private ContactsContract_TestDataBuilder mBuilder;
 
+    private static final String[] RAW_CONTACTS_PROJECTION = new String[]{
+            RawContacts._ID,
+            RawContacts.CONTACT_ID,
+            RawContacts.DELETED,
+            RawContacts.DISPLAY_NAME_PRIMARY,
+            RawContacts.DISPLAY_NAME_ALTERNATIVE,
+            RawContacts.DISPLAY_NAME_SOURCE,
+            RawContacts.PHONETIC_NAME,
+            RawContacts.PHONETIC_NAME_STYLE,
+            RawContacts.SORT_KEY_PRIMARY,
+            RawContacts.SORT_KEY_ALTERNATIVE,
+            RawContacts.TIMES_CONTACTED,
+            RawContacts.LAST_TIME_CONTACTED,
+            RawContacts.CUSTOM_RINGTONE,
+            RawContacts.SEND_TO_VOICEMAIL,
+            RawContacts.STARRED,
+            RawContacts.PINNED,
+            RawContacts.AGGREGATION_MODE,
+            RawContacts.RAW_CONTACT_IS_USER_PROFILE,
+            RawContacts.ACCOUNT_NAME,
+            RawContacts.ACCOUNT_TYPE,
+            RawContacts.DATA_SET,
+            RawContacts.ACCOUNT_TYPE_AND_DATA_SET,
+            RawContacts.DIRTY,
+            RawContacts.SOURCE_ID,
+            RawContacts.BACKUP_ID,
+            RawContacts.VERSION,
+            RawContacts.SYNC1,
+            RawContacts.SYNC2,
+            RawContacts.SYNC3,
+            RawContacts.SYNC4
+    };
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -187,4 +221,19 @@
 
         return ContactUtil.queryContactLastUpdatedTimestamp(mResolver, contactId);
     }
+
+    public void testProjection() throws Exception {
+        TestRawContact rawContact = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_type")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        rawContact.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.DISPLAY_NAME, "test name")
+                .insert();
+
+        DatabaseAsserts.checkProjection(mResolver, RawContacts.CONTENT_URI,
+                RAW_CONTACTS_PROJECTION,
+                new long[]{rawContact.getId()}
+        );
+    }
 }
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsContract_StructuredPhoneticName.java b/tests/tests/provider/src/android/provider/cts/ContactsContract_StructuredPhoneticName.java
new file mode 100644
index 0000000..4efd9a7
--- /dev/null
+++ b/tests/tests/provider/src/android/provider/cts/ContactsContract_StructuredPhoneticName.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 junit.framework.Assert;
+
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.AggregationExceptions;
+import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Contacts;
+import android.provider.ContactsContract.DisplayNameSources;
+import android.provider.ContactsContract.RawContacts;
+import android.provider.cts.ContactsContract_TestDataBuilder.TestContact;
+import android.provider.cts.ContactsContract_TestDataBuilder.TestData;
+import android.provider.cts.ContactsContract_TestDataBuilder.TestRawContact;
+import android.provider.cts.contacts.ContactUtil;
+import android.test.AndroidTestCase;
+
+/**
+ * CTS tests for {@link DisplayNameSources#STRUCTURED_PHONETIC_NAME}.
+ */
+public class ContactsContract_StructuredPhoneticName extends AndroidTestCase {
+    private ContentResolver mResolver;
+    private ContactsContract_TestDataBuilder mBuilder;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mResolver = getContext().getContentResolver();
+        ContentProviderClient provider =
+                mResolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
+        mBuilder = new ContactsContract_TestDataBuilder(provider);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        mBuilder.cleanup();
+        super.tearDown();
+    }
+
+    public void testPhoneticStructuredName() throws Exception {
+        // Setup: contact with only phonetic name
+        TestRawContact rawContact1 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        TestData name1 = rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.PHONETIC_FAMILY_NAME, "phonetic name")
+                .insert();
+        rawContact1.load();
+        name1.load();
+
+        // Verify: DISPLAY_NAME_SOURCE notices that the StructuredName only has phonetic components
+        TestContact contact = rawContact1.getContact().load();
+        contact.assertColumn(Contacts.DISPLAY_NAME_SOURCE,
+                DisplayNameSources.STRUCTURED_PHONETIC_NAME);
+    }
+
+    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()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        TestData name1 = rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "name")
+                .insert();
+        rawContact1.load();
+        name1.load();
+
+        TestRawContact rawContact2 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        TestData name2 = rawContact2.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.PHONETIC_FAMILY_NAME, "name phonetic")
+                .insert();
+        rawContact2.load();
+        name2.load();
+
+        // Execute: aggregate the two raw contacts together
+        ContactUtil.setAggregationException(mResolver, AggregationExceptions.TYPE_KEEP_TOGETHER,
+                rawContact1.getId(), rawContact2.getId());
+
+        // Sanity check: two contacts are aggregated
+        rawContact1.load();
+        rawContact2.load();
+        Assert.assertEquals(rawContact1.getContactId(), rawContact2.getContactId());
+
+        // Verify: the display name is taken from the name with more than phonetic components
+        TestContact contact = rawContact2.getContact().load();
+        contact.assertColumn(Contacts.DISPLAY_NAME, "name");
+    }
+
+    // Same as testPhoneticStructuredName_phoneticPriority1, but with setup order reversed
+    public void testPhoneticStructuredName_phoneticPriority2() throws Exception {
+        // Setup: one raw contact has a complex phonetic name and the other a simple given name
+        TestRawContact rawContact2 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        TestData name2 = rawContact2.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.PHONETIC_FAMILY_NAME, "name phonetic")
+                .insert();
+        rawContact2.load();
+        name2.load();
+
+        TestRawContact rawContact1 = mBuilder.newRawContact()
+                .with(RawContacts.ACCOUNT_TYPE, "test_account")
+                .with(RawContacts.ACCOUNT_NAME, "test_name")
+                .insert();
+        TestData name1 = rawContact1.newDataRow(StructuredName.CONTENT_ITEM_TYPE)
+                .with(StructuredName.GIVEN_NAME, "name")
+                .insert();
+        rawContact1.load();
+        name1.load();
+
+        // Execute: aggregate the two raw contacts together
+        ContactUtil.setAggregationException(mResolver, AggregationExceptions.TYPE_KEEP_TOGETHER,
+                rawContact1.getId(), rawContact2.getId());
+
+        // Sanity check: two contacts are aggregated
+        rawContact1.load();
+        rawContact2.load();
+        Assert.assertEquals(rawContact1.getContactId(), rawContact2.getContactId());
+
+        // Verify: the display name is taken from the name with more than phonetic components
+        TestContact contact = rawContact2.getContact().load();
+        contact.assertColumn(Contacts.DISPLAY_NAME, "name");
+    }
+}
diff --git a/tests/tests/provider/src/android/provider/cts/ContactsTest.java b/tests/tests/provider/src/android/provider/cts/ContactsTest.java
index 9a3fc19..4d1cb86 100644
--- a/tests/tests/provider/src/android/provider/cts/ContactsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/ContactsTest.java
@@ -40,6 +40,7 @@
 import android.provider.Contacts.Phones;
 import android.provider.Contacts.Photos;
 import android.provider.Contacts.Settings;
+import android.provider.ContactsContract;
 import android.telephony.PhoneNumberUtils;
 import android.test.InstrumentationTestCase;
 
@@ -56,7 +57,7 @@
     protected void setUp() throws Exception {
         super.setUp();
         mContentResolver = getInstrumentation().getTargetContext().getContentResolver();
-        mProvider = mContentResolver.acquireContentProviderClient(Contacts.AUTHORITY);
+        mProvider = mContentResolver.acquireContentProviderClient(ContactsContract.AUTHORITY);
         mCallLogProvider = mContentResolver.acquireContentProviderClient(CallLog.AUTHORITY);
     }
 
@@ -416,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.GEOCODED_LOCATION, Calls.CACHED_PHOTO_URI};
         final int ID_INDEX = 0;
         final int NUMBER_INDEX = 1;
         final int DATE_INDEX = 2;
@@ -433,6 +434,7 @@
         final int CACHED_PHOTO_ID_INDEX = 13;
         final int COUNTRY_ISO_INDEX = 14;
         final int GEOCODED_LOCATION_INDEX = 15;
+        final int CACHED_PHOTO_URI_INDEX = 16;
 
         String insertCallsNumber = "0123456789";
         int insertCallsDuration = 120;
@@ -448,6 +450,7 @@
         String updateCachedNormalizedNumber = "+1987654321";
         String updateCachedLookupUri = "cached_lookup_uri_update";
         long updateCachedPhotoId = 100;
+        String updateCachedPhotoUri = "content://com.android.contacts/display_photo/1";
         String updateCountryIso = "hk";
         String updateGeocodedLocation = "Hong Kong";
 
@@ -497,6 +500,7 @@
             value.put(Calls.CACHED_MATCHED_NUMBER, updateCachedMatchedNumber);
             value.put(Calls.CACHED_NORMALIZED_NUMBER, updateCachedNormalizedNumber);
             value.put(Calls.CACHED_PHOTO_ID, updateCachedPhotoId);
+            value.put(Calls.CACHED_PHOTO_URI, updateCachedPhotoUri);
             value.put(Calls.COUNTRY_ISO, updateCountryIso);
             value.put(Calls.GEOCODED_LOCATION, updateGeocodedLocation);
             value.put(Calls.CACHED_LOOKUP_URI, updateCachedLookupUri);
@@ -519,6 +523,7 @@
             assertEquals(updateCachedNormalizedNumber,
                     cursor.getString(CACHED_NORMALIZED_NUMBER_INDEX));
             assertEquals(updateCachedPhotoId, cursor.getLong(CACHED_PHOTO_ID_INDEX));
+            assertEquals(updateCachedPhotoUri, cursor.getString(CACHED_PHOTO_URI_INDEX));
             assertEquals(updateCountryIso, cursor.getString(COUNTRY_ISO_INDEX));
             assertEquals(updateGeocodedLocation, cursor.getString(GEOCODED_LOCATION_INDEX));
             assertEquals(updateCachedLookupUri, cursor.getString(CACHED_LOOKUP_URI_INDEX));
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 c1b2229..8fc5df1 100644
--- a/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
+++ b/tests/tests/provider/src/android/provider/cts/MediaStore_FilesTest.java
@@ -306,19 +306,25 @@
 
                 // get the real path from the file descriptor (this relies on the media provider
                 // having opened the path via the real path instead of the emulated path).
-                values = new ContentValues();
-                values.put("_data", realPathFor(pfd));
-                mResolver.update(uri, values, null, null);
+                String realPath = realPathFor(pfd);
                 pfd.close();
+                if (realPath.equals(sdfile.getCanonicalPath())) {
+                    // provider did not use real/translated path
+                    sdfile = null;
+                } else {
+                    values = new ContentValues();
+                    values.put("_data", realPath);
+                    mResolver.update(uri, values, null, null);
 
-                // we shouldn't be able to access this
-                try {
-                    pfd = mResolver.openFileDescriptor(uri, "r");
-                    fail("shouldn't have fd for " + realPathFor(pfd));
-                } catch (FileNotFoundException e) {
-                    // expected
-                } finally {
-                    pfd.close();
+                    // we shouldn't be able to access this
+                    try {
+                        pfd = mResolver.openFileDescriptor(uri, "r");
+                        fail("shouldn't have fd for " + realPath);
+                    } catch (FileNotFoundException e) {
+                        // expected
+                    } finally {
+                        pfd.close();
+                    }
                 }
             } catch (FileNotFoundException e) {
                 fail("couldn't open file");
@@ -328,7 +334,7 @@
         // clean up
         assertEquals(1, mResolver.delete(uri, null, null));
         if (sdfile != null) {
-            assertEquals(true, sdfile.delete());
+            assertEquals("couldn't delete " + sdfile.getCanonicalPath(), true, sdfile.delete());
         }
 
         // test secondary storage if present
diff --git a/tests/tests/provider/src/android/provider/cts/SettingsTest.java b/tests/tests/provider/src/android/provider/cts/SettingsTest.java
index c732305..5cf5106 100644
--- a/tests/tests/provider/src/android/provider/cts/SettingsTest.java
+++ b/tests/tests/provider/src/android/provider/cts/SettingsTest.java
@@ -16,7 +16,6 @@
 
 package android.provider.cts;
 
-
 import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentValues;
@@ -35,14 +34,11 @@
         final String[] SYSTEM_PROJECTION = new String[] {
                 Settings.System._ID, Settings.System.NAME, Settings.System.VALUE
         };
-        final int ID_INDEX = 0;
         final int NAME_INDEX = 1;
         final int VALUE_INDEX = 2;
 
-        String insertName = "name_insert";
+        String name = "name";
         String insertValue = "value_insert";
-
-        String updateName = "name_update";
         String updateValue = "value_update";
 
         // get provider
@@ -54,119 +50,50 @@
         try {
             // Test: insert
             ContentValues value = new ContentValues();
-            value.put(Settings.System.NAME, insertName);
+            value.put(Settings.System.NAME, name);
             value.put(Settings.System.VALUE, insertValue);
 
             provider.insert(Settings.System.CONTENT_URI, value);
             cursor = provider.query(Settings.System.CONTENT_URI, SYSTEM_PROJECTION,
-                    Settings.System.NAME + "=\"" + insertName + "\"", null, null, null);
+                    Settings.System.NAME + "=\"" + name + "\"", null, null, null);
             assertNotNull(cursor);
             assertEquals(1, cursor.getCount());
             assertTrue(cursor.moveToFirst());
-            assertEquals(insertName, cursor.getString(NAME_INDEX));
+            assertEquals(name, cursor.getString(NAME_INDEX));
             assertEquals(insertValue, cursor.getString(VALUE_INDEX));
-            int Id = cursor.getInt(ID_INDEX);
             cursor.close();
+            cursor = null;
 
             // Test: update
             value.clear();
-            value.put(Settings.System.NAME, updateName);
+            value.put(Settings.System.NAME, name);
             value.put(Settings.System.VALUE, updateValue);
 
             provider.update(Settings.System.CONTENT_URI, value,
-                    Settings.System.NAME + "=\"" + insertName + "\"", null);
+                    Settings.System.NAME + "=\"" + name + "\"", null);
             cursor = provider.query(Settings.System.CONTENT_URI, SYSTEM_PROJECTION,
-                    Settings.System._ID + " = " + Id, null, null, null);
+                    Settings.System.NAME + "=\"" + name + "\"", null, null, null);
             assertNotNull(cursor);
             assertEquals(1, cursor.getCount());
             assertTrue(cursor.moveToFirst());
-            assertEquals(updateName, cursor.getString(NAME_INDEX));
+            assertEquals(name, cursor.getString(NAME_INDEX));
             assertEquals(updateValue, cursor.getString(VALUE_INDEX));
             cursor.close();
+            cursor = null;
 
             // Test: delete
             provider.delete(Settings.System.CONTENT_URI,
-                    Settings.System.NAME + "=\"" + updateName + "\"", null);
+                    Settings.System.NAME + "=\"" + name + "\"", null);
             cursor = provider.query(Settings.System.CONTENT_URI, SYSTEM_PROJECTION,
-                    Settings.System._ID + " = " + Id, null, null, null);
+                    Settings.System.NAME + "=\"" + name + "\"", null, null, null);
             assertNotNull(cursor);
             assertEquals(0, cursor.getCount());
-        } finally {
-            // TODO should clean up more better
-            if (cursor != null)
-                cursor.close();
-        }
-    }
-
-    public void testBluetoothDevicesTable() throws RemoteException {
-        final String[] BLUETOOTH_DEVICES_PROJECTION = new String[] {
-                "name", "addr", "channel", "type"
-        };
-        final int ID_INDEX = 0;
-        final int ADDR_INDEX = 1;
-        final int CHANNEL_INDEX = 2;
-        final int TYPE_INDEX = 3;
-
-        String insertName = "name_insert";
-        String insertAddr = "addr_insert";
-
-        String updateName = "name_update";
-        String updateAddr = "addr_update";
-
-        // get provider
-        Uri uri = Uri.parse("content://settings/bluetooth_devices");
-        ContentResolver cr = mContext.getContentResolver();
-        ContentProviderClient provider = cr.acquireContentProviderClient(uri);
-        Cursor cursor = null;
-
-        try {
-            // Test: insert
-            ContentValues value = new ContentValues();
-            value.put("name", insertName);
-            value.put("addr", insertAddr);
-            value.put("channel", 1);
-            value.put("type", 2);
-
-            provider.insert(uri, value);
-            cursor = provider.query(uri, BLUETOOTH_DEVICES_PROJECTION,
-                    "name=\"" + insertName + "\"", null, null, null);
-            assertNotNull(cursor);
-            assertEquals(1, cursor.getCount());
-            assertTrue(cursor.moveToFirst());
-            assertEquals(insertAddr, cursor.getString(ADDR_INDEX));
-            assertEquals(1, cursor.getInt(CHANNEL_INDEX));
-            assertEquals(2, cursor.getInt(TYPE_INDEX));
-            int Id = cursor.getInt(ID_INDEX);
             cursor.close();
-
-            // Test: update
-            value.clear();
-            value.put("name", updateName);
-            value.put("addr", updateAddr);
-            value.put("channel", 3);
-            value.put("type", 4);
-
-            provider.update(uri, value, "name=\"" + insertName + "\"", null);
-            cursor = provider.query(uri, BLUETOOTH_DEVICES_PROJECTION,
-                    "name=\"" + updateName + "\"", null, null, null);
-            assertNotNull(cursor);
-            assertEquals(1, cursor.getCount());
-            assertTrue(cursor.moveToFirst());
-            assertEquals(updateAddr, cursor.getString(ADDR_INDEX));
-            assertEquals(3, cursor.getInt(CHANNEL_INDEX));
-            assertEquals(4, cursor.getInt(TYPE_INDEX));
-            cursor.close();
-
-            // Test: delete
-            provider.delete(uri, "name=\"" + updateName + "\"", null);
-            cursor = provider.query(uri, BLUETOOTH_DEVICES_PROJECTION, "_id = " + Id,
-                    null, null, null);
-            assertNotNull(cursor);
-            assertEquals(0, cursor.getCount());
+            cursor = null;
         } finally {
-            // TODO should clean up more better
-            if (cursor != null)
+            if (cursor != null) {
                 cursor.close();
+            }
         }
     }
 
@@ -211,22 +138,24 @@
             fail("SettingsProvider didn't throw IllegalArgumentException for insert name "
                     + name + " at URI " + uri);
         } catch (IllegalArgumentException e) {
+            /* ignore */
         }
 
-
         try {
             cr.update(uri, cv, NAME_EQ_PLACEHOLDER, new String[]{name});
-            fail("SettingsProvider didn't throw IllegalArgumentException for update name "
+            fail("SettingsProvider didn't throw SecurityException for update name "
                     + name + " at URI " + uri);
         } catch (IllegalArgumentException e) {
+            /* ignore */
         }
 
         try {
-            Cursor c = cr.query(uri, SELECT_VALUE, NAME_EQ_PLACEHOLDER,
+            cr.query(uri, SELECT_VALUE, NAME_EQ_PLACEHOLDER,
                     new String[]{name}, null);
             fail("SettingsProvider didn't throw IllegalArgumentException for query name "
                     + name + " at URI " + uri);
         } catch (IllegalArgumentException e) {
+            /* ignore */
         }
 
 
@@ -235,6 +164,7 @@
             fail("SettingsProvider didn't throw IllegalArgumentException for delete name "
                     + name + " at URI " + uri);
         } catch (IllegalArgumentException e) {
+            /* ignore */
         }
 
 
@@ -259,9 +189,7 @@
 
     public void testAccessNonTable() {
         tryBadTableAccess("SYSTEM", "system", "install_non_market_apps");
-        tryBadTableAccess("BOOKMARKS", "bookmarks", "install_non_market_apps");
         tryBadTableAccess("SECURE", "secure", "install_non_market_apps");
-        tryBadTableAccess("BLUETOOTH_DEVICES", "bluetooth_devices", "install_non_market_apps");
         tryBadTableAccess(" secure", "secure", "install_non_market_apps");
         tryBadTableAccess("secure ", "secure", "install_non_market_apps");
         tryBadTableAccess(" secure ", "secure", "install_non_market_apps");
diff --git a/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java b/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java
index 2052e2e..b3c545e 100644
--- a/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java
+++ b/tests/tests/provider/src/android/provider/cts/Settings_SystemTest.java
@@ -21,11 +21,16 @@
 import android.content.res.Configuration;
 import android.database.Cursor;
 import android.net.Uri;
+import android.os.ParcelFileDescriptor;
 import android.provider.Settings.SettingNotFoundException;
 import android.provider.Settings.System;
-import android.test.AndroidTestCase;
+import android.test.InstrumentationTestCase;
 
-public class Settings_SystemTest extends AndroidTestCase {
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Scanner;
+
+public class Settings_SystemTest extends InstrumentationTestCase {
     private ContentResolver cr;
 
     private static final String INT_FIELD = "IntField";
@@ -37,7 +42,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
-        cr = mContext.getContentResolver();
+        cr = getInstrumentation().getContext().getContentResolver();
         assertNotNull(cr);
     }
 
@@ -53,9 +58,34 @@
 
         selection = System.NAME + "=\"" + STRING_FIELD + "\"";
         cr.delete(System.CONTENT_URI, selection, null);
+    }
 
-        selection = System.NAME + "=\"" + System.SHOW_GTALK_SERVICE_STATUS + "\"";
-        cr.delete(System.CONTENT_URI, selection, null);
+    private void enableAppOps() {
+        StringBuilder cmd = new StringBuilder();
+        cmd.append("appops set ");
+        cmd.append(getInstrumentation().getContext().getPackageName());
+        cmd.append(" android:write_settings allow");
+        getInstrumentation().getUiAutomation().executeShellCommand(cmd.toString());
+
+        StringBuilder query = new StringBuilder();
+        query.append("appops get ");
+        query.append(getInstrumentation().getContext().getPackageName());
+        query.append(" android:write_settings");
+        String queryStr = query.toString();
+
+        String result = "No operations.";
+        while (result.contains("No operations")) {
+            ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation().executeShellCommand(
+                    queryStr);
+            InputStream inputStream = new FileInputStream(pfd.getFileDescriptor());
+            result = convertStreamToString(inputStream);
+        }
+    }
+
+    private String convertStreamToString(InputStream is) {
+        try (Scanner scanner = new Scanner(is).useDelimiter("\\A")) {
+            return scanner.hasNext() ? scanner.next() : "";
+        }
     }
 
     public void testSystemSettings() throws SettingNotFoundException {
@@ -76,16 +106,15 @@
 
             String stringValue = "cts";
 
-            // insert 5 rows, and update 1 rows
+            // insert 4 rows, and update 1 rows
             assertTrue(System.putInt(cr, INT_FIELD, 10));
             assertTrue(System.putLong(cr, LONG_FIELD, 20l));
             assertTrue(System.putFloat(cr, FLOAT_FIELD, 30.0f));
             assertTrue(System.putString(cr, STRING_FIELD, stringValue));
-            System.setShowGTalkServiceStatus(cr, true);
 
             c = cr.query(System.CONTENT_URI, null, null, null, null);
             assertNotNull(c);
-            assertEquals(origCount + 5, c.getCount());
+            assertEquals(origCount + 4, c.getCount());
             c.close();
 
             // get these rows to assert
@@ -94,7 +123,6 @@
             assertEquals(30.0f, System.getFloat(cr, FLOAT_FIELD), 0.001);
 
             assertEquals(stringValue, System.getString(cr, STRING_FIELD));
-            assertTrue(System.getShowGTalkServiceStatus(cr));
 
             // delete the tested rows again
             deleteTestedRows();
diff --git a/tests/tests/provider/src/android/provider/cts/TelephonyProviderTest.java b/tests/tests/provider/src/android/provider/cts/TelephonyProviderTest.java
index 0eba9f2..b06ddfa 100644
--- a/tests/tests/provider/src/android/provider/cts/TelephonyProviderTest.java
+++ b/tests/tests/provider/src/android/provider/cts/TelephonyProviderTest.java
@@ -52,32 +52,35 @@
 
     // Test that the TelephonyProvider doesn't allow clients to update _data column data and
     // if they can, that they can't abuse the provider to open an arbitrary file.
-    public void testOpeningAnyFile() {
-        Uri uri = Uri.parse("content://mms/100/part");
-        try {
-            ContentValues values2 = new ContentValues();
-            values2.put("_data", "/dev/urandom");
-            Uri uri2 = mContentResolver.insert(uri, values2);
-            assertEquals("The code was able to insert the _data column", null, uri2);
-            if (uri2 == null) {
-                return;
-            }
-            ContentValues values = new ContentValues();
-            values.put("_data", "/dev/urandom");
-            int rowCnt = mContentResolver.update(uri2, values, null, null);
-            assertEquals("Was able to update the _data column", 0, rowCnt);
-
-            ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(uri2, "rw");
-            pfd.getFileDescriptor();
-            FileDescriptor fd = pfd.getFileDescriptor();
-            Field fld = fd.getClass().getDeclaredField("descriptor");
-            fld.setAccessible(true);
-            int fint  = fld.getInt(fd);
-            fail("The code was able to abuse the MmsProvider to open any file");
-        } catch(Exception e){
-            e.printStackTrace();
-        }
-    }
+    // --- This test is commented out for now because the test needs to run as if it were
+    // the default SMS app. Until we have a way to do that in the test framework, the test will
+    // fail (i.e. the insert will appear to have succeeded when it really hasn't).
+//    public void testOpeningAnyFile() {
+//        Uri uri = Uri.parse("content://mms/100/part");
+//        try {
+//            ContentValues values2 = new ContentValues();
+//            values2.put("_data", "/dev/urandom");
+//            Uri uri2 = mContentResolver.insert(uri, values2);
+//            assertNull("The code was able to insert the _data column", uri2);
+//            if (uri2 == null) {
+//                return;
+//            }
+//            ContentValues values = new ContentValues();
+//            values.put("_data", "/dev/urandom");
+//            int rowCnt = mContentResolver.update(uri2, values, null, null);
+//            assertEquals("Was able to update the _data column", 0, rowCnt);
+//
+//            ParcelFileDescriptor pfd = mContentResolver.openFileDescriptor(uri2, "rw");
+//            pfd.getFileDescriptor();
+//            FileDescriptor fd = pfd.getFileDescriptor();
+//            Field fld = fd.getClass().getDeclaredField("descriptor");
+//            fld.setAccessible(true);
+//            int fint  = fld.getInt(fd);
+//            fail("The code was able to abuse the MmsProvider to open any file");
+//        } catch(Exception e){
+//            e.printStackTrace();
+//        }
+//    }
 
     // In JB MR1 access to the TelephonyProvider's Carriers table was clamped down and would
     // throw a SecurityException when queried. That was fixed in JB MR2. Verify that 3rd parties
diff --git a/tests/tests/renderscript/Android.mk b/tests/tests/renderscript/Android.mk
index 245c5b9..7b30859 100644
--- a/tests/tests/renderscript/Android.mk
+++ b/tests/tests/renderscript/Android.mk
@@ -29,11 +29,13 @@
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
-LOCAL_JNI_SHARED_LIBRARIES := libcoremathtestcpp_jni
+LOCAL_JNI_SHARED_LIBRARIES := libcoremathtestcpp_jni libbnnmdata_jni
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src) $(call all-renderscript-files-under, src)
 
+LOCAL_RENDERSCRIPT_FLAGS := -Wno-error=deprecated-declarations
+
 LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
-include $(LOCAL_PATH)/libcoremathtestcpp/Android.mk
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/renderscript/assets/BLASData.txt b/tests/tests/renderscript/assets/BLASData.txt
new file mode 100644
index 0000000..31c671f
--- /dev/null
+++ b/tests/tests/renderscript/assets/BLASData.txt
@@ -0,0 +1,1577 @@
+/* Don't edit this file!  It is auto-generated by blas_gen.py. */
+
+M, N, K, KL, KU;
+10 17 16 2 1
+
+L2_sGEMV_A_mn
+0.4, 0.8, 0.6, 0.5, 0.9, 0.4, 0.2, 0.9, 0.9, 0.4, 0.5, 0.8, 0.5, 0.4, 0.9, 0.1, 0.6, 0.1, 0.6, 0.2, 0.6, 0.1, 0.3, 0.3, 0.9, 0.8, 0.4, 0.8, 0.1, 0.2, 0.1, 0.3, 0.1, 0.2, 0.2, 0.9, 0.4, 0.1, 0.9, 0.7, 0.2, 0.9, 0.2, 0.1, 0.6, 0.8, 0.3, 0.4, 0.7, 0.7, 0.4, 0.4, 0.3, 0.8, 0.1, 0.6, 0.4, 0.9, 0.8, 0.4, 0.9, 0.8, 0.2, 0.4, 0.5, 0.7, 0.3, 0.7, 0.3, 0.1, 0.7, 0.7, 0.4, 0.3, 0.6, 0.1, 0.6, 0.4, 0.8, 0.7, 0.9, 0.8, 0.1, 0.7, 0.6, 0.6, 0.6, 0.3, 0.1, 0.5, 0.9, 0.2, 0.2, 0.2, 0.3, 0.8, 0.2, 0.9, 0.8, 0.3, 0.1, 0.1, 0.1, 0.8, 0.1, 0.3, 0.8, 0.2, 0.5, 0.9, 0.7, 0.2, 0.3, 0.7, 0.1, 0.2, 0.8, 0.8, 0.4, 0.2, 0.2, 0.4, 0.2, 0.3, 0.1, 0.8, 0.2, 0.3, 0.9, 0.5, 0.3, 0.5, 0.4, 0.5, 0.6, 0.6, 0.4, 0.2, 0.2, 0.7, 0.9, 0.1, 0.8, 0.7, 0.5, 0.6, 0.8, 0.7, 0.8, 0.2, 0.4, 0.1, 0.2, 0.7, 0.7, 0.3, 0.3, 0.4, 0.8, 0.9, 0.5, 0.4, 0.5, 0.7, 0.6, 0.4, 0.1, 0.9, 0.2, 0.2, 
+
+L2_sGEMV_x_n1
+0.6, 0.8, 0.7, 0.9, 0.8, 0.4, 0.6, 0.6, 0.3, 0.2, 0.1, 0.2, 0.7, 0.8, 0.5, 0.4, 0.6, 
+
+L2_sGEMV_x_n2
+0.6, 0.0, 0.8, 0.0, 0.7, 0.0, 0.9, 0.0, 0.8, 0.0, 0.4, 0.0, 0.6, 0.0, 0.6, 0.0, 0.3, 0.0, 0.2, 0.0, 0.1, 0.0, 0.2, 0.0, 0.7, 0.0, 0.8, 0.0, 0.5, 0.0, 0.4, 0.0, 0.6, 0.0, 
+
+L2_sGEMV_y_m1
+0.4, 0.5, 0.7, 0.2, 0.2, 0.4, 0.1, 0.8, 0.5, 0.4, 
+
+L2_sGEMV_y_m2
+0.4, 0.0, 0.0, 0.5, 0.0, 0.0, 0.7, 0.0, 0.0, 0.2, 0.0, 0.0, 0.2, 0.0, 0.0, 0.4, 0.0, 0.0, 0.1, 0.0, 0.0, 0.8, 0.0, 0.0, 0.5, 0.0, 0.0, 0.4, 0.0, 0.0, 
+
+L2_sGEMV_o_N
+5.77000007883, 3.59000010103, 5.2700000222, 4.98000011489, 4.88000006273, 4.30000009164, 4.31000010833, 4.32000012204, 4.90000004768, 4.76000007406, 
+
+L2_sGEMV_o_N2
+5.77000007883, 0.0, 0.0, 3.59000010103, 0.0, 0.0, 5.2700000222, 0.0, 0.0, 4.98000011489, 0.0, 0.0, 4.88000006273, 0.0, 0.0, 4.30000009164, 0.0, 0.0, 4.31000010833, 0.0, 0.0, 4.32000012204, 0.0, 0.0, 4.90000004768, 0.0, 0.0, 4.76000007406, 0.0, 0.0, 
+
+L2_sGEMV_o_T
+1.98000005528, 2.99000003099, 2.29000003099, 2.3299999994, 3.17000000134, 2.17000001475, 2.80000006035, 3.09999998882, 2.20000004247, 2.25000002459, 2.87000005201, 2.29000003546, 2.80000001043, 2.35000004545, 2.81999999911, 1.91000002712, 2.22000007659, 
+
+L2_sGEMV_o_H
+1.98000005528, 2.99000003099, 2.29000003099, 2.3299999994, 3.17000000134, 2.17000001475, 2.80000006035, 3.09999998882, 2.20000004247, 2.25000002459, 2.87000005201, 2.29000003546, 2.80000001043, 2.35000004545, 2.81999999911, 1.91000002712, 2.22000007659, 
+
+L2_dGEMV_A_mn
+0.8, 0.7, 0.9, 0.2, 0.6, 0.9, 0.4, 0.1, 0.9, 0.9, 0.6, 0.2, 0.9, 0.9, 0.1, 0.5, 0.7, 0.6, 0.5, 0.6, 0.9, 0.3, 0.6, 0.1, 0.7, 0.7, 0.6, 0.2, 0.5, 0.9, 0.6, 0.4, 0.6, 0.9, 0.4, 0.2, 0.2, 0.9, 0.3, 0.8, 0.7, 0.1, 0.1, 0.9, 0.5, 0.1, 0.6, 0.5, 0.7, 0.8, 0.4, 0.3, 0.3, 0.9, 0.4, 0.9, 0.6, 0.2, 0.7, 0.2, 0.9, 0.3, 0.7, 0.4, 0.2, 0.3, 0.8, 0.1, 0.5, 0.1, 0.7, 0.8, 0.8, 0.8, 0.1, 0.4, 0.2, 0.5, 0.3, 0.6, 0.9, 0.6, 0.2, 0.4, 0.6, 0.7, 0.7, 0.2, 0.5, 0.8, 0.2, 0.4, 0.6, 0.9, 0.1, 0.6, 0.3, 0.8, 0.2, 0.3, 0.5, 0.6, 0.8, 0.1, 0.4, 0.2, 0.4, 0.6, 0.3, 0.5, 0.7, 0.6, 0.7, 0.2, 0.7, 0.2, 0.9, 0.2, 0.7, 0.7, 0.2, 0.3, 0.1, 0.3, 0.2, 0.7, 0.5, 0.2, 0.5, 0.7, 0.4, 0.6, 0.6, 0.5, 0.1, 0.9, 0.6, 0.8, 0.2, 0.8, 0.2, 0.8, 0.3, 0.6, 0.2, 0.9, 0.7, 0.1, 0.8, 0.9, 0.6, 0.1, 0.6, 0.1, 0.2, 0.3, 0.3, 0.5, 0.1, 0.1, 0.5, 0.2, 0.3, 0.3, 0.4, 0.6, 0.4, 0.2, 0.1, 0.4, 
+
+L2_dGEMV_x_n1
+0.7, 0.8, 0.7, 0.8, 0.9, 0.4, 0.2, 0.5, 0.4, 0.5, 0.2, 0.8, 0.9, 0.7, 0.4, 0.2, 0.4, 
+
+L2_dGEMV_x_n2
+0.7, 0.0, 0.8, 0.0, 0.7, 0.0, 0.8, 0.0, 0.9, 0.0, 0.4, 0.0, 0.2, 0.0, 0.5, 0.0, 0.4, 0.0, 0.5, 0.0, 0.2, 0.0, 0.8, 0.0, 0.9, 0.0, 0.7, 0.0, 0.4, 0.0, 0.2, 0.0, 0.4, 0.0, 
+
+L2_dGEMV_y_m1
+0.9, 0.7, 0.4, 0.1, 0.5, 0.6, 0.8, 0.9, 0.3, 0.4, 
+
+L2_dGEMV_y_m2
+0.9, 0.0, 0.0, 0.7, 0.0, 0.0, 0.4, 0.0, 0.0, 0.1, 0.0, 0.0, 0.5, 0.0, 0.0, 0.6, 0.0, 0.0, 0.8, 0.0, 0.0, 0.9, 0.0, 0.0, 0.3, 0.0, 0.0, 0.4, 0.0, 0.0, 
+
+L2_dGEMV_o_N
+6.79, 6.43, 4.64, 4.91, 5.82, 5.46, 5.12, 4.91, 5.6, 3.53, 
+
+L2_dGEMV_o_N2
+6.79, 0.0, 0.0, 6.43, 0.0, 0.0, 4.64, 0.0, 0.0, 4.91, 0.0, 0.0, 5.82, 0.0, 0.0, 5.46, 0.0, 0.0, 5.12, 0.0, 0.0, 4.91, 0.0, 0.0, 5.6, 0.0, 0.0, 3.53, 0.0, 0.0, 
+
+L2_dGEMV_o_T
+4.19, 2.94, 3.34, 3.32, 3.59, 3.47, 2.22, 2.98, 3.28, 3.81, 3.14, 2.63, 5.13, 3.7, 2.79, 2.29, 4.2, 
+
+L2_dGEMV_o_H
+4.19, 2.94, 3.34, 3.32, 3.59, 3.47, 2.22, 2.98, 3.28, 3.81, 3.14, 2.63, 5.13, 3.7, 2.79, 2.29, 4.2, 
+
+L2_cGEMV_A_mn
+0.600000023842, 0.899999976158, 0.899999976158, 0.899999976158, 0.40000000596, 0.20000000298, 0.300000011921, 0.699999988079, 0.5, 0.800000011921, 0.5, 0.10000000149, 0.10000000149, 0.899999976158, 0.20000000298, 0.600000023842, 0.5, 0.800000011921, 0.5, 0.5, 0.40000000596, 0.40000000596, 0.800000011921, 0.5, 0.699999988079, 0.800000011921, 0.10000000149, 0.5, 0.40000000596, 0.5, 0.40000000596, 0.10000000149, 0.600000023842, 0.5, 0.5, 0.5, 0.300000011921, 0.300000011921, 0.899999976158, 0.10000000149, 0.899999976158, 0.800000011921, 0.5, 0.899999976158, 0.699999988079, 0.5, 0.10000000149, 0.40000000596, 0.899999976158, 0.600000023842, 0.899999976158, 0.40000000596, 0.40000000596, 0.5, 0.600000023842, 0.10000000149, 0.40000000596, 0.600000023842, 0.10000000149, 0.5, 0.800000011921, 0.5, 0.10000000149, 0.40000000596, 0.20000000298, 0.800000011921, 0.899999976158, 0.10000000149, 0.20000000298, 0.899999976158, 0.20000000298, 0.800000011921, 0.699999988079, 0.600000023842, 0.800000011921, 0.800000011921, 0.300000011921, 0.600000023842, 0.300000011921, 0.899999976158, 0.600000023842, 0.300000011921, 0.5, 0.20000000298, 0.20000000298, 0.5, 0.699999988079, 0.300000011921, 0.899999976158, 0.800000011921, 0.20000000298, 0.40000000596, 0.10000000149, 0.20000000298, 0.40000000596, 0.600000023842, 0.10000000149, 0.300000011921, 0.20000000298, 0.20000000298, 0.300000011921, 0.800000011921, 0.800000011921, 0.899999976158, 0.5, 0.699999988079, 0.699999988079, 0.5, 0.40000000596, 0.20000000298, 0.40000000596, 0.699999988079, 0.899999976158, 0.899999976158, 0.300000011921, 0.800000011921, 0.20000000298, 0.800000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.800000011921, 0.300000011921, 0.800000011921, 0.5, 0.10000000149, 0.800000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.699999988079, 0.40000000596, 0.699999988079, 0.10000000149, 0.5, 0.300000011921, 0.800000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.300000011921, 0.5, 0.699999988079, 0.899999976158, 0.300000011921, 0.20000000298, 0.5, 0.10000000149, 0.40000000596, 0.10000000149, 0.40000000596, 0.300000011921, 0.699999988079, 0.600000023842, 0.20000000298, 0.899999976158, 0.600000023842, 0.20000000298, 0.5, 0.40000000596, 0.40000000596, 0.800000011921, 0.699999988079, 0.40000000596, 0.40000000596, 0.899999976158, 0.10000000149, 0.20000000298, 0.600000023842, 0.40000000596, 0.600000023842, 0.600000023842, 0.800000011921, 0.899999976158, 0.600000023842, 0.800000011921, 0.5, 0.699999988079, 0.300000011921, 0.5, 0.899999976158, 0.899999976158, 0.40000000596, 0.600000023842, 0.40000000596, 0.899999976158, 0.800000011921, 0.10000000149, 0.10000000149, 0.10000000149, 0.10000000149, 0.5, 0.699999988079, 0.699999988079, 0.20000000298, 0.600000023842, 0.20000000298, 0.300000011921, 0.800000011921, 0.5, 0.40000000596, 0.20000000298, 0.40000000596, 0.300000011921, 0.10000000149, 0.600000023842, 0.899999976158, 0.40000000596, 0.899999976158, 0.40000000596, 0.10000000149, 0.800000011921, 0.300000011921, 0.40000000596, 0.10000000149, 0.600000023842, 0.40000000596, 0.300000011921, 0.699999988079, 0.600000023842, 0.800000011921, 0.300000011921, 0.5, 0.20000000298, 0.300000011921, 0.699999988079, 0.800000011921, 0.600000023842, 0.899999976158, 0.10000000149, 0.10000000149, 0.800000011921, 0.300000011921, 0.10000000149, 0.40000000596, 0.899999976158, 0.300000011921, 0.899999976158, 0.20000000298, 0.40000000596, 0.600000023842, 0.899999976158, 0.20000000298, 0.40000000596, 0.600000023842, 0.20000000298, 0.40000000596, 0.10000000149, 0.600000023842, 0.300000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.699999988079, 0.899999976158, 0.300000011921, 0.699999988079, 0.699999988079, 0.800000011921, 0.20000000298, 0.40000000596, 0.699999988079, 0.5, 0.20000000298, 0.899999976158, 0.600000023842, 0.20000000298, 0.699999988079, 0.5, 0.20000000298, 0.20000000298, 0.800000011921, 0.800000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.699999988079, 0.300000011921, 0.5, 0.899999976158, 0.899999976158, 0.699999988079, 0.40000000596, 0.800000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.5, 0.10000000149, 0.40000000596, 0.600000023842, 0.20000000298, 0.600000023842, 0.40000000596, 0.20000000298, 0.600000023842, 0.300000011921, 0.5, 0.699999988079, 0.600000023842, 0.10000000149, 0.600000023842, 0.600000023842, 0.20000000298, 0.600000023842, 0.699999988079, 0.5, 0.10000000149, 0.40000000596, 0.600000023842, 0.40000000596, 0.699999988079, 0.5, 0.899999976158, 0.600000023842, 0.600000023842, 0.699999988079, 0.600000023842, 0.800000011921, 0.5, 0.10000000149, 0.800000011921, 0.10000000149, 0.699999988079, 0.20000000298, 0.800000011921, 0.10000000149, 0.800000011921, 0.5, 0.600000023842, 0.20000000298, 0.899999976158, 0.20000000298, 0.899999976158, 0.5, 0.800000011921, 0.300000011921, 0.40000000596, 0.10000000149, 
+
+L2_cGEMV_x_n1
+0.5, 0.40000000596, 0.300000011921, 0.300000011921, 0.40000000596, 0.5, 0.20000000298, 0.699999988079, 0.5, 0.10000000149, 0.699999988079, 0.899999976158, 0.699999988079, 0.899999976158, 0.600000023842, 0.600000023842, 0.699999988079, 0.800000011921, 0.20000000298, 0.5, 0.5, 0.800000011921, 0.899999976158, 0.300000011921, 0.899999976158, 0.5, 0.899999976158, 0.699999988079, 0.699999988079, 0.20000000298, 0.899999976158, 0.600000023842, 0.899999976158, 0.699999988079, 
+
+L2_cGEMV_x_n2
+0.5, 0.40000000596, 0.0, 0.0, 0.300000011921, 0.300000011921, 0.0, 0.0, 0.40000000596, 0.5, 0.0, 0.0, 0.20000000298, 0.699999988079, 0.0, 0.0, 0.5, 0.10000000149, 0.0, 0.0, 0.699999988079, 0.899999976158, 0.0, 0.0, 0.699999988079, 0.899999976158, 0.0, 0.0, 0.600000023842, 0.600000023842, 0.0, 0.0, 0.699999988079, 0.800000011921, 0.0, 0.0, 0.20000000298, 0.5, 0.0, 0.0, 0.5, 0.800000011921, 0.0, 0.0, 0.899999976158, 0.300000011921, 0.0, 0.0, 0.899999976158, 0.5, 0.0, 0.0, 0.899999976158, 0.699999988079, 0.0, 0.0, 0.699999988079, 0.20000000298, 0.0, 0.0, 0.899999976158, 0.600000023842, 0.0, 0.0, 0.899999976158, 0.699999988079, 0.0, 0.0, 
+
+L2_cGEMV_y_m1
+0.699999988079, 0.300000011921, 0.20000000298, 0.40000000596, 0.699999988079, 0.699999988079, 0.20000000298, 0.600000023842, 0.40000000596, 0.40000000596, 0.800000011921, 0.800000011921, 0.300000011921, 0.5, 0.5, 0.5, 0.600000023842, 0.10000000149, 0.40000000596, 0.300000011921, 
+
+L2_cGEMV_y_m2
+0.699999988079, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cGEMV_o_N
+0.369999971539, 10.0700000311, 1.44999985248, 10.9199999611, -1.03000003666, 10.2100000301, -0.440000020564, 11.8699999484, 1.32999995992, 9.55000003353, 0.859999980181, 10.7200000505, -0.0200000840426, 10.2000000387, 0.449999946356, 10.3200000088, 2.18999997288, 9.83000009477, 4.28999994755, 10.3300000791, 
+
+L2_cGEMV_o_N2
+0.369999971539, 10.0700000311, 0.0, 0.0, 0.0, 0.0, 1.44999985248, 10.9199999611, 0.0, 0.0, 0.0, 0.0, -1.03000003666, 10.2100000301, 0.0, 0.0, 0.0, 0.0, -0.440000020564, 11.8699999484, 0.0, 0.0, 0.0, 0.0, 1.32999995992, 9.55000003353, 0.0, 0.0, 0.0, 0.0, 0.859999980181, 10.7200000505, 0.0, 0.0, 0.0, 0.0, -0.0200000840426, 10.2000000387, 0.0, 0.0, 0.0, 0.0, 0.449999946356, 10.3200000088, 0.0, 0.0, 0.0, 0.0, 2.18999997288, 9.83000009477, 0.0, 0.0, 0.0, 0.0, 4.28999994755, 10.3300000791, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cGEMV_o_T
+0.0800000418723, 5.80000011399, -0.369999973774, 5.96000003904, 0.930000003129, 5.72000009149, -0.129999988973, 6.23000003964, 0.349999982119, 4.70000010133, 0.630000014305, 6.19000001237, 0.389999969155, 5.09000008985, 0.679999983758, 5.34000007868, 1.37000000283, 5.9000000827, 0.109999974966, 4.40000005662, 0.269999968559, 5.56000010014, 1.31999997079, 4.87000009596, 0.869999949187, 4.98000009328, -0.0100000442564, 5.00000004992, 1.29000001609, 4.30000008345, 1.37000000581, 4.20000011697, 0.869999999851, 4.86000010163, 
+
+L2_cGEMV_o_H
+5.94000011817, -0.519999925345, 6.01000006139, -0.479999917448, 5.43000012383, 0.879999977052, 5.53000006795, 0.210000015199, 5.23000008881, -0.759999982417, 6.35000001639, 1.01000001743, 5.09000016585, 0.229999995679, 5.58000012234, 0.659999977946, 5.87000006393, 1.64000006601, 4.21000005543, 0.179999993443, 5.31000006065, 0.539999995232, 5.56000006437, 0.490000033975, 5.49000007793, 0.339999989271, 5.3700000371, -0.28000001803, 4.95000009388, 0.560000053942, 4.65000004545, 0.940000015348, 4.81000006512, 0.540000002682, 
+
+L2_zGEMV_A_mn
+0.3, 0.7, 0.7, 0.2, 0.6, 0.4, 0.3, 0.7, 0.3, 0.7, 0.4, 0.1, 0.6, 0.7, 0.6, 0.6, 0.1, 0.5, 0.4, 0.9, 0.4, 0.5, 0.1, 0.1, 0.6, 0.9, 0.3, 0.8, 0.5, 0.3, 0.5, 0.3, 0.5, 0.4, 0.7, 0.7, 0.7, 0.6, 0.3, 0.3, 0.4, 0.5, 0.8, 0.9, 0.5, 0.4, 0.7, 0.2, 0.5, 0.8, 0.4, 0.5, 0.1, 0.2, 0.4, 0.5, 0.5, 0.1, 0.6, 0.4, 0.8, 0.4, 0.4, 0.5, 0.1, 0.6, 0.2, 0.2, 0.8, 0.8, 0.4, 0.9, 0.6, 0.9, 0.9, 0.8, 0.5, 0.1, 0.2, 0.8, 0.2, 0.5, 0.4, 0.5, 0.4, 0.6, 0.6, 0.8, 0.7, 0.6, 0.6, 0.8, 0.2, 0.8, 0.9, 0.2, 0.7, 0.3, 0.3, 0.4, 0.5, 0.6, 0.1, 0.7, 0.7, 0.6, 0.9, 0.4, 0.9, 0.2, 0.5, 0.8, 0.4, 0.6, 0.8, 0.5, 0.3, 0.3, 0.3, 0.2, 0.2, 0.8, 0.2, 0.9, 0.2, 0.5, 0.5, 0.3, 0.4, 0.5, 0.4, 0.7, 0.4, 0.6, 0.9, 0.2, 0.1, 0.9, 0.2, 0.5, 0.6, 0.8, 0.6, 0.5, 0.1, 0.6, 0.7, 0.5, 0.3, 0.1, 0.5, 0.1, 0.6, 0.4, 0.8, 0.6, 0.5, 0.4, 0.7, 0.2, 0.4, 0.6, 0.9, 0.7, 0.6, 0.3, 0.7, 0.6, 0.9, 0.2, 0.1, 0.3, 0.6, 0.5, 0.7, 0.3, 0.8, 0.4, 0.9, 0.4, 0.6, 0.2, 0.8, 0.5, 0.1, 0.8, 0.2, 0.1, 0.9, 0.8, 0.5, 0.3, 0.1, 0.8, 0.9, 0.9, 0.1, 0.8, 0.4, 0.7, 0.5, 0.9, 0.8, 0.6, 0.1, 0.8, 0.9, 0.1, 0.5, 0.4, 0.5, 0.7, 0.7, 0.7, 0.4, 0.7, 0.3, 0.6, 0.4, 0.8, 0.6, 0.7, 0.8, 0.3, 0.5, 0.6, 0.7, 0.3, 0.5, 0.3, 0.3, 0.8, 0.6, 0.8, 0.5, 0.3, 0.1, 0.6, 0.2, 0.5, 0.6, 0.9, 0.3, 0.8, 0.5, 0.7, 0.8, 0.9, 0.5, 0.5, 0.7, 0.1, 0.3, 0.4, 0.7, 0.5, 0.3, 0.1, 0.1, 0.4, 0.6, 0.6, 0.3, 0.3, 0.3, 0.7, 0.6, 0.1, 0.4, 0.8, 0.1, 0.8, 0.1, 0.8, 0.2, 0.5, 0.5, 0.8, 0.6, 0.1, 0.5, 0.7, 0.5, 0.8, 0.2, 0.5, 0.3, 0.5, 0.4, 0.3, 0.2, 0.1, 0.1, 0.6, 0.3, 0.9, 0.2, 0.1, 0.2, 0.8, 0.2, 0.2, 0.9, 0.3, 0.4, 0.9, 0.5, 0.9, 0.1, 0.5, 0.9, 0.4, 0.4, 0.1, 0.5, 0.2, 0.5, 0.8, 0.4, 0.8, 0.2, 0.9, 0.5, 0.5, 0.5, 0.7, 0.2, 0.7, 0.6, 0.6, 0.6, 0.1, 0.1, 0.2, 0.4, 0.7, 0.8, 0.3, 0.8, 0.2, 
+
+L2_zGEMV_x_n1
+0.4, 0.2, 0.6, 0.2, 0.1, 0.7, 0.2, 0.8, 0.4, 0.2, 0.9, 0.6, 0.5, 0.1, 0.6, 0.8, 0.2, 0.3, 0.1, 0.2, 0.9, 0.4, 0.1, 0.7, 0.9, 0.4, 0.9, 0.8, 0.1, 0.6, 0.1, 0.9, 0.8, 0.8, 
+
+L2_zGEMV_x_n2
+0.4, 0.2, 0.0, 0.0, 0.6, 0.2, 0.0, 0.0, 0.1, 0.7, 0.0, 0.0, 0.2, 0.8, 0.0, 0.0, 0.4, 0.2, 0.0, 0.0, 0.9, 0.6, 0.0, 0.0, 0.5, 0.1, 0.0, 0.0, 0.6, 0.8, 0.0, 0.0, 0.2, 0.3, 0.0, 0.0, 0.1, 0.2, 0.0, 0.0, 0.9, 0.4, 0.0, 0.0, 0.1, 0.7, 0.0, 0.0, 0.9, 0.4, 0.0, 0.0, 0.9, 0.8, 0.0, 0.0, 0.1, 0.6, 0.0, 0.0, 0.1, 0.9, 0.0, 0.0, 0.8, 0.8, 0.0, 0.0, 
+
+L2_zGEMV_y_m1
+0.7, 0.5, 0.2, 0.6, 0.8, 0.1, 0.5, 0.1, 0.1, 0.4, 0.9, 0.3, 0.4, 0.5, 0.5, 0.2, 0.6, 0.4, 0.5, 0.3, 
+
+L2_zGEMV_y_m2
+0.7, 0.5, 0.0, 0.0, 0.0, 0.0, 0.2, 0.6, 0.0, 0.0, 0.0, 0.0, 0.8, 0.1, 0.0, 0.0, 0.0, 0.0, 0.5, 0.1, 0.0, 0.0, 0.0, 0.0, 0.1, 0.4, 0.0, 0.0, 0.0, 0.0, 0.9, 0.3, 0.0, 0.0, 0.0, 0.0, 0.4, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.2, 0.0, 0.0, 0.0, 0.0, 0.6, 0.4, 0.0, 0.0, 0.0, 0.0, 0.5, 0.3, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zGEMV_o_N
+0.1, 8.39, 0.51, 8.0, -0.56, 9.56, 0.18, 8.46, 0.33, 9.43, -0.05, 8.77, -1.2, 9.11, -1.65, 7.85, -1.87, 8.4, -0.32, 8.49, 
+
+L2_zGEMV_o_N2
+0.1, 8.39, 0.0, 0.0, 0.0, 0.0, 0.51, 8.0, 0.0, 0.0, 0.0, 0.0, -0.56, 9.56, 0.0, 0.0, 0.0, 0.0, 0.18, 8.46, 0.0, 0.0, 0.0, 0.0, 0.33, 9.43, 0.0, 0.0, 0.0, 0.0, -0.05, 8.77, 0.0, 0.0, 0.0, 0.0, -1.2, 9.11, 0.0, 0.0, 0.0, 0.0, -1.65, 7.85, 0.0, 0.0, 0.0, 0.0, -1.87, 8.4, 0.0, 0.0, 0.0, 0.0, -0.32, 8.49, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zGEMV_o_T
+-0.47, 4.69, 1.75, 4.84, 1.58, 5.41, 1.82, 5.04, 1.26, 4.92, 1.51, 5.0, 1.64, 4.4, 0.23, 5.27, 0.6, 3.83, 1.08, 4.89, 1.05, 4.49, 0.7, 5.19, 1.88, 4.88, 0.66, 5.36, 0.98, 4.58, 1.13, 5.31, 2.04, 5.12, 
+
+L2_zGEMV_o_H
+4.45, -2.27, 4.83, -0.8, 5.02, -0.29, 5.08, 0.08, 5.68, -0.72, 4.91, -0.46, 4.68, -0.86, 4.41, -0.99, 3.68, -0.41, 4.34, -1.25, 4.61, -1.19, 3.44, -0.77, 5.06, -0.62, 4.96, -0.82, 4.16, -0.22, 4.41, -0.03, 5.12, -0.36, 
+
+L2_sGBMV_A_mn
+0.0, 0.0, 0.3, 0.1, 0.0, 0.2, 0.1, 0.2, 0.9, 0.1, 0.3, 0.1, 0.9, 0.1, 0.3, 0.5, 0.6, 0.8, 0.3, 0.7, 0.6, 0.8, 0.9, 0.7, 0.6, 0.6, 0.3, 0.3, 0.6, 0.2, 0.8, 0.7, 0.2, 0.1, 0.8, 0.3, 0.5, 0.7, 0.4, 0.3, 
+
+L2_sGBMV_x_n1
+0.2, 0.8, 0.6, 0.9, 0.1, 0.2, 0.7, 0.5, 0.1, 0.2, 0.3, 0.8, 0.1, 0.5, 0.7, 0.2, 0.9, 
+
+L2_sGBMV_x_n2
+0.2, 0.0, 0.8, 0.0, 0.6, 0.0, 0.9, 0.0, 0.1, 0.0, 0.2, 0.0, 0.7, 0.0, 0.5, 0.0, 0.1, 0.0, 0.2, 0.0, 0.3, 0.0, 0.8, 0.0, 0.1, 0.0, 0.5, 0.0, 0.7, 0.0, 0.2, 0.0, 0.9, 0.0, 
+
+L2_sGBMV_y_m1
+0.9, 0.8, 0.3, 0.4, 0.7, 0.7, 0.2, 0.3, 0.9, 0.8, 
+
+L2_sGBMV_y_m2
+0.9, 0.0, 0.0, 0.8, 0.0, 0.0, 0.3, 0.0, 0.0, 0.4, 0.0, 0.0, 0.7, 0.0, 0.0, 0.7, 0.0, 0.0, 0.2, 0.0, 0.0, 0.3, 0.0, 0.0, 0.9, 0.0, 0.0, 0.8, 0.0, 0.0, 
+
+L2_sGBMV_o_N
+1.03999998182, 1.04000002205, 0.830000025481, 1.50000000522, 1.95000000969, 1.98999997884, 0.740000023544, 1.03000002399, 1.22999998227, 1.29000002131, 
+
+L2_sGBMV_o_N2
+1.03999998182, 0.0, 0.0, 1.04000002205, 0.0, 0.0, 0.830000025481, 0.0, 0.0, 1.50000000522, 0.0, 0.0, 1.95000000969, 0.0, 0.0, 1.98999997884, 0.0, 0.0, 0.740000023544, 0.0, 0.0, 1.03000002399, 0.0, 0.0, 1.22999998227, 0.0, 0.0, 1.29000002131, 0.0, 0.0, 
+
+L2_sGBMV_o_T
+0.900000014901, 1.36000001073, 1.31000004649, 2.0299999927, 1.1900000146, 1.61999997973, 1.48999997586, 1.29000002131, 1.58999999672, 0.790000016093, 0.540000025034, 0.800000011921, 0.10000000149, 0.5, 0.699999988079, 0.20000000298, 0.899999976158, 
+
+L2_sGBMV_o_H
+0.900000014901, 1.36000001073, 1.31000004649, 2.0299999927, 1.1900000146, 1.61999997973, 1.48999997586, 1.29000002131, 1.58999999672, 0.790000016093, 0.540000025034, 0.800000011921, 0.10000000149, 0.5, 0.699999988079, 0.20000000298, 0.899999976158, 
+
+L2_dGBMV_A_mn
+0.0, 0.0, 0.5, 0.8, 0.0, 0.9, 0.1, 0.5, 0.4, 0.1, 0.4, 0.1, 0.5, 0.9, 0.9, 0.4, 0.8, 0.7, 0.7, 0.9, 0.7, 0.3, 0.5, 0.9, 0.3, 0.4, 0.3, 0.2, 0.4, 0.8, 0.3, 0.4, 0.6, 0.8, 0.4, 0.7, 0.7, 0.5, 0.3, 0.9, 
+
+L2_dGBMV_x_n1
+0.9, 0.3, 0.1, 0.5, 0.5, 0.9, 0.5, 0.1, 0.7, 0.4, 0.4, 0.6, 0.8, 0.2, 0.1, 0.9, 0.9, 
+
+L2_dGBMV_x_n2
+0.9, 0.0, 0.3, 0.0, 0.1, 0.0, 0.5, 0.0, 0.5, 0.0, 0.9, 0.0, 0.5, 0.0, 0.1, 0.0, 0.7, 0.0, 0.4, 0.0, 0.4, 0.0, 0.6, 0.0, 0.8, 0.0, 0.2, 0.0, 0.1, 0.0, 0.9, 0.0, 0.9, 0.0, 
+
+L2_dGBMV_y_m1
+0.5, 0.1, 0.4, 0.4, 0.2, 0.5, 0.1, 0.3, 0.8, 0.7, 
+
+L2_dGBMV_y_m2
+0.5, 0.0, 0.0, 0.1, 0.0, 0.0, 0.4, 0.0, 0.0, 0.4, 0.0, 0.0, 0.2, 0.0, 0.0, 0.5, 0.0, 0.0, 0.1, 0.0, 0.0, 0.3, 0.0, 0.0, 0.8, 0.0, 0.0, 0.7, 0.0, 0.0, 
+
+L2_dGBMV_o_N
+1.19, 0.99, 0.88, 1.29, 1.79, 1.9, 0.78, 1.37, 1.74, 1.6, 
+
+L2_dGBMV_o_N2
+1.19, 0.0, 0.0, 0.99, 0.0, 0.0, 0.88, 0.0, 0.0, 1.29, 0.0, 0.0, 1.79, 0.0, 0.0, 1.9, 0.0, 0.0, 0.78, 0.0, 0.0, 1.37, 0.0, 0.0, 1.74, 0.0, 0.0, 1.6, 0.0, 0.0, 
+
+L2_dGBMV_o_T
+1.4, 0.95, 0.83, 1.39, 0.98, 1.49, 1.7, 1.34, 1.49, 1.17, 1.03, 0.6, 0.8, 0.2, 0.1, 0.9, 0.9, 
+
+L2_dGBMV_o_H
+1.4, 0.95, 0.83, 1.39, 0.98, 1.49, 1.7, 1.34, 1.49, 1.17, 1.03, 0.6, 0.8, 0.2, 0.1, 0.9, 0.9, 
+
+L2_cGBMV_A_mn
+0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.5, 0.40000000596, 0.10000000149, 0.0, 0.0, 0.600000023842, 0.800000011921, 0.10000000149, 0.899999976158, 0.600000023842, 0.899999976158, 0.800000011921, 0.20000000298, 0.300000011921, 0.600000023842, 0.300000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.5, 0.300000011921, 0.5, 0.899999976158, 0.300000011921, 0.10000000149, 0.20000000298, 0.899999976158, 0.899999976158, 0.800000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.10000000149, 0.20000000298, 0.699999988079, 0.899999976158, 0.800000011921, 0.5, 0.899999976158, 0.10000000149, 0.699999988079, 0.899999976158, 0.40000000596, 0.10000000149, 0.20000000298, 0.5, 0.20000000298, 0.899999976158, 0.699999988079, 0.600000023842, 0.5, 0.600000023842, 0.800000011921, 0.10000000149, 0.5, 0.699999988079, 0.699999988079, 0.20000000298, 0.600000023842, 0.10000000149, 0.800000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.300000011921, 0.5, 0.20000000298, 0.5, 0.20000000298, 0.300000011921, 0.899999976158, 0.20000000298, 0.300000011921, 0.600000023842, 0.699999988079, 
+
+L2_cGBMV_x_n1
+0.5, 0.600000023842, 0.5, 0.20000000298, 0.300000011921, 0.40000000596, 0.5, 0.40000000596, 0.899999976158, 0.800000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.40000000596, 0.899999976158, 0.699999988079, 0.300000011921, 0.600000023842, 0.600000023842, 0.5, 0.600000023842, 0.5, 0.699999988079, 0.699999988079, 0.699999988079, 0.600000023842, 0.5, 0.40000000596, 0.600000023842, 0.5, 0.5, 0.699999988079, 0.20000000298, 0.40000000596, 
+
+L2_cGBMV_x_n2
+0.5, 0.600000023842, 0.0, 0.0, 0.5, 0.20000000298, 0.0, 0.0, 0.300000011921, 0.40000000596, 0.0, 0.0, 0.5, 0.40000000596, 0.0, 0.0, 0.899999976158, 0.800000011921, 0.0, 0.0, 0.800000011921, 0.10000000149, 0.0, 0.0, 0.699999988079, 0.40000000596, 0.0, 0.0, 0.899999976158, 0.699999988079, 0.0, 0.0, 0.300000011921, 0.600000023842, 0.0, 0.0, 0.600000023842, 0.5, 0.0, 0.0, 0.600000023842, 0.5, 0.0, 0.0, 0.699999988079, 0.699999988079, 0.0, 0.0, 0.699999988079, 0.600000023842, 0.0, 0.0, 0.5, 0.40000000596, 0.0, 0.0, 0.600000023842, 0.5, 0.0, 0.0, 0.5, 0.699999988079, 0.0, 0.0, 0.20000000298, 0.40000000596, 0.0, 0.0, 
+
+L2_cGBMV_y_m1
+0.5, 0.5, 0.10000000149, 0.40000000596, 0.20000000298, 0.5, 0.300000011921, 0.20000000298, 0.800000011921, 0.300000011921, 0.10000000149, 0.600000023842, 0.5, 0.20000000298, 0.10000000149, 0.600000023842, 0.600000023842, 0.20000000298, 0.40000000596, 0.699999988079, 
+
+L2_cGBMV_y_m2
+0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.5, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.5, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cGBMV_o_N
+0.729999984503, 1.30000001267, -0.389999991506, 2.1400000459, 0.379999994934, 1.92000006765, -0.149999970198, 2.05999998614, 1.22999998525, 2.47000004008, 0.439999946803, 3.77999998301, 1.34999998584, 2.38999998555, 0.209999986142, 3.11000001818, 0.510000021905, 2.24000003844, 0.240000029504, 2.68000003517, 
+
+L2_cGBMV_o_N2
+0.729999984503, 1.30000001267, 0.0, 0.0, 0.0, 0.0, -0.389999991506, 2.1400000459, 0.0, 0.0, 0.0, 0.0, 0.379999994934, 1.92000006765, 0.0, 0.0, 0.0, 0.0, -0.149999970198, 2.05999998614, 0.0, 0.0, 0.0, 0.0, 1.22999998525, 2.47000004008, 0.0, 0.0, 0.0, 0.0, 0.439999946803, 3.77999998301, 0.0, 0.0, 0.0, 0.0, 1.34999998584, 2.38999998555, 0.0, 0.0, 0.0, 0.0, 0.209999986142, 3.11000001818, 0.0, 0.0, 0.0, 0.0, 0.510000021905, 2.24000003844, 0.0, 0.0, 0.0, 0.0, 0.240000029504, 2.68000003517, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cGBMV_o_T
+0.399999991059, 1.96000004053, 0.150000000745, 1.04000002801, 0.209999997318, 2.28000005826, 0.499999963492, 1.94000005409, 0.589999982566, 1.82000003859, 0.129999978542, 1.49000004068, 0.469999949187, 2.1200000371, 0.849999984354, 2.27000001475, -0.129999959171, 1.69000005335, 0.730000032187, 0.980000014305, 0.350000053644, 1.20000000894, 0.699999988079, 0.699999988079, 0.699999988079, 0.600000023842, 0.5, 0.40000000596, 0.600000023842, 0.5, 0.5, 0.699999988079, 0.20000000298, 0.40000000596, 
+
+L2_cGBMV_o_H
+1.74000001311, 1.22000003338, 1.69000002429, 0.340000001192, 2.37000003487, 0.0400000019372, 2.06000004873, 0.679999991208, 2.16999999836, 0.740000025779, 2.43000006199, -0.129999964386, 2.1500000082, 0.279999992698, 2.33000001058, 0.989999984056, 1.97000004977, 0.490000026524, 1.23000004411, 0.499999988079, 1.33000002027, 0.640000010133, 0.699999988079, 0.699999988079, 0.699999988079, 0.600000023842, 0.5, 0.40000000596, 0.600000023842, 0.5, 0.5, 0.699999988079, 0.20000000298, 0.40000000596, 
+
+L2_zGBMV_A_mn
+0.0, 0.0, 0.0, 0.0, 0.3, 0.6, 0.4, 0.4, 0.0, 0.0, 0.1, 0.3, 0.5, 0.1, 0.1, 0.8, 0.7, 0.7, 0.1, 0.2, 0.4, 0.6, 0.1, 0.1, 0.9, 0.3, 0.7, 0.6, 0.8, 0.1, 0.2, 0.7, 0.7, 0.2, 0.2, 0.1, 0.6, 0.4, 0.6, 0.6, 0.5, 0.5, 0.4, 0.6, 0.3, 0.2, 0.5, 0.8, 0.5, 0.5, 0.5, 0.4, 0.9, 0.1, 0.2, 0.1, 0.7, 0.8, 0.1, 0.4, 0.7, 0.8, 0.5, 0.6, 0.3, 0.9, 0.2, 0.8, 0.9, 0.1, 0.6, 0.3, 0.4, 0.8, 0.5, 0.5, 0.1, 0.5, 0.5, 0.3, 
+
+L2_zGBMV_x_n1
+0.1, 0.4, 0.6, 0.8, 0.7, 0.7, 0.6, 0.2, 0.2, 0.4, 0.1, 0.8, 0.7, 0.8, 0.7, 0.4, 0.5, 0.9, 0.1, 0.1, 0.5, 0.3, 0.9, 0.6, 0.4, 0.6, 0.7, 0.5, 0.3, 0.5, 0.9, 0.4, 0.9, 0.6, 
+
+L2_zGBMV_x_n2
+0.1, 0.4, 0.0, 0.0, 0.6, 0.8, 0.0, 0.0, 0.7, 0.7, 0.0, 0.0, 0.6, 0.2, 0.0, 0.0, 0.2, 0.4, 0.0, 0.0, 0.1, 0.8, 0.0, 0.0, 0.7, 0.8, 0.0, 0.0, 0.7, 0.4, 0.0, 0.0, 0.5, 0.9, 0.0, 0.0, 0.1, 0.1, 0.0, 0.0, 0.5, 0.3, 0.0, 0.0, 0.9, 0.6, 0.0, 0.0, 0.4, 0.6, 0.0, 0.0, 0.7, 0.5, 0.0, 0.0, 0.3, 0.5, 0.0, 0.0, 0.9, 0.4, 0.0, 0.0, 0.9, 0.6, 0.0, 0.0, 
+
+L2_zGBMV_y_m1
+0.5, 0.7, 0.7, 0.2, 0.5, 0.6, 0.8, 0.9, 0.3, 0.8, 0.1, 0.7, 0.8, 0.6, 0.7, 0.6, 0.7, 0.1, 0.1, 0.3, 
+
+L2_zGBMV_y_m2
+0.5, 0.7, 0.0, 0.0, 0.0, 0.0, 0.7, 0.2, 0.0, 0.0, 0.0, 0.0, 0.5, 0.6, 0.0, 0.0, 0.0, 0.0, 0.8, 0.9, 0.0, 0.0, 0.0, 0.0, 0.3, 0.8, 0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, 0.0, 0.0, 0.0, 0.8, 0.6, 0.0, 0.0, 0.0, 0.0, 0.7, 0.6, 0.0, 0.0, 0.0, 0.0, 0.7, 0.1, 0.0, 0.0, 0.0, 0.0, 0.1, 0.3, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zGBMV_o_N
+0.21, 1.44, 0.32, 1.36, 0.09, 1.93, 1.39, 3.15, 0.29, 2.39, -0.28, 2.6, 1.08, 2.28, -0.24, 3.19, 0.4, 2.56, -0.02, 2.08, 
+
+L2_zGBMV_o_N2
+0.21, 1.44, 0.0, 0.0, 0.0, 0.0, 0.32, 1.36, 0.0, 0.0, 0.0, 0.0, 0.09, 1.93, 0.0, 0.0, 0.0, 0.0, 1.39, 3.15, 0.0, 0.0, 0.0, 0.0, 0.29, 2.39, 0.0, 0.0, 0.0, 0.0, -0.28, 2.6, 0.0, 0.0, 0.0, 0.0, 1.08, 2.28, 0.0, 0.0, 0.0, 0.0, -0.24, 3.19, 0.0, 0.0, 0.0, 0.0, 0.4, 2.56, 0.0, 0.0, 0.0, 0.0, -0.02, 2.08, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zGBMV_o_T
+-0.23, 1.91, 1.23, 2.66, 0.52, 3.55, 0.82, 1.7, -0.69, 2.78, -0.14, 3.29, 0.8, 2.85, 0.67, 2.36, 1.01, 1.98, 0.35, 0.45, 0.46, 0.48, 0.9, 0.6, 0.4, 0.6, 0.7, 0.5, 0.3, 0.5, 0.9, 0.4, 0.9, 0.6, 
+
+L2_zGBMV_o_H
+1.57, 0.19, 2.61, 1.44, 2.96, 0.75, 1.98, 1.28, 2.65, 0.5, 2.54, 1.13, 2.7, 0.71, 2.39, -0.2, 2.05, 0.9, 0.71, -0.07, 0.64, 0.42, 0.9, 0.6, 0.4, 0.6, 0.7, 0.5, 0.3, 0.5, 0.9, 0.4, 0.9, 0.6, 
+
+L2_cHEMV_A_nn
+0.800000011921, 0.0, 0.5, 0.800000011921, 0.699999988079, 0.800000011921, 0.300000011921, 0.20000000298, 0.10000000149, 0.800000011921, 0.600000023842, 0.5, 0.40000000596, 0.300000011921, 0.899999976158, 0.20000000298, 0.5, 0.5, 0.699999988079, 0.10000000149, 0.300000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.20000000298, 0.699999988079, 0.40000000596, 0.10000000149, 0.10000000149, 0.10000000149, 0.40000000596, 0.5, -0.800000011921, 0.899999976158, 0.0, 0.20000000298, 0.600000023842, 0.699999988079, 0.40000000596, 0.600000023842, 0.10000000149, 0.20000000298, 0.40000000596, 0.699999988079, 0.10000000149, 0.20000000298, 0.300000011921, 0.5, 0.300000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.800000011921, 0.10000000149, 0.899999976158, 0.40000000596, 0.5, 0.40000000596, 0.800000011921, 0.899999976158, 0.300000011921, 0.699999988079, 0.699999988079, 0.10000000149, 0.40000000596, 0.699999988079, -0.800000011921, 0.20000000298, -0.600000023842, 0.5, 0.0, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 0.699999988079, 0.699999988079, 0.5, 0.5, 0.40000000596, 0.20000000298, 0.800000011921, 0.699999988079, 0.300000011921, 0.699999988079, 0.5, 0.5, 0.20000000298, 0.800000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.40000000596, 0.20000000298, 0.300000011921, 0.40000000596, 0.5, 0.300000011921, 0.300000011921, 0.300000011921, -0.20000000298, 0.699999988079, -0.40000000596, 0.10000000149, -0.300000011921, 0.899999976158, 0.0, 0.899999976158, 0.699999988079, 0.600000023842, 0.10000000149, 0.600000023842, 0.800000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.300000011921, 0.600000023842, 0.40000000596, 0.10000000149, 0.10000000149, 0.20000000298, 0.699999988079, 0.5, 0.5, 0.20000000298, 0.699999988079, 0.899999976158, 0.800000011921, 0.20000000298, 0.10000000149, 0.699999988079, 0.899999976158, 0.10000000149, -0.800000011921, 0.600000023842, -0.10000000149, 0.800000011921, -0.899999976158, 0.899999976158, -0.699999988079, 0.40000000596, 0.0, 0.5, 0.300000011921, 0.20000000298, 0.600000023842, 0.5, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.600000023842, 0.800000011921, 0.800000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.40000000596, 0.40000000596, 0.899999976158, 0.600000023842, 0.699999988079, 0.5, 0.300000011921, 0.40000000596, 0.600000023842, 0.600000023842, -0.5, 0.20000000298, -0.40000000596, 0.699999988079, -0.699999988079, 0.600000023842, -0.10000000149, 0.5, -0.300000011921, 0.300000011921, 0.0, 0.800000011921, 0.899999976158, 0.600000023842, 0.5, 0.300000011921, 0.600000023842, 0.5, 0.800000011921, 0.800000011921, 0.10000000149, 0.40000000596, 0.699999988079, 0.40000000596, 0.600000023842, 0.300000011921, 0.800000011921, 0.20000000298, 0.600000023842, 0.300000011921, 0.600000023842, 0.699999988079, 0.20000000298, 0.40000000596, -0.300000011921, 0.699999988079, -0.10000000149, 0.5, -0.5, 0.600000023842, -0.800000011921, 0.20000000298, -0.600000023842, 0.800000011921, -0.899999976158, 0.699999988079, 0.0, 0.300000011921, 0.20000000298, 0.5, 0.40000000596, 0.699999988079, 0.600000023842, 0.5, 0.20000000298, 0.20000000298, 0.300000011921, 0.800000011921, 0.899999976158, 0.300000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.20000000298, 0.40000000596, 0.800000011921, 0.600000023842, 0.899999976158, -0.20000000298, 0.20000000298, -0.300000011921, 0.40000000596, -0.20000000298, 0.10000000149, -0.800000011921, 0.5, -0.899999976158, 0.600000023842, -0.5, 0.300000011921, -0.20000000298, 0.899999976158, 0.0, 0.600000023842, 0.699999988079, 0.40000000596, 0.10000000149, 0.300000011921, 0.699999988079, 0.600000023842, 0.20000000298, 0.5, 0.600000023842, 0.5, 0.40000000596, 0.10000000149, 0.10000000149, 0.5, 0.5, 0.600000023842, 0.300000011921, 0.5, -0.5, 0.5, -0.300000011921, 0.800000011921, -0.699999988079, 0.10000000149, -0.300000011921, 0.10000000149, -0.800000011921, 0.300000011921, -0.600000023842, 0.5, -0.40000000596, 0.600000023842, -0.699999988079, 0.600000023842, 0.0, 0.800000011921, 0.20000000298, 0.300000011921, 0.5, 0.10000000149, 0.10000000149, 0.40000000596, 0.800000011921, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.600000023842, 0.699999988079, 0.699999988079, 0.699999988079, 0.699999988079, -0.10000000149, 0.40000000596, -0.40000000596, 0.300000011921, -0.699999988079, 0.600000023842, -0.40000000596, 0.800000011921, -0.600000023842, 0.5, -0.800000011921, 0.699999988079, -0.600000023842, 0.40000000596, -0.10000000149, 0.800000011921, -0.20000000298, 0.300000011921, 0.0, 0.600000023842, 0.300000011921, 0.699999988079, 0.699999988079, 0.800000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.300000011921, 0.40000000596, 0.10000000149, 0.699999988079, 0.40000000596, 0.5, 0.300000011921, -0.600000023842, 0.800000011921, -0.800000011921, 0.5, -0.5, 0.10000000149, -0.10000000149, 0.800000011921, -0.800000011921, 0.800000011921, -0.10000000149, 0.5, -0.20000000298, 0.300000011921, -0.699999988079, 0.300000011921, -0.5, 0.600000023842, -0.300000011921, 0.20000000298, 0.0, 0.20000000298, 0.300000011921, 0.300000011921, 0.5, 0.699999988079, 0.699999988079, 0.699999988079, 0.40000000596, 0.40000000596, 0.600000023842, 0.10000000149, 0.300000011921, 0.899999976158, -0.300000011921, 0.10000000149, -0.899999976158, 0.20000000298, -0.800000011921, 0.20000000298, -0.699999988079, 0.899999976158, -0.20000000298, 0.40000000596, -0.699999988079, 0.20000000298, -0.300000011921, 0.600000023842, -0.20000000298, 0.10000000149, -0.10000000149, 0.699999988079, -0.699999988079, 0.20000000298, -0.300000011921, 0.800000011921, 0.0, 0.600000023842, 0.20000000298, 0.800000011921, 0.20000000298, 0.300000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.699999988079, 0.10000000149, 0.10000000149, -0.800000011921, 0.40000000596, -0.5, 0.899999976158, -0.899999976158, 0.5, -0.5, 0.800000011921, -0.40000000596, 0.40000000596, -0.600000023842, 0.800000011921, -0.899999976158, 0.5, -0.600000023842, 0.40000000596, -0.800000011921, 0.800000011921, -0.899999976158, 0.300000011921, -0.5, 0.600000023842, -0.20000000298, 0.300000011921, 0.0, 0.899999976158, 0.10000000149, 0.5, 0.20000000298, 0.800000011921, 0.300000011921, 0.699999988079, 0.5, 0.10000000149, -0.20000000298, 0.40000000596, -0.800000011921, 0.10000000149, -0.40000000596, 0.20000000298, -0.699999988079, 0.40000000596, -0.899999976158, 0.300000011921, -0.800000011921, 0.300000011921, -0.699999988079, 0.5, -0.40000000596, 0.899999976158, -0.10000000149, 0.899999976158, -0.10000000149, 0.699999988079, -0.699999988079, 0.800000011921, -0.20000000298, 0.899999976158, -0.10000000149, 0.800000011921, 0.0, 0.40000000596, 0.10000000149, 0.20000000298, 0.300000011921, 0.20000000298, 0.300000011921, 0.699999988079, -0.40000000596, 0.899999976158, -0.300000011921, 0.20000000298, -0.300000011921, 0.899999976158, -0.800000011921, 0.600000023842, -0.699999988079, 0.20000000298, -0.600000023842, 0.300000011921, -0.899999976158, 0.10000000149, -0.10000000149, 0.800000011921, -0.800000011921, 0.300000011921, -0.40000000596, 0.699999988079, -0.40000000596, 0.300000011921, -0.300000011921, 0.5, -0.20000000298, 0.40000000596, -0.10000000149, 0.600000023842, 0.0, 0.699999988079, 0.899999976158, 0.899999976158, 0.300000011921, 0.10000000149, -0.10000000149, 0.699999988079, -0.699999988079, 0.40000000596, -0.5, 0.20000000298, -0.10000000149, 0.5, -0.300000011921, 0.300000011921, -0.600000023842, 0.20000000298, -0.40000000596, 0.5, -0.5, 0.600000023842, -0.699999988079, 0.10000000149, -0.699999988079, 0.40000000596, -0.600000023842, 0.899999976158, -0.20000000298, 0.800000011921, -0.300000011921, 0.20000000298, -0.300000011921, 0.699999988079, -0.899999976158, 0.899999976158, 0.0, 0.300000011921, 0.40000000596, 0.10000000149, -0.40000000596, 0.10000000149, -0.40000000596, 0.300000011921, -0.300000011921, 0.699999988079, -0.899999976158, 0.40000000596, -0.600000023842, 0.699999988079, -0.20000000298, 0.800000011921, -0.600000023842, 0.600000023842, -0.300000011921, 0.699999988079, -0.699999988079, 0.40000000596, -0.5, 0.10000000149, -0.300000011921, 0.699999988079, -0.10000000149, 0.699999988079, -0.5, 0.20000000298, -0.300000011921, 0.899999976158, -0.300000011921, 0.300000011921, -0.40000000596, 0.5, 0.0, 
+
+L2_cHEMV_A_nn_pu
+0.800000011921, 0.0, 0.5, 0.800000011921, 0.699999988079, 0.800000011921, 0.300000011921, 0.20000000298, 0.10000000149, 0.800000011921, 0.600000023842, 0.5, 0.40000000596, 0.300000011921, 0.899999976158, 0.20000000298, 0.5, 0.5, 0.699999988079, 0.10000000149, 0.300000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.20000000298, 0.699999988079, 0.40000000596, 0.10000000149, 0.10000000149, 0.10000000149, 0.40000000596, 0.899999976158, 0.0, 0.20000000298, 0.600000023842, 0.699999988079, 0.40000000596, 0.600000023842, 0.10000000149, 0.20000000298, 0.40000000596, 0.699999988079, 0.10000000149, 0.20000000298, 0.300000011921, 0.5, 0.300000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.800000011921, 0.10000000149, 0.899999976158, 0.40000000596, 0.5, 0.40000000596, 0.800000011921, 0.899999976158, 0.300000011921, 0.699999988079, 0.699999988079, 0.10000000149, 0.40000000596, 0.5, 0.0, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 0.699999988079, 0.699999988079, 0.5, 0.5, 0.40000000596, 0.20000000298, 0.800000011921, 0.699999988079, 0.300000011921, 0.699999988079, 0.5, 0.5, 0.20000000298, 0.800000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.40000000596, 0.20000000298, 0.300000011921, 0.40000000596, 0.5, 0.300000011921, 0.300000011921, 0.899999976158, 0.0, 0.899999976158, 0.699999988079, 0.600000023842, 0.10000000149, 0.600000023842, 0.800000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.300000011921, 0.600000023842, 0.40000000596, 0.10000000149, 0.10000000149, 0.20000000298, 0.699999988079, 0.5, 0.5, 0.20000000298, 0.699999988079, 0.899999976158, 0.800000011921, 0.20000000298, 0.10000000149, 0.699999988079, 0.899999976158, 0.40000000596, 0.0, 0.5, 0.300000011921, 0.20000000298, 0.600000023842, 0.5, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.600000023842, 0.800000011921, 0.800000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.40000000596, 0.40000000596, 0.899999976158, 0.600000023842, 0.699999988079, 0.5, 0.300000011921, 0.40000000596, 0.600000023842, 0.300000011921, 0.0, 0.800000011921, 0.899999976158, 0.600000023842, 0.5, 0.300000011921, 0.600000023842, 0.5, 0.800000011921, 0.800000011921, 0.10000000149, 0.40000000596, 0.699999988079, 0.40000000596, 0.600000023842, 0.300000011921, 0.800000011921, 0.20000000298, 0.600000023842, 0.300000011921, 0.600000023842, 0.699999988079, 0.20000000298, 0.699999988079, 0.0, 0.300000011921, 0.20000000298, 0.5, 0.40000000596, 0.699999988079, 0.600000023842, 0.5, 0.20000000298, 0.20000000298, 0.300000011921, 0.800000011921, 0.899999976158, 0.300000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.20000000298, 0.40000000596, 0.800000011921, 0.600000023842, 0.899999976158, 0.0, 0.600000023842, 0.699999988079, 0.40000000596, 0.10000000149, 0.300000011921, 0.699999988079, 0.600000023842, 0.20000000298, 0.5, 0.600000023842, 0.5, 0.40000000596, 0.10000000149, 0.10000000149, 0.5, 0.5, 0.600000023842, 0.300000011921, 0.600000023842, 0.0, 0.800000011921, 0.20000000298, 0.300000011921, 0.5, 0.10000000149, 0.10000000149, 0.40000000596, 0.800000011921, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.600000023842, 0.699999988079, 0.699999988079, 0.699999988079, 0.300000011921, 0.0, 0.600000023842, 0.300000011921, 0.699999988079, 0.699999988079, 0.800000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.300000011921, 0.40000000596, 0.10000000149, 0.699999988079, 0.40000000596, 0.5, 0.20000000298, 0.0, 0.20000000298, 0.300000011921, 0.300000011921, 0.5, 0.699999988079, 0.699999988079, 0.699999988079, 0.40000000596, 0.40000000596, 0.600000023842, 0.10000000149, 0.300000011921, 0.800000011921, 0.0, 0.600000023842, 0.20000000298, 0.800000011921, 0.20000000298, 0.300000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.699999988079, 0.10000000149, 0.300000011921, 0.0, 0.899999976158, 0.10000000149, 0.5, 0.20000000298, 0.800000011921, 0.300000011921, 0.699999988079, 0.5, 0.800000011921, 0.0, 0.40000000596, 0.10000000149, 0.20000000298, 0.300000011921, 0.20000000298, 0.300000011921, 0.600000023842, 0.0, 0.699999988079, 0.899999976158, 0.899999976158, 0.300000011921, 0.899999976158, 0.0, 0.300000011921, 0.40000000596, 0.5, 0.0, 
+
+L2_cHEMV_x_n1
+0.10000000149, 0.40000000596, 0.300000011921, 0.300000011921, 0.300000011921, 0.899999976158, 0.600000023842, 0.800000011921, 0.300000011921, 0.10000000149, 0.300000011921, 0.10000000149, 0.899999976158, 0.5, 0.300000011921, 0.5, 0.899999976158, 0.40000000596, 0.40000000596, 0.40000000596, 0.899999976158, 0.899999976158, 0.800000011921, 0.5, 0.20000000298, 0.300000011921, 0.5, 0.10000000149, 0.10000000149, 0.20000000298, 0.300000011921, 0.5, 0.5, 0.600000023842, 
+
+L2_cHEMV_x_n2
+0.10000000149, 0.40000000596, 0.0, 0.0, 0.300000011921, 0.300000011921, 0.0, 0.0, 0.300000011921, 0.899999976158, 0.0, 0.0, 0.600000023842, 0.800000011921, 0.0, 0.0, 0.300000011921, 0.10000000149, 0.0, 0.0, 0.300000011921, 0.10000000149, 0.0, 0.0, 0.899999976158, 0.5, 0.0, 0.0, 0.300000011921, 0.5, 0.0, 0.0, 0.899999976158, 0.40000000596, 0.0, 0.0, 0.40000000596, 0.40000000596, 0.0, 0.0, 0.899999976158, 0.899999976158, 0.0, 0.0, 0.800000011921, 0.5, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.0, 0.0, 0.5, 0.10000000149, 0.0, 0.0, 0.10000000149, 0.20000000298, 0.0, 0.0, 0.300000011921, 0.5, 0.0, 0.0, 0.5, 0.600000023842, 0.0, 0.0, 
+
+L2_cHEMV_y_n1
+0.40000000596, 0.40000000596, 0.800000011921, 0.20000000298, 0.800000011921, 0.899999976158, 0.800000011921, 0.5, 0.899999976158, 0.5, 0.40000000596, 0.20000000298, 0.20000000298, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.300000011921, 0.899999976158, 0.40000000596, 0.300000011921, 0.699999988079, 0.800000011921, 0.600000023842, 0.300000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.800000011921, 0.40000000596, 0.5, 0.20000000298, 0.40000000596, 0.40000000596, 
+
+L2_cHEMV_y_n2
+0.40000000596, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.5, 0.0, 0.0, 0.0, 0.0, 0.899999976158, 0.5, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.899999976158, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.5, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cHEMV_o_N
+0.739999967664, 7.07000008181, 1.44999999404, 7.30000005662, 1.67000003487, 7.67999999344, 1.81000004649, 6.5400000377, 3.78999994904, 7.950000038, 2.99000002354, 7.19000005409, 3.60000000298, 5.52000003189, 3.57000014737, 5.01000000477, 3.89000004664, 3.95000003204, 5.54000002056, 4.05000003651, 4.24000006527, 2.67000003338, 6.51000007257, 2.03000002325, 8.07000004455, 1.22000005722, 6.97999996439, 1.13000004038, 7.23000007689, 1.47000000134, 6.52000005201, 0.600000000745, 7.33000007316, 0.609999997318, 
+
+L2_cHEMV_o_N2
+0.739999967664, 7.07000008181, 0.0, 0.0, 0.0, 0.0, 1.44999999404, 7.30000005662, 0.0, 0.0, 0.0, 0.0, 1.67000003487, 7.67999999344, 0.0, 0.0, 0.0, 0.0, 1.81000004649, 6.5400000377, 0.0, 0.0, 0.0, 0.0, 3.78999994904, 7.950000038, 0.0, 0.0, 0.0, 0.0, 2.99000002354, 7.19000005409, 0.0, 0.0, 0.0, 0.0, 3.60000000298, 5.52000003189, 0.0, 0.0, 0.0, 0.0, 3.57000014737, 5.01000000477, 0.0, 0.0, 0.0, 0.0, 3.89000004664, 3.95000003204, 0.0, 0.0, 0.0, 0.0, 5.54000002056, 4.05000003651, 0.0, 0.0, 0.0, 0.0, 4.24000006527, 2.67000003338, 0.0, 0.0, 0.0, 0.0, 6.51000007257, 2.03000002325, 0.0, 0.0, 0.0, 0.0, 8.07000004455, 1.22000005722, 0.0, 0.0, 0.0, 0.0, 6.97999996439, 1.13000004038, 0.0, 0.0, 0.0, 0.0, 7.23000007689, 1.47000000134, 0.0, 0.0, 0.0, 0.0, 6.52000005201, 0.600000000745, 0.0, 0.0, 0.0, 0.0, 7.33000007316, 0.609999997318, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zHEMV_A_nn
+0.3, 0.0, 0.6, 0.2, 0.8, 0.4, 0.7, 0.7, 0.1, 0.3, 0.9, 0.5, 0.5, 0.3, 0.3, 0.9, 0.1, 0.7, 0.9, 0.8, 0.4, 0.8, 0.6, 0.1, 0.3, 0.8, 0.7, 0.9, 0.8, 0.6, 0.1, 0.1, 0.8, 0.1, 0.6, -0.2, 0.7, 0.0, 0.9, 0.1, 0.3, 0.7, 0.6, 0.2, 0.5, 0.3, 0.8, 0.8, 0.1, 0.2, 0.8, 0.2, 0.4, 0.9, 0.9, 0.5, 0.1, 0.4, 0.5, 0.3, 0.1, 0.3, 0.8, 0.3, 0.2, 0.1, 0.1, 0.2, 0.8, -0.4, 0.9, -0.1, 0.9, 0.0, 0.8, 0.6, 0.3, 0.2, 0.9, 0.8, 0.5, 0.4, 0.6, 0.7, 0.5, 0.6, 0.2, 0.8, 0.9, 0.8, 0.5, 0.9, 0.1, 0.5, 0.6, 0.2, 0.9, 0.6, 0.3, 0.6, 0.9, 0.8, 0.7, -0.7, 0.3, -0.7, 0.8, -0.6, 0.3, 0.0, 0.4, 0.2, 0.2, 0.5, 0.4, 0.1, 0.5, 0.5, 0.9, 0.6, 0.6, 0.8, 0.7, 0.4, 0.8, 0.1, 0.7, 0.8, 0.7, 0.3, 0.4, 0.7, 0.6, 0.1, 0.7, 0.5, 0.1, -0.3, 0.6, -0.2, 0.3, -0.2, 0.4, -0.2, 0.4, 0.0, 0.2, 0.9, 0.6, 0.2, 0.8, 0.1, 0.2, 0.8, 0.4, 0.2, 0.6, 0.8, 0.1, 0.6, 0.3, 0.6, 0.9, 0.3, 0.6, 0.2, 0.9, 0.9, 0.6, 0.3, 0.9, -0.5, 0.5, -0.3, 0.9, -0.8, 0.2, -0.5, 0.2, -0.9, 0.5, 0.0, 0.4, 0.1, 0.6, 0.8, 0.1, 0.2, 0.4, 0.6, 0.2, 0.7, 0.7, 0.7, 0.9, 0.9, 0.6, 0.7, 0.2, 0.5, 0.4, 0.5, 0.4, 0.1, 0.5, -0.3, 0.8, -0.8, 0.5, -0.4, 0.4, -0.1, 0.6, -0.2, 0.4, -0.1, 0.9, 0.0, 0.8, 0.1, 0.8, 0.1, 0.5, 0.2, 0.6, 0.9, 0.9, 0.4, 0.9, 0.4, 0.9, 0.4, 0.4, 0.9, 0.1, 0.1, 0.1, 0.2, 0.3, -0.9, 0.1, -0.2, 0.6, -0.7, 0.5, -0.5, 0.8, -0.1, 0.6, -0.8, 0.8, -0.1, 0.5, 0.0, 0.4, 0.9, 0.9, 0.4, 0.7, 0.1, 0.5, 0.3, 0.9, 0.9, 0.7, 0.5, 0.6, 0.1, 0.5, 0.1, 0.5, 0.3, 0.1, -0.7, 0.8, -0.2, 0.5, -0.6, 0.9, -0.6, 0.2, -0.8, 0.1, -0.2, 0.8, -0.1, 0.4, -0.9, 0.9, 0.0, 0.4, 0.5, 0.3, 0.8, 0.1, 0.9, 0.5, 0.8, 0.1, 0.7, 0.6, 0.3, 0.2, 0.8, 0.8, 0.1, 0.9, -0.8, 0.4, -0.9, 0.2, -0.8, 0.6, -0.8, 0.4, -0.2, 0.4, -0.6, 0.5, -0.2, 0.9, -0.4, 0.4, -0.5, 0.9, 0.0, 0.3, 0.9, 0.7, 0.2, 0.2, 0.2, 0.1, 0.9, 0.3, 0.9, 0.7, 0.5, 0.8, 0.8, 0.4, -0.8, 0.9, -0.5, 0.9, -0.8, 0.7, -0.4, 0.6, -0.8, 0.2, -0.7, 0.6, -0.9, 0.7, -0.1, 0.3, -0.8, 0.3, -0.9, 0.3, 0.0, 0.7, 0.2, 0.5, 0.2, 0.8, 0.9, 0.2, 0.6, 0.8, 0.6, 0.8, 0.8, 0.6, -0.1, 0.1, -0.4, 0.5, -0.9, 0.8, -0.1, 0.1, -0.6, 0.7, -0.7, 0.9, -0.4, 0.5, -0.3, 0.1, -0.9, 0.7, -0.2, 0.7, -0.2, 0.8, 0.0, 0.9, 0.4, 0.2, 0.9, 0.7, 0.8, 0.4, 0.9, 0.9, 0.1, 0.3, -0.8, 0.5, -0.3, 0.1, -0.5, 0.7, -0.8, 0.3, -0.6, 0.9, -0.9, 0.9, -0.4, 0.9, -0.9, 0.5, -0.8, 0.2, -0.2, 0.5, -0.2, 0.9, -0.4, 0.8, 0.0, 0.8, 0.3, 0.6, 0.8, 0.4, 0.5, 0.6, 0.1, 0.7, -0.9, 0.1, -0.3, 0.6, -0.2, 0.7, -0.3, 0.9, -0.3, 0.6, -0.7, 0.9, -0.4, 0.7, -0.5, 0.1, -0.7, 0.1, -0.9, 0.8, -0.9, 0.2, -0.9, 0.8, -0.3, 0.1, 0.0, 0.1, 0.7, 0.1, 0.1, 0.8, 0.2, 0.8, -0.6, 0.8, -0.3, 0.9, -0.6, 0.4, -0.7, 0.6, -0.2, 0.2, -0.5, 0.4, -0.9, 0.6, -0.1, 0.6, -0.3, 0.3, -0.9, 0.2, -0.6, 0.7, -0.8, 0.6, -0.8, 0.1, -0.7, 0.8, 0.0, 0.9, 0.6, 0.1, 0.4, 0.1, -0.1, 0.2, -0.1, 0.3, -0.6, 0.6, -0.1, 0.9, -0.9, 0.4, -0.5, 0.1, -0.1, 0.5, -0.1, 0.2, -0.8, 0.7, -0.5, 0.8, -0.6, 0.4, -0.9, 0.4, -0.5, 0.1, -0.1, 0.9, -0.6, 0.5, 0.0, 0.4, 0.7, 0.8, -0.1, 0.1, -0.2, 0.9, -0.8, 0.7, -0.5, 0.6, -0.3, 0.4, -0.1, 0.1, -0.2, 0.5, -0.3, 0.8, -0.1, 0.8, -0.8, 0.8, -0.8, 0.9, -0.1, 0.6, -0.1, 0.8, -0.2, 0.1, -0.4, 0.4, -0.7, 0.1, 0.0, 
+
+L2_zHEMV_A_nn_pu
+0.3, 0.0, 0.6, 0.2, 0.8, 0.4, 0.7, 0.7, 0.1, 0.3, 0.9, 0.5, 0.5, 0.3, 0.3, 0.9, 0.1, 0.7, 0.9, 0.8, 0.4, 0.8, 0.6, 0.1, 0.3, 0.8, 0.7, 0.9, 0.8, 0.6, 0.1, 0.1, 0.8, 0.1, 0.7, 0.0, 0.9, 0.1, 0.3, 0.7, 0.6, 0.2, 0.5, 0.3, 0.8, 0.8, 0.1, 0.2, 0.8, 0.2, 0.4, 0.9, 0.9, 0.5, 0.1, 0.4, 0.5, 0.3, 0.1, 0.3, 0.8, 0.3, 0.2, 0.1, 0.1, 0.2, 0.9, 0.0, 0.8, 0.6, 0.3, 0.2, 0.9, 0.8, 0.5, 0.4, 0.6, 0.7, 0.5, 0.6, 0.2, 0.8, 0.9, 0.8, 0.5, 0.9, 0.1, 0.5, 0.6, 0.2, 0.9, 0.6, 0.3, 0.6, 0.9, 0.8, 0.3, 0.0, 0.4, 0.2, 0.2, 0.5, 0.4, 0.1, 0.5, 0.5, 0.9, 0.6, 0.6, 0.8, 0.7, 0.4, 0.8, 0.1, 0.7, 0.8, 0.7, 0.3, 0.4, 0.7, 0.6, 0.1, 0.7, 0.5, 0.4, 0.0, 0.2, 0.9, 0.6, 0.2, 0.8, 0.1, 0.2, 0.8, 0.4, 0.2, 0.6, 0.8, 0.1, 0.6, 0.3, 0.6, 0.9, 0.3, 0.6, 0.2, 0.9, 0.9, 0.6, 0.3, 0.5, 0.0, 0.4, 0.1, 0.6, 0.8, 0.1, 0.2, 0.4, 0.6, 0.2, 0.7, 0.7, 0.7, 0.9, 0.9, 0.6, 0.7, 0.2, 0.5, 0.4, 0.5, 0.4, 0.1, 0.9, 0.0, 0.8, 0.1, 0.8, 0.1, 0.5, 0.2, 0.6, 0.9, 0.9, 0.4, 0.9, 0.4, 0.9, 0.4, 0.4, 0.9, 0.1, 0.1, 0.1, 0.2, 0.5, 0.0, 0.4, 0.9, 0.9, 0.4, 0.7, 0.1, 0.5, 0.3, 0.9, 0.9, 0.7, 0.5, 0.6, 0.1, 0.5, 0.1, 0.5, 0.3, 0.9, 0.0, 0.4, 0.5, 0.3, 0.8, 0.1, 0.9, 0.5, 0.8, 0.1, 0.7, 0.6, 0.3, 0.2, 0.8, 0.8, 0.1, 0.9, 0.0, 0.3, 0.9, 0.7, 0.2, 0.2, 0.2, 0.1, 0.9, 0.3, 0.9, 0.7, 0.5, 0.8, 0.8, 0.3, 0.0, 0.7, 0.2, 0.5, 0.2, 0.8, 0.9, 0.2, 0.6, 0.8, 0.6, 0.8, 0.8, 0.8, 0.0, 0.9, 0.4, 0.2, 0.9, 0.7, 0.8, 0.4, 0.9, 0.9, 0.1, 0.8, 0.0, 0.8, 0.3, 0.6, 0.8, 0.4, 0.5, 0.6, 0.1, 0.1, 0.0, 0.1, 0.7, 0.1, 0.1, 0.8, 0.2, 0.8, 0.0, 0.9, 0.6, 0.1, 0.4, 0.5, 0.0, 0.4, 0.7, 0.1, 0.0, 
+
+L2_zHEMV_x_n1
+0.3, 0.3, 0.8, 0.2, 0.2, 0.6, 0.6, 0.1, 0.4, 0.2, 0.1, 0.1, 0.7, 0.2, 0.5, 0.5, 0.2, 0.8, 0.3, 0.9, 0.2, 0.8, 0.8, 0.5, 0.2, 0.4, 0.6, 0.9, 0.1, 0.2, 0.2, 0.9, 0.5, 0.8, 
+
+L2_zHEMV_x_n2
+0.3, 0.3, 0.0, 0.0, 0.8, 0.2, 0.0, 0.0, 0.2, 0.6, 0.0, 0.0, 0.6, 0.1, 0.0, 0.0, 0.4, 0.2, 0.0, 0.0, 0.1, 0.1, 0.0, 0.0, 0.7, 0.2, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.2, 0.8, 0.0, 0.0, 0.3, 0.9, 0.0, 0.0, 0.2, 0.8, 0.0, 0.0, 0.8, 0.5, 0.0, 0.0, 0.2, 0.4, 0.0, 0.0, 0.6, 0.9, 0.0, 0.0, 0.1, 0.2, 0.0, 0.0, 0.2, 0.9, 0.0, 0.0, 0.5, 0.8, 0.0, 0.0, 
+
+L2_zHEMV_y_n1
+0.5, 0.1, 0.5, 0.4, 0.7, 0.7, 0.6, 0.1, 0.7, 0.4, 0.2, 0.2, 0.1, 0.4, 0.6, 0.5, 0.2, 0.7, 0.9, 0.4, 0.8, 0.6, 0.4, 0.5, 0.5, 0.4, 0.6, 0.9, 0.6, 0.9, 0.9, 0.2, 0.6, 0.1, 
+
+L2_zHEMV_y_n2
+0.5, 0.1, 0.0, 0.0, 0.0, 0.0, 0.5, 0.4, 0.0, 0.0, 0.0, 0.0, 0.7, 0.7, 0.0, 0.0, 0.0, 0.0, 0.6, 0.1, 0.0, 0.0, 0.0, 0.0, 0.7, 0.4, 0.0, 0.0, 0.0, 0.0, 0.2, 0.2, 0.0, 0.0, 0.0, 0.0, 0.1, 0.4, 0.0, 0.0, 0.0, 0.0, 0.6, 0.5, 0.0, 0.0, 0.0, 0.0, 0.2, 0.7, 0.0, 0.0, 0.0, 0.0, 0.9, 0.4, 0.0, 0.0, 0.0, 0.0, 0.8, 0.6, 0.0, 0.0, 0.0, 0.0, 0.4, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.4, 0.0, 0.0, 0.0, 0.0, 0.6, 0.9, 0.0, 0.0, 0.0, 0.0, 0.6, 0.9, 0.0, 0.0, 0.0, 0.0, 0.9, 0.2, 0.0, 0.0, 0.0, 0.0, 0.6, 0.1, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zHEMV_o_N
+-0.25, 7.31, 0.7, 6.42, 0.46, 8.58, 1.87, 6.38, 0.74, 6.16, 0.73, 5.15, 2.89, 5.43, 2.71, 5.71, 1.43, 4.43, 3.27, 4.15, 5.68, 4.32, 4.26, 4.35, 6.42, 2.64, 7.06, 1.77, 7.05, 1.92, 6.08, 1.99, 7.42, 3.38, 
+
+L2_zHEMV_o_N2
+-0.25, 7.31, 0.0, 0.0, 0.0, 0.0, 0.7, 6.42, 0.0, 0.0, 0.0, 0.0, 0.46, 8.58, 0.0, 0.0, 0.0, 0.0, 1.87, 6.38, 0.0, 0.0, 0.0, 0.0, 0.74, 6.16, 0.0, 0.0, 0.0, 0.0, 0.73, 5.15, 0.0, 0.0, 0.0, 0.0, 2.89, 5.43, 0.0, 0.0, 0.0, 0.0, 2.71, 5.71, 0.0, 0.0, 0.0, 0.0, 1.43, 4.43, 0.0, 0.0, 0.0, 0.0, 3.27, 4.15, 0.0, 0.0, 0.0, 0.0, 5.68, 4.32, 0.0, 0.0, 0.0, 0.0, 4.26, 4.35, 0.0, 0.0, 0.0, 0.0, 6.42, 2.64, 0.0, 0.0, 0.0, 0.0, 7.06, 1.77, 0.0, 0.0, 0.0, 0.0, 7.05, 1.92, 0.0, 0.0, 0.0, 0.0, 6.08, 1.99, 0.0, 0.0, 0.0, 0.0, 7.42, 3.38, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cHBMV_A_nn
+0.5, 0.0, 0.800000011921, 0.300000011921, 0.40000000596, 0.5, 0.699999988079, 0.0, 0.699999988079, 0.699999988079, 0.699999988079, 0.899999976158, 0.5, 0.0, 0.699999988079, 0.5, 0.800000011921, 0.40000000596, 0.800000011921, 0.0, 0.899999976158, 0.20000000298, 0.699999988079, 0.600000023842, 0.5, 0.0, 0.800000011921, 0.899999976158, 0.300000011921, 0.10000000149, 0.10000000149, 0.0, 0.300000011921, 0.899999976158, 0.899999976158, 0.300000011921, 0.10000000149, 0.0, 0.300000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.5, 0.0, 0.10000000149, 0.899999976158, 0.40000000596, 0.899999976158, 0.300000011921, 0.0, 0.40000000596, 0.699999988079, 0.300000011921, 0.5, 0.800000011921, 0.0, 0.800000011921, 0.800000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.0, 0.40000000596, 0.40000000596, 0.40000000596, 0.699999988079, 0.800000011921, 0.0, 0.699999988079, 0.600000023842, 0.10000000149, 0.600000023842, 0.300000011921, 0.0, 0.5, 0.699999988079, 0.40000000596, 0.300000011921, 0.40000000596, 0.0, 0.5, 0.699999988079, 0.300000011921, 0.10000000149, 0.20000000298, 0.0, 0.10000000149, 0.899999976158, 0.899999976158, 0.20000000298, 0.600000023842, 0.0, 0.10000000149, 0.899999976158, 0.0, 0.0, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cHBMV_x_n1
+0.5, 0.300000011921, 0.800000011921, 0.300000011921, 0.20000000298, 0.600000023842, 0.899999976158, 0.699999988079, 0.300000011921, 0.699999988079, 0.699999988079, 0.5, 0.600000023842, 0.699999988079, 0.600000023842, 0.699999988079, 0.40000000596, 0.800000011921, 0.5, 0.300000011921, 0.40000000596, 0.600000023842, 0.899999976158, 0.10000000149, 0.5, 0.699999988079, 0.40000000596, 0.5, 0.10000000149, 0.600000023842, 0.800000011921, 0.40000000596, 0.699999988079, 0.20000000298, 
+
+L2_cHBMV_x_n2
+0.5, 0.300000011921, 0.0, 0.0, 0.800000011921, 0.300000011921, 0.0, 0.0, 0.20000000298, 0.600000023842, 0.0, 0.0, 0.899999976158, 0.699999988079, 0.0, 0.0, 0.300000011921, 0.699999988079, 0.0, 0.0, 0.699999988079, 0.5, 0.0, 0.0, 0.600000023842, 0.699999988079, 0.0, 0.0, 0.600000023842, 0.699999988079, 0.0, 0.0, 0.40000000596, 0.800000011921, 0.0, 0.0, 0.5, 0.300000011921, 0.0, 0.0, 0.40000000596, 0.600000023842, 0.0, 0.0, 0.899999976158, 0.10000000149, 0.0, 0.0, 0.5, 0.699999988079, 0.0, 0.0, 0.40000000596, 0.5, 0.0, 0.0, 0.10000000149, 0.600000023842, 0.0, 0.0, 0.800000011921, 0.40000000596, 0.0, 0.0, 0.699999988079, 0.20000000298, 0.0, 0.0, 
+
+L2_cHBMV_y_n1
+0.10000000149, 0.899999976158, 0.40000000596, 0.20000000298, 0.699999988079, 0.899999976158, 0.10000000149, 0.800000011921, 0.600000023842, 0.10000000149, 0.20000000298, 0.800000011921, 0.699999988079, 0.800000011921, 0.40000000596, 0.10000000149, 0.699999988079, 0.699999988079, 0.300000011921, 0.300000011921, 0.800000011921, 0.699999988079, 0.600000023842, 0.300000011921, 0.800000011921, 0.699999988079, 0.600000023842, 0.600000023842, 0.600000023842, 0.300000011921, 0.699999988079, 0.40000000596, 0.40000000596, 0.40000000596, 
+
+L2_cHBMV_y_n2
+0.10000000149, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cHBMV_o_N
+0.680000003874, 1.87000002295, 1.17000000805, 2.35999996454, 2.15999999434, 2.33999997735, 2.40999998242, 2.63000001132, 2.32000002965, 2.59999998063, 2.07000001475, 2.64999998286, 1.57000000209, 1.00000006109, 0.980000019521, 1.84999997318, 1.51999996632, 1.27000000507, 2.89999994636, 1.57000005797, 2.31000006735, 2.09000002205, 1.96000000179, 1.61000003234, 1.93000000387, 1.20000001341, 1.48000001729, 0.84000004068, 1.89000000715, 1.60000000298, 1.79000003099, 1.37000000134, 1.47000001922, 0.36000002861, 
+
+L2_cHBMV_o_N2
+0.680000003874, 1.87000002295, 0.0, 0.0, 0.0, 0.0, 1.17000000805, 2.35999996454, 0.0, 0.0, 0.0, 0.0, 2.15999999434, 2.33999997735, 0.0, 0.0, 0.0, 0.0, 2.40999998242, 2.63000001132, 0.0, 0.0, 0.0, 0.0, 2.32000002965, 2.59999998063, 0.0, 0.0, 0.0, 0.0, 2.07000001475, 2.64999998286, 0.0, 0.0, 0.0, 0.0, 1.57000000209, 1.00000006109, 0.0, 0.0, 0.0, 0.0, 0.980000019521, 1.84999997318, 0.0, 0.0, 0.0, 0.0, 1.51999996632, 1.27000000507, 0.0, 0.0, 0.0, 0.0, 2.89999994636, 1.57000005797, 0.0, 0.0, 0.0, 0.0, 2.31000006735, 2.09000002205, 0.0, 0.0, 0.0, 0.0, 1.96000000179, 1.61000003234, 0.0, 0.0, 0.0, 0.0, 1.93000000387, 1.20000001341, 0.0, 0.0, 0.0, 0.0, 1.48000001729, 0.84000004068, 0.0, 0.0, 0.0, 0.0, 1.89000000715, 1.60000000298, 0.0, 0.0, 0.0, 0.0, 1.79000003099, 1.37000000134, 0.0, 0.0, 0.0, 0.0, 1.47000001922, 0.36000002861, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zHBMV_A_nn
+0.3, 0.0, 0.6, 0.6, 0.5, 0.6, 0.4, 0.0, 0.3, 0.2, 0.7, 0.7, 0.1, 0.0, 0.9, 0.8, 0.8, 0.2, 0.7, 0.0, 0.8, 0.4, 0.3, 0.5, 0.6, 0.0, 0.8, 0.6, 0.3, 0.1, 0.4, 0.0, 0.3, 0.6, 0.3, 0.8, 0.2, 0.0, 0.4, 0.4, 0.8, 0.1, 0.5, 0.0, 0.3, 0.4, 0.8, 0.6, 0.8, 0.0, 0.8, 0.3, 0.2, 0.6, 0.7, 0.0, 0.5, 0.1, 0.9, 0.5, 0.5, 0.0, 0.5, 0.7, 0.5, 0.9, 0.2, 0.0, 0.9, 0.2, 0.8, 0.6, 0.4, 0.0, 0.2, 0.2, 0.1, 0.4, 0.4, 0.0, 0.9, 0.8, 0.7, 0.1, 0.7, 0.0, 0.4, 0.3, 0.7, 0.2, 0.9, 0.0, 0.1, 0.8, 0.0, 0.0, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zHBMV_x_n1
+0.4, 0.2, 0.2, 0.8, 0.6, 0.4, 0.7, 0.8, 0.5, 0.8, 0.4, 0.3, 0.8, 0.2, 0.5, 0.3, 0.2, 0.6, 0.6, 0.5, 0.3, 0.6, 0.8, 0.1, 0.6, 0.8, 0.2, 0.9, 0.2, 0.5, 0.3, 0.3, 0.2, 0.7, 
+
+L2_zHBMV_x_n2
+0.4, 0.2, 0.0, 0.0, 0.2, 0.8, 0.0, 0.0, 0.6, 0.4, 0.0, 0.0, 0.7, 0.8, 0.0, 0.0, 0.5, 0.8, 0.0, 0.0, 0.4, 0.3, 0.0, 0.0, 0.8, 0.2, 0.0, 0.0, 0.5, 0.3, 0.0, 0.0, 0.2, 0.6, 0.0, 0.0, 0.6, 0.5, 0.0, 0.0, 0.3, 0.6, 0.0, 0.0, 0.8, 0.1, 0.0, 0.0, 0.6, 0.8, 0.0, 0.0, 0.2, 0.9, 0.0, 0.0, 0.2, 0.5, 0.0, 0.0, 0.3, 0.3, 0.0, 0.0, 0.2, 0.7, 0.0, 0.0, 
+
+L2_zHBMV_y_n1
+0.2, 0.5, 0.2, 0.4, 0.2, 0.6, 0.7, 0.4, 0.5, 0.9, 0.4, 0.3, 0.6, 0.2, 0.5, 0.3, 0.6, 0.9, 0.9, 0.1, 0.3, 0.3, 0.9, 0.4, 0.5, 0.1, 0.9, 0.5, 0.6, 0.3, 0.5, 0.8, 0.5, 0.2, 
+
+L2_zHBMV_y_n2
+0.2, 0.5, 0.0, 0.0, 0.0, 0.0, 0.2, 0.4, 0.0, 0.0, 0.0, 0.0, 0.2, 0.6, 0.0, 0.0, 0.0, 0.0, 0.7, 0.4, 0.0, 0.0, 0.0, 0.0, 0.5, 0.9, 0.0, 0.0, 0.0, 0.0, 0.4, 0.3, 0.0, 0.0, 0.0, 0.0, 0.6, 0.2, 0.0, 0.0, 0.0, 0.0, 0.5, 0.3, 0.0, 0.0, 0.0, 0.0, 0.6, 0.9, 0.0, 0.0, 0.0, 0.0, 0.9, 0.1, 0.0, 0.0, 0.0, 0.0, 0.3, 0.3, 0.0, 0.0, 0.0, 0.0, 0.9, 0.4, 0.0, 0.0, 0.0, 0.0, 0.5, 0.1, 0.0, 0.0, 0.0, 0.0, 0.9, 0.5, 0.0, 0.0, 0.0, 0.0, 0.6, 0.3, 0.0, 0.0, 0.0, 0.0, 0.5, 0.8, 0.0, 0.0, 0.0, 0.0, 0.5, 0.2, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zHBMV_o_N
+0.02, 1.72, 0.67, 1.89, 1.03, 2.72, 2.8, 2.39, 2.6, 2.56, 2.08, 1.68, 1.47, 1.1, 1.51, 1.0, 1.72, 2.23, 3.0, 1.63, 1.11, 2.34, 2.42, 2.34, 1.85, 0.73, 1.92, 1.35, 2.05, 1.88, 0.69, 2.05, 1.07, 0.51, 
+
+L2_zHBMV_o_N2
+0.02, 1.72, 0.0, 0.0, 0.0, 0.0, 0.67, 1.89, 0.0, 0.0, 0.0, 0.0, 1.03, 2.72, 0.0, 0.0, 0.0, 0.0, 2.8, 2.39, 0.0, 0.0, 0.0, 0.0, 2.6, 2.56, 0.0, 0.0, 0.0, 0.0, 2.08, 1.68, 0.0, 0.0, 0.0, 0.0, 1.47, 1.1, 0.0, 0.0, 0.0, 0.0, 1.51, 1.0, 0.0, 0.0, 0.0, 0.0, 1.72, 2.23, 0.0, 0.0, 0.0, 0.0, 3.0, 1.63, 0.0, 0.0, 0.0, 0.0, 1.11, 2.34, 0.0, 0.0, 0.0, 0.0, 2.42, 2.34, 0.0, 0.0, 0.0, 0.0, 1.85, 0.73, 0.0, 0.0, 0.0, 0.0, 1.92, 1.35, 0.0, 0.0, 0.0, 0.0, 2.05, 1.88, 0.0, 0.0, 0.0, 0.0, 0.69, 2.05, 0.0, 0.0, 0.0, 0.0, 1.07, 0.51, 0.0, 0.0, 0.0, 0.0, 
+
+L2_sSYMV_A_nn
+0.3, 0.7, 0.4, 0.5, 0.5, 0.5, 0.9, 0.7, 0.6, 0.5, 0.6, 0.4, 0.3, 0.2, 0.2, 0.3, 0.3, 0.7, 0.9, 0.5, 0.4, 0.6, 0.1, 0.8, 0.6, 0.1, 0.7, 0.5, 0.6, 0.3, 0.9, 0.9, 0.2, 0.5, 0.4, 0.5, 0.4, 0.3, 0.2, 0.3, 0.9, 0.9, 0.4, 0.4, 0.2, 0.4, 0.5, 0.1, 0.2, 0.2, 0.4, 0.5, 0.4, 0.3, 0.7, 0.5, 0.4, 0.2, 0.6, 0.7, 0.6, 0.8, 0.2, 0.3, 0.5, 0.8, 0.3, 0.1, 0.5, 0.6, 0.2, 0.5, 0.4, 0.9, 0.2, 0.8, 0.2, 0.2, 0.2, 0.7, 0.8, 0.5, 0.6, 0.5, 0.4, 0.5, 0.1, 0.3, 0.4, 0.9, 0.7, 0.9, 0.3, 0.2, 0.1, 0.4, 0.9, 0.3, 0.3, 0.4, 0.9, 0.9, 0.9, 0.8, 0.9, 0.2, 0.2, 0.9, 0.8, 0.1, 0.9, 0.8, 0.5, 0.1, 0.4, 0.4, 0.5, 0.3, 0.3, 0.7, 0.6, 0.9, 0.6, 0.8, 0.3, 0.1, 0.3, 0.7, 0.4, 0.2, 0.7, 0.4, 0.4, 0.9, 0.4, 0.5, 0.6, 0.1, 0.4, 0.7, 0.2, 0.2, 0.9, 0.7, 0.8, 0.4, 0.7, 0.2, 0.4, 0.5, 0.4, 0.9, 0.6, 0.5, 0.7, 0.4, 0.6, 0.2, 0.1, 0.8, 0.4, 0.4, 0.2, 0.4, 0.1, 0.6, 0.4, 0.2, 0.4, 0.2, 0.6, 0.5, 0.2, 0.8, 0.2, 0.4, 0.5, 0.2, 0.7, 0.4, 0.7, 0.7, 0.1, 0.8, 0.6, 0.8, 0.9, 0.4, 0.6, 0.4, 0.2, 0.7, 0.9, 0.1, 0.7, 0.2, 0.1, 0.7, 0.1, 0.8, 0.3, 0.6, 0.4, 0.5, 0.3, 0.3, 0.5, 0.3, 0.8, 0.3, 0.4, 0.4, 0.4, 0.6, 0.1, 0.8, 0.8, 0.8, 0.2, 0.8, 0.5, 0.2, 0.9, 0.1, 0.5, 0.5, 0.3, 0.4, 0.4, 0.5, 0.4, 0.8, 0.3, 0.8, 0.5, 0.3, 0.2, 0.1, 0.2, 0.9, 0.2, 0.8, 0.6, 0.4, 0.5, 0.9, 0.4, 0.2, 0.6, 0.6, 0.2, 0.3, 0.8, 0.1, 0.1, 0.3, 0.2, 0.2, 0.3, 0.5, 0.9, 0.3, 0.4, 0.9, 0.4, 0.8, 0.4, 0.8, 0.2, 0.1, 0.4, 0.5, 0.3, 0.5, 0.4, 0.1, 0.4, 0.9, 0.3, 0.5, 0.6, 0.2, 0.9, 0.5, 0.5, 0.1, 0.1, 0.5, 0.9, 
+
+L2_sSYMV_A_nn_pu
+0.3, 0.7, 0.4, 0.5, 0.5, 0.5, 0.9, 0.7, 0.6, 0.5, 0.6, 0.4, 0.3, 0.2, 0.2, 0.3, 0.3, 0.9, 0.5, 0.4, 0.6, 0.1, 0.8, 0.6, 0.1, 0.7, 0.5, 0.6, 0.3, 0.9, 0.9, 0.2, 0.5, 0.4, 0.3, 0.2, 0.3, 0.9, 0.9, 0.4, 0.4, 0.2, 0.4, 0.5, 0.1, 0.2, 0.2, 0.4, 0.7, 0.5, 0.4, 0.2, 0.6, 0.7, 0.6, 0.8, 0.2, 0.3, 0.5, 0.8, 0.3, 0.1, 0.4, 0.9, 0.2, 0.8, 0.2, 0.2, 0.2, 0.7, 0.8, 0.5, 0.6, 0.5, 0.4, 0.7, 0.9, 0.3, 0.2, 0.1, 0.4, 0.9, 0.3, 0.3, 0.4, 0.9, 0.9, 0.8, 0.1, 0.9, 0.8, 0.5, 0.1, 0.4, 0.4, 0.5, 0.3, 0.3, 0.3, 0.7, 0.4, 0.2, 0.7, 0.4, 0.4, 0.9, 0.4, 0.5, 0.8, 0.4, 0.7, 0.2, 0.4, 0.5, 0.4, 0.9, 0.6, 0.2, 0.4, 0.1, 0.6, 0.4, 0.2, 0.4, 0.2, 0.7, 0.7, 0.1, 0.8, 0.6, 0.8, 0.9, 0.1, 0.8, 0.3, 0.6, 0.4, 0.5, 0.8, 0.8, 0.2, 0.8, 0.5, 0.5, 0.3, 0.2, 0.1, 0.8, 0.1, 0.1, 0.4, 0.5, 0.9, 
+
+L2_sSYMV_x_n1
+0.7, 0.3, 0.5, 0.3, 0.6, 0.4, 0.6, 0.2, 0.5, 0.9, 0.5, 0.4, 0.9, 0.6, 0.1, 0.4, 0.1, 
+
+L2_sSYMV_x_n2
+0.7, 0.0, 0.3, 0.0, 0.5, 0.0, 0.3, 0.0, 0.6, 0.0, 0.4, 0.0, 0.6, 0.0, 0.2, 0.0, 0.5, 0.0, 0.9, 0.0, 0.5, 0.0, 0.4, 0.0, 0.9, 0.0, 0.6, 0.0, 0.1, 0.0, 0.4, 0.0, 0.1, 0.0, 
+
+L2_sSYMV_y_n1
+0.6, 0.1, 0.2, 0.7, 0.9, 0.8, 0.6, 0.9, 0.2, 0.6, 0.3, 0.7, 0.5, 0.8, 0.9, 0.3, 0.2, 
+
+L2_sSYMV_y_n2
+0.6, 0.0, 0.0, 0.1, 0.0, 0.0, 0.2, 0.0, 0.0, 0.7, 0.0, 0.0, 0.9, 0.0, 0.0, 0.8, 0.0, 0.0, 0.6, 0.0, 0.0, 0.9, 0.0, 0.0, 0.2, 0.0, 0.0, 0.6, 0.0, 0.0, 0.3, 0.0, 0.0, 0.7, 0.0, 0.0, 0.5, 0.0, 0.0, 0.8, 0.0, 0.0, 0.9, 0.0, 0.0, 0.3, 0.0, 0.0, 0.2, 0.0, 0.0, 
+
+L2_sSYMV_o_N
+4.32000009969, 4.43000005677, 3.35000003725, 4.38000006348, 4.54000002354, 4.56000005022, 5.22000002891, 4.91000001967, 4.25000004396, 3.86000010759, 4.21000008672, 4.15000002682, 4.76000011653, 4.42000007212, 4.06000007927, 4.11000005171, 3.61000003755, 
+
+L2_sSYMV_o_N2
+4.32000009969, 0.0, 0.0, 4.43000005677, 0.0, 0.0, 3.35000003725, 0.0, 0.0, 4.38000006348, 0.0, 0.0, 4.54000002354, 0.0, 0.0, 4.56000005022, 0.0, 0.0, 5.22000002891, 0.0, 0.0, 4.91000001967, 0.0, 0.0, 4.25000004396, 0.0, 0.0, 3.86000010759, 0.0, 0.0, 4.21000008672, 0.0, 0.0, 4.15000002682, 0.0, 0.0, 4.76000011653, 0.0, 0.0, 4.42000007212, 0.0, 0.0, 4.06000007927, 0.0, 0.0, 4.11000005171, 0.0, 0.0, 3.61000003755, 0.0, 0.0, 
+
+L2_dSYMV_A_nn
+0.9, 0.4, 0.9, 0.1, 0.5, 0.2, 0.9, 0.3, 0.5, 0.8, 0.7, 0.7, 0.2, 0.5, 0.4, 0.3, 0.1, 0.4, 0.7, 0.8, 0.8, 0.7, 0.4, 0.2, 0.9, 0.1, 0.3, 0.5, 0.6, 0.8, 0.3, 0.5, 0.5, 0.2, 0.9, 0.8, 0.6, 0.6, 0.8, 0.2, 0.3, 0.6, 0.3, 0.1, 0.8, 0.4, 0.5, 0.5, 0.2, 0.3, 0.8, 0.1, 0.8, 0.6, 0.1, 0.3, 0.7, 0.7, 0.6, 0.5, 0.9, 0.8, 0.8, 0.2, 0.8, 0.6, 0.4, 0.9, 0.5, 0.7, 0.8, 0.3, 0.4, 0.3, 0.7, 0.7, 0.8, 0.6, 0.4, 0.4, 0.8, 0.3, 0.2, 0.3, 0.9, 0.2, 0.4, 0.2, 0.7, 0.3, 0.7, 0.3, 0.7, 0.4, 0.5, 0.1, 0.5, 0.9, 0.9, 0.9, 0.9, 0.3, 0.9, 0.2, 0.3, 0.7, 0.7, 0.3, 0.6, 0.3, 0.9, 0.4, 0.1, 0.4, 0.5, 0.8, 0.4, 0.9, 0.3, 0.3, 0.9, 0.6, 0.6, 0.7, 0.7, 0.3, 0.5, 0.5, 0.3, 0.4, 0.7, 0.2, 0.3, 0.2, 0.6, 0.7, 0.5, 0.1, 0.3, 0.5, 0.8, 0.4, 0.9, 0.5, 0.5, 0.8, 0.3, 0.4, 0.3, 0.6, 0.3, 0.7, 0.4, 0.8, 0.3, 0.1, 0.9, 0.6, 0.5, 0.4, 0.3, 0.8, 0.8, 0.3, 0.6, 0.4, 0.1, 0.4, 0.7, 0.1, 0.7, 0.5, 0.8, 0.8, 0.4, 0.1, 0.1, 0.4, 0.3, 0.3, 0.3, 0.7, 0.5, 0.4, 0.8, 0.7, 0.1, 0.7, 0.6, 0.4, 0.8, 0.4, 0.5, 0.4, 0.7, 0.4, 0.6, 0.7, 0.4, 0.2, 0.2, 0.2, 0.6, 0.2, 0.2, 0.8, 0.5, 0.2, 0.8, 0.9, 0.5, 0.2, 0.3, 0.4, 0.5, 0.2, 0.4, 0.2, 0.5, 0.4, 0.7, 0.5, 0.3, 0.5, 0.8, 0.3, 0.9, 0.8, 0.3, 0.6, 0.1, 0.4, 0.2, 0.2, 0.8, 0.7, 0.8, 0.9, 0.4, 0.5, 0.2, 0.6, 0.2, 0.9, 0.4, 0.2, 0.3, 0.4, 0.8, 0.2, 0.5, 0.7, 0.5, 0.7, 0.5, 0.3, 0.5, 0.3, 0.4, 0.3, 0.9, 0.9, 0.6, 0.7, 0.7, 0.7, 0.6, 0.4, 0.8, 0.7, 0.7, 0.3, 0.1, 0.2, 0.8, 0.9, 0.9, 0.3, 0.3, 0.7, 0.4, 0.1, 0.1, 0.2, 0.7, 0.9, 0.5, 0.3, 0.8, 
+
+L2_dSYMV_A_nn_pu
+0.9, 0.4, 0.9, 0.1, 0.5, 0.2, 0.9, 0.3, 0.5, 0.8, 0.7, 0.7, 0.2, 0.5, 0.4, 0.3, 0.1, 0.7, 0.8, 0.8, 0.7, 0.4, 0.2, 0.9, 0.1, 0.3, 0.5, 0.6, 0.8, 0.3, 0.5, 0.5, 0.2, 0.6, 0.6, 0.8, 0.2, 0.3, 0.6, 0.3, 0.1, 0.8, 0.4, 0.5, 0.5, 0.2, 0.3, 0.8, 0.1, 0.3, 0.7, 0.7, 0.6, 0.5, 0.9, 0.8, 0.8, 0.2, 0.8, 0.6, 0.4, 0.9, 0.4, 0.3, 0.7, 0.7, 0.8, 0.6, 0.4, 0.4, 0.8, 0.3, 0.2, 0.3, 0.9, 0.7, 0.3, 0.7, 0.4, 0.5, 0.1, 0.5, 0.9, 0.9, 0.9, 0.9, 0.3, 0.6, 0.3, 0.9, 0.4, 0.1, 0.4, 0.5, 0.8, 0.4, 0.9, 0.3, 0.5, 0.5, 0.3, 0.4, 0.7, 0.2, 0.3, 0.2, 0.6, 0.7, 0.5, 0.8, 0.3, 0.4, 0.3, 0.6, 0.3, 0.7, 0.4, 0.8, 0.3, 0.6, 0.4, 0.1, 0.4, 0.7, 0.1, 0.3, 0.7, 0.5, 0.4, 0.8, 0.7, 0.1, 0.4, 0.2, 0.2, 0.2, 0.6, 0.2, 0.4, 0.2, 0.5, 0.4, 0.7, 0.8, 0.7, 0.8, 0.9, 0.5, 0.7, 0.5, 0.7, 0.3, 0.8, 
+
+L2_dSYMV_x_n1
+0.1, 0.4, 0.9, 0.2, 0.8, 0.7, 0.7, 0.8, 0.2, 0.4, 0.1, 0.6, 0.6, 0.6, 0.7, 0.2, 0.3, 
+
+L2_dSYMV_x_n2
+0.1, 0.0, 0.4, 0.0, 0.9, 0.0, 0.2, 0.0, 0.8, 0.0, 0.7, 0.0, 0.7, 0.0, 0.8, 0.0, 0.2, 0.0, 0.4, 0.0, 0.1, 0.0, 0.6, 0.0, 0.6, 0.0, 0.6, 0.0, 0.7, 0.0, 0.2, 0.0, 0.3, 0.0, 
+
+L2_dSYMV_y_n1
+0.7, 0.2, 0.2, 0.7, 0.9, 0.5, 0.5, 0.7, 0.3, 0.9, 0.2, 0.7, 0.3, 0.4, 0.5, 0.9, 0.8, 
+
+L2_dSYMV_y_n2
+0.7, 0.0, 0.0, 0.2, 0.0, 0.0, 0.2, 0.0, 0.0, 0.7, 0.0, 0.0, 0.9, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.7, 0.0, 0.0, 0.3, 0.0, 0.0, 0.9, 0.0, 0.0, 0.2, 0.0, 0.0, 0.7, 0.0, 0.0, 0.3, 0.0, 0.0, 0.4, 0.0, 0.0, 0.5, 0.0, 0.0, 0.9, 0.0, 0.0, 0.8, 0.0, 0.0, 
+
+L2_dSYMV_o_N
+4.89, 4.82, 4.2, 5.68, 5.4, 5.07, 4.43, 4.86, 4.41, 4.34, 4.03, 4.23, 4.3, 4.69, 4.05, 5.75, 5.35, 
+
+L2_dSYMV_o_N2
+4.89, 0.0, 0.0, 4.82, 0.0, 0.0, 4.2, 0.0, 0.0, 5.68, 0.0, 0.0, 5.4, 0.0, 0.0, 5.07, 0.0, 0.0, 4.43, 0.0, 0.0, 4.86, 0.0, 0.0, 4.41, 0.0, 0.0, 4.34, 0.0, 0.0, 4.03, 0.0, 0.0, 4.23, 0.0, 0.0, 4.3, 0.0, 0.0, 4.69, 0.0, 0.0, 4.05, 0.0, 0.0, 5.75, 0.0, 0.0, 5.35, 0.0, 0.0, 
+
+L2_sSBMV_A_nn
+0.1, 0.4, 0.4, 0.4, 0.9, 0.4, 0.7, 0.1, 0.3, 0.6, 0.3, 0.1, 0.9, 0.2, 0.1, 0.2, 0.9, 0.3, 0.7, 0.6, 0.2, 0.7, 0.1, 0.2, 0.3, 0.8, 0.5, 0.1, 0.5, 0.9, 0.7, 0.8, 0.7, 0.3, 0.5, 0.2, 0.2, 0.8, 0.8, 0.7, 0.4, 0.2, 0.1, 0.4, 0.2, 0.9, 0.2, 0.0, 0.9, 0.0, 0.0, 
+
+L2_sSBMV_x_n1
+0.2, 0.1, 0.5, 0.4, 0.3, 0.8, 0.5, 0.5, 0.1, 0.3, 0.4, 0.8, 0.3, 0.6, 0.6, 0.1, 0.7, 
+
+L2_sSBMV_x_n2
+0.2, 0.0, 0.1, 0.0, 0.5, 0.0, 0.4, 0.0, 0.3, 0.0, 0.8, 0.0, 0.5, 0.0, 0.5, 0.0, 0.1, 0.0, 0.3, 0.0, 0.4, 0.0, 0.8, 0.0, 0.3, 0.0, 0.6, 0.0, 0.6, 0.0, 0.1, 0.0, 0.7, 0.0, 
+
+L2_sSBMV_y_n1
+0.3, 0.6, 0.6, 0.8, 0.3, 0.7, 0.6, 0.4, 0.7, 0.4, 0.2, 0.6, 0.5, 0.3, 0.2, 0.3, 0.9, 
+
+L2_sSBMV_y_n2
+0.3, 0.0, 0.0, 0.6, 0.0, 0.0, 0.6, 0.0, 0.0, 0.8, 0.0, 0.0, 0.3, 0.0, 0.0, 0.7, 0.0, 0.0, 0.6, 0.0, 0.0, 0.4, 0.0, 0.0, 0.7, 0.0, 0.0, 0.4, 0.0, 0.0, 0.2, 0.0, 0.0, 0.6, 0.0, 0.0, 0.5, 0.0, 0.0, 0.3, 0.0, 0.0, 0.2, 0.0, 0.0, 0.3, 0.0, 0.0, 0.9, 0.0, 0.0, 
+
+L2_sSBMV_o_N
+0.560000016689, 1.33000002027, 1.25000002757, 1.30000003651, 1.05000003353, 1.55999999136, 2.02000002369, 1.36000002861, 1.32000000805, 1.53000000611, 1.53000003293, 1.70000006258, 2.20000006109, 1.38000005305, 0.920000033379, 0.890000030249, 1.66999995589, 
+
+L2_sSBMV_o_N2
+0.560000016689, 0.0, 0.0, 1.33000002027, 0.0, 0.0, 1.25000002757, 0.0, 0.0, 1.30000003651, 0.0, 0.0, 1.05000003353, 0.0, 0.0, 1.55999999136, 0.0, 0.0, 2.02000002369, 0.0, 0.0, 1.36000002861, 0.0, 0.0, 1.32000000805, 0.0, 0.0, 1.53000000611, 0.0, 0.0, 1.53000003293, 0.0, 0.0, 1.70000006258, 0.0, 0.0, 2.20000006109, 0.0, 0.0, 1.38000005305, 0.0, 0.0, 0.920000033379, 0.0, 0.0, 0.890000030249, 0.0, 0.0, 1.66999995589, 0.0, 0.0, 
+
+L2_dSBMV_A_nn
+0.6, 0.9, 0.1, 0.3, 0.4, 0.6, 0.6, 0.4, 0.4, 0.1, 0.1, 0.1, 0.3, 0.7, 0.2, 0.2, 0.4, 0.3, 0.7, 0.6, 0.5, 0.1, 0.8, 0.2, 0.6, 0.1, 0.6, 0.4, 0.8, 0.7, 0.2, 0.1, 0.2, 0.7, 0.4, 0.1, 0.3, 0.3, 0.9, 0.1, 0.7, 0.5, 0.8, 0.4, 0.5, 0.3, 0.8, 0.0, 0.4, 0.0, 0.0, 
+
+L2_dSBMV_x_n1
+0.8, 0.5, 0.3, 0.8, 0.2, 0.5, 0.4, 0.5, 0.3, 0.5, 0.8, 0.9, 0.1, 0.4, 0.2, 0.2, 0.6, 
+
+L2_dSBMV_x_n2
+0.8, 0.0, 0.5, 0.0, 0.3, 0.0, 0.8, 0.0, 0.2, 0.0, 0.5, 0.0, 0.4, 0.0, 0.5, 0.0, 0.3, 0.0, 0.5, 0.0, 0.8, 0.0, 0.9, 0.0, 0.1, 0.0, 0.4, 0.0, 0.2, 0.0, 0.2, 0.0, 0.6, 0.0, 
+
+L2_dSBMV_y_n1
+0.9, 0.8, 0.6, 0.8, 0.4, 0.3, 0.3, 0.1, 0.5, 0.4, 0.2, 0.1, 0.1, 0.4, 0.9, 0.6, 0.4, 
+
+L2_dSBMV_y_n2
+0.9, 0.0, 0.0, 0.8, 0.0, 0.0, 0.6, 0.0, 0.0, 0.8, 0.0, 0.0, 0.4, 0.0, 0.0, 0.3, 0.0, 0.0, 0.3, 0.0, 0.0, 0.1, 0.0, 0.0, 0.5, 0.0, 0.0, 0.4, 0.0, 0.0, 0.2, 0.0, 0.0, 0.1, 0.0, 0.0, 0.1, 0.0, 0.0, 0.4, 0.0, 0.0, 0.9, 0.0, 0.0, 0.6, 0.0, 0.0, 0.4, 0.0, 0.0, 
+
+L2_dSBMV_o_N
+1.86, 2.27, 1.46, 1.37, 1.09, 0.93, 1.27, 0.88, 1.81, 2.0, 1.05, 1.24, 0.95, 0.8, 1.81, 1.42, 0.9, 
+
+L2_dSBMV_o_N2
+1.86, 0.0, 0.0, 2.27, 0.0, 0.0, 1.46, 0.0, 0.0, 1.37, 0.0, 0.0, 1.09, 0.0, 0.0, 0.93, 0.0, 0.0, 1.27, 0.0, 0.0, 0.88, 0.0, 0.0, 1.81, 0.0, 0.0, 2.0, 0.0, 0.0, 1.05, 0.0, 0.0, 1.24, 0.0, 0.0, 0.95, 0.0, 0.0, 0.8, 0.0, 0.0, 1.81, 0.0, 0.0, 1.42, 0.0, 0.0, 0.9, 0.0, 0.0, 
+
+L2_sTRMV_A_nn
+0.7, 0.8, 0.7, 0.1, 0.3, 0.3, 0.5, 0.4, 0.6, 0.3, 0.8, 0.4, 0.7, 0.6, 0.7, 0.9, 0.2, 0.0, 0.1, 0.3, 0.7, 0.1, 0.7, 0.4, 0.2, 0.6, 0.4, 0.8, 0.4, 0.1, 0.8, 0.9, 0.1, 0.8, 0.0, 0.0, 0.4, 0.8, 0.7, 0.2, 0.8, 0.9, 0.8, 0.9, 0.7, 0.4, 0.8, 0.4, 0.5, 0.2, 0.6, 0.0, 0.0, 0.0, 0.7, 0.5, 0.2, 0.1, 0.9, 0.9, 0.6, 0.2, 0.7, 0.2, 0.2, 0.8, 0.8, 0.6, 0.0, 0.0, 0.0, 0.0, 0.3, 0.3, 0.6, 0.2, 0.4, 0.5, 0.2, 0.9, 0.4, 0.5, 0.1, 0.1, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6, 0.5, 0.2, 0.5, 0.3, 0.8, 0.5, 0.5, 0.8, 0.6, 0.8, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.6, 0.9, 0.3, 0.1, 0.6, 0.9, 0.8, 0.2, 0.1, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.3, 0.5, 0.1, 0.4, 0.8, 0.6, 0.4, 0.3, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6, 0.2, 0.7, 0.5, 0.6, 0.5, 0.1, 0.3, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.8, 0.5, 0.5, 0.6, 0.1, 0.2, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.1, 0.7, 0.2, 0.8, 0.7, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.8, 0.6, 0.9, 0.5, 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.1, 0.9, 0.1, 0.2, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.6, 0.4, 0.4, 0.0, 0.0, 0.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, 0.9, 0.6, 0.0, 0.0, 0.0, 0.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, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 
+
+L2_sTRMV_A_nn_pu
+0.7, 0.8, 0.7, 0.1, 0.3, 0.3, 0.5, 0.4, 0.6, 0.3, 0.8, 0.4, 0.7, 0.6, 0.7, 0.9, 0.2, 0.1, 0.3, 0.7, 0.1, 0.7, 0.4, 0.2, 0.6, 0.4, 0.8, 0.4, 0.1, 0.8, 0.9, 0.1, 0.8, 0.4, 0.8, 0.7, 0.2, 0.8, 0.9, 0.8, 0.9, 0.7, 0.4, 0.8, 0.4, 0.5, 0.2, 0.6, 0.7, 0.5, 0.2, 0.1, 0.9, 0.9, 0.6, 0.2, 0.7, 0.2, 0.2, 0.8, 0.8, 0.6, 0.3, 0.3, 0.6, 0.2, 0.4, 0.5, 0.2, 0.9, 0.4, 0.5, 0.1, 0.1, 0.5, 0.6, 0.5, 0.2, 0.5, 0.3, 0.8, 0.5, 0.5, 0.8, 0.6, 0.8, 0.6, 0.5, 0.6, 0.9, 0.3, 0.1, 0.6, 0.9, 0.8, 0.2, 0.1, 0.2, 0.1, 0.3, 0.5, 0.1, 0.4, 0.8, 0.6, 0.4, 0.3, 0.9, 0.6, 0.2, 0.7, 0.5, 0.6, 0.5, 0.1, 0.3, 0.9, 0.3, 0.8, 0.5, 0.5, 0.6, 0.1, 0.2, 0.3, 0.2, 0.1, 0.7, 0.2, 0.8, 0.7, 0.2, 0.2, 0.8, 0.6, 0.9, 0.5, 0.8, 0.1, 0.9, 0.1, 0.2, 0.3, 0.3, 0.6, 0.4, 0.4, 0.5, 0.9, 0.6, 0.5, 0.4, 0.7, 
+
+L2_sTRMV_x_n1
+0.2, 0.7, 0.3, 0.3, 0.6, 0.1, 0.1, 0.6, 0.5, 0.5, 0.2, 0.4, 0.3, 0.1, 0.7, 0.7, 0.3, 
+
+L2_sTRMV_x_n2
+0.2, 0.0, 0.7, 0.0, 0.3, 0.0, 0.3, 0.0, 0.6, 0.0, 0.1, 0.0, 0.1, 0.0, 0.6, 0.0, 0.5, 0.0, 0.5, 0.0, 0.2, 0.0, 0.4, 0.0, 0.3, 0.0, 0.1, 0.0, 0.7, 0.0, 0.7, 0.0, 0.3, 0.0, 
+
+L2_sTRMV_o_UN
+3.66, 2.53, 3.52, 3.53, 1.7, 2.38, 1.89, 1.7, 1.52, 1.02, 1.42, 1.6, 0.42, 0.85, 1.16, 0.47, 0.21, 
+
+L2_sTRMV_o_UN2
+3.66, 0.0, 2.53, 0.0, 3.52, 0.0, 3.53, 0.0, 1.7, 0.0, 2.38, 0.0, 1.89, 0.0, 1.7, 0.0, 1.52, 0.0, 1.02, 0.0, 1.42, 0.0, 1.6, 0.0, 0.42, 0.0, 0.85, 0.0, 1.16, 0.0, 0.47, 0.0, 0.21, 0.0, 
+
+L2_sTRMV_o_UT
+0.14, 0.23, 0.47, 0.96, 0.67, 0.91, 1.11, 1.02, 1.91, 1.7, 2.05, 2.18, 2.41, 2.81, 2.6, 2.55, 3.88, 
+
+L2_sTRMV_o_UH
+0.14, 0.23, 0.47, 0.96, 0.67, 0.91, 1.11, 1.02, 1.91, 1.7, 2.05, 2.18, 2.41, 2.81, 2.6, 2.55, 3.88, 
+
+L2_dTRMV_A_nn
+0.2, 0.8, 0.5, 0.5, 0.5, 0.6, 0.2, 0.9, 0.8, 0.8, 0.7, 0.5, 0.7, 0.2, 0.4, 0.4, 0.7, 0.0, 0.9, 0.1, 0.3, 0.6, 0.1, 0.1, 0.2, 0.1, 0.5, 0.4, 0.9, 0.6, 0.2, 0.1, 0.4, 0.2, 0.0, 0.0, 0.1, 0.1, 0.6, 0.7, 0.3, 0.4, 0.4, 0.7, 0.5, 0.3, 0.9, 0.9, 0.9, 0.5, 0.1, 0.0, 0.0, 0.0, 0.6, 0.3, 0.4, 0.8, 0.2, 0.6, 0.8, 0.3, 0.9, 0.8, 0.2, 0.2, 0.3, 0.2, 0.0, 0.0, 0.0, 0.0, 0.3, 0.8, 0.1, 0.4, 0.4, 0.2, 0.3, 0.7, 0.7, 0.9, 0.3, 0.2, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.9, 0.7, 0.6, 0.6, 0.5, 0.5, 0.9, 0.1, 0.1, 0.2, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.3, 0.6, 0.3, 0.3, 0.6, 0.2, 0.9, 0.9, 0.7, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.8, 0.5, 0.1, 0.9, 0.9, 0.4, 0.8, 0.8, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.5, 0.7, 0.4, 0.5, 0.5, 0.8, 0.4, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6, 0.5, 0.9, 0.3, 0.8, 0.3, 0.1, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4, 0.4, 0.8, 0.9, 0.7, 0.7, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.7, 0.8, 0.9, 0.2, 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.9, 0.7, 0.6, 0.7, 0.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.1, 0.6, 0.5, 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.6, 0.3, 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.6, 0.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.5, 
+
+L2_dTRMV_A_nn_pu
+0.2, 0.8, 0.5, 0.5, 0.5, 0.6, 0.2, 0.9, 0.8, 0.8, 0.7, 0.5, 0.7, 0.2, 0.4, 0.4, 0.7, 0.9, 0.1, 0.3, 0.6, 0.1, 0.1, 0.2, 0.1, 0.5, 0.4, 0.9, 0.6, 0.2, 0.1, 0.4, 0.2, 0.1, 0.1, 0.6, 0.7, 0.3, 0.4, 0.4, 0.7, 0.5, 0.3, 0.9, 0.9, 0.9, 0.5, 0.1, 0.6, 0.3, 0.4, 0.8, 0.2, 0.6, 0.8, 0.3, 0.9, 0.8, 0.2, 0.2, 0.3, 0.2, 0.3, 0.8, 0.1, 0.4, 0.4, 0.2, 0.3, 0.7, 0.7, 0.9, 0.3, 0.2, 0.6, 0.9, 0.9, 0.7, 0.6, 0.6, 0.5, 0.5, 0.9, 0.1, 0.1, 0.2, 0.6, 0.9, 0.3, 0.6, 0.3, 0.3, 0.6, 0.2, 0.9, 0.9, 0.7, 0.3, 0.3, 0.8, 0.5, 0.1, 0.9, 0.9, 0.4, 0.8, 0.8, 0.2, 0.3, 0.5, 0.7, 0.4, 0.5, 0.5, 0.8, 0.4, 0.8, 0.6, 0.5, 0.9, 0.3, 0.8, 0.3, 0.1, 0.1, 0.4, 0.4, 0.8, 0.9, 0.7, 0.7, 0.3, 0.5, 0.7, 0.8, 0.9, 0.2, 0.8, 0.9, 0.7, 0.6, 0.7, 0.1, 0.1, 0.6, 0.5, 0.9, 0.6, 0.3, 0.8, 0.6, 0.2, 0.5, 
+
+L2_dTRMV_x_n1
+0.3, 0.8, 0.3, 0.3, 0.4, 0.5, 0.3, 0.4, 0.5, 0.1, 0.1, 0.5, 0.6, 0.4, 0.8, 0.8, 0.3, 
+
+L2_dTRMV_x_n2
+0.3, 0.0, 0.8, 0.0, 0.3, 0.0, 0.3, 0.0, 0.4, 0.0, 0.5, 0.0, 0.3, 0.0, 0.4, 0.0, 0.5, 0.0, 0.1, 0.0, 0.1, 0.0, 0.5, 0.0, 0.6, 0.0, 0.4, 0.0, 0.8, 0.0, 0.8, 0.0, 0.3, 0.0, 
+
+L2_dTRMV_o_UN
+4.07, 2.73, 3.42, 2.7, 2.67, 2.66, 2.9, 3.07, 2.17, 1.41, 2.29, 2.11, 1.89, 1.19, 0.96, 0.54, 0.15, 
+
+L2_dTRMV_o_UN2
+4.07, 0.0, 2.73, 0.0, 3.42, 0.0, 2.7, 0.0, 2.67, 0.0, 2.66, 0.0, 2.9, 0.0, 3.07, 0.0, 2.17, 0.0, 1.41, 0.0, 2.29, 0.0, 2.11, 0.0, 1.89, 0.0, 1.19, 0.0, 0.96, 0.0, 0.54, 0.0, 0.15, 0.0, 
+
+L2_dTRMV_o_UT
+0.06, 0.96, 0.26, 0.6, 1.02, 1.36, 1.23, 1.33, 1.73, 2.07, 1.71, 2.88, 3.6, 2.67, 3.32, 3.11, 3.38, 
+
+L2_dTRMV_o_UH
+0.06, 0.96, 0.26, 0.6, 1.02, 1.36, 1.23, 1.33, 1.73, 2.07, 1.71, 2.88, 3.6, 2.67, 3.32, 3.11, 3.38, 
+
+L2_cTRMV_A_nn
+0.10000000149, 0.5, 0.899999976158, 0.5, 0.699999988079, 0.40000000596, 0.300000011921, 0.600000023842, 0.300000011921, 0.20000000298, 0.10000000149, 0.699999988079, 0.5, 0.899999976158, 0.20000000298, 0.5, 0.10000000149, 0.699999988079, 0.300000011921, 0.600000023842, 0.600000023842, 0.800000011921, 0.899999976158, 0.600000023842, 0.5, 0.300000011921, 0.699999988079, 0.40000000596, 0.800000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.699999988079, 0.10000000149, 0.0, 0.0, 0.20000000298, 0.40000000596, 0.899999976158, 0.899999976158, 0.699999988079, 0.300000011921, 0.5, 0.20000000298, 0.20000000298, 0.20000000298, 0.5, 0.40000000596, 0.300000011921, 0.20000000298, 0.699999988079, 0.20000000298, 0.600000023842, 0.699999988079, 0.300000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.40000000596, 0.300000011921, 0.5, 0.600000023842, 0.5, 0.300000011921, 0.40000000596, 0.699999988079, 0.20000000298, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.5, 0.300000011921, 0.10000000149, 0.10000000149, 0.300000011921, 0.600000023842, 0.600000023842, 0.5, 0.20000000298, 0.10000000149, 0.600000023842, 0.300000011921, 0.5, 0.699999988079, 0.5, 0.20000000298, 0.40000000596, 0.699999988079, 0.800000011921, 0.20000000298, 0.899999976158, 0.20000000298, 0.40000000596, 0.600000023842, 0.40000000596, 0.899999976158, 0.899999976158, 0.300000011921, 0.899999976158, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.699999988079, 0.20000000298, 0.800000011921, 0.300000011921, 0.5, 0.300000011921, 0.300000011921, 0.300000011921, 0.300000011921, 0.800000011921, 0.600000023842, 0.899999976158, 0.20000000298, 0.300000011921, 0.5, 0.600000023842, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.20000000298, 0.20000000298, 0.20000000298, 0.10000000149, 0.40000000596, 0.5, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.5, 0.5, 0.899999976158, 0.5, 0.800000011921, 0.5, 0.899999976158, 0.800000011921, 0.600000023842, 0.10000000149, 0.10000000149, 0.899999976158, 0.899999976158, 0.40000000596, 0.699999988079, 0.899999976158, 0.10000000149, 0.40000000596, 0.40000000596, 0.10000000149, 0.300000011921, 0.699999988079, 0.300000011921, 0.20000000298, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.5, 0.300000011921, 0.10000000149, 0.10000000149, 0.40000000596, 0.699999988079, 0.10000000149, 0.899999976158, 0.600000023842, 0.20000000298, 0.800000011921, 0.699999988079, 0.5, 0.899999976158, 0.40000000596, 0.10000000149, 0.600000023842, 0.300000011921, 0.300000011921, 0.600000023842, 0.5, 0.600000023842, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.40000000596, 0.300000011921, 0.699999988079, 0.899999976158, 0.5, 0.20000000298, 0.600000023842, 0.899999976158, 0.600000023842, 0.10000000149, 0.10000000149, 0.40000000596, 0.699999988079, 0.10000000149, 0.40000000596, 0.10000000149, 0.10000000149, 0.10000000149, 0.5, 0.300000011921, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.300000011921, 0.40000000596, 0.899999976158, 0.800000011921, 0.300000011921, 0.600000023842, 0.10000000149, 0.5, 0.699999988079, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.600000023842, 0.300000011921, 0.600000023842, 0.699999988079, 0.600000023842, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.800000011921, 0.800000011921, 0.600000023842, 0.899999976158, 0.20000000298, 0.40000000596, 0.300000011921, 0.20000000298, 0.20000000298, 0.40000000596, 0.20000000298, 0.699999988079, 0.5, 0.300000011921, 0.300000011921, 0.10000000149, 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.800000011921, 0.20000000298, 0.800000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.600000023842, 0.40000000596, 0.20000000298, 0.40000000596, 0.300000011921, 0.300000011921, 0.600000023842, 0.300000011921, 0.10000000149, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.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, 0.10000000149, 0.10000000149, 0.300000011921, 0.5, 0.899999976158, 0.899999976158, 0.20000000298, 0.20000000298, 0.600000023842, 0.10000000149, 0.20000000298, 0.800000011921, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.10000000149, 0.20000000298, 0.5, 0.5, 0.10000000149, 0.300000011921, 0.40000000596, 0.699999988079, 0.899999976158, 0.40000000596, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.40000000596, 0.40000000596, 0.600000023842, 0.20000000298, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.899999976158, 0.800000011921, 0.600000023842, 0.40000000596, 0.300000011921, 0.300000011921, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.20000000298, 0.899999976158, 0.5, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.699999988079, 0.40000000596, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.10000000149, 
+
+L2_cTRMV_A_nn_pu
+0.10000000149, 0.5, 0.899999976158, 0.5, 0.699999988079, 0.40000000596, 0.300000011921, 0.600000023842, 0.300000011921, 0.20000000298, 0.10000000149, 0.699999988079, 0.5, 0.899999976158, 0.20000000298, 0.5, 0.10000000149, 0.699999988079, 0.300000011921, 0.600000023842, 0.600000023842, 0.800000011921, 0.899999976158, 0.600000023842, 0.5, 0.300000011921, 0.699999988079, 0.40000000596, 0.800000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.699999988079, 0.10000000149, 0.20000000298, 0.40000000596, 0.899999976158, 0.899999976158, 0.699999988079, 0.300000011921, 0.5, 0.20000000298, 0.20000000298, 0.20000000298, 0.5, 0.40000000596, 0.300000011921, 0.20000000298, 0.699999988079, 0.20000000298, 0.600000023842, 0.699999988079, 0.300000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.40000000596, 0.300000011921, 0.5, 0.600000023842, 0.5, 0.300000011921, 0.40000000596, 0.699999988079, 0.20000000298, 0.899999976158, 0.5, 0.300000011921, 0.10000000149, 0.10000000149, 0.300000011921, 0.600000023842, 0.600000023842, 0.5, 0.20000000298, 0.10000000149, 0.600000023842, 0.300000011921, 0.5, 0.699999988079, 0.5, 0.20000000298, 0.40000000596, 0.699999988079, 0.800000011921, 0.20000000298, 0.899999976158, 0.20000000298, 0.40000000596, 0.600000023842, 0.40000000596, 0.899999976158, 0.899999976158, 0.300000011921, 0.899999976158, 0.5, 0.800000011921, 0.699999988079, 0.20000000298, 0.800000011921, 0.300000011921, 0.5, 0.300000011921, 0.300000011921, 0.300000011921, 0.300000011921, 0.800000011921, 0.600000023842, 0.899999976158, 0.20000000298, 0.300000011921, 0.5, 0.600000023842, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.20000000298, 0.20000000298, 0.20000000298, 0.10000000149, 0.40000000596, 0.5, 0.600000023842, 0.800000011921, 0.5, 0.5, 0.899999976158, 0.5, 0.800000011921, 0.5, 0.899999976158, 0.800000011921, 0.600000023842, 0.10000000149, 0.10000000149, 0.899999976158, 0.899999976158, 0.40000000596, 0.699999988079, 0.899999976158, 0.10000000149, 0.40000000596, 0.40000000596, 0.10000000149, 0.300000011921, 0.699999988079, 0.300000011921, 0.20000000298, 0.600000023842, 0.699999988079, 0.5, 0.300000011921, 0.10000000149, 0.10000000149, 0.40000000596, 0.699999988079, 0.10000000149, 0.899999976158, 0.600000023842, 0.20000000298, 0.800000011921, 0.699999988079, 0.5, 0.899999976158, 0.40000000596, 0.10000000149, 0.600000023842, 0.300000011921, 0.300000011921, 0.600000023842, 0.5, 0.600000023842, 0.10000000149, 0.300000011921, 0.40000000596, 0.300000011921, 0.699999988079, 0.899999976158, 0.5, 0.20000000298, 0.600000023842, 0.899999976158, 0.600000023842, 0.10000000149, 0.10000000149, 0.40000000596, 0.699999988079, 0.10000000149, 0.40000000596, 0.10000000149, 0.10000000149, 0.10000000149, 0.5, 0.300000011921, 0.899999976158, 0.800000011921, 0.300000011921, 0.40000000596, 0.899999976158, 0.800000011921, 0.300000011921, 0.600000023842, 0.10000000149, 0.5, 0.699999988079, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.600000023842, 0.300000011921, 0.600000023842, 0.699999988079, 0.600000023842, 0.600000023842, 0.10000000149, 0.800000011921, 0.800000011921, 0.600000023842, 0.899999976158, 0.20000000298, 0.40000000596, 0.300000011921, 0.20000000298, 0.20000000298, 0.40000000596, 0.20000000298, 0.699999988079, 0.5, 0.300000011921, 0.300000011921, 0.10000000149, 0.5, 0.800000011921, 0.20000000298, 0.800000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.600000023842, 0.40000000596, 0.20000000298, 0.40000000596, 0.300000011921, 0.300000011921, 0.600000023842, 0.300000011921, 0.10000000149, 0.10000000149, 0.5, 0.10000000149, 0.10000000149, 0.300000011921, 0.5, 0.899999976158, 0.899999976158, 0.20000000298, 0.20000000298, 0.600000023842, 0.10000000149, 0.20000000298, 0.800000011921, 0.600000023842, 0.300000011921, 0.10000000149, 0.20000000298, 0.5, 0.5, 0.10000000149, 0.300000011921, 0.40000000596, 0.699999988079, 0.899999976158, 0.40000000596, 0.699999988079, 0.40000000596, 0.40000000596, 0.40000000596, 0.600000023842, 0.20000000298, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.300000011921, 0.899999976158, 0.800000011921, 0.600000023842, 0.40000000596, 0.300000011921, 0.300000011921, 0.40000000596, 0.20000000298, 0.300000011921, 0.20000000298, 0.899999976158, 0.5, 0.699999988079, 0.10000000149, 0.699999988079, 0.40000000596, 0.800000011921, 0.20000000298, 0.10000000149, 
+
+L2_cTRMV_x_n1
+0.300000011921, 0.600000023842, 0.699999988079, 0.40000000596, 0.10000000149, 0.699999988079, 0.899999976158, 0.699999988079, 0.300000011921, 0.600000023842, 0.10000000149, 0.20000000298, 0.699999988079, 0.800000011921, 0.600000023842, 0.699999988079, 0.10000000149, 0.20000000298, 0.600000023842, 0.5, 0.899999976158, 0.40000000596, 0.10000000149, 0.800000011921, 0.300000011921, 0.899999976158, 0.800000011921, 0.800000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.5, 0.20000000298, 0.600000023842, 
+
+L2_cTRMV_x_n2
+0.300000011921, 0.600000023842, 0.0, 0.0, 0.699999988079, 0.40000000596, 0.0, 0.0, 0.10000000149, 0.699999988079, 0.0, 0.0, 0.899999976158, 0.699999988079, 0.0, 0.0, 0.300000011921, 0.600000023842, 0.0, 0.0, 0.10000000149, 0.20000000298, 0.0, 0.0, 0.699999988079, 0.800000011921, 0.0, 0.0, 0.600000023842, 0.699999988079, 0.0, 0.0, 0.10000000149, 0.20000000298, 0.0, 0.0, 0.600000023842, 0.5, 0.0, 0.0, 0.899999976158, 0.40000000596, 0.0, 0.0, 0.10000000149, 0.800000011921, 0.0, 0.0, 0.300000011921, 0.899999976158, 0.0, 0.0, 0.800000011921, 0.800000011921, 0.0, 0.0, 0.899999976158, 0.899999976158, 0.0, 0.0, 0.10000000149, 0.5, 0.0, 0.0, 0.20000000298, 0.600000023842, 0.0, 0.0, 
+
+L2_cTRMV_o_UN
+-1.51000003606, 9.79000002131, -0.990000025034, 7.61000006884, -0.829999991208, 7.85000001118, -1.33999999076, 6.02000009298, -1.3100000532, 7.02000000209, -0.920000028163, 5.94000007793, -1.58000001654, 4.44000008538, 0.730000029206, 5.39000010476, 0.379999931604, 3.89000003099, -0.239999983311, 3.80000006855, -0.570000024438, 3.39000003323, -0.929999969602, 2.51000003085, -1.49000000641, 2.55000004694, -0.590000008643, 2.71000002488, -0.840000001192, 1.08000001356, -0.740000017583, 0.520000018477, -0.0200000020862, 0.140000007153, 
+
+L2_cTRMV_o_UN2
+-1.51000003606, 9.79000002131, 0.0, 0.0, -0.990000025034, 7.61000006884, 0.0, 0.0, -0.829999991208, 7.85000001118, 0.0, 0.0, -1.33999999076, 6.02000009298, 0.0, 0.0, -1.3100000532, 7.02000000209, 0.0, 0.0, -0.920000028163, 5.94000007793, 0.0, 0.0, -1.58000001654, 4.44000008538, 0.0, 0.0, 0.730000029206, 5.39000010476, 0.0, 0.0, 0.379999931604, 3.89000003099, 0.0, 0.0, -0.239999983311, 3.80000006855, 0.0, 0.0, -0.570000024438, 3.39000003323, 0.0, 0.0, -0.929999969602, 2.51000003085, 0.0, 0.0, -1.49000000641, 2.55000004694, 0.0, 0.0, -0.590000008643, 2.71000002488, 0.0, 0.0, -0.840000001192, 1.08000001356, 0.0, 0.0, -0.740000017583, 0.520000018477, 0.0, 0.0, -0.0200000020862, 0.140000007153, 0.0, 0.0, 
+
+L2_cTRMV_o_UT
+-0.270000010282, 0.210000009239, -0.050000013411, 1.0500000149, 0.0799999643862, 1.90999998018, 0.269999964088, 2.12000000432, -0.590000015348, 2.34000005186, -1.11999999464, 2.38000002921, -0.620000036359, 2.81000006735, -0.739999984801, 3.56000006512, -0.500000040978, 5.01000004277, 0.659999953359, 4.66000004426, -0.290000020564, 6.07000011086, -0.819999991655, 5.09000007719, -0.679999957681, 6.59999995157, -0.600000074506, 6.39000007868, -1.20999998912, 6.10000017136, -3.29999985546, 7.79000002876, -2.48999999225, 8.90000004843, 
+
+L2_cTRMV_o_UH
+0.33000001356, -0.0900000026822, 0.870000019968, 0.190000004172, 1.6999999918, 0.350000018626, 2.35000000075, 0.0600000204146, 2.37000004306, 0.0800000441074, 2.56000002265, 0.0400000339746, 2.98000006944, 0.0900000280142, 3.64000008911, 0.420000038594, 5.45999999359, 0.76999998346, 4.68000010595, 1.17999997482, 6.2900001055, 0.870000000596, 4.44000006378, 0.550000011921, 5.72000004083, 0.620000077337, 6.58000007987, 0.849999961257, 6.49000013307, 0.559999994338, 8.10000002533, -0.069999935776, 9.09000006825, 0.0200000341237, 
+
+L2_zTRMV_A_nn
+0.3, 0.3, 0.6, 0.9, 0.8, 0.8, 0.8, 0.4, 0.6, 0.5, 0.3, 0.1, 0.6, 0.7, 0.1, 0.1, 0.8, 0.6, 0.1, 0.6, 0.5, 0.9, 0.5, 0.1, 0.5, 0.4, 0.8, 0.2, 0.4, 0.9, 0.7, 0.1, 0.2, 0.3, 0.0, 0.0, 0.6, 0.9, 0.8, 0.3, 0.2, 0.6, 0.1, 0.7, 0.7, 0.1, 0.7, 0.5, 0.5, 0.4, 0.8, 0.2, 0.2, 0.6, 0.2, 0.4, 0.7, 0.7, 0.1, 0.1, 0.6, 0.2, 0.6, 0.2, 0.5, 0.1, 0.8, 0.9, 0.0, 0.0, 0.0, 0.0, 0.7, 0.9, 0.7, 0.6, 0.3, 0.8, 0.9, 0.4, 0.9, 0.2, 0.1, 0.6, 0.6, 0.8, 0.6, 0.4, 0.1, 0.7, 0.1, 0.4, 0.4, 0.2, 0.3, 0.6, 0.7, 0.4, 0.5, 0.2, 0.5, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.6, 0.5, 0.3, 0.6, 0.5, 0.2, 0.8, 0.5, 0.6, 0.7, 0.9, 0.9, 0.9, 0.7, 0.2, 0.1, 0.8, 0.1, 0.6, 0.1, 0.3, 0.3, 0.9, 0.3, 0.8, 0.7, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.6, 0.9, 0.1, 0.5, 0.9, 0.4, 0.5, 0.8, 0.7, 0.8, 0.1, 0.9, 0.1, 0.2, 0.8, 0.3, 0.3, 0.1, 0.6, 0.9, 0.7, 0.1, 0.3, 0.2, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.5, 0.2, 0.5, 0.8, 0.3, 0.4, 0.6, 0.4, 0.5, 0.1, 0.5, 0.3, 0.4, 0.4, 0.3, 0.4, 0.3, 0.8, 0.1, 0.9, 0.6, 0.2, 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.9, 0.7, 0.9, 0.1, 0.1, 0.8, 0.9, 0.1, 0.2, 0.7, 0.8, 0.4, 0.7, 0.3, 0.7, 0.9, 0.2, 0.6, 0.5, 0.6, 0.3, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.4, 0.3, 0.3, 0.8, 0.5, 0.6, 0.5, 0.4, 0.8, 0.1, 0.7, 0.6, 0.5, 0.2, 0.3, 0.4, 0.4, 0.7, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 0.3, 0.2, 0.8, 0.4, 0.3, 0.5, 0.8, 0.7, 0.5, 0.7, 0.1, 0.7, 0.2, 0.5, 0.8, 0.1, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.1, 0.6, 0.3, 0.2, 0.9, 0.4, 0.9, 0.6, 0.9, 0.5, 0.4, 0.7, 0.3, 0.6, 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.1, 0.4, 0.1, 0.6, 0.1, 0.3, 0.2, 0.5, 0.3, 0.3, 0.4, 0.8, 0.8, 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.5, 0.3, 0.1, 0.8, 0.6, 0.5, 0.7, 0.7, 0.2, 0.2, 0.5, 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.4, 0.8, 0.2, 0.2, 0.7, 0.1, 0.8, 0.6, 0.4, 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.9, 0.1, 0.3, 0.2, 0.5, 0.3, 0.9, 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.9, 0.7, 0.2, 0.3, 0.6, 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.8, 0.3, 0.8, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.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.3, 
+
+L2_zTRMV_A_nn_pu
+0.3, 0.3, 0.6, 0.9, 0.8, 0.8, 0.8, 0.4, 0.6, 0.5, 0.3, 0.1, 0.6, 0.7, 0.1, 0.1, 0.8, 0.6, 0.1, 0.6, 0.5, 0.9, 0.5, 0.1, 0.5, 0.4, 0.8, 0.2, 0.4, 0.9, 0.7, 0.1, 0.2, 0.3, 0.6, 0.9, 0.8, 0.3, 0.2, 0.6, 0.1, 0.7, 0.7, 0.1, 0.7, 0.5, 0.5, 0.4, 0.8, 0.2, 0.2, 0.6, 0.2, 0.4, 0.7, 0.7, 0.1, 0.1, 0.6, 0.2, 0.6, 0.2, 0.5, 0.1, 0.8, 0.9, 0.7, 0.9, 0.7, 0.6, 0.3, 0.8, 0.9, 0.4, 0.9, 0.2, 0.1, 0.6, 0.6, 0.8, 0.6, 0.4, 0.1, 0.7, 0.1, 0.4, 0.4, 0.2, 0.3, 0.6, 0.7, 0.4, 0.5, 0.2, 0.5, 0.8, 0.5, 0.6, 0.5, 0.3, 0.6, 0.5, 0.2, 0.8, 0.5, 0.6, 0.7, 0.9, 0.9, 0.9, 0.7, 0.2, 0.1, 0.8, 0.1, 0.6, 0.1, 0.3, 0.3, 0.9, 0.3, 0.8, 0.7, 0.5, 0.2, 0.6, 0.9, 0.1, 0.5, 0.9, 0.4, 0.5, 0.8, 0.7, 0.8, 0.1, 0.9, 0.1, 0.2, 0.8, 0.3, 0.3, 0.1, 0.6, 0.9, 0.7, 0.1, 0.3, 0.2, 0.6, 0.1, 0.5, 0.2, 0.5, 0.8, 0.3, 0.4, 0.6, 0.4, 0.5, 0.1, 0.5, 0.3, 0.4, 0.4, 0.3, 0.4, 0.3, 0.8, 0.1, 0.9, 0.6, 0.2, 0.8, 0.9, 0.7, 0.9, 0.1, 0.1, 0.8, 0.9, 0.1, 0.2, 0.7, 0.8, 0.4, 0.7, 0.3, 0.7, 0.9, 0.2, 0.6, 0.5, 0.6, 0.3, 0.3, 0.3, 0.4, 0.3, 0.3, 0.8, 0.5, 0.6, 0.5, 0.4, 0.8, 0.1, 0.7, 0.6, 0.5, 0.2, 0.3, 0.4, 0.4, 0.7, 0.6, 0.7, 0.3, 0.2, 0.8, 0.4, 0.3, 0.5, 0.8, 0.7, 0.5, 0.7, 0.1, 0.7, 0.2, 0.5, 0.8, 0.1, 0.7, 0.3, 0.1, 0.6, 0.3, 0.2, 0.9, 0.4, 0.9, 0.6, 0.9, 0.5, 0.4, 0.7, 0.3, 0.6, 0.5, 0.1, 0.4, 0.1, 0.6, 0.1, 0.3, 0.2, 0.5, 0.3, 0.3, 0.4, 0.8, 0.8, 0.8, 0.5, 0.3, 0.1, 0.8, 0.6, 0.5, 0.7, 0.7, 0.2, 0.2, 0.5, 0.8, 0.4, 0.8, 0.2, 0.2, 0.7, 0.1, 0.8, 0.6, 0.4, 0.8, 0.9, 0.1, 0.3, 0.2, 0.5, 0.3, 0.9, 0.5, 0.9, 0.7, 0.2, 0.3, 0.6, 0.5, 0.8, 0.3, 0.8, 0.7, 0.1, 0.3, 
+
+L2_zTRMV_x_n1
+0.6, 0.2, 0.6, 0.1, 0.2, 0.6, 0.9, 0.9, 0.5, 0.8, 0.2, 0.4, 0.2, 0.3, 0.5, 0.2, 0.2, 0.8, 0.6, 0.3, 0.8, 0.5, 0.3, 0.2, 0.5, 0.8, 0.7, 0.1, 0.7, 0.4, 0.3, 0.2, 0.5, 0.4, 
+
+L2_zTRMV_x_n2
+0.6, 0.2, 0.0, 0.0, 0.6, 0.1, 0.0, 0.0, 0.2, 0.6, 0.0, 0.0, 0.9, 0.9, 0.0, 0.0, 0.5, 0.8, 0.0, 0.0, 0.2, 0.4, 0.0, 0.0, 0.2, 0.3, 0.0, 0.0, 0.5, 0.2, 0.0, 0.0, 0.2, 0.8, 0.0, 0.0, 0.6, 0.3, 0.0, 0.0, 0.8, 0.5, 0.0, 0.0, 0.3, 0.2, 0.0, 0.0, 0.5, 0.8, 0.0, 0.0, 0.7, 0.1, 0.0, 0.0, 0.7, 0.4, 0.0, 0.0, 0.3, 0.2, 0.0, 0.0, 0.5, 0.4, 0.0, 0.0, 
+
+L2_zTRMV_o_UN
+0.49, 8.08, 0.49, 6.68, -0.77, 7.48, -0.67, 7.0, 0.41, 5.55, 0.24, 4.05, 0.73, 4.61, 0.44, 4.03, 0.54, 4.04, 0.61, 3.66, -0.18, 2.54, 0.03, 2.55, 0.13, 2.13, 1.09, 1.22, 0.45, 1.47, 0.3, 0.92, -0.07, 0.19, 
+
+L2_zTRMV_o_UN2
+0.49, 8.08, 0.0, 0.0, 0.49, 6.68, 0.0, 0.0, -0.77, 7.48, 0.0, 0.0, -0.67, 7.0, 0.0, 0.0, 0.41, 5.55, 0.0, 0.0, 0.24, 4.05, 0.0, 0.0, 0.73, 4.61, 0.0, 0.0, 0.44, 4.03, 0.0, 0.0, 0.54, 4.04, 0.0, 0.0, 0.61, 3.66, 0.0, 0.0, -0.18, 2.54, 0.0, 0.0, 0.03, 2.55, 0.0, 0.0, 0.13, 2.13, 0.0, 0.0, 1.09, 1.22, 0.0, 0.0, 0.45, 1.47, 0.0, 0.0, 0.3, 0.92, 0.0, 0.0, -0.07, 0.19, 0.0, 0.0, 
+
+L2_zTRMV_o_UT
+0.12, 0.24, 0.45, 1.26, 0.37, 1.5, 0.15, 2.31, -0.37, 2.37, 0.79, 2.77, -0.55, 3.83, -0.07, 3.04, -0.27, 4.97, 0.08, 4.94, 0.46, 4.5, -1.6, 5.04, -1.32, 5.16, 0.6, 4.97, 0.8, 7.52, 0.18, 6.53, 0.08, 8.06, 
+
+L2_zTRMV_o_UH
+0.24, -0.12, 0.99, -0.9, 1.83, -0.18, 2.23, -0.21, 2.43, -0.53, 2.79, 1.17, 3.77, -0.51, 3.11, 0.06, 5.27, 0.39, 4.7, 0.44, 4.34, 0.1, 5.2, -1.98, 4.6, -0.88, 5.66, -0.43, 6.88, 0.32, 7.12, -0.11, 9.1, -1.8, 
+
+L2_sTBMV_A_nn
+0.7, 0.3, 0.8, 0.3, 0.3, 0.9, 0.4, 0.1, 0.4, 0.7, 0.7, 0.2, 0.7, 0.1, 0.8, 0.6, 0.5, 0.6, 0.1, 0.2, 0.4, 0.2, 0.8, 0.7, 0.8, 0.1, 0.5, 0.1, 0.2, 0.4, 0.2, 0.2, 0.7, 0.7, 0.6, 0.7, 0.4, 0.1, 0.5, 0.4, 0.1, 0.8, 0.4, 0.4, 0.9, 0.5, 0.9, 0.0, 0.9, 0.0, 0.0, 
+
+L2_sTBMV_x_n1
+0.8, 0.7, 0.1, 0.9, 0.1, 0.9, 0.3, 0.1, 0.1, 0.2, 0.3, 0.3, 0.5, 0.5, 0.7, 0.8, 0.4, 
+
+L2_sTBMV_x_n2
+0.8, 0.0, 0.7, 0.0, 0.1, 0.0, 0.9, 0.0, 0.1, 0.0, 0.9, 0.0, 0.3, 0.0, 0.1, 0.0, 0.1, 0.0, 0.2, 0.0, 0.3, 0.0, 0.3, 0.0, 0.5, 0.0, 0.5, 0.0, 0.7, 0.0, 0.8, 0.0, 0.4, 0.0, 
+
+L2_sTBMV_o_UN
+0.85, 1.05, 0.17, 0.88, 0.4, 0.75, 0.09, 0.24, 0.25, 0.2, 0.47, 0.86, 0.6, 0.91, 0.96, 0.76, 0.36, 
+
+L2_sTBMV_o_UN2
+0.85, 0.0, 1.05, 0.0, 0.17, 0.0, 0.88, 0.0, 0.4, 0.0, 0.75, 0.0, 0.09, 0.0, 0.24, 0.0, 0.25, 0.0, 0.2, 0.0, 0.47, 0.0, 0.86, 0.0, 0.6, 0.0, 0.91, 0.0, 0.96, 0.0, 0.76, 0.0, 0.36, 0.0, 
+
+L2_sTBMV_o_UT
+0.56, 0.45, 0.89, 1.27, 0.74, 0.73, 0.56, 0.62, 0.28, 0.1, 0.15, 0.35, 0.59, 0.46, 0.58, 1.08, 1.71, 
+
+L2_sTBMV_o_UH
+0.56, 0.45, 0.89, 1.27, 0.74, 0.73, 0.56, 0.62, 0.28, 0.1, 0.15, 0.35, 0.59, 0.46, 0.58, 1.08, 1.71, 
+
+L2_dTBMV_A_nn
+0.1, 0.4, 0.8, 0.2, 0.1, 0.1, 0.5, 0.2, 0.3, 0.8, 0.8, 0.4, 0.8, 0.6, 0.9, 0.8, 0.6, 0.4, 0.8, 0.1, 0.8, 0.3, 0.3, 0.6, 0.6, 0.3, 0.8, 0.4, 0.9, 0.3, 0.3, 0.2, 0.7, 0.3, 0.3, 0.8, 0.4, 0.5, 0.5, 0.5, 0.4, 0.4, 0.8, 0.9, 0.4, 0.2, 0.5, 0.0, 0.5, 0.0, 0.0, 
+
+L2_dTBMV_x_n1
+0.1, 0.5, 0.6, 0.9, 0.3, 0.9, 0.7, 0.3, 0.1, 0.1, 0.8, 0.3, 0.7, 0.7, 0.7, 0.2, 0.1, 
+
+L2_dTBMV_x_n2
+0.1, 0.0, 0.5, 0.0, 0.6, 0.0, 0.9, 0.0, 0.3, 0.0, 0.9, 0.0, 0.7, 0.0, 0.3, 0.0, 0.1, 0.0, 0.1, 0.0, 0.8, 0.0, 0.3, 0.0, 0.7, 0.0, 0.7, 0.0, 0.7, 0.0, 0.2, 0.0, 0.1, 0.0, 
+
+L2_dTBMV_o_UN
+0.69, 0.25, 0.57, 1.32, 1.41, 1.26, 0.67, 0.18, 0.73, 0.85, 0.79, 0.86, 0.98, 0.71, 0.78, 0.09, 0.05, 
+
+L2_dTBMV_o_UN2
+0.69, 0.0, 0.25, 0.0, 0.57, 0.0, 1.32, 0.0, 1.41, 0.0, 1.26, 0.0, 0.67, 0.0, 0.18, 0.0, 0.73, 0.0, 0.85, 0.0, 0.79, 0.0, 0.86, 0.0, 0.98, 0.0, 0.71, 0.0, 0.78, 0.0, 0.09, 0.0, 0.05, 0.0, 
+
+L2_dTBMV_o_UT
+0.01, 0.14, 0.43, 0.89, 1.14, 1.26, 1.37, 0.52, 0.71, 0.25, 0.41, 0.28, 0.93, 0.94, 1.19, 0.95, 0.43, 
+
+L2_dTBMV_o_UH
+0.01, 0.14, 0.43, 0.89, 1.14, 1.26, 1.37, 0.52, 0.71, 0.25, 0.41, 0.28, 0.93, 0.94, 1.19, 0.95, 0.43, 
+
+L2_cTBMV_A_nn
+0.40000000596, 0.20000000298, 0.600000023842, 0.10000000149, 0.800000011921, 0.40000000596, 0.10000000149, 0.20000000298, 0.300000011921, 0.899999976158, 0.600000023842, 0.40000000596, 0.899999976158, 0.800000011921, 0.300000011921, 0.699999988079, 0.5, 0.20000000298, 0.40000000596, 0.899999976158, 0.20000000298, 0.5, 0.600000023842, 0.20000000298, 0.40000000596, 0.10000000149, 0.10000000149, 0.699999988079, 0.600000023842, 0.5, 0.800000011921, 0.300000011921, 0.40000000596, 0.20000000298, 0.40000000596, 0.600000023842, 0.600000023842, 0.800000011921, 0.20000000298, 0.800000011921, 0.699999988079, 0.800000011921, 0.600000023842, 0.5, 0.899999976158, 0.300000011921, 0.899999976158, 0.10000000149, 0.5, 0.20000000298, 0.300000011921, 0.5, 0.10000000149, 0.800000011921, 0.5, 0.20000000298, 0.699999988079, 0.40000000596, 0.300000011921, 0.899999976158, 0.10000000149, 0.5, 0.20000000298, 0.800000011921, 0.699999988079, 0.20000000298, 0.699999988079, 0.600000023842, 0.600000023842, 0.40000000596, 0.899999976158, 0.10000000149, 0.300000011921, 0.699999988079, 0.899999976158, 0.40000000596, 0.40000000596, 0.40000000596, 0.40000000596, 0.899999976158, 0.20000000298, 0.800000011921, 0.699999988079, 0.600000023842, 0.899999976158, 0.600000023842, 0.800000011921, 0.699999988079, 0.899999976158, 0.5, 0.5, 0.800000011921, 0.10000000149, 0.10000000149, 0.0, 0.0, 0.600000023842, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cTBMV_x_n1
+0.10000000149, 0.40000000596, 0.699999988079, 0.300000011921, 0.600000023842, 0.10000000149, 0.600000023842, 0.20000000298, 0.899999976158, 0.699999988079, 0.899999976158, 0.5, 0.600000023842, 0.10000000149, 0.20000000298, 0.300000011921, 0.20000000298, 0.5, 0.5, 0.20000000298, 0.899999976158, 0.40000000596, 0.20000000298, 0.5, 0.10000000149, 0.10000000149, 0.40000000596, 0.800000011921, 0.5, 0.20000000298, 0.40000000596, 0.800000011921, 0.899999976158, 0.899999976158, 
+
+L2_cTBMV_x_n2
+0.10000000149, 0.40000000596, 0.0, 0.0, 0.699999988079, 0.300000011921, 0.0, 0.0, 0.600000023842, 0.10000000149, 0.0, 0.0, 0.600000023842, 0.20000000298, 0.0, 0.0, 0.899999976158, 0.699999988079, 0.0, 0.0, 0.899999976158, 0.5, 0.0, 0.0, 0.600000023842, 0.10000000149, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.0, 0.0, 0.20000000298, 0.5, 0.0, 0.0, 0.5, 0.20000000298, 0.0, 0.0, 0.899999976158, 0.40000000596, 0.0, 0.0, 0.20000000298, 0.5, 0.0, 0.0, 0.10000000149, 0.10000000149, 0.0, 0.0, 0.40000000596, 0.800000011921, 0.0, 0.0, 0.5, 0.20000000298, 0.0, 0.0, 0.40000000596, 0.800000011921, 0.0, 0.0, 0.899999976158, 0.899999976158, 0.0, 0.0, 
+
+L2_cTBMV_o_UN
+0.790000031739, 0.750000035018, 0.380000038147, 1.1000000298, 0.810000007749, 1.58000002995, 0.330000024736, 1.69000000715, 0.340000028759, 1.40999998689, 0.689999986291, 1.0700000304, -0.179999991953, 1.27000003636, 0.429999980032, 1.02000000581, -0.180000006109, 1.35999999732, 0.289999981821, 1.17000000209, -0.420000009537, 0.839999995977, 0.139999983311, 1.32999999791, 0.119999988675, 1.26000000328, -0.820000016987, 1.92000002444, 0.449999961257, 2.65999997348, -0.440000016093, 0.900000013411, 0.270000003576, 0.810000010729, 
+
+L2_cTBMV_o_UN2
+0.790000031739, 0.750000035018, 0.0, 0.0, 0.380000038147, 1.1000000298, 0.0, 0.0, 0.810000007749, 1.58000002995, 0.0, 0.0, 0.330000024736, 1.69000000715, 0.0, 0.0, 0.340000028759, 1.40999998689, 0.0, 0.0, 0.689999986291, 1.0700000304, 0.0, 0.0, -0.179999991953, 1.27000003636, 0.0, 0.0, 0.429999980032, 1.02000000581, 0.0, 0.0, -0.180000006109, 1.35999999732, 0.0, 0.0, 0.289999981821, 1.17000000209, 0.0, 0.0, -0.420000009537, 0.839999995977, 0.0, 0.0, 0.139999983311, 1.32999999791, 0.0, 0.0, 0.119999988675, 1.26000000328, 0.0, 0.0, -0.820000016987, 1.92000002444, 0.0, 0.0, 0.449999961257, 2.65999997348, 0.0, 0.0, -0.440000016093, 0.900000013411, 0.0, 0.0, 0.270000003576, 0.810000010729, 0.0, 0.0, 
+
+L2_cTBMV_o_UT
+-0.0400000011921, 0.180000005364, 0.0299999986589, 0.420000014752, 0.320000003576, 1.65000001565, 0.470000032634, 1.53000003442, 0.590000012368, 0.880000018775, 0.490000028759, 1.60999999508, 0.730000033677, 1.79000002801, 0.0699999886751, 1.52000005275, 0.429999997914, 1.17000003412, 0.169999998361, 0.740000014603, -0.220000017732, 1.03999999747, -0.330000015795, 1.77999998599, 0.429999975562, 0.940000013113, -0.379999991953, 1.27999999419, -0.230000035167, 1.04000002652, -0.380000036657, 2.03000002623, 0.579999988973, 1.36000001222, 
+
+L2_cTBMV_o_UH
+0.120000003576, 0.140000004172, 0.2300000076, 0.120000014752, 1.34000002503, -0.649999984354, 1.21000004128, -0.949999997765, 0.970000016242, -0.140000016093, 1.85000000969, -0.429999970347, 1.7900000295, -0.429999996424, 1.13000002921, -0.720000016987, 0.970000019968, 0.00999997273087, 0.810000004023, 0.300000007451, 1.14000000492, -0.579999994189, 1.27000002295, -0.799999986589, 1.12999998599, 0.280000012815, 1.23999999523, 0.439999998957, 1.37000001848, -0.280000018775, 2.14000005335, 0.209999992847, 1.48000000387, 0.240000002682, 
+
+L2_zTBMV_A_nn
+0.6, 0.8, 0.6, 0.1, 0.1, 0.3, 0.3, 0.3, 0.1, 0.5, 0.9, 0.9, 0.7, 0.3, 0.6, 0.3, 0.1, 0.1, 0.3, 0.5, 0.1, 0.8, 0.4, 0.2, 0.3, 0.8, 0.9, 0.5, 0.8, 0.8, 0.7, 0.8, 0.6, 0.8, 0.8, 0.8, 0.5, 0.6, 0.6, 0.8, 0.3, 0.2, 0.1, 0.6, 0.8, 0.3, 0.7, 0.7, 0.8, 0.2, 0.3, 0.5, 0.5, 0.2, 0.5, 0.6, 0.5, 0.3, 0.9, 0.6, 0.5, 0.2, 0.3, 0.9, 0.1, 0.8, 0.6, 0.4, 0.8, 0.5, 0.1, 0.4, 0.5, 0.8, 0.8, 0.9, 0.3, 0.7, 0.4, 0.6, 0.6, 0.4, 0.8, 0.2, 0.7, 0.1, 0.2, 0.3, 0.2, 0.8, 0.9, 0.6, 0.9, 0.2, 0.0, 0.0, 0.9, 0.9, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zTBMV_x_n1
+0.1, 0.1, 0.4, 0.6, 0.8, 0.8, 0.2, 0.7, 0.6, 0.1, 0.2, 0.7, 0.3, 0.7, 0.6, 0.5, 0.7, 0.4, 0.2, 0.6, 0.3, 0.3, 0.8, 0.9, 0.2, 0.7, 0.8, 0.4, 0.3, 0.8, 0.8, 0.1, 0.7, 0.7, 
+
+L2_zTBMV_x_n2
+0.1, 0.1, 0.0, 0.0, 0.4, 0.6, 0.0, 0.0, 0.8, 0.8, 0.0, 0.0, 0.2, 0.7, 0.0, 0.0, 0.6, 0.1, 0.0, 0.0, 0.2, 0.7, 0.0, 0.0, 0.3, 0.7, 0.0, 0.0, 0.6, 0.5, 0.0, 0.0, 0.7, 0.4, 0.0, 0.0, 0.2, 0.6, 0.0, 0.0, 0.3, 0.3, 0.0, 0.0, 0.8, 0.9, 0.0, 0.0, 0.2, 0.7, 0.0, 0.0, 0.8, 0.4, 0.0, 0.0, 0.3, 0.8, 0.0, 0.0, 0.8, 0.1, 0.0, 0.0, 0.7, 0.7, 0.0, 0.0, 
+
+L2_zTBMV_o_UN
+0.0, 0.86, -0.83, 1.59, 0.28, 1.35, -0.37, 1.12, -0.39, 2.04, -0.72, 2.19, -0.18, 1.57, -0.08, 1.5, 0.33, 0.95, -0.02, 1.95, -1.02, 1.43, -0.15, 1.88, -0.65, 2.0, 0.56, 1.48, -0.16, 1.55, 1.15, 1.34, 0.0, 1.26, 
+
+L2_zTBMV_o_UN2
+0.0, 0.86, 0.0, 0.0, -0.83, 1.59, 0.0, 0.0, 0.28, 1.35, 0.0, 0.0, -0.37, 1.12, 0.0, 0.0, -0.39, 2.04, 0.0, 0.0, -0.72, 2.19, 0.0, 0.0, -0.18, 1.57, 0.0, 0.0, -0.08, 1.5, 0.0, 0.0, 0.33, 0.95, 0.0, 0.0, -0.02, 1.95, 0.0, 0.0, -1.02, 1.43, 0.0, 0.0, -0.15, 1.88, 0.0, 0.0, -0.65, 2.0, 0.0, 0.0, 0.56, 1.48, 0.0, 0.0, -0.16, 1.55, 0.0, 0.0, 1.15, 1.34, 0.0, 0.0, 0.0, 1.26, 0.0, 0.0, 
+
+L2_zTBMV_o_UT
+-0.02, 0.14, -0.01, 0.37, 0.04, 1.1, -0.23, 1.93, -0.44, 0.9, 0.01, 1.36, -0.31, 1.67, -1.02, 1.79, 0.76, 1.31, -0.18, 1.66, 0.28, 0.91, -0.24, 1.88, -0.48, 1.9, -0.67, 1.79, 0.02, 1.5, 1.04, 1.3, 0.12, 1.91, 
+
+L2_zTBMV_o_UH
+0.14, -0.02, 0.37, 0.11, 1.18, 0.16, 2.03, 0.53, 1.0, -0.54, 1.51, 0.36, 1.81, 0.03, 1.82, 0.27, 1.5, 0.55, 1.64, -0.12, 0.92, 0.39, 1.74, 0.46, 2.02, 0.3, 1.79, -0.17, 1.48, 0.52, 1.8, -0.16, 2.7, -0.15, 
+
+L2_sTRSV_A_nn
+24.0, 28.0, 28.0, 24.0, 8.0, 12.0, 20.0, 32.0, 28.0, 4.0, 24.0, 28.0, 20.0, 36.0, 12.0, 4.0, 24.0, 0.0, 4.0, 28.0, 24.0, 12.0, 4.0, 32.0, 36.0, 8.0, 36.0, 16.0, 20.0, 12.0, 8.0, 36.0, 28.0, 16.0, 0.0, 0.0, 12.0, 16.0, 12.0, 32.0, 20.0, 4.0, 32.0, 24.0, 16.0, 16.0, 28.0, 8.0, 20.0, 8.0, 20.0, 0.0, 0.0, 0.0, 36.0, 4.0, 16.0, 24.0, 12.0, 16.0, 24.0, 20.0, 12.0, 24.0, 20.0, 20.0, 36.0, 4.0, 0.0, 0.0, 0.0, 0.0, 28.0, 20.0, 20.0, 32.0, 20.0, 32.0, 8.0, 24.0, 4.0, 4.0, 24.0, 32.0, 12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 32.0, 28.0, 24.0, 36.0, 8.0, 12.0, 4.0, 24.0, 12.0, 36.0, 24.0, 28.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 32.0, 20.0, 32.0, 20.0, 16.0, 4.0, 16.0, 16.0, 28.0, 36.0, 12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 28.0, 8.0, 32.0, 20.0, 20.0, 20.0, 32.0, 28.0, 12.0, 32.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 28.0, 24.0, 28.0, 8.0, 36.0, 20.0, 36.0, 4.0, 32.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 24.0, 16.0, 20.0, 4.0, 28.0, 28.0, 28.0, 28.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 20.0, 32.0, 24.0, 16.0, 16.0, 8.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, 28.0, 28.0, 24.0, 20.0, 12.0, 12.0, 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.0, 32.0, 4.0, 20.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, 24.0, 8.0, 28.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, 16.0, 28.0, 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, 32.0, 4.0, 0.0, 0.0, 0.0, 0.0, 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, 
+
+L2_sTRSV_A_nn_pu
+24.0, 28.0, 28.0, 24.0, 8.0, 12.0, 20.0, 32.0, 28.0, 4.0, 24.0, 28.0, 20.0, 36.0, 12.0, 4.0, 24.0, 4.0, 28.0, 24.0, 12.0, 4.0, 32.0, 36.0, 8.0, 36.0, 16.0, 20.0, 12.0, 8.0, 36.0, 28.0, 16.0, 12.0, 16.0, 12.0, 32.0, 20.0, 4.0, 32.0, 24.0, 16.0, 16.0, 28.0, 8.0, 20.0, 8.0, 20.0, 36.0, 4.0, 16.0, 24.0, 12.0, 16.0, 24.0, 20.0, 12.0, 24.0, 20.0, 20.0, 36.0, 4.0, 28.0, 20.0, 20.0, 32.0, 20.0, 32.0, 8.0, 24.0, 4.0, 4.0, 24.0, 32.0, 12.0, 32.0, 28.0, 24.0, 36.0, 8.0, 12.0, 4.0, 24.0, 12.0, 36.0, 24.0, 28.0, 32.0, 20.0, 32.0, 20.0, 16.0, 4.0, 16.0, 16.0, 28.0, 36.0, 12.0, 28.0, 8.0, 32.0, 20.0, 20.0, 20.0, 32.0, 28.0, 12.0, 32.0, 28.0, 24.0, 28.0, 8.0, 36.0, 20.0, 36.0, 4.0, 32.0, 24.0, 16.0, 20.0, 4.0, 28.0, 28.0, 28.0, 28.0, 20.0, 32.0, 24.0, 16.0, 16.0, 8.0, 36.0, 28.0, 28.0, 24.0, 20.0, 12.0, 12.0, 24.0, 32.0, 4.0, 20.0, 24.0, 24.0, 8.0, 28.0, 8.0, 16.0, 28.0, 32.0, 32.0, 4.0, 12.0, 
+
+L2_sTRSV_x_n1
+0.2, 0.8, 0.1, 0.6, 0.5, 0.2, 0.5, 0.1, 0.6, 0.1, 0.8, 0.1, 0.9, 0.9, 0.9, 0.2, 0.9, 
+
+L2_sTRSV_x_n2
+0.2, 0.0, 0.8, 0.0, 0.1, 0.0, 0.6, 0.0, 0.5, 0.0, 0.2, 0.0, 0.5, 0.0, 0.1, 0.0, 0.6, 0.0, 0.1, 0.0, 0.8, 0.0, 0.1, 0.0, 0.9, 0.0, 0.9, 0.0, 0.9, 0.0, 0.2, 0.0, 0.9, 0.0, 
+
+L2_sTRSV_o_UN
+-2.40269, 2.01972, -0.194703, 0.104684, 0.0046076, -0.05174, -0.0637408, -0.0124843, 0.205715, -0.0232726, -0.0867832, 0.0777096, -0.0809462, 0.0455729, -0.0882813, -0.003125, 0.075, 
+
+L2_sTRSV_o_UN2
+-2.40269, 0.0, 2.01972, 0.0, -0.194703, 0.0, 0.104684, 0.0, 0.0046076, 0.0, -0.05174, 0.0, -0.0637408, 0.0, -0.0124843, 0.0, 0.205715, 0.0, -0.0232726, 0.0, -0.0867832, 0.0, 0.0777096, 0.0, -0.0809462, 0.0, 0.0455729, 0.0, -0.0882813, 0.0, -0.003125, 0.0, 0.075, 0.0, 
+
+L2_sTRSV_o_UT
+0.00833333, 0.141667, -0.341667, 0.0685185, 0.0914021, 0.235698, -0.232459, -0.309095, 0.309595, 0.159238, -0.122259, 0.139423, -0.079898, 0.0734248, -0.691031, 0.389425, 1.6854, 
+
+L2_sTRSV_o_UH
+0.00833333, 0.141667, -0.341667, 0.0685185, 0.0914021, 0.235698, -0.232459, -0.309095, 0.309595, 0.159238, -0.122259, 0.139423, -0.079898, 0.0734248, -0.691031, 0.389425, 1.6854, 
+
+L2_dTRSV_A_nn
+24.0, 36.0, 20.0, 28.0, 32.0, 20.0, 32.0, 16.0, 8.0, 16.0, 24.0, 20.0, 36.0, 24.0, 32.0, 12.0, 12.0, 0.0, 32.0, 36.0, 36.0, 8.0, 32.0, 28.0, 20.0, 36.0, 32.0, 24.0, 12.0, 4.0, 4.0, 32.0, 36.0, 28.0, 0.0, 0.0, 4.0, 4.0, 16.0, 16.0, 16.0, 8.0, 12.0, 24.0, 12.0, 20.0, 36.0, 20.0, 20.0, 32.0, 28.0, 0.0, 0.0, 0.0, 20.0, 36.0, 16.0, 12.0, 8.0, 4.0, 8.0, 24.0, 4.0, 24.0, 16.0, 28.0, 24.0, 16.0, 0.0, 0.0, 0.0, 0.0, 16.0, 32.0, 8.0, 20.0, 24.0, 12.0, 20.0, 24.0, 4.0, 36.0, 28.0, 12.0, 12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 12.0, 16.0, 24.0, 16.0, 32.0, 24.0, 4.0, 36.0, 28.0, 8.0, 12.0, 36.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 16.0, 4.0, 20.0, 36.0, 28.0, 24.0, 24.0, 32.0, 28.0, 12.0, 36.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 32.0, 12.0, 20.0, 24.0, 32.0, 32.0, 12.0, 24.0, 4.0, 32.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 32.0, 24.0, 8.0, 8.0, 16.0, 24.0, 4.0, 8.0, 36.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 32.0, 32.0, 36.0, 32.0, 20.0, 12.0, 20.0, 16.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 16.0, 24.0, 36.0, 12.0, 20.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, 36.0, 20.0, 20.0, 4.0, 36.0, 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, 4.0, 4.0, 24.0, 24.0, 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, 36.0, 8.0, 20.0, 4.0, 0.0, 0.0, 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, 8.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, 4.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 32.0, 
+
+L2_dTRSV_A_nn_pu
+24.0, 36.0, 20.0, 28.0, 32.0, 20.0, 32.0, 16.0, 8.0, 16.0, 24.0, 20.0, 36.0, 24.0, 32.0, 12.0, 12.0, 32.0, 36.0, 36.0, 8.0, 32.0, 28.0, 20.0, 36.0, 32.0, 24.0, 12.0, 4.0, 4.0, 32.0, 36.0, 28.0, 4.0, 4.0, 16.0, 16.0, 16.0, 8.0, 12.0, 24.0, 12.0, 20.0, 36.0, 20.0, 20.0, 32.0, 28.0, 20.0, 36.0, 16.0, 12.0, 8.0, 4.0, 8.0, 24.0, 4.0, 24.0, 16.0, 28.0, 24.0, 16.0, 16.0, 32.0, 8.0, 20.0, 24.0, 12.0, 20.0, 24.0, 4.0, 36.0, 28.0, 12.0, 12.0, 12.0, 16.0, 24.0, 16.0, 32.0, 24.0, 4.0, 36.0, 28.0, 8.0, 12.0, 36.0, 16.0, 4.0, 20.0, 36.0, 28.0, 24.0, 24.0, 32.0, 28.0, 12.0, 36.0, 32.0, 12.0, 20.0, 24.0, 32.0, 32.0, 12.0, 24.0, 4.0, 32.0, 32.0, 24.0, 8.0, 8.0, 16.0, 24.0, 4.0, 8.0, 36.0, 32.0, 32.0, 36.0, 32.0, 20.0, 12.0, 20.0, 16.0, 4.0, 16.0, 24.0, 36.0, 12.0, 20.0, 8.0, 36.0, 20.0, 20.0, 4.0, 36.0, 16.0, 4.0, 4.0, 24.0, 24.0, 16.0, 36.0, 8.0, 20.0, 4.0, 12.0, 8.0, 20.0, 4.0, 4.0, 32.0, 
+
+L2_dTRSV_x_n1
+0.7, 0.3, 0.2, 0.1, 0.9, 0.9, 0.7, 0.4, 0.8, 0.9, 0.6, 0.6, 0.7, 0.3, 0.7, 0.2, 0.2, 
+
+L2_dTRSV_x_n2
+0.7, 0.0, 0.3, 0.0, 0.2, 0.0, 0.1, 0.0, 0.9, 0.0, 0.9, 0.0, 0.7, 0.0, 0.4, 0.0, 0.8, 0.0, 0.9, 0.0, 0.6, 0.0, 0.6, 0.0, 0.7, 0.0, 0.3, 0.0, 0.7, 0.0, 0.2, 0.0, 0.2, 0.0, 
+
+L2_dTRSV_o_UN
+11.4385137035, -12.228712972, 6.48869547526, 3.95473442925, -2.9291273329, 1.00749782986, -0.137443033854, -0.249099392361, 0.473177083333, -0.799652777778, 0.902777777778, 0.0930555555556, -0.204166666667, -0.0208333333333, 0.01875, 0.04375, 0.00625, 
+
+L2_dTRSV_o_UN2
+11.4385137035, 0.0, -12.228712972, 0.0, 6.48869547526, 0.0, 3.95473442925, 0.0, -2.9291273329, 0.0, 1.00749782986, 0.0, -0.137443033854, 0.0, -0.249099392361, 0.0, 0.473177083333, 0.0, -0.799652777778, 0.0, 0.902777777778, 0.0, 0.0930555555556, 0.0, -0.204166666667, 0.0, -0.0208333333333, 0.0, 0.01875, 0.0, 0.04375, 0.0, 0.00625, 0.0, 
+
+L2_dTRSV_o_UT
+0.0291666666667, -0.0234375, 0.115104166667, -0.0166666666667, -0.06796875, 0.138888888889, -0.181076388889, -0.0510959201389, 0.11686062283, -0.0105824788411, 0.801871744792, -0.229576845522, -4.73293445728, -0.147588847596, 9.29135302634, 8.1630378001, -4.60693336769, 
+
+L2_dTRSV_o_UH
+0.0291666666667, -0.0234375, 0.115104166667, -0.0166666666667, -0.06796875, 0.138888888889, -0.181076388889, -0.0510959201389, 0.11686062283, -0.0105824788411, 0.801871744792, -0.229576845522, -4.73293445728, -0.147588847596, 9.29135302634, 8.1630378001, -4.60693336769, 
+
+L2_cTRSV_A_nn
+36.0, 36.0, 16.0, 8.0, 28.0, 16.0, 36.0, 16.0, 32.0, 8.0, 20.0, 36.0, 20.0, 24.0, 36.0, 16.0, 32.0, 8.0, 32.0, 16.0, 28.0, 20.0, 28.0, 24.0, 24.0, 16.0, 20.0, 16.0, 20.0, 20.0, 28.0, 4.0, 8.0, 4.0, 0.0, 0.0, 12.0, 32.0, 36.0, 8.0, 12.0, 24.0, 36.0, 36.0, 32.0, 12.0, 16.0, 20.0, 36.0, 20.0, 8.0, 4.0, 8.0, 16.0, 28.0, 24.0, 8.0, 20.0, 20.0, 4.0, 36.0, 36.0, 20.0, 32.0, 36.0, 32.0, 36.0, 20.0, 0.0, 0.0, 0.0, 0.0, 20.0, 8.0, 36.0, 28.0, 28.0, 24.0, 8.0, 8.0, 12.0, 8.0, 16.0, 8.0, 16.0, 4.0, 36.0, 32.0, 24.0, 4.0, 16.0, 4.0, 12.0, 24.0, 28.0, 24.0, 16.0, 8.0, 32.0, 20.0, 28.0, 36.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 16.0, 16.0, 36.0, 8.0, 20.0, 8.0, 20.0, 28.0, 20.0, 4.0, 12.0, 32.0, 32.0, 28.0, 16.0, 28.0, 24.0, 20.0, 16.0, 4.0, 20.0, 28.0, 12.0, 36.0, 4.0, 12.0, 16.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 36.0, 36.0, 32.0, 8.0, 20.0, 12.0, 24.0, 8.0, 16.0, 32.0, 20.0, 32.0, 36.0, 20.0, 20.0, 24.0, 16.0, 8.0, 16.0, 28.0, 12.0, 32.0, 32.0, 36.0, 8.0, 24.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 36.0, 28.0, 8.0, 8.0, 32.0, 20.0, 32.0, 8.0, 28.0, 16.0, 16.0, 36.0, 8.0, 20.0, 24.0, 8.0, 20.0, 12.0, 8.0, 16.0, 36.0, 12.0, 28.0, 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, 20.0, 28.0, 24.0, 4.0, 32.0, 28.0, 28.0, 12.0, 20.0, 36.0, 4.0, 28.0, 24.0, 24.0, 4.0, 4.0, 36.0, 20.0, 20.0, 24.0, 24.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, 20.0, 12.0, 8.0, 16.0, 24.0, 20.0, 8.0, 24.0, 28.0, 16.0, 4.0, 8.0, 24.0, 8.0, 36.0, 36.0, 36.0, 24.0, 4.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, 12.0, 32.0, 16.0, 36.0, 28.0, 12.0, 32.0, 32.0, 20.0, 16.0, 16.0, 8.0, 24.0, 28.0, 24.0, 24.0, 24.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 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, 8.0, 4.0, 32.0, 28.0, 12.0, 8.0, 28.0, 8.0, 20.0, 16.0, 8.0, 16.0, 20.0, 4.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, 24.0, 4.0, 12.0, 28.0, 4.0, 12.0, 28.0, 24.0, 28.0, 12.0, 28.0, 8.0, 20.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, 12.0, 32.0, 16.0, 16.0, 4.0, 8.0, 32.0, 36.0, 12.0, 20.0, 4.0, 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, 24.0, 8.0, 20.0, 8.0, 16.0, 16.0, 8.0, 24.0, 36.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, 24.0, 16.0, 36.0, 28.0, 8.0, 28.0, 28.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, 32.0, 20.0, 32.0, 32.0, 8.0, 12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 8.0, 12.0, 12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 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, 4.0, 
+
+L2_cTRSV_A_nn_pu
+36.0, 36.0, 16.0, 8.0, 28.0, 16.0, 36.0, 16.0, 32.0, 8.0, 20.0, 36.0, 20.0, 24.0, 36.0, 16.0, 32.0, 8.0, 32.0, 16.0, 28.0, 20.0, 28.0, 24.0, 24.0, 16.0, 20.0, 16.0, 20.0, 20.0, 28.0, 4.0, 8.0, 4.0, 12.0, 32.0, 36.0, 8.0, 12.0, 24.0, 36.0, 36.0, 32.0, 12.0, 16.0, 20.0, 36.0, 20.0, 8.0, 4.0, 8.0, 16.0, 28.0, 24.0, 8.0, 20.0, 20.0, 4.0, 36.0, 36.0, 20.0, 32.0, 36.0, 32.0, 36.0, 20.0, 20.0, 8.0, 36.0, 28.0, 28.0, 24.0, 8.0, 8.0, 12.0, 8.0, 16.0, 8.0, 16.0, 4.0, 36.0, 32.0, 24.0, 4.0, 16.0, 4.0, 12.0, 24.0, 28.0, 24.0, 16.0, 8.0, 32.0, 20.0, 28.0, 36.0, 4.0, 16.0, 16.0, 36.0, 8.0, 20.0, 8.0, 20.0, 28.0, 20.0, 4.0, 12.0, 32.0, 32.0, 28.0, 16.0, 28.0, 24.0, 20.0, 16.0, 4.0, 20.0, 28.0, 12.0, 36.0, 4.0, 12.0, 16.0, 36.0, 36.0, 32.0, 8.0, 20.0, 12.0, 24.0, 8.0, 16.0, 32.0, 20.0, 32.0, 36.0, 20.0, 20.0, 24.0, 16.0, 8.0, 16.0, 28.0, 12.0, 32.0, 32.0, 36.0, 8.0, 24.0, 36.0, 28.0, 8.0, 8.0, 32.0, 20.0, 32.0, 8.0, 28.0, 16.0, 16.0, 36.0, 8.0, 20.0, 24.0, 8.0, 20.0, 12.0, 8.0, 16.0, 36.0, 12.0, 28.0, 16.0, 20.0, 28.0, 24.0, 4.0, 32.0, 28.0, 28.0, 12.0, 20.0, 36.0, 4.0, 28.0, 24.0, 24.0, 4.0, 4.0, 36.0, 20.0, 20.0, 24.0, 24.0, 36.0, 20.0, 12.0, 8.0, 16.0, 24.0, 20.0, 8.0, 24.0, 28.0, 16.0, 4.0, 8.0, 24.0, 8.0, 36.0, 36.0, 36.0, 24.0, 4.0, 24.0, 12.0, 32.0, 16.0, 36.0, 28.0, 12.0, 32.0, 32.0, 20.0, 16.0, 16.0, 8.0, 24.0, 28.0, 24.0, 24.0, 24.0, 4.0, 20.0, 8.0, 4.0, 32.0, 28.0, 12.0, 8.0, 28.0, 8.0, 20.0, 16.0, 8.0, 16.0, 20.0, 4.0, 8.0, 24.0, 4.0, 12.0, 28.0, 4.0, 12.0, 28.0, 24.0, 28.0, 12.0, 28.0, 8.0, 20.0, 8.0, 12.0, 32.0, 16.0, 16.0, 4.0, 8.0, 32.0, 36.0, 12.0, 20.0, 4.0, 16.0, 24.0, 8.0, 20.0, 8.0, 16.0, 16.0, 8.0, 24.0, 36.0, 8.0, 24.0, 16.0, 36.0, 28.0, 8.0, 28.0, 28.0, 8.0, 32.0, 20.0, 32.0, 32.0, 8.0, 12.0, 8.0, 8.0, 12.0, 12.0, 20.0, 4.0, 
+
+L2_cTRSV_x_n1
+0.800000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.600000023842, 0.699999988079, 0.300000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.20000000298, 0.300000011921, 0.10000000149, 0.10000000149, 0.300000011921, 0.300000011921, 0.20000000298, 0.300000011921, 0.600000023842, 0.5, 0.899999976158, 0.800000011921, 0.699999988079, 0.600000023842, 0.10000000149, 0.10000000149, 0.10000000149, 0.300000011921, 0.40000000596, 0.300000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.20000000298, 
+
+L2_cTRSV_x_n2
+0.800000011921, 0.800000011921, 0.0, 0.0, 0.10000000149, 0.300000011921, 0.0, 0.0, 0.600000023842, 0.699999988079, 0.0, 0.0, 0.300000011921, 0.10000000149, 0.0, 0.0, 0.10000000149, 0.20000000298, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.0, 0.0, 0.10000000149, 0.10000000149, 0.0, 0.0, 0.300000011921, 0.300000011921, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.0, 0.0, 0.600000023842, 0.5, 0.0, 0.0, 0.899999976158, 0.800000011921, 0.0, 0.0, 0.699999988079, 0.600000023842, 0.0, 0.0, 0.10000000149, 0.10000000149, 0.0, 0.0, 0.10000000149, 0.300000011921, 0.0, 0.0, 0.40000000596, 0.300000011921, 0.0, 0.0, 0.699999988079, 0.899999976158, 0.0, 0.0, 0.10000000149, 0.20000000298, 0.0, 0.0, 
+
+L2_cTRSV_o_UN
+0.594933566964, -0.315019222695, -1.01289503455, -0.527617393149, -0.28430160669, 1.43833818036, 0.173852765488, -0.810668303673, -0.0911287027816, -0.107413567973, 0.0938391484999, 0.0905342581104, -0.0131405830986, 0.0756930302523, -0.0906741384626, 0.0651067764121, 0.206488087396, -0.27259336822, -0.151479130295, 0.291555146095, -0.158686981083, -0.0655027960141, 0.119051667585, -0.0182250461356, -0.0594643999837, -0.0214315033817, 0.0735765960864, -0.00521013472739, -0.0929667214656, -0.0266313723803, 0.0899038437682, -0.000480770169256, 0.00673076933107, 0.0086538462828, 
+
+L2_cTRSV_o_UN2
+0.594933566964, -0.315019222695, 0.0, 0.0, -1.01289503455, -0.527617393149, 0.0, 0.0, -0.28430160669, 1.43833818036, 0.0, 0.0, 0.173852765488, -0.810668303673, 0.0, 0.0, -0.0911287027816, -0.107413567973, 0.0, 0.0, 0.0938391484999, 0.0905342581104, 0.0, 0.0, -0.0131405830986, 0.0756930302523, 0.0, 0.0, -0.0906741384626, 0.0651067764121, 0.0, 0.0, 0.206488087396, -0.27259336822, 0.0, 0.0, -0.151479130295, 0.291555146095, 0.0, 0.0, -0.158686981083, -0.0655027960141, 0.0, 0.0, 0.119051667585, -0.0182250461356, 0.0, 0.0, -0.0594643999837, -0.0214315033817, 0.0, 0.0, 0.0735765960864, -0.00521013472739, 0.0, 0.0, -0.0929667214656, -0.0266313723803, 0.0, 0.0, 0.0899038437682, -0.000480770169256, 0.0, 0.0, 0.00673076933107, 0.0086538462828, 0.0, 0.0, 
+
+L2_cTRSV_o_UT
+0.0222222225534, 0.0, 0.000722983472129, 0.00825723003216, 0.00148139391917, 0.00147745634686, -0.0321927824925, 0.0121057846439, 0.0165590884117, -0.000246312854666, -0.00851089877641, -0.00377372562026, -0.00362477871118, -0.00282459746629, 0.026956984416, -0.00873253174881, -0.00990029188872, 0.0143110987186, 0.0553322087818, -0.00981568541087, 0.00107993786542, -0.0883967226031, -0.0165171394379, 0.0960778411503, -0.0103183345591, -0.110338024807, -0.0232084033053, 0.148210184476, 0.0698025092923, -0.17763135155, -0.0632964177877, 0.588402352205, 0.319569918938, -0.323324580596, 
+
+L2_cTRSV_o_UH
+0.0, 0.0222222225534, 0.000722983063878, -0.00270167424073, 0.00722852194437, 0.0119325034659, 0.0428804602116, -0.0478281182381, -0.0169457796429, 0.0319569268372, 0.00276812767431, 0.00201685861762, -0.00146435426717, -0.00046826879169, -0.0325393550607, 0.0189311969316, 0.0389615566629, -0.0325025624574, -0.0369859311847, 0.0925037321174, -0.157063281758, -0.0484729195251, 0.153439961314, 0.039218306506, -0.193450545686, -0.0687363086255, 0.264967311446, 0.0513555138895, -0.300406005324, 0.00917295898706, 0.905211268549, 0.167336111703, -0.630807531883, 0.314511320045, 
+
+L2_zTRSV_A_nn
+24.0, 16.0, 16.0, 20.0, 36.0, 36.0, 36.0, 4.0, 32.0, 36.0, 24.0, 24.0, 32.0, 4.0, 12.0, 36.0, 28.0, 4.0, 36.0, 32.0, 28.0, 16.0, 24.0, 36.0, 20.0, 12.0, 24.0, 12.0, 20.0, 16.0, 8.0, 8.0, 24.0, 36.0, 0.0, 0.0, 24.0, 4.0, 12.0, 16.0, 32.0, 8.0, 32.0, 4.0, 4.0, 4.0, 28.0, 36.0, 8.0, 16.0, 20.0, 36.0, 16.0, 32.0, 16.0, 4.0, 24.0, 12.0, 12.0, 36.0, 8.0, 20.0, 4.0, 36.0, 28.0, 20.0, 24.0, 24.0, 0.0, 0.0, 0.0, 0.0, 36.0, 8.0, 16.0, 4.0, 20.0, 28.0, 20.0, 24.0, 36.0, 20.0, 12.0, 4.0, 24.0, 16.0, 4.0, 24.0, 16.0, 24.0, 8.0, 32.0, 32.0, 24.0, 32.0, 32.0, 8.0, 12.0, 4.0, 12.0, 32.0, 20.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 28.0, 32.0, 4.0, 12.0, 12.0, 32.0, 12.0, 4.0, 36.0, 16.0, 24.0, 24.0, 36.0, 24.0, 20.0, 4.0, 16.0, 12.0, 4.0, 8.0, 20.0, 36.0, 4.0, 8.0, 32.0, 24.0, 12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 20.0, 36.0, 16.0, 4.0, 20.0, 36.0, 24.0, 20.0, 32.0, 16.0, 12.0, 8.0, 8.0, 8.0, 12.0, 24.0, 28.0, 28.0, 12.0, 12.0, 8.0, 8.0, 8.0, 32.0, 16.0, 20.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 16.0, 32.0, 32.0, 16.0, 36.0, 32.0, 8.0, 12.0, 28.0, 4.0, 12.0, 8.0, 8.0, 12.0, 8.0, 36.0, 12.0, 32.0, 28.0, 4.0, 16.0, 12.0, 20.0, 12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 36.0, 36.0, 12.0, 32.0, 20.0, 4.0, 20.0, 36.0, 12.0, 12.0, 16.0, 4.0, 16.0, 8.0, 12.0, 12.0, 16.0, 8.0, 4.0, 12.0, 16.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, 12.0, 36.0, 16.0, 16.0, 32.0, 12.0, 12.0, 36.0, 24.0, 8.0, 12.0, 8.0, 36.0, 4.0, 12.0, 28.0, 24.0, 8.0, 12.0, 28.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 36.0, 4.0, 12.0, 12.0, 32.0, 32.0, 4.0, 8.0, 32.0, 8.0, 20.0, 8.0, 16.0, 4.0, 24.0, 20.0, 28.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, 28.0, 28.0, 28.0, 16.0, 20.0, 20.0, 4.0, 32.0, 20.0, 28.0, 36.0, 24.0, 8.0, 20.0, 16.0, 28.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 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, 28.0, 28.0, 28.0, 32.0, 24.0, 24.0, 12.0, 12.0, 4.0, 4.0, 4.0, 36.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, 4.0, 24.0, 36.0, 12.0, 32.0, 36.0, 28.0, 28.0, 4.0, 16.0, 36.0, 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, 32.0, 24.0, 36.0, 32.0, 28.0, 12.0, 20.0, 28.0, 36.0, 12.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 28.0, 28.0, 12.0, 8.0, 8.0, 12.0, 36.0, 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, 24.0, 4.0, 4.0, 16.0, 32.0, 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, 24.0, 32.0, 20.0, 28.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 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.0, 4.0, 
+
+L2_zTRSV_A_nn_pu
+24.0, 16.0, 16.0, 20.0, 36.0, 36.0, 36.0, 4.0, 32.0, 36.0, 24.0, 24.0, 32.0, 4.0, 12.0, 36.0, 28.0, 4.0, 36.0, 32.0, 28.0, 16.0, 24.0, 36.0, 20.0, 12.0, 24.0, 12.0, 20.0, 16.0, 8.0, 8.0, 24.0, 36.0, 24.0, 4.0, 12.0, 16.0, 32.0, 8.0, 32.0, 4.0, 4.0, 4.0, 28.0, 36.0, 8.0, 16.0, 20.0, 36.0, 16.0, 32.0, 16.0, 4.0, 24.0, 12.0, 12.0, 36.0, 8.0, 20.0, 4.0, 36.0, 28.0, 20.0, 24.0, 24.0, 36.0, 8.0, 16.0, 4.0, 20.0, 28.0, 20.0, 24.0, 36.0, 20.0, 12.0, 4.0, 24.0, 16.0, 4.0, 24.0, 16.0, 24.0, 8.0, 32.0, 32.0, 24.0, 32.0, 32.0, 8.0, 12.0, 4.0, 12.0, 32.0, 20.0, 8.0, 28.0, 32.0, 4.0, 12.0, 12.0, 32.0, 12.0, 4.0, 36.0, 16.0, 24.0, 24.0, 36.0, 24.0, 20.0, 4.0, 16.0, 12.0, 4.0, 8.0, 20.0, 36.0, 4.0, 8.0, 32.0, 24.0, 12.0, 20.0, 36.0, 16.0, 4.0, 20.0, 36.0, 24.0, 20.0, 32.0, 16.0, 12.0, 8.0, 8.0, 8.0, 12.0, 24.0, 28.0, 28.0, 12.0, 12.0, 8.0, 8.0, 8.0, 32.0, 16.0, 20.0, 16.0, 32.0, 32.0, 16.0, 36.0, 32.0, 8.0, 12.0, 28.0, 4.0, 12.0, 8.0, 8.0, 12.0, 8.0, 36.0, 12.0, 32.0, 28.0, 4.0, 16.0, 12.0, 20.0, 12.0, 36.0, 36.0, 12.0, 32.0, 20.0, 4.0, 20.0, 36.0, 12.0, 12.0, 16.0, 4.0, 16.0, 8.0, 12.0, 12.0, 16.0, 8.0, 4.0, 12.0, 16.0, 24.0, 12.0, 36.0, 16.0, 16.0, 32.0, 12.0, 12.0, 36.0, 24.0, 8.0, 12.0, 8.0, 36.0, 4.0, 12.0, 28.0, 24.0, 8.0, 12.0, 28.0, 36.0, 4.0, 12.0, 12.0, 32.0, 32.0, 4.0, 8.0, 32.0, 8.0, 20.0, 8.0, 16.0, 4.0, 24.0, 20.0, 28.0, 20.0, 28.0, 28.0, 28.0, 16.0, 20.0, 20.0, 4.0, 32.0, 20.0, 28.0, 36.0, 24.0, 8.0, 20.0, 16.0, 28.0, 4.0, 28.0, 28.0, 28.0, 32.0, 24.0, 24.0, 12.0, 12.0, 4.0, 4.0, 4.0, 36.0, 8.0, 4.0, 24.0, 36.0, 12.0, 32.0, 36.0, 28.0, 28.0, 4.0, 16.0, 36.0, 32.0, 32.0, 24.0, 36.0, 32.0, 28.0, 12.0, 20.0, 28.0, 36.0, 12.0, 28.0, 28.0, 12.0, 8.0, 8.0, 12.0, 36.0, 32.0, 24.0, 4.0, 4.0, 16.0, 32.0, 32.0, 24.0, 32.0, 20.0, 28.0, 24.0, 4.0, 
+
+L2_zTRSV_x_n1
+0.5, 0.2, 0.5, 0.5, 0.8, 0.6, 0.5, 0.4, 0.7, 0.8, 0.8, 0.6, 0.6, 0.9, 0.6, 0.7, 0.3, 0.8, 0.5, 0.7, 0.6, 0.9, 0.9, 0.3, 0.3, 0.1, 0.6, 0.3, 0.7, 0.8, 0.9, 0.2, 0.5, 0.2, 
+
+L2_zTRSV_x_n2
+0.5, 0.2, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.8, 0.6, 0.0, 0.0, 0.5, 0.4, 0.0, 0.0, 0.7, 0.8, 0.0, 0.0, 0.8, 0.6, 0.0, 0.0, 0.6, 0.9, 0.0, 0.0, 0.6, 0.7, 0.0, 0.0, 0.3, 0.8, 0.0, 0.0, 0.5, 0.7, 0.0, 0.0, 0.6, 0.9, 0.0, 0.0, 0.9, 0.3, 0.0, 0.0, 0.3, 0.1, 0.0, 0.0, 0.6, 0.3, 0.0, 0.0, 0.7, 0.8, 0.0, 0.0, 0.9, 0.2, 0.0, 0.0, 0.5, 0.2, 0.0, 0.0, 
+
+L2_zTRSV_o_UN
+-0.117782452318, -0.112026835825, 0.00381797959204, 0.00792418146995, 0.0447425590052, -0.0727856782286, -0.0733041598802, 0.0803069249097, 0.0157904572008, 0.0210530076009, 0.0108108011673, 0.062824650788, 0.0250326465768, 0.00144442830828, 0.0106845239065, -0.0334233841644, -0.0506804969493, -0.0410505909674, -0.00931030768772, 0.0289467583966, 0.060236627361, 0.00219814254409, -0.0175502974016, -0.0318983095064, -0.00268201502661, 0.0184899561724, -0.00974741730147, -0.00401925284358, -0.00567896274653, 0.00306135865595, -0.001, -0.0195, 0.0216216216216, 0.00472972972973, 
+
+L2_zTRSV_o_UN2
+-0.117782452318, -0.112026835825, 0.0, 0.0, 0.00381797959204, 0.00792418146995, 0.0, 0.0, 0.0447425590052, -0.0727856782286, 0.0, 0.0, -0.0733041598802, 0.0803069249097, 0.0, 0.0, 0.0157904572008, 0.0210530076009, 0.0, 0.0, 0.0108108011673, 0.062824650788, 0.0, 0.0, 0.0250326465768, 0.00144442830828, 0.0, 0.0, 0.0106845239065, -0.0334233841644, 0.0, 0.0, -0.0506804969493, -0.0410505909674, 0.0, 0.0, -0.00931030768772, 0.0289467583966, 0.0, 0.0, 0.060236627361, 0.00219814254409, 0.0, 0.0, -0.0175502974016, -0.0318983095064, 0.0, 0.0, -0.00268201502661, 0.0184899561724, 0.0, 0.0, -0.00974741730147, -0.00401925284358, 0.0, 0.0, -0.00567896274653, 0.00306135865595, 0.0, 0.0, -0.001, -0.0195, 0.0, 0.0, 0.0216216216216, 0.00472972972973, 0.0, 0.0, 
+
+L2_zTRSV_o_UT
+0.0182692307692, -0.00384615384615, 0.00662681912682, 0.00706860706861, 0.000343035343035, -0.0031340956341, 0.00448780057271, 0.013661201114, -0.0128687777037, 0.00369625975758, 0.00719757629545, -0.012641374593, 0.0108229274267, 0.0115987885563, -0.00265416786525, -0.020885148029, -0.00172173509619, 0.0113541605254, 0.00109700943918, -0.00858587046508, 0.0101682777897, 0.0186443889184, -0.0281381989712, -0.016837557351, 0.0012046368883, -0.0197832517297, 0.0268252893523, 0.0439875141638, -0.0140740190926, 0.0515215838321, 0.0289779557733, -0.027294391418, 0.00333242458548, -0.14092609678, 
+
+L2_zTRSV_o_UH
+0.0105769230769, 0.0153846153846, -0.00220893970894, 0.0190228690229, -0.0118790509967, 0.00189647792589, 0.0284337742079, -0.00245699511515, -0.00849250140177, -0.0206510062739, -0.0159887222502, 0.0145098488685, 0.0130575854605, -0.00530441170702, -0.0320986394862, 0.0241269063715, -0.0106011857456, -0.00358290866981, 0.000217611862516, -0.00178943302941, 0.0323917365637, -0.0140144534922, -0.00553998052406, 0.0178351801378, -0.000818170373114, -0.0236781122664, 0.0264375795928, 0.00865952061921, -0.0685576112938, -0.0252999785684, 0.0647926233732, 0.0362570666294, -0.0759178018159, -0.0275969662468, 
+
+L2_sTBSV_A_nn
+16.0, 20.0, 16.0, 20.0, 24.0, 36.0, 28.0, 8.0, 12.0, 28.0, 32.0, 24.0, 28.0, 4.0, 4.0, 4.0, 20.0, 28.0, 12.0, 4.0, 20.0, 24.0, 8.0, 32.0, 20.0, 12.0, 36.0, 24.0, 32.0, 32.0, 20.0, 8.0, 12.0, 12.0, 12.0, 8.0, 12.0, 28.0, 36.0, 4.0, 20.0, 8.0, 8.0, 24.0, 20.0, 36.0, 8.0, 0.0, 20.0, 0.0, 0.0, 
+
+L2_sTBSV_x_n1
+0.2, 0.6, 0.1, 0.6, 0.2, 0.9, 0.5, 0.2, 0.2, 0.6, 0.3, 0.3, 0.1, 0.3, 0.2, 0.7, 0.7, 
+
+L2_sTBSV_x_n2
+0.2, 0.0, 0.6, 0.0, 0.1, 0.0, 0.6, 0.0, 0.2, 0.0, 0.9, 0.0, 0.5, 0.0, 0.2, 0.0, 0.2, 0.0, 0.6, 0.0, 0.3, 0.0, 0.3, 0.0, 0.1, 0.0, 0.3, 0.0, 0.2, 0.0, 0.7, 0.0, 0.7, 0.0, 
+
+L2_sTBSV_o_UN
+10.3602, -6.72359, -1.94319, 5.04746, 1.17748, -7.43367, -0.758667, 1.636, 0.153, -1.259, 0.340222, 0.622778, -0.957222, 0.539167, -0.0975, 0.0116667, 0.035, 
+
+L2_sTBSV_o_UN2
+10.3602, 0.0, -6.72359, 0.0, -1.94319, 0.0, 5.04746, 0.0, 1.17748, 0.0, -7.43367, 0.0, -0.758667, 0.0, 1.636, 0.0, 0.153, 0.0, -1.259, 0.0, 0.340222, 0.0, 0.622778, 0.0, -0.957222, 0.0, 0.539167, 0.0, -0.0975, 0.0, 0.0116667, 0.0, 0.035, 0.0, 
+
+L2_sTBSV_o_UT
+0.0125, 0.0175, -0.0185714, 0.0042347, 0.0102624, 0.189329, -0.277303, -0.166334, 0.353837, 0.0698601, -0.733682, 0.327828, 0.414188, -3.47997, 6.86108, -3.78128, -5.31357, 
+
+L2_sTBSV_o_UH
+0.0125, 0.0175, -0.0185714, 0.0042347, 0.0102624, 0.189329, -0.277303, -0.166334, 0.353837, 0.0698601, -0.733682, 0.327828, 0.414188, -3.47997, 6.86108, -3.78128, -5.31357, 
+
+L2_dTBSV_A_nn
+8.0, 12.0, 12.0, 36.0, 36.0, 36.0, 8.0, 28.0, 16.0, 28.0, 12.0, 12.0, 36.0, 36.0, 8.0, 32.0, 12.0, 12.0, 24.0, 32.0, 28.0, 16.0, 8.0, 8.0, 16.0, 12.0, 16.0, 16.0, 12.0, 4.0, 8.0, 20.0, 20.0, 12.0, 36.0, 32.0, 8.0, 32.0, 20.0, 36.0, 12.0, 12.0, 36.0, 8.0, 12.0, 32.0, 24.0, 0.0, 12.0, 0.0, 0.0, 
+
+L2_dTBSV_x_n1
+0.6, 0.8, 0.6, 0.1, 0.8, 0.8, 0.5, 0.7, 0.3, 0.8, 0.5, 0.2, 0.3, 0.2, 0.7, 0.6, 0.3, 
+
+L2_dTBSV_x_n2
+0.6, 0.0, 0.8, 0.0, 0.6, 0.0, 0.1, 0.0, 0.8, 0.0, 0.8, 0.0, 0.5, 0.0, 0.7, 0.0, 0.3, 0.0, 0.8, 0.0, 0.5, 0.0, 0.2, 0.0, 0.3, 0.0, 0.2, 0.0, 0.7, 0.0, 0.6, 0.0, 0.3, 0.0, 
+
+L2_dTBSV_o_UN
+0.0315060534245, -0.036767906644, 0.0657638710277, -0.00677374216147, 0.0164721132687, 0.00766661844136, -0.00862429269547, 0.0548466435185, -0.0374324845679, 0.0152391975309, 0.0447530864198, 0.00478395061728, 0.00231481481481, 0.00185185185185, 0.0111111111111, 0.0, 0.025, 
+
+L2_dTBSV_o_UN2
+0.0315060534245, 0.0, -0.036767906644, 0.0, 0.0657638710277, 0.0, -0.00677374216147, 0.0, 0.0164721132687, 0.0, 0.00766661844136, 0.0, -0.00862429269547, 0.0, 0.0548466435185, 0.0, -0.0374324845679, 0.0, 0.0152391975309, 0.0, 0.0447530864198, 0.0, 0.00478395061728, 0.0, 0.00231481481481, 0.0, 0.00185185185185, 0.0, 0.0111111111111, 0.0, 0.0, 0.0, 0.025, 0.0, 
+
+L2_dTBSV_o_UT
+0.075, -0.00277777777778, -0.025, 0.0321428571429, 0.022619047619, -0.0125, 0.0195436507937, 0.0140376984127, -0.0224702380952, 0.0598338293651, 0.0176897321429, -0.0327608300265, 0.140699404762, -0.0903898442093, -0.0285919434646, 0.0597941774446, -0.0659964114247, 
+
+L2_dTBSV_o_UH
+0.075, -0.00277777777778, -0.025, 0.0321428571429, 0.022619047619, -0.0125, 0.0195436507937, 0.0140376984127, -0.0224702380952, 0.0598338293651, 0.0176897321429, -0.0327608300265, 0.140699404762, -0.0903898442093, -0.0285919434646, 0.0597941774446, -0.0659964114247, 
+
+L2_cTBSV_A_nn
+12.0, 28.0, 28.0, 32.0, 16.0, 20.0, 20.0, 32.0, 4.0, 16.0, 28.0, 28.0, 8.0, 28.0, 20.0, 16.0, 32.0, 28.0, 4.0, 8.0, 32.0, 4.0, 16.0, 24.0, 28.0, 8.0, 32.0, 8.0, 8.0, 20.0, 20.0, 4.0, 16.0, 12.0, 32.0, 16.0, 8.0, 16.0, 8.0, 20.0, 24.0, 28.0, 4.0, 32.0, 16.0, 32.0, 8.0, 24.0, 28.0, 28.0, 32.0, 32.0, 20.0, 24.0, 28.0, 24.0, 32.0, 24.0, 36.0, 36.0, 32.0, 32.0, 20.0, 20.0, 12.0, 8.0, 32.0, 36.0, 16.0, 16.0, 24.0, 4.0, 16.0, 8.0, 36.0, 8.0, 32.0, 32.0, 28.0, 28.0, 28.0, 20.0, 36.0, 32.0, 28.0, 8.0, 24.0, 20.0, 12.0, 20.0, 32.0, 12.0, 16.0, 16.0, 0.0, 0.0, 8.0, 36.0, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cTBSV_x_n1
+0.600000023842, 0.10000000149, 0.699999988079, 0.10000000149, 0.800000011921, 0.899999976158, 0.800000011921, 0.600000023842, 0.800000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.899999976158, 0.600000023842, 0.800000011921, 0.300000011921, 0.800000011921, 0.699999988079, 0.40000000596, 0.40000000596, 0.600000023842, 0.5, 0.899999976158, 0.699999988079, 0.40000000596, 0.800000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.600000023842, 0.800000011921, 0.300000011921, 0.699999988079, 0.300000011921, 
+
+L2_cTBSV_x_n2
+0.600000023842, 0.10000000149, 0.0, 0.0, 0.699999988079, 0.10000000149, 0.0, 0.0, 0.800000011921, 0.899999976158, 0.0, 0.0, 0.800000011921, 0.600000023842, 0.0, 0.0, 0.800000011921, 0.899999976158, 0.0, 0.0, 0.40000000596, 0.800000011921, 0.0, 0.0, 0.899999976158, 0.600000023842, 0.0, 0.0, 0.800000011921, 0.300000011921, 0.0, 0.0, 0.800000011921, 0.699999988079, 0.0, 0.0, 0.40000000596, 0.40000000596, 0.0, 0.0, 0.600000023842, 0.5, 0.0, 0.0, 0.899999976158, 0.699999988079, 0.0, 0.0, 0.40000000596, 0.800000011921, 0.0, 0.0, 0.600000023842, 0.899999976158, 0.0, 0.0, 0.300000011921, 0.600000023842, 0.0, 0.0, 0.800000011921, 0.300000011921, 0.0, 0.0, 0.699999988079, 0.300000011921, 0.0, 0.0, 
+
+L2_cTBSV_o_UN
+0.198946958765, 0.117478549396, -0.0353376512917, -0.104767313443, -0.106854235755, -0.0424301939902, 0.0537191514755, 0.132192979229, 0.03795553912, -0.0104612804481, 0.00236279684018, -0.014518338199, 0.0482618685686, 0.0462148240025, -0.0010443325467, -0.00690483429921, 0.0102385856959, -0.0313526474763, 0.0127657172257, 0.0285835493187, 0.00211550689121, -0.00413774884384, -0.00088219272563, -0.0164811625734, 0.0401482120582, 0.0492327626666, 0.0183150482147, -0.0101749858294, -0.010599713923, 0.00781437695206, 0.0131385983117, 0.00680096686655, 0.0120588237748, -0.0167647054967, 
+
+L2_cTBSV_o_UN2
+0.198946958765, 0.117478549396, 0.0, 0.0, -0.0353376512917, -0.104767313443, 0.0, 0.0, -0.106854235755, -0.0424301939902, 0.0, 0.0, 0.0537191514755, 0.132192979229, 0.0, 0.0, 0.03795553912, -0.0104612804481, 0.0, 0.0, 0.00236279684018, -0.014518338199, 0.0, 0.0, 0.0482618685686, 0.0462148240025, 0.0, 0.0, -0.0010443325467, -0.00690483429921, 0.0, 0.0, 0.0102385856959, -0.0313526474763, 0.0, 0.0, 0.0127657172257, 0.0285835493187, 0.0, 0.0, 0.00211550689121, -0.00413774884384, 0.0, 0.0, -0.00088219272563, -0.0164811625734, 0.0, 0.0, 0.0401482120582, 0.0492327626666, 0.0, 0.0, 0.0183150482147, -0.0101749858294, 0.0, 0.0, -0.010599713923, 0.00781437695206, 0.0, 0.0, 0.0131385983117, 0.00680096686655, 0.0, 0.0, 0.0120588237748, -0.0167647054967, 0.0, 0.0, 
+
+L2_cTBSV_o_UT
+0.0107758624222, -0.0168103455277, 0.00311410265979, 0.00631053968203, 0.032587010556, -0.00425698008703, -0.00153183508691, -0.0219719620473, -0.00537692413934, 0.0312868772269, 0.0175754337602, 0.00799245167891, 0.0405093376863, -0.066211293269, -0.0208558827875, 0.0374816149145, 0.0130260264227, 0.0306344015019, 0.0277366008263, -0.0522187085669, -0.00759542985136, 0.0257206670428, 0.00081570054013, 0.0371714344833, 0.0625381443266, -0.0347489917981, -0.0186602658002, 0.0456345978187, -0.056762713099, -0.0264183776856, 0.113694688836, -0.0106486857358, -0.00394579174857, 0.0306984074336, 
+
+L2_cTBSV_o_UH
+0.00474137957368, 0.0193965524628, 0.00579717127785, -0.00529349201093, -0.0226106221883, 0.0206642519306, 0.0318257100359, 0.0975223206475, 0.0166534523774, -0.116233475302, -0.135770263175, 0.16565388492, 0.202736408524, 0.103376761671, 0.116803981872, -0.0519517548223, -0.279127916407, 0.0231768208681, 0.290144026964, 0.0324505237072, -0.0578053165319, -0.0808542703641, -0.271488281928, 0.0207614697672, 0.371811030669, -0.0246061911088, -0.166638524348, -0.0532069993725, -0.275700502482, 0.329884735584, 0.403460613734, -0.36583428527, -0.101786598743, -0.0660282544249, 
+
+L2_zTBSV_A_nn
+16.0, 36.0, 20.0, 28.0, 24.0, 28.0, 32.0, 36.0, 8.0, 36.0, 4.0, 32.0, 12.0, 24.0, 28.0, 4.0, 28.0, 4.0, 12.0, 4.0, 4.0, 28.0, 8.0, 24.0, 24.0, 24.0, 20.0, 4.0, 4.0, 36.0, 16.0, 32.0, 36.0, 24.0, 12.0, 12.0, 12.0, 32.0, 12.0, 16.0, 24.0, 4.0, 4.0, 20.0, 36.0, 20.0, 28.0, 12.0, 8.0, 24.0, 4.0, 36.0, 16.0, 24.0, 8.0, 20.0, 12.0, 4.0, 16.0, 16.0, 16.0, 4.0, 4.0, 36.0, 32.0, 8.0, 32.0, 24.0, 28.0, 20.0, 8.0, 28.0, 32.0, 36.0, 36.0, 12.0, 4.0, 20.0, 20.0, 4.0, 24.0, 16.0, 8.0, 12.0, 24.0, 24.0, 8.0, 36.0, 28.0, 24.0, 8.0, 12.0, 32.0, 36.0, 0.0, 0.0, 20.0, 20.0, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zTBSV_x_n1
+0.4, 0.9, 0.5, 0.3, 0.8, 0.4, 0.5, 0.7, 0.4, 0.7, 0.5, 0.9, 0.2, 0.3, 0.3, 0.3, 0.4, 0.5, 0.3, 0.4, 0.9, 0.1, 0.9, 0.4, 0.9, 0.1, 0.8, 0.3, 0.3, 0.1, 0.1, 0.1, 0.6, 0.6, 
+
+L2_zTBSV_x_n2
+0.4, 0.9, 0.0, 0.0, 0.5, 0.3, 0.0, 0.0, 0.8, 0.4, 0.0, 0.0, 0.5, 0.7, 0.0, 0.0, 0.4, 0.7, 0.0, 0.0, 0.5, 0.9, 0.0, 0.0, 0.2, 0.3, 0.0, 0.0, 0.3, 0.3, 0.0, 0.0, 0.4, 0.5, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.9, 0.1, 0.0, 0.0, 0.9, 0.4, 0.0, 0.0, 0.9, 0.1, 0.0, 0.0, 0.8, 0.3, 0.0, 0.0, 0.3, 0.1, 0.0, 0.0, 0.1, 0.1, 0.0, 0.0, 0.6, 0.6, 0.0, 0.0, 
+
+L2_zTBSV_o_UN
+-0.0303491976507, 0.0174194805318, 0.00198090085122, -0.0263601890476, 0.0579679317513, 0.0234373289583, -0.0374976911197, -0.000551110000482, 0.0544761245615, -0.047320034403, -0.0254179925622, 0.0163230694833, 0.00384671971049, 0.0412456268004, 0.0898117521034, -0.100224851071, -0.0526903223032, -0.0142321284972, -0.00753561498054, 0.0200448147837, 0.0833845913799, 0.00426859064377, -0.00677397469904, 0.00712349520506, -0.00456335441747, -0.00156124600422, 0.0285650887574, -0.0412771203156, 0.0649358974359, 0.0396794871795, -0.0896153846154, 0.0119230769231, 0.03, 0.0, 
+
+L2_zTBSV_o_UN2
+-0.0303491976507, 0.0174194805318, 0.0, 0.0, 0.00198090085122, -0.0263601890476, 0.0, 0.0, 0.0579679317513, 0.0234373289583, 0.0, 0.0, -0.0374976911197, -0.000551110000482, 0.0, 0.0, 0.0544761245615, -0.047320034403, 0.0, 0.0, -0.0254179925622, 0.0163230694833, 0.0, 0.0, 0.00384671971049, 0.0412456268004, 0.0, 0.0, 0.0898117521034, -0.100224851071, 0.0, 0.0, -0.0526903223032, -0.0142321284972, 0.0, 0.0, -0.00753561498054, 0.0200448147837, 0.0, 0.0, 0.0833845913799, 0.00426859064377, 0.0, 0.0, -0.00677397469904, 0.00712349520506, 0.0, 0.0, -0.00456335441747, -0.00156124600422, 0.0, 0.0, 0.0285650887574, -0.0412771203156, 0.0, 0.0, 0.0649358974359, 0.0396794871795, 0.0, 0.0, -0.0896153846154, 0.0119230769231, 0.0, 0.0, 0.03, 0.0, 0.0, 0.0, 
+
+L2_zTBSV_o_UT
+0.025, -1.73472347598e-18, -0.00620689655172, -0.00551724137931, -0.000229885057471, -0.00224137931034, 0.0505402298851, 0.065183908046, 0.0230890804598, -0.061096743295, 0.0193025862069, -0.0201588122605, -0.034269003569, 0.0893536136042, 0.00575986645551, -0.0822154806532, 0.0467456690144, 0.0269066507293, 0.0351707871565, 0.0173785787823, -0.000300785763599, -0.112526588686, -0.0683864158642, 0.0519193364986, 0.0969933562886, 0.00392134978096, -0.0262017626546, 0.0299591567626, -0.0220146187989, -0.0677913847312, 0.0257368831154, 0.150095331872, 0.0366549748027, -0.171808414224, 
+
+L2_zTBSV_o_UH
+-0.0167525773196, 0.0185567010309, 0.0127337362247, -0.00255599004621, 0.0123960184856, 0.0218278232018, -0.00666844412845, 0.0441195639294, -0.0212142532686, -0.0305804893945, -0.0223302770865, 0.0124490460955, 0.0557413364971, 0.0381866081917, -0.0234870964854, -0.0383679305599, -0.0203951922942, 0.028563213097, -0.00669972139988, 0.0262478368596, 0.0478399123453, -0.0623068314466, 0.0251137801358, 0.0764698112914, -0.0456189069472, -0.0251444330777, 0.0121206191156, 0.0398841268684, 0.0319044363813, -0.0295576280198, -0.062839541545, 0.069665081223, 0.0554291824065, -0.059480119446, 
+
+L2_sGER_A_mn
+0.7, 0.6, 0.2, 0.9, 0.8, 0.5, 0.6, 0.3, 0.2, 0.7, 0.2, 0.8, 0.9, 0.3, 0.1, 0.8, 0.4, 0.7, 0.5, 0.6, 0.3, 0.7, 0.2, 0.5, 0.1, 0.1, 0.5, 0.9, 0.8, 0.6, 0.4, 0.4, 0.8, 0.8, 0.1, 0.5, 0.4, 0.6, 0.1, 0.5, 0.3, 0.7, 0.2, 0.4, 0.2, 0.2, 0.5, 0.6, 0.2, 0.4, 0.9, 0.7, 0.2, 0.4, 0.9, 0.2, 0.4, 0.9, 0.5, 0.6, 0.9, 0.4, 0.5, 0.8, 0.6, 0.8, 0.6, 0.9, 0.6, 0.9, 0.8, 0.7, 0.6, 0.9, 0.9, 0.8, 0.5, 0.4, 0.5, 0.9, 0.7, 0.3, 0.7, 0.6, 0.8, 0.2, 0.3, 0.7, 0.3, 0.9, 0.3, 0.2, 0.6, 0.9, 0.3, 0.8, 0.8, 0.8, 0.4, 0.6, 0.7, 0.2, 0.2, 0.3, 0.1, 0.5, 0.8, 0.9, 0.4, 0.2, 0.8, 0.8, 0.2, 0.3, 0.8, 0.8, 0.8, 0.5, 0.3, 0.2, 0.8, 0.4, 0.8, 0.8, 0.7, 0.6, 0.2, 0.4, 0.9, 0.8, 0.7, 0.7, 0.6, 0.1, 0.4, 0.8, 0.3, 0.9, 0.8, 0.4, 0.5, 0.8, 0.7, 0.1, 0.4, 0.4, 0.9, 0.4, 0.7, 0.1, 0.5, 0.2, 0.3, 0.6, 0.2, 0.4, 0.4, 0.7, 0.9, 0.3, 0.6, 0.2, 0.5, 0.1, 0.8, 0.1, 0.1, 0.7, 0.2, 0.8, 
+
+L2_sGER_x_m1
+0.5, 0.3, 0.3, 0.4, 0.9, 0.7, 0.4, 0.1, 0.9, 0.7, 
+
+L2_sGER_x_m2
+0.5, 0.0, 0.3, 0.0, 0.3, 0.0, 0.4, 0.0, 0.9, 0.0, 0.7, 0.0, 0.4, 0.0, 0.1, 0.0, 0.9, 0.0, 0.7, 0.0, 
+
+L2_sGER_y_n1
+0.6, 0.2, 0.5, 0.4, 0.3, 0.3, 0.1, 0.4, 0.7, 0.2, 0.2, 0.7, 0.1, 0.2, 0.4, 0.9, 0.2, 
+
+L2_sGER_y_n2
+0.6, 0.0, 0.0, 0.2, 0.0, 0.0, 0.5, 0.0, 0.0, 0.4, 0.0, 0.0, 0.3, 0.0, 0.0, 0.3, 0.0, 0.0, 0.1, 0.0, 0.0, 0.4, 0.0, 0.0, 0.7, 0.0, 0.0, 0.2, 0.0, 0.0, 0.2, 0.0, 0.0, 0.7, 0.0, 0.0, 0.1, 0.0, 0.0, 0.2, 0.0, 0.0, 0.4, 0.0, 0.0, 0.9, 0.0, 0.0, 0.2, 0.0, 0.0, 
+
+L2_sGER_o_N
+1.0, 0.700000025332, 0.45000000298, 1.09999997914, 0.950000017881, 0.65000000596, 0.650000024587, 0.500000014901, 0.54999999702, 0.799999989569, 0.30000000447, 1.15000000596, 0.949999976903, 0.400000013411, 0.30000000447, 1.25, 0.500000007451, 0.880000002384, 0.560000003278, 0.750000029802, 0.420000018477, 0.789999995232, 0.290000010133, 0.530000001639, 0.220000008047, 0.310000006258, 0.560000003278, 0.959999979436, 1.01000001669, 0.630000025481, 0.460000009239, 0.520000012517, 1.0700000155, 0.860000015199, 0.280000015795, 0.560000003278, 0.550000011921, 0.720000030398, 0.190000008643, 0.590000007153, 0.33000001356, 0.819999994636, 0.410000007749, 0.460000009239, 0.260000006258, 0.410000007749, 0.530000001639, 0.66000002712, 0.320000009537, 0.670000009537, 0.959999979436, 0.940000001192, 0.280000005364, 0.600000008941, 1.05999998093, 0.320000009537, 0.520000012517, 0.93999997735, 0.660000004768, 0.880000023246, 0.979999978542, 0.480000008345, 0.779999999404, 0.840000013113, 0.680000026226, 0.960000016689, 0.96000001967, 0.979999978542, 1.14000003099, 1.07999997407, 1.25, 1.05999998391, 0.870000027418, 1.16999997973, 0.989999975115, 1.16000000775, 1.12999997258, 0.580000003874, 0.679999997914, 1.52999994874, 0.789999987036, 0.480000009835, 1.05999998391, 1.40999998093, 0.980000009835, 0.620000012517, 0.440000011623, 1.04999998212, 0.580000011325, 1.10999998093, 0.510000016689, 0.270000002831, 0.880000023246, 1.38999995947, 0.440000011623, 0.940000011623, 1.28999999523, 0.870000011772, 0.540000005662, 0.880000023246, 1.32999996066, 0.340000002682, 0.440000016093, 0.380000014305, 0.30000000447, 0.660000004768, 0.920000018477, 1.01999998271, 0.440000007153, 0.360000007749, 1.08000001132, 0.880000014305, 0.280000005364, 0.580000011325, 0.840000013113, 0.880000014305, 0.960000016689, 0.859999995828, 0.380000014305, 0.260000006258, 0.820000012517, 0.450000006706, 0.840000013113, 0.83000001356, 0.729999989718, 0.61000002414, 0.240000004172, 0.470000005811, 0.919999976754, 0.820000012517, 0.76999998793, 0.709999988377, 0.620000024438, 0.140000002682, 0.490000004917, 0.820000012517, 0.840000019073, 1.07999997407, 1.25, 0.760000001788, 0.770000003576, 1.0700000155, 0.789999987036, 0.459999997318, 1.02999997854, 0.580000003874, 1.07999997407, 1.02999997854, 0.789999987036, 0.279999999404, 0.859999995828, 1.00999996006, 0.480000009835, 1.02000003338, 0.340000002682, 0.75, 0.680000005364, 0.909999992847, 1.10999998093, 0.370000011772, 0.880000023246, 0.689999986291, 0.639999999702, 0.240000001192, 1.28999999523, 0.170000001341, 0.240000001192, 0.979999987483, 0.829999975562, 0.940000011623, 
+
+L2_dGER_A_mn
+0.9, 0.4, 0.9, 0.9, 0.2, 0.3, 0.7, 0.5, 0.6, 0.1, 0.5, 0.1, 0.9, 0.5, 0.2, 0.5, 0.4, 0.1, 0.3, 0.3, 0.9, 0.6, 0.4, 0.3, 0.8, 0.4, 0.4, 0.1, 0.6, 0.2, 0.3, 0.9, 0.5, 0.2, 0.1, 0.7, 0.8, 0.8, 0.6, 0.1, 0.9, 0.4, 0.8, 0.9, 0.3, 0.9, 0.6, 0.4, 0.3, 0.6, 0.1, 0.6, 0.4, 0.2, 0.8, 0.2, 0.3, 0.8, 0.5, 0.2, 0.7, 0.5, 0.1, 0.2, 0.4, 0.7, 0.2, 0.7, 0.8, 0.2, 0.7, 0.4, 0.8, 0.5, 0.1, 0.2, 0.3, 0.6, 0.2, 0.8, 0.9, 0.6, 0.8, 0.5, 0.1, 0.7, 0.1, 0.2, 0.9, 0.6, 0.2, 0.6, 0.5, 0.5, 0.9, 0.5, 0.3, 0.5, 0.8, 0.8, 0.7, 0.1, 0.5, 0.8, 0.7, 0.8, 0.1, 0.8, 0.5, 0.6, 0.5, 0.7, 0.1, 0.6, 0.3, 0.1, 0.5, 0.7, 0.4, 0.6, 0.9, 0.6, 0.1, 0.1, 0.6, 0.9, 0.4, 0.4, 0.6, 0.3, 0.5, 0.4, 0.4, 0.2, 0.6, 0.6, 0.3, 0.7, 0.9, 0.2, 0.9, 0.6, 0.9, 0.7, 0.7, 0.8, 0.6, 0.9, 0.7, 0.2, 0.3, 0.5, 0.5, 0.5, 0.6, 0.8, 0.9, 0.6, 0.9, 0.1, 0.8, 0.2, 0.1, 0.5, 0.9, 0.1, 0.4, 0.7, 0.5, 0.7, 
+
+L2_dGER_x_m1
+0.5, 0.2, 0.1, 0.3, 0.6, 0.6, 0.1, 0.1, 0.4, 0.6, 
+
+L2_dGER_x_m2
+0.5, 0.0, 0.2, 0.0, 0.1, 0.0, 0.3, 0.0, 0.6, 0.0, 0.6, 0.0, 0.1, 0.0, 0.1, 0.0, 0.4, 0.0, 0.6, 0.0, 
+
+L2_dGER_y_n1
+0.1, 0.3, 0.7, 0.8, 0.1, 0.2, 0.4, 0.9, 0.4, 0.7, 0.7, 0.6, 0.6, 0.6, 0.8, 0.4, 0.2, 
+
+L2_dGER_y_n2
+0.1, 0.0, 0.0, 0.3, 0.0, 0.0, 0.7, 0.0, 0.0, 0.8, 0.0, 0.0, 0.1, 0.0, 0.0, 0.2, 0.0, 0.0, 0.4, 0.0, 0.0, 0.9, 0.0, 0.0, 0.4, 0.0, 0.0, 0.7, 0.0, 0.0, 0.7, 0.0, 0.0, 0.6, 0.0, 0.0, 0.6, 0.0, 0.0, 0.6, 0.0, 0.0, 0.8, 0.0, 0.0, 0.4, 0.0, 0.0, 0.2, 0.0, 0.0, 
+
+L2_dGER_o_N
+0.95, 0.55, 1.25, 1.3, 0.25, 0.4, 0.9, 0.95, 0.8, 0.45, 0.85, 0.4, 1.2, 0.8, 0.6, 0.7, 0.5, 0.12, 0.36, 0.44, 1.06, 0.62, 0.44, 0.38, 0.98, 0.48, 0.54, 0.24, 0.72, 0.32, 0.42, 1.06, 0.58, 0.24, 0.11, 0.73, 0.87, 0.88, 0.61, 0.12, 0.94, 0.49, 0.84, 0.97, 0.37, 0.96, 0.66, 0.46, 0.38, 0.64, 0.12, 0.63, 0.49, 0.41, 1.04, 0.23, 0.36, 0.92, 0.77, 0.32, 0.91, 0.71, 0.28, 0.38, 0.58, 0.94, 0.32, 0.76, 0.86, 0.38, 1.12, 0.88, 0.86, 0.62, 0.34, 0.74, 0.54, 1.02, 0.62, 1.16, 1.26, 0.96, 1.28, 0.74, 0.22, 0.76, 0.28, 0.62, 1.38, 0.66, 0.32, 0.84, 1.04, 0.74, 1.32, 0.92, 0.66, 0.86, 1.16, 1.28, 0.94, 0.22, 0.51, 0.83, 0.77, 0.88, 0.11, 0.82, 0.54, 0.69, 0.54, 0.77, 0.17, 0.66, 0.36, 0.16, 0.58, 0.74, 0.42, 0.61, 0.93, 0.67, 0.18, 0.11, 0.62, 0.94, 0.49, 0.44, 0.67, 0.37, 0.56, 0.46, 0.46, 0.28, 0.64, 0.62, 0.34, 0.82, 1.18, 0.52, 0.94, 0.68, 1.06, 1.06, 0.86, 1.08, 0.88, 1.14, 0.94, 0.44, 0.62, 0.66, 0.58, 0.56, 0.78, 1.22, 1.38, 0.66, 1.02, 0.34, 1.34, 0.44, 0.52, 0.92, 1.26, 0.46, 0.76, 1.18, 0.74, 0.82, 
+
+L2_cGERU_A_mn
+0.5, 0.699999988079, 0.20000000298, 0.699999988079, 0.300000011921, 0.600000023842, 0.20000000298, 0.300000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.10000000149, 0.800000011921, 0.5, 0.40000000596, 0.899999976158, 0.899999976158, 0.699999988079, 0.20000000298, 0.699999988079, 0.899999976158, 0.600000023842, 0.5, 0.20000000298, 0.800000011921, 0.10000000149, 0.899999976158, 0.600000023842, 0.5, 0.5, 0.5, 0.300000011921, 0.899999976158, 0.800000011921, 0.899999976158, 0.600000023842, 0.40000000596, 0.40000000596, 0.5, 0.800000011921, 0.800000011921, 0.699999988079, 0.20000000298, 0.699999988079, 0.5, 0.899999976158, 0.699999988079, 0.300000011921, 0.10000000149, 0.699999988079, 0.10000000149, 0.40000000596, 0.10000000149, 0.10000000149, 0.40000000596, 0.40000000596, 0.600000023842, 0.300000011921, 0.600000023842, 0.699999988079, 0.899999976158, 0.300000011921, 0.5, 0.40000000596, 0.600000023842, 0.600000023842, 0.10000000149, 0.300000011921, 0.20000000298, 0.699999988079, 0.40000000596, 0.600000023842, 0.600000023842, 0.300000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.699999988079, 0.699999988079, 0.699999988079, 0.5, 0.40000000596, 0.600000023842, 0.699999988079, 0.899999976158, 0.40000000596, 0.600000023842, 0.10000000149, 0.20000000298, 0.800000011921, 0.40000000596, 0.20000000298, 0.5, 0.699999988079, 0.300000011921, 0.20000000298, 0.20000000298, 0.5, 0.40000000596, 0.800000011921, 0.600000023842, 0.600000023842, 0.899999976158, 0.699999988079, 0.20000000298, 0.40000000596, 0.800000011921, 0.600000023842, 0.10000000149, 0.699999988079, 0.800000011921, 0.899999976158, 0.40000000596, 0.699999988079, 0.300000011921, 0.300000011921, 0.800000011921, 0.5, 0.800000011921, 0.40000000596, 0.5, 0.600000023842, 0.800000011921, 0.600000023842, 0.5, 0.20000000298, 0.20000000298, 0.5, 0.600000023842, 0.800000011921, 0.5, 0.40000000596, 0.10000000149, 0.10000000149, 0.699999988079, 0.800000011921, 0.5, 0.899999976158, 0.699999988079, 0.5, 0.800000011921, 0.40000000596, 0.40000000596, 0.300000011921, 0.899999976158, 0.10000000149, 0.300000011921, 0.300000011921, 0.40000000596, 0.899999976158, 0.40000000596, 0.600000023842, 0.5, 0.800000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.10000000149, 0.10000000149, 0.5, 0.20000000298, 0.20000000298, 0.699999988079, 0.899999976158, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.600000023842, 0.40000000596, 0.10000000149, 0.40000000596, 0.800000011921, 0.899999976158, 0.10000000149, 0.699999988079, 0.600000023842, 0.40000000596, 0.699999988079, 0.899999976158, 0.5, 0.899999976158, 0.600000023842, 0.40000000596, 0.10000000149, 0.300000011921, 0.600000023842, 0.699999988079, 0.40000000596, 0.20000000298, 0.899999976158, 0.600000023842, 0.300000011921, 0.10000000149, 0.5, 0.800000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.699999988079, 0.5, 0.10000000149, 0.800000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.20000000298, 0.800000011921, 0.10000000149, 0.40000000596, 0.5, 0.300000011921, 0.600000023842, 0.800000011921, 0.699999988079, 0.300000011921, 0.300000011921, 0.300000011921, 0.10000000149, 0.20000000298, 0.20000000298, 0.699999988079, 0.20000000298, 0.10000000149, 0.600000023842, 0.5, 0.20000000298, 0.5, 0.600000023842, 0.899999976158, 0.40000000596, 0.899999976158, 0.699999988079, 0.300000011921, 0.300000011921, 0.300000011921, 0.20000000298, 0.5, 0.20000000298, 0.40000000596, 0.5, 0.10000000149, 0.899999976158, 0.699999988079, 0.10000000149, 0.600000023842, 0.40000000596, 0.600000023842, 0.40000000596, 0.20000000298, 0.300000011921, 0.10000000149, 0.800000011921, 0.699999988079, 0.699999988079, 0.5, 0.40000000596, 0.699999988079, 0.10000000149, 0.10000000149, 0.600000023842, 0.600000023842, 0.5, 0.40000000596, 0.699999988079, 0.300000011921, 0.5, 0.5, 0.800000011921, 0.699999988079, 0.5, 0.600000023842, 0.10000000149, 0.600000023842, 0.10000000149, 0.5, 0.800000011921, 0.600000023842, 0.300000011921, 0.300000011921, 0.20000000298, 0.600000023842, 0.899999976158, 0.600000023842, 0.800000011921, 0.899999976158, 0.5, 0.699999988079, 0.300000011921, 0.699999988079, 0.699999988079, 0.300000011921, 0.300000011921, 0.300000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.800000011921, 0.699999988079, 0.699999988079, 0.20000000298, 0.10000000149, 0.10000000149, 0.20000000298, 0.10000000149, 0.40000000596, 0.5, 0.699999988079, 0.699999988079, 0.5, 0.600000023842, 0.600000023842, 0.40000000596, 0.600000023842, 0.699999988079, 0.600000023842, 0.800000011921, 0.899999976158, 0.899999976158, 0.300000011921, 0.5, 0.899999976158, 0.899999976158, 0.20000000298, 0.40000000596, 0.600000023842, 0.600000023842, 0.600000023842, 0.600000023842, 0.10000000149, 0.40000000596, 0.40000000596, 0.699999988079, 0.300000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.40000000596, 0.899999976158, 
+
+L2_cGERU_x_m1
+0.5, 0.800000011921, 0.699999988079, 0.5, 0.10000000149, 0.40000000596, 0.20000000298, 0.10000000149, 0.800000011921, 0.899999976158, 0.800000011921, 0.40000000596, 0.5, 0.5, 0.800000011921, 0.300000011921, 0.20000000298, 0.5, 0.5, 0.20000000298, 
+
+L2_cGERU_x_m2
+0.5, 0.800000011921, 0.0, 0.0, 0.699999988079, 0.5, 0.0, 0.0, 0.10000000149, 0.40000000596, 0.0, 0.0, 0.20000000298, 0.10000000149, 0.0, 0.0, 0.800000011921, 0.899999976158, 0.0, 0.0, 0.800000011921, 0.40000000596, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.800000011921, 0.300000011921, 0.0, 0.0, 0.20000000298, 0.5, 0.0, 0.0, 0.5, 0.20000000298, 0.0, 0.0, 
+
+L2_cGERU_y_n1
+0.10000000149, 0.300000011921, 0.10000000149, 0.5, 0.20000000298, 0.699999988079, 0.10000000149, 0.5, 0.600000023842, 0.5, 0.10000000149, 0.5, 0.40000000596, 0.5, 0.5, 0.699999988079, 0.10000000149, 0.5, 0.699999988079, 0.800000011921, 0.600000023842, 0.600000023842, 0.899999976158, 0.40000000596, 0.300000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.600000023842, 0.5, 0.20000000298, 0.300000011921, 0.20000000298, 0.300000011921, 
+
+L2_cGERU_y_n2
+0.10000000149, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.5, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.5, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.5, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.5, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.5, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.899999976158, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.899999976158, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.5, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cGERU_o_N
+0.309999987632, 0.929999996424, -0.150000002235, 1.02999999046, -0.159999985397, 1.11000002265, -0.150000002235, 0.630000014305, 0.300000011921, 1.63000000238, -0.150000002235, 0.430000003874, 0.600000008941, 1.07000000954, 0.0900000071526, 1.64999997616, 0.549999970943, 1.02999999046, -0.0900000220537, 1.65999999285, 0.719999961853, 1.38000006199, 0.629999978542, 1.11999999762, 0.469999991655, 0.640000026524, 1.10999995112, 1.47000002146, 0.40000000596, 1.23000002623, 0.359999988377, 0.61000002265, 0.759999964535, 1.11000002265, 0.819999970049, 0.860000029355, 0.220000005811, 0.800000000745, 0.290000005662, 1.38999999672, 0.620000011772, 1.09999998286, 0.370000012517, 1.34999999404, 0.319999999851, 1.29999997094, 0.729999987483, 0.850000008941, 0.10000000149, 1.43999997139, -0.0799999986589, 0.800000000745, 0.18999997884, 1.00999999434, 0.520000003576, 1.12000002742, 1.02999999344, 1.0299999994, 0.510000016689, 1.27000000358, 1.37999994278, 0.960000004768, 0.670000009537, 1.05000001192, 0.590000017583, 0.9100000301, 0.0899999952316, 0.610000018179, 0.0899999967217, 0.76999999091, 0.210000003278, 0.690000025779, 0.340000025034, 0.450000014156, 0.709999973476, 0.989999978095, -0.0399999982119, 0.990000001937, 0.509999985397, 0.789999990016, 0.339999998212, 0.610000011474, 0.370000025183, 0.96999999091, 0.709999973476, 0.490000007898, 0.350000014156, 0.460000003278, 0.0199999931455, 1.10000002831, 0.330000000149, 0.6, 0.289999988526, 0.879999997914, 0.270000004321, 0.590000000447, 0.0600000032783, 0.790000013858, 0.3, 0.910000015944, 0.500000017881, 0.710000027865, 0.889999975115, 0.769999991655, 0.170000002831, 0.510000007749, 0.770000013262, 0.76000002414, 0.0700000013411, 0.809999989867, 0.870000017732, 1.05999998093, 0.370000005811, 0.809999989867, 0.33000001356, 0.440000014603, 0.83000001356, 0.690000000447, 0.770000011772, 0.510000007749, 0.559999997318, 0.830000028461, 0.860000015199, 0.780000033677, 0.639999996722, 0.370000004321, 0.20000000298, 0.650000008196, 0.750000020117, 0.950000014156, 0.570000005811, 0.560000010729, 0.110000001043, 0.180000005364, 0.709999987632, 0.880000015795, 0.309999998808, 1.22999998823, 0.330000002384, 0.990000004917, 0.330000044107, 1.14000000268, 0.0300000202656, 0.790000016838, 0.930000014305, 1.0400000146, -0.069999973774, 0.790000016838, 0.270000027418, 1.65999997795, 0.170000039339, 1.61000001073, 0.130000014305, 1.29000001684, 0.140000019073, 2.16999996781, 0.140000022054, 1.12000003487, 0.459999997318, 1.62999996662, -0.0999999910593, 0.950000032783, 1.14999997616, 1.94999994636, 0.530000038147, 1.24000002503, 0.78999997735, 0.820000016987, 0.490000025034, 0.820000016987, 0.0599999973178, 0.680000020266, 0.680000011325, 1.33999998331, -0.0199999931455, 1.33999998927, 0.480000023246, 0.840000013113, 0.980000011325, 1.53999999523, 0.379999999404, 1.33999998331, 0.720000030398, 0.960000016689, 0.220000008047, 1.06000001371, 0.480000023246, 1.13999999523, 0.639999995232, 1.12000002146, 1.13999998927, 1.32000006318, 0.859999998808, 0.780000006855, 0.5, 1.4000000447, 1.29999997318, 0.900000020862, 1.1799999994, 1.34000000715, 0.539999998212, 0.420000016987, 0.840000010133, 0.620000027418, 0.500000018626, 1.09999998286, 0.200000006706, 0.500000003725, 0.550000019372, 0.54999999702, 0.200000006706, 0.800000000745, 0.350000023842, 1.15000003576, 0.600000012666, 0.999999988824, 0.250000014901, 0.750000014901, 0.200000017881, 0.69999999553, 3.72529029846e-09, 0.500000003725, 0.649999976158, 0.95000000298, 0.10000000149, 1.20000004768, 0.749999985099, 0.84999999404, 0.34999999404, 1.05000004172, 1.19999995828, 1.0, 0.949999988079, 1.25, 0.250000007451, 0.550000019372, 0.250000007451, 0.450000010431, 0.489999995232, 0.470000017732, 0.330000002384, 0.9300000076, 0.0500000014901, 1.51999997824, 0.629999984503, 0.53000000909, 0.930000044107, 0.980000026226, 0.530000020266, 0.83000001356, 0.370000006557, 0.820000024438, 0.290000002682, 1.51000001669, 0.629999984503, 1.12999999568, 0.819999985695, 1.2500000298, 1.0, 0.760000042021, 0.699999986589, 1.19000003695, 0.66000002265, 1.07000003338, 1.02999999046, 1.21000000477, 0.630000032187, 1.08000002027, 0.569999997616, 1.10000002831, 0.769999985695, 0.800000016391, 0.470000018477, 0.210000005513, 0.370000024438, 0.250000003725, 0.190000007153, 1.04000001311, 0.370000024438, 0.450000014156, 0.170000018477, 0.600000016391, 0.370000024438, 1.04999997839, 0.430000026226, 1.10000001639, 0.649999983609, 0.889999999702, 0.469999988675, 0.450000014156, 0.439999981821, 1.20999998689, 0.120000006557, 0.720000030398, 0.280000006855, 0.830000002384, 0.159999997318, 0.870000036359, 0.830000003874, 1.20999997944, 0.569999994636, 0.600000016391, -0.0100000032783, 0.260000006258, 0.0899999982119, 0.260000006258, 0.390000003427, 0.670000006557, 0.649999987334, 0.969999988675, 0.460000001788, 0.990000019073, 0.550000023097, 0.670000006557, 0.800000034273, 1.06999999464, 0.550000023097, 1.07000001252, 0.999999977648, 1.22999997854, 0.410000012219, 0.94999999553, 0.849999975413, 1.16999997675, 0.389999992251, 0.940000011623, 0.780000029206, 1.02000004232, 0.970000009537, 0.980000024736, 0.130000000894, 0.76000002116, 0.789999990761, 1.02999999195, 0.500000022352, 0.670000018477, 0.93999997437, 0.390000010133, 0.440000004172, 1.08999998331, 
+
+L2_zGERU_A_mn
+0.1, 0.1, 0.6, 0.4, 0.9, 0.9, 0.1, 0.5, 0.4, 0.4, 0.5, 0.5, 0.5, 0.4, 0.6, 0.4, 0.3, 0.9, 0.2, 0.8, 0.3, 0.9, 0.1, 0.6, 0.7, 0.8, 0.3, 0.6, 0.7, 0.1, 0.7, 0.1, 0.7, 0.4, 0.5, 0.8, 0.7, 0.7, 0.7, 0.2, 0.1, 0.7, 0.2, 0.7, 0.7, 0.6, 0.8, 0.7, 0.2, 0.2, 0.8, 0.8, 0.6, 0.3, 0.3, 0.9, 0.8, 0.8, 0.1, 0.4, 0.8, 0.6, 0.7, 0.2, 0.2, 0.1, 0.1, 0.6, 0.7, 0.6, 0.3, 0.8, 0.5, 0.9, 0.1, 0.2, 0.6, 0.1, 0.1, 0.3, 0.7, 0.6, 0.1, 0.6, 0.8, 0.6, 0.5, 0.5, 0.6, 0.1, 0.2, 0.9, 0.5, 0.1, 0.8, 0.7, 0.6, 0.6, 0.9, 0.2, 0.7, 0.6, 0.4, 0.4, 0.3, 0.6, 0.4, 0.8, 0.6, 0.5, 0.2, 0.3, 0.1, 0.6, 0.2, 0.5, 0.6, 0.8, 0.9, 0.1, 0.1, 0.2, 0.1, 0.9, 0.9, 0.4, 0.9, 0.2, 0.4, 0.5, 0.3, 0.7, 0.6, 0.4, 0.3, 0.4, 0.1, 0.4, 0.6, 0.5, 0.9, 0.3, 0.2, 0.9, 0.6, 0.4, 0.7, 0.1, 0.2, 0.2, 0.7, 0.2, 0.9, 0.6, 0.9, 0.1, 0.9, 0.6, 0.5, 0.9, 0.1, 0.5, 0.3, 0.5, 0.4, 0.4, 0.2, 0.5, 0.4, 0.3, 0.2, 0.7, 0.1, 0.8, 0.1, 0.8, 0.9, 0.9, 0.4, 0.5, 0.1, 0.3, 0.1, 0.4, 0.2, 0.9, 0.9, 0.7, 0.2, 0.5, 0.6, 0.7, 0.8, 0.1, 0.9, 0.3, 0.8, 0.2, 0.4, 0.6, 0.3, 0.9, 0.2, 0.8, 0.4, 0.5, 0.3, 0.1, 0.5, 0.3, 0.8, 0.8, 0.2, 0.4, 0.7, 0.1, 0.2, 0.4, 0.6, 0.8, 0.8, 0.7, 0.2, 0.8, 0.6, 0.4, 0.5, 0.4, 0.4, 0.6, 0.4, 0.6, 0.3, 0.5, 0.2, 0.3, 0.2, 0.1, 0.2, 0.5, 0.5, 0.5, 0.1, 0.9, 0.1, 0.7, 0.8, 0.7, 0.9, 0.4, 0.4, 0.4, 0.1, 0.4, 0.4, 0.4, 0.7, 0.4, 0.7, 0.6, 0.9, 0.9, 0.2, 0.4, 0.4, 0.4, 0.4, 0.6, 0.8, 0.1, 0.1, 0.9, 0.6, 0.4, 0.6, 0.4, 0.8, 0.1, 0.4, 0.6, 0.1, 0.8, 0.2, 0.7, 0.4, 0.3, 0.9, 0.9, 0.1, 0.4, 0.7, 0.9, 0.7, 0.6, 0.6, 0.5, 0.8, 0.4, 0.1, 0.1, 0.7, 0.4, 0.6, 0.8, 0.7, 0.7, 0.8, 0.1, 0.7, 0.8, 0.8, 0.9, 0.8, 0.8, 0.6, 0.9, 0.1, 0.9, 0.6, 0.9, 0.2, 0.1, 0.8, 0.4, 0.5, 0.8, 0.3, 0.3, 0.7, 0.5, 0.4, 0.8, 0.4, 0.5, 0.9, 0.8, 0.4, 0.7, 0.9, 0.7, 
+
+L2_zGERU_x_m1
+0.4, 0.6, 0.8, 0.7, 0.4, 0.6, 0.5, 0.8, 0.4, 0.1, 0.1, 0.2, 0.4, 0.4, 0.1, 0.4, 0.9, 0.1, 0.7, 0.7, 
+
+L2_zGERU_x_m2
+0.4, 0.6, 0.0, 0.0, 0.8, 0.7, 0.0, 0.0, 0.4, 0.6, 0.0, 0.0, 0.5, 0.8, 0.0, 0.0, 0.4, 0.1, 0.0, 0.0, 0.1, 0.2, 0.0, 0.0, 0.4, 0.4, 0.0, 0.0, 0.1, 0.4, 0.0, 0.0, 0.9, 0.1, 0.0, 0.0, 0.7, 0.7, 0.0, 0.0, 
+
+L2_zGERU_y_n1
+0.4, 0.2, 0.8, 0.2, 0.9, 0.9, 0.7, 0.2, 0.6, 0.6, 0.3, 0.9, 0.8, 0.5, 0.1, 0.4, 0.8, 0.1, 0.6, 0.1, 0.6, 0.9, 0.1, 0.2, 0.6, 0.3, 0.6, 0.2, 0.3, 0.2, 0.5, 0.5, 0.6, 0.8, 
+
+L2_zGERU_y_n2
+0.4, 0.2, 0.0, 0.0, 0.0, 0.0, 0.8, 0.2, 0.0, 0.0, 0.0, 0.0, 0.9, 0.9, 0.0, 0.0, 0.0, 0.0, 0.7, 0.2, 0.0, 0.0, 0.0, 0.0, 0.6, 0.6, 0.0, 0.0, 0.0, 0.0, 0.3, 0.9, 0.0, 0.0, 0.0, 0.0, 0.8, 0.5, 0.0, 0.0, 0.0, 0.0, 0.1, 0.4, 0.0, 0.0, 0.0, 0.0, 0.8, 0.1, 0.0, 0.0, 0.0, 0.0, 0.6, 0.1, 0.0, 0.0, 0.0, 0.0, 0.6, 0.9, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.0, 0.0, 0.0, 0.0, 0.6, 0.3, 0.0, 0.0, 0.0, 0.0, 0.6, 0.2, 0.0, 0.0, 0.0, 0.0, 0.3, 0.2, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.6, 0.8, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zGERU_o_N
+0.14, 0.42, 0.8, 0.96, 0.72, 1.8, 0.26, 1.0, 0.28, 1.0, 0.08, 1.04, 0.52, 1.08, 0.4, 0.62, 0.56, 1.42, 0.38, 1.2, -5.55111512313e-17, 1.62, 0.02, 0.74, 0.76, 1.28, 0.42, 1.04, 0.7, 0.36, 0.6, 0.6, 0.46, 1.08, 0.68, 1.24, 1.2, 1.42, 0.79, 1.55, 0.52, 1.35, 0.26, 1.6, 0.31, 1.53, 1.09, 1.66, 5.55111512313e-17, 0.59, 1.37, 1.44, 1.01, 0.8, 0.15, 2.04, 0.74, 1.03, 0.37, 1.06, 1.14, 1.18, 0.8, 0.57, 0.25, 0.85, 0.02, 1.66, 0.74, 0.92, 0.5, 1.36, 0.32, 1.8, 0.26, 0.7, 0.48, 0.7, -0.32, 0.84, 0.72, 1.28, -0.1, 0.82, 1.06, 1.12, 0.68, 0.9, 0.3, 0.82, 0.12, 1.04, 0.56, 0.58, 0.92, 1.14, 0.6, 0.86, 0.8, 0.7, 0.46, 1.28, 0.44, 0.82, 0.54, 1.34, 0.13, 1.97, 0.79, 1.16, 0.02, 1.08, -0.47, 1.29, 0.2, 1.39, 0.33, 1.08, 1.22, 0.79, 0.32, 0.73, -0.32, 1.83, 0.79, 0.58, 0.96, 0.83, 0.54, 1.08, 0.29, 1.04, 0.45, 1.05, -0.04, 1.28, 0.24, 0.52, 0.9, 0.66, 1.17, 0.75, 0.46, 1.05, 0.78, 0.7, 0.73, 0.49, 0.47, 0.48, 0.7, 0.37, 1.21, 0.72, 1.13, 0.2, 1.05, 1.02, 0.52, 0.99, 0.31, 0.68, 0.52, 0.64, 0.5, 0.51, 0.35, 0.75, 0.56, 0.68, 0.2, 0.8, 0.14, 0.98, 0.01, 1.07, 0.93, 1.06, 0.34, 0.68, -0.05, 0.45, 0.08, 0.61, 0.13, 0.96, 0.96, 0.87, 0.24, 0.63, 0.48, 0.91, 0.77, 0.14, 0.9, 0.45, 0.82, 0.34, 0.39, 0.68, 0.25, 1.05, 0.1, 1.0, 0.48, 0.74, 0.54, 0.5, 0.5, 1.02, 1.0, 1.16, 0.2, 0.88, 0.46, 0.58, 0.32, 0.92, 0.48, 1.0, 1.08, 1.06, 0.4, 1.08, 0.48, 1.0, 0.46, 0.52, 0.52, 0.96, 0.56, 0.92, 0.34, 0.7, 0.2, 0.7, 0.12, 0.66, 0.16, 0.68, 0.5, 0.84, -0.17, 1.35, 0.09, 1.0, 0.62, 1.0, 0.57, 0.61, 0.28, 0.77, -0.05, 0.48, 0.44, 0.73, 0.72, 0.65, 0.4, 0.93, 0.83, 0.96, 0.14, 0.67, 0.38, 0.66, 0.35, 0.74, 0.65, 0.35, -0.16, 1.22, 0.94, 0.62, 1.3, 0.66, 1.52, 1.0, 1.01, 0.85, 0.58, 1.4, 0.38, 1.54, 1.07, 0.83, 0.95, 1.27, 0.81, 0.57, 1.23, 1.05, 1.15, 1.47, 0.67, 0.69, 1.31, 0.73, 0.62, 0.34, 0.95, 0.61, 1.0, 1.3, 1.16, 1.48, 0.94, 0.52, 1.12, 1.5, 0.8, 2.16, 1.15, 1.43, 0.6, 1.74, -0.32, 1.74, 0.81, 1.81, -0.01, 0.45, 1.29, 1.03, 0.85, 1.29, 0.09, 1.35, 0.63, 0.71, 0.61, 1.43, 0.68, 1.06, 0.97, 1.15, 0.4, 1.4, 0.76, 1.68, 
+
+L2_cGERC_A_mn
+0.5, 0.40000000596, 0.10000000149, 0.10000000149, 0.10000000149, 0.20000000298, 0.5, 0.40000000596, 0.800000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.899999976158, 0.40000000596, 0.300000011921, 0.40000000596, 0.699999988079, 0.699999988079, 0.899999976158, 0.699999988079, 0.800000011921, 0.600000023842, 0.300000011921, 0.5, 0.300000011921, 0.5, 0.300000011921, 0.300000011921, 0.800000011921, 0.699999988079, 0.800000011921, 0.600000023842, 0.600000023842, 0.699999988079, 0.899999976158, 0.600000023842, 0.699999988079, 0.5, 0.10000000149, 0.600000023842, 0.300000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.899999976158, 0.40000000596, 0.300000011921, 0.40000000596, 0.300000011921, 0.300000011921, 0.800000011921, 0.5, 0.20000000298, 0.300000011921, 0.300000011921, 0.10000000149, 0.40000000596, 0.40000000596, 0.300000011921, 0.899999976158, 0.800000011921, 0.40000000596, 0.20000000298, 0.300000011921, 0.40000000596, 0.10000000149, 0.300000011921, 0.600000023842, 0.600000023842, 0.40000000596, 0.800000011921, 0.600000023842, 0.600000023842, 0.300000011921, 0.899999976158, 0.10000000149, 0.300000011921, 0.10000000149, 0.800000011921, 0.5, 0.600000023842, 0.600000023842, 0.40000000596, 0.699999988079, 0.5, 0.5, 0.600000023842, 0.600000023842, 0.699999988079, 0.5, 0.40000000596, 0.10000000149, 0.10000000149, 0.899999976158, 0.5, 0.40000000596, 0.10000000149, 0.10000000149, 0.40000000596, 0.699999988079, 0.40000000596, 0.899999976158, 0.10000000149, 0.699999988079, 0.5, 0.20000000298, 0.899999976158, 0.5, 0.40000000596, 0.20000000298, 0.10000000149, 0.20000000298, 0.899999976158, 0.10000000149, 0.40000000596, 0.699999988079, 0.40000000596, 0.600000023842, 0.20000000298, 0.5, 0.699999988079, 0.20000000298, 0.10000000149, 0.40000000596, 0.40000000596, 0.800000011921, 0.20000000298, 0.10000000149, 0.40000000596, 0.20000000298, 0.600000023842, 0.800000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.10000000149, 0.5, 0.5, 0.40000000596, 0.10000000149, 0.10000000149, 0.699999988079, 0.10000000149, 0.40000000596, 0.300000011921, 0.5, 0.800000011921, 0.40000000596, 0.40000000596, 0.10000000149, 0.699999988079, 0.10000000149, 0.5, 0.300000011921, 0.5, 0.600000023842, 0.40000000596, 0.699999988079, 0.800000011921, 0.699999988079, 0.600000023842, 0.20000000298, 0.40000000596, 0.20000000298, 0.10000000149, 0.20000000298, 0.5, 0.40000000596, 0.800000011921, 0.800000011921, 0.5, 0.5, 0.800000011921, 0.20000000298, 0.40000000596, 0.10000000149, 0.10000000149, 0.600000023842, 0.899999976158, 0.10000000149, 0.800000011921, 0.899999976158, 0.5, 0.20000000298, 0.5, 0.300000011921, 0.5, 0.10000000149, 0.10000000149, 0.600000023842, 0.40000000596, 0.899999976158, 0.899999976158, 0.699999988079, 0.300000011921, 0.600000023842, 0.300000011921, 0.20000000298, 0.10000000149, 0.300000011921, 0.5, 0.5, 0.899999976158, 0.600000023842, 0.300000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.20000000298, 0.899999976158, 0.699999988079, 0.899999976158, 0.5, 0.800000011921, 0.40000000596, 0.899999976158, 0.300000011921, 0.300000011921, 0.5, 0.300000011921, 0.600000023842, 0.10000000149, 0.40000000596, 0.5, 0.800000011921, 0.899999976158, 0.600000023842, 0.300000011921, 0.899999976158, 0.300000011921, 0.600000023842, 0.800000011921, 0.20000000298, 0.800000011921, 0.600000023842, 0.40000000596, 0.40000000596, 0.300000011921, 0.5, 0.20000000298, 0.899999976158, 0.600000023842, 0.800000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.300000011921, 0.5, 0.5, 0.600000023842, 0.40000000596, 0.20000000298, 0.699999988079, 0.600000023842, 0.899999976158, 0.10000000149, 0.5, 0.899999976158, 0.600000023842, 0.899999976158, 0.5, 0.699999988079, 0.10000000149, 0.899999976158, 0.20000000298, 0.10000000149, 0.699999988079, 0.899999976158, 0.899999976158, 0.40000000596, 0.5, 0.20000000298, 0.800000011921, 0.300000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.5, 0.899999976158, 0.699999988079, 0.10000000149, 0.5, 0.800000011921, 0.699999988079, 0.600000023842, 0.600000023842, 0.699999988079, 0.20000000298, 0.699999988079, 0.800000011921, 0.699999988079, 0.10000000149, 0.5, 0.800000011921, 0.40000000596, 0.899999976158, 0.899999976158, 0.699999988079, 0.600000023842, 0.600000023842, 0.20000000298, 0.300000011921, 0.40000000596, 0.600000023842, 0.699999988079, 0.20000000298, 0.699999988079, 0.5, 0.699999988079, 0.20000000298, 0.699999988079, 0.5, 0.300000011921, 0.5, 0.699999988079, 0.5, 0.10000000149, 0.20000000298, 0.5, 0.899999976158, 0.600000023842, 0.600000023842, 0.5, 0.699999988079, 0.40000000596, 0.800000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.10000000149, 0.899999976158, 0.899999976158, 0.20000000298, 0.600000023842, 0.40000000596, 0.10000000149, 0.300000011921, 0.699999988079, 0.699999988079, 0.899999976158, 
+
+L2_cGERC_x_m1
+0.40000000596, 0.800000011921, 0.600000023842, 0.300000011921, 0.800000011921, 0.800000011921, 0.5, 0.699999988079, 0.600000023842, 0.10000000149, 0.300000011921, 0.20000000298, 0.20000000298, 0.300000011921, 0.800000011921, 0.20000000298, 0.600000023842, 0.600000023842, 0.40000000596, 0.800000011921, 
+
+L2_cGERC_x_m2
+0.40000000596, 0.800000011921, 0.0, 0.0, 0.600000023842, 0.300000011921, 0.0, 0.0, 0.800000011921, 0.800000011921, 0.0, 0.0, 0.5, 0.699999988079, 0.0, 0.0, 0.600000023842, 0.10000000149, 0.0, 0.0, 0.300000011921, 0.20000000298, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.0, 0.0, 0.800000011921, 0.20000000298, 0.0, 0.0, 0.600000023842, 0.600000023842, 0.0, 0.0, 0.40000000596, 0.800000011921, 0.0, 0.0, 
+
+L2_cGERC_y_n1
+0.20000000298, 0.300000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.300000011921, 0.600000023842, 0.5, 0.20000000298, 0.10000000149, 0.20000000298, 0.800000011921, 0.5, 0.300000011921, 0.20000000298, 0.5, 0.20000000298, 0.20000000298, 0.300000011921, 0.699999988079, 0.5, 0.899999976158, 0.40000000596, 0.699999988079, 0.40000000596, 0.899999976158, 0.300000011921, 0.800000011921, 0.40000000596, 0.300000011921, 0.800000011921, 0.600000023842, 0.10000000149, 0.20000000298, 
+
+L2_cGERC_y_n2
+0.20000000298, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.899999976158, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.5, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.5, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.5, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.5, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cGERC_o_N
+0.820000015497, 0.440000004172, 0.939999999702, 0.380000000894, 0.700000010431, 0.799999988079, 1.14000001907, 0.680000029206, 0.960000016689, 0.920000015497, 0.820000022948, 0.539999983311, 1.33999999225, 0.680000005364, 0.780000020266, 0.360000007749, 0.939999995232, 0.779999990463, 1.57999998152, 0.660000001788, 1.72000000656, 0.640000033975, 1.0200000155, 0.540000010133, 1.18000000834, 0.460000013709, 1.06000003755, 0.220000015497, 1.2000000298, 0.899999991059, 1.60000004768, 1.0000000298, 0.800000029802, 0.699999988079, 1.10999998987, 0.480000012815, 1.33000000238, 0.289999995232, 0.730000015795, 0.690000013113, 0.810000046492, 0.0800000053644, 0.950000020117, 0.40000000596, 1.25999999583, -0.0200000169873, 0.690000030994, 0.369999997616, 0.570000024438, 0.0600000032783, 0.980000021756, 0.439999996722, 0.590000022054, -0.0299999904633, 0.870000027418, -0.289999999702, 0.850000023842, 0.10000000298, 0.81000002861, 0.479999975562, 1.22000003934, 0.00999998688698, 0.530000023246, 0.240000004172, 1.06000004649, -0.0200000140071, 0.420000018477, 0.510000018924, 1.00000004172, 0.319999997616, 1.92000000954, 0.600000023842, 1.56000002861, 0.779999990463, 1.78000000834, 0.180000021756, 0.540000019073, 0.180000003874, 1.60000003576, 0.0199999856949, 1.24000004292, 0.760000016689, 0.960000016689, 0.459999986887, 0.820000009537, 0.5, 1.40000003576, 0.280000038147, 1.81999998569, 0.180000014305, 1.28000001431, -0.139999987781, 1.14000000268, 0.49999999404, 1.38000003219, 0.0, 0.66000002414, 0.179999997914, 1.52000005126, 0.859999980927, 0.640000013113, 0.819999973774, 0.410000007749, 0.689999981821, 1.33999997735, 0.339999992251, 1.55999996901, 0.979999966621, 1.05000001192, 0.370000012517, 0.270000002831, 0.290000001937, 1.55999997646, -0.160000004768, 0.860000010729, 0.899999976158, 0.85000000149, 0.490000023544, 0.440000004172, 0.539999998212, 1.33999997735, 0.0600000137091, 0.979999974072, 0.300000011921, 1.08999999225, 0.730000017285, 1.02999997854, -0.069999987185, 1.11000001073, 0.0100000017881, 1.01000003159, 0.930000005364, 1.12000002742, 0.860000010729, 1.08999997661, 0.069999999851, 0.650000008196, 0.339999986291, 0.890000015348, -0.250000008196, 0.670000010282, 0.609999972731, 0.510000030845, 0.159999997318, 0.430000018775, 0.459999997318, 1.00000002086, -0.0600000196695, 0.730000019521, -0.0300000120699, 0.869999995381, -0.180000009835, 0.640000007153, 0.20000000596, 0.750000014156, 0.210000015944, 0.790000016838, 0.209999981672, 1.11000002488, 0.319999979734, 0.930000035912, -0.30000000298, 0.66000002265, -0.250000021607, 0.370000016242, 0.0599999898672, 1.0400000295, 0.119999979734, 0.880000015795, 0.690000005662, 0.620000006557, 0.44999999404, 1.15000001639, 0.129999997914, 0.730000012815, 0.189999992251, 0.380000017285, 0.570000024438, 0.979999980032, 0.110000001043, 1.02000001997, 0.699999964237, 0.710000009239, 0.209999997318, 0.660000004768, 0.190000007153, 0.60000000447, 0.079999999404, 0.330000008345, 0.450000022352, 0.730000009835, 0.729999974072, 1.15999998242, 0.569999985695, 0.600000016391, 0.41000002265, 0.550000023842, 0.0199999931455, 0.280000011325, 0.290000007153, 0.86000001967, 0.479999990463, 0.969999978989, 0.56000002116, 0.430000020266, 0.800000011921, 0.45000000596, 0.769999993145, 0.470000008047, 1.10999997646, 0.970000000596, 0.979999988973, 0.570000002831, 0.840000014603, 0.680000020266, 0.799999974668, 0.490000020564, 0.390000014603, 0.690000007153, 0.260000013709, 0.700000028312, 0.120000003576, 0.670000014007, 0.450000007451, 1.17000001699, 0.869999984205, 0.890000030994, 0.280000018775, 1.24999998212, 0.240000020564, 0.900000040233, 0.730000014305, 0.370000012517, 0.860000015199, 0.940000042915, 0.520000012517, 0.480000009835, 0.290000012368, 0.720000008047, -8.94069684954e-09, 1.59999997467, 0.180000024736, 1.58000000685, 0.0399999862909, 0.680000029206, -0.0799999964237, 0.480000017285, 0.459999998808, 0.820000009537, 5.96046434431e-09, 0.860000015199, 0.0599999913573, 0.959999994338, 0.240000019073, 1.09999998212, -0.0200000020862, 0.880000012815, 0.399999980628, 1.18000002772, 0.279999985993, 0.960000009239, 0.219999991655, 0.600000008941, 0.259999986887, 0.600000020862, -0.480000014305, 1.08000000089, 0.739999965429, 1.66000000179, 0.0799999845028, 0.620000003576, 0.0599999988079, 1.10000003278, 0.240000004172, 1.04000002205, 0.899999976158, 1.12000002742, 0.859999992847, 1.56000001669, 0.760000004768, 0.280000011325, 0.560000003278, 1.4000000447, 0.33999996841, 1.08000005007, 0.720000021458, 1.12000000656, 0.0199999976158, 0.940000001192, 0.800000011921, 1.30000001192, -0.139999993742, 1.34000001907, 0.560000016689, 1.06000002861, 0.719999979734, 1.67999999642, 0.39999999404, 1.26000006437, 0.300000011921, 0.620000030398, 0.360000010729, 1.2400000608, 0.720000021458, 0.879999997914, 0.139999999702, 1.02000000358, 0.539999998212, 1.53999998629, 0.480000002384, 1.29999999702, 1.0999999851, 0.940000030994, 0.780000023246, 0.859999992847, 0.620000003576, 0.820000022948, 0.0399999982119, 0.940000016093, 1.17999997556, 1.08000003219, 0.56000002563, 0.740000007153, 0.779999990463, 1.08000001132, 0.76000002563, 1.22000000656, 0.640000033975, 1.61999997973, 0.140000011623, 1.77999997258, 0.859999989867, 0.96000002861, 0.520000027418, 0.800000023842, 0.30000000447, 1.10000004768, 1.09999999404, 0.89999999404, 0.899999976158, 
+
+L2_zGERC_A_mn
+0.8, 0.6, 0.6, 0.3, 0.8, 0.6, 0.7, 0.5, 0.7, 0.2, 0.4, 0.2, 0.1, 0.2, 0.5, 0.2, 0.7, 0.1, 0.1, 0.4, 0.8, 0.3, 0.1, 0.4, 0.8, 0.2, 0.3, 0.6, 0.9, 0.9, 0.6, 0.7, 0.2, 0.5, 0.9, 0.3, 0.6, 0.9, 0.2, 0.8, 0.1, 0.7, 0.5, 0.9, 0.3, 0.5, 0.1, 0.7, 0.5, 0.1, 0.2, 0.2, 0.4, 0.8, 0.2, 0.7, 0.3, 0.1, 0.2, 0.8, 0.7, 0.4, 0.3, 0.2, 0.7, 0.8, 0.3, 0.9, 0.5, 0.2, 0.8, 0.2, 0.9, 0.8, 0.2, 0.4, 0.4, 0.9, 0.1, 0.1, 0.3, 0.5, 0.6, 0.9, 0.1, 0.3, 0.7, 0.1, 0.1, 0.6, 0.5, 0.9, 0.1, 0.3, 0.6, 0.6, 0.4, 0.9, 0.5, 0.7, 0.1, 0.1, 0.7, 0.8, 0.3, 0.7, 0.2, 0.3, 0.7, 0.5, 0.1, 0.4, 0.9, 0.6, 0.7, 0.4, 0.6, 0.1, 0.3, 0.7, 0.8, 0.8, 0.4, 0.9, 0.9, 0.3, 0.1, 0.4, 0.6, 0.1, 0.1, 0.9, 0.2, 0.4, 0.9, 0.3, 0.7, 0.9, 0.9, 0.4, 0.7, 0.8, 0.4, 0.7, 0.4, 0.2, 0.3, 0.6, 0.5, 0.9, 0.4, 0.7, 0.3, 0.5, 0.2, 0.2, 0.4, 0.8, 0.8, 0.2, 0.8, 0.9, 0.7, 0.4, 0.8, 0.2, 0.1, 0.2, 0.8, 0.2, 0.7, 0.4, 0.1, 0.2, 0.2, 0.6, 0.1, 0.2, 0.3, 0.7, 0.4, 0.7, 0.2, 0.4, 0.1, 0.2, 0.2, 0.4, 0.5, 0.5, 0.2, 0.3, 0.5, 0.3, 0.7, 0.6, 0.2, 0.3, 0.1, 0.2, 0.3, 0.9, 0.1, 0.5, 0.7, 0.1, 0.4, 0.4, 0.2, 0.1, 0.2, 0.1, 0.2, 0.2, 0.8, 0.7, 0.2, 0.8, 0.7, 0.5, 0.7, 0.6, 0.7, 0.2, 0.4, 0.5, 0.1, 0.1, 0.9, 0.3, 0.6, 0.9, 0.3, 0.2, 0.3, 0.2, 0.4, 0.5, 0.2, 0.9, 0.5, 0.3, 0.2, 0.7, 0.8, 0.2, 0.1, 0.7, 0.2, 0.4, 0.7, 0.8, 0.6, 0.1, 0.4, 0.7, 0.7, 0.1, 0.4, 0.9, 0.9, 0.1, 0.8, 0.4, 0.6, 0.6, 0.4, 0.8, 0.5, 0.3, 0.6, 0.8, 0.2, 0.1, 0.7, 0.1, 0.4, 0.7, 0.4, 0.3, 0.7, 0.8, 0.2, 0.3, 0.9, 0.5, 0.5, 0.5, 0.9, 0.2, 0.9, 0.5, 0.7, 0.3, 0.7, 0.5, 0.7, 0.2, 0.6, 0.9, 0.5, 0.9, 0.8, 0.8, 0.8, 0.6, 0.4, 0.8, 0.5, 0.7, 0.3, 0.5, 0.5, 0.8, 0.8, 0.6, 0.7, 0.3, 0.6, 0.5, 0.5, 0.7, 0.5, 0.6, 0.7, 0.6, 0.1, 0.2, 0.1, 0.5, 0.6, 0.9, 0.5, 0.2, 0.1, 0.3, 0.2, 0.4, 0.9, 0.1, 
+
+L2_zGERC_x_m1
+0.9, 0.5, 0.8, 0.3, 0.5, 0.4, 0.8, 0.6, 0.9, 0.8, 0.1, 0.2, 0.9, 0.4, 0.2, 0.3, 0.6, 0.2, 0.2, 0.6, 
+
+L2_zGERC_x_m2
+0.9, 0.5, 0.0, 0.0, 0.8, 0.3, 0.0, 0.0, 0.5, 0.4, 0.0, 0.0, 0.8, 0.6, 0.0, 0.0, 0.9, 0.8, 0.0, 0.0, 0.1, 0.2, 0.0, 0.0, 0.9, 0.4, 0.0, 0.0, 0.2, 0.3, 0.0, 0.0, 0.6, 0.2, 0.0, 0.0, 0.2, 0.6, 0.0, 0.0, 
+
+L2_zGERC_y_n1
+0.9, 0.7, 0.3, 0.8, 0.3, 0.2, 0.3, 0.6, 0.1, 0.4, 0.1, 0.5, 0.6, 0.6, 0.4, 0.7, 0.2, 0.4, 0.6, 0.5, 0.9, 0.1, 0.4, 0.6, 0.4, 0.8, 0.3, 0.5, 0.9, 0.5, 0.6, 0.7, 0.5, 0.7, 
+
+L2_zGERC_y_n2
+0.9, 0.7, 0.0, 0.0, 0.0, 0.0, 0.3, 0.8, 0.0, 0.0, 0.0, 0.0, 0.3, 0.2, 0.0, 0.0, 0.0, 0.0, 0.3, 0.6, 0.0, 0.0, 0.0, 0.0, 0.1, 0.4, 0.0, 0.0, 0.0, 0.0, 0.1, 0.5, 0.0, 0.0, 0.0, 0.0, 0.6, 0.6, 0.0, 0.0, 0.0, 0.0, 0.4, 0.7, 0.0, 0.0, 0.0, 0.0, 0.2, 0.4, 0.0, 0.0, 0.0, 0.0, 0.6, 0.5, 0.0, 0.0, 0.0, 0.0, 0.9, 0.1, 0.0, 0.0, 0.0, 0.0, 0.4, 0.6, 0.0, 0.0, 0.0, 0.0, 0.4, 0.8, 0.0, 0.0, 0.0, 0.0, 0.3, 0.5, 0.0, 0.0, 0.0, 0.0, 0.9, 0.5, 0.0, 0.0, 0.0, 0.0, 0.6, 0.7, 0.0, 0.0, 0.0, 0.0, 0.5, 0.7, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zGERC_o_N
+1.96, 0.42, 1.27, -0.27, 1.17, 0.57, 1.27, 0.11, 0.99, -0.11, 0.74, -0.2, 0.94, -0.04, 1.21, -0.23, 1.08, -0.16, 0.89, 0.25, 1.66, 0.66, 0.76, 0.06, 1.56, -0.32, 0.82, 0.3, 1.96, 0.9, 1.49, 0.37, 1.0, 0.12, 1.83, 0.01, 1.08, 0.35, 0.5, 0.73, 0.52, 0.31, 0.7, 0.61, 0.53, 0.13, 0.76, 0.4, 1.03, -0.34, 0.48, -0.06, 1.03, 0.58, 0.95, 0.89, 0.8, -0.26, 0.76, 0.28, 1.09, 0.09, 1.17, 0.07, 1.39, 0.42, 0.91, 0.49, 1.23, 0.21, 1.27, -0.08, 1.13, 0.82, 0.59, 0.22, 0.61, 0.74, 0.35, -0.11, 0.84, 0.44, 1.08, 0.71, 0.36, 0.18, 1.2, 0.09, 0.59, 0.91, 0.94, 0.76, 0.62, 0.06, 0.95, 0.47, 1.05, 1.01, 1.08, 0.59, 0.63, -0.05, 1.84, 0.78, 1.02, 0.24, 0.56, 0.32, 1.3, 0.2, 0.42, 0.14, 1.28, 0.26, 1.54, 0.28, 1.34, -0.22, 0.7, 0.5, 1.58, 0.76, 1.18, 1.36, 1.58, 0.06, 0.9, -1.11022302463e-16, 1.14, -0.12, 1.12, 1.04, 1.1, 0.2, 1.72, 0.04, 2.07, 0.99, 1.81, -0.08, 1.13, 0.86, 1.15, 0.4, 0.81, -0.08, 0.79, 0.23, 1.52, 0.84, 1.32, 0.39, 0.8, 0.3, 1.14, 0.23, 1.29, 1.43, 1.64, -0.02, 1.8, 0.5, 1.37, 0.19, 2.01, 0.47, 1.2, 0.05, 1.81, -0.03, 0.93, 0.51, 0.29, 0.18, 0.27, 0.64, 0.25, 0.2, 0.39, 0.68, 0.51, 0.67, 0.38, 0.46, 0.28, 0.21, 0.3, 0.4, 0.66, 0.57, 0.31, 0.47, 0.66, 0.32, 0.9, 0.6, 0.33, 0.31, 0.29, 0.33, 0.5, 0.95, 0.29, 0.53, 1.79, -0.17, 0.99, -0.2, 0.55, 0.04, 0.71, -0.32, 0.45, -0.12, 1.09, 0.29, 0.98, 0.5, 1.34, 0.03, 1.04, 0.32, 1.44, -0.01, 1.25, 0.77, 0.7, -0.28, 1.58, -0.26, 1.07, 0.57, 1.31, 0.11, 1.12, -0.19, 1.13, 0.07, 0.59, 1.03, 0.8, 0.23, 0.32, 0.75, 1.04, 0.17, 0.24, 0.65, 0.37, 0.33, 1.0, 0.86, 0.89, 0.08, 0.56, 0.68, 0.97, 0.18, 0.61, 1.15, 1.16, 0.1, 1.12, 0.36, 0.81, 0.59, 0.73, 0.97, 0.83, 0.34, 0.91, 0.81, 0.88, -0.14, 1.04, -0.32, 0.62, 0.64, 0.7, 0.0, 0.84, 0.58, 0.36, 0.02, 1.38, 0.26, 0.88, 0.16, 1.1, 2.77555756156e-17, 1.36, 0.32, 1.26, 0.42, 1.06, 0.22, 1.1, -0.2, 0.88, 0.66, 1.14, 0.78, 1.3, 0.5, 1.24, 0.28, 1.0, 1.2, 1.04, 0.72, 0.48, 0.64, 0.92, 0.86, 1.06, 0.58, 1.02, 0.26, 1.08, 0.74, 1.0, 0.8, 0.78, 0.64, 1.12, 0.86, 0.34, 0.72, 0.54, 0.62, 1.16, 0.98, 0.86, 0.28, 0.58, 0.74, 0.74, 0.62, 1.42, 0.26, 
+
+L2_cHER_A_nn
+0.899999976158, 0.0, 0.10000000149, 0.600000023842, 0.40000000596, 0.20000000298, 0.40000000596, 0.800000011921, 0.5, 0.5, 0.40000000596, 0.10000000149, 0.10000000149, 0.40000000596, 0.20000000298, 0.699999988079, 0.899999976158, 0.300000011921, 0.699999988079, 0.800000011921, 0.300000011921, 0.10000000149, 0.600000023842, 0.40000000596, 0.5, 0.699999988079, 0.40000000596, 0.800000011921, 0.5, 0.20000000298, 0.20000000298, 0.800000011921, 0.600000023842, 0.899999976158, 0.10000000149, -0.600000023842, 0.300000011921, 0.0, 0.5, 0.40000000596, 0.10000000149, 0.600000023842, 0.600000023842, 0.300000011921, 0.5, 0.5, 0.699999988079, 0.699999988079, 0.40000000596, 0.600000023842, 0.300000011921, 0.40000000596, 0.899999976158, 0.699999988079, 0.800000011921, 0.699999988079, 0.600000023842, 0.300000011921, 0.899999976158, 0.300000011921, 0.10000000149, 0.699999988079, 0.899999976158, 0.600000023842, 0.899999976158, 0.300000011921, 0.40000000596, 0.20000000298, 0.40000000596, -0.20000000298, 0.5, -0.40000000596, 0.10000000149, 0.0, 0.20000000298, 0.300000011921, 0.600000023842, 0.5, 0.600000023842, 0.5, 0.20000000298, 0.20000000298, 0.5, 0.300000011921, 0.699999988079, 0.800000011921, 0.800000011921, 0.5, 0.10000000149, 0.899999976158, 0.699999988079, 0.300000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.40000000596, 0.10000000149, 0.600000023842, 0.899999976158, 0.40000000596, 0.20000000298, 0.5, 0.40000000596, -0.800000011921, 0.10000000149, -0.600000023842, 0.20000000298, -0.300000011921, 0.300000011921, 0.0, 0.899999976158, 0.10000000149, 0.20000000298, 0.899999976158, 0.300000011921, 0.10000000149, 0.300000011921, 0.10000000149, 0.699999988079, 0.300000011921, 0.10000000149, 0.899999976158, 0.20000000298, 0.20000000298, 0.10000000149, 0.10000000149, 0.10000000149, 0.20000000298, 0.5, 0.40000000596, 0.600000023842, 0.800000011921, 0.600000023842, 0.699999988079, 0.10000000149, 0.800000011921, 0.5, -0.5, 0.600000023842, -0.300000011921, 0.600000023842, -0.5, 0.899999976158, -0.10000000149, 0.600000023842, 0.0, 0.800000011921, 0.10000000149, 0.800000011921, 0.899999976158, 0.300000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.800000011921, 0.600000023842, 0.10000000149, 0.300000011921, 0.20000000298, 0.40000000596, 0.899999976158, 0.600000023842, 0.899999976158, 0.800000011921, 0.10000000149, 0.5, 0.10000000149, 0.10000000149, 0.10000000149, 0.899999976158, 0.40000000596, -0.10000000149, 0.5, -0.5, 0.600000023842, -0.5, 0.20000000298, -0.899999976158, 0.800000011921, -0.10000000149, 0.899999976158, 0.0, 0.5, 0.699999988079, 0.800000011921, 0.20000000298, 0.800000011921, 0.5, 0.20000000298, 0.800000011921, 0.800000011921, 0.5, 0.40000000596, 0.699999988079, 0.20000000298, 0.40000000596, 0.10000000149, 0.899999976158, 0.699999988079, 0.800000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.300000011921, 0.10000000149, -0.40000000596, 0.699999988079, -0.699999988079, 0.20000000298, -0.20000000298, 0.300000011921, -0.10000000149, 0.800000011921, -0.899999976158, 0.5, -0.699999988079, 0.899999976158, 0.0, 0.20000000298, 0.800000011921, 0.899999976158, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.600000023842, 0.600000023842, 0.899999976158, 0.699999988079, 0.20000000298, 0.699999988079, 0.600000023842, 0.600000023842, 0.10000000149, 0.10000000149, 0.10000000149, 0.40000000596, 0.5, 0.20000000298, -0.699999988079, 0.40000000596, -0.600000023842, 0.5, -0.300000011921, 0.300000011921, -0.10000000149, 0.300000011921, -0.699999988079, 0.800000011921, -0.20000000298, 0.20000000298, -0.800000011921, 0.5, 0.0, 0.10000000149, 0.10000000149, 0.800000011921, 0.899999976158, 0.800000011921, 0.10000000149, 0.300000011921, 0.699999988079, 0.800000011921, 0.300000011921, 0.10000000149, 0.600000023842, 0.899999976158, 0.600000023842, 0.10000000149, 0.40000000596, 0.800000011921, 0.600000023842, 0.899999976158, -0.300000011921, 0.300000011921, -0.40000000596, 0.699999988079, -0.800000011921, 0.699999988079, -0.300000011921, 0.10000000149, -0.40000000596, 0.800000011921, -0.5, 0.899999976158, -0.699999988079, 0.10000000149, -0.10000000149, 0.20000000298, 0.0, 0.899999976158, 0.800000011921, 0.10000000149, 0.10000000149, 0.699999988079, 0.699999988079, 0.5, 0.10000000149, 0.10000000149, 0.600000023842, 0.600000023842, 0.899999976158, 0.10000000149, 0.10000000149, 0.800000011921, 0.10000000149, 0.699999988079, -0.800000011921, 0.899999976158, -0.699999988079, 0.800000011921, -0.5, 0.10000000149, -0.899999976158, 0.800000011921, -0.600000023842, 0.20000000298, -0.800000011921, 0.600000023842, -0.800000011921, 0.800000011921, -0.899999976158, 0.899999976158, -0.800000011921, 0.20000000298, 0.0, 0.600000023842, 0.5, 0.5, 0.20000000298, 0.20000000298, 0.699999988079, 0.5, 0.699999988079, 0.300000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.10000000149, 0.800000011921, 0.300000011921, -0.10000000149, 0.800000011921, -0.699999988079, 0.10000000149, -0.899999976158, 0.20000000298, -0.20000000298, 0.10000000149, -0.300000011921, 0.800000011921, -0.5, 0.20000000298, -0.600000023842, 0.800000011921, -0.10000000149, 0.10000000149, -0.10000000149, 0.600000023842, -0.5, 0.10000000149, 0.0, 0.40000000596, 0.600000023842, 0.699999988079, 0.800000011921, 0.600000023842, 0.40000000596, 0.600000023842, 0.699999988079, 0.300000011921, 0.899999976158, 0.899999976158, 0.5, 0.600000023842, -0.40000000596, 0.600000023842, -0.300000011921, 0.699999988079, -0.300000011921, 0.10000000149, -0.10000000149, 0.20000000298, -0.40000000596, 0.40000000596, -0.699999988079, 0.600000023842, -0.899999976158, 0.300000011921, -0.699999988079, 0.699999988079, -0.699999988079, 0.5, -0.20000000298, 0.40000000596, -0.600000023842, 0.40000000596, 0.0, 0.800000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.600000023842, 0.800000011921, 0.20000000298, 0.40000000596, 0.899999976158, 0.600000023842, 0.5, -0.699999988079, 0.899999976158, -0.300000011921, 0.600000023842, -0.899999976158, 0.10000000149, -0.20000000298, 0.899999976158, -0.600000023842, 0.20000000298, -0.40000000596, 0.699999988079, -0.20000000298, 0.800000011921, -0.300000011921, 0.5, -0.10000000149, 0.20000000298, -0.699999988079, 0.699999988079, -0.800000011921, 0.800000011921, -0.899999976158, 0.699999988079, 0.0, 0.899999976158, 0.899999976158, 0.899999976158, 0.699999988079, 0.699999988079, 0.600000023842, 0.40000000596, 0.20000000298, 0.40000000596, -0.800000011921, 0.10000000149, -0.699999988079, 0.40000000596, -0.40000000596, 0.5, -0.40000000596, 0.899999976158, -0.800000011921, 0.10000000149, -0.899999976158, 0.699999988079, -0.600000023842, 0.10000000149, -0.600000023842, 0.10000000149, -0.600000023842, 0.5, -0.699999988079, 0.600000023842, -0.40000000596, 0.40000000596, -0.800000011921, 0.899999976158, -0.899999976158, 0.40000000596, 0.0, 0.300000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.5, 0.10000000149, 0.5, -0.20000000298, 0.899999976158, -0.600000023842, 0.10000000149, -0.600000023842, 0.600000023842, -0.800000011921, 0.10000000149, -0.5, 0.699999988079, -0.800000011921, 0.600000023842, -0.10000000149, 0.899999976158, -0.600000023842, 0.600000023842, -0.899999976158, 0.300000011921, -0.899999976158, 0.600000023842, -0.699999988079, 0.600000023842, -0.800000011921, 0.899999976158, -0.699999988079, 0.300000011921, -0.10000000149, 0.600000023842, 0.0, 0.899999976158, 0.699999988079, 0.5, 0.300000011921, 0.20000000298, -0.800000011921, 0.899999976158, -0.300000011921, 0.899999976158, -0.40000000596, 0.600000023842, -0.699999988079, 0.10000000149, -0.10000000149, 0.800000011921, -0.10000000149, 0.10000000149, -0.10000000149, 0.10000000149, -0.40000000596, 0.10000000149, -0.10000000149, 0.40000000596, -0.800000011921, 0.300000011921, -0.899999976158, 0.20000000298, -0.40000000596, 0.699999988079, -0.600000023842, 0.800000011921, -0.40000000596, 0.899999976158, -0.699999988079, 0.5, 0.0, 0.699999988079, 0.300000011921, 0.600000023842, -0.899999976158, 0.40000000596, -0.20000000298, 0.20000000298, -0.5, 0.10000000149, -0.800000011921, 0.10000000149, -0.899999976158, 0.300000011921, -0.300000011921, 0.40000000596, -0.5, 0.800000011921, -0.600000023842, 0.800000011921, -0.10000000149, 0.10000000149, -0.800000011921, 0.899999976158, -0.5, 0.899999976158, -0.600000023842, 0.40000000596, -0.20000000298, 0.5, -0.10000000149, 0.5, -0.300000011921, 0.699999988079, -0.300000011921, 0.600000023842, 0.0, 
+
+L2_cHER_A_nn_pu
+0.899999976158, 0.0, 0.10000000149, 0.600000023842, 0.40000000596, 0.20000000298, 0.40000000596, 0.800000011921, 0.5, 0.5, 0.40000000596, 0.10000000149, 0.10000000149, 0.40000000596, 0.20000000298, 0.699999988079, 0.899999976158, 0.300000011921, 0.699999988079, 0.800000011921, 0.300000011921, 0.10000000149, 0.600000023842, 0.40000000596, 0.5, 0.699999988079, 0.40000000596, 0.800000011921, 0.5, 0.20000000298, 0.20000000298, 0.800000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.0, 0.5, 0.40000000596, 0.10000000149, 0.600000023842, 0.600000023842, 0.300000011921, 0.5, 0.5, 0.699999988079, 0.699999988079, 0.40000000596, 0.600000023842, 0.300000011921, 0.40000000596, 0.899999976158, 0.699999988079, 0.800000011921, 0.699999988079, 0.600000023842, 0.300000011921, 0.899999976158, 0.300000011921, 0.10000000149, 0.699999988079, 0.899999976158, 0.600000023842, 0.899999976158, 0.300000011921, 0.40000000596, 0.20000000298, 0.10000000149, 0.0, 0.20000000298, 0.300000011921, 0.600000023842, 0.5, 0.600000023842, 0.5, 0.20000000298, 0.20000000298, 0.5, 0.300000011921, 0.699999988079, 0.800000011921, 0.800000011921, 0.5, 0.10000000149, 0.899999976158, 0.699999988079, 0.300000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.40000000596, 0.10000000149, 0.600000023842, 0.899999976158, 0.40000000596, 0.20000000298, 0.5, 0.300000011921, 0.0, 0.899999976158, 0.10000000149, 0.20000000298, 0.899999976158, 0.300000011921, 0.10000000149, 0.300000011921, 0.10000000149, 0.699999988079, 0.300000011921, 0.10000000149, 0.899999976158, 0.20000000298, 0.20000000298, 0.10000000149, 0.10000000149, 0.10000000149, 0.20000000298, 0.5, 0.40000000596, 0.600000023842, 0.800000011921, 0.600000023842, 0.699999988079, 0.10000000149, 0.800000011921, 0.600000023842, 0.0, 0.800000011921, 0.10000000149, 0.800000011921, 0.899999976158, 0.300000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.800000011921, 0.600000023842, 0.10000000149, 0.300000011921, 0.20000000298, 0.40000000596, 0.899999976158, 0.600000023842, 0.899999976158, 0.800000011921, 0.10000000149, 0.5, 0.10000000149, 0.10000000149, 0.10000000149, 0.899999976158, 0.899999976158, 0.0, 0.5, 0.699999988079, 0.800000011921, 0.20000000298, 0.800000011921, 0.5, 0.20000000298, 0.800000011921, 0.800000011921, 0.5, 0.40000000596, 0.699999988079, 0.20000000298, 0.40000000596, 0.10000000149, 0.899999976158, 0.699999988079, 0.800000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.300000011921, 0.899999976158, 0.0, 0.20000000298, 0.800000011921, 0.899999976158, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.600000023842, 0.600000023842, 0.899999976158, 0.699999988079, 0.20000000298, 0.699999988079, 0.600000023842, 0.600000023842, 0.10000000149, 0.10000000149, 0.10000000149, 0.40000000596, 0.5, 0.5, 0.0, 0.10000000149, 0.10000000149, 0.800000011921, 0.899999976158, 0.800000011921, 0.10000000149, 0.300000011921, 0.699999988079, 0.800000011921, 0.300000011921, 0.10000000149, 0.600000023842, 0.899999976158, 0.600000023842, 0.10000000149, 0.40000000596, 0.800000011921, 0.600000023842, 0.20000000298, 0.0, 0.899999976158, 0.800000011921, 0.10000000149, 0.10000000149, 0.699999988079, 0.699999988079, 0.5, 0.10000000149, 0.10000000149, 0.600000023842, 0.600000023842, 0.899999976158, 0.10000000149, 0.10000000149, 0.800000011921, 0.10000000149, 0.20000000298, 0.0, 0.600000023842, 0.5, 0.5, 0.20000000298, 0.20000000298, 0.699999988079, 0.5, 0.699999988079, 0.300000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.0, 0.40000000596, 0.600000023842, 0.699999988079, 0.800000011921, 0.600000023842, 0.40000000596, 0.600000023842, 0.699999988079, 0.300000011921, 0.899999976158, 0.899999976158, 0.5, 0.40000000596, 0.0, 0.800000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.600000023842, 0.800000011921, 0.20000000298, 0.40000000596, 0.899999976158, 0.600000023842, 0.699999988079, 0.0, 0.899999976158, 0.899999976158, 0.899999976158, 0.699999988079, 0.699999988079, 0.600000023842, 0.40000000596, 0.20000000298, 0.40000000596, 0.0, 0.300000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.5, 0.10000000149, 0.600000023842, 0.0, 0.899999976158, 0.699999988079, 0.5, 0.300000011921, 0.5, 0.0, 0.699999988079, 0.300000011921, 0.600000023842, 0.0, 
+
+L2_cHER_x_n1
+0.300000011921, 0.300000011921, 0.800000011921, 0.600000023842, 0.800000011921, 0.800000011921, 0.600000023842, 0.10000000149, 0.5, 0.10000000149, 0.800000011921, 0.300000011921, 0.20000000298, 0.20000000298, 0.40000000596, 0.10000000149, 0.800000011921, 0.800000011921, 0.40000000596, 0.5, 0.300000011921, 0.800000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.699999988079, 0.300000011921, 0.5, 0.20000000298, 0.899999976158, 0.20000000298, 0.5, 0.899999976158, 0.699999988079, 
+
+L2_cHER_x_n2
+0.300000011921, 0.300000011921, 0.0, 0.0, 0.800000011921, 0.600000023842, 0.0, 0.0, 0.800000011921, 0.800000011921, 0.0, 0.0, 0.600000023842, 0.10000000149, 0.0, 0.0, 0.5, 0.10000000149, 0.0, 0.0, 0.800000011921, 0.300000011921, 0.0, 0.0, 0.20000000298, 0.20000000298, 0.0, 0.0, 0.40000000596, 0.10000000149, 0.0, 0.0, 0.800000011921, 0.800000011921, 0.0, 0.0, 0.40000000596, 0.5, 0.0, 0.0, 0.300000011921, 0.800000011921, 0.0, 0.0, 0.600000023842, 0.40000000596, 0.0, 0.0, 0.699999988079, 0.699999988079, 0.0, 0.0, 0.300000011921, 0.5, 0.0, 0.0, 0.20000000298, 0.899999976158, 0.0, 0.0, 0.20000000298, 0.5, 0.0, 0.0, 0.899999976158, 0.699999988079, 0.0, 0.0, 
+
+L2_cHER_o_N
+1.07999999046, 0.0, 0.520000028908, 0.66000002265, 0.880000032187, 0.20000000298, 0.610000021905, 0.950000024587, 0.6800000076, 0.620000004321, 0.730000026226, 0.250000007451, 0.220000008047, 0.40000000596, 0.350000011176, 0.789999992996, 1.38000000238, 0.300000011921, 0.970000000596, 0.770000012517, 0.630000032187, -0.0500000044703, 0.900000044703, 0.460000013709, 0.920000009537, 0.699999988079, 0.640000019073, 0.740000013113, 0.830000006855, -0.00999999731779, 0.410000012219, 0.710000009239, 1.08000003219, 0.959999974966, 0.520000028908, -0.66000002265, 1.3000000596, 0.0, 1.6200000453, 0.240000013113, 0.640000030994, 0.880000050068, 1.06000003308, 0.520000021458, 1.32000003338, 0.740000013113, 0.979999999404, 0.659999989867, 0.780000018775, 0.760000034571, 1.42000005722, 0.240000013113, 1.51999999762, 0.539999995232, 1.52000005126, 0.239999983311, 1.32000006318, 0.340000030994, 1.8799999845, 0.16000002265, 0.640000026524, 0.479999996424, 1.59999998808, 3.87430194593e-08, 1.35999999285, 0.020000012517, 1.54000000715, 0.180000011325, 0.880000032187, -0.20000000298, 1.6200000453, -0.240000013113, 1.38000003964, 0.0, 0.76000003159, 0.700000035763, 1.08000003219, 0.820000003576, 1.48000005603, 0.90000000596, 0.520000012517, 0.20000000298, 0.900000011921, 0.540000019073, 1.98000002623, 0.800000011921, 1.52000002742, 0.420000003576, 0.980000033677, 0.499999970198, 1.50000002384, 0.46000002861, 1.72000002146, 0.899999976158, 1.04000002503, 0.240000013113, 0.979999997914, 0.0400000369549, 1.45999998689, 0.160000004768, 1.47999999344, 0.659999992847, 0.610000021905, -0.950000024587, 0.640000030994, -0.880000050068, 0.76000003159, -0.700000035763, 0.670000040829, 0.0, 1.20999998838, 0.0899999989569, 0.710000030845, 0.799999964237, 0.440000019073, -4.47034842477e-09, 0.550000025332, 0.079999999404, 1.26000001669, -0.100000011921, 0.390000015348, 0.639999965429, 0.46000001967, -0.250000021607, 0.500000031292, -0.0800000083447, 0.590000010878, -0.150000006706, 0.73000001505, 0.129999995679, 0.810000029355, 0.280000005364, 0.770000031143, 0.419999976754, 0.710000008494, 0.470000001341, 0.6800000076, -0.620000004321, 1.06000003308, -0.520000021458, 1.08000003219, -0.820000003576, 1.20999998838, -0.0899999989569, 0.86000002414, 0.0, 1.23000001952, 0.0299999979138, 0.920000014007, 0.819999975264, 0.510000015199, 0.689999988526, 0.580000009835, 0.0800000023842, 1.05000001565, 0.390000025034, 0.330000009835, -0.0699999924004, 0.540000016093, 0.260000006258, 1.31999997005, 0.320000029653, 1.09999998286, 0.58000001356, 0.290000001937, 0.070000012517, 0.250000003725, -0.129999997914, 0.61999998942, 0.639999981076, 0.730000026226, -0.250000007451, 1.32000003338, -0.740000013113, 1.48000005603, -0.90000000596, 0.710000030845, -0.799999964237, 1.23000001952, -0.0299999979138, 1.63000000238, 0.0, 0.720000008047, 0.599999986589, 1.1500000231, 0.240000007153, 1.68000004411, 0.0999999940395, 0.670000018477, 0.520000012517, 1.28000003815, -0.0500000119209, 1.00000003874, 0.559999992847, 0.970000006557, 0.0500000119209, 0.490000020564, 0.58999997735, 1.12999999642, 0.140000023544, 1.11000002265, -0.240000001192, 1.23000000834, 0.0100000166893, 0.220000008047, -0.40000000596, 0.979999999404, -0.659999989867, 0.520000012517, -0.20000000298, 0.440000019073, 4.47034842477e-09, 0.920000014007, -0.819999975264, 0.720000008047, -0.599999986589, 0.979999978542, 0.0, 0.30000000596, 0.860000013709, 1.21999998569, 0.699999988079, 0.780000027716, 0.780000012815, 0.420000011027, 0.500000022352, 0.800000032783, 0.93999998033, 0.979999987483, 0.20000000298, 0.859999992847, 0.56000002563, 0.820000022948, -0.0399999952316, 0.240000004172, 0.0400000011921, 0.720000003576, 0.539999998212, 0.350000011176, -0.789999992996, 0.780000018775, -0.760000034571, 0.900000011921, -0.540000019073, 0.550000025332, -0.079999999404, 0.510000015199, -0.689999988526, 1.1500000231, -0.240000007153, 0.30000000596, -0.860000013709, 0.670000005066, 0.0, 0.500000013411, -0.140000005662, 1.01000001743, 0.73999997437, 1.00000002086, -0.190000006407, 0.580000026226, 0.599999986589, 1.15000001118, 0.090000012368, 0.270000008792, 0.430000022501, 1.0699999775, 0.26000002861, 0.230000004619, 0.220000003576, 1.2300000076, 0.410000023395, 1.38000000238, -0.300000011921, 1.42000005722, -0.240000013113, 1.98000002623, -0.800000011921, 1.26000001669, 0.100000011921, 0.580000009835, -0.0800000023842, 1.68000004411, -0.0999999940395, 1.21999998569, -0.699999988079, 0.500000013411, 0.140000005662, 1.48000004113, 0.0, 1.61999999166, 0.720000015497, 0.980000033677, -0.30000000447, 1.50000002384, 0.860000004768, 1.61999999762, 0.10000000149, 0.740000020564, 0.440000030994, 1.48000002027, 0.339999989271, 0.660000012219, -0.139999999702, 2.08000000238, 0.259999994338, 0.970000000596, -0.770000012517, 1.51999999762, -0.539999995232, 1.52000002742, -0.420000003576, 0.390000015348, -0.639999965429, 1.05000001565, -0.390000025034, 0.670000018477, -0.520000012517, 0.780000027716, -0.780000012815, 1.01000001743, -0.73999997437, 1.61999999166, -0.720000015497, 0.610000007749, 0.0, 1.12000003636, 0.329999996424, 0.940000016093, 0.340000010133, 0.829999996424, 0.769999982715, 0.870000006557, 0.649999991059, 0.830000002384, 0.639999981821, 0.730000008345, 0.700000010431, 0.809999991357, 0.970000000596, 0.630000032187, 0.0500000044703, 1.52000005126, -0.239999983311, 0.980000033677, -0.499999970198, 0.46000001967, 0.250000021607, 0.330000009835, 0.0699999924004, 1.28000003815, 0.0500000119209, 0.420000011027, -0.500000022352, 1.00000002086, 0.190000006407, 0.980000033677, 0.30000000447, 1.12000003636, -0.329999996424, 0.830000027716, 0.0, 0.900000029802, 0.960000043511, 1.46999999166, 1.15000000596, 1.09000003695, 0.490000013113, 1.38000001878, 0.589999989271, 0.76000002116, 0.909999974966, 1.72999997854, 1.00999998689, 0.900000044703, -0.460000013709, 1.32000006318, -0.340000030994, 1.50000002384, -0.46000002861, 0.500000031292, 0.0800000083447, 0.540000016093, -0.260000006258, 1.00000003874, -0.559999992847, 0.800000032783, -0.93999998033, 0.580000026226, -0.599999986589, 1.50000002384, -0.860000004768, 0.940000016093, -0.340000010133, 0.900000029802, -0.960000043511, 0.920000039339, 0.0, 1.50000002086, 0.759999966025, 0.780000023246, 0.620000006557, 1.08000002623, 0.340000007153, 0.520000012517, 0.179999996424, 1.71999998271, 0.540000010133, 0.920000009537, -0.699999988079, 1.8799999845, -0.16000002265, 1.72000002146, -0.899999976158, 0.590000010878, 0.150000006706, 1.31999997005, -0.320000029653, 0.970000006557, -0.0500000119209, 0.979999987483, -0.20000000298, 1.15000001118, -0.090000012368, 1.61999999762, -0.10000000149, 0.829999996424, -0.769999982715, 1.46999999166, -1.15000000596, 1.50000002086, -0.759999966025, 1.6799999547, 0.0, 1.45999997497, 0.759999986887, 1.66999994844, 0.210000015199, 1.18999998182, 0.390000029504, 1.51999996185, 0.339999992251, 0.640000019073, -0.740000013113, 0.640000026524, -0.479999996424, 1.04000002503, -0.240000013113, 0.73000001505, -0.129999995679, 1.09999998286, -0.58000001356, 0.490000020564, -0.58999997735, 0.859999992847, -0.56000002563, 0.270000008792, -0.430000022501, 0.740000020564, -0.440000030994, 0.870000006557, -0.649999991059, 1.09000003695, -0.490000013113, 0.780000023246, -0.620000006557, 1.45999997497, -0.759999986887, 0.740000013113, 0.0, 0.810000003278, -0.070000000596, 1.1100000152, 0.35000000149, 1.11999999762, 0.339999984801, 0.830000006855, 0.00999999731779, 1.59999998808, -3.87430194593e-08, 0.979999997914, -0.0400000369549, 0.810000029355, -0.280000005364, 0.290000001937, -0.070000012517, 1.12999999642, -0.140000023544, 0.820000022948, 0.0399999952316, 1.0699999775, -0.26000002861, 1.48000002027, -0.339999989271, 0.830000002384, -0.639999981821, 1.38000001878, -0.589999989271, 1.08000002623, -0.340000007153, 1.66999994844, -0.210000015199, 0.810000003278, 0.070000000596, 1.44999998212, 0.0, 1.38999996543, 0.779999984503, 1.3099999705, 0.969999969304, 0.410000012219, -0.710000009239, 1.35999999285, -0.020000012517, 1.45999998689, -0.160000004768, 0.770000031143, -0.419999976754, 0.250000003725, 0.129999997914, 1.11000002265, 0.240000001192, 0.240000004172, -0.0400000011921, 0.230000004619, -0.220000003576, 0.660000012219, 0.139999999702, 0.730000008345, -0.700000010431, 0.76000002116, -0.909999974966, 0.520000012517, -0.179999996424, 1.18999998182, -0.390000029504, 1.1100000152, -0.35000000149, 1.38999996543, -0.779999984503, 0.790000001192, 0.0, 1.22999998003, 0.610000000298, 1.08000003219, -0.959999974966, 1.54000000715, -0.180000011325, 1.47999999344, -0.659999992847, 0.710000008494, -0.470000001341, 0.61999998942, -0.639999981076, 1.23000000834, -0.0100000166893, 0.720000003576, -0.539999998212, 1.2300000076, -0.410000023395, 2.08000000238, -0.259999994338, 0.809999991357, -0.970000000596, 1.72999997854, -1.00999998689, 1.71999998271, -0.540000010133, 1.51999996185, -0.339999992251, 1.11999999762, -0.339999984801, 1.3099999705, -0.969999969304, 1.22999998003, -0.610000000298, 1.89999996424, 0.0, 
+
+L2_cHER_o_N_pu
+1.07999999046, 0.0, 0.520000028908, 0.66000002265, 0.880000032187, 0.20000000298, 0.610000021905, 0.950000024587, 0.6800000076, 0.620000004321, 0.730000026226, 0.250000007451, 0.220000008047, 0.40000000596, 0.350000011176, 0.789999992996, 1.38000000238, 0.300000011921, 0.970000000596, 0.770000012517, 0.630000032187, -0.0500000044703, 0.900000044703, 0.460000013709, 0.920000009537, 0.699999988079, 0.640000019073, 0.740000013113, 0.830000006855, -0.00999999731779, 0.410000012219, 0.710000009239, 1.08000003219, 0.959999974966, 1.3000000596, 0.0, 1.6200000453, 0.240000013113, 0.640000030994, 0.880000050068, 1.06000003308, 0.520000021458, 1.32000003338, 0.740000013113, 0.979999999404, 0.659999989867, 0.780000018775, 0.760000034571, 1.42000005722, 0.240000013113, 1.51999999762, 0.539999995232, 1.52000005126, 0.239999983311, 1.32000006318, 0.340000030994, 1.8799999845, 0.16000002265, 0.640000026524, 0.479999996424, 1.59999998808, 3.87430194593e-08, 1.35999999285, 0.020000012517, 1.54000000715, 0.180000011325, 1.38000003964, 0.0, 0.76000003159, 0.700000035763, 1.08000003219, 0.820000003576, 1.48000005603, 0.90000000596, 0.520000012517, 0.20000000298, 0.900000011921, 0.540000019073, 1.98000002623, 0.800000011921, 1.52000002742, 0.420000003576, 0.980000033677, 0.499999970198, 1.50000002384, 0.46000002861, 1.72000002146, 0.899999976158, 1.04000002503, 0.240000013113, 0.979999997914, 0.0400000369549, 1.45999998689, 0.160000004768, 1.47999999344, 0.659999992847, 0.670000040829, 0.0, 1.20999998838, 0.0899999989569, 0.710000030845, 0.799999964237, 0.440000019073, -4.47034842477e-09, 0.550000025332, 0.079999999404, 1.26000001669, -0.100000011921, 0.390000015348, 0.639999965429, 0.46000001967, -0.250000021607, 0.500000031292, -0.0800000083447, 0.590000010878, -0.150000006706, 0.73000001505, 0.129999995679, 0.810000029355, 0.280000005364, 0.770000031143, 0.419999976754, 0.710000008494, 0.470000001341, 0.86000002414, 0.0, 1.23000001952, 0.0299999979138, 0.920000014007, 0.819999975264, 0.510000015199, 0.689999988526, 0.580000009835, 0.0800000023842, 1.05000001565, 0.390000025034, 0.330000009835, -0.0699999924004, 0.540000016093, 0.260000006258, 1.31999997005, 0.320000029653, 1.09999998286, 0.58000001356, 0.290000001937, 0.070000012517, 0.250000003725, -0.129999997914, 0.61999998942, 0.639999981076, 1.63000000238, 0.0, 0.720000008047, 0.599999986589, 1.1500000231, 0.240000007153, 1.68000004411, 0.0999999940395, 0.670000018477, 0.520000012517, 1.28000003815, -0.0500000119209, 1.00000003874, 0.559999992847, 0.970000006557, 0.0500000119209, 0.490000020564, 0.58999997735, 1.12999999642, 0.140000023544, 1.11000002265, -0.240000001192, 1.23000000834, 0.0100000166893, 0.979999978542, 0.0, 0.30000000596, 0.860000013709, 1.21999998569, 0.699999988079, 0.780000027716, 0.780000012815, 0.420000011027, 0.500000022352, 0.800000032783, 0.93999998033, 0.979999987483, 0.20000000298, 0.859999992847, 0.56000002563, 0.820000022948, -0.0399999952316, 0.240000004172, 0.0400000011921, 0.720000003576, 0.539999998212, 0.670000005066, 0.0, 0.500000013411, -0.140000005662, 1.01000001743, 0.73999997437, 1.00000002086, -0.190000006407, 0.580000026226, 0.599999986589, 1.15000001118, 0.090000012368, 0.270000008792, 0.430000022501, 1.0699999775, 0.26000002861, 0.230000004619, 0.220000003576, 1.2300000076, 0.410000023395, 1.48000004113, 0.0, 1.61999999166, 0.720000015497, 0.980000033677, -0.30000000447, 1.50000002384, 0.860000004768, 1.61999999762, 0.10000000149, 0.740000020564, 0.440000030994, 1.48000002027, 0.339999989271, 0.660000012219, -0.139999999702, 2.08000000238, 0.259999994338, 0.610000007749, 0.0, 1.12000003636, 0.329999996424, 0.940000016093, 0.340000010133, 0.829999996424, 0.769999982715, 0.870000006557, 0.649999991059, 0.830000002384, 0.639999981821, 0.730000008345, 0.700000010431, 0.809999991357, 0.970000000596, 0.830000027716, 0.0, 0.900000029802, 0.960000043511, 1.46999999166, 1.15000000596, 1.09000003695, 0.490000013113, 1.38000001878, 0.589999989271, 0.76000002116, 0.909999974966, 1.72999997854, 1.00999998689, 0.920000039339, 0.0, 1.50000002086, 0.759999966025, 0.780000023246, 0.620000006557, 1.08000002623, 0.340000007153, 0.520000012517, 0.179999996424, 1.71999998271, 0.540000010133, 1.6799999547, 0.0, 1.45999997497, 0.759999986887, 1.66999994844, 0.210000015199, 1.18999998182, 0.390000029504, 1.51999996185, 0.339999992251, 0.740000013113, 0.0, 0.810000003278, -0.070000000596, 1.1100000152, 0.35000000149, 1.11999999762, 0.339999984801, 1.44999998212, 0.0, 1.38999996543, 0.779999984503, 1.3099999705, 0.969999969304, 0.790000001192, 0.0, 1.22999998003, 0.610000000298, 1.89999996424, 0.0, 
+
+L2_zHER_A_nn
+0.9, 0.0, 0.8, 0.4, 0.6, 0.1, 0.9, 0.1, 0.8, 0.9, 0.4, 0.6, 0.2, 0.8, 0.6, 0.7, 0.5, 0.2, 0.8, 0.8, 0.4, 0.1, 0.1, 0.5, 0.7, 0.5, 0.2, 0.4, 0.3, 0.9, 0.7, 0.3, 0.3, 0.2, 0.8, -0.4, 0.4, 0.0, 0.5, 0.6, 0.8, 0.2, 0.7, 0.7, 0.6, 0.8, 0.7, 0.6, 0.1, 0.7, 0.6, 0.6, 0.8, 0.2, 0.3, 0.8, 0.3, 0.5, 0.4, 0.9, 0.3, 0.3, 0.1, 0.9, 0.3, 0.5, 0.6, 0.2, 0.6, -0.1, 0.5, -0.6, 0.2, 0.0, 0.2, 0.9, 0.4, 0.1, 0.5, 0.5, 0.4, 0.7, 0.1, 0.9, 0.5, 0.2, 0.2, 0.7, 0.5, 0.2, 0.7, 0.7, 0.8, 0.5, 0.8, 0.4, 0.1, 0.6, 0.7, 0.1, 0.8, 0.8, 0.9, -0.1, 0.8, -0.2, 0.2, -0.9, 0.5, 0.0, 0.8, 0.3, 0.3, 0.4, 0.1, 0.3, 0.6, 0.7, 0.4, 0.9, 0.4, 0.5, 0.4, 0.2, 0.7, 0.8, 0.5, 0.1, 0.4, 0.9, 0.7, 0.1, 0.2, 0.3, 0.8, 0.4, 0.8, -0.9, 0.7, -0.7, 0.4, -0.1, 0.8, -0.3, 0.6, 0.0, 0.6, 0.5, 0.8, 0.2, 0.6, 0.4, 0.3, 0.5, 0.2, 0.2, 0.5, 0.9, 0.1, 0.5, 0.2, 0.2, 0.9, 0.9, 0.5, 0.7, 0.6, 0.3, 0.3, 0.8, 0.4, -0.6, 0.6, -0.8, 0.5, -0.5, 0.3, -0.4, 0.6, -0.5, 0.7, 0.0, 0.3, 0.4, 0.4, 0.7, 0.9, 0.2, 0.3, 0.6, 0.2, 0.6, 0.9, 0.3, 0.1, 0.3, 0.7, 0.9, 0.7, 0.8, 0.9, 0.7, 0.3, 0.3, 0.2, -0.8, 0.7, -0.6, 0.4, -0.7, 0.1, -0.3, 0.8, -0.2, 0.3, -0.4, 0.3, 0.0, 0.5, 0.9, 0.2, 0.9, 0.4, 0.6, 0.2, 0.3, 0.7, 0.8, 0.5, 0.3, 0.3, 0.1, 0.5, 0.6, 0.4, 0.7, 0.8, 0.3, 0.6, -0.7, 0.1, -0.7, 0.1, -0.9, 0.6, -0.7, 0.6, -0.4, 0.4, -0.7, 0.5, -0.9, 0.8, 0.0, 0.2, 0.3, 0.5, 0.5, 0.6, 0.8, 0.2, 0.2, 0.3, 0.6, 0.8, 0.4, 0.2, 0.7, 0.5, 0.3, 0.5, 0.9, 0.5, -0.2, 0.6, -0.6, 0.5, -0.2, 0.4, -0.9, 0.3, -0.5, 0.9, -0.2, 0.2, -0.9, 0.2, -0.3, 0.5, 0.0, 0.4, 0.9, 0.8, 0.2, 0.1, 0.1, 0.6, 0.1, 0.8, 0.3, 0.9, 0.4, 0.1, 0.4, 0.8, 0.7, 0.8, -0.8, 0.8, -0.2, 0.2, -0.7, 0.4, -0.5, 0.2, -0.2, 0.3, -0.6, 0.4, -0.6, 0.5, -0.5, 0.4, -0.9, 0.3, 0.0, 0.1, 0.2, 0.8, 0.2, 0.9, 0.2, 0.8, 0.5, 0.4, 0.8, 0.4, 0.1, 0.6, 0.4, 0.4, -0.1, 0.3, -0.8, 0.5, -0.2, 0.4, -0.2, 0.5, -0.9, 0.2, -0.6, 0.2, -0.3, 0.6, -0.8, 0.8, -0.2, 0.1, -0.2, 0.1, 0.0, 0.7, 0.3, 0.8, 0.3, 0.1, 0.6, 0.8, 0.8, 0.3, 0.1, 0.1, 0.5, 0.1, -0.5, 0.3, -0.5, 0.7, -0.7, 0.7, -0.8, 0.1, -0.5, 0.9, -0.3, 0.7, -0.8, 0.2, -0.2, 0.1, -0.1, 0.8, -0.2, 0.7, -0.3, 0.1, 0.0, 0.5, 0.2, 0.6, 0.9, 0.1, 0.5, 0.9, 0.3, 0.2, 0.7, 0.7, -0.5, 0.4, -0.9, 0.8, -0.5, 0.5, -0.1, 0.2, -0.2, 0.1, -0.3, 0.5, -0.3, 0.3, -0.6, 0.6, -0.1, 0.9, -0.2, 0.8, -0.3, 0.5, -0.2, 0.4, 0.0, 0.5, 0.8, 0.7, 0.3, 0.7, 0.8, 0.4, 0.5, 0.2, -0.4, 0.3, -0.3, 0.8, -0.4, 0.4, -0.9, 0.9, -0.9, 0.7, -0.9, 0.3, -0.1, 0.8, -0.4, 0.8, -0.3, 0.8, -0.5, 0.1, -0.6, 0.6, -0.9, 0.5, -0.8, 0.8, 0.0, 0.3, 0.1, 0.4, 0.6, 0.1, 0.9, 0.3, -0.9, 0.1, -0.9, 0.1, -0.6, 0.7, -0.1, 0.5, -0.7, 0.7, -0.8, 0.5, -0.6, 0.2, -0.7, 0.9, -0.4, 0.4, -0.8, 0.8, -0.8, 0.1, -0.5, 0.7, -0.3, 0.3, -0.1, 0.4, 0.0, 0.7, 0.1, 0.2, 0.4, 0.7, -0.3, 0.3, -0.5, 0.7, -0.1, 0.2, -0.3, 0.6, -0.3, 0.9, -0.7, 0.4, -0.7, 0.5, -0.3, 0.1, -0.4, 0.4, -0.1, 0.3, -0.1, 0.9, -0.3, 0.7, -0.8, 0.4, -0.6, 0.7, -0.1, 0.3, 0.0, 0.3, 0.9, 0.3, -0.2, 0.6, -0.2, 0.8, -0.8, 0.8, -0.4, 0.3, -0.8, 0.3, -0.3, 0.8, -0.3, 0.5, -0.9, 0.8, -0.7, 0.6, -0.4, 0.1, -0.5, 0.2, -0.7, 0.4, -0.5, 0.1, -0.9, 0.2, -0.4, 0.3, -0.9, 0.1, 0.0, 
+
+L2_zHER_A_nn_pu
+0.9, 0.0, 0.8, 0.4, 0.6, 0.1, 0.9, 0.1, 0.8, 0.9, 0.4, 0.6, 0.2, 0.8, 0.6, 0.7, 0.5, 0.2, 0.8, 0.8, 0.4, 0.1, 0.1, 0.5, 0.7, 0.5, 0.2, 0.4, 0.3, 0.9, 0.7, 0.3, 0.3, 0.2, 0.4, 0.0, 0.5, 0.6, 0.8, 0.2, 0.7, 0.7, 0.6, 0.8, 0.7, 0.6, 0.1, 0.7, 0.6, 0.6, 0.8, 0.2, 0.3, 0.8, 0.3, 0.5, 0.4, 0.9, 0.3, 0.3, 0.1, 0.9, 0.3, 0.5, 0.6, 0.2, 0.2, 0.0, 0.2, 0.9, 0.4, 0.1, 0.5, 0.5, 0.4, 0.7, 0.1, 0.9, 0.5, 0.2, 0.2, 0.7, 0.5, 0.2, 0.7, 0.7, 0.8, 0.5, 0.8, 0.4, 0.1, 0.6, 0.7, 0.1, 0.8, 0.8, 0.5, 0.0, 0.8, 0.3, 0.3, 0.4, 0.1, 0.3, 0.6, 0.7, 0.4, 0.9, 0.4, 0.5, 0.4, 0.2, 0.7, 0.8, 0.5, 0.1, 0.4, 0.9, 0.7, 0.1, 0.2, 0.3, 0.8, 0.4, 0.6, 0.0, 0.6, 0.5, 0.8, 0.2, 0.6, 0.4, 0.3, 0.5, 0.2, 0.2, 0.5, 0.9, 0.1, 0.5, 0.2, 0.2, 0.9, 0.9, 0.5, 0.7, 0.6, 0.3, 0.3, 0.8, 0.7, 0.0, 0.3, 0.4, 0.4, 0.7, 0.9, 0.2, 0.3, 0.6, 0.2, 0.6, 0.9, 0.3, 0.1, 0.3, 0.7, 0.9, 0.7, 0.8, 0.9, 0.7, 0.3, 0.3, 0.3, 0.0, 0.5, 0.9, 0.2, 0.9, 0.4, 0.6, 0.2, 0.3, 0.7, 0.8, 0.5, 0.3, 0.3, 0.1, 0.5, 0.6, 0.4, 0.7, 0.8, 0.3, 0.8, 0.0, 0.2, 0.3, 0.5, 0.5, 0.6, 0.8, 0.2, 0.2, 0.3, 0.6, 0.8, 0.4, 0.2, 0.7, 0.5, 0.3, 0.5, 0.9, 0.5, 0.0, 0.4, 0.9, 0.8, 0.2, 0.1, 0.1, 0.6, 0.1, 0.8, 0.3, 0.9, 0.4, 0.1, 0.4, 0.8, 0.7, 0.3, 0.0, 0.1, 0.2, 0.8, 0.2, 0.9, 0.2, 0.8, 0.5, 0.4, 0.8, 0.4, 0.1, 0.6, 0.4, 0.1, 0.0, 0.7, 0.3, 0.8, 0.3, 0.1, 0.6, 0.8, 0.8, 0.3, 0.1, 0.1, 0.5, 0.1, 0.0, 0.5, 0.2, 0.6, 0.9, 0.1, 0.5, 0.9, 0.3, 0.2, 0.7, 0.4, 0.0, 0.5, 0.8, 0.7, 0.3, 0.7, 0.8, 0.4, 0.5, 0.8, 0.0, 0.3, 0.1, 0.4, 0.6, 0.1, 0.9, 0.4, 0.0, 0.7, 0.1, 0.2, 0.4, 0.3, 0.0, 0.3, 0.9, 0.1, 0.0, 
+
+L2_zHER_x_n1
+0.4, 0.2, 0.7, 0.9, 0.7, 0.3, 0.5, 0.8, 0.9, 0.6, 0.3, 0.7, 0.6, 0.1, 0.9, 0.2, 0.3, 0.7, 0.9, 0.9, 0.2, 0.3, 0.2, 0.7, 0.8, 0.8, 0.2, 0.5, 0.5, 0.5, 0.8, 0.3, 0.9, 0.1, 
+
+L2_zHER_x_n2
+0.4, 0.2, 0.0, 0.0, 0.7, 0.9, 0.0, 0.0, 0.7, 0.3, 0.0, 0.0, 0.5, 0.8, 0.0, 0.0, 0.9, 0.6, 0.0, 0.0, 0.3, 0.7, 0.0, 0.0, 0.6, 0.1, 0.0, 0.0, 0.9, 0.2, 0.0, 0.0, 0.3, 0.7, 0.0, 0.0, 0.9, 0.9, 0.0, 0.0, 0.2, 0.3, 0.0, 0.0, 0.2, 0.7, 0.0, 0.0, 0.8, 0.8, 0.0, 0.0, 0.2, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.8, 0.3, 0.0, 0.0, 0.9, 0.1, 0.0, 0.0, 
+
+L2_zHER_o_N
+1.1, 0.0, 1.26, 0.18, 0.94, 0.12, 1.26, -0.12, 1.28, 0.84, 0.66, 0.38, 0.46, 0.88, 1.0, 0.8, 0.76, -0.02, 1.34, 0.62, 0.54, 0.02, 0.32, 0.26, 1.18, 0.34, 0.38, 0.24, 0.6, 0.8, 1.08, 0.34, 0.68, 0.34, 1.26, -0.18, 1.7, 0.0, 1.26, 1.02, 1.87, 0.09, 1.87, 1.09, 1.44, 0.58, 1.21, 1.07, 0.91, 1.37, 1.44, 0.38, 2.24, 0.38, 0.71, 0.77, 1.07, 0.19, 1.68, 1.06, 0.89, 0.13, 0.9, 1.0, 1.13, 1.01, 1.32, 0.94, 0.94, -0.12, 1.26, -1.02, 0.78, 0.0, 0.79, 0.49, 1.21, -0.05, 0.92, 0.1, 0.85, 0.81, 0.79, 1.03, 0.92, -0.2, 1.1, 0.34, 0.73, 0.05, 1.05, 0.27, 1.6, 0.18, 1.09, 0.11, 0.6, 0.4, 1.35, 0.13, 1.46, 1.0, 1.26, 0.12, 1.87, -0.09, 0.79, -0.49, 1.39, 0.0, 1.73, 0.72, 1.01, 0.29, 0.48, 0.73, 1.21, 1.32, 1.11, 0.79, 1.57, 0.77, 0.74, 0.21, 1.36, 0.61, 1.54, 0.34, 0.9, 0.81, 1.35, 0.25, 0.84, 0.79, 1.33, 1.07, 1.28, -0.84, 1.87, -1.09, 1.21, 0.05, 1.73, -0.72, 1.77, 0.0, 1.29, 0.05, 1.4, 0.47, 1.53, 0.76, 0.99, 0.05, 1.55, -0.07, 0.86, 0.75, 0.7, -0.01, 1.4, -0.04, 1.38, 0.57, 1.25, 0.55, 1.5, 0.51, 1.17, 1.25, 0.66, -0.38, 1.44, -0.58, 0.92, -0.1, 1.01, -0.29, 1.29, -0.05, 1.28, 0.0, 0.55, 0.79, 0.81, 1.27, 1.48, 0.2, 1.2, 0.96, 0.47, 0.65, 1.45, 0.23, 0.9, 0.62, 1.11, 0.89, 1.2, 1.0, 1.35, 1.17, 0.64, 0.9, 0.46, -0.88, 1.21, -1.07, 0.85, -0.81, 0.48, -0.73, 1.4, -0.47, 0.55, -0.79, 0.67, 0.0, 1.06, 0.87, 0.45, 0.51, 1.03, 0.15, 0.35, 0.14, 0.89, 0.4, 1.06, -0.1, 0.47, -0.18, 0.85, 0.35, 0.91, 0.6, 1.35, 0.33, 1.0, -0.8, 0.91, -1.37, 0.79, -1.03, 1.21, -1.32, 1.53, -0.76, 0.81, -1.27, 1.06, -0.87, 1.65, 0.0, 0.61, -0.27, 1.49, -0.13, 0.84, 0.57, 0.52, -0.39, 1.18, 0.04, 1.08, -0.01, 0.75, 0.35, 1.28, 0.19, 1.33, 0.99, 0.76, 0.02, 1.44, -0.38, 0.92, 0.2, 1.11, -0.79, 0.99, -0.05, 1.48, -0.2, 0.45, -0.51, 0.61, 0.27, 1.08, 0.0, 1.3, 1.26, 1.07, 0.25, 0.65, 0.03, 1.4, 0.42, 1.21, 0.29, 1.4, 0.6, 0.55, 0.87, 1.14, 1.3, 1.34, -0.62, 2.24, -0.38, 1.1, -0.34, 1.57, -0.77, 1.55, 0.07, 1.2, -0.96, 1.03, -0.15, 1.49, 0.13, 1.3, -1.26, 1.92, 0.0, 0.55, 0.11, 1.61, -0.25, 2.34, 0.2, 1.43, 0.23, 1.3, 0.8, 1.39, 0.55, 1.5, 1.12, 0.54, -0.02, 0.71, -0.77, 0.73, -0.05, 0.74, -0.21, 0.86, -0.75, 0.47, -0.65, 0.35, -0.14, 0.84, -0.57, 1.07, -0.25, 0.55, -0.11, 0.23, 0.0, 0.95, 0.22, 1.2, 0.38, 0.29, 0.56, 1.05, 0.85, 0.55, 0.28, 0.31, 0.75, 0.32, -0.26, 1.07, -0.19, 1.05, -0.27, 1.36, -0.61, 0.7, 0.01, 1.45, -0.23, 0.89, -0.4, 0.52, 0.39, 0.65, -0.03, 1.61, 0.25, 0.95, -0.22, 0.63, 0.0, 1.22, 0.6, 0.99, 0.94, 0.55, 0.75, 1.27, 0.8, 0.45, 1.31, 1.18, -0.34, 1.68, -1.06, 1.6, -0.18, 1.54, -0.34, 1.4, 0.04, 0.9, -0.62, 1.06, 0.1, 1.18, -0.04, 1.4, -0.42, 2.34, -0.2, 1.2, -0.38, 1.22, -0.6, 1.68, 0.0, 1.06, 0.56, 1.5, 0.3, 1.58, 1.2, 1.2, 1.14, 0.38, -0.24, 0.89, -0.13, 1.09, -0.11, 0.9, -0.81, 1.38, -0.57, 1.11, -0.89, 0.47, 0.18, 1.08, 0.01, 1.21, -0.29, 1.43, -0.23, 0.29, -0.56, 0.99, -0.94, 1.06, -0.56, 1.09, 0.0, 0.65, 0.25, 0.71, 0.94, 0.33, 1.33, 0.6, -0.8, 0.9, -1.0, 0.6, -0.4, 1.35, -0.25, 1.25, -0.55, 1.2, -1.0, 0.85, -0.35, 0.75, -0.35, 1.4, -0.6, 1.3, -0.8, 1.05, -0.85, 0.55, -0.75, 1.5, -0.3, 0.65, -0.25, 0.9, 0.0, 1.25, 0.35, 0.7, 0.8, 1.08, -0.34, 1.13, -1.01, 1.35, -0.13, 0.84, -0.79, 1.5, -0.51, 1.35, -1.17, 0.91, -0.6, 1.28, -0.19, 0.55, -0.87, 1.39, -0.55, 0.55, -0.28, 1.27, -0.8, 1.58, -1.2, 0.71, -0.94, 1.25, -0.35, 1.03, 0.0, 1.05, 1.09, 0.68, -0.34, 1.32, -0.94, 1.46, -1.0, 1.33, -1.07, 1.17, -1.25, 0.64, -0.9, 1.35, -0.33, 1.33, -0.99, 1.14, -1.3, 1.5, -1.12, 0.31, -0.75, 0.45, -1.31, 1.2, -1.14, 0.33, -1.33, 0.7, -0.8, 1.05, -1.09, 0.92, 0.0, 
+
+L2_zHER_o_N_pu
+1.1, 0.0, 1.26, 0.18, 0.94, 0.12, 1.26, -0.12, 1.28, 0.84, 0.66, 0.38, 0.46, 0.88, 1.0, 0.8, 0.76, -0.02, 1.34, 0.62, 0.54, 0.02, 0.32, 0.26, 1.18, 0.34, 0.38, 0.24, 0.6, 0.8, 1.08, 0.34, 0.68, 0.34, 1.7, 0.0, 1.26, 1.02, 1.87, 0.09, 1.87, 1.09, 1.44, 0.58, 1.21, 1.07, 0.91, 1.37, 1.44, 0.38, 2.24, 0.38, 0.71, 0.77, 1.07, 0.19, 1.68, 1.06, 0.89, 0.13, 0.9, 1.0, 1.13, 1.01, 1.32, 0.94, 0.78, 0.0, 0.79, 0.49, 1.21, -0.05, 0.92, 0.1, 0.85, 0.81, 0.79, 1.03, 0.92, -0.2, 1.1, 0.34, 0.73, 0.05, 1.05, 0.27, 1.6, 0.18, 1.09, 0.11, 0.6, 0.4, 1.35, 0.13, 1.46, 1.0, 1.39, 0.0, 1.73, 0.72, 1.01, 0.29, 0.48, 0.73, 1.21, 1.32, 1.11, 0.79, 1.57, 0.77, 0.74, 0.21, 1.36, 0.61, 1.54, 0.34, 0.9, 0.81, 1.35, 0.25, 0.84, 0.79, 1.33, 1.07, 1.77, 0.0, 1.29, 0.05, 1.4, 0.47, 1.53, 0.76, 0.99, 0.05, 1.55, -0.07, 0.86, 0.75, 0.7, -0.01, 1.4, -0.04, 1.38, 0.57, 1.25, 0.55, 1.5, 0.51, 1.17, 1.25, 1.28, 0.0, 0.55, 0.79, 0.81, 1.27, 1.48, 0.2, 1.2, 0.96, 0.47, 0.65, 1.45, 0.23, 0.9, 0.62, 1.11, 0.89, 1.2, 1.0, 1.35, 1.17, 0.64, 0.9, 0.67, 0.0, 1.06, 0.87, 0.45, 0.51, 1.03, 0.15, 0.35, 0.14, 0.89, 0.4, 1.06, -0.1, 0.47, -0.18, 0.85, 0.35, 0.91, 0.6, 1.35, 0.33, 1.65, 0.0, 0.61, -0.27, 1.49, -0.13, 0.84, 0.57, 0.52, -0.39, 1.18, 0.04, 1.08, -0.01, 0.75, 0.35, 1.28, 0.19, 1.33, 0.99, 1.08, 0.0, 1.3, 1.26, 1.07, 0.25, 0.65, 0.03, 1.4, 0.42, 1.21, 0.29, 1.4, 0.6, 0.55, 0.87, 1.14, 1.3, 1.92, 0.0, 0.55, 0.11, 1.61, -0.25, 2.34, 0.2, 1.43, 0.23, 1.3, 0.8, 1.39, 0.55, 1.5, 1.12, 0.23, 0.0, 0.95, 0.22, 1.2, 0.38, 0.29, 0.56, 1.05, 0.85, 0.55, 0.28, 0.31, 0.75, 0.63, 0.0, 1.22, 0.6, 0.99, 0.94, 0.55, 0.75, 1.27, 0.8, 0.45, 1.31, 1.68, 0.0, 1.06, 0.56, 1.5, 0.3, 1.58, 1.2, 1.2, 1.14, 1.09, 0.0, 0.65, 0.25, 0.71, 0.94, 0.33, 1.33, 0.9, 0.0, 1.25, 0.35, 0.7, 0.8, 1.03, 0.0, 1.05, 1.09, 0.92, 0.0, 
+
+L2_cHER2_A_nn
+0.699999988079, 0.0, 0.300000011921, 0.40000000596, 0.40000000596, 0.40000000596, 0.40000000596, 0.20000000298, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.899999976158, 0.699999988079, 0.600000023842, 0.5, 0.800000011921, 0.40000000596, 0.699999988079, 0.899999976158, 0.800000011921, 0.600000023842, 0.699999988079, 0.600000023842, 0.600000023842, 0.40000000596, 0.699999988079, 0.300000011921, 0.899999976158, 0.10000000149, 0.40000000596, 0.10000000149, 0.40000000596, 0.300000011921, 0.300000011921, -0.40000000596, 0.5, 0.0, 0.20000000298, 0.600000023842, 0.600000023842, 0.800000011921, 0.300000011921, 0.899999976158, 0.699999988079, 0.699999988079, 0.20000000298, 0.10000000149, 0.5, 0.800000011921, 0.800000011921, 0.800000011921, 0.20000000298, 0.20000000298, 0.10000000149, 0.899999976158, 0.600000023842, 0.300000011921, 0.600000023842, 0.800000011921, 0.10000000149, 0.20000000298, 0.800000011921, 0.10000000149, 0.10000000149, 0.899999976158, 0.40000000596, 0.40000000596, 0.40000000596, -0.40000000596, 0.20000000298, -0.600000023842, 0.5, 0.0, 0.10000000149, 0.899999976158, 0.40000000596, 0.10000000149, 0.600000023842, 0.20000000298, 0.40000000596, 0.40000000596, 0.899999976158, 0.699999988079, 0.800000011921, 0.300000011921, 0.300000011921, 0.5, 0.600000023842, 0.10000000149, 0.600000023842, 0.800000011921, 0.40000000596, 0.20000000298, 0.600000023842, 0.300000011921, 0.5, 0.20000000298, 0.10000000149, 0.800000011921, 0.699999988079, 0.300000011921, 0.40000000596, -0.20000000298, 0.600000023842, -0.800000011921, 0.10000000149, -0.899999976158, 0.800000011921, 0.0, 0.300000011921, 0.20000000298, 0.800000011921, 0.899999976158, 0.5, 0.10000000149, 0.800000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.10000000149, 0.899999976158, 0.40000000596, 0.800000011921, 0.40000000596, 0.20000000298, 0.40000000596, 0.10000000149, 0.699999988079, 0.800000011921, 0.40000000596, 0.10000000149, 0.20000000298, 0.699999988079, 0.10000000149, 0.300000011921, 0.600000023842, -0.899999976158, 0.300000011921, -0.899999976158, 0.40000000596, -0.10000000149, 0.300000011921, -0.20000000298, 0.10000000149, 0.0, 0.899999976158, 0.20000000298, 0.10000000149, 0.600000023842, 0.5, 0.20000000298, 0.600000023842, 0.800000011921, 0.600000023842, 0.20000000298, 0.5, 0.5, 0.20000000298, 0.800000011921, 0.10000000149, 0.5, 0.20000000298, 0.800000011921, 0.10000000149, 0.20000000298, 0.800000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.300000011921, -0.10000000149, 0.699999988079, -0.699999988079, 0.600000023842, -0.20000000298, 0.800000011921, -0.899999976158, 0.899999976158, -0.20000000298, 0.800000011921, 0.0, 0.600000023842, 0.600000023842, 0.899999976158, 0.20000000298, 0.800000011921, 0.5, 0.899999976158, 0.699999988079, 0.40000000596, 0.899999976158, 0.300000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.10000000149, 0.40000000596, 0.5, 0.699999988079, 0.5, 0.600000023842, 0.40000000596, 0.10000000149, 0.899999976158, -0.699999988079, 0.20000000298, -0.10000000149, 0.40000000596, -0.40000000596, 0.5, -0.10000000149, 0.10000000149, -0.600000023842, 0.600000023842, -0.600000023842, 0.899999976158, 0.0, 0.899999976158, 0.20000000298, 0.800000011921, 0.699999988079, 0.300000011921, 0.10000000149, 0.5, 0.699999988079, 0.5, 0.40000000596, 0.5, 0.20000000298, 0.40000000596, 0.10000000149, 0.800000011921, 0.699999988079, 0.5, 0.699999988079, 0.10000000149, 0.800000011921, 0.600000023842, -0.5, 0.5, -0.800000011921, 0.899999976158, -0.699999988079, 0.800000011921, -0.699999988079, 0.5, -0.20000000298, 0.899999976158, -0.20000000298, 0.899999976158, -0.20000000298, 0.10000000149, 0.0, 0.40000000596, 0.699999988079, 0.699999988079, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.899999976158, 0.899999976158, 0.800000011921, 0.800000011921, 0.10000000149, 0.800000011921, 0.5, 0.600000023842, 0.699999988079, 0.40000000596, 0.800000011921, -0.40000000596, 0.800000011921, -0.800000011921, 0.800000011921, -0.300000011921, 0.699999988079, -0.899999976158, 0.600000023842, -0.800000011921, 0.800000011921, -0.5, 0.800000011921, -0.699999988079, 0.40000000596, -0.699999988079, 0.5, 0.0, 0.10000000149, 0.300000011921, 0.5, 0.699999988079, 0.20000000298, 0.10000000149, 0.10000000149, 0.300000011921, 0.10000000149, 0.40000000596, 0.899999976158, 0.600000023842, 0.20000000298, 0.899999976158, 0.40000000596, 0.300000011921, 0.699999988079, -0.899999976158, 0.20000000298, -0.20000000298, 0.300000011921, -0.5, 0.10000000149, -0.899999976158, 0.600000023842, -0.20000000298, 0.899999976158, -0.699999988079, 0.300000011921, -0.10000000149, 0.699999988079, -0.5, 0.10000000149, -0.300000011921, 0.899999976158, 0.0, 0.899999976158, 0.899999976158, 0.800000011921, 0.899999976158, 0.699999988079, 0.800000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.5, 0.899999976158, 0.300000011921, 0.699999988079, 0.5, 0.800000011921, -0.600000023842, 0.10000000149, -0.899999976158, 0.600000023842, -0.10000000149, 0.40000000596, -0.800000011921, 0.5, -0.5, 0.40000000596, -0.899999976158, 0.5, -0.699999988079, 0.300000011921, -0.899999976158, 0.5, -0.699999988079, 0.899999976158, -0.899999976158, 0.300000011921, 0.0, 0.5, 0.20000000298, 0.20000000298, 0.899999976158, 0.300000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.699999988079, -0.600000023842, 0.600000023842, -0.300000011921, 0.600000023842, -0.800000011921, 0.40000000596, -0.20000000298, 0.20000000298, -0.800000011921, 0.300000011921, -0.699999988079, 0.5, -0.40000000596, 0.40000000596, -0.800000011921, 0.20000000298, -0.10000000149, 0.800000011921, -0.899999976158, 0.5, -0.20000000298, 0.699999988079, 0.0, 0.40000000596, 0.899999976158, 0.699999988079, 0.300000011921, 0.800000011921, 0.699999988079, 0.800000011921, 0.10000000149, 0.600000023842, 0.5, 0.600000023842, -0.40000000596, 0.600000023842, -0.800000011921, 0.40000000596, -0.20000000298, 0.40000000596, -0.10000000149, 0.10000000149, -0.5, 0.10000000149, -0.40000000596, 0.5, -0.20000000298, 0.899999976158, -0.899999976158, 0.10000000149, -0.300000011921, 0.699999988079, -0.800000011921, 0.20000000298, -0.899999976158, 0.40000000596, -0.899999976158, 0.10000000149, 0.0, 0.300000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.800000011921, 0.800000011921, 0.20000000298, 0.300000011921, 0.699999988079, -0.300000011921, 0.10000000149, -0.20000000298, 0.600000023842, -0.300000011921, 0.699999988079, -0.800000011921, 0.20000000298, -0.800000011921, 0.10000000149, -0.40000000596, 0.40000000596, -0.10000000149, 0.800000011921, -0.800000011921, 0.10000000149, -0.40000000596, 0.300000011921, -0.40000000596, 0.300000011921, -0.10000000149, 0.699999988079, -0.300000011921, 0.300000011921, -0.800000011921, 0.5, 0.0, 0.20000000298, 0.300000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.10000000149, 0.899999976158, -0.10000000149, 0.800000011921, -0.10000000149, 0.5, -0.20000000298, 0.40000000596, -0.10000000149, 0.10000000149, -0.20000000298, 0.5, -0.699999988079, 0.800000011921, -0.699999988079, 0.10000000149, -0.800000011921, 0.899999976158, -0.600000023842, 0.600000023842, -0.5, 0.10000000149, -0.20000000298, 0.800000011921, -0.699999988079, 0.600000023842, -0.20000000298, 0.20000000298, -0.300000011921, 0.5, 0.0, 0.5, 0.300000011921, 0.40000000596, 0.899999976158, 0.40000000596, -0.10000000149, 0.10000000149, -0.899999976158, 0.10000000149, -0.800000011921, 0.20000000298, -0.699999988079, 0.800000011921, -0.20000000298, 0.5, -0.600000023842, 0.5, -0.699999988079, 0.5, -0.600000023842, 0.20000000298, -0.899999976158, 0.899999976158, -0.300000011921, 0.5, -0.10000000149, 0.800000011921, -0.10000000149, 0.800000011921, -0.800000011921, 0.20000000298, -0.899999976158, 0.5, -0.300000011921, 0.300000011921, 0.0, 0.5, 0.5, 0.40000000596, -0.300000011921, 0.40000000596, -0.40000000596, 0.699999988079, -0.300000011921, 0.10000000149, -0.300000011921, 0.800000011921, -0.40000000596, 0.40000000596, -0.10000000149, 0.10000000149, -0.800000011921, 0.699999988079, -0.40000000596, 0.40000000596, -0.300000011921, 0.699999988079, -0.5, 0.899999976158, -0.300000011921, 0.600000023842, -0.5, 0.20000000298, -0.300000011921, 0.40000000596, -0.10000000149, 0.40000000596, -0.899999976158, 0.5, -0.5, 0.10000000149, 0.0, 
+
+L2_cHER2_A_nn_pu
+0.699999988079, 0.0, 0.300000011921, 0.40000000596, 0.40000000596, 0.40000000596, 0.40000000596, 0.20000000298, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.899999976158, 0.699999988079, 0.600000023842, 0.5, 0.800000011921, 0.40000000596, 0.699999988079, 0.899999976158, 0.800000011921, 0.600000023842, 0.699999988079, 0.600000023842, 0.600000023842, 0.40000000596, 0.699999988079, 0.300000011921, 0.899999976158, 0.10000000149, 0.40000000596, 0.10000000149, 0.40000000596, 0.300000011921, 0.5, 0.0, 0.20000000298, 0.600000023842, 0.600000023842, 0.800000011921, 0.300000011921, 0.899999976158, 0.699999988079, 0.699999988079, 0.20000000298, 0.10000000149, 0.5, 0.800000011921, 0.800000011921, 0.800000011921, 0.20000000298, 0.20000000298, 0.10000000149, 0.899999976158, 0.600000023842, 0.300000011921, 0.600000023842, 0.800000011921, 0.10000000149, 0.20000000298, 0.800000011921, 0.10000000149, 0.10000000149, 0.899999976158, 0.40000000596, 0.40000000596, 0.5, 0.0, 0.10000000149, 0.899999976158, 0.40000000596, 0.10000000149, 0.600000023842, 0.20000000298, 0.40000000596, 0.40000000596, 0.899999976158, 0.699999988079, 0.800000011921, 0.300000011921, 0.300000011921, 0.5, 0.600000023842, 0.10000000149, 0.600000023842, 0.800000011921, 0.40000000596, 0.20000000298, 0.600000023842, 0.300000011921, 0.5, 0.20000000298, 0.10000000149, 0.800000011921, 0.699999988079, 0.300000011921, 0.800000011921, 0.0, 0.300000011921, 0.20000000298, 0.800000011921, 0.899999976158, 0.5, 0.10000000149, 0.800000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.10000000149, 0.899999976158, 0.40000000596, 0.800000011921, 0.40000000596, 0.20000000298, 0.40000000596, 0.10000000149, 0.699999988079, 0.800000011921, 0.40000000596, 0.10000000149, 0.20000000298, 0.699999988079, 0.10000000149, 0.300000011921, 0.10000000149, 0.0, 0.899999976158, 0.20000000298, 0.10000000149, 0.600000023842, 0.5, 0.20000000298, 0.600000023842, 0.800000011921, 0.600000023842, 0.20000000298, 0.5, 0.5, 0.20000000298, 0.800000011921, 0.10000000149, 0.5, 0.20000000298, 0.800000011921, 0.10000000149, 0.20000000298, 0.800000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.800000011921, 0.0, 0.600000023842, 0.600000023842, 0.899999976158, 0.20000000298, 0.800000011921, 0.5, 0.899999976158, 0.699999988079, 0.40000000596, 0.899999976158, 0.300000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.10000000149, 0.40000000596, 0.5, 0.699999988079, 0.5, 0.600000023842, 0.40000000596, 0.10000000149, 0.899999976158, 0.0, 0.899999976158, 0.20000000298, 0.800000011921, 0.699999988079, 0.300000011921, 0.10000000149, 0.5, 0.699999988079, 0.5, 0.40000000596, 0.5, 0.20000000298, 0.40000000596, 0.10000000149, 0.800000011921, 0.699999988079, 0.5, 0.699999988079, 0.10000000149, 0.800000011921, 0.10000000149, 0.0, 0.40000000596, 0.699999988079, 0.699999988079, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.899999976158, 0.899999976158, 0.800000011921, 0.800000011921, 0.10000000149, 0.800000011921, 0.5, 0.600000023842, 0.699999988079, 0.40000000596, 0.5, 0.0, 0.10000000149, 0.300000011921, 0.5, 0.699999988079, 0.20000000298, 0.10000000149, 0.10000000149, 0.300000011921, 0.10000000149, 0.40000000596, 0.899999976158, 0.600000023842, 0.20000000298, 0.899999976158, 0.40000000596, 0.300000011921, 0.899999976158, 0.0, 0.899999976158, 0.899999976158, 0.800000011921, 0.899999976158, 0.699999988079, 0.800000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.5, 0.899999976158, 0.300000011921, 0.699999988079, 0.5, 0.300000011921, 0.0, 0.5, 0.20000000298, 0.20000000298, 0.899999976158, 0.300000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.699999988079, 0.0, 0.40000000596, 0.899999976158, 0.699999988079, 0.300000011921, 0.800000011921, 0.699999988079, 0.800000011921, 0.10000000149, 0.600000023842, 0.5, 0.10000000149, 0.0, 0.300000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.800000011921, 0.800000011921, 0.20000000298, 0.300000011921, 0.5, 0.0, 0.20000000298, 0.300000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.10000000149, 0.5, 0.0, 0.5, 0.300000011921, 0.40000000596, 0.899999976158, 0.300000011921, 0.0, 0.5, 0.5, 0.10000000149, 0.0, 
+
+L2_cHER2_x_n1
+0.899999976158, 0.300000011921, 0.5, 0.5, 0.300000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.300000011921, 0.5, 0.40000000596, 0.699999988079, 0.300000011921, 0.40000000596, 0.300000011921, 0.5, 0.600000023842, 0.20000000298, 0.600000023842, 0.20000000298, 0.600000023842, 0.699999988079, 0.20000000298, 0.699999988079, 0.40000000596, 0.300000011921, 0.20000000298, 0.699999988079, 0.800000011921, 0.20000000298, 0.699999988079, 0.600000023842, 0.800000011921, 0.5, 
+
+L2_cHER2_x_n2
+0.899999976158, 0.300000011921, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.300000011921, 0.899999976158, 0.0, 0.0, 0.899999976158, 0.10000000149, 0.0, 0.0, 0.300000011921, 0.5, 0.0, 0.0, 0.40000000596, 0.699999988079, 0.0, 0.0, 0.300000011921, 0.40000000596, 0.0, 0.0, 0.300000011921, 0.5, 0.0, 0.0, 0.600000023842, 0.20000000298, 0.0, 0.0, 0.600000023842, 0.20000000298, 0.0, 0.0, 0.600000023842, 0.699999988079, 0.0, 0.0, 0.20000000298, 0.699999988079, 0.0, 0.0, 0.40000000596, 0.300000011921, 0.0, 0.0, 0.20000000298, 0.699999988079, 0.0, 0.0, 0.800000011921, 0.20000000298, 0.0, 0.0, 0.699999988079, 0.600000023842, 0.0, 0.0, 0.800000011921, 0.5, 0.0, 0.0, 
+
+L2_cHER2_y_n1
+0.899999976158, 0.300000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.20000000298, 0.600000023842, 0.40000000596, 0.600000023842, 0.600000023842, 0.300000011921, 0.5, 0.899999976158, 0.10000000149, 0.5, 0.899999976158, 0.20000000298, 0.899999976158, 0.899999976158, 0.899999976158, 0.5, 0.899999976158, 0.20000000298, 0.5, 0.600000023842, 0.40000000596, 0.600000023842, 0.899999976158, 0.300000011921, 0.300000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.600000023842, 
+
+L2_cHER2_y_n2
+0.899999976158, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.5, 0.0, 0.0, 0.0, 0.0, 0.899999976158, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.5, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.899999976158, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.5, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.5, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 
+
+L2_cHER2_o_N
+2.49999991655, 0.0, 1.70999999285, -0.229999978542, 1.36000001222, -0.379999935329, 1.89999997839, 0.200000026077, 1.74000005484, 0.180000002384, 1.29000002205, -0.769999945462, 2.12999994501, 0.610000004023, 1.74000002503, -0.519999932051, 1.85000002384, -0.349999931455, 2.37999995917, 0.360000039041, 2.2700000155, -0.509999885559, 1.41999999464, -0.359999930263, 1.71000004053, 0.0700000274181, 1.90000000149, -0.899999900162, 2.03999998182, -0.0199999797344, 1.63000000387, -0.889999989271, 1.81000001371, -0.329999963641, 1.70999999285, 0.229999978542, 1.80000001192, 0.0, 1.25000001937, 0.250000067055, 1.7900000146, 1.37000002816, 1.41000005245, 0.729999996424, 1.80000000298, 0.350000023842, 1.15000000969, 0.400000003725, 1.71000000477, 0.430000044107, 1.89000001758, 0.67000005424, 1.63999999523, 0.420000031888, 1.64000000864, 0.570000033379, 1.51000003457, -0.219999963343, 1.56000005245, 0.930000029206, 1.41000001073, -0.319999949932, 1.78000002921, 0.440000028014, 1.45000002086, 0.599999971688, 1.76000003159, 0.430000029206, 1.36000001222, 0.379999935329, 1.25000001937, -0.250000067055, 1.10000000894, 0.0, 1.02000000805, 1.45999997348, 1.34000003546, 0.319999994636, 1.44000002354, 0.120000003576, 0.960000017434, 1.07999995992, 2.07999994725, 0.73999997288, 1.94999998659, 0.250000010431, 1.65999998689, 1.07999995768, 1.9399999997, 0.119999993145, 1.33000001729, 0.590000005662, 1.16000002414, 0.579999999404, 1.80999999732, 0.330000017285, 1.22000002146, 0.460000001788, 1.28000000238, 0.639999983311, 1.78000001281, 0.439999995232, 1.89999997839, -0.200000026077, 1.7900000146, -1.37000002816, 1.02000000805, -1.45999997348, 1.96000002861, 0.0, 1.28000003964, -0.460000006258, 1.64000002876, 0.21999998495, 1.65999997646, -0.0200000050664, 1.72000001624, -0.239999973625, 1.41000001594, 0.230000026226, 1.43999998853, 0.300000024587, 1.58000002101, -0.139999940842, 1.03000001058, -0.569999991655, 1.34000003397, -0.220000000596, 1.73000000015, -0.289999949038, 1.26000003979, 0.0600000025332, 1.12000002593, -0.0800000321865, 1.2000000298, -0.179999996424, 1.74000005484, -0.180000002384, 1.41000005245, -0.729999996424, 1.34000003546, -0.319999994636, 1.28000003964, 0.460000006258, 1.06000005394, 0.0, 1.90000000596, 0.0200000065565, 0.84000003323, 0.960000011474, 1.58000002027, 0.0600000017881, 1.59000005037, 0.870000031888, 1.80000005066, 0.620000009537, 1.88000003219, 0.420000015497, 1.05000002235, 0.45000000447, 0.900000046194, 0.740000004172, 1.37000002146, 0.530000017285, 0.940000047386, 0.620000021458, 2.04000005931, 0.119999972284, 2.00000006855, 0.600000008941, 1.29000002205, 0.769999945462, 1.80000000298, -0.350000023842, 1.44000002354, -0.120000003576, 1.64000002876, -0.21999998495, 1.90000000596, -0.0200000065565, 1.74000001311, 0.0, 1.32000002965, 1.21999999464, 2.06999995887, 0.190000001192, 1.79000000268, 0.520000012517, 2.16999996036, 1.20999997348, 1.75999998987, 0.979999981523, 1.14000000566, 0.529999981523, 0.890000026524, 0.770000006557, 1.3799999845, 0.350000016391, 1.17000002593, 1.12999998897, 1.65000001788, 0.589999993742, 1.47000003338, 0.389999987781, 2.12999994501, -0.610000004023, 1.15000000969, -0.400000003725, 0.960000017434, -1.07999995992, 1.65999997646, 0.0200000050664, 0.84000003323, -0.960000011474, 1.32000002965, -1.21999999464, 1.51999998569, 0.0, 1.72999998227, -0.289999984056, 1.78000001878, 0.389999992251, 1.49000001907, 0.0699999991059, 1.62000000879, 0.0600000181794, 1.01000000402, -0.279999969602, 1.23000001654, 0.0900000071526, 1.19000001386, -0.539999960959, 1.75000001788, 0.629999991953, 1.56999998868, 0.0699999700487, 1.23000001356, 0.410000016689, 1.74000002503, 0.519999932051, 1.71000000477, -0.430000044107, 2.07999994725, -0.73999997288, 1.72000001624, 0.239999973625, 1.58000002027, -0.0600000017881, 2.06999995887, -0.190000001192, 1.72999998227, 0.289999984056, 1.29999998957, 0.0, 1.39000000715, 0.969999991655, 1.89999998957, 1.11999999017, 1.82999999046, 1.06999998569, 1.43999998331, 0.580000011325, 1.75, 1.28999997139, 2.15999998838, 0.66000002414, 0.920000018477, 1.48000000089, 1.85000001043, 0.78999997288, 1.9700000006, 0.889999986291, 1.85000002384, 0.349999931455, 1.89000001758, -0.67000005424, 1.94999998659, -0.250000010431, 1.41000001594, -0.230000026226, 1.59000005037, -0.870000031888, 1.79000000268, -0.520000012517, 1.78000001878, -0.389999992251, 1.39000000715, -0.969999991655, 1.10000000894, 0.0, 1.12000001103, 0.440000008643, 1.72999998897, 0.659999989867, 1.0899999848, -0.120000011027, 0.890000038445, 0.479999997914, 1.31000000179, 0.0200000035763, 1.47999999642, 1.16000000328, 1.16000002116, 0.96999991715, 1.37000001848, 0.63999997586, 2.37999995917, -0.360000039041, 1.63999999523, -0.420000031888, 1.65999998689, -1.07999995768, 1.43999998853, -0.300000024587, 1.80000005066, -0.620000009537, 2.16999996036, -1.20999997348, 1.49000001907, -0.0699999991059, 1.89999998957, -1.11999999017, 1.12000001103, -0.440000008643, 2.33999998629, 0.0, 2.54999996573, 0.370000005066, 1.82999999046, 0.189999990761, 1.77000001848, 0.769999997616, 1.65000000894, -0.469999969304, 1.74000003099, 0.919999982715, 2.34999996722, -0.0500000476837, 2.22999998748, 0.48999997735, 2.2700000155, 0.509999885559, 1.64000000864, -0.570000033379, 1.9399999997, -0.119999993145, 1.58000002101, 0.139999940842, 1.88000003219, -0.420000015497, 1.75999998987, -0.979999981523, 1.62000000879, -0.0600000181794, 1.82999999046, -1.06999998569, 1.72999998897, -0.659999989867, 2.54999996573, -0.370000005066, 2.15999998093, 0.0, 1.69999997467, -0.130000005364, 1.31000003755, 1.28999996245, 2.01999998719, -0.189999992251, 1.07000002444, 0.849999983609, 2.07000000656, 0.089999935627, 2.40999999285, 0.68999997437, 1.41999999464, 0.359999930263, 1.51000003457, 0.219999963343, 1.33000001729, -0.590000005662, 1.03000001058, 0.569999991655, 1.05000002235, -0.45000000447, 1.14000000566, -0.529999981523, 1.01000000402, 0.279999969602, 1.43999998331, -0.580000011325, 1.0899999848, 0.120000011027, 1.82999999046, -0.189999990761, 1.69999997467, 0.130000005364, 1.47999997854, 0.0, 1.03000002027, 1.37999998301, 1.83999996245, 0.500000025332, 1.33000002623, 1.20999999434, 1.84000002354, 0.309999983907, 1.51000004053, 0.959999997318, 1.71000004053, -0.0700000274181, 1.56000005245, -0.930000029206, 1.16000002414, -0.579999999404, 1.34000003397, 0.220000000596, 0.900000046194, -0.740000004172, 0.890000026524, -0.770000006557, 1.23000001654, -0.0900000071526, 1.75, -1.28999997139, 0.890000038445, -0.479999997914, 1.77000001848, -0.769999997616, 1.31000003755, -1.28999996245, 1.03000002027, -1.37999998301, 0.820000040829, 0.0, 1.21000003457, 0.280000023246, 1.37000006616, 0.370000006557, 1.78000005007, 0.459999976456, 1.22000005126, 0.20000000298, 1.90000000149, 0.899999900162, 1.41000001073, 0.319999949932, 1.80999999732, -0.330000017285, 1.73000000015, 0.289999949038, 1.37000002146, -0.530000017285, 1.3799999845, -0.350000016391, 1.19000001386, 0.539999960959, 2.15999998838, -0.66000002414, 1.31000000179, -0.0200000035763, 1.65000000894, 0.469999969304, 2.01999998719, 0.189999992251, 1.83999996245, -0.500000025332, 1.21000003457, -0.280000023246, 1.99999995828, 0.0, 1.13000003517, 1.04999999851, 1.76000001967, 1.14999991506, 1.83000003219, 0.679999974072, 2.03999998182, 0.0199999797344, 1.78000002921, -0.440000028014, 1.22000002146, -0.460000001788, 1.26000003979, -0.0600000025332, 0.940000047386, -0.620000021458, 1.17000002593, -1.12999998897, 1.75000001788, -0.629999991953, 0.920000018477, -1.48000000089, 1.47999999642, -1.16000000328, 1.74000003099, -0.919999982715, 1.07000002444, -0.849999983609, 1.33000002623, -1.20999999434, 1.37000006616, -0.370000006557, 1.13000003517, -1.04999999851, 1.10000003278, 0.0, 1.21000002861, -0.270000015497, 1.23000004113, 0.589999959469, 1.63000000387, 0.889999989271, 1.45000002086, -0.599999971688, 1.28000000238, -0.639999983311, 1.12000002593, 0.0800000321865, 2.04000005931, -0.119999972284, 1.65000001788, -0.589999993742, 1.56999998868, -0.0699999700487, 1.85000001043, -0.78999997288, 1.16000002116, -0.96999991715, 2.34999996722, 0.0500000476837, 2.07000000656, -0.089999935627, 1.84000002354, -0.309999983907, 1.78000005007, -0.459999976456, 1.76000001967, -1.14999991506, 1.21000002861, 0.270000015497, 1.54000006378, 0.0, 1.70000003874, 0.86000002116, 1.81000001371, 0.329999963641, 1.76000003159, -0.430000029206, 1.78000001281, -0.439999995232, 1.2000000298, 0.179999996424, 2.00000006855, -0.600000008941, 1.47000003338, -0.389999987781, 1.23000001356, -0.410000016689, 1.9700000006, -0.889999986291, 1.37000001848, -0.63999997586, 2.22999998748, -0.48999997735, 2.40999999285, -0.68999997437, 1.51000004053, -0.959999997318, 1.22000005126, -0.20000000298, 1.83000003219, -0.679999974072, 1.23000004113, -0.589999959469, 1.70000003874, -0.86000002116, 1.34000004441, 0.0, 
+
+L2_cHER2_o_N_pu
+2.49999991655, 0.0, 1.70999999285, -0.229999978542, 1.36000001222, -0.379999935329, 1.89999997839, 0.200000026077, 1.74000005484, 0.180000002384, 1.29000002205, -0.769999945462, 2.12999994501, 0.610000004023, 1.74000002503, -0.519999932051, 1.85000002384, -0.349999931455, 2.37999995917, 0.360000039041, 2.2700000155, -0.509999885559, 1.41999999464, -0.359999930263, 1.71000004053, 0.0700000274181, 1.90000000149, -0.899999900162, 2.03999998182, -0.0199999797344, 1.63000000387, -0.889999989271, 1.81000001371, -0.329999963641, 1.80000001192, 0.0, 1.25000001937, 0.250000067055, 1.7900000146, 1.37000002816, 1.41000005245, 0.729999996424, 1.80000000298, 0.350000023842, 1.15000000969, 0.400000003725, 1.71000000477, 0.430000044107, 1.89000001758, 0.67000005424, 1.63999999523, 0.420000031888, 1.64000000864, 0.570000033379, 1.51000003457, -0.219999963343, 1.56000005245, 0.930000029206, 1.41000001073, -0.319999949932, 1.78000002921, 0.440000028014, 1.45000002086, 0.599999971688, 1.76000003159, 0.430000029206, 1.10000000894, 0.0, 1.02000000805, 1.45999997348, 1.34000003546, 0.319999994636, 1.44000002354, 0.120000003576, 0.960000017434, 1.07999995992, 2.07999994725, 0.73999997288, 1.94999998659, 0.250000010431, 1.65999998689, 1.07999995768, 1.9399999997, 0.119999993145, 1.33000001729, 0.590000005662, 1.16000002414, 0.579999999404, 1.80999999732, 0.330000017285, 1.22000002146, 0.460000001788, 1.28000000238, 0.639999983311, 1.78000001281, 0.439999995232, 1.96000002861, 0.0, 1.28000003964, -0.460000006258, 1.64000002876, 0.21999998495, 1.65999997646, -0.0200000050664, 1.72000001624, -0.239999973625, 1.41000001594, 0.230000026226, 1.43999998853, 0.300000024587, 1.58000002101, -0.139999940842, 1.03000001058, -0.569999991655, 1.34000003397, -0.220000000596, 1.73000000015, -0.289999949038, 1.26000003979, 0.0600000025332, 1.12000002593, -0.0800000321865, 1.2000000298, -0.179999996424, 1.06000005394, 0.0, 1.90000000596, 0.0200000065565, 0.84000003323, 0.960000011474, 1.58000002027, 0.0600000017881, 1.59000005037, 0.870000031888, 1.80000005066, 0.620000009537, 1.88000003219, 0.420000015497, 1.05000002235, 0.45000000447, 0.900000046194, 0.740000004172, 1.37000002146, 0.530000017285, 0.940000047386, 0.620000021458, 2.04000005931, 0.119999972284, 2.00000006855, 0.600000008941, 1.74000001311, 0.0, 1.32000002965, 1.21999999464, 2.06999995887, 0.190000001192, 1.79000000268, 0.520000012517, 2.16999996036, 1.20999997348, 1.75999998987, 0.979999981523, 1.14000000566, 0.529999981523, 0.890000026524, 0.770000006557, 1.3799999845, 0.350000016391, 1.17000002593, 1.12999998897, 1.65000001788, 0.589999993742, 1.47000003338, 0.389999987781, 1.51999998569, 0.0, 1.72999998227, -0.289999984056, 1.78000001878, 0.389999992251, 1.49000001907, 0.0699999991059, 1.62000000879, 0.0600000181794, 1.01000000402, -0.279999969602, 1.23000001654, 0.0900000071526, 1.19000001386, -0.539999960959, 1.75000001788, 0.629999991953, 1.56999998868, 0.0699999700487, 1.23000001356, 0.410000016689, 1.29999998957, 0.0, 1.39000000715, 0.969999991655, 1.89999998957, 1.11999999017, 1.82999999046, 1.06999998569, 1.43999998331, 0.580000011325, 1.75, 1.28999997139, 2.15999998838, 0.66000002414, 0.920000018477, 1.48000000089, 1.85000001043, 0.78999997288, 1.9700000006, 0.889999986291, 1.10000000894, 0.0, 1.12000001103, 0.440000008643, 1.72999998897, 0.659999989867, 1.0899999848, -0.120000011027, 0.890000038445, 0.479999997914, 1.31000000179, 0.0200000035763, 1.47999999642, 1.16000000328, 1.16000002116, 0.96999991715, 1.37000001848, 0.63999997586, 2.33999998629, 0.0, 2.54999996573, 0.370000005066, 1.82999999046, 0.189999990761, 1.77000001848, 0.769999997616, 1.65000000894, -0.469999969304, 1.74000003099, 0.919999982715, 2.34999996722, -0.0500000476837, 2.22999998748, 0.48999997735, 2.15999998093, 0.0, 1.69999997467, -0.130000005364, 1.31000003755, 1.28999996245, 2.01999998719, -0.189999992251, 1.07000002444, 0.849999983609, 2.07000000656, 0.089999935627, 2.40999999285, 0.68999997437, 1.47999997854, 0.0, 1.03000002027, 1.37999998301, 1.83999996245, 0.500000025332, 1.33000002623, 1.20999999434, 1.84000002354, 0.309999983907, 1.51000004053, 0.959999997318, 0.820000040829, 0.0, 1.21000003457, 0.280000023246, 1.37000006616, 0.370000006557, 1.78000005007, 0.459999976456, 1.22000005126, 0.20000000298, 1.99999995828, 0.0, 1.13000003517, 1.04999999851, 1.76000001967, 1.14999991506, 1.83000003219, 0.679999974072, 1.10000003278, 0.0, 1.21000002861, -0.270000015497, 1.23000004113, 0.589999959469, 1.54000006378, 0.0, 1.70000003874, 0.86000002116, 1.34000004441, 0.0, 
+
+L2_zHER2_A_nn
+0.4, 0.0, 0.3, 0.1, 0.4, 0.7, 0.1, 0.2, 0.4, 0.6, 0.2, 0.7, 0.1, 0.1, 0.1, 0.3, 0.8, 0.1, 0.9, 0.5, 0.2, 0.5, 0.9, 0.8, 0.8, 0.4, 0.6, 0.3, 0.1, 0.3, 0.8, 0.7, 0.6, 0.4, 0.3, -0.1, 0.4, 0.0, 0.9, 0.1, 0.4, 0.5, 0.9, 0.3, 0.8, 0.6, 0.2, 0.1, 0.2, 0.7, 0.9, 0.6, 0.8, 0.5, 0.2, 0.2, 0.3, 0.4, 0.8, 0.9, 0.1, 0.5, 0.1, 0.8, 0.7, 0.2, 0.1, 0.1, 0.4, -0.7, 0.9, -0.1, 0.8, 0.0, 0.1, 0.6, 0.2, 0.8, 0.1, 0.5, 0.8, 0.4, 0.1, 0.3, 0.9, 0.3, 0.7, 0.4, 0.4, 0.6, 0.4, 0.5, 0.8, 0.4, 0.4, 0.4, 0.5, 0.4, 0.8, 0.5, 0.1, 0.4, 0.1, -0.2, 0.4, -0.5, 0.1, -0.6, 0.1, 0.0, 0.1, 0.8, 0.7, 0.4, 0.3, 0.8, 0.7, 0.2, 0.9, 0.1, 0.2, 0.3, 0.8, 0.1, 0.4, 0.7, 0.4, 0.8, 0.5, 0.9, 0.6, 0.4, 0.3, 0.2, 0.5, 0.6, 0.4, -0.6, 0.9, -0.3, 0.2, -0.8, 0.1, -0.8, 0.1, 0.0, 0.4, 0.3, 0.1, 0.1, 0.6, 0.9, 0.4, 0.9, 0.5, 0.1, 0.1, 0.1, 0.4, 0.4, 0.9, 0.6, 0.5, 0.4, 0.5, 0.3, 0.6, 0.8, 0.2, 0.6, 0.2, -0.7, 0.8, -0.6, 0.1, -0.5, 0.7, -0.4, 0.4, -0.3, 0.7, 0.0, 0.4, 0.6, 0.5, 0.7, 0.3, 0.9, 0.2, 0.9, 0.2, 0.5, 0.5, 0.7, 0.9, 0.1, 0.1, 0.3, 0.5, 0.2, 0.9, 0.8, 0.8, 0.5, 0.1, -0.1, 0.2, -0.1, 0.8, -0.4, 0.3, -0.8, 0.1, -0.1, 0.4, -0.6, 0.8, 0.0, 0.9, 0.7, 0.2, 0.7, 0.8, 0.2, 0.4, 0.9, 0.3, 0.9, 0.5, 0.7, 0.3, 0.7, 0.5, 0.2, 0.7, 0.6, 0.8, 0.5, 0.1, -0.3, 0.2, -0.7, 0.1, -0.3, 0.7, -0.2, 0.6, -0.9, 0.5, -0.7, 0.9, -0.7, 0.5, 0.0, 0.6, 0.2, 0.7, 0.8, 0.3, 0.7, 0.1, 0.3, 0.1, 0.6, 0.5, 0.3, 0.2, 0.5, 0.3, 0.7, 0.8, 0.8, 0.8, -0.1, 0.9, -0.6, 0.9, -0.3, 0.9, -0.1, 0.4, -0.9, 0.3, -0.9, 0.2, -0.7, 0.6, -0.2, 0.1, 0.0, 0.5, 0.3, 0.2, 0.6, 0.9, 0.9, 0.2, 0.7, 0.6, 0.2, 0.6, 0.8, 0.1, 0.9, 0.1, 0.6, 0.9, -0.5, 0.8, -0.5, 0.7, -0.4, 0.2, -0.3, 0.5, -0.1, 0.2, -0.9, 0.8, -0.2, 0.7, -0.8, 0.5, -0.3, 0.7, 0.0, 0.2, 0.2, 0.7, 0.1, 0.8, 0.9, 0.7, 0.6, 0.8, 0.1, 0.2, 0.2, 0.2, 0.1, 0.2, -0.5, 0.2, -0.2, 0.4, -0.6, 0.8, -0.1, 0.1, -0.1, 0.2, -0.5, 0.4, -0.9, 0.3, -0.7, 0.2, -0.6, 0.2, -0.2, 0.3, 0.0, 0.6, 0.8, 0.4, 0.5, 0.8, 0.4, 0.4, 0.3, 0.3, 0.9, 0.7, 0.8, 0.9, -0.8, 0.3, -0.4, 0.4, -0.5, 0.4, -0.7, 0.4, -0.4, 0.5, -0.7, 0.3, -0.9, 0.1, -0.3, 0.9, -0.9, 0.7, -0.1, 0.6, -0.8, 0.3, 0.0, 0.6, 0.4, 0.5, 0.6, 0.2, 0.6, 0.6, 0.6, 0.2, 0.1, 0.8, -0.4, 0.8, -0.9, 0.8, -0.4, 0.4, -0.8, 0.9, -0.6, 0.9, -0.1, 0.5, -0.7, 0.1, -0.6, 0.2, -0.7, 0.8, -0.9, 0.4, -0.5, 0.6, -0.4, 0.2, 0.0, 0.4, 0.4, 0.6, 0.6, 0.6, 0.1, 0.4, 0.8, 0.6, -0.3, 0.1, -0.5, 0.4, -0.4, 0.5, -0.9, 0.5, -0.4, 0.1, -0.3, 0.3, -0.7, 0.5, -0.3, 0.6, -0.2, 0.7, -0.6, 0.8, -0.4, 0.5, -0.6, 0.4, -0.4, 0.6, 0.0, 0.4, 0.7, 0.1, 0.3, 0.7, 0.8, 0.1, -0.3, 0.1, -0.8, 0.5, -0.4, 0.6, -0.4, 0.5, -0.3, 0.5, -0.2, 0.5, -0.2, 0.2, -0.5, 0.6, -0.8, 0.8, -0.1, 0.4, -0.3, 0.2, -0.6, 0.6, -0.6, 0.4, -0.7, 0.6, 0.0, 0.1, 0.6, 0.4, 0.7, 0.8, -0.7, 0.7, -0.2, 0.8, -0.5, 0.3, -0.2, 0.6, -0.8, 0.9, -0.8, 0.7, -0.6, 0.3, -0.7, 0.1, -0.9, 0.2, -0.2, 0.3, -0.9, 0.6, -0.6, 0.6, -0.1, 0.1, -0.3, 0.1, -0.6, 0.8, 0.0, 0.5, 0.6, 0.6, -0.4, 0.1, -0.1, 0.1, -0.4, 0.5, -0.6, 0.2, -0.6, 0.8, -0.5, 0.8, -0.5, 0.8, -0.8, 0.1, -0.6, 0.2, -0.1, 0.7, -0.8, 0.2, -0.1, 0.4, -0.8, 0.7, -0.8, 0.4, -0.7, 0.5, -0.6, 0.8, 0.0, 
+
+L2_zHER2_A_nn_pu
+0.4, 0.0, 0.3, 0.1, 0.4, 0.7, 0.1, 0.2, 0.4, 0.6, 0.2, 0.7, 0.1, 0.1, 0.1, 0.3, 0.8, 0.1, 0.9, 0.5, 0.2, 0.5, 0.9, 0.8, 0.8, 0.4, 0.6, 0.3, 0.1, 0.3, 0.8, 0.7, 0.6, 0.4, 0.4, 0.0, 0.9, 0.1, 0.4, 0.5, 0.9, 0.3, 0.8, 0.6, 0.2, 0.1, 0.2, 0.7, 0.9, 0.6, 0.8, 0.5, 0.2, 0.2, 0.3, 0.4, 0.8, 0.9, 0.1, 0.5, 0.1, 0.8, 0.7, 0.2, 0.1, 0.1, 0.8, 0.0, 0.1, 0.6, 0.2, 0.8, 0.1, 0.5, 0.8, 0.4, 0.1, 0.3, 0.9, 0.3, 0.7, 0.4, 0.4, 0.6, 0.4, 0.5, 0.8, 0.4, 0.4, 0.4, 0.5, 0.4, 0.8, 0.5, 0.1, 0.4, 0.1, 0.0, 0.1, 0.8, 0.7, 0.4, 0.3, 0.8, 0.7, 0.2, 0.9, 0.1, 0.2, 0.3, 0.8, 0.1, 0.4, 0.7, 0.4, 0.8, 0.5, 0.9, 0.6, 0.4, 0.3, 0.2, 0.5, 0.6, 0.1, 0.0, 0.4, 0.3, 0.1, 0.1, 0.6, 0.9, 0.4, 0.9, 0.5, 0.1, 0.1, 0.1, 0.4, 0.4, 0.9, 0.6, 0.5, 0.4, 0.5, 0.3, 0.6, 0.8, 0.2, 0.6, 0.7, 0.0, 0.4, 0.6, 0.5, 0.7, 0.3, 0.9, 0.2, 0.9, 0.2, 0.5, 0.5, 0.7, 0.9, 0.1, 0.1, 0.3, 0.5, 0.2, 0.9, 0.8, 0.8, 0.5, 0.8, 0.0, 0.9, 0.7, 0.2, 0.7, 0.8, 0.2, 0.4, 0.9, 0.3, 0.9, 0.5, 0.7, 0.3, 0.7, 0.5, 0.2, 0.7, 0.6, 0.8, 0.5, 0.5, 0.0, 0.6, 0.2, 0.7, 0.8, 0.3, 0.7, 0.1, 0.3, 0.1, 0.6, 0.5, 0.3, 0.2, 0.5, 0.3, 0.7, 0.8, 0.8, 0.1, 0.0, 0.5, 0.3, 0.2, 0.6, 0.9, 0.9, 0.2, 0.7, 0.6, 0.2, 0.6, 0.8, 0.1, 0.9, 0.1, 0.6, 0.7, 0.0, 0.2, 0.2, 0.7, 0.1, 0.8, 0.9, 0.7, 0.6, 0.8, 0.1, 0.2, 0.2, 0.2, 0.1, 0.3, 0.0, 0.6, 0.8, 0.4, 0.5, 0.8, 0.4, 0.4, 0.3, 0.3, 0.9, 0.7, 0.8, 0.3, 0.0, 0.6, 0.4, 0.5, 0.6, 0.2, 0.6, 0.6, 0.6, 0.2, 0.1, 0.2, 0.0, 0.4, 0.4, 0.6, 0.6, 0.6, 0.1, 0.4, 0.8, 0.6, 0.0, 0.4, 0.7, 0.1, 0.3, 0.7, 0.8, 0.6, 0.0, 0.1, 0.6, 0.4, 0.7, 0.8, 0.0, 0.5, 0.6, 0.8, 0.0, 
+
+L2_zHER2_x_n1
+0.5, 0.6, 0.6, 0.8, 0.6, 0.3, 0.1, 0.6, 0.7, 0.4, 0.5, 0.4, 0.3, 0.7, 0.3, 0.9, 0.3, 0.8, 0.1, 0.8, 0.7, 0.2, 0.1, 0.8, 0.9, 0.8, 0.4, 0.7, 0.4, 0.8, 0.9, 0.9, 0.4, 0.1, 
+
+L2_zHER2_x_n2
+0.5, 0.6, 0.0, 0.0, 0.6, 0.8, 0.0, 0.0, 0.6, 0.3, 0.0, 0.0, 0.1, 0.6, 0.0, 0.0, 0.7, 0.4, 0.0, 0.0, 0.5, 0.4, 0.0, 0.0, 0.3, 0.7, 0.0, 0.0, 0.3, 0.9, 0.0, 0.0, 0.3, 0.8, 0.0, 0.0, 0.1, 0.8, 0.0, 0.0, 0.7, 0.2, 0.0, 0.0, 0.1, 0.8, 0.0, 0.0, 0.9, 0.8, 0.0, 0.0, 0.4, 0.7, 0.0, 0.0, 0.4, 0.8, 0.0, 0.0, 0.9, 0.9, 0.0, 0.0, 0.4, 0.1, 0.0, 0.0, 
+
+L2_zHER2_y_n1
+0.9, 0.8, 0.9, 0.8, 0.9, 0.8, 0.9, 0.7, 0.8, 0.4, 0.7, 0.1, 0.8, 0.6, 0.4, 0.2, 0.4, 0.1, 0.9, 0.7, 0.6, 0.7, 0.7, 0.1, 0.8, 0.7, 0.8, 0.3, 0.6, 0.6, 0.8, 0.3, 0.7, 0.7, 
+
+L2_zHER2_y_n2
+0.9, 0.8, 0.0, 0.0, 0.0, 0.0, 0.9, 0.8, 0.0, 0.0, 0.0, 0.0, 0.9, 0.8, 0.0, 0.0, 0.0, 0.0, 0.9, 0.7, 0.0, 0.0, 0.0, 0.0, 0.8, 0.4, 0.0, 0.0, 0.0, 0.0, 0.7, 0.1, 0.0, 0.0, 0.0, 0.0, 0.8, 0.6, 0.0, 0.0, 0.0, 0.0, 0.4, 0.2, 0.0, 0.0, 0.0, 0.0, 0.4, 0.1, 0.0, 0.0, 0.0, 0.0, 0.9, 0.7, 0.0, 0.0, 0.0, 0.0, 0.6, 0.7, 0.0, 0.0, 0.0, 0.0, 0.7, 0.1, 0.0, 0.0, 0.0, 0.0, 0.8, 0.7, 0.0, 0.0, 0.0, 0.0, 0.8, 0.3, 0.0, 0.0, 0.0, 0.0, 0.6, 0.6, 0.0, 0.0, 0.0, 0.0, 0.8, 0.3, 0.0, 0.0, 0.0, 0.0, 0.7, 0.7, 0.0, 0.0, 0.0, 0.0, 
+
+L2_zHER2_o_N
+2.26, 0.0, 2.41, -8.32667268469e-17, 2.11, 1.05, 1.54, -0.07, 1.99, 1.08, 1.38, 1.11, 1.69, -0.11, 1.41, -0.13, 1.97, -0.19, 2.5, 0.05, 1.71, 0.89, 2.04, 0.53, 3.07, 0.53, 2.1, 0.32, 1.76, -0.04, 2.91, 0.94, 1.81, 0.7, 2.41, 8.32667268469e-17, 2.76, 0.0, 2.86, 0.55, 2.07, 0.34, 2.65, 0.9, 2.07, 1.14, 1.99, -0.01, 1.59, 0.33, 2.13, 0.38, 2.63, 0.16, 1.91, 0.64, 1.53, 0.26, 3.29, 1.12, 1.74, 0.65, 1.94, 0.52, 2.95, 0.57, 1.52, 0.47, 2.11, -1.05, 2.86, -0.55, 2.36, 0.0, 1.42, -0.01, 1.75, 1.0, 1.32, 0.69, 2.29, -0.11, 1.39, -0.27, 2.08, -0.12, 2.18, -0.39, 1.76, 0.74, 1.58, 0.01, 2.94, 0.22, 1.89, 0.15, 2.04, -0.18, 2.9, 0.47, 1.17, 0.42, 1.54, 0.07, 2.07, -0.34, 1.42, 0.01, 1.12, 0.0, 1.33, 1.37, 1.56, 0.8, 1.5, 0.8, 1.76, -0.18, 1.83, -0.18, 1.36, 0.12, 2.05, 0.7, 1.18, 0.46, 2.27, 1.12, 1.61, 1.0, 1.94, 0.26, 2.0, 0.47, 1.42, 1.14, 1.99, -1.08, 2.65, -0.9, 1.75, -1.0, 1.33, -1.37, 1.54, 0.0, 1.49, 0.39, 1.42, -0.44, 1.56, 0.32, 1.28, 0.47, 1.81, -0.63, 1.44, -0.03, 1.33, 0.01, 2.78, 0.15, 1.78, 0.11, 1.8, -0.36, 2.36, 0.55, 1.33, 0.47, 1.38, -1.11, 2.07, -1.14, 1.32, -0.69, 1.56, -0.8, 1.49, -0.39, 1.48, 0.0, 1.32, 0.16, 1.08, 0.16, 0.83, 0.48, 1.08, 0.36, 1.29, 0.32, 1.04, 0.38, 2.29, -0.4, 0.97, 0.02, 1.4, -0.38, 2.14, 0.43, 1.72, 0.4, 1.69, 0.11, 1.99, 0.01, 2.29, 0.11, 1.5, -0.8, 1.42, 0.44, 1.32, -0.16, 2.12, 0.0, 1.94, 0.38, 1.11, 0.49, 2.12, 0.04, 1.75, 1.37, 1.14, 0.78, 2.43, 0.95, 1.49, 0.85, 1.9, 0.04, 2.41, 0.89, 1.88, 0.94, 1.41, 0.13, 1.59, -0.33, 1.39, 0.27, 1.76, 0.18, 1.56, -0.32, 1.08, -0.16, 1.94, -0.38, 1.1, 0.0, 1.09, 0.27, 1.8, 1.1, 1.43, 1.09, 0.6, 0.6, 1.49, 0.97, 1.31, 0.73, 1.24, 0.62, 1.35, 1.15, 1.82, 1.26, 1.97, 0.19, 2.13, -0.38, 2.08, 0.12, 1.83, 0.18, 1.28, -0.47, 0.83, -0.48, 1.11, -0.49, 1.09, -0.27, 0.5, 0.0, 1.45, 0.5, 1.24, 0.86, 1.31, 1.12, 1.44, 0.9, 1.31, 0.51, 1.5, 0.82, 1.03, 1.18, 1.04, 0.95, 2.5, -0.05, 2.63, -0.16, 2.18, 0.39, 1.36, -0.12, 1.81, 0.63, 1.08, -0.36, 2.12, -0.04, 1.8, -1.1, 1.45, -0.5, 2.0, 0.0, 1.59, 0.92, 1.5, -1.94289029309e-16, 2.81, 1.38, 1.87, 0.86, 2.26, 0.08, 1.96, 0.63, 1.26, 0.78, 1.71, -0.89, 1.91, -0.64, 1.76, -0.74, 2.05, -0.7, 1.44, 0.03, 1.29, -0.32, 1.75, -1.37, 1.43, -1.09, 1.24, -0.86, 1.59, -0.92, 1.42, 0.0, 1.73, 0.46, 2.2, 0.32, 2.15, 0.21, 1.74, -0.2, 2.09, 0.94, 1.64, 0.67, 2.04, -0.53, 1.53, -0.26, 1.58, -0.01, 1.18, -0.46, 1.33, -0.01, 1.04, -0.38, 1.14, -0.78, 0.6, -0.6, 1.31, -1.12, 1.5, 1.94289029309e-16, 1.73, -0.46, 0.6, 0.0, 1.95, 0.5, 1.17, 0.76, 1.1, 0.5, 1.64, 0.67, 1.12, 0.56, 3.07, -0.53, 3.29, -1.12, 2.94, -0.22, 2.27, -1.12, 2.78, -0.15, 2.29, 0.4, 2.43, -0.95, 1.49, -0.97, 1.44, -0.9, 2.81, -1.38, 2.2, -0.32, 1.95, -0.5, 2.76, 0.0, 2.17, 0.49, 2.5, 0.18, 2.91, 0.38, 1.98, 0.93, 2.1, -0.32, 1.74, -0.65, 1.89, -0.15, 1.61, -1.0, 1.78, -0.11, 0.97, -0.02, 1.49, -0.85, 1.31, -0.73, 1.31, -0.51, 1.87, -0.86, 2.15, -0.21, 1.17, -0.76, 2.17, -0.49, 1.66, 0.0, 1.62, 0.36, 1.62, 0.29, 1.82, 1.05, 1.76, 0.04, 1.94, -0.52, 2.04, 0.18, 1.94, -0.26, 1.8, 0.36, 1.4, 0.38, 1.9, -0.04, 1.24, -0.62, 1.5, -0.82, 2.26, -0.08, 1.74, 0.2, 1.1, -0.5, 2.5, -0.18, 1.62, -0.36, 2.04, 0.0, 1.74, 1.12, 1.54, 1.16, 2.91, -0.94, 2.95, -0.57, 2.9, -0.47, 2.0, -0.47, 2.36, -0.55, 2.14, -0.43, 2.41, -0.89, 1.35, -1.15, 1.03, -1.18, 1.96, -0.63, 2.09, -0.94, 1.64, -0.67, 2.91, -0.38, 1.62, -0.29, 1.74, -1.12, 2.78, 0.0, 2.11, 0.64, 1.81, -0.7, 1.52, -0.47, 1.17, -0.42, 1.42, -1.14, 1.33, -0.47, 1.72, -0.4, 1.88, -0.94, 1.82, -1.26, 1.04, -0.95, 1.26, -0.78, 1.64, -0.67, 1.12, -0.56, 1.98, -0.93, 1.82, -1.05, 1.54, -1.16, 2.11, -0.64, 1.5, 0.0, 
+
+L2_zHER2_o_N_pu
+2.26, 0.0, 2.41, -8.32667268469e-17, 2.11, 1.05, 1.54, -0.07, 1.99, 1.08, 1.38, 1.11, 1.69, -0.11, 1.41, -0.13, 1.97, -0.19, 2.5, 0.05, 1.71, 0.89, 2.04, 0.53, 3.07, 0.53, 2.1, 0.32, 1.76, -0.04, 2.91, 0.94, 1.81, 0.7, 2.76, 0.0, 2.86, 0.55, 2.07, 0.34, 2.65, 0.9, 2.07, 1.14, 1.99, -0.01, 1.59, 0.33, 2.13, 0.38, 2.63, 0.16, 1.91, 0.64, 1.53, 0.26, 3.29, 1.12, 1.74, 0.65, 1.94, 0.52, 2.95, 0.57, 1.52, 0.47, 2.36, 0.0, 1.42, -0.01, 1.75, 1.0, 1.32, 0.69, 2.29, -0.11, 1.39, -0.27, 2.08, -0.12, 2.18, -0.39, 1.76, 0.74, 1.58, 0.01, 2.94, 0.22, 1.89, 0.15, 2.04, -0.18, 2.9, 0.47, 1.17, 0.42, 1.12, 0.0, 1.33, 1.37, 1.56, 0.8, 1.5, 0.8, 1.76, -0.18, 1.83, -0.18, 1.36, 0.12, 2.05, 0.7, 1.18, 0.46, 2.27, 1.12, 1.61, 1.0, 1.94, 0.26, 2.0, 0.47, 1.42, 1.14, 1.54, 0.0, 1.49, 0.39, 1.42, -0.44, 1.56, 0.32, 1.28, 0.47, 1.81, -0.63, 1.44, -0.03, 1.33, 0.01, 2.78, 0.15, 1.78, 0.11, 1.8, -0.36, 2.36, 0.55, 1.33, 0.47, 1.48, 0.0, 1.32, 0.16, 1.08, 0.16, 0.83, 0.48, 1.08, 0.36, 1.29, 0.32, 1.04, 0.38, 2.29, -0.4, 0.97, 0.02, 1.4, -0.38, 2.14, 0.43, 1.72, 0.4, 2.12, 0.0, 1.94, 0.38, 1.11, 0.49, 2.12, 0.04, 1.75, 1.37, 1.14, 0.78, 2.43, 0.95, 1.49, 0.85, 1.9, 0.04, 2.41, 0.89, 1.88, 0.94, 1.1, 0.0, 1.09, 0.27, 1.8, 1.1, 1.43, 1.09, 0.6, 0.6, 1.49, 0.97, 1.31, 0.73, 1.24, 0.62, 1.35, 1.15, 1.82, 1.26, 0.5, 0.0, 1.45, 0.5, 1.24, 0.86, 1.31, 1.12, 1.44, 0.9, 1.31, 0.51, 1.5, 0.82, 1.03, 1.18, 1.04, 0.95, 2.0, 0.0, 1.59, 0.92, 1.5, -1.94289029309e-16, 2.81, 1.38, 1.87, 0.86, 2.26, 0.08, 1.96, 0.63, 1.26, 0.78, 1.42, 0.0, 1.73, 0.46, 2.2, 0.32, 2.15, 0.21, 1.74, -0.2, 2.09, 0.94, 1.64, 0.67, 0.6, 0.0, 1.95, 0.5, 1.17, 0.76, 1.1, 0.5, 1.64, 0.67, 1.12, 0.56, 2.76, 0.0, 2.17, 0.49, 2.5, 0.18, 2.91, 0.38, 1.98, 0.93, 1.66, 0.0, 1.62, 0.36, 1.62, 0.29, 1.82, 1.05, 2.04, 0.0, 1.74, 1.12, 1.54, 1.16, 2.78, 0.0, 2.11, 0.64, 1.5, 0.0, 
+
+L2_sSYR_A_nn
+0.6, 0.2, 0.3, 0.3, 0.2, 0.7, 0.8, 0.8, 0.9, 0.1, 0.7, 0.2, 0.7, 0.4, 0.4, 0.9, 0.5, 0.9, 0.1, 0.5, 0.8, 0.2, 0.8, 0.4, 0.1, 0.4, 0.3, 0.7, 0.9, 0.8, 0.9, 0.3, 0.3, 0.3, 0.4, 0.4, 0.3, 0.8, 0.4, 0.8, 0.1, 0.7, 0.7, 0.6, 0.2, 0.4, 0.3, 0.6, 0.5, 0.4, 0.6, 0.6, 0.8, 0.3, 0.4, 0.2, 0.8, 0.4, 0.7, 0.1, 0.1, 0.1, 0.3, 0.8, 0.4, 0.3, 0.8, 0.1, 0.3, 0.8, 0.8, 0.1, 0.3, 0.7, 0.4, 0.2, 0.8, 0.6, 0.1, 0.1, 0.2, 0.4, 0.7, 0.8, 0.8, 0.8, 0.4, 0.7, 0.9, 0.1, 0.3, 0.8, 0.5, 0.9, 0.6, 0.7, 0.9, 0.7, 0.4, 0.5, 0.9, 0.2, 0.2, 0.1, 0.6, 0.4, 0.4, 0.5, 0.7, 0.8, 0.4, 0.1, 0.3, 0.7, 0.8, 0.3, 0.8, 0.3, 0.7, 0.8, 0.5, 0.9, 0.3, 0.2, 0.6, 0.2, 0.6, 0.6, 0.8, 0.6, 0.3, 0.2, 0.6, 0.4, 0.1, 0.9, 0.5, 0.6, 0.5, 0.2, 0.5, 0.2, 0.5, 0.8, 0.1, 0.1, 0.6, 0.1, 0.8, 0.1, 0.4, 0.6, 0.4, 0.7, 0.6, 0.5, 0.6, 0.8, 0.7, 0.9, 0.5, 0.3, 0.2, 0.2, 0.2, 0.2, 0.9, 0.6, 0.6, 0.7, 0.9, 0.7, 0.9, 0.7, 0.9, 0.3, 0.2, 0.4, 0.5, 0.4, 0.9, 0.4, 0.2, 0.9, 0.6, 0.2, 0.2, 0.2, 0.1, 0.4, 0.1, 0.7, 0.8, 0.7, 0.3, 0.1, 0.7, 0.5, 0.7, 0.3, 0.5, 0.7, 0.4, 0.3, 0.6, 0.8, 0.6, 0.3, 0.1, 0.7, 0.5, 0.1, 0.3, 0.8, 0.5, 0.4, 0.9, 0.3, 0.6, 0.5, 0.6, 0.4, 0.1, 0.1, 0.9, 0.8, 0.8, 0.7, 0.8, 0.9, 0.7, 0.4, 0.7, 0.1, 0.8, 0.7, 0.4, 0.3, 0.1, 0.7, 0.2, 0.6, 0.8, 0.3, 0.3, 0.8, 0.4, 0.6, 0.6, 0.3, 0.9, 0.4, 0.1, 0.3, 0.5, 0.5, 0.1, 0.9, 0.1, 0.2, 0.4, 0.6, 0.6, 0.7, 0.2, 0.8, 0.7, 0.7, 0.8, 0.8, 0.3, 0.9, 0.5, 0.7, 0.5, 0.4, 0.2, 0.6, 0.2, 0.2, 0.2, 0.8, 0.7, 0.7, 0.8, 0.1, 0.1, 0.1, 0.9, 
+
+L2_sSYR_A_nn_pu
+0.6, 0.2, 0.3, 0.3, 0.2, 0.7, 0.8, 0.8, 0.9, 0.1, 0.7, 0.2, 0.7, 0.4, 0.4, 0.9, 0.5, 0.1, 0.5, 0.8, 0.2, 0.8, 0.4, 0.1, 0.4, 0.3, 0.7, 0.9, 0.8, 0.9, 0.3, 0.3, 0.3, 0.3, 0.8, 0.4, 0.8, 0.1, 0.7, 0.7, 0.6, 0.2, 0.4, 0.3, 0.6, 0.5, 0.4, 0.6, 0.4, 0.2, 0.8, 0.4, 0.7, 0.1, 0.1, 0.1, 0.3, 0.8, 0.4, 0.3, 0.8, 0.1, 0.3, 0.7, 0.4, 0.2, 0.8, 0.6, 0.1, 0.1, 0.2, 0.4, 0.7, 0.8, 0.8, 0.3, 0.8, 0.5, 0.9, 0.6, 0.7, 0.9, 0.7, 0.4, 0.5, 0.9, 0.2, 0.7, 0.8, 0.4, 0.1, 0.3, 0.7, 0.8, 0.3, 0.8, 0.3, 0.7, 0.6, 0.6, 0.8, 0.6, 0.3, 0.2, 0.6, 0.4, 0.1, 0.9, 0.1, 0.1, 0.6, 0.1, 0.8, 0.1, 0.4, 0.6, 0.4, 0.2, 0.2, 0.2, 0.2, 0.9, 0.6, 0.6, 0.7, 0.9, 0.4, 0.2, 0.9, 0.6, 0.2, 0.2, 0.7, 0.3, 0.5, 0.7, 0.4, 0.3, 0.9, 0.3, 0.6, 0.5, 0.6, 0.8, 0.7, 0.4, 0.3, 0.1, 0.3, 0.5, 0.3, 0.9, 0.9, 
+
+L2_sSYR_x_n1
+0.8, 0.3, 0.5, 0.6, 0.5, 0.9, 0.2, 0.2, 0.5, 0.8, 0.4, 0.5, 0.5, 0.4, 0.2, 0.3, 0.3, 
+
+L2_sSYR_x_n2
+0.8, 0.0, 0.3, 0.0, 0.5, 0.0, 0.6, 0.0, 0.5, 0.0, 0.9, 0.0, 0.2, 0.0, 0.2, 0.0, 0.5, 0.0, 0.8, 0.0, 0.4, 0.0, 0.5, 0.0, 0.5, 0.0, 0.4, 0.0, 0.2, 0.0, 0.3, 0.0, 0.3, 0.0, 
+
+L2_sSYR_o_N
+1.24000004292, 0.440000016093, 0.700000017881, 0.780000038147, 0.600000008941, 1.41999997973, 0.960000016689, 0.960000016689, 1.29999998212, 0.740000020564, 1.01999999762, 0.600000008941, 1.09999999404, 0.720000015497, 0.560000010729, 1.13999998927, 0.740000013113, 1.13999998927, 0.190000008643, 0.65000000596, 0.980000026226, 0.350000008941, 1.0700000155, 0.460000009239, 0.160000004768, 0.550000011921, 0.540000025034, 0.819999994636, 1.04999998212, 0.950000017881, 1.01999998271, 0.360000015199, 0.390000019073, 0.390000019073, 0.800000011921, 0.550000011921, 0.550000011921, 1.10000002384, 0.65000000596, 1.25, 0.20000000298, 0.799999989569, 0.949999988079, 1.0000000298, 0.40000000596, 0.65000000596, 0.550000011921, 0.800000026822, 0.60000000149, 0.550000011921, 0.750000029802, 1.08000005007, 0.980000026226, 0.600000023842, 0.760000034571, 0.500000014901, 1.34000001907, 0.520000012517, 0.819999994636, 0.400000013411, 0.580000027716, 0.340000014603, 0.600000023842, 1.10000002384, 0.640000019073, 0.420000018477, 0.980000026226, 0.280000015795, 0.700000017881, 0.950000017881, 1.05000001192, 0.400000013411, 0.550000011921, 1.14999997616, 0.500000007451, 0.30000000447, 1.05000001192, 1.0000000298, 0.30000000447, 0.35000000149, 0.45000000298, 0.600000008941, 0.799999989569, 0.950000017881, 0.950000017881, 1.52000000358, 0.670000009537, 1.14999997616, 1.43999998331, 0.549999989569, 1.10999996901, 0.980000009835, 0.679999997914, 1.34999996424, 1.3200000155, 1.05999998391, 1.34999996424, 1.14999997616, 0.760000001788, 0.679999997914, 1.16999997973, 0.470000006557, 0.360000007749, 0.160000004768, 0.700000025332, 0.520000012517, 0.500000007451, 0.679999997914, 0.739999989271, 0.840000013113, 0.500000007451, 0.260000006258, 0.380000014305, 0.799999989569, 0.900000013411, 0.380000014305, 0.840000013113, 0.360000015199, 0.759999991357, 0.960000016689, 0.560000003278, 0.999999977648, 0.420000018477, 0.30000000447, 0.780000021756, 0.240000004172, 0.640000025034, 0.700000025332, 0.960000016689, 0.680000026226, 0.400000013411, 0.30000000447, 0.680000026226, 0.440000007153, 0.160000004768, 0.959999979436, 0.90000000596, 0.750000029802, 0.75, 0.500000014901, 0.75, 0.649999991059, 0.60000000149, 0.900000013411, 0.35000000149, 0.500000007451, 0.800000026822, 0.35000000149, 1.05000001192, 0.30000000447, 0.500000007451, 0.750000029802, 0.550000011921, 1.34000000715, 0.840000036955, 0.90000000596, 1.08000005007, 1.20000001788, 1.41999997973, 1.05999998093, 0.660000004768, 0.700000017881, 0.840000022054, 0.520000012517, 0.600000008941, 0.600000008941, 1.21999998569, 0.76000002861, 0.840000036955, 0.940000001192, 1.21999998569, 0.819999994636, 1.09999997914, 0.940000001192, 1.09999997914, 0.660000007749, 0.280000005364, 0.480000008345, 0.70000000298, 0.720000015497, 1.05999998093, 0.600000008941, 0.40000000596, 1.05999998093, 0.680000026226, 0.320000009537, 0.320000009537, 0.600000008941, 0.250000007451, 0.65000000596, 0.400000013411, 0.949999988079, 1.25, 0.799999989569, 0.400000013411, 0.35000000149, 1.09999999404, 0.70000000298, 0.949999988079, 0.550000011921, 0.70000000298, 0.799999989569, 0.550000011921, 0.450000017881, 1.0000000298, 0.950000017881, 0.850000023842, 0.600000023842, 0.35000000149, 1.14999997616, 0.60000000149, 0.20000000298, 0.550000011921, 1.20000001788, 0.70000000298, 0.65000000596, 1.14999997616, 0.500000014901, 0.700000025332, 0.65000000596, 0.750000029802, 0.720000015497, 0.220000008047, 0.30000000447, 1.13999998927, 1.0000000149, 1.16000000775, 0.779999990463, 0.880000014305, 1.09999997914, 1.01999999762, 0.560000010729, 0.899999991059, 0.30000000447, 0.960000016689, 0.779999990463, 0.520000012517, 0.420000018477, 0.260000006258, 0.759999991357, 0.30000000447, 0.720000030398, 0.900000013411, 0.480000009835, 0.340000013113, 0.840000013113, 0.500000007451, 0.76000002861, 0.680000026226, 0.400000013411, 0.999999977648, 0.480000008345, 0.140000002682, 0.360000015199, 0.560000003278, 0.740000013113, 0.190000008643, 1.04999998212, 0.280000015795, 0.350000008941, 0.670000009537, 0.66000002712, 0.66000002712, 0.84999999404, 0.440000016093, 0.920000018477, 0.84999999404, 0.84999999404, 0.920000018477, 0.860000015199, 0.390000019073, 0.989999983311, 0.740000013113, 0.789999995232, 0.65000000596, 0.580000020266, 0.350000008941, 0.870000027418, 0.260000006258, 0.260000006258, 0.350000008941, 1.04000002503, 0.819999994636, 0.84999999404, 0.950000017881, 0.220000008047, 0.160000004768, 0.190000008643, 0.989999983311, 
+
+L2_sSYR_o_N_pu
+1.24000004292, 0.440000016093, 0.700000017881, 0.780000038147, 0.600000008941, 1.41999997973, 0.960000016689, 0.960000016689, 1.29999998212, 0.740000020564, 1.01999999762, 0.600000008941, 1.09999999404, 0.720000015497, 0.560000010729, 1.13999998927, 0.740000013113, 0.190000008643, 0.65000000596, 0.980000026226, 0.350000008941, 1.0700000155, 0.460000009239, 0.160000004768, 0.550000011921, 0.540000025034, 0.819999994636, 1.04999998212, 0.950000017881, 1.01999998271, 0.360000015199, 0.390000019073, 0.390000019073, 0.550000011921, 1.10000002384, 0.65000000596, 1.25, 0.20000000298, 0.799999989569, 0.949999988079, 1.0000000298, 0.40000000596, 0.65000000596, 0.550000011921, 0.800000026822, 0.60000000149, 0.550000011921, 0.750000029802, 0.760000034571, 0.500000014901, 1.34000001907, 0.520000012517, 0.819999994636, 0.400000013411, 0.580000027716, 0.340000014603, 0.600000023842, 1.10000002384, 0.640000019073, 0.420000018477, 0.980000026226, 0.280000015795, 0.550000011921, 1.14999997616, 0.500000007451, 0.30000000447, 1.05000001192, 1.0000000298, 0.30000000447, 0.35000000149, 0.45000000298, 0.600000008941, 0.799999989569, 0.950000017881, 0.950000017881, 1.10999996901, 0.980000009835, 0.679999997914, 1.34999996424, 1.3200000155, 1.05999998391, 1.34999996424, 1.14999997616, 0.760000001788, 0.679999997914, 1.16999997973, 0.470000006557, 0.739999989271, 0.840000013113, 0.500000007451, 0.260000006258, 0.380000014305, 0.799999989569, 0.900000013411, 0.380000014305, 0.840000013113, 0.360000015199, 0.759999991357, 0.640000025034, 0.700000025332, 0.960000016689, 0.680000026226, 0.400000013411, 0.30000000447, 0.680000026226, 0.440000007153, 0.160000004768, 0.959999979436, 0.35000000149, 0.500000007451, 0.800000026822, 0.35000000149, 1.05000001192, 0.30000000447, 0.500000007451, 0.750000029802, 0.550000011921, 0.840000022054, 0.520000012517, 0.600000008941, 0.600000008941, 1.21999998569, 0.76000002861, 0.840000036955, 0.940000001192, 1.05999998093, 0.600000008941, 0.40000000596, 1.05999998093, 0.680000026226, 0.320000009537, 0.320000009537, 0.949999988079, 0.550000011921, 0.70000000298, 0.799999989569, 0.550000011921, 0.450000017881, 1.14999997616, 0.500000014901, 0.700000025332, 0.65000000596, 0.750000029802, 0.960000016689, 0.779999990463, 0.520000012517, 0.420000018477, 0.140000002682, 0.360000015199, 0.560000003278, 0.390000019073, 0.989999983311, 0.989999983311, 
+
+L2_dSYR_A_nn
+0.9, 0.8, 0.3, 0.5, 0.4, 0.8, 0.1, 0.4, 0.7, 0.4, 0.4, 0.7, 0.6, 0.5, 0.2, 0.8, 0.6, 0.5, 0.7, 0.3, 0.1, 0.9, 0.5, 0.7, 0.6, 0.2, 0.1, 0.7, 0.4, 0.9, 0.8, 0.5, 0.3, 0.5, 0.3, 0.2, 0.3, 0.8, 0.3, 0.1, 0.7, 0.2, 0.4, 0.6, 0.6, 0.7, 0.4, 0.6, 0.9, 0.6, 0.1, 0.9, 0.7, 0.9, 0.9, 0.4, 0.8, 0.8, 0.6, 0.9, 0.9, 0.9, 0.3, 0.8, 0.8, 0.7, 0.2, 0.8, 0.9, 0.4, 0.3, 0.4, 0.1, 0.9, 0.6, 0.9, 0.8, 0.9, 0.8, 0.3, 0.4, 0.1, 0.2, 0.4, 0.8, 0.4, 0.9, 0.5, 0.1, 0.1, 0.5, 0.8, 0.3, 0.7, 0.6, 0.8, 0.2, 0.5, 0.7, 0.1, 0.5, 0.7, 0.7, 0.4, 0.6, 0.5, 0.6, 0.4, 0.2, 0.6, 0.3, 0.5, 0.5, 0.2, 0.9, 0.8, 0.8, 0.1, 0.9, 0.4, 0.5, 0.2, 0.5, 0.3, 0.9, 0.6, 0.9, 0.5, 0.6, 0.6, 0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 0.8, 0.7, 0.5, 0.5, 0.3, 0.2, 0.4, 0.1, 0.3, 0.4, 0.3, 0.2, 0.9, 0.9, 0.1, 0.5, 0.3, 0.5, 0.9, 0.7, 0.8, 0.8, 0.7, 0.2, 0.2, 0.6, 0.5, 0.2, 0.5, 0.6, 0.7, 0.5, 0.8, 0.7, 0.3, 0.5, 0.9, 0.9, 0.6, 0.9, 0.4, 0.4, 0.8, 0.6, 0.4, 0.1, 0.8, 0.3, 0.5, 0.6, 0.4, 0.4, 0.1, 0.2, 0.5, 0.1, 0.7, 0.6, 0.7, 0.8, 0.8, 0.1, 0.9, 0.2, 0.5, 0.8, 0.5, 0.1, 0.5, 0.2, 0.4, 0.8, 0.3, 0.2, 0.5, 0.4, 0.7, 0.5, 0.7, 0.1, 0.3, 0.2, 0.6, 0.4, 0.4, 0.9, 0.8, 0.4, 0.1, 0.4, 0.5, 0.9, 0.2, 0.9, 0.8, 0.1, 0.2, 0.8, 0.4, 0.7, 0.4, 0.9, 0.9, 0.7, 0.1, 0.3, 0.9, 0.1, 0.5, 0.1, 0.4, 0.8, 0.7, 0.9, 0.9, 0.4, 0.6, 0.1, 0.8, 0.3, 0.4, 0.2, 0.4, 0.5, 0.5, 0.8, 0.3, 0.6, 0.1, 0.8, 0.8, 0.2, 0.1, 0.6, 0.8, 0.3, 0.6, 0.5, 0.8, 0.6, 0.2, 0.4, 0.5, 0.3, 0.1, 0.2, 0.2, 0.2, 0.4, 0.3, 0.6, 0.5, 0.2, 
+
+L2_dSYR_A_nn_pu
+0.9, 0.8, 0.3, 0.5, 0.4, 0.8, 0.1, 0.4, 0.7, 0.4, 0.4, 0.7, 0.6, 0.5, 0.2, 0.8, 0.6, 0.7, 0.3, 0.1, 0.9, 0.5, 0.7, 0.6, 0.2, 0.1, 0.7, 0.4, 0.9, 0.8, 0.5, 0.3, 0.5, 0.3, 0.8, 0.3, 0.1, 0.7, 0.2, 0.4, 0.6, 0.6, 0.7, 0.4, 0.6, 0.9, 0.6, 0.1, 0.9, 0.4, 0.8, 0.8, 0.6, 0.9, 0.9, 0.9, 0.3, 0.8, 0.8, 0.7, 0.2, 0.8, 0.1, 0.9, 0.6, 0.9, 0.8, 0.9, 0.8, 0.3, 0.4, 0.1, 0.2, 0.4, 0.8, 0.5, 0.8, 0.3, 0.7, 0.6, 0.8, 0.2, 0.5, 0.7, 0.1, 0.5, 0.7, 0.2, 0.6, 0.3, 0.5, 0.5, 0.2, 0.9, 0.8, 0.8, 0.1, 0.9, 0.9, 0.5, 0.6, 0.6, 0.5, 0.5, 0.5, 0.5, 0.5, 0.1, 0.3, 0.4, 0.3, 0.2, 0.9, 0.9, 0.1, 0.5, 0.3, 0.5, 0.2, 0.5, 0.6, 0.7, 0.5, 0.8, 0.7, 0.4, 0.1, 0.8, 0.3, 0.5, 0.6, 0.4, 0.9, 0.2, 0.5, 0.8, 0.5, 0.1, 0.3, 0.2, 0.6, 0.4, 0.4, 0.4, 0.7, 0.4, 0.9, 0.6, 0.1, 0.8, 0.8, 0.3, 0.2, 
+
+L2_dSYR_x_n1
+0.9, 0.7, 0.1, 0.8, 0.2, 0.9, 0.7, 0.8, 0.8, 0.4, 0.1, 0.9, 0.4, 0.3, 0.2, 0.1, 0.8, 
+
+L2_dSYR_x_n2
+0.9, 0.0, 0.7, 0.0, 0.1, 0.0, 0.8, 0.0, 0.2, 0.0, 0.9, 0.0, 0.7, 0.0, 0.8, 0.0, 0.8, 0.0, 0.4, 0.0, 0.1, 0.0, 0.9, 0.0, 0.4, 0.0, 0.3, 0.0, 0.2, 0.0, 0.1, 0.0, 0.8, 0.0, 
+
+L2_dSYR_o_N
+1.71, 1.43, 0.39, 1.22, 0.58, 1.61, 0.73, 1.12, 1.42, 0.76, 0.49, 1.51, 0.96, 0.77, 0.38, 0.89, 1.32, 1.13, 1.19, 0.37, 0.66, 1.04, 1.13, 1.19, 1.16, 0.76, 0.38, 0.77, 1.03, 1.18, 1.01, 0.64, 0.37, 1.06, 0.39, 0.27, 0.31, 0.88, 0.32, 0.19, 0.77, 0.28, 0.48, 0.64, 0.61, 0.79, 0.44, 0.63, 0.92, 0.61, 0.18, 1.62, 1.26, 0.98, 1.54, 0.56, 1.52, 1.36, 1.24, 1.54, 1.22, 0.98, 1.02, 1.12, 1.04, 0.86, 0.28, 1.44, 1.08, 0.54, 0.32, 0.56, 0.14, 1.08, 0.74, 1.06, 0.96, 0.98, 0.82, 0.48, 0.48, 0.16, 0.24, 0.42, 0.96, 1.21, 1.53, 0.59, 0.82, 0.28, 1.31, 1.43, 1.02, 1.42, 0.96, 0.89, 1.01, 0.86, 0.97, 0.28, 0.59, 1.42, 1.33, 0.89, 0.67, 1.06, 0.74, 1.03, 0.69, 1.16, 0.86, 0.78, 0.57, 0.83, 1.18, 1.01, 0.94, 0.17, 1.46, 1.12, 1.06, 0.28, 1.14, 0.46, 1.62, 1.16, 1.54, 1.14, 0.92, 0.68, 1.22, 0.82, 0.74, 0.66, 0.58, 0.74, 1.52, 1.26, 0.58, 1.14, 0.46, 0.92, 0.96, 0.74, 0.94, 0.72, 0.38, 0.92, 1.22, 1.14, 0.26, 0.58, 0.94, 0.86, 1.18, 0.74, 1.12, 0.88, 1.06, 0.48, 0.52, 0.92, 0.66, 0.24, 0.86, 0.76, 0.82, 0.58, 0.84, 1.02, 0.39, 0.57, 0.91, 0.98, 0.62, 0.99, 0.47, 0.48, 0.88, 0.64, 0.41, 0.19, 0.84, 0.33, 0.52, 0.61, 0.48, 1.21, 0.73, 0.29, 1.22, 0.28, 1.51, 1.23, 1.42, 1.52, 1.16, 0.19, 1.71, 0.56, 0.77, 0.98, 0.59, 0.82, 0.86, 0.48, 0.44, 1.12, 0.38, 0.56, 0.78, 0.72, 1.02, 0.66, 0.74, 0.46, 0.46, 0.32, 0.68, 0.44, 0.72, 1.17, 1.01, 0.43, 0.34, 0.46, 0.77, 1.11, 0.44, 1.14, 0.92, 0.13, 0.47, 0.92, 0.49, 0.76, 0.43, 1.14, 1.08, 0.84, 0.12, 0.46, 0.94, 0.28, 0.64, 0.26, 0.56, 0.88, 0.72, 1.08, 0.98, 0.46, 0.64, 0.12, 0.96, 0.39, 0.47, 0.21, 0.48, 0.52, 0.59, 0.87, 0.38, 0.68, 0.14, 0.81, 0.89, 0.24, 0.13, 0.62, 0.81, 0.38, 1.32, 1.06, 0.88, 1.24, 0.36, 1.12, 1.06, 0.94, 0.74, 0.52, 0.28, 0.92, 0.72, 0.54, 0.76, 0.58, 0.84, 
+
+L2_dSYR_o_N_pu
+1.71, 1.43, 0.39, 1.22, 0.58, 1.61, 0.73, 1.12, 1.42, 0.76, 0.49, 1.51, 0.96, 0.77, 0.38, 0.89, 1.32, 1.19, 0.37, 0.66, 1.04, 1.13, 1.19, 1.16, 0.76, 0.38, 0.77, 1.03, 1.18, 1.01, 0.64, 0.37, 1.06, 0.31, 0.88, 0.32, 0.19, 0.77, 0.28, 0.48, 0.64, 0.61, 0.79, 0.44, 0.63, 0.92, 0.61, 0.18, 1.54, 0.56, 1.52, 1.36, 1.24, 1.54, 1.22, 0.98, 1.02, 1.12, 1.04, 0.86, 0.28, 1.44, 0.14, 1.08, 0.74, 1.06, 0.96, 0.98, 0.82, 0.48, 0.48, 0.16, 0.24, 0.42, 0.96, 1.31, 1.43, 1.02, 1.42, 0.96, 0.89, 1.01, 0.86, 0.97, 0.28, 0.59, 1.42, 0.69, 1.16, 0.86, 0.78, 0.57, 0.83, 1.18, 1.01, 0.94, 0.17, 1.46, 1.54, 1.14, 0.92, 0.68, 1.22, 0.82, 0.74, 0.66, 0.58, 0.74, 0.94, 0.72, 0.38, 0.92, 1.22, 1.14, 0.26, 0.58, 0.94, 0.66, 0.24, 0.86, 0.76, 0.82, 0.58, 0.84, 1.02, 0.41, 0.19, 0.84, 0.33, 0.52, 0.61, 0.48, 1.71, 0.56, 0.77, 0.98, 0.59, 0.82, 0.46, 0.32, 0.68, 0.44, 0.72, 0.49, 0.76, 0.43, 1.14, 0.64, 0.12, 0.96, 0.81, 0.38, 0.84, 
+
+L2_sSYR2_A_nn
+0.7, 0.1, 0.5, 0.2, 0.2, 0.3, 0.3, 0.5, 0.8, 0.5, 0.6, 0.1, 0.4, 0.8, 0.9, 0.5, 0.1, 0.4, 0.8, 0.5, 0.2, 0.2, 0.4, 0.4, 0.3, 0.3, 0.4, 0.1, 0.2, 0.4, 0.4, 0.3, 0.4, 0.5, 0.8, 0.5, 0.2, 0.5, 0.9, 0.7, 0.5, 0.5, 0.8, 0.3, 0.5, 0.7, 0.8, 0.9, 0.4, 0.9, 0.6, 0.5, 0.8, 0.3, 0.3, 0.4, 0.4, 0.4, 0.1, 0.2, 0.5, 0.8, 0.1, 0.5, 0.2, 0.1, 0.9, 0.2, 0.6, 0.8, 0.3, 0.3, 0.8, 0.4, 0.5, 0.4, 0.4, 0.8, 0.1, 0.6, 0.8, 0.8, 0.1, 0.8, 0.8, 0.1, 0.2, 0.9, 0.3, 0.4, 0.2, 0.8, 0.9, 0.4, 0.6, 0.5, 0.7, 0.2, 0.5, 0.7, 0.4, 0.2, 0.6, 0.9, 0.9, 0.5, 0.8, 0.4, 0.7, 0.4, 0.7, 0.6, 0.3, 0.7, 0.7, 0.9, 0.1, 0.8, 0.5, 0.7, 0.5, 0.6, 0.3, 0.8, 0.7, 0.9, 0.9, 0.9, 0.8, 0.6, 0.9, 0.2, 0.9, 0.2, 0.4, 0.2, 0.7, 0.5, 0.9, 0.4, 0.1, 0.8, 0.7, 0.2, 0.9, 0.6, 0.9, 0.2, 0.3, 0.6, 0.8, 0.8, 0.9, 0.2, 0.7, 0.6, 0.1, 0.4, 0.9, 0.7, 0.5, 0.1, 0.1, 0.5, 0.6, 0.5, 0.4, 0.4, 0.3, 0.4, 0.9, 0.8, 0.2, 0.6, 0.8, 0.5, 0.1, 0.8, 0.7, 0.1, 0.2, 0.7, 0.9, 0.1, 0.8, 0.2, 0.9, 0.5, 0.3, 0.6, 0.2, 0.2, 0.4, 0.7, 0.5, 0.6, 0.7, 0.1, 0.7, 0.9, 0.4, 0.5, 0.4, 0.2, 0.7, 0.5, 0.7, 0.5, 0.6, 0.5, 0.1, 0.3, 0.9, 0.3, 0.4, 0.9, 0.5, 0.1, 0.8, 0.5, 0.2, 0.8, 0.6, 0.8, 0.1, 0.7, 0.6, 0.9, 0.2, 0.7, 0.7, 0.7, 0.7, 0.2, 0.8, 0.2, 0.4, 0.5, 0.1, 0.5, 0.5, 0.6, 0.2, 0.6, 0.2, 0.6, 0.6, 0.2, 0.7, 0.4, 0.3, 0.1, 0.1, 0.5, 0.4, 0.9, 0.1, 0.2, 0.7, 0.4, 0.8, 0.5, 0.7, 0.5, 0.9, 0.4, 0.8, 0.6, 0.3, 0.1, 0.6, 0.2, 0.7, 0.1, 0.8, 0.3, 0.8, 0.6, 0.1, 0.4, 0.8, 0.3, 0.2, 0.5, 0.2, 0.9, 0.9, 0.1, 0.8, 
+
+L2_sSYR2_A_nn_pu
+0.7, 0.1, 0.5, 0.2, 0.2, 0.3, 0.3, 0.5, 0.8, 0.5, 0.6, 0.1, 0.4, 0.8, 0.9, 0.5, 0.1, 0.8, 0.5, 0.2, 0.2, 0.4, 0.4, 0.3, 0.3, 0.4, 0.1, 0.2, 0.4, 0.4, 0.3, 0.4, 0.5, 0.2, 0.5, 0.9, 0.7, 0.5, 0.5, 0.8, 0.3, 0.5, 0.7, 0.8, 0.9, 0.4, 0.9, 0.6, 0.3, 0.4, 0.4, 0.4, 0.1, 0.2, 0.5, 0.8, 0.1, 0.5, 0.2, 0.1, 0.9, 0.2, 0.8, 0.4, 0.5, 0.4, 0.4, 0.8, 0.1, 0.6, 0.8, 0.8, 0.1, 0.8, 0.8, 0.2, 0.8, 0.9, 0.4, 0.6, 0.5, 0.7, 0.2, 0.5, 0.7, 0.4, 0.2, 0.7, 0.4, 0.7, 0.6, 0.3, 0.7, 0.7, 0.9, 0.1, 0.8, 0.5, 0.9, 0.9, 0.8, 0.6, 0.9, 0.2, 0.9, 0.2, 0.4, 0.2, 0.9, 0.6, 0.9, 0.2, 0.3, 0.6, 0.8, 0.8, 0.9, 0.1, 0.5, 0.6, 0.5, 0.4, 0.4, 0.3, 0.4, 0.2, 0.7, 0.9, 0.1, 0.8, 0.2, 0.9, 0.7, 0.9, 0.4, 0.5, 0.4, 0.2, 0.5, 0.1, 0.8, 0.5, 0.2, 0.8, 0.2, 0.4, 0.5, 0.1, 0.5, 0.4, 0.6, 0.2, 0.8, 
+
+L2_sSYR2_x_n1
+0.4, 0.4, 0.1, 0.2, 0.2, 0.9, 0.1, 0.7, 0.7, 0.6, 0.1, 0.4, 0.3, 0.6, 0.6, 0.4, 0.6, 
+
+L2_sSYR2_x_n2
+0.4, 0.0, 0.4, 0.0, 0.1, 0.0, 0.2, 0.0, 0.2, 0.0, 0.9, 0.0, 0.1, 0.0, 0.7, 0.0, 0.7, 0.0, 0.6, 0.0, 0.1, 0.0, 0.4, 0.0, 0.3, 0.0, 0.6, 0.0, 0.6, 0.0, 0.4, 0.0, 0.6, 0.0, 
+
+L2_sSYR2_y_n1
+0.4, 0.5, 0.8, 0.4, 0.9, 0.5, 0.5, 0.2, 0.7, 0.2, 0.8, 0.5, 0.5, 0.6, 0.1, 0.5, 0.2, 
+
+L2_sSYR2_y_n2
+0.4, 0.0, 0.0, 0.5, 0.0, 0.0, 0.8, 0.0, 0.0, 0.4, 0.0, 0.0, 0.9, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.2, 0.0, 0.0, 0.7, 0.0, 0.0, 0.2, 0.0, 0.0, 0.8, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.6, 0.0, 0.0, 0.1, 0.0, 0.0, 0.5, 0.0, 0.0, 0.2, 0.0, 0.0, 
+
+L2_sSYR2_o_N
+1.01999999762, 0.460000009239, 0.860000010729, 0.440000010133, 0.640000001192, 0.860000010729, 0.540000016093, 0.860000001788, 1.36000001073, 0.820000015497, 0.960000034571, 0.460000009239, 0.720000015497, 1.28000003815, 1.17999999046, 0.860000007749, 0.420000016987, 0.760000013709, 1.20000001788, 0.870000010282, 0.460000009239, 0.660000000298, 1.04999999702, 0.650000009686, 0.730000008345, 0.930000005364, 0.780000020266, 0.470000011772, 0.600000008941, 0.750000014901, 0.940000030994, 0.640000025034, 0.800000011921, 0.880000014305, 1.16000002265, 0.870000010282, 0.360000007749, 0.70000000596, 1.14999997988, 1.46999998048, 0.630000003129, 1.0799999994, 1.43000001058, 0.800000038743, 0.660000004768, 1.06999999836, 1.09000002578, 1.44000000566, 0.890000032485, 1.26999998644, 1.10000005066, 0.740000007153, 1.06000001818, 0.500000017881, 0.460000016689, 0.660000006258, 0.860000003278, 0.540000008643, 0.420000002086, 0.620000002086, 0.780000014305, 1.00000001788, 0.360000007749, 0.720000008047, 0.56000002265, 0.360000015199, 1.15999998242, 0.480000017285, 1.04000002205, 1.26000000924, 0.550000015646, 0.560000012219, 1.16000000775, 1.30999996454, 0.690000000447, 1.06999997973, 1.16999997824, 1.38000002027, 0.350000005215, 1.06000002116, 1.17000001699, 1.46000002563, 0.660000009239, 1.26000000924, 1.38000002027, 0.660000000298, 0.84999999404, 1.66999996856, 0.760000009239, 1.30999996454, 1.09999997914, 1.30000000075, 1.42999996811, 1.37999997258, 1.08000003368, 1.2699999924, 1.34999997914, 0.79999999702, 1.34000001907, 1.08999999896, 1.04999999702, 0.680000012815, 0.840000028014, 1.14999997988, 1.02999997929, 0.640000002682, 0.990000012368, 0.899999994785, 0.799999989569, 0.770000000596, 1.11999998197, 0.920000036359, 0.43000001505, 0.949999991804, 0.899999994785, 1.25999999136, 0.410000013709, 1.05000001565, 0.820000012517, 1.05999998987, 0.929999996424, 1.18000002325, 0.620000012517, 1.46999998569, 1.22999998003, 1.26999997079, 1.17999997556, 1.52999995917, 1.06000001818, 1.18000002325, 1.32999997258, 0.610000000298, 1.43999999225, 0.390000009388, 0.830000002384, 0.460000009239, 1.25999998689, 1.12999999344, 1.52999997482, 0.820000005066, 0.869999973774, 1.77999997854, 1.11999998197, 0.829999985993, 1.87999994278, 1.16000003308, 1.52999997482, 0.829999996424, 0.860000010729, 1.44000004292, 1.29000002131, 1.43000000536, 1.4599999854, 0.520000018477, 1.08000000238, 1.10000005066, 0.380000015795, 0.980000014305, 1.37999998599, 1.0200000006, 0.760000006258, 0.660000010729, 0.340000014603, 1.00000002682, 0.980000038147, 0.860000015199, 0.880000041127, 0.580000015795, 0.680000026226, 0.640000019073, 1.25999998689, 1.1700000222, 0.360000007749, 0.800000029802, 1.05000001565, 1.2699999924, 0.230000004619, 1.38000001132, 1.32999998674, 0.600000028312, 0.360000007749, 1.06999999836, 1.18999999002, 0.640000030994, 1.29000003844, 0.570000013262, 1.40000000298, 0.860000007749, 0.700000017881, 0.970000034124, 0.460000009239, 0.660000000298, 1.04999999702, 0.949999991804, 0.929999996424, 1.23000001729, 1.08000000238, 0.470000011772, 1.09999999404, 1.2499999851, 0.940000030994, 0.840000013113, 0.800000011921, 0.580000017285, 1.01999999762, 0.850000008941, 0.990000001937, 0.720000008047, 0.970000028908, 1.09999999404, 0.300000008196, 0.710000009239, 1.45999997497, 0.66000002712, 0.690000019819, 1.2499999851, 0.800000011921, 0.580000027716, 1.13000002548, 0.850000008941, 0.560000018179, 1.28000003815, 1.14000004888, 1.34000004143, 0.46000002116, 1.36000000179, 1.44000004292, 1.25999999136, 0.740000019073, 1.54000000715, 1.18000002325, 1.24000001758, 1.24000001311, 0.680000029206, 1.52000006914, 0.620000034869, 0.940000030994, 0.980000035167, 0.380000015795, 0.840000013113, 0.990000026524, 0.860000037551, 0.760000010729, 0.99000003472, 0.510000015199, 0.790000030249, 1.09000003323, 0.380000012815, 1.1900000146, 0.740000019073, 0.630000025481, 0.520000033379, 0.220000008047, 0.840000013113, 0.580000015795, 1.25999998391, 0.500000007451, 0.570000013262, 0.959999994338, 0.860000003278, 1.45000000298, 0.750000003725, 1.1299999845, 1.12999999344, 1.27999999046, 0.770000016242, 1.20000001788, 0.950000032783, 0.840000036955, 0.440000014603, 1.0000000298, 0.580000017285, 1.02000000358, 0.480000015795, 1.30000003874, 0.580000026226, 1.38000002027, 1.08000003368, 0.420000014007, 0.660000012219, 1.36000002116, 0.540000025034, 0.700000029802, 0.880000014305, 0.560000018179, 1.38000001132, 1.07999998599, 0.480000015795, 1.04000002503, 
+
+L2_sSYR2_o_N_pu
+1.01999999762, 0.460000009239, 0.860000010729, 0.440000010133, 0.640000001192, 0.860000010729, 0.540000016093, 0.860000001788, 1.36000001073, 0.820000015497, 0.960000034571, 0.460000009239, 0.720000015497, 1.28000003815, 1.17999999046, 0.860000007749, 0.420000016987, 1.20000001788, 0.870000010282, 0.460000009239, 0.660000000298, 1.04999999702, 0.650000009686, 0.730000008345, 0.930000005364, 0.780000020266, 0.470000011772, 0.600000008941, 0.750000014901, 0.940000030994, 0.640000025034, 0.800000011921, 0.880000014305, 0.360000007749, 0.70000000596, 1.14999997988, 1.46999998048, 0.630000003129, 1.0799999994, 1.43000001058, 0.800000038743, 0.660000004768, 1.06999999836, 1.09000002578, 1.44000000566, 0.890000032485, 1.26999998644, 1.10000005066, 0.460000016689, 0.660000006258, 0.860000003278, 0.540000008643, 0.420000002086, 0.620000002086, 0.780000014305, 1.00000001788, 0.360000007749, 0.720000008047, 0.56000002265, 0.360000015199, 1.15999998242, 0.480000017285, 1.16000000775, 1.30999996454, 0.690000000447, 1.06999997973, 1.16999997824, 1.38000002027, 0.350000005215, 1.06000002116, 1.17000001699, 1.46000002563, 0.660000009239, 1.26000000924, 1.38000002027, 1.09999997914, 1.30000000075, 1.42999996811, 1.37999997258, 1.08000003368, 1.2699999924, 1.34999997914, 0.79999999702, 1.34000001907, 1.08999999896, 1.04999999702, 0.680000012815, 0.799999989569, 0.770000000596, 1.11999998197, 0.920000036359, 0.43000001505, 0.949999991804, 0.899999994785, 1.25999999136, 0.410000013709, 1.05000001565, 0.820000012517, 1.17999997556, 1.52999995917, 1.06000001818, 1.18000002325, 1.32999997258, 0.610000000298, 1.43999999225, 0.390000009388, 0.830000002384, 0.460000009239, 1.87999994278, 1.16000003308, 1.52999997482, 0.829999996424, 0.860000010729, 1.44000004292, 1.29000002131, 1.43000000536, 1.4599999854, 0.340000014603, 1.00000002682, 0.980000038147, 0.860000015199, 0.880000041127, 0.580000015795, 0.680000026226, 0.640000019073, 0.360000007749, 1.06999999836, 1.18999999002, 0.640000030994, 1.29000003844, 0.570000013262, 1.40000000298, 1.09999999404, 1.2499999851, 0.940000030994, 0.840000013113, 0.800000011921, 0.580000017285, 0.800000011921, 0.580000027716, 1.13000002548, 0.850000008941, 0.560000018179, 1.52000006914, 0.620000034869, 0.940000030994, 0.980000035167, 0.220000008047, 0.840000013113, 0.580000015795, 1.0000000298, 0.580000017285, 1.04000002503, 
+
+L2_dSYR2_A_nn
+0.6, 0.4, 0.2, 0.3, 0.2, 0.3, 0.9, 0.5, 0.2, 0.7, 0.4, 0.6, 0.3, 0.7, 0.5, 0.4, 0.4, 0.2, 0.3, 0.3, 0.4, 0.7, 0.9, 0.8, 0.1, 0.3, 0.6, 0.3, 0.4, 0.1, 0.8, 0.3, 0.9, 0.7, 0.1, 0.2, 0.6, 0.7, 0.7, 0.6, 0.1, 0.4, 0.9, 0.8, 0.4, 0.4, 0.8, 0.3, 0.1, 0.9, 0.3, 0.6, 0.3, 0.4, 0.6, 0.9, 0.6, 0.9, 0.8, 0.3, 0.2, 0.9, 0.6, 0.3, 0.4, 0.9, 0.2, 0.1, 0.5, 0.6, 0.1, 0.4, 0.3, 0.5, 0.2, 0.2, 0.2, 0.4, 0.5, 0.5, 0.5, 0.8, 0.1, 0.5, 0.6, 0.1, 0.1, 0.1, 0.5, 0.8, 0.8, 0.7, 0.2, 0.3, 0.9, 0.7, 0.1, 0.7, 0.8, 0.6, 0.6, 0.2, 0.8, 0.3, 0.1, 0.1, 0.4, 0.8, 0.9, 0.9, 0.4, 0.9, 0.8, 0.2, 0.6, 0.5, 0.3, 0.4, 0.6, 0.1, 0.9, 0.1, 0.3, 0.5, 0.3, 0.3, 0.5, 0.7, 0.4, 0.4, 0.1, 0.6, 0.2, 0.8, 0.8, 0.1, 0.2, 0.4, 0.8, 0.6, 0.4, 0.4, 0.2, 0.5, 0.9, 0.8, 0.4, 0.9, 0.4, 0.2, 0.9, 0.9, 0.7, 0.8, 0.8, 0.6, 0.4, 0.2, 0.1, 0.3, 0.8, 0.9, 0.1, 0.9, 0.9, 0.1, 0.5, 0.2, 0.1, 0.3, 0.8, 0.3, 0.8, 0.2, 0.7, 0.9, 0.3, 0.6, 0.3, 0.8, 0.8, 0.4, 0.5, 0.8, 0.9, 0.1, 0.6, 0.1, 0.2, 0.7, 0.2, 0.1, 0.3, 0.2, 0.3, 0.3, 0.9, 0.8, 0.6, 0.1, 0.4, 0.9, 0.3, 0.2, 0.6, 0.5, 0.2, 0.9, 0.1, 0.5, 0.1, 0.7, 0.8, 0.4, 0.1, 0.6, 0.9, 0.1, 0.2, 0.9, 0.8, 0.7, 0.9, 0.6, 0.5, 0.2, 0.7, 0.4, 0.6, 0.2, 0.9, 0.1, 0.3, 0.2, 0.7, 0.2, 0.8, 0.6, 0.5, 0.6, 0.7, 0.6, 0.4, 0.8, 0.3, 0.3, 0.5, 0.9, 0.5, 0.5, 0.7, 0.9, 0.1, 0.9, 0.7, 0.4, 0.4, 0.6, 0.9, 0.2, 0.7, 0.9, 0.8, 0.5, 0.6, 0.8, 0.9, 0.1, 0.5, 0.1, 0.1, 0.8, 0.7, 0.2, 0.6, 0.4, 0.9, 0.3, 0.4, 0.6, 0.2, 0.8, 0.3, 0.1, 0.2, 0.9, 0.1, 0.1, 0.5, 
+
+L2_dSYR2_A_nn_pu
+0.6, 0.4, 0.2, 0.3, 0.2, 0.3, 0.9, 0.5, 0.2, 0.7, 0.4, 0.6, 0.3, 0.7, 0.5, 0.4, 0.4, 0.3, 0.3, 0.4, 0.7, 0.9, 0.8, 0.1, 0.3, 0.6, 0.3, 0.4, 0.1, 0.8, 0.3, 0.9, 0.7, 0.6, 0.7, 0.7, 0.6, 0.1, 0.4, 0.9, 0.8, 0.4, 0.4, 0.8, 0.3, 0.1, 0.9, 0.3, 0.6, 0.9, 0.6, 0.9, 0.8, 0.3, 0.2, 0.9, 0.6, 0.3, 0.4, 0.9, 0.2, 0.1, 0.3, 0.5, 0.2, 0.2, 0.2, 0.4, 0.5, 0.5, 0.5, 0.8, 0.1, 0.5, 0.6, 0.8, 0.7, 0.2, 0.3, 0.9, 0.7, 0.1, 0.7, 0.8, 0.6, 0.6, 0.2, 0.9, 0.9, 0.4, 0.9, 0.8, 0.2, 0.6, 0.5, 0.3, 0.4, 0.6, 0.5, 0.7, 0.4, 0.4, 0.1, 0.6, 0.2, 0.8, 0.8, 0.1, 0.9, 0.8, 0.4, 0.9, 0.4, 0.2, 0.9, 0.9, 0.7, 0.1, 0.9, 0.9, 0.1, 0.5, 0.2, 0.1, 0.3, 0.8, 0.4, 0.5, 0.8, 0.9, 0.1, 0.6, 0.6, 0.1, 0.4, 0.9, 0.3, 0.2, 0.9, 0.1, 0.2, 0.9, 0.8, 0.7, 0.2, 0.8, 0.6, 0.1, 0.9, 0.7, 0.1, 0.8, 0.5, 
+
+L2_dSYR2_x_n1
+0.6, 0.7, 0.1, 0.8, 0.8, 0.7, 0.3, 0.4, 0.4, 0.7, 0.1, 0.7, 0.1, 0.3, 0.4, 0.9, 0.3, 
+
+L2_dSYR2_x_n2
+0.6, 0.0, 0.7, 0.0, 0.1, 0.0, 0.8, 0.0, 0.8, 0.0, 0.7, 0.0, 0.3, 0.0, 0.4, 0.0, 0.4, 0.0, 0.7, 0.0, 0.1, 0.0, 0.7, 0.0, 0.1, 0.0, 0.3, 0.0, 0.4, 0.0, 0.9, 0.0, 0.3, 0.0, 
+
+L2_dSYR2_y_n1
+0.9, 0.4, 0.8, 0.5, 0.6, 0.7, 0.6, 0.2, 0.9, 0.4, 0.3, 0.1, 0.5, 0.1, 0.7, 0.7, 0.9, 
+
+L2_dSYR2_y_n2
+0.9, 0.0, 0.0, 0.4, 0.0, 0.0, 0.8, 0.0, 0.0, 0.5, 0.0, 0.0, 0.6, 0.0, 0.0, 0.7, 0.0, 0.0, 0.6, 0.0, 0.0, 0.2, 0.0, 0.0, 0.9, 0.0, 0.0, 0.4, 0.0, 0.0, 0.3, 0.0, 0.0, 0.1, 0.0, 0.0, 0.5, 0.0, 0.0, 0.1, 0.0, 0.0, 0.7, 0.0, 0.0, 0.7, 0.0, 0.0, 0.9, 0.0, 0.0, 
+
+L2_dSYR2_o_N
+1.68, 1.27, 0.77, 1.32, 1.28, 1.35, 1.53, 0.98, 1.1, 1.57, 0.67, 1.29, 0.69, 1.03, 1.28, 1.63, 1.21, 1.07, 0.86, 0.9, 1.07, 1.44, 1.67, 1.34, 0.4, 1.09, 1.16, 0.55, 0.75, 0.49, 0.99, 0.95, 1.75, 1.45, 0.67, 0.8, 0.76, 1.39, 1.4, 1.23, 0.4, 0.74, 1.31, 1.4, 0.51, 0.97, 0.93, 0.55, 0.49, 1.69, 0.63, 1.62, 0.97, 1.09, 1.4, 1.78, 1.51, 1.53, 1.16, 1.22, 0.87, 1.19, 1.03, 0.75, 0.63, 1.66, 1.21, 0.97, 1.58, 1.34, 0.8, 1.28, 1.26, 1.48, 0.86, 0.6, 1.16, 1.14, 0.8, 1.0, 0.96, 1.06, 0.9, 1.6, 1.5, 1.15, 0.87, 0.73, 1.41, 1.78, 1.78, 1.33, 0.62, 1.21, 1.67, 0.98, 0.66, 1.12, 1.08, 1.37, 1.72, 1.04, 1.43, 0.84, 0.4, 0.73, 1.06, 1.43, 1.26, 1.2, 0.91, 1.44, 0.95, 0.65, 0.81, 0.71, 0.75, 1.15, 1.05, 0.58, 1.2, 0.44, 0.66, 0.9, 0.72, 0.6, 0.66, 1.14, 0.7, 0.54, 0.28, 0.82, 0.3, 1.16, 1.26, 0.52, 1.1, 1.19, 1.21, 1.52, 1.36, 1.31, 0.71, 0.94, 1.62, 1.59, 0.61, 1.57, 0.69, 0.51, 1.54, 1.99, 1.33, 1.67, 1.36, 1.2, 1.07, 0.94, 0.87, 0.84, 1.1, 1.69, 0.66, 1.15, 1.25, 0.49, 0.69, 0.85, 0.95, 1.05, 1.07, 0.55, 0.91, 0.49, 1.0, 1.18, 0.45, 0.74, 0.51, 1.05, 0.86, 0.62, 0.58, 0.9, 1.09, 0.44, 0.78, 0.79, 0.55, 1.27, 0.63, 0.6, 0.86, 0.65, 0.48, 0.97, 1.25, 1.02, 0.74, 0.46, 0.5, 1.43, 0.88, 0.86, 0.99, 0.89, 0.33, 1.35, 0.56, 0.92, 0.31, 0.92, 1.09, 0.79, 0.18, 0.96, 1.0, 0.26, 0.47, 1.42, 1.04, 1.03, 1.09, 0.85, 0.73, 0.46, 0.98, 0.61, 0.7, 0.51, 1.09, 0.2, 0.4, 0.36, 0.76, 0.45, 1.1, 0.9, 1.28, 1.25, 1.09, 1.36, 1.2, 1.57, 0.75, 0.66, 1.14, 1.55, 0.69, 1.03, 0.97, 1.15, 0.66, 1.81, 1.27, 1.63, 1.25, 1.39, 1.91, 1.3, 1.82, 1.65, 1.26, 1.59, 1.45, 1.14, 1.48, 0.62, 0.8, 1.01, 1.36, 1.82, 1.51, 0.95, 0.93, 1.27, 1.8, 1.14, 0.85, 1.02, 0.83, 1.55, 0.48, 0.76, 0.44, 1.2, 0.67, 1.12, 1.04, 
+
+L2_dSYR2_o_N_pu
+1.68, 1.27, 0.77, 1.32, 1.28, 1.35, 1.53, 0.98, 1.1, 1.57, 0.67, 1.29, 0.69, 1.03, 1.28, 1.63, 1.21, 0.86, 0.9, 1.07, 1.44, 1.67, 1.34, 0.4, 1.09, 1.16, 0.55, 0.75, 0.49, 0.99, 0.95, 1.75, 1.45, 0.76, 1.39, 1.4, 1.23, 0.4, 0.74, 1.31, 1.4, 0.51, 0.97, 0.93, 0.55, 0.49, 1.69, 0.63, 1.4, 1.78, 1.51, 1.53, 1.16, 1.22, 0.87, 1.19, 1.03, 0.75, 0.63, 1.66, 1.21, 0.97, 1.26, 1.48, 0.86, 0.6, 1.16, 1.14, 0.8, 1.0, 0.96, 1.06, 0.9, 1.6, 1.5, 1.78, 1.33, 0.62, 1.21, 1.67, 0.98, 0.66, 1.12, 1.08, 1.37, 1.72, 1.04, 1.26, 1.2, 0.91, 1.44, 0.95, 0.65, 0.81, 0.71, 0.75, 1.15, 1.05, 0.66, 1.14, 0.7, 0.54, 0.28, 0.82, 0.3, 1.16, 1.26, 0.52, 1.62, 1.59, 0.61, 1.57, 0.69, 0.51, 1.54, 1.99, 1.33, 0.66, 1.15, 1.25, 0.49, 0.69, 0.85, 0.95, 1.05, 0.86, 0.62, 0.58, 0.9, 1.09, 0.44, 0.78, 0.74, 0.46, 0.5, 1.43, 0.88, 0.86, 1.0, 0.26, 0.47, 1.42, 1.04, 0.76, 0.45, 1.1, 0.9, 0.66, 1.81, 1.27, 1.36, 1.82, 1.04, 
+
+L3_sGEMM_A_mk
+0.4, 0.5, 0.6, 0.8, 0.9, 0.8, 0.2, 0.9, 0.6, 0.1, 0.1, 0.4, 0.5, 0.6, 0.1, 0.9, 0.9, 0.4, 0.7, 0.6, 0.5, 0.1, 0.8, 0.2, 0.9, 0.9, 0.5, 0.1, 0.4, 0.8, 0.6, 0.6, 0.5, 0.1, 0.1, 0.5, 0.7, 0.2, 0.6, 0.3, 0.2, 0.2, 0.1, 0.2, 0.3, 0.1, 0.4, 0.8, 0.2, 0.4, 0.3, 0.8, 0.3, 0.6, 0.8, 0.5, 0.6, 0.2, 0.5, 0.1, 0.5, 0.5, 0.2, 0.7, 0.8, 0.5, 0.4, 0.8, 0.6, 0.5, 0.7, 0.7, 0.5, 0.2, 0.6, 0.5, 0.6, 0.7, 0.7, 0.8, 0.9, 0.9, 0.4, 0.7, 0.3, 0.4, 0.2, 0.3, 0.4, 0.1, 0.4, 0.6, 0.7, 0.4, 0.9, 0.8, 0.3, 0.1, 0.5, 0.6, 0.4, 0.2, 0.3, 0.6, 0.8, 0.8, 0.5, 0.9, 0.2, 0.7, 0.2, 0.9, 0.9, 0.1, 0.9, 0.5, 0.1, 0.9, 0.6, 0.6, 0.7, 0.6, 0.7, 0.9, 0.9, 0.7, 0.9, 0.7, 0.2, 0.4, 0.4, 0.9, 0.3, 0.3, 0.8, 0.9, 0.9, 0.4, 0.6, 0.9, 0.6, 0.2, 0.3, 0.9, 0.6, 0.6, 0.3, 0.4, 0.1, 0.7, 0.5, 0.5, 0.4, 0.3, 0.6, 0.7, 0.3, 0.3, 0.3, 0.6, 
+
+L3_sGEMM_B_kn
+0.2, 0.4, 0.6, 0.5, 0.1, 0.9, 0.1, 0.6, 0.9, 0.1, 0.2, 0.3, 0.6, 0.9, 0.1, 0.1, 0.8, 0.9, 0.4, 0.1, 0.2, 0.8, 0.6, 0.3, 0.3, 0.8, 0.5, 0.1, 0.4, 0.6, 0.9, 0.6, 0.8, 0.2, 0.2, 0.2, 0.8, 0.5, 0.2, 0.3, 0.7, 0.5, 0.2, 0.8, 0.4, 0.4, 0.1, 0.4, 0.4, 0.6, 0.6, 0.1, 0.2, 0.8, 0.5, 0.3, 0.2, 0.8, 0.2, 0.3, 0.1, 0.4, 0.2, 0.7, 0.1, 0.1, 0.5, 0.4, 0.4, 0.8, 0.9, 0.3, 0.3, 0.4, 0.4, 0.5, 0.8, 0.4, 0.1, 0.4, 0.3, 0.8, 0.2, 0.7, 0.4, 0.8, 0.4, 0.5, 0.9, 0.9, 0.4, 0.5, 0.8, 0.5, 0.4, 0.1, 0.2, 0.1, 0.5, 0.5, 0.6, 0.7, 0.1, 0.3, 0.9, 0.8, 0.7, 0.4, 0.1, 0.2, 0.3, 0.6, 0.5, 0.1, 0.2, 0.4, 0.2, 0.9, 0.1, 0.7, 0.8, 0.7, 0.6, 0.4, 0.5, 0.8, 0.1, 0.4, 0.4, 0.9, 0.4, 0.5, 0.9, 0.4, 0.6, 0.1, 0.5, 0.9, 0.1, 0.7, 0.3, 0.8, 0.4, 0.5, 0.3, 0.6, 0.3, 0.3, 0.8, 0.1, 0.6, 0.7, 0.4, 0.4, 0.2, 0.2, 0.4, 0.3, 0.1, 0.6, 0.1, 0.2, 0.4, 0.2, 0.1, 0.1, 0.7, 0.4, 0.8, 0.8, 0.3, 0.2, 0.3, 0.2, 0.3, 0.8, 0.9, 0.2, 0.2, 0.2, 0.7, 0.8, 0.3, 0.2, 0.7, 0.2, 0.8, 0.9, 0.8, 0.4, 0.2, 0.7, 0.4, 0.6, 0.7, 0.5, 0.9, 0.9, 0.9, 0.8, 0.4, 0.6, 0.4, 0.3, 0.9, 0.8, 0.8, 0.1, 0.5, 0.4, 0.3, 0.1, 0.4, 0.2, 0.3, 0.7, 0.1, 0.8, 0.2, 0.5, 0.8, 0.7, 0.9, 0.2, 0.9, 0.6, 0.5, 0.1, 0.9, 0.3, 0.4, 0.5, 0.9, 0.5, 0.4, 0.3, 0.6, 0.8, 0.4, 0.4, 0.2, 0.1, 0.4, 0.3, 0.5, 0.3, 0.1, 0.7, 0.5, 0.5, 0.8, 0.7, 0.5, 0.7, 0.8, 0.1, 0.9, 0.9, 0.8, 0.4, 0.5, 0.1, 0.1, 0.9, 0.9, 0.2, 0.5, 0.7, 0.1, 0.6, 0.8, 0.7, 
+
+L3_sGEMM_C_mn
+0.6, 0.6, 0.7, 0.2, 0.5, 0.3, 0.4, 0.8, 0.7, 0.4, 0.1, 0.8, 0.9, 0.1, 0.1, 0.6, 0.7, 0.4, 0.5, 0.6, 0.3, 0.7, 0.6, 0.5, 0.7, 0.3, 0.7, 0.9, 0.9, 0.2, 0.3, 0.6, 0.9, 0.8, 0.5, 0.1, 0.5, 0.1, 0.9, 0.1, 0.1, 0.5, 0.6, 0.2, 0.6, 0.7, 0.4, 0.1, 0.5, 0.1, 0.3, 0.1, 0.6, 0.7, 0.2, 0.9, 0.8, 0.4, 0.8, 0.7, 0.7, 0.2, 0.3, 0.1, 0.6, 0.3, 0.6, 0.3, 0.3, 0.4, 0.9, 0.4, 0.2, 0.4, 0.8, 0.9, 0.9, 0.1, 0.9, 0.5, 0.6, 0.7, 0.5, 0.2, 0.2, 0.6, 0.9, 0.9, 0.1, 0.7, 0.8, 0.2, 0.3, 0.9, 0.5, 0.5, 0.6, 0.4, 0.9, 0.5, 0.9, 0.1, 0.1, 0.6, 0.1, 0.4, 0.8, 0.1, 0.9, 0.4, 0.9, 0.8, 0.3, 0.5, 0.3, 0.5, 0.7, 0.7, 0.5, 0.9, 0.5, 0.1, 0.1, 0.7, 0.4, 0.8, 0.6, 0.1, 0.9, 0.9, 0.1, 0.1, 0.2, 0.3, 0.8, 0.3, 0.4, 0.5, 0.3, 0.3, 0.2, 0.7, 0.3, 0.6, 0.5, 0.9, 0.9, 0.8, 0.3, 0.3, 0.9, 0.4, 0.1, 0.8, 0.6, 0.4, 0.8, 0.6, 0.2, 0.9, 0.5, 0.5, 0.7, 0.6, 0.7, 0.2, 0.6, 0.9, 0.2, 0.5, 
+
+L3_sGEMM_o_NN
+4.71000001967, 5.75000002831, 5.74999996126, 4.77000004604, 4.3200000602, 4.22000007287, 4.13000007316, 4.1900000757, 4.9799999994, 4.41000004128, 3.18000001431, 4.44000003919, 4.80000002384, 4.34999998435, 3.32000009745, 5.71000010684, 4.94000006303, 3.91000000998, 5.11000001222, 5.18000006944, 4.89000003174, 4.23000008509, 4.93000005528, 4.14000004441, 4.05000000894, 4.12000004679, 4.86000005692, 4.11000001818, 4.56000002116, 4.27000008702, 4.73999998778, 3.95000010431, 6.35000003353, 6.00000009388, 2.44000002801, 3.13000004932, 4.00000002012, 2.80000007078, 3.11000003606, 2.52000004679, 2.12000005424, 2.24000003472, 3.39000004962, 2.77000004753, 2.46000006363, 2.77000002518, 2.95000005588, 2.80000002682, 2.34000006974, 3.40000005439, 3.07000006542, 3.24000003695, 4.50000006557, 4.84000002205, 4.20000006631, 4.30000005588, 4.20000009835, 3.53000008285, 3.31000007927, 3.8500000529, 3.98000006422, 2.96000003606, 3.26000004724, 3.2900000608, 3.80000006333, 3.10000010431, 5.08000011861, 3.99000008762, 4.62000000879, 5.73000005007, 6.25000003129, 5.16000003234, 4.4600000599, 5.07000008404, 4.9100000897, 4.52000001773, 5.36000004277, 4.5300000307, 4.77999997854, 4.85000004247, 5.23000009254, 5.58999999449, 4.17000009447, 5.77000006616, 5.38000011563, 4.65999999061, 5.48000001132, 5.23000001207, 3.7500000298, 4.47000003189, 4.96000004649, 3.70000005588, 3.4800000605, 5.06999997601, 4.50000001341, 3.63000002325, 4.56000004053, 4.81000005618, 5.39999991208, 3.89000008762, 5.65000002012, 4.87000004157, 3.69999999031, 5.33000001132, 4.2200000304, 4.57000004381, 4.1600000681, 3.78000005752, 4.6700000684, 3.4700000006, 4.35000000149, 4.98000000983, 3.81000001222, 4.26999997899, 4.2600000532, 3.97000003487, 4.11000007108, 5.48000007167, 4.8300000672, 5.97999988243, 6.22999993831, 5.69999997914, 5.36999995515, 5.43999996394, 5.44999997765, 5.65000000894, 4.90999996901, 4.47999995396, 6.13999992892, 5.42999992862, 5.0899999103, 4.87999999046, 5.50999993473, 4.64000003248, 6.80000003725, 6.64999998808, 4.52999997556, 5.63999997735, 5.36999999389, 4.75000002012, 4.27000004232, 4.91000003904, 4.63000005975, 3.52000003636, 4.40000001714, 5.45999996975, 4.95999993771, 4.78000002027, 4.74999999627, 4.32000002816, 4.67000005499, 5.86000003457, 4.38000008211, 4.35000003949, 4.40000010431, 4.08000008062, 4.40000007674, 4.10000008568, 3.81000012025, 4.14000006378, 3.32000006318, 3.91000008151, 4.20000005364, 3.58000005081, 3.94000006229, 3.61000011876, 4.20000007302, 4.01000009865, 4.3000001289, 4.3000001356, 
+
+L3_sGEMM_A_km
+0.3, 0.6, 0.6, 0.1, 0.7, 0.5, 0.6, 0.8, 0.3, 0.3, 0.5, 0.3, 0.5, 0.6, 0.1, 0.7, 0.6, 0.6, 0.8, 0.2, 0.6, 0.3, 0.3, 0.3, 0.7, 0.4, 0.6, 0.4, 0.2, 0.9, 0.3, 0.2, 0.5, 0.3, 0.8, 0.4, 0.8, 0.7, 0.2, 0.1, 0.6, 0.2, 0.5, 0.5, 0.3, 0.2, 0.9, 0.5, 0.9, 0.4, 0.5, 0.7, 0.7, 0.4, 0.3, 0.4, 0.1, 0.9, 0.1, 0.9, 0.5, 0.4, 0.8, 0.1, 0.9, 0.9, 0.9, 0.6, 0.7, 0.8, 0.3, 0.6, 0.5, 0.4, 0.3, 0.8, 0.2, 0.1, 0.7, 0.6, 0.8, 0.2, 0.9, 0.2, 0.3, 0.5, 0.1, 0.9, 0.2, 0.7, 0.3, 0.7, 0.9, 0.1, 0.8, 0.7, 0.8, 0.8, 0.5, 0.2, 0.8, 0.5, 0.9, 0.8, 0.6, 0.2, 0.7, 0.7, 0.4, 0.9, 0.5, 0.9, 0.5, 0.2, 0.4, 0.7, 0.8, 0.7, 0.9, 0.8, 0.4, 0.2, 0.6, 0.6, 0.5, 0.7, 0.4, 0.2, 0.1, 0.5, 0.5, 0.3, 0.1, 0.1, 0.9, 0.3, 0.4, 0.3, 0.2, 0.4, 0.6, 0.4, 0.5, 0.7, 0.1, 0.1, 0.2, 0.5, 0.8, 0.5, 0.5, 0.9, 0.8, 0.1, 0.6, 0.7, 0.3, 0.7, 0.9, 0.6, 
+
+L3_sGEMM_B_nk
+0.8, 0.8, 0.1, 0.1, 0.7, 0.3, 0.4, 0.8, 0.7, 0.1, 0.2, 0.6, 0.5, 0.7, 0.5, 0.6, 0.2, 0.4, 0.6, 0.3, 0.5, 0.2, 0.6, 0.1, 0.8, 0.8, 0.2, 0.5, 0.7, 0.9, 0.6, 0.5, 0.1, 0.9, 0.9, 0.3, 0.9, 0.2, 0.3, 0.2, 0.2, 0.2, 0.4, 0.9, 0.6, 0.9, 0.8, 0.7, 0.1, 0.5, 0.4, 0.6, 0.7, 0.7, 0.9, 0.9, 0.7, 0.4, 0.5, 0.2, 0.3, 0.6, 0.5, 0.6, 0.2, 0.5, 0.3, 0.5, 0.7, 0.4, 0.9, 0.6, 0.8, 0.1, 0.3, 0.4, 0.3, 0.3, 0.5, 0.4, 0.3, 0.6, 0.9, 0.7, 0.9, 0.9, 0.5, 0.3, 0.1, 0.6, 0.7, 0.8, 0.6, 0.6, 0.5, 0.8, 0.6, 0.6, 0.7, 0.6, 0.3, 0.6, 0.3, 0.1, 0.1, 0.1, 0.5, 0.8, 0.1, 0.1, 0.7, 0.3, 0.7, 0.6, 0.3, 0.9, 0.2, 0.9, 0.4, 0.5, 0.2, 0.8, 0.3, 0.5, 0.9, 0.6, 0.2, 0.8, 0.9, 0.8, 0.9, 0.2, 0.8, 0.6, 0.6, 0.1, 0.6, 0.4, 0.5, 0.5, 0.7, 0.4, 0.1, 0.7, 0.5, 0.5, 0.9, 0.2, 0.3, 0.3, 0.1, 0.5, 0.2, 0.7, 0.1, 0.4, 0.9, 0.4, 0.4, 0.8, 0.2, 0.9, 0.5, 0.8, 0.6, 0.3, 0.7, 0.1, 0.9, 0.2, 0.9, 0.1, 0.8, 0.6, 0.1, 0.2, 0.4, 0.3, 0.7, 0.1, 0.7, 0.3, 0.2, 0.4, 0.6, 0.3, 0.1, 0.3, 0.8, 0.3, 0.7, 0.5, 0.8, 0.7, 0.3, 0.9, 0.6, 0.4, 0.3, 0.3, 0.6, 0.4, 0.5, 0.2, 0.7, 0.2, 0.1, 0.2, 0.8, 0.9, 0.3, 0.3, 0.1, 0.4, 0.3, 0.9, 0.8, 0.3, 0.6, 0.6, 0.4, 0.3, 0.7, 0.7, 0.7, 0.6, 0.7, 0.7, 0.4, 0.3, 0.9, 0.8, 0.3, 0.8, 0.7, 0.5, 0.3, 0.1, 0.7, 0.8, 0.3, 0.4, 0.7, 0.7, 0.2, 0.8, 0.6, 0.4, 0.8, 0.2, 0.6, 0.3, 0.9, 0.7, 0.2, 0.3, 0.5, 0.4, 0.6, 0.7, 0.1, 0.9, 0.4, 0.8, 0.8, 0.9, 0.9, 0.5, 0.7, 0.1, 0.4, 0.2, 
+
+L3_sGEMM_o_TT
+4.54000011742, 4.67000014588, 5.1700000371, 4.5900000824, 4.27000010267, 5.23000010967, 3.71000012323, 4.75000010133, 5.2200000982, 3.78000008211, 4.37000006169, 4.25000012591, 4.38000009179, 4.33000011861, 4.60000010058, 4.7700001362, 5.12000006691, 4.06000010759, 3.8900000459, 4.35000000149, 4.110000045, 3.75000004843, 5.29000005484, 3.69000007421, 5.06000000775, 4.30000004172, 4.19000001386, 3.69000001386, 3.76000003681, 3.11000007182, 4.450000076, 5.19000006154, 4.24000005633, 5.03000000611, 5.04000006825, 4.75000006557, 4.94000001535, 5.34999998212, 5.32000000954, 5.80000003353, 3.82000009075, 5.82000002444, 5.93000008583, 4.33000003591, 5.43999999449, 4.58000006273, 4.84000006005, 5.30000005215, 6.36000002116, 4.92000007138, 6.1099999474, 2.76000006512, 3.04000009805, 3.89000003621, 3.16000004724, 3.39000004441, 4.30000007749, 2.85000007898, 3.5700000833, 3.60000006929, 3.07000003934, 3.25000007004, 2.75000006557, 2.70000007451, 3.62000008777, 3.44000007421, 3.43000011042, 3.55000005886, 3.93000006497, 4.74000005558, 5.01999997228, 4.79000007346, 3.69000005484, 5.56000008076, 3.94000010028, 5.7900000295, 5.53000000313, 3.88000001431, 5.13000002027, 3.62000006169, 4.36000008747, 4.53000010297, 5.50000002235, 4.62000004977, 4.77000003636, 4.81000006586, 4.95999999434, 4.95999993548, 4.57999998599, 4.50000000149, 5.62000004977, 3.25000006631, 5.1700000006, 5.50999996901, 4.44999997094, 4.42999997333, 3.9000000678, 4.08000002474, 5.41999998495, 5.54999999106, 5.05000000745, 4.78999998108, 3.91000008076, 4.76000011653, 4.77000000954, 4.71000003159, 4.55000002831, 5.5900000675, 4.5300001052, 4.9600000979, 5.76000004649, 4.40000007823, 4.72000004381, 3.68000006497, 4.34000008613, 4.37000012949, 5.92000002444, 4.65000006706, 4.9500000298, 5.32000003561, 5.06000007629, 4.64999998659, 5.02000000581, 4.91000001371, 6.17000001252, 4.91000009865, 5.87000003114, 5.47000005201, 4.78000000536, 5.55999996901, 3.74000005484, 4.52000004679, 5.20000006109, 5.83000003591, 5.48000006348, 5.7799999547, 4.76000003532, 4.29000003397, 5.08999992594, 4.69999997094, 4.07999998748, 5.66999998495, 3.68000006944, 4.53000005007, 4.73000000387, 4.38999998108, 4.25999997273, 4.13000001505, 3.41000005469, 4.7300000076, 5.96999996483, 3.48000006124, 3.86000000402, 4.96000010386, 4.84000008985, 5.08999998927, 5.70000001118, 4.73000008658, 5.76999999613, 4.65000002086, 4.9400000377, 5.49000002727, 4.5300000076, 4.86999999389, 4.45000003502, 3.67000006318, 5.23000010595, 5.98000000164, 4.98000004187, 5.64999997392, 
+
+L3_sGEMM_o_HH
+4.54000011742, 4.67000014588, 5.1700000371, 4.5900000824, 4.27000010267, 5.23000010967, 3.71000012323, 4.75000010133, 5.2200000982, 3.78000008211, 4.37000006169, 4.25000012591, 4.38000009179, 4.33000011861, 4.60000010058, 4.7700001362, 5.12000006691, 4.06000010759, 3.8900000459, 4.35000000149, 4.110000045, 3.75000004843, 5.29000005484, 3.69000007421, 5.06000000775, 4.30000004172, 4.19000001386, 3.69000001386, 3.76000003681, 3.11000007182, 4.450000076, 5.19000006154, 4.24000005633, 5.03000000611, 5.04000006825, 4.75000006557, 4.94000001535, 5.34999998212, 5.32000000954, 5.80000003353, 3.82000009075, 5.82000002444, 5.93000008583, 4.33000003591, 5.43999999449, 4.58000006273, 4.84000006005, 5.30000005215, 6.36000002116, 4.92000007138, 6.1099999474, 2.76000006512, 3.04000009805, 3.89000003621, 3.16000004724, 3.39000004441, 4.30000007749, 2.85000007898, 3.5700000833, 3.60000006929, 3.07000003934, 3.25000007004, 2.75000006557, 2.70000007451, 3.62000008777, 3.44000007421, 3.43000011042, 3.55000005886, 3.93000006497, 4.74000005558, 5.01999997228, 4.79000007346, 3.69000005484, 5.56000008076, 3.94000010028, 5.7900000295, 5.53000000313, 3.88000001431, 5.13000002027, 3.62000006169, 4.36000008747, 4.53000010297, 5.50000002235, 4.62000004977, 4.77000003636, 4.81000006586, 4.95999999434, 4.95999993548, 4.57999998599, 4.50000000149, 5.62000004977, 3.25000006631, 5.1700000006, 5.50999996901, 4.44999997094, 4.42999997333, 3.9000000678, 4.08000002474, 5.41999998495, 5.54999999106, 5.05000000745, 4.78999998108, 3.91000008076, 4.76000011653, 4.77000000954, 4.71000003159, 4.55000002831, 5.5900000675, 4.5300001052, 4.9600000979, 5.76000004649, 4.40000007823, 4.72000004381, 3.68000006497, 4.34000008613, 4.37000012949, 5.92000002444, 4.65000006706, 4.9500000298, 5.32000003561, 5.06000007629, 4.64999998659, 5.02000000581, 4.91000001371, 6.17000001252, 4.91000009865, 5.87000003114, 5.47000005201, 4.78000000536, 5.55999996901, 3.74000005484, 4.52000004679, 5.20000006109, 5.83000003591, 5.48000006348, 5.7799999547, 4.76000003532, 4.29000003397, 5.08999992594, 4.69999997094, 4.07999998748, 5.66999998495, 3.68000006944, 4.53000005007, 4.73000000387, 4.38999998108, 4.25999997273, 4.13000001505, 3.41000005469, 4.7300000076, 5.96999996483, 3.48000006124, 3.86000000402, 4.96000010386, 4.84000008985, 5.08999998927, 5.70000001118, 4.73000008658, 5.76999999613, 4.65000002086, 4.9400000377, 5.49000002727, 4.5300000076, 4.86999999389, 4.45000003502, 3.67000006318, 5.23000010595, 5.98000000164, 4.98000004187, 5.64999997392, 
+
+L3_dGEMM_A_mk
+0.1, 0.2, 0.2, 0.9, 0.5, 0.1, 0.4, 0.1, 0.3, 0.2, 0.6, 0.5, 0.6, 0.4, 0.7, 0.9, 0.4, 0.9, 0.6, 0.8, 0.9, 0.7, 0.9, 0.5, 0.3, 0.1, 0.5, 0.6, 0.1, 0.8, 0.8, 0.3, 0.3, 0.2, 0.6, 0.6, 0.8, 0.6, 0.3, 0.2, 0.1, 0.1, 0.8, 0.7, 0.6, 0.3, 0.2, 0.2, 0.3, 0.6, 0.5, 0.8, 0.5, 0.5, 0.8, 0.7, 0.6, 0.3, 0.5, 0.2, 0.6, 0.8, 0.4, 0.1, 0.9, 0.4, 0.2, 0.2, 0.7, 0.2, 0.1, 0.1, 0.5, 0.6, 0.1, 0.6, 0.1, 0.5, 0.5, 0.6, 0.2, 0.8, 0.3, 0.1, 0.8, 0.3, 0.7, 0.4, 0.3, 0.4, 0.9, 0.2, 0.7, 0.8, 0.5, 0.8, 0.1, 0.7, 0.9, 0.5, 0.3, 0.3, 0.7, 0.8, 0.1, 0.7, 0.2, 0.5, 0.3, 0.6, 0.2, 0.7, 0.5, 0.4, 0.9, 0.1, 0.6, 0.5, 0.9, 0.7, 0.2, 0.7, 0.4, 0.1, 0.7, 0.9, 0.5, 0.6, 0.3, 0.4, 0.4, 0.8, 0.1, 0.5, 0.1, 0.8, 0.6, 0.2, 0.7, 0.7, 0.6, 0.2, 0.2, 0.2, 0.6, 0.3, 0.8, 0.9, 0.6, 0.8, 0.7, 0.9, 0.6, 0.5, 0.8, 0.6, 0.7, 0.8, 0.9, 0.6, 
+
+L3_dGEMM_B_kn
+0.7, 0.1, 0.3, 0.8, 0.9, 0.7, 0.3, 0.6, 0.8, 0.9, 0.5, 0.6, 0.6, 0.4, 0.2, 0.1, 0.4, 0.6, 0.7, 0.8, 0.8, 0.1, 0.9, 0.8, 0.7, 0.4, 0.8, 0.9, 0.8, 0.9, 0.5, 0.5, 0.4, 0.1, 0.7, 0.4, 0.5, 0.2, 0.5, 0.9, 0.8, 0.5, 0.5, 0.7, 0.5, 0.1, 0.5, 0.9, 0.4, 0.7, 0.8, 0.8, 0.1, 0.7, 0.6, 0.9, 0.5, 0.4, 0.2, 0.3, 0.4, 0.2, 0.7, 0.2, 0.9, 0.3, 0.6, 0.3, 0.9, 0.9, 0.8, 0.3, 0.1, 0.5, 0.2, 0.7, 0.6, 0.8, 0.2, 0.6, 0.4, 0.3, 0.1, 0.4, 0.1, 0.7, 0.8, 0.4, 0.2, 0.4, 0.6, 0.8, 0.3, 0.7, 0.4, 0.3, 0.1, 0.6, 0.5, 0.6, 0.3, 0.3, 0.6, 0.4, 0.8, 0.5, 0.1, 0.6, 0.4, 0.1, 0.7, 0.5, 0.2, 0.1, 0.7, 0.5, 0.9, 0.7, 0.9, 0.7, 0.2, 0.1, 0.3, 0.5, 0.6, 0.4, 0.4, 0.6, 0.7, 0.8, 0.3, 0.3, 0.1, 0.4, 0.1, 0.7, 0.2, 0.8, 0.6, 0.9, 0.4, 0.6, 0.7, 0.6, 0.8, 0.2, 0.2, 0.9, 0.5, 0.3, 0.6, 0.6, 0.1, 0.5, 0.2, 0.2, 0.8, 0.9, 0.3, 0.6, 0.8, 0.2, 0.1, 0.7, 0.4, 0.1, 0.5, 0.7, 0.4, 0.7, 0.8, 0.3, 0.4, 0.9, 0.9, 0.5, 0.6, 0.9, 0.6, 0.6, 0.4, 0.7, 0.4, 0.9, 0.3, 0.5, 0.2, 0.4, 0.3, 0.1, 0.7, 0.6, 0.8, 0.6, 0.5, 0.5, 0.7, 0.3, 0.1, 0.1, 0.9, 0.9, 0.8, 0.8, 0.3, 0.1, 0.8, 0.8, 0.7, 0.3, 0.3, 0.8, 0.3, 0.5, 0.3, 0.1, 0.7, 0.7, 0.9, 0.2, 0.9, 0.1, 0.2, 0.2, 0.2, 0.7, 0.9, 0.6, 0.4, 0.4, 0.2, 0.6, 0.4, 0.2, 0.6, 0.3, 0.7, 0.4, 0.8, 0.4, 0.7, 0.1, 0.6, 0.6, 0.2, 0.2, 0.4, 0.4, 0.3, 0.9, 0.7, 0.2, 0.3, 0.8, 0.6, 0.6, 0.7, 0.6, 0.1, 0.9, 0.4, 0.8, 0.3, 0.7, 0.2, 0.3, 0.1, 0.7, 0.5, 0.6, 0.2, 0.4, 
+
+L3_dGEMM_C_mn
+0.4, 0.4, 0.4, 0.3, 0.8, 0.4, 0.2, 0.3, 0.8, 0.7, 0.6, 0.7, 0.6, 0.9, 0.4, 0.3, 0.8, 0.4, 0.5, 0.9, 0.5, 0.1, 0.2, 0.5, 0.3, 0.9, 0.6, 0.7, 0.6, 0.5, 0.3, 0.1, 0.6, 0.7, 0.4, 0.5, 0.9, 0.4, 0.6, 0.9, 0.8, 0.2, 0.3, 0.1, 0.5, 0.3, 0.2, 0.6, 0.1, 0.9, 0.3, 0.6, 0.4, 0.1, 0.6, 0.6, 0.8, 0.9, 0.2, 0.3, 0.7, 0.9, 0.7, 0.7, 0.2, 0.2, 0.8, 0.8, 0.5, 0.3, 0.6, 0.3, 0.7, 0.5, 0.1, 0.2, 0.1, 0.1, 0.1, 0.4, 0.7, 0.4, 0.4, 0.3, 0.4, 0.4, 0.4, 0.3, 0.8, 0.1, 0.4, 0.4, 0.3, 0.3, 0.8, 0.4, 0.1, 0.5, 0.5, 0.7, 0.7, 0.3, 0.3, 0.6, 0.3, 0.5, 0.2, 0.9, 0.4, 0.4, 0.9, 0.4, 0.6, 0.9, 0.9, 0.2, 0.9, 0.7, 0.5, 0.3, 0.6, 0.3, 0.2, 0.6, 0.1, 0.2, 0.5, 0.2, 0.1, 0.6, 0.1, 0.7, 0.8, 0.8, 0.3, 0.5, 0.7, 0.6, 0.4, 0.9, 0.1, 0.6, 0.2, 0.1, 0.2, 0.2, 0.2, 0.7, 0.5, 0.6, 0.7, 0.6, 0.3, 0.5, 0.9, 0.1, 0.7, 0.9, 0.3, 0.4, 0.2, 0.8, 0.9, 0.1, 0.3, 0.5, 0.5, 0.2, 0.6, 0.5, 
+
+L3_dGEMM_o_NN
+4.44, 3.09, 4.19, 3.56, 5.07, 4.15, 3.56, 3.42, 4.18, 3.79, 2.89, 3.71, 3.77, 4.87, 3.74, 3.69, 3.97, 6.15, 4.61, 5.81, 4.72, 4.68, 6.23, 5.28, 4.42, 5.82, 5.6, 4.49, 4.83, 4.99, 5.28, 4.32, 5.38, 4.82, 4.57, 3.22, 4.28, 3.81, 4.38, 4.89, 4.2, 3.7, 3.78, 3.84, 2.91, 2.89, 3.14, 4.78, 3.28, 4.11, 3.43, 5.32, 3.64, 4.41, 4.82, 4.97, 5.89, 5.13, 4.13, 4.57, 4.84, 4.37, 4.39, 4.58, 4.65, 4.21, 4.79, 4.7, 4.13, 3.08, 3.57, 3.56, 4.49, 4.39, 3.35, 3.49, 3.56, 3.32, 2.75, 3.44, 3.59, 3.54, 3.28, 3.19, 3.11, 5.17, 4.07, 4.77, 4.88, 4.55, 5.28, 4.76, 4.66, 4.63, 4.91, 3.94, 3.66, 4.75, 4.87, 4.75, 4.46, 4.03, 4.74, 3.61, 3.94, 3.99, 4.41, 5.69, 4.77, 3.97, 4.71, 4.2, 4.22, 3.56, 4.38, 4.49, 4.93, 4.32, 4.64, 5.33, 4.06, 4.64, 4.12, 5.42, 5.4, 4.78, 4.78, 4.78, 4.43, 4.49, 3.28, 4.99, 5.34, 5.17, 4.26, 5.2, 4.67, 3.1, 3.54, 4.82, 4.28, 4.71, 3.91, 3.63, 3.77, 3.79, 3.07, 3.68, 3.46, 4.63, 4.2, 3.7, 3.55, 7.15, 5.23, 5.55, 6.03, 7.48, 7.0, 6.13, 5.46, 6.69, 6.44, 4.58, 5.01, 5.62, 6.58, 5.58, 5.92, 6.02, 
+
+L3_dGEMM_A_km
+0.4, 0.7, 0.4, 0.5, 0.8, 0.3, 0.9, 0.6, 0.5, 0.5, 0.7, 0.4, 0.6, 0.9, 0.2, 0.4, 0.1, 0.8, 0.9, 0.8, 0.8, 0.6, 0.6, 0.1, 0.5, 0.3, 0.1, 0.6, 0.5, 0.6, 0.6, 0.9, 0.2, 0.5, 0.2, 0.7, 0.2, 0.7, 0.9, 0.7, 0.3, 0.7, 0.8, 0.7, 0.4, 0.8, 0.5, 0.4, 0.5, 0.2, 0.3, 0.1, 0.7, 0.9, 0.7, 0.4, 0.5, 0.2, 0.9, 0.3, 0.1, 0.9, 0.1, 0.7, 0.3, 0.5, 0.5, 0.9, 0.9, 0.8, 0.1, 0.2, 0.4, 0.1, 0.9, 0.9, 0.1, 0.8, 0.5, 0.9, 0.6, 0.1, 0.3, 0.5, 0.3, 0.3, 0.6, 0.9, 0.8, 0.7, 0.2, 0.6, 0.1, 0.8, 0.7, 0.1, 0.5, 0.9, 0.3, 0.7, 0.9, 0.9, 0.5, 0.1, 0.4, 0.3, 0.6, 0.4, 0.4, 0.1, 0.8, 0.4, 0.1, 0.9, 0.5, 0.7, 0.5, 0.9, 0.4, 0.1, 0.5, 0.2, 0.7, 0.7, 0.4, 0.1, 0.5, 0.7, 0.9, 0.2, 0.9, 0.1, 0.4, 0.3, 0.2, 0.7, 0.9, 0.2, 0.8, 0.6, 0.5, 0.1, 0.5, 0.2, 0.8, 0.1, 0.6, 0.2, 0.7, 0.1, 0.1, 0.6, 0.7, 0.2, 0.8, 0.3, 0.3, 0.4, 0.8, 0.4, 
+
+L3_dGEMM_B_nk
+0.7, 0.9, 0.2, 0.6, 0.3, 0.5, 0.1, 0.1, 0.1, 0.7, 0.3, 0.1, 0.7, 0.8, 0.8, 0.1, 0.6, 0.2, 0.2, 0.9, 0.8, 0.4, 0.2, 0.7, 0.9, 0.4, 0.2, 0.3, 0.4, 0.2, 0.1, 0.2, 0.9, 0.7, 0.5, 0.1, 0.8, 0.3, 0.2, 0.8, 0.8, 0.7, 0.9, 0.7, 0.9, 0.4, 0.9, 0.6, 0.8, 0.1, 0.4, 0.6, 0.7, 0.1, 0.8, 0.1, 0.1, 0.3, 0.3, 0.8, 0.6, 0.1, 0.9, 0.2, 0.6, 0.9, 0.7, 0.6, 0.8, 0.1, 0.7, 0.9, 0.7, 0.9, 0.7, 0.5, 0.8, 0.1, 0.9, 0.2, 0.3, 0.6, 0.6, 0.3, 0.3, 0.3, 0.2, 0.9, 0.4, 0.3, 0.3, 0.5, 0.9, 0.1, 0.3, 0.2, 0.4, 0.1, 0.6, 0.2, 0.6, 0.7, 0.1, 0.9, 0.9, 0.2, 0.8, 0.9, 0.5, 0.7, 0.8, 0.9, 0.8, 0.5, 0.9, 0.1, 0.6, 0.1, 0.1, 0.9, 0.1, 0.9, 0.2, 0.6, 0.3, 0.9, 0.8, 0.9, 0.9, 0.6, 0.5, 0.4, 0.8, 0.8, 0.7, 0.1, 0.1, 0.5, 0.4, 0.4, 0.2, 0.7, 0.7, 0.5, 0.4, 0.5, 0.6, 0.5, 0.4, 0.2, 0.5, 0.8, 0.2, 0.6, 0.4, 0.5, 0.1, 0.7, 0.3, 0.8, 0.3, 0.8, 0.4, 0.2, 0.7, 0.7, 0.2, 0.1, 0.3, 0.5, 0.1, 0.4, 0.5, 0.9, 0.2, 0.8, 0.8, 0.1, 0.8, 0.7, 0.4, 0.6, 0.7, 0.5, 0.9, 0.3, 0.7, 0.9, 0.5, 0.9, 0.2, 0.6, 0.5, 0.9, 0.8, 0.3, 0.8, 0.2, 0.8, 0.5, 0.6, 0.7, 0.1, 0.4, 0.1, 0.5, 0.1, 0.9, 0.6, 0.1, 0.1, 0.4, 0.8, 0.8, 0.9, 0.7, 0.1, 0.2, 0.7, 0.8, 0.1, 0.9, 0.6, 0.2, 0.2, 0.9, 0.6, 0.6, 0.3, 0.5, 0.3, 0.3, 0.4, 0.2, 0.1, 0.8, 0.1, 0.1, 0.2, 0.7, 0.2, 0.5, 0.2, 0.5, 0.4, 0.5, 0.4, 0.1, 0.8, 0.9, 0.9, 0.8, 0.6, 0.3, 0.1, 0.6, 0.5, 0.7, 0.7, 0.2, 0.8, 0.5, 0.2, 0.7, 0.2, 0.2, 0.8, 0.9, 0.8, 0.6, 0.1, 0.2, 
+
+L3_dGEMM_o_TT
+4.12, 3.42, 5.45, 3.59, 5.61, 3.57, 4.91, 4.41, 4.75, 4.21, 4.1, 5.74, 4.23, 4.72, 3.57, 4.3, 5.26, 3.38, 3.71, 5.39, 4.24, 5.04, 2.91, 4.2, 4.13, 5.03, 4.34, 3.68, 5.21, 4.71, 4.14, 3.13, 4.49, 4.43, 3.64, 3.37, 5.68, 3.23, 4.95, 3.94, 5.2, 4.18, 4.15, 3.28, 4.09, 4.28, 3.83, 3.96, 2.91, 4.12, 4.23, 4.46, 3.94, 5.06, 4.29, 5.71, 4.09, 4.96, 4.01, 4.76, 4.12, 4.92, 5.33, 4.99, 4.28, 3.74, 5.22, 5.02, 3.9, 3.61, 6.12, 3.86, 5.83, 3.9, 5.23, 5.26, 4.37, 4.04, 3.52, 5.07, 4.74, 4.52, 3.47, 3.97, 4.34, 3.03, 3.71, 4.36, 3.7, 4.27, 3.23, 4.55, 4.07, 3.85, 4.38, 3.49, 4.49, 4.23, 4.65, 3.62, 3.8, 4.17, 3.84, 3.64, 5.23, 3.98, 4.54, 3.44, 4.86, 4.41, 5.11, 3.61, 3.95, 5.67, 4.33, 4.42, 3.2, 4.39, 4.16, 4.15, 4.95, 6.44, 4.42, 7.22, 4.4, 5.34, 5.49, 4.67, 4.66, 4.49, 5.92, 6.01, 5.15, 4.86, 5.34, 5.35, 5.6, 5.07, 6.8, 5.36, 6.57, 4.9, 6.19, 5.36, 5.78, 5.03, 5.2, 7.08, 5.95, 5.81, 5.08, 5.68, 5.42, 3.83, 4.43, 4.57, 3.48, 5.95, 3.54, 4.3, 4.47, 4.59, 4.91, 3.46, 4.92, 5.12, 4.03, 3.41, 4.12, 4.03, 
+
+L3_dGEMM_o_HH
+4.12, 3.42, 5.45, 3.59, 5.61, 3.57, 4.91, 4.41, 4.75, 4.21, 4.1, 5.74, 4.23, 4.72, 3.57, 4.3, 5.26, 3.38, 3.71, 5.39, 4.24, 5.04, 2.91, 4.2, 4.13, 5.03, 4.34, 3.68, 5.21, 4.71, 4.14, 3.13, 4.49, 4.43, 3.64, 3.37, 5.68, 3.23, 4.95, 3.94, 5.2, 4.18, 4.15, 3.28, 4.09, 4.28, 3.83, 3.96, 2.91, 4.12, 4.23, 4.46, 3.94, 5.06, 4.29, 5.71, 4.09, 4.96, 4.01, 4.76, 4.12, 4.92, 5.33, 4.99, 4.28, 3.74, 5.22, 5.02, 3.9, 3.61, 6.12, 3.86, 5.83, 3.9, 5.23, 5.26, 4.37, 4.04, 3.52, 5.07, 4.74, 4.52, 3.47, 3.97, 4.34, 3.03, 3.71, 4.36, 3.7, 4.27, 3.23, 4.55, 4.07, 3.85, 4.38, 3.49, 4.49, 4.23, 4.65, 3.62, 3.8, 4.17, 3.84, 3.64, 5.23, 3.98, 4.54, 3.44, 4.86, 4.41, 5.11, 3.61, 3.95, 5.67, 4.33, 4.42, 3.2, 4.39, 4.16, 4.15, 4.95, 6.44, 4.42, 7.22, 4.4, 5.34, 5.49, 4.67, 4.66, 4.49, 5.92, 6.01, 5.15, 4.86, 5.34, 5.35, 5.6, 5.07, 6.8, 5.36, 6.57, 4.9, 6.19, 5.36, 5.78, 5.03, 5.2, 7.08, 5.95, 5.81, 5.08, 5.68, 5.42, 3.83, 4.43, 4.57, 3.48, 5.95, 3.54, 4.3, 4.47, 4.59, 4.91, 3.46, 4.92, 5.12, 4.03, 3.41, 4.12, 4.03, 
+
+L3_cGEMM_A_mk
+0.5, 0.5, 0.40000000596, 0.300000011921, 0.40000000596, 0.20000000298, 0.800000011921, 0.800000011921, 0.600000023842, 0.10000000149, 0.10000000149, 0.600000023842, 0.10000000149, 0.5, 0.600000023842, 0.10000000149, 0.5, 0.899999976158, 0.899999976158, 0.899999976158, 0.5, 0.10000000149, 0.10000000149, 0.800000011921, 0.10000000149, 0.300000011921, 0.5, 0.899999976158, 0.300000011921, 0.20000000298, 0.699999988079, 0.10000000149, 0.10000000149, 0.40000000596, 0.300000011921, 0.899999976158, 0.300000011921, 0.300000011921, 0.899999976158, 0.699999988079, 0.899999976158, 0.600000023842, 0.699999988079, 0.899999976158, 0.40000000596, 0.5, 0.20000000298, 0.5, 0.40000000596, 0.600000023842, 0.699999988079, 0.20000000298, 0.10000000149, 0.20000000298, 0.699999988079, 0.800000011921, 0.800000011921, 0.699999988079, 0.800000011921, 0.899999976158, 0.40000000596, 0.20000000298, 0.10000000149, 0.40000000596, 0.300000011921, 0.10000000149, 0.699999988079, 0.5, 0.899999976158, 0.699999988079, 0.600000023842, 0.10000000149, 0.300000011921, 0.899999976158, 0.10000000149, 0.40000000596, 0.800000011921, 0.800000011921, 0.5, 0.5, 0.800000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.800000011921, 0.40000000596, 0.40000000596, 0.20000000298, 0.899999976158, 0.300000011921, 0.20000000298, 0.800000011921, 0.699999988079, 0.899999976158, 0.40000000596, 0.699999988079, 0.899999976158, 0.600000023842, 0.300000011921, 0.20000000298, 0.899999976158, 0.20000000298, 0.600000023842, 0.10000000149, 0.699999988079, 0.800000011921, 0.5, 0.899999976158, 0.10000000149, 0.5, 0.899999976158, 0.40000000596, 0.5, 0.10000000149, 0.600000023842, 0.5, 0.899999976158, 0.800000011921, 0.20000000298, 0.20000000298, 0.10000000149, 0.10000000149, 0.300000011921, 0.800000011921, 0.300000011921, 0.40000000596, 0.20000000298, 0.800000011921, 0.20000000298, 0.600000023842, 0.699999988079, 0.600000023842, 0.10000000149, 0.300000011921, 0.10000000149, 0.800000011921, 0.300000011921, 0.899999976158, 0.300000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.899999976158, 0.5, 0.10000000149, 0.10000000149, 0.5, 0.40000000596, 0.699999988079, 0.40000000596, 0.300000011921, 0.800000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.699999988079, 0.899999976158, 0.800000011921, 0.600000023842, 0.40000000596, 0.600000023842, 0.20000000298, 0.40000000596, 0.600000023842, 0.40000000596, 0.20000000298, 0.699999988079, 0.300000011921, 0.600000023842, 0.5, 0.10000000149, 0.40000000596, 0.699999988079, 0.899999976158, 0.699999988079, 0.300000011921, 0.300000011921, 0.800000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.800000011921, 0.699999988079, 0.600000023842, 0.699999988079, 0.5, 0.600000023842, 0.20000000298, 0.699999988079, 0.10000000149, 0.20000000298, 0.10000000149, 0.40000000596, 0.899999976158, 0.600000023842, 0.800000011921, 0.5, 0.600000023842, 0.5, 0.300000011921, 0.600000023842, 0.40000000596, 0.10000000149, 0.899999976158, 0.899999976158, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 0.699999988079, 0.20000000298, 0.300000011921, 0.300000011921, 0.5, 0.20000000298, 0.300000011921, 0.5, 0.10000000149, 0.300000011921, 0.699999988079, 0.800000011921, 0.800000011921, 0.5, 0.40000000596, 0.800000011921, 0.20000000298, 0.899999976158, 0.20000000298, 0.699999988079, 0.600000023842, 0.300000011921, 0.10000000149, 0.600000023842, 0.899999976158, 0.40000000596, 0.20000000298, 0.600000023842, 0.300000011921, 0.10000000149, 0.800000011921, 0.5, 0.5, 0.899999976158, 0.300000011921, 0.20000000298, 0.20000000298, 0.20000000298, 0.5, 0.800000011921, 0.300000011921, 0.20000000298, 0.699999988079, 0.600000023842, 0.20000000298, 0.699999988079, 0.699999988079, 0.699999988079, 0.5, 0.20000000298, 0.699999988079, 0.10000000149, 0.5, 0.10000000149, 0.5, 0.699999988079, 0.20000000298, 0.10000000149, 0.800000011921, 0.10000000149, 0.300000011921, 0.40000000596, 0.300000011921, 0.699999988079, 0.5, 0.20000000298, 0.5, 0.800000011921, 0.10000000149, 0.899999976158, 0.300000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.899999976158, 0.899999976158, 0.699999988079, 0.20000000298, 0.699999988079, 0.10000000149, 0.5, 0.899999976158, 0.699999988079, 0.5, 0.300000011921, 0.699999988079, 0.899999976158, 0.899999976158, 0.5, 0.800000011921, 0.300000011921, 0.300000011921, 0.10000000149, 0.699999988079, 0.5, 0.5, 0.40000000596, 0.5, 0.800000011921, 0.5, 0.40000000596, 0.40000000596, 0.800000011921, 0.40000000596, 0.600000023842, 0.800000011921, 0.300000011921, 0.5, 0.699999988079, 0.899999976158, 0.5, 
+
+L3_cGEMM_B_kn
+0.699999988079, 0.800000011921, 0.5, 0.5, 0.10000000149, 0.300000011921, 0.300000011921, 0.300000011921, 0.20000000298, 0.10000000149, 0.699999988079, 0.10000000149, 0.20000000298, 0.300000011921, 0.699999988079, 0.40000000596, 0.40000000596, 0.699999988079, 0.10000000149, 0.10000000149, 0.699999988079, 0.10000000149, 0.10000000149, 0.5, 0.699999988079, 0.300000011921, 0.600000023842, 0.40000000596, 0.300000011921, 0.800000011921, 0.20000000298, 0.300000011921, 0.10000000149, 0.20000000298, 0.5, 0.20000000298, 0.300000011921, 0.300000011921, 0.899999976158, 0.800000011921, 0.699999988079, 0.300000011921, 0.800000011921, 0.899999976158, 0.10000000149, 0.10000000149, 0.899999976158, 0.5, 0.20000000298, 0.40000000596, 0.20000000298, 0.899999976158, 0.699999988079, 0.899999976158, 0.800000011921, 0.699999988079, 0.20000000298, 0.20000000298, 0.300000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.10000000149, 0.300000011921, 0.699999988079, 0.20000000298, 0.899999976158, 0.5, 0.800000011921, 0.899999976158, 0.5, 0.5, 0.20000000298, 0.699999988079, 0.40000000596, 0.800000011921, 0.800000011921, 0.300000011921, 0.5, 0.899999976158, 0.899999976158, 0.800000011921, 0.899999976158, 0.10000000149, 0.300000011921, 0.20000000298, 0.40000000596, 0.10000000149, 0.5, 0.699999988079, 0.5, 0.5, 0.40000000596, 0.20000000298, 0.899999976158, 0.20000000298, 0.300000011921, 0.10000000149, 0.300000011921, 0.5, 0.800000011921, 0.899999976158, 0.5, 0.20000000298, 0.20000000298, 0.40000000596, 0.20000000298, 0.40000000596, 0.600000023842, 0.300000011921, 0.899999976158, 0.300000011921, 0.300000011921, 0.699999988079, 0.300000011921, 0.40000000596, 0.600000023842, 0.20000000298, 0.10000000149, 0.600000023842, 0.10000000149, 0.10000000149, 0.899999976158, 0.10000000149, 0.699999988079, 0.800000011921, 0.20000000298, 0.10000000149, 0.40000000596, 0.899999976158, 0.10000000149, 0.5, 0.899999976158, 0.40000000596, 0.40000000596, 0.899999976158, 0.899999976158, 0.20000000298, 0.10000000149, 0.899999976158, 0.20000000298, 0.300000011921, 0.699999988079, 0.800000011921, 0.40000000596, 0.40000000596, 0.899999976158, 0.800000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.300000011921, 0.600000023842, 0.20000000298, 0.10000000149, 0.800000011921, 0.300000011921, 0.600000023842, 0.40000000596, 0.5, 0.600000023842, 0.699999988079, 0.40000000596, 0.899999976158, 0.10000000149, 0.5, 0.5, 0.10000000149, 0.300000011921, 0.5, 0.40000000596, 0.300000011921, 0.699999988079, 0.699999988079, 0.20000000298, 0.20000000298, 0.600000023842, 0.300000011921, 0.5, 0.5, 0.40000000596, 0.20000000298, 0.600000023842, 0.20000000298, 0.10000000149, 0.300000011921, 0.5, 0.5, 0.699999988079, 0.10000000149, 0.40000000596, 0.800000011921, 0.899999976158, 0.800000011921, 0.20000000298, 0.5, 0.5, 0.5, 0.800000011921, 0.600000023842, 0.5, 0.800000011921, 0.5, 0.20000000298, 0.10000000149, 0.300000011921, 0.10000000149, 0.40000000596, 0.600000023842, 0.40000000596, 0.20000000298, 0.300000011921, 0.300000011921, 0.600000023842, 0.10000000149, 0.800000011921, 0.800000011921, 0.699999988079, 0.699999988079, 0.800000011921, 0.899999976158, 0.20000000298, 0.699999988079, 0.40000000596, 0.899999976158, 0.600000023842, 0.20000000298, 0.40000000596, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.699999988079, 0.600000023842, 0.20000000298, 0.699999988079, 0.10000000149, 0.899999976158, 0.5, 0.300000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.5, 0.40000000596, 0.20000000298, 0.5, 0.699999988079, 0.800000011921, 0.699999988079, 0.800000011921, 0.5, 0.899999976158, 0.300000011921, 0.5, 0.20000000298, 0.300000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.300000011921, 0.899999976158, 0.20000000298, 0.699999988079, 0.40000000596, 0.20000000298, 0.699999988079, 0.699999988079, 0.20000000298, 0.5, 0.300000011921, 0.10000000149, 0.40000000596, 0.800000011921, 0.699999988079, 0.20000000298, 0.10000000149, 0.10000000149, 0.20000000298, 0.899999976158, 0.600000023842, 0.699999988079, 0.20000000298, 0.899999976158, 0.600000023842, 0.5, 0.300000011921, 0.300000011921, 0.20000000298, 0.300000011921, 0.600000023842, 0.5, 0.300000011921, 0.20000000298, 0.800000011921, 0.10000000149, 0.300000011921, 0.899999976158, 0.300000011921, 0.300000011921, 0.899999976158, 0.10000000149, 0.10000000149, 0.899999976158, 0.20000000298, 0.600000023842, 0.300000011921, 0.5, 0.899999976158, 0.40000000596, 0.20000000298, 0.5, 0.600000023842, 0.699999988079, 0.800000011921, 0.40000000596, 0.800000011921, 0.20000000298, 0.5, 0.20000000298, 0.10000000149, 0.5, 0.600000023842, 0.600000023842, 0.20000000298, 0.5, 0.40000000596, 0.5, 0.800000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.40000000596, 0.5, 0.899999976158, 0.10000000149, 0.5, 0.800000011921, 0.5, 0.20000000298, 0.10000000149, 0.40000000596, 0.699999988079, 0.600000023842, 0.300000011921, 0.5, 0.40000000596, 0.300000011921, 0.600000023842, 0.300000011921, 0.40000000596, 0.600000023842, 0.300000011921, 0.699999988079, 0.40000000596, 0.5, 0.10000000149, 0.10000000149, 0.699999988079, 0.899999976158, 0.20000000298, 0.10000000149, 0.699999988079, 0.800000011921, 0.20000000298, 0.699999988079, 0.40000000596, 0.20000000298, 0.699999988079, 0.800000011921, 0.899999976158, 0.40000000596, 0.899999976158, 0.40000000596, 0.10000000149, 0.600000023842, 0.600000023842, 0.40000000596, 0.10000000149, 0.699999988079, 0.600000023842, 0.800000011921, 0.300000011921, 0.600000023842, 0.20000000298, 0.10000000149, 0.699999988079, 0.699999988079, 0.20000000298, 0.20000000298, 0.20000000298, 0.10000000149, 0.5, 0.20000000298, 0.899999976158, 0.40000000596, 0.20000000298, 0.5, 0.899999976158, 0.10000000149, 0.300000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.40000000596, 0.20000000298, 0.800000011921, 0.800000011921, 0.40000000596, 0.300000011921, 0.5, 0.20000000298, 0.10000000149, 0.699999988079, 0.600000023842, 0.800000011921, 0.40000000596, 0.899999976158, 0.5, 0.699999988079, 0.5, 0.800000011921, 0.800000011921, 0.300000011921, 0.10000000149, 0.699999988079, 0.800000011921, 0.10000000149, 0.20000000298, 0.600000023842, 0.300000011921, 0.800000011921, 0.899999976158, 0.40000000596, 0.20000000298, 0.300000011921, 0.20000000298, 0.800000011921, 0.10000000149, 0.40000000596, 0.5, 0.600000023842, 0.300000011921, 0.899999976158, 0.20000000298, 0.5, 0.899999976158, 0.300000011921, 0.20000000298, 0.699999988079, 0.5, 0.300000011921, 0.5, 0.10000000149, 0.5, 0.40000000596, 0.300000011921, 0.800000011921, 0.300000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.10000000149, 0.300000011921, 0.300000011921, 0.600000023842, 0.699999988079, 0.899999976158, 0.899999976158, 0.699999988079, 0.800000011921, 0.20000000298, 0.600000023842, 0.20000000298, 0.300000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.40000000596, 0.10000000149, 0.20000000298, 0.800000011921, 0.40000000596, 0.5, 0.800000011921, 0.300000011921, 0.10000000149, 0.5, 0.300000011921, 0.300000011921, 0.20000000298, 0.300000011921, 0.699999988079, 0.20000000298, 0.600000023842, 0.600000023842, 0.20000000298, 0.20000000298, 0.10000000149, 0.300000011921, 0.10000000149, 0.20000000298, 0.40000000596, 0.40000000596, 0.699999988079, 0.800000011921, 0.40000000596, 0.800000011921, 0.800000011921, 0.5, 0.899999976158, 0.40000000596, 0.10000000149, 0.10000000149, 0.40000000596, 0.5, 0.20000000298, 0.800000011921, 0.899999976158, 0.5, 0.300000011921, 0.5, 0.600000023842, 0.600000023842, 0.800000011921, 0.40000000596, 0.40000000596, 0.10000000149, 0.10000000149, 0.899999976158, 0.800000011921, 0.5, 0.300000011921, 0.10000000149, 0.5, 0.40000000596, 0.20000000298, 0.899999976158, 0.800000011921, 0.600000023842, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 
+
+L3_cGEMM_C_mn
+0.699999988079, 0.800000011921, 0.600000023842, 0.800000011921, 0.20000000298, 0.300000011921, 0.40000000596, 0.699999988079, 0.5, 0.899999976158, 0.40000000596, 0.5, 0.600000023842, 0.600000023842, 0.800000011921, 0.20000000298, 0.699999988079, 0.20000000298, 0.699999988079, 0.40000000596, 0.300000011921, 0.5, 0.10000000149, 0.5, 0.40000000596, 0.600000023842, 0.800000011921, 0.40000000596, 0.20000000298, 0.899999976158, 0.40000000596, 0.10000000149, 0.300000011921, 0.40000000596, 0.899999976158, 0.800000011921, 0.600000023842, 0.10000000149, 0.800000011921, 0.699999988079, 0.899999976158, 0.699999988079, 0.5, 0.5, 0.300000011921, 0.600000023842, 0.20000000298, 0.899999976158, 0.300000011921, 0.10000000149, 0.10000000149, 0.40000000596, 0.40000000596, 0.20000000298, 0.300000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.899999976158, 0.899999976158, 0.40000000596, 0.20000000298, 0.40000000596, 0.600000023842, 0.300000011921, 0.40000000596, 0.5, 0.20000000298, 0.5, 0.899999976158, 0.10000000149, 0.5, 0.899999976158, 0.10000000149, 0.600000023842, 0.20000000298, 0.800000011921, 0.800000011921, 0.600000023842, 0.10000000149, 0.5, 0.800000011921, 0.800000011921, 0.5, 0.10000000149, 0.699999988079, 0.40000000596, 0.10000000149, 0.5, 0.5, 0.40000000596, 0.10000000149, 0.800000011921, 0.5, 0.10000000149, 0.699999988079, 0.899999976158, 0.300000011921, 0.899999976158, 0.10000000149, 0.20000000298, 0.10000000149, 0.10000000149, 0.40000000596, 0.699999988079, 0.800000011921, 0.600000023842, 0.800000011921, 0.800000011921, 0.800000011921, 0.5, 0.800000011921, 0.899999976158, 0.300000011921, 0.800000011921, 0.800000011921, 0.10000000149, 0.10000000149, 0.600000023842, 0.300000011921, 0.40000000596, 0.800000011921, 0.600000023842, 0.40000000596, 0.20000000298, 0.5, 0.899999976158, 0.5, 0.300000011921, 0.699999988079, 0.899999976158, 0.699999988079, 0.300000011921, 0.800000011921, 0.10000000149, 0.40000000596, 0.800000011921, 0.899999976158, 0.5, 0.699999988079, 0.699999988079, 0.699999988079, 0.5, 0.40000000596, 0.600000023842, 0.899999976158, 0.600000023842, 0.5, 0.40000000596, 0.800000011921, 0.20000000298, 0.10000000149, 0.10000000149, 0.600000023842, 0.600000023842, 0.699999988079, 0.300000011921, 0.899999976158, 0.600000023842, 0.699999988079, 0.20000000298, 0.10000000149, 0.300000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.699999988079, 0.800000011921, 0.5, 0.600000023842, 0.600000023842, 0.20000000298, 0.699999988079, 0.699999988079, 0.20000000298, 0.800000011921, 0.40000000596, 0.10000000149, 0.800000011921, 0.800000011921, 0.699999988079, 0.10000000149, 0.300000011921, 0.800000011921, 0.699999988079, 0.10000000149, 0.300000011921, 0.300000011921, 0.10000000149, 0.300000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.800000011921, 0.300000011921, 0.40000000596, 0.300000011921, 0.899999976158, 0.800000011921, 0.300000011921, 0.40000000596, 0.10000000149, 0.800000011921, 0.20000000298, 0.40000000596, 0.699999988079, 0.20000000298, 0.699999988079, 0.40000000596, 0.300000011921, 0.300000011921, 0.699999988079, 0.10000000149, 0.800000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.20000000298, 0.20000000298, 0.699999988079, 0.899999976158, 0.300000011921, 0.800000011921, 0.5, 0.40000000596, 0.600000023842, 0.899999976158, 0.300000011921, 0.20000000298, 0.600000023842, 0.5, 0.800000011921, 0.40000000596, 0.699999988079, 0.699999988079, 0.800000011921, 0.300000011921, 0.899999976158, 0.800000011921, 0.20000000298, 0.800000011921, 0.20000000298, 0.899999976158, 0.600000023842, 0.600000023842, 0.5, 0.300000011921, 0.20000000298, 0.300000011921, 0.40000000596, 0.300000011921, 0.20000000298, 0.899999976158, 0.600000023842, 0.5, 0.899999976158, 0.699999988079, 0.699999988079, 0.699999988079, 0.5, 0.800000011921, 0.699999988079, 0.5, 0.699999988079, 0.600000023842, 0.10000000149, 0.600000023842, 0.10000000149, 0.20000000298, 0.10000000149, 0.699999988079, 0.800000011921, 0.600000023842, 0.800000011921, 0.5, 0.300000011921, 0.800000011921, 0.899999976158, 0.20000000298, 0.5, 0.600000023842, 0.300000011921, 0.20000000298, 0.600000023842, 0.899999976158, 0.699999988079, 0.600000023842, 0.899999976158, 0.40000000596, 0.40000000596, 0.300000011921, 0.699999988079, 0.10000000149, 0.10000000149, 0.699999988079, 0.20000000298, 0.800000011921, 0.20000000298, 0.699999988079, 0.20000000298, 0.600000023842, 0.20000000298, 0.10000000149, 0.5, 0.5, 0.300000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.600000023842, 0.600000023842, 0.699999988079, 0.600000023842, 0.20000000298, 0.5, 0.10000000149, 0.20000000298, 0.600000023842, 0.10000000149, 0.20000000298, 0.10000000149, 0.5, 0.40000000596, 0.40000000596, 0.300000011921, 0.899999976158, 0.699999988079, 0.800000011921, 0.300000011921, 0.699999988079, 0.10000000149, 0.899999976158, 0.5, 0.20000000298, 0.600000023842, 0.600000023842, 0.899999976158, 0.699999988079, 0.899999976158, 0.699999988079, 
+
+L3_cGEMM_o_NN
+0.65000000447, 6.93000006944, 0.619999984205, 7.09000004292, -0.370000001341, 5.88000005975, -0.699999899417, 7.83000014767, 1.60999999061, 8.18000006869, 0.810000075549, 7.00000005141, 1.14000006378, 7.98000015587, 1.26000003085, 5.7000001058, 0.0599999965727, 5.66000009716, 0.270000060946, 7.01000003755, 1.23999999151, 6.86000004053, -0.400000051409, 7.77000009969, 0.540000047386, 8.1199999693, 0.150000059605, 8.09000000864, 0.82999988541, 8.40000001267, -0.139999985546, 6.51000006661, -0.329999949485, 7.43000005901, 0.559999913126, 8.1400000675, 0.270000009537, 7.05999999732, -0.839999984801, 7.67999997109, -0.0400000347197, 9.4500000909, 0.250000024587, 9.26000006735, -0.160000012964, 7.92000003263, 0.159999974221, 10.0900000519, 0.160000004768, 6.94000011072, -0.829999945015, 6.81000010014, 0.0700000706315, 7.39000000715, 0.219999935776, 9.03000007167, -0.480000014305, 8.39000007048, 0.949999986589, 8.81999993652, -0.949999913573, 9.11999993876, -0.270000070632, 8.78000008285, 0.0499999679625, 7.73000001281, -0.819999955893, 9.07000001103, 1.4999999769, 9.30999993622, 1.14999997616, 6.62000007361, -0.0300000105798, 8.17000000581, 0.23000007093, 8.80000006407, 2.7600000301, 10.320000046, 0.160000064373, 8.65999998242, 1.77999996588, 10.7400000601, 2.13999994457, 7.7800000672, 0.889999983311, 7.89000001907, 0.700000053644, 7.6700000304, 1.72999997333, 8.11000003308, 0.61999998495, 7.86000010014, 1.81999999464, 8.34999999031, 0.0600000673532, 9.49000000492, 1.85999986917, 9.28000010297, 1.00999995261, 8.04000003099, 0.600000044703, 9.68000001952, 0.959999904931, 8.00000002459, 0.989999938607, 7.33000001356, -0.0100000233948, 7.18000007838, 0.49999999404, 8.00000013486, 2.02000000358, 8.31000010833, 1.7499998942, 8.03000001505, 1.70999993324, 8.84000010774, 0.949999852479, 6.18000011787, 0.910000015199, 6.50000012666, -0.399999999255, 7.04000001758, 1.59999996424, 6.77000008628, -0.0100000695884, 8.39000002876, 0.679999970347, 8.00999997944, 0.140000016838, 8.16000004947, 0.999999836832, 9.1900000377, 0.549999958277, 7.77000008032, 0.330000004619, 7.95000005364, 0.549999903142, 8.02000004753, -0.41000002414, 6.76000010014, -1.08000006273, 7.64000001684, -1.30000002757, 8.45000019744, 0.38000001654, 9.96000006437, -0.639999954253, 8.13000002548, -0.0400000220537, 9.58000011042, 0.369999916404, 7.03000012606, -0.760000035316, 6.56000008374, 0.260000012964, 8.14000003397, 0.249999967217, 8.4100001061, -2.02000002593, 8.16000005022, -0.469999979734, 7.90999995857, -1.63999994457, 8.51000011504, -0.870000130981, 9.27000010043, -0.370000122041, 8.36000008225, -0.420000030398, 9.01000014335, 1.49999993294, 6.58000013426, 1.21999993429, 7.26000010535, -0.130000039637, 7.50000008494, 0.389999991506, 7.95000019595, 1.69999997839, 8.76000019252, 0.74999999404, 7.12000005946, 1.19999998733, 9.47000014886, 1.92999992192, 6.48000012532, 0.999999966472, 6.35000010505, 0.369999996126, 7.37000009969, 2.14999990389, 7.84000009656, -0.0500000603497, 8.83000014096, 1.57999994501, 7.75000004694, 0.730000021756, 8.79000005707, 1.46999988064, 8.79000008687, 0.389999973625, 7.0100000681, 0.96999998793, 8.44000007123, 0.289999996722, 8.53000004485, -0.329999988228, 7.24000005037, -0.970000022948, 7.19000010103, -0.939999963194, 8.71000013962, 0.610000056177, 9.72000015408, -0.339999978095, 8.22000001401, 1.1000000082, 9.16000014856, 0.829999964386, 7.4800000985, 0.499999985844, 6.39000011593, 0.520000058711, 7.87000008926, 1.11999997824, 7.98000015512, -0.550000038743, 7.34000011593, -0.47999994725, 7.54000005409, -0.0399999400973, 9.50000006631, -0.0300000940263, 9.30000009537, -0.620000004321, 8.19000004515, -0.189999943823, 9.99000004068, 2.10999997869, 7.5600000301, 1.79000000492, 5.94000009656, 0.509999940693, 7.4900000824, 0.320000071377, 8.23000012606, 2.08000001878, 8.25000007898, 0.320000028908, 7.82000005573, 1.58999996543, 8.77000014067, 2.43999995351, 7.3200001429, 1.79000002652, 7.33000004858, 1.22000006616, 7.14000004441, 2.34999995232, 7.8800000985, 0.839999997467, 7.36000014782, 1.67000003487, 7.78000000983, 1.18000010446, 8.12000003785, 1.5799999696, 7.91000016943, 0.579999968857, 6.58000009403, 1.28000000238, 8.78000010148, 0.179999962896, 8.28000002176, 0.709999991357, 6.56000001818, -1.45999995336, 7.40999995634, -1.46999994919, 8.31000009045, 1.02072952757e-07, 8.71000004053, -0.55999995932, 7.40000003874, 0.439999958724, 9.16000004947, 0.390000004172, 7.26000004947, -0.909999980181, 5.82000006318, -0.0699998888373, 7.82000000134, -0.390000049621, 6.51000007108, -0.970000041574, 7.27000007883, 0.460000037551, 7.73999992594, -0.979999914467, 7.53999998331, 0.0699999216199, 9.00000004098, -1.15000003278, 6.93000001356, -0.529999943525, 8.30000004023, 2.23999984547, 8.6600000383, 0.769999961108, 8.05000007153, -4.24683084255e-08, 7.79000000343, 0.339999965429, 9.47000013545, 2.2699999328, 9.95000003353, 0.439999995977, 8.73000003889, 1.67999992266, 9.49000009283, 1.48999992147, 7.73000012234, 0.459999995083, 6.9800000836, 0.680000036657, 8.94999996126, 2.40999990046, 9.44000003919, 0.0899999326468, 9.07000008628, 0.909999981672, 9.72999992117, 0.530000026226, 9.37999994278, 1.15999993399, 9.23000010595, 1.35999988109, 8.55000000969, 1.43999995127, 10.5499999762, 
+
+L3_cGEMM_A_km
+0.800000011921, 0.20000000298, 0.300000011921, 0.600000023842, 0.600000023842, 0.5, 0.300000011921, 0.300000011921, 0.10000000149, 0.300000011921, 0.300000011921, 0.600000023842, 0.300000011921, 0.800000011921, 0.600000023842, 0.300000011921, 0.10000000149, 0.40000000596, 0.40000000596, 0.300000011921, 0.800000011921, 0.600000023842, 0.300000011921, 0.699999988079, 0.300000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.40000000596, 0.40000000596, 0.699999988079, 0.699999988079, 0.600000023842, 0.600000023842, 0.40000000596, 0.5, 0.600000023842, 0.20000000298, 0.300000011921, 0.600000023842, 0.5, 0.600000023842, 0.40000000596, 0.600000023842, 0.5, 0.800000011921, 0.600000023842, 0.600000023842, 0.20000000298, 0.10000000149, 0.600000023842, 0.899999976158, 0.699999988079, 0.699999988079, 0.600000023842, 0.300000011921, 0.600000023842, 0.20000000298, 0.40000000596, 0.40000000596, 0.300000011921, 0.10000000149, 0.800000011921, 0.20000000298, 0.699999988079, 0.5, 0.5, 0.800000011921, 0.20000000298, 0.5, 0.300000011921, 0.40000000596, 0.40000000596, 0.899999976158, 0.5, 0.699999988079, 0.40000000596, 0.20000000298, 0.20000000298, 0.899999976158, 0.10000000149, 0.20000000298, 0.10000000149, 0.40000000596, 0.800000011921, 0.5, 0.800000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.10000000149, 0.699999988079, 0.800000011921, 0.600000023842, 0.600000023842, 0.40000000596, 0.800000011921, 0.800000011921, 0.600000023842, 0.10000000149, 0.20000000298, 0.800000011921, 0.600000023842, 0.10000000149, 0.40000000596, 0.20000000298, 0.899999976158, 0.40000000596, 0.20000000298, 0.600000023842, 0.5, 0.300000011921, 0.600000023842, 0.300000011921, 0.40000000596, 0.5, 0.20000000298, 0.800000011921, 0.10000000149, 0.10000000149, 0.699999988079, 0.600000023842, 0.899999976158, 0.600000023842, 0.40000000596, 0.10000000149, 0.5, 0.800000011921, 0.899999976158, 0.20000000298, 0.40000000596, 0.5, 0.5, 0.10000000149, 0.800000011921, 0.5, 0.300000011921, 0.10000000149, 0.40000000596, 0.5, 0.10000000149, 0.10000000149, 0.40000000596, 0.5, 0.600000023842, 0.5, 0.800000011921, 0.40000000596, 0.600000023842, 0.5, 0.20000000298, 0.699999988079, 0.10000000149, 0.899999976158, 0.20000000298, 0.5, 0.600000023842, 0.699999988079, 0.899999976158, 0.20000000298, 0.10000000149, 0.10000000149, 0.10000000149, 0.300000011921, 0.5, 0.40000000596, 0.699999988079, 0.5, 0.600000023842, 0.899999976158, 0.10000000149, 0.5, 0.300000011921, 0.800000011921, 0.699999988079, 0.5, 0.10000000149, 0.5, 0.10000000149, 0.600000023842, 0.800000011921, 0.699999988079, 0.5, 0.300000011921, 0.40000000596, 0.5, 0.5, 0.40000000596, 0.40000000596, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.899999976158, 0.5, 0.20000000298, 0.20000000298, 0.40000000596, 0.40000000596, 0.300000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.600000023842, 0.5, 0.10000000149, 0.899999976158, 0.10000000149, 0.10000000149, 0.40000000596, 0.600000023842, 0.40000000596, 0.10000000149, 0.10000000149, 0.300000011921, 0.699999988079, 0.20000000298, 0.300000011921, 0.40000000596, 0.5, 0.699999988079, 0.800000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.20000000298, 0.300000011921, 0.5, 0.5, 0.699999988079, 0.5, 0.20000000298, 0.20000000298, 0.300000011921, 0.20000000298, 0.10000000149, 0.10000000149, 0.10000000149, 0.699999988079, 0.10000000149, 0.800000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.800000011921, 0.5, 0.300000011921, 0.10000000149, 0.20000000298, 0.20000000298, 0.40000000596, 0.699999988079, 0.800000011921, 0.20000000298, 0.800000011921, 0.5, 0.300000011921, 0.899999976158, 0.5, 0.699999988079, 0.10000000149, 0.20000000298, 0.600000023842, 0.600000023842, 0.20000000298, 0.10000000149, 0.800000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.5, 0.800000011921, 0.800000011921, 0.20000000298, 0.800000011921, 0.20000000298, 0.5, 0.5, 0.10000000149, 0.699999988079, 0.699999988079, 0.300000011921, 0.899999976158, 0.5, 0.699999988079, 0.20000000298, 0.20000000298, 0.899999976158, 0.300000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.20000000298, 0.10000000149, 0.600000023842, 0.699999988079, 0.40000000596, 0.800000011921, 0.40000000596, 0.699999988079, 0.300000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.899999976158, 0.5, 0.800000011921, 0.5, 0.40000000596, 0.300000011921, 0.40000000596, 0.300000011921, 0.699999988079, 0.20000000298, 0.600000023842, 0.300000011921, 0.10000000149, 0.899999976158, 0.10000000149, 0.5, 
+
+L3_cGEMM_B_nk
+0.899999976158, 0.300000011921, 0.800000011921, 0.5, 0.699999988079, 0.20000000298, 0.699999988079, 0.600000023842, 0.5, 0.40000000596, 0.40000000596, 0.10000000149, 0.40000000596, 0.20000000298, 0.600000023842, 0.600000023842, 0.899999976158, 0.800000011921, 0.300000011921, 0.899999976158, 0.10000000149, 0.800000011921, 0.300000011921, 0.600000023842, 0.20000000298, 0.800000011921, 0.600000023842, 0.20000000298, 0.40000000596, 0.20000000298, 0.10000000149, 0.40000000596, 0.800000011921, 0.40000000596, 0.20000000298, 0.899999976158, 0.800000011921, 0.699999988079, 0.300000011921, 0.300000011921, 0.600000023842, 0.10000000149, 0.899999976158, 0.10000000149, 0.300000011921, 0.5, 0.899999976158, 0.40000000596, 0.600000023842, 0.40000000596, 0.5, 0.699999988079, 0.10000000149, 0.800000011921, 0.10000000149, 0.5, 0.899999976158, 0.800000011921, 0.40000000596, 0.699999988079, 0.800000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.699999988079, 0.300000011921, 0.300000011921, 0.10000000149, 0.899999976158, 0.300000011921, 0.899999976158, 0.20000000298, 0.699999988079, 0.699999988079, 0.699999988079, 0.10000000149, 0.40000000596, 0.899999976158, 0.800000011921, 0.5, 0.899999976158, 0.20000000298, 0.300000011921, 0.899999976158, 0.600000023842, 0.20000000298, 0.10000000149, 0.600000023842, 0.899999976158, 0.40000000596, 0.300000011921, 0.10000000149, 0.600000023842, 0.600000023842, 0.699999988079, 0.699999988079, 0.600000023842, 0.699999988079, 0.300000011921, 0.300000011921, 0.40000000596, 0.699999988079, 0.40000000596, 0.800000011921, 0.5, 0.699999988079, 0.20000000298, 0.5, 0.300000011921, 0.10000000149, 0.5, 0.20000000298, 0.20000000298, 0.600000023842, 0.699999988079, 0.899999976158, 0.300000011921, 0.800000011921, 0.300000011921, 0.699999988079, 0.800000011921, 0.899999976158, 0.5, 0.20000000298, 0.600000023842, 0.20000000298, 0.40000000596, 0.600000023842, 0.600000023842, 0.5, 0.300000011921, 0.600000023842, 0.300000011921, 0.600000023842, 0.20000000298, 0.800000011921, 0.40000000596, 0.699999988079, 0.899999976158, 0.20000000298, 0.699999988079, 0.40000000596, 0.10000000149, 0.899999976158, 0.20000000298, 0.300000011921, 0.10000000149, 0.300000011921, 0.20000000298, 0.20000000298, 0.20000000298, 0.600000023842, 0.699999988079, 0.5, 0.899999976158, 0.20000000298, 0.10000000149, 0.899999976158, 0.300000011921, 0.300000011921, 0.899999976158, 0.40000000596, 0.5, 0.699999988079, 0.5, 0.20000000298, 0.800000011921, 0.300000011921, 0.600000023842, 0.699999988079, 0.600000023842, 0.10000000149, 0.699999988079, 0.10000000149, 0.800000011921, 0.699999988079, 0.600000023842, 0.5, 0.20000000298, 0.899999976158, 0.800000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.10000000149, 0.10000000149, 0.40000000596, 0.300000011921, 0.600000023842, 0.699999988079, 0.899999976158, 0.600000023842, 0.699999988079, 0.300000011921, 0.10000000149, 0.600000023842, 0.800000011921, 0.40000000596, 0.5, 0.600000023842, 0.300000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.899999976158, 0.600000023842, 0.20000000298, 0.5, 0.800000011921, 0.899999976158, 0.20000000298, 0.10000000149, 0.899999976158, 0.800000011921, 0.5, 0.20000000298, 0.20000000298, 0.600000023842, 0.10000000149, 0.800000011921, 0.800000011921, 0.40000000596, 0.20000000298, 0.699999988079, 0.699999988079, 0.800000011921, 0.800000011921, 0.10000000149, 0.10000000149, 0.899999976158, 0.600000023842, 0.40000000596, 0.10000000149, 0.899999976158, 0.10000000149, 0.10000000149, 0.40000000596, 0.300000011921, 0.40000000596, 0.899999976158, 0.699999988079, 0.300000011921, 0.10000000149, 0.699999988079, 0.300000011921, 0.699999988079, 0.800000011921, 0.5, 0.600000023842, 0.10000000149, 0.10000000149, 0.10000000149, 0.5, 0.699999988079, 0.10000000149, 0.10000000149, 0.5, 0.699999988079, 0.699999988079, 0.899999976158, 0.5, 0.5, 0.300000011921, 0.5, 0.800000011921, 0.40000000596, 0.699999988079, 0.10000000149, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.699999988079, 0.5, 0.10000000149, 0.300000011921, 0.5, 0.699999988079, 0.5, 0.10000000149, 0.10000000149, 0.899999976158, 0.300000011921, 0.20000000298, 0.300000011921, 0.10000000149, 0.40000000596, 0.20000000298, 0.10000000149, 0.300000011921, 0.300000011921, 0.20000000298, 0.600000023842, 0.10000000149, 0.899999976158, 0.600000023842, 0.699999988079, 0.699999988079, 0.600000023842, 0.10000000149, 0.20000000298, 0.800000011921, 0.40000000596, 0.600000023842, 0.5, 0.800000011921, 0.600000023842, 0.600000023842, 0.899999976158, 0.800000011921, 0.600000023842, 0.899999976158, 0.699999988079, 0.5, 0.20000000298, 0.20000000298, 0.40000000596, 0.300000011921, 0.10000000149, 0.899999976158, 0.899999976158, 0.899999976158, 0.10000000149, 0.10000000149, 0.20000000298, 0.20000000298, 0.899999976158, 0.699999988079, 0.5, 0.600000023842, 0.300000011921, 0.600000023842, 0.5, 0.5, 0.40000000596, 0.20000000298, 0.899999976158, 0.600000023842, 0.699999988079, 0.800000011921, 0.899999976158, 0.699999988079, 0.800000011921, 0.300000011921, 0.899999976158, 0.699999988079, 0.20000000298, 0.5, 0.600000023842, 0.899999976158, 0.699999988079, 0.800000011921, 0.300000011921, 0.800000011921, 0.699999988079, 0.20000000298, 0.20000000298, 0.40000000596, 0.699999988079, 0.699999988079, 0.40000000596, 0.5, 0.40000000596, 0.5, 0.40000000596, 0.20000000298, 0.800000011921, 0.20000000298, 0.20000000298, 0.10000000149, 0.300000011921, 0.600000023842, 0.20000000298, 0.600000023842, 0.10000000149, 0.899999976158, 0.20000000298, 0.20000000298, 0.5, 0.20000000298, 0.899999976158, 0.20000000298, 0.20000000298, 0.899999976158, 0.20000000298, 0.20000000298, 0.300000011921, 0.800000011921, 0.699999988079, 0.5, 0.600000023842, 0.300000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.20000000298, 0.10000000149, 0.5, 0.600000023842, 0.600000023842, 0.40000000596, 0.899999976158, 0.800000011921, 0.5, 0.899999976158, 0.699999988079, 0.5, 0.899999976158, 0.20000000298, 0.40000000596, 0.699999988079, 0.699999988079, 0.899999976158, 0.899999976158, 0.300000011921, 0.800000011921, 0.10000000149, 0.10000000149, 0.800000011921, 0.5, 0.5, 0.600000023842, 0.40000000596, 0.40000000596, 0.300000011921, 0.300000011921, 0.300000011921, 0.10000000149, 0.40000000596, 0.300000011921, 0.300000011921, 0.40000000596, 0.800000011921, 0.699999988079, 0.600000023842, 0.300000011921, 0.40000000596, 0.899999976158, 0.899999976158, 0.899999976158, 0.10000000149, 0.5, 0.5, 0.5, 0.800000011921, 0.5, 0.600000023842, 0.699999988079, 0.600000023842, 0.10000000149, 0.20000000298, 0.600000023842, 0.10000000149, 0.10000000149, 0.699999988079, 0.40000000596, 0.800000011921, 0.10000000149, 0.800000011921, 0.800000011921, 0.800000011921, 0.40000000596, 0.600000023842, 0.300000011921, 0.40000000596, 0.40000000596, 0.20000000298, 0.40000000596, 0.300000011921, 0.600000023842, 0.5, 0.800000011921, 0.899999976158, 0.20000000298, 0.10000000149, 0.10000000149, 0.10000000149, 0.5, 0.5, 0.699999988079, 0.300000011921, 0.800000011921, 0.20000000298, 0.300000011921, 0.600000023842, 0.800000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.5, 0.699999988079, 0.899999976158, 0.699999988079, 0.300000011921, 0.5, 0.20000000298, 0.899999976158, 0.40000000596, 0.10000000149, 0.899999976158, 0.899999976158, 0.10000000149, 0.10000000149, 0.5, 0.40000000596, 0.5, 0.40000000596, 0.20000000298, 0.5, 0.800000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.300000011921, 0.899999976158, 0.5, 0.300000011921, 0.600000023842, 0.10000000149, 0.20000000298, 0.20000000298, 0.20000000298, 0.20000000298, 0.600000023842, 0.5, 0.600000023842, 0.40000000596, 0.800000011921, 0.5, 0.800000011921, 0.800000011921, 0.20000000298, 0.300000011921, 0.699999988079, 0.800000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.699999988079, 0.10000000149, 0.5, 0.300000011921, 0.899999976158, 0.20000000298, 
+
+L3_cGEMM_o_TT
+1.10999998763, 7.23000018194, 0.730000036657, 8.33000011116, 1.51999999464, 7.18000010148, 0.180000101477, 7.57000008181, 0.409999925047, 7.25000008941, 1.04000003695, 7.38000010222, 0.969999907464, 7.45000017062, 1.14000007644, 6.20000008941, 1.27999999866, 6.71000005618, 0.840000007153, 7.65000014454, 1.47999996141, 8.46000002265, -0.150000029802, 6.28000011414, -0.0299999919534, 8.29000003546, 1.20000004247, 7.32000011683, 0.389999950528, 6.84000012562, -1.11758715615e-08, 7.43000006646, 1.16999994919, 6.94000011593, 1.05999992579, 7.97000019431, 0.299999991804, 8.5800001432, 2.35999997199, 9.17000007734, 0.519999975264, 8.35000016689, -5.66244138245e-08, 7.780000135, 1.46000002638, 8.45000017956, 0.159999826699, 8.68000019684, 0.0700000058115, 6.67000007808, 0.210000008494, 6.45000011176, 0.479999945015, 8.00000011995, 1.05999991834, 9.83000010148, 1.18999993786, 7.22000006393, 0.369999932796, 9.42000004679, 1.0799999696, 7.58000012457, 1.67999995992, 7.74000018001, 0.549999929965, 8.420000128, 1.8599998863, 7.77000010043, 1.62999999195, 8.75000013486, 1.70000005513, 8.8800000985, 4.13999994978, 8.46000003308, 0.950000119209, 8.46000009343, 0.660000001043, 7.79000013232, 2.81000007108, 8.07000009894, 1.78999995947, 8.10000014007, 1.3500001207, 7.52000007361, 1.53000004187, 7.46000004202, 1.93000000462, 8.3700001049, 3.04999994934, 9.50000000969, 1.12000001848, 7.09000005335, 1.47000001624, 9.1500000596, 1.59000002801, 8.18000008807, 3.35999999583, 6.98000010967, 1.96999997824, 7.88000007316, 2.26999994174, 7.21000011206, 1.73999996319, 8.9200001362, 2.0599999921, 10.1100000964, 2.99000000939, 9.31000005841, 0.820000053495, 9.30000014156, 0.169999957383, 8.05000014454, 3.20000002906, 9.61000010163, 1.30999992356, 10.4500001132, -0.299999946356, 7.51000005469, 3.32999996364, 8.10000004172, 1.09999997467, 9.57000013247, 1.51999995291, 10.0600000808, 0.810000000298, 8.21000005692, 0.840000036955, 10.4200000431, 1.54000005558, 9.44000008091, 2.38999999598, 8.47000010863, 1.49999996051, 9.49000006527, 1.66999990299, 8.50000009611, -0.219999939501, 7.70000009611, -0.689999907315, 8.09000008538, 0.610000035316, 8.0700000155, -1.41999994174, 6.4400001137, -0.999999996275, 6.69000006527, -0.349999892712, 7.52000016823, -1.18000001281, 7.65000012964, -1.07999991819, 5.72000005648, 0.170000026673, 6.46000008747, -1.2799999398, 8.00000010431, -1.12999999717, 8.66000001967, -0.409999948889, 6.34000002205, -2.4099998416, 8.14000004813, -0.479999860823, 7.81000010908, -0.289999999702, 6.6500001356, -0.429999991953, 7.45000005737, 0.270000008047, 7.64000008613, -0.209999975711, 7.59000010848, -0.869999946207, 9.20000005588, 0.490000054091, 8.54000002652, -1.39999990314, 7.31000013366, -0.959999977946, 7.12000013396, 0.360000068843, 7.67000010937, -1.33000001654, 8.03000014842, -0.959999895245, 6.03000009254, -0.559999919087, 7.21000002265, -0.779999961406, 7.21000009939, -0.369999981225, 8.6200000304, -0.470000012517, 7.20000009313, -1.70999990642, 8.07000005946, -0.479999937564, 7.8200000833, 0.730000006109, 6.88000014022, -0.649999976158, 7.4900000757, 0.659999969751, 7.18000005677, -0.0799999703467, 8.29000009581, 0.440000084639, 9.03000005677, 1.84000001088, 8.24999998584, -1.16999989554, 8.11000007331, -0.619999993891, 6.67000016972, 0.690000073463, 7.48000011861, -0.129999993443, 7.69000016734, -1.59999985322, 6.78000004932, 0.880000026971, 7.40000005513, 0.220000002086, 7.83000007391, 0.0099999846518, 9.1800000523, 0.130000003129, 6.66000006065, -1.20999998316, 8.7800001052, 0.410000055432, 7.76000015005, 1.36000000775, 6.95000013337, 0.380000042617, 8.32000007659, 0.659999947399, 7.09000010476, 1.81000003755, 7.50000013486, 1.96000012919, 8.67000014141, 3.60000002384, 8.90000010282, 0.790000147223, 8.16000015751, 0.410000068098, 6.8600001508, 1.91000016794, 8.35000015274, 0.500000041723, 8.50000015125, 0.940000083148, 7.2800001432, 1.40000010878, 7.88000003219, 1.0400000228, 8.73000009924, 1.76000002712, 9.89000007793, 1.3700000602, 7.41000008002, 0.300000105053, 9.35000006557, 1.34000016287, 7.33000015512, 1.85000008345, 6.61000013813, 1.40000005662, 8.52000009298, 2.1099999921, 7.36000014111, -0.059999923557, 6.69000015616, -0.369999908209, 8.19000008762, 0.840000086874, 8.43000000313, -1.63999990582, 6.99000010923, -1.21999992982, 6.71000010237, -0.429999883175, 7.80000013784, -1.06999999091, 6.670000166, -0.959999873638, 6.54000003844, 0.300000096858, 6.56000007927, -0.929999926388, 6.94000011593, -2.13999998257, 7.48000003293, 0.0200000415742, 5.57000008553, -1.20999989673, 7.3900001137, -0.249999904633, 6.17000018314, 0.0100000748038, 6.06000011355, -1.60999989226, 6.99000010476, 0.149999987334, 6.6800000672, 0.11999998793, 7.330000135, -0.720000002831, 7.44000010848, 1.44000002876, 8.26000000924, -0.489999943823, 6.78000007167, -1.16000000104, 6.37000002667, 0.230000029206, 7.91000008374, -1.34000005186, 6.38000008956, -0.239999960959, 7.2000000447, 0.280000018775, 5.9200000751, -0.310000005513, 7.80000001788, 0.0100000099838, 8.37000000358, -0.0599999727309, 6.60000000596, -1.27999997109, 8.3700000006, -0.359999961555, 6.75000010431, 0.850000023097, 6.06000008672, 0.38999997735, 7.41000002265, 1.16999992162, 7.53000000536, 
+
+L3_cGEMM_o_HH
+1.10999998763, -5.6300001581, 0.730000036657, -6.73000008732, 1.51999999464, -6.58000007764, 0.180000101477, -6.17000010565, 0.409999925047, -5.45000013709, 1.04000003695, -6.38000010222, 0.969999907464, -6.25000012293, 1.14000007644, -5.80000008345, 1.27999999866, -6.31000005022, 0.840000007153, -6.85000013262, 1.47999996141, -7.46000002265, -0.150000029802, -5.28000011414, -0.0299999919534, -7.08999998778, 1.20000004247, -6.5200001049, 0.389999950528, -5.0400001733, -1.11758715615e-08, -7.23000006348, 1.16999994919, -6.14000010401, 1.05999992579, -6.37000017047, 0.299999991804, -8.38000014022, 2.35999997199, -7.77000010118, 0.519999975264, -6.95000019073, -5.66244138245e-08, -6.780000135, 1.46000002638, -7.25000013188, 0.159999826699, -6.88000024453, 0.0700000058115, -6.4700000751, 0.210000008494, -5.65000009984, 0.479999945015, -7.60000011399, 1.05999991834, -8.23000007764, 1.18999993786, -6.82000005797, 0.369999932796, -7.62000009447, 1.0799999696, -7.18000011861, 1.67999995992, -6.54000013232, 0.549999929965, -7.62000011608, 1.8599998863, -7.37000009447, 1.62999999195, -6.95000018254, 1.70000005513, -7.8800000985, 4.13999994978, -8.2600000301, 0.950000119209, -8.06000008747, 0.660000001043, -6.19000010848, 2.81000007108, -7.87000009596, 1.78999995947, -6.50000011623, 1.3500001207, -6.52000007361, 1.53000004187, -6.06000006586, 1.93000000462, -8.17000010192, 3.04999994934, -8.50000000969, 1.12000001848, -6.89000005037, 1.47000001624, -8.1500000596, 1.59000002801, -6.78000011191, 3.35999999583, -6.38000008583, 1.96999997824, -7.68000007018, 2.26999994174, -7.01000010908, 1.73999996319, -8.12000012428, 2.0599999921, -8.51000007257, 2.99000000939, -7.71000003457, 0.820000053495, -7.70000011772, 0.169999957383, -6.4500001207, 3.20000002906, -9.01000007778, 1.30999992356, -8.85000008941, -0.299999946356, -7.31000005171, 3.32999996364, -7.50000001788, 1.09999997467, -7.97000010863, 1.51999995291, -9.26000006884, 0.810000000298, -7.21000005692, 0.840000036955, -9.42000004306, 1.54000005558, -8.04000010476, 2.38999999598, -7.07000013247, 1.49999996051, -7.89000004143, 1.66999990299, -7.70000008419, -0.219999939501, -5.9000001438, -0.689999907315, -6.69000010923, 0.610000035316, -6.67000003934, -1.41999994174, -5.64000010177, -0.999999996275, -4.89000011295, -0.349999892712, -6.52000016823, -1.18000001281, -6.0500001058, -1.07999991819, -5.5200000535, 0.170000026673, -5.26000003979, -1.2799999398, -6.60000012815, -1.12999999717, -6.86000006735, -0.409999948889, -4.9400000459, -2.4099998416, -7.94000004515, -0.479999860823, -6.61000006139, -0.289999999702, -5.25000015944, -0.429999991953, -5.85000003353, 0.270000008047, -6.44000003844, -0.209999975711, -7.19000010252, -0.869999946207, -7.80000007972, 0.490000054091, -6.94000000268, -1.39999990314, -7.11000013068, -0.959999977946, -5.52000011012, 0.360000068843, -7.47000010639, -1.33000001654, -6.43000012457, -0.959999895245, -5.83000008956, -0.559999919087, -6.60999999881, -0.779999961406, -6.61000007555, -0.369999981225, -6.82000007808, -0.470000012517, -5.60000006929, -1.70999990642, -7.27000004753, -0.479999937564, -6.02000013098, 0.730000006109, -6.28000011638, -0.649999976158, -7.29000007272, 0.659999969751, -6.78000005081, -0.0799999703467, -6.89000011966, 0.440000084639, -7.63000008062, 1.84000001088, -7.649999962, -1.16999989554, -6.71000009716, -0.619999993891, -5.07000014588, 0.690000073463, -7.28000011563, -0.129999993443, -7.29000016138, -1.59999985322, -5.38000007316, 0.880000026971, -6.80000003129, 0.220000002086, -6.83000007391, 0.0099999846518, -7.98000000462, 0.130000003129, -6.06000003681, -1.20999998316, -7.58000005752, 0.410000055432, -6.16000012621, 1.36000000775, -5.55000015721, 0.380000042617, -6.72000005275, 0.659999947399, -5.29000015244, 1.81000003755, -7.1000001289, 1.96000012919, -8.27000013545, 3.60000002384, -7.70000005513, 0.790000147223, -7.16000015751, 0.410000068098, -6.46000014484, 1.91000016794, -7.55000014082, 0.500000041723, -8.10000014529, 0.940000083148, -6.08000009552, 1.40000010878, -6.08000007987, 1.0400000228, -7.33000012308, 1.76000002712, -8.89000007793, 1.3700000602, -6.01000010386, 0.300000105053, -7.95000008941, 1.34000016287, -7.13000015214, 1.85000008345, -6.41000013515, 1.40000005662, -8.32000009, 2.1099999921, -5.76000011727, -0.059999923557, -5.09000013232, -0.369999908209, -7.59000006378, 0.840000086874, -6.63000005081, -1.63999990582, -5.99000010923, -1.21999992982, -6.11000007853, -0.429999883175, -6.60000009015, -1.06999999091, -5.27000018984, -0.959999873638, -4.74000008613, 0.300000096858, -5.76000006735, -0.929999926388, -5.54000013977, -2.13999998257, -7.28000002995, 0.0200000415742, -5.17000007957, -1.20999989673, -6.99000010774, -0.249999904633, -5.77000017717, 0.0100000748038, -5.66000010759, -1.60999989226, -5.99000010476, 0.149999987334, -6.08000004336, 0.11999998793, -6.13000008732, -0.720000002831, -6.2400000608, 1.44000002876, -6.86000003308, -0.489999943823, -6.38000006571, -1.16000000104, -6.17000002369, 0.230000029206, -6.71000003606, -1.34000005186, -5.9800000836, -0.239999960959, -6.2000000447, 0.280000018775, -5.12000006318, -0.310000005513, -6.00000006557, 0.0100000099838, -6.76999997973, -0.0599999727309, -5.2000000298, -1.27999997109, -6.57000004828, -0.359999961555, -6.35000009835, 0.850000023097, -4.86000003904, 0.38999997735, -6.01000004649, 1.16999992162, -6.13000002921, 
+
+L3_zGEMM_A_mk
+0.8, 0.1, 0.1, 0.7, 0.9, 0.8, 0.9, 0.6, 0.6, 0.4, 0.6, 0.2, 0.5, 0.5, 0.6, 0.6, 0.8, 0.8, 0.8, 0.7, 0.5, 0.8, 0.1, 0.1, 0.6, 0.8, 0.5, 0.3, 0.8, 0.8, 0.7, 0.1, 0.6, 0.9, 0.2, 0.5, 0.6, 0.6, 0.3, 0.7, 0.5, 0.5, 0.4, 0.4, 0.5, 0.6, 0.9, 0.9, 0.2, 0.1, 0.5, 0.5, 0.9, 0.4, 0.8, 0.3, 0.9, 0.4, 0.7, 0.1, 0.1, 0.6, 0.4, 0.3, 0.6, 0.6, 0.7, 0.3, 0.8, 0.6, 0.5, 0.9, 0.2, 0.7, 0.2, 0.2, 0.8, 0.1, 0.4, 0.1, 0.1, 0.2, 0.6, 0.9, 0.5, 0.9, 0.9, 0.7, 0.1, 0.3, 0.5, 0.4, 0.5, 0.3, 0.4, 0.3, 0.5, 0.6, 0.3, 0.2, 0.1, 0.5, 0.2, 0.9, 0.3, 0.4, 0.1, 0.2, 0.6, 0.9, 0.4, 0.7, 0.3, 0.5, 0.3, 0.6, 0.5, 0.1, 0.9, 0.3, 0.3, 0.9, 0.2, 0.4, 0.7, 0.6, 0.1, 0.9, 0.7, 0.2, 0.1, 0.9, 0.5, 0.9, 0.9, 0.2, 0.4, 0.2, 0.7, 0.8, 0.7, 0.1, 0.1, 0.8, 0.8, 0.5, 0.4, 0.1, 0.8, 0.1, 0.2, 0.2, 0.7, 0.8, 0.9, 0.7, 0.4, 0.3, 0.3, 0.5, 0.1, 0.1, 0.5, 0.2, 0.1, 0.6, 0.2, 0.6, 0.7, 0.7, 0.7, 0.8, 0.9, 0.7, 0.9, 0.2, 0.3, 0.8, 0.3, 0.7, 0.5, 0.2, 0.5, 0.4, 0.6, 0.6, 0.6, 0.1, 0.8, 0.8, 0.3, 0.5, 0.8, 0.4, 0.8, 0.6, 0.7, 0.9, 0.5, 0.1, 0.3, 0.5, 0.9, 0.3, 0.9, 0.9, 0.4, 0.6, 0.5, 0.1, 0.6, 0.7, 0.4, 0.4, 0.9, 0.6, 0.9, 0.4, 0.5, 0.2, 0.3, 0.1, 0.7, 0.9, 0.7, 0.2, 0.6, 0.5, 0.2, 0.6, 0.2, 0.4, 0.8, 0.2, 0.5, 0.7, 0.1, 0.1, 0.3, 0.5, 0.2, 0.7, 0.4, 0.5, 0.5, 0.7, 0.7, 0.1, 0.1, 0.8, 0.8, 0.8, 0.2, 0.7, 0.8, 0.6, 0.1, 0.8, 0.8, 0.4, 0.1, 0.5, 0.7, 0.7, 0.7, 0.5, 0.1, 0.2, 0.1, 0.1, 0.1, 0.4, 0.7, 0.5, 0.2, 0.7, 0.8, 0.5, 0.8, 0.9, 0.5, 0.7, 0.4, 0.6, 0.6, 0.4, 0.8, 0.2, 0.9, 0.8, 0.8, 0.1, 0.6, 0.3, 0.2, 0.1, 0.3, 0.5, 0.5, 0.2, 0.4, 0.5, 0.1, 0.2, 0.8, 0.3, 0.7, 0.8, 0.7, 0.9, 0.4, 0.7, 0.7, 0.9, 0.7, 0.9, 0.5, 0.1, 0.4, 0.2, 
+
+L3_zGEMM_B_kn
+0.2, 0.8, 0.2, 0.2, 0.2, 0.2, 0.5, 0.2, 0.1, 0.1, 0.2, 0.5, 0.3, 0.8, 0.2, 0.3, 0.4, 0.4, 0.9, 0.7, 0.9, 0.7, 0.3, 0.7, 0.9, 0.4, 0.4, 0.9, 0.3, 0.9, 0.4, 0.2, 0.6, 0.3, 0.2, 0.8, 0.7, 0.3, 0.6, 0.7, 0.5, 0.5, 0.3, 0.2, 0.7, 0.7, 0.5, 0.3, 0.8, 0.8, 0.2, 0.2, 0.8, 0.2, 0.4, 0.4, 0.4, 0.1, 0.4, 0.7, 0.6, 0.2, 0.2, 0.2, 0.8, 0.8, 0.6, 0.2, 0.7, 0.9, 0.1, 0.8, 0.9, 0.3, 0.6, 0.6, 0.5, 0.7, 0.8, 0.5, 0.8, 0.9, 0.9, 0.4, 0.2, 0.4, 0.4, 0.3, 0.4, 0.1, 0.2, 0.5, 0.7, 0.1, 0.5, 0.3, 0.8, 0.4, 0.2, 0.6, 0.7, 0.8, 0.4, 0.4, 0.2, 0.3, 0.6, 0.1, 0.9, 0.9, 0.8, 0.9, 0.1, 0.4, 0.5, 0.4, 0.2, 0.2, 0.8, 0.2, 0.2, 0.4, 0.8, 0.2, 0.7, 0.1, 0.6, 0.5, 0.6, 0.5, 0.3, 0.6, 0.5, 0.6, 0.1, 0.8, 0.6, 0.3, 0.8, 0.4, 0.7, 0.4, 0.9, 0.1, 0.7, 0.6, 0.5, 0.5, 0.2, 0.7, 0.4, 0.5, 0.2, 0.6, 0.2, 0.9, 0.9, 0.7, 0.6, 0.2, 0.8, 0.2, 0.4, 0.6, 0.6, 0.5, 0.6, 0.5, 0.2, 0.4, 0.3, 0.5, 0.9, 0.3, 0.4, 0.1, 0.1, 0.5, 0.8, 0.4, 0.2, 0.4, 0.3, 0.6, 0.7, 0.4, 0.3, 0.9, 0.6, 0.6, 0.2, 0.2, 0.1, 0.7, 0.2, 0.1, 0.2, 0.7, 0.1, 0.7, 0.2, 0.6, 0.6, 0.8, 0.7, 0.7, 0.5, 0.3, 0.2, 0.7, 0.8, 0.7, 0.9, 0.8, 0.2, 0.3, 0.3, 0.8, 0.7, 0.3, 0.9, 0.9, 0.1, 0.6, 0.8, 0.6, 0.8, 0.7, 0.8, 0.4, 0.3, 0.9, 0.8, 0.9, 0.9, 0.6, 0.3, 0.9, 0.7, 0.1, 0.1, 0.2, 0.1, 0.2, 0.9, 0.3, 0.4, 0.3, 0.7, 0.1, 0.5, 0.5, 0.3, 0.6, 0.8, 0.1, 0.1, 0.9, 0.4, 0.1, 0.6, 0.6, 0.7, 0.3, 0.2, 0.7, 0.7, 0.7, 0.6, 0.1, 0.4, 0.8, 0.6, 0.3, 0.5, 0.4, 0.8, 0.1, 0.4, 0.2, 0.9, 0.4, 0.4, 0.4, 0.5, 0.4, 0.3, 0.1, 0.8, 0.7, 0.4, 0.6, 0.7, 0.9, 0.9, 0.3, 0.2, 0.4, 0.1, 0.6, 0.8, 0.6, 0.4, 0.7, 0.6, 0.6, 0.1, 0.4, 0.9, 0.4, 0.6, 0.1, 0.7, 0.6, 0.9, 0.8, 0.1, 0.4, 0.7, 0.4, 0.3, 0.8, 0.9, 0.8, 0.5, 0.2, 0.4, 0.3, 0.2, 0.4, 0.6, 0.8, 0.1, 0.8, 0.6, 0.3, 0.6, 0.1, 0.4, 0.6, 0.5, 0.8, 0.3, 0.2, 0.1, 0.7, 0.3, 0.5, 0.1, 0.3, 0.6, 0.1, 0.8, 0.1, 0.5, 0.1, 0.9, 0.7, 0.1, 0.7, 0.5, 0.6, 0.9, 0.8, 0.1, 0.4, 0.6, 0.2, 0.7, 0.3, 0.8, 0.9, 0.8, 0.4, 0.8, 0.6, 0.3, 0.6, 0.3, 0.6, 0.1, 0.7, 0.9, 0.4, 0.6, 0.3, 0.5, 0.7, 0.6, 0.1, 0.4, 0.6, 0.5, 0.4, 0.4, 0.8, 0.3, 0.6, 0.4, 0.4, 0.9, 0.2, 0.4, 0.7, 0.6, 0.1, 0.4, 0.4, 0.6, 0.6, 0.3, 0.2, 0.9, 0.8, 0.5, 0.9, 0.4, 0.4, 0.2, 0.6, 0.6, 0.6, 0.8, 0.6, 0.6, 0.8, 0.4, 0.2, 0.4, 0.4, 0.9, 0.1, 0.5, 0.1, 0.9, 0.1, 0.4, 0.7, 0.7, 0.2, 0.3, 0.6, 0.9, 0.1, 0.7, 0.6, 0.2, 0.8, 0.6, 0.3, 0.5, 0.7, 0.1, 0.1, 0.7, 0.6, 0.9, 0.8, 0.3, 0.4, 0.1, 0.7, 0.8, 0.4, 0.9, 0.2, 0.2, 0.9, 0.2, 0.6, 0.1, 0.3, 0.6, 0.8, 0.3, 0.4, 0.6, 0.6, 0.4, 0.5, 0.1, 0.3, 0.7, 0.3, 0.9, 0.6, 0.1, 0.8, 0.5, 0.1, 0.1, 0.1, 0.6, 0.8, 0.6, 0.3, 0.8, 0.2, 0.8, 0.7, 0.9, 0.4, 0.7, 0.4, 0.5, 0.9, 0.9, 0.5, 0.7, 0.8, 0.7, 0.4, 0.5, 0.8, 0.1, 0.8, 0.1, 0.7, 0.4, 0.7, 0.4, 0.3, 0.7, 0.9, 0.7, 0.4, 0.3, 0.1, 0.9, 0.5, 0.5, 0.2, 0.5, 0.7, 0.3, 0.1, 0.4, 0.1, 0.3, 0.8, 0.2, 0.5, 0.2, 0.4, 
+
+L3_zGEMM_C_mn
+0.1, 0.9, 0.1, 0.6, 0.2, 0.3, 0.2, 0.6, 0.2, 0.1, 0.5, 0.5, 0.5, 0.7, 0.3, 0.2, 0.2, 0.6, 0.3, 0.5, 0.6, 0.7, 0.9, 0.9, 0.4, 0.9, 0.1, 0.1, 0.3, 0.3, 0.6, 0.9, 0.7, 0.6, 0.4, 0.6, 0.6, 0.4, 0.4, 0.5, 0.3, 0.8, 0.8, 0.5, 0.8, 0.1, 0.3, 0.6, 0.9, 0.4, 0.6, 0.6, 0.3, 0.9, 0.7, 0.6, 0.5, 0.6, 0.9, 0.1, 0.6, 0.8, 0.2, 0.1, 0.7, 0.8, 0.5, 0.4, 0.5, 0.6, 0.7, 0.8, 0.3, 0.7, 0.7, 0.9, 0.2, 0.7, 0.5, 0.6, 0.6, 0.2, 0.8, 0.7, 0.7, 0.5, 0.4, 0.9, 0.9, 0.7, 0.9, 0.6, 0.8, 0.1, 0.4, 0.5, 0.6, 0.1, 0.9, 0.3, 0.5, 0.6, 0.1, 0.3, 0.2, 0.2, 0.6, 0.7, 0.4, 0.7, 0.7, 0.3, 0.1, 0.6, 0.3, 0.2, 0.7, 0.4, 0.9, 0.4, 0.4, 0.6, 0.3, 0.5, 0.4, 0.8, 0.7, 0.2, 0.5, 0.9, 0.6, 0.6, 0.6, 0.2, 0.5, 0.5, 0.7, 0.7, 0.8, 0.2, 0.5, 0.6, 0.8, 0.7, 0.6, 0.8, 0.6, 0.7, 0.7, 0.3, 0.5, 0.7, 0.1, 0.5, 0.1, 0.2, 0.5, 0.5, 0.9, 0.6, 0.4, 0.8, 0.3, 0.4, 0.2, 0.9, 0.7, 0.3, 0.5, 0.4, 0.8, 0.4, 0.9, 0.5, 0.6, 0.4, 0.8, 0.4, 0.4, 0.7, 0.7, 0.4, 0.4, 0.7, 0.1, 0.7, 0.1, 0.5, 0.5, 0.3, 0.3, 0.1, 0.7, 0.1, 0.4, 0.4, 0.3, 0.4, 0.6, 0.1, 0.1, 0.4, 0.6, 0.9, 0.6, 0.8, 0.6, 0.4, 0.1, 0.4, 0.4, 0.3, 0.8, 0.5, 0.2, 0.2, 0.6, 0.1, 0.6, 0.2, 0.2, 0.5, 0.4, 0.1, 0.2, 0.4, 0.4, 0.4, 0.9, 0.4, 0.5, 0.3, 0.9, 0.5, 0.7, 0.2, 0.8, 0.5, 0.7, 0.4, 0.3, 0.8, 0.7, 0.7, 0.3, 0.7, 0.4, 0.1, 0.6, 0.3, 0.3, 0.9, 0.5, 0.5, 0.7, 0.2, 0.4, 0.1, 0.6, 0.5, 0.8, 0.4, 0.3, 0.6, 0.3, 0.9, 0.2, 0.6, 0.9, 0.5, 0.1, 0.3, 0.8, 0.1, 0.4, 0.5, 0.2, 0.8, 0.3, 0.7, 0.6, 0.8, 0.9, 0.2, 0.3, 0.5, 0.7, 0.9, 0.5, 0.4, 0.1, 0.8, 0.2, 0.3, 0.2, 0.3, 0.3, 0.5, 0.1, 0.6, 0.1, 0.2, 0.1, 0.7, 0.5, 0.2, 0.5, 0.4, 0.8, 0.8, 0.8, 0.4, 0.6, 0.7, 0.7, 0.1, 0.7, 0.4, 0.1, 0.5, 0.9, 0.4, 0.8, 0.3, 0.2, 0.3, 0.2, 0.3, 0.2, 0.2, 0.1, 0.9, 0.7, 0.5, 0.6, 0.2, 0.5, 0.2, 0.7, 0.6, 
+
+L3_zGEMM_o_NN
+0.77, 10.23, 1.25, 8.29, 1.15, 7.99, 1.58, 10.38, 1.75, 10.51, 0.21, 7.72, 1.79, 10.8, 1.62, 8.23, 1.02, 10.89, 0.56, 8.66, 3.2, 9.29, 2.99, 10.69, 2.5, 8.87, 0.3, 8.99, 0.63, 10.83, 1.45, 10.68, 0.02, 10.67, 1.01, 8.88, 1.26, 6.88, 0.89, 7.69, 0.92, 9.92, 1.41, 9.07, 0.95, 5.97, 0.63, 9.39, 2.5, 7.67, 1.37, 9.5, -0.64, 8.89, 2.39, 8.93, 1.61, 8.84, 2.29, 8.03, 0.4, 8.33, -0.53, 8.91, 2.12, 9.04, -0.44, 8.73, 0.63, 8.83, 0.98, 7.59, 0.28, 7.64, 1.0, 9.15, 0.74, 9.24, 0.67, 6.44, 0.87, 8.8, 2.15, 7.46, 0.84, 8.66, 0.08, 7.71, 2.09, 8.46, 1.62, 8.5, 1.94, 7.35, 0.55, 7.89, 0.36, 8.24, 1.88, 8.24, 0.07, 8.38, -0.97, 8.35, -0.93, 6.09, -1.12, 7.07, -1.27, 8.66, -0.64, 8.45, -1.28, 5.75, -1.93, 7.73, -0.11, 6.72, -0.19, 8.87, -1.51, 7.25, 0.42, 8.7, -0.07, 9.06, 0.81, 7.58, -0.92, 7.62, -2.14, 8.62, 0.53, 7.6, -2.14, 7.19, 1.64, 9.23, 1.65, 6.86, 1.01, 7.77, 1.79, 8.81, 2.23, 9.44, 0.16, 7.07, 1.05, 8.99, 1.48, 8.48, 1.54, 8.81, -0.22, 8.04, 3.33, 8.06, 3.28, 8.42, 2.01, 7.68, 0.78, 8.07, 0.13, 9.18, 1.72, 8.7, 0.1, 8.96, 1.3, 8.52, 1.47, 7.53, 0.54, 8.03, 1.19, 8.62, 0.8, 10.44, 0.07, 6.16, -0.07, 8.92, 1.39, 8.08, -0.37, 9.64, -0.41, 8.09, 1.6, 8.07, 1.97, 8.46, 1.91, 7.77, -0.18, 7.92, -0.54, 9.15, 1.26, 8.68, -1.0, 9.28, 1.6, 10.65, 1.88, 8.02, 0.83, 8.24, 1.21, 9.85, 2.62, 10.0, 0.94, 7.64, 0.96, 10.26, 2.97, 8.94, 1.48, 10.04, 1.24, 8.4, 2.65, 8.92, 1.86, 9.0, 3.3, 8.37, 1.51, 8.53, 0.9, 10.65, 2.73, 9.14, 0.91, 9.63, 0.48, 8.32, 0.62, 7.74, -0.25, 7.67, -0.35, 8.03, 0.06, 8.18, 0.1, 5.83, -0.12, 9.69, 0.93, 8.09, -0.56, 8.0, -0.2, 7.5, 1.75, 8.2, 0.9, 8.66, 0.57, 7.22, -0.22, 7.78, -1.49, 8.31, 0.38, 8.45, -1.55, 7.58, 0.76, 8.22, 0.68, 7.18, 0.08, 8.24, -0.12, 8.94, 0.96, 9.37, 0.6, 6.24, -0.02, 8.54, 1.3, 7.65, 0.13, 8.57, -0.58, 7.94, 0.95, 8.66, 1.5, 7.96, 0.31, 7.76, 0.14, 7.31, -1.16, 8.16, 1.0, 9.32, -0.63, 7.6, 0.9, 9.38, 2.12, 7.8, 1.0, 7.42, 1.17, 8.76, 1.78, 8.35, 1.14, 6.6, 0.58, 9.29, 2.4, 8.22, 0.85, 9.46, 0.34, 7.38, 1.5, 8.77, 1.66, 8.64, 1.16, 8.24, 0.79, 8.14, 0.39, 8.69, 2.01, 9.11, 1.1, 8.59, 
+
+L3_zGEMM_A_km
+0.7, 0.7, 0.6, 0.5, 0.1, 0.5, 0.2, 0.4, 0.7, 0.9, 0.7, 0.1, 0.9, 0.1, 0.2, 0.4, 0.8, 0.9, 0.9, 0.4, 0.1, 0.2, 0.2, 0.8, 0.7, 0.9, 0.5, 0.7, 0.1, 0.7, 0.1, 0.2, 0.8, 0.5, 0.8, 0.4, 0.7, 0.2, 0.9, 0.7, 0.2, 0.6, 0.4, 0.6, 0.8, 0.1, 0.2, 0.7, 0.4, 0.6, 0.6, 0.6, 0.8, 0.1, 0.8, 0.5, 0.2, 0.7, 0.9, 0.9, 0.3, 0.9, 0.6, 0.3, 0.3, 0.2, 0.8, 0.5, 0.1, 0.9, 0.7, 0.1, 0.1, 0.3, 0.8, 0.7, 0.6, 0.2, 0.8, 0.4, 0.5, 0.3, 0.4, 0.2, 0.5, 0.5, 0.8, 0.4, 0.9, 0.8, 0.2, 0.3, 0.6, 0.4, 0.7, 0.7, 0.4, 0.8, 0.5, 0.9, 0.3, 0.4, 0.9, 0.3, 0.2, 0.7, 0.5, 0.1, 0.6, 0.7, 0.2, 0.2, 0.9, 0.4, 0.5, 0.1, 0.5, 0.4, 0.6, 0.8, 0.5, 0.8, 0.3, 0.2, 0.6, 0.9, 0.5, 0.8, 0.5, 0.3, 0.7, 0.2, 0.1, 0.6, 0.1, 0.7, 0.6, 0.4, 0.5, 0.9, 0.5, 0.1, 0.5, 0.8, 0.4, 0.3, 0.1, 0.7, 0.6, 0.1, 0.7, 0.4, 0.9, 0.3, 0.5, 0.3, 0.9, 0.3, 0.9, 0.1, 0.1, 0.9, 0.4, 0.1, 0.5, 0.7, 0.5, 0.2, 0.2, 0.8, 0.8, 0.7, 0.8, 0.3, 0.5, 0.3, 0.1, 0.4, 0.8, 0.9, 0.5, 0.2, 0.6, 0.9, 0.5, 0.5, 0.8, 0.8, 0.3, 0.6, 0.5, 0.9, 0.2, 0.7, 0.3, 0.8, 0.5, 0.2, 0.6, 0.2, 0.1, 0.2, 0.1, 0.8, 0.5, 0.8, 0.6, 0.3, 0.2, 0.7, 0.8, 0.9, 0.4, 0.6, 0.6, 0.5, 0.1, 0.8, 0.8, 0.7, 0.8, 0.9, 0.3, 0.9, 0.5, 0.1, 0.6, 0.7, 0.3, 0.2, 0.8, 0.6, 0.3, 0.1, 0.3, 0.6, 0.7, 0.9, 0.5, 0.9, 0.4, 0.7, 0.4, 0.4, 0.9, 0.9, 0.5, 0.6, 0.3, 0.8, 0.2, 0.1, 0.1, 0.1, 0.3, 0.2, 0.8, 0.2, 0.4, 0.9, 0.8, 0.1, 0.2, 0.8, 0.7, 0.2, 0.9, 0.4, 0.1, 0.2, 0.6, 0.4, 0.1, 0.8, 0.4, 0.2, 0.8, 0.1, 0.7, 0.8, 0.3, 0.1, 0.1, 0.9, 0.2, 0.2, 0.6, 0.3, 0.2, 0.5, 0.2, 0.4, 0.6, 0.1, 0.8, 0.6, 0.1, 0.1, 0.2, 0.9, 0.9, 0.4, 0.1, 0.4, 0.9, 0.7, 0.7, 0.5, 0.2, 0.4, 0.7, 0.7, 0.1, 0.7, 0.5, 0.1, 0.4, 0.3, 0.5, 0.6, 
+
+L3_zGEMM_B_nk
+0.3, 0.9, 0.9, 0.7, 0.2, 0.6, 0.2, 0.1, 0.7, 0.1, 0.6, 0.8, 0.1, 0.3, 0.8, 0.2, 0.4, 0.7, 0.8, 0.4, 0.6, 0.8, 0.2, 0.9, 0.6, 0.8, 0.8, 0.6, 0.7, 0.4, 0.5, 0.9, 0.5, 0.6, 0.4, 0.6, 0.6, 0.2, 0.9, 0.2, 0.5, 0.9, 0.9, 0.6, 0.5, 0.9, 0.8, 0.4, 0.5, 0.8, 0.1, 0.7, 0.6, 0.5, 0.4, 0.7, 0.7, 0.5, 0.2, 0.9, 0.5, 0.3, 0.5, 0.4, 0.9, 0.9, 0.4, 0.6, 0.3, 0.9, 0.7, 0.7, 0.3, 0.3, 0.4, 0.5, 0.3, 0.6, 0.5, 0.1, 0.6, 0.8, 0.6, 0.5, 0.5, 0.4, 0.5, 0.6, 0.6, 0.4, 0.2, 0.6, 0.9, 0.2, 0.6, 0.6, 0.5, 0.1, 0.9, 0.9, 0.7, 0.6, 0.4, 0.9, 0.2, 0.5, 0.7, 0.1, 0.2, 0.5, 0.6, 0.1, 0.5, 0.8, 0.3, 0.9, 0.6, 0.1, 0.7, 0.1, 0.5, 0.1, 0.4, 0.4, 0.5, 0.4, 0.7, 0.7, 0.8, 0.1, 0.9, 0.5, 0.2, 0.2, 0.6, 0.9, 0.6, 0.9, 0.3, 0.9, 0.4, 0.6, 0.4, 0.7, 0.1, 0.5, 0.3, 0.5, 0.4, 0.6, 0.2, 0.1, 0.2, 0.4, 0.3, 0.1, 0.2, 0.5, 0.6, 0.6, 0.4, 0.6, 0.9, 0.9, 0.4, 0.8, 0.4, 0.1, 0.3, 0.4, 0.1, 0.7, 0.9, 0.3, 0.5, 0.8, 0.7, 0.3, 0.5, 0.6, 0.4, 0.9, 0.8, 0.1, 0.3, 0.6, 0.6, 0.4, 0.7, 0.4, 0.7, 0.6, 0.7, 0.2, 0.5, 0.4, 0.8, 0.6, 0.3, 0.7, 0.9, 0.3, 0.2, 0.5, 0.4, 0.5, 0.4, 0.4, 0.6, 0.7, 0.4, 0.9, 0.1, 0.6, 0.1, 0.8, 0.8, 0.8, 0.4, 0.8, 0.9, 0.3, 0.9, 0.3, 0.7, 0.7, 0.6, 0.7, 0.6, 0.3, 0.4, 0.8, 0.9, 0.1, 0.6, 0.2, 0.1, 0.5, 0.2, 0.5, 0.9, 0.9, 0.6, 0.7, 0.8, 0.8, 0.4, 0.5, 0.7, 0.7, 0.1, 0.8, 0.6, 0.2, 0.9, 0.4, 0.4, 0.9, 0.1, 0.2, 0.3, 0.1, 0.7, 0.1, 0.2, 0.7, 0.3, 0.5, 0.3, 0.7, 0.9, 0.3, 0.5, 0.6, 0.3, 0.7, 0.6, 0.5, 0.7, 0.2, 0.3, 0.6, 0.8, 0.8, 0.6, 0.1, 0.5, 0.5, 0.2, 0.6, 0.3, 0.2, 0.8, 0.2, 0.8, 0.8, 0.2, 0.9, 0.6, 0.8, 0.6, 0.6, 0.5, 0.9, 0.4, 0.6, 0.5, 0.4, 0.9, 0.4, 0.2, 0.5, 0.1, 0.2, 0.5, 0.8, 0.3, 0.3, 0.3, 0.1, 0.2, 0.5, 0.3, 0.7, 0.1, 0.4, 0.5, 0.9, 0.2, 0.7, 0.4, 0.4, 0.8, 0.6, 0.2, 0.4, 0.1, 0.1, 0.6, 0.1, 0.3, 0.2, 0.2, 0.3, 0.9, 0.2, 0.4, 0.4, 0.5, 0.5, 0.2, 0.8, 0.8, 0.3, 0.5, 0.3, 0.1, 0.7, 0.1, 0.3, 0.3, 0.6, 0.3, 0.3, 0.9, 0.5, 0.7, 0.2, 0.1, 0.3, 0.3, 0.5, 0.7, 0.8, 0.3, 0.4, 0.2, 0.1, 0.9, 0.7, 0.8, 0.3, 0.7, 0.3, 0.6, 0.3, 0.2, 0.3, 0.2, 0.2, 0.1, 0.8, 0.2, 0.8, 0.2, 0.6, 0.3, 0.3, 0.3, 0.7, 0.9, 0.8, 0.7, 0.2, 0.6, 0.1, 0.4, 0.6, 0.6, 0.1, 0.1, 0.8, 0.3, 0.1, 0.2, 0.9, 0.3, 0.6, 0.4, 0.6, 0.3, 0.7, 0.8, 0.2, 0.1, 0.7, 0.2, 0.4, 0.5, 0.3, 0.6, 0.1, 0.9, 0.6, 0.7, 0.1, 0.6, 0.9, 0.8, 0.2, 0.3, 0.4, 0.9, 0.9, 0.4, 0.6, 0.9, 0.4, 0.7, 0.5, 0.9, 0.2, 0.8, 0.8, 0.4, 0.3, 0.1, 0.6, 0.9, 0.9, 0.5, 0.1, 0.4, 0.9, 0.6, 0.7, 0.9, 0.4, 0.7, 0.2, 0.6, 0.1, 0.4, 0.2, 0.7, 0.9, 0.5, 0.4, 0.9, 0.2, 0.6, 0.6, 0.2, 0.3, 0.4, 0.8, 0.3, 0.2, 0.5, 0.6, 0.1, 0.3, 0.7, 0.2, 0.6, 0.9, 0.5, 0.3, 0.9, 0.6, 0.2, 0.5, 0.7, 0.6, 0.4, 0.8, 0.8, 0.9, 0.3, 0.9, 0.1, 0.2, 0.3, 0.6, 0.2, 0.1, 0.7, 0.5, 0.2, 0.2, 0.3, 0.2, 0.3, 0.5, 0.4, 0.9, 0.7, 0.7, 0.3, 0.5, 0.9, 0.2, 0.7, 0.4, 0.7, 0.6, 0.7, 0.8, 0.2, 0.1, 0.3, 0.5, 0.6, 0.6, 
+
+L3_zGEMM_o_TT
+-0.85, 7.98, -0.76, 9.17, -0.91, 8.16, 0.27, 7.31, -0.48, 6.17, 1.1, 7.99, -0.11, 8.33, -0.39, 8.24, 0.27, 7.71, -0.86, 7.58, -0.23, 6.87, 1.88, 6.71, -0.96, 7.74, 0.95, 7.48, 1.63, 7.96, 0.66, 8.37, 0.16, 7.45, -1.79, 9.13, -0.73, 8.28, -0.93, 8.64, -0.35, 8.4, -0.7, 7.41, -1.47, 8.34, -1.77, 8.4, -0.66, 8.43, -0.48, 8.11, -1.16, 8.54, -0.72, 6.47, -0.86, 7.61, -0.51, 6.37, -0.65, 8.38, -5.55111512313e-17, 9.24, -1.92, 8.3, -0.52, 7.8, -0.15, 10.08, -0.1, 10.08, -0.19, 9.48, 1.43, 9.26, -1.04, 8.28, 0.41, 9.66, 0.85, 9.34, 0.84, 10.43, 0.07, 7.66, 0.12, 8.22, 0.45, 7.81, 1.56, 8.22, 0.18, 7.43, 1.08, 8.84, 2.61, 8.98, 0.82, 8.21, 0.65, 8.3, 0.47, 9.33, 1.66533453694e-16, 9.67, 0.64, 9.46, 0.86, 9.32, 0.38, 8.33, 0.56, 9.53, 0.2, 9.54, 1.23, 9.56, 1.4, 8.39, 0.39, 8.85, 0.07, 7.79, 1.25, 8.53, 0.19, 7.6, 2.16, 9.71, 2.67, 9.48, 0.19, 8.86, 0.59, 8.26, -1.74, 8.48, -1.11, 8.87, -1.93, 8.62, -0.86, 7.56, -1.89, 7.91, -1.68, 8.33, -1.09, 8.15, -1.39, 9.25, -1.89, 7.36, -2.2, 7.76, -1.73, 6.54, -0.03, 6.79, -1.66, 7.26, -1.91, 7.64, -0.71, 9.59, -1.22, 7.34, -0.82, 7.34, 0.55, 9.1, 1.51, 8.63, 1.38, 8.84, 1.91, 7.82, 0.45, 7.09, 1.68, 8.46, 0.43, 8.95, 0.86, 10.0, 1.44, 7.95, 1.5, 8.2, 0.59, 5.94, 1.74, 7.0, 0.6, 7.66, 2.25, 8.61, 2.86, 8.57, 0.52, 8.09, 1.82, 8.85, 1.43, 8.91, 1.16, 7.61, 0.94, 7.44, 1.69, 6.51, 0.78, 7.11, 0.71, 8.33, 1.33, 6.72, 1.75, 7.41, 0.34, 6.75, 0.58, 7.33, -0.51, 6.09, 1.12, 6.79, 0.68, 6.08, 0.98, 7.97, 3.04, 9.0, 0.93, 7.45, 1.7, 6.9, 1.66, 8.28, 0.74, 8.63, 1.07, 8.74, 1.23, 8.14, 0.12, 7.46, 1.41, 8.74, 0.77, 8.8, 1.52, 8.65, 1.3, 6.59, 0.51, 7.55, 0.01, 7.22, 1.22, 7.11, -0.14, 7.18, 1.33, 8.87, 2.3, 8.7, 0.25, 8.51, 0.56, 7.02, 0.91, 7.9, 0.71, 9.15, 0.33, 8.74, 2.08, 7.71, 1.03, 7.64, 1.63, 8.02, 0.76, 8.56, 1.15, 9.9, 1.09, 7.61, -0.25, 8.49, 0.49, 6.17, 1.22, 6.56, -0.1, 7.35, 0.99, 7.53, 2.03, 8.2, 0.5, 8.53, 0.93, 7.52, -0.66, 12.0, -0.04, 12.61, 0.03, 11.87, 1.5, 11.37, -0.14, 9.44, 0.68, 12.36, -0.75, 12.28, 1.05, 12.99, 0.68, 10.07, -0.2, 10.71, -1.21, 9.14, 0.42, 9.78, -1.09, 9.99, 0.67, 11.4, 2.42, 12.14, -0.65, 10.62, 0.35, 10.15, 
+
+L3_zGEMM_o_HH
+-0.85, -6.18, -0.76, -7.97, -0.91, -7.56, 0.27, -6.11, -0.48, -5.97, 1.1, -6.99, -0.11, -6.93, -0.39, -7.84, 0.27, -6.51, -0.86, -6.58, -0.23, -5.47, 1.88, -4.91, -0.96, -5.94, 0.95, -7.28, 1.63, -7.36, 0.66, -6.57, 0.16, -6.25, -1.79, -7.93, -0.73, -7.48, -0.93, -7.64, -0.35, -6.8, -0.7, -6.41, -1.47, -8.14, -1.77, -7.2, -0.66, -7.63, -0.48, -6.91, -1.16, -6.74, -0.72, -5.27, -0.86, -6.41, -0.51, -6.17, -0.65, -6.78, -5.55111512313e-17, -9.04, -1.92, -6.7, -0.52, -7.0, -0.15, -8.88, -0.1, -8.48, -0.19, -8.08, 1.43, -7.46, -1.04, -6.88, 0.41, -8.46, 0.85, -8.94, 0.84, -9.03, 0.07, -6.66, 0.12, -6.42, 0.45, -6.41, 1.56, -7.02, 0.18, -7.23, 1.08, -7.84, 2.61, -8.78, 0.82, -7.61, 0.65, -7.1, 0.47, -8.73, 1.66533453694e-16, -9.27, 0.64, -8.06, 0.86, -7.92, 0.38, -7.73, 0.56, -8.33, 0.2, -9.14, 1.23, -8.76, 1.4, -7.59, 0.39, -7.65, 0.07, -6.79, 1.25, -6.93, 0.19, -7.2, 2.16, -7.91, 2.67, -8.28, 0.19, -8.46, 0.59, -7.26, -1.74, -7.08, -1.11, -8.47, -1.93, -7.42, -0.86, -6.16, -1.89, -6.31, -1.68, -6.93, -1.09, -7.55, -1.39, -7.85, -1.89, -6.36, -2.2, -7.36, -1.73, -5.54, -0.03, -5.59, -1.66, -5.66, -1.91, -6.84, -0.71, -7.79, -1.22, -6.74, -0.82, -6.54, 0.55, -8.3, 1.51, -7.63, 1.38, -8.04, 1.91, -7.02, 0.45, -5.69, 1.68, -7.66, 0.43, -7.55, 0.86, -8.6, 1.44, -6.95, 1.5, -7.6, 0.59, -5.74, 1.74, -6.8, 0.6, -6.86, 2.25, -7.81, 2.86, -8.37, 0.52, -7.29, 1.82, -7.05, 1.43, -7.31, 1.16, -6.81, 0.94, -6.64, 1.69, -5.91, 0.78, -6.11, 0.71, -7.93, 1.33, -6.52, 1.75, -7.01, 0.34, -5.75, 0.58, -7.13, -0.51, -5.29, 1.12, -5.99, 0.68, -5.28, 0.98, -7.37, 3.04, -8.0, 0.93, -7.05, 1.7, -5.9, 1.66, -7.48, 0.74, -7.03, 1.07, -7.34, 1.23, -6.74, 0.12, -7.26, 1.41, -8.14, 0.77, -7.0, 1.52, -7.65, 1.3, -6.19, 0.51, -7.35, 0.01, -6.22, 1.22, -6.31, -0.14, -5.98, 1.33, -7.07, 2.3, -7.5, 0.25, -7.51, 0.56, -6.42, 0.91, -7.7, 0.71, -8.15, 0.33, -7.14, 2.08, -6.31, 1.03, -6.04, 1.63, -7.62, 0.76, -7.56, 1.15, -8.1, 1.09, -6.81, -0.25, -6.89, 0.49, -5.57, 1.22, -5.96, -0.1, -6.35, 0.99, -6.33, 2.03, -7.8, 0.5, -7.13, 0.93, -7.12, -0.66, -11.2, -0.04, -11.01, 0.03, -11.07, 1.5, -9.97, -0.14, -9.24, 0.68, -11.56, -0.75, -11.28, 1.05, -12.19, 0.68, -9.47, -0.2, -10.11, -1.21, -8.54, 0.42, -9.38, -1.09, -8.19, 0.67, -10.4, 2.42, -11.74, -0.65, -10.22, 0.35, -8.95, 
+
+L3_sSYMM_A_mm
+0.5, 0.6, 0.1, 0.2, 0.2, 0.2, 0.3, 0.8, 0.5, 0.9, 0.6, 0.8, 0.7, 0.9, 0.6, 0.2, 0.6, 0.2, 0.2, 0.6, 0.1, 0.7, 0.5, 0.9, 0.1, 0.8, 0.6, 0.4, 0.6, 0.6, 0.2, 0.9, 0.9, 0.7, 0.2, 0.6, 0.1, 0.9, 0.7, 0.8, 0.2, 0.6, 0.1, 0.2, 0.5, 0.5, 0.5, 0.6, 0.8, 0.4, 0.2, 0.2, 0.8, 0.6, 0.5, 0.4, 0.4, 0.2, 0.1, 0.3, 0.3, 0.6, 0.6, 0.1, 0.5, 0.4, 0.1, 0.7, 0.9, 0.2, 0.8, 0.2, 0.4, 0.9, 0.6, 0.2, 0.7, 0.2, 0.5, 0.8, 0.5, 0.2, 0.6, 0.7, 0.8, 0.1, 0.9, 0.5, 0.2, 0.3, 0.9, 0.6, 0.6, 0.8, 0.4, 0.3, 0.2, 0.8, 0.3, 0.2, 
+
+L3_sSYMM_B_mn
+0.4, 0.7, 0.2, 0.9, 0.6, 0.8, 0.4, 0.9, 0.6, 0.4, 0.4, 0.5, 0.9, 0.7, 0.4, 0.7, 0.3, 0.2, 0.1, 0.8, 0.1, 0.2, 0.7, 0.9, 0.9, 0.6, 0.7, 0.7, 0.5, 0.9, 0.3, 0.5, 0.4, 0.6, 0.3, 0.9, 0.9, 0.7, 0.6, 0.4, 0.5, 0.3, 0.9, 0.5, 0.3, 0.8, 0.6, 0.4, 0.3, 0.9, 0.2, 0.5, 0.7, 0.4, 0.5, 0.7, 0.3, 0.4, 0.3, 0.3, 0.8, 0.7, 0.2, 0.3, 0.6, 0.5, 0.6, 0.4, 0.6, 0.5, 0.1, 0.1, 0.5, 0.9, 0.4, 0.6, 0.7, 0.8, 0.2, 0.6, 0.9, 0.5, 0.1, 0.5, 0.9, 0.7, 0.9, 0.5, 0.9, 0.6, 0.6, 0.5, 0.1, 0.2, 0.2, 0.5, 0.6, 0.8, 0.4, 0.7, 0.4, 0.9, 0.6, 0.3, 0.5, 0.9, 0.5, 0.2, 0.7, 0.7, 0.2, 0.2, 0.3, 0.6, 0.9, 0.1, 0.3, 0.2, 0.4, 0.3, 0.4, 0.6, 0.2, 0.7, 0.1, 0.7, 0.3, 0.4, 0.2, 0.8, 0.5, 0.6, 0.1, 0.4, 0.3, 0.5, 0.7, 0.2, 0.3, 0.3, 0.8, 0.6, 0.6, 0.4, 0.2, 0.3, 0.9, 0.4, 0.6, 0.4, 0.4, 0.6, 0.2, 0.1, 0.3, 0.3, 0.1, 0.9, 0.9, 0.3, 0.4, 0.7, 0.1, 0.2, 0.5, 0.3, 0.3, 0.3, 0.3, 0.7, 
+
+L3_sSYMM_C_mn
+0.6, 0.7, 0.5, 0.3, 0.5, 0.6, 0.6, 0.4, 0.7, 0.4, 0.6, 0.5, 0.8, 0.8, 0.9, 0.6, 0.4, 0.6, 0.9, 0.8, 0.9, 0.9, 0.6, 0.8, 0.6, 0.3, 0.6, 0.4, 0.4, 0.8, 0.2, 0.3, 0.5, 0.2, 0.1, 0.2, 0.6, 0.1, 0.1, 0.7, 0.3, 0.3, 0.3, 0.6, 0.5, 0.8, 0.8, 0.8, 0.9, 0.1, 0.1, 0.4, 0.9, 0.8, 0.6, 0.4, 0.6, 0.6, 0.4, 0.7, 0.1, 0.9, 0.6, 0.9, 0.6, 0.3, 0.8, 0.1, 0.9, 0.4, 0.9, 0.5, 0.9, 0.6, 0.6, 0.5, 0.5, 0.4, 0.7, 0.4, 0.8, 0.2, 0.9, 0.2, 0.4, 0.9, 0.9, 0.3, 0.5, 0.1, 0.7, 0.3, 0.3, 0.9, 0.2, 0.6, 0.5, 0.4, 0.4, 0.7, 0.8, 0.5, 0.5, 0.6, 0.6, 0.4, 0.1, 0.7, 0.3, 0.1, 0.8, 0.8, 0.8, 0.9, 0.4, 0.3, 0.8, 0.6, 0.3, 0.8, 0.8, 0.3, 0.2, 0.5, 0.5, 0.8, 0.2, 0.1, 0.3, 0.1, 0.3, 0.8, 0.4, 0.1, 0.9, 0.6, 0.4, 0.2, 0.4, 0.9, 0.9, 0.2, 0.9, 0.3, 0.3, 0.5, 0.9, 0.2, 0.4, 0.9, 0.6, 0.4, 0.3, 0.6, 0.4, 0.3, 0.2, 0.4, 0.9, 0.2, 0.2, 0.1, 0.3, 0.7, 0.6, 0.9, 0.3, 0.2, 0.5, 0.8, 
+
+L3_sSYMM_o_L
+2.17000006318, 2.40000000522, 2.42000007287, 1.85000001639, 3.25999999732, 3.07000002295, 2.99000006005, 2.63000002995, 2.80000001863, 1.89000004292, 2.8900000526, 2.64000003994, 3.57000006169, 2.25000004247, 2.57000001773, 2.45000007227, 2.62000002593, 2.78000009775, 3.61999997526, 3.37000004679, 3.39999997318, 4.03000003368, 3.65000008643, 3.67000005126, 3.52000008851, 3.16000007331, 3.27000006318, 2.90000002682, 3.16000010014, 4.41000007033, 2.40000006706, 2.3200000602, 3.27000004381, 2.88000006944, 2.46000004649, 2.82999999568, 3.30000006706, 2.65000000149, 3.36000006065, 3.37000004902, 3.26000004053, 2.60000004098, 2.55000004843, 2.78000003368, 3.39000000715, 3.42000009671, 4.14000008017, 2.71000006884, 3.22000001103, 2.59000006229, 2.80000003278, 2.72000001252, 3.83999993414, 4.00999999955, 2.96999999911, 4.14999999478, 3.75000002906, 3.95999998018, 2.98999999151, 3.71999996483, 2.58999998033, 4.24999992177, 3.68000003666, 4.58999999598, 2.75000005886, 2.80000002012, 3.8200000155, 3.07000000209, 2.96000002041, 2.20000002608, 2.86000005394, 2.2600000003, 3.56000002861, 3.03000006944, 3.17000007585, 2.6700000453, 2.36000005171, 2.1100000532, 3.15000002906, 2.64000008315, 3.90000006706, 1.68000004783, 2.64000002354, 2.12000007287, 2.76000003606, 2.54000003397, 3.11999999017, 2.1500000447, 2.43000000611, 2.34000006676, 2.62000002742, 2.17000004679, 1.92000005871, 2.86000000179, 1.96000005245, 2.21000006661, 2.5300000754, 2.82000005275, 1.88000006199, 2.08000003442, 2.80000005513, 2.38000002325, 2.47000002071, 2.64000003695, 2.77000008255, 2.1300000225, 2.76000003755, 3.13000003219, 2.8600000383, 2.18000004411, 2.96000005767, 2.65000005513, 3.33000000536, 3.26000004053, 3.48000006348, 1.90000005141, 2.51000004575, 2.89000007272, 2.43000003219, 3.14000005484, 3.48000001132, 2.36000003755, 2.80999996603, 3.92000002295, 3.5500000447, 3.37000004083, 2.94000003099, 2.67000004679, 2.61000005245, 2.5100000003, 2.90000008196, 4.20000003427, 2.63000005081, 2.02000003338, 3.56000002265, 3.16000004798, 2.58000005901, 2.6900000079, 2.51000003234, 3.30999993324, 3.78000000089, 2.59000003025, 3.41999997899, 2.79000003099, 2.68000004858, 2.7300000374, 3.0299999927, 2.7300000754, 3.72000000209, 2.72000001252, 2.22000005499, 2.77000004381, 2.6400000228, 2.70000008941, 3.16000001371, 2.74000009805, 2.64999999404, 3.4400000757, 3.5400000295, 2.97000005424, 2.82000003114, 2.68000007391, 2.7100000748, 3.46000004202, 3.15000010282, 4.35000003278, 2.4300000605, 2.2500000596, 3.2300000605, 3.18000007093, 
+
+L3_sSYMM_A_nn
+0.6, 0.6, 0.5, 0.9, 0.1, 0.5, 0.1, 0.9, 0.3, 0.9, 0.7, 0.3, 0.3, 0.2, 0.6, 0.9, 0.8, 0.6, 0.7, 0.6, 0.6, 0.2, 0.1, 0.9, 0.6, 0.7, 0.4, 0.3, 0.5, 0.3, 0.3, 0.5, 0.5, 0.3, 0.5, 0.6, 0.6, 0.4, 0.1, 0.6, 0.5, 0.9, 0.6, 0.3, 0.5, 0.3, 0.9, 0.9, 0.8, 0.6, 0.4, 0.9, 0.6, 0.4, 0.1, 0.5, 0.7, 0.9, 0.1, 0.2, 0.1, 0.4, 0.3, 0.4, 0.7, 0.4, 0.4, 0.4, 0.1, 0.2, 0.1, 0.5, 0.3, 0.8, 0.7, 0.8, 0.3, 0.7, 0.2, 0.1, 0.9, 0.5, 0.7, 0.2, 0.4, 0.5, 0.1, 0.6, 0.7, 0.8, 0.4, 0.2, 0.4, 0.4, 0.1, 0.5, 0.3, 0.8, 0.2, 0.6, 0.5, 0.2, 0.1, 0.9, 0.5, 0.9, 0.7, 0.2, 0.2, 0.1, 0.9, 0.8, 0.6, 0.1, 0.4, 0.2, 0.1, 0.1, 0.5, 0.9, 0.6, 0.9, 0.1, 0.8, 0.4, 0.1, 0.3, 0.4, 0.1, 0.6, 0.9, 0.1, 0.3, 0.9, 0.1, 0.2, 0.3, 0.7, 0.6, 0.2, 0.3, 0.4, 0.9, 0.4, 0.3, 0.3, 0.4, 0.3, 0.5, 0.8, 0.3, 0.6, 0.6, 0.9, 0.4, 0.3, 0.1, 0.7, 0.1, 0.8, 0.1, 0.3, 0.4, 0.2, 0.4, 0.3, 0.7, 0.5, 0.3, 0.4, 0.7, 0.3, 0.5, 0.4, 0.2, 0.5, 0.6, 0.6, 0.4, 0.2, 0.5, 0.9, 0.7, 0.6, 0.9, 0.8, 0.3, 0.3, 0.5, 0.3, 0.3, 0.1, 0.3, 0.1, 0.9, 0.3, 0.4, 0.9, 0.1, 0.3, 0.2, 0.3, 0.8, 0.1, 0.3, 0.3, 0.9, 0.4, 0.9, 0.8, 0.4, 0.1, 0.5, 0.3, 0.7, 0.3, 0.9, 0.3, 0.9, 0.2, 0.2, 0.2, 0.3, 0.9, 0.7, 0.5, 0.2, 0.2, 0.3, 0.8, 0.7, 0.6, 0.2, 0.3, 0.1, 0.3, 0.4, 0.1, 0.6, 0.5, 0.8, 0.4, 0.7, 0.6, 0.1, 0.9, 0.3, 0.5, 0.9, 0.3, 0.9, 0.3, 0.8, 0.1, 0.8, 0.9, 0.5, 0.6, 0.4, 0.2, 0.5, 0.1, 0.1, 0.6, 0.3, 0.8, 0.8, 0.2, 0.4, 0.1, 0.9, 0.7, 0.8, 0.3, 0.4, 0.4, 0.4, 0.2, 0.5, 0.2, 0.6, 0.4, 0.3, 0.1, 0.2, 0.1, 0.8, 0.7, 0.4, 
+
+L3_sSYMM_o_R
+5.96999999017, 5.26000004351, 6.28000000387, 4.44000003248, 5.25999998763, 5.00000006482, 4.84000000492, 4.32000006691, 5.17000004679, 4.01000004947, 5.88000004858, 4.32000000805, 5.53000003144, 4.58000006348, 6.29999998137, 4.98000005528, 4.0200000751, 5.46000000626, 5.24000001907, 6.21000002563, 4.74999996126, 5.52999991745, 4.45000007898, 4.33000004187, 4.34000003621, 4.70000007078, 3.98000007093, 5.42000001773, 3.90999999881, 5.53999996841, 3.91000003979, 5.73999998927, 4.48000006795, 3.63000005975, 5.05999999657, 5.04000002354, 5.7700001213, 4.07000004455, 3.81000004351, 4.86000007033, 4.85999994367, 4.66000003457, 4.76000008374, 4.27000009, 5.55000004768, 4.23000005826, 5.54000002876, 5.10000000596, 5.69000004739, 4.87000002667, 3.90000004768, 5.03000005677, 4.7200000684, 5.19000013307, 4.25000006855, 3.86000006512, 4.0400000973, 4.49000003174, 4.09000003994, 4.54000010848, 3.60000004694, 5.00000007153, 3.78000008509, 4.91999999836, 4.04000008017, 4.86000005841, 4.71000007331, 3.50000008494, 5.63000001207, 4.30000008196, 5.87000001624, 4.48000000089, 5.20999996752, 4.11000006884, 4.34000000045, 4.00000005364, 4.65000007227, 3.9900000526, 5.28000004262, 3.45000006333, 4.89000000268, 3.32000004753, 5.87999999866, 4.51000002414, 3.6900000675, 6.00999998689, 5.33000001878, 5.46000007108, 4.98000001952, 4.15000000894, 4.98000005677, 4.54999996275, 4.8000000231, 5.34000004441, 4.15000002459, 5.68000004858, 3.55000004545, 5.34000001907, 3.90000003725, 6.20000002235, 5.46000001967, 4.33000003964, 4.55000002086, 4.46000010088, 4.82000004232, 3.65000003353, 3.66999996781, 4.39000002727, 3.49999999255, 3.43000005454, 4.21000006586, 3.85000006333, 5.01000005394, 3.51000001222, 4.21999999315, 3.32000003189, 5.27000002593, 3.90000009462, 3.24000007719, 4.28000009999, 4.26000009343, 4.06000012398, 3.41000004724, 3.3900000377, 3.77000010639, 3.98000004858, 3.72000005797, 3.50000009537, 3.32000006318, 3.88000007913, 2.85000008121, 4.71000003159, 3.38000008956, 4.34000006899, 4.26000006363, 3.46000010982, 4.44000007272, 3.710000121, 4.71000011802, 4.75000002533, 4.36000006884, 3.9400001137, 3.9300000374, 4.06000005543, 3.92000014812, 3.91000005916, 5.29000007123, 3.28000005752, 4.66000006139, 3.93000006795, 5.16000008523, 4.24000005633, 3.51000010461, 3.76000006735, 3.22000006393, 3.83000010297, 3.22000002071, 3.410000045, 3.84000003174, 3.09999997616, 3.40000002384, 3.15000009537, 2.9200000453, 4.06000004575, 2.6800000754, 4.51999996483, 2.81000004798, 4.0300000374, 3.6400000295, 3.29000006825, 
+
+L3_dSYMM_A_mm
+0.3, 0.5, 0.4, 0.3, 0.9, 0.9, 0.4, 0.6, 0.4, 0.8, 0.5, 0.1, 0.4, 0.7, 0.8, 0.7, 0.7, 0.5, 0.6, 0.8, 0.4, 0.4, 0.7, 0.5, 0.8, 0.6, 0.7, 0.1, 0.9, 0.1, 0.3, 0.7, 0.5, 0.8, 0.1, 0.2, 0.7, 0.2, 0.6, 0.6, 0.9, 0.8, 0.8, 0.1, 0.9, 0.2, 0.3, 0.7, 0.9, 0.3, 0.9, 0.7, 0.6, 0.2, 0.2, 0.2, 0.6, 0.7, 0.3, 0.8, 0.4, 0.7, 0.7, 0.7, 0.3, 0.6, 0.5, 0.5, 0.2, 0.5, 0.6, 0.5, 0.1, 0.2, 0.7, 0.7, 0.5, 0.3, 0.8, 0.8, 0.4, 0.6, 0.9, 0.6, 0.9, 0.3, 0.2, 0.8, 0.6, 0.9, 0.8, 0.8, 0.1, 0.6, 0.3, 0.8, 0.5, 0.8, 0.9, 0.8, 
+
+L3_dSYMM_B_mn
+0.3, 0.4, 0.1, 0.9, 0.6, 0.5, 0.3, 0.3, 0.3, 0.8, 0.7, 0.1, 0.7, 0.7, 0.1, 0.3, 0.3, 0.5, 0.1, 0.1, 0.2, 0.8, 0.5, 0.2, 0.9, 0.3, 0.4, 0.5, 0.6, 0.1, 0.8, 0.7, 0.2, 0.9, 0.5, 0.9, 0.6, 0.8, 0.5, 0.3, 0.6, 0.1, 0.7, 0.5, 0.6, 0.5, 0.4, 0.6, 0.1, 0.2, 0.3, 0.6, 0.9, 0.1, 0.7, 0.3, 0.7, 0.2, 0.2, 0.4, 0.8, 0.5, 0.3, 0.1, 0.3, 0.9, 0.7, 0.9, 0.7, 0.4, 0.3, 0.5, 0.2, 0.1, 0.1, 0.9, 0.5, 0.3, 0.6, 0.5, 0.4, 0.5, 0.6, 0.9, 0.1, 0.4, 0.6, 0.9, 0.3, 0.5, 0.4, 0.7, 0.2, 0.5, 0.8, 0.1, 0.1, 0.4, 0.1, 0.3, 0.7, 0.3, 0.7, 0.1, 0.2, 0.2, 0.7, 0.7, 0.4, 0.2, 0.5, 0.8, 0.9, 0.6, 0.2, 0.6, 0.1, 0.8, 0.8, 0.5, 0.8, 0.9, 0.7, 0.6, 0.7, 0.2, 0.5, 0.9, 0.4, 0.3, 0.5, 0.1, 0.4, 0.1, 0.3, 0.7, 0.2, 0.6, 0.1, 0.2, 0.8, 0.4, 0.2, 0.9, 0.3, 0.7, 0.2, 0.9, 0.6, 0.8, 0.4, 0.9, 0.8, 0.6, 0.9, 0.9, 0.2, 0.2, 0.6, 0.3, 0.6, 0.6, 0.8, 0.3, 0.8, 0.2, 0.2, 0.9, 0.9, 0.1, 
+
+L3_dSYMM_C_mn
+0.1, 0.1, 0.5, 0.3, 0.3, 0.4, 0.6, 0.6, 0.8, 0.1, 0.4, 0.3, 0.6, 0.9, 0.1, 0.7, 0.8, 0.6, 0.3, 0.7, 0.4, 0.5, 0.7, 0.7, 0.5, 0.7, 0.2, 0.7, 0.5, 0.8, 0.8, 0.6, 0.8, 0.6, 0.6, 0.2, 0.3, 0.9, 0.7, 0.2, 0.2, 0.4, 0.4, 0.9, 0.8, 0.3, 0.3, 0.5, 0.9, 0.6, 0.4, 0.6, 0.7, 0.7, 0.5, 0.7, 0.6, 0.8, 0.9, 0.7, 0.8, 0.9, 0.5, 0.1, 0.3, 0.8, 0.6, 0.1, 0.8, 0.3, 0.3, 0.2, 0.4, 0.8, 0.5, 0.9, 0.6, 0.6, 0.8, 0.2, 0.5, 0.9, 0.7, 0.6, 0.3, 0.4, 0.2, 0.2, 0.3, 0.2, 0.2, 0.2, 0.2, 0.9, 0.5, 0.4, 0.5, 0.3, 0.7, 0.6, 0.6, 0.2, 0.7, 0.5, 0.1, 0.7, 0.5, 0.8, 0.3, 0.3, 0.6, 0.6, 0.2, 0.1, 0.9, 0.5, 0.3, 0.8, 0.1, 0.6, 0.3, 0.7, 0.8, 0.8, 0.5, 0.6, 0.1, 0.3, 0.6, 0.1, 0.2, 0.2, 0.9, 0.8, 0.4, 0.7, 0.4, 0.4, 0.5, 0.8, 0.2, 0.8, 0.6, 0.9, 0.7, 0.7, 0.8, 0.9, 0.5, 0.6, 0.3, 0.2, 0.5, 0.1, 0.5, 0.4, 0.3, 0.4, 0.3, 0.3, 0.8, 0.2, 0.5, 0.6, 0.2, 0.7, 0.4, 0.5, 0.4, 0.2, 
+
+L3_dSYMM_o_L
+2.95, 3.28, 3.31, 2.66, 2.92, 2.92, 2.41, 3.45, 3.68, 3.45, 2.74, 3.0, 2.31, 3.34, 2.58, 4.2, 3.23, 3.6, 3.79, 3.31, 3.06, 3.23, 3.53, 2.56, 3.19, 3.65, 4.02, 3.38, 3.34, 2.7, 3.41, 3.16, 4.72, 3.35, 3.15, 2.94, 2.04, 3.24, 3.51, 2.46, 1.93, 2.95, 2.8, 4.16, 3.36, 2.9, 2.22, 3.33, 2.93, 3.92, 3.16, 2.99, 3.35, 2.31, 2.5, 3.26, 3.13, 2.26, 3.1, 2.89, 3.94, 3.23, 3.05, 1.42, 2.78, 3.08, 3.42, 3.0, 3.56, 3.43, 2.46, 3.18, 3.7, 3.37, 2.19, 4.24, 3.49, 3.94, 3.67, 3.25, 2.71, 4.39, 2.85, 3.74, 3.25, 2.97, 3.07, 2.48, 2.86, 3.04, 2.93, 1.85, 2.64, 3.58, 3.79, 3.03, 3.11, 1.95, 3.47, 2.57, 3.27, 2.83, 3.33, 3.49, 2.35, 3.17, 3.13, 3.4, 2.06, 2.48, 3.21, 3.82, 2.63, 2.46, 2.33, 2.94, 2.52, 3.56, 2.86, 3.11, 3.05, 2.9, 2.85, 3.49, 2.93, 2.2, 3.0, 2.72, 3.98, 2.36, 2.9, 2.06, 3.48, 3.15, 3.89, 3.15, 3.58, 4.34, 3.37, 3.86, 3.16, 3.68, 2.43, 4.16, 4.01, 4.32, 3.6, 4.19, 2.4, 3.66, 3.17, 3.81, 3.44, 3.09, 4.08, 3.12, 3.07, 3.92, 3.65, 2.25, 4.11, 3.26, 4.71, 3.29, 3.37, 2.76, 3.57, 3.32, 4.24, 3.76, 
+
+L3_dSYMM_A_nn
+0.1, 0.6, 0.4, 0.6, 0.1, 0.1, 0.1, 0.8, 0.2, 0.8, 0.1, 0.9, 0.4, 0.7, 0.7, 0.3, 0.6, 0.6, 0.1, 0.5, 0.3, 0.5, 0.9, 0.4, 0.6, 0.6, 0.2, 0.1, 0.7, 0.1, 0.5, 0.4, 0.8, 0.1, 0.4, 0.5, 0.7, 0.9, 0.5, 0.2, 0.1, 0.2, 0.9, 0.3, 0.4, 0.5, 0.2, 0.8, 0.6, 0.1, 0.3, 0.6, 0.3, 0.9, 0.5, 0.9, 0.1, 0.3, 0.6, 0.9, 0.4, 0.5, 0.1, 0.7, 0.1, 0.9, 0.6, 0.5, 0.1, 0.5, 0.5, 0.9, 0.9, 0.9, 0.4, 0.1, 0.7, 0.9, 0.5, 0.3, 0.1, 0.1, 0.6, 0.3, 0.4, 0.1, 0.9, 0.2, 0.1, 0.9, 0.2, 0.9, 0.2, 0.9, 0.2, 0.6, 0.7, 0.8, 0.8, 0.4, 0.8, 0.4, 0.1, 0.4, 0.1, 0.3, 0.4, 0.9, 0.4, 0.5, 0.6, 0.6, 0.4, 0.1, 0.4, 0.6, 0.3, 0.8, 0.7, 0.8, 0.6, 0.2, 0.6, 0.1, 0.2, 0.5, 0.4, 0.9, 0.8, 0.7, 0.4, 0.7, 0.7, 0.3, 0.1, 0.2, 0.2, 0.6, 0.9, 0.9, 0.7, 0.9, 0.6, 0.9, 0.4, 0.3, 0.8, 0.7, 0.8, 0.3, 0.4, 0.4, 0.4, 0.8, 0.2, 0.3, 0.4, 0.9, 0.2, 0.6, 0.8, 0.3, 0.5, 0.8, 0.4, 0.9, 0.3, 0.4, 0.8, 0.6, 0.1, 0.1, 0.4, 0.5, 0.5, 0.6, 0.4, 0.7, 0.8, 0.8, 0.4, 0.8, 0.3, 0.5, 0.4, 0.8, 0.6, 0.9, 0.7, 0.5, 0.1, 0.3, 0.7, 0.1, 0.4, 0.7, 0.4, 0.8, 0.2, 0.4, 0.4, 0.5, 0.5, 0.4, 0.4, 0.1, 0.2, 0.7, 0.1, 0.8, 0.4, 0.7, 0.8, 0.9, 0.3, 0.4, 0.6, 0.9, 0.4, 0.7, 0.9, 0.7, 0.5, 0.8, 0.1, 0.1, 0.8, 0.6, 0.7, 0.3, 0.3, 0.5, 0.4, 0.9, 0.7, 0.2, 0.8, 0.9, 0.7, 0.4, 0.6, 0.9, 0.6, 0.4, 0.3, 0.3, 0.4, 0.4, 0.4, 0.5, 0.4, 0.2, 0.7, 0.7, 0.5, 0.3, 0.8, 0.1, 0.6, 0.3, 0.8, 0.8, 0.1, 0.4, 0.8, 0.8, 0.5, 0.7, 0.8, 0.7, 0.7, 0.2, 0.6, 0.1, 0.3, 0.5, 0.4, 0.4, 0.7, 0.2, 0.4, 0.6, 0.6, 0.4, 0.9, 0.9, 0.5, 0.2, 0.7, 
+
+L3_dSYMM_o_R
+3.3, 2.9, 3.91, 3.93, 4.25, 4.31, 4.16, 4.61, 5.36, 4.26, 4.15, 3.66, 4.98, 4.7, 3.7, 5.27, 4.85, 4.4, 3.86, 4.16, 4.38, 4.1, 4.65, 4.36, 3.96, 5.17, 4.63, 4.96, 4.12, 5.36, 4.99, 4.3, 4.71, 4.61, 4.07, 3.45, 4.48, 5.01, 4.92, 4.89, 3.6, 4.85, 5.37, 4.99, 4.72, 4.16, 4.49, 4.67, 4.93, 5.33, 4.47, 4.61, 4.22, 4.53, 4.83, 5.38, 4.82, 5.0, 4.98, 5.4, 5.14, 5.27, 4.85, 5.05, 4.75, 5.35, 5.72, 4.15, 4.4, 3.86, 3.74, 4.4, 3.5, 4.75, 3.77, 4.74, 5.03, 5.02, 4.78, 4.01, 4.7, 5.05, 4.61, 4.69, 3.77, 3.33, 3.39, 3.28, 4.46, 4.08, 4.13, 3.51, 3.57, 5.19, 4.36, 4.11, 3.93, 4.1, 4.76, 4.3, 4.61, 3.54, 4.03, 4.4, 3.57, 4.82, 4.74, 5.4, 4.53, 4.36, 5.3, 5.52, 4.93, 4.34, 5.91, 5.29, 4.42, 5.61, 4.52, 4.34, 4.21, 5.06, 5.37, 5.4, 4.86, 4.46, 4.17, 5.65, 4.73, 4.58, 4.43, 4.87, 5.53, 5.13, 4.63, 4.49, 5.08, 4.46, 4.15, 5.19, 4.18, 6.04, 5.03, 4.86, 5.9, 5.83, 5.91, 4.83, 5.79, 5.67, 4.53, 5.1, 4.83, 4.46, 4.9, 4.43, 5.18, 4.86, 4.94, 4.21, 5.02, 5.51, 4.99, 5.39, 4.83, 5.38, 5.31, 5.14, 5.45, 3.95, 
+
+L3_cSYMM_A_mm
+0.10000000149, 0.699999988079, 0.800000011921, 0.5, 0.899999976158, 0.5, 0.40000000596, 0.699999988079, 0.300000011921, 0.600000023842, 0.5, 0.10000000149, 0.300000011921, 0.699999988079, 0.20000000298, 0.300000011921, 0.699999988079, 0.20000000298, 0.899999976158, 0.800000011921, 0.800000011921, 0.5, 0.699999988079, 0.5, 0.10000000149, 0.40000000596, 0.600000023842, 0.600000023842, 0.600000023842, 0.10000000149, 0.300000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.800000011921, 0.300000011921, 0.800000011921, 0.20000000298, 0.600000023842, 0.699999988079, 0.899999976158, 0.5, 0.10000000149, 0.40000000596, 0.40000000596, 0.800000011921, 0.10000000149, 0.699999988079, 0.20000000298, 0.600000023842, 0.600000023842, 0.20000000298, 0.600000023842, 0.10000000149, 0.600000023842, 0.5, 0.10000000149, 0.40000000596, 0.899999976158, 0.600000023842, 0.40000000596, 0.699999988079, 0.600000023842, 0.600000023842, 0.10000000149, 0.699999988079, 0.699999988079, 0.5, 0.800000011921, 0.300000011921, 0.40000000596, 0.5, 0.600000023842, 0.600000023842, 0.699999988079, 0.899999976158, 0.800000011921, 0.20000000298, 0.800000011921, 0.300000011921, 0.300000011921, 0.600000023842, 0.600000023842, 0.10000000149, 0.20000000298, 0.600000023842, 0.800000011921, 0.300000011921, 0.5, 0.300000011921, 0.899999976158, 0.699999988079, 0.600000023842, 0.20000000298, 0.600000023842, 0.5, 0.5, 0.40000000596, 0.300000011921, 0.699999988079, 0.5, 0.10000000149, 0.300000011921, 0.300000011921, 0.600000023842, 0.20000000298, 0.40000000596, 0.5, 0.899999976158, 0.699999988079, 0.600000023842, 0.800000011921, 0.699999988079, 0.40000000596, 0.10000000149, 0.800000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.300000011921, 0.300000011921, 0.699999988079, 0.600000023842, 0.899999976158, 0.600000023842, 0.10000000149, 0.600000023842, 0.600000023842, 0.600000023842, 0.20000000298, 0.699999988079, 0.40000000596, 0.20000000298, 0.40000000596, 0.699999988079, 0.20000000298, 0.600000023842, 0.699999988079, 0.300000011921, 0.899999976158, 0.20000000298, 0.300000011921, 0.800000011921, 0.300000011921, 0.600000023842, 0.5, 0.699999988079, 0.899999976158, 0.600000023842, 0.5, 0.10000000149, 0.800000011921, 0.699999988079, 0.20000000298, 0.20000000298, 0.899999976158, 0.899999976158, 0.5, 0.40000000596, 0.10000000149, 0.699999988079, 0.20000000298, 0.800000011921, 0.20000000298, 0.10000000149, 0.40000000596, 0.800000011921, 0.20000000298, 0.5, 0.40000000596, 0.899999976158, 0.20000000298, 0.600000023842, 0.699999988079, 0.899999976158, 0.5, 0.10000000149, 0.899999976158, 0.5, 0.5, 0.899999976158, 0.800000011921, 0.600000023842, 0.699999988079, 0.899999976158, 0.600000023842, 0.800000011921, 0.300000011921, 0.300000011921, 0.699999988079, 0.800000011921, 0.300000011921, 0.300000011921, 0.899999976158, 0.40000000596, 0.10000000149, 0.5, 0.5, 0.699999988079, 0.40000000596, 
+
+L3_cSYMM_B_mn
+0.20000000298, 0.5, 0.899999976158, 0.600000023842, 0.800000011921, 0.300000011921, 0.40000000596, 0.300000011921, 0.40000000596, 0.10000000149, 0.300000011921, 0.10000000149, 0.699999988079, 0.40000000596, 0.20000000298, 0.899999976158, 0.20000000298, 0.20000000298, 0.300000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.600000023842, 0.40000000596, 0.699999988079, 0.5, 0.699999988079, 0.800000011921, 0.300000011921, 0.600000023842, 0.699999988079, 0.5, 0.20000000298, 0.699999988079, 0.20000000298, 0.5, 0.10000000149, 0.40000000596, 0.800000011921, 0.20000000298, 0.699999988079, 0.300000011921, 0.300000011921, 0.600000023842, 0.5, 0.300000011921, 0.800000011921, 0.20000000298, 0.899999976158, 0.800000011921, 0.40000000596, 0.600000023842, 0.800000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.40000000596, 0.699999988079, 0.300000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.699999988079, 0.300000011921, 0.800000011921, 0.5, 0.20000000298, 0.20000000298, 0.40000000596, 0.40000000596, 0.40000000596, 0.600000023842, 0.600000023842, 0.20000000298, 0.699999988079, 0.600000023842, 0.899999976158, 0.800000011921, 0.20000000298, 0.300000011921, 0.20000000298, 0.600000023842, 0.699999988079, 0.40000000596, 0.800000011921, 0.10000000149, 0.20000000298, 0.899999976158, 0.899999976158, 0.800000011921, 0.5, 0.40000000596, 0.5, 0.300000011921, 0.300000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.5, 0.10000000149, 0.20000000298, 0.899999976158, 0.800000011921, 0.699999988079, 0.5, 0.600000023842, 0.699999988079, 0.699999988079, 0.699999988079, 0.5, 0.40000000596, 0.300000011921, 0.40000000596, 0.5, 0.800000011921, 0.5, 0.5, 0.699999988079, 0.300000011921, 0.699999988079, 0.20000000298, 0.5, 0.20000000298, 0.699999988079, 0.40000000596, 0.600000023842, 0.800000011921, 0.600000023842, 0.300000011921, 0.300000011921, 0.5, 0.300000011921, 0.40000000596, 0.5, 0.300000011921, 0.10000000149, 0.5, 0.899999976158, 0.800000011921, 0.800000011921, 0.40000000596, 0.699999988079, 0.40000000596, 0.40000000596, 0.20000000298, 0.300000011921, 0.20000000298, 0.10000000149, 0.800000011921, 0.40000000596, 0.10000000149, 0.600000023842, 0.600000023842, 0.20000000298, 0.699999988079, 0.899999976158, 0.20000000298, 0.899999976158, 0.20000000298, 0.800000011921, 0.899999976158, 0.300000011921, 0.5, 0.800000011921, 0.899999976158, 0.20000000298, 0.699999988079, 0.10000000149, 0.899999976158, 0.5, 0.699999988079, 0.300000011921, 0.5, 0.40000000596, 0.600000023842, 0.5, 0.899999976158, 0.699999988079, 0.899999976158, 0.899999976158, 0.800000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.300000011921, 0.300000011921, 0.800000011921, 0.899999976158, 0.699999988079, 0.699999988079, 0.600000023842, 0.40000000596, 0.899999976158, 0.20000000298, 0.5, 0.5, 0.899999976158, 0.800000011921, 0.10000000149, 0.40000000596, 0.10000000149, 0.40000000596, 0.300000011921, 0.40000000596, 0.699999988079, 0.600000023842, 0.600000023842, 0.600000023842, 0.600000023842, 0.800000011921, 0.600000023842, 0.300000011921, 0.699999988079, 0.20000000298, 0.899999976158, 0.10000000149, 0.699999988079, 0.899999976158, 0.699999988079, 0.10000000149, 0.20000000298, 0.300000011921, 0.899999976158, 0.899999976158, 0.699999988079, 0.5, 0.300000011921, 0.300000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.800000011921, 0.5, 0.300000011921, 0.300000011921, 0.40000000596, 0.699999988079, 0.300000011921, 0.800000011921, 0.5, 0.899999976158, 0.300000011921, 0.5, 0.899999976158, 0.600000023842, 0.300000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.899999976158, 0.20000000298, 0.300000011921, 0.5, 0.300000011921, 0.10000000149, 0.40000000596, 0.10000000149, 0.899999976158, 0.600000023842, 0.300000011921, 0.300000011921, 0.20000000298, 0.699999988079, 0.40000000596, 0.5, 0.800000011921, 0.800000011921, 0.40000000596, 0.5, 0.899999976158, 0.20000000298, 0.10000000149, 0.40000000596, 0.699999988079, 0.899999976158, 0.20000000298, 0.10000000149, 0.800000011921, 0.600000023842, 0.40000000596, 0.40000000596, 0.600000023842, 0.10000000149, 0.899999976158, 0.699999988079, 0.20000000298, 0.10000000149, 0.40000000596, 0.699999988079, 0.899999976158, 0.699999988079, 0.10000000149, 0.899999976158, 0.800000011921, 0.20000000298, 0.20000000298, 0.300000011921, 0.600000023842, 0.5, 0.5, 0.899999976158, 0.800000011921, 0.5, 0.40000000596, 0.10000000149, 0.899999976158, 0.699999988079, 0.10000000149, 0.699999988079, 0.10000000149, 0.800000011921, 0.699999988079, 0.899999976158, 0.40000000596, 0.300000011921, 0.800000011921, 0.800000011921, 0.800000011921, 0.699999988079, 0.10000000149, 0.800000011921, 0.10000000149, 0.600000023842, 0.800000011921, 0.20000000298, 0.5, 0.699999988079, 0.300000011921, 0.40000000596, 0.10000000149, 0.5, 0.800000011921, 0.600000023842, 0.800000011921, 
+
+L3_cSYMM_C_mn
+0.40000000596, 0.300000011921, 0.20000000298, 0.5, 0.40000000596, 0.600000023842, 0.800000011921, 0.10000000149, 0.899999976158, 0.40000000596, 0.40000000596, 0.300000011921, 0.40000000596, 0.300000011921, 0.899999976158, 0.20000000298, 0.300000011921, 0.20000000298, 0.899999976158, 0.699999988079, 0.5, 0.5, 0.600000023842, 0.699999988079, 0.300000011921, 0.899999976158, 0.300000011921, 0.899999976158, 0.10000000149, 0.5, 0.300000011921, 0.600000023842, 0.5, 0.40000000596, 0.40000000596, 0.600000023842, 0.300000011921, 0.300000011921, 0.800000011921, 0.899999976158, 0.600000023842, 0.899999976158, 0.800000011921, 0.899999976158, 0.899999976158, 0.5, 0.600000023842, 0.300000011921, 0.5, 0.800000011921, 0.600000023842, 0.40000000596, 0.300000011921, 0.10000000149, 0.899999976158, 0.800000011921, 0.300000011921, 0.800000011921, 0.40000000596, 0.800000011921, 0.300000011921, 0.699999988079, 0.600000023842, 0.800000011921, 0.40000000596, 0.10000000149, 0.600000023842, 0.300000011921, 0.800000011921, 0.699999988079, 0.300000011921, 0.5, 0.600000023842, 0.699999988079, 0.800000011921, 0.699999988079, 0.699999988079, 0.600000023842, 0.899999976158, 0.5, 0.10000000149, 0.5, 0.40000000596, 0.40000000596, 0.300000011921, 0.5, 0.899999976158, 0.10000000149, 0.300000011921, 0.10000000149, 0.300000011921, 0.40000000596, 0.300000011921, 0.20000000298, 0.10000000149, 0.20000000298, 0.899999976158, 0.800000011921, 0.5, 0.40000000596, 0.899999976158, 0.800000011921, 0.899999976158, 0.899999976158, 0.699999988079, 0.40000000596, 0.20000000298, 0.20000000298, 0.699999988079, 0.800000011921, 0.10000000149, 0.899999976158, 0.300000011921, 0.699999988079, 0.899999976158, 0.899999976158, 0.899999976158, 0.600000023842, 0.40000000596, 0.300000011921, 0.600000023842, 0.20000000298, 0.300000011921, 0.5, 0.20000000298, 0.800000011921, 0.40000000596, 0.5, 0.300000011921, 0.800000011921, 0.800000011921, 0.300000011921, 0.899999976158, 0.699999988079, 0.800000011921, 0.300000011921, 0.5, 0.300000011921, 0.5, 0.899999976158, 0.899999976158, 0.899999976158, 0.699999988079, 0.300000011921, 0.20000000298, 0.899999976158, 0.20000000298, 0.699999988079, 0.899999976158, 0.899999976158, 0.899999976158, 0.10000000149, 0.5, 0.300000011921, 0.20000000298, 0.800000011921, 0.10000000149, 0.10000000149, 0.10000000149, 0.800000011921, 0.300000011921, 0.20000000298, 0.600000023842, 0.10000000149, 0.899999976158, 0.600000023842, 0.300000011921, 0.300000011921, 0.699999988079, 0.5, 0.600000023842, 0.600000023842, 0.899999976158, 0.5, 0.800000011921, 0.20000000298, 0.800000011921, 0.800000011921, 0.40000000596, 0.899999976158, 0.5, 0.40000000596, 0.20000000298, 0.899999976158, 0.600000023842, 0.20000000298, 0.40000000596, 0.40000000596, 0.40000000596, 0.800000011921, 0.300000011921, 0.5, 0.5, 0.600000023842, 0.800000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.300000011921, 0.10000000149, 0.300000011921, 0.899999976158, 0.800000011921, 0.899999976158, 0.40000000596, 0.300000011921, 0.20000000298, 0.899999976158, 0.699999988079, 0.10000000149, 0.40000000596, 0.40000000596, 0.10000000149, 0.800000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.600000023842, 0.300000011921, 0.899999976158, 0.40000000596, 0.10000000149, 0.800000011921, 0.300000011921, 0.40000000596, 0.300000011921, 0.300000011921, 0.300000011921, 0.300000011921, 0.899999976158, 0.600000023842, 0.699999988079, 0.5, 0.899999976158, 0.20000000298, 0.899999976158, 0.5, 0.300000011921, 0.40000000596, 0.899999976158, 0.800000011921, 0.899999976158, 0.699999988079, 0.300000011921, 0.699999988079, 0.10000000149, 0.800000011921, 0.20000000298, 0.699999988079, 0.699999988079, 0.300000011921, 0.10000000149, 0.699999988079, 0.20000000298, 0.899999976158, 0.5, 0.20000000298, 0.699999988079, 0.899999976158, 0.899999976158, 0.300000011921, 0.20000000298, 0.899999976158, 0.300000011921, 0.899999976158, 0.10000000149, 0.899999976158, 0.800000011921, 0.800000011921, 0.40000000596, 0.300000011921, 0.699999988079, 0.600000023842, 0.600000023842, 0.5, 0.699999988079, 0.20000000298, 0.300000011921, 0.20000000298, 0.20000000298, 0.300000011921, 0.600000023842, 0.20000000298, 0.300000011921, 0.600000023842, 0.800000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.800000011921, 0.10000000149, 0.40000000596, 0.899999976158, 0.300000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.10000000149, 0.20000000298, 0.899999976158, 0.699999988079, 0.20000000298, 0.699999988079, 0.699999988079, 0.800000011921, 0.300000011921, 0.20000000298, 0.10000000149, 0.600000023842, 0.5, 0.600000023842, 0.800000011921, 0.10000000149, 0.699999988079, 0.300000011921, 0.899999976158, 0.20000000298, 0.20000000298, 0.20000000298, 0.600000023842, 0.800000011921, 0.10000000149, 0.800000011921, 0.899999976158, 0.600000023842, 0.899999976158, 0.20000000298, 0.20000000298, 0.10000000149, 0.20000000298, 0.300000011921, 0.300000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.899999976158, 0.20000000298, 0.10000000149, 0.5, 0.300000011921, 
+
+L3_cSYMM_o_L
+1.30999990419, 5.19000004366, 0.499999948591, 5.15999998689, 0.1200000453, 4.68000002474, 1.44999997541, 5.42000002369, 1.60999987885, 5.52000012428, 0.310000039041, 5.86000006139, 2.07999993533, 6.00000003502, 0.879999900311, 6.15000000298, 0.349999993294, 5.1800000158, 1.29999998137, 6.01000007182, 1.5199999395, 4.8900000228, 1.0400000608, 6.42000003487, -1.03999995053, 6.43999990135, 0.619999950677, 6.7799999845, -0.060000051707, 4.23000006795, 0.78999997437, 6.10000006482, 0.279999982268, 5.19000010103, 1.42000005871, 5.45000013337, 1.14000004664, 5.02000010043, 1.42000007659, 5.04000007719, 2.28000006348, 6.71000006065, 2.63000001431, 5.76000012845, 1.15000007898, 6.6100001359, 2.77000008777, 5.78000011861, 0.470000012517, 7.07000007659, 0.90000006333, 5.77000005051, 1.34000009432, 5.49000008911, 2.1799999778, 5.51000008821, 0.65000012964, 6.4400001286, 0.230000085086, 6.57000000879, 1.3700000453, 6.95000008196, 0.87000005275, 5.03000014842, 2.1200000453, 5.39000015095, 0.840000081658, 5.9100001955, 1.22999992639, 5.62000004306, 0.639999949783, 4.90000007376, 0.860000048727, 4.62000002444, 1.23000001356, 5.26000009194, 1.27999992192, 4.96000014037, 0.750000040978, 5.45000009164, 1.29999993891, 5.71000008002, -0.550000026077, 6.05000001043, 0.200000008941, 4.21000007406, 0.889999935627, 4.97000010118, 0.619999988675, 3.72000006616, 0.140000067502, 5.39000013977, -0.689999985546, 5.14000001758, 0.0599999600649, 5.44000007719, 0.659999951869, 4.11000010237, 1.13999993265, 5.4000000596, 0.459999954104, 6.11000013664, 2.17999993905, 6.13000004336, 1.05999997497, 5.55000004321, 0.670000031143, 5.32000001773, 1.99999998435, 7.13000006199, 1.64999992847, 6.43000009775, 0.400000078231, 7.2700000751, 2.69000000343, 6.89000005931, 0.0200000341237, 7.1700000751, 0.470000052005, 5.53000007764, 1.44000003323, 5.42000013471, 1.17000001103, 5.37000006542, 0.410000106096, 6.94000011519, -0.599999915808, 6.50999999136, 0.690000027269, 7.49000008613, 0.690000005662, 4.82000011981, 2.45999997273, 6.57000007883, 0.750000045449, 6.40000014752, 1.71999995813, 5.12000008106, 0.989999966919, 5.40000006035, 1.64000000864, 5.13000002101, 2.28999999374, 5.59000008464, 1.7899999781, 5.99000010177, 0.560000091195, 6.25000010133, 2.55999998689, 6.34000002503, 0.659999961555, 5.68000005826, 0.790000028014, 4.69000009134, 1.30000000373, 5.63000012532, 1.05999999434, 4.09000008836, 0.300000087172, 6.58000010148, 0.0400000183284, 5.69000001088, 1.05000001639, 5.93000008136, 1.59999992698, 4.67000012502, 1.40000001788, 5.08000011936, 0.749999983609, 5.80000011027, 2.49999997094, 5.60000008568, 2.24999996871, 5.1200000155, 1.25000003353, 4.54000003994, 1.90000000894, 6.58000002697, 1.98999992967, 6.17000007212, 0.570000090003, 6.11000005916, 2.25999999583, 6.33000007838, 0.790000006407, 6.01000008747, 0.940000005662, 4.88000007167, 1.83999994308, 5.9100000897, 1.21999999911, 4.50000007972, 1.46000007331, 5.92000009596, 0.789999985546, 6.32999993905, 1.85999999285, 6.37000008255, 0.770000019968, 4.25000007972, 1.99999995306, 6.24000005856, 0.829999992698, 6.79000004813, 1.10000005886, 5.10000008419, 0.460000080019, 5.43000002027, 0.900000043213, 4.33000004187, 1.4400000526, 6.16000005022, 1.38999999523, 6.08000012457, 0.690000077933, 5.79000007421, 2.37000007659, 6.59000007048, -0.249999940395, 6.98000001952, -0.359999929518, 5.01000006959, 1.2800000985, 5.92000010863, 1.06000002638, 4.96000007704, -0.339999788851, 6.10000008345, -0.319999908954, 6.72999995172, 0.830000090301, 6.96000005767, 0.550000020117, 5.01000009567, 0.890000035465, 5.87000009522, 0.410000054687, 5.81000010833, 1.4699999842, 6.19999999776, 1.08000002995, 5.84999998584, 0.600000053644, 4.60000000149, 1.17000001624, 6.08000000685, 1.65999996305, 5.81000007555, 0.200000094622, 6.33000001431, 1.50000003204, 5.55000005662, 0.259999984652, 5.85000006258, 0.450000010431, 4.89000003174, 1.15999996305, 5.85000004843, 1.43999994904, 5.01000001222, 0.220000126511, 5.6900000295, 0.0300000225008, 5.68999998853, 1.11999995664, 6.18000005677, 0.639999973625, 5.22000008404, 1.62000000507, 5.53000004932, -0.0999999657273, 5.81000004351, 1.95999995932, 5.37000004977, 1.01999998793, 4.64000002801, 1.94999997765, 4.41000002265, 1.93999999747, 5.38000002325, 2.01999995142, 6.00000008643, 0.630000069439, 5.6900000295, 3.09999997988, 5.9900000459, 1.29999993816, 6.15999993026, 0.940000058562, 5.27000000954, 1.50000003874, 5.88000002548, 2.45999995261, 4.34000004143, 1.10000012368, 6.04999999851, 0.770000010282, 6.33999987751, 0.950000022352, 6.83999995202, 1.73999995947, 4.13000007913, 2.61999994174, 5.57000001922, 1.29999999851, 5.87000005499, 1.66999994099, 5.17000006765, 1.53999996468, 5.53000004932, 1.70000002831, 5.78000004783, 1.21000000849, 6.42000002369, 1.28999995276, 6.3900001137, 0.710000070333, 5.89000009432, 2.56999992236, 6.95000009388, 0.989999945313, 7.28999997586, 1.36000002116, 6.04000000939, 0.930000059754, 7.1100000383, 1.389999955, 5.07000002965, 0.940000087619, 6.70000009462, -0.549999935925, 7.13999992445, 1.22999993905, 7.13000002921, 0.810000001788, 5.35000008941, 1.84999995232, 6.1300000605, 0.490000030249, 6.08000009254, 
+
+L3_cSYMM_A_nn
+0.600000023842, 0.20000000298, 0.300000011921, 0.899999976158, 0.800000011921, 0.40000000596, 0.20000000298, 0.899999976158, 0.300000011921, 0.5, 0.899999976158, 0.20000000298, 0.300000011921, 0.5, 0.699999988079, 0.899999976158, 0.699999988079, 0.40000000596, 0.20000000298, 0.300000011921, 0.699999988079, 0.899999976158, 0.40000000596, 0.800000011921, 0.600000023842, 0.40000000596, 0.600000023842, 0.699999988079, 0.20000000298, 0.10000000149, 0.300000011921, 0.20000000298, 0.800000011921, 0.20000000298, 0.300000011921, 0.899999976158, 0.800000011921, 0.800000011921, 0.5, 0.300000011921, 0.600000023842, 0.600000023842, 0.40000000596, 0.600000023842, 0.10000000149, 0.699999988079, 0.899999976158, 0.300000011921, 0.40000000596, 0.600000023842, 0.5, 0.10000000149, 0.10000000149, 0.20000000298, 0.600000023842, 0.800000011921, 0.800000011921, 0.10000000149, 0.20000000298, 0.5, 0.300000011921, 0.600000023842, 0.40000000596, 0.800000011921, 0.899999976158, 0.600000023842, 0.40000000596, 0.899999976158, 0.800000011921, 0.40000000596, 0.5, 0.300000011921, 0.5, 0.800000011921, 0.600000023842, 0.10000000149, 0.699999988079, 0.40000000596, 0.600000023842, 0.800000011921, 0.699999988079, 0.699999988079, 0.20000000298, 0.20000000298, 0.800000011921, 0.899999976158, 0.10000000149, 0.300000011921, 0.699999988079, 0.10000000149, 0.300000011921, 0.300000011921, 0.10000000149, 0.5, 0.40000000596, 0.40000000596, 0.5, 0.600000023842, 0.10000000149, 0.800000011921, 0.5, 0.699999988079, 0.20000000298, 0.899999976158, 0.600000023842, 0.600000023842, 0.600000023842, 0.10000000149, 0.600000023842, 0.300000011921, 0.600000023842, 0.40000000596, 0.600000023842, 0.40000000596, 0.300000011921, 0.40000000596, 0.699999988079, 0.600000023842, 0.20000000298, 0.899999976158, 0.10000000149, 0.899999976158, 0.600000023842, 0.600000023842, 0.300000011921, 0.899999976158, 0.5, 0.40000000596, 0.899999976158, 0.10000000149, 0.10000000149, 0.300000011921, 0.899999976158, 0.300000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.5, 0.40000000596, 0.600000023842, 0.699999988079, 0.40000000596, 0.600000023842, 0.40000000596, 0.40000000596, 0.300000011921, 0.899999976158, 0.5, 0.600000023842, 0.5, 0.10000000149, 0.800000011921, 0.600000023842, 0.600000023842, 0.5, 0.600000023842, 0.699999988079, 0.5, 0.5, 0.10000000149, 0.699999988079, 0.300000011921, 0.5, 0.20000000298, 0.899999976158, 0.699999988079, 0.5, 0.40000000596, 0.600000023842, 0.5, 0.899999976158, 0.20000000298, 0.10000000149, 0.699999988079, 0.600000023842, 0.800000011921, 0.600000023842, 0.40000000596, 0.899999976158, 0.5, 0.899999976158, 0.5, 0.600000023842, 0.899999976158, 0.899999976158, 0.800000011921, 0.5, 0.40000000596, 0.899999976158, 0.10000000149, 0.5, 0.800000011921, 0.800000011921, 0.699999988079, 0.300000011921, 0.300000011921, 0.10000000149, 0.899999976158, 0.5, 0.5, 0.40000000596, 0.300000011921, 0.899999976158, 0.300000011921, 0.300000011921, 0.5, 0.899999976158, 0.300000011921, 0.699999988079, 0.699999988079, 0.300000011921, 0.40000000596, 0.600000023842, 0.5, 0.600000023842, 0.899999976158, 0.300000011921, 0.600000023842, 0.300000011921, 0.699999988079, 0.5, 0.699999988079, 0.5, 0.40000000596, 0.10000000149, 0.800000011921, 0.600000023842, 0.300000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.699999988079, 0.600000023842, 0.5, 0.20000000298, 0.699999988079, 0.40000000596, 0.699999988079, 0.699999988079, 0.899999976158, 0.40000000596, 0.600000023842, 0.20000000298, 0.20000000298, 0.699999988079, 0.600000023842, 0.10000000149, 0.800000011921, 0.899999976158, 0.800000011921, 0.300000011921, 0.699999988079, 0.800000011921, 0.40000000596, 0.699999988079, 0.800000011921, 0.5, 0.800000011921, 0.10000000149, 0.20000000298, 0.20000000298, 0.20000000298, 0.20000000298, 0.600000023842, 0.600000023842, 0.5, 0.699999988079, 0.600000023842, 0.800000011921, 0.10000000149, 0.5, 0.300000011921, 0.699999988079, 0.40000000596, 0.5, 0.10000000149, 0.800000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.600000023842, 0.600000023842, 0.5, 0.40000000596, 0.5, 0.699999988079, 0.699999988079, 0.800000011921, 0.300000011921, 0.300000011921, 0.5, 0.699999988079, 0.40000000596, 0.699999988079, 0.699999988079, 0.800000011921, 0.10000000149, 0.20000000298, 0.5, 0.699999988079, 0.800000011921, 0.300000011921, 0.40000000596, 0.20000000298, 0.300000011921, 0.40000000596, 0.20000000298, 0.300000011921, 0.10000000149, 0.20000000298, 0.10000000149, 0.300000011921, 0.10000000149, 0.899999976158, 0.5, 0.600000023842, 0.899999976158, 0.10000000149, 0.5, 0.40000000596, 0.5, 0.800000011921, 0.5, 0.699999988079, 0.10000000149, 0.5, 0.40000000596, 0.600000023842, 0.800000011921, 0.899999976158, 0.800000011921, 0.899999976158, 0.600000023842, 0.5, 0.10000000149, 0.20000000298, 0.899999976158, 0.600000023842, 0.899999976158, 0.40000000596, 0.699999988079, 0.899999976158, 0.600000023842, 0.800000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.600000023842, 0.699999988079, 0.5, 0.5, 0.800000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.20000000298, 0.40000000596, 0.699999988079, 0.40000000596, 0.600000023842, 0.10000000149, 0.5, 0.600000023842, 0.20000000298, 0.899999976158, 0.5, 0.20000000298, 0.699999988079, 0.800000011921, 0.600000023842, 0.699999988079, 0.699999988079, 0.40000000596, 0.10000000149, 0.40000000596, 0.800000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.300000011921, 0.300000011921, 0.899999976158, 0.5, 0.10000000149, 0.800000011921, 0.699999988079, 0.600000023842, 0.300000011921, 0.20000000298, 0.20000000298, 0.699999988079, 0.800000011921, 0.800000011921, 0.899999976158, 0.600000023842, 0.20000000298, 0.800000011921, 0.800000011921, 0.699999988079, 0.10000000149, 0.699999988079, 0.300000011921, 0.899999976158, 0.600000023842, 0.699999988079, 0.699999988079, 0.300000011921, 0.899999976158, 0.600000023842, 0.40000000596, 0.20000000298, 0.5, 0.10000000149, 0.5, 0.5, 0.40000000596, 0.699999988079, 0.300000011921, 0.300000011921, 0.300000011921, 0.699999988079, 0.600000023842, 0.20000000298, 0.600000023842, 0.10000000149, 0.20000000298, 0.800000011921, 0.899999976158, 0.899999976158, 0.5, 0.699999988079, 0.10000000149, 0.699999988079, 0.699999988079, 0.699999988079, 0.699999988079, 0.300000011921, 0.800000011921, 0.40000000596, 0.40000000596, 0.10000000149, 0.10000000149, 0.600000023842, 0.699999988079, 0.300000011921, 0.600000023842, 0.40000000596, 0.40000000596, 0.899999976158, 0.10000000149, 0.5, 0.20000000298, 0.10000000149, 0.899999976158, 0.40000000596, 0.699999988079, 0.600000023842, 0.5, 0.5, 0.699999988079, 0.600000023842, 0.5, 0.20000000298, 0.699999988079, 0.699999988079, 0.300000011921, 0.699999988079, 0.699999988079, 0.10000000149, 0.300000011921, 0.800000011921, 0.800000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.800000011921, 0.20000000298, 0.10000000149, 0.40000000596, 0.800000011921, 0.5, 0.600000023842, 0.10000000149, 0.300000011921, 0.899999976158, 0.699999988079, 0.5, 0.5, 0.600000023842, 0.5, 0.699999988079, 0.600000023842, 0.800000011921, 0.300000011921, 0.10000000149, 0.20000000298, 0.800000011921, 0.600000023842, 0.899999976158, 0.600000023842, 0.300000011921, 0.800000011921, 0.800000011921, 0.800000011921, 0.800000011921, 0.10000000149, 0.899999976158, 0.5, 0.600000023842, 0.40000000596, 0.300000011921, 0.20000000298, 0.899999976158, 0.600000023842, 0.10000000149, 0.800000011921, 0.899999976158, 0.300000011921, 0.5, 0.40000000596, 0.40000000596, 0.300000011921, 0.20000000298, 0.699999988079, 0.800000011921, 0.10000000149, 0.40000000596, 0.20000000298, 0.899999976158, 0.600000023842, 0.699999988079, 0.699999988079, 0.699999988079, 0.699999988079, 0.40000000596, 0.40000000596, 0.699999988079, 0.20000000298, 0.899999976158, 0.5, 0.10000000149, 0.899999976158, 0.5, 0.600000023842, 0.800000011921, 0.20000000298, 0.40000000596, 0.899999976158, 0.5, 0.699999988079, 0.600000023842, 0.899999976158, 0.600000023842, 0.5, 0.899999976158, 0.300000011921, 0.40000000596, 0.699999988079, 0.5, 0.300000011921, 0.300000011921, 0.40000000596, 0.899999976158, 0.40000000596, 0.40000000596, 0.10000000149, 0.300000011921, 0.899999976158, 0.10000000149, 0.10000000149, 0.40000000596, 0.800000011921, 0.600000023842, 0.40000000596, 0.5, 0.600000023842, 0.800000011921, 0.300000011921, 
+
+L3_cSYMM_o_R
+-0.0399998991191, 8.4100000681, -0.220000080317, 8.34000016585, 0.219999972284, 7.86000014484, 0.640000045151, 7.70000011474, 1.36999993503, 7.85000014603, 0.120000038594, 9.56999997601, -0.189999983311, 8.35000012815, 0.329999922663, 8.25000012815, -0.0699999551475, 8.37000006989, 0.35999995634, 8.42000002891, 0.459999957085, 8.54000008985, 1.42000004381, 8.81000012621, -0.170000043064, 8.47000002593, -0.210000004768, 8.78000008807, 0.689999914765, 9.50000013486, 0.569999908954, 9.65000005439, 0.230000002384, 9.24000004962, 1.33000004113, 9.36000009269, 0.869999993891, 8.69000019491, 1.79999998659, 8.72000016525, 0.870000097454, 9.24000012785, 2.49999997541, 9.4500000976, 2.95999995857, 10.7900000906, 0.390000077188, 9.9300001514, 0.629999901801, 9.15000018254, 1.17000001103, 10.3400000668, 0.250000029802, 8.74000011966, 0.809999977201, 9.37000015855, 1.67000007734, 10.510000118, 1.15999996379, 9.16000012174, 0.760000045747, 9.92000008926, 2.28999999821, 9.99000020981, 2.42999992713, 9.54000011146, 1.9800000754, 8.79000019416, 1.23000003517, 9.48000002846, 0.73999991104, 9.2000001803, 1.58999996245, 7.95000014305, 1.80999995261, 9.34000012785, 1.80999988928, 8.77000014737, 2.01999988735, 10.2500000425, -0.309999997318, 9.34000008315, 0.669999870956, 8.71000016198, 1.02999991968, 9.0900000906, 0.96999991715, 8.21000009641, 0.0299999643862, 8.8200000684, 2.54999998361, 9.15000014901, 0.579999897331, 8.40000008568, 0.319999985695, 8.76000011727, 2.3699998568, 9.81000021264, 2.45999985278, 9.05000007525, 1.90999995708, 9.3200001429, 0.240000082403, 9.76000002041, 0.0299999405444, 9.66000016347, -0.269999998361, 8.73000011116, 0.270000067651, 10.1400001584, 0.729999991208, 10.5400000697, 0.670000032634, 10.5700000431, -1.02999992639, 10.1000000924, 0.71999991864, 9.95000013486, -0.80999990195, 9.55000009611, -0.589999996722, 8.91000010908, -0.43999996841, 10.4500001043, 0.430000068694, 11.190000104, 0.250000014901, 9.14000005707, 9.68575473159e-08, 9.9100000681, 0.749999973178, 9.6600001359, 0.929999947995, 9.76000001818, 0.960000100881, 9.44000012338, -0.539999867827, 8.21000012994, -1.40000005737, 8.92000013545, 0.0699999804795, 8.9800000903, 0.239999981821, 9.27000012502, 0.339999976605, 9.55000007674, 0.450000008196, 9.46000006065, -0.709999960065, 9.45000007749, -0.450000111014, 8.71000010759, -0.499999941885, 8.34000015095, -0.570000017732, 9.47000006095, -0.610000030845, 9.00000006929, 0.40000006184, 10.4300000538, -0.219999985695, 8.30000003278, -0.0199999752641, 8.27000006095, 0.529999931604, 9.49000018224, 0.259999931753, 9.77000001699, 0.570000057966, 9.29000013828, 2.61000008151, 10.8600000107, 2.5999998942, 11.1000000201, 2.53999997959, 9.77000005051, 1.90000007451, 11.4100000264, 3.31999993652, 11.0800000329, 3.41999991864, 12.4699999589, 1.01000002712, 11.7200000006, 2.60999989823, 10.6100000808, 1.79999996796, 10.9499999784, 1.18999998555, 11.5999999687, 2.48999992818, 10.7600000279, 3.07999999717, 11.590000072, 2.17999995619, 10.1799999912, 2.38999999002, 11.2699999835, 2.92999994352, 10.8500000902, 2.63999988869, 10.9599999779, 3.03000003517, 11.3199999909, 1.61000000253, 8.91000005618, 0.0899999631941, 8.60000019893, 1.10999996603, 8.08000016481, 1.11000004724, 8.75000015199, 1.88999994904, 9.56000015303, 2.72999992639, 10.0200000669, 0.360000033826, 10.3100001203, 0.439999902844, 9.62000010639, 0.400000021607, 8.64000008464, 1.60999999657, 9.46000002787, 0.559999934733, 9.63000010297, 1.68000002623, 9.460000083, 1.12999997333, 9.24000002578, 0.980000002384, 9.27000004455, 2.12999995545, 9.36000016049, 1.61999983892, 9.54000003546, 1.45000000596, 9.06000013739, 0.200000090897, 9.7199999924, 0.180000011325, 9.29000015095, 0.41000002712, 8.0500001289, 0.380000071675, 7.99000013158, 1.10000000447, 8.46000010908, 1.35999993697, 10.4300000151, -1.51999988586, 8.94000006378, 0.0299999517202, 8.89000006452, 0.689999990016, 8.84000006378, -0.869999991655, 9.35000002682, 0.399999953061, 9.3900000608, 0.140000091344, 8.9100000599, 0.989999949038, 7.31000012994, -0.139999960959, 8.05000006706, 1.31999991193, 9.58000013202, 1.2399999401, 8.8000000447, 0.99000003919, 9.26000008747, -0.55999983564, 9.29000004217, -0.480000039637, 9.71000008896, -0.340000010133, 8.1400001055, -0.699999948591, 9.20000007972, 0.399999959767, 8.6700001429, 0.28999996841, 9.58999999374, -0.579999957681, 9.25000007749, -0.250000045449, 9.56000007108, -0.0600000070035, 9.48000003591, -0.699999991059, 9.37000001773, 0.0299999405444, 8.81000008449, 0.550000039488, 9.69000005484, 1.5899998872, 7.83000001803, -0.199999982119, 8.94000001609, 0.759999878109, 9.78000006571, 1.37999988168, 9.50999997497, 0.140000092089, 9.0700000684, 1.37000004679, 10.2200000513, 1.07000000954, 10.4300001246, 1.16000001222, 9.6400001286, 0.0600000718236, 10.8600000905, 2.04999998584, 10.1600000979, 2.15999992132, 11.0500000179, -0.619999898523, 10.6600001098, 1.81999992982, 10.5600000808, 1.4200000006, 10.8000000149, 1.0399999848, 10.8100000398, 0.630000006855, 10.7000000246, 1.60000001341, 10.6000000924, 2.11999991789, 8.09000008464, 0.810000001043, 9.87000007883, 2.27999996737, 10.7900001219, 1.73999991626, 8.69000010028, 2.02000000954, 9.82000006989, 
+
+L3_zSYMM_A_mm
+0.5, 0.1, 0.9, 0.9, 0.1, 0.8, 0.1, 0.8, 0.5, 0.9, 0.4, 0.1, 0.7, 0.2, 0.7, 0.5, 0.6, 0.9, 0.5, 0.6, 0.9, 0.9, 0.5, 0.3, 0.1, 0.3, 0.9, 0.6, 0.6, 0.3, 0.2, 0.5, 0.7, 0.3, 0.4, 0.6, 0.8, 0.5, 0.5, 0.3, 0.1, 0.8, 0.1, 0.3, 0.6, 0.7, 0.3, 0.2, 0.7, 0.4, 0.5, 0.5, 0.5, 0.2, 0.8, 0.4, 0.8, 0.1, 0.7, 0.9, 0.1, 0.8, 0.9, 0.6, 0.3, 0.2, 0.5, 0.1, 0.2, 0.9, 0.8, 0.5, 0.2, 0.4, 0.1, 0.2, 0.7, 0.3, 0.8, 0.8, 0.5, 0.9, 0.6, 0.3, 0.7, 0.4, 0.2, 0.9, 0.9, 0.2, 0.7, 0.4, 0.4, 0.4, 0.3, 0.5, 0.4, 0.5, 0.7, 0.8, 0.4, 0.1, 0.2, 0.5, 0.5, 0.5, 0.8, 0.5, 0.7, 0.4, 0.1, 0.5, 0.3, 0.9, 0.7, 0.9, 0.7, 0.6, 0.6, 0.4, 0.7, 0.2, 0.7, 0.3, 0.5, 0.2, 0.2, 0.4, 0.4, 0.4, 0.3, 0.9, 0.2, 0.4, 0.4, 0.8, 0.2, 0.3, 0.4, 0.4, 0.7, 0.5, 0.4, 0.6, 0.8, 0.4, 0.1, 0.2, 0.3, 0.5, 0.7, 0.9, 0.4, 0.8, 0.5, 0.3, 0.8, 0.7, 0.7, 0.8, 0.6, 0.9, 0.8, 0.5, 0.8, 0.1, 0.7, 0.3, 0.4, 0.5, 0.7, 0.6, 0.2, 0.3, 0.8, 0.7, 0.9, 0.7, 0.9, 0.1, 0.5, 0.6, 0.5, 0.3, 0.7, 0.9, 0.8, 0.8, 0.7, 0.8, 0.6, 0.4, 0.4, 0.4, 0.7, 0.8, 0.9, 0.1, 0.1, 0.1, 
+
+L3_zSYMM_B_mn
+0.3, 0.5, 0.9, 0.9, 0.6, 0.9, 0.8, 0.2, 0.5, 0.4, 0.6, 0.4, 0.6, 0.1, 0.3, 0.1, 0.7, 0.2, 0.9, 0.7, 0.5, 0.8, 0.6, 0.6, 0.1, 0.3, 0.8, 0.2, 0.4, 0.2, 0.4, 0.2, 0.3, 0.9, 0.4, 0.6, 0.8, 0.7, 0.7, 0.2, 0.5, 0.7, 0.7, 0.7, 0.6, 0.3, 0.4, 0.6, 0.7, 0.3, 0.3, 0.5, 0.4, 0.2, 0.4, 0.5, 0.3, 0.6, 0.8, 0.2, 0.6, 0.8, 0.2, 0.5, 0.8, 0.3, 0.7, 0.5, 0.8, 0.2, 0.1, 0.9, 0.7, 0.3, 0.1, 0.9, 0.4, 0.6, 0.7, 0.6, 0.9, 0.2, 0.5, 0.1, 0.4, 0.6, 0.8, 0.9, 0.4, 0.2, 0.5, 0.9, 0.4, 0.2, 0.4, 0.4, 0.4, 0.3, 0.1, 0.4, 0.2, 0.6, 0.2, 0.8, 0.8, 0.5, 0.1, 0.5, 0.6, 0.2, 0.2, 0.7, 0.6, 0.2, 0.6, 0.3, 0.5, 0.1, 0.7, 0.7, 0.8, 0.9, 0.1, 0.1, 0.1, 0.2, 0.6, 0.5, 0.3, 0.4, 0.8, 0.1, 0.4, 0.4, 0.1, 0.2, 0.4, 0.7, 0.4, 0.5, 0.4, 0.1, 0.4, 0.1, 0.5, 0.4, 0.5, 0.1, 0.4, 0.8, 0.4, 0.4, 0.5, 0.3, 0.1, 0.8, 0.4, 0.4, 0.3, 0.8, 0.8, 0.1, 0.2, 0.2, 0.5, 0.6, 0.1, 0.1, 0.9, 0.9, 0.3, 0.2, 0.3, 0.7, 0.6, 0.8, 0.3, 0.6, 0.1, 0.3, 0.7, 0.2, 0.5, 0.2, 0.8, 0.1, 0.4, 0.7, 0.5, 0.7, 0.7, 0.5, 0.6, 0.7, 0.1, 0.8, 0.3, 0.5, 0.2, 0.9, 0.9, 0.2, 0.2, 0.5, 0.8, 0.8, 0.9, 0.3, 0.3, 0.2, 0.4, 0.3, 0.6, 0.4, 0.5, 0.8, 0.5, 0.9, 0.1, 0.1, 0.9, 0.6, 0.6, 0.9, 0.6, 0.6, 0.3, 0.1, 0.5, 0.5, 0.9, 0.7, 0.8, 0.1, 0.7, 0.7, 0.6, 0.3, 0.1, 0.5, 0.9, 0.9, 0.4, 0.2, 0.8, 0.3, 0.8, 0.1, 0.6, 0.1, 0.6, 0.6, 0.7, 0.5, 0.8, 0.4, 0.9, 0.6, 0.1, 0.7, 0.1, 0.4, 0.7, 0.1, 0.5, 0.6, 0.8, 0.8, 0.1, 0.4, 0.3, 0.6, 0.5, 0.9, 0.2, 0.2, 0.8, 0.8, 0.5, 0.1, 0.9, 0.6, 0.7, 0.9, 0.6, 0.8, 0.8, 0.3, 0.4, 0.4, 0.8, 0.7, 0.3, 0.1, 0.8, 0.4, 0.2, 0.9, 0.4, 0.8, 0.6, 0.5, 0.7, 0.5, 0.4, 0.2, 0.2, 0.5, 0.7, 0.8, 0.4, 0.7, 0.8, 0.9, 0.6, 0.3, 0.3, 0.2, 0.5, 0.6, 0.9, 0.6, 0.8, 0.6, 0.1, 0.2, 0.2, 0.5, 0.7, 0.8, 0.3, 0.9, 0.1, 0.2, 0.9, 0.4, 0.6, 0.4, 0.4, 0.1, 
+
+L3_zSYMM_C_mn
+0.4, 0.2, 0.2, 0.3, 0.2, 0.4, 0.4, 0.4, 0.9, 0.1, 0.5, 0.1, 0.4, 0.5, 0.1, 0.3, 0.6, 0.3, 0.9, 0.2, 0.1, 0.7, 0.7, 0.8, 0.9, 0.9, 0.5, 0.2, 0.5, 0.4, 0.9, 0.3, 0.8, 0.3, 0.5, 0.2, 0.8, 0.3, 0.2, 0.2, 0.9, 0.3, 0.4, 0.1, 0.5, 0.2, 0.6, 0.5, 0.2, 0.6, 0.2, 0.4, 0.2, 0.2, 0.9, 0.1, 0.4, 0.4, 0.8, 0.1, 0.5, 0.8, 0.8, 0.4, 0.6, 0.3, 0.8, 0.6, 0.4, 0.2, 0.3, 0.9, 0.5, 0.3, 0.2, 0.5, 0.2, 0.6, 0.3, 0.8, 0.4, 0.9, 0.4, 0.8, 0.3, 0.9, 0.3, 0.7, 0.7, 0.3, 0.6, 0.6, 0.9, 0.8, 0.1, 0.4, 0.5, 0.4, 0.2, 0.9, 0.5, 0.7, 0.4, 0.7, 0.5, 0.5, 0.9, 0.4, 0.3, 0.8, 0.4, 0.2, 0.9, 0.2, 0.2, 0.4, 0.3, 0.3, 0.1, 0.6, 0.2, 0.2, 0.9, 0.9, 0.8, 0.5, 0.2, 0.5, 0.4, 0.3, 0.4, 0.8, 0.9, 0.6, 0.2, 0.3, 0.7, 0.5, 0.7, 0.4, 0.1, 0.1, 0.4, 0.6, 0.2, 0.5, 0.6, 0.8, 0.4, 0.6, 0.7, 0.5, 0.4, 0.3, 0.4, 0.4, 0.6, 0.6, 0.8, 0.2, 0.5, 0.1, 0.7, 0.9, 0.3, 0.1, 0.7, 0.7, 0.8, 0.5, 0.7, 0.9, 0.8, 0.4, 0.7, 0.9, 0.6, 0.1, 0.6, 0.4, 0.4, 0.8, 0.3, 0.9, 0.6, 0.9, 0.8, 0.7, 0.3, 0.2, 0.5, 0.3, 0.7, 0.2, 0.8, 0.1, 0.8, 0.6, 0.8, 0.5, 0.5, 0.4, 0.8, 0.4, 0.5, 0.8, 0.1, 0.7, 0.4, 0.6, 0.5, 0.9, 0.9, 0.6, 0.5, 0.6, 0.2, 0.7, 0.8, 0.5, 0.6, 0.7, 0.7, 0.5, 0.1, 0.7, 0.2, 0.6, 0.8, 0.4, 0.8, 0.2, 0.4, 0.2, 0.5, 0.9, 0.8, 0.9, 0.9, 0.9, 0.7, 0.4, 0.3, 0.8, 0.4, 0.3, 0.9, 0.3, 0.9, 0.5, 0.8, 0.7, 0.4, 0.1, 0.1, 0.7, 0.8, 0.2, 0.5, 0.9, 0.2, 0.5, 0.9, 0.1, 0.1, 0.6, 0.2, 0.6, 0.7, 0.8, 0.5, 0.1, 0.3, 0.3, 0.7, 0.5, 0.9, 0.9, 0.4, 0.2, 0.3, 0.4, 0.7, 0.2, 0.5, 0.1, 0.2, 0.4, 0.2, 0.1, 0.1, 0.5, 0.1, 0.9, 0.3, 0.8, 0.7, 0.3, 0.5, 0.6, 0.9, 0.4, 0.6, 0.7, 0.8, 0.4, 0.3, 0.7, 0.2, 0.2, 0.2, 0.7, 0.7, 0.6, 0.5, 0.9, 0.1, 0.2, 0.9, 0.8, 0.3, 0.7, 0.2, 0.9, 0.1, 0.7, 0.5, 0.6, 0.9, 0.2, 0.9, 0.4, 0.9, 0.7, 0.4, 0.6, 0.7, 0.8, 0.9, 0.8, 
+
+L3_zSYMM_o_L
+-1.2, 5.58, -0.02, 6.56, 0.46, 5.56, 0.66, 5.35, 1.0, 5.55, 1.14, 5.42, -0.26, 6.72, 1.28, 5.31, 0.68, 5.78, -0.01, 6.38, -0.03, 5.0, -0.5, 5.81, 0.88, 6.15, 0.11, 5.13, 0.73, 6.07, 1.49, 4.67, 0.57, 5.33, 0.01, 5.51, 1.48, 6.52, 0.34, 5.31, 2.42, 4.76, 1.49, 5.14, 2.0, 5.21, 1.57, 6.13, 2.06, 4.58, 1.53, 5.84, 0.51, 7.06, 0.7, 4.22, 0.36, 5.07, 1.26, 4.58, 1.09, 5.68, 2.18, 5.04, 1.78, 4.53, 0.81, 4.85, 0.3, 4.83, -0.35, 6.73, 0.69, 4.92, 0.42, 5.12, 1.25, 4.93, 1.74, 5.3, 1.39, 6.44, 2.25, 5.02, 1.17, 6.19, 0.43, 6.64, 0.23, 4.1, -0.05, 5.65, 1.18, 5.03, 0.37, 4.76, 1.66, 5.39, 0.97, 4.82, 0.27, 4.71, -0.57, 5.11, -0.14, 6.3, 1.03, 5.32, 0.53, 5.84, 0.75, 5.04, 1.96, 4.54, 0.12, 5.23, 2.04, 4.29, 0.32, 5.96, -0.31, 5.06, 0.21, 4.63, 0.07, 5.45, -0.01, 5.25, 0.17, 4.82, 0.59, 5.55, 2.27, 4.63, -0.54, 4.4, -0.12, 5.23, 0.11, 7.45, 0.03, 5.06, 0.79, 6.28, 0.58, 5.6, 1.73, 5.73, 0.97, 6.39, 2.49, 5.02, 0.74, 6.33, -0.32, 7.21, 0.41, 4.79, 0.52, 5.97, 0.3, 4.6, 0.61, 5.67, 1.05, 5.88, 1.32, 4.99, 0.89, 5.14, -0.59, 6.22, 0.57, 6.78, 0.87, 5.72, 1.15, 4.66, 1.11, 5.65, 1.09, 5.72, 0.12, 6.56, 2.06, 5.37, 1.11, 6.38, -0.26, 6.87, -0.33, 4.17, 0.15, 4.92, 0.85, 4.9, -0.07, 5.36, 1.54, 5.8, 0.32, 4.79, 0.48, 4.91, -0.23, 4.39, -0.21, 6.17, 0.54, 4.51, 0.81, 5.07, 1.41, 4.57, 1.48, 4.51, 0.26, 4.88, 1.88, 4.21, 0.6, 5.15, 0.22, 5.44, -0.41, 4.28, -0.37, 4.77, 0.61, 3.84, 0.58, 3.84, 0.07, 4.39, 0.84, 4.35, 0.48, 4.76, -0.03, 6.12, 0.1, 7.3, 0.45, 6.7, 0.52, 5.77, 1.39, 5.68, 1.74, 6.05, 0.89, 6.37, 2.18, 4.88, 0.25, 6.67, 0.5, 6.73, 0.01, 5.7, -0.25, 6.53, -0.1, 5.08, -0.31, 5.77, 0.44, 6.21, 1.29, 5.97, -0.01, 5.17, 0.07, 5.71, 1.59, 7.99, 2.04, 6.86, 2.49, 6.05, 2.0, 6.15, 2.93, 5.56, 2.07, 5.94, 3.33, 4.98, 1.98, 6.25, 1.09, 7.77, 0.1, 5.56, 0.92, 6.8, 1.63, 5.53, 0.96, 6.25, 2.36, 5.99, 2.36, 5.42, 0.76, 5.43, -0.11, 6.26, -0.12, 6.93, 1.16, 5.82, 1.53, 5.35, 1.3, 6.19, 2.02, 5.65, 1.94, 6.85, 2.44, 4.76, 0.94, 6.91, 0.06, 8.26, 0.34, 4.75, 0.42, 5.14, 1.95, 5.54, 1.26, 6.03, 1.37, 6.18, 1.6, 4.71, 0.28, 5.75, 
+
+L3_zSYMM_A_nn
+0.7, 0.2, 0.1, 0.2, 0.4, 0.9, 0.8, 0.1, 0.8, 0.3, 0.1, 0.7, 0.1, 0.5, 0.6, 0.3, 0.8, 0.8, 0.2, 0.2, 0.4, 0.5, 0.3, 0.4, 0.8, 0.2, 0.1, 0.2, 0.5, 0.4, 0.2, 0.8, 0.7, 0.8, 0.1, 0.2, 0.7, 0.9, 0.2, 0.2, 0.5, 0.9, 0.8, 0.3, 0.4, 0.4, 0.1, 0.3, 0.6, 0.8, 0.5, 0.5, 0.3, 0.7, 0.1, 0.8, 0.4, 0.3, 0.5, 0.3, 0.8, 0.4, 0.1, 0.1, 0.6, 0.7, 0.5, 0.8, 0.4, 0.9, 0.2, 0.2, 0.4, 0.7, 0.8, 0.1, 0.7, 0.6, 0.3, 0.8, 0.6, 0.8, 0.9, 0.8, 0.1, 0.9, 0.4, 0.2, 0.3, 0.3, 0.4, 0.9, 0.5, 0.7, 0.2, 0.2, 0.4, 0.8, 0.4, 0.1, 0.8, 0.1, 0.8, 0.1, 0.5, 0.9, 0.8, 0.1, 0.6, 0.3, 0.4, 0.6, 0.3, 0.2, 0.7, 0.3, 0.1, 0.2, 0.2, 0.8, 0.9, 0.9, 0.8, 0.1, 0.7, 0.6, 0.3, 0.7, 0.6, 0.1, 0.5, 0.3, 0.3, 0.5, 0.1, 0.4, 0.8, 0.3, 0.8, 0.3, 0.7, 0.6, 0.4, 0.6, 0.8, 0.9, 0.5, 0.2, 0.8, 0.8, 0.6, 0.9, 0.8, 0.7, 0.5, 0.6, 0.9, 0.3, 0.9, 0.1, 0.2, 0.2, 0.1, 0.2, 0.8, 0.8, 0.7, 0.5, 0.8, 0.9, 0.1, 0.7, 0.4, 0.4, 0.3, 0.8, 0.3, 0.2, 0.5, 0.2, 0.3, 0.5, 0.9, 0.2, 0.3, 0.4, 0.7, 0.4, 0.4, 0.5, 0.6, 0.3, 0.1, 0.2, 0.9, 0.4, 0.4, 0.7, 0.9, 0.4, 0.2, 0.4, 0.4, 0.4, 0.1, 0.5, 0.1, 0.3, 0.6, 0.8, 0.7, 0.3, 0.8, 0.8, 0.9, 0.2, 0.6, 0.4, 0.2, 0.8, 0.5, 0.9, 0.5, 0.4, 0.2, 0.3, 0.7, 0.4, 0.1, 0.3, 0.7, 0.6, 0.1, 0.6, 0.3, 0.4, 0.9, 0.8, 0.6, 0.3, 0.6, 0.8, 0.9, 0.8, 0.1, 0.2, 0.6, 0.9, 0.3, 0.4, 0.2, 0.8, 0.6, 0.7, 0.4, 0.8, 0.7, 0.7, 0.4, 0.1, 0.2, 0.5, 0.7, 0.9, 0.6, 0.4, 0.8, 0.9, 0.6, 0.1, 0.8, 0.8, 0.8, 0.8, 0.5, 0.5, 0.1, 0.9, 0.2, 0.8, 0.8, 0.7, 0.7, 0.4, 0.5, 0.9, 0.4, 0.8, 0.3, 0.9, 0.2, 0.2, 0.8, 0.9, 0.5, 0.6, 0.7, 0.4, 0.3, 0.4, 0.7, 0.6, 0.7, 0.8, 0.7, 0.4, 0.2, 0.2, 0.3, 0.7, 0.4, 0.2, 0.9, 0.9, 0.5, 0.6, 0.4, 0.5, 0.5, 0.4, 0.7, 0.7, 0.2, 0.2, 0.6, 0.6, 0.2, 0.8, 0.7, 0.8, 0.5, 0.5, 0.6, 0.6, 0.8, 0.3, 0.7, 0.8, 0.2, 0.3, 0.4, 0.5, 0.1, 0.8, 0.3, 0.3, 0.8, 0.1, 0.9, 0.3, 0.6, 0.3, 0.2, 0.3, 0.4, 0.1, 0.8, 0.9, 0.2, 0.8, 0.7, 0.1, 0.1, 0.4, 0.9, 0.9, 0.3, 0.9, 0.7, 0.1, 0.8, 0.7, 0.5, 0.4, 0.3, 0.4, 0.4, 0.3, 0.4, 0.9, 0.7, 0.6, 0.9, 0.1, 0.1, 0.2, 0.7, 0.4, 0.2, 0.5, 0.5, 0.6, 0.7, 0.8, 0.1, 0.4, 0.1, 0.3, 0.5, 0.1, 0.6, 0.4, 0.2, 0.8, 0.9, 0.8, 0.7, 0.2, 0.8, 0.2, 0.5, 0.3, 0.5, 0.7, 0.3, 0.7, 0.2, 0.2, 0.9, 0.4, 0.1, 0.3, 0.7, 0.9, 0.7, 0.4, 0.5, 0.5, 0.9, 0.9, 0.5, 0.1, 0.4, 0.3, 0.7, 0.9, 0.1, 0.5, 0.7, 0.6, 0.9, 0.5, 0.1, 0.2, 0.8, 0.4, 0.2, 0.2, 0.6, 0.1, 0.1, 0.2, 0.4, 0.7, 0.7, 0.6, 0.6, 0.4, 0.3, 0.4, 0.6, 0.6, 0.3, 0.9, 0.6, 0.4, 0.7, 0.9, 0.5, 0.6, 0.3, 0.4, 0.7, 0.4, 0.8, 0.4, 0.5, 0.4, 0.1, 0.1, 0.4, 0.8, 0.5, 0.3, 0.8, 0.8, 0.9, 0.4, 0.1, 0.6, 0.8, 0.9, 0.7, 0.6, 0.8, 0.3, 0.7, 0.1, 0.2, 0.8, 0.1, 0.5, 0.3, 0.4, 0.9, 0.5, 0.5, 0.1, 0.6, 0.6, 0.2, 0.8, 0.6, 0.7, 0.4, 0.1, 0.3, 0.5, 0.7, 0.5, 0.2, 0.4, 0.3, 0.4, 0.6, 0.1, 0.7, 0.8, 0.7, 0.8, 0.8, 0.7, 0.9, 0.8, 0.7, 0.6, 0.7, 0.4, 0.5, 0.1, 0.2, 0.8, 0.9, 0.4, 0.7, 0.8, 0.5, 0.8, 0.8, 0.1, 0.1, 0.4, 0.8, 0.9, 0.4, 0.4, 0.9, 0.8, 0.8, 0.8, 0.7, 0.4, 0.2, 0.3, 0.5, 0.4, 0.7, 0.2, 0.9, 0.5, 0.8, 0.4, 0.6, 0.6, 0.9, 0.4, 0.1, 0.9, 
+
+L3_zSYMM_o_R
+0.46, 7.37, 0.17, 8.33, 0.51, 8.27, 2.15, 8.81, 3.18, 10.19, 1.17, 7.06, 1.23, 8.84, 0.2, 10.17, 0.25, 10.19, 1.6, 8.58, 0.84, 8.64, 1.81, 8.67, 2.27, 10.2, 1.62, 8.05, 1.81, 8.47, 1.86, 9.98, 2.2, 9.07, 1.35, 8.04, 1.03, 8.96, 0.42, 8.5, 1.9, 8.52, 1.97, 10.4, 1.28, 7.86, 0.74, 9.35, 0.69, 10.29, -0.28, 10.65, 0.22, 9.38, 2.0, 8.74, 1.6, 8.41, 2.16, 9.18, 1.77, 9.02, 1.56, 8.91, 1.29, 9.69, 1.94, 10.71, 0.15, 7.22, -1.62, 8.13, 0.11, 8.95, 0.39, 7.78, 1.17, 10.11, 0.67, 7.64, 0.09, 9.43, -0.37, 9.76, -0.66, 9.97, -0.82, 8.7, 0.07, 7.78, 0.23, 8.41, 1.41, 8.93, 0.05, 8.49, 0.88, 8.83, -0.54, 9.7, 1.31, 9.1, 0.74, 6.88, 0.48, 7.45, 0.49, 7.26, 0.52, 8.25, 1.51, 8.64, 1.7, 6.21, -0.34, 7.13, -0.07, 9.04, -0.47, 8.59, 0.86, 7.29, 0.83, 8.15, 1.19, 7.87, 0.97, 7.8, 1.43, 6.93, 1.21, 7.6, 0.72, 8.25, 0.98, 8.67, 1.39, 6.98, 0.09, 6.66, -0.4, 7.69, 0.3, 7.58, 0.79, 9.82, 1.35, 7.06, -0.02, 7.95, -0.01, 9.17, -0.07, 8.89, -0.02, 7.35, 1.37, 6.85, 0.9, 6.41, 1.38, 7.37, 0.97, 8.03, 0.34, 7.62, 0.89, 8.68, 0.67, 8.86, -0.22, 8.64, -0.39, 7.99, -0.46, 8.57, 0.39, 7.55, 1.34, 9.73, -0.27, 8.22, -0.67, 8.5, -1.16, 9.65, -0.72, 10.0, -0.36, 8.84, -0.19, 7.9, -0.29, 7.93, 1.2, 8.6, 0.56, 8.41, 0.8, 8.31, -0.13, 9.55, 1.42, 9.04, 1.18, 8.42, 0.3, 9.03, 0.15, 9.11, 2.11, 9.85, 3.4, 10.85, 1.63, 8.78, 0.74, 9.88, 1.79, 10.65, 0.79, 11.48, 1.02, 9.41, 0.9, 10.22, 1.36, 9.46, 2.41, 10.05, 1.33, 8.85, 2.14, 8.83, 1.15, 10.71, 2.49, 11.55, 1.92, 7.59, 0.66, 8.3, 0.81, 9.11, 1.5, 8.95, 2.38, 10.99, 2.39, 7.88, 1.13, 8.75, 0.75, 10.68, -0.49, 10.43, 1.4, 8.85, 1.69, 8.86, 1.01, 8.26, 1.27, 8.91, 1.05, 8.82, 1.87, 9.14, 1.7, 9.82, 1.45, 9.8, 0.46, 8.49, 1.06, 8.75, 0.04, 10.28, 1.75, 8.96, 2.29, 11.3, 0.46, 8.43, 0.78, 9.66, -0.31, 11.26, -0.57, 11.2, 0.84, 10.12, 0.2, 9.47, 0.78, 9.84, 1.66, 9.87, 0.56, 8.8, 1.74, 10.1, 1.08, 10.09, 2.08, 11.54, 0.9, 8.67, -0.44, 8.25, -0.59, 9.61, 0.67, 8.94, 2.14, 11.61, 0.62, 7.38, 0.45, 9.1, -0.57, 10.42, -1.46, 11.11, -0.16, 9.86, 1.07, 8.53, 0.82, 8.16, 0.99, 8.92, 1.29, 8.5, 0.71, 8.93, 0.7, 9.71, 1.74, 11.15, 
+
+L3_cHEMM_A_mm
+0.899999976158, 0.0, 0.10000000149, 0.300000011921, 0.899999976158, 0.5, 0.800000011921, 0.800000011921, 0.40000000596, 0.600000023842, 0.10000000149, 0.699999988079, 0.899999976158, 0.10000000149, 0.300000011921, 0.699999988079, 0.600000023842, 0.899999976158, 0.800000011921, 0.300000011921, 0.10000000149, -0.300000011921, 0.10000000149, 0.0, 0.5, 0.300000011921, 0.5, 0.800000011921, 0.899999976158, 0.5, 0.699999988079, 0.5, 0.5, 0.600000023842, 0.300000011921, 0.20000000298, 0.800000011921, 0.800000011921, 0.5, 0.600000023842, 0.899999976158, -0.5, 0.5, -0.300000011921, 0.5, 0.0, 0.800000011921, 0.20000000298, 0.5, 0.699999988079, 0.5, 0.800000011921, 0.899999976158, 0.699999988079, 0.300000011921, 0.300000011921, 0.40000000596, 0.699999988079, 0.899999976158, 0.10000000149, 0.800000011921, -0.800000011921, 0.5, -0.800000011921, 0.800000011921, -0.20000000298, 0.899999976158, 0.0, 0.899999976158, 0.5, 0.10000000149, 0.600000023842, 0.10000000149, 0.10000000149, 0.699999988079, 0.699999988079, 0.699999988079, 0.40000000596, 0.10000000149, 0.600000023842, 0.40000000596, -0.600000023842, 0.899999976158, -0.5, 0.5, -0.699999988079, 0.899999976158, -0.5, 0.899999976158, 0.0, 0.600000023842, 0.800000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.10000000149, 0.40000000596, 0.20000000298, 0.5, 0.899999976158, 0.10000000149, -0.699999988079, 0.699999988079, -0.5, 0.5, -0.800000011921, 0.10000000149, -0.600000023842, 0.600000023842, -0.800000011921, 0.899999976158, 0.0, 0.699999988079, 0.600000023842, 0.40000000596, 0.600000023842, 0.600000023842, 0.20000000298, 0.600000023842, 0.20000000298, 0.899999976158, -0.10000000149, 0.5, -0.600000023842, 0.899999976158, -0.699999988079, 0.10000000149, -0.10000000149, 0.20000000298, -0.40000000596, 0.699999988079, -0.600000023842, 0.600000023842, 0.0, 0.899999976158, 0.300000011921, 0.10000000149, 0.20000000298, 0.899999976158, 0.699999988079, 0.300000011921, -0.699999988079, 0.300000011921, -0.20000000298, 0.300000011921, -0.300000011921, 0.699999988079, -0.699999988079, 0.800000011921, -0.10000000149, 0.40000000596, -0.600000023842, 0.899999976158, -0.300000011921, 0.20000000298, 0.0, 0.899999976158, 0.600000023842, 0.800000011921, 0.20000000298, 0.600000023842, -0.899999976158, 0.800000011921, -0.800000011921, 0.40000000596, -0.699999988079, 0.699999988079, -0.40000000596, 0.40000000596, -0.20000000298, 0.600000023842, -0.20000000298, 0.10000000149, -0.20000000298, 0.899999976158, -0.600000023842, 0.10000000149, 0.0, 0.600000023842, 0.40000000596, 0.800000011921, -0.300000011921, 0.5, -0.600000023842, 0.899999976158, -0.10000000149, 0.10000000149, -0.600000023842, 0.5, -0.899999976158, 0.600000023842, -0.20000000298, 0.899999976158, -0.699999988079, 0.800000011921, -0.20000000298, 0.600000023842, -0.40000000596, 0.600000023842, 0.0, 
+
+L3_cHEMM_B_mn
+0.10000000149, 0.600000023842, 0.300000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.40000000596, 0.5, 0.699999988079, 0.20000000298, 0.10000000149, 0.5, 0.40000000596, 0.20000000298, 0.699999988079, 0.300000011921, 0.20000000298, 0.10000000149, 0.600000023842, 0.40000000596, 0.20000000298, 0.5, 0.20000000298, 0.899999976158, 0.5, 0.800000011921, 0.20000000298, 0.699999988079, 0.40000000596, 0.600000023842, 0.10000000149, 0.300000011921, 0.20000000298, 0.800000011921, 0.20000000298, 0.699999988079, 0.899999976158, 0.20000000298, 0.300000011921, 0.5, 0.40000000596, 0.600000023842, 0.20000000298, 0.600000023842, 0.600000023842, 0.300000011921, 0.5, 0.699999988079, 0.800000011921, 0.300000011921, 0.20000000298, 0.40000000596, 0.300000011921, 0.40000000596, 0.600000023842, 0.699999988079, 0.699999988079, 0.40000000596, 0.600000023842, 0.40000000596, 0.300000011921, 0.5, 0.5, 0.800000011921, 0.10000000149, 0.20000000298, 0.899999976158, 0.899999976158, 0.600000023842, 0.899999976158, 0.300000011921, 0.600000023842, 0.300000011921, 0.40000000596, 0.5, 0.699999988079, 0.10000000149, 0.5, 0.5, 0.899999976158, 0.899999976158, 0.20000000298, 0.5, 0.20000000298, 0.699999988079, 0.20000000298, 0.20000000298, 0.20000000298, 0.699999988079, 0.10000000149, 0.899999976158, 0.699999988079, 0.40000000596, 0.5, 0.5, 0.800000011921, 0.800000011921, 0.600000023842, 0.5, 0.300000011921, 0.600000023842, 0.600000023842, 0.40000000596, 0.699999988079, 0.40000000596, 0.40000000596, 0.10000000149, 0.600000023842, 0.800000011921, 0.800000011921, 0.5, 0.40000000596, 0.300000011921, 0.600000023842, 0.699999988079, 0.800000011921, 0.800000011921, 0.10000000149, 0.20000000298, 0.5, 0.40000000596, 0.20000000298, 0.800000011921, 0.600000023842, 0.300000011921, 0.800000011921, 0.5, 0.300000011921, 0.699999988079, 0.699999988079, 0.10000000149, 0.5, 0.300000011921, 0.5, 0.40000000596, 0.40000000596, 0.20000000298, 0.899999976158, 0.699999988079, 0.5, 0.899999976158, 0.699999988079, 0.899999976158, 0.20000000298, 0.20000000298, 0.600000023842, 0.300000011921, 0.699999988079, 0.40000000596, 0.600000023842, 0.40000000596, 0.600000023842, 0.899999976158, 0.600000023842, 0.699999988079, 0.699999988079, 0.899999976158, 0.20000000298, 0.40000000596, 0.800000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.5, 0.899999976158, 0.600000023842, 0.10000000149, 0.5, 0.5, 0.20000000298, 0.10000000149, 0.10000000149, 0.800000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.10000000149, 0.600000023842, 0.600000023842, 0.600000023842, 0.20000000298, 0.600000023842, 0.10000000149, 0.600000023842, 0.20000000298, 0.300000011921, 0.40000000596, 0.800000011921, 0.899999976158, 0.300000011921, 0.10000000149, 0.5, 0.800000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.699999988079, 0.899999976158, 0.699999988079, 0.20000000298, 0.40000000596, 0.899999976158, 0.40000000596, 0.600000023842, 0.300000011921, 0.300000011921, 0.300000011921, 0.300000011921, 0.300000011921, 0.699999988079, 0.300000011921, 0.40000000596, 0.40000000596, 0.5, 0.10000000149, 0.40000000596, 0.899999976158, 0.699999988079, 0.699999988079, 0.40000000596, 0.800000011921, 0.5, 0.800000011921, 0.800000011921, 0.800000011921, 0.40000000596, 0.300000011921, 0.5, 0.10000000149, 0.899999976158, 0.600000023842, 0.40000000596, 0.800000011921, 0.800000011921, 0.600000023842, 0.300000011921, 0.40000000596, 0.40000000596, 0.699999988079, 0.800000011921, 0.899999976158, 0.699999988079, 0.300000011921, 0.899999976158, 0.20000000298, 0.10000000149, 0.899999976158, 0.800000011921, 0.40000000596, 0.800000011921, 0.5, 0.899999976158, 0.40000000596, 0.10000000149, 0.899999976158, 0.300000011921, 0.800000011921, 0.20000000298, 0.699999988079, 0.5, 0.899999976158, 0.300000011921, 0.899999976158, 0.300000011921, 0.600000023842, 0.600000023842, 0.300000011921, 0.800000011921, 0.899999976158, 0.10000000149, 0.20000000298, 0.899999976158, 0.10000000149, 0.800000011921, 0.300000011921, 0.300000011921, 0.5, 0.899999976158, 0.600000023842, 0.5, 0.20000000298, 0.5, 0.300000011921, 0.600000023842, 0.40000000596, 0.20000000298, 0.800000011921, 0.5, 0.5, 0.600000023842, 0.699999988079, 0.10000000149, 0.10000000149, 0.600000023842, 0.300000011921, 0.600000023842, 0.20000000298, 0.10000000149, 0.20000000298, 0.699999988079, 0.40000000596, 0.800000011921, 0.600000023842, 0.10000000149, 0.10000000149, 0.300000011921, 0.5, 0.699999988079, 0.800000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.20000000298, 0.10000000149, 0.800000011921, 0.699999988079, 0.600000023842, 0.5, 0.699999988079, 0.699999988079, 0.20000000298, 0.5, 0.800000011921, 0.40000000596, 0.600000023842, 0.899999976158, 0.10000000149, 0.5, 0.699999988079, 0.40000000596, 0.699999988079, 0.5, 0.10000000149, 0.5, 0.300000011921, 0.40000000596, 0.899999976158, 0.800000011921, 0.40000000596, 
+
+L3_cHEMM_C_mn
+0.899999976158, 0.699999988079, 0.10000000149, 0.10000000149, 0.40000000596, 0.10000000149, 0.5, 0.20000000298, 0.300000011921, 0.699999988079, 0.300000011921, 0.600000023842, 0.20000000298, 0.300000011921, 0.800000011921, 0.800000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.800000011921, 0.899999976158, 0.40000000596, 0.40000000596, 0.899999976158, 0.600000023842, 0.699999988079, 0.600000023842, 0.300000011921, 0.600000023842, 0.5, 0.800000011921, 0.20000000298, 0.5, 0.800000011921, 0.20000000298, 0.600000023842, 0.20000000298, 0.40000000596, 0.40000000596, 0.600000023842, 0.20000000298, 0.5, 0.20000000298, 0.899999976158, 0.800000011921, 0.300000011921, 0.800000011921, 0.699999988079, 0.5, 0.10000000149, 0.40000000596, 0.40000000596, 0.10000000149, 0.20000000298, 0.10000000149, 0.20000000298, 0.600000023842, 0.40000000596, 0.10000000149, 0.600000023842, 0.699999988079, 0.40000000596, 0.20000000298, 0.699999988079, 0.300000011921, 0.699999988079, 0.20000000298, 0.600000023842, 0.800000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.40000000596, 0.699999988079, 0.40000000596, 0.10000000149, 0.300000011921, 0.5, 0.10000000149, 0.800000011921, 0.600000023842, 0.5, 0.40000000596, 0.600000023842, 0.300000011921, 0.40000000596, 0.40000000596, 0.5, 0.699999988079, 0.699999988079, 0.600000023842, 0.20000000298, 0.40000000596, 0.600000023842, 0.10000000149, 0.800000011921, 0.800000011921, 0.5, 0.899999976158, 0.300000011921, 0.40000000596, 0.300000011921, 0.20000000298, 0.699999988079, 0.5, 0.40000000596, 0.40000000596, 0.899999976158, 0.300000011921, 0.699999988079, 0.300000011921, 0.5, 0.899999976158, 0.40000000596, 0.300000011921, 0.600000023842, 0.40000000596, 0.5, 0.40000000596, 0.600000023842, 0.600000023842, 0.600000023842, 0.800000011921, 0.5, 0.10000000149, 0.699999988079, 0.20000000298, 0.899999976158, 0.5, 0.40000000596, 0.40000000596, 0.699999988079, 0.10000000149, 0.600000023842, 0.899999976158, 0.20000000298, 0.40000000596, 0.20000000298, 0.5, 0.699999988079, 0.10000000149, 0.300000011921, 0.899999976158, 0.600000023842, 0.20000000298, 0.10000000149, 0.699999988079, 0.899999976158, 0.600000023842, 0.300000011921, 0.600000023842, 0.800000011921, 0.10000000149, 0.800000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.699999988079, 0.40000000596, 0.600000023842, 0.20000000298, 0.300000011921, 0.5, 0.40000000596, 0.899999976158, 0.899999976158, 0.300000011921, 0.40000000596, 0.600000023842, 0.5, 0.20000000298, 0.600000023842, 0.600000023842, 0.10000000149, 0.40000000596, 0.800000011921, 0.10000000149, 0.600000023842, 0.899999976158, 0.40000000596, 0.899999976158, 0.600000023842, 0.5, 0.5, 0.800000011921, 0.10000000149, 0.20000000298, 0.600000023842, 0.600000023842, 0.300000011921, 0.40000000596, 0.300000011921, 0.300000011921, 0.800000011921, 0.40000000596, 0.5, 0.699999988079, 0.699999988079, 0.300000011921, 0.20000000298, 0.699999988079, 0.5, 0.40000000596, 0.899999976158, 0.40000000596, 0.600000023842, 0.300000011921, 0.300000011921, 0.800000011921, 0.300000011921, 0.300000011921, 0.10000000149, 0.300000011921, 0.600000023842, 0.5, 0.800000011921, 0.600000023842, 0.10000000149, 0.20000000298, 0.10000000149, 0.300000011921, 0.600000023842, 0.300000011921, 0.5, 0.20000000298, 0.5, 0.699999988079, 0.20000000298, 0.5, 0.699999988079, 0.40000000596, 0.5, 0.600000023842, 0.40000000596, 0.899999976158, 0.5, 0.10000000149, 0.20000000298, 0.699999988079, 0.10000000149, 0.800000011921, 0.5, 0.20000000298, 0.899999976158, 0.5, 0.10000000149, 0.899999976158, 0.5, 0.40000000596, 0.40000000596, 0.20000000298, 0.40000000596, 0.800000011921, 0.40000000596, 0.40000000596, 0.10000000149, 0.10000000149, 0.5, 0.20000000298, 0.20000000298, 0.800000011921, 0.40000000596, 0.40000000596, 0.20000000298, 0.20000000298, 0.899999976158, 0.699999988079, 0.699999988079, 0.300000011921, 0.5, 0.20000000298, 0.300000011921, 0.5, 0.600000023842, 0.600000023842, 0.699999988079, 0.5, 0.600000023842, 0.5, 0.699999988079, 0.800000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.800000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.40000000596, 0.300000011921, 0.899999976158, 0.600000023842, 0.600000023842, 0.10000000149, 0.600000023842, 0.800000011921, 0.40000000596, 0.699999988079, 0.40000000596, 0.300000011921, 0.899999976158, 0.899999976158, 0.300000011921, 0.899999976158, 0.300000011921, 0.40000000596, 0.10000000149, 0.300000011921, 0.699999988079, 0.40000000596, 0.5, 0.20000000298, 0.600000023842, 0.800000011921, 0.800000011921, 0.5, 0.40000000596, 0.10000000149, 0.899999976158, 0.5, 0.800000011921, 0.699999988079, 0.10000000149, 0.899999976158, 0.300000011921, 0.899999976158, 0.20000000298, 0.40000000596, 0.40000000596, 0.600000023842, 0.20000000298, 0.699999988079, 0.300000011921, 0.800000011921, 0.800000011921, 0.899999976158, 0.10000000149, 0.899999976158, 0.600000023842, 0.800000011921, 
+
+L3_cHEMM_o_L
+0.810000040531, 6.09999996275, 0.250000034273, 5.95000008792, 0.709999999553, 4.55000007302, 2.31999995738, 6.36000000402, -0.270000039339, 5.04000004515, 0.549999988824, 6.08000008658, 1.16999995962, 6.49000004366, 2.49999995008, 5.89000007123, 0.709999946654, 5.15000005662, 0.670000044554, 6.18000009626, 2.7399999319, 5.1500000678, -0.110000011474, 7.26999997973, 0.590000088364, 6.19000003919, 0.759999970496, 5.20000003651, 1.08999998182, 6.70000004396, 0.720000041574, 5.49000006899, 1.24000000566, 5.64000005782, 0.420000027418, 5.06000004053, 1.03999993637, 5.47000009447, 1.05999996454, 4.07000007063, 1.94999989495, 5.42000007212, -0.200000055134, 4.76000005618, 1.40999998093, 4.70000008643, 1.2699999842, 5.56000006735, 1.49999996051, 4.46000009194, 0.319999896288, 4.96000006884, 0.239999976605, 5.27000003636, 1.66999991119, 4.19000007942, 0.679999976307, 5.5900000824, 0.8400000377, 5.49000003323, 0.759999933243, 4.78000003964, 1.27999989212, 5.70000004023, 0.0199999894202, 5.41000009641, 1.38999994904, 4.17000010118, 2.17000008106, 5.45999995336, 1.76999998048, 5.11000005096, 2.04000003844, 4.39000002354, 3.71999996632, 4.83999996915, 1.0899999781, 4.56000006214, 2.06000001818, 5.18000005528, 2.53000004336, 5.41000000477, 2.87999997854, 4.15000004694, 0.799999980628, 5.05999999806, 1.12000006914, 5.61999999613, 3.66999995068, 4.76999997154, 1.91999998197, 5.6199999924, 2.10000006706, 5.5299999927, 1.57999994501, 5.27999997929, 2.55999999806, 6.04999999776, 1.55999998391, 5.14000003025, 3.08999999374, 4.38000000536, 2.26000003755, 5.01999991938, 2.08999996468, 4.04000003546, 2.9799999994, 4.26999996334, 4.50999993324, 4.84999997467, 1.04999998882, 3.300000038, 2.88999998182, 4.50000001416, 3.08999997735, 4.13000006199, 3.11999997303, 3.09000002578, 1.2599999474, 3.99000001088, 1.6900000377, 4.18000000983, 3.90999998912, 3.35999997571, 1.96999997601, 5.16999997973, 1.93000009179, 4.65999995485, 2.45999997124, 4.03000000089, 3.48999998853, 4.87000004679, 0.750000026822, 4.43000003815, 3.8199999693, 3.05000006631, 3.42000002369, 3.95999991387, 3.56999998793, 4.40000001192, 3.56000003085, 3.06000001594, 5.9099999243, 3.45000002012, 1.59000001684, 3.51000006586, 4.26000003457, 4.49999997616, 4.03000006869, 3.34000004143, 4.28000003144, 2.87000003934, 1.58999996766, 4.16000003904, 1.94000005335, 4.25000000969, 4.72999998376, 3.26999995142, 3.55000000075, 4.77000004157, 2.99000011519, 4.15999995634, 3.4499999769, 3.72999999344, 4.60999999434, 4.71000000104, 1.64000009283, 3.99000001833, 4.3900000146, 3.58999998033, 4.11000002787, 2.94000002131, 4.37000007361, 2.10000008643, 4.07000007212, 1.73000006497, 4.73000002921, 1.70000007153, 3.1300000374, 2.56000009567, 5.38000002697, 2.57000006989, 4.0000000827, 2.08000005081, 4.13000004485, 1.29000004366, 2.39000003919, 2.32000010416, 3.32000003189, 2.7800000307, 3.68000002176, 0.720000013262, 4.71000002488, 3.02000007287, 4.46000006586, 2.38999996096, 4.10999995857, 2.76999999762, 4.9700000453, 2.15000008121, 2.95000003576, 3.63000009328, 4.72000000507, 1.79999997467, 3.38000002772, 3.66999994099, 4.02000002891, 2.7799999465, 4.48000002623, 1.47999999046, 4.54999996722, 2.0899999781, 2.60000007078, 3.34999996647, 4.26999996781, 3.13999991179, 4.30000002161, 1.88999996394, 4.43999994829, 1.30999995336, 2.44000002429, 2.87000000209, 3.36000003606, 3.14999996349, 3.69999998584, 1.98999993488, 4.57999997109, 3.34999989271, 4.06000002712, 3.51999983743, 4.00000000671, 3.38999996915, 5.34000003844, 2.46000004426, 3.15000002906, 3.67999996662, 4.0800000076, 1.90999997124, 4.51999999315, 2.67999998599, 4.97000006616, 2.35000004172, 3.45000007302, 2.12999997705, 5.51999994397, 1.62000004306, 3.81000002339, 2.16000006959, 4.09000003621, 2.2400000228, 4.16000003755, 2.44000000268, 4.3400000228, 1.15000000224, 3.58000001803, 2.77000002295, 3.83000005081, 2.76999998942, 4.80000002384, 0.939999988526, 5.28000005156, 3.04000005484, 4.73000007391, 1.88000002548, 4.53999997735, 2.54000000715, 5.40000001416, 2.87000003785, 3.4200000371, 3.37000002369, 4.21000007257, 1.16000003904, 4.56000002488, 2.62999998301, 5.28000009179, 1.5499999851, 4.66000009194, 0.760000050962, 5.65000002533, 0.920000034124, 4.16000009269, 2.61000004575, 4.63000006646, 1.85999997497, 5.4700000751, 0.690000024289, 5.21000007257, -0.379999933839, 3.45000006184, 1.92000004157, 4.86000008896, 1.9300000374, 5.31000008747, 0.709999973476, 5.74000003099, 2.74000004143, 5.12000009224, 2.27999996811, 4.89000004664, 1.9200000304, 6.06000008523, 1.76000004947, 3.45000008047, 2.43999995276, 5.19000006527, 1.35000006407, 4.9300000523, 2.19999996722, 5.91000009939, 1.16000005469, 5.53000010967, 0.620000037104, 6.3400000973, 0.510000071079, 4.77000011459, 2.35000003576, 5.30000010356, 1.21999996856, 7.00000005588, 1.40999995336, 6.56000004798, 0.799999994785, 4.83000004187, 2.43000004709, 5.58000010669, 2.59000000715, 5.36000004649, 0.379999990463, 6.12000006914, 2.8700000073, 5.35000007823, 2.17999993682, 5.0200000371, 2.45000005364, 7.13000012159, 2.24000008538, 4.87000009, 2.72000000954, 5.17000010639, 1.83000003964, 
+
+L3_cHEMM_A_nn
+0.800000011921, 0.0, 0.300000011921, 0.20000000298, 0.899999976158, 0.300000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.800000011921, 0.899999976158, 0.10000000149, 0.600000023842, 0.40000000596, 0.600000023842, 0.699999988079, 0.20000000298, 0.10000000149, 0.699999988079, 0.899999976158, 0.40000000596, 0.300000011921, 0.899999976158, 0.800000011921, 0.800000011921, 0.800000011921, 0.20000000298, 0.800000011921, 0.600000023842, 0.40000000596, 0.300000011921, 0.40000000596, 0.600000023842, 0.5, 0.300000011921, -0.20000000298, 0.40000000596, 0.0, 0.10000000149, 0.699999988079, 0.600000023842, 0.5, 0.10000000149, 0.699999988079, 0.699999988079, 0.699999988079, 0.800000011921, 0.300000011921, 0.600000023842, 0.5, 0.5, 0.10000000149, 0.600000023842, 0.20000000298, 0.10000000149, 0.300000011921, 0.10000000149, 0.300000011921, 0.20000000298, 0.899999976158, 0.899999976158, 0.800000011921, 0.10000000149, 0.899999976158, 0.899999976158, 0.800000011921, 0.300000011921, 0.600000023842, 0.899999976158, -0.300000011921, 0.10000000149, -0.699999988079, 0.10000000149, 0.0, 0.20000000298, 0.800000011921, 0.20000000298, 0.5, 0.600000023842, 0.899999976158, 0.5, 0.40000000596, 0.300000011921, 0.5, 0.40000000596, 0.300000011921, 0.20000000298, 0.699999988079, 0.800000011921, 0.899999976158, 0.800000011921, 0.899999976158, 0.300000011921, 0.20000000298, 0.699999988079, 0.300000011921, 0.10000000149, 0.699999988079, 0.899999976158, 0.20000000298, 0.40000000596, 0.40000000596, 0.10000000149, -0.10000000149, 0.600000023842, -0.5, 0.20000000298, -0.800000011921, 0.40000000596, 0.0, 0.600000023842, 0.899999976158, 0.10000000149, 0.40000000596, 0.699999988079, 0.40000000596, 0.899999976158, 0.600000023842, 0.5, 0.10000000149, 0.800000011921, 0.699999988079, 0.300000011921, 0.5, 0.800000011921, 0.20000000298, 0.5, 0.300000011921, 0.699999988079, 0.800000011921, 0.20000000298, 0.800000011921, 0.699999988079, 0.5, 0.899999976158, 0.899999976158, 0.20000000298, -0.800000011921, 0.10000000149, -0.699999988079, 0.20000000298, -0.5, 0.600000023842, -0.899999976158, 0.899999976158, 0.0, 0.800000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.20000000298, 0.600000023842, 0.20000000298, 0.600000023842, 0.300000011921, 0.899999976158, 0.5, 0.899999976158, 0.10000000149, 0.10000000149, 0.600000023842, 0.40000000596, 0.40000000596, 0.300000011921, 0.800000011921, 0.699999988079, 0.20000000298, 0.699999988079, 0.600000023842, 0.600000023842, 0.899999976158, -0.10000000149, 0.699999988079, -0.699999988079, 0.600000023842, -0.899999976158, 0.10000000149, -0.40000000596, 0.800000011921, -0.300000011921, 0.20000000298, 0.0, 0.10000000149, 0.40000000596, 0.899999976158, 0.899999976158, 0.600000023842, 0.10000000149, 0.899999976158, 0.800000011921, 0.699999988079, 0.699999988079, 0.10000000149, 0.5, 0.600000023842, 0.699999988079, 0.20000000298, 0.300000011921, 0.800000011921, 0.699999988079, 0.899999976158, 0.300000011921, 0.10000000149, 0.600000023842, 0.600000023842, -0.40000000596, 0.800000011921, -0.300000011921, 0.5, -0.40000000596, 0.699999988079, -0.40000000596, 0.40000000596, -0.600000023842, 0.10000000149, -0.40000000596, 0.300000011921, 0.0, 0.5, 0.899999976158, 0.300000011921, 0.899999976158, 0.300000011921, 0.10000000149, 0.899999976158, 0.10000000149, 0.699999988079, 0.899999976158, 0.600000023842, 0.699999988079, 0.800000011921, 0.300000011921, 0.800000011921, 0.300000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.5, 0.600000023842, -0.699999988079, 0.600000023842, -0.5, 0.300000011921, -0.5, 0.899999976158, -0.600000023842, 0.20000000298, -0.600000023842, 0.899999976158, -0.899999976158, 0.5, -0.899999976158, 0.10000000149, 0.0, 0.600000023842, 0.10000000149, 0.899999976158, 0.600000023842, 0.600000023842, 0.699999988079, 0.699999988079, 0.5, 0.40000000596, 0.800000011921, 0.5, 0.40000000596, 0.20000000298, 0.300000011921, 0.600000023842, 0.699999988079, 0.800000011921, 0.40000000596, 0.20000000298, -0.10000000149, 0.5, -0.10000000149, 0.40000000596, -0.300000011921, 0.5, -0.10000000149, 0.20000000298, -0.600000023842, 0.600000023842, -0.10000000149, 0.300000011921, -0.899999976158, 0.600000023842, -0.10000000149, 0.5, 0.0, 0.899999976158, 0.40000000596, 0.10000000149, 0.800000011921, 0.800000011921, 0.600000023842, 0.10000000149, 0.600000023842, 0.10000000149, 0.300000011921, 0.600000023842, 0.800000011921, 0.800000011921, 0.40000000596, 0.899999976158, 0.699999988079, 0.699999988079, -0.899999976158, 0.600000023842, -0.20000000298, 0.20000000298, -0.699999988079, 0.800000011921, -0.699999988079, 0.300000011921, -0.899999976158, 0.899999976158, -0.800000011921, 0.300000011921, -0.10000000149, 0.899999976158, -0.600000023842, 0.899999976158, -0.40000000596, 0.10000000149, 0.0, 0.40000000596, 0.40000000596, 0.5, 0.20000000298, 0.10000000149, 0.800000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.5, 0.800000011921, 0.40000000596, 0.300000011921, 0.800000011921, 0.40000000596, -0.300000011921, 0.10000000149, -0.300000011921, 0.800000011921, -0.899999976158, 0.300000011921, -0.5, 0.5, -0.899999976158, 0.699999988079, -0.699999988079, 0.899999976158, -0.10000000149, 0.600000023842, -0.699999988079, 0.10000000149, -0.800000011921, 0.40000000596, -0.40000000596, 0.5, 0.0, 0.600000023842, 0.300000011921, 0.899999976158, 0.699999988079, 0.600000023842, 0.300000011921, 0.40000000596, 0.699999988079, 0.10000000149, 0.10000000149, 0.5, 0.10000000149, 0.899999976158, -0.800000011921, 0.10000000149, -0.300000011921, 0.800000011921, -0.899999976158, 0.800000011921, -0.20000000298, 0.10000000149, -0.10000000149, 0.10000000149, -0.5, 0.699999988079, -0.899999976158, 0.699999988079, -0.5, 0.800000011921, -0.600000023842, 0.5, -0.20000000298, 0.600000023842, -0.300000011921, 0.300000011921, 0.0, 0.300000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.600000023842, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 0.300000011921, 0.800000011921, -0.800000011921, 0.20000000298, -0.899999976158, 0.300000011921, -0.20000000298, 0.5, -0.300000011921, 0.600000023842, -0.40000000596, 0.600000023842, -0.699999988079, 0.600000023842, -0.699999988079, 0.40000000596, -0.800000011921, 0.10000000149, -0.600000023842, 0.10000000149, -0.800000011921, 0.899999976158, -0.699999988079, 0.300000011921, -0.600000023842, 0.699999988079, 0.0, 0.800000011921, 0.899999976158, 0.10000000149, 0.899999976158, 0.899999976158, 0.899999976158, 0.300000011921, 0.20000000298, 0.20000000298, -0.800000011921, 0.899999976158, -0.800000011921, 0.699999988079, -0.300000011921, 0.699999988079, -0.800000011921, 0.40000000596, -0.300000011921, 0.20000000298, -0.300000011921, 0.800000011921, -0.300000011921, 0.5, -0.40000000596, 0.10000000149, -0.300000011921, 0.699999988079, -0.899999976158, 0.600000023842, -0.300000011921, 0.20000000298, -0.20000000298, 0.800000011921, -0.899999976158, 0.20000000298, 0.0, 0.800000011921, 0.899999976158, 0.600000023842, 0.699999988079, 0.899999976158, 0.10000000149, 0.600000023842, -0.40000000596, 0.10000000149, -0.899999976158, 0.10000000149, -0.699999988079, 0.20000000298, -0.800000011921, 0.800000011921, -0.699999988079, 0.800000011921, -0.699999988079, 0.800000011921, -0.300000011921, 0.20000000298, -0.300000011921, 0.600000023842, -0.800000011921, 0.10000000149, -0.5, 0.40000000596, -0.699999988079, 0.600000023842, -0.10000000149, 0.10000000149, -0.899999976158, 0.800000011921, -0.899999976158, 0.20000000298, 0.0, 0.899999976158, 0.899999976158, 0.40000000596, 0.10000000149, 0.300000011921, -0.40000000596, 0.899999976158, -0.800000011921, 0.899999976158, -0.20000000298, 0.699999988079, -0.5, 0.20000000298, -0.699999988079, 0.899999976158, -0.300000011921, 0.899999976158, -0.899999976158, 0.600000023842, -0.699999988079, 0.800000011921, -0.40000000596, 0.800000011921, -0.40000000596, 0.10000000149, -0.10000000149, 0.300000011921, -0.800000011921, 0.899999976158, -0.899999976158, 0.600000023842, -0.699999988079, 0.899999976158, -0.899999976158, 0.20000000298, 0.0, 0.699999988079, 0.5, 0.600000023842, -0.5, 0.300000011921, -0.600000023842, 0.40000000596, -0.40000000596, 0.899999976158, -0.899999976158, 0.600000023842, -0.600000023842, 0.10000000149, -0.600000023842, 0.10000000149, -0.5, 0.800000011921, -0.40000000596, 0.899999976158, -0.699999988079, 0.300000011921, -0.800000011921, 0.5, -0.10000000149, 0.899999976158, -0.300000011921, 0.300000011921, -0.20000000298, 0.899999976158, -0.10000000149, 0.40000000596, -0.10000000149, 0.699999988079, -0.5, 0.10000000149, 0.0, 
+
+L3_cHEMM_o_R
+8.16000009716, 2.23000002474, 6.58000012308, -0.0399999415874, 5.98000001654, 1.53000003666, 6.95000007898, 2.47000003114, 4.79000011072, 2.96000006661, 6.45000009164, 3.30000010133, 5.32000002295, 4.01000013515, 4.62000009969, 5.73000003964, 6.0500001058, 3.81000004202, 4.17000000879, 5.63000000983, 4.00000003129, 6.59000005409, 2.91000007853, 6.57000005648, 1.92000000954, 6.70000012368, 2.22000002667, 6.7800001432, -0.579999906272, 7.20000009686, 1.2700000371, 8.41000002339, 0.819999984205, 7.68000009403, 8.58000017375, 1.49000003099, 7.55000014305, -0.0799999934435, 7.45000011623, 1.11999999538, 8.17000002444, 2.1499999769, 5.61000014484, 2.93999996543, 6.87000005648, 2.45000000969, 6.26000002638, 3.45000011772, 4.80000006855, 4.75000001788, 5.86000006586, 2.73000001058, 3.80000003353, 4.08000007018, 3.01000006065, 5.76000006288, 2.82000009298, 6.84000003397, 1.74000004068, 7.62000013843, 3.4499999173, 7.89000012189, -0.429999930114, 8.39000011444, 1.83999998257, 10.0000000082, 0.629999977797, 7.90000017136, 9.29000016063, 1.63999997288, 8.1000000596, -0.149999992549, 7.94999998137, 0.55000006482, 7.74000003025, 0.960000045747, 4.37000020102, 1.67000006989, 5.49000007644, 2.12000006542, 6.350000038, 2.62000017866, 4.52000014365, 5.37000001773, 5.87000014737, 2.69999999925, 4.20000010654, 5.01999998495, 3.91000006959, 5.84000003323, 4.16000012845, 6.13000001281, 2.96000005692, 7.04000013307, 2.38000004709, 6.92000014737, 1.09000012338, 8.02000008181, 2.31999996707, 10.109999963, 1.63999993414, 8.19000004441, 7.48000019833, 1.79000004143, 8.25000014901, 0.720000013262, 7.65000011399, 1.88999999598, 7.23000006422, 2.01000001818, 4.83000016704, 2.42000005648, 6.10000002906, 2.42000004753, 5.7900000079, 4.3600001359, 3.87000008553, 5.84000008762, 4.56000014707, 3.8700000602, 3.9000000827, 5.77000009596, 3.21000004426, 6.54000011891, 1.96000003457, 6.91000007555, 2.17999994054, 8.07000016823, 2.40999993548, 7.91000016719, -0.149999965727, 9.14000010923, 0.300000002235, 9.97000004753, 1.26999994099, 8.310000083, 9.87000009373, 2.15999999806, 8.64000004888, 0.390000077188, 7.05000005364, 0.760000094175, 8.46000005767, 3.17000008255, 6.11000015453, 1.96000004947, 7.84000000268, 4.75999996454, 7.789999955, 3.95000014752, 5.51000006139, 5.71000002712, 5.5700000155, 3.53000008807, 3.33999999076, 5.67999997258, 3.40000003055, 7.72999998376, 3.52000000283, 7.68000002697, 1.0199999395, 7.70000011176, 2.84999993667, 8.4300001052, -0.349999934435, 10.5200000215, 1.41999987617, 11.2999999575, 1.14999987483, 9.57000004977, 9.72000012353, 0.369999974519, 7.84000012338, -1.35000000522, 6.25000007823, 0.250000026077, 8.04000005782, 1.86000006661, 7.09000005856, 0.940000006407, 7.89000002205, 2.64000003844, 6.99000001162, 3.27000014439, 6.94000007123, 4.23000005901, 6.89000008091, 3.03000009552, 5.1800000754, 3.77000015035, 4.64000003621, 5.44000014573, 4.55000007302, 5.45000011995, 2.59000002578, 6.28000019833, 4.05000001565, 7.45000009984, 0.0600001947582, 7.19000013605, 2.54000002056, 9.90999999061, 1.00000003204, 8.40000014827, 8.81000017762, 0.730000108182, 8.41000012323, -0.129999913722, 8.98000008211, 0.27000011906, 8.70000007376, 1.51000004649, 7.49000013009, 1.72000008851, 8.33000003666, 3.37000008032, 8.16000003979, 2.92000019506, 5.74000015467, 4.11000013441, 5.53000020355, 3.21000007629, 5.16000003979, 4.99000008687, 2.94000006378, 6.01000007182, 3.25000009015, 6.24000011295, 3.33000000089, 6.48000020429, 3.34000000566, 7.67000015631, 1.53000005081, 8.29000011221, 1.8899999997, 9.98000003815, 1.58999992222, 8.5000001438, 10.5100000748, 2.13999994457, 9.60000006482, 0.729999978542, 7.47000002518, 2.66999993876, 8.36000001818, 3.90999990866, 6.85000009909, 3.46999990448, 7.25000002682, 5.46999987468, 7.6399998939, 5.21000004575, 6.23000007391, 7.53999997139, 6.3200001511, 4.55999992803, 4.39000006676, 7.46999989256, 2.58000008881, 7.10999994069, 3.62000004008, 7.26999997303, 1.200000076, 7.97000000358, 1.70000004545, 8.6700000222, -0.429999863803, 9.22000002369, 0.600000070035, 11.219999979, -0.100000012666, 10.1300000106, 8.0700001429, 0.409999990612, 7.52000016376, 0.0400000607967, 7.03000007167, 0.0600000829995, 6.80000014752, 2.06000001147, 6.04000012264, 2.47999995694, 6.68000003517, 3.46999994919, 7.48000005007, 2.62000011832, 5.43000007987, 4.92000001997, 5.26000013441, 3.01000005245, 4.36999998271, 5.58000000238, 2.62000009894, 4.6900000824, 3.57000008181, 5.88000007242, 2.71000000402, 6.0100001806, 3.50000002608, 6.76000016943, 2.34000002876, 7.15000008866, 2.73999998331, 9.94000005931, 1.71999996483, 8.39000013158, 8.6400001055, 1.10000004396, 8.45000004768, 0.0400000153482, 7.40000005141, 0.110000047237, 8.29000004441, 2.4900000459, 6.6800001432, 1.65000005588, 6.49999999702, 2.57000003934, 7.80999984086, 3.02000011161, 5.89000005111, 5.4700000535, 5.27000008926, 3.47000001028, 4.29999998882, 5.48000001356, 2.79999998286, 5.88000001132, 3.99000002727, 6.13000005081, 1.7199999246, 7.4400000377, 2.85999993995, 7.98000011414, 1.2900000146, 9.40000000969, 1.50999996752, 10.1799999659, 1.0599999176, 8.7100000748, 
+
+L3_zHEMM_A_mm
+0.2, 0.0, 0.3, 0.5, 0.2, 0.9, 0.8, 0.2, 0.9, 0.1, 0.8, 0.3, 0.1, 0.3, 0.8, 0.9, 0.8, 0.4, 0.5, 0.1, 0.3, -0.5, 0.3, 0.0, 0.3, 0.2, 0.8, 0.9, 0.2, 0.2, 0.8, 0.9, 0.5, 0.4, 0.6, 0.9, 0.8, 0.6, 0.5, 0.9, 0.2, -0.9, 0.3, -0.2, 0.7, 0.0, 0.5, 0.8, 0.9, 0.3, 0.2, 0.1, 0.8, 0.7, 0.8, 0.9, 0.9, 0.8, 0.1, 0.6, 0.8, -0.2, 0.8, -0.9, 0.5, -0.8, 0.2, 0.0, 0.7, 0.7, 0.8, 0.6, 0.5, 0.2, 0.7, 0.6, 0.1, 0.5, 0.1, 0.2, 0.9, -0.1, 0.2, -0.2, 0.9, -0.3, 0.7, -0.7, 0.4, 0.0, 0.4, 0.7, 0.7, 0.5, 0.2, 0.4, 0.8, 0.6, 0.7, 0.4, 0.8, -0.3, 0.8, -0.9, 0.2, -0.1, 0.8, -0.6, 0.4, -0.7, 0.3, 0.0, 0.1, 0.4, 0.7, 0.2, 0.6, 0.3, 0.8, 0.8, 0.1, -0.3, 0.5, -0.4, 0.8, -0.7, 0.5, -0.2, 0.7, -0.5, 0.1, -0.4, 0.9, 0.0, 0.5, 0.2, 0.7, 0.2, 0.7, 0.1, 0.8, -0.9, 0.6, -0.9, 0.8, -0.9, 0.7, -0.6, 0.2, -0.4, 0.7, -0.2, 0.5, -0.2, 0.6, 0.0, 0.9, 0.8, 0.1, 0.6, 0.8, -0.4, 0.8, -0.6, 0.9, -0.8, 0.1, -0.5, 0.8, -0.6, 0.6, -0.3, 0.7, -0.2, 0.9, -0.8, 0.8, 0.0, 0.7, 0.4, 0.5, -0.1, 0.5, -0.9, 0.1, -0.6, 0.1, -0.2, 0.7, -0.4, 0.8, -0.8, 0.7, -0.1, 0.1, -0.6, 0.7, -0.4, 0.2, 0.0, 
+
+L3_zHEMM_B_mn
+0.8, 0.9, 0.2, 0.7, 0.1, 0.8, 0.4, 0.4, 0.4, 0.7, 0.9, 0.8, 0.5, 0.2, 0.1, 0.7, 0.8, 0.5, 0.9, 0.7, 0.7, 0.5, 0.8, 0.4, 0.3, 0.3, 0.5, 0.3, 0.4, 0.9, 0.8, 0.8, 0.8, 0.2, 0.1, 0.6, 0.6, 0.3, 0.2, 0.3, 0.3, 0.4, 0.1, 0.4, 0.1, 0.5, 0.2, 0.9, 0.5, 0.4, 0.7, 0.2, 0.9, 0.4, 0.7, 0.8, 0.6, 0.8, 0.6, 0.3, 0.4, 0.5, 0.4, 0.2, 0.1, 0.8, 0.5, 0.3, 0.1, 0.2, 0.2, 0.1, 0.9, 0.6, 0.9, 0.4, 0.6, 0.5, 0.3, 0.4, 0.2, 0.2, 0.6, 0.7, 0.5, 0.6, 0.9, 0.6, 0.9, 0.8, 0.8, 0.9, 0.3, 0.6, 0.3, 0.8, 0.8, 0.8, 0.9, 0.7, 0.8, 0.5, 0.2, 0.5, 0.2, 0.3, 0.6, 0.7, 0.1, 0.3, 0.9, 0.8, 0.4, 0.4, 0.2, 0.1, 0.7, 0.5, 0.5, 0.6, 0.9, 0.4, 0.2, 0.4, 0.1, 0.6, 0.9, 0.9, 0.2, 0.9, 0.1, 0.8, 0.1, 0.4, 0.2, 0.2, 0.2, 0.7, 0.7, 0.2, 0.5, 0.2, 0.2, 0.2, 0.3, 0.7, 0.2, 0.6, 0.2, 0.7, 0.1, 0.4, 0.9, 0.9, 0.7, 0.3, 0.6, 0.6, 0.7, 0.9, 0.3, 0.6, 0.8, 0.3, 0.2, 0.6, 0.5, 0.8, 0.9, 0.7, 0.6, 0.9, 0.5, 0.4, 0.5, 0.5, 0.2, 0.4, 0.5, 0.7, 0.3, 0.7, 0.8, 0.1, 0.8, 0.4, 0.6, 0.6, 0.3, 0.4, 0.5, 0.8, 0.1, 0.4, 0.8, 0.8, 0.2, 0.9, 0.7, 0.7, 0.8, 0.9, 0.8, 0.6, 0.4, 0.3, 0.3, 0.9, 0.3, 0.9, 0.2, 0.7, 0.8, 0.9, 0.1, 0.5, 0.6, 0.6, 0.8, 0.4, 0.6, 0.9, 0.2, 0.2, 0.8, 0.8, 0.8, 0.9, 0.3, 0.5, 0.3, 0.5, 0.7, 0.3, 0.6, 0.9, 0.6, 0.5, 0.3, 0.8, 0.9, 0.1, 0.4, 0.1, 0.8, 0.1, 0.3, 0.9, 0.9, 0.4, 0.5, 0.7, 0.6, 0.7, 0.4, 0.2, 0.3, 0.7, 0.9, 0.6, 0.2, 0.8, 0.6, 0.3, 0.9, 0.1, 0.8, 0.9, 0.8, 0.6, 0.8, 0.7, 0.5, 0.7, 0.4, 0.5, 0.5, 0.6, 0.3, 0.6, 0.2, 0.8, 0.1, 0.5, 0.6, 0.3, 0.2, 0.9, 0.4, 0.2, 0.1, 0.9, 0.2, 0.5, 0.2, 0.8, 0.2, 0.2, 0.9, 0.7, 0.4, 0.7, 0.4, 0.2, 0.6, 0.1, 0.9, 0.3, 0.3, 0.5, 0.4, 0.2, 0.7, 0.2, 0.5, 0.8, 0.5, 0.2, 0.5, 0.9, 0.4, 0.6, 0.3, 0.8, 0.4, 0.6, 0.4, 0.6, 0.6, 0.3, 0.1, 0.9, 0.9, 0.3, 0.6, 0.1, 0.9, 0.8, 0.1, 0.8, 
+
+L3_zHEMM_C_mn
+0.8, 0.2, 0.7, 0.7, 0.5, 0.2, 0.2, 0.7, 0.3, 0.8, 0.1, 0.2, 0.9, 0.4, 0.8, 0.1, 0.8, 0.9, 0.8, 0.7, 0.7, 0.6, 0.3, 0.6, 0.1, 0.8, 0.7, 0.1, 0.5, 0.5, 0.3, 0.2, 0.5, 0.5, 0.2, 0.3, 0.7, 0.6, 0.3, 0.1, 0.3, 0.4, 0.2, 0.3, 0.2, 0.3, 0.4, 0.3, 0.3, 0.3, 0.9, 0.2, 0.6, 0.8, 0.5, 0.1, 0.4, 0.9, 0.2, 0.8, 0.2, 0.7, 0.2, 0.2, 0.3, 0.8, 0.6, 0.1, 0.8, 0.6, 0.7, 0.7, 0.9, 0.2, 0.6, 0.5, 0.7, 0.3, 0.1, 0.6, 0.6, 0.1, 0.6, 0.5, 0.1, 0.6, 0.2, 0.9, 0.5, 0.6, 0.5, 0.5, 0.1, 0.4, 0.6, 0.4, 0.9, 0.5, 0.6, 0.9, 0.9, 0.7, 0.5, 0.6, 0.6, 0.3, 0.8, 0.6, 0.9, 0.9, 0.5, 0.7, 0.4, 0.4, 0.8, 0.7, 0.9, 0.6, 0.8, 0.8, 0.7, 0.4, 0.6, 0.9, 0.2, 0.6, 0.1, 0.2, 0.9, 0.3, 0.4, 0.6, 0.2, 0.8, 0.2, 0.8, 0.8, 0.6, 0.7, 0.5, 0.3, 0.3, 0.2, 0.7, 0.8, 0.2, 0.1, 0.1, 0.1, 0.7, 0.9, 0.5, 0.7, 0.9, 0.3, 0.1, 0.1, 0.4, 0.5, 0.2, 0.4, 0.4, 0.7, 0.8, 0.5, 0.3, 0.4, 0.8, 0.7, 0.2, 0.4, 0.5, 0.4, 0.6, 0.1, 0.2, 0.7, 0.5, 0.9, 0.5, 0.4, 0.6, 0.6, 0.8, 0.8, 0.8, 0.7, 0.2, 0.1, 0.7, 0.5, 0.9, 0.2, 0.8, 0.4, 0.9, 0.7, 0.2, 0.1, 0.7, 0.6, 0.7, 0.2, 0.3, 0.7, 0.2, 0.6, 0.8, 0.1, 0.7, 0.2, 0.6, 0.3, 0.5, 0.9, 0.9, 0.4, 0.6, 0.1, 0.8, 0.1, 0.2, 0.3, 0.1, 0.7, 0.9, 0.5, 0.7, 0.2, 0.3, 0.1, 0.1, 0.7, 0.9, 0.7, 0.5, 0.6, 0.5, 0.1, 0.4, 0.1, 0.3, 0.9, 0.3, 0.1, 0.9, 0.4, 0.5, 0.6, 0.9, 0.6, 0.6, 0.5, 0.6, 0.7, 0.4, 0.8, 0.9, 0.6, 0.4, 0.1, 0.2, 0.9, 0.1, 0.7, 0.8, 0.8, 0.9, 0.7, 0.6, 0.8, 0.1, 0.7, 0.9, 0.7, 0.1, 0.1, 0.9, 0.7, 0.6, 0.7, 0.7, 0.7, 0.8, 0.6, 0.9, 0.9, 0.6, 0.7, 0.9, 0.9, 0.1, 0.2, 0.8, 0.7, 0.5, 0.5, 0.1, 0.7, 0.2, 0.6, 0.1, 0.4, 0.1, 0.2, 0.5, 0.4, 0.1, 0.7, 0.3, 0.7, 0.6, 0.7, 0.3, 0.5, 0.7, 0.8, 0.7, 0.3, 0.2, 0.4, 0.9, 0.4, 0.6, 0.1, 0.4, 0.9, 0.7, 0.2, 0.5, 0.6, 0.6, 0.4, 0.8, 0.5, 0.2, 0.6, 0.5, 0.5, 0.3, 
+
+L3_zHEMM_o_L
+0.92, 4.79, 2.32, 4.34, 1.42, 4.38, 0.9, 4.48, 0.08, 6.43, 0.48, 4.32, 1.5, 4.35, 1.04, 5.28, 2.17, 5.66, 1.48, 5.6, 0.95, 6.44, -0.59, 5.93, 0.99, 5.61, 1.94, 5.02, 0.57, 6.32, 0.88, 5.95, 2.02, 5.58, -0.11, 5.33, 1.32, 4.84, 0.8, 5.06, 0.77, 4.25, -0.91, 6.55, 0.28, 4.44, 0.72, 4.63, 0.45, 6.06, 1.06, 4.84, 0.73, 5.27, 0.36, 5.46, -0.55, 5.47, -0.32, 6.05, 0.23, 6.31, 0.19, 5.89, 0.4, 6.76, 1.05, 4.58, 1.12, 4.73, 2.17, 4.35, 2.3, 4.62, 1.73, 3.85, 0.39, 6.09, 0.92, 4.1, 1.04, 4.11, 1.29, 5.67, 1.42, 4.7, 1.36, 4.42, 1.97, 5.42, 0.7, 5.47, 0.37, 4.5, 2.04, 5.38, 1.97, 5.64, 2.07, 5.92, 2.78, 4.53, 1.38, 4.88, 2.64, 3.2, 2.77, 3.42, 2.83, 2.76, 1.38, 4.68, 2.01, 3.82, 2.63, 4.18, 2.88, 3.67, 3.32, 4.0, 3.36, 2.24, 3.79, 4.52, 2.46, 3.91, 1.95, 3.18, 3.32, 4.08, 2.36, 4.3, 2.91, 5.6, 3.01, 4.07, 2.44, 4.97, 1.82, 4.01, 2.56, 4.04, 2.03, 3.66, 2.56, 4.81, 1.66, 3.45, 1.8, 4.39, 2.77, 4.77, 3.29, 4.86, 2.86, 2.81, 2.43, 4.84, 2.87, 4.51, 2.18, 3.9, 3.32, 5.33, 2.95, 5.18, 3.04, 6.08, 3.23, 3.7, 3.72, 4.43, 2.69, 2.15, 2.69, 2.33, 3.18, 2.53, 3.39, 4.27, 3.65, 3.16, 3.1, 3.87, 3.35, 3.84, 4.04, 1.72, 3.53, 2.08, 4.04, 3.59, 3.61, 3.76, 3.25, 2.77, 4.64, 2.96, 3.46, 4.27, 4.25, 4.71, 3.2, 1.8, 3.83, 2.47, 3.48, 2.25, 3.79, 2.28, 3.32, 1.95, 4.03, 3.55, 3.79, 2.81, 3.27, 2.95, 3.72, 3.0, 4.4, 1.96, 4.01, 1.09, 5.45, 3.08, 4.9, 3.5, 3.53, 2.26, 4.6, 2.38, 4.89, 2.96, 5.53, 3.03, 4.73, 1.63, 4.01, 3.69, 3.3, 1.7, 5.28, 2.39, 3.45, 2.28, 4.51, 3.23, 4.61, 2.82, 4.08, 2.31, 4.57, 2.7, 5.59, 1.05, 5.1, 1.16, 6.0, 1.86, 4.83, 2.3, 5.11, 1.27, 5.25, 3.91, 5.86, 3.7, 6.43, 3.12, 5.55, 0.27, 6.03, 4.31, 4.94, 0.96, 4.94, 2.34, 5.2, 1.54, 6.14, 4.05, 5.51, 2.78, 5.3, 3.25, 6.18, 2.82, 6.63, 2.24, 6.61, 1.25, 7.26, 2.73, 7.51, 3.59, 5.09, 1.49, 6.86, 1.9, 7.33, 2.37, 7.56, 3.03, 6.57, 1.05, 4.98, 1.72, 3.88, 0.26, 4.15, 1.0, 3.49, 0.46, 5.02, 2.34, 4.22, 1.84, 4.39, 0.52, 4.63, 1.11, 5.0, 0.72, 4.34, 0.16, 6.25, 1.0, 5.39, 1.77, 4.48, 0.65, 5.1, 1.17, 5.22, 0.45, 5.97, 1.41, 5.36, -0.59, 
+
+L3_zHEMM_A_nn
+0.7, 0.0, 0.2, 0.2, 0.1, 0.1, 0.7, 0.4, 0.1, 0.6, 0.8, 0.2, 0.8, 0.5, 0.1, 0.2, 0.2, 0.7, 0.7, 0.3, 0.9, 0.9, 0.7, 0.7, 0.4, 0.7, 0.2, 0.7, 0.3, 0.2, 0.6, 0.5, 0.5, 0.3, 0.2, -0.2, 0.2, 0.0, 0.1, 0.8, 0.4, 0.9, 0.6, 0.1, 0.9, 0.3, 0.7, 0.7, 0.1, 0.4, 0.4, 0.7, 0.5, 0.8, 0.8, 0.7, 0.9, 0.9, 0.9, 0.8, 0.1, 0.3, 0.7, 0.8, 0.1, 0.3, 0.1, 0.1, 0.1, -0.1, 0.1, -0.8, 0.7, 0.0, 0.1, 0.9, 0.7, 0.3, 0.6, 0.5, 0.5, 0.5, 0.5, 0.9, 0.7, 0.3, 0.3, 0.8, 0.3, 0.4, 0.7, 0.9, 0.4, 0.2, 0.5, 0.9, 0.8, 0.8, 0.4, 0.5, 0.5, 0.5, 0.7, -0.4, 0.4, -0.9, 0.1, -0.9, 0.6, 0.0, 0.3, 0.3, 0.3, 0.8, 0.2, 0.5, 0.5, 0.1, 0.2, 0.8, 0.4, 0.3, 0.8, 0.8, 0.8, 0.5, 0.9, 0.2, 0.3, 0.1, 0.9, 0.1, 0.1, 0.4, 0.7, 0.9, 0.1, -0.6, 0.6, -0.1, 0.7, -0.3, 0.3, -0.3, 0.4, 0.0, 0.4, 0.9, 0.5, 0.2, 0.1, 0.6, 0.1, 0.1, 0.4, 0.1, 0.6, 0.5, 0.4, 0.3, 0.3, 0.4, 0.5, 0.9, 0.2, 0.3, 0.7, 0.9, 0.3, 0.7, 0.8, -0.2, 0.9, -0.3, 0.6, -0.5, 0.3, -0.8, 0.4, -0.9, 0.7, 0.0, 0.3, 0.8, 0.5, 0.5, 0.2, 0.8, 0.2, 0.2, 0.2, 0.5, 0.4, 0.7, 0.1, 0.1, 0.6, 0.9, 0.7, 0.2, 0.1, 0.6, 0.7, 0.6, 0.8, -0.5, 0.7, -0.7, 0.5, -0.5, 0.2, -0.5, 0.5, -0.2, 0.3, -0.8, 0.1, 0.0, 0.4, 0.8, 0.2, 0.9, 0.4, 0.8, 0.8, 0.7, 0.9, 0.3, 0.2, 0.9, 0.8, 0.5, 0.8, 0.7, 0.1, 0.8, 0.2, 0.1, 0.1, -0.2, 0.1, -0.4, 0.5, -0.9, 0.5, -0.1, 0.1, -0.6, 0.5, -0.5, 0.4, -0.8, 0.5, 0.0, 0.2, 0.8, 0.2, 0.6, 0.6, 0.1, 0.8, 0.6, 0.4, 0.1, 0.1, 0.9, 0.4, 0.5, 0.6, 0.2, 0.2, 0.8, 0.2, -0.7, 0.4, -0.7, 0.7, -0.3, 0.2, -0.8, 0.1, -0.1, 0.2, -0.8, 0.2, -0.9, 0.2, -0.8, 0.4, 0.0, 0.6, 0.1, 0.9, 0.2, 0.9, 0.9, 0.9, 0.6, 0.7, 0.2, 0.8, 0.4, 0.5, 0.9, 0.2, 0.3, 0.7, -0.3, 0.5, -0.8, 0.3, -0.8, 0.4, -0.3, 0.4, -0.1, 0.2, -0.2, 0.4, -0.8, 0.2, -0.6, 0.6, -0.1, 0.9, 0.0, 0.5, 0.8, 0.5, 0.2, 0.1, 0.2, 0.2, 0.5, 0.5, 0.1, 0.9, 0.2, 0.5, 0.7, 0.9, -0.9, 0.8, -0.7, 0.3, -0.4, 0.8, -0.8, 0.6, -0.5, 0.2, -0.5, 0.8, -0.7, 0.6, -0.1, 0.9, -0.2, 0.5, -0.8, 0.8, 0.0, 0.6, 0.7, 0.3, 0.3, 0.4, 0.8, 0.2, 0.1, 0.9, 0.6, 0.4, 0.1, 0.7, -0.7, 0.9, -0.9, 0.7, -0.9, 0.8, -0.5, 0.4, -0.3, 0.4, -0.7, 0.9, -0.3, 0.8, -0.6, 0.9, -0.9, 0.5, -0.2, 0.6, -0.7, 0.5, 0.0, 0.4, 0.7, 0.9, 0.8, 0.5, 0.2, 0.3, 0.5, 0.5, 0.8, 0.4, -0.7, 0.9, -0.8, 0.4, -0.2, 0.9, -0.2, 0.3, -0.4, 0.1, -0.1, 0.2, -0.9, 0.4, -0.1, 0.9, -0.6, 0.1, -0.2, 0.3, -0.3, 0.4, -0.7, 0.7, 0.0, 0.6, 0.2, 0.7, 0.2, 0.3, 0.9, 0.3, 0.3, 0.2, -0.7, 0.1, -0.3, 0.5, -0.9, 0.3, -0.1, 0.5, -0.9, 0.6, -0.9, 0.8, -0.5, 0.1, -0.9, 0.7, -0.2, 0.2, -0.5, 0.4, -0.8, 0.9, -0.8, 0.6, -0.2, 0.8, 0.0, 0.7, 0.2, 0.5, 0.1, 0.6, 0.5, 0.3, -0.2, 0.7, -0.8, 0.8, -0.8, 0.9, -0.1, 0.2, -0.3, 0.7, -0.2, 0.8, -0.7, 0.4, -0.5, 0.8, -0.4, 0.5, -0.1, 0.2, -0.1, 0.5, -0.2, 0.7, -0.2, 0.7, -0.2, 0.3, 0.0, 0.1, 0.6, 0.2, 0.2, 0.6, -0.5, 0.1, -0.3, 0.4, -0.5, 0.1, -0.4, 0.7, -0.9, 0.1, -0.6, 0.1, -0.8, 0.6, -0.2, 0.5, -0.9, 0.9, -0.2, 0.9, -0.6, 0.3, -0.5, 0.3, -0.9, 0.5, -0.1, 0.1, -0.6, 0.8, 0.0, 0.2, 0.3, 0.5, -0.3, 0.1, -0.1, 0.5, -0.5, 0.7, -0.9, 0.3, -0.7, 0.7, -0.6, 0.2, -0.1, 0.2, -0.8, 0.2, -0.3, 0.5, -0.7, 0.4, -0.1, 0.5, -0.8, 0.3, -0.3, 0.6, -0.5, 0.2, -0.2, 0.2, -0.3, 0.9, 0.0, 
+
+L3_zHEMM_o_R
+9.61, 0.42, 9.77, 0.45, 8.71, 0.16, 5.97, 1.69, 6.09, 1.54, 5.06, 2.21, 6.62, 3.08, 4.24, 1.9, 4.02, 5.47, 4.33, 5.05, 4.07, 7.78, 2.7, 8.21, 2.07, 7.05, 1.13, 8.12, 2.74, 6.56, 0.12, 8.67, 0.44, 8.15, 7.24, 1.47, 8.09, 0.51, 7.34, 0.47, 6.35, 2.35, 5.33, 1.72, 5.35, 1.54, 5.44, 1.39, 3.01, 1.79, 4.29, 3.98, 3.55, 4.61, 3.53, 6.17, 3.26, 7.36, 1.79, 5.82, -0.16, 7.54, 2.24, 5.91, -0.15, 7.55, 0.01, 6.3, 10.06, 0.51, 10.44, -0.64, 10.98, -0.37, 8.23, 2.69, 8.15, 1.09, 6.84, 2.76, 8.62, 1.91, 6.61, 2.95, 6.12, 5.37, 5.56, 5.14, 6.21, 7.02, 5.29, 8.04, 3.41, 5.84, 1.87, 9.27, 3.99, 6.7, 1.15, 9.32, 0.99, 9.19, 6.98, 1.35, 8.25, 1.06, 8.07, 2.35, 5.3, 4.04, 5.31, 2.47, 4.4, 3.91, 5.91, 3.32, 4.03, 3.77, 4.06, 6.25, 3.18, 5.02, 3.47, 7.36, 2.79, 7.68, 1.36, 6.06, 0.17, 8.47, 1.77, 7.13, -0.96, 8.19, -1.28, 7.51, 8.78, 1.5, 8.53, 1.28, 8.43, 1.7, 7.24, 3.25, 7.07, 1.12, 6.4, 1.52, 6.54, 2.73, 4.75, 2.03, 5.11, 4.8, 4.26, 4.27, 3.96, 6.69, 4.07, 6.99, 2.23, 6.14, 1.22, 8.56, 2.94, 6.45, -0.58, 7.97, 0.49, 7.0, 8.9, 1.58, 8.78, 0.96, 8.72, 1.38, 7.41, 3.55, 7.5, 1.8, 6.34, 3.11, 6.73, 3.3, 5.26, 4.09, 4.85, 6.07, 4.56, 6.28, 4.93, 8.34, 4.35, 8.45, 3.28, 7.15, 1.29, 8.53, 2.73, 7.54, -0.11, 9.51, -0.6, 7.75, 9.49, 1.1, 9.91, 1.44, 8.48, 1.73, 6.62, 2.83, 6.19, 2.51, 6.24, 3.21, 6.17, 2.83, 3.5, 4.02, 3.64, 5.32, 3.25, 5.18, 4.38, 8.29, 2.73, 9.15, 1.41, 7.38, -0.11, 9.19, 1.67, 8.35, -0.56, 8.99, -0.79, 8.09, 8.68, 0.41, 8.73, -0.25, 9.99, 0.04, 7.99, 3.16, 7.16, -0.18, 7.55, 2.59, 7.75, 3.0, 5.1, 2.99, 5.57, 5.47, 5.19, 5.53, 5.09, 6.88, 5.31, 6.91, 4.14, 4.71, 2.02, 8.6, 4.7, 6.54, 0.81, 8.86, 1.55, 7.56, 7.01, 2.47, 7.51, 1.56, 7.59, 2.58, 4.65, 4.23, 5.19, 2.4, 4.82, 3.44, 5.1, 4.85, 3.31, 3.23, 2.29, 5.93, 2.57, 4.71, 1.86, 6.72, 2.27, 6.99, 1.19, 5.34, -0.65, 6.24, 1.43, 6.32, -1.36, 6.74, -1.85, 6.5, 8.9, 0.73, 8.51, 0.41, 8.16, 0.48, 7.46, 2.93, 6.72, 1.93, 7.17, 2.5, 7.51, 2.26, 4.25, 3.39, 4.12, 5.37, 3.86, 5.27, 4.78, 7.55, 4.31, 7.69, 2.63, 6.04, 1.4, 8.77, 2.8, 6.13, 0.25, 8.31, 0.72, 7.53, 
+
+L3_sSYRK_A_nk
+0.5, 0.2, 0.4, 0.6, 0.6, 0.1, 0.3, 0.2, 0.7, 0.9, 0.4, 0.4, 0.7, 0.5, 0.8, 0.9, 0.2, 0.2, 0.2, 0.8, 0.8, 0.6, 0.7, 0.5, 0.4, 0.9, 0.5, 0.3, 0.1, 0.8, 0.5, 0.3, 0.3, 0.7, 0.4, 0.2, 0.7, 0.4, 0.7, 0.6, 0.3, 0.2, 0.1, 0.3, 0.2, 0.6, 0.6, 0.7, 0.7, 0.9, 0.6, 0.1, 0.6, 0.8, 0.6, 0.4, 0.5, 0.5, 0.2, 0.8, 0.2, 0.9, 0.8, 0.8, 0.6, 0.6, 0.1, 0.1, 0.8, 0.6, 0.5, 0.5, 0.9, 0.2, 0.5, 0.1, 0.1, 0.4, 0.1, 0.8, 0.3, 0.6, 0.4, 0.9, 0.7, 0.6, 0.7, 0.9, 0.8, 0.1, 0.6, 0.7, 0.5, 0.8, 0.2, 0.6, 0.2, 0.6, 0.3, 0.1, 0.2, 0.7, 0.4, 0.5, 0.1, 0.6, 0.3, 0.7, 0.8, 0.9, 0.2, 0.6, 0.8, 0.9, 0.1, 0.3, 0.5, 0.6, 0.2, 0.6, 0.1, 0.3, 0.7, 0.4, 0.3, 0.6, 0.8, 0.9, 0.5, 0.5, 0.2, 0.1, 0.6, 0.1, 0.8, 0.1, 0.7, 0.8, 0.5, 0.8, 0.2, 0.3, 0.2, 0.9, 0.1, 0.1, 0.9, 0.5, 0.6, 0.2, 0.9, 0.1, 0.5, 0.5, 0.3, 0.6, 0.2, 0.4, 0.5, 0.5, 0.7, 0.3, 0.3, 0.3, 0.2, 0.9, 0.4, 0.9, 0.5, 0.2, 0.2, 0.8, 0.4, 0.8, 0.1, 0.5, 0.8, 0.7, 0.1, 0.3, 0.9, 0.8, 0.3, 0.2, 0.8, 0.9, 0.8, 0.1, 0.5, 0.3, 0.1, 0.2, 0.1, 0.2, 0.2, 0.5, 0.5, 0.2, 0.5, 0.1, 0.6, 0.5, 0.6, 0.9, 0.1, 0.4, 0.8, 0.4, 0.2, 0.1, 0.7, 0.8, 0.7, 0.3, 0.6, 0.4, 0.7, 0.5, 0.9, 0.6, 0.9, 0.1, 0.8, 0.5, 0.3, 0.9, 0.4, 0.8, 0.9, 0.4, 0.2, 0.6, 0.5, 0.4, 0.3, 0.3, 0.8, 0.1, 0.5, 0.7, 0.6, 0.1, 0.2, 0.4, 0.8, 0.9, 0.3, 0.6, 0.5, 0.6, 0.8, 0.9, 0.5, 0.3, 0.6, 0.2, 0.6, 0.1, 0.4, 0.3, 0.9, 0.1, 0.5, 0.6, 0.2, 0.1, 0.7, 0.7, 0.3, 0.2, 0.2, 0.9, 
+
+L3_sSYRK_C_nn
+0.5, 0.8, 0.8, 0.8, 0.9, 0.8, 0.4, 0.3, 0.1, 0.7, 0.4, 0.7, 0.5, 0.2, 0.7, 0.6, 0.5, 0.8, 0.1, 0.3, 0.3, 0.8, 0.7, 0.1, 0.6, 0.7, 0.2, 0.6, 0.7, 0.7, 0.3, 0.1, 0.5, 0.6, 0.8, 0.3, 0.7, 0.9, 0.6, 0.2, 0.9, 0.3, 0.1, 0.5, 0.6, 0.5, 0.8, 0.8, 0.7, 0.5, 0.5, 0.8, 0.3, 0.9, 0.4, 0.1, 0.8, 0.1, 0.7, 0.4, 0.6, 0.1, 0.4, 0.5, 0.9, 0.2, 0.9, 0.2, 0.9, 0.8, 0.6, 0.1, 0.4, 0.2, 0.4, 0.3, 0.1, 0.1, 0.1, 0.3, 0.5, 0.9, 0.3, 0.8, 0.8, 0.8, 0.7, 0.2, 0.8, 0.2, 0.2, 0.5, 0.6, 0.5, 0.1, 0.7, 0.5, 0.4, 0.2, 0.9, 0.7, 0.9, 0.4, 0.1, 0.9, 0.1, 0.4, 0.5, 0.4, 0.3, 0.7, 0.2, 0.8, 0.5, 0.4, 0.5, 0.1, 0.2, 0.8, 0.3, 0.6, 0.3, 0.7, 0.3, 0.6, 0.3, 0.2, 0.4, 0.6, 0.4, 0.6, 0.6, 0.4, 0.3, 0.3, 0.3, 0.1, 0.7, 0.1, 0.4, 0.1, 0.5, 0.7, 0.4, 0.4, 0.1, 0.8, 0.9, 0.5, 0.4, 0.6, 0.3, 0.7, 0.7, 0.2, 0.5, 0.6, 0.1, 0.1, 0.2, 0.6, 0.1, 0.1, 0.8, 0.5, 0.9, 0.2, 0.4, 0.3, 0.7, 0.4, 0.6, 0.6, 0.1, 0.1, 0.7, 0.8, 0.4, 0.8, 0.8, 0.3, 0.2, 0.7, 0.9, 0.4, 0.2, 0.7, 0.7, 0.7, 0.5, 0.4, 0.3, 0.5, 0.5, 0.6, 0.9, 0.5, 0.2, 0.2, 0.8, 0.4, 0.8, 0.8, 0.3, 0.5, 0.7, 0.8, 0.5, 0.5, 0.4, 0.4, 0.6, 0.5, 0.9, 0.7, 0.8, 0.2, 0.1, 0.7, 0.6, 0.7, 0.2, 0.3, 0.8, 0.9, 0.9, 0.2, 0.5, 0.4, 0.4, 0.2, 0.9, 0.4, 0.1, 0.4, 0.3, 0.2, 0.2, 0.7, 0.1, 0.7, 0.2, 0.3, 0.9, 0.1, 0.3, 0.6, 0.4, 0.4, 0.8, 0.7, 0.3, 0.1, 0.5, 0.7, 0.6, 0.5, 0.5, 0.9, 0.8, 0.7, 0.2, 0.3, 0.3, 0.3, 0.2, 0.8, 0.6, 0.2, 0.5, 0.4, 0.9, 0.5, 0.6, 0.5, 0.2, 0.8, 0.9, 0.8, 0.3, 0.7, 0.7, 0.7, 0.3, 0.7, 0.2, 0.7, 0.9, 0.9, 
+
+L3_sSYRK_o_N
+5.61999998122, 4.90000006035, 4.26000007182, 5.4800000605, 4.3300000076, 5.26000007406, 3.93000005007, 4.38000005677, 4.21000000626, 4.45000002906, 3.76000003383, 4.69999999404, 4.2000000596, 5.10000001937, 5.0200000222, 4.75000012144, 4.05000001714, 4.90000006035, 4.90000005066, 3.78000008509, 4.77000010043, 4.18000008881, 5.43000005156, 3.53000005752, 4.36000012919, 4.29000004664, 3.82000004157, 4.13000008509, 4.7300000225, 4.23000004336, 4.58000006124, 3.88000006199, 4.75000010952, 3.78000005901, 4.26000007182, 3.78000008509, 4.46000004202, 5.53000006348, 3.9800000903, 4.4600000748, 4.15000004917, 4.17000007957, 3.41000003532, 3.64000003025, 3.94000009209, 3.62000002816, 3.62000007287, 4.29000007272, 4.39000000343, 3.80000010952, 3.64000001609, 5.4800000605, 4.77000010043, 5.53000006348, 6.90000007302, 4.42000010043, 6.15000011325, 4.67000005201, 5.92000004381, 4.9700000751, 4.69000011072, 4.82000003561, 4.82000003859, 4.45000007004, 5.38000008285, 4.72000004455, 5.63000008211, 4.11000005916, 4.3300000076, 4.18000008881, 3.9800000903, 4.42000010043, 4.57000009447, 4.57000009671, 3.32000009671, 4.13000010148, 3.72000004157, 2.85000004023, 3.55000004172, 4.34000008315, 3.17000006095, 4.31999999017, 3.94000005633, 4.36000010461, 4.09000004217, 5.26000007406, 5.43000005156, 4.4600000748, 6.15000011325, 4.57000009671, 6.56000003308, 4.75000006482, 5.22000013545, 4.67000006467, 4.13000003293, 5.51000002712, 4.88000009328, 4.28000005454, 5.33000002697, 5.79000002503, 5.53000005603, 5.11999999613, 3.93000005007, 3.53000005752, 4.15000004917, 4.67000005201, 3.32000009671, 4.75000006482, 4.64000005782, 4.12000010341, 4.00000006929, 3.05000005737, 4.67000002444, 3.84000006154, 3.15000004023, 4.01000006437, 3.58000008732, 3.88000005081, 3.66000005394, 4.38000005677, 4.36000012919, 4.17000007957, 5.92000004381, 4.13000010148, 5.22000013545, 4.12000010341, 5.41000005245, 4.07000002146, 3.47000008479, 4.31000007182, 4.62000007361, 3.82000008628, 4.36000005618, 4.55000004098, 4.51000014335, 3.97000002742, 4.21000000626, 4.29000004664, 3.41000003532, 4.9700000751, 3.72000004157, 4.67000006467, 4.00000006929, 4.07000002146, 4.97000004381, 3.6300000523, 4.05000005439, 4.7300000076, 3.97000004977, 4.38000004485, 4.14000004217, 4.04000009954, 4.26999998122, 4.45000002906, 3.82000004157, 3.64000003025, 4.69000011072, 2.85000004023, 4.13000003293, 3.05000005737, 3.47000008479, 3.6300000523, 4.04999998808, 3.66000006586, 3.40000004396, 4.21000002414, 4.42000003487, 3.66000004351, 3.69000010103, 3.82000000432, 3.76000003383, 4.13000008509, 3.94000009209, 4.82000003561, 3.55000004172, 5.51000002712, 4.67000002444, 4.31000007182, 4.05000005439, 3.66000006586, 4.90999998242, 3.6600000383, 3.4900000295, 4.41000002787, 3.83000006273, 4.31000002339, 3.94000002056, 4.69999999404, 4.7300000225, 3.62000002816, 4.82000003859, 4.34000008315, 4.88000009328, 3.84000006154, 4.62000007361, 4.7300000076, 3.40000004396, 3.6600000383, 5.50000000149, 3.80000007153, 4.52000000134, 4.91000001296, 5.25000008494, 3.43000002846, 4.2000000596, 4.23000004336, 3.62000007287, 4.45000007004, 3.17000006095, 4.28000005454, 3.15000004023, 3.82000008628, 3.97000004977, 4.21000002414, 3.4900000295, 3.80000007153, 3.84000005037, 4.15000006482, 3.83000003293, 4.33000008807, 3.63999998629, 5.10000001937, 4.58000006124, 4.29000007272, 5.38000008285, 4.31999999017, 5.33000002697, 4.01000006437, 4.36000005618, 4.38000004485, 4.42000003487, 4.41000002787, 4.52000000134, 4.15000006482, 6.29999997914, 4.9600000383, 5.01000007108, 4.19000000119, 5.0200000222, 3.88000006199, 4.39000000343, 4.72000004455, 3.94000005633, 5.79000002503, 3.58000008732, 4.55000004098, 4.14000004217, 3.66000004351, 3.83000006273, 4.91000001296, 3.83000003293, 4.9600000383, 5.15000000298, 4.54000009358, 4.2300000076, 4.75000012144, 4.75000010952, 3.80000010952, 5.63000008211, 4.36000010461, 5.53000005603, 3.88000005081, 4.51000014335, 4.04000009954, 3.69000010103, 4.31000002339, 5.25000008494, 4.33000008807, 5.01000007108, 4.54000009358, 5.67000009447, 4.65000002906, 4.05000001714, 3.78000005901, 3.64000001609, 4.11000005916, 4.09000004217, 5.11999999613, 3.66000005394, 3.97000002742, 4.26999998122, 3.82000000432, 3.94000002056, 3.43000002846, 3.63999998629, 4.19000000119, 4.2300000076, 4.65000002906, 4.95999993771, 
+
+L3_sSYRK_A_kn
+0.1, 0.5, 0.7, 0.6, 0.6, 0.1, 0.8, 0.9, 0.2, 0.1, 0.3, 0.1, 0.8, 0.8, 0.5, 0.9, 0.7, 0.9, 0.4, 0.2, 0.8, 0.9, 0.1, 0.7, 0.6, 0.2, 0.2, 0.7, 0.5, 0.5, 0.6, 0.1, 0.1, 0.6, 0.4, 0.1, 0.2, 0.5, 0.2, 0.4, 0.9, 0.6, 0.7, 0.7, 0.9, 0.6, 0.8, 0.4, 0.6, 0.4, 0.3, 0.6, 0.7, 0.3, 0.9, 0.7, 0.5, 0.7, 0.2, 0.9, 0.6, 0.7, 0.6, 0.4, 0.6, 0.2, 0.7, 0.1, 0.6, 0.4, 0.8, 0.5, 0.5, 0.6, 0.7, 0.4, 0.3, 0.8, 0.9, 0.4, 0.7, 0.1, 0.6, 0.2, 0.1, 0.9, 0.6, 0.6, 0.1, 0.1, 0.2, 0.7, 0.2, 0.5, 0.4, 0.3, 0.5, 0.3, 0.3, 0.4, 0.5, 0.4, 0.8, 0.9, 0.8, 0.1, 0.1, 0.3, 0.2, 0.8, 0.5, 0.2, 0.7, 0.3, 0.8, 0.5, 0.4, 0.2, 0.4, 0.6, 0.1, 0.6, 0.5, 0.9, 0.9, 0.1, 0.8, 0.7, 0.4, 0.6, 0.9, 0.5, 0.4, 0.3, 0.7, 0.2, 0.8, 0.5, 0.9, 0.6, 0.9, 0.5, 0.4, 0.8, 0.6, 0.9, 0.7, 0.6, 0.6, 0.4, 0.2, 0.9, 0.9, 0.2, 0.2, 0.2, 0.7, 0.5, 0.7, 0.1, 0.5, 0.7, 0.5, 0.1, 0.1, 0.7, 0.4, 0.6, 0.8, 0.4, 0.8, 0.6, 0.1, 0.6, 0.1, 0.2, 0.4, 0.9, 0.5, 0.8, 0.8, 0.3, 0.3, 0.2, 0.9, 0.5, 0.3, 0.2, 0.2, 0.6, 0.4, 0.7, 0.6, 0.4, 0.3, 0.9, 0.7, 0.3, 0.1, 0.9, 0.6, 0.8, 0.7, 0.3, 0.5, 0.8, 0.6, 0.6, 0.1, 0.2, 0.1, 0.5, 0.7, 0.9, 0.6, 0.7, 0.8, 0.2, 0.2, 0.1, 0.2, 0.1, 0.4, 0.1, 0.8, 0.6, 0.6, 0.2, 0.3, 0.7, 0.4, 0.1, 0.2, 0.6, 0.1, 0.8, 0.4, 0.8, 0.5, 0.2, 0.5, 0.9, 0.8, 0.4, 0.9, 0.2, 0.4, 0.7, 0.7, 0.7, 0.5, 0.4, 0.6, 0.8, 0.6, 0.9, 0.4, 0.9, 0.1, 0.5, 0.6, 0.9, 0.9, 0.6, 0.7, 0.4, 0.6, 0.7, 0.2, 0.6, 0.4, 0.4, 
+
+L3_sSYRK_o_T
+6.69000002205, 5.09000007346, 5.66000007853, 5.19000009805, 5.27999996215, 4.40000010654, 5.22999994501, 5.54000006974, 4.93000005826, 5.84000002205, 5.87000004753, 5.250000076, 5.600000076, 3.48000009775, 4.60000008643, 4.78000005081, 4.09000005409, 5.09000007346, 4.04000004143, 4.07000007063, 3.90000009015, 3.84000002354, 3.25000005364, 3.49000001386, 4.5900000608, 4.60000000596, 4.07000004828, 4.5700000535, 3.79000006527, 4.95000006184, 2.9900000757, 3.2200000833, 3.760000007, 3.48000007689, 5.66000007853, 4.07000007063, 6.01000004947, 4.65000006035, 4.84000002503, 3.79000010177, 5.18999995351, 5.12000004083, 4.55000008047, 5.18000001058, 5.15000007302, 4.35000008792, 6.09000008538, 3.9700001049, 4.3800001134, 4.77999998972, 3.92000001848, 5.19000009805, 3.90000009015, 4.65000006035, 6.17000006169, 5.17000001028, 4.56000005767, 4.53999997735, 5.20000009909, 5.34999999702, 5.58000005975, 4.97000002369, 4.35000006184, 5.72000009447, 4.3900000824, 4.35000011623, 5.68999998108, 4.03000010967, 5.27999996215, 3.84000002354, 4.84000002503, 5.17000001028, 5.99999992251, 4.1800000158, 4.73999996319, 4.77000003338, 4.72999996364, 4.58999996319, 4.51999995515, 4.18000000834, 5.52000001103, 4.41000004426, 4.01000011951, 5.6399999617, 4.63000005528, 4.40000010654, 3.25000005364, 3.79000010177, 4.56000005767, 4.1800000158, 3.99000007868, 3.70000003204, 4.3400000973, 4.8400000295, 4.19000005782, 4.3200000371, 3.73000005752, 4.75000008717, 2.69000008166, 4.43000013724, 4.57000000432, 3.61000005543, 5.22999994501, 3.49000001386, 5.18999995351, 4.53999997735, 4.73999996319, 3.70000003204, 6.01999984711, 4.72999999791, 4.96999995217, 4.8299999398, 5.66999991715, 4.36000001073, 5.36999998868, 3.86000005767, 4.14000005782, 4.52999995917, 4.29000004441, 5.54000006974, 4.5900000608, 5.12000004083, 5.20000009909, 4.77000003338, 4.3400000973, 4.72999999791, 6.23000001132, 5.21000005096, 5.47000002667, 5.48000005752, 4.61000011727, 6.2400001055, 3.93000009403, 4.60000008643, 4.91999999091, 4.19000006825, 4.93000005826, 4.60000000596, 4.55000008047, 5.34999999702, 4.72999996364, 4.8400000295, 4.96999995217, 5.21000005096, 6.26999990821, 5.53999997139, 5.62000001401, 5.07000002444, 6.20000000745, 3.86000006288, 5.12000009447, 5.19999997094, 4.25000004619, 5.84000002205, 4.07000004828, 5.18000001058, 5.58000005975, 4.58999996319, 4.19000005782, 4.8299999398, 5.47000002667, 5.53999997139, 6.13999993265, 6.11999999464, 4.85000004023, 6.47999997407, 3.28000006646, 4.95000009015, 4.97999998301, 4.22000000879, 5.87000004753, 4.5700000535, 5.15000007302, 4.97000002369, 4.51999995515, 4.3200000371, 5.66999991715, 5.48000005752, 5.62000001401, 6.11999999464, 6.17999994576, 4.6700000602, 6.04000002578, 4.26000004575, 4.44000008538, 4.4199999924, 4.06000003457, 5.250000076, 3.79000006527, 4.35000008792, 4.35000006184, 4.18000000834, 3.73000005752, 4.36000001073, 4.61000011727, 5.07000002444, 4.85000004023, 4.6700000602, 4.34000006229, 5.03000010371, 3.04000009805, 3.82000013322, 4.41000004202, 3.11000009418, 5.600000076, 4.95000006184, 6.09000008538, 5.72000009447, 5.52000001103, 4.75000008717, 5.36999998868, 6.2400001055, 6.20000000745, 6.47999997407, 6.04000002578, 5.03000010371, 6.85000006258, 4.04000010476, 5.61000011876, 5.65000003502, 4.85000009015, 3.48000009775, 2.9900000757, 3.9700001049, 4.3900000824, 4.41000004426, 2.69000008166, 3.86000005767, 3.93000009403, 3.86000006288, 3.28000006646, 4.26000004575, 3.04000009805, 4.04000010476, 3.40000014603, 3.08000012308, 3.77000004977, 2.9100000897, 4.60000008643, 3.2200000833, 4.3800001134, 4.35000011623, 4.01000011951, 4.43000013724, 4.14000005782, 4.60000008643, 5.12000009447, 4.95000009015, 4.44000008538, 3.82000013322, 5.61000011876, 3.08000012308, 4.78000016034, 4.68000007838, 3.9600001061, 4.78000005081, 3.760000007, 4.77999998972, 5.68999998108, 5.6399999617, 4.57000000432, 4.52999995917, 4.91999999091, 5.19999997094, 4.97999998301, 4.4199999924, 4.41000004202, 5.65000003502, 3.77000004977, 4.68000007838, 5.84999992549, 4.68999998257, 4.09000005409, 3.48000007689, 3.92000001848, 4.03000010967, 4.63000005528, 3.61000005543, 4.29000004441, 4.19000006825, 4.25000004619, 4.22000000879, 4.06000003457, 3.11000009418, 4.85000009015, 2.9100000897, 3.9600001061, 4.68999998257, 4.57000003636, 
+
+L3_dSYRK_A_nk
+0.9, 0.2, 0.9, 0.5, 0.4, 0.5, 0.6, 0.2, 0.9, 0.6, 0.4, 0.3, 0.6, 0.4, 0.7, 0.1, 0.4, 0.9, 0.8, 0.4, 0.6, 0.7, 0.6, 0.5, 0.5, 0.6, 0.6, 0.4, 0.7, 0.4, 0.1, 0.9, 0.7, 0.8, 0.2, 0.7, 0.1, 0.2, 0.6, 0.7, 0.7, 0.8, 0.1, 0.4, 0.6, 0.2, 0.7, 0.2, 0.5, 0.2, 0.1, 0.4, 0.6, 0.8, 0.2, 0.8, 0.4, 0.2, 0.1, 0.8, 0.7, 0.4, 0.1, 0.1, 0.1, 0.5, 0.8, 0.1, 0.1, 0.5, 0.9, 0.5, 0.3, 0.2, 0.1, 0.2, 0.4, 0.8, 0.4, 0.5, 0.5, 0.4, 0.1, 0.9, 0.5, 0.2, 0.3, 0.4, 0.6, 0.9, 0.2, 0.4, 0.1, 0.6, 0.1, 0.9, 0.1, 0.5, 0.6, 0.4, 0.3, 0.1, 0.5, 0.8, 0.7, 0.8, 0.9, 0.4, 0.1, 0.1, 0.3, 0.5, 0.4, 0.6, 0.7, 0.6, 0.3, 0.2, 0.6, 0.2, 0.7, 0.7, 0.2, 0.1, 0.7, 0.1, 0.7, 0.9, 0.2, 0.3, 0.6, 0.9, 0.5, 0.9, 0.2, 0.5, 0.4, 0.6, 0.9, 0.4, 0.9, 0.1, 0.4, 0.3, 0.8, 0.7, 0.2, 0.8, 0.5, 0.2, 0.1, 0.8, 0.7, 0.4, 0.6, 0.5, 0.8, 0.3, 0.8, 0.5, 0.4, 0.6, 0.8, 0.5, 0.3, 0.2, 0.7, 0.3, 0.4, 0.3, 0.3, 0.5, 0.3, 0.8, 0.8, 0.2, 0.9, 0.3, 0.4, 0.9, 0.1, 0.1, 0.7, 0.2, 0.2, 0.4, 0.7, 0.9, 0.3, 0.9, 0.1, 0.5, 0.4, 0.3, 0.6, 0.6, 0.3, 0.5, 0.5, 0.7, 0.9, 0.8, 0.1, 0.8, 0.6, 0.9, 0.4, 0.2, 0.8, 0.2, 0.3, 0.3, 0.4, 0.2, 0.4, 0.3, 0.1, 0.4, 0.6, 0.8, 0.6, 0.1, 0.3, 0.8, 0.2, 0.4, 0.1, 0.4, 0.6, 0.8, 0.3, 0.4, 0.8, 0.6, 0.2, 0.9, 0.4, 0.3, 0.2, 0.9, 0.7, 0.6, 0.5, 0.3, 0.3, 0.1, 0.4, 0.3, 0.1, 0.9, 0.6, 0.8, 0.2, 0.2, 0.8, 0.9, 0.4, 0.6, 0.6, 0.2, 0.8, 0.5, 0.2, 0.9, 0.3, 0.8, 0.2, 0.6, 0.6, 0.4, 0.7, 0.4, 
+
+L3_dSYRK_C_nn
+0.1, 0.4, 0.5, 0.9, 0.3, 0.9, 0.1, 0.2, 0.5, 0.8, 0.8, 0.1, 0.9, 0.9, 0.4, 0.2, 0.8, 0.4, 0.6, 0.3, 0.8, 0.1, 0.3, 0.1, 0.9, 0.2, 0.6, 0.7, 0.1, 0.7, 0.9, 0.5, 0.7, 0.2, 0.5, 0.3, 0.1, 0.2, 0.5, 0.7, 0.1, 0.8, 0.8, 0.4, 0.1, 0.8, 0.9, 0.5, 0.1, 0.9, 0.2, 0.9, 0.8, 0.2, 0.8, 0.5, 0.8, 0.4, 0.6, 0.8, 0.4, 0.7, 0.3, 0.9, 0.5, 0.1, 0.3, 0.8, 0.3, 0.1, 0.5, 0.5, 0.8, 0.8, 0.9, 0.1, 0.3, 0.7, 0.2, 0.6, 0.2, 0.1, 0.6, 0.7, 0.8, 0.9, 0.3, 0.7, 0.8, 0.8, 0.4, 0.5, 0.6, 0.9, 0.8, 0.5, 0.5, 0.5, 0.4, 0.7, 0.8, 0.2, 0.1, 0.1, 0.1, 0.4, 0.9, 0.5, 0.3, 0.7, 0.8, 0.5, 0.6, 0.8, 0.2, 0.9, 0.6, 0.6, 0.7, 0.2, 0.9, 0.8, 0.6, 0.1, 0.6, 0.7, 0.7, 0.6, 0.1, 0.4, 0.8, 0.3, 0.5, 0.7, 0.9, 0.7, 0.5, 0.2, 0.8, 0.8, 0.3, 0.9, 0.8, 0.6, 0.2, 0.7, 0.1, 0.9, 0.7, 0.5, 0.1, 0.1, 0.2, 0.8, 0.6, 0.4, 0.4, 0.7, 0.8, 0.5, 0.1, 0.7, 0.4, 0.5, 0.4, 0.5, 0.9, 0.1, 0.5, 0.7, 0.8, 0.7, 0.1, 0.7, 0.2, 0.5, 0.6, 0.4, 0.1, 0.5, 0.4, 0.6, 0.5, 0.8, 0.6, 0.2, 0.4, 0.1, 0.1, 0.8, 0.3, 0.6, 0.5, 0.8, 0.8, 0.9, 0.4, 0.6, 0.2, 0.6, 0.6, 0.8, 0.4, 0.6, 0.9, 0.7, 0.9, 0.9, 0.2, 0.5, 0.2, 0.3, 0.7, 0.5, 0.5, 0.6, 0.9, 0.9, 0.3, 0.5, 0.6, 0.9, 0.9, 0.5, 0.5, 0.1, 0.4, 0.9, 0.5, 0.5, 0.9, 0.8, 0.6, 0.9, 0.2, 0.4, 0.8, 0.7, 0.4, 0.5, 0.1, 0.1, 0.6, 0.7, 0.6, 0.7, 0.1, 0.1, 0.6, 0.8, 0.3, 0.4, 0.5, 0.6, 0.7, 0.2, 0.7, 0.9, 0.3, 0.7, 0.8, 0.6, 0.9, 0.1, 0.5, 0.2, 0.4, 0.5, 0.8, 0.6, 0.5, 0.4, 0.8, 0.2, 0.2, 0.8, 0.8, 0.2, 0.7, 0.7, 0.2, 0.7, 0.4, 0.6, 0.6, 0.7, 0.7, 0.4, 0.4, 
+
+L3_dSYRK_o_N
+5.26, 4.82, 4.68, 4.02, 3.57, 4.27, 3.61, 4.43, 4.69, 5.23, 4.84, 3.96, 5.56, 4.14, 3.87, 3.98, 4.85, 4.82, 6.43, 4.45, 4.31, 3.97, 4.37, 4.3, 5.52, 4.93, 5.29, 4.68, 4.21, 5.34, 4.71, 4.95, 5.06, 4.86, 4.68, 4.45, 4.89, 3.27, 3.44, 4.32, 3.65, 4.91, 4.54, 5.1, 3.76, 4.39, 5.34, 3.54, 3.58, 4.75, 4.27, 4.02, 4.31, 3.27, 4.46, 2.83, 3.51, 2.81, 3.06, 4.27, 4.03, 3.3, 3.23, 4.71, 3.2, 3.52, 2.83, 4.37, 3.57, 3.97, 3.44, 2.83, 4.42, 3.31, 3.64, 3.31, 3.13, 3.59, 3.63, 3.56, 3.83, 2.37, 3.36, 3.53, 4.03, 4.27, 4.37, 4.32, 3.51, 3.31, 4.73, 3.84, 4.24, 4.26, 4.75, 3.53, 4.29, 4.52, 3.39, 4.51, 4.46, 3.71, 3.61, 4.3, 3.65, 2.81, 3.64, 3.84, 4.53, 4.28, 4.53, 4.38, 3.76, 4.04, 3.99, 3.77, 3.93, 4.31, 4.37, 4.43, 5.52, 4.91, 3.06, 3.31, 4.24, 4.28, 5.43, 4.48, 4.41, 4.02, 4.14, 4.31, 3.7, 4.3, 4.91, 4.58, 4.69, 4.93, 4.54, 4.27, 3.13, 4.26, 4.53, 4.48, 5.41, 5.24, 3.45, 4.46, 4.92, 3.83, 3.92, 3.69, 4.34, 5.23, 5.29, 5.1, 4.03, 3.59, 4.75, 4.38, 4.41, 5.24, 6.03, 4.35, 4.44, 5.07, 4.64, 4.08, 4.77, 5.27, 4.84, 4.68, 3.76, 3.3, 3.63, 3.53, 3.76, 4.02, 3.45, 4.35, 4.52, 4.36, 4.66, 3.56, 3.58, 3.8, 4.11, 3.96, 4.21, 4.39, 3.23, 3.56, 4.29, 4.04, 4.14, 4.46, 4.44, 4.36, 5.28, 4.82, 4.19, 4.14, 4.35, 3.88, 5.56, 5.34, 5.34, 4.71, 3.83, 4.52, 3.99, 4.31, 4.92, 5.07, 4.66, 4.82, 6.42, 4.11, 4.52, 4.3, 5.13, 4.14, 4.71, 3.54, 3.2, 2.37, 3.39, 3.77, 3.7, 3.83, 4.64, 3.56, 4.19, 4.11, 3.78, 3.64, 4.58, 4.03, 3.87, 4.95, 3.58, 3.52, 3.36, 4.51, 3.93, 4.3, 3.92, 4.08, 3.58, 4.14, 4.52, 3.64, 5.07, 4.22, 4.62, 3.98, 5.06, 4.75, 2.83, 3.53, 4.46, 4.31, 4.91, 3.69, 4.77, 3.8, 4.35, 4.3, 4.58, 4.22, 5.39, 4.51, 4.85, 4.86, 4.27, 4.37, 4.03, 3.71, 4.37, 4.58, 4.34, 5.27, 4.11, 3.88, 5.13, 4.03, 4.62, 4.51, 5.36, 
+
+L3_dSYRK_A_kn
+0.8, 0.5, 0.1, 0.4, 0.9, 0.5, 0.2, 0.6, 0.9, 0.2, 0.7, 0.8, 0.2, 0.2, 0.3, 0.5, 0.5, 0.9, 0.2, 0.3, 0.8, 0.6, 0.4, 0.5, 0.1, 0.6, 0.4, 0.9, 0.8, 0.4, 0.1, 0.4, 0.7, 0.9, 0.3, 0.3, 0.4, 0.8, 0.6, 0.7, 0.9, 0.6, 0.5, 0.3, 0.6, 0.9, 0.2, 0.8, 0.9, 0.2, 0.8, 0.9, 0.2, 0.7, 0.7, 0.3, 0.1, 0.3, 0.2, 0.6, 0.4, 0.5, 0.2, 0.7, 0.5, 0.3, 0.6, 0.9, 0.8, 0.3, 0.1, 0.4, 0.7, 0.7, 0.6, 0.5, 0.6, 0.9, 0.6, 0.7, 0.3, 0.3, 0.7, 0.2, 0.4, 0.3, 0.3, 0.5, 0.2, 0.7, 0.4, 0.6, 0.5, 0.2, 0.6, 0.4, 0.2, 0.7, 0.7, 0.2, 0.2, 0.2, 0.4, 0.2, 0.1, 0.3, 0.5, 0.1, 0.6, 0.3, 0.4, 0.3, 0.9, 0.7, 0.5, 0.5, 0.6, 0.9, 0.2, 0.4, 0.8, 0.1, 0.6, 0.4, 0.5, 0.5, 0.5, 0.2, 0.2, 0.6, 0.7, 0.2, 0.2, 0.1, 0.3, 0.4, 0.4, 0.4, 0.5, 0.5, 0.8, 0.8, 0.2, 0.3, 0.7, 0.3, 0.9, 0.3, 0.7, 0.1, 0.5, 0.5, 0.8, 0.4, 0.4, 0.9, 0.7, 0.8, 0.6, 0.5, 0.3, 0.2, 0.5, 0.2, 0.4, 0.9, 0.4, 0.6, 0.1, 0.9, 0.8, 0.1, 0.3, 0.7, 0.5, 0.5, 0.7, 0.6, 0.7, 0.7, 0.7, 0.9, 0.3, 0.1, 0.4, 0.3, 0.3, 0.6, 0.3, 0.1, 0.5, 0.6, 0.1, 0.5, 0.9, 0.1, 0.6, 0.8, 0.1, 0.3, 0.9, 0.5, 0.7, 0.1, 0.1, 0.2, 0.5, 0.3, 0.9, 0.5, 0.6, 0.1, 0.7, 0.8, 0.1, 0.9, 0.2, 0.8, 0.8, 0.2, 0.2, 0.7, 0.8, 0.3, 0.4, 0.3, 0.9, 0.2, 0.4, 0.8, 0.2, 0.1, 0.2, 0.6, 0.9, 0.5, 0.4, 0.6, 0.5, 0.2, 0.3, 0.3, 0.6, 0.8, 0.7, 0.4, 0.1, 0.1, 0.3, 0.9, 0.4, 0.5, 0.6, 0.6, 0.4, 0.9, 0.9, 0.1, 0.8, 0.6, 0.3, 0.3, 0.1, 0.7, 0.6, 0.8, 0.2, 0.6, 0.3, 0.4, 0.5, 0.1, 
+
+L3_dSYRK_o_T
+6.38, 4.05, 3.27, 6.07, 5.68, 5.25, 4.31, 3.84, 5.52, 4.92, 6.43, 5.01, 5.08, 4.62, 4.59, 4.48, 5.39, 4.05, 3.83, 2.06, 4.12, 3.7, 3.5, 2.7, 3.28, 3.41, 3.07, 4.1, 3.04, 3.54, 3.65, 3.2, 3.22, 3.02, 3.27, 2.06, 2.73, 3.1, 3.84, 3.44, 2.72, 2.64, 3.35, 2.8, 2.61, 3.52, 3.8, 3.05, 2.79, 2.85, 3.39, 6.07, 4.12, 3.1, 5.84, 5.5, 4.85, 4.55, 3.85, 5.13, 4.13, 5.76, 4.96, 4.72, 4.02, 4.17, 3.89, 5.28, 5.68, 3.7, 3.84, 5.5, 7.32, 5.77, 5.76, 4.0, 5.27, 5.25, 5.76, 6.26, 4.55, 4.46, 5.56, 4.73, 5.45, 5.25, 3.5, 3.44, 4.85, 5.77, 5.27, 4.42, 3.78, 5.04, 4.1, 4.54, 5.21, 4.03, 3.95, 4.81, 3.76, 4.37, 4.31, 2.7, 2.72, 4.55, 5.76, 4.42, 4.83, 4.03, 4.37, 4.18, 5.02, 5.75, 3.48, 4.7, 4.76, 3.82, 4.34, 3.84, 3.28, 2.64, 3.85, 4.0, 3.78, 4.03, 4.0, 3.52, 2.92, 4.16, 4.34, 2.88, 3.65, 3.78, 3.59, 3.52, 5.52, 3.41, 3.35, 5.13, 5.27, 5.04, 4.37, 3.52, 5.24, 4.34, 4.77, 5.5, 4.19, 3.85, 4.06, 3.53, 4.26, 4.92, 3.07, 2.8, 4.13, 5.25, 4.1, 4.18, 2.92, 4.34, 4.39, 4.5, 4.28, 3.65, 4.19, 3.73, 3.24, 3.72, 6.43, 4.1, 2.61, 5.76, 5.76, 4.54, 5.02, 4.16, 4.77, 4.5, 6.73, 5.67, 4.44, 4.31, 4.84, 4.67, 4.7, 5.01, 3.04, 3.52, 4.96, 6.26, 5.21, 5.75, 4.34, 5.5, 4.28, 5.67, 6.61, 3.89, 4.28, 5.49, 4.11, 4.92, 5.08, 3.54, 3.8, 4.72, 4.55, 4.03, 3.48, 2.88, 4.19, 3.65, 4.44, 3.89, 4.9, 4.17, 3.68, 3.61, 4.4, 4.62, 3.65, 3.05, 4.02, 4.46, 3.95, 4.7, 3.65, 3.85, 4.19, 4.31, 4.28, 4.17, 4.79, 4.33, 3.86, 3.91, 4.59, 3.2, 2.79, 4.17, 5.56, 4.81, 4.76, 3.78, 4.06, 3.73, 4.84, 5.49, 3.68, 4.33, 4.98, 3.84, 4.53, 4.48, 3.22, 2.85, 3.89, 4.73, 3.76, 3.82, 3.59, 3.53, 3.24, 4.67, 4.11, 3.61, 3.86, 3.84, 4.27, 3.62, 5.39, 3.02, 3.39, 5.28, 5.45, 4.37, 4.34, 3.52, 4.26, 3.72, 4.7, 4.92, 4.4, 3.91, 4.53, 3.62, 5.43, 
+
+L3_cSYRK_A_nk
+0.40000000596, 0.300000011921, 0.800000011921, 0.300000011921, 0.800000011921, 0.20000000298, 0.10000000149, 0.40000000596, 0.600000023842, 0.699999988079, 0.800000011921, 0.20000000298, 0.600000023842, 0.899999976158, 0.800000011921, 0.10000000149, 0.10000000149, 0.5, 0.899999976158, 0.5, 0.899999976158, 0.699999988079, 0.5, 0.600000023842, 0.699999988079, 0.10000000149, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.699999988079, 0.899999976158, 0.300000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.10000000149, 0.600000023842, 0.40000000596, 0.600000023842, 0.699999988079, 0.699999988079, 0.5, 0.40000000596, 0.20000000298, 0.5, 0.40000000596, 0.10000000149, 0.899999976158, 0.800000011921, 0.40000000596, 0.600000023842, 0.300000011921, 0.600000023842, 0.600000023842, 0.20000000298, 0.699999988079, 0.899999976158, 0.800000011921, 0.899999976158, 0.10000000149, 0.800000011921, 0.5, 0.699999988079, 0.20000000298, 0.10000000149, 0.699999988079, 0.899999976158, 0.300000011921, 0.600000023842, 0.40000000596, 0.10000000149, 0.600000023842, 0.899999976158, 0.20000000298, 0.600000023842, 0.800000011921, 0.10000000149, 0.800000011921, 0.600000023842, 0.20000000298, 0.10000000149, 0.40000000596, 0.40000000596, 0.300000011921, 0.600000023842, 0.800000011921, 0.5, 0.800000011921, 0.300000011921, 0.600000023842, 0.5, 0.800000011921, 0.40000000596, 0.699999988079, 0.800000011921, 0.5, 0.899999976158, 0.5, 0.5, 0.300000011921, 0.5, 0.10000000149, 0.40000000596, 0.600000023842, 0.600000023842, 0.20000000298, 0.899999976158, 0.10000000149, 0.600000023842, 0.800000011921, 0.10000000149, 0.300000011921, 0.699999988079, 0.899999976158, 0.699999988079, 0.20000000298, 0.40000000596, 0.899999976158, 0.10000000149, 0.699999988079, 0.40000000596, 0.5, 0.699999988079, 0.800000011921, 0.20000000298, 0.40000000596, 0.5, 0.600000023842, 0.10000000149, 0.20000000298, 0.10000000149, 0.40000000596, 0.899999976158, 0.699999988079, 0.40000000596, 0.800000011921, 0.899999976158, 0.300000011921, 0.20000000298, 0.899999976158, 0.899999976158, 0.300000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.699999988079, 0.20000000298, 0.40000000596, 0.20000000298, 0.800000011921, 0.40000000596, 0.10000000149, 0.5, 0.899999976158, 0.20000000298, 0.899999976158, 0.699999988079, 0.699999988079, 0.899999976158, 0.300000011921, 0.10000000149, 0.600000023842, 0.899999976158, 0.899999976158, 0.600000023842, 0.699999988079, 0.40000000596, 0.300000011921, 0.5, 0.899999976158, 0.5, 0.699999988079, 0.300000011921, 0.699999988079, 0.600000023842, 0.600000023842, 0.699999988079, 0.5, 0.800000011921, 0.5, 0.800000011921, 0.800000011921, 0.10000000149, 0.600000023842, 0.600000023842, 0.300000011921, 0.600000023842, 0.600000023842, 0.899999976158, 0.40000000596, 0.800000011921, 0.800000011921, 0.899999976158, 0.600000023842, 0.800000011921, 0.899999976158, 0.699999988079, 0.10000000149, 0.699999988079, 0.800000011921, 0.40000000596, 0.300000011921, 0.10000000149, 0.600000023842, 0.800000011921, 0.300000011921, 0.40000000596, 0.40000000596, 0.5, 0.40000000596, 0.699999988079, 0.699999988079, 0.20000000298, 0.300000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.699999988079, 0.899999976158, 0.800000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.20000000298, 0.899999976158, 0.300000011921, 0.800000011921, 0.699999988079, 0.5, 0.899999976158, 0.20000000298, 0.20000000298, 0.600000023842, 0.699999988079, 0.800000011921, 0.600000023842, 0.10000000149, 0.5, 0.600000023842, 0.600000023842, 0.40000000596, 0.300000011921, 0.20000000298, 0.300000011921, 0.10000000149, 0.40000000596, 0.10000000149, 0.600000023842, 0.899999976158, 0.300000011921, 0.600000023842, 0.300000011921, 0.10000000149, 0.5, 0.699999988079, 0.20000000298, 0.10000000149, 0.699999988079, 0.20000000298, 0.600000023842, 0.300000011921, 0.5, 0.20000000298, 0.5, 0.5, 0.20000000298, 0.899999976158, 0.20000000298, 0.5, 0.800000011921, 0.800000011921, 0.10000000149, 0.40000000596, 0.10000000149, 0.800000011921, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.300000011921, 0.699999988079, 0.899999976158, 0.40000000596, 0.800000011921, 0.699999988079, 0.699999988079, 0.800000011921, 0.10000000149, 0.10000000149, 0.600000023842, 0.800000011921, 0.800000011921, 0.600000023842, 0.5, 0.699999988079, 0.20000000298, 0.20000000298, 0.300000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.699999988079, 0.40000000596, 0.699999988079, 0.40000000596, 0.699999988079, 0.300000011921, 0.20000000298, 0.899999976158, 0.20000000298, 0.699999988079, 0.20000000298, 0.800000011921, 0.699999988079, 0.5, 0.40000000596, 0.10000000149, 0.899999976158, 0.899999976158, 0.5, 0.699999988079, 0.899999976158, 0.40000000596, 0.899999976158, 0.20000000298, 0.10000000149, 0.20000000298, 0.5, 0.699999988079, 0.10000000149, 0.699999988079, 0.20000000298, 0.20000000298, 0.800000011921, 0.10000000149, 0.40000000596, 0.899999976158, 0.699999988079, 0.699999988079, 0.899999976158, 0.20000000298, 0.300000011921, 0.300000011921, 0.699999988079, 0.899999976158, 0.800000011921, 0.899999976158, 0.699999988079, 0.800000011921, 0.40000000596, 0.5, 0.5, 0.5, 0.10000000149, 0.300000011921, 0.5, 0.5, 0.300000011921, 0.20000000298, 0.10000000149, 0.699999988079, 0.20000000298, 0.699999988079, 0.699999988079, 0.600000023842, 0.300000011921, 0.600000023842, 0.20000000298, 0.899999976158, 0.20000000298, 0.300000011921, 0.10000000149, 0.10000000149, 0.600000023842, 0.40000000596, 0.40000000596, 0.800000011921, 0.800000011921, 0.5, 0.20000000298, 0.699999988079, 0.899999976158, 0.20000000298, 0.899999976158, 0.300000011921, 0.699999988079, 0.300000011921, 0.10000000149, 0.899999976158, 0.699999988079, 0.10000000149, 0.40000000596, 0.600000023842, 0.800000011921, 0.800000011921, 0.300000011921, 0.699999988079, 0.699999988079, 0.600000023842, 0.40000000596, 0.5, 0.40000000596, 0.10000000149, 0.800000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.600000023842, 0.10000000149, 0.600000023842, 0.300000011921, 0.800000011921, 0.899999976158, 0.899999976158, 0.600000023842, 0.10000000149, 0.40000000596, 0.10000000149, 0.899999976158, 0.899999976158, 0.10000000149, 0.5, 0.800000011921, 0.800000011921, 0.5, 0.699999988079, 0.699999988079, 0.40000000596, 0.20000000298, 0.899999976158, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.699999988079, 0.10000000149, 0.300000011921, 0.600000023842, 0.800000011921, 0.300000011921, 0.10000000149, 0.20000000298, 0.5, 0.300000011921, 0.899999976158, 0.699999988079, 0.5, 0.699999988079, 0.699999988079, 0.600000023842, 0.5, 0.600000023842, 0.899999976158, 0.40000000596, 0.5, 0.20000000298, 0.800000011921, 0.40000000596, 0.20000000298, 0.5, 0.899999976158, 0.300000011921, 0.899999976158, 0.20000000298, 0.10000000149, 0.40000000596, 0.20000000298, 0.699999988079, 0.800000011921, 0.40000000596, 0.5, 0.300000011921, 0.800000011921, 0.800000011921, 0.40000000596, 0.20000000298, 0.300000011921, 0.600000023842, 0.5, 0.699999988079, 0.699999988079, 0.600000023842, 0.899999976158, 0.600000023842, 0.699999988079, 0.699999988079, 0.40000000596, 0.800000011921, 0.699999988079, 0.40000000596, 0.600000023842, 0.5, 0.20000000298, 0.800000011921, 0.699999988079, 0.899999976158, 0.800000011921, 0.800000011921, 0.899999976158, 0.20000000298, 0.699999988079, 0.300000011921, 0.699999988079, 0.5, 0.699999988079, 0.600000023842, 0.20000000298, 0.800000011921, 0.40000000596, 0.5, 0.300000011921, 0.40000000596, 0.699999988079, 0.300000011921, 0.800000011921, 0.20000000298, 0.600000023842, 0.20000000298, 0.600000023842, 0.10000000149, 0.800000011921, 0.699999988079, 0.20000000298, 0.300000011921, 0.5, 0.300000011921, 0.300000011921, 0.300000011921, 0.899999976158, 0.10000000149, 0.699999988079, 0.600000023842, 0.5, 0.10000000149, 0.5, 0.800000011921, 0.300000011921, 0.10000000149, 0.300000011921, 0.300000011921, 0.699999988079, 0.40000000596, 
+
+L3_cSYRK_C_nn
+0.300000011921, 0.699999988079, 0.20000000298, 0.699999988079, 0.699999988079, 0.800000011921, 0.40000000596, 0.600000023842, 0.10000000149, 0.40000000596, 0.600000023842, 0.800000011921, 0.40000000596, 0.5, 0.300000011921, 0.800000011921, 0.10000000149, 0.600000023842, 0.800000011921, 0.300000011921, 0.699999988079, 0.20000000298, 0.899999976158, 0.40000000596, 0.699999988079, 0.10000000149, 0.899999976158, 0.800000011921, 0.300000011921, 0.600000023842, 0.40000000596, 0.40000000596, 0.5, 0.899999976158, 0.20000000298, 0.699999988079, 0.10000000149, 0.40000000596, 0.300000011921, 0.300000011921, 0.699999988079, 0.20000000298, 0.800000011921, 0.5, 0.300000011921, 0.300000011921, 0.40000000596, 0.5, 0.10000000149, 0.20000000298, 0.699999988079, 0.899999976158, 0.899999976158, 0.899999976158, 0.40000000596, 0.10000000149, 0.600000023842, 0.5, 0.300000011921, 0.800000011921, 0.40000000596, 0.40000000596, 0.899999976158, 0.600000023842, 0.5, 0.699999988079, 0.699999988079, 0.5, 0.699999988079, 0.800000011921, 0.300000011921, 0.300000011921, 0.800000011921, 0.5, 0.300000011921, 0.5, 0.899999976158, 0.40000000596, 0.800000011921, 0.899999976158, 0.300000011921, 0.10000000149, 0.40000000596, 0.5, 0.300000011921, 0.40000000596, 0.5, 0.300000011921, 0.20000000298, 0.5, 0.600000023842, 0.899999976158, 0.10000000149, 0.300000011921, 0.600000023842, 0.800000011921, 0.40000000596, 0.300000011921, 0.10000000149, 0.5, 0.20000000298, 0.20000000298, 0.40000000596, 0.600000023842, 0.699999988079, 0.20000000298, 0.300000011921, 0.5, 0.600000023842, 0.10000000149, 0.600000023842, 0.40000000596, 0.5, 0.40000000596, 0.899999976158, 0.10000000149, 0.699999988079, 0.899999976158, 0.800000011921, 0.10000000149, 0.300000011921, 0.699999988079, 0.10000000149, 0.899999976158, 0.600000023842, 0.300000011921, 0.40000000596, 0.5, 0.600000023842, 0.10000000149, 0.40000000596, 0.20000000298, 0.899999976158, 0.20000000298, 0.40000000596, 0.10000000149, 0.10000000149, 0.40000000596, 0.800000011921, 0.5, 0.899999976158, 0.40000000596, 0.600000023842, 0.40000000596, 0.5, 0.300000011921, 0.600000023842, 0.5, 0.40000000596, 0.300000011921, 0.40000000596, 0.40000000596, 0.20000000298, 0.800000011921, 0.800000011921, 0.600000023842, 0.600000023842, 0.899999976158, 0.5, 0.10000000149, 0.300000011921, 0.600000023842, 0.600000023842, 0.20000000298, 0.40000000596, 0.800000011921, 0.600000023842, 0.40000000596, 0.10000000149, 0.10000000149, 0.600000023842, 0.800000011921, 0.300000011921, 0.300000011921, 0.800000011921, 0.899999976158, 0.5, 0.40000000596, 0.600000023842, 0.5, 0.899999976158, 0.600000023842, 0.300000011921, 0.600000023842, 0.699999988079, 0.5, 0.5, 0.800000011921, 0.20000000298, 0.20000000298, 0.300000011921, 0.10000000149, 0.699999988079, 0.10000000149, 0.20000000298, 0.20000000298, 0.5, 0.699999988079, 0.20000000298, 0.600000023842, 0.10000000149, 0.699999988079, 0.699999988079, 0.600000023842, 0.40000000596, 0.5, 0.40000000596, 0.5, 0.300000011921, 0.10000000149, 0.899999976158, 0.10000000149, 0.40000000596, 0.300000011921, 0.300000011921, 0.600000023842, 0.10000000149, 0.300000011921, 0.5, 0.600000023842, 0.899999976158, 0.5, 0.40000000596, 0.20000000298, 0.800000011921, 0.800000011921, 0.20000000298, 0.300000011921, 0.899999976158, 0.800000011921, 0.800000011921, 0.10000000149, 0.10000000149, 0.300000011921, 0.899999976158, 0.20000000298, 0.600000023842, 0.10000000149, 0.300000011921, 0.800000011921, 0.10000000149, 0.20000000298, 0.40000000596, 0.5, 0.699999988079, 0.899999976158, 0.40000000596, 0.40000000596, 0.699999988079, 0.5, 0.5, 0.600000023842, 0.10000000149, 0.800000011921, 0.800000011921, 0.699999988079, 0.699999988079, 0.5, 0.5, 0.899999976158, 0.10000000149, 0.800000011921, 0.899999976158, 0.20000000298, 0.20000000298, 0.40000000596, 0.899999976158, 0.20000000298, 0.699999988079, 0.899999976158, 0.899999976158, 0.800000011921, 0.10000000149, 0.600000023842, 0.699999988079, 0.899999976158, 0.300000011921, 0.40000000596, 0.800000011921, 0.10000000149, 0.20000000298, 0.800000011921, 0.5, 0.800000011921, 0.899999976158, 0.5, 0.800000011921, 0.699999988079, 0.5, 0.899999976158, 0.300000011921, 0.899999976158, 0.40000000596, 0.20000000298, 0.40000000596, 0.5, 0.899999976158, 0.5, 0.40000000596, 0.600000023842, 0.20000000298, 0.800000011921, 0.20000000298, 0.800000011921, 0.899999976158, 0.600000023842, 0.800000011921, 0.300000011921, 0.899999976158, 0.899999976158, 0.5, 0.300000011921, 0.300000011921, 0.699999988079, 0.800000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.40000000596, 0.20000000298, 0.699999988079, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.899999976158, 0.699999988079, 0.10000000149, 0.699999988079, 0.300000011921, 0.40000000596, 0.600000023842, 0.5, 0.800000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.5, 0.600000023842, 0.800000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.10000000149, 0.20000000298, 0.5, 0.10000000149, 0.899999976158, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.800000011921, 0.800000011921, 0.5, 0.899999976158, 0.40000000596, 0.20000000298, 0.699999988079, 0.10000000149, 0.800000011921, 0.5, 0.899999976158, 0.899999976158, 0.20000000298, 0.5, 0.699999988079, 0.20000000298, 0.40000000596, 0.600000023842, 0.40000000596, 0.40000000596, 0.10000000149, 0.899999976158, 0.899999976158, 0.40000000596, 0.600000023842, 0.5, 0.600000023842, 0.899999976158, 0.600000023842, 0.300000011921, 0.5, 0.10000000149, 0.699999988079, 0.10000000149, 0.20000000298, 0.300000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.5, 0.699999988079, 0.300000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.10000000149, 0.600000023842, 0.20000000298, 0.699999988079, 0.40000000596, 0.10000000149, 0.600000023842, 0.5, 0.899999976158, 0.10000000149, 0.800000011921, 0.699999988079, 0.10000000149, 0.300000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.40000000596, 0.5, 0.300000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.899999976158, 0.800000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.5, 0.40000000596, 0.600000023842, 0.20000000298, 0.5, 0.600000023842, 0.20000000298, 0.40000000596, 0.800000011921, 0.10000000149, 0.20000000298, 0.600000023842, 0.20000000298, 0.5, 0.5, 0.800000011921, 0.699999988079, 0.899999976158, 0.800000011921, 0.40000000596, 0.40000000596, 0.600000023842, 0.800000011921, 0.600000023842, 0.10000000149, 0.600000023842, 0.20000000298, 0.5, 0.699999988079, 0.800000011921, 0.10000000149, 0.20000000298, 0.40000000596, 0.40000000596, 0.600000023842, 0.5, 0.800000011921, 0.699999988079, 0.20000000298, 0.699999988079, 0.40000000596, 0.10000000149, 0.20000000298, 0.899999976158, 0.699999988079, 0.5, 0.300000011921, 0.300000011921, 0.899999976158, 0.600000023842, 0.800000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.600000023842, 0.40000000596, 0.300000011921, 0.40000000596, 0.20000000298, 0.40000000596, 0.800000011921, 0.20000000298, 0.600000023842, 0.10000000149, 0.300000011921, 0.899999976158, 0.20000000298, 0.20000000298, 0.800000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.600000023842, 0.10000000149, 0.600000023842, 0.600000023842, 0.20000000298, 0.5, 0.300000011921, 0.20000000298, 0.800000011921, 0.800000011921, 0.699999988079, 0.5, 0.600000023842, 0.40000000596, 0.40000000596, 0.5, 0.699999988079, 0.10000000149, 0.5, 0.899999976158, 0.20000000298, 0.600000023842, 0.40000000596, 0.10000000149, 0.699999988079, 0.899999976158, 0.20000000298, 0.699999988079, 0.899999976158, 0.20000000298, 0.800000011921, 0.10000000149, 0.5, 0.40000000596, 0.40000000596, 0.5, 0.899999976158, 0.5, 0.5, 0.300000011921, 0.899999976158, 0.800000011921, 0.699999988079, 0.40000000596, 0.10000000149, 0.40000000596, 0.5, 0.5, 0.899999976158, 0.699999988079, 0.5, 0.20000000298, 0.20000000298, 0.40000000596, 0.10000000149, 0.10000000149, 0.10000000149, 0.699999988079, 0.600000023842, 0.600000023842, 0.10000000149, 0.899999976158, 0.800000011921, 0.899999976158, 0.600000023842, 0.600000023842, 0.800000011921, 0.10000000149, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.699999988079, 0.600000023842, 0.800000011921, 0.5, 0.600000023842, 0.40000000596, 0.5, 0.10000000149, 0.20000000298, 
+
+L3_cSYRK_o_N
+3.07000007957, 9.07999997854, 2.4000000529, 9.34000008315, 1.03999997362, 9.07000017568, 2.71000000328, 9.05000000969, -0.139999984801, 8.4600000003, 2.24999998808, 10.8500000678, 2.14000003546, 9.83000006199, 1.49000001758, 8.01000012249, 1.55000002012, 9.1700000006, 2.39000008985, 8.31000006288, 2.89999992549, 9.96999990001, 2.99999999702, 7.68000001654, 0.900000044703, 9.07000003859, 3.65999993548, 9.43999998406, 1.9800000076, 8.70000013784, 2.56999992535, 10.200000114, 4.199999962, 7.9300000523, 2.4000000529, 9.34000008315, 1.18000013947, 8.92000017643, -0.109999980927, 8.55000020713, 1.77000002667, 8.49000008538, 0.909999978691, 9.839999993, 1.32000004455, 9.50000019297, 1.99000001535, 10.3500000916, 0.799999988824, 7.71000009418, 1.42000003561, 9.21000003159, 1.69000007346, 9.39000005409, 1.60999997869, 9.12000001177, 2.60999999732, 8.09000008762, -0.169999934286, 9.64000014126, 2.13000001878, 8.51000007406, 2.29999995157, 9.75000013039, 1.06000001296, 10.970000084, 3.30000004992, 7.40000011548, 1.03999997362, 9.07000017568, -0.109999980927, 8.55000020713, -0.220000104904, 7.58000022441, -0.550000030547, 8.11000009418, -0.730000087321, 8.07000009373, 0.509999933988, 10.2400001293, -0.370000074357, 9.3600001128, 0.179999972582, 8.09000013977, -0.350000010431, 7.37000010863, 0.430000021011, 8.30000016615, -0.700000080466, 8.76000000775, 0.739999998212, 8.35000010654, -1.29999997243, 8.48000012606, 0.829999938309, 8.81000007555, 0.939999921471, 8.52000015035, -0.270000160784, 9.610000121, 1.43999996915, 7.34000013009, 2.71000000328, 9.05000000969, 1.77000002667, 8.49000008538, -0.550000030547, 8.11000009418, 1.14999999404, 8.20000004023, -0.369999970794, 8.68999999151, 0.989999951273, 9.8100000681, 1.91999987915, 9.8300000903, 1.87999992117, 7.65000007972, 1.27999995172, 7.50000003129, 0.970000069141, 9.12000002146, 0.619999897033, 10.0599998677, 2.23999998257, 7.26000006363, -0.289999989271, 8.81000006214, 1.75999993771, 7.93000005826, 1.56999996036, 8.66000006661, 1.13999984026, 9.74000004217, 2.73999997139, 7.02000009, -0.139999984801, 8.4600000003, 0.909999978691, 9.839999993, -0.730000087321, 8.07000009373, -0.369999970794, 8.68999999151, -1.06000005692, 7.99999996722, -0.180000003129, 10.43999999, -0.490000026524, 9.20000002012, -0.460000012964, 8.33999997586, -0.380000002384, 8.69999994934, 0.440000073463, 9.2599999921, -0.340000010878, 9.70999986097, 0.819999979734, 7.59999996498, -0.820000054985, 9.41999997526, 0.229999971092, 8.589999917, 0.959999866933, 8.61000006139, -0.630000083596, 10.2599999563, 1.75999994889, 7.19000006005, 2.24999998808, 10.8500000678, 1.32000004455, 9.50000019297, 0.509999933988, 10.2400001293, 0.989999951273, 9.8100000681, -0.180000003129, 10.43999999, 1.20999997199, 11.4000001371, 0.989999979585, 11.6300000851, 0.0900000332296, 9.1900001502, 1.21999996856, 9.40000009611, 0.730000050813, 9.71000007555, 0.709999933243, 9.9599999921, 1.99999997243, 8.81000006884, -0.680000009835, 10.1300001, 1.43999996543, 9.97000000954, 0.989999976605, 10.6600001076, 0.39999987185, 12.120000046, 2.65999995336, 8.68000014544, 2.14000003546, 9.83000006199, 1.99000001535, 10.3500000916, -0.370000074357, 9.3600001128, 1.91999987915, 9.8300000903, -0.490000026524, 9.20000002012, 0.989999979585, 11.6300000851, 0.889999954998, 11.9800000843, 1.3499999322, 9.12000015408, 0.649999999255, 10.2800000113, 1.25000007153, 9.73000009701, 0.9399999699, 12.3499999262, 1.51000005171, 8.330000135, -0.500000032783, 10.3900000891, 2.10999999881, 9.84000001386, 1.25999990717, 9.42000016153, 1.17999980643, 11.7200000677, 3.1199999842, 7.96000013366, 1.49000001758, 8.01000012249, 0.799999988824, 7.71000009418, 0.179999972582, 8.09000013977, 1.87999992117, 7.65000007972, -0.460000012964, 8.33999997586, 0.0900000332296, 9.1900001502, 1.3499999322, 9.12000015408, 0.710000000298, 7.7800001961, 1.07999999493, 7.75000006035, 0.640000028759, 8.20000013113, 1.29999990836, 8.6999999918, 1.3199999924, 7.52000011757, -0.119999984205, 8.13000012159, 0.430000045598, 7.2100000912, 1.88999989316, 8.26000008747, 1.00999989748, 10.180000097, 2.13999997288, 7.05000016242, 1.55000002012, 9.1700000006, 1.42000003561, 9.21000003159, -0.350000010431, 7.37000010863, 1.27999995172, 7.50000003129, -0.380000002384, 8.69999994934, 1.21999996856, 9.40000009611, 0.649999999255, 10.2800000113, 1.07999999493, 7.75000006035, 0.539999983311, 7.87999995768, 0.260000056922, 8.61000002041, 0.17999994725, 8.56999994621, 1.78999999523, 7.67000001326, -0.0999999970198, 8.25000003204, 1.1799999629, 7.47000002891, 0.67999995172, 8.87000003338, 0.339999897629, 9.64999999404, 2.3699999477, 7.24000012338, 2.39000008985, 8.31000006288, 1.69000007346, 9.39000005409, 0.430000021011, 8.30000016615, 0.970000069141, 9.12000002146, 0.440000073463, 9.2599999921, 0.730000050813, 9.71000007555, 1.25000007153, 9.73000009701, 0.640000028759, 8.20000013113, 0.260000056922, 8.61000002041, 1.39000009805, 8.48000006348, 0.420000003576, 9.20999998763, 1.57000008702, 8.15000008792, -0.389999918491, 8.9900000973, 1.35000005811, 9.02999999791, 1.65999993697, 8.98000008881, 0.339999949038, 10.4400000772, 2.75000005811, 7.5800001052, 2.89999992549, 9.96999990001, 1.60999997869, 9.12000001177, -0.700000080466, 8.76000000775, 0.619999897033, 10.0599998677, -0.340000010878, 9.70999986097, 0.709999933243, 9.9599999921, 0.9399999699, 12.3499999262, 1.29999990836, 8.6999999918, 0.17999994725, 8.56999994621, 0.420000003576, 9.20999998763, 0.909999931753, 10.8399997821, 2.82999985933, 9.04999997243, -1.30999998242, 9.33999998704, 2.19999992028, 8.6299999249, 0.359999940693, 9.87000000507, 0.309999860227, 11.1199998985, 2.03999991849, 8.83999997213, 2.99999999702, 7.68000001654, 2.60999999732, 8.09000008762, 0.739999998212, 8.35000010654, 2.23999998257, 7.26000006363, 0.819999979734, 7.59999996498, 1.99999997243, 8.81000006884, 1.51000005171, 8.330000135, 1.3199999924, 7.52000011757, 1.78999999523, 7.67000001326, 1.57000008702, 8.15000008792, 2.82999985933, 9.04999997243, 1.79999999255, 6.80000003725, 1.20000002608, 8.33000006199, 2.41999993578, 7.21999999538, 1.51999996781, 7.84000016659, 2.0299999316, 9.82000006244, 2.72999998301, 6.55000011846, 0.900000044703, 9.07000003859, -0.169999934286, 9.64000014126, -1.29999997243, 8.48000012606, -0.289999989271, 8.81000006214, -0.820000054985, 9.41999997526, -0.680000009835, 10.1300001, -0.500000032783, 10.3900000891, -0.119999984205, 8.13000012159, -0.0999999970198, 8.25000003204, -0.389999918491, 8.9900000973, -1.30999998242, 9.33999998704, 1.20000002608, 8.33000006199, -1.48999996841, 9.14000002354, 0.150000009686, 8.78000003144, 0.459999977946, 8.5400000906, -0.850000011921, 10.2800000463, 1.31999997973, 8.00000009909, 3.65999993548, 9.43999998406, 2.13000001878, 8.51000007406, 0.829999938309, 8.81000007555, 1.75999993771, 7.93000005826, 0.229999971092, 8.589999917, 1.43999996543, 9.97000000954, 2.10999999881, 9.84000001386, 0.430000045598, 7.2100000912, 1.1799999629, 7.47000002891, 1.35000005811, 9.02999999791, 2.19999992028, 8.6299999249, 2.41999993578, 7.21999999538, 0.150000009686, 8.78000003144, 2.64999993742, 8.739999955, 1.64999995381, 8.47000004977, 1.63999988943, 10.2500000007, 3.64999997616, 8.06000010908, 1.9800000076, 8.70000013784, 2.29999995157, 9.75000013039, 0.939999921471, 8.52000015035, 1.56999996036, 8.66000006661, 0.959999866933, 8.61000006139, 0.989999976605, 10.6600001076, 1.25999990717, 9.42000016153, 1.88999989316, 8.26000008747, 0.67999995172, 8.87000003338, 1.65999993697, 8.98000008881, 0.359999940693, 9.87000000507, 1.51999996781, 7.84000016659, 0.459999977946, 8.5400000906, 1.64999995381, 8.47000004977, 2.48999982089, 8.70000016689, 2.08999981046, 11.0400000265, 2.84999997243, 7.45000016615, 2.56999992535, 10.200000114, 1.06000001296, 10.970000084, -0.270000160784, 9.610000121, 1.13999984026, 9.74000004217, -0.630000083596, 10.2599999563, 0.39999987185, 12.120000046, 1.17999980643, 11.7200000677, 1.00999989748, 10.180000097, 0.339999897629, 9.64999999404, 0.339999949038, 10.4400000772, 0.309999860227, 11.1199998985, 2.0299999316, 9.82000006244, -0.850000011921, 10.2800000463, 1.63999988943, 10.2500000007, 2.08999981046, 11.0400000265, 0.629999763966, 11.4000000522, 3.13999990061, 8.88000014395, 4.199999962, 7.9300000523, 3.30000004992, 7.40000011548, 1.43999996915, 7.34000013009, 2.73999997139, 7.02000009, 1.75999994889, 7.19000006005, 2.65999995336, 8.68000014544, 3.1199999842, 7.96000013366, 2.13999997288, 7.05000016242, 2.3699999477, 7.24000012338, 2.75000005811, 7.5800001052, 2.03999991849, 8.83999997213, 2.72999998301, 6.55000011846, 1.31999997973, 8.00000009909, 3.64999997616, 8.06000010908, 2.84999997243, 7.45000016615, 3.13999990061, 8.88000014395, 3.14999995381, 5.98000013202, 
+
+L3_cSYRK_A_kn
+0.800000011921, 0.20000000298, 0.20000000298, 0.899999976158, 0.699999988079, 0.899999976158, 0.40000000596, 0.20000000298, 0.20000000298, 0.300000011921, 0.600000023842, 0.600000023842, 0.20000000298, 0.20000000298, 0.600000023842, 0.5, 0.20000000298, 0.40000000596, 0.899999976158, 0.600000023842, 0.20000000298, 0.40000000596, 0.899999976158, 0.899999976158, 0.899999976158, 0.10000000149, 0.300000011921, 0.699999988079, 0.5, 0.5, 0.5, 0.800000011921, 0.899999976158, 0.899999976158, 0.20000000298, 0.300000011921, 0.800000011921, 0.300000011921, 0.300000011921, 0.5, 0.5, 0.5, 0.800000011921, 0.600000023842, 0.40000000596, 0.300000011921, 0.899999976158, 0.699999988079, 0.300000011921, 0.20000000298, 0.800000011921, 0.800000011921, 0.20000000298, 0.800000011921, 0.300000011921, 0.699999988079, 0.300000011921, 0.40000000596, 0.800000011921, 0.899999976158, 0.5, 0.40000000596, 0.699999988079, 0.699999988079, 0.800000011921, 0.5, 0.699999988079, 0.5, 0.300000011921, 0.899999976158, 0.600000023842, 0.699999988079, 0.40000000596, 0.600000023842, 0.899999976158, 0.40000000596, 0.5, 0.300000011921, 0.40000000596, 0.5, 0.20000000298, 0.300000011921, 0.600000023842, 0.800000011921, 0.899999976158, 0.300000011921, 0.800000011921, 0.20000000298, 0.5, 0.600000023842, 0.800000011921, 0.600000023842, 0.10000000149, 0.5, 0.600000023842, 0.899999976158, 0.10000000149, 0.899999976158, 0.600000023842, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 0.800000011921, 0.5, 0.800000011921, 0.10000000149, 0.5, 0.699999988079, 0.600000023842, 0.10000000149, 0.5, 0.10000000149, 0.40000000596, 0.40000000596, 0.20000000298, 0.699999988079, 0.40000000596, 0.40000000596, 0.300000011921, 0.300000011921, 0.300000011921, 0.699999988079, 0.40000000596, 0.5, 0.10000000149, 0.600000023842, 0.10000000149, 0.10000000149, 0.40000000596, 0.5, 0.10000000149, 0.10000000149, 0.600000023842, 0.300000011921, 0.899999976158, 0.300000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.699999988079, 0.40000000596, 0.600000023842, 0.800000011921, 0.40000000596, 0.20000000298, 0.899999976158, 0.10000000149, 0.699999988079, 0.300000011921, 0.20000000298, 0.20000000298, 0.40000000596, 0.20000000298, 0.800000011921, 0.800000011921, 0.40000000596, 0.300000011921, 0.899999976158, 0.10000000149, 0.600000023842, 0.10000000149, 0.899999976158, 0.600000023842, 0.10000000149, 0.40000000596, 0.300000011921, 0.5, 0.40000000596, 0.800000011921, 0.800000011921, 0.5, 0.899999976158, 0.300000011921, 0.699999988079, 0.800000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.300000011921, 0.10000000149, 0.800000011921, 0.20000000298, 0.300000011921, 0.699999988079, 0.899999976158, 0.600000023842, 0.899999976158, 0.699999988079, 0.300000011921, 0.20000000298, 0.10000000149, 0.40000000596, 0.899999976158, 0.40000000596, 0.300000011921, 0.600000023842, 0.899999976158, 0.899999976158, 0.300000011921, 0.600000023842, 0.5, 0.300000011921, 0.40000000596, 0.300000011921, 0.5, 0.10000000149, 0.600000023842, 0.300000011921, 0.20000000298, 0.699999988079, 0.800000011921, 0.300000011921, 0.10000000149, 0.699999988079, 0.40000000596, 0.40000000596, 0.699999988079, 0.800000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.699999988079, 0.20000000298, 0.300000011921, 0.5, 0.40000000596, 0.899999976158, 0.20000000298, 0.899999976158, 0.800000011921, 0.20000000298, 0.20000000298, 0.899999976158, 0.40000000596, 0.300000011921, 0.40000000596, 0.5, 0.40000000596, 0.300000011921, 0.600000023842, 0.10000000149, 0.5, 0.600000023842, 0.899999976158, 0.800000011921, 0.899999976158, 0.600000023842, 0.10000000149, 0.800000011921, 0.20000000298, 0.20000000298, 0.300000011921, 0.10000000149, 0.5, 0.20000000298, 0.699999988079, 0.10000000149, 0.5, 0.20000000298, 0.40000000596, 0.5, 0.5, 0.5, 0.600000023842, 0.40000000596, 0.300000011921, 0.800000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.300000011921, 0.699999988079, 0.800000011921, 0.40000000596, 0.20000000298, 0.5, 0.5, 0.40000000596, 0.699999988079, 0.600000023842, 0.899999976158, 0.10000000149, 0.699999988079, 0.10000000149, 0.899999976158, 0.899999976158, 0.600000023842, 0.300000011921, 0.5, 0.40000000596, 0.20000000298, 0.10000000149, 0.899999976158, 0.600000023842, 0.5, 0.10000000149, 0.899999976158, 0.600000023842, 0.800000011921, 0.699999988079, 0.20000000298, 0.800000011921, 0.10000000149, 0.699999988079, 0.600000023842, 0.5, 0.5, 0.300000011921, 0.300000011921, 0.800000011921, 0.600000023842, 0.10000000149, 0.5, 0.40000000596, 0.10000000149, 0.40000000596, 0.699999988079, 0.699999988079, 0.899999976158, 0.899999976158, 0.40000000596, 0.600000023842, 0.10000000149, 0.10000000149, 0.300000011921, 0.10000000149, 0.10000000149, 0.300000011921, 0.40000000596, 0.20000000298, 0.5, 0.10000000149, 0.5, 0.800000011921, 0.10000000149, 0.10000000149, 0.600000023842, 0.20000000298, 0.20000000298, 0.20000000298, 0.5, 0.800000011921, 0.600000023842, 0.600000023842, 0.800000011921, 0.20000000298, 0.40000000596, 0.899999976158, 0.800000011921, 0.899999976158, 0.800000011921, 0.5, 0.800000011921, 0.20000000298, 0.600000023842, 0.600000023842, 0.40000000596, 0.40000000596, 0.800000011921, 0.5, 0.800000011921, 0.20000000298, 0.300000011921, 0.800000011921, 0.699999988079, 0.40000000596, 0.699999988079, 0.10000000149, 0.10000000149, 0.10000000149, 0.600000023842, 0.600000023842, 0.899999976158, 0.699999988079, 0.20000000298, 0.600000023842, 0.300000011921, 0.600000023842, 0.600000023842, 0.600000023842, 0.600000023842, 0.20000000298, 0.600000023842, 0.600000023842, 0.899999976158, 0.5, 0.800000011921, 0.5, 0.40000000596, 0.899999976158, 0.40000000596, 0.899999976158, 0.699999988079, 0.20000000298, 0.300000011921, 0.10000000149, 0.20000000298, 0.300000011921, 0.699999988079, 0.800000011921, 0.699999988079, 0.5, 0.40000000596, 0.800000011921, 0.600000023842, 0.300000011921, 0.10000000149, 0.5, 0.40000000596, 0.20000000298, 0.800000011921, 0.10000000149, 0.20000000298, 0.10000000149, 0.899999976158, 0.699999988079, 0.40000000596, 0.20000000298, 0.5, 0.20000000298, 0.10000000149, 0.10000000149, 0.40000000596, 0.300000011921, 0.300000011921, 0.600000023842, 0.699999988079, 0.300000011921, 0.20000000298, 0.5, 0.800000011921, 0.600000023842, 0.5, 0.800000011921, 0.800000011921, 0.600000023842, 0.300000011921, 0.5, 0.800000011921, 0.300000011921, 0.300000011921, 0.300000011921, 0.10000000149, 0.40000000596, 0.899999976158, 0.5, 0.20000000298, 0.10000000149, 0.899999976158, 0.600000023842, 0.699999988079, 0.40000000596, 0.800000011921, 0.20000000298, 0.20000000298, 0.10000000149, 0.699999988079, 0.10000000149, 0.300000011921, 0.600000023842, 0.800000011921, 0.600000023842, 0.20000000298, 0.10000000149, 0.699999988079, 0.20000000298, 0.600000023842, 0.800000011921, 0.899999976158, 0.20000000298, 0.20000000298, 0.20000000298, 0.5, 0.800000011921, 0.5, 0.5, 0.600000023842, 0.699999988079, 0.899999976158, 0.600000023842, 0.20000000298, 0.699999988079, 0.600000023842, 0.300000011921, 0.5, 0.600000023842, 0.40000000596, 0.899999976158, 0.10000000149, 0.699999988079, 0.699999988079, 0.699999988079, 0.300000011921, 0.40000000596, 0.300000011921, 0.300000011921, 0.600000023842, 0.40000000596, 0.300000011921, 0.20000000298, 0.300000011921, 0.800000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.10000000149, 0.899999976158, 0.5, 0.40000000596, 0.600000023842, 0.40000000596, 0.5, 0.20000000298, 0.40000000596, 0.800000011921, 0.40000000596, 0.10000000149, 0.20000000298, 0.5, 0.300000011921, 0.20000000298, 0.40000000596, 0.40000000596, 0.800000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.20000000298, 0.600000023842, 0.300000011921, 0.600000023842, 0.600000023842, 0.5, 0.5, 0.800000011921, 0.20000000298, 0.20000000298, 0.20000000298, 0.300000011921, 0.600000023842, 0.10000000149, 0.699999988079, 0.20000000298, 
+
+L3_cSYRK_o_T
+0.949999980628, 8.2800001052, 0.210000005513, 8.81000012174, 0.789999962449, 8.64000018373, -0.250000049174, 9.08000008509, -0.0800000098348, 7.410000121, -0.39999993816, 8.23000010744, 0.109999996573, 6.85000005662, 0.979999960661, 9.41000010163, 0.76999998495, 7.81000015602, 2.26999994993, 7.61000017092, -0.240000042915, 6.03000011861, 1.20000000596, 8.12000012428, 0.390000051111, 6.7500001274, 0.480000086576, 9.60000014827, 1.04000000194, 6.5100001277, 0.839999994487, 7.62000018835, 0.449999999255, 8.43000007913, 0.210000005513, 8.81000012174, -1.05999982446, 8.90000014305, 0.290000062287, 9.05000018403, -0.759999983907, 9.25000008792, 1.07000004753, 8.4300001812, -0.769999973774, 9.20000013486, 0.979999950975, 7.91000007629, -0.429999985993, 8.66000009269, 1.87000000656, 8.60000009388, 0.669999984205, 10.0900001413, -0.379999993443, 7.14000016734, -0.279999887645, 8.65000002235, 0.140000074953, 9.07000014812, -0.729999799728, 10.7900000943, 0.679999988973, 6.95000016019, -0.599999918789, 7.91000015751, -0.309999907911, 9.25000009984, 0.789999962449, 8.64000018373, 0.290000062287, 9.05000018403, 0.0199999529123, 9.30000021011, -0.760000033081, 8.99000013456, 0.569999926835, 7.77000018463, -0.440000024289, 9.02000013918, -0.230000038892, 7.12000011757, 0.23999996841, 9.23000015065, 0.540000033975, 7.73000020206, 0.839999893159, 8.66000018135, -1.06000002339, 6.48000018269, -0.0499999806285, 8.87000006393, -0.869999998361, 8.25000014603, -0.189999892414, 9.88000017896, 0.259999954849, 7.00000010505, -0.430000030696, 8.4300002408, -0.199999983609, 8.71000009269, -0.250000049174, 9.08000008509, -0.759999983907, 9.25000008792, -0.760000033081, 8.99000013456, -1.5400000459, 9.02000012577, -0.530000036657, 8.59000009954, -1.86999999017, 8.19000008836, 0.0399999386072, 7.09000006005, -0.040000025034, 9.27000003189, 0.819999961853, 7.8500001438, 0.149999944866, 9.33000012904, -0.860000056177, 7.78000011042, -0.669999914914, 7.99000006005, -1.50999992952, 8.26000007257, -1.23999987081, 10.4200001042, -1.06000002861, 8.18999995947, -0.300000059605, 7.88000013128, -0.530000068694, 9.0100000532, -0.0800000098348, 7.410000121, 1.07000004753, 8.4300001812, 0.569999926835, 7.77000018463, -0.530000036657, 8.59000009954, 0.749999932945, 8.0600001657, -0.710000037551, 7.89000013381, -3.2037498876e-08, 6.73000008136, -0.109999992847, 7.62000012055, 0.839999973625, 7.46000019327, 1.00999995261, 8.19000018671, -0.349999984354, 6.96000010908, 0.220000010282, 7.05000013262, -0.519999961108, 8.25000014901, 0.27000011757, 9.12000015929, 0.679999966621, 6.99000007793, 0.659999983907, 7.48000019386, 0.429999988973, 8.28000010446, -0.39999993816, 8.23000010744, -0.769999973774, 9.20000013486, -0.440000024289, 9.02000013918, -1.86999999017, 8.19000008836, -0.710000037551, 7.89000013381, -0.930000063479, 7.76000015974, -0.54999999553, 7.19000006378, -0.720000002086, 8.5400000906, 0.329999990463, 8.02000012949, 0.0099999473989, 9.05000011697, -0.970000003576, 6.23000015661, -0.840000025779, 6.89000011593, -1.41999993578, 7.42000010341, -1.28999991477, 9.79000014797, -1.14000000045, 7.44000006303, -1.66000003085, 8.41000015751, -0.220000008792, 9.15000009537, 0.109999996573, 6.85000005662, 0.979999950975, 7.91000007629, -0.230000038892, 7.12000011757, 0.0399999386072, 7.09000006005, -3.2037498876e-08, 6.73000008136, -0.54999999553, 7.19000006378, -0.560000046492, 6.75999996603, 0.449999912083, 7.89000000641, 1.41999994397, 7.07000009149, 0.159999942929, 7.20000006482, -0.449999964982, 5.90000009388, -0.249999984354, 5.94000008985, -0.58999990806, 7.21000003904, 0.370000016987, 7.61000005618, -0.0800000083447, 6.26999997526, 0.449999926984, 7.26000007629, 0.389999996722, 6.99000000939, 0.979999960661, 9.41000010163, -0.429999985993, 8.66000009269, 0.23999996841, 9.23000015065, -0.040000025034, 9.27000003189, -0.109999992847, 7.62000012055, -0.720000002086, 8.5400000906, 0.449999912083, 7.89000000641, 0.739999944568, 10.1600000882, 1.23000000611, 8.37000010341, 1.17999992266, 8.28000014916, -0.660000056922, 7.50000010803, -0.379999919683, 8.92000010267, -0.310000009984, 7.90000005439, -0.98999985218, 9.84000011072, 1.39999991432, 6.87000006244, 0.680000030696, 8.25000014752, 0.709999949634, 9.13000010669, 0.76999998495, 7.81000015602, 1.87000000656, 8.60000009388, 0.540000033975, 7.73000020206, 0.819999961853, 7.8500001438, 0.839999973625, 7.46000019327, 0.329999990463, 8.02000012949, 1.41999994397, 7.07000009149, 1.23000000611, 8.37000010341, 1.72999999195, 7.52000013024, 1.36999990597, 8.10000009164, -0.100000018626, 5.79000016585, -0.00999992877245, 7.09000015318, 0.230000067204, 7.72000009149, 0.890000088364, 9.280000135, 0.490000030249, 7.40000000224, 0.830000001639, 8.1200002189, 1.12999998972, 8.08000014395, 2.26999994993, 7.61000017092, 0.669999984205, 10.0900001413, 0.839999893159, 8.66000018135, 0.149999944866, 9.33000012904, 1.00999995261, 8.19000018671, 0.0099999473989, 9.05000011697, 0.159999942929, 7.20000006482, 1.17999992266, 8.28000014916, 1.36999990597, 8.10000009164, 1.39999985695, 9.32000014067, 0.389999950528, 6.27000018165, 1.29999993891, 8.450000076, 0.100000011921, 8.77000015557, 1.11000006512, 10.9400000958, 0.549999943376, 7.86000006512, 0.209999930263, 8.18000018418, 1.04999997169, 9.63000015885, -0.240000042915, 6.03000011861, -0.379999993443, 7.14000016734, -1.06000002339, 6.48000018269, -0.860000056177, 7.78000011042, -0.349999984354, 6.96000010908, -0.970000003576, 6.23000015661, -0.449999964982, 5.90000009388, -0.660000056922, 7.50000010803, -0.100000018626, 5.79000016585, 0.389999950528, 6.27000018165, -0.760000004768, 5.22000016004, 0.119999974519, 6.81000013888, -1.40999990642, 6.26000014186, -0.379999939054, 7.29000016138, -0.709999989122, 5.41000006586, -0.450000012666, 6.31000018358, -0.949999977648, 7.92000004902, 1.20000000596, 8.12000012428, -0.279999887645, 8.65000002235, -0.0499999806285, 8.87000006393, -0.669999914914, 7.99000006005, 0.220000010282, 7.05000013262, -0.840000025779, 6.89000011593, -0.249999984354, 5.94000008985, -0.379999919683, 8.92000010267, -0.00999992877245, 7.09000015318, 1.29999993891, 8.450000076, 0.119999974519, 6.81000013888, -0.769999900758, 7.82000006318, -0.389999926686, 7.05000008419, -0.419999881387, 9.59000013456, -0.749999950081, 7.45000004098, 0.0900000585616, 8.25000008345, -0.109999983907, 9.53000002325, 0.390000051111, 6.7500001274, 0.140000074953, 9.07000014812, -0.869999998361, 8.25000014603, -1.50999992952, 8.26000007257, -0.519999961108, 8.25000014901, -1.41999993578, 7.42000010341, -0.58999990806, 7.21000003904, -0.310000009984, 7.90000005439, 0.230000067204, 7.72000009149, 0.100000011921, 8.77000015557, -1.40999990642, 6.26000014186, -0.389999926686, 7.05000008419, -1.11999979645, 7.54000008017, -1.21999985531, 9.08000013351, -0.179999889135, 6.4400000295, 0.100000017136, 8.58000016034, 0.8400000377, 9.27000001326, 0.480000086576, 9.60000014827, -0.729999799728, 10.7900000943, -0.189999892414, 9.88000017896, -1.23999987081, 10.4200001042, 0.27000011757, 9.12000015929, -1.28999991477, 9.79000014797, 0.370000016987, 7.61000005618, -0.98999985218, 9.84000011072, 0.890000088364, 9.280000135, 1.11000006512, 10.9400000958, -0.379999939054, 7.29000016138, -0.419999881387, 9.59000013456, -1.21999985531, 9.08000013351, 0.0700002688169, 12.3000001565, -0.0299999114871, 8.460000083, -0.459999866933, 9.72000015035, -0.0899998566508, 10.2400001331, 1.04000000194, 6.5100001277, 0.679999988973, 6.95000016019, 0.259999954849, 7.00000010505, -1.06000002861, 8.18999995947, 0.679999966621, 6.99000007793, -1.14000000045, 7.44000006303, -0.0800000083447, 6.26999997526, 1.39999991432, 6.87000006244, 0.490000030249, 7.40000000224, 0.549999943376, 7.86000006512, -0.709999989122, 5.41000006586, -0.749999950081, 7.45000004098, -0.179999889135, 6.4400000295, -0.0299999114871, 8.460000083, 0.130000030696, 5.5200000602, 1.22999999791, 7.5000001274, 0.249999992549, 7.21000004128, 0.839999994487, 7.62000018835, -0.599999918789, 7.91000015751, -0.430000030696, 8.4300002408, -0.300000059605, 7.88000013128, 0.659999983907, 7.48000019386, -1.66000003085, 8.41000015751, 0.449999926984, 7.26000007629, 0.680000030696, 8.25000014752, 0.830000001639, 8.1200002189, 0.209999930263, 8.18000018418, -0.450000012666, 6.31000018358, 0.0900000585616, 8.25000008345, 0.100000017136, 8.58000016034, -0.459999866933, 9.72000015035, 1.22999999791, 7.5000001274, -0.0199999782443, 6.16000018656, 0.289999990761, 7.8000001736, 0.449999999255, 8.43000007913, -0.309999907911, 9.25000009984, -0.199999983609, 8.71000009269, -0.530000068694, 9.0100000532, 0.429999988973, 8.28000010446, -0.220000008792, 9.15000009537, 0.389999996722, 6.99000000939, 0.709999949634, 9.13000010669, 1.12999998972, 8.08000014395, 1.04999997169, 9.63000015885, -0.949999977648, 7.92000004902, -0.109999983907, 9.53000002325, 0.8400000377, 9.27000001326, -0.0899998566508, 10.2400001331, 0.249999992549, 7.21000004128, 0.289999990761, 7.8000001736, -0.160000004768, 9.08000005454, 
+
+L3_zSYRK_A_nk
+0.5, 0.7, 0.8, 0.2, 0.4, 0.8, 0.2, 0.1, 0.4, 0.6, 0.2, 0.5, 0.7, 0.7, 0.8, 0.1, 0.1, 0.6, 0.8, 0.8, 0.3, 0.9, 0.9, 0.1, 0.4, 0.8, 0.6, 0.6, 0.2, 0.4, 0.2, 0.3, 0.2, 0.2, 0.5, 0.5, 0.6, 0.7, 0.8, 0.9, 0.5, 0.1, 0.7, 0.1, 0.9, 0.7, 0.1, 0.1, 0.5, 0.6, 0.8, 0.8, 0.6, 0.2, 0.7, 0.1, 0.2, 0.6, 0.3, 0.6, 0.1, 0.7, 0.8, 0.4, 0.5, 0.7, 0.1, 0.3, 0.9, 0.2, 0.4, 0.6, 0.2, 0.9, 0.2, 0.7, 0.9, 0.2, 0.2, 0.8, 0.5, 0.8, 0.6, 0.4, 0.8, 0.3, 0.6, 0.5, 0.9, 0.8, 0.6, 0.5, 0.8, 0.5, 0.4, 0.7, 0.4, 0.8, 0.9, 0.9, 0.3, 0.6, 0.5, 0.9, 0.8, 0.3, 0.7, 0.5, 0.1, 0.6, 0.2, 0.5, 0.5, 0.6, 0.3, 0.1, 0.2, 0.9, 0.8, 0.7, 0.8, 0.2, 0.9, 0.4, 0.1, 0.5, 0.2, 0.1, 0.6, 0.8, 0.3, 0.3, 0.8, 0.3, 0.3, 0.6, 0.5, 0.5, 0.6, 0.8, 0.8, 0.4, 0.6, 0.2, 0.4, 0.3, 0.2, 0.5, 0.3, 0.1, 0.5, 0.9, 0.6, 0.8, 0.3, 0.6, 0.2, 0.1, 0.7, 0.9, 0.6, 0.4, 0.4, 0.3, 0.3, 0.1, 0.3, 0.8, 0.2, 0.4, 0.2, 0.9, 0.1, 0.7, 0.3, 0.7, 0.2, 0.4, 0.8, 0.9, 0.4, 0.4, 0.4, 0.5, 0.8, 0.8, 0.9, 0.8, 0.8, 0.5, 0.4, 0.7, 0.3, 0.4, 0.1, 0.9, 0.7, 0.4, 0.5, 0.4, 0.9, 0.7, 0.9, 0.5, 0.1, 0.1, 0.9, 0.9, 0.4, 0.2, 0.3, 0.4, 0.8, 0.4, 0.6, 0.3, 0.1, 0.2, 0.1, 0.8, 0.7, 0.3, 0.3, 0.3, 0.2, 0.9, 0.4, 0.3, 0.4, 0.1, 0.2, 0.9, 0.2, 0.1, 0.6, 0.6, 0.1, 0.7, 0.7, 0.6, 0.5, 0.6, 0.7, 0.7, 0.8, 0.5, 0.4, 0.7, 0.3, 0.2, 0.7, 0.6, 0.8, 0.3, 0.4, 0.5, 0.2, 0.7, 0.2, 0.5, 0.6, 0.4, 0.2, 0.9, 0.9, 0.4, 0.4, 0.1, 0.7, 0.4, 0.9, 0.6, 0.2, 0.2, 0.4, 0.8, 0.4, 0.5, 0.1, 0.6, 0.5, 0.8, 0.5, 0.7, 0.8, 0.3, 0.4, 0.6, 0.8, 0.3, 0.3, 0.7, 0.3, 0.2, 0.5, 0.3, 0.9, 0.7, 0.2, 0.1, 0.6, 0.7, 0.6, 0.9, 0.3, 0.7, 0.8, 0.7, 0.1, 0.5, 0.6, 0.6, 0.7, 0.5, 0.7, 0.5, 0.1, 0.6, 0.5, 0.2, 0.7, 0.5, 0.2, 0.9, 0.5, 0.6, 0.4, 0.3, 0.2, 0.8, 0.8, 0.9, 0.2, 0.1, 0.7, 0.7, 0.7, 0.4, 0.2, 0.5, 0.9, 0.6, 0.5, 0.2, 0.8, 0.4, 0.7, 0.1, 0.2, 0.7, 0.9, 0.9, 0.8, 0.1, 0.6, 0.7, 0.8, 0.6, 0.2, 0.1, 0.8, 0.6, 0.7, 0.4, 0.6, 0.2, 0.4, 0.8, 0.1, 0.8, 0.3, 0.1, 0.6, 0.9, 0.8, 0.3, 0.3, 0.4, 0.5, 0.1, 0.9, 0.6, 0.6, 0.5, 0.5, 0.4, 0.8, 0.4, 0.1, 0.4, 0.1, 0.6, 0.6, 0.9, 0.8, 0.4, 0.3, 0.8, 0.6, 0.3, 0.5, 0.1, 0.2, 0.3, 0.2, 0.4, 0.9, 0.2, 0.5, 0.5, 0.6, 0.7, 0.6, 0.2, 0.1, 0.8, 0.8, 0.4, 0.8, 0.6, 0.3, 0.5, 0.3, 0.6, 0.4, 0.9, 0.8, 0.7, 0.9, 0.3, 0.5, 0.9, 0.2, 0.8, 0.7, 0.9, 0.2, 0.9, 0.7, 0.6, 0.6, 0.1, 0.1, 0.8, 0.5, 0.3, 0.3, 0.3, 0.3, 0.4, 0.2, 0.3, 0.3, 0.7, 0.8, 0.8, 0.4, 0.4, 0.3, 0.8, 0.3, 0.2, 0.1, 0.3, 0.6, 0.5, 0.8, 0.7, 0.6, 0.7, 0.9, 0.3, 0.4, 0.4, 0.6, 0.6, 0.2, 0.2, 0.1, 0.7, 0.1, 0.2, 0.3, 0.8, 0.8, 0.3, 0.1, 0.4, 0.8, 0.9, 0.3, 0.2, 0.3, 0.5, 0.8, 0.3, 0.8, 0.7, 0.3, 0.6, 0.2, 0.8, 0.7, 0.7, 0.5, 0.1, 0.8, 0.8, 0.4, 0.9, 0.1, 0.8, 0.9, 0.8, 0.7, 0.4, 0.3, 0.5, 0.1, 0.4, 0.7, 0.4, 0.1, 0.1, 0.1, 0.9, 0.7, 0.9, 0.7, 0.8, 0.4, 0.5, 0.9, 0.3, 0.5, 0.3, 0.7, 0.5, 0.9, 0.7, 0.2, 0.6, 0.1, 0.2, 
+
+L3_zSYRK_C_nn
+0.1, 0.5, 0.3, 0.9, 0.1, 0.7, 0.4, 0.9, 0.7, 0.4, 0.2, 0.4, 0.3, 0.5, 0.6, 0.8, 0.2, 0.9, 0.4, 0.8, 0.5, 0.1, 0.8, 0.1, 0.1, 0.4, 0.3, 0.4, 0.7, 0.3, 0.1, 0.9, 0.6, 0.7, 0.3, 0.9, 0.2, 0.4, 0.5, 0.5, 0.7, 0.7, 0.1, 0.8, 0.3, 0.9, 0.6, 0.6, 0.1, 0.4, 0.4, 0.3, 0.9, 0.7, 0.1, 0.3, 0.4, 0.3, 0.7, 0.9, 0.2, 0.2, 0.5, 0.7, 0.5, 0.6, 0.2, 0.9, 0.1, 0.7, 0.5, 0.5, 0.8, 0.9, 0.1, 0.6, 0.8, 0.1, 0.7, 0.3, 0.8, 0.9, 0.5, 0.8, 0.6, 0.4, 0.6, 0.6, 0.4, 0.2, 0.2, 0.3, 0.8, 0.6, 0.8, 0.5, 0.9, 0.2, 0.1, 0.4, 0.6, 0.6, 0.4, 0.9, 0.7, 0.7, 0.1, 0.6, 0.5, 0.7, 0.8, 0.2, 0.9, 0.3, 0.9, 0.5, 0.4, 0.3, 0.6, 0.4, 0.4, 0.5, 0.7, 0.2, 0.6, 0.2, 0.9, 0.1, 0.4, 0.1, 0.1, 0.3, 0.9, 0.5, 0.2, 0.5, 0.7, 0.4, 0.1, 0.8, 0.8, 0.1, 0.8, 0.2, 0.7, 0.3, 0.3, 0.5, 0.1, 0.8, 0.5, 0.1, 0.3, 0.2, 0.9, 0.5, 0.8, 0.7, 0.2, 0.7, 0.9, 0.8, 0.2, 0.2, 0.1, 0.8, 0.5, 0.2, 0.8, 0.1, 0.2, 0.4, 0.3, 0.9, 0.7, 0.3, 0.9, 0.3, 0.3, 0.5, 0.2, 0.8, 0.9, 0.1, 0.4, 0.2, 0.4, 0.5, 0.4, 0.2, 0.7, 0.4, 0.4, 0.3, 0.2, 0.1, 0.9, 0.7, 0.8, 0.2, 0.3, 0.3, 0.9, 0.8, 0.3, 0.5, 0.6, 0.6, 0.8, 0.9, 0.9, 0.5, 0.1, 0.8, 0.9, 0.1, 0.5, 0.6, 0.7, 0.8, 0.4, 0.2, 0.8, 0.3, 0.5, 0.9, 0.6, 0.1, 0.5, 0.7, 0.2, 0.2, 0.7, 0.1, 0.9, 0.6, 0.7, 0.7, 0.6, 0.8, 0.1, 0.4, 0.5, 0.8, 0.4, 0.3, 0.5, 0.1, 0.4, 0.2, 0.7, 0.8, 0.4, 0.3, 0.1, 0.3, 0.4, 0.5, 0.3, 0.3, 0.2, 0.9, 0.9, 0.7, 0.4, 0.8, 0.6, 0.3, 0.1, 0.5, 0.8, 0.4, 0.2, 0.9, 0.4, 0.3, 0.6, 0.4, 0.6, 0.4, 0.3, 0.2, 0.4, 0.5, 0.4, 0.2, 0.1, 0.3, 0.5, 0.7, 0.6, 0.1, 0.4, 0.2, 0.2, 0.3, 0.4, 0.8, 0.8, 0.7, 0.7, 0.1, 0.9, 0.6, 0.8, 0.4, 0.4, 0.8, 0.9, 0.7, 0.6, 0.6, 0.4, 0.5, 0.9, 0.5, 0.4, 0.2, 0.8, 0.3, 0.4, 0.5, 0.6, 0.1, 0.2, 0.5, 0.1, 0.9, 0.6, 0.5, 0.6, 0.3, 0.6, 0.9, 0.8, 0.4, 0.4, 0.7, 0.5, 0.1, 0.5, 0.1, 0.1, 0.3, 0.4, 0.2, 0.7, 0.2, 0.8, 0.7, 0.7, 0.4, 0.5, 0.9, 0.3, 0.3, 0.4, 0.2, 0.1, 0.9, 0.8, 0.4, 0.6, 0.7, 0.9, 0.4, 0.4, 0.2, 0.5, 0.8, 0.4, 0.8, 0.7, 0.9, 0.8, 0.1, 0.4, 0.3, 0.2, 0.3, 0.6, 0.2, 0.2, 0.7, 0.4, 0.3, 0.6, 0.1, 0.2, 0.9, 0.2, 0.3, 0.6, 0.5, 0.6, 0.7, 0.8, 0.1, 0.3, 0.2, 0.3, 0.3, 0.6, 0.1, 0.5, 0.1, 0.1, 0.2, 0.1, 0.4, 0.7, 0.9, 0.8, 0.6, 0.9, 0.1, 0.9, 0.8, 0.2, 0.1, 0.5, 0.7, 0.9, 0.7, 0.4, 0.8, 0.6, 0.3, 0.9, 0.4, 0.3, 0.2, 0.6, 0.9, 0.6, 0.1, 0.2, 0.5, 0.8, 0.9, 0.3, 0.3, 0.3, 0.4, 0.2, 0.2, 0.8, 0.5, 0.4, 0.1, 0.2, 0.2, 0.9, 0.7, 0.2, 0.2, 0.4, 0.8, 0.8, 0.7, 0.6, 0.9, 0.4, 0.2, 0.3, 0.3, 0.6, 0.1, 0.4, 0.5, 0.1, 0.9, 0.2, 0.3, 0.3, 0.4, 0.7, 0.3, 0.5, 0.7, 0.9, 0.2, 0.1, 0.3, 0.1, 0.8, 0.8, 0.2, 0.7, 0.1, 0.6, 0.3, 0.7, 0.1, 0.8, 0.4, 0.5, 0.8, 0.6, 0.1, 0.2, 0.5, 0.1, 0.9, 0.9, 0.3, 0.5, 0.5, 0.7, 0.5, 0.1, 0.9, 0.5, 0.6, 0.1, 0.4, 0.9, 0.5, 0.5, 0.2, 0.3, 0.3, 0.9, 0.6, 0.1, 0.5, 0.9, 0.6, 0.4, 0.7, 0.4, 0.8, 0.5, 0.1, 0.8, 0.9, 0.2, 0.3, 0.5, 0.5, 0.2, 0.9, 0.1, 0.5, 0.6, 0.7, 0.2, 0.9, 0.6, 0.6, 0.2, 0.5, 0.8, 0.1, 0.9, 0.8, 0.7, 0.7, 0.8, 0.4, 0.8, 0.4, 0.5, 0.1, 0.7, 0.9, 0.1, 0.2, 0.3, 0.3, 0.3, 0.4, 0.7, 0.5, 0.1, 0.5, 0.1, 0.6, 
+
+L3_zSYRK_o_N
+-0.69, 7.78, 0.26, 8.42, -0.3, 9.65, 0.06, 8.71, 0.33, 8.27, -0.98, 8.67, 0.27, 8.0, 0.04, 8.68, -0.58, 9.15, 0.54, 9.31, -0.1, 8.39, 1.46, 7.84, 0.03, 7.2, -0.29, 9.15, -0.21, 7.27, -0.7, 8.85, 0.28, 9.29, 0.26, 8.42, 1.04, 8.42, 1.3, 9.21, 0.75, 8.44, 0.77, 8.57, -0.9, 9.44, 1.56, 6.81, -0.15, 8.27, -0.25, 7.98, 1.29, 8.28, 0.9, 8.11, 2.07, 7.41, 0.71, 7.8, 0.47, 8.79, 0.68, 8.61, -0.22, 8.55, -0.39, 7.93, -0.3, 9.65, 1.3, 9.21, 0.81, 9.58, -0.67, 9.71, 0.19, 8.61, -0.53, 9.14, 0.53, 8.61, -0.12, 9.17, -0.06, 9.27, 0.2, 9.69, 0.05, 9.32, 1.02, 8.81, 0.17, 8.87, -0.37, 9.55, 0.37, 8.17, -0.81, 9.37, 0.18, 9.95, 0.06, 8.71, 0.75, 8.44, -0.67, 9.71, -0.19, 9.04, 0.34, 8.65, -0.09, 8.28, 0.37, 8.68, -1.0, 7.96, -0.71, 8.14, 0.19, 8.29, 0.38, 8.81, 0.83, 8.41, 1.47, 7.88, -0.93, 9.31, -0.47, 8.02, 0.01, 8.56, 0.04, 8.69, 0.33, 8.27, 0.77, 8.57, 0.19, 8.61, 0.34, 8.65, -0.24, 8.64, -1.78, 8.6, 0.4, 7.62, -0.83, 7.32, -0.58, 7.44, 1.21, 8.8, 0.96, 9.57, 1.78, 8.75, 0.32, 8.5, -0.22, 8.86, -1.19, 8.29, -0.09, 7.54, 0.59, 8.02, -0.98, 8.67, -0.9, 9.44, -0.53, 9.14, -0.09, 8.28, -1.78, 8.6, -1.92, 9.54, -0.28, 7.6, -1.18, 8.26, -1.56, 9.03, -0.58, 8.78, -0.24, 9.16, 0.71, 7.97, -0.95, 7.52, -1.16, 9.62, -0.83, 7.9, -1.51, 8.35, 0.05, 8.87, 0.27, 8.0, 1.56, 6.81, 0.53, 8.61, 0.37, 8.68, 0.4, 7.62, -0.28, 7.6, 1.47, 7.98, 1.03, 8.13, 0.52, 7.38, 0.37, 7.9, 0.51, 9.39, 1.86, 8.3, 0.78, 7.74, -0.98, 8.92, 0.36, 7.0, 0.53, 8.53, 0.67, 8.46, 0.04, 8.68, -0.15, 8.27, -0.12, 9.17, -1.0, 7.96, -0.83, 7.32, -1.18, 8.26, 1.03, 8.13, -0.65, 7.86, -1.03, 7.44, -0.5, 8.75, 0.5, 9.09, 1.19, 8.96, 0.71, 7.47, -1.25, 10.03, -0.46, 8.1, -0.82, 8.27, 0.18, 8.22, -0.58, 9.15, -0.25, 7.98, -0.06, 9.27, -0.71, 8.14, -0.58, 7.44, -1.56, 9.03, 0.52, 7.38, -1.03, 7.44, -0.35, 8.16, 0.03, 8.94, -0.09, 8.98, 1.27, 8.41, -0.32, 8.16, -0.55, 9.43, -0.95, 7.52, 0.08, 8.47, -0.07, 8.99, 0.54, 9.31, 1.29, 8.28, 0.2, 9.69, 0.19, 8.29, 1.21, 8.8, -0.58, 8.78, 0.37, 7.9, -0.5, 8.75, 0.03, 8.94, 0.18, 9.12, -0.01, 8.84, 1.02, 7.9, 0.67, 8.47, -0.4, 9.99, 0.83, 7.87, -0.73, 9.18, 0.1, 9.03, -0.1, 8.39, 0.9, 8.11, 0.05, 9.32, 0.38, 8.81, 0.96, 9.57, -0.24, 9.16, 0.51, 9.39, 0.5, 9.09, -0.09, 8.98, -0.01, 8.84, 0.78, 9.8, 0.76, 9.93, 0.84, 8.39, -0.89, 9.77, -0.31, 8.53, -0.68, 8.99, 1.35, 9.35, 1.46, 7.84, 2.07, 7.41, 1.02, 8.81, 0.83, 8.41, 1.78, 8.75, 0.71, 7.97, 1.86, 8.3, 1.19, 8.96, 1.27, 8.41, 1.02, 7.9, 0.76, 9.93, 2.34, 8.3, 1.7, 7.9, 0.52, 8.81, 0.68, 7.07, 0.22, 8.99, 0.84, 8.57, 0.03, 7.2, 0.71, 7.8, 0.17, 8.87, 1.47, 7.88, 0.32, 8.5, -0.95, 7.52, 0.78, 7.74, 0.71, 7.47, -0.32, 8.16, 0.67, 8.47, 0.84, 8.39, 1.7, 7.9, 0.82, 7.18, 0.45, 8.31, -0.46, 6.77, 0.3, 8.37, 0.64, 7.65, -0.29, 9.15, 0.47, 8.79, -0.37, 9.55, -0.93, 9.31, -0.22, 8.86, -1.16, 9.62, -0.98, 8.92, -1.25, 10.03, -0.55, 9.43, -0.4, 9.99, -0.89, 9.77, 0.52, 8.81, 0.45, 8.31, -1.29, 9.58, -1.64, 9.1, -2.19, 9.24, -0.86, 9.9, -0.21, 7.27, 0.68, 8.61, 0.37, 8.17, -0.47, 8.02, -1.19, 8.29, -0.83, 7.9, 0.36, 7.0, -0.46, 8.1, -0.95, 7.52, 0.83, 7.87, -0.31, 8.53, 0.68, 7.07, -0.46, 6.77, -1.64, 9.1, 0.17, 7.7, -0.63, 7.94, 0.56, 7.72, -0.7, 8.85, -0.22, 8.55, -0.81, 9.37, 0.01, 8.56, -0.09, 7.54, -1.51, 8.35, 0.53, 8.53, -0.82, 8.27, 0.08, 8.47, -0.73, 9.18, -0.68, 8.99, 0.22, 8.99, 0.3, 8.37, -2.19, 9.24, -0.63, 7.94, -1.47, 9.36, -0.31, 9.24, 0.28, 9.29, -0.39, 7.93, 0.18, 9.95, 0.04, 8.69, 0.59, 8.02, 0.05, 8.87, 0.67, 8.46, 0.18, 8.22, -0.07, 8.99, 0.1, 9.03, 1.35, 9.35, 0.84, 8.57, 0.64, 7.65, -0.86, 9.9, 0.56, 7.72, -0.31, 9.24, 0.35, 9.6, 
+
+L3_zSYRK_A_kn
+0.4, 0.8, 0.7, 0.6, 0.9, 0.3, 0.7, 0.9, 0.7, 0.6, 0.3, 0.8, 0.7, 0.1, 0.8, 0.7, 0.1, 0.8, 0.4, 0.9, 0.3, 0.2, 0.7, 0.5, 0.1, 0.6, 0.7, 0.6, 0.4, 0.2, 0.6, 0.6, 0.9, 0.3, 0.4, 0.6, 0.4, 0.3, 0.2, 0.6, 0.4, 0.2, 0.3, 0.3, 0.2, 0.9, 0.8, 0.4, 0.6, 0.4, 0.1, 0.3, 0.2, 0.4, 0.8, 0.4, 0.1, 0.1, 0.4, 0.6, 0.9, 0.5, 0.6, 0.2, 0.3, 0.2, 0.8, 0.9, 0.2, 0.3, 0.9, 0.1, 0.3, 0.3, 0.7, 0.5, 0.1, 0.1, 0.6, 0.2, 0.1, 0.5, 0.2, 0.2, 0.1, 0.6, 0.3, 0.7, 0.1, 0.7, 0.5, 0.2, 0.8, 0.3, 0.8, 0.3, 0.7, 0.5, 0.8, 0.7, 0.7, 0.3, 0.4, 0.9, 0.3, 0.1, 0.6, 0.4, 0.9, 0.2, 0.1, 0.5, 0.5, 0.3, 0.8, 0.9, 0.5, 0.7, 0.2, 0.9, 0.9, 0.5, 0.3, 0.3, 0.3, 0.6, 0.6, 0.2, 0.2, 0.3, 0.2, 0.3, 0.1, 0.5, 0.4, 0.9, 0.1, 0.1, 0.6, 0.4, 0.8, 0.1, 0.6, 0.3, 0.1, 0.7, 0.9, 0.9, 0.8, 0.4, 0.9, 0.3, 0.5, 0.7, 0.8, 0.6, 0.4, 0.1, 0.8, 0.8, 0.6, 0.7, 0.2, 0.8, 0.8, 0.4, 0.6, 0.3, 0.6, 0.4, 0.3, 0.2, 0.3, 0.8, 0.3, 0.9, 0.2, 0.6, 0.7, 0.1, 0.1, 0.6, 0.4, 0.8, 0.3, 0.1, 0.4, 0.6, 0.4, 0.5, 0.5, 0.2, 0.3, 0.6, 0.5, 0.1, 0.7, 0.8, 0.2, 0.9, 0.2, 0.6, 0.9, 0.6, 0.7, 0.2, 0.3, 0.4, 0.3, 0.2, 0.1, 0.3, 0.4, 0.5, 0.2, 0.7, 0.9, 0.6, 0.3, 0.9, 0.1, 0.4, 0.7, 0.7, 0.7, 0.6, 0.6, 0.1, 0.9, 0.4, 0.7, 0.4, 0.3, 0.9, 0.6, 0.4, 0.3, 0.4, 0.5, 0.8, 0.3, 0.3, 0.4, 0.8, 0.5, 0.6, 0.2, 0.3, 0.5, 0.9, 0.4, 0.6, 0.5, 0.6, 0.1, 0.7, 0.3, 0.9, 0.8, 0.8, 0.8, 0.6, 0.8, 0.1, 0.3, 0.5, 0.1, 0.6, 0.7, 0.6, 0.1, 0.6, 0.4, 0.9, 0.7, 0.3, 0.8, 0.5, 0.5, 0.5, 0.7, 0.7, 0.1, 0.7, 0.3, 0.5, 0.7, 0.6, 0.6, 0.8, 0.5, 0.2, 0.6, 0.9, 0.9, 0.4, 0.6, 0.4, 0.9, 0.8, 0.8, 0.2, 0.9, 0.6, 0.6, 0.8, 0.1, 0.7, 0.6, 0.1, 0.5, 0.8, 0.8, 0.9, 0.4, 0.4, 0.3, 0.5, 0.9, 0.6, 0.2, 0.7, 0.6, 0.7, 0.9, 0.3, 0.5, 0.2, 0.6, 0.5, 0.8, 0.1, 0.3, 0.3, 0.3, 0.2, 0.6, 0.7, 0.9, 0.5, 0.3, 0.3, 0.6, 0.6, 0.4, 0.1, 0.2, 0.8, 0.9, 0.9, 0.7, 0.6, 0.6, 0.6, 0.6, 0.7, 0.3, 0.4, 0.3, 0.8, 0.4, 0.1, 0.7, 0.8, 0.4, 0.2, 0.5, 0.5, 0.3, 0.8, 0.6, 0.3, 0.1, 0.2, 0.2, 0.3, 0.1, 0.9, 0.6, 0.2, 0.7, 0.6, 0.9, 0.9, 0.4, 0.2, 0.9, 0.8, 0.4, 0.8, 0.6, 0.9, 0.6, 0.1, 0.9, 0.3, 0.2, 0.9, 0.6, 0.4, 0.7, 0.3, 0.8, 0.2, 0.4, 0.3, 0.1, 0.9, 0.1, 0.3, 0.9, 0.2, 0.6, 0.3, 0.7, 0.8, 0.4, 0.9, 0.4, 0.2, 0.4, 0.6, 0.8, 0.9, 0.4, 0.8, 0.3, 0.3, 0.6, 0.7, 0.7, 0.6, 0.2, 0.2, 0.5, 0.7, 0.7, 0.9, 0.9, 0.1, 0.5, 0.4, 0.1, 0.4, 0.7, 0.2, 0.8, 0.6, 0.3, 0.9, 0.6, 0.9, 0.5, 0.3, 0.1, 0.1, 0.4, 0.2, 0.6, 0.2, 0.4, 0.4, 0.7, 0.1, 0.4, 0.8, 0.6, 0.9, 0.6, 0.5, 0.8, 0.5, 0.9, 0.6, 0.6, 0.8, 0.8, 0.7, 0.3, 0.9, 0.2, 0.4, 0.4, 0.5, 0.5, 0.9, 0.6, 0.5, 0.5, 0.2, 0.6, 0.3, 0.2, 0.6, 0.6, 0.4, 0.4, 0.1, 0.7, 0.3, 0.3, 0.6, 0.3, 0.6, 0.1, 0.1, 0.1, 0.7, 0.5, 0.1, 0.9, 0.8, 0.7, 0.8, 0.7, 0.1, 0.5, 0.4, 0.8, 0.7, 0.7, 0.7, 0.1, 0.5, 0.3, 0.5, 0.7, 0.4, 0.7, 0.5, 0.4, 0.4, 0.4, 0.3, 0.4, 0.9, 0.6, 0.8, 0.6, 0.2, 0.7, 0.3, 0.6, 0.6, 
+
+L3_zSYRK_o_T
+-2.26, 7.54, -0.38, 8.34, -0.75, 7.51, -1.5, 8.45, -1.09, 7.93, -2.1, 7.55, -0.75, 7.83, -1.17, 8.28, -3.23, 7.2, -0.65, 8.48, 0.16, 6.76, 0.1, 7.15, -0.35, 7.47, -0.88, 8.27, 0.19, 6.37, -1.06, 8.27, -1.19, 8.35, -0.38, 8.34, 1.16, 6.84, 2.65, 7.34, 1.24, 8.99, -0.36, 10.07, 0.05, 8.63, 1.03, 8.41, 0.85, 8.4, -0.78, 7.96, 1.52, 8.72, 1.92, 7.47, 1.61, 8.14, 1.79, 7.96, 0.92, 8.96, 2.06, 7.69, 2.76, 7.97, 1.54, 8.74, -0.75, 7.51, 2.65, 7.34, 2.26, 7.34, 0.8, 8.91, 1.84, 8.52, 0.69, 7.41, 1.79, 8.47, 1.85, 8.55, -0.07, 8.04, 1.89, 8.09, 2.14, 7.04, 1.69, 8.44, 2.79, 8.26, 1.87, 8.95, 2.46, 6.44, 1.78, 7.84, 1.31, 9.32, -1.5, 8.45, 1.24, 8.99, 0.8, 8.91, -0.44, 10.0, -1.13, 9.84, -0.18, 8.47, 1.17, 9.51, -0.3, 9.48, -1.99, 9.33, 0.29, 8.96, 1.55, 8.15, 0.07, 9.64, 1.64, 8.01, -0.17, 9.35, 0.06, 7.77, 1.12, 9.88, 0.14, 10.07, -1.09, 7.93, -0.36, 10.07, 1.84, 8.52, -1.13, 9.84, -1.06, 10.6, -1.51, 9.29, -0.34, 9.87, -1.02, 9.65, -2.3, 8.57, 0.32, 9.27, 1.84, 8.49, -0.89, 10.3, 0.29, 8.9, -0.33, 9.68, -0.02, 9.1, 0.86, 9.26, -0.13, 8.92, -2.1, 7.55, 0.05, 8.63, 0.69, 7.41, -0.18, 8.47, -1.51, 9.29, -2.0, 8.58, 0.15, 8.67, -0.68, 8.63, -2.4, 7.69, -0.85, 8.64, 0.62, 7.59, 0.06, 9.29, -0.05, 8.14, -0.91, 9.55, 0.39, 7.31, 0.14, 8.48, -0.47, 9.25, -0.75, 7.83, 1.03, 8.41, 1.79, 8.47, 1.17, 9.51, -0.34, 9.87, 0.15, 8.67, 1.53, 10.1, 0.56, 9.94, -2.09, 8.75, 1.71, 9.16, 1.94, 8.25, 0.9, 8.82, 2.5, 8.75, 0.49, 9.06, 0.63, 7.55, 1.51, 8.81, 0.45, 9.57, -1.17, 8.28, 0.85, 8.4, 1.85, 8.55, -0.3, 9.48, -1.02, 9.65, -0.68, 8.63, 0.56, 9.94, -0.39, 9.28, -2.73, 8.44, 0.1, 9.35, 0.96, 8.1, 0.56, 10.08, 1.54, 8.86, 0.32, 10.23, 0.75, 7.86, 0.99, 9.05, 0.41, 8.8, -3.23, 7.2, -0.78, 7.96, -0.07, 8.04, -1.99, 9.33, -2.3, 8.57, -2.4, 7.69, -2.09, 8.75, -2.73, 8.44, -3.48, 7.6, -1.09, 7.76, -0.46, 7.22, -1.99, 9.04, -0.27, 8.62, -1.4, 9.2, -0.29, 7.06, -0.33, 8.53, -1.49, 8.92, -0.65, 8.48, 1.52, 8.72, 1.89, 8.09, 0.29, 8.96, 0.32, 9.27, -0.85, 8.64, 1.71, 9.16, 0.1, 9.35, -1.09, 7.76, 0.23, 8.6, 1.2, 7.8, 1.08, 9.5, 1.96, 8.27, 0.34, 9.75, 0.69, 7.25, 0.85, 9.36, 0.99, 8.99, 0.16, 6.76, 1.92, 7.47, 2.14, 7.04, 1.55, 8.15, 1.84, 8.49, 0.62, 7.59, 1.94, 8.25, 0.96, 8.1, -0.46, 7.22, 1.2, 7.8, 2.47, 7.16, 2.34, 8.66, 3.34, 7.49, 1.89, 8.48, 1.74, 7.73, 2.35, 8.49, 1.38, 9.0, 0.1, 7.15, 1.61, 8.14, 1.69, 8.44, 0.07, 9.64, -0.89, 10.3, 0.06, 9.29, 0.9, 8.82, 0.56, 10.08, -1.99, 9.04, 1.08, 9.5, 2.34, 8.66, 1.3, 9.04, 1.69, 7.99, 0.46, 9.41, 0.96, 8.16, 2.15, 8.96, 0.09, 8.38, -0.35, 7.47, 1.79, 7.96, 2.79, 8.26, 1.64, 8.01, 0.29, 8.9, -0.05, 8.14, 2.5, 8.75, 1.54, 8.86, -0.27, 8.62, 1.96, 8.27, 3.34, 7.49, 1.69, 7.99, 2.09, 7.56, 1.42, 8.35, 1.85, 8.22, 2.75, 9.08, 0.98, 9.0, -0.88, 8.27, 0.92, 8.96, 1.87, 8.95, -0.17, 9.35, -0.33, 9.68, -0.91, 9.55, 0.49, 9.06, 0.32, 10.23, -1.4, 9.2, 0.34, 9.75, 1.89, 8.48, 0.46, 9.41, 1.42, 8.35, 0.9, 10.3, 0.86, 9.21, 1.49, 9.44, 0.7, 10.37, 0.19, 6.37, 2.06, 7.69, 2.46, 6.44, 0.06, 7.77, -0.02, 9.1, 0.39, 7.31, 0.63, 7.55, 0.75, 7.86, -0.29, 7.06, 0.69, 7.25, 1.74, 7.73, 0.96, 8.16, 1.85, 8.22, 0.86, 9.21, 1.26, 6.74, 2.33, 8.07, 1.4, 8.54, -1.06, 8.27, 2.76, 7.97, 1.78, 7.84, 1.12, 9.88, 0.86, 9.26, 0.14, 8.48, 1.51, 8.81, 0.99, 9.05, -0.33, 8.53, 0.85, 9.36, 2.35, 8.49, 2.15, 8.96, 2.75, 9.08, 1.49, 9.44, 2.33, 8.07, 2.27, 9.22, 0.96, 9.59, -1.19, 8.35, 1.54, 8.74, 1.31, 9.32, 0.14, 10.07, -0.13, 8.92, -0.47, 9.25, 0.45, 9.57, 0.41, 8.8, -1.49, 8.92, 0.99, 8.99, 1.38, 9.0, 0.09, 8.38, 0.98, 9.0, 0.7, 10.37, 1.4, 8.54, 0.96, 9.59, 0.13, 9.9, 
+
+L3_cHERK_A_nk
+0.40000000596, 0.10000000149, 0.800000011921, 0.10000000149, 0.20000000298, 0.5, 0.800000011921, 0.899999976158, 0.699999988079, 0.600000023842, 0.300000011921, 0.10000000149, 0.5, 0.5, 0.699999988079, 0.800000011921, 0.699999988079, 0.300000011921, 0.20000000298, 0.699999988079, 0.699999988079, 0.5, 0.600000023842, 0.10000000149, 0.300000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.899999976158, 0.5, 0.600000023842, 0.800000011921, 0.800000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.40000000596, 0.300000011921, 0.20000000298, 0.40000000596, 0.699999988079, 0.800000011921, 0.40000000596, 0.5, 0.5, 0.10000000149, 0.300000011921, 0.300000011921, 0.600000023842, 0.800000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.699999988079, 0.899999976158, 0.20000000298, 0.10000000149, 0.800000011921, 0.5, 0.300000011921, 0.600000023842, 0.800000011921, 0.300000011921, 0.899999976158, 0.40000000596, 0.40000000596, 0.899999976158, 0.800000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.600000023842, 0.20000000298, 0.699999988079, 0.800000011921, 0.800000011921, 0.699999988079, 0.899999976158, 0.20000000298, 0.300000011921, 0.899999976158, 0.699999988079, 0.899999976158, 0.699999988079, 0.10000000149, 0.699999988079, 0.20000000298, 0.699999988079, 0.800000011921, 0.20000000298, 0.800000011921, 0.899999976158, 0.600000023842, 0.10000000149, 0.5, 0.40000000596, 0.300000011921, 0.800000011921, 0.699999988079, 0.899999976158, 0.300000011921, 0.40000000596, 0.10000000149, 0.899999976158, 0.40000000596, 0.20000000298, 0.600000023842, 0.699999988079, 0.600000023842, 0.300000011921, 0.899999976158, 0.699999988079, 0.20000000298, 0.40000000596, 0.10000000149, 0.40000000596, 0.10000000149, 0.600000023842, 0.40000000596, 0.5, 0.5, 0.10000000149, 0.699999988079, 0.600000023842, 0.20000000298, 0.800000011921, 0.800000011921, 0.899999976158, 0.10000000149, 0.699999988079, 0.699999988079, 0.300000011921, 0.10000000149, 0.10000000149, 0.40000000596, 0.40000000596, 0.5, 0.20000000298, 0.800000011921, 0.600000023842, 0.699999988079, 0.600000023842, 0.40000000596, 0.600000023842, 0.20000000298, 0.800000011921, 0.899999976158, 0.800000011921, 0.300000011921, 0.20000000298, 0.40000000596, 0.20000000298, 0.40000000596, 0.300000011921, 0.5, 0.300000011921, 0.800000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.5, 0.40000000596, 0.20000000298, 0.10000000149, 0.699999988079, 0.20000000298, 0.600000023842, 0.699999988079, 0.699999988079, 0.5, 0.699999988079, 0.10000000149, 0.600000023842, 0.40000000596, 0.20000000298, 0.40000000596, 0.10000000149, 0.699999988079, 0.699999988079, 0.800000011921, 0.699999988079, 0.40000000596, 0.10000000149, 0.300000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.20000000298, 0.40000000596, 0.300000011921, 0.800000011921, 0.899999976158, 0.699999988079, 0.20000000298, 0.5, 0.10000000149, 0.699999988079, 0.20000000298, 0.20000000298, 0.40000000596, 0.5, 0.899999976158, 0.800000011921, 0.600000023842, 0.899999976158, 0.10000000149, 0.800000011921, 0.10000000149, 0.10000000149, 0.300000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.300000011921, 0.40000000596, 0.5, 0.600000023842, 0.40000000596, 0.899999976158, 0.899999976158, 0.5, 0.699999988079, 0.600000023842, 0.20000000298, 0.800000011921, 0.600000023842, 0.800000011921, 0.20000000298, 0.5, 0.5, 0.300000011921, 0.40000000596, 0.20000000298, 0.800000011921, 0.10000000149, 0.800000011921, 0.300000011921, 0.600000023842, 0.800000011921, 0.40000000596, 0.10000000149, 0.899999976158, 0.10000000149, 0.20000000298, 0.800000011921, 0.300000011921, 0.600000023842, 0.20000000298, 0.10000000149, 0.40000000596, 0.600000023842, 0.800000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.20000000298, 0.40000000596, 0.300000011921, 0.800000011921, 0.800000011921, 0.40000000596, 0.5, 0.899999976158, 0.40000000596, 0.10000000149, 0.40000000596, 0.300000011921, 0.10000000149, 0.899999976158, 0.20000000298, 0.899999976158, 0.699999988079, 0.300000011921, 0.699999988079, 0.899999976158, 0.699999988079, 0.300000011921, 0.40000000596, 0.899999976158, 0.899999976158, 0.800000011921, 0.800000011921, 0.699999988079, 0.40000000596, 0.699999988079, 0.899999976158, 0.20000000298, 0.40000000596, 0.5, 0.300000011921, 0.300000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.600000023842, 0.40000000596, 0.800000011921, 0.300000011921, 0.699999988079, 0.40000000596, 0.5, 0.5, 0.40000000596, 0.600000023842, 0.699999988079, 0.699999988079, 0.300000011921, 0.800000011921, 0.10000000149, 0.10000000149, 0.899999976158, 0.899999976158, 0.300000011921, 0.699999988079, 0.300000011921, 0.800000011921, 0.5, 0.300000011921, 0.5, 0.20000000298, 0.300000011921, 0.699999988079, 0.300000011921, 0.10000000149, 0.20000000298, 0.600000023842, 0.20000000298, 0.10000000149, 0.800000011921, 0.300000011921, 0.699999988079, 0.20000000298, 0.10000000149, 0.699999988079, 0.800000011921, 0.800000011921, 0.5, 0.40000000596, 0.5, 0.800000011921, 0.800000011921, 0.699999988079, 0.40000000596, 0.5, 0.40000000596, 0.800000011921, 0.20000000298, 0.600000023842, 0.800000011921, 0.300000011921, 0.800000011921, 0.300000011921, 0.300000011921, 0.10000000149, 0.899999976158, 0.899999976158, 0.600000023842, 0.5, 0.5, 0.899999976158, 0.5, 0.10000000149, 0.699999988079, 0.899999976158, 0.10000000149, 0.800000011921, 0.600000023842, 0.899999976158, 0.800000011921, 0.40000000596, 0.10000000149, 0.40000000596, 0.800000011921, 0.300000011921, 0.899999976158, 0.10000000149, 0.800000011921, 0.20000000298, 0.899999976158, 0.699999988079, 0.699999988079, 0.20000000298, 0.600000023842, 0.5, 0.40000000596, 0.5, 0.699999988079, 0.5, 0.40000000596, 0.800000011921, 0.40000000596, 0.600000023842, 0.899999976158, 0.40000000596, 0.10000000149, 0.10000000149, 0.300000011921, 0.20000000298, 0.800000011921, 0.10000000149, 0.300000011921, 0.800000011921, 0.20000000298, 0.600000023842, 0.40000000596, 0.600000023842, 0.800000011921, 0.5, 0.40000000596, 0.899999976158, 0.20000000298, 0.600000023842, 0.10000000149, 0.800000011921, 0.40000000596, 0.20000000298, 0.600000023842, 0.699999988079, 0.899999976158, 0.20000000298, 0.20000000298, 0.699999988079, 0.40000000596, 0.699999988079, 0.899999976158, 0.600000023842, 0.300000011921, 0.10000000149, 0.899999976158, 0.20000000298, 0.300000011921, 0.800000011921, 0.10000000149, 0.600000023842, 0.5, 0.10000000149, 0.899999976158, 0.899999976158, 0.600000023842, 0.10000000149, 0.899999976158, 0.5, 0.10000000149, 0.800000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.600000023842, 0.20000000298, 0.300000011921, 0.899999976158, 0.40000000596, 0.10000000149, 0.699999988079, 0.800000011921, 0.5, 0.600000023842, 0.600000023842, 0.20000000298, 0.10000000149, 0.800000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.20000000298, 0.899999976158, 0.699999988079, 0.40000000596, 0.10000000149, 0.800000011921, 0.600000023842, 0.10000000149, 0.800000011921, 0.5, 0.5, 0.40000000596, 0.699999988079, 0.600000023842, 0.300000011921, 0.899999976158, 0.10000000149, 0.300000011921, 0.600000023842, 0.300000011921, 0.10000000149, 0.20000000298, 0.300000011921, 0.40000000596, 0.699999988079, 0.40000000596, 0.800000011921, 0.40000000596, 0.40000000596, 0.20000000298, 0.899999976158, 0.20000000298, 0.5, 0.300000011921, 0.899999976158, 0.5, 0.5, 0.800000011921, 0.699999988079, 0.5, 0.300000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.10000000149, 0.300000011921, 0.899999976158, 0.300000011921, 0.20000000298, 0.600000023842, 0.10000000149, 0.5, 0.800000011921, 0.20000000298, 0.899999976158, 0.300000011921, 0.899999976158, 0.300000011921, 0.10000000149, 0.800000011921, 0.899999976158, 0.300000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.699999988079, 0.40000000596, 0.300000011921, 0.899999976158, 0.600000023842, 0.699999988079, 0.20000000298, 0.40000000596, 0.40000000596, 0.20000000298, 0.800000011921, 0.899999976158, 0.699999988079, 0.300000011921, 
+
+L3_cHERK_C_nn
+0.300000011921, 0.0, 0.600000023842, 0.20000000298, 0.800000011921, 0.699999988079, 0.899999976158, 0.20000000298, 0.5, 0.899999976158, 0.5, 0.10000000149, 0.600000023842, 0.10000000149, 0.899999976158, 0.800000011921, 0.40000000596, 0.5, 0.800000011921, 0.20000000298, 0.10000000149, 0.300000011921, 0.899999976158, 0.300000011921, 0.40000000596, 0.600000023842, 0.899999976158, 0.40000000596, 0.10000000149, 0.699999988079, 0.699999988079, 0.899999976158, 0.40000000596, 0.899999976158, 0.600000023842, -0.20000000298, 0.5, 0.0, 0.800000011921, 0.5, 0.300000011921, 0.40000000596, 0.40000000596, 0.300000011921, 0.300000011921, 0.5, 0.800000011921, 0.800000011921, 0.5, 0.300000011921, 0.40000000596, 0.800000011921, 0.300000011921, 0.600000023842, 0.300000011921, 0.699999988079, 0.20000000298, 0.899999976158, 0.5, 0.10000000149, 0.5, 0.800000011921, 0.40000000596, 0.5, 0.300000011921, 0.5, 0.800000011921, 0.5, 0.800000011921, -0.699999988079, 0.800000011921, -0.5, 0.699999988079, 0.0, 0.40000000596, 0.699999988079, 0.300000011921, 0.699999988079, 0.40000000596, 0.5, 0.600000023842, 0.600000023842, 0.899999976158, 0.800000011921, 0.5, 0.800000011921, 0.699999988079, 0.899999976158, 0.20000000298, 0.800000011921, 0.699999988079, 0.699999988079, 0.300000011921, 0.5, 0.600000023842, 0.40000000596, 0.699999988079, 0.40000000596, 0.899999976158, 0.5, 0.10000000149, 0.40000000596, 0.899999976158, -0.20000000298, 0.300000011921, -0.40000000596, 0.40000000596, -0.699999988079, 0.300000011921, 0.0, 0.10000000149, 0.5, 0.20000000298, 0.699999988079, 0.899999976158, 0.600000023842, 0.699999988079, 0.600000023842, 0.600000023842, 0.20000000298, 0.5, 0.20000000298, 0.40000000596, 0.899999976158, 0.800000011921, 0.800000011921, 0.300000011921, 0.699999988079, 0.10000000149, 0.800000011921, 0.300000011921, 0.800000011921, 0.699999988079, 0.5, 0.699999988079, 0.600000023842, 0.5, -0.899999976158, 0.40000000596, -0.300000011921, 0.300000011921, -0.699999988079, 0.10000000149, -0.5, 0.10000000149, 0.0, 0.899999976158, 0.5, 0.600000023842, 0.899999976158, 0.800000011921, 0.600000023842, 0.40000000596, 0.800000011921, 0.20000000298, 0.699999988079, 0.5, 0.600000023842, 0.40000000596, 0.300000011921, 0.899999976158, 0.300000011921, 0.10000000149, 0.20000000298, 0.699999988079, 0.5, 0.300000011921, 0.600000023842, 0.600000023842, 0.20000000298, 0.5, -0.10000000149, 0.300000011921, -0.5, 0.40000000596, -0.5, 0.20000000298, -0.699999988079, 0.899999976158, -0.5, 0.699999988079, 0.0, 0.899999976158, 0.899999976158, 0.20000000298, 0.699999988079, 0.899999976158, 0.800000011921, 0.699999988079, 0.699999988079, 0.600000023842, 0.20000000298, 0.300000011921, 0.699999988079, 0.699999988079, 0.20000000298, 0.300000011921, 0.10000000149, 0.10000000149, 0.10000000149, 0.300000011921, 0.10000000149, 0.5, 0.699999988079, 0.600000023842, -0.10000000149, 0.800000011921, -0.800000011921, 0.600000023842, -0.600000023842, 0.899999976158, -0.600000023842, 0.600000023842, -0.899999976158, 0.899999976158, -0.899999976158, 0.600000023842, 0.0, 0.699999988079, 0.20000000298, 0.10000000149, 0.10000000149, 0.899999976158, 0.600000023842, 0.20000000298, 0.600000023842, 0.5, 0.40000000596, 0.800000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.800000011921, 0.5, 0.10000000149, 0.10000000149, 0.899999976158, -0.800000011921, 0.5, -0.300000011921, 0.899999976158, -0.800000011921, 0.699999988079, -0.600000023842, 0.800000011921, -0.600000023842, 0.20000000298, -0.699999988079, 0.699999988079, -0.20000000298, 0.20000000298, 0.0, 0.600000023842, 0.40000000596, 0.300000011921, 0.699999988079, 0.699999988079, 0.800000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.300000011921, 0.300000011921, 0.40000000596, 0.10000000149, 0.800000011921, 0.899999976158, 0.699999988079, 0.800000011921, 0.600000023842, 0.40000000596, -0.5, 0.40000000596, -0.800000011921, 0.5, -0.800000011921, 0.600000023842, -0.20000000298, 0.40000000596, -0.800000011921, 0.899999976158, -0.800000011921, 0.10000000149, -0.10000000149, 0.600000023842, -0.40000000596, 0.800000011921, 0.0, 0.20000000298, 0.800000011921, 0.600000023842, 0.20000000298, 0.800000011921, 0.300000011921, 0.699999988079, 0.699999988079, 0.600000023842, 0.600000023842, 0.300000011921, 0.10000000149, 0.20000000298, 0.899999976158, 0.600000023842, 0.40000000596, 0.800000011921, -0.20000000298, 0.300000011921, -0.600000023842, 0.699999988079, -0.899999976158, 0.5, -0.20000000298, 0.20000000298, -0.699999988079, 0.699999988079, -0.699999988079, 0.899999976158, -0.600000023842, 0.300000011921, -0.699999988079, 0.20000000298, -0.800000011921, 0.40000000596, 0.0, 0.699999988079, 0.699999988079, 0.899999976158, 0.20000000298, 0.5, 0.899999976158, 0.20000000298, 0.899999976158, 0.899999976158, 0.40000000596, 0.10000000149, 0.800000011921, 0.899999976158, 0.40000000596, 0.10000000149, -0.300000011921, 0.300000011921, -0.699999988079, 0.20000000298, -0.800000011921, 0.40000000596, -0.899999976158, 0.5, -0.600000023842, 0.600000023842, -0.20000000298, 0.20000000298, -0.600000023842, 0.699999988079, -0.800000011921, 0.600000023842, -0.20000000298, 0.699999988079, -0.699999988079, 0.10000000149, 0.0, 0.20000000298, 0.600000023842, 0.800000011921, 0.300000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.600000023842, 0.600000023842, 0.20000000298, 0.10000000149, 0.800000011921, 0.899999976158, -0.300000011921, 0.20000000298, -0.899999976158, 0.699999988079, -0.699999988079, 0.800000011921, -0.800000011921, 0.40000000596, -0.300000011921, 0.300000011921, -0.699999988079, 0.5, -0.40000000596, 0.40000000596, -0.899999976158, 0.800000011921, -0.300000011921, 0.899999976158, -0.20000000298, 0.20000000298, -0.600000023842, 0.5, 0.0, 0.800000011921, 0.300000011921, 0.20000000298, 0.20000000298, 0.699999988079, 0.600000023842, 0.40000000596, 0.10000000149, 0.899999976158, 0.40000000596, 0.40000000596, -0.600000023842, 0.5, -0.10000000149, 0.300000011921, -0.5, 0.300000011921, -0.699999988079, 0.899999976158, -0.300000011921, 0.699999988079, -0.20000000298, 0.800000011921, -0.899999976158, 0.20000000298, -0.300000011921, 0.699999988079, -0.699999988079, 0.5, -0.899999976158, 0.800000011921, -0.300000011921, 0.800000011921, -0.300000011921, 0.699999988079, 0.0, 0.300000011921, 0.10000000149, 0.10000000149, 0.899999976158, 0.10000000149, 0.899999976158, 0.20000000298, 0.899999976158, 0.899999976158, -0.40000000596, 0.5, -0.800000011921, 0.600000023842, -0.40000000596, 0.10000000149, -0.800000011921, 0.10000000149, -0.20000000298, 0.300000011921, -0.10000000149, 0.899999976158, -0.10000000149, 0.300000011921, -0.40000000596, 0.600000023842, -0.600000023842, 0.20000000298, -0.899999976158, 0.699999988079, -0.20000000298, 0.20000000298, -0.20000000298, 0.300000011921, -0.10000000149, 0.600000023842, 0.0, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 0.20000000298, 0.5, 0.10000000149, -0.699999988079, 0.40000000596, -0.5, 0.699999988079, -0.40000000596, 0.300000011921, -0.800000011921, 0.699999988079, -0.5, 0.10000000149, -0.10000000149, 0.800000011921, -0.800000011921, 0.10000000149, -0.800000011921, 0.300000011921, -0.10000000149, 0.899999976158, -0.40000000596, 0.40000000596, -0.600000023842, 0.699999988079, -0.600000023842, 0.10000000149, -0.899999976158, 0.10000000149, -0.300000011921, 0.800000011921, 0.0, 0.40000000596, 0.300000011921, 0.600000023842, 0.600000023842, 0.699999988079, -0.899999976158, 0.300000011921, -0.5, 0.899999976158, -0.5, 0.699999988079, -0.5, 0.300000011921, -0.600000023842, 0.300000011921, -0.10000000149, 0.800000011921, -0.5, 0.899999976158, -0.699999988079, 0.20000000298, -0.899999976158, 0.10000000149, -0.800000011921, 0.600000023842, -0.20000000298, 0.40000000596, -0.10000000149, 0.10000000149, -0.899999976158, 0.800000011921, -0.899999976158, 0.40000000596, -0.300000011921, 0.800000011921, 0.0, 0.20000000298, 0.699999988079, 0.40000000596, -0.899999976158, 0.800000011921, -0.5, 0.10000000149, -0.40000000596, 0.699999988079, -0.600000023842, 0.600000023842, -0.20000000298, 0.5, -0.699999988079, 0.10000000149, -0.10000000149, 0.800000011921, -0.600000023842, 0.600000023842, -0.40000000596, 0.899999976158, -0.40000000596, 0.10000000149, -0.800000011921, 0.899999976158, -0.40000000596, 0.20000000298, -0.899999976158, 0.20000000298, -0.5, 0.600000023842, -0.600000023842, 0.20000000298, -0.699999988079, 0.40000000596, 0.0, 
+
+L3_cHERK_o_N
+10.4700000229, 6.66133814775e-16, 9.30000010133, -2.08999994233, 9.22000003412, -0.450000023842, 8.7200000304, -1.80999996752, 8.12000013173, 0.679999892861, 8.17000005573, 0.679999997914, 7.95000010431, 1.21000003457, 8.35000016689, 0.330000042617, 9.17999995694, -0.190000016093, 8.44000014722, -0.020000025928, 8.4800001432, -0.599999988824, 9.63999999225, -1.07000002518, 7.99000018969, 0.910000043511, 9.36999998048, -1.42999999195, 8.3500001058, -0.610000027865, 8.67000000358, -0.520000014007, 9.1400000824, -0.839999873787, 9.30000010133, 2.08999994233, 11.5999999732, 0.0, 10.2100000323, 1.06999999762, 9.07000003487, -0.21000002563, 8.58000009552, 1.47999989361, 7.90000003874, 2.46999991342, 9.09000008613, 2.63000003517, 8.34000016958, 0.719999977499, 9.04000005856, 1.63999998704, 8.30000016987, 1.48000004783, 9.03000013053, 1.70999996006, 9.79000005782, 0.379999971092, 8.35000009984, 1.84000005335, 10.0199999619, 1.13000003517, 9.00000009611, 1.05999999881, 9.25000000075, 0.750000015646, 9.67000011012, 0.810000081509, 9.22000003412, 0.450000023842, 10.2100000323, -1.06999999762, 13.5499998182, 4.4408920985e-16, 9.71000006512, 0.160000004768, 9.17000008628, 1.05999988556, 8.5000000231, 2.08999998108, 9.86000004053, 2.77999990925, 9.20000008196, 0.920000040829, 10.8699999276, 0.680000003874, 10.3000000477, 1.67999993756, 8.76000008076, 1.61999998942, 10.3199999201, 0.309999878854, 8.8400000757, 2.67000000954, 9.94000001088, 0.600000029802, 9.41000005245, 0.490000041425, 10.1199999797, 0.040000025779, 10.0299999398, 1.02000008851, 8.7200000304, 1.80999996752, 9.07000003487, 0.21000002563, 9.71000006512, -0.160000004768, 10.5899999952, 2.22044604925e-16, 7.90000011995, 1.66999989852, 7.42000006467, 2.60999998987, 8.92000007883, 3.20000002906, 8.32000014812, 1.94000002652, 9.5400000079, 0.620000031143, 8.2700000751, 1.12000003114, 8.35000007749, 2.20999997944, 9.62000004083, 0.370000005811, 7.60000008568, 2.64000003099, 7.68000004932, 1.25999998316, 7.96000008598, 1.42000006989, 8.6400000079, 0.550000047684, 8.66000006884, 1.97000007883, 8.12000013173, -0.679999892861, 8.58000009552, -1.47999989361, 9.17000008628, -1.05999988556, 7.90000011995, -1.66999989852, 8.83000015736, 0.0, 8.38000005528, 1.13000006646, 8.02000013992, 1.81000006512, 7.44000022247, 0.380000074655, 8.45000008717, -0.369999885112, 7.67000013173, 0.590000054836, 7.91000018135, 0.210000085235, 7.84000011668, -0.659999943674, 7.82000014886, 1.00000010207, 7.74000013456, -0.829999877214, 8.12000012651, -0.479999893606, 7.96000012025, -0.709999901205, 8.24000012562, -0.099999833107, 8.17000005573, -0.679999997914, 7.90000003874, -2.46999991342, 8.5000000231, -2.08999998108, 7.42000006467, -2.60999998987, 8.38000005528, -1.13000006646, 9.30999995708, 0.0, 8.39000004441, 1.00000001192, 6.73000011414, -0.350000016391, 9.25999993101, 0.0799999725819, 8.42000003487, 0.0499999836087, 7.38000014469, -0.709999964535, 7.67000004232, -0.400000053644, 8.09000009656, 0.730000053048, 7.07000006318, -1.66999994695, 7.3800000903, -0.420000026673, 7.66999999389, -1.46999992833, 8.20000002384, -0.539999931157, 7.95000010431, -1.21000003457, 9.09000008613, -2.63000003517, 9.86000004053, -2.77999990925, 8.92000007883, -3.20000002906, 8.02000013992, -1.81000006512, 8.39000004441, -1.00000001192, 10.5700000095, 0.0, 8.19000013307, -1.90000000596, 8.45000002608, -1.96999992833, 9.13000004783, -0.380000002384, 7.64000011221, -0.500000000745, 8.92999995247, -1.82000005424, 8.27000008106, 1.12999998748, 7.90000003576, -1.22000000134, 8.4300001201, -0.799999967217, 8.76000002116, -1.30000000671, 8.2900000295, -1.33999990359, 8.35000016689, -0.330000042617, 8.34000016958, -0.719999977499, 9.20000008196, -0.920000040829, 8.32000014812, -1.94000002652, 7.44000022247, -0.380000074655, 6.73000011414, 0.350000016391, 8.19000013307, 1.90000000596, 9.28000028104, -2.22044604925e-16, 8.14000015095, 0.179999965876, 7.84000019416, 1.23999997139, 8.04000017628, 0.7099999623, 8.18000014246, 0.159999849051, 7.30000021011, 0.58000000909, 6.90000014529, -0.330000039637, 6.95000023618, 0.630000024736, 8.50000010356, 0.0900000041723, 8.38000015065, 0.410000082999, 9.17999995694, 0.190000016093, 9.04000005856, -1.63999998704, 10.8699999276, -0.680000003874, 9.5400000079, -0.620000031143, 8.45000008717, 0.369999885112, 9.25999993101, -0.0799999725819, 8.45000002608, 1.96999992833, 8.14000015095, -0.179999965876, 13.1899997658, -8.881784197e-16, 9.54000001684, 1.61999995515, 8.93000010595, 1.07999997854, 10.209999963, -0.750000075251, 9.69000004739, 2.47999997184, 9.35000003129, 0.700000026077, 10.3799999711, 0.489999955744, 8.89999996275, 0.740000008643, 9.69999996126, 0.390000094324, 8.44000014722, 0.020000025928, 8.30000016987, -1.48000004783, 10.3000000477, -1.67999993756, 8.2700000751, -1.12000003114, 7.67000013173, -0.590000054836, 8.42000003487, -0.0499999836087, 9.13000004783, 0.380000002384, 7.84000019416, -1.23999997139, 9.54000001684, -1.61999995515, 10.2000000864, 0.0, 8.70000013262, 0.239999956489, 9.94000003099, -0.710000077039, 8.48000012904, 1.900000038, 7.70000013709, 0.789999990761, 8.50000013337, 0.260000070333, 8.18000002697, 0.480000036657, 9.54000006005, -0.499999904633, 8.4800001432, 0.599999988824, 9.03000013053, -1.70999996006, 8.76000008076, -1.61999998942, 8.35000007749, -2.20999997944, 7.91000018135, -0.210000085235, 7.38000014469, 0.709999964535, 7.64000011221, 0.500000000745, 8.04000017628, -0.7099999623, 8.93000010595, -1.07999997854, 8.70000013262, -0.239999956489, 9.72000019431, -4.4408920985e-16, 8.63000013202, -1.0099999854, 8.43000019833, 1.13000010893, 8.98000010297, -0.149999960512, 7.93000015736, -0.00999991238117, 8.81000007778, -0.609999951869, 8.13000013426, 0.150000116974, 9.63999999225, 1.07000002518, 9.79000005782, -0.379999971092, 10.3199999201, -0.309999878854, 9.62000004083, -0.370000005811, 7.84000011668, 0.659999943674, 7.67000004232, 0.400000053644, 8.92999995247, 1.82000005424, 8.18000014246, -0.159999849051, 10.209999963, 0.750000075251, 9.94000003099, 0.710000077039, 8.63000013202, 1.0099999854, 12.7499998465, 2.22044604925e-16, 8.65000011995, 2.14000006527, 8.88999999896, 1.15, 9.01000001594, 1.01000009194, 8.88000000611, 0.950000040978, 10.0699999842, -0.539999735206, 7.99000018969, -0.910000043511, 8.35000009984, -1.84000005335, 8.8400000757, -2.67000000954, 7.60000008568, -2.64000003099, 7.82000014886, -1.00000010207, 8.09000009656, -0.730000053048, 8.27000008106, -1.12999998748, 7.30000021011, -0.58000000909, 9.69000004739, -2.47999997184, 8.48000012904, -1.900000038, 8.43000019833, -1.13000010893, 8.65000011995, -2.14000006527, 9.91000014782, 2.22044604925e-16, 8.50000008941, -1.36000009939, 8.52000015408, -0.440000047386, 8.08000007093, -0.790000001192, 8.00000011325, -0.58999997437, 9.36999998048, 1.42999999195, 10.0199999619, -1.13000003517, 9.94000001088, -0.600000029802, 7.68000004932, -1.25999998316, 7.74000013456, 0.829999877214, 7.07000006318, 1.66999994695, 7.90000003576, 1.22000000134, 6.90000014529, 0.330000039637, 9.35000003129, -0.700000026077, 7.70000013709, -0.789999990761, 8.98000010297, 0.149999960512, 8.88999999896, -1.15, 8.50000008941, 1.36000009939, 11.4399999207, 0.0, 8.92000005722, 0.0400000801682, 8.95000001788, 0.850000011921, 8.73000001952, 0.320000146627, 8.3500001058, 0.610000027865, 9.00000009611, -1.05999999881, 9.41000005245, -0.490000041425, 7.96000008598, -1.42000006989, 8.12000012651, 0.479999893606, 7.3800000903, 0.420000026673, 8.4300001201, 0.799999967217, 6.95000023618, -0.630000024736, 10.3799999711, -0.489999955744, 8.50000013337, -0.260000070333, 7.93000015736, 0.00999991238117, 9.01000001594, -1.01000009194, 8.52000015408, 0.440000047386, 8.92000005722, -0.0400000801682, 10.8300000918, 6.66133814775e-16, 8.59000007495, -0.259999953359, 8.79000011593, 0.610000128448, 8.67000000358, 0.520000014007, 9.25000000075, -0.750000015646, 10.1199999797, -0.040000025779, 8.6400000079, -0.550000047684, 7.96000012025, 0.709999901205, 7.66999999389, 1.46999992833, 8.76000002116, 1.30000000671, 8.50000010356, -0.0900000041723, 8.89999996275, -0.740000008643, 8.18000002697, -0.480000036657, 8.81000007778, 0.609999951869, 8.88000000611, -0.950000040978, 8.08000007093, 0.790000001192, 8.95000001788, -0.850000011921, 8.59000007495, 0.259999953359, 10.7799998638, 0.0, 7.87000004306, 0.790000066012, 9.1400000824, 0.839999873787, 9.67000011012, -0.810000081509, 10.0299999398, -1.02000008851, 8.66000006884, -1.97000007883, 8.24000012562, 0.099999833107, 8.20000002384, 0.539999931157, 8.2900000295, 1.33999990359, 8.38000015065, -0.410000082999, 9.69999996126, -0.390000094324, 9.54000006005, 0.499999904633, 8.13000013426, -0.150000116974, 10.0699999842, 0.539999735206, 8.00000011325, 0.58999997437, 8.73000001952, -0.320000146627, 8.79000011593, -0.610000128448, 7.87000004306, -0.790000066012, 11.2699999112, -4.4408920985e-16, 
+
+L3_cHERK_A_kn
+0.800000011921, 0.699999988079, 0.699999988079, 0.699999988079, 0.20000000298, 0.699999988079, 0.10000000149, 0.40000000596, 0.10000000149, 0.800000011921, 0.20000000298, 0.5, 0.300000011921, 0.300000011921, 0.800000011921, 0.800000011921, 0.300000011921, 0.600000023842, 0.600000023842, 0.800000011921, 0.10000000149, 0.300000011921, 0.600000023842, 0.699999988079, 0.10000000149, 0.5, 0.5, 0.800000011921, 0.300000011921, 0.10000000149, 0.10000000149, 0.5, 0.600000023842, 0.800000011921, 0.300000011921, 0.600000023842, 0.300000011921, 0.20000000298, 0.600000023842, 0.899999976158, 0.20000000298, 0.600000023842, 0.899999976158, 0.800000011921, 0.800000011921, 0.300000011921, 0.300000011921, 0.899999976158, 0.10000000149, 0.20000000298, 0.5, 0.5, 0.5, 0.20000000298, 0.5, 0.600000023842, 0.10000000149, 0.20000000298, 0.40000000596, 0.699999988079, 0.40000000596, 0.40000000596, 0.899999976158, 0.800000011921, 0.899999976158, 0.600000023842, 0.800000011921, 0.10000000149, 0.600000023842, 0.5, 0.300000011921, 0.800000011921, 0.800000011921, 0.10000000149, 0.40000000596, 0.10000000149, 0.300000011921, 0.800000011921, 0.10000000149, 0.600000023842, 0.20000000298, 0.600000023842, 0.600000023842, 0.10000000149, 0.899999976158, 0.600000023842, 0.40000000596, 0.10000000149, 0.10000000149, 0.600000023842, 0.20000000298, 0.20000000298, 0.5, 0.300000011921, 0.300000011921, 0.20000000298, 0.5, 0.800000011921, 0.800000011921, 0.699999988079, 0.10000000149, 0.300000011921, 0.10000000149, 0.5, 0.300000011921, 0.5, 0.10000000149, 0.40000000596, 0.20000000298, 0.899999976158, 0.699999988079, 0.300000011921, 0.10000000149, 0.899999976158, 0.300000011921, 0.40000000596, 0.40000000596, 0.899999976158, 0.40000000596, 0.300000011921, 0.10000000149, 0.699999988079, 0.899999976158, 0.899999976158, 0.40000000596, 0.699999988079, 0.899999976158, 0.899999976158, 0.800000011921, 0.5, 0.20000000298, 0.800000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.40000000596, 0.699999988079, 0.899999976158, 0.800000011921, 0.800000011921, 0.5, 0.600000023842, 0.40000000596, 0.5, 0.10000000149, 0.10000000149, 0.899999976158, 0.5, 0.600000023842, 0.10000000149, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.5, 0.699999988079, 0.699999988079, 0.899999976158, 0.800000011921, 0.699999988079, 0.800000011921, 0.20000000298, 0.899999976158, 0.5, 0.600000023842, 0.800000011921, 0.300000011921, 0.899999976158, 0.10000000149, 0.800000011921, 0.300000011921, 0.40000000596, 0.10000000149, 0.899999976158, 0.899999976158, 0.899999976158, 0.600000023842, 0.300000011921, 0.699999988079, 0.699999988079, 0.600000023842, 0.699999988079, 0.300000011921, 0.600000023842, 0.40000000596, 0.899999976158, 0.699999988079, 0.800000011921, 0.699999988079, 0.699999988079, 0.600000023842, 0.300000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.600000023842, 0.300000011921, 0.20000000298, 0.20000000298, 0.899999976158, 0.40000000596, 0.800000011921, 0.10000000149, 0.800000011921, 0.600000023842, 0.10000000149, 0.5, 0.899999976158, 0.899999976158, 0.899999976158, 0.699999988079, 0.699999988079, 0.300000011921, 0.699999988079, 0.899999976158, 0.300000011921, 0.600000023842, 0.40000000596, 0.800000011921, 0.300000011921, 0.20000000298, 0.10000000149, 0.800000011921, 0.20000000298, 0.5, 0.20000000298, 0.20000000298, 0.800000011921, 0.40000000596, 0.899999976158, 0.300000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.10000000149, 0.600000023842, 0.40000000596, 0.20000000298, 0.20000000298, 0.600000023842, 0.699999988079, 0.5, 0.40000000596, 0.10000000149, 0.5, 0.10000000149, 0.20000000298, 0.40000000596, 0.699999988079, 0.20000000298, 0.20000000298, 0.600000023842, 0.20000000298, 0.600000023842, 0.5, 0.300000011921, 0.899999976158, 0.600000023842, 0.800000011921, 0.40000000596, 0.800000011921, 0.800000011921, 0.300000011921, 0.10000000149, 0.5, 0.40000000596, 0.600000023842, 0.10000000149, 0.300000011921, 0.300000011921, 0.699999988079, 0.20000000298, 0.800000011921, 0.300000011921, 0.5, 0.40000000596, 0.40000000596, 0.5, 0.40000000596, 0.300000011921, 0.300000011921, 0.5, 0.899999976158, 0.600000023842, 0.5, 0.300000011921, 0.800000011921, 0.5, 0.40000000596, 0.5, 0.699999988079, 0.20000000298, 0.10000000149, 0.40000000596, 0.699999988079, 0.600000023842, 0.10000000149, 0.40000000596, 0.20000000298, 0.20000000298, 0.699999988079, 0.800000011921, 0.899999976158, 0.699999988079, 0.300000011921, 0.5, 0.10000000149, 0.10000000149, 0.5, 0.5, 0.699999988079, 0.10000000149, 0.10000000149, 0.40000000596, 0.699999988079, 0.5, 0.699999988079, 0.5, 0.20000000298, 0.20000000298, 0.600000023842, 0.600000023842, 0.899999976158, 0.800000011921, 0.20000000298, 0.899999976158, 0.800000011921, 0.899999976158, 0.10000000149, 0.800000011921, 0.20000000298, 0.20000000298, 0.20000000298, 0.600000023842, 0.699999988079, 0.40000000596, 0.20000000298, 0.800000011921, 0.300000011921, 0.899999976158, 0.800000011921, 0.800000011921, 0.699999988079, 0.5, 0.600000023842, 0.699999988079, 0.300000011921, 0.5, 0.800000011921, 0.899999976158, 0.5, 0.600000023842, 0.800000011921, 0.10000000149, 0.699999988079, 0.300000011921, 0.40000000596, 0.899999976158, 0.5, 0.10000000149, 0.10000000149, 0.20000000298, 0.20000000298, 0.40000000596, 0.10000000149, 0.20000000298, 0.40000000596, 0.40000000596, 0.5, 0.300000011921, 0.40000000596, 0.40000000596, 0.40000000596, 0.10000000149, 0.40000000596, 0.699999988079, 0.40000000596, 0.600000023842, 0.20000000298, 0.899999976158, 0.899999976158, 0.800000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.600000023842, 0.20000000298, 0.10000000149, 0.699999988079, 0.800000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.300000011921, 0.40000000596, 0.10000000149, 0.600000023842, 0.899999976158, 0.300000011921, 0.5, 0.5, 0.20000000298, 0.20000000298, 0.600000023842, 0.20000000298, 0.10000000149, 0.899999976158, 0.699999988079, 0.800000011921, 0.5, 0.300000011921, 0.40000000596, 0.699999988079, 0.300000011921, 0.20000000298, 0.20000000298, 0.20000000298, 0.300000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.300000011921, 0.10000000149, 0.40000000596, 0.20000000298, 0.10000000149, 0.10000000149, 0.899999976158, 0.899999976158, 0.600000023842, 0.5, 0.600000023842, 0.40000000596, 0.699999988079, 0.5, 0.300000011921, 0.600000023842, 0.800000011921, 0.899999976158, 0.40000000596, 0.600000023842, 0.300000011921, 0.10000000149, 0.10000000149, 0.10000000149, 0.300000011921, 0.300000011921, 0.800000011921, 0.899999976158, 0.40000000596, 0.300000011921, 0.699999988079, 0.899999976158, 0.699999988079, 0.40000000596, 0.600000023842, 0.600000023842, 0.5, 0.40000000596, 0.300000011921, 0.300000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.899999976158, 0.800000011921, 0.40000000596, 0.20000000298, 0.5, 0.40000000596, 0.10000000149, 0.300000011921, 0.699999988079, 0.300000011921, 0.20000000298, 0.300000011921, 0.600000023842, 0.5, 0.699999988079, 0.899999976158, 0.300000011921, 0.800000011921, 0.40000000596, 0.800000011921, 0.40000000596, 0.699999988079, 0.5, 0.699999988079, 0.600000023842, 0.600000023842, 0.300000011921, 0.800000011921, 0.10000000149, 0.899999976158, 0.10000000149, 0.800000011921, 0.699999988079, 0.20000000298, 0.5, 0.300000011921, 0.899999976158, 0.300000011921, 0.800000011921, 0.300000011921, 0.300000011921, 0.5, 0.800000011921, 0.40000000596, 0.300000011921, 0.800000011921, 0.600000023842, 0.699999988079, 0.20000000298, 0.300000011921, 0.10000000149, 0.600000023842, 0.899999976158, 0.20000000298, 0.40000000596, 0.40000000596, 0.800000011921, 0.10000000149, 0.10000000149, 0.40000000596, 0.699999988079, 0.10000000149, 0.300000011921, 0.300000011921, 0.699999988079, 0.699999988079, 0.699999988079, 0.600000023842, 0.40000000596, 0.800000011921, 0.600000023842, 0.899999976158, 0.899999976158, 0.300000011921, 0.300000011921, 0.600000023842, 0.20000000298, 0.800000011921, 0.20000000298, 0.300000011921, 
+
+L3_cHERK_o_H
+10.1200002033, 0.0, 9.06000011206, 1.01000008747, 9.38000012159, 1.8700000222, 7.85000009909, 0.0500001087785, 7.68000014991, 1.76000006065, 8.82000011086, -0.359999869168, 7.2600002782, -0.339999937117, 9.7800001283, 0.660000075549, 7.39000012934, 1.17000005201, 8.74000009432, 0.37000005126, 7.46000009641, -0.329999851882, 9.24000008762, 0.740000076443, 7.36000009418, 0.680000089556, 7.92000011012, -1.27999987498, 8.54000022247, 1.51000006884, 9.15000007749, 1.46000005394, 7.17000015929, 1.26000003681, 9.06000011206, -1.01000008747, 10.5299999338, -4.4408920985e-16, 9.63000001207, -0.269999975264, 7.43000004858, -0.41999998197, 8.42000000134, 0.289999994487, 9.35000000894, -1.02999991223, 7.5500001967, -0.450000008941, 9.78000007018, -0.580000034422, 8.00000005886, 0.55000000298, 8.53999999672, 0.0900000421703, 8.11000008076, -0.679999958426, 8.8400001055, 0.649999950081, 7.76000003234, -1.39999996796, 7.48000008136, -0.949999971688, 9.20000014156, -0.119999961108, 8.94000006303, 0.170000019222, 8.49000009432, 0.819999980479, 9.38000012159, -1.8700000222, 9.63000001207, 0.269999975264, 12.2599998751, 2.22044604925e-16, 8.46000005692, -0.819999931306, 9.21999998048, 0.840000057071, 9.83000001505, -1.39999989793, 7.83000018045, -0.0599999816716, 10.0600000614, -0.420000001341, 9.0799999465, 1.22000005871, 8.9300000225, 0.259999952614, 8.18000009328, 0.0500000655651, 9.39000005335, 0.0199999983609, 8.39999998808, -0.180000034422, 7.13000013426, -1.75999996752, 10.1200000982, 0.890000042915, 9.90000006482, 0.610000068843, 7.3400001204, 0.140000028014, 7.85000009909, -0.0500001087785, 7.43000004858, 0.41999998197, 8.46000005692, 0.819999931306, 8.89999996424, 4.4408920985e-16, 7.09000005782, 0.679999968857, 8.88999999598, 0.1800000076, 6.37000014067, 0.539999997467, 9.16000005245, 0.529999974817, 7.27000010118, 0.999999972433, 7.73000001654, 0.759999961555, 7.53000002697, 0.330000023991, 9.07000005797, 2.04999992475, 7.36000003755, 0.709999948144, 6.56000004873, -0.79999999404, 7.36000016943, 1.57000002891, 8.03000004187, 0.650000038743, 6.96000003979, 0.94999999702, 7.68000014991, -1.76000006065, 8.42000000134, -0.289999994487, 9.21999998048, -0.840000057071, 7.09000005782, -0.679999968857, 10.0299999249, 0.0, 9.50000003129, -0.679999924898, 7.25000020862, 0.299999940395, 8.73000010967, -0.300000033528, 8.5500000149, 1.07000000134, 7.30000003427, -0.12000004977, 8.27000008106, 0.150000026822, 7.96000011206, 0.200000017881, 8.13999998704, 0.269999980479, 6.71000010833, -1.24999999851, 8.68000006348, 0.560000017434, 9.0100000532, 0.170000062436, 7.30000008792, 0.0999999321997, 8.82000011086, 0.359999869168, 9.35000000894, 1.02999991223, 9.83000001505, 1.39999989793, 8.88999999598, -0.1800000076, 9.50000003129, 0.679999924898, 12.1799998996, 0.0, 7.87000014067, 1.3399999252, 10.1800000396, 1.13999985591, 9.18000004634, 1.50999999359, 9.73999992073, 1.95999990419, 9.600000038, 0.78000001505, 9.63000005454, 2.18999994233, 8.40000004545, 0.510000004768, 7.87000004977, -0.710000001788, 9.62000009671, 1.71999997303, 9.37999999791, 0.940000022054, 8.11000008151, 2.11999990746, 7.2600002782, 0.339999937117, 7.5500001967, 0.450000008941, 7.83000018045, 0.0599999816716, 6.37000014067, -0.539999997467, 7.25000020862, -0.299999940395, 7.87000014067, -1.3399999252, 7.33000032425, -1.11022302463e-16, 7.27000023305, 0.73999997735, 5.60000019222, 0.220000004321, 6.91000015527, 0.740000030994, 6.76000020444, 0.170000050515, 6.97000022635, 0.900000017881, 6.84000015244, 0.719999966323, 6.39000017703, -0.779999998659, 7.76000025585, 1.34000008613, 8.0400001964, 0.260000056922, 5.22000023603, 0.460000044256, 9.7800001283, -0.660000075549, 9.78000007018, 0.580000034422, 10.0600000614, 0.420000001341, 9.16000005245, -0.529999974817, 8.73000010967, 0.300000033528, 10.1800000396, -1.13999985591, 7.27000023305, -0.73999997735, 11.4700001496, 2.22044604925e-16, 8.7500001736, 1.20000004694, 9.57000009149, 1.03000002623, 8.76000005171, -0.0599998766184, 9.76000016868, 1.3000000149, 7.49000010177, 6.33299346298e-08, 7.82000015259, -1.08999990657, 8.79000014201, 1.67000006393, 9.57000004157, 1.42000010341, 8.75000012591, 1.52000004306, 7.39000012934, -1.17000005201, 8.00000005886, -0.55000000298, 9.0799999465, -1.22000005871, 7.27000010118, -0.999999972433, 8.5500000149, -1.07000000134, 9.18000004634, -1.50999999359, 5.60000019222, -0.220000004321, 8.7500001736, -1.20000004694, 9.81999995589, -1.11022302463e-16, 7.36000005916, 0.819999958873, 7.43000014767, 0.259999986887, 8.11000012547, 0.339999996722, 6.94000006452, 0.309999998808, 6.48000017375, -0.559999969006, 7.98000010669, 0.600000014901, 8.00000008866, 1.16999997303, 7.20000011846, 0.469999994636, 8.74000009432, -0.37000005126, 8.53999999672, -0.0900000421703, 8.9300000225, -0.259999952614, 7.73000001654, -0.759999961555, 7.30000003427, 0.12000004977, 9.73999992073, -1.95999990419, 6.91000015527, -0.740000030994, 9.57000009149, -1.03000002623, 7.36000005916, -0.819999958873, 10.3999999061, 0.0, 8.70999996901, -1.18999989465, 9.77000003636, 0.139999998212, 7.42999998972, 0.289999985546, 7.06000007108, -1.08999995649, 9.22000003114, 0.649999991059, 8.22999997854, 1.14000008091, 8.34000003546, 0.519999979734, 7.46000009641, 0.329999851882, 8.11000008076, 0.679999958426, 8.18000009328, -0.0500000655651, 7.53000002697, -0.330000023991, 8.27000008106, -0.150000026822, 9.600000038, -0.78000001505, 6.76000020444, -0.170000050515, 8.76000005171, 0.0599998766184, 7.43000014767, -0.259999986887, 8.70999996901, 1.18999989465, 10.8299999756, 6.66133814775e-16, 9.21000010461, 1.86999999315, 8.91000001967, 0.659999906421, 8.54000002801, -0.929999971837, 9.0900001882, 1.64999998882, 10.0099999988, 0.779999994934, 6.97000008255, 2.28999994978, 9.24000008762, -0.740000076443, 8.8400001055, -0.649999950081, 9.39000005335, -0.0199999983609, 9.07000005797, -2.04999992475, 7.96000011206, -0.200000017881, 9.63000005454, -2.18999994233, 6.97000022635, -0.900000017881, 9.76000016868, -1.3000000149, 8.11000012547, -0.339999996722, 9.77000003636, -0.139999998212, 9.21000010461, -1.86999999315, 11.9400001428, 4.4408920985e-16, 8.92000005051, -0.240000001937, 7.99000013232, -1.83999993637, 8.68000022069, 0.59999999404, 9.52000006765, 0.23000001803, 8.24000009283, 0.620000052005, 7.36000009418, -0.680000089556, 7.76000003234, 1.39999996796, 8.39999998808, 0.180000034422, 7.36000003755, -0.709999948144, 8.13999998704, -0.269999980479, 8.40000004545, -0.510000004768, 6.84000015244, -0.719999966323, 7.49000010177, -6.33299350739e-08, 6.94000006452, -0.309999998808, 7.42999998972, -0.289999985546, 8.91000001967, -0.659999906421, 8.92000005051, 0.240000001937, 9.72999985933, 0.0, 7.15000007227, -1.3699999328, 7.80000013709, 1.88000002176, 8.7099999921, 1.46000004798, 5.64000012115, 1.53000000089, 7.92000011012, 1.27999987498, 7.48000008136, 0.949999971688, 7.13000013426, 1.75999996752, 6.56000004873, 0.79999999404, 6.71000010833, 1.24999999851, 7.87000004977, 0.710000001788, 6.39000017703, 0.779999998659, 7.82000015259, 1.08999990657, 6.48000017375, 0.559999969006, 7.06000007108, 1.08999995649, 8.54000002801, 0.929999971837, 7.99000013232, 1.83999993637, 7.15000007227, 1.3699999328, 8.03000010371, -2.22044604925e-16, 6.49000018373, 2.12000002146, 8.32000011235, 2.82999995992, 6.05000013784, 2.05999997497, 8.54000022247, -1.51000006884, 9.20000014156, 0.119999961108, 10.1200000982, -0.890000042915, 7.36000016943, -1.57000002891, 8.68000006348, -0.560000017434, 9.62000009671, -1.71999997303, 7.76000025585, -1.34000008613, 8.79000014201, -1.67000006393, 7.98000010669, -0.600000014901, 9.22000003114, -0.649999991059, 9.0900001882, -1.64999998882, 8.68000022069, -0.59999999404, 7.80000013709, -1.88000002176, 6.49000018373, -2.12000002146, 11.350000219, -4.4408920985e-16, 9.93000008136, -0.469999940991, 8.02000019878, 0.699999981374, 9.15000007749, -1.46000005394, 8.94000006303, -0.170000019222, 9.90000006482, -0.610000068843, 8.03000004187, -0.650000038743, 9.0100000532, -0.170000062436, 9.37999999791, -0.940000022054, 8.0400001964, -0.260000056922, 9.57000004157, -1.42000010341, 8.00000008866, -1.16999997303, 8.22999997854, -1.14000008091, 10.0099999988, -0.779999994934, 9.52000006765, -0.23000001803, 8.7099999921, -1.46000004798, 8.32000011235, -2.82999995992, 9.93000008136, 0.469999940991, 12.6099999139, 0.0, 7.62000009224, 1.25999993697, 7.17000015929, -1.26000003681, 8.49000009432, -0.819999980479, 7.3400001204, -0.140000028014, 6.96000003979, -0.94999999702, 7.30000008792, -0.0999999321997, 8.11000008151, -2.11999990746, 5.22000023603, -0.460000044256, 8.75000012591, -1.52000004306, 7.20000011846, -0.469999994636, 8.34000003546, -0.519999979734, 6.97000008255, -2.28999994978, 8.24000009283, -0.620000052005, 5.64000012115, -1.53000000089, 6.05000013784, -2.05999997497, 8.02000019878, -0.699999981374, 7.62000009224, -1.25999993697, 8.50000011027, 2.22044604925e-16, 
+
+L3_zHERK_A_nk
+0.2, 0.4, 0.8, 0.1, 0.1, 0.1, 0.7, 0.1, 0.7, 0.9, 0.4, 0.9, 0.5, 0.3, 0.5, 0.8, 0.3, 0.4, 0.3, 0.9, 0.3, 0.3, 0.3, 0.1, 0.9, 0.1, 0.5, 0.8, 0.5, 0.3, 0.5, 0.4, 0.1, 0.9, 0.6, 0.7, 0.4, 0.6, 0.6, 0.7, 0.6, 0.8, 0.8, 0.4, 0.4, 0.2, 0.3, 0.9, 0.7, 0.9, 0.2, 0.9, 0.9, 0.6, 0.3, 0.3, 0.2, 0.5, 0.2, 0.2, 0.9, 0.6, 0.8, 0.7, 0.5, 0.8, 0.9, 0.1, 0.8, 0.6, 0.5, 0.8, 0.1, 0.7, 0.4, 0.7, 0.1, 0.1, 0.1, 0.4, 0.7, 0.8, 0.9, 0.2, 0.4, 0.1, 0.5, 0.3, 0.5, 0.5, 0.8, 0.3, 0.3, 0.8, 0.7, 0.8, 0.4, 0.9, 0.9, 0.5, 0.3, 0.6, 0.9, 0.2, 0.8, 0.8, 0.7, 0.1, 0.4, 0.1, 0.6, 0.4, 0.2, 0.9, 0.3, 0.6, 0.3, 0.6, 0.2, 0.3, 0.6, 0.9, 0.7, 0.6, 0.4, 0.4, 0.8, 0.4, 0.6, 0.6, 0.2, 0.7, 0.6, 0.2, 0.7, 0.3, 0.5, 0.2, 0.4, 0.7, 0.8, 0.4, 0.7, 0.2, 0.5, 0.7, 0.5, 0.8, 0.6, 0.2, 0.7, 0.2, 0.7, 0.2, 0.3, 0.3, 0.5, 0.9, 0.5, 0.7, 0.3, 0.5, 0.9, 0.3, 0.1, 0.7, 0.7, 0.8, 0.3, 0.7, 0.9, 0.7, 0.8, 0.4, 0.4, 0.1, 0.2, 0.9, 0.2, 0.4, 0.6, 0.4, 0.5, 0.5, 0.1, 0.3, 0.3, 0.9, 0.3, 0.2, 0.4, 0.2, 0.6, 0.1, 0.7, 0.6, 0.6, 0.7, 0.3, 0.8, 0.3, 0.1, 0.4, 0.1, 0.7, 0.8, 0.5, 0.8, 0.1, 0.2, 0.8, 0.1, 0.5, 0.7, 0.3, 0.4, 0.3, 0.8, 0.6, 0.7, 0.7, 0.4, 0.4, 0.7, 0.7, 0.8, 0.2, 0.9, 0.6, 0.2, 0.4, 0.6, 0.7, 0.8, 0.3, 0.1, 0.6, 0.7, 0.3, 0.5, 0.2, 0.3, 0.8, 0.5, 0.1, 0.5, 0.7, 0.7, 0.6, 0.1, 0.2, 0.7, 0.3, 0.6, 0.1, 0.1, 0.4, 0.3, 0.5, 0.7, 0.1, 0.7, 0.8, 0.3, 0.1, 0.4, 0.5, 0.8, 0.5, 0.5, 0.2, 0.4, 0.2, 0.6, 0.8, 0.8, 0.4, 0.9, 0.9, 0.2, 0.3, 0.6, 0.4, 0.6, 0.1, 0.7, 0.8, 0.7, 0.7, 0.7, 0.2, 0.5, 0.3, 0.7, 0.3, 0.3, 0.4, 0.1, 0.9, 0.3, 0.6, 0.7, 0.1, 0.4, 0.7, 0.6, 0.1, 0.8, 0.1, 0.5, 0.8, 0.7, 0.8, 0.8, 0.8, 0.3, 0.8, 0.7, 0.5, 0.8, 0.8, 0.9, 0.1, 0.4, 0.3, 0.6, 0.4, 0.3, 0.8, 0.7, 0.9, 0.1, 0.6, 0.6, 0.1, 0.5, 0.5, 0.7, 0.9, 0.8, 0.6, 0.3, 0.2, 0.8, 0.8, 0.3, 0.4, 0.5, 0.3, 0.6, 0.4, 0.4, 0.2, 0.3, 0.7, 0.9, 0.2, 0.1, 0.5, 0.7, 0.9, 0.4, 0.6, 0.2, 0.5, 0.6, 0.9, 0.5, 0.4, 0.8, 0.6, 0.5, 0.4, 0.7, 0.8, 0.9, 0.4, 0.6, 0.8, 0.2, 0.3, 0.6, 0.2, 0.8, 0.4, 0.9, 0.9, 0.3, 0.5, 0.1, 0.6, 0.5, 0.3, 0.3, 0.3, 0.8, 0.6, 0.4, 0.4, 0.3, 0.6, 0.7, 0.2, 0.5, 0.1, 0.1, 0.7, 0.8, 0.2, 0.5, 0.1, 0.1, 0.3, 0.3, 0.5, 0.4, 0.8, 0.1, 0.7, 0.5, 0.9, 0.6, 0.2, 0.7, 0.1, 0.9, 0.5, 0.7, 0.3, 0.9, 0.7, 0.3, 0.2, 0.4, 0.8, 0.1, 0.5, 0.4, 0.5, 0.3, 0.1, 0.6, 0.1, 0.4, 0.3, 0.8, 0.8, 0.7, 0.9, 0.5, 0.6, 0.5, 0.5, 0.8, 0.2, 0.5, 0.3, 0.2, 0.4, 0.2, 0.1, 0.4, 0.9, 0.8, 0.2, 0.3, 0.1, 0.3, 0.6, 0.1, 0.3, 0.2, 0.1, 0.5, 0.2, 0.6, 0.5, 0.3, 0.3, 0.2, 0.4, 0.5, 0.9, 0.5, 0.9, 0.1, 0.3, 0.4, 0.8, 0.9, 0.3, 0.2, 0.1, 0.1, 0.8, 0.1, 0.1, 0.7, 0.1, 0.3, 0.8, 0.7, 0.7, 0.4, 0.5, 0.1, 0.2, 0.3, 0.6, 0.8, 0.8, 0.8, 0.1, 0.7, 0.4, 0.9, 0.9, 0.3, 0.8, 0.2, 0.8, 0.6, 0.9, 0.9, 0.4, 0.7, 0.3, 0.1, 0.9, 0.8, 0.2, 0.9, 0.2, 0.6, 0.3, 0.7, 0.7, 0.3, 0.5, 0.7, 0.1, 0.2, 0.4, 0.6, 
+
+L3_zHERK_C_nn
+0.7, 0.0, 0.5, 0.7, 0.2, 0.9, 0.9, 0.8, 0.6, 0.9, 0.6, 0.4, 0.3, 0.1, 0.7, 0.4, 0.6, 0.3, 0.1, 0.4, 0.4, 0.7, 0.6, 0.8, 0.1, 0.4, 0.6, 0.7, 0.8, 0.1, 0.6, 0.5, 0.8, 0.4, 0.5, -0.7, 0.9, 0.0, 0.3, 0.2, 0.1, 0.5, 0.1, 0.2, 0.7, 0.7, 0.1, 0.1, 0.9, 0.2, 0.1, 0.4, 0.7, 0.3, 0.9, 0.9, 0.8, 0.4, 0.1, 0.2, 0.4, 0.4, 0.2, 0.3, 0.4, 0.7, 0.3, 0.1, 0.2, -0.9, 0.3, -0.2, 0.1, 0.0, 0.4, 0.3, 0.8, 0.6, 0.4, 0.1, 0.8, 0.2, 0.9, 0.4, 0.2, 0.2, 0.6, 0.5, 0.8, 0.4, 0.2, 0.5, 0.3, 0.9, 0.9, 0.6, 0.3, 0.7, 0.2, 0.7, 0.5, 0.2, 0.9, -0.8, 0.1, -0.5, 0.4, -0.3, 0.4, 0.0, 0.4, 0.3, 0.9, 0.4, 0.5, 0.2, 0.9, 0.7, 0.4, 0.2, 0.2, 0.5, 0.8, 0.2, 0.5, 0.2, 0.8, 0.3, 0.9, 0.1, 0.8, 0.5, 0.6, 0.7, 0.2, 0.4, 0.6, -0.9, 0.1, -0.2, 0.8, -0.6, 0.4, -0.3, 0.1, 0.0, 0.2, 0.8, 0.9, 0.8, 0.6, 0.8, 0.9, 0.6, 0.5, 0.7, 0.1, 0.1, 0.7, 0.1, 0.8, 0.3, 0.3, 0.3, 0.4, 0.2, 0.2, 0.9, 0.5, 0.5, 0.6, -0.4, 0.7, -0.7, 0.4, -0.1, 0.9, -0.4, 0.2, -0.8, 0.9, 0.0, 0.1, 0.3, 0.5, 0.1, 0.4, 0.5, 0.2, 0.6, 0.3, 0.7, 0.7, 0.7, 0.4, 0.9, 0.9, 0.2, 0.3, 0.7, 0.2, 0.5, 0.9, 0.8, 0.3, -0.1, 0.1, -0.1, 0.8, -0.2, 0.5, -0.2, 0.9, -0.8, 0.1, -0.3, 0.2, 0.0, 0.1, 0.1, 0.3, 0.5, 0.6, 0.2, 0.7, 0.2, 0.2, 0.6, 0.7, 0.1, 0.7, 0.8, 0.3, 0.5, 0.6, 0.6, 0.9, 0.3, 0.7, -0.4, 0.9, -0.2, 0.9, -0.4, 0.9, -0.7, 0.6, -0.8, 0.5, -0.1, 0.1, -0.1, 0.1, 0.0, 0.8, 0.3, 0.9, 0.7, 0.8, 0.8, 0.6, 0.3, 0.6, 0.9, 0.9, 0.1, 0.8, 0.6, 0.7, 0.2, 0.1, 0.1, 0.6, -0.3, 0.1, -0.4, 0.2, -0.2, 0.4, -0.2, 0.9, -0.6, 0.4, -0.5, 0.3, -0.5, 0.8, -0.3, 0.5, 0.0, 0.7, 0.1, 0.9, 0.1, 0.8, 0.8, 0.9, 0.9, 0.3, 0.7, 0.3, 0.4, 0.1, 0.6, 0.5, 0.9, 0.1, -0.4, 0.7, -0.3, 0.6, -0.5, 0.2, -0.5, 0.5, -0.7, 0.2, -0.6, 0.6, -0.2, 0.9, -0.7, 0.7, -0.1, 0.3, 0.0, 0.2, 0.2, 0.9, 0.7, 0.7, 0.8, 0.9, 0.2, 0.3, 0.2, 0.6, 0.7, 0.1, 0.2, 0.4, -0.7, 0.9, -0.9, 0.8, -0.4, 0.8, -0.2, 0.1, -0.1, 0.3, -0.7, 0.7, -0.2, 0.8, -0.8, 0.9, -0.1, 0.2, -0.2, 0.7, 0.0, 0.2, 0.7, 0.4, 0.8, 0.4, 0.4, 0.1, 0.6, 0.5, 0.4, 0.9, 0.3, 0.6, -0.8, 0.8, -0.4, 0.2, -0.5, 0.5, -0.2, 0.7, -0.1, 0.7, -0.7, 0.2, -0.6, 0.6, -0.3, 0.8, -0.8, 0.9, -0.7, 0.2, -0.7, 0.7, 0.0, 0.4, 0.1, 0.1, 0.8, 0.5, 0.8, 0.8, 0.2, 0.9, 0.8, 0.1, -0.4, 0.1, -0.2, 0.3, -0.9, 0.8, -0.3, 0.8, -0.3, 0.4, -0.9, 0.7, -0.1, 0.6, -0.9, 0.9, -0.9, 0.7, -0.8, 0.4, -0.8, 0.4, -0.1, 0.1, 0.0, 0.4, 0.8, 0.7, 0.5, 0.3, 0.2, 0.8, 0.5, 0.6, -0.7, 0.4, -0.4, 0.9, -0.6, 0.9, -0.1, 0.3, -0.3, 0.9, -0.2, 0.7, -0.8, 0.9, -0.1, 0.3, -0.7, 0.9, -0.2, 0.4, -0.4, 0.1, -0.8, 0.4, -0.8, 0.9, 0.0, 0.5, 0.8, 0.2, 0.1, 0.3, 0.1, 0.8, -0.1, 0.2, -0.3, 0.3, -0.7, 0.8, -0.5, 0.4, -0.2, 0.3, -0.7, 0.3, -0.5, 0.8, -0.6, 0.3, -0.4, 0.3, -0.2, 0.1, -0.6, 0.5, -0.8, 0.7, -0.5, 0.5, -0.8, 0.1, 0.0, 0.1, 0.4, 0.7, 0.9, 0.6, -0.5, 0.4, -0.7, 0.2, -0.7, 0.6, -0.7, 0.2, -0.9, 0.2, -0.5, 0.6, -0.6, 0.7, -0.2, 0.1, -0.6, 0.6, -0.7, 0.5, -0.4, 0.8, -0.2, 0.3, -0.2, 0.2, -0.1, 0.1, -0.4, 0.9, 0.0, 0.9, 0.1, 0.8, -0.4, 0.3, -0.1, 0.5, -0.2, 0.2, -0.4, 0.5, -0.5, 0.9, -0.8, 0.9, -0.3, 0.1, -0.1, 0.5, -0.9, 0.1, -0.2, 0.9, -0.3, 0.9, -0.8, 0.8, -0.5, 0.3, -0.1, 0.7, -0.9, 0.9, -0.1, 0.7, 0.0, 
+
+L3_zHERK_o_N
+9.46, 2.77555756156e-17, 8.78, -0.52, 7.37, 0.5, 9.1, 0.78, 8.0, 1.13, 7.71, -0.25, 6.62, -0.52, 7.27, -0.54, 8.0, -1.08, 7.26, -0.13, 7.88, 1.1, 8.01, 0.59, 6.33, -0.43, 7.08, -0.44, 6.11, -0.23, 7.6, 0.41, 9.0, -0.3, 8.78, 0.52, 13.01, 7.77156117238e-16, 9.56, 1.07, 10.12, 1.94, 9.12, 1.61, 9.41, 0.75, 8.4, 0.9, 8.68, 0.64, 9.16, -0.44, 10.22, 0.5, 10.32, 2.16, 10.32, 0.75, 7.96, 1.08, 8.89, 0.67, 7.34, 1.8, 9.5, 1.88, 10.01, 0.32, 7.37, -0.5, 9.56, -1.07, 10.62, -1.66533453694e-15, 9.08, 0.18, 8.88, 0.93, 8.05, -1.11, 8.53, -0.34, 7.91, -0.22, 8.55, -1.58, 9.01, 0.17, 9.1, 0.22, 8.45, -0.29, 7.76, 0.69, 9.62, 0.37, 6.44, 0.49, 8.23, 1.31, 8.88, -0.53, 9.1, -0.78, 10.12, -1.94, 9.08, -0.18, 11.22, -9.43689570931e-16, 8.56, 0.91, 9.31, -0.99, 8.41, -0.42, 8.44, 4.4408920985e-16, 9.02, -1.51, 9.12, 0.41, 9.78, 0.65, 9.67, -0.29, 8.07, -0.03, 8.66, -0.97, 7.48, 0.32, 9.12, 1.33, 9.51, -0.24, 8.0, -1.13, 9.12, -1.61, 8.88, -0.93, 8.56, -0.91, 9.67, -4.99600361081e-16, 7.44, -0.17, 8.18, -0.02, 8.22, -0.66, 9.32, -0.9, 9.26, -0.45, 8.56, -0.82, 9.38, -1.29, 8.0, -0.49, 8.16, -0.66, 6.43, -0.55, 8.22, 0.74, 9.43, -0.91, 7.71, 0.25, 9.41, -0.75, 8.05, 1.11, 9.31, 0.99, 7.44, 0.17, 10.02, -1.11022302463e-16, 7.29, 0.25, 7.24, -0.28, 8.38, -0.11, 7.71, 1.36, 7.99, 1.71, 8.67, 0.86, 7.33, 1.04, 8.44, -0.46, 6.3, 0.85, 7.28, 1.2, 9.21, 1.13, 6.62, 0.52, 8.4, -0.9, 8.53, 0.34, 8.41, 0.42, 8.18, 0.02, 7.29, -0.25, 9.86, -3.33066907388e-16, 7.42, -1.1, 8.32, -0.64, 8.84, -0.57, 8.41, -0.65, 8.86, 0.64, 6.75, 0.42, 9.21, 0.47, 7.13, 0.27, 7.64, 1.92, 8.18, -0.33, 7.27, 0.54, 8.68, -0.64, 7.91, 0.22, 8.44, 4.4408920985e-16, 8.22, 0.66, 7.24, 0.28, 7.42, 1.1, 9.05, 1.31838984174e-16, 8.14, 0.31, 8.63, 0.64, 9.37, 0.56, 8.86, 1.49, 6.91, 1.23, 8.27, 0.32, 6.53, 1.19, 7.78, 1.81, 8.27, -0.38, 8.0, 1.08, 9.16, 0.44, 8.55, 1.58, 9.02, 1.51, 9.32, 0.9, 8.38, 0.11, 8.32, 0.64, 8.14, -0.31, 10.58, 0.0, 9.41, 0.5, 9.05, 1.26, 9.51, 1.11, 7.78, 1.04, 8.73, 1.76, 6.19, 1.38, 7.49, 2.47, 9.19, 1.03, 7.26, 0.13, 10.22, -0.5, 9.01, -0.17, 9.12, -0.41, 9.26, 0.45, 7.71, -1.36, 8.84, 0.57, 8.63, -0.64, 9.41, -0.5, 11.34, -6.66133814775e-16, 9.51, 0.38, 10.12, 0.57, 8.08, 0.53, 8.59, 0.29, 6.68, 0.51, 8.02, 1.78, 9.44, -0.63, 7.88, -1.1, 10.32, -2.16, 9.1, -0.22, 9.78, -0.65, 8.56, 0.82, 7.99, -1.71, 8.41, 0.65, 9.37, -0.56, 9.05, -1.26, 9.51, -0.38, 11.18, -1.11022302463e-16, 8.95, 1.11, 7.2, 0.54, 8.1, 0.3, 6.33, 1.08, 7.92, 1.19, 10.12, -0.93, 8.01, -0.59, 10.32, -0.75, 8.45, 0.29, 9.67, 0.29, 9.38, 1.29, 8.67, -0.86, 8.86, -0.64, 8.86, -1.49, 9.51, -1.11, 10.12, -0.57, 8.95, -1.11, 11.8, -7.21644966006e-16, 7.92, 0.65, 8.35, 0.48, 6.89, 0.66, 9.39, 1.45, 10.24, -0.11, 6.33, 0.43, 7.96, -1.08, 7.76, -0.69, 8.07, 0.03, 8.0, 0.49, 7.33, -1.04, 6.75, -0.42, 6.91, -1.23, 7.78, -1.04, 8.08, -0.53, 7.2, -0.54, 7.92, -0.65, 7.71, -8.04911692853e-16, 7.16, 0.53, 5.91, 0.42, 6.94, 0.47, 8.62, 0.02, 7.08, 0.44, 8.89, -0.67, 9.62, -0.37, 8.66, 0.97, 8.16, 0.66, 8.44, 0.46, 9.21, -0.47, 8.27, -0.32, 8.73, -1.76, 8.59, -0.29, 8.1, -0.3, 8.35, -0.48, 7.16, -0.53, 11.03, 3.33066907388e-16, 7.23, 0.53, 8.38, 1.54, 8.12, 0.28, 6.11, 0.23, 7.34, -1.8, 6.44, -0.49, 7.48, -0.32, 6.43, 0.55, 6.3, -0.85, 7.13, -0.27, 6.53, -1.19, 6.19, -1.38, 6.68, -0.51, 6.33, -1.08, 6.89, -0.66, 5.91, -0.42, 7.23, -0.53, 6.76, 4.16333634234e-16, 6.15, 1.06, 6.56, 0.85, 7.6, -0.41, 9.5, -1.88, 8.23, -1.31, 9.12, -1.33, 8.22, -0.74, 7.28, -1.2, 7.64, -1.92, 7.78, -1.81, 7.49, -2.47, 8.02, -1.78, 7.92, -1.19, 9.39, -1.45, 6.94, -0.47, 8.38, -1.54, 6.15, -1.06, 10.74, 4.4408920985e-16, 8.97, -1.05, 9.0, 0.3, 10.01, -0.32, 8.88, 0.53, 9.51, 0.24, 9.43, 0.91, 9.21, -1.13, 8.18, 0.33, 8.27, 0.38, 9.19, -1.03, 9.44, 0.63, 10.12, 0.93, 10.24, 0.11, 8.62, -0.02, 8.12, -0.28, 6.56, -0.85, 8.97, 1.05, 12.29, 5.55111512313e-16, 
+
+L3_zHERK_A_kn
+0.4, 0.7, 0.5, 0.5, 0.2, 0.2, 0.3, 0.6, 0.3, 0.5, 0.1, 0.2, 0.2, 0.2, 0.7, 0.4, 0.1, 0.1, 0.6, 0.7, 0.3, 0.8, 0.2, 0.2, 0.4, 0.4, 0.3, 0.7, 0.1, 0.3, 0.9, 0.1, 0.5, 0.7, 0.1, 0.5, 0.6, 0.8, 0.9, 0.1, 0.4, 0.9, 0.7, 0.5, 0.8, 0.7, 0.7, 0.6, 0.1, 0.6, 0.8, 0.8, 0.4, 0.6, 0.4, 0.2, 0.6, 0.8, 0.5, 0.6, 0.8, 0.2, 0.3, 0.3, 0.2, 0.8, 0.2, 0.7, 0.4, 0.2, 0.9, 0.3, 0.2, 0.3, 0.6, 0.6, 0.2, 0.4, 0.4, 0.2, 0.6, 0.9, 0.2, 0.2, 0.6, 0.4, 0.7, 0.4, 0.8, 0.8, 0.5, 0.8, 0.5, 0.1, 0.6, 0.3, 0.5, 0.4, 0.6, 0.4, 0.8, 0.5, 0.9, 0.6, 0.3, 0.5, 0.1, 0.9, 0.8, 0.6, 0.6, 0.7, 0.3, 0.6, 0.2, 0.3, 0.3, 0.5, 0.9, 0.2, 0.1, 0.9, 0.4, 0.4, 0.7, 0.8, 0.6, 0.2, 0.7, 0.8, 0.6, 0.1, 0.3, 0.7, 0.6, 0.2, 0.8, 0.7, 0.6, 0.5, 0.4, 0.9, 0.5, 0.9, 0.9, 0.6, 0.4, 0.6, 0.8, 0.5, 0.7, 0.1, 0.8, 0.1, 0.1, 0.3, 0.5, 0.4, 0.4, 0.4, 0.3, 0.3, 0.7, 0.4, 0.9, 0.3, 0.7, 0.9, 0.7, 0.6, 0.5, 0.4, 0.4, 0.6, 0.9, 0.3, 0.8, 0.9, 0.2, 0.6, 0.6, 0.6, 0.8, 0.5, 0.6, 0.7, 0.6, 0.7, 0.5, 0.7, 0.9, 0.9, 0.7, 0.4, 0.3, 0.8, 0.1, 0.9, 0.6, 0.1, 0.2, 0.1, 0.6, 0.3, 0.3, 0.9, 0.9, 0.1, 0.8, 0.9, 0.3, 0.5, 0.1, 0.7, 0.7, 0.7, 0.4, 0.9, 0.9, 0.5, 0.6, 0.4, 0.4, 0.5, 0.8, 0.4, 0.3, 0.2, 0.5, 0.5, 0.3, 0.4, 0.1, 0.4, 0.7, 0.1, 0.7, 0.7, 0.9, 0.2, 0.5, 0.4, 0.9, 0.2, 0.1, 0.5, 0.8, 0.6, 0.1, 0.5, 0.4, 0.5, 0.3, 0.3, 0.1, 0.2, 0.6, 0.9, 0.4, 0.5, 0.6, 0.2, 0.1, 0.3, 0.2, 0.9, 0.6, 0.7, 0.7, 0.4, 0.3, 0.2, 0.1, 0.4, 0.1, 0.2, 0.5, 0.3, 0.9, 0.2, 0.7, 0.3, 0.8, 0.1, 0.4, 0.1, 0.9, 0.3, 0.9, 0.4, 0.1, 0.3, 0.9, 0.5, 0.8, 0.6, 0.7, 0.1, 0.6, 0.5, 0.3, 0.8, 0.3, 0.3, 0.6, 0.3, 0.2, 0.2, 0.2, 0.6, 0.7, 0.2, 0.2, 0.7, 0.3, 0.4, 0.7, 0.3, 0.8, 0.8, 0.9, 0.7, 0.7, 0.4, 0.5, 0.2, 0.4, 0.1, 0.2, 0.8, 0.1, 0.1, 0.9, 0.1, 0.8, 0.5, 0.9, 0.2, 0.6, 0.8, 0.9, 0.1, 0.6, 0.8, 0.1, 0.6, 0.5, 0.9, 0.6, 0.3, 0.9, 0.6, 0.2, 0.7, 0.7, 0.1, 0.5, 0.3, 0.9, 0.8, 0.3, 0.4, 0.8, 0.9, 0.3, 0.6, 0.1, 0.7, 0.4, 0.5, 0.6, 0.2, 0.4, 0.2, 0.9, 0.9, 0.8, 0.4, 0.7, 0.7, 0.8, 0.6, 0.7, 0.7, 0.7, 0.4, 0.6, 0.3, 0.2, 0.7, 0.2, 0.2, 0.2, 0.6, 0.2, 0.3, 0.5, 0.7, 0.6, 0.4, 0.1, 0.2, 0.4, 0.7, 0.7, 0.3, 0.1, 0.6, 0.6, 0.1, 0.4, 0.9, 0.4, 0.9, 0.9, 0.1, 0.8, 0.6, 0.7, 0.5, 0.7, 0.2, 0.2, 0.9, 0.2, 0.6, 0.7, 0.2, 0.2, 0.1, 0.9, 0.7, 0.8, 0.8, 0.6, 0.7, 0.1, 0.9, 0.5, 0.6, 0.3, 0.5, 0.4, 0.3, 0.9, 0.3, 0.7, 0.1, 0.7, 0.5, 0.5, 0.2, 0.6, 0.6, 0.8, 0.5, 0.6, 0.1, 0.2, 0.4, 0.9, 0.2, 0.1, 0.9, 0.7, 0.2, 0.6, 0.9, 0.8, 0.8, 0.8, 0.7, 0.9, 0.8, 0.8, 0.6, 0.1, 0.1, 0.7, 0.9, 0.8, 0.5, 0.5, 0.2, 0.7, 0.8, 0.9, 0.8, 0.3, 0.5, 0.9, 0.6, 0.5, 0.7, 0.7, 0.3, 0.5, 0.5, 0.3, 0.6, 0.9, 0.8, 0.5, 0.1, 0.9, 0.2, 0.3, 0.5, 0.9, 0.5, 0.4, 0.5, 0.6, 0.5, 0.5, 0.1, 0.8, 0.9, 0.2, 0.5, 0.1, 0.1, 0.2, 0.8, 0.4, 0.8, 0.8, 0.7, 0.9, 0.2, 0.9, 0.6, 0.8, 0.1, 0.6, 0.8, 0.8, 0.4, 0.1, 0.8, 0.7, 0.6, 0.2, 0.8, 
+
+L3_zHERK_o_H
+10.01, -1.11022302463e-16, 8.04, 0.77, 7.53, 1.36, 9.86, 1.94, 8.93, 1.85, 7.68, 0.77, 7.58, 0.63, 7.69, 0.21, 6.88, -0.82, 7.57, 2.06, 7.2, 0.95, 8.53, 1.49, 6.7, 0.76, 7.32, 2.07, 7.69, 1.13, 8.25, 7.77156117238e-16, 8.31, 0.63, 8.04, -0.77, 12.03, -2.77555756156e-16, 9.18, -0.21, 10.13, 1.27, 9.05, 0.33, 9.86, 0.29, 8.91, 0.99, 9.79, -0.12, 8.31, -0.23, 9.8, 0.01, 8.97, 1.79, 10.49, 0.1, 9.07, 0.73, 8.88, 0.5, 8.26, 0.59, 9.68, 0.31, 9.31, 0.84, 7.53, -1.36, 9.18, 0.21, 10.96, -4.57966997658e-16, 9.17, 1.17, 9.59, 1.29, 9.35, 0.33, 9.24, 1.36, 9.16, 1.0, 7.35, 0.36, 8.77, 1.51, 8.31, 1.2, 9.09, 0.69, 7.85, 1.75, 8.94, 1.45, 7.96, 1.64, 8.36, 0.51, 8.45, 1.08, 9.86, -1.94, 10.13, -1.27, 9.17, -1.17, 13.39, -1.88737914186e-15, 10.16, 0.35, 10.6, -0.52, 10.62, -0.45, 9.87, 0.21, 9.41, -1.29, 9.78, -0.33, 10.33, -0.18, 11.23, -0.2, 10.43, 0.84, 10.46, 0.05, 9.12, 0.53, 9.69, -0.68, 9.9, 0.15, 8.93, -1.85, 9.05, -0.33, 9.59, -1.29, 10.16, -0.35, 10.27, -1.02695629778e-15, 9.17, 0.4, 9.49, 0.39, 9.08, 0.1, 8.67, -0.59, 8.71, 0.71, 7.63, -0.55, 9.97, 0.22, 9.1, 0.03, 8.67, 0.49, 8.41, 0.45, 8.41, 0.46, 8.89, 0.14, 7.68, -0.77, 9.86, -0.29, 9.35, -0.33, 10.6, 0.52, 9.17, -0.4, 11.19, -2.15105711021e-16, 8.81, 0.94, 9.06, 0.24, 8.49, 0.57, 8.57, 0.77, 8.08, 1.11, 9.75, 1.82, 9.01, 1.66, 9.15, 0.56, 7.79, 1.04, 8.39, 0.19, 9.32, 1.19, 7.58, -0.63, 8.91, -0.99, 9.24, -1.36, 10.62, 0.45, 9.49, -0.39, 8.81, -0.94, 10.46, 6.93889390391e-16, 8.13, -0.6, 8.21, -0.7, 8.57, -0.97, 8.69, -0.44, 9.04, 0.52, 8.5, 0.32, 8.89, 0.41, 8.36, 0.45, 8.83, -0.61, 9.73, 0.18, 7.69, -0.21, 9.79, 0.12, 9.16, -1.0, 9.87, -0.21, 9.08, -0.1, 9.06, -0.24, 8.13, 0.6, 10.55, 8.881784197e-16, 9.18, -0.27, 8.8, 0.71, 8.64, 1.27, 9.02, 0.29, 8.64, 1.06, 8.73, 0.43, 8.85, 1.43, 8.98, -0.59, 9.31, 1.12, 6.88, 0.82, 8.31, 0.23, 7.35, -0.36, 9.41, 1.29, 8.67, 0.59, 8.49, -0.57, 8.21, 0.7, 9.18, 0.27, 9.75, -2.22044604925e-16, 7.49, 0.3, 9.04, 0.42, 9.22, 1.67, 8.84, 1.11, 8.29, 1.01, 7.59, 1.17, 7.48, 1.24, 8.64, 1.9, 7.57, -2.06, 9.8, -0.01, 8.77, -1.51, 9.78, 0.33, 8.71, -0.71, 8.57, -0.77, 8.57, 0.97, 8.8, -0.71, 7.49, -0.3, 10.61, 7.77156117238e-16, 8.09, 0.83, 9.94, 0.39, 8.31, 2.05, 9.55, 1.33, 7.39, 0.94, 8.81, -0.02, 7.92, 0.78, 7.2, -0.95, 8.97, -1.79, 8.31, -1.2, 10.33, 0.18, 7.63, 0.55, 8.08, -1.11, 8.69, 0.44, 8.64, -1.27, 9.04, -0.42, 8.09, -0.83, 10.62, -1.11022302463e-16, 8.29, 0.25, 8.29, 0.68, 8.87, 0.59, 7.17, 0.52, 8.0, -0.98, 9.15, -0.06, 8.53, -1.49, 10.49, -0.1, 9.09, -0.69, 11.23, 0.2, 9.97, -0.22, 9.75, -1.82, 9.04, -0.52, 9.02, -0.29, 9.22, -1.67, 9.94, -0.39, 8.29, -0.25, 12.1, -2.22044604925e-16, 8.66, 0.56, 8.53, 1.48, 8.33, 1.41, 9.35, -1.11022302463e-16, 9.33, 0.75, 6.7, -0.76, 9.07, -0.73, 7.85, -1.75, 10.43, -0.84, 9.1, -0.03, 9.01, -1.66, 8.5, -0.32, 8.64, -1.06, 8.84, -1.11, 8.31, -2.05, 8.29, -0.68, 8.66, -0.56, 9.59, 5.55111512313e-16, 8.68, 0.76, 7.94, 0.92, 8.05, -0.41, 9.01, 0.65, 7.32, -2.07, 8.88, -0.5, 8.94, -1.45, 10.46, -0.05, 8.67, -0.49, 9.15, -0.56, 8.89, -0.41, 8.73, -0.43, 8.29, -1.01, 9.55, -1.33, 8.87, -0.59, 8.53, -1.48, 8.68, -0.76, 11.48, -8.32667268469e-16, 8.48, 1.14, 8.39, -0.25, 8.31, 0.5, 7.69, -1.13, 8.26, -0.59, 7.96, -1.64, 9.12, -0.53, 8.41, -0.45, 7.79, -1.04, 8.36, -0.45, 8.85, -1.43, 7.59, -1.17, 7.39, -0.94, 7.17, -0.52, 8.33, -1.41, 7.94, -0.92, 8.48, -1.14, 9.58, 1.94289029309e-16, 7.84, -0.73, 9.21, 1.0, 8.25, -6.66133814775e-16, 9.68, -0.31, 8.36, -0.51, 9.69, 0.68, 8.41, -0.46, 8.39, -0.19, 8.83, 0.61, 8.98, 0.59, 7.48, -1.24, 8.81, 0.02, 8.0, 0.98, 9.35, 1.05471187339e-15, 8.05, 0.41, 8.39, 0.25, 7.84, 0.73, 11.26, 1.05471187339e-15, 9.34, 1.56, 8.31, -0.63, 9.31, -0.84, 8.45, -1.08, 9.9, -0.15, 8.89, -0.14, 9.32, -1.19, 9.73, -0.18, 9.31, -1.12, 8.64, -1.9, 7.92, -0.78, 9.15, 0.06, 9.33, -0.75, 9.01, -0.65, 8.31, -0.5, 9.21, -1.0, 9.34, -1.56, 10.77, 5.55111512313e-17, 
+
+L3_sSYR2K_A_nk
+0.2, 0.7, 0.6, 0.9, 0.4, 0.3, 0.2, 0.1, 0.7, 0.8, 0.2, 0.7, 0.2, 0.7, 0.7, 0.4, 0.1, 0.4, 0.6, 0.3, 0.2, 0.7, 0.2, 0.8, 0.7, 0.1, 0.8, 0.6, 0.2, 0.9, 0.5, 0.1, 0.3, 0.1, 0.4, 0.4, 0.7, 0.4, 0.4, 0.5, 0.1, 0.7, 0.2, 0.5, 0.6, 0.7, 0.9, 0.9, 0.3, 0.2, 0.9, 0.7, 0.7, 0.7, 0.3, 0.2, 0.3, 0.1, 0.7, 0.2, 0.1, 0.5, 0.3, 0.3, 0.4, 0.1, 0.8, 0.6, 0.1, 0.9, 0.9, 0.3, 0.3, 0.9, 0.4, 0.7, 0.4, 0.4, 0.6, 0.4, 0.9, 0.4, 0.2, 0.8, 0.2, 0.2, 0.4, 0.4, 0.4, 0.9, 0.1, 0.9, 0.4, 0.8, 0.6, 0.1, 0.9, 0.4, 0.9, 0.9, 0.8, 0.9, 0.5, 0.4, 0.9, 0.3, 0.4, 0.7, 0.3, 0.6, 0.9, 0.4, 0.1, 0.2, 0.2, 0.5, 0.2, 0.8, 0.9, 0.7, 0.1, 0.3, 0.9, 0.1, 0.4, 0.9, 0.2, 0.3, 0.1, 0.3, 0.9, 0.7, 0.3, 0.6, 0.5, 0.4, 0.1, 0.8, 0.9, 0.5, 0.7, 0.9, 0.1, 0.1, 0.6, 0.2, 0.4, 0.1, 0.1, 0.6, 0.6, 0.2, 0.7, 0.3, 0.4, 0.1, 0.7, 0.2, 0.1, 0.7, 0.9, 0.2, 0.1, 0.8, 0.6, 0.8, 0.8, 0.6, 0.4, 0.8, 0.4, 0.9, 0.1, 0.4, 0.1, 0.1, 0.2, 0.3, 0.4, 0.1, 0.9, 0.5, 0.9, 0.8, 0.1, 0.4, 0.6, 0.7, 0.1, 0.3, 0.7, 0.6, 0.1, 0.7, 0.9, 0.2, 0.5, 0.6, 0.3, 0.7, 0.8, 0.3, 0.9, 0.4, 0.5, 0.4, 0.4, 0.6, 0.5, 0.7, 0.6, 0.5, 0.4, 0.7, 0.8, 0.5, 0.8, 0.1, 0.3, 0.8, 0.8, 0.8, 0.4, 0.7, 0.6, 0.3, 0.5, 0.4, 0.9, 0.2, 0.8, 0.3, 0.8, 0.4, 0.1, 0.6, 0.5, 0.3, 0.2, 0.3, 0.3, 0.9, 0.7, 0.8, 0.5, 0.5, 0.3, 0.9, 0.3, 0.9, 0.7, 0.3, 0.1, 0.4, 0.9, 0.9, 0.5, 0.3, 0.9, 0.5, 0.1, 0.5, 0.2, 0.6, 0.7, 0.8, 0.8, 0.5, 0.8, 0.5, 0.2, 0.8, 
+
+L3_sSYR2K_B_nk
+0.3, 0.8, 0.6, 0.5, 0.7, 0.4, 0.3, 0.3, 0.6, 0.3, 0.5, 0.6, 0.6, 0.2, 0.1, 0.6, 0.5, 0.7, 0.4, 0.5, 0.7, 0.1, 0.4, 0.2, 0.9, 0.9, 0.5, 0.5, 0.5, 0.3, 0.2, 0.9, 0.9, 0.1, 0.9, 0.8, 0.2, 0.9, 0.1, 0.6, 0.4, 0.5, 0.5, 0.4, 0.1, 0.3, 0.9, 0.9, 0.8, 0.1, 0.5, 0.2, 0.7, 0.4, 0.5, 0.6, 0.1, 0.4, 0.1, 0.5, 0.7, 0.9, 0.6, 0.5, 0.2, 0.8, 0.2, 0.6, 0.4, 0.1, 0.9, 0.1, 0.7, 0.7, 0.9, 0.3, 0.3, 0.5, 0.2, 0.1, 0.2, 0.2, 0.2, 0.3, 0.3, 0.9, 0.2, 0.9, 0.5, 0.1, 0.7, 0.7, 0.9, 0.6, 0.6, 0.9, 0.8, 0.7, 0.6, 0.6, 0.5, 0.4, 0.4, 0.9, 0.3, 0.1, 0.8, 0.5, 0.5, 0.1, 0.5, 0.4, 0.3, 0.7, 0.6, 0.5, 0.3, 0.1, 0.5, 0.9, 0.8, 0.5, 0.8, 0.8, 0.1, 0.5, 0.4, 0.1, 0.1, 0.6, 0.6, 0.4, 0.4, 0.9, 0.3, 0.3, 0.6, 0.2, 0.7, 0.4, 0.4, 0.4, 0.9, 0.5, 0.3, 0.6, 0.3, 0.6, 0.2, 0.9, 0.9, 0.5, 0.8, 0.3, 0.6, 0.6, 0.9, 0.2, 0.9, 0.1, 0.8, 0.7, 0.1, 0.7, 0.7, 0.6, 0.6, 0.6, 0.2, 0.4, 0.1, 0.8, 0.7, 0.8, 0.7, 0.8, 0.6, 0.5, 0.5, 0.7, 0.1, 0.6, 0.6, 0.4, 0.4, 0.4, 0.9, 0.6, 0.2, 0.2, 0.5, 0.9, 0.3, 0.2, 0.1, 0.7, 0.6, 0.6, 0.8, 0.6, 0.7, 0.9, 0.3, 0.9, 0.4, 0.4, 0.8, 0.9, 0.5, 0.7, 0.6, 0.1, 0.1, 0.7, 0.4, 0.6, 0.5, 0.3, 0.5, 0.3, 0.3, 0.9, 0.3, 0.2, 0.5, 0.3, 0.1, 0.3, 0.1, 0.7, 0.3, 0.9, 0.9, 0.5, 0.5, 0.8, 0.3, 0.5, 0.8, 0.1, 0.8, 0.7, 0.1, 0.1, 0.8, 0.1, 0.5, 0.4, 0.7, 0.4, 0.9, 0.1, 0.5, 0.3, 0.7, 0.6, 0.5, 0.9, 0.6, 0.7, 0.4, 0.3, 0.2, 0.5, 0.2, 0.7, 0.8, 0.3, 0.6, 0.5, 0.3, 0.7, 
+
+L3_sSYR2K_C_nn
+0.7, 0.3, 0.2, 0.7, 0.4, 0.5, 0.5, 0.7, 0.6, 0.5, 0.9, 0.9, 0.8, 0.8, 0.7, 0.9, 0.8, 0.3, 0.9, 0.5, 0.2, 0.4, 0.3, 0.7, 0.7, 0.5, 0.6, 0.6, 0.2, 0.4, 0.7, 0.2, 0.8, 0.3, 0.2, 0.5, 0.9, 0.6, 0.8, 0.4, 0.3, 0.5, 0.3, 0.7, 0.7, 0.9, 0.3, 0.1, 0.6, 0.7, 0.3, 0.7, 0.2, 0.6, 0.1, 0.6, 0.1, 0.9, 0.7, 0.9, 0.9, 0.6, 0.1, 0.2, 0.1, 0.6, 0.4, 0.6, 0.4, 0.4, 0.8, 0.6, 0.4, 0.1, 0.4, 0.1, 0.7, 0.9, 0.4, 0.9, 0.3, 0.5, 0.8, 0.2, 0.6, 0.5, 0.3, 0.4, 0.1, 0.1, 0.7, 0.8, 0.6, 0.1, 0.2, 0.1, 0.1, 0.1, 0.9, 0.9, 0.5, 0.6, 0.5, 0.7, 0.3, 0.9, 0.4, 0.8, 0.6, 0.6, 0.8, 0.5, 0.6, 0.7, 0.7, 0.2, 0.9, 0.8, 0.7, 0.7, 0.7, 0.5, 0.7, 0.1, 0.6, 0.6, 0.7, 0.9, 0.1, 0.7, 0.1, 0.3, 0.2, 0.8, 0.7, 0.9, 0.6, 0.5, 0.3, 0.9, 0.7, 0.1, 0.8, 0.9, 0.8, 0.8, 0.5, 0.1, 0.8, 0.1, 0.2, 0.4, 0.3, 0.5, 0.6, 0.7, 0.9, 0.9, 0.2, 0.5, 0.1, 0.8, 0.8, 0.7, 0.2, 0.8, 0.9, 0.9, 0.1, 0.2, 0.9, 0.6, 0.7, 0.6, 0.4, 0.1, 0.6, 0.7, 0.5, 0.7, 0.5, 0.2, 0.9, 0.2, 0.6, 0.7, 0.4, 0.9, 0.2, 0.9, 0.1, 0.9, 0.1, 0.7, 0.1, 0.1, 0.2, 0.2, 0.6, 0.3, 0.3, 0.8, 0.6, 0.7, 0.8, 0.4, 0.3, 0.2, 0.3, 0.1, 0.7, 0.3, 0.8, 0.8, 0.9, 0.3, 0.8, 0.2, 0.7, 0.5, 0.8, 0.8, 0.7, 0.1, 0.1, 0.5, 0.9, 0.2, 0.2, 0.1, 0.9, 0.2, 0.3, 0.2, 0.4, 0.5, 0.6, 0.5, 0.7, 0.2, 0.6, 0.6, 0.8, 0.9, 0.9, 0.8, 0.2, 0.9, 0.6, 0.8, 0.7, 0.5, 0.1, 0.1, 0.5, 0.9, 0.8, 0.7, 0.4, 0.2, 0.5, 0.8, 0.7, 0.4, 0.1, 0.7, 0.6, 0.5, 0.6, 0.1, 0.8, 0.1, 0.8, 0.3, 0.3, 0.6, 0.6, 0.6, 0.7, 0.9, 0.3, 0.2, 0.4, 0.7, 0.8, 0.5, 0.5, 0.1, 0.7, 
+
+L3_sSYR2K_o_N
+8.0400006175, 7.79999953508, 7.75000019372, 7.22999972105, 7.5300001204, 7.22000026703, 8.66999912262, 7.55000036955, 8.07000029087, 7.45000076294, 8.91000020504, 8.14999997616, 9.66999989748, 8.62000018358, 7.96999949217, 8.5799998045, 9.02000027895, 7.79999953508, 7.19999921322, 8.31999969482, 6.52999992669, 7.42999973893, 8.44000035524, 9.38999956846, 7.7600004077, 8.17999982834, 7.99999964237, 8.40000021458, 7.45000000298, 8.54999962449, 9.19999998808, 8.31000061333, 8.88999921083, 8.53000050783, 7.75000019372, 8.31999969482, 9.65999925137, 8.75999987125, 8.45999985933, 8.80000057817, 9.9099996686, 7.25, 8.01000005007, 7.87000006437, 9.91999930143, 8.61999976635, 9.64000016451, 7.87999973446, 7.49999964237, 9.89000052214, 9.16999989748, 7.22999972105, 6.52999992669, 8.75999987125, 6.06000003964, 7.28999960423, 7.25000009686, 9.18999898434, 7.10999983549, 8.0799998045, 7.04999959469, 7.86000025272, 7.33000002056, 7.08999939263, 7.56999931484, 6.88999998569, 7.40000000596, 7.92999994755, 7.5300001204, 7.42999973893, 8.45999985933, 7.28999960423, 7.47999992967, 7.60000000149, 8.35999956727, 7.32000026852, 8.52000063658, 8.22999989986, 8.65000000596, 8.50000035763, 9.04000073671, 8.06999969482, 8.10000020266, 7.52000065148, 8.23000013828, 7.22000026703, 8.44000035524, 8.80000057817, 7.25000009686, 7.60000000149, 7.69999951124, 9.45999985933, 8.47999966145, 7.27999982983, 7.60000009835, 8.7599998489, 7.87999973446, 9.40000019222, 9.34000051022, 8.19000041485, 8.59000015259, 9.20999968052, 8.66999912262, 9.38999956846, 9.9099996686, 9.18999898434, 8.35999956727, 9.45999985933, 10.9799991846, 8.95000040531, 9.76999932528, 9.08999919891, 10.530000329, 9.81999891996, 10.9100000262, 9.29000015557, 9.42999875546, 10.4399994016, 9.89000052214, 7.55000036955, 7.7600004077, 7.25, 7.10999983549, 7.32000026852, 8.47999966145, 8.95000040531, 7.47999972105, 8.33000028133, 6.61999950558, 8.64999979734, 7.56000003964, 8.57999974489, 8.16000004113, 7.65000039339, 8.60999983549, 8.75000035763, 8.07000029087, 8.17999982834, 8.01000005007, 8.0799998045, 8.52000063658, 7.27999982983, 9.76999932528, 8.33000028133, 8.33999949694, 7.89999991655, 8.01999998093, 7.7599998489, 9.41000062227, 8.40999946743, 6.78000040352, 8.30999985337, 8.81000119448, 7.45000076294, 7.99999964237, 7.87000006437, 7.04999959469, 8.22999989986, 7.60000009835, 9.08999919891, 6.61999950558, 7.89999991655, 7.71999913454, 8.37000006437, 7.49999971688, 8.74999982119, 8.98000085354, 7.51999938488, 7.94000015408, 7.67999954522, 8.91000020504, 8.40000021458, 9.91999930143, 7.86000025272, 8.65000000596, 8.7599998489, 10.530000329, 8.64999979734, 8.01999998093, 8.37000006437, 10.2400007248, 8.83999939263, 10.1499999762, 9.2699996978, 8.97000086308, 9.53999918699, 8.76000061631, 8.14999997616, 7.45000000298, 8.61999976635, 7.33000002056, 8.50000035763, 7.87999973446, 9.81999891996, 7.56000003964, 7.7599998489, 7.49999971688, 8.83999939263, 8.43999969959, 9.34999924898, 8.15000039339, 7.74999982119, 9.46999895573, 8.92000025511, 9.66999989748, 8.54999962449, 9.64000016451, 7.08999939263, 9.04000073671, 9.40000019222, 10.9100000262, 8.57999974489, 9.41000062227, 8.74999982119, 10.1499999762, 9.34999924898, 9.60000020266, 9.47000046074, 8.96000021696, 10.1199989319, 10.0299995542, 8.62000018358, 9.19999998808, 7.87999973446, 7.56999931484, 8.06999969482, 9.34000051022, 9.29000015557, 8.16000004113, 8.40999946743, 8.98000085354, 9.2699996978, 8.15000039339, 9.47000046074, 9.07999935746, 7.85000038147, 8.91999971867, 8.97000026703, 7.96999949217, 8.31000061333, 7.49999964237, 6.88999998569, 8.10000020266, 8.19000041485, 9.42999875546, 7.65000039339, 6.78000040352, 7.51999938488, 8.97000086308, 7.74999982119, 8.96000021696, 7.85000038147, 6.5800004974, 8.04999981076, 7.9000005722, 8.5799998045, 8.88999921083, 9.89000052214, 7.40000000596, 7.52000065148, 8.59000015259, 10.4399994016, 8.60999983549, 8.30999985337, 7.94000015408, 9.53999918699, 9.46999895573, 10.1199989319, 8.91999971867, 8.04999981076, 9.89999943972, 9.37000045925, 9.02000027895, 8.53000050783, 9.16999989748, 7.92999994755, 8.23000013828, 9.20999968052, 9.89000052214, 8.75000035763, 8.81000119448, 7.67999954522, 8.76000061631, 8.92000025511, 10.0299995542, 8.97000026703, 7.9000005722, 9.37000045925, 10.259999454, 
+
+L3_sSYR2K_A_kn
+0.6, 0.3, 0.8, 0.5, 0.6, 0.9, 0.6, 0.8, 0.5, 0.7, 0.5, 0.6, 0.3, 0.5, 0.9, 0.5, 0.5, 0.9, 0.3, 0.3, 0.1, 0.6, 0.4, 0.7, 0.6, 0.2, 0.3, 0.3, 0.9, 0.3, 0.1, 0.2, 0.9, 0.2, 0.6, 0.9, 0.6, 0.9, 0.3, 0.5, 0.4, 0.3, 0.5, 0.9, 0.5, 0.5, 0.8, 0.4, 0.3, 0.9, 0.6, 0.7, 0.8, 0.1, 0.1, 0.8, 0.4, 0.1, 0.2, 0.1, 0.7, 0.6, 0.4, 0.5, 0.5, 0.4, 0.4, 0.3, 0.5, 0.9, 0.1, 0.6, 0.6, 0.1, 0.7, 0.2, 0.2, 0.5, 0.8, 0.9, 0.4, 0.3, 0.9, 0.7, 0.4, 0.4, 0.3, 0.1, 0.9, 0.2, 0.5, 0.2, 0.9, 0.4, 0.1, 0.4, 0.7, 0.4, 0.2, 0.1, 0.9, 0.1, 0.6, 0.7, 0.4, 0.7, 0.7, 0.6, 0.7, 0.6, 0.5, 0.6, 0.5, 0.4, 0.3, 0.5, 0.3, 0.2, 0.3, 0.1, 0.1, 0.1, 0.5, 0.9, 0.3, 0.3, 0.6, 0.4, 0.1, 0.7, 0.2, 0.6, 0.8, 0.5, 0.2, 0.6, 0.1, 0.1, 0.7, 0.3, 0.8, 0.9, 0.7, 0.3, 0.2, 0.7, 0.4, 0.1, 0.3, 0.7, 0.6, 0.9, 0.5, 0.1, 0.3, 0.4, 0.5, 0.9, 0.7, 0.2, 0.5, 0.6, 0.5, 0.6, 0.7, 0.2, 0.8, 0.1, 0.1, 0.7, 0.4, 0.5, 0.2, 0.2, 0.4, 0.5, 0.2, 0.8, 0.7, 0.8, 0.4, 0.7, 0.9, 0.5, 0.9, 0.3, 0.7, 0.4, 0.3, 0.8, 0.3, 0.1, 0.8, 0.8, 0.9, 0.1, 0.8, 0.5, 0.6, 0.8, 0.4, 0.9, 0.3, 0.2, 0.8, 0.8, 0.6, 0.6, 0.4, 0.6, 0.1, 0.1, 0.3, 0.7, 0.1, 0.9, 0.6, 0.3, 0.8, 0.1, 0.3, 0.1, 0.9, 0.2, 0.7, 0.8, 0.4, 0.1, 0.6, 0.8, 0.3, 0.7, 0.4, 0.8, 0.5, 0.9, 0.9, 0.1, 0.7, 0.8, 0.2, 0.6, 0.2, 0.1, 0.1, 0.4, 0.5, 0.7, 0.5, 0.9, 0.8, 0.3, 0.1, 0.3, 0.6, 0.5, 0.6, 0.9, 0.5, 0.9, 0.6, 0.6, 0.2, 0.1, 0.8, 0.8, 0.7, 0.7, 0.9, 0.7, 0.1, 0.8, 
+
+L3_sSYR2K_B_kn
+0.9, 0.1, 0.2, 0.5, 0.8, 0.6, 0.4, 0.8, 0.2, 0.2, 0.7, 0.7, 0.4, 0.6, 0.3, 0.9, 0.7, 0.7, 0.7, 0.6, 0.3, 0.6, 0.1, 0.7, 0.1, 0.7, 0.4, 0.5, 0.8, 0.8, 0.2, 0.6, 0.9, 0.4, 0.8, 0.3, 0.3, 0.9, 0.7, 0.1, 0.4, 0.8, 0.4, 0.5, 0.5, 0.2, 0.2, 0.8, 0.3, 0.3, 0.7, 0.6, 0.7, 0.7, 0.6, 0.3, 0.4, 0.2, 0.7, 0.5, 0.5, 0.3, 0.6, 0.9, 0.2, 0.6, 0.5, 0.3, 0.5, 0.9, 0.4, 0.1, 0.8, 0.6, 0.4, 0.4, 0.7, 0.6, 0.3, 0.3, 0.7, 0.5, 0.3, 0.8, 0.1, 0.9, 0.7, 0.2, 0.2, 0.6, 0.4, 0.8, 0.4, 0.6, 0.7, 0.9, 0.4, 0.4, 0.4, 0.7, 0.3, 0.5, 0.4, 0.8, 0.2, 0.3, 0.8, 0.9, 0.3, 0.1, 0.7, 0.8, 0.1, 0.1, 0.8, 0.2, 0.2, 0.8, 0.4, 0.4, 0.9, 0.1, 0.6, 0.6, 0.3, 0.5, 0.4, 0.4, 0.2, 0.5, 0.9, 0.3, 0.1, 0.5, 0.3, 0.4, 0.4, 0.5, 0.5, 0.4, 0.9, 0.1, 0.7, 0.2, 0.3, 0.1, 0.5, 0.1, 0.4, 0.7, 0.8, 0.1, 0.8, 0.1, 0.3, 0.6, 0.6, 0.8, 0.1, 0.6, 0.5, 0.9, 0.6, 0.6, 0.5, 0.6, 0.8, 0.3, 0.4, 0.7, 0.4, 0.5, 0.8, 0.5, 0.7, 0.4, 0.8, 0.7, 0.8, 0.4, 0.8, 0.6, 0.1, 0.7, 0.6, 0.1, 0.5, 0.6, 0.5, 0.6, 0.2, 0.2, 0.7, 0.5, 0.6, 0.8, 0.1, 0.6, 0.9, 0.9, 0.8, 0.2, 0.7, 0.2, 0.3, 0.3, 0.9, 0.3, 0.6, 0.5, 0.4, 0.5, 0.9, 0.1, 0.7, 0.6, 0.3, 0.6, 0.2, 0.7, 0.7, 0.8, 0.1, 0.8, 0.2, 0.6, 0.3, 0.6, 0.9, 0.2, 0.9, 0.9, 0.5, 0.1, 0.3, 0.5, 0.9, 0.2, 0.3, 0.5, 0.6, 0.6, 0.4, 0.7, 0.9, 0.9, 0.4, 0.7, 0.5, 0.7, 0.2, 0.9, 0.7, 0.1, 0.1, 0.7, 0.7, 0.9, 0.8, 0.7, 0.2, 0.9, 0.7, 0.1, 0.4, 0.8, 0.6, 0.9, 0.6, 0.9, 0.5, 0.7, 
+
+L3_sSYR2K_o_T
+9.27999991179, 9.17999917269, 7.99999971688, 8.64999979734, 9.80999985337, 8.44999980927, 8.36999988556, 9.4499990344, 8.12000048161, 8.78999996185, 9.60999906063, 10.249999404, 9.7399995923, 8.69000035524, 9.12000006437, 10.0899995565, 7.64999943972, 9.17999917269, 9.75999963284, 8.42000007629, 8.15000028908, 10.7400001585, 8.03000050783, 9.08999937773, 10.0299999118, 7.88999938965, 9.65000021458, 9.9699999094, 9.5199996978, 9.0300001204, 9.34999960661, 8.39999981225, 9.50000077486, 7.55999976397, 7.99999971688, 8.42000007629, 8.09999978542, 7.54999983311, 9.91999989748, 7.28000059724, 7.11999970675, 7.94000053406, 6.64999943972, 8.22000044584, 8.87000006437, 9.71000039577, 8.78999978304, 8.15000019222, 8.52999985218, 7.97999972105, 7.58999997377, 8.64999979734, 8.15000028908, 7.54999983311, 7.21999988705, 10.1200004816, 7.15999994427, 8.12000024319, 8.48000019789, 7.79000031948, 9.38999974728, 9.14000093937, 8.03999958187, 7.83000011742, 8.23000011593, 7.73999989033, 7.63999977708, 8.02000010014, 9.80999985337, 10.7400001585, 9.91999989748, 10.1200004816, 12.7200006545, 8.78000030667, 9.79999962449, 9.81000003964, 9.32999914885, 10.8700002432, 10.7999996245, 11.6199992895, 10.3299987912, 9.890001297, 10.8899992108, 10.1799995452, 9.67999994755, 8.44999980927, 8.03000050783, 7.28000059724, 7.15999994427, 8.78000030667, 7.12000006437, 8.1800006032, 8.41999971867, 6.98000011593, 7.27999992669, 8.35000000149, 8.42000064999, 7.96000061184, 8.33000028133, 8.45999991894, 7.53000068665, 7.56000006199, 8.36999988556, 9.08999937773, 7.11999970675, 8.12000024319, 9.79999962449, 8.1800006032, 7.82000029087, 8.32000029087, 7.80000001192, 8.22999954224, 8.7199999094, 9.67999953032, 9.7699996829, 8.04000063241, 8.61000001431, 9.0600002408, 7.89999979734, 9.4499990344, 10.0299999118, 7.94000053406, 8.48000019789, 9.81000003964, 8.41999971867, 8.32000029087, 9.33999937773, 8.94999921322, 9.12999973446, 10.3099986911, 10.0099998489, 9.50999909639, 8.60999985039, 9.57000046968, 8.97999972105, 8.43999993801, 8.12000048161, 7.88999938965, 6.64999943972, 7.79000031948, 9.32999914885, 6.98000011593, 7.80000001192, 8.94999921322, 7.31999999285, 8.89000016451, 8.36999988556, 8.79999981076, 7.66000062227, 7.19000015408, 7.46000023186, 7.24000015855, 6.6599996686, 8.78999996185, 9.65000021458, 8.22000044584, 9.38999974728, 10.8700002432, 7.27999992669, 8.22999954224, 9.12999973446, 8.89000016451, 8.49999934435, 9.85999983549, 9.38000030816, 9.42999917269, 9.6800006628, 8.58999955654, 8.4299999252, 7.60999985039, 9.60999906063, 9.9699999094, 8.87000006437, 9.14000093937, 10.7999996245, 8.35000000149, 8.7199999094, 10.3099986911, 8.36999988556, 9.85999983549, 9.89999961853, 10.2699996978, 10.5300000906, 8.92000027001, 9.92999994755, 9.60999983549, 7.99000015855, 10.249999404, 9.5199996978, 9.71000039577, 8.03999958187, 11.6199992895, 8.42000064999, 9.67999953032, 10.0099998489, 8.79999981076, 9.38000030816, 10.2699996978, 11.3200002909, 10.0899999738, 9.69999963045, 10.0800006986, 9.44999945164, 8.62999981642, 9.7399995923, 9.0300001204, 8.78999978304, 7.83000011742, 10.3299987912, 7.96000061184, 9.7699996829, 9.50999909639, 7.66000062227, 9.42999917269, 10.5300000906, 10.0899999738, 8.6599996686, 8.96000023186, 9.15999907255, 8.23999929428, 7.87999993563, 8.69000035524, 9.34999960661, 8.15000019222, 8.23000011593, 9.890001297, 8.33000028133, 8.04000063241, 8.60999985039, 7.19000015408, 9.6800006628, 8.92000027001, 9.69999963045, 8.96000023186, 8.58000031114, 8.98000049591, 8.17999994755, 8.42000007629, 9.12000006437, 8.39999981225, 8.52999985218, 7.73999989033, 10.8899992108, 8.45999991894, 8.61000001431, 9.57000046968, 7.46000023186, 8.58999955654, 9.92999994755, 10.0800006986, 9.15999907255, 8.98000049591, 7.92000064999, 9.0099998489, 7.92000007629, 10.0899995565, 9.50000077486, 7.97999972105, 7.63999977708, 10.1799995452, 7.53000068665, 9.0600002408, 8.97999972105, 7.24000015855, 8.4299999252, 9.60999983549, 9.44999945164, 8.23999929428, 8.17999994755, 9.0099998489, 9.02000027895, 6.61999950558, 7.64999943972, 7.55999976397, 7.58999997377, 8.02000010014, 9.67999994755, 7.56000006199, 7.89999979734, 8.43999993801, 6.6599996686, 7.60999985039, 7.99000015855, 8.62999981642, 7.87999993563, 8.42000007629, 7.92000007629, 6.61999950558, 7.73999947309, 
+
+L3_dSYR2K_A_nk
+0.9, 0.2, 0.3, 0.4, 0.3, 0.5, 0.9, 0.9, 0.9, 0.2, 0.2, 0.4, 0.7, 0.1, 0.4, 0.1, 0.6, 0.2, 0.2, 0.3, 0.1, 0.4, 0.3, 0.8, 0.2, 0.5, 0.7, 0.5, 0.3, 0.5, 0.1, 0.3, 0.2, 0.5, 0.9, 0.1, 0.7, 0.2, 0.5, 0.8, 0.8, 0.7, 0.8, 0.1, 0.2, 0.6, 0.5, 0.3, 0.4, 0.7, 0.2, 0.5, 0.2, 0.8, 0.8, 0.9, 0.5, 0.5, 0.8, 0.3, 0.9, 0.3, 0.6, 0.5, 0.6, 0.5, 0.3, 0.3, 0.4, 0.2, 0.1, 0.4, 0.9, 0.8, 0.2, 0.3, 0.2, 0.3, 0.2, 0.4, 0.4, 0.5, 0.9, 0.1, 0.3, 0.1, 0.9, 0.1, 0.1, 0.5, 0.6, 0.4, 0.2, 0.1, 0.9, 0.9, 0.1, 0.1, 0.7, 0.4, 0.8, 0.4, 0.5, 0.3, 0.1, 0.3, 0.6, 0.1, 0.5, 0.8, 0.7, 0.5, 0.5, 0.2, 0.9, 0.2, 0.9, 0.7, 0.7, 0.2, 0.8, 0.4, 0.9, 0.9, 0.4, 0.9, 0.7, 0.6, 0.6, 0.9, 0.4, 0.4, 0.3, 0.1, 0.9, 0.4, 0.4, 0.7, 0.3, 0.7, 0.4, 0.8, 0.3, 0.9, 0.1, 0.8, 0.2, 0.4, 0.7, 0.9, 0.4, 0.2, 0.6, 0.7, 0.5, 0.2, 0.3, 0.2, 0.9, 0.2, 0.5, 0.5, 0.3, 0.2, 0.6, 0.9, 0.5, 0.4, 0.6, 0.8, 0.3, 0.5, 0.8, 0.2, 0.3, 0.1, 0.6, 0.6, 0.4, 0.2, 0.1, 0.7, 0.1, 0.4, 0.7, 0.8, 0.8, 0.4, 0.6, 0.9, 0.9, 0.1, 0.1, 0.5, 0.1, 0.7, 0.2, 0.6, 0.9, 0.3, 0.9, 0.8, 0.4, 0.1, 0.3, 0.6, 0.9, 0.3, 0.2, 0.8, 0.8, 0.9, 0.8, 0.3, 0.6, 0.8, 0.4, 0.6, 0.5, 0.8, 0.9, 0.9, 0.5, 0.8, 0.7, 0.2, 0.4, 0.7, 0.8, 0.7, 0.7, 0.3, 0.6, 0.1, 0.8, 0.5, 0.1, 0.7, 0.4, 0.2, 0.3, 0.2, 0.5, 0.6, 0.7, 0.1, 0.7, 0.9, 0.6, 0.2, 0.5, 0.9, 0.6, 0.7, 0.8, 0.4, 0.4, 0.6, 0.8, 0.4, 0.1, 0.6, 0.5, 0.9, 0.7, 0.5, 0.9, 0.9, 0.3, 0.9, 0.4, 0.8, 
+
+L3_dSYR2K_B_nk
+0.1, 0.9, 0.9, 0.9, 0.4, 0.9, 0.8, 0.9, 0.3, 0.9, 0.6, 0.1, 0.1, 0.2, 0.1, 0.3, 0.2, 0.4, 0.5, 0.2, 0.3, 0.4, 0.6, 0.3, 0.6, 0.9, 0.4, 0.6, 0.6, 0.1, 0.6, 0.2, 0.4, 0.9, 0.1, 0.9, 0.8, 0.7, 0.8, 0.3, 0.8, 0.4, 0.4, 0.5, 0.3, 0.5, 0.5, 0.7, 0.7, 0.7, 0.8, 0.4, 0.5, 0.5, 0.4, 0.4, 0.8, 0.8, 0.1, 0.2, 0.8, 0.1, 0.7, 0.5, 0.9, 0.8, 0.4, 0.4, 0.5, 0.5, 0.3, 0.3, 0.9, 0.4, 0.6, 0.7, 0.2, 0.1, 0.8, 0.1, 0.9, 0.5, 0.9, 0.8, 0.5, 0.6, 0.1, 0.3, 0.7, 0.9, 0.7, 0.7, 0.4, 0.3, 0.7, 0.6, 0.5, 0.5, 0.5, 0.2, 0.4, 0.4, 0.1, 0.5, 0.9, 0.2, 0.9, 0.5, 0.8, 0.6, 0.7, 0.5, 0.8, 0.1, 0.4, 0.4, 0.4, 0.8, 0.6, 0.5, 0.1, 0.5, 0.3, 0.9, 0.6, 0.4, 0.7, 0.6, 0.5, 0.4, 0.4, 0.3, 0.1, 0.2, 0.4, 0.7, 0.7, 0.7, 0.4, 0.9, 0.9, 0.4, 0.6, 0.1, 0.5, 0.1, 0.8, 0.4, 0.8, 0.9, 0.3, 0.8, 0.9, 0.5, 0.4, 0.1, 0.5, 0.1, 0.2, 0.6, 0.1, 0.6, 0.5, 0.5, 0.3, 0.7, 0.2, 0.3, 0.8, 0.6, 0.7, 0.8, 0.1, 0.1, 0.9, 0.6, 0.1, 0.9, 0.9, 0.6, 0.6, 0.2, 0.8, 0.1, 0.5, 0.7, 0.8, 0.3, 0.2, 0.9, 0.9, 0.9, 0.9, 0.9, 0.3, 0.5, 0.2, 0.8, 0.6, 0.2, 0.9, 0.3, 0.4, 0.1, 0.5, 0.7, 0.3, 0.2, 0.1, 0.9, 0.7, 0.7, 0.8, 0.6, 0.8, 0.3, 0.9, 0.9, 0.9, 0.2, 0.7, 0.4, 0.5, 0.9, 0.9, 0.9, 0.8, 0.3, 0.3, 0.6, 0.7, 0.1, 0.5, 0.5, 0.2, 0.8, 0.1, 0.3, 0.6, 0.9, 0.4, 0.7, 0.5, 0.2, 0.7, 0.1, 0.1, 0.7, 0.6, 0.5, 0.4, 0.7, 0.9, 0.3, 0.7, 0.4, 0.8, 0.7, 0.2, 0.2, 0.9, 0.4, 0.5, 0.1, 0.2, 0.4, 0.8, 0.2, 0.2, 0.9, 0.1, 0.4, 
+
+L3_dSYR2K_C_nn
+0.8, 0.8, 0.1, 0.1, 0.5, 0.7, 0.7, 0.5, 0.3, 0.9, 0.5, 0.4, 0.5, 0.7, 0.5, 0.5, 0.5, 0.8, 0.1, 0.1, 0.4, 0.2, 0.4, 0.4, 0.6, 0.6, 0.9, 0.4, 0.2, 0.4, 0.1, 0.2, 0.7, 0.8, 0.1, 0.1, 0.3, 0.9, 0.6, 0.7, 0.5, 0.9, 0.9, 0.3, 0.4, 0.5, 0.1, 0.9, 0.6, 0.6, 0.8, 0.1, 0.4, 0.9, 0.9, 0.9, 0.9, 0.3, 0.9, 0.4, 0.2, 0.9, 0.3, 0.6, 0.6, 0.2, 0.8, 0.2, 0.5, 0.2, 0.6, 0.9, 0.4, 0.8, 0.9, 0.3, 0.9, 0.2, 0.5, 0.9, 0.7, 0.8, 0.7, 0.1, 0.4, 0.7, 0.4, 0.7, 0.9, 0.8, 0.2, 0.9, 0.5, 0.7, 0.5, 0.8, 0.2, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.4, 0.5, 0.3, 0.9, 0.9, 0.1, 0.5, 0.3, 0.5, 0.3, 0.9, 0.8, 0.1, 0.4, 0.7, 0.8, 0.5, 0.6, 0.9, 0.9, 0.3, 0.5, 0.5, 0.8, 0.1, 0.3, 0.7, 0.3, 0.5, 0.3, 0.7, 0.1, 0.3, 0.3, 0.6, 0.9, 0.4, 0.9, 0.7, 0.3, 0.1, 0.2, 0.6, 0.5, 0.4, 0.9, 0.1, 0.9, 0.7, 0.8, 0.9, 0.9, 0.3, 0.2, 0.2, 0.5, 0.5, 0.3, 0.6, 0.3, 0.3, 0.9, 0.4, 0.8, 0.2, 0.9, 0.7, 0.5, 0.4, 0.4, 0.9, 0.5, 0.8, 0.3, 0.7, 0.5, 0.3, 0.1, 0.5, 0.9, 0.5, 0.4, 0.1, 0.7, 0.4, 0.2, 0.5, 0.3, 0.9, 0.2, 0.9, 0.3, 0.4, 0.9, 0.5, 0.8, 0.9, 0.5, 0.7, 0.9, 0.7, 0.5, 0.4, 0.1, 0.6, 0.7, 0.7, 0.8, 0.5, 0.9, 0.4, 0.9, 0.9, 0.9, 0.7, 0.7, 0.9, 0.7, 0.7, 0.1, 0.9, 0.6, 0.8, 0.7, 0.1, 0.3, 0.1, 0.8, 0.5, 0.5, 0.7, 0.1, 0.2, 0.2, 0.5, 0.5, 0.2, 0.6, 0.2, 0.7, 0.7, 0.4, 0.7, 0.9, 0.2, 0.4, 0.7, 0.7, 0.2, 0.6, 0.2, 0.2, 0.5, 0.7, 0.6, 0.8, 0.1, 0.7, 0.7, 0.1, 0.7, 0.9, 0.1, 0.9, 0.9, 0.2, 0.2, 0.9, 0.7, 0.5, 0.8, 0.8, 0.2, 0.4, 0.7, 0.8, 0.3, 0.8, 0.7, 0.7, 0.7, 0.7, 0.5, 0.2, 0.7, 0.3, 
+
+L3_dSYR2K_o_N
+8.34, 7.38, 8.81, 9.29, 7.65, 8.58, 8.06, 9.09, 8.7, 9.19, 7.82, 7.88, 8.87, 10.72, 8.37, 8.28, 8.55, 7.38, 5.04, 6.71, 7.14, 5.83, 7.26, 6.32, 8.11, 7.34, 7.31, 6.79, 7.09, 6.92, 8.03, 6.2, 7.27, 7.62, 8.81, 6.71, 8.62, 10.17, 8.01, 9.15, 8.49, 9.73, 9.64, 9.13, 8.54, 9.96, 8.62, 12.33, 9.22, 9.44, 9.58, 9.29, 7.14, 10.17, 10.24, 8.79, 9.72, 8.37, 10.29, 9.23, 8.73, 9.52, 9.68, 9.29, 11.87, 8.23, 9.39, 8.5, 7.65, 5.83, 8.01, 8.79, 7.12, 8.25, 6.97, 8.05, 7.98, 7.52, 7.5, 8.83, 7.8, 9.54, 8.21, 7.46, 7.73, 8.58, 7.26, 9.15, 9.72, 8.25, 8.86, 8.28, 10.17, 8.69, 8.09, 9.0, 10.45, 8.11, 11.63, 9.89, 8.97, 9.48, 8.06, 6.32, 8.49, 8.37, 6.97, 8.28, 7.24, 9.32, 7.27, 7.66, 7.23, 10.31, 7.59, 10.05, 7.7, 8.6, 9.27, 9.09, 8.11, 9.73, 10.29, 8.05, 10.17, 9.32, 11.02, 8.96, 8.74, 9.67, 10.57, 8.78, 11.84, 10.09, 9.36, 9.77, 8.7, 7.34, 9.64, 9.23, 7.98, 8.69, 7.27, 8.96, 8.4, 7.49, 8.29, 10.26, 8.85, 10.75, 9.35, 9.33, 9.6, 9.19, 7.31, 9.13, 8.73, 7.52, 8.09, 7.66, 8.74, 7.49, 7.66, 8.49, 9.31, 7.8, 10.98, 8.03, 8.62, 8.6, 7.82, 6.79, 8.54, 9.52, 7.5, 9.0, 7.23, 9.67, 8.29, 8.49, 7.36, 8.64, 8.91, 10.34, 8.04, 8.09, 8.92, 7.88, 7.09, 9.96, 9.68, 8.83, 10.45, 10.31, 10.57, 10.26, 9.31, 8.64, 10.6, 10.37, 12.21, 9.5, 10.18, 10.27, 8.87, 6.92, 8.62, 9.29, 7.8, 8.11, 7.59, 8.78, 8.85, 7.8, 8.91, 10.37, 9.22, 10.85, 8.76, 8.07, 8.45, 10.72, 8.03, 12.33, 11.87, 9.54, 11.63, 10.05, 11.84, 10.75, 10.98, 10.34, 12.21, 10.85, 13.98, 10.46, 10.92, 11.11, 8.37, 6.2, 9.22, 8.23, 8.21, 9.89, 7.7, 10.09, 9.35, 8.03, 8.04, 9.5, 8.76, 10.46, 8.74, 7.82, 9.42, 8.28, 7.27, 9.44, 9.39, 7.46, 8.97, 8.6, 9.36, 9.33, 8.62, 8.09, 10.18, 8.07, 10.92, 7.82, 10.08, 8.85, 8.55, 7.62, 9.58, 8.5, 7.73, 9.48, 9.27, 9.77, 9.6, 8.6, 8.92, 10.27, 8.45, 11.11, 9.42, 8.85, 8.54, 
+
+L3_dSYR2K_A_kn
+0.1, 0.5, 0.7, 0.6, 0.4, 0.2, 0.1, 0.8, 0.9, 0.9, 0.9, 0.2, 0.3, 0.1, 0.5, 0.8, 0.9, 0.6, 0.2, 0.2, 0.5, 0.1, 0.3, 0.5, 0.4, 0.9, 0.9, 0.3, 0.2, 0.6, 0.5, 0.5, 0.7, 0.9, 0.8, 0.6, 0.2, 0.6, 0.6, 0.8, 0.5, 0.9, 0.1, 0.1, 0.1, 0.7, 0.3, 0.3, 0.8, 0.6, 0.6, 0.7, 0.5, 0.4, 0.7, 0.1, 0.8, 0.5, 0.7, 0.8, 0.4, 0.9, 0.6, 0.8, 0.1, 0.2, 0.8, 0.2, 0.9, 0.1, 0.5, 0.9, 0.9, 0.3, 0.5, 0.4, 0.2, 0.3, 0.2, 0.6, 0.3, 0.7, 0.5, 0.8, 0.9, 0.7, 0.7, 0.5, 0.7, 0.8, 0.5, 0.3, 0.9, 0.6, 0.6, 0.6, 0.3, 0.2, 0.2, 0.7, 0.3, 0.6, 0.5, 0.9, 0.6, 0.5, 0.4, 0.2, 0.5, 0.2, 0.6, 0.6, 0.5, 0.2, 0.4, 0.3, 0.5, 0.1, 0.9, 0.9, 0.5, 0.5, 0.7, 0.7, 0.4, 0.6, 0.8, 0.2, 0.5, 0.8, 0.2, 0.3, 0.4, 0.2, 0.8, 0.9, 0.1, 0.6, 0.5, 0.4, 0.5, 0.5, 0.7, 0.5, 0.7, 0.5, 0.5, 0.2, 0.5, 0.1, 0.5, 0.4, 0.5, 0.6, 0.8, 0.5, 0.3, 0.1, 0.1, 0.1, 0.3, 0.1, 0.6, 0.6, 0.8, 0.7, 0.1, 0.8, 0.9, 0.2, 0.2, 0.7, 0.6, 0.6, 0.9, 0.3, 0.4, 0.3, 0.1, 0.6, 0.3, 0.2, 0.8, 0.7, 0.3, 0.9, 0.8, 0.6, 0.6, 0.4, 0.6, 0.1, 0.2, 0.3, 0.9, 0.2, 0.8, 0.1, 0.9, 0.4, 0.2, 0.7, 0.9, 0.2, 0.2, 0.5, 0.7, 0.6, 0.9, 0.8, 0.2, 0.2, 0.4, 0.8, 0.9, 0.7, 0.7, 0.6, 0.7, 0.2, 0.5, 0.1, 0.5, 0.2, 0.3, 0.6, 0.9, 0.5, 0.9, 0.3, 0.7, 0.9, 0.4, 0.5, 0.9, 0.4, 0.4, 0.5, 0.9, 0.3, 0.6, 0.7, 0.7, 0.9, 0.7, 0.4, 0.6, 0.4, 0.8, 0.9, 0.3, 0.4, 0.8, 0.7, 0.7, 0.9, 0.9, 0.7, 0.5, 0.1, 0.1, 0.1, 0.2, 0.1, 0.3, 0.5, 0.9, 0.2, 0.9, 0.7, 0.4, 0.6, 
+
+L3_dSYR2K_B_kn
+0.7, 0.9, 0.4, 0.9, 0.4, 0.9, 0.3, 0.7, 0.1, 0.7, 0.1, 0.4, 0.2, 0.1, 0.2, 0.6, 0.4, 0.9, 0.5, 0.6, 0.3, 0.6, 0.5, 0.2, 0.8, 0.8, 0.3, 0.8, 0.7, 0.3, 0.1, 0.4, 0.5, 0.3, 0.1, 0.4, 0.1, 0.4, 0.6, 0.3, 0.7, 0.5, 0.4, 0.1, 0.8, 0.3, 0.9, 0.2, 0.1, 0.2, 0.5, 0.9, 0.4, 0.1, 0.5, 0.1, 0.9, 0.9, 0.6, 0.7, 0.6, 0.4, 0.6, 0.8, 0.6, 0.3, 0.3, 0.5, 0.8, 0.9, 0.6, 0.6, 0.2, 0.9, 0.7, 0.9, 0.3, 0.4, 0.3, 0.3, 0.4, 0.7, 0.2, 0.6, 0.4, 0.9, 0.4, 0.4, 0.5, 0.9, 0.9, 0.1, 0.7, 0.8, 0.9, 0.3, 0.7, 0.5, 0.6, 0.6, 0.3, 0.2, 0.8, 0.7, 0.2, 0.8, 0.6, 0.3, 0.8, 0.6, 0.6, 0.9, 0.7, 0.4, 0.1, 0.7, 0.1, 0.1, 0.3, 0.9, 0.6, 0.4, 0.1, 0.9, 0.6, 0.4, 0.5, 0.1, 0.8, 0.5, 0.9, 0.7, 0.5, 0.4, 0.3, 0.8, 0.2, 0.3, 0.3, 0.8, 0.9, 0.3, 0.4, 0.1, 0.9, 0.5, 0.4, 0.7, 0.6, 0.1, 0.3, 0.1, 0.3, 0.5, 0.5, 0.4, 0.9, 0.6, 0.5, 0.9, 0.2, 0.5, 0.7, 0.4, 0.5, 0.3, 0.9, 0.4, 0.6, 0.9, 0.1, 0.1, 0.3, 0.6, 0.3, 0.8, 0.2, 0.9, 0.4, 0.1, 0.6, 0.4, 0.4, 0.7, 0.6, 0.6, 0.8, 0.8, 0.8, 0.7, 0.2, 0.4, 0.8, 0.3, 0.2, 0.1, 0.3, 0.7, 0.6, 0.8, 0.1, 0.2, 0.5, 0.7, 0.4, 0.9, 0.3, 0.3, 0.3, 0.8, 0.8, 0.2, 0.5, 0.6, 0.8, 0.2, 0.1, 0.4, 0.6, 0.3, 0.6, 0.8, 0.3, 0.5, 0.8, 0.1, 0.2, 0.3, 0.9, 0.2, 0.4, 0.2, 0.1, 0.4, 0.3, 0.8, 0.2, 0.2, 0.2, 0.5, 0.4, 0.1, 0.5, 0.4, 0.5, 0.4, 0.9, 0.5, 0.6, 0.2, 0.4, 0.1, 0.4, 0.7, 0.9, 0.8, 0.3, 0.1, 0.9, 0.2, 0.2, 0.2, 0.7, 0.2, 0.9, 0.8, 0.3, 0.4, 0.4, 0.3, 0.2, 0.1, 
+
+L3_dSYR2K_o_T
+12.32, 10.9, 7.92, 10.05, 9.11, 9.84, 8.92, 11.16, 8.95, 11.72, 11.14, 9.3, 9.21, 8.55, 8.48, 9.86, 11.16, 10.9, 8.98, 7.31, 10.82, 8.83, 8.97, 7.95, 10.01, 8.45, 11.18, 10.01, 8.68, 8.13, 7.28, 8.25, 8.95, 10.52, 7.92, 7.31, 5.72, 8.67, 7.18, 7.89, 6.66, 8.48, 6.99, 8.51, 7.54, 6.84, 5.94, 6.63, 6.65, 7.44, 8.4, 10.05, 10.82, 8.67, 10.2, 9.2, 10.13, 7.93, 10.68, 8.39, 10.08, 10.67, 8.67, 8.94, 7.98, 8.24, 9.48, 10.17, 9.11, 8.83, 7.18, 9.2, 8.16, 8.98, 7.94, 9.32, 8.07, 8.58, 8.56, 7.55, 7.35, 6.68, 8.27, 7.62, 9.38, 9.84, 8.97, 7.89, 10.13, 8.98, 8.42, 8.22, 9.81, 8.71, 9.66, 9.84, 7.73, 8.72, 6.79, 8.64, 9.38, 10.1, 8.92, 7.95, 6.66, 7.93, 7.94, 8.22, 6.44, 8.03, 6.91, 7.82, 8.18, 8.22, 7.85, 5.35, 7.07, 7.71, 8.51, 11.16, 10.01, 8.48, 10.68, 9.32, 9.81, 8.03, 10.74, 7.7, 9.87, 9.78, 8.58, 9.15, 7.72, 8.51, 8.82, 10.64, 8.95, 8.45, 6.99, 8.39, 8.07, 8.71, 6.91, 7.7, 7.98, 8.69, 8.06, 7.37, 7.38, 5.05, 7.6, 7.49, 8.35, 11.72, 11.18, 8.51, 10.08, 8.58, 9.66, 7.82, 9.87, 8.69, 10.2, 10.37, 9.4, 7.78, 7.6, 8.55, 9.3, 10.57, 11.14, 10.01, 7.54, 10.67, 8.56, 9.84, 8.18, 9.78, 8.06, 10.37, 8.56, 8.99, 8.51, 7.78, 8.92, 8.33, 10.33, 9.3, 8.68, 6.84, 8.67, 7.55, 7.73, 8.22, 8.58, 7.37, 9.4, 8.99, 7.26, 8.11, 6.15, 7.29, 8.79, 9.49, 9.21, 8.13, 5.94, 8.94, 7.35, 8.72, 7.85, 9.15, 7.38, 7.78, 8.51, 8.11, 7.38, 6.59, 7.52, 8.56, 8.72, 8.55, 7.28, 6.63, 7.98, 6.68, 6.79, 5.35, 7.72, 5.05, 7.6, 7.78, 6.15, 6.59, 5.54, 6.38, 6.6, 7.39, 8.48, 8.25, 6.65, 8.24, 8.27, 8.64, 7.07, 8.51, 7.6, 8.55, 8.92, 7.29, 7.52, 6.38, 6.9, 7.09, 8.15, 9.86, 8.95, 7.44, 9.48, 7.62, 9.38, 7.71, 8.82, 7.49, 9.3, 8.33, 8.79, 8.56, 6.6, 7.09, 9.48, 9.99, 11.16, 10.52, 8.4, 10.17, 9.38, 10.1, 8.51, 10.64, 8.35, 10.57, 10.33, 9.49, 8.72, 7.39, 8.15, 9.99, 9.7, 
+
+L3_cSYR2K_A_nk
+0.10000000149, 0.699999988079, 0.40000000596, 0.699999988079, 0.600000023842, 0.10000000149, 0.699999988079, 0.5, 0.899999976158, 0.300000011921, 0.699999988079, 0.40000000596, 0.5, 0.5, 0.5, 0.20000000298, 0.699999988079, 0.40000000596, 0.40000000596, 0.699999988079, 0.300000011921, 0.600000023842, 0.300000011921, 0.699999988079, 0.5, 0.699999988079, 0.300000011921, 0.20000000298, 0.20000000298, 0.899999976158, 0.600000023842, 0.40000000596, 0.899999976158, 0.800000011921, 0.40000000596, 0.5, 0.800000011921, 0.10000000149, 0.899999976158, 0.10000000149, 0.40000000596, 0.300000011921, 0.600000023842, 0.699999988079, 0.40000000596, 0.5, 0.300000011921, 0.699999988079, 0.300000011921, 0.10000000149, 0.600000023842, 0.899999976158, 0.699999988079, 0.40000000596, 0.10000000149, 0.5, 0.20000000298, 0.300000011921, 0.699999988079, 0.40000000596, 0.40000000596, 0.600000023842, 0.899999976158, 0.5, 0.699999988079, 0.800000011921, 0.899999976158, 0.899999976158, 0.800000011921, 0.899999976158, 0.800000011921, 0.300000011921, 0.5, 0.800000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.300000011921, 0.5, 0.699999988079, 0.699999988079, 0.300000011921, 0.600000023842, 0.10000000149, 0.899999976158, 0.300000011921, 0.10000000149, 0.20000000298, 0.20000000298, 0.800000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.600000023842, 0.899999976158, 0.699999988079, 0.800000011921, 0.20000000298, 0.40000000596, 0.899999976158, 0.5, 0.5, 0.20000000298, 0.899999976158, 0.699999988079, 0.40000000596, 0.10000000149, 0.800000011921, 0.10000000149, 0.899999976158, 0.20000000298, 0.40000000596, 0.5, 0.699999988079, 0.40000000596, 0.5, 0.5, 0.699999988079, 0.600000023842, 0.10000000149, 0.5, 0.10000000149, 0.10000000149, 0.699999988079, 0.800000011921, 0.899999976158, 0.20000000298, 0.20000000298, 0.600000023842, 0.5, 0.300000011921, 0.300000011921, 0.5, 0.300000011921, 0.40000000596, 0.899999976158, 0.699999988079, 0.10000000149, 0.600000023842, 0.300000011921, 0.300000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.5, 0.10000000149, 0.40000000596, 0.10000000149, 0.10000000149, 0.699999988079, 0.40000000596, 0.699999988079, 0.800000011921, 0.40000000596, 0.800000011921, 0.699999988079, 0.5, 0.10000000149, 0.899999976158, 0.5, 0.699999988079, 0.899999976158, 0.20000000298, 0.40000000596, 0.5, 0.300000011921, 0.20000000298, 0.10000000149, 0.40000000596, 0.300000011921, 0.600000023842, 0.20000000298, 0.899999976158, 0.899999976158, 0.600000023842, 0.300000011921, 0.40000000596, 0.699999988079, 0.5, 0.899999976158, 0.300000011921, 0.5, 0.899999976158, 0.5, 0.20000000298, 0.899999976158, 0.40000000596, 0.300000011921, 0.40000000596, 0.800000011921, 0.40000000596, 0.40000000596, 0.20000000298, 0.40000000596, 0.10000000149, 0.800000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.300000011921, 0.10000000149, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.300000011921, 0.899999976158, 0.600000023842, 0.20000000298, 0.800000011921, 0.899999976158, 0.899999976158, 0.699999988079, 0.699999988079, 0.800000011921, 0.40000000596, 0.10000000149, 0.5, 0.800000011921, 0.300000011921, 0.10000000149, 0.899999976158, 0.699999988079, 0.800000011921, 0.20000000298, 0.699999988079, 0.800000011921, 0.20000000298, 0.10000000149, 0.800000011921, 0.699999988079, 0.800000011921, 0.40000000596, 0.40000000596, 0.5, 0.40000000596, 0.10000000149, 0.899999976158, 0.899999976158, 0.5, 0.800000011921, 0.10000000149, 0.800000011921, 0.5, 0.300000011921, 0.20000000298, 0.10000000149, 0.20000000298, 0.300000011921, 0.800000011921, 0.5, 0.899999976158, 0.40000000596, 0.699999988079, 0.40000000596, 0.699999988079, 0.699999988079, 0.899999976158, 0.600000023842, 0.5, 0.20000000298, 0.20000000298, 0.800000011921, 0.5, 0.40000000596, 0.300000011921, 0.600000023842, 0.300000011921, 0.10000000149, 0.5, 0.5, 0.600000023842, 0.10000000149, 0.800000011921, 0.699999988079, 0.600000023842, 0.5, 0.600000023842, 0.20000000298, 0.300000011921, 0.699999988079, 0.300000011921, 0.10000000149, 0.300000011921, 0.20000000298, 0.300000011921, 0.5, 0.5, 0.800000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.899999976158, 0.699999988079, 0.699999988079, 0.40000000596, 0.600000023842, 0.10000000149, 0.899999976158, 0.899999976158, 0.300000011921, 0.20000000298, 0.40000000596, 0.300000011921, 0.20000000298, 0.10000000149, 0.20000000298, 0.5, 0.699999988079, 0.899999976158, 0.40000000596, 0.40000000596, 0.40000000596, 0.300000011921, 0.899999976158, 0.300000011921, 0.600000023842, 0.5, 0.300000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.5, 0.40000000596, 0.10000000149, 0.899999976158, 0.699999988079, 0.40000000596, 0.20000000298, 0.40000000596, 0.20000000298, 0.600000023842, 0.699999988079, 0.40000000596, 0.5, 0.20000000298, 0.40000000596, 0.40000000596, 0.5, 0.10000000149, 0.899999976158, 0.699999988079, 0.20000000298, 0.800000011921, 0.40000000596, 0.20000000298, 0.20000000298, 0.10000000149, 0.5, 0.5, 0.800000011921, 0.699999988079, 0.300000011921, 0.800000011921, 0.899999976158, 0.300000011921, 0.899999976158, 0.800000011921, 0.20000000298, 0.699999988079, 0.10000000149, 0.5, 0.10000000149, 0.600000023842, 0.800000011921, 0.40000000596, 0.300000011921, 0.899999976158, 0.5, 0.40000000596, 0.899999976158, 0.300000011921, 0.20000000298, 0.699999988079, 0.699999988079, 0.699999988079, 0.600000023842, 0.20000000298, 0.800000011921, 0.899999976158, 0.5, 0.899999976158, 0.40000000596, 0.20000000298, 0.600000023842, 0.699999988079, 0.300000011921, 0.5, 0.800000011921, 0.40000000596, 0.20000000298, 0.699999988079, 0.10000000149, 0.800000011921, 0.899999976158, 0.800000011921, 0.20000000298, 0.699999988079, 0.600000023842, 0.800000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.5, 0.40000000596, 0.40000000596, 0.40000000596, 0.699999988079, 0.699999988079, 0.40000000596, 0.300000011921, 0.10000000149, 0.899999976158, 0.5, 0.5, 0.300000011921, 0.300000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.10000000149, 0.20000000298, 0.699999988079, 0.300000011921, 0.600000023842, 0.40000000596, 0.800000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.899999976158, 0.40000000596, 0.10000000149, 0.699999988079, 0.600000023842, 0.40000000596, 0.699999988079, 0.20000000298, 0.40000000596, 0.800000011921, 0.300000011921, 0.800000011921, 0.300000011921, 0.800000011921, 0.10000000149, 0.40000000596, 0.20000000298, 0.800000011921, 0.899999976158, 0.40000000596, 0.699999988079, 0.300000011921, 0.899999976158, 0.10000000149, 0.40000000596, 0.5, 0.800000011921, 0.20000000298, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.5, 0.899999976158, 0.10000000149, 0.600000023842, 0.600000023842, 0.10000000149, 0.899999976158, 0.899999976158, 0.600000023842, 0.899999976158, 0.300000011921, 0.699999988079, 0.40000000596, 0.40000000596, 0.899999976158, 0.699999988079, 0.10000000149, 0.600000023842, 0.5, 0.5, 0.10000000149, 0.5, 0.800000011921, 0.600000023842, 0.899999976158, 0.899999976158, 0.5, 0.800000011921, 0.699999988079, 0.800000011921, 0.5, 0.5, 0.600000023842, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.699999988079, 0.40000000596, 0.300000011921, 0.20000000298, 0.600000023842, 0.899999976158, 0.800000011921, 0.800000011921, 0.10000000149, 0.899999976158, 0.699999988079, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.20000000298, 0.300000011921, 0.10000000149, 0.300000011921, 0.800000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.800000011921, 0.40000000596, 0.600000023842, 0.40000000596, 0.699999988079, 0.40000000596, 0.699999988079, 0.899999976158, 0.10000000149, 0.300000011921, 0.10000000149, 0.20000000298, 0.10000000149, 0.899999976158, 0.10000000149, 0.10000000149, 0.600000023842, 
+
+L3_cSYR2K_B_nk
+0.40000000596, 0.300000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.5, 0.10000000149, 0.699999988079, 0.300000011921, 0.600000023842, 0.800000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.40000000596, 0.800000011921, 0.800000011921, 0.20000000298, 0.699999988079, 0.20000000298, 0.699999988079, 0.20000000298, 0.40000000596, 0.800000011921, 0.20000000298, 0.800000011921, 0.600000023842, 0.800000011921, 0.899999976158, 0.899999976158, 0.600000023842, 0.600000023842, 0.20000000298, 0.20000000298, 0.300000011921, 0.20000000298, 0.20000000298, 0.899999976158, 0.5, 0.10000000149, 0.600000023842, 0.10000000149, 0.800000011921, 0.10000000149, 0.699999988079, 0.300000011921, 0.699999988079, 0.10000000149, 0.899999976158, 0.800000011921, 0.10000000149, 0.40000000596, 0.40000000596, 0.20000000298, 0.800000011921, 0.10000000149, 0.10000000149, 0.5, 0.10000000149, 0.899999976158, 0.20000000298, 0.20000000298, 0.899999976158, 0.40000000596, 0.800000011921, 0.20000000298, 0.40000000596, 0.40000000596, 0.300000011921, 0.20000000298, 0.10000000149, 0.899999976158, 0.300000011921, 0.10000000149, 0.699999988079, 0.899999976158, 0.20000000298, 0.300000011921, 0.40000000596, 0.20000000298, 0.20000000298, 0.5, 0.899999976158, 0.800000011921, 0.800000011921, 0.40000000596, 0.10000000149, 0.699999988079, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.800000011921, 0.5, 0.20000000298, 0.600000023842, 0.5, 0.300000011921, 0.899999976158, 0.10000000149, 0.300000011921, 0.699999988079, 0.20000000298, 0.600000023842, 0.40000000596, 0.699999988079, 0.10000000149, 0.699999988079, 0.800000011921, 0.699999988079, 0.800000011921, 0.300000011921, 0.899999976158, 0.800000011921, 0.600000023842, 0.800000011921, 0.600000023842, 0.600000023842, 0.300000011921, 0.600000023842, 0.800000011921, 0.699999988079, 0.600000023842, 0.10000000149, 0.40000000596, 0.899999976158, 0.899999976158, 0.20000000298, 0.20000000298, 0.5, 0.5, 0.10000000149, 0.10000000149, 0.899999976158, 0.300000011921, 0.699999988079, 0.800000011921, 0.10000000149, 0.800000011921, 0.5, 0.300000011921, 0.10000000149, 0.800000011921, 0.300000011921, 0.800000011921, 0.40000000596, 0.5, 0.10000000149, 0.600000023842, 0.699999988079, 0.699999988079, 0.699999988079, 0.5, 0.800000011921, 0.10000000149, 0.40000000596, 0.300000011921, 0.699999988079, 0.20000000298, 0.5, 0.699999988079, 0.10000000149, 0.899999976158, 0.40000000596, 0.20000000298, 0.10000000149, 0.300000011921, 0.10000000149, 0.300000011921, 0.899999976158, 0.699999988079, 0.800000011921, 0.20000000298, 0.800000011921, 0.300000011921, 0.10000000149, 0.300000011921, 0.600000023842, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.300000011921, 0.5, 0.20000000298, 0.5, 0.600000023842, 0.20000000298, 0.40000000596, 0.699999988079, 0.10000000149, 0.20000000298, 0.300000011921, 0.5, 0.600000023842, 0.20000000298, 0.40000000596, 0.5, 0.300000011921, 0.899999976158, 0.800000011921, 0.5, 0.899999976158, 0.40000000596, 0.699999988079, 0.40000000596, 0.600000023842, 0.600000023842, 0.899999976158, 0.20000000298, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.20000000298, 0.300000011921, 0.300000011921, 0.800000011921, 0.10000000149, 0.899999976158, 0.899999976158, 0.300000011921, 0.10000000149, 0.40000000596, 0.300000011921, 0.5, 0.699999988079, 0.899999976158, 0.300000011921, 0.600000023842, 0.899999976158, 0.800000011921, 0.899999976158, 0.40000000596, 0.5, 0.600000023842, 0.699999988079, 0.899999976158, 0.5, 0.5, 0.899999976158, 0.20000000298, 0.5, 0.800000011921, 0.600000023842, 0.600000023842, 0.699999988079, 0.10000000149, 0.10000000149, 0.699999988079, 0.600000023842, 0.300000011921, 0.10000000149, 0.600000023842, 0.899999976158, 0.10000000149, 0.800000011921, 0.300000011921, 0.40000000596, 0.300000011921, 0.5, 0.899999976158, 0.40000000596, 0.20000000298, 0.699999988079, 0.40000000596, 0.40000000596, 0.899999976158, 0.300000011921, 0.800000011921, 0.40000000596, 0.899999976158, 0.300000011921, 0.899999976158, 0.10000000149, 0.699999988079, 0.40000000596, 0.600000023842, 0.600000023842, 0.800000011921, 0.10000000149, 0.20000000298, 0.40000000596, 0.600000023842, 0.20000000298, 0.800000011921, 0.899999976158, 0.800000011921, 0.10000000149, 0.40000000596, 0.300000011921, 0.40000000596, 0.800000011921, 0.10000000149, 0.600000023842, 0.600000023842, 0.40000000596, 0.5, 0.20000000298, 0.40000000596, 0.600000023842, 0.20000000298, 0.300000011921, 0.899999976158, 0.10000000149, 0.899999976158, 0.5, 0.20000000298, 0.20000000298, 0.699999988079, 0.10000000149, 0.5, 0.300000011921, 0.600000023842, 0.800000011921, 0.699999988079, 0.899999976158, 0.800000011921, 0.699999988079, 0.40000000596, 0.800000011921, 0.300000011921, 0.10000000149, 0.20000000298, 0.10000000149, 0.5, 0.300000011921, 0.800000011921, 0.20000000298, 0.5, 0.20000000298, 0.10000000149, 0.899999976158, 0.40000000596, 0.600000023842, 0.600000023842, 0.5, 0.800000011921, 0.40000000596, 0.40000000596, 0.600000023842, 0.300000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.600000023842, 0.899999976158, 0.800000011921, 0.5, 0.10000000149, 0.300000011921, 0.800000011921, 0.800000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.40000000596, 0.600000023842, 0.899999976158, 0.5, 0.40000000596, 0.40000000596, 0.300000011921, 0.5, 0.899999976158, 0.699999988079, 0.899999976158, 0.10000000149, 0.5, 0.699999988079, 0.600000023842, 0.600000023842, 0.5, 0.600000023842, 0.600000023842, 0.899999976158, 0.300000011921, 0.800000011921, 0.5, 0.899999976158, 0.5, 0.5, 0.600000023842, 0.10000000149, 0.699999988079, 0.699999988079, 0.20000000298, 0.300000011921, 0.699999988079, 0.5, 0.10000000149, 0.800000011921, 0.800000011921, 0.10000000149, 0.20000000298, 0.40000000596, 0.600000023842, 0.40000000596, 0.10000000149, 0.600000023842, 0.40000000596, 0.600000023842, 0.699999988079, 0.20000000298, 0.40000000596, 0.5, 0.600000023842, 0.10000000149, 0.300000011921, 0.600000023842, 0.40000000596, 0.5, 0.600000023842, 0.40000000596, 0.20000000298, 0.600000023842, 0.20000000298, 0.600000023842, 0.800000011921, 0.699999988079, 0.5, 0.10000000149, 0.20000000298, 0.40000000596, 0.40000000596, 0.5, 0.899999976158, 0.800000011921, 0.20000000298, 0.10000000149, 0.20000000298, 0.600000023842, 0.300000011921, 0.20000000298, 0.40000000596, 0.20000000298, 0.300000011921, 0.10000000149, 0.899999976158, 0.5, 0.899999976158, 0.5, 0.699999988079, 0.40000000596, 0.10000000149, 0.300000011921, 0.300000011921, 0.899999976158, 0.899999976158, 0.300000011921, 0.300000011921, 0.20000000298, 0.300000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.699999988079, 0.20000000298, 0.10000000149, 0.5, 0.10000000149, 0.300000011921, 0.600000023842, 0.5, 0.600000023842, 0.20000000298, 0.40000000596, 0.20000000298, 0.300000011921, 0.300000011921, 0.600000023842, 0.800000011921, 0.5, 0.40000000596, 0.10000000149, 0.699999988079, 0.40000000596, 0.699999988079, 0.600000023842, 0.899999976158, 0.699999988079, 0.300000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.699999988079, 0.40000000596, 0.300000011921, 0.40000000596, 0.600000023842, 0.10000000149, 0.20000000298, 0.10000000149, 0.20000000298, 0.10000000149, 0.899999976158, 0.899999976158, 0.600000023842, 0.20000000298, 0.10000000149, 0.5, 0.20000000298, 0.20000000298, 0.699999988079, 0.40000000596, 0.40000000596, 0.800000011921, 0.899999976158, 0.899999976158, 0.899999976158, 0.800000011921, 0.300000011921, 0.899999976158, 0.600000023842, 0.800000011921, 0.10000000149, 0.699999988079, 0.300000011921, 0.899999976158, 0.899999976158, 0.300000011921, 0.699999988079, 0.10000000149, 0.300000011921, 0.699999988079, 0.5, 0.699999988079, 0.600000023842, 0.800000011921, 0.600000023842, 0.600000023842, 0.10000000149, 0.300000011921, 0.5, 0.300000011921, 0.600000023842, 0.10000000149, 0.699999988079, 0.40000000596, 0.699999988079, 0.800000011921, 0.300000011921, 0.10000000149, 0.800000011921, 
+
+L3_cSYR2K_C_nn
+0.600000023842, 0.20000000298, 0.699999988079, 0.800000011921, 0.699999988079, 0.699999988079, 0.699999988079, 0.899999976158, 0.5, 0.899999976158, 0.899999976158, 0.5, 0.600000023842, 0.5, 0.899999976158, 0.5, 0.300000011921, 0.5, 0.20000000298, 0.20000000298, 0.10000000149, 0.699999988079, 0.10000000149, 0.5, 0.10000000149, 0.40000000596, 0.800000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.800000011921, 0.800000011921, 0.20000000298, 0.899999976158, 0.699999988079, 0.800000011921, 0.800000011921, 0.300000011921, 0.699999988079, 0.800000011921, 0.10000000149, 0.800000011921, 0.800000011921, 0.699999988079, 0.899999976158, 0.899999976158, 0.20000000298, 0.300000011921, 0.300000011921, 0.899999976158, 0.699999988079, 0.600000023842, 0.20000000298, 0.699999988079, 0.40000000596, 0.10000000149, 0.5, 0.5, 0.300000011921, 0.10000000149, 0.899999976158, 0.20000000298, 0.20000000298, 0.10000000149, 0.899999976158, 0.600000023842, 0.899999976158, 0.699999988079, 0.699999988079, 0.699999988079, 0.699999988079, 0.800000011921, 0.600000023842, 0.600000023842, 0.5, 0.40000000596, 0.10000000149, 0.40000000596, 0.300000011921, 0.300000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.699999988079, 0.800000011921, 0.600000023842, 0.800000011921, 0.5, 0.10000000149, 0.699999988079, 0.20000000298, 0.40000000596, 0.800000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.10000000149, 0.20000000298, 0.10000000149, 0.20000000298, 0.800000011921, 0.600000023842, 0.699999988079, 0.899999976158, 0.10000000149, 0.800000011921, 0.5, 0.40000000596, 0.300000011921, 0.300000011921, 0.10000000149, 0.600000023842, 0.699999988079, 0.600000023842, 0.600000023842, 0.899999976158, 0.20000000298, 0.5, 0.40000000596, 0.10000000149, 0.20000000298, 0.5, 0.20000000298, 0.800000011921, 0.20000000298, 0.699999988079, 0.5, 0.40000000596, 0.40000000596, 0.699999988079, 0.300000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.600000023842, 0.899999976158, 0.5, 0.899999976158, 0.800000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.10000000149, 0.600000023842, 0.10000000149, 0.899999976158, 0.699999988079, 0.800000011921, 0.899999976158, 0.899999976158, 0.300000011921, 0.40000000596, 0.300000011921, 0.20000000298, 0.800000011921, 0.699999988079, 0.40000000596, 0.300000011921, 0.300000011921, 0.800000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.600000023842, 0.899999976158, 0.40000000596, 0.300000011921, 0.10000000149, 0.300000011921, 0.10000000149, 0.899999976158, 0.5, 0.899999976158, 0.899999976158, 0.300000011921, 0.300000011921, 0.699999988079, 0.600000023842, 0.699999988079, 0.800000011921, 0.300000011921, 0.300000011921, 0.600000023842, 0.600000023842, 0.5, 0.10000000149, 0.300000011921, 0.10000000149, 0.10000000149, 0.5, 0.5, 0.10000000149, 0.800000011921, 0.300000011921, 0.5, 0.10000000149, 0.40000000596, 0.20000000298, 0.10000000149, 0.5, 0.899999976158, 0.40000000596, 0.899999976158, 0.800000011921, 0.600000023842, 0.5, 0.20000000298, 0.300000011921, 0.10000000149, 0.10000000149, 0.600000023842, 0.899999976158, 0.899999976158, 0.899999976158, 0.600000023842, 0.600000023842, 0.40000000596, 0.699999988079, 0.5, 0.40000000596, 0.800000011921, 0.40000000596, 0.300000011921, 0.20000000298, 0.600000023842, 0.300000011921, 0.5, 0.600000023842, 0.20000000298, 0.20000000298, 0.899999976158, 0.699999988079, 0.699999988079, 0.20000000298, 0.20000000298, 0.10000000149, 0.800000011921, 0.20000000298, 0.899999976158, 0.5, 0.300000011921, 0.899999976158, 0.20000000298, 0.699999988079, 0.20000000298, 0.5, 0.300000011921, 0.40000000596, 0.5, 0.10000000149, 0.5, 0.40000000596, 0.20000000298, 0.10000000149, 0.40000000596, 0.600000023842, 0.40000000596, 0.800000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.10000000149, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.899999976158, 0.699999988079, 0.20000000298, 0.800000011921, 0.40000000596, 0.699999988079, 0.300000011921, 0.5, 0.699999988079, 0.600000023842, 0.800000011921, 0.600000023842, 0.40000000596, 0.10000000149, 0.300000011921, 0.20000000298, 0.300000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.40000000596, 0.600000023842, 0.300000011921, 0.40000000596, 0.800000011921, 0.5, 0.699999988079, 0.300000011921, 0.800000011921, 0.40000000596, 0.20000000298, 0.899999976158, 0.899999976158, 0.5, 0.40000000596, 0.899999976158, 0.600000023842, 0.20000000298, 0.800000011921, 0.40000000596, 0.20000000298, 0.20000000298, 0.20000000298, 0.699999988079, 0.800000011921, 0.5, 0.20000000298, 0.5, 0.800000011921, 0.699999988079, 0.10000000149, 0.5, 0.300000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.800000011921, 0.5, 0.800000011921, 0.20000000298, 0.699999988079, 0.10000000149, 0.600000023842, 0.800000011921, 0.300000011921, 0.10000000149, 0.899999976158, 0.600000023842, 0.10000000149, 0.10000000149, 0.20000000298, 0.5, 0.10000000149, 0.800000011921, 0.10000000149, 0.699999988079, 0.40000000596, 0.10000000149, 0.10000000149, 0.699999988079, 0.20000000298, 0.800000011921, 0.40000000596, 0.300000011921, 0.5, 0.10000000149, 0.600000023842, 0.300000011921, 0.699999988079, 0.20000000298, 0.699999988079, 0.300000011921, 0.699999988079, 0.10000000149, 0.5, 0.699999988079, 0.300000011921, 0.20000000298, 0.40000000596, 0.600000023842, 0.699999988079, 0.600000023842, 0.40000000596, 0.899999976158, 0.600000023842, 0.800000011921, 0.10000000149, 0.5, 0.10000000149, 0.5, 0.5, 0.5, 0.20000000298, 0.40000000596, 0.20000000298, 0.699999988079, 0.300000011921, 0.800000011921, 0.800000011921, 0.300000011921, 0.5, 0.600000023842, 0.40000000596, 0.10000000149, 0.800000011921, 0.40000000596, 0.600000023842, 0.800000011921, 0.300000011921, 0.20000000298, 0.300000011921, 0.800000011921, 0.800000011921, 0.20000000298, 0.300000011921, 0.899999976158, 0.899999976158, 0.600000023842, 0.899999976158, 0.40000000596, 0.40000000596, 0.699999988079, 0.10000000149, 0.40000000596, 0.300000011921, 0.10000000149, 0.800000011921, 0.699999988079, 0.5, 0.40000000596, 0.800000011921, 0.10000000149, 0.5, 0.10000000149, 0.20000000298, 0.20000000298, 0.899999976158, 0.10000000149, 0.20000000298, 0.899999976158, 0.300000011921, 0.10000000149, 0.40000000596, 0.600000023842, 0.800000011921, 0.20000000298, 0.699999988079, 0.899999976158, 0.800000011921, 0.20000000298, 0.699999988079, 0.300000011921, 0.5, 0.20000000298, 0.40000000596, 0.20000000298, 0.800000011921, 0.800000011921, 0.899999976158, 0.20000000298, 0.10000000149, 0.600000023842, 0.40000000596, 0.699999988079, 0.699999988079, 0.600000023842, 0.40000000596, 0.20000000298, 0.899999976158, 0.699999988079, 0.800000011921, 0.800000011921, 0.899999976158, 0.5, 0.899999976158, 0.600000023842, 0.699999988079, 0.600000023842, 0.300000011921, 0.899999976158, 0.800000011921, 0.20000000298, 0.5, 0.800000011921, 0.300000011921, 0.5, 0.899999976158, 0.899999976158, 0.40000000596, 0.699999988079, 0.10000000149, 0.699999988079, 0.20000000298, 0.10000000149, 0.10000000149, 0.20000000298, 0.300000011921, 0.300000011921, 0.899999976158, 0.40000000596, 0.10000000149, 0.5, 0.699999988079, 0.20000000298, 0.899999976158, 0.699999988079, 0.40000000596, 0.899999976158, 0.10000000149, 0.10000000149, 0.40000000596, 0.899999976158, 0.899999976158, 0.600000023842, 0.699999988079, 0.300000011921, 0.300000011921, 0.5, 0.699999988079, 0.5, 0.300000011921, 0.899999976158, 0.300000011921, 0.40000000596, 0.800000011921, 0.800000011921, 0.899999976158, 0.600000023842, 0.10000000149, 0.20000000298, 0.10000000149, 0.800000011921, 0.300000011921, 0.10000000149, 0.899999976158, 0.40000000596, 0.20000000298, 0.10000000149, 0.20000000298, 0.800000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.5, 0.600000023842, 0.800000011921, 0.899999976158, 0.40000000596, 0.5, 0.20000000298, 0.899999976158, 0.899999976158, 0.300000011921, 0.899999976158, 0.699999988079, 0.800000011921, 0.899999976158, 0.899999976158, 0.20000000298, 0.899999976158, 0.899999976158, 0.699999988079, 0.800000011921, 0.600000023842, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.899999976158, 0.800000011921, 0.800000011921, 0.20000000298, 0.40000000596, 0.699999988079, 0.800000011921, 0.40000000596, 0.10000000149, 0.800000011921, 0.10000000149, 0.5, 0.40000000596, 0.699999988079, 0.40000000596, 0.20000000298, 0.40000000596, 0.699999988079, 0.300000011921, 0.40000000596, 0.899999976158, 0.899999976158, 0.300000011921, 0.10000000149, 
+
+L3_cSYR2K_o_N
+0.100000205636, 17.3600001836, 3.19999998882, 15.6400001837, 0.390000019819, 17.9800001387, -0.719999894798, 18.6800000799, 1.09000013381, 16.1700002398, 0.0500000879169, 16.4000001229, -0.399999970943, 17.5600000837, 3.10999989375, 18.5100001754, -0.0299999681115, 16.5200002718, -2.50999992356, 16.6200001667, -0.619999962598, 15.6900002359, -0.189999952763, 18.5300001998, 1.24999995008, 16.4600003006, 1.80000002831, 16.6200002114, -1.32999993458, 17.4800001253, 1.6600000979, 18.590000186, -8.86619080376e-08, 18.1200001273, 3.19999998882, 15.6400001837, 4.21999997973, 13.2200000334, 2.71000001818, 15.8300001067, 0.550000087172, 15.7400001331, 2.84000010625, 14.7500000276, 1.8400000526, 13.4300000791, 0.490000068247, 15.7300000612, 2.89999991283, 16.1500000499, 0.86000001967, 15.2300002103, 0.889999989271, 14.75000007, 1.98000000536, 13.9000001088, 2.50999998763, 16.2200000855, 2.16999993131, 14.8900000653, 1.93999998927, 13.9300000672, 0.570000029653, 16.1999999344, 4.10999997422, 15.1500001065, 2.23999989912, 15.0200001094, 0.390000019819, 17.9800001387, 2.71000001818, 15.8300001067, 3.37999994129, 17.5200001705, 1.31000006512, 17.6800001156, 0.95000012368, 14.7500001468, 0.850000036508, 15.7600000703, 0.0400000473857, 16.5800002132, 2.63999987826, 18.9900000921, 1.53000002474, 17.6200001489, -0.53999991104, 16.1100001098, 0.340000019819, 14.6300001924, 1.61999995813, 18.5800001611, 1.69999990091, 16.5600001806, 0.860000013709, 15.6600001284, -0.409999904931, 16.420000131, 1.58999997735, 17.4500000671, 1.29999994412, 17.4900000995, -0.719999894798, 18.6800000799, 0.550000087172, 15.7400001331, 1.31000006512, 17.6800001156, -2.59999978095, 18.060000045, 0.920000131726, 15.9400002091, -1.58999983653, 16.960000083, -1.93999978215, 18.3000000894, -1.21000002638, 18.5100000241, -1.44999985024, 15.8100002313, -3.029999872, 16.8700000975, -0.599999890476, 15.430000053, -0.309999875128, 19.1700000967, 1.04000002205, 17.230000176, 0.0600000874698, 15.2500001542, -0.719999842644, 16.3300000709, 0.480000142455, 19.5200000237, -0.709999872148, 18.1600000972, 1.09000013381, 16.1700002398, 2.84000010625, 14.7500000276, 0.95000012368, 14.7500001468, 0.920000131726, 15.9400002091, 0.380000218451, 14.5200001734, 1.70000014752, 14.1800001477, -0.689999858886, 16.6000001661, 2.43000000834, 15.9900001286, 0.890000083894, 15.7700001757, 0.160000083745, 15.2000001699, 0.860000102371, 14.1500001788, 0.450000228733, 16.9900001793, 2.11000006363, 13.9900002106, 1.62000008553, 15.0400001696, -0.419999831468, 16.2000000969, 2.96000013366, 15.8500001319, 0.0800001402199, 15.2000001483, 0.0500000879169, 16.4000001229, 1.8400000526, 13.4300000791, 0.850000036508, 15.7600000703, -1.58999983653, 16.960000083, 1.70000014752, 14.1800001477, -2.01999979496, 14.1000001103, -1.1199999015, 15.2300001186, 0.370000032634, 15.6800001149, -1.09999993518, 14.6700001936, -2.54999989718, 14.1900001316, 0.310000056922, 13.2100001061, 1.27000007063, 17.0200000758, 0.999999981374, 14.5300002289, 0.0800000292063, 12.8600001769, -0.269999954402, 15.1700000453, 0.600000037253, 16.3700000989, 0.459999935478, 15.7400001442, -0.399999970943, 17.5600000837, 0.490000068247, 15.7300000612, 0.0400000473857, 16.5800002132, -1.93999978215, 18.3000000894, -0.689999858886, 16.6000001661, -1.1199999015, 15.2300001186, -1.32000000507, 18.1800001082, 0.629999933839, 17.1200001019, -1.66999981359, 15.7200002725, -2.93999987751, 15.5600001381, 0.0600000539422, 13.9800002378, -0.98999991402, 18.3200001965, 0.489999958724, 15.3100002417, 1.19999991283, 15.6200000781, -1.12999992639, 16.5600001694, 0.220000107884, 17.3200000677, -0.44999999404, 16.0600002052, 3.10999989375, 18.5100001754, 2.89999991283, 16.1500000499, 2.63999987826, 18.9900000921, -1.21000002638, 18.5100000241, 2.43000000834, 15.9900001286, 0.370000032634, 15.6800001149, 0.629999933839, 17.1200001019, 2.95999968141, 18.060000115, 0.429999964386, 18.8200001384, -0.830000011325, 17.6600000443, 1.39999996349, 15.9100000726, 1.3199998866, 18.4600001188, 2.82999986678, 18.330000135, 2.93999993041, 16.3400001651, 0.989999978095, 18.869999938, 3.03999986783, 20.4800000508, 0.549999915063, 17.4800001961, -0.0299999681115, 16.5200002718, 0.86000001967, 15.2300002103, 1.53000002474, 17.6200001489, -1.44999985024, 15.8100002313, 0.890000083894, 15.7700001757, -1.09999993518, 14.6700001936, -1.66999981359, 15.7200002725, 0.429999964386, 18.8200001384, -1.21999999166, 16.6800002676, -1.96999992609, 15.5100002149, -0.829999933094, 14.0800002296, -0.00999994292855, 18.1900002143, 0.10999996379, 17.5300001656, 0.570000049025, 15.7900002076, -2.26999984786, 16.6000001155, 0.22000004679, 17.6700000915, -1.02999996737, 15.4400002545, -2.50999992356, 16.6200001667, 0.889999989271, 14.75000007, -0.53999991104, 16.1100001098, -3.029999872, 16.8700000975, 0.160000083745, 15.2000001699, -2.54999989718, 14.1900001316, -2.93999987751, 15.5600001381, -0.830000011325, 17.6600000443, -1.96999992609, 15.5100002149, -2.29999995232, 16.1400001234, -1.59999992177, 13.6400001472, -1.29999994859, 18.110000115, -0.880000041127, 15.9000001684, 0.409999938458, 15.490000174, -2.71999992758, 15.8500001058, -1.34999990016, 18.5200000587, -2.33000002995, 16.5900001167, -0.619999962598, 15.6900002359, 1.98000000536, 13.9000001088, 0.340000019819, 14.6300001924, -0.599999890476, 15.430000053, 0.860000102371, 14.1500001788, 0.310000056922, 13.2100001061, 0.0600000539422, 13.9800002378, 1.39999996349, 15.9100000726, -0.829999933094, 14.0800002296, -1.59999992177, 13.6400001472, 0.480000005364, 12.96000027, -0.300000012666, 16.2600002402, 1.12999990404, 14.910000241, 1.5800000374, 14.2000002131, -0.789999981821, 14.4000001952, 0.720000101179, 15.9100001583, -0.660000046492, 14.0300001991, -0.189999952763, 18.5300001998, 2.50999998763, 16.2200000855, 1.61999995813, 18.5800001611, -0.309999875128, 19.1700000967, 0.450000228733, 16.9900001793, 1.27000007063, 17.0200000758, -0.98999991402, 18.3200001965, 1.3199998866, 18.4600001188, -0.00999994292855, 18.1900002143, -1.29999994859, 18.110000115, -0.300000012666, 16.2600002402, 0.540000016093, 20.8400001204, 1.60999992803, 18.3000001512, 1.40999994516, 16.740000069, -0.609999887794, 18.9900000541, 2.36000000253, 20.030000132, -0.200000020117, 18.8100001024, 1.24999995008, 16.4600003006, 2.16999993131, 14.8900000653, 1.69999990091, 16.5600001806, 1.04000002205, 17.230000176, 2.11000006363, 13.9900002106, 0.999999981374, 14.5300002289, 0.489999958724, 15.3100002417, 2.82999986678, 18.330000135, 0.10999996379, 17.5300001656, -0.880000041127, 15.9000001684, 1.12999990404, 14.910000241, 1.60999992803, 18.3000001512, 1.95999982446, 16.3000002071, 1.67999996886, 14.7100002626, -0.340000032485, 15.2600002432, 2.31999990001, 16.8300001976, 0.659999901205, 15.6000001907, 1.80000002831, 16.6200002114, 1.93999998927, 13.9300000672, 0.860000013709, 15.6600001284, 0.0600000874698, 15.2500001542, 1.62000008553, 15.0400001696, 0.0800000292063, 12.8600001769, 1.19999991283, 15.6200000781, 2.93999993041, 16.3400001651, 0.570000049025, 15.7900002076, 0.409999938458, 15.490000174, 1.5800000374, 14.2000002131, 1.40999994516, 16.740000069, 1.67999996886, 14.7100002626, 1.2799999994, 14.760000203, -0.0299999278784, 15.800000076, 2.24999999851, 16.560000077, 0.54999994114, 15.2400002031, -1.32999993458, 17.4800001253, 0.570000029653, 16.1999999344, -0.409999904931, 16.420000131, -0.719999842644, 16.3300000709, -0.419999831468, 16.2000000969, -0.269999954402, 15.1700000453, -1.12999992639, 16.5600001694, 0.989999978095, 18.869999938, -2.26999984786, 16.6000001155, -2.71999992758, 15.8500001058, -0.789999981821, 14.4000001952, -0.609999887794, 18.9900000541, -0.340000032485, 15.2600002432, -0.0299999278784, 15.800000076, -3.35999974102, 16.5000000745, -0.0399998469651, 17.6200000244, -0.97999994725, 15.5800000791, 1.6600000979, 18.590000186, 4.10999997422, 15.1500001065, 1.58999997735, 17.4500000671, 0.480000142455, 19.5200000237, 2.96000013366, 15.8500001319, 0.600000037253, 16.3700000989, 0.220000107884, 17.3200000677, 3.03999986783, 20.4800000508, 0.22000004679, 17.6700000915, -1.34999990016, 18.5200000587, 0.720000101179, 15.9100001583, 2.36000000253, 20.030000132, 2.31999990001, 16.8300001976, 2.24999999851, 16.560000077, -0.0399998469651, 17.6200000244, 1.42000006169, 19.2200000781, 1.94999997839, 17.6300001343, -8.86619080376e-08, 18.1200001273, 2.23999989912, 15.0200001094, 1.29999994412, 17.4900000995, -0.709999872148, 18.1600000972, 0.0800001402199, 15.2000001483, 0.459999935478, 15.7400001442, -0.44999999404, 16.0600002052, 0.549999915063, 17.4800001961, -1.02999996737, 15.4400002545, -2.33000002995, 16.5900001167, -0.660000046492, 14.0300001991, -0.200000020117, 18.8100001024, 0.659999901205, 15.6000001907, 0.54999994114, 15.2400002031, -0.97999994725, 15.5800000791, 1.94999997839, 17.6300001343, 0.779999850392, 15.8000001729, 
+
+L3_cSYR2K_A_kn
+0.10000000149, 0.10000000149, 0.300000011921, 0.800000011921, 0.699999988079, 0.699999988079, 0.800000011921, 0.40000000596, 0.699999988079, 0.20000000298, 0.899999976158, 0.5, 0.600000023842, 0.20000000298, 0.40000000596, 0.899999976158, 0.5, 0.20000000298, 0.800000011921, 0.899999976158, 0.10000000149, 0.5, 0.899999976158, 0.300000011921, 0.300000011921, 0.40000000596, 0.40000000596, 0.300000011921, 0.10000000149, 0.5, 0.800000011921, 0.899999976158, 0.300000011921, 0.699999988079, 0.10000000149, 0.40000000596, 0.600000023842, 0.800000011921, 0.10000000149, 0.600000023842, 0.20000000298, 0.800000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.800000011921, 0.20000000298, 0.600000023842, 0.300000011921, 0.40000000596, 0.20000000298, 0.800000011921, 0.600000023842, 0.20000000298, 0.5, 0.300000011921, 0.300000011921, 0.300000011921, 0.899999976158, 0.300000011921, 0.20000000298, 0.899999976158, 0.600000023842, 0.699999988079, 0.5, 0.20000000298, 0.699999988079, 0.899999976158, 0.600000023842, 0.40000000596, 0.5, 0.5, 0.300000011921, 0.800000011921, 0.5, 0.300000011921, 0.5, 0.800000011921, 0.800000011921, 0.600000023842, 0.899999976158, 0.899999976158, 0.899999976158, 0.899999976158, 0.600000023842, 0.600000023842, 0.699999988079, 0.600000023842, 0.5, 0.800000011921, 0.40000000596, 0.800000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.899999976158, 0.699999988079, 0.300000011921, 0.699999988079, 0.600000023842, 0.10000000149, 0.20000000298, 0.800000011921, 0.10000000149, 0.20000000298, 0.600000023842, 0.20000000298, 0.800000011921, 0.300000011921, 0.5, 0.10000000149, 0.899999976158, 0.300000011921, 0.899999976158, 0.800000011921, 0.899999976158, 0.800000011921, 0.899999976158, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.20000000298, 0.5, 0.600000023842, 0.699999988079, 0.699999988079, 0.20000000298, 0.300000011921, 0.800000011921, 0.40000000596, 0.899999976158, 0.899999976158, 0.600000023842, 0.899999976158, 0.300000011921, 0.20000000298, 0.699999988079, 0.10000000149, 0.699999988079, 0.800000011921, 0.10000000149, 0.20000000298, 0.5, 0.699999988079, 0.5, 0.10000000149, 0.5, 0.10000000149, 0.600000023842, 0.800000011921, 0.699999988079, 0.699999988079, 0.40000000596, 0.899999976158, 0.800000011921, 0.300000011921, 0.10000000149, 0.40000000596, 0.10000000149, 0.800000011921, 0.10000000149, 0.300000011921, 0.10000000149, 0.600000023842, 0.699999988079, 0.600000023842, 0.699999988079, 0.5, 0.600000023842, 0.10000000149, 0.800000011921, 0.800000011921, 0.20000000298, 0.800000011921, 0.10000000149, 0.20000000298, 0.5, 0.5, 0.20000000298, 0.699999988079, 0.40000000596, 0.5, 0.899999976158, 0.10000000149, 0.20000000298, 0.600000023842, 0.300000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.300000011921, 0.899999976158, 0.699999988079, 0.600000023842, 0.800000011921, 0.899999976158, 0.20000000298, 0.20000000298, 0.699999988079, 0.899999976158, 0.300000011921, 0.699999988079, 0.10000000149, 0.20000000298, 0.20000000298, 0.20000000298, 0.699999988079, 0.899999976158, 0.600000023842, 0.699999988079, 0.20000000298, 0.800000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.5, 0.5, 0.800000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.699999988079, 0.20000000298, 0.5, 0.5, 0.600000023842, 0.40000000596, 0.699999988079, 0.800000011921, 0.40000000596, 0.10000000149, 0.800000011921, 0.699999988079, 0.800000011921, 0.20000000298, 0.300000011921, 0.10000000149, 0.40000000596, 0.699999988079, 0.40000000596, 0.20000000298, 0.5, 0.699999988079, 0.5, 0.699999988079, 0.300000011921, 0.699999988079, 0.600000023842, 0.5, 0.300000011921, 0.40000000596, 0.5, 0.5, 0.20000000298, 0.600000023842, 0.800000011921, 0.300000011921, 0.800000011921, 0.5, 0.300000011921, 0.5, 0.699999988079, 0.20000000298, 0.20000000298, 0.699999988079, 0.10000000149, 0.5, 0.699999988079, 0.5, 0.899999976158, 0.899999976158, 0.699999988079, 0.10000000149, 0.600000023842, 0.699999988079, 0.300000011921, 0.800000011921, 0.20000000298, 0.300000011921, 0.899999976158, 0.300000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.699999988079, 0.600000023842, 0.300000011921, 0.10000000149, 0.5, 0.300000011921, 0.699999988079, 0.5, 0.800000011921, 0.699999988079, 0.600000023842, 0.5, 0.699999988079, 0.899999976158, 0.899999976158, 0.40000000596, 0.5, 0.10000000149, 0.20000000298, 0.10000000149, 0.20000000298, 0.800000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.20000000298, 0.699999988079, 0.600000023842, 0.20000000298, 0.5, 0.699999988079, 0.800000011921, 0.10000000149, 0.10000000149, 0.600000023842, 0.300000011921, 0.10000000149, 0.20000000298, 0.10000000149, 0.600000023842, 0.300000011921, 0.699999988079, 0.20000000298, 0.20000000298, 0.10000000149, 0.20000000298, 0.5, 0.20000000298, 0.5, 0.300000011921, 0.40000000596, 0.40000000596, 0.300000011921, 0.699999988079, 0.899999976158, 0.5, 0.40000000596, 0.899999976158, 0.800000011921, 0.899999976158, 0.10000000149, 0.600000023842, 0.899999976158, 0.20000000298, 0.699999988079, 0.800000011921, 0.899999976158, 0.5, 0.600000023842, 0.600000023842, 0.800000011921, 0.899999976158, 0.699999988079, 0.300000011921, 0.40000000596, 0.300000011921, 0.40000000596, 0.10000000149, 0.699999988079, 0.699999988079, 0.10000000149, 0.699999988079, 0.5, 0.699999988079, 0.5, 0.899999976158, 0.300000011921, 0.40000000596, 0.40000000596, 0.600000023842, 0.40000000596, 0.10000000149, 0.40000000596, 0.600000023842, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.300000011921, 0.600000023842, 0.10000000149, 0.40000000596, 0.10000000149, 0.5, 0.5, 0.800000011921, 0.40000000596, 0.899999976158, 0.800000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.300000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.899999976158, 0.699999988079, 0.10000000149, 0.699999988079, 0.800000011921, 0.600000023842, 0.300000011921, 0.800000011921, 0.5, 0.600000023842, 0.20000000298, 0.20000000298, 0.40000000596, 0.5, 0.300000011921, 0.699999988079, 0.899999976158, 0.600000023842, 0.5, 0.699999988079, 0.20000000298, 0.800000011921, 0.300000011921, 0.600000023842, 0.699999988079, 0.300000011921, 0.800000011921, 0.899999976158, 0.699999988079, 0.600000023842, 0.899999976158, 0.300000011921, 0.600000023842, 0.899999976158, 0.699999988079, 0.40000000596, 0.40000000596, 0.300000011921, 0.899999976158, 0.20000000298, 0.5, 0.5, 0.899999976158, 0.40000000596, 0.5, 0.699999988079, 0.899999976158, 0.800000011921, 0.699999988079, 0.40000000596, 0.300000011921, 0.800000011921, 0.699999988079, 0.899999976158, 0.600000023842, 0.600000023842, 0.300000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.40000000596, 0.20000000298, 0.899999976158, 0.899999976158, 0.800000011921, 0.20000000298, 0.10000000149, 0.5, 0.5, 0.20000000298, 0.5, 0.40000000596, 0.600000023842, 0.40000000596, 0.600000023842, 0.899999976158, 0.10000000149, 0.899999976158, 0.300000011921, 0.20000000298, 0.10000000149, 0.699999988079, 0.40000000596, 0.699999988079, 0.600000023842, 0.10000000149, 0.40000000596, 0.300000011921, 0.600000023842, 0.40000000596, 0.10000000149, 0.5, 0.699999988079, 0.20000000298, 0.40000000596, 0.800000011921, 0.5, 0.600000023842, 0.899999976158, 0.5, 0.899999976158, 0.10000000149, 0.300000011921, 0.899999976158, 0.800000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.899999976158, 0.20000000298, 0.40000000596, 0.40000000596, 0.899999976158, 0.5, 0.5, 0.800000011921, 0.800000011921, 0.300000011921, 0.5, 0.20000000298, 0.40000000596, 0.899999976158, 0.800000011921, 0.10000000149, 0.800000011921, 0.300000011921, 0.899999976158, 0.600000023842, 0.899999976158, 0.20000000298, 0.10000000149, 0.10000000149, 0.40000000596, 0.5, 0.699999988079, 0.600000023842, 0.600000023842, 0.699999988079, 0.800000011921, 0.800000011921, 0.600000023842, 0.899999976158, 0.699999988079, 
+
+L3_cSYR2K_B_kn
+0.800000011921, 0.699999988079, 0.899999976158, 0.40000000596, 0.5, 0.600000023842, 0.300000011921, 0.800000011921, 0.300000011921, 0.20000000298, 0.600000023842, 0.20000000298, 0.800000011921, 0.600000023842, 0.800000011921, 0.10000000149, 0.800000011921, 0.899999976158, 0.300000011921, 0.5, 0.800000011921, 0.20000000298, 0.20000000298, 0.699999988079, 0.5, 0.10000000149, 0.10000000149, 0.699999988079, 0.40000000596, 0.40000000596, 0.10000000149, 0.10000000149, 0.40000000596, 0.10000000149, 0.10000000149, 0.800000011921, 0.5, 0.800000011921, 0.40000000596, 0.20000000298, 0.10000000149, 0.10000000149, 0.699999988079, 0.899999976158, 0.899999976158, 0.600000023842, 0.300000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.899999976158, 0.800000011921, 0.300000011921, 0.20000000298, 0.10000000149, 0.20000000298, 0.899999976158, 0.600000023842, 0.5, 0.10000000149, 0.699999988079, 0.800000011921, 0.10000000149, 0.600000023842, 0.600000023842, 0.5, 0.10000000149, 0.699999988079, 0.40000000596, 0.5, 0.699999988079, 0.5, 0.10000000149, 0.800000011921, 0.699999988079, 0.899999976158, 0.800000011921, 0.40000000596, 0.5, 0.300000011921, 0.800000011921, 0.5, 0.800000011921, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.300000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.10000000149, 0.20000000298, 0.699999988079, 0.300000011921, 0.40000000596, 0.5, 0.5, 0.5, 0.800000011921, 0.699999988079, 0.10000000149, 0.600000023842, 0.5, 0.800000011921, 0.600000023842, 0.899999976158, 0.10000000149, 0.20000000298, 0.5, 0.699999988079, 0.5, 0.899999976158, 0.40000000596, 0.10000000149, 0.899999976158, 0.800000011921, 0.10000000149, 0.20000000298, 0.10000000149, 0.800000011921, 0.800000011921, 0.899999976158, 0.699999988079, 0.699999988079, 0.300000011921, 0.40000000596, 0.600000023842, 0.40000000596, 0.10000000149, 0.600000023842, 0.699999988079, 0.800000011921, 0.899999976158, 0.40000000596, 0.699999988079, 0.5, 0.10000000149, 0.300000011921, 0.899999976158, 0.600000023842, 0.40000000596, 0.40000000596, 0.20000000298, 0.300000011921, 0.300000011921, 0.800000011921, 0.899999976158, 0.899999976158, 0.699999988079, 0.800000011921, 0.899999976158, 0.5, 0.300000011921, 0.600000023842, 0.5, 0.10000000149, 0.20000000298, 0.800000011921, 0.899999976158, 0.600000023842, 0.899999976158, 0.40000000596, 0.40000000596, 0.899999976158, 0.20000000298, 0.899999976158, 0.899999976158, 0.699999988079, 0.699999988079, 0.800000011921, 0.40000000596, 0.20000000298, 0.40000000596, 0.800000011921, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.40000000596, 0.300000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.300000011921, 0.699999988079, 0.20000000298, 0.5, 0.600000023842, 0.10000000149, 0.800000011921, 0.600000023842, 0.300000011921, 0.300000011921, 0.5, 0.300000011921, 0.20000000298, 0.600000023842, 0.5, 0.800000011921, 0.5, 0.899999976158, 0.800000011921, 0.600000023842, 0.800000011921, 0.5, 0.20000000298, 0.5, 0.40000000596, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.40000000596, 0.20000000298, 0.5, 0.5, 0.10000000149, 0.699999988079, 0.899999976158, 0.800000011921, 0.699999988079, 0.600000023842, 0.20000000298, 0.10000000149, 0.600000023842, 0.600000023842, 0.40000000596, 0.300000011921, 0.5, 0.899999976158, 0.699999988079, 0.5, 0.300000011921, 0.40000000596, 0.20000000298, 0.20000000298, 0.899999976158, 0.699999988079, 0.300000011921, 0.300000011921, 0.899999976158, 0.40000000596, 0.600000023842, 0.600000023842, 0.300000011921, 0.5, 0.699999988079, 0.800000011921, 0.600000023842, 0.40000000596, 0.899999976158, 0.899999976158, 0.20000000298, 0.600000023842, 0.699999988079, 0.5, 0.800000011921, 0.5, 0.899999976158, 0.20000000298, 0.699999988079, 0.300000011921, 0.10000000149, 0.20000000298, 0.899999976158, 0.20000000298, 0.20000000298, 0.600000023842, 0.300000011921, 0.699999988079, 0.699999988079, 0.699999988079, 0.300000011921, 0.5, 0.20000000298, 0.800000011921, 0.600000023842, 0.899999976158, 0.5, 0.40000000596, 0.699999988079, 0.300000011921, 0.300000011921, 0.20000000298, 0.899999976158, 0.20000000298, 0.899999976158, 0.699999988079, 0.699999988079, 0.10000000149, 0.699999988079, 0.600000023842, 0.600000023842, 0.5, 0.40000000596, 0.699999988079, 0.600000023842, 0.5, 0.699999988079, 0.600000023842, 0.600000023842, 0.40000000596, 0.10000000149, 0.899999976158, 0.40000000596, 0.10000000149, 0.800000011921, 0.899999976158, 0.300000011921, 0.5, 0.899999976158, 0.40000000596, 0.300000011921, 0.699999988079, 0.40000000596, 0.899999976158, 0.600000023842, 0.800000011921, 0.40000000596, 0.600000023842, 0.300000011921, 0.5, 0.40000000596, 0.300000011921, 0.800000011921, 0.899999976158, 0.5, 0.300000011921, 0.800000011921, 0.899999976158, 0.20000000298, 0.10000000149, 0.899999976158, 0.40000000596, 0.300000011921, 0.899999976158, 0.899999976158, 0.699999988079, 0.300000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.699999988079, 0.300000011921, 0.600000023842, 0.699999988079, 0.20000000298, 0.10000000149, 0.5, 0.699999988079, 0.699999988079, 0.699999988079, 0.5, 0.5, 0.20000000298, 0.20000000298, 0.899999976158, 0.5, 0.600000023842, 0.40000000596, 0.300000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.20000000298, 0.600000023842, 0.20000000298, 0.5, 0.40000000596, 0.20000000298, 0.899999976158, 0.40000000596, 0.300000011921, 0.20000000298, 0.899999976158, 0.10000000149, 0.800000011921, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.800000011921, 0.800000011921, 0.5, 0.600000023842, 0.20000000298, 0.20000000298, 0.20000000298, 0.699999988079, 0.300000011921, 0.20000000298, 0.5, 0.600000023842, 0.899999976158, 0.10000000149, 0.699999988079, 0.800000011921, 0.10000000149, 0.699999988079, 0.40000000596, 0.5, 0.300000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.10000000149, 0.800000011921, 0.899999976158, 0.300000011921, 0.699999988079, 0.699999988079, 0.10000000149, 0.10000000149, 0.699999988079, 0.20000000298, 0.600000023842, 0.20000000298, 0.40000000596, 0.899999976158, 0.699999988079, 0.5, 0.899999976158, 0.10000000149, 0.40000000596, 0.40000000596, 0.600000023842, 0.699999988079, 0.800000011921, 0.699999988079, 0.40000000596, 0.899999976158, 0.699999988079, 0.300000011921, 0.800000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.600000023842, 0.699999988079, 0.600000023842, 0.699999988079, 0.300000011921, 0.5, 0.899999976158, 0.600000023842, 0.20000000298, 0.5, 0.899999976158, 0.800000011921, 0.20000000298, 0.699999988079, 0.40000000596, 0.20000000298, 0.600000023842, 0.40000000596, 0.600000023842, 0.300000011921, 0.899999976158, 0.10000000149, 0.20000000298, 0.20000000298, 0.699999988079, 0.699999988079, 0.699999988079, 0.10000000149, 0.10000000149, 0.800000011921, 0.5, 0.899999976158, 0.600000023842, 0.600000023842, 0.899999976158, 0.40000000596, 0.899999976158, 0.10000000149, 0.20000000298, 0.600000023842, 0.899999976158, 0.899999976158, 0.699999988079, 0.800000011921, 0.600000023842, 0.600000023842, 0.5, 0.800000011921, 0.300000011921, 0.40000000596, 0.800000011921, 0.10000000149, 0.10000000149, 0.899999976158, 0.5, 0.300000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.5, 0.699999988079, 0.40000000596, 0.20000000298, 0.5, 0.600000023842, 0.899999976158, 0.800000011921, 0.600000023842, 0.800000011921, 0.800000011921, 0.10000000149, 0.800000011921, 0.800000011921, 0.40000000596, 0.600000023842, 0.800000011921, 0.20000000298, 0.899999976158, 0.899999976158, 0.20000000298, 0.10000000149, 0.699999988079, 0.600000023842, 0.40000000596, 0.699999988079, 0.300000011921, 0.10000000149, 0.5, 0.300000011921, 0.40000000596, 0.899999976158, 0.800000011921, 0.20000000298, 0.20000000298, 0.899999976158, 0.5, 0.300000011921, 0.800000011921, 0.699999988079, 0.800000011921, 0.699999988079, 0.5, 0.40000000596, 0.40000000596, 0.699999988079, 
+
+L3_cSYR2K_o_T
+1.22000005275, 15.4400001681, -0.509999865443, 17.0800001968, 2.36999992535, 16.5100001806, 1.20000006333, 16.6700001697, 1.30000008121, 16.4700001027, 2.79000000492, 17.7300002088, 1.34000004664, 18.4100000644, 1.730000211, 16.4800001588, -0.0699999022484, 15.1300001179, 0.0600001001358, 16.6600002961, 1.43000004187, 16.8800001059, 0.490000062287, 16.9500001684, 2.08000002325, 14.8600002074, -0.379999884665, 16.7800001097, 0.500000003725, 17.0500001132, 1.98000019312, 19.5400001651, 1.06000005022, 16.4600000502, -0.509999865443, 17.0800001968, -2.22000001401, 17.9800001112, -0.520000070632, 19.4800000732, -1.68999990359, 18.0800001059, -1.30999996603, 17.6400000779, 0.0199999335408, 19.3900001755, -1.8100000599, 18.4100001098, -0.819999798685, 18.6900000973, -2.72999991447, 18.3500000946, -2.22999996811, 17.5500002272, -0.199999958277, 17.1700001779, -2.83999988571, 18.1800001559, 0.759999995083, 15.4100001143, -2.98999989912, 18.3500000976, -2.34000000194, 18.3500001669, -0.769999940991, 21.00000007, -0.889999948293, 17.9300000434, 2.36999992535, 16.5100001806, -0.520000070632, 19.4800000732, 1.68000001878, 17.9800002736, 1.3100000152, 17.4100001687, 0.209999983162, 17.3400001204, 1.75999992505, 19.4100001523, -0.130000067949, 16.780000205, 1.71000004947, 18.1100001746, 0.850000056624, 17.8000001043, 1.18999998331, 16.5000002913, 1.09999995306, 17.110000127, 0.200000044703, 18.64000011, 2.34000000864, 16.2500001259, -0.48999997437, 17.7000001408, 0.879999867529, 17.3200001839, 1.81999998793, 19.8500000969, 1.71000004798, 17.6199999902, 1.20000006333, 16.6700001697, -1.68999990359, 18.0800001059, 1.3100000152, 17.4100001687, 1.22000002444, 17.6000001162, -0.21999992609, 16.0600001448, 1.15000005588, 18.990000136, -0.519999950677, 19.560000001, 0.930000178963, 16.4200000758, -1.05999983117, 16.9100000785, -1.33999989986, 16.2400002195, 0.370000127256, 16.8300001216, -2.51999988362, 19.1200000602, 1.84999997914, 14.5500001028, -0.779999931604, 18.2600000279, 0.299999913573, 16.9900001256, -0.00999989748001, 19.4400001696, 0.310000076294, 17.029999951, 1.30000008121, 16.4700001027, -1.30999996603, 17.6400000779, 0.209999983162, 17.3400001204, -0.21999992609, 16.0600001448, -1.31999990374, 17.6999999866, 0.740000051856, 18.4300001283, -8.9406961834e-09, 17.5900000258, 1.62000012055, 17.9899999885, 0.29000004217, 16.2700000952, -0.149999985844, 16.070000201, 0.34000003472, 16.6300001074, -0.639999947548, 17.7300001231, 2.29999995604, 15.0599999839, -2.03999987453, 18.1900000288, 0.569999973029, 16.380000176, -0.0599999593198, 18.5300001104, 0.790000003427, 16.8699999708, 2.79000000492, 17.7300002088, 0.0199999335408, 19.3900001755, 1.75999992505, 19.4100001523, 1.15000005588, 18.990000136, 0.740000051856, 18.4300001283, 1.54000006229, 19.3600001955, 0.360000003278, 18.6400002255, 2.31000016347, 18.7000001453, -0.309999911636, 18.4100000443, 0.850000028312, 17.6700003597, 2.47000000954, 16.7000002481, 0.400000128895, 18.2000001714, 3.13999989837, 15.610000162, -0.959999958575, 19.040000069, -2.23517417908e-08, 18.7500001788, 2.46000001073, 20.5300002177, 2.39999989346, 19.6900000466, 1.34000004664, 18.4100000644, -1.8100000599, 18.4100001098, -0.130000067949, 16.780000205, -0.519999950677, 19.560000001, -8.9406961834e-09, 17.5900000258, 0.360000003278, 18.6400002255, -1.72000004381, 19.280000056, 0.300000147521, 18.2800000747, -1.05999995783, 17.000000079, -1.34999995157, 17.210000194, 0.449999964982, 16.7000000849, -1.45000008419, 18.3200001138, 0.789999998957, 15.9500000551, -1.17000004977, 17.6300000665, -0.990000051856, 18.300000082, -1.25999997273, 20.2200000237, -0.820000018477, 18.0699998963, 1.730000211, 16.4800001588, -0.819999798685, 18.6900000973, 1.71000004947, 18.1100001746, 0.930000178963, 16.4200000758, 1.62000012055, 17.9899999885, 2.31000016347, 18.7000001453, 0.300000147521, 18.2800000747, 3.72000023305, 19.120000011, 0.530000184178, 16.540000174, 0.990000150949, 16.920000236, 1.77000007659, 17.1400000988, 0.520000198781, 17.1000001274, 3.07000006914, 14.9200001019, 0.200000292063, 18.300000044, 1.69000015989, 17.620000122, 2.32000020623, 19.1300001194, 3.09999999553, 17.2000000104, -0.0699999022484, 15.1300001179, -2.72999991447, 18.3500000946, 0.850000056624, 17.8000001043, -1.05999983117, 16.9100000785, 0.29000004217, 16.2700000952, -0.309999911636, 18.4100000443, -1.05999995783, 17.000000079, 0.530000184178, 16.540000174, -2.81999984562, 16.1399999878, 0.290000128597, 15.3800002542, 0.240000074953, 15.0700001682, -1.00999985278, 17.6200000125, 1.20000000447, 16.0399999818, -1.92999989286, 16.9500000395, -0.470000005811, 17.6000000566, 0.600000137836, 19.1900000526, -0.0699998754263, 16.859999963, 0.0600001001358, 16.6600002961, -2.22999996811, 17.5500002272, 1.18999998331, 16.5000002913, -1.33999989986, 16.2400002195, -0.149999985844, 16.070000201, 0.850000028312, 17.6700003597, -1.34999995157, 17.210000194, 0.990000150949, 16.920000236, 0.290000128597, 15.3800002542, -0.459999933243, 16.2800003749, 1.92999996364, 15.0800002326, -0.869999902993, 17.090000256, 1.02000011086, 15.0500001572, -1.96999997526, 16.6800002371, -0.639999966174, 16.2300002691, 1.3199999328, 18.5300002185, 0.639999983311, 17.690000075, 1.43000004187, 16.8800001059, -0.199999958277, 17.1700001779, 1.09999995306, 17.110000127, 0.370000127256, 16.8300001216, 0.34000003472, 16.6300001074, 2.47000000954, 16.7000002481, 0.449999964982, 16.7000000849, 1.77000007659, 17.1400000988, 0.240000074953, 15.0700001682, 1.92999996364, 15.0800002326, 0.8199999246, 16.2200001884, -0.0399999661744, 17.060000194, 1.99999991283, 14.930000129, 2.2351743123e-08, 17.8800001074, -0.520000060946, 16.5000001632, 2.45000001192, 18.6400001755, 2.25999996305, 16.1499999732, 0.490000062287, 16.9500001684, -2.83999988571, 18.1800001559, 0.200000044703, 18.64000011, -2.51999988362, 19.1200000602, -0.639999947548, 17.7300001231, 0.400000128895, 18.2000001714, -1.45000008419, 18.3200001138, 0.520000198781, 17.1000001274, -1.00999985278, 17.6200000125, -0.869999902993, 17.090000256, -0.0399999661744, 17.060000194, -0.479999893606, 17.960000115, 1.77000001624, 15.3900001465, -2.14999997318, 18.6100000472, -0.419999999106, 18.6600001471, -0.659999839365, 20.0500001319, -0.989999946803, 18.7799999912, 2.08000002325, 14.8600002074, 0.759999995083, 15.4100001143, 2.34000000864, 16.2500001259, 1.84999997914, 14.5500001028, 2.29999995604, 15.0599999839, 3.13999989837, 15.610000162, 0.789999998957, 15.9500000551, 3.07000006914, 14.9200001019, 1.20000000447, 16.0399999818, 1.02000011086, 15.0500001572, 1.99999991283, 14.930000129, 1.77000001624, 15.3900001465, 3.0599999705, 15.3400000504, 0.48999997288, 15.9300000151, 1.48999998033, 15.9500001267, 2.64000005856, 16.9100000554, 2.94999992028, 15.7499999575, -0.379999884665, 16.7800001097, -2.98999989912, 18.3500000976, -0.48999997437, 17.7000001408, -0.779999931604, 18.2600000279, -2.03999987453, 18.1900000288, -0.959999958575, 19.040000069, -1.17000004977, 17.6300000665, 0.200000292063, 18.300000044, -1.92999989286, 16.9500000395, -1.96999997526, 16.6800002371, 2.2351743123e-08, 17.8800001074, -2.14999997318, 18.6100000472, 0.48999997288, 15.9300000151, -2.93999978065, 17.880000065, -1.21999996409, 17.3700001764, -0.22999995023, 19.8500000782, -0.829999937564, 18.0299998936, 0.500000003725, 17.0500001132, -2.34000000194, 18.3500001669, 0.879999867529, 17.3200001839, 0.299999913573, 16.9900001256, 0.569999973029, 16.380000176, -2.23517417908e-08, 18.7500001788, -0.990000051856, 18.300000082, 1.69000015989, 17.620000122, -0.470000005811, 17.6000000566, -0.639999966174, 16.2300002691, -0.520000060946, 16.5000001632, -0.419999999106, 18.6600001471, 1.48999998033, 15.9500001267, -1.21999996409, 17.3700001764, -0.0600001075864, 18.3800001216, 0.500000043958, 20.4100000875, -0.289999987036, 16.9700000468, 1.98000019312, 19.5400001651, -0.769999940991, 21.00000007, 1.81999998793, 19.8500000969, -0.00999989748001, 19.4400001696, -0.0599999593198, 18.5300001104, 2.46000001073, 20.5300002177, -1.25999997273, 20.2200000237, 2.32000020623, 19.1300001194, 0.600000137836, 19.1900000526, 1.3199999328, 18.5300002185, 2.45000001192, 18.6400001755, -0.659999839365, 20.0500001319, 2.64000005856, 16.9100000554, -0.22999995023, 19.8500000782, 0.500000043958, 20.4100000875, 1.8399999401, 23.1600000033, 2.55999991685, 20.7199999022, 1.06000005022, 16.4600000502, -0.889999948293, 17.9300000434, 1.71000004798, 17.6199999902, 0.310000076294, 17.029999951, 0.790000003427, 16.8699999708, 2.39999989346, 19.6900000466, -0.820000018477, 18.0699998963, 3.09999999553, 17.2000000104, -0.0699998754263, 16.859999963, 0.639999983311, 17.690000075, 2.25999996305, 16.1499999732, -0.989999946803, 18.7799999912, 2.94999992028, 15.7499999575, -0.829999937564, 18.0299998936, -0.289999987036, 16.9700000468, 2.55999991685, 20.7199999022, 0.679999991953, 18.0799997923, 
+
+L3_zSYR2K_A_nk
+0.7, 0.6, 0.3, 0.5, 0.4, 0.8, 0.6, 0.8, 0.9, 0.9, 0.5, 0.8, 0.7, 0.8, 0.7, 0.4, 0.2, 0.1, 0.8, 0.3, 0.6, 0.8, 0.8, 0.1, 0.8, 0.8, 0.5, 0.8, 0.8, 0.4, 0.2, 0.9, 0.5, 0.6, 0.8, 0.8, 0.7, 0.8, 0.1, 0.1, 0.6, 0.3, 0.8, 0.2, 0.6, 0.2, 0.6, 0.8, 0.8, 0.3, 0.9, 0.6, 0.4, 0.8, 0.8, 0.5, 0.8, 0.7, 0.7, 0.9, 0.5, 0.9, 0.8, 0.5, 0.4, 0.1, 0.3, 0.2, 0.4, 0.9, 0.5, 0.6, 0.3, 0.5, 0.3, 0.8, 0.9, 0.1, 0.8, 0.4, 0.9, 0.8, 0.2, 0.9, 0.5, 0.7, 0.2, 0.5, 0.6, 0.2, 0.1, 0.7, 0.6, 0.6, 0.8, 0.7, 0.7, 0.4, 0.4, 0.8, 0.1, 0.5, 0.7, 0.7, 0.1, 0.5, 0.8, 0.4, 0.2, 0.6, 0.3, 0.5, 0.7, 0.4, 0.2, 0.1, 0.7, 0.7, 0.1, 0.3, 0.7, 0.7, 0.8, 0.3, 0.1, 0.9, 0.3, 0.6, 0.3, 0.5, 0.8, 0.7, 0.4, 0.2, 0.4, 0.7, 0.8, 0.5, 0.5, 0.8, 0.3, 0.4, 0.2, 0.1, 0.3, 0.1, 0.6, 0.5, 0.7, 0.1, 0.3, 0.2, 0.2, 0.3, 0.9, 0.4, 0.6, 0.8, 0.7, 0.8, 0.5, 0.2, 0.9, 0.9, 0.6, 0.2, 0.1, 0.9, 0.9, 0.3, 0.8, 0.8, 0.6, 0.8, 0.8, 0.2, 0.1, 0.2, 0.2, 0.2, 0.2, 0.2, 0.6, 0.1, 0.4, 0.5, 0.6, 0.9, 0.1, 0.6, 0.2, 0.2, 0.7, 0.6, 0.5, 0.8, 0.3, 0.2, 0.2, 0.2, 0.9, 0.6, 0.5, 0.9, 0.4, 0.6, 0.4, 0.3, 0.9, 0.6, 0.4, 0.7, 0.8, 0.5, 0.7, 0.7, 0.5, 0.7, 0.4, 0.1, 0.7, 0.6, 0.6, 0.6, 0.2, 0.9, 0.9, 0.5, 0.2, 0.2, 0.4, 0.5, 0.2, 0.7, 0.2, 0.5, 0.3, 0.4, 0.6, 0.3, 0.6, 0.8, 0.6, 0.9, 0.5, 0.7, 0.6, 0.8, 0.1, 0.4, 0.8, 0.5, 0.2, 0.1, 0.7, 0.1, 0.6, 0.1, 0.2, 0.3, 0.3, 0.2, 0.5, 0.9, 0.3, 0.8, 0.8, 0.9, 0.2, 0.1, 0.3, 0.4, 0.3, 0.5, 0.3, 0.4, 0.7, 0.6, 0.5, 0.4, 0.7, 0.7, 0.5, 0.5, 0.7, 0.6, 0.9, 0.8, 0.7, 0.1, 0.2, 0.5, 0.7, 0.1, 0.3, 0.4, 0.3, 0.3, 0.4, 0.6, 0.3, 0.4, 0.1, 0.9, 0.4, 0.3, 0.1, 0.8, 0.1, 0.1, 0.6, 0.2, 0.4, 0.2, 0.2, 0.7, 0.9, 0.7, 0.5, 0.8, 0.4, 0.6, 0.2, 0.8, 0.7, 0.5, 0.6, 0.7, 0.2, 0.3, 0.2, 0.2, 0.8, 0.3, 0.6, 0.9, 0.3, 0.4, 0.5, 0.4, 0.8, 0.7, 0.5, 0.3, 0.1, 0.5, 0.8, 0.4, 0.1, 0.7, 0.1, 0.6, 0.2, 0.9, 0.3, 0.3, 0.1, 0.1, 0.9, 0.6, 0.2, 0.9, 0.6, 0.8, 0.6, 0.3, 0.4, 0.3, 0.8, 0.5, 0.5, 0.7, 0.9, 0.7, 0.6, 0.5, 0.4, 0.5, 0.8, 0.4, 0.3, 0.5, 0.9, 0.7, 0.9, 0.1, 0.5, 0.7, 0.9, 0.9, 0.2, 0.3, 0.9, 0.6, 0.1, 0.2, 0.7, 0.2, 0.1, 0.8, 0.3, 0.1, 0.9, 0.7, 0.5, 0.4, 0.5, 0.6, 0.1, 0.9, 0.1, 0.2, 0.7, 0.2, 0.2, 0.5, 0.1, 0.5, 0.4, 0.9, 0.1, 0.3, 0.1, 0.8, 0.9, 0.4, 0.2, 0.3, 0.6, 0.7, 0.2, 0.9, 0.1, 0.4, 0.4, 0.5, 0.7, 0.1, 0.9, 0.8, 0.2, 0.3, 0.9, 0.7, 0.8, 0.5, 0.2, 0.2, 0.2, 0.7, 0.9, 0.6, 0.6, 0.6, 0.1, 0.7, 0.1, 0.4, 0.8, 0.3, 0.7, 0.7, 0.5, 0.1, 0.7, 0.3, 0.9, 0.5, 0.5, 0.2, 0.5, 0.1, 0.4, 0.6, 0.8, 0.3, 0.5, 0.2, 0.5, 0.2, 0.6, 0.7, 0.3, 0.8, 0.7, 0.2, 0.3, 0.6, 0.6, 0.1, 0.7, 0.1, 0.5, 0.7, 0.7, 0.6, 0.3, 0.7, 0.2, 0.9, 0.3, 0.5, 0.5, 0.1, 0.8, 0.7, 0.2, 0.5, 0.2, 0.1, 0.8, 0.4, 0.8, 0.7, 0.2, 0.1, 0.5, 0.5, 0.6, 0.2, 0.7, 0.7, 0.1, 0.1, 0.1, 0.7, 0.6, 0.3, 0.4, 0.9, 0.6, 0.3, 0.1, 0.3, 0.1, 0.3, 0.9, 0.8, 0.7, 0.5, 0.9, 0.3, 0.7, 0.4, 
+
+L3_zSYR2K_B_nk
+0.5, 0.6, 0.2, 0.8, 0.6, 0.8, 0.2, 0.7, 0.2, 0.6, 0.6, 0.7, 0.9, 0.3, 0.6, 0.2, 0.4, 0.3, 0.2, 0.2, 0.9, 0.8, 0.4, 0.7, 0.7, 0.7, 0.5, 0.6, 0.8, 0.6, 0.9, 0.7, 0.4, 0.9, 0.4, 0.9, 0.9, 0.7, 0.1, 0.4, 0.9, 0.7, 0.8, 0.8, 0.2, 0.9, 0.2, 0.6, 0.6, 0.7, 0.5, 0.9, 0.1, 0.2, 0.8, 0.8, 0.5, 0.3, 0.5, 0.1, 0.5, 0.4, 0.2, 0.5, 0.7, 0.2, 0.9, 0.6, 0.4, 0.4, 0.1, 0.7, 0.3, 0.7, 0.5, 0.1, 0.7, 0.3, 0.9, 0.6, 0.9, 0.7, 0.9, 0.8, 0.6, 0.9, 0.4, 0.7, 0.6, 0.8, 0.8, 0.3, 0.6, 0.4, 0.4, 0.3, 0.4, 0.7, 0.1, 0.1, 0.5, 0.8, 0.3, 0.9, 0.4, 0.7, 0.4, 0.9, 0.8, 0.3, 0.7, 0.8, 0.3, 0.9, 0.3, 0.3, 0.8, 0.8, 0.7, 0.5, 0.8, 0.1, 0.2, 0.3, 0.7, 0.6, 0.1, 0.8, 0.8, 0.7, 0.1, 0.5, 0.3, 0.4, 0.8, 0.8, 0.8, 0.9, 0.5, 0.5, 0.8, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.1, 0.8, 0.1, 0.7, 0.5, 0.3, 0.9, 0.8, 0.9, 0.7, 0.3, 0.8, 0.5, 0.8, 0.6, 0.7, 0.3, 0.4, 0.3, 0.8, 0.7, 0.2, 0.2, 0.4, 0.1, 0.4, 0.3, 0.7, 0.7, 0.8, 0.9, 0.7, 0.4, 0.6, 0.1, 0.3, 0.5, 0.4, 0.4, 0.1, 0.2, 0.9, 0.5, 0.5, 0.2, 0.2, 0.9, 0.7, 0.6, 0.7, 0.5, 0.6, 0.3, 0.6, 0.4, 0.5, 0.5, 0.4, 0.7, 0.4, 0.4, 0.3, 0.5, 0.4, 0.2, 0.1, 0.5, 0.9, 0.9, 0.2, 0.5, 0.8, 0.2, 0.5, 0.4, 0.8, 0.9, 0.3, 0.5, 0.4, 0.2, 0.2, 0.1, 0.8, 0.3, 0.9, 0.1, 0.3, 0.2, 0.1, 0.3, 0.8, 0.3, 0.3, 0.7, 0.6, 0.7, 0.8, 0.2, 0.9, 0.6, 0.9, 0.3, 0.5, 0.7, 0.9, 0.1, 0.9, 0.9, 0.4, 0.7, 0.3, 0.1, 0.1, 0.7, 0.8, 0.5, 0.7, 0.6, 0.1, 0.5, 0.1, 0.3, 0.8, 0.8, 0.5, 0.1, 0.4, 0.8, 0.6, 0.9, 0.6, 0.4, 0.2, 0.2, 0.1, 0.7, 0.9, 0.5, 0.7, 0.4, 0.1, 0.7, 0.4, 0.3, 0.8, 0.8, 0.2, 0.9, 0.9, 0.8, 0.9, 0.2, 0.5, 0.6, 0.2, 0.2, 0.2, 0.2, 0.1, 0.8, 0.6, 0.2, 0.6, 0.4, 0.2, 0.3, 0.2, 0.3, 0.2, 0.6, 0.4, 0.2, 0.6, 0.4, 0.8, 0.7, 0.8, 0.5, 0.2, 0.9, 0.6, 0.1, 0.3, 0.2, 0.1, 0.8, 0.3, 0.6, 0.5, 0.5, 0.8, 0.3, 0.9, 0.8, 0.9, 0.7, 0.8, 0.6, 0.5, 0.9, 0.9, 0.5, 0.5, 0.4, 0.1, 0.2, 0.3, 0.1, 0.8, 0.6, 0.8, 0.9, 0.1, 0.7, 0.6, 0.7, 0.7, 0.9, 0.5, 0.6, 0.8, 0.1, 0.2, 0.7, 0.3, 0.9, 0.7, 0.5, 0.9, 0.2, 0.8, 0.2, 0.5, 0.2, 0.8, 0.5, 0.1, 0.2, 0.3, 0.2, 0.2, 0.2, 0.1, 0.5, 0.7, 0.2, 0.4, 0.3, 0.6, 0.9, 0.1, 0.9, 0.6, 0.2, 0.8, 0.9, 0.3, 0.2, 0.6, 0.8, 0.5, 0.5, 0.3, 0.4, 0.4, 0.1, 0.4, 0.4, 0.9, 0.2, 0.6, 0.5, 0.5, 0.1, 0.9, 0.1, 0.1, 0.2, 0.1, 0.2, 0.4, 0.9, 0.1, 0.6, 0.1, 0.2, 0.6, 0.5, 0.9, 0.2, 0.5, 0.9, 0.4, 0.8, 0.1, 0.8, 0.5, 0.8, 0.8, 0.5, 0.1, 0.3, 0.8, 0.9, 0.4, 0.2, 0.9, 0.9, 0.7, 0.7, 0.4, 0.1, 0.8, 0.8, 0.1, 0.6, 0.3, 0.5, 0.3, 0.7, 0.5, 0.8, 0.4, 0.1, 0.6, 0.4, 0.3, 0.8, 0.2, 0.1, 0.2, 0.8, 0.9, 0.6, 0.6, 0.8, 0.6, 0.4, 0.1, 0.5, 0.4, 0.1, 0.7, 0.3, 0.5, 0.5, 0.5, 0.6, 0.2, 0.6, 0.4, 0.5, 0.8, 0.3, 0.3, 0.9, 0.4, 0.1, 0.8, 0.5, 0.7, 0.3, 0.6, 0.8, 0.6, 0.1, 0.4, 0.9, 0.3, 0.3, 0.1, 0.5, 0.5, 0.2, 0.9, 0.5, 0.7, 0.4, 0.5, 0.9, 0.3, 0.6, 0.8, 0.1, 0.2, 0.2, 0.5, 0.2, 0.9, 0.5, 0.8, 0.8, 0.2, 0.7, 0.2, 0.3, 
+
+L3_zSYR2K_C_nn
+0.6, 0.1, 0.6, 0.9, 0.4, 0.3, 0.4, 0.1, 0.6, 0.2, 0.6, 0.3, 0.3, 0.2, 0.4, 0.6, 0.7, 0.6, 0.5, 0.6, 0.6, 0.1, 0.7, 0.1, 0.8, 0.2, 0.7, 0.9, 0.8, 0.6, 0.9, 0.9, 0.5, 0.2, 0.6, 0.9, 0.5, 0.3, 0.6, 0.4, 0.4, 0.2, 0.4, 0.8, 0.1, 0.5, 0.1, 0.8, 0.4, 0.2, 0.1, 0.4, 0.5, 0.7, 0.6, 0.4, 0.9, 0.5, 0.9, 0.2, 0.6, 0.2, 0.6, 0.9, 0.6, 0.6, 0.7, 0.4, 0.4, 0.3, 0.6, 0.4, 0.4, 0.5, 0.8, 0.8, 0.8, 0.3, 0.4, 0.3, 0.1, 0.7, 0.3, 0.1, 0.1, 0.9, 0.1, 0.3, 0.3, 0.1, 0.7, 0.6, 0.6, 0.5, 0.5, 0.1, 0.9, 0.2, 0.6, 0.9, 0.3, 0.4, 0.4, 0.1, 0.4, 0.2, 0.8, 0.8, 0.5, 0.5, 0.7, 0.9, 0.3, 0.3, 0.7, 0.9, 0.9, 0.2, 0.3, 0.7, 0.7, 0.1, 0.2, 0.4, 0.6, 0.6, 0.4, 0.3, 0.1, 0.8, 0.1, 0.6, 0.5, 0.2, 0.7, 0.7, 0.6, 0.2, 0.4, 0.8, 0.8, 0.3, 0.7, 0.9, 0.2, 0.3, 0.8, 0.1, 0.7, 0.7, 0.8, 0.1, 0.1, 0.6, 0.7, 0.7, 0.9, 0.1, 0.3, 0.8, 0.7, 0.1, 0.4, 0.3, 0.1, 0.1, 0.9, 0.3, 0.5, 0.1, 0.6, 0.3, 0.1, 0.5, 0.4, 0.3, 0.3, 0.3, 0.8, 0.1, 0.3, 0.5, 0.3, 0.4, 0.3, 0.2, 0.8, 0.7, 0.1, 0.2, 0.9, 0.1, 0.3, 0.7, 0.4, 0.2, 0.2, 0.9, 0.8, 0.5, 0.2, 0.1, 0.3, 0.2, 0.3, 0.2, 0.1, 0.8, 0.1, 0.7, 0.7, 0.9, 0.7, 0.7, 0.3, 0.4, 0.4, 0.2, 0.6, 0.5, 0.2, 0.2, 0.8, 0.2, 0.1, 0.5, 0.1, 0.4, 0.5, 0.3, 0.7, 0.4, 0.1, 0.9, 0.9, 0.7, 0.6, 0.9, 0.4, 0.6, 0.4, 0.2, 0.3, 0.1, 0.9, 0.2, 0.8, 0.1, 0.3, 0.2, 0.6, 0.5, 0.7, 0.9, 0.8, 0.6, 0.3, 0.4, 0.1, 0.3, 0.3, 0.2, 0.1, 0.2, 0.6, 0.7, 0.1, 0.6, 0.3, 0.9, 0.2, 0.2, 0.7, 0.6, 0.1, 0.4, 0.1, 0.9, 0.3, 0.7, 0.1, 0.6, 0.8, 0.7, 0.2, 0.2, 0.8, 0.6, 0.9, 0.6, 0.6, 0.6, 0.9, 0.9, 0.6, 0.9, 0.8, 0.2, 0.7, 0.9, 0.1, 0.3, 0.5, 0.2, 0.6, 0.1, 0.5, 0.6, 0.5, 0.7, 0.1, 0.3, 0.7, 0.1, 0.7, 0.7, 0.1, 0.2, 0.8, 0.2, 0.3, 0.4, 0.6, 0.6, 0.7, 0.4, 0.9, 0.4, 0.2, 0.6, 0.2, 0.5, 0.2, 0.1, 0.5, 0.2, 0.5, 0.8, 0.9, 0.7, 0.6, 0.1, 0.6, 0.4, 0.3, 0.1, 0.2, 0.4, 0.9, 0.1, 0.9, 0.1, 0.1, 0.5, 0.1, 0.3, 0.9, 0.9, 0.9, 0.4, 0.8, 0.2, 0.2, 0.8, 0.7, 0.1, 0.2, 0.9, 0.4, 0.7, 0.2, 0.8, 0.2, 0.8, 0.7, 0.1, 0.9, 0.5, 0.7, 0.6, 0.6, 0.6, 0.3, 0.8, 0.3, 0.7, 0.1, 0.4, 0.3, 0.2, 0.6, 0.9, 0.2, 0.6, 0.2, 0.8, 0.4, 0.8, 0.7, 0.6, 0.3, 0.4, 0.9, 0.4, 0.8, 0.2, 0.8, 0.2, 0.8, 0.2, 0.9, 0.2, 0.6, 0.5, 0.4, 0.3, 0.7, 0.1, 0.4, 0.2, 0.5, 0.3, 0.1, 0.2, 0.8, 0.2, 0.2, 0.5, 0.7, 0.1, 0.7, 0.6, 0.1, 0.2, 0.7, 0.4, 0.4, 0.4, 0.8, 0.2, 0.1, 0.9, 0.7, 0.9, 0.6, 0.2, 0.5, 0.1, 0.1, 0.8, 0.4, 0.3, 0.2, 0.9, 0.7, 0.4, 0.6, 0.7, 0.7, 0.9, 0.2, 0.1, 0.2, 0.9, 0.3, 0.4, 0.7, 0.4, 0.8, 0.1, 0.3, 0.5, 0.9, 0.8, 0.4, 0.3, 0.8, 0.6, 0.6, 0.9, 0.9, 0.2, 0.1, 0.6, 0.1, 0.1, 0.8, 0.5, 0.1, 0.9, 0.1, 0.6, 0.1, 0.3, 0.5, 0.2, 0.4, 0.7, 0.9, 0.4, 0.4, 0.4, 0.3, 0.5, 0.7, 0.6, 0.9, 0.1, 0.6, 0.5, 0.9, 0.9, 0.6, 0.6, 0.6, 0.9, 0.5, 0.2, 0.9, 0.3, 0.2, 0.1, 0.9, 0.7, 0.3, 0.9, 0.5, 0.2, 0.5, 0.8, 0.2, 0.8, 0.8, 0.2, 0.8, 0.2, 0.9, 0.8, 0.9, 0.1, 0.5, 0.4, 0.2, 0.4, 0.5, 0.2, 0.7, 0.4, 0.3, 0.4, 0.7, 0.7, 0.5, 0.1, 0.3, 0.2, 0.6, 0.9, 0.2, 0.2, 0.6, 0.1, 0.9, 0.7, 0.2, 0.8, 0.8, 0.2, 0.1, 0.9, 0.4, 0.3, 0.6, 0.5, 0.2, 0.4, 0.3, 0.8, 
+
+L3_zSYR2K_o_N
+-1.52, 22.08, -0.2, 22.21, 0.8, 19.83, -1.98, 19.01, 0.75, 19.53, 1.84, 17.26, -0.4, 19.89, 1.94, 17.78, -0.36, 19.16, -0.56, 17.55, -0.15, 19.17, -0.06, 20.14, 0.33, 16.49, -0.09, 18.49, 0.19, 18.35, 1.92, 19.23, 1.58, 17.62, -0.2, 22.21, 0.98, 22.08, 0.5, 20.97, -1.73, 17.81, 0.96, 18.47, 1.94, 17.73, -0.44, 20.74, 0.68, 18.57, -1.43, 17.84, -0.11, 15.59, -0.08, 19.41, 0.91, 19.08, 1.18, 17.22, -1.38, 17.3, 0.13, 18.37, 0.73, 18.97, 1.32, 17.52, 0.8, 19.83, 0.5, 20.97, 0.68, 19.0, -1.19, 18.01, 2.83, 16.59, 2.89, 16.54, 0.37, 19.93, 1.28, 17.61, -0.95, 17.01, -1.13, 15.01, -0.41, 18.75, 1.23, 19.3, 0.28, 16.13, 0.19, 16.77, 2.18, 16.44, 0.44, 18.41, 1.03, 16.8, -1.98, 19.01, -1.73, 17.81, -1.19, 18.01, -3.36, 17.22, -0.35, 16.86, 0.52, 15.28, -1.36, 18.12, -0.02, 16.11, -2.5, 16.84, -1.78, 13.19, -2.4, 17.58, -1.12, 17.81, -0.78, 14.08, -1.7, 15.27, -1.23, 16.18, 0.08, 16.12, -0.28, 15.92, 0.75, 19.53, 0.96, 18.47, 2.83, 16.59, -0.35, 16.86, 2.08, 16.74, 2.55, 14.95, 2.43, 17.42, 2.85, 15.38, 0.73, 17.0, 1.09, 14.32, 2.47, 16.15, 1.64, 17.8, 1.94, 12.9, 1.21, 15.53, 0.7, 15.34, 2.82, 15.9, 2.02, 15.69, 1.84, 17.26, 1.94, 17.73, 2.89, 16.54, 0.52, 15.28, 2.55, 14.95, 2.16, 13.48, 2.55, 16.75, 2.46, 14.12, 1.62, 14.69, 1.1, 13.12, 0.82, 15.58, 1.9, 16.97, 1.82, 13.03, -1.05, 14.64, 2.02, 15.25, 1.61, 15.22, 2.07, 14.84, -0.4, 19.89, -0.44, 20.74, 0.37, 19.93, -1.36, 18.12, 2.43, 17.42, 2.55, 16.75, -0.72, 18.5, 2.38, 16.82, 0.34, 17.08, 0.6, 15.36, 0.41, 18.04, 0.2, 17.73, 0.55, 15.64, 0.07, 16.51, 0.49, 16.96, 1.41, 17.46, 1.24, 16.48, 1.94, 17.78, 0.68, 18.57, 1.28, 17.61, -0.02, 16.11, 2.85, 15.38, 2.46, 14.12, 2.38, 16.82, 2.36, 17.12, 1.71, 16.61, -0.53, 13.38, 0.55, 17.6, 1.89, 16.97, 0.82, 14.57, 1.68, 15.65, 0.91, 15.76, 1.22, 16.46, 2.67, 15.42, -0.36, 19.16, -1.43, 17.84, -0.95, 17.01, -2.5, 16.84, 0.73, 17.0, 1.62, 14.69, 0.34, 17.08, 1.71, 16.61, 0.04, 17.06, -0.71, 14.02, -0.2, 18.15, 0.18, 18.07, 0.09, 14.17, 0.28, 15.86, -1.1, 14.84, 0.85, 15.17, 1.26, 14.64, -0.56, 17.55, -0.11, 15.59, -1.13, 15.01, -1.78, 13.19, 1.09, 14.32, 1.1, 13.12, 0.6, 15.36, -0.53, 13.38, -0.71, 14.02, -0.32, 11.72, 0.02, 13.93, -0.6, 14.44, -1.08, 13.29, -1.39, 12.26, -1.29, 11.71, 0.18, 13.44, -0.8, 13.78, -0.15, 19.17, -0.08, 19.41, -0.41, 18.75, -2.4, 17.58, 2.47, 16.15, 0.82, 15.58, 0.41, 18.04, 0.55, 17.6, -0.2, 18.15, 0.02, 13.93, -1.22, 19.08, 0.42, 19.65, 0.77, 15.04, -0.87, 17.03, 0.3, 16.93, -0.45, 17.13, 0.56, 15.81, -0.06, 20.14, 0.91, 19.08, 1.23, 19.3, -1.12, 17.81, 1.64, 17.8, 1.9, 16.97, 0.2, 17.73, 1.89, 16.97, 0.18, 18.07, -0.6, 14.44, 0.42, 19.65, 1.82, 18.64, 0.22, 16.22, 0.23, 16.81, 1.67, 16.95, 1.87, 17.41, 2.58, 16.03, 0.33, 16.49, 1.18, 17.22, 0.28, 16.13, -0.78, 14.08, 1.94, 12.9, 1.82, 13.03, 0.55, 15.64, 0.82, 14.57, 0.09, 14.17, -1.08, 13.29, 0.77, 15.04, 0.22, 16.22, -0.3, 12.44, 0.12, 13.3, 0.64, 14.15, 0.72, 13.96, 0.5, 13.6, -0.09, 18.49, -1.38, 17.3, 0.19, 16.77, -1.7, 15.27, 1.21, 15.53, -1.05, 14.64, 0.07, 16.51, 1.68, 15.65, 0.28, 15.86, -1.39, 12.26, -0.87, 17.03, 0.23, 16.81, 0.12, 13.3, -2.08, 15.38, -0.42, 15.89, 0.02, 15.61, 0.01, 14.32, 0.19, 18.35, 0.13, 18.37, 2.18, 16.44, -1.23, 16.18, 0.7, 15.34, 2.02, 15.25, 0.49, 16.96, 0.91, 15.76, -1.1, 14.84, -1.29, 11.71, 0.3, 16.93, 1.67, 16.95, 0.64, 14.15, -0.42, 15.89, 0.54, 16.74, 1.0, 15.36, 1.78, 15.45, 1.92, 19.23, 0.73, 18.97, 0.44, 18.41, 0.08, 16.12, 2.82, 15.9, 1.61, 15.22, 1.41, 17.46, 1.22, 16.46, 0.85, 15.17, 0.18, 13.44, -0.45, 17.13, 1.87, 17.41, 0.72, 13.96, 0.02, 15.61, 1.0, 15.36, 0.82, 15.68, 1.66, 14.93, 1.58, 17.62, 1.32, 17.52, 1.03, 16.8, -0.28, 15.92, 2.02, 15.69, 2.07, 14.84, 1.24, 16.48, 2.67, 15.42, 1.26, 14.64, -0.8, 13.78, 0.56, 15.81, 2.58, 16.03, 0.5, 13.6, 0.01, 14.32, 1.78, 15.45, 1.66, 14.93, 2.24, 15.52, 
+
+L3_zSYR2K_A_kn
+0.4, 0.7, 0.4, 0.4, 0.7, 0.8, 0.2, 0.2, 0.4, 0.6, 0.8, 0.7, 0.9, 0.6, 0.5, 0.6, 0.5, 0.6, 0.5, 0.2, 0.9, 0.1, 0.4, 0.5, 0.5, 0.1, 0.2, 0.8, 0.4, 0.5, 0.3, 0.3, 0.4, 0.8, 0.6, 0.4, 0.9, 0.5, 0.8, 0.1, 0.3, 0.8, 0.9, 0.3, 0.1, 0.6, 0.5, 0.8, 0.7, 0.1, 0.1, 0.7, 0.1, 0.9, 0.8, 0.2, 0.9, 0.4, 0.9, 0.1, 0.2, 0.9, 0.4, 0.7, 0.7, 0.3, 0.3, 0.1, 0.8, 0.2, 0.5, 0.6, 0.8, 0.7, 0.2, 0.2, 0.2, 0.6, 0.9, 0.7, 0.5, 0.6, 0.9, 0.2, 0.1, 0.4, 0.5, 0.1, 0.3, 0.8, 0.7, 0.6, 0.8, 0.2, 0.4, 0.3, 0.1, 0.3, 0.2, 0.2, 0.3, 0.4, 0.5, 0.4, 0.8, 0.8, 0.3, 0.7, 0.1, 0.3, 0.3, 0.6, 0.6, 0.3, 0.9, 0.3, 0.1, 0.7, 0.8, 0.6, 0.9, 0.8, 0.9, 0.1, 0.5, 0.5, 0.6, 0.5, 0.8, 0.1, 0.6, 0.8, 0.8, 0.2, 0.1, 0.4, 0.8, 0.2, 0.1, 0.6, 0.2, 0.3, 0.9, 0.4, 0.9, 0.6, 0.3, 0.2, 0.8, 0.9, 0.7, 0.6, 0.7, 0.2, 0.8, 0.2, 0.1, 0.3, 0.6, 0.3, 0.4, 0.1, 0.2, 0.3, 0.8, 0.5, 0.4, 0.6, 0.6, 0.1, 0.3, 0.9, 0.9, 0.4, 0.8, 0.2, 0.4, 0.2, 0.6, 0.1, 0.8, 0.1, 0.6, 0.9, 0.4, 0.1, 0.9, 0.5, 0.4, 0.8, 0.7, 0.1, 0.8, 0.2, 0.1, 0.7, 0.7, 0.7, 0.7, 0.4, 0.6, 0.6, 0.6, 0.9, 0.2, 0.9, 0.9, 0.7, 0.5, 0.4, 0.2, 0.3, 0.6, 0.2, 0.6, 0.1, 0.5, 0.9, 0.3, 0.1, 0.2, 0.6, 0.5, 0.5, 0.9, 0.9, 0.8, 0.8, 0.1, 0.6, 0.5, 0.9, 0.4, 0.3, 0.3, 0.9, 0.6, 0.4, 0.3, 0.4, 0.2, 0.8, 0.3, 0.1, 0.6, 0.8, 0.9, 0.9, 0.7, 0.3, 0.3, 0.5, 0.6, 0.7, 0.7, 0.2, 0.3, 0.7, 0.9, 0.1, 0.3, 0.6, 0.8, 0.3, 0.3, 0.9, 0.4, 0.4, 0.1, 0.8, 0.6, 0.4, 0.5, 0.3, 0.2, 0.2, 0.8, 0.1, 0.5, 0.6, 0.2, 0.3, 0.5, 0.1, 0.8, 0.9, 0.5, 0.6, 0.2, 0.2, 0.5, 0.5, 0.1, 0.1, 0.8, 0.7, 0.6, 0.2, 0.1, 0.7, 0.2, 0.9, 0.9, 0.2, 0.7, 0.9, 0.2, 0.7, 0.5, 0.9, 0.6, 0.5, 0.1, 0.8, 0.1, 0.8, 0.2, 0.6, 0.4, 0.2, 0.5, 0.5, 0.7, 0.3, 0.8, 0.5, 0.2, 0.5, 0.8, 0.2, 0.8, 0.7, 0.2, 0.5, 0.5, 0.5, 0.6, 0.8, 0.1, 0.2, 0.1, 0.1, 0.7, 0.6, 0.3, 0.1, 0.2, 0.3, 0.1, 0.7, 0.9, 0.5, 0.8, 0.3, 0.8, 0.8, 0.7, 0.9, 0.7, 0.8, 0.1, 0.5, 0.1, 0.1, 0.4, 0.5, 0.5, 0.6, 0.4, 0.4, 0.5, 0.4, 0.8, 0.6, 0.6, 0.5, 0.5, 0.2, 0.3, 0.2, 0.7, 0.9, 0.9, 0.5, 0.2, 0.1, 0.7, 0.1, 0.3, 0.9, 0.2, 0.6, 0.9, 0.4, 0.2, 0.3, 0.7, 0.1, 0.3, 0.5, 0.7, 0.4, 0.2, 0.1, 0.5, 0.2, 0.9, 0.2, 0.5, 0.8, 0.1, 0.6, 0.4, 0.6, 0.7, 0.8, 0.4, 0.8, 0.9, 0.5, 0.2, 0.7, 0.5, 0.4, 0.5, 0.9, 0.5, 0.1, 0.5, 0.3, 0.8, 0.6, 0.6, 0.7, 0.3, 0.9, 0.9, 0.4, 0.3, 0.4, 0.1, 0.5, 0.4, 0.4, 0.6, 0.4, 0.2, 0.9, 0.4, 0.6, 0.3, 0.5, 0.7, 0.2, 0.6, 0.7, 0.1, 0.1, 0.2, 0.8, 0.4, 0.8, 0.2, 0.2, 0.4, 0.6, 0.6, 0.2, 0.5, 0.7, 0.3, 0.4, 0.1, 0.2, 0.8, 0.6, 0.6, 0.9, 0.9, 0.2, 0.9, 0.2, 0.3, 0.6, 0.7, 0.5, 0.6, 0.5, 0.3, 0.1, 0.8, 0.3, 0.2, 0.1, 0.7, 0.7, 0.3, 0.9, 0.7, 0.4, 0.8, 0.7, 0.6, 0.8, 0.5, 0.6, 0.6, 0.9, 0.4, 0.5, 0.1, 0.2, 0.7, 0.6, 0.2, 0.7, 0.3, 0.5, 0.3, 0.6, 0.9, 0.7, 0.7, 0.6, 0.8, 0.4, 0.6, 0.5, 0.5, 0.8, 0.1, 0.3, 0.6, 0.9, 0.1, 0.2, 0.6, 0.3, 0.5, 0.7, 0.1, 0.9, 0.3, 0.5, 
+
+L3_zSYR2K_B_kn
+0.7, 0.2, 0.6, 0.4, 0.5, 0.4, 0.6, 0.6, 0.7, 0.5, 0.2, 0.2, 0.3, 0.1, 0.5, 0.7, 0.1, 0.3, 0.9, 0.4, 0.3, 0.3, 0.6, 0.2, 0.2, 0.7, 0.6, 0.9, 0.4, 0.3, 0.2, 0.5, 0.6, 0.2, 0.2, 0.1, 0.5, 0.9, 0.6, 0.2, 0.8, 0.1, 0.2, 0.3, 0.7, 0.1, 0.1, 0.2, 0.5, 0.4, 0.6, 0.3, 0.2, 0.8, 0.1, 0.1, 0.7, 0.9, 0.8, 0.6, 0.9, 0.4, 0.6, 0.3, 0.1, 0.4, 0.7, 0.6, 0.3, 0.4, 0.8, 0.6, 0.4, 0.1, 0.5, 0.3, 0.7, 0.4, 0.3, 0.3, 0.6, 0.6, 0.6, 0.8, 0.4, 0.5, 0.1, 0.8, 0.2, 0.3, 0.8, 0.9, 0.9, 0.6, 0.4, 0.1, 0.7, 0.1, 0.2, 0.7, 0.8, 0.5, 0.3, 0.7, 0.8, 0.2, 0.9, 0.9, 0.1, 0.1, 0.9, 0.2, 0.3, 0.7, 0.8, 0.5, 0.4, 0.2, 0.7, 0.7, 0.9, 0.1, 0.5, 0.4, 0.1, 0.4, 0.3, 0.6, 0.6, 0.6, 0.1, 0.5, 0.5, 0.4, 0.1, 0.8, 0.7, 0.2, 0.1, 0.6, 0.2, 0.4, 0.1, 0.9, 0.2, 0.7, 0.4, 0.4, 0.9, 0.6, 0.2, 0.9, 0.4, 0.6, 0.1, 0.1, 0.5, 0.3, 0.7, 0.4, 0.7, 0.2, 0.5, 0.1, 0.9, 0.7, 0.6, 0.7, 0.2, 0.4, 0.1, 0.1, 0.4, 0.8, 0.4, 0.4, 0.2, 0.5, 0.3, 0.7, 0.8, 0.3, 0.9, 0.8, 0.3, 0.8, 0.4, 0.3, 0.2, 0.9, 0.7, 0.8, 0.3, 0.8, 0.5, 0.9, 0.5, 0.1, 0.4, 0.3, 0.9, 0.1, 0.6, 0.8, 0.7, 0.4, 0.7, 0.3, 0.4, 0.3, 0.6, 0.6, 0.2, 0.3, 0.8, 0.4, 0.8, 0.1, 0.9, 0.9, 0.1, 0.4, 0.8, 0.3, 0.4, 0.7, 0.8, 0.9, 0.6, 0.5, 0.8, 0.5, 0.6, 0.3, 0.4, 0.5, 0.9, 0.5, 0.5, 0.4, 0.3, 0.4, 0.5, 0.9, 0.8, 0.3, 0.2, 0.5, 0.8, 0.6, 0.1, 0.7, 0.7, 0.2, 0.6, 0.7, 0.6, 0.5, 0.4, 0.1, 0.7, 0.3, 0.5, 0.4, 0.2, 0.3, 0.9, 0.1, 0.5, 0.8, 0.1, 0.7, 0.5, 0.5, 0.6, 0.8, 0.8, 0.8, 0.6, 0.5, 0.9, 0.9, 0.8, 0.3, 0.2, 0.5, 0.8, 0.3, 0.3, 0.6, 0.8, 0.6, 0.3, 0.5, 0.2, 0.8, 0.9, 0.4, 0.3, 0.2, 0.1, 0.8, 0.7, 0.8, 0.2, 0.4, 0.4, 0.9, 0.8, 0.6, 0.1, 0.1, 0.1, 0.3, 0.7, 0.1, 0.9, 0.2, 0.2, 0.1, 0.2, 0.7, 0.2, 0.6, 0.6, 0.6, 0.9, 0.3, 0.5, 0.3, 0.2, 0.5, 0.4, 0.4, 0.6, 0.9, 0.2, 0.2, 0.7, 0.2, 0.8, 0.8, 0.3, 0.8, 0.3, 0.3, 0.5, 0.5, 0.3, 0.3, 0.7, 0.4, 0.8, 0.4, 0.2, 0.9, 0.7, 0.2, 0.5, 0.3, 0.2, 0.6, 0.4, 0.7, 0.7, 0.9, 0.1, 0.6, 0.5, 0.5, 0.4, 0.9, 0.1, 0.2, 0.3, 0.4, 0.4, 0.5, 0.3, 0.9, 0.2, 0.3, 0.1, 0.2, 0.4, 0.3, 0.8, 0.1, 0.7, 0.6, 0.9, 0.5, 0.5, 0.6, 0.7, 0.2, 0.4, 0.1, 0.5, 0.6, 0.9, 0.8, 0.2, 0.4, 0.9, 0.1, 0.3, 0.1, 0.1, 0.8, 0.2, 0.6, 0.9, 0.4, 0.8, 0.2, 0.9, 0.1, 0.4, 0.3, 0.1, 0.8, 0.2, 0.3, 0.2, 0.1, 0.6, 0.1, 0.2, 0.7, 0.2, 0.4, 0.3, 0.8, 0.8, 0.5, 0.6, 0.2, 0.3, 0.5, 0.2, 0.3, 0.2, 0.6, 0.1, 0.1, 0.7, 0.8, 0.3, 0.5, 0.1, 0.5, 0.3, 0.3, 0.6, 0.5, 0.9, 0.1, 0.2, 0.3, 0.3, 0.5, 0.4, 0.3, 0.1, 0.5, 0.6, 0.2, 0.2, 0.7, 0.4, 0.9, 0.8, 0.8, 0.5, 0.5, 0.7, 0.2, 0.1, 0.3, 0.9, 0.1, 0.5, 0.9, 0.7, 0.5, 0.3, 0.2, 0.7, 0.9, 0.8, 0.4, 0.1, 0.7, 0.6, 0.8, 0.4, 0.4, 0.2, 0.7, 0.3, 0.2, 0.5, 0.4, 0.7, 0.9, 0.1, 0.8, 0.2, 0.4, 0.6, 0.6, 0.2, 0.6, 0.1, 0.5, 0.3, 0.1, 0.8, 0.7, 0.6, 0.7, 0.4, 0.7, 0.4, 0.2, 0.3, 0.8, 0.9, 0.3, 0.8, 0.2, 0.4, 0.3, 0.4, 0.8, 0.7, 0.9, 0.8, 0.9, 0.3, 0.8, 0.3, 0.6, 
+
+L3_zSYR2K_o_T
+-0.52, 12.4, -0.8, 15.71, 0.86, 13.79, -1.58, 12.76, -0.16, 13.93, 2.75, 14.48, 0.91, 15.94, 0.29, 15.73, -0.85, 13.4, -0.16, 16.88, 0.19, 12.01, 0.07, 15.02, 0.57, 13.91, -0.56, 15.83, 0.09, 15.06, -0.5, 15.3, -0.1, 13.49, -0.8, 15.71, -0.32, 17.5, 2.12, 15.78, -1.51, 14.17, -0.24, 16.47, 2.34, 16.3, 0.47, 18.1, 0.37, 17.08, -1.78, 15.37, 0.9, 18.28, 2.08, 13.95, 1.08, 18.65, 1.18, 16.86, -0.81, 16.29, -0.42, 17.78, -1.11, 16.03, -0.36, 15.54, 0.86, 13.79, 2.12, 15.78, 2.84, 13.58, 1.02, 14.51, 2.27, 15.73, 5.14, 13.22, 1.33, 17.31, 1.53, 14.71, -0.7, 14.52, 1.51, 17.56, 3.31, 12.6, 2.56, 16.64, 3.2, 15.16, 0.27, 15.66, 1.55, 15.12, 0.65, 14.81, 0.99, 15.16, -1.58, 12.76, -1.51, 14.17, 1.02, 14.51, -0.44, 13.68, 0.22, 15.01, 2.87, 14.15, -0.15, 16.08, 1.29, 14.34, -1.43, 13.65, -0.57, 15.0, 0.87, 11.76, 0.58, 14.83, 0.74, 13.71, -2.3, 15.78, -1.0, 14.7, -1.56, 13.75, -0.81, 13.51, -0.16, 13.93, -0.24, 16.47, 2.27, 15.73, 0.22, 15.01, -0.58, 16.18, 4.53, 15.26, 0.95, 17.19, 2.2, 15.87, -0.08, 14.81, 1.49, 17.07, 2.48, 12.26, 1.68, 17.07, 2.2, 14.97, -0.19, 15.38, 0.32, 16.06, -0.28, 14.8, -0.86, 14.57, 2.75, 14.48, 2.34, 16.3, 5.14, 13.22, 2.87, 14.15, 4.53, 15.26, 6.16, 14.3, 4.28, 17.04, 3.96, 14.84, 2.69, 14.57, 3.87, 16.57, 4.87, 12.5, 3.8, 16.29, 3.92, 15.43, 2.16, 17.18, 4.01, 15.83, 1.79, 15.04, 3.01, 14.19, 0.91, 15.94, 0.47, 18.1, 1.33, 17.31, -0.15, 16.08, 0.95, 17.19, 4.28, 17.04, 2.18, 17.8, 1.56, 18.48, 0.48, 15.94, 2.71, 17.95, 1.33, 14.39, 0.01, 17.84, 1.07, 18.54, 1.38, 17.93, 0.31, 18.49, -0.12, 17.61, 0.44, 16.58, 0.29, 15.73, 0.37, 17.08, 1.53, 14.71, 1.29, 14.34, 2.2, 15.87, 3.96, 14.84, 1.56, 18.48, 1.54, 17.24, -0.75, 16.02, 1.92, 18.62, 1.43, 13.59, 3.11, 17.61, 1.75, 15.71, -0.13, 16.86, 1.11, 16.28, -1.34, 17.27, 1.33, 14.29, -0.85, 13.4, -1.78, 15.37, -0.7, 14.52, -1.43, 13.65, -0.08, 14.81, 2.69, 14.57, 0.48, 15.94, -0.75, 16.02, 0.42, 14.34, 0.43, 16.24, 1.18, 12.31, -0.79, 15.0, -0.45, 15.27, -1.42, 15.48, -1.02, 14.34, -1.64, 13.79, -0.55, 13.09, -0.16, 16.88, 0.9, 18.28, 1.51, 17.56, -0.57, 15.0, 1.49, 17.07, 3.87, 16.57, 2.71, 17.95, 1.92, 18.62, 0.43, 16.24, 1.8, 18.06, 3.14, 14.36, 0.81, 18.18, 0.93, 17.96, -0.61, 17.48, 0.4, 17.32, -0.32, 17.83, -0.11, 16.02, 0.19, 12.01, 2.08, 13.95, 3.31, 12.6, 0.87, 11.76, 2.48, 12.26, 4.87, 12.5, 1.33, 14.39, 1.43, 13.59, 1.18, 12.31, 3.14, 14.36, 1.76, 10.76, 1.75, 14.71, 1.54, 13.27, 1.13, 14.04, 1.52, 13.28, -0.31, 13.2, 1.1, 13.46, 0.07, 15.02, 1.08, 18.65, 2.56, 16.64, 0.58, 14.83, 1.68, 17.07, 3.8, 16.29, 0.01, 17.84, 3.11, 17.61, -0.79, 15.0, 0.81, 18.18, 1.75, 14.71, 0.96, 18.8, 2.24, 17.16, -0.51, 16.81, 0.99, 16.56, -0.98, 16.25, 0.72, 14.93, 0.57, 13.91, 1.18, 16.86, 3.2, 15.16, 0.74, 13.71, 2.2, 14.97, 3.92, 15.43, 1.07, 18.54, 1.75, 15.71, -0.45, 15.27, 0.93, 17.96, 1.54, 13.27, 2.24, 17.16, 1.62, 14.58, -0.06, 16.54, 0.96, 16.18, 0.33, 15.65, 0.67, 15.12, -0.56, 15.83, -0.81, 16.29, 0.27, 15.66, -2.3, 15.78, -0.19, 15.38, 2.16, 17.18, 1.38, 17.93, -0.13, 16.86, -1.42, 15.48, -0.61, 17.48, 1.13, 14.04, -0.51, 16.81, -0.06, 16.54, -0.88, 17.34, -0.59, 16.72, -1.22, 15.77, -1.2, 14.95, 0.09, 15.06, -0.42, 17.78, 1.55, 15.12, -1.0, 14.7, 0.32, 16.06, 4.01, 15.83, 0.31, 18.49, 1.11, 16.28, -1.02, 14.34, 0.4, 17.32, 1.52, 13.28, 0.99, 16.56, 0.96, 16.18, -0.59, 16.72, 0.08, 16.14, -1.71, 16.03, -0.46, 14.38, -0.5, 15.3, -1.11, 16.03, 0.65, 14.81, -1.56, 13.75, -0.28, 14.8, 1.79, 15.04, -0.12, 17.61, -1.34, 17.27, -1.64, 13.79, -0.32, 17.83, -0.31, 13.2, -0.98, 16.25, 0.33, 15.65, -1.22, 15.77, -1.71, 16.03, -2.26, 13.92, -1.11, 14.89, -0.1, 13.49, -0.36, 15.54, 0.99, 15.16, -0.81, 13.51, -0.86, 14.57, 3.01, 14.19, 0.44, 16.58, 1.33, 14.29, -0.55, 13.09, -0.11, 16.02, 1.1, 13.46, 0.72, 14.93, 0.67, 15.12, -1.2, 14.95, -0.46, 14.38, -1.11, 14.89, -0.78, 13.22, 
+
+L3_cHER2K_A_nk
+0.699999988079, 0.699999988079, 0.899999976158, 0.20000000298, 0.600000023842, 0.699999988079, 0.800000011921, 0.40000000596, 0.40000000596, 0.899999976158, 0.800000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.40000000596, 0.10000000149, 0.600000023842, 0.10000000149, 0.5, 0.5, 0.300000011921, 0.40000000596, 0.699999988079, 0.10000000149, 0.300000011921, 0.5, 0.5, 0.899999976158, 0.800000011921, 0.20000000298, 0.800000011921, 0.800000011921, 0.20000000298, 0.699999988079, 0.800000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.800000011921, 0.40000000596, 0.20000000298, 0.5, 0.899999976158, 0.40000000596, 0.5, 0.40000000596, 0.10000000149, 0.800000011921, 0.699999988079, 0.800000011921, 0.20000000298, 0.20000000298, 0.5, 0.300000011921, 0.5, 0.20000000298, 0.800000011921, 0.800000011921, 0.699999988079, 0.5, 0.10000000149, 0.800000011921, 0.5, 0.5, 0.699999988079, 0.5, 0.5, 0.10000000149, 0.5, 0.800000011921, 0.899999976158, 0.20000000298, 0.300000011921, 0.5, 0.10000000149, 0.40000000596, 0.699999988079, 0.5, 0.300000011921, 0.5, 0.300000011921, 0.5, 0.899999976158, 0.300000011921, 0.10000000149, 0.600000023842, 0.5, 0.899999976158, 0.5, 0.600000023842, 0.699999988079, 0.300000011921, 0.5, 0.300000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.5, 0.300000011921, 0.800000011921, 0.899999976158, 0.300000011921, 0.10000000149, 0.699999988079, 0.10000000149, 0.699999988079, 0.10000000149, 0.600000023842, 0.5, 0.5, 0.300000011921, 0.40000000596, 0.10000000149, 0.600000023842, 0.40000000596, 0.10000000149, 0.10000000149, 0.10000000149, 0.10000000149, 0.10000000149, 0.600000023842, 0.699999988079, 0.10000000149, 0.699999988079, 0.20000000298, 0.10000000149, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.800000011921, 0.20000000298, 0.20000000298, 0.300000011921, 0.5, 0.5, 0.10000000149, 0.40000000596, 0.20000000298, 0.40000000596, 0.10000000149, 0.899999976158, 0.800000011921, 0.800000011921, 0.800000011921, 0.5, 0.600000023842, 0.600000023842, 0.40000000596, 0.10000000149, 0.20000000298, 0.10000000149, 0.899999976158, 0.40000000596, 0.300000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.20000000298, 0.600000023842, 0.699999988079, 0.40000000596, 0.600000023842, 0.800000011921, 0.600000023842, 0.300000011921, 0.5, 0.20000000298, 0.600000023842, 0.899999976158, 0.699999988079, 0.800000011921, 0.10000000149, 0.899999976158, 0.600000023842, 0.899999976158, 0.5, 0.10000000149, 0.600000023842, 0.899999976158, 0.20000000298, 0.600000023842, 0.20000000298, 0.600000023842, 0.20000000298, 0.899999976158, 0.800000011921, 0.699999988079, 0.40000000596, 0.10000000149, 0.40000000596, 0.40000000596, 0.899999976158, 0.20000000298, 0.40000000596, 0.800000011921, 0.5, 0.899999976158, 0.40000000596, 0.800000011921, 0.40000000596, 0.800000011921, 0.699999988079, 0.300000011921, 0.10000000149, 0.10000000149, 0.300000011921, 0.300000011921, 0.5, 0.300000011921, 0.699999988079, 0.40000000596, 0.5, 0.800000011921, 0.800000011921, 0.300000011921, 0.10000000149, 0.20000000298, 0.899999976158, 0.899999976158, 0.699999988079, 0.800000011921, 0.20000000298, 0.300000011921, 0.10000000149, 0.20000000298, 0.699999988079, 0.699999988079, 0.300000011921, 0.300000011921, 0.20000000298, 0.20000000298, 0.699999988079, 0.600000023842, 0.300000011921, 0.10000000149, 0.10000000149, 0.699999988079, 0.899999976158, 0.800000011921, 0.699999988079, 0.899999976158, 0.5, 0.699999988079, 0.5, 0.899999976158, 0.5, 0.5, 0.300000011921, 0.699999988079, 0.5, 0.20000000298, 0.600000023842, 0.699999988079, 0.600000023842, 0.20000000298, 0.20000000298, 0.800000011921, 0.899999976158, 0.10000000149, 0.899999976158, 0.40000000596, 0.10000000149, 0.10000000149, 0.20000000298, 0.800000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.300000011921, 0.699999988079, 0.899999976158, 0.40000000596, 0.10000000149, 0.40000000596, 0.699999988079, 0.600000023842, 0.800000011921, 0.5, 0.300000011921, 0.699999988079, 0.699999988079, 0.300000011921, 0.20000000298, 0.800000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.40000000596, 0.899999976158, 0.300000011921, 0.10000000149, 0.5, 0.600000023842, 0.40000000596, 0.899999976158, 0.800000011921, 0.5, 0.800000011921, 0.300000011921, 0.899999976158, 0.10000000149, 0.300000011921, 0.40000000596, 0.600000023842, 0.20000000298, 0.5, 0.300000011921, 0.20000000298, 0.300000011921, 0.40000000596, 0.899999976158, 0.300000011921, 0.800000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.20000000298, 0.699999988079, 0.800000011921, 0.40000000596, 0.10000000149, 0.5, 0.5, 0.20000000298, 0.300000011921, 0.899999976158, 0.699999988079, 0.40000000596, 0.699999988079, 0.10000000149, 0.5, 0.40000000596, 0.5, 0.5, 0.10000000149, 0.40000000596, 0.800000011921, 0.10000000149, 0.800000011921, 0.20000000298, 0.699999988079, 0.800000011921, 0.10000000149, 0.699999988079, 0.5, 0.10000000149, 0.20000000298, 0.20000000298, 0.600000023842, 0.699999988079, 0.20000000298, 0.699999988079, 0.699999988079, 0.600000023842, 0.300000011921, 0.800000011921, 0.20000000298, 0.5, 0.20000000298, 0.600000023842, 0.899999976158, 0.800000011921, 0.40000000596, 0.20000000298, 0.699999988079, 0.800000011921, 0.600000023842, 0.800000011921, 0.5, 0.699999988079, 0.20000000298, 0.300000011921, 0.20000000298, 0.699999988079, 0.40000000596, 0.699999988079, 0.5, 0.699999988079, 0.899999976158, 0.20000000298, 0.899999976158, 0.300000011921, 0.800000011921, 0.5, 0.699999988079, 0.20000000298, 0.899999976158, 0.600000023842, 0.300000011921, 0.800000011921, 0.300000011921, 0.40000000596, 0.699999988079, 0.699999988079, 0.600000023842, 0.20000000298, 0.20000000298, 0.5, 0.899999976158, 0.10000000149, 0.300000011921, 0.5, 0.20000000298, 0.800000011921, 0.600000023842, 0.20000000298, 0.20000000298, 0.20000000298, 0.800000011921, 0.699999988079, 0.10000000149, 0.800000011921, 0.899999976158, 0.10000000149, 0.300000011921, 0.300000011921, 0.300000011921, 0.20000000298, 0.899999976158, 0.40000000596, 0.600000023842, 0.699999988079, 0.5, 0.800000011921, 0.300000011921, 0.600000023842, 0.5, 0.20000000298, 0.20000000298, 0.800000011921, 0.699999988079, 0.300000011921, 0.600000023842, 0.899999976158, 0.40000000596, 0.40000000596, 0.899999976158, 0.300000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.5, 0.40000000596, 0.899999976158, 0.5, 0.600000023842, 0.699999988079, 0.800000011921, 0.600000023842, 0.10000000149, 0.699999988079, 0.800000011921, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.40000000596, 0.20000000298, 0.5, 0.40000000596, 0.300000011921, 0.20000000298, 0.699999988079, 0.300000011921, 0.5, 0.699999988079, 0.300000011921, 0.5, 0.5, 0.600000023842, 0.699999988079, 0.600000023842, 0.40000000596, 0.40000000596, 0.800000011921, 0.699999988079, 0.20000000298, 0.5, 0.10000000149, 0.600000023842, 0.699999988079, 0.899999976158, 0.20000000298, 0.40000000596, 0.600000023842, 0.300000011921, 0.40000000596, 0.20000000298, 0.699999988079, 0.300000011921, 0.5, 0.5, 0.899999976158, 0.600000023842, 0.300000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.600000023842, 0.10000000149, 0.40000000596, 0.40000000596, 0.899999976158, 0.600000023842, 0.800000011921, 0.300000011921, 0.800000011921, 0.5, 0.300000011921, 0.10000000149, 0.899999976158, 0.40000000596, 0.300000011921, 0.10000000149, 0.600000023842, 0.800000011921, 0.300000011921, 0.699999988079, 0.40000000596, 0.899999976158, 0.40000000596, 0.699999988079, 0.899999976158, 0.20000000298, 0.600000023842, 0.40000000596, 0.5, 0.20000000298, 0.20000000298, 0.699999988079, 0.40000000596, 0.800000011921, 0.600000023842, 0.699999988079, 0.10000000149, 0.40000000596, 0.600000023842, 0.800000011921, 0.10000000149, 0.899999976158, 
+
+L3_cHER2K_B_nk
+0.800000011921, 0.5, 0.5, 0.20000000298, 0.20000000298, 0.5, 0.899999976158, 0.899999976158, 0.10000000149, 0.800000011921, 0.10000000149, 0.600000023842, 0.20000000298, 0.699999988079, 0.600000023842, 0.899999976158, 0.40000000596, 0.699999988079, 0.699999988079, 0.5, 0.800000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.10000000149, 0.20000000298, 0.300000011921, 0.5, 0.5, 0.10000000149, 0.699999988079, 0.20000000298, 0.600000023842, 0.300000011921, 0.40000000596, 0.20000000298, 0.800000011921, 0.20000000298, 0.20000000298, 0.800000011921, 0.10000000149, 0.20000000298, 0.699999988079, 0.699999988079, 0.20000000298, 0.600000023842, 0.5, 0.800000011921, 0.800000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.899999976158, 0.300000011921, 0.10000000149, 0.899999976158, 0.300000011921, 0.40000000596, 0.300000011921, 0.300000011921, 0.800000011921, 0.10000000149, 0.899999976158, 0.699999988079, 0.5, 0.10000000149, 0.5, 0.899999976158, 0.699999988079, 0.800000011921, 0.600000023842, 0.20000000298, 0.800000011921, 0.800000011921, 0.40000000596, 0.5, 0.699999988079, 0.800000011921, 0.40000000596, 0.800000011921, 0.5, 0.800000011921, 0.10000000149, 0.600000023842, 0.600000023842, 0.40000000596, 0.300000011921, 0.20000000298, 0.40000000596, 0.899999976158, 0.10000000149, 0.20000000298, 0.600000023842, 0.600000023842, 0.699999988079, 0.5, 0.40000000596, 0.300000011921, 0.600000023842, 0.40000000596, 0.600000023842, 0.40000000596, 0.40000000596, 0.899999976158, 0.20000000298, 0.5, 0.899999976158, 0.600000023842, 0.20000000298, 0.600000023842, 0.20000000298, 0.800000011921, 0.800000011921, 0.20000000298, 0.300000011921, 0.20000000298, 0.800000011921, 0.10000000149, 0.300000011921, 0.899999976158, 0.300000011921, 0.20000000298, 0.899999976158, 0.899999976158, 0.600000023842, 0.20000000298, 0.20000000298, 0.800000011921, 0.899999976158, 0.10000000149, 0.899999976158, 0.600000023842, 0.699999988079, 0.20000000298, 0.300000011921, 0.20000000298, 0.600000023842, 0.20000000298, 0.40000000596, 0.10000000149, 0.800000011921, 0.300000011921, 0.600000023842, 0.300000011921, 0.20000000298, 0.40000000596, 0.699999988079, 0.10000000149, 0.10000000149, 0.300000011921, 0.699999988079, 0.10000000149, 0.10000000149, 0.600000023842, 0.600000023842, 0.5, 0.20000000298, 0.5, 0.40000000596, 0.600000023842, 0.600000023842, 0.5, 0.600000023842, 0.800000011921, 0.10000000149, 0.899999976158, 0.5, 0.600000023842, 0.699999988079, 0.300000011921, 0.699999988079, 0.300000011921, 0.800000011921, 0.40000000596, 0.899999976158, 0.699999988079, 0.699999988079, 0.699999988079, 0.40000000596, 0.20000000298, 0.300000011921, 0.300000011921, 0.40000000596, 0.800000011921, 0.800000011921, 0.20000000298, 0.20000000298, 0.10000000149, 0.10000000149, 0.5, 0.20000000298, 0.5, 0.5, 0.300000011921, 0.40000000596, 0.20000000298, 0.40000000596, 0.5, 0.20000000298, 0.600000023842, 0.300000011921, 0.5, 0.899999976158, 0.699999988079, 0.899999976158, 0.10000000149, 0.5, 0.300000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.10000000149, 0.600000023842, 0.800000011921, 0.40000000596, 0.699999988079, 0.699999988079, 0.800000011921, 0.20000000298, 0.5, 0.10000000149, 0.10000000149, 0.10000000149, 0.5, 0.699999988079, 0.699999988079, 0.600000023842, 0.899999976158, 0.899999976158, 0.600000023842, 0.600000023842, 0.800000011921, 0.300000011921, 0.10000000149, 0.600000023842, 0.10000000149, 0.699999988079, 0.800000011921, 0.5, 0.300000011921, 0.10000000149, 0.899999976158, 0.20000000298, 0.20000000298, 0.899999976158, 0.300000011921, 0.40000000596, 0.10000000149, 0.600000023842, 0.10000000149, 0.800000011921, 0.600000023842, 0.5, 0.40000000596, 0.40000000596, 0.699999988079, 0.10000000149, 0.699999988079, 0.699999988079, 0.40000000596, 0.300000011921, 0.300000011921, 0.300000011921, 0.600000023842, 0.300000011921, 0.800000011921, 0.600000023842, 0.20000000298, 0.699999988079, 0.5, 0.20000000298, 0.899999976158, 0.40000000596, 0.10000000149, 0.20000000298, 0.40000000596, 0.699999988079, 0.300000011921, 0.10000000149, 0.800000011921, 0.5, 0.5, 0.5, 0.699999988079, 0.20000000298, 0.600000023842, 0.800000011921, 0.40000000596, 0.800000011921, 0.899999976158, 0.699999988079, 0.20000000298, 0.20000000298, 0.300000011921, 0.300000011921, 0.300000011921, 0.800000011921, 0.40000000596, 0.5, 0.899999976158, 0.699999988079, 0.5, 0.40000000596, 0.800000011921, 0.40000000596, 0.5, 0.10000000149, 0.699999988079, 0.699999988079, 0.20000000298, 0.899999976158, 0.600000023842, 0.300000011921, 0.10000000149, 0.40000000596, 0.20000000298, 0.20000000298, 0.300000011921, 0.300000011921, 0.10000000149, 0.40000000596, 0.300000011921, 0.20000000298, 0.699999988079, 0.600000023842, 0.899999976158, 0.20000000298, 0.300000011921, 0.40000000596, 0.600000023842, 0.800000011921, 0.800000011921, 0.40000000596, 0.20000000298, 0.699999988079, 0.800000011921, 0.5, 0.899999976158, 0.300000011921, 0.20000000298, 0.600000023842, 0.800000011921, 0.300000011921, 0.5, 0.699999988079, 0.10000000149, 0.20000000298, 0.699999988079, 0.10000000149, 0.20000000298, 0.20000000298, 0.600000023842, 0.699999988079, 0.600000023842, 0.10000000149, 0.20000000298, 0.300000011921, 0.699999988079, 0.600000023842, 0.899999976158, 0.300000011921, 0.5, 0.40000000596, 0.800000011921, 0.899999976158, 0.300000011921, 0.899999976158, 0.300000011921, 0.800000011921, 0.800000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.10000000149, 0.40000000596, 0.5, 0.600000023842, 0.300000011921, 0.20000000298, 0.600000023842, 0.20000000298, 0.5, 0.699999988079, 0.300000011921, 0.40000000596, 0.899999976158, 0.40000000596, 0.800000011921, 0.699999988079, 0.40000000596, 0.600000023842, 0.699999988079, 0.899999976158, 0.300000011921, 0.20000000298, 0.300000011921, 0.5, 0.10000000149, 0.40000000596, 0.5, 0.5, 0.899999976158, 0.600000023842, 0.300000011921, 0.300000011921, 0.800000011921, 0.699999988079, 0.699999988079, 0.600000023842, 0.600000023842, 0.40000000596, 0.800000011921, 0.300000011921, 0.300000011921, 0.699999988079, 0.600000023842, 0.40000000596, 0.300000011921, 0.699999988079, 0.600000023842, 0.300000011921, 0.300000011921, 0.20000000298, 0.40000000596, 0.300000011921, 0.10000000149, 0.899999976158, 0.10000000149, 0.899999976158, 0.600000023842, 0.699999988079, 0.10000000149, 0.10000000149, 0.600000023842, 0.10000000149, 0.10000000149, 0.10000000149, 0.300000011921, 0.10000000149, 0.20000000298, 0.600000023842, 0.699999988079, 0.800000011921, 0.300000011921, 0.20000000298, 0.699999988079, 0.40000000596, 0.600000023842, 0.40000000596, 0.20000000298, 0.699999988079, 0.600000023842, 0.5, 0.600000023842, 0.800000011921, 0.10000000149, 0.800000011921, 0.10000000149, 0.10000000149, 0.20000000298, 0.300000011921, 0.600000023842, 0.699999988079, 0.699999988079, 0.20000000298, 0.10000000149, 0.40000000596, 0.699999988079, 0.10000000149, 0.600000023842, 0.40000000596, 0.10000000149, 0.899999976158, 0.20000000298, 0.699999988079, 0.5, 0.40000000596, 0.40000000596, 0.800000011921, 0.40000000596, 0.600000023842, 0.899999976158, 0.899999976158, 0.10000000149, 0.20000000298, 0.5, 0.5, 0.40000000596, 0.800000011921, 0.10000000149, 0.300000011921, 0.5, 0.600000023842, 0.20000000298, 0.300000011921, 0.899999976158, 0.899999976158, 0.5, 0.10000000149, 0.699999988079, 0.300000011921, 0.699999988079, 0.5, 0.699999988079, 0.10000000149, 0.699999988079, 0.10000000149, 0.5, 0.600000023842, 0.300000011921, 0.899999976158, 0.40000000596, 0.300000011921, 0.40000000596, 0.800000011921, 0.300000011921, 0.800000011921, 0.10000000149, 0.699999988079, 0.600000023842, 0.40000000596, 0.699999988079, 0.5, 0.40000000596, 0.10000000149, 0.300000011921, 0.40000000596, 0.800000011921, 0.899999976158, 0.699999988079, 0.899999976158, 0.40000000596, 0.5, 0.800000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.300000011921, 0.699999988079, 0.10000000149, 0.20000000298, 0.10000000149, 0.40000000596, 0.300000011921, 
+
+L3_cHER2K_C_nn
+0.10000000149, 0.0, 0.800000011921, 0.40000000596, 0.800000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.300000011921, 0.40000000596, 0.5, 0.20000000298, 0.40000000596, 0.899999976158, 0.300000011921, 0.10000000149, 0.699999988079, 0.40000000596, 0.899999976158, 0.899999976158, 0.20000000298, 0.600000023842, 0.699999988079, 0.600000023842, 0.20000000298, 0.40000000596, 0.20000000298, 0.20000000298, 0.800000011921, 0.800000011921, 0.5, 0.699999988079, 0.5, 0.899999976158, 0.800000011921, -0.40000000596, 0.899999976158, 0.0, 0.10000000149, 0.699999988079, 0.899999976158, 0.600000023842, 0.40000000596, 0.300000011921, 0.40000000596, 0.5, 0.10000000149, 0.899999976158, 0.899999976158, 0.600000023842, 0.40000000596, 0.20000000298, 0.5, 0.600000023842, 0.20000000298, 0.5, 0.899999976158, 0.40000000596, 0.20000000298, 0.600000023842, 0.899999976158, 0.699999988079, 0.899999976158, 0.300000011921, 0.699999988079, 0.5, 0.300000011921, 0.600000023842, 0.800000011921, -0.699999988079, 0.10000000149, -0.699999988079, 0.800000011921, 0.0, 0.5, 0.300000011921, 0.600000023842, 0.5, 0.300000011921, 0.899999976158, 0.40000000596, 0.899999976158, 0.20000000298, 0.300000011921, 0.699999988079, 0.40000000596, 0.300000011921, 0.600000023842, 0.899999976158, 0.10000000149, 0.800000011921, 0.20000000298, 0.5, 0.300000011921, 0.899999976158, 0.600000023842, 0.20000000298, 0.699999988079, 0.899999976158, 0.600000023842, 0.300000011921, 0.5, 0.300000011921, -0.899999976158, 0.899999976158, -0.600000023842, 0.5, -0.300000011921, 0.899999976158, 0.0, 0.5, 0.300000011921, 0.899999976158, 0.699999988079, 0.300000011921, 0.600000023842, 0.10000000149, 0.300000011921, 0.699999988079, 0.5, 0.300000011921, 0.800000011921, 0.5, 0.699999988079, 0.699999988079, 0.40000000596, 0.20000000298, 0.5, 0.20000000298, 0.300000011921, 0.600000023842, 0.10000000149, 0.600000023842, 0.40000000596, 0.10000000149, 0.40000000596, 0.300000011921, -0.40000000596, 0.40000000596, -0.300000011921, 0.600000023842, -0.5, 0.5, -0.300000011921, 0.10000000149, 0.0, 0.10000000149, 0.300000011921, 0.10000000149, 0.800000011921, 0.40000000596, 0.300000011921, 0.5, 0.20000000298, 0.800000011921, 0.600000023842, 0.20000000298, 0.40000000596, 0.40000000596, 0.5, 0.600000023842, 0.40000000596, 0.600000023842, 0.5, 0.10000000149, 0.40000000596, 0.40000000596, 0.600000023842, 0.5, 0.600000023842, 0.5, -0.20000000298, 0.40000000596, -0.5, 0.300000011921, -0.899999976158, 0.899999976158, -0.699999988079, 0.10000000149, -0.300000011921, 0.40000000596, 0.0, 0.10000000149, 0.800000011921, 0.699999988079, 0.300000011921, 0.899999976158, 0.699999988079, 0.20000000298, 0.800000011921, 0.10000000149, 0.40000000596, 0.899999976158, 0.800000011921, 0.899999976158, 0.600000023842, 0.699999988079, 0.600000023842, 0.10000000149, 0.699999988079, 0.20000000298, 0.20000000298, 0.10000000149, 0.20000000298, 0.40000000596, -0.899999976158, 0.10000000149, -0.899999976158, 0.40000000596, -0.899999976158, 0.300000011921, -0.600000023842, 0.10000000149, -0.800000011921, 0.10000000149, -0.800000011921, 0.10000000149, 0.0, 0.40000000596, 0.300000011921, 0.899999976158, 0.5, 0.40000000596, 0.300000011921, 0.40000000596, 0.5, 0.40000000596, 0.300000011921, 0.600000023842, 0.800000011921, 0.699999988079, 0.699999988079, 0.699999988079, 0.5, 0.20000000298, 0.899999976158, 0.699999988079, 0.699999988079, 0.300000011921, -0.10000000149, 0.899999976158, -0.600000023842, 0.20000000298, -0.300000011921, 0.10000000149, -0.300000011921, 0.40000000596, -0.300000011921, 0.699999988079, -0.300000011921, 0.40000000596, -0.300000011921, 0.300000011921, 0.0, 0.20000000298, 0.40000000596, 0.5, 0.899999976158, 0.800000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.899999976158, 0.300000011921, 0.300000011921, 0.699999988079, 0.20000000298, 0.800000011921, 0.600000023842, 0.800000011921, 0.300000011921, 0.300000011921, 0.699999988079, -0.40000000596, 0.40000000596, -0.20000000298, 0.699999988079, -0.40000000596, 0.699999988079, -0.5, 0.5, -0.20000000298, 0.899999976158, -0.699999988079, 0.899999976158, -0.5, 0.20000000298, -0.40000000596, 0.20000000298, 0.0, 0.800000011921, 0.20000000298, 0.20000000298, 0.5, 0.10000000149, 0.699999988079, 0.10000000149, 0.699999988079, 0.300000011921, 0.899999976158, 0.40000000596, 0.300000011921, 0.899999976158, 0.300000011921, 0.600000023842, 0.300000011921, 0.899999976158, -0.899999976158, 0.5, -0.600000023842, 0.300000011921, -0.600000023842, 0.300000011921, -0.800000011921, 0.800000011921, -0.600000023842, 0.20000000298, -0.800000011921, 0.40000000596, -0.300000011921, 0.5, -0.899999976158, 0.800000011921, -0.20000000298, 0.300000011921, 0.0, 0.600000023842, 0.699999988079, 0.699999988079, 0.699999988079, 0.600000023842, 0.10000000149, 0.600000023842, 0.40000000596, 0.20000000298, 0.800000011921, 0.10000000149, 0.600000023842, 0.600000023842, 0.600000023842, 0.20000000298, -0.600000023842, 0.20000000298, -0.5, 0.899999976158, -0.10000000149, 0.5, -0.699999988079, 0.20000000298, -0.40000000596, 0.10000000149, -0.40000000596, 0.40000000596, -0.5, 0.800000011921, -0.899999976158, 0.20000000298, -0.5, 0.600000023842, -0.699999988079, 0.300000011921, 0.0, 0.20000000298, 0.699999988079, 0.699999988079, 0.300000011921, 0.899999976158, 0.5, 0.600000023842, 0.899999976158, 0.800000011921, 0.40000000596, 0.20000000298, 0.10000000149, 0.699999988079, -0.600000023842, 0.899999976158, -0.40000000596, 0.800000011921, -0.20000000298, 0.699999988079, -0.40000000596, 0.40000000596, -0.5, 0.899999976158, -0.800000011921, 0.40000000596, -0.300000011921, 0.20000000298, -0.800000011921, 0.10000000149, -0.699999988079, 0.699999988079, -0.699999988079, 0.20000000298, -0.699999988079, 0.5, 0.0, 0.600000023842, 0.300000011921, 0.800000011921, 0.10000000149, 0.5, 0.600000023842, 0.800000011921, 0.20000000298, 0.600000023842, 0.800000011921, 0.20000000298, -0.40000000596, 0.20000000298, -0.600000023842, 0.5, -0.300000011921, 0.20000000298, -0.5, 0.600000023842, -0.40000000596, 0.899999976158, -0.600000023842, 0.600000023842, -0.800000011921, 0.899999976158, -0.300000011921, 0.10000000149, -0.699999988079, 0.600000023842, -0.10000000149, 0.699999988079, -0.300000011921, 0.600000023842, -0.300000011921, 0.300000011921, 0.0, 0.899999976158, 0.899999976158, 0.10000000149, 0.5, 0.699999988079, 0.5, 0.300000011921, 0.5, 0.20000000298, -0.20000000298, 0.899999976158, -0.699999988079, 0.899999976158, -0.600000023842, 0.20000000298, -0.300000011921, 0.600000023842, -0.5, 0.699999988079, -0.600000023842, 0.699999988079, -0.699999988079, 0.300000011921, -0.699999988079, 0.300000011921, -0.899999976158, 0.600000023842, -0.40000000596, 0.899999976158, -0.5, 0.800000011921, -0.10000000149, 0.899999976158, -0.899999976158, 0.10000000149, 0.0, 0.699999988079, 0.899999976158, 0.699999988079, 0.20000000298, 0.600000023842, 0.600000023842, 0.800000011921, -0.800000011921, 0.899999976158, -0.300000011921, 0.20000000298, -0.699999988079, 0.600000023842, -0.10000000149, 0.10000000149, -0.40000000596, 0.10000000149, -0.699999988079, 0.699999988079, -0.5, 0.20000000298, -0.800000011921, 0.40000000596, -0.300000011921, 0.20000000298, -0.800000011921, 0.600000023842, -0.899999976158, 0.5, -0.600000023842, 0.10000000149, -0.5, 0.699999988079, -0.899999976158, 0.300000011921, 0.0, 0.20000000298, 0.300000011921, 0.20000000298, 0.20000000298, 0.5, -0.699999988079, 0.699999988079, -0.5, 0.899999976158, -0.600000023842, 0.600000023842, -0.40000000596, 0.40000000596, -0.600000023842, 0.20000000298, -0.20000000298, 0.20000000298, -0.899999976158, 0.600000023842, -0.800000011921, 0.899999976158, -0.300000011921, 0.10000000149, -0.600000023842, 0.800000011921, -0.40000000596, 0.800000011921, -0.20000000298, 0.699999988079, -0.5, 0.699999988079, -0.20000000298, 0.20000000298, -0.300000011921, 0.600000023842, 0.0, 0.300000011921, 0.10000000149, 0.5, -0.899999976158, 0.300000011921, -0.600000023842, 0.300000011921, -0.5, 0.10000000149, -0.40000000596, 0.5, -0.600000023842, 0.10000000149, -0.20000000298, 0.699999988079, -0.699999988079, 0.300000011921, -0.300000011921, 0.600000023842, -0.300000011921, 0.600000023842, -0.600000023842, 0.20000000298, -0.10000000149, 0.600000023842, -0.800000011921, 0.300000011921, -0.5, 0.600000023842, -0.600000023842, 0.20000000298, -0.20000000298, 0.300000011921, -0.10000000149, 0.600000023842, 0.0, 
+
+L3_cHER2K_o_N
+16.7000000253, -1.33226762955e-15, 16.3100001925, 0.0299998816848, 18.260000039, 0.319999764413, 15.3900001539, -1.89000006229, 15.3100001419, 1.47999986008, 17.3600000994, -1.34000002801, 16.5900000705, 0.709999814034, 17.3500000954, -0.63000007689, 16.2800001164, -1.12000010863, 16.3199999641, 0.719999999851, 14.9700000863, -1.36000007182, 17.760000086, 1.20999989152, 16.860000159, -0.550000102818, 15.7500000365, -0.570000060201, 16.8200001407, 2.32999984741, 16.6000000745, 1.23999989465, 16.5300001149, 1.38999987304, 16.3100001925, -0.0299998816848, 15.1400001383, -3.33066907388e-16, 16.1700001921, 0.699999976158, 15.5700001377, -1.12999984965, 14.0000003263, 0.629999983013, 17.0700002435, 0.0700000587106, 14.760000156, 0.1299999547, 16.7600001895, -0.319999841154, 16.1700001876, -1.25000002161, 16.0800001164, 1.35000008419, 13.4900001748, -0.899999985099, 17.2500002533, 0.960000034571, 16.040000262, -1.28999993414, 16.4300001231, -0.429999971092, 16.4600001985, 2.07999999121, 16.3600000606, 1.00000007302, 16.2500001878, 0.790000140518, 18.260000039, -0.319999764413, 16.1700001921, -0.699999976158, 17.0600002104, -2.22044604925e-16, 15.0700001034, -1.64999979585, 14.770000248, 2.2199999842, 17.3000001445, 0.330000127554, 15.5800001797, 1.04999995828, 16.8300001484, 0.340000114441, 16.2900001509, -0.220000038594, 15.4200001884, 1.90000008941, 15.7500001729, -0.519999971539, 17.9500001825, 1.31000011653, 17.6000001974, -1.03999991328, 15.9900002009, -0.189999897629, 16.1700001965, 2.45999998391, 17.6400001144, 1.35000015274, 16.1000001512, 1.31000006959, 15.3900001539, 1.89000006229, 15.5700001377, 1.12999984965, 15.0700001034, 1.64999979585, 13.9200001198, 2.22044604925e-16, 13.7300002505, 2.38999994159, 16.090000212, 1.90000004768, 14.8400000705, 1.67999990404, 14.7400001234, 1.53000004038, 14.370000207, 1.43999991998, 14.130000167, 3.30000005886, 12.8200001958, 1.29999991804, 16.8400001934, 2.93000001431, 15.220000204, 1.49999988377, 13.7400002314, 1.51999993056, 14.8500002563, 3.22999983847, 14.6000001587, 2.71999994248, 14.2500002459, 2.30999999434, 15.3100001419, -1.47999986008, 14.0000003263, -0.629999983013, 14.770000248, -2.2199999842, 13.7300002505, -2.38999994159, 11.3800003138, 2.22044604925e-16, 14.4200002711, -2.31999993578, 13.2800001805, -0.25000006035, 14.060000232, -0.70999989599, 13.3600001538, -1.3299999927, 13.5500002772, -0.539999925941, 12.400000231, -1.39999997318, 15.6900002545, 0.0199999976158, 13.7000003479, -2.00999992281, 13.1900002992, -1.03999995276, 14.3800002207, 0.70000000447, 13.5000002593, -0.3199999246, 14.3900002165, -0.199999940395, 17.3600000994, 1.34000002801, 17.0700002435, -0.0700000587106, 17.3000001445, -0.330000127554, 16.090000212, -1.90000004768, 14.4200002711, 2.31999993578, 16.2600002596, 0.0, 15.5100001881, 3.19999983981, 16.6600001113, 1.08000001505, 16.4200001027, 0.919999851584, 16.2000001684, 2.22000000507, 15.1000002347, 0.0199999588728, 17.4800001998, 2.51999990299, 16.9300002192, -6.70552391391e-09, 15.9400001726, 1.90999991834, 16.4000002332, 3.25999978572, 16.3100000688, 1.42999995843, 16.6300002423, 1.73999998033, 16.5900000705, -0.709999814034, 14.760000156, -0.1299999547, 15.5800001797, -1.04999995828, 14.8400000705, -1.67999990404, 13.2800001805, 0.25000006035, 15.5100001881, -3.19999983981, 14.8000001207, 0.0, 15.4800001283, 0.0700001391768, 15.5100001664, -0.969999974519, 15.3800001648, 0.15000012666, 14.1700001474, -1.64999989867, 16.5500001013, 0.210000110567, 15.9100002581, -0.27999988988, 14.5500001356, 3.50177284947e-08, 15.7700001772, 2.49000000343, 14.4200001325, 1.10000010207, 16.1600001054, 1.12000011533, 17.3500000954, 0.63000007689, 16.7600001895, 0.319999841154, 16.8300001484, -0.340000114441, 14.7400001234, -1.53000004038, 14.060000232, 0.70999989599, 16.6600001113, -1.08000001505, 15.4800001283, -0.0700001391768, 15.4800000873, 0.0, 14.9600001739, -0.970000097454, 15.5000001281, 1.57999992117, 15.2300001246, -0.410000073314, 16.7000001356, 2.14999992251, 17.4100000688, -0.989999978095, 14.7200001511, -0.590000064522, 16.6200001802, 1.64999988154, 17.4800000344, 1.6699999775, 15.8700001645, 0.419999969304, 16.2800001164, 1.12000010863, 16.1700001876, 1.25000002161, 16.2900001509, 0.220000038594, 14.370000207, -1.43999991998, 13.3600001538, 1.3299999927, 16.4200001027, -0.919999851584, 15.5100001664, 0.969999974519, 14.9600001739, 0.970000097454, 15.5200001347, 4.4408920985e-16, 16.2700001355, 2.01000007108, 13.7800002177, 0.150000099838, 15.7800002125, 3.02999997035, 15.0200001712, 0.940000025034, 13.6800001618, 1.23000006422, 15.3500001691, 2.03999994308, 16.130000053, 1.30000016391, 15.7800002021, 1.01000007257, 16.3199999641, -0.719999999851, 16.0800001164, -1.35000008419, 15.4200001884, -1.90000008941, 14.130000167, -3.30000005886, 13.5500002772, 0.539999925941, 16.2000001684, -2.22000000507, 15.3800001648, -0.15000012666, 15.5000001281, -1.57999992117, 16.2700001355, -2.01000007108, 14.9800001723, 4.4408920985e-16, 14.1600002544, -1.24999999851, 17.2100001292, 1.00999993399, 16.5000001438, -0.480000074655, 14.140000253, -0.659999928027, 14.420000242, 2.30999992579, 15.79000011, 0.98999997139, 14.6300002229, 0.48000007093, 14.9700000863, 1.36000007182, 13.4900001748, 0.899999985099, 15.7500001729, 0.519999971539, 12.8200001958, -1.29999991804, 12.400000231, 1.39999997318, 15.1000002347, -0.0199999588728, 14.1700001474, 1.64999989867, 15.2300001246, 0.410000073314, 13.7800002177, -0.150000099838, 14.1600002544, 1.24999999851, 13.0000001281, -1.11022302463e-16, 16.0600001985, 3.7600000301, 15.6100001985, 0.490000058562, 14.6700001772, 0.570000025183, 15.1800002401, 4.27999993607, 15.3500001222, 3.13999999076, 14.5300001402, 1.98999997884, 17.760000086, -1.20999989152, 17.2500002533, -0.960000034571, 17.9500001825, -1.31000011653, 16.8400001934, -2.93000001431, 15.6900002545, -0.0199999976158, 17.4800001998, -2.51999990299, 16.5500001013, -0.210000110567, 16.7000001356, -2.14999992251, 15.7800002125, -3.02999997035, 17.2100001292, -1.00999993399, 16.0600001985, -3.7600000301, 18.5000001997, -4.4408920985e-16, 17.3600002357, -1.2700000155, 16.3300002192, -0.399999993294, 16.9200002085, 2.09999997392, 17.4500001401, 0.21000008896, 17.5200002033, -0.329999930859, 16.860000159, 0.550000102818, 16.040000262, 1.28999993414, 17.6000001974, 1.03999991328, 15.220000204, -1.49999988377, 13.7000003479, 2.00999992281, 16.9300002192, 6.70552546822e-09, 15.9100002581, 0.27999988988, 17.4100000688, 0.989999978095, 15.0200001712, -0.940000025034, 16.5000001438, 0.480000074655, 15.6100001985, -0.490000058562, 17.3600002357, 1.2700000155, 16.1400003082, 2.22044604925e-16, 16.4100001433, 1.23999997139, 16.4100002357, 3.279999872, 16.3200001906, 2.15999999508, 15.9900002694, 1.18000005677, 15.7500000365, 0.570000060201, 16.4300001231, 0.429999971092, 15.9900002009, 0.189999897629, 13.7400002314, -1.51999993056, 13.1900002992, 1.03999995276, 15.9400001726, -1.90999991834, 14.5500001356, -3.50177287167e-08, 14.7200001511, 0.590000064522, 13.6800001618, -1.23000006422, 14.140000253, 0.659999928027, 14.6700001772, -0.570000025183, 16.3300002192, 0.399999993294, 16.4100001433, -1.23999997139, 13.1400002724, 2.22044604925e-16, 15.3100002164, 2.35999994218, 15.2600001709, 1.46999996632, 15.1500001706, 1.42000012353, 16.8200001407, -2.32999984741, 16.4600001985, -2.07999999121, 16.1700001965, -2.45999998391, 14.8500002563, -3.22999983847, 14.3800002207, -0.70000000447, 16.4000002332, -3.25999978572, 15.7700001772, -2.49000000343, 16.6200001802, -1.64999988154, 15.3500001691, -2.03999994308, 14.420000242, -2.30999992579, 15.1800002401, -4.27999993607, 16.9200002085, -2.09999997392, 16.4100002357, -3.279999872, 15.3100002164, -2.35999994218, 16.1800001812, 6.66133814775e-16, 15.8700001906, -0.649999931455, 15.2600002015, -0.959999923557, 16.6000000745, -1.23999989465, 16.3600000606, -1.00000007302, 17.6400001144, -1.35000015274, 14.6000001587, -2.71999994248, 13.5000002593, 0.3199999246, 16.3100000688, -1.42999995843, 14.4200001325, -1.10000010207, 17.4800000344, -1.6699999775, 16.130000053, -1.30000016391, 15.79000011, -0.98999997139, 15.3500001222, -3.13999999076, 17.4500001401, -0.21000008896, 16.3200001906, -2.15999999508, 15.2600001709, -1.46999996632, 15.8700001906, 0.649999931455, 16.1600001404, 2.22044604925e-16, 15.2000001252, -0.249999957532, 16.5300001149, -1.38999987304, 16.2500001878, -0.790000140518, 16.1000001512, -1.31000006959, 14.2500002459, -2.30999999434, 14.3900002165, 0.199999940395, 16.6300002423, -1.73999998033, 16.1600001054, -1.12000011533, 15.8700001645, -0.419999969304, 15.7800002021, -1.01000007257, 14.6300002229, -0.48000007093, 14.5300001402, -1.98999997884, 17.5200002033, 0.329999930859, 15.9900002694, -1.18000005677, 15.1500001706, -1.42000012353, 15.2600002015, 0.959999923557, 15.2000001252, 0.249999957532, 15.7600002298, -2.22044604925e-16, 
+
+L3_cHER2K_A_kn
+0.20000000298, 0.600000023842, 0.800000011921, 0.5, 0.600000023842, 0.800000011921, 0.5, 0.20000000298, 0.800000011921, 0.699999988079, 0.300000011921, 0.40000000596, 0.600000023842, 0.20000000298, 0.5, 0.10000000149, 0.10000000149, 0.600000023842, 0.600000023842, 0.899999976158, 0.699999988079, 0.899999976158, 0.800000011921, 0.600000023842, 0.800000011921, 0.800000011921, 0.699999988079, 0.600000023842, 0.899999976158, 0.40000000596, 0.899999976158, 0.699999988079, 0.800000011921, 0.600000023842, 0.20000000298, 0.5, 0.40000000596, 0.5, 0.20000000298, 0.5, 0.5, 0.5, 0.600000023842, 0.20000000298, 0.5, 0.800000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.699999988079, 0.5, 0.40000000596, 0.600000023842, 0.5, 0.5, 0.899999976158, 0.5, 0.699999988079, 0.899999976158, 0.5, 0.800000011921, 0.40000000596, 0.300000011921, 0.40000000596, 0.40000000596, 0.40000000596, 0.899999976158, 0.40000000596, 0.600000023842, 0.699999988079, 0.300000011921, 0.40000000596, 0.699999988079, 0.300000011921, 0.10000000149, 0.300000011921, 0.300000011921, 0.699999988079, 0.20000000298, 0.899999976158, 0.300000011921, 0.300000011921, 0.699999988079, 0.20000000298, 0.40000000596, 0.600000023842, 0.899999976158, 0.600000023842, 0.800000011921, 0.300000011921, 0.600000023842, 0.600000023842, 0.10000000149, 0.20000000298, 0.20000000298, 0.800000011921, 0.40000000596, 0.699999988079, 0.40000000596, 0.10000000149, 0.5, 0.5, 0.20000000298, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.699999988079, 0.20000000298, 0.899999976158, 0.40000000596, 0.10000000149, 0.800000011921, 0.40000000596, 0.20000000298, 0.300000011921, 0.899999976158, 0.300000011921, 0.40000000596, 0.40000000596, 0.600000023842, 0.600000023842, 0.899999976158, 0.600000023842, 0.300000011921, 0.5, 0.600000023842, 0.20000000298, 0.5, 0.699999988079, 0.40000000596, 0.10000000149, 0.40000000596, 0.699999988079, 0.899999976158, 0.40000000596, 0.600000023842, 0.40000000596, 0.40000000596, 0.10000000149, 0.300000011921, 0.899999976158, 0.899999976158, 0.40000000596, 0.10000000149, 0.10000000149, 0.40000000596, 0.10000000149, 0.699999988079, 0.40000000596, 0.899999976158, 0.800000011921, 0.10000000149, 0.5, 0.800000011921, 0.899999976158, 0.10000000149, 0.899999976158, 0.10000000149, 0.800000011921, 0.800000011921, 0.800000011921, 0.600000023842, 0.40000000596, 0.300000011921, 0.699999988079, 0.5, 0.800000011921, 0.899999976158, 0.600000023842, 0.20000000298, 0.800000011921, 0.800000011921, 0.699999988079, 0.5, 0.20000000298, 0.899999976158, 0.10000000149, 0.10000000149, 0.40000000596, 0.300000011921, 0.899999976158, 0.600000023842, 0.600000023842, 0.800000011921, 0.10000000149, 0.600000023842, 0.20000000298, 0.5, 0.899999976158, 0.20000000298, 0.5, 0.600000023842, 0.20000000298, 0.300000011921, 0.40000000596, 0.300000011921, 0.10000000149, 0.5, 0.899999976158, 0.300000011921, 0.300000011921, 0.40000000596, 0.5, 0.899999976158, 0.20000000298, 0.40000000596, 0.699999988079, 0.699999988079, 0.699999988079, 0.20000000298, 0.40000000596, 0.40000000596, 0.899999976158, 0.20000000298, 0.40000000596, 0.10000000149, 0.699999988079, 0.40000000596, 0.800000011921, 0.20000000298, 0.300000011921, 0.699999988079, 0.20000000298, 0.300000011921, 0.699999988079, 0.20000000298, 0.5, 0.699999988079, 0.800000011921, 0.40000000596, 0.5, 0.10000000149, 0.800000011921, 0.899999976158, 0.800000011921, 0.10000000149, 0.5, 0.20000000298, 0.699999988079, 0.10000000149, 0.899999976158, 0.800000011921, 0.899999976158, 0.10000000149, 0.10000000149, 0.300000011921, 0.40000000596, 0.699999988079, 0.899999976158, 0.600000023842, 0.300000011921, 0.40000000596, 0.800000011921, 0.5, 0.5, 0.10000000149, 0.800000011921, 0.10000000149, 0.10000000149, 0.10000000149, 0.10000000149, 0.20000000298, 0.10000000149, 0.899999976158, 0.600000023842, 0.10000000149, 0.899999976158, 0.600000023842, 0.800000011921, 0.40000000596, 0.10000000149, 0.5, 0.20000000298, 0.40000000596, 0.699999988079, 0.300000011921, 0.899999976158, 0.40000000596, 0.899999976158, 0.800000011921, 0.20000000298, 0.5, 0.20000000298, 0.40000000596, 0.300000011921, 0.5, 0.5, 0.300000011921, 0.5, 0.5, 0.600000023842, 0.5, 0.699999988079, 0.10000000149, 0.899999976158, 0.800000011921, 0.800000011921, 0.5, 0.800000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.40000000596, 0.20000000298, 0.699999988079, 0.899999976158, 0.699999988079, 0.5, 0.899999976158, 0.300000011921, 0.300000011921, 0.5, 0.5, 0.699999988079, 0.699999988079, 0.20000000298, 0.40000000596, 0.40000000596, 0.600000023842, 0.899999976158, 0.600000023842, 0.899999976158, 0.699999988079, 0.40000000596, 0.800000011921, 0.600000023842, 0.600000023842, 0.600000023842, 0.20000000298, 0.40000000596, 0.899999976158, 0.899999976158, 0.40000000596, 0.40000000596, 0.40000000596, 0.20000000298, 0.899999976158, 0.699999988079, 0.300000011921, 0.699999988079, 0.10000000149, 0.800000011921, 0.600000023842, 0.40000000596, 0.40000000596, 0.699999988079, 0.600000023842, 0.899999976158, 0.10000000149, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.699999988079, 0.699999988079, 0.10000000149, 0.699999988079, 0.600000023842, 0.600000023842, 0.300000011921, 0.5, 0.699999988079, 0.800000011921, 0.800000011921, 0.699999988079, 0.800000011921, 0.800000011921, 0.20000000298, 0.800000011921, 0.300000011921, 0.899999976158, 0.300000011921, 0.800000011921, 0.20000000298, 0.40000000596, 0.899999976158, 0.40000000596, 0.20000000298, 0.10000000149, 0.699999988079, 0.600000023842, 0.699999988079, 0.5, 0.20000000298, 0.20000000298, 0.600000023842, 0.600000023842, 0.899999976158, 0.899999976158, 0.10000000149, 0.10000000149, 0.40000000596, 0.40000000596, 0.5, 0.20000000298, 0.10000000149, 0.40000000596, 0.10000000149, 0.5, 0.600000023842, 0.20000000298, 0.5, 0.20000000298, 0.699999988079, 0.5, 0.699999988079, 0.800000011921, 0.300000011921, 0.699999988079, 0.20000000298, 0.800000011921, 0.600000023842, 0.10000000149, 0.899999976158, 0.10000000149, 0.10000000149, 0.300000011921, 0.699999988079, 0.699999988079, 0.300000011921, 0.5, 0.800000011921, 0.300000011921, 0.5, 0.5, 0.699999988079, 0.800000011921, 0.20000000298, 0.800000011921, 0.600000023842, 0.800000011921, 0.600000023842, 0.20000000298, 0.40000000596, 0.5, 0.40000000596, 0.10000000149, 0.800000011921, 0.800000011921, 0.10000000149, 0.600000023842, 0.699999988079, 0.899999976158, 0.20000000298, 0.10000000149, 0.5, 0.899999976158, 0.20000000298, 0.300000011921, 0.800000011921, 0.40000000596, 0.20000000298, 0.699999988079, 0.5, 0.899999976158, 0.20000000298, 0.800000011921, 0.20000000298, 0.600000023842, 0.300000011921, 0.800000011921, 0.300000011921, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.800000011921, 0.800000011921, 0.10000000149, 0.10000000149, 0.699999988079, 0.300000011921, 0.800000011921, 0.699999988079, 0.300000011921, 0.20000000298, 0.20000000298, 0.600000023842, 0.10000000149, 0.300000011921, 0.899999976158, 0.800000011921, 0.5, 0.20000000298, 0.300000011921, 0.5, 0.800000011921, 0.899999976158, 0.300000011921, 0.899999976158, 0.800000011921, 0.5, 0.10000000149, 0.10000000149, 0.5, 0.5, 0.899999976158, 0.300000011921, 0.800000011921, 0.800000011921, 0.300000011921, 0.699999988079, 0.300000011921, 0.699999988079, 0.699999988079, 0.899999976158, 0.20000000298, 0.20000000298, 0.5, 0.800000011921, 0.40000000596, 0.20000000298, 0.20000000298, 0.5, 0.899999976158, 0.600000023842, 0.800000011921, 0.20000000298, 0.699999988079, 0.5, 0.300000011921, 0.20000000298, 0.5, 0.5, 0.699999988079, 0.5, 0.600000023842, 0.10000000149, 0.300000011921, 0.5, 0.10000000149, 0.5, 0.300000011921, 0.20000000298, 0.800000011921, 0.800000011921, 0.899999976158, 0.600000023842, 0.899999976158, 0.10000000149, 0.300000011921, 0.699999988079, 0.40000000596, 
+
+L3_cHER2K_B_kn
+0.800000011921, 0.5, 0.10000000149, 0.5, 0.300000011921, 0.600000023842, 0.899999976158, 0.20000000298, 0.300000011921, 0.20000000298, 0.600000023842, 0.699999988079, 0.699999988079, 0.300000011921, 0.800000011921, 0.699999988079, 0.10000000149, 0.899999976158, 0.699999988079, 0.800000011921, 0.20000000298, 0.899999976158, 0.10000000149, 0.699999988079, 0.600000023842, 0.40000000596, 0.20000000298, 0.600000023842, 0.10000000149, 0.5, 0.20000000298, 0.10000000149, 0.300000011921, 0.10000000149, 0.20000000298, 0.300000011921, 0.5, 0.5, 0.300000011921, 0.600000023842, 0.899999976158, 0.800000011921, 0.699999988079, 0.40000000596, 0.699999988079, 0.600000023842, 0.699999988079, 0.600000023842, 0.20000000298, 0.5, 0.800000011921, 0.40000000596, 0.5, 0.899999976158, 0.10000000149, 0.300000011921, 0.699999988079, 0.10000000149, 0.20000000298, 0.20000000298, 0.899999976158, 0.300000011921, 0.10000000149, 0.20000000298, 0.800000011921, 0.699999988079, 0.20000000298, 0.600000023842, 0.10000000149, 0.300000011921, 0.300000011921, 0.600000023842, 0.10000000149, 0.899999976158, 0.40000000596, 0.800000011921, 0.899999976158, 0.5, 0.800000011921, 0.600000023842, 0.5, 0.40000000596, 0.800000011921, 0.20000000298, 0.800000011921, 0.20000000298, 0.800000011921, 0.899999976158, 0.5, 0.5, 0.600000023842, 0.20000000298, 0.600000023842, 0.899999976158, 0.899999976158, 0.5, 0.899999976158, 0.20000000298, 0.699999988079, 0.10000000149, 0.800000011921, 0.10000000149, 0.600000023842, 0.5, 0.899999976158, 0.899999976158, 0.10000000149, 0.600000023842, 0.699999988079, 0.800000011921, 0.800000011921, 0.20000000298, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 0.800000011921, 0.899999976158, 0.20000000298, 0.10000000149, 0.899999976158, 0.699999988079, 0.10000000149, 0.5, 0.600000023842, 0.300000011921, 0.20000000298, 0.20000000298, 0.40000000596, 0.10000000149, 0.5, 0.20000000298, 0.600000023842, 0.20000000298, 0.600000023842, 0.5, 0.20000000298, 0.20000000298, 0.800000011921, 0.20000000298, 0.600000023842, 0.899999976158, 0.800000011921, 0.10000000149, 0.899999976158, 0.10000000149, 0.600000023842, 0.5, 0.40000000596, 0.899999976158, 0.300000011921, 0.10000000149, 0.600000023842, 0.10000000149, 0.10000000149, 0.600000023842, 0.20000000298, 0.800000011921, 0.699999988079, 0.600000023842, 0.300000011921, 0.600000023842, 0.300000011921, 0.600000023842, 0.20000000298, 0.5, 0.20000000298, 0.5, 0.20000000298, 0.20000000298, 0.800000011921, 0.800000011921, 0.10000000149, 0.40000000596, 0.5, 0.20000000298, 0.5, 0.20000000298, 0.5, 0.800000011921, 0.600000023842, 0.40000000596, 0.699999988079, 0.600000023842, 0.300000011921, 0.5, 0.899999976158, 0.699999988079, 0.300000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.699999988079, 0.800000011921, 0.300000011921, 0.20000000298, 0.600000023842, 0.800000011921, 0.20000000298, 0.20000000298, 0.300000011921, 0.5, 0.600000023842, 0.600000023842, 0.5, 0.600000023842, 0.899999976158, 0.20000000298, 0.800000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.600000023842, 0.10000000149, 0.40000000596, 0.600000023842, 0.800000011921, 0.899999976158, 0.20000000298, 0.10000000149, 0.600000023842, 0.20000000298, 0.699999988079, 0.5, 0.5, 0.800000011921, 0.699999988079, 0.5, 0.600000023842, 0.300000011921, 0.10000000149, 0.800000011921, 0.600000023842, 0.40000000596, 0.600000023842, 0.899999976158, 0.800000011921, 0.20000000298, 0.20000000298, 0.20000000298, 0.5, 0.10000000149, 0.800000011921, 0.899999976158, 0.5, 0.600000023842, 0.600000023842, 0.699999988079, 0.10000000149, 0.600000023842, 0.699999988079, 0.800000011921, 0.300000011921, 0.300000011921, 0.600000023842, 0.20000000298, 0.10000000149, 0.600000023842, 0.699999988079, 0.300000011921, 0.300000011921, 0.300000011921, 0.899999976158, 0.300000011921, 0.5, 0.699999988079, 0.300000011921, 0.699999988079, 0.5, 0.699999988079, 0.800000011921, 0.10000000149, 0.899999976158, 0.800000011921, 0.300000011921, 0.20000000298, 0.699999988079, 0.600000023842, 0.600000023842, 0.40000000596, 0.300000011921, 0.800000011921, 0.899999976158, 0.899999976158, 0.800000011921, 0.300000011921, 0.800000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.20000000298, 0.5, 0.5, 0.40000000596, 0.10000000149, 0.40000000596, 0.699999988079, 0.300000011921, 0.899999976158, 0.699999988079, 0.600000023842, 0.600000023842, 0.800000011921, 0.20000000298, 0.899999976158, 0.899999976158, 0.800000011921, 0.899999976158, 0.20000000298, 0.600000023842, 0.800000011921, 0.699999988079, 0.800000011921, 0.20000000298, 0.10000000149, 0.10000000149, 0.40000000596, 0.600000023842, 0.10000000149, 0.600000023842, 0.40000000596, 0.20000000298, 0.40000000596, 0.10000000149, 0.20000000298, 0.800000011921, 0.800000011921, 0.899999976158, 0.40000000596, 0.800000011921, 0.5, 0.20000000298, 0.20000000298, 0.699999988079, 0.5, 0.600000023842, 0.40000000596, 0.600000023842, 0.899999976158, 0.699999988079, 0.699999988079, 0.600000023842, 0.20000000298, 0.800000011921, 0.800000011921, 0.40000000596, 0.10000000149, 0.600000023842, 0.699999988079, 0.40000000596, 0.600000023842, 0.300000011921, 0.300000011921, 0.899999976158, 0.699999988079, 0.20000000298, 0.20000000298, 0.800000011921, 0.600000023842, 0.699999988079, 0.5, 0.10000000149, 0.300000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.300000011921, 0.5, 0.300000011921, 0.10000000149, 0.600000023842, 0.600000023842, 0.300000011921, 0.600000023842, 0.699999988079, 0.20000000298, 0.300000011921, 0.800000011921, 0.800000011921, 0.600000023842, 0.5, 0.699999988079, 0.600000023842, 0.899999976158, 0.899999976158, 0.600000023842, 0.800000011921, 0.699999988079, 0.40000000596, 0.600000023842, 0.300000011921, 0.10000000149, 0.600000023842, 0.300000011921, 0.300000011921, 0.40000000596, 0.300000011921, 0.600000023842, 0.20000000298, 0.10000000149, 0.10000000149, 0.899999976158, 0.300000011921, 0.10000000149, 0.600000023842, 0.699999988079, 0.300000011921, 0.300000011921, 0.5, 0.10000000149, 0.699999988079, 0.40000000596, 0.600000023842, 0.800000011921, 0.10000000149, 0.300000011921, 0.600000023842, 0.40000000596, 0.10000000149, 0.699999988079, 0.600000023842, 0.600000023842, 0.5, 0.5, 0.699999988079, 0.5, 0.800000011921, 0.699999988079, 0.5, 0.699999988079, 0.10000000149, 0.40000000596, 0.40000000596, 0.40000000596, 0.20000000298, 0.600000023842, 0.699999988079, 0.5, 0.5, 0.20000000298, 0.600000023842, 0.300000011921, 0.800000011921, 0.699999988079, 0.600000023842, 0.600000023842, 0.800000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.800000011921, 0.5, 0.899999976158, 0.600000023842, 0.600000023842, 0.800000011921, 0.600000023842, 0.10000000149, 0.899999976158, 0.300000011921, 0.800000011921, 0.10000000149, 0.10000000149, 0.10000000149, 0.5, 0.600000023842, 0.10000000149, 0.300000011921, 0.600000023842, 0.600000023842, 0.699999988079, 0.10000000149, 0.899999976158, 0.5, 0.20000000298, 0.699999988079, 0.699999988079, 0.10000000149, 0.40000000596, 0.899999976158, 0.300000011921, 0.10000000149, 0.5, 0.699999988079, 0.800000011921, 0.300000011921, 0.699999988079, 0.5, 0.20000000298, 0.20000000298, 0.899999976158, 0.20000000298, 0.20000000298, 0.5, 0.899999976158, 0.20000000298, 0.20000000298, 0.899999976158, 0.800000011921, 0.10000000149, 0.699999988079, 0.699999988079, 0.5, 0.699999988079, 0.600000023842, 0.20000000298, 0.800000011921, 0.10000000149, 0.600000023842, 0.300000011921, 0.10000000149, 0.899999976158, 0.800000011921, 0.899999976158, 0.699999988079, 0.40000000596, 0.10000000149, 0.300000011921, 0.10000000149, 0.300000011921, 0.5, 0.800000011921, 0.10000000149, 0.5, 0.10000000149, 0.40000000596, 0.699999988079, 0.40000000596, 0.699999988079, 0.300000011921, 0.600000023842, 0.800000011921, 0.20000000298, 0.10000000149, 0.800000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.300000011921, 0.600000023842, 0.300000011921, 0.600000023842, 0.800000011921, 0.899999976158, 
+
+L3_cHER2K_o_H
+15.859999966, -5.55111512313e-16, 17.8500001632, 1.51999998197, 18.5300001, 1.91999987021, 16.4000000961, 0.510000042766, 16.0600000666, -2.25000000373, 16.7900001815, 1.56000006512, 16.8700002226, 1.97999996588, 16.9800000806, -2.21999998346, 14.8100001702, -1.24999989867, 18.5500001647, 2.48999998704, 15.9700000982, 3.18999999374, 15.0500002749, 1.75999997348, 16.1900002068, 1.30999995336, 17.5400001889, 0.110000080019, 16.0200000677, 1.52000006095, 17.610000042, 1.73999997959, 16.5500001557, 0.409999994338, 17.8500001632, -1.51999998197, 15.200000225, -6.66133814775e-16, 17.5800001186, 1.29999991804, 17.3500001654, -0.819999829978, 14.9700002174, -1.97000008926, 17.8000001989, 0.700000106543, 16.800000266, 0.470000004321, 18.3000000894, -1.96999984339, 13.5900002173, -0.969999910444, 18.9800002512, 1.03000004411, 15.7300000583, 0.64000004366, 15.6400002508, 1.25000000596, 14.8700002539, -0.4799998869, 18.0800001626, 0.340000028759, 14.5700001481, -0.469999976754, 17.4600001687, -0.160000004023, 16.4600002402, -2.60999979541, 18.5300001, -1.91999987021, 17.5800001186, -1.29999991804, 19.1600002104, 8.881784197e-16, 17.380000217, -1.45999976933, 16.4900001755, -2.0999999918, 18.0400001383, 0.25000019148, 18.0200002457, 0.620000099689, 17.4800001998, -2.729999796, 15.8500001676, -1.10999983266, 19.2500002876, 0.270000271797, 17.9500000998, 1.43000007465, 15.9700003172, 0.100000120699, 16.9200003143, -0.589999916255, 20.4300002296, -0.409999785721, 15.4200000893, 1.49999998435, 19.090000145, -0.47999988094, 17.7000002339, -2.479999796, 16.4000000961, -0.510000042766, 17.3500001654, 0.819999829978, 17.380000217, 1.45999976933, 16.9200001109, -5.55111512313e-17, 15.580000132, -0.980000166297, 17.8900001763, 1.77999991074, 17.070000166, 1.8499999404, 17.6900000183, -1.49999996498, 14.1200001809, 1.04999990612, 17.6600002909, 2.44999989197, 16.5600000547, 4.01999978378, 14.9600002193, 2.55999986768, 15.180000246, 1.17999992266, 16.9900002329, 0.989999990761, 14.6500001848, 1.29999990687, 17.2000002585, 0.139999867827, 17.2100001195, -0.349999937415, 16.0600000666, 2.25000000373, 14.9700002174, 1.97000008926, 16.4900001755, 2.0999999918, 15.580000132, 0.980000166297, 13.4600002134, -6.66133814775e-16, 16.8200001429, 3.33000012085, 15.8500002503, 2.80000004992, 17.0600000562, 0.770000109375, 12.5100002104, 1.01000003904, 17.8700002174, 3.84000012934, 14.5000000693, 3.75999998465, 13.2800002475, 4.22000001922, 14.350000257, 1.41999999389, 16.9900002858, 2.76000007108, 13.3000001416, 2.38000001207, 16.6600002253, 2.30000008419, 15.5100000837, 1.50000014529, 16.7900001815, -1.56000006512, 17.8000001989, -0.700000106543, 18.0400001383, -0.25000019148, 17.8900001763, -1.77999991074, 16.8200001429, -3.33000012085, 16.6800002602, 4.4408920985e-16, 17.7300002944, 0.489999949038, 18.6200001317, -2.20000006109, 15.100000196, -1.20999995634, 19.1200002353, 0.919999985695, 16.5500000782, 1.46999992609, 15.8800002669, 0.809999952614, 17.3900001815, 0.089999987781, 19.2000002086, -1.38999996692, 15.2100001307, 0.819999958873, 17.8300001685, -2.30999999061, 16.980000249, -1.5600000219, 16.8700002226, -1.97999996588, 16.800000266, -0.470000004321, 18.0200002457, -0.620000099689, 17.070000166, -1.8499999404, 15.8500002503, -2.80000004992, 17.7300002944, -0.489999949038, 17.6000003487, 4.4408920985e-16, 18.4900001748, -2.31999989405, 14.8100002372, -0.959999985397, 18.9600003318, 0.60000006333, 16.5800001894, 2.62999990925, 15.5600003102, 0.910000057667, 16.4000002958, 0.139999992996, 18.7500002705, 0.070000037849, 15.4200001466, 1.23999991998, 19.6800001723, 0.0599999846518, 17.4100002462, -1.23999992147, 16.9800000806, 2.21999998346, 18.3000000894, 1.96999984339, 17.4800001998, 2.729999796, 17.6900000183, 1.49999996498, 17.0600000562, -0.770000109375, 18.6200001317, 2.20000006109, 18.4900001748, 2.31999989405, 16.9200000438, 5.55111512313e-16, 14.0200001496, 0.969999976009, 18.9700001474, 4.84999995083, 17.4500001125, 5.56999986202, 15.7600002193, 3.82999999866, 16.2700001884, 1.7899999699, 18.5600001106, 4.19999999255, 14.3800001097, 2.45999992803, 19.2600000964, 1.78999991179, 17.3900002106, 1.03000002697, 14.8100001702, 1.24999989867, 13.5900002173, 0.969999910444, 15.8500001676, 1.10999983266, 14.1200001809, -1.04999990612, 12.5100002104, -1.01000003904, 15.100000196, 1.20999995634, 14.8100002372, 0.959999985397, 14.0200001496, -0.969999976009, 12.6600002044, -4.4408920985e-16, 16.7100001724, 2.42999994949, 14.2800001104, 3.22999992639, 13.2100002469, 1.72000000432, 13.550000225, 0.789999952763, 15.6000003055, 1.79000000268, 12.8700001645, 2.18999997213, 15.1400002038, 0.580000056028, 15.5500001729, 0.420000021458, 18.5500001647, -2.48999998704, 18.9800002512, -1.03000004411, 19.2500002876, -0.270000271797, 17.6600002909, -2.44999989197, 17.8700002174, -3.84000012934, 19.1200002353, -0.919999985695, 18.9600003318, -0.60000006333, 18.9700001474, -4.84999995083, 16.7100001724, -2.42999994949, 20.8600003326, 1.22124532709e-15, 18.9200000393, 1.76999993727, 18.3700002867, 1.07000003189, 17.1700002919, -1.37000004157, 20.5400002672, -0.450000008196, 16.150000117, 0.399999909103, 18.9900001748, -1.1300000605, 18.2800002527, -2.08999992818, 15.9700000982, -3.18999999374, 15.7300000583, -0.64000004366, 17.9500000998, -1.43000007465, 16.5600000547, -4.01999978378, 14.5000000693, -3.75999998465, 16.5500000782, -1.46999992609, 16.5800001894, -2.62999990925, 17.4500001125, -5.56999986202, 14.2800001104, -3.22999992639, 18.9200000393, -1.76999993727, 16.4400000206, -2.22044604925e-16, 15.3500002496, -1.20999992579, 15.7200001571, -2.02999998674, 18.2600000942, -1.56999985009, 14.6000001311, -0.410000036061, 17.0500001088, -3.27999988765, 15.7000002146, -2.85999994516, 15.0500002749, -1.75999997348, 15.6400002508, -1.25000000596, 15.9700003172, -0.100000120699, 14.9600002193, -2.55999986768, 13.2800002475, -4.22000001922, 15.8800002669, -0.809999952614, 15.5600003102, -0.910000057667, 15.7600002193, -3.82999999866, 13.2100002469, -1.72000000432, 18.3700002867, -1.07000003189, 15.3500002496, 1.20999992579, 13.3600003415, 4.4408920985e-16, 15.5900003238, -0.740000070482, 16.2300003354, -1.44999987185, 13.1600002357, 0.509999969006, 16.1100002395, -1.86000002936, 15.5900003253, -1.20999999359, 16.1900002068, -1.30999995336, 14.8700002539, 0.4799998869, 16.9200003143, 0.589999916255, 15.180000246, -1.17999992266, 14.350000257, -1.41999999389, 17.3900001815, -0.089999987781, 16.4000002958, -0.139999992996, 16.2700001884, -1.7899999699, 13.550000225, -0.789999952763, 17.1700002919, 1.37000004157, 15.7200001571, 2.02999998674, 15.5900003238, 0.740000070482, 14.340000326, -4.4408920985e-16, 18.1500001892, 2.36000006065, 13.9700002539, 2.08999995574, 17.3200002353, -0.0600000487268, 15.8200002651, -0.21999991864, 17.5400001889, -0.110000080019, 18.0800001626, -0.340000028759, 20.4300002296, 0.409999785721, 16.9900002329, -0.989999990761, 16.9900002858, -2.76000007108, 19.2000002086, 1.38999996692, 18.7500002705, -0.070000037849, 18.5600001106, -4.19999999255, 15.6000003055, -1.79000000268, 20.5400002672, 0.450000008196, 18.2600000942, 1.56999985009, 16.2300003354, 1.44999987185, 18.1500001892, -2.36000006065, 17.8400002933, 0.0, 16.8000001617, 1.41999987096, 18.8500002451, -1.4100000003, 18.3500001989, -1.07000002071, 16.0200000677, -1.52000006095, 14.5700001481, 0.469999976754, 15.4200000893, -1.49999998435, 14.6500001848, -1.29999990687, 13.3000001416, -2.38000001207, 15.2100001307, -0.819999958873, 15.4200001466, -1.23999991998, 14.3800001097, -2.45999992803, 12.8700001645, -2.18999997213, 16.150000117, -0.399999909103, 14.6000001311, 0.410000036061, 13.1600002357, -0.509999969006, 13.9700002539, -2.08999995574, 16.8000001617, -1.41999987096, 12.6800001454, 4.4408920985e-16, 15.5700001809, -1.70999992356, 14.1200001392, -1.79999990985, 17.610000042, -1.73999997959, 17.4600001687, 0.160000004023, 19.090000145, 0.47999988094, 17.2000002585, -0.139999867827, 16.6600002253, -2.30000008419, 17.8300001685, 2.30999999061, 19.6800001723, -0.0599999846518, 19.2600000964, -1.78999991179, 15.1400002038, -0.580000056028, 18.9900001748, 1.1300000605, 17.0500001088, 3.27999988765, 16.1100002395, 1.86000002936, 17.3200002353, 0.0600000487268, 18.8500002451, 1.4100000003, 15.5700001809, 1.70999992356, 19.5400002366, 1.33226762955e-15, 17.0800002043, -1.17999990031, 16.5500001557, -0.409999994338, 16.4600002402, 2.60999979541, 17.7000002339, 2.479999796, 17.2100001195, 0.349999937415, 15.5100000837, -1.50000014529, 16.980000249, 1.5600000219, 17.4100002462, 1.23999992147, 17.3900002106, -1.03000002697, 15.5500001729, -0.420000021458, 18.2800002527, 2.08999992818, 15.7000002146, 2.85999994516, 15.5900003253, 1.20999999359, 15.8200002651, 0.21999991864, 18.3500001989, 1.07000002071, 14.1200001392, 1.79999990985, 17.0800002043, 1.17999990031, 16.0200002554, 8.881784197e-16, 
+
+L3_zHER2K_A_nk
+0.1, 0.6, 0.1, 0.8, 0.8, 0.1, 0.9, 0.2, 0.1, 0.2, 0.4, 0.7, 0.6, 0.5, 0.6, 0.5, 0.6, 0.4, 0.3, 0.1, 0.1, 0.7, 0.4, 0.5, 0.7, 0.7, 0.6, 0.5, 0.5, 0.3, 0.7, 0.3, 0.8, 0.7, 0.8, 0.8, 0.3, 0.2, 0.8, 0.5, 0.5, 0.1, 0.5, 0.9, 0.2, 0.8, 0.2, 0.4, 0.7, 0.5, 0.8, 0.5, 0.3, 0.4, 0.7, 0.2, 0.4, 0.3, 0.6, 0.5, 0.3, 0.8, 0.1, 0.1, 0.3, 0.9, 0.3, 0.4, 0.1, 0.8, 0.2, 0.5, 0.2, 0.3, 0.1, 0.8, 0.4, 0.2, 0.8, 0.8, 0.8, 0.1, 0.6, 0.4, 0.6, 0.5, 0.1, 0.1, 0.3, 0.8, 0.7, 0.9, 0.9, 0.6, 0.9, 0.5, 0.7, 0.3, 0.7, 0.8, 0.7, 0.3, 0.1, 0.8, 0.7, 0.2, 0.9, 0.5, 0.5, 0.3, 0.1, 0.8, 0.2, 0.6, 0.3, 0.7, 0.2, 0.5, 0.1, 0.7, 0.9, 0.3, 0.1, 0.9, 0.4, 0.7, 0.9, 0.9, 0.5, 0.7, 0.6, 0.2, 0.1, 0.2, 0.4, 0.8, 0.2, 0.7, 0.3, 0.5, 0.6, 0.8, 0.2, 0.6, 0.7, 0.2, 0.1, 0.4, 0.5, 0.7, 0.2, 0.1, 0.8, 0.1, 0.3, 0.5, 0.5, 0.2, 0.7, 0.5, 0.1, 0.5, 0.4, 0.9, 0.1, 0.5, 0.3, 0.4, 0.3, 0.9, 0.8, 0.5, 0.7, 0.4, 0.2, 0.3, 0.4, 0.9, 0.7, 0.8, 0.3, 0.7, 0.8, 0.8, 0.1, 0.9, 0.1, 0.4, 0.8, 0.2, 0.8, 0.6, 0.4, 0.8, 0.5, 0.1, 0.3, 0.7, 0.3, 0.4, 0.4, 0.2, 0.3, 0.6, 0.2, 0.4, 0.9, 0.6, 0.6, 0.4, 0.3, 0.7, 0.3, 0.6, 0.7, 0.6, 0.1, 0.4, 0.1, 0.9, 0.3, 0.2, 0.3, 0.3, 0.2, 0.4, 0.7, 0.2, 0.2, 0.9, 0.8, 0.7, 0.1, 0.6, 0.7, 0.7, 0.1, 0.7, 0.7, 0.4, 0.3, 0.3, 0.8, 0.5, 0.7, 0.4, 0.4, 0.7, 0.8, 0.4, 0.2, 0.5, 0.9, 0.8, 0.6, 0.8, 0.9, 0.1, 0.5, 0.2, 0.7, 0.7, 0.1, 0.3, 0.7, 0.2, 0.8, 0.3, 0.8, 0.8, 0.5, 0.7, 0.6, 0.8, 0.5, 0.4, 0.5, 0.2, 0.4, 0.3, 0.1, 0.3, 0.7, 0.2, 0.2, 0.6, 0.6, 0.3, 0.4, 0.2, 0.8, 0.3, 0.2, 0.3, 0.3, 0.8, 0.6, 0.3, 0.9, 0.4, 0.3, 0.9, 0.6, 0.7, 0.4, 0.9, 0.2, 0.2, 0.4, 0.5, 0.2, 0.3, 0.9, 0.7, 0.2, 0.7, 0.5, 0.5, 0.6, 0.6, 0.3, 0.7, 0.4, 0.1, 0.9, 0.1, 0.9, 0.7, 0.9, 0.2, 0.1, 0.3, 0.4, 0.7, 0.9, 0.1, 0.5, 0.1, 0.3, 0.4, 0.9, 0.2, 0.4, 0.7, 0.5, 0.9, 0.3, 0.1, 0.6, 0.2, 0.9, 0.3, 0.8, 0.9, 0.7, 0.2, 0.7, 0.7, 0.8, 0.6, 0.8, 0.1, 0.2, 0.6, 0.4, 0.2, 0.7, 0.6, 0.3, 0.7, 0.9, 0.6, 0.6, 0.9, 0.4, 0.5, 0.6, 0.3, 0.1, 0.7, 0.5, 0.3, 0.3, 0.3, 0.7, 0.5, 0.4, 0.4, 0.7, 0.7, 0.3, 0.1, 0.2, 0.1, 0.4, 0.7, 0.5, 0.8, 0.7, 0.5, 0.6, 0.5, 0.8, 0.5, 0.9, 0.7, 0.6, 0.1, 0.3, 0.7, 0.4, 0.9, 0.8, 0.5, 0.7, 0.6, 0.8, 0.3, 0.9, 0.1, 0.5, 0.3, 0.2, 0.7, 0.5, 0.7, 0.6, 0.4, 0.6, 0.5, 0.7, 0.4, 0.9, 0.4, 0.8, 0.5, 0.3, 0.4, 0.7, 0.2, 0.1, 0.6, 0.4, 0.8, 0.8, 0.7, 0.8, 0.6, 0.5, 0.2, 0.9, 0.9, 0.4, 0.7, 0.5, 0.3, 0.4, 0.5, 0.8, 0.2, 0.3, 0.1, 0.6, 0.5, 0.1, 0.9, 0.6, 0.8, 0.6, 0.4, 0.2, 0.5, 0.4, 0.1, 0.6, 0.4, 0.5, 0.8, 0.5, 0.3, 0.7, 0.4, 0.3, 0.8, 0.2, 0.5, 0.6, 0.4, 0.9, 0.2, 0.6, 0.6, 0.2, 0.3, 0.3, 0.9, 0.4, 0.4, 0.2, 0.1, 0.7, 0.1, 0.8, 0.6, 0.6, 0.4, 0.9, 0.7, 0.8, 0.5, 0.7, 0.1, 0.3, 0.4, 0.4, 0.7, 0.9, 0.6, 0.4, 0.3, 0.4, 0.1, 0.8, 0.1, 0.8, 0.8, 0.7, 0.7, 0.1, 0.6, 0.4, 0.8, 0.2, 0.8, 0.9, 0.9, 0.6, 0.9, 0.6, 0.3, 0.6, 0.9, 0.1, 0.5, 
+
+L3_zHER2K_B_nk
+0.1, 0.1, 0.2, 0.5, 0.9, 0.3, 0.7, 0.2, 0.1, 0.8, 0.1, 0.7, 0.1, 0.5, 0.9, 0.8, 0.7, 0.8, 0.5, 0.9, 0.6, 0.9, 0.8, 0.5, 0.8, 0.8, 0.3, 0.6, 0.6, 0.4, 0.9, 0.9, 0.7, 0.6, 0.9, 0.3, 0.6, 0.3, 0.5, 0.7, 0.9, 0.9, 0.2, 0.9, 0.6, 0.8, 0.6, 0.5, 0.7, 0.5, 0.2, 0.5, 0.1, 0.1, 0.2, 0.1, 0.1, 0.3, 0.7, 0.5, 0.4, 0.4, 0.1, 0.2, 0.3, 0.1, 0.2, 0.1, 0.1, 0.3, 0.8, 0.2, 0.5, 0.7, 0.9, 0.5, 0.4, 0.4, 0.9, 0.1, 0.1, 0.4, 0.4, 0.6, 0.9, 0.3, 0.7, 0.6, 0.2, 0.7, 0.4, 0.7, 0.7, 0.1, 0.9, 0.5, 0.6, 0.6, 0.4, 0.7, 0.1, 0.1, 0.1, 0.1, 0.9, 0.7, 0.8, 0.1, 0.3, 0.4, 0.1, 0.9, 0.2, 0.5, 0.2, 0.4, 0.1, 0.1, 0.4, 0.2, 0.6, 0.1, 0.7, 0.9, 0.9, 0.7, 0.6, 0.7, 0.4, 0.5, 0.8, 0.7, 0.4, 0.1, 0.1, 0.8, 0.2, 0.7, 0.5, 0.4, 0.1, 0.4, 0.3, 0.5, 0.5, 0.3, 0.7, 0.2, 0.7, 0.7, 0.1, 0.2, 0.8, 0.6, 0.3, 0.4, 0.8, 0.8, 0.3, 0.8, 0.9, 0.6, 0.4, 0.7, 0.7, 0.7, 0.7, 0.5, 0.4, 0.7, 0.1, 0.8, 0.3, 0.2, 0.6, 0.4, 0.7, 0.2, 0.7, 0.8, 0.7, 0.8, 0.6, 0.2, 0.8, 0.6, 0.3, 0.3, 0.9, 0.2, 0.4, 0.2, 0.8, 0.8, 0.4, 0.6, 0.3, 0.7, 0.2, 0.4, 0.5, 0.4, 0.4, 0.7, 0.5, 0.6, 0.2, 0.6, 0.3, 0.5, 0.2, 0.9, 0.8, 0.9, 0.4, 0.7, 0.6, 0.8, 0.7, 0.1, 0.7, 0.3, 0.8, 0.1, 0.1, 0.7, 0.2, 0.9, 0.5, 0.6, 0.1, 0.3, 0.1, 0.6, 0.9, 0.3, 0.9, 0.4, 0.5, 0.2, 0.3, 0.9, 0.4, 0.3, 0.1, 0.7, 0.4, 0.8, 0.9, 0.7, 0.3, 0.5, 0.9, 0.5, 0.3, 0.1, 0.7, 0.6, 0.6, 0.8, 0.7, 0.9, 0.8, 0.5, 0.4, 0.7, 0.7, 0.2, 0.1, 0.8, 0.9, 0.7, 0.1, 0.8, 0.9, 0.1, 0.7, 0.3, 0.3, 0.4, 0.6, 0.5, 0.4, 0.9, 0.5, 0.1, 0.8, 0.1, 0.9, 0.6, 0.9, 0.9, 0.3, 0.1, 0.1, 0.8, 0.3, 0.9, 0.1, 0.8, 0.9, 0.1, 0.5, 0.5, 0.6, 0.9, 0.7, 0.2, 0.3, 0.5, 0.1, 0.5, 0.9, 0.2, 0.5, 0.9, 0.4, 0.9, 0.3, 0.4, 0.5, 0.7, 0.2, 0.6, 0.7, 0.3, 0.9, 0.4, 0.7, 0.1, 0.3, 0.2, 0.2, 0.6, 0.8, 0.8, 0.7, 0.3, 0.3, 0.9, 0.5, 0.4, 0.1, 0.8, 0.1, 0.7, 0.6, 0.3, 0.5, 0.6, 0.3, 0.4, 0.8, 0.9, 0.2, 0.7, 0.9, 0.2, 0.8, 0.3, 0.2, 0.8, 0.5, 0.5, 0.8, 0.6, 0.2, 0.4, 0.2, 0.1, 0.6, 0.8, 0.3, 0.1, 0.4, 0.4, 0.2, 0.6, 0.2, 0.8, 0.3, 0.2, 0.2, 0.2, 0.5, 0.6, 0.8, 0.7, 0.1, 0.2, 0.1, 0.8, 0.2, 0.1, 0.6, 0.7, 0.8, 0.6, 0.2, 0.5, 0.6, 0.3, 0.8, 0.3, 0.2, 0.4, 0.5, 0.2, 0.4, 0.2, 0.2, 0.7, 0.7, 0.2, 0.9, 0.8, 0.4, 0.8, 0.2, 0.2, 0.1, 0.7, 0.8, 0.5, 0.3, 0.6, 0.9, 0.4, 0.5, 0.9, 0.3, 0.8, 0.8, 0.3, 0.8, 0.5, 0.7, 0.1, 0.4, 0.5, 0.3, 0.2, 0.5, 0.9, 0.4, 0.2, 0.8, 0.9, 0.8, 0.8, 0.9, 0.2, 0.4, 0.9, 0.3, 0.6, 0.8, 0.9, 0.3, 0.5, 0.7, 0.4, 0.8, 0.3, 0.2, 0.1, 0.6, 0.9, 0.2, 0.2, 0.6, 0.7, 0.6, 0.3, 0.2, 0.6, 0.7, 0.8, 0.4, 0.1, 0.9, 0.2, 0.6, 0.4, 0.1, 0.4, 0.2, 0.7, 0.6, 0.3, 0.6, 0.2, 0.6, 0.5, 0.8, 0.6, 0.8, 0.4, 0.4, 0.7, 0.6, 0.6, 0.2, 0.1, 0.2, 0.2, 0.2, 0.2, 0.4, 0.6, 0.8, 0.4, 0.9, 0.5, 0.9, 0.2, 0.3, 0.3, 0.6, 0.1, 0.4, 0.4, 0.8, 0.9, 0.2, 0.8, 0.9, 0.2, 0.5, 0.3, 0.9, 0.5, 0.4, 0.6, 0.2, 0.9, 0.3, 0.6, 0.2, 0.7, 0.3, 0.6, 0.9, 0.9, 
+
+L3_zHER2K_C_nn
+0.4, 0.0, 0.7, 0.8, 0.5, 0.3, 0.8, 0.2, 0.8, 0.7, 0.2, 0.2, 0.3, 0.8, 0.7, 0.3, 0.6, 0.9, 0.8, 0.3, 0.7, 0.9, 0.1, 0.2, 0.1, 0.4, 0.3, 0.1, 0.3, 0.3, 0.4, 0.1, 0.8, 0.1, 0.7, -0.8, 0.1, 0.0, 0.1, 0.6, 0.6, 0.9, 0.4, 0.8, 0.5, 0.1, 0.2, 0.8, 0.6, 0.4, 0.6, 0.2, 0.4, 0.7, 0.8, 0.3, 0.2, 0.7, 0.2, 0.9, 0.3, 0.9, 0.4, 0.8, 0.5, 0.3, 0.8, 0.3, 0.5, -0.3, 0.1, -0.6, 0.4, 0.0, 0.9, 0.4, 0.3, 0.8, 0.5, 0.2, 0.5, 0.5, 0.4, 0.4, 0.8, 0.6, 0.4, 0.9, 0.6, 0.6, 0.1, 0.3, 0.9, 0.2, 0.3, 0.6, 0.1, 0.7, 0.7, 0.3, 0.2, 0.7, 0.8, -0.2, 0.6, -0.9, 0.9, -0.4, 0.2, 0.0, 0.6, 0.2, 0.7, 0.4, 0.8, 0.1, 0.8, 0.7, 0.2, 0.1, 0.9, 0.7, 0.4, 0.2, 0.4, 0.3, 0.5, 0.5, 0.4, 0.3, 0.3, 0.5, 0.2, 0.3, 0.4, 0.7, 0.8, -0.7, 0.4, -0.8, 0.3, -0.8, 0.6, -0.2, 0.6, 0.0, 0.2, 0.9, 0.6, 0.1, 0.7, 0.4, 0.7, 0.4, 0.3, 0.8, 0.3, 0.6, 0.1, 0.8, 0.1, 0.4, 0.9, 0.7, 0.2, 0.2, 0.1, 0.6, 0.7, 0.4, 0.2, -0.2, 0.5, -0.1, 0.5, -0.2, 0.7, -0.4, 0.2, -0.9, 0.1, 0.0, 0.3, 0.2, 0.7, 0.9, 0.9, 0.5, 0.3, 0.6, 0.2, 0.1, 0.1, 0.2, 0.4, 0.1, 0.5, 0.4, 0.2, 0.2, 0.6, 0.8, 0.2, 0.7, 0.3, -0.8, 0.2, -0.8, 0.5, -0.5, 0.8, -0.1, 0.6, -0.1, 0.3, -0.2, 0.5, 0.0, 0.4, 0.7, 0.6, 0.4, 0.9, 0.4, 0.7, 0.6, 0.2, 0.4, 0.4, 0.9, 0.3, 0.7, 0.1, 0.2, 0.1, 0.8, 0.3, 0.4, 0.7, -0.3, 0.6, -0.4, 0.4, -0.4, 0.8, -0.7, 0.7, -0.4, 0.7, -0.9, 0.4, -0.7, 0.6, 0.0, 0.2, 0.8, 0.2, 0.2, 0.2, 0.1, 0.1, 0.4, 0.2, 0.9, 0.8, 0.1, 0.9, 0.5, 0.6, 0.4, 0.1, 0.3, 0.6, -0.9, 0.6, -0.2, 0.8, -0.6, 0.2, -0.1, 0.7, -0.4, 0.9, -0.5, 0.6, -0.4, 0.2, -0.8, 0.1, 0.0, 0.5, 0.7, 0.2, 0.2, 0.1, 0.5, 0.8, 0.6, 0.6, 0.6, 0.5, 0.2, 0.5, 0.3, 0.2, 0.1, 0.8, -0.3, 0.4, -0.7, 0.4, -0.9, 0.9, -0.7, 0.3, -0.8, 0.3, -0.6, 0.9, -0.4, 0.2, -0.2, 0.5, -0.7, 0.8, 0.0, 0.9, 0.1, 0.1, 0.1, 0.5, 0.7, 0.9, 0.4, 0.5, 0.9, 0.6, 0.6, 0.4, 0.1, 0.7, -0.9, 0.8, -0.3, 0.6, -0.6, 0.4, -0.2, 0.3, -0.6, 0.2, -0.1, 0.7, -0.6, 0.2, -0.1, 0.2, -0.2, 0.9, -0.1, 0.8, 0.0, 0.8, 0.4, 0.2, 0.6, 0.4, 0.8, 0.1, 0.9, 0.1, 0.6, 0.9, 0.1, 0.1, -0.2, 0.2, -0.7, 0.1, -0.3, 0.4, -0.3, 0.1, -0.8, 0.1, -0.2, 0.2, -0.4, 0.1, -0.4, 0.1, -0.5, 0.1, -0.1, 0.8, -0.4, 0.2, 0.0, 0.5, 0.7, 0.5, 0.9, 0.2, 0.4, 0.2, 0.1, 0.3, 0.2, 0.1, -0.4, 0.2, -0.9, 0.9, -0.2, 0.5, -0.5, 0.1, -0.4, 0.4, -0.1, 0.4, -0.9, 0.2, -0.9, 0.8, -0.6, 0.5, -0.7, 0.2, -0.6, 0.5, -0.7, 0.6, 0.0, 0.9, 0.5, 0.2, 0.3, 0.3, 0.2, 0.3, 0.4, 0.3, -0.1, 0.3, -0.9, 0.3, -0.6, 0.4, -0.3, 0.9, -0.7, 0.5, -0.4, 0.3, -0.7, 0.8, -0.1, 0.6, -0.6, 0.9, -0.4, 0.4, -0.8, 0.5, -0.9, 0.9, -0.5, 0.4, 0.0, 0.4, 0.1, 0.3, 0.1, 0.3, 0.2, 0.3, -0.3, 0.4, -0.8, 0.1, -0.7, 0.3, -0.5, 0.2, -0.2, 0.2, -0.2, 0.1, -0.2, 0.9, -0.5, 0.5, -0.2, 0.5, -0.9, 0.1, -0.9, 0.2, -0.4, 0.2, -0.3, 0.4, -0.1, 0.2, 0.0, 0.5, 0.7, 0.6, 0.4, 0.4, -0.1, 0.5, -0.3, 0.7, -0.3, 0.2, -0.3, 0.1, -0.6, 0.6, -0.8, 0.1, -0.8, 0.6, -0.4, 0.5, -0.3, 0.6, -0.6, 0.1, -0.6, 0.2, -0.1, 0.3, -0.2, 0.3, -0.1, 0.5, -0.7, 0.9, 0.0, 0.6, 0.7, 0.8, -0.1, 0.8, -0.3, 0.2, -0.7, 0.4, -0.7, 0.7, -0.4, 0.2, -0.7, 0.3, -0.4, 0.1, -0.3, 0.2, -0.1, 0.4, -0.1, 0.9, -0.1, 0.3, -0.2, 0.3, -0.4, 0.3, -0.2, 0.6, -0.4, 0.6, -0.7, 0.7, 0.0, 
+
+L3_zHER2K_o_N
+18.44, -1.99840144433e-15, 15.34, 1.79, 16.34, 1.52, 16.2, -0.34, 15.27, 1.29, 17.95, 0.27, 16.05, 0.21, 18.46, 0.28, 16.46, 2.3, 17.33, 0.38, 16.83, 2.79, 16.43, 0.54, 17.2, 1.65, 17.27, 1.25, 15.48, 1.04, 14.74, 2.46, 18.63, -0.7, 15.34, -1.79, 16.32, -5.55111512313e-16, 13.95, 0.64, 15.09, 0.43, 14.89, 0.06, 16.18, -1.01, 15.09, -1.01, 15.16, -0.88, 16.69, 1.5, 16.7, -0.41, 15.71, 1.36, 15.69, 0.49, 15.65, 1.44, 17.03, 2.03, 15.65, 0.43, 14.97, 1.73, 17.06, 0.82, 16.34, -1.52, 13.95, -0.64, 15.06, -4.4408920985e-16, 15.26, -1.89, 14.26, -0.88, 17.82, 0.33, 15.79, -0.76, 16.36, -1.3, 16.25, 2.89, 16.41, -0.7, 16.15, 1.35, 14.42, -0.2, 17.16, -0.48, 17.31, 0.15, 15.65, 1.26, 15.74, 1.32, 16.72, 0.25, 16.2, 0.34, 15.09, -0.43, 15.26, 1.89, 17.34, 1.11022302463e-16, 15.49, 0.26, 16.47, 0.37, 15.36, -0.06, 16.42, -0.1, 16.12, 3.67, 18.13, 0.98, 13.87, 2.64, 14.77, 0.8, 16.55, 2.06, 16.93, 2.59, 16.43, 2.03, 16.27, 3.33, 17.43, 1.51, 15.27, -1.29, 14.89, -0.06, 14.26, 0.88, 15.49, -0.26, 14.86, 4.4408920985e-16, 15.62, 0.8, 14.19, -0.33, 15.85, 0.33, 14.56, 2.53, 16.26, 1.11, 13.31, 3.68, 14.13, 2.13, 15.6, 0.81, 17.18, 2.88, 14.94, 1.71, 14.07, 3.75, 16.08, 0.02, 17.95, -0.27, 16.18, 1.01, 17.82, -0.33, 16.47, -0.37, 15.62, -0.8, 17.58, 0.0, 17.02, -0.72, 19.08, 0.57, 17.18, 3.7, 16.55, 0.86, 16.06, 1.56, 17.53, 0.79, 18.27, 1.44, 18.34, 1.95, 16.79, 1.58, 16.34, 3.13, 18.05, -0.18, 16.05, -0.21, 15.09, 1.01, 15.79, 0.76, 15.36, 0.06, 14.19, 0.33, 17.02, 0.72, 15.2, 1.44328993201e-15, 15.61, 1.14, 16.28, 4.0, 16.06, 0.86, 15.86, 3.2, 15.54, 2.84, 16.14, 2.65, 16.3, 3.17, 16.12, 2.29, 15.24, 3.61, 17.68, 2.0, 18.46, -0.28, 15.16, 0.88, 16.36, 1.3, 16.42, 0.1, 15.85, -0.33, 19.08, -0.57, 15.61, -1.14, 17.08, 4.4408920985e-16, 16.87, 3.8, 16.8, -0.61, 14.8, 1.67, 15.15, 2.59, 16.5, 1.92, 18.15, 2.89, 18.06, 2.19, 15.69, 2.45, 19.65, 0.46, 16.46, -2.3, 16.69, -1.5, 16.25, -2.89, 16.12, -3.67, 14.56, -2.53, 17.18, -3.7, 16.28, -4.0, 16.87, -3.8, 16.86, 3.10862446895e-15, 17.31, -1.66, 15.91, 0.89, 16.41, -1.4, 17.57, -0.75, 17.8, -0.73, 17.38, -1.33, 17.26, 0.68, 17.62, -2.23, 17.33, -0.38, 16.7, 0.41, 16.41, 0.7, 18.13, -0.98, 16.26, -1.11, 16.55, -0.86, 16.06, -0.86, 16.8, 0.61, 17.31, 1.66, 18.04, -2.22044604925e-16, 14.99, 2.53, 15.6, 0.83, 17.07, 1.47, 18.65, 3.49, 17.04, 2.6, 16.46, 4.19, 17.81, -0.41, 16.83, -2.79, 15.71, -1.36, 16.15, -1.35, 13.87, -2.64, 13.31, -3.68, 16.06, -1.56, 15.86, -3.2, 14.8, -1.67, 15.91, -0.89, 14.99, -2.53, 17.26, -8.881784197e-16, 16.11, 0.18, 14.96, 0.63, 15.98, 0.21, 15.56, -0.21, 14.72, 0.03, 18.27, -0.91, 16.43, -0.54, 15.69, -0.49, 14.42, 0.2, 14.77, -0.8, 14.13, -2.13, 17.53, -0.79, 15.54, -2.84, 15.15, -2.59, 16.41, 1.4, 15.6, -0.83, 16.11, -0.18, 15.74, 4.4408920985e-16, 16.15, 0.77, 16.72, 2.33, 16.3, 0.31, 14.77, 1.83, 17.65, 0.87, 17.2, -1.65, 15.65, -1.44, 17.16, 0.48, 16.55, -2.06, 15.6, -0.81, 18.27, -1.44, 16.14, -2.65, 16.5, -1.92, 17.57, 0.75, 17.07, -1.47, 14.96, -0.63, 16.15, -0.77, 17.48, -4.4408920985e-16, 18.95, 1.04, 15.84, -0.05, 15.65, 1.37, 17.68, -1.39, 17.27, -1.25, 17.03, -2.03, 17.31, -0.15, 16.93, -2.59, 17.18, -2.88, 18.34, -1.95, 16.3, -3.17, 18.15, -2.89, 17.8, 0.73, 18.65, -3.49, 15.98, -0.21, 16.72, -2.33, 18.95, -1.04, 18.7, -4.4408920985e-16, 17.61, -0.65, 17.25, 1.3, 18.51, -1.05, 15.48, -1.04, 15.65, -0.43, 15.65, -1.26, 16.43, -2.03, 14.94, -1.71, 16.79, -1.58, 16.12, -2.29, 18.06, -2.19, 17.38, 1.33, 17.04, -2.6, 15.56, 0.21, 16.3, -0.31, 15.84, 0.05, 17.61, 0.65, 16.94, -2.37310171514e-15, 16.0, 2.04, 18.1, 0.03, 14.74, -2.46, 14.97, -1.73, 15.74, -1.32, 16.27, -3.33, 14.07, -3.75, 16.34, -3.13, 15.24, -3.61, 15.69, -2.45, 17.26, -0.68, 16.46, -4.19, 14.72, -0.03, 14.77, -1.83, 15.65, -1.37, 17.25, -1.3, 16.0, -2.04, 14.96, -6.93889390391e-16, 16.17, -1.95, 18.63, 0.7, 17.06, -0.82, 16.72, -0.25, 17.43, -1.51, 16.08, -0.02, 18.05, 0.18, 17.68, -2.0, 19.65, -0.46, 17.62, 2.23, 17.81, 0.41, 18.27, 0.91, 17.65, -0.87, 17.68, 1.39, 18.51, 1.05, 18.1, -0.03, 16.17, 1.95, 18.78, 2.38697950294e-15, 
+
+L3_zHER2K_A_kn
+0.8, 0.9, 0.5, 0.5, 0.9, 0.3, 0.6, 0.8, 0.5, 0.5, 0.2, 0.7, 0.8, 0.3, 0.8, 0.1, 0.4, 0.5, 0.4, 0.8, 0.4, 0.3, 0.5, 0.8, 0.9, 0.2, 0.8, 0.2, 0.6, 0.4, 0.3, 0.2, 0.8, 0.3, 0.8, 0.1, 0.5, 0.1, 0.3, 0.5, 0.6, 0.6, 0.9, 0.4, 0.2, 0.4, 0.1, 0.6, 0.3, 0.9, 0.5, 0.6, 0.6, 0.7, 0.1, 0.6, 0.7, 0.6, 0.2, 0.5, 0.2, 0.6, 0.1, 0.1, 0.7, 0.9, 0.4, 0.8, 0.5, 0.5, 0.8, 0.4, 0.5, 0.9, 0.5, 0.6, 0.4, 0.2, 0.1, 0.6, 0.6, 0.5, 0.6, 0.3, 0.5, 0.9, 0.6, 0.4, 0.1, 0.4, 0.7, 0.5, 0.6, 0.3, 0.4, 0.5, 0.3, 0.5, 0.1, 0.3, 0.9, 0.1, 0.7, 0.1, 0.5, 0.5, 0.4, 0.5, 0.8, 0.6, 0.1, 0.3, 0.7, 0.5, 0.5, 0.3, 0.2, 0.6, 0.7, 0.5, 0.1, 0.3, 0.1, 0.9, 0.5, 0.3, 0.5, 0.4, 0.2, 0.3, 0.2, 0.1, 0.5, 0.2, 0.4, 0.8, 0.6, 0.3, 0.7, 0.8, 0.2, 0.7, 0.6, 0.4, 0.1, 0.8, 0.6, 0.7, 0.8, 0.6, 0.3, 0.9, 0.9, 0.6, 0.5, 0.5, 0.4, 0.2, 0.3, 0.8, 0.5, 0.6, 0.1, 0.1, 0.9, 0.7, 0.5, 0.9, 0.7, 0.3, 0.7, 0.5, 0.7, 0.2, 0.8, 0.5, 0.6, 0.6, 0.1, 0.5, 0.5, 0.6, 0.6, 0.5, 0.9, 0.9, 0.2, 0.1, 0.6, 0.8, 0.8, 0.8, 0.8, 0.8, 0.1, 0.3, 0.5, 0.2, 0.1, 0.8, 0.7, 0.1, 0.6, 0.8, 0.2, 0.4, 0.2, 0.2, 0.1, 0.1, 0.8, 0.4, 0.6, 0.5, 0.8, 0.1, 0.7, 0.9, 0.8, 0.8, 0.9, 0.7, 0.2, 0.7, 0.7, 0.2, 0.7, 0.6, 0.6, 0.4, 0.1, 0.3, 0.3, 0.2, 0.1, 0.9, 0.4, 0.2, 0.3, 0.7, 0.7, 0.3, 0.1, 0.3, 0.6, 0.4, 0.5, 0.2, 0.4, 0.9, 0.1, 0.5, 0.4, 0.2, 0.8, 0.6, 0.4, 0.9, 0.3, 0.9, 0.1, 0.4, 0.1, 0.8, 0.9, 0.1, 0.5, 0.3, 0.3, 0.5, 0.1, 0.1, 0.3, 0.9, 0.6, 0.2, 0.8, 0.6, 0.8, 0.9, 0.5, 0.1, 0.8, 0.7, 0.7, 0.6, 0.5, 0.5, 0.8, 0.5, 0.6, 0.6, 0.5, 0.9, 0.3, 0.5, 0.7, 0.5, 0.2, 0.7, 0.1, 0.3, 0.6, 0.6, 0.8, 0.2, 0.8, 0.1, 0.7, 0.2, 0.6, 0.1, 0.5, 0.6, 0.5, 0.3, 0.1, 0.7, 0.2, 0.4, 0.1, 0.7, 0.9, 0.3, 0.8, 0.4, 0.2, 0.2, 0.9, 0.4, 0.8, 0.2, 0.3, 0.1, 0.2, 0.4, 0.2, 0.3, 0.5, 0.8, 0.4, 0.3, 0.5, 0.1, 0.4, 0.5, 0.3, 0.1, 0.6, 0.2, 0.3, 0.6, 0.9, 0.3, 0.1, 0.4, 0.2, 0.9, 0.6, 0.1, 0.7, 0.8, 0.9, 0.5, 0.5, 0.9, 0.5, 0.4, 0.5, 0.2, 0.8, 0.2, 0.3, 0.2, 0.9, 0.3, 0.8, 0.9, 0.3, 0.4, 0.3, 0.4, 0.2, 0.6, 0.9, 0.8, 0.7, 0.4, 0.6, 0.2, 0.9, 0.8, 0.2, 0.1, 0.1, 0.6, 0.5, 0.3, 0.8, 0.5, 0.5, 0.9, 0.9, 0.7, 0.6, 0.3, 0.4, 0.5, 0.1, 0.5, 0.2, 0.7, 0.8, 0.8, 0.4, 0.3, 0.4, 0.7, 0.5, 0.3, 0.3, 0.1, 0.3, 0.2, 0.7, 0.9, 0.8, 0.1, 0.8, 0.4, 0.1, 0.8, 0.1, 0.1, 0.7, 0.4, 0.6, 0.8, 0.1, 0.6, 0.3, 0.2, 0.5, 0.2, 0.6, 0.6, 0.3, 0.3, 0.1, 0.2, 0.9, 0.2, 0.8, 0.1, 0.3, 0.5, 0.4, 0.7, 0.5, 0.3, 0.9, 0.8, 0.5, 0.9, 0.8, 0.9, 0.3, 0.9, 0.5, 0.8, 0.6, 0.7, 0.8, 0.3, 0.1, 0.1, 0.5, 0.9, 0.6, 0.8, 0.5, 0.1, 0.4, 0.5, 0.7, 0.8, 0.4, 0.5, 0.4, 0.2, 0.3, 0.1, 0.4, 0.5, 0.6, 0.3, 0.2, 0.4, 0.3, 0.7, 0.7, 0.3, 0.8, 0.6, 0.3, 0.8, 0.4, 0.1, 0.4, 0.3, 0.2, 0.8, 0.5, 0.9, 0.9, 0.7, 0.8, 0.6, 0.8, 0.5, 0.8, 0.6, 0.5, 0.9, 0.9, 0.3, 0.1, 0.1, 0.7, 0.4, 0.5, 0.7, 0.4, 0.7, 0.8, 0.3, 0.7, 0.1, 0.2, 0.6, 0.2, 0.9, 0.2, 0.2, 
+
+L3_zHER2K_B_kn
+0.3, 0.9, 0.9, 0.3, 0.7, 0.5, 0.5, 0.4, 0.9, 0.2, 0.7, 0.5, 0.1, 0.2, 0.6, 0.6, 0.1, 0.7, 0.5, 0.3, 0.9, 0.5, 0.5, 0.7, 0.4, 0.7, 0.4, 0.4, 0.3, 0.5, 0.4, 0.3, 0.5, 0.9, 0.8, 0.1, 0.6, 0.6, 0.4, 0.8, 0.7, 0.2, 0.6, 0.1, 0.9, 0.2, 0.3, 0.3, 0.4, 0.1, 0.7, 0.3, 0.4, 0.2, 0.2, 0.3, 0.4, 0.2, 0.9, 0.3, 0.8, 0.5, 0.9, 0.8, 0.9, 0.1, 0.3, 0.9, 0.1, 0.8, 0.5, 0.1, 0.6, 0.3, 0.4, 0.1, 0.9, 0.2, 0.6, 0.9, 0.9, 0.2, 0.8, 0.9, 0.9, 0.9, 0.1, 0.2, 0.2, 0.6, 0.3, 0.8, 0.4, 0.5, 0.3, 0.7, 0.6, 0.5, 0.2, 0.1, 0.6, 0.9, 0.2, 0.3, 0.9, 0.7, 0.1, 0.9, 0.1, 0.8, 0.8, 0.8, 0.3, 0.8, 0.4, 0.5, 0.3, 0.3, 0.2, 0.9, 0.5, 0.5, 0.2, 0.5, 0.5, 0.6, 0.3, 0.2, 0.9, 0.8, 0.5, 0.9, 0.8, 0.9, 0.5, 0.2, 0.2, 0.5, 0.4, 0.3, 0.1, 0.7, 0.8, 0.7, 0.8, 0.9, 0.7, 0.8, 0.6, 0.7, 0.4, 0.8, 0.3, 0.1, 0.7, 0.9, 0.4, 0.6, 0.5, 0.9, 0.8, 0.2, 0.4, 0.9, 0.2, 0.7, 0.2, 0.4, 0.8, 0.4, 0.7, 0.8, 0.6, 0.9, 0.1, 0.7, 0.7, 0.5, 0.2, 0.9, 0.1, 0.9, 0.4, 0.3, 0.3, 0.4, 0.3, 0.4, 0.2, 0.4, 0.6, 0.3, 0.2, 0.8, 0.3, 0.3, 0.2, 0.4, 0.2, 0.3, 0.2, 0.3, 0.1, 0.3, 0.6, 0.5, 0.3, 0.7, 0.9, 0.2, 0.9, 0.4, 0.6, 0.3, 0.1, 0.1, 0.1, 0.1, 0.1, 0.5, 0.3, 0.2, 0.7, 0.4, 0.9, 0.7, 0.3, 0.2, 0.7, 0.1, 0.1, 0.3, 0.4, 0.2, 0.2, 0.5, 0.3, 0.9, 0.7, 0.6, 0.1, 0.8, 0.5, 0.3, 0.7, 0.1, 0.7, 0.9, 0.1, 0.4, 0.3, 0.7, 0.7, 0.7, 0.5, 0.1, 0.6, 0.6, 0.3, 0.2, 0.6, 0.9, 0.9, 0.7, 0.3, 0.9, 0.8, 0.8, 0.9, 0.8, 0.9, 0.6, 0.5, 0.2, 0.3, 0.4, 0.2, 0.9, 0.3, 0.2, 0.5, 0.6, 0.9, 0.9, 0.4, 0.8, 0.4, 0.3, 0.1, 0.3, 0.2, 0.9, 0.3, 0.2, 0.6, 0.2, 0.5, 0.3, 0.1, 0.3, 0.2, 0.4, 0.3, 0.6, 0.2, 0.2, 0.2, 0.9, 0.6, 0.5, 0.2, 0.9, 0.4, 0.4, 0.8, 0.5, 0.2, 0.1, 0.3, 0.7, 0.9, 0.5, 0.6, 0.2, 0.3, 0.9, 0.2, 0.2, 0.4, 0.5, 0.7, 0.7, 0.3, 0.2, 0.1, 0.9, 0.5, 0.8, 0.8, 0.2, 0.7, 0.7, 0.2, 0.3, 0.8, 0.8, 0.5, 0.5, 0.4, 0.4, 0.5, 0.8, 0.6, 0.1, 0.5, 0.7, 0.2, 0.4, 0.3, 0.8, 0.3, 0.5, 0.5, 0.4, 0.5, 0.1, 0.5, 0.6, 0.6, 0.7, 0.6, 0.1, 0.6, 0.8, 0.1, 0.2, 0.1, 0.8, 0.4, 0.3, 0.3, 0.3, 0.9, 0.3, 0.3, 0.7, 0.2, 0.5, 0.2, 0.2, 0.5, 0.3, 0.4, 0.9, 0.9, 0.3, 0.2, 0.8, 0.8, 0.6, 0.9, 0.2, 0.2, 0.8, 0.2, 0.5, 0.8, 0.9, 0.1, 0.6, 0.4, 0.5, 0.9, 0.4, 0.8, 0.5, 0.6, 0.1, 0.4, 0.3, 0.7, 0.4, 0.6, 0.1, 0.9, 0.9, 0.2, 0.4, 0.3, 0.4, 0.6, 0.4, 0.1, 0.5, 0.4, 0.6, 0.5, 0.5, 0.5, 0.3, 0.4, 0.3, 0.1, 0.2, 0.4, 0.8, 0.7, 0.9, 0.6, 0.2, 0.8, 0.4, 0.5, 0.7, 0.7, 0.6, 0.4, 0.7, 0.6, 0.1, 0.2, 0.7, 0.4, 0.6, 0.3, 0.7, 0.7, 0.6, 0.8, 0.9, 0.2, 0.8, 0.9, 0.4, 0.2, 0.1, 0.2, 0.3, 0.8, 0.6, 0.1, 0.5, 0.7, 0.8, 0.9, 0.6, 0.3, 0.7, 0.8, 0.5, 0.1, 0.5, 0.8, 0.6, 0.3, 0.7, 0.6, 0.4, 0.4, 0.6, 0.1, 0.7, 0.6, 0.7, 0.8, 0.8, 0.6, 0.9, 0.3, 0.2, 0.5, 0.2, 0.8, 0.5, 0.7, 0.9, 0.3, 0.9, 0.5, 0.1, 0.9, 0.6, 0.2, 0.4, 0.8, 0.1, 0.7, 0.7, 0.5, 0.4, 0.5, 0.7, 0.1, 0.8, 0.2, 0.1, 0.4, 0.2, 0.5, 0.7, 0.7, 0.9, 0.6, 0.2, 
+
+L3_zHER2K_o_H
+13.76, 0.0, 15.48, -0.88, 14.52, 0.6, 15.95, -1.51, 16.57, -1.53, 16.2, 1.55, 13.52, 0.25, 14.65, 0.16, 15.64, -0.47, 15.22, 1.48, 14.55, 1.0, 15.99, 1.41, 13.95, -0.26, 13.66, -0.19, 13.83, 1.71, 14.45, 0.58, 14.14, -0.63, 15.48, 0.88, 17.1, 1.11022302463e-15, 16.39, 2.45, 17.94, 0.44, 17.69, -0.89, 17.8, 1.55, 15.98, 1.11, 16.6, 1.08, 17.28, -1.36, 17.09, 2.63, 16.69, 1.21, 18.24, 4.0, 16.85, 0.29, 16.05, 0.64, 16.28, 4.08, 16.22, 0.49, 16.26, 0.74, 14.52, -0.6, 16.39, -2.45, 17.0, 8.881784197e-16, 17.08, -1.87, 16.7, -2.79, 18.64, -0.44, 15.74, -1.06, 16.87, -1.24, 17.4, 0.04, 16.06, 0.49, 17.17, 1.22, 17.78, 1.04, 15.26, -1.75, 15.34, -0.36, 15.67, 2.07, 15.05, -0.39, 14.56, -1.95, 15.95, 1.51, 17.94, -0.44, 17.08, 1.87, 16.4, 3.88578058619e-16, 17.89, -0.35, 17.79, 2.04, 15.43, 1.06, 15.9, 1.87, 16.58, 1.58, 16.76, 3.38, 15.43, 2.11, 17.44, 4.17, 15.12, -0.15, 14.47, 1.27, 16.37, 4.07, 15.51, 2.43, 15.21, 1.15, 16.57, 1.53, 17.69, 0.89, 16.7, 2.79, 17.89, 0.35, 17.34, 0.0, 17.94, 4.16, 15.82, 1.59, 16.29, 2.82, 18.45, 1.83, 16.72, 3.89, 15.15, 3.66, 17.24, 5.15, 16.64, 1.82, 15.85, 2.81, 16.61, 4.7, 15.56, 2.6, 15.67, 1.47, 16.2, -1.55, 17.8, -1.55, 18.64, 0.44, 17.79, -2.04, 17.94, -4.16, 18.56, -8.881784197e-16, 16.1, -1.28, 16.2, -1.05, 17.55, -1.19, 17.71, 0.86, 16.6, 0.54, 18.33, 1.17, 17.08, -3.11, 16.32, -0.53, 16.93, 1.07, 16.31, 0.37, 15.55, -2.65, 13.52, -0.25, 15.98, -1.11, 15.74, 1.06, 15.43, -1.06, 15.82, -1.59, 16.1, 1.28, 14.14, 9.43689570931e-16, 13.78, 1.51, 14.42, 0.17, 16.08, 1.36, 15.4, 2.39, 15.67, 3.58, 13.79, -0.7, 13.81, 1.55, 14.36, 2.68, 13.74, 0.53, 14.15, 0.3, 14.65, -0.16, 16.6, -1.08, 16.87, 1.24, 15.9, -1.87, 16.29, -2.82, 16.2, 1.05, 13.78, -1.51, 14.74, -7.91033905045e-16, 15.02, 0.46, 16.03, 0.64, 14.71, 1.66, 15.6, 2.38, 14.22, -1.3, 14.55, -0.8, 15.29, 1.91, 13.39, 0.48, 12.99, -0.19, 15.64, 0.47, 17.28, 1.36, 17.4, -0.04, 16.58, -1.58, 18.45, -1.83, 17.55, 1.19, 14.42, -0.17, 15.02, -0.46, 17.14, 2.22044604925e-16, 16.94, 2.95, 15.15, 1.63, 17.3, 3.33, 16.17, -0.65, 16.46, 1.16, 16.41, 3.65, 14.61, 1.99, 16.25, -0.53, 15.22, -1.48, 17.09, -2.63, 16.06, -0.49, 16.76, -3.38, 16.72, -3.89, 17.71, -0.86, 16.08, -1.36, 16.03, -0.64, 16.94, -2.95, 15.06, -1.55431223448e-15, 15.57, -0.2, 16.67, 0.78, 15.91, -2.28, 15.64, -0.31, 16.22, 1.69, 15.53, -0.6, 14.46, -1.59, 14.55, -1.0, 16.69, -1.21, 17.17, -1.22, 15.43, -2.11, 15.15, -3.66, 16.6, -0.54, 15.4, -2.39, 14.71, -1.66, 15.15, -1.63, 15.57, 0.2, 14.66, -2.22044604925e-16, 17.12, 0.96, 14.13, -2.54, 14.2, -0.65, 15.34, 1.07, 14.23, -1.4, 13.51, -1.86, 15.99, -1.41, 18.24, -4.0, 17.78, -1.04, 17.44, -4.17, 17.24, -5.15, 18.33, -1.17, 15.67, -3.58, 15.6, -2.38, 17.3, -3.33, 16.67, -0.78, 17.12, -0.96, 17.98, -2.22044604925e-15, 16.56, -2.63, 16.26, -1.47, 17.28, 0.35, 15.68, -2.12, 15.23, -1.72, 13.95, 0.26, 16.85, -0.29, 15.26, 1.75, 15.12, 0.15, 16.64, -1.82, 17.08, 3.11, 13.79, 0.7, 14.22, 1.3, 16.17, 0.65, 15.91, 2.28, 14.13, 2.54, 16.56, 2.63, 14.52, 2.22044604925e-16, 15.2, 0.57, 15.39, 3.06, 13.8, 2.11, 14.36, 1.11, 13.66, 0.19, 16.05, -0.64, 15.34, 0.36, 14.47, -1.27, 15.85, -2.81, 16.32, 0.53, 13.81, -1.55, 14.55, 0.8, 16.46, -1.16, 15.64, 0.31, 14.2, 0.65, 16.26, 1.47, 15.2, -0.57, 14.04, 4.4408920985e-16, 15.48, 1.97, 14.63, -0.02, 13.25, 0.41, 13.83, -1.71, 16.28, -4.08, 15.67, -2.07, 16.37, -4.07, 16.61, -4.7, 16.93, -1.07, 14.36, -2.68, 15.29, -1.91, 16.41, -3.65, 16.22, -1.69, 15.34, -1.07, 17.28, -0.35, 15.39, -3.06, 15.48, -1.97, 14.96, 4.4408920985e-16, 14.76, -1.2, 14.5, -1.66, 14.45, -0.58, 16.22, -0.49, 15.05, 0.39, 15.51, -2.43, 15.56, -2.6, 16.31, -0.37, 13.74, -0.53, 13.39, -0.48, 14.61, -1.99, 15.53, 0.6, 14.23, 1.4, 15.68, 2.12, 13.8, -2.11, 14.63, 0.02, 14.76, 1.2, 15.5, 3.33066907388e-16, 13.54, 0.14, 14.14, 0.63, 16.26, -0.74, 14.56, 1.95, 15.21, -1.15, 15.67, -1.47, 15.55, 2.65, 14.15, -0.3, 12.99, 0.19, 16.25, 0.53, 14.46, 1.59, 13.51, 1.86, 15.23, 1.72, 14.36, -1.11, 13.25, -0.41, 14.5, 1.66, 13.54, -0.14, 13.4, -4.4408920985e-16, 
+
+L3_sTRMM_A_mm
+0.5, 0.8, 0.6, 0.6, 0.3, 0.2, 0.2, 0.1, 0.3, 0.4, 0.0, 0.6, 0.7, 0.7, 0.6, 0.3, 0.6, 0.7, 0.9, 0.1, 0.0, 0.0, 0.2, 0.8, 0.5, 0.5, 0.1, 0.9, 0.7, 0.1, 0.0, 0.0, 0.0, 0.1, 0.1, 0.6, 0.6, 0.2, 0.7, 0.3, 0.0, 0.0, 0.0, 0.0, 0.1, 0.3, 0.9, 0.1, 0.1, 0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.3, 0.7, 0.5, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.5, 0.3, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.8, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.4, 
+
+L3_sTRMM_B_mn
+0.4, 0.2, 0.3, 0.8, 0.3, 0.9, 0.7, 0.4, 0.3, 0.7, 0.7, 0.2, 0.8, 0.5, 0.4, 0.4, 0.8, 0.8, 0.3, 0.5, 0.7, 0.4, 0.7, 0.6, 0.9, 0.5, 0.5, 0.7, 0.4, 0.4, 0.9, 0.6, 0.1, 0.9, 0.5, 0.1, 0.9, 0.4, 0.9, 0.6, 0.3, 0.3, 0.2, 0.2, 0.7, 0.4, 0.4, 0.1, 0.6, 0.6, 0.6, 0.5, 0.7, 0.5, 0.4, 0.8, 0.2, 0.3, 0.6, 0.9, 0.8, 0.4, 0.5, 0.9, 0.2, 0.8, 0.8, 0.4, 0.5, 0.3, 0.6, 0.5, 0.8, 0.7, 0.7, 0.6, 0.9, 0.5, 0.9, 0.2, 0.6, 0.9, 0.8, 0.9, 0.3, 0.7, 0.9, 0.7, 0.6, 0.3, 0.8, 0.7, 0.9, 0.2, 0.1, 0.1, 0.6, 0.1, 0.3, 0.2, 0.1, 0.2, 0.7, 0.2, 0.9, 0.7, 0.3, 0.6, 0.1, 0.6, 0.4, 0.9, 0.8, 0.4, 0.5, 0.2, 0.9, 0.3, 0.4, 0.9, 0.9, 0.5, 0.3, 0.7, 0.6, 0.4, 0.6, 0.3, 0.2, 0.2, 0.1, 0.9, 0.6, 0.2, 0.1, 0.7, 0.8, 0.9, 0.8, 0.8, 0.5, 0.1, 0.2, 0.7, 0.9, 0.6, 0.1, 0.4, 0.3, 0.1, 0.5, 0.2, 0.1, 0.4, 0.1, 0.6, 0.6, 0.3, 0.7, 0.7, 0.3, 0.1, 0.1, 0.2, 0.1, 0.9, 0.4, 0.9, 0.8, 0.8, 
+
+L3_sTRMM_o_LUN
+2.3600000681, 1.5300000374, 2.42000006989, 2.36000007108, 2.19000008091, 2.35000004247, 1.94000005782, 2.33000007093, 1.94000003919, 1.94000005335, 2.15000002906, 1.39000005633, 2.34000005409, 1.77000001922, 2.51000009865, 1.86000008076, 2.35000006109, 3.50000000596, 2.75999995187, 3.52000000805, 2.87000004381, 3.15000000522, 2.58000007838, 2.0000000529, 3.24000006601, 2.9399999699, 2.5600000383, 2.49000002652, 1.85000003651, 2.83000000238, 2.05000003725, 3.10000006035, 2.12000003487, 2.38000003144, 2.57999995843, 2.649999924, 2.38999999896, 1.91000002936, 2.40999999881, 1.77000002146, 1.58000000015, 2.41000002488, 2.25999996006, 1.68000002772, 1.30999999881, 1.30000002161, 2.30999996826, 1.4500000082, 1.97000002295, 1.60000001714, 1.50999999955, 1.80000002384, 1.59999998733, 1.91000003532, 1.67000005648, 1.10000003427, 1.33000006646, 1.01000002116, 1.72000003934, 1.25999999508, 1.22000002593, 0.840000033975, 1.0000000447, 1.17000002369, 0.720000033379, 1.48000001729, 0.810000032336, 0.880000035167, 1.37999998897, 0.740000003427, 1.68999999449, 1.45000001788, 0.800000026822, 1.4800000225, 0.990000004172, 1.24000003025, 0.710000001043, 1.04999996573, 1.02999999791, 0.690000014603, 1.37999998525, 0.750000017136, 1.73999995574, 1.06000002414, 1.17000001997, 1.65999998242, 1.3899999617, 1.58000001281, 1.36000003159, 1.09999999851, 1.30000001267, 1.03999998555, 1.34000002056, 0.890000000447, 0.800000015646, 0.590000013858, 0.580000015795, 1.57999995768, 0.870000016242, 1.32999997705, 0.840000007898, 1.25999999061, 1.03000000387, 0.809999993593, 0.970000022948, 0.830000030696, 0.710000009239, 0.800000014156, 0.630000000894, 0.780000029206, 0.550000012666, 0.510000014454, 0.390000009388, 0.300000010431, 1.0899999848, 0.570000017732, 0.879999993443, 0.570000013262, 0.860000004023, 1.80999997199, 1.6199999477, 1.63000001431, 1.4500000298, 1.29999998212, 1.24999998212, 1.14999997318, 1.37000000954, 1.07999999419, 0.750000023097, 0.439999998212, 0.500000007451, 1.85999992728, 0.980000005364, 1.38999996096, 0.969999995381, 1.42999996662, 0.480000026226, 0.330000006855, 0.600000041723, 0.600000041723, 0.330000020266, 0.450000011176, 0.480000012815, 0.390000019073, 0.330000006855, 0.240000017583, 0.150000008196, 0.180000009835, 0.630000014305, 0.270000014752, 0.690000013113, 0.540000029504, 0.510000027865, 0.160000004768, 0.0400000011921, 0.240000013113, 0.240000013113, 0.120000006557, 0.279999999404, 0.279999999404, 0.120000006557, 0.0400000011921, 0.0400000011921, 0.0800000023842, 0.0400000011921, 0.359999995828, 0.160000004768, 0.359999995828, 0.320000009537, 0.320000009537, 
+
+L3_sTRMM_A_nn
+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.6, 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.1, 0.2, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.2, 0.6, 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.1, 0.2, 0.1, 0.2, 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.6, 0.3, 0.1, 0.2, 0.9, 0.6, 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.7, 0.5, 0.6, 0.2, 0.8, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.3, 0.3, 0.2, 0.5, 0.2, 0.3, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.8, 0.1, 0.9, 0.3, 0.6, 0.3, 0.9, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.9, 0.7, 0.3, 0.1, 0.4, 0.3, 0.3, 0.9, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.9, 0.1, 0.5, 0.7, 0.4, 0.8, 0.1, 0.5, 0.5, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.3, 0.6, 0.2, 0.4, 0.7, 0.2, 0.9, 0.4, 0.9, 0.8, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.3, 0.7, 0.7, 0.2, 0.9, 0.1, 0.7, 0.3, 0.5, 0.4, 0.7, 0.6, 0.0, 0.0, 0.0, 0.0, 0.5, 0.8, 0.2, 0.1, 0.3, 0.3, 0.9, 0.5, 0.6, 0.4, 0.3, 0.6, 0.6, 0.3, 0.0, 0.0, 0.0, 0.3, 0.1, 0.2, 0.6, 0.7, 0.1, 0.6, 0.4, 0.8, 0.8, 0.5, 0.3, 0.5, 0.1, 0.8, 0.0, 0.0, 0.4, 0.6, 0.1, 0.2, 0.2, 0.5, 0.4, 0.5, 0.7, 0.7, 0.7, 0.4, 0.9, 0.2, 0.8, 0.3, 0.0, 0.8, 0.6, 0.1, 0.7, 0.7, 0.5, 0.5, 0.6, 0.8, 0.3, 0.8, 0.8, 0.6, 0.8, 0.2, 0.3, 0.3, 
+
+L3_sTRMM_o_RLT
+0.20000000298, 0.400000017881, 0.260000016689, 1.02000000954, 0.420000014752, 1.30000003353, 2.13000004113, 1.21000003159, 2.74000001237, 2.29000003174, 3.26999997452, 3.09999998212, 3.71000000253, 3.11000005692, 3.54000008017, 3.98999999449, 4.77000009224, 0.40000000596, 0.720000039339, 0.440000017583, 1.14999999255, 0.53000000909, 1.54000003919, 2.20000005364, 1.66000003159, 3.61999995366, 2.94000002801, 3.64999998659, 3.59999997467, 4.16999997228, 3.59000007644, 3.90000009015, 4.21000001967, 5.64000006676, 0.25, 0.380000014305, 0.610000008494, 1.02000000507, 0.689999990761, 1.6700000006, 1.80000004247, 1.41000001594, 2.15000002608, 2.03000000983, 2.79999996498, 2.77000002965, 3.26000000775, 2.34000007048, 3.05000005364, 3.15000005439, 3.99000007942, 0.25, 0.860000010729, 0.490000012368, 0.900000008941, 0.720000009537, 1.48000001803, 1.68000002325, 1.46000004053, 3.21999997452, 3.13999996841, 3.47999997184, 3.25000004247, 3.75000003353, 3.70000007898, 4.38000007465, 4.83000000462, 5.22000010714, 0.25, 0.540000025034, 0.470000032634, 0.970000021458, 0.670000014752, 1.69000002503, 2.1500000447, 1.61000004649, 3.4199999842, 3.05000000298, 3.9999999404, 3.74000001907, 3.92000003114, 3.80000007525, 4.55000006631, 4.95000000149, 5.96000006288, 0.34999999404, 1.14000000119, 0.670000007302, 1.28000001431, 0.590000010133, 1.63000004932, 2.74000002652, 1.83000002027, 3.72999996439, 3.09999997169, 3.2299999547, 2.95999999359, 3.84999998063, 3.38000001803, 2.58000007391, 3.06000003085, 4.27000008479, 0.34999999404, 0.580000014305, 0.650000008196, 1.34999998063, 0.490000005662, 1.34000004366, 1.8900000295, 1.36000002787, 2.88999998927, 2.86999998868, 3.20999996975, 3.70000002086, 4.23999999374, 2.86000007927, 3.95000004321, 4.25999999657, 4.58000010371, 0.449999988079, 1.25999999881, 0.570000008792, 0.930000011325, 0.729999994934, 1.91000001594, 2.28000002176, 1.76000002116, 3.35000000373, 2.94999998882, 3.35999993548, 2.69000005037, 3.57000002965, 3.45000005439, 2.87000004828, 3.56000001073, 4.71000009567, 0.40000000596, 1.20000001788, 0.740000026524, 1.54000002056, 0.750000007451, 1.50000002831, 2.13000002474, 1.6800000307, 3.94999991953, 3.71999996707, 3.46999995589, 3.11000003085, 3.80000003502, 3.33000005528, 3.66000008076, 3.71000002265, 4.49000007421, 0.20000000298, 0.320000015497, 0.420000030398, 1.00000003874, 0.390000017583, 1.1400000377, 1.93000005677, 1.15000004247, 2.12000003263, 1.760000045, 2.17000001401, 1.95000004172, 2.9300000225, 2.4200000304, 2.93000005156, 3.4099999854, 3.82000008479, 
+
+L3_dTRMM_A_mm
+0.2, 0.2, 0.4, 0.1, 0.4, 0.1, 0.6, 0.9, 0.2, 0.5, 0.0, 0.4, 0.8, 0.6, 0.8, 0.9, 0.7, 0.9, 0.6, 0.4, 0.0, 0.0, 0.7, 0.8, 0.1, 0.4, 0.5, 0.2, 0.5, 0.9, 0.0, 0.0, 0.0, 0.7, 0.3, 0.9, 0.1, 0.3, 0.2, 0.3, 0.0, 0.0, 0.0, 0.0, 0.8, 0.3, 0.6, 0.8, 0.4, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.5, 0.1, 0.5, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.9, 0.4, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.7, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 
+
+L3_dTRMM_B_mn
+0.2, 0.5, 0.8, 0.7, 0.7, 0.3, 0.7, 0.7, 0.9, 0.6, 0.8, 0.1, 0.4, 0.3, 0.8, 0.3, 0.4, 0.8, 0.8, 0.4, 0.5, 0.7, 0.2, 0.4, 0.3, 0.8, 0.2, 0.4, 0.5, 0.9, 0.7, 0.5, 0.6, 0.4, 0.7, 0.1, 0.4, 0.4, 0.8, 0.4, 0.8, 0.1, 0.9, 0.8, 0.6, 0.2, 0.4, 0.7, 0.1, 0.2, 0.2, 0.3, 0.9, 0.9, 0.2, 0.4, 0.1, 0.2, 0.4, 0.6, 0.5, 0.4, 0.3, 0.6, 0.9, 0.7, 0.7, 0.9, 0.6, 0.5, 0.7, 0.4, 0.6, 0.3, 0.3, 0.6, 0.2, 0.9, 0.9, 0.2, 0.8, 0.6, 0.8, 0.5, 0.3, 0.4, 0.3, 0.9, 0.6, 0.9, 0.8, 0.7, 0.9, 0.8, 0.4, 0.2, 0.2, 0.4, 0.2, 0.9, 0.5, 0.2, 0.4, 0.1, 0.3, 0.8, 0.7, 0.2, 0.3, 0.6, 0.3, 0.9, 0.2, 0.3, 0.7, 0.1, 0.1, 0.6, 0.4, 0.4, 0.8, 0.6, 0.3, 0.8, 0.9, 0.3, 0.8, 0.7, 0.9, 0.8, 0.9, 0.2, 0.6, 0.9, 0.8, 0.2, 0.5, 0.5, 0.1, 0.6, 0.7, 0.4, 0.9, 0.4, 0.3, 0.6, 0.3, 0.4, 0.3, 0.5, 0.6, 0.3, 0.4, 0.5, 0.4, 0.8, 0.7, 0.8, 0.6, 0.3, 0.5, 0.2, 0.4, 0.3, 0.8, 0.2, 0.9, 0.7, 0.1, 0.2, 
+
+L3_dTRMM_o_LUN
+1.74, 1.7, 2.0, 1.86, 2.65, 1.78, 1.53, 2.02, 1.89, 2.6, 1.95, 1.8, 1.6, 1.98, 2.12, 1.77, 1.07, 3.04, 2.86, 3.52, 2.97, 4.4, 2.85, 2.93, 3.31, 3.38, 4.06, 2.94, 2.46, 2.97, 3.31, 3.67, 3.03, 2.06, 1.93, 1.78, 2.47, 2.11, 2.88, 1.73, 1.96, 1.92, 2.07, 2.5, 1.59, 1.73, 1.72, 2.58, 2.23, 1.65, 1.59, 1.16, 1.52, 2.12, 1.3, 1.96, 1.43, 1.25, 1.8, 1.56, 1.58, 1.14, 1.07, 1.27, 1.55, 2.15, 1.48, 1.14, 1.71, 1.67, 2.09, 1.95, 2.65, 1.9, 1.44, 2.26, 1.4, 2.62, 1.87, 1.84, 1.6, 1.91, 2.42, 1.74, 1.0, 1.05, 0.81, 1.39, 1.55, 1.91, 1.35, 1.38, 1.59, 1.17, 1.36, 0.63, 0.94, 0.96, 0.9, 1.53, 1.02, 0.68, 0.84, 1.1, 0.96, 0.95, 1.46, 1.25, 0.81, 1.2, 0.89, 1.39, 1.0, 1.35, 0.52, 1.12, 1.35, 1.0, 0.5, 0.87, 1.15, 0.87, 0.94, 1.45, 1.24, 0.99, 1.12, 0.85, 1.3, 0.97, 1.32, 0.45, 1.19, 1.42, 0.89, 0.52, 0.7, 0.64, 0.56, 0.9, 1.04, 0.68, 0.9, 0.62, 0.36, 0.72, 0.42, 0.8, 0.36, 0.94, 0.9, 0.3, 0.44, 0.15, 0.12, 0.24, 0.21, 0.24, 0.18, 0.09, 0.15, 0.06, 0.12, 0.09, 0.24, 0.06, 0.27, 0.21, 0.03, 0.06, 
+
+L3_dTRMM_A_nn
+0.4, 0.0, 0.0, 0.0, 0.0, 0.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.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 0.8, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.3, 0.3, 0.4, 0.0, 0.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, 0.3, 0.7, 0.3, 0.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.7, 0.5, 0.5, 0.3, 0.7, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.7, 0.4, 0.3, 0.7, 0.7, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 0.5, 0.7, 0.9, 0.4, 0.8, 0.1, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.4, 0.8, 0.1, 0.8, 0.9, 0.3, 0.9, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.8, 0.4, 0.8, 0.8, 0.4, 0.9, 0.6, 0.7, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.1, 0.9, 0.2, 0.4, 0.3, 0.9, 0.9, 0.3, 0.1, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 0.6, 0.9, 0.9, 0.9, 0.9, 0.8, 0.3, 0.5, 0.2, 0.4, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.7, 0.3, 0.4, 0.3, 0.5, 0.2, 0.3, 0.3, 0.8, 0.2, 0.7, 0.4, 0.0, 0.0, 0.0, 0.0, 0.7, 0.1, 0.1, 0.1, 0.8, 0.3, 0.6, 0.3, 0.1, 0.2, 0.9, 0.4, 0.7, 0.7, 0.0, 0.0, 0.0, 0.7, 0.3, 0.8, 0.7, 0.7, 0.6, 0.2, 0.6, 0.4, 0.3, 0.7, 0.9, 0.8, 0.3, 0.6, 0.0, 0.0, 0.4, 0.7, 0.4, 0.4, 0.2, 0.1, 0.5, 0.6, 0.6, 0.4, 0.9, 0.4, 0.3, 0.7, 0.3, 0.1, 0.0, 0.6, 0.1, 0.2, 0.2, 0.6, 0.4, 0.9, 0.7, 0.4, 0.4, 0.4, 0.6, 0.1, 0.5, 0.6, 0.2, 0.3, 
+
+L3_dTRMM_o_RLT
+0.08, 0.32, 1.1, 0.85, 1.09, 1.58, 2.27, 2.31, 2.87, 3.92, 3.39, 4.36, 2.9, 3.08, 4.73, 4.11, 3.96, 0.32, 0.56, 1.48, 1.28, 1.14, 1.86, 2.1, 2.23, 2.14, 3.4, 2.17, 3.72, 3.27, 3.48, 4.68, 3.87, 3.65, 0.28, 0.13, 0.85, 0.94, 0.86, 1.54, 2.12, 1.92, 2.07, 3.36, 2.55, 3.89, 2.94, 3.49, 3.93, 3.47, 3.61, 0.12, 0.57, 1.56, 0.89, 1.15, 1.48, 1.67, 1.81, 2.14, 2.74, 2.2, 3.06, 2.69, 2.69, 4.07, 3.75, 3.35, 0.24, 0.36, 1.31, 1.06, 1.12, 1.65, 1.83, 2.15, 2.3, 2.94, 2.71, 3.6, 3.25, 3.58, 4.89, 4.01, 3.77, 0.16, 0.22, 1.15, 0.96, 1.19, 1.93, 2.69, 2.85, 3.64, 4.17, 3.48, 4.75, 3.06, 2.95, 4.98, 3.6, 4.21, 0.16, 0.1, 0.57, 0.8, 0.75, 1.27, 1.45, 1.85, 1.86, 2.79, 1.97, 3.0, 2.73, 2.45, 3.59, 2.55, 2.82, 0.16, 0.52, 1.34, 0.9, 1.03, 1.9, 2.47, 2.6, 3.34, 3.83, 3.12, 4.52, 4.01, 3.67, 5.65, 4.65, 4.75, 0.2, 0.35, 0.82, 0.87, 0.72, 1.44, 2.3, 1.98, 2.03, 3.33, 2.26, 3.54, 2.81, 2.95, 3.77, 3.2, 3.7, 0.2, 0.29, 1.23, 1.09, 1.22, 1.9, 2.21, 2.67, 2.7, 3.16, 2.5, 3.97, 3.08, 3.15, 4.86, 3.53, 3.79, 
+
+L3_cTRMM_A_mm
+0.40000000596, 0.300000011921, 0.10000000149, 0.300000011921, 0.699999988079, 0.40000000596, 0.899999976158, 0.300000011921, 0.5, 0.300000011921, 0.40000000596, 0.899999976158, 0.899999976158, 0.5, 0.600000023842, 0.699999988079, 0.10000000149, 0.5, 0.5, 0.300000011921, 0.0, 0.0, 0.5, 0.899999976158, 0.800000011921, 0.10000000149, 0.40000000596, 0.40000000596, 0.899999976158, 0.800000011921, 0.10000000149, 0.800000011921, 0.699999988079, 0.20000000298, 0.699999988079, 0.800000011921, 0.10000000149, 0.5, 0.699999988079, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.10000000149, 0.40000000596, 0.600000023842, 0.300000011921, 0.10000000149, 0.5, 0.20000000298, 0.300000011921, 0.300000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.699999988079, 0.800000011921, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.800000011921, 0.20000000298, 0.20000000298, 0.5, 0.600000023842, 0.10000000149, 0.600000023842, 0.800000011921, 0.20000000298, 0.800000011921, 0.40000000596, 0.300000011921, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.10000000149, 0.699999988079, 0.10000000149, 0.899999976158, 0.899999976158, 0.300000011921, 0.600000023842, 0.899999976158, 0.600000023842, 0.300000011921, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.10000000149, 0.699999988079, 0.5, 0.10000000149, 0.5, 0.10000000149, 0.40000000596, 0.300000011921, 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.300000011921, 0.899999976158, 0.20000000298, 0.600000023842, 0.5, 0.800000011921, 0.699999988079, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.5, 0.600000023842, 0.10000000149, 0.20000000298, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.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, 0.40000000596, 0.600000023842, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.600000023842, 
+
+L3_cTRMM_B_mn
+0.20000000298, 0.10000000149, 0.800000011921, 0.800000011921, 0.300000011921, 0.699999988079, 0.40000000596, 0.10000000149, 0.899999976158, 0.300000011921, 0.10000000149, 0.20000000298, 0.40000000596, 0.699999988079, 0.300000011921, 0.600000023842, 0.10000000149, 0.40000000596, 0.10000000149, 0.899999976158, 0.20000000298, 0.10000000149, 0.40000000596, 0.899999976158, 0.300000011921, 0.300000011921, 0.20000000298, 0.10000000149, 0.5, 0.10000000149, 0.600000023842, 0.40000000596, 0.899999976158, 0.5, 0.40000000596, 0.300000011921, 0.800000011921, 0.5, 0.5, 0.20000000298, 0.800000011921, 0.10000000149, 0.20000000298, 0.5, 0.800000011921, 0.10000000149, 0.699999988079, 0.40000000596, 0.899999976158, 0.40000000596, 0.20000000298, 0.5, 0.300000011921, 0.600000023842, 0.300000011921, 0.699999988079, 0.20000000298, 0.300000011921, 0.10000000149, 0.10000000149, 0.5, 0.300000011921, 0.20000000298, 0.699999988079, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.899999976158, 0.800000011921, 0.899999976158, 0.899999976158, 0.5, 0.699999988079, 0.10000000149, 0.300000011921, 0.300000011921, 0.600000023842, 0.699999988079, 0.10000000149, 0.300000011921, 0.40000000596, 0.600000023842, 0.300000011921, 0.699999988079, 0.10000000149, 0.10000000149, 0.899999976158, 0.40000000596, 0.600000023842, 0.899999976158, 0.600000023842, 0.699999988079, 0.40000000596, 0.300000011921, 0.300000011921, 0.10000000149, 0.800000011921, 0.600000023842, 0.5, 0.800000011921, 0.600000023842, 0.5, 0.5, 0.600000023842, 0.20000000298, 0.10000000149, 0.300000011921, 0.20000000298, 0.699999988079, 0.699999988079, 0.20000000298, 0.5, 0.40000000596, 0.20000000298, 0.20000000298, 0.699999988079, 0.300000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.20000000298, 0.40000000596, 0.10000000149, 0.20000000298, 0.600000023842, 0.10000000149, 0.699999988079, 0.20000000298, 0.699999988079, 0.600000023842, 0.20000000298, 0.40000000596, 0.800000011921, 0.600000023842, 0.300000011921, 0.899999976158, 0.699999988079, 0.899999976158, 0.20000000298, 0.600000023842, 0.40000000596, 0.300000011921, 0.10000000149, 0.899999976158, 0.40000000596, 0.40000000596, 0.5, 0.5, 0.20000000298, 0.699999988079, 0.10000000149, 0.40000000596, 0.899999976158, 0.300000011921, 0.600000023842, 0.800000011921, 0.10000000149, 0.20000000298, 0.20000000298, 0.40000000596, 0.600000023842, 0.899999976158, 0.600000023842, 0.20000000298, 0.10000000149, 0.5, 0.899999976158, 0.800000011921, 0.699999988079, 0.300000011921, 0.20000000298, 0.10000000149, 0.800000011921, 0.600000023842, 0.20000000298, 0.40000000596, 0.600000023842, 0.300000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.600000023842, 0.5, 0.5, 0.699999988079, 0.899999976158, 0.800000011921, 0.300000011921, 0.699999988079, 0.899999976158, 0.600000023842, 0.5, 0.800000011921, 0.10000000149, 0.600000023842, 0.600000023842, 0.5, 0.600000023842, 0.20000000298, 0.899999976158, 0.5, 0.300000011921, 0.899999976158, 0.300000011921, 0.20000000298, 0.10000000149, 0.699999988079, 0.40000000596, 0.800000011921, 0.10000000149, 0.600000023842, 0.800000011921, 0.10000000149, 0.40000000596, 0.699999988079, 0.10000000149, 0.699999988079, 0.20000000298, 0.10000000149, 0.5, 0.5, 0.899999976158, 0.5, 0.5, 0.600000023842, 0.300000011921, 0.10000000149, 0.5, 0.40000000596, 0.300000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.899999976158, 0.600000023842, 0.699999988079, 0.20000000298, 0.20000000298, 0.10000000149, 0.300000011921, 0.300000011921, 0.20000000298, 0.600000023842, 0.899999976158, 0.5, 0.800000011921, 0.40000000596, 0.600000023842, 0.899999976158, 0.40000000596, 0.899999976158, 0.20000000298, 0.10000000149, 0.600000023842, 0.300000011921, 0.800000011921, 0.600000023842, 0.300000011921, 0.300000011921, 0.800000011921, 0.20000000298, 0.40000000596, 0.600000023842, 0.300000011921, 0.899999976158, 0.800000011921, 0.300000011921, 0.699999988079, 0.899999976158, 0.5, 0.600000023842, 0.300000011921, 0.20000000298, 0.5, 0.40000000596, 0.600000023842, 0.300000011921, 0.20000000298, 0.5, 0.300000011921, 0.300000011921, 0.699999988079, 0.800000011921, 0.800000011921, 0.40000000596, 0.20000000298, 0.699999988079, 0.20000000298, 0.800000011921, 0.699999988079, 0.600000023842, 0.899999976158, 0.40000000596, 0.5, 0.800000011921, 0.800000011921, 0.899999976158, 0.800000011921, 0.800000011921, 0.800000011921, 0.600000023842, 0.699999988079, 0.20000000298, 0.20000000298, 0.600000023842, 0.899999976158, 0.600000023842, 0.10000000149, 0.10000000149, 0.800000011921, 0.600000023842, 0.20000000298, 0.899999976158, 0.5, 0.10000000149, 0.899999976158, 0.600000023842, 0.600000023842, 0.899999976158, 0.300000011921, 0.800000011921, 0.40000000596, 0.5, 0.40000000596, 0.20000000298, 0.300000011921, 0.600000023842, 0.899999976158, 0.20000000298, 0.800000011921, 0.699999988079, 0.5, 0.899999976158, 0.300000011921, 0.20000000298, 0.899999976158, 0.300000011921, 0.699999988079, 0.699999988079, 
+
+L3_cTRMM_o_LUN
+1.20999991462, 4.01000003383, 0.0499999791384, 4.42000002667, -1.7881393255e-08, 4.82000009298, -0.58000000909, 4.27000000581, 1.82999994054, 3.96000008076, 0.719999982715, 5.26999998868, -0.689999937117, 4.85000002608, 0.399999979138, 3.61000006214, 0.579999932349, 4.64999999478, -0.0200000356138, 5.02000002369, 0.409999944419, 4.45000004992, 0.329999956191, 4.50000004321, -0.370000042319, 4.55000005513, -0.839999965429, 5.40000000224, 0.210000030845, 4.31000002563, 0.9299999547, 6.43999997437, 0.739999976605, 4.91000007182, 1.41999991417, 4.36000002638, 0.569999943972, 4.48999999523, 0.629999959916, 4.71000008672, -0.090000051856, 4.40000000373, 1.30999993324, 4.10000006109, 0.869999968559, 5.40999998167, -0.159999991357, 5.03999997139, 0.719999987185, 3.92999999344, -0.150000028312, 4.65999998465, -0.260000080019, 4.97000007138, 0.389999981821, 4.76000007331, 0.609999915361, 3.51000007853, -0.160000077039, 4.03000004262, -0.560000049472, 5.73999997959, -0.119999984205, 4.40000006557, 0.529999935329, 6.20999993175, 0.639999949783, 4.5700000535, 1.50000001118, 2.7400000973, 0.720000019222, 2.88000007167, 1.06000004277, 2.95000012442, -0.260000005513, 3.08000005081, 1.39000003919, 2.64000010699, 1.29999999925, 3.69000007421, 0.800000077486, 3.37000004455, 0.640000051856, 2.91000005841, 0.960000010729, 3.52000007883, 0.850000009686, 3.88000009701, 1.4299999994, 3.30000010133, 1.16999998644, 3.15000009611, 0.52000005424, 3.78000006571, 0.190000057817, 4.06000006512, 0.840000045896, 3.20000012219, 1.51999998197, 3.74000005335, 0.96000002861, 3.6800001134, 0.0199999730289, 2.85000004917, -0.0700000229478, 2.36000007033, -0.230000023991, 3.09000014871, -0.97000004679, 2.88000004411, 1.16999999166, 3.05000008717, 0.289999953508, 4.4700000535, -0.289999965429, 3.37000008181, -0.3700000453, 2.95000004768, 0.0699999417365, 3.96000007406, 0.659999974221, 3.86000011429, 0.469999910444, 3.1700000982, 0.189999958724, 3.4900000757, -0.870000002831, 3.92000007659, -1.05999997422, 4.2400000675, 0.850000028312, 2.85000013337, 0.329999918193, 4.66000001967, -0.390000009388, 3.97000010788, 0.359999980927, 2.01000004351, -0.390000011623, 2.42000000432, -3.27825566693e-08, 2.97000008851, -0.840000036955, 2.78000003666, 1.03999998555, 2.56000006139, 0.0299999241531, 3.80000002384, -0.439999979585, 3.18000004113, -0.200000037998, 2.20999999583, 0.0199999387562, 3.36000002712, 0.619999900758, 3.79000000864, 0.759999867678, 3.12000005946, 0.689999961704, 3.17000004679, -0.160000047237, 3.74000003994, -0.739999984801, 3.86000001147, 0.170000012517, 3.05000004321, 1.07999987647, 3.8499999918, -0.0200000751019, 3.39000000119, 0.189999998212, 1.34000001833, -0.540000004172, 1.60999999732, -0.120000011027, 1.97000004455, -0.740000004172, 1.93000001803, 0.580000000894, 1.58000002921, -0.130000025481, 2.3, -0.669999948442, 2.17000000954, -0.230000004619, 1.36000000849, 0.129999959171, 2.09000001907, 0.149999959767, 2.37999998525, 0.219999936521, 2.09000004292, 0.309999989867, 2.04000000864, -0.489999997467, 2.24000003472, -0.82999995023, 2.34999999627, -0.149999988079, 1.95000000671, 0.639999939352, 2.58999997884, -0.100000025332, 2.15999997571, 0.269999967813, 1.59000003397, -0.759999992847, 1.25000003129, -0.540000028014, 2.21000007331, -1.15000002012, 2.03000000164, 0.289999991506, 1.97000004381, -0.830000032187, 2.85000003725, -0.919999965578, 2.4300000225, -0.619999999851, 1.54000001088, -0.820000011027, 2.09000003546, -0.310000043511, 2.72000001103, -0.410000042021, 2.3300000307, 0.199999957532, 2.12000004008, -0.530000002384, 2.83000001431, -1.44999996871, 2.77000001997, -0.719999981225, 2.19000006825, 0.0299999442697, 2.81999997973, -0.400000061095, 2.33999999374, -0.109999998063, 1.00999998912, 0.0900000071526, 0.560000021905, -0.209999989122, 1.08000002772, -0.679999966621, 1.13999999896, 0.0600000137091, 1.02000001773, -0.289999989271, 1.69000001609, -0.479999927878, 1.21000002488, -0.479999988973, 0.920000021458, -0.319999990165, 1.21000004128, 0.079999999404, 1.2100000383, 0.0199999953806, 0.840000030994, 0.240000008643, 1.6200000073, -0.199999962002, 1.58000001431, -0.54999993369, 1.33000002548, 0.270000022948, 1.12000004455, -0.00999998614192, 1.31999997526, -0.539999991506, 1.3200000155, 0.550000007451, 0.670000035614, 0.139999998212, 0.470000009537, 0.600000028312, 0.830000050068, -0.0699999938905, 0.890000010133, 0.320000011027, 0.38000001654, 0.509999988377, 1.13000003293, 0.510000030845, 1.12000002295, -0.0799999859929, 0.940000024289, -0.0299999956787, 0.820000021458, 0.329999993443, 0.740000019073, 0.409999994338, 0.950000029057, 0.44999999702, 0.810000014454, 0.450000036508, 1.27000000954, 0.290000009388, 1.31000002339, 0.320000006557, 0.770000029653, 0.779999997169, 0.650000014156, 0.209999998063, 0.870000023693, -0.180000030696, 0.660000013709, -0.0400000026822, 0.0800000038743, -0.200000023842, 0.600000032783, -0.50000000596, 0.30000000447, 0.0399999982119, 0.320000012517, -0.180000030696, 0.660000013709, -0.420000000596, 0.540000026524, -0.420000022948, 0.340000019073, -0.220000009537, 0.340000014603, -0.0400000041723, 0.280000014305, -0.300000025332, 0.300000020862, 0.0599999913573, 0.580000008345, -0.260000004768, 0.620000025928, -0.440000005662, 0.480000009835, -0.0600000032783, 0.220000015497, -1.63912776685e-08, 0.600000010431, -0.280000009835, 0.560000009239, 
+
+L3_cTRMM_A_nn
+0.20000000298, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.20000000298, 0.40000000596, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.300000011921, 0.5, 0.600000023842, 0.40000000596, 0.40000000596, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.899999976158, 0.300000011921, 0.800000011921, 0.899999976158, 0.10000000149, 0.40000000596, 0.20000000298, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.10000000149, 0.699999988079, 0.5, 0.800000011921, 0.40000000596, 0.899999976158, 0.20000000298, 0.10000000149, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.40000000596, 0.899999976158, 0.10000000149, 0.5, 0.40000000596, 0.899999976158, 0.699999988079, 0.899999976158, 0.40000000596, 0.300000011921, 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.800000011921, 0.800000011921, 0.5, 0.899999976158, 0.40000000596, 0.699999988079, 0.5, 0.20000000298, 0.899999976158, 0.20000000298, 0.5, 0.600000023842, 0.300000011921, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.20000000298, 0.699999988079, 0.899999976158, 0.5, 0.699999988079, 0.10000000149, 0.600000023842, 0.800000011921, 0.800000011921, 0.5, 0.899999976158, 0.5, 0.5, 0.899999976158, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.5, 0.300000011921, 0.5, 0.899999976158, 0.600000023842, 0.40000000596, 0.40000000596, 0.699999988079, 0.800000011921, 0.699999988079, 0.699999988079, 0.40000000596, 0.699999988079, 0.899999976158, 0.300000011921, 0.899999976158, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.300000011921, 0.20000000298, 0.10000000149, 0.20000000298, 0.899999976158, 0.300000011921, 0.699999988079, 0.600000023842, 0.20000000298, 0.600000023842, 0.20000000298, 0.899999976158, 0.600000023842, 0.5, 0.5, 0.899999976158, 0.300000011921, 0.10000000149, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.800000011921, 0.20000000298, 0.20000000298, 0.699999988079, 0.5, 0.300000011921, 0.699999988079, 0.20000000298, 0.800000011921, 0.800000011921, 0.10000000149, 0.300000011921, 0.600000023842, 0.10000000149, 0.300000011921, 0.899999976158, 0.10000000149, 0.40000000596, 0.800000011921, 0.20000000298, 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.600000023842, 0.600000023842, 0.800000011921, 0.699999988079, 0.899999976158, 0.800000011921, 0.300000011921, 0.800000011921, 0.5, 0.10000000149, 0.40000000596, 0.300000011921, 0.40000000596, 0.40000000596, 0.600000023842, 0.20000000298, 0.600000023842, 0.300000011921, 0.40000000596, 0.40000000596, 0.5, 0.800000011921, 0.40000000596, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.899999976158, 0.40000000596, 0.20000000298, 0.600000023842, 0.600000023842, 0.600000023842, 0.20000000298, 0.899999976158, 0.600000023842, 0.800000011921, 0.300000011921, 0.20000000298, 0.699999988079, 0.899999976158, 0.300000011921, 0.899999976158, 0.800000011921, 0.800000011921, 0.800000011921, 0.5, 0.600000023842, 0.699999988079, 0.40000000596, 0.300000011921, 0.899999976158, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.10000000149, 0.800000011921, 0.40000000596, 0.699999988079, 0.20000000298, 0.300000011921, 0.800000011921, 0.600000023842, 0.40000000596, 0.20000000298, 0.800000011921, 0.600000023842, 0.5, 0.10000000149, 0.40000000596, 0.40000000596, 0.10000000149, 0.699999988079, 0.300000011921, 0.300000011921, 0.600000023842, 0.40000000596, 0.20000000298, 0.20000000298, 0.800000011921, 0.300000011921, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.600000023842, 0.20000000298, 0.300000011921, 0.40000000596, 0.699999988079, 0.20000000298, 0.40000000596, 0.20000000298, 0.300000011921, 0.40000000596, 0.5, 0.40000000596, 0.300000011921, 0.40000000596, 0.800000011921, 0.5, 0.699999988079, 0.40000000596, 0.20000000298, 0.800000011921, 0.699999988079, 0.899999976158, 0.699999988079, 0.5, 0.20000000298, 0.800000011921, 0.600000023842, 0.300000011921, 0.5, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.10000000149, 0.5, 0.10000000149, 0.20000000298, 0.20000000298, 0.40000000596, 0.40000000596, 0.40000000596, 0.10000000149, 0.899999976158, 0.699999988079, 0.699999988079, 0.600000023842, 0.600000023842, 0.899999976158, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 0.899999976158, 0.899999976158, 0.300000011921, 0.600000023842, 0.10000000149, 0.20000000298, 0.899999976158, 0.800000011921, 0.20000000298, 0.40000000596, 0.300000011921, 0.300000011921, 0.0, 0.0, 0.800000011921, 0.40000000596, 0.800000011921, 0.40000000596, 0.20000000298, 0.5, 0.800000011921, 0.899999976158, 0.899999976158, 0.10000000149, 0.800000011921, 0.20000000298, 0.800000011921, 0.600000023842, 0.300000011921, 0.600000023842, 0.300000011921, 0.40000000596, 0.800000011921, 0.899999976158, 0.40000000596, 0.300000011921, 0.5, 0.899999976158, 0.20000000298, 0.5, 0.600000023842, 0.699999988079, 0.300000011921, 0.600000023842, 0.40000000596, 0.600000023842, 0.300000011921, 0.40000000596, 
+
+L3_cTRMM_o_RLT
+-0.0499999977648, 0.19999999851, 0.0, 0.690000020564, 0.220000025928, 1.24000003994, -0.119999972284, 1.80000002235, 0.499999985844, 2.47000002071, 1.51999994099, 2.52999999866, 0.29999999702, 2.84000002429, -0.530000004619, 4.62000002667, -0.110000024885, 4.5400000228, -0.339999979585, 3.36000003532, -1.12000000656, 3.98000002921, -0.0599999630451, 5.09000008389, -0.590000014603, 6.07000006318, 0.0400000190735, 5.19000006974, -0.629999966621, 5.10000006333, -0.809999958575, 5.26000009045, -0.469999935776, 7.20000013337, -0.190000001192, 0.419999999106, 0.10000000447, 0.63000001654, 0.430000026226, 1.04000003472, 0.570000022203, 1.91000001669, 1.29999997988, 1.78000002474, 1.81999998048, 2.8100000003, 1.06000002563, 3.38000003889, 0.929999952465, 5.0799999994, 1.58999994829, 4.72000002518, 1.24999997839, 4.06000001892, 0.209999980181, 4.28000007316, 1.21000002787, 5.49000013605, 1.09999997392, 5.90000008792, 0.83000001356, 5.43000014022, 0.890000019819, 5.60000008866, 0.989999984801, 6.77000004828, 1.35000002608, 7.62000014514, -0.539999993742, 0.969999961853, -0.0700000058115, 0.979999991953, 0.18000001207, 1.92000000432, 0.209999977201, 2.86999995068, 0.549999929965, 3.01999998197, 1.06999991044, 3.74999996051, -0.0899999855459, 4.6399999848, -0.390000008643, 4.98999997437, 0.939999930412, 5.1500000298, 0.389999995977, 3.47000006616, -0.52000011161, 4.48000004187, 0.51999998793, 6.350000076, 0.53999991551, 8.0200000684, 0.239999934137, 6.27000008255, 0.599999951571, 7.0100001061, -0.190000031739, 7.09000009581, -0.200000014156, 9.31000015229, -0.349999986589, 0.549999989569, 0.110000009984, 0.470000017732, 0.190000031739, 0.890000032485, 0.390000005662, 1.55000000969, 0.569999988675, 2.23000000462, 0.789999979585, 2.57999998152, 0.549999973178, 2.92000003859, 0.309999955595, 3.64000002131, 1.44999990836, 4.17000003189, 1.01999997079, 2.88000005081, 0.75999995932, 4.12000006616, 1.32000002369, 4.28000013053, 1.70999994591, 6.17000011235, 0.150000018626, 4.17000011086, 1.08999998629, 5.71000009939, 0.559999984652, 6.12000002593, 0.440000061542, 7.31000016198, -0.449999974668, 0.949999956787, 0.229999992698, 0.689999995977, 0.580000026226, 1.36000000328, 1.07999994725, 2.22999995619, 1.5099999541, 2.46000000328, 1.99999989942, 2.92999999642, 1.27999995321, 4.01999997824, 1.23999995053, 4.65999997795, 1.63999995723, 5.58999996766, 1.13999998704, 4.13000001952, 0.669999960363, 5.82000000432, 2.09999999553, 5.76000010684, 1.18999996915, 7.4600000748, 1.33999998108, 5.62000011757, 1.77999997109, 6.42000006616, 1.71999991044, 6.76000004724, 1.75999998987, 8.40000013933, -0.119999994636, 0.310000004768, -0.290000007898, 0.440000014603, -0.0499999880791, 0.870000042319, -0.489999992251, 1.46000004575, 0.34999999851, 2.01000004426, 0.619999993891, 3.05000002086, 0.26000002265, 2.95000007376, -0.610000015199, 4.52000000432, 1.12999991521, 5.20000003949, 0.799999967963, 4.41000006661, 0.339999928921, 4.64000010177, 0.449999976903, 6.20000017807, 0.459999905676, 7.94000013158, -0.470000032634, 6.16000015303, 0.519999950677, 7.09000008762, 0.149999950081, 8.36000007331, -0.59999993518, 9.28000022888, -0.119999994636, 0.310000004768, -0.249999997765, 0.40000000447, -0.149999988079, 1.0300000307, -0.719999984205, 1.30000001714, -0.0999999985099, 2.56000004351, 0.149999987334, 2.89000001311, -0.529999977052, 2.82000004828, -1.3499999471, 3.5400000079, -0.340000010133, 4.40000003129, -0.509999987632, 3.44000001386, -0.49000004366, 4.94000005037, -0.690000028759, 4.96000008896, 0.269999961108, 6.73000012755, -0.81000003159, 5.29000010625, -0.489999994487, 6.66000005543, -1.00000000298, 7.27999995396, -0.8699999924, 8.25000009984, -0.0499999977648, 0.19999999851, 0.0, 0.290000014603, 0.0900000093877, 0.6900000377, -0.0200000102818, 1.08000002399, 0.659999934733, 2.1600000532, 0.949999964982, 3.16000000328, 0.399999985844, 3.11000004947, -0.929999945015, 4.41000004798, 0.120000024438, 4.89000004515, 0.320000044554, 4.18000002176, -0.119999998361, 5.15000008568, 0.450000029802, 5.11000013292, 1.06999999613, 6.93000019833, -0.35999995634, 5.96000017613, 0.50000000447, 6.42000015557, -0.169999943972, 8.06000004351, 0.460000067353, 9.7000001274, -0.119999994636, 0.310000004768, 0.0299999986589, 0.440000011623, 0.340000024289, 0.830000035167, 0.130000006855, 1.45000002012, 0.629999998659, 1.88000003219, 0.509999994338, 2.63000002697, 0.280000000894, 3.23000005752, -0.760000001043, 4.45000000522, 0.0399999758601, 5.2600000301, 0.1199999924, 4.28000008658, 0.0399999579787, 5.1700001049, 0.60999996677, 6.03000015885, -0.130000023246, 8.57000011981, -0.380000005364, 6.47000017196, 0.0799999830127, 8.20000010282, 0.129999892861, 8.78000005901, -0.219999980479, 9.70000022873, -0.360000009239, 0.929999963641, -0.0300000075996, 0.320000003576, 0.25, 1.05000002235, 0.319999938756, 1.58000002399, 0.979999971837, 2.59000001535, 0.559999954849, 3.36999998719, 0.629999933094, 3.99000004515, -0.880000023991, 4.76999999836, 0.57999994427, 6.07000003561, -0.279999985993, 4.76000003904, 0.0199999335408, 5.36000010833, 0.269999950677, 5.7800001812, 0.599999976158, 8.3600001277, -0.709999995828, 5.8500001289, 0.689999985546, 7.53000014022, -0.420000028163, 8.05000004396, 0.150000028312, 9.57000013173, 
+
+L3_zTRMM_A_mm
+0.9, 0.9, 0.6, 0.1, 0.9, 0.2, 0.2, 0.6, 0.9, 0.9, 0.7, 0.6, 0.8, 0.8, 0.4, 0.3, 0.4, 0.8, 0.9, 0.5, 0.0, 0.0, 0.7, 0.5, 0.8, 0.1, 0.9, 0.2, 0.3, 0.1, 0.4, 0.6, 0.7, 0.7, 0.9, 0.8, 0.3, 0.3, 0.7, 0.1, 0.0, 0.0, 0.0, 0.0, 0.4, 0.9, 0.1, 0.9, 0.1, 0.6, 0.5, 0.9, 0.8, 0.6, 0.3, 0.8, 0.6, 0.7, 0.2, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.9, 0.8, 0.8, 0.4, 0.5, 0.7, 0.3, 0.6, 0.8, 0.6, 0.7, 0.7, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.6, 0.7, 0.2, 0.5, 0.8, 0.5, 0.9, 0.6, 0.1, 0.1, 0.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.6, 0.5, 0.8, 0.7, 0.1, 0.2, 0.2, 0.7, 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.3, 0.9, 0.1, 0.6, 0.5, 0.5, 0.8, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6, 0.1, 0.8, 0.9, 0.7, 0.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.2, 0.2, 0.1, 0.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.7, 0.8, 
+
+L3_zTRMM_B_mn
+0.8, 0.2, 0.7, 0.9, 0.2, 0.9, 0.2, 0.5, 0.1, 0.7, 0.6, 0.9, 0.4, 0.7, 0.2, 0.6, 0.4, 0.9, 0.1, 0.6, 0.3, 0.4, 0.5, 0.3, 0.9, 0.2, 0.6, 0.4, 0.2, 0.7, 0.8, 0.8, 0.2, 0.4, 0.9, 0.9, 0.5, 0.5, 0.3, 0.9, 0.7, 0.7, 0.2, 0.8, 0.4, 0.1, 0.5, 0.3, 0.2, 0.2, 0.4, 0.3, 0.9, 0.8, 0.3, 0.9, 0.8, 0.7, 0.1, 0.6, 0.6, 0.5, 0.1, 0.7, 0.4, 0.8, 0.6, 0.6, 0.6, 0.4, 0.4, 0.7, 0.1, 0.4, 0.9, 0.4, 0.9, 0.8, 0.6, 0.9, 0.4, 0.4, 0.7, 0.8, 0.9, 0.3, 0.8, 0.8, 0.1, 0.2, 0.7, 0.9, 0.4, 0.9, 0.4, 0.3, 0.4, 0.8, 0.7, 0.6, 0.2, 0.2, 0.1, 0.6, 0.5, 0.2, 0.2, 0.2, 0.7, 0.1, 0.7, 0.7, 0.1, 0.8, 0.9, 0.3, 0.7, 0.2, 0.8, 0.3, 0.2, 0.3, 0.4, 0.7, 0.8, 0.1, 0.8, 0.1, 0.2, 0.6, 0.8, 0.7, 0.9, 0.1, 0.4, 0.9, 0.1, 0.3, 0.1, 0.9, 0.2, 0.9, 0.1, 0.4, 0.5, 0.9, 0.2, 0.2, 0.4, 0.1, 0.7, 0.1, 0.6, 0.9, 0.5, 0.9, 0.9, 0.8, 0.2, 0.2, 0.7, 0.6, 0.8, 0.1, 0.8, 0.8, 0.6, 0.2, 0.4, 0.3, 0.2, 0.5, 0.6, 0.2, 0.1, 0.6, 0.5, 0.7, 0.5, 0.1, 0.7, 0.3, 0.8, 0.3, 0.5, 0.1, 0.2, 0.8, 0.8, 0.2, 0.7, 0.1, 0.5, 0.5, 0.1, 0.2, 0.5, 0.9, 0.5, 0.4, 0.4, 0.6, 0.8, 0.7, 0.8, 0.9, 0.8, 0.8, 0.8, 0.2, 0.4, 0.2, 0.8, 0.8, 0.6, 0.9, 0.9, 0.1, 0.5, 0.9, 0.8, 0.3, 0.6, 0.3, 0.2, 0.3, 0.1, 0.3, 0.9, 0.7, 0.2, 0.7, 0.7, 0.4, 0.4, 0.6, 0.1, 0.1, 0.5, 0.7, 0.3, 0.7, 0.6, 0.9, 0.9, 0.3, 0.7, 0.7, 0.7, 0.4, 0.8, 0.7, 0.3, 0.6, 0.7, 0.3, 0.8, 0.8, 0.1, 0.7, 0.1, 0.9, 0.8, 0.4, 0.6, 0.3, 0.7, 0.2, 0.6, 0.8, 0.4, 0.5, 0.9, 0.7, 0.1, 0.3, 0.3, 0.8, 0.8, 0.1, 0.7, 0.2, 0.7, 0.8, 0.3, 0.4, 0.6, 0.9, 0.1, 0.5, 0.1, 0.9, 0.4, 0.3, 0.2, 0.6, 0.4, 0.6, 0.1, 0.7, 0.7, 0.3, 0.2, 0.1, 0.4, 0.3, 0.9, 0.6, 0.9, 0.7, 0.5, 0.2, 0.8, 0.4, 0.4, 0.6, 0.5, 0.8, 0.5, 0.8, 0.4, 0.7, 0.9, 0.4, 0.9, 0.1, 0.6, 0.4, 0.2, 0.6, 0.4, 0.3, 0.9, 0.7, 0.1, 0.6, 0.3, 0.8, 0.8, 0.6, 
+
+L3_zTRMM_o_LUN
+0.99, 6.8, 0.02, 7.17, -1.25, 5.9, 1.74, 5.65, 0.05, 7.46, -0.22, 7.01, 1.53, 6.09, 0.21, 6.39, 0.72, 6.71, 0.91, 6.4, 0.24, 5.61, 0.28, 5.43, 1.2, 6.83, 0.6, 6.05, -0.12, 7.12, 0.78, 6.95, 0.38, 5.06, 0.82, 5.65, 1.03, 4.89, 0.01, 4.43, 2.64, 4.23, 1.51, 5.86, 1.03, 5.44, 2.44, 4.73, 1.08, 4.45, 2.38, 4.09, 1.84, 5.37, 0.32, 4.06, 0.51, 4.36, 1.5, 4.54, 0.74, 4.48, 1.47, 5.03, 1.05, 4.76, 0.92, 4.3, -1.37, 4.53, -1.43, 4.04, -1.83, 3.27, 0.09, 4.58, -1.2, 5.42, -1.67, 4.98, -0.09, 4.66, -1.24, 5.15, -0.96, 4.71, -1.43, 4.75, -1.34, 3.21, -2.01, 3.87, -1.02, 4.76, -1.88, 4.17, -1.14, 4.85, -1.21, 4.59, -1.43, 3.4, -0.5, 4.98, -0.35, 4.62, -0.87, 4.09, 1.29, 4.26, 0.08, 5.69, -0.61, 5.01, 1.07, 4.73, 0.31, 4.83, 0.52, 5.05, -0.05, 4.84, -0.28, 4.6, -0.76, 3.49, 1.04, 4.74, -0.31, 4.81, 0.5, 5.3, 0.33, 4.44, -0.39, 4.48, -0.37, 3.18, -0.87, 2.69, -0.69, 3.19, 0.69, 2.49, -0.26, 3.09, 0.17, 3.02, 0.73, 2.93, -0.21, 2.79, -0.12, 3.33, -0.09, 3.36, -0.27, 2.12, -0.8, 1.88, -0.03, 3.26, -0.14, 3.12, 0.51, 2.92, -0.5, 2.7, 0.25, 2.16, 0.01, 3.61, 0.29, 3.37, 0.38, 2.73, 1.0, 2.68, 0.42, 2.9, 0.1, 3.2, 1.01, 3.16, -0.32, 2.79, 0.53, 2.95, 1.45, 2.9, 0.48, 2.21, -0.53, 2.31, 0.37, 2.38, -0.26, 3.17, 0.33, 2.29, -0.39, 2.82, 0.52, 2.76, -0.3, 2.91, -0.46, 2.24, -0.33, 2.09, 0.72, 2.0, -0.44, 2.5, -0.69, 2.81, -0.05, 2.53, -1.03, 2.39, 0.26, 2.15, -0.2, 2.04, -0.21, 1.25, -0.99, 1.27, -0.39, 2.4, -0.48, 2.01, -0.1, 2.2, -0.79, 1.86, 0.19, 1.48, 0.83, 2.44, 0.41, 1.45, 0.1, 1.75, 1.54, 1.51, 0.89, 1.78, 0.41, 2.24, 0.48, 1.75, -0.07, 2.22, 0.57, 1.2, 0.28, 1.62, 0.38, 1.43, -0.39, 1.67, 0.44, 1.45, 0.27, 1.56, 0.64, 1.5, 0.4, 1.42, 0.68, 1.52, 0.07, 0.47, -0.02, 0.24, -0.07, 0.29, 0.18, 0.3, 0.08, 0.28, -0.05, 0.43, -0.05, 0.27, -0.09, 0.41, -0.03, 0.25, -0.08, 0.3, 0.04, 0.24, -0.12, 0.24, -0.03, 0.27, -0.1, 0.32, 0.03, 0.27, -0.03, 0.17, 0.04, 0.28, 0.15, 1.14, 0.07, 1.21, 0.19, 0.54, 0.24, 0.92, -0.2, 0.74, -0.29, 0.96, -0.29, 0.96, -0.28, 0.81, 0.31, 1.0, 0.55, 0.79, 0.1, 0.76, -0.34, 0.58, 0.04, 0.53, 0.07, 1.21, -0.41, 0.5, -0.43, 0.8, 0.08, 1.06, 
+
+L3_zTRMM_A_nn
+0.9, 0.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.8, 0.8, 0.5, 0.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.3, 0.2, 0.4, 0.4, 0.8, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.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.7, 0.3, 0.7, 0.7, 0.1, 0.4, 0.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.2, 0.8, 0.2, 0.8, 0.4, 0.6, 0.1, 0.4, 0.3, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.9, 0.8, 0.3, 0.1, 0.7, 0.8, 0.7, 0.4, 0.1, 0.4, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.1, 0.2, 0.7, 0.5, 0.5, 0.8, 0.4, 0.9, 0.4, 0.9, 0.8, 0.2, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.3, 0.3, 0.7, 0.2, 0.6, 0.8, 0.6, 0.5, 0.8, 0.7, 0.1, 0.5, 0.1, 0.7, 0.6, 0.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.9, 0.7, 0.8, 0.9, 0.7, 0.9, 0.2, 0.2, 0.5, 0.7, 0.3, 0.2, 0.6, 0.4, 0.8, 0.4, 0.2, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 0.1, 0.1, 0.2, 0.8, 0.9, 0.5, 0.9, 0.5, 0.1, 0.8, 0.1, 0.7, 0.9, 0.3, 0.3, 0.4, 0.5, 0.6, 0.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.6, 0.6, 0.4, 0.8, 0.9, 0.4, 0.6, 0.1, 0.9, 0.8, 0.3, 0.4, 0.5, 0.2, 0.5, 0.9, 0.8, 0.9, 0.8, 0.2, 0.2, 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.3, 0.2, 0.1, 0.7, 0.6, 0.8, 0.8, 0.3, 0.1, 0.9, 0.9, 0.6, 0.4, 0.9, 0.6, 0.3, 0.4, 0.4, 0.6, 0.3, 0.7, 0.9, 0.3, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6, 0.2, 0.9, 0.7, 0.1, 0.1, 0.1, 0.7, 0.5, 0.4, 0.4, 0.2, 0.4, 0.9, 0.4, 0.3, 0.9, 0.6, 0.1, 0.1, 0.6, 0.6, 0.9, 0.9, 0.6, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.9, 0.8, 0.9, 0.3, 0.1, 0.6, 0.4, 0.2, 0.7, 0.5, 0.5, 0.9, 0.7, 0.8, 0.2, 0.9, 0.9, 0.8, 0.6, 0.6, 0.6, 0.5, 0.4, 0.9, 0.9, 0.9, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.1, 0.3, 0.9, 0.4, 0.4, 0.3, 0.8, 0.4, 0.2, 0.1, 0.9, 0.2, 0.1, 0.4, 0.8, 0.8, 0.7, 0.4, 0.8, 0.6, 0.6, 0.3, 0.6, 0.6, 0.8, 0.2, 0.3, 0.6, 0.3, 0.0, 0.0, 0.0, 0.0, 0.1, 0.3, 0.8, 0.3, 0.5, 0.8, 0.5, 0.2, 0.1, 0.4, 0.1, 0.8, 0.1, 0.3, 0.1, 0.5, 0.3, 0.4, 0.7, 0.1, 0.9, 0.4, 0.8, 0.4, 0.5, 0.8, 0.1, 0.2, 0.9, 0.7, 0.9, 0.7, 0.0, 0.0, 0.5, 0.8, 0.1, 0.4, 0.3, 0.8, 0.5, 0.1, 0.7, 0.8, 0.2, 0.1, 0.7, 0.8, 0.4, 0.5, 0.8, 0.1, 0.1, 0.7, 0.6, 0.2, 0.1, 0.9, 0.3, 0.8, 0.6, 0.9, 0.8, 0.5, 0.3, 0.1, 0.4, 0.4, 
+
+L3_zTRMM_o_RLT
+0.68, 0.34, 0.65, 1.39, 0.01, 1.64, -0.45, 2.23, -1.61, 2.3, -0.2, 3.47, -0.68, 4.18, -1.49, 3.94, -1.24, 5.33, -0.96, 4.94, -2.05, 6.79, -2.69, 6.35, -0.45, 6.88, -0.38, 9.54, -2.87, 6.99, -1.41, 7.93, -1.92, 8.22, 0.63, 0.99, 0.15, 1.79, 0.06, 1.66, -0.48, 2.3, -1.89, 2.65, -0.25, 3.97, 0.6, 4.21, -0.71, 4.07, -0.61, 4.96, 0.52, 5.05, -0.35, 6.57, -1.46, 6.6, -0.71, 6.71, -0.18, 9.45, -2.25, 7.34, -1.0, 7.84, -2.61, 8.77, 0.46, 0.48, 0.22, 1.23, -0.06, 1.03, -0.28, 1.58, -1.16, 2.42, 0.56, 3.61, 0.77, 4.34, 0.07, 4.48, 0.03, 5.49, 1.35, 5.4, 0.66, 7.17, -0.89, 7.1, -0.22, 7.77, 0.46, 10.3, -2.16, 8.22, -0.84, 8.38, -1.35, 8.4, -0.03, 0.56, -0.19, 0.76, 0.13, 0.7, -0.02, 0.88, -0.74, 1.76, 0.18, 2.32, 0.4, 3.54, 0.43, 3.24, 0.64, 4.16, 1.31, 4.65, 0.51, 5.56, -0.16, 6.16, 1.88, 6.69, 1.6, 7.75, 0.56, 6.56, 1.67, 6.56, 0.82, 8.05, 0.03, 0.29, -0.29, 0.79, -0.46, 1.29, -0.79, 1.27, -1.92, 1.53, -1.08, 2.27, -0.82, 2.93, -0.85, 3.44, -1.46, 3.96, -0.42, 4.12, -1.46, 7.03, -1.83, 5.73, -0.73, 6.4, -0.34, 8.42, -1.59, 7.39, -0.2, 8.02, -0.52, 7.91, 0.08, 0.49, 0.02, 0.78, 0.02, 1.02, -0.22, 1.48, -0.86, 1.68, -0.02, 2.45, 0.85, 3.46, 0.22, 3.14, 0.39, 3.69, 0.59, 4.02, 1.03, 5.49, 0.66, 6.04, 0.58, 5.5, 1.24, 7.87, -0.51, 6.34, 0.74, 6.02, -0.06, 7.53, 0.54, 0.97, 0.16, 1.92, 0.64, 1.47, -0.21, 1.83, -1.12, 3.08, 0.47, 4.34, 1.14, 5.05, 0.66, 5.18, 0.85, 6.78, 2.5, 5.61, 0.81, 7.2, -0.08, 6.99, 1.0, 7.67, 1.03, 10.52, -0.82, 7.62, -0.04, 7.88, -0.17, 8.78, 0.31, 0.73, -0.15, 1.37, 0.06, 1.61, -0.21, 1.83, -1.5, 2.66, 0.07, 3.83, 1.01, 4.59, -0.37, 5.05, -0.49, 6.0, 1.19, 6.21, 0.28, 7.13, -1.6, 7.11, -0.82, 7.62, 0.58, 10.38, -1.31, 7.82, -0.37, 8.84, -1.13, 8.87, 0.67, 0.81, 0.15, 1.45, 0.05, 1.28, -0.15, 1.65, -0.83, 2.31, 0.34, 3.32, 1.38, 3.71, 0.06, 3.88, -0.02, 5.03, 0.67, 4.99, -0.4, 6.3, -0.87, 6.21, -0.53, 5.9, -0.89, 8.76, -2.33, 6.27, -1.21, 6.44, -1.67, 6.86, 0.69, 0.72, 0.55, 1.73, 0.57, 1.31, 0.02, 2.04, -0.92, 2.86, 0.94, 4.17, 0.86, 4.52, 0.14, 4.3, 0.54, 6.13, 1.47, 5.42, 0.98, 7.12, -0.32, 6.92, 0.38, 7.38, 1.8, 10.75, -0.82, 7.84, -0.14, 7.28, -0.41, 9.23, 
+
+L3_sTRSM_A_mm
+1.0, 4.0, 4.0, 2.0, 3.0, 6.0, 9.0, 9.0, 3.0, 8.0, 0.0, 2.0, 3.0, 8.0, 3.0, 6.0, 5.0, 1.0, 9.0, 5.0, 0.0, 0.0, 2.0, 2.0, 5.0, 7.0, 1.0, 8.0, 2.0, 1.0, 0.0, 0.0, 0.0, 5.0, 5.0, 8.0, 1.0, 1.0, 5.0, 2.0, 0.0, 0.0, 0.0, 0.0, 6.0, 6.0, 5.0, 6.0, 8.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 2.0, 1.0, 7.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 4.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 3.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 6.0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 
+
+L3_sTRSM_B_mn
+0.5, 0.6, 0.6, 0.8, 0.9, 0.2, 0.5, 0.7, 0.8, 0.7, 0.8, 0.6, 0.1, 0.2, 0.6, 0.4, 0.6, 0.2, 0.9, 0.6, 0.4, 0.2, 0.6, 0.4, 0.4, 0.1, 0.6, 0.2, 0.1, 0.2, 0.7, 0.1, 0.9, 0.2, 0.1, 0.5, 0.5, 0.6, 0.9, 0.6, 0.2, 0.4, 0.4, 0.9, 0.6, 0.4, 0.2, 0.2, 0.4, 0.4, 0.3, 0.4, 0.4, 0.5, 0.1, 0.7, 0.2, 0.3, 0.7, 0.3, 0.2, 0.9, 0.4, 0.8, 0.7, 0.7, 0.9, 0.4, 0.5, 0.1, 0.4, 0.3, 0.9, 0.1, 0.8, 0.3, 0.6, 0.7, 0.9, 0.7, 0.2, 0.1, 0.1, 0.8, 0.8, 0.6, 0.8, 0.2, 0.7, 0.4, 0.4, 0.8, 0.8, 0.3, 0.3, 0.3, 0.6, 0.6, 0.5, 0.9, 0.5, 0.7, 0.8, 0.5, 0.4, 0.8, 0.1, 0.5, 0.7, 0.7, 0.6, 0.6, 0.4, 0.9, 0.3, 0.9, 0.1, 0.9, 0.4, 0.3, 0.4, 0.1, 0.3, 0.5, 0.7, 0.4, 0.7, 0.1, 0.9, 0.1, 0.5, 0.7, 0.9, 0.9, 0.1, 0.6, 0.3, 0.8, 0.8, 0.5, 0.5, 0.5, 0.6, 0.4, 0.7, 0.7, 0.2, 0.4, 0.6, 0.5, 0.4, 0.4, 0.2, 0.1, 0.7, 0.4, 0.7, 0.1, 0.4, 0.4, 0.5, 0.1, 0.5, 0.5, 0.9, 0.9, 0.9, 0.6, 0.5, 0.1, 
+
+L3_sTRSM_o_LUN
+1.46520638466, -1.54896688461, 1.99039387703, -2.01419639587, 1.81852555275, -0.895377159119, -1.13288402557, -0.886934757233, 4.2189283371, -1.06383061409, -1.27475452423, -3.97711014748, -3.44645786285, -3.54849243164, -2.61162471771, -1.03318476677, -1.06028676033, -0.666151702404, -0.401585698128, -1.12818288803, -0.364658713341, -0.545352995396, -0.39260995388, -0.161377370358, -0.200671315193, -1.51934599876, -0.355410814285, 0.0172800421715, 0.257222175598, 0.371354043484, 0.153767347336, 0.533437430859, -0.428796291351, 0.320115804672, -0.00877776741982, 0.209888875484, 0.397222280502, 0.205888926983, 0.133555576205, 0.169222265482, -0.0421110987663, -0.178222194314, 0.440888911486, 0.202777802944, -0.174555510283, -0.245333313942, -0.394999951124, -0.340666621923, -0.396999955177, -0.0332221984863, -0.263444423676, 0.0949467644095, 0.0233287215233, 0.131134271622, -0.0575671195984, 0.0300439726561, 0.0690300837159, -0.0392546504736, 0.0696573853493, 0.135557845235, 0.0204282253981, -0.0239398255944, -0.0935555547476, 0.000208348035812, 0.110284730792, -0.0436250045896, 0.0934073925018, -0.0557685121894, -0.144363433123, -0.428495377302, -0.0853009298444, -0.417349547148, 0.0290393531322, -0.261446774006, -0.22891202569, -0.391990721226, 0.0170254632831, -0.172511577606, -0.132893532515, -0.434444457293, -0.467708319426, -0.52253472805, -0.461875021458, -0.210740745068, -0.121898137033, 0.0496874935925, 0.345624983311, 0.0218749940395, 0.374062478542, 0.0165624953806, 0.158437490463, 0.204374969006, 0.326249986887, -0.122812509537, 0.129687488079, 0.276874989271, 0.490000009537, 0.496874988079, 0.444062501192, 0.474375009537, 0.219999998808, 0.148749992251, 0.140555560589, 0.112222224474, 0.105555564165, 0.177222236991, -0.0161111094058, 0.0605555549264, 0.132222220302, 0.10444444418, 0.12722222507, 0.0694444552064, 0.101111114025, 0.18666665256, 0.0500000044703, 0.148333325982, -0.0299999900162, 0.204444423318, 0.0288888923824, 0.0145833343267, -0.0291666667908, -0.0541666671634, -0.0229166653007, 0.0270833335817, 0.0395833328366, -0.00416666828096, 0.0416666641831, -0.0354166664183, 0.0479166582227, -0.0208333339542, 0.0, 0.0124999955297, 0.0437499955297, 0.0624999962747, -0.0333333350718, 0.0583333335817, 0.00555555894971, -0.177777782083, -0.0444444417953, -0.227777779102, 0.0388888902962, -0.0944444462657, -0.0777777731419, -0.155555546284, 0.0722222179174, -0.105555556715, -0.188888892531, -0.333333343267, -0.300000011921, -0.316666662693, -0.200000017881, -0.155555546284, -0.0111111104488, 0.0333333350718, 0.233333334327, 0.133333340287, 0.233333334327, 0.0333333350718, 0.133333340287, 0.133333340287, 0.166666671634, 0.0333333350718, 0.166666671634, 0.166666671634, 0.300000011921, 0.300000011921, 0.300000011921, 0.200000017881, 0.166666671634, 0.0333333350718, 
+
+L3_sTRSM_A_nn
+0.4, 0.0, 0.0, 0.0, 0.0, 0.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, 0.6, 0.0, 0.0, 0.0, 0.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.5, 0.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.8, 0.9, 0.6, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.6, 0.8, 0.6, 0.6, 0.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.2, 0.9, 0.1, 0.9, 0.9, 0.4, 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.3, 0.3, 0.7, 0.5, 0.6, 0.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.5, 0.4, 0.3, 0.5, 0.7, 0.6, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.2, 0.8, 0.5, 0.8, 0.7, 0.2, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.2, 0.5, 0.1, 0.7, 0.7, 0.2, 0.1, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.8, 0.1, 0.2, 0.7, 0.8, 0.8, 0.6, 0.5, 0.8, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.6, 0.3, 0.5, 0.2, 0.7, 0.2, 0.3, 0.6, 0.1, 0.3, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.2, 0.6, 0.6, 0.5, 0.5, 0.7, 0.9, 0.4, 0.6, 0.4, 0.5, 0.9, 0.0, 0.0, 0.0, 0.0, 0.9, 0.2, 0.9, 0.6, 0.6, 0.2, 0.9, 0.5, 0.3, 0.1, 0.2, 0.1, 0.2, 0.3, 0.0, 0.0, 0.0, 0.6, 0.3, 0.4, 0.9, 0.8, 0.4, 0.7, 0.8, 0.9, 0.9, 0.7, 0.1, 0.6, 0.6, 0.4, 0.0, 0.0, 0.2, 0.5, 0.1, 0.6, 0.8, 0.9, 0.7, 0.6, 0.6, 0.6, 0.8, 0.8, 0.5, 0.4, 0.9, 0.1, 0.0, 0.3, 0.1, 0.8, 0.1, 0.5, 0.4, 0.3, 0.5, 0.8, 0.7, 0.3, 0.2, 0.2, 0.8, 0.2, 0.1, 0.6, 
+
+L3_sTRSM_o_RLT
+1.25, -0.0416666269302, 4.95833301544, -10.4583330154, 17.4166660309, -16.9270839691, 19.171875, -8.31944561005, 2.2704873085, -10.9107666016, 1.33900761604, 21.1916599274, -10.291601181, -63.9414329529, 106.560028076, -791.99621582, 176.765274048, 0.5, 1.08333325386, 0.0833339691162, -3.4166674614, 5.16666793823, -5.14583396912, 7.23958396912, -3.19444537163, -0.690971434116, -0.428475856781, -9.7613363266, 13.096663475, -3.03346061707, -11.6049003601, 33.1082611084, -259.884613037, 49.2269973755, 0.25, 0.625, 1.625, -3.79166698456, 7.75, -9.34374904633, 9.71354103088, -3.09722232819, 0.756597876549, -1.20798754692, -9.01191520691, 15.5116615295, -6.41001653671, -26.284286499, 52.0520133972, -386.388214111, 80.1968383789, 1.0, -0.16666662693, 4.83333301544, -11.5000009537, 21.1666660309, -22.5833320618, 24.5416660309, -8.88889122009, 1.09722340107, -9.61944675446, -5.17684555054, 31.7799949646, -14.3599767685, -73.6030273438, 128.730529785, -966.596191406, 211.087921143, 1.25, -0.874999940395, 7.125, -13.9583339691, 24.75, -24.46875, 27.1927089691, -11.6527795792, 1.77465426922, -13.7982635498, 2.30984330177, 31.5983257294, -15.9633569717, -90.2416534424, 148.418395996, -1105.81958008, 248.000167847, 1.5, 0.0833333730698, 0.0833334922791, -2.0833337307, 3.16666698456, -2.3958325386, 4.78125095367, -2.91666698456, -1.29374969006, -0.814582705498, -3.94930410385, 8.84333133698, -2.62183618546, -10.1927108765, 26.7363319397, -218.988800049, 43.3896217346, 2.0, -0.833333313465, 6.16666650772, -12.5, 16.8333320618, -9.16666889191, 11.8333330154, -9.22222328186, 3.62222337723, -20.1777763367, 26.3259296417, 1.99333024025, -2.24361944199, -57.2452316284, 72.9840316772, -545.544616699, 136.073165894, 0.75, 0.0416666865349, 0.0416667461395, -1.20833349228, 3.58333349228, -4.07291555405, 4.49479198456, -1.3472224474, -0.870485842228, 1.71076393127, -10.1390028, 12.0483312607, -3.9380273819, -7.00769615173, 24.7647743225, -204.368988037, 36.0493278503, 0.75, 0.70833337307, 3.70833349228, -9.875, 15.9166679382, -15.2395820618, 18.2447910309, -8.12500095367, 1.45729315281, -8.99479103088, -4.4704785347, 22.7283267975, -7.77897167206, -53.1657066345, 96.0997085571, -728.817810059, 157.212936401, 0.25, 0.958333313465, -1.04166650772, 0.874999284744, -3.58333301544, 5.07291603088, -3.66145801544, 0.458334028721, -0.807291805744, 1.47812449932, -0.457289814949, -3.18166708946, 3.58205962181, 16.2832775116, -22.6479034424, 147.264984131, -37.0808677673, 
+
+L3_dTRSM_A_mm
+6.0, 5.0, 8.0, 5.0, 2.0, 8.0, 5.0, 1.0, 4.0, 2.0, 0.0, 6.0, 5.0, 1.0, 8.0, 1.0, 4.0, 2.0, 3.0, 9.0, 0.0, 0.0, 2.0, 9.0, 1.0, 5.0, 7.0, 3.0, 9.0, 3.0, 0.0, 0.0, 0.0, 2.0, 2.0, 5.0, 7.0, 7.0, 9.0, 6.0, 0.0, 0.0, 0.0, 0.0, 8.0, 3.0, 2.0, 7.0, 2.0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 8.0, 5.0, 7.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4.0, 1.0, 6.0, 2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7.0, 1.0, 5.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 
+
+L3_dTRSM_B_mn
+0.5, 0.1, 0.8, 0.2, 0.7, 0.3, 0.1, 0.6, 0.5, 0.2, 0.2, 0.3, 0.6, 0.2, 0.2, 0.1, 0.3, 0.8, 0.1, 0.8, 0.9, 0.9, 0.2, 0.1, 0.8, 0.5, 0.4, 0.1, 0.8, 0.1, 0.7, 0.1, 0.7, 0.4, 0.4, 0.4, 0.1, 0.5, 0.3, 0.7, 0.2, 0.4, 0.2, 0.7, 0.2, 0.1, 0.5, 0.4, 0.4, 0.5, 0.2, 0.2, 0.1, 0.7, 0.5, 0.2, 0.1, 0.4, 0.3, 0.3, 0.1, 0.2, 0.8, 0.6, 0.6, 0.4, 0.1, 0.9, 0.7, 0.5, 0.1, 0.4, 0.2, 0.4, 0.3, 0.6, 0.1, 0.7, 0.2, 0.7, 0.4, 0.2, 0.2, 0.8, 0.2, 0.1, 0.7, 0.2, 0.9, 0.1, 0.8, 0.1, 0.3, 0.1, 0.8, 0.2, 0.9, 0.7, 0.2, 0.4, 0.4, 0.9, 0.5, 0.5, 0.4, 0.5, 0.9, 0.3, 0.7, 0.9, 0.8, 0.4, 0.4, 0.1, 0.1, 0.6, 0.7, 0.8, 0.3, 0.1, 0.7, 0.7, 0.3, 0.4, 0.9, 0.3, 0.8, 0.4, 0.2, 0.2, 0.9, 0.5, 0.4, 0.9, 0.9, 0.4, 0.9, 0.3, 0.7, 0.2, 0.7, 0.2, 0.6, 0.2, 0.5, 0.2, 0.7, 0.7, 0.6, 0.2, 0.1, 0.7, 0.2, 0.6, 0.7, 0.1, 0.2, 0.4, 0.1, 0.5, 0.6, 0.7, 0.9, 0.6, 0.4, 0.5, 0.7, 0.3, 0.2, 0.1, 
+
+L3_dTRSM_o_LUN
+0.0674593874008, -0.373323102679, 0.250619109623, -0.372651909722, -0.110824962798, -0.952495039683, 0.301252480159, -0.119270213294, 0.33933500744, -0.21607514881, 0.205055493552, -0.00562282986111, 0.187065972222, 0.541959325397, -0.185227244544, -0.919556361607, 0.200939980159, -0.378703497024, -1.12616629464, 0.42337983631, -0.506848958333, -0.670329241071, -1.51952380952, -0.146949404762, -0.92173735119, -0.153565848214, -0.906183035714, -0.129242931548, 0.175169270833, 0.103645833333, 0.433720238095, -0.73763578869, -1.77744977679, 0.443050595238, 0.313973214286, 1.19915178571, -0.332901785714, 0.693125, 0.808794642857, 1.95616071429, -0.0428571428571, 0.996785714286, 0.0232589285714, 0.833571428571, -0.0123660714286, -0.0934375, -0.2, -0.673392857143, 0.835223214286, 2.19111607143, -0.475982142857, -0.0440736607143, -0.242332589286, 0.0528013392857, -0.17453125, -0.186283482143, -0.410089285714, 0.0102678571429, -0.199933035714, 0.0122433035714, -0.123616071429, 0.0194308035714, -0.008828125, 0.078125, 0.200357142857, -0.171729910714, -0.498024553571, 0.0608928571429, 0.0580022321429, -0.0565959821429, -0.0576227678571, -0.01546875, -0.0106808035714, -0.0697321428571, 0.000446428571429, -0.0173883928571, -0.0406361607143, -0.00102678571429, -0.0215736607143, -0.058671875, -0.053125, -0.0385714285714, -0.0730915178571, 0.00891741071429, -0.0514285714286, -0.115446428571, -0.135803571429, -0.0654464285714, -0.03625, -0.223839285714, -0.0185714285714, -0.189285714286, -0.287321428571, -0.252767857143, -0.104642857143, -0.100267857143, 0.049375, 0.025, -0.215714285714, -0.201696428571, -0.163482142857, 0.0207142857143, 0.0499107142857, 0.153839285714, -0.0375892857143, 0.10875, 0.144732142857, 0.0217857142857, 0.132142857143, 0.253035714286, 0.202946428571, 0.196071428571, 0.0579464285714, -0.073125, -0.025, 0.207857142857, 0.171160714286, 0.0708035714286, 0.0396428571429, -0.0746428571429, 0.00964285714286, 0.0753571428571, 0.015, -0.00392857142857, 0.112857142857, -0.0285714285714, 0.0378571428571, -0.0367857142857, -0.0842857142857, -0.0567857142857, 0.0675, 6.93889390391e-18, -0.0314285714286, 0.0903571428571, 0.0917857142857, 0.0414285714286, 0.0225, -0.0675, 0.0725, -0.005, 0.0275, 0.01, -1.38777878078e-17, -0.065, -0.0425, -0.11, -0.0025, 0.0275, -1.38777878078e-17, -0.08, -0.0325, 0.0575, 0.01, 0.12, 0.14, 0.02, 0.04, 0.08, 0.02, 0.1, 0.12, 0.14, 0.18, 0.12, 0.08, 0.1, 0.14, 0.06, 0.04, 0.02, 
+
+L3_dTRSM_A_nn
+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.7, 0.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.7, 0.2, 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.3, 0.7, 0.8, 0.3, 0.0, 0.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, 0.1, 0.8, 0.9, 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.7, 0.8, 0.7, 0.8, 0.3, 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.3, 0.2, 0.5, 0.9, 0.5, 0.6, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.2, 0.1, 0.7, 0.8, 0.6, 0.5, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.5, 0.8, 0.8, 0.8, 0.6, 0.9, 0.5, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.2, 0.3, 0.2, 0.2, 0.3, 0.2, 0.4, 0.8, 0.6, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 0.8, 0.1, 0.6, 0.2, 0.8, 0.1, 0.3, 0.2, 0.9, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.8, 0.6, 0.5, 0.6, 0.9, 0.8, 0.9, 0.3, 0.1, 0.6, 0.8, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9, 0.2, 0.5, 0.1, 0.5, 0.7, 0.8, 0.8, 0.1, 0.3, 0.2, 0.9, 0.6, 0.0, 0.0, 0.0, 0.0, 0.9, 0.4, 0.4, 0.1, 0.7, 0.6, 0.2, 0.2, 0.8, 0.8, 0.3, 0.3, 0.8, 0.4, 0.0, 0.0, 0.0, 0.3, 0.1, 0.8, 0.9, 0.4, 0.4, 0.9, 0.6, 0.7, 0.6, 0.2, 0.3, 0.3, 0.8, 0.7, 0.0, 0.0, 0.6, 0.3, 0.5, 0.1, 0.5, 0.8, 0.9, 0.3, 0.3, 0.5, 0.2, 0.1, 0.7, 0.6, 0.4, 0.3, 0.0, 0.4, 0.6, 0.9, 0.9, 0.7, 0.9, 0.2, 0.8, 0.4, 0.8, 0.2, 0.7, 0.9, 0.6, 0.1, 0.4, 0.7, 
+
+L3_dTRSM_o_RLT
+0.555555555556, -1.44444444444, 1.4, -0.251851851852, -0.653333333333, 0.605185185185, -0.575111111111, 1.5635978836, -0.350548752834, -0.492165616864, 2.41928949358, -1.4215239215, -0.32576685983, 0.687357856723, -1.55104068435, -0.460651240234, -0.0668249165347, 0.888888888889, -2.61111111111, 1.4, 4.47037037037, -8.85333333333, -0.292037037037, 0.468222222222, 6.61756613757, -0.105922902494, -3.19099907617, 5.36577475435, 1.88985006019, -6.94746816998, 27.2790749139, -35.9615205641, 17.6737228874, -22.8409931072, 0.444444444444, 0.444444444444, -0.6, 1.78518518519, -2.18666666667, -0.398518518519, 0.00711111111112, 1.26306878307, 0.0351201814059, -0.0643634836651, -3.50119425548, 3.82691369223, -3.73240245234, 10.7776156883, -12.2439782121, 8.77068584173, -11.0944239527, 0.222222222222, -0.277777777778, 1.2, -1.10740740741, 0.306666666667, 0.150740740741, 1.08355555556, 0.0315343915344, -1.62815419501, 0.573850004199, 1.06845049131, -1.73797172532, 0.260862265894, 1.12333165365, -0.933043527817, -6.7320077972, 4.82082387292, 0.777777777778, -0.222222222222, -0.8, 3.20740740741, -4.82666666667, -0.655740740741, 0.862444444444, 2.73417989418, -0.322213151927, -0.700240026875, -2.4434164777, 4.85100422721, -6.36028516839, 19.5621218611, -23.6343706283, 14.799242671, -17.6038039532, 0.111111111111, 3.11111111111, -1.0, -1.7037037037, 4.13333333333, -1.17962962963, 0.237777777778, -2.57566137566, -1.29505668934, 2.35951457126, -7.47679516251, 3.27144648806, -1.24960401445, -2.20582850424, 6.690148952, -1.98253247723, 2.87346488765, 0.555555555556, 0.555555555556, -0.2, 0.348148148148, 0.826666666667, -1.14981481481, 0.970888888889, -0.242116402116, -1.09275283447, 0.595049802637, -0.697173091459, -1.22444002128, 0.891306836315, 0.375078945158, 0.103402950245, -1.75868379611, 0.986152500282, 0.111111111111, 3.11111111111, -2.20606726491e-15, -6.37037037037, 11.5333333333, -0.037962962963, -0.732222222222, -6.08042328042, -2.36117913832, 4.04449567481, -6.97067271353, -1.90430811008, 3.75936612917, -21.7177143697, 33.4798733338, -18.1277933982, 21.68599013, 1.0, -2.0, 0.8, 2.2, -4.44, 0.14, 0.912, 2.13142857143, -0.169306122449, -0.738176870748, 3.14530612245, -0.280707482993, -1.61797278912, 7.84074829932, -12.52898931, 6.62129640428, -7.17676856865, 0.666666666667, 1.16666666667, -1.2, 0.477777777778, 0.96, -1.41277777778, 1.20866666667, -1.00825396825, -0.489850340136, 1.30301486521, -3.07192743764, 0.761796086336, 0.257254598136, 0.094609473419, 0.00809406831515, -1.1310244894, 0.493807445914, 
+
+L3_cTRSM_A_mm
+8.0, 2.0, 8.0, 1.0, 3.0, 2.0, 2.0, 3.0, 4.0, 9.0, 2.0, 9.0, 3.0, 7.0, 3.0, 9.0, 4.0, 4.0, 4.0, 1.0, 0.0, 0.0, 6.0, 1.0, 8.0, 8.0, 6.0, 9.0, 5.0, 6.0, 1.0, 8.0, 9.0, 4.0, 4.0, 7.0, 4.0, 5.0, 6.0, 9.0, 0.0, 0.0, 0.0, 0.0, 3.0, 8.0, 1.0, 3.0, 2.0, 3.0, 2.0, 6.0, 1.0, 3.0, 9.0, 1.0, 7.0, 3.0, 2.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 6.0, 7.0, 8.0, 5.0, 3.0, 7.0, 8.0, 5.0, 4.0, 5.0, 1.0, 1.0, 7.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 5.0, 5.0, 6.0, 5.0, 9.0, 5.0, 2.0, 7.0, 1.0, 4.0, 7.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 9.0, 7.0, 2.0, 9.0, 8.0, 2.0, 5.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, 3.0, 5.0, 3.0, 4.0, 5.0, 3.0, 7.0, 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, 4.0, 4.0, 6.0, 2.0, 9.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, 7.0, 8.0, 7.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, 3.0, 7.0, 
+
+L3_cTRSM_B_mn
+0.20000000298, 0.899999976158, 0.800000011921, 0.699999988079, 0.40000000596, 0.5, 0.899999976158, 0.40000000596, 0.800000011921, 0.800000011921, 0.600000023842, 0.40000000596, 0.300000011921, 0.5, 0.899999976158, 0.20000000298, 0.899999976158, 0.699999988079, 0.800000011921, 0.300000011921, 0.10000000149, 0.300000011921, 0.5, 0.10000000149, 0.699999988079, 0.699999988079, 0.5, 0.300000011921, 0.300000011921, 0.800000011921, 0.600000023842, 0.10000000149, 0.699999988079, 0.5, 0.300000011921, 0.10000000149, 0.600000023842, 0.10000000149, 0.300000011921, 0.800000011921, 0.899999976158, 0.20000000298, 0.800000011921, 0.40000000596, 0.20000000298, 0.20000000298, 0.300000011921, 0.5, 0.699999988079, 0.800000011921, 0.800000011921, 0.800000011921, 0.5, 0.5, 0.40000000596, 0.600000023842, 0.5, 0.699999988079, 0.699999988079, 0.699999988079, 0.10000000149, 0.699999988079, 0.40000000596, 0.5, 0.20000000298, 0.899999976158, 0.10000000149, 0.20000000298, 0.600000023842, 0.300000011921, 0.20000000298, 0.899999976158, 0.20000000298, 0.300000011921, 0.800000011921, 0.10000000149, 0.20000000298, 0.300000011921, 0.600000023842, 0.800000011921, 0.40000000596, 0.10000000149, 0.20000000298, 0.300000011921, 0.699999988079, 0.899999976158, 0.10000000149, 0.899999976158, 0.5, 0.699999988079, 0.5, 0.600000023842, 0.5, 0.20000000298, 0.899999976158, 0.5, 0.699999988079, 0.10000000149, 0.10000000149, 0.300000011921, 0.300000011921, 0.800000011921, 0.5, 0.600000023842, 0.300000011921, 0.899999976158, 0.699999988079, 0.10000000149, 0.300000011921, 0.10000000149, 0.40000000596, 0.600000023842, 0.600000023842, 0.10000000149, 0.899999976158, 0.20000000298, 0.600000023842, 0.600000023842, 0.899999976158, 0.20000000298, 0.20000000298, 0.5, 0.20000000298, 0.10000000149, 0.40000000596, 0.600000023842, 0.300000011921, 0.20000000298, 0.899999976158, 0.300000011921, 0.300000011921, 0.40000000596, 0.40000000596, 0.40000000596, 0.10000000149, 0.20000000298, 0.5, 0.899999976158, 0.800000011921, 0.10000000149, 0.5, 0.5, 0.10000000149, 0.600000023842, 0.899999976158, 0.899999976158, 0.800000011921, 0.300000011921, 0.899999976158, 0.20000000298, 0.300000011921, 0.20000000298, 0.600000023842, 0.10000000149, 0.40000000596, 0.800000011921, 0.800000011921, 0.20000000298, 0.10000000149, 0.20000000298, 0.10000000149, 0.5, 0.699999988079, 0.10000000149, 0.10000000149, 0.10000000149, 0.300000011921, 0.899999976158, 0.800000011921, 0.600000023842, 0.10000000149, 0.20000000298, 0.10000000149, 0.10000000149, 0.20000000298, 0.5, 0.20000000298, 0.899999976158, 0.10000000149, 0.5, 0.10000000149, 0.800000011921, 0.20000000298, 0.10000000149, 0.20000000298, 0.300000011921, 0.10000000149, 0.5, 0.600000023842, 0.300000011921, 0.40000000596, 0.699999988079, 0.600000023842, 0.40000000596, 0.600000023842, 0.300000011921, 0.800000011921, 0.699999988079, 0.5, 0.899999976158, 0.600000023842, 0.300000011921, 0.20000000298, 0.699999988079, 0.5, 0.699999988079, 0.899999976158, 0.699999988079, 0.800000011921, 0.899999976158, 0.600000023842, 0.10000000149, 0.600000023842, 0.20000000298, 0.300000011921, 0.899999976158, 0.5, 0.40000000596, 0.10000000149, 0.20000000298, 0.300000011921, 0.5, 0.699999988079, 0.800000011921, 0.600000023842, 0.600000023842, 0.20000000298, 0.899999976158, 0.300000011921, 0.899999976158, 0.20000000298, 0.899999976158, 0.800000011921, 0.40000000596, 0.300000011921, 0.20000000298, 0.10000000149, 0.800000011921, 0.5, 0.5, 0.899999976158, 0.20000000298, 0.800000011921, 0.40000000596, 0.600000023842, 0.40000000596, 0.40000000596, 0.10000000149, 0.40000000596, 0.600000023842, 0.300000011921, 0.5, 0.300000011921, 0.10000000149, 0.10000000149, 0.600000023842, 0.10000000149, 0.300000011921, 0.5, 0.899999976158, 0.10000000149, 0.5, 0.699999988079, 0.5, 0.600000023842, 0.300000011921, 0.5, 0.600000023842, 0.10000000149, 0.300000011921, 0.5, 0.899999976158, 0.699999988079, 0.5, 0.600000023842, 0.10000000149, 0.800000011921, 0.300000011921, 0.600000023842, 0.899999976158, 0.300000011921, 0.10000000149, 0.600000023842, 0.10000000149, 0.10000000149, 0.699999988079, 0.10000000149, 0.800000011921, 0.40000000596, 0.300000011921, 0.899999976158, 0.10000000149, 0.899999976158, 0.20000000298, 0.20000000298, 0.10000000149, 0.899999976158, 0.699999988079, 0.300000011921, 0.600000023842, 0.10000000149, 0.699999988079, 0.40000000596, 0.300000011921, 0.10000000149, 0.899999976158, 0.20000000298, 0.600000023842, 0.699999988079, 0.300000011921, 0.40000000596, 0.800000011921, 0.800000011921, 0.899999976158, 0.699999988079, 0.5, 0.699999988079, 0.40000000596, 0.699999988079, 0.20000000298, 0.899999976158, 0.699999988079, 0.10000000149, 0.10000000149, 0.300000011921, 0.20000000298, 0.40000000596, 0.800000011921, 0.699999988079, 0.40000000596, 0.600000023842, 0.699999988079, 0.10000000149, 0.899999976158, 0.40000000596, 0.800000011921, 0.300000011921, 0.600000023842, 0.699999988079, 0.699999988079, 
+
+L3_cTRSM_o_LUN
+0.329132588213, 0.290983445686, 0.518608890416, 0.450196678153, 0.59571196627, 0.333239109024, 0.807574982661, -0.307282948652, 0.532035038056, -0.166371615227, 0.396249635758, -0.0151301144297, 0.215690257052, -0.345604787386, 0.748164415979, -0.267674370174, 0.0230110472586, -0.054737867756, 0.29684452105, -0.153817808947, 0.14229890285, 0.0778728674113, 0.416792329049, -0.204635719884, 0.412984492231, 0.135348752859, 0.631664019438, 0.49230799723, 0.632190181758, 0.0104684502782, 0.337012656824, -0.32228511293, 0.328758498139, 0.056546513907, -0.480492886975, -0.413052117291, -0.823867218711, -0.664741879488, -0.87659115525, -0.472506386307, -0.823887182769, 0.601166816594, -0.646982430633, 0.23380446764, -0.450590407047, -0.12590112238, -0.407571331233, 0.340184591706, -0.790302344175, 0.320752521432, 0.00225306717399, 0.0680875999274, -0.260370712498, 0.0420986120425, -0.138956112778, -0.0997526423358, -0.339441849887, -0.00149673230105, -0.36340069964, -0.290458217323, -0.795143312374, -0.692900475193, -0.754201690112, 0.222163757593, -0.201301434402, 0.295653097511, -0.317864896997, -0.257372231279, 0.473204254415, -0.0511578474303, 0.776631765195, -0.299306031636, 0.77534765503, -0.0988899177863, 0.233904499388, -0.699907489587, 0.349208153287, -0.537165320026, 0.367858800363, -0.142890125039, 0.170325758528, -0.452782048209, 0.415971872253, -0.532645494953, -0.0224603350875, -0.0362953265799, 0.211016081385, -0.173731075134, 0.217661533137, 0.0449093984318, 0.383660994825, -0.111264311302, 0.536568362345, 0.0401773954804, 0.735559101649, 0.214556970308, 0.324030905281, -0.440376627925, 0.0893926728849, -0.10017952398, 0.446071807497, -0.0677657625545, -0.44786413179, 0.539273296714, -0.243963300324, 1.33049162938, -0.483647044419, 0.884941168953, 0.308416184748, 0.420066381715, 0.0879201118076, 0.728919060165, -0.350498418455, 0.544288094865, 0.0369674484374, 0.692570792665, -0.0529057724369, 0.629825082104, 0.0808144226271, 0.0467457051333, -0.0832147547532, 0.398661367271, -0.336831347372, 0.145000576864, -0.50130529731, 0.418361500248, -0.752655616474, 0.455224091141, -0.789686869352, 0.331402634912, 0.159779003254, 0.45480297157, -0.175209524234, -0.0684370114627, -0.645024480938, 0.514515369092, 1.01798421074, 0.265736825651, 1.79507192861, -0.351450690041, 1.47686610636, 0.131430006596, 0.472894345416, -0.631143938025, 0.951318859842, -0.575110593075, 0.899727768759, 0.0602936616812, 0.967481467645, -0.493097453218, 0.976572440131, -0.176342152909, 0.0323085948794, -0.169432819907, 0.587679912908, -0.152717166778, 0.267770683165, 0.305291273015, 0.871964895125, 0.518556298855, 1.08468911466, 0.756843205244, 0.872120402327, 0.945645313259, 0.482536367515, -0.339251893584, 0.116576581664, 0.272477384295, 1.00996556082, 0.448549974153, -1.01187196302, -0.31068589079, -1.86004791772, 0.238580597367, -1.6270790887, -0.22210951623, -0.615089810619, 0.76630010891, -0.951613075389, 0.650753261395, -0.930374968557, -0.137471270174, -0.887196193697, 0.49220926558, -1.02710780924, 0.260015430996, -0.0178976789243, 0.0906117130146, -0.637543531318, 0.207283128951, -0.348201005626, -0.352171984869, -0.945315117009, -0.448338017751, -1.15201692465, -0.763114307642, -1.00379624616, -1.08615326276, -0.686885214367, 0.401387322611, -0.121636766229, -0.123993655176, -0.941323687807, -0.481315418513, 0.11861660694, 0.0630726204339, 0.195093698521, -0.00668271511545, 0.204411762255, 0.0926470568598, 0.154216552534, -0.000722285451242, 0.175800364411, -0.0284357121106, 0.181721752362, 0.0162675655527, 0.13067412641, -0.0935645461459, 0.188144190454, 0.0368688201022, 0.0395887542365, -0.0421980777833, 0.188625717074, -0.0478201446893, 0.111979448349, 0.0135150982211, 0.216410719047, 0.00424908861064, 0.175162676832, 0.109057773248, 0.152492182456, 0.205765221906, 0.140415149467, -0.010684541591, 0.10612962379, 0.0117972407341, 0.134643416818, 0.0549453437059, -0.0362297860894, 0.0108635910998, -0.00440570980204, 0.0158109581322, -0.0396551737629, -0.024137931592, -0.17842919669, -0.00143804813476, -0.0942592291516, 0.0119736031608, -0.0283147659565, 0.116657768817, -0.0782842501779, 0.0731499820128, -0.218812934101, -0.0149527034405, 0.0232873069137, 0.0949992401876, -0.0418484890436, 0.124858864666, -0.0071330532252, 0.0886939211777, -0.0676952999152, 0.100949799671, -0.0949153199515, 0.0348909098063, -0.0708613017987, -0.116367864913, -0.0742790641199, -0.0434963353749, -0.0945643919643, 0.0220514191565, -0.0806835498735, 0.034574303601, -0.009429360049, -0.031095514469, -0.0375648450662, 0.033079031856, -0.0551724140878, -0.0379310345864, -0.0628318563627, 0.0575221237301, -0.081354896179, 0.0417454966779, -0.0501678348552, 0.0267927948184, -0.0134574309546, 0.111931642263, -0.0819652081468, 0.111901127459, 0.0271284720944, -0.00341775973586, 0.0187671625936, -0.0322856240027, -0.0560573726883, -0.0512053688916, -0.0749465972094, 0.0551113803662, -0.0206286260585, 0.0112603037576, -0.0586512000333, -0.0280439403109, -0.0702166642094, 0.0364052478609, -0.0484589589035, -0.00964296580743, -0.0623130905858, 0.0928898359313, 0.0827586237213, 0.00689655259765, 0.0724137939256, -0.068965515186, 0.117241381057, -0.0068965518269, 0.149999997739, -0.0500000026719, 0.0965517235213, -0.0586206882164, 0.0844827587235, -0.0637931017012, 0.0603448273293, -0.0741379294416, 0.131034480087, -0.0724137908426, 0.0172413795673, -0.0068965518269, 0.0396551733901, -0.0258620702501, 0.117241381057, -0.0068965518269, 0.0844827587235, -0.0637931017012, 0.115517241174, -0.0362069000458, 0.113793100648, 0.0344827572076, 0.117241381057, -0.0068965518269, 0.0879310379768, -0.00517241399864, 0.120689653117, -0.0482758612468, 
+
+L3_cTRSM_A_nn
+0.300000011921, 0.40000000596, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.800000011921, 0.699999988079, 0.300000011921, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.40000000596, 0.10000000149, 0.5, 0.5, 0.20000000298, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.10000000149, 0.699999988079, 0.40000000596, 0.20000000298, 0.10000000149, 0.600000023842, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.40000000596, 0.10000000149, 0.300000011921, 0.899999976158, 0.899999976158, 0.300000011921, 0.20000000298, 0.300000011921, 0.300000011921, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.699999988079, 0.899999976158, 0.899999976158, 0.300000011921, 0.20000000298, 0.10000000149, 0.20000000298, 0.300000011921, 0.699999988079, 0.600000023842, 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.800000011921, 0.5, 0.40000000596, 0.5, 0.699999988079, 0.800000011921, 0.300000011921, 0.699999988079, 0.5, 0.800000011921, 0.20000000298, 0.5, 0.800000011921, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.699999988079, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.800000011921, 0.600000023842, 0.600000023842, 0.699999988079, 0.300000011921, 0.800000011921, 0.10000000149, 0.20000000298, 0.10000000149, 0.600000023842, 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.600000023842, 0.600000023842, 0.5, 0.699999988079, 0.300000011921, 0.600000023842, 0.600000023842, 0.699999988079, 0.899999976158, 0.800000011921, 0.800000011921, 0.300000011921, 0.40000000596, 0.699999988079, 0.20000000298, 0.899999976158, 0.300000011921, 0.10000000149, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.40000000596, 0.40000000596, 0.5, 0.10000000149, 0.40000000596, 0.699999988079, 0.300000011921, 0.899999976158, 0.699999988079, 0.899999976158, 0.699999988079, 0.899999976158, 0.899999976158, 0.600000023842, 0.20000000298, 0.699999988079, 0.600000023842, 0.300000011921, 0.600000023842, 0.699999988079, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.10000000149, 0.5, 0.10000000149, 0.5, 0.800000011921, 0.300000011921, 0.20000000298, 0.20000000298, 0.600000023842, 0.699999988079, 0.699999988079, 0.40000000596, 0.10000000149, 0.600000023842, 0.300000011921, 0.300000011921, 0.699999988079, 0.40000000596, 0.10000000149, 0.10000000149, 0.10000000149, 0.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, 0.300000011921, 0.699999988079, 0.20000000298, 0.10000000149, 0.10000000149, 0.40000000596, 0.5, 0.899999976158, 0.600000023842, 0.600000023842, 0.300000011921, 0.300000011921, 0.5, 0.800000011921, 0.699999988079, 0.300000011921, 0.800000011921, 0.20000000298, 0.10000000149, 0.300000011921, 0.699999988079, 0.800000011921, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.800000011921, 0.800000011921, 0.800000011921, 0.600000023842, 0.600000023842, 0.20000000298, 0.5, 0.10000000149, 0.40000000596, 0.699999988079, 0.5, 0.10000000149, 0.800000011921, 0.699999988079, 0.300000011921, 0.699999988079, 0.899999976158, 0.800000011921, 0.40000000596, 0.600000023842, 0.699999988079, 0.699999988079, 0.300000011921, 0.699999988079, 0.600000023842, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.20000000298, 0.40000000596, 0.20000000298, 0.20000000298, 0.899999976158, 0.300000011921, 0.5, 0.300000011921, 0.899999976158, 0.699999988079, 0.899999976158, 0.300000011921, 0.5, 0.699999988079, 0.699999988079, 0.800000011921, 0.600000023842, 0.800000011921, 0.699999988079, 0.800000011921, 0.20000000298, 0.600000023842, 0.899999976158, 0.800000011921, 0.800000011921, 0.899999976158, 0.800000011921, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.10000000149, 0.10000000149, 0.5, 0.5, 0.300000011921, 0.10000000149, 0.800000011921, 0.899999976158, 0.699999988079, 0.300000011921, 0.20000000298, 0.40000000596, 0.40000000596, 0.300000011921, 0.300000011921, 0.600000023842, 0.20000000298, 0.40000000596, 0.10000000149, 0.300000011921, 0.600000023842, 0.10000000149, 0.20000000298, 0.600000023842, 0.800000011921, 0.300000011921, 0.40000000596, 0.5, 0.800000011921, 0.800000011921, 0.0, 0.0, 0.0, 0.0, 0.899999976158, 0.20000000298, 0.300000011921, 0.800000011921, 0.699999988079, 0.300000011921, 0.300000011921, 0.10000000149, 0.699999988079, 0.600000023842, 0.800000011921, 0.20000000298, 0.699999988079, 0.5, 0.899999976158, 0.800000011921, 0.5, 0.5, 0.300000011921, 0.20000000298, 0.20000000298, 0.899999976158, 0.699999988079, 0.300000011921, 0.5, 0.300000011921, 0.699999988079, 0.10000000149, 0.20000000298, 0.699999988079, 0.600000023842, 0.899999976158, 0.0, 0.0, 0.699999988079, 0.699999988079, 0.699999988079, 0.300000011921, 0.899999976158, 0.699999988079, 0.699999988079, 0.10000000149, 0.300000011921, 0.300000011921, 0.300000011921, 0.300000011921, 0.5, 0.10000000149, 0.300000011921, 0.300000011921, 0.40000000596, 0.600000023842, 0.20000000298, 0.699999988079, 0.800000011921, 0.40000000596, 0.40000000596, 0.800000011921, 0.699999988079, 0.10000000149, 0.800000011921, 0.300000011921, 0.20000000298, 0.10000000149, 0.300000011921, 0.600000023842, 0.40000000596, 0.10000000149, 
+
+L3_cTRSM_o_RLT
+1.67999991632, 0.759999968529, -1.69538434108, -2.48307671443, -0.33931028015, 1.8317238564, 1.75765674459, 3.06021323111, 0.585745284258, -6.85189338833, -1.63353699604, 6.67286980754, 0.000959390164332, 0.216487260406, -0.727348486408, -3.1358742578, -10.1429168345, 4.3685838467, 7.71081038778, -8.7110985358, 65.6802732624, 9.92302133024, -29.4099425286, -16.6939457264, -24.8344729512, -10.4877177906, 28.4642727556, 23.3848352086, -11.8524871075, 19.0874764207, -19.9631034063, -31.8548662784, -139.885318318, 27.1869354532, 0.520000008583, -0.360000002503, -0.119999954985, 0.159999991408, 0.801379300572, 1.02344824357, 1.19448260124, -0.293793071317, -1.85724112856, -3.17310319017, -0.609790967585, 3.04011264086, -0.361343777873, 1.52979339832, 0.931884405582, -1.71123304671, 0.248635733027, 1.57473051435, -0.192799010887, -2.7172814814, 6.80443254935, -7.89169301645, -4.22216516114, 4.51843426281, -4.49336734933, 0.917969187391, 4.36693978702, -0.535341848317, 3.59140682231, 3.09039986078, -8.29561445716, -0.38186485114, -5.04546803723, 18.766682786, 1.20000002623, -0.599999995232, -1.89230775479, 3.06153831848, 3.04827576645, -0.17931025339, 3.14993181827, -2.91685386908, -9.56824289783, 2.45004130334, 10.2381901924, -1.50468017004, -0.225730006256, -2.88434154029, -3.83194620666, 1.44183565442, 5.6183924538, 18.6532356715, -12.3068309129, -8.50922080102, 22.0776695017, -93.0940213305, -28.0425331456, 37.1303660105, -19.0967213639, 33.8218691411, 41.9847843332, -37.8252941288, 22.8627220686, 19.1052532302, -47.2094044371, 26.4297586128, 20.7991151033, 202.687902914, 1.56000000191, -0.0799999508858, -2.51384609398, 1.24923055492, 2.81793083241, 0.104827602781, 2.17567688944, -0.688748708747, -7.97975692369, 0.520548951678, 8.61388753898, 0.565967103179, 1.19720571237, -2.27396124285, -2.82715461133, 0.203501372167, 0.165392174888, 10.1741900769, -6.71005472238, -6.25503436169, 12.9058433932, -44.6834068804, -11.0757742946, 17.4501156854, -11.3760300002, 16.866416402, 20.2825001837, -15.4983088186, 12.1816651301, 6.58157547078, -25.1364964735, 15.4060069199, 7.79243016012, 88.9124742882, 2.03999990988, 0.279999989033, -3.85538420434, -2.60307674094, 0.395862053267, 3.52965478575, 2.80075066828, 4.37119179344, -1.49417981798, -11.7043190143, 0.563008016326, 11.1883233417, 1.63603714951, 0.287903545504, -1.32969693006, -3.37608500479, -15.8803174444, 5.45970314172, 9.64624356726, -12.769162384, 83.7781785236, 1.0282072251, -37.8717061034, -12.7808478524, -34.6731579882, -9.80879193149, 38.3240707105, 24.4324370684, -8.26559310622, 24.0229074031, -32.2435529464, -34.6351508366, -159.359885665, 54.7649451264, 0.439999995112, 0.0800000045299, -0.870769185026, -0.326153836442, 0.733793103045, 1.27448270522, 1.08728067783, 1.60601895099, -2.31665473867, -4.03289125767, 1.44985876196, 4.56110908056, 1.58318353146, -0.332410652563, -0.897702513666, -2.58073502069, -8.34227645985, 3.31803439919, 3.92590632128, -5.7896042397, 44.665809798, 10.567607219, -17.0654718408, -14.0594508363, -18.0085829768, -9.3014064921, 19.955841365, 21.5047227326, -8.78300196637, 9.16611021857, -13.4134128091, -20.8476712848, -98.2515099469, 6.05619155639, 1.71999993944, 0.0400000052452, -1.85846138447, -0.547692215793, 1.78068968207, 1.67172392491, 1.45395633132, 0.634932834626, -5.97644416334, -5.59734076626, 3.82604135329, 7.63881801064, 1.7246691959, 1.02484299446, -2.72301495574, -3.37893397943, -5.25597054885, 8.81631803923, 1.0811224398, -10.328733993, 52.0361342214, -30.6214656454, -28.2304782516, 6.23471149207, -26.5030593691, 6.0761789177, 34.719761658, 0.878809790678, 5.1075849796, 18.1310021403, -36.0624237836, -9.53757355549, -78.7473293002, 96.4253813812, 1.39999996901, -0.199999978542, -1.78461527254, -0.876923010455, 1.13103452765, 1.22758607577, 1.67544605794, 1.90254481531, -4.84229665654, -4.57615051408, 3.60703618702, 6.5574875994, 2.19719852196, 0.653175535422, -2.91755171075, -3.20928638183, -7.07749782598, 6.82274143327, 1.7291711383, -9.33758466576, 57.2116644619, -12.5388509499, -27.5637334594, -5.35888354408, -25.1267129094, -1.22995412304, 32.4091243293, 12.2799900392, -3.36058089806, 16.7269071597, -27.9420386115, -16.9115321538, -106.749841706, 64.3199559284, 1.63999995279, -0.519999948978, -3.45538428301, 0.196922946733, 2.47172394154, 1.81931013513, 3.79459972803, 1.99635529703, -9.68749971232, -5.82861334931, 8.3822122484, 7.38774878553, 2.76373567412, 0.197721735731, -3.40276542304, -2.55056141222, -5.53076170098, 9.16103128127, -2.24440575496, -12.8333088411, 41.1968899739, -34.1353052562, -21.3307448808, 9.1539906215, -21.4669480287, 10.1295786911, 27.2639448603, -0.314860866604, 7.21959529993, 11.4838956611, -33.281192872, -0.579878201698, -54.8822985595, 87.4250704373, 1.20000000834, 0.40000002861, -1.27692306474, -2.01538455498, 0.0137931900618, 2.23448270158, 1.64960914158, 3.21383583072, -0.838872730612, -8.4708118791, -1.42559503597, 8.133199623, 1.35165436708, 1.11007750638, 0.298360526841, -3.75726722065, -14.0170761831, -0.0323845440388, 9.75416091125, -7.08888853629, 62.1032648557, 39.1233604822, -19.0664270127, -29.5706275294, -22.3689160698, -22.3290804208, 18.6576095623, 41.1612152132, -18.670155371, 9.45567102512, -8.90589354986, -38.129342871, -150.807653441, -41.9973898509, 
+
+L3_zTRSM_A_mm
+8.0, 9.0, 9.0, 5.0, 9.0, 9.0, 8.0, 3.0, 7.0, 8.0, 6.0, 7.0, 2.0, 2.0, 2.0, 1.0, 9.0, 1.0, 4.0, 5.0, 0.0, 0.0, 9.0, 8.0, 4.0, 9.0, 2.0, 8.0, 6.0, 3.0, 7.0, 4.0, 2.0, 8.0, 5.0, 1.0, 9.0, 3.0, 3.0, 5.0, 0.0, 0.0, 0.0, 0.0, 9.0, 8.0, 5.0, 9.0, 2.0, 8.0, 1.0, 1.0, 4.0, 6.0, 1.0, 6.0, 3.0, 5.0, 3.0, 4.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 2.0, 8.0, 6.0, 8.0, 6.0, 1.0, 8.0, 1.0, 5.0, 9.0, 5.0, 3.0, 1.0, 8.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 3.0, 3.0, 6.0, 6.0, 8.0, 7.0, 1.0, 7.0, 6.0, 5.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 8.0, 6.0, 5.0, 5.0, 8.0, 3.0, 3.0, 4.0, 4.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, 9.0, 2.0, 1.0, 2.0, 9.0, 3.0, 9.0, 7.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 9.0, 2.0, 7.0, 3.0, 8.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, 9.0, 2.0, 5.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 9.0, 
+
+L3_zTRSM_B_mn
+0.6, 0.7, 0.1, 0.1, 0.7, 0.5, 0.4, 0.2, 0.5, 0.7, 0.4, 0.3, 0.3, 0.3, 0.2, 0.3, 0.1, 0.3, 0.1, 0.9, 0.6, 0.2, 0.5, 0.9, 0.6, 0.9, 0.1, 0.1, 0.5, 0.4, 0.2, 0.6, 0.7, 0.5, 0.6, 0.8, 0.4, 0.6, 0.3, 0.8, 0.8, 0.2, 0.1, 0.2, 0.3, 0.3, 0.7, 0.5, 0.5, 0.8, 0.2, 0.5, 0.3, 0.8, 0.1, 0.3, 0.1, 0.2, 0.8, 0.8, 0.1, 0.9, 0.1, 0.2, 0.6, 0.7, 0.6, 0.3, 0.7, 0.7, 0.8, 0.7, 0.5, 0.1, 0.6, 0.4, 0.1, 0.6, 0.6, 0.9, 0.8, 0.9, 0.1, 0.2, 0.4, 0.7, 0.6, 0.2, 0.6, 0.2, 0.7, 0.6, 0.2, 0.7, 0.6, 0.7, 0.6, 0.8, 0.5, 0.1, 0.6, 0.9, 0.4, 0.3, 0.8, 0.5, 0.8, 0.5, 0.4, 0.2, 0.9, 0.4, 0.1, 0.9, 0.7, 0.8, 0.6, 0.2, 0.8, 0.6, 0.2, 0.4, 0.5, 0.8, 0.1, 0.1, 0.4, 0.7, 0.4, 0.6, 0.2, 0.3, 0.2, 0.8, 0.8, 0.8, 0.4, 0.3, 0.9, 0.4, 0.1, 0.3, 0.7, 0.8, 0.3, 0.2, 0.3, 0.5, 0.1, 0.4, 0.6, 0.3, 0.1, 0.7, 0.7, 0.1, 0.7, 0.8, 0.3, 0.5, 0.8, 0.1, 0.4, 0.3, 0.4, 0.6, 0.9, 0.3, 0.8, 0.3, 0.1, 0.5, 0.6, 0.7, 0.6, 0.4, 0.1, 0.5, 0.4, 0.8, 0.9, 0.9, 0.5, 0.9, 0.2, 0.5, 0.5, 0.6, 0.4, 0.4, 0.8, 0.2, 0.3, 0.2, 0.4, 0.4, 0.3, 0.3, 0.1, 0.7, 0.1, 0.8, 0.9, 0.9, 0.4, 0.6, 0.6, 0.3, 0.7, 0.1, 0.9, 0.1, 0.8, 0.5, 0.9, 0.4, 0.8, 0.4, 0.7, 0.1, 0.9, 0.8, 0.7, 0.9, 0.4, 0.3, 0.6, 0.2, 0.9, 0.6, 0.5, 0.2, 0.6, 0.7, 0.6, 0.4, 0.5, 0.1, 0.1, 0.5, 0.1, 0.3, 0.2, 0.4, 0.1, 0.1, 0.3, 0.7, 0.9, 0.9, 0.2, 0.1, 0.4, 0.8, 0.8, 0.7, 0.6, 0.9, 0.2, 0.1, 0.7, 0.1, 0.5, 0.5, 0.4, 0.5, 0.3, 0.9, 0.4, 0.7, 0.7, 0.1, 0.7, 0.5, 0.6, 0.8, 0.2, 0.4, 0.8, 0.3, 0.3, 0.9, 0.8, 0.5, 0.7, 0.6, 0.5, 0.8, 0.2, 0.7, 0.8, 0.5, 0.3, 0.2, 0.2, 0.5, 0.1, 0.9, 0.2, 0.8, 0.6, 0.1, 0.8, 0.8, 0.5, 0.5, 0.3, 0.5, 0.5, 0.6, 0.9, 0.9, 0.4, 0.7, 0.3, 0.1, 0.2, 0.9, 0.2, 0.7, 0.5, 0.6, 0.6, 0.1, 0.2, 0.1, 0.1, 0.5, 0.7, 0.3, 0.9, 0.8, 0.2, 0.5, 0.8, 0.7, 0.5, 0.9, 0.3, 0.3, 
+
+L3_zTRSM_o_LUN
+-0.133958047225, 0.0634023358484, -0.229395361146, 0.0019440773242, 0.0129991149435, 0.00295962291275, -0.120025004919, -0.014606037272, 0.0653351315443, 0.0580553772721, 0.00608264893155, 0.0320668880271, -0.126348882414, 0.0696735063329, -0.044177548257, -0.0502170168136, 0.0522860973768, 0.036810427771, -0.0664892116058, 0.18989329588, -0.0375597994313, -0.0275390571767, 0.00870806224388, -0.0700975283092, -0.104577165629, 0.0383595871779, -0.0619419158678, -0.0757518930715, -0.0557894015604, 0.0664938853937, -0.184517662625, 0.0196137392561, -0.0949210300684, -0.0304115608193, 0.00359490016574, 0.0296444215786, -0.0702236760827, 0.0231733017109, 0.0232103541111, -0.0087275635157, -0.0309628976085, -0.021056980123, -0.0372198465751, -0.058278935698, -0.066225517515, -0.0303442676089, -0.0360089621826, -0.0510206414236, 0.0177940788551, 0.00506527587377, -0.0300546336791, -0.0604138046683, 0.0170327950245, 0.101334473014, -0.0717738695849, 0.0692380499707, -0.0779814679933, -0.0523878250108, 0.0703523517282, -0.0586185162717, -0.0454528399349, 0.00843251396343, -0.0257737754508, -0.0133396070809, -0.00436180784171, 0.0597108371938, -0.0711525797109, -0.0222505361281, 0.0360949489608, -0.0189699613951, 0.0216083084991, -0.055554647386, -0.0397030805685, 0.0541809370015, 0.044520325295, -0.0156491073175, -0.0705400040511, 0.0239758416537, -0.00973008140189, 0.0331645117989, -0.0234601152208, -0.0280363313687, -0.0262208353337, 0.0666168234385, 0.023301531523, 0.0402349038871, -0.0261517269967, -0.0874177357089, -0.0144525547592, -0.0612651780432, 0.158607562703, -0.000349319494803, 0.0201660941589, -0.0278132634654, 0.0188873817629, 0.0174304814112, 0.0859319234439, 0.0386937865608, -0.00437738220405, -0.0769941563961, 0.0312701548396, -0.0326239737149, 0.0290051239392, 0.0517531091139, 0.0200295195647, 0.123820434735, 0.0794637653298, -0.0720673352695, -0.0400311865241, 0.0315069978245, 0.0818066545241, 0.0407339255733, 0.120215863434, -0.00944115085266, 0.128069456553, 0.0893168438244, -0.00875999697558, -0.0402889951796, 0.000516531239594, -0.0609614066776, 0.0669900723735, 0.0830178622181, 0.0428576236321, 0.00970051385759, -0.14037004318, 0.00733230807618, -0.0370168081054, 0.112840401769, 0.0199351305638, -0.00559938448532, -0.0238751260468, -0.0362600511932, -0.0116826188016, 0.112092594679, 0.0092104972435, 0.105881476364, 0.0416925499118, -0.0682518953071, 0.084448549975, -0.077911404558, -0.000930781906544, -0.000697974900251, 0.0922679184012, 0.011955012654, -0.0431252487344, -0.0940662263104, -0.0749553909254, 0.010252209449, -0.0114065153767, -0.0452389587963, 0.0335658206213, -0.0205401306942, -0.0487380679532, -0.0130192249246, -0.0287451612394, -0.106177023589, 0.0459277994176, 0.0408918896563, 0.0458419959347, 0.0354121587773, 0.0741133847671, -0.0698810090088, 0.0183565138432, 0.0121731293456, 0.0385894026379, -0.0524649875877, 0.104782397274, -0.0682930088564, 0.0355549910916, -0.0500824092637, 0.0674926385779, -0.0311124228238, 0.123709478255, 0.0159810027817, 0.046337472013, -0.0281180541421, 0.0639560350092, 0.0120628265147, 0.0193178641699, 0.0339603772305, 0.0638918515503, -0.0100080059706, 0.121624940634, 0.0401738245471, 0.0147084605468, 0.0269608521609, -0.0449512178574, -0.00616744690956, -0.0022122260669, -0.0766020761246, 0.0766254155641, -0.0452167718298, -0.0171635796187, 0.0316277902164, -0.00764841576769, 0.00589470113305, 0.0126037044576, 0.0390200149264, 0.00950932899111, -0.087315285976, 0.0740282244386, 0.0286921772169, 0.107964583757, 0.0616987583961, -0.0432178899518, 0.0334484456205, -0.0351676016012, -0.019795845037, 0.00814990433544, 0.00268010584164, -0.0219320985141, 0.00585111608657, 0.043428335708, -0.0472336196486, -0.0359114892462, -0.0200928204084, -0.0281111120157, -0.00386401791166, -0.0176438075853, -0.0614647235226, 0.0684794735057, 0.00583490874551, 0.00200184544406, 0.0365965397924, -0.0129022158898, 0.0152881253816, 0.0111644914852, -0.0106977352602, 0.0366999606486, -0.00801811249067, -0.00943461021779, -0.0649279489789, -0.0025281118122, 0.0907113861185, -0.0672198873736, -0.0143031033313, -0.0336919682475, -0.0307169713006, -0.0806292964245, 0.00124659746251, -0.0911783160323, -0.0412239907728, -0.0742366782007, 0.0089937716263, -0.11307266436, -0.0265720876586, 0.000429988465975, -0.00167289504037, -0.0115880046136, 0.00234417531719, -0.0856050749712, -0.0663404844291, -0.0386938869666, 0.00436770472895, 0.0497130334487, 0.0195713956171, -0.0023137254902, 0.0445882352941, -0.0339644752018, -0.0280166089965, 0.0109305651672, -0.0273614763552, -0.0274874279123, -0.0281444059977, -0.000563321799308, -0.039260438293, -0.0721739331027, 0.0912761245675, -0.0833014994233, -0.0185430219146, 0.00165813148789, -0.0470089965398, 0.0387450980392, 0.0143529411765, 0.0154117647059, 0.0510196078431, -0.0809411764706, 0.0157647058824, 0.0272549019608, -0.0190196078431, 0.0257254901961, 0.0957647058824, 0.0368235294118, -0.0226274509804, 0.0385490196078, 0.00513725490196, 0.00482352941176, 0.0533725490196, -0.0118039215686, 0.0918823529412, 0.0766666666667, 0.0366666666667, 0.0041568627451, -0.0179607843137, -0.0338823529412, 0.060862745098, -0.0747843137255, 0.0784705882353, 0.000274509803922, 0.0529019607843, -0.0282745098039, -0.015568627451, 0.0216470588235, 0.0240784313725, 0.0275294117647, 0.0338823529412, 0.06, -0.0133333333333, 0.0766666666667, -0.03, 0.12, -0.06, 0.0833333333333, -0.0166666666667, 0.02, -0.0266666666667, 0.0966666666667, 0.01, 0.0766666666667, 0.00333333333333, 0.0766666666667, -0.03, 0.03, -0.0566666666667, 0.0166666666667, -0.0166666666667, 0.0533333333333, 0.00666666666667, 0.0533333333333, -0.06, 0.11, -0.0633333333333, 0.0566666666667, -0.00333333333333, 0.0966666666667, -0.0566666666667, 0.106666666667, -0.02, 0.04, -0.02, 
+
+L3_zTRSM_A_nn
+0.2, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.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, 0.7, 0.4, 0.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.8, 0.2, 0.8, 0.6, 0.5, 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.5, 0.2, 0.4, 0.9, 0.5, 0.6, 0.7, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.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, 0.4, 0.4, 0.2, 0.5, 0.3, 0.3, 0.4, 0.4, 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.8, 0.6, 0.1, 0.6, 0.1, 0.3, 0.9, 0.7, 0.9, 0.3, 0.9, 0.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.7, 0.5, 0.1, 0.9, 0.2, 0.6, 0.6, 0.6, 0.4, 0.1, 0.5, 0.2, 0.3, 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.6, 0.3, 0.4, 0.2, 0.3, 0.1, 0.2, 0.5, 0.6, 0.3, 0.9, 0.4, 0.4, 0.2, 0.2, 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.8, 0.3, 0.1, 0.2, 0.3, 0.7, 0.8, 0.7, 0.7, 0.3, 0.9, 0.6, 0.9, 0.6, 0.5, 0.5, 0.1, 0.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.3, 0.5, 0.3, 0.9, 0.2, 0.5, 0.6, 0.9, 0.7, 0.6, 0.5, 0.8, 0.1, 0.7, 0.6, 0.3, 0.1, 0.2, 0.2, 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.1, 0.3, 0.2, 0.7, 0.3, 0.4, 0.6, 0.2, 0.6, 0.5, 0.5, 0.2, 0.8, 0.9, 0.8, 0.2, 0.7, 0.3, 0.2, 0.1, 0.9, 0.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.5, 0.2, 0.7, 0.5, 0.7, 0.4, 0.3, 0.9, 0.3, 0.6, 0.4, 0.3, 0.5, 0.1, 0.7, 0.5, 0.7, 0.5, 0.3, 0.3, 0.2, 0.6, 0.1, 0.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.1, 0.1, 0.4, 0.7, 0.4, 0.5, 0.1, 0.1, 0.9, 0.9, 0.3, 0.9, 0.9, 0.4, 0.4, 0.8, 0.3, 0.1, 0.2, 0.5, 0.8, 0.9, 0.4, 0.8, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.7, 0.2, 0.5, 0.9, 0.9, 0.2, 0.5, 0.9, 0.4, 0.8, 0.3, 0.3, 0.6, 0.5, 0.6, 0.8, 0.7, 0.4, 0.3, 0.6, 0.5, 0.4, 0.4, 0.4, 0.6, 0.5, 0.3, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.1, 0.2, 0.8, 0.2, 0.5, 0.9, 0.4, 0.7, 0.3, 0.1, 0.5, 0.9, 0.4, 0.5, 0.6, 0.8, 0.5, 0.2, 0.2, 0.8, 0.6, 0.2, 0.9, 0.7, 0.6, 0.9, 0.1, 0.6, 0.8, 0.4, 0.0, 0.0, 0.0, 0.0, 0.7, 0.8, 0.1, 0.4, 0.5, 0.7, 0.9, 0.7, 0.4, 0.6, 0.1, 0.2, 0.8, 0.6, 0.5, 0.7, 0.2, 0.5, 0.6, 0.9, 0.8, 0.5, 0.4, 0.1, 0.2, 0.3, 0.2, 0.6, 0.6, 0.4, 0.9, 0.1, 0.0, 0.0, 0.2, 0.6, 0.1, 0.3, 0.1, 0.8, 0.4, 0.6, 0.8, 0.2, 0.8, 0.1, 0.7, 0.3, 0.5, 0.1, 0.1, 0.7, 0.7, 0.6, 0.6, 0.7, 0.6, 0.5, 0.6, 0.8, 0.5, 0.4, 0.8, 0.3, 0.3, 0.8, 0.8, 0.9, 
+
+L3_zTRSM_o_RLT
+2.53846153846, -0.307692307692, -4.15384615385, -2.76923076923, 5.21538461538, 4.67692307692, -1.67032967033, 0.562637362637, -1.61789962615, -0.426758808202, 1.30479681244, 1.29092252982, -1.39577608417, -0.0483354595973, -0.208248556046, 0.0157485581257, -2.02035446306, -34.2377188373, 5.69400474025, 6.16629014222, -2.055880265, 26.7795013692, 20.2801007147, 0.278781388609, -6.25011901787, 6.68033222065, -4.12199872781, 5.13849823069, -2.29543358145, -22.0613616902, -7.99109118095, -10.4457153525, -6.66624028927, 3.46331067699, 2.76923076923, -0.153846153846, -3.31221719457, -2.3257918552, 3.52533936652, 4.90904977376, -0.8116354234, -0.524563671622, -2.41070845467, -0.246187166381, 0.729709858838, 1.49444808619, -0.42191991045, -0.671009605184, 0.000773037351422, -0.370450372745, -0.00130467069877, -21.1058235257, 4.1354934297, 3.510742543, -2.55678416358, 17.4503433975, 11.9832781916, 1.28734237506, -3.29038338627, 3.52567535025, -5.63831248523, 7.04314615589, 2.39776977535, -16.8129785333, -5.32238564128, -6.21393748331, -3.65402287287, 0.742114632218, 2.69230769231, -0.538461538462, -2.71040723982, -1.61085972851, 2.34751131222, 3.46696832579, -0.171816418875, 0.275371687136, -1.64351355134, 0.0156818318128, 0.168410734054, 0.873667804485, 0.165145889102, -0.0927408839467, -0.748944788567, -0.170503340371, -0.0961770961587, -17.0867957406, 2.36254716039, 1.43059904007, -1.01356575191, 13.0879883852, 10.5001711663, 0.360988341662, -5.51078502821, 3.47243269102, 1.35004023866, 6.05762015159, 2.46624134146, -12.4092405352, -7.63693603868, -7.78872991181, -3.27576706848, 4.99494351606, 1.30769230769, -0.461538461538, -0.524886877828, -0.330316742081, 1.07013574661, 1.3036199095, -0.50465416936, -0.23839689722, -0.280630951826, -0.255264262723, -0.528016914973, 1.46191156682, 0.633149468622, -0.980241636281, -0.432232432901, -0.445317384693, 5.30822261293, -2.07028985163, -0.566963802194, 0.016982586198, -4.31464745211, 1.5670058865, 1.53041642631, 3.79356533355, -3.16476205317, -1.51247583365, 1.79859544629, 6.13411478114, 5.95391524855, -5.79066511702, -1.88281388485, -1.81491681163, -0.353228514663, 0.427052252733, 1.30769230769, -0.461538461538, -0.348416289593, -0.62443438914, -0.0180995475113, 2.25067873303, 0.791984486102, -0.480413703943, -1.09967279537, -0.189310871057, -0.817521482201, 0.662763946994, -0.257990720685, -0.113867691238, 0.0744146168347, -1.3252465096, 9.81203388397, 2.34390357873, -0.849335367589, -0.663692181433, -5.58114129107, -1.22420572359, -2.72646876007, 5.68098357425, -0.294067581753, -3.76422238669, -6.8481772104, 5.645062895, 9.24436713199, -0.42753814601, 2.24819912654, -2.28205905397, -0.959987448054, -4.73388687297, 1.30769230769, 0.538461538462, 0.475113122172, -1.33031674208, -1.02986425339, 2.0036199095, -0.30465416936, -0.13839689722, 0.192564924463, -0.644954984373, -0.108052117387, 0.569429796638, 0.175456705824, -0.181404942941, -0.320928629805, 0.449351598639, 7.93853301365, -5.95304327899, -1.54921582808, 1.44540181613, -6.16283041715, 2.49515570153, 2.6474178988, 5.34680760955, -3.04712049237, -1.15044450837, -0.790782115983, 1.925040681, 6.81450686799, -2.61955436635, 0.369845380883, -4.44821450918, -2.69242270613, 0.0129199093012, 2.0, -1.00180120306e-14, -1.58823529412, -2.35294117647, 1.49411764706, 3.57647058824, -0.56974789916, -0.30756302521, -0.748800138612, -0.708897167114, -0.160427500143, 1.26297048364, -0.378591893501, -0.241123944142, -0.265897391581, -0.640956708658, 11.8162836787, -13.2459191191, 0.854494198758, 3.29188659552, -10.5662371442, 9.22982933662, 7.23290619328, 7.94219010944, -4.8198313183, -0.265492608928, -4.28523934809, 4.93193453847, 9.1289867142, -11.5275406773, -1.34903647525, -7.15891029276, -4.2179011628, -0.802262005682, 1.30769230769, 0.538461538462, -0.93665158371, -1.97737556561, 0.676018099547, 3.02714932127, -0.777763413058, -0.245119586296, -0.188384568736, -0.690549717111, 0.624547515376, 1.46602323411, -1.37757905802, -0.538098068801, -0.0256531620363, -0.297484429759, 14.7149585002, -15.3217706237, -0.247114014262, 4.02045016071, -12.8325779909, 10.5455082286, 7.72893334625, 8.50289849881, -4.81759944993, 1.61211987571, -2.48088891757, 0.00422538669345, 6.97778944266, -12.1728944531, 0.82877103129, -6.07537214734, -3.66381659073, -2.57786582966, 2.23076923077, -0.846153846154, -2.80542986425, -0.144796380091, 2.8334841629, 2.02624434389, 0.323400129282, -0.114091790562, -1.26034759661, 0.56446664312, -0.0173885913817, 0.257394546763, 0.123747653039, 0.328399812669, -0.052001074913, -0.336106066568, -10.2450611787, -8.3265399976, 3.94284803098, -0.803047613867, 7.42671088274, 7.91688706589, 4.6789781649, -4.95090202473, 0.490431402225, 2.46397654929, -3.65001545059, 6.55600322606, -1.95689400404, -6.09235040312, -7.18696801329, -1.57535421932, -0.664443491156, 3.1835957169, 1.61538461538, 0.0769230769231, -0.932126696833, -1.19004524887, 1.6814479638, 2.37194570136, -0.749644473174, -0.0238526179703, -1.31686270067, -0.300972950639, 0.814887835175, 1.04060724733, -1.00626442169, -0.502843676322, 0.00138141101527, -0.270867647939, 5.00518717734, -16.1468502699, 0.643427728952, 3.09479951647, -5.18511978123, 12.7925473525, 9.21147753243, 2.88082426014, -3.21234806046, 3.89942511486, -2.51974230756, 0.685276255354, 1.3928270861, -11.4078509372, -1.40871362384, -3.80464519077, -2.60694542596, -2.04083275412, 
+
diff --git a/tests/tests/renderscript/assets/blas_gen.py b/tests/tests/renderscript/assets/blas_gen.py
new file mode 100644
index 0000000..301b249
--- /dev/null
+++ b/tests/tests/renderscript/assets/blas_gen.py
@@ -0,0 +1,901 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 Python script is used to generate all input and output
+# reference data into BLASData.txt
+
+#!/usr/bin/python
+
+from numpy import *
+
+# functions used for generating input matrices.
+
+# Modify a regular matrix to a triangular matrix.
+def triangularMatrixGen(a, uplo):
+    if uplo == 'u': #upper = 1, lower = 2
+        for i in range(1, a.shape[0]):
+            for j in range(0, i):
+                a[i, j] = 0
+    elif uplo == 'l':
+        for i in range(0, a.shape[0]-1):
+            for j in range(i+1, a.shape[1]):
+                a[i, j] = 0
+
+# Modify a regular matrix to a symmetric matrix.
+def symm(a):
+    for i in range(1, a.shape[0]):
+        for j in range(0, i):
+            a[i, j] = a[j, i];
+
+# Modify a regular matrix to a hermitian matrix.
+def herm(a):
+    for i in range(0, a.shape[0]):
+        a[i,i] = complex(a[i,i].real, 0);
+    for i in range(1, a.shape[0]):
+        for j in range(0, i):
+            a[i, j] = complex(a[j, i].real, -a[j, i].imag);
+
+# Zero all elments in a matrix
+def zero(a):
+    for i in range(0, a.shape[0]):
+        for j in range(0, a.shape[1]):
+            a[i, j] = 0;
+
+# Generate a random float matrix given a scale.
+def sMatGen(m, n, scale):
+    a = mat(random.randint(1, 10, size=(m, n)).astype('f4')/scale)
+    return a;
+
+# Generate a random double matrix given a scale.
+def dMatGen(m, n, scale):
+    a = mat(random.randint(1, 10, size=(m, n)).astype('f8')/scale)
+    return a;
+
+# Generate a random float complex matrix given a scale.
+def cMatGen(m, n, scale):
+    a_real = mat(random.randint(1, 10, size=(m, n)).astype('f4')/scale)
+    a_img = mat(random.randint(1, 10, size=(m, n)).astype('f4')/scale)
+    a = a_real + 1j * a_img
+    return a;
+
+# Generate a random double complex matrix given a scale.
+def zMatGen(m, n, scale):
+    a_real = mat(random.randint(1, 10, size=(m, n)).astype('f8')/scale)
+    a_img = mat(random.randint(1, 10, size=(m, n)).astype('f8')/scale)
+    a = a_real + 1j * a_img
+    return a;
+
+# A wrapper to generated random matrices given a scale
+def matrixCreateScale(dt, m, n, scale):
+    if dt == 's':
+        return sMatGen(m, n, scale);
+    elif dt == 'd':
+        return dMatGen(m, n, scale);
+    elif dt == 'c':
+        return cMatGen(m, n, scale);
+    else:
+        return zMatGen(m, n, scale);
+
+# A wrapper to generated random matrices
+def matrixCreate(dt, m, n):
+    return matrixCreateScale(dt, m, n, 10);
+
+# Write a float matrix into a given file.
+# For each element, can pad arbitrary number of 0s after it.
+def writeFloatMatrix(a, name, skip, fo):
+    fo.write(name + '\n');
+    for i in range(0, a.shape[0]):
+        for j in range(0, a.shape[1]):
+            fo.write(str(a[i,j]) + ", ");
+            for hh in range(0, skip):
+                fo.write("0.0, ");
+    fo.write("\n\n");
+
+# Write a double matrix into a given file.
+# For each element, can pad arbitrary number of 0s after it.
+def writeDoubleMatrix(a, name, skip, fo):
+    writeFloatMatrix(a, name, skip, fo);
+
+# Write a float complex matrix into a given file.
+# For each element, can pad arbitrary number of 0s after it.
+def writeFloatComplexMatrix(a, name, skip, fo):
+    fo.write(name + '\n');
+    for i in range(0, a.shape[0]):
+        for j in range(0, a.shape[1]):
+            fo.write(str(real(a[i,j])) + ", ");
+            fo.write(str(imag(a[i,j])) + ", ");
+            for hh in range(0, skip):
+                fo.write("0.0, ");
+                fo.write("0.0, ");
+    fo.write("\n\n");
+
+# Write a double complex matrix into a given file.
+# For each element, can pad arbitrary number of 0s after it.
+def writeDoubleComplexMatrix(a, name, skip, fo):
+    writeFloatComplexMatrix(a, name, skip, fo);
+
+# Wrapper to write a matrix into a given file.
+# For each element, can pad arbitrary number of 0s after it.
+def writeMatrixWithIncrements(dt, a, name, skip, fo):
+    if dt == 's':
+        writeFloatMatrix(a, name, skip, fo);
+    elif dt == 'd':
+        writeDoubleMatrix(a, name, skip, fo);
+    elif dt == 'c':
+        writeFloatComplexMatrix(a, name, skip, fo);
+    else:
+        writeDoubleComplexMatrix(a, name, skip, fo);
+
+# Wrapper to write a matrix into a given file.
+def writeMatrix(dt, a, name, fo):
+    writeMatrixWithIncrements(dt, a, name, 0, fo);
+
+# Write a symmetric or hermitian float matrix into a given file, in a packed form.
+def writeFloatPackedMatrix(a, name, fo):
+    fo.write(name + '\n');
+    for i in range(0, a.shape[0]):
+        for j in range(i, a.shape[1]):
+            fo.write(str(a[i,j]) + ", ");
+    fo.write("\n\n");
+
+# Write a symmetric or hermitian double matrix into a given file, in a packed form.
+def writeDoublePackedMatrix(a, name, fo):
+    writeFloatPackedMatrix(a, name, fo);
+
+# Write a symmetric or hermitian float complex matrix into a given file, in a packed form.
+def writeFloatComplexPackedMatrix(a, name, fo):
+    fo.write(name + '\n');
+    for i in range(0, a.shape[0]):
+        for j in range(i, a.shape[1]):
+            fo.write(str(real(a[i,j])) + ", ");
+            fo.write(str(imag(a[i,j])) + ", ");
+    fo.write("\n\n");
+
+# Write a symmetric or hermitian double complex matrix into a given file, in a packed form.
+def writeDoubleComplexPackedMatrix(a, name, fo):
+    writeFloatComplexPackedMatrix(a, name, fo);
+
+# Wrapper to write a symmetric or hermitian matrix into a given file, in a packed form.
+def writePackedMatrix(dt, a, name, fo):
+    if dt == 's':
+        writeFloatPackedMatrix(a, name, fo);
+    elif dt == 'd':
+        writeDoublePackedMatrix(a, name, fo);
+    elif dt == 'c':
+        writeFloatComplexPackedMatrix(a, name, fo);
+    else:
+        writeDoubleComplexPackedMatrix(a, name, fo);
+
+# Write a float band matrix into a given file, in a banded-storage form.
+def writeGeneralFloatBandedMatrix(a, kl, ku, name, fo):
+    m = a.shape[0];
+    n = a.shape[1];
+    b = sMatGen(m, kl + ku + 1, 1);
+    zero(b);
+    for i in range(0, m):
+        for j in range(max(0, i-kl), min(i+ku+1, n)):
+            b[i, j-i+kl] = a[i, j]
+    writeFloatMatrix(b, name, 0, fo);
+    zero(a);
+    for i in range(0, m):
+        for j in range(max(0, i-kl), min(i+ku+1, n)):
+            a[i, j] = b[i, j-i+kl]
+
+# Write a double band matrix into a given file, in a banded-storage form.
+def writeGeneralDoubleBandedMatrix(a, kl, ku, name, fo):
+    m = a.shape[0];
+    n = a.shape[1];
+    b = dMatGen(m, kl + ku + 1, 1);
+    zero(b);
+    for i in range(0, m):
+        for j in range(max(0, i-kl), min(i+ku+1, n)):
+            b[i, j-i+kl] = a[i, j]
+    writeDoubleMatrix(b, name, 0, fo);
+    zero(a);
+    for i in range(0, m):
+        for j in range(max(0, i-kl), min(i+ku+1, n)):
+            a[i, j] = b[i, j-i+kl]
+
+# Write a float complex band matrix into a given file, in a banded-storage form.
+def writeGeneralFloatComplexBandedMatrix(a, kl, ku, name, fo):
+    m = a.shape[0];
+    n = a.shape[1];
+    b = cMatGen(m, kl + ku + 1, 1);
+    zero(b);
+    for i in range(0, m):
+        for j in range(max(0, i-kl), min(i+ku+1, n)):
+            b[i, j-i+kl] = a[i, j]
+    writeFloatComplexMatrix(b, name, 0, fo);
+    zero(a);
+    for i in range(0, m):
+        for j in range(max(0, i-kl), min(i+ku+1, n)):
+            a[i, j] = b[i, j-i+kl]
+
+# Write a double complex band matrix into a given file, in a banded-storage form.
+def writeGeneralDoubleComplexBandedMatrix(a, kl, ku, name, fo):
+    m = a.shape[0];
+    n = a.shape[1];
+    b = zMatGen(m, kl + ku + 1, 1);
+    zero(b);
+    for i in range(0, m):
+        for j in range(max(0, i-kl), min(i+ku+1, n)):
+            b[i, j-i+kl] = a[i, j]
+    writeDoubleComplexMatrix(b, name, 0, fo);
+    zero(a);
+    for i in range(0, m):
+        for j in range(max(0, i-kl), min(i+ku+1, n)):
+            a[i, j] = b[i, j-i+kl]
+
+# Wrapper to write a band matrix into a given file, in a banded-storage form.
+def writeGeneralBandedMatrix(dt, a, kl, ku, name, fo):
+    if dt == 's':
+        writeGeneralFloatBandedMatrix(a, kl, ku, name, fo);
+    elif dt == 'd':
+        writeGeneralDoubleBandedMatrix(a, kl, ku, name, fo);
+    elif dt == 'c':
+        writeGeneralFloatComplexBandedMatrix(a, kl, ku, name, fo);
+    else:
+        writeGeneralDoubleComplexBandedMatrix(a, kl, ku, name, fo);
+
+# Write a float symmetric or hermitian band matrix into a given file, in a banded-storage form.
+def writeFloatSymmBandedMatrix(a, k, name, fo):
+    n = a.shape[1];
+    b = sMatGen(n, k+1, 1);
+    zero(b);
+    for i in range(0, n):
+        for j in range(i, min(i+k+1, n)):
+            b[i, j-i] = a[i, j]
+    writeFloatMatrix(b, name, 0, fo);
+    zero(a);
+    for i in range(0, n):
+        for j in range(i, min(i+k+1, n)):
+            a[i, j] = b[i, j-i]
+
+# Write a double symmetric or hermitian band matrix into a given file, in a banded-storage form.
+def writeDoubleSymmBandedMatrix(a, k, name, fo):
+    n = a.shape[1];
+    b = dMatGen(n, k+1, 1);
+    zero(b);
+    for i in range(0, n):
+        for j in range(i, min(i+k+1, n)):
+            b[i, j-i] = a[i, j]
+    writeDoubleMatrix(b, name, 0, fo);
+    zero(a);
+    for i in range(0, n):
+        for j in range(i, min(i+k+1, n)):
+            a[i, j] = b[i, j-i]
+
+# Write a float complex symmetric or hermitian band matrix into a given file, in a banded-storage form.
+def writeFloatComplexSymmBandedMatrix(a, k, name, fo):
+    n = a.shape[1];
+    b = cMatGen(n, k+1, 1);
+    zero(b);
+    for i in range(0, n):
+        for j in range(i, min(i+k+1, n)):
+            b[i, j-i] = a[i, j]
+    writeFloatComplexMatrix(b, name, 0, fo);
+    zero(a);
+    for i in range(0, n):
+        for j in range(i, min(i+k+1, n)):
+            a[i, j] = b[i, j-i]
+
+# Write a double complex symmetric or hermitian band matrix into a given file, in a banded-storage form.
+def writeDoubleComplexSymmBandedMatrix(a, k, name, fo):
+    n = a.shape[1];
+    b = zMatGen(n, k+1, 1);
+    zero(b);
+    for i in range(0, n):
+        for j in range(i, min(i+k+1, n)):
+            b[i, j-i] = a[i, j]
+    writeDoubleComplexMatrix(b, name, 0, fo);
+    zero(a);
+    for i in range(0, n):
+        for j in range(i, min(i+k+1, n)):
+            a[i, j] = b[i, j-i]
+
+# Wrapper to write a symmetric or hermitian band matrix into a given file, in a banded-storage form.
+def writeSymmBandedMatrix(dt, a, k, name, fo):
+    if dt == 's':
+        writeFloatSymmBandedMatrix(a, k, name, fo);
+    elif dt == 'd':
+        writeDoubleSymmBandedMatrix(a, k, name, fo);
+    elif dt == 'c':
+        writeFloatComplexSymmBandedMatrix(a, k, name, fo);
+    else:
+        writeDoubleComplexSymmBandedMatrix(a, k, name, fo);
+
+
+
+#L3 Functions, generate input and output matrices to file.
+def L3_xGEMM(fo, alpha, beta, m, n, k):
+    dataType = ['s', 'd', 'c', 'z'];
+
+    for dt in dataType:
+        a = matrixCreate(dt, m, k);
+        b = matrixCreate(dt, k, n);
+        c = matrixCreate(dt, m, n);
+        writeMatrix(dt, a, "L3_" + dt + "GEMM_A_mk", fo);
+        writeMatrix(dt, b, "L3_" + dt + "GEMM_B_kn", fo);
+        writeMatrix(dt, c, "L3_" + dt + "GEMM_C_mn", fo);
+
+        d = alpha * a * b + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "GEMM_o_NN", fo);
+
+        a = matrixCreate(dt, k, m);
+        b = matrixCreate(dt, n, k);
+        writeMatrix(dt, a, "L3_" + dt + "GEMM_A_km", fo);
+        writeMatrix(dt, b, "L3_" + dt + "GEMM_B_nk", fo);
+
+        d = alpha * a.T * b.T + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "GEMM_o_TT", fo);
+        d = alpha * a.H * b.H + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "GEMM_o_HH", fo);
+
+def L3_xSYMM(fo, alpha, beta, m, n):
+    dataType = ['s', 'd', 'c', 'z'];
+
+    for dt in dataType:
+        a = matrixCreate(dt, m, m);
+        symm(a);
+        writeMatrix(dt, a, "L3_" + dt + "SYMM_A_mm", fo);
+
+        b = matrixCreate(dt, m, n);
+        c = matrixCreate(dt, m, n);
+        writeMatrix(dt, b, "L3_" + dt + "SYMM_B_mn", fo);
+        writeMatrix(dt, c, "L3_" + dt + "SYMM_C_mn", fo);
+
+        d = alpha * a * b + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "SYMM_o_L", fo);
+
+        a = matrixCreate(dt, n, n);
+        symm(a);
+        writeMatrix(dt, a, "L3_" + dt + "SYMM_A_nn", fo);
+        d = alpha * b * a + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "SYMM_o_R", fo);
+
+def L3_xHEMM(fo, alpha, beta, m, n):
+    dataType = ['c', 'z'];
+
+    for dt in dataType:
+        a = matrixCreate(dt, m, m);
+        herm(a);
+        writeMatrix(dt, a, "L3_" + dt + "HEMM_A_mm", fo);
+
+        b = matrixCreate(dt, m, n);
+        c = matrixCreate(dt, m, n);
+        writeMatrix(dt, b, "L3_" + dt + "HEMM_B_mn", fo);
+        writeMatrix(dt, c, "L3_" + dt + "HEMM_C_mn", fo);
+
+        d = alpha * a * b + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "HEMM_o_L", fo);
+
+        a = matrixCreate(dt, n, n);
+        herm(a);
+        writeMatrix(dt, a, "L3_" + dt + "HEMM_A_nn", fo);
+        d = alpha * b * a + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "HEMM_o_R", fo);
+
+def L3_xSYRK(fo, alpha, beta, n, k):
+    dataType = ['s', 'd', 'c', 'z'];
+
+    for dt in dataType:
+        a = matrixCreate(dt, n, k);
+        writeMatrix(dt, a, "L3_" + dt + "SYRK_A_nk", fo);
+        c = matrixCreate(dt, n, n);
+        symm(c);
+        writeMatrix(dt, c, "L3_" + dt + "SYRK_C_nn", fo);
+        d = alpha * a * a.T + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "SYRK_o_N", fo);
+
+        a = matrixCreate(dt, k, n);
+        writeMatrix(dt, a, "L3_" + dt + "SYRK_A_kn", fo);
+        d = alpha * a.T * a + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "SYRK_o_T", fo);
+
+def L3_xHERK(fo, alpha, beta, n, k):
+    dataType = ['c', 'z'];
+
+    for dt in dataType:
+        a = matrixCreate(dt, n, k);
+        writeMatrix(dt, a, "L3_" + dt + "HERK_A_nk", fo);
+        c = matrixCreate(dt, n, n);
+        herm(c);
+        writeMatrix(dt, c, "L3_" + dt + "HERK_C_nn", fo);
+        d = alpha * a * a.H + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "HERK_o_N", fo);
+
+        a = matrixCreate(dt, k, n);
+        writeMatrix(dt, a, "L3_" + dt + "HERK_A_kn", fo);
+        d = alpha * a.H * a + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "HERK_o_H", fo);
+
+def L3_xSYR2K(fo, alpha, beta, n, k):
+    dataType = ['s', 'd', 'c', 'z'];
+
+    for dt in dataType:
+        a = matrixCreate(dt, n, k);
+        b = matrixCreate(dt, n, k);
+        writeMatrix(dt, a, "L3_" + dt + "SYR2K_A_nk", fo);
+        writeMatrix(dt, b, "L3_" + dt + "SYR2K_B_nk", fo);
+        c = matrixCreate(dt, n, n);
+        symm(c);
+        writeMatrix(dt, c, "L3_" + dt + "SYR2K_C_nn", fo);
+        d = alpha * (a * b.T + b * a.T) + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "SYR2K_o_N", fo);
+
+        a = matrixCreate(dt, k, n);
+        b = matrixCreate(dt, k, n);
+        writeMatrix(dt, a, "L3_" + dt + "SYR2K_A_kn", fo);
+        writeMatrix(dt, b, "L3_" + dt + "SYR2K_B_kn", fo);
+        d = alpha * (a.T * b + b.T * a) + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "SYR2K_o_T", fo);
+
+def L3_xHER2K(fo, alpha, beta, n, k):
+    dataType = ['c', 'z'];
+
+    for dt in dataType:
+        a = matrixCreate(dt, n, k);
+        b = matrixCreate(dt, n, k);
+        writeMatrix(dt, a, "L3_" + dt + "HER2K_A_nk", fo);
+        writeMatrix(dt, b, "L3_" + dt + "HER2K_B_nk", fo);
+        c = matrixCreate(dt, n, n);
+        herm(c);
+        writeMatrix(dt, c, "L3_" + dt + "HER2K_C_nn", fo);
+        d = alpha * (a * b.H + b * a.H) + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "HER2K_o_N", fo);
+
+        a = matrixCreate(dt, k, n);
+        b = matrixCreate(dt, k, n);
+        writeMatrix(dt, a, "L3_" + dt + "HER2K_A_kn", fo);
+        writeMatrix(dt, b, "L3_" + dt + "HER2K_B_kn", fo);
+        d = alpha * (a.H * b + b.H * a) + beta * c;
+        writeMatrix(dt, d, "L3_" + dt + "HER2K_o_H", fo);
+
+
+def L3_xTRMM(fo, alpha, m, n):
+    dataType = ['s', 'd', 'c', 'z'];
+
+    for dt in dataType:
+        a = matrixCreate(dt, m, m);
+        triangularMatrixGen(a, 'u');
+        writeMatrix(dt, a, "L3_" + dt + "TRMM_A_mm", fo);
+        b = matrixCreate(dt, m, n);
+        writeMatrix(dt, b, "L3_" + dt + "TRMM_B_mn", fo);
+        d = alpha * a * b;
+        writeMatrix(dt, d, "L3_" + dt + "TRMM_o_LUN", fo);
+
+        a = matrixCreate(dt, n, n);
+        triangularMatrixGen(a, 'l');
+        writeMatrix(dt, a, "L3_" + dt + "TRMM_A_nn", fo);
+        d = alpha * b * a.T;
+        writeMatrix(dt, d, "L3_" + dt + "TRMM_o_RLT", fo);
+
+def L3_xTRSM(fo, alpha, m, n):
+    dataType = ['s', 'd', 'c', 'z'];
+
+    for dt in dataType:
+        a = matrixCreateScale(dt, m, m, 1);
+        triangularMatrixGen(a, 'u');
+        writeMatrix(dt, a, "L3_" + dt + "TRSM_A_mm", fo);
+        b = matrixCreate(dt, m, n);
+        writeMatrix(dt, b, "L3_" + dt + "TRSM_B_mn", fo);
+
+        d = alpha * (a.I * b);
+        writeMatrix(dt, d, "L3_" + dt + "TRSM_o_LUN", fo);
+
+        a = matrixCreate(dt, n, n);
+        triangularMatrixGen(a, 'l');
+        writeMatrix(dt, a, "L3_" + dt + "TRSM_A_nn", fo);
+
+        d = alpha * (b * a.I.T);
+        writeMatrix(dt, d, "L3_" + dt + "TRSM_o_RLT", fo);
+
+#L2 Functions, generate input and output matrices to file.
+def L2_xGEMV(fo, alpha, beta, m, n):
+    dataType = ['s', 'd', 'c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, m, n);
+        writeMatrix(dt, a, "L2_" + dt + "GEMV_A_mn", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "GEMV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "GEMV_x_n2", 1, fo);
+
+        y = matrixCreate(dt, m, 1);
+        writeMatrix(dt, y, "L2_" + dt + "GEMV_y_m1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "GEMV_y_m2", 2, fo);
+
+        d = alpha * a * x + beta * y;
+        writeMatrix(dt, d, "L2_" + dt + "GEMV_o_N", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "GEMV_o_N2", 2, fo);
+
+        d = alpha * a.T * y + beta * x;
+        writeMatrix(dt, d, "L2_" + dt + "GEMV_o_T", fo);
+
+        d = alpha * a.H * y + beta * x;
+        writeMatrix(dt, d, "L2_" + dt + "GEMV_o_H", fo);
+
+def L2_xGBMV(fo, alpha, beta, m, n, kl, ku):
+    dataType = ['s', 'd', 'c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, m, n);
+        writeGeneralBandedMatrix(dt, a, kl, ku, "L2_" + dt + "GBMV_A_mn", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "GBMV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "GBMV_x_n2", 1, fo);
+
+        y = matrixCreate(dt, m, 1);
+        writeMatrix(dt, y, "L2_" + dt + "GBMV_y_m1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "GBMV_y_m2", 2, fo);
+
+        d = alpha * a * x + beta * y;
+        writeMatrix(dt, d, "L2_" + dt + "GBMV_o_N", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "GBMV_o_N2", 2, fo);
+
+        d = alpha * a.T * y + beta * x;
+        writeMatrix(dt, d, "L2_" + dt + "GBMV_o_T", fo);
+
+        d = alpha * a.H * y + beta * x;
+        writeMatrix(dt, d, "L2_" + dt + "GBMV_o_H", fo);
+
+def L2_xHEMV(fo, alpha, beta, n):
+    dataType = ['c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        herm(a);
+        writeMatrix(dt, a, "L2_" + dt + "HEMV_A_nn", fo);
+        writePackedMatrix(dt, a, "L2_" + dt + "HEMV_A_nn_pu", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "HEMV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "HEMV_x_n2", 1, fo);
+
+        y = matrixCreate(dt, n, 1);
+        writeMatrix(dt, y, "L2_" + dt + "HEMV_y_n1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "HEMV_y_n2", 2, fo);
+
+        d = alpha * a * x + beta * y;
+        writeMatrix(dt, d, "L2_" + dt + "HEMV_o_N", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "HEMV_o_N2", 2, fo);
+
+def L2_xHBMV(fo, alpha, beta, n, k):
+    dataType = ['c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        herm(a);
+        writeSymmBandedMatrix(dt, a, k, "L2_" + dt + "HBMV_A_nn", fo);
+        herm(a);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "HBMV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "HBMV_x_n2", 1, fo);
+
+        y = matrixCreate(dt, n, 1);
+        writeMatrix(dt, y, "L2_" + dt + "HBMV_y_n1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "HBMV_y_n2", 2, fo);
+
+        d = alpha * a * x + beta * y;
+        writeMatrix(dt, d, "L2_" + dt + "HBMV_o_N", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "HBMV_o_N2", 2, fo);
+
+
+def L2_xSYMV(fo, alpha, beta, n):
+    dataType = ['s', 'd'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        symm(a);
+        writeMatrix(dt, a, "L2_" + dt + "SYMV_A_nn", fo);
+        writePackedMatrix(dt, a, "L2_" + dt + "SYMV_A_nn_pu", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "SYMV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "SYMV_x_n2", 1, fo);
+
+        y = matrixCreate(dt, n, 1);
+        writeMatrix(dt, y, "L2_" + dt + "SYMV_y_n1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "SYMV_y_n2", 2, fo);
+
+        d = alpha * a * x + beta * y;
+        writeMatrix(dt, d, "L2_" + dt + "SYMV_o_N", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "SYMV_o_N2", 2, fo);
+
+def L2_xSBMV(fo, alpha, beta, n, k):
+    dataType = ['s', 'd'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        symm(a);
+        writeSymmBandedMatrix(dt, a, k, "L2_" + dt + "SBMV_A_nn", fo);
+        symm(a);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "SBMV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "SBMV_x_n2", 1, fo);
+
+        y = matrixCreate(dt, n, 1);
+        writeMatrix(dt, y, "L2_" + dt + "SBMV_y_n1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "SBMV_y_n2", 2, fo);
+
+        d = alpha * a * x + beta * y;
+        writeMatrix(dt, d, "L2_" + dt + "SBMV_o_N", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "SBMV_o_N2", 2, fo);
+
+
+def L2_xTRMV(fo, n):
+    dataType = ['s', 'd', 'c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        triangularMatrixGen(a, 'u');
+        writeMatrix(dt, a, "L2_" + dt + "TRMV_A_nn", fo);
+        writePackedMatrix(dt, a, "L2_" + dt + "TRMV_A_nn_pu", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "TRMV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "TRMV_x_n2", 1, fo);
+
+        d = a * x;
+        writeMatrix(dt, d, "L2_" + dt + "TRMV_o_UN", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "TRMV_o_UN2", 1, fo);
+
+        d = a.T * x;
+        writeMatrix(dt, d, "L2_" + dt + "TRMV_o_UT", fo);
+
+        d = a.H * x;
+        writeMatrix(dt, d, "L2_" + dt + "TRMV_o_UH", fo);
+
+def L2_xTBMV(fo, n, k):
+    dataType = ['s', 'd', 'c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        writeSymmBandedMatrix(dt, a, k, "L2_" + dt + "TBMV_A_nn", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "TBMV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "TBMV_x_n2", 1, fo);
+
+        d = a * x;
+        writeMatrix(dt, d, "L2_" + dt + "TBMV_o_UN", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "TBMV_o_UN2", 1, fo);
+
+        d = a.T * x;
+        writeMatrix(dt, d, "L2_" + dt + "TBMV_o_UT", fo);
+
+        d = a.H * x;
+        writeMatrix(dt, d, "L2_" + dt + "TBMV_o_UH", fo);
+
+
+def L2_xTRSV(fo, n):
+    dataType = ['s', 'd', 'c', 'z'];
+    for dt in dataType:
+        a = matrixCreateScale(dt, n, n, 0.25);
+        triangularMatrixGen(a, 'u');
+        writeMatrix(dt, a, "L2_" + dt + "TRSV_A_nn", fo);
+        writePackedMatrix(dt, a, "L2_" + dt + "TRSV_A_nn_pu", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "TRSV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "TRSV_x_n2", 1, fo);
+
+        d = a.I * x;
+        writeMatrix(dt, d, "L2_" + dt + "TRSV_o_UN", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "TRSV_o_UN2", 1, fo);
+
+        d = a.I.T * x;
+        writeMatrix(dt, d, "L2_" + dt + "TRSV_o_UT", fo);
+
+        d = a.I.H * x;
+        writeMatrix(dt, d, "L2_" + dt + "TRSV_o_UH", fo);
+
+def L2_xTBSV(fo, n, k):
+    dataType = ['s', 'd', 'c', 'z'];
+    for dt in dataType:
+        a = matrixCreateScale(dt, n, n, 0.25);
+        writeSymmBandedMatrix(dt, a, k, "L2_" + dt + "TBSV_A_nn", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "TBSV_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "TBSV_x_n2", 1, fo);
+
+        d = a.I * x;
+        writeMatrix(dt, d, "L2_" + dt + "TBSV_o_UN", fo);
+        writeMatrixWithIncrements(dt, d, "L2_" + dt + "TBSV_o_UN2", 1, fo);
+
+        d = a.I.T * x;
+        writeMatrix(dt, d, "L2_" + dt + "TBSV_o_UT", fo);
+
+        d = a.I.H * x;
+        writeMatrix(dt, d, "L2_" + dt + "TBSV_o_UH", fo);
+
+
+def L2_xGER(fo, alpha, m, n):
+    dataType = ['s', 'd'];
+    for dt in dataType:
+        a = matrixCreate(dt, m, n);
+        writeMatrix(dt, a, "L2_" + dt + "GER_A_mn", fo);
+
+        x = matrixCreate(dt, m, 1);
+        writeMatrix(dt, x, "L2_" + dt + "GER_x_m1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "GER_x_m2", 1, fo);
+
+        y = matrixCreate(dt, n, 1);
+        writeMatrix(dt, y, "L2_" + dt + "GER_y_n1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "GER_y_n2", 2, fo);
+
+        d = alpha * x * y.T + a;
+        writeMatrix(dt, d, "L2_" + dt + "GER_o_N", fo);
+
+def L2_xGERU(fo, alpha, m, n):
+    dataType = ['c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, m, n);
+        writeMatrix(dt, a, "L2_" + dt + "GERU_A_mn", fo);
+
+        x = matrixCreate(dt, m, 1);
+        writeMatrix(dt, x, "L2_" + dt + "GERU_x_m1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "GERU_x_m2", 1, fo);
+
+        y = matrixCreate(dt, n, 1);
+        writeMatrix(dt, y, "L2_" + dt + "GERU_y_n1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "GERU_y_n2", 2, fo);
+
+        d = alpha * x * y.T + a;
+        writeMatrix(dt, d, "L2_" + dt + "GERU_o_N", fo);
+
+def L2_xGERC(fo, alpha, m, n):
+    dataType = ['c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, m, n);
+        writeMatrix(dt, a, "L2_" + dt + "GERC_A_mn", fo);
+
+        x = matrixCreate(dt, m, 1);
+        writeMatrix(dt, x, "L2_" + dt + "GERC_x_m1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "GERC_x_m2", 1, fo);
+
+        y = matrixCreate(dt, n, 1);
+        writeMatrix(dt, y, "L2_" + dt + "GERC_y_n1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "GERC_y_n2", 2, fo);
+
+        d = alpha * x * y.H + a;
+        writeMatrix(dt, d, "L2_" + dt + "GERC_o_N", fo);
+
+def L2_xHER(fo, alpha, n):
+    dataType = ['c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        herm(a);
+        writeMatrix(dt, a, "L2_" + dt + "HER_A_nn", fo);
+        writePackedMatrix(dt, a, "L2_" + dt + "HER_A_nn_pu", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "HER_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "HER_x_n2", 1, fo);
+
+        d = alpha * x * x.H + a;
+        writeMatrix(dt, d, "L2_" + dt + "HER_o_N", fo);
+        writePackedMatrix(dt, d, "L2_" + dt + "HER_o_N_pu", fo);
+
+
+def L2_xHER2(fo, alpha, n):
+    dataType = ['c', 'z'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        herm(a);
+        writeMatrix(dt, a, "L2_" + dt + "HER2_A_nn", fo);
+        writePackedMatrix(dt, a, "L2_" + dt + "HER2_A_nn_pu", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "HER2_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "HER2_x_n2", 1, fo);
+
+        y = matrixCreate(dt, n, 1);
+        writeMatrix(dt, y, "L2_" + dt + "HER2_y_n1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "HER2_y_n2", 2, fo);
+
+        d = alpha * x * y.H + y * (alpha * x.H) + a;
+        writeMatrix(dt, d, "L2_" + dt + "HER2_o_N", fo);
+        writePackedMatrix(dt, d, "L2_" + dt + "HER2_o_N_pu", fo);
+
+def L2_xSYR(fo, alpha, n):
+    dataType = ['s', 'd'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        writeMatrix(dt, a, "L2_" + dt + "SYR_A_nn", fo);
+        writePackedMatrix(dt, a, "L2_" + dt + "SYR_A_nn_pu", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "SYR_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "SYR_x_n2", 1, fo);
+
+        d = alpha * x * x.T + a;
+        writeMatrix(dt, d, "L2_" + dt + "SYR_o_N", fo);
+        writePackedMatrix(dt, d, "L2_" + dt + "SYR_o_N_pu", fo);
+
+def L2_xSYR2(fo, alpha, n):
+    dataType = ['s', 'd'];
+    for dt in dataType:
+        a = matrixCreate(dt, n, n);
+        writeMatrix(dt, a, "L2_" + dt + "SYR2_A_nn", fo);
+        writePackedMatrix(dt, a, "L2_" + dt + "SYR2_A_nn_pu", fo);
+
+        x = matrixCreate(dt, n, 1);
+        writeMatrix(dt, x, "L2_" + dt + "SYR2_x_n1", fo);
+        writeMatrixWithIncrements(dt, x, "L2_" + dt + "SYR2_x_n2", 1, fo);
+
+        y = matrixCreate(dt, n, 1);
+        writeMatrix(dt, y, "L2_" + dt + "SYR2_y_n1", fo);
+        writeMatrixWithIncrements(dt, y, "L2_" + dt + "SYR2_y_n2", 2, fo);
+
+        d = alpha * x * y.T + y * (alpha * x.T) + a;
+        writeMatrix(dt, d, "L2_" + dt + "SYR2_o_N", fo);
+        writePackedMatrix(dt, d, "L2_" + dt + "SYR2_o_N_pu", fo);
+
+
+def testBLASL2L3(fo):
+    m = random.randint(10, 20);
+    n = random.randint(10, 20);
+    k = random.randint(10, 20);
+    kl = random.randint(1, 5);
+    ku = random.randint(1, 5);
+
+    alpha = 1.0;
+    beta = 1.0;
+
+    fo.write("M, N, K, KL, KU" + ';\n');
+    fo.write(str(m) + " " + str(n) + " " + str(k) + " " + str(kl) + " " + str(ku) + '\n');
+    fo.write('\n');
+
+    L2_xGEMV(fo, alpha, beta, m, n);
+    L2_xGBMV(fo, alpha, beta, m, n, kl, ku);
+    L2_xHEMV(fo, alpha, beta, n);
+    L2_xHBMV(fo, alpha, beta, n, kl);
+    L2_xSYMV(fo, alpha, beta, n);
+    L2_xSBMV(fo, alpha, beta, n, kl);
+    L2_xTRMV(fo, n);
+    L2_xTBMV(fo, n, kl);
+    L2_xTRSV(fo, n);
+    L2_xTBSV(fo, n, kl);
+    L2_xGER(fo, alpha, m, n);
+    L2_xGERU(fo, alpha, m, n);
+    L2_xGERC(fo, alpha, m, n);
+    L2_xHER(fo, alpha, n);
+    L2_xHER2(fo, alpha, n);
+    L2_xSYR(fo, alpha, n);
+    L2_xSYR2(fo, alpha, n);
+
+    L3_xGEMM(fo, alpha, beta, m, n, k);
+    L3_xSYMM(fo, alpha, beta, m, n);
+    L3_xHEMM(fo, alpha, beta, m, n);
+    L3_xSYRK(fo, alpha, beta, n, k);
+    L3_xHERK(fo, alpha, beta, n, k);
+    L3_xSYR2K(fo, alpha, beta, n, k);
+    L3_xHER2K(fo, alpha, beta, n, k);
+    L3_xTRMM(fo, alpha, m, n);
+    L3_xTRSM(fo, alpha, m, n);
+
+    return;
+
+def javaDataGen():
+    fo = open("BLASData.txt", "w+")
+    fo.write("/* Don't edit this file!  It is auto-generated by blas_gen.py. */\n");
+    fo.write("\n");
+
+    #data body
+    testBLASL2L3(fo);
+    fo.close()
+    return;
+
+javaDataGen();
+
diff --git a/tests/tests/renderscript/libbnnmdata/Android.mk b/tests/tests/renderscript/libbnnmdata/Android.mk
new file mode 100644
index 0000000..471d74a
--- /dev/null
+++ b/tests/tests/renderscript/libbnnmdata/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_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
new file mode 100644
index 0000000..91222c2
--- /dev/null
+++ b/tests/tests/renderscript/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_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 7ec8671..3b693e0 100644
--- a/tests/tests/renderscript/libcoremathtestcpp/Android.mk
+++ b/tests/tests/renderscript/libcoremathtestcpp/Android.mk
@@ -17,15 +17,17 @@
 #
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_MODULE := libcoremathtestcpp_jni
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := CoreMathTestJni.cpp
 
+LOCAL_CFLAGS := -std=c++11
+
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 LOCAL_C_INCLUDES += frameworks/rs/cpp
 LOCAL_C_INCLUDES += frameworks/rs
-LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
 
-LOCAL_SHARED_LIBRARIES := libdl liblog libRScpp libstlport
+LOCAL_SHARED_LIBRARIES := libdl liblog libRScpp
 LOCAL_STATIC_LIBRARIES := libcutils
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyPaddedTest.java b/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyPaddedTest.java
new file mode 100644
index 0000000..c74dbc0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyPaddedTest.java
@@ -0,0 +1,1117 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Type;
+import java.util.Random;
+
+public class AllocationCopyPaddedTest extends RSBaseCompute {
+    public void test_AllocationPadded_Byte3_1D() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);;
+        int arr_len = width * 3;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_1D_Padded_Byte Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Byte3_2D() {
+        Random random = new Random(0x172d8ab9);
+        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);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_2D_AllocationCopyTo_Padded_Byte Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Byte3_3D() {
+        Random random = new Random(0x172d8ab9);
+        int w = random.nextInt(32);
+        int h = random.nextInt(32);
+        int d = random.nextInt(32);
+        int arr_len = w * d * h * 3;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8_3(mRS));
+        typeBuilder.setX(w).setY(h).setZ(d);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_3D_Padded_Byte Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Short3_1D() {
+        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));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_1D_Padded_Short Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Short3_2D() {
+        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];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = (short)random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I16_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_2D_Padded_Short Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Short3_3D() {
+        Random random = new Random(0x172d8ab9);
+        int w = random.nextInt(32);
+        int h = random.nextInt(32);
+        int d = random.nextInt(32);
+        int arr_len = w * d * h * 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));
+        typeBuilder.setX(w).setY(h).setZ(d);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_3D_Padded_Short Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Int3_1D() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_1D_Padded_Int Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Int3_2D() {
+        Random random = new Random(0x172d8ab9);
+        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];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_2D_Padded_Int Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Int3_3D() {
+        Random random = new Random(0x172d8ab9);
+        int w = random.nextInt(32);
+        int h = random.nextInt(32);
+        int d = random.nextInt(32);
+        int arr_len = w * d * h * 3;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32_3(mRS));
+        typeBuilder.setX(w).setY(h).setZ(d);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_3D_Padded_Int Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Float3_1D() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_1D_Padded_Float Failed, output array does not match input",
+                   result);
+    }
+    public void test_AllocationPadded_Float3_2D() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int arr_len = width * height * 3;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_2D_Padded_Float Failed, output array does not match input",
+                   result);
+    }
+    public void test_AllocationPadded_Float3_3D() {
+        Random random = new Random(0x172d8ab9);
+        int w = random.nextInt(32);
+        int h = random.nextInt(32);
+        int d = random.nextInt(32);
+        int arr_len = w * d * h * 3;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32_3(mRS));
+        typeBuilder.setX(w).setY(h).setZ(d);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_3D_Padded_Float Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Double3_1D() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        double[] inArray = new double[arr_len];
+        double[] outArray = new double[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = (double)random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F64_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_1D_Padded_Double Failed, output array does not match input",
+                   result);
+    }
+    public void test_AllocationPadded_Double3_2D() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int arr_len = width * height * 3;
+
+        double[] inArray = new double[arr_len];
+        double[] outArray = new double[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = (double)random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F64_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_2D_Padded_Double Failed, output array does not match input",
+                   result);
+    }
+    public void test_AllocationPadded_Double3_3D() {
+        Random random = new Random(0x172d8ab9);
+        int w = random.nextInt(32);
+        int h = random.nextInt(32);
+        int d = random.nextInt(32);
+        int arr_len = w * d * h * 3;
+
+        double[] inArray = new double[arr_len];
+        double[] outArray = new double[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = (double)random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F64_3(mRS));
+        typeBuilder.setX(w).setY(h).setZ(d);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_3D_Padded_Double Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Long3_1D() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_1D_Padded_Long Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Long3_2D() {
+        Random random = new Random(0x172d8ab9);
+        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];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_2D_Padded_Long Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_Long3_3D() {
+        Random random = new Random(0x172d8ab9);
+        int w = random.nextInt(32);
+        int h = random.nextInt(32);
+        int d = random.nextInt(32);
+        int arr_len = w * d * h * 3;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64_3(mRS));
+        typeBuilder.setX(w).setY(h).setZ(d);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copyFrom(inArray);
+        alloc.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopyTo_3D_Padded_Long Failed, output array does not match input",
+                   result);
+    }
+
+
+    public void test_AllocationPadded_copy1DRangeTo_Byte3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeTo(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeTo_Padded_Byte Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy1DRangeTo_Short3() {
+        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));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeTo(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeTo_Padded_Short Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy1DRangeTo_Int3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeTo(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeTo_Padded_Int Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy1DRangeTo_Float3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeTo(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0f) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeTo_Padded_Float Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy1DRangeTo_Long3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeTo(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeTo_Padded_Long Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy2DRangeTo_Byte3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount * 3;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copy2DRangeFrom(xoff, yoff, xcount, ycount, inArray);
+        alloc.copy2DRangeTo(xoff, yoff, xcount, ycount, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy2DRangeTo_Padded_Byte Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy2DRangeTo_Short3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount * 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));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copy2DRangeFrom(xoff, yoff, xcount, ycount, inArray);
+        alloc.copy2DRangeTo(xoff, yoff, xcount, ycount, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy2DRangeTo_Padded_Short Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy2DRangeTo_Int3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount * 3;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copy2DRangeFrom(xoff, yoff, xcount, ycount, inArray);
+        alloc.copy2DRangeTo(xoff, yoff, xcount, ycount, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy2DRangeTo_Padded_Int Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy2DRangeTo_Float3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount * 3;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copy2DRangeFrom(xoff, yoff, xcount, ycount, inArray);
+        alloc.copy2DRangeTo(xoff, yoff, xcount, ycount, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy2DRangeTo_Padded_Float Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy2DRangeTo_Long3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount * 3;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64_3(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        alloc.copy2DRangeFrom(xoff, yoff, xcount, ycount, inArray);
+        alloc.copy2DRangeTo(xoff, yoff, xcount, ycount, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy2DRangeTo_Padded_Long Failed, output array does not match input",
+                   result);
+    }
+
+
+    public void test_AllocationPadded_copy1DRangeToUnchecked_Byte3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeToUnchecked_Padded_Byte Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy1DRangeToUnchecked_Short3() {
+        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));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeToUnchecked_Padded_Short Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy1DRangeToUnchecked_Int3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeToUnchecked_1D_Padded_Int Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy1DRangeToUnchecked_Float3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0f) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeToUnchecked_Padded_Float Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationPadded_copy1DRangeToUnchecked_Long3() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width * 3;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64_3(mRS));
+        typeBuilder.setX(width);
+        Allocation alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.setAutoPadding(true);
+        int offset = random.nextInt(width);
+        int count = width - offset;
+        alloc.copy1DRangeFrom(offset, count, inArray);
+        alloc.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count * 3; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count * 3; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_copy1DRangeToUnchecked_Padded_Long 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
new file mode 100644
index 0000000..f6bef0a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/AllocationCopyToTest.java
@@ -0,0 +1,797 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Type;
+import java.util.Random;
+
+public class AllocationCopyToTest extends RSBaseCompute {
+    private Allocation alloc;
+
+    public void test_Allocationcopy1DRangeTo_Byte() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8(mRS));
+        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);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeTo_Byte failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy1DRangeTo_Short() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        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(mRS));
+        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);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeTo_Short failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy1DRangeTo_Int() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        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);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeTo_Int failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy1DRangeTo_Float() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32(mRS));
+        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);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0f) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeTo_Float failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy1DRangeTo_Long() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64(mRS));
+        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);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeTo_Long failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy2DRangeTo_Byte() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8(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);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy2DRangeTo_Byte failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy2DRangeTo_Short() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount;
+
+        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(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);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy2DRangeTo_Short failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy2DRangeTo_Int() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(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);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy2DRangeTo_Int failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy2DRangeTo_Float() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32(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);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy2DRangeTo_Float failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy2DRangeTo_Long() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int arr_len = xcount * ycount;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64(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);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy2DRangeTo_Long failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy3DRangeTo_Byte() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(64);
+        int height = random.nextInt(64);
+        int depth = random.nextInt(64);
+
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int zoff = random.nextInt(height);
+
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int zcount = depth - zoff;
+        int arr_len = xcount * ycount * zcount;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8(mRS));
+        typeBuilder.setX(width).setY(height).setZ(depth);
+        alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.copy3DRangeFrom(xoff, yoff, zoff, xcount, ycount, zcount, (Object)inArray);
+        alloc.copy3DRangeTo(xoff, yoff, zoff, xcount, ycount, zcount, (Object)outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                android.util.Log.v("Allocation CopyTo Test", "Failed: " + i + " " + inArray[i] + " " + outArray[i]);
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy3DRangeTo_Byte failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy3DRangeTo_Short() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(64);
+        int height = random.nextInt(64);
+        int depth = random.nextInt(64);
+
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int zoff = random.nextInt(height);
+
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int zcount = depth - zoff;
+        int arr_len = xcount * ycount * zcount;
+
+        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(mRS));
+        typeBuilder.setX(width).setY(height).setZ(depth);
+        alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.copy3DRangeFrom(xoff, yoff, zoff, xcount, ycount, zcount, (Object)inArray);
+        alloc.copy3DRangeTo(xoff, yoff, zoff, xcount, ycount, zcount, (Object)outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                android.util.Log.v("Allocation CopyTo Test", "Failed: " + i + " " + inArray[i] + " " + outArray[i]);
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy3DRangeTo_Short failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy3DRangeTo_Int() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(64);
+        int height = random.nextInt(64);
+        int depth = random.nextInt(64);
+
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int zoff = random.nextInt(height);
+
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int zcount = depth - zoff;
+        int arr_len = xcount * ycount * zcount;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        typeBuilder.setX(width).setY(height).setZ(depth);
+        alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.copy3DRangeFrom(xoff, yoff, zoff, xcount, ycount, zcount, (Object)inArray);
+        alloc.copy3DRangeTo(xoff, yoff, zoff, xcount, ycount, zcount, (Object)outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                android.util.Log.v("Allocation CopyTo Test", "Failed: " + i + " " + inArray[i] + " " + outArray[i]);
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy3DRangeTo_Int failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy3DRangeTo_Float() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(64);
+        int height = random.nextInt(64);
+        int depth = random.nextInt(64);
+
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int zoff = random.nextInt(height);
+
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int zcount = depth - zoff;
+        int arr_len = xcount * ycount * zcount;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32(mRS));
+        typeBuilder.setX(width).setY(height).setZ(depth);
+        alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.copy3DRangeFrom(xoff, yoff, zoff, xcount, ycount, zcount, (Object)inArray);
+        alloc.copy3DRangeTo(xoff, yoff, zoff, xcount, ycount, zcount, (Object)outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                android.util.Log.v("Allocation CopyTo Test", "Failed: " + i + " " + inArray[i] + " " + outArray[i]);
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy3DRangeTo_Float failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy3DRangeTo_Long() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(64);
+        int height = random.nextInt(64);
+        int depth = random.nextInt(64);
+
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int zoff = random.nextInt(height);
+
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int zcount = depth - zoff;
+        int arr_len = xcount * ycount * zcount;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64(mRS));
+        typeBuilder.setX(width).setY(height).setZ(depth);
+        alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        alloc.copy3DRangeFrom(xoff, yoff, zoff, xcount, ycount, zcount, (Object)inArray);
+        alloc.copy3DRangeTo(xoff, yoff, zoff, xcount, ycount, zcount, (Object)outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                android.util.Log.v("Allocation CopyTo Test", "Failed: " + i + " " + inArray[i] + " " + outArray[i]);
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy3DRangeTo_Long failed, output array does not match input",
+                   result);
+    }
+
+    public void test_AllocationCopy3DRangeFrom_Alloc() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(64);
+        int height = random.nextInt(64);
+        int depth = random.nextInt(64);
+
+        int xoff = random.nextInt(width);
+        int yoff = random.nextInt(height);
+        int zoff = random.nextInt(height);
+
+        int xcount = width - xoff;
+        int ycount = height - yoff;
+        int zcount = depth - zoff;
+        int arr_len = xcount * ycount * zcount;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64(mRS));
+        typeBuilder.setX(width).setY(height).setZ(depth);
+        alloc = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation allocRef = Allocation.createTyped(mRS, typeBuilder.create());
+
+        allocRef.copy3DRangeFrom(xoff, yoff, zoff, xcount, ycount, zcount, (Object)inArray);
+        alloc.copy3DRangeFrom(xoff, yoff, zoff, xcount, ycount, zcount, allocRef, xoff, yoff, zoff);
+        alloc.copy3DRangeTo(xoff, yoff, zoff, xcount, ycount, zcount, (Object)outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                android.util.Log.v("Allocation Copy3DRangeFrom (alloc) Test", "Failed: " + i + " " + inArray[i] + " " + outArray[i]);
+                break;
+            }
+        }
+        assertTrue("test_AllocationCopy3DRangeFrom_Alloc failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy1DRangeToUnchecked_Byte() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8(mRS));
+        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.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeToUnchecked_Byte failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy1DRangeToUnchecked_Short() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        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(mRS));
+        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.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeToUnchecked_Short failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy1DRangeToUnchecked_Int() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        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.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeToUnchecked_Int Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy1DRangeToUnchecked_Float() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32(mRS));
+        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.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0f) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeToUnchecked_Float Failed, output array does not match input",
+                   result);
+    }
+
+    public void test_Allocationcopy1DRangeToUnchecked_Long() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64(mRS));
+        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.copy1DRangeToUnchecked(offset, count, outArray);
+
+        boolean result = true;
+        for (int i = 0; i < count; i++) {
+            if (inArray[i] != outArray[i]) {
+                result = false;
+                break;
+            }
+        }
+        for (int i = count; i < arr_len; i++) {
+            if (outArray[i] != 0) {
+                result = false;
+                break;
+            }
+        }
+        assertTrue("test_Allocationcopy1DRangeToUnchecked_Long Failed, output array does not match input",
+                   result);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/BLASData.java b/tests/tests/renderscript/src/android/renderscript/cts/BLASData.java
new file mode 100644
index 0000000..def0352
--- /dev/null
+++ b/tests/tests/renderscript/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.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
new file mode 100644
index 0000000..1822f6a
--- /dev/null
+++ b/tests/tests/renderscript/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.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 dfcf1f5..686281c 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/CoreMathVerifier.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/CoreMathVerifier.java
@@ -290,14 +290,14 @@
     }
 
     static private Target.Floaty atan2(float y, float x, Target t) {
-        Target.Floaty inY = t.new32(y);
-        Target.Floaty inX = t.new32(x);
+        Target.Floaty numerator = t.new32(y);
+        Target.Floaty denominator = t.new32(x);
         return t.new32(
-            atan2(inY.mid32(), inX.mid32()),
-            atan2(inY.min32(), inX.min32()),
-            atan2(inY.min32(), inX.max32()),
-            atan2(inY.max32(), inX.min32()),
-            atan2(inY.max32(), inX.max32()));
+            atan2(numerator.mid32(), denominator.mid32()),
+            atan2(numerator.min32(), denominator.min32()),
+            atan2(numerator.min32(), denominator.max32()),
+            atan2(numerator.max32(), denominator.min32()),
+            atan2(numerator.max32(), denominator.max32()));
     }
 
     static private Target.Floaty atan2pi(float y, float x, Target t) {
@@ -462,14 +462,14 @@
     }
 
     static private Target.Floaty powr(float x, float y, Target t) {
-        Target.Floaty inX = t.new32(x);
-        Target.Floaty inY = t.new32(y);
+        Target.Floaty base = t.new32(x);
+        Target.Floaty exponent = t.new32(y);
         return t.new32(
-            pow(inX.mid32(), inY.mid32()),
-            pow(inX.min32(), inY.min32()),
-            pow(inX.min32(), inY.max32()),
-            pow(inX.max32(), inY.min32()),
-            pow(inX.max32(), inY.max32()));
+            pow(base.mid32(), exponent.mid32()),
+            pow(base.min32(), exponent.min32()),
+            pow(base.min32(), exponent.max32()),
+            pow(base.max32(), exponent.min32()),
+            pow(base.max32(), exponent.max32()));
     }
 
     static private Target.Floaty recip(float f, Target t) {
@@ -570,15 +570,15 @@
     }
 
     static public void computeAbs(TestAbs.ArgumentsCharUchar args) {
-        args.out = (byte)Math.abs(args.inValue);
+        args.out = (byte)Math.abs(args.inV);
     }
 
     static public void computeAbs(TestAbs.ArgumentsShortUshort args) {
-        args.out = (short)Math.abs(args.inValue);
+        args.out = (short)Math.abs(args.inV);
     }
 
     static public void computeAbs(TestAbs.ArgumentsIntUint args) {
-        args.out = Math.abs(args.inValue);
+        args.out = Math.abs(args.inV);
     }
 
     static public void computeAcos(TestAcos.ArgumentsFloatFloat args, Target t) {
@@ -588,7 +588,7 @@
 
     static public void computeAcosh(TestAcosh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.out = acosh(args.in, t);
+        args.out = acosh(args.inV, t);
     }
 
     static public void computeAcospi(TestAcospi.ArgumentsFloatFloat args, Target t) {
@@ -603,7 +603,7 @@
 
     static public void computeAsinh(TestAsinh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.out = asinh(args.in, t);
+        args.out = asinh(args.inV, t);
     }
 
     static public void computeAsinpi(TestAsinpi.ArgumentsFloatFloat args, Target t) {
@@ -628,22 +628,22 @@
 
     static public void computeAtan2(TestAtan2.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(6, 128, false);
-        args.out = atan2(args.inY, args.inX, t);
+        args.out = atan2(args.inNumerator, args.inDenominator, t);
     }
 
     static public void computeAtan2pi(TestAtan2pi.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(6, 128, false);
-        args.out = atan2pi(args.inY, args.inX, t);
+        args.out = atan2pi(args.inNumerator, args.inDenominator, t);
     }
 
     static public void computeCbrt(TestCbrt.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(2, 128, false);
-        args.out = cbrt(args.in, t);
+        args.out = cbrt(args.inV, t);
     }
 
     static public void computeCeil(TestCeil.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(0, 1, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             ceil(in.mid32()),
             ceil(in.min32()),
@@ -1047,59 +1047,59 @@
 
     static public void computeCopysign(TestCopysign.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        args.out = t.new32(Math.copySign(args.inX, args.inY));
+        args.out = t.new32(Math.copySign(args.inMagnitudeValue, args.inSignValue));
     }
 
     static public void computeCos(TestCos.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.out = cos(args.in, t);
+        args.out = cos(args.inV, t);
     }
 
     static public void computeCosh(TestCosh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.out = cosh(args.in, t);
+        args.out = cosh(args.inV, t);
     }
 
     static public void computeCospi(TestCospi.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.out = cospi(args.in, t);
+        args.out = cospi(args.inV, t);
     }
 
     static public void computeCross(TestCross.ArgumentsFloatNFloatNFloatN args, Target t) {
         t.setPrecision(1, 4, false);
-        cross(args.inLhs, args.inRhs, args.out, t);
+        cross(args.inLeftVector, args.inRightVector, args.out, t);
     }
 
     static public void computeDegrees(TestDegrees.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 3, false);
-        Target.Floaty in = t.new32(args.inValue);
+        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.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(1, 1, false);
-        args.out = distance(new float[] {args.inLhs}, new float[] {args.inRhs}, t);
+        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);
-        args.out = distance(args.inLhs, args.inRhs, t);
+        args.out = distance(args.inLeftVector, args.inRightVector, t);
     }
 
     static public void computeDot(TestDot.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(1, 4, false);
-        Target.Floaty a = t.new32(args.inLhs);
-        Target.Floaty b = t.new32(args.inRhs);
+        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);
         Target.Floaty sum = t.new32(0.f);
-        for (int i = 0; i < args.inLhs.length; i++) {
-            Target.Floaty a = t.new32(args.inLhs[i]);
-            Target.Floaty b = t.new32(args.inRhs[i]);
+        for (int i = 0; i < args.inLeftVector.length; i++) {
+            Target.Floaty a = t.new32(args.inLeftVector[i]);
+            Target.Floaty b = t.new32(args.inRightVector[i]);
             sum = t.add(sum, t.multiply(a, b));
         }
         args.out = sum;
@@ -1107,59 +1107,59 @@
 
     static public void computeErf(TestErf.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(16, 128, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
-            erf(args.in),
+            erf(args.inV),
             erf(in.min32()),
             erf(in.max32()));
     }
 
     static public void computeErfc(TestErfc.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(16, 128, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
-            erfc(args.in),
+            erfc(args.inV),
             erfc(in.min32()),
             erfc(in.max32()));
     }
 
     static public void computeExp(TestExp.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 16, false);
-        args.out = exp(args.in, t);
+        args.out = exp(args.inV, t);
     }
 
     static public void computeExp10(TestExp10.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 32, false);
-        args.out = exp10(args.in, t);
+        args.out = exp10(args.inV, t);
     }
 
     static public void computeExp2(TestExp2.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 16, false);
-        args.out = exp2(args.in, t);
+        args.out = exp2(args.inV, t);
     }
 
     static public void computeExpm1(TestExpm1.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 16, false);
-        args.out = expm1(args.in, t);
+        args.out = expm1(args.inV, t);
     }
 
     static public void computeFabs(TestFabs.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
-            Math.abs(args.in),
+            Math.abs(args.inV),
             Math.abs(in.min32()),
             Math.abs(in.max32()));
     }
 
     static public void computeFastDistance(TestFastDistance.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(FAST_PRECISION, FAST_PRECISION, false);
-        args.out = distance(new float[] {args.inLhs}, new float[] {args.inRhs}, t);
+        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);
-        args.out = distance(args.inLhs, args.inRhs, t);
+        args.out = distance(args.inLeftVector, args.inRightVector, t);
     }
 
     static public void computeFastLength(TestFastLength.ArgumentsFloatFloat args, Target t) {
@@ -1197,53 +1197,53 @@
 
     static public void computeFloor(TestFloor.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
-            floor(args.in),
+            floor(args.inV),
             floor(in.min32()),
             floor(in.max32()));
     }
 
     static public void computeFma(TestFma.ArgumentsFloatFloatFloatFloat args, Target t) {
         t.setPrecision(1, 1, false);
-        Target.Floaty ab = t.multiply(t.new32(args.inA), t.new32(args.inB));
-        args.out = t.add(ab, t.new32(args.inC));
+        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.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        Target.Floaty inX = t.new32(args.inX);
-        Target.Floaty inY = t.new32(args.inY);
+        Target.Floaty a = t.new32(args.inA);
+        Target.Floaty b = t.new32(args.inB);
         args.out = t.new32(
-            Math.max(args.inX, args.inY),
-            Math.max(inX.min32(), inY.min32()),
-            Math.max(inX.min32(), inY.max32()),
-            Math.max(inX.max32(), inY.min32()),
-            Math.max(inX.max32(), inY.max32()));
+            Math.max(args.inA, args.inB),
+            Math.max(a.min32(), b.min32()),
+            Math.max(a.min32(), b.max32()),
+            Math.max(a.max32(), b.min32()),
+            Math.max(a.max32(), b.max32()));
     }
 
     static public void computeFmin(TestFmin.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        Target.Floaty inX = t.new32(args.inX);
-        Target.Floaty inY = t.new32(args.inY);
+        Target.Floaty a = t.new32(args.inA);
+        Target.Floaty b = t.new32(args.inB);
         args.out = t.new32(
-            Math.min(args.inX, args.inY),
-            Math.min(inX.min32(), inY.min32()),
-            Math.min(inX.min32(), inY.max32()),
-            Math.min(inX.max32(), inY.min32()),
-            Math.min(inX.max32(), inY.max32()));
+            Math.min(args.inA, args.inB),
+            Math.min(a.min32(), b.min32()),
+            Math.min(a.min32(), b.max32()),
+            Math.min(a.max32(), b.min32()),
+            Math.min(a.max32(), b.max32()));
     }
 
     static public void computeFmod(TestFmod.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(1, 1, false);
-        Target.Floaty inX = t.new32(args.inX);
-        Target.Floaty inY = t.new32(args.inY);
+        Target.Floaty numerator = t.new32(args.inNumerator);
+        Target.Floaty denominator = t.new32(args.inDenominator);
         args.out = t.new32(
-            args.inX % args.inY,
-            inX.min32() % inY.min32(),
-            inX.min32() % inY.max32(),
-            inX.max32() % inY.min32(),
-            inX.max32() % inY.max32());
+            args.inNumerator % args.inDenominator,
+            numerator.min32() % denominator.min32(),
+            numerator.min32() % denominator.max32(),
+            numerator.max32() % denominator.min32(),
+            numerator.max32() % denominator.max32());
     }
 
     static public void computeFract(TestFract.ArgumentsFloatFloatFloat args, Target t) {
@@ -1265,7 +1265,7 @@
         t.setPrecision(0, 0, false);
         FrexpResult result = frexp(args.inV);
         args.out = t.new32(result.significand);
-        args.outIptr = result.exponent;
+        args.outExponent = result.exponent;
     }
 
     static public void computeHalfRecip(TestHalfRecip.ArgumentsFloatFloat args, Target t) {
@@ -1285,18 +1285,18 @@
 
     static public void computeHypot(TestHypot.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(4, 4, false);
-        args.out = hypot(args.inX, args.inY, t);
+        args.out = hypot(args.inA, args.inB, t);
     }
 
     static public String verifyIlogb(TestIlogb.ArgumentsFloatInt args) {
         // Special case when the input is 0.  We accept two different answers.
-        if (args.in == 0.f) {
+        if (args.inV == 0.f) {
             if (args.out != -Integer.MAX_VALUE && args.out != Integer.MIN_VALUE) {
                 return "Expected " + Integer.toString(-Integer.MAX_VALUE) + " or " +
                     Integer.toString(Integer.MIN_VALUE);
             }
         } else {
-            int result = ilogb(args.in);
+            int result = ilogb(args.inV);
             if (args.out != result) {
                 return "Expected " + Integer.toString(result);
             }
@@ -1306,11 +1306,11 @@
 
     static public void computeLdexp(TestLdexp.ArgumentsFloatIntFloat args, Target t) {
         t.setPrecision(1, 1, false);
-        Target.Floaty inX = t.new32(args.inX);
+        Target.Floaty inMantissa = t.new32(args.inMantissa);
         args.out = t.new32(
-            ldexp(inX.mid32(), args.inY),
-            ldexp(inX.min32(), args.inY),
-            ldexp(inX.max32(), args.inY));
+            ldexp(inMantissa.mid32(), args.inExponent),
+            ldexp(inMantissa.min32(), args.inExponent),
+            ldexp(inMantissa.max32(), args.inExponent));
     }
 
     static public void computeLength(TestLength.ArgumentsFloatFloat args, Target t) {
@@ -1325,7 +1325,7 @@
 
     static public void computeLgamma(TestLgamma.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(16, 128, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             lgamma(in.mid32()),
             lgamma(in.min32()),
@@ -1337,7 +1337,7 @@
      * is fixed, we can restore computeLgamma and remove verifyLgamma.
     static public void computeLgamma(TestLgamma.ArgumentsFloatIntFloat args, Target t) {
         t.setPrecision(16, 128, false);
-        Target.Floaty in = t.new32(args.inX);
+        Target.Floaty in = t.new32(args.inV);
         LgammaResult result = lgamma2(in.mid32());
         LgammaResult resultMin = lgamma2(in.min32());
         LgammaResult resultMax = lgamma2(in.max32());
@@ -1347,25 +1347,25 @@
     */
     static public String verifyLgamma(TestLgamma.ArgumentsFloatIntFloat args, Target t) {
         t.setPrecision(16, 128, false);
-        Target.Floaty in = t.new32(args.inX);
+        Target.Floaty in = t.new32(args.inV);
         LgammaResult result = lgamma2(in.mid32());
         LgammaResult resultMin = lgamma2(in.min32());
         LgammaResult resultMax = lgamma2(in.max32());
         Target.Floaty expectedOut = t.new32(result.lgamma, resultMin.lgamma, resultMax.lgamma);
-        boolean isNegativeZero = args.inX == 0.f && 1.f / args.inX < 0.f;
+        boolean isNegativeZero = args.inV == 0.f && 1.f / args.inV < 0.f;
         /* TODO The current implementation of bionic does not handle the -0.f case correctly.
          * It should set the sign to -1 but sets it to 1.
          */
         if (!expectedOut.couldBe(args.out) ||
-            (args.outY != result.gammaSign && !isNegativeZero)) {
+            (args.outSignOfGamma != result.gammaSign && !isNegativeZero)) {
             StringBuilder message = new StringBuilder();
-            message.append(String.format("Input in %14.8g {%8x}:\n", args.inX, Float.floatToRawIntBits(args.inX)));
+            message.append(String.format("Input in %14.8g {%8x}:\n", args.inV, Float.floatToRawIntBits(args.inV)));
             message.append("Expected out: ");
             message.append(expectedOut.toString());
             message.append("\n");
             message.append(String.format("Actual   out: %14.8g {%8x}", args.out, Float.floatToRawIntBits(args.out)));
-            message.append(String.format("Expected outY: %d\n", result.gammaSign));
-            message.append(String.format("Actual   outY: %d\n", args.outY));
+            message.append(String.format("Expected outSign: %d\n", result.gammaSign));
+            message.append(String.format("Actual   outSign: %d\n", args.outSignOfGamma));
             return message.toString();
         }
 
@@ -1376,27 +1376,27 @@
     // They are not consistent.
     static public void computeLog(TestLog.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 16, false);
-        args.out = log(args.in, t);
+        args.out = log(args.inV, t);
     }
 
     static public void computeLog10(TestLog10.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 16, false);
-        args.out = log10(args.in, t);
+        args.out = log10(args.inV, t);
     }
 
     static public void computeLog1p(TestLog1p.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(2, 16, false);
-        args.out = log1p(args.in, t);
+        args.out = log1p(args.inV, t);
     }
 
     static public void computeLog2(TestLog2.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 128, false);
-        args.out = log2(args.in, t);
+        args.out = log2(args.inV, t);
     }
 
     static public void computeLogb(TestLogb.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             logb(in.mid32()),
             logb(in.min32()),
@@ -1405,89 +1405,89 @@
 
     static public void computeMad(TestMad.ArgumentsFloatFloatFloatFloat args, Target t) {
         t.setPrecision(1, 4, false);
-        Target.Floaty ab = t.multiply(t.new32(args.inA), t.new32(args.inB));
-        args.out = t.add(ab, t.new32(args.inC));
+        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 computeMax(TestMax.ArgumentsCharCharChar args) {
-        args.out = maxI8(args.inV1, args.inV2);
+        args.out = maxI8(args.inA, args.inB);
     }
 
     static public void computeMax(TestMax.ArgumentsUcharUcharUchar args) {
-        args.out = maxU8(args.inV1, args.inV2);
+        args.out = maxU8(args.inA, args.inB);
     }
 
     static public void computeMax(TestMax.ArgumentsShortShortShort args) {
-        args.out = maxI16(args.inV1, args.inV2);
+        args.out = maxI16(args.inA, args.inB);
     }
 
     static public void computeMax(TestMax.ArgumentsUshortUshortUshort args) {
-        args.out = maxU16(args.inV1, args.inV2);
+        args.out = maxU16(args.inA, args.inB);
     }
 
     static public void computeMax(TestMax.ArgumentsIntIntInt args) {
-        args.out = maxI32(args.inV1, args.inV2);
+        args.out = maxI32(args.inA, args.inB);
     }
 
     static public void computeMax(TestMax.ArgumentsUintUintUint args) {
-        args.out = maxU32(args.inV1, args.inV2);
+        args.out = maxU32(args.inA, args.inB);
     }
 
     static public void computeMax(TestMax.ArgumentsLongLongLong args) {
-        args.out = maxI64(args.inV1, args.inV2);
+        args.out = maxI64(args.inA, args.inB);
     }
 
     static public void computeMax(TestMax.ArgumentsUlongUlongUlong args) {
-        args.out = maxU64(args.inV1, args.inV2);
+        args.out = maxU64(args.inA, args.inB);
     }
 
     static public void computeMax(TestMax.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        Target.Floaty in = t.new32(args.in);
-        Target.Floaty in1 = t.new32(args.in1);
+        Target.Floaty a = t.new32(args.inA);
+        Target.Floaty b = t.new32(args.inB);
         args.out = t.new32(
-            Math.max(in.mid32(), in1.mid32()),
-            Math.max(in.min32(), in1.min32()),
-            Math.max(in.min32(), in1.max32()),
-            Math.max(in.max32(), in1.min32()),
-            Math.max(in.max32(), in1.max32()));
+            Math.max(a.mid32(), b.mid32()),
+            Math.max(a.min32(), b.min32()),
+            Math.max(a.min32(), b.max32()),
+            Math.max(a.max32(), b.min32()),
+            Math.max(a.max32(), b.max32()));
     }
 
     static public void computeMin(TestMin.ArgumentsCharCharChar args) {
-        args.out = minI8(args.inV1, args.inV2);
+        args.out = minI8(args.inA, args.inB);
     }
 
     static public void computeMin(TestMin.ArgumentsUcharUcharUchar args) {
-        args.out = minU8(args.inV1, args.inV2);
+        args.out = minU8(args.inA, args.inB);
     }
 
     static public void computeMin(TestMin.ArgumentsShortShortShort args) {
-        args.out = minI16(args.inV1, args.inV2);
+        args.out = minI16(args.inA, args.inB);
     }
 
     static public void computeMin(TestMin.ArgumentsUshortUshortUshort args) {
-        args.out = minU16(args.inV1, args.inV2);
+        args.out = minU16(args.inA, args.inB);
     }
 
     static public void computeMin(TestMin.ArgumentsIntIntInt args) {
-        args.out = minI32(args.inV1, args.inV2);
+        args.out = minI32(args.inA, args.inB);
     }
 
     static public void computeMin(TestMin.ArgumentsUintUintUint args) {
-        args.out = minU32(args.inV1, args.inV2);
+        args.out = minU32(args.inA, args.inB);
     }
 
     static public void computeMin(TestMin.ArgumentsLongLongLong args) {
-        args.out = minI64(args.inV1, args.inV2);
+        args.out = minI64(args.inA, args.inB);
     }
 
     static public void computeMin(TestMin.ArgumentsUlongUlongUlong args) {
-        args.out = minU64(args.inV1, args.inV2);
+        args.out = minU64(args.inA, args.inB);
     }
 
     static public void computeMin(TestMin.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        args.out = t.new32(Math.min(args.in, args.in1));
+        args.out = t.new32(Math.min(args.inA, args.inB));
     }
 
     static public void computeMix(TestMix.ArgumentsFloatFloatFloatFloat args, Target t) {
@@ -1495,18 +1495,19 @@
         Target.Floaty start = t.new32(args.inStart);
         Target.Floaty stop = t.new32(args.inStop);
         Target.Floaty diff = t.subtract(stop, start);
-        args.out = t.add(start, t.multiply(diff, t.new32(args.inAmount)));
+        args.out = t.add(start, t.multiply(diff, t.new32(args.inFraction)));
     }
 
     static public void computeModf(TestModf.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        float ret = (float)(int)args.inX;
-        args.outIret = t.new32(ret);
-        args.out = t.new32(args.inX - ret);
+        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);
+        // TODO(jeanluc) We're not using the input argument
         args.out = t.new32(Float.NaN);
     }
 
@@ -1517,7 +1518,7 @@
 
     static public void computeNativeAcosh(TestNativeAcosh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = acosh(args.in, t);
+        args.out = acosh(args.inV, t);
     }
 
     static public void computeNativeAcospi(TestNativeAcospi.ArgumentsFloatFloat args, Target t) {
@@ -1532,7 +1533,7 @@
 
     static public void computeNativeAsinh(TestNativeAsinh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = asinh(args.in, t);
+        args.out = asinh(args.inV, t);
     }
 
     static public void computeNativeAsinpi(TestNativeAsinpi.ArgumentsFloatFloat args, Target t) {
@@ -1547,7 +1548,7 @@
 
     static public void computeNativeAtanh(TestNativeAtanh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = atanh(args.inIn, t);
+        args.out = atanh(args.inV, t);
     }
 
     static public void computeNativeAtanpi(TestNativeAtanpi.ArgumentsFloatFloat args, Target t) {
@@ -1557,47 +1558,47 @@
 
     static public void computeNativeAtan2(TestNativeAtan2.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = atan2(args.inY, args.inX, t);
+        args.out = atan2(args.inNumerator, args.inDenominator, t);
     }
 
     static public void computeNativeAtan2pi(TestNativeAtan2pi.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = atan2pi(args.inY, args.inX, t);
+        args.out = atan2pi(args.inNumerator, args.inDenominator, t);
     }
 
     static public void computeNativeCbrt(TestNativeCbrt.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = cbrt(args.in, t);
+        args.out = cbrt(args.inV, t);
     }
 
     static public void computeNativeCos(TestNativeCos.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = cos(args.in, t);
+        args.out = cos(args.inV, t);
     }
 
     static public void computeNativeCosh(TestNativeCosh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = cosh(args.in, t);
+        args.out = cosh(args.inV, t);
     }
 
     static public void computeNativeCospi(TestNativeCospi.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = cospi(args.in, t);
+        args.out = cospi(args.inV, t);
     }
 
     static public void computeNativeDistance(TestNativeDistance.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = distance(new float[]{args.inLhs}, new float[]{args.inRhs}, t);
+        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);
-        args.out = distance(args.inLhs, args.inRhs, t);
+        args.out = distance(args.inLeftVector, args.inRightVector, t);
     }
 
     static public void computeNativeDivide(TestNativeDivide.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = t.divide(t.new32(args.inLhs), t.new32(args.inRhs));
+        args.out = t.divide(t.new32(args.inLeftVector), t.new32(args.inRightVector));
     }
 
     static public void computeNativeExp(TestNativeExp.ArgumentsFloatFloat args, Target t) {
@@ -1618,12 +1619,12 @@
 
     static public void computeNativeExpm1(TestNativeExpm1.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = expm1(args.in, t);
+        args.out = expm1(args.inV, t);
     }
 
     static public void computeNativeHypot(TestNativeHypot.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = hypot(args.inX, args.inY, t);
+        args.out = hypot(args.inA, args.inB, t);
     }
 
     static public void computeNativeLength(TestNativeLength.ArgumentsFloatFloat args, Target t) {
@@ -1658,7 +1659,7 @@
 
     static public void computeNativeLog1p(TestNativeLog1p.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = log1p(args.in, t);
+        args.out = log1p(args.inV, t);
     }
 
     static public void computeNativeLog2(TestNativeLog2.ArgumentsFloatFloat args, Target t) {
@@ -1687,10 +1688,10 @@
         // TODO we would like to use NATIVE_PRECISION, NATIVE_PRECISION
         t.setPrecision(32000, 32000, true);
         // For very small values, allow anything.
-        if (Math.abs(args.inV) < 1.e-20) {
+        if (Math.abs(args.inBase) < 1.e-20) {
             args.out = any32(t);
         } else {
-            args.out = powr(args.inV, args.inY, t);
+            args.out = powr(args.inBase, args.inExponent, t);
         }
     }
 
@@ -1711,53 +1712,53 @@
 
     static public void computeNativeRsqrt(TestNativeRsqrt.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = rsqrt(args.in, t);
+        args.out = rsqrt(args.inV, t);
     }
 
     static public void computeNativeSin(TestNativeSin.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = sin(args.in, t);
+        args.out = sin(args.inV, t);
     }
 
     static public void computeNativeSincos(TestNativeSincos.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.outCosptr = cos(args.inV, t);
+        args.outCos = cos(args.inV, t);
         args.out = sin(args.inV, t);
     }
 
     static public void computeNativeSinh(TestNativeSinh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = sinh(args.in, t);
+        args.out = sinh(args.inV, t);
     }
 
     static public void computeNativeSinpi(TestNativeSinpi.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = sinpi(args.in, t);
+        args.out = sinpi(args.inV, t);
     }
 
     static public void computeNativeSqrt(TestNativeSqrt.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = sqrt(args.in, t);
+        args.out = sqrt(args.inV, t);
     }
 
     static public void computeNativeTan(TestNativeTan.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = tan(args.in, t);
+        args.out = tan(args.inV, t);
     }
 
     static public void computeNativeTanh(TestNativeTanh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = tanh(args.in, t);
+        args.out = tanh(args.inV, t);
     }
 
     static public void computeNativeTanpi(TestNativeTanpi.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(NATIVE_PRECISION, NATIVE_PRECISION, true);
-        args.out = tanpi(args.in, t);
+        args.out = tanpi(args.inV, t);
     }
 
     static public void computeNextafter(TestNextafter.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        args.out = t.new32(Math.nextAfter(args.inX, args.inY));
+        args.out = t.new32(Math.nextAfter(args.inV, args.inTarget));
     }
 
     static public void computeNormalize(TestNormalize.ArgumentsFloatFloat args, Target t) {
@@ -1774,23 +1775,23 @@
 
     static public void computePow(TestPow.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(16, 128, false);
-        Target.Floaty inX = t.new32(args.inX);
-        Target.Floaty inY = t.new32(args.inY);
+        Target.Floaty base = t.new32(args.inBase);
+        Target.Floaty exponent = t.new32(args.inExponent);
         args.out = t.new32(
-            pow(inX.mid32(), inY.mid32()),
-            pow(inX.min32(), inY.min32()),
-            pow(inX.min32(), inY.max32()),
-            pow(inX.max32(), inY.min32()),
-            pow(inX.max32(), inY.max32()));
+            pow(base.mid32(), exponent.mid32()),
+            pow(base.min32(), exponent.min32()),
+            pow(base.min32(), exponent.max32()),
+            pow(base.max32(), exponent.min32()),
+            pow(base.max32(), exponent.max32()));
     }
 
     static public void computePown(TestPown.ArgumentsFloatIntFloat args, Target t) {
         t.setPrecision(16, 128, false);
-        Target.Floaty in = t.new32(args.inX);
+        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
         // numbers.  Using a float loses the lowest bit.
-        final double y = (double) args.inY;
+        final double y = (double) args.inExponent;
         args.out = t.new32(
             (float) Math.pow(in.mid32(), y),
             (float) Math.pow(in.min32(), y),
@@ -1799,25 +1800,25 @@
 
     static public void computePowr(TestPowr.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(16, 128, false);
-        args.out = powr(args.inX, args.inY, t);
+        args.out = powr(args.inBase, args.inExponent, t);
     }
 
     static public void computeRadians(TestRadians.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 3, false);
-        Target.Floaty in = t.new32(args.inValue);
+        Target.Floaty in = t.new32(args.inV);
         Target.Floaty k = t.new32((float)(Math.PI / 180.0));
         args.out = t.multiply(in, k);
     }
 
     static public void computeRemainder(TestRemainder.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        RemquoResult result = remquo(args.inX, args.inY);
+        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);
-        RemquoResult expected = remquo(args.inB, args.inC);
+        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.
         if (expected.remainder != expected.remainder) {
@@ -1827,8 +1828,8 @@
             }
         } else {
             // The quotient should have the same lowest three bits.
-            if ((args.outD & 0x07) != (expected.quotient & 0x07)) {
-                return "Quotient returned " +  Integer.toString(args.outD) +
+            if ((args.outQuotient & 0x07) != (expected.quotient & 0x07)) {
+                return "Quotient returned " +  Integer.toString(args.outQuotient) +
                     " does not have the same lower three bits as the expected " +
                     Integer.toString(expected.quotient);
             }
@@ -1844,7 +1845,7 @@
 
     static public void computeRint(TestRint.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             rint(in.mid32()),
             rint(in.min32()),
@@ -1858,7 +1859,7 @@
 
     static public void computeRound(TestRound.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             round(in.mid32()),
             round(in.min32()),
@@ -1867,7 +1868,7 @@
 
     static public void computeRsqrt(TestRsqrt.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(2, 2, false);
-        args.out = rsqrt(args.in, t);
+        args.out = rsqrt(args.inV, t);
     }
 
     static public void computeSign(TestSign.ArgumentsFloatFloat args, Target t) {
@@ -1877,28 +1878,28 @@
 
     static public void computeSin(TestSin.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.out = sin(args.in, t);
+        args.out = sin(args.inV, t);
     }
 
     static public void computeSincos(TestSincos.ArgumentsFloatFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.outCosptr = cos(args.inV,t );
+        args.outCos = cos(args.inV,t );
         args.out = sin(args.inV, t);
     }
 
     static public void computeSinh(TestSinh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.out = sinh(args.in, t);
+        args.out = sinh(args.inV, t);
     }
 
     static public void computeSinpi(TestSinpi.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.out = sinpi(args.in, t);
+        args.out = sinpi(args.inV, t);
     }
 
     static public void computeSqrt(TestSqrt.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(3, 3, false);
-        args.out = sqrt(args.in, t);
+        args.out = sqrt(args.inV, t);
     }
 
     static public void computeStep(TestStep.ArgumentsFloatFloatFloat args, Target t) {
@@ -1908,22 +1909,22 @@
 
     static public void computeTan(TestTan.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(5, 128, false);
-        args.out = tan(args.in, t);
+        args.out = tan(args.inV, t);
     }
 
     static public void computeTanh(TestTanh.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(5, 128, false);
-        args.out = tanh(args.in, t);
+        args.out = tanh(args.inV, t);
     }
 
     static public void computeTanpi(TestTanpi.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(4, 128, false);
-        args.out = tanpi(args.in, t);
+        args.out = tanpi(args.inV, t);
     }
 
     static public void computeTgamma(TestTgamma.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(16, 128, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             tgamma(in.mid32()),
             tgamma(in.min32()),
@@ -1932,7 +1933,7 @@
 
     static public void computeTrunc(TestTrunc.ArgumentsFloatFloat args, Target t) {
         t.setPrecision(0, 0, false);
-        Target.Floaty in = t.new32(args.in);
+        Target.Floaty in = t.new32(args.inV);
         args.out = t.new32(
             trunc(in.mid32()),
             trunc(in.min32()),
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/DebugContext.java b/tests/tests/renderscript/src/android/renderscript/cts/DebugContext.java
index cf0f76d..5c71155 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/DebugContext.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/DebugContext.java
@@ -61,13 +61,16 @@
     public void testDebugContextI() {
         setupDebugContext();
         Soob.invoke_write_i(7, 1);  // Write to invalid location.
-        for (int i = 0; i < 100; i++) {
-            Soob.invoke_write_i(9, 0);
-            mRS.finish();
-        }
+
+        // Flush messages through the pipeline.
+        mRS.sendMessage(RS_MSG_TEST_FLUSH, null);
+        waitForMessage();
+
         Soob.destroy();
         assertTrue(mRanErrorHandler);
-        checkForErrors();
+
+        // The context is dead at this point so make sure it's not reused
+        RenderScript.releaseAllContexts();
     }
 
     /**
@@ -77,12 +80,15 @@
     public void testDebugContextK() {
         setupDebugContext();
         Soob.forEach_write_k(AUnused);  // Write to invalid location.
-        for (int i = 0; i < 100; i++) {
-            Soob.invoke_write_i(9, 0);
-            mRS.finish();
-        }
+
+        // Flush messages through the pipeline.
+        mRS.sendMessage(RS_MSG_TEST_FLUSH, null);
+        waitForMessage();
+
         Soob.destroy();
         assertTrue(mRanErrorHandler);
-        checkForErrors();
+
+        // The context is dead at this point so make sure it's not reused
+        RenderScript.releaseAllContexts();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/DoubleTest.java b/tests/tests/renderscript/src/android/renderscript/cts/DoubleTest.java
new file mode 100644
index 0000000..2de6afd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/DoubleTest.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.renderscript.cts;
+
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+
+public class DoubleTest extends RSBaseCompute {
+
+    public void testDoubleGlobal() {
+        RenderScript rs = RenderScript.create(getContext());
+        ScriptC_doubleglobal dc = new ScriptC_doubleglobal(rs);
+        dc.invoke_func_setup();
+        int big = 1024 * 1024;
+        Allocation out = Allocation.createSized(rs, Element.F32(rs), big);
+
+        dc.forEach_times2pi(out);
+        float[] data = new float[big];
+        out.copyTo(data);
+
+        Target t = new Target(true);
+        t.setPrecision(1, 1, false);
+        double pi = 3.14159265359;
+        Target.Floaty pi2 = t.new32((float) (pi * 2));
+        for (int x = 0; x < data.length; x++) {
+            float v = data[x];
+            Target.Floaty expected = t.multiply(pi2, t.new32(x));
+            if (!expected.couldBe(v)) {
+                StringBuilder message = new StringBuilder();
+                message.append("X: ");
+                appendVariableToMessage(message, x);
+                message.append("\n");
+                message.append("Expected output: ");
+                appendVariableToMessage(message, expected);
+                message.append("\n");
+                message.append("Actual   output: ");
+                appendVariableToMessage(message, v);
+
+                message.append("\n");
+                assertTrue("Incorrect output for testDoubleGlobal " + message.toString(), false);
+            }
+        }
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java
index ead4528..9fa9c15 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ElementTest.java
@@ -183,6 +183,13 @@
         // A_8 is in U8
         Element[] BOOLEAN = { Element.BOOLEAN(mRS) };
         Element[] ELEMENT = { Element.ELEMENT(mRS) };
+        Element[] F16 = { Element.F16(mRS) };
+        Element[] F16_2 = { Element.F16_2(mRS),
+            Element.createVector(mRS, Element.DataType.FLOAT_16, 2) };
+        Element[] F16_3 = { Element.F16_3(mRS),
+            Element.createVector(mRS, Element.DataType.FLOAT_16, 3) };
+        Element[] F16_4 = { Element.F16_4(mRS),
+            Element.createVector(mRS, Element.DataType.FLOAT_16, 4) };
         Element[] F32 = { Element.F32(mRS) };
         Element[] F32_2 = { Element.F32_2(mRS),
             Element.createVector(mRS, Element.DataType.FLOAT_32, 2) };
@@ -236,8 +243,10 @@
             Element.createPixel(mRS, Element.DataType.UNSIGNED_8,
                                 Element.DataKind.PIXEL_RGBA) };
 
-        Element[][] ElementArrs = { ALLOCATION, BOOLEAN, ELEMENT, F32, F32_2,
-                                    F32_3, F32_4, F64, I16, I32, I64, I8,
+        Element[][] ElementArrs = { ALLOCATION, BOOLEAN, ELEMENT,
+                                    F16, F16_2, F16_3, F16_4,
+                                    F32, F32_2, F32_3, F32_4,
+                                    F64, I16, I32, I64, I8,
                                     MATRIX_2X2, MATRIX_3X3, MATRIX_4X4, MESH,
                                     PROGRAM_FRAGMENT, PROGRAM_RASTER,
                                     PROGRAM_STORE, PROGRAM_VERTEX, RGBA_4444,
@@ -272,6 +281,10 @@
             eb.add(Element.RGB_565(mRS), "RGB_565", arraySize);
             eb.add(Element.RGB_888(mRS), "RGB_888", arraySize);
             eb.add(Element.RGBA_8888(mRS), "RGBA_8888", arraySize);
+            eb.add(Element.F16(mRS), "F16", arraySize);
+            eb.add(Element.F16_2(mRS), "F16_2", arraySize);
+            eb.add(Element.F16_3(mRS), "F16_3", arraySize);
+            eb.add(Element.F16_4(mRS), "F16_4", arraySize);
             eb.add(Element.F32(mRS), "F32", arraySize);
             eb.add(Element.F32_2(mRS), "F32_2", arraySize);
             eb.add(Element.F32_3(mRS), "F32_3", arraySize);
@@ -338,6 +351,10 @@
         assertFalse(Element.RGB_565(mRS).isComplex());
         assertFalse(Element.RGB_888(mRS).isComplex());
         assertFalse(Element.RGBA_8888(mRS).isComplex());
+        assertFalse(Element.F16(mRS).isComplex());
+        assertFalse(Element.F16_2(mRS).isComplex());
+        assertFalse(Element.F16_3(mRS).isComplex());
+        assertFalse(Element.F16_4(mRS).isComplex());
         assertFalse(Element.F32(mRS).isComplex());
         assertFalse(Element.F32_2(mRS).isComplex());
         assertFalse(Element.F32_3(mRS).isComplex());
@@ -416,6 +433,7 @@
         // Uncomment when NONE is no longer hidden.
         //assertEquals(DataType.NONE, DataType.valueOf("NONE"));
 
+        assertEquals(DataType.FLOAT_16, DataType.valueOf("FLOAT_16"));
         assertEquals(DataType.FLOAT_32, DataType.valueOf("FLOAT_32"));
         assertEquals(DataType.FLOAT_64, DataType.valueOf("FLOAT_64"));
         assertEquals(DataType.SIGNED_8, DataType.valueOf("SIGNED_8"));
@@ -448,10 +466,11 @@
         assertEquals(DataType.RS_PROGRAM_RASTER, DataType.valueOf("RS_PROGRAM_RASTER"));
         assertEquals(DataType.RS_PROGRAM_STORE, DataType.valueOf("RS_PROGRAM_STORE"));
         // Make sure no new enums are added
-        assertEquals(29, DataType.values().length);
+        assertEquals(30, DataType.values().length);
 
         for (DataType dt : DataType.values()) {
             switch (dt) {
+            case FLOAT_16:
             case FLOAT_32:
             case FLOAT_64:
             case SIGNED_8:
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Float16ArithmeticTest.java b/tests/tests/renderscript/src/android/renderscript/cts/Float16ArithmeticTest.java
new file mode 100644
index 0000000..8f6d4a1
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Float16ArithmeticTest.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.util.Random;
+import java.lang.Math;
+import java.lang.Float;
+import java.lang.Integer;
+import java.lang.Short;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.renderscript.Allocation;
+import android.renderscript.Element;
+import android.renderscript.RenderScript;
+import android.renderscript.RSRuntimeException;
+import android.renderscript.Script;
+import android.renderscript.Type;
+import android.util.Log;
+
+public class Float16ArithmeticTest extends RSBaseCompute {
+    private int numInputs = Float16TestData.input.length;
+
+    // Allocations to hold float16 input and output
+    private Allocation mInput;
+    private Allocation mF16Matrix;
+    private Allocation mU16Matrix;
+
+    // A numInputs * numInputs length 1-D array with data copied from
+    // 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() {
+        Element f16 = Element.F16(mRS);
+        Element u16 = Element.U16(mRS);
+        Type f16Matrix = Type.createXY(mRS, f16, numInputs, numInputs);
+        Type u16Matrix = Type.createXY(mRS, u16, numInputs, numInputs);
+
+        mInput = Allocation.createSized(mRS, f16, numInputs);
+        mF16Matrix = Allocation.createTyped(mRS, f16Matrix);
+        mU16Matrix = Allocation.createTyped(mRS, u16Matrix);
+
+        mInput.copyFromUnchecked(Float16TestData.input);
+    }
+
+    // Check the output of performing 'operation' on inputs x and y against the
+    // reference output in refValues.  For special cases like Infinity, NaN and
+    // zero, use exact comparison.  Otherwise, check if the output is within
+    // the bounds in 'refValues' by converting all values to float.
+    private boolean checkFloat16Output(int x, int y, short[][][] refValues,
+                                       String operation)
+    {
+        // Find the input, output and reference values based on the indices
+        short in1 = Float16TestData.input[x];
+        short in2 = Float16TestData.input[y];
+        short out = output[x + y * numInputs];
+        short lb = refValues[x][y][0];
+        short ub = refValues[x][y][1];
+
+        // Do exact match if the reference value is a special case (Nan, zero
+        // infinity or their negative equivalents).
+        if (isFloat16Infinite(lb))
+            return lb == out;
+        // NaN can have any non-zero mantissa.  Do not use equality check
+        if (isFloat16NaN(lb))
+            return 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))
+                return lb == out;
+        }
+
+        float floatLB = convertFloat16ToFloat(lb);
+        float floatUB = convertFloat16ToFloat(ub);
+        float floatOut = convertFloat16ToFloat(out);
+
+        if (floatOut < floatLB || floatOut > floatUB) {
+            StringBuilder message = new StringBuilder();
+            message.append("Incorrect output for float16 " + operation + ":");
+            message.append("\nInput 1: " + Short.toString(in1));
+            message.append("\nInput 2: " + Short.toString(in2));
+            message.append("\nExpected output between: " + Short.toString(lb) +
+                           " and " + Short.toString(ub));
+            message.append("\nActual   output: " + Short.toString(out));
+            message.append("\nExpected output (in float) between: " +
+                           Float.toString(floatLB) + " and " + Float.toString(floatUB));
+            message.append("\nActual   output: " + Float.toString(floatOut));
+            assertTrue(message.toString(), false);
+        }
+        return true;
+    }
+
+    private boolean checkFloat16Add(int x, int y) {
+        return checkFloat16Output(x, y, Float16TestData.ReferenceOutputForAdd,
+                                  "addition");
+    }
+
+    public void testFloat16Add() {
+        setupTest();
+        ScriptC_float16_arithmetic script = new ScriptC_float16_arithmetic(mRS);
+
+        script.set_gInput(mInput);
+        script.forEach_add(mF16Matrix);
+        script.forEach_bitcast(mF16Matrix, mU16Matrix);
+        mU16Matrix.copyTo(output);
+
+        for (int x = 0; x < numInputs; x ++) {
+            for (int y = 0; y < numInputs; y ++) {
+                checkFloat16Add(x, y);
+            }
+        }
+    }
+
+    private boolean checkFloat16Sub(int x, int y) {
+        return checkFloat16Output(x, y, Float16TestData.ReferenceOutputForSub,
+                                  "subtraction");
+    }
+
+    public void testFloat16Sub() {
+        setupTest();
+        ScriptC_float16_arithmetic script = new ScriptC_float16_arithmetic(mRS);
+
+        script.set_gInput(mInput);
+        script.forEach_sub(mF16Matrix);
+        script.forEach_bitcast(mF16Matrix, mU16Matrix);
+        mU16Matrix.copyTo(output);
+
+        for (int x = 0; x < numInputs; x ++) {
+            for (int y = 0; y < numInputs; y ++) {
+                checkFloat16Sub(x, y);
+            }
+        }
+    }
+
+    private boolean checkFloat16Mul(int x, int y) {
+        return checkFloat16Output(x, y, Float16TestData.ReferenceOutputForMul,
+                                  "multiplication");
+    }
+
+    public void testFloat16Mul() {
+        setupTest();
+        ScriptC_float16_arithmetic script = new ScriptC_float16_arithmetic(mRS);
+
+        script.set_gInput(mInput);
+        script.forEach_mul(mF16Matrix);
+        script.forEach_bitcast(mF16Matrix, mU16Matrix);
+        mU16Matrix.copyTo(output);
+
+        for (int x = 0; x < numInputs; x ++) {
+            for (int y = 0; y < numInputs; y ++) {
+                checkFloat16Mul(x, y);
+            }
+        }
+    }
+
+    private boolean checkFloat16Div(int x, int y) {
+        return checkFloat16Output(x, y, Float16TestData.ReferenceOutputForDiv,
+                                  "division");
+    }
+
+    public void testFloat16Div() {
+        setupTest();
+        ScriptC_float16_arithmetic script = new ScriptC_float16_arithmetic(mRS);
+
+        script.set_gInput(mInput);
+        script.forEach_div(mF16Matrix);
+        script.forEach_bitcast(mF16Matrix, mU16Matrix);
+        mU16Matrix.copyTo(output);
+
+        for (int x = 0; x < numInputs; x ++) {
+            for (int y = 0; y < numInputs; y ++) {
+                checkFloat16Div(x, y);
+            }
+        }
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Float16TestData.java b/tests/tests/renderscript/src/android/renderscript/cts/Float16TestData.java
new file mode 100644
index 0000000..f4cef49
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Float16TestData.java
@@ -0,0 +1,2037 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 float16_gen.sh */
+
+package android.renderscript.cts;
+
+public class Float16TestData {
+  static short[] input = {
+      (short) 0x3c00, // one
+      (short) 0x4000, // two
+      (short) 0x0001, // smallest subnormal
+      (short) 0x03ff, // largest subnormal
+      (short) 0x0400, // smallest normal
+      (short) 0x7bff, // largest normal
+      (short) 0x3880, // 0.562500
+      (short) 0x3e80, // 1.625000
+      (short) 0x5140, // 42.000000
+      (short) 0x5ac0, // 216.000000
+      (short) 0x6c75, // 4564.000000
+      (short) 0x7b53, // 60000.000000
+      (short) 0xbc00, // negative one
+      (short) 0xc000, // negative two
+      (short) 0x8001, // negative (smallest subnormal)
+      (short) 0x83ff, // negative (largest subnormal)
+      (short) 0x8400, // negative (smallest normal)
+      (short) 0xfbff, // negative (largest normal)
+      (short) 0xb880, // -0.562500
+      (short) 0xbe80, // -1.625000
+      (short) 0xd140, // -42.000000
+      (short) 0xdac0, // -216.000000
+      (short) 0xec75, // -4564.000000
+      (short) 0xfb53, // -60000.000000
+      (short) 0x0000, // zero
+      (short) 0x7c00, // infinity
+      (short) 0x8000, // negative zero
+      (short) 0xfc00, // negative infinity
+      (short) 0x7c01, // nan
+  };
+
+  static short[][][] ReferenceOutputForAdd = {
+      {
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x41ff, (short) 0x4201},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3bfe, (short) 0x3c01},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x3e3f, (short) 0x3e41}, {(short) 0x413f, (short) 0x4141},
+          {(short) 0x515f, (short) 0x5161}, {(short) 0x5ac7, (short) 0x5ac9},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xbc01, (short) 0xbbfe},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3bfe, (short) 0x3c01},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0x36ff, (short) 0x3701}, {(short) 0xb901, (short) 0xb8ff},
+          {(short) 0xd121, (short) 0xd11f}, {(short) 0xdab9, (short) 0xdab7},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x41ff, (short) 0x4201}, {(short) 0x43fe, (short) 0x4401},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x411f, (short) 0x4121}, {(short) 0x433f, (short) 0x4341},
+          {(short) 0x517f, (short) 0x5181}, {(short) 0x5acf, (short) 0x5ad1},
+          {(short) 0x6c75, (short) 0x6c77}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0x3dbf, (short) 0x3dc1}, {(short) 0x35ff, (short) 0x3601},
+          {(short) 0xd101, (short) 0xd0ff}, {(short) 0xdab1, (short) 0xdaaf},
+          {(short) 0xec75, (short) 0xec73}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0003}, {(short) 0x0000, (short) 0x0401},
+          {(short) 0x0400, (short) 0x0402}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x83ff, (short) 0x8000},
+          {(short) 0x8400, (short) 0x8000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x07fd, (short) 0x07ff},
+          {(short) 0x07fe, (short) 0x0800}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x0000, (short) 0x03ff}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x0000, (short) 0x0400}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x0000, (short) 0x0400}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0400, (short) 0x0402}, {(short) 0x07fe, (short) 0x0800},
+          {(short) 0x07fe, (short) 0x0801}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x0000, (short) 0x0400}, {(short) 0x0000, (short) 0x0002},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfd, (short) 0x7bff}, {(short) 0x7bf7, (short) 0x7bf9},
+          {(short) 0x7b6f, (short) 0x7b71}, {(short) 0x6d5f, (short) 0x6d61},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3e3f, (short) 0x3e41}, {(short) 0x411f, (short) 0x4121},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x387f, (short) 0x3881},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x3c7f, (short) 0x3c81}, {(short) 0x405f, (short) 0x4061},
+          {(short) 0x5151, (short) 0x5153}, {(short) 0x5ac3, (short) 0x5ac5},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xb701, (short) 0xb6ff}, {(short) 0xbdc1, (short) 0xbdbf},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x387f, (short) 0x3881},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xbc41, (short) 0xbc3f},
+          {(short) 0xd12f, (short) 0xd12d}, {(short) 0xdabd, (short) 0xdabb},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x413f, (short) 0x4141}, {(short) 0x433f, (short) 0x4341},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x405f, (short) 0x4061}, {(short) 0x427f, (short) 0x4281},
+          {(short) 0x5173, (short) 0x5175}, {(short) 0x5acc, (short) 0x5ace},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x38ff, (short) 0x3901}, {(short) 0xb601, (short) 0xb5ff},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0x3c3f, (short) 0x3c41}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xd10d, (short) 0xd10b}, {(short) 0xdab4, (short) 0xdab2},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x515f, (short) 0x5161}, {(short) 0x517f, (short) 0x5181},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x513f, (short) 0x5141},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x5151, (short) 0x5153}, {(short) 0x5173, (short) 0x5175},
+          {(short) 0x553f, (short) 0x5541}, {(short) 0x5c07, (short) 0x5c09},
+          {(short) 0x6c7f, (short) 0x6c81}, {(short) 0x7b53, (short) 0x7b55},
+          {(short) 0x511f, (short) 0x5121}, {(short) 0x50ff, (short) 0x5101},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x513f, (short) 0x5141},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0xfbff, (short) 0xfbfd},
+          {(short) 0x512d, (short) 0x512f}, {(short) 0x510b, (short) 0x510d},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xd971, (short) 0xd96f},
+          {(short) 0xec6b, (short) 0xec69}, {(short) 0xfb53, (short) 0xfb51},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x5ac7, (short) 0x5ac9}, {(short) 0x5acf, (short) 0x5ad1},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x5ac3, (short) 0x5ac5}, {(short) 0x5acc, (short) 0x5ace},
+          {(short) 0x5c07, (short) 0x5c09}, {(short) 0x5ebf, (short) 0x5ec1},
+          {(short) 0x6caa, (short) 0x6cac}, {(short) 0x7b59, (short) 0x7b5b},
+          {(short) 0x5ab7, (short) 0x5ab9}, {(short) 0x5aaf, (short) 0x5ab1},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0xfbf9, (short) 0xfbf7},
+          {(short) 0x5abb, (short) 0x5abd}, {(short) 0x5ab2, (short) 0x5ab4},
+          {(short) 0x596f, (short) 0x5971}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xec40, (short) 0xec3e}, {(short) 0xfb4d, (short) 0xfb4b},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c75, (short) 0x6c77},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c74, (short) 0x6c76},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c74, (short) 0x6c76},
+          {(short) 0x6c7f, (short) 0x6c81}, {(short) 0x6caa, (short) 0x6cac},
+          {(short) 0x7074, (short) 0x7076}, {(short) 0x7be1, (short) 0x7be3},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c73, (short) 0x6c75},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c74, (short) 0x6c76},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0xfb71, (short) 0xfb6f},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c74, (short) 0x6c76},
+          {(short) 0x6c69, (short) 0x6c6b}, {(short) 0x6c3e, (short) 0x6c40},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfac5, (short) 0xfac3},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b53, (short) 0x7b55}, {(short) 0x7b59, (short) 0x7b5b},
+          {(short) 0x7be1, (short) 0x7be3}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0xed61, (short) 0xed5f},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b51, (short) 0x7b53}, {(short) 0x7b4b, (short) 0x7b4d},
+          {(short) 0x7ac3, (short) 0x7ac5}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x3bfe, (short) 0x3c01},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xbc01, (short) 0xbbfe},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0xb701, (short) 0xb6ff}, {(short) 0x38ff, (short) 0x3901},
+          {(short) 0x511f, (short) 0x5121}, {(short) 0x5ab7, (short) 0x5ab9},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xc201, (short) 0xc1ff},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xbc01, (short) 0xbbfe},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xbe41, (short) 0xbe3f}, {(short) 0xc141, (short) 0xc13f},
+          {(short) 0xd161, (short) 0xd15f}, {(short) 0xdac9, (short) 0xdac7},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0xbdc1, (short) 0xbdbf}, {(short) 0xb601, (short) 0xb5ff},
+          {(short) 0x50ff, (short) 0x5101}, {(short) 0x5aaf, (short) 0x5ab1},
+          {(short) 0x6c73, (short) 0x6c75}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xc201, (short) 0xc1ff}, {(short) 0xc401, (short) 0xc3fe},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xc121, (short) 0xc11f}, {(short) 0xc341, (short) 0xc33f},
+          {(short) 0xd181, (short) 0xd17f}, {(short) 0xdad1, (short) 0xdacf},
+          {(short) 0xec77, (short) 0xec75}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x0000, (short) 0x03ff},
+          {(short) 0x0000, (short) 0x0400}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8003, (short) 0x8000}, {(short) 0x8401, (short) 0x8000},
+          {(short) 0x8402, (short) 0x8400}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x83ff, (short) 0x8000}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0x87ff, (short) 0x87fd},
+          {(short) 0x8800, (short) 0x87fe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x8400, (short) 0x8000}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8400, (short) 0x8000}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x8400, (short) 0x8000}, {(short) 0x8002, (short) 0x0000},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8402, (short) 0x8400}, {(short) 0x8800, (short) 0x87fe},
+          {(short) 0x8801, (short) 0x87fe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfbff, (short) 0xfbfd}, {(short) 0xfbf9, (short) 0xfbf7},
+          {(short) 0xfb71, (short) 0xfb6f}, {(short) 0xed61, (short) 0xed5f},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x36ff, (short) 0x3701}, {(short) 0x3dbf, (short) 0x3dc1},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xb881, (short) 0xb87f},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x3c3f, (short) 0x3c41},
+          {(short) 0x512d, (short) 0x512f}, {(short) 0x5abb, (short) 0x5abd},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbe41, (short) 0xbe3f}, {(short) 0xc121, (short) 0xc11f},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xb881, (short) 0xb87f},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xbc81, (short) 0xbc7f}, {(short) 0xc061, (short) 0xc05f},
+          {(short) 0xd153, (short) 0xd151}, {(short) 0xdac5, (short) 0xdac3},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xb901, (short) 0xb8ff}, {(short) 0x35ff, (short) 0x3601},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0xbc41, (short) 0xbc3f}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x510b, (short) 0x510d}, {(short) 0x5ab2, (short) 0x5ab4},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xc141, (short) 0xc13f}, {(short) 0xc341, (short) 0xc33f},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xc061, (short) 0xc05f}, {(short) 0xc281, (short) 0xc27f},
+          {(short) 0xd175, (short) 0xd173}, {(short) 0xdace, (short) 0xdacc},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xd121, (short) 0xd11f}, {(short) 0xd101, (short) 0xd0ff},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xd141, (short) 0xd13f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0x7bfd, (short) 0x7bff},
+          {(short) 0xd12f, (short) 0xd12d}, {(short) 0xd10d, (short) 0xd10b},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x596f, (short) 0x5971},
+          {(short) 0x6c69, (short) 0x6c6b}, {(short) 0x7b51, (short) 0x7b53},
+          {(short) 0xd161, (short) 0xd15f}, {(short) 0xd181, (short) 0xd17f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xd141, (short) 0xd13f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xd153, (short) 0xd151}, {(short) 0xd175, (short) 0xd173},
+          {(short) 0xd541, (short) 0xd53f}, {(short) 0xdc09, (short) 0xdc07},
+          {(short) 0xec81, (short) 0xec7f}, {(short) 0xfb55, (short) 0xfb53},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xdab9, (short) 0xdab7}, {(short) 0xdab1, (short) 0xdaaf},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0x7bf7, (short) 0x7bf9},
+          {(short) 0xdabd, (short) 0xdabb}, {(short) 0xdab4, (short) 0xdab2},
+          {(short) 0xd971, (short) 0xd96f}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x6c3e, (short) 0x6c40}, {(short) 0x7b4b, (short) 0x7b4d},
+          {(short) 0xdac9, (short) 0xdac7}, {(short) 0xdad1, (short) 0xdacf},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xdac5, (short) 0xdac3}, {(short) 0xdace, (short) 0xdacc},
+          {(short) 0xdc09, (short) 0xdc07}, {(short) 0xdec1, (short) 0xdebf},
+          {(short) 0xecac, (short) 0xecaa}, {(short) 0xfb5b, (short) 0xfb59},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec75, (short) 0xec73},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec76, (short) 0xec74},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0x7b6f, (short) 0x7b71},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec76, (short) 0xec74},
+          {(short) 0xec6b, (short) 0xec69}, {(short) 0xec40, (short) 0xec3e},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7ac3, (short) 0x7ac5},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec77, (short) 0xec75},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec76, (short) 0xec74},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec76, (short) 0xec74},
+          {(short) 0xec81, (short) 0xec7f}, {(short) 0xecac, (short) 0xecaa},
+          {(short) 0xf076, (short) 0xf074}, {(short) 0xfbe3, (short) 0xfbe1},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0x6d5f, (short) 0x6d61},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb53, (short) 0xfb51}, {(short) 0xfb4d, (short) 0xfb4b},
+          {(short) 0xfac5, (short) 0xfac3}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb55, (short) 0xfb53}, {(short) 0xfb5b, (short) 0xfb59},
+          {(short) 0xfbe3, (short) 0xfbe1}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0400},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8400, (short) 0x8000},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0400},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8400, (short) 0x8000},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+  };
+
+  static short[][][] ReferenceOutputForSub = {
+      {
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xbc01, (short) 0xbbfe},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3bfe, (short) 0x3c01},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0x36ff, (short) 0x3701}, {(short) 0xb901, (short) 0xb8ff},
+          {(short) 0xd121, (short) 0xd11f}, {(short) 0xdab9, (short) 0xdab7},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x41ff, (short) 0x4201},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3bfe, (short) 0x3c01},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x3e3f, (short) 0x3e41}, {(short) 0x413f, (short) 0x4141},
+          {(short) 0x515f, (short) 0x5161}, {(short) 0x5ac7, (short) 0x5ac9},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0x3dbf, (short) 0x3dc1}, {(short) 0x35ff, (short) 0x3601},
+          {(short) 0xd101, (short) 0xd0ff}, {(short) 0xdab1, (short) 0xdaaf},
+          {(short) 0xec75, (short) 0xec73}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x41ff, (short) 0x4201}, {(short) 0x43fe, (short) 0x4401},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x411f, (short) 0x4121}, {(short) 0x433f, (short) 0x4341},
+          {(short) 0x517f, (short) 0x5181}, {(short) 0x5acf, (short) 0x5ad1},
+          {(short) 0x6c75, (short) 0x6c77}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x83ff, (short) 0x8000},
+          {(short) 0x8400, (short) 0x8000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0003}, {(short) 0x0000, (short) 0x0401},
+          {(short) 0x0400, (short) 0x0402}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x0000, (short) 0x03ff}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x07fd, (short) 0x07ff},
+          {(short) 0x07fe, (short) 0x0800}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x0000, (short) 0x0400}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x0000, (short) 0x0400}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x0000, (short) 0x0400}, {(short) 0x0000, (short) 0x0002},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0400, (short) 0x0402}, {(short) 0x07fe, (short) 0x0800},
+          {(short) 0x07fe, (short) 0x0801}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfd, (short) 0x7bff}, {(short) 0x7bf7, (short) 0x7bf9},
+          {(short) 0x7b6f, (short) 0x7b71}, {(short) 0x6d5f, (short) 0x6d61},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xb701, (short) 0xb6ff}, {(short) 0xbdc1, (short) 0xbdbf},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x387f, (short) 0x3881},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xbc41, (short) 0xbc3f},
+          {(short) 0xd12f, (short) 0xd12d}, {(short) 0xdabd, (short) 0xdabb},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3e3f, (short) 0x3e41}, {(short) 0x411f, (short) 0x4121},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x387f, (short) 0x3881},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x3c7f, (short) 0x3c81}, {(short) 0x405f, (short) 0x4061},
+          {(short) 0x5151, (short) 0x5153}, {(short) 0x5ac3, (short) 0x5ac5},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x38ff, (short) 0x3901}, {(short) 0xb601, (short) 0xb5ff},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0x3c3f, (short) 0x3c41}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xd10d, (short) 0xd10b}, {(short) 0xdab4, (short) 0xdab2},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x413f, (short) 0x4141}, {(short) 0x433f, (short) 0x4341},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x405f, (short) 0x4061}, {(short) 0x427f, (short) 0x4281},
+          {(short) 0x5173, (short) 0x5175}, {(short) 0x5acc, (short) 0x5ace},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x511f, (short) 0x5121}, {(short) 0x50ff, (short) 0x5101},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x513f, (short) 0x5141},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0xfbff, (short) 0xfbfd},
+          {(short) 0x512d, (short) 0x512f}, {(short) 0x510b, (short) 0x510d},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xd971, (short) 0xd96f},
+          {(short) 0xec6b, (short) 0xec69}, {(short) 0xfb53, (short) 0xfb51},
+          {(short) 0x515f, (short) 0x5161}, {(short) 0x517f, (short) 0x5181},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x513f, (short) 0x5141},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x5151, (short) 0x5153}, {(short) 0x5173, (short) 0x5175},
+          {(short) 0x553f, (short) 0x5541}, {(short) 0x5c07, (short) 0x5c09},
+          {(short) 0x6c7f, (short) 0x6c81}, {(short) 0x7b53, (short) 0x7b55},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x5ab7, (short) 0x5ab9}, {(short) 0x5aaf, (short) 0x5ab1},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0xfbf9, (short) 0xfbf7},
+          {(short) 0x5abb, (short) 0x5abd}, {(short) 0x5ab2, (short) 0x5ab4},
+          {(short) 0x596f, (short) 0x5971}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xec40, (short) 0xec3e}, {(short) 0xfb4d, (short) 0xfb4b},
+          {(short) 0x5ac7, (short) 0x5ac9}, {(short) 0x5acf, (short) 0x5ad1},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x5ac3, (short) 0x5ac5}, {(short) 0x5acc, (short) 0x5ace},
+          {(short) 0x5c07, (short) 0x5c09}, {(short) 0x5ebf, (short) 0x5ec1},
+          {(short) 0x6caa, (short) 0x6cac}, {(short) 0x7b59, (short) 0x7b5b},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c73, (short) 0x6c75},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c74, (short) 0x6c76},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0xfb71, (short) 0xfb6f},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c74, (short) 0x6c76},
+          {(short) 0x6c69, (short) 0x6c6b}, {(short) 0x6c3e, (short) 0x6c40},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfac5, (short) 0xfac3},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c75, (short) 0x6c77},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c74, (short) 0x6c76},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x6c74, (short) 0x6c76},
+          {(short) 0x6c7f, (short) 0x6c81}, {(short) 0x6caa, (short) 0x6cac},
+          {(short) 0x7074, (short) 0x7076}, {(short) 0x7be1, (short) 0x7be3},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0xed61, (short) 0xed5f},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b51, (short) 0x7b53}, {(short) 0x7b4b, (short) 0x7b4d},
+          {(short) 0x7ac3, (short) 0x7ac5}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x7b53, (short) 0x7b55}, {(short) 0x7b59, (short) 0x7b5b},
+          {(short) 0x7be1, (short) 0x7be3}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xc201, (short) 0xc1ff},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xbc01, (short) 0xbbfe},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xbe41, (short) 0xbe3f}, {(short) 0xc141, (short) 0xc13f},
+          {(short) 0xd161, (short) 0xd15f}, {(short) 0xdac9, (short) 0xdac7},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x3bfe, (short) 0x3c01},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xbc01, (short) 0xbbfe},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0xb701, (short) 0xb6ff}, {(short) 0x38ff, (short) 0x3901},
+          {(short) 0x511f, (short) 0x5121}, {(short) 0x5ab7, (short) 0x5ab9},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xc201, (short) 0xc1ff}, {(short) 0xc401, (short) 0xc3fe},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xc121, (short) 0xc11f}, {(short) 0xc341, (short) 0xc33f},
+          {(short) 0xd181, (short) 0xd17f}, {(short) 0xdad1, (short) 0xdacf},
+          {(short) 0xec77, (short) 0xec75}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0xbdc1, (short) 0xbdbf}, {(short) 0xb601, (short) 0xb5ff},
+          {(short) 0x50ff, (short) 0x5101}, {(short) 0x5aaf, (short) 0x5ab1},
+          {(short) 0x6c73, (short) 0x6c75}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8003, (short) 0x8000}, {(short) 0x8401, (short) 0x8000},
+          {(short) 0x8402, (short) 0x8400}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x0000, (short) 0x03ff},
+          {(short) 0x0000, (short) 0x0400}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0x87ff, (short) 0x87fd},
+          {(short) 0x8800, (short) 0x87fe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x83ff, (short) 0x8000}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x8400, (short) 0x8000}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8400, (short) 0x8000}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8402, (short) 0x8400}, {(short) 0x8800, (short) 0x87fe},
+          {(short) 0x8801, (short) 0x87fe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x8400, (short) 0x8000}, {(short) 0x8002, (short) 0x0000},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xfbff, (short) 0xfbfd}, {(short) 0xfbf9, (short) 0xfbf7},
+          {(short) 0xfb71, (short) 0xfb6f}, {(short) 0xed61, (short) 0xed5f},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbe41, (short) 0xbe3f}, {(short) 0xc121, (short) 0xc11f},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xb881, (short) 0xb87f},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xbc81, (short) 0xbc7f}, {(short) 0xc061, (short) 0xc05f},
+          {(short) 0xd153, (short) 0xd151}, {(short) 0xdac5, (short) 0xdac3},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x36ff, (short) 0x3701}, {(short) 0x3dbf, (short) 0x3dc1},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xb881, (short) 0xb87f},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x3c3f, (short) 0x3c41},
+          {(short) 0x512d, (short) 0x512f}, {(short) 0x5abb, (short) 0x5abd},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xc141, (short) 0xc13f}, {(short) 0xc341, (short) 0xc33f},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xc061, (short) 0xc05f}, {(short) 0xc281, (short) 0xc27f},
+          {(short) 0xd175, (short) 0xd173}, {(short) 0xdace, (short) 0xdacc},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xb901, (short) 0xb8ff}, {(short) 0x35ff, (short) 0x3601},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0xbc41, (short) 0xbc3f}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x510b, (short) 0x510d}, {(short) 0x5ab2, (short) 0x5ab4},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xd161, (short) 0xd15f}, {(short) 0xd181, (short) 0xd17f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xd141, (short) 0xd13f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xd153, (short) 0xd151}, {(short) 0xd175, (short) 0xd173},
+          {(short) 0xd541, (short) 0xd53f}, {(short) 0xdc09, (short) 0xdc07},
+          {(short) 0xec81, (short) 0xec7f}, {(short) 0xfb55, (short) 0xfb53},
+          {(short) 0xd121, (short) 0xd11f}, {(short) 0xd101, (short) 0xd0ff},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xd141, (short) 0xd13f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0x7bfd, (short) 0x7bff},
+          {(short) 0xd12f, (short) 0xd12d}, {(short) 0xd10d, (short) 0xd10b},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x596f, (short) 0x5971},
+          {(short) 0x6c69, (short) 0x6c6b}, {(short) 0x7b51, (short) 0x7b53},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xdac9, (short) 0xdac7}, {(short) 0xdad1, (short) 0xdacf},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xdac5, (short) 0xdac3}, {(short) 0xdace, (short) 0xdacc},
+          {(short) 0xdc09, (short) 0xdc07}, {(short) 0xdec1, (short) 0xdebf},
+          {(short) 0xecac, (short) 0xecaa}, {(short) 0xfb5b, (short) 0xfb59},
+          {(short) 0xdab9, (short) 0xdab7}, {(short) 0xdab1, (short) 0xdaaf},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0x7bf7, (short) 0x7bf9},
+          {(short) 0xdabd, (short) 0xdabb}, {(short) 0xdab4, (short) 0xdab2},
+          {(short) 0xd971, (short) 0xd96f}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x6c3e, (short) 0x6c40}, {(short) 0x7b4b, (short) 0x7b4d},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec77, (short) 0xec75},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec76, (short) 0xec74},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec76, (short) 0xec74},
+          {(short) 0xec81, (short) 0xec7f}, {(short) 0xecac, (short) 0xecaa},
+          {(short) 0xf076, (short) 0xf074}, {(short) 0xfbe3, (short) 0xfbe1},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec75, (short) 0xec73},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec76, (short) 0xec74},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0x7b6f, (short) 0x7b71},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xec76, (short) 0xec74},
+          {(short) 0xec6b, (short) 0xec69}, {(short) 0xec40, (short) 0xec3e},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7ac3, (short) 0x7ac5},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb55, (short) 0xfb53}, {(short) 0xfb5b, (short) 0xfb59},
+          {(short) 0xfbe3, (short) 0xfbe1}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0x6d5f, (short) 0x6d61},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0xfb53, (short) 0xfb51}, {(short) 0xfb4d, (short) 0xfb4b},
+          {(short) 0xfac5, (short) 0xfac3}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8400, (short) 0x8000},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0400},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8400, (short) 0x8000},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0400},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+  };
+
+  static short[][][] ReferenceOutputForMul = {
+      {
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0400},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8400, (short) 0x8000},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x43fe, (short) 0x4401},
+          {(short) 0x0000, (short) 0x0003}, {(short) 0x07fd, (short) 0x07ff},
+          {(short) 0x07fe, (short) 0x0801}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x3c7f, (short) 0x3c81}, {(short) 0x427f, (short) 0x4281},
+          {(short) 0x553f, (short) 0x5541}, {(short) 0x5ebf, (short) 0x5ec1},
+          {(short) 0x7074, (short) 0x7076}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xc401, (short) 0xc3fe},
+          {(short) 0x8003, (short) 0x8000}, {(short) 0x87ff, (short) 0x87fd},
+          {(short) 0x8801, (short) 0x87fe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xbc81, (short) 0xbc7f}, {(short) 0xc281, (short) 0xc27f},
+          {(short) 0xd541, (short) 0xd53f}, {(short) 0xdec1, (short) 0xdebf},
+          {(short) 0xf076, (short) 0xf074}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0003},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x1bfe, (short) 0x1c00},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0003},
+          {(short) 0x0000, (short) 0x002b}, {(short) 0x0000, (short) 0x00d9},
+          {(short) 0x0c74, (short) 0x0c76}, {(short) 0x1b52, (short) 0x1b54},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8003, (short) 0x8000},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x9c00, (short) 0x9bfe},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8003, (short) 0x8000},
+          {(short) 0x802b, (short) 0x8000}, {(short) 0x80d9, (short) 0x8000},
+          {(short) 0x8c76, (short) 0x8c74}, {(short) 0x9b54, (short) 0x9b52},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x0000, (short) 0x0400}, {(short) 0x07fd, (short) 0x07ff},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x43fc, (short) 0x43fe},
+          {(short) 0x0000, (short) 0x0240}, {(short) 0x067d, (short) 0x067f},
+          {(short) 0x193e, (short) 0x1940}, {(short) 0x22bd, (short) 0x22bf},
+          {(short) 0x3473, (short) 0x3475}, {(short) 0x4350, (short) 0x4352},
+          {(short) 0x8400, (short) 0x8000}, {(short) 0x87ff, (short) 0x87fd},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xc3fe, (short) 0xc3fc},
+          {(short) 0x8240, (short) 0x8000}, {(short) 0x867f, (short) 0x867d},
+          {(short) 0x9940, (short) 0x993e}, {(short) 0xa2bf, (short) 0xa2bd},
+          {(short) 0xb475, (short) 0xb473}, {(short) 0xc352, (short) 0xc350},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x07fe, (short) 0x0801},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x43fe, (short) 0x4400},
+          {(short) 0x0000, (short) 0x0241}, {(short) 0x067f, (short) 0x0681},
+          {(short) 0x193f, (short) 0x1941}, {(short) 0x22bf, (short) 0x22c1},
+          {(short) 0x3474, (short) 0x3476}, {(short) 0x4352, (short) 0x4354},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0x8801, (short) 0x87fe},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xc400, (short) 0xc3fe},
+          {(short) 0x8241, (short) 0x8000}, {(short) 0x8681, (short) 0x867f},
+          {(short) 0x9941, (short) 0x993f}, {(short) 0xa2c1, (short) 0xa2bf},
+          {(short) 0xb476, (short) 0xb474}, {(short) 0xc354, (short) 0xc352},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x1bfe, (short) 0x1c00}, {(short) 0x43fc, (short) 0x43fe},
+          {(short) 0x43fe, (short) 0x4400}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x787e, (short) 0x7880}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x9c00, (short) 0x9bfe}, {(short) 0xc3fe, (short) 0xc3fc},
+          {(short) 0xc400, (short) 0xc3fe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xf880, (short) 0xf87e}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3c7f, (short) 0x3c81},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0240},
+          {(short) 0x0000, (short) 0x0241}, {(short) 0x787e, (short) 0x7880},
+          {(short) 0x350f, (short) 0x3511}, {(short) 0x3b4f, (short) 0x3b51},
+          {(short) 0x4de7, (short) 0x4de9}, {(short) 0x5797, (short) 0x5799},
+          {(short) 0x6903, (short) 0x6905}, {(short) 0x781e, (short) 0x7820},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbc81, (short) 0xbc7f},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8240, (short) 0x8000},
+          {(short) 0x8241, (short) 0x8000}, {(short) 0xf880, (short) 0xf87e},
+          {(short) 0xb511, (short) 0xb50f}, {(short) 0xbb51, (short) 0xbb4f},
+          {(short) 0xcde9, (short) 0xcde7}, {(short) 0xd799, (short) 0xd797},
+          {(short) 0xe905, (short) 0xe903}, {(short) 0xf820, (short) 0xf81e},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x427f, (short) 0x4281},
+          {(short) 0x0000, (short) 0x0003}, {(short) 0x067d, (short) 0x067f},
+          {(short) 0x067f, (short) 0x0681}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x3b4f, (short) 0x3b51}, {(short) 0x4147, (short) 0x4149},
+          {(short) 0x5443, (short) 0x5445}, {(short) 0x5d7b, (short) 0x5d7d},
+          {(short) 0x6f3d, (short) 0x6f3f}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xc281, (short) 0xc27f},
+          {(short) 0x8003, (short) 0x8000}, {(short) 0x867f, (short) 0x867d},
+          {(short) 0x8681, (short) 0x867f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xbb51, (short) 0xbb4f}, {(short) 0xc149, (short) 0xc147},
+          {(short) 0xd445, (short) 0xd443}, {(short) 0xdd7d, (short) 0xdd7b},
+          {(short) 0xef3f, (short) 0xef3d}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x553f, (short) 0x5541},
+          {(short) 0x0000, (short) 0x002b}, {(short) 0x193e, (short) 0x1940},
+          {(short) 0x193f, (short) 0x1941}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x4de7, (short) 0x4de9}, {(short) 0x5443, (short) 0x5445},
+          {(short) 0x66e3, (short) 0x66e5}, {(short) 0x706d, (short) 0x706f},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xd541, (short) 0xd53f},
+          {(short) 0x802b, (short) 0x8000}, {(short) 0x9940, (short) 0x993e},
+          {(short) 0x9941, (short) 0x993f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xcde9, (short) 0xcde7}, {(short) 0xd445, (short) 0xd443},
+          {(short) 0xe6e5, (short) 0xe6e3}, {(short) 0xf06f, (short) 0xf06d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x5ebf, (short) 0x5ec1},
+          {(short) 0x0000, (short) 0x00d9}, {(short) 0x22bd, (short) 0x22bf},
+          {(short) 0x22bf, (short) 0x22c1}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x5797, (short) 0x5799}, {(short) 0x5d7b, (short) 0x5d7d},
+          {(short) 0x706d, (short) 0x706f}, {(short) 0x79b1, (short) 0x79b3},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xdec1, (short) 0xdebf},
+          {(short) 0x80d9, (short) 0x8000}, {(short) 0xa2bf, (short) 0xa2bd},
+          {(short) 0xa2c1, (short) 0xa2bf}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xd799, (short) 0xd797}, {(short) 0xdd7d, (short) 0xdd7b},
+          {(short) 0xf06f, (short) 0xf06d}, {(short) 0xf9b3, (short) 0xf9b1},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7074, (short) 0x7076},
+          {(short) 0x0c74, (short) 0x0c76}, {(short) 0x3473, (short) 0x3475},
+          {(short) 0x3474, (short) 0x3476}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x6903, (short) 0x6905}, {(short) 0x6f3d, (short) 0x6f3f},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xf076, (short) 0xf074},
+          {(short) 0x8c76, (short) 0x8c74}, {(short) 0xb475, (short) 0xb473},
+          {(short) 0xb476, (short) 0xb474}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xe905, (short) 0xe903}, {(short) 0xef3f, (short) 0xef3d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x1b52, (short) 0x1b54}, {(short) 0x4350, (short) 0x4352},
+          {(short) 0x4352, (short) 0x4354}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x781e, (short) 0x7820}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x9b54, (short) 0x9b52}, {(short) 0xc352, (short) 0xc350},
+          {(short) 0xc354, (short) 0xc352}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xf820, (short) 0xf81e}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc01, (short) 0xbbfe}, {(short) 0xc001, (short) 0xbffe},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8400, (short) 0x8000},
+          {(short) 0x8401, (short) 0x8000}, {(short) 0xfc00, (short) 0xfbfe},
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbe81, (short) 0xbe7f},
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xdac1, (short) 0xdabf},
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xfb54, (short) 0xfb52},
+          {(short) 0x3bfe, (short) 0x3c01}, {(short) 0x3ffe, (short) 0x4001},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0400},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x7bfe, (short) 0x7c00},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3e7f, (short) 0x3e81},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x5abf, (short) 0x5ac1},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7b52, (short) 0x7b54},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xc001, (short) 0xbffe}, {(short) 0xc401, (short) 0xc3fe},
+          {(short) 0x8003, (short) 0x8000}, {(short) 0x87ff, (short) 0x87fd},
+          {(short) 0x8801, (short) 0x87fe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xbc81, (short) 0xbc7f}, {(short) 0xc281, (short) 0xc27f},
+          {(short) 0xd541, (short) 0xd53f}, {(short) 0xdec1, (short) 0xdebf},
+          {(short) 0xf076, (short) 0xf074}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x3ffe, (short) 0x4001}, {(short) 0x43fe, (short) 0x4401},
+          {(short) 0x0000, (short) 0x0003}, {(short) 0x07fd, (short) 0x07ff},
+          {(short) 0x07fe, (short) 0x0801}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x3c7f, (short) 0x3c81}, {(short) 0x427f, (short) 0x4281},
+          {(short) 0x553f, (short) 0x5541}, {(short) 0x5ebf, (short) 0x5ec1},
+          {(short) 0x7074, (short) 0x7076}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8003, (short) 0x8000},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x9c00, (short) 0x9bfe},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8003, (short) 0x8000},
+          {(short) 0x802b, (short) 0x8000}, {(short) 0x80d9, (short) 0x8000},
+          {(short) 0x8c76, (short) 0x8c74}, {(short) 0x9b54, (short) 0x9b52},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0003},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x1bfe, (short) 0x1c00},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0003},
+          {(short) 0x0000, (short) 0x002b}, {(short) 0x0000, (short) 0x00d9},
+          {(short) 0x0c74, (short) 0x0c76}, {(short) 0x1b52, (short) 0x1b54},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8400, (short) 0x8000}, {(short) 0x87ff, (short) 0x87fd},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xc3fe, (short) 0xc3fc},
+          {(short) 0x8240, (short) 0x8000}, {(short) 0x867f, (short) 0x867d},
+          {(short) 0x9940, (short) 0x993e}, {(short) 0xa2bf, (short) 0xa2bd},
+          {(short) 0xb475, (short) 0xb473}, {(short) 0xc352, (short) 0xc350},
+          {(short) 0x0000, (short) 0x0400}, {(short) 0x07fd, (short) 0x07ff},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x43fc, (short) 0x43fe},
+          {(short) 0x0000, (short) 0x0240}, {(short) 0x067d, (short) 0x067f},
+          {(short) 0x193e, (short) 0x1940}, {(short) 0x22bd, (short) 0x22bf},
+          {(short) 0x3473, (short) 0x3475}, {(short) 0x4350, (short) 0x4352},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8401, (short) 0x8000}, {(short) 0x8801, (short) 0x87fe},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xc400, (short) 0xc3fe},
+          {(short) 0x8241, (short) 0x8000}, {(short) 0x8681, (short) 0x867f},
+          {(short) 0x9941, (short) 0x993f}, {(short) 0xa2c1, (short) 0xa2bf},
+          {(short) 0xb476, (short) 0xb474}, {(short) 0xc354, (short) 0xc352},
+          {(short) 0x0000, (short) 0x0401}, {(short) 0x07fe, (short) 0x0801},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x43fe, (short) 0x4400},
+          {(short) 0x0000, (short) 0x0241}, {(short) 0x067f, (short) 0x0681},
+          {(short) 0x193f, (short) 0x1941}, {(short) 0x22bf, (short) 0x22c1},
+          {(short) 0x3474, (short) 0x3476}, {(short) 0x4352, (short) 0x4354},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfc00, (short) 0xfbfe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x9c00, (short) 0x9bfe}, {(short) 0xc3fe, (short) 0xc3fc},
+          {(short) 0xc400, (short) 0xc3fe}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xf880, (short) 0xf87e}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7bfe, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x1bfe, (short) 0x1c00}, {(short) 0x43fc, (short) 0x43fe},
+          {(short) 0x43fe, (short) 0x4400}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x787e, (short) 0x7880}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xb881, (short) 0xb87f}, {(short) 0xbc81, (short) 0xbc7f},
+          {(short) 0x8002, (short) 0x0000}, {(short) 0x8240, (short) 0x8000},
+          {(short) 0x8241, (short) 0x8000}, {(short) 0xf880, (short) 0xf87e},
+          {(short) 0xb511, (short) 0xb50f}, {(short) 0xbb51, (short) 0xbb4f},
+          {(short) 0xcde9, (short) 0xcde7}, {(short) 0xd799, (short) 0xd797},
+          {(short) 0xe905, (short) 0xe903}, {(short) 0xf820, (short) 0xf81e},
+          {(short) 0x387f, (short) 0x3881}, {(short) 0x3c7f, (short) 0x3c81},
+          {(short) 0x0000, (short) 0x0002}, {(short) 0x0000, (short) 0x0240},
+          {(short) 0x0000, (short) 0x0241}, {(short) 0x787e, (short) 0x7880},
+          {(short) 0x350f, (short) 0x3511}, {(short) 0x3b4f, (short) 0x3b51},
+          {(short) 0x4de7, (short) 0x4de9}, {(short) 0x5797, (short) 0x5799},
+          {(short) 0x6903, (short) 0x6905}, {(short) 0x781e, (short) 0x7820},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbe81, (short) 0xbe7f}, {(short) 0xc281, (short) 0xc27f},
+          {(short) 0x8003, (short) 0x8000}, {(short) 0x867f, (short) 0x867d},
+          {(short) 0x8681, (short) 0x867f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xbb51, (short) 0xbb4f}, {(short) 0xc149, (short) 0xc147},
+          {(short) 0xd445, (short) 0xd443}, {(short) 0xdd7d, (short) 0xdd7b},
+          {(short) 0xef3f, (short) 0xef3d}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x3e7f, (short) 0x3e81}, {(short) 0x427f, (short) 0x4281},
+          {(short) 0x0000, (short) 0x0003}, {(short) 0x067d, (short) 0x067f},
+          {(short) 0x067f, (short) 0x0681}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x3b4f, (short) 0x3b51}, {(short) 0x4147, (short) 0x4149},
+          {(short) 0x5443, (short) 0x5445}, {(short) 0x5d7b, (short) 0x5d7d},
+          {(short) 0x6f3d, (short) 0x6f3f}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xd141, (short) 0xd13f}, {(short) 0xd541, (short) 0xd53f},
+          {(short) 0x802b, (short) 0x8000}, {(short) 0x9940, (short) 0x993e},
+          {(short) 0x9941, (short) 0x993f}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xcde9, (short) 0xcde7}, {(short) 0xd445, (short) 0xd443},
+          {(short) 0xe6e5, (short) 0xe6e3}, {(short) 0xf06f, (short) 0xf06d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x513f, (short) 0x5141}, {(short) 0x553f, (short) 0x5541},
+          {(short) 0x0000, (short) 0x002b}, {(short) 0x193e, (short) 0x1940},
+          {(short) 0x193f, (short) 0x1941}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x4de7, (short) 0x4de9}, {(short) 0x5443, (short) 0x5445},
+          {(short) 0x66e3, (short) 0x66e5}, {(short) 0x706d, (short) 0x706f},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xdac1, (short) 0xdabf}, {(short) 0xdec1, (short) 0xdebf},
+          {(short) 0x80d9, (short) 0x8000}, {(short) 0xa2bf, (short) 0xa2bd},
+          {(short) 0xa2c1, (short) 0xa2bf}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xd799, (short) 0xd797}, {(short) 0xdd7d, (short) 0xdd7b},
+          {(short) 0xf06f, (short) 0xf06d}, {(short) 0xf9b3, (short) 0xf9b1},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x5abf, (short) 0x5ac1}, {(short) 0x5ebf, (short) 0x5ec1},
+          {(short) 0x0000, (short) 0x00d9}, {(short) 0x22bd, (short) 0x22bf},
+          {(short) 0x22bf, (short) 0x22c1}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x5797, (short) 0x5799}, {(short) 0x5d7b, (short) 0x5d7d},
+          {(short) 0x706d, (short) 0x706f}, {(short) 0x79b1, (short) 0x79b3},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xec76, (short) 0xec74}, {(short) 0xf076, (short) 0xf074},
+          {(short) 0x8c76, (short) 0x8c74}, {(short) 0xb475, (short) 0xb473},
+          {(short) 0xb476, (short) 0xb474}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xe905, (short) 0xe903}, {(short) 0xef3f, (short) 0xef3d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x6c74, (short) 0x6c76}, {(short) 0x7074, (short) 0x7076},
+          {(short) 0x0c74, (short) 0x0c76}, {(short) 0x3473, (short) 0x3475},
+          {(short) 0x3474, (short) 0x3476}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x6903, (short) 0x6905}, {(short) 0x6f3d, (short) 0x6f3f},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfb54, (short) 0xfb52}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x9b54, (short) 0x9b52}, {(short) 0xc352, (short) 0xc350},
+          {(short) 0xc354, (short) 0xc352}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xf820, (short) 0xf81e}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7b52, (short) 0x7b54}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x1b52, (short) 0x1b54}, {(short) 0x4350, (short) 0x4352},
+          {(short) 0x4352, (short) 0x4354}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x781e, (short) 0x7820}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfe00, (short) 0xfe00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xfe00, (short) 0xfe00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0x8001, (short) 0x0001},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x8001, (short) 0x0001}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xfe00, (short) 0xfe00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfe00, (short) 0xfe00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+  };
+
+  static short[][][] ReferenceOutputForDiv = {
+      {
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x37fa, (short) 0x3803},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x73fc, (short) 0x7404},
+          {(short) 0x73fa, (short) 0x7403}, {(short) 0x0000, (short) 0x0103},
+          {(short) 0x3f19, (short) 0x3f1f}, {(short) 0x38e9, (short) 0x38ef},
+          {(short) 0x2615, (short) 0x261b}, {(short) 0x1cbb, (short) 0x1cc1},
+          {(short) 0x0b2b, (short) 0x0b31}, {(short) 0x0000, (short) 0x011b},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0xb803, (short) 0xb7fa},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf404, (short) 0xf3fc},
+          {(short) 0xf403, (short) 0xf3fa}, {(short) 0x8103, (short) 0x8000},
+          {(short) 0xbf1f, (short) 0xbf19}, {(short) 0xb8ef, (short) 0xb8e9},
+          {(short) 0xa61b, (short) 0xa615}, {(short) 0x9cc1, (short) 0x9cbb},
+          {(short) 0x8b31, (short) 0x8b2b}, {(short) 0x811b, (short) 0x8000},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3ffa, (short) 0x4003}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x77fc, (short) 0x7804},
+          {(short) 0x77fa, (short) 0x7803}, {(short) 0x0000, (short) 0x0203},
+          {(short) 0x4319, (short) 0x431f}, {(short) 0x3ce9, (short) 0x3cef},
+          {(short) 0x2a15, (short) 0x2a1b}, {(short) 0x20bb, (short) 0x20c1},
+          {(short) 0x0f2b, (short) 0x0f31}, {(short) 0x0000, (short) 0x0232},
+          {(short) 0xc003, (short) 0xbffa}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf804, (short) 0xf7fc},
+          {(short) 0xf803, (short) 0xf7fa}, {(short) 0x8203, (short) 0x8000},
+          {(short) 0xc31f, (short) 0xc319}, {(short) 0xbcef, (short) 0xbce9},
+          {(short) 0xaa1b, (short) 0xaa15}, {(short) 0xa0c1, (short) 0xa0bb},
+          {(short) 0x8f31, (short) 0x8f2b}, {(short) 0x8232, (short) 0x8000},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8002, (short) 0x0004}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x13fc, (short) 0x1404},
+          {(short) 0x13fa, (short) 0x1403}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8001, (short) 0x0005}, {(short) 0x8002, (short) 0x0004},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8004, (short) 0x0002}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0x9404, (short) 0x93fc},
+          {(short) 0x9403, (short) 0x93fa}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8005, (short) 0x0001}, {(short) 0x8004, (short) 0x0002},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x0000, (short) 0x0402}, {(short) 0x0000, (short) 0x0203},
+          {(short) 0x63fb, (short) 0x6400}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x3bfb, (short) 0x3c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x0718, (short) 0x071e}, {(short) 0x0000, (short) 0x0279},
+          {(short) 0x0000, (short) 0x001b}, {(short) 0x0000, (short) 0x0008},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8402, (short) 0x8000}, {(short) 0x8203, (short) 0x8000},
+          {(short) 0xe400, (short) 0xe3fb}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xbc00, (short) 0xbbfb}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x871e, (short) 0x8718}, {(short) 0x8279, (short) 0x8000},
+          {(short) 0x801b, (short) 0x8000}, {(short) 0x8008, (short) 0x8000},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x0000, (short) 0x0403}, {(short) 0x0000, (short) 0x0203},
+          {(short) 0x63fa, (short) 0x6403}, {(short) 0x3bfc, (short) 0x3c04},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x0719, (short) 0x071f}, {(short) 0x0000, (short) 0x0279},
+          {(short) 0x0000, (short) 0x001b}, {(short) 0x0000, (short) 0x0008},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8403, (short) 0x8000}, {(short) 0x8203, (short) 0x8000},
+          {(short) 0xe403, (short) 0xe3fa}, {(short) 0xbc04, (short) 0xbbfc},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x871f, (short) 0x8719}, {(short) 0x8279, (short) 0x8000},
+          {(short) 0x801b, (short) 0x8000}, {(short) 0x8008, (short) 0x8000},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7bfc, (short) 0x7c00}, {(short) 0x77fc, (short) 0x7801},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x78e9, (short) 0x78ef},
+          {(short) 0x6615, (short) 0x661b}, {(short) 0x5cba, (short) 0x5cc0},
+          {(short) 0x4b2a, (short) 0x4b30}, {(short) 0x3c5b, (short) 0x3c61},
+          {(short) 0xfc00, (short) 0xfbfc}, {(short) 0xf801, (short) 0xf7fc},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf8ef, (short) 0xf8e9},
+          {(short) 0xe61b, (short) 0xe615}, {(short) 0xdcc0, (short) 0xdcba},
+          {(short) 0xcb30, (short) 0xcb2a}, {(short) 0xbc61, (short) 0xbc5b},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x387d, (short) 0x3883}, {(short) 0x347d, (short) 0x3483},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x707e, (short) 0x7084},
+          {(short) 0x707d, (short) 0x7083}, {(short) 0x0000, (short) 0x0093},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x3587, (short) 0x358d},
+          {(short) 0x22d8, (short) 0x22de}, {(short) 0x1952, (short) 0x1958},
+          {(short) 0x0807, (short) 0x080d}, {(short) 0x0000, (short) 0x00a0},
+          {(short) 0xb883, (short) 0xb87d}, {(short) 0xb483, (short) 0xb47d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf084, (short) 0xf07e},
+          {(short) 0xf083, (short) 0xf07d}, {(short) 0x8093, (short) 0x8000},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0xb58d, (short) 0xb587},
+          {(short) 0xa2de, (short) 0xa2d8}, {(short) 0x9958, (short) 0x9952},
+          {(short) 0x880d, (short) 0x8807}, {(short) 0x80a0, (short) 0x8000},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x3e7d, (short) 0x3e83}, {(short) 0x3a7d, (short) 0x3a83},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x767f, (short) 0x7685},
+          {(short) 0x767d, (short) 0x7683}, {(short) 0x0000, (short) 0x01a3},
+          {(short) 0x41c4, (short) 0x41ca}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x28f1, (short) 0x28f7}, {(short) 0x1fb1, (short) 0x1fb7},
+          {(short) 0x0dd2, (short) 0x0dd8}, {(short) 0x0000, (short) 0x01c9},
+          {(short) 0xbe83, (short) 0xbe7d}, {(short) 0xba83, (short) 0xba7d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf685, (short) 0xf67f},
+          {(short) 0xf683, (short) 0xf67d}, {(short) 0x81a3, (short) 0x8000},
+          {(short) 0xc1ca, (short) 0xc1c4}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xa8f7, (short) 0xa8f1}, {(short) 0x9fb7, (short) 0x9fb1},
+          {(short) 0x8dd8, (short) 0x8dd2}, {(short) 0x81c9, (short) 0x8000},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x513d, (short) 0x5143}, {(short) 0x4d3d, (short) 0x4d43},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x113e, (short) 0x1144},
+          {(short) 0x54a8, (short) 0x54ae}, {(short) 0x4e73, (short) 0x4e79},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x3236, (short) 0x323c},
+          {(short) 0x20b3, (short) 0x20b9}, {(short) 0x11b9, (short) 0x11bf},
+          {(short) 0xd143, (short) 0xd13d}, {(short) 0xcd43, (short) 0xcd3d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x9144, (short) 0x913e},
+          {(short) 0xd4ae, (short) 0xd4a8}, {(short) 0xce79, (short) 0xce73},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0xb23c, (short) 0xb236},
+          {(short) 0xa0b9, (short) 0xa0b3}, {(short) 0x91bf, (short) 0x91b9},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x5abd, (short) 0x5ac3}, {(short) 0x56bd, (short) 0x56c3},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x1abe, (short) 0x1ac4},
+          {(short) 0x5dfd, (short) 0x5e03}, {(short) 0x5824, (short) 0x582a},
+          {(short) 0x4522, (short) 0x4528}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x2a0c, (short) 0x2a12}, {(short) 0x1b5c, (short) 0x1b62},
+          {(short) 0xdac3, (short) 0xdabd}, {(short) 0xd6c3, (short) 0xd6bd},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x9ac4, (short) 0x9abe},
+          {(short) 0xde03, (short) 0xddfd}, {(short) 0xd82a, (short) 0xd824},
+          {(short) 0xc528, (short) 0xc522}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xaa12, (short) 0xaa0c}, {(short) 0x9b62, (short) 0x9b5c},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x6c72, (short) 0x6c78}, {(short) 0x6872, (short) 0x6878},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x2c73, (short) 0x2c79},
+          {(short) 0x6fe9, (short) 0x6fef}, {(short) 0x6979, (short) 0x697f},
+          {(short) 0x56c8, (short) 0x56ce}, {(short) 0x4d45, (short) 0x4d4b},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x2cdb, (short) 0x2ce1},
+          {(short) 0xec78, (short) 0xec72}, {(short) 0xe878, (short) 0xe872},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xac79, (short) 0xac73},
+          {(short) 0xefef, (short) 0xefe9}, {(short) 0xe97f, (short) 0xe979},
+          {(short) 0xd6ce, (short) 0xd6c8}, {(short) 0xcd4b, (short) 0xcd45},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0xace1, (short) 0xacdb},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7b50, (short) 0x7b56}, {(short) 0x7750, (short) 0x7756},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x3b51, (short) 0x3b57},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x787f, (short) 0x7885},
+          {(short) 0x6592, (short) 0x6598}, {(short) 0x5c54, (short) 0x5c5a},
+          {(short) 0x4a90, (short) 0x4a96}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0xfb56, (short) 0xfb50}, {(short) 0xf756, (short) 0xf750},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xbb57, (short) 0xbb51},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf885, (short) 0xf87f},
+          {(short) 0xe598, (short) 0xe592}, {(short) 0xdc5a, (short) 0xdc54},
+          {(short) 0xca96, (short) 0xca90}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0xb803, (short) 0xb7fa},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf404, (short) 0xf3fc},
+          {(short) 0xf403, (short) 0xf3fa}, {(short) 0x8103, (short) 0x8000},
+          {(short) 0xbf1f, (short) 0xbf19}, {(short) 0xb8ef, (short) 0xb8e9},
+          {(short) 0xa61b, (short) 0xa615}, {(short) 0x9cc1, (short) 0x9cbb},
+          {(short) 0x8b31, (short) 0x8b2b}, {(short) 0x811b, (short) 0x8000},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x37fa, (short) 0x3803},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x73fc, (short) 0x7404},
+          {(short) 0x73fa, (short) 0x7403}, {(short) 0x0000, (short) 0x0103},
+          {(short) 0x3f19, (short) 0x3f1f}, {(short) 0x38e9, (short) 0x38ef},
+          {(short) 0x2615, (short) 0x261b}, {(short) 0x1cbb, (short) 0x1cc1},
+          {(short) 0x0b2b, (short) 0x0b31}, {(short) 0x0000, (short) 0x011b},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xc003, (short) 0xbffa}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf804, (short) 0xf7fc},
+          {(short) 0xf803, (short) 0xf7fa}, {(short) 0x8203, (short) 0x8000},
+          {(short) 0xc31f, (short) 0xc319}, {(short) 0xbcef, (short) 0xbce9},
+          {(short) 0xaa1b, (short) 0xaa15}, {(short) 0xa0c1, (short) 0xa0bb},
+          {(short) 0x8f31, (short) 0x8f2b}, {(short) 0x8232, (short) 0x8000},
+          {(short) 0x3ffa, (short) 0x4003}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x77fc, (short) 0x7804},
+          {(short) 0x77fa, (short) 0x7803}, {(short) 0x0000, (short) 0x0203},
+          {(short) 0x4319, (short) 0x431f}, {(short) 0x3ce9, (short) 0x3cef},
+          {(short) 0x2a15, (short) 0x2a1b}, {(short) 0x20bb, (short) 0x20c1},
+          {(short) 0x0f2b, (short) 0x0f31}, {(short) 0x0000, (short) 0x0232},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8004, (short) 0x0002}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0x9404, (short) 0x93fc},
+          {(short) 0x9403, (short) 0x93fa}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8005, (short) 0x0001}, {(short) 0x8004, (short) 0x0002},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8002, (short) 0x0004}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x13fc, (short) 0x1404},
+          {(short) 0x13fa, (short) 0x1403}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8001, (short) 0x0005}, {(short) 0x8002, (short) 0x0004},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8402, (short) 0x8000}, {(short) 0x8203, (short) 0x8000},
+          {(short) 0xe400, (short) 0xe3fb}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xbc00, (short) 0xbbfb}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x871e, (short) 0x8718}, {(short) 0x8279, (short) 0x8000},
+          {(short) 0x801b, (short) 0x8000}, {(short) 0x8008, (short) 0x8000},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x0000, (short) 0x0402}, {(short) 0x0000, (short) 0x0203},
+          {(short) 0x63fb, (short) 0x6400}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x3bfb, (short) 0x3c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x0718, (short) 0x071e}, {(short) 0x0000, (short) 0x0279},
+          {(short) 0x0000, (short) 0x001b}, {(short) 0x0000, (short) 0x0008},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8403, (short) 0x8000}, {(short) 0x8203, (short) 0x8000},
+          {(short) 0xe403, (short) 0xe3fa}, {(short) 0xbc04, (short) 0xbbfc},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x871f, (short) 0x8719}, {(short) 0x8279, (short) 0x8000},
+          {(short) 0x801b, (short) 0x8000}, {(short) 0x8008, (short) 0x8000},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x0000, (short) 0x0403}, {(short) 0x0000, (short) 0x0203},
+          {(short) 0x63fa, (short) 0x6403}, {(short) 0x3bfc, (short) 0x3c04},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x0719, (short) 0x071f}, {(short) 0x0000, (short) 0x0279},
+          {(short) 0x0000, (short) 0x001b}, {(short) 0x0000, (short) 0x0008},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfc00, (short) 0xfbfc}, {(short) 0xf801, (short) 0xf7fc},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf8ef, (short) 0xf8e9},
+          {(short) 0xe61b, (short) 0xe615}, {(short) 0xdcc0, (short) 0xdcba},
+          {(short) 0xcb30, (short) 0xcb2a}, {(short) 0xbc61, (short) 0xbc5b},
+          {(short) 0x7bfc, (short) 0x7c00}, {(short) 0x77fc, (short) 0x7801},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x78e9, (short) 0x78ef},
+          {(short) 0x6615, (short) 0x661b}, {(short) 0x5cba, (short) 0x5cc0},
+          {(short) 0x4b2a, (short) 0x4b30}, {(short) 0x3c5b, (short) 0x3c61},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xb883, (short) 0xb87d}, {(short) 0xb483, (short) 0xb47d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf084, (short) 0xf07e},
+          {(short) 0xf083, (short) 0xf07d}, {(short) 0x8093, (short) 0x8000},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0xb58d, (short) 0xb587},
+          {(short) 0xa2de, (short) 0xa2d8}, {(short) 0x9958, (short) 0x9952},
+          {(short) 0x880d, (short) 0x8807}, {(short) 0x80a0, (short) 0x8000},
+          {(short) 0x387d, (short) 0x3883}, {(short) 0x347d, (short) 0x3483},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x707e, (short) 0x7084},
+          {(short) 0x707d, (short) 0x7083}, {(short) 0x0000, (short) 0x0093},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x3587, (short) 0x358d},
+          {(short) 0x22d8, (short) 0x22de}, {(short) 0x1952, (short) 0x1958},
+          {(short) 0x0807, (short) 0x080d}, {(short) 0x0000, (short) 0x00a0},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xbe83, (short) 0xbe7d}, {(short) 0xba83, (short) 0xba7d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf685, (short) 0xf67f},
+          {(short) 0xf683, (short) 0xf67d}, {(short) 0x81a3, (short) 0x8000},
+          {(short) 0xc1ca, (short) 0xc1c4}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xa8f7, (short) 0xa8f1}, {(short) 0x9fb7, (short) 0x9fb1},
+          {(short) 0x8dd8, (short) 0x8dd2}, {(short) 0x81c9, (short) 0x8000},
+          {(short) 0x3e7d, (short) 0x3e83}, {(short) 0x3a7d, (short) 0x3a83},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x767f, (short) 0x7685},
+          {(short) 0x767d, (short) 0x7683}, {(short) 0x0000, (short) 0x01a3},
+          {(short) 0x41c4, (short) 0x41ca}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x28f1, (short) 0x28f7}, {(short) 0x1fb1, (short) 0x1fb7},
+          {(short) 0x0dd2, (short) 0x0dd8}, {(short) 0x0000, (short) 0x01c9},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xd143, (short) 0xd13d}, {(short) 0xcd43, (short) 0xcd3d},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x9144, (short) 0x913e},
+          {(short) 0xd4ae, (short) 0xd4a8}, {(short) 0xce79, (short) 0xce73},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0xb23c, (short) 0xb236},
+          {(short) 0xa0b9, (short) 0xa0b3}, {(short) 0x91bf, (short) 0x91b9},
+          {(short) 0x513d, (short) 0x5143}, {(short) 0x4d3d, (short) 0x4d43},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x113e, (short) 0x1144},
+          {(short) 0x54a8, (short) 0x54ae}, {(short) 0x4e73, (short) 0x4e79},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x3236, (short) 0x323c},
+          {(short) 0x20b3, (short) 0x20b9}, {(short) 0x11b9, (short) 0x11bf},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xdac3, (short) 0xdabd}, {(short) 0xd6c3, (short) 0xd6bd},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x9ac4, (short) 0x9abe},
+          {(short) 0xde03, (short) 0xddfd}, {(short) 0xd82a, (short) 0xd824},
+          {(short) 0xc528, (short) 0xc522}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0xaa12, (short) 0xaa0c}, {(short) 0x9b62, (short) 0x9b5c},
+          {(short) 0x5abd, (short) 0x5ac3}, {(short) 0x56bd, (short) 0x56c3},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x1abe, (short) 0x1ac4},
+          {(short) 0x5dfd, (short) 0x5e03}, {(short) 0x5824, (short) 0x582a},
+          {(short) 0x4522, (short) 0x4528}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0x2a0c, (short) 0x2a12}, {(short) 0x1b5c, (short) 0x1b62},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xec78, (short) 0xec72}, {(short) 0xe878, (short) 0xe872},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xac79, (short) 0xac73},
+          {(short) 0xefef, (short) 0xefe9}, {(short) 0xe97f, (short) 0xe979},
+          {(short) 0xd6ce, (short) 0xd6c8}, {(short) 0xcd4b, (short) 0xcd45},
+          {(short) 0xbc03, (short) 0xbbfa}, {(short) 0xace1, (short) 0xacdb},
+          {(short) 0x6c72, (short) 0x6c78}, {(short) 0x6872, (short) 0x6878},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x2c73, (short) 0x2c79},
+          {(short) 0x6fe9, (short) 0x6fef}, {(short) 0x6979, (short) 0x697f},
+          {(short) 0x56c8, (short) 0x56ce}, {(short) 0x4d45, (short) 0x4d4b},
+          {(short) 0x3bfa, (short) 0x3c03}, {(short) 0x2cdb, (short) 0x2ce1},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfb56, (short) 0xfb50}, {(short) 0xf756, (short) 0xf750},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xbb57, (short) 0xbb51},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xf885, (short) 0xf87f},
+          {(short) 0xe598, (short) 0xe592}, {(short) 0xdc5a, (short) 0xdc54},
+          {(short) 0xca96, (short) 0xca90}, {(short) 0xbc03, (short) 0xbbfa},
+          {(short) 0x7b50, (short) 0x7b56}, {(short) 0x7750, (short) 0x7756},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x3b51, (short) 0x3b57},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x787f, (short) 0x7885},
+          {(short) 0x6592, (short) 0x6598}, {(short) 0x5c54, (short) 0x5c5a},
+          {(short) 0x4a90, (short) 0x4a96}, {(short) 0x3bfa, (short) 0x3c03},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfe00, (short) 0xfe00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfe00, (short) 0xfe00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x8003, (short) 0x0003}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfe00, (short) 0xfe00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0xfe00, (short) 0xfe00}, {(short) 0x8003, (short) 0x0003},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfc00, (short) 0xfc00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0x7c00, (short) 0x7c00},
+          {(short) 0xfc00, (short) 0xfc00}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x7c00, (short) 0x7c00}, {(short) 0xfe00, (short) 0xfe00},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+      {
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01}, {(short) 0x7e01, (short) 0x7e01},
+          {(short) 0x7e01, (short) 0x7e01},
+      },
+  };
+}
\ No newline at end of file
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ForEachTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ForEachTest.java
index b90633e..38831f4 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ForEachTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ForEachTest.java
@@ -475,8 +475,8 @@
         s.invoke_verify_foo();
         s.invoke_foreach_test();
         mRS.finish();
-        checkForErrors();
         waitForMessage();
+        checkForErrors();
     }
 
     public void testNoRoot() {
@@ -494,7 +494,7 @@
         s.invoke_verify_foo();
         s.invoke_noroot_test();
         mRS.finish();
-        checkForErrors();
         waitForMessage();
+        checkForErrors();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/GetSetTest.java b/tests/tests/renderscript/src/android/renderscript/cts/GetSetTest.java
new file mode 100644
index 0000000..9607923
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/GetSetTest.java
@@ -0,0 +1,1083 @@
+ /*
+ * 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.renderscript.cts;
+
+import android.renderscript.*;
+
+public class GetSetTest extends RSBaseCompute {
+
+    private ScriptC_getset script;
+    private ScriptC_getset_relaxed scriptRelaxed;
+    Allocation walkAlloc;
+    Allocation in1DAlloc;
+    Allocation out1DAlloc;
+    Allocation in2DAlloc;
+    Allocation out2DAlloc;
+    Allocation in3DAlloc;
+    Allocation out3DAlloc;
+    private static java.util.Random random = new java.util.Random();
+
+    final int gWidth = 252;
+    final int gHeight = 31;
+    final int gDepth = 4;
+    final int gCount = gWidth * gHeight * gDepth;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        random.setSeed(10);
+        script = new ScriptC_getset(mRS);
+        scriptRelaxed = new ScriptC_getset_relaxed(mRS);
+        script.set_gWidth(gWidth);
+        script.set_gHeight(gHeight);
+        scriptRelaxed.set_gWidth(gWidth);
+        scriptRelaxed.set_gHeight(gHeight);
+    }
+
+
+
+    protected void createWalk(int vsize) {
+        // We do a random copy order to attempt to get multiple threads
+        // reading and writing the same cache line
+        // We could do this as a simple walk but that would likely miss
+        // some caching issues.
+        final int tw = gCount / vsize;
+        int tmp[] = new int[tw];
+        boolean b[] = new boolean[tw];
+        int toCopy = tw;
+        int i = 0;
+
+        while (toCopy > 0) {
+            int x = random.nextInt(tw);
+
+            while ((x < tw) && b[x]) {
+                x++;
+                if (x >= tw) {
+                    x = 0;
+                }
+            }
+
+            b[x] = true;
+            toCopy --;
+
+            //android.util.Log.v("rs", "walk  " + i + ", " + x);
+            tmp[i++] = x;
+        }
+
+        walkAlloc = Allocation.createSized(mRS, Element.I32(mRS), tw);
+        walkAlloc.copy1DRangeFrom(0, tw, tmp);
+    }
+
+    private void testSetup(Element e) {
+        int vs = e.getVectorSize();
+        if (vs == 3) {
+            vs = 4;
+        }
+        createWalk(vs);
+
+        Type t1 = Type.createX(mRS, e, gWidth * gHeight * gDepth / vs);
+        in1DAlloc = Allocation.createTyped(mRS, t1);
+        out1DAlloc = Allocation.createTyped(mRS, t1);
+        script.set_gAlloc1DIn(in1DAlloc);
+        script.set_gAlloc1DOut(out1DAlloc);
+        scriptRelaxed.set_gAlloc1DIn(in1DAlloc);
+        scriptRelaxed.set_gAlloc1DOut(out1DAlloc);
+
+        Type t2 = Type.createXY(mRS, e, gWidth / vs, gHeight * gDepth);
+        in2DAlloc = Allocation.createTyped(mRS, t2);
+        out2DAlloc = Allocation.createTyped(mRS, t2);
+        script.set_gAlloc2DIn(in2DAlloc);
+        script.set_gAlloc2DOut(out2DAlloc);
+        scriptRelaxed.set_gAlloc2DIn(in2DAlloc);
+        scriptRelaxed.set_gAlloc2DOut(out2DAlloc);
+
+        Type t3 = Type.createXYZ(mRS, e, gWidth / vs, gHeight, gDepth);
+        in3DAlloc = Allocation.createTyped(mRS, t3);
+        out3DAlloc = Allocation.createTyped(mRS, t3);
+        script.set_gAlloc3DIn(in3DAlloc);
+        script.set_gAlloc3DOut(out3DAlloc);
+        scriptRelaxed.set_gAlloc3DIn(in3DAlloc);
+        scriptRelaxed.set_gAlloc3DOut(out3DAlloc);
+    }
+
+    private void verify(byte[] a1, byte[] a2, Allocation alloc, String s, int vsize) {
+        alloc.copyTo(a2);
+        for (int i=0; i < gWidth; i++) {
+            if (a1[i] != a2[i]) {
+                if ((vsize == 3) && ((i % 4) == 3)) {
+                    continue;
+                }
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        alloc.copyFrom(a2);
+    }
+
+    private void verify(short[] a1, short[] a2, Allocation alloc, String s, int vsize) {
+        alloc.copyTo(a2);
+        for (int i=0; i < gWidth; i++) {
+            if (a1[i] != a2[i]) {
+                if ((vsize == 3) && ((i % 4) == 3)) {
+                    continue;
+                }
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        alloc.copyFrom(a2);
+    }
+
+    private void verify(int[] a1, int[] a2, Allocation alloc, String s, int vsize) {
+        alloc.copyTo(a2);
+        for (int i=0; i < gWidth; i++) {
+            if (a1[i] != a2[i]) {
+                if ((vsize == 3) && ((i % 4) == 3)) {
+                    continue;
+                }
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        alloc.copyFrom(a2);
+    }
+
+    private void verify(long[] a1, long[] a2, Allocation alloc, String s, int vsize) {
+        alloc.copyTo(a2);
+        for (int i=0; i < gWidth; i++) {
+            if (a1[i] != a2[i]) {
+                if ((vsize == 3) && ((i % 4) == 3)) {
+                    continue;
+                }
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        alloc.copyFrom(a2);
+    }
+
+    private void verify(float[] a1, float[] a2, Allocation alloc, String s, int vsize) {
+        alloc.copyTo(a2);
+        for (int i=0; i < gWidth; i++) {
+            if (a1[i] != a2[i]) {
+                if ((vsize == 3) && ((i % 4) == 3)) {
+                    continue;
+                }
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        alloc.copyFrom(a2);
+    }
+
+    private void verify(double[] a1, double[] a2, Allocation alloc, String s, int vsize) {
+        alloc.copyTo(a2);
+        for (int i=0; i < gWidth; i++) {
+            if (a1[i] != a2[i]) {
+                if ((vsize == 3) && ((i % 4) == 3)) {
+                    continue;
+                }
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        alloc.copyFrom(a2);
+    }
+
+    private byte[] randomByteArray(int len) {
+        byte t[] = new byte[len];
+        random.nextBytes(t);
+        in1DAlloc.copyFrom(t);
+        in2DAlloc.copyFrom(t);
+        in3DAlloc.copyFrom(t);
+        return t;
+    }
+
+    private short[] randomShortArray(int len) {
+        short t[] = new short[len];
+        for (int i = 0; i < t.length; i++) {
+            t[i] = (short)(random.nextInt() & 0xffff);
+        }
+        in1DAlloc.copyFrom(t);
+        in2DAlloc.copyFrom(t);
+        in3DAlloc.copyFrom(t);
+        return t;
+    }
+
+    private int[] randomIntArray(int len) {
+        int t[] = new int[len];
+        for (int i = 0; i < t.length; i++) {
+            t[i] = random.nextInt();
+        }
+        in1DAlloc.copyFrom(t);
+        in2DAlloc.copyFrom(t);
+        in3DAlloc.copyFrom(t);
+        return t;
+    }
+
+    private long[] randomLongArray(int len) {
+        long t[] = new long[len];
+        for (int i = 0; i < t.length; i++) {
+            t[i] = random.nextLong();
+        }
+        in1DAlloc.copyFrom(t);
+        in2DAlloc.copyFrom(t);
+        in3DAlloc.copyFrom(t);
+        return t;
+    }
+
+    private float[] randomFloatArray(int len) {
+        float t[] = new float[len];
+        for (int i = 0; i < t.length; i++) {
+            t[i] = random.nextFloat();
+        }
+        in1DAlloc.copyFrom(t);
+        in2DAlloc.copyFrom(t);
+        in3DAlloc.copyFrom(t);
+        return t;
+    }
+
+    private double[] randomDoubleArray(int len) {
+        double t[] = new double[len];
+        for (int i = 0; i < t.length; i++) {
+            t[i] = random.nextDouble();
+        }
+        in1DAlloc.copyFrom(t);
+        in2DAlloc.copyFrom(t);
+        in3DAlloc.copyFrom(t);
+        return t;
+    }
+
+    public void testGetSet_char() {
+        testSetup(Element.I8(mRS));
+        byte tmp[] = randomByteArray(gCount);
+        byte tmp2[] = new byte[gCount];
+
+        script.forEach_copy1D_char(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch char: ", 1);
+        scriptRelaxed.forEach_copy1D_char(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed char: ", 1);
+
+        script.forEach_copy2D_char(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch char: ", 1);
+        scriptRelaxed.forEach_copy2D_char(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed char: ", 1);
+
+        script.forEach_copy3D_char(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch char: ", 1);
+        scriptRelaxed.forEach_copy3D_char(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed char: ", 1);
+    }
+
+    public void testGetSet_char2() {
+        testSetup(Element.I8_2(mRS));
+        byte tmp[] = randomByteArray(gCount);
+        byte tmp2[] = new byte[gCount];
+        script.forEach_copy1D_char2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch char2: ", 2);
+        scriptRelaxed.forEach_copy1D_char2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed char2: ", 2);
+
+        script.forEach_copy2D_char2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch char2: ", 2);
+        scriptRelaxed.forEach_copy2D_char2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed char2: ", 2);
+
+        script.forEach_copy3D_char2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch char2: ", 2);
+        scriptRelaxed.forEach_copy3D_char2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed char2: ", 2);
+    }
+
+    public void testGetSet_char3() {
+        testSetup(Element.I8_3(mRS));
+        byte tmp[] = randomByteArray(gCount);
+        byte tmp2[] = new byte[gCount];
+        script.forEach_copy1D_char3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch char3: ", 3);
+        scriptRelaxed.forEach_copy1D_char3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed char3: ", 3);
+
+        script.forEach_copy2D_char3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch char3: ", 3);
+        scriptRelaxed.forEach_copy2D_char3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed char3: ", 3);
+
+        script.forEach_copy3D_char3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch char3: ", 3);
+        scriptRelaxed.forEach_copy3D_char3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed char3: ", 3);
+    }
+
+    public void testGetSet_char4() {
+        testSetup(Element.I8_4(mRS));
+        byte tmp[] = randomByteArray(gCount);
+        byte tmp2[] = new byte[gCount];
+        script.forEach_copy1D_char4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch char4: ", 4);
+        scriptRelaxed.forEach_copy1D_char4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed char4: ", 4);
+
+        script.forEach_copy2D_char4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch char4: ", 4);
+        scriptRelaxed.forEach_copy2D_char4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed char4: ", 4);
+
+        script.forEach_copy3D_char4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch char4: ", 4);
+        scriptRelaxed.forEach_copy3D_char4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed char4: ", 4);
+    }
+
+    public void testGetSet_uchar() {
+        testSetup(Element.U8(mRS));
+        byte tmp[] = randomByteArray(gCount);
+        byte tmp2[] = new byte[gCount];
+        script.forEach_copy1D_uchar(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch uchar: ", 1);
+        scriptRelaxed.forEach_copy1D_uchar(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uchar: ", 1);
+
+        script.forEach_copy2D_uchar(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch uchar: ", 1);
+        scriptRelaxed.forEach_copy2D_uchar(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uchar: ", 1);
+
+        script.forEach_copy3D_uchar(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch uchar: ", 1);
+        scriptRelaxed.forEach_copy3D_uchar(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uchar: ", 1);
+    }
+
+    public void testGetSet_uchar2() {
+        testSetup(Element.U8_2(mRS));
+        byte tmp[] = randomByteArray(gCount);
+        byte tmp2[] = new byte[gCount];
+        script.forEach_copy1D_uchar2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch uchar2: ", 2);
+        scriptRelaxed.forEach_copy1D_uchar2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uchar2: ", 2);
+
+        script.forEach_copy2D_uchar2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch uchar2: ", 2);
+        scriptRelaxed.forEach_copy2D_uchar2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uchar2: ", 2);
+
+        script.forEach_copy3D_uchar2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch uchar2: ", 2);
+        scriptRelaxed.forEach_copy3D_uchar2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uchar2: ", 2);
+    }
+
+    public void testGetSet_uchar3() {
+        testSetup(Element.U8_3(mRS));
+        byte tmp[] = randomByteArray(gCount);
+        byte tmp2[] = new byte[gCount];
+        script.forEach_copy1D_uchar3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch uchar3: ", 3);
+        scriptRelaxed.forEach_copy1D_uchar3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uchar3: ", 3);
+
+        script.forEach_copy2D_uchar3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch uchar3: ", 3);
+        scriptRelaxed.forEach_copy2D_uchar3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uchar3: ", 3);
+
+        script.forEach_copy3D_uchar3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch uchar3: ", 3);
+        scriptRelaxed.forEach_copy3D_uchar3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uchar3: ", 3);
+    }
+
+    public void testGetSet_uchar4() {
+        testSetup(Element.U8_4(mRS));
+        byte tmp[] = randomByteArray(gCount);
+        byte tmp2[] = new byte[gCount];
+        script.forEach_copy1D_uchar4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch uchar4: ", 4);
+        scriptRelaxed.forEach_copy1D_uchar4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uchar4: ", 4);
+
+        script.forEach_copy2D_uchar4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch uchar4: ", 4);
+        scriptRelaxed.forEach_copy2D_uchar4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uchar4: ", 4);
+
+        script.forEach_copy3D_uchar4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch uchar4: ", 4);
+        scriptRelaxed.forEach_copy3D_uchar4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uchar4: ", 4);
+    }
+
+
+
+
+
+
+    public void testGetSet_short() {
+        testSetup(Element.I16(mRS));
+        short tmp[] = randomShortArray(gCount);
+        short tmp2[] = new short[gCount];
+        script.forEach_copy1D_short(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch short: ", 1);
+        scriptRelaxed.forEach_copy1D_short(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed short: ", 1);
+
+        script.forEach_copy2D_short(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch short: ", 1);
+        scriptRelaxed.forEach_copy2D_short(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed short: ", 1);
+
+        script.forEach_copy3D_short(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch short: ", 1);
+        scriptRelaxed.forEach_copy3D_short(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed short: ", 1);
+    }
+
+    public void testGetSet_short2() {
+        testSetup(Element.I16_2(mRS));
+        short tmp[] = randomShortArray(gCount);
+        short tmp2[] = new short[gCount];
+        script.forEach_copy1D_short2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch short2: ", 2);
+        scriptRelaxed.forEach_copy1D_short2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed short2: ", 2);
+
+        script.forEach_copy2D_short2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch short2: ", 2);
+        scriptRelaxed.forEach_copy2D_short2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed short2: ", 2);
+
+        script.forEach_copy3D_short2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch short2: ", 2);
+        scriptRelaxed.forEach_copy3D_short2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed short2: ", 2);
+    }
+
+    public void testGetSet_short3() {
+        testSetup(Element.I16_3(mRS));
+        short tmp[] = randomShortArray(gCount);
+        short tmp2[] = new short[gCount];
+        script.forEach_copy1D_short3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch short3: ", 3);
+        scriptRelaxed.forEach_copy1D_short3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed short3: ", 3);
+
+        script.forEach_copy2D_short3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch short3: ", 3);
+        scriptRelaxed.forEach_copy2D_short3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed short3: ", 3);
+
+        script.forEach_copy3D_short3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch short3: ", 3);
+        scriptRelaxed.forEach_copy3D_short3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed short3: ", 3);
+    }
+
+    public void testGetSet_short4() {
+        testSetup(Element.I16_4(mRS));
+        short tmp[] = randomShortArray(gCount);
+        short tmp2[] = new short[gCount];
+        script.forEach_copy1D_short4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch short4: ", 4);
+        scriptRelaxed.forEach_copy1D_short4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed short4: ", 4);
+
+        script.forEach_copy2D_short4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch short4: ", 4);
+        scriptRelaxed.forEach_copy2D_short4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed short4: ", 4);
+
+        script.forEach_copy3D_short4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch short4: ", 4);
+        scriptRelaxed.forEach_copy3D_short4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed short4: ", 4);
+    }
+
+    public void testGetSet_ushort() {
+        testSetup(Element.U16(mRS));
+        short tmp[] = randomShortArray(gCount);
+        short tmp2[] = new short[gCount];
+        script.forEach_copy1D_ushort(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch ushort: ", 1);
+        scriptRelaxed.forEach_copy1D_ushort(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ushort: ", 1);
+
+        script.forEach_copy2D_ushort(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch ushort: ", 1);
+        scriptRelaxed.forEach_copy2D_ushort(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ushort: ", 1);
+
+        script.forEach_copy3D_ushort(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch ushort: ", 1);
+        scriptRelaxed.forEach_copy3D_ushort(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ushort: ", 1);
+    }
+
+    public void testGetSet_ushort2() {
+        testSetup(Element.U16_2(mRS));
+        short tmp[] = randomShortArray(gCount);
+        short tmp2[] = new short[gCount];
+        script.forEach_copy1D_ushort2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch ushort2: ", 2);
+        scriptRelaxed.forEach_copy1D_ushort2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ushort2: ", 2);
+
+        script.forEach_copy2D_ushort2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch ushort2: ", 2);
+        scriptRelaxed.forEach_copy2D_ushort2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ushort2: ", 2);
+
+        script.forEach_copy3D_ushort2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch ushort2: ", 2);
+        scriptRelaxed.forEach_copy3D_ushort2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ushort2: ", 2);
+    }
+
+    public void testGetSet_ushort3() {
+        testSetup(Element.U16_3(mRS));
+        short tmp[] = randomShortArray(gCount);
+        short tmp2[] = new short[gCount];
+        script.forEach_copy1D_ushort3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch ushort3: ", 3);
+        scriptRelaxed.forEach_copy1D_ushort3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ushort3: ", 3);
+
+        script.forEach_copy2D_ushort3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch ushort3: ", 3);
+        scriptRelaxed.forEach_copy2D_ushort3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ushort3: ", 3);
+
+        script.forEach_copy3D_ushort3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch ushort3: ", 3);
+        scriptRelaxed.forEach_copy3D_ushort3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ushort3: ", 3);
+    }
+
+    public void testGetSet_ushort4() {
+        testSetup(Element.U16_4(mRS));
+        short tmp[] = randomShortArray(gCount);
+        short tmp2[] = new short[gCount];
+        script.forEach_copy1D_ushort4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch ushort4: ", 4);
+        scriptRelaxed.forEach_copy1D_ushort4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ushort4: ", 4);
+
+        script.forEach_copy2D_ushort4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch ushort4: ", 4);
+        scriptRelaxed.forEach_copy2D_ushort4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ushort4: ", 4);
+
+        script.forEach_copy3D_ushort4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch ushort4: ", 4);
+        scriptRelaxed.forEach_copy3D_ushort4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ushort4: ", 4);
+    }
+
+
+
+
+    public void testGetSet_int() {
+        testSetup(Element.I32(mRS));
+        int tmp[] = randomIntArray(gCount);
+        int tmp2[] = new int[gCount];
+        script.forEach_copy1D_int(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch int: ", 1);
+        scriptRelaxed.forEach_copy1D_int(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed int: ", 1);
+
+        script.forEach_copy2D_int(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch int: ", 1);
+        scriptRelaxed.forEach_copy2D_int(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed int: ", 1);
+
+        script.forEach_copy3D_int(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch int: ", 1);
+        scriptRelaxed.forEach_copy3D_int(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed int: ", 1);
+    }
+
+    public void testGetSet_int2() {
+        testSetup(Element.I32_2(mRS));
+        int tmp[] = randomIntArray(gCount);
+        int tmp2[] = new int[gCount];
+        script.forEach_copy1D_int2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch int2: ", 2);
+        scriptRelaxed.forEach_copy1D_int2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed int2: ", 2);
+
+        script.forEach_copy2D_int2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch int2: ", 2);
+        scriptRelaxed.forEach_copy2D_int2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed int2: ", 2);
+
+        script.forEach_copy3D_int2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch int2: ", 2);
+        scriptRelaxed.forEach_copy3D_int2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed int2: ", 2);
+    }
+
+    public void testGetSet_int3() {
+        testSetup(Element.I32_3(mRS));
+        int tmp[] = randomIntArray(gCount);
+        int tmp2[] = new int[gCount];
+        script.forEach_copy1D_int3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch int3: ", 3);
+        scriptRelaxed.forEach_copy1D_int3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed int3: ", 3);
+
+        script.forEach_copy2D_int3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch int3: ", 3);
+        scriptRelaxed.forEach_copy2D_int3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed int3: ", 3);
+
+        script.forEach_copy3D_int3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch int3: ", 3);
+        scriptRelaxed.forEach_copy3D_int3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed int3: ", 3);
+    }
+
+    public void testGetSet_int4() {
+        testSetup(Element.I32_4(mRS));
+        int tmp[] = randomIntArray(gCount);
+        int tmp2[] = new int[gCount];
+        script.forEach_copy1D_int4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch int4: ", 4);
+        scriptRelaxed.forEach_copy1D_int4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed int4: ", 4);
+
+        script.forEach_copy2D_int4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch int4: ", 4);
+        scriptRelaxed.forEach_copy2D_int4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed int4: ", 4);
+
+        script.forEach_copy3D_int4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch int4: ", 4);
+        scriptRelaxed.forEach_copy3D_int4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed int4: ", 4);
+    }
+
+    public void testGetSet_uint() {
+        testSetup(Element.U32(mRS));
+        int tmp[] = randomIntArray(gCount);
+        int tmp2[] = new int[gCount];
+        script.forEach_copy1D_uint(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch uint: ", 1);
+        scriptRelaxed.forEach_copy1D_uint(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uint: ", 1);
+
+        script.forEach_copy2D_uint(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch uint: ", 1);
+        scriptRelaxed.forEach_copy2D_uint(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uint: ", 1);
+
+        script.forEach_copy3D_uint(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch uint: ", 1);
+        scriptRelaxed.forEach_copy3D_uint(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uint: ", 1);
+    }
+
+    public void testGetSet_uint2() {
+        testSetup(Element.U32_2(mRS));
+        int tmp[] = randomIntArray(gCount);
+        int tmp2[] = new int[gCount];
+        script.forEach_copy1D_uint2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch uint2: ", 2);
+        scriptRelaxed.forEach_copy1D_uint2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uint2: ", 2);
+
+        script.forEach_copy2D_uint2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch uint2: ", 2);
+        scriptRelaxed.forEach_copy2D_uint2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uint2: ", 2);
+
+        script.forEach_copy3D_uint2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch uint2: ", 2);
+        scriptRelaxed.forEach_copy3D_uint2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uint2: ", 2);
+    }
+
+    public void testGetSet_uint3() {
+        testSetup(Element.U32_3(mRS));
+        int tmp[] = randomIntArray(gCount);
+        int tmp2[] = new int[gCount];
+        script.forEach_copy1D_uint3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch uint3: ", 3);
+        scriptRelaxed.forEach_copy1D_uint3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uint3: ", 3);
+
+        script.forEach_copy2D_uint3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch uint3: ", 3);
+        scriptRelaxed.forEach_copy2D_uint3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uint3: ", 3);
+
+        script.forEach_copy3D_uint3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch uint3: ", 3);
+        scriptRelaxed.forEach_copy3D_uint3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uint3: ", 3);
+    }
+
+    public void testGetSet_uint4() {
+        testSetup(Element.U32_4(mRS));
+        int tmp[] = randomIntArray(gCount);
+        int tmp2[] = new int[gCount];
+        script.forEach_copy1D_uint4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch uint4: ", 4);
+        scriptRelaxed.forEach_copy1D_uint4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uint4: ", 4);
+
+        script.forEach_copy2D_uint4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch uint4: ", 4);
+        scriptRelaxed.forEach_copy2D_uint4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uint4: ", 4);
+
+        script.forEach_copy3D_uint4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch uint4: ", 4);
+        scriptRelaxed.forEach_copy3D_uint4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uint4: ", 4);
+    }
+
+
+
+
+    public void testGetSet_long() {
+        testSetup(Element.I64(mRS));
+        long tmp[] = randomLongArray(gCount);
+        long tmp2[] = new long[gCount];
+        script.forEach_copy1D_long(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch long: ", 1);
+        scriptRelaxed.forEach_copy1D_long(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed long: ", 1);
+
+        script.forEach_copy2D_long(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch long: ", 1);
+        scriptRelaxed.forEach_copy2D_long(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed long: ", 1);
+
+        script.forEach_copy3D_long(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch long: ", 1);
+        scriptRelaxed.forEach_copy3D_long(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed long: ", 1);
+    }
+
+    public void testGetSet_long2() {
+        testSetup(Element.I64_2(mRS));
+        long tmp[] = randomLongArray(gCount);
+        long tmp2[] = new long[gCount];
+        script.forEach_copy1D_long2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch long2: ", 2);
+        scriptRelaxed.forEach_copy1D_long2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed long2: ", 2);
+
+        script.forEach_copy2D_long2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch long2: ", 2);
+        scriptRelaxed.forEach_copy2D_long2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed long2: ", 2);
+
+        script.forEach_copy3D_long2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch long2: ", 2);
+        scriptRelaxed.forEach_copy3D_long2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed long2: ", 2);
+    }
+
+    public void testGetSet_long3() {
+        testSetup(Element.I64_3(mRS));
+        long tmp[] = randomLongArray(gCount);
+        long tmp2[] = new long[gCount];
+        script.forEach_copy1D_long3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch long3: ", 3);
+        scriptRelaxed.forEach_copy1D_long3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed long3: ", 3);
+
+        script.forEach_copy2D_long3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch long3: ", 3);
+        scriptRelaxed.forEach_copy2D_long3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed long3: ", 3);
+
+        script.forEach_copy3D_long3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch long3: ", 3);
+        scriptRelaxed.forEach_copy3D_long3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed long3: ", 3);
+    }
+
+    public void testGetSet_long4() {
+        testSetup(Element.I64_4(mRS));
+        long tmp[] = randomLongArray(gCount);
+        long tmp2[] = new long[gCount];
+        script.forEach_copy1D_long4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch long4: ", 4);
+        scriptRelaxed.forEach_copy1D_long4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed long4: ", 4);
+
+        script.forEach_copy2D_long4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch long4: ", 4);
+        scriptRelaxed.forEach_copy2D_long4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed long4: ", 4);
+
+        script.forEach_copy3D_long4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch long4: ", 4);
+        scriptRelaxed.forEach_copy3D_long4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed long4: ", 4);
+    }
+
+    public void testGetSet_ulong() {
+        testSetup(Element.U64(mRS));
+        long tmp[] = randomLongArray(gCount);
+        long tmp2[] = new long[gCount];
+        script.forEach_copy1D_ulong(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch ulong: ", 1);
+        scriptRelaxed.forEach_copy1D_ulong(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ulong: ", 1);
+
+        script.forEach_copy2D_ulong(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch ulong: ", 1);
+        scriptRelaxed.forEach_copy2D_ulong(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ulong: ", 1);
+
+        script.forEach_copy3D_ulong(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch ulong: ", 1);
+        scriptRelaxed.forEach_copy3D_ulong(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ulong: ", 1);
+    }
+
+    public void testGetSet_ulong2() {
+        testSetup(Element.U64_2(mRS));
+        long tmp[] = randomLongArray(gCount);
+        long tmp2[] = new long[gCount];
+        script.forEach_copy1D_ulong2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch ulong2: ", 2);
+        scriptRelaxed.forEach_copy1D_ulong2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ulong2: ", 2);
+
+        script.forEach_copy2D_ulong2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch ulong2: ", 2);
+        scriptRelaxed.forEach_copy2D_ulong2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ulong2: ", 2);
+
+        script.forEach_copy3D_ulong2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch ulong2: ", 2);
+        scriptRelaxed.forEach_copy3D_ulong2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ulong2: ", 2);
+    }
+
+    public void testGetSet_ulong3() {
+        testSetup(Element.U64_3(mRS));
+        long tmp[] = randomLongArray(gCount);
+        long tmp2[] = new long[gCount];
+        script.forEach_copy1D_ulong3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch ulong3: ", 3);
+        scriptRelaxed.forEach_copy1D_ulong3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ulong3: ", 3);
+
+        script.forEach_copy2D_ulong3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch ulong3: ", 3);
+        scriptRelaxed.forEach_copy2D_ulong3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ulong3: ", 3);
+
+        script.forEach_copy3D_ulong3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch ulong3: ", 3);
+        scriptRelaxed.forEach_copy3D_ulong3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ulong3: ", 3);
+    }
+
+    public void testGetSet_ulong4() {
+        testSetup(Element.U64_4(mRS));
+        long tmp[] = randomLongArray(gCount);
+        long tmp2[] = new long[gCount];
+        script.forEach_copy1D_ulong4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch ulong4: ", 4);
+        scriptRelaxed.forEach_copy1D_ulong4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ulong4: ", 4);
+
+        script.forEach_copy2D_ulong4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch ulong4: ", 4);
+        scriptRelaxed.forEach_copy2D_ulong4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ulong4: ", 4);
+
+        script.forEach_copy3D_ulong4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch ulong4: ", 4);
+        scriptRelaxed.forEach_copy3D_ulong4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ulong4: ", 4);
+    }
+
+
+
+
+    public void testGetSet_float() {
+        testSetup(Element.F32(mRS));
+        float tmp[] = randomFloatArray(gCount);
+        float tmp2[] = new float[gCount];
+        script.forEach_copy1D_float(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch float: ", 1);
+        scriptRelaxed.forEach_copy1D_float(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed float: ", 1);
+
+        script.forEach_copy2D_float(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch float: ", 1);
+        scriptRelaxed.forEach_copy2D_float(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed float: ", 1);
+
+        script.forEach_copy3D_float(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch float: ", 1);
+        scriptRelaxed.forEach_copy3D_float(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed float: ", 1);
+    }
+
+    public void testGetSet_float2() {
+        testSetup(Element.F32_2(mRS));
+        float tmp[] = randomFloatArray(gCount);
+        float tmp2[] = new float[gCount];
+        script.forEach_copy1D_float2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch float2: ", 2);
+        scriptRelaxed.forEach_copy1D_float2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed float2: ", 2);
+
+        script.forEach_copy2D_float2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch float2: ", 2);
+        scriptRelaxed.forEach_copy2D_float2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed float2: ", 2);
+
+        script.forEach_copy3D_float2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch float2: ", 2);
+        scriptRelaxed.forEach_copy3D_float2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed float2: ", 2);
+    }
+
+    public void testGetSet_float3() {
+        testSetup(Element.F32_3(mRS));
+        float tmp[] = randomFloatArray(gCount);
+        float tmp2[] = new float[gCount];
+        script.forEach_copy1D_float3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch float3: ", 3);
+        scriptRelaxed.forEach_copy1D_float3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed float3: ", 3);
+
+        script.forEach_copy2D_float3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch float3: ", 3);
+        scriptRelaxed.forEach_copy2D_float3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed float3: ", 3);
+
+        script.forEach_copy3D_float3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch float3: ", 3);
+        scriptRelaxed.forEach_copy3D_float3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed float3: ", 3);
+    }
+
+    public void testGetSet_float4() {
+        testSetup(Element.F32_4(mRS));
+        float tmp[] = randomFloatArray(gCount);
+        float tmp2[] = new float[gCount];
+        script.forEach_copy1D_float4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch float4: ", 4);
+        scriptRelaxed.forEach_copy1D_float4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed float4: ", 4);
+
+        script.forEach_copy2D_float4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch float4: ", 4);
+        scriptRelaxed.forEach_copy2D_float4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed float4: ", 4);
+
+        script.forEach_copy3D_float4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch float4: ", 4);
+        scriptRelaxed.forEach_copy3D_float4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed float4: ", 4);
+    }
+
+
+    public void testGetSet_double() {
+        testSetup(Element.F64(mRS));
+        double tmp[] = randomDoubleArray(gCount);
+        double tmp2[] = new double[gCount];
+        script.forEach_copy1D_double(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch double: ", 1);
+        scriptRelaxed.forEach_copy1D_double(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed double: ", 1);
+
+        script.forEach_copy2D_double(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch double: ", 1);
+        scriptRelaxed.forEach_copy2D_double(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed double: ", 1);
+
+        script.forEach_copy3D_double(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch double: ", 1);
+        scriptRelaxed.forEach_copy3D_double(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed double: ", 1);
+    }
+
+    public void testGetSet_double2() {
+        testSetup(Element.F64_2(mRS));
+        double tmp[] = randomDoubleArray(gCount);
+        double tmp2[] = new double[gCount];
+        script.forEach_copy1D_double2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch double2: ", 2);
+        scriptRelaxed.forEach_copy1D_double2(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed double2: ", 2);
+
+        script.forEach_copy2D_double2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch double2: ", 2);
+        scriptRelaxed.forEach_copy2D_double2(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed double2: ", 2);
+
+        script.forEach_copy3D_double2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch double2: ", 2);
+        scriptRelaxed.forEach_copy3D_double2(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed double2: ", 2);
+    }
+
+    public void testGetSet_double3() {
+        testSetup(Element.F64_3(mRS));
+        double tmp[] = randomDoubleArray(gCount);
+        double tmp2[] = new double[gCount];
+        script.forEach_copy1D_double3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch double3: ", 3);
+        scriptRelaxed.forEach_copy1D_double3(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed double3: ", 3);
+
+        script.forEach_copy2D_double3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch double3: ", 3);
+        scriptRelaxed.forEach_copy2D_double3(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed double3: ", 3);
+
+        script.forEach_copy3D_double3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch double3: ", 3);
+        scriptRelaxed.forEach_copy3D_double3(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed double3: ", 3);
+    }
+
+    public void testGetSet_double4() {
+        testSetup(Element.F64_4(mRS));
+        double tmp[] = randomDoubleArray(gCount);
+        double tmp2[] = new double[gCount];
+        script.forEach_copy1D_double4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch double4: ", 4);
+        scriptRelaxed.forEach_copy1D_double4(walkAlloc);
+        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed double4: ", 4);
+
+        script.forEach_copy2D_double4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch double4: ", 4);
+        scriptRelaxed.forEach_copy2D_double4(walkAlloc);
+        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed double4: ", 4);
+
+        script.forEach_copy3D_double4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch double4: ", 4);
+        scriptRelaxed.forEach_copy3D_double4(walkAlloc);
+        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed double4: ", 4);
+    }
+
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/Intrinsic3DLut.java b/tests/tests/renderscript/src/android/renderscript/cts/Intrinsic3DLut.java
index 87a03ad..4ec84ad 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/Intrinsic3DLut.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/Intrinsic3DLut.java
@@ -136,5 +136,12 @@
         checkError();
     }
 
+    public void test_ID() {
+        ScriptIntrinsic3DLUT s = ScriptIntrinsic3DLUT.create(mRS, Element.U8_4(mRS));
+        Script.KernelID kid = s.getKernelID();
+        if (kid == null) {
+            throw new IllegalStateException("kid must be valid");
+        }
+    }
 
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBLAS.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBLAS.java
new file mode 100644
index 0000000..17f546b
--- /dev/null
+++ b/tests/tests/renderscript/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.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/IntrinsicBlur.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBlur.java
index 076dcd4..4e99391 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBlur.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicBlur.java
@@ -141,5 +141,17 @@
         checkError();
     }
 
+    public void test_ID() {
+        ScriptIntrinsicBlur s = ScriptIntrinsicBlur.create(mRS, Element.U8_4(mRS));
+        Script.KernelID kid = s.getKernelID();
+        if (kid == null) {
+            throw new IllegalStateException("kid must be valid");
+        }
+
+        Script.FieldID fid = s.getFieldID_Input();
+        if (fid == null) {
+            throw new IllegalStateException("fid must be valid");
+        }
+    }
 
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve3x3.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve3x3.java
index 8faeb22..8a2bc27 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve3x3.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve3x3.java
@@ -247,4 +247,17 @@
         checkError();
     }
 
+    public void test_ID() {
+        ScriptIntrinsicConvolve3x3 s = ScriptIntrinsicConvolve3x3.create(mRS, Element.U8_4(mRS));
+        Script.KernelID kid = s.getKernelID();
+        if (kid == null) {
+            throw new IllegalStateException("kid must be valid");
+        }
+
+        Script.FieldID fid = s.getFieldID_Input();
+        if (fid == null) {
+            throw new IllegalStateException("fid must be valid");
+        }
+    }
+
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve5x5.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve5x5.java
index 0753c62..410aebd 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve5x5.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicConvolve5x5.java
@@ -184,4 +184,17 @@
         checkError();
     }
 
+    public void test_ID() {
+        ScriptIntrinsicConvolve5x5 s = ScriptIntrinsicConvolve5x5.create(mRS, Element.U8_4(mRS));
+        Script.KernelID kid = s.getKernelID();
+        if (kid == null) {
+            throw new IllegalStateException("kid must be valid");
+        }
+
+        Script.FieldID fid = s.getFieldID_Input();
+        if (fid == null) {
+            throw new IllegalStateException("fid must be valid");
+        }
+    }
+
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicLut.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicLut.java
index 1567639..3309bb0 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicLut.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicLut.java
@@ -83,5 +83,12 @@
     }
 
 
+    public void test_ID() {
+        ScriptIntrinsicLUT s = ScriptIntrinsicLUT.create(mRS, Element.U8_4(mRS));
+        Script.KernelID kid = s.getKernelID();
+        if (kid == null) {
+            throw new IllegalStateException("kid must be valid");
+        }
+    }
 
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
index d593bff..c8b3640 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/IntrinsicResize.java
@@ -24,7 +24,7 @@
     static final int inX = 307;
     static final int inY = 157;
 
-    private void testReszie(int w, int h, Element.DataType dt, int vecSize, float scaleX, float scaleY) {
+    private void testResize(int w, int h, Element.DataType dt, int vecSize, float scaleX, float scaleY) {
 
         Element e = makeElement(dt, vecSize);
 
@@ -67,10 +67,28 @@
                 sr.forEach_bicubic_U1(mAllocDst);
                 break;
             }
+        } else {
+            switch(vecSize) {
+            case 4:
+                sr.forEach_bicubic_F4(mAllocDst);
+                break;
+            case 3:
+                sr.forEach_bicubic_F3(mAllocDst);
+                break;
+            case 2:
+                sr.forEach_bicubic_F2(mAllocDst);
+                break;
+            case 1:
+                sr.forEach_bicubic_F1(mAllocDst);
+                break;
+            }
         }
 
+
+        mVerify.set_gAllowedIntError(1);
         mVerify.invoke_verify(mAllocRef, mAllocDst, mAllocSrc);
         if (outW == w && outH == h) {
+            mVerify.set_gAllowedIntError(0);
             //when scale = 1, check with the original.
             mVerify.invoke_verify(mAllocRef, mAllocSrc, mAllocSrc);
             mVerify.invoke_verify(mAllocDst, mAllocSrc, mAllocSrc);
@@ -80,172 +98,344 @@
 
 
     public void test_U8_4_SCALE10_10_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 1.f, 1.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 1.f, 1.f);
         checkError();
     }
     public void test_U8_3_SCALE10_10_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 1.f, 1.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 1.f, 1.f);
         checkError();
     }
     public void test_U8_2_SCALE10_10_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 1.f, 1.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 1.f, 1.f);
         checkError();
     }
     public void test_U8_1_SCALE10_10_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 1.f, 1.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 1.f, 1.f);
         checkError();
     }
 
     public void test_U8_4_SCALE20_20_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 2.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 2.f);
         checkError();
     }
     public void test_U8_3_SCALE20_20_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 2.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 2.f);
         checkError();
     }
     public void test_U8_2_SCALE20_20_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 2.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 2.f);
         checkError();
     }
     public void test_U8_1_SCALE20_20_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 2.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 2.f);
         checkError();
     }
 
     public void test_U8_4_SCALE05_20_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 2.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 2.f);
         checkError();
     }
     public void test_U8_3_SCALE05_20_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 2.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 2.f);
         checkError();
     }
     public void test_U8_2_SCALE05_20_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 2.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 2.f);
         checkError();
     }
     public void test_U8_1_SCALE05_20_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 2.f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 2.f);
         checkError();
     }
 
     public void test_U8_4_SCALE20_05_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 0.5f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 0.5f);
         checkError();
     }
     public void test_U8_3_SCALE20_05_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 0.5f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 0.5f);
         checkError();
     }
     public void test_U8_2_SCALE20_05_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 0.5f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 0.5f);
         checkError();
     }
     public void test_U8_1_SCALE20_05_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 0.5f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 0.5f);
         checkError();
     }
 
     public void test_U8_4_SCALE05_05_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 0.5f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 0.5f);
         checkError();
     }
     public void test_U8_3_SCALE05_05_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 0.5f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 0.5f);
         checkError();
     }
     public void test_U8_2_SCALE05_05_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 0.5f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 0.5f);
         checkError();
     }
     public void test_U8_1_SCALE05_05_inSqure() {
-        testReszie(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 0.5f);
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 0.5f);
         checkError();
     }
 
     public void test_U8_4_SCALE10_10_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 1.f, 1.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 1.f, 1.f);
         checkError();
     }
     public void test_U8_3_SCALE10_10_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 1.f, 1.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 1.f, 1.f);
         checkError();
     }
     public void test_U8_2_SCALE10_10_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 1.f, 1.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 1.f, 1.f);
         checkError();
     }
     public void test_U8_1_SCALE10_10_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 1.f, 1.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 1.f, 1.f);
         checkError();
     }
 
     public void test_U8_4_SCALE20_20_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 2.f, 2.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 2.f, 2.f);
         checkError();
     }
     public void test_U8_3_SCALE20_20_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 2.f, 2.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 2.f, 2.f);
         checkError();
     }
     public void test_U8_2_SCALE20_20_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 2.f, 2.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 2.f, 2.f);
         checkError();
     }
     public void test_U8_1_SCALE20_20_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 2.f, 2.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 2.f, 2.f);
         checkError();
     }
 
     public void test_U8_4_SCALE05_20_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 0.5f, 2.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 0.5f, 2.f);
         checkError();
     }
     public void test_U8_3_SCALE05_20_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 0.5f, 2.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 0.5f, 2.f);
         checkError();
     }
     public void test_U8_2_SCALE05_20_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 0.5f, 2.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 0.5f, 2.f);
         checkError();
     }
     public void test_U8_1_SCALE05_20_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 0.5f, 2.f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 0.5f, 2.f);
         checkError();
     }
-    
+
     public void test_U8_4_SCALE20_05_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 2.f, 0.5f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 2.f, 0.5f);
         checkError();
     }
     public void test_U8_3_SCALE20_05_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 2.f, 0.5f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 2.f, 0.5f);
         checkError();
     }
     public void test_U8_2_SCALE20_05_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 2.f, 0.5f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 2.f, 0.5f);
         checkError();
     }
     public void test_U8_1_SCALE20_05_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 2.f, 0.5f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 2.f, 0.5f);
         checkError();
     }
-    
+
     public void test_U8_4_SCALE05_05_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 4, 0.5f, 0.5f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 0.5f, 0.5f);
         checkError();
     }
     public void test_U8_3_SCALE05_05_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 3, 0.5f, 0.5f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 0.5f, 0.5f);
         checkError();
     }
     public void test_U8_2_SCALE05_05_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 2, 0.5f, 0.5f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 0.5f, 0.5f);
         checkError();
     }
     public void test_U8_1_SCALE05_05_inRectangle() {
-        testReszie(inX, inY, Element.DataType.UNSIGNED_8, 1, 0.5f, 0.5f);
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 0.5f, 0.5f);
         checkError();
     }
+
+
+    public void test_F32_4_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 1.f, 1.f);
+        checkError();
+    }
+    public void test_F32_3_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 1.f, 1.f);
+        checkError();
+    }
+    public void test_F32_2_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 1.f, 1.f);
+        checkError();
+    }
+    public void test_F32_1_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 1.f, 1.f);
+        checkError();
+    }
+
+    public void test_F32_4_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 2.f, 2.f);
+        checkError();
+    }
+    public void test_F32_3_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 2.f, 2.f);
+        checkError();
+    }
+    public void test_F32_2_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 2.f, 2.f);
+        checkError();
+    }
+    public void test_F32_1_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 2.f, 2.f);
+        checkError();
+    }
+
+    public void test_F32_4_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 0.5f, 2.f);
+        checkError();
+    }
+    public void test_F32_3_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 0.5f, 2.f);
+        checkError();
+    }
+    public void test_F32_2_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 0.5f, 2.f);
+        checkError();
+    }
+    public void test_F32_1_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 0.5f, 2.f);
+        checkError();
+    }
+
+    public void test_F32_4_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 2.f, 0.5f);
+        checkError();
+    }
+    public void test_F32_3_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 2.f, 0.5f);
+        checkError();
+    }
+    public void test_F32_2_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 2.f, 0.5f);
+        checkError();
+    }
+    public void test_F32_1_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 2.f, 0.5f);
+        checkError();
+    }
+
+    public void test_F32_4_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 0.5f, 0.5f);
+        checkError();
+    }
+    public void test_F32_3_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 0.5f, 0.5f);
+        checkError();
+    }
+    public void test_F32_2_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 0.5f, 0.5f);
+        checkError();
+    }
+    public void test_F32_1_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 0.5f, 0.5f);
+        checkError();
+    }
+
+    public void test_F32_4_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 1.f, 1.f);
+        checkError();
+    }
+    public void test_F32_3_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 1.f, 1.f);
+        checkError();
+    }
+    public void test_F32_2_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 1.f, 1.f);
+        checkError();
+    }
+    public void test_F32_1_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 1.f, 1.f);
+        checkError();
+    }
+
+    public void test_F32_4_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 2.f, 2.f);
+        checkError();
+    }
+    public void test_F32_3_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 2.f, 2.f);
+        checkError();
+    }
+    public void test_F32_2_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 2.f, 2.f);
+        checkError();
+    }
+    public void test_F32_1_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 2.f, 2.f);
+        checkError();
+    }
+
+    public void test_F32_4_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 0.5f, 2.f);
+        checkError();
+    }
+    public void test_F32_3_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 0.5f, 2.f);
+        checkError();
+    }
+    public void test_F32_2_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 0.5f, 2.f);
+        checkError();
+    }
+    public void test_F32_1_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 0.5f, 2.f);
+        checkError();
+    }
+
+    public void test_F32_4_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 2.f, 0.5f);
+        checkError();
+    }
+    public void test_F32_3_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 2.f, 0.5f);
+        checkError();
+    }
+    public void test_F32_2_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 2.f, 0.5f);
+        checkError();
+    }
+    public void test_F32_1_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 2.f, 0.5f);
+        checkError();
+    }
+
+    public void test_F32_4_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 0.5f, 0.5f);
+        checkError();
+    }
+    public void test_F32_3_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 0.5f, 0.5f);
+        checkError();
+    }
+    public void test_F32_2_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 0.5f, 0.5f);
+        checkError();
+    }
+    public void test_F32_1_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 0.5f, 0.5f);
+        checkError();
+    }
+
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/KernelInputTest.java b/tests/tests/renderscript/src/android/renderscript/cts/KernelInputTest.java
new file mode 100644
index 0000000..ecb1b6d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/KernelInputTest.java
@@ -0,0 +1,619 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Byte2;
+import android.renderscript.Byte3;
+import android.renderscript.Byte4;
+
+import android.renderscript.Double2;
+import android.renderscript.Double3;
+import android.renderscript.Double4;
+
+import android.renderscript.Element;
+
+import android.renderscript.Float2;
+import android.renderscript.Float3;
+import android.renderscript.Float4;
+
+import android.renderscript.Int2;
+import android.renderscript.Int3;
+import android.renderscript.Int4;
+
+import android.renderscript.Long2;
+import android.renderscript.Long3;
+import android.renderscript.Long4;
+
+import android.renderscript.Short2;
+import android.renderscript.Short3;
+import android.renderscript.Short4;
+
+import android.renderscript.Element;
+
+/*
+ * This checks that modifications to input arguments done by a kernel
+ * are never reflected back to the input Allocation.
+ *
+ * The test works by launching forEach kernels that take different
+ * types of inputs. Each forEach kernel modifies its input in some way.
+ * After running the forEach kernel, the input Allocation is checked
+ * that it remains unmodified.
+ */
+public class KernelInputTest extends RSBaseCompute {
+
+    void checkForErrorsInScript(ScriptC_kernel_input script) {
+        mRS.finish();
+        script.invoke_checkError();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    public void testInputNotModified_char() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I8(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I8(mRS), 1);
+
+        script.set_initial_value_char((byte) 6);
+        ain.copyFrom(new byte[]{ (byte) 6 });
+        script.forEach_clear_input_char(ain, tmp);
+        script.invoke_verify_input_char(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_char2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I8_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I8_2(mRS), 1);
+
+        script.set_initial_value_char2(new Byte2((byte) 127, (byte) 3));
+        ain.copyFrom(new byte[]{ (byte) 127, (byte) 3 });
+        script.forEach_clear_input_char2(ain, tmp);
+        script.invoke_verify_input_char2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_char3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I8_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I8_3(mRS), 1);
+
+        script.set_initial_value_char3(new Byte3((byte) 127, (byte) 3, (byte) 4));
+        ain.copyFrom(new byte[]{ (byte) 127, (byte) 3, (byte) 4, 0 });
+        script.forEach_clear_input_char3(ain, tmp);
+        script.invoke_verify_input_char3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_char4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I8_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I8_4(mRS), 1);
+
+        script.set_initial_value_char4(new Byte4((byte) 127, (byte) 3, (byte) 4, (byte) 7));
+        ain.copyFrom(new byte[]{ (byte) 127, (byte) 3, (byte) 4, (byte) 7 });
+        script.forEach_clear_input_char4(ain, tmp);
+        script.invoke_verify_input_char4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_double() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.F64(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.F64(mRS), 1);
+
+        script.set_initial_value_double((double) 6);
+        ain.copyFrom(new double[]{ (double) 6 });
+        script.forEach_clear_input_double(ain, tmp);
+        script.invoke_verify_input_double(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_double2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.F64_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.F64_2(mRS), 1);
+
+        script.set_initial_value_double2(new Double2((double) 127, (double) 3));
+        ain.copyFrom(new double[]{ (double) 127, (double) 3 });
+        script.forEach_clear_input_double2(ain, tmp);
+        script.invoke_verify_input_double2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_double3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.F64_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.F64_3(mRS), 1);
+
+        script.set_initial_value_double3(new Double3((double) 127, (double) 3, (double) 4));
+        ain.copyFrom(new double[]{ (double) 127, (double) 3, (double) 4, 0 });
+        script.forEach_clear_input_double3(ain, tmp);
+        script.invoke_verify_input_double3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_double4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.F64_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.F64_4(mRS), 1);
+
+        script.set_initial_value_double4(new Double4((double) 127, (double) 3, (double) 4, (double) 7));
+        ain.copyFrom(new double[]{ (double) 127, (double) 3, (double) 4, (double) 7 });
+        script.forEach_clear_input_double4(ain, tmp);
+        script.invoke_verify_input_double4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_float() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.F32(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.F32(mRS), 1);
+
+        script.set_initial_value_float((float) 6);
+        ain.copyFrom(new float[]{ (float) 6 });
+        script.forEach_clear_input_float(ain, tmp);
+        script.invoke_verify_input_float(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_float2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.F32_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.F32_2(mRS), 1);
+
+        script.set_initial_value_float2(new Float2((float) 127, (float) 3));
+        ain.copyFrom(new float[]{ (float) 127, (float) 3 });
+        script.forEach_clear_input_float2(ain, tmp);
+        script.invoke_verify_input_float2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_float3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.F32_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.F32_3(mRS), 1);
+
+        script.set_initial_value_float3(new Float3((float) 127, (float) 3, (float) 4));
+        ain.copyFrom(new float[]{ (float) 127, (float) 3, (float) 4, 0 });
+        script.forEach_clear_input_float3(ain, tmp);
+        script.invoke_verify_input_float3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_float4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.F32_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.F32_4(mRS), 1);
+
+        script.set_initial_value_float4(new Float4((float) 127, (float) 3, (float) 4, (float) 7));
+        ain.copyFrom(new float[]{ (float) 127, (float) 3, (float) 4, (float) 7 });
+        script.forEach_clear_input_float4(ain, tmp);
+        script.invoke_verify_input_float4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_int() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I32(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I32(mRS), 1);
+
+        script.set_initial_value_int(6);
+        ain.copyFrom(new int[]{ 6 });
+        script.forEach_clear_input_int(ain, tmp);
+        script.invoke_verify_input_int(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_int2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I32_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I32_2(mRS), 1);
+
+        script.set_initial_value_int2(new Int2(127, 3));
+        ain.copyFrom(new int[]{ 127, 3 });
+        script.forEach_clear_input_int2(ain, tmp);
+        script.invoke_verify_input_int2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_int3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I32_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I32_3(mRS), 1);
+
+        script.set_initial_value_int3(new Int3(127, 3, 4));
+        ain.copyFrom(new int[]{ 127, 3, 4, 0 });
+        script.forEach_clear_input_int3(ain, tmp);
+        script.invoke_verify_input_int3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_int4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I32_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I32_4(mRS), 1);
+
+        script.set_initial_value_int4(new Int4(127, 3, 4, 7));
+        ain.copyFrom(new int[]{ 127, 3, 4, 7 });
+        script.forEach_clear_input_int4(ain, tmp);
+        script.invoke_verify_input_int4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_long() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I64(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I64(mRS), 1);
+
+        script.set_initial_value_long((long) 6);
+        ain.copyFrom(new long[]{ (long) 6 });
+        script.forEach_clear_input_long(ain, tmp);
+        script.invoke_verify_input_long(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_long2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I64_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I64_2(mRS), 1);
+
+        script.set_initial_value_long2(new Long2((long) 127, (long) 3));
+        ain.copyFrom(new long[]{ (long) 127, (long) 3 });
+        script.forEach_clear_input_long2(ain, tmp);
+        script.invoke_verify_input_long2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_long3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I64_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I64_3(mRS), 1);
+
+        script.set_initial_value_long3(new Long3((long) 127, (long) 3, (long) 4));
+        ain.copyFrom(new long[]{ (long) 127, (long) 3, (long) 4, 0 });
+        script.forEach_clear_input_long3(ain, tmp);
+        script.invoke_verify_input_long3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_long4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I64_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I64_4(mRS), 1);
+
+        script.set_initial_value_long4(new Long4((long) 127, (long) 3, (long) 4, (long) 7));
+        ain.copyFrom(new long[]{ (long) 127, (long) 3, (long) 4, (long) 7 });
+        script.forEach_clear_input_long4(ain, tmp);
+        script.invoke_verify_input_long4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_short() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I16(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I16(mRS), 1);
+
+        script.set_initial_value_short((short) 6);
+        ain.copyFrom(new short[]{ (short) 6 });
+        script.forEach_clear_input_short(ain, tmp);
+        script.invoke_verify_input_short(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_short2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I16_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I16_2(mRS), 1);
+
+        script.set_initial_value_short2(new Short2((short) 127, (short) 3));
+        ain.copyFrom(new short[]{ (short) 127, (short) 3 });
+        script.forEach_clear_input_short2(ain, tmp);
+        script.invoke_verify_input_short2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_short3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I16_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I16_3(mRS), 1);
+
+        script.set_initial_value_short3(new Short3((short) 127, (short) 3, (short) 4));
+        ain.copyFrom(new short[]{ (short) 127, (short) 3, (short) 4, 0 });
+        script.forEach_clear_input_short3(ain, tmp);
+        script.invoke_verify_input_short3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_short4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.I16_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.I16_4(mRS), 1);
+
+        script.set_initial_value_short4(new Short4((short) 127, (short) 3, (short) 4, (short) 7));
+        ain.copyFrom(new short[]{ (short) 127, (short) 3, (short) 4, (short) 7 });
+        script.forEach_clear_input_short4(ain, tmp);
+        script.invoke_verify_input_short4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_uchar() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U8(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U8(mRS), 1);
+
+        script.set_initial_value_uchar((short) 6);
+        ain.copyFrom(new byte[]{ (byte) 6 });
+        script.forEach_clear_input_uchar(ain, tmp);
+        script.invoke_verify_input_uchar(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_uchar2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U8_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U8_2(mRS), 1);
+
+        script.set_initial_value_uchar2(new Short2((short) 127, (short) 3));
+        ain.copyFrom(new byte[]{ (byte) 127, (byte) 3 });
+        script.forEach_clear_input_uchar2(ain, tmp);
+        script.invoke_verify_input_uchar2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_uchar3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U8_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U8_3(mRS), 1);
+
+        script.set_initial_value_uchar3(new Short3((short) 127, (short) 3, (short) 4));
+        ain.copyFrom(new byte[]{ (byte) 127, (byte) 3, (byte) 4, 0 });
+        script.forEach_clear_input_uchar3(ain, tmp);
+        script.invoke_verify_input_uchar3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_uchar4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U8_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U8_4(mRS), 1);
+
+        script.set_initial_value_uchar4(new Short4((short) 127, (short) 3, (short) 4, (short) 7));
+        ain.copyFrom(new byte[]{ (byte) 127, (byte) 3, (byte) 4, (byte) 7 });
+        script.forEach_clear_input_uchar4(ain, tmp);
+        script.invoke_verify_input_uchar4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_uint() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U32(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U32(mRS), 1);
+
+        script.set_initial_value_uint((long) 6);
+        ain.copyFrom(new int[]{ 6 });
+        script.forEach_clear_input_uint(ain, tmp);
+        script.invoke_verify_input_uint(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_uint2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U32_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U32_2(mRS), 1);
+
+        script.set_initial_value_uint2(new Long2((long) 127, (long) 3));
+        ain.copyFrom(new int[]{ 127, 3 });
+        script.forEach_clear_input_uint2(ain, tmp);
+        script.invoke_verify_input_uint2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_uint3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U32_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U32_3(mRS), 1);
+
+        script.set_initial_value_uint3(new Long3((long) 127, (long) 3, (long) 4));
+        ain.copyFrom(new int[]{ 127, 3, 4, 0 });
+        script.forEach_clear_input_uint3(ain, tmp);
+        script.invoke_verify_input_uint3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_uint4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U32_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U32_4(mRS), 1);
+
+        script.set_initial_value_uint4(new Long4((long) 127, (long) 3, (long) 4, (long) 7));
+        ain.copyFrom(new int[]{ 127, 3, 4, 7 });
+        script.forEach_clear_input_uint4(ain, tmp);
+        script.invoke_verify_input_uint4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_ulong() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U64(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U64(mRS), 1);
+
+        script.set_initial_value_ulong((long) 6);
+        ain.copyFrom(new long[]{ (long) 6 });
+        script.forEach_clear_input_ulong(ain, tmp);
+        script.invoke_verify_input_ulong(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_ulong2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U64_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U64_2(mRS), 1);
+
+        script.set_initial_value_ulong2(new Long2((long) 127, (long) 3));
+        ain.copyFrom(new long[]{ (long) 127, (long) 3 });
+        script.forEach_clear_input_ulong2(ain, tmp);
+        script.invoke_verify_input_ulong2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_ulong3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U64_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U64_3(mRS), 1);
+
+        script.set_initial_value_ulong3(new Long3((long) 127, (long) 3, (long) 4));
+        ain.copyFrom(new long[]{ (long) 127, (long) 3, (long) 4, 0 });
+        script.forEach_clear_input_ulong3(ain, tmp);
+        script.invoke_verify_input_ulong3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_ulong4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U64_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U64_4(mRS), 1);
+
+        script.set_initial_value_ulong4(new Long4((long) 127, (long) 3, (long) 4, (long) 7));
+        ain.copyFrom(new long[]{ (long) 127, (long) 3, (long) 4, (long) 7 });
+        script.forEach_clear_input_ulong4(ain, tmp);
+        script.invoke_verify_input_ulong4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_ushort() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U16(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U16(mRS), 1);
+
+        script.set_initial_value_ushort(6);
+        ain.copyFrom(new short[]{ (short) 6 });
+        script.forEach_clear_input_ushort(ain, tmp);
+        script.invoke_verify_input_ushort(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_ushort2() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U16_2(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U16_2(mRS), 1);
+
+        script.set_initial_value_ushort2(new Int2(127, 3));
+        ain.copyFrom(new short[]{ (short) 127, (short) 3 });
+        script.forEach_clear_input_ushort2(ain, tmp);
+        script.invoke_verify_input_ushort2(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_ushort3() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U16_3(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U16_3(mRS), 1);
+
+        script.set_initial_value_ushort3(new Int3(127, 3, 4));
+        ain.copyFrom(new short[]{ (short) 127, (short) 3, (short) 4, 0 });
+        script.forEach_clear_input_ushort3(ain, tmp);
+        script.invoke_verify_input_ushort3(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputNotModified_ushort4() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+        Allocation ain = Allocation.createSized(mRS, Element.U16_4(mRS), 1);
+        Allocation tmp = Allocation.createSized(mRS, Element.U16_4(mRS), 1);
+
+        script.set_initial_value_ushort4(new Int4(127, 3, 4, 7));
+        ain.copyFrom(new short[]{ (short) 127, (short) 3, (short) 4, (short) 7 });
+        script.forEach_clear_input_ushort4(ain, tmp);
+        script.invoke_verify_input_ushort4(ain);
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputsNotModified_small() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+
+        Allocation tmp = Allocation.createSized(mRS, ScriptField_small.createElement(mRS), 1);
+        ScriptField_small item = new ScriptField_small(mRS, 1);
+
+        item.set_x(0, new int[]{6}, true);
+        script.set_initial_value_small(item.get(0));
+        script.forEach_clear_input_small(item.getAllocation(), tmp);
+        script.invoke_verify_input_small(item.getAllocation());
+
+        checkForErrorsInScript(script);
+    }
+
+    public void testInputsNotModified_big() {
+        ScriptC_kernel_input script = new ScriptC_kernel_input(mRS);
+
+        Allocation tmp = Allocation.createSized(mRS, ScriptField_big.createElement(mRS), 1);
+        ScriptField_big item = new ScriptField_big(mRS, 1);
+
+        for (int i = 0; i < 100; i++) {
+            int[] input = new int[100];
+
+            input[i] = 6;
+            item.set_x(0, input, true);
+            script.set_initial_value_big(item.get(0));
+            script.forEach_clear_input_big(item.getAllocation(), tmp);
+            script.invoke_verify_input_big(item.getAllocation());
+       }
+
+      checkForErrorsInScript(script);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java b/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java
index 64368b6..90d4fe9 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/KernelTest.java
@@ -475,8 +475,8 @@
         s.invoke_verify_foo();
         s.invoke_foreach_test();
         mRS.finish();
-        checkForErrors();
         waitForMessage();
+        checkForErrors();
     }
 
     public void testNoRoot() {
@@ -494,7 +494,7 @@
         s.invoke_verify_foo();
         s.invoke_noroot_test();
         mRS.finish();
-        checkForErrors();
         waitForMessage();
+        checkForErrors();
     }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/LaunchClip.java b/tests/tests/renderscript/src/android/renderscript/cts/LaunchClip.java
new file mode 100644
index 0000000..b87b705
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/LaunchClip.java
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+
+
+public class LaunchClip extends RSBaseCompute {
+    Allocation mAPassFail;
+    Allocation mAin;
+    Allocation mAout;
+    ScriptC_launchclip mScript;
+
+    int[] mIn;
+    int[] mOut;
+    int[] mPassFail;
+
+    int mDimX = 0;
+    int mDimY = 0;
+    int mDimZ = 0;
+    boolean mHasFaces = false;
+    boolean mHasLods = false;
+    int mDimA0 = 0;
+    int mDimA1 = 0;
+    int mDimA2 = 0;
+    int mDimA3 = 0;
+    int mCellCount = 0;
+
+    void setup(boolean makeIn, boolean makeOut, int x, int y, int z, boolean face, boolean lods,
+               int a0, int a1, int a2, int a3) {
+
+        mDimX = x;
+        mDimY = y;
+        mDimZ = z;
+        mHasFaces = face;
+        mHasLods = lods;
+        mDimA0 = a0;
+        mDimA1 = a1;
+        mDimA2 = a2;
+        mDimA3 = a3;
+
+        mScript = new ScriptC_launchclip(mRS);
+        mScript.set_dimX(mDimX);
+        mScript.set_dimY(mDimY);
+        mScript.set_dimZ(mDimZ);
+        mScript.set_hasFaces(mHasFaces);
+        mScript.set_hasLod(mHasLods);
+        mScript.set_dimA0(mDimA0);
+        mScript.set_dimA1(mDimA1);
+        mScript.set_dimA2(mDimA2);
+        mScript.set_dimA3(mDimA3);
+
+        Type.Builder tb = new Type.Builder(mRS, Element.I32(mRS));
+        tb.setX(mDimX);
+        if (mDimY > 0) tb.setY(mDimY);
+        if (mDimZ > 0) tb.setZ(mDimZ);
+        if (mHasFaces) tb.setFaces(true);
+        if (mHasLods) tb.setMipmaps(true);
+        //if (mDimA0 != 0) tb.setArray(0, mDimA0);
+        //if (mDimA1 != 0) tb.setArray(1, mDimA1);
+        //if (mDimA2 != 0) tb.setArray(2, mDimA2);
+        //if (mDimA3 != 0) tb.setArray(3, mDimA3);
+        Type t = tb.create();
+
+        if (makeIn) {
+            mIn = new int[t.getCount()];
+            mAin = Allocation.createTyped(mRS, t);
+            mScript.forEach_zero(mAin);
+        }
+        if (makeOut) {
+            mOut = new int[t.getCount()];
+            mAout = Allocation.createTyped(mRS, t);
+            mScript.forEach_zero(mAout);
+        }
+
+        mPassFail = new int[1];
+        mAPassFail = Allocation.createSized(mRS, Element.U32(mRS), 1);
+        mAPassFail.copyFrom(mPassFail);
+        mScript.set_passfail(mAPassFail);
+    }
+
+    private void verifyCell(int x, int y, int z, int[] a, Script.LaunchOptions sc) {
+        int expected = 0x80000000;
+        boolean inRange = true;
+
+        if (mDimX != 0) {
+            if (x >= sc.getXStart() && x < sc.getXEnd()) {
+                expected |= x;
+            } else {
+                inRange = false;
+            }
+        }
+
+        if (mDimY != 0) {
+            if (y >= sc.getYStart() && y < sc.getYEnd()) {
+                expected |= y << 8;
+            } else {
+                inRange = false;
+            }
+        }
+
+        if (mDimZ != 0) {
+            if (z >= sc.getZStart() && z < sc.getZEnd()) {
+                expected |= z << 16;
+            } else {
+                inRange = false;
+            }
+        }
+
+        if (!inRange) {
+            expected = 0;
+        }
+
+        int val = a[x + y * mDimX + z * mDimX * mDimY];
+        if (val != expected) {
+            String s = new String("verify error @ " + x + ", " + y + ", " + z +
+                                  ", expected " + expected + ", got " + val);
+            ///android.util.Log.e("rs", s);
+            throw new IllegalStateException(s);
+        }
+    }
+
+    void verifyRange(Script.LaunchOptions sc, int[] a) {
+        int itY = (mDimY > 0) ? mDimY : 1;
+        int itZ = (mDimZ > 0) ? mDimZ : 1;
+
+        for (int x = 0; x < mDimX; x++) {
+            for (int y = 0; y < itY; y++) {
+                for (int z = 0; z < itZ; z++) {
+                    verifyCell(x, y, z, a, sc);
+                }
+            }
+        }
+    }
+
+    AllocationAdapter makeAdapter(Allocation base, int ax, int ay, int az, int ox, int oy, int oz) {
+        Type.Builder tb = new Type.Builder(mRS, base.getType().getElement());
+        tb.setX(ax);
+        if (ay > 0) {
+            tb.setY(ay);
+        }
+        if (az > 0) {
+            tb.setZ(az);
+        }
+        Type t = tb.create();
+
+        AllocationAdapter a = AllocationAdapter.createTyped(mRS, base, t);
+        a.setX(ox);
+        if (base.getType().getY() > 0) {
+            a.setY(oy);
+        }
+        if (base.getType().getZ() > 0) {
+            a.setZ(oz);
+        }
+
+        mScript.set_biasX(ox);
+        mScript.set_biasY(oy);
+        mScript.set_biasZ(oz);
+        return a;
+    }
+
+    public void testWrite1D() {
+        setup(false, true, 256, 0, 0, false, false, 0, 0, 0, 0);
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(9, 77);
+
+        mScript.forEach_write1d(mAout, sc);
+        mAout.copyTo(mOut);
+
+        verifyRange(sc, mOut);
+    }
+
+    public void testWrite1DAdapter1D() {
+        setup(false, true, 256, 0, 0, false, false, 0, 0, 0, 0);
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(9, 77);
+
+        AllocationAdapter a = makeAdapter(mAout, 68, 0, 0,  9, 0, 0);
+        mScript.forEach_write1d(a);
+        mAout.copyTo(mOut);
+
+        verifyRange(sc, mOut);
+    }
+
+
+    public void testWrite2D() {
+        setup(false, true, 256, 256, 0, false, false, 0, 0, 0, 0);
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(9, 77);
+        sc.setY(17, 177);
+
+        mScript.forEach_write2d(mAout, sc);
+        mAout.copyTo(mOut);
+
+        verifyRange(sc, mOut);
+    }
+
+    public void testWrite2DAdapter1D() {
+        setup(false, true, 256, 256, 0, false, false, 0, 0, 0, 0);
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(9, 77);
+        sc.setY(17, 18);
+
+        AllocationAdapter a = makeAdapter(mAout, 68, 0, 0,  9, 17, 0);
+        mScript.forEach_write1d(a);
+        mAout.copyTo(mOut);
+
+        verifyRange(sc, mOut);
+    }
+
+    public void testWrite2DAdapter2D() {
+        setup(false, true, 256, 256, 0, false, false, 0, 0, 0, 0);
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(9, 77);
+        sc.setY(17, 177);
+
+        AllocationAdapter a = makeAdapter(mAout, 68, 160, 0,  9, 17, 0);
+        mScript.forEach_write2d(a);
+        mAout.copyTo(mOut);
+
+        verifyRange(sc, mOut);
+    }
+
+    public void testWrite3D() {
+        setup(false, true, 64, 64, 64, false, false, 0, 0, 0, 0);
+
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(9, 37);
+        sc.setY(17, 27);
+        sc.setZ(7, 21);
+        mScript.forEach_write3d(mAout, sc);
+        mAout.copyTo(mOut);
+
+        verifyRange(sc, mOut);
+    }
+
+    public void testWrite3DAdapter1D() {
+        setup(false, true, 64, 64, 64, false, false, 0, 0, 0, 0);
+
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(9, 37);
+        sc.setY(17, 18);
+        sc.setZ(7, 8);
+
+        AllocationAdapter a = makeAdapter(mAout, 28, 0, 0,  9, 17, 7);
+        mScript.forEach_write1d(a);
+        mAout.copyTo(mOut);
+
+        verifyRange(sc, mOut);
+    }
+
+    public void testWrite3DAdapter2D() {
+        setup(false, true, 64, 64, 64, false, false, 0, 0, 0, 0);
+
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(9, 37);
+        sc.setY(17, 27);
+        sc.setZ(7, 8);
+
+        AllocationAdapter a = makeAdapter(mAout, 28, 10, 0,  9, 17, 7);
+        mScript.forEach_write2d(a);
+        mAout.copyTo(mOut);
+
+        verifyRange(sc, mOut);
+    }
+
+    public void testWrite3DAdapter3D() {
+        setup(false, true, 64, 64, 64, false, false, 0, 0, 0, 0);
+
+        Script.LaunchOptions sc = new Script.LaunchOptions();
+        sc.setX(9, 37);
+        sc.setY(17, 27);
+        sc.setZ(7, 21);
+
+        AllocationAdapter a = makeAdapter(mAout, 28, 10, 14,  9, 17, 7);
+        mScript.forEach_write3d(a);
+        mAout.copyTo(mOut);
+
+        verifyRange(sc, mOut);
+    }
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/MatrixTest.rs b/tests/tests/renderscript/src/android/renderscript/cts/MatrixTest.rs
index f1dbc64..a71deef 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/MatrixTest.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/MatrixTest.rs
@@ -268,11 +268,13 @@
   const float2 f2r = rsMatrixMultiply(&m2, f2);
   const float3 f3r = rsMatrixMultiply(&m3, f3);
   const float4 f4r = rsMatrixMultiply(&m4, f4);
+  const float4 f3m4r = rsMatrixMultiply(&m4, f3);
 
   // rsMatrixMultiply returns (matrix * vector)
   const float2 f2rExpectedValues = { 14.f, 24.f };
   const float3 f3rExpectedValues = { 21.f, 31.f, 41.f };
   const float4 f4rExpectedValues = {168.f, 298.f, 428.f, 558.f};
+  const float4 f3m4rExpectedValues = {35.0, 55.0, 75.0, 95.0};
 
   for (int row = 0; row < 2; row++) {
     EXPECT(row, 0, f2r[row], f2rExpectedValues[row]);
@@ -286,6 +288,10 @@
     EXPECT(row, 0, f4r[row], f4rExpectedValues[row]);
   }
 
+  for (int row = 0; row < 4; row++) {
+    EXPECT(row, 0, f3m4r[row], f3m4rExpectedValues[row]);
+  }
+
   return failed;
 }
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java
index ebf15dc..2ca4f13 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBase.java
@@ -34,10 +34,13 @@
     Resources mRes;
 
     private int result;
-    private boolean msgHandled;
+    // msgHandled is used to synchronize between waitForMessage() and the
+    // RSMessageHandler thread.
+    private volatile boolean msgHandled;
 
-    private static final int RS_MSG_TEST_PASSED = 100;
-    private static final int RS_MSG_TEST_FAILED = 101;
+    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() {
@@ -47,6 +50,8 @@
                     case RS_MSG_TEST_FAILED:
                         result = mID;
                         break;
+                    case RS_MSG_TEST_FLUSH:
+                        break;
                     default:
                         fail("Got unexpected RS message");
                         return;
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
index 0413f22..0ba8248 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/RSBaseCompute.java
@@ -39,10 +39,6 @@
 
     @Override
     protected void tearDown() throws Exception {
-        if (mRS != null) {
-            mRS.destroy();
-            mRS = null;
-        }
         super.tearDown();
     }
 
@@ -388,4 +384,22 @@
     public void forEach(int testId, Allocation mIn) throws RSRuntimeException {
         // Intentionally empty... subclass will likely define only one, but not both
     }
+
+    protected void appendVariableToMessage(StringBuilder message, int value) {
+        message.append(String.format("%d {%x}", value, value));
+    }
+
+    protected void appendVariableToMessage(StringBuilder message, float value) {
+        message.append(String.format("%14.8g {%8x} %15a", value,
+                        Float.floatToRawIntBits(value), value));
+    }
+
+    protected void appendVariableToMessage(StringBuilder message, double value) {
+        message.append(String.format("%24.8g {%16x} %31a", value,
+                        Double.doubleToRawLongBits(value), value));
+    }
+
+    protected void appendVariableToMessage(StringBuilder message, Target.Floaty value) {
+        message.append(value.toString());
+    }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/SampleTest.java b/tests/tests/renderscript/src/android/renderscript/cts/SampleTest.java
index bc69b0e..a468b9f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/SampleTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/SampleTest.java
@@ -92,8 +92,8 @@
     public void testNearest() {
         mScript.invoke_test_RGBA(mAlloc_RGBA_1D, mAlloc_RGBA_2D);
         mRS.finish();
-        checkForErrors();
         waitForMessage();
+        checkForErrors();
     }
 }
 
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java
index d44c305..a52d308 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ScriptGroupTest.java
@@ -34,6 +34,8 @@
 
 public class ScriptGroupTest extends RSBaseCompute {
 
+    private static final String TAG = "ScriptGroupTest";
+    private static final int ARRAY_SIZE = 256;
     static int bDimX = 48;
     static int bDimY = 8;
 
@@ -309,4 +311,242 @@
 
         checkForErrors();
     }
+
+    /**
+     * Tests that kernel-to-kernel dependency via input/output is handled correctly
+     */
+    public void testBuilder2PointWiseKernelToKernelDependency() {
+        ScriptC_increment s_inc = new ScriptC_increment(mRS);
+        ScriptC_double s_double = new ScriptC_double(mRS);
+        mRS.setMessageHandler(mRsMessage);
+
+        int[] array = new int[ARRAY_SIZE * 4];
+
+        for (int i = 0; i < ARRAY_SIZE * 4; i++) {
+            array[i] = i;
+        }
+
+        Allocation input = Allocation.createSized(mRS, Element.I32_4(mRS), ARRAY_SIZE);
+        input.copyFrom(array);
+
+        ScriptGroup.Builder2 builder = new ScriptGroup.Builder2(mRS);
+
+        ScriptGroup.Input unbound = builder.addInput();
+
+        Type connectType = Type.createX(mRS, Element.I32_4(mRS), ARRAY_SIZE);
+
+        ScriptGroup.Closure c0 =
+                builder.addKernel(s_inc.getKernelID_increment(),
+                                  connectType,
+                                  unbound);
+
+        ScriptGroup.Closure c1 =
+                builder.addKernel(s_double.getKernelID_doubleKernel(),
+                                  connectType,
+                                  c0.getReturn());
+
+        ScriptGroup group = builder.create("IncAndDbl", c1.getReturn());
+
+        int[] a = new int[ARRAY_SIZE * 4];
+        ((Allocation)group.execute(input)[0]).copyTo(a);
+
+        mRS.finish();
+
+        boolean failed = false;
+        for (int i = 0; i < ARRAY_SIZE * 4; i++) {
+            if (a[i] != (i+1) * 2) {
+                Log.e(TAG, "a["+i+"]="+a[i]+", should be "+ ((i+1) * 2));
+                failed = true;
+            }
+        }
+
+        assertTrue(!failed);
+    }
+
+    /**
+     * Tests that kernel-to-kernel dependency via global allocations is handled correctly
+     */
+    public void testBuilder2GatherScatterAcrossKernelsViaGlobals() {
+        ScriptC_reduction s = new ScriptC_reduction(mRS);
+
+        int[] array = new int[ARRAY_SIZE * 4];
+
+        for (int i = 0; i < ARRAY_SIZE; i++) {
+            array[i*4] = i * 7;
+            array[i*4 + 1] = i * 7;
+            array[i*4 + 2] = i * 7;
+            array[i*4 + 3] = i * 7;
+        }
+
+        Allocation input = Allocation.createSized(mRS, Element.I32_4(mRS), ARRAY_SIZE);
+        input.copyFrom(array);
+
+        ScriptGroup.Builder2 builder = new ScriptGroup.Builder2(mRS);
+
+        ScriptGroup.Input unbound = builder.addInput();
+
+        ScriptGroup.Closure c = null;
+        ScriptGroup.Binding b2 = new ScriptGroup.Binding(s.getFieldID_a(), unbound);
+        for (int stride = ARRAY_SIZE / 2; stride >= 1; stride >>= 1) {
+            ScriptGroup.Binding b1 = new ScriptGroup.Binding(s.getFieldID_reduction_stride(),
+                                                             stride);
+            c = builder.addKernel(s.getKernelID_add(),
+                                  Type.createX(mRS, Element.I32_4(mRS), stride),
+                                  b1, b2);
+            b2 = new ScriptGroup.Binding(s.getFieldID_a(), c.getReturn());
+        }
+
+        if (c == null) {
+            return;
+        }
+
+        ScriptGroup group = builder.create("Summation", c.getReturn());
+
+        int[] a = new int[4];
+        ((Allocation)group.execute(input)[0]).copyTo(a);
+
+        mRS.finish();
+
+        boolean failed = false;
+        for (int i = 0; i < 4; i++) {
+            if (failed == false && a[i] != ARRAY_SIZE * (ARRAY_SIZE - 1) * 7 / 2) {
+                Log.e(TAG,
+                      "a["+i+"]="+a[i]+", should be "+ (ARRAY_SIZE * (ARRAY_SIZE - 1) * 7 / 2));
+                failed = true;
+            }
+        }
+
+        assertTrue(!failed);
+    }
+
+    /**
+     * Tests that the kernel output to a global can be used as a future
+     */
+    public void testBuilder2KernelOutputToGlobal() {
+        ScriptC_reduction s = new ScriptC_reduction(mRS);
+
+        int[] array = new int[ARRAY_SIZE * 4];
+
+        for (int i = 0; i < ARRAY_SIZE; i++) {
+            array[i*4] = i;
+            array[i*4 + 1] = i;
+            array[i*4 + 2] = i;
+            array[i*4 + 3] = i;
+        }
+
+        Allocation input = Allocation.createSized(mRS, Element.I32_4(mRS), ARRAY_SIZE);
+        input.copyFrom(array);
+        Allocation input1 = Allocation.createSized(mRS, Element.I32_4(mRS), ARRAY_SIZE);
+
+        ScriptGroup.Builder2 builder = new ScriptGroup.Builder2(mRS);
+
+        ScriptGroup.Input unbound = builder.addInput();
+
+        ScriptGroup.Closure c = null;
+        ScriptGroup.Binding b2 = new ScriptGroup.Binding(s.getFieldID_a(), unbound);
+        for (int stride = ARRAY_SIZE / 2; stride >= 1; stride >>= 1) {
+            ScriptGroup.Binding b1 = new ScriptGroup.Binding(s.getFieldID_reduction_stride(),
+                                                             stride);
+            c = builder.addKernel(s.getKernelID_add2(),
+                                  Type.createX(mRS, Element.I32_4(mRS), stride),
+                                  b1, b2);
+            b2 = new ScriptGroup.Binding(s.getFieldID_a(),
+                                         c.getGlobal(s.getFieldID_a()));
+        }
+
+        if (c == null) {
+            return;
+        }
+
+        ScriptGroup group = builder.create("SummationGlobal", c.getGlobal(s.getFieldID_a()));
+
+        int[] a = new int[4 * ARRAY_SIZE];
+        ((Allocation)group.execute(input, input1)[0]).copyTo(a);
+
+        mRS.finish();
+
+        boolean failed = false;
+        for (int i = 0; i < 4; i++) {
+            if (failed == false && a[i] != ARRAY_SIZE * (ARRAY_SIZE - 1) / 2) {
+                Log.e(TAG,
+                      "a["+i+"]="+a[i]+", should be "+ (ARRAY_SIZE * (ARRAY_SIZE - 1) / 2));
+                failed = true;
+            }
+        }
+
+        assertTrue(!failed);
+    }
+
+    /**
+     * Tests that invoke-to-kernel dependency is handled correctly
+     */
+    public void testBuilder2InvokeToKernelDependency() {
+        ScriptC_matrix s = new ScriptC_matrix(mRS);
+
+        float[] array = new float[ARRAY_SIZE * 4];
+
+        for (int i = 0; i < ARRAY_SIZE; i++) {
+            array[i * 4] = i * 4 * 7;
+            array[i * 4 + 1] = (i * 4 + 1) * 7;
+            array[i * 4 + 2] = (i * 4 + 2) * 7;
+            array[i * 4 + 3] = (i * 4 + 3) * 7;
+        }
+
+        Allocation input = Allocation.createSized(mRS, Element.F32_4(mRS), ARRAY_SIZE);
+        input.copyFrom(array);
+
+        ScriptGroup.Builder2 builder = new ScriptGroup.Builder2(mRS);
+
+        ScriptGroup.Input unbound = builder.addInput();
+
+        Matrix4f mat = new Matrix4f();
+
+        mat.set(0, 0, 0.0f);
+        mat.set(0, 1, 0.0f);
+        mat.set(0, 2, 0.0f);
+        mat.set(0, 3, 1.0f);
+
+        mat.set(1, 0, 1.0f);
+        mat.set(1, 1, 0.0f);
+        mat.set(1, 2, 0.0f);
+        mat.set(1, 3, 0.0f);
+
+        mat.set(2, 0, 0.0f);
+        mat.set(2, 1, 1.0f);
+        mat.set(2, 2, 0.0f);
+        mat.set(2, 3, 0.0f);
+
+        mat.set(3, 0, 0.0f);
+        mat.set(3, 1, 0.0f);
+        mat.set(3, 2, 1.0f);
+        mat.set(3, 3, 0.0f);
+
+        ScriptGroup.Closure c1 =
+                builder.addInvoke(s.getInvokeID_setMatrix(), mat);
+
+        ScriptGroup.Closure c2 =
+                builder.addKernel(s.getKernelID_multiply(),
+                                  Type.createX(mRS, Element.F32_4(mRS), ARRAY_SIZE),
+                                  unbound);
+
+        ScriptGroup group = builder.create("Multiply", c2.getReturn());
+
+        float[] a = new float[ARRAY_SIZE * 4];
+        ((Allocation)group.execute(input)[0]).copyTo(a);
+
+        mRS.finish();
+
+        boolean failed = false;
+        for (int i = 0; i < ARRAY_SIZE; i++) {
+            for (int j = 0; j < 4; j++) {
+                float expected = (i*4+((j+1)%4))*7;
+                if (failed == false && a[i * 4 + j] != expected) {
+                    Log.e(TAG, "a["+i+"]="+a[i]+", should be "+ expected);
+                    failed = true;
+                }
+            }
+        }
+
+        assertTrue(!failed);
+    }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAbs.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAbs.java
deleted file mode 100644
index 6b3914c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAbs.java
+++ /dev/null
@@ -1,738 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAbs extends RSBaseCompute {
-
-    private ScriptC_TestAbs script;
-    private ScriptC_TestAbsRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAbs(mRS);
-        scriptRelaxed = new ScriptC_TestAbsRelaxed(mRS);
-    }
-
-    public class ArgumentsCharUchar {
-        public byte inValue;
-        public byte out;
-    }
-
-    private void checkAbsCharUchar() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x4c0d03eb0d0c5a91l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            script.forEach_testAbsCharUchar(inValue, out);
-            verifyResultsAbsCharUchar(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsCharUchar: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsCharUchar(inValue, out);
-            verifyResultsAbsCharUchar(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsCharUchar: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsCharUchar(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUchar args = new ArgumentsCharUchar();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsCharUchar" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAbsChar2Uchar2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x901d551e7f67bb87l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testAbsChar2Uchar2(inValue, out);
-            verifyResultsAbsChar2Uchar2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsChar2Uchar2(inValue, out);
-            verifyResultsAbsChar2Uchar2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsChar2Uchar2(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUchar args = new ArgumentsCharUchar();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsChar2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAbsChar3Uchar3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xb5d1caa5c8a5e105l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testAbsChar3Uchar3(inValue, out);
-            verifyResultsAbsChar3Uchar3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsChar3Uchar3(inValue, out);
-            verifyResultsAbsChar3Uchar3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsChar3Uchar3(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUchar args = new ArgumentsCharUchar();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsChar3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAbsChar4Uchar4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xdb86402d11e40683l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testAbsChar4Uchar4(inValue, out);
-            verifyResultsAbsChar4Uchar4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsChar4Uchar4(inValue, out);
-            verifyResultsAbsChar4Uchar4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsChar4Uchar4(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUchar args = new ArgumentsCharUchar();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsChar4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortUshort {
-        public short inValue;
-        public short out;
-    }
-
-    private void checkAbsShortUshort() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xaead1a96b6ea02a7l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            script.forEach_testAbsShortUshort(inValue, out);
-            verifyResultsAbsShortUshort(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShortUshort: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsShortUshort(inValue, out);
-            verifyResultsAbsShortUshort(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShortUshort: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsShortUshort(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUshort args = new ArgumentsShortUshort();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsShortUshort" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAbsShort2Ushort2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x41a1894ff6b0da9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testAbsShort2Ushort2(inValue, out);
-            verifyResultsAbsShort2Ushort2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsShort2Ushort2(inValue, out);
-            verifyResultsAbsShort2Ushort2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsShort2Ushort2(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUshort args = new ArgumentsShortUshort();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsShort2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAbsShort3Ushort3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x5969cbec377ba515l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testAbsShort3Ushort3(inValue, out);
-            verifyResultsAbsShort3Ushort3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsShort3Ushort3(inValue, out);
-            verifyResultsAbsShort3Ushort3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsShort3Ushort3(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUshort args = new ArgumentsShortUshort();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsShort3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAbsShort4Ushort4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xaeb97f436f8c3c81l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testAbsShort4Ushort4(inValue, out);
-            verifyResultsAbsShort4Ushort4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsShort4Ushort4(inValue, out);
-            verifyResultsAbsShort4Ushort4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsShort4Ushort4(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUshort args = new ArgumentsShortUshort();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsShort4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntUint {
-        public int inValue;
-        public int out;
-    }
-
-    private void checkAbsIntUint() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xcda40fd4fa1abbd1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            script.forEach_testAbsIntUint(inValue, out);
-            verifyResultsAbsIntUint(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsIntUint: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsIntUint(inValue, out);
-            verifyResultsAbsIntUint(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsIntUint: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsIntUint(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUint args = new ArgumentsIntUint();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsIntUint" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAbsInt2Uint2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x71326739aabbb4a5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testAbsInt2Uint2(inValue, out);
-            verifyResultsAbsInt2Uint2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsInt2Uint2(inValue, out);
-            verifyResultsAbsInt2Uint2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsInt2Uint2(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUint args = new ArgumentsIntUint();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsInt2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAbsInt3Uint3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x9bbf87f7a6fae959l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testAbsInt3Uint3(inValue, out);
-            verifyResultsAbsInt3Uint3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsInt3Uint3(inValue, out);
-            verifyResultsAbsInt3Uint3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsInt3Uint3(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUint args = new ArgumentsIntUint();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsInt3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAbsInt4Uint4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xc64ca8b5a33a1e0dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testAbsInt4Uint4(inValue, out);
-            verifyResultsAbsInt4Uint4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAbsInt4Uint4(inValue, out);
-            verifyResultsAbsInt4Uint4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAbsInt4Uint4(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUint args = new ArgumentsIntUint();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeAbs(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAbsInt4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAbs() {
-        checkAbsCharUchar();
-        checkAbsChar2Uchar2();
-        checkAbsChar3Uchar3();
-        checkAbsChar4Uchar4();
-        checkAbsShortUshort();
-        checkAbsShort2Ushort2();
-        checkAbsShort3Ushort3();
-        checkAbsShort4Ushort4();
-        checkAbsIntUint();
-        checkAbsInt2Uint2();
-        checkAbsInt3Uint3();
-        checkAbsInt4Uint4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAbs.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAbs.rs
deleted file mode 100644
index 8f1747e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAbs.rs
+++ /dev/null
@@ -1,69 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-uchar __attribute__((kernel)) testAbsCharUchar(char inValue) {
-    return abs(inValue);
-}
-
-uchar2 __attribute__((kernel)) testAbsChar2Uchar2(char2 inValue) {
-    return abs(inValue);
-}
-
-uchar3 __attribute__((kernel)) testAbsChar3Uchar3(char3 inValue) {
-    return abs(inValue);
-}
-
-uchar4 __attribute__((kernel)) testAbsChar4Uchar4(char4 inValue) {
-    return abs(inValue);
-}
-
-ushort __attribute__((kernel)) testAbsShortUshort(short inValue) {
-    return abs(inValue);
-}
-
-ushort2 __attribute__((kernel)) testAbsShort2Ushort2(short2 inValue) {
-    return abs(inValue);
-}
-
-ushort3 __attribute__((kernel)) testAbsShort3Ushort3(short3 inValue) {
-    return abs(inValue);
-}
-
-ushort4 __attribute__((kernel)) testAbsShort4Ushort4(short4 inValue) {
-    return abs(inValue);
-}
-
-uint __attribute__((kernel)) testAbsIntUint(int inValue) {
-    return abs(inValue);
-}
-
-uint2 __attribute__((kernel)) testAbsInt2Uint2(int2 inValue) {
-    return abs(inValue);
-}
-
-uint3 __attribute__((kernel)) testAbsInt3Uint3(int3 inValue) {
-    return abs(inValue);
-}
-
-uint4 __attribute__((kernel)) testAbsInt4Uint4(int4 inValue) {
-    return abs(inValue);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAbsRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAbsRelaxed.rs
deleted file mode 100644
index 437a467..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAbsRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAbs.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcos.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAcos.java
deleted file mode 100644
index 999fd1b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAcos.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAcos extends RSBaseCompute {
-
-    private ScriptC_TestAcos script;
-    private ScriptC_TestAcosRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAcos(mRS);
-        scriptRelaxed = new ScriptC_TestAcosRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkAcosFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf6e893f6d1cc3bdfl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testAcosFloatFloat(inV, out);
-            verifyResultsAcosFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAcosFloatFloat(inV, out);
-            verifyResultsAcosFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcosFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcosFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAcosFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x55af66f81096ae8bl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testAcosFloat2Float2(inV, out);
-            verifyResultsAcosFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAcosFloat2Float2(inV, out);
-            verifyResultsAcosFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcosFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcosFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAcosFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x55b1301306b1cf69l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testAcosFloat3Float3(inV, out);
-            verifyResultsAcosFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAcosFloat3Float3(inV, out);
-            verifyResultsAcosFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcosFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcosFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAcosFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x55b2f92dfcccf047l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testAcosFloat4Float4(inV, out);
-            verifyResultsAcosFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAcosFloat4Float4(inV, out);
-            verifyResultsAcosFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcosFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcosFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAcos() {
-        checkAcosFloatFloat();
-        checkAcosFloat2Float2();
-        checkAcosFloat3Float3();
-        checkAcosFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcos.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAcos.rs
deleted file mode 100644
index ccf273e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAcos.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testAcosFloatFloat(float inV) {
-    return acos(inV);
-}
-
-float2 __attribute__((kernel)) testAcosFloat2Float2(float2 inV) {
-    return acos(inV);
-}
-
-float3 __attribute__((kernel)) testAcosFloat3Float3(float3 inV) {
-    return acos(inV);
-}
-
-float4 __attribute__((kernel)) testAcosFloat4Float4(float4 inV) {
-    return acos(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAcosRelaxed.rs
deleted file mode 100644
index 92fd9e87..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAcosRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAcos.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcosh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAcosh.java
deleted file mode 100644
index 1412c2e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAcosh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAcosh extends RSBaseCompute {
-
-    private ScriptC_TestAcosh script;
-    private ScriptC_TestAcoshRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAcosh(mRS);
-        scriptRelaxed = new ScriptC_TestAcoshRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkAcoshFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb2c74105f8e94ea7l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testAcoshFloatFloat(in, out);
-            verifyResultsAcoshFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAcoshFloatFloat(in, out);
-            verifyResultsAcoshFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcoshFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcoshFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAcoshFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4123c61e7e518f4bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testAcoshFloat2Float2(in, out);
-            verifyResultsAcoshFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAcoshFloat2Float2(in, out);
-            verifyResultsAcoshFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcoshFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcoshFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAcoshFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4123d0bfdd5824e5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testAcoshFloat3Float3(in, out);
-            verifyResultsAcoshFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAcoshFloat3Float3(in, out);
-            verifyResultsAcoshFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcoshFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcoshFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAcoshFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4123db613c5eba7fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testAcoshFloat4Float4(in, out);
-            verifyResultsAcoshFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAcoshFloat4Float4(in, out);
-            verifyResultsAcoshFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcoshFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcoshFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAcosh() {
-        checkAcoshFloatFloat();
-        checkAcoshFloat2Float2();
-        checkAcoshFloat3Float3();
-        checkAcoshFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAcosh.rs
deleted file mode 100644
index 9be2fa2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAcosh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testAcoshFloatFloat(float in) {
-    return acosh(in);
-}
-
-float2 __attribute__((kernel)) testAcoshFloat2Float2(float2 in) {
-    return acosh(in);
-}
-
-float3 __attribute__((kernel)) testAcoshFloat3Float3(float3 in) {
-    return acosh(in);
-}
-
-float4 __attribute__((kernel)) testAcoshFloat4Float4(float4 in) {
-    return acosh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcoshRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAcoshRelaxed.rs
deleted file mode 100644
index 269cec5..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAcoshRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAcosh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcospi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAcospi.java
deleted file mode 100644
index 7669fea..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAcospi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAcospi extends RSBaseCompute {
-
-    private ScriptC_TestAcospi script;
-    private ScriptC_TestAcospiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAcospi(mRS);
-        scriptRelaxed = new ScriptC_TestAcospiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkAcospiFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9fbdc3b5d1e084b2l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testAcospiFloatFloat(inV, out);
-            verifyResultsAcospiFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAcospiFloatFloat(inV, out);
-            verifyResultsAcospiFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcospiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcospiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAcospiFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc175417fa318aa86l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testAcospiFloat2Float2(inV, out);
-            verifyResultsAcospiFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAcospiFloat2Float2(inV, out);
-            verifyResultsAcospiFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcospiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcospiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAcospiFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc1770a9a9933cb64l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testAcospiFloat3Float3(inV, out);
-            verifyResultsAcospiFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAcospiFloat3Float3(inV, out);
-            verifyResultsAcospiFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcospiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcospiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAcospiFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc178d3b58f4eec42l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testAcospiFloat4Float4(inV, out);
-            verifyResultsAcospiFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAcospiFloat4Float4(inV, out);
-            verifyResultsAcospiFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAcospiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAcospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAcospiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAcospi() {
-        checkAcospiFloatFloat();
-        checkAcospiFloat2Float2();
-        checkAcospiFloat3Float3();
-        checkAcospiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAcospi.rs
deleted file mode 100644
index b29cff7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAcospi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testAcospiFloatFloat(float inV) {
-    return acospi(inV);
-}
-
-float2 __attribute__((kernel)) testAcospiFloat2Float2(float2 inV) {
-    return acospi(inV);
-}
-
-float3 __attribute__((kernel)) testAcospiFloat3Float3(float3 inV) {
-    return acospi(inV);
-}
-
-float4 __attribute__((kernel)) testAcospiFloat4Float4(float4 inV) {
-    return acospi(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAcospiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAcospiRelaxed.rs
deleted file mode 100644
index 203fe7e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAcospiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAcospi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAsin.java
deleted file mode 100644
index ce728e7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAsin.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAsin extends RSBaseCompute {
-
-    private ScriptC_TestAsin script;
-    private ScriptC_TestAsinRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAsin(mRS);
-        scriptRelaxed = new ScriptC_TestAsinRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkAsinFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x80b5674ff98b5a12l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testAsinFloatFloat(inV, out);
-            verifyResultsAsinFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinFloatFloat(inV, out);
-            verifyResultsAsinFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAsinFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9e11e5e823f7cce6l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testAsinFloat2Float2(inV, out);
-            verifyResultsAsinFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinFloat2Float2(inV, out);
-            verifyResultsAsinFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAsinFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9e13af031a12edc4l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testAsinFloat3Float3(inV, out);
-            verifyResultsAsinFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinFloat3Float3(inV, out);
-            verifyResultsAsinFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAsinFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9e15781e102e0ea2l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testAsinFloat4Float4(inV, out);
-            verifyResultsAsinFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinFloat4Float4(inV, out);
-            verifyResultsAsinFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAsin() {
-        checkAsinFloatFloat();
-        checkAsinFloat2Float2();
-        checkAsinFloat3Float3();
-        checkAsinFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsin.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAsin.rs
deleted file mode 100644
index 43e6940..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAsin.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testAsinFloatFloat(float inV) {
-    return asin(inV);
-}
-
-float2 __attribute__((kernel)) testAsinFloat2Float2(float2 inV) {
-    return asin(inV);
-}
-
-float3 __attribute__((kernel)) testAsinFloat3Float3(float3 inV) {
-    return asin(inV);
-}
-
-float4 __attribute__((kernel)) testAsinFloat4Float4(float4 inV) {
-    return asin(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinRelaxed.rs
deleted file mode 100644
index f972148..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAsin.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinh.java
deleted file mode 100644
index 90c26a0..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAsinh extends RSBaseCompute {
-
-    private ScriptC_TestAsinh script;
-    private ScriptC_TestAsinhRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAsinh(mRS);
-        scriptRelaxed = new ScriptC_TestAsinhRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkAsinhFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3c94145f20a86cdal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testAsinhFloatFloat(in, out);
-            verifyResultsAsinhFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinhFloatFloat(in, out);
-            verifyResultsAsinhFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinhFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAsinhFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8986450e91b2ada6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testAsinhFloat2Float2(in, out);
-            verifyResultsAsinhFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinhFloat2Float2(in, out);
-            verifyResultsAsinhFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinhFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAsinhFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x89864faff0b94340l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testAsinhFloat3Float3(in, out);
-            verifyResultsAsinhFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinhFloat3Float3(in, out);
-            verifyResultsAsinhFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinhFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAsinhFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x89865a514fbfd8dal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testAsinhFloat4Float4(in, out);
-            verifyResultsAsinhFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinhFloat4Float4(in, out);
-            verifyResultsAsinhFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinhFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAsinh() {
-        checkAsinhFloatFloat();
-        checkAsinhFloat2Float2();
-        checkAsinhFloat3Float3();
-        checkAsinhFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinh.rs
deleted file mode 100644
index a72a5f4..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testAsinhFloatFloat(float in) {
-    return asinh(in);
-}
-
-float2 __attribute__((kernel)) testAsinhFloat2Float2(float2 in) {
-    return asinh(in);
-}
-
-float3 __attribute__((kernel)) testAsinhFloat3Float3(float3 in) {
-    return asinh(in);
-}
-
-float4 __attribute__((kernel)) testAsinhFloat4Float4(float4 in) {
-    return asinh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinhRelaxed.rs
deleted file mode 100644
index 7540ea8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinhRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAsinh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpi.java
deleted file mode 100644
index 50bc387..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAsinpi extends RSBaseCompute {
-
-    private ScriptC_TestAsinpi script;
-    private ScriptC_TestAsinpiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAsinpi(mRS);
-        scriptRelaxed = new ScriptC_TestAsinpiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkAsinpiFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe82042a5e541a30dl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testAsinpiFloatFloat(inV, out);
-            verifyResultsAsinpiFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinpiFloatFloat(inV, out);
-            verifyResultsAsinpiFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinpiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAsinpiFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x90dc157b9b8ce9c9l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testAsinpiFloat2Float2(inV, out);
-            verifyResultsAsinpiFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinpiFloat2Float2(inV, out);
-            verifyResultsAsinpiFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinpiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAsinpiFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x90ddde9691a80aa7l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testAsinpiFloat3Float3(inV, out);
-            verifyResultsAsinpiFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinpiFloat3Float3(inV, out);
-            verifyResultsAsinpiFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinpiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAsinpiFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x90dfa7b187c32b85l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testAsinpiFloat4Float4(inV, out);
-            verifyResultsAsinpiFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAsinpiFloat4Float4(inV, out);
-            verifyResultsAsinpiFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAsinpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAsinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAsinpiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAsinpi() {
-        checkAsinpiFloatFloat();
-        checkAsinpiFloat2Float2();
-        checkAsinpiFloat3Float3();
-        checkAsinpiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpi.rs
deleted file mode 100644
index 112f722..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testAsinpiFloatFloat(float inV) {
-    return asinpi(inV);
-}
-
-float2 __attribute__((kernel)) testAsinpiFloat2Float2(float2 inV) {
-    return asinpi(inV);
-}
-
-float3 __attribute__((kernel)) testAsinpiFloat3Float3(float3 inV) {
-    return asinpi(inV);
-}
-
-float4 __attribute__((kernel)) testAsinpiFloat4Float4(float4 inV) {
-    return asinpi(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpiRelaxed.rs
deleted file mode 100644
index aad672b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAsinpiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAsinpi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan.java
deleted file mode 100644
index 1d7055c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAtan extends RSBaseCompute {
-
-    private ScriptC_TestAtan script;
-    private ScriptC_TestAtanRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAtan(mRS);
-        scriptRelaxed = new ScriptC_TestAtanRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkAtanFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2a9ae39592004c8dl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testAtanFloatFloat(inV, out);
-            verifyResultsAtanFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanFloatFloat(inV, out);
-            verifyResultsAtanFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtanFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb890789248a32749l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testAtanFloat2Float2(inV, out);
-            verifyResultsAtanFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanFloat2Float2(inV, out);
-            verifyResultsAtanFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtanFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xb89241ad3ebe4827l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testAtanFloat3Float3(inV, out);
-            verifyResultsAtanFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanFloat3Float3(inV, out);
-            verifyResultsAtanFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtanFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb8940ac834d96905l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testAtanFloat4Float4(inV, out);
-            verifyResultsAtanFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanFloat4Float4(inV, out);
-            verifyResultsAtanFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAtan() {
-        checkAtanFloatFloat();
-        checkAtanFloat2Float2();
-        checkAtanFloat3Float3();
-        checkAtanFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan.rs
deleted file mode 100644
index 36d3814..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testAtanFloatFloat(float inV) {
-    return atan(inV);
-}
-
-float2 __attribute__((kernel)) testAtanFloat2Float2(float2 inV) {
-    return atan(inV);
-}
-
-float3 __attribute__((kernel)) testAtanFloat3Float3(float3 inV) {
-    return atan(inV);
-}
-
-float4 __attribute__((kernel)) testAtanFloat4Float4(float4 inV) {
-    return atan(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2.java
deleted file mode 100644
index 10b862d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAtan2 extends RSBaseCompute {
-
-    private ScriptC_TestAtan2 script;
-    private ScriptC_TestAtan2Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAtan2(mRS);
-        scriptRelaxed = new ScriptC_TestAtan2Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inY;
-        public float inX;
-        public Target.Floaty out;
-    }
-
-    private void checkAtan2FloatFloatFloat() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8f58f1f953c03c32l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8f58f1f953c03c31l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testAtan2FloatFloatFloat(inY, out);
-            verifyResultsAtan2FloatFloatFloat(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2FloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testAtan2FloatFloatFloat(inY, out);
-            verifyResultsAtan2FloatFloatFloat(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2FloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtan2FloatFloatFloat(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i];
-                args.inX = arrayInX[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtan2FloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtan2Float2Float2Float2() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbe78dcdcd414b6c0l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbe78dcdcd414b6bfl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testAtan2Float2Float2Float2(inY, out);
-            verifyResultsAtan2Float2Float2Float2(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testAtan2Float2Float2Float2(inY, out);
-            verifyResultsAtan2Float2Float2Float2(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtan2Float2Float2Float2(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 2 + j];
-                args.inX = arrayInX[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtan2Float2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtan2Float3Float3Float3() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x12ddbafcd5f2b861l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x12ddbafcd5f2b860l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testAtan2Float3Float3Float3(inY, out);
-            verifyResultsAtan2Float3Float3Float3(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testAtan2Float3Float3Float3(inY, out);
-            verifyResultsAtan2Float3Float3Float3(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtan2Float3Float3Float3(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 4 + j];
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtan2Float3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtan2Float4Float4Float4() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6742991cd7d0ba02l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6742991cd7d0ba01l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testAtan2Float4Float4Float4(inY, out);
-            verifyResultsAtan2Float4Float4Float4(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testAtan2Float4Float4Float4(inY, out);
-            verifyResultsAtan2Float4Float4Float4(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtan2Float4Float4Float4(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 4 + j];
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtan2Float4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAtan2() {
-        checkAtan2FloatFloatFloat();
-        checkAtan2Float2Float2Float2();
-        checkAtan2Float3Float3Float3();
-        checkAtan2Float4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2.rs
deleted file mode 100644
index 877402d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInX;
-
-float __attribute__((kernel)) testAtan2FloatFloatFloat(float inY, unsigned int x) {
-    float inX = rsGetElementAt_float(gAllocInX, x);
-    return atan2(inY, inX);
-}
-
-float2 __attribute__((kernel)) testAtan2Float2Float2Float2(float2 inY, unsigned int x) {
-    float2 inX = rsGetElementAt_float2(gAllocInX, x);
-    return atan2(inY, inX);
-}
-
-float3 __attribute__((kernel)) testAtan2Float3Float3Float3(float3 inY, unsigned int x) {
-    float3 inX = rsGetElementAt_float3(gAllocInX, x);
-    return atan2(inY, inX);
-}
-
-float4 __attribute__((kernel)) testAtan2Float4Float4Float4(float4 inY, unsigned int x) {
-    float4 inX = rsGetElementAt_float4(gAllocInX, x);
-    return atan2(inY, inX);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2Relaxed.rs
deleted file mode 100644
index d5d90a1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAtan2.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2pi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2pi.java
deleted file mode 100644
index 8837003..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2pi.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAtan2pi extends RSBaseCompute {
-
-    private ScriptC_TestAtan2pi script;
-    private ScriptC_TestAtan2piRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAtan2pi(mRS);
-        scriptRelaxed = new ScriptC_TestAtan2piRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inY;
-        public float inX;
-        public Target.Floaty out;
-    }
-
-    private void checkAtan2piFloatFloatFloat() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5a912731bef85233l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5a912731bef85232l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testAtan2piFloatFloatFloat(inY, out);
-            verifyResultsAtan2piFloatFloatFloat(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testAtan2piFloatFloatFloat(inY, out);
-            verifyResultsAtan2piFloatFloatFloat(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtan2piFloatFloatFloat(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i];
-                args.inX = arrayInX[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan2pi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtan2piFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtan2piFloat2Float2Float2() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8031be184fee8f53l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8031be184fee8f52l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testAtan2piFloat2Float2Float2(inY, out);
-            verifyResultsAtan2piFloat2Float2Float2(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testAtan2piFloat2Float2Float2(inY, out);
-            verifyResultsAtan2piFloat2Float2Float2(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtan2piFloat2Float2Float2(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 2 + j];
-                args.inX = arrayInX[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan2pi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtan2piFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtan2piFloat3Float3Float3() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd4969c3851cc90f4l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd4969c3851cc90f3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testAtan2piFloat3Float3Float3(inY, out);
-            verifyResultsAtan2piFloat3Float3Float3(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testAtan2piFloat3Float3Float3(inY, out);
-            verifyResultsAtan2piFloat3Float3Float3(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtan2piFloat3Float3Float3(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 4 + j];
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan2pi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtan2piFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtan2piFloat4Float4Float4() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x28fb7a5853aa9295l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x28fb7a5853aa9294l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testAtan2piFloat4Float4Float4(inY, out);
-            verifyResultsAtan2piFloat4Float4Float4(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testAtan2piFloat4Float4Float4(inY, out);
-            verifyResultsAtan2piFloat4Float4Float4(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtan2piFloat4Float4Float4(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 4 + j];
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtan2pi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtan2piFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAtan2pi() {
-        checkAtan2piFloatFloatFloat();
-        checkAtan2piFloat2Float2Float2();
-        checkAtan2piFloat3Float3Float3();
-        checkAtan2piFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2pi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2pi.rs
deleted file mode 100644
index f0520d7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2pi.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInX;
-
-float __attribute__((kernel)) testAtan2piFloatFloatFloat(float inY, unsigned int x) {
-    float inX = rsGetElementAt_float(gAllocInX, x);
-    return atan2pi(inY, inX);
-}
-
-float2 __attribute__((kernel)) testAtan2piFloat2Float2Float2(float2 inY, unsigned int x) {
-    float2 inX = rsGetElementAt_float2(gAllocInX, x);
-    return atan2pi(inY, inX);
-}
-
-float3 __attribute__((kernel)) testAtan2piFloat3Float3Float3(float3 inY, unsigned int x) {
-    float3 inX = rsGetElementAt_float3(gAllocInX, x);
-    return atan2pi(inY, inX);
-}
-
-float4 __attribute__((kernel)) testAtan2piFloat4Float4Float4(float4 inY, unsigned int x) {
-    float4 inX = rsGetElementAt_float4(gAllocInX, x);
-    return atan2pi(inY, inX);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2piRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2piRelaxed.rs
deleted file mode 100644
index 9f87fff..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtan2piRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAtan2pi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanRelaxed.rs
deleted file mode 100644
index cab9300..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAtan.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanh.java
deleted file mode 100644
index a07c171..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAtanh extends RSBaseCompute {
-
-    private ScriptC_TestAtanh script;
-    private ScriptC_TestAtanhRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAtanh(mRS);
-        scriptRelaxed = new ScriptC_TestAtanhRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkAtanhFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb66b4bab17ef039dl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testAtanhFloatFloat(inV, out);
-            verifyResultsAtanhFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanhFloatFloat(inV, out);
-            verifyResultsAtanhFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanhFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanhFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtanhFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8cd03c06a1cb59d9l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testAtanhFloat2Float2(inV, out);
-            verifyResultsAtanhFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanhFloat2Float2(inV, out);
-            verifyResultsAtanhFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanhFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanhFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtanhFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8cd2052197e67ab7l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testAtanhFloat3Float3(inV, out);
-            verifyResultsAtanhFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanhFloat3Float3(inV, out);
-            verifyResultsAtanhFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanhFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanhFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtanhFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8cd3ce3c8e019b95l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testAtanhFloat4Float4(inV, out);
-            verifyResultsAtanhFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanhFloat4Float4(inV, out);
-            verifyResultsAtanhFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanhFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanhFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAtanh() {
-        checkAtanhFloatFloat();
-        checkAtanhFloat2Float2();
-        checkAtanhFloat3Float3();
-        checkAtanhFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanh.rs
deleted file mode 100644
index 081996c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testAtanhFloatFloat(float inV) {
-    return atanh(inV);
-}
-
-float2 __attribute__((kernel)) testAtanhFloat2Float2(float2 inV) {
-    return atanh(inV);
-}
-
-float3 __attribute__((kernel)) testAtanhFloat3Float3(float3 inV) {
-    return atanh(inV);
-}
-
-float4 __attribute__((kernel)) testAtanhFloat4Float4(float4 inV) {
-    return atanh(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanhRelaxed.rs
deleted file mode 100644
index 88dfc75..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanhRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAtanh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpi.java
deleted file mode 100644
index 34c4e32..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestAtanpi extends RSBaseCompute {
-
-    private ScriptC_TestAtanpi script;
-    private ScriptC_TestAtanpiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestAtanpi(mRS);
-        scriptRelaxed = new ScriptC_TestAtanpiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkAtanpiFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x29ed55009ecfd70l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testAtanpiFloatFloat(inV, out);
-            verifyResultsAtanpiFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanpiFloatFloat(inV, out);
-            verifyResultsAtanpiFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanpiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtanpiFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xed0d645e752cbed4l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testAtanpiFloat2Float2(inV, out);
-            verifyResultsAtanpiFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanpiFloat2Float2(inV, out);
-            verifyResultsAtanpiFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanpiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtanpiFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xed0f2d796b47dfb2l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testAtanpiFloat3Float3(inV, out);
-            verifyResultsAtanpiFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanpiFloat3Float3(inV, out);
-            verifyResultsAtanpiFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanpiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkAtanpiFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xed10f69461630090l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testAtanpiFloat4Float4(inV, out);
-            verifyResultsAtanpiFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testAtanpiFloat4Float4(inV, out);
-            verifyResultsAtanpiFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsAtanpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeAtanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkAtanpiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testAtanpi() {
-        checkAtanpiFloatFloat();
-        checkAtanpiFloat2Float2();
-        checkAtanpiFloat3Float3();
-        checkAtanpiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpi.rs
deleted file mode 100644
index a1c6d2d7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testAtanpiFloatFloat(float inV) {
-    return atanpi(inV);
-}
-
-float2 __attribute__((kernel)) testAtanpiFloat2Float2(float2 inV) {
-    return atanpi(inV);
-}
-
-float3 __attribute__((kernel)) testAtanpiFloat3Float3(float3 inV) {
-    return atanpi(inV);
-}
-
-float4 __attribute__((kernel)) testAtanpiFloat4Float4(float4 inV) {
-    return atanpi(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpiRelaxed.rs
deleted file mode 100644
index 6183636..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestAtanpiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestAtanpi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCbrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCbrt.java
deleted file mode 100644
index c6e6bd3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCbrt.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestCbrt extends RSBaseCompute {
-
-    private ScriptC_TestCbrt script;
-    private ScriptC_TestCbrtRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestCbrt(mRS);
-        scriptRelaxed = new ScriptC_TestCbrtRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkCbrtFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4e2c540726cc677al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testCbrtFloatFloat(in, out);
-            verifyResultsCbrtFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testCbrtFloatFloat(in, out);
-            verifyResultsCbrtFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCbrtFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCbrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCbrtFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCbrtFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9e2a09a2eb8fdb46l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testCbrtFloat2Float2(in, out);
-            verifyResultsCbrtFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testCbrtFloat2Float2(in, out);
-            verifyResultsCbrtFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCbrtFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCbrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCbrtFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCbrtFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9e2a14444a9670e0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testCbrtFloat3Float3(in, out);
-            verifyResultsCbrtFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testCbrtFloat3Float3(in, out);
-            verifyResultsCbrtFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCbrtFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCbrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCbrtFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCbrtFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9e2a1ee5a99d067al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testCbrtFloat4Float4(in, out);
-            verifyResultsCbrtFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testCbrtFloat4Float4(in, out);
-            verifyResultsCbrtFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCbrtFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCbrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCbrtFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testCbrt() {
-        checkCbrtFloatFloat();
-        checkCbrtFloat2Float2();
-        checkCbrtFloat3Float3();
-        checkCbrtFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCbrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCbrt.rs
deleted file mode 100644
index d14f508..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCbrt.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testCbrtFloatFloat(float in) {
-    return cbrt(in);
-}
-
-float2 __attribute__((kernel)) testCbrtFloat2Float2(float2 in) {
-    return cbrt(in);
-}
-
-float3 __attribute__((kernel)) testCbrtFloat3Float3(float3 in) {
-    return cbrt(in);
-}
-
-float4 __attribute__((kernel)) testCbrtFloat4Float4(float4 in) {
-    return cbrt(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCbrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCbrtRelaxed.rs
deleted file mode 100644
index ad970fe..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCbrtRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestCbrt.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCeil.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCeil.java
deleted file mode 100644
index 80121a8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCeil.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestCeil extends RSBaseCompute {
-
-    private ScriptC_TestCeil script;
-    private ScriptC_TestCeilRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestCeil(mRS);
-        scriptRelaxed = new ScriptC_TestCeilRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkCeilFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa65a49d160f51d9al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testCeilFloatFloat(in, out);
-            verifyResultsCeilFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testCeilFloatFloat(in, out);
-            verifyResultsCeilFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCeilFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCeil(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCeilFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCeilFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x821e4b40fb9b4866l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testCeilFloat2Float2(in, out);
-            verifyResultsCeilFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testCeilFloat2Float2(in, out);
-            verifyResultsCeilFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCeilFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCeil(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCeilFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCeilFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x821e55e25aa1de00l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testCeilFloat3Float3(in, out);
-            verifyResultsCeilFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testCeilFloat3Float3(in, out);
-            verifyResultsCeilFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCeilFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCeil(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCeilFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCeilFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x821e6083b9a8739al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testCeilFloat4Float4(in, out);
-            verifyResultsCeilFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testCeilFloat4Float4(in, out);
-            verifyResultsCeilFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCeilFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCeil(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCeilFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testCeil() {
-        checkCeilFloatFloat();
-        checkCeilFloat2Float2();
-        checkCeilFloat3Float3();
-        checkCeilFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCeil.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCeil.rs
deleted file mode 100644
index 80c8708..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCeil.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testCeilFloatFloat(float in) {
-    return ceil(in);
-}
-
-float2 __attribute__((kernel)) testCeilFloat2Float2(float2 in) {
-    return ceil(in);
-}
-
-float3 __attribute__((kernel)) testCeilFloat3Float3(float3 in) {
-    return ceil(in);
-}
-
-float4 __attribute__((kernel)) testCeilFloat4Float4(float4 in) {
-    return ceil(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCeilRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCeilRelaxed.rs
deleted file mode 100644
index bbafb0d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCeilRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestCeil.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestClamp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestClamp.java
deleted file mode 100644
index 44f60d6..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestClamp.java
+++ /dev/null
@@ -1,4925 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestClamp extends RSBaseCompute {
-
-    private ScriptC_TestClamp script;
-    private ScriptC_TestClampRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestClamp(mRS);
-        scriptRelaxed = new ScriptC_TestClampRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloatFloat {
-        public float inValue;
-        public float inMinValue;
-        public float inMaxValue;
-        public Target.Floaty out;
-    }
-
-    private void checkClampFloatFloatFloatFloat() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7e886d7cc83c447dl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdcebf6f230234027l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdcebf6e6c180322dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampFloatFloatFloatFloat(inValue, out);
-            verifyResultsClampFloatFloatFloatFloat(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloatFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampFloatFloatFloatFloat(inValue, out);
-            verifyResultsClampFloatFloatFloatFloat(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloatFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampFloatFloatFloatFloat(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        float[] arrayInMinValue = new float[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inValue = arrayInValue[i];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeClamp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampFloatFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampFloat2Float2Float2Float2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa0d28bf142b07a5l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb4e5c5f6ea8fc01fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb4e5c5eb7becb225l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampFloat2Float2Float2Float2(inValue, out);
-            verifyResultsClampFloat2Float2Float2Float2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2Float2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampFloat2Float2Float2Float2(inValue, out);
-            verifyResultsClampFloat2Float2Float2Float2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2Float2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampFloat2Float2Float2Float2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        float[] arrayInMinValue = new float[INPUTSIZE * 2];
-        inMinValue.copyTo(arrayInMinValue);
-        float[] arrayInMaxValue = new float[INPUTSIZE * 2];
-        inMaxValue.copyTo(arrayInMaxValue);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inValue = arrayInValue[i * 2 + j];
-                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);
-                CoreMathVerifier.computeClamp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampFloat2Float2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampFloat3Float3Float3Float3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd3716a4730ad7481l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc0d239a53946aa73l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc0d23999caa39c79l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampFloat3Float3Float3Float3(inValue, out);
-            verifyResultsClampFloat3Float3Float3Float3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3Float3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampFloat3Float3Float3Float3(inValue, out);
-            verifyResultsClampFloat3Float3Float3Float3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3Float3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampFloat3Float3Float3Float3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        float[] arrayInMinValue = new float[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        float[] arrayInMaxValue = new float[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inValue = arrayInValue[i * 4 + j];
-                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);
-                CoreMathVerifier.computeClamp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampFloat3Float3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampFloat4Float4Float4Float4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9cd5abcf4d2fe15dl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xccbead5387fd94c7l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xccbead48195a86cdl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampFloat4Float4Float4Float4(inValue, out);
-            verifyResultsClampFloat4Float4Float4Float4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4Float4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampFloat4Float4Float4Float4(inValue, out);
-            verifyResultsClampFloat4Float4Float4Float4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4Float4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampFloat4Float4Float4Float4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        float[] arrayInMinValue = new float[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        float[] arrayInMaxValue = new float[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inValue = arrayInValue[i * 4 + j];
-                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);
-                CoreMathVerifier.computeClamp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampFloat4Float4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampFloat2FloatFloatFloat2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x71623fb3f1fca1a1l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x148e792e1a6253d3l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x148e7922abbf45d9l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampFloat2FloatFloatFloat2(inValue, out);
-            verifyResultsClampFloat2FloatFloatFloat2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2FloatFloatFloat2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampFloat2FloatFloatFloat2(inValue, out);
-            verifyResultsClampFloat2FloatFloatFloat2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2FloatFloatFloat2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampFloat2FloatFloatFloat2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        float[] arrayInMinValue = new float[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeClamp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampFloat2FloatFloatFloat2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampFloat3FloatFloatFloat3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc06893ff6ab8cf27l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1f4444b84d90bbc5l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1f4444acdeedadcbl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampFloat3FloatFloatFloat3(inValue, out);
-            verifyResultsClampFloat3FloatFloatFloat3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3FloatFloatFloat3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampFloat3FloatFloatFloat3(inValue, out);
-            verifyResultsClampFloat3FloatFloatFloat3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3FloatFloatFloat3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampFloat3FloatFloatFloat3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        float[] arrayInMinValue = new float[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeClamp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampFloat3FloatFloatFloat3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampFloat4FloatFloatFloat4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf6ee84ae374fcadl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x29fa104280bf23b7l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x29fa1037121c15bdl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampFloat4FloatFloatFloat4(inValue, out);
-            verifyResultsClampFloat4FloatFloatFloat4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4FloatFloatFloat4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampFloat4FloatFloatFloat4(inValue, out);
-            verifyResultsClampFloat4FloatFloatFloat4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4FloatFloatFloat4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampFloat4FloatFloatFloat4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        float[] arrayInMinValue = new float[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeClamp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMinValue, Float.floatToRawIntBits(args.inMinValue), args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inMaxValue, Float.floatToRawIntBits(args.inMaxValue), args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampFloat4FloatFloatFloat4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharCharCharChar {
-        public byte inValue;
-        public byte inMinValue;
-        public byte inMaxValue;
-        public byte out;
-    }
-
-    private void checkClampCharCharCharChar() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xaec8640bb673cf75l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x6379f7c3c505c8fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x6379f70cdad4e95l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampCharCharCharChar(inValue, out);
-            verifyResultsClampCharCharCharChar(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampCharCharCharChar: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampCharCharCharChar(inValue, out);
-            verifyResultsClampCharCharCharChar(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampCharCharCharChar: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampCharCharCharChar(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
-                args.inValue = arrayInValue[i];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampCharCharCharChar" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampChar2Char2Char2Char2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xa209cfe6c3feb45dl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xed63d0ab3442bdc7l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xed63d09fc59fafcdl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampChar2Char2Char2Char2(inValue, out);
-            verifyResultsClampChar2Char2Char2Char2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2Char2Char2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampChar2Char2Char2Char2(inValue, out);
-            verifyResultsClampChar2Char2Char2Char2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2Char2Char2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampChar2Char2Char2Char2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 2];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 2];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i * 2 + j];
-                args.inMaxValue = arrayInMaxValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampChar2Char2Char2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampChar3Char3Char3Char3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xfab6edb7b9d3b0a5l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x7ae6f958470ecb1fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x7ae6f94cd86bbd25l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampChar3Char3Char3Char3(inValue, out);
-            verifyResultsClampChar3Char3Char3Char3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3Char3Char3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampChar3Char3Char3Char3(inValue, out);
-            verifyResultsClampChar3Char3Char3Char3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3Char3Char3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampChar3Char3Char3Char3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampChar3Char3Char3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampChar4Char4Char4Char4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x53640b88afa8acedl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x86a220559dad877l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x86a21f9eb37ca7dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampChar4Char4Char4Char4(inValue, out);
-            verifyResultsClampChar4Char4Char4Char4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4Char4Char4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampChar4Char4Char4Char4(inValue, out);
-            verifyResultsClampChar4Char4Char4Char4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4Char4Char4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampChar4Char4Char4Char4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampChar4Char4Char4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharUcharUcharUchar {
-        public byte inValue;
-        public byte inMinValue;
-        public byte inMaxValue;
-        public byte out;
-    }
-
-    private void checkClampUcharUcharUcharUchar() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x680c818a4447655l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xae40bae375336f2fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xae40bad806906135l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUcharUcharUcharUchar(inValue, out);
-            verifyResultsClampUcharUcharUcharUchar(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUcharUcharUcharUchar: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUcharUcharUcharUchar(inValue, out);
-            verifyResultsClampUcharUcharUcharUchar(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUcharUcharUcharUchar: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUcharUcharUcharUchar(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
-                args.inValue = arrayInValue[i];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUcharUcharUcharUchar" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUchar2Uchar2Uchar2Uchar2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xd69df43245dae301l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x82681747662c1df3l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x8268173bf7890ff9l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUchar2Uchar2Uchar2Uchar2(inValue, out);
-            verifyResultsClampUchar2Uchar2Uchar2Uchar2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2Uchar2Uchar2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUchar2Uchar2Uchar2Uchar2(inValue, out);
-            verifyResultsClampUchar2Uchar2Uchar2Uchar2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2Uchar2Uchar2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUchar2Uchar2Uchar2Uchar2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 2];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 2];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i * 2 + j];
-                args.inMaxValue = arrayInMaxValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUchar2Uchar2Uchar2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUchar3Uchar3Uchar3Uchar3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xa00235ba625d4fddl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x8e548af5b4e30847l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x8e548aea463ffa4dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUchar3Uchar3Uchar3Uchar3(inValue, out);
-            verifyResultsClampUchar3Uchar3Uchar3Uchar3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3Uchar3Uchar3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUchar3Uchar3Uchar3Uchar3(inValue, out);
-            verifyResultsClampUchar3Uchar3Uchar3Uchar3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3Uchar3Uchar3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUchar3Uchar3Uchar3Uchar3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUchar3Uchar3Uchar3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUchar4Uchar4Uchar4Uchar4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x696677427edfbcb9l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x9a40fea40399f29bl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x9a40fe9894f6e4a1l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUchar4Uchar4Uchar4Uchar4(inValue, out);
-            verifyResultsClampUchar4Uchar4Uchar4Uchar4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4Uchar4Uchar4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUchar4Uchar4Uchar4Uchar4(inValue, out);
-            verifyResultsClampUchar4Uchar4Uchar4Uchar4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4Uchar4Uchar4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUchar4Uchar4Uchar4Uchar4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUchar4Uchar4Uchar4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortShortShortShort {
-        public short inValue;
-        public short inMinValue;
-        public short inMaxValue;
-        public short out;
-    }
-
-    private void checkClampShortShortShortShort() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x8035c0627fc993ddl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xb5d4bd1fb4661447l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xb5d4bd1445c3064dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampShortShortShortShort(inValue, out);
-            verifyResultsClampShortShortShortShort(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShortShortShortShort: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampShortShortShortShort(inValue, out);
-            verifyResultsClampShortShortShortShort(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShortShortShortShort: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampShortShortShortShort(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
-                args.inValue = arrayInValue[i];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampShortShortShortShort" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampShort2Short2Short2Short2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x7eab8e9b984e0915l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x7b334b992e67336fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x7b334b8dbfc42575l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampShort2Short2Short2Short2(inValue, out);
-            verifyResultsClampShort2Short2Short2Short2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2Short2Short2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampShort2Short2Short2Short2(inValue, out);
-            verifyResultsClampShort2Short2Short2Short2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2Short2Short2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampShort2Short2Short2Short2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 2];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 2];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i * 2 + j];
-                args.inMaxValue = arrayInMaxValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampShort2Short2Short2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampShort3Short3Short3Short3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x480fd023b4d075f1l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x871fbf477d1e1dc3l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x871fbf3c0e7b0fc9l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampShort3Short3Short3Short3(inValue, out);
-            verifyResultsClampShort3Short3Short3Short3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3Short3Short3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampShort3Short3Short3Short3(inValue, out);
-            verifyResultsClampShort3Short3Short3Short3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3Short3Short3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampShort3Short3Short3Short3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampShort3Short3Short3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampShort4Short4Short4Short4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x117411abd152e2cdl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x930c32f5cbd50817l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x930c32ea5d31fa1dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampShort4Short4Short4Short4(inValue, out);
-            verifyResultsClampShort4Short4Short4Short4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4Short4Short4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampShort4Short4Short4Short4(inValue, out);
-            verifyResultsClampShort4Short4Short4Short4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4Short4Short4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampShort4Short4Short4Short4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampShort4Short4Short4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortUshortUshortUshort {
-        public short inValue;
-        public short inMinValue;
-        public short inMaxValue;
-        public short out;
-    }
-
-    private void checkClampUshortUshortUshortUshort() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xf5881eeff74c4341l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xd2a0571394d3e2b3l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xd2a057082630d4b9l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUshortUshortUshortUshort(inValue, out);
-            verifyResultsClampUshortUshortUshortUshort(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshortUshortUshortUshort: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUshortUshortUshortUshort(inValue, out);
-            verifyResultsClampUshortUshortUshortUshort(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshortUshortUshortUshort: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUshortUshortUshortUshort(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
-                args.inValue = arrayInValue[i];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUshortUshortUshortUshort" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUshort2Ushort2Ushort2Ushort2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x6441dbe2fc36b705l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x52161e934fa3b43fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x52161e87e100a645l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUshort2Ushort2Ushort2Ushort2(inValue, out);
-            verifyResultsClampUshort2Ushort2Ushort2Ushort2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2Ushort2Ushort2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUshort2Ushort2Ushort2Ushort2(inValue, out);
-            verifyResultsClampUshort2Ushort2Ushort2Ushort2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2Ushort2Ushort2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUshort2Ushort2Ushort2Ushort2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 2];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 2];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i * 2 + j];
-                args.inMaxValue = arrayInMaxValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUshort2Ushort2Ushort2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUshort3Ushort3Ushort3Ushort3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x6b244d61fc64ee3dl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x7b8d14b8610b3967l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x7b8d14acf2682b6dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUshort3Ushort3Ushort3Ushort3(inValue, out);
-            verifyResultsClampUshort3Ushort3Ushort3Ushort3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3Ushort3Ushort3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUshort3Ushort3Ushort3Ushort3(inValue, out);
-            verifyResultsClampUshort3Ushort3Ushort3Ushort3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3Ushort3Ushort3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUshort3Ushort3Ushort3Ushort3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUshort3Ushort3Ushort3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUshort4Ushort4Ushort4Ushort4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x7206bee0fc932575l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xa5040add7272be8fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xa5040ad203cfb095l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUshort4Ushort4Ushort4Ushort4(inValue, out);
-            verifyResultsClampUshort4Ushort4Ushort4Ushort4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4Ushort4Ushort4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUshort4Ushort4Ushort4Ushort4(inValue, out);
-            verifyResultsClampUshort4Ushort4Ushort4Ushort4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4Ushort4Ushort4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUshort4Ushort4Ushort4Ushort4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUshort4Ushort4Ushort4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntIntIntInt {
-        public int inValue;
-        public int inMinValue;
-        public int inMaxValue;
-        public int out;
-    }
-
-    private void checkClampIntIntIntInt() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xfeb3aa11be6164c5l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xd11c228c7c8bf97fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xd11c22810de8eb85l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampIntIntIntInt(inValue, out);
-            verifyResultsClampIntIntIntInt(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampIntIntIntInt: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampIntIntIntInt(inValue, out);
-            verifyResultsClampIntIntIntInt(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampIntIntIntInt: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampIntIntIntInt(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
-                args.inValue = arrayInValue[i];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampIntIntIntInt" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampInt2Int2Int2Int2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x56252903bd307c01l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x770112109398f8f3l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x7701120524f5eaf9l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampInt2Int2Int2Int2(inValue, out);
-            verifyResultsClampInt2Int2Int2Int2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2Int2Int2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampInt2Int2Int2Int2(inValue, out);
-            verifyResultsClampInt2Int2Int2Int2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2Int2Int2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampInt2Int2Int2Int2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 2];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 2];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i * 2 + j];
-                args.inMaxValue = arrayInMaxValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampInt2Int2Int2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampInt3Int3Int3Int3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x966882045600d2edl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xeb73e6749c7caa77l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xeb73e6692dd99c7dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampInt3Int3Int3Int3(inValue, out);
-            verifyResultsClampInt3Int3Int3Int3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3Int3Int3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampInt3Int3Int3Int3(inValue, out);
-            verifyResultsClampInt3Int3Int3Int3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3Int3Int3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampInt3Int3Int3Int3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampInt3Int3Int3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampInt4Int4Int4Int4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd6abdb04eed129d9l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x5fe6bad8a5605bfbl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x5fe6bacd36bd4e01l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampInt4Int4Int4Int4(inValue, out);
-            verifyResultsClampInt4Int4Int4Int4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4Int4Int4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampInt4Int4Int4Int4(inValue, out);
-            verifyResultsClampInt4Int4Int4Int4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4Int4Int4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampInt4Int4Int4Int4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampInt4Int4Int4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintUintUintUint {
-        public int inValue;
-        public int inMinValue;
-        public int inMaxValue;
-        public int out;
-    }
-
-    private void checkClampUintUintUintUint() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xd8df32b2efc89475l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xcf8ec8eece8b7b8fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xcf8ec8e35fe86d95l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUintUintUintUint(inValue, out);
-            verifyResultsClampUintUintUintUint(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUintUintUintUint: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUintUintUintUint(inValue, out);
-            verifyResultsClampUintUintUintUint(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUintUintUintUint: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUintUintUintUint(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
-                args.inValue = arrayInValue[i];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUintUintUintUint" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUint2Uint2Uint2Uint2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xaf28d478873ae5dl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x5bbd21aa2a4bc7l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x5bbd163b873dcdl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUint2Uint2Uint2Uint2(inValue, out);
-            verifyResultsClampUint2Uint2Uint2Uint2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2Uint2Uint2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUint2Uint2Uint2Uint2(inValue, out);
-            verifyResultsClampUint2Uint2Uint2Uint2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2Uint2Uint2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUint2Uint2Uint2Uint2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 2];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 2];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i * 2 + j];
-                args.inMaxValue = arrayInMaxValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUint2Uint2Uint2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUint3Uint3Uint3Uint3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x639fab187e48aaa5l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x8ddee5cebcf6591fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x8ddee5c34e534b25l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUint3Uint3Uint3Uint3(inValue, out);
-            verifyResultsClampUint3Uint3Uint3Uint3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3Uint3Uint3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUint3Uint3Uint3Uint3(inValue, out);
-            verifyResultsClampUint3Uint3Uint3Uint3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3Uint3Uint3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUint3Uint3Uint3Uint3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUint3Uint3Uint3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUint4Uint4Uint4Uint4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xbc4cc8e9741da6edl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x1b620e7bcfc26677l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x1b620e70611f587dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUint4Uint4Uint4Uint4(inValue, out);
-            verifyResultsClampUint4Uint4Uint4Uint4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4Uint4Uint4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUint4Uint4Uint4Uint4(inValue, out);
-            verifyResultsClampUint4Uint4Uint4Uint4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4Uint4Uint4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUint4Uint4Uint4Uint4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUint4Uint4Uint4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongLongLongLong {
-        public long inValue;
-        public long inMinValue;
-        public long inMaxValue;
-        public long out;
-    }
-
-    private void checkClampLongLongLongLong() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x63fd360531c9c41dl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x9d04d1824ef4907l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x9d04d0cb64c3b0dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampLongLongLongLong(inValue, out);
-            verifyResultsClampLongLongLongLong(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLongLongLongLong: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampLongLongLongLong(inValue, out);
-            verifyResultsClampLongLongLongLong(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLongLongLongLong: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampLongLongLongLong(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
-                args.inValue = arrayInValue[i];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampLongLongLongLong" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampLong2Long2Long2Long2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xccbae869c2b0f12dl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xe4c3844f4a3f8937l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xe4c38443db9c7b3dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampLong2Long2Long2Long2(inValue, out);
-            verifyResultsClampLong2Long2Long2Long2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong2Long2Long2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampLong2Long2Long2Long2(inValue, out);
-            verifyResultsClampLong2Long2Long2Long2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong2Long2Long2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampLong2Long2Long2Long2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 2];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 2];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i * 2 + j];
-                args.inMaxValue = arrayInMaxValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampLong2Long2Long2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampLong3Long3Long3Long3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x2568063ab885ed75l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x7246acfc5d0b968fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x7246acf0ee688895l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampLong3Long3Long3Long3(inValue, out);
-            verifyResultsClampLong3Long3Long3Long3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong3Long3Long3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampLong3Long3Long3Long3(inValue, out);
-            verifyResultsClampLong3Long3Long3Long3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong3Long3Long3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampLong3Long3Long3Long3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampLong3Long3Long3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampLong4Long4Long4Long4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x7e15240bae5ae9bdl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xffc9d5a96fd7a3e7l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xffc9d59e013495edl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampLong4Long4Long4Long4(inValue, out);
-            verifyResultsClampLong4Long4Long4Long4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong4Long4Long4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampLong4Long4Long4Long4(inValue, out);
-            verifyResultsClampLong4Long4Long4Long4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong4Long4Long4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampLong4Long4Long4Long4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampLong4Long4Long4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongUlongUlongUlong {
-        public long inValue;
-        public long inMinValue;
-        public long inMaxValue;
-        public long out;
-    }
-
-    private void checkClampUlongUlongUlongUlong() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x2b378139749bf4c5l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x75ac5050a8ca97fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x75ac4f99be99b85l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUlongUlongUlongUlong(inValue, out);
-            verifyResultsClampUlongUlongUlongUlong(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlongUlongUlongUlong: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUlongUlongUlongUlong(inValue, out);
-            verifyResultsClampUlongUlongUlongUlong(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlongUlongUlongUlong: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUlongUlongUlongUlong(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
-                args.inValue = arrayInValue[i];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUlongUlongUlongUlong" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUlong2Ulong2Ulong2Ulong2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xa8c7fb17a09bb299l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x14e3c8dffe45623bl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x14e3c8d48fa25441l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUlong2Ulong2Ulong2Ulong2(inValue, out);
-            verifyResultsClampUlong2Ulong2Ulong2Ulong2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong2Ulong2Ulong2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUlong2Ulong2Ulong2Ulong2(inValue, out);
-            verifyResultsClampUlong2Ulong2Ulong2Ulong2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong2Ulong2Ulong2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUlong2Ulong2Ulong2Ulong2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 2];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 2];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i * 2 + j];
-                args.inMaxValue = arrayInMaxValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUlong2Ulong2Ulong2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUlong3Ulong3Ulong3Ulong3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x722c3c9fbd1e1f75l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x20d03c8e4cfc4c8fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x20d03c82de593e95l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUlong3Ulong3Ulong3Ulong3(inValue, out);
-            verifyResultsClampUlong3Ulong3Ulong3Ulong3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong3Ulong3Ulong3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUlong3Ulong3Ulong3Ulong3(inValue, out);
-            verifyResultsClampUlong3Ulong3Ulong3Ulong3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong3Ulong3Ulong3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUlong3Ulong3Ulong3Ulong3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUlong3Ulong3Ulong3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUlong4Ulong4Ulong4Ulong4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x3b907e27d9a08c51l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x2cbcb03c9bb336e3l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x2cbcb0312d1028e9l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUlong4Ulong4Ulong4Ulong4(inValue, out);
-            verifyResultsClampUlong4Ulong4Ulong4Ulong4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong4Ulong4Ulong4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUlong4Ulong4Ulong4Ulong4(inValue, out);
-            verifyResultsClampUlong4Ulong4Ulong4Ulong4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong4Ulong4Ulong4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUlong4Ulong4Ulong4Ulong4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 4];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 4];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i * 4 + j];
-                args.inMaxValue = arrayInMaxValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUlong4Ulong4Ulong4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampChar2CharCharChar2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd6884bbb7c57a5d1l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x3bf8830cc3b7db63l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x3bf883015514cd69l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampChar2CharCharChar2(inValue, out);
-            verifyResultsClampChar2CharCharChar2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2CharCharChar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampChar2CharCharChar2(inValue, out);
-            verifyResultsClampChar2CharCharChar2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2CharCharChar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampChar2CharCharChar2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampChar2CharCharChar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampChar3CharCharChar3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x4aa68c1b65a26ee5l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x8b4b9ea0492789dfl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x8b4b9e94da847be5l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampChar3CharCharChar3(inValue, out);
-            verifyResultsClampChar3CharCharChar3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3CharCharChar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampChar3CharCharChar3(inValue, out);
-            verifyResultsClampChar3CharCharChar3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3CharCharChar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampChar3CharCharChar3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampChar3CharCharChar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampChar4CharCharChar4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xbec4cc7b4eed37f9l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xda9eba33ce97385bl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xda9eba285ff42a61l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampChar4CharCharChar4(inValue, out);
-            verifyResultsClampChar4CharCharChar4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4CharCharChar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampChar4CharCharChar4(inValue, out);
-            verifyResultsClampChar4CharCharChar4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4CharCharChar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampChar4CharCharChar4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampChar4CharCharChar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUchar2UcharUcharUchar2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xafd4a680f02e0d63l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x78bbbcb3e9402039l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x78bbbca87a9d123fl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUchar2UcharUcharUchar2(inValue, out);
-            verifyResultsClampUchar2UcharUcharUchar2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2UcharUcharUchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUchar2UcharUcharUchar2(inValue, out);
-            verifyResultsClampUchar2UcharUcharUchar2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2UcharUcharUchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUchar2UcharUcharUchar2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUchar2UcharUcharUchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUchar3UcharUcharUchar3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xfedafacc68ea3ae9l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x8371883e1c6e882bl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x83718832adcb7a31l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUchar3UcharUcharUchar3(inValue, out);
-            verifyResultsClampUchar3UcharUcharUchar3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3UcharUcharUchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUchar3UcharUcharUchar3(inValue, out);
-            verifyResultsClampUchar3UcharUcharUchar3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3UcharUcharUchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUchar3UcharUcharUchar3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUchar3UcharUcharUchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUchar4UcharUcharUchar4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x4de14f17e1a6686fl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x8e2753c84f9cf01dl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x8e2753bce0f9e223l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUchar4UcharUcharUchar4(inValue, out);
-            verifyResultsClampUchar4UcharUcharUchar4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4UcharUcharUchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUchar4UcharUcharUchar4(inValue, out);
-            verifyResultsClampUchar4UcharUcharUchar4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4UcharUcharUchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUchar4UcharUcharUchar4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUchar4UcharUcharUchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampShort2ShortShortShort2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x89e3627eae2d6a9l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x886d6d2ccaca776bl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x886d6d215c276971l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampShort2ShortShortShort2(inValue, out);
-            verifyResultsClampShort2ShortShortShort2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2ShortShortShort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampShort2ShortShortShort2(inValue, out);
-            verifyResultsClampShort2ShortShortShort2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2ShortShortShort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampShort2ShortShortShort2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampShort2ShortShortShort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampShort3ShortShortShort3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x57a48a73639f042fl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x932338b6fdf8df5dl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x932338ab8f55d163l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampShort3ShortShortShort3(inValue, out);
-            verifyResultsClampShort3ShortShortShort3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3ShortShortShort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampShort3ShortShortShort3(inValue, out);
-            verifyResultsClampShort3ShortShortShort3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3ShortShortShort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampShort3ShortShortShort3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampShort3ShortShortShort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampShort4ShortShortShort4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xa6aadebedc5b31b5l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x9dd904413127474fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x9dd90435c2843955l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampShort4ShortShortShort4(inValue, out);
-            verifyResultsClampShort4ShortShortShort4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4ShortShortShort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampShort4ShortShortShort4(inValue, out);
-            verifyResultsClampShort4ShortShortShort4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4ShortShortShort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampShort4ShortShortShort4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampShort4ShortShortShort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUshort2UshortUshortUshort2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x2ece6d045621ef07l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xd88bd79cc7874965l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xd88bd79158e43b6bl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUshort2UshortUshortUshort2(inValue, out);
-            verifyResultsClampUshort2UshortUshortUshort2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2UshortUshortUshort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUshort2UshortUshortUshort2(inValue, out);
-            verifyResultsClampUshort2UshortUshortUshort2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2UshortUshortUshort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUshort2UshortUshortUshort2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUshort2UshortUshortUshort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUshort3UshortUshortUshort3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x393771467c9cd603l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xfe016431b3cf1419l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xfe016426452c061fl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUshort3UshortUshortUshort3(inValue, out);
-            verifyResultsClampUshort3UshortUshortUshort3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3UshortUshortUshort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUshort3UshortUshortUshort3(inValue, out);
-            verifyResultsClampUshort3UshortUshortUshort3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3UshortUshortUshort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUshort3UshortUshortUshort3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUshort3UshortUshortUshort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUshort4UshortUshortUshort4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x43a07588a317bcffl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x2376f0c6a016decdl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x2376f0bb3173d0d3l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUshort4UshortUshortUshort4(inValue, out);
-            verifyResultsClampUshort4UshortUshortUshort4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4UshortUshortUshort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUshort4UshortUshortUshort4(inValue, out);
-            verifyResultsClampUshort4UshortUshortUshort4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4UshortUshortUshort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUshort4UshortUshortUshort4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayInMinValue = new short[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        short[] arrayInMaxValue = new short[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUshort4UshortUshortUshort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampInt2IntIntInt2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xbb55c0997906d1dbl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x69776e80fba24121l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x69776e758cff3327l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampInt2IntIntInt2(inValue, out);
-            verifyResultsClampInt2IntIntInt2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2IntIntInt2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampInt2IntIntInt2(inValue, out);
-            verifyResultsClampInt2IntIntInt2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2IntIntInt2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampInt2IntIntInt2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampInt2IntIntInt2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampInt3IntIntInt3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x3af8924ab5370be9l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xdde27628f1a08b2bl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xdde2761d82fd7d31l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampInt3IntIntInt3(inValue, out);
-            verifyResultsClampInt3IntIntInt3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3IntIntInt3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampInt3IntIntInt3(inValue, out);
-            verifyResultsClampInt3IntIntInt3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3IntIntInt3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampInt3IntIntInt3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampInt3IntIntInt3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampInt4IntIntInt4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xba9b63fbf16745f7l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x524d7dd0e79ed535l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x524d7dc578fbc73bl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampInt4IntIntInt4(inValue, out);
-            verifyResultsClampInt4IntIntInt4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4IntIntInt4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampInt4IntIntInt4(inValue, out);
-            verifyResultsClampInt4IntIntInt4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4IntIntInt4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampInt4IntIntInt4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampInt4IntIntInt4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUint2UintUintUint2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x4fd098dd770d5a51l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x6de3f327c2a180e3l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x6de3f31c53fe72e9l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUint2UintUintUint2(inValue, out);
-            verifyResultsClampUint2UintUintUint2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2UintUintUint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUint2UintUintUint2(inValue, out);
-            verifyResultsClampUint2UintUintUint2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2UintUintUint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUint2UintUintUint2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUint2UintUintUint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUint3UintUintUint3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xc3eed93d60582365l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xbd370ebb48112f5fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xbd370eafd96e2165l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUint3UintUintUint3(inValue, out);
-            verifyResultsClampUint3UintUintUint3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3UintUintUint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUint3UintUintUint3(inValue, out);
-            verifyResultsClampUint3UintUintUint3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3UintUintUint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUint3UintUintUint3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUint3UintUintUint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUint4UintUintUint4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x380d199d49a2ec79l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xc8a2a4ecd80dddbl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xc8a2a435eddcfe1l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUint4UintUintUint4(inValue, out);
-            verifyResultsClampUint4UintUintUint4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4UintUintUint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUint4UintUintUint4(inValue, out);
-            verifyResultsClampUint4UintUintUint4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4UintUintUint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUint4UintUintUint4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayInMinValue = new int[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUint4UintUintUint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampLong2LongLongLong2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x19353a9f7c535bb5l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0xee8dc7f38f83654fl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0xee8dc7e820e05755l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampLong2LongLongLong2(inValue, out);
-            verifyResultsClampLong2LongLongLong2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong2LongLongLong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampLong2LongLongLong2(inValue, out);
-            verifyResultsClampLong2LongLongLong2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong2LongLongLong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampLong2LongLongLong2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampLong2LongLongLong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampLong3LongLongLong3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x8d537aff659e24c9l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x3de0e38714f313cbl, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x3de0e37ba65005d1l, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampLong3LongLongLong3(inValue, out);
-            verifyResultsClampLong3LongLongLong3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong3LongLongLong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampLong3LongLongLong3(inValue, out);
-            verifyResultsClampLong3LongLongLong3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong3LongLongLong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampLong3LongLongLong3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampLong3LongLongLong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampLong4LongLongLong4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x171bb5f4ee8edddl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x8d33ff1a9a62c247l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x8d33ff0f2bbfb44dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampLong4LongLongLong4(inValue, out);
-            verifyResultsClampLong4LongLongLong4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong4LongLongLong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampLong4LongLongLong4(inValue, out);
-            verifyResultsClampLong4LongLongLong4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong4LongLongLong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampLong4LongLongLong4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("%d", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("%d", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampLong4LongLongLong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUlong2UlongUlongUlong2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xf275dabaa7fa1bf7l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0xf08a9e698d13b735l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0xf08a9e5e1e70a93bl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUlong2UlongUlongUlong2(inValue, out);
-            verifyResultsClampUlong2UlongUlongUlong2(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong2UlongUlongUlong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUlong2UlongUlongUlong2(inValue, out);
-            verifyResultsClampUlong2UlongUlongUlong2(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong2UlongUlongUlong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUlong2UlongUlongUlong2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
-                args.inValue = arrayInValue[i * 2 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUlong2UlongUlongUlong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUlong3UlongUlongUlong3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x417c2f0620b6497dl, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0xfb4069f3c0421f27l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0xfb4069e8519f112dl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUlong3UlongUlongUlong3(inValue, out);
-            verifyResultsClampUlong3UlongUlongUlong3(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong3UlongUlongUlong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUlong3UlongUlongUlong3(inValue, out);
-            verifyResultsClampUlong3UlongUlongUlong3(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong3UlongUlongUlong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUlong3UlongUlongUlong3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUlong3UlongUlongUlong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClampUlong4UlongUlongUlong4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x9082835199727703l, false);
-        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x5f6357df3708719l, false);
-        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x5f6357284cd791fl, false);
-        enforceOrdering(inMinValue, inMaxValue);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.set_gAllocInMinValue(inMinValue);
-            script.set_gAllocInMaxValue(inMaxValue);
-            script.forEach_testClampUlong4UlongUlongUlong4(inValue, out);
-            verifyResultsClampUlong4UlongUlongUlong4(inValue, inMinValue, inMaxValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong4UlongUlongUlong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInMinValue(inMinValue);
-            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
-            scriptRelaxed.forEach_testClampUlong4UlongUlongUlong4(inValue, out);
-            verifyResultsClampUlong4UlongUlongUlong4(inValue, inMinValue, inMaxValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong4UlongUlongUlong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClampUlong4UlongUlongUlong4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
-        long[] arrayInValue = new long[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        long[] arrayInMinValue = new long[INPUTSIZE * 1];
-        inMinValue.copyTo(arrayInMinValue);
-        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
-        inMaxValue.copyTo(arrayInMaxValue);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
-                args.inValue = arrayInValue[i * 4 + j];
-                args.inMinValue = arrayInMinValue[i];
-                args.inMaxValue = arrayInMaxValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClamp(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Input inMinValue: ");
-                    message.append(String.format("0x%x", args.inMinValue));
-                    message.append("\n");
-                    message.append("Input inMaxValue: ");
-                    message.append(String.format("0x%x", args.inMaxValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClampUlong4UlongUlongUlong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testClamp() {
-        checkClampFloatFloatFloatFloat();
-        checkClampFloat2Float2Float2Float2();
-        checkClampFloat3Float3Float3Float3();
-        checkClampFloat4Float4Float4Float4();
-        checkClampFloat2FloatFloatFloat2();
-        checkClampFloat3FloatFloatFloat3();
-        checkClampFloat4FloatFloatFloat4();
-        checkClampCharCharCharChar();
-        checkClampChar2Char2Char2Char2();
-        checkClampChar3Char3Char3Char3();
-        checkClampChar4Char4Char4Char4();
-        checkClampUcharUcharUcharUchar();
-        checkClampUchar2Uchar2Uchar2Uchar2();
-        checkClampUchar3Uchar3Uchar3Uchar3();
-        checkClampUchar4Uchar4Uchar4Uchar4();
-        checkClampShortShortShortShort();
-        checkClampShort2Short2Short2Short2();
-        checkClampShort3Short3Short3Short3();
-        checkClampShort4Short4Short4Short4();
-        checkClampUshortUshortUshortUshort();
-        checkClampUshort2Ushort2Ushort2Ushort2();
-        checkClampUshort3Ushort3Ushort3Ushort3();
-        checkClampUshort4Ushort4Ushort4Ushort4();
-        checkClampIntIntIntInt();
-        checkClampInt2Int2Int2Int2();
-        checkClampInt3Int3Int3Int3();
-        checkClampInt4Int4Int4Int4();
-        checkClampUintUintUintUint();
-        checkClampUint2Uint2Uint2Uint2();
-        checkClampUint3Uint3Uint3Uint3();
-        checkClampUint4Uint4Uint4Uint4();
-        checkClampLongLongLongLong();
-        checkClampLong2Long2Long2Long2();
-        checkClampLong3Long3Long3Long3();
-        checkClampLong4Long4Long4Long4();
-        checkClampUlongUlongUlongUlong();
-        checkClampUlong2Ulong2Ulong2Ulong2();
-        checkClampUlong3Ulong3Ulong3Ulong3();
-        checkClampUlong4Ulong4Ulong4Ulong4();
-        checkClampChar2CharCharChar2();
-        checkClampChar3CharCharChar3();
-        checkClampChar4CharCharChar4();
-        checkClampUchar2UcharUcharUchar2();
-        checkClampUchar3UcharUcharUchar3();
-        checkClampUchar4UcharUcharUchar4();
-        checkClampShort2ShortShortShort2();
-        checkClampShort3ShortShortShort3();
-        checkClampShort4ShortShortShort4();
-        checkClampUshort2UshortUshortUshort2();
-        checkClampUshort3UshortUshortUshort3();
-        checkClampUshort4UshortUshortUshort4();
-        checkClampInt2IntIntInt2();
-        checkClampInt3IntIntInt3();
-        checkClampInt4IntIntInt4();
-        checkClampUint2UintUintUint2();
-        checkClampUint3UintUintUint3();
-        checkClampUint4UintUintUint4();
-        checkClampLong2LongLongLong2();
-        checkClampLong3LongLongLong3();
-        checkClampLong4LongLongLong4();
-        checkClampUlong2UlongUlongUlong2();
-        checkClampUlong3UlongUlongUlong3();
-        checkClampUlong4UlongUlongUlong4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestClamp.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestClamp.rs
deleted file mode 100644
index 9bb5c87..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestClamp.rs
+++ /dev/null
@@ -1,401 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInMinValue;
-rs_allocation gAllocInMaxValue;
-
-float __attribute__((kernel)) testClampFloatFloatFloatFloat(float inValue, unsigned int x) {
-    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
-    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-float2 __attribute__((kernel)) testClampFloat2Float2Float2Float2(float2 inValue, unsigned int x) {
-    float2 inMinValue = rsGetElementAt_float2(gAllocInMinValue, x);
-    float2 inMaxValue = rsGetElementAt_float2(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-float3 __attribute__((kernel)) testClampFloat3Float3Float3Float3(float3 inValue, unsigned int x) {
-    float3 inMinValue = rsGetElementAt_float3(gAllocInMinValue, x);
-    float3 inMaxValue = rsGetElementAt_float3(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-float4 __attribute__((kernel)) testClampFloat4Float4Float4Float4(float4 inValue, unsigned int x) {
-    float4 inMinValue = rsGetElementAt_float4(gAllocInMinValue, x);
-    float4 inMaxValue = rsGetElementAt_float4(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-float2 __attribute__((kernel)) testClampFloat2FloatFloatFloat2(float2 inValue, unsigned int x) {
-    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
-    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-float3 __attribute__((kernel)) testClampFloat3FloatFloatFloat3(float3 inValue, unsigned int x) {
-    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
-    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-float4 __attribute__((kernel)) testClampFloat4FloatFloatFloat4(float4 inValue, unsigned int x) {
-    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
-    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-char __attribute__((kernel)) testClampCharCharCharChar(char inValue, unsigned int x) {
-    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
-    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-char2 __attribute__((kernel)) testClampChar2Char2Char2Char2(char2 inValue, unsigned int x) {
-    char2 inMinValue = rsGetElementAt_char2(gAllocInMinValue, x);
-    char2 inMaxValue = rsGetElementAt_char2(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-char3 __attribute__((kernel)) testClampChar3Char3Char3Char3(char3 inValue, unsigned int x) {
-    char3 inMinValue = rsGetElementAt_char3(gAllocInMinValue, x);
-    char3 inMaxValue = rsGetElementAt_char3(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-char4 __attribute__((kernel)) testClampChar4Char4Char4Char4(char4 inValue, unsigned int x) {
-    char4 inMinValue = rsGetElementAt_char4(gAllocInMinValue, x);
-    char4 inMaxValue = rsGetElementAt_char4(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uchar __attribute__((kernel)) testClampUcharUcharUcharUchar(uchar inValue, unsigned int x) {
-    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
-    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uchar2 __attribute__((kernel)) testClampUchar2Uchar2Uchar2Uchar2(uchar2 inValue, unsigned int x) {
-    uchar2 inMinValue = rsGetElementAt_uchar2(gAllocInMinValue, x);
-    uchar2 inMaxValue = rsGetElementAt_uchar2(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uchar3 __attribute__((kernel)) testClampUchar3Uchar3Uchar3Uchar3(uchar3 inValue, unsigned int x) {
-    uchar3 inMinValue = rsGetElementAt_uchar3(gAllocInMinValue, x);
-    uchar3 inMaxValue = rsGetElementAt_uchar3(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uchar4 __attribute__((kernel)) testClampUchar4Uchar4Uchar4Uchar4(uchar4 inValue, unsigned int x) {
-    uchar4 inMinValue = rsGetElementAt_uchar4(gAllocInMinValue, x);
-    uchar4 inMaxValue = rsGetElementAt_uchar4(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-short __attribute__((kernel)) testClampShortShortShortShort(short inValue, unsigned int x) {
-    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
-    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-short2 __attribute__((kernel)) testClampShort2Short2Short2Short2(short2 inValue, unsigned int x) {
-    short2 inMinValue = rsGetElementAt_short2(gAllocInMinValue, x);
-    short2 inMaxValue = rsGetElementAt_short2(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-short3 __attribute__((kernel)) testClampShort3Short3Short3Short3(short3 inValue, unsigned int x) {
-    short3 inMinValue = rsGetElementAt_short3(gAllocInMinValue, x);
-    short3 inMaxValue = rsGetElementAt_short3(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-short4 __attribute__((kernel)) testClampShort4Short4Short4Short4(short4 inValue, unsigned int x) {
-    short4 inMinValue = rsGetElementAt_short4(gAllocInMinValue, x);
-    short4 inMaxValue = rsGetElementAt_short4(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ushort __attribute__((kernel)) testClampUshortUshortUshortUshort(ushort inValue, unsigned int x) {
-    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
-    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ushort2 __attribute__((kernel)) testClampUshort2Ushort2Ushort2Ushort2(ushort2 inValue, unsigned int x) {
-    ushort2 inMinValue = rsGetElementAt_ushort2(gAllocInMinValue, x);
-    ushort2 inMaxValue = rsGetElementAt_ushort2(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ushort3 __attribute__((kernel)) testClampUshort3Ushort3Ushort3Ushort3(ushort3 inValue, unsigned int x) {
-    ushort3 inMinValue = rsGetElementAt_ushort3(gAllocInMinValue, x);
-    ushort3 inMaxValue = rsGetElementAt_ushort3(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ushort4 __attribute__((kernel)) testClampUshort4Ushort4Ushort4Ushort4(ushort4 inValue, unsigned int x) {
-    ushort4 inMinValue = rsGetElementAt_ushort4(gAllocInMinValue, x);
-    ushort4 inMaxValue = rsGetElementAt_ushort4(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-int __attribute__((kernel)) testClampIntIntIntInt(int inValue, unsigned int x) {
-    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
-    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-int2 __attribute__((kernel)) testClampInt2Int2Int2Int2(int2 inValue, unsigned int x) {
-    int2 inMinValue = rsGetElementAt_int2(gAllocInMinValue, x);
-    int2 inMaxValue = rsGetElementAt_int2(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-int3 __attribute__((kernel)) testClampInt3Int3Int3Int3(int3 inValue, unsigned int x) {
-    int3 inMinValue = rsGetElementAt_int3(gAllocInMinValue, x);
-    int3 inMaxValue = rsGetElementAt_int3(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-int4 __attribute__((kernel)) testClampInt4Int4Int4Int4(int4 inValue, unsigned int x) {
-    int4 inMinValue = rsGetElementAt_int4(gAllocInMinValue, x);
-    int4 inMaxValue = rsGetElementAt_int4(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uint __attribute__((kernel)) testClampUintUintUintUint(uint inValue, unsigned int x) {
-    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
-    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uint2 __attribute__((kernel)) testClampUint2Uint2Uint2Uint2(uint2 inValue, unsigned int x) {
-    uint2 inMinValue = rsGetElementAt_uint2(gAllocInMinValue, x);
-    uint2 inMaxValue = rsGetElementAt_uint2(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uint3 __attribute__((kernel)) testClampUint3Uint3Uint3Uint3(uint3 inValue, unsigned int x) {
-    uint3 inMinValue = rsGetElementAt_uint3(gAllocInMinValue, x);
-    uint3 inMaxValue = rsGetElementAt_uint3(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uint4 __attribute__((kernel)) testClampUint4Uint4Uint4Uint4(uint4 inValue, unsigned int x) {
-    uint4 inMinValue = rsGetElementAt_uint4(gAllocInMinValue, x);
-    uint4 inMaxValue = rsGetElementAt_uint4(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-long __attribute__((kernel)) testClampLongLongLongLong(long inValue, unsigned int x) {
-    long inMinValue = rsGetElementAt_long(gAllocInMinValue, x);
-    long inMaxValue = rsGetElementAt_long(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-long2 __attribute__((kernel)) testClampLong2Long2Long2Long2(long2 inValue, unsigned int x) {
-    long2 inMinValue = rsGetElementAt_long2(gAllocInMinValue, x);
-    long2 inMaxValue = rsGetElementAt_long2(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-long3 __attribute__((kernel)) testClampLong3Long3Long3Long3(long3 inValue, unsigned int x) {
-    long3 inMinValue = rsGetElementAt_long3(gAllocInMinValue, x);
-    long3 inMaxValue = rsGetElementAt_long3(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-long4 __attribute__((kernel)) testClampLong4Long4Long4Long4(long4 inValue, unsigned int x) {
-    long4 inMinValue = rsGetElementAt_long4(gAllocInMinValue, x);
-    long4 inMaxValue = rsGetElementAt_long4(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ulong __attribute__((kernel)) testClampUlongUlongUlongUlong(ulong inValue, unsigned int x) {
-    ulong inMinValue = rsGetElementAt_ulong(gAllocInMinValue, x);
-    ulong inMaxValue = rsGetElementAt_ulong(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ulong2 __attribute__((kernel)) testClampUlong2Ulong2Ulong2Ulong2(ulong2 inValue, unsigned int x) {
-    ulong2 inMinValue = rsGetElementAt_ulong2(gAllocInMinValue, x);
-    ulong2 inMaxValue = rsGetElementAt_ulong2(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ulong3 __attribute__((kernel)) testClampUlong3Ulong3Ulong3Ulong3(ulong3 inValue, unsigned int x) {
-    ulong3 inMinValue = rsGetElementAt_ulong3(gAllocInMinValue, x);
-    ulong3 inMaxValue = rsGetElementAt_ulong3(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ulong4 __attribute__((kernel)) testClampUlong4Ulong4Ulong4Ulong4(ulong4 inValue, unsigned int x) {
-    ulong4 inMinValue = rsGetElementAt_ulong4(gAllocInMinValue, x);
-    ulong4 inMaxValue = rsGetElementAt_ulong4(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-char2 __attribute__((kernel)) testClampChar2CharCharChar2(char2 inValue, unsigned int x) {
-    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
-    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-char3 __attribute__((kernel)) testClampChar3CharCharChar3(char3 inValue, unsigned int x) {
-    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
-    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-char4 __attribute__((kernel)) testClampChar4CharCharChar4(char4 inValue, unsigned int x) {
-    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
-    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uchar2 __attribute__((kernel)) testClampUchar2UcharUcharUchar2(uchar2 inValue, unsigned int x) {
-    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
-    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uchar3 __attribute__((kernel)) testClampUchar3UcharUcharUchar3(uchar3 inValue, unsigned int x) {
-    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
-    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uchar4 __attribute__((kernel)) testClampUchar4UcharUcharUchar4(uchar4 inValue, unsigned int x) {
-    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
-    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-short2 __attribute__((kernel)) testClampShort2ShortShortShort2(short2 inValue, unsigned int x) {
-    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
-    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-short3 __attribute__((kernel)) testClampShort3ShortShortShort3(short3 inValue, unsigned int x) {
-    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
-    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-short4 __attribute__((kernel)) testClampShort4ShortShortShort4(short4 inValue, unsigned int x) {
-    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
-    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ushort2 __attribute__((kernel)) testClampUshort2UshortUshortUshort2(ushort2 inValue, unsigned int x) {
-    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
-    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ushort3 __attribute__((kernel)) testClampUshort3UshortUshortUshort3(ushort3 inValue, unsigned int x) {
-    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
-    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ushort4 __attribute__((kernel)) testClampUshort4UshortUshortUshort4(ushort4 inValue, unsigned int x) {
-    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
-    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-int2 __attribute__((kernel)) testClampInt2IntIntInt2(int2 inValue, unsigned int x) {
-    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
-    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-int3 __attribute__((kernel)) testClampInt3IntIntInt3(int3 inValue, unsigned int x) {
-    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
-    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-int4 __attribute__((kernel)) testClampInt4IntIntInt4(int4 inValue, unsigned int x) {
-    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
-    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uint2 __attribute__((kernel)) testClampUint2UintUintUint2(uint2 inValue, unsigned int x) {
-    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
-    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uint3 __attribute__((kernel)) testClampUint3UintUintUint3(uint3 inValue, unsigned int x) {
-    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
-    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-uint4 __attribute__((kernel)) testClampUint4UintUintUint4(uint4 inValue, unsigned int x) {
-    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
-    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-long2 __attribute__((kernel)) testClampLong2LongLongLong2(long2 inValue, unsigned int x) {
-    long inMinValue = rsGetElementAt_long(gAllocInMinValue, x);
-    long inMaxValue = rsGetElementAt_long(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-long3 __attribute__((kernel)) testClampLong3LongLongLong3(long3 inValue, unsigned int x) {
-    long inMinValue = rsGetElementAt_long(gAllocInMinValue, x);
-    long inMaxValue = rsGetElementAt_long(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-long4 __attribute__((kernel)) testClampLong4LongLongLong4(long4 inValue, unsigned int x) {
-    long inMinValue = rsGetElementAt_long(gAllocInMinValue, x);
-    long inMaxValue = rsGetElementAt_long(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ulong2 __attribute__((kernel)) testClampUlong2UlongUlongUlong2(ulong2 inValue, unsigned int x) {
-    ulong inMinValue = rsGetElementAt_ulong(gAllocInMinValue, x);
-    ulong inMaxValue = rsGetElementAt_ulong(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ulong3 __attribute__((kernel)) testClampUlong3UlongUlongUlong3(ulong3 inValue, unsigned int x) {
-    ulong inMinValue = rsGetElementAt_ulong(gAllocInMinValue, x);
-    ulong inMaxValue = rsGetElementAt_ulong(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
-
-ulong4 __attribute__((kernel)) testClampUlong4UlongUlongUlong4(ulong4 inValue, unsigned int x) {
-    ulong inMinValue = rsGetElementAt_ulong(gAllocInMinValue, x);
-    ulong inMaxValue = rsGetElementAt_ulong(gAllocInMaxValue, x);
-    return clamp(inValue, inMinValue, inMaxValue);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestClampRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestClampRelaxed.rs
deleted file mode 100644
index 15fd58c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestClampRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestClamp.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestClz.java b/tests/tests/renderscript/src/android/renderscript/cts/TestClz.java
deleted file mode 100644
index 51241aa..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestClz.java
+++ /dev/null
@@ -1,1437 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestClz extends RSBaseCompute {
-
-    private ScriptC_TestClz script;
-    private ScriptC_TestClzRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestClz(mRS);
-        scriptRelaxed = new ScriptC_TestClzRelaxed(mRS);
-    }
-
-    public class ArgumentsCharChar {
-        public byte inValue;
-        public byte out;
-    }
-
-    private void checkClzCharChar() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xf6f3a15e2f7765afl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
-            script.forEach_testClzCharChar(inValue, out);
-            verifyResultsClzCharChar(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzCharChar: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testClzCharChar(inValue, out);
-            verifyResultsClzCharChar(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzCharChar: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzCharChar(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharChar args = new ArgumentsCharChar();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzCharChar" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzChar2Char2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xf718b99dcaca5e93l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testClzChar2Char2(inValue, out);
-            verifyResultsClzChar2Char2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testClzChar2Char2(inValue, out);
-            verifyResultsClzChar2Char2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzChar2Char2(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharChar args = new ArgumentsCharChar();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzChar2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzChar3Char3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x21a5da5bc7099347l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testClzChar3Char3(inValue, out);
-            verifyResultsClzChar3Char3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testClzChar3Char3(inValue, out);
-            verifyResultsClzChar3Char3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzChar3Char3(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharChar args = new ArgumentsCharChar();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzChar3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzChar4Char4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x4c32fb19c348c7fbl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testClzChar4Char4(inValue, out);
-            verifyResultsClzChar4Char4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testClzChar4Char4(inValue, out);
-            verifyResultsClzChar4Char4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzChar4Char4(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharChar args = new ArgumentsCharChar();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzChar4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharUchar {
-        public byte inValue;
-        public byte out;
-    }
-
-    private void checkClzUcharUchar() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xd2e451b48b84f57fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            script.forEach_testClzUcharUchar(inValue, out);
-            verifyResultsClzUcharUchar(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUcharUchar: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUcharUchar(inValue, out);
-            verifyResultsClzUcharUchar(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUcharUchar: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUcharUchar(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUcharUchar" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzUchar2Uchar2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x792e2970f47ebc85l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testClzUchar2Uchar2(inValue, out);
-            verifyResultsClzUchar2Uchar2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUchar2Uchar2(inValue, out);
-            verifyResultsClzUchar2Uchar2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUchar2Uchar2(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUchar2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzUchar3Uchar3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x9ee29ef83dbce203l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testClzUchar3Uchar3(inValue, out);
-            verifyResultsClzUchar3Uchar3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUchar3Uchar3(inValue, out);
-            verifyResultsClzUchar3Uchar3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUchar3Uchar3(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUchar3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzUchar4Uchar4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xc497147f86fb0781l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testClzUchar4Uchar4(inValue, out);
-            verifyResultsClzUchar4Uchar4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUchar4Uchar4(inValue, out);
-            verifyResultsClzUchar4Uchar4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUchar4Uchar4(Allocation inValue, Allocation out, boolean relaxed) {
-        byte[] arrayInValue = new byte[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUchar4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortShort {
-        public short inValue;
-        public short out;
-    }
-
-    private void checkClzShortShort() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x3290aea900d8ad53l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
-            script.forEach_testClzShortShort(inValue, out);
-            verifyResultsClzShortShort(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShortShort: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testClzShortShort(inValue, out);
-            verifyResultsClzShortShort(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShortShort: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzShortShort(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShort args = new ArgumentsShortShort();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzShortShort" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzShort2Short2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x81f69d4442dd6ebfl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testClzShort2Short2(inValue, out);
-            verifyResultsClzShort2Short2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testClzShort2Short2(inValue, out);
-            verifyResultsClzShort2Short2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzShort2Short2(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShort args = new ArgumentsShortShort();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzShort2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzShort3Short3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xa7ab12cb8c1b943dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testClzShort3Short3(inValue, out);
-            verifyResultsClzShort3Short3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testClzShort3Short3(inValue, out);
-            verifyResultsClzShort3Short3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzShort3Short3(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShort args = new ArgumentsShortShort();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzShort3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzShort4Short4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xcd5f8852d559b9bbl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testClzShort4Short4(inValue, out);
-            verifyResultsClzShort4Short4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testClzShort4Short4(inValue, out);
-            verifyResultsClzShort4Short4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzShort4Short4(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShort args = new ArgumentsShortShort();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzShort4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortUshort {
-        public short inValue;
-        public short out;
-    }
-
-    private void checkClzUshortUshort() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x97bdeee92c0103a5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            script.forEach_testClzUshortUshort(inValue, out);
-            verifyResultsClzUshortUshort(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshortUshort: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUshortUshort(inValue, out);
-            verifyResultsClzUshortUshort(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshortUshort: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUshortUshort(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUshortUshort" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzUshort2Ushort2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x5ea7a024b2913837l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testClzUshort2Ushort2(inValue, out);
-            verifyResultsClzUshort2Ushort2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUshort2Ushort2(inValue, out);
-            verifyResultsClzUshort2Ushort2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUshort2Ushort2(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUshort2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzUshort3Ushort3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xb3f7537beaa1cfa3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testClzUshort3Ushort3(inValue, out);
-            verifyResultsClzUshort3Ushort3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUshort3Ushort3(inValue, out);
-            verifyResultsClzUshort3Ushort3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUshort3Ushort3(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUshort3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzUshort4Ushort4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x94706d322b2670fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testClzUshort4Ushort4(inValue, out);
-            verifyResultsClzUshort4Ushort4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUshort4Ushort4(inValue, out);
-            verifyResultsClzUshort4Ushort4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUshort4Ushort4(Allocation inValue, Allocation out, boolean relaxed) {
-        short[] arrayInValue = new short[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUshort4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntInt {
-        public int inValue;
-        public int out;
-    }
-
-    private void checkClzIntInt() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xb13809da3142eb97l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            script.forEach_testClzIntInt(inValue, out);
-            verifyResultsClzIntInt(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzIntInt: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testClzIntInt(inValue, out);
-            verifyResultsClzIntInt(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzIntInt: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzIntInt(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntInt args = new ArgumentsIntInt();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzIntInt" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzInt2Int2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xc9fd2c1a27fe3ad5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testClzInt2Int2(inValue, out);
-            verifyResultsClzInt2Int2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testClzInt2Int2(inValue, out);
-            verifyResultsClzInt2Int2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzInt2Int2(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntInt args = new ArgumentsIntInt();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzInt2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzInt3Int3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xd6e2b014f2d24c2bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testClzInt3Int3(inValue, out);
-            verifyResultsClzInt3Int3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testClzInt3Int3(inValue, out);
-            verifyResultsClzInt3Int3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzInt3Int3(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntInt args = new ArgumentsIntInt();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzInt3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzInt4Int4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xe3c8340fbda65d81l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testClzInt4Int4(inValue, out);
-            verifyResultsClzInt4Int4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testClzInt4Int4(inValue, out);
-            verifyResultsClzInt4Int4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzInt4Int4(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntInt args = new ArgumentsIntInt();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%d", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzInt4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintUint {
-        public int inValue;
-        public int out;
-    }
-
-    private void checkClzUintUint() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x64a0b78a75ac502fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            script.forEach_testClzUintUint(inValue, out);
-            verifyResultsClzUintUint(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUintUint: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUintUint(inValue, out);
-            verifyResultsClzUintUint(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUintUint: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUintUint(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUint args = new ArgumentsUintUint();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUintUint" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzUint2Uint2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xf809b50329344f93l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testClzUint2Uint2(inValue, out);
-            verifyResultsClzUint2Uint2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUint2Uint2(inValue, out);
-            verifyResultsClzUint2Uint2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUint2Uint2(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUint args = new ArgumentsUintUint();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUint2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzUint3Uint3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x2296d5c125738447l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testClzUint3Uint3(inValue, out);
-            verifyResultsClzUint3Uint3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUint3Uint3(inValue, out);
-            verifyResultsClzUint3Uint3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUint3Uint3(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUint args = new ArgumentsUintUint();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUint3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkClzUint4Uint4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x4d23f67f21b2b8fbl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testClzUint4Uint4(inValue, out);
-            verifyResultsClzUint4Uint4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testClzUint4Uint4(inValue, out);
-            verifyResultsClzUint4Uint4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsClzUint4Uint4(Allocation inValue, Allocation out, boolean relaxed) {
-        int[] arrayInValue = new int[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUint args = new ArgumentsUintUint();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeClz(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("0x%x", args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkClzUint4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testClz() {
-        checkClzCharChar();
-        checkClzChar2Char2();
-        checkClzChar3Char3();
-        checkClzChar4Char4();
-        checkClzUcharUchar();
-        checkClzUchar2Uchar2();
-        checkClzUchar3Uchar3();
-        checkClzUchar4Uchar4();
-        checkClzShortShort();
-        checkClzShort2Short2();
-        checkClzShort3Short3();
-        checkClzShort4Short4();
-        checkClzUshortUshort();
-        checkClzUshort2Ushort2();
-        checkClzUshort3Ushort3();
-        checkClzUshort4Ushort4();
-        checkClzIntInt();
-        checkClzInt2Int2();
-        checkClzInt3Int3();
-        checkClzInt4Int4();
-        checkClzUintUint();
-        checkClzUint2Uint2();
-        checkClzUint3Uint3();
-        checkClzUint4Uint4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestClz.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestClz.rs
deleted file mode 100644
index 3501e01..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestClz.rs
+++ /dev/null
@@ -1,117 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-char __attribute__((kernel)) testClzCharChar(char inValue) {
-    return clz(inValue);
-}
-
-char2 __attribute__((kernel)) testClzChar2Char2(char2 inValue) {
-    return clz(inValue);
-}
-
-char3 __attribute__((kernel)) testClzChar3Char3(char3 inValue) {
-    return clz(inValue);
-}
-
-char4 __attribute__((kernel)) testClzChar4Char4(char4 inValue) {
-    return clz(inValue);
-}
-
-uchar __attribute__((kernel)) testClzUcharUchar(uchar inValue) {
-    return clz(inValue);
-}
-
-uchar2 __attribute__((kernel)) testClzUchar2Uchar2(uchar2 inValue) {
-    return clz(inValue);
-}
-
-uchar3 __attribute__((kernel)) testClzUchar3Uchar3(uchar3 inValue) {
-    return clz(inValue);
-}
-
-uchar4 __attribute__((kernel)) testClzUchar4Uchar4(uchar4 inValue) {
-    return clz(inValue);
-}
-
-short __attribute__((kernel)) testClzShortShort(short inValue) {
-    return clz(inValue);
-}
-
-short2 __attribute__((kernel)) testClzShort2Short2(short2 inValue) {
-    return clz(inValue);
-}
-
-short3 __attribute__((kernel)) testClzShort3Short3(short3 inValue) {
-    return clz(inValue);
-}
-
-short4 __attribute__((kernel)) testClzShort4Short4(short4 inValue) {
-    return clz(inValue);
-}
-
-ushort __attribute__((kernel)) testClzUshortUshort(ushort inValue) {
-    return clz(inValue);
-}
-
-ushort2 __attribute__((kernel)) testClzUshort2Ushort2(ushort2 inValue) {
-    return clz(inValue);
-}
-
-ushort3 __attribute__((kernel)) testClzUshort3Ushort3(ushort3 inValue) {
-    return clz(inValue);
-}
-
-ushort4 __attribute__((kernel)) testClzUshort4Ushort4(ushort4 inValue) {
-    return clz(inValue);
-}
-
-int __attribute__((kernel)) testClzIntInt(int inValue) {
-    return clz(inValue);
-}
-
-int2 __attribute__((kernel)) testClzInt2Int2(int2 inValue) {
-    return clz(inValue);
-}
-
-int3 __attribute__((kernel)) testClzInt3Int3(int3 inValue) {
-    return clz(inValue);
-}
-
-int4 __attribute__((kernel)) testClzInt4Int4(int4 inValue) {
-    return clz(inValue);
-}
-
-uint __attribute__((kernel)) testClzUintUint(uint inValue) {
-    return clz(inValue);
-}
-
-uint2 __attribute__((kernel)) testClzUint2Uint2(uint2 inValue) {
-    return clz(inValue);
-}
-
-uint3 __attribute__((kernel)) testClzUint3Uint3(uint3 inValue) {
-    return clz(inValue);
-}
-
-uint4 __attribute__((kernel)) testClzUint4Uint4(uint4 inValue) {
-    return clz(inValue);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestClzRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestClzRelaxed.rs
deleted file mode 100644
index c463c94..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestClzRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestClz.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestConvert.java b/tests/tests/renderscript/src/android/renderscript/cts/TestConvert.java
deleted file mode 100644
index fc56b26..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestConvert.java
+++ /dev/null
@@ -1,17819 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestConvert extends RSBaseCompute {
-
-    private ScriptC_TestConvert script;
-    private ScriptC_TestConvertRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestConvert(mRS);
-        scriptRelaxed = new ScriptC_TestConvertRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb5215c44e1f6ac6l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Float2Float2(inV, out);
-            verifyResultsConvertFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Float2Float2(inV, out);
-            verifyResultsConvertFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfb53dedf443a8ba4l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Float3Float3(inV, out);
-            verifyResultsConvertFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Float3Float3(inV, out);
-            verifyResultsConvertFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfb55a7fa3a55ac82l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Float4Float4(inV, out);
-            verifyResultsConvertFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Float4Float4(inV, out);
-            verifyResultsConvertFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharFloat {
-        public byte inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertChar2Float2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x5861e2161f489286l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Char2Float2(inV, out);
-            verifyResultsConvertChar2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Char2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Char2Float2(inV, out);
-            verifyResultsConvertChar2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Char2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharFloat args = new ArgumentsCharFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Float3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x5863ab311563b364l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Char3Float3(inV, out);
-            verifyResultsConvertChar3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Char3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Char3Float3(inV, out);
-            verifyResultsConvertChar3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Char3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharFloat args = new ArgumentsCharFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Float4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x5865744c0b7ed442l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Char4Float4(inV, out);
-            verifyResultsConvertChar4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Char4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Char4Float4(inV, out);
-            verifyResultsConvertChar4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Char4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharFloat args = new ArgumentsCharFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharFloat {
-        public byte inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertUchar2Float2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7d30021dbb20ac31l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Uchar2Float2(inV, out);
-            verifyResultsConvertUchar2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uchar2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Uchar2Float2(inV, out);
-            verifyResultsConvertUchar2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uchar2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharFloat args = new ArgumentsUcharFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Float3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7d31cb38b13bcd0fl, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Uchar3Float3(inV, out);
-            verifyResultsConvertUchar3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uchar3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Uchar3Float3(inV, out);
-            verifyResultsConvertUchar3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uchar3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharFloat args = new ArgumentsUcharFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Float4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7d339453a756ededl, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Uchar4Float4(inV, out);
-            verifyResultsConvertUchar4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uchar4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Uchar4Float4(inV, out);
-            verifyResultsConvertUchar4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uchar4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharFloat args = new ArgumentsUcharFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortFloat {
-        public short inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertShort2Float2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x94ca184eff219172l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Short2Float2(inV, out);
-            verifyResultsConvertShort2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Short2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Short2Float2(inV, out);
-            verifyResultsConvertShort2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Short2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortFloat args = new ArgumentsShortFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Float3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x94cbe169f53cb250l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Short3Float3(inV, out);
-            verifyResultsConvertShort3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Short3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Short3Float3(inV, out);
-            verifyResultsConvertShort3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Short3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortFloat args = new ArgumentsShortFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Float4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x94cdaa84eb57d32el, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Short4Float4(inV, out);
-            verifyResultsConvertShort4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Short4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Short4Float4(inV, out);
-            verifyResultsConvertShort4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Short4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortFloat args = new ArgumentsShortFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortFloat {
-        public short inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertUshort2Float2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xc36979962c6de12bl, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Ushort2Float2(inV, out);
-            verifyResultsConvertUshort2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ushort2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Ushort2Float2(inV, out);
-            verifyResultsConvertUshort2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ushort2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortFloat args = new ArgumentsUshortFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Float3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xc36b42b122890209l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Ushort3Float3(inV, out);
-            verifyResultsConvertUshort3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ushort3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Ushort3Float3(inV, out);
-            verifyResultsConvertUshort3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ushort3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortFloat args = new ArgumentsUshortFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Float4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xc36d0bcc18a422e7l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Ushort4Float4(inV, out);
-            verifyResultsConvertUshort4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ushort4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Ushort4Float4(inV, out);
-            verifyResultsConvertUshort4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ushort4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortFloat args = new ArgumentsUshortFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntFloat {
-        public int inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertInt2Float2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x2a52c7eb7402bfc5l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Int2Float2(inV, out);
-            verifyResultsConvertInt2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Int2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Int2Float2(inV, out);
-            verifyResultsConvertInt2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Int2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntFloat args = new ArgumentsIntFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Float3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x2a5491066a1de0a3l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Int3Float3(inV, out);
-            verifyResultsConvertInt3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Int3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Int3Float3(inV, out);
-            verifyResultsConvertInt3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Int3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntFloat args = new ArgumentsIntFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Float4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x2a565a2160390181l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Int4Float4(inV, out);
-            verifyResultsConvertInt4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Int4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Int4Float4(inV, out);
-            verifyResultsConvertInt4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Int4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntFloat args = new ArgumentsIntFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintFloat {
-        public int inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertUint2Float2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xd1e081390684cc46l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Uint2Float2(inV, out);
-            verifyResultsConvertUint2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uint2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Uint2Float2(inV, out);
-            verifyResultsConvertUint2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uint2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintFloat args = new ArgumentsUintFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Float3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xd1e24a53fc9fed24l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Uint3Float3(inV, out);
-            verifyResultsConvertUint3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uint3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Uint3Float3(inV, out);
-            verifyResultsConvertUint3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uint3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintFloat args = new ArgumentsUintFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Float4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xd1e4136ef2bb0e02l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Uint4Float4(inV, out);
-            verifyResultsConvertUint4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uint4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Uint4Float4(inV, out);
-            verifyResultsConvertUint4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uint4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintFloat args = new ArgumentsUintFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatChar {
-        public float inV;
-        public byte out;
-    }
-
-    private void checkConvertFloat2Char2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x239cb25829789662l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Float2Char2(inV, out);
-            verifyResultsConvertFloat2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Float2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Float2Char2(inV, out);
-            verifyResultsConvertFloat2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Float2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatChar args = new ArgumentsFloatChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Char3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x239cbcf988805b56l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Float3Char3(inV, out);
-            verifyResultsConvertFloat3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Float3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Float3Char3(inV, out);
-            verifyResultsConvertFloat3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Float3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatChar args = new ArgumentsFloatChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Char4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x239cc79ae788204al, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Float4Char4(inV, out);
-            verifyResultsConvertFloat4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Float4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Float4Char4(inV, out);
-            verifyResultsConvertFloat4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Float4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatChar args = new ArgumentsFloatChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharChar {
-        public byte inV;
-        public byte out;
-    }
-
-    private void checkConvertChar2Char2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd8618777d5086da2l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Char2Char2(inV, out);
-            verifyResultsConvertChar2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Char2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Char2Char2(inV, out);
-            verifyResultsConvertChar2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Char2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharChar args = new ArgumentsCharChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Char3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xd861921934103296l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Char3Char3(inV, out);
-            verifyResultsConvertChar3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Char3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Char3Char3(inV, out);
-            verifyResultsConvertChar3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Char3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharChar args = new ArgumentsCharChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Char4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd8619cba9317f78al, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Char4Char4(inV, out);
-            verifyResultsConvertChar4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Char4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Char4Char4(inV, out);
-            verifyResultsConvertChar4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Char4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharChar args = new ArgumentsCharChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharChar {
-        public byte inV;
-        public byte out;
-    }
-
-    private void checkConvertUchar2Char2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7fef40c5678a7a23l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Uchar2Char2(inV, out);
-            verifyResultsConvertUchar2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uchar2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Uchar2Char2(inV, out);
-            verifyResultsConvertUchar2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uchar2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharChar args = new ArgumentsUcharChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Char3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7fef4b66c6923f17l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Uchar3Char3(inV, out);
-            verifyResultsConvertUchar3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uchar3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Uchar3Char3(inV, out);
-            verifyResultsConvertUchar3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uchar3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharChar args = new ArgumentsUcharChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Char4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7fef5608259a040bl, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Uchar4Char4(inV, out);
-            verifyResultsConvertUchar4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uchar4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Uchar4Char4(inV, out);
-            verifyResultsConvertUchar4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uchar4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharChar args = new ArgumentsUcharChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortChar {
-        public short inV;
-        public byte out;
-    }
-
-    private void checkConvertShort2Char2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x68ab650215c60866l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Short2Char2(inV, out);
-            verifyResultsConvertShort2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Short2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Short2Char2(inV, out);
-            verifyResultsConvertShort2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Short2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortChar args = new ArgumentsShortChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Char3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x68ab6fa374cdcd5al, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Short3Char3(inV, out);
-            verifyResultsConvertShort3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Short3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Short3Char3(inV, out);
-            verifyResultsConvertShort3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Short3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortChar args = new ArgumentsShortChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Char4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x68ab7a44d3d5924el, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Short4Char4(inV, out);
-            verifyResultsConvertShort4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Short4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Short4Char4(inV, out);
-            verifyResultsConvertShort4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Short4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortChar args = new ArgumentsShortChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortChar {
-        public short inV;
-        public byte out;
-    }
-
-    private void checkConvertUshort2Char2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x8d798509b19e2211l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Ushort2Char2(inV, out);
-            verifyResultsConvertUshort2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ushort2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Ushort2Char2(inV, out);
-            verifyResultsConvertUshort2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ushort2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortChar args = new ArgumentsUshortChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Char3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x8d798fab10a5e705l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Ushort3Char3(inV, out);
-            verifyResultsConvertUshort3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ushort3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Ushort3Char3(inV, out);
-            verifyResultsConvertUshort3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ushort3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortChar args = new ArgumentsUshortChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Char4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x8d799a4c6fadabf9l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Ushort4Char4(inV, out);
-            verifyResultsConvertUshort4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ushort4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Ushort4Char4(inV, out);
-            verifyResultsConvertUshort4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ushort4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortChar args = new ArgumentsUshortChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntChar {
-        public int inV;
-        public byte out;
-    }
-
-    private void checkConvertInt2Char2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xd74f5147364256dfl, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Int2Char2(inV, out);
-            verifyResultsConvertInt2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Int2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Int2Char2(inV, out);
-            verifyResultsConvertInt2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Int2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntChar args = new ArgumentsIntChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Char3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xd74f5be8954a1bd3l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Int3Char3(inV, out);
-            verifyResultsConvertInt3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Int3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Int3Char3(inV, out);
-            verifyResultsConvertInt3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Int3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntChar args = new ArgumentsIntChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Char4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd74f6689f451e0c7l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Int4Char4(inV, out);
-            verifyResultsConvertInt4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Int4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Int4Char4(inV, out);
-            verifyResultsConvertInt4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Int4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntChar args = new ArgumentsIntChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintChar {
-        public int inV;
-        public byte out;
-    }
-
-    private void checkConvertUint2Char2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xe71d083133b67ae2l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Uint2Char2(inV, out);
-            verifyResultsConvertUint2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uint2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Uint2Char2(inV, out);
-            verifyResultsConvertUint2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uint2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintChar args = new ArgumentsUintChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Char3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe71d12d292be3fd6l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Uint3Char3(inV, out);
-            verifyResultsConvertUint3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uint3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Uint3Char3(inV, out);
-            verifyResultsConvertUint3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uint3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintChar args = new ArgumentsUintChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Char4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xe71d1d73f1c604cal, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Uint4Char4(inV, out);
-            verifyResultsConvertUint4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uint4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Uint4Char4(inV, out);
-            verifyResultsConvertUint4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uint4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintChar args = new ArgumentsUintChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatUchar {
-        public float inV;
-        public byte out;
-    }
-
-    private void checkConvertFloat2Uchar2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb52b2f4fac15b79l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Float2Uchar2(inV, out);
-            verifyResultsConvertFloat2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Float2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Float2Uchar2(inV, out);
-            verifyResultsConvertFloat2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Float2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUchar args = new ArgumentsFloatUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Uchar3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfb547c0ff0dc7c57l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Float3Uchar3(inV, out);
-            verifyResultsConvertFloat3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Float3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Float3Uchar3(inV, out);
-            verifyResultsConvertFloat3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Float3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUchar args = new ArgumentsFloatUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Uchar4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfb56452ae6f79d35l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Float4Uchar4(inV, out);
-            verifyResultsConvertFloat4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Float4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Float4Uchar4(inV, out);
-            verifyResultsConvertFloat4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Float4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUchar args = new ArgumentsFloatUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharUchar {
-        public byte inV;
-        public byte out;
-    }
-
-    private void checkConvertChar2Uchar2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x58627f46cbea8339l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Char2Uchar2(inV, out);
-            verifyResultsConvertChar2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Char2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Char2Uchar2(inV, out);
-            verifyResultsConvertChar2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Char2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUchar args = new ArgumentsCharUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Uchar3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x58644861c205a417l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Char3Uchar3(inV, out);
-            verifyResultsConvertChar3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Char3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Char3Uchar3(inV, out);
-            verifyResultsConvertChar3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Char3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUchar args = new ArgumentsCharUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Uchar4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x5866117cb820c4f5l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Char4Uchar4(inV, out);
-            verifyResultsConvertChar4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Char4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Char4Uchar4(inV, out);
-            verifyResultsConvertChar4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Char4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUchar args = new ArgumentsCharUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharUchar {
-        public byte inV;
-        public byte out;
-    }
-
-    private void checkConvertUchar2Uchar2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7d309f4e67c29ce4l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Uchar2Uchar2(inV, out);
-            verifyResultsConvertUchar2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uchar2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Uchar2Uchar2(inV, out);
-            verifyResultsConvertUchar2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uchar2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Uchar3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7d3268695dddbdc2l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Uchar3Uchar3(inV, out);
-            verifyResultsConvertUchar3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uchar3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Uchar3Uchar3(inV, out);
-            verifyResultsConvertUchar3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uchar3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Uchar4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7d34318453f8dea0l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Uchar4Uchar4(inV, out);
-            verifyResultsConvertUchar4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uchar4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Uchar4Uchar4(inV, out);
-            verifyResultsConvertUchar4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uchar4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortUchar {
-        public short inV;
-        public byte out;
-    }
-
-    private void checkConvertShort2Uchar2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x94cab57fabc38225l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Short2Uchar2(inV, out);
-            verifyResultsConvertShort2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Short2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Short2Uchar2(inV, out);
-            verifyResultsConvertShort2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Short2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUchar args = new ArgumentsShortUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Uchar3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x94cc7e9aa1dea303l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Short3Uchar3(inV, out);
-            verifyResultsConvertShort3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Short3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Short3Uchar3(inV, out);
-            verifyResultsConvertShort3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Short3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUchar args = new ArgumentsShortUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Uchar4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x94ce47b597f9c3e1l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Short4Uchar4(inV, out);
-            verifyResultsConvertShort4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Short4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Short4Uchar4(inV, out);
-            verifyResultsConvertShort4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Short4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUchar args = new ArgumentsShortUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortUchar {
-        public short inV;
-        public byte out;
-    }
-
-    private void checkConvertUshort2Uchar2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xc36a16c6d90fd1del, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Ushort2Uchar2(inV, out);
-            verifyResultsConvertUshort2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ushort2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Ushort2Uchar2(inV, out);
-            verifyResultsConvertUshort2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ushort2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUchar args = new ArgumentsUshortUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Uchar3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xc36bdfe1cf2af2bcl, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Ushort3Uchar3(inV, out);
-            verifyResultsConvertUshort3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ushort3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Ushort3Uchar3(inV, out);
-            verifyResultsConvertUshort3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ushort3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUchar args = new ArgumentsUshortUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Uchar4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xc36da8fcc546139al, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Ushort4Uchar4(inV, out);
-            verifyResultsConvertUshort4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ushort4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Ushort4Uchar4(inV, out);
-            verifyResultsConvertUshort4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ushort4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUchar args = new ArgumentsUshortUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntUchar {
-        public int inV;
-        public byte out;
-    }
-
-    private void checkConvertInt2Uchar2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x2a53651c20a4b078l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Int2Uchar2(inV, out);
-            verifyResultsConvertInt2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Int2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Int2Uchar2(inV, out);
-            verifyResultsConvertInt2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Int2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUchar args = new ArgumentsIntUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Uchar3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x2a552e3716bfd156l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Int3Uchar3(inV, out);
-            verifyResultsConvertInt3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Int3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Int3Uchar3(inV, out);
-            verifyResultsConvertInt3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Int3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUchar args = new ArgumentsIntUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Uchar4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x2a56f7520cdaf234l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Int4Uchar4(inV, out);
-            verifyResultsConvertInt4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Int4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Int4Uchar4(inV, out);
-            verifyResultsConvertInt4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Int4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUchar args = new ArgumentsIntUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintUchar {
-        public int inV;
-        public byte out;
-    }
-
-    private void checkConvertUint2Uchar2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xd1e11e69b326bcf9l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Uint2Uchar2(inV, out);
-            verifyResultsConvertUint2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uint2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Uint2Uchar2(inV, out);
-            verifyResultsConvertUint2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uint2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUchar args = new ArgumentsUintUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Uchar3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xd1e2e784a941ddd7l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Uint3Uchar3(inV, out);
-            verifyResultsConvertUint3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uint3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Uint3Uchar3(inV, out);
-            verifyResultsConvertUint3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uint3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUchar args = new ArgumentsUintUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Uchar4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xd1e4b09f9f5cfeb5l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Uint4Uchar4(inV, out);
-            verifyResultsConvertUint4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uint4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Uint4Uchar4(inV, out);
-            verifyResultsConvertUint4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uint4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUchar args = new ArgumentsUintUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatShort {
-        public float inV;
-        public short out;
-    }
-
-    private void checkConvertFloat2Short2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb529ef98fcf2692l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Float2Short2(inV, out);
-            verifyResultsConvertFloat2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Float2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Float2Short2(inV, out);
-            verifyResultsConvertFloat2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Float2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatShort args = new ArgumentsFloatShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Short3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfb54681485ea4770l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Float3Short3(inV, out);
-            verifyResultsConvertFloat3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Float3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Float3Short3(inV, out);
-            verifyResultsConvertFloat3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Float3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatShort args = new ArgumentsFloatShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Short4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfb56312f7c05684el, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Float4Short4(inV, out);
-            verifyResultsConvertFloat4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Float4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Float4Short4(inV, out);
-            verifyResultsConvertFloat4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Float4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatShort args = new ArgumentsFloatShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharShort {
-        public byte inV;
-        public short out;
-    }
-
-    private void checkConvertChar2Short2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x58626b4b60f84e52l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Char2Short2(inV, out);
-            verifyResultsConvertChar2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Char2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Char2Short2(inV, out);
-            verifyResultsConvertChar2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Char2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharShort args = new ArgumentsCharShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Short3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x5864346657136f30l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Char3Short3(inV, out);
-            verifyResultsConvertChar3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Char3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Char3Short3(inV, out);
-            verifyResultsConvertChar3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Char3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharShort args = new ArgumentsCharShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Short4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x5865fd814d2e900el, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Char4Short4(inV, out);
-            verifyResultsConvertChar4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Char4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Char4Short4(inV, out);
-            verifyResultsConvertChar4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Char4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharShort args = new ArgumentsCharShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharShort {
-        public byte inV;
-        public short out;
-    }
-
-    private void checkConvertUchar2Short2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7d308b52fcd067fdl, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Uchar2Short2(inV, out);
-            verifyResultsConvertUchar2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uchar2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Uchar2Short2(inV, out);
-            verifyResultsConvertUchar2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uchar2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharShort args = new ArgumentsUcharShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Short3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7d32546df2eb88dbl, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Uchar3Short3(inV, out);
-            verifyResultsConvertUchar3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uchar3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Uchar3Short3(inV, out);
-            verifyResultsConvertUchar3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uchar3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharShort args = new ArgumentsUcharShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Short4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7d341d88e906a9b9l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Uchar4Short4(inV, out);
-            verifyResultsConvertUchar4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uchar4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Uchar4Short4(inV, out);
-            verifyResultsConvertUchar4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uchar4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharShort args = new ArgumentsUcharShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortShort {
-        public short inV;
-        public short out;
-    }
-
-    private void checkConvertShort2Short2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x94caa18440d14d3el, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Short2Short2(inV, out);
-            verifyResultsConvertShort2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Short2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Short2Short2(inV, out);
-            verifyResultsConvertShort2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Short2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShort args = new ArgumentsShortShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Short3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x94cc6a9f36ec6e1cl, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Short3Short3(inV, out);
-            verifyResultsConvertShort3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Short3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Short3Short3(inV, out);
-            verifyResultsConvertShort3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Short3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShort args = new ArgumentsShortShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Short4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x94ce33ba2d078efal, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Short4Short4(inV, out);
-            verifyResultsConvertShort4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Short4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Short4Short4(inV, out);
-            verifyResultsConvertShort4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Short4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShort args = new ArgumentsShortShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortShort {
-        public short inV;
-        public short out;
-    }
-
-    private void checkConvertUshort2Short2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xc36a02cb6e1d9cf7l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Ushort2Short2(inV, out);
-            verifyResultsConvertUshort2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ushort2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Ushort2Short2(inV, out);
-            verifyResultsConvertUshort2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ushort2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortShort args = new ArgumentsUshortShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Short3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xc36bcbe66438bdd5l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Ushort3Short3(inV, out);
-            verifyResultsConvertUshort3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ushort3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Ushort3Short3(inV, out);
-            verifyResultsConvertUshort3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ushort3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortShort args = new ArgumentsUshortShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Short4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xc36d95015a53deb3l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Ushort4Short4(inV, out);
-            verifyResultsConvertUshort4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ushort4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Ushort4Short4(inV, out);
-            verifyResultsConvertUshort4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ushort4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortShort args = new ArgumentsUshortShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntShort {
-        public int inV;
-        public short out;
-    }
-
-    private void checkConvertInt2Short2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x2a535120b5b27b91l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Int2Short2(inV, out);
-            verifyResultsConvertInt2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Int2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Int2Short2(inV, out);
-            verifyResultsConvertInt2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Int2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntShort args = new ArgumentsIntShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Short3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x2a551a3babcd9c6fl, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Int3Short3(inV, out);
-            verifyResultsConvertInt3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Int3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Int3Short3(inV, out);
-            verifyResultsConvertInt3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Int3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntShort args = new ArgumentsIntShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Short4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x2a56e356a1e8bd4dl, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Int4Short4(inV, out);
-            verifyResultsConvertInt4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Int4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Int4Short4(inV, out);
-            verifyResultsConvertInt4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Int4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntShort args = new ArgumentsIntShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintShort {
-        public int inV;
-        public short out;
-    }
-
-    private void checkConvertUint2Short2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xd1e10a6e48348812l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Uint2Short2(inV, out);
-            verifyResultsConvertUint2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uint2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Uint2Short2(inV, out);
-            verifyResultsConvertUint2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uint2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintShort args = new ArgumentsUintShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Short3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xd1e2d3893e4fa8f0l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Uint3Short3(inV, out);
-            verifyResultsConvertUint3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uint3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Uint3Short3(inV, out);
-            verifyResultsConvertUint3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uint3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintShort args = new ArgumentsUintShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Short4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xd1e49ca4346ac9cel, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Uint4Short4(inV, out);
-            verifyResultsConvertUint4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uint4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Uint4Short4(inV, out);
-            verifyResultsConvertUint4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uint4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintShort args = new ArgumentsUintShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatUshort {
-        public float inV;
-        public short out;
-    }
-
-    private void checkConvertFloat2Ushort2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x36e4b950b708416fl, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Float2Ushort2(inV, out);
-            verifyResultsConvertFloat2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Float2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Float2Ushort2(inV, out);
-            verifyResultsConvertFloat2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Float2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUshort args = new ArgumentsFloatUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Ushort3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x373180d80d63d29bl, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Float3Ushort3(inV, out);
-            verifyResultsConvertFloat3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Float3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Float3Ushort3(inV, out);
-            verifyResultsConvertFloat3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Float3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUshort args = new ArgumentsFloatUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Ushort4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x377e485f63bf63c7l, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Float4Ushort4(inV, out);
-            verifyResultsConvertFloat4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Float4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Float4Ushort4(inV, out);
-            verifyResultsConvertFloat4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Float4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUshort args = new ArgumentsFloatUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharUshort {
-        public byte inV;
-        public short out;
-    }
-
-    private void checkConvertChar2Ushort2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd88c0b0ed8f1eeafl, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Char2Ushort2(inV, out);
-            verifyResultsConvertChar2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Char2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Char2Ushort2(inV, out);
-            verifyResultsConvertChar2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Char2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUshort args = new ArgumentsCharUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Ushort3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xd8d8d2962f4d7fdbl, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Char3Ushort3(inV, out);
-            verifyResultsConvertChar3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Char3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Char3Ushort3(inV, out);
-            verifyResultsConvertChar3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Char3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUshort args = new ArgumentsCharUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Ushort4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd9259a1d85a91107l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Char4Ushort4(inV, out);
-            verifyResultsConvertChar4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Char4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Char4Ushort4(inV, out);
-            verifyResultsConvertChar4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Char4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUshort args = new ArgumentsCharUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharUshort {
-        public byte inV;
-        public short out;
-    }
-
-    private void checkConvertUchar2Ushort2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x72b6c56063e3e68l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Uchar2Ushort2(inV, out);
-            verifyResultsConvertUchar2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uchar2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Uchar2Ushort2(inV, out);
-            verifyResultsConvertUchar2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uchar2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUshort args = new ArgumentsUcharUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Ushort3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x77833dd5c99cf94l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Uchar3Ushort3(inV, out);
-            verifyResultsConvertUchar3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uchar3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Uchar3Ushort3(inV, out);
-            verifyResultsConvertUchar3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uchar3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUshort args = new ArgumentsUcharUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Ushort4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7c4fb64b2f560c0l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Uchar4Ushort4(inV, out);
-            verifyResultsConvertUchar4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uchar4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Uchar4Ushort4(inV, out);
-            verifyResultsConvertUchar4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uchar4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUshort args = new ArgumentsUcharUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortUshort {
-        public short inV;
-        public short out;
-    }
-
-    private void checkConvertShort2Ushort2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xfe0d269c7264c053l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Short2Ushort2(inV, out);
-            verifyResultsConvertShort2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Short2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Short2Ushort2(inV, out);
-            verifyResultsConvertShort2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Short2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUshort args = new ArgumentsShortUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Ushort3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xfe59ee23c8c0517fl, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Short3Ushort3(inV, out);
-            verifyResultsConvertShort3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Short3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Short3Ushort3(inV, out);
-            verifyResultsConvertShort3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Short3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUshort args = new ArgumentsShortUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Ushort4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xfea6b5ab1f1be2abl, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Short4Ushort4(inV, out);
-            verifyResultsConvertShort4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Short4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Short4Ushort4(inV, out);
-            verifyResultsConvertShort4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Short4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUshort args = new ArgumentsShortUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortUshort {
-        public short inV;
-        public short out;
-    }
-
-    private void checkConvertUshort2Ushort2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xd2d27d910e362466l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Ushort2Ushort2(inV, out);
-            verifyResultsConvertUshort2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ushort2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Ushort2Ushort2(inV, out);
-            verifyResultsConvertUshort2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ushort2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Ushort3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xd31f45186491b592l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Ushort3Ushort3(inV, out);
-            verifyResultsConvertUshort3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ushort3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Ushort3Ushort3(inV, out);
-            verifyResultsConvertUshort3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ushort3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Ushort4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xd36c0c9fbaed46bel, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Ushort4Ushort4(inV, out);
-            verifyResultsConvertUshort4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ushort4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Ushort4Ushort4(inV, out);
-            verifyResultsConvertUshort4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ushort4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntUshort {
-        public int inV;
-        public short out;
-    }
-
-    private void checkConvertInt2Ushort2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x1c02a5e414378844l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Int2Ushort2(inV, out);
-            verifyResultsConvertInt2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Int2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Int2Ushort2(inV, out);
-            verifyResultsConvertInt2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Int2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUshort args = new ArgumentsIntUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Ushort3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x1c4f6d6b6a931970l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Int3Ushort3(inV, out);
-            verifyResultsConvertInt3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Int3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Int3Ushort3(inV, out);
-            verifyResultsConvertInt3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Int3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUshort args = new ArgumentsIntUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Ushort4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x1c9c34f2c0eeaa9cl, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Int4Ushort4(inV, out);
-            verifyResultsConvertInt4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Int4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Int4Ushort4(inV, out);
-            verifyResultsConvertInt4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Int4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUshort args = new ArgumentsIntUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintUshort {
-        public int inV;
-        public short out;
-    }
-
-    private void checkConvertUint2Ushort2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x40d0c5ebb00fa1efl, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Uint2Ushort2(inV, out);
-            verifyResultsConvertUint2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uint2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Uint2Ushort2(inV, out);
-            verifyResultsConvertUint2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uint2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUshort args = new ArgumentsUintUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Ushort3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x411d8d73066b331bl, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Uint3Ushort3(inV, out);
-            verifyResultsConvertUint3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uint3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Uint3Ushort3(inV, out);
-            verifyResultsConvertUint3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uint3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUshort args = new ArgumentsUintUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Ushort4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x416a54fa5cc6c447l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Uint4Ushort4(inV, out);
-            verifyResultsConvertUint4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uint4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Uint4Ushort4(inV, out);
-            verifyResultsConvertUint4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uint4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUshort args = new ArgumentsUintUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatInt {
-        public float inV;
-        public int out;
-    }
-
-    private void checkConvertFloat2Int2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8fb63fb7c069dd5dl, -2.1474835210000000000e+09, 2.1474835200000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Float2Int2(inV, out);
-            verifyResultsConvertFloat2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Float2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Float2Int2(inV, out);
-            verifyResultsConvertFloat2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Float2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatInt args = new ArgumentsFloatInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Int3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8fb63ff70a11ed93l, -2.1474835210000000000e+09, 2.1474835200000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Float3Int3(inV, out);
-            verifyResultsConvertFloat3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Float3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Float3Int3(inV, out);
-            verifyResultsConvertFloat3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Float3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatInt args = new ArgumentsFloatInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Int4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8fb6403653b9fdc9l, -2.1474835210000000000e+09, 2.1474835200000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Float4Int4(inV, out);
-            verifyResultsConvertFloat4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Float4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Float4Int4(inV, out);
-            verifyResultsConvertFloat4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Float4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatInt args = new ArgumentsFloatInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharInt {
-        public byte inV;
-        public int out;
-    }
-
-    private void checkConvertChar2Int2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x880244ac94c6831dl, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Char2Int2(inV, out);
-            verifyResultsConvertChar2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Char2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Char2Int2(inV, out);
-            verifyResultsConvertChar2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Char2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharInt args = new ArgumentsCharInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Int3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x880244ebde6e9353l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Char3Int3(inV, out);
-            verifyResultsConvertChar3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Char3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Char3Int3(inV, out);
-            verifyResultsConvertChar3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Char3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharInt args = new ArgumentsCharInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Int4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x8802452b2816a389l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Char4Int4(inV, out);
-            verifyResultsConvertChar4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Char4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Char4Int4(inV, out);
-            verifyResultsConvertChar4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Char4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharInt args = new ArgumentsCharInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharInt {
-        public byte inV;
-        public int out;
-    }
-
-    private void checkConvertUchar2Int2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x97cffb96923aa720l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Uchar2Int2(inV, out);
-            verifyResultsConvertUchar2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uchar2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Uchar2Int2(inV, out);
-            verifyResultsConvertUchar2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uchar2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharInt args = new ArgumentsUcharInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Int3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x97cffbd5dbe2b756l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Uchar3Int3(inV, out);
-            verifyResultsConvertUchar3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uchar3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Uchar3Int3(inV, out);
-            verifyResultsConvertUchar3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uchar3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharInt args = new ArgumentsUcharInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Int4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x97cffc15258ac78cl, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Uchar4Int4(inV, out);
-            verifyResultsConvertUchar4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uchar4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Uchar4Int4(inV, out);
-            verifyResultsConvertUchar4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uchar4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharInt args = new ArgumentsUcharInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortInt {
-        public short inV;
-        public int out;
-    }
-
-    private void checkConvertShort2Int2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x85693203252a2d69l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Short2Int2(inV, out);
-            verifyResultsConvertShort2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Short2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Short2Int2(inV, out);
-            verifyResultsConvertShort2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Short2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortInt args = new ArgumentsShortInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Int3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x856932426ed23d9fl, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Short3Int3(inV, out);
-            verifyResultsConvertShort3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Short3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Short3Int3(inV, out);
-            verifyResultsConvertShort3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Short3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortInt args = new ArgumentsShortInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Int4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x85693281b87a4dd5l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Short4Int4(inV, out);
-            verifyResultsConvertShort4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Short4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Short4Int4(inV, out);
-            verifyResultsConvertShort4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Short4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortInt args = new ArgumentsShortInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortInt {
-        public short inV;
-        public int out;
-    }
-
-    private void checkConvertUshort2Int2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x2cf6eb50b7ac39eal, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Ushort2Int2(inV, out);
-            verifyResultsConvertUshort2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ushort2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Ushort2Int2(inV, out);
-            verifyResultsConvertUshort2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ushort2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortInt args = new ArgumentsUshortInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Int3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x2cf6eb9001544a20l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Ushort3Int3(inV, out);
-            verifyResultsConvertUshort3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ushort3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Ushort3Int3(inV, out);
-            verifyResultsConvertUshort3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ushort3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortInt args = new ArgumentsUshortInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Int4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x2cf6ebcf4afc5a56l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Ushort4Int4(inV, out);
-            verifyResultsConvertUshort4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ushort4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Ushort4Int4(inV, out);
-            verifyResultsConvertUshort4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ushort4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortInt args = new ArgumentsUshortInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntInt {
-        public int inV;
-        public int out;
-    }
-
-    private void checkConvertInt2Int2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x501d84049a42354l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Int2Int2(inV, out);
-            verifyResultsConvertInt2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Int2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Int2Int2(inV, out);
-            verifyResultsConvertInt2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Int2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntInt args = new ArgumentsIntInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Int3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x501d87f934c338al, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Int3Int3(inV, out);
-            verifyResultsConvertInt3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Int3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Int3Int3(inV, out);
-            verifyResultsConvertInt3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Int3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntInt args = new ArgumentsIntInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Int4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x501d8bedcf443c0l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Int4Int4(inV, out);
-            verifyResultsConvertInt4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Int4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Int4Int4(inV, out);
-            verifyResultsConvertInt4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Int4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntInt args = new ArgumentsIntInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintInt {
-        public int inV;
-        public int out;
-    }
-
-    private void checkConvertUint2Int2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x70899b043daccaddl, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Uint2Int2(inV, out);
-            verifyResultsConvertUint2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uint2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Uint2Int2(inV, out);
-            verifyResultsConvertUint2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uint2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintInt args = new ArgumentsUintInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Int3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x70899b438754db13l, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Uint3Int3(inV, out);
-            verifyResultsConvertUint3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uint3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Uint3Int3(inV, out);
-            verifyResultsConvertUint3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uint3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintInt args = new ArgumentsUintInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Int4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x70899b82d0fceb49l, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Uint4Int4(inV, out);
-            verifyResultsConvertUint4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uint4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Uint4Int4(inV, out);
-            verifyResultsConvertUint4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uint4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintInt args = new ArgumentsUintInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatUint {
-        public float inV;
-        public int out;
-    }
-
-    private void checkConvertFloat2Uint2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x239cb6cd424dca22l, 0.0000000000000000000e+00, 4.2949670400000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Float2Uint2(inV, out);
-            verifyResultsConvertFloat2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Float2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Float2Uint2(inV, out);
-            verifyResultsConvertFloat2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Float2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUint args = new ArgumentsFloatUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Uint3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x239cc16ea1558f16l, 0.0000000000000000000e+00, 4.2949670400000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Float3Uint3(inV, out);
-            verifyResultsConvertFloat3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Float3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Float3Uint3(inV, out);
-            verifyResultsConvertFloat3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Float3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUint args = new ArgumentsFloatUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Uint4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x239ccc10005d540al, 0.0000000000000000000e+00, 4.2949670400000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Float4Uint4(inV, out);
-            verifyResultsConvertFloat4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Float4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Float4Uint4(inV, out);
-            verifyResultsConvertFloat4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Float4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUint args = new ArgumentsFloatUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharUint {
-        public byte inV;
-        public int out;
-    }
-
-    private void checkConvertChar2Uint2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd8618beceddda162l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Char2Uint2(inV, out);
-            verifyResultsConvertChar2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Char2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Char2Uint2(inV, out);
-            verifyResultsConvertChar2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Char2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUint args = new ArgumentsCharUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Uint3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xd861968e4ce56656l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Char3Uint3(inV, out);
-            verifyResultsConvertChar3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Char3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Char3Uint3(inV, out);
-            verifyResultsConvertChar3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Char3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUint args = new ArgumentsCharUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Uint4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd861a12fabed2b4al, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Char4Uint4(inV, out);
-            verifyResultsConvertChar4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Char4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Char4Uint4(inV, out);
-            verifyResultsConvertChar4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Char4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUint args = new ArgumentsCharUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharUint {
-        public byte inV;
-        public int out;
-    }
-
-    private void checkConvertUchar2Uint2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7fef453a805fade3l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Uchar2Uint2(inV, out);
-            verifyResultsConvertUchar2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uchar2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Uchar2Uint2(inV, out);
-            verifyResultsConvertUchar2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uchar2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUint args = new ArgumentsUcharUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Uint3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7fef4fdbdf6772d7l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Uchar3Uint3(inV, out);
-            verifyResultsConvertUchar3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uchar3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Uchar3Uint3(inV, out);
-            verifyResultsConvertUchar3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uchar3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUint args = new ArgumentsUcharUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Uint4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7fef5a7d3e6f37cbl, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Uchar4Uint4(inV, out);
-            verifyResultsConvertUchar4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uchar4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Uchar4Uint4(inV, out);
-            verifyResultsConvertUchar4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uchar4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUint args = new ArgumentsUcharUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortUint {
-        public short inV;
-        public int out;
-    }
-
-    private void checkConvertShort2Uint2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x68ab69772e9b3c26l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Short2Uint2(inV, out);
-            verifyResultsConvertShort2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Short2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Short2Uint2(inV, out);
-            verifyResultsConvertShort2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Short2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUint args = new ArgumentsShortUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Uint3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x68ab74188da3011al, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Short3Uint3(inV, out);
-            verifyResultsConvertShort3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Short3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Short3Uint3(inV, out);
-            verifyResultsConvertShort3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Short3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUint args = new ArgumentsShortUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Uint4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x68ab7eb9ecaac60el, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Short4Uint4(inV, out);
-            verifyResultsConvertShort4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Short4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Short4Uint4(inV, out);
-            verifyResultsConvertShort4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Short4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUint args = new ArgumentsShortUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortUint {
-        public short inV;
-        public int out;
-    }
-
-    private void checkConvertUshort2Uint2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x8d79897eca7355d1l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Ushort2Uint2(inV, out);
-            verifyResultsConvertUshort2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ushort2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Ushort2Uint2(inV, out);
-            verifyResultsConvertUshort2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ushort2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUint args = new ArgumentsUshortUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Uint3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x8d799420297b1ac5l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Ushort3Uint3(inV, out);
-            verifyResultsConvertUshort3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ushort3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Ushort3Uint3(inV, out);
-            verifyResultsConvertUshort3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ushort3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUint args = new ArgumentsUshortUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Uint4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x8d799ec18882dfb9l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Ushort4Uint4(inV, out);
-            verifyResultsConvertUshort4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ushort4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Ushort4Uint4(inV, out);
-            verifyResultsConvertUshort4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ushort4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUint args = new ArgumentsUshortUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntUint {
-        public int inV;
-        public int out;
-    }
-
-    private void checkConvertInt2Uint2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xd74f55bc4f178a9fl, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Int2Uint2(inV, out);
-            verifyResultsConvertInt2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Int2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Int2Uint2(inV, out);
-            verifyResultsConvertInt2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Int2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUint args = new ArgumentsIntUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Uint3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xd74f605dae1f4f93l, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Int3Uint3(inV, out);
-            verifyResultsConvertInt3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Int3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Int3Uint3(inV, out);
-            verifyResultsConvertInt3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Int3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUint args = new ArgumentsIntUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Uint4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd74f6aff0d271487l, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Int4Uint4(inV, out);
-            verifyResultsConvertInt4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Int4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Int4Uint4(inV, out);
-            verifyResultsConvertInt4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Int4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUint args = new ArgumentsIntUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintUint {
-        public int inV;
-        public int out;
-    }
-
-    private void checkConvertUint2Uint2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xe71d0ca64c8baea2l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Uint2Uint2(inV, out);
-            verifyResultsConvertUint2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uint2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Uint2Uint2(inV, out);
-            verifyResultsConvertUint2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uint2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUint args = new ArgumentsUintUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Uint3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe71d1747ab937396l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Uint3Uint3(inV, out);
-            verifyResultsConvertUint3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uint3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Uint3Uint3(inV, out);
-            verifyResultsConvertUint3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uint3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUint args = new ArgumentsUintUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Uint4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xe71d21e90a9b388al, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Uint4Uint4(inV, out);
-            verifyResultsConvertUint4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uint4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Uint4Uint4(inV, out);
-            verifyResultsConvertUint4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uint4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUint args = new ArgumentsUintUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleDouble {
-        public double inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertDouble2Double2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x345b4a823902786el, -8.5390423905960001625e+307, 8.5390423905960001625e+307);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Double2Double2(inV, out);
-            verifyResultsConvertDouble2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Double2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Double2Double2(inV, out);
-            verifyResultsConvertDouble2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Double2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleDouble args = new ArgumentsDoubleDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Double3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x34a812098f5e099al, -8.5390423905960001625e+307, 8.5390423905960001625e+307);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Double3Double3(inV, out);
-            verifyResultsConvertDouble3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Double3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Double3Double3(inV, out);
-            verifyResultsConvertDouble3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Double3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleDouble args = new ArgumentsDoubleDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Double4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x34f4d990e5b99ac6l, -8.5390423905960001625e+307, 8.5390423905960001625e+307);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Double4Double4(inV, out);
-            verifyResultsConvertDouble4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Double4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Double4Double4(inV, out);
-            verifyResultsConvertDouble4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Double4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleDouble args = new ArgumentsDoubleDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongDouble {
-        public long inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertLong2Double2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x7b7807124c70299bl, true, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Long2Double2(inV, out);
-            verifyResultsConvertLong2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Long2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Long2Double2(inV, out);
-            verifyResultsConvertLong2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Long2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongDouble args = new ArgumentsLongDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Double3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x7bc4ce99a2cbbac7l, true, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Long3Double3(inV, out);
-            verifyResultsConvertLong3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Long3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Long3Double3(inV, out);
-            verifyResultsConvertLong3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Long3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongDouble args = new ArgumentsLongDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Double4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x7c119620f9274bf3l, true, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Long4Double4(inV, out);
-            verifyResultsConvertLong4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Long4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Long4Double4(inV, out);
-            verifyResultsConvertLong4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Long4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongDouble args = new ArgumentsLongDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongDouble {
-        public long inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertUlong2Double2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xaa17685979bc7954l, false, 64);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Ulong2Double2(inV, out);
-            verifyResultsConvertUlong2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Ulong2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Ulong2Double2(inV, out);
-            verifyResultsConvertUlong2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Ulong2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongDouble args = new ArgumentsUlongDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Double3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xaa642fe0d0180a80l, false, 64);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Ulong3Double3(inV, out);
-            verifyResultsConvertUlong3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Ulong3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Ulong3Double3(inV, out);
-            verifyResultsConvertUlong3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Ulong3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongDouble args = new ArgumentsUlongDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Double4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xaab0f76826739bacl, false, 64);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Ulong4Double4(inV, out);
-            verifyResultsConvertUlong4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Ulong4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Ulong4Double4(inV, out);
-            verifyResultsConvertUlong4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Ulong4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongDouble args = new ArgumentsUlongDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleLong {
-        public double inV;
-        public long out;
-    }
-
-    private void checkConvertDouble2Long2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0xcbf84dc0430cbe95l, -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);
-            verifyResultsConvertDouble2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Double2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Double2Long2(inV, out);
-            verifyResultsConvertDouble2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Double2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleLong args = new ArgumentsDoubleLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Long3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xcbf85861a2148389l, -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);
-            verifyResultsConvertDouble3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Double3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Double3Long3(inV, out);
-            verifyResultsConvertDouble3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Double3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleLong args = new ArgumentsDoubleLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Long4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0xcbf86303011c487dl, -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);
-            verifyResultsConvertDouble4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Double4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Double4Long4(inV, out);
-            verifyResultsConvertDouble4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Double4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleLong args = new ArgumentsDoubleLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongLong {
-        public long inV;
-        public long out;
-    }
-
-    private void checkConvertLong2Long2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xb570c607c81d242al, true, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertLong2Long2Long2(inV, out);
-            verifyResultsConvertLong2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Long2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Long2Long2(inV, out);
-            verifyResultsConvertLong2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Long2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLong args = new ArgumentsLongLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Long3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xb570d0a92724e91el, true, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertLong3Long3Long3(inV, out);
-            verifyResultsConvertLong3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Long3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Long3Long3(inV, out);
-            verifyResultsConvertLong3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Long3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLong args = new ArgumentsLongLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Long4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xb570db4a862cae12l, true, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertLong4Long4Long4(inV, out);
-            verifyResultsConvertLong4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Long4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Long4Long4(inV, out);
-            verifyResultsConvertLong4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Long4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLong args = new ArgumentsLongLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongLong {
-        public long inV;
-        public long out;
-    }
-
-    private void checkConvertUlong2Long2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x5cfe7f555a9f30abl, false, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertLong2Ulong2Long2(inV, out);
-            verifyResultsConvertUlong2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Ulong2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Ulong2Long2(inV, out);
-            verifyResultsConvertUlong2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Ulong2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongLong args = new ArgumentsUlongLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Long3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x5cfe89f6b9a6f59fl, false, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertLong3Ulong3Long3(inV, out);
-            verifyResultsConvertUlong3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Ulong3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Ulong3Long3(inV, out);
-            verifyResultsConvertUlong3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Ulong3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongLong args = new ArgumentsUlongLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Long4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x5cfe949818aeba93l, false, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertLong4Ulong4Long4(inV, out);
-            verifyResultsConvertUlong4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Ulong4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Ulong4Long4(inV, out);
-            verifyResultsConvertUlong4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Ulong4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongLong args = new ArgumentsUlongLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleUlong {
-        public double inV;
-        public long out;
-    }
-
-    private void checkConvertDouble2Ulong2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x42b56e3b7e12ff5el, 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);
-            verifyResultsConvertDouble2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Double2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Double2Ulong2(inV, out);
-            verifyResultsConvertDouble2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Double2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUlong args = new ArgumentsDoubleUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Ulong3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x42b73756742e203cl, 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);
-            verifyResultsConvertDouble3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Double3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Double3Ulong3(inV, out);
-            verifyResultsConvertDouble3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Double3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUlong args = new ArgumentsDoubleUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Ulong4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x42b900716a49411al, 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);
-            verifyResultsConvertDouble4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Double4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Double4Ulong4(inV, out);
-            verifyResultsConvertDouble4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Double4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUlong args = new ArgumentsDoubleUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongUlong {
-        public long inV;
-        public long out;
-    }
-
-    private void checkConvertLong2Ulong2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x79f1a23ed7d40f65l, false, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertUlong2Long2Ulong2(inV, out);
-            verifyResultsConvertLong2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Long2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Long2Ulong2(inV, out);
-            verifyResultsConvertLong2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Long2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUlong args = new ArgumentsLongUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Ulong3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x79f36b59cdef3043l, false, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertUlong3Long3Ulong3(inV, out);
-            verifyResultsConvertLong3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Long3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Long3Ulong3(inV, out);
-            verifyResultsConvertLong3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Long3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUlong args = new ArgumentsLongUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Ulong4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x79f53474c40a5121l, false, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertUlong4Long4Ulong4(inV, out);
-            verifyResultsConvertLong4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Long4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Long4Ulong4(inV, out);
-            verifyResultsConvertLong4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Long4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUlong args = new ArgumentsLongUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongUlong {
-        public long inV;
-        public long out;
-    }
-
-    private void checkConvertUlong2Ulong2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x9ebfc24673ac2910l, false, 64);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertUlong2Ulong2Ulong2(inV, out);
-            verifyResultsConvertUlong2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Ulong2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Ulong2Ulong2(inV, out);
-            verifyResultsConvertUlong2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Ulong2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlong args = new ArgumentsUlongUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Ulong3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x9ec18b6169c749eel, false, 64);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertUlong3Ulong3Ulong3(inV, out);
-            verifyResultsConvertUlong3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Ulong3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Ulong3Ulong3(inV, out);
-            verifyResultsConvertUlong3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Ulong3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlong args = new ArgumentsUlongUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Ulong4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x9ec3547c5fe26accl, false, 64);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertUlong4Ulong4Ulong4(inV, out);
-            verifyResultsConvertUlong4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Ulong4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Ulong4Ulong4(inV, out);
-            verifyResultsConvertUlong4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Ulong4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlong args = new ArgumentsUlongUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleFloat {
-        public double inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertDouble2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x42b4cec67d6d9a2dl, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Double2Float2(inV, out);
-            verifyResultsConvertDouble2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Double2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Double2Float2(inV, out);
-            verifyResultsConvertDouble2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Double2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleFloat args = new ArgumentsDoubleFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x42b697e17388bb0bl, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Double3Float3(inV, out);
-            verifyResultsConvertDouble3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Double3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Double3Float3(inV, out);
-            verifyResultsConvertDouble3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Double3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleFloat args = new ArgumentsDoubleFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x42b860fc69a3dbe9l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Double4Float4(inV, out);
-            verifyResultsConvertDouble4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Double4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Double4Float4(inV, out);
-            verifyResultsConvertDouble4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Double4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleFloat args = new ArgumentsDoubleFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongFloat {
-        public long inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertLong2Float2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x79f102c9d72eaa34l, true, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Long2Float2(inV, out);
-            verifyResultsConvertLong2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Long2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Long2Float2(inV, out);
-            verifyResultsConvertLong2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Long2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongFloat args = new ArgumentsLongFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Float3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x79f2cbe4cd49cb12l, true, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Long3Float3(inV, out);
-            verifyResultsConvertLong3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Long3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Long3Float3(inV, out);
-            verifyResultsConvertLong3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Long3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongFloat args = new ArgumentsLongFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Float4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x79f494ffc364ebf0l, true, 63);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Long4Float4(inV, out);
-            verifyResultsConvertLong4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Long4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Long4Float4(inV, out);
-            verifyResultsConvertLong4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Long4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongFloat args = new ArgumentsLongFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongFloat {
-        public long inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertUlong2Float2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x9ebf22d17306c3dfl, false, 64);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testConvertFloat2Ulong2Float2(inV, out);
-            verifyResultsConvertUlong2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ulong2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat2Ulong2Float2(inV, out);
-            verifyResultsConvertUlong2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ulong2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongFloat args = new ArgumentsUlongFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Float3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x9ec0ebec6921e4bdl, false, 64);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testConvertFloat3Ulong3Float3(inV, out);
-            verifyResultsConvertUlong3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ulong3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat3Ulong3Float3(inV, out);
-            verifyResultsConvertUlong3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ulong3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongFloat args = new ArgumentsUlongFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Float4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x9ec2b5075f3d059bl, false, 64);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testConvertFloat4Ulong4Float4(inV, out);
-            verifyResultsConvertUlong4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ulong4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertFloat4Ulong4Float4(inV, out);
-            verifyResultsConvertUlong4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ulong4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongFloat args = new ArgumentsUlongFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleChar {
-        public double inV;
-        public byte out;
-    }
-
-    private void checkConvertDouble2Char2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0xcbf84b7bef094a17l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Double2Char2(inV, out);
-            verifyResultsConvertDouble2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Double2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Double2Char2(inV, out);
-            verifyResultsConvertDouble2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Double2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleChar args = new ArgumentsDoubleChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Char3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xcbf8561d4e110f0bl, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Double3Char3(inV, out);
-            verifyResultsConvertDouble3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Double3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Double3Char3(inV, out);
-            verifyResultsConvertDouble3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Double3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleChar args = new ArgumentsDoubleChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Char4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0xcbf860bead18d3ffl, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Double4Char4(inV, out);
-            verifyResultsConvertDouble4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Double4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Double4Char4(inV, out);
-            verifyResultsConvertDouble4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Double4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleChar args = new ArgumentsDoubleChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongChar {
-        public long inV;
-        public byte out;
-    }
-
-    private void checkConvertLong2Char2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xb570c3c37419afacl, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Long2Char2(inV, out);
-            verifyResultsConvertLong2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Long2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Long2Char2(inV, out);
-            verifyResultsConvertLong2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Long2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongChar args = new ArgumentsLongChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Char3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xb570ce64d32174a0l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Long3Char3(inV, out);
-            verifyResultsConvertLong3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Long3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Long3Char3(inV, out);
-            verifyResultsConvertLong3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Long3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongChar args = new ArgumentsLongChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Char4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xb570d90632293994l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Long4Char4(inV, out);
-            verifyResultsConvertLong4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Long4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Long4Char4(inV, out);
-            verifyResultsConvertLong4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Long4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongChar args = new ArgumentsLongChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongChar {
-        public long inV;
-        public byte out;
-    }
-
-    private void checkConvertUlong2Char2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x5cfe7d11069bbc2dl, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertChar2Ulong2Char2(inV, out);
-            verifyResultsConvertUlong2Char2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ulong2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar2Ulong2Char2(inV, out);
-            verifyResultsConvertUlong2Char2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ulong2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Char2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongChar args = new ArgumentsUlongChar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Char3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x5cfe87b265a38121l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertChar3Ulong3Char3(inV, out);
-            verifyResultsConvertUlong3Char3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ulong3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar3Ulong3Char3(inV, out);
-            verifyResultsConvertUlong3Char3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ulong3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Char3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongChar args = new ArgumentsUlongChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Char4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x5cfe9253c4ab4615l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertChar4Ulong4Char4(inV, out);
-            verifyResultsConvertUlong4Char4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ulong4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertChar4Ulong4Char4(inV, out);
-            verifyResultsConvertUlong4Char4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ulong4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Char4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongChar args = new ArgumentsUlongChar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleUchar {
-        public double inV;
-        public byte out;
-    }
-
-    private void checkConvertDouble2Uchar2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x42b56bf72a0f8ae0l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Double2Uchar2(inV, out);
-            verifyResultsConvertDouble2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Double2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Double2Uchar2(inV, out);
-            verifyResultsConvertDouble2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Double2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUchar args = new ArgumentsDoubleUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Uchar3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x42b73512202aabbel, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Double3Uchar3(inV, out);
-            verifyResultsConvertDouble3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Double3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Double3Uchar3(inV, out);
-            verifyResultsConvertDouble3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Double3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUchar args = new ArgumentsDoubleUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Uchar4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x42b8fe2d1645cc9cl, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Double4Uchar4(inV, out);
-            verifyResultsConvertDouble4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Double4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Double4Uchar4(inV, out);
-            verifyResultsConvertDouble4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Double4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUchar args = new ArgumentsDoubleUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongUchar {
-        public long inV;
-        public byte out;
-    }
-
-    private void checkConvertLong2Uchar2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x79f19ffa83d09ae7l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Long2Uchar2(inV, out);
-            verifyResultsConvertLong2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Long2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Long2Uchar2(inV, out);
-            verifyResultsConvertLong2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Long2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUchar args = new ArgumentsLongUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Uchar3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x79f3691579ebbbc5l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Long3Uchar3(inV, out);
-            verifyResultsConvertLong3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Long3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Long3Uchar3(inV, out);
-            verifyResultsConvertLong3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Long3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUchar args = new ArgumentsLongUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Uchar4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x79f532307006dca3l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Long4Uchar4(inV, out);
-            verifyResultsConvertLong4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Long4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Long4Uchar4(inV, out);
-            verifyResultsConvertLong4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Long4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUchar args = new ArgumentsLongUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongUchar {
-        public long inV;
-        public byte out;
-    }
-
-    private void checkConvertUlong2Uchar2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x9ebfc0021fa8b492l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.forEach_testConvertUchar2Ulong2Uchar2(inV, out);
-            verifyResultsConvertUlong2Uchar2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ulong2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar2Ulong2Uchar2(inV, out);
-            verifyResultsConvertUlong2Uchar2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ulong2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUchar args = new ArgumentsUlongUchar();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Uchar3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x9ec1891d15c3d570l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.forEach_testConvertUchar3Ulong3Uchar3(inV, out);
-            verifyResultsConvertUlong3Uchar3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ulong3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar3Ulong3Uchar3(inV, out);
-            verifyResultsConvertUlong3Uchar3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ulong3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUchar args = new ArgumentsUlongUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Uchar4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x9ec352380bdef64el, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.forEach_testConvertUchar4Ulong4Uchar4(inV, out);
-            verifyResultsConvertUlong4Uchar4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ulong4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUchar4Ulong4Uchar4(inV, out);
-            verifyResultsConvertUlong4Uchar4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ulong4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUchar args = new ArgumentsUlongUchar();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleShort {
-        public double inV;
-        public short out;
-    }
-
-    private void checkConvertDouble2Short2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x42b557fbbf1d55f9l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Double2Short2(inV, out);
-            verifyResultsConvertDouble2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Double2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Double2Short2(inV, out);
-            verifyResultsConvertDouble2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Double2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleShort args = new ArgumentsDoubleShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Short3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x42b72116b53876d7l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Double3Short3(inV, out);
-            verifyResultsConvertDouble3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Double3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Double3Short3(inV, out);
-            verifyResultsConvertDouble3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Double3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleShort args = new ArgumentsDoubleShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Short4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x42b8ea31ab5397b5l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Double4Short4(inV, out);
-            verifyResultsConvertDouble4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Double4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Double4Short4(inV, out);
-            verifyResultsConvertDouble4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Double4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleShort args = new ArgumentsDoubleShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongShort {
-        public long inV;
-        public short out;
-    }
-
-    private void checkConvertLong2Short2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x79f18bff18de6600l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Long2Short2(inV, out);
-            verifyResultsConvertLong2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Long2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Long2Short2(inV, out);
-            verifyResultsConvertLong2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Long2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongShort args = new ArgumentsLongShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Short3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x79f3551a0ef986del, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Long3Short3(inV, out);
-            verifyResultsConvertLong3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Long3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Long3Short3(inV, out);
-            verifyResultsConvertLong3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Long3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongShort args = new ArgumentsLongShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Short4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x79f51e350514a7bcl, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Long4Short4(inV, out);
-            verifyResultsConvertLong4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Long4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Long4Short4(inV, out);
-            verifyResultsConvertLong4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Long4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongShort args = new ArgumentsLongShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongShort {
-        public long inV;
-        public short out;
-    }
-
-    private void checkConvertUlong2Short2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x9ebfac06b4b67fabl, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertShort2Ulong2Short2(inV, out);
-            verifyResultsConvertUlong2Short2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ulong2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort2Ulong2Short2(inV, out);
-            verifyResultsConvertUlong2Short2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ulong2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Short2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongShort args = new ArgumentsUlongShort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Short3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x9ec17521aad1a089l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertShort3Ulong3Short3(inV, out);
-            verifyResultsConvertUlong3Short3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ulong3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort3Ulong3Short3(inV, out);
-            verifyResultsConvertUlong3Short3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ulong3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Short3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongShort args = new ArgumentsUlongShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Short4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x9ec33e3ca0ecc167l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertShort4Ulong4Short4(inV, out);
-            verifyResultsConvertUlong4Short4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ulong4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertShort4Ulong4Short4(inV, out);
-            verifyResultsConvertUlong4Short4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ulong4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Short4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongShort args = new ArgumentsUlongShort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleUshort {
-        public double inV;
-        public short out;
-    }
-
-    private void checkConvertDouble2Ushort2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x3479ccaea92a37bcl, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Double2Ushort2(inV, out);
-            verifyResultsConvertDouble2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Double2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Double2Ushort2(inV, out);
-            verifyResultsConvertDouble2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Double2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUshort args = new ArgumentsDoubleUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Ushort3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x34c69435ff85c8e8l, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Double3Ushort3(inV, out);
-            verifyResultsConvertDouble3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Double3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Double3Ushort3(inV, out);
-            verifyResultsConvertDouble3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Double3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUshort args = new ArgumentsDoubleUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Ushort4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x35135bbd55e15a14l, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Double4Ushort4(inV, out);
-            verifyResultsConvertDouble4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Double4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Double4Ushort4(inV, out);
-            verifyResultsConvertDouble4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Double4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUshort args = new ArgumentsDoubleUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongUshort {
-        public long inV;
-        public short out;
-    }
-
-    private void checkConvertLong2Ushort2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x7b96893ebc97e8e9l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Long2Ushort2(inV, out);
-            verifyResultsConvertLong2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Long2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Long2Ushort2(inV, out);
-            verifyResultsConvertLong2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Long2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUshort args = new ArgumentsLongUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Ushort3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x7be350c612f37a15l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Long3Ushort3(inV, out);
-            verifyResultsConvertLong3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Long3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Long3Ushort3(inV, out);
-            verifyResultsConvertLong3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Long3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUshort args = new ArgumentsLongUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Ushort4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x7c30184d694f0b41l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Long4Ushort4(inV, out);
-            verifyResultsConvertLong4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Long4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Long4Ushort4(inV, out);
-            verifyResultsConvertLong4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Long4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUshort args = new ArgumentsLongUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongUshort {
-        public long inV;
-        public short out;
-    }
-
-    private void checkConvertUlong2Ushort2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xaa35ea85e9e438a2l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.forEach_testConvertUshort2Ulong2Ushort2(inV, out);
-            verifyResultsConvertUlong2Ushort2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ulong2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort2Ulong2Ushort2(inV, out);
-            verifyResultsConvertUlong2Ushort2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ulong2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Ushort2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUshort args = new ArgumentsUlongUshort();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Ushort3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xaa82b20d403fc9cel, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.forEach_testConvertUshort3Ulong3Ushort3(inV, out);
-            verifyResultsConvertUlong3Ushort3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ulong3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort3Ulong3Ushort3(inV, out);
-            verifyResultsConvertUlong3Ushort3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ulong3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Ushort3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUshort args = new ArgumentsUlongUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Ushort4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xaacf7994969b5afal, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.forEach_testConvertUshort4Ulong4Ushort4(inV, out);
-            verifyResultsConvertUlong4Ushort4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ulong4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUshort4Ulong4Ushort4(inV, out);
-            verifyResultsConvertUlong4Ushort4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ulong4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Ushort4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUshort args = new ArgumentsUlongUshort();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleInt {
-        public double inV;
-        public int out;
-    }
-
-    private void checkConvertDouble2Int2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0xa57cd81dcaf628fcl, -2.1474836480000000000e+09, 2.1474836470000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Double2Int2(inV, out);
-            verifyResultsConvertDouble2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Double2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Double2Int2(inV, out);
-            verifyResultsConvertDouble2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Double2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleInt args = new ArgumentsDoubleInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Int3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xa57cd85d149e3932l, -2.1474836480000000000e+09, 2.1474836470000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Double3Int3(inV, out);
-            verifyResultsConvertDouble3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Double3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Double3Int3(inV, out);
-            verifyResultsConvertDouble3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Double3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleInt args = new ArgumentsDoubleInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Int4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0xa57cd89c5e464968l, -2.1474836480000000000e+09, 2.1474836470000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Double4Int4(inV, out);
-            verifyResultsConvertDouble4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Double4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Double4Int4(inV, out);
-            verifyResultsConvertDouble4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Double4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleInt args = new ArgumentsDoubleInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongInt {
-        public long inV;
-        public int out;
-    }
-
-    private void checkConvertLong2Int2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xfe441c66e5deba3bl, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Long2Int2(inV, out);
-            verifyResultsConvertLong2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Long2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Long2Int2(inV, out);
-            verifyResultsConvertLong2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Long2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongInt args = new ArgumentsLongInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Int3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xfe441ca62f86ca71l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Long3Int3(inV, out);
-            verifyResultsConvertLong3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Long3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Long3Int3(inV, out);
-            verifyResultsConvertLong3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Long3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongInt args = new ArgumentsLongInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Int4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xfe441ce5792edaa7l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Long4Int4(inV, out);
-            verifyResultsConvertLong4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Long4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Long4Int4(inV, out);
-            verifyResultsConvertLong4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Long4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongInt args = new ArgumentsLongInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongInt {
-        public long inV;
-        public int out;
-    }
-
-    private void checkConvertUlong2Int2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xe11d350e352de3el, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertInt2Ulong2Int2(inV, out);
-            verifyResultsConvertUlong2Int2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ulong2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt2Ulong2Int2(inV, out);
-            verifyResultsConvertUlong2Int2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ulong2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Int2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongInt args = new ArgumentsUlongInt();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Int3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xe11d3902cfaee74l, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertInt3Ulong3Int3(inV, out);
-            verifyResultsConvertUlong3Int3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ulong3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt3Ulong3Int3(inV, out);
-            verifyResultsConvertUlong3Int3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ulong3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Int3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongInt args = new ArgumentsUlongInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Int4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xe11d3cf76a2feaal, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertInt4Ulong4Int4(inV, out);
-            verifyResultsConvertUlong4Int4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ulong4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertInt4Ulong4Int4(inV, out);
-            verifyResultsConvertUlong4Int4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ulong4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Int4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongInt args = new ArgumentsUlongInt();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsDoubleUint {
-        public double inV;
-        public int out;
-    }
-
-    private void checkConvertDouble2Uint2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0xcbf84ff107de7dd7l, 0.0000000000000000000e+00, 4.2949672950000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Double2Uint2(inV, out);
-            verifyResultsConvertDouble2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Double2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Double2Uint2(inV, out);
-            verifyResultsConvertDouble2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Double2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUint args = new ArgumentsDoubleUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble3Uint3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xcbf85a9266e642cbl, 0.0000000000000000000e+00, 4.2949672950000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Double3Uint3(inV, out);
-            verifyResultsConvertDouble3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Double3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Double3Uint3(inV, out);
-            verifyResultsConvertDouble3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Double3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUint args = new ArgumentsDoubleUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertDouble4Uint4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0xcbf86533c5ee07bfl, 0.0000000000000000000e+00, 4.2949672950000000000e+09);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Double4Uint4(inV, out);
-            verifyResultsConvertDouble4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Double4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Double4Uint4(inV, out);
-            verifyResultsConvertDouble4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Double4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertDouble4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        double[] arrayInV = new double[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsDoubleUint args = new ArgumentsDoubleUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            args.inV, Double.doubleToRawLongBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertDouble4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongUint {
-        public long inV;
-        public int out;
-    }
-
-    private void checkConvertLong2Uint2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xb570c8388ceee36cl, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Long2Uint2(inV, out);
-            verifyResultsConvertLong2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Long2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Long2Uint2(inV, out);
-            verifyResultsConvertLong2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Long2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUint args = new ArgumentsLongUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong3Uint3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xb570d2d9ebf6a860l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Long3Uint3(inV, out);
-            verifyResultsConvertLong3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Long3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Long3Uint3(inV, out);
-            verifyResultsConvertLong3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Long3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUint args = new ArgumentsLongUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertLong4Uint4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xb570dd7b4afe6d54l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Long4Uint4(inV, out);
-            verifyResultsConvertLong4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Long4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Long4Uint4(inV, out);
-            verifyResultsConvertLong4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Long4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertLong4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongUint args = new ArgumentsLongUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertLong4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongUint {
-        public long inV;
-        public int out;
-    }
-
-    private void checkConvertUlong2Uint2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x5cfe81861f70efedl, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.forEach_testConvertUint2Ulong2Uint2(inV, out);
-            verifyResultsConvertUlong2Uint2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ulong2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint2Ulong2Uint2(inV, out);
-            verifyResultsConvertUlong2Uint2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ulong2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong2Uint2(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUint args = new ArgumentsUlongUint();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong3Uint3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x5cfe8c277e78b4e1l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.forEach_testConvertUint3Ulong3Uint3(inV, out);
-            verifyResultsConvertUlong3Uint3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ulong3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint3Ulong3Uint3(inV, out);
-            verifyResultsConvertUlong3Uint3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ulong3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong3Uint3(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUint args = new ArgumentsUlongUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUlong4Uint4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x5cfe96c8dd8079d5l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.forEach_testConvertUint4Ulong4Uint4(inV, out);
-            verifyResultsConvertUlong4Uint4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ulong4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUint4Ulong4Uint4(inV, out);
-            verifyResultsConvertUlong4Uint4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ulong4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUlong4Uint4(Allocation inV, Allocation out, boolean relaxed) {
-        long[] arrayInV = new long[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUint args = new ArgumentsUlongUint();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUlong4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatDouble {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertFloat2Double2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x36c6372446e08221l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Float2Double2(inV, out);
-            verifyResultsConvertFloat2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Float2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Float2Double2(inV, out);
-            verifyResultsConvertFloat2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Float2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatDouble args = new ArgumentsFloatDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Double3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3712feab9d3c134dl, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Float3Double3(inV, out);
-            verifyResultsConvertFloat3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Float3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Float3Double3(inV, out);
-            verifyResultsConvertFloat3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Float3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatDouble args = new ArgumentsFloatDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Double4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x375fc632f397a479l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Float4Double4(inV, out);
-            verifyResultsConvertFloat4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Float4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Float4Double4(inV, out);
-            verifyResultsConvertFloat4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Float4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatDouble args = new ArgumentsFloatDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharDouble {
-        public byte inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertChar2Double2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd86d88e268ca2f61l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Char2Double2(inV, out);
-            verifyResultsConvertChar2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Char2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Char2Double2(inV, out);
-            verifyResultsConvertChar2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Char2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharDouble args = new ArgumentsCharDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Double3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xd8ba5069bf25c08dl, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Char3Double3(inV, out);
-            verifyResultsConvertChar3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Char3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Char3Double3(inV, out);
-            verifyResultsConvertChar3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Char3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharDouble args = new ArgumentsCharDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Double4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd90717f1158151b9l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Char4Double4(inV, out);
-            verifyResultsConvertChar4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Char4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Char4Double4(inV, out);
-            verifyResultsConvertChar4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Char4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharDouble args = new ArgumentsCharDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharDouble {
-        public byte inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertUchar2Double2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x70cea2996167f1al, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Uchar2Double2(inV, out);
-            verifyResultsConvertUchar2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Uchar2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Uchar2Double2(inV, out);
-            verifyResultsConvertUchar2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Uchar2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharDouble args = new ArgumentsUcharDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Double3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x759b1b0ec721046l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Uchar3Double3(inV, out);
-            verifyResultsConvertUchar3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Uchar3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Uchar3Double3(inV, out);
-            verifyResultsConvertUchar3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Uchar3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharDouble args = new ArgumentsUcharDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Double4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7a6793842cda172l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Uchar4Double4(inV, out);
-            verifyResultsConvertUchar4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Uchar4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Uchar4Double4(inV, out);
-            verifyResultsConvertUchar4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Uchar4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharDouble args = new ArgumentsUcharDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortDouble {
-        public short inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertShort2Double2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xfdeea470023d0105l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Short2Double2(inV, out);
-            verifyResultsConvertShort2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Short2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Short2Double2(inV, out);
-            verifyResultsConvertShort2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Short2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortDouble args = new ArgumentsShortDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Double3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xfe3b6bf758989231l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Short3Double3(inV, out);
-            verifyResultsConvertShort3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Short3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Short3Double3(inV, out);
-            verifyResultsConvertShort3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Short3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortDouble args = new ArgumentsShortDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Double4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xfe88337eaef4235dl, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Short4Double4(inV, out);
-            verifyResultsConvertShort4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Short4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Short4Double4(inV, out);
-            verifyResultsConvertShort4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Short4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortDouble args = new ArgumentsShortDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortDouble {
-        public short inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertUshort2Double2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xd2b3fb649e0e6518l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Ushort2Double2(inV, out);
-            verifyResultsConvertUshort2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Ushort2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Ushort2Double2(inV, out);
-            verifyResultsConvertUshort2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Ushort2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortDouble args = new ArgumentsUshortDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Double3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xd300c2ebf469f644l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Ushort3Double3(inV, out);
-            verifyResultsConvertUshort3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Ushort3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Ushort3Double3(inV, out);
-            verifyResultsConvertUshort3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Ushort3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortDouble args = new ArgumentsUshortDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Double4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xd34d8a734ac58770l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Ushort4Double4(inV, out);
-            verifyResultsConvertUshort4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Ushort4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Ushort4Double4(inV, out);
-            verifyResultsConvertUshort4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Ushort4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortDouble args = new ArgumentsUshortDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntDouble {
-        public int inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertInt2Double2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x1be423b7a40fc8f6l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Int2Double2(inV, out);
-            verifyResultsConvertInt2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Int2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Int2Double2(inV, out);
-            verifyResultsConvertInt2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Int2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntDouble args = new ArgumentsIntDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Double3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x1c30eb3efa6b5a22l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Int3Double3(inV, out);
-            verifyResultsConvertInt3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Int3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Int3Double3(inV, out);
-            verifyResultsConvertInt3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Int3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntDouble args = new ArgumentsIntDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Double4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x1c7db2c650c6eb4el, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Int4Double4(inV, out);
-            verifyResultsConvertInt4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Int4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Int4Double4(inV, out);
-            verifyResultsConvertInt4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Int4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntDouble args = new ArgumentsIntDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintDouble {
-        public int inV;
-        public Target.Floaty out;
-    }
-
-    private void checkConvertUint2Double2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x40b243bf3fe7e2a1l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            script.forEach_testConvertDouble2Uint2Double2(inV, out);
-            verifyResultsConvertUint2Double2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Uint2Double2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble2Uint2Double2(inV, out);
-            verifyResultsConvertUint2Double2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Uint2Double2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Double2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintDouble args = new ArgumentsUintDouble();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 2 + j], Double.doubleToRawLongBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Double2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Double3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x40ff0b46964373cdl, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            script.forEach_testConvertDouble3Uint3Double3(inV, out);
-            verifyResultsConvertUint3Double3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Uint3Double3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble3Uint3Double3(inV, out);
-            verifyResultsConvertUint3Double3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Uint3Double3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Double3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintDouble args = new ArgumentsUintDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Double3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Double4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x414bd2cdec9f04f9l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            script.forEach_testConvertDouble4Uint4Double4(inV, out);
-            verifyResultsConvertUint4Double4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Uint4Double4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertDouble4Uint4Double4(inV, out);
-            verifyResultsConvertUint4Double4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Uint4Double4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Double4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        double[] arrayOut = new double[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintDouble args = new ArgumentsUintDouble();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeConvert(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%24.8g {%16x} %31a",
-                            arrayOut[i * 4 + j], Double.doubleToRawLongBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Double4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatLong {
-        public float inV;
-        public long out;
-    }
-
-    private void checkConvertFloat2Long2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x239cb49c7d7c0ae0l, -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);
-            verifyResultsConvertFloat2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Float2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Float2Long2(inV, out);
-            verifyResultsConvertFloat2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Float2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatLong args = new ArgumentsFloatLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Long3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x239cbf3ddc83cfd4l, -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);
-            verifyResultsConvertFloat3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Float3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Float3Long3(inV, out);
-            verifyResultsConvertFloat3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Float3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatLong args = new ArgumentsFloatLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Long4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x239cc9df3b8b94c8l, -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);
-            verifyResultsConvertFloat4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Float4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Float4Long4(inV, out);
-            verifyResultsConvertFloat4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Float4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatLong args = new ArgumentsFloatLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharLong {
-        public byte inV;
-        public long out;
-    }
-
-    private void checkConvertChar2Long2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd86189bc290be220l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertLong2Char2Long2(inV, out);
-            verifyResultsConvertChar2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Char2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Char2Long2(inV, out);
-            verifyResultsConvertChar2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Char2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharLong args = new ArgumentsCharLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Long3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xd861945d8813a714l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertLong3Char3Long3(inV, out);
-            verifyResultsConvertChar3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Char3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Char3Long3(inV, out);
-            verifyResultsConvertChar3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Char3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharLong args = new ArgumentsCharLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Long4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd8619efee71b6c08l, true, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertLong4Char4Long4(inV, out);
-            verifyResultsConvertChar4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Char4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Char4Long4(inV, out);
-            verifyResultsConvertChar4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Char4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharLong args = new ArgumentsCharLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharLong {
-        public byte inV;
-        public long out;
-    }
-
-    private void checkConvertUchar2Long2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7fef4309bb8deea1l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertLong2Uchar2Long2(inV, out);
-            verifyResultsConvertUchar2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Uchar2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Uchar2Long2(inV, out);
-            verifyResultsConvertUchar2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Uchar2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharLong args = new ArgumentsUcharLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Long3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7fef4dab1a95b395l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertLong3Uchar3Long3(inV, out);
-            verifyResultsConvertUchar3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Uchar3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Uchar3Long3(inV, out);
-            verifyResultsConvertUchar3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Uchar3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharLong args = new ArgumentsUcharLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Long4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7fef584c799d7889l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertLong4Uchar4Long4(inV, out);
-            verifyResultsConvertUchar4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Uchar4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Uchar4Long4(inV, out);
-            verifyResultsConvertUchar4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Uchar4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharLong args = new ArgumentsUcharLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortLong {
-        public short inV;
-        public long out;
-    }
-
-    private void checkConvertShort2Long2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x68ab674669c97ce4l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertLong2Short2Long2(inV, out);
-            verifyResultsConvertShort2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Short2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Short2Long2(inV, out);
-            verifyResultsConvertShort2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Short2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortLong args = new ArgumentsShortLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Long3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x68ab71e7c8d141d8l, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertLong3Short3Long3(inV, out);
-            verifyResultsConvertShort3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Short3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Short3Long3(inV, out);
-            verifyResultsConvertShort3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Short3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortLong args = new ArgumentsShortLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Long4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x68ab7c8927d906ccl, true, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertLong4Short4Long4(inV, out);
-            verifyResultsConvertShort4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Short4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Short4Long4(inV, out);
-            verifyResultsConvertShort4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Short4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortLong args = new ArgumentsShortLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortLong {
-        public short inV;
-        public long out;
-    }
-
-    private void checkConvertUshort2Long2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x8d79874e05a1968fl, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertLong2Ushort2Long2(inV, out);
-            verifyResultsConvertUshort2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Ushort2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Ushort2Long2(inV, out);
-            verifyResultsConvertUshort2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Ushort2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortLong args = new ArgumentsUshortLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Long3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x8d7991ef64a95b83l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertLong3Ushort3Long3(inV, out);
-            verifyResultsConvertUshort3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Ushort3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Ushort3Long3(inV, out);
-            verifyResultsConvertUshort3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Ushort3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortLong args = new ArgumentsUshortLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Long4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x8d799c90c3b12077l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertLong4Ushort4Long4(inV, out);
-            verifyResultsConvertUshort4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Ushort4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Ushort4Long4(inV, out);
-            verifyResultsConvertUshort4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Ushort4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortLong args = new ArgumentsUshortLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntLong {
-        public int inV;
-        public long out;
-    }
-
-    private void checkConvertInt2Long2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xd74f538b8a45cb5dl, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertLong2Int2Long2(inV, out);
-            verifyResultsConvertInt2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Int2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Int2Long2(inV, out);
-            verifyResultsConvertInt2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Int2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntLong args = new ArgumentsIntLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Long3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xd74f5e2ce94d9051l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertLong3Int3Long3(inV, out);
-            verifyResultsConvertInt3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Int3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Int3Long3(inV, out);
-            verifyResultsConvertInt3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Int3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntLong args = new ArgumentsIntLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Long4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd74f68ce48555545l, true, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertLong4Int4Long4(inV, out);
-            verifyResultsConvertInt4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Int4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Int4Long4(inV, out);
-            verifyResultsConvertInt4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Int4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntLong args = new ArgumentsIntLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintLong {
-        public int inV;
-        public long out;
-    }
-
-    private void checkConvertUint2Long2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xe71d0a7587b9ef60l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertLong2Uint2Long2(inV, out);
-            verifyResultsConvertUint2Long2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Uint2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong2Uint2Long2(inV, out);
-            verifyResultsConvertUint2Long2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Uint2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Long2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintLong args = new ArgumentsUintLong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Long3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe71d1516e6c1b454l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertLong3Uint3Long3(inV, out);
-            verifyResultsConvertUint3Long3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Uint3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong3Uint3Long3(inV, out);
-            verifyResultsConvertUint3Long3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Uint3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Long3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintLong args = new ArgumentsUintLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Long4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xe71d1fb845c97948l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertLong4Uint4Long4(inV, out);
-            verifyResultsConvertUint4Long4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Uint4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertLong4Uint4Long4(inV, out);
-            verifyResultsConvertUint4Long4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Uint4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Long4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintLong args = new ArgumentsUintLong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatUlong {
-        public float inV;
-        public long out;
-    }
-
-    private void checkConvertFloat2Ulong2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb52b5394ec4cff7l, 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);
-            verifyResultsConvertFloat2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Float2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Float2Ulong2(inV, out);
-            verifyResultsConvertFloat2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Float2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUlong args = new ArgumentsFloatUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat3Ulong3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfb547e5444dff0d5l, 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);
-            verifyResultsConvertFloat3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Float3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Float3Ulong3(inV, out);
-            verifyResultsConvertFloat3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Float3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUlong args = new ArgumentsFloatUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertFloat4Ulong4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfb56476f3afb11b3l, 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);
-            verifyResultsConvertFloat4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Float4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Float4Ulong4(inV, out);
-            verifyResultsConvertFloat4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Float4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertFloat4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatUlong args = new ArgumentsFloatUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertFloat4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharUlong {
-        public byte inV;
-        public long out;
-    }
-
-    private void checkConvertChar2Ulong2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x5862818b1fedf7b7l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertUlong2Char2Ulong2(inV, out);
-            verifyResultsConvertChar2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Char2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Char2Ulong2(inV, out);
-            verifyResultsConvertChar2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Char2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUlong args = new ArgumentsCharUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar3Ulong3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x58644aa616091895l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertUlong3Char3Ulong3(inV, out);
-            verifyResultsConvertChar3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Char3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Char3Ulong3(inV, out);
-            verifyResultsConvertChar3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Char3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUlong args = new ArgumentsCharUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertChar4Ulong4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x586613c10c243973l, false, 7);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertUlong4Char4Ulong4(inV, out);
-            verifyResultsConvertChar4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Char4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Char4Ulong4(inV, out);
-            verifyResultsConvertChar4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Char4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertChar4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharUlong args = new ArgumentsCharUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertChar4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharUlong {
-        public byte inV;
-        public long out;
-    }
-
-    private void checkConvertUchar2Ulong2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x7d30a192bbc61162l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertUlong2Uchar2Ulong2(inV, out);
-            verifyResultsConvertUchar2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Uchar2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Uchar2Ulong2(inV, out);
-            verifyResultsConvertUchar2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Uchar2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUlong args = new ArgumentsUcharUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar3Ulong3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x7d326aadb1e13240l, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertUlong3Uchar3Ulong3(inV, out);
-            verifyResultsConvertUchar3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Uchar3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Uchar3Ulong3(inV, out);
-            verifyResultsConvertUchar3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Uchar3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUlong args = new ArgumentsUcharUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUchar4Ulong4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7d3433c8a7fc531el, false, 8);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertUlong4Uchar4Ulong4(inV, out);
-            verifyResultsConvertUchar4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Uchar4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Uchar4Ulong4(inV, out);
-            verifyResultsConvertUchar4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Uchar4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUchar4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        byte[] arrayInV = new byte[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUlong args = new ArgumentsUcharUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUchar4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortUlong {
-        public short inV;
-        public long out;
-    }
-
-    private void checkConvertShort2Ulong2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x94cab7c3ffc6f6a3l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertUlong2Short2Ulong2(inV, out);
-            verifyResultsConvertShort2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Short2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Short2Ulong2(inV, out);
-            verifyResultsConvertShort2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Short2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUlong args = new ArgumentsShortUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort3Ulong3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x94cc80def5e21781l, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertUlong3Short3Ulong3(inV, out);
-            verifyResultsConvertShort3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Short3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Short3Ulong3(inV, out);
-            verifyResultsConvertShort3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Short3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUlong args = new ArgumentsShortUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertShort4Ulong4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x94ce49f9ebfd385fl, false, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertUlong4Short4Ulong4(inV, out);
-            verifyResultsConvertShort4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Short4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Short4Ulong4(inV, out);
-            verifyResultsConvertShort4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Short4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertShort4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortUlong args = new ArgumentsShortUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertShort4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortUlong {
-        public short inV;
-        public long out;
-    }
-
-    private void checkConvertUshort2Ulong2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xc36a190b2d13465cl, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertUlong2Ushort2Ulong2(inV, out);
-            verifyResultsConvertUshort2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Ushort2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Ushort2Ulong2(inV, out);
-            verifyResultsConvertUshort2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Ushort2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUlong args = new ArgumentsUshortUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort3Ulong3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xc36be226232e673al, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertUlong3Ushort3Ulong3(inV, out);
-            verifyResultsConvertUshort3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Ushort3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Ushort3Ulong3(inV, out);
-            verifyResultsConvertUshort3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Ushort3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUlong args = new ArgumentsUshortUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUshort4Ulong4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xc36dab4119498818l, false, 16);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertUlong4Ushort4Ulong4(inV, out);
-            verifyResultsConvertUshort4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Ushort4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Ushort4Ulong4(inV, out);
-            verifyResultsConvertUshort4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Ushort4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUshort4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        short[] arrayInV = new short[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUlong args = new ArgumentsUshortUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUshort4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntUlong {
-        public int inV;
-        public long out;
-    }
-
-    private void checkConvertInt2Ulong2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x2a53676074a824f6l, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertUlong2Int2Ulong2(inV, out);
-            verifyResultsConvertInt2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Int2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Int2Ulong2(inV, out);
-            verifyResultsConvertInt2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Int2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUlong args = new ArgumentsIntUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt3Ulong3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x2a55307b6ac345d4l, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertUlong3Int3Ulong3(inV, out);
-            verifyResultsConvertInt3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Int3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Int3Ulong3(inV, out);
-            verifyResultsConvertInt3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Int3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUlong args = new ArgumentsIntUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertInt4Ulong4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x2a56f99660de66b2l, false, 31);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertUlong4Int4Ulong4(inV, out);
-            verifyResultsConvertInt4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Int4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Int4Ulong4(inV, out);
-            verifyResultsConvertInt4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Int4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertInt4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntUlong args = new ArgumentsIntUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%d", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertInt4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintUlong {
-        public int inV;
-        public long out;
-    }
-
-    private void checkConvertUint2Ulong2() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xd1e120ae072a3177l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.forEach_testConvertUlong2Uint2Ulong2(inV, out);
-            verifyResultsConvertUint2Ulong2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Uint2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong2Uint2Ulong2(inV, out);
-            verifyResultsConvertUint2Ulong2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Uint2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUlong args = new ArgumentsUintUlong();
-                args.inV = arrayInV[i * 2 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint3Ulong3() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xd1e2e9c8fd455255l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.forEach_testConvertUlong3Uint3Ulong3(inV, out);
-            verifyResultsConvertUint3Ulong3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Uint3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong3Uint3Ulong3(inV, out);
-            verifyResultsConvertUint3Ulong3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Uint3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUlong args = new ArgumentsUintUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkConvertUint4Ulong4() {
-        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xd1e4b2e3f3607333l, false, 32);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.forEach_testConvertUlong4Uint4Ulong4(inV, out);
-            verifyResultsConvertUint4Ulong4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Uint4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testConvertUlong4Uint4Ulong4(inV, out);
-            verifyResultsConvertUint4Ulong4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Uint4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsConvertUint4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
-        int[] arrayInV = new int[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUlong args = new ArgumentsUintUlong();
-                args.inV = arrayInV[i * 4 + j];
-                // 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) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("0x%x", args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkConvertUint4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testConvert() {
-        checkConvertFloat2Float2();
-        checkConvertFloat3Float3();
-        checkConvertFloat4Float4();
-        checkConvertChar2Float2();
-        checkConvertChar3Float3();
-        checkConvertChar4Float4();
-        checkConvertUchar2Float2();
-        checkConvertUchar3Float3();
-        checkConvertUchar4Float4();
-        checkConvertShort2Float2();
-        checkConvertShort3Float3();
-        checkConvertShort4Float4();
-        checkConvertUshort2Float2();
-        checkConvertUshort3Float3();
-        checkConvertUshort4Float4();
-        checkConvertInt2Float2();
-        checkConvertInt3Float3();
-        checkConvertInt4Float4();
-        checkConvertUint2Float2();
-        checkConvertUint3Float3();
-        checkConvertUint4Float4();
-        checkConvertFloat2Char2();
-        checkConvertFloat3Char3();
-        checkConvertFloat4Char4();
-        checkConvertChar2Char2();
-        checkConvertChar3Char3();
-        checkConvertChar4Char4();
-        checkConvertUchar2Char2();
-        checkConvertUchar3Char3();
-        checkConvertUchar4Char4();
-        checkConvertShort2Char2();
-        checkConvertShort3Char3();
-        checkConvertShort4Char4();
-        checkConvertUshort2Char2();
-        checkConvertUshort3Char3();
-        checkConvertUshort4Char4();
-        checkConvertInt2Char2();
-        checkConvertInt3Char3();
-        checkConvertInt4Char4();
-        checkConvertUint2Char2();
-        checkConvertUint3Char3();
-        checkConvertUint4Char4();
-        checkConvertFloat2Uchar2();
-        checkConvertFloat3Uchar3();
-        checkConvertFloat4Uchar4();
-        checkConvertChar2Uchar2();
-        checkConvertChar3Uchar3();
-        checkConvertChar4Uchar4();
-        checkConvertUchar2Uchar2();
-        checkConvertUchar3Uchar3();
-        checkConvertUchar4Uchar4();
-        checkConvertShort2Uchar2();
-        checkConvertShort3Uchar3();
-        checkConvertShort4Uchar4();
-        checkConvertUshort2Uchar2();
-        checkConvertUshort3Uchar3();
-        checkConvertUshort4Uchar4();
-        checkConvertInt2Uchar2();
-        checkConvertInt3Uchar3();
-        checkConvertInt4Uchar4();
-        checkConvertUint2Uchar2();
-        checkConvertUint3Uchar3();
-        checkConvertUint4Uchar4();
-        checkConvertFloat2Short2();
-        checkConvertFloat3Short3();
-        checkConvertFloat4Short4();
-        checkConvertChar2Short2();
-        checkConvertChar3Short3();
-        checkConvertChar4Short4();
-        checkConvertUchar2Short2();
-        checkConvertUchar3Short3();
-        checkConvertUchar4Short4();
-        checkConvertShort2Short2();
-        checkConvertShort3Short3();
-        checkConvertShort4Short4();
-        checkConvertUshort2Short2();
-        checkConvertUshort3Short3();
-        checkConvertUshort4Short4();
-        checkConvertInt2Short2();
-        checkConvertInt3Short3();
-        checkConvertInt4Short4();
-        checkConvertUint2Short2();
-        checkConvertUint3Short3();
-        checkConvertUint4Short4();
-        checkConvertFloat2Ushort2();
-        checkConvertFloat3Ushort3();
-        checkConvertFloat4Ushort4();
-        checkConvertChar2Ushort2();
-        checkConvertChar3Ushort3();
-        checkConvertChar4Ushort4();
-        checkConvertUchar2Ushort2();
-        checkConvertUchar3Ushort3();
-        checkConvertUchar4Ushort4();
-        checkConvertShort2Ushort2();
-        checkConvertShort3Ushort3();
-        checkConvertShort4Ushort4();
-        checkConvertUshort2Ushort2();
-        checkConvertUshort3Ushort3();
-        checkConvertUshort4Ushort4();
-        checkConvertInt2Ushort2();
-        checkConvertInt3Ushort3();
-        checkConvertInt4Ushort4();
-        checkConvertUint2Ushort2();
-        checkConvertUint3Ushort3();
-        checkConvertUint4Ushort4();
-        checkConvertFloat2Int2();
-        checkConvertFloat3Int3();
-        checkConvertFloat4Int4();
-        checkConvertChar2Int2();
-        checkConvertChar3Int3();
-        checkConvertChar4Int4();
-        checkConvertUchar2Int2();
-        checkConvertUchar3Int3();
-        checkConvertUchar4Int4();
-        checkConvertShort2Int2();
-        checkConvertShort3Int3();
-        checkConvertShort4Int4();
-        checkConvertUshort2Int2();
-        checkConvertUshort3Int3();
-        checkConvertUshort4Int4();
-        checkConvertInt2Int2();
-        checkConvertInt3Int3();
-        checkConvertInt4Int4();
-        checkConvertUint2Int2();
-        checkConvertUint3Int3();
-        checkConvertUint4Int4();
-        checkConvertFloat2Uint2();
-        checkConvertFloat3Uint3();
-        checkConvertFloat4Uint4();
-        checkConvertChar2Uint2();
-        checkConvertChar3Uint3();
-        checkConvertChar4Uint4();
-        checkConvertUchar2Uint2();
-        checkConvertUchar3Uint3();
-        checkConvertUchar4Uint4();
-        checkConvertShort2Uint2();
-        checkConvertShort3Uint3();
-        checkConvertShort4Uint4();
-        checkConvertUshort2Uint2();
-        checkConvertUshort3Uint3();
-        checkConvertUshort4Uint4();
-        checkConvertInt2Uint2();
-        checkConvertInt3Uint3();
-        checkConvertInt4Uint4();
-        checkConvertUint2Uint2();
-        checkConvertUint3Uint3();
-        checkConvertUint4Uint4();
-        checkConvertDouble2Double2();
-        checkConvertDouble3Double3();
-        checkConvertDouble4Double4();
-        checkConvertLong2Double2();
-        checkConvertLong3Double3();
-        checkConvertLong4Double4();
-        checkConvertUlong2Double2();
-        checkConvertUlong3Double3();
-        checkConvertUlong4Double4();
-        checkConvertDouble2Long2();
-        checkConvertDouble3Long3();
-        checkConvertDouble4Long4();
-        checkConvertLong2Long2();
-        checkConvertLong3Long3();
-        checkConvertLong4Long4();
-        checkConvertUlong2Long2();
-        checkConvertUlong3Long3();
-        checkConvertUlong4Long4();
-        checkConvertDouble2Ulong2();
-        checkConvertDouble3Ulong3();
-        checkConvertDouble4Ulong4();
-        checkConvertLong2Ulong2();
-        checkConvertLong3Ulong3();
-        checkConvertLong4Ulong4();
-        checkConvertUlong2Ulong2();
-        checkConvertUlong3Ulong3();
-        checkConvertUlong4Ulong4();
-        checkConvertDouble2Float2();
-        checkConvertDouble3Float3();
-        checkConvertDouble4Float4();
-        checkConvertLong2Float2();
-        checkConvertLong3Float3();
-        checkConvertLong4Float4();
-        checkConvertUlong2Float2();
-        checkConvertUlong3Float3();
-        checkConvertUlong4Float4();
-        checkConvertDouble2Char2();
-        checkConvertDouble3Char3();
-        checkConvertDouble4Char4();
-        checkConvertLong2Char2();
-        checkConvertLong3Char3();
-        checkConvertLong4Char4();
-        checkConvertUlong2Char2();
-        checkConvertUlong3Char3();
-        checkConvertUlong4Char4();
-        checkConvertDouble2Uchar2();
-        checkConvertDouble3Uchar3();
-        checkConvertDouble4Uchar4();
-        checkConvertLong2Uchar2();
-        checkConvertLong3Uchar3();
-        checkConvertLong4Uchar4();
-        checkConvertUlong2Uchar2();
-        checkConvertUlong3Uchar3();
-        checkConvertUlong4Uchar4();
-        checkConvertDouble2Short2();
-        checkConvertDouble3Short3();
-        checkConvertDouble4Short4();
-        checkConvertLong2Short2();
-        checkConvertLong3Short3();
-        checkConvertLong4Short4();
-        checkConvertUlong2Short2();
-        checkConvertUlong3Short3();
-        checkConvertUlong4Short4();
-        checkConvertDouble2Ushort2();
-        checkConvertDouble3Ushort3();
-        checkConvertDouble4Ushort4();
-        checkConvertLong2Ushort2();
-        checkConvertLong3Ushort3();
-        checkConvertLong4Ushort4();
-        checkConvertUlong2Ushort2();
-        checkConvertUlong3Ushort3();
-        checkConvertUlong4Ushort4();
-        checkConvertDouble2Int2();
-        checkConvertDouble3Int3();
-        checkConvertDouble4Int4();
-        checkConvertLong2Int2();
-        checkConvertLong3Int3();
-        checkConvertLong4Int4();
-        checkConvertUlong2Int2();
-        checkConvertUlong3Int3();
-        checkConvertUlong4Int4();
-        checkConvertDouble2Uint2();
-        checkConvertDouble3Uint3();
-        checkConvertDouble4Uint4();
-        checkConvertLong2Uint2();
-        checkConvertLong3Uint3();
-        checkConvertLong4Uint4();
-        checkConvertUlong2Uint2();
-        checkConvertUlong3Uint3();
-        checkConvertUlong4Uint4();
-        checkConvertFloat2Double2();
-        checkConvertFloat3Double3();
-        checkConvertFloat4Double4();
-        checkConvertChar2Double2();
-        checkConvertChar3Double3();
-        checkConvertChar4Double4();
-        checkConvertUchar2Double2();
-        checkConvertUchar3Double3();
-        checkConvertUchar4Double4();
-        checkConvertShort2Double2();
-        checkConvertShort3Double3();
-        checkConvertShort4Double4();
-        checkConvertUshort2Double2();
-        checkConvertUshort3Double3();
-        checkConvertUshort4Double4();
-        checkConvertInt2Double2();
-        checkConvertInt3Double3();
-        checkConvertInt4Double4();
-        checkConvertUint2Double2();
-        checkConvertUint3Double3();
-        checkConvertUint4Double4();
-        checkConvertFloat2Long2();
-        checkConvertFloat3Long3();
-        checkConvertFloat4Long4();
-        checkConvertChar2Long2();
-        checkConvertChar3Long3();
-        checkConvertChar4Long4();
-        checkConvertUchar2Long2();
-        checkConvertUchar3Long3();
-        checkConvertUchar4Long4();
-        checkConvertShort2Long2();
-        checkConvertShort3Long3();
-        checkConvertShort4Long4();
-        checkConvertUshort2Long2();
-        checkConvertUshort3Long3();
-        checkConvertUshort4Long4();
-        checkConvertInt2Long2();
-        checkConvertInt3Long3();
-        checkConvertInt4Long4();
-        checkConvertUint2Long2();
-        checkConvertUint3Long3();
-        checkConvertUint4Long4();
-        checkConvertFloat2Ulong2();
-        checkConvertFloat3Ulong3();
-        checkConvertFloat4Ulong4();
-        checkConvertChar2Ulong2();
-        checkConvertChar3Ulong3();
-        checkConvertChar4Ulong4();
-        checkConvertUchar2Ulong2();
-        checkConvertUchar3Ulong3();
-        checkConvertUchar4Ulong4();
-        checkConvertShort2Ulong2();
-        checkConvertShort3Ulong3();
-        checkConvertShort4Ulong4();
-        checkConvertUshort2Ulong2();
-        checkConvertUshort3Ulong3();
-        checkConvertUshort4Ulong4();
-        checkConvertInt2Ulong2();
-        checkConvertInt3Ulong3();
-        checkConvertInt4Ulong4();
-        checkConvertUint2Ulong2();
-        checkConvertUint3Ulong3();
-        checkConvertUint4Ulong4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestConvert.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestConvert.rs
deleted file mode 100644
index 7c94d5e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestConvert.rs
+++ /dev/null
@@ -1,1221 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float2 __attribute__((kernel)) testConvertFloat2Float2Float2(float2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Float3Float3(float3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Float4Float4(float4 inV) {
-    return convert_float4(inV);
-}
-
-float2 __attribute__((kernel)) testConvertFloat2Char2Float2(char2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Char3Float3(char3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Char4Float4(char4 inV) {
-    return convert_float4(inV);
-}
-
-float2 __attribute__((kernel)) testConvertFloat2Uchar2Float2(uchar2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Uchar3Float3(uchar3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Uchar4Float4(uchar4 inV) {
-    return convert_float4(inV);
-}
-
-float2 __attribute__((kernel)) testConvertFloat2Short2Float2(short2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Short3Float3(short3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Short4Float4(short4 inV) {
-    return convert_float4(inV);
-}
-
-float2 __attribute__((kernel)) testConvertFloat2Ushort2Float2(ushort2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Ushort3Float3(ushort3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Ushort4Float4(ushort4 inV) {
-    return convert_float4(inV);
-}
-
-float2 __attribute__((kernel)) testConvertFloat2Int2Float2(int2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Int3Float3(int3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Int4Float4(int4 inV) {
-    return convert_float4(inV);
-}
-
-float2 __attribute__((kernel)) testConvertFloat2Uint2Float2(uint2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Uint3Float3(uint3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Uint4Float4(uint4 inV) {
-    return convert_float4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Float2Char2(float2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Float3Char3(float3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Float4Char4(float4 inV) {
-    return convert_char4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Char2Char2(char2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Char3Char3(char3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Char4Char4(char4 inV) {
-    return convert_char4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Uchar2Char2(uchar2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Uchar3Char3(uchar3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Uchar4Char4(uchar4 inV) {
-    return convert_char4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Short2Char2(short2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Short3Char3(short3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Short4Char4(short4 inV) {
-    return convert_char4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Ushort2Char2(ushort2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Ushort3Char3(ushort3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Ushort4Char4(ushort4 inV) {
-    return convert_char4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Int2Char2(int2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Int3Char3(int3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Int4Char4(int4 inV) {
-    return convert_char4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Uint2Char2(uint2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Uint3Char3(uint3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Uint4Char4(uint4 inV) {
-    return convert_char4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Float2Uchar2(float2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Float3Uchar3(float3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Float4Uchar4(float4 inV) {
-    return convert_uchar4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Char2Uchar2(char2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Char3Uchar3(char3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Char4Uchar4(char4 inV) {
-    return convert_uchar4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Uchar2Uchar2(uchar2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Uchar3Uchar3(uchar3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Uchar4Uchar4(uchar4 inV) {
-    return convert_uchar4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Short2Uchar2(short2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Short3Uchar3(short3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Short4Uchar4(short4 inV) {
-    return convert_uchar4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Ushort2Uchar2(ushort2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Ushort3Uchar3(ushort3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Ushort4Uchar4(ushort4 inV) {
-    return convert_uchar4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Int2Uchar2(int2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Int3Uchar3(int3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Int4Uchar4(int4 inV) {
-    return convert_uchar4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Uint2Uchar2(uint2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Uint3Uchar3(uint3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Uint4Uchar4(uint4 inV) {
-    return convert_uchar4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Float2Short2(float2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Float3Short3(float3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Float4Short4(float4 inV) {
-    return convert_short4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Char2Short2(char2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Char3Short3(char3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Char4Short4(char4 inV) {
-    return convert_short4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Uchar2Short2(uchar2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Uchar3Short3(uchar3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Uchar4Short4(uchar4 inV) {
-    return convert_short4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Short2Short2(short2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Short3Short3(short3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Short4Short4(short4 inV) {
-    return convert_short4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Ushort2Short2(ushort2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Ushort3Short3(ushort3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Ushort4Short4(ushort4 inV) {
-    return convert_short4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Int2Short2(int2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Int3Short3(int3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Int4Short4(int4 inV) {
-    return convert_short4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Uint2Short2(uint2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Uint3Short3(uint3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Uint4Short4(uint4 inV) {
-    return convert_short4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Float2Ushort2(float2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Float3Ushort3(float3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Float4Ushort4(float4 inV) {
-    return convert_ushort4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Char2Ushort2(char2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Char3Ushort3(char3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Char4Ushort4(char4 inV) {
-    return convert_ushort4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Uchar2Ushort2(uchar2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Uchar3Ushort3(uchar3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Uchar4Ushort4(uchar4 inV) {
-    return convert_ushort4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Short2Ushort2(short2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Short3Ushort3(short3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Short4Ushort4(short4 inV) {
-    return convert_ushort4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Ushort2Ushort2(ushort2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Ushort3Ushort3(ushort3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Ushort4Ushort4(ushort4 inV) {
-    return convert_ushort4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Int2Ushort2(int2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Int3Ushort3(int3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Int4Ushort4(int4 inV) {
-    return convert_ushort4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Uint2Ushort2(uint2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Uint3Ushort3(uint3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Uint4Ushort4(uint4 inV) {
-    return convert_ushort4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Float2Int2(float2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Float3Int3(float3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Float4Int4(float4 inV) {
-    return convert_int4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Char2Int2(char2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Char3Int3(char3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Char4Int4(char4 inV) {
-    return convert_int4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Uchar2Int2(uchar2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Uchar3Int3(uchar3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Uchar4Int4(uchar4 inV) {
-    return convert_int4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Short2Int2(short2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Short3Int3(short3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Short4Int4(short4 inV) {
-    return convert_int4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Ushort2Int2(ushort2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Ushort3Int3(ushort3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Ushort4Int4(ushort4 inV) {
-    return convert_int4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Int2Int2(int2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Int3Int3(int3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Int4Int4(int4 inV) {
-    return convert_int4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Uint2Int2(uint2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Uint3Int3(uint3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Uint4Int4(uint4 inV) {
-    return convert_int4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Float2Uint2(float2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Float3Uint3(float3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Float4Uint4(float4 inV) {
-    return convert_uint4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Char2Uint2(char2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Char3Uint3(char3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Char4Uint4(char4 inV) {
-    return convert_uint4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Uchar2Uint2(uchar2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Uchar3Uint3(uchar3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Uchar4Uint4(uchar4 inV) {
-    return convert_uint4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Short2Uint2(short2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Short3Uint3(short3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Short4Uint4(short4 inV) {
-    return convert_uint4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Ushort2Uint2(ushort2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Ushort3Uint3(ushort3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Ushort4Uint4(ushort4 inV) {
-    return convert_uint4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Int2Uint2(int2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Int3Uint3(int3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Int4Uint4(int4 inV) {
-    return convert_uint4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Uint2Uint2(uint2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Uint3Uint3(uint3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Uint4Uint4(uint4 inV) {
-    return convert_uint4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Double2Double2(double2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Double3Double3(double3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Double4Double4(double4 inV) {
-    return convert_double4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Long2Double2(long2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Long3Double3(long3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Long4Double4(long4 inV) {
-    return convert_double4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Ulong2Double2(ulong2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Ulong3Double3(ulong3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Ulong4Double4(ulong4 inV) {
-    return convert_double4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Double2Long2(double2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Double3Long3(double3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Double4Long4(double4 inV) {
-    return convert_long4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Long2Long2(long2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Long3Long3(long3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Long4Long4(long4 inV) {
-    return convert_long4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Ulong2Long2(ulong2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Ulong3Long3(ulong3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Ulong4Long4(ulong4 inV) {
-    return convert_long4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Double2Ulong2(double2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Double3Ulong3(double3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Double4Ulong4(double4 inV) {
-    return convert_ulong4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Long2Ulong2(long2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Long3Ulong3(long3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Long4Ulong4(long4 inV) {
-    return convert_ulong4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Ulong2Ulong2(ulong2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Ulong3Ulong3(ulong3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Ulong4Ulong4(ulong4 inV) {
-    return convert_ulong4(inV);
-}
-
-float2 __attribute__((kernel)) testConvertFloat2Double2Float2(double2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Double3Float3(double3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Double4Float4(double4 inV) {
-    return convert_float4(inV);
-}
-
-float2 __attribute__((kernel)) testConvertFloat2Long2Float2(long2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Long3Float3(long3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Long4Float4(long4 inV) {
-    return convert_float4(inV);
-}
-
-float2 __attribute__((kernel)) testConvertFloat2Ulong2Float2(ulong2 inV) {
-    return convert_float2(inV);
-}
-
-float3 __attribute__((kernel)) testConvertFloat3Ulong3Float3(ulong3 inV) {
-    return convert_float3(inV);
-}
-
-float4 __attribute__((kernel)) testConvertFloat4Ulong4Float4(ulong4 inV) {
-    return convert_float4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Double2Char2(double2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Double3Char3(double3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Double4Char4(double4 inV) {
-    return convert_char4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Long2Char2(long2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Long3Char3(long3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Long4Char4(long4 inV) {
-    return convert_char4(inV);
-}
-
-char2 __attribute__((kernel)) testConvertChar2Ulong2Char2(ulong2 inV) {
-    return convert_char2(inV);
-}
-
-char3 __attribute__((kernel)) testConvertChar3Ulong3Char3(ulong3 inV) {
-    return convert_char3(inV);
-}
-
-char4 __attribute__((kernel)) testConvertChar4Ulong4Char4(ulong4 inV) {
-    return convert_char4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Double2Uchar2(double2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Double3Uchar3(double3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Double4Uchar4(double4 inV) {
-    return convert_uchar4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Long2Uchar2(long2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Long3Uchar3(long3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Long4Uchar4(long4 inV) {
-    return convert_uchar4(inV);
-}
-
-uchar2 __attribute__((kernel)) testConvertUchar2Ulong2Uchar2(ulong2 inV) {
-    return convert_uchar2(inV);
-}
-
-uchar3 __attribute__((kernel)) testConvertUchar3Ulong3Uchar3(ulong3 inV) {
-    return convert_uchar3(inV);
-}
-
-uchar4 __attribute__((kernel)) testConvertUchar4Ulong4Uchar4(ulong4 inV) {
-    return convert_uchar4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Double2Short2(double2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Double3Short3(double3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Double4Short4(double4 inV) {
-    return convert_short4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Long2Short2(long2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Long3Short3(long3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Long4Short4(long4 inV) {
-    return convert_short4(inV);
-}
-
-short2 __attribute__((kernel)) testConvertShort2Ulong2Short2(ulong2 inV) {
-    return convert_short2(inV);
-}
-
-short3 __attribute__((kernel)) testConvertShort3Ulong3Short3(ulong3 inV) {
-    return convert_short3(inV);
-}
-
-short4 __attribute__((kernel)) testConvertShort4Ulong4Short4(ulong4 inV) {
-    return convert_short4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Double2Ushort2(double2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Double3Ushort3(double3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Double4Ushort4(double4 inV) {
-    return convert_ushort4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Long2Ushort2(long2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Long3Ushort3(long3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Long4Ushort4(long4 inV) {
-    return convert_ushort4(inV);
-}
-
-ushort2 __attribute__((kernel)) testConvertUshort2Ulong2Ushort2(ulong2 inV) {
-    return convert_ushort2(inV);
-}
-
-ushort3 __attribute__((kernel)) testConvertUshort3Ulong3Ushort3(ulong3 inV) {
-    return convert_ushort3(inV);
-}
-
-ushort4 __attribute__((kernel)) testConvertUshort4Ulong4Ushort4(ulong4 inV) {
-    return convert_ushort4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Double2Int2(double2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Double3Int3(double3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Double4Int4(double4 inV) {
-    return convert_int4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Long2Int2(long2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Long3Int3(long3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Long4Int4(long4 inV) {
-    return convert_int4(inV);
-}
-
-int2 __attribute__((kernel)) testConvertInt2Ulong2Int2(ulong2 inV) {
-    return convert_int2(inV);
-}
-
-int3 __attribute__((kernel)) testConvertInt3Ulong3Int3(ulong3 inV) {
-    return convert_int3(inV);
-}
-
-int4 __attribute__((kernel)) testConvertInt4Ulong4Int4(ulong4 inV) {
-    return convert_int4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Double2Uint2(double2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Double3Uint3(double3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Double4Uint4(double4 inV) {
-    return convert_uint4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Long2Uint2(long2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Long3Uint3(long3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Long4Uint4(long4 inV) {
-    return convert_uint4(inV);
-}
-
-uint2 __attribute__((kernel)) testConvertUint2Ulong2Uint2(ulong2 inV) {
-    return convert_uint2(inV);
-}
-
-uint3 __attribute__((kernel)) testConvertUint3Ulong3Uint3(ulong3 inV) {
-    return convert_uint3(inV);
-}
-
-uint4 __attribute__((kernel)) testConvertUint4Ulong4Uint4(ulong4 inV) {
-    return convert_uint4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Float2Double2(float2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Float3Double3(float3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Float4Double4(float4 inV) {
-    return convert_double4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Char2Double2(char2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Char3Double3(char3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Char4Double4(char4 inV) {
-    return convert_double4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Uchar2Double2(uchar2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Uchar3Double3(uchar3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Uchar4Double4(uchar4 inV) {
-    return convert_double4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Short2Double2(short2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Short3Double3(short3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Short4Double4(short4 inV) {
-    return convert_double4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Ushort2Double2(ushort2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Ushort3Double3(ushort3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Ushort4Double4(ushort4 inV) {
-    return convert_double4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Int2Double2(int2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Int3Double3(int3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Int4Double4(int4 inV) {
-    return convert_double4(inV);
-}
-
-double2 __attribute__((kernel)) testConvertDouble2Uint2Double2(uint2 inV) {
-    return convert_double2(inV);
-}
-
-double3 __attribute__((kernel)) testConvertDouble3Uint3Double3(uint3 inV) {
-    return convert_double3(inV);
-}
-
-double4 __attribute__((kernel)) testConvertDouble4Uint4Double4(uint4 inV) {
-    return convert_double4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Float2Long2(float2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Float3Long3(float3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Float4Long4(float4 inV) {
-    return convert_long4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Char2Long2(char2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Char3Long3(char3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Char4Long4(char4 inV) {
-    return convert_long4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Uchar2Long2(uchar2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Uchar3Long3(uchar3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Uchar4Long4(uchar4 inV) {
-    return convert_long4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Short2Long2(short2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Short3Long3(short3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Short4Long4(short4 inV) {
-    return convert_long4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Ushort2Long2(ushort2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Ushort3Long3(ushort3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Ushort4Long4(ushort4 inV) {
-    return convert_long4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Int2Long2(int2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Int3Long3(int3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Int4Long4(int4 inV) {
-    return convert_long4(inV);
-}
-
-long2 __attribute__((kernel)) testConvertLong2Uint2Long2(uint2 inV) {
-    return convert_long2(inV);
-}
-
-long3 __attribute__((kernel)) testConvertLong3Uint3Long3(uint3 inV) {
-    return convert_long3(inV);
-}
-
-long4 __attribute__((kernel)) testConvertLong4Uint4Long4(uint4 inV) {
-    return convert_long4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Float2Ulong2(float2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Float3Ulong3(float3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Float4Ulong4(float4 inV) {
-    return convert_ulong4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Char2Ulong2(char2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Char3Ulong3(char3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Char4Ulong4(char4 inV) {
-    return convert_ulong4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Uchar2Ulong2(uchar2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Uchar3Ulong3(uchar3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Uchar4Ulong4(uchar4 inV) {
-    return convert_ulong4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Short2Ulong2(short2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Short3Ulong3(short3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Short4Ulong4(short4 inV) {
-    return convert_ulong4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Ushort2Ulong2(ushort2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Ushort3Ulong3(ushort3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Ushort4Ulong4(ushort4 inV) {
-    return convert_ulong4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Int2Ulong2(int2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Int3Ulong3(int3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Int4Ulong4(int4 inV) {
-    return convert_ulong4(inV);
-}
-
-ulong2 __attribute__((kernel)) testConvertUlong2Uint2Ulong2(uint2 inV) {
-    return convert_ulong2(inV);
-}
-
-ulong3 __attribute__((kernel)) testConvertUlong3Uint3Ulong3(uint3 inV) {
-    return convert_ulong3(inV);
-}
-
-ulong4 __attribute__((kernel)) testConvertUlong4Uint4Ulong4(uint4 inV) {
-    return convert_ulong4(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestConvertRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestConvertRelaxed.rs
deleted file mode 100644
index d13c634..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestConvertRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestConvert.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCopysign.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCopysign.java
deleted file mode 100644
index cb8794a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCopysign.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestCopysign extends RSBaseCompute {
-
-    private ScriptC_TestCopysign script;
-    private ScriptC_TestCopysignRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestCopysign(mRS);
-        scriptRelaxed = new ScriptC_TestCopysignRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkCopysignFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xeebba96e8c48145l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xeebba96e8c48146l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testCopysignFloatFloatFloat(inX, out);
-            verifyResultsCopysignFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testCopysignFloatFloatFloat(inX, out);
-            verifyResultsCopysignFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCopysignFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCopysign(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCopysignFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCopysignFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbeb0e1cc912e993bl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbeb0e1cc912e993cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testCopysignFloat2Float2Float2(inX, out);
-            verifyResultsCopysignFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testCopysignFloat2Float2Float2(inX, out);
-            verifyResultsCopysignFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCopysignFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCopysign(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCopysignFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCopysignFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1315bfec930c9adcl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1315bfec930c9addl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testCopysignFloat3Float3Float3(inX, out);
-            verifyResultsCopysignFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testCopysignFloat3Float3Float3(inX, out);
-            verifyResultsCopysignFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCopysignFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCopysign(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCopysignFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCopysignFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x677a9e0c94ea9c7dl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x677a9e0c94ea9c7el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testCopysignFloat4Float4Float4(inX, out);
-            verifyResultsCopysignFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testCopysignFloat4Float4Float4(inX, out);
-            verifyResultsCopysignFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCopysignFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCopysign(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCopysignFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testCopysign() {
-        checkCopysignFloatFloatFloat();
-        checkCopysignFloat2Float2Float2();
-        checkCopysignFloat3Float3Float3();
-        checkCopysignFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCopysign.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCopysign.rs
deleted file mode 100644
index d7bc4d0..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCopysign.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testCopysignFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return copysign(inX, inY);
-}
-
-float2 __attribute__((kernel)) testCopysignFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return copysign(inX, inY);
-}
-
-float3 __attribute__((kernel)) testCopysignFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return copysign(inX, inY);
-}
-
-float4 __attribute__((kernel)) testCopysignFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return copysign(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCopysignRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCopysignRelaxed.rs
deleted file mode 100644
index 01002d7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCopysignRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestCopysign.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCos.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCos.java
deleted file mode 100644
index c3aaf28..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCos.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestCos extends RSBaseCompute {
-
-    private ScriptC_TestCos script;
-    private ScriptC_TestCosRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestCos(mRS);
-        scriptRelaxed = new ScriptC_TestCosRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkCosFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x35eace7a33fd0be0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testCosFloatFloat(in, out);
-            verifyResultsCosFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testCosFloatFloat(in, out);
-            verifyResultsCosFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCosFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCosFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCosFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6cec729d2fe33ffcl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testCosFloat2Float2(in, out);
-            verifyResultsCosFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testCosFloat2Float2(in, out);
-            verifyResultsCosFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCosFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCosFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCosFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6cec7d3e8ee9d596l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testCosFloat3Float3(in, out);
-            verifyResultsCosFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testCosFloat3Float3(in, out);
-            verifyResultsCosFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCosFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCosFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCosFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6cec87dfedf06b30l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testCosFloat4Float4(in, out);
-            verifyResultsCosFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testCosFloat4Float4(in, out);
-            verifyResultsCosFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCosFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCosFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testCos() {
-        checkCosFloatFloat();
-        checkCosFloat2Float2();
-        checkCosFloat3Float3();
-        checkCosFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCos.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCos.rs
deleted file mode 100644
index 5605139..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCos.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testCosFloatFloat(float in) {
-    return cos(in);
-}
-
-float2 __attribute__((kernel)) testCosFloat2Float2(float2 in) {
-    return cos(in);
-}
-
-float3 __attribute__((kernel)) testCosFloat3Float3(float3 in) {
-    return cos(in);
-}
-
-float4 __attribute__((kernel)) testCosFloat4Float4(float4 in) {
-    return cos(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCosRelaxed.rs
deleted file mode 100644
index 1871a69..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCosRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestCos.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCosh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCosh.java
deleted file mode 100644
index c1f6bf3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCosh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestCosh extends RSBaseCompute {
-
-    private ScriptC_TestCosh script;
-    private ScriptC_TestCoshRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestCosh(mRS);
-        scriptRelaxed = new ScriptC_TestCoshRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkCoshFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xca4f5b95e29e11bel, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testCoshFloatFloat(in, out);
-            verifyResultsCoshFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testCoshFloatFloat(in, out);
-            verifyResultsCoshFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCoshFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCoshFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCoshFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x372b9f8d78e6a06al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testCoshFloat2Float2(in, out);
-            verifyResultsCoshFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testCoshFloat2Float2(in, out);
-            verifyResultsCoshFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCoshFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCoshFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCoshFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x372baa2ed7ed3604l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testCoshFloat3Float3(in, out);
-            verifyResultsCoshFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testCoshFloat3Float3(in, out);
-            verifyResultsCoshFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCoshFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCoshFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCoshFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x372bb4d036f3cb9el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testCoshFloat4Float4(in, out);
-            verifyResultsCoshFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testCoshFloat4Float4(in, out);
-            verifyResultsCoshFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCoshFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCoshFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testCosh() {
-        checkCoshFloatFloat();
-        checkCoshFloat2Float2();
-        checkCoshFloat3Float3();
-        checkCoshFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCosh.rs
deleted file mode 100644
index b2d89b9..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCosh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testCoshFloatFloat(float in) {
-    return cosh(in);
-}
-
-float2 __attribute__((kernel)) testCoshFloat2Float2(float2 in) {
-    return cosh(in);
-}
-
-float3 __attribute__((kernel)) testCoshFloat3Float3(float3 in) {
-    return cosh(in);
-}
-
-float4 __attribute__((kernel)) testCoshFloat4Float4(float4 in) {
-    return cosh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCoshRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCoshRelaxed.rs
deleted file mode 100644
index cf28629..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCoshRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestCosh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCospi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCospi.java
deleted file mode 100644
index 2d18af9..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCospi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestCospi extends RSBaseCompute {
-
-    private ScriptC_TestCospi script;
-    private ScriptC_TestCospiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestCospi(mRS);
-        scriptRelaxed = new ScriptC_TestCospiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkCospiFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf63d9fae6fcc7f1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testCospiFloatFloat(in, out);
-            verifyResultsCospiFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testCospiFloatFloat(in, out);
-            verifyResultsCospiFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCospiFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCospiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCospiFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2830872a08f896c5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testCospiFloat2Float2(in, out);
-            verifyResultsCospiFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testCospiFloat2Float2(in, out);
-            verifyResultsCospiFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCospiFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCospiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCospiFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x283091cb67ff2c5fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testCospiFloat3Float3(in, out);
-            verifyResultsCospiFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testCospiFloat3Float3(in, out);
-            verifyResultsCospiFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCospiFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCospiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkCospiFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x28309c6cc705c1f9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testCospiFloat4Float4(in, out);
-            verifyResultsCospiFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testCospiFloat4Float4(in, out);
-            verifyResultsCospiFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCospiFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeCospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkCospiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testCospi() {
-        checkCospiFloatFloat();
-        checkCospiFloat2Float2();
-        checkCospiFloat3Float3();
-        checkCospiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCospi.rs
deleted file mode 100644
index a0cc778..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCospi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testCospiFloatFloat(float in) {
-    return cospi(in);
-}
-
-float2 __attribute__((kernel)) testCospiFloat2Float2(float2 in) {
-    return cospi(in);
-}
-
-float3 __attribute__((kernel)) testCospiFloat3Float3(float3 in) {
-    return cospi(in);
-}
-
-float4 __attribute__((kernel)) testCospiFloat4Float4(float4 in) {
-    return cospi(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCospiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCospiRelaxed.rs
deleted file mode 100644
index aac7b90..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCospiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestCospi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCross.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCross.java
deleted file mode 100644
index c5dc979..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCross.java
+++ /dev/null
@@ -1,213 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestCross extends RSBaseCompute {
-
-    private ScriptC_TestCross script;
-    private ScriptC_TestCrossRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestCross(mRS);
-        scriptRelaxed = new ScriptC_TestCrossRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatNFloatNFloatN {
-        public float[] inLhs;
-        public float[] inRhs;
-        public Target.Floaty[] out;
-    }
-
-    private void checkCrossFloat3Float3Float3() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdec3726a2995edb5l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdec3726a2996190bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testCrossFloat3Float3Float3(inLhs, out);
-            verifyResultsCrossFloat3Float3Float3(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testCrossFloat3Float3Float3(inLhs, out);
-            verifyResultsCrossFloat3Float3Float3(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCrossFloat3Float3Float3(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloatN args = new ArgumentsFloatNFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[3];
-            args.inRhs = new float[3];
-            args.out = new Target.Floaty[3];
-            // Fill args with the input values
-            for (int j = 0; j < 3 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 3 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(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(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkCrossFloat3Float3Float3" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkCrossFloat4Float4Float4() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6b4bc797a60fb18el, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6b4bc797a60fdce4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testCrossFloat4Float4Float4(inLhs, out);
-            verifyResultsCrossFloat4Float4Float4(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testCrossFloat4Float4Float4(inLhs, out);
-            verifyResultsCrossFloat4Float4Float4(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsCrossFloat4Float4Float4(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloatN args = new ArgumentsFloatNFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[4];
-            args.inRhs = new float[4];
-            args.out = new Target.Floaty[4];
-            // Fill args with the input values
-            for (int j = 0; j < 4 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 4 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(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(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkCrossFloat4Float4Float4" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testCross() {
-        checkCrossFloat3Float3Float3();
-        checkCrossFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCross.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCross.rs
deleted file mode 100644
index 16d5d35..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCross.rs
+++ /dev/null
@@ -1,32 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInRhs;
-
-float3 __attribute__((kernel)) testCrossFloat3Float3Float3(float3 inLhs, unsigned int x) {
-    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
-    return cross(inLhs, inRhs);
-}
-
-float4 __attribute__((kernel)) testCrossFloat4Float4Float4(float4 inLhs, unsigned int x) {
-    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
-    return cross(inLhs, inRhs);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCrossRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCrossRelaxed.rs
deleted file mode 100644
index 59fa62d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestCrossRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestCross.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCtxDim.java b/tests/tests/renderscript/src/android/renderscript/cts/TestCtxDim.java
new file mode 100644
index 0000000..4a2af00
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestCtxDim.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.renderscript.cts;
+
+import android.renderscript.*;
+
+public class TestCtxDim extends RSBaseCompute {
+
+    public void test() {
+        ScriptC_TestCtxDim script = new ScriptC_TestCtxDim(mRS);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        int X = 2;
+        script.set_gDimX(X);
+        typeBuilder.setX(X);
+        int Y = 5;
+        script.set_gDimY(Y);
+        typeBuilder.setY(Y);
+        int Z = 11;
+        script.set_gDimZ(Z);
+        typeBuilder.setZ(Z);
+
+        Allocation A = Allocation.createTyped(mRS, typeBuilder.create());
+
+        script.forEach_check_kernel(A);
+        script.invoke_check_result();
+        mRS.finish();
+        waitForMessage();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestCtxDim.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestCtxDim.rs
new file mode 100644
index 0000000..3530f1c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TestCtxDim.rs
@@ -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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+#include "shared.rsh"
+
+int gDimX, gDimY, gDimZ;
+static bool failed = false;
+
+void __attribute__((kernel)) check_kernel(int32_t in /* dummy */, rs_kernel_context context) {
+    uint32_t dimX = rsGetDimX(context);
+    _RS_ASSERT(gDimX == dimX);
+    uint32_t dimY = rsGetDimY(context);
+    _RS_ASSERT(gDimY == dimY);
+    uint32_t dimZ = rsGetDimZ(context);
+    _RS_ASSERT(gDimZ == dimZ);
+}
+
+void check_result() {
+    if (failed) {
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDegrees.java b/tests/tests/renderscript/src/android/renderscript/cts/TestDegrees.java
deleted file mode 100644
index b956dbd..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestDegrees.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestDegrees extends RSBaseCompute {
-
-    private ScriptC_TestDegrees script;
-    private ScriptC_TestDegreesRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestDegrees(mRS);
-        scriptRelaxed = new ScriptC_TestDegreesRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inValue;
-        public Target.Floaty out;
-    }
-
-    private void checkDegreesFloatFloat() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3325fa58542a6bb5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testDegreesFloatFloat(inValue, out);
-            verifyResultsDegreesFloatFloat(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testDegreesFloatFloat(inValue, out);
-            verifyResultsDegreesFloatFloat(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDegreesFloatFloat(Allocation inValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeDegrees(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkDegreesFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkDegreesFloat2Float2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7a202f393d2a289l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testDegreesFloat2Float2(inValue, out);
-            verifyResultsDegreesFloat2Float2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testDegreesFloat2Float2(inValue, out);
-            verifyResultsDegreesFloat2Float2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDegreesFloat2Float2(Allocation inValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeDegrees(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkDegreesFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkDegreesFloat3Float3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2d56787add10c807l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testDegreesFloat3Float3(inValue, out);
-            verifyResultsDegreesFloat3Float3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testDegreesFloat3Float3(inValue, out);
-            verifyResultsDegreesFloat3Float3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDegreesFloat3Float3(Allocation inValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeDegrees(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkDegreesFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkDegreesFloat4Float4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x530aee02264eed85l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testDegreesFloat4Float4(inValue, out);
-            verifyResultsDegreesFloat4Float4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testDegreesFloat4Float4(inValue, out);
-            verifyResultsDegreesFloat4Float4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDegreesFloat4Float4(Allocation inValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeDegrees(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkDegreesFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testDegrees() {
-        checkDegreesFloatFloat();
-        checkDegreesFloat2Float2();
-        checkDegreesFloat3Float3();
-        checkDegreesFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDegrees.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestDegrees.rs
deleted file mode 100644
index 78741a8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestDegrees.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testDegreesFloatFloat(float inValue) {
-    return degrees(inValue);
-}
-
-float2 __attribute__((kernel)) testDegreesFloat2Float2(float2 inValue) {
-    return degrees(inValue);
-}
-
-float3 __attribute__((kernel)) testDegreesFloat3Float3(float3 inValue) {
-    return degrees(inValue);
-}
-
-float4 __attribute__((kernel)) testDegreesFloat4Float4(float4 inValue) {
-    return degrees(inValue);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDegreesRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestDegreesRelaxed.rs
deleted file mode 100644
index 7a443bf..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestDegreesRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestDegrees.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/TestDistance.java
deleted file mode 100644
index 091c12c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestDistance.java
+++ /dev/null
@@ -1,357 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestDistance extends RSBaseCompute {
-
-    private ScriptC_TestDistance script;
-    private ScriptC_TestDistanceRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestDistance(mRS);
-        scriptRelaxed = new ScriptC_TestDistanceRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inLhs;
-        public float inRhs;
-        public Target.Floaty out;
-    }
-
-    private void checkDistanceFloatFloatFloat() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf62f685ebafc5b67l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf62f685ebafc86bdl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testDistanceFloatFloatFloat(inLhs, out);
-            verifyResultsDistanceFloatFloatFloat(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testDistanceFloatFloatFloat(inLhs, out);
-            verifyResultsDistanceFloatFloatFloat(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDistanceFloatFloatFloat(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 1];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 1];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inLhs = arrayInLhs[i];
-            args.inRhs = arrayInRhs[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inLhs: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInLhs[i], Float.floatToRawIntBits(arrayInLhs[i]), arrayInLhs[i]));
-                message.append("\n");
-                message.append("Input inRhs: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInRhs[i], Float.floatToRawIntBits(arrayInRhs[i]), arrayInRhs[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkDistanceFloatFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloatNFloat {
-        public float[] inLhs;
-        public float[] inRhs;
-        public Target.Floaty out;
-    }
-
-    private void checkDistanceFloat2Float2Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3fdeb51f89981593l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3fdeb51f899840e9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testDistanceFloat2Float2Float(inLhs, out);
-            verifyResultsDistanceFloat2Float2Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat2Float2Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testDistanceFloat2Float2Float(inLhs, out);
-            verifyResultsDistanceFloat2Float2Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat2Float2Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDistanceFloat2Float2Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 2];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 2];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[2];
-            args.inRhs = new float[2];
-            // Fill args with the input values
-            for (int j = 0; j < 2 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 2 + j];
-            }
-            for (int j = 0; j < 2 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 2 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 2 + j], Float.floatToRawIntBits(arrayInLhs[i * 2 + j]), arrayInLhs[i * 2 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 2 + j], Float.floatToRawIntBits(arrayInRhs[i * 2 + j]), arrayInRhs[i * 2 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkDistanceFloat2Float2Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkDistanceFloat3Float3Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6cd0047fd9ae30edl, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6cd0047fd9ae5c43l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testDistanceFloat3Float3Float(inLhs, out);
-            verifyResultsDistanceFloat3Float3Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat3Float3Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testDistanceFloat3Float3Float(inLhs, out);
-            verifyResultsDistanceFloat3Float3Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat3Float3Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDistanceFloat3Float3Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[3];
-            args.inRhs = new float[3];
-            // Fill args with the input values
-            for (int j = 0; j < 3 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 3 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkDistanceFloat3Float3Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkDistanceFloat4Float4Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x99c153e029c44c47l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x99c153e029c4779dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testDistanceFloat4Float4Float(inLhs, out);
-            verifyResultsDistanceFloat4Float4Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat4Float4Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testDistanceFloat4Float4Float(inLhs, out);
-            verifyResultsDistanceFloat4Float4Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat4Float4Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDistanceFloat4Float4Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[4];
-            args.inRhs = new float[4];
-            // Fill args with the input values
-            for (int j = 0; j < 4 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 4 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkDistanceFloat4Float4Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testDistance() {
-        checkDistanceFloatFloatFloat();
-        checkDistanceFloat2Float2Float();
-        checkDistanceFloat3Float3Float();
-        checkDistanceFloat4Float4Float();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDistance.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestDistance.rs
deleted file mode 100644
index fdc1783..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestDistance.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInRhs;
-
-float __attribute__((kernel)) testDistanceFloatFloatFloat(float inLhs, unsigned int x) {
-    float inRhs = rsGetElementAt_float(gAllocInRhs, x);
-    return distance(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testDistanceFloat2Float2Float(float2 inLhs, unsigned int x) {
-    float2 inRhs = rsGetElementAt_float2(gAllocInRhs, x);
-    return distance(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testDistanceFloat3Float3Float(float3 inLhs, unsigned int x) {
-    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
-    return distance(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testDistanceFloat4Float4Float(float4 inLhs, unsigned int x) {
-    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
-    return distance(inLhs, inRhs);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDistanceRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestDistanceRelaxed.rs
deleted file mode 100644
index ba4c096..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestDistanceRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestDistance.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDot.java b/tests/tests/renderscript/src/android/renderscript/cts/TestDot.java
deleted file mode 100644
index 666906b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestDot.java
+++ /dev/null
@@ -1,357 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestDot extends RSBaseCompute {
-
-    private ScriptC_TestDot script;
-    private ScriptC_TestDotRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestDot(mRS);
-        scriptRelaxed = new ScriptC_TestDotRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inLhs;
-        public float inRhs;
-        public Target.Floaty out;
-    }
-
-    private void checkDotFloatFloatFloat() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x93a0502d7b6ecc43l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x93a0502d7b6ef799l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testDotFloatFloatFloat(inLhs, out);
-            verifyResultsDotFloatFloatFloat(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testDotFloatFloatFloat(inLhs, out);
-            verifyResultsDotFloatFloatFloat(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDotFloatFloatFloat(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 1];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 1];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inLhs = arrayInLhs[i];
-            args.inRhs = arrayInRhs[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeDot(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inLhs: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInLhs[i], Float.floatToRawIntBits(arrayInLhs[i]), arrayInLhs[i]));
-                message.append("\n");
-                message.append("Input inRhs: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInRhs[i], Float.floatToRawIntBits(arrayInRhs[i]), arrayInRhs[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkDotFloatFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloatNFloat {
-        public float[] inLhs;
-        public float[] inRhs;
-        public Target.Floaty out;
-    }
-
-    private void checkDotFloat2Float2Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6458f96b84293a8fl, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6458f96b842965e5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testDotFloat2Float2Float(inLhs, out);
-            verifyResultsDotFloat2Float2Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat2Float2Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testDotFloat2Float2Float(inLhs, out);
-            verifyResultsDotFloat2Float2Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat2Float2Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDotFloat2Float2Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 2];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 2];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[2];
-            args.inRhs = new float[2];
-            // Fill args with the input values
-            for (int j = 0; j < 2 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 2 + j];
-            }
-            for (int j = 0; j < 2 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 2 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeDot(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 2 + j], Float.floatToRawIntBits(arrayInLhs[i * 2 + j]), arrayInLhs[i * 2 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 2 + j], Float.floatToRawIntBits(arrayInRhs[i * 2 + j]), arrayInRhs[i * 2 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkDotFloat2Float2Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkDotFloat3Float3Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x914a48cbd43f55e9l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x914a48cbd43f813fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testDotFloat3Float3Float(inLhs, out);
-            verifyResultsDotFloat3Float3Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat3Float3Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testDotFloat3Float3Float(inLhs, out);
-            verifyResultsDotFloat3Float3Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat3Float3Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDotFloat3Float3Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[3];
-            args.inRhs = new float[3];
-            // Fill args with the input values
-            for (int j = 0; j < 3 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 3 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeDot(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkDotFloat3Float3Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkDotFloat4Float4Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbe3b982c24557143l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbe3b982c24559c99l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testDotFloat4Float4Float(inLhs, out);
-            verifyResultsDotFloat4Float4Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat4Float4Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testDotFloat4Float4Float(inLhs, out);
-            verifyResultsDotFloat4Float4Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat4Float4Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsDotFloat4Float4Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[4];
-            args.inRhs = new float[4];
-            // Fill args with the input values
-            for (int j = 0; j < 4 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 4 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeDot(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkDotFloat4Float4Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testDot() {
-        checkDotFloatFloatFloat();
-        checkDotFloat2Float2Float();
-        checkDotFloat3Float3Float();
-        checkDotFloat4Float4Float();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDot.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestDot.rs
deleted file mode 100644
index 27aa8aa..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestDot.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInRhs;
-
-float __attribute__((kernel)) testDotFloatFloatFloat(float inLhs, unsigned int x) {
-    float inRhs = rsGetElementAt_float(gAllocInRhs, x);
-    return dot(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testDotFloat2Float2Float(float2 inLhs, unsigned int x) {
-    float2 inRhs = rsGetElementAt_float2(gAllocInRhs, x);
-    return dot(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testDotFloat3Float3Float(float3 inLhs, unsigned int x) {
-    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
-    return dot(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testDotFloat4Float4Float(float4 inLhs, unsigned int x) {
-    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
-    return dot(inLhs, inRhs);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestDotRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestDotRelaxed.rs
deleted file mode 100644
index 53e7080..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestDotRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestDot.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestErf.java b/tests/tests/renderscript/src/android/renderscript/cts/TestErf.java
deleted file mode 100644
index 6c73bf1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestErf.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestErf extends RSBaseCompute {
-
-    private ScriptC_TestErf script;
-    private ScriptC_TestErfRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestErf(mRS);
-        scriptRelaxed = new ScriptC_TestErfRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkErfFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x287cee12fdd9cb26l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testErfFloatFloat(in, out);
-            verifyResultsErfFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testErfFloatFloat(in, out);
-            verifyResultsErfFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsErfFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeErf(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkErfFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkErfFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6e52a9272b44c092l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testErfFloat2Float2(in, out);
-            verifyResultsErfFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testErfFloat2Float2(in, out);
-            verifyResultsErfFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsErfFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeErf(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkErfFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkErfFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6e52b3c88a4b562cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testErfFloat3Float3(in, out);
-            verifyResultsErfFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testErfFloat3Float3(in, out);
-            verifyResultsErfFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsErfFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeErf(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkErfFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkErfFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6e52be69e951ebc6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testErfFloat4Float4(in, out);
-            verifyResultsErfFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testErfFloat4Float4(in, out);
-            verifyResultsErfFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsErfFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeErf(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkErfFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testErf() {
-        checkErfFloatFloat();
-        checkErfFloat2Float2();
-        checkErfFloat3Float3();
-        checkErfFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestErf.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestErf.rs
deleted file mode 100644
index 5d26ed6..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestErf.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testErfFloatFloat(float in) {
-    return erf(in);
-}
-
-float2 __attribute__((kernel)) testErfFloat2Float2(float2 in) {
-    return erf(in);
-}
-
-float3 __attribute__((kernel)) testErfFloat3Float3(float3 in) {
-    return erf(in);
-}
-
-float4 __attribute__((kernel)) testErfFloat4Float4(float4 in) {
-    return erf(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestErfRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestErfRelaxed.rs
deleted file mode 100644
index 1551db8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestErfRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestErf.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestErfc.java b/tests/tests/renderscript/src/android/renderscript/cts/TestErfc.java
deleted file mode 100644
index 86c2aa1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestErfc.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestErfc extends RSBaseCompute {
-
-    private ScriptC_TestErfc script;
-    private ScriptC_TestErfcRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestErfc(mRS);
-        scriptRelaxed = new ScriptC_TestErfcRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkErfcFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb41907c64db86b2bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testErfcFloatFloat(in, out);
-            verifyResultsErfcFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testErfcFloatFloat(in, out);
-            verifyResultsErfcFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsErfcFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeErfc(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkErfcFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkErfcFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc8c849430a3684afl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testErfcFloat2Float2(in, out);
-            verifyResultsErfcFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testErfcFloat2Float2(in, out);
-            verifyResultsErfcFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsErfcFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeErfc(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkErfcFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkErfcFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc8c853e4693d1a49l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testErfcFloat3Float3(in, out);
-            verifyResultsErfcFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testErfcFloat3Float3(in, out);
-            verifyResultsErfcFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsErfcFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeErfc(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkErfcFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkErfcFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc8c85e85c843afe3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testErfcFloat4Float4(in, out);
-            verifyResultsErfcFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testErfcFloat4Float4(in, out);
-            verifyResultsErfcFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsErfcFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeErfc(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkErfcFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testErfc() {
-        checkErfcFloatFloat();
-        checkErfcFloat2Float2();
-        checkErfcFloat3Float3();
-        checkErfcFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestErfc.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestErfc.rs
deleted file mode 100644
index d12ea25..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestErfc.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testErfcFloatFloat(float in) {
-    return erfc(in);
-}
-
-float2 __attribute__((kernel)) testErfcFloat2Float2(float2 in) {
-    return erfc(in);
-}
-
-float3 __attribute__((kernel)) testErfcFloat3Float3(float3 in) {
-    return erfc(in);
-}
-
-float4 __attribute__((kernel)) testErfcFloat4Float4(float4 in) {
-    return erfc(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestErfcRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestErfcRelaxed.rs
deleted file mode 100644
index f6117c8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestErfcRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestErfc.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestExp.java
deleted file mode 100644
index 224a64c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExp.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestExp extends RSBaseCompute {
-
-    private ScriptC_TestExp script;
-    private ScriptC_TestExpRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestExp(mRS);
-        scriptRelaxed = new ScriptC_TestExpRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkExpFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb43af2b5f55920f2l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testExpFloatFloat(in, out);
-            verifyResultsExpFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testExpFloatFloat(in, out);
-            verifyResultsExpFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExpFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExpFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExpFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbdc22634c1f76efel, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testExpFloat2Float2(in, out);
-            verifyResultsExpFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testExpFloat2Float2(in, out);
-            verifyResultsExpFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExpFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExpFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExpFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbdc230d620fe0498l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testExpFloat3Float3(in, out);
-            verifyResultsExpFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testExpFloat3Float3(in, out);
-            verifyResultsExpFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExpFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExpFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExpFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbdc23b7780049a32l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testExpFloat4Float4(in, out);
-            verifyResultsExpFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testExpFloat4Float4(in, out);
-            verifyResultsExpFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExpFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExpFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testExp() {
-        checkExpFloatFloat();
-        checkExpFloat2Float2();
-        checkExpFloat3Float3();
-        checkExpFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestExp.rs
deleted file mode 100644
index 90879d9..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExp.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testExpFloatFloat(float in) {
-    return exp(in);
-}
-
-float2 __attribute__((kernel)) testExpFloat2Float2(float2 in) {
-    return exp(in);
-}
-
-float3 __attribute__((kernel)) testExpFloat3Float3(float3 in) {
-    return exp(in);
-}
-
-float4 __attribute__((kernel)) testExpFloat4Float4(float4 in) {
-    return exp(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp10.java b/tests/tests/renderscript/src/android/renderscript/cts/TestExp10.java
deleted file mode 100644
index 874d17b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExp10.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestExp10 extends RSBaseCompute {
-
-    private ScriptC_TestExp10 script;
-    private ScriptC_TestExp10Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestExp10(mRS);
-        scriptRelaxed = new ScriptC_TestExp10Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkExp10FloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9f6474a4cee90545l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testExp10FloatFloat(in, out);
-            verifyResultsExp10FloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testExp10FloatFloat(in, out);
-            verifyResultsExp10FloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExp10FloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExp10FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExp10Float2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3c8d9c56223f8a79l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testExp10Float2Float2(in, out);
-            verifyResultsExp10Float2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testExp10Float2Float2(in, out);
-            verifyResultsExp10Float2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExp10Float2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExp10Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExp10Float3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3c8da6f781462013l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testExp10Float3Float3(in, out);
-            verifyResultsExp10Float3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testExp10Float3Float3(in, out);
-            verifyResultsExp10Float3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExp10Float3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExp10Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExp10Float4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3c8db198e04cb5adl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testExp10Float4Float4(in, out);
-            verifyResultsExp10Float4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testExp10Float4Float4(in, out);
-            verifyResultsExp10Float4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExp10Float4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExp10Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testExp10() {
-        checkExp10FloatFloat();
-        checkExp10Float2Float2();
-        checkExp10Float3Float3();
-        checkExp10Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp10.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestExp10.rs
deleted file mode 100644
index 117fe26..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExp10.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testExp10FloatFloat(float in) {
-    return exp10(in);
-}
-
-float2 __attribute__((kernel)) testExp10Float2Float2(float2 in) {
-    return exp10(in);
-}
-
-float3 __attribute__((kernel)) testExp10Float3Float3(float3 in) {
-    return exp10(in);
-}
-
-float4 __attribute__((kernel)) testExp10Float4Float4(float4 in) {
-    return exp10(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp10Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestExp10Relaxed.rs
deleted file mode 100644
index 9b07598..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExp10Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestExp10.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestExp2.java
deleted file mode 100644
index bbb9c68..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExp2.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestExp2 extends RSBaseCompute {
-
-    private ScriptC_TestExp2 script;
-    private ScriptC_TestExp2Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestExp2(mRS);
-        scriptRelaxed = new ScriptC_TestExp2Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkExp2FloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x80096e5b0f2662el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testExp2FloatFloat(in, out);
-            verifyResultsExp2FloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testExp2FloatFloat(in, out);
-            verifyResultsExp2FloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExp2FloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExp2FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExp2Float2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xcc4102f6b7fc7d5al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testExp2Float2Float2(in, out);
-            verifyResultsExp2Float2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testExp2Float2Float2(in, out);
-            verifyResultsExp2Float2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExp2Float2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExp2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExp2Float3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcc410d98170312f4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testExp2Float3Float3(in, out);
-            verifyResultsExp2Float3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testExp2Float3Float3(in, out);
-            verifyResultsExp2Float3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExp2Float3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExp2Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExp2Float4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xcc4118397609a88el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testExp2Float4Float4(in, out);
-            verifyResultsExp2Float4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testExp2Float4Float4(in, out);
-            verifyResultsExp2Float4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExp2Float4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExp2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExp2Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testExp2() {
-        checkExp2FloatFloat();
-        checkExp2Float2Float2();
-        checkExp2Float3Float3();
-        checkExp2Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp2.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestExp2.rs
deleted file mode 100644
index 61ff900..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExp2.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testExp2FloatFloat(float in) {
-    return exp2(in);
-}
-
-float2 __attribute__((kernel)) testExp2Float2Float2(float2 in) {
-    return exp2(in);
-}
-
-float3 __attribute__((kernel)) testExp2Float3Float3(float3 in) {
-    return exp2(in);
-}
-
-float4 __attribute__((kernel)) testExp2Float4Float4(float4 in) {
-    return exp2(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExp2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestExp2Relaxed.rs
deleted file mode 100644
index 06810b3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExp2Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestExp2.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestExpRelaxed.rs
deleted file mode 100644
index f98bf80..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExpRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestExp.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1.java b/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1.java
deleted file mode 100644
index c922e49..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestExpm1 extends RSBaseCompute {
-
-    private ScriptC_TestExpm1 script;
-    private ScriptC_TestExpm1Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestExpm1(mRS);
-        scriptRelaxed = new ScriptC_TestExpm1Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkExpm1FloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa03d120368f727aal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testExpm1FloatFloat(in, out);
-            verifyResultsExpm1FloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testExpm1FloatFloat(in, out);
-            verifyResultsExpm1FloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExpm1FloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExpm1(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExpm1FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExpm1Float2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x59163c9cd255f5f6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testExpm1Float2Float2(in, out);
-            verifyResultsExpm1Float2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testExpm1Float2Float2(in, out);
-            verifyResultsExpm1Float2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExpm1Float2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExpm1(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExpm1Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExpm1Float3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5916473e315c8b90l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testExpm1Float3Float3(in, out);
-            verifyResultsExpm1Float3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testExpm1Float3Float3(in, out);
-            verifyResultsExpm1Float3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExpm1Float3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExpm1(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExpm1Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkExpm1Float4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x591651df9063212al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testExpm1Float4Float4(in, out);
-            verifyResultsExpm1Float4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testExpm1Float4Float4(in, out);
-            verifyResultsExpm1Float4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsExpm1Float4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeExpm1(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkExpm1Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testExpm1() {
-        checkExpm1FloatFloat();
-        checkExpm1Float2Float2();
-        checkExpm1Float3Float3();
-        checkExpm1Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1.rs
deleted file mode 100644
index 9399576..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testExpm1FloatFloat(float in) {
-    return expm1(in);
-}
-
-float2 __attribute__((kernel)) testExpm1Float2Float2(float2 in) {
-    return expm1(in);
-}
-
-float3 __attribute__((kernel)) testExpm1Float3Float3(float3 in) {
-    return expm1(in);
-}
-
-float4 __attribute__((kernel)) testExpm1Float4Float4(float4 in) {
-    return expm1(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1Relaxed.rs
deleted file mode 100644
index bd73f9d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestExpm1Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestExpm1.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFabs.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFabs.java
deleted file mode 100644
index 29cdd86..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFabs.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFabs extends RSBaseCompute {
-
-    private ScriptC_TestFabs script;
-    private ScriptC_TestFabsRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFabs(mRS);
-        scriptRelaxed = new ScriptC_TestFabsRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkFabsFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x70316affaf9e3339l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testFabsFloatFloat(in, out);
-            verifyResultsFabsFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testFabsFloatFloat(in, out);
-            verifyResultsFabsFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFabsFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFabs(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFabsFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFabsFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x54ecf2b71ed871cdl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testFabsFloat2Float2(in, out);
-            verifyResultsFabsFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testFabsFloat2Float2(in, out);
-            verifyResultsFabsFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFabsFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFabs(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFabsFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFabsFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x54ecfd587ddf0767l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testFabsFloat3Float3(in, out);
-            verifyResultsFabsFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testFabsFloat3Float3(in, out);
-            verifyResultsFabsFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFabsFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFabs(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFabsFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFabsFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x54ed07f9dce59d01l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testFabsFloat4Float4(in, out);
-            verifyResultsFabsFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testFabsFloat4Float4(in, out);
-            verifyResultsFabsFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFabsFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFabs(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFabsFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testFabs() {
-        checkFabsFloatFloat();
-        checkFabsFloat2Float2();
-        checkFabsFloat3Float3();
-        checkFabsFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFabs.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFabs.rs
deleted file mode 100644
index aed0318..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFabs.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testFabsFloatFloat(float in) {
-    return fabs(in);
-}
-
-float2 __attribute__((kernel)) testFabsFloat2Float2(float2 in) {
-    return fabs(in);
-}
-
-float3 __attribute__((kernel)) testFabsFloat3Float3(float3 in) {
-    return fabs(in);
-}
-
-float4 __attribute__((kernel)) testFabsFloat4Float4(float4 in) {
-    return fabs(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFabsRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFabsRelaxed.rs
deleted file mode 100644
index 4d2214a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFabsRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFabs.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistance.java
deleted file mode 100644
index 8091015..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistance.java
+++ /dev/null
@@ -1,357 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFastDistance extends RSBaseCompute {
-
-    private ScriptC_TestFastDistance script;
-    private ScriptC_TestFastDistanceRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFastDistance(mRS);
-        scriptRelaxed = new ScriptC_TestFastDistanceRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inLhs;
-        public float inRhs;
-        public Target.Floaty out;
-    }
-
-    private void checkFastDistanceFloatFloatFloat() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe7e5e843bff0cb7l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe7e5e843bff380dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testFastDistanceFloatFloatFloat(inLhs, out);
-            verifyResultsFastDistanceFloatFloatFloat(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testFastDistanceFloatFloatFloat(inLhs, out);
-            verifyResultsFastDistanceFloatFloatFloat(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastDistanceFloatFloatFloat(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 1];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 1];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inLhs = arrayInLhs[i];
-            args.inRhs = arrayInRhs[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inLhs: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInLhs[i], Float.floatToRawIntBits(arrayInLhs[i]), arrayInLhs[i]));
-                message.append("\n");
-                message.append("Input inRhs: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInRhs[i], Float.floatToRawIntBits(arrayInRhs[i]), arrayInRhs[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkFastDistanceFloatFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloatNFloat {
-        public float[] inLhs;
-        public float[] inRhs;
-        public Target.Floaty out;
-    }
-
-    private void checkFastDistanceFloat2Float2Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x422e8a00560ac063l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x422e8a00560aebb9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testFastDistanceFloat2Float2Float(inLhs, out);
-            verifyResultsFastDistanceFloat2Float2Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat2Float2Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testFastDistanceFloat2Float2Float(inLhs, out);
-            verifyResultsFastDistanceFloat2Float2Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat2Float2Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastDistanceFloat2Float2Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 2];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 2];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[2];
-            args.inRhs = new float[2];
-            // Fill args with the input values
-            for (int j = 0; j < 2 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 2 + j];
-            }
-            for (int j = 0; j < 2 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 2 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 2 + j], Float.floatToRawIntBits(arrayInLhs[i * 2 + j]), arrayInLhs[i * 2 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 2 + j], Float.floatToRawIntBits(arrayInRhs[i * 2 + j]), arrayInRhs[i * 2 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkFastDistanceFloat2Float2Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkFastDistanceFloat3Float3Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6f1fd960a620dbbdl, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6f1fd960a6210713l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testFastDistanceFloat3Float3Float(inLhs, out);
-            verifyResultsFastDistanceFloat3Float3Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat3Float3Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testFastDistanceFloat3Float3Float(inLhs, out);
-            verifyResultsFastDistanceFloat3Float3Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat3Float3Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastDistanceFloat3Float3Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[3];
-            args.inRhs = new float[3];
-            // Fill args with the input values
-            for (int j = 0; j < 3 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 3 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkFastDistanceFloat3Float3Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkFastDistanceFloat4Float4Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9c1128c0f636f717l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9c1128c0f637226dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testFastDistanceFloat4Float4Float(inLhs, out);
-            verifyResultsFastDistanceFloat4Float4Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat4Float4Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testFastDistanceFloat4Float4Float(inLhs, out);
-            verifyResultsFastDistanceFloat4Float4Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat4Float4Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastDistanceFloat4Float4Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[4];
-            args.inRhs = new float[4];
-            // Fill args with the input values
-            for (int j = 0; j < 4 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 4 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkFastDistanceFloat4Float4Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testFastDistance() {
-        checkFastDistanceFloatFloatFloat();
-        checkFastDistanceFloat2Float2Float();
-        checkFastDistanceFloat3Float3Float();
-        checkFastDistanceFloat4Float4Float();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistance.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistance.rs
deleted file mode 100644
index 62c0931..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistance.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInRhs;
-
-float __attribute__((kernel)) testFastDistanceFloatFloatFloat(float inLhs, unsigned int x) {
-    float inRhs = rsGetElementAt_float(gAllocInRhs, x);
-    return fast_distance(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testFastDistanceFloat2Float2Float(float2 inLhs, unsigned int x) {
-    float2 inRhs = rsGetElementAt_float2(gAllocInRhs, x);
-    return fast_distance(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testFastDistanceFloat3Float3Float(float3 inLhs, unsigned int x) {
-    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
-    return fast_distance(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testFastDistanceFloat4Float4Float(float4 inLhs, unsigned int x) {
-    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
-    return fast_distance(inLhs, inRhs);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistanceRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistanceRelaxed.rs
deleted file mode 100644
index 245bc65..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFastDistanceRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFastDistance.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastLength.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFastLength.java
deleted file mode 100644
index e990d15..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFastLength.java
+++ /dev/null
@@ -1,300 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFastLength extends RSBaseCompute {
-
-    private ScriptC_TestFastLength script;
-    private ScriptC_TestFastLengthRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFastLength(mRS);
-        scriptRelaxed = new ScriptC_TestFastLengthRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkFastLengthFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xebac65aea2660e8fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testFastLengthFloatFloat(inV, out);
-            verifyResultsFastLengthFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testFastLengthFloatFloat(inV, out);
-            verifyResultsFastLengthFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastLengthFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inV: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkFastLengthFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloat {
-        public float[] inV;
-        public Target.Floaty out;
-    }
-
-    private void checkFastLengthFloat2Float() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x95f43650f85e6cadl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testFastLengthFloat2Float(inV, out);
-            verifyResultsFastLengthFloat2Float(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat2Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testFastLengthFloat2Float(inV, out);
-            verifyResultsFastLengthFloat2Float(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat2Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastLengthFloat2Float(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[2];
-            // Fill args with the input values
-            for (int j = 0; j < 2 ; j++) {
-                args.inV[j] = arrayInV[i * 2 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkFastLengthFloat2Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkFastLengthFloat3Float() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x95f440f25764fb0el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testFastLengthFloat3Float(inV, out);
-            verifyResultsFastLengthFloat3Float(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat3Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testFastLengthFloat3Float(inV, out);
-            verifyResultsFastLengthFloat3Float(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat3Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastLengthFloat3Float(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[3];
-            // Fill args with the input values
-            for (int j = 0; j < 3 ; j++) {
-                args.inV[j] = arrayInV[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkFastLengthFloat3Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkFastLengthFloat4Float() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x95f44b93b66b896fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testFastLengthFloat4Float(inV, out);
-            verifyResultsFastLengthFloat4Float(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat4Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testFastLengthFloat4Float(inV, out);
-            verifyResultsFastLengthFloat4Float(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat4Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastLengthFloat4Float(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[4];
-            // Fill args with the input values
-            for (int j = 0; j < 4 ; j++) {
-                args.inV[j] = arrayInV[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkFastLengthFloat4Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testFastLength() {
-        checkFastLengthFloatFloat();
-        checkFastLengthFloat2Float();
-        checkFastLengthFloat3Float();
-        checkFastLengthFloat4Float();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastLength.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFastLength.rs
deleted file mode 100644
index f4fc853..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFastLength.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testFastLengthFloatFloat(float inV) {
-    return fast_length(inV);
-}
-
-float __attribute__((kernel)) testFastLengthFloat2Float(float2 inV) {
-    return fast_length(inV);
-}
-
-float __attribute__((kernel)) testFastLengthFloat3Float(float3 inV) {
-    return fast_length(inV);
-}
-
-float __attribute__((kernel)) testFastLengthFloat4Float(float4 inV) {
-    return fast_length(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastLengthRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFastLengthRelaxed.rs
deleted file mode 100644
index 680c3e1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFastLengthRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFastLength.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalize.java
deleted file mode 100644
index 4e42575..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalize.java
+++ /dev/null
@@ -1,315 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFastNormalize extends RSBaseCompute {
-
-    private ScriptC_TestFastNormalize script;
-    private ScriptC_TestFastNormalizeRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFastNormalize(mRS);
-        scriptRelaxed = new ScriptC_TestFastNormalizeRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkFastNormalizeFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdcfb9adc9f8882ecl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testFastNormalizeFloatFloat(inV, out);
-            verifyResultsFastNormalizeFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testFastNormalizeFloatFloat(inV, out);
-            verifyResultsFastNormalizeFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastNormalizeFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastNormalize(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inV: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkFastNormalizeFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloatN {
-        public float[] inV;
-        public Target.Floaty[] out;
-    }
-
-    private void checkFastNormalizeFloat2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x151c38c30573db70l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testFastNormalizeFloat2Float2(inV, out);
-            verifyResultsFastNormalizeFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testFastNormalizeFloat2Float2(inV, out);
-            verifyResultsFastNormalizeFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastNormalizeFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[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];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastNormalize(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(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkFastNormalizeFloat2Float2" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkFastNormalizeFloat3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x151e01ddfb8efc4el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testFastNormalizeFloat3Float3(inV, out);
-            verifyResultsFastNormalizeFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testFastNormalizeFloat3Float3(inV, out);
-            verifyResultsFastNormalizeFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastNormalizeFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[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];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastNormalize(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(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkFastNormalizeFloat3Float3" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkFastNormalizeFloat4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x151fcaf8f1aa1d2cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testFastNormalizeFloat4Float4(inV, out);
-            verifyResultsFastNormalizeFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testFastNormalizeFloat4Float4(inV, out);
-            verifyResultsFastNormalizeFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFastNormalizeFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[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];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeFastNormalize(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(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkFastNormalizeFloat4Float4" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testFastNormalize() {
-        checkFastNormalizeFloatFloat();
-        checkFastNormalizeFloat2Float2();
-        checkFastNormalizeFloat3Float3();
-        checkFastNormalizeFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalize.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalize.rs
deleted file mode 100644
index 449c49c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalize.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testFastNormalizeFloatFloat(float inV) {
-    return fast_normalize(inV);
-}
-
-float2 __attribute__((kernel)) testFastNormalizeFloat2Float2(float2 inV) {
-    return fast_normalize(inV);
-}
-
-float3 __attribute__((kernel)) testFastNormalizeFloat3Float3(float3 inV) {
-    return fast_normalize(inV);
-}
-
-float4 __attribute__((kernel)) testFastNormalizeFloat4Float4(float4 inV) {
-    return fast_normalize(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalizeRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalizeRelaxed.rs
deleted file mode 100644
index e195f60..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFastNormalizeRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFastNormalize.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFdim.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFdim.java
deleted file mode 100644
index bbe1e7a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFdim.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFdim extends RSBaseCompute {
-
-    private ScriptC_TestFdim script;
-    private ScriptC_TestFdimRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFdim(mRS);
-        scriptRelaxed = new ScriptC_TestFdimRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inA;
-        public float inB;
-        public Target.Floaty out;
-    }
-
-    private void checkFdimFloatFloatFloat() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf5dd38fbc3a47366l, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf5dd38fbc3a47367l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.forEach_testFdimFloatFloatFloat(inA, out);
-            verifyResultsFdimFloatFloatFloat(inA, inB, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.forEach_testFdimFloatFloatFloat(inA, out);
-            verifyResultsFdimFloatFloatFloat(inA, inB, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFdimFloatFloatFloat(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 1];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 1];
-        inB.copyTo(arrayInB);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inA = arrayInA[i];
-                args.inB = arrayInB[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFdim(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFdimFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFdimFloat2Float2Float2() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xca6a96c16f167f4cl, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xca6a96c16f167f4dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.forEach_testFdimFloat2Float2Float2(inA, out);
-            verifyResultsFdimFloat2Float2Float2(inA, inB, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.forEach_testFdimFloat2Float2Float2(inA, out);
-            verifyResultsFdimFloat2Float2Float2(inA, inB, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFdimFloat2Float2Float2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 2];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 2];
-        inB.copyTo(arrayInB);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                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);
-                CoreMathVerifier.computeFdim(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFdimFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFdimFloat3Float3Float3() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1ecf74e170f480edl, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1ecf74e170f480eel, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.forEach_testFdimFloat3Float3Float3(inA, out);
-            verifyResultsFdimFloat3Float3Float3(inA, inB, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.forEach_testFdimFloat3Float3Float3(inA, out);
-            verifyResultsFdimFloat3Float3Float3(inA, inB, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFdimFloat3Float3Float3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 4];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 4];
-        inB.copyTo(arrayInB);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                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);
-                CoreMathVerifier.computeFdim(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFdimFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFdimFloat4Float4Float4() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7334530172d2828el, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7334530172d2828fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.forEach_testFdimFloat4Float4Float4(inA, out);
-            verifyResultsFdimFloat4Float4Float4(inA, inB, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.forEach_testFdimFloat4Float4Float4(inA, out);
-            verifyResultsFdimFloat4Float4Float4(inA, inB, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFdimFloat4Float4Float4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 4];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 4];
-        inB.copyTo(arrayInB);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                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);
-                CoreMathVerifier.computeFdim(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFdimFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testFdim() {
-        checkFdimFloatFloatFloat();
-        checkFdimFloat2Float2Float2();
-        checkFdimFloat3Float3Float3();
-        checkFdimFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFdim.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFdim.rs
deleted file mode 100644
index 8f68c14..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFdim.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInB;
-
-float __attribute__((kernel)) testFdimFloatFloatFloat(float inA, unsigned int x) {
-    float inB = rsGetElementAt_float(gAllocInB, x);
-    return fdim(inA, inB);
-}
-
-float2 __attribute__((kernel)) testFdimFloat2Float2Float2(float2 inA, unsigned int x) {
-    float2 inB = rsGetElementAt_float2(gAllocInB, x);
-    return fdim(inA, inB);
-}
-
-float3 __attribute__((kernel)) testFdimFloat3Float3Float3(float3 inA, unsigned int x) {
-    float3 inB = rsGetElementAt_float3(gAllocInB, x);
-    return fdim(inA, inB);
-}
-
-float4 __attribute__((kernel)) testFdimFloat4Float4Float4(float4 inA, unsigned int x) {
-    float4 inB = rsGetElementAt_float4(gAllocInB, x);
-    return fdim(inA, inB);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFdimRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFdimRelaxed.rs
deleted file mode 100644
index 473a588..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFdimRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFdim.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFloor.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFloor.java
deleted file mode 100644
index 39ec8bd..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFloor.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFloor extends RSBaseCompute {
-
-    private ScriptC_TestFloor script;
-    private ScriptC_TestFloorRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFloor(mRS);
-        scriptRelaxed = new ScriptC_TestFloorRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkFloorFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9c2b15433f045885l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testFloorFloatFloat(in, out);
-            verifyResultsFloorFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testFloorFloatFloat(in, out);
-            verifyResultsFloorFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFloorFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFloor(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFloorFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFloorFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf32bb4add79bd3b9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testFloorFloat2Float2(in, out);
-            verifyResultsFloorFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testFloorFloat2Float2(in, out);
-            verifyResultsFloorFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFloorFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFloor(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFloorFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFloorFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf32bbf4f36a26953l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testFloorFloat3Float3(in, out);
-            verifyResultsFloorFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testFloorFloat3Float3(in, out);
-            verifyResultsFloorFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFloorFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFloor(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFloorFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFloorFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf32bc9f095a8feedl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testFloorFloat4Float4(in, out);
-            verifyResultsFloorFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testFloorFloat4Float4(in, out);
-            verifyResultsFloorFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFloorFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFloor(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFloorFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testFloor() {
-        checkFloorFloatFloat();
-        checkFloorFloat2Float2();
-        checkFloorFloat3Float3();
-        checkFloorFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFloor.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFloor.rs
deleted file mode 100644
index f74fc2b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFloor.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testFloorFloatFloat(float in) {
-    return floor(in);
-}
-
-float2 __attribute__((kernel)) testFloorFloat2Float2(float2 in) {
-    return floor(in);
-}
-
-float3 __attribute__((kernel)) testFloorFloat3Float3(float3 in) {
-    return floor(in);
-}
-
-float4 __attribute__((kernel)) testFloorFloat4Float4(float4 in) {
-    return floor(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFloorRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFloorRelaxed.rs
deleted file mode 100644
index 4caf0de..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFloorRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFloor.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFma.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFma.java
deleted file mode 100644
index fcb7c5f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFma.java
+++ /dev/null
@@ -1,366 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFma extends RSBaseCompute {
-
-    private ScriptC_TestFma script;
-    private ScriptC_TestFmaRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFma(mRS);
-        scriptRelaxed = new ScriptC_TestFmaRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloatFloat {
-        public float inA;
-        public float inB;
-        public float inC;
-        public Target.Floaty out;
-    }
-
-    private void checkFmaFloatFloatFloatFloat() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5f6b3ee0c3466c2l, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5f6b3ee0c3466c3l, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5f6b3ee0c3466c4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.set_gAllocInC(inC);
-            script.forEach_testFmaFloatFloatFloatFloat(inA, out);
-            verifyResultsFmaFloatFloatFloatFloat(inA, inB, inC, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloatFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.forEach_testFmaFloatFloatFloatFloat(inA, out);
-            verifyResultsFmaFloatFloatFloatFloat(inA, inB, inC, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloatFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaFloatFloatFloatFloat(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 1];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 1];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 1];
-        inC.copyTo(arrayInC);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inA = arrayInA[i];
-                args.inB = arrayInB[i];
-                args.inC = arrayInC[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaFloatFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmaFloat2Float2Float2Float2() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x47b62b8849bc43dal, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x47b62b8849bc43dbl, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x47b62b8849bc43dcl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.set_gAllocInC(inC);
-            script.forEach_testFmaFloat2Float2Float2Float2(inA, out);
-            verifyResultsFmaFloat2Float2Float2Float2(inA, inB, inC, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat2Float2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.forEach_testFmaFloat2Float2Float2Float2(inA, out);
-            verifyResultsFmaFloat2Float2Float2Float2(inA, inB, inC, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat2Float2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaFloat2Float2Float2Float2(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 2];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 2];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 2];
-        inC.copyTo(arrayInC);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inA = arrayInA[i * 2 + j];
-                args.inB = arrayInB[i * 2 + j];
-                args.inC = arrayInC[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaFloat2Float2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmaFloat3Float3Float3Float3() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1d2fcf231c237d76l, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1d2fcf231c237d77l, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1d2fcf231c237d78l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.set_gAllocInC(inC);
-            script.forEach_testFmaFloat3Float3Float3Float3(inA, out);
-            verifyResultsFmaFloat3Float3Float3Float3(inA, inB, inC, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat3Float3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.forEach_testFmaFloat3Float3Float3Float3(inA, out);
-            verifyResultsFmaFloat3Float3Float3Float3(inA, inB, inC, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat3Float3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaFloat3Float3Float3Float3(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 4];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 4];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 4];
-        inC.copyTo(arrayInC);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inA = arrayInA[i * 4 + j];
-                args.inB = arrayInB[i * 4 + j];
-                args.inC = arrayInC[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaFloat3Float3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmaFloat4Float4Float4Float4() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf2a972bdee8ab712l, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf2a972bdee8ab713l, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf2a972bdee8ab714l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.set_gAllocInC(inC);
-            script.forEach_testFmaFloat4Float4Float4Float4(inA, out);
-            verifyResultsFmaFloat4Float4Float4Float4(inA, inB, inC, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat4Float4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.forEach_testFmaFloat4Float4Float4Float4(inA, out);
-            verifyResultsFmaFloat4Float4Float4Float4(inA, inB, inC, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat4Float4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaFloat4Float4Float4Float4(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 4];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 4];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 4];
-        inC.copyTo(arrayInC);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inA = arrayInA[i * 4 + j];
-                args.inB = arrayInB[i * 4 + j];
-                args.inC = arrayInC[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaFloat4Float4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testFma() {
-        checkFmaFloatFloatFloatFloat();
-        checkFmaFloat2Float2Float2Float2();
-        checkFmaFloat3Float3Float3Float3();
-        checkFmaFloat4Float4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFma.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFma.rs
deleted file mode 100644
index b0cb2dd..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFma.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInB;
-rs_allocation gAllocInC;
-
-float __attribute__((kernel)) testFmaFloatFloatFloatFloat(float inA, unsigned int x) {
-    float inB = rsGetElementAt_float(gAllocInB, x);
-    float inC = rsGetElementAt_float(gAllocInC, x);
-    return fma(inA, inB, inC);
-}
-
-float2 __attribute__((kernel)) testFmaFloat2Float2Float2Float2(float2 inA, unsigned int x) {
-    float2 inB = rsGetElementAt_float2(gAllocInB, x);
-    float2 inC = rsGetElementAt_float2(gAllocInC, x);
-    return fma(inA, inB, inC);
-}
-
-float3 __attribute__((kernel)) testFmaFloat3Float3Float3Float3(float3 inA, unsigned int x) {
-    float3 inB = rsGetElementAt_float3(gAllocInB, x);
-    float3 inC = rsGetElementAt_float3(gAllocInC, x);
-    return fma(inA, inB, inC);
-}
-
-float4 __attribute__((kernel)) testFmaFloat4Float4Float4Float4(float4 inA, unsigned int x) {
-    float4 inB = rsGetElementAt_float4(gAllocInB, x);
-    float4 inC = rsGetElementAt_float4(gAllocInC, x);
-    return fma(inA, inB, inC);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmaRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFmaRelaxed.rs
deleted file mode 100644
index cc80e06..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFmaRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFma.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmax.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFmax.java
deleted file mode 100644
index 7d4e633..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFmax.java
+++ /dev/null
@@ -1,535 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFmax extends RSBaseCompute {
-
-    private ScriptC_TestFmax script;
-    private ScriptC_TestFmaxRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFmax(mRS);
-        scriptRelaxed = new ScriptC_TestFmaxRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkFmaxFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe6ec75a46e6fdd91l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe6ec75a46e6fdd92l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmaxFloatFloatFloat(inX, out);
-            verifyResultsFmaxFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmaxFloatFloatFloat(inX, out);
-            verifyResultsFmaxFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaxFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaxFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmaxFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa99eaa6dd458a0dfl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa99eaa6dd458a0e0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmaxFloat2Float2Float2(inX, out);
-            verifyResultsFmaxFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmaxFloat2Float2Float2(inX, out);
-            verifyResultsFmaxFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaxFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaxFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmaxFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfe03888dd636a280l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfe03888dd636a281l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmaxFloat3Float3Float3(inX, out);
-            verifyResultsFmaxFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmaxFloat3Float3Float3(inX, out);
-            verifyResultsFmaxFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaxFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaxFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmaxFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x526866add814a421l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x526866add814a422l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmaxFloat4Float4Float4(inX, out);
-            verifyResultsFmaxFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmaxFloat4Float4Float4(inX, out);
-            verifyResultsFmaxFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaxFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaxFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmaxFloat2FloatFloat2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xce5ddc06dc631119l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xce5ddc06dc63111al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmaxFloat2FloatFloat2(inX, out);
-            verifyResultsFmaxFloat2FloatFloat2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2FloatFloat2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmaxFloat2FloatFloat2(inX, out);
-            verifyResultsFmaxFloat2FloatFloat2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2FloatFloat2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaxFloat2FloatFloat2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaxFloat2FloatFloat2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmaxFloat3FloatFloat3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x23ad8f1ecace0575l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x23ad8f1ecace0576l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmaxFloat3FloatFloat3(inX, out);
-            verifyResultsFmaxFloat3FloatFloat3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3FloatFloat3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmaxFloat3FloatFloat3(inX, out);
-            verifyResultsFmaxFloat3FloatFloat3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3FloatFloat3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaxFloat3FloatFloat3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaxFloat3FloatFloat3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmaxFloat4FloatFloat4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x78fd4236b938f9d1l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x78fd4236b938f9d2l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmaxFloat4FloatFloat4(inX, out);
-            verifyResultsFmaxFloat4FloatFloat4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4FloatFloat4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmaxFloat4FloatFloat4(inX, out);
-            verifyResultsFmaxFloat4FloatFloat4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4FloatFloat4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmaxFloat4FloatFloat4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmaxFloat4FloatFloat4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testFmax() {
-        checkFmaxFloatFloatFloat();
-        checkFmaxFloat2Float2Float2();
-        checkFmaxFloat3Float3Float3();
-        checkFmaxFloat4Float4Float4();
-        checkFmaxFloat2FloatFloat2();
-        checkFmaxFloat3FloatFloat3();
-        checkFmaxFloat4FloatFloat4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmax.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFmax.rs
deleted file mode 100644
index 50e5e3f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFmax.rs
+++ /dev/null
@@ -1,57 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testFmaxFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return fmax(inX, inY);
-}
-
-float2 __attribute__((kernel)) testFmaxFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return fmax(inX, inY);
-}
-
-float3 __attribute__((kernel)) testFmaxFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return fmax(inX, inY);
-}
-
-float4 __attribute__((kernel)) testFmaxFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return fmax(inX, inY);
-}
-
-float2 __attribute__((kernel)) testFmaxFloat2FloatFloat2(float2 inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return fmax(inX, inY);
-}
-
-float3 __attribute__((kernel)) testFmaxFloat3FloatFloat3(float3 inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return fmax(inX, inY);
-}
-
-float4 __attribute__((kernel)) testFmaxFloat4FloatFloat4(float4 inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return fmax(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmaxRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFmaxRelaxed.rs
deleted file mode 100644
index 74c8b3d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFmaxRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFmax.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFmin.java
deleted file mode 100644
index f206a74..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFmin.java
+++ /dev/null
@@ -1,535 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFmin extends RSBaseCompute {
-
-    private ScriptC_TestFmin script;
-    private ScriptC_TestFminRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFmin(mRS);
-        scriptRelaxed = new ScriptC_TestFminRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkFminFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7b46a8451d7b106fl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7b46a8451d7b1070l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFminFloatFloatFloat(inX, out);
-            verifyResultsFminFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFminFloatFloatFloat(inX, out);
-            verifyResultsFminFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFminFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFminFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFminFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x12b850a9e75faa59l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x12b850a9e75faa5al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFminFloat2Float2Float2(inX, out);
-            verifyResultsFminFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFminFloat2Float2Float2(inX, out);
-            verifyResultsFminFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFminFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFminFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFminFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x671d2ec9e93dabfal, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x671d2ec9e93dabfbl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFminFloat3Float3Float3(inX, out);
-            verifyResultsFminFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFminFloat3Float3Float3(inX, out);
-            verifyResultsFminFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFminFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFminFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFminFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbb820ce9eb1bad9bl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbb820ce9eb1bad9cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFminFloat4Float4Float4(inX, out);
-            verifyResultsFminFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFminFloat4Float4Float4(inX, out);
-            verifyResultsFminFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFminFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFminFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFminFloat2FloatFloat2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4dd5869724457687l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4dd5869724457688l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFminFloat2FloatFloat2(inX, out);
-            verifyResultsFminFloat2FloatFloat2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2FloatFloat2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFminFloat2FloatFloat2(inX, out);
-            verifyResultsFminFloat2FloatFloat2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2FloatFloat2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFminFloat2FloatFloat2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFminFloat2FloatFloat2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFminFloat3FloatFloat3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa32539af12b06ae3l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa32539af12b06ae4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFminFloat3FloatFloat3(inX, out);
-            verifyResultsFminFloat3FloatFloat3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3FloatFloat3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFminFloat3FloatFloat3(inX, out);
-            verifyResultsFminFloat3FloatFloat3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3FloatFloat3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFminFloat3FloatFloat3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFminFloat3FloatFloat3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFminFloat4FloatFloat4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf874ecc7011b5f3fl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf874ecc7011b5f40l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFminFloat4FloatFloat4(inX, out);
-            verifyResultsFminFloat4FloatFloat4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4FloatFloat4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFminFloat4FloatFloat4(inX, out);
-            verifyResultsFminFloat4FloatFloat4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4FloatFloat4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFminFloat4FloatFloat4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFminFloat4FloatFloat4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testFmin() {
-        checkFminFloatFloatFloat();
-        checkFminFloat2Float2Float2();
-        checkFminFloat3Float3Float3();
-        checkFminFloat4Float4Float4();
-        checkFminFloat2FloatFloat2();
-        checkFminFloat3FloatFloat3();
-        checkFminFloat4FloatFloat4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmin.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFmin.rs
deleted file mode 100644
index 28db18f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFmin.rs
+++ /dev/null
@@ -1,57 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testFminFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return fmin(inX, inY);
-}
-
-float2 __attribute__((kernel)) testFminFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return fmin(inX, inY);
-}
-
-float3 __attribute__((kernel)) testFminFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return fmin(inX, inY);
-}
-
-float4 __attribute__((kernel)) testFminFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return fmin(inX, inY);
-}
-
-float2 __attribute__((kernel)) testFminFloat2FloatFloat2(float2 inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return fmin(inX, inY);
-}
-
-float3 __attribute__((kernel)) testFminFloat3FloatFloat3(float3 inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return fmin(inX, inY);
-}
-
-float4 __attribute__((kernel)) testFminFloat4FloatFloat4(float4 inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return fmin(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFminRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFminRelaxed.rs
deleted file mode 100644
index 571f64a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFminRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFmin.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmod.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFmod.java
deleted file mode 100644
index 7bd59ef..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFmod.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFmod extends RSBaseCompute {
-
-    private ScriptC_TestFmod script;
-    private ScriptC_TestFmodRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFmod(mRS);
-        scriptRelaxed = new ScriptC_TestFmodRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkFmodFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x51ab5ae4481379a7l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x51ab5ae4481379a8l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmodFloatFloatFloat(inX, out);
-            verifyResultsFmodFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmodFloatFloatFloat(inX, out);
-            verifyResultsFmodFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmodFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmod(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmodFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmodFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1ed79fa3ec4de581l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1ed79fa3ec4de582l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmodFloat2Float2Float2(inX, out);
-            verifyResultsFmodFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmodFloat2Float2Float2(inX, out);
-            verifyResultsFmodFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmodFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmod(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmodFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmodFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x733c7dc3ee2be722l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x733c7dc3ee2be723l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmodFloat3Float3Float3(inX, out);
-            verifyResultsFmodFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmodFloat3Float3Float3(inX, out);
-            verifyResultsFmodFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmodFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmod(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmodFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFmodFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc7a15be3f009e8c3l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc7a15be3f009e8c4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testFmodFloat4Float4Float4(inX, out);
-            verifyResultsFmodFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testFmodFloat4Float4Float4(inX, out);
-            verifyResultsFmodFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFmodFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFmod(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFmodFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testFmod() {
-        checkFmodFloatFloatFloat();
-        checkFmodFloat2Float2Float2();
-        checkFmodFloat3Float3Float3();
-        checkFmodFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmod.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFmod.rs
deleted file mode 100644
index c1c2bff..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFmod.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testFmodFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return fmod(inX, inY);
-}
-
-float2 __attribute__((kernel)) testFmodFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return fmod(inX, inY);
-}
-
-float3 __attribute__((kernel)) testFmodFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return fmod(inX, inY);
-}
-
-float4 __attribute__((kernel)) testFmodFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return fmod(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFmodRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFmodRelaxed.rs
deleted file mode 100644
index 02888a1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFmodRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFmod.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFract.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFract.java
deleted file mode 100644
index 891ad96..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFract.java
+++ /dev/null
@@ -1,606 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFract extends RSBaseCompute {
-
-    private ScriptC_TestFract script;
-    private ScriptC_TestFractRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFract(mRS);
-        scriptRelaxed = new ScriptC_TestFractRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inV;
-        public Target.Floaty outFloor;
-        public Target.Floaty out;
-    }
-
-    private void checkFractFloatFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x57d8e6573c675d27l, false);
-        try {
-            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocOutFloor(outFloor);
-            script.forEach_testFractFloatFloatFloat(inV, out);
-            verifyResultsFractFloatFloatFloat(inV, outFloor, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutFloor(outFloor);
-            scriptRelaxed.forEach_testFractFloatFloatFloat(inV, out);
-            verifyResultsFractFloatFloatFloat(inV, outFloor, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFractFloatFloatFloat(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOutFloor = new float[INPUTSIZE * 1];
-        outFloor.copyTo(arrayOutFloor);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFract(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outFloor.couldBe(arrayOutFloor[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outFloor: ");
-                    message.append(args.outFloor.toString());
-                    message.append("\n");
-                    message.append("Actual   output outFloor: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutFloor[i * 1 + j], Float.floatToRawIntBits(arrayOutFloor[i * 1 + j]), arrayOutFloor[i * 1 + j]));
-                    if (!args.outFloor.couldBe(arrayOutFloor[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFractFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFractFloat2Float2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd1dbe683cdf8f525l, false);
-        try {
-            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocOutFloor(outFloor);
-            script.forEach_testFractFloat2Float2Float2(inV, out);
-            verifyResultsFractFloat2Float2Float2(inV, outFloor, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutFloor(outFloor);
-            scriptRelaxed.forEach_testFractFloat2Float2Float2(inV, out);
-            verifyResultsFractFloat2Float2Float2(inV, outFloor, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFractFloat2Float2Float2(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOutFloor = new float[INPUTSIZE * 2];
-        outFloor.copyTo(arrayOutFloor);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFract(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outFloor.couldBe(arrayOutFloor[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outFloor: ");
-                    message.append(args.outFloor.toString());
-                    message.append("\n");
-                    message.append("Actual   output outFloor: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutFloor[i * 2 + j], Float.floatToRawIntBits(arrayOutFloor[i * 2 + j]), arrayOutFloor[i * 2 + j]));
-                    if (!args.outFloor.couldBe(arrayOutFloor[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFractFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFractFloat3Float3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2640c4a3cfd6f6c6l, false);
-        try {
-            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocOutFloor(outFloor);
-            script.forEach_testFractFloat3Float3Float3(inV, out);
-            verifyResultsFractFloat3Float3Float3(inV, outFloor, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutFloor(outFloor);
-            scriptRelaxed.forEach_testFractFloat3Float3Float3(inV, out);
-            verifyResultsFractFloat3Float3Float3(inV, outFloor, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFractFloat3Float3Float3(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOutFloor = new float[INPUTSIZE * 4];
-        outFloor.copyTo(arrayOutFloor);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFract(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outFloor: ");
-                    message.append(args.outFloor.toString());
-                    message.append("\n");
-                    message.append("Actual   output outFloor: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutFloor[i * 4 + j], Float.floatToRawIntBits(arrayOutFloor[i * 4 + j]), arrayOutFloor[i * 4 + j]));
-                    if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFractFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFractFloat4Float4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7aa5a2c3d1b4f867l, false);
-        try {
-            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocOutFloor(outFloor);
-            script.forEach_testFractFloat4Float4Float4(inV, out);
-            verifyResultsFractFloat4Float4Float4(inV, outFloor, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutFloor(outFloor);
-            scriptRelaxed.forEach_testFractFloat4Float4Float4(inV, out);
-            verifyResultsFractFloat4Float4Float4(inV, outFloor, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFractFloat4Float4Float4(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOutFloor = new float[INPUTSIZE * 4];
-        outFloor.copyTo(arrayOutFloor);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFract(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outFloor: ");
-                    message.append(args.outFloor.toString());
-                    message.append("\n");
-                    message.append("Actual   output outFloor: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutFloor[i * 4 + j], Float.floatToRawIntBits(arrayOutFloor[i * 4 + j]), arrayOutFloor[i * 4 + j]));
-                    if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFractFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkFractFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf559208b9db2cad3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testFractFloatFloat(inV, out);
-            verifyResultsFractFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testFractFloatFloat(inV, out);
-            verifyResultsFractFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFractFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFract(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFractFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFractFloat2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1096c5acc4d52edfl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testFractFloat2Float2(inV, out);
-            verifyResultsFractFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testFractFloat2Float2(inV, out);
-            verifyResultsFractFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFractFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFract(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFractFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFractFloat3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x10988ec7baf04fbdl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testFractFloat3Float3(inV, out);
-            verifyResultsFractFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testFractFloat3Float3(inV, out);
-            verifyResultsFractFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFractFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFract(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFractFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFractFloat4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x109a57e2b10b709bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testFractFloat4Float4(inV, out);
-            verifyResultsFractFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testFractFloat4Float4(inV, out);
-            verifyResultsFractFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFractFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFract(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFractFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testFract() {
-        checkFractFloatFloatFloat();
-        checkFractFloat2Float2Float2();
-        checkFractFloat3Float3Float3();
-        checkFractFloat4Float4Float4();
-        checkFractFloatFloat();
-        checkFractFloat2Float2();
-        checkFractFloat3Float3();
-        checkFractFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFract.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFract.rs
deleted file mode 100644
index 38351ab..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFract.rs
+++ /dev/null
@@ -1,66 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocOutFloor;
-
-float __attribute__((kernel)) testFractFloatFloatFloat(float inV, unsigned int x) {
-    float outFloor = 0;
-    float out = fract(inV, &outFloor);
-    rsSetElementAt_float(gAllocOutFloor, outFloor, x);
-    return out;
-}
-
-float2 __attribute__((kernel)) testFractFloat2Float2Float2(float2 inV, unsigned int x) {
-    float2 outFloor = 0;
-    float2 out = fract(inV, &outFloor);
-    rsSetElementAt_float2(gAllocOutFloor, outFloor, x);
-    return out;
-}
-
-float3 __attribute__((kernel)) testFractFloat3Float3Float3(float3 inV, unsigned int x) {
-    float3 outFloor = 0;
-    float3 out = fract(inV, &outFloor);
-    rsSetElementAt_float3(gAllocOutFloor, outFloor, x);
-    return out;
-}
-
-float4 __attribute__((kernel)) testFractFloat4Float4Float4(float4 inV, unsigned int x) {
-    float4 outFloor = 0;
-    float4 out = fract(inV, &outFloor);
-    rsSetElementAt_float4(gAllocOutFloor, outFloor, x);
-    return out;
-}
-
-float __attribute__((kernel)) testFractFloatFloat(float inV) {
-    return fract(inV);
-}
-
-float2 __attribute__((kernel)) testFractFloat2Float2(float2 inV) {
-    return fract(inV);
-}
-
-float3 __attribute__((kernel)) testFractFloat3Float3(float3 inV) {
-    return fract(inV);
-}
-
-float4 __attribute__((kernel)) testFractFloat4Float4(float4 inV) {
-    return fract(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFractRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFractRelaxed.rs
deleted file mode 100644
index c9a98df..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFractRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFract.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFrexp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestFrexp.java
deleted file mode 100644
index 7258d3c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFrexp.java
+++ /dev/null
@@ -1,357 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestFrexp extends RSBaseCompute {
-
-    private ScriptC_TestFrexp script;
-    private ScriptC_TestFrexpRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestFrexp(mRS);
-        scriptRelaxed = new ScriptC_TestFrexpRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatIntFloat {
-        public float inV;
-        public int outIptr;
-        public Target.Floaty out;
-    }
-
-    private void checkFrexpFloatIntFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x57ae9fe07384e56dl, false);
-        try {
-            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocOutIptr(outIptr);
-            script.forEach_testFrexpFloatIntFloat(inV, out);
-            verifyResultsFrexpFloatIntFloat(inV, outIptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloatIntFloat: " + e.toString());
-        }
-        try {
-            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutIptr(outIptr);
-            scriptRelaxed.forEach_testFrexpFloatIntFloat(inV, out);
-            verifyResultsFrexpFloatIntFloat(inV, outIptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloatIntFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFrexpFloatIntFloat(Allocation inV, Allocation outIptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        int[] arrayOutIptr = new int[INPUTSIZE * 1];
-        outIptr.copyTo(arrayOutIptr);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFrexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.outIptr != arrayOutIptr[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outIptr: ");
-                    message.append(String.format("%d", args.outIptr));
-                    message.append("\n");
-                    message.append("Actual   output outIptr: ");
-                    message.append(String.format("%d", arrayOutIptr[i * 1 + j]));
-                    if (args.outIptr != arrayOutIptr[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFrexpFloatIntFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFrexpFloat2Int2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x544e0a688fe7701l, false);
-        try {
-            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocOutIptr(outIptr);
-            script.forEach_testFrexpFloat2Int2Float2(inV, out);
-            verifyResultsFrexpFloat2Int2Float2(inV, outIptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat2Int2Float2: " + e.toString());
-        }
-        try {
-            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutIptr(outIptr);
-            scriptRelaxed.forEach_testFrexpFloat2Int2Float2(inV, out);
-            verifyResultsFrexpFloat2Int2Float2(inV, outIptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat2Int2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFrexpFloat2Int2Float2(Allocation inV, Allocation outIptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayOutIptr = new int[INPUTSIZE * 2];
-        outIptr.copyTo(arrayOutIptr);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFrexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.outIptr != arrayOutIptr[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outIptr: ");
-                    message.append(String.format("%d", args.outIptr));
-                    message.append("\n");
-                    message.append("Actual   output outIptr: ");
-                    message.append(String.format("%d", arrayOutIptr[i * 2 + j]));
-                    if (args.outIptr != arrayOutIptr[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFrexpFloat2Int2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFrexpFloat3Int3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2afb1f097eb0e3bal, false);
-        try {
-            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocOutIptr(outIptr);
-            script.forEach_testFrexpFloat3Int3Float3(inV, out);
-            verifyResultsFrexpFloat3Int3Float3(inV, outIptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat3Int3Float3: " + e.toString());
-        }
-        try {
-            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutIptr(outIptr);
-            scriptRelaxed.forEach_testFrexpFloat3Int3Float3(inV, out);
-            verifyResultsFrexpFloat3Int3Float3(inV, outIptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat3Int3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFrexpFloat3Int3Float3(Allocation inV, Allocation outIptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOutIptr = new int[INPUTSIZE * 4];
-        outIptr.copyTo(arrayOutIptr);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFrexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.outIptr != arrayOutIptr[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outIptr: ");
-                    message.append(String.format("%d", args.outIptr));
-                    message.append("\n");
-                    message.append("Actual   output outIptr: ");
-                    message.append(String.format("%d", arrayOutIptr[i * 4 + j]));
-                    if (args.outIptr != arrayOutIptr[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFrexpFloat3Int3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkFrexpFloat4Int4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x50b15d6c74635073l, false);
-        try {
-            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocOutIptr(outIptr);
-            script.forEach_testFrexpFloat4Int4Float4(inV, out);
-            verifyResultsFrexpFloat4Int4Float4(inV, outIptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat4Int4Float4: " + e.toString());
-        }
-        try {
-            Allocation outIptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutIptr(outIptr);
-            scriptRelaxed.forEach_testFrexpFloat4Int4Float4(inV, out);
-            verifyResultsFrexpFloat4Int4Float4(inV, outIptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat4Int4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsFrexpFloat4Int4Float4(Allocation inV, Allocation outIptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayOutIptr = new int[INPUTSIZE * 4];
-        outIptr.copyTo(arrayOutIptr);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeFrexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.outIptr != arrayOutIptr[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outIptr: ");
-                    message.append(String.format("%d", args.outIptr));
-                    message.append("\n");
-                    message.append("Actual   output outIptr: ");
-                    message.append(String.format("%d", arrayOutIptr[i * 4 + j]));
-                    if (args.outIptr != arrayOutIptr[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkFrexpFloat4Int4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testFrexp() {
-        checkFrexpFloatIntFloat();
-        checkFrexpFloat2Int2Float2();
-        checkFrexpFloat3Int3Float3();
-        checkFrexpFloat4Int4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFrexp.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFrexp.rs
deleted file mode 100644
index 70c6c13..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFrexp.rs
+++ /dev/null
@@ -1,50 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocOutIptr;
-
-float __attribute__((kernel)) testFrexpFloatIntFloat(float inV, unsigned int x) {
-    int outIptr = 0;
-    float out = frexp(inV, &outIptr);
-    rsSetElementAt_int(gAllocOutIptr, outIptr, x);
-    return out;
-}
-
-float2 __attribute__((kernel)) testFrexpFloat2Int2Float2(float2 inV, unsigned int x) {
-    int2 outIptr = 0;
-    float2 out = frexp(inV, &outIptr);
-    rsSetElementAt_int2(gAllocOutIptr, outIptr, x);
-    return out;
-}
-
-float3 __attribute__((kernel)) testFrexpFloat3Int3Float3(float3 inV, unsigned int x) {
-    int3 outIptr = 0;
-    float3 out = frexp(inV, &outIptr);
-    rsSetElementAt_int3(gAllocOutIptr, outIptr, x);
-    return out;
-}
-
-float4 __attribute__((kernel)) testFrexpFloat4Int4Float4(float4 inV, unsigned int x) {
-    int4 outIptr = 0;
-    float4 out = frexp(inV, &outIptr);
-    rsSetElementAt_int4(gAllocOutIptr, outIptr, x);
-    return out;
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestFrexpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestFrexpRelaxed.rs
deleted file mode 100644
index 8dc4c4d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestFrexpRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestFrexp.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestGetSet.java b/tests/tests/renderscript/src/android/renderscript/cts/TestGetSet.java
deleted file mode 100644
index d11de84..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestGetSet.java
+++ /dev/null
@@ -1,1084 +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.renderscript.cts;
-
-import android.renderscript.*;
-
-public class TestGetSet extends RSBaseCompute {
-
-    private ScriptC_getset script;
-    private ScriptC_getset_relaxed scriptRelaxed;
-    Allocation walkAlloc;
-    Allocation in1DAlloc;
-    Allocation out1DAlloc;
-    Allocation in2DAlloc;
-    Allocation out2DAlloc;
-    Allocation in3DAlloc;
-    Allocation out3DAlloc;
-    private static java.util.Random random = new java.util.Random();
-
-    final int gWidth = 252;
-    final int gHeight = 31;
-    final int gDepth = 4;
-    final int gCount = gWidth * gHeight * gDepth;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        random.setSeed(10);
-        script = new ScriptC_getset(mRS);
-        scriptRelaxed = new ScriptC_getset_relaxed(mRS);
-        script.set_gWidth(gWidth);
-        script.set_gHeight(gHeight);
-        scriptRelaxed.set_gWidth(gWidth);
-        scriptRelaxed.set_gHeight(gHeight);
-    }
-
-
-
-    protected void createWalk(int vsize) {
-        // We do a random copy order to attempt to get multiple threads
-        // reading and writing the same cache line
-        // We could do this as a simple walk but that would likely miss
-        // some caching issues.
-        final int tw = gCount / vsize;
-        int tmp[] = new int[tw];
-        boolean b[] = new boolean[tw];
-        int toCopy = tw;
-        int i = 0;
-
-        while (toCopy > 0) {
-            int x = random.nextInt(tw);
-
-            while ((x < tw) && b[x]) {
-                x++;
-                if (x >= tw) {
-                    x = 0;
-                }
-            }
-
-            b[x] = true;
-            toCopy --;
-
-            //android.util.Log.v("rs", "walk  " + i + ", " + x);
-            tmp[i++] = x;
-        }
-
-        walkAlloc = Allocation.createSized(mRS, Element.I32(mRS), tw);
-        walkAlloc.copy1DRangeFrom(0, tw, tmp);
-    }
-
-    private void testSetup(Element e) {
-        int vs = e.getVectorSize();
-        if (vs == 3) {
-            vs = 4;
-        }
-        createWalk(vs);
-
-        Type t1 = Type.createX(mRS, e, gWidth * gHeight * gDepth / vs);
-        in1DAlloc = Allocation.createTyped(mRS, t1);
-        out1DAlloc = Allocation.createTyped(mRS, t1);
-        script.set_gAlloc1DIn(in1DAlloc);
-        script.set_gAlloc1DOut(out1DAlloc);
-        scriptRelaxed.set_gAlloc1DIn(in1DAlloc);
-        scriptRelaxed.set_gAlloc1DOut(out1DAlloc);
-
-        Type t2 = Type.createXY(mRS, e, gWidth / vs, gHeight * gDepth);
-        in2DAlloc = Allocation.createTyped(mRS, t2);
-        out2DAlloc = Allocation.createTyped(mRS, t2);
-        script.set_gAlloc2DIn(in2DAlloc);
-        script.set_gAlloc2DOut(out2DAlloc);
-        scriptRelaxed.set_gAlloc2DIn(in2DAlloc);
-        scriptRelaxed.set_gAlloc2DOut(out2DAlloc);
-
-        Type t3 = Type.createXYZ(mRS, e, gWidth / vs, gHeight, gDepth);
-        in3DAlloc = Allocation.createTyped(mRS, t3);
-        out3DAlloc = Allocation.createTyped(mRS, t3);
-        script.set_gAlloc3DIn(in3DAlloc);
-        script.set_gAlloc3DOut(out3DAlloc);
-        scriptRelaxed.set_gAlloc3DIn(in3DAlloc);
-        scriptRelaxed.set_gAlloc3DOut(out3DAlloc);
-    }
-
-    private void verify(byte[] a1, byte[] a2, Allocation alloc, String s, int vsize) {
-        alloc.copyTo(a2);
-        for (int i=0; i < gWidth; i++) {
-            if (a1[i] != a2[i]) {
-                if ((vsize == 3) && ((i % 4) == 3)) {
-                    continue;
-                }
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        alloc.copyFrom(a2);
-    }
-
-    private void verify(short[] a1, short[] a2, Allocation alloc, String s, int vsize) {
-        alloc.copyTo(a2);
-        for (int i=0; i < gWidth; i++) {
-            if (a1[i] != a2[i]) {
-                if ((vsize == 3) && ((i % 4) == 3)) {
-                    continue;
-                }
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        alloc.copyFrom(a2);
-    }
-
-    private void verify(int[] a1, int[] a2, Allocation alloc, String s, int vsize) {
-        alloc.copyTo(a2);
-        for (int i=0; i < gWidth; i++) {
-            if (a1[i] != a2[i]) {
-                if ((vsize == 3) && ((i % 4) == 3)) {
-                    continue;
-                }
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        alloc.copyFrom(a2);
-    }
-
-    private void verify(long[] a1, long[] a2, Allocation alloc, String s, int vsize) {
-        alloc.copyTo(a2);
-        for (int i=0; i < gWidth; i++) {
-            if (a1[i] != a2[i]) {
-                if ((vsize == 3) && ((i % 4) == 3)) {
-                    continue;
-                }
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        alloc.copyFrom(a2);
-    }
-
-    private void verify(float[] a1, float[] a2, Allocation alloc, String s, int vsize) {
-        alloc.copyTo(a2);
-        for (int i=0; i < gWidth; i++) {
-            if (a1[i] != a2[i]) {
-                if ((vsize == 3) && ((i % 4) == 3)) {
-                    continue;
-                }
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        alloc.copyFrom(a2);
-    }
-
-    private void verify(double[] a1, double[] a2, Allocation alloc, String s, int vsize) {
-        alloc.copyTo(a2);
-        for (int i=0; i < gWidth; i++) {
-            if (a1[i] != a2[i]) {
-                if ((vsize == 3) && ((i % 4) == 3)) {
-                    continue;
-                }
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        alloc.copyFrom(a2);
-    }
-
-    private byte[] randomByteArray(int len) {
-        byte t[] = new byte[len];
-        random.nextBytes(t);
-        in1DAlloc.copyFrom(t);
-        in2DAlloc.copyFrom(t);
-        in3DAlloc.copyFrom(t);
-        return t;
-    }
-
-    private short[] randomShortArray(int len) {
-        short t[] = new short[len];
-        for (int i = 0; i < t.length; i++) {
-            t[i] = (short)(random.nextInt() & 0xffff);
-        }
-        in1DAlloc.copyFrom(t);
-        in2DAlloc.copyFrom(t);
-        in3DAlloc.copyFrom(t);
-        return t;
-    }
-
-    private int[] randomIntArray(int len) {
-        int t[] = new int[len];
-        for (int i = 0; i < t.length; i++) {
-            t[i] = random.nextInt();
-        }
-        in1DAlloc.copyFrom(t);
-        in2DAlloc.copyFrom(t);
-        in3DAlloc.copyFrom(t);
-        return t;
-    }
-
-    private long[] randomLongArray(int len) {
-        long t[] = new long[len];
-        for (int i = 0; i < t.length; i++) {
-            t[i] = random.nextLong();
-        }
-        in1DAlloc.copyFrom(t);
-        in2DAlloc.copyFrom(t);
-        in3DAlloc.copyFrom(t);
-        return t;
-    }
-
-    private float[] randomFloatArray(int len) {
-        float t[] = new float[len];
-        for (int i = 0; i < t.length; i++) {
-            t[i] = random.nextFloat();
-        }
-        in1DAlloc.copyFrom(t);
-        in2DAlloc.copyFrom(t);
-        in3DAlloc.copyFrom(t);
-        return t;
-    }
-
-    private double[] randomDoubleArray(int len) {
-        double t[] = new double[len];
-        for (int i = 0; i < t.length; i++) {
-            t[i] = random.nextDouble();
-        }
-        in1DAlloc.copyFrom(t);
-        in2DAlloc.copyFrom(t);
-        in3DAlloc.copyFrom(t);
-        return t;
-    }
-
-    public void testGetSet_char() {
-        testSetup(Element.I8(mRS));
-        byte tmp[] = randomByteArray(gCount);
-        byte tmp2[] = new byte[gCount];
-
-        script.forEach_copy1D_char(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch char: ", 1);
-        scriptRelaxed.forEach_copy1D_char(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed char: ", 1);
-
-        script.forEach_copy2D_char(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch char: ", 1);
-        scriptRelaxed.forEach_copy2D_char(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed char: ", 1);
-
-        script.forEach_copy3D_char(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch char: ", 1);
-        scriptRelaxed.forEach_copy3D_char(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed char: ", 1);
-    }
-
-    public void testGetSet_char2() {
-        testSetup(Element.I8_2(mRS));
-        byte tmp[] = randomByteArray(gCount);
-        byte tmp2[] = new byte[gCount];
-        script.forEach_copy1D_char2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch char2: ", 2);
-        scriptRelaxed.forEach_copy1D_char2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed char2: ", 2);
-
-        script.forEach_copy2D_char2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch char2: ", 2);
-        scriptRelaxed.forEach_copy2D_char2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed char2: ", 2);
-
-        script.forEach_copy3D_char2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch char2: ", 2);
-        scriptRelaxed.forEach_copy3D_char2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed char2: ", 2);
-    }
-
-    public void testGetSet_char3() {
-        testSetup(Element.I8_3(mRS));
-        byte tmp[] = randomByteArray(gCount);
-        byte tmp2[] = new byte[gCount];
-        script.forEach_copy1D_char3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch char3: ", 3);
-        scriptRelaxed.forEach_copy1D_char3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed char3: ", 3);
-
-        script.forEach_copy2D_char3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch char3: ", 3);
-        scriptRelaxed.forEach_copy2D_char3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed char3: ", 3);
-
-        script.forEach_copy3D_char3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch char3: ", 3);
-        scriptRelaxed.forEach_copy3D_char3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed char3: ", 3);
-    }
-
-    public void testGetSet_char4() {
-        testSetup(Element.I8_4(mRS));
-        byte tmp[] = randomByteArray(gCount);
-        byte tmp2[] = new byte[gCount];
-        script.forEach_copy1D_char4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch char4: ", 4);
-        scriptRelaxed.forEach_copy1D_char4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed char4: ", 4);
-
-        script.forEach_copy2D_char4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch char4: ", 4);
-        scriptRelaxed.forEach_copy2D_char4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed char4: ", 4);
-
-        script.forEach_copy3D_char4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch char4: ", 4);
-        scriptRelaxed.forEach_copy3D_char4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed char4: ", 4);
-    }
-
-    public void testGetSet_uchar() {
-        testSetup(Element.U8(mRS));
-        byte tmp[] = randomByteArray(gCount);
-        byte tmp2[] = new byte[gCount];
-        script.forEach_copy1D_uchar(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch uchar: ", 1);
-        scriptRelaxed.forEach_copy1D_uchar(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uchar: ", 1);
-
-        script.forEach_copy2D_uchar(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch uchar: ", 1);
-        scriptRelaxed.forEach_copy2D_uchar(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uchar: ", 1);
-
-        script.forEach_copy3D_uchar(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch uchar: ", 1);
-        scriptRelaxed.forEach_copy3D_uchar(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uchar: ", 1);
-    }
-
-    public void testGetSet_uchar2() {
-        testSetup(Element.U8_2(mRS));
-        byte tmp[] = randomByteArray(gCount);
-        byte tmp2[] = new byte[gCount];
-        script.forEach_copy1D_uchar2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch uchar2: ", 2);
-        scriptRelaxed.forEach_copy1D_uchar2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uchar2: ", 2);
-
-        script.forEach_copy2D_uchar2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch uchar2: ", 2);
-        scriptRelaxed.forEach_copy2D_uchar2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uchar2: ", 2);
-
-        script.forEach_copy3D_uchar2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch uchar2: ", 2);
-        scriptRelaxed.forEach_copy3D_uchar2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uchar2: ", 2);
-    }
-
-    public void testGetSet_uchar3() {
-        testSetup(Element.U8_3(mRS));
-        byte tmp[] = randomByteArray(gCount);
-        byte tmp2[] = new byte[gCount];
-        script.forEach_copy1D_uchar3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch uchar3: ", 3);
-        scriptRelaxed.forEach_copy1D_uchar3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uchar3: ", 3);
-
-        script.forEach_copy2D_uchar3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch uchar3: ", 3);
-        scriptRelaxed.forEach_copy2D_uchar3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uchar3: ", 3);
-
-        script.forEach_copy3D_uchar3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch uchar3: ", 3);
-        scriptRelaxed.forEach_copy3D_uchar3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uchar3: ", 3);
-    }
-
-    public void testGetSet_uchar4() {
-        testSetup(Element.U8_4(mRS));
-        byte tmp[] = randomByteArray(gCount);
-        byte tmp2[] = new byte[gCount];
-        script.forEach_copy1D_uchar4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch uchar4: ", 4);
-        scriptRelaxed.forEach_copy1D_uchar4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uchar4: ", 4);
-
-        script.forEach_copy2D_uchar4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch uchar4: ", 4);
-        scriptRelaxed.forEach_copy2D_uchar4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uchar4: ", 4);
-
-        script.forEach_copy3D_uchar4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch uchar4: ", 4);
-        scriptRelaxed.forEach_copy3D_uchar4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uchar4: ", 4);
-    }
-
-
-
-
-
-
-    public void testGetSet_short() {
-        testSetup(Element.I16(mRS));
-        short tmp[] = randomShortArray(gCount);
-        short tmp2[] = new short[gCount];
-        script.forEach_copy1D_short(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch short: ", 1);
-        scriptRelaxed.forEach_copy1D_short(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed short: ", 1);
-
-        script.forEach_copy2D_short(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch short: ", 1);
-        scriptRelaxed.forEach_copy2D_short(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed short: ", 1);
-
-        script.forEach_copy3D_short(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch short: ", 1);
-        scriptRelaxed.forEach_copy3D_short(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed short: ", 1);
-    }
-
-    public void testGetSet_short2() {
-        testSetup(Element.I16_2(mRS));
-        short tmp[] = randomShortArray(gCount);
-        short tmp2[] = new short[gCount];
-        script.forEach_copy1D_short2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch short2: ", 2);
-        scriptRelaxed.forEach_copy1D_short2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed short2: ", 2);
-
-        script.forEach_copy2D_short2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch short2: ", 2);
-        scriptRelaxed.forEach_copy2D_short2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed short2: ", 2);
-
-        script.forEach_copy3D_short2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch short2: ", 2);
-        scriptRelaxed.forEach_copy3D_short2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed short2: ", 2);
-    }
-
-    public void testGetSet_short3() {
-        testSetup(Element.I16_3(mRS));
-        short tmp[] = randomShortArray(gCount);
-        short tmp2[] = new short[gCount];
-        script.forEach_copy1D_short3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch short3: ", 3);
-        scriptRelaxed.forEach_copy1D_short3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed short3: ", 3);
-
-        script.forEach_copy2D_short3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch short3: ", 3);
-        scriptRelaxed.forEach_copy2D_short3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed short3: ", 3);
-
-        script.forEach_copy3D_short3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch short3: ", 3);
-        scriptRelaxed.forEach_copy3D_short3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed short3: ", 3);
-    }
-
-    public void testGetSet_short4() {
-        testSetup(Element.I16_4(mRS));
-        short tmp[] = randomShortArray(gCount);
-        short tmp2[] = new short[gCount];
-        script.forEach_copy1D_short4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch short4: ", 4);
-        scriptRelaxed.forEach_copy1D_short4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed short4: ", 4);
-
-        script.forEach_copy2D_short4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch short4: ", 4);
-        scriptRelaxed.forEach_copy2D_short4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed short4: ", 4);
-
-        script.forEach_copy3D_short4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch short4: ", 4);
-        scriptRelaxed.forEach_copy3D_short4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed short4: ", 4);
-    }
-
-    public void testGetSet_ushort() {
-        testSetup(Element.U16(mRS));
-        short tmp[] = randomShortArray(gCount);
-        short tmp2[] = new short[gCount];
-        script.forEach_copy1D_ushort(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch ushort: ", 1);
-        scriptRelaxed.forEach_copy1D_ushort(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ushort: ", 1);
-
-        script.forEach_copy2D_ushort(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch ushort: ", 1);
-        scriptRelaxed.forEach_copy2D_ushort(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ushort: ", 1);
-
-        script.forEach_copy3D_ushort(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch ushort: ", 1);
-        scriptRelaxed.forEach_copy3D_ushort(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ushort: ", 1);
-    }
-
-    public void testGetSet_ushort2() {
-        testSetup(Element.U16_2(mRS));
-        short tmp[] = randomShortArray(gCount);
-        short tmp2[] = new short[gCount];
-        script.forEach_copy1D_ushort2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch ushort2: ", 2);
-        scriptRelaxed.forEach_copy1D_ushort2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ushort2: ", 2);
-
-        script.forEach_copy2D_ushort2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch ushort2: ", 2);
-        scriptRelaxed.forEach_copy2D_ushort2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ushort2: ", 2);
-
-        script.forEach_copy3D_ushort2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch ushort2: ", 2);
-        scriptRelaxed.forEach_copy3D_ushort2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ushort2: ", 2);
-    }
-
-    public void testGetSet_ushort3() {
-        testSetup(Element.U16_3(mRS));
-        short tmp[] = randomShortArray(gCount);
-        short tmp2[] = new short[gCount];
-        script.forEach_copy1D_ushort3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch ushort3: ", 3);
-        scriptRelaxed.forEach_copy1D_ushort3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ushort3: ", 3);
-
-        script.forEach_copy2D_ushort3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch ushort3: ", 3);
-        scriptRelaxed.forEach_copy2D_ushort3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ushort3: ", 3);
-
-        script.forEach_copy3D_ushort3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch ushort3: ", 3);
-        scriptRelaxed.forEach_copy3D_ushort3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ushort3: ", 3);
-    }
-
-    public void testGetSet_ushort4() {
-        testSetup(Element.U16_4(mRS));
-        short tmp[] = randomShortArray(gCount);
-        short tmp2[] = new short[gCount];
-        script.forEach_copy1D_ushort4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch ushort4: ", 4);
-        scriptRelaxed.forEach_copy1D_ushort4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ushort4: ", 4);
-
-        script.forEach_copy2D_ushort4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch ushort4: ", 4);
-        scriptRelaxed.forEach_copy2D_ushort4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ushort4: ", 4);
-
-        script.forEach_copy3D_ushort4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch ushort4: ", 4);
-        scriptRelaxed.forEach_copy3D_ushort4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ushort4: ", 4);
-    }
-
-
-
-
-    public void testGetSet_int() {
-        testSetup(Element.I32(mRS));
-        int tmp[] = randomIntArray(gCount);
-        int tmp2[] = new int[gCount];
-        script.forEach_copy1D_int(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch int: ", 1);
-        scriptRelaxed.forEach_copy1D_int(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed int: ", 1);
-
-        script.forEach_copy2D_int(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch int: ", 1);
-        scriptRelaxed.forEach_copy2D_int(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed int: ", 1);
-
-        script.forEach_copy3D_int(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch int: ", 1);
-        scriptRelaxed.forEach_copy3D_int(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed int: ", 1);
-    }
-
-    public void testGetSet_int2() {
-        testSetup(Element.I32_2(mRS));
-        int tmp[] = randomIntArray(gCount);
-        int tmp2[] = new int[gCount];
-        script.forEach_copy1D_int2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch int2: ", 2);
-        scriptRelaxed.forEach_copy1D_int2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed int2: ", 2);
-
-        script.forEach_copy2D_int2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch int2: ", 2);
-        scriptRelaxed.forEach_copy2D_int2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed int2: ", 2);
-
-        script.forEach_copy3D_int2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch int2: ", 2);
-        scriptRelaxed.forEach_copy3D_int2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed int2: ", 2);
-    }
-
-    public void testGetSet_int3() {
-        testSetup(Element.I32_3(mRS));
-        int tmp[] = randomIntArray(gCount);
-        int tmp2[] = new int[gCount];
-        script.forEach_copy1D_int3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch int3: ", 3);
-        scriptRelaxed.forEach_copy1D_int3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed int3: ", 3);
-
-        script.forEach_copy2D_int3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch int3: ", 3);
-        scriptRelaxed.forEach_copy2D_int3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed int3: ", 3);
-
-        script.forEach_copy3D_int3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch int3: ", 3);
-        scriptRelaxed.forEach_copy3D_int3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed int3: ", 3);
-    }
-
-    public void testGetSet_int4() {
-        testSetup(Element.I32_4(mRS));
-        int tmp[] = randomIntArray(gCount);
-        int tmp2[] = new int[gCount];
-        script.forEach_copy1D_int4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch int4: ", 4);
-        scriptRelaxed.forEach_copy1D_int4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed int4: ", 4);
-
-        script.forEach_copy2D_int4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch int4: ", 4);
-        scriptRelaxed.forEach_copy2D_int4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed int4: ", 4);
-
-        script.forEach_copy3D_int4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch int4: ", 4);
-        scriptRelaxed.forEach_copy3D_int4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed int4: ", 4);
-    }
-
-    public void testGetSet_uint() {
-        testSetup(Element.U32(mRS));
-        int tmp[] = randomIntArray(gCount);
-        int tmp2[] = new int[gCount];
-        script.forEach_copy1D_uint(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch uint: ", 1);
-        scriptRelaxed.forEach_copy1D_uint(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uint: ", 1);
-
-        script.forEach_copy2D_uint(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch uint: ", 1);
-        scriptRelaxed.forEach_copy2D_uint(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uint: ", 1);
-
-        script.forEach_copy3D_uint(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch uint: ", 1);
-        scriptRelaxed.forEach_copy3D_uint(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uint: ", 1);
-    }
-
-    public void testGetSet_uint2() {
-        testSetup(Element.U32_2(mRS));
-        int tmp[] = randomIntArray(gCount);
-        int tmp2[] = new int[gCount];
-        script.forEach_copy1D_uint2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch uint2: ", 2);
-        scriptRelaxed.forEach_copy1D_uint2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uint2: ", 2);
-
-        script.forEach_copy2D_uint2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch uint2: ", 2);
-        scriptRelaxed.forEach_copy2D_uint2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uint2: ", 2);
-
-        script.forEach_copy3D_uint2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch uint2: ", 2);
-        scriptRelaxed.forEach_copy3D_uint2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uint2: ", 2);
-    }
-
-    public void testGetSet_uint3() {
-        testSetup(Element.U32_3(mRS));
-        int tmp[] = randomIntArray(gCount);
-        int tmp2[] = new int[gCount];
-        script.forEach_copy1D_uint3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch uint3: ", 3);
-        scriptRelaxed.forEach_copy1D_uint3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uint3: ", 3);
-
-        script.forEach_copy2D_uint3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch uint3: ", 3);
-        scriptRelaxed.forEach_copy2D_uint3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uint3: ", 3);
-
-        script.forEach_copy3D_uint3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch uint3: ", 3);
-        scriptRelaxed.forEach_copy3D_uint3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uint3: ", 3);
-    }
-
-    public void testGetSet_uint4() {
-        testSetup(Element.U32_4(mRS));
-        int tmp[] = randomIntArray(gCount);
-        int tmp2[] = new int[gCount];
-        script.forEach_copy1D_uint4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch uint4: ", 4);
-        scriptRelaxed.forEach_copy1D_uint4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed uint4: ", 4);
-
-        script.forEach_copy2D_uint4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch uint4: ", 4);
-        scriptRelaxed.forEach_copy2D_uint4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed uint4: ", 4);
-
-        script.forEach_copy3D_uint4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch uint4: ", 4);
-        scriptRelaxed.forEach_copy3D_uint4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed uint4: ", 4);
-    }
-
-
-
-
-    public void testGetSet_long() {
-        testSetup(Element.I64(mRS));
-        long tmp[] = randomLongArray(gCount);
-        long tmp2[] = new long[gCount];
-        script.forEach_copy1D_long(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch long: ", 1);
-        scriptRelaxed.forEach_copy1D_long(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed long: ", 1);
-
-        script.forEach_copy2D_long(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch long: ", 1);
-        scriptRelaxed.forEach_copy2D_long(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed long: ", 1);
-
-        script.forEach_copy3D_long(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch long: ", 1);
-        scriptRelaxed.forEach_copy3D_long(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed long: ", 1);
-    }
-
-    public void testGetSet_long2() {
-        testSetup(Element.I64_2(mRS));
-        long tmp[] = randomLongArray(gCount);
-        long tmp2[] = new long[gCount];
-        script.forEach_copy1D_long2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch long2: ", 2);
-        scriptRelaxed.forEach_copy1D_long2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed long2: ", 2);
-
-        script.forEach_copy2D_long2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch long2: ", 2);
-        scriptRelaxed.forEach_copy2D_long2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed long2: ", 2);
-
-        script.forEach_copy3D_long2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch long2: ", 2);
-        scriptRelaxed.forEach_copy3D_long2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed long2: ", 2);
-    }
-
-    public void testGetSet_long3() {
-        testSetup(Element.I64_3(mRS));
-        long tmp[] = randomLongArray(gCount);
-        long tmp2[] = new long[gCount];
-        script.forEach_copy1D_long3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch long3: ", 3);
-        scriptRelaxed.forEach_copy1D_long3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed long3: ", 3);
-
-        script.forEach_copy2D_long3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch long3: ", 3);
-        scriptRelaxed.forEach_copy2D_long3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed long3: ", 3);
-
-        script.forEach_copy3D_long3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch long3: ", 3);
-        scriptRelaxed.forEach_copy3D_long3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed long3: ", 3);
-    }
-
-    public void testGetSet_long4() {
-        testSetup(Element.I64_4(mRS));
-        long tmp[] = randomLongArray(gCount);
-        long tmp2[] = new long[gCount];
-        script.forEach_copy1D_long4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch long4: ", 4);
-        scriptRelaxed.forEach_copy1D_long4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed long4: ", 4);
-
-        script.forEach_copy2D_long4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch long4: ", 4);
-        scriptRelaxed.forEach_copy2D_long4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed long4: ", 4);
-
-        script.forEach_copy3D_long4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch long4: ", 4);
-        scriptRelaxed.forEach_copy3D_long4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed long4: ", 4);
-    }
-
-    public void testGetSet_ulong() {
-        testSetup(Element.U64(mRS));
-        long tmp[] = randomLongArray(gCount);
-        long tmp2[] = new long[gCount];
-        script.forEach_copy1D_ulong(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch ulong: ", 1);
-        scriptRelaxed.forEach_copy1D_ulong(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ulong: ", 1);
-
-        script.forEach_copy2D_ulong(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch ulong: ", 1);
-        scriptRelaxed.forEach_copy2D_ulong(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ulong: ", 1);
-
-        script.forEach_copy3D_ulong(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch ulong: ", 1);
-        scriptRelaxed.forEach_copy3D_ulong(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ulong: ", 1);
-    }
-
-    public void testGetSet_ulong2() {
-        testSetup(Element.U64_2(mRS));
-        long tmp[] = randomLongArray(gCount);
-        long tmp2[] = new long[gCount];
-        script.forEach_copy1D_ulong2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch ulong2: ", 2);
-        scriptRelaxed.forEach_copy1D_ulong2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ulong2: ", 2);
-
-        script.forEach_copy2D_ulong2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch ulong2: ", 2);
-        scriptRelaxed.forEach_copy2D_ulong2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ulong2: ", 2);
-
-        script.forEach_copy3D_ulong2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch ulong2: ", 2);
-        scriptRelaxed.forEach_copy3D_ulong2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ulong2: ", 2);
-    }
-
-    public void testGetSet_ulong3() {
-        testSetup(Element.U64_3(mRS));
-        long tmp[] = randomLongArray(gCount);
-        long tmp2[] = new long[gCount];
-        script.forEach_copy1D_ulong3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch ulong3: ", 3);
-        scriptRelaxed.forEach_copy1D_ulong3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ulong3: ", 3);
-
-        script.forEach_copy2D_ulong3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch ulong3: ", 3);
-        scriptRelaxed.forEach_copy2D_ulong3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ulong3: ", 3);
-
-        script.forEach_copy3D_ulong3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch ulong3: ", 3);
-        scriptRelaxed.forEach_copy3D_ulong3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ulong3: ", 3);
-    }
-
-    public void testGetSet_ulong4() {
-        testSetup(Element.U64_4(mRS));
-        long tmp[] = randomLongArray(gCount);
-        long tmp2[] = new long[gCount];
-        script.forEach_copy1D_ulong4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch ulong4: ", 4);
-        scriptRelaxed.forEach_copy1D_ulong4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed ulong4: ", 4);
-
-        script.forEach_copy2D_ulong4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch ulong4: ", 4);
-        scriptRelaxed.forEach_copy2D_ulong4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed ulong4: ", 4);
-
-        script.forEach_copy3D_ulong4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch ulong4: ", 4);
-        scriptRelaxed.forEach_copy3D_ulong4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed ulong4: ", 4);
-    }
-
-
-
-
-    public void testGetSet_float() {
-        testSetup(Element.F32(mRS));
-        float tmp[] = randomFloatArray(gCount);
-        float tmp2[] = new float[gCount];
-        script.forEach_copy1D_float(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch float: ", 1);
-        scriptRelaxed.forEach_copy1D_float(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed float: ", 1);
-
-        script.forEach_copy2D_float(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch float: ", 1);
-        scriptRelaxed.forEach_copy2D_float(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed float: ", 1);
-
-        script.forEach_copy3D_float(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch float: ", 1);
-        scriptRelaxed.forEach_copy3D_float(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed float: ", 1);
-    }
-
-    public void testGetSet_float2() {
-        testSetup(Element.F32_2(mRS));
-        float tmp[] = randomFloatArray(gCount);
-        float tmp2[] = new float[gCount];
-        script.forEach_copy1D_float2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch float2: ", 2);
-        scriptRelaxed.forEach_copy1D_float2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed float2: ", 2);
-
-        script.forEach_copy2D_float2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch float2: ", 2);
-        scriptRelaxed.forEach_copy2D_float2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed float2: ", 2);
-
-        script.forEach_copy3D_float2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch float2: ", 2);
-        scriptRelaxed.forEach_copy3D_float2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed float2: ", 2);
-    }
-
-    public void testGetSet_float3() {
-        testSetup(Element.F32_3(mRS));
-        float tmp[] = randomFloatArray(gCount);
-        float tmp2[] = new float[gCount];
-        script.forEach_copy1D_float3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch float3: ", 3);
-        scriptRelaxed.forEach_copy1D_float3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed float3: ", 3);
-
-        script.forEach_copy2D_float3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch float3: ", 3);
-        scriptRelaxed.forEach_copy2D_float3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed float3: ", 3);
-
-        script.forEach_copy3D_float3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch float3: ", 3);
-        scriptRelaxed.forEach_copy3D_float3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed float3: ", 3);
-    }
-
-    public void testGetSet_float4() {
-        testSetup(Element.F32_4(mRS));
-        float tmp[] = randomFloatArray(gCount);
-        float tmp2[] = new float[gCount];
-        script.forEach_copy1D_float4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch float4: ", 4);
-        scriptRelaxed.forEach_copy1D_float4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed float4: ", 4);
-
-        script.forEach_copy2D_float4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch float4: ", 4);
-        scriptRelaxed.forEach_copy2D_float4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed float4: ", 4);
-
-        script.forEach_copy3D_float4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch float4: ", 4);
-        scriptRelaxed.forEach_copy3D_float4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed float4: ", 4);
-    }
-
-
-    public void testGetSet_double() {
-        testSetup(Element.F64(mRS));
-        double tmp[] = randomDoubleArray(gCount);
-        double tmp2[] = new double[gCount];
-        script.forEach_copy1D_double(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch double: ", 1);
-        scriptRelaxed.forEach_copy1D_double(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed double: ", 1);
-
-        script.forEach_copy2D_double(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch double: ", 1);
-        scriptRelaxed.forEach_copy2D_double(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed double: ", 1);
-
-        script.forEach_copy3D_double(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch double: ", 1);
-        scriptRelaxed.forEach_copy3D_double(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed double: ", 1);
-    }
-
-    public void testGetSet_double2() {
-        testSetup(Element.F64_2(mRS));
-        double tmp[] = randomDoubleArray(gCount);
-        double tmp2[] = new double[gCount];
-        script.forEach_copy1D_double2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch double2: ", 2);
-        scriptRelaxed.forEach_copy1D_double2(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed double2: ", 2);
-
-        script.forEach_copy2D_double2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch double2: ", 2);
-        scriptRelaxed.forEach_copy2D_double2(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed double2: ", 2);
-
-        script.forEach_copy3D_double2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch double2: ", 2);
-        scriptRelaxed.forEach_copy3D_double2(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed double2: ", 2);
-    }
-
-    public void testGetSet_double3() {
-        testSetup(Element.F64_3(mRS));
-        double tmp[] = randomDoubleArray(gCount);
-        double tmp2[] = new double[gCount];
-        script.forEach_copy1D_double3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch double3: ", 3);
-        scriptRelaxed.forEach_copy1D_double3(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed double3: ", 3);
-
-        script.forEach_copy2D_double3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch double3: ", 3);
-        scriptRelaxed.forEach_copy2D_double3(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed double3: ", 3);
-
-        script.forEach_copy3D_double3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch double3: ", 3);
-        scriptRelaxed.forEach_copy3D_double3(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed double3: ", 3);
-    }
-
-    public void testGetSet_double4() {
-        testSetup(Element.F64_4(mRS));
-        double tmp[] = randomDoubleArray(gCount);
-        double tmp2[] = new double[gCount];
-        script.forEach_copy1D_double4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch double4: ", 4);
-        scriptRelaxed.forEach_copy1D_double4(walkAlloc);
-        verify(tmp, tmp2, out1DAlloc, "Data mismatch relaxed double4: ", 4);
-
-        script.forEach_copy2D_double4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch double4: ", 4);
-        scriptRelaxed.forEach_copy2D_double4(walkAlloc);
-        verify(tmp, tmp2, out2DAlloc, "Data mismatch relaxed double4: ", 4);
-
-        script.forEach_copy3D_double4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch double4: ", 4);
-        scriptRelaxed.forEach_copy3D_double4(walkAlloc);
-        verify(tmp, tmp2, out3DAlloc, "Data mismatch relaxed double4: ", 4);
-    }
-
-
-}
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecip.java b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecip.java
deleted file mode 100644
index 8d4f1b7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecip.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestHalfRecip extends RSBaseCompute {
-
-    private ScriptC_TestHalfRecip script;
-    private ScriptC_TestHalfRecipRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestHalfRecip(mRS);
-        scriptRelaxed = new ScriptC_TestHalfRecipRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkHalfRecipFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x854e263130d5b3dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testHalfRecipFloatFloat(inV, out);
-            verifyResultsHalfRecipFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfRecipFloatFloat(inV, out);
-            verifyResultsHalfRecipFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfRecipFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfRecip(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfRecipFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHalfRecipFloat2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2cf1d2db5ff23c79l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testHalfRecipFloat2Float2(inV, out);
-            verifyResultsHalfRecipFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfRecipFloat2Float2(inV, out);
-            verifyResultsHalfRecipFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfRecipFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfRecip(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfRecipFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHalfRecipFloat3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2cf39bf6560d5d57l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testHalfRecipFloat3Float3(inV, out);
-            verifyResultsHalfRecipFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfRecipFloat3Float3(inV, out);
-            verifyResultsHalfRecipFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfRecipFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfRecip(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfRecipFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHalfRecipFloat4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2cf565114c287e35l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testHalfRecipFloat4Float4(inV, out);
-            verifyResultsHalfRecipFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfRecipFloat4Float4(inV, out);
-            verifyResultsHalfRecipFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfRecipFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfRecip(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfRecipFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testHalfRecip() {
-        checkHalfRecipFloatFloat();
-        checkHalfRecipFloat2Float2();
-        checkHalfRecipFloat3Float3();
-        checkHalfRecipFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecip.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecip.rs
deleted file mode 100644
index 03c5802..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecip.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testHalfRecipFloatFloat(float inV) {
-    return half_recip(inV);
-}
-
-float2 __attribute__((kernel)) testHalfRecipFloat2Float2(float2 inV) {
-    return half_recip(inV);
-}
-
-float3 __attribute__((kernel)) testHalfRecipFloat3Float3(float3 inV) {
-    return half_recip(inV);
-}
-
-float4 __attribute__((kernel)) testHalfRecipFloat4Float4(float4 inV) {
-    return half_recip(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecipRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecipRelaxed.rs
deleted file mode 100644
index da453fa..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRecipRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestHalfRecip.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrt.java
deleted file mode 100644
index 5cd4e90..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrt.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestHalfRsqrt extends RSBaseCompute {
-
-    private ScriptC_TestHalfRsqrt script;
-    private ScriptC_TestHalfRsqrtRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestHalfRsqrt(mRS);
-        scriptRelaxed = new ScriptC_TestHalfRsqrtRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkHalfRsqrtFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xad5e977ec00f0bf2l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testHalfRsqrtFloatFloat(inV, out);
-            verifyResultsHalfRsqrtFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfRsqrtFloatFloat(inV, out);
-            verifyResultsHalfRsqrtFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfRsqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfRsqrtFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHalfRsqrtFloat2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x300ee7bff12787c6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testHalfRsqrtFloat2Float2(inV, out);
-            verifyResultsHalfRsqrtFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfRsqrtFloat2Float2(inV, out);
-            verifyResultsHalfRsqrtFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfRsqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfRsqrtFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHalfRsqrtFloat3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3010b0dae742a8a4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testHalfRsqrtFloat3Float3(inV, out);
-            verifyResultsHalfRsqrtFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfRsqrtFloat3Float3(inV, out);
-            verifyResultsHalfRsqrtFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfRsqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfRsqrtFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHalfRsqrtFloat4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x301279f5dd5dc982l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testHalfRsqrtFloat4Float4(inV, out);
-            verifyResultsHalfRsqrtFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfRsqrtFloat4Float4(inV, out);
-            verifyResultsHalfRsqrtFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfRsqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfRsqrtFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testHalfRsqrt() {
-        checkHalfRsqrtFloatFloat();
-        checkHalfRsqrtFloat2Float2();
-        checkHalfRsqrtFloat3Float3();
-        checkHalfRsqrtFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrt.rs
deleted file mode 100644
index 27840d1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrt.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testHalfRsqrtFloatFloat(float inV) {
-    return half_rsqrt(inV);
-}
-
-float2 __attribute__((kernel)) testHalfRsqrtFloat2Float2(float2 inV) {
-    return half_rsqrt(inV);
-}
-
-float3 __attribute__((kernel)) testHalfRsqrtFloat3Float3(float3 inV) {
-    return half_rsqrt(inV);
-}
-
-float4 __attribute__((kernel)) testHalfRsqrtFloat4Float4(float4 inV) {
-    return half_rsqrt(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrtRelaxed.rs
deleted file mode 100644
index 4f94200..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfRsqrtRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestHalfRsqrt.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrt.java
deleted file mode 100644
index b57291d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrt.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestHalfSqrt extends RSBaseCompute {
-
-    private ScriptC_TestHalfSqrt script;
-    private ScriptC_TestHalfSqrtRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestHalfSqrt(mRS);
-        scriptRelaxed = new ScriptC_TestHalfSqrtRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkHalfSqrtFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8be766c7a15db5fal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testHalfSqrtFloatFloat(inV, out);
-            verifyResultsHalfSqrtFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfSqrtFloatFloat(inV, out);
-            verifyResultsHalfSqrtFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfSqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfSqrtFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHalfSqrtFloat2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7a300d2342519b8el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testHalfSqrtFloat2Float2(inV, out);
-            verifyResultsHalfSqrtFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfSqrtFloat2Float2(inV, out);
-            verifyResultsHalfSqrtFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfSqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfSqrtFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHalfSqrtFloat3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7a31d63e386cbc6cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testHalfSqrtFloat3Float3(inV, out);
-            verifyResultsHalfSqrtFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfSqrtFloat3Float3(inV, out);
-            verifyResultsHalfSqrtFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfSqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfSqrtFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHalfSqrtFloat4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7a339f592e87dd4al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testHalfSqrtFloat4Float4(inV, out);
-            verifyResultsHalfSqrtFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testHalfSqrtFloat4Float4(inV, out);
-            verifyResultsHalfSqrtFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHalfSqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHalfSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHalfSqrtFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testHalfSqrt() {
-        checkHalfSqrtFloatFloat();
-        checkHalfSqrtFloat2Float2();
-        checkHalfSqrtFloat3Float3();
-        checkHalfSqrtFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrt.rs
deleted file mode 100644
index d785e44..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrt.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testHalfSqrtFloatFloat(float inV) {
-    return half_sqrt(inV);
-}
-
-float2 __attribute__((kernel)) testHalfSqrtFloat2Float2(float2 inV) {
-    return half_sqrt(inV);
-}
-
-float3 __attribute__((kernel)) testHalfSqrtFloat3Float3(float3 inV) {
-    return half_sqrt(inV);
-}
-
-float4 __attribute__((kernel)) testHalfSqrtFloat4Float4(float4 inV) {
-    return half_sqrt(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrtRelaxed.rs
deleted file mode 100644
index 46b979d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHalfSqrtRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestHalfSqrt.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHypot.java b/tests/tests/renderscript/src/android/renderscript/cts/TestHypot.java
deleted file mode 100644
index 8aecdcd..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHypot.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestHypot extends RSBaseCompute {
-
-    private ScriptC_TestHypot script;
-    private ScriptC_TestHypotRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestHypot(mRS);
-        scriptRelaxed = new ScriptC_TestHypotRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkHypotFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7deb65e7738c74dbl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7deb65e7738c74dcl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testHypotFloatFloatFloat(inX, out);
-            verifyResultsHypotFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testHypotFloatFloatFloat(inX, out);
-            verifyResultsHypotFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHypotFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHypot(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHypotFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHypotFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x14f3c91a62f71c5dl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x14f3c91a62f71c5el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testHypotFloat2Float2Float2(inX, out);
-            verifyResultsHypotFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testHypotFloat2Float2Float2(inX, out);
-            verifyResultsHypotFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHypotFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHypot(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHypotFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHypotFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6958a73a64d51dfel, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6958a73a64d51dffl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testHypotFloat3Float3Float3(inX, out);
-            verifyResultsHypotFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testHypotFloat3Float3Float3(inX, out);
-            verifyResultsHypotFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHypotFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHypot(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHypotFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkHypotFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbdbd855a66b31f9fl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbdbd855a66b31fa0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testHypotFloat4Float4Float4(inX, out);
-            verifyResultsHypotFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testHypotFloat4Float4Float4(inX, out);
-            verifyResultsHypotFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsHypotFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeHypot(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkHypotFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testHypot() {
-        checkHypotFloatFloatFloat();
-        checkHypotFloat2Float2Float2();
-        checkHypotFloat3Float3Float3();
-        checkHypotFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHypot.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestHypot.rs
deleted file mode 100644
index 9425121..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHypot.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testHypotFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return hypot(inX, inY);
-}
-
-float2 __attribute__((kernel)) testHypotFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return hypot(inX, inY);
-}
-
-float3 __attribute__((kernel)) testHypotFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return hypot(inX, inY);
-}
-
-float4 __attribute__((kernel)) testHypotFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return hypot(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestHypotRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestHypotRelaxed.rs
deleted file mode 100644
index 15d02f3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestHypotRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestHypot.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestIlogb.java b/tests/tests/renderscript/src/android/renderscript/cts/TestIlogb.java
deleted file mode 100644
index 9bac16f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestIlogb.java
+++ /dev/null
@@ -1,248 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestIlogb extends RSBaseCompute {
-
-    private ScriptC_TestIlogb script;
-    private ScriptC_TestIlogbRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestIlogb(mRS);
-        scriptRelaxed = new ScriptC_TestIlogbRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatInt {
-        public float in;
-        public int out;
-    }
-
-    private void checkIlogbFloatInt() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc0c48da27f084aefl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            script.forEach_testIlogbFloatInt(in, out);
-            verifyResultsIlogbFloatInt(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloatInt: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testIlogbFloatInt(in, out);
-            verifyResultsIlogbFloatInt(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloatInt: " + e.toString());
-        }
-    }
-
-    private void verifyResultsIlogbFloatInt(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatInt args = new ArgumentsFloatInt();
-                args.in = arrayIn[i];
-                // Extract the outputs.
-                args.out = arrayOut[i * 1 + j];
-                // Ask the CoreMathVerifier to validate.
-                String errorMessage = CoreMathVerifier.verifyIlogb(args);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkIlogbFloatInt" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkIlogbFloat2Int2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4ba2fa846382ada1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.forEach_testIlogbFloat2Int2(in, out);
-            verifyResultsIlogbFloat2Int2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testIlogbFloat2Int2(in, out);
-            verifyResultsIlogbFloat2Int2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsIlogbFloat2Int2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatInt args = new ArgumentsFloatInt();
-                args.in = arrayIn[i * 2 + j];
-                // Extract the outputs.
-                args.out = arrayOut[i * 2 + j];
-                // Ask the CoreMathVerifier to validate.
-                String errorMessage = CoreMathVerifier.verifyIlogb(args);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkIlogbFloat2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkIlogbFloat3Int3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4ba2fa85dc4b0d43l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.forEach_testIlogbFloat3Int3(in, out);
-            verifyResultsIlogbFloat3Int3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testIlogbFloat3Int3(in, out);
-            verifyResultsIlogbFloat3Int3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsIlogbFloat3Int3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatInt args = new ArgumentsFloatInt();
-                args.in = arrayIn[i * 4 + j];
-                // Extract the outputs.
-                args.out = arrayOut[i * 4 + j];
-                // Ask the CoreMathVerifier to validate.
-                String errorMessage = CoreMathVerifier.verifyIlogb(args);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkIlogbFloat3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkIlogbFloat4Int4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4ba2fa8755136ce5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.forEach_testIlogbFloat4Int4(in, out);
-            verifyResultsIlogbFloat4Int4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testIlogbFloat4Int4(in, out);
-            verifyResultsIlogbFloat4Int4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsIlogbFloat4Int4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatInt args = new ArgumentsFloatInt();
-                args.in = arrayIn[i * 4 + j];
-                // Extract the outputs.
-                args.out = arrayOut[i * 4 + j];
-                // Ask the CoreMathVerifier to validate.
-                String errorMessage = CoreMathVerifier.verifyIlogb(args);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkIlogbFloat4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testIlogb() {
-        checkIlogbFloatInt();
-        checkIlogbFloat2Int2();
-        checkIlogbFloat3Int3();
-        checkIlogbFloat4Int4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestIlogb.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestIlogb.rs
deleted file mode 100644
index d9d62ed..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestIlogb.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-int __attribute__((kernel)) testIlogbFloatInt(float in) {
-    return ilogb(in);
-}
-
-int2 __attribute__((kernel)) testIlogbFloat2Int2(float2 in) {
-    return ilogb(in);
-}
-
-int3 __attribute__((kernel)) testIlogbFloat3Int3(float3 in) {
-    return ilogb(in);
-}
-
-int4 __attribute__((kernel)) testIlogbFloat4Int4(float4 in) {
-    return ilogb(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestIlogbRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestIlogbRelaxed.rs
deleted file mode 100644
index 6a60e53c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestIlogbRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestIlogb.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLdexp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLdexp.java
deleted file mode 100644
index 3f3aee9..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLdexp.java
+++ /dev/null
@@ -1,528 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestLdexp extends RSBaseCompute {
-
-    private ScriptC_TestLdexp script;
-    private ScriptC_TestLdexpRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestLdexp(mRS);
-        scriptRelaxed = new ScriptC_TestLdexpRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatIntFloat {
-        public float inX;
-        public int inY;
-        public Target.Floaty out;
-    }
-
-    private void checkLdexpFloatIntFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdeada0999238fe8bl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xdeada0999238fe8cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testLdexpFloatIntFloat(inX, out);
-            verifyResultsLdexpFloatIntFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloatIntFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testLdexpFloatIntFloat(inX, out);
-            verifyResultsLdexpFloatIntFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloatIntFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLdexpFloatIntFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLdexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLdexpFloatIntFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLdexpFloat2Int2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x5492762140d0ca17l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x5492762140d0ca18l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testLdexpFloat2Int2Float2(inX, out);
-            verifyResultsLdexpFloat2Int2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2Int2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testLdexpFloat2Int2Float2(inX, out);
-            verifyResultsLdexpFloat2Int2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2Int2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLdexpFloat2Int2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLdexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLdexpFloat2Int2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLdexpFloat3Int3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7a48b484368336d0l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x7a48b484368336d1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testLdexpFloat3Int3Float3(inX, out);
-            verifyResultsLdexpFloat3Int3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3Int3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testLdexpFloat3Int3Float3(inX, out);
-            verifyResultsLdexpFloat3Int3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3Int3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLdexpFloat3Int3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLdexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLdexpFloat3Int3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLdexpFloat4Int4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9ffef2e72c35a389l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x9ffef2e72c35a38al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testLdexpFloat4Int4Float4(inX, out);
-            verifyResultsLdexpFloat4Int4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4Int4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testLdexpFloat4Int4Float4(inX, out);
-            verifyResultsLdexpFloat4Int4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4Int4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLdexpFloat4Int4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLdexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLdexpFloat4Int4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLdexpFloat2IntFloat2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa2b6e0c39777b8c1l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xa2b6e0c39777b8c2l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testLdexpFloat2IntFloat2(inX, out);
-            verifyResultsLdexpFloat2IntFloat2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2IntFloat2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testLdexpFloat2IntFloat2(inX, out);
-            verifyResultsLdexpFloat2IntFloat2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2IntFloat2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLdexpFloat2IntFloat2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLdexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLdexpFloat2IntFloat2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLdexpFloat3IntFloat3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcd4401424a114a65l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xcd4401424a114a66l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testLdexpFloat3IntFloat3(inX, out);
-            verifyResultsLdexpFloat3IntFloat3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3IntFloat3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testLdexpFloat3IntFloat3(inX, out);
-            verifyResultsLdexpFloat3IntFloat3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3IntFloat3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLdexpFloat3IntFloat3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLdexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLdexpFloat3IntFloat3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLdexpFloat4IntFloat4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf7d121c0fcaadc09l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xf7d121c0fcaadc0al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testLdexpFloat4IntFloat4(inX, out);
-            verifyResultsLdexpFloat4IntFloat4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4IntFloat4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testLdexpFloat4IntFloat4(inX, out);
-            verifyResultsLdexpFloat4IntFloat4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4IntFloat4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLdexpFloat4IntFloat4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLdexp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLdexpFloat4IntFloat4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testLdexp() {
-        checkLdexpFloatIntFloat();
-        checkLdexpFloat2Int2Float2();
-        checkLdexpFloat3Int3Float3();
-        checkLdexpFloat4Int4Float4();
-        checkLdexpFloat2IntFloat2();
-        checkLdexpFloat3IntFloat3();
-        checkLdexpFloat4IntFloat4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLdexp.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLdexp.rs
deleted file mode 100644
index e8b05f2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLdexp.rs
+++ /dev/null
@@ -1,57 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testLdexpFloatIntFloat(float inX, unsigned int x) {
-    int inY = rsGetElementAt_int(gAllocInY, x);
-    return ldexp(inX, inY);
-}
-
-float2 __attribute__((kernel)) testLdexpFloat2Int2Float2(float2 inX, unsigned int x) {
-    int2 inY = rsGetElementAt_int2(gAllocInY, x);
-    return ldexp(inX, inY);
-}
-
-float3 __attribute__((kernel)) testLdexpFloat3Int3Float3(float3 inX, unsigned int x) {
-    int3 inY = rsGetElementAt_int3(gAllocInY, x);
-    return ldexp(inX, inY);
-}
-
-float4 __attribute__((kernel)) testLdexpFloat4Int4Float4(float4 inX, unsigned int x) {
-    int4 inY = rsGetElementAt_int4(gAllocInY, x);
-    return ldexp(inX, inY);
-}
-
-float2 __attribute__((kernel)) testLdexpFloat2IntFloat2(float2 inX, unsigned int x) {
-    int inY = rsGetElementAt_int(gAllocInY, x);
-    return ldexp(inX, inY);
-}
-
-float3 __attribute__((kernel)) testLdexpFloat3IntFloat3(float3 inX, unsigned int x) {
-    int inY = rsGetElementAt_int(gAllocInY, x);
-    return ldexp(inX, inY);
-}
-
-float4 __attribute__((kernel)) testLdexpFloat4IntFloat4(float4 inX, unsigned int x) {
-    int inY = rsGetElementAt_int(gAllocInY, x);
-    return ldexp(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLdexpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLdexpRelaxed.rs
deleted file mode 100644
index ee9f5cf..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLdexpRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestLdexp.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLength.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLength.java
deleted file mode 100644
index 2d89536..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLength.java
+++ /dev/null
@@ -1,300 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestLength extends RSBaseCompute {
-
-    private ScriptC_TestLength script;
-    private ScriptC_TestLengthRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestLength(mRS);
-        scriptRelaxed = new ScriptC_TestLengthRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkLengthFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8119352509f7cc9fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLengthFloatFloat(inV, out);
-            verifyResultsLengthFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLengthFloatFloat(inV, out);
-            verifyResultsLengthFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLengthFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inV: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkLengthFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloat {
-        public float[] inV;
-        public Target.Floaty out;
-    }
-
-    private void checkLengthFloat2Float() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xaf3b0f345dd9595dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLengthFloat2Float(inV, out);
-            verifyResultsLengthFloat2Float(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat2Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLengthFloat2Float(inV, out);
-            verifyResultsLengthFloat2Float(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat2Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLengthFloat2Float(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[2];
-            // Fill args with the input values
-            for (int j = 0; j < 2 ; j++) {
-                args.inV[j] = arrayInV[i * 2 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkLengthFloat2Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkLengthFloat3Float() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xaf3b19d5bcdfe7bel, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLengthFloat3Float(inV, out);
-            verifyResultsLengthFloat3Float(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat3Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLengthFloat3Float(inV, out);
-            verifyResultsLengthFloat3Float(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat3Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLengthFloat3Float(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[3];
-            // Fill args with the input values
-            for (int j = 0; j < 3 ; j++) {
-                args.inV[j] = arrayInV[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkLengthFloat3Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkLengthFloat4Float() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xaf3b24771be6761fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLengthFloat4Float(inV, out);
-            verifyResultsLengthFloat4Float(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat4Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLengthFloat4Float(inV, out);
-            verifyResultsLengthFloat4Float(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat4Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLengthFloat4Float(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[4];
-            // Fill args with the input values
-            for (int j = 0; j < 4 ; j++) {
-                args.inV[j] = arrayInV[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkLengthFloat4Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testLength() {
-        checkLengthFloatFloat();
-        checkLengthFloat2Float();
-        checkLengthFloat3Float();
-        checkLengthFloat4Float();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLength.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLength.rs
deleted file mode 100644
index 3239dbd..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLength.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testLengthFloatFloat(float inV) {
-    return length(inV);
-}
-
-float __attribute__((kernel)) testLengthFloat2Float(float2 inV) {
-    return length(inV);
-}
-
-float __attribute__((kernel)) testLengthFloat3Float(float3 inV) {
-    return length(inV);
-}
-
-float __attribute__((kernel)) testLengthFloat4Float(float4 inV) {
-    return length(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLengthRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLengthRelaxed.rs
deleted file mode 100644
index 12eba8b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLengthRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestLength.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLgamma.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLgamma.java
deleted file mode 100644
index 113df19..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLgamma.java
+++ /dev/null
@@ -1,538 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestLgamma extends RSBaseCompute {
-
-    private ScriptC_TestLgamma script;
-    private ScriptC_TestLgammaRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestLgamma(mRS);
-        scriptRelaxed = new ScriptC_TestLgammaRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkLgammaFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe748c67429cab138l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLgammaFloatFloat(in, out);
-            verifyResultsLgammaFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLgammaFloatFloat(in, out);
-            verifyResultsLgammaFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLgammaFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLgamma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLgammaFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLgammaFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7ca07efd8a327894l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testLgammaFloat2Float2(in, out);
-            verifyResultsLgammaFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testLgammaFloat2Float2(in, out);
-            verifyResultsLgammaFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLgammaFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLgamma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLgammaFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLgammaFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7ca0899ee9390e2el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testLgammaFloat3Float3(in, out);
-            verifyResultsLgammaFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testLgammaFloat3Float3(in, out);
-            verifyResultsLgammaFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLgammaFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLgamma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLgammaFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLgammaFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7ca09440483fa3c8l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testLgammaFloat4Float4(in, out);
-            verifyResultsLgammaFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testLgammaFloat4Float4(in, out);
-            verifyResultsLgammaFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLgammaFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLgamma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLgammaFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsFloatIntFloat {
-        public float inX;
-        public int outY;
-        public float out;
-    }
-
-    private void checkLgammaFloatIntFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2a62d992979c4bb9l, false);
-        try {
-            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocOutY(outY);
-            script.forEach_testLgammaFloatIntFloat(inX, out);
-            verifyResultsLgammaFloatIntFloat(inX, outY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatIntFloat: " + e.toString());
-        }
-        try {
-            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutY(outY);
-            scriptRelaxed.forEach_testLgammaFloatIntFloat(inX, out);
-            verifyResultsLgammaFloatIntFloat(inX, outY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatIntFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLgammaFloatIntFloat(Allocation inX, Allocation outY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        int[] arrayOutY = new int[INPUTSIZE * 1];
-        outY.copyTo(arrayOutY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i];
-                // Extract the outputs.
-                args.outY = arrayOutY[i * 1 + j];
-                args.out = arrayOut[i * 1 + j];
-                // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
-                String errorMessage = CoreMathVerifier.verifyLgamma(args, target);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Output outY: ");
-                    message.append(String.format("%d", args.outY));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(Float.toString(args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkLgammaFloatIntFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLgammaFloat2Int2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x409fb9a5984bcf81l, false);
-        try {
-            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocOutY(outY);
-            script.forEach_testLgammaFloat2Int2Float2(inX, out);
-            verifyResultsLgammaFloat2Int2Float2(inX, outY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Int2Float2: " + e.toString());
-        }
-        try {
-            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutY(outY);
-            scriptRelaxed.forEach_testLgammaFloat2Int2Float2(inX, out);
-            verifyResultsLgammaFloat2Int2Float2(inX, outY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Int2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLgammaFloat2Int2Float2(Allocation inX, Allocation outY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        int[] arrayOutY = new int[INPUTSIZE * 2];
-        outY.copyTo(arrayOutY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 2 + j];
-                // Extract the outputs.
-                args.outY = arrayOutY[i * 2 + j];
-                args.out = arrayOut[i * 2 + j];
-                // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
-                String errorMessage = CoreMathVerifier.verifyLgamma(args, target);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Output outY: ");
-                    message.append(String.format("%d", args.outY));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(Float.toString(args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkLgammaFloat2Int2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLgammaFloat3Int3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6655f8088dfe3c3al, false);
-        try {
-            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocOutY(outY);
-            script.forEach_testLgammaFloat3Int3Float3(inX, out);
-            verifyResultsLgammaFloat3Int3Float3(inX, outY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Int3Float3: " + e.toString());
-        }
-        try {
-            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutY(outY);
-            scriptRelaxed.forEach_testLgammaFloat3Int3Float3(inX, out);
-            verifyResultsLgammaFloat3Int3Float3(inX, outY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Int3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLgammaFloat3Int3Float3(Allocation inX, Allocation outY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        int[] arrayOutY = new int[INPUTSIZE * 4];
-        outY.copyTo(arrayOutY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 4 + j];
-                // Extract the outputs.
-                args.outY = arrayOutY[i * 4 + j];
-                args.out = arrayOut[i * 4 + j];
-                // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
-                String errorMessage = CoreMathVerifier.verifyLgamma(args, target);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Output outY: ");
-                    message.append(String.format("%d", args.outY));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(Float.toString(args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkLgammaFloat3Int3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLgammaFloat4Int4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8c0c366b83b0a8f3l, false);
-        try {
-            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocOutY(outY);
-            script.forEach_testLgammaFloat4Int4Float4(inX, out);
-            verifyResultsLgammaFloat4Int4Float4(inX, outY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Int4Float4: " + e.toString());
-        }
-        try {
-            Allocation outY = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutY(outY);
-            scriptRelaxed.forEach_testLgammaFloat4Int4Float4(inX, out);
-            verifyResultsLgammaFloat4Int4Float4(inX, outY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Int4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLgammaFloat4Int4Float4(Allocation inX, Allocation outY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        int[] arrayOutY = new int[INPUTSIZE * 4];
-        outY.copyTo(arrayOutY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 4 + j];
-                // Extract the outputs.
-                args.outY = arrayOutY[i * 4 + j];
-                args.out = arrayOut[i * 4 + j];
-                // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
-                String errorMessage = CoreMathVerifier.verifyLgamma(args, target);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Output outY: ");
-                    message.append(String.format("%d", args.outY));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(Float.toString(args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkLgammaFloat4Int4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testLgamma() {
-        checkLgammaFloatFloat();
-        checkLgammaFloat2Float2();
-        checkLgammaFloat3Float3();
-        checkLgammaFloat4Float4();
-        checkLgammaFloatIntFloat();
-        checkLgammaFloat2Int2Float2();
-        checkLgammaFloat3Int3Float3();
-        checkLgammaFloat4Int4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLgamma.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLgamma.rs
deleted file mode 100644
index b39e592..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLgamma.rs
+++ /dev/null
@@ -1,66 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testLgammaFloatFloat(float in) {
-    return lgamma(in);
-}
-
-float2 __attribute__((kernel)) testLgammaFloat2Float2(float2 in) {
-    return lgamma(in);
-}
-
-float3 __attribute__((kernel)) testLgammaFloat3Float3(float3 in) {
-    return lgamma(in);
-}
-
-float4 __attribute__((kernel)) testLgammaFloat4Float4(float4 in) {
-    return lgamma(in);
-}
-rs_allocation gAllocOutY;
-
-float __attribute__((kernel)) testLgammaFloatIntFloat(float inX, unsigned int x) {
-    int outY = 0;
-    float out = lgamma(inX, &outY);
-    rsSetElementAt_int(gAllocOutY, outY, x);
-    return out;
-}
-
-float2 __attribute__((kernel)) testLgammaFloat2Int2Float2(float2 inX, unsigned int x) {
-    int2 outY = 0;
-    float2 out = lgamma(inX, &outY);
-    rsSetElementAt_int2(gAllocOutY, outY, x);
-    return out;
-}
-
-float3 __attribute__((kernel)) testLgammaFloat3Int3Float3(float3 inX, unsigned int x) {
-    int3 outY = 0;
-    float3 out = lgamma(inX, &outY);
-    rsSetElementAt_int3(gAllocOutY, outY, x);
-    return out;
-}
-
-float4 __attribute__((kernel)) testLgammaFloat4Int4Float4(float4 inX, unsigned int x) {
-    int4 outY = 0;
-    float4 out = lgamma(inX, &outY);
-    rsSetElementAt_int4(gAllocOutY, outY, x);
-    return out;
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLgammaRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLgammaRelaxed.rs
deleted file mode 100644
index a259576..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLgammaRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestLgamma.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLog.java
deleted file mode 100644
index 8b4717c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestLog extends RSBaseCompute {
-
-    private ScriptC_TestLog script;
-    private ScriptC_TestLogRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestLog(mRS);
-        scriptRelaxed = new ScriptC_TestLogRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkLogFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x371a946136907325l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLogFloatFloat(in, out);
-            verifyResultsLogFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLogFloatFloat(in, out);
-            verifyResultsLogFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLogFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLogFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLogFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfef8d41eca882159l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testLogFloat2Float2(in, out);
-            verifyResultsLogFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testLogFloat2Float2(in, out);
-            verifyResultsLogFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLogFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLogFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLogFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfef8dec0298eb6f3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testLogFloat3Float3(in, out);
-            verifyResultsLogFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testLogFloat3Float3(in, out);
-            verifyResultsLogFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLogFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLogFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLogFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfef8e96188954c8dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testLogFloat4Float4(in, out);
-            verifyResultsLogFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testLogFloat4Float4(in, out);
-            verifyResultsLogFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLogFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLogFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testLog() {
-        checkLogFloatFloat();
-        checkLogFloat2Float2();
-        checkLogFloat3Float3();
-        checkLogFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLog.rs
deleted file mode 100644
index 4261b61..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testLogFloatFloat(float in) {
-    return log(in);
-}
-
-float2 __attribute__((kernel)) testLogFloat2Float2(float2 in) {
-    return log(in);
-}
-
-float3 __attribute__((kernel)) testLogFloat3Float3(float3 in) {
-    return log(in);
-}
-
-float4 __attribute__((kernel)) testLogFloat4Float4(float4 in) {
-    return log(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog10.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLog10.java
deleted file mode 100644
index 5928090..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog10.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestLog10 extends RSBaseCompute {
-
-    private ScriptC_TestLog10 script;
-    private ScriptC_TestLog10Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestLog10(mRS);
-        scriptRelaxed = new ScriptC_TestLog10Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkLog10FloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe09b228ed779b7a0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLog10FloatFloat(in, out);
-            verifyResultsLog10FloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLog10FloatFloat(in, out);
-            verifyResultsLog10FloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog10FloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog10FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLog10Float2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x407bbbadff57bdbcl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testLog10Float2Float2(in, out);
-            verifyResultsLog10Float2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testLog10Float2Float2(in, out);
-            verifyResultsLog10Float2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog10Float2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog10Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLog10Float3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x407bc64f5e5e5356l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testLog10Float3Float3(in, out);
-            verifyResultsLog10Float3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testLog10Float3Float3(in, out);
-            verifyResultsLog10Float3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog10Float3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog10Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLog10Float4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x407bd0f0bd64e8f0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testLog10Float4Float4(in, out);
-            verifyResultsLog10Float4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testLog10Float4Float4(in, out);
-            verifyResultsLog10Float4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog10Float4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog10Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testLog10() {
-        checkLog10FloatFloat();
-        checkLog10Float2Float2();
-        checkLog10Float3Float3();
-        checkLog10Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog10.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLog10.rs
deleted file mode 100644
index 18fb3c3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog10.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testLog10FloatFloat(float in) {
-    return log10(in);
-}
-
-float2 __attribute__((kernel)) testLog10Float2Float2(float2 in) {
-    return log10(in);
-}
-
-float3 __attribute__((kernel)) testLog10Float3Float3(float3 in) {
-    return log10(in);
-}
-
-float4 __attribute__((kernel)) testLog10Float4Float4(float4 in) {
-    return log10(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog10Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLog10Relaxed.rs
deleted file mode 100644
index c0c47f3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog10Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestLog10.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog1p.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLog1p.java
deleted file mode 100644
index 019cffb..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog1p.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestLog1p extends RSBaseCompute {
-
-    private ScriptC_TestLog1p script;
-    private ScriptC_TestLog1pRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestLog1p(mRS);
-        scriptRelaxed = new ScriptC_TestLog1pRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkLog1pFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x83e3423b7d907be0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLog1pFloatFloat(in, out);
-            verifyResultsLog1pFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLog1pFloatFloat(in, out);
-            verifyResultsLog1pFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog1pFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog1p(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog1pFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLog1pFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x946881a999c72ffcl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testLog1pFloat2Float2(in, out);
-            verifyResultsLog1pFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testLog1pFloat2Float2(in, out);
-            verifyResultsLog1pFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog1pFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog1p(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog1pFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLog1pFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x94688c4af8cdc596l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testLog1pFloat3Float3(in, out);
-            verifyResultsLog1pFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testLog1pFloat3Float3(in, out);
-            verifyResultsLog1pFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog1pFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog1p(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog1pFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLog1pFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x946896ec57d45b30l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testLog1pFloat4Float4(in, out);
-            verifyResultsLog1pFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testLog1pFloat4Float4(in, out);
-            verifyResultsLog1pFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog1pFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog1p(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog1pFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testLog1p() {
-        checkLog1pFloatFloat();
-        checkLog1pFloat2Float2();
-        checkLog1pFloat3Float3();
-        checkLog1pFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog1p.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLog1p.rs
deleted file mode 100644
index bc5577e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog1p.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testLog1pFloatFloat(float in) {
-    return log1p(in);
-}
-
-float2 __attribute__((kernel)) testLog1pFloat2Float2(float2 in) {
-    return log1p(in);
-}
-
-float3 __attribute__((kernel)) testLog1pFloat3Float3(float3 in) {
-    return log1p(in);
-}
-
-float4 __attribute__((kernel)) testLog1pFloat4Float4(float4 in) {
-    return log1p(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog1pRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLog1pRelaxed.rs
deleted file mode 100644
index 3136d9e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog1pRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestLog1p.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLog2.java
deleted file mode 100644
index 92a4985..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog2.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestLog2 extends RSBaseCompute {
-
-    private ScriptC_TestLog2 script;
-    private ScriptC_TestLog2Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestLog2(mRS);
-        scriptRelaxed = new ScriptC_TestLog2Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkLog2FloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x390bea9a53d34bfl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLog2FloatFloat(in, out);
-            verifyResultsLog2FloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLog2FloatFloat(in, out);
-            verifyResultsLog2FloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog2FloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog2FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLog2Float2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc0703946284a72a3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testLog2Float2Float2(in, out);
-            verifyResultsLog2Float2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testLog2Float2Float2(in, out);
-            verifyResultsLog2Float2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog2Float2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLog2Float3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc07043e78751083dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testLog2Float3Float3(in, out);
-            verifyResultsLog2Float3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testLog2Float3Float3(in, out);
-            verifyResultsLog2Float3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog2Float3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog2Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLog2Float4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc0704e88e6579dd7l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testLog2Float4Float4(in, out);
-            verifyResultsLog2Float4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testLog2Float4Float4(in, out);
-            verifyResultsLog2Float4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLog2Float4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLog2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLog2Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testLog2() {
-        checkLog2FloatFloat();
-        checkLog2Float2Float2();
-        checkLog2Float3Float3();
-        checkLog2Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog2.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLog2.rs
deleted file mode 100644
index 4cf8ef2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog2.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testLog2FloatFloat(float in) {
-    return log2(in);
-}
-
-float2 __attribute__((kernel)) testLog2Float2Float2(float2 in) {
-    return log2(in);
-}
-
-float3 __attribute__((kernel)) testLog2Float3Float3(float3 in) {
-    return log2(in);
-}
-
-float4 __attribute__((kernel)) testLog2Float4Float4(float4 in) {
-    return log2(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLog2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLog2Relaxed.rs
deleted file mode 100644
index e79f105..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLog2Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestLog2.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLogRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLogRelaxed.rs
deleted file mode 100644
index 3fed787..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLogRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestLog.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLogb.java b/tests/tests/renderscript/src/android/renderscript/cts/TestLogb.java
deleted file mode 100644
index 8679aa0..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLogb.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestLogb extends RSBaseCompute {
-
-    private ScriptC_TestLogb script;
-    private ScriptC_TestLogbRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestLogb(mRS);
-        scriptRelaxed = new ScriptC_TestLogbRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkLogbFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe06d66b21ce47efl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testLogbFloatFloat(in, out);
-            verifyResultsLogbFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testLogbFloatFloat(in, out);
-            verifyResultsLogbFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLogbFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLogb(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLogbFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLogbFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbf61cdc2dc1e0853l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testLogbFloat2Float2(in, out);
-            verifyResultsLogbFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testLogbFloat2Float2(in, out);
-            verifyResultsLogbFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLogbFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLogb(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLogbFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLogbFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbf61d8643b249dedl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testLogbFloat3Float3(in, out);
-            verifyResultsLogbFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testLogbFloat3Float3(in, out);
-            verifyResultsLogbFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLogbFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLogb(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLogbFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkLogbFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbf61e3059a2b3387l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testLogbFloat4Float4(in, out);
-            verifyResultsLogbFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testLogbFloat4Float4(in, out);
-            verifyResultsLogbFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsLogbFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeLogb(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkLogbFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testLogb() {
-        checkLogbFloatFloat();
-        checkLogbFloat2Float2();
-        checkLogbFloat3Float3();
-        checkLogbFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLogb.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLogb.rs
deleted file mode 100644
index 8317a22..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLogb.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testLogbFloatFloat(float in) {
-    return logb(in);
-}
-
-float2 __attribute__((kernel)) testLogbFloat2Float2(float2 in) {
-    return logb(in);
-}
-
-float3 __attribute__((kernel)) testLogbFloat3Float3(float3 in) {
-    return logb(in);
-}
-
-float4 __attribute__((kernel)) testLogbFloat4Float4(float4 in) {
-    return logb(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestLogbRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestLogbRelaxed.rs
deleted file mode 100644
index bcf84b7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestLogbRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestLogb.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMad.java b/tests/tests/renderscript/src/android/renderscript/cts/TestMad.java
deleted file mode 100644
index 0ac029c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMad.java
+++ /dev/null
@@ -1,366 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestMad extends RSBaseCompute {
-
-    private ScriptC_TestMad script;
-    private ScriptC_TestMadRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestMad(mRS);
-        scriptRelaxed = new ScriptC_TestMadRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloatFloat {
-        public float inA;
-        public float inB;
-        public float inC;
-        public Target.Floaty out;
-    }
-
-    private void checkMadFloatFloatFloatFloat() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb3b9b8429c37eacl, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb3b9b8429c37eadl, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb3b9b8429c37eael, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.set_gAllocInC(inC);
-            script.forEach_testMadFloatFloatFloatFloat(inA, out);
-            verifyResultsMadFloatFloatFloatFloat(inA, inB, inC, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloatFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.forEach_testMadFloatFloatFloatFloat(inA, out);
-            verifyResultsMadFloatFloatFloatFloat(inA, inB, inC, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloatFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMadFloatFloatFloatFloat(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 1];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 1];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 1];
-        inC.copyTo(arrayInC);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inA = arrayInA[i];
-                args.inB = arrayInB[i];
-                args.inC = arrayInC[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMad(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMadFloatFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMadFloat2Float2Float2Float2() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x44d6ec3d0f2030a4l, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x44d6ec3d0f2030a5l, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x44d6ec3d0f2030a6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.set_gAllocInC(inC);
-            script.forEach_testMadFloat2Float2Float2Float2(inA, out);
-            verifyResultsMadFloat2Float2Float2Float2(inA, inB, inC, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat2Float2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.forEach_testMadFloat2Float2Float2Float2(inA, out);
-            verifyResultsMadFloat2Float2Float2Float2(inA, inB, inC, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat2Float2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMadFloat2Float2Float2Float2(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 2];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 2];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 2];
-        inC.copyTo(arrayInC);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inA = arrayInA[i * 2 + j];
-                args.inB = arrayInB[i * 2 + j];
-                args.inC = arrayInC[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMad(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMadFloat2Float2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMadFloat3Float3Float3Float3() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1a508fd7e1876a40l, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1a508fd7e1876a41l, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1a508fd7e1876a42l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.set_gAllocInC(inC);
-            script.forEach_testMadFloat3Float3Float3Float3(inA, out);
-            verifyResultsMadFloat3Float3Float3Float3(inA, inB, inC, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat3Float3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.forEach_testMadFloat3Float3Float3Float3(inA, out);
-            verifyResultsMadFloat3Float3Float3Float3(inA, inB, inC, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat3Float3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMadFloat3Float3Float3Float3(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 4];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 4];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 4];
-        inC.copyTo(arrayInC);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inA = arrayInA[i * 4 + j];
-                args.inB = arrayInB[i * 4 + j];
-                args.inC = arrayInC[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMad(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMadFloat3Float3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMadFloat4Float4Float4Float4() {
-        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xefca3372b3eea3dcl, false);
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xefca3372b3eea3ddl, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xefca3372b3eea3del, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInB(inB);
-            script.set_gAllocInC(inC);
-            script.forEach_testMadFloat4Float4Float4Float4(inA, out);
-            verifyResultsMadFloat4Float4Float4Float4(inA, inB, inC, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat4Float4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInB(inB);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.forEach_testMadFloat4Float4Float4Float4(inA, out);
-            verifyResultsMadFloat4Float4Float4Float4(inA, inB, inC, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat4Float4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMadFloat4Float4Float4Float4(Allocation inA, Allocation inB, Allocation inC, Allocation out, boolean relaxed) {
-        float[] arrayInA = new float[INPUTSIZE * 4];
-        inA.copyTo(arrayInA);
-        float[] arrayInB = new float[INPUTSIZE * 4];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 4];
-        inC.copyTo(arrayInC);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inA = arrayInA[i * 4 + j];
-                args.inB = arrayInB[i * 4 + j];
-                args.inC = arrayInC[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMad(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inA: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inA, Float.floatToRawIntBits(args.inA), args.inA));
-                    message.append("\n");
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMadFloat4Float4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testMad() {
-        checkMadFloatFloatFloatFloat();
-        checkMadFloat2Float2Float2Float2();
-        checkMadFloat3Float3Float3Float3();
-        checkMadFloat4Float4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMad.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestMad.rs
deleted file mode 100644
index bcf908b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMad.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInB;
-rs_allocation gAllocInC;
-
-float __attribute__((kernel)) testMadFloatFloatFloatFloat(float inA, unsigned int x) {
-    float inB = rsGetElementAt_float(gAllocInB, x);
-    float inC = rsGetElementAt_float(gAllocInC, x);
-    return mad(inA, inB, inC);
-}
-
-float2 __attribute__((kernel)) testMadFloat2Float2Float2Float2(float2 inA, unsigned int x) {
-    float2 inB = rsGetElementAt_float2(gAllocInB, x);
-    float2 inC = rsGetElementAt_float2(gAllocInC, x);
-    return mad(inA, inB, inC);
-}
-
-float3 __attribute__((kernel)) testMadFloat3Float3Float3Float3(float3 inA, unsigned int x) {
-    float3 inB = rsGetElementAt_float3(gAllocInB, x);
-    float3 inC = rsGetElementAt_float3(gAllocInC, x);
-    return mad(inA, inB, inC);
-}
-
-float4 __attribute__((kernel)) testMadFloat4Float4Float4Float4(float4 inA, unsigned int x) {
-    float4 inB = rsGetElementAt_float4(gAllocInB, x);
-    float4 inC = rsGetElementAt_float4(gAllocInC, x);
-    return mad(inA, inB, inC);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMadRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestMadRelaxed.rs
deleted file mode 100644
index acec458..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMadRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestMad.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMax.java b/tests/tests/renderscript/src/android/renderscript/cts/TestMax.java
deleted file mode 100644
index e52ef48..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMax.java
+++ /dev/null
@@ -1,2485 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestMax extends RSBaseCompute {
-
-    private ScriptC_TestMax script;
-    private ScriptC_TestMaxRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestMax(mRS);
-        scriptRelaxed = new ScriptC_TestMaxRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float in;
-        public float in1;
-        public Target.Floaty out;
-    }
-
-    private void checkMaxFloatFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfb01ed3804837dddl, false);
-        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2952d868c2162450l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocIn1(in1);
-            script.forEach_testMaxFloatFloatFloat(in, out);
-            verifyResultsMaxFloatFloatFloat(in, in1, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocIn1(in1);
-            scriptRelaxed.forEach_testMaxFloatFloatFloat(in, out);
-            verifyResultsMaxFloatFloatFloat(in, in1, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxFloatFloatFloat(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayIn1 = new float[INPUTSIZE * 1];
-        in1.copyTo(arrayIn1);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.in = arrayIn[i];
-                args.in1 = arrayIn1[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Input in1: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxFloat2Float2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x63dc5a02b9d46a4bl, false);
-        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc6031e7536addacal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocIn1(in1);
-            script.forEach_testMaxFloat2Float2Float2(in, out);
-            verifyResultsMaxFloat2Float2Float2(in, in1, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocIn1(in1);
-            scriptRelaxed.forEach_testMaxFloat2Float2Float2(in, out);
-            verifyResultsMaxFloat2Float2Float2(in, in1, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxFloat2Float2Float2(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayIn1 = new float[INPUTSIZE * 2];
-        in1.copyTo(arrayIn1);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                args.in1 = arrayIn1[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Input in1: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxFloat3Float3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xb92c17bc0744bdael, false);
-        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1a67fc95388bdc6bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocIn1(in1);
-            script.forEach_testMaxFloat3Float3Float3(in, out);
-            verifyResultsMaxFloat3Float3Float3(in, in1, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocIn1(in1);
-            scriptRelaxed.forEach_testMaxFloat3Float3Float3(in, out);
-            verifyResultsMaxFloat3Float3Float3(in, in1, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxFloat3Float3Float3(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayIn1 = new float[INPUTSIZE * 4];
-        in1.copyTo(arrayIn1);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                args.in1 = arrayIn1[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Input in1: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxFloat4Float4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe7bd57554b51111l, false);
-        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6eccdab53a69de0cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocIn1(in1);
-            script.forEach_testMaxFloat4Float4Float4(in, out);
-            verifyResultsMaxFloat4Float4Float4(in, in1, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocIn1(in1);
-            scriptRelaxed.forEach_testMaxFloat4Float4Float4(in, out);
-            verifyResultsMaxFloat4Float4Float4(in, in1, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxFloat4Float4Float4(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayIn1 = new float[INPUTSIZE * 4];
-        in1.copyTo(arrayIn1);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                args.in1 = arrayIn1[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMax(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Input in1: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharCharChar {
-        public byte inV1;
-        public byte inV2;
-        public byte out;
-    }
-
-    private void checkMaxCharCharChar() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x91fcf329ccedf8al, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x91fcf329ccedf8bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxCharCharChar(inV1, out);
-            verifyResultsMaxCharCharChar(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxCharCharChar: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxCharCharChar(inV1, out);
-            verifyResultsMaxCharCharChar(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxCharCharChar: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxCharCharChar(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxCharCharChar" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxChar2Char2Char2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x12084b25952bc64l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x12084b25952bc65l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxChar2Char2Char2(inV1, out);
-            verifyResultsMaxChar2Char2Char2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar2Char2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxChar2Char2Char2(inV1, out);
-            verifyResultsMaxChar2Char2Char2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar2Char2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxChar2Char2Char2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxChar2Char2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxChar3Char3Char3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x567200e53e0a8f29l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x567200e53e0a8f2al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxChar3Char3Char3(inV1, out);
-            verifyResultsMaxChar3Char3Char3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar3Char3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxChar3Char3Char3(inV1, out);
-            verifyResultsMaxChar3Char3Char3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar3Char3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxChar3Char3Char3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxChar3Char3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxChar4Char4Char4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xabc37d1822c261eel, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xabc37d1822c261efl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxChar4Char4Char4(inV1, out);
-            verifyResultsMaxChar4Char4Char4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar4Char4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxChar4Char4Char4(inV1, out);
-            verifyResultsMaxChar4Char4Char4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar4Char4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxChar4Char4Char4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxChar4Char4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharUcharUchar {
-        public byte inV1;
-        public byte inV2;
-        public byte out;
-    }
-
-    private void checkMaxUcharUcharUchar() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x829ebf2e60c1bd47l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x829ebf2e60c1bd48l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUcharUcharUchar(inV1, out);
-            verifyResultsMaxUcharUcharUchar(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUcharUcharUchar: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUcharUcharUchar(inV1, out);
-            verifyResultsMaxUcharUcharUchar(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUcharUcharUchar: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUcharUcharUchar(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUcharUcharUchar" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUchar2Uchar2Uchar2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x75eda605e43f8b81l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x75eda605e43f8b82l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUchar2Uchar2Uchar2(inV1, out);
-            verifyResultsMaxUchar2Uchar2Uchar2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar2Uchar2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUchar2Uchar2Uchar2(inV1, out);
-            verifyResultsMaxUchar2Uchar2Uchar2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar2Uchar2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUchar2Uchar2Uchar2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUchar2Uchar2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUchar3Uchar3Uchar3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xa2def5663489d18cl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xa2def5663489d18dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUchar3Uchar3Uchar3(inV1, out);
-            verifyResultsMaxUchar3Uchar3Uchar3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar3Uchar3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUchar3Uchar3Uchar3(inV1, out);
-            verifyResultsMaxUchar3Uchar3Uchar3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar3Uchar3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUchar3Uchar3Uchar3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUchar3Uchar3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUchar4Uchar4Uchar4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xcfd044c684d41797l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xcfd044c684d41798l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUchar4Uchar4Uchar4(inV1, out);
-            verifyResultsMaxUchar4Uchar4Uchar4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar4Uchar4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUchar4Uchar4Uchar4(inV1, out);
-            verifyResultsMaxUchar4Uchar4Uchar4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar4Uchar4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUchar4Uchar4Uchar4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUchar4Uchar4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortShortShort {
-        public short inV1;
-        public short inV2;
-        public short out;
-    }
-
-    private void checkMaxShortShortShort() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x868a0cd65f7a4294l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x868a0cd65f7a4295l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxShortShortShort(inV1, out);
-            verifyResultsMaxShortShortShort(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShortShortShort: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxShortShortShort(inV1, out);
-            verifyResultsMaxShortShortShort(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShortShortShort: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxShortShortShort(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxShortShortShort" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxShort2Short2Short2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x3d46ae0799c33c02l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x3d46ae0799c33c03l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxShort2Short2Short2(inV1, out);
-            verifyResultsMaxShort2Short2Short2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort2Short2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxShort2Short2Short2(inV1, out);
-            verifyResultsMaxShort2Short2Short2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort2Short2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxShort2Short2Short2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxShort2Short2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxShort3Short3Short3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x6a37fd67ea0d820dl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x6a37fd67ea0d820el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxShort3Short3Short3(inV1, out);
-            verifyResultsMaxShort3Short3Short3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort3Short3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxShort3Short3Short3(inV1, out);
-            verifyResultsMaxShort3Short3Short3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort3Short3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxShort3Short3Short3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxShort3Short3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxShort4Short4Short4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x97294cc83a57c818l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x97294cc83a57c819l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxShort4Short4Short4(inV1, out);
-            verifyResultsMaxShort4Short4Short4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort4Short4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxShort4Short4Short4(inV1, out);
-            verifyResultsMaxShort4Short4Short4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort4Short4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxShort4Short4Short4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxShort4Short4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortUshortUshort {
-        public short inV1;
-        public short inV2;
-        public short out;
-    }
-
-    private void checkMaxUshortUshortUshort() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x1b9c47701effe051l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x1b9c47701effe052l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUshortUshortUshort(inV1, out);
-            verifyResultsMaxUshortUshortUshort(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshortUshortUshort: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUshortUshortUshort(inV1, out);
-            verifyResultsMaxUshortUshortUshort(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshortUshortUshort: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUshortUshortUshort(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUshortUshortUshort" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUshort2Ushort2Ushort2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xf42196a588de51bfl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xf42196a588de51c0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUshort2Ushort2Ushort2(inV1, out);
-            verifyResultsMaxUshort2Ushort2Ushort2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort2Ushort2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUshort2Ushort2Ushort2(inV1, out);
-            verifyResultsMaxUshort2Ushort2Ushort2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort2Ushort2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUshort2Ushort2Ushort2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUshort2Ushort2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUshort3Ushort3Ushort3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x71604884c752e61cl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x71604884c752e61dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUshort3Ushort3Ushort3(inV1, out);
-            verifyResultsMaxUshort3Ushort3Ushort3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort3Ushort3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUshort3Ushort3Ushort3(inV1, out);
-            verifyResultsMaxUshort3Ushort3Ushort3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort3Ushort3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUshort3Ushort3Ushort3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUshort3Ushort3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUshort4Ushort4Ushort4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xee9efa6405c77a79l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xee9efa6405c77a7al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUshort4Ushort4Ushort4(inV1, out);
-            verifyResultsMaxUshort4Ushort4Ushort4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort4Ushort4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUshort4Ushort4Ushort4(inV1, out);
-            verifyResultsMaxUshort4Ushort4Ushort4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort4Ushort4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUshort4Ushort4Ushort4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUshort4Ushort4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntIntInt {
-        public int inV1;
-        public int inV2;
-        public int out;
-    }
-
-    private void checkMaxIntIntInt() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x7413f465641a51bl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x7413f465641a51cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxIntIntInt(inV1, out);
-            verifyResultsMaxIntIntInt(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxIntIntInt: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxIntIntInt(inV1, out);
-            verifyResultsMaxIntIntInt(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxIntIntInt: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxIntIntInt(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxIntIntInt" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxInt2Int2Int2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x7bba1e4a83816bd5l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x7bba1e4a83816bd6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxInt2Int2Int2(inV1, out);
-            verifyResultsMaxInt2Int2Int2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt2Int2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxInt2Int2Int2(inV1, out);
-            verifyResultsMaxInt2Int2Int2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt2Int2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxInt2Int2Int2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxInt2Int2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxInt3Int3Int3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xa647496a95547ff8l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xa647496a95547ff9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxInt3Int3Int3(inV1, out);
-            verifyResultsMaxInt3Int3Int3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt3Int3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxInt3Int3Int3(inV1, out);
-            verifyResultsMaxInt3Int3Int3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt3Int3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxInt3Int3Int3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxInt3Int3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxInt4Int4Int4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd0d4748aa727941bl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd0d4748aa727941cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxInt4Int4Int4(inV1, out);
-            verifyResultsMaxInt4Int4Int4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt4Int4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxInt4Int4Int4(inV1, out);
-            verifyResultsMaxInt4Int4Int4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt4Int4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxInt4Int4Int4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxInt4Int4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintUintUint {
-        public int inV1;
-        public int inV2;
-        public int out;
-    }
-
-    private void checkMaxUintUintUint() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x75328d17808776cal, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x75328d17808776cbl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUintUintUint(inV1, out);
-            verifyResultsMaxUintUintUint(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUintUintUint: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUintUintUint(inV1, out);
-            verifyResultsMaxUintUintUint(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUintUintUint: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUintUintUint(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUintUintUint" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUint2Uint2Uint2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xcda90384705016a4l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xcda90384705016a5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUint2Uint2Uint2(inV1, out);
-            verifyResultsMaxUint2Uint2Uint2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint2Uint2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUint2Uint2Uint2(inV1, out);
-            verifyResultsMaxUint2Uint2Uint2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint2Uint2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUint2Uint2Uint2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUint2Uint2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUint3Uint3Uint3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x22fa7fb75507e969l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x22fa7fb75507e96al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUint3Uint3Uint3(inV1, out);
-            verifyResultsMaxUint3Uint3Uint3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint3Uint3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUint3Uint3Uint3(inV1, out);
-            verifyResultsMaxUint3Uint3Uint3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint3Uint3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUint3Uint3Uint3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUint3Uint3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUint4Uint4Uint4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x784bfbea39bfbc2el, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x784bfbea39bfbc2fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUint4Uint4Uint4(inV1, out);
-            verifyResultsMaxUint4Uint4Uint4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint4Uint4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUint4Uint4Uint4(inV1, out);
-            verifyResultsMaxUint4Uint4Uint4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint4Uint4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUint4Uint4Uint4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUint4Uint4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongLongLong {
-        public long inV1;
-        public long inV2;
-        public long out;
-    }
-
-    private void checkMaxLongLongLong() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0xe224db3c7ecb92e4l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0xe224db3c7ecb92e5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxLongLongLong(inV1, out);
-            verifyResultsMaxLongLongLong(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLongLongLong: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxLongLongLong(inV1, out);
-            verifyResultsMaxLongLongLong(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLongLongLong: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxLongLongLong(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxLongLongLong" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxLong2Long2Long2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x375f5f0ca264eb56l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x375f5f0ca264eb57l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxLong2Long2Long2(inV1, out);
-            verifyResultsMaxLong2Long2Long2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong2Long2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxLong2Long2Long2(inV1, out);
-            verifyResultsMaxLong2Long2Long2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong2Long2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxLong2Long2Long2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxLong2Long2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxLong3Long3Long3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x8cb0db3f871cbe1bl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x8cb0db3f871cbe1cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxLong3Long3Long3(inV1, out);
-            verifyResultsMaxLong3Long3Long3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong3Long3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxLong3Long3Long3(inV1, out);
-            verifyResultsMaxLong3Long3Long3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong3Long3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxLong3Long3Long3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxLong3Long3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxLong4Long4Long4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xe20257726bd490e0l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xe20257726bd490e1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxLong4Long4Long4(inV1, out);
-            verifyResultsMaxLong4Long4Long4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong4Long4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxLong4Long4Long4(inV1, out);
-            verifyResultsMaxLong4Long4Long4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong4Long4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxLong4Long4Long4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxLong4Long4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongUlongUlong {
-        public long inV1;
-        public long inV2;
-        public long out;
-    }
-
-    private void checkMaxUlongUlongUlong() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0xb38270e909275f1dl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0xb38270e909275f1el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUlongUlongUlong(inV1, out);
-            verifyResultsMaxUlongUlongUlong(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlongUlongUlong: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUlongUlongUlong(inV1, out);
-            verifyResultsMaxUlongUlongUlong(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlongUlongUlong: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUlongUlongUlong(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUlongUlongUlong" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUlong2Ulong2Ulong2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x7f6c5ec5fee1a8afl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x7f6c5ec5fee1a8b0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUlong2Ulong2Ulong2(inV1, out);
-            verifyResultsMaxUlong2Ulong2Ulong2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong2Ulong2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUlong2Ulong2Ulong2(inV1, out);
-            verifyResultsMaxUlong2Ulong2Ulong2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong2Ulong2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUlong2Ulong2Ulong2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUlong2Ulong2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUlong3Ulong3Ulong3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xac5dae264f2beebal, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xac5dae264f2beebbl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUlong3Ulong3Ulong3(inV1, out);
-            verifyResultsMaxUlong3Ulong3Ulong3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong3Ulong3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUlong3Ulong3Ulong3(inV1, out);
-            verifyResultsMaxUlong3Ulong3Ulong3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong3Ulong3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUlong3Ulong3Ulong3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUlong3Ulong3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMaxUlong4Ulong4Ulong4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xd94efd869f7634c5l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xd94efd869f7634c6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMaxUlong4Ulong4Ulong4(inV1, out);
-            verifyResultsMaxUlong4Ulong4Ulong4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong4Ulong4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMaxUlong4Ulong4Ulong4(inV1, out);
-            verifyResultsMaxUlong4Ulong4Ulong4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong4Ulong4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMaxUlong4Ulong4Ulong4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMax(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMaxUlong4Ulong4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testMax() {
-        checkMaxFloatFloatFloat();
-        checkMaxFloat2Float2Float2();
-        checkMaxFloat3Float3Float3();
-        checkMaxFloat4Float4Float4();
-        checkMaxCharCharChar();
-        checkMaxChar2Char2Char2();
-        checkMaxChar3Char3Char3();
-        checkMaxChar4Char4Char4();
-        checkMaxUcharUcharUchar();
-        checkMaxUchar2Uchar2Uchar2();
-        checkMaxUchar3Uchar3Uchar3();
-        checkMaxUchar4Uchar4Uchar4();
-        checkMaxShortShortShort();
-        checkMaxShort2Short2Short2();
-        checkMaxShort3Short3Short3();
-        checkMaxShort4Short4Short4();
-        checkMaxUshortUshortUshort();
-        checkMaxUshort2Ushort2Ushort2();
-        checkMaxUshort3Ushort3Ushort3();
-        checkMaxUshort4Ushort4Ushort4();
-        checkMaxIntIntInt();
-        checkMaxInt2Int2Int2();
-        checkMaxInt3Int3Int3();
-        checkMaxInt4Int4Int4();
-        checkMaxUintUintUint();
-        checkMaxUint2Uint2Uint2();
-        checkMaxUint3Uint3Uint3();
-        checkMaxUint4Uint4Uint4();
-        checkMaxLongLongLong();
-        checkMaxLong2Long2Long2();
-        checkMaxLong3Long3Long3();
-        checkMaxLong4Long4Long4();
-        checkMaxUlongUlongUlong();
-        checkMaxUlong2Ulong2Ulong2();
-        checkMaxUlong3Ulong3Ulong3();
-        checkMaxUlong4Ulong4Ulong4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMax.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestMax.rs
deleted file mode 100644
index dff7927..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMax.rs
+++ /dev/null
@@ -1,203 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocIn1;
-
-float __attribute__((kernel)) testMaxFloatFloatFloat(float in, unsigned int x) {
-    float in1 = rsGetElementAt_float(gAllocIn1, x);
-    return max(in, in1);
-}
-
-float2 __attribute__((kernel)) testMaxFloat2Float2Float2(float2 in, unsigned int x) {
-    float2 in1 = rsGetElementAt_float2(gAllocIn1, x);
-    return max(in, in1);
-}
-
-float3 __attribute__((kernel)) testMaxFloat3Float3Float3(float3 in, unsigned int x) {
-    float3 in1 = rsGetElementAt_float3(gAllocIn1, x);
-    return max(in, in1);
-}
-
-float4 __attribute__((kernel)) testMaxFloat4Float4Float4(float4 in, unsigned int x) {
-    float4 in1 = rsGetElementAt_float4(gAllocIn1, x);
-    return max(in, in1);
-}
-rs_allocation gAllocInV2;
-
-char __attribute__((kernel)) testMaxCharCharChar(char inV1, unsigned int x) {
-    char inV2 = rsGetElementAt_char(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-char2 __attribute__((kernel)) testMaxChar2Char2Char2(char2 inV1, unsigned int x) {
-    char2 inV2 = rsGetElementAt_char2(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-char3 __attribute__((kernel)) testMaxChar3Char3Char3(char3 inV1, unsigned int x) {
-    char3 inV2 = rsGetElementAt_char3(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-char4 __attribute__((kernel)) testMaxChar4Char4Char4(char4 inV1, unsigned int x) {
-    char4 inV2 = rsGetElementAt_char4(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-uchar __attribute__((kernel)) testMaxUcharUcharUchar(uchar inV1, unsigned int x) {
-    uchar inV2 = rsGetElementAt_uchar(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-uchar2 __attribute__((kernel)) testMaxUchar2Uchar2Uchar2(uchar2 inV1, unsigned int x) {
-    uchar2 inV2 = rsGetElementAt_uchar2(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-uchar3 __attribute__((kernel)) testMaxUchar3Uchar3Uchar3(uchar3 inV1, unsigned int x) {
-    uchar3 inV2 = rsGetElementAt_uchar3(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-uchar4 __attribute__((kernel)) testMaxUchar4Uchar4Uchar4(uchar4 inV1, unsigned int x) {
-    uchar4 inV2 = rsGetElementAt_uchar4(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-short __attribute__((kernel)) testMaxShortShortShort(short inV1, unsigned int x) {
-    short inV2 = rsGetElementAt_short(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-short2 __attribute__((kernel)) testMaxShort2Short2Short2(short2 inV1, unsigned int x) {
-    short2 inV2 = rsGetElementAt_short2(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-short3 __attribute__((kernel)) testMaxShort3Short3Short3(short3 inV1, unsigned int x) {
-    short3 inV2 = rsGetElementAt_short3(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-short4 __attribute__((kernel)) testMaxShort4Short4Short4(short4 inV1, unsigned int x) {
-    short4 inV2 = rsGetElementAt_short4(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-ushort __attribute__((kernel)) testMaxUshortUshortUshort(ushort inV1, unsigned int x) {
-    ushort inV2 = rsGetElementAt_ushort(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-ushort2 __attribute__((kernel)) testMaxUshort2Ushort2Ushort2(ushort2 inV1, unsigned int x) {
-    ushort2 inV2 = rsGetElementAt_ushort2(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-ushort3 __attribute__((kernel)) testMaxUshort3Ushort3Ushort3(ushort3 inV1, unsigned int x) {
-    ushort3 inV2 = rsGetElementAt_ushort3(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-ushort4 __attribute__((kernel)) testMaxUshort4Ushort4Ushort4(ushort4 inV1, unsigned int x) {
-    ushort4 inV2 = rsGetElementAt_ushort4(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-int __attribute__((kernel)) testMaxIntIntInt(int inV1, unsigned int x) {
-    int inV2 = rsGetElementAt_int(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-int2 __attribute__((kernel)) testMaxInt2Int2Int2(int2 inV1, unsigned int x) {
-    int2 inV2 = rsGetElementAt_int2(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-int3 __attribute__((kernel)) testMaxInt3Int3Int3(int3 inV1, unsigned int x) {
-    int3 inV2 = rsGetElementAt_int3(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-int4 __attribute__((kernel)) testMaxInt4Int4Int4(int4 inV1, unsigned int x) {
-    int4 inV2 = rsGetElementAt_int4(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-uint __attribute__((kernel)) testMaxUintUintUint(uint inV1, unsigned int x) {
-    uint inV2 = rsGetElementAt_uint(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-uint2 __attribute__((kernel)) testMaxUint2Uint2Uint2(uint2 inV1, unsigned int x) {
-    uint2 inV2 = rsGetElementAt_uint2(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-uint3 __attribute__((kernel)) testMaxUint3Uint3Uint3(uint3 inV1, unsigned int x) {
-    uint3 inV2 = rsGetElementAt_uint3(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-uint4 __attribute__((kernel)) testMaxUint4Uint4Uint4(uint4 inV1, unsigned int x) {
-    uint4 inV2 = rsGetElementAt_uint4(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-long __attribute__((kernel)) testMaxLongLongLong(long inV1, unsigned int x) {
-    long inV2 = rsGetElementAt_long(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-long2 __attribute__((kernel)) testMaxLong2Long2Long2(long2 inV1, unsigned int x) {
-    long2 inV2 = rsGetElementAt_long2(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-long3 __attribute__((kernel)) testMaxLong3Long3Long3(long3 inV1, unsigned int x) {
-    long3 inV2 = rsGetElementAt_long3(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-long4 __attribute__((kernel)) testMaxLong4Long4Long4(long4 inV1, unsigned int x) {
-    long4 inV2 = rsGetElementAt_long4(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-ulong __attribute__((kernel)) testMaxUlongUlongUlong(ulong inV1, unsigned int x) {
-    ulong inV2 = rsGetElementAt_ulong(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-ulong2 __attribute__((kernel)) testMaxUlong2Ulong2Ulong2(ulong2 inV1, unsigned int x) {
-    ulong2 inV2 = rsGetElementAt_ulong2(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-ulong3 __attribute__((kernel)) testMaxUlong3Ulong3Ulong3(ulong3 inV1, unsigned int x) {
-    ulong3 inV2 = rsGetElementAt_ulong3(gAllocInV2, x);
-    return max(inV1, inV2);
-}
-
-ulong4 __attribute__((kernel)) testMaxUlong4Ulong4Ulong4(ulong4 inV1, unsigned int x) {
-    ulong4 inV2 = rsGetElementAt_ulong4(gAllocInV2, x);
-    return max(inV1, inV2);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMaxRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestMaxRelaxed.rs
deleted file mode 100644
index fb0319b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMaxRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestMax.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestMin.java
deleted file mode 100644
index a04ef55..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMin.java
+++ /dev/null
@@ -1,2485 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestMin extends RSBaseCompute {
-
-    private ScriptC_TestMin script;
-    private ScriptC_TestMinRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestMin(mRS);
-        scriptRelaxed = new ScriptC_TestMinRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float in;
-        public float in1;
-        public Target.Floaty out;
-    }
-
-    private void checkMinFloatFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x816f2fe273bf4977l, false);
-        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbdad0b097121572el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocIn1(in1);
-            script.forEach_testMinFloatFloatFloat(in, out);
-            verifyResultsMinFloatFloatFloat(in, in1, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocIn1(in1);
-            scriptRelaxed.forEach_testMinFloatFloatFloat(in, out);
-            verifyResultsMinFloatFloatFloat(in, in1, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinFloatFloatFloat(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayIn1 = new float[INPUTSIZE * 1];
-        in1.copyTo(arrayIn1);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.in = arrayIn[i];
-                args.in1 = arrayIn1[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Input in1: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinFloat2Float2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe354049301b6cfb9l, false);
-        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2f1cc4b149b4e444l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocIn1(in1);
-            script.forEach_testMinFloat2Float2Float2(in, out);
-            verifyResultsMinFloat2Float2Float2(in, in1, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocIn1(in1);
-            scriptRelaxed.forEach_testMinFloat2Float2Float2(in, out);
-            verifyResultsMinFloat2Float2Float2(in, in1, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinFloat2Float2Float2(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayIn1 = new float[INPUTSIZE * 2];
-        in1.copyTo(arrayIn1);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                args.in1 = arrayIn1[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Input in1: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinFloat3Float3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x38a3c24c4f27231cl, false);
-        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8381a2d14b92e5e5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocIn1(in1);
-            script.forEach_testMinFloat3Float3Float3(in, out);
-            verifyResultsMinFloat3Float3Float3(in, in1, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocIn1(in1);
-            scriptRelaxed.forEach_testMinFloat3Float3Float3(in, out);
-            verifyResultsMinFloat3Float3Float3(in, in1, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinFloat3Float3Float3(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayIn1 = new float[INPUTSIZE * 4];
-        in1.copyTo(arrayIn1);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                args.in1 = arrayIn1[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Input in1: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinFloat4Float4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8df380059c97767fl, false);
-        Allocation in1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd7e680f14d70e786l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocIn1(in1);
-            script.forEach_testMinFloat4Float4Float4(in, out);
-            verifyResultsMinFloat4Float4Float4(in, in1, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocIn1(in1);
-            scriptRelaxed.forEach_testMinFloat4Float4Float4(in, out);
-            verifyResultsMinFloat4Float4Float4(in, in1, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinFloat4Float4Float4(Allocation in, Allocation in1, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayIn1 = new float[INPUTSIZE * 4];
-        in1.copyTo(arrayIn1);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                args.in1 = arrayIn1[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Input in1: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in1, Float.floatToRawIntBits(args.in1), args.in1));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsCharCharChar {
-        public byte inV1;
-        public byte inV2;
-        public byte out;
-    }
-
-    private void checkMinCharCharChar() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x47c90c486fc45b58l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x47c90c486fc45b59l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinCharCharChar(inV1, out);
-            verifyResultsMinCharCharChar(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinCharCharChar: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinCharCharChar(inV1, out);
-            verifyResultsMinCharCharChar(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinCharCharChar: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinCharCharChar(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinCharCharChar" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinChar2Char2Char2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xec4705afc03447ael, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xec4705afc03447afl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinChar2Char2Char2(inV1, out);
-            verifyResultsMinChar2Char2Char2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar2Char2Char2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinChar2Char2Char2(inV1, out);
-            verifyResultsMinChar2Char2Char2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar2Char2Char2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinChar2Char2Char2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinChar2Char2Char2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinChar3Char3Char3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x419881e2a4ec1a73l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x419881e2a4ec1a74l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinChar3Char3Char3(inV1, out);
-            verifyResultsMinChar3Char3Char3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar3Char3Char3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinChar3Char3Char3(inV1, out);
-            verifyResultsMinChar3Char3Char3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar3Char3Char3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinChar3Char3Char3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinChar3Char3Char3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinChar4Char4Char4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x96e9fe1589a3ed38l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x96e9fe1589a3ed39l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinChar4Char4Char4(inV1, out);
-            verifyResultsMinChar4Char4Char4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar4Char4Char4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinChar4Char4Char4(inV1, out);
-            verifyResultsMinChar4Char4Char4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar4Char4Char4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinChar4Char4Char4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinChar4Char4Char4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUcharUcharUchar {
-        public byte inV1;
-        public byte inV2;
-        public byte out;
-    }
-
-    private void checkMinUcharUcharUchar() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x6dc5402bc7a34891l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x6dc5402bc7a34892l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUcharUcharUchar(inV1, out);
-            verifyResultsMinUcharUcharUchar(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUcharUcharUchar: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUcharUcharUchar(inV1, out);
-            verifyResultsMinUcharUcharUchar(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUcharUcharUchar: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUcharUcharUchar(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUcharUcharUchar" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUchar2Uchar2Uchar2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x1d3c921d166e22ffl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x1d3c921d166e2300l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUchar2Uchar2Uchar2(inV1, out);
-            verifyResultsMinUchar2Uchar2Uchar2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar2Uchar2Uchar2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUchar2Uchar2Uchar2(inV1, out);
-            verifyResultsMinUchar2Uchar2Uchar2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar2Uchar2Uchar2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUchar2Uchar2Uchar2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUchar2Uchar2Uchar2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUchar3Uchar3Uchar3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x4a2de17d66b8690al, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x4a2de17d66b8690bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUchar3Uchar3Uchar3(inV1, out);
-            verifyResultsMinUchar3Uchar3Uchar3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar3Uchar3Uchar3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUchar3Uchar3Uchar3(inV1, out);
-            verifyResultsMinUchar3Uchar3Uchar3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar3Uchar3Uchar3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUchar3Uchar3Uchar3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUchar3Uchar3Uchar3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUchar4Uchar4Uchar4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x771f30ddb702af15l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x771f30ddb702af16l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUchar4Uchar4Uchar4(inV1, out);
-            verifyResultsMinUchar4Uchar4Uchar4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar4Uchar4Uchar4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUchar4Uchar4Uchar4(inV1, out);
-            verifyResultsMinUchar4Uchar4Uchar4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar4Uchar4Uchar4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUchar4Uchar4Uchar4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        byte[] arrayInV1 = new byte[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        byte[] arrayInV2 = new byte[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        byte[] arrayOut = new byte[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUchar4Uchar4Uchar4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsShortShortShort {
-        public short inV1;
-        public short inV2;
-        public short out;
-    }
-
-    private void checkMinShortShortShort() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x71b08dd3c65bcddel, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x71b08dd3c65bcddfl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinShortShortShort(inV1, out);
-            verifyResultsMinShortShortShort(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShortShortShort: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinShortShortShort(inV1, out);
-            verifyResultsMinShortShortShort(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShortShortShort: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinShortShortShort(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinShortShortShort" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinShort2Short2Short2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xe4959a1ecbf1d380l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xe4959a1ecbf1d381l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinShort2Short2Short2(inV1, out);
-            verifyResultsMinShort2Short2Short2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort2Short2Short2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinShort2Short2Short2(inV1, out);
-            verifyResultsMinShort2Short2Short2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort2Short2Short2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinShort2Short2Short2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinShort2Short2Short2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinShort3Short3Short3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x1186e97f1c3c198bl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x1186e97f1c3c198cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinShort3Short3Short3(inV1, out);
-            verifyResultsMinShort3Short3Short3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort3Short3Short3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinShort3Short3Short3(inV1, out);
-            verifyResultsMinShort3Short3Short3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort3Short3Short3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinShort3Short3Short3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinShort3Short3Short3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinShort4Short4Short4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x3e7838df6c865f96l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x3e7838df6c865f97l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinShort4Short4Short4(inV1, out);
-            verifyResultsMinShort4Short4Short4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort4Short4Short4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinShort4Short4Short4(inV1, out);
-            verifyResultsMinShort4Short4Short4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort4Short4Short4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinShort4Short4Short4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinShort4Short4Short4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUshortUshortUshort {
-        public short inV1;
-        public short inV2;
-        public short out;
-    }
-
-    private void checkMinUshortUshortUshort() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xc2eb3387512e77cfl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xc2eb3387512e77d0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUshortUshortUshort(inV1, out);
-            verifyResultsMinUshortUshortUshort(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshortUshortUshort: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUshortUshortUshort(inV1, out);
-            verifyResultsMinUshortUshortUshort(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshortUshortUshort: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUshortUshortUshort(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUshortUshortUshort" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUshort2Ushort2Ushort2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x98573ebbc511e319l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x98573ebbc511e31al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUshort2Ushort2Ushort2(inV1, out);
-            verifyResultsMinUshort2Ushort2Ushort2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort2Ushort2Ushort2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUshort2Ushort2Ushort2(inV1, out);
-            verifyResultsMinUshort2Ushort2Ushort2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort2Ushort2Ushort2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUshort2Ushort2Ushort2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUshort2Ushort2Ushort2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUshort3Ushort3Ushort3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x1595f09b03867776l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x1595f09b03867777l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUshort3Ushort3Ushort3(inV1, out);
-            verifyResultsMinUshort3Ushort3Ushort3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort3Ushort3Ushort3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUshort3Ushort3Ushort3(inV1, out);
-            verifyResultsMinUshort3Ushort3Ushort3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort3Ushort3Ushort3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUshort3Ushort3Ushort3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUshort3Ushort3Ushort3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUshort4Ushort4Ushort4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x92d4a27a41fb0bd3l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x92d4a27a41fb0bd4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUshort4Ushort4Ushort4(inV1, out);
-            verifyResultsMinUshort4Ushort4Ushort4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort4Ushort4Ushort4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUshort4Ushort4Ushort4(inV1, out);
-            verifyResultsMinUshort4Ushort4Ushort4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort4Ushort4Ushort4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUshort4Ushort4Ushort4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        short[] arrayInV1 = new short[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        short[] arrayInV2 = new short[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        short[] arrayOut = new short[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUshort4Ushort4Ushort4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsIntIntInt {
-        public int inV1;
-        public int inV2;
-        public int out;
-    }
-
-    private void checkMinIntIntInt() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x38b24335cda69cd5l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x38b24335cda69cd6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinIntIntInt(inV1, out);
-            verifyResultsMinIntIntInt(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinIntIntInt: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinIntIntInt(inV1, out);
-            verifyResultsMinIntIntInt(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinIntIntInt: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinIntIntInt(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinIntIntInt" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinInt2Int2Int2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xba635b605676e7a3l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xba635b605676e7a4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinInt2Int2Int2(inV1, out);
-            verifyResultsMinInt2Int2Int2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt2Int2Int2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinInt2Int2Int2(inV1, out);
-            verifyResultsMinInt2Int2Int2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt2Int2Int2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinInt2Int2Int2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinInt2Int2Int2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinInt3Int3Int3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xe4f086806849fbc6l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xe4f086806849fbc7l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinInt3Int3Int3(inV1, out);
-            verifyResultsMinInt3Int3Int3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt3Int3Int3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinInt3Int3Int3(inV1, out);
-            verifyResultsMinInt3Int3Int3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt3Int3Int3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinInt3Int3Int3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinInt3Int3Int3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinInt4Int4Int4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xf7db1a07a1d0fe9l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xf7db1a07a1d0feal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinInt4Int4Int4(inV1, out);
-            verifyResultsMinInt4Int4Int4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt4Int4Int4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinInt4Int4Int4(inV1, out);
-            verifyResultsMinInt4Int4Int4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt4Int4Int4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinInt4Int4Int4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinInt4Int4Int4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUintUintUint {
-        public int inV1;
-        public int inV2;
-        public int out;
-    }
-
-    private void checkMinUintUintUint() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xb3dbca2d537cf298l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xb3dbca2d537cf299l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUintUintUint(inV1, out);
-            verifyResultsMinUintUintUint(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUintUintUint: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUintUintUint(inV1, out);
-            verifyResultsMinUintUintUint(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUintUintUint: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUintUintUint(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUintUintUint" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUint2Uint2Uint2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xb8cf8481d731a1eel, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xb8cf8481d731a1efl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUint2Uint2Uint2(inV1, out);
-            verifyResultsMinUint2Uint2Uint2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint2Uint2Uint2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUint2Uint2Uint2(inV1, out);
-            verifyResultsMinUint2Uint2Uint2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint2Uint2Uint2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUint2Uint2Uint2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUint2Uint2Uint2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUint3Uint3Uint3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe2100b4bbe974b3l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe2100b4bbe974b4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUint3Uint3Uint3(inV1, out);
-            verifyResultsMinUint3Uint3Uint3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint3Uint3Uint3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUint3Uint3Uint3(inV1, out);
-            verifyResultsMinUint3Uint3Uint3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint3Uint3Uint3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUint3Uint3Uint3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUint3Uint3Uint3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUint4Uint4Uint4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x63727ce7a0a14778l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x63727ce7a0a14779l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUint4Uint4Uint4(inV1, out);
-            verifyResultsMinUint4Uint4Uint4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint4Uint4Uint4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUint4Uint4Uint4(inV1, out);
-            verifyResultsMinUint4Uint4Uint4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint4Uint4Uint4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUint4Uint4Uint4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        int[] arrayInV1 = new int[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        int[] arrayInV2 = new int[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        int[] arrayOut = new int[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUint4Uint4Uint4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsLongLongLong {
-        public long inV1;
-        public long inV2;
-        public long out;
-    }
-
-    private void checkMinLongLongLong() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x20ce185251c10eb2l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x20ce185251c10eb3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinLongLongLong(inV1, out);
-            verifyResultsMinLongLongLong(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLongLongLong: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinLongLongLong(inV1, out);
-            verifyResultsMinLongLongLong(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLongLongLong: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinLongLongLong(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinLongLongLong" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinLong2Long2Long2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x2285e00a094676a0l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x2285e00a094676a1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinLong2Long2Long2(inV1, out);
-            verifyResultsMinLong2Long2Long2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong2Long2Long2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinLong2Long2Long2(inV1, out);
-            verifyResultsMinLong2Long2Long2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong2Long2Long2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinLong2Long2Long2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinLong2Long2Long2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinLong3Long3Long3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x77d75c3cedfe4965l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x77d75c3cedfe4966l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinLong3Long3Long3(inV1, out);
-            verifyResultsMinLong3Long3Long3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong3Long3Long3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinLong3Long3Long3(inV1, out);
-            verifyResultsMinLong3Long3Long3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong3Long3Long3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinLong3Long3Long3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinLong3Long3Long3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinLong4Long4Long4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xcd28d86fd2b61c2al, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xcd28d86fd2b61c2bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinLong4Long4Long4(inV1, out);
-            verifyResultsMinLong4Long4Long4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong4Long4Long4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinLong4Long4Long4(inV1, out);
-            verifyResultsMinLong4Long4Long4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong4Long4Long4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinLong4Long4Long4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("%d", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("%d", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("%d", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%d", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinLong4Long4Long4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public class ArgumentsUlongUlongUlong {
-        public long inV1;
-        public long inV2;
-        public long out;
-    }
-
-    private void checkMinUlongUlongUlong() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x9ea8f1e67008ea67l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x9ea8f1e67008ea68l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUlongUlongUlong(inV1, out);
-            verifyResultsMinUlongUlongUlong(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlongUlongUlong: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUlongUlongUlong(inV1, out);
-            verifyResultsMinUlongUlongUlong(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlongUlongUlong: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUlongUlongUlong(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 1];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 1];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
-                args.inV1 = arrayInV1[i];
-                args.inV2 = arrayInV2[i];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 1 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 1 + j]));
-                    if (args.out != arrayOut[i * 1 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUlongUlongUlong" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUlong2Ulong2Ulong2() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x26bb4add3110402dl, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x26bb4add3110402el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUlong2Ulong2Ulong2(inV1, out);
-            verifyResultsMinUlong2Ulong2Ulong2(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong2Ulong2Ulong2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUlong2Ulong2Ulong2(inV1, out);
-            verifyResultsMinUlong2Ulong2Ulong2(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong2Ulong2Ulong2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUlong2Ulong2Ulong2(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 2];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 2];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
-                args.inV1 = arrayInV1[i * 2 + j];
-                args.inV2 = arrayInV2[i * 2 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 2 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 2 + j]));
-                    if (args.out != arrayOut[i * 2 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUlong2Ulong2Ulong2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUlong3Ulong3Ulong3() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x53ac9a3d815a8638l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x53ac9a3d815a8639l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUlong3Ulong3Ulong3(inV1, out);
-            verifyResultsMinUlong3Ulong3Ulong3(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong3Ulong3Ulong3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUlong3Ulong3Ulong3(inV1, out);
-            verifyResultsMinUlong3Ulong3Ulong3(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong3Ulong3Ulong3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUlong3Ulong3Ulong3(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUlong3Ulong3Ulong3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMinUlong4Ulong4Ulong4() {
-        Allocation inV1 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x809de99dd1a4cc43l, false);
-        Allocation inV2 = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x809de99dd1a4cc44l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            script.set_gAllocInV2(inV2);
-            script.forEach_testMinUlong4Ulong4Ulong4(inV1, out);
-            verifyResultsMinUlong4Ulong4Ulong4(inV1, inV2, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong4Ulong4Ulong4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV2(inV2);
-            scriptRelaxed.forEach_testMinUlong4Ulong4Ulong4(inV1, out);
-            verifyResultsMinUlong4Ulong4Ulong4(inV1, inV2, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong4Ulong4Ulong4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMinUlong4Ulong4Ulong4(Allocation inV1, Allocation inV2, Allocation out, boolean relaxed) {
-        long[] arrayInV1 = new long[INPUTSIZE * 4];
-        inV1.copyTo(arrayInV1);
-        long[] arrayInV2 = new long[INPUTSIZE * 4];
-        inV2.copyTo(arrayInV2);
-        long[] arrayOut = new long[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
-                args.inV1 = arrayInV1[i * 4 + j];
-                args.inV2 = arrayInV2[i * 4 + j];
-                // Figure out what the outputs should have been.
-                CoreMathVerifier.computeMin(args);
-                // Validate the outputs.
-                boolean valid = true;
-                if (args.out != arrayOut[i * 4 + j]) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV1: ");
-                    message.append(String.format("0x%x", args.inV1));
-                    message.append("\n");
-                    message.append("Input inV2: ");
-                    message.append(String.format("0x%x", args.inV2));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(String.format("0x%x", args.out));
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("0x%x", arrayOut[i * 4 + j]));
-                    if (args.out != arrayOut[i * 4 + j]) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMinUlong4Ulong4Ulong4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testMin() {
-        checkMinFloatFloatFloat();
-        checkMinFloat2Float2Float2();
-        checkMinFloat3Float3Float3();
-        checkMinFloat4Float4Float4();
-        checkMinCharCharChar();
-        checkMinChar2Char2Char2();
-        checkMinChar3Char3Char3();
-        checkMinChar4Char4Char4();
-        checkMinUcharUcharUchar();
-        checkMinUchar2Uchar2Uchar2();
-        checkMinUchar3Uchar3Uchar3();
-        checkMinUchar4Uchar4Uchar4();
-        checkMinShortShortShort();
-        checkMinShort2Short2Short2();
-        checkMinShort3Short3Short3();
-        checkMinShort4Short4Short4();
-        checkMinUshortUshortUshort();
-        checkMinUshort2Ushort2Ushort2();
-        checkMinUshort3Ushort3Ushort3();
-        checkMinUshort4Ushort4Ushort4();
-        checkMinIntIntInt();
-        checkMinInt2Int2Int2();
-        checkMinInt3Int3Int3();
-        checkMinInt4Int4Int4();
-        checkMinUintUintUint();
-        checkMinUint2Uint2Uint2();
-        checkMinUint3Uint3Uint3();
-        checkMinUint4Uint4Uint4();
-        checkMinLongLongLong();
-        checkMinLong2Long2Long2();
-        checkMinLong3Long3Long3();
-        checkMinLong4Long4Long4();
-        checkMinUlongUlongUlong();
-        checkMinUlong2Ulong2Ulong2();
-        checkMinUlong3Ulong3Ulong3();
-        checkMinUlong4Ulong4Ulong4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMin.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestMin.rs
deleted file mode 100644
index 29a9aeb1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMin.rs
+++ /dev/null
@@ -1,203 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocIn1;
-
-float __attribute__((kernel)) testMinFloatFloatFloat(float in, unsigned int x) {
-    float in1 = rsGetElementAt_float(gAllocIn1, x);
-    return min(in, in1);
-}
-
-float2 __attribute__((kernel)) testMinFloat2Float2Float2(float2 in, unsigned int x) {
-    float2 in1 = rsGetElementAt_float2(gAllocIn1, x);
-    return min(in, in1);
-}
-
-float3 __attribute__((kernel)) testMinFloat3Float3Float3(float3 in, unsigned int x) {
-    float3 in1 = rsGetElementAt_float3(gAllocIn1, x);
-    return min(in, in1);
-}
-
-float4 __attribute__((kernel)) testMinFloat4Float4Float4(float4 in, unsigned int x) {
-    float4 in1 = rsGetElementAt_float4(gAllocIn1, x);
-    return min(in, in1);
-}
-rs_allocation gAllocInV2;
-
-char __attribute__((kernel)) testMinCharCharChar(char inV1, unsigned int x) {
-    char inV2 = rsGetElementAt_char(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-char2 __attribute__((kernel)) testMinChar2Char2Char2(char2 inV1, unsigned int x) {
-    char2 inV2 = rsGetElementAt_char2(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-char3 __attribute__((kernel)) testMinChar3Char3Char3(char3 inV1, unsigned int x) {
-    char3 inV2 = rsGetElementAt_char3(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-char4 __attribute__((kernel)) testMinChar4Char4Char4(char4 inV1, unsigned int x) {
-    char4 inV2 = rsGetElementAt_char4(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-uchar __attribute__((kernel)) testMinUcharUcharUchar(uchar inV1, unsigned int x) {
-    uchar inV2 = rsGetElementAt_uchar(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-uchar2 __attribute__((kernel)) testMinUchar2Uchar2Uchar2(uchar2 inV1, unsigned int x) {
-    uchar2 inV2 = rsGetElementAt_uchar2(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-uchar3 __attribute__((kernel)) testMinUchar3Uchar3Uchar3(uchar3 inV1, unsigned int x) {
-    uchar3 inV2 = rsGetElementAt_uchar3(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-uchar4 __attribute__((kernel)) testMinUchar4Uchar4Uchar4(uchar4 inV1, unsigned int x) {
-    uchar4 inV2 = rsGetElementAt_uchar4(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-short __attribute__((kernel)) testMinShortShortShort(short inV1, unsigned int x) {
-    short inV2 = rsGetElementAt_short(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-short2 __attribute__((kernel)) testMinShort2Short2Short2(short2 inV1, unsigned int x) {
-    short2 inV2 = rsGetElementAt_short2(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-short3 __attribute__((kernel)) testMinShort3Short3Short3(short3 inV1, unsigned int x) {
-    short3 inV2 = rsGetElementAt_short3(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-short4 __attribute__((kernel)) testMinShort4Short4Short4(short4 inV1, unsigned int x) {
-    short4 inV2 = rsGetElementAt_short4(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-ushort __attribute__((kernel)) testMinUshortUshortUshort(ushort inV1, unsigned int x) {
-    ushort inV2 = rsGetElementAt_ushort(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-ushort2 __attribute__((kernel)) testMinUshort2Ushort2Ushort2(ushort2 inV1, unsigned int x) {
-    ushort2 inV2 = rsGetElementAt_ushort2(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-ushort3 __attribute__((kernel)) testMinUshort3Ushort3Ushort3(ushort3 inV1, unsigned int x) {
-    ushort3 inV2 = rsGetElementAt_ushort3(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-ushort4 __attribute__((kernel)) testMinUshort4Ushort4Ushort4(ushort4 inV1, unsigned int x) {
-    ushort4 inV2 = rsGetElementAt_ushort4(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-int __attribute__((kernel)) testMinIntIntInt(int inV1, unsigned int x) {
-    int inV2 = rsGetElementAt_int(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-int2 __attribute__((kernel)) testMinInt2Int2Int2(int2 inV1, unsigned int x) {
-    int2 inV2 = rsGetElementAt_int2(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-int3 __attribute__((kernel)) testMinInt3Int3Int3(int3 inV1, unsigned int x) {
-    int3 inV2 = rsGetElementAt_int3(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-int4 __attribute__((kernel)) testMinInt4Int4Int4(int4 inV1, unsigned int x) {
-    int4 inV2 = rsGetElementAt_int4(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-uint __attribute__((kernel)) testMinUintUintUint(uint inV1, unsigned int x) {
-    uint inV2 = rsGetElementAt_uint(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-uint2 __attribute__((kernel)) testMinUint2Uint2Uint2(uint2 inV1, unsigned int x) {
-    uint2 inV2 = rsGetElementAt_uint2(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-uint3 __attribute__((kernel)) testMinUint3Uint3Uint3(uint3 inV1, unsigned int x) {
-    uint3 inV2 = rsGetElementAt_uint3(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-uint4 __attribute__((kernel)) testMinUint4Uint4Uint4(uint4 inV1, unsigned int x) {
-    uint4 inV2 = rsGetElementAt_uint4(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-long __attribute__((kernel)) testMinLongLongLong(long inV1, unsigned int x) {
-    long inV2 = rsGetElementAt_long(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-long2 __attribute__((kernel)) testMinLong2Long2Long2(long2 inV1, unsigned int x) {
-    long2 inV2 = rsGetElementAt_long2(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-long3 __attribute__((kernel)) testMinLong3Long3Long3(long3 inV1, unsigned int x) {
-    long3 inV2 = rsGetElementAt_long3(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-long4 __attribute__((kernel)) testMinLong4Long4Long4(long4 inV1, unsigned int x) {
-    long4 inV2 = rsGetElementAt_long4(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-ulong __attribute__((kernel)) testMinUlongUlongUlong(ulong inV1, unsigned int x) {
-    ulong inV2 = rsGetElementAt_ulong(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-ulong2 __attribute__((kernel)) testMinUlong2Ulong2Ulong2(ulong2 inV1, unsigned int x) {
-    ulong2 inV2 = rsGetElementAt_ulong2(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-ulong3 __attribute__((kernel)) testMinUlong3Ulong3Ulong3(ulong3 inV1, unsigned int x) {
-    ulong3 inV2 = rsGetElementAt_ulong3(gAllocInV2, x);
-    return min(inV1, inV2);
-}
-
-ulong4 __attribute__((kernel)) testMinUlong4Ulong4Ulong4(ulong4 inV1, unsigned int x) {
-    ulong4 inV2 = rsGetElementAt_ulong4(gAllocInV2, x);
-    return min(inV1, inV2);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestMinRelaxed.rs
deleted file mode 100644
index 29a4d89..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMinRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestMin.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMix.java b/tests/tests/renderscript/src/android/renderscript/cts/TestMix.java
deleted file mode 100644
index 3500e41..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMix.java
+++ /dev/null
@@ -1,606 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestMix extends RSBaseCompute {
-
-    private ScriptC_TestMix script;
-    private ScriptC_TestMixRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestMix(mRS);
-        scriptRelaxed = new ScriptC_TestMixRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloatFloat {
-        public float inStart;
-        public float inStop;
-        public float inAmount;
-        public Target.Floaty out;
-    }
-
-    private void checkMixFloatFloatFloatFloat() {
-        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9f4beff6471d6db1l, false);
-        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6ede0b88b4422e8fl, false);
-        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc1c14e5d52dc3fe5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInStop(inStop);
-            script.set_gAllocInAmount(inAmount);
-            script.forEach_testMixFloatFloatFloatFloat(inStart, out);
-            verifyResultsMixFloatFloatFloatFloat(inStart, inStop, inAmount, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloatFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInStop(inStop);
-            scriptRelaxed.set_gAllocInAmount(inAmount);
-            scriptRelaxed.forEach_testMixFloatFloatFloatFloat(inStart, out);
-            verifyResultsMixFloatFloatFloatFloat(inStart, inStop, inAmount, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloatFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMixFloatFloatFloatFloat(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
-        float[] arrayInStart = new float[INPUTSIZE * 1];
-        inStart.copyTo(arrayInStart);
-        float[] arrayInStop = new float[INPUTSIZE * 1];
-        inStop.copyTo(arrayInStop);
-        float[] arrayInAmount = new float[INPUTSIZE * 1];
-        inAmount.copyTo(arrayInAmount);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inStart = arrayInStart[i];
-                args.inStop = arrayInStop[i];
-                args.inAmount = arrayInAmount[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMix(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inStart: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
-                    message.append("\n");
-                    message.append("Input inStop: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
-                    message.append("\n");
-                    message.append("Input inAmount: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMixFloatFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMixFloat2Float2Float2Float2() {
-        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x45502e8f0a2d9ce9l, false);
-        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xba2b8a035395e837l, false);
-        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa477d20616942e4dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInStop(inStop);
-            script.set_gAllocInAmount(inAmount);
-            script.forEach_testMixFloat2Float2Float2Float2(inStart, out);
-            verifyResultsMixFloat2Float2Float2Float2(inStart, inStop, inAmount, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInStop(inStop);
-            scriptRelaxed.set_gAllocInAmount(inAmount);
-            scriptRelaxed.forEach_testMixFloat2Float2Float2Float2(inStart, out);
-            verifyResultsMixFloat2Float2Float2Float2(inStart, inStop, inAmount, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMixFloat2Float2Float2Float2(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
-        float[] arrayInStart = new float[INPUTSIZE * 2];
-        inStart.copyTo(arrayInStart);
-        float[] arrayInStop = new float[INPUTSIZE * 2];
-        inStop.copyTo(arrayInStop);
-        float[] arrayInAmount = new float[INPUTSIZE * 2];
-        inAmount.copyTo(arrayInAmount);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inStart = arrayInStart[i * 2 + j];
-                args.inStop = arrayInStop[i * 2 + j];
-                args.inAmount = arrayInAmount[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMix(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inStart: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
-                    message.append("\n");
-                    message.append("Input inStop: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
-                    message.append("\n");
-                    message.append("Input inAmount: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMixFloat2Float2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMixFloat3Float3Float3Float3() {
-        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xeb4701726b009c5l, false);
-        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9b21f6b3249ee4cbl, false);
-        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x784ed3e2e07c7741l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInStop(inStop);
-            script.set_gAllocInAmount(inAmount);
-            script.forEach_testMixFloat3Float3Float3Float3(inStart, out);
-            verifyResultsMixFloat3Float3Float3Float3(inStart, inStop, inAmount, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInStop(inStop);
-            scriptRelaxed.set_gAllocInAmount(inAmount);
-            scriptRelaxed.forEach_testMixFloat3Float3Float3Float3(inStart, out);
-            verifyResultsMixFloat3Float3Float3Float3(inStart, inStop, inAmount, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMixFloat3Float3Float3Float3(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
-        float[] arrayInStart = new float[INPUTSIZE * 4];
-        inStart.copyTo(arrayInStart);
-        float[] arrayInStop = new float[INPUTSIZE * 4];
-        inStop.copyTo(arrayInStop);
-        float[] arrayInAmount = new float[INPUTSIZE * 4];
-        inAmount.copyTo(arrayInAmount);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inStart = arrayInStart[i * 4 + j];
-                args.inStop = arrayInStop[i * 4 + j];
-                args.inAmount = arrayInAmount[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMix(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inStart: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
-                    message.append("\n");
-                    message.append("Input inStop: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
-                    message.append("\n");
-                    message.append("Input inAmount: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMixFloat3Float3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMixFloat4Float4Float4Float4() {
-        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd818b19f433276a1l, false);
-        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7c186362f5a7e15fl, false);
-        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4c25d5bfaa64c035l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInStop(inStop);
-            script.set_gAllocInAmount(inAmount);
-            script.forEach_testMixFloat4Float4Float4Float4(inStart, out);
-            verifyResultsMixFloat4Float4Float4Float4(inStart, inStop, inAmount, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInStop(inStop);
-            scriptRelaxed.set_gAllocInAmount(inAmount);
-            scriptRelaxed.forEach_testMixFloat4Float4Float4Float4(inStart, out);
-            verifyResultsMixFloat4Float4Float4Float4(inStart, inStop, inAmount, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMixFloat4Float4Float4Float4(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
-        float[] arrayInStart = new float[INPUTSIZE * 4];
-        inStart.copyTo(arrayInStart);
-        float[] arrayInStop = new float[INPUTSIZE * 4];
-        inStop.copyTo(arrayInStop);
-        float[] arrayInAmount = new float[INPUTSIZE * 4];
-        inAmount.copyTo(arrayInAmount);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inStart = arrayInStart[i * 4 + j];
-                args.inStop = arrayInStop[i * 4 + j];
-                args.inAmount = arrayInAmount[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMix(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inStart: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
-                    message.append("\n");
-                    message.append("Input inStop: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
-                    message.append("\n");
-                    message.append("Input inAmount: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMixFloat4Float4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMixFloat2Float2FloatFloat2() {
-        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf811b2d52bd1d7c3l, false);
-        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x17a127e13c8dd1c5l, false);
-        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xaaf909cdbd2a10ebl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInStop(inStop);
-            script.set_gAllocInAmount(inAmount);
-            script.forEach_testMixFloat2Float2FloatFloat2(inStart, out);
-            verifyResultsMixFloat2Float2FloatFloat2(inStart, inStop, inAmount, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2FloatFloat2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInStop(inStop);
-            scriptRelaxed.set_gAllocInAmount(inAmount);
-            scriptRelaxed.forEach_testMixFloat2Float2FloatFloat2(inStart, out);
-            verifyResultsMixFloat2Float2FloatFloat2(inStart, inStop, inAmount, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2FloatFloat2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMixFloat2Float2FloatFloat2(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
-        float[] arrayInStart = new float[INPUTSIZE * 2];
-        inStart.copyTo(arrayInStart);
-        float[] arrayInStop = new float[INPUTSIZE * 2];
-        inStop.copyTo(arrayInStop);
-        float[] arrayInAmount = new float[INPUTSIZE * 1];
-        inAmount.copyTo(arrayInAmount);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inStart = arrayInStart[i * 2 + j];
-                args.inStop = arrayInStop[i * 2 + j];
-                args.inAmount = arrayInAmount[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMix(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inStart: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
-                    message.append("\n");
-                    message.append("Input inStop: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
-                    message.append("\n");
-                    message.append("Input inAmount: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMixFloat2Float2FloatFloat2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMixFloat3Float3FloatFloat3() {
-        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xae7aff441b20fa80l, false);
-        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe64a4d60d6f4de7cl, false);
-        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4ea8e06fef74e6aal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInStop(inStop);
-            script.set_gAllocInAmount(inAmount);
-            script.forEach_testMixFloat3Float3FloatFloat3(inStart, out);
-            verifyResultsMixFloat3Float3FloatFloat3(inStart, inStop, inAmount, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3FloatFloat3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInStop(inStop);
-            scriptRelaxed.set_gAllocInAmount(inAmount);
-            scriptRelaxed.forEach_testMixFloat3Float3FloatFloat3(inStart, out);
-            verifyResultsMixFloat3Float3FloatFloat3(inStart, inStop, inAmount, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3FloatFloat3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMixFloat3Float3FloatFloat3(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
-        float[] arrayInStart = new float[INPUTSIZE * 4];
-        inStart.copyTo(arrayInStart);
-        float[] arrayInStop = new float[INPUTSIZE * 4];
-        inStop.copyTo(arrayInStop);
-        float[] arrayInAmount = new float[INPUTSIZE * 1];
-        inAmount.copyTo(arrayInAmount);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inStart = arrayInStart[i * 4 + j];
-                args.inStop = arrayInStop[i * 4 + j];
-                args.inAmount = arrayInAmount[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMix(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inStart: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
-                    message.append("\n");
-                    message.append("Input inStop: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
-                    message.append("\n");
-                    message.append("Input inAmount: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMixFloat3Float3FloatFloat3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkMixFloat4Float4FloatFloat4() {
-        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x64e44bb30a701d3dl, false);
-        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb4f372e0715beb33l, false);
-        Allocation inAmount = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf258b71221bfbc69l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInStop(inStop);
-            script.set_gAllocInAmount(inAmount);
-            script.forEach_testMixFloat4Float4FloatFloat4(inStart, out);
-            verifyResultsMixFloat4Float4FloatFloat4(inStart, inStop, inAmount, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4FloatFloat4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInStop(inStop);
-            scriptRelaxed.set_gAllocInAmount(inAmount);
-            scriptRelaxed.forEach_testMixFloat4Float4FloatFloat4(inStart, out);
-            verifyResultsMixFloat4Float4FloatFloat4(inStart, inStop, inAmount, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4FloatFloat4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsMixFloat4Float4FloatFloat4(Allocation inStart, Allocation inStop, Allocation inAmount, Allocation out, boolean relaxed) {
-        float[] arrayInStart = new float[INPUTSIZE * 4];
-        inStart.copyTo(arrayInStart);
-        float[] arrayInStop = new float[INPUTSIZE * 4];
-        inStop.copyTo(arrayInStop);
-        float[] arrayInAmount = new float[INPUTSIZE * 1];
-        inAmount.copyTo(arrayInAmount);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
-                args.inStart = arrayInStart[i * 4 + j];
-                args.inStop = arrayInStop[i * 4 + j];
-                args.inAmount = arrayInAmount[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeMix(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inStart: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStart, Float.floatToRawIntBits(args.inStart), args.inStart));
-                    message.append("\n");
-                    message.append("Input inStop: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inStop, Float.floatToRawIntBits(args.inStop), args.inStop));
-                    message.append("\n");
-                    message.append("Input inAmount: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inAmount, Float.floatToRawIntBits(args.inAmount), args.inAmount));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkMixFloat4Float4FloatFloat4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testMix() {
-        checkMixFloatFloatFloatFloat();
-        checkMixFloat2Float2Float2Float2();
-        checkMixFloat3Float3Float3Float3();
-        checkMixFloat4Float4Float4Float4();
-        checkMixFloat2Float2FloatFloat2();
-        checkMixFloat3Float3FloatFloat3();
-        checkMixFloat4Float4FloatFloat4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMix.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestMix.rs
deleted file mode 100644
index c2ebcb3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMix.rs
+++ /dev/null
@@ -1,65 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInStop;
-rs_allocation gAllocInAmount;
-
-float __attribute__((kernel)) testMixFloatFloatFloatFloat(float inStart, unsigned int x) {
-    float inStop = rsGetElementAt_float(gAllocInStop, x);
-    float inAmount = rsGetElementAt_float(gAllocInAmount, x);
-    return mix(inStart, inStop, inAmount);
-}
-
-float2 __attribute__((kernel)) testMixFloat2Float2Float2Float2(float2 inStart, unsigned int x) {
-    float2 inStop = rsGetElementAt_float2(gAllocInStop, x);
-    float2 inAmount = rsGetElementAt_float2(gAllocInAmount, x);
-    return mix(inStart, inStop, inAmount);
-}
-
-float3 __attribute__((kernel)) testMixFloat3Float3Float3Float3(float3 inStart, unsigned int x) {
-    float3 inStop = rsGetElementAt_float3(gAllocInStop, x);
-    float3 inAmount = rsGetElementAt_float3(gAllocInAmount, x);
-    return mix(inStart, inStop, inAmount);
-}
-
-float4 __attribute__((kernel)) testMixFloat4Float4Float4Float4(float4 inStart, unsigned int x) {
-    float4 inStop = rsGetElementAt_float4(gAllocInStop, x);
-    float4 inAmount = rsGetElementAt_float4(gAllocInAmount, x);
-    return mix(inStart, inStop, inAmount);
-}
-
-float2 __attribute__((kernel)) testMixFloat2Float2FloatFloat2(float2 inStart, unsigned int x) {
-    float2 inStop = rsGetElementAt_float2(gAllocInStop, x);
-    float inAmount = rsGetElementAt_float(gAllocInAmount, x);
-    return mix(inStart, inStop, inAmount);
-}
-
-float3 __attribute__((kernel)) testMixFloat3Float3FloatFloat3(float3 inStart, unsigned int x) {
-    float3 inStop = rsGetElementAt_float3(gAllocInStop, x);
-    float inAmount = rsGetElementAt_float(gAllocInAmount, x);
-    return mix(inStart, inStop, inAmount);
-}
-
-float4 __attribute__((kernel)) testMixFloat4Float4FloatFloat4(float4 inStart, unsigned int x) {
-    float4 inStop = rsGetElementAt_float4(gAllocInStop, x);
-    float inAmount = rsGetElementAt_float(gAllocInAmount, x);
-    return mix(inStart, inStop, inAmount);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestMixRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestMixRelaxed.rs
deleted file mode 100644
index 6b59e70..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestMixRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestMix.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestModf.java b/tests/tests/renderscript/src/android/renderscript/cts/TestModf.java
deleted file mode 100644
index 25d7765..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestModf.java
+++ /dev/null
@@ -1,361 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestModf extends RSBaseCompute {
-
-    private ScriptC_TestModf script;
-    private ScriptC_TestModfRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestModf(mRS);
-        scriptRelaxed = new ScriptC_TestModfRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public Target.Floaty outIret;
-        public Target.Floaty out;
-    }
-
-    private void checkModfFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd655dc05ccaef47l, false);
-        try {
-            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocOutIret(outIret);
-            script.forEach_testModfFloatFloatFloat(inX, out);
-            verifyResultsModfFloatFloatFloat(inX, outIret, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutIret(outIret);
-            scriptRelaxed.forEach_testModfFloatFloatFloat(inX, out);
-            verifyResultsModfFloatFloatFloat(inX, outIret, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsModfFloatFloatFloat(Allocation inX, Allocation outIret, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayOutIret = new float[INPUTSIZE * 1];
-        outIret.copyTo(arrayOutIret);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeModf(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outIret.couldBe(arrayOutIret[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output outIret: ");
-                    message.append(args.outIret.toString());
-                    message.append("\n");
-                    message.append("Actual   output outIret: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutIret[i * 1 + j], Float.floatToRawIntBits(arrayOutIret[i * 1 + j]), arrayOutIret[i * 1 + j]));
-                    if (!args.outIret.couldBe(arrayOutIret[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkModfFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkModfFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2a1dc519fa163061l, false);
-        try {
-            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocOutIret(outIret);
-            script.forEach_testModfFloat2Float2Float2(inX, out);
-            verifyResultsModfFloat2Float2Float2(inX, outIret, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutIret(outIret);
-            scriptRelaxed.forEach_testModfFloat2Float2Float2(inX, out);
-            verifyResultsModfFloat2Float2Float2(inX, outIret, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsModfFloat2Float2Float2(Allocation inX, Allocation outIret, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayOutIret = new float[INPUTSIZE * 2];
-        outIret.copyTo(arrayOutIret);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeModf(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outIret.couldBe(arrayOutIret[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output outIret: ");
-                    message.append(args.outIret.toString());
-                    message.append("\n");
-                    message.append("Actual   output outIret: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutIret[i * 2 + j], Float.floatToRawIntBits(arrayOutIret[i * 2 + j]), arrayOutIret[i * 2 + j]));
-                    if (!args.outIret.couldBe(arrayOutIret[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkModfFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkModfFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7e82a339fbf43202l, false);
-        try {
-            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocOutIret(outIret);
-            script.forEach_testModfFloat3Float3Float3(inX, out);
-            verifyResultsModfFloat3Float3Float3(inX, outIret, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutIret(outIret);
-            scriptRelaxed.forEach_testModfFloat3Float3Float3(inX, out);
-            verifyResultsModfFloat3Float3Float3(inX, outIret, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsModfFloat3Float3Float3(Allocation inX, Allocation outIret, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOutIret = new float[INPUTSIZE * 4];
-        outIret.copyTo(arrayOutIret);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeModf(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outIret.couldBe(arrayOutIret[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output outIret: ");
-                    message.append(args.outIret.toString());
-                    message.append("\n");
-                    message.append("Actual   output outIret: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutIret[i * 4 + j], Float.floatToRawIntBits(arrayOutIret[i * 4 + j]), arrayOutIret[i * 4 + j]));
-                    if (!args.outIret.couldBe(arrayOutIret[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkModfFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkModfFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd2e78159fdd233a3l, false);
-        try {
-            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocOutIret(outIret);
-            script.forEach_testModfFloat4Float4Float4(inX, out);
-            verifyResultsModfFloat4Float4Float4(inX, outIret, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation outIret = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutIret(outIret);
-            scriptRelaxed.forEach_testModfFloat4Float4Float4(inX, out);
-            verifyResultsModfFloat4Float4Float4(inX, outIret, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsModfFloat4Float4Float4(Allocation inX, Allocation outIret, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOutIret = new float[INPUTSIZE * 4];
-        outIret.copyTo(arrayOutIret);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeModf(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outIret.couldBe(arrayOutIret[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output outIret: ");
-                    message.append(args.outIret.toString());
-                    message.append("\n");
-                    message.append("Actual   output outIret: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutIret[i * 4 + j], Float.floatToRawIntBits(arrayOutIret[i * 4 + j]), arrayOutIret[i * 4 + j]));
-                    if (!args.outIret.couldBe(arrayOutIret[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkModfFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testModf() {
-        checkModfFloatFloatFloat();
-        checkModfFloat2Float2Float2();
-        checkModfFloat3Float3Float3();
-        checkModfFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestModf.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestModf.rs
deleted file mode 100644
index be10983..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestModf.rs
+++ /dev/null
@@ -1,50 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocOutIret;
-
-float __attribute__((kernel)) testModfFloatFloatFloat(float inX, unsigned int x) {
-    float outIret = 0;
-    float out = modf(inX, &outIret);
-    rsSetElementAt_float(gAllocOutIret, outIret, x);
-    return out;
-}
-
-float2 __attribute__((kernel)) testModfFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 outIret = 0;
-    float2 out = modf(inX, &outIret);
-    rsSetElementAt_float2(gAllocOutIret, outIret, x);
-    return out;
-}
-
-float3 __attribute__((kernel)) testModfFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 outIret = 0;
-    float3 out = modf(inX, &outIret);
-    rsSetElementAt_float3(gAllocOutIret, outIret, x);
-    return out;
-}
-
-float4 __attribute__((kernel)) testModfFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 outIret = 0;
-    float4 out = modf(inX, &outIret);
-    rsSetElementAt_float4(gAllocOutIret, outIret, x);
-    return out;
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestModfRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestModfRelaxed.rs
deleted file mode 100644
index 4c9cd9a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestModfRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestModf.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNan.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNan.java
deleted file mode 100644
index 1be946d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNan.java
+++ /dev/null
@@ -1,103 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNan extends RSBaseCompute {
-
-    private ScriptC_TestNan script;
-    private ScriptC_TestNanRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNan(mRS);
-        scriptRelaxed = new ScriptC_TestNanRelaxed(mRS);
-    }
-
-    public class ArgumentsUintFloat {
-        public int in;
-        public Target.Floaty out;
-    }
-
-    private void checkNanUintFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x757e939c0e627774l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNanUintFloat(in, out);
-            verifyResultsNanUintFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNanUintFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNanUintFloat(in, out);
-            verifyResultsNanUintFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNanUintFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNanUintFloat(Allocation in, Allocation out, boolean relaxed) {
-        int[] arrayIn = new int[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsUintFloat args = new ArgumentsUintFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("0x%x", args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNanUintFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNan() {
-        checkNanUintFloat();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNan.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNan.rs
deleted file mode 100644
index bb434d6..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNan.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNanUintFloat(uint in) {
-    return nan(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNanRelaxed.rs
deleted file mode 100644
index fc7b9eb..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNanRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNan.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcos.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcos.java
deleted file mode 100644
index 430cf59..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcos.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAcos extends RSBaseCompute {
-
-    private ScriptC_TestNativeAcos script;
-    private ScriptC_TestNativeAcosRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAcos(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAcosRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAcosFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7749aa14657f3d94l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeAcosFloatFloat(inV, out);
-            verifyResultsNativeAcosFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcosFloatFloat(inV, out);
-            verifyResultsNativeAcosFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcosFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcosFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAcosFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x92e82297d87e02d8l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeAcosFloat2Float2(inV, out);
-            verifyResultsNativeAcosFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcosFloat2Float2(inV, out);
-            verifyResultsNativeAcosFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcosFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcosFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAcosFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x92e9ebb2ce9923b6l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeAcosFloat3Float3(inV, out);
-            verifyResultsNativeAcosFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcosFloat3Float3(inV, out);
-            verifyResultsNativeAcosFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcosFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcosFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAcosFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x92ebb4cdc4b44494l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeAcosFloat4Float4(inV, out);
-            verifyResultsNativeAcosFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcosFloat4Float4(inV, out);
-            verifyResultsNativeAcosFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcosFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcosFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAcos() {
-        checkNativeAcosFloatFloat();
-        checkNativeAcosFloat2Float2();
-        checkNativeAcosFloat3Float3();
-        checkNativeAcosFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcos.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcos.rs
deleted file mode 100644
index 2419c0e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcos.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeAcosFloatFloat(float inV) {
-    return native_acos(inV);
-}
-
-float2 __attribute__((kernel)) testNativeAcosFloat2Float2(float2 inV) {
-    return native_acos(inV);
-}
-
-float3 __attribute__((kernel)) testNativeAcosFloat3Float3(float3 inV) {
-    return native_acos(inV);
-}
-
-float4 __attribute__((kernel)) testNativeAcosFloat4Float4(float4 inV) {
-    return native_acos(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcosRelaxed.rs
deleted file mode 100644
index 01a9de2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcosRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAcos.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcosh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcosh.java
deleted file mode 100644
index d4a840a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcosh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAcosh extends RSBaseCompute {
-
-    private ScriptC_TestNativeAcosh script;
-    private ScriptC_TestNativeAcoshRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAcosh(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAcoshRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAcoshFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x332857238c9c505cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeAcoshFloatFloat(in, out);
-            verifyResultsNativeAcoshFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcoshFloatFloat(in, out);
-            verifyResultsNativeAcoshFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcoshFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcoshFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAcoshFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7e5c81be4638e398l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeAcoshFloat2Float2(in, out);
-            verifyResultsNativeAcoshFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcoshFloat2Float2(in, out);
-            verifyResultsNativeAcoshFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcoshFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcoshFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAcoshFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7e5c8c5fa53f7932l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeAcoshFloat3Float3(in, out);
-            verifyResultsNativeAcoshFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcoshFloat3Float3(in, out);
-            verifyResultsNativeAcoshFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcoshFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcoshFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAcoshFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7e5c970104460eccl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeAcoshFloat4Float4(in, out);
-            verifyResultsNativeAcoshFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcoshFloat4Float4(in, out);
-            verifyResultsNativeAcoshFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcoshFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcoshFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAcosh() {
-        checkNativeAcoshFloatFloat();
-        checkNativeAcoshFloat2Float2();
-        checkNativeAcoshFloat3Float3();
-        checkNativeAcoshFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcosh.rs
deleted file mode 100644
index 370f4ed..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcosh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeAcoshFloatFloat(float in) {
-    return native_acosh(in);
-}
-
-float2 __attribute__((kernel)) testNativeAcoshFloat2Float2(float2 in) {
-    return native_acosh(in);
-}
-
-float3 __attribute__((kernel)) testNativeAcoshFloat3Float3(float3 in) {
-    return native_acosh(in);
-}
-
-float4 __attribute__((kernel)) testNativeAcoshFloat4Float4(float4 in) {
-    return native_acosh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcoshRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcoshRelaxed.rs
deleted file mode 100644
index 9ea7b88..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcoshRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAcosh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcospi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcospi.java
deleted file mode 100644
index 187b787..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcospi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAcospi extends RSBaseCompute {
-
-    private ScriptC_TestNativeAcospi script;
-    private ScriptC_TestNativeAcospiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAcospi(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAcospiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAcospiFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdcf67f5599c7d8ffl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeAcospiFloatFloat(inV, out);
-            verifyResultsNativeAcospiFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcospiFloatFloat(inV, out);
-            verifyResultsNativeAcospiFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcospiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcospiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAcospiFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf038668a78e88aabl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeAcospiFloat2Float2(inV, out);
-            verifyResultsNativeAcospiFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcospiFloat2Float2(inV, out);
-            verifyResultsNativeAcospiFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcospiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcospiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAcospiFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf03a2fa56f03ab89l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeAcospiFloat3Float3(inV, out);
-            verifyResultsNativeAcospiFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcospiFloat3Float3(inV, out);
-            verifyResultsNativeAcospiFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcospiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcospiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAcospiFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf03bf8c0651ecc67l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeAcospiFloat4Float4(inV, out);
-            verifyResultsNativeAcospiFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAcospiFloat4Float4(inV, out);
-            verifyResultsNativeAcospiFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAcospiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAcospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAcospiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAcospi() {
-        checkNativeAcospiFloatFloat();
-        checkNativeAcospiFloat2Float2();
-        checkNativeAcospiFloat3Float3();
-        checkNativeAcospiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcospi.rs
deleted file mode 100644
index d9d4ae5..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcospi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeAcospiFloatFloat(float inV) {
-    return native_acospi(inV);
-}
-
-float2 __attribute__((kernel)) testNativeAcospiFloat2Float2(float2 inV) {
-    return native_acospi(inV);
-}
-
-float3 __attribute__((kernel)) testNativeAcospiFloat3Float3(float3 inV) {
-    return native_acospi(inV);
-}
-
-float4 __attribute__((kernel)) testNativeAcospiFloat4Float4(float4 inV) {
-    return native_acospi(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcospiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcospiRelaxed.rs
deleted file mode 100644
index ff6025e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAcospiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAcospi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsin.java
deleted file mode 100644
index b9f61a6..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsin.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAsin extends RSBaseCompute {
-
-    private ScriptC_TestNativeAsin script;
-    private ScriptC_TestNativeAsinRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAsin(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAsinRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAsinFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1167d6d8d3e5bc7l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeAsinFloatFloat(inV, out);
-            verifyResultsNativeAsinFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinFloatFloat(inV, out);
-            verifyResultsNativeAsinFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAsinFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdb4aa187ebdf2133l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeAsinFloat2Float2(inV, out);
-            verifyResultsNativeAsinFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinFloat2Float2(inV, out);
-            verifyResultsNativeAsinFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAsinFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdb4c6aa2e1fa4211l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeAsinFloat3Float3(inV, out);
-            verifyResultsNativeAsinFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinFloat3Float3(inV, out);
-            verifyResultsNativeAsinFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAsinFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xdb4e33bdd81562efl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeAsinFloat4Float4(inV, out);
-            verifyResultsNativeAsinFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinFloat4Float4(inV, out);
-            verifyResultsNativeAsinFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAsin() {
-        checkNativeAsinFloatFloat();
-        checkNativeAsinFloat2Float2();
-        checkNativeAsinFloat3Float3();
-        checkNativeAsinFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsin.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsin.rs
deleted file mode 100644
index 28b8173..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsin.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeAsinFloatFloat(float inV) {
-    return native_asin(inV);
-}
-
-float2 __attribute__((kernel)) testNativeAsinFloat2Float2(float2 inV) {
-    return native_asin(inV);
-}
-
-float3 __attribute__((kernel)) testNativeAsinFloat3Float3(float3 inV) {
-    return native_asin(inV);
-}
-
-float4 __attribute__((kernel)) testNativeAsinFloat4Float4(float4 inV) {
-    return native_asin(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinRelaxed.rs
deleted file mode 100644
index 9d04b24..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAsin.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinh.java
deleted file mode 100644
index f8382a8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAsinh extends RSBaseCompute {
-
-    private ScriptC_TestNativeAsinh script;
-    private ScriptC_TestNativeAsinhRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAsinh(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAsinhRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAsinhFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbcf52a7cb45b6e8fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeAsinhFloatFloat(in, out);
-            verifyResultsNativeAsinhFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinhFloatFloat(in, out);
-            verifyResultsNativeAsinhFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinhFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAsinhFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc6bf00ae599a01f3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeAsinhFloat2Float2(in, out);
-            verifyResultsNativeAsinhFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinhFloat2Float2(in, out);
-            verifyResultsNativeAsinhFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinhFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAsinhFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc6bf0b4fb8a0978dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeAsinhFloat3Float3(in, out);
-            verifyResultsNativeAsinhFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinhFloat3Float3(in, out);
-            verifyResultsNativeAsinhFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinhFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAsinhFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc6bf15f117a72d27l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeAsinhFloat4Float4(in, out);
-            verifyResultsNativeAsinhFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinhFloat4Float4(in, out);
-            verifyResultsNativeAsinhFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinhFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAsinh() {
-        checkNativeAsinhFloatFloat();
-        checkNativeAsinhFloat2Float2();
-        checkNativeAsinhFloat3Float3();
-        checkNativeAsinhFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinh.rs
deleted file mode 100644
index 2c40a7a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeAsinhFloatFloat(float in) {
-    return native_asinh(in);
-}
-
-float2 __attribute__((kernel)) testNativeAsinhFloat2Float2(float2 in) {
-    return native_asinh(in);
-}
-
-float3 __attribute__((kernel)) testNativeAsinhFloat3Float3(float3 in) {
-    return native_asinh(in);
-}
-
-float4 __attribute__((kernel)) testNativeAsinhFloat4Float4(float4 in) {
-    return native_asinh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinhRelaxed.rs
deleted file mode 100644
index 1155084..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinhRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAsinh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinpi.java
deleted file mode 100644
index e0029b7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinpi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAsinpi extends RSBaseCompute {
-
-    private ScriptC_TestNativeAsinpi script;
-    private ScriptC_TestNativeAsinpiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAsinpi(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAsinpiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAsinpiFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2558fe45ad28f75al, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeAsinpiFloatFloat(inV, out);
-            verifyResultsNativeAsinpiFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinpiFloatFloat(inV, out);
-            verifyResultsNativeAsinpiFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinpiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAsinpiFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbf9f3a86715cc9eel, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeAsinpiFloat2Float2(inV, out);
-            verifyResultsNativeAsinpiFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinpiFloat2Float2(inV, out);
-            verifyResultsNativeAsinpiFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinpiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAsinpiFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbfa103a16777eaccl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeAsinpiFloat3Float3(inV, out);
-            verifyResultsNativeAsinpiFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinpiFloat3Float3(inV, out);
-            verifyResultsNativeAsinpiFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinpiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAsinpiFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbfa2ccbc5d930baal, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeAsinpiFloat4Float4(inV, out);
-            verifyResultsNativeAsinpiFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAsinpiFloat4Float4(inV, out);
-            verifyResultsNativeAsinpiFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAsinpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAsinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAsinpiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAsinpi() {
-        checkNativeAsinpiFloatFloat();
-        checkNativeAsinpiFloat2Float2();
-        checkNativeAsinpiFloat3Float3();
-        checkNativeAsinpiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinpi.rs
deleted file mode 100644
index f08c041..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinpi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeAsinpiFloatFloat(float inV) {
-    return native_asinpi(inV);
-}
-
-float2 __attribute__((kernel)) testNativeAsinpiFloat2Float2(float2 inV) {
-    return native_asinpi(inV);
-}
-
-float3 __attribute__((kernel)) testNativeAsinpiFloat3Float3(float3 inV) {
-    return native_asinpi(inV);
-}
-
-float4 __attribute__((kernel)) testNativeAsinpiFloat4Float4(float4 inV) {
-    return native_asinpi(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinpiRelaxed.rs
deleted file mode 100644
index 83a97d3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAsinpiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAsinpi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan.java
deleted file mode 100644
index 26225c5..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAtan extends RSBaseCompute {
-
-    private ScriptC_TestNativeAtan script;
-    private ScriptC_TestNativeAtanRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAtan(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAtanRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAtanFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xaafbf9b325b34e42l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeAtanFloatFloat(inV, out);
-            verifyResultsNativeAtanFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanFloatFloat(inV, out);
-            verifyResultsNativeAtanFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtanFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf5c93432108a7b96l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeAtanFloat2Float2(inV, out);
-            verifyResultsNativeAtanFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanFloat2Float2(inV, out);
-            verifyResultsNativeAtanFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtanFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf5cafd4d06a59c74l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeAtanFloat3Float3(inV, out);
-            verifyResultsNativeAtanFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanFloat3Float3(inV, out);
-            verifyResultsNativeAtanFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtanFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf5ccc667fcc0bd52l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeAtanFloat4Float4(inV, out);
-            verifyResultsNativeAtanFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanFloat4Float4(inV, out);
-            verifyResultsNativeAtanFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAtan() {
-        checkNativeAtanFloatFloat();
-        checkNativeAtanFloat2Float2();
-        checkNativeAtanFloat3Float3();
-        checkNativeAtanFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan.rs
deleted file mode 100644
index f15e5fd..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeAtanFloatFloat(float inV) {
-    return native_atan(inV);
-}
-
-float2 __attribute__((kernel)) testNativeAtanFloat2Float2(float2 inV) {
-    return native_atan(inV);
-}
-
-float3 __attribute__((kernel)) testNativeAtanFloat3Float3(float3 inV) {
-    return native_atan(inV);
-}
-
-float4 __attribute__((kernel)) testNativeAtanFloat4Float4(float4 inV) {
-    return native_atan(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2.java
deleted file mode 100644
index c33523c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAtan2 extends RSBaseCompute {
-
-    private ScriptC_TestNativeAtan2 script;
-    private ScriptC_TestNativeAtan2Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAtan2(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAtan2Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inY;
-        public float inX;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAtan2FloatFloatFloat() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4ecf7d3b9e2a276fl, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4ecf7d3b9e2a276el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testNativeAtan2FloatFloatFloat(inY, out);
-            verifyResultsNativeAtan2FloatFloatFloat(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2FloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testNativeAtan2FloatFloatFloat(inY, out);
-            verifyResultsNativeAtan2FloatFloatFloat(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2FloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtan2FloatFloatFloat(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i];
-                args.inX = arrayInX[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtan2FloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtan2Float2Float2Float2() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3c2d1a09d1c2a8c7l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3c2d1a09d1c2a8c6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testNativeAtan2Float2Float2Float2(inY, out);
-            verifyResultsNativeAtan2Float2Float2Float2(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testNativeAtan2Float2Float2Float2(inY, out);
-            verifyResultsNativeAtan2Float2Float2Float2(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtan2Float2Float2Float2(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 2 + j];
-                args.inX = arrayInX[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtan2Float2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtan2Float3Float3Float3() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9091f829d3a0aa68l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9091f829d3a0aa67l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testNativeAtan2Float3Float3Float3(inY, out);
-            verifyResultsNativeAtan2Float3Float3Float3(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testNativeAtan2Float3Float3Float3(inY, out);
-            verifyResultsNativeAtan2Float3Float3Float3(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtan2Float3Float3Float3(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 4 + j];
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtan2Float3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtan2Float4Float4Float4() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe4f6d649d57eac09l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe4f6d649d57eac08l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testNativeAtan2Float4Float4Float4(inY, out);
-            verifyResultsNativeAtan2Float4Float4Float4(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testNativeAtan2Float4Float4Float4(inY, out);
-            verifyResultsNativeAtan2Float4Float4Float4(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtan2Float4Float4Float4(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 4 + j];
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtan2Float4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAtan2() {
-        checkNativeAtan2FloatFloatFloat();
-        checkNativeAtan2Float2Float2Float2();
-        checkNativeAtan2Float3Float3Float3();
-        checkNativeAtan2Float4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2.rs
deleted file mode 100644
index 3ab222c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInX;
-
-float __attribute__((kernel)) testNativeAtan2FloatFloatFloat(float inY, unsigned int x) {
-    float inX = rsGetElementAt_float(gAllocInX, x);
-    return native_atan2(inY, inX);
-}
-
-float2 __attribute__((kernel)) testNativeAtan2Float2Float2Float2(float2 inY, unsigned int x) {
-    float2 inX = rsGetElementAt_float2(gAllocInX, x);
-    return native_atan2(inY, inX);
-}
-
-float3 __attribute__((kernel)) testNativeAtan2Float3Float3Float3(float3 inY, unsigned int x) {
-    float3 inX = rsGetElementAt_float3(gAllocInX, x);
-    return native_atan2(inY, inX);
-}
-
-float4 __attribute__((kernel)) testNativeAtan2Float4Float4Float4(float4 inY, unsigned int x) {
-    float4 inX = rsGetElementAt_float4(gAllocInX, x);
-    return native_atan2(inY, inX);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2Relaxed.rs
deleted file mode 100644
index 40e8b3e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAtan2.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2pi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2pi.java
deleted file mode 100644
index dd62b78..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2pi.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAtan2pi extends RSBaseCompute {
-
-    private ScriptC_TestNativeAtan2pi script;
-    private ScriptC_TestNativeAtan2piRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAtan2pi(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAtan2piRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inY;
-        public float inX;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAtan2piFloatFloatFloat() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x39c4f8fd35fc5dc8l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x39c4f8fd35fc5dc7l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testNativeAtan2piFloatFloatFloat(inY, out);
-            verifyResultsNativeAtan2piFloatFloatFloat(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testNativeAtan2piFloatFloatFloat(inY, out);
-            verifyResultsNativeAtan2piFloatFloatFloat(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtan2piFloatFloatFloat(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i];
-                args.inX = arrayInX[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan2pi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtan2piFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtan2piFloat2Float2Float2() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6aff980c8d47a3e2l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6aff980c8d47a3e1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testNativeAtan2piFloat2Float2Float2(inY, out);
-            verifyResultsNativeAtan2piFloat2Float2Float2(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testNativeAtan2piFloat2Float2Float2(inY, out);
-            verifyResultsNativeAtan2piFloat2Float2Float2(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtan2piFloat2Float2Float2(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 2 + j];
-                args.inX = arrayInX[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan2pi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtan2piFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtan2piFloat3Float3Float3() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbf64762c8f25a583l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbf64762c8f25a582l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testNativeAtan2piFloat3Float3Float3(inY, out);
-            verifyResultsNativeAtan2piFloat3Float3Float3(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testNativeAtan2piFloat3Float3Float3(inY, out);
-            verifyResultsNativeAtan2piFloat3Float3Float3(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtan2piFloat3Float3Float3(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 4 + j];
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan2pi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtan2piFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtan2piFloat4Float4Float4() {
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x13c9544c9103a724l, false);
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x13c9544c9103a723l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInX(inX);
-            script.forEach_testNativeAtan2piFloat4Float4Float4(inY, out);
-            verifyResultsNativeAtan2piFloat4Float4Float4(inY, inX, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInX(inX);
-            scriptRelaxed.forEach_testNativeAtan2piFloat4Float4Float4(inY, out);
-            verifyResultsNativeAtan2piFloat4Float4Float4(inY, inX, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtan2piFloat4Float4Float4(Allocation inY, Allocation inX, Allocation out, boolean relaxed) {
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inY = arrayInY[i * 4 + j];
-                args.inX = arrayInX[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtan2pi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtan2piFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAtan2pi() {
-        checkNativeAtan2piFloatFloatFloat();
-        checkNativeAtan2piFloat2Float2Float2();
-        checkNativeAtan2piFloat3Float3Float3();
-        checkNativeAtan2piFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2pi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2pi.rs
deleted file mode 100644
index ea3e3f9..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2pi.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInX;
-
-float __attribute__((kernel)) testNativeAtan2piFloatFloatFloat(float inY, unsigned int x) {
-    float inX = rsGetElementAt_float(gAllocInX, x);
-    return native_atan2pi(inY, inX);
-}
-
-float2 __attribute__((kernel)) testNativeAtan2piFloat2Float2Float2(float2 inY, unsigned int x) {
-    float2 inX = rsGetElementAt_float2(gAllocInX, x);
-    return native_atan2pi(inY, inX);
-}
-
-float3 __attribute__((kernel)) testNativeAtan2piFloat3Float3Float3(float3 inY, unsigned int x) {
-    float3 inX = rsGetElementAt_float3(gAllocInX, x);
-    return native_atan2pi(inY, inX);
-}
-
-float4 __attribute__((kernel)) testNativeAtan2piFloat4Float4Float4(float4 inY, unsigned int x) {
-    float4 inX = rsGetElementAt_float4(gAllocInX, x);
-    return native_atan2pi(inY, inX);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2piRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2piRelaxed.rs
deleted file mode 100644
index e301936..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtan2piRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAtan2pi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanRelaxed.rs
deleted file mode 100644
index 083f168..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAtan.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanh.java
deleted file mode 100644
index 6161483..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAtanh extends RSBaseCompute {
-
-    private ScriptC_TestNativeAtanh script;
-    private ScriptC_TestNativeAtanhRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAtanh(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAtanhRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inIn;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAtanhFloatFloat() {
-        Allocation inIn = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe13e715ccd0cedebl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeAtanhFloatFloat(inIn, out);
-            verifyResultsNativeAtanhFloatFloat(inIn, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanhFloatFloat(inIn, out);
-            verifyResultsNativeAtanhFloatFloat(inIn, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanhFloatFloat(Allocation inIn, Allocation out, boolean relaxed) {
-        float[] arrayInIn = new float[INPUTSIZE * 1];
-        inIn.copyTo(arrayInIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inIn = arrayInIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inIn: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inIn, Float.floatToRawIntBits(args.inIn), args.inIn));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanhFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtanhFloat2Float2() {
-        Allocation inIn = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd5bd3a2802f7f5d7l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeAtanhFloat2Float2(inIn, out);
-            verifyResultsNativeAtanhFloat2Float2(inIn, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanhFloat2Float2(inIn, out);
-            verifyResultsNativeAtanhFloat2Float2(inIn, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanhFloat2Float2(Allocation inIn, Allocation out, boolean relaxed) {
-        float[] arrayInIn = new float[INPUTSIZE * 2];
-        inIn.copyTo(arrayInIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inIn = arrayInIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inIn: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inIn, Float.floatToRawIntBits(args.inIn), args.inIn));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanhFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtanhFloat3Float3() {
-        Allocation inIn = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd60a01af59867b21l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeAtanhFloat3Float3(inIn, out);
-            verifyResultsNativeAtanhFloat3Float3(inIn, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanhFloat3Float3(inIn, out);
-            verifyResultsNativeAtanhFloat3Float3(inIn, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanhFloat3Float3(Allocation inIn, Allocation out, boolean relaxed) {
-        float[] arrayInIn = new float[INPUTSIZE * 4];
-        inIn.copyTo(arrayInIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inIn = arrayInIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inIn: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inIn, Float.floatToRawIntBits(args.inIn), args.inIn));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanhFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtanhFloat4Float4() {
-        Allocation inIn = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd656c936b015006bl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeAtanhFloat4Float4(inIn, out);
-            verifyResultsNativeAtanhFloat4Float4(inIn, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanhFloat4Float4(inIn, out);
-            verifyResultsNativeAtanhFloat4Float4(inIn, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanhFloat4Float4(Allocation inIn, Allocation out, boolean relaxed) {
-        float[] arrayInIn = new float[INPUTSIZE * 4];
-        inIn.copyTo(arrayInIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inIn = arrayInIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inIn: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inIn, Float.floatToRawIntBits(args.inIn), args.inIn));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanhFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAtanh() {
-        checkNativeAtanhFloatFloat();
-        checkNativeAtanhFloat2Float2();
-        checkNativeAtanhFloat3Float3();
-        checkNativeAtanhFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanh.rs
deleted file mode 100644
index de772e7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeAtanhFloatFloat(float inIn) {
-    return native_atanh(inIn);
-}
-
-float2 __attribute__((kernel)) testNativeAtanhFloat2Float2(float2 inIn) {
-    return native_atanh(inIn);
-}
-
-float3 __attribute__((kernel)) testNativeAtanhFloat3Float3(float3 inIn) {
-    return native_atanh(inIn);
-}
-
-float4 __attribute__((kernel)) testNativeAtanhFloat4Float4(float4 inIn) {
-    return native_atanh(inIn);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanhRelaxed.rs
deleted file mode 100644
index 40442c7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanhRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAtanh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanpi.java
deleted file mode 100644
index 1e88568..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanpi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeAtanpi extends RSBaseCompute {
-
-    private ScriptC_TestNativeAtanpi script;
-    private ScriptC_TestNativeAtanpiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeAtanpi(mRS);
-        scriptRelaxed = new ScriptC_TestNativeAtanpiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeAtanpiFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3fd790efd1d451bdl, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeAtanpiFloatFloat(inV, out);
-            verifyResultsNativeAtanpiFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanpiFloatFloat(inV, out);
-            verifyResultsNativeAtanpiFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanpiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtanpiFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1bd089694afc9ef9l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeAtanpiFloat2Float2(inV, out);
-            verifyResultsNativeAtanpiFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanpiFloat2Float2(inV, out);
-            verifyResultsNativeAtanpiFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanpiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtanpiFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1bd252844117bfd7l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeAtanpiFloat3Float3(inV, out);
-            verifyResultsNativeAtanpiFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanpiFloat3Float3(inV, out);
-            verifyResultsNativeAtanpiFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanpiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeAtanpiFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1bd41b9f3732e0b5l, -1, 1);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeAtanpiFloat4Float4(inV, out);
-            verifyResultsNativeAtanpiFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeAtanpiFloat4Float4(inV, out);
-            verifyResultsNativeAtanpiFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeAtanpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeAtanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeAtanpiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeAtanpi() {
-        checkNativeAtanpiFloatFloat();
-        checkNativeAtanpiFloat2Float2();
-        checkNativeAtanpiFloat3Float3();
-        checkNativeAtanpiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanpi.rs
deleted file mode 100644
index 19d5262..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanpi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeAtanpiFloatFloat(float inV) {
-    return native_atanpi(inV);
-}
-
-float2 __attribute__((kernel)) testNativeAtanpiFloat2Float2(float2 inV) {
-    return native_atanpi(inV);
-}
-
-float3 __attribute__((kernel)) testNativeAtanpiFloat3Float3(float3 inV) {
-    return native_atanpi(inV);
-}
-
-float4 __attribute__((kernel)) testNativeAtanpiFloat4Float4(float4 inV) {
-    return native_atanpi(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanpiRelaxed.rs
deleted file mode 100644
index 7758862d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeAtanpiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeAtanpi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCbrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCbrt.java
deleted file mode 100644
index cd6a030..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCbrt.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeCbrt extends RSBaseCompute {
-
-    private ScriptC_TestNativeCbrt script;
-    private ScriptC_TestNativeCbrtRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeCbrt(mRS);
-        scriptRelaxed = new ScriptC_TestNativeCbrtRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeCbrtFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6eed1901e2ca9d19l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeCbrtFloatFloat(in, out);
-            verifyResultsNativeCbrtFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCbrtFloatFloat(in, out);
-            verifyResultsNativeCbrtFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCbrtFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCbrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCbrtFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCbrtFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2e78c09abaa124adl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeCbrtFloat2Float2(in, out);
-            verifyResultsNativeCbrtFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCbrtFloat2Float2(in, out);
-            verifyResultsNativeCbrtFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCbrtFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCbrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCbrtFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCbrtFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2e78cb3c19a7ba47l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeCbrtFloat3Float3(in, out);
-            verifyResultsNativeCbrtFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCbrtFloat3Float3(in, out);
-            verifyResultsNativeCbrtFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCbrtFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCbrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCbrtFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCbrtFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2e78d5dd78ae4fe1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeCbrtFloat4Float4(in, out);
-            verifyResultsNativeCbrtFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCbrtFloat4Float4(in, out);
-            verifyResultsNativeCbrtFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCbrtFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCbrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCbrtFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeCbrt() {
-        checkNativeCbrtFloatFloat();
-        checkNativeCbrtFloat2Float2();
-        checkNativeCbrtFloat3Float3();
-        checkNativeCbrtFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCbrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCbrt.rs
deleted file mode 100644
index 828214b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCbrt.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeCbrtFloatFloat(float in) {
-    return native_cbrt(in);
-}
-
-float2 __attribute__((kernel)) testNativeCbrtFloat2Float2(float2 in) {
-    return native_cbrt(in);
-}
-
-float3 __attribute__((kernel)) testNativeCbrtFloat3Float3(float3 in) {
-    return native_cbrt(in);
-}
-
-float4 __attribute__((kernel)) testNativeCbrtFloat4Float4(float4 in) {
-    return native_cbrt(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCbrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCbrtRelaxed.rs
deleted file mode 100644
index 2a49b9e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCbrtRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeCbrt.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCos.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCos.java
deleted file mode 100644
index d7c9ebf..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCos.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeCos extends RSBaseCompute {
-
-    private ScriptC_TestNativeCos script;
-    private ScriptC_TestNativeCosRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeCos(mRS);
-        scriptRelaxed = new ScriptC_TestNativeCosRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeCosFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x95ef4a20c73e7e3dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeCosFloatFloat(in, out);
-            verifyResultsNativeCosFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCosFloatFloat(in, out);
-            verifyResultsNativeCosFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCosFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCosFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCosFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xed4d88bac39641b1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeCosFloat2Float2(in, out);
-            verifyResultsNativeCosFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCosFloat2Float2(in, out);
-            verifyResultsNativeCosFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCosFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCosFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCosFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xed4d935c229cd74bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeCosFloat3Float3(in, out);
-            verifyResultsNativeCosFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCosFloat3Float3(in, out);
-            verifyResultsNativeCosFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCosFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCosFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCosFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xed4d9dfd81a36ce5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeCosFloat4Float4(in, out);
-            verifyResultsNativeCosFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCosFloat4Float4(in, out);
-            verifyResultsNativeCosFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCosFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCosFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeCos() {
-        checkNativeCosFloatFloat();
-        checkNativeCosFloat2Float2();
-        checkNativeCosFloat3Float3();
-        checkNativeCosFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCos.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCos.rs
deleted file mode 100644
index 212c12e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCos.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeCosFloatFloat(float in) {
-    return native_cos(in);
-}
-
-float2 __attribute__((kernel)) testNativeCosFloat2Float2(float2 in) {
-    return native_cos(in);
-}
-
-float3 __attribute__((kernel)) testNativeCosFloat3Float3(float3 in) {
-    return native_cos(in);
-}
-
-float4 __attribute__((kernel)) testNativeCosFloat4Float4(float4 in) {
-    return native_cos(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCosRelaxed.rs
deleted file mode 100644
index 66f3fef..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCosRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeCos.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCosh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCosh.java
deleted file mode 100644
index 4e841c60..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCosh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeCosh extends RSBaseCompute {
-
-    private ScriptC_TestNativeCosh script;
-    private ScriptC_TestNativeCoshRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeCosh(mRS);
-        scriptRelaxed = new ScriptC_TestNativeCoshRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeCoshFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xeb1020909e9c475dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeCoshFloatFloat(in, out);
-            verifyResultsNativeCoshFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCoshFloatFloat(in, out);
-            verifyResultsNativeCoshFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCoshFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCoshFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCoshFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc77a568547f7e9d1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeCoshFloat2Float2(in, out);
-            verifyResultsNativeCoshFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCoshFloat2Float2(in, out);
-            verifyResultsNativeCoshFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCoshFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCoshFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCoshFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc77a6126a6fe7f6bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeCoshFloat3Float3(in, out);
-            verifyResultsNativeCoshFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCoshFloat3Float3(in, out);
-            verifyResultsNativeCoshFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCoshFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCoshFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCoshFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc77a6bc806051505l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeCoshFloat4Float4(in, out);
-            verifyResultsNativeCoshFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCoshFloat4Float4(in, out);
-            verifyResultsNativeCoshFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCoshFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCosh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCoshFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeCosh() {
-        checkNativeCoshFloatFloat();
-        checkNativeCoshFloat2Float2();
-        checkNativeCoshFloat3Float3();
-        checkNativeCoshFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCosh.rs
deleted file mode 100644
index f3635d8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCosh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeCoshFloatFloat(float in) {
-    return native_cosh(in);
-}
-
-float2 __attribute__((kernel)) testNativeCoshFloat2Float2(float2 in) {
-    return native_cosh(in);
-}
-
-float3 __attribute__((kernel)) testNativeCoshFloat3Float3(float3 in) {
-    return native_cosh(in);
-}
-
-float4 __attribute__((kernel)) testNativeCoshFloat4Float4(float4 in) {
-    return native_cosh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCoshRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCoshRelaxed.rs
deleted file mode 100644
index 138b5c2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCoshRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeCosh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCospi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCospi.java
deleted file mode 100644
index ab5065b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCospi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeCospi extends RSBaseCompute {
-
-    private ScriptC_TestNativeCospi script;
-    private ScriptC_TestNativeCospiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeCospi(mRS);
-        scriptRelaxed = new ScriptC_TestNativeCospiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeCospiFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8fc4f0187aafc9a6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeCospiFloatFloat(in, out);
-            verifyResultsNativeCospiFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCospiFloatFloat(in, out);
-            verifyResultsNativeCospiFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCospiFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCospiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCospiFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x656942c9d0dfeb12l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeCospiFloat2Float2(in, out);
-            verifyResultsNativeCospiFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCospiFloat2Float2(in, out);
-            verifyResultsNativeCospiFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCospiFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCospiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCospiFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x65694d6b2fe680acl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeCospiFloat3Float3(in, out);
-            verifyResultsNativeCospiFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCospiFloat3Float3(in, out);
-            verifyResultsNativeCospiFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCospiFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCospiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeCospiFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6569580c8eed1646l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeCospiFloat4Float4(in, out);
-            verifyResultsNativeCospiFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeCospiFloat4Float4(in, out);
-            verifyResultsNativeCospiFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeCospiFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeCospi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeCospiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeCospi() {
-        checkNativeCospiFloatFloat();
-        checkNativeCospiFloat2Float2();
-        checkNativeCospiFloat3Float3();
-        checkNativeCospiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCospi.rs
deleted file mode 100644
index 471403f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCospi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeCospiFloatFloat(float in) {
-    return native_cospi(in);
-}
-
-float2 __attribute__((kernel)) testNativeCospiFloat2Float2(float2 in) {
-    return native_cospi(in);
-}
-
-float3 __attribute__((kernel)) testNativeCospiFloat3Float3(float3 in) {
-    return native_cospi(in);
-}
-
-float4 __attribute__((kernel)) testNativeCospiFloat4Float4(float4 in) {
-    return native_cospi(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCospiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCospiRelaxed.rs
deleted file mode 100644
index f72429e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeCospiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeCospi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDistance.java
deleted file mode 100644
index 360da34..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDistance.java
+++ /dev/null
@@ -1,357 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeDistance extends RSBaseCompute {
-
-    private ScriptC_TestNativeDistance script;
-    private ScriptC_TestNativeDistanceRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeDistance(mRS);
-        scriptRelaxed = new ScriptC_TestNativeDistanceRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inLhs;
-        public float inRhs;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeDistanceFloatFloatFloat() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe0fd4252f8556ff6l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe0fd4252f8559b4cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testNativeDistanceFloatFloatFloat(inLhs, out);
-            verifyResultsNativeDistanceFloatFloatFloat(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testNativeDistanceFloatFloatFloat(inLhs, out);
-            verifyResultsNativeDistanceFloatFloatFloat(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeDistanceFloatFloatFloat(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 1];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 1];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inLhs = arrayInLhs[i];
-            args.inRhs = arrayInRhs[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNativeDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inLhs: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInLhs[i], Float.floatToRawIntBits(arrayInLhs[i]), arrayInLhs[i]));
-                message.append("\n");
-                message.append("Input inRhs: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInRhs[i], Float.floatToRawIntBits(arrayInRhs[i]), arrayInRhs[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNativeDistanceFloatFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloatNFloat {
-        public float[] inLhs;
-        public float[] inRhs;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeDistanceFloat2Float2Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x28a9ea2ea1fd926al, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x28a9ea2ea1fdbdc0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testNativeDistanceFloat2Float2Float(inLhs, out);
-            verifyResultsNativeDistanceFloat2Float2Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat2Float2Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testNativeDistanceFloat2Float2Float(inLhs, out);
-            verifyResultsNativeDistanceFloat2Float2Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat2Float2Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeDistanceFloat2Float2Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 2];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 2];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[2];
-            args.inRhs = new float[2];
-            // Fill args with the input values
-            for (int j = 0; j < 2 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 2 + j];
-            }
-            for (int j = 0; j < 2 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 2 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNativeDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 2 + j], Float.floatToRawIntBits(arrayInLhs[i * 2 + j]), arrayInLhs[i * 2 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 2 + j], Float.floatToRawIntBits(arrayInRhs[i * 2 + j]), arrayInRhs[i * 2 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNativeDistanceFloat2Float2Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkNativeDistanceFloat3Float3Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x559b398ef213adc4l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x559b398ef213d91al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testNativeDistanceFloat3Float3Float(inLhs, out);
-            verifyResultsNativeDistanceFloat3Float3Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat3Float3Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testNativeDistanceFloat3Float3Float(inLhs, out);
-            verifyResultsNativeDistanceFloat3Float3Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat3Float3Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeDistanceFloat3Float3Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[3];
-            args.inRhs = new float[3];
-            // Fill args with the input values
-            for (int j = 0; j < 3 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 3 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNativeDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNativeDistanceFloat3Float3Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkNativeDistanceFloat4Float4Float() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x828c88ef4229c91el, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x828c88ef4229f474l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testNativeDistanceFloat4Float4Float(inLhs, out);
-            verifyResultsNativeDistanceFloat4Float4Float(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat4Float4Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testNativeDistanceFloat4Float4Float(inLhs, out);
-            verifyResultsNativeDistanceFloat4Float4Float(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat4Float4Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeDistanceFloat4Float4Float(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inLhs = new float[4];
-            args.inRhs = new float[4];
-            // Fill args with the input values
-            for (int j = 0; j < 4 ; j++) {
-                args.inLhs[j] = arrayInLhs[i * 4 + j];
-            }
-            for (int j = 0; j < 4 ; j++) {
-                args.inRhs[j] = arrayInRhs[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNativeDistance(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInLhs[i * 4 + j], Float.floatToRawIntBits(arrayInLhs[i * 4 + j]), arrayInLhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInRhs[i * 4 + j], Float.floatToRawIntBits(arrayInRhs[i * 4 + j]), arrayInRhs[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNativeDistanceFloat4Float4Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testNativeDistance() {
-        checkNativeDistanceFloatFloatFloat();
-        checkNativeDistanceFloat2Float2Float();
-        checkNativeDistanceFloat3Float3Float();
-        checkNativeDistanceFloat4Float4Float();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDistance.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDistance.rs
deleted file mode 100644
index d9c215c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDistance.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInRhs;
-
-float __attribute__((kernel)) testNativeDistanceFloatFloatFloat(float inLhs, unsigned int x) {
-    float inRhs = rsGetElementAt_float(gAllocInRhs, x);
-    return native_distance(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testNativeDistanceFloat2Float2Float(float2 inLhs, unsigned int x) {
-    float2 inRhs = rsGetElementAt_float2(gAllocInRhs, x);
-    return native_distance(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testNativeDistanceFloat3Float3Float(float3 inLhs, unsigned int x) {
-    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
-    return native_distance(inLhs, inRhs);
-}
-
-float __attribute__((kernel)) testNativeDistanceFloat4Float4Float(float4 inLhs, unsigned int x) {
-    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
-    return native_distance(inLhs, inRhs);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDistanceRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDistanceRelaxed.rs
deleted file mode 100644
index 167b79a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDistanceRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeDistance.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDivide.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDivide.java
deleted file mode 100644
index c546724..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDivide.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeDivide extends RSBaseCompute {
-
-    private ScriptC_TestNativeDivide script;
-    private ScriptC_TestNativeDivideRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeDivide(mRS);
-        scriptRelaxed = new ScriptC_TestNativeDivideRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inLhs;
-        public float inRhs;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeDivideFloatFloatFloat() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe2845ef0c23d02del, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe2845ef0c23d2e34l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testNativeDivideFloatFloatFloat(inLhs, out);
-            verifyResultsNativeDivideFloatFloatFloat(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testNativeDivideFloatFloatFloat(inLhs, out);
-            verifyResultsNativeDivideFloatFloatFloat(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeDivideFloatFloatFloat(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 1];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 1];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inLhs = arrayInLhs[i];
-                args.inRhs = arrayInRhs[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeDivide(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inLhs, Float.floatToRawIntBits(args.inLhs), args.inLhs));
-                    message.append("\n");
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inRhs, Float.floatToRawIntBits(args.inRhs), args.inRhs));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeDivideFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeDivideFloat2Float2Float2() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x51c6d6ecaeab1c48l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x51c6d6ecaeab479el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testNativeDivideFloat2Float2Float2(inLhs, out);
-            verifyResultsNativeDivideFloat2Float2Float2(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testNativeDivideFloat2Float2Float2(inLhs, out);
-            verifyResultsNativeDivideFloat2Float2Float2(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeDivideFloat2Float2Float2(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 2];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 2];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inLhs = arrayInLhs[i * 2 + j];
-                args.inRhs = arrayInRhs[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeDivide(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inLhs, Float.floatToRawIntBits(args.inLhs), args.inLhs));
-                    message.append("\n");
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inRhs, Float.floatToRawIntBits(args.inRhs), args.inRhs));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeDivideFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeDivideFloat3Float3Float3() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xde4f2c1a2b24e021l, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xde4f2c1a2b250b77l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testNativeDivideFloat3Float3Float3(inLhs, out);
-            verifyResultsNativeDivideFloat3Float3Float3(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testNativeDivideFloat3Float3Float3(inLhs, out);
-            verifyResultsNativeDivideFloat3Float3Float3(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeDivideFloat3Float3Float3(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inLhs = arrayInLhs[i * 4 + j];
-                args.inRhs = arrayInRhs[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeDivide(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inLhs, Float.floatToRawIntBits(args.inLhs), args.inLhs));
-                    message.append("\n");
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inRhs, Float.floatToRawIntBits(args.inRhs), args.inRhs));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeDivideFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeDivideFloat4Float4Float4() {
-        Allocation inLhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6ad78147a79ea3fal, false);
-        Allocation inRhs = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6ad78147a79ecf50l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInRhs(inRhs);
-            script.forEach_testNativeDivideFloat4Float4Float4(inLhs, out);
-            verifyResultsNativeDivideFloat4Float4Float4(inLhs, inRhs, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInRhs(inRhs);
-            scriptRelaxed.forEach_testNativeDivideFloat4Float4Float4(inLhs, out);
-            verifyResultsNativeDivideFloat4Float4Float4(inLhs, inRhs, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeDivideFloat4Float4Float4(Allocation inLhs, Allocation inRhs, Allocation out, boolean relaxed) {
-        float[] arrayInLhs = new float[INPUTSIZE * 4];
-        inLhs.copyTo(arrayInLhs);
-        float[] arrayInRhs = new float[INPUTSIZE * 4];
-        inRhs.copyTo(arrayInRhs);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inLhs = arrayInLhs[i * 4 + j];
-                args.inRhs = arrayInRhs[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeDivide(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inLhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inLhs, Float.floatToRawIntBits(args.inLhs), args.inLhs));
-                    message.append("\n");
-                    message.append("Input inRhs: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inRhs, Float.floatToRawIntBits(args.inRhs), args.inRhs));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeDivideFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeDivide() {
-        checkNativeDivideFloatFloatFloat();
-        checkNativeDivideFloat2Float2Float2();
-        checkNativeDivideFloat3Float3Float3();
-        checkNativeDivideFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDivide.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDivide.rs
deleted file mode 100644
index ee36b50..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDivide.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInRhs;
-
-float __attribute__((kernel)) testNativeDivideFloatFloatFloat(float inLhs, unsigned int x) {
-    float inRhs = rsGetElementAt_float(gAllocInRhs, x);
-    return native_divide(inLhs, inRhs);
-}
-
-float2 __attribute__((kernel)) testNativeDivideFloat2Float2Float2(float2 inLhs, unsigned int x) {
-    float2 inRhs = rsGetElementAt_float2(gAllocInRhs, x);
-    return native_divide(inLhs, inRhs);
-}
-
-float3 __attribute__((kernel)) testNativeDivideFloat3Float3Float3(float3 inLhs, unsigned int x) {
-    float3 inRhs = rsGetElementAt_float3(gAllocInRhs, x);
-    return native_divide(inLhs, inRhs);
-}
-
-float4 __attribute__((kernel)) testNativeDivideFloat4Float4Float4(float4 inLhs, unsigned int x) {
-    float4 inRhs = rsGetElementAt_float4(gAllocInRhs, x);
-    return native_divide(inLhs, inRhs);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDivideRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDivideRelaxed.rs
deleted file mode 100644
index b6d50045..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeDivideRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeDivide.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp.java
deleted file mode 100644
index 3c9a847..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeExp extends RSBaseCompute {
-
-    private ScriptC_TestNativeExp script;
-    private ScriptC_TestNativeExpRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeExp(mRS);
-        scriptRelaxed = new ScriptC_TestNativeExpRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeExpFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x66a7898af1f6be9bl, -86, 86);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeExpFloatFloat(inV, out);
-            verifyResultsNativeExpFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExpFloatFloat(inV, out);
-            verifyResultsNativeExpFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExpFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExpFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExpFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6feb21d463a0ee67l, -86, 86);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeExpFloat2Float2(inV, out);
-            verifyResultsNativeExpFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExpFloat2Float2(inV, out);
-            verifyResultsNativeExpFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExpFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExpFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExpFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6feceaef59bc0f45l, -86, 86);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeExpFloat3Float3(inV, out);
-            verifyResultsNativeExpFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExpFloat3Float3(inV, out);
-            verifyResultsNativeExpFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExpFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExpFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExpFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6feeb40a4fd73023l, -86, 86);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeExpFloat4Float4(inV, out);
-            verifyResultsNativeExpFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExpFloat4Float4(inV, out);
-            verifyResultsNativeExpFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExpFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExpFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeExp() {
-        checkNativeExpFloatFloat();
-        checkNativeExpFloat2Float2();
-        checkNativeExpFloat3Float3();
-        checkNativeExpFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp.rs
deleted file mode 100644
index 6143d9f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeExpFloatFloat(float inV) {
-    return native_exp(inV);
-}
-
-float2 __attribute__((kernel)) testNativeExpFloat2Float2(float2 inV) {
-    return native_exp(inV);
-}
-
-float3 __attribute__((kernel)) testNativeExpFloat3Float3(float3 inV) {
-    return native_exp(inV);
-}
-
-float4 __attribute__((kernel)) testNativeExpFloat4Float4(float4 inV) {
-    return native_exp(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10.java
deleted file mode 100644
index 75eb8df..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeExp10 extends RSBaseCompute {
-
-    private ScriptC_TestNativeExp10 script;
-    private ScriptC_TestNativeExp10Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeExp10(mRS);
-        scriptRelaxed = new ScriptC_TestNativeExp10Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeExp10FloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x562e4ea690352c54l, -37, 37);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeExp10FloatFloat(inV, out);
-            verifyResultsNativeExp10FloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExp10FloatFloat(inV, out);
-            verifyResultsNativeExp10FloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExp10FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExp10FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExp10Float2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7450c64e54876b98l, -37, 37);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeExp10Float2Float2(inV, out);
-            verifyResultsNativeExp10Float2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExp10Float2Float2(inV, out);
-            verifyResultsNativeExp10Float2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExp10Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExp10Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExp10Float3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x74528f694aa28c76l, -37, 37);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeExp10Float3Float3(inV, out);
-            verifyResultsNativeExp10Float3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExp10Float3Float3(inV, out);
-            verifyResultsNativeExp10Float3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExp10Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExp10Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExp10Float4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7454588440bdad54l, -37, 37);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeExp10Float4Float4(inV, out);
-            verifyResultsNativeExp10Float4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExp10Float4Float4(inV, out);
-            verifyResultsNativeExp10Float4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExp10Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExp10Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeExp10() {
-        checkNativeExp10FloatFloat();
-        checkNativeExp10Float2Float2();
-        checkNativeExp10Float3Float3();
-        checkNativeExp10Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10.rs
deleted file mode 100644
index 1d03607..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeExp10FloatFloat(float inV) {
-    return native_exp10(inV);
-}
-
-float2 __attribute__((kernel)) testNativeExp10Float2Float2(float2 inV) {
-    return native_exp10(inV);
-}
-
-float3 __attribute__((kernel)) testNativeExp10Float3Float3(float3 inV) {
-    return native_exp10(inV);
-}
-
-float4 __attribute__((kernel)) testNativeExp10Float4Float4(float4 inV) {
-    return native_exp10(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10Relaxed.rs
deleted file mode 100644
index 4f12665..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp10Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeExp10.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2.java
deleted file mode 100644
index bb0e9b3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeExp2 extends RSBaseCompute {
-
-    private ScriptC_TestNativeExp2 script;
-    private ScriptC_TestNativeExp2Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeExp2(mRS);
-        scriptRelaxed = new ScriptC_TestNativeExp2Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeExp2FloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd87a6eb24c6a2bc5l, -125, 125);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeExp2FloatFloat(inV, out);
-            verifyResultsNativeExp2FloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExp2FloatFloat(inV, out);
-            verifyResultsNativeExp2FloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExp2FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExp2FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExp2Float2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8c243b10af5062c1l, -125, 125);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeExp2Float2Float2(inV, out);
-            verifyResultsNativeExp2Float2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExp2Float2Float2(inV, out);
-            verifyResultsNativeExp2Float2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExp2Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExp2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExp2Float3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8c26042ba56b839fl, -125, 125);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeExp2Float3Float3(inV, out);
-            verifyResultsNativeExp2Float3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExp2Float3Float3(inV, out);
-            verifyResultsNativeExp2Float3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExp2Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExp2Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExp2Float4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8c27cd469b86a47dl, -125, 125);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeExp2Float4Float4(inV, out);
-            verifyResultsNativeExp2Float4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExp2Float4Float4(inV, out);
-            verifyResultsNativeExp2Float4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExp2Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExp2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExp2Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeExp2() {
-        checkNativeExp2FloatFloat();
-        checkNativeExp2Float2Float2();
-        checkNativeExp2Float3Float3();
-        checkNativeExp2Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2.rs
deleted file mode 100644
index 1112900..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeExp2FloatFloat(float inV) {
-    return native_exp2(inV);
-}
-
-float2 __attribute__((kernel)) testNativeExp2Float2Float2(float2 inV) {
-    return native_exp2(inV);
-}
-
-float3 __attribute__((kernel)) testNativeExp2Float3Float3(float3 inV) {
-    return native_exp2(inV);
-}
-
-float4 __attribute__((kernel)) testNativeExp2Float4Float4(float4 inV) {
-    return native_exp2(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2Relaxed.rs
deleted file mode 100644
index 8b99710..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExp2Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeExp2.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpRelaxed.rs
deleted file mode 100644
index dd3a73c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeExp.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpm1.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpm1.java
deleted file mode 100644
index 3eecc32..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpm1.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeExpm1 extends RSBaseCompute {
-
-    private ScriptC_TestNativeExpm1 script;
-    private ScriptC_TestNativeExpm1Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeExpm1(mRS);
-        scriptRelaxed = new ScriptC_TestNativeExpm1Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeExpm1FloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x209e2820fcaa295fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeExpm1FloatFloat(in, out);
-            verifyResultsNativeExpm1FloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExpm1FloatFloat(in, out);
-            verifyResultsNativeExpm1FloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExpm1FloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExpm1(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExpm1FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExpm1Float2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x964ef83c9a3d4a43l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeExpm1Float2Float2(in, out);
-            verifyResultsNativeExpm1Float2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExpm1Float2Float2(in, out);
-            verifyResultsNativeExpm1Float2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExpm1Float2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExpm1(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExpm1Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExpm1Float3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x964f02ddf943dfddl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeExpm1Float3Float3(in, out);
-            verifyResultsNativeExpm1Float3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExpm1Float3Float3(in, out);
-            verifyResultsNativeExpm1Float3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExpm1Float3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExpm1(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExpm1Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeExpm1Float4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x964f0d7f584a7577l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeExpm1Float4Float4(in, out);
-            verifyResultsNativeExpm1Float4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeExpm1Float4Float4(in, out);
-            verifyResultsNativeExpm1Float4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeExpm1Float4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeExpm1(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeExpm1Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeExpm1() {
-        checkNativeExpm1FloatFloat();
-        checkNativeExpm1Float2Float2();
-        checkNativeExpm1Float3Float3();
-        checkNativeExpm1Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpm1.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpm1.rs
deleted file mode 100644
index 6d265d6..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpm1.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeExpm1FloatFloat(float in) {
-    return native_expm1(in);
-}
-
-float2 __attribute__((kernel)) testNativeExpm1Float2Float2(float2 in) {
-    return native_expm1(in);
-}
-
-float3 __attribute__((kernel)) testNativeExpm1Float3Float3(float3 in) {
-    return native_expm1(in);
-}
-
-float4 __attribute__((kernel)) testNativeExpm1Float4Float4(float4 in) {
-    return native_expm1(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpm1Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpm1Relaxed.rs
deleted file mode 100644
index a74a0d1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeExpm1Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeExpm1.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeHypot.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeHypot.java
deleted file mode 100644
index 0a50675..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeHypot.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeHypot extends RSBaseCompute {
-
-    private ScriptC_TestNativeHypot script;
-    private ScriptC_TestNativeHypotRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeHypot(mRS);
-        scriptRelaxed = new ScriptC_TestNativeHypotRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeHypotFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3d61f129bdf66018l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3d61f129bdf66019l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNativeHypotFloatFloatFloat(inX, out);
-            verifyResultsNativeHypotFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNativeHypotFloatFloatFloat(inX, out);
-            verifyResultsNativeHypotFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeHypotFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeHypot(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeHypotFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeHypotFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x92a8064760a50e64l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x92a8064760a50e65l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNativeHypotFloat2Float2Float2(inX, out);
-            verifyResultsNativeHypotFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNativeHypotFloat2Float2Float2(inX, out);
-            verifyResultsNativeHypotFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeHypotFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeHypot(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeHypotFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeHypotFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe70ce46762831005l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe70ce46762831006l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNativeHypotFloat3Float3Float3(inX, out);
-            verifyResultsNativeHypotFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNativeHypotFloat3Float3Float3(inX, out);
-            verifyResultsNativeHypotFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeHypotFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeHypot(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeHypotFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeHypotFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3b71c287646111a6l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3b71c287646111a7l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNativeHypotFloat4Float4Float4(inX, out);
-            verifyResultsNativeHypotFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNativeHypotFloat4Float4Float4(inX, out);
-            verifyResultsNativeHypotFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeHypotFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeHypot(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeHypotFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeHypot() {
-        checkNativeHypotFloatFloatFloat();
-        checkNativeHypotFloat2Float2Float2();
-        checkNativeHypotFloat3Float3Float3();
-        checkNativeHypotFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeHypot.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeHypot.rs
deleted file mode 100644
index b4e8a7c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeHypot.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testNativeHypotFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return native_hypot(inX, inY);
-}
-
-float2 __attribute__((kernel)) testNativeHypotFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return native_hypot(inX, inY);
-}
-
-float3 __attribute__((kernel)) testNativeHypotFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return native_hypot(inX, inY);
-}
-
-float4 __attribute__((kernel)) testNativeHypotFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return native_hypot(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeHypotRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeHypotRelaxed.rs
deleted file mode 100644
index 79aa107..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeHypotRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeHypot.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLength.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLength.java
deleted file mode 100644
index b3a5df6..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLength.java
+++ /dev/null
@@ -1,300 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeLength extends RSBaseCompute {
-
-    private ScriptC_TestNativeLength script;
-    private ScriptC_TestNativeLengthRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeLength(mRS);
-        scriptRelaxed = new ScriptC_TestNativeLengthRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeLengthFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbe51f0c4d1df20ecl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeLengthFloatFloat(inV, out);
-            verifyResultsNativeLengthFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLengthFloatFloat(inV, out);
-            verifyResultsNativeLengthFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLengthFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNativeLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inV: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNativeLengthFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloat {
-        public float[] inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeLengthFloat2Float() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf7c2930af1b4824cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeLengthFloat2Float(inV, out);
-            verifyResultsNativeLengthFloat2Float(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat2Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLengthFloat2Float(inV, out);
-            verifyResultsNativeLengthFloat2Float(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat2Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLengthFloat2Float(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[2];
-            // Fill args with the input values
-            for (int j = 0; j < 2 ; j++) {
-                args.inV[j] = arrayInV[i * 2 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNativeLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNativeLengthFloat2Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkNativeLengthFloat3Float() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf7c29dac50bb10adl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeLengthFloat3Float(inV, out);
-            verifyResultsNativeLengthFloat3Float(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat3Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLengthFloat3Float(inV, out);
-            verifyResultsNativeLengthFloat3Float(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat3Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLengthFloat3Float(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[3];
-            // Fill args with the input values
-            for (int j = 0; j < 3 ; j++) {
-                args.inV[j] = arrayInV[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNativeLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNativeLengthFloat3Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkNativeLengthFloat4Float() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf7c2a84dafc19f0el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeLengthFloat4Float(inV, out);
-            verifyResultsNativeLengthFloat4Float(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat4Float: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLengthFloat4Float(inV, out);
-            verifyResultsNativeLengthFloat4Float(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat4Float: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLengthFloat4Float(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[4];
-            // Fill args with the input values
-            for (int j = 0; j < 4 ; j++) {
-                args.inV[j] = arrayInV[i * 4 + j];
-            }
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNativeLength(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNativeLengthFloat4Float" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testNativeLength() {
-        checkNativeLengthFloatFloat();
-        checkNativeLengthFloat2Float();
-        checkNativeLengthFloat3Float();
-        checkNativeLengthFloat4Float();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLength.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLength.rs
deleted file mode 100644
index ae30d2d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLength.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeLengthFloatFloat(float inV) {
-    return native_length(inV);
-}
-
-float __attribute__((kernel)) testNativeLengthFloat2Float(float2 inV) {
-    return native_length(inV);
-}
-
-float __attribute__((kernel)) testNativeLengthFloat3Float(float3 inV) {
-    return native_length(inV);
-}
-
-float __attribute__((kernel)) testNativeLengthFloat4Float(float4 inV) {
-    return native_length(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLengthRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLengthRelaxed.rs
deleted file mode 100644
index cb03c1e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLengthRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeLength.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog.java
deleted file mode 100644
index 4116cba..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeLog extends RSBaseCompute {
-
-    private ScriptC_TestNativeLog script;
-    private ScriptC_TestNativeLogRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeLog(mRS);
-        scriptRelaxed = new ScriptC_TestNativeLogRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeLogFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6237b14ee6418d2cl, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeLogFloatFloat(inV, out);
-            verifyResultsNativeLogFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLogFloatFloat(inV, out);
-            verifyResultsNativeLogFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLogFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLogFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLogFloat2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x641a5823d3eee3b0l, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeLogFloat2Float2(inV, out);
-            verifyResultsNativeLogFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLogFloat2Float2(inV, out);
-            verifyResultsNativeLogFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLogFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLogFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLogFloat3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x641c213eca0a048el, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeLogFloat3Float3(inV, out);
-            verifyResultsNativeLogFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLogFloat3Float3(inV, out);
-            verifyResultsNativeLogFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLogFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLogFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLogFloat4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x641dea59c025256cl, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeLogFloat4Float4(inV, out);
-            verifyResultsNativeLogFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLogFloat4Float4(inV, out);
-            verifyResultsNativeLogFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLogFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLogFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeLog() {
-        checkNativeLogFloatFloat();
-        checkNativeLogFloat2Float2();
-        checkNativeLogFloat3Float3();
-        checkNativeLogFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog.rs
deleted file mode 100644
index 05a4688..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeLogFloatFloat(float inV) {
-    return native_log(inV);
-}
-
-float2 __attribute__((kernel)) testNativeLogFloat2Float2(float2 inV) {
-    return native_log(inV);
-}
-
-float3 __attribute__((kernel)) testNativeLogFloat3Float3(float3 inV) {
-    return native_log(inV);
-}
-
-float4 __attribute__((kernel)) testNativeLogFloat4Float4(float4 inV) {
-    return native_log(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10.java
deleted file mode 100644
index 9a64239..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeLog10 extends RSBaseCompute {
-
-    private ScriptC_TestNativeLog10 script;
-    private ScriptC_TestNativeLog10Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeLog10(mRS);
-        scriptRelaxed = new ScriptC_TestNativeLog10Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeLog10FloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4a5d84f60083219dl, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeLog10FloatFloat(inV, out);
-            verifyResultsNativeLog10FloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog10FloatFloat(inV, out);
-            verifyResultsNativeLog10FloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog10FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog10FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLog10Float2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1d500a10779807d9l, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeLog10Float2Float2(inV, out);
-            verifyResultsNativeLog10Float2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog10Float2Float2(inV, out);
-            verifyResultsNativeLog10Float2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog10Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog10Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLog10Float3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1d51d32b6db328b7l, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeLog10Float3Float3(inV, out);
-            verifyResultsNativeLog10Float3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog10Float3Float3(inV, out);
-            verifyResultsNativeLog10Float3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog10Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog10Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLog10Float4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1d539c4663ce4995l, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeLog10Float4Float4(inV, out);
-            verifyResultsNativeLog10Float4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog10Float4Float4(inV, out);
-            verifyResultsNativeLog10Float4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog10Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog10(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog10Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeLog10() {
-        checkNativeLog10FloatFloat();
-        checkNativeLog10Float2Float2();
-        checkNativeLog10Float3Float3();
-        checkNativeLog10Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10.rs
deleted file mode 100644
index 3e86a13..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeLog10FloatFloat(float inV) {
-    return native_log10(inV);
-}
-
-float2 __attribute__((kernel)) testNativeLog10Float2Float2(float2 inV) {
-    return native_log10(inV);
-}
-
-float3 __attribute__((kernel)) testNativeLog10Float3Float3(float3 inV) {
-    return native_log10(inV);
-}
-
-float4 __attribute__((kernel)) testNativeLog10Float4Float4(float4 inV) {
-    return native_log10(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10Relaxed.rs
deleted file mode 100644
index a00ed08..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog10Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeLog10.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog1p.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog1p.java
deleted file mode 100644
index 0d88a75..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog1p.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeLog1p extends RSBaseCompute {
-
-    private ScriptC_TestNativeLog1p script;
-    private ScriptC_TestNativeLog1pRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeLog1p(mRS);
-        scriptRelaxed = new ScriptC_TestNativeLog1pRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeLog1pFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x444585911437d95l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeLog1pFloatFloat(in, out);
-            verifyResultsNativeLog1pFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog1pFloatFloat(in, out);
-            verifyResultsNativeLog1pFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog1pFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog1p(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog1pFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLog1pFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd1a13d4961ae8449l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeLog1pFloat2Float2(in, out);
-            verifyResultsNativeLog1pFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog1pFloat2Float2(in, out);
-            verifyResultsNativeLog1pFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog1pFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog1p(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog1pFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLog1pFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd1a147eac0b519e3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeLog1pFloat3Float3(in, out);
-            verifyResultsNativeLog1pFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog1pFloat3Float3(in, out);
-            verifyResultsNativeLog1pFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog1pFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog1p(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog1pFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLog1pFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd1a1528c1fbbaf7dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeLog1pFloat4Float4(in, out);
-            verifyResultsNativeLog1pFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog1pFloat4Float4(in, out);
-            verifyResultsNativeLog1pFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog1pFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog1p(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog1pFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeLog1p() {
-        checkNativeLog1pFloatFloat();
-        checkNativeLog1pFloat2Float2();
-        checkNativeLog1pFloat3Float3();
-        checkNativeLog1pFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog1p.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog1p.rs
deleted file mode 100644
index 8d9cdd2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog1p.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeLog1pFloatFloat(float in) {
-    return native_log1p(in);
-}
-
-float2 __attribute__((kernel)) testNativeLog1pFloat2Float2(float2 in) {
-    return native_log1p(in);
-}
-
-float3 __attribute__((kernel)) testNativeLog1pFloat3Float3(float3 in) {
-    return native_log1p(in);
-}
-
-float4 __attribute__((kernel)) testNativeLog1pFloat4Float4(float4 in) {
-    return native_log1p(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog1pRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog1pRelaxed.rs
deleted file mode 100644
index 3411c6e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog1pRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeLog1p.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2.java
deleted file mode 100644
index 674abb7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeLog2 extends RSBaseCompute {
-
-    private ScriptC_TestNativeLog2 script;
-    private ScriptC_TestNativeLog2Relaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeLog2(mRS);
-        scriptRelaxed = new ScriptC_TestNativeLog2Relaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeLog2FloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x19b11c9c54fade20l, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeLog2FloatFloat(inV, out);
-            verifyResultsNativeLog2FloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2FloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog2FloatFloat(inV, out);
-            verifyResultsNativeLog2FloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2FloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog2FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog2FloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLog2Float2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x90125a688c689604l, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeLog2Float2Float2(inV, out);
-            verifyResultsNativeLog2Float2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog2Float2Float2(inV, out);
-            verifyResultsNativeLog2Float2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog2Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLog2Float3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x901423838283b6e2l, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeLog2Float3Float3(inV, out);
-            verifyResultsNativeLog2Float3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog2Float3Float3(inV, out);
-            verifyResultsNativeLog2Float3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog2Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog2Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeLog2Float4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9015ec9e789ed7c0l, 10e-10, 10e10);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeLog2Float4Float4(inV, out);
-            verifyResultsNativeLog2Float4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeLog2Float4Float4(inV, out);
-            verifyResultsNativeLog2Float4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeLog2Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeLog2(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeLog2Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeLog2() {
-        checkNativeLog2FloatFloat();
-        checkNativeLog2Float2Float2();
-        checkNativeLog2Float3Float3();
-        checkNativeLog2Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2.rs
deleted file mode 100644
index 748a2a0..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeLog2FloatFloat(float inV) {
-    return native_log2(inV);
-}
-
-float2 __attribute__((kernel)) testNativeLog2Float2Float2(float2 inV) {
-    return native_log2(inV);
-}
-
-float3 __attribute__((kernel)) testNativeLog2Float3Float3(float3 inV) {
-    return native_log2(inV);
-}
-
-float4 __attribute__((kernel)) testNativeLog2Float4Float4(float4 inV) {
-    return native_log2(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2Relaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2Relaxed.rs
deleted file mode 100644
index 71c2580..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLog2Relaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeLog2.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLogRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLogRelaxed.rs
deleted file mode 100644
index 70d5e2f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeLogRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeLog.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeNormalize.java
deleted file mode 100644
index 42f4553..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeNormalize.java
+++ /dev/null
@@ -1,315 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeNormalize extends RSBaseCompute {
-
-    private ScriptC_TestNativeNormalize script;
-    private ScriptC_TestNativeNormalizeRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeNormalize(mRS);
-        scriptRelaxed = new ScriptC_TestNativeNormalizeRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeNormalizeFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x487756167e4aac53l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeNormalizeFloatFloat(inV, out);
-            verifyResultsNativeNormalizeFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeNormalizeFloatFloat(inV, out);
-            verifyResultsNativeNormalizeFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeNormalizeFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNativeNormalize(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inV: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNativeNormalizeFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloatN {
-        public float[] inV;
-        public Target.Floaty[] out;
-    }
-
-    private void checkNativeNormalizeFloat2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x65c77dbcedd0e45fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeNormalizeFloat2Float2(inV, out);
-            verifyResultsNativeNormalizeFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeNormalizeFloat2Float2(inV, out);
-            verifyResultsNativeNormalizeFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeNormalizeFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[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];
-            }
-            Target target = new Target(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(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkNativeNormalizeFloat2Float2" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkNativeNormalizeFloat3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x65c946d7e3ec053dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeNormalizeFloat3Float3(inV, out);
-            verifyResultsNativeNormalizeFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeNormalizeFloat3Float3(inV, out);
-            verifyResultsNativeNormalizeFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeNormalizeFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[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];
-            }
-            Target target = new Target(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(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkNativeNormalizeFloat3Float3" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkNativeNormalizeFloat4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x65cb0ff2da07261bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeNormalizeFloat4Float4(inV, out);
-            verifyResultsNativeNormalizeFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeNormalizeFloat4Float4(inV, out);
-            verifyResultsNativeNormalizeFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeNormalizeFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[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];
-            }
-            Target target = new Target(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(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkNativeNormalizeFloat4Float4" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testNativeNormalize() {
-        checkNativeNormalizeFloatFloat();
-        checkNativeNormalizeFloat2Float2();
-        checkNativeNormalizeFloat3Float3();
-        checkNativeNormalizeFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeNormalize.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeNormalize.rs
deleted file mode 100644
index 89e0b52..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeNormalize.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeNormalizeFloatFloat(float inV) {
-    return native_normalize(inV);
-}
-
-float2 __attribute__((kernel)) testNativeNormalizeFloat2Float2(float2 inV) {
-    return native_normalize(inV);
-}
-
-float3 __attribute__((kernel)) testNativeNormalizeFloat3Float3(float3 inV) {
-    return native_normalize(inV);
-}
-
-float4 __attribute__((kernel)) testNativeNormalizeFloat4Float4(float4 inV) {
-    return native_normalize(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeNormalizeRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeNormalizeRelaxed.rs
deleted file mode 100644
index 9050ff3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeNormalizeRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeNormalize.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowr.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowr.java
deleted file mode 100644
index f19d80c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowr.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativePowr extends RSBaseCompute {
-
-    private ScriptC_TestNativePowr script;
-    private ScriptC_TestNativePowrRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativePowr(mRS);
-        scriptRelaxed = new ScriptC_TestNativePowrRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inV;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkNativePowrFloatFloatFloat() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3c3550bdff7a10c2l, 0, 256);
-        Allocation inY = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3c3550bdff7a10c5l, -15, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNativePowrFloatFloatFloat(inV, out);
-            verifyResultsNativePowrFloatFloatFloat(inV, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNativePowrFloatFloatFloat(inV, out);
-            verifyResultsNativePowrFloatFloatFloat(inV, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativePowrFloatFloatFloat(Allocation inV, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativePowr(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativePowrFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativePowrFloat2Float2Float2() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdbc56fbe7733c926l, 0, 256);
-        Allocation inY = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdbc56fbe7733c929l, -15, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNativePowrFloat2Float2Float2(inV, out);
-            verifyResultsNativePowrFloat2Float2Float2(inV, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNativePowrFloat2Float2Float2(inV, out);
-            verifyResultsNativePowrFloat2Float2Float2(inV, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativePowrFloat2Float2Float2(Allocation inV, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativePowr(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativePowrFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativePowrFloat3Float3Float3() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x302a4dde7911cac7l, 0, 256);
-        Allocation inY = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x302a4dde7911cacal, -15, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNativePowrFloat3Float3Float3(inV, out);
-            verifyResultsNativePowrFloat3Float3Float3(inV, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNativePowrFloat3Float3Float3(inV, out);
-            verifyResultsNativePowrFloat3Float3Float3(inV, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativePowrFloat3Float3Float3(Allocation inV, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativePowr(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativePowrFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativePowrFloat4Float4Float4() {
-        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x848f2bfe7aefcc68l, 0, 256);
-        Allocation inY = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x848f2bfe7aefcc6bl, -15, 15);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNativePowrFloat4Float4Float4(inV, out);
-            verifyResultsNativePowrFloat4Float4Float4(inV, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNativePowrFloat4Float4Float4(inV, out);
-            verifyResultsNativePowrFloat4Float4Float4(inV, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativePowrFloat4Float4Float4(Allocation inV, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativePowr(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativePowrFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativePowr() {
-        checkNativePowrFloatFloatFloat();
-        checkNativePowrFloat2Float2Float2();
-        checkNativePowrFloat3Float3Float3();
-        checkNativePowrFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowr.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowr.rs
deleted file mode 100644
index 06de2f9..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowr.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testNativePowrFloatFloatFloat(float inV, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return native_powr(inV, inY);
-}
-
-float2 __attribute__((kernel)) testNativePowrFloat2Float2Float2(float2 inV, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return native_powr(inV, inY);
-}
-
-float3 __attribute__((kernel)) testNativePowrFloat3Float3Float3(float3 inV, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return native_powr(inV, inY);
-}
-
-float4 __attribute__((kernel)) testNativePowrFloat4Float4Float4(float4 inV, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return native_powr(inV, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowrRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowrRelaxed.rs
deleted file mode 100644
index 069e40e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativePowrRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativePowr.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRecip.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRecip.java
deleted file mode 100644
index 976526b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRecip.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeRecip extends RSBaseCompute {
-
-    private ScriptC_TestNativeRecip script;
-    private ScriptC_TestNativeRecipRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeRecip(mRS);
-        scriptRelaxed = new ScriptC_TestNativeRecipRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeRecipFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4ec14a4fcc4ed441l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeRecipFloatFloat(inV, out);
-            verifyResultsNativeRecipFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeRecipFloatFloat(inV, out);
-            verifyResultsNativeRecipFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRecipFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeRecip(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRecipFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeRecipFloat2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd1ec6fa169d54a5dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeRecipFloat2Float2(inV, out);
-            verifyResultsNativeRecipFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeRecipFloat2Float2(inV, out);
-            verifyResultsNativeRecipFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRecipFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeRecip(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRecipFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeRecipFloat3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd1ee38bc5ff06b3bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeRecipFloat3Float3(inV, out);
-            verifyResultsNativeRecipFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeRecipFloat3Float3(inV, out);
-            verifyResultsNativeRecipFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRecipFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeRecip(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRecipFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeRecipFloat4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd1f001d7560b8c19l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeRecipFloat4Float4(inV, out);
-            verifyResultsNativeRecipFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeRecipFloat4Float4(inV, out);
-            verifyResultsNativeRecipFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRecipFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeRecip(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRecipFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeRecip() {
-        checkNativeRecipFloatFloat();
-        checkNativeRecipFloat2Float2();
-        checkNativeRecipFloat3Float3();
-        checkNativeRecipFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRecip.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRecip.rs
deleted file mode 100644
index 01220dc..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRecip.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeRecipFloatFloat(float inV) {
-    return native_recip(inV);
-}
-
-float2 __attribute__((kernel)) testNativeRecipFloat2Float2(float2 inV) {
-    return native_recip(inV);
-}
-
-float3 __attribute__((kernel)) testNativeRecipFloat3Float3(float3 inV) {
-    return native_recip(inV);
-}
-
-float4 __attribute__((kernel)) testNativeRecipFloat4Float4(float4 inV) {
-    return native_recip(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRecipRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRecipRelaxed.rs
deleted file mode 100644
index f2cbc83..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRecipRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeRecip.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRootn.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRootn.java
deleted file mode 100644
index d125e3b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRootn.java
+++ /dev/null
@@ -1,321 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeRootn extends RSBaseCompute {
-
-    private ScriptC_TestNativeRootn script;
-    private ScriptC_TestNativeRootnRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeRootn(mRS);
-        scriptRelaxed = new ScriptC_TestNativeRootnRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatIntFloat {
-        public float inV;
-        public int inN;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeRootnFloatIntFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6693fe5c237ac0f1l, false);
-        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x6693fe5c237ac0e9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInN(inN);
-            script.forEach_testNativeRootnFloatIntFloat(inV, out);
-            verifyResultsNativeRootnFloatIntFloat(inV, inN, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloatIntFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInN(inN);
-            scriptRelaxed.forEach_testNativeRootnFloatIntFloat(inV, out);
-            verifyResultsNativeRootnFloatIntFloat(inV, inN, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloatIntFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRootnFloatIntFloat(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        int[] arrayInN = new int[INPUTSIZE * 1];
-        inN.copyTo(arrayInN);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inV = arrayInV[i];
-                args.inN = arrayInN[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeRootn(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inN: ");
-                    message.append(String.format("%d", args.inN));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRootnFloatIntFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeRootnFloat2Int2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x5363e8c04afd5bcdl, false);
-        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x5363e8c04afd5bc5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInN(inN);
-            script.forEach_testNativeRootnFloat2Int2Float2(inV, out);
-            verifyResultsNativeRootnFloat2Int2Float2(inV, inN, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat2Int2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInN(inN);
-            scriptRelaxed.forEach_testNativeRootnFloat2Int2Float2(inV, out);
-            verifyResultsNativeRootnFloat2Int2Float2(inV, inN, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat2Int2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRootnFloat2Int2Float2(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayInN = new int[INPUTSIZE * 2];
-        inN.copyTo(arrayInN);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                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);
-                CoreMathVerifier.computeNativeRootn(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inN: ");
-                    message.append(String.format("%d", args.inN));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRootnFloat2Int2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeRootnFloat3Int3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x791a272340afc886l, false);
-        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x791a272340afc87el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInN(inN);
-            script.forEach_testNativeRootnFloat3Int3Float3(inV, out);
-            verifyResultsNativeRootnFloat3Int3Float3(inV, inN, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat3Int3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInN(inN);
-            scriptRelaxed.forEach_testNativeRootnFloat3Int3Float3(inV, out);
-            verifyResultsNativeRootnFloat3Int3Float3(inV, inN, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat3Int3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRootnFloat3Int3Float3(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayInN = new int[INPUTSIZE * 4];
-        inN.copyTo(arrayInN);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                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);
-                CoreMathVerifier.computeNativeRootn(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inN: ");
-                    message.append(String.format("%d", args.inN));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRootnFloat3Int3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeRootnFloat4Int4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9ed065863662353fl, false);
-        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x9ed0658636623537l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInN(inN);
-            script.forEach_testNativeRootnFloat4Int4Float4(inV, out);
-            verifyResultsNativeRootnFloat4Int4Float4(inV, inN, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat4Int4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInN(inN);
-            scriptRelaxed.forEach_testNativeRootnFloat4Int4Float4(inV, out);
-            verifyResultsNativeRootnFloat4Int4Float4(inV, inN, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat4Int4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRootnFloat4Int4Float4(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayInN = new int[INPUTSIZE * 4];
-        inN.copyTo(arrayInN);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                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);
-                CoreMathVerifier.computeNativeRootn(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inN: ");
-                    message.append(String.format("%d", args.inN));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRootnFloat4Int4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeRootn() {
-        checkNativeRootnFloatIntFloat();
-        checkNativeRootnFloat2Int2Float2();
-        checkNativeRootnFloat3Int3Float3();
-        checkNativeRootnFloat4Int4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRootn.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRootn.rs
deleted file mode 100644
index 1aeb2b2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRootn.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInN;
-
-float __attribute__((kernel)) testNativeRootnFloatIntFloat(float inV, unsigned int x) {
-    int inN = rsGetElementAt_int(gAllocInN, x);
-    return native_rootn(inV, inN);
-}
-
-float2 __attribute__((kernel)) testNativeRootnFloat2Int2Float2(float2 inV, unsigned int x) {
-    int2 inN = rsGetElementAt_int2(gAllocInN, x);
-    return native_rootn(inV, inN);
-}
-
-float3 __attribute__((kernel)) testNativeRootnFloat3Int3Float3(float3 inV, unsigned int x) {
-    int3 inN = rsGetElementAt_int3(gAllocInN, x);
-    return native_rootn(inV, inN);
-}
-
-float4 __attribute__((kernel)) testNativeRootnFloat4Int4Float4(float4 inV, unsigned int x) {
-    int4 inN = rsGetElementAt_int4(gAllocInN, x);
-    return native_rootn(inV, inN);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRootnRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRootnRelaxed.rs
deleted file mode 100644
index 3b05992..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRootnRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeRootn.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRsqrt.java
deleted file mode 100644
index fc2549d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRsqrt.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeRsqrt extends RSBaseCompute {
-
-    private ScriptC_TestNativeRsqrt script;
-    private ScriptC_TestNativeRsqrtRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeRsqrt(mRS);
-        scriptRelaxed = new ScriptC_TestNativeRsqrtRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeRsqrtFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf3cf23b51aa29de0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeRsqrtFloatFloat(in, out);
-            verifyResultsNativeRsqrtFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeRsqrtFloatFloat(in, out);
-            verifyResultsNativeRsqrtFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRsqrtFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRsqrtFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeRsqrtFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf318090911bec1fcl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeRsqrtFloat2Float2(in, out);
-            verifyResultsNativeRsqrtFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeRsqrtFloat2Float2(in, out);
-            verifyResultsNativeRsqrtFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRsqrtFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRsqrtFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeRsqrtFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf31813aa70c55796l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeRsqrtFloat3Float3(in, out);
-            verifyResultsNativeRsqrtFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeRsqrtFloat3Float3(in, out);
-            verifyResultsNativeRsqrtFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRsqrtFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRsqrtFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeRsqrtFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf3181e4bcfcbed30l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeRsqrtFloat4Float4(in, out);
-            verifyResultsNativeRsqrtFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeRsqrtFloat4Float4(in, out);
-            verifyResultsNativeRsqrtFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeRsqrtFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeRsqrtFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeRsqrt() {
-        checkNativeRsqrtFloatFloat();
-        checkNativeRsqrtFloat2Float2();
-        checkNativeRsqrtFloat3Float3();
-        checkNativeRsqrtFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRsqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRsqrt.rs
deleted file mode 100644
index af291cb..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRsqrt.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeRsqrtFloatFloat(float in) {
-    return native_rsqrt(in);
-}
-
-float2 __attribute__((kernel)) testNativeRsqrtFloat2Float2(float2 in) {
-    return native_rsqrt(in);
-}
-
-float3 __attribute__((kernel)) testNativeRsqrtFloat3Float3(float3 in) {
-    return native_rsqrt(in);
-}
-
-float4 __attribute__((kernel)) testNativeRsqrtFloat4Float4(float4 in) {
-    return native_rsqrt(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRsqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRsqrtRelaxed.rs
deleted file mode 100644
index c18cc22..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeRsqrtRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeRsqrt.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSin.java
deleted file mode 100644
index 1637326..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSin.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeSin extends RSBaseCompute {
-
-    private ScriptC_TestNativeSin script;
-    private ScriptC_TestNativeSinRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeSin(mRS);
-        scriptRelaxed = new ScriptC_TestNativeSinRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeSinFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x33ee19763354cc56l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeSinFloatFloat(in, out);
-            verifyResultsNativeSinFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinFloatFloat(in, out);
-            verifyResultsNativeSinFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSinFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x12b508b470b05442l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeSinFloat2Float2(in, out);
-            verifyResultsNativeSinFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinFloat2Float2(in, out);
-            verifyResultsNativeSinFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSinFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x12b51355cfb6e9dcl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeSinFloat3Float3(in, out);
-            verifyResultsNativeSinFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinFloat3Float3(in, out);
-            verifyResultsNativeSinFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSinFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x12b51df72ebd7f76l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeSinFloat4Float4(in, out);
-            verifyResultsNativeSinFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinFloat4Float4(in, out);
-            verifyResultsNativeSinFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeSin() {
-        checkNativeSinFloatFloat();
-        checkNativeSinFloat2Float2();
-        checkNativeSinFloat3Float3();
-        checkNativeSinFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSin.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSin.rs
deleted file mode 100644
index 1af8929..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSin.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeSinFloatFloat(float in) {
-    return native_sin(in);
-}
-
-float2 __attribute__((kernel)) testNativeSinFloat2Float2(float2 in) {
-    return native_sin(in);
-}
-
-float3 __attribute__((kernel)) testNativeSinFloat3Float3(float3 in) {
-    return native_sin(in);
-}
-
-float4 __attribute__((kernel)) testNativeSinFloat4Float4(float4 in) {
-    return native_sin(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinRelaxed.rs
deleted file mode 100644
index e3dbf27..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeSin.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSincos.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSincos.java
deleted file mode 100644
index 380f2b4..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSincos.java
+++ /dev/null
@@ -1,361 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeSincos extends RSBaseCompute {
-
-    private ScriptC_TestNativeSincos script;
-    private ScriptC_TestNativeSincosRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeSincos(mRS);
-        scriptRelaxed = new ScriptC_TestNativeSincosRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inV;
-        public Target.Floaty outCosptr;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeSincosFloatFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe15df2366436cc13l, false);
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocOutCosptr(outCosptr);
-            script.forEach_testNativeSincosFloatFloatFloat(inV, out);
-            verifyResultsNativeSincosFloatFloatFloat(inV, outCosptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
-            scriptRelaxed.forEach_testNativeSincosFloatFloatFloat(inV, out);
-            verifyResultsNativeSincosFloatFloatFloat(inV, outCosptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSincosFloatFloatFloat(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOutCosptr = new float[INPUTSIZE * 1];
-        outCosptr.copyTo(arrayOutCosptr);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSincos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outCosptr: ");
-                    message.append(args.outCosptr.toString());
-                    message.append("\n");
-                    message.append("Actual   output outCosptr: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutCosptr[i * 1 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 1 + j]), arrayOutCosptr[i * 1 + j]));
-                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSincosFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSincosFloat2Float2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe5a1f1dcda676ea9l, false);
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocOutCosptr(outCosptr);
-            script.forEach_testNativeSincosFloat2Float2Float2(inV, out);
-            verifyResultsNativeSincosFloat2Float2Float2(inV, outCosptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
-            scriptRelaxed.forEach_testNativeSincosFloat2Float2Float2(inV, out);
-            verifyResultsNativeSincosFloat2Float2Float2(inV, outCosptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSincosFloat2Float2Float2(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOutCosptr = new float[INPUTSIZE * 2];
-        outCosptr.copyTo(arrayOutCosptr);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSincos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outCosptr: ");
-                    message.append(args.outCosptr.toString());
-                    message.append("\n");
-                    message.append("Actual   output outCosptr: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutCosptr[i * 2 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 2 + j]), arrayOutCosptr[i * 2 + j]));
-                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSincosFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSincosFloat3Float3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3a06cffcdc45704al, false);
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocOutCosptr(outCosptr);
-            script.forEach_testNativeSincosFloat3Float3Float3(inV, out);
-            verifyResultsNativeSincosFloat3Float3Float3(inV, outCosptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
-            scriptRelaxed.forEach_testNativeSincosFloat3Float3Float3(inV, out);
-            verifyResultsNativeSincosFloat3Float3Float3(inV, outCosptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSincosFloat3Float3Float3(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOutCosptr = new float[INPUTSIZE * 4];
-        outCosptr.copyTo(arrayOutCosptr);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSincos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outCosptr: ");
-                    message.append(args.outCosptr.toString());
-                    message.append("\n");
-                    message.append("Actual   output outCosptr: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutCosptr[i * 4 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 4 + j]), arrayOutCosptr[i * 4 + j]));
-                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSincosFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSincosFloat4Float4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8e6bae1cde2371ebl, false);
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocOutCosptr(outCosptr);
-            script.forEach_testNativeSincosFloat4Float4Float4(inV, out);
-            verifyResultsNativeSincosFloat4Float4Float4(inV, outCosptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
-            scriptRelaxed.forEach_testNativeSincosFloat4Float4Float4(inV, out);
-            verifyResultsNativeSincosFloat4Float4Float4(inV, outCosptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSincosFloat4Float4Float4(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOutCosptr = new float[INPUTSIZE * 4];
-        outCosptr.copyTo(arrayOutCosptr);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSincos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outCosptr: ");
-                    message.append(args.outCosptr.toString());
-                    message.append("\n");
-                    message.append("Actual   output outCosptr: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutCosptr[i * 4 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 4 + j]), arrayOutCosptr[i * 4 + j]));
-                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSincosFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeSincos() {
-        checkNativeSincosFloatFloatFloat();
-        checkNativeSincosFloat2Float2Float2();
-        checkNativeSincosFloat3Float3Float3();
-        checkNativeSincosFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSincos.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSincos.rs
deleted file mode 100644
index 8148c67..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSincos.rs
+++ /dev/null
@@ -1,50 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocOutCosptr;
-
-float __attribute__((kernel)) testNativeSincosFloatFloatFloat(float inV, unsigned int x) {
-    float outCosptr = 0;
-    float out = native_sincos(inV, &outCosptr);
-    rsSetElementAt_float(gAllocOutCosptr, outCosptr, x);
-    return out;
-}
-
-float2 __attribute__((kernel)) testNativeSincosFloat2Float2Float2(float2 inV, unsigned int x) {
-    float2 outCosptr = 0;
-    float2 out = native_sincos(inV, &outCosptr);
-    rsSetElementAt_float2(gAllocOutCosptr, outCosptr, x);
-    return out;
-}
-
-float3 __attribute__((kernel)) testNativeSincosFloat3Float3Float3(float3 inV, unsigned int x) {
-    float3 outCosptr = 0;
-    float3 out = native_sincos(inV, &outCosptr);
-    rsSetElementAt_float3(gAllocOutCosptr, outCosptr, x);
-    return out;
-}
-
-float4 __attribute__((kernel)) testNativeSincosFloat4Float4Float4(float4 inV, unsigned int x) {
-    float4 outCosptr = 0;
-    float4 out = native_sincos(inV, &outCosptr);
-    rsSetElementAt_float4(gAllocOutCosptr, outCosptr, x);
-    return out;
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSincosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSincosRelaxed.rs
deleted file mode 100644
index 175e265..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSincosRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeSincos.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinh.java
deleted file mode 100644
index 9c2edc7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeSinh extends RSBaseCompute {
-
-    private ScriptC_TestNativeSinh script;
-    private ScriptC_TestNativeSinhRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeSinh(mRS);
-        scriptRelaxed = new ScriptC_TestNativeSinhRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeSinhFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x74dcf3e9c65b6590l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeSinhFloatFloat(in, out);
-            verifyResultsNativeSinhFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinhFloatFloat(in, out);
-            verifyResultsNativeSinhFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinhFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSinhFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfdcd5755b59082cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeSinhFloat2Float2(in, out);
-            verifyResultsNativeSinhFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinhFloat2Float2(in, out);
-            verifyResultsNativeSinhFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinhFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSinhFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfdce016ba5f9dc6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeSinhFloat3Float3(in, out);
-            verifyResultsNativeSinhFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinhFloat3Float3(in, out);
-            verifyResultsNativeSinhFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinhFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSinhFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfdceab819663360l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeSinhFloat4Float4(in, out);
-            verifyResultsNativeSinhFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinhFloat4Float4(in, out);
-            verifyResultsNativeSinhFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinhFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeSinh() {
-        checkNativeSinhFloatFloat();
-        checkNativeSinhFloat2Float2();
-        checkNativeSinhFloat3Float3();
-        checkNativeSinhFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinh.rs
deleted file mode 100644
index 20728d5..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeSinhFloatFloat(float in) {
-    return native_sinh(in);
-}
-
-float2 __attribute__((kernel)) testNativeSinhFloat2Float2(float2 in) {
-    return native_sinh(in);
-}
-
-float3 __attribute__((kernel)) testNativeSinhFloat3Float3(float3 in) {
-    return native_sinh(in);
-}
-
-float4 __attribute__((kernel)) testNativeSinhFloat4Float4(float4 in) {
-    return native_sinh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinhRelaxed.rs
deleted file mode 100644
index 7ba4ce8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinhRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeSinh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinpi.java
deleted file mode 100644
index 2f67e8e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinpi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeSinpi extends RSBaseCompute {
-
-    private ScriptC_TestNativeSinpi script;
-    private ScriptC_TestNativeSinpiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeSinpi(mRS);
-        scriptRelaxed = new ScriptC_TestNativeSinpiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeSinpiFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb52c701227c9dc37l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeSinpiFloatFloat(in, out);
-            verifyResultsNativeSinpiFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinpiFloatFloat(in, out);
-            verifyResultsNativeSinpiFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinpiFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinpiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSinpiFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8df4951d1230045bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeSinpiFloat2Float2(in, out);
-            verifyResultsNativeSinpiFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinpiFloat2Float2(in, out);
-            verifyResultsNativeSinpiFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinpiFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinpiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSinpiFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8df49fbe713699f5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeSinpiFloat3Float3(in, out);
-            verifyResultsNativeSinpiFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinpiFloat3Float3(in, out);
-            verifyResultsNativeSinpiFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinpiFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinpiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSinpiFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8df4aa5fd03d2f8fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeSinpiFloat4Float4(in, out);
-            verifyResultsNativeSinpiFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSinpiFloat4Float4(in, out);
-            verifyResultsNativeSinpiFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSinpiFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSinpiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeSinpi() {
-        checkNativeSinpiFloatFloat();
-        checkNativeSinpiFloat2Float2();
-        checkNativeSinpiFloat3Float3();
-        checkNativeSinpiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinpi.rs
deleted file mode 100644
index 1b17471..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinpi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeSinpiFloatFloat(float in) {
-    return native_sinpi(in);
-}
-
-float2 __attribute__((kernel)) testNativeSinpiFloat2Float2(float2 in) {
-    return native_sinpi(in);
-}
-
-float3 __attribute__((kernel)) testNativeSinpiFloat3Float3(float3 in) {
-    return native_sinpi(in);
-}
-
-float4 __attribute__((kernel)) testNativeSinpiFloat4Float4(float4 in) {
-    return native_sinpi(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinpiRelaxed.rs
deleted file mode 100644
index 2bc871f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSinpiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeSinpi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSqrt.java
deleted file mode 100644
index edb07bc..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSqrt.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeSqrt extends RSBaseCompute {
-
-    private ScriptC_TestNativeSqrt script;
-    private ScriptC_TestNativeSqrtRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeSqrt(mRS);
-        scriptRelaxed = new ScriptC_TestNativeSqrtRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeSqrtFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb4c9e7b9972ac810l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeSqrtFloatFloat(in, out);
-            verifyResultsNativeSqrtFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSqrtFloatFloat(in, out);
-            verifyResultsNativeSqrtFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSqrtFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSqrtFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSqrtFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc649cd70853776acl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeSqrtFloat2Float2(in, out);
-            verifyResultsNativeSqrtFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSqrtFloat2Float2(in, out);
-            verifyResultsNativeSqrtFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSqrtFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSqrtFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSqrtFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc649d811e43e0c46l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeSqrtFloat3Float3(in, out);
-            verifyResultsNativeSqrtFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSqrtFloat3Float3(in, out);
-            verifyResultsNativeSqrtFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSqrtFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSqrtFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeSqrtFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc649e2b34344a1e0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeSqrtFloat4Float4(in, out);
-            verifyResultsNativeSqrtFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeSqrtFloat4Float4(in, out);
-            verifyResultsNativeSqrtFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeSqrtFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeSqrtFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeSqrt() {
-        checkNativeSqrtFloatFloat();
-        checkNativeSqrtFloat2Float2();
-        checkNativeSqrtFloat3Float3();
-        checkNativeSqrtFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSqrt.rs
deleted file mode 100644
index 2ed1cc8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSqrt.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeSqrtFloatFloat(float in) {
-    return native_sqrt(in);
-}
-
-float2 __attribute__((kernel)) testNativeSqrtFloat2Float2(float2 in) {
-    return native_sqrt(in);
-}
-
-float3 __attribute__((kernel)) testNativeSqrtFloat3Float3(float3 in) {
-    return native_sqrt(in);
-}
-
-float4 __attribute__((kernel)) testNativeSqrtFloat4Float4(float4 in) {
-    return native_sqrt(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSqrtRelaxed.rs
deleted file mode 100644
index aa39435..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeSqrtRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeSqrt.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTan.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTan.java
deleted file mode 100644
index cd51a53..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTan.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeTan extends RSBaseCompute {
-
-    private ScriptC_TestNativeTan script;
-    private ScriptC_TestNativeTanRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeTan(mRS);
-        scriptRelaxed = new ScriptC_TestNativeTanRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeTanFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5b9a224e25042b47l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeTanFloatFloat(in, out);
-            verifyResultsNativeTanFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanFloatFloat(in, out);
-            verifyResultsNativeTanFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeTanFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9c40e8650c550eebl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeTanFloat2Float2(in, out);
-            verifyResultsNativeTanFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanFloat2Float2(in, out);
-            verifyResultsNativeTanFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeTanFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9c40f3066b5ba485l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeTanFloat3Float3(in, out);
-            verifyResultsNativeTanFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanFloat3Float3(in, out);
-            verifyResultsNativeTanFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeTanFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9c40fda7ca623a1fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeTanFloat4Float4(in, out);
-            verifyResultsNativeTanFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanFloat4Float4(in, out);
-            verifyResultsNativeTanFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeTan() {
-        checkNativeTanFloatFloat();
-        checkNativeTanFloat2Float2();
-        checkNativeTanFloat3Float3();
-        checkNativeTanFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTan.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTan.rs
deleted file mode 100644
index 000bc74..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTan.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeTanFloatFloat(float in) {
-    return native_tan(in);
-}
-
-float2 __attribute__((kernel)) testNativeTanFloat2Float2(float2 in) {
-    return native_tan(in);
-}
-
-float3 __attribute__((kernel)) testNativeTanFloat3Float3(float3 in) {
-    return native_tan(in);
-}
-
-float4 __attribute__((kernel)) testNativeTanFloat4Float4(float4 in) {
-    return native_tan(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanRelaxed.rs
deleted file mode 100644
index 9ec6688..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeTan.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanh.java
deleted file mode 100644
index 0b69e5f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeTanh extends RSBaseCompute {
-
-    private ScriptC_TestNativeTanh script;
-    private ScriptC_TestNativeTanhRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeTanh(mRS);
-        scriptRelaxed = new ScriptC_TestNativeTanhRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeTanhFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1ec2702f5ed0580bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeTanhFloatFloat(in, out);
-            verifyResultsNativeTanhFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanhFloatFloat(in, out);
-            verifyResultsNativeTanhFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanhFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeTanhFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2a5b681f8004628fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeTanhFloat2Float2(in, out);
-            verifyResultsNativeTanhFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanhFloat2Float2(in, out);
-            verifyResultsNativeTanhFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanhFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeTanhFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2a5b72c0df0af829l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeTanhFloat3Float3(in, out);
-            verifyResultsNativeTanhFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanhFloat3Float3(in, out);
-            verifyResultsNativeTanhFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanhFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeTanhFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2a5b7d623e118dc3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeTanhFloat4Float4(in, out);
-            verifyResultsNativeTanhFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanhFloat4Float4(in, out);
-            verifyResultsNativeTanhFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanhFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeTanh() {
-        checkNativeTanhFloatFloat();
-        checkNativeTanhFloat2Float2();
-        checkNativeTanhFloat3Float3();
-        checkNativeTanhFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanh.rs
deleted file mode 100644
index a7bfcfd..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeTanhFloatFloat(float in) {
-    return native_tanh(in);
-}
-
-float2 __attribute__((kernel)) testNativeTanhFloat2Float2(float2 in) {
-    return native_tanh(in);
-}
-
-float3 __attribute__((kernel)) testNativeTanhFloat3Float3(float3 in) {
-    return native_tanh(in);
-}
-
-float4 __attribute__((kernel)) testNativeTanhFloat4Float4(float4 in) {
-    return native_tanh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanhRelaxed.rs
deleted file mode 100644
index 27c9275..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanhRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeTanh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanpi.java
deleted file mode 100644
index 1d9b538..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanpi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNativeTanpi extends RSBaseCompute {
-
-    private ScriptC_TestNativeTanpi script;
-    private ScriptC_TestNativeTanpiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNativeTanpi(mRS);
-        scriptRelaxed = new ScriptC_TestNativeTanpiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkNativeTanpiFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3eb84fc2c36e96e0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNativeTanpiFloatFloat(in, out);
-            verifyResultsNativeTanpiFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanpiFloatFloat(in, out);
-            verifyResultsNativeTanpiFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanpiFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanpiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeTanpiFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x13737b13af832fcl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNativeTanpiFloat2Float2(in, out);
-            verifyResultsNativeTanpiFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanpiFloat2Float2(in, out);
-            verifyResultsNativeTanpiFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanpiFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanpiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeTanpiFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x137425299fec896l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNativeTanpiFloat3Float3(in, out);
-            verifyResultsNativeTanpiFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanpiFloat3Float3(in, out);
-            verifyResultsNativeTanpiFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanpiFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanpiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNativeTanpiFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1374cf3f9055e30l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNativeTanpiFloat4Float4(in, out);
-            verifyResultsNativeTanpiFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNativeTanpiFloat4Float4(in, out);
-            verifyResultsNativeTanpiFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNativeTanpiFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNativeTanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNativeTanpiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNativeTanpi() {
-        checkNativeTanpiFloatFloat();
-        checkNativeTanpiFloat2Float2();
-        checkNativeTanpiFloat3Float3();
-        checkNativeTanpiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanpi.rs
deleted file mode 100644
index ae1f633..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanpi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNativeTanpiFloatFloat(float in) {
-    return native_tanpi(in);
-}
-
-float2 __attribute__((kernel)) testNativeTanpiFloat2Float2(float2 in) {
-    return native_tanpi(in);
-}
-
-float3 __attribute__((kernel)) testNativeTanpiFloat3Float3(float3 in) {
-    return native_tanpi(in);
-}
-
-float4 __attribute__((kernel)) testNativeTanpiFloat4Float4(float4 in) {
-    return native_tanpi(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanpiRelaxed.rs
deleted file mode 100644
index 921fa3c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNativeTanpiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNativeTanpi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNextafter.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNextafter.java
deleted file mode 100644
index df69e42..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNextafter.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNextafter extends RSBaseCompute {
-
-    private ScriptC_TestNextafter script;
-    private ScriptC_TestNextafterRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNextafter(mRS);
-        scriptRelaxed = new ScriptC_TestNextafterRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkNextafterFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa3b02393ad412958l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa3b02393ad412959l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNextafterFloatFloatFloat(inX, out);
-            verifyResultsNextafterFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNextafterFloatFloatFloat(inX, out);
-            verifyResultsNextafterFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNextafterFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNextafter(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNextafterFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNextafterFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x29b40e0584a1e24l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x29b40e0584a1e25l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNextafterFloat2Float2Float2(inX, out);
-            verifyResultsNextafterFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNextafterFloat2Float2Float2(inX, out);
-            verifyResultsNextafterFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNextafterFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNextafter(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNextafterFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNextafterFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x57001f005a281fc5l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x57001f005a281fc6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNextafterFloat3Float3Float3(inX, out);
-            verifyResultsNextafterFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNextafterFloat3Float3Float3(inX, out);
-            verifyResultsNextafterFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNextafterFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNextafter(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNextafterFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkNextafterFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xab64fd205c062166l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xab64fd205c062167l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testNextafterFloat4Float4Float4(inX, out);
-            verifyResultsNextafterFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testNextafterFloat4Float4Float4(inX, out);
-            verifyResultsNextafterFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNextafterFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeNextafter(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkNextafterFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testNextafter() {
-        checkNextafterFloatFloatFloat();
-        checkNextafterFloat2Float2Float2();
-        checkNextafterFloat3Float3Float3();
-        checkNextafterFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNextafter.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNextafter.rs
deleted file mode 100644
index a7ae02d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNextafter.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testNextafterFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return nextafter(inX, inY);
-}
-
-float2 __attribute__((kernel)) testNextafterFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return nextafter(inX, inY);
-}
-
-float3 __attribute__((kernel)) testNextafterFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return nextafter(inX, inY);
-}
-
-float4 __attribute__((kernel)) testNextafterFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return nextafter(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNextafterRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNextafterRelaxed.rs
deleted file mode 100644
index 2111f17..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNextafterRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNextafter.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/TestNormalize.java
deleted file mode 100644
index 0d71ec5..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNormalize.java
+++ /dev/null
@@ -1,315 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestNormalize extends RSBaseCompute {
-
-    private ScriptC_TestNormalize script;
-    private ScriptC_TestNormalizeRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestNormalize(mRS);
-        scriptRelaxed = new ScriptC_TestNormalizeRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkNormalizeFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6db01d449460061cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testNormalizeFloatFloat(inV, out);
-            verifyResultsNormalizeFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testNormalizeFloatFloat(inV, out);
-            verifyResultsNormalizeFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNormalizeFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-            // Create the appropriate sized arrays in args
-            // Fill args with the input values
-            args.inV = arrayInV[i];
-            Target target = new Target(relaxed);
-            CoreMathVerifier.computeNormalize(args, target);
-
-            // Compare the expected outputs to the actual values returned by RS.
-            boolean valid = true;
-            if (!args.out.couldBe(arrayOut[i])) {
-                valid = false;
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                message.append("Input inV: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayInV[i], Float.floatToRawIntBits(arrayInV[i]), arrayInV[i]));
-                message.append("\n");
-                message.append("Expected output out: ");
-                message.append(args.out.toString());
-                message.append("\n");
-                message.append("Actual   output out: ");
-                message.append(String.format("%14.8g {%8x} %15a",
-                        arrayOut[i], Float.floatToRawIntBits(arrayOut[i]), arrayOut[i]));
-                if (!args.out.couldBe(arrayOut[i])) {
-                    message.append(" FAIL");
-                }
-                message.append("\n");
-                assertTrue("Incorrect output for checkNormalizeFloatFloat" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public class ArgumentsFloatNFloatN {
-        public float[] inV;
-        public Target.Floaty[] out;
-    }
-
-    private void checkNormalizeFloat2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3cde199a6e066120l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testNormalizeFloat2Float2(inV, out);
-            verifyResultsNormalizeFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testNormalizeFloat2Float2(inV, out);
-            verifyResultsNormalizeFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNormalizeFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[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];
-            }
-            Target target = new Target(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(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 2 + j], Float.floatToRawIntBits(arrayInV[i * 2 + j]), arrayInV[i * 2 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 2 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkNormalizeFloat2Float2" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkNormalizeFloat3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3cdfe2b5642181fel, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testNormalizeFloat3Float3(inV, out);
-            verifyResultsNormalizeFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testNormalizeFloat3Float3(inV, out);
-            verifyResultsNormalizeFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNormalizeFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[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];
-            }
-            Target target = new Target(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(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 3 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkNormalizeFloat3Float3" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    private void checkNormalizeFloat4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3ce1abd05a3ca2dcl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testNormalizeFloat4Float4(inV, out);
-            verifyResultsNormalizeFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testNormalizeFloat4Float4(inV, out);
-            verifyResultsNormalizeFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsNormalizeFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
-            // Create the appropriate sized arrays in args
-            args.inV = new float[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];
-            }
-            Target target = new Target(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(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-            }
-            if (!valid) {
-                StringBuilder message = new StringBuilder();
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayInV[i * 4 + j], Float.floatToRawIntBits(arrayInV[i * 4 + j]), arrayInV[i * 4 + j]));
-                    message.append("\n");
-                }
-                for (int j = 0; j < 4 ; j++) {
-                    message.append("Expected output out: ");
-                    message.append(args.out[j].toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out[j].couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                }
-                assertTrue("Incorrect output for checkNormalizeFloat4Float4" +
-                        (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-            }
-        }
-    }
-
-    public void testNormalize() {
-        checkNormalizeFloatFloat();
-        checkNormalizeFloat2Float2();
-        checkNormalizeFloat3Float3();
-        checkNormalizeFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNormalize.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNormalize.rs
deleted file mode 100644
index fbb5281..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNormalize.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testNormalizeFloatFloat(float inV) {
-    return normalize(inV);
-}
-
-float2 __attribute__((kernel)) testNormalizeFloat2Float2(float2 inV) {
-    return normalize(inV);
-}
-
-float3 __attribute__((kernel)) testNormalizeFloat3Float3(float3 inV) {
-    return normalize(inV);
-}
-
-float4 __attribute__((kernel)) testNormalizeFloat4Float4(float4 inV) {
-    return normalize(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestNormalizeRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestNormalizeRelaxed.rs
deleted file mode 100644
index 148bec3..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestNormalizeRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestNormalize.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPow.java b/tests/tests/renderscript/src/android/renderscript/cts/TestPow.java
deleted file mode 100644
index 39369c4..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestPow.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestPow extends RSBaseCompute {
-
-    private ScriptC_TestPow script;
-    private ScriptC_TestPowRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestPow(mRS);
-        scriptRelaxed = new ScriptC_TestPowRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkPowFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x470aeab18312445bl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x470aeab18312445cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPowFloatFloatFloat(inX, out);
-            verifyResultsPowFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPowFloatFloatFloat(inX, out);
-            verifyResultsPowFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPowFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePow(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPowFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkPowFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbcd9b7ed561242ddl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbcd9b7ed561242del, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPowFloat2Float2Float2(inX, out);
-            verifyResultsPowFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPowFloat2Float2Float2(inX, out);
-            verifyResultsPowFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPowFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePow(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPowFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkPowFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x113e960d57f0447el, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x113e960d57f0447fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPowFloat3Float3Float3(inX, out);
-            verifyResultsPowFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPowFloat3Float3Float3(inX, out);
-            verifyResultsPowFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPowFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePow(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPowFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkPowFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x65a3742d59ce461fl, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x65a3742d59ce4620l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPowFloat4Float4Float4(inX, out);
-            verifyResultsPowFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPowFloat4Float4Float4(inX, out);
-            verifyResultsPowFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPowFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePow(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPowFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testPow() {
-        checkPowFloatFloatFloat();
-        checkPowFloat2Float2Float2();
-        checkPowFloat3Float3Float3();
-        checkPowFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPow.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestPow.rs
deleted file mode 100644
index 855419a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestPow.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testPowFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return pow(inX, inY);
-}
-
-float2 __attribute__((kernel)) testPowFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return pow(inX, inY);
-}
-
-float3 __attribute__((kernel)) testPowFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return pow(inX, inY);
-}
-
-float4 __attribute__((kernel)) testPowFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return pow(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPowRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestPowRelaxed.rs
deleted file mode 100644
index eae1207..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestPowRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestPow.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPown.java b/tests/tests/renderscript/src/android/renderscript/cts/TestPown.java
deleted file mode 100644
index 14a09e1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestPown.java
+++ /dev/null
@@ -1,321 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestPown extends RSBaseCompute {
-
-    private ScriptC_TestPown script;
-    private ScriptC_TestPownRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestPown(mRS);
-        scriptRelaxed = new ScriptC_TestPownRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatIntFloat {
-        public float inX;
-        public int inY;
-        public Target.Floaty out;
-    }
-
-    private void checkPownFloatIntFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xde633e0d2c462948l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xde633e0d2c462949l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPownFloatIntFloat(inX, out);
-            verifyResultsPownFloatIntFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloatIntFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPownFloatIntFloat(inX, out);
-            verifyResultsPownFloatIntFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloatIntFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPownFloatIntFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePown(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPownFloatIntFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkPownFloat2Int2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1685dc0ea821329el, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x1685dc0ea821329fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPownFloat2Int2Float2(inX, out);
-            verifyResultsPownFloat2Int2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat2Int2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPownFloat2Int2Float2(inX, out);
-            verifyResultsPownFloat2Int2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat2Int2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPownFloat2Int2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePown(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPownFloat2Int2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkPownFloat3Int3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3c3c1a719dd39f57l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x3c3c1a719dd39f58l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPownFloat3Int3Float3(inX, out);
-            verifyResultsPownFloat3Int3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat3Int3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPownFloat3Int3Float3(inX, out);
-            verifyResultsPownFloat3Int3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat3Int3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPownFloat3Int3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePown(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPownFloat3Int3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkPownFloat4Int4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x61f258d493860c10l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x61f258d493860c11l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPownFloat4Int4Float4(inX, out);
-            verifyResultsPownFloat4Int4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat4Int4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPownFloat4Int4Float4(inX, out);
-            verifyResultsPownFloat4Int4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat4Int4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPownFloat4Int4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        int[] arrayInY = new int[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePown(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%d", args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPownFloat4Int4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testPown() {
-        checkPownFloatIntFloat();
-        checkPownFloat2Int2Float2();
-        checkPownFloat3Int3Float3();
-        checkPownFloat4Int4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPown.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestPown.rs
deleted file mode 100644
index 3ee4fc0..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestPown.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testPownFloatIntFloat(float inX, unsigned int x) {
-    int inY = rsGetElementAt_int(gAllocInY, x);
-    return pown(inX, inY);
-}
-
-float2 __attribute__((kernel)) testPownFloat2Int2Float2(float2 inX, unsigned int x) {
-    int2 inY = rsGetElementAt_int2(gAllocInY, x);
-    return pown(inX, inY);
-}
-
-float3 __attribute__((kernel)) testPownFloat3Int3Float3(float3 inX, unsigned int x) {
-    int3 inY = rsGetElementAt_int3(gAllocInY, x);
-    return pown(inX, inY);
-}
-
-float4 __attribute__((kernel)) testPownFloat4Int4Float4(float4 inX, unsigned int x) {
-    int4 inY = rsGetElementAt_int4(gAllocInY, x);
-    return pown(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPownRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestPownRelaxed.rs
deleted file mode 100644
index d35cd0b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestPownRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestPown.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPowr.java b/tests/tests/renderscript/src/android/renderscript/cts/TestPowr.java
deleted file mode 100644
index b1f281b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestPowr.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestPowr extends RSBaseCompute {
-
-    private ScriptC_TestPowr script;
-    private ScriptC_TestPowrRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestPowr(mRS);
-        scriptRelaxed = new ScriptC_TestPowrRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkPowrFloatFloatFloat() {
-        Allocation inX = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x616e17ec158f6a8dl, 0, 3000);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x616e17ec158f6a8el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPowrFloatFloatFloat(inX, out);
-            verifyResultsPowrFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPowrFloatFloatFloat(inX, out);
-            verifyResultsPowrFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPowrFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePowr(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPowrFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkPowrFloat2Float2Float2() {
-        Allocation inX = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfc919df3002fbd93l, 0, 3000);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfc919df3002fbd94l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPowrFloat2Float2Float2(inX, out);
-            verifyResultsPowrFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPowrFloat2Float2Float2(inX, out);
-            verifyResultsPowrFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPowrFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePowr(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPowrFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkPowrFloat3Float3Float3() {
-        Allocation inX = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x50f67c13020dbf34l, 0, 3000);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x50f67c13020dbf35l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPowrFloat3Float3Float3(inX, out);
-            verifyResultsPowrFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPowrFloat3Float3Float3(inX, out);
-            verifyResultsPowrFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPowrFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePowr(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPowrFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkPowrFloat4Float4Float4() {
-        Allocation inX = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa55b5a3303ebc0d5l, 0, 3000);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa55b5a3303ebc0d6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testPowrFloat4Float4Float4(inX, out);
-            verifyResultsPowrFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testPowrFloat4Float4Float4(inX, out);
-            verifyResultsPowrFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsPowrFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computePowr(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkPowrFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testPowr() {
-        checkPowrFloatFloatFloat();
-        checkPowrFloat2Float2Float2();
-        checkPowrFloat3Float3Float3();
-        checkPowrFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPowr.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestPowr.rs
deleted file mode 100644
index 0fd603e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestPowr.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testPowrFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return powr(inX, inY);
-}
-
-float2 __attribute__((kernel)) testPowrFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return powr(inX, inY);
-}
-
-float3 __attribute__((kernel)) testPowrFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return powr(inX, inY);
-}
-
-float4 __attribute__((kernel)) testPowrFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return powr(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestPowrRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestPowrRelaxed.rs
deleted file mode 100644
index 95e6f84..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestPowrRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestPowr.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRadians.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRadians.java
deleted file mode 100644
index 2707ac2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRadians.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestRadians extends RSBaseCompute {
-
-    private ScriptC_TestRadians script;
-    private ScriptC_TestRadiansRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestRadians(mRS);
-        scriptRelaxed = new ScriptC_TestRadiansRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inValue;
-        public Target.Floaty out;
-    }
-
-    private void checkRadiansFloatFloat() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xaa72f227598b8106l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testRadiansFloatFloat(inValue, out);
-            verifyResultsRadiansFloatFloat(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testRadiansFloatFloat(inValue, out);
-            verifyResultsRadiansFloatFloat(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRadiansFloatFloat(Allocation inValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 1];
-        inValue.copyTo(arrayInValue);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inValue = arrayInValue[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRadians(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRadiansFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRadiansFloat2Float2() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb28bd9316e059892l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testRadiansFloat2Float2(inValue, out);
-            verifyResultsRadiansFloat2Float2(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testRadiansFloat2Float2(inValue, out);
-            verifyResultsRadiansFloat2Float2(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRadiansFloat2Float2(Allocation inValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 2];
-        inValue.copyTo(arrayInValue);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inValue = arrayInValue[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRadians(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRadiansFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRadiansFloat3Float3() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd8404eb8b743be10l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testRadiansFloat3Float3(inValue, out);
-            verifyResultsRadiansFloat3Float3(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testRadiansFloat3Float3(inValue, out);
-            verifyResultsRadiansFloat3Float3(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRadiansFloat3Float3(Allocation inValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRadians(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRadiansFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRadiansFloat4Float4() {
-        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfdf4c4400081e38el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testRadiansFloat4Float4(inValue, out);
-            verifyResultsRadiansFloat4Float4(inValue, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testRadiansFloat4Float4(inValue, out);
-            verifyResultsRadiansFloat4Float4(inValue, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRadiansFloat4Float4(Allocation inValue, Allocation out, boolean relaxed) {
-        float[] arrayInValue = new float[INPUTSIZE * 4];
-        inValue.copyTo(arrayInValue);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inValue = arrayInValue[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRadians(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inValue: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inValue, Float.floatToRawIntBits(args.inValue), args.inValue));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRadiansFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testRadians() {
-        checkRadiansFloatFloat();
-        checkRadiansFloat2Float2();
-        checkRadiansFloat3Float3();
-        checkRadiansFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRadians.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRadians.rs
deleted file mode 100644
index 09aa9a0..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRadians.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testRadiansFloatFloat(float inValue) {
-    return radians(inValue);
-}
-
-float2 __attribute__((kernel)) testRadiansFloat2Float2(float2 inValue) {
-    return radians(inValue);
-}
-
-float3 __attribute__((kernel)) testRadiansFloat3Float3(float3 inValue) {
-    return radians(inValue);
-}
-
-float4 __attribute__((kernel)) testRadiansFloat4Float4(float4 inValue) {
-    return radians(inValue);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRadiansRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRadiansRelaxed.rs
deleted file mode 100644
index fa9209f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRadiansRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestRadians.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRemainder.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRemainder.java
deleted file mode 100644
index 8208d23..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRemainder.java
+++ /dev/null
@@ -1,325 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestRemainder extends RSBaseCompute {
-
-    private ScriptC_TestRemainder script;
-    private ScriptC_TestRemainderRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestRemainder(mRS);
-        scriptRelaxed = new ScriptC_TestRemainderRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inX;
-        public float inY;
-        public Target.Floaty out;
-    }
-
-    private void checkRemainderFloatFloatFloat() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x27d6330966022888l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x27d6330966022889l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testRemainderFloatFloatFloat(inX, out);
-            verifyResultsRemainderFloatFloatFloat(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testRemainderFloatFloatFloat(inX, out);
-            verifyResultsRemainderFloatFloatFloat(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRemainderFloatFloatFloat(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 1];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 1];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i];
-                args.inY = arrayInY[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRemainder(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRemainderFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRemainderFloat2Float2Float2() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb2eaf332420c6b4l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb2eaf332420c6b5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testRemainderFloat2Float2Float2(inX, out);
-            verifyResultsRemainderFloat2Float2Float2(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testRemainderFloat2Float2Float2(inX, out);
-            verifyResultsRemainderFloat2Float2Float2(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRemainderFloat2Float2Float2(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 2];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 2];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 2 + j];
-                args.inY = arrayInY[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRemainder(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRemainderFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRemainderFloat3Float3Float3() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4f938d5325fec855l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4f938d5325fec856l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testRemainderFloat3Float3Float3(inX, out);
-            verifyResultsRemainderFloat3Float3Float3(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testRemainderFloat3Float3Float3(inX, out);
-            verifyResultsRemainderFloat3Float3Float3(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRemainderFloat3Float3Float3(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRemainder(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRemainderFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRemainderFloat4Float4Float4() {
-        Allocation inX = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa3f86b7327dcc9f6l, false);
-        Allocation inY = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa3f86b7327dcc9f7l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInY(inY);
-            script.forEach_testRemainderFloat4Float4Float4(inX, out);
-            verifyResultsRemainderFloat4Float4Float4(inX, inY, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInY(inY);
-            scriptRelaxed.forEach_testRemainderFloat4Float4Float4(inX, out);
-            verifyResultsRemainderFloat4Float4Float4(inX, inY, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRemainderFloat4Float4Float4(Allocation inX, Allocation inY, Allocation out, boolean relaxed) {
-        float[] arrayInX = new float[INPUTSIZE * 4];
-        inX.copyTo(arrayInX);
-        float[] arrayInY = new float[INPUTSIZE * 4];
-        inY.copyTo(arrayInY);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inX = arrayInX[i * 4 + j];
-                args.inY = arrayInY[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRemainder(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inX: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inX, Float.floatToRawIntBits(args.inX), args.inX));
-                    message.append("\n");
-                    message.append("Input inY: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inY, Float.floatToRawIntBits(args.inY), args.inY));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRemainderFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testRemainder() {
-        checkRemainderFloatFloatFloat();
-        checkRemainderFloat2Float2Float2();
-        checkRemainderFloat3Float3Float3();
-        checkRemainderFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRemainder.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRemainder.rs
deleted file mode 100644
index 86f2030..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRemainder.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInY;
-
-float __attribute__((kernel)) testRemainderFloatFloatFloat(float inX, unsigned int x) {
-    float inY = rsGetElementAt_float(gAllocInY, x);
-    return remainder(inX, inY);
-}
-
-float2 __attribute__((kernel)) testRemainderFloat2Float2Float2(float2 inX, unsigned int x) {
-    float2 inY = rsGetElementAt_float2(gAllocInY, x);
-    return remainder(inX, inY);
-}
-
-float3 __attribute__((kernel)) testRemainderFloat3Float3Float3(float3 inX, unsigned int x) {
-    float3 inY = rsGetElementAt_float3(gAllocInY, x);
-    return remainder(inX, inY);
-}
-
-float4 __attribute__((kernel)) testRemainderFloat4Float4Float4(float4 inX, unsigned int x) {
-    float4 inY = rsGetElementAt_float4(gAllocInY, x);
-    return remainder(inX, inY);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRemainderRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRemainderRelaxed.rs
deleted file mode 100644
index 7c45964..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRemainderRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestRemainder.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRemquo.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRemquo.java
deleted file mode 100644
index 7052dd1..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRemquo.java
+++ /dev/null
@@ -1,334 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestRemquo extends RSBaseCompute {
-
-    private ScriptC_TestRemquo script;
-    private ScriptC_TestRemquoRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestRemquo(mRS);
-        scriptRelaxed = new ScriptC_TestRemquoRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatIntFloat {
-        public float inB;
-        public float inC;
-        public int outD;
-        public float out;
-    }
-
-    private void checkRemquoFloatFloatIntFloat() {
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x118af9b82db63b13l, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x118af9b82db63b14l, false);
-        try {
-            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInC(inC);
-            script.set_gAllocOutD(outD);
-            script.forEach_testRemquoFloatFloatIntFloat(inB, out);
-            verifyResultsRemquoFloatFloatIntFloat(inB, inC, outD, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloatFloatIntFloat: " + e.toString());
-        }
-        try {
-            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.set_gAllocOutD(outD);
-            scriptRelaxed.forEach_testRemquoFloatFloatIntFloat(inB, out);
-            verifyResultsRemquoFloatFloatIntFloat(inB, inC, outD, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloatFloatIntFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRemquoFloatFloatIntFloat(Allocation inB, Allocation inC, Allocation outD, Allocation out, boolean relaxed) {
-        float[] arrayInB = new float[INPUTSIZE * 1];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 1];
-        inC.copyTo(arrayInC);
-        int[] arrayOutD = new int[INPUTSIZE * 1];
-        outD.copyTo(arrayOutD);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
-                args.inB = arrayInB[i];
-                args.inC = arrayInC[i];
-                // Extract the outputs.
-                args.outD = arrayOutD[i * 1 + j];
-                args.out = arrayOut[i * 1 + j];
-                // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
-                String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Output outD: ");
-                    message.append(String.format("%d", args.outD));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(Float.toString(args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkRemquoFloatFloatIntFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRemquoFloat2Float2Int2Float2() {
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9b98a1a6b125f903l, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9b98a1a6b125f904l, false);
-        try {
-            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInC(inC);
-            script.set_gAllocOutD(outD);
-            script.forEach_testRemquoFloat2Float2Int2Float2(inB, out);
-            verifyResultsRemquoFloat2Float2Int2Float2(inB, inC, outD, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat2Float2Int2Float2: " + e.toString());
-        }
-        try {
-            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.set_gAllocOutD(outD);
-            scriptRelaxed.forEach_testRemquoFloat2Float2Int2Float2(inB, out);
-            verifyResultsRemquoFloat2Float2Int2Float2(inB, inC, outD, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat2Float2Int2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRemquoFloat2Float2Int2Float2(Allocation inB, Allocation inC, Allocation outD, Allocation out, boolean relaxed) {
-        float[] arrayInB = new float[INPUTSIZE * 2];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 2];
-        inC.copyTo(arrayInC);
-        int[] arrayOutD = new int[INPUTSIZE * 2];
-        outD.copyTo(arrayOutD);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
-                args.inB = arrayInB[i * 2 + j];
-                args.inC = arrayInC[i * 2 + j];
-                // Extract the outputs.
-                args.outD = arrayOutD[i * 2 + j];
-                args.out = arrayOut[i * 2 + j];
-                // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
-                String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Output outD: ");
-                    message.append(String.format("%d", args.outD));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(Float.toString(args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkRemquoFloat2Float2Int2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRemquoFloat3Float3Int3Float3() {
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa049a00a6911ca8fl, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa049a00a6911ca90l, false);
-        try {
-            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInC(inC);
-            script.set_gAllocOutD(outD);
-            script.forEach_testRemquoFloat3Float3Int3Float3(inB, out);
-            verifyResultsRemquoFloat3Float3Int3Float3(inB, inC, outD, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat3Float3Int3Float3: " + e.toString());
-        }
-        try {
-            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.set_gAllocOutD(outD);
-            scriptRelaxed.forEach_testRemquoFloat3Float3Int3Float3(inB, out);
-            verifyResultsRemquoFloat3Float3Int3Float3(inB, inC, outD, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat3Float3Int3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRemquoFloat3Float3Int3Float3(Allocation inB, Allocation inC, Allocation outD, Allocation out, boolean relaxed) {
-        float[] arrayInB = new float[INPUTSIZE * 4];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 4];
-        inC.copyTo(arrayInC);
-        int[] arrayOutD = new int[INPUTSIZE * 4];
-        outD.copyTo(arrayOutD);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
-                args.inB = arrayInB[i * 4 + j];
-                args.inC = arrayInC[i * 4 + j];
-                // Extract the outputs.
-                args.outD = arrayOutD[i * 4 + j];
-                args.out = arrayOut[i * 4 + j];
-                // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
-                String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Output outD: ");
-                    message.append(String.format("%d", args.outD));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(Float.toString(args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkRemquoFloat3Float3Int3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRemquoFloat4Float4Int4Float4() {
-        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa4fa9e6e20fd9c1bl, false);
-        Allocation inC = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa4fa9e6e20fd9c1cl, false);
-        try {
-            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInC(inC);
-            script.set_gAllocOutD(outD);
-            script.forEach_testRemquoFloat4Float4Int4Float4(inB, out);
-            verifyResultsRemquoFloat4Float4Int4Float4(inB, inC, outD, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat4Float4Int4Float4: " + e.toString());
-        }
-        try {
-            Allocation outD = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInC(inC);
-            scriptRelaxed.set_gAllocOutD(outD);
-            scriptRelaxed.forEach_testRemquoFloat4Float4Int4Float4(inB, out);
-            verifyResultsRemquoFloat4Float4Int4Float4(inB, inC, outD, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat4Float4Int4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRemquoFloat4Float4Int4Float4(Allocation inB, Allocation inC, Allocation outD, Allocation out, boolean relaxed) {
-        float[] arrayInB = new float[INPUTSIZE * 4];
-        inB.copyTo(arrayInB);
-        float[] arrayInC = new float[INPUTSIZE * 4];
-        inC.copyTo(arrayInC);
-        int[] arrayOutD = new int[INPUTSIZE * 4];
-        outD.copyTo(arrayOutD);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
-                args.inB = arrayInB[i * 4 + j];
-                args.inC = arrayInC[i * 4 + j];
-                // Extract the outputs.
-                args.outD = arrayOutD[i * 4 + j];
-                args.out = arrayOut[i * 4 + j];
-                // Ask the CoreMathVerifier to validate.
-                Target target = new Target(relaxed);
-                String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
-                boolean valid = errorMessage == null;
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inB: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inB, Float.floatToRawIntBits(args.inB), args.inB));
-                    message.append("\n");
-                    message.append("Input inC: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inC, Float.floatToRawIntBits(args.inC), args.inC));
-                    message.append("\n");
-                    message.append("Output outD: ");
-                    message.append(String.format("%d", args.outD));
-                    message.append("\n");
-                    message.append("Output out: ");
-                    message.append(Float.toString(args.out));
-                    message.append("\n");
-                    message.append(errorMessage);
-                    assertTrue("Incorrect output for checkRemquoFloat4Float4Int4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testRemquo() {
-        checkRemquoFloatFloatIntFloat();
-        checkRemquoFloat2Float2Int2Float2();
-        checkRemquoFloat3Float3Int3Float3();
-        checkRemquoFloat4Float4Int4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRemquo.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRemquo.rs
deleted file mode 100644
index 032e6c0..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRemquo.rs
+++ /dev/null
@@ -1,55 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInC;
-rs_allocation gAllocOutD;
-
-float __attribute__((kernel)) testRemquoFloatFloatIntFloat(float inB, unsigned int x) {
-    float inC = rsGetElementAt_float(gAllocInC, x);
-    int outD = 0;
-    float out = remquo(inB, inC, &outD);
-    rsSetElementAt_int(gAllocOutD, outD, x);
-    return out;
-}
-
-float2 __attribute__((kernel)) testRemquoFloat2Float2Int2Float2(float2 inB, unsigned int x) {
-    float2 inC = rsGetElementAt_float2(gAllocInC, x);
-    int2 outD = 0;
-    float2 out = remquo(inB, inC, &outD);
-    rsSetElementAt_int2(gAllocOutD, outD, x);
-    return out;
-}
-
-float3 __attribute__((kernel)) testRemquoFloat3Float3Int3Float3(float3 inB, unsigned int x) {
-    float3 inC = rsGetElementAt_float3(gAllocInC, x);
-    int3 outD = 0;
-    float3 out = remquo(inB, inC, &outD);
-    rsSetElementAt_int3(gAllocOutD, outD, x);
-    return out;
-}
-
-float4 __attribute__((kernel)) testRemquoFloat4Float4Int4Float4(float4 inB, unsigned int x) {
-    float4 inC = rsGetElementAt_float4(gAllocInC, x);
-    int4 outD = 0;
-    float4 out = remquo(inB, inC, &outD);
-    rsSetElementAt_int4(gAllocOutD, outD, x);
-    return out;
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRemquoRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRemquoRelaxed.rs
deleted file mode 100644
index 3962532..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRemquoRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestRemquo.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRint.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRint.java
deleted file mode 100644
index 6d42aeb..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRint.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestRint extends RSBaseCompute {
-
-    private ScriptC_TestRint script;
-    private ScriptC_TestRintRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestRint(mRS);
-        scriptRelaxed = new ScriptC_TestRintRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkRintFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe569fda5dbe93fal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testRintFloatFloat(in, out);
-            verifyResultsRintFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testRintFloatFloat(in, out);
-            verifyResultsRintFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRintFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRint(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRintFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRintFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xffa7b22ac6b343c6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testRintFloat2Float2(in, out);
-            verifyResultsRintFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testRintFloat2Float2(in, out);
-            verifyResultsRintFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRintFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRint(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRintFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRintFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xffa7bccc25b9d960l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testRintFloat3Float3(in, out);
-            verifyResultsRintFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testRintFloat3Float3(in, out);
-            verifyResultsRintFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRintFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRint(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRintFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRintFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xffa7c76d84c06efal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testRintFloat4Float4(in, out);
-            verifyResultsRintFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testRintFloat4Float4(in, out);
-            verifyResultsRintFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRintFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRint(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRintFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testRint() {
-        checkRintFloatFloat();
-        checkRintFloat2Float2();
-        checkRintFloat3Float3();
-        checkRintFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRint.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRint.rs
deleted file mode 100644
index a551d68..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRint.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testRintFloatFloat(float in) {
-    return rint(in);
-}
-
-float2 __attribute__((kernel)) testRintFloat2Float2(float2 in) {
-    return rint(in);
-}
-
-float3 __attribute__((kernel)) testRintFloat3Float3(float3 in) {
-    return rint(in);
-}
-
-float4 __attribute__((kernel)) testRintFloat4Float4(float4 in) {
-    return rint(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRintRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRintRelaxed.rs
deleted file mode 100644
index 9fb4636..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRintRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestRint.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRootn.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRootn.java
deleted file mode 100644
index b9562e4..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRootn.java
+++ /dev/null
@@ -1,321 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestRootn extends RSBaseCompute {
-
-    private ScriptC_TestRootn script;
-    private ScriptC_TestRootnRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestRootn(mRS);
-        scriptRelaxed = new ScriptC_TestRootnRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatIntFloat {
-        public float inV;
-        public int inN;
-        public Target.Floaty out;
-    }
-
-    private void checkRootnFloatIntFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x37d0d9514daae0ccl, false);
-        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x37d0d9514daae0c4l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInN(inN);
-            script.forEach_testRootnFloatIntFloat(inV, out);
-            verifyResultsRootnFloatIntFloat(inV, inN, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloatIntFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInN(inN);
-            scriptRelaxed.forEach_testRootnFloatIntFloat(inV, out);
-            verifyResultsRootnFloatIntFloat(inV, inN, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloatIntFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRootnFloatIntFloat(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        int[] arrayInN = new int[INPUTSIZE * 1];
-        inN.copyTo(arrayInN);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                args.inV = arrayInV[i];
-                args.inN = arrayInN[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRootn(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inN: ");
-                    message.append(String.format("%d", args.inN));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRootnFloatIntFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRootnFloat2Int2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2a7a849dcb32d88el, false);
-        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x2a7a849dcb32d886l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInN(inN);
-            script.forEach_testRootnFloat2Int2Float2(inV, out);
-            verifyResultsRootnFloat2Int2Float2(inV, inN, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat2Int2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInN(inN);
-            scriptRelaxed.forEach_testRootnFloat2Int2Float2(inV, out);
-            verifyResultsRootnFloat2Int2Float2(inV, inN, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat2Int2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRootnFloat2Int2Float2(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        int[] arrayInN = new int[INPUTSIZE * 2];
-        inN.copyTo(arrayInN);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                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);
-                CoreMathVerifier.computeRootn(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inN: ");
-                    message.append(String.format("%d", args.inN));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRootnFloat2Int2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRootnFloat3Int3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5030c300c0e54547l, false);
-        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x5030c300c0e5453fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInN(inN);
-            script.forEach_testRootnFloat3Int3Float3(inV, out);
-            verifyResultsRootnFloat3Int3Float3(inV, inN, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat3Int3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInN(inN);
-            scriptRelaxed.forEach_testRootnFloat3Int3Float3(inV, out);
-            verifyResultsRootnFloat3Int3Float3(inV, inN, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat3Int3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRootnFloat3Int3Float3(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayInN = new int[INPUTSIZE * 4];
-        inN.copyTo(arrayInN);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                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);
-                CoreMathVerifier.computeRootn(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inN: ");
-                    message.append(String.format("%d", args.inN));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRootnFloat3Int3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRootnFloat4Int4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x75e70163b697b200l, false);
-        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x75e70163b697b1f8l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInN(inN);
-            script.forEach_testRootnFloat4Int4Float4(inV, out);
-            verifyResultsRootnFloat4Int4Float4(inV, inN, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat4Int4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInN(inN);
-            scriptRelaxed.forEach_testRootnFloat4Int4Float4(inV, out);
-            verifyResultsRootnFloat4Int4Float4(inV, inN, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat4Int4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRootnFloat4Int4Float4(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        int[] arrayInN = new int[INPUTSIZE * 4];
-        inN.copyTo(arrayInN);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
-                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);
-                CoreMathVerifier.computeRootn(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Input inN: ");
-                    message.append(String.format("%d", args.inN));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRootnFloat4Int4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testRootn() {
-        checkRootnFloatIntFloat();
-        checkRootnFloat2Int2Float2();
-        checkRootnFloat3Int3Float3();
-        checkRootnFloat4Int4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRootn.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRootn.rs
deleted file mode 100644
index e4ee02b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRootn.rs
+++ /dev/null
@@ -1,42 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInN;
-
-float __attribute__((kernel)) testRootnFloatIntFloat(float inV, unsigned int x) {
-    int inN = rsGetElementAt_int(gAllocInN, x);
-    return rootn(inV, inN);
-}
-
-float2 __attribute__((kernel)) testRootnFloat2Int2Float2(float2 inV, unsigned int x) {
-    int2 inN = rsGetElementAt_int2(gAllocInN, x);
-    return rootn(inV, inN);
-}
-
-float3 __attribute__((kernel)) testRootnFloat3Int3Float3(float3 inV, unsigned int x) {
-    int3 inN = rsGetElementAt_int3(gAllocInN, x);
-    return rootn(inV, inN);
-}
-
-float4 __attribute__((kernel)) testRootnFloat4Int4Float4(float4 inV, unsigned int x) {
-    int4 inN = rsGetElementAt_int4(gAllocInN, x);
-    return rootn(inV, inN);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRootnRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRootnRelaxed.rs
deleted file mode 100644
index e42d664..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRootnRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestRootn.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRound.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRound.java
deleted file mode 100644
index f9c9a9d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRound.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestRound extends RSBaseCompute {
-
-    private ScriptC_TestRound script;
-    private ScriptC_TestRoundRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestRound(mRS);
-        scriptRelaxed = new ScriptC_TestRoundRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkRoundFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x377ca8d7e9a82fc7l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testRoundFloatFloat(in, out);
-            verifyResultsRoundFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testRoundFloatFloat(in, out);
-            verifyResultsRoundFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRoundFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRound(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRoundFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRoundFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc35ea17250f98f6bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testRoundFloat2Float2(in, out);
-            verifyResultsRoundFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testRoundFloat2Float2(in, out);
-            verifyResultsRoundFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRoundFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRound(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRoundFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRoundFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc35eac13b0002505l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testRoundFloat3Float3(in, out);
-            verifyResultsRoundFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testRoundFloat3Float3(in, out);
-            verifyResultsRoundFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRoundFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRound(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRoundFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRoundFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc35eb6b50f06ba9fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testRoundFloat4Float4(in, out);
-            verifyResultsRoundFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testRoundFloat4Float4(in, out);
-            verifyResultsRoundFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRoundFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRound(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRoundFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testRound() {
-        checkRoundFloatFloat();
-        checkRoundFloat2Float2();
-        checkRoundFloat3Float3();
-        checkRoundFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRound.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRound.rs
deleted file mode 100644
index 0442849..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRound.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testRoundFloatFloat(float in) {
-    return round(in);
-}
-
-float2 __attribute__((kernel)) testRoundFloat2Float2(float2 in) {
-    return round(in);
-}
-
-float3 __attribute__((kernel)) testRoundFloat3Float3(float3 in) {
-    return round(in);
-}
-
-float4 __attribute__((kernel)) testRoundFloat4Float4(float4 in) {
-    return round(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRoundRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRoundRelaxed.rs
deleted file mode 100644
index ebbdccf..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRoundRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestRound.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrt.java
deleted file mode 100644
index 7b57621..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrt.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestRsqrt extends RSBaseCompute {
-
-    private ScriptC_TestRsqrt script;
-    private ScriptC_TestRsqrtRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestRsqrt(mRS);
-        scriptRelaxed = new ScriptC_TestRsqrtRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkRsqrtFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x736e0d9786ef9c2bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testRsqrtFloatFloat(in, out);
-            verifyResultsRsqrtFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testRsqrtFloatFloat(in, out);
-            verifyResultsRsqrtFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRsqrtFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRsqrtFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRsqrtFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb5df4d6949d76dafl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testRsqrtFloat2Float2(in, out);
-            verifyResultsRsqrtFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testRsqrtFloat2Float2(in, out);
-            verifyResultsRsqrtFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRsqrtFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRsqrtFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRsqrtFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xb5df580aa8de0349l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testRsqrtFloat3Float3(in, out);
-            verifyResultsRsqrtFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testRsqrtFloat3Float3(in, out);
-            verifyResultsRsqrtFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRsqrtFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRsqrtFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkRsqrtFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb5df62ac07e498e3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testRsqrtFloat4Float4(in, out);
-            verifyResultsRsqrtFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testRsqrtFloat4Float4(in, out);
-            verifyResultsRsqrtFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsRsqrtFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeRsqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkRsqrtFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testRsqrt() {
-        checkRsqrtFloatFloat();
-        checkRsqrtFloat2Float2();
-        checkRsqrtFloat3Float3();
-        checkRsqrtFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrt.rs
deleted file mode 100644
index 5978899..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrt.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testRsqrtFloatFloat(float in) {
-    return rsqrt(in);
-}
-
-float2 __attribute__((kernel)) testRsqrtFloat2Float2(float2 in) {
-    return rsqrt(in);
-}
-
-float3 __attribute__((kernel)) testRsqrtFloat3Float3(float3 in) {
-    return rsqrt(in);
-}
-
-float4 __attribute__((kernel)) testRsqrtFloat4Float4(float4 in) {
-    return rsqrt(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrtRelaxed.rs
deleted file mode 100644
index 262761e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestRsqrtRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestRsqrt.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSign.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSign.java
deleted file mode 100644
index 77c467c..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSign.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestSign extends RSBaseCompute {
-
-    private ScriptC_TestSign script;
-    private ScriptC_TestSignRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestSign(mRS);
-        scriptRelaxed = new ScriptC_TestSignRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkSignFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xadc8bc2f364ea474l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testSignFloatFloat(inV, out);
-            verifyResultsSignFloatFloat(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testSignFloatFloat(inV, out);
-            verifyResultsSignFloatFloat(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSignFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSign(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSignFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSignFloat2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2eb1e646027c0ab8l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testSignFloat2Float2(inV, out);
-            verifyResultsSignFloat2Float2(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testSignFloat2Float2(inV, out);
-            verifyResultsSignFloat2Float2(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSignFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSign(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSignFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSignFloat3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2eb3af60f8972b96l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testSignFloat3Float3(inV, out);
-            verifyResultsSignFloat3Float3(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testSignFloat3Float3(inV, out);
-            verifyResultsSignFloat3Float3(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSignFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSign(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSignFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSignFloat4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2eb5787beeb24c74l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testSignFloat4Float4(inV, out);
-            verifyResultsSignFloat4Float4(inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testSignFloat4Float4(inV, out);
-            verifyResultsSignFloat4Float4(inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSignFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSign(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSignFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testSign() {
-        checkSignFloatFloat();
-        checkSignFloat2Float2();
-        checkSignFloat3Float3();
-        checkSignFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSign.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSign.rs
deleted file mode 100644
index 8f35b36..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSign.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testSignFloatFloat(float inV) {
-    return sign(inV);
-}
-
-float2 __attribute__((kernel)) testSignFloat2Float2(float2 inV) {
-    return sign(inV);
-}
-
-float3 __attribute__((kernel)) testSignFloat3Float3(float3 inV) {
-    return sign(inV);
-}
-
-float4 __attribute__((kernel)) testSignFloat4Float4(float4 inV) {
-    return sign(inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSignRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSignRelaxed.rs
deleted file mode 100644
index 1bc69fb..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSignRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestSign.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSin.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSin.java
deleted file mode 100644
index ae039e2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSin.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestSin extends RSBaseCompute {
-
-    private ScriptC_TestSin script;
-    private ScriptC_TestSinRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestSin(mRS);
-        scriptRelaxed = new ScriptC_TestSinRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkSinFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd3e99dcfa01359f9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testSinFloatFloat(in, out);
-            verifyResultsSinFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testSinFloatFloat(in, out);
-            verifyResultsSinFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSinFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9253f296dcfd528dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testSinFloat2Float2(in, out);
-            verifyResultsSinFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testSinFloat2Float2(in, out);
-            verifyResultsSinFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSinFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9253fd383c03e827l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testSinFloat3Float3(in, out);
-            verifyResultsSinFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testSinFloat3Float3(in, out);
-            verifyResultsSinFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSinFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x925407d99b0a7dc1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testSinFloat4Float4(in, out);
-            verifyResultsSinFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testSinFloat4Float4(in, out);
-            verifyResultsSinFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSin(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testSin() {
-        checkSinFloatFloat();
-        checkSinFloat2Float2();
-        checkSinFloat3Float3();
-        checkSinFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSin.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSin.rs
deleted file mode 100644
index 15e78ba..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSin.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testSinFloatFloat(float in) {
-    return sin(in);
-}
-
-float2 __attribute__((kernel)) testSinFloat2Float2(float2 in) {
-    return sin(in);
-}
-
-float3 __attribute__((kernel)) testSinFloat3Float3(float3 in) {
-    return sin(in);
-}
-
-float4 __attribute__((kernel)) testSinFloat4Float4(float4 in) {
-    return sin(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSinRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSinRelaxed.rs
deleted file mode 100644
index e9e49123..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSinRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestSin.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSincos.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSincos.java
deleted file mode 100644
index 60c6ef0..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSincos.java
+++ /dev/null
@@ -1,361 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestSincos extends RSBaseCompute {
-
-    private ScriptC_TestSincos script;
-    private ScriptC_TestSincosRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestSincos(mRS);
-        scriptRelaxed = new ScriptC_TestSincosRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inV;
-        public Target.Floaty outCosptr;
-        public Target.Floaty out;
-    }
-
-    private void checkSincosFloatFloatFloat() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb8748e13e46c48d4l, false);
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocOutCosptr(outCosptr);
-            script.forEach_testSincosFloatFloatFloat(inV, out);
-            verifyResultsSincosFloatFloatFloat(inV, outCosptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
-            scriptRelaxed.forEach_testSincosFloatFloatFloat(inV, out);
-            verifyResultsSincosFloatFloatFloat(inV, outCosptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSincosFloatFloatFloat(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOutCosptr = new float[INPUTSIZE * 1];
-        outCosptr.copyTo(arrayOutCosptr);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSincos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outCosptr: ");
-                    message.append(args.outCosptr.toString());
-                    message.append("\n");
-                    message.append("Actual   output outCosptr: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutCosptr[i * 1 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 1 + j]), arrayOutCosptr[i * 1 + j]));
-                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSincosFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSincosFloat2Float2Float2() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc85bab4e3e2fc77cl, false);
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocOutCosptr(outCosptr);
-            script.forEach_testSincosFloat2Float2Float2(inV, out);
-            verifyResultsSincosFloat2Float2Float2(inV, outCosptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
-            scriptRelaxed.forEach_testSincosFloat2Float2Float2(inV, out);
-            verifyResultsSincosFloat2Float2Float2(inV, outCosptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSincosFloat2Float2Float2(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOutCosptr = new float[INPUTSIZE * 2];
-        outCosptr.copyTo(arrayOutCosptr);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSincos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outCosptr: ");
-                    message.append(args.outCosptr.toString());
-                    message.append("\n");
-                    message.append("Actual   output outCosptr: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutCosptr[i * 2 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 2 + j]), arrayOutCosptr[i * 2 + j]));
-                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSincosFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSincosFloat3Float3Float3() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1cc0896e400dc91dl, false);
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocOutCosptr(outCosptr);
-            script.forEach_testSincosFloat3Float3Float3(inV, out);
-            verifyResultsSincosFloat3Float3Float3(inV, outCosptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
-            scriptRelaxed.forEach_testSincosFloat3Float3Float3(inV, out);
-            verifyResultsSincosFloat3Float3Float3(inV, outCosptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSincosFloat3Float3Float3(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOutCosptr = new float[INPUTSIZE * 4];
-        outCosptr.copyTo(arrayOutCosptr);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSincos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outCosptr: ");
-                    message.append(args.outCosptr.toString());
-                    message.append("\n");
-                    message.append("Actual   output outCosptr: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutCosptr[i * 4 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 4 + j]), arrayOutCosptr[i * 4 + j]));
-                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSincosFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSincosFloat4Float4Float4() {
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7125678e41ebcabel, false);
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocOutCosptr(outCosptr);
-            script.forEach_testSincosFloat4Float4Float4(inV, out);
-            verifyResultsSincosFloat4Float4Float4(inV, outCosptr, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation outCosptr = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocOutCosptr(outCosptr);
-            scriptRelaxed.forEach_testSincosFloat4Float4Float4(inV, out);
-            verifyResultsSincosFloat4Float4Float4(inV, outCosptr, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSincosFloat4Float4Float4(Allocation inV, Allocation outCosptr, Allocation out, boolean relaxed) {
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOutCosptr = new float[INPUTSIZE * 4];
-        outCosptr.copyTo(arrayOutCosptr);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSincos(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output outCosptr: ");
-                    message.append(args.outCosptr.toString());
-                    message.append("\n");
-                    message.append("Actual   output outCosptr: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOutCosptr[i * 4 + j], Float.floatToRawIntBits(arrayOutCosptr[i * 4 + j]), arrayOutCosptr[i * 4 + j]));
-                    if (!args.outCosptr.couldBe(arrayOutCosptr[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSincosFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testSincos() {
-        checkSincosFloatFloatFloat();
-        checkSincosFloat2Float2Float2();
-        checkSincosFloat3Float3Float3();
-        checkSincosFloat4Float4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSincos.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSincos.rs
deleted file mode 100644
index 82ff9cd..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSincos.rs
+++ /dev/null
@@ -1,50 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocOutCosptr;
-
-float __attribute__((kernel)) testSincosFloatFloatFloat(float inV, unsigned int x) {
-    float outCosptr = 0;
-    float out = sincos(inV, &outCosptr);
-    rsSetElementAt_float(gAllocOutCosptr, outCosptr, x);
-    return out;
-}
-
-float2 __attribute__((kernel)) testSincosFloat2Float2Float2(float2 inV, unsigned int x) {
-    float2 outCosptr = 0;
-    float2 out = sincos(inV, &outCosptr);
-    rsSetElementAt_float2(gAllocOutCosptr, outCosptr, x);
-    return out;
-}
-
-float3 __attribute__((kernel)) testSincosFloat3Float3Float3(float3 inV, unsigned int x) {
-    float3 outCosptr = 0;
-    float3 out = sincos(inV, &outCosptr);
-    rsSetElementAt_float3(gAllocOutCosptr, outCosptr, x);
-    return out;
-}
-
-float4 __attribute__((kernel)) testSincosFloat4Float4Float4(float4 inV, unsigned int x) {
-    float4 outCosptr = 0;
-    float4 out = sincos(inV, &outCosptr);
-    rsSetElementAt_float4(gAllocOutCosptr, outCosptr, x);
-    return out;
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSincosRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSincosRelaxed.rs
deleted file mode 100644
index 56cb9fc..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSincosRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestSincos.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSinh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSinh.java
deleted file mode 100644
index 1ebcba2..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSinh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestSinh extends RSBaseCompute {
-
-    private ScriptC_TestSinh script;
-    private ScriptC_TestSinhRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestSinh(mRS);
-        scriptRelaxed = new ScriptC_TestSinhRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkSinhFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x541c2eef0a5d2ff1l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testSinhFloatFloat(in, out);
-            verifyResultsSinhFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testSinhFloatFloat(in, out);
-            verifyResultsSinhFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinhFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSinhFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7f8e1e7d8c47bec5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testSinhFloat2Float2(in, out);
-            verifyResultsSinhFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testSinhFloat2Float2(in, out);
-            verifyResultsSinhFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinhFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSinhFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7f8e291eeb4e545fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testSinhFloat3Float3(in, out);
-            verifyResultsSinhFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testSinhFloat3Float3(in, out);
-            verifyResultsSinhFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinhFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSinhFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7f8e33c04a54e9f9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testSinhFloat4Float4(in, out);
-            verifyResultsSinhFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testSinhFloat4Float4(in, out);
-            verifyResultsSinhFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSinh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinhFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testSinh() {
-        checkSinhFloatFloat();
-        checkSinhFloat2Float2();
-        checkSinhFloat3Float3();
-        checkSinhFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSinh.rs
deleted file mode 100644
index bd94f0d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSinh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testSinhFloatFloat(float in) {
-    return sinh(in);
-}
-
-float2 __attribute__((kernel)) testSinhFloat2Float2(float2 in) {
-    return sinh(in);
-}
-
-float3 __attribute__((kernel)) testSinhFloat3Float3(float3 in) {
-    return sinh(in);
-}
-
-float4 __attribute__((kernel)) testSinhFloat4Float4(float4 in) {
-    return sinh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSinhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSinhRelaxed.rs
deleted file mode 100644
index 8ca3390..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSinhRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestSinh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSinpi.java
deleted file mode 100644
index 2df09b8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSinpi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestSinpi extends RSBaseCompute {
-
-    private ScriptC_TestSinpi script;
-    private ScriptC_TestSinpiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestSinpi(mRS);
-        scriptRelaxed = new ScriptC_TestSinpiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkSinpiFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x34cb59f49416da82l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testSinpiFloatFloat(in, out);
-            verifyResultsSinpiFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testSinpiFloatFloat(in, out);
-            verifyResultsSinpiFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinpiFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinpiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSinpiFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x50bbd97d4a48b00el, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testSinpiFloat2Float2(in, out);
-            verifyResultsSinpiFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testSinpiFloat2Float2(in, out);
-            verifyResultsSinpiFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinpiFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinpiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSinpiFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x50bbe41ea94f45a8l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testSinpiFloat3Float3(in, out);
-            verifyResultsSinpiFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testSinpiFloat3Float3(in, out);
-            verifyResultsSinpiFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinpiFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinpiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSinpiFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x50bbeec00855db42l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testSinpiFloat4Float4(in, out);
-            verifyResultsSinpiFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testSinpiFloat4Float4(in, out);
-            verifyResultsSinpiFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSinpiFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSinpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSinpiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testSinpi() {
-        checkSinpiFloatFloat();
-        checkSinpiFloat2Float2();
-        checkSinpiFloat3Float3();
-        checkSinpiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSinpi.rs
deleted file mode 100644
index 367040e..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSinpi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testSinpiFloatFloat(float in) {
-    return sinpi(in);
-}
-
-float2 __attribute__((kernel)) testSinpiFloat2Float2(float2 in) {
-    return sinpi(in);
-}
-
-float3 __attribute__((kernel)) testSinpiFloat3Float3(float3 in) {
-    return sinpi(in);
-}
-
-float4 __attribute__((kernel)) testSinpiFloat4Float4(float4 in) {
-    return sinpi(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSinpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSinpiRelaxed.rs
deleted file mode 100644
index dd611a7..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSinpiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestSinpi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/TestSqrt.java
deleted file mode 100644
index 4537c3d..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSqrt.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestSqrt extends RSBaseCompute {
-
-    private ScriptC_TestSqrt script;
-    private ScriptC_TestSqrtRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestSqrt(mRS);
-        scriptRelaxed = new ScriptC_TestSqrtRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkSqrtFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x940922bedb2c9271l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testSqrtFloatFloat(in, out);
-            verifyResultsSqrtFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testSqrtFloatFloat(in, out);
-            verifyResultsSqrtFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSqrtFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSqrtFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSqrtFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x35fb1678b6262d45l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testSqrtFloat2Float2(in, out);
-            verifyResultsSqrtFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testSqrtFloat2Float2(in, out);
-            verifyResultsSqrtFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSqrtFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSqrtFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSqrtFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x35fb211a152cc2dfl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testSqrtFloat3Float3(in, out);
-            verifyResultsSqrtFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testSqrtFloat3Float3(in, out);
-            verifyResultsSqrtFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSqrtFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSqrtFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkSqrtFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x35fb2bbb74335879l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testSqrtFloat4Float4(in, out);
-            verifyResultsSqrtFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testSqrtFloat4Float4(in, out);
-            verifyResultsSqrtFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsSqrtFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeSqrt(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkSqrtFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testSqrt() {
-        checkSqrtFloatFloat();
-        checkSqrtFloat2Float2();
-        checkSqrtFloat3Float3();
-        checkSqrtFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSqrt.rs
deleted file mode 100644
index f1c163b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSqrt.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testSqrtFloatFloat(float in) {
-    return sqrt(in);
-}
-
-float2 __attribute__((kernel)) testSqrtFloat2Float2(float2 in) {
-    return sqrt(in);
-}
-
-float3 __attribute__((kernel)) testSqrtFloat3Float3(float3 in) {
-    return sqrt(in);
-}
-
-float4 __attribute__((kernel)) testSqrtFloat4Float4(float4 in) {
-    return sqrt(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestSqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestSqrtRelaxed.rs
deleted file mode 100644
index ee5b6a8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestSqrtRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestSqrt.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestStep.java b/tests/tests/renderscript/src/android/renderscript/cts/TestStep.java
deleted file mode 100644
index dabfd45..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestStep.java
+++ /dev/null
@@ -1,745 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestStep extends RSBaseCompute {
-
-    private ScriptC_TestStep script;
-    private ScriptC_TestStepRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestStep(mRS);
-        scriptRelaxed = new ScriptC_TestStepRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloatFloat {
-        public float inEdge;
-        public float inV;
-        public Target.Floaty out;
-    }
-
-    private void checkStepFloatFloatFloat() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x598900c49184fbfel, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9aefccaa832f44e9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloatFloatFloat(inEdge, out);
-            verifyResultsStepFloatFloatFloat(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloatFloatFloat(inEdge, out);
-            verifyResultsStepFloatFloatFloat(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloatFloatFloat(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 1];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inEdge = arrayInEdge[i];
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloatFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkStepFloat2Float2Float2() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6efefa297df69504l, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x12eb000b8567f58bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloat2Float2Float2(inEdge, out);
-            verifyResultsStepFloat2Float2Float2(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2Float2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloat2Float2Float2(inEdge, out);
-            verifyResultsStepFloat2Float2Float2(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2Float2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloat2Float2Float2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 2];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                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);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloat2Float2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkStepFloat3Float3Float3() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9e548cd666a7a77l, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x674fde2b8745f72cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloat3Float3Float3(inEdge, out);
-            verifyResultsStepFloat3Float3Float3(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3Float3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloat3Float3Float3(inEdge, out);
-            verifyResultsStepFloat3Float3Float3(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3Float3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloat3Float3Float3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 4];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                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);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloat3Float3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkStepFloat4Float4Float4() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa4cb97714ede5feal, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbbb4bc4b8923f8cdl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloat4Float4Float4(inEdge, out);
-            verifyResultsStepFloat4Float4Float4(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4Float4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloat4Float4Float4(inEdge, out);
-            verifyResultsStepFloat4Float4Float4(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4Float4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloat4Float4Float4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 4];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                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);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloat4Float4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkStepFloat2FloatFloat2() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb0ac06c45b3d8b26l, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfa7d66f2b6d48a21l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloat2FloatFloat2(inEdge, out);
-            verifyResultsStepFloat2FloatFloat2(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2FloatFloat2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloat2FloatFloat2(inEdge, out);
-            verifyResultsStepFloat2FloatFloat2(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2FloatFloat2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloat2FloatFloat2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 2];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inEdge = arrayInEdge[i * 2 + j];
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloat2FloatFloat2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkStepFloat3FloatFloat3() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x304ed837c68f43fal, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4fcd1a0aa53f7e7dl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloat3FloatFloat3(inEdge, out);
-            verifyResultsStepFloat3FloatFloat3(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3FloatFloat3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloat3FloatFloat3(inEdge, out);
-            verifyResultsStepFloat3FloatFloat3(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3FloatFloat3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloat3FloatFloat3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 4];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inEdge = arrayInEdge[i * 4 + j];
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloat3FloatFloat3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkStepFloat4FloatFloat4() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xaff1a9ab31e0fccel, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa51ccd2293aa72d9l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloat4FloatFloat4(inEdge, out);
-            verifyResultsStepFloat4FloatFloat4(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4FloatFloat4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloat4FloatFloat4(inEdge, out);
-            verifyResultsStepFloat4FloatFloat4(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4FloatFloat4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloat4FloatFloat4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 4];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 1];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inEdge = arrayInEdge[i * 4 + j];
-                args.inV = arrayInV[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloat4FloatFloat4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkStepFloatFloat2Float2() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x70a0554e664b1852l, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdd7f0d444e2f7c5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloatFloat2Float2(inEdge, out);
-            verifyResultsStepFloatFloat2Float2(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloatFloat2Float2(inEdge, out);
-            verifyResultsStepFloatFloat2Float2(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloatFloat2Float2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 1];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 2];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inEdge = arrayInEdge[i];
-                args.inV = arrayInV[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloatFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkStepFloatFloat3Float3() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9b2d75ce91abcbccl, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdd9b9ef3afe18a3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloatFloat3Float3(inEdge, out);
-            verifyResultsStepFloatFloat3Float3(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloatFloat3Float3(inEdge, out);
-            verifyResultsStepFloatFloat3Float3(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloatFloat3Float3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 1];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inEdge = arrayInEdge[i];
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloatFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkStepFloatFloat4Float4() {
-        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc5ba964ebd0c7f46l, false);
-        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xddb830a31193981l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.set_gAllocInV(inV);
-            script.forEach_testStepFloatFloat4Float4(inEdge, out);
-            verifyResultsStepFloatFloat4Float4(inEdge, inV, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.set_gAllocInV(inV);
-            scriptRelaxed.forEach_testStepFloatFloat4Float4(inEdge, out);
-            verifyResultsStepFloatFloat4Float4(inEdge, inV, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsStepFloatFloat4Float4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
-        float[] arrayInEdge = new float[INPUTSIZE * 1];
-        inEdge.copyTo(arrayInEdge);
-        float[] arrayInV = new float[INPUTSIZE * 4];
-        inV.copyTo(arrayInV);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
-                args.inEdge = arrayInEdge[i];
-                args.inV = arrayInV[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeStep(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input inEdge: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inEdge, Float.floatToRawIntBits(args.inEdge), args.inEdge));
-                    message.append("\n");
-                    message.append("Input inV: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.inV, Float.floatToRawIntBits(args.inV), args.inV));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkStepFloatFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testStep() {
-        checkStepFloatFloatFloat();
-        checkStepFloat2Float2Float2();
-        checkStepFloat3Float3Float3();
-        checkStepFloat4Float4Float4();
-        checkStepFloat2FloatFloat2();
-        checkStepFloat3FloatFloat3();
-        checkStepFloat4FloatFloat4();
-        checkStepFloatFloat2Float2();
-        checkStepFloatFloat3Float3();
-        checkStepFloatFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestStep.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestStep.rs
deleted file mode 100644
index b815d52..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestStep.rs
+++ /dev/null
@@ -1,72 +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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-rs_allocation gAllocInV;
-
-float __attribute__((kernel)) testStepFloatFloatFloat(float inEdge, unsigned int x) {
-    float inV = rsGetElementAt_float(gAllocInV, x);
-    return step(inEdge, inV);
-}
-
-float2 __attribute__((kernel)) testStepFloat2Float2Float2(float2 inEdge, unsigned int x) {
-    float2 inV = rsGetElementAt_float2(gAllocInV, x);
-    return step(inEdge, inV);
-}
-
-float3 __attribute__((kernel)) testStepFloat3Float3Float3(float3 inEdge, unsigned int x) {
-    float3 inV = rsGetElementAt_float3(gAllocInV, x);
-    return step(inEdge, inV);
-}
-
-float4 __attribute__((kernel)) testStepFloat4Float4Float4(float4 inEdge, unsigned int x) {
-    float4 inV = rsGetElementAt_float4(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);
-}
-
-float3 __attribute__((kernel)) testStepFloat3FloatFloat3(float3 inEdge, unsigned int x) {
-    float inV = rsGetElementAt_float(gAllocInV, x);
-    return step(inEdge, inV);
-}
-
-float4 __attribute__((kernel)) testStepFloat4FloatFloat4(float4 inEdge, unsigned int x) {
-    float inV = rsGetElementAt_float(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);
-}
-
-float3 __attribute__((kernel)) testStepFloatFloat3Float3(float inEdge, unsigned int x) {
-    float3 inV = rsGetElementAt_float3(gAllocInV, x);
-    return step(inEdge, inV);
-}
-
-float4 __attribute__((kernel)) testStepFloatFloat4Float4(float inEdge, unsigned int x) {
-    float4 inV = rsGetElementAt_float4(gAllocInV, x);
-    return step(inEdge, inV);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestStepRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestStepRelaxed.rs
deleted file mode 100644
index b2bad68..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestStepRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestStep.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTan.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTan.java
deleted file mode 100644
index 29dae6f..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTan.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestTan extends RSBaseCompute {
-
-    private ScriptC_TestTan script;
-    private ScriptC_TestTanRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestTan(mRS);
-        scriptRelaxed = new ScriptC_TestTanRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkTanFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfb95a6a791c2b8eal, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testTanFloatFloat(in, out);
-            verifyResultsTanFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testTanFloatFloat(in, out);
-            verifyResultsTanFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTanFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1bdfd24778a20d36l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testTanFloat2Float2(in, out);
-            verifyResultsTanFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testTanFloat2Float2(in, out);
-            verifyResultsTanFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTanFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1bdfdce8d7a8a2d0l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testTanFloat3Float3(in, out);
-            verifyResultsTanFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testTanFloat3Float3(in, out);
-            verifyResultsTanFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTanFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1bdfe78a36af386al, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testTanFloat4Float4(in, out);
-            verifyResultsTanFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testTanFloat4Float4(in, out);
-            verifyResultsTanFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTan(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testTan() {
-        checkTanFloatFloat();
-        checkTanFloat2Float2();
-        checkTanFloat3Float3();
-        checkTanFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTan.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTan.rs
deleted file mode 100644
index 1024943..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTan.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testTanFloatFloat(float in) {
-    return tan(in);
-}
-
-float2 __attribute__((kernel)) testTanFloat2Float2(float2 in) {
-    return tan(in);
-}
-
-float3 __attribute__((kernel)) testTanFloat3Float3(float3 in) {
-    return tan(in);
-}
-
-float4 __attribute__((kernel)) testTanFloat4Float4(float4 in) {
-    return tan(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTanRelaxed.rs
deleted file mode 100644
index 9297033..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTanRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestTan.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTanh.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTanh.java
deleted file mode 100644
index e554ad8..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTanh.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestTanh extends RSBaseCompute {
-
-    private ScriptC_TestTanh script;
-    private ScriptC_TestTanhRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestTanh(mRS);
-        scriptRelaxed = new ScriptC_TestTanhRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkTanhFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfe01ab34a2d2226cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testTanhFloatFloat(in, out);
-            verifyResultsTanhFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testTanhFloatFloat(in, out);
-            verifyResultsTanhFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanhFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanhFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTanhFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9a0cb127b0f31928l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testTanhFloat2Float2(in, out);
-            verifyResultsTanhFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testTanhFloat2Float2(in, out);
-            verifyResultsTanhFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanhFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanhFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTanhFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9a0cbbc90ff9aec2l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testTanhFloat3Float3(in, out);
-            verifyResultsTanhFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testTanhFloat3Float3(in, out);
-            verifyResultsTanhFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanhFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanhFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTanhFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9a0cc66a6f00445cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testTanhFloat4Float4(in, out);
-            verifyResultsTanhFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testTanhFloat4Float4(in, out);
-            verifyResultsTanhFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanhFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTanh(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanhFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testTanh() {
-        checkTanhFloatFloat();
-        checkTanhFloat2Float2();
-        checkTanhFloat3Float3();
-        checkTanhFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTanh.rs
deleted file mode 100644
index a017c2b..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTanh.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testTanhFloatFloat(float in) {
-    return tanh(in);
-}
-
-float2 __attribute__((kernel)) testTanhFloat2Float2(float2 in) {
-    return tanh(in);
-}
-
-float3 __attribute__((kernel)) testTanhFloat3Float3(float3 in) {
-    return tanh(in);
-}
-
-float4 __attribute__((kernel)) testTanhFloat4Float4(float4 in) {
-    return tanh(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTanhRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTanhRelaxed.rs
deleted file mode 100644
index f99420a..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTanhRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestTanh.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTanpi.java
deleted file mode 100644
index 5e45440..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTanpi.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestTanpi extends RSBaseCompute {
-
-    private ScriptC_TestTanpi script;
-    private ScriptC_TestTanpiRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestTanpi(mRS);
-        scriptRelaxed = new ScriptC_TestTanpiRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkTanpiFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbe5739a52fbb952bl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testTanpiFloatFloat(in, out);
-            verifyResultsTanpiFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testTanpiFloatFloat(in, out);
-            verifyResultsTanpiFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanpiFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanpiFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTanpiFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc3fe7c117310deafl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testTanpiFloat2Float2(in, out);
-            verifyResultsTanpiFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testTanpiFloat2Float2(in, out);
-            verifyResultsTanpiFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanpiFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanpiFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTanpiFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc3fe86b2d2177449l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testTanpiFloat3Float3(in, out);
-            verifyResultsTanpiFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testTanpiFloat3Float3(in, out);
-            verifyResultsTanpiFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanpiFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanpiFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTanpiFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc3fe9154311e09e3l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testTanpiFloat4Float4(in, out);
-            verifyResultsTanpiFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testTanpiFloat4Float4(in, out);
-            verifyResultsTanpiFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTanpiFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTanpi(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTanpiFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testTanpi() {
-        checkTanpiFloatFloat();
-        checkTanpiFloat2Float2();
-        checkTanpiFloat3Float3();
-        checkTanpiFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTanpi.rs
deleted file mode 100644
index 883a571..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTanpi.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testTanpiFloatFloat(float in) {
-    return tanpi(in);
-}
-
-float2 __attribute__((kernel)) testTanpiFloat2Float2(float2 in) {
-    return tanpi(in);
-}
-
-float3 __attribute__((kernel)) testTanpiFloat3Float3(float3 in) {
-    return tanpi(in);
-}
-
-float4 __attribute__((kernel)) testTanpiFloat4Float4(float4 in) {
-    return tanpi(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTanpiRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTanpiRelaxed.rs
deleted file mode 100644
index 3fc9d28..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTanpiRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestTanpi.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTgamma.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTgamma.java
deleted file mode 100644
index c7bb7b5..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTgamma.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestTgamma extends RSBaseCompute {
-
-    private ScriptC_TestTgamma script;
-    private ScriptC_TestTgammaRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestTgamma(mRS);
-        scriptRelaxed = new ScriptC_TestTgammaRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkTgammaFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe45f5203be15b490l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testTgammaFloatFloat(in, out);
-            verifyResultsTgammaFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testTgammaFloatFloat(in, out);
-            verifyResultsTgammaFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTgammaFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTgamma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTgammaFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTgammaFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x74767f039bfd9f2cl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testTgammaFloat2Float2(in, out);
-            verifyResultsTgammaFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testTgammaFloat2Float2(in, out);
-            verifyResultsTgammaFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTgammaFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTgamma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTgammaFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTgammaFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x747689a4fb0434c6l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testTgammaFloat3Float3(in, out);
-            verifyResultsTgammaFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testTgammaFloat3Float3(in, out);
-            verifyResultsTgammaFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTgammaFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTgamma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTgammaFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTgammaFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x747694465a0aca60l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testTgammaFloat4Float4(in, out);
-            verifyResultsTgammaFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testTgammaFloat4Float4(in, out);
-            verifyResultsTgammaFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTgammaFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTgamma(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTgammaFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testTgamma() {
-        checkTgammaFloatFloat();
-        checkTgammaFloat2Float2();
-        checkTgammaFloat3Float3();
-        checkTgammaFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTgamma.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTgamma.rs
deleted file mode 100644
index 7dae4cf..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTgamma.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testTgammaFloatFloat(float in) {
-    return tgamma(in);
-}
-
-float2 __attribute__((kernel)) testTgammaFloat2Float2(float2 in) {
-    return tgamma(in);
-}
-
-float3 __attribute__((kernel)) testTgammaFloat3Float3(float3 in) {
-    return tgamma(in);
-}
-
-float4 __attribute__((kernel)) testTgammaFloat4Float4(float4 in) {
-    return tgamma(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTgammaRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTgammaRelaxed.rs
deleted file mode 100644
index 7d57ba0..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTgammaRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestTgamma.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTrunc.java b/tests/tests/renderscript/src/android/renderscript/cts/TestTrunc.java
deleted file mode 100644
index 0657844..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTrunc.java
+++ /dev/null
@@ -1,284 +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.
- */
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-package android.renderscript.cts;
-
-import android.renderscript.Allocation;
-import android.renderscript.RSRuntimeException;
-import android.renderscript.Element;
-
-public class TestTrunc extends RSBaseCompute {
-
-    private ScriptC_TestTrunc script;
-    private ScriptC_TestTruncRelaxed scriptRelaxed;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        script = new ScriptC_TestTrunc(mRS);
-        scriptRelaxed = new ScriptC_TestTruncRelaxed(mRS);
-    }
-
-    public class ArgumentsFloatFloat {
-        public float in;
-        public Target.Floaty out;
-    }
-
-    private void checkTruncFloatFloat() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6361d71a4dcff881l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            script.forEach_testTruncFloatFloat(in, out);
-            verifyResultsTruncFloatFloat(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloatFloat: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
-            scriptRelaxed.forEach_testTruncFloatFloat(in, out);
-            verifyResultsTruncFloatFloat(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloatFloat: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTruncFloatFloat(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 1];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 1];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 1 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTrunc(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 1 + j], Float.floatToRawIntBits(arrayOut[i * 1 + j]), arrayOut[i * 1 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 1 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTruncFloatFloat" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTruncFloat2Float2() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xcda9bef7b45256d5l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            script.forEach_testTruncFloat2Float2(in, out);
-            verifyResultsTruncFloat2Float2(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat2Float2: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
-            scriptRelaxed.forEach_testTruncFloat2Float2(in, out);
-            verifyResultsTruncFloat2Float2(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat2Float2: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTruncFloat2Float2(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 2];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 2];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 2 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 2 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTrunc(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 2 + j], Float.floatToRawIntBits(arrayOut[i * 2 + j]), arrayOut[i * 2 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 2 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTruncFloat2Float2" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTruncFloat3Float3() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcda9c9991358ec6fl, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            script.forEach_testTruncFloat3Float3(in, out);
-            verifyResultsTruncFloat3Float3(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat3Float3: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
-            scriptRelaxed.forEach_testTruncFloat3Float3(in, out);
-            verifyResultsTruncFloat3Float3(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat3Float3: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTruncFloat3Float3(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 3 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTrunc(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTruncFloat3Float3" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    private void checkTruncFloat4Float4() {
-        Allocation in = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xcda9d43a725f8209l, false);
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            script.forEach_testTruncFloat4Float4(in, out);
-            verifyResultsTruncFloat4Float4(in, out, false);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat4Float4: " + e.toString());
-        }
-        try {
-            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
-            scriptRelaxed.forEach_testTruncFloat4Float4(in, out);
-            verifyResultsTruncFloat4Float4(in, out, true);
-        } catch (Exception e) {
-            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat4Float4: " + e.toString());
-        }
-    }
-
-    private void verifyResultsTruncFloat4Float4(Allocation in, Allocation out, boolean relaxed) {
-        float[] arrayIn = new float[INPUTSIZE * 4];
-        in.copyTo(arrayIn);
-        float[] arrayOut = new float[INPUTSIZE * 4];
-        out.copyTo(arrayOut);
-        for (int i = 0; i < INPUTSIZE; i++) {
-            for (int j = 0; j < 4 ; j++) {
-                // Extract the inputs.
-                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
-                args.in = arrayIn[i * 4 + j];
-                // Figure out what the outputs should have been.
-                Target target = new Target(relaxed);
-                CoreMathVerifier.computeTrunc(args, target);
-                // Validate the outputs.
-                boolean valid = true;
-                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                    valid = false;
-                }
-                if (!valid) {
-                    StringBuilder message = new StringBuilder();
-                    message.append("Input in: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            args.in, Float.floatToRawIntBits(args.in), args.in));
-                    message.append("\n");
-                    message.append("Expected output out: ");
-                    message.append(args.out.toString());
-                    message.append("\n");
-                    message.append("Actual   output out: ");
-                    message.append(String.format("%14.8g {%8x} %15a",
-                            arrayOut[i * 4 + j], Float.floatToRawIntBits(arrayOut[i * 4 + j]), arrayOut[i * 4 + j]));
-                    if (!args.out.couldBe(arrayOut[i * 4 + j])) {
-                        message.append(" FAIL");
-                    }
-                    message.append("\n");
-                    assertTrue("Incorrect output for checkTruncFloat4Float4" +
-                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
-                }
-            }
-        }
-    }
-
-    public void testTrunc() {
-        checkTruncFloatFloat();
-        checkTruncFloat2Float2();
-        checkTruncFloat3Float3();
-        checkTruncFloat4Float4();
-    }
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTrunc.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTrunc.rs
deleted file mode 100644
index 2422ae4..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTrunc.rs
+++ /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.
- */
-
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
-
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
-
-float __attribute__((kernel)) testTruncFloatFloat(float in) {
-    return trunc(in);
-}
-
-float2 __attribute__((kernel)) testTruncFloat2Float2(float2 in) {
-    return trunc(in);
-}
-
-float3 __attribute__((kernel)) testTruncFloat3Float3(float3 in) {
-    return trunc(in);
-}
-
-float4 __attribute__((kernel)) testTruncFloat4Float4(float4 in) {
-    return trunc(in);
-}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestTruncRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/TestTruncRelaxed.rs
deleted file mode 100644
index b365243..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestTruncRelaxed.rs
+++ /dev/null
@@ -1,20 +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 "TestTrunc.rs"
-#pragma rs_fp_relaxed
-// Don't edit this file!  It is auto-generated by frameworks/rs/api/gen_runtime.
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TestVLoad.java b/tests/tests/renderscript/src/android/renderscript/cts/TestVLoad.java
deleted file mode 100644
index a2d22d9..0000000
--- a/tests/tests/renderscript/src/android/renderscript/cts/TestVLoad.java
+++ /dev/null
@@ -1,371 +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.renderscript.cts;
-
-import android.renderscript.*;
-
-public class TestVLoad extends RSBaseCompute {
-
-    private ScriptC_vload script;
-    private ScriptC_vload_relaxed scriptRelaxed;
-    Allocation walkAlloc;
-    Allocation inAlloc;
-    Allocation outAlloc;
-    private static java.util.Random random = new java.util.Random();
-
-    final int w = 253;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        random.setSeed(10);
-        script = new ScriptC_vload(mRS);
-        scriptRelaxed = new ScriptC_vload_relaxed(mRS);
-    }
-
-
-
-    protected void createWalk() {
-        int tmp[] = new int[w];
-        boolean b[] = new boolean[w];
-        int toCopy = w;
-        int i = 0;
-
-        while (toCopy > 0) {
-            int x = random.nextInt(w);
-
-            //android.util.Log.v("rs", "x " + x + ", y " + y + ", toCopy " + toCopy);
-            while ((x < w) && b[x]) {
-                x++;
-                if (x >= w) {
-                    x = 0;
-                }
-            }
-
-            int maxsize = 1;
-            b[x] = true;
-            if ((x+1 < w) && !b[x+1]) {
-                maxsize ++;
-                b[x+1] = true;
-                if ((x+2 < w) && !b[x+2]) {
-                    maxsize ++;
-                    b[x+2] = true;
-                    if ((x+3 < w) && !b[x+3]) {
-                        maxsize ++;
-                        b[x+3] = true;
-                    }
-                }
-            }
-
-            toCopy -= maxsize;
-            tmp[i] = x | (maxsize << 16);
-            android.util.Log.v("rs", "x " + x + ", vec " + maxsize);
-            i++;
-        }
-
-        walkAlloc = Allocation.createSized(mRS, Element.I32(mRS), i);
-        walkAlloc.copy1DRangeFrom(0, i, tmp);
-    }
-
-    private void testSetup(Type t) {
-        createWalk();
-
-        inAlloc = Allocation.createTyped(mRS, t);
-        outAlloc = Allocation.createTyped(mRS, t);
-        script.set_gAllocIn(inAlloc);
-        script.set_gAllocOut(outAlloc);
-        scriptRelaxed.set_gAllocIn(inAlloc);
-        scriptRelaxed.set_gAllocOut(outAlloc);
-    }
-
-    private void verify(byte[] a1, byte[] a2, String s) {
-        outAlloc.copyTo(a2);
-        for (int i=0; i < w; i++) {
-            if (a1[i] != a2[i]) {
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        outAlloc.copyFrom(a2);
-    }
-
-    private void verify(short[] a1, short[] a2, String s) {
-        outAlloc.copyTo(a2);
-        for (int i=0; i < w; i++) {
-            if (a1[i] != a2[i]) {
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        outAlloc.copyFrom(a2);
-    }
-
-    private void verify(int[] a1, int[] a2, String s) {
-        outAlloc.copyTo(a2);
-        for (int i=0; i < w; i++) {
-            if (a1[i] != a2[i]) {
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        outAlloc.copyFrom(a2);
-    }
-
-    private void verify(long[] a1, long[] a2, String s) {
-        outAlloc.copyTo(a2);
-        for (int i=0; i < w; i++) {
-            if (a1[i] != a2[i]) {
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        outAlloc.copyFrom(a2);
-    }
-
-    private void verify(float[] a1, float[] a2, String s) {
-        outAlloc.copyTo(a2);
-        for (int i=0; i < w; i++) {
-            if (a1[i] != a2[i]) {
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        outAlloc.copyFrom(a2);
-    }
-
-    private void verify(double[] a1, double[] a2, String s) {
-        outAlloc.copyTo(a2);
-        for (int i=0; i < w; i++) {
-            if (a1[i] != a2[i]) {
-                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
-            }
-            a2[i] = 0;
-        }
-        outAlloc.copyFrom(a2);
-    }
-
-    private byte[] randomByteArray(int len) {
-        byte t[] = new byte[len];
-        random.nextBytes(t);
-        inAlloc.copyFrom(t);
-        return t;
-    }
-
-    private short[] randomShortArray(int len) {
-        short t[] = new short[len];
-        for (int i = 0; i < t.length; i++) {
-            t[i] = (short)(random.nextInt() & 0xffff);
-        }
-        inAlloc.copyFrom(t);
-        return t;
-    }
-
-    private int[] randomIntArray(int len) {
-        int t[] = new int[len];
-        for (int i = 0; i < t.length; i++) {
-            t[i] = random.nextInt();
-        }
-        inAlloc.copyFrom(t);
-        return t;
-    }
-
-    private long[] randomLongArray(int len) {
-        long t[] = new long[len];
-        for (int i = 0; i < t.length; i++) {
-            t[i] = random.nextLong();
-        }
-        inAlloc.copyFrom(t);
-        return t;
-    }
-
-    public void testVload_char() {
-        testSetup(Type.createX(mRS, Element.I8(mRS), w));
-        byte tmp[] = randomByteArray(w);
-        byte tmp2[] = new byte[w];
-        script.forEach_copy2d_char(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch char: ");
-    }
-
-    public void testVload_uchar() {
-        testSetup(Type.createX(mRS, Element.I8(mRS), w));
-        byte tmp[] = randomByteArray(w);
-        byte tmp2[] = new byte[w];
-        script.forEach_copy2d_uchar(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch uchar: ");
-    }
-
-    public void testVload_char_relaxed() {
-        testSetup(Type.createX(mRS, Element.I8(mRS), w));
-        byte tmp[] = randomByteArray(w);
-        byte tmp2[] = new byte[w];
-        scriptRelaxed.forEach_copy2d_char(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch relaxed char: ");
-    }
-
-    public void testVload_uchar_relaxed() {
-        testSetup(Type.createX(mRS, Element.I8(mRS), w));
-        byte tmp[] = randomByteArray(w);
-        byte tmp2[] = new byte[w];
-        scriptRelaxed.forEach_copy2d_uchar(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch relaxed uchar: ");
-    }
-
-    public void testVload_short() {
-        testSetup(Type.createX(mRS, Element.I16(mRS), w));
-        short tmp[] = randomShortArray(w);
-        short tmp2[] = new short[w];
-        script.forEach_copy2d_short(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch short: ");
-    }
-
-    public void testVload_ushort() {
-        testSetup(Type.createX(mRS, Element.I16(mRS), w));
-        short tmp[] = randomShortArray(w);
-        short tmp2[] = new short[w];
-        script.forEach_copy2d_ushort(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch ushort: ");
-    }
-
-    public void testVload_short_relaxed() {
-        testSetup(Type.createX(mRS, Element.I16(mRS), w));
-        short tmp[] = randomShortArray(w);
-        short tmp2[] = new short[w];
-        scriptRelaxed.forEach_copy2d_short(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch relaxed short: ");
-    }
-
-    public void testVload_ushort_relaxed() {
-        testSetup(Type.createX(mRS, Element.I16(mRS), w));
-        short tmp[] = randomShortArray(w);
-        short tmp2[] = new short[w];
-        scriptRelaxed.forEach_copy2d_ushort(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch ushort: ");
-    }
-
-    public void testVload_int() {
-        testSetup(Type.createX(mRS, Element.I32(mRS), w));
-        int tmp[] = randomIntArray(w);
-        int tmp2[] = new int[w];
-        script.forEach_copy2d_int(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch int: ");
-    }
-
-    public void testVload_uint() {
-        testSetup(Type.createX(mRS, Element.I32(mRS), w));
-        int tmp[] = randomIntArray(w);
-        int tmp2[] = new int[w];
-        script.forEach_copy2d_uint(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch uint: ");
-    }
-
-    public void testVload_int_relaxed() {
-        testSetup(Type.createX(mRS, Element.I32(mRS), w));
-        int tmp[] = randomIntArray(w);
-        int tmp2[] = new int[w];
-        scriptRelaxed.forEach_copy2d_int(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch relaxed int: ");
-    }
-
-    public void testVload_uint_relaxed() {
-        testSetup(Type.createX(mRS, Element.I32(mRS), w));
-        int tmp[] = randomIntArray(w);
-        int tmp2[] = new int[w];
-        scriptRelaxed.forEach_copy2d_uint(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch uint: ");
-    }
-
-    public void testVload_long() {
-        testSetup(Type.createX(mRS, Element.I64(mRS), w));
-        long tmp[] = randomLongArray(w);
-        long tmp2[] = new long[w];
-        script.forEach_copy2d_long(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch long: ");
-    }
-
-    public void testVload_ulong() {
-        testSetup(Type.createX(mRS, Element.I64(mRS), w));
-        long tmp[] = randomLongArray(w);
-        long tmp2[] = new long[w];
-        script.forEach_copy2d_ulong(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch ulong: ");
-    }
-    public void testVload_long_relaxed() {
-        testSetup(Type.createX(mRS, Element.I64(mRS), w));
-        long tmp[] = randomLongArray(w);
-        long tmp2[] = new long[w];
-        scriptRelaxed.forEach_copy2d_long(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch relaxed long: ");
-    }
-    public void testVload_ulong_relaxed() {
-        testSetup(Type.createX(mRS, Element.I64(mRS), w));
-        long tmp[] = randomLongArray(w);
-        long tmp2[] = new long[w];
-        scriptRelaxed.forEach_copy2d_ulong(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch ulong: ");
-    }
-
-    public void testVload_float() {
-        testSetup(Type.createX(mRS, Element.F32(mRS), w));
-        float tmp[] = new float[w];
-        float tmp2[] = new float[w];
-        for (int i=0; i < w; i++) {
-            tmp[i] = random.nextFloat();
-        }
-        inAlloc.copyFrom(tmp);
-        script.forEach_copy2d_float(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch float: ");
-    }
-
-    public void testVload_float_relaxed() {
-        testSetup(Type.createX(mRS, Element.F32(mRS), w));
-        float tmp[] = new float[w];
-        float tmp2[] = new float[w];
-        for (int i=0; i < w; i++) {
-            tmp[i] = random.nextFloat();
-        }
-        inAlloc.copyFrom(tmp);
-        scriptRelaxed.forEach_copy2d_float(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch relaxed float: ");
-    }
-
-    public void testVload_double() {
-        testSetup(Type.createX(mRS, Element.F64(mRS), w));
-        double tmp[] = new double[w];
-        double tmp2[] = new double[w];
-        for (int i=0; i < w; i++) {
-            tmp[i] = random.nextDouble();
-        }
-        inAlloc.copyFrom(tmp);
-        script.forEach_copy2d_double(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch double: ");
-    }
-
-    public void testVload_double_relaxed() {
-        testSetup(Type.createX(mRS, Element.F64(mRS), w));
-        double tmp[] = new double[w];
-        double tmp2[] = new double[w];
-        for (int i=0; i < w; i++) {
-            tmp[i] = random.nextDouble();
-        }
-        inAlloc.copyFrom(tmp);
-        scriptRelaxed.forEach_copy2d_double(walkAlloc);
-        verify(tmp, tmp2, "Data mismatch relaxed double: ");
-    }
-
-}
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/ThunkerCreateTest.java b/tests/tests/renderscript/src/android/renderscript/cts/ThunkerCreateTest.java
new file mode 100644
index 0000000..735519c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/ThunkerCreateTest.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 android.renderscript.cts;
+
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+import android.content.Context;
+import android.renderscript.RSRuntimeException;
+
+public class ThunkerCreateTest extends RSBase {
+
+    public void testCreateReflection() {
+        int sdkVersion = mCtx.getApplicationInfo().targetSdkVersion;
+
+        try {
+            Class<?> javaRS = Class.forName("android.renderscript.RenderScript");
+            Class[] signature = {Context.class, Integer.TYPE};
+            Object[] args = {mCtx, new Integer(sdkVersion)};
+            Method create = javaRS.getDeclaredMethod("create", signature);
+
+            assertTrue (create.invoke(null, args) != null);
+        }
+        catch (Exception e) {
+            throw new RSRuntimeException("Failure to create platform RenderScript context");
+        }
+
+    }
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/TypeTest.java b/tests/tests/renderscript/src/android/renderscript/cts/TypeTest.java
index 13d4977..abb532d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/TypeTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/TypeTest.java
@@ -143,6 +143,14 @@
         assertTrue(t.getY() == 4);
     }
 
+    public void testGetYuv() {
+        Type.Builder b = new Type.Builder(mRS, Element.F32(mRS));
+        b.setX(64).setY(64);
+        b.setYuvFormat(android.graphics.ImageFormat.YV12);
+        Type t = b.create();
+        assertTrue(t.getYuv() == android.graphics.ImageFormat.YV12);
+    }
+
     public void testGetZ() {
         Type.Builder b = new Type.Builder(mRS, Element.F32(mRS));
         b.setX(3).setY(4);
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/VLoadTest.java b/tests/tests/renderscript/src/android/renderscript/cts/VLoadTest.java
new file mode 100644
index 0000000..0b30bde
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/VLoadTest.java
@@ -0,0 +1,370 @@
+ /*
+ * 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.renderscript.cts;
+
+import android.renderscript.*;
+
+public class VLoadTest extends RSBaseCompute {
+
+    private ScriptC_vload script;
+    private ScriptC_vload_relaxed scriptRelaxed;
+    Allocation walkAlloc;
+    Allocation inAlloc;
+    Allocation outAlloc;
+    private static java.util.Random random = new java.util.Random();
+
+    final int w = 253;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        random.setSeed(10);
+        script = new ScriptC_vload(mRS);
+        scriptRelaxed = new ScriptC_vload_relaxed(mRS);
+    }
+
+
+
+    protected void createWalk() {
+        int tmp[] = new int[w];
+        boolean b[] = new boolean[w];
+        int toCopy = w;
+        int i = 0;
+
+        while (toCopy > 0) {
+            int x = random.nextInt(w);
+
+            //android.util.Log.v("rs", "x " + x + ", y " + y + ", toCopy " + toCopy);
+            while ((x < w) && b[x]) {
+                x++;
+                if (x >= w) {
+                    x = 0;
+                }
+            }
+
+            int maxsize = 1;
+            b[x] = true;
+            if ((x+1 < w) && !b[x+1]) {
+                maxsize ++;
+                b[x+1] = true;
+                if ((x+2 < w) && !b[x+2]) {
+                    maxsize ++;
+                    b[x+2] = true;
+                    if ((x+3 < w) && !b[x+3]) {
+                        maxsize ++;
+                        b[x+3] = true;
+                    }
+                }
+            }
+
+            toCopy -= maxsize;
+            tmp[i] = x | (maxsize << 16);
+            android.util.Log.v("rs", "x " + x + ", vec " + maxsize);
+            i++;
+        }
+
+        walkAlloc = Allocation.createSized(mRS, Element.I32(mRS), i);
+        walkAlloc.copy1DRangeFrom(0, i, tmp);
+    }
+
+    private void testSetup(Type t) {
+        createWalk();
+
+        inAlloc = Allocation.createTyped(mRS, t);
+        outAlloc = Allocation.createTyped(mRS, t);
+        script.set_gAllocIn(inAlloc);
+        script.set_gAllocOut(outAlloc);
+        scriptRelaxed.set_gAllocIn(inAlloc);
+        scriptRelaxed.set_gAllocOut(outAlloc);
+    }
+
+    private void verify(byte[] a1, byte[] a2, String s) {
+        outAlloc.copyTo(a2);
+        for (int i=0; i < w; i++) {
+            if (a1[i] != a2[i]) {
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        outAlloc.copyFrom(a2);
+    }
+
+    private void verify(short[] a1, short[] a2, String s) {
+        outAlloc.copyTo(a2);
+        for (int i=0; i < w; i++) {
+            if (a1[i] != a2[i]) {
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        outAlloc.copyFrom(a2);
+    }
+
+    private void verify(int[] a1, int[] a2, String s) {
+        outAlloc.copyTo(a2);
+        for (int i=0; i < w; i++) {
+            if (a1[i] != a2[i]) {
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        outAlloc.copyFrom(a2);
+    }
+
+    private void verify(long[] a1, long[] a2, String s) {
+        outAlloc.copyTo(a2);
+        for (int i=0; i < w; i++) {
+            if (a1[i] != a2[i]) {
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        outAlloc.copyFrom(a2);
+    }
+
+    private void verify(float[] a1, float[] a2, String s) {
+        outAlloc.copyTo(a2);
+        for (int i=0; i < w; i++) {
+            if (a1[i] != a2[i]) {
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        outAlloc.copyFrom(a2);
+    }
+
+    private void verify(double[] a1, double[] a2, String s) {
+        outAlloc.copyTo(a2);
+        for (int i=0; i < w; i++) {
+            if (a1[i] != a2[i]) {
+                throw new RSRuntimeException(s + a1[i] + ", " + a2[i] + ", at " + i);
+            }
+            a2[i] = 0;
+        }
+        outAlloc.copyFrom(a2);
+    }
+
+    private byte[] randomByteArray(int len) {
+        byte t[] = new byte[len];
+        random.nextBytes(t);
+        inAlloc.copyFrom(t);
+        return t;
+    }
+
+    private short[] randomShortArray(int len) {
+        short t[] = new short[len];
+        for (int i = 0; i < t.length; i++) {
+            t[i] = (short)(random.nextInt() & 0xffff);
+        }
+        inAlloc.copyFrom(t);
+        return t;
+    }
+
+    private int[] randomIntArray(int len) {
+        int t[] = new int[len];
+        for (int i = 0; i < t.length; i++) {
+            t[i] = random.nextInt();
+        }
+        inAlloc.copyFrom(t);
+        return t;
+    }
+
+    private long[] randomLongArray(int len) {
+        long t[] = new long[len];
+        for (int i = 0; i < t.length; i++) {
+            t[i] = random.nextLong();
+        }
+        inAlloc.copyFrom(t);
+        return t;
+    }
+
+    public void testVload_char() {
+        testSetup(Type.createX(mRS, Element.I8(mRS), w));
+        byte tmp[] = randomByteArray(w);
+        byte tmp2[] = new byte[w];
+        script.forEach_copy2d_char(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch char: ");
+    }
+
+    public void testVload_uchar() {
+        testSetup(Type.createX(mRS, Element.I8(mRS), w));
+        byte tmp[] = randomByteArray(w);
+        byte tmp2[] = new byte[w];
+        script.forEach_copy2d_uchar(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch uchar: ");
+    }
+
+    public void testVload_char_relaxed() {
+        testSetup(Type.createX(mRS, Element.I8(mRS), w));
+        byte tmp[] = randomByteArray(w);
+        byte tmp2[] = new byte[w];
+        scriptRelaxed.forEach_copy2d_char(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch relaxed char: ");
+    }
+
+    public void testVload_uchar_relaxed() {
+        testSetup(Type.createX(mRS, Element.I8(mRS), w));
+        byte tmp[] = randomByteArray(w);
+        byte tmp2[] = new byte[w];
+        scriptRelaxed.forEach_copy2d_uchar(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch relaxed uchar: ");
+    }
+
+    public void testVload_short() {
+        testSetup(Type.createX(mRS, Element.I16(mRS), w));
+        short tmp[] = randomShortArray(w);
+        short tmp2[] = new short[w];
+        script.forEach_copy2d_short(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch short: ");
+    }
+
+    public void testVload_ushort() {
+        testSetup(Type.createX(mRS, Element.I16(mRS), w));
+        short tmp[] = randomShortArray(w);
+        short tmp2[] = new short[w];
+        script.forEach_copy2d_ushort(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch ushort: ");
+    }
+
+    public void testVload_short_relaxed() {
+        testSetup(Type.createX(mRS, Element.I16(mRS), w));
+        short tmp[] = randomShortArray(w);
+        short tmp2[] = new short[w];
+        scriptRelaxed.forEach_copy2d_short(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch relaxed short: ");
+    }
+
+    public void testVload_ushort_relaxed() {
+        testSetup(Type.createX(mRS, Element.I16(mRS), w));
+        short tmp[] = randomShortArray(w);
+        short tmp2[] = new short[w];
+        scriptRelaxed.forEach_copy2d_ushort(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch ushort: ");
+    }
+
+    public void testVload_int() {
+        testSetup(Type.createX(mRS, Element.I32(mRS), w));
+        int tmp[] = randomIntArray(w);
+        int tmp2[] = new int[w];
+        script.forEach_copy2d_int(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch int: ");
+    }
+
+    public void testVload_uint() {
+        testSetup(Type.createX(mRS, Element.I32(mRS), w));
+        int tmp[] = randomIntArray(w);
+        int tmp2[] = new int[w];
+        script.forEach_copy2d_uint(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch uint: ");
+    }
+
+    public void testVload_int_relaxed() {
+        testSetup(Type.createX(mRS, Element.I32(mRS), w));
+        int tmp[] = randomIntArray(w);
+        int tmp2[] = new int[w];
+        scriptRelaxed.forEach_copy2d_int(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch relaxed int: ");
+    }
+
+    public void testVload_uint_relaxed() {
+        testSetup(Type.createX(mRS, Element.I32(mRS), w));
+        int tmp[] = randomIntArray(w);
+        int tmp2[] = new int[w];
+        scriptRelaxed.forEach_copy2d_uint(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch uint: ");
+    }
+
+    public void testVload_long() {
+        testSetup(Type.createX(mRS, Element.I64(mRS), w));
+        long tmp[] = randomLongArray(w);
+        long tmp2[] = new long[w];
+        script.forEach_copy2d_long(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch long: ");
+    }
+
+    public void testVload_ulong() {
+        testSetup(Type.createX(mRS, Element.I64(mRS), w));
+        long tmp[] = randomLongArray(w);
+        long tmp2[] = new long[w];
+        script.forEach_copy2d_ulong(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch ulong: ");
+    }
+    public void testVload_long_relaxed() {
+        testSetup(Type.createX(mRS, Element.I64(mRS), w));
+        long tmp[] = randomLongArray(w);
+        long tmp2[] = new long[w];
+        scriptRelaxed.forEach_copy2d_long(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch relaxed long: ");
+    }
+    public void testVload_ulong_relaxed() {
+        testSetup(Type.createX(mRS, Element.I64(mRS), w));
+        long tmp[] = randomLongArray(w);
+        long tmp2[] = new long[w];
+        scriptRelaxed.forEach_copy2d_ulong(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch ulong: ");
+    }
+
+    public void testVload_float() {
+        testSetup(Type.createX(mRS, Element.F32(mRS), w));
+        float tmp[] = new float[w];
+        float tmp2[] = new float[w];
+        for (int i=0; i < w; i++) {
+            tmp[i] = random.nextFloat();
+        }
+        inAlloc.copyFrom(tmp);
+        script.forEach_copy2d_float(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch float: ");
+    }
+
+    public void testVload_float_relaxed() {
+        testSetup(Type.createX(mRS, Element.F32(mRS), w));
+        float tmp[] = new float[w];
+        float tmp2[] = new float[w];
+        for (int i=0; i < w; i++) {
+            tmp[i] = random.nextFloat();
+        }
+        inAlloc.copyFrom(tmp);
+        scriptRelaxed.forEach_copy2d_float(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch relaxed float: ");
+    }
+
+    public void testVload_double() {
+        testSetup(Type.createX(mRS, Element.F64(mRS), w));
+        double tmp[] = new double[w];
+        double tmp2[] = new double[w];
+        for (int i=0; i < w; i++) {
+            tmp[i] = random.nextDouble();
+        }
+        inAlloc.copyFrom(tmp);
+        script.forEach_copy2d_double(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch double: ");
+    }
+
+    public void testVload_double_relaxed() {
+        testSetup(Type.createX(mRS, Element.F64(mRS), w));
+        double tmp[] = new double[w];
+        double tmp2[] = new double[w];
+        for (int i=0; i < w; i++) {
+            tmp[i] = random.nextDouble();
+        }
+        inAlloc.copyFrom(tmp);
+        scriptRelaxed.forEach_copy2d_double(walkAlloc);
+        verify(tmp, tmp2, "Data mismatch relaxed double: ");
+    }
+
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/YuvTest.java b/tests/tests/renderscript/src/android/renderscript/cts/YuvTest.java
index 21f4417..e162d1d 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/YuvTest.java
+++ b/tests/tests/renderscript/src/android/renderscript/cts/YuvTest.java
@@ -72,6 +72,9 @@
         return Allocation.createTyped(mRS, Type.createXY(mRS, Element.RGBA_8888(mRS), width, height));
     }
 
+    public Allocation makeOutput_f4() {
+        return Allocation.createTyped(mRS, Type.createXY(mRS, Element.F32_4(mRS), width, height));
+    }
     // Test for the API 17 conversion path
     // This used a uchar buffer assuming nv21
     public void testV17() {
@@ -94,11 +97,11 @@
         Allocation ta = Allocation.createSized(mRS, Element.U8(mRS), tmp.length);
         ta.copyFrom(tmp);
 
-
         ScriptIntrinsicYuvToRGB syuv = ScriptIntrinsicYuvToRGB.create(mRS, Element.U8(mRS));
         syuv.setInput(ta);
         syuv.forEach(aout);
-
+        
+        mVerify.set_gAllowedIntError(2); // this will allow for less strict implementation
         ScriptC_yuv script = new ScriptC_yuv(mRS);
         script.invoke_makeRef(ay, au, av, aref);
 
@@ -138,7 +141,8 @@
         }
         ta.copyFrom(tmp);
         script.invoke_makeRef(ay, au, av, aref);
-
+        
+        mVerify.set_gAllowedIntError(2); // this will allow for less strict implementation
         syuv.setInput(ta);
         syuv.forEach(aout);
         mVerify.invoke_verify(aref, aout, ay);
@@ -183,6 +187,7 @@
         }
         ta.copyFrom(tmp);
         script.invoke_makeRef(ay, au, av, aref);
+        mVerify.set_gAllowedIntError(2); // this will allow for less strict implementation
 
         syuv.setInput(ta);
         syuv.forEach(aout);
@@ -198,4 +203,84 @@
         checkForErrors();
     }
 
+    // Test for the API conversion to float4 RGBA using rsYuvToRGBA, YV12.
+    public void test_YV12_Float4() {
+        mVerify = new ScriptC_verify(mRS);
+        ScriptC_yuv script = new ScriptC_yuv(mRS);
+
+        makeYuvBuffer(512, 512);
+        Allocation aout = makeOutput_f4();
+        Allocation aref = makeOutput_f4();
+
+
+        Type.Builder tb = new Type.Builder(mRS, Element.YUV(mRS));
+        tb.setX(width);
+        tb.setY(height);
+        tb.setYuvFormat(android.graphics.ImageFormat.YV12);
+        Allocation ta = Allocation.createTyped(mRS, tb.create(), Allocation.USAGE_SCRIPT);
+
+        byte tmp[] = new byte[(width * height) + (getCWidth() * getCHeight() * 2)];
+        int i = 0;
+        for (int j = 0; j < (width * height); j++) {
+            tmp[i++] = by[j];
+        }
+        for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+            tmp[i++] = bu[j];
+        }
+        for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+            tmp[i++] = bv[j];
+        }
+        ta.copyFrom(tmp);
+        script.invoke_makeRef_f4(ay, au, av, aref);
+
+        script.set_mInput(ta);
+        script.forEach_cvt_f4(aout);
+        mVerify.invoke_verify(aref, aout, ay);
+
+        mRS.finish();
+        mVerify.set_gAllowedFloatError(0.01f); // this will allow for less strict implementation
+        mVerify.invoke_checkError();
+        waitForMessage();
+        checkForErrors();
+    }
+
+    // Test for the API conversion to float4 RGBA using rsYuvToRGBA, NV21.
+    public void test_NV21_Float4() {
+        mVerify = new ScriptC_verify(mRS);
+        ScriptC_yuv script = new ScriptC_yuv(mRS);
+
+        makeYuvBuffer(512, 512);
+        Allocation aout = makeOutput_f4();
+        Allocation aref = makeOutput_f4();
+
+
+        Type.Builder tb = new Type.Builder(mRS, Element.YUV(mRS));
+        tb.setX(width);
+        tb.setY(height);
+        tb.setYuvFormat(android.graphics.ImageFormat.NV21);
+        Allocation ta = Allocation.createTyped(mRS, tb.create(), Allocation.USAGE_SCRIPT);
+
+        byte tmp[] = new byte[(width * height) + (getCWidth() * getCHeight() * 2)];
+        int i = 0;
+        for (int j = 0; j < (width * height); j++) {
+            tmp[i++] = by[j];
+        }
+        for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+            tmp[i++] = bv[j];
+            tmp[i++] = bu[j];
+        }
+
+        ta.copyFrom(tmp);
+        script.invoke_makeRef_f4(ay, au, av, aref);
+
+        script.set_mInput(ta);
+        script.forEach_cvt_f4(aout);
+        mVerify.set_gAllowedFloatError(0.01f); // this will allow for less strict implementation
+        mVerify.invoke_verify(aref, aout, ay);
+
+        mRS.finish();
+        mVerify.invoke_checkError();
+        waitForMessage();
+        checkForErrors();
+    }
 }
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/double.rs b/tests/tests/renderscript/src/android/renderscript/cts/double.rs
new file mode 100644
index 0000000..86ced05
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/double.rs
@@ -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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+int4 __attribute__((kernel)) doubleKernel(int4 in)
+{
+  return in * 2;
+}
\ No newline at end of file
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/doubleglobal.rs b/tests/tests/renderscript/src/android/renderscript/cts/doubleglobal.rs
new file mode 100644
index 0000000..9a8cb69
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/doubleglobal.rs
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 test the case where a kernel does not use a double but there is a global variable of type
+// double present in the file see bug:23213925
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+#pragma rs_fp_relaxed
+
+float pi2;
+double pi = 3.14159265359;
+
+void func_setup() {
+  pi2 = pi * 2;
+}
+
+float RS_KERNEL times2pi(uint32_t x) {
+  return pi2 * x;
+}
\ No newline at end of file
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/float16_arithmetic.rs b/tests/tests/renderscript/src/android/renderscript/cts/float16_arithmetic.rs
new file mode 100644
index 0000000..9bd90fd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/float16_arithmetic.rs
@@ -0,0 +1,38 @@
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+rs_allocation gInput;
+
+half RS_KERNEL add(int x, int y) {
+    half a = rsGetElementAt_half(gInput, x);
+    half b = rsGetElementAt_half(gInput, y);
+    return a + b;
+}
+
+half RS_KERNEL sub(int x, int y) {
+    half a = rsGetElementAt_half(gInput, x);
+    half b = rsGetElementAt_half(gInput, y);
+    return a - b;
+}
+
+half RS_KERNEL mul(int x, int y) {
+    half a = rsGetElementAt_half(gInput, x);
+    half b = rsGetElementAt_half(gInput, y);
+    return a * b;
+}
+
+half RS_KERNEL div(int x, int y) {
+    half a = rsGetElementAt_half(gInput, x);
+    half b = rsGetElementAt_half(gInput, y);
+    return a / b;
+}
+
+union Bit16Type {
+    half h;
+    unsigned short s;
+};
+
+unsigned short __attribute__((kernel)) bitcast(half h) {
+    union Bit16Type u = {h};
+    return u.s;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/float16_gen.c b/tests/tests/renderscript/src/android/renderscript/cts/float16_gen.c
new file mode 100644
index 0000000..fed0563
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/float16_gen.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+// This utility generates a Java file containing data used in the CTS test for
+// FP16 arithmetic.  The Java file containes a class with the following fields:
+//     * A 1D array of length 'n' containing various constants used in the test
+//     * Four n x n x 2 arrays, each containing the reference output for
+//     pair-wise addition, subtraction, multiplication and division.  The
+//     reference output is a range accounting for tolerable error.  The
+//     acceptable error is 3 x ULP for division and 1 x ULP for other
+//     operations.
+
+typedef __fp16 half;
+
+// Macros for names of the package, class and fields in the generated java file
+#define PACKAGE_NAME "android.renderscript.cts"
+#define CLASS_NAME "Float16TestData"
+#define INPUT_ARRAY "input"
+#define OUTPUT_ARRAY_ADD "ReferenceOutputForAdd"
+#define OUTPUT_ARRAY_SUB "ReferenceOutputForSub"
+#define OUTPUT_ARRAY_MUL "ReferenceOutputForMul"
+#define OUTPUT_ARRAY_DIV "ReferenceOutputForDiv"
+
+// Structure to hold an FP16 constant and its human-readable description, to be
+// added as a comment, in the generated Java file
+typedef struct {
+  unsigned short value;
+  const char* description;
+} FP16Constant;
+
+FP16Constant input[] = {
+    { 0b0011110000000000, "one" },
+    { 0b0100000000000000, "two" },
+    { 0b0000000000000001, "smallest subnormal" },
+    { 0b0000001111111111, "largest subnormal" },
+    { 0b0000010000000000, "smallest normal" },
+    { 0b0111101111111111, "largest normal" },
+    { 0x3880, "0.562500" },
+    { 0x3e80, "1.625000" },
+    { 0x5140, "42.000000" },
+    { 0x5ac0, "216.000000" },
+    { 0x6c75, "4564.000000" },
+    { 0x7b53, "60000.000000" },
+    { 0b1011110000000000, "negative one" },
+    { 0b1100000000000000, "negative two" },
+    { 0b1000000000000001, "negative (smallest subnormal)" },
+    { 0b1000001111111111, "negative (largest subnormal)" },
+    { 0b1000010000000000, "negative (smallest normal)" },
+    { 0b1111101111111111, "negative (largest normal)" },
+    { 0xb880, "-0.562500" },
+    { 0xbe80, "-1.625000" },
+    { 0xd140, "-42.000000" },
+    { 0xdac0, "-216.000000" },
+    { 0xec75, "-4564.000000" },
+    { 0xfb53, "-60000.000000" },
+    { 0b0000000000000000, "zero" },
+    { 0b0111110000000000, "infinity" },
+    { 0b1000000000000000, "negative zero" },
+    { 0b1111110000000000, "negative infinity" },
+    { 0b0111110000000001, "nan" },
+};
+
+const int numInputs = sizeof(input) / sizeof(FP16Constant);
+
+// 16-bit masks for extracting sign, exponent and mantissa bits
+static unsigned short SIGN_MASK     = 0x8000;
+static unsigned short EXPONENT_MASK = 0x7C00;
+static unsigned short MANTISSA_MASK = 0x03FF;
+
+// NaN has all exponent bits set to 1 and a non-zero mantissa
+int isFloat16NaN(unsigned short val) {
+  return (val & EXPONENT_MASK) == EXPONENT_MASK &&
+         (val & MANTISSA_MASK) != 0;
+}
+
+// Infinity has all exponent bits set to 1 and zeroes in mantissa
+int isFloat16Infinite(unsigned 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
+int isFloat16SubNormal(unsigned short val) {
+    return (val & EXPONENT_MASK) == 0 && (val & MANTISSA_MASK) != 0;
+}
+
+// Negativity test checks the sign bit
+int isFloat16Negative(unsigned short val) {
+    return (val & SIGN_MASK) != 0;
+}
+
+// Interpret a short as a FP16 value and convert to float
+float half2float(unsigned short s) {
+  half h = *(half *) &s;
+  return (float) h;
+}
+
+// Return the short value representing a float value in FP16
+unsigned short float2half(float f) {
+  half h = (half) f;
+  return *(unsigned short *) &h;
+}
+
+// Compute ULP for 'value' and store value +/- tolerance * ULP in bounds sarray
+void getErrorBar(unsigned short value, int tolerance, unsigned short bounds[2]) {
+  // Validate 'tolerance' parameter
+  if (tolerance != 1 && tolerance != 3) {
+    fprintf(stderr, "Allowed ULP error should either be 1 or 3, and not %d\n",
+            tolerance);
+    exit(0);
+  }
+
+  half hValue = *(half *) &value;
+  half ulp;
+
+  // For Infinity and NaN, bounds are equal to 'value'
+  if (isFloat16Infinite(value) || isFloat16NaN(value)) {
+    bounds[0] = value;
+    bounds[1] = value;
+    return;
+  }
+
+  // Compute ULP
+  if (isFloat16SubNormal(value)) {
+    // 1 ulp for a subnormal number is the smallest possible subnormal
+    unsigned short ulpInShort = 0b0000000000000001;
+    ulp = *(half *) &ulpInShort;
+  }
+  else {
+    // 1 ulp for a non-subnormal number is (b - a) where
+    //   - a has same exponent as 'value', zeroes for sign and mantissa
+    //   - b has same exponent and sign as 'a', and has '1' in the mantissa
+    // (b - a) gives the ULP by getting rid of the implied '1' at the front of
+    // the mantissa
+    unsigned short a = (value & EXPONENT_MASK);
+    unsigned short b = (a | 1);
+    half hA = *(half *) &a;
+    half hB = *(half *) &b;
+    ulp = hB - hA;
+  }
+
+  // Compute error bar based on error tolerance
+  half lb = hValue - tolerance * ulp;
+  half ub = hValue + tolerance * ulp;
+  if (lb > ub) {
+    fprintf(stderr, "Warning! inconsistency in bounds\n");
+    fprintf(stderr, "Value: %f, ulp: %f\n", (float) hValue, (float) ulp);
+    fprintf(stderr, "lb: %f ub: %f\n", (float) lb, (float) ub);
+    fprintf(stderr, "lb: %x ub: %x\n", *(unsigned short *) &lb, *(unsigned short *) &ub);
+  }
+
+  // Set the bounds
+  bounds[0] = *(unsigned short *) &lb;
+  bounds[1] = *(unsigned short *) &ub;
+
+  // RS allows flush-to-zero for sub-normal results in relaxed precision.
+  // Flush lower bound of a positive sub-normal result to zero.
+  if (!isFloat16Negative(bounds[0]) && isFloat16SubNormal(bounds[0]))
+    bounds[0] = 0x0;
+  // Flush upper bound of a negative sub-normal result to negative zero.
+  if (isFloat16Negative(bounds[1]) && isFloat16SubNormal(bounds[1]))
+    bounds[1] = 0x0 | SIGN_MASK;
+
+}
+
+// Utilities that take 'unsigned short' representations of two fp16 values and
+// return the result of an arithmetic operation as an 'unsigned short'.
+typedef unsigned short operation_t(unsigned short, unsigned short);
+
+unsigned short add(unsigned short a, unsigned short b) {
+  float op1 = half2float(a);
+  float op2 = half2float(b);
+  return float2half(op1 + op2);
+}
+
+unsigned short subtract(unsigned short a, unsigned short b) {
+  float op1 = half2float(a);
+  float op2 = half2float(b);
+  return float2half(op1 - op2);
+}
+
+unsigned short multiply(unsigned short a, unsigned short b) {
+  float op1 = half2float(a);
+  float op2 = half2float(b);
+  return float2half(op1 * op2);
+}
+
+unsigned short divide(unsigned short a, unsigned short b) {
+  float op1 = half2float(a);
+  float op2 = half2float(b);
+  return float2half(op1 / op2);
+}
+
+// Print Java code that initializes the input array (along with the description
+// of the constant as a comment)
+void printInput() {
+  printf("static short[] %s = {\n", INPUT_ARRAY);
+
+  for (int x = 0; x < numInputs; x ++)
+    printf("(short) 0x%04x, // %s\n", input[x].value, input[x].description);
+
+  printf("};\n\n");
+}
+
+// Print Java code that initializes the output array with the acceptable bounds
+// on the output.  For each pair of inputs, bounds are calculated on the result
+// from applying 'operation' on the pair.
+void printReferenceOutput(const char *fieldName, operation_t operation,
+                          int tolerance) {
+  unsigned short result;
+  unsigned short resultBounds[2];
+
+  printf("static short[][][] %s = {\n", fieldName);
+
+  for (int x = 0; x < numInputs; x ++) {
+    printf("{");
+    for (int y = 0; y < numInputs; y ++) {
+      // Apply 'operation' and compute error bounds for the result.
+      result = operation(input[x].value, input[y].value);
+      getErrorBar(result, tolerance, resultBounds);
+
+      printf("{ (short) 0x%04x, (short) 0x%04x},", resultBounds[0],
+                                                   resultBounds[1]);
+    }
+    printf("},\n");
+  }
+
+  printf("};\n\n");
+}
+
+const char *preamble = "/*\n"
+" * Copyright (C) 2015 The Android Open Source Project\n"
+" *\n"
+" * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
+" * you may not use this file except in compliance with the License.\n"
+" * You may obtain a copy of the License at\n"
+" *\n"
+" *      http://www.apache.org/licenses/LICENSE-2.0\n"
+" *\n"
+" * Unless required by applicable law or agreed to in writing, software\n"
+" * distributed under the License is distributed on an \"AS IS\" BASIS,\n"
+" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
+" * See the License for the specific language governing permissions and\n"
+" * limitations under the License.\n"
+" */\n"
+"\n"
+"/* Don't edit this file!  It is auto-generated by float16_gen.sh */\n\n"
+"package "PACKAGE_NAME";\n\n"
+"public class "CLASS_NAME" {\n";
+
+int main() {
+  // Print a preamble with copyright and class declaration, followed by the
+  // input FP16 array, and reference outputs for pair-wise arithmetic
+  // operations.
+  printf("%s", preamble);
+  printInput();
+
+  printReferenceOutput(OUTPUT_ARRAY_ADD, add, 1);
+  printReferenceOutput(OUTPUT_ARRAY_SUB, subtract, 1);
+  printReferenceOutput(OUTPUT_ARRAY_MUL, multiply, 1);
+  printReferenceOutput(OUTPUT_ARRAY_DIV, divide, 3);
+
+  printf("}");
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/float16_gen.sh b/tests/tests/renderscript/src/android/renderscript/cts/float16_gen.sh
new file mode 100644
index 0000000..8ddea46
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/float16_gen.sh
@@ -0,0 +1,31 @@
+#!/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.
+#
+
+LIBDIR=$ANDROID_HOST_OUT/lib64
+CLANG=$ANDROID_BUILD_TOP/prebuilts/clang/linux-x86/host/3.6/bin/clang
+
+TMPDIR=`mktemp -d /tmp/float16_gen.XXXXXXXX`
+TMPFILE=$TMPDIR/tmp.java
+OUTFILE=$TMPDIR/Float16TestData.java
+EXECUTABLE=$TMPDIR/float16_gen
+
+$CLANG -Wl,-rpath=$LIBDIR -L $LIBDIR -lcompiler_rt -m64 float16_gen.c -o $EXECUTABLE
+$EXECUTABLE > $TMPFILE
+clang-format -style='{ColumnLimit: 80}' $TMPFILE > $OUTFILE
+cp $OUTFILE .
+
+rm -rf $TMPDIR
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.java
new file mode 100644
index 0000000..78bdfe8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.java
@@ -0,0 +1,884 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAbs extends RSBaseCompute {
+
+    private ScriptC_TestAbs script;
+    private ScriptC_TestAbsRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAbs(mRS);
+        scriptRelaxed = new ScriptC_TestAbsRelaxed(mRS);
+    }
+
+    public class ArgumentsCharUchar {
+        public byte inV;
+        public byte out;
+    }
+
+    private void checkAbsCharUchar() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xf7393ea6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.forEach_testAbsCharUchar(inV, out);
+            verifyResultsAbsCharUchar(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsCharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsCharUchar(inV, out);
+            verifyResultsAbsCharUchar(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsCharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsCharUchar(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (byte) 42);
+        inV.copyTo(arrayInV);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkAbsCharUchar" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAbsChar2Uchar2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xe5e407cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testAbsChar2Uchar2(inV, out);
+            verifyResultsAbsChar2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsChar2Uchar2(inV, out);
+            verifyResultsAbsChar2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsChar2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(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 checkAbsChar2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAbsChar3Uchar3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x479615al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testAbsChar3Uchar3(inV, out);
+            verifyResultsAbsChar3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsChar3Uchar3(inV, out);
+            verifyResultsAbsChar3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsChar3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(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 checkAbsChar3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAbsChar4Uchar4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xfa948238l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testAbsChar4Uchar4(inV, out);
+            verifyResultsAbsChar4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsChar4Uchar4(inV, out);
+            verifyResultsAbsChar4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsChar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsChar4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(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 checkAbsChar4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortUshort {
+        public short inV;
+        public short out;
+    }
+
+    private void checkAbsShortUshort() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xa064819cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.forEach_testAbsShortUshort(inV, out);
+            verifyResultsAbsShortUshort(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsShortUshort(inV, out);
+            verifyResultsAbsShortUshort(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsShortUshort(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.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkAbsShortUshort" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAbsShort2Ushort2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x6856b93el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testAbsShort2Ushort2(inV, out);
+            verifyResultsAbsShort2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsShort2Ushort2(inV, out);
+            verifyResultsAbsShort2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsShort2Ushort2(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.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(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 checkAbsShort2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAbsShort3Ushort3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xbeb24a6al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testAbsShort3Ushort3(inV, out);
+            verifyResultsAbsShort3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsShort3Ushort3(inV, out);
+            verifyResultsAbsShort3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsShort3Ushort3(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.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(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 checkAbsShort3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAbsShort4Ushort4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x150ddb96l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testAbsShort4Ushort4(inV, out);
+            verifyResultsAbsShort4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsShort4Ushort4(inV, out);
+            verifyResultsAbsShort4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsShort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsShort4Ushort4(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.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(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 checkAbsShort4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntUint {
+        public int inV;
+        public int out;
+    }
+
+    private void checkAbsIntUint() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xac5b83e6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.forEach_testAbsIntUint(inV, out);
+            verifyResultsAbsIntUint(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsIntUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsIntUint(inV, out);
+            verifyResultsAbsIntUint(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsIntUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsIntUint(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (int) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkAbsIntUint" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAbsInt2Uint2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x938616fal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testAbsInt2Uint2(inV, out);
+            verifyResultsAbsInt2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsInt2Uint2(inV, out);
+            verifyResultsAbsInt2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsInt2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(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 checkAbsInt2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAbsInt3Uint3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xf28ddbeel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testAbsInt3Uint3(inV, out);
+            verifyResultsAbsInt3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsInt3Uint3(inV, out);
+            verifyResultsAbsInt3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsInt3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(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 checkAbsInt3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAbsInt4Uint4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x5195a0e2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testAbsInt4Uint4(inV, out);
+            verifyResultsAbsInt4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAbsInt4Uint4(inV, out);
+            verifyResultsAbsInt4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAbsInt4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAbsInt4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeAbs(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 checkAbsInt4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAbs() {
+        checkAbsCharUchar();
+        checkAbsChar2Uchar2();
+        checkAbsChar3Uchar3();
+        checkAbsChar4Uchar4();
+        checkAbsShortUshort();
+        checkAbsShort2Ushort2();
+        checkAbsShort3Ushort3();
+        checkAbsShort4Ushort4();
+        checkAbsIntUint();
+        checkAbsInt2Uint2();
+        checkAbsInt3Uint3();
+        checkAbsInt4Uint4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.rs
new file mode 100644
index 0000000..918fa14
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbs.rs
@@ -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.
+ */
+
+// 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)
+
+
+uchar __attribute__((kernel)) testAbsCharUchar(char inV) {
+    return abs(inV);
+}
+
+uchar2 __attribute__((kernel)) testAbsChar2Uchar2(char2 inV) {
+    return abs(inV);
+}
+
+uchar3 __attribute__((kernel)) testAbsChar3Uchar3(char3 inV) {
+    return abs(inV);
+}
+
+uchar4 __attribute__((kernel)) testAbsChar4Uchar4(char4 inV) {
+    return abs(inV);
+}
+
+ushort __attribute__((kernel)) testAbsShortUshort(short inV) {
+    return abs(inV);
+}
+
+ushort2 __attribute__((kernel)) testAbsShort2Ushort2(short2 inV) {
+    return abs(inV);
+}
+
+ushort3 __attribute__((kernel)) testAbsShort3Ushort3(short3 inV) {
+    return abs(inV);
+}
+
+ushort4 __attribute__((kernel)) testAbsShort4Ushort4(short4 inV) {
+    return abs(inV);
+}
+
+uint __attribute__((kernel)) testAbsIntUint(int inV) {
+    return abs(inV);
+}
+
+uint2 __attribute__((kernel)) testAbsInt2Uint2(int2 inV) {
+    return abs(inV);
+}
+
+uint3 __attribute__((kernel)) testAbsInt3Uint3(int3 inV) {
+    return abs(inV);
+}
+
+uint4 __attribute__((kernel)) testAbsInt4Uint4(int4 inV) {
+    return abs(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbsRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbsRelaxed.rs
new file mode 100644
index 0000000..f3672ab
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAbsRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAbs.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.java
new file mode 100644
index 0000000..8ea35f7
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAcos extends RSBaseCompute {
+
+    private ScriptC_TestAcos script;
+    private ScriptC_TestAcosRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAcos(mRS);
+        scriptRelaxed = new ScriptC_TestAcosRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkAcosFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd1cc3bdfl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAcosFloatFloat(inV, out);
+            verifyResultsAcosFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosFloatFloat(inV, out);
+            verifyResultsAcosFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAcosFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcosFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1096ae8bl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAcosFloat2Float2(inV, out);
+            verifyResultsAcosFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosFloat2Float2(inV, out);
+            verifyResultsAcosFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcos(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 checkAcosFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcosFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6b1cf69l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAcosFloat3Float3(inV, out);
+            verifyResultsAcosFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosFloat3Float3(inV, out);
+            verifyResultsAcosFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcos(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 checkAcosFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcosFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfcccf047l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAcosFloat4Float4(inV, out);
+            verifyResultsAcosFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAcosFloat4Float4(inV, out);
+            verifyResultsAcosFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcosFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcosFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcos(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 checkAcosFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAcos() {
+        checkAcosFloatFloat();
+        checkAcosFloat2Float2();
+        checkAcosFloat3Float3();
+        checkAcosFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.rs
new file mode 100644
index 0000000..fc21625
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcos.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testAcosFloatFloat(float inV) {
+    return acos(inV);
+}
+
+float2 __attribute__((kernel)) testAcosFloat2Float2(float2 inV) {
+    return acos(inV);
+}
+
+float3 __attribute__((kernel)) testAcosFloat3Float3(float3 inV) {
+    return acos(inV);
+}
+
+float4 __attribute__((kernel)) testAcosFloat4Float4(float4 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
new file mode 100644
index 0000000..e2d5dc9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAcos.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.java
new file mode 100644
index 0000000..6a4e844
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAcosh extends RSBaseCompute {
+
+    private ScriptC_TestAcosh script;
+    private ScriptC_TestAcoshRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAcosh(mRS);
+        scriptRelaxed = new ScriptC_TestAcoshRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkAcoshFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xcf303663l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAcoshFloatFloat(inV, out);
+            verifyResultsAcoshFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshFloatFloat(inV, out);
+            verifyResultsAcoshFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAcoshFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcoshFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x37b311efl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAcoshFloat2Float2(inV, out);
+            verifyResultsAcoshFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshFloat2Float2(inV, out);
+            verifyResultsAcoshFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcosh(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 checkAcoshFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcoshFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2dce32cdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAcoshFloat3Float3(inV, out);
+            verifyResultsAcoshFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshFloat3Float3(inV, out);
+            verifyResultsAcoshFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcosh(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 checkAcoshFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcoshFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x23e953abl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAcoshFloat4Float4(inV, out);
+            verifyResultsAcoshFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAcoshFloat4Float4(inV, out);
+            verifyResultsAcoshFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcoshFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcoshFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcosh(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 checkAcoshFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAcosh() {
+        checkAcoshFloatFloat();
+        checkAcoshFloat2Float2();
+        checkAcoshFloat3Float3();
+        checkAcoshFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.rs
new file mode 100644
index 0000000..7f6330a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcosh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testAcoshFloatFloat(float inV) {
+    return acosh(inV);
+}
+
+float2 __attribute__((kernel)) testAcoshFloat2Float2(float2 inV) {
+    return acosh(inV);
+}
+
+float3 __attribute__((kernel)) testAcoshFloat3Float3(float3 inV) {
+    return acosh(inV);
+}
+
+float4 __attribute__((kernel)) testAcoshFloat4Float4(float4 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
new file mode 100644
index 0000000..4190d6e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcoshRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAcosh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.java
new file mode 100644
index 0000000..877f06b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAcospi extends RSBaseCompute {
+
+    private ScriptC_TestAcospi script;
+    private ScriptC_TestAcospiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAcospi(mRS);
+        scriptRelaxed = new ScriptC_TestAcospiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkAcospiFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd1e084b2l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAcospiFloatFloat(inV, out);
+            verifyResultsAcospiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiFloatFloat(inV, out);
+            verifyResultsAcospiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAcospiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcospiFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa318aa86l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAcospiFloat2Float2(inV, out);
+            verifyResultsAcospiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiFloat2Float2(inV, out);
+            verifyResultsAcospiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcospi(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 checkAcospiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcospiFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9933cb64l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAcospiFloat3Float3(inV, out);
+            verifyResultsAcospiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiFloat3Float3(inV, out);
+            verifyResultsAcospiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcospi(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 checkAcospiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAcospiFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8f4eec42l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAcospiFloat4Float4(inV, out);
+            verifyResultsAcospiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAcospiFloat4Float4(inV, out);
+            verifyResultsAcospiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAcospiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAcospiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAcospi(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 checkAcospiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAcospi() {
+        checkAcospiFloatFloat();
+        checkAcospiFloat2Float2();
+        checkAcospiFloat3Float3();
+        checkAcospiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.rs
new file mode 100644
index 0000000..84d65b7
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testAcospiFloatFloat(float inV) {
+    return acospi(inV);
+}
+
+float2 __attribute__((kernel)) testAcospiFloat2Float2(float2 inV) {
+    return acospi(inV);
+}
+
+float3 __attribute__((kernel)) testAcospiFloat3Float3(float3 inV) {
+    return acospi(inV);
+}
+
+float4 __attribute__((kernel)) testAcospiFloat4Float4(float4 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
new file mode 100644
index 0000000..c3d887e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAcospiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAcospi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.java
new file mode 100644
index 0000000..4f354fe
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAsin extends RSBaseCompute {
+
+    private ScriptC_TestAsin script;
+    private ScriptC_TestAsinRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAsin(mRS);
+        scriptRelaxed = new ScriptC_TestAsinRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkAsinFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf98b5a12l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAsinFloatFloat(inV, out);
+            verifyResultsAsinFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinFloatFloat(inV, out);
+            verifyResultsAsinFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAsinFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x23f7cce6l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAsinFloat2Float2(inV, out);
+            verifyResultsAsinFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinFloat2Float2(inV, out);
+            verifyResultsAsinFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsin(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 checkAsinFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1a12edc4l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAsinFloat3Float3(inV, out);
+            verifyResultsAsinFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinFloat3Float3(inV, out);
+            verifyResultsAsinFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsin(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 checkAsinFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x102e0ea2l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAsinFloat4Float4(inV, out);
+            verifyResultsAsinFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinFloat4Float4(inV, out);
+            verifyResultsAsinFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsin(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 checkAsinFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAsin() {
+        checkAsinFloatFloat();
+        checkAsinFloat2Float2();
+        checkAsinFloat3Float3();
+        checkAsinFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.rs
new file mode 100644
index 0000000..59313a4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsin.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testAsinFloatFloat(float inV) {
+    return asin(inV);
+}
+
+float2 __attribute__((kernel)) testAsinFloat2Float2(float2 inV) {
+    return asin(inV);
+}
+
+float3 __attribute__((kernel)) testAsinFloat3Float3(float3 inV) {
+    return asin(inV);
+}
+
+float4 __attribute__((kernel)) testAsinFloat4Float4(float4 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
new file mode 100644
index 0000000..6a08389
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAsin.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.java
new file mode 100644
index 0000000..c22e658
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAsinh extends RSBaseCompute {
+
+    private ScriptC_TestAsinh script;
+    private ScriptC_TestAsinhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAsinh(mRS);
+        scriptRelaxed = new ScriptC_TestAsinhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkAsinhFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7c4a48f4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAsinhFloatFloat(inV, out);
+            verifyResultsAsinhFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhFloatFloat(inV, out);
+            verifyResultsAsinhFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAsinhFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinhFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x79032b38l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAsinhFloat2Float2(inV, out);
+            verifyResultsAsinhFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhFloat2Float2(inV, out);
+            verifyResultsAsinhFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsinh(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 checkAsinhFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinhFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6f1e4c16l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAsinhFloat3Float3(inV, out);
+            verifyResultsAsinhFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhFloat3Float3(inV, out);
+            verifyResultsAsinhFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsinh(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 checkAsinhFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinhFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x65396cf4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAsinhFloat4Float4(inV, out);
+            verifyResultsAsinhFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinhFloat4Float4(inV, out);
+            verifyResultsAsinhFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinhFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsinh(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 checkAsinhFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAsinh() {
+        checkAsinhFloatFloat();
+        checkAsinhFloat2Float2();
+        checkAsinhFloat3Float3();
+        checkAsinhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.rs
new file mode 100644
index 0000000..5c6f6c20
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testAsinhFloatFloat(float inV) {
+    return asinh(inV);
+}
+
+float2 __attribute__((kernel)) testAsinhFloat2Float2(float2 inV) {
+    return asinh(inV);
+}
+
+float3 __attribute__((kernel)) testAsinhFloat3Float3(float3 inV) {
+    return asinh(inV);
+}
+
+float4 __attribute__((kernel)) testAsinhFloat4Float4(float4 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
new file mode 100644
index 0000000..0d385ff
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinhRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAsinh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.java
new file mode 100644
index 0000000..5cd7a0e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAsinpi extends RSBaseCompute {
+
+    private ScriptC_TestAsinpi script;
+    private ScriptC_TestAsinpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAsinpi(mRS);
+        scriptRelaxed = new ScriptC_TestAsinpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkAsinpiFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe541a30dl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAsinpiFloatFloat(inV, out);
+            verifyResultsAsinpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiFloatFloat(inV, out);
+            verifyResultsAsinpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAsinpiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinpiFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9b8ce9c9l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAsinpiFloat2Float2(inV, out);
+            verifyResultsAsinpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiFloat2Float2(inV, out);
+            verifyResultsAsinpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsinpi(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 checkAsinpiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinpiFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x91a80aa7l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAsinpiFloat3Float3(inV, out);
+            verifyResultsAsinpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiFloat3Float3(inV, out);
+            verifyResultsAsinpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsinpi(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 checkAsinpiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAsinpiFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x87c32b85l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAsinpiFloat4Float4(inV, out);
+            verifyResultsAsinpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAsinpiFloat4Float4(inV, out);
+            verifyResultsAsinpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAsinpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAsinpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAsinpi(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 checkAsinpiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAsinpi() {
+        checkAsinpiFloatFloat();
+        checkAsinpiFloat2Float2();
+        checkAsinpiFloat3Float3();
+        checkAsinpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.rs
new file mode 100644
index 0000000..4bbbe13
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testAsinpiFloatFloat(float inV) {
+    return asinpi(inV);
+}
+
+float2 __attribute__((kernel)) testAsinpiFloat2Float2(float2 inV) {
+    return asinpi(inV);
+}
+
+float3 __attribute__((kernel)) testAsinpiFloat3Float3(float3 inV) {
+    return asinpi(inV);
+}
+
+float4 __attribute__((kernel)) testAsinpiFloat4Float4(float4 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
new file mode 100644
index 0000000..a0648dc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAsinpiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAsinpi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.java
new file mode 100644
index 0000000..331227a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAtan extends RSBaseCompute {
+
+    private ScriptC_TestAtan script;
+    private ScriptC_TestAtanRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtan(mRS);
+        scriptRelaxed = new ScriptC_TestAtanRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkAtanFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x92004c8dl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAtanFloatFloat(inV, out);
+            verifyResultsAtanFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanFloatFloat(inV, out);
+            verifyResultsAtanFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAtanFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x48a32749l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAtanFloat2Float2(inV, out);
+            verifyResultsAtanFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanFloat2Float2(inV, out);
+            verifyResultsAtanFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtan(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 checkAtanFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3ebe4827l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAtanFloat3Float3(inV, out);
+            verifyResultsAtanFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanFloat3Float3(inV, out);
+            verifyResultsAtanFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtan(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 checkAtanFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x34d96905l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAtanFloat4Float4(inV, out);
+            verifyResultsAtanFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanFloat4Float4(inV, out);
+            verifyResultsAtanFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtan(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 checkAtanFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAtan() {
+        checkAtanFloatFloat();
+        checkAtanFloat2Float2();
+        checkAtanFloat3Float3();
+        checkAtanFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.rs
new file mode 100644
index 0000000..1b987fa
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testAtanFloatFloat(float inV) {
+    return atan(inV);
+}
+
+float2 __attribute__((kernel)) testAtanFloat2Float2(float2 inV) {
+    return atan(inV);
+}
+
+float3 __attribute__((kernel)) testAtanFloat3Float3(float3 inV) {
+    return atan(inV);
+}
+
+float4 __attribute__((kernel)) testAtanFloat4Float4(float4 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
new file mode 100644
index 0000000..b8894cd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAtan2 extends RSBaseCompute {
+
+    private ScriptC_TestAtan2 script;
+    private ScriptC_TestAtan2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtan2(mRS);
+        scriptRelaxed = new ScriptC_TestAtan2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inNumerator;
+        public float inDenominator;
+        public Target.Floaty out;
+    }
+
+    private void checkAtan2FloatFloatFloat() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe261d332l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7bd90d5bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2FloatFloatFloat(inNumerator, out);
+            verifyResultsAtan2FloatFloatFloat(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2FloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2FloatFloatFloat(inNumerator, out);
+            verifyResultsAtan2FloatFloatFloat(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2FloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2FloatFloatFloat(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inNumerator = arrayInNumerator[i];
+                args.inDenominator = arrayInDenominator[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAtan2FloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2Float2Float2Float2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xefb30700l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xab583839l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2Float2Float2Float2(inNumerator, out);
+            verifyResultsAtan2Float2Float2Float2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2Float2Float2Float2(inNumerator, out);
+            verifyResultsAtan2Float2Float2Float2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2Float2Float2Float2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeAtan2(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 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]);
+                        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 checkAtan2Float2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2Float3Float3Float3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x927ef301l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7e33cb72l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2Float3Float3Float3(inNumerator, out);
+            verifyResultsAtan2Float3Float3Float3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2Float3Float3Float3(inNumerator, out);
+            verifyResultsAtan2Float3Float3Float3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2Float3Float3Float3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeAtan2(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 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]);
+                        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 checkAtan2Float3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2Float4Float4Float4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x354adf02l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x510f5eabl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2Float4Float4Float4(inNumerator, out);
+            verifyResultsAtan2Float4Float4Float4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2Float4Float4Float4(inNumerator, out);
+            verifyResultsAtan2Float4Float4Float4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2Float4Float4Float4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeAtan2(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 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]);
+                        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 checkAtan2Float4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAtan2() {
+        checkAtan2FloatFloatFloat();
+        checkAtan2Float2Float2Float2();
+        checkAtan2Float3Float3Float3();
+        checkAtan2Float4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.rs
new file mode 100644
index 0000000..19b2ed4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInDenominator;
+
+float __attribute__((kernel)) testAtan2FloatFloatFloat(float inNumerator, unsigned int x) {
+    float inDenominator = rsGetElementAt_float(gAllocInDenominator, x);
+    return atan2(inNumerator, inDenominator);
+}
+
+float2 __attribute__((kernel)) testAtan2Float2Float2Float2(float2 inNumerator, unsigned int x) {
+    float2 inDenominator = rsGetElementAt_float2(gAllocInDenominator, x);
+    return atan2(inNumerator, inDenominator);
+}
+
+float3 __attribute__((kernel)) testAtan2Float3Float3Float3(float3 inNumerator, unsigned int x) {
+    float3 inDenominator = rsGetElementAt_float3(gAllocInDenominator, x);
+    return atan2(inNumerator, inDenominator);
+}
+
+float4 __attribute__((kernel)) testAtan2Float4Float4Float4(float4 inNumerator, unsigned int x) {
+    float4 inDenominator = rsGetElementAt_float4(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
new file mode 100644
index 0000000..54e930b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAtan2.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.java
new file mode 100644
index 0000000..f22b020
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAtan2pi extends RSBaseCompute {
+
+    private ScriptC_TestAtan2pi script;
+    private ScriptC_TestAtan2piRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtan2pi(mRS);
+        scriptRelaxed = new ScriptC_TestAtan2piRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inNumerator;
+        public float inDenominator;
+        public Target.Floaty out;
+    }
+
+    private void checkAtan2piFloatFloatFloat() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x81dcb793l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5a748df4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2piFloatFloatFloat(inNumerator, out);
+            verifyResultsAtan2piFloatFloatFloat(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2piFloatFloatFloat(inNumerator, out);
+            verifyResultsAtan2piFloatFloatFloat(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piFloatFloatFloat(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inNumerator = arrayInNumerator[i];
+                args.inDenominator = arrayInDenominator[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAtan2piFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2piFloat2Float2Float2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x53d1a0b3l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xcc5c5614l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2piFloat2Float2Float2(inNumerator, out);
+            verifyResultsAtan2piFloat2Float2Float2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2piFloat2Float2Float2(inNumerator, out);
+            verifyResultsAtan2piFloat2Float2Float2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piFloat2Float2Float2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeAtan2pi(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 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]);
+                        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 checkAtan2piFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2piFloat3Float3Float3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf69d8cb4l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9f37e94dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2piFloat3Float3Float3(inNumerator, out);
+            verifyResultsAtan2piFloat3Float3Float3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2piFloat3Float3Float3(inNumerator, out);
+            verifyResultsAtan2piFloat3Float3Float3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piFloat3Float3Float3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeAtan2pi(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 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]);
+                        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 checkAtan2piFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtan2piFloat4Float4Float4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x996978b5l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x72137c86l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testAtan2piFloat4Float4Float4(inNumerator, out);
+            verifyResultsAtan2piFloat4Float4Float4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testAtan2piFloat4Float4Float4(inNumerator, out);
+            verifyResultsAtan2piFloat4Float4Float4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtan2piFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtan2piFloat4Float4Float4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeAtan2pi(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 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]);
+                        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 checkAtan2piFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAtan2pi() {
+        checkAtan2piFloatFloatFloat();
+        checkAtan2piFloat2Float2Float2();
+        checkAtan2piFloat3Float3Float3();
+        checkAtan2piFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.rs
new file mode 100644
index 0000000..14d11d9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2pi.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInDenominator;
+
+float __attribute__((kernel)) testAtan2piFloatFloatFloat(float inNumerator, unsigned int x) {
+    float inDenominator = rsGetElementAt_float(gAllocInDenominator, x);
+    return atan2pi(inNumerator, inDenominator);
+}
+
+float2 __attribute__((kernel)) testAtan2piFloat2Float2Float2(float2 inNumerator, unsigned int x) {
+    float2 inDenominator = rsGetElementAt_float2(gAllocInDenominator, x);
+    return atan2pi(inNumerator, inDenominator);
+}
+
+float3 __attribute__((kernel)) testAtan2piFloat3Float3Float3(float3 inNumerator, unsigned int x) {
+    float3 inDenominator = rsGetElementAt_float3(gAllocInDenominator, x);
+    return atan2pi(inNumerator, inDenominator);
+}
+
+float4 __attribute__((kernel)) testAtan2piFloat4Float4Float4(float4 inNumerator, unsigned int x) {
+    float4 inDenominator = rsGetElementAt_float4(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
new file mode 100644
index 0000000..8682f5c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtan2piRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAtan2pi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanRelaxed.rs
new file mode 100644
index 0000000..dce7eb4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAtan.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.java
new file mode 100644
index 0000000..f292c1a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAtanh extends RSBaseCompute {
+
+    private ScriptC_TestAtanh script;
+    private ScriptC_TestAtanhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtanh(mRS);
+        scriptRelaxed = new ScriptC_TestAtanhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkAtanhFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x17ef039dl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAtanhFloatFloat(inV, out);
+            verifyResultsAtanhFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhFloatFloat(inV, out);
+            verifyResultsAtanhFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAtanhFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanhFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa1cb59d9l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAtanhFloat2Float2(inV, out);
+            verifyResultsAtanhFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhFloat2Float2(inV, out);
+            verifyResultsAtanhFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtanh(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 checkAtanhFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanhFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x97e67ab7l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAtanhFloat3Float3(inV, out);
+            verifyResultsAtanhFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhFloat3Float3(inV, out);
+            verifyResultsAtanhFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtanh(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 checkAtanhFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanhFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8e019b95l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAtanhFloat4Float4(inV, out);
+            verifyResultsAtanhFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanhFloat4Float4(inV, out);
+            verifyResultsAtanhFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanhFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtanh(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 checkAtanhFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAtanh() {
+        checkAtanhFloatFloat();
+        checkAtanhFloat2Float2();
+        checkAtanhFloat3Float3();
+        checkAtanhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.rs
new file mode 100644
index 0000000..06c11e9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testAtanhFloatFloat(float inV) {
+    return atanh(inV);
+}
+
+float2 __attribute__((kernel)) testAtanhFloat2Float2(float2 inV) {
+    return atanh(inV);
+}
+
+float3 __attribute__((kernel)) testAtanhFloat3Float3(float3 inV) {
+    return atanh(inV);
+}
+
+float4 __attribute__((kernel)) testAtanhFloat4Float4(float4 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
new file mode 100644
index 0000000..455c61b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanhRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAtanh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.java
new file mode 100644
index 0000000..ed33df6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestAtanpi extends RSBaseCompute {
+
+    private ScriptC_TestAtanpi script;
+    private ScriptC_TestAtanpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestAtanpi(mRS);
+        scriptRelaxed = new ScriptC_TestAtanpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkAtanpiFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9ecfd70l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testAtanpiFloatFloat(inV, out);
+            verifyResultsAtanpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiFloatFloat(inV, out);
+            verifyResultsAtanpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkAtanpiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanpiFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x752cbed4l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testAtanpiFloat2Float2(inV, out);
+            verifyResultsAtanpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiFloat2Float2(inV, out);
+            verifyResultsAtanpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtanpi(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 checkAtanpiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanpiFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6b47dfb2l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testAtanpiFloat3Float3(inV, out);
+            verifyResultsAtanpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiFloat3Float3(inV, out);
+            verifyResultsAtanpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtanpi(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 checkAtanpiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkAtanpiFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x61630090l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testAtanpiFloat4Float4(inV, out);
+            verifyResultsAtanpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testAtanpiFloat4Float4(inV, out);
+            verifyResultsAtanpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testAtanpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsAtanpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeAtanpi(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 checkAtanpiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testAtanpi() {
+        checkAtanpiFloatFloat();
+        checkAtanpiFloat2Float2();
+        checkAtanpiFloat3Float3();
+        checkAtanpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.rs
new file mode 100644
index 0000000..501431a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testAtanpiFloatFloat(float inV) {
+    return atanpi(inV);
+}
+
+float2 __attribute__((kernel)) testAtanpiFloat2Float2(float2 inV) {
+    return atanpi(inV);
+}
+
+float3 __attribute__((kernel)) testAtanpiFloat3Float3(float3 inV) {
+    return atanpi(inV);
+}
+
+float4 __attribute__((kernel)) testAtanpiFloat4Float4(float4 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
new file mode 100644
index 0000000..16acf54
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestAtanpiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestAtanpi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.java
new file mode 100644
index 0000000..206b9bb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestCbrt extends RSBaseCompute {
+
+    private ScriptC_TestCbrt script;
+    private ScriptC_TestCbrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCbrt(mRS);
+        scriptRelaxed = new ScriptC_TestCbrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkCbrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x845561d4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCbrtFloatFloat(inV, out);
+            verifyResultsCbrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtFloatFloat(inV, out);
+            verifyResultsCbrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkCbrtFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCbrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x9129d518l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCbrtFloat2Float2(inV, out);
+            verifyResultsCbrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtFloat2Float2(inV, out);
+            verifyResultsCbrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCbrt(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 checkCbrtFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCbrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8744f5f6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCbrtFloat3Float3(inV, out);
+            verifyResultsCbrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtFloat3Float3(inV, out);
+            verifyResultsCbrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCbrt(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 checkCbrtFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCbrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7d6016d4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCbrtFloat4Float4(inV, out);
+            verifyResultsCbrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCbrtFloat4Float4(inV, out);
+            verifyResultsCbrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCbrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCbrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCbrt(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 checkCbrtFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testCbrt() {
+        checkCbrtFloatFloat();
+        checkCbrtFloat2Float2();
+        checkCbrtFloat3Float3();
+        checkCbrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.rs
new file mode 100644
index 0000000..a7ee6ee
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrt.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testCbrtFloatFloat(float inV) {
+    return cbrt(inV);
+}
+
+float2 __attribute__((kernel)) testCbrtFloat2Float2(float2 inV) {
+    return cbrt(inV);
+}
+
+float3 __attribute__((kernel)) testCbrtFloat3Float3(float3 inV) {
+    return cbrt(inV);
+}
+
+float4 __attribute__((kernel)) testCbrtFloat4Float4(float4 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
new file mode 100644
index 0000000..7e7f8bc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCbrtRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestCbrt.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.java
new file mode 100644
index 0000000..ea77e11
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestCeil extends RSBaseCompute {
+
+    private ScriptC_TestCeil script;
+    private ScriptC_TestCeilRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCeil(mRS);
+        scriptRelaxed = new ScriptC_TestCeilRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkCeilFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x492bf934l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCeilFloatFloat(inV, out);
+            verifyResultsCeilFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilFloatFloat(inV, out);
+            verifyResultsCeilFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCeil(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkCeilFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCeilFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x43152978l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCeilFloat2Float2(inV, out);
+            verifyResultsCeilFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilFloat2Float2(inV, out);
+            verifyResultsCeilFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCeil(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 checkCeilFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCeilFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x39304a56l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCeilFloat3Float3(inV, out);
+            verifyResultsCeilFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilFloat3Float3(inV, out);
+            verifyResultsCeilFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCeil(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 checkCeilFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCeilFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2f4b6b34l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCeilFloat4Float4(inV, out);
+            verifyResultsCeilFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCeilFloat4Float4(inV, out);
+            verifyResultsCeilFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCeilFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCeilFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCeil(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 checkCeilFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testCeil() {
+        checkCeilFloatFloat();
+        checkCeilFloat2Float2();
+        checkCeilFloat3Float3();
+        checkCeilFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.rs
new file mode 100644
index 0000000..39a4c19
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeil.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testCeilFloatFloat(float inV) {
+    return ceil(inV);
+}
+
+float2 __attribute__((kernel)) testCeilFloat2Float2(float2 inV) {
+    return ceil(inV);
+}
+
+float3 __attribute__((kernel)) testCeilFloat3Float3(float3 inV) {
+    return ceil(inV);
+}
+
+float4 __attribute__((kernel)) testCeilFloat4Float4(float4 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
new file mode 100644
index 0000000..90f2636
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCeilRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestCeil.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.java
new file mode 100644
index 0000000..8b0160c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.java
@@ -0,0 +1,5781 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestClamp extends RSBaseCompute {
+
+    private ScriptC_TestClamp script;
+    private ScriptC_TestClampRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestClamp(mRS);
+        scriptRelaxed = new ScriptC_TestClampRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloatFloat {
+        public float inValue;
+        public float inMinValue;
+        public float inMaxValue;
+        public Target.Floaty out;
+    }
+
+    private void checkClampFloatFloatFloatFloat() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc83c447dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x30234027l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc180322dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloatFloatFloatFloat(inValue, out);
+            verifyResultsClampFloatFloatFloatFloat(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloatFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloatFloatFloatFloat(inValue, out);
+            verifyResultsClampFloatFloatFloatFloat(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloatFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloatFloatFloatFloat(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (float) 42);
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (float) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (float) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeClamp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkClampFloatFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampFloat2Float2Float2Float2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x142b07a5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xea8fc01fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7becb225l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat2Float2Float2Float2(inValue, out);
+            verifyResultsClampFloat2Float2Float2Float2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat2Float2Float2Float2(inValue, out);
+            verifyResultsClampFloat2Float2Float2Float2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat2Float2Float2Float2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (float) 42);
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInMinValue, (float) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInMaxValue, (float) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 2 + j];
+                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);
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampFloat2Float2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampFloat3Float3Float3Float3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x30ad7481l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3946aa73l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcaa39c79l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat3Float3Float3Float3(inValue, out);
+            verifyResultsClampFloat3Float3Float3Float3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat3Float3Float3Float3(inValue, out);
+            verifyResultsClampFloat3Float3Float3Float3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat3Float3Float3Float3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (float) 42);
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (float) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (float) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                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);
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampFloat3Float3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampFloat4Float4Float4Float4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4d2fe15dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x87fd94c7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x195a86cdl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat4Float4Float4Float4(inValue, out);
+            verifyResultsClampFloat4Float4Float4Float4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat4Float4Float4Float4(inValue, out);
+            verifyResultsClampFloat4Float4Float4Float4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat4Float4Float4Float4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (float) 42);
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (float) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (float) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                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);
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampFloat4Float4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampFloat2FloatFloatFloat2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf1fca1a1l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1a6253d3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xabbf45d9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat2FloatFloatFloat2(inValue, out);
+            verifyResultsClampFloat2FloatFloatFloat2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2FloatFloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat2FloatFloatFloat2(inValue, out);
+            verifyResultsClampFloat2FloatFloatFloat2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat2FloatFloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat2FloatFloatFloat2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (float) 42);
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (float) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (float) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampFloat2FloatFloatFloat2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampFloat3FloatFloatFloat3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6ab8cf27l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4d90bbc5l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdeedadcbl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat3FloatFloatFloat3(inValue, out);
+            verifyResultsClampFloat3FloatFloatFloat3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3FloatFloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat3FloatFloatFloat3(inValue, out);
+            verifyResultsClampFloat3FloatFloatFloat3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat3FloatFloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat3FloatFloatFloat3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (float) 42);
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (float) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (float) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampFloat3FloatFloatFloat3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampFloat4FloatFloatFloat4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe374fcadl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x80bf23b7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x121c15bdl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampFloat4FloatFloatFloat4(inValue, out);
+            verifyResultsClampFloat4FloatFloatFloat4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4FloatFloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampFloat4FloatFloatFloat4(inValue, out);
+            verifyResultsClampFloat4FloatFloatFloat4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampFloat4FloatFloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampFloat4FloatFloatFloat4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        float[] arrayInValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (float) 42);
+        inValue.copyTo(arrayInValue);
+        float[] arrayInMinValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (float) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        float[] arrayInMaxValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (float) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampFloat4FloatFloatFloat4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharCharCharChar {
+        public byte inValue;
+        public byte inMinValue;
+        public byte inMaxValue;
+        public byte out;
+    }
+
+    private void checkClampCharCharCharChar() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xb673cf75l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x3c505c8fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xcdad4e95l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampCharCharCharChar(inValue, out);
+            verifyResultsClampCharCharCharChar(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampCharCharCharChar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampCharCharCharChar(inValue, out);
+            verifyResultsClampCharCharCharChar(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampCharCharCharChar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampCharCharCharChar(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkClampCharCharCharChar" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampChar2Char2Char2Char2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xc3feb45dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x3442bdc7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xc59fafcdl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar2Char2Char2Char2(inValue, out);
+            verifyResultsClampChar2Char2Char2Char2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2Char2Char2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar2Char2Char2Char2(inValue, out);
+            verifyResultsClampChar2Char2Char2Char2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2Char2Char2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar2Char2Char2Char2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampChar2Char2Char2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampChar3Char3Char3Char3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xb9d3b0a5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x470ecb1fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xd86bbd25l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar3Char3Char3Char3(inValue, out);
+            verifyResultsClampChar3Char3Char3Char3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3Char3Char3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar3Char3Char3Char3(inValue, out);
+            verifyResultsClampChar3Char3Char3Char3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3Char3Char3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar3Char3Char3Char3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampChar3Char3Char3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampChar4Char4Char4Char4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xafa8acedl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x59dad877l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xeb37ca7dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar4Char4Char4Char4(inValue, out);
+            verifyResultsClampChar4Char4Char4Char4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4Char4Char4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar4Char4Char4Char4(inValue, out);
+            verifyResultsClampChar4Char4Char4Char4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4Char4Char4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar4Char4Char4Char4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampChar4Char4Char4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharUcharUcharUchar {
+        public byte inValue;
+        public byte inMinValue;
+        public byte inMaxValue;
+        public byte out;
+    }
+
+    private void checkClampUcharUcharUcharUchar() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xa4447655l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x75336f2fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x6906135l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUcharUcharUcharUchar(inValue, out);
+            verifyResultsClampUcharUcharUcharUchar(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUcharUcharUcharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUcharUcharUcharUchar(inValue, out);
+            verifyResultsClampUcharUcharUcharUchar(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUcharUcharUcharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUcharUcharUcharUchar(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkClampUcharUcharUcharUchar" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUchar2Uchar2Uchar2Uchar2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x45dae301l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x662c1df3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xf7890ff9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar2Uchar2Uchar2Uchar2(inValue, out);
+            verifyResultsClampUchar2Uchar2Uchar2Uchar2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2Uchar2Uchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar2Uchar2Uchar2Uchar2(inValue, out);
+            verifyResultsClampUchar2Uchar2Uchar2Uchar2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2Uchar2Uchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar2Uchar2Uchar2Uchar2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUchar2Uchar2Uchar2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUchar3Uchar3Uchar3Uchar3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x625d4fddl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xb4e30847l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x463ffa4dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar3Uchar3Uchar3Uchar3(inValue, out);
+            verifyResultsClampUchar3Uchar3Uchar3Uchar3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3Uchar3Uchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar3Uchar3Uchar3Uchar3(inValue, out);
+            verifyResultsClampUchar3Uchar3Uchar3Uchar3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3Uchar3Uchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar3Uchar3Uchar3Uchar3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUchar3Uchar3Uchar3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUchar4Uchar4Uchar4Uchar4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x7edfbcb9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x399f29bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x94f6e4a1l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar4Uchar4Uchar4Uchar4(inValue, out);
+            verifyResultsClampUchar4Uchar4Uchar4Uchar4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4Uchar4Uchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar4Uchar4Uchar4Uchar4(inValue, out);
+            verifyResultsClampUchar4Uchar4Uchar4Uchar4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4Uchar4Uchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar4Uchar4Uchar4Uchar4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUchar4Uchar4Uchar4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortShortShortShort {
+        public short inValue;
+        public short inMinValue;
+        public short inMaxValue;
+        public short out;
+    }
+
+    private void checkClampShortShortShortShort() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x7fc993ddl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xb4661447l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x45c3064dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShortShortShortShort(inValue, out);
+            verifyResultsClampShortShortShortShort(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShortShortShortShort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShortShortShortShort(inValue, out);
+            verifyResultsClampShortShortShortShort(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShortShortShortShort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShortShortShortShort(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.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkClampShortShortShortShort" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampShort2Short2Short2Short2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x984e0915l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x2e67336fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xbfc42575l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort2Short2Short2Short2(inValue, out);
+            verifyResultsClampShort2Short2Short2Short2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2Short2Short2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort2Short2Short2Short2(inValue, out);
+            verifyResultsClampShort2Short2Short2Short2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2Short2Short2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort2Short2Short2Short2(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.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampShort2Short2Short2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampShort3Short3Short3Short3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xb4d075f1l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x7d1e1dc3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xe7b0fc9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort3Short3Short3Short3(inValue, out);
+            verifyResultsClampShort3Short3Short3Short3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3Short3Short3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort3Short3Short3Short3(inValue, out);
+            verifyResultsClampShort3Short3Short3Short3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3Short3Short3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort3Short3Short3Short3(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.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampShort3Short3Short3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampShort4Short4Short4Short4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xd152e2cdl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xcbd50817l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x5d31fa1dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort4Short4Short4Short4(inValue, out);
+            verifyResultsClampShort4Short4Short4Short4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4Short4Short4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort4Short4Short4Short4(inValue, out);
+            verifyResultsClampShort4Short4Short4Short4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4Short4Short4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort4Short4Short4Short4(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.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampShort4Short4Short4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortUshortUshortUshort {
+        public short inValue;
+        public short inMinValue;
+        public short inMaxValue;
+        public short out;
+    }
+
+    private void checkClampUshortUshortUshortUshort() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xf74c4341l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x94d3e2b3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x2630d4b9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshortUshortUshortUshort(inValue, out);
+            verifyResultsClampUshortUshortUshortUshort(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshortUshortUshortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshortUshortUshortUshort(inValue, out);
+            verifyResultsClampUshortUshortUshortUshort(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshortUshortUshortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshortUshortUshortUshort(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.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkClampUshortUshortUshortUshort" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUshort2Ushort2Ushort2Ushort2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xfc36b705l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x4fa3b43fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xe100a645l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort2Ushort2Ushort2Ushort2(inValue, out);
+            verifyResultsClampUshort2Ushort2Ushort2Ushort2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2Ushort2Ushort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort2Ushort2Ushort2Ushort2(inValue, out);
+            verifyResultsClampUshort2Ushort2Ushort2Ushort2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2Ushort2Ushort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort2Ushort2Ushort2Ushort2(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.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUshort2Ushort2Ushort2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUshort3Ushort3Ushort3Ushort3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xfc64ee3dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x610b3967l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xf2682b6dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort3Ushort3Ushort3Ushort3(inValue, out);
+            verifyResultsClampUshort3Ushort3Ushort3Ushort3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3Ushort3Ushort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort3Ushort3Ushort3Ushort3(inValue, out);
+            verifyResultsClampUshort3Ushort3Ushort3Ushort3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3Ushort3Ushort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort3Ushort3Ushort3Ushort3(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.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUshort3Ushort3Ushort3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUshort4Ushort4Ushort4Ushort4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xfc932575l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x7272be8fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x3cfb095l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort4Ushort4Ushort4Ushort4(inValue, out);
+            verifyResultsClampUshort4Ushort4Ushort4Ushort4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4Ushort4Ushort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort4Ushort4Ushort4Ushort4(inValue, out);
+            verifyResultsClampUshort4Ushort4Ushort4Ushort4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4Ushort4Ushort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort4Ushort4Ushort4Ushort4(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.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUshort4Ushort4Ushort4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntIntIntInt {
+        public int inValue;
+        public int inMinValue;
+        public int inMaxValue;
+        public int out;
+    }
+
+    private void checkClampIntIntIntInt() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xbe6164c5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x7c8bf97fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xde8eb85l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampIntIntIntInt(inValue, out);
+            verifyResultsClampIntIntIntInt(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampIntIntIntInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampIntIntIntInt(inValue, out);
+            verifyResultsClampIntIntIntInt(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampIntIntIntInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampIntIntIntInt(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkClampIntIntIntInt" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampInt2Int2Int2Int2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xbd307c01l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x9398f8f3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x24f5eaf9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt2Int2Int2Int2(inValue, out);
+            verifyResultsClampInt2Int2Int2Int2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2Int2Int2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt2Int2Int2Int2(inValue, out);
+            verifyResultsClampInt2Int2Int2Int2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2Int2Int2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt2Int2Int2Int2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampInt2Int2Int2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampInt3Int3Int3Int3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x5600d2edl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x9c7caa77l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x2dd99c7dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt3Int3Int3Int3(inValue, out);
+            verifyResultsClampInt3Int3Int3Int3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3Int3Int3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt3Int3Int3Int3(inValue, out);
+            verifyResultsClampInt3Int3Int3Int3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3Int3Int3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt3Int3Int3Int3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampInt3Int3Int3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampInt4Int4Int4Int4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xeed129d9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xa5605bfbl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x36bd4e01l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt4Int4Int4Int4(inValue, out);
+            verifyResultsClampInt4Int4Int4Int4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4Int4Int4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt4Int4Int4Int4(inValue, out);
+            verifyResultsClampInt4Int4Int4Int4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4Int4Int4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt4Int4Int4Int4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampInt4Int4Int4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintUintUintUint {
+        public int inValue;
+        public int inMinValue;
+        public int inMaxValue;
+        public int out;
+    }
+
+    private void checkClampUintUintUintUint() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xefc89475l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xce8b7b8fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x5fe86d95l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUintUintUintUint(inValue, out);
+            verifyResultsClampUintUintUintUint(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUintUintUintUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUintUintUintUint(inValue, out);
+            verifyResultsClampUintUintUintUint(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUintUintUintUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUintUintUintUint(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkClampUintUintUintUint" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUint2Uint2Uint2Uint2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x8873ae5dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xaa2a4bc7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x3b873dcdl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint2Uint2Uint2Uint2(inValue, out);
+            verifyResultsClampUint2Uint2Uint2Uint2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2Uint2Uint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint2Uint2Uint2Uint2(inValue, out);
+            verifyResultsClampUint2Uint2Uint2Uint2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2Uint2Uint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint2Uint2Uint2Uint2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUint2Uint2Uint2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUint3Uint3Uint3Uint3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x7e48aaa5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xbcf6591fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x4e534b25l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint3Uint3Uint3Uint3(inValue, out);
+            verifyResultsClampUint3Uint3Uint3Uint3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3Uint3Uint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint3Uint3Uint3Uint3(inValue, out);
+            verifyResultsClampUint3Uint3Uint3Uint3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3Uint3Uint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint3Uint3Uint3Uint3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUint3Uint3Uint3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUint4Uint4Uint4Uint4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x741da6edl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xcfc26677l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x611f587dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint4Uint4Uint4Uint4(inValue, out);
+            verifyResultsClampUint4Uint4Uint4Uint4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4Uint4Uint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint4Uint4Uint4Uint4(inValue, out);
+            verifyResultsClampUint4Uint4Uint4Uint4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4Uint4Uint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint4Uint4Uint4Uint4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUint4Uint4Uint4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongLongLongLong {
+        public long inValue;
+        public long inMinValue;
+        public long inMaxValue;
+        public long out;
+    }
+
+    private void checkClampLongLongLongLong() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x31c9c41dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x24ef4907l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0xb64c3b0dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampLongLongLongLong(inValue, out);
+            verifyResultsClampLongLongLongLong(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLongLongLongLong: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampLongLongLongLong(inValue, out);
+            verifyResultsClampLongLongLongLong(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLongLongLongLong: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampLongLongLongLong(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        long[] arrayOut = new long[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkClampLongLongLongLong" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampLong2Long2Long2Long2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xc2b0f12dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x4a3f8937l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xdb9c7b3dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampLong2Long2Long2Long2(inValue, out);
+            verifyResultsClampLong2Long2Long2Long2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong2Long2Long2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampLong2Long2Long2Long2(inValue, out);
+            verifyResultsClampLong2Long2Long2Long2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong2Long2Long2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampLong2Long2Long2Long2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampLong2Long2Long2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampLong3Long3Long3Long3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xb885ed75l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x5d0b968fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xee688895l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampLong3Long3Long3Long3(inValue, out);
+            verifyResultsClampLong3Long3Long3Long3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong3Long3Long3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampLong3Long3Long3Long3(inValue, out);
+            verifyResultsClampLong3Long3Long3Long3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong3Long3Long3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampLong3Long3Long3Long3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampLong3Long3Long3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampLong4Long4Long4Long4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xae5ae9bdl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x6fd7a3e7l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x13495edl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampLong4Long4Long4Long4(inValue, out);
+            verifyResultsClampLong4Long4Long4Long4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong4Long4Long4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampLong4Long4Long4Long4(inValue, out);
+            verifyResultsClampLong4Long4Long4Long4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong4Long4Long4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampLong4Long4Long4Long4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampLong4Long4Long4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongUlongUlongUlong {
+        public long inValue;
+        public long inMinValue;
+        public long inMaxValue;
+        public long out;
+    }
+
+    private void checkClampUlongUlongUlongUlong() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x749bf4c5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0xa8ca97fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x9be99b85l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUlongUlongUlongUlong(inValue, out);
+            verifyResultsClampUlongUlongUlongUlong(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlongUlongUlongUlong: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUlongUlongUlongUlong(inValue, out);
+            verifyResultsClampUlongUlongUlongUlong(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlongUlongUlongUlong: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUlongUlongUlongUlong(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        long[] arrayOut = new long[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
+                args.inValue = arrayInValue[i];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkClampUlongUlongUlongUlong" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUlong2Ulong2Ulong2Ulong2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xa09bb299l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xfe45623bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x8fa25441l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUlong2Ulong2Ulong2Ulong2(inValue, out);
+            verifyResultsClampUlong2Ulong2Ulong2Ulong2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong2Ulong2Ulong2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUlong2Ulong2Ulong2Ulong2(inValue, out);
+            verifyResultsClampUlong2Ulong2Ulong2Ulong2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong2Ulong2Ulong2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUlong2Ulong2Ulong2Ulong2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i * 2 + j];
+                args.inMaxValue = arrayInMaxValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUlong2Ulong2Ulong2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUlong3Ulong3Ulong3Ulong3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xbd1e1f75l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x4cfc4c8fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xde593e95l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUlong3Ulong3Ulong3Ulong3(inValue, out);
+            verifyResultsClampUlong3Ulong3Ulong3Ulong3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong3Ulong3Ulong3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUlong3Ulong3Ulong3Ulong3(inValue, out);
+            verifyResultsClampUlong3Ulong3Ulong3Ulong3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong3Ulong3Ulong3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUlong3Ulong3Ulong3Ulong3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUlong3Ulong3Ulong3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUlong4Ulong4Ulong4Ulong4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xd9a08c51l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x9bb336e3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x2d1028e9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUlong4Ulong4Ulong4Ulong4(inValue, out);
+            verifyResultsClampUlong4Ulong4Ulong4Ulong4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong4Ulong4Ulong4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUlong4Ulong4Ulong4Ulong4(inValue, out);
+            verifyResultsClampUlong4Ulong4Ulong4Ulong4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong4Ulong4Ulong4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUlong4Ulong4Ulong4Ulong4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i * 4 + j];
+                args.inMaxValue = arrayInMaxValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUlong4Ulong4Ulong4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampChar2CharCharChar2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x7c57a5d1l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xc3b7db63l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x5514cd69l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar2CharCharChar2(inValue, out);
+            verifyResultsClampChar2CharCharChar2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2CharCharChar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar2CharCharChar2(inValue, out);
+            verifyResultsClampChar2CharCharChar2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar2CharCharChar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar2CharCharChar2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampChar2CharCharChar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampChar3CharCharChar3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x65a26ee5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x492789dfl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xda847be5l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar3CharCharChar3(inValue, out);
+            verifyResultsClampChar3CharCharChar3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3CharCharChar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar3CharCharChar3(inValue, out);
+            verifyResultsClampChar3CharCharChar3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar3CharCharChar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar3CharCharChar3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampChar3CharCharChar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampChar4CharCharChar4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x4eed37f9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xce97385bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x5ff42a61l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampChar4CharCharChar4(inValue, out);
+            verifyResultsClampChar4CharCharChar4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4CharCharChar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampChar4CharCharChar4(inValue, out);
+            verifyResultsClampChar4CharCharChar4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampChar4CharCharChar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampChar4CharCharChar4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsCharCharCharChar args = new ArgumentsCharCharCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampChar4CharCharChar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUchar2UcharUcharUchar2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xf02e0d63l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xe9402039l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x7a9d123fl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar2UcharUcharUchar2(inValue, out);
+            verifyResultsClampUchar2UcharUcharUchar2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2UcharUcharUchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar2UcharUcharUchar2(inValue, out);
+            verifyResultsClampUchar2UcharUcharUchar2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar2UcharUcharUchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar2UcharUcharUchar2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUchar2UcharUcharUchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUchar3UcharUcharUchar3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x68ea3ae9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x1c6e882bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xadcb7a31l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar3UcharUcharUchar3(inValue, out);
+            verifyResultsClampUchar3UcharUcharUchar3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3UcharUcharUchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar3UcharUcharUchar3(inValue, out);
+            verifyResultsClampUchar3UcharUcharUchar3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar3UcharUcharUchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar3UcharUcharUchar3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUchar3UcharUcharUchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUchar4UcharUcharUchar4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xe1a6686fl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x4f9cf01dl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0xe0f9e223l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUchar4UcharUcharUchar4(inValue, out);
+            verifyResultsClampUchar4UcharUcharUchar4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4UcharUcharUchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUchar4UcharUcharUchar4(inValue, out);
+            verifyResultsClampUchar4UcharUcharUchar4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUchar4UcharUcharUchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUchar4UcharUcharUchar4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayInMinValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (byte) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        byte[] arrayInMaxValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (byte) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUcharUcharUcharUchar args = new ArgumentsUcharUcharUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUchar4UcharUcharUchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampShort2ShortShortShort2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xeae2d6a9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xcaca776bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x5c276971l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort2ShortShortShort2(inValue, out);
+            verifyResultsClampShort2ShortShortShort2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2ShortShortShort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort2ShortShortShort2(inValue, out);
+            verifyResultsClampShort2ShortShortShort2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort2ShortShortShort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort2ShortShortShort2(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.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampShort2ShortShortShort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampShort3ShortShortShort3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x639f042fl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xfdf8df5dl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x8f55d163l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort3ShortShortShort3(inValue, out);
+            verifyResultsClampShort3ShortShortShort3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3ShortShortShort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort3ShortShortShort3(inValue, out);
+            verifyResultsClampShort3ShortShortShort3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort3ShortShortShort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort3ShortShortShort3(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.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampShort3ShortShortShort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampShort4ShortShortShort4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xdc5b31b5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x3127474fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xc2843955l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampShort4ShortShortShort4(inValue, out);
+            verifyResultsClampShort4ShortShortShort4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4ShortShortShort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampShort4ShortShortShort4(inValue, out);
+            verifyResultsClampShort4ShortShortShort4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampShort4ShortShortShort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampShort4ShortShortShort4(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.
+                ArgumentsShortShortShortShort args = new ArgumentsShortShortShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampShort4ShortShortShort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUshort2UshortUshortUshort2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x5621ef07l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xc7874965l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x58e43b6bl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort2UshortUshortUshort2(inValue, out);
+            verifyResultsClampUshort2UshortUshortUshort2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2UshortUshortUshort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort2UshortUshortUshort2(inValue, out);
+            verifyResultsClampUshort2UshortUshortUshort2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort2UshortUshortUshort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort2UshortUshortUshort2(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.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUshort2UshortUshortUshort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUshort3UshortUshortUshort3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x7c9cd603l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xb3cf1419l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x452c061fl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort3UshortUshortUshort3(inValue, out);
+            verifyResultsClampUshort3UshortUshortUshort3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3UshortUshortUshort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort3UshortUshortUshort3(inValue, out);
+            verifyResultsClampUshort3UshortUshortUshort3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort3UshortUshortUshort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort3UshortUshortUshort3(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.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUshort3UshortUshortUshort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUshort4UshortUshortUshort4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xa317bcffl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xa016decdl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x3173d0d3l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUshort4UshortUshortUshort4(inValue, out);
+            verifyResultsClampUshort4UshortUshortUshort4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4UshortUshortUshort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUshort4UshortUshortUshort4(inValue, out);
+            verifyResultsClampUshort4UshortUshortUshort4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUshort4UshortUshortUshort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUshort4UshortUshortUshort4(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.
+                ArgumentsUshortUshortUshortUshort args = new ArgumentsUshortUshortUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUshort4UshortUshortUshort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampInt2IntIntInt2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x7906d1dbl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xfba24121l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x8cff3327l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt2IntIntInt2(inValue, out);
+            verifyResultsClampInt2IntIntInt2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2IntIntInt2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt2IntIntInt2(inValue, out);
+            verifyResultsClampInt2IntIntInt2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt2IntIntInt2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt2IntIntInt2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampInt2IntIntInt2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampInt3IntIntInt3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xb5370be9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xf1a08b2bl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x82fd7d31l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt3IntIntInt3(inValue, out);
+            verifyResultsClampInt3IntIntInt3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3IntIntInt3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt3IntIntInt3(inValue, out);
+            verifyResultsClampInt3IntIntInt3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt3IntIntInt3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt3IntIntInt3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampInt3IntIntInt3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampInt4IntIntInt4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xf16745f7l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xe79ed535l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x78fbc73bl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampInt4IntIntInt4(inValue, out);
+            verifyResultsClampInt4IntIntInt4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4IntIntInt4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampInt4IntIntInt4(inValue, out);
+            verifyResultsClampInt4IntIntInt4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampInt4IntIntInt4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampInt4IntIntInt4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsIntIntIntInt args = new ArgumentsIntIntIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampInt4IntIntInt4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUint2UintUintUint2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x770d5a51l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xc2a180e3l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x53fe72e9l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint2UintUintUint2(inValue, out);
+            verifyResultsClampUint2UintUintUint2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2UintUintUint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint2UintUintUint2(inValue, out);
+            verifyResultsClampUint2UintUintUint2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint2UintUintUint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint2UintUintUint2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUint2UintUintUint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUint3UintUintUint3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x60582365l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x48112f5fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xd96e2165l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint3UintUintUint3(inValue, out);
+            verifyResultsClampUint3UintUintUint3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3UintUintUint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint3UintUintUint3(inValue, out);
+            verifyResultsClampUint3UintUintUint3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint3UintUintUint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint3UintUintUint3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUint3UintUintUint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUint4UintUintUint4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x49a2ec79l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xcd80dddbl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x5eddcfe1l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUint4UintUintUint4(inValue, out);
+            verifyResultsClampUint4UintUintUint4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4UintUintUint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUint4UintUintUint4(inValue, out);
+            verifyResultsClampUint4UintUintUint4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUint4UintUintUint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUint4UintUintUint4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayInMinValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (int) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        int[] arrayInMaxValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (int) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUintUintUintUint args = new ArgumentsUintUintUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUint4UintUintUint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampLong2LongLongLong2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x7c535bb5l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x8f83654fl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x20e05755l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampLong2LongLongLong2(inValue, out);
+            verifyResultsClampLong2LongLongLong2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong2LongLongLong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampLong2LongLongLong2(inValue, out);
+            verifyResultsClampLong2LongLongLong2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong2LongLongLong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampLong2LongLongLong2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampLong2LongLongLong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampLong3LongLongLong3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x659e24c9l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x14f313cbl, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0xa65005d1l, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampLong3LongLongLong3(inValue, out);
+            verifyResultsClampLong3LongLongLong3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong3LongLongLong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampLong3LongLongLong3(inValue, out);
+            verifyResultsClampLong3LongLongLong3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong3LongLongLong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampLong3LongLongLong3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampLong3LongLongLong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampLong4LongLongLong4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x4ee8edddl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x9a62c247l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x2bbfb44dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampLong4LongLongLong4(inValue, out);
+            verifyResultsClampLong4LongLongLong4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong4LongLongLong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampLong4LongLongLong4(inValue, out);
+            verifyResultsClampLong4LongLongLong4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampLong4LongLongLong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampLong4LongLongLong4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsLongLongLongLong args = new ArgumentsLongLongLongLong();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampLong4LongLongLong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUlong2UlongUlongUlong2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xa7fa1bf7l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x8d13b735l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x1e70a93bl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUlong2UlongUlongUlong2(inValue, out);
+            verifyResultsClampUlong2UlongUlongUlong2(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong2UlongUlongUlong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUlong2UlongUlongUlong2(inValue, out);
+            verifyResultsClampUlong2UlongUlongUlong2(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong2UlongUlongUlong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUlong2UlongUlongUlong2(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
+                args.inValue = arrayInValue[i * 2 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUlong2UlongUlongUlong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUlong3UlongUlongUlong3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x20b6497dl, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0xc0421f27l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x519f112dl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUlong3UlongUlongUlong3(inValue, out);
+            verifyResultsClampUlong3UlongUlongUlong3(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong3UlongUlongUlong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUlong3UlongUlongUlong3(inValue, out);
+            verifyResultsClampUlong3UlongUlongUlong3(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong3UlongUlongUlong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUlong3UlongUlongUlong3(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUlong3UlongUlongUlong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClampUlong4UlongUlongUlong4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x99727703l, false);
+        Allocation inMinValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0xf3708719l, false);
+        Allocation inMaxValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x84cd791fl, false);
+        enforceOrdering(inMinValue, inMaxValue);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.set_gAllocInMinValue(inMinValue);
+            script.set_gAllocInMaxValue(inMaxValue);
+            script.forEach_testClampUlong4UlongUlongUlong4(inValue, out);
+            verifyResultsClampUlong4UlongUlongUlong4(inValue, inMinValue, inMaxValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong4UlongUlongUlong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMinValue(inMinValue);
+            scriptRelaxed.set_gAllocInMaxValue(inMaxValue);
+            scriptRelaxed.forEach_testClampUlong4UlongUlongUlong4(inValue, out);
+            verifyResultsClampUlong4UlongUlongUlong4(inValue, inMinValue, inMaxValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClampUlong4UlongUlongUlong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClampUlong4UlongUlongUlong4(Allocation inValue, Allocation inMinValue, Allocation inMaxValue, Allocation out, boolean relaxed) {
+        long[] arrayInValue = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (long) 42);
+        inValue.copyTo(arrayInValue);
+        long[] arrayInMinValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMinValue, (long) 42);
+        inMinValue.copyTo(arrayInMinValue);
+        long[] arrayInMaxValue = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInMaxValue, (long) 42);
+        inMaxValue.copyTo(arrayInMaxValue);
+        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.
+                ArgumentsUlongUlongUlongUlong args = new ArgumentsUlongUlongUlongUlong();
+                args.inValue = arrayInValue[i * 4 + j];
+                args.inMinValue = arrayInMinValue[i];
+                args.inMaxValue = arrayInMaxValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClamp(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 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]);
+                        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 checkClampUlong4UlongUlongUlong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testClamp() {
+        checkClampFloatFloatFloatFloat();
+        checkClampFloat2Float2Float2Float2();
+        checkClampFloat3Float3Float3Float3();
+        checkClampFloat4Float4Float4Float4();
+        checkClampFloat2FloatFloatFloat2();
+        checkClampFloat3FloatFloatFloat3();
+        checkClampFloat4FloatFloatFloat4();
+        checkClampCharCharCharChar();
+        checkClampChar2Char2Char2Char2();
+        checkClampChar3Char3Char3Char3();
+        checkClampChar4Char4Char4Char4();
+        checkClampUcharUcharUcharUchar();
+        checkClampUchar2Uchar2Uchar2Uchar2();
+        checkClampUchar3Uchar3Uchar3Uchar3();
+        checkClampUchar4Uchar4Uchar4Uchar4();
+        checkClampShortShortShortShort();
+        checkClampShort2Short2Short2Short2();
+        checkClampShort3Short3Short3Short3();
+        checkClampShort4Short4Short4Short4();
+        checkClampUshortUshortUshortUshort();
+        checkClampUshort2Ushort2Ushort2Ushort2();
+        checkClampUshort3Ushort3Ushort3Ushort3();
+        checkClampUshort4Ushort4Ushort4Ushort4();
+        checkClampIntIntIntInt();
+        checkClampInt2Int2Int2Int2();
+        checkClampInt3Int3Int3Int3();
+        checkClampInt4Int4Int4Int4();
+        checkClampUintUintUintUint();
+        checkClampUint2Uint2Uint2Uint2();
+        checkClampUint3Uint3Uint3Uint3();
+        checkClampUint4Uint4Uint4Uint4();
+        checkClampLongLongLongLong();
+        checkClampLong2Long2Long2Long2();
+        checkClampLong3Long3Long3Long3();
+        checkClampLong4Long4Long4Long4();
+        checkClampUlongUlongUlongUlong();
+        checkClampUlong2Ulong2Ulong2Ulong2();
+        checkClampUlong3Ulong3Ulong3Ulong3();
+        checkClampUlong4Ulong4Ulong4Ulong4();
+        checkClampChar2CharCharChar2();
+        checkClampChar3CharCharChar3();
+        checkClampChar4CharCharChar4();
+        checkClampUchar2UcharUcharUchar2();
+        checkClampUchar3UcharUcharUchar3();
+        checkClampUchar4UcharUcharUchar4();
+        checkClampShort2ShortShortShort2();
+        checkClampShort3ShortShortShort3();
+        checkClampShort4ShortShortShort4();
+        checkClampUshort2UshortUshortUshort2();
+        checkClampUshort3UshortUshortUshort3();
+        checkClampUshort4UshortUshortUshort4();
+        checkClampInt2IntIntInt2();
+        checkClampInt3IntIntInt3();
+        checkClampInt4IntIntInt4();
+        checkClampUint2UintUintUint2();
+        checkClampUint3UintUintUint3();
+        checkClampUint4UintUintUint4();
+        checkClampLong2LongLongLong2();
+        checkClampLong3LongLongLong3();
+        checkClampLong4LongLongLong4();
+        checkClampUlong2UlongUlongUlong2();
+        checkClampUlong3UlongUlongUlong3();
+        checkClampUlong4UlongUlongUlong4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.rs
new file mode 100644
index 0000000..6035974
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClamp.rs
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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)
+
+rs_allocation gAllocInMinValue;
+rs_allocation gAllocInMaxValue;
+
+float __attribute__((kernel)) testClampFloatFloatFloatFloat(float inValue, unsigned int x) {
+    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
+    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float2 __attribute__((kernel)) testClampFloat2Float2Float2Float2(float2 inValue, unsigned int x) {
+    float2 inMinValue = rsGetElementAt_float2(gAllocInMinValue, x);
+    float2 inMaxValue = rsGetElementAt_float2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float3 __attribute__((kernel)) testClampFloat3Float3Float3Float3(float3 inValue, unsigned int x) {
+    float3 inMinValue = rsGetElementAt_float3(gAllocInMinValue, x);
+    float3 inMaxValue = rsGetElementAt_float3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float4 __attribute__((kernel)) testClampFloat4Float4Float4Float4(float4 inValue, unsigned int x) {
+    float4 inMinValue = rsGetElementAt_float4(gAllocInMinValue, x);
+    float4 inMaxValue = rsGetElementAt_float4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float2 __attribute__((kernel)) testClampFloat2FloatFloatFloat2(float2 inValue, unsigned int x) {
+    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
+    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float3 __attribute__((kernel)) testClampFloat3FloatFloatFloat3(float3 inValue, unsigned int x) {
+    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
+    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+float4 __attribute__((kernel)) testClampFloat4FloatFloatFloat4(float4 inValue, unsigned int x) {
+    float inMinValue = rsGetElementAt_float(gAllocInMinValue, x);
+    float inMaxValue = rsGetElementAt_float(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char __attribute__((kernel)) testClampCharCharCharChar(char inValue, unsigned int x) {
+    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
+    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char2 __attribute__((kernel)) testClampChar2Char2Char2Char2(char2 inValue, unsigned int x) {
+    char2 inMinValue = rsGetElementAt_char2(gAllocInMinValue, x);
+    char2 inMaxValue = rsGetElementAt_char2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char3 __attribute__((kernel)) testClampChar3Char3Char3Char3(char3 inValue, unsigned int x) {
+    char3 inMinValue = rsGetElementAt_char3(gAllocInMinValue, x);
+    char3 inMaxValue = rsGetElementAt_char3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char4 __attribute__((kernel)) testClampChar4Char4Char4Char4(char4 inValue, unsigned int x) {
+    char4 inMinValue = rsGetElementAt_char4(gAllocInMinValue, x);
+    char4 inMaxValue = rsGetElementAt_char4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar __attribute__((kernel)) testClampUcharUcharUcharUchar(uchar inValue, unsigned int x) {
+    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
+    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar2 __attribute__((kernel)) testClampUchar2Uchar2Uchar2Uchar2(uchar2 inValue, unsigned int x) {
+    uchar2 inMinValue = rsGetElementAt_uchar2(gAllocInMinValue, x);
+    uchar2 inMaxValue = rsGetElementAt_uchar2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar3 __attribute__((kernel)) testClampUchar3Uchar3Uchar3Uchar3(uchar3 inValue, unsigned int x) {
+    uchar3 inMinValue = rsGetElementAt_uchar3(gAllocInMinValue, x);
+    uchar3 inMaxValue = rsGetElementAt_uchar3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar4 __attribute__((kernel)) testClampUchar4Uchar4Uchar4Uchar4(uchar4 inValue, unsigned int x) {
+    uchar4 inMinValue = rsGetElementAt_uchar4(gAllocInMinValue, x);
+    uchar4 inMaxValue = rsGetElementAt_uchar4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short __attribute__((kernel)) testClampShortShortShortShort(short inValue, unsigned int x) {
+    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
+    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short2 __attribute__((kernel)) testClampShort2Short2Short2Short2(short2 inValue, unsigned int x) {
+    short2 inMinValue = rsGetElementAt_short2(gAllocInMinValue, x);
+    short2 inMaxValue = rsGetElementAt_short2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short3 __attribute__((kernel)) testClampShort3Short3Short3Short3(short3 inValue, unsigned int x) {
+    short3 inMinValue = rsGetElementAt_short3(gAllocInMinValue, x);
+    short3 inMaxValue = rsGetElementAt_short3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short4 __attribute__((kernel)) testClampShort4Short4Short4Short4(short4 inValue, unsigned int x) {
+    short4 inMinValue = rsGetElementAt_short4(gAllocInMinValue, x);
+    short4 inMaxValue = rsGetElementAt_short4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort __attribute__((kernel)) testClampUshortUshortUshortUshort(ushort inValue, unsigned int x) {
+    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
+    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort2 __attribute__((kernel)) testClampUshort2Ushort2Ushort2Ushort2(ushort2 inValue, unsigned int x) {
+    ushort2 inMinValue = rsGetElementAt_ushort2(gAllocInMinValue, x);
+    ushort2 inMaxValue = rsGetElementAt_ushort2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort3 __attribute__((kernel)) testClampUshort3Ushort3Ushort3Ushort3(ushort3 inValue, unsigned int x) {
+    ushort3 inMinValue = rsGetElementAt_ushort3(gAllocInMinValue, x);
+    ushort3 inMaxValue = rsGetElementAt_ushort3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort4 __attribute__((kernel)) testClampUshort4Ushort4Ushort4Ushort4(ushort4 inValue, unsigned int x) {
+    ushort4 inMinValue = rsGetElementAt_ushort4(gAllocInMinValue, x);
+    ushort4 inMaxValue = rsGetElementAt_ushort4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int __attribute__((kernel)) testClampIntIntIntInt(int inValue, unsigned int x) {
+    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
+    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int2 __attribute__((kernel)) testClampInt2Int2Int2Int2(int2 inValue, unsigned int x) {
+    int2 inMinValue = rsGetElementAt_int2(gAllocInMinValue, x);
+    int2 inMaxValue = rsGetElementAt_int2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int3 __attribute__((kernel)) testClampInt3Int3Int3Int3(int3 inValue, unsigned int x) {
+    int3 inMinValue = rsGetElementAt_int3(gAllocInMinValue, x);
+    int3 inMaxValue = rsGetElementAt_int3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int4 __attribute__((kernel)) testClampInt4Int4Int4Int4(int4 inValue, unsigned int x) {
+    int4 inMinValue = rsGetElementAt_int4(gAllocInMinValue, x);
+    int4 inMaxValue = rsGetElementAt_int4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint __attribute__((kernel)) testClampUintUintUintUint(uint inValue, unsigned int x) {
+    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
+    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint2 __attribute__((kernel)) testClampUint2Uint2Uint2Uint2(uint2 inValue, unsigned int x) {
+    uint2 inMinValue = rsGetElementAt_uint2(gAllocInMinValue, x);
+    uint2 inMaxValue = rsGetElementAt_uint2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint3 __attribute__((kernel)) testClampUint3Uint3Uint3Uint3(uint3 inValue, unsigned int x) {
+    uint3 inMinValue = rsGetElementAt_uint3(gAllocInMinValue, x);
+    uint3 inMaxValue = rsGetElementAt_uint3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint4 __attribute__((kernel)) testClampUint4Uint4Uint4Uint4(uint4 inValue, unsigned int x) {
+    uint4 inMinValue = rsGetElementAt_uint4(gAllocInMinValue, x);
+    uint4 inMaxValue = rsGetElementAt_uint4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+long __attribute__((kernel)) testClampLongLongLongLong(long inValue, unsigned int x) {
+    long inMinValue = rsGetElementAt_long(gAllocInMinValue, x);
+    long inMaxValue = rsGetElementAt_long(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+long2 __attribute__((kernel)) testClampLong2Long2Long2Long2(long2 inValue, unsigned int x) {
+    long2 inMinValue = rsGetElementAt_long2(gAllocInMinValue, x);
+    long2 inMaxValue = rsGetElementAt_long2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+long3 __attribute__((kernel)) testClampLong3Long3Long3Long3(long3 inValue, unsigned int x) {
+    long3 inMinValue = rsGetElementAt_long3(gAllocInMinValue, x);
+    long3 inMaxValue = rsGetElementAt_long3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+long4 __attribute__((kernel)) testClampLong4Long4Long4Long4(long4 inValue, unsigned int x) {
+    long4 inMinValue = rsGetElementAt_long4(gAllocInMinValue, x);
+    long4 inMaxValue = rsGetElementAt_long4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ulong __attribute__((kernel)) testClampUlongUlongUlongUlong(ulong inValue, unsigned int x) {
+    ulong inMinValue = rsGetElementAt_ulong(gAllocInMinValue, x);
+    ulong inMaxValue = rsGetElementAt_ulong(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ulong2 __attribute__((kernel)) testClampUlong2Ulong2Ulong2Ulong2(ulong2 inValue, unsigned int x) {
+    ulong2 inMinValue = rsGetElementAt_ulong2(gAllocInMinValue, x);
+    ulong2 inMaxValue = rsGetElementAt_ulong2(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ulong3 __attribute__((kernel)) testClampUlong3Ulong3Ulong3Ulong3(ulong3 inValue, unsigned int x) {
+    ulong3 inMinValue = rsGetElementAt_ulong3(gAllocInMinValue, x);
+    ulong3 inMaxValue = rsGetElementAt_ulong3(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ulong4 __attribute__((kernel)) testClampUlong4Ulong4Ulong4Ulong4(ulong4 inValue, unsigned int x) {
+    ulong4 inMinValue = rsGetElementAt_ulong4(gAllocInMinValue, x);
+    ulong4 inMaxValue = rsGetElementAt_ulong4(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char2 __attribute__((kernel)) testClampChar2CharCharChar2(char2 inValue, unsigned int x) {
+    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
+    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char3 __attribute__((kernel)) testClampChar3CharCharChar3(char3 inValue, unsigned int x) {
+    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
+    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+char4 __attribute__((kernel)) testClampChar4CharCharChar4(char4 inValue, unsigned int x) {
+    char inMinValue = rsGetElementAt_char(gAllocInMinValue, x);
+    char inMaxValue = rsGetElementAt_char(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar2 __attribute__((kernel)) testClampUchar2UcharUcharUchar2(uchar2 inValue, unsigned int x) {
+    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
+    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar3 __attribute__((kernel)) testClampUchar3UcharUcharUchar3(uchar3 inValue, unsigned int x) {
+    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
+    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uchar4 __attribute__((kernel)) testClampUchar4UcharUcharUchar4(uchar4 inValue, unsigned int x) {
+    uchar inMinValue = rsGetElementAt_uchar(gAllocInMinValue, x);
+    uchar inMaxValue = rsGetElementAt_uchar(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short2 __attribute__((kernel)) testClampShort2ShortShortShort2(short2 inValue, unsigned int x) {
+    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
+    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short3 __attribute__((kernel)) testClampShort3ShortShortShort3(short3 inValue, unsigned int x) {
+    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
+    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+short4 __attribute__((kernel)) testClampShort4ShortShortShort4(short4 inValue, unsigned int x) {
+    short inMinValue = rsGetElementAt_short(gAllocInMinValue, x);
+    short inMaxValue = rsGetElementAt_short(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort2 __attribute__((kernel)) testClampUshort2UshortUshortUshort2(ushort2 inValue, unsigned int x) {
+    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
+    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort3 __attribute__((kernel)) testClampUshort3UshortUshortUshort3(ushort3 inValue, unsigned int x) {
+    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
+    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ushort4 __attribute__((kernel)) testClampUshort4UshortUshortUshort4(ushort4 inValue, unsigned int x) {
+    ushort inMinValue = rsGetElementAt_ushort(gAllocInMinValue, x);
+    ushort inMaxValue = rsGetElementAt_ushort(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int2 __attribute__((kernel)) testClampInt2IntIntInt2(int2 inValue, unsigned int x) {
+    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
+    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int3 __attribute__((kernel)) testClampInt3IntIntInt3(int3 inValue, unsigned int x) {
+    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
+    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+int4 __attribute__((kernel)) testClampInt4IntIntInt4(int4 inValue, unsigned int x) {
+    int inMinValue = rsGetElementAt_int(gAllocInMinValue, x);
+    int inMaxValue = rsGetElementAt_int(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint2 __attribute__((kernel)) testClampUint2UintUintUint2(uint2 inValue, unsigned int x) {
+    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
+    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint3 __attribute__((kernel)) testClampUint3UintUintUint3(uint3 inValue, unsigned int x) {
+    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
+    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+uint4 __attribute__((kernel)) testClampUint4UintUintUint4(uint4 inValue, unsigned int x) {
+    uint inMinValue = rsGetElementAt_uint(gAllocInMinValue, x);
+    uint inMaxValue = rsGetElementAt_uint(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+long2 __attribute__((kernel)) testClampLong2LongLongLong2(long2 inValue, unsigned int x) {
+    long inMinValue = rsGetElementAt_long(gAllocInMinValue, x);
+    long inMaxValue = rsGetElementAt_long(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+long3 __attribute__((kernel)) testClampLong3LongLongLong3(long3 inValue, unsigned int x) {
+    long inMinValue = rsGetElementAt_long(gAllocInMinValue, x);
+    long inMaxValue = rsGetElementAt_long(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+long4 __attribute__((kernel)) testClampLong4LongLongLong4(long4 inValue, unsigned int x) {
+    long inMinValue = rsGetElementAt_long(gAllocInMinValue, x);
+    long inMaxValue = rsGetElementAt_long(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ulong2 __attribute__((kernel)) testClampUlong2UlongUlongUlong2(ulong2 inValue, unsigned int x) {
+    ulong inMinValue = rsGetElementAt_ulong(gAllocInMinValue, x);
+    ulong inMaxValue = rsGetElementAt_ulong(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ulong3 __attribute__((kernel)) testClampUlong3UlongUlongUlong3(ulong3 inValue, unsigned int x) {
+    ulong inMinValue = rsGetElementAt_ulong(gAllocInMinValue, x);
+    ulong inMaxValue = rsGetElementAt_ulong(gAllocInMaxValue, x);
+    return clamp(inValue, inMinValue, inMaxValue);
+}
+
+ulong4 __attribute__((kernel)) testClampUlong4UlongUlongUlong4(ulong4 inValue, unsigned int x) {
+    ulong inMinValue = rsGetElementAt_ulong(gAllocInMinValue, x);
+    ulong inMaxValue = rsGetElementAt_ulong(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
new file mode 100644
index 0000000..6d9474d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClampRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestClamp.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.java
new file mode 100644
index 0000000..d2fe5df
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.java
@@ -0,0 +1,1727 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestClz extends RSBaseCompute {
+
+    private ScriptC_TestClz script;
+    private ScriptC_TestClzRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestClz(mRS);
+        scriptRelaxed = new ScriptC_TestClzRelaxed(mRS);
+    }
+
+    public class ArgumentsCharChar {
+        public byte inValue;
+        public byte out;
+    }
+
+    private void checkClzCharChar() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0x2f7765afl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            script.forEach_testClzCharChar(inValue, out);
+            verifyResultsClzCharChar(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzCharChar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzCharChar(inValue, out);
+            verifyResultsClzCharChar(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzCharChar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzCharChar(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        if (args.out != 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 checkClzCharChar" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzChar2Char2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xcaca5e93l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testClzChar2Char2(inValue, out);
+            verifyResultsClzChar2Char2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzChar2Char2(inValue, out);
+            verifyResultsClzChar2Char2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzChar2Char2(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        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 checkClzChar2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzChar3Char3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xc7099347l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testClzChar3Char3(inValue, out);
+            verifyResultsClzChar3Char3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzChar3Char3(inValue, out);
+            verifyResultsClzChar3Char3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzChar3Char3(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzChar3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzChar4Char4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xc348c7fbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testClzChar4Char4(inValue, out);
+            verifyResultsClzChar4Char4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzChar4Char4(inValue, out);
+            verifyResultsClzChar4Char4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzChar4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzChar4Char4(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzChar4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharUchar {
+        public byte inValue;
+        public byte out;
+    }
+
+    private void checkClzUcharUchar() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x8b84f57fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.forEach_testClzUcharUchar(inValue, out);
+            verifyResultsClzUcharUchar(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUcharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUcharUchar(inValue, out);
+            verifyResultsClzUcharUchar(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUcharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUcharUchar(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        if (args.out != 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 checkClzUcharUchar" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzUchar2Uchar2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xf47ebc85l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testClzUchar2Uchar2(inValue, out);
+            verifyResultsClzUchar2Uchar2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUchar2Uchar2(inValue, out);
+            verifyResultsClzUchar2Uchar2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUchar2Uchar2(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        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 checkClzUchar2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzUchar3Uchar3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x3dbce203l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testClzUchar3Uchar3(inValue, out);
+            verifyResultsClzUchar3Uchar3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUchar3Uchar3(inValue, out);
+            verifyResultsClzUchar3Uchar3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUchar3Uchar3(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzUchar3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzUchar4Uchar4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x86fb0781l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testClzUchar4Uchar4(inValue, out);
+            verifyResultsClzUchar4Uchar4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUchar4Uchar4(inValue, out);
+            verifyResultsClzUchar4Uchar4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUchar4Uchar4(Allocation inValue, Allocation out, boolean relaxed) {
+        byte[] arrayInValue = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (byte) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzUchar4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortShort {
+        public short inValue;
+        public short out;
+    }
+
+    private void checkClzShortShort() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xd8ad53l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            script.forEach_testClzShortShort(inValue, out);
+            verifyResultsClzShortShort(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShortShort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzShortShort(inValue, out);
+            verifyResultsClzShortShort(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShortShort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzShortShort(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        if (args.out != 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 checkClzShortShort" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzShort2Short2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x42dd6ebfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testClzShort2Short2(inValue, out);
+            verifyResultsClzShort2Short2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzShort2Short2(inValue, out);
+            verifyResultsClzShort2Short2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzShort2Short2(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        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 checkClzShort2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzShort3Short3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x8c1b943dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testClzShort3Short3(inValue, out);
+            verifyResultsClzShort3Short3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzShort3Short3(inValue, out);
+            verifyResultsClzShort3Short3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzShort3Short3(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzShort3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzShort4Short4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xd559b9bbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testClzShort4Short4(inValue, out);
+            verifyResultsClzShort4Short4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzShort4Short4(inValue, out);
+            verifyResultsClzShort4Short4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzShort4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzShort4Short4(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzShort4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortUshort {
+        public short inValue;
+        public short out;
+    }
+
+    private void checkClzUshortUshort() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0x2c0103a5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.forEach_testClzUshortUshort(inValue, out);
+            verifyResultsClzUshortUshort(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUshortUshort(inValue, out);
+            verifyResultsClzUshortUshort(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUshortUshort(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        if (args.out != 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 checkClzUshortUshort" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzUshort2Ushort2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xb2913837l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testClzUshort2Ushort2(inValue, out);
+            verifyResultsClzUshort2Ushort2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUshort2Ushort2(inValue, out);
+            verifyResultsClzUshort2Ushort2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUshort2Ushort2(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        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 checkClzUshort2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzUshort3Ushort3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xeaa1cfa3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testClzUshort3Ushort3(inValue, out);
+            verifyResultsClzUshort3Ushort3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUshort3Ushort3(inValue, out);
+            verifyResultsClzUshort3Ushort3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUshort3Ushort3(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzUshort3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzUshort4Ushort4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x22b2670fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testClzUshort4Ushort4(inValue, out);
+            verifyResultsClzUshort4Ushort4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUshort4Ushort4(inValue, out);
+            verifyResultsClzUshort4Ushort4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUshort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUshort4Ushort4(Allocation inValue, Allocation out, boolean relaxed) {
+        short[] arrayInValue = new short[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (short) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzUshort4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntInt {
+        public int inValue;
+        public int out;
+    }
+
+    private void checkClzIntInt() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x3142eb97l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.forEach_testClzIntInt(inValue, out);
+            verifyResultsClzIntInt(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzIntInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzIntInt(inValue, out);
+            verifyResultsClzIntInt(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzIntInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzIntInt(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        if (args.out != 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 checkClzIntInt" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzInt2Int2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x27fe3ad5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testClzInt2Int2(inValue, out);
+            verifyResultsClzInt2Int2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzInt2Int2(inValue, out);
+            verifyResultsClzInt2Int2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzInt2Int2(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        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 checkClzInt2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzInt3Int3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xf2d24c2bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testClzInt3Int3(inValue, out);
+            verifyResultsClzInt3Int3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzInt3Int3(inValue, out);
+            verifyResultsClzInt3Int3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzInt3Int3(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzInt3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzInt4Int4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xbda65d81l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testClzInt4Int4(inValue, out);
+            verifyResultsClzInt4Int4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzInt4Int4(inValue, out);
+            verifyResultsClzInt4Int4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzInt4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzInt4Int4(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzInt4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintUint {
+        public int inValue;
+        public int out;
+    }
+
+    private void checkClzUintUint() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x75ac502fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.forEach_testClzUintUint(inValue, out);
+            verifyResultsClzUintUint(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUintUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUintUint(inValue, out);
+            verifyResultsClzUintUint(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUintUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUintUint(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inValue = arrayInValue[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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("Expected output out: ");
+                        appendVariableToMessage(message, args.out);
+                        message.append("\n");
+                        message.append("Actual   output out: ");
+                        appendVariableToMessage(message, arrayOut[i * 1 + j]);
+                        if (args.out != 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 checkClzUintUint" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzUint2Uint2() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x29344f93l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testClzUint2Uint2(inValue, out);
+            verifyResultsClzUint2Uint2(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUint2Uint2(inValue, out);
+            verifyResultsClzUint2Uint2(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUint2Uint2(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inValue = arrayInValue[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        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 checkClzUint2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzUint3Uint3() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x25738447l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testClzUint3Uint3(inValue, out);
+            verifyResultsClzUint3Uint3(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUint3Uint3(inValue, out);
+            verifyResultsClzUint3Uint3(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUint3Uint3(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzUint3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkClzUint4Uint4() {
+        Allocation inValue = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x21b2b8fbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testClzUint4Uint4(inValue, out);
+            verifyResultsClzUint4Uint4(inValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testClzUint4Uint4(inValue, out);
+            verifyResultsClzUint4Uint4(inValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testClzUint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsClzUint4Uint4(Allocation inValue, Allocation out, boolean relaxed) {
+        int[] arrayInValue = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInValue, (int) 42);
+        inValue.copyTo(arrayInValue);
+        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.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inValue = arrayInValue[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeClz(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 inValue: ");
+                        appendVariableToMessage(message, args.inValue);
+                        message.append("\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 checkClzUint4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testClz() {
+        checkClzCharChar();
+        checkClzChar2Char2();
+        checkClzChar3Char3();
+        checkClzChar4Char4();
+        checkClzUcharUchar();
+        checkClzUchar2Uchar2();
+        checkClzUchar3Uchar3();
+        checkClzUchar4Uchar4();
+        checkClzShortShort();
+        checkClzShort2Short2();
+        checkClzShort3Short3();
+        checkClzShort4Short4();
+        checkClzUshortUshort();
+        checkClzUshort2Ushort2();
+        checkClzUshort3Ushort3();
+        checkClzUshort4Ushort4();
+        checkClzIntInt();
+        checkClzInt2Int2();
+        checkClzInt3Int3();
+        checkClzInt4Int4();
+        checkClzUintUint();
+        checkClzUint2Uint2();
+        checkClzUint3Uint3();
+        checkClzUint4Uint4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.rs
new file mode 100644
index 0000000..40570bd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClz.rs
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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)
+
+
+char __attribute__((kernel)) testClzCharChar(char inValue) {
+    return clz(inValue);
+}
+
+char2 __attribute__((kernel)) testClzChar2Char2(char2 inValue) {
+    return clz(inValue);
+}
+
+char3 __attribute__((kernel)) testClzChar3Char3(char3 inValue) {
+    return clz(inValue);
+}
+
+char4 __attribute__((kernel)) testClzChar4Char4(char4 inValue) {
+    return clz(inValue);
+}
+
+uchar __attribute__((kernel)) testClzUcharUchar(uchar inValue) {
+    return clz(inValue);
+}
+
+uchar2 __attribute__((kernel)) testClzUchar2Uchar2(uchar2 inValue) {
+    return clz(inValue);
+}
+
+uchar3 __attribute__((kernel)) testClzUchar3Uchar3(uchar3 inValue) {
+    return clz(inValue);
+}
+
+uchar4 __attribute__((kernel)) testClzUchar4Uchar4(uchar4 inValue) {
+    return clz(inValue);
+}
+
+short __attribute__((kernel)) testClzShortShort(short inValue) {
+    return clz(inValue);
+}
+
+short2 __attribute__((kernel)) testClzShort2Short2(short2 inValue) {
+    return clz(inValue);
+}
+
+short3 __attribute__((kernel)) testClzShort3Short3(short3 inValue) {
+    return clz(inValue);
+}
+
+short4 __attribute__((kernel)) testClzShort4Short4(short4 inValue) {
+    return clz(inValue);
+}
+
+ushort __attribute__((kernel)) testClzUshortUshort(ushort inValue) {
+    return clz(inValue);
+}
+
+ushort2 __attribute__((kernel)) testClzUshort2Ushort2(ushort2 inValue) {
+    return clz(inValue);
+}
+
+ushort3 __attribute__((kernel)) testClzUshort3Ushort3(ushort3 inValue) {
+    return clz(inValue);
+}
+
+ushort4 __attribute__((kernel)) testClzUshort4Ushort4(ushort4 inValue) {
+    return clz(inValue);
+}
+
+int __attribute__((kernel)) testClzIntInt(int inValue) {
+    return clz(inValue);
+}
+
+int2 __attribute__((kernel)) testClzInt2Int2(int2 inValue) {
+    return clz(inValue);
+}
+
+int3 __attribute__((kernel)) testClzInt3Int3(int3 inValue) {
+    return clz(inValue);
+}
+
+int4 __attribute__((kernel)) testClzInt4Int4(int4 inValue) {
+    return clz(inValue);
+}
+
+uint __attribute__((kernel)) testClzUintUint(uint inValue) {
+    return clz(inValue);
+}
+
+uint2 __attribute__((kernel)) testClzUint2Uint2(uint2 inValue) {
+    return clz(inValue);
+}
+
+uint3 __attribute__((kernel)) testClzUint3Uint3(uint3 inValue) {
+    return clz(inValue);
+}
+
+uint4 __attribute__((kernel)) testClzUint4Uint4(uint4 inValue) {
+    return clz(inValue);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClzRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClzRelaxed.rs
new file mode 100644
index 0000000..27af443
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestClzRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestClz.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.java
new file mode 100644
index 0000000..0db6576
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.java
@@ -0,0 +1,21301 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestConvert extends RSBaseCompute {
+
+    private ScriptC_TestConvert script;
+    private ScriptC_TestConvertRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestConvert(mRS);
+        scriptRelaxed = new ScriptC_TestConvertRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4e1f6ac6l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Float2Float2(inV, out);
+            verifyResultsConvertFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Float2Float2(inV, out);
+            verifyResultsConvertFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x443a8ba4l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Float3Float3(inV, out);
+            verifyResultsConvertFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Float3Float3(inV, out);
+            verifyResultsConvertFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3a55ac82l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Float4Float4(inV, out);
+            verifyResultsConvertFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Float4Float4(inV, out);
+            verifyResultsConvertFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharFloat {
+        public byte inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertChar2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x1f489286l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Char2Float2(inV, out);
+            verifyResultsConvertChar2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Char2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Char2Float2(inV, out);
+            verifyResultsConvertChar2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Char2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharFloat args = new ArgumentsCharFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertChar2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x1563b364l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Char3Float3(inV, out);
+            verifyResultsConvertChar3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Char3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Char3Float3(inV, out);
+            verifyResultsConvertChar3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Char3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharFloat args = new ArgumentsCharFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertChar3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xb7ed442l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Char4Float4(inV, out);
+            verifyResultsConvertChar4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Char4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Char4Float4(inV, out);
+            verifyResultsConvertChar4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Char4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharFloat args = new ArgumentsCharFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertChar4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharFloat {
+        public byte inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUchar2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xbb20ac31l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Uchar2Float2(inV, out);
+            verifyResultsConvertUchar2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uchar2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Uchar2Float2(inV, out);
+            verifyResultsConvertUchar2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uchar2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharFloat args = new ArgumentsUcharFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUchar2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xb13bcd0fl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Uchar3Float3(inV, out);
+            verifyResultsConvertUchar3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uchar3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Uchar3Float3(inV, out);
+            verifyResultsConvertUchar3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uchar3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharFloat args = new ArgumentsUcharFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUchar3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xa756ededl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Uchar4Float4(inV, out);
+            verifyResultsConvertUchar4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uchar4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Uchar4Float4(inV, out);
+            verifyResultsConvertUchar4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uchar4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharFloat args = new ArgumentsUcharFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUchar4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortFloat {
+        public short inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertShort2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xff219172l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Short2Float2(inV, out);
+            verifyResultsConvertShort2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Short2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Short2Float2(inV, out);
+            verifyResultsConvertShort2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Short2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Float2(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.
+                ArgumentsShortFloat args = new ArgumentsShortFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertShort2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xf53cb250l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Short3Float3(inV, out);
+            verifyResultsConvertShort3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Short3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Short3Float3(inV, out);
+            verifyResultsConvertShort3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Short3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Float3(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.
+                ArgumentsShortFloat args = new ArgumentsShortFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertShort3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xeb57d32el, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Short4Float4(inV, out);
+            verifyResultsConvertShort4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Short4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Short4Float4(inV, out);
+            verifyResultsConvertShort4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Short4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Float4(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.
+                ArgumentsShortFloat args = new ArgumentsShortFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertShort4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortFloat {
+        public short inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUshort2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x2c6de12bl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Ushort2Float2(inV, out);
+            verifyResultsConvertUshort2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ushort2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Ushort2Float2(inV, out);
+            verifyResultsConvertUshort2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ushort2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Float2(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.
+                ArgumentsUshortFloat args = new ArgumentsUshortFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUshort2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x22890209l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Ushort3Float3(inV, out);
+            verifyResultsConvertUshort3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ushort3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Ushort3Float3(inV, out);
+            verifyResultsConvertUshort3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ushort3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Float3(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.
+                ArgumentsUshortFloat args = new ArgumentsUshortFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUshort3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x18a422e7l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Ushort4Float4(inV, out);
+            verifyResultsConvertUshort4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ushort4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Ushort4Float4(inV, out);
+            verifyResultsConvertUshort4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ushort4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Float4(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.
+                ArgumentsUshortFloat args = new ArgumentsUshortFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUshort4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntFloat {
+        public int inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertInt2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x7402bfc5l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Int2Float2(inV, out);
+            verifyResultsConvertInt2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Int2Float2(inV, out);
+            verifyResultsConvertInt2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntFloat args = new ArgumentsIntFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertInt2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x6a1de0a3l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Int3Float3(inV, out);
+            verifyResultsConvertInt3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Int3Float3(inV, out);
+            verifyResultsConvertInt3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntFloat args = new ArgumentsIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertInt3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x60390181l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Int4Float4(inV, out);
+            verifyResultsConvertInt4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Int4Float4(inV, out);
+            verifyResultsConvertInt4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntFloat args = new ArgumentsIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertInt4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintFloat {
+        public int inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUint2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x684cc46l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Uint2Float2(inV, out);
+            verifyResultsConvertUint2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uint2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Uint2Float2(inV, out);
+            verifyResultsConvertUint2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Uint2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintFloat args = new ArgumentsUintFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUint2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xfc9fed24l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Uint3Float3(inV, out);
+            verifyResultsConvertUint3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uint3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Uint3Float3(inV, out);
+            verifyResultsConvertUint3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Uint3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintFloat args = new ArgumentsUintFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUint3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xf2bb0e02l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Uint4Float4(inV, out);
+            verifyResultsConvertUint4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uint4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Uint4Float4(inV, out);
+            verifyResultsConvertUint4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Uint4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintFloat args = new ArgumentsUintFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUint4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatChar {
+        public float inV;
+        public byte out;
+    }
+
+    private void checkConvertFloat2Char2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x29789662l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Float2Char2(inV, out);
+            verifyResultsConvertFloat2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Float2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Float2Char2(inV, out);
+            verifyResultsConvertFloat2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Float2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatChar args = new ArgumentsFloatChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertFloat2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Char3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x88805b56l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Float3Char3(inV, out);
+            verifyResultsConvertFloat3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Float3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Float3Char3(inV, out);
+            verifyResultsConvertFloat3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Float3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatChar args = new ArgumentsFloatChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Char4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe788204al, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Float4Char4(inV, out);
+            verifyResultsConvertFloat4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Float4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Float4Char4(inV, out);
+            verifyResultsConvertFloat4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Float4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatChar args = new ArgumentsFloatChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharChar {
+        public byte inV;
+        public byte out;
+    }
+
+    private void checkConvertChar2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd5086da2l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Char2Char2(inV, out);
+            verifyResultsConvertChar2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Char2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Char2Char2(inV, out);
+            verifyResultsConvertChar2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Char2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertChar2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x34103296l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Char3Char3(inV, out);
+            verifyResultsConvertChar3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Char3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Char3Char3(inV, out);
+            verifyResultsConvertChar3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Char3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x9317f78al, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Char4Char4(inV, out);
+            verifyResultsConvertChar4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Char4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Char4Char4(inV, out);
+            verifyResultsConvertChar4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Char4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharChar args = new ArgumentsCharChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharChar {
+        public byte inV;
+        public byte out;
+    }
+
+    private void checkConvertUchar2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x678a7a23l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Uchar2Char2(inV, out);
+            verifyResultsConvertUchar2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uchar2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Uchar2Char2(inV, out);
+            verifyResultsConvertUchar2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uchar2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharChar args = new ArgumentsUcharChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUchar2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xc6923f17l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Uchar3Char3(inV, out);
+            verifyResultsConvertUchar3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uchar3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Uchar3Char3(inV, out);
+            verifyResultsConvertUchar3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uchar3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharChar args = new ArgumentsUcharChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x259a040bl, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Uchar4Char4(inV, out);
+            verifyResultsConvertUchar4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uchar4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Uchar4Char4(inV, out);
+            verifyResultsConvertUchar4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uchar4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharChar args = new ArgumentsUcharChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortChar {
+        public short inV;
+        public byte out;
+    }
+
+    private void checkConvertShort2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x15c60866l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Short2Char2(inV, out);
+            verifyResultsConvertShort2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Short2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Short2Char2(inV, out);
+            verifyResultsConvertShort2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Short2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Char2(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.
+                ArgumentsShortChar args = new ArgumentsShortChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertShort2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x74cdcd5al, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Short3Char3(inV, out);
+            verifyResultsConvertShort3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Short3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Short3Char3(inV, out);
+            verifyResultsConvertShort3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Short3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Char3(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.
+                ArgumentsShortChar args = new ArgumentsShortChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xd3d5924el, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Short4Char4(inV, out);
+            verifyResultsConvertShort4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Short4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Short4Char4(inV, out);
+            verifyResultsConvertShort4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Short4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Char4(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.
+                ArgumentsShortChar args = new ArgumentsShortChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortChar {
+        public short inV;
+        public byte out;
+    }
+
+    private void checkConvertUshort2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xb19e2211l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Ushort2Char2(inV, out);
+            verifyResultsConvertUshort2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ushort2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Ushort2Char2(inV, out);
+            verifyResultsConvertUshort2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ushort2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Char2(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.
+                ArgumentsUshortChar args = new ArgumentsUshortChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUshort2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x10a5e705l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Ushort3Char3(inV, out);
+            verifyResultsConvertUshort3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ushort3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Ushort3Char3(inV, out);
+            verifyResultsConvertUshort3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ushort3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Char3(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.
+                ArgumentsUshortChar args = new ArgumentsUshortChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x6fadabf9l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Ushort4Char4(inV, out);
+            verifyResultsConvertUshort4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ushort4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Ushort4Char4(inV, out);
+            verifyResultsConvertUshort4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ushort4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Char4(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.
+                ArgumentsUshortChar args = new ArgumentsUshortChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntChar {
+        public int inV;
+        public byte out;
+    }
+
+    private void checkConvertInt2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x364256dfl, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Int2Char2(inV, out);
+            verifyResultsConvertInt2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Int2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Int2Char2(inV, out);
+            verifyResultsConvertInt2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Int2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntChar args = new ArgumentsIntChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertInt2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x954a1bd3l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Int3Char3(inV, out);
+            verifyResultsConvertInt3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Int3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Int3Char3(inV, out);
+            verifyResultsConvertInt3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Int3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntChar args = new ArgumentsIntChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xf451e0c7l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Int4Char4(inV, out);
+            verifyResultsConvertInt4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Int4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Int4Char4(inV, out);
+            verifyResultsConvertInt4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Int4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntChar args = new ArgumentsIntChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintChar {
+        public int inV;
+        public byte out;
+    }
+
+    private void checkConvertUint2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x33b67ae2l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Uint2Char2(inV, out);
+            verifyResultsConvertUint2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uint2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Uint2Char2(inV, out);
+            verifyResultsConvertUint2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Uint2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintChar args = new ArgumentsUintChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUint2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x92be3fd6l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Uint3Char3(inV, out);
+            verifyResultsConvertUint3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uint3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Uint3Char3(inV, out);
+            verifyResultsConvertUint3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Uint3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintChar args = new ArgumentsUintChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xf1c604cal, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Uint4Char4(inV, out);
+            verifyResultsConvertUint4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uint4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Uint4Char4(inV, out);
+            verifyResultsConvertUint4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Uint4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintChar args = new ArgumentsUintChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatUchar {
+        public float inV;
+        public byte out;
+    }
+
+    private void checkConvertFloat2Uchar2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfac15b79l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Float2Uchar2(inV, out);
+            verifyResultsConvertFloat2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Float2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Float2Uchar2(inV, out);
+            verifyResultsConvertFloat2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Float2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatUchar args = new ArgumentsFloatUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertFloat2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Uchar3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf0dc7c57l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Float3Uchar3(inV, out);
+            verifyResultsConvertFloat3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Float3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Float3Uchar3(inV, out);
+            verifyResultsConvertFloat3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Float3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatUchar args = new ArgumentsFloatUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Uchar4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe6f79d35l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Float4Uchar4(inV, out);
+            verifyResultsConvertFloat4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Float4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Float4Uchar4(inV, out);
+            verifyResultsConvertFloat4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Float4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatUchar args = new ArgumentsFloatUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharUchar {
+        public byte inV;
+        public byte out;
+    }
+
+    private void checkConvertChar2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xcbea8339l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Char2Uchar2(inV, out);
+            verifyResultsConvertChar2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Char2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Char2Uchar2(inV, out);
+            verifyResultsConvertChar2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Char2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertChar2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xc205a417l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Char3Uchar3(inV, out);
+            verifyResultsConvertChar3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Char3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Char3Uchar3(inV, out);
+            verifyResultsConvertChar3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Char3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xb820c4f5l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Char4Uchar4(inV, out);
+            verifyResultsConvertChar4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Char4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Char4Uchar4(inV, out);
+            verifyResultsConvertChar4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Char4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUchar args = new ArgumentsCharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharUchar {
+        public byte inV;
+        public byte out;
+    }
+
+    private void checkConvertUchar2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x67c29ce4l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Uchar2Uchar2(inV, out);
+            verifyResultsConvertUchar2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Uchar2Uchar2(inV, out);
+            verifyResultsConvertUchar2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUchar2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x5dddbdc2l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Uchar3Uchar3(inV, out);
+            verifyResultsConvertUchar3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Uchar3Uchar3(inV, out);
+            verifyResultsConvertUchar3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x53f8dea0l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Uchar4Uchar4(inV, out);
+            verifyResultsConvertUchar4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Uchar4Uchar4(inV, out);
+            verifyResultsConvertUchar4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharUchar args = new ArgumentsUcharUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortUchar {
+        public short inV;
+        public byte out;
+    }
+
+    private void checkConvertShort2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xabc38225l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Short2Uchar2(inV, out);
+            verifyResultsConvertShort2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Short2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Short2Uchar2(inV, out);
+            verifyResultsConvertShort2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Short2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Uchar2(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.
+                ArgumentsShortUchar args = new ArgumentsShortUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertShort2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xa1dea303l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Short3Uchar3(inV, out);
+            verifyResultsConvertShort3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Short3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Short3Uchar3(inV, out);
+            verifyResultsConvertShort3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Short3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Uchar3(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.
+                ArgumentsShortUchar args = new ArgumentsShortUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x97f9c3e1l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Short4Uchar4(inV, out);
+            verifyResultsConvertShort4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Short4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Short4Uchar4(inV, out);
+            verifyResultsConvertShort4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Short4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Uchar4(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.
+                ArgumentsShortUchar args = new ArgumentsShortUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortUchar {
+        public short inV;
+        public byte out;
+    }
+
+    private void checkConvertUshort2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xd90fd1del, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Ushort2Uchar2(inV, out);
+            verifyResultsConvertUshort2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ushort2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Ushort2Uchar2(inV, out);
+            verifyResultsConvertUshort2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ushort2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Uchar2(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.
+                ArgumentsUshortUchar args = new ArgumentsUshortUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUshort2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xcf2af2bcl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Ushort3Uchar3(inV, out);
+            verifyResultsConvertUshort3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ushort3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Ushort3Uchar3(inV, out);
+            verifyResultsConvertUshort3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ushort3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Uchar3(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.
+                ArgumentsUshortUchar args = new ArgumentsUshortUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xc546139al, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Ushort4Uchar4(inV, out);
+            verifyResultsConvertUshort4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ushort4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Ushort4Uchar4(inV, out);
+            verifyResultsConvertUshort4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ushort4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Uchar4(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.
+                ArgumentsUshortUchar args = new ArgumentsUshortUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntUchar {
+        public int inV;
+        public byte out;
+    }
+
+    private void checkConvertInt2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x20a4b078l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Int2Uchar2(inV, out);
+            verifyResultsConvertInt2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Int2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Int2Uchar2(inV, out);
+            verifyResultsConvertInt2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Int2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUchar args = new ArgumentsIntUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertInt2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x16bfd156l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Int3Uchar3(inV, out);
+            verifyResultsConvertInt3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Int3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Int3Uchar3(inV, out);
+            verifyResultsConvertInt3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Int3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUchar args = new ArgumentsIntUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xcdaf234l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Int4Uchar4(inV, out);
+            verifyResultsConvertInt4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Int4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Int4Uchar4(inV, out);
+            verifyResultsConvertInt4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Int4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUchar args = new ArgumentsIntUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintUchar {
+        public int inV;
+        public byte out;
+    }
+
+    private void checkConvertUint2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xb326bcf9l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Uint2Uchar2(inV, out);
+            verifyResultsConvertUint2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uint2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Uint2Uchar2(inV, out);
+            verifyResultsConvertUint2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Uint2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintUchar args = new ArgumentsUintUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUint2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xa941ddd7l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Uint3Uchar3(inV, out);
+            verifyResultsConvertUint3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uint3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Uint3Uchar3(inV, out);
+            verifyResultsConvertUint3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Uint3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintUchar args = new ArgumentsUintUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x9f5cfeb5l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Uint4Uchar4(inV, out);
+            verifyResultsConvertUint4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uint4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Uint4Uchar4(inV, out);
+            verifyResultsConvertUint4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Uint4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintUchar args = new ArgumentsUintUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatShort {
+        public float inV;
+        public short out;
+    }
+
+    private void checkConvertFloat2Short2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8fcf2692l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Float2Short2(inV, out);
+            verifyResultsConvertFloat2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Float2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Float2Short2(inV, out);
+            verifyResultsConvertFloat2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Float2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Short2(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.
+                ArgumentsFloatShort args = new ArgumentsFloatShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertFloat2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Short3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x85ea4770l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Float3Short3(inV, out);
+            verifyResultsConvertFloat3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Float3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Float3Short3(inV, out);
+            verifyResultsConvertFloat3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Float3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Short3(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.
+                ArgumentsFloatShort args = new ArgumentsFloatShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Short4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7c05684el, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Float4Short4(inV, out);
+            verifyResultsConvertFloat4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Float4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Float4Short4(inV, out);
+            verifyResultsConvertFloat4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Float4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Short4(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.
+                ArgumentsFloatShort args = new ArgumentsFloatShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharShort {
+        public byte inV;
+        public short out;
+    }
+
+    private void checkConvertChar2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x60f84e52l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Char2Short2(inV, out);
+            verifyResultsConvertChar2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Char2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Char2Short2(inV, out);
+            verifyResultsConvertChar2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Char2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Short2(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.
+                ArgumentsCharShort args = new ArgumentsCharShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertChar2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x57136f30l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Char3Short3(inV, out);
+            verifyResultsConvertChar3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Char3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Char3Short3(inV, out);
+            verifyResultsConvertChar3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Char3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Short3(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.
+                ArgumentsCharShort args = new ArgumentsCharShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x4d2e900el, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Char4Short4(inV, out);
+            verifyResultsConvertChar4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Char4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Char4Short4(inV, out);
+            verifyResultsConvertChar4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Char4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Short4(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.
+                ArgumentsCharShort args = new ArgumentsCharShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharShort {
+        public byte inV;
+        public short out;
+    }
+
+    private void checkConvertUchar2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xfcd067fdl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Uchar2Short2(inV, out);
+            verifyResultsConvertUchar2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uchar2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Uchar2Short2(inV, out);
+            verifyResultsConvertUchar2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uchar2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Short2(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.
+                ArgumentsUcharShort args = new ArgumentsUcharShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUchar2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xf2eb88dbl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Uchar3Short3(inV, out);
+            verifyResultsConvertUchar3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uchar3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Uchar3Short3(inV, out);
+            verifyResultsConvertUchar3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uchar3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Short3(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.
+                ArgumentsUcharShort args = new ArgumentsUcharShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xe906a9b9l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Uchar4Short4(inV, out);
+            verifyResultsConvertUchar4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uchar4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Uchar4Short4(inV, out);
+            verifyResultsConvertUchar4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uchar4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Short4(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.
+                ArgumentsUcharShort args = new ArgumentsUcharShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortShort {
+        public short inV;
+        public short out;
+    }
+
+    private void checkConvertShort2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x40d14d3el, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Short2Short2(inV, out);
+            verifyResultsConvertShort2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Short2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Short2Short2(inV, out);
+            verifyResultsConvertShort2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Short2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Short2(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.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertShort2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x36ec6e1cl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Short3Short3(inV, out);
+            verifyResultsConvertShort3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Short3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Short3Short3(inV, out);
+            verifyResultsConvertShort3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Short3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Short3(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.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x2d078efal, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Short4Short4(inV, out);
+            verifyResultsConvertShort4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Short4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Short4Short4(inV, out);
+            verifyResultsConvertShort4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Short4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Short4(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.
+                ArgumentsShortShort args = new ArgumentsShortShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortShort {
+        public short inV;
+        public short out;
+    }
+
+    private void checkConvertUshort2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x6e1d9cf7l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Ushort2Short2(inV, out);
+            verifyResultsConvertUshort2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ushort2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Ushort2Short2(inV, out);
+            verifyResultsConvertUshort2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ushort2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Short2(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.
+                ArgumentsUshortShort args = new ArgumentsUshortShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUshort2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x6438bdd5l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Ushort3Short3(inV, out);
+            verifyResultsConvertUshort3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ushort3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Ushort3Short3(inV, out);
+            verifyResultsConvertUshort3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ushort3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Short3(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.
+                ArgumentsUshortShort args = new ArgumentsUshortShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x5a53deb3l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Ushort4Short4(inV, out);
+            verifyResultsConvertUshort4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ushort4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Ushort4Short4(inV, out);
+            verifyResultsConvertUshort4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ushort4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Short4(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.
+                ArgumentsUshortShort args = new ArgumentsUshortShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntShort {
+        public int inV;
+        public short out;
+    }
+
+    private void checkConvertInt2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xb5b27b91l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Int2Short2(inV, out);
+            verifyResultsConvertInt2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Int2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Int2Short2(inV, out);
+            verifyResultsConvertInt2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Int2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Short2(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.
+                ArgumentsIntShort args = new ArgumentsIntShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertInt2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xabcd9c6fl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Int3Short3(inV, out);
+            verifyResultsConvertInt3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Int3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Int3Short3(inV, out);
+            verifyResultsConvertInt3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Int3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Short3(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.
+                ArgumentsIntShort args = new ArgumentsIntShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xa1e8bd4dl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Int4Short4(inV, out);
+            verifyResultsConvertInt4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Int4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Int4Short4(inV, out);
+            verifyResultsConvertInt4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Int4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Short4(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.
+                ArgumentsIntShort args = new ArgumentsIntShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintShort {
+        public int inV;
+        public short out;
+    }
+
+    private void checkConvertUint2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x48348812l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Uint2Short2(inV, out);
+            verifyResultsConvertUint2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uint2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Uint2Short2(inV, out);
+            verifyResultsConvertUint2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Uint2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Short2(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.
+                ArgumentsUintShort args = new ArgumentsUintShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUint2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x3e4fa8f0l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Uint3Short3(inV, out);
+            verifyResultsConvertUint3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uint3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Uint3Short3(inV, out);
+            verifyResultsConvertUint3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Uint3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Short3(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.
+                ArgumentsUintShort args = new ArgumentsUintShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x346ac9cel, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Uint4Short4(inV, out);
+            verifyResultsConvertUint4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uint4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Uint4Short4(inV, out);
+            verifyResultsConvertUint4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Uint4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Short4(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.
+                ArgumentsUintShort args = new ArgumentsUintShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatUshort {
+        public float inV;
+        public short out;
+    }
+
+    private void checkConvertFloat2Ushort2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb708416fl, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Float2Ushort2(inV, out);
+            verifyResultsConvertFloat2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Float2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Float2Ushort2(inV, out);
+            verifyResultsConvertFloat2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Float2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Ushort2(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.
+                ArgumentsFloatUshort args = new ArgumentsFloatUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertFloat2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Ushort3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd63d29bl, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Float3Ushort3(inV, out);
+            verifyResultsConvertFloat3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Float3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Float3Ushort3(inV, out);
+            verifyResultsConvertFloat3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Float3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Ushort3(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.
+                ArgumentsFloatUshort args = new ArgumentsFloatUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Ushort4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x63bf63c7l, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Float4Ushort4(inV, out);
+            verifyResultsConvertFloat4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Float4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Float4Ushort4(inV, out);
+            verifyResultsConvertFloat4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Float4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Ushort4(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.
+                ArgumentsFloatUshort args = new ArgumentsFloatUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharUshort {
+        public byte inV;
+        public short out;
+    }
+
+    private void checkConvertChar2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xd8f1eeafl, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Char2Ushort2(inV, out);
+            verifyResultsConvertChar2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Char2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Char2Ushort2(inV, out);
+            verifyResultsConvertChar2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Char2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Ushort2(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.
+                ArgumentsCharUshort args = new ArgumentsCharUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertChar2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x2f4d7fdbl, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Char3Ushort3(inV, out);
+            verifyResultsConvertChar3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Char3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Char3Ushort3(inV, out);
+            verifyResultsConvertChar3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Char3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Ushort3(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.
+                ArgumentsCharUshort args = new ArgumentsCharUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x85a91107l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Char4Ushort4(inV, out);
+            verifyResultsConvertChar4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Char4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Char4Ushort4(inV, out);
+            verifyResultsConvertChar4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Char4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Ushort4(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.
+                ArgumentsCharUshort args = new ArgumentsCharUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharUshort {
+        public byte inV;
+        public short out;
+    }
+
+    private void checkConvertUchar2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x63e3e68l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Uchar2Ushort2(inV, out);
+            verifyResultsConvertUchar2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uchar2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Uchar2Ushort2(inV, out);
+            verifyResultsConvertUchar2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uchar2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Ushort2(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.
+                ArgumentsUcharUshort args = new ArgumentsUcharUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUchar2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x5c99cf94l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Uchar3Ushort3(inV, out);
+            verifyResultsConvertUchar3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uchar3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Uchar3Ushort3(inV, out);
+            verifyResultsConvertUchar3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uchar3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Ushort3(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.
+                ArgumentsUcharUshort args = new ArgumentsUcharUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xb2f560c0l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Uchar4Ushort4(inV, out);
+            verifyResultsConvertUchar4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uchar4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Uchar4Ushort4(inV, out);
+            verifyResultsConvertUchar4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uchar4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Ushort4(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.
+                ArgumentsUcharUshort args = new ArgumentsUcharUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortUshort {
+        public short inV;
+        public short out;
+    }
+
+    private void checkConvertShort2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x7264c053l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Short2Ushort2(inV, out);
+            verifyResultsConvertShort2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Short2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Short2Ushort2(inV, out);
+            verifyResultsConvertShort2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Short2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Ushort2(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.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertShort2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xc8c0517fl, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Short3Ushort3(inV, out);
+            verifyResultsConvertShort3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Short3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Short3Ushort3(inV, out);
+            verifyResultsConvertShort3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Short3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Ushort3(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.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x1f1be2abl, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Short4Ushort4(inV, out);
+            verifyResultsConvertShort4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Short4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Short4Ushort4(inV, out);
+            verifyResultsConvertShort4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Short4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Ushort4(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.
+                ArgumentsShortUshort args = new ArgumentsShortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortUshort {
+        public short inV;
+        public short out;
+    }
+
+    private void checkConvertUshort2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xe362466l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Ushort2Ushort2(inV, out);
+            verifyResultsConvertUshort2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ushort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Ushort2Ushort2(inV, out);
+            verifyResultsConvertUshort2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ushort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Ushort2(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.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUshort2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x6491b592l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Ushort3Ushort3(inV, out);
+            verifyResultsConvertUshort3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ushort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Ushort3Ushort3(inV, out);
+            verifyResultsConvertUshort3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ushort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Ushort3(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.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xbaed46bel, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Ushort4Ushort4(inV, out);
+            verifyResultsConvertUshort4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ushort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Ushort4Ushort4(inV, out);
+            verifyResultsConvertUshort4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ushort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Ushort4(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.
+                ArgumentsUshortUshort args = new ArgumentsUshortUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntUshort {
+        public int inV;
+        public short out;
+    }
+
+    private void checkConvertInt2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x14378844l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Int2Ushort2(inV, out);
+            verifyResultsConvertInt2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Int2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Int2Ushort2(inV, out);
+            verifyResultsConvertInt2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Int2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Ushort2(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.
+                ArgumentsIntUshort args = new ArgumentsIntUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertInt2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x6a931970l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Int3Ushort3(inV, out);
+            verifyResultsConvertInt3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Int3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Int3Ushort3(inV, out);
+            verifyResultsConvertInt3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Int3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Ushort3(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.
+                ArgumentsIntUshort args = new ArgumentsIntUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xc0eeaa9cl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Int4Ushort4(inV, out);
+            verifyResultsConvertInt4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Int4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Int4Ushort4(inV, out);
+            verifyResultsConvertInt4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Int4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Ushort4(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.
+                ArgumentsIntUshort args = new ArgumentsIntUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintUshort {
+        public int inV;
+        public short out;
+    }
+
+    private void checkConvertUint2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xb00fa1efl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Uint2Ushort2(inV, out);
+            verifyResultsConvertUint2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uint2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Uint2Ushort2(inV, out);
+            verifyResultsConvertUint2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Uint2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Ushort2(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.
+                ArgumentsUintUshort args = new ArgumentsUintUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUint2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x66b331bl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Uint3Ushort3(inV, out);
+            verifyResultsConvertUint3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uint3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Uint3Ushort3(inV, out);
+            verifyResultsConvertUint3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Uint3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Ushort3(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.
+                ArgumentsUintUshort args = new ArgumentsUintUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x5cc6c447l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Uint4Ushort4(inV, out);
+            verifyResultsConvertUint4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uint4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Uint4Ushort4(inV, out);
+            verifyResultsConvertUint4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Uint4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Ushort4(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.
+                ArgumentsUintUshort args = new ArgumentsUintUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatInt {
+        public float inV;
+        public int out;
+    }
+
+    private void checkConvertFloat2Int2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc069dd5dl, -2.1474835210000000000e+09, 2.1474835200000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Float2Int2(inV, out);
+            verifyResultsConvertFloat2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Float2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Float2Int2(inV, out);
+            verifyResultsConvertFloat2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Float2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertFloat2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Int3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa11ed93l, -2.1474835210000000000e+09, 2.1474835200000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Float3Int3(inV, out);
+            verifyResultsConvertFloat3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Float3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Float3Int3(inV, out);
+            verifyResultsConvertFloat3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Float3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Int4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x53b9fdc9l, -2.1474835210000000000e+09, 2.1474835200000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Float4Int4(inV, out);
+            verifyResultsConvertFloat4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Float4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Float4Int4(inV, out);
+            verifyResultsConvertFloat4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Float4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharInt {
+        public byte inV;
+        public int out;
+    }
+
+    private void checkConvertChar2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x94c6831dl, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Char2Int2(inV, out);
+            verifyResultsConvertChar2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Char2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Char2Int2(inV, out);
+            verifyResultsConvertChar2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Char2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharInt args = new ArgumentsCharInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertChar2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xde6e9353l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Char3Int3(inV, out);
+            verifyResultsConvertChar3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Char3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Char3Int3(inV, out);
+            verifyResultsConvertChar3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Char3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharInt args = new ArgumentsCharInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x2816a389l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Char4Int4(inV, out);
+            verifyResultsConvertChar4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Char4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Char4Int4(inV, out);
+            verifyResultsConvertChar4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Char4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharInt args = new ArgumentsCharInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharInt {
+        public byte inV;
+        public int out;
+    }
+
+    private void checkConvertUchar2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x923aa720l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Uchar2Int2(inV, out);
+            verifyResultsConvertUchar2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uchar2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Uchar2Int2(inV, out);
+            verifyResultsConvertUchar2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uchar2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharInt args = new ArgumentsUcharInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUchar2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xdbe2b756l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Uchar3Int3(inV, out);
+            verifyResultsConvertUchar3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uchar3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Uchar3Int3(inV, out);
+            verifyResultsConvertUchar3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uchar3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharInt args = new ArgumentsUcharInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x258ac78cl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Uchar4Int4(inV, out);
+            verifyResultsConvertUchar4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uchar4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Uchar4Int4(inV, out);
+            verifyResultsConvertUchar4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uchar4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharInt args = new ArgumentsUcharInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortInt {
+        public short inV;
+        public int out;
+    }
+
+    private void checkConvertShort2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x252a2d69l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Short2Int2(inV, out);
+            verifyResultsConvertShort2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Short2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Short2Int2(inV, out);
+            verifyResultsConvertShort2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Short2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Int2(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.
+                ArgumentsShortInt args = new ArgumentsShortInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertShort2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x6ed23d9fl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Short3Int3(inV, out);
+            verifyResultsConvertShort3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Short3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Short3Int3(inV, out);
+            verifyResultsConvertShort3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Short3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Int3(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.
+                ArgumentsShortInt args = new ArgumentsShortInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xb87a4dd5l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Short4Int4(inV, out);
+            verifyResultsConvertShort4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Short4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Short4Int4(inV, out);
+            verifyResultsConvertShort4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Short4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Int4(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.
+                ArgumentsShortInt args = new ArgumentsShortInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortInt {
+        public short inV;
+        public int out;
+    }
+
+    private void checkConvertUshort2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xb7ac39eal, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Ushort2Int2(inV, out);
+            verifyResultsConvertUshort2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ushort2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Ushort2Int2(inV, out);
+            verifyResultsConvertUshort2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ushort2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Int2(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.
+                ArgumentsUshortInt args = new ArgumentsUshortInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUshort2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x1544a20l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Ushort3Int3(inV, out);
+            verifyResultsConvertUshort3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ushort3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Ushort3Int3(inV, out);
+            verifyResultsConvertUshort3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ushort3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Int3(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.
+                ArgumentsUshortInt args = new ArgumentsUshortInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x4afc5a56l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Ushort4Int4(inV, out);
+            verifyResultsConvertUshort4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ushort4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Ushort4Int4(inV, out);
+            verifyResultsConvertUshort4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ushort4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Int4(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.
+                ArgumentsUshortInt args = new ArgumentsUshortInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntInt {
+        public int inV;
+        public int out;
+    }
+
+    private void checkConvertInt2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x49a42354l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Int2Int2(inV, out);
+            verifyResultsConvertInt2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Int2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Int2Int2(inV, out);
+            verifyResultsConvertInt2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Int2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertInt2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x934c338al, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Int3Int3(inV, out);
+            verifyResultsConvertInt3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Int3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Int3Int3(inV, out);
+            verifyResultsConvertInt3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Int3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xdcf443c0l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Int4Int4(inV, out);
+            verifyResultsConvertInt4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Int4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Int4Int4(inV, out);
+            verifyResultsConvertInt4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Int4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntInt args = new ArgumentsIntInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintInt {
+        public int inV;
+        public int out;
+    }
+
+    private void checkConvertUint2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x3daccaddl, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Uint2Int2(inV, out);
+            verifyResultsConvertUint2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uint2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Uint2Int2(inV, out);
+            verifyResultsConvertUint2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Uint2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintInt args = new ArgumentsUintInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUint2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x8754db13l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Uint3Int3(inV, out);
+            verifyResultsConvertUint3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uint3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Uint3Int3(inV, out);
+            verifyResultsConvertUint3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Uint3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintInt args = new ArgumentsUintInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xd0fceb49l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Uint4Int4(inV, out);
+            verifyResultsConvertUint4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uint4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Uint4Int4(inV, out);
+            verifyResultsConvertUint4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Uint4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintInt args = new ArgumentsUintInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatUint {
+        public float inV;
+        public int out;
+    }
+
+    private void checkConvertFloat2Uint2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x424dca22l, 0.0000000000000000000e+00, 4.2949670400000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Float2Uint2(inV, out);
+            verifyResultsConvertFloat2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Float2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Float2Uint2(inV, out);
+            verifyResultsConvertFloat2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Float2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatUint args = new ArgumentsFloatUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertFloat2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Uint3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa1558f16l, 0.0000000000000000000e+00, 4.2949670400000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Float3Uint3(inV, out);
+            verifyResultsConvertFloat3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Float3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Float3Uint3(inV, out);
+            verifyResultsConvertFloat3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Float3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatUint args = new ArgumentsFloatUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Uint4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x5d540al, 0.0000000000000000000e+00, 4.2949670400000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Float4Uint4(inV, out);
+            verifyResultsConvertFloat4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Float4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Float4Uint4(inV, out);
+            verifyResultsConvertFloat4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Float4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatUint args = new ArgumentsFloatUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharUint {
+        public byte inV;
+        public int out;
+    }
+
+    private void checkConvertChar2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xeddda162l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Char2Uint2(inV, out);
+            verifyResultsConvertChar2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Char2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Char2Uint2(inV, out);
+            verifyResultsConvertChar2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Char2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUint args = new ArgumentsCharUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertChar2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x4ce56656l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Char3Uint3(inV, out);
+            verifyResultsConvertChar3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Char3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Char3Uint3(inV, out);
+            verifyResultsConvertChar3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Char3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUint args = new ArgumentsCharUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xabed2b4al, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Char4Uint4(inV, out);
+            verifyResultsConvertChar4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Char4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Char4Uint4(inV, out);
+            verifyResultsConvertChar4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Char4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUint args = new ArgumentsCharUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharUint {
+        public byte inV;
+        public int out;
+    }
+
+    private void checkConvertUchar2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x805fade3l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Uchar2Uint2(inV, out);
+            verifyResultsConvertUchar2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uchar2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Uchar2Uint2(inV, out);
+            verifyResultsConvertUchar2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uchar2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharUint args = new ArgumentsUcharUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUchar2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xdf6772d7l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Uchar3Uint3(inV, out);
+            verifyResultsConvertUchar3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uchar3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Uchar3Uint3(inV, out);
+            verifyResultsConvertUchar3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uchar3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharUint args = new ArgumentsUcharUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x3e6f37cbl, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Uchar4Uint4(inV, out);
+            verifyResultsConvertUchar4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uchar4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Uchar4Uint4(inV, out);
+            verifyResultsConvertUchar4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uchar4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharUint args = new ArgumentsUcharUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortUint {
+        public short inV;
+        public int out;
+    }
+
+    private void checkConvertShort2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x2e9b3c26l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Short2Uint2(inV, out);
+            verifyResultsConvertShort2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Short2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Short2Uint2(inV, out);
+            verifyResultsConvertShort2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Short2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Uint2(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.
+                ArgumentsShortUint args = new ArgumentsShortUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertShort2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x8da3011al, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Short3Uint3(inV, out);
+            verifyResultsConvertShort3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Short3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Short3Uint3(inV, out);
+            verifyResultsConvertShort3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Short3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Uint3(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.
+                ArgumentsShortUint args = new ArgumentsShortUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xecaac60el, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Short4Uint4(inV, out);
+            verifyResultsConvertShort4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Short4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Short4Uint4(inV, out);
+            verifyResultsConvertShort4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Short4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Uint4(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.
+                ArgumentsShortUint args = new ArgumentsShortUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortUint {
+        public short inV;
+        public int out;
+    }
+
+    private void checkConvertUshort2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0xca7355d1l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Ushort2Uint2(inV, out);
+            verifyResultsConvertUshort2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ushort2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Ushort2Uint2(inV, out);
+            verifyResultsConvertUshort2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ushort2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Uint2(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.
+                ArgumentsUshortUint args = new ArgumentsUshortUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUshort2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x297b1ac5l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Ushort3Uint3(inV, out);
+            verifyResultsConvertUshort3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ushort3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Ushort3Uint3(inV, out);
+            verifyResultsConvertUshort3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ushort3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Uint3(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.
+                ArgumentsUshortUint args = new ArgumentsUshortUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x8882dfb9l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Ushort4Uint4(inV, out);
+            verifyResultsConvertUshort4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ushort4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Ushort4Uint4(inV, out);
+            verifyResultsConvertUshort4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ushort4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Uint4(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.
+                ArgumentsUshortUint args = new ArgumentsUshortUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntUint {
+        public int inV;
+        public int out;
+    }
+
+    private void checkConvertInt2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x4f178a9fl, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Int2Uint2(inV, out);
+            verifyResultsConvertInt2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Int2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Int2Uint2(inV, out);
+            verifyResultsConvertInt2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Int2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertInt2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xae1f4f93l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Int3Uint3(inV, out);
+            verifyResultsConvertInt3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Int3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Int3Uint3(inV, out);
+            verifyResultsConvertInt3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Int3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xd271487l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Int4Uint4(inV, out);
+            verifyResultsConvertInt4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Int4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Int4Uint4(inV, out);
+            verifyResultsConvertInt4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Int4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUint args = new ArgumentsIntUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintUint {
+        public int inV;
+        public int out;
+    }
+
+    private void checkConvertUint2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x4c8baea2l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Uint2Uint2(inV, out);
+            verifyResultsConvertUint2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Uint2Uint2(inV, out);
+            verifyResultsConvertUint2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Uint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUint2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xab937396l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Uint3Uint3(inV, out);
+            verifyResultsConvertUint3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Uint3Uint3(inV, out);
+            verifyResultsConvertUint3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Uint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xa9b388al, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Uint4Uint4(inV, out);
+            verifyResultsConvertUint4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Uint4Uint4(inV, out);
+            verifyResultsConvertUint4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Uint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintUint args = new ArgumentsUintUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleDouble {
+        public double inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertDouble2Double2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x3902786el, -8.5390423905960001625e+307, 8.5390423905960001625e+307);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Double2Double2(inV, out);
+            verifyResultsConvertDouble2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Double2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Double2Double2(inV, out);
+            verifyResultsConvertDouble2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Double2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Double2(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleDouble args = new ArgumentsDoubleDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertDouble2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Double3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x8f5e099al, -8.5390423905960001625e+307, 8.5390423905960001625e+307);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Double3Double3(inV, out);
+            verifyResultsConvertDouble3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Double3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Double3Double3(inV, out);
+            verifyResultsConvertDouble3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Double3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Double3(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleDouble args = new ArgumentsDoubleDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertDouble3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Double4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0xe5b99ac6l, -8.5390423905960001625e+307, 8.5390423905960001625e+307);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Double4Double4(inV, out);
+            verifyResultsConvertDouble4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Double4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Double4Double4(inV, out);
+            verifyResultsConvertDouble4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Double4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Double4(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleDouble args = new ArgumentsDoubleDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertDouble4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongDouble {
+        public long inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertLong2Double2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x4c70299bl, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Long2Double2(inV, out);
+            verifyResultsConvertLong2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Long2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Long2Double2(inV, out);
+            verifyResultsConvertLong2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Long2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Double2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongDouble args = new ArgumentsLongDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertLong2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Double3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xa2cbbac7l, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Long3Double3(inV, out);
+            verifyResultsConvertLong3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Long3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Long3Double3(inV, out);
+            verifyResultsConvertLong3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Long3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Double3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongDouble args = new ArgumentsLongDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertLong3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Double4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xf9274bf3l, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Long4Double4(inV, out);
+            verifyResultsConvertLong4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Long4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Long4Double4(inV, out);
+            verifyResultsConvertLong4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Long4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Double4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongDouble args = new ArgumentsLongDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertLong4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongDouble {
+        public long inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUlong2Double2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x79bc7954l, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Ulong2Double2(inV, out);
+            verifyResultsConvertUlong2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Ulong2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Ulong2Double2(inV, out);
+            verifyResultsConvertUlong2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Ulong2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Double2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongDouble args = new ArgumentsUlongDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUlong2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Double3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xd0180a80l, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Ulong3Double3(inV, out);
+            verifyResultsConvertUlong3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Ulong3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Ulong3Double3(inV, out);
+            verifyResultsConvertUlong3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Ulong3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Double3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongDouble args = new ArgumentsUlongDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUlong3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Double4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x26739bacl, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Ulong4Double4(inV, out);
+            verifyResultsConvertUlong4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Ulong4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Ulong4Double4(inV, out);
+            verifyResultsConvertUlong4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Ulong4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Double4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongDouble args = new ArgumentsUlongDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUlong4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleLong {
+        public double inV;
+        public long out;
+    }
+
+    private void checkConvertDouble2Long2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x430cbe95l, -4.2949662730000000000e+09, 4.2949662720000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Double2Long2(inV, out);
+            verifyResultsConvertDouble2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Double2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Double2Long2(inV, out);
+            verifyResultsConvertDouble2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Double2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Long2(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleLong args = new ArgumentsDoubleLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertDouble2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Long3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xa2148389l, -4.2949662730000000000e+09, 4.2949662720000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Double3Long3(inV, out);
+            verifyResultsConvertDouble3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Double3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Double3Long3(inV, out);
+            verifyResultsConvertDouble3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Double3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Long3(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleLong args = new ArgumentsDoubleLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Long4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x11c487dl, -4.2949662730000000000e+09, 4.2949662720000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Double4Long4(inV, out);
+            verifyResultsConvertDouble4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Double4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Double4Long4(inV, out);
+            verifyResultsConvertDouble4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Double4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Long4(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleLong args = new ArgumentsDoubleLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongLong {
+        public long inV;
+        public long out;
+    }
+
+    private void checkConvertLong2Long2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xc81d242al, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Long2Long2(inV, out);
+            verifyResultsConvertLong2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Long2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Long2Long2(inV, out);
+            verifyResultsConvertLong2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Long2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Long2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongLong args = new ArgumentsLongLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertLong2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Long3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x2724e91el, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Long3Long3(inV, out);
+            verifyResultsConvertLong3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Long3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Long3Long3(inV, out);
+            verifyResultsConvertLong3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Long3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Long3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongLong args = new ArgumentsLongLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Long4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x862cae12l, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Long4Long4(inV, out);
+            verifyResultsConvertLong4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Long4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Long4Long4(inV, out);
+            verifyResultsConvertLong4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Long4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Long4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongLong args = new ArgumentsLongLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongLong {
+        public long inV;
+        public long out;
+    }
+
+    private void checkConvertUlong2Long2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x5a9f30abl, false, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Ulong2Long2(inV, out);
+            verifyResultsConvertUlong2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Ulong2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Ulong2Long2(inV, out);
+            verifyResultsConvertUlong2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Ulong2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Long2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongLong args = new ArgumentsUlongLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUlong2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Long3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xb9a6f59fl, false, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Ulong3Long3(inV, out);
+            verifyResultsConvertUlong3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Ulong3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Ulong3Long3(inV, out);
+            verifyResultsConvertUlong3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Ulong3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Long3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongLong args = new ArgumentsUlongLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Long4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x18aeba93l, false, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Ulong4Long4(inV, out);
+            verifyResultsConvertUlong4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Ulong4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Ulong4Long4(inV, out);
+            verifyResultsConvertUlong4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Ulong4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Long4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongLong args = new ArgumentsUlongLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleUlong {
+        public double inV;
+        public long out;
+    }
+
+    private void checkConvertDouble2Ulong2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x7e12ff5el, 0.0000000000000000000e+00, 4.2949652480000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Double2Ulong2(inV, out);
+            verifyResultsConvertDouble2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Double2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Double2Ulong2(inV, out);
+            verifyResultsConvertDouble2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Double2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleUlong args = new ArgumentsDoubleUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertDouble2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Ulong3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x742e203cl, 0.0000000000000000000e+00, 4.2949652480000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Double3Ulong3(inV, out);
+            verifyResultsConvertDouble3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Double3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Double3Ulong3(inV, out);
+            verifyResultsConvertDouble3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Double3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleUlong args = new ArgumentsDoubleUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Ulong4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x6a49411al, 0.0000000000000000000e+00, 4.2949652480000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Double4Ulong4(inV, out);
+            verifyResultsConvertDouble4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Double4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Double4Ulong4(inV, out);
+            verifyResultsConvertDouble4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Double4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleUlong args = new ArgumentsDoubleUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongUlong {
+        public long inV;
+        public long out;
+    }
+
+    private void checkConvertLong2Ulong2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xd7d40f65l, false, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Long2Ulong2(inV, out);
+            verifyResultsConvertLong2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Long2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Long2Ulong2(inV, out);
+            verifyResultsConvertLong2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Long2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongUlong args = new ArgumentsLongUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertLong2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Ulong3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xcdef3043l, false, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Long3Ulong3(inV, out);
+            verifyResultsConvertLong3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Long3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Long3Ulong3(inV, out);
+            verifyResultsConvertLong3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Long3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongUlong args = new ArgumentsLongUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Ulong4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xc40a5121l, false, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Long4Ulong4(inV, out);
+            verifyResultsConvertLong4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Long4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Long4Ulong4(inV, out);
+            verifyResultsConvertLong4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Long4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongUlong args = new ArgumentsLongUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongUlong {
+        public long inV;
+        public long out;
+    }
+
+    private void checkConvertUlong2Ulong2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x73ac2910l, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Ulong2Ulong2(inV, out);
+            verifyResultsConvertUlong2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Ulong2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Ulong2Ulong2(inV, out);
+            verifyResultsConvertUlong2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Ulong2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongUlong args = new ArgumentsUlongUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUlong2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Ulong3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x69c749eel, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Ulong3Ulong3(inV, out);
+            verifyResultsConvertUlong3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Ulong3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Ulong3Ulong3(inV, out);
+            verifyResultsConvertUlong3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Ulong3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongUlong args = new ArgumentsUlongUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Ulong4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x5fe26accl, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Ulong4Ulong4(inV, out);
+            verifyResultsConvertUlong4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Ulong4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Ulong4Ulong4(inV, out);
+            verifyResultsConvertUlong4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Ulong4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongUlong args = new ArgumentsUlongUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleFloat {
+        public double inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertDouble2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x7d6d9a2dl, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Double2Float2(inV, out);
+            verifyResultsConvertDouble2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Double2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Double2Float2(inV, out);
+            verifyResultsConvertDouble2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Double2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleFloat args = new ArgumentsDoubleFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertDouble2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x7388bb0bl, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Double3Float3(inV, out);
+            verifyResultsConvertDouble3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Double3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Double3Float3(inV, out);
+            verifyResultsConvertDouble3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Double3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleFloat args = new ArgumentsDoubleFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertDouble3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x69a3dbe9l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Double4Float4(inV, out);
+            verifyResultsConvertDouble4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Double4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Double4Float4(inV, out);
+            verifyResultsConvertDouble4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Double4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleFloat args = new ArgumentsDoubleFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertDouble4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongFloat {
+        public long inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertLong2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xd72eaa34l, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Long2Float2(inV, out);
+            verifyResultsConvertLong2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Long2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Long2Float2(inV, out);
+            verifyResultsConvertLong2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Long2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongFloat args = new ArgumentsLongFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertLong2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xcd49cb12l, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Long3Float3(inV, out);
+            verifyResultsConvertLong3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Long3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Long3Float3(inV, out);
+            verifyResultsConvertLong3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Long3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongFloat args = new ArgumentsLongFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertLong3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0xc364ebf0l, true, 63);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Long4Float4(inV, out);
+            verifyResultsConvertLong4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Long4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Long4Float4(inV, out);
+            verifyResultsConvertLong4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Long4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongFloat args = new ArgumentsLongFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertLong4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongFloat {
+        public long inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUlong2Float2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x7306c3dfl, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testConvertFloat2Ulong2Float2(inV, out);
+            verifyResultsConvertUlong2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ulong2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat2Ulong2Float2(inV, out);
+            verifyResultsConvertUlong2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat2Ulong2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongFloat args = new ArgumentsUlongFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUlong2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Float3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x6921e4bdl, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testConvertFloat3Ulong3Float3(inV, out);
+            verifyResultsConvertUlong3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ulong3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat3Ulong3Float3(inV, out);
+            verifyResultsConvertUlong3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat3Ulong3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongFloat args = new ArgumentsUlongFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUlong3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Float4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x5f3d059bl, false, 64);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testConvertFloat4Ulong4Float4(inV, out);
+            verifyResultsConvertUlong4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ulong4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertFloat4Ulong4Float4(inV, out);
+            verifyResultsConvertUlong4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertFloat4Ulong4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongFloat args = new ArgumentsUlongFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUlong4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleChar {
+        public double inV;
+        public byte out;
+    }
+
+    private void checkConvertDouble2Char2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0xef094a17l, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Double2Char2(inV, out);
+            verifyResultsConvertDouble2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Double2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Double2Char2(inV, out);
+            verifyResultsConvertDouble2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Double2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleChar args = new ArgumentsDoubleChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertDouble2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Char3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x4e110f0bl, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Double3Char3(inV, out);
+            verifyResultsConvertDouble3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Double3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Double3Char3(inV, out);
+            verifyResultsConvertDouble3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Double3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleChar args = new ArgumentsDoubleChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Char4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0xad18d3ffl, -1.2800000000000000000e+02, 1.2700000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Double4Char4(inV, out);
+            verifyResultsConvertDouble4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Double4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Double4Char4(inV, out);
+            verifyResultsConvertDouble4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Double4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleChar args = new ArgumentsDoubleChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongChar {
+        public long inV;
+        public byte out;
+    }
+
+    private void checkConvertLong2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x7419afacl, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Long2Char2(inV, out);
+            verifyResultsConvertLong2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Long2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Long2Char2(inV, out);
+            verifyResultsConvertLong2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Long2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongChar args = new ArgumentsLongChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertLong2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xd32174a0l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Long3Char3(inV, out);
+            verifyResultsConvertLong3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Long3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Long3Char3(inV, out);
+            verifyResultsConvertLong3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Long3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongChar args = new ArgumentsLongChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x32293994l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Long4Char4(inV, out);
+            verifyResultsConvertLong4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Long4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Long4Char4(inV, out);
+            verifyResultsConvertLong4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Long4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongChar args = new ArgumentsLongChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongChar {
+        public long inV;
+        public byte out;
+    }
+
+    private void checkConvertUlong2Char2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x69bbc2dl, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertChar2Ulong2Char2(inV, out);
+            verifyResultsConvertUlong2Char2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ulong2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar2Ulong2Char2(inV, out);
+            verifyResultsConvertUlong2Char2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar2Ulong2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Char2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongChar args = new ArgumentsUlongChar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUlong2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Char3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x65a38121l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertChar3Ulong3Char3(inV, out);
+            verifyResultsConvertUlong3Char3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ulong3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar3Ulong3Char3(inV, out);
+            verifyResultsConvertUlong3Char3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar3Ulong3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Char3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongChar args = new ArgumentsUlongChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Char4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xc4ab4615l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertChar4Ulong4Char4(inV, out);
+            verifyResultsConvertUlong4Char4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ulong4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertChar4Ulong4Char4(inV, out);
+            verifyResultsConvertUlong4Char4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertChar4Ulong4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Char4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongChar args = new ArgumentsUlongChar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleUchar {
+        public double inV;
+        public byte out;
+    }
+
+    private void checkConvertDouble2Uchar2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x2a0f8ae0l, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Double2Uchar2(inV, out);
+            verifyResultsConvertDouble2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Double2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Double2Uchar2(inV, out);
+            verifyResultsConvertDouble2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Double2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleUchar args = new ArgumentsDoubleUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertDouble2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Uchar3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x202aabbel, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Double3Uchar3(inV, out);
+            verifyResultsConvertDouble3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Double3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Double3Uchar3(inV, out);
+            verifyResultsConvertDouble3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Double3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleUchar args = new ArgumentsDoubleUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Uchar4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x1645cc9cl, 0.0000000000000000000e+00, 2.5500000000000000000e+02);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Double4Uchar4(inV, out);
+            verifyResultsConvertDouble4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Double4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Double4Uchar4(inV, out);
+            verifyResultsConvertDouble4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Double4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleUchar args = new ArgumentsDoubleUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongUchar {
+        public long inV;
+        public byte out;
+    }
+
+    private void checkConvertLong2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x83d09ae7l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Long2Uchar2(inV, out);
+            verifyResultsConvertLong2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Long2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Long2Uchar2(inV, out);
+            verifyResultsConvertLong2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Long2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongUchar args = new ArgumentsLongUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertLong2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x79ebbbc5l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Long3Uchar3(inV, out);
+            verifyResultsConvertLong3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Long3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Long3Uchar3(inV, out);
+            verifyResultsConvertLong3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Long3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongUchar args = new ArgumentsLongUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x7006dca3l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Long4Uchar4(inV, out);
+            verifyResultsConvertLong4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Long4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Long4Uchar4(inV, out);
+            verifyResultsConvertLong4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Long4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongUchar args = new ArgumentsLongUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongUchar {
+        public long inV;
+        public byte out;
+    }
+
+    private void checkConvertUlong2Uchar2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x1fa8b492l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.forEach_testConvertUchar2Ulong2Uchar2(inV, out);
+            verifyResultsConvertUlong2Uchar2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ulong2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar2Ulong2Uchar2(inV, out);
+            verifyResultsConvertUlong2Uchar2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar2Ulong2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Uchar2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongUchar args = new ArgumentsUlongUchar();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUlong2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Uchar3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x15c3d570l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.forEach_testConvertUchar3Ulong3Uchar3(inV, out);
+            verifyResultsConvertUlong3Uchar3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ulong3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar3Ulong3Uchar3(inV, out);
+            verifyResultsConvertUlong3Uchar3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar3Ulong3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Uchar3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongUchar args = new ArgumentsUlongUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Uchar4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xbdef64el, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.forEach_testConvertUchar4Ulong4Uchar4(inV, out);
+            verifyResultsConvertUlong4Uchar4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ulong4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUchar4Ulong4Uchar4(inV, out);
+            verifyResultsConvertUlong4Uchar4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUchar4Ulong4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Uchar4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongUchar args = new ArgumentsUlongUchar();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleShort {
+        public double inV;
+        public short out;
+    }
+
+    private void checkConvertDouble2Short2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0xbf1d55f9l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Double2Short2(inV, out);
+            verifyResultsConvertDouble2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Double2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Double2Short2(inV, out);
+            verifyResultsConvertDouble2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Double2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Short2(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.
+                ArgumentsDoubleShort args = new ArgumentsDoubleShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertDouble2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Short3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xb53876d7l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Double3Short3(inV, out);
+            verifyResultsConvertDouble3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Double3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Double3Short3(inV, out);
+            verifyResultsConvertDouble3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Double3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Short3(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.
+                ArgumentsDoubleShort args = new ArgumentsDoubleShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Short4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0xab5397b5l, -3.2768000000000000000e+04, 3.2767000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Double4Short4(inV, out);
+            verifyResultsConvertDouble4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Double4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Double4Short4(inV, out);
+            verifyResultsConvertDouble4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Double4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Short4(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.
+                ArgumentsDoubleShort args = new ArgumentsDoubleShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongShort {
+        public long inV;
+        public short out;
+    }
+
+    private void checkConvertLong2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x18de6600l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Long2Short2(inV, out);
+            verifyResultsConvertLong2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Long2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Long2Short2(inV, out);
+            verifyResultsConvertLong2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Long2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Short2(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.
+                ArgumentsLongShort args = new ArgumentsLongShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertLong2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xef986del, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Long3Short3(inV, out);
+            verifyResultsConvertLong3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Long3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Long3Short3(inV, out);
+            verifyResultsConvertLong3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Long3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Short3(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.
+                ArgumentsLongShort args = new ArgumentsLongShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x514a7bcl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Long4Short4(inV, out);
+            verifyResultsConvertLong4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Long4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Long4Short4(inV, out);
+            verifyResultsConvertLong4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Long4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Short4(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.
+                ArgumentsLongShort args = new ArgumentsLongShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongShort {
+        public long inV;
+        public short out;
+    }
+
+    private void checkConvertUlong2Short2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xb4b67fabl, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertShort2Ulong2Short2(inV, out);
+            verifyResultsConvertUlong2Short2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ulong2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort2Ulong2Short2(inV, out);
+            verifyResultsConvertUlong2Short2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort2Ulong2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Short2(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.
+                ArgumentsUlongShort args = new ArgumentsUlongShort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUlong2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Short3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0xaad1a089l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertShort3Ulong3Short3(inV, out);
+            verifyResultsConvertUlong3Short3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ulong3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort3Ulong3Short3(inV, out);
+            verifyResultsConvertUlong3Short3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort3Ulong3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Short3(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.
+                ArgumentsUlongShort args = new ArgumentsUlongShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Short4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xa0ecc167l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertShort4Ulong4Short4(inV, out);
+            verifyResultsConvertUlong4Short4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ulong4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertShort4Ulong4Short4(inV, out);
+            verifyResultsConvertUlong4Short4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertShort4Ulong4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Short4(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.
+                ArgumentsUlongShort args = new ArgumentsUlongShort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleUshort {
+        public double inV;
+        public short out;
+    }
+
+    private void checkConvertDouble2Ushort2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0xa92a37bcl, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Double2Ushort2(inV, out);
+            verifyResultsConvertDouble2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Double2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Double2Ushort2(inV, out);
+            verifyResultsConvertDouble2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Double2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Ushort2(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.
+                ArgumentsDoubleUshort args = new ArgumentsDoubleUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertDouble2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Ushort3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0xff85c8e8l, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Double3Ushort3(inV, out);
+            verifyResultsConvertDouble3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Double3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Double3Ushort3(inV, out);
+            verifyResultsConvertDouble3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Double3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Ushort3(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.
+                ArgumentsDoubleUshort args = new ArgumentsDoubleUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Ushort4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x55e15a14l, 0.0000000000000000000e+00, 6.5535000000000000000e+04);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Double4Ushort4(inV, out);
+            verifyResultsConvertDouble4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Double4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Double4Ushort4(inV, out);
+            verifyResultsConvertDouble4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Double4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Ushort4(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.
+                ArgumentsDoubleUshort args = new ArgumentsDoubleUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongUshort {
+        public long inV;
+        public short out;
+    }
+
+    private void checkConvertLong2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xbc97e8e9l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Long2Ushort2(inV, out);
+            verifyResultsConvertLong2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Long2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Long2Ushort2(inV, out);
+            verifyResultsConvertLong2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Long2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Ushort2(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.
+                ArgumentsLongUshort args = new ArgumentsLongUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertLong2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x12f37a15l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Long3Ushort3(inV, out);
+            verifyResultsConvertLong3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Long3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Long3Ushort3(inV, out);
+            verifyResultsConvertLong3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Long3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Ushort3(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.
+                ArgumentsLongUshort args = new ArgumentsLongUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x694f0b41l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Long4Ushort4(inV, out);
+            verifyResultsConvertLong4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Long4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Long4Ushort4(inV, out);
+            verifyResultsConvertLong4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Long4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Ushort4(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.
+                ArgumentsLongUshort args = new ArgumentsLongUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongUshort {
+        public long inV;
+        public short out;
+    }
+
+    private void checkConvertUlong2Ushort2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xe9e438a2l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.forEach_testConvertUshort2Ulong2Ushort2(inV, out);
+            verifyResultsConvertUlong2Ushort2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ulong2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort2Ulong2Ushort2(inV, out);
+            verifyResultsConvertUlong2Ushort2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort2Ulong2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Ushort2(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.
+                ArgumentsUlongUshort args = new ArgumentsUlongUshort();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUlong2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Ushort3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x403fc9cel, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.forEach_testConvertUshort3Ulong3Ushort3(inV, out);
+            verifyResultsConvertUlong3Ushort3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ulong3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort3Ulong3Ushort3(inV, out);
+            verifyResultsConvertUlong3Ushort3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort3Ulong3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Ushort3(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.
+                ArgumentsUlongUshort args = new ArgumentsUlongUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Ushort4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x969b5afal, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.forEach_testConvertUshort4Ulong4Ushort4(inV, out);
+            verifyResultsConvertUlong4Ushort4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ulong4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUshort4Ulong4Ushort4(inV, out);
+            verifyResultsConvertUlong4Ushort4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUshort4Ulong4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Ushort4(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.
+                ArgumentsUlongUshort args = new ArgumentsUlongUshort();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleInt {
+        public double inV;
+        public int out;
+    }
+
+    private void checkConvertDouble2Int2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0xcaf628fcl, -2.1474836480000000000e+09, 2.1474836470000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Double2Int2(inV, out);
+            verifyResultsConvertDouble2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Double2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Double2Int2(inV, out);
+            verifyResultsConvertDouble2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Double2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleInt args = new ArgumentsDoubleInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertDouble2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Int3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x149e3932l, -2.1474836480000000000e+09, 2.1474836470000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Double3Int3(inV, out);
+            verifyResultsConvertDouble3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Double3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Double3Int3(inV, out);
+            verifyResultsConvertDouble3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Double3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleInt args = new ArgumentsDoubleInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Int4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0x5e464968l, -2.1474836480000000000e+09, 2.1474836470000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Double4Int4(inV, out);
+            verifyResultsConvertDouble4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Double4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Double4Int4(inV, out);
+            verifyResultsConvertDouble4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Double4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleInt args = new ArgumentsDoubleInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongInt {
+        public long inV;
+        public int out;
+    }
+
+    private void checkConvertLong2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xe5deba3bl, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Long2Int2(inV, out);
+            verifyResultsConvertLong2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Long2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Long2Int2(inV, out);
+            verifyResultsConvertLong2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Long2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongInt args = new ArgumentsLongInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertLong2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x2f86ca71l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Long3Int3(inV, out);
+            verifyResultsConvertLong3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Long3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Long3Int3(inV, out);
+            verifyResultsConvertLong3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Long3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongInt args = new ArgumentsLongInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x792edaa7l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Long4Int4(inV, out);
+            verifyResultsConvertLong4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Long4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Long4Int4(inV, out);
+            verifyResultsConvertLong4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Long4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongInt args = new ArgumentsLongInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongInt {
+        public long inV;
+        public int out;
+    }
+
+    private void checkConvertUlong2Int2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0xe352de3el, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertInt2Ulong2Int2(inV, out);
+            verifyResultsConvertUlong2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ulong2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt2Ulong2Int2(inV, out);
+            verifyResultsConvertUlong2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt2Ulong2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongInt args = new ArgumentsUlongInt();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUlong2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Int3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x2cfaee74l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertInt3Ulong3Int3(inV, out);
+            verifyResultsConvertUlong3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ulong3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt3Ulong3Int3(inV, out);
+            verifyResultsConvertUlong3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt3Ulong3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongInt args = new ArgumentsUlongInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Int4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x76a2feaal, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertInt4Ulong4Int4(inV, out);
+            verifyResultsConvertUlong4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ulong4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertInt4Ulong4Int4(inV, out);
+            verifyResultsConvertUlong4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertInt4Ulong4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongInt args = new ArgumentsUlongInt();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsDoubleUint {
+        public double inV;
+        public int out;
+    }
+
+    private void checkConvertDouble2Uint2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 2, 0x7de7dd7l, 0.0000000000000000000e+00, 4.2949672950000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Double2Uint2(inV, out);
+            verifyResultsConvertDouble2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Double2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Double2Uint2(inV, out);
+            verifyResultsConvertDouble2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Double2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleUint args = new ArgumentsDoubleUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertDouble2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble3Uint3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 3, 0x66e642cbl, 0.0000000000000000000e+00, 4.2949672950000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Double3Uint3(inV, out);
+            verifyResultsConvertDouble3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Double3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Double3Uint3(inV, out);
+            verifyResultsConvertDouble3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Double3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleUint args = new ArgumentsDoubleUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertDouble4Uint4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_64, 4, 0xc5ee07bfl, 0.0000000000000000000e+00, 4.2949672950000000000e+09);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Double4Uint4(inV, out);
+            verifyResultsConvertDouble4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Double4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Double4Uint4(inV, out);
+            verifyResultsConvertDouble4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Double4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertDouble4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        double[] arrayInV = new double[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (double) 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.
+                ArgumentsDoubleUint args = new ArgumentsDoubleUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertDouble4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongUint {
+        public long inV;
+        public int out;
+    }
+
+    private void checkConvertLong2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x8ceee36cl, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Long2Uint2(inV, out);
+            verifyResultsConvertLong2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Long2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Long2Uint2(inV, out);
+            verifyResultsConvertLong2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Long2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongUint args = new ArgumentsLongUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertLong2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xebf6a860l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Long3Uint3(inV, out);
+            verifyResultsConvertLong3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Long3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Long3Uint3(inV, out);
+            verifyResultsConvertLong3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Long3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongUint args = new ArgumentsLongUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertLong4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x4afe6d54l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Long4Uint4(inV, out);
+            verifyResultsConvertLong4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Long4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Long4Uint4(inV, out);
+            verifyResultsConvertLong4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Long4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertLong4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsLongUint args = new ArgumentsLongUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertLong4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongUint {
+        public long inV;
+        public int out;
+    }
+
+    private void checkConvertUlong2Uint2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x1f70efedl, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.forEach_testConvertUint2Ulong2Uint2(inV, out);
+            verifyResultsConvertUlong2Uint2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ulong2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint2Ulong2Uint2(inV, out);
+            verifyResultsConvertUlong2Uint2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint2Ulong2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong2Uint2(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongUint args = new ArgumentsUlongUint();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUlong2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong3Uint3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x7e78b4e1l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.forEach_testConvertUint3Ulong3Uint3(inV, out);
+            verifyResultsConvertUlong3Uint3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ulong3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint3Ulong3Uint3(inV, out);
+            verifyResultsConvertUlong3Uint3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint3Ulong3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong3Uint3(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongUint args = new ArgumentsUlongUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUlong4Uint4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0xdd8079d5l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.forEach_testConvertUint4Ulong4Uint4(inV, out);
+            verifyResultsConvertUlong4Uint4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ulong4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUint4Ulong4Uint4(inV, out);
+            verifyResultsConvertUlong4Uint4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUint4Ulong4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUlong4Uint4(Allocation inV, Allocation out, boolean relaxed) {
+        long[] arrayInV = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (long) 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.
+                ArgumentsUlongUint args = new ArgumentsUlongUint();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUlong4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatDouble {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertFloat2Double2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x46e08221l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Float2Double2(inV, out);
+            verifyResultsConvertFloat2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Float2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Float2Double2(inV, out);
+            verifyResultsConvertFloat2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Float2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Double2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatDouble args = new ArgumentsFloatDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertFloat2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Double3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9d3c134dl, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Float3Double3(inV, out);
+            verifyResultsConvertFloat3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Float3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Float3Double3(inV, out);
+            verifyResultsConvertFloat3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Float3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Double3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatDouble args = new ArgumentsFloatDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertFloat3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Double4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf397a479l, -1.6163412428744576259e+38, 1.6163412428744576259e+38);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Float4Double4(inV, out);
+            verifyResultsConvertFloat4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Float4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Float4Double4(inV, out);
+            verifyResultsConvertFloat4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Float4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Double4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatDouble args = new ArgumentsFloatDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertFloat4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharDouble {
+        public byte inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertChar2Double2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x68ca2f61l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Char2Double2(inV, out);
+            verifyResultsConvertChar2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Char2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Char2Double2(inV, out);
+            verifyResultsConvertChar2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Char2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Double2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharDouble args = new ArgumentsCharDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertChar2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Double3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0xbf25c08dl, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Char3Double3(inV, out);
+            verifyResultsConvertChar3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Char3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Char3Double3(inV, out);
+            verifyResultsConvertChar3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Char3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Double3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharDouble args = new ArgumentsCharDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertChar3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Double4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x158151b9l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Char4Double4(inV, out);
+            verifyResultsConvertChar4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Char4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Char4Double4(inV, out);
+            verifyResultsConvertChar4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Char4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Double4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharDouble args = new ArgumentsCharDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertChar4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharDouble {
+        public byte inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUchar2Double2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0x96167f1al, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Uchar2Double2(inV, out);
+            verifyResultsConvertUchar2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Uchar2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Uchar2Double2(inV, out);
+            verifyResultsConvertUchar2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Uchar2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Double2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharDouble args = new ArgumentsUcharDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUchar2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Double3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xec721046l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Uchar3Double3(inV, out);
+            verifyResultsConvertUchar3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Uchar3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Uchar3Double3(inV, out);
+            verifyResultsConvertUchar3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Uchar3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Double3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharDouble args = new ArgumentsUcharDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUchar3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Double4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x42cda172l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Uchar4Double4(inV, out);
+            verifyResultsConvertUchar4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Uchar4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Uchar4Double4(inV, out);
+            verifyResultsConvertUchar4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Uchar4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Double4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharDouble args = new ArgumentsUcharDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUchar4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortDouble {
+        public short inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertShort2Double2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x23d0105l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Short2Double2(inV, out);
+            verifyResultsConvertShort2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Short2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Short2Double2(inV, out);
+            verifyResultsConvertShort2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Short2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Double2(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.
+                ArgumentsShortDouble args = new ArgumentsShortDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertShort2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Double3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x58989231l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Short3Double3(inV, out);
+            verifyResultsConvertShort3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Short3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Short3Double3(inV, out);
+            verifyResultsConvertShort3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Short3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Double3(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.
+                ArgumentsShortDouble args = new ArgumentsShortDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertShort3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Double4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xaef4235dl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Short4Double4(inV, out);
+            verifyResultsConvertShort4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Short4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Short4Double4(inV, out);
+            verifyResultsConvertShort4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Short4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Double4(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.
+                ArgumentsShortDouble args = new ArgumentsShortDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertShort4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortDouble {
+        public short inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUshort2Double2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x9e0e6518l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Ushort2Double2(inV, out);
+            verifyResultsConvertUshort2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Ushort2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Ushort2Double2(inV, out);
+            verifyResultsConvertUshort2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Ushort2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Double2(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.
+                ArgumentsUshortDouble args = new ArgumentsUshortDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUshort2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Double3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xf469f644l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Ushort3Double3(inV, out);
+            verifyResultsConvertUshort3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Ushort3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Ushort3Double3(inV, out);
+            verifyResultsConvertUshort3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Ushort3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Double3(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.
+                ArgumentsUshortDouble args = new ArgumentsUshortDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUshort3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Double4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x4ac58770l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Ushort4Double4(inV, out);
+            verifyResultsConvertUshort4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Ushort4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Ushort4Double4(inV, out);
+            verifyResultsConvertUshort4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Ushort4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Double4(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.
+                ArgumentsUshortDouble args = new ArgumentsUshortDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUshort4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntDouble {
+        public int inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertInt2Double2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xa40fc8f6l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Int2Double2(inV, out);
+            verifyResultsConvertInt2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Int2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Int2Double2(inV, out);
+            verifyResultsConvertInt2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Int2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Double2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntDouble args = new ArgumentsIntDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertInt2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Double3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xfa6b5a22l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Int3Double3(inV, out);
+            verifyResultsConvertInt3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Int3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Int3Double3(inV, out);
+            verifyResultsConvertInt3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Int3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Double3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntDouble args = new ArgumentsIntDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertInt3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Double4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x50c6eb4el, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Int4Double4(inV, out);
+            verifyResultsConvertInt4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Int4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Int4Double4(inV, out);
+            verifyResultsConvertInt4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Int4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Double4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntDouble args = new ArgumentsIntDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertInt4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintDouble {
+        public int inV;
+        public Target.Floaty out;
+    }
+
+    private void checkConvertUint2Double2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x3fe7e2a1l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            script.forEach_testConvertDouble2Uint2Double2(inV, out);
+            verifyResultsConvertUint2Double2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Uint2Double2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble2Uint2Double2(inV, out);
+            verifyResultsConvertUint2Double2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble2Uint2Double2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Double2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintDouble args = new ArgumentsUintDouble();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUint2Double2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Double3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x964373cdl, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            script.forEach_testConvertDouble3Uint3Double3(inV, out);
+            verifyResultsConvertUint3Double3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Uint3Double3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble3Uint3Double3(inV, out);
+            verifyResultsConvertUint3Double3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble3Uint3Double3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Double3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintDouble args = new ArgumentsUintDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUint3Double3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Double4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xec9f04f9l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            script.forEach_testConvertDouble4Uint4Double4(inV, out);
+            verifyResultsConvertUint4Double4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Uint4Double4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertDouble4Uint4Double4(inV, out);
+            verifyResultsConvertUint4Double4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertDouble4Uint4Double4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Double4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintDouble args = new ArgumentsUintDouble();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(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 checkConvertUint4Double4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatLong {
+        public float inV;
+        public long out;
+    }
+
+    private void checkConvertFloat2Long2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7d7c0ae0l, -1.0000000000000000000e+00, 0.0000000000000000000e+00);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Float2Long2(inV, out);
+            verifyResultsConvertFloat2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Float2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Float2Long2(inV, out);
+            verifyResultsConvertFloat2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Float2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Long2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatLong args = new ArgumentsFloatLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertFloat2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Long3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdc83cfd4l, -1.0000000000000000000e+00, 0.0000000000000000000e+00);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Float3Long3(inV, out);
+            verifyResultsConvertFloat3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Float3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Float3Long3(inV, out);
+            verifyResultsConvertFloat3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Float3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Long3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatLong args = new ArgumentsFloatLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Long4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3b8b94c8l, -1.0000000000000000000e+00, 0.0000000000000000000e+00);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Float4Long4(inV, out);
+            verifyResultsConvertFloat4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Float4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Float4Long4(inV, out);
+            verifyResultsConvertFloat4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Float4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Long4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatLong args = new ArgumentsFloatLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharLong {
+        public byte inV;
+        public long out;
+    }
+
+    private void checkConvertChar2Long2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x290be220l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Char2Long2(inV, out);
+            verifyResultsConvertChar2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Char2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Char2Long2(inV, out);
+            verifyResultsConvertChar2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Char2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Long2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharLong args = new ArgumentsCharLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertChar2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Long3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x8813a714l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Char3Long3(inV, out);
+            verifyResultsConvertChar3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Char3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Char3Long3(inV, out);
+            verifyResultsConvertChar3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Char3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Long3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharLong args = new ArgumentsCharLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Long4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xe71b6c08l, true, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Char4Long4(inV, out);
+            verifyResultsConvertChar4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Char4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Char4Long4(inV, out);
+            verifyResultsConvertChar4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Char4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Long4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharLong args = new ArgumentsCharLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharLong {
+        public byte inV;
+        public long out;
+    }
+
+    private void checkConvertUchar2Long2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xbb8deea1l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Uchar2Long2(inV, out);
+            verifyResultsConvertUchar2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Uchar2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Uchar2Long2(inV, out);
+            verifyResultsConvertUchar2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Uchar2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Long2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharLong args = new ArgumentsUcharLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUchar2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Long3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0x1a95b395l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Uchar3Long3(inV, out);
+            verifyResultsConvertUchar3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Uchar3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Uchar3Long3(inV, out);
+            verifyResultsConvertUchar3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Uchar3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Long3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharLong args = new ArgumentsUcharLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Long4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0x799d7889l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Uchar4Long4(inV, out);
+            verifyResultsConvertUchar4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Uchar4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Uchar4Long4(inV, out);
+            verifyResultsConvertUchar4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Uchar4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Long4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharLong args = new ArgumentsUcharLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortLong {
+        public short inV;
+        public long out;
+    }
+
+    private void checkConvertShort2Long2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x69c97ce4l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Short2Long2(inV, out);
+            verifyResultsConvertShort2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Short2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Short2Long2(inV, out);
+            verifyResultsConvertShort2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Short2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Long2(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.
+                ArgumentsShortLong args = new ArgumentsShortLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertShort2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Long3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xc8d141d8l, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Short3Long3(inV, out);
+            verifyResultsConvertShort3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Short3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Short3Long3(inV, out);
+            verifyResultsConvertShort3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Short3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Long3(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.
+                ArgumentsShortLong args = new ArgumentsShortLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Long4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x27d906ccl, true, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Short4Long4(inV, out);
+            verifyResultsConvertShort4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Short4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Short4Long4(inV, out);
+            verifyResultsConvertShort4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Short4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Long4(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.
+                ArgumentsShortLong args = new ArgumentsShortLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortLong {
+        public short inV;
+        public long out;
+    }
+
+    private void checkConvertUshort2Long2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x5a1968fl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Ushort2Long2(inV, out);
+            verifyResultsConvertUshort2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Ushort2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Ushort2Long2(inV, out);
+            verifyResultsConvertUshort2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Ushort2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Long2(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.
+                ArgumentsUshortLong args = new ArgumentsUshortLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUshort2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Long3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x64a95b83l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Ushort3Long3(inV, out);
+            verifyResultsConvertUshort3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Ushort3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Ushort3Long3(inV, out);
+            verifyResultsConvertUshort3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Ushort3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Long3(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.
+                ArgumentsUshortLong args = new ArgumentsUshortLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Long4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xc3b12077l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Ushort4Long4(inV, out);
+            verifyResultsConvertUshort4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Ushort4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Ushort4Long4(inV, out);
+            verifyResultsConvertUshort4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Ushort4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Long4(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.
+                ArgumentsUshortLong args = new ArgumentsUshortLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntLong {
+        public int inV;
+        public long out;
+    }
+
+    private void checkConvertInt2Long2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x8a45cb5dl, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Int2Long2(inV, out);
+            verifyResultsConvertInt2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Int2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Int2Long2(inV, out);
+            verifyResultsConvertInt2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Int2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Long2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntLong args = new ArgumentsIntLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertInt2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Long3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xe94d9051l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Int3Long3(inV, out);
+            verifyResultsConvertInt3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Int3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Int3Long3(inV, out);
+            verifyResultsConvertInt3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Int3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Long3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntLong args = new ArgumentsIntLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Long4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x48555545l, true, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Int4Long4(inV, out);
+            verifyResultsConvertInt4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Int4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Int4Long4(inV, out);
+            verifyResultsConvertInt4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Int4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Long4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntLong args = new ArgumentsIntLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintLong {
+        public int inV;
+        public long out;
+    }
+
+    private void checkConvertUint2Long2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x87b9ef60l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertLong2Uint2Long2(inV, out);
+            verifyResultsConvertUint2Long2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Uint2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong2Uint2Long2(inV, out);
+            verifyResultsConvertUint2Long2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong2Uint2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Long2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintLong args = new ArgumentsUintLong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUint2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Long3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xe6c1b454l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertLong3Uint3Long3(inV, out);
+            verifyResultsConvertUint3Long3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Uint3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong3Uint3Long3(inV, out);
+            verifyResultsConvertUint3Long3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong3Uint3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Long3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintLong args = new ArgumentsUintLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Long4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x45c97948l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertLong4Uint4Long4(inV, out);
+            verifyResultsConvertUint4Long4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Uint4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertLong4Uint4Long4(inV, out);
+            verifyResultsConvertUint4Long4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertLong4Uint4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Long4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintLong args = new ArgumentsUintLong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatUlong {
+        public float inV;
+        public long out;
+    }
+
+    private void checkConvertFloat2Ulong2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4ec4cff7l, 0.0000000000000000000e+00, 0.0000000000000000000e+00);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Float2Ulong2(inV, out);
+            verifyResultsConvertFloat2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Float2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Float2Ulong2(inV, out);
+            verifyResultsConvertFloat2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Float2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatUlong args = new ArgumentsFloatUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertFloat2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat3Ulong3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x44dff0d5l, 0.0000000000000000000e+00, 0.0000000000000000000e+00);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Float3Ulong3(inV, out);
+            verifyResultsConvertFloat3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Float3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Float3Ulong3(inV, out);
+            verifyResultsConvertFloat3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Float3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatUlong args = new ArgumentsFloatUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertFloat4Ulong4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3afb11b3l, 0.0000000000000000000e+00, 0.0000000000000000000e+00);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Float4Ulong4(inV, out);
+            verifyResultsConvertFloat4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Float4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Float4Ulong4(inV, out);
+            verifyResultsConvertFloat4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Float4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertFloat4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatUlong args = new ArgumentsFloatUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertFloat4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsCharUlong {
+        public byte inV;
+        public long out;
+    }
+
+    private void checkConvertChar2Ulong2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x1fedf7b7l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Char2Ulong2(inV, out);
+            verifyResultsConvertChar2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Char2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Char2Ulong2(inV, out);
+            verifyResultsConvertChar2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Char2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUlong args = new ArgumentsCharUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertChar2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar3Ulong3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x16091895l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Char3Ulong3(inV, out);
+            verifyResultsConvertChar3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Char3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Char3Ulong3(inV, out);
+            verifyResultsConvertChar3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Char3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUlong args = new ArgumentsCharUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertChar4Ulong4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xc243973l, false, 7);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Char4Ulong4(inV, out);
+            verifyResultsConvertChar4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Char4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Char4Ulong4(inV, out);
+            verifyResultsConvertChar4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Char4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertChar4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsCharUlong args = new ArgumentsCharUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertChar4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharUlong {
+        public byte inV;
+        public long out;
+    }
+
+    private void checkConvertUchar2Ulong2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xbbc61162l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Uchar2Ulong2(inV, out);
+            verifyResultsConvertUchar2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Uchar2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Uchar2Ulong2(inV, out);
+            verifyResultsConvertUchar2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Uchar2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharUlong args = new ArgumentsUcharUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUchar2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar3Ulong3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xb1e13240l, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Uchar3Ulong3(inV, out);
+            verifyResultsConvertUchar3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Uchar3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Uchar3Ulong3(inV, out);
+            verifyResultsConvertUchar3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Uchar3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharUlong args = new ArgumentsUcharUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUchar4Ulong4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xa7fc531el, false, 8);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Uchar4Ulong4(inV, out);
+            verifyResultsConvertUchar4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Uchar4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Uchar4Ulong4(inV, out);
+            verifyResultsConvertUchar4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Uchar4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUchar4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
+        byte[] arrayInV = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (byte) 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.
+                ArgumentsUcharUlong args = new ArgumentsUcharUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUchar4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortUlong {
+        public short inV;
+        public long out;
+    }
+
+    private void checkConvertShort2Ulong2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 2, 0xffc6f6a3l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Short2Ulong2(inV, out);
+            verifyResultsConvertShort2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Short2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Short2Ulong2(inV, out);
+            verifyResultsConvertShort2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Short2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort2Ulong2(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.
+                ArgumentsShortUlong args = new ArgumentsShortUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertShort2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort3Ulong3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 3, 0xf5e21781l, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Short3Ulong3(inV, out);
+            verifyResultsConvertShort3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Short3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Short3Ulong3(inV, out);
+            verifyResultsConvertShort3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Short3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort3Ulong3(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.
+                ArgumentsShortUlong args = new ArgumentsShortUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertShort4Ulong4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_16, 4, 0xebfd385fl, false, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Short4Ulong4(inV, out);
+            verifyResultsConvertShort4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Short4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Short4Ulong4(inV, out);
+            verifyResultsConvertShort4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Short4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertShort4Ulong4(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.
+                ArgumentsShortUlong args = new ArgumentsShortUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertShort4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortUlong {
+        public short inV;
+        public long out;
+    }
+
+    private void checkConvertUshort2Ulong2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x2d13465cl, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Ushort2Ulong2(inV, out);
+            verifyResultsConvertUshort2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Ushort2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Ushort2Ulong2(inV, out);
+            verifyResultsConvertUshort2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Ushort2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort2Ulong2(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.
+                ArgumentsUshortUlong args = new ArgumentsUshortUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUshort2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort3Ulong3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x232e673al, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Ushort3Ulong3(inV, out);
+            verifyResultsConvertUshort3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Ushort3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Ushort3Ulong3(inV, out);
+            verifyResultsConvertUshort3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Ushort3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort3Ulong3(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.
+                ArgumentsUshortUlong args = new ArgumentsUshortUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUshort4Ulong4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x19498818l, false, 16);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Ushort4Ulong4(inV, out);
+            verifyResultsConvertUshort4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Ushort4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Ushort4Ulong4(inV, out);
+            verifyResultsConvertUshort4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Ushort4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUshort4Ulong4(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.
+                ArgumentsUshortUlong args = new ArgumentsUshortUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUshort4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntUlong {
+        public int inV;
+        public long out;
+    }
+
+    private void checkConvertInt2Ulong2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x74a824f6l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Int2Ulong2(inV, out);
+            verifyResultsConvertInt2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Int2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Int2Ulong2(inV, out);
+            verifyResultsConvertInt2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Int2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUlong args = new ArgumentsIntUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertInt2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt3Ulong3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x6ac345d4l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Int3Ulong3(inV, out);
+            verifyResultsConvertInt3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Int3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Int3Ulong3(inV, out);
+            verifyResultsConvertInt3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Int3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUlong args = new ArgumentsIntUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertInt4Ulong4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x60de66b2l, false, 31);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Int4Ulong4(inV, out);
+            verifyResultsConvertInt4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Int4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Int4Ulong4(inV, out);
+            verifyResultsConvertInt4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Int4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertInt4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsIntUlong args = new ArgumentsIntUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertInt4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintUlong {
+        public int inV;
+        public long out;
+    }
+
+    private void checkConvertUint2Ulong2() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0x72a3177l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.forEach_testConvertUlong2Uint2Ulong2(inV, out);
+            verifyResultsConvertUint2Ulong2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Uint2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong2Uint2Ulong2(inV, out);
+            verifyResultsConvertUint2Ulong2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong2Uint2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint2Ulong2(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintUlong args = new ArgumentsUintUlong();
+                args.inV = arrayInV[i * 2 + j];
+                // 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 checkConvertUint2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint3Ulong3() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0xfd455255l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.forEach_testConvertUlong3Uint3Ulong3(inV, out);
+            verifyResultsConvertUint3Ulong3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Uint3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong3Uint3Ulong3(inV, out);
+            verifyResultsConvertUint3Ulong3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong3Uint3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint3Ulong3(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintUlong args = new ArgumentsUintUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkConvertUint4Ulong4() {
+        Allocation inV = createRandomIntegerAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xf3607333l, false, 32);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.forEach_testConvertUlong4Uint4Ulong4(inV, out);
+            verifyResultsConvertUint4Ulong4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Uint4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testConvertUlong4Uint4Ulong4(inV, out);
+            verifyResultsConvertUint4Ulong4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testConvertUlong4Uint4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsConvertUint4Ulong4(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (int) 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.
+                ArgumentsUintUlong args = new ArgumentsUintUlong();
+                args.inV = arrayInV[i * 4 + j];
+                // 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 checkConvertUint4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testConvert() {
+        checkConvertFloat2Float2();
+        checkConvertFloat3Float3();
+        checkConvertFloat4Float4();
+        checkConvertChar2Float2();
+        checkConvertChar3Float3();
+        checkConvertChar4Float4();
+        checkConvertUchar2Float2();
+        checkConvertUchar3Float3();
+        checkConvertUchar4Float4();
+        checkConvertShort2Float2();
+        checkConvertShort3Float3();
+        checkConvertShort4Float4();
+        checkConvertUshort2Float2();
+        checkConvertUshort3Float3();
+        checkConvertUshort4Float4();
+        checkConvertInt2Float2();
+        checkConvertInt3Float3();
+        checkConvertInt4Float4();
+        checkConvertUint2Float2();
+        checkConvertUint3Float3();
+        checkConvertUint4Float4();
+        checkConvertFloat2Char2();
+        checkConvertFloat3Char3();
+        checkConvertFloat4Char4();
+        checkConvertChar2Char2();
+        checkConvertChar3Char3();
+        checkConvertChar4Char4();
+        checkConvertUchar2Char2();
+        checkConvertUchar3Char3();
+        checkConvertUchar4Char4();
+        checkConvertShort2Char2();
+        checkConvertShort3Char3();
+        checkConvertShort4Char4();
+        checkConvertUshort2Char2();
+        checkConvertUshort3Char3();
+        checkConvertUshort4Char4();
+        checkConvertInt2Char2();
+        checkConvertInt3Char3();
+        checkConvertInt4Char4();
+        checkConvertUint2Char2();
+        checkConvertUint3Char3();
+        checkConvertUint4Char4();
+        checkConvertFloat2Uchar2();
+        checkConvertFloat3Uchar3();
+        checkConvertFloat4Uchar4();
+        checkConvertChar2Uchar2();
+        checkConvertChar3Uchar3();
+        checkConvertChar4Uchar4();
+        checkConvertUchar2Uchar2();
+        checkConvertUchar3Uchar3();
+        checkConvertUchar4Uchar4();
+        checkConvertShort2Uchar2();
+        checkConvertShort3Uchar3();
+        checkConvertShort4Uchar4();
+        checkConvertUshort2Uchar2();
+        checkConvertUshort3Uchar3();
+        checkConvertUshort4Uchar4();
+        checkConvertInt2Uchar2();
+        checkConvertInt3Uchar3();
+        checkConvertInt4Uchar4();
+        checkConvertUint2Uchar2();
+        checkConvertUint3Uchar3();
+        checkConvertUint4Uchar4();
+        checkConvertFloat2Short2();
+        checkConvertFloat3Short3();
+        checkConvertFloat4Short4();
+        checkConvertChar2Short2();
+        checkConvertChar3Short3();
+        checkConvertChar4Short4();
+        checkConvertUchar2Short2();
+        checkConvertUchar3Short3();
+        checkConvertUchar4Short4();
+        checkConvertShort2Short2();
+        checkConvertShort3Short3();
+        checkConvertShort4Short4();
+        checkConvertUshort2Short2();
+        checkConvertUshort3Short3();
+        checkConvertUshort4Short4();
+        checkConvertInt2Short2();
+        checkConvertInt3Short3();
+        checkConvertInt4Short4();
+        checkConvertUint2Short2();
+        checkConvertUint3Short3();
+        checkConvertUint4Short4();
+        checkConvertFloat2Ushort2();
+        checkConvertFloat3Ushort3();
+        checkConvertFloat4Ushort4();
+        checkConvertChar2Ushort2();
+        checkConvertChar3Ushort3();
+        checkConvertChar4Ushort4();
+        checkConvertUchar2Ushort2();
+        checkConvertUchar3Ushort3();
+        checkConvertUchar4Ushort4();
+        checkConvertShort2Ushort2();
+        checkConvertShort3Ushort3();
+        checkConvertShort4Ushort4();
+        checkConvertUshort2Ushort2();
+        checkConvertUshort3Ushort3();
+        checkConvertUshort4Ushort4();
+        checkConvertInt2Ushort2();
+        checkConvertInt3Ushort3();
+        checkConvertInt4Ushort4();
+        checkConvertUint2Ushort2();
+        checkConvertUint3Ushort3();
+        checkConvertUint4Ushort4();
+        checkConvertFloat2Int2();
+        checkConvertFloat3Int3();
+        checkConvertFloat4Int4();
+        checkConvertChar2Int2();
+        checkConvertChar3Int3();
+        checkConvertChar4Int4();
+        checkConvertUchar2Int2();
+        checkConvertUchar3Int3();
+        checkConvertUchar4Int4();
+        checkConvertShort2Int2();
+        checkConvertShort3Int3();
+        checkConvertShort4Int4();
+        checkConvertUshort2Int2();
+        checkConvertUshort3Int3();
+        checkConvertUshort4Int4();
+        checkConvertInt2Int2();
+        checkConvertInt3Int3();
+        checkConvertInt4Int4();
+        checkConvertUint2Int2();
+        checkConvertUint3Int3();
+        checkConvertUint4Int4();
+        checkConvertFloat2Uint2();
+        checkConvertFloat3Uint3();
+        checkConvertFloat4Uint4();
+        checkConvertChar2Uint2();
+        checkConvertChar3Uint3();
+        checkConvertChar4Uint4();
+        checkConvertUchar2Uint2();
+        checkConvertUchar3Uint3();
+        checkConvertUchar4Uint4();
+        checkConvertShort2Uint2();
+        checkConvertShort3Uint3();
+        checkConvertShort4Uint4();
+        checkConvertUshort2Uint2();
+        checkConvertUshort3Uint3();
+        checkConvertUshort4Uint4();
+        checkConvertInt2Uint2();
+        checkConvertInt3Uint3();
+        checkConvertInt4Uint4();
+        checkConvertUint2Uint2();
+        checkConvertUint3Uint3();
+        checkConvertUint4Uint4();
+        checkConvertDouble2Double2();
+        checkConvertDouble3Double3();
+        checkConvertDouble4Double4();
+        checkConvertLong2Double2();
+        checkConvertLong3Double3();
+        checkConvertLong4Double4();
+        checkConvertUlong2Double2();
+        checkConvertUlong3Double3();
+        checkConvertUlong4Double4();
+        checkConvertDouble2Long2();
+        checkConvertDouble3Long3();
+        checkConvertDouble4Long4();
+        checkConvertLong2Long2();
+        checkConvertLong3Long3();
+        checkConvertLong4Long4();
+        checkConvertUlong2Long2();
+        checkConvertUlong3Long3();
+        checkConvertUlong4Long4();
+        checkConvertDouble2Ulong2();
+        checkConvertDouble3Ulong3();
+        checkConvertDouble4Ulong4();
+        checkConvertLong2Ulong2();
+        checkConvertLong3Ulong3();
+        checkConvertLong4Ulong4();
+        checkConvertUlong2Ulong2();
+        checkConvertUlong3Ulong3();
+        checkConvertUlong4Ulong4();
+        checkConvertDouble2Float2();
+        checkConvertDouble3Float3();
+        checkConvertDouble4Float4();
+        checkConvertLong2Float2();
+        checkConvertLong3Float3();
+        checkConvertLong4Float4();
+        checkConvertUlong2Float2();
+        checkConvertUlong3Float3();
+        checkConvertUlong4Float4();
+        checkConvertDouble2Char2();
+        checkConvertDouble3Char3();
+        checkConvertDouble4Char4();
+        checkConvertLong2Char2();
+        checkConvertLong3Char3();
+        checkConvertLong4Char4();
+        checkConvertUlong2Char2();
+        checkConvertUlong3Char3();
+        checkConvertUlong4Char4();
+        checkConvertDouble2Uchar2();
+        checkConvertDouble3Uchar3();
+        checkConvertDouble4Uchar4();
+        checkConvertLong2Uchar2();
+        checkConvertLong3Uchar3();
+        checkConvertLong4Uchar4();
+        checkConvertUlong2Uchar2();
+        checkConvertUlong3Uchar3();
+        checkConvertUlong4Uchar4();
+        checkConvertDouble2Short2();
+        checkConvertDouble3Short3();
+        checkConvertDouble4Short4();
+        checkConvertLong2Short2();
+        checkConvertLong3Short3();
+        checkConvertLong4Short4();
+        checkConvertUlong2Short2();
+        checkConvertUlong3Short3();
+        checkConvertUlong4Short4();
+        checkConvertDouble2Ushort2();
+        checkConvertDouble3Ushort3();
+        checkConvertDouble4Ushort4();
+        checkConvertLong2Ushort2();
+        checkConvertLong3Ushort3();
+        checkConvertLong4Ushort4();
+        checkConvertUlong2Ushort2();
+        checkConvertUlong3Ushort3();
+        checkConvertUlong4Ushort4();
+        checkConvertDouble2Int2();
+        checkConvertDouble3Int3();
+        checkConvertDouble4Int4();
+        checkConvertLong2Int2();
+        checkConvertLong3Int3();
+        checkConvertLong4Int4();
+        checkConvertUlong2Int2();
+        checkConvertUlong3Int3();
+        checkConvertUlong4Int4();
+        checkConvertDouble2Uint2();
+        checkConvertDouble3Uint3();
+        checkConvertDouble4Uint4();
+        checkConvertLong2Uint2();
+        checkConvertLong3Uint3();
+        checkConvertLong4Uint4();
+        checkConvertUlong2Uint2();
+        checkConvertUlong3Uint3();
+        checkConvertUlong4Uint4();
+        checkConvertFloat2Double2();
+        checkConvertFloat3Double3();
+        checkConvertFloat4Double4();
+        checkConvertChar2Double2();
+        checkConvertChar3Double3();
+        checkConvertChar4Double4();
+        checkConvertUchar2Double2();
+        checkConvertUchar3Double3();
+        checkConvertUchar4Double4();
+        checkConvertShort2Double2();
+        checkConvertShort3Double3();
+        checkConvertShort4Double4();
+        checkConvertUshort2Double2();
+        checkConvertUshort3Double3();
+        checkConvertUshort4Double4();
+        checkConvertInt2Double2();
+        checkConvertInt3Double3();
+        checkConvertInt4Double4();
+        checkConvertUint2Double2();
+        checkConvertUint3Double3();
+        checkConvertUint4Double4();
+        checkConvertFloat2Long2();
+        checkConvertFloat3Long3();
+        checkConvertFloat4Long4();
+        checkConvertChar2Long2();
+        checkConvertChar3Long3();
+        checkConvertChar4Long4();
+        checkConvertUchar2Long2();
+        checkConvertUchar3Long3();
+        checkConvertUchar4Long4();
+        checkConvertShort2Long2();
+        checkConvertShort3Long3();
+        checkConvertShort4Long4();
+        checkConvertUshort2Long2();
+        checkConvertUshort3Long3();
+        checkConvertUshort4Long4();
+        checkConvertInt2Long2();
+        checkConvertInt3Long3();
+        checkConvertInt4Long4();
+        checkConvertUint2Long2();
+        checkConvertUint3Long3();
+        checkConvertUint4Long4();
+        checkConvertFloat2Ulong2();
+        checkConvertFloat3Ulong3();
+        checkConvertFloat4Ulong4();
+        checkConvertChar2Ulong2();
+        checkConvertChar3Ulong3();
+        checkConvertChar4Ulong4();
+        checkConvertUchar2Ulong2();
+        checkConvertUchar3Ulong3();
+        checkConvertUchar4Ulong4();
+        checkConvertShort2Ulong2();
+        checkConvertShort3Ulong3();
+        checkConvertShort4Ulong4();
+        checkConvertUshort2Ulong2();
+        checkConvertUshort3Ulong3();
+        checkConvertUshort4Ulong4();
+        checkConvertInt2Ulong2();
+        checkConvertInt3Ulong3();
+        checkConvertInt4Ulong4();
+        checkConvertUint2Ulong2();
+        checkConvertUint3Ulong3();
+        checkConvertUint4Ulong4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.rs
new file mode 100644
index 0000000..d307e92
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvert.rs
@@ -0,0 +1,1221 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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)
+
+
+float2 __attribute__((kernel)) testConvertFloat2Float2Float2(float2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Float3Float3(float3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Float4Float4(float4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Char2Float2(char2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Char3Float3(char3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Char4Float4(char4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Uchar2Float2(uchar2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Uchar3Float3(uchar3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Uchar4Float4(uchar4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Short2Float2(short2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Short3Float3(short3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Short4Float4(short4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Ushort2Float2(ushort2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Ushort3Float3(ushort3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Ushort4Float4(ushort4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Int2Float2(int2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Int3Float3(int3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Int4Float4(int4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Uint2Float2(uint2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Uint3Float3(uint3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Uint4Float4(uint4 inV) {
+    return convert_float4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Float2Char2(float2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Float3Char3(float3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Float4Char4(float4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Char2Char2(char2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Char3Char3(char3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Char4Char4(char4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Uchar2Char2(uchar2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Uchar3Char3(uchar3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Uchar4Char4(uchar4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Short2Char2(short2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Short3Char3(short3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Short4Char4(short4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Ushort2Char2(ushort2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Ushort3Char3(ushort3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Ushort4Char4(ushort4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Int2Char2(int2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Int3Char3(int3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Int4Char4(int4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Uint2Char2(uint2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Uint3Char3(uint3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Uint4Char4(uint4 inV) {
+    return convert_char4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Float2Uchar2(float2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Float3Uchar3(float3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Float4Uchar4(float4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Char2Uchar2(char2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Char3Uchar3(char3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Char4Uchar4(char4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Uchar2Uchar2(uchar2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Uchar3Uchar3(uchar3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Uchar4Uchar4(uchar4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Short2Uchar2(short2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Short3Uchar3(short3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Short4Uchar4(short4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Ushort2Uchar2(ushort2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Ushort3Uchar3(ushort3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Ushort4Uchar4(ushort4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Int2Uchar2(int2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Int3Uchar3(int3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Int4Uchar4(int4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Uint2Uchar2(uint2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Uint3Uchar3(uint3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Uint4Uchar4(uint4 inV) {
+    return convert_uchar4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Float2Short2(float2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Float3Short3(float3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Float4Short4(float4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Char2Short2(char2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Char3Short3(char3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Char4Short4(char4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Uchar2Short2(uchar2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Uchar3Short3(uchar3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Uchar4Short4(uchar4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Short2Short2(short2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Short3Short3(short3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Short4Short4(short4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Ushort2Short2(ushort2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Ushort3Short3(ushort3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Ushort4Short4(ushort4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Int2Short2(int2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Int3Short3(int3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Int4Short4(int4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Uint2Short2(uint2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Uint3Short3(uint3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Uint4Short4(uint4 inV) {
+    return convert_short4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Float2Ushort2(float2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Float3Ushort3(float3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Float4Ushort4(float4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Char2Ushort2(char2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Char3Ushort3(char3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Char4Ushort4(char4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Uchar2Ushort2(uchar2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Uchar3Ushort3(uchar3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Uchar4Ushort4(uchar4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Short2Ushort2(short2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Short3Ushort3(short3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Short4Ushort4(short4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Ushort2Ushort2(ushort2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Ushort3Ushort3(ushort3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Ushort4Ushort4(ushort4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Int2Ushort2(int2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Int3Ushort3(int3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Int4Ushort4(int4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Uint2Ushort2(uint2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Uint3Ushort3(uint3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Uint4Ushort4(uint4 inV) {
+    return convert_ushort4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Float2Int2(float2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Float3Int3(float3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Float4Int4(float4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Char2Int2(char2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Char3Int3(char3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Char4Int4(char4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Uchar2Int2(uchar2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Uchar3Int3(uchar3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Uchar4Int4(uchar4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Short2Int2(short2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Short3Int3(short3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Short4Int4(short4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Ushort2Int2(ushort2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Ushort3Int3(ushort3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Ushort4Int4(ushort4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Int2Int2(int2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Int3Int3(int3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Int4Int4(int4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Uint2Int2(uint2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Uint3Int3(uint3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Uint4Int4(uint4 inV) {
+    return convert_int4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Float2Uint2(float2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Float3Uint3(float3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Float4Uint4(float4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Char2Uint2(char2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Char3Uint3(char3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Char4Uint4(char4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Uchar2Uint2(uchar2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Uchar3Uint3(uchar3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Uchar4Uint4(uchar4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Short2Uint2(short2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Short3Uint3(short3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Short4Uint4(short4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Ushort2Uint2(ushort2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Ushort3Uint3(ushort3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Ushort4Uint4(ushort4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Int2Uint2(int2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Int3Uint3(int3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Int4Uint4(int4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Uint2Uint2(uint2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Uint3Uint3(uint3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Uint4Uint4(uint4 inV) {
+    return convert_uint4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Double2Double2(double2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Double3Double3(double3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Double4Double4(double4 inV) {
+    return convert_double4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Long2Double2(long2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Long3Double3(long3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Long4Double4(long4 inV) {
+    return convert_double4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Ulong2Double2(ulong2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Ulong3Double3(ulong3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Ulong4Double4(ulong4 inV) {
+    return convert_double4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Double2Long2(double2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Double3Long3(double3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Double4Long4(double4 inV) {
+    return convert_long4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Long2Long2(long2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Long3Long3(long3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Long4Long4(long4 inV) {
+    return convert_long4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Ulong2Long2(ulong2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Ulong3Long3(ulong3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Ulong4Long4(ulong4 inV) {
+    return convert_long4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Double2Ulong2(double2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Double3Ulong3(double3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Double4Ulong4(double4 inV) {
+    return convert_ulong4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Long2Ulong2(long2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Long3Ulong3(long3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Long4Ulong4(long4 inV) {
+    return convert_ulong4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Ulong2Ulong2(ulong2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Ulong3Ulong3(ulong3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Ulong4Ulong4(ulong4 inV) {
+    return convert_ulong4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Double2Float2(double2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Double3Float3(double3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Double4Float4(double4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Long2Float2(long2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Long3Float3(long3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Long4Float4(long4 inV) {
+    return convert_float4(inV);
+}
+
+float2 __attribute__((kernel)) testConvertFloat2Ulong2Float2(ulong2 inV) {
+    return convert_float2(inV);
+}
+
+float3 __attribute__((kernel)) testConvertFloat3Ulong3Float3(ulong3 inV) {
+    return convert_float3(inV);
+}
+
+float4 __attribute__((kernel)) testConvertFloat4Ulong4Float4(ulong4 inV) {
+    return convert_float4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Double2Char2(double2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Double3Char3(double3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Double4Char4(double4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Long2Char2(long2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Long3Char3(long3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Long4Char4(long4 inV) {
+    return convert_char4(inV);
+}
+
+char2 __attribute__((kernel)) testConvertChar2Ulong2Char2(ulong2 inV) {
+    return convert_char2(inV);
+}
+
+char3 __attribute__((kernel)) testConvertChar3Ulong3Char3(ulong3 inV) {
+    return convert_char3(inV);
+}
+
+char4 __attribute__((kernel)) testConvertChar4Ulong4Char4(ulong4 inV) {
+    return convert_char4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Double2Uchar2(double2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Double3Uchar3(double3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Double4Uchar4(double4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Long2Uchar2(long2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Long3Uchar3(long3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Long4Uchar4(long4 inV) {
+    return convert_uchar4(inV);
+}
+
+uchar2 __attribute__((kernel)) testConvertUchar2Ulong2Uchar2(ulong2 inV) {
+    return convert_uchar2(inV);
+}
+
+uchar3 __attribute__((kernel)) testConvertUchar3Ulong3Uchar3(ulong3 inV) {
+    return convert_uchar3(inV);
+}
+
+uchar4 __attribute__((kernel)) testConvertUchar4Ulong4Uchar4(ulong4 inV) {
+    return convert_uchar4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Double2Short2(double2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Double3Short3(double3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Double4Short4(double4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Long2Short2(long2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Long3Short3(long3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Long4Short4(long4 inV) {
+    return convert_short4(inV);
+}
+
+short2 __attribute__((kernel)) testConvertShort2Ulong2Short2(ulong2 inV) {
+    return convert_short2(inV);
+}
+
+short3 __attribute__((kernel)) testConvertShort3Ulong3Short3(ulong3 inV) {
+    return convert_short3(inV);
+}
+
+short4 __attribute__((kernel)) testConvertShort4Ulong4Short4(ulong4 inV) {
+    return convert_short4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Double2Ushort2(double2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Double3Ushort3(double3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Double4Ushort4(double4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Long2Ushort2(long2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Long3Ushort3(long3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Long4Ushort4(long4 inV) {
+    return convert_ushort4(inV);
+}
+
+ushort2 __attribute__((kernel)) testConvertUshort2Ulong2Ushort2(ulong2 inV) {
+    return convert_ushort2(inV);
+}
+
+ushort3 __attribute__((kernel)) testConvertUshort3Ulong3Ushort3(ulong3 inV) {
+    return convert_ushort3(inV);
+}
+
+ushort4 __attribute__((kernel)) testConvertUshort4Ulong4Ushort4(ulong4 inV) {
+    return convert_ushort4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Double2Int2(double2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Double3Int3(double3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Double4Int4(double4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Long2Int2(long2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Long3Int3(long3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Long4Int4(long4 inV) {
+    return convert_int4(inV);
+}
+
+int2 __attribute__((kernel)) testConvertInt2Ulong2Int2(ulong2 inV) {
+    return convert_int2(inV);
+}
+
+int3 __attribute__((kernel)) testConvertInt3Ulong3Int3(ulong3 inV) {
+    return convert_int3(inV);
+}
+
+int4 __attribute__((kernel)) testConvertInt4Ulong4Int4(ulong4 inV) {
+    return convert_int4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Double2Uint2(double2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Double3Uint3(double3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Double4Uint4(double4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Long2Uint2(long2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Long3Uint3(long3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Long4Uint4(long4 inV) {
+    return convert_uint4(inV);
+}
+
+uint2 __attribute__((kernel)) testConvertUint2Ulong2Uint2(ulong2 inV) {
+    return convert_uint2(inV);
+}
+
+uint3 __attribute__((kernel)) testConvertUint3Ulong3Uint3(ulong3 inV) {
+    return convert_uint3(inV);
+}
+
+uint4 __attribute__((kernel)) testConvertUint4Ulong4Uint4(ulong4 inV) {
+    return convert_uint4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Float2Double2(float2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Float3Double3(float3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Float4Double4(float4 inV) {
+    return convert_double4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Char2Double2(char2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Char3Double3(char3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Char4Double4(char4 inV) {
+    return convert_double4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Uchar2Double2(uchar2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Uchar3Double3(uchar3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Uchar4Double4(uchar4 inV) {
+    return convert_double4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Short2Double2(short2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Short3Double3(short3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Short4Double4(short4 inV) {
+    return convert_double4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Ushort2Double2(ushort2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Ushort3Double3(ushort3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Ushort4Double4(ushort4 inV) {
+    return convert_double4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Int2Double2(int2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Int3Double3(int3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Int4Double4(int4 inV) {
+    return convert_double4(inV);
+}
+
+double2 __attribute__((kernel)) testConvertDouble2Uint2Double2(uint2 inV) {
+    return convert_double2(inV);
+}
+
+double3 __attribute__((kernel)) testConvertDouble3Uint3Double3(uint3 inV) {
+    return convert_double3(inV);
+}
+
+double4 __attribute__((kernel)) testConvertDouble4Uint4Double4(uint4 inV) {
+    return convert_double4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Float2Long2(float2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Float3Long3(float3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Float4Long4(float4 inV) {
+    return convert_long4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Char2Long2(char2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Char3Long3(char3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Char4Long4(char4 inV) {
+    return convert_long4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Uchar2Long2(uchar2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Uchar3Long3(uchar3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Uchar4Long4(uchar4 inV) {
+    return convert_long4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Short2Long2(short2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Short3Long3(short3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Short4Long4(short4 inV) {
+    return convert_long4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Ushort2Long2(ushort2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Ushort3Long3(ushort3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Ushort4Long4(ushort4 inV) {
+    return convert_long4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Int2Long2(int2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Int3Long3(int3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Int4Long4(int4 inV) {
+    return convert_long4(inV);
+}
+
+long2 __attribute__((kernel)) testConvertLong2Uint2Long2(uint2 inV) {
+    return convert_long2(inV);
+}
+
+long3 __attribute__((kernel)) testConvertLong3Uint3Long3(uint3 inV) {
+    return convert_long3(inV);
+}
+
+long4 __attribute__((kernel)) testConvertLong4Uint4Long4(uint4 inV) {
+    return convert_long4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Float2Ulong2(float2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Float3Ulong3(float3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Float4Ulong4(float4 inV) {
+    return convert_ulong4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Char2Ulong2(char2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Char3Ulong3(char3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Char4Ulong4(char4 inV) {
+    return convert_ulong4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Uchar2Ulong2(uchar2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Uchar3Ulong3(uchar3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Uchar4Ulong4(uchar4 inV) {
+    return convert_ulong4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Short2Ulong2(short2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Short3Ulong3(short3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Short4Ulong4(short4 inV) {
+    return convert_ulong4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Ushort2Ulong2(ushort2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Ushort3Ulong3(ushort3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Ushort4Ulong4(ushort4 inV) {
+    return convert_ulong4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Int2Ulong2(int2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Int3Ulong3(int3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Int4Ulong4(int4 inV) {
+    return convert_ulong4(inV);
+}
+
+ulong2 __attribute__((kernel)) testConvertUlong2Uint2Ulong2(uint2 inV) {
+    return convert_ulong2(inV);
+}
+
+ulong3 __attribute__((kernel)) testConvertUlong3Uint3Ulong3(uint3 inV) {
+    return convert_ulong3(inV);
+}
+
+ulong4 __attribute__((kernel)) testConvertUlong4Uint4Ulong4(uint4 inV) {
+    return convert_ulong4(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
new file mode 100644
index 0000000..57ae29c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestConvertRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestConvert.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.java
new file mode 100644
index 0000000..24b71ec
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestCopysign extends RSBaseCompute {
+
+    private ScriptC_TestCopysign script;
+    private ScriptC_TestCopysignRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCopysign(mRS);
+        scriptRelaxed = new ScriptC_TestCopysignRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inMagnitudeValue;
+        public float inSignValue;
+        public Target.Floaty out;
+    }
+
+    private void checkCopysignFloatFloatFloat() {
+        Allocation inMagnitudeValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xcf086614l, false);
+        Allocation inSignValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9d8d3ef5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInSignValue(inSignValue);
+            script.forEach_testCopysignFloatFloatFloat(inMagnitudeValue, out);
+            verifyResultsCopysignFloatFloatFloat(inMagnitudeValue, inSignValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInSignValue(inSignValue);
+            scriptRelaxed.forEach_testCopysignFloatFloatFloat(inMagnitudeValue, out);
+            verifyResultsCopysignFloatFloatFloat(inMagnitudeValue, inSignValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignFloatFloatFloat(Allocation inMagnitudeValue, Allocation inSignValue, Allocation out, boolean relaxed) {
+        float[] arrayInMagnitudeValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMagnitudeValue, (float) 42);
+        inMagnitudeValue.copyTo(arrayInMagnitudeValue);
+        float[] arrayInSignValue = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInSignValue, (float) 42);
+        inSignValue.copyTo(arrayInSignValue);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inMagnitudeValue = arrayInMagnitudeValue[i];
+                args.inSignValue = arrayInSignValue[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCopysign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkCopysignFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCopysignFloat2Float2Float2() {
+        Allocation inMagnitudeValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x22e9f786l, false);
+        Allocation inSignValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x20cec72bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInSignValue(inSignValue);
+            script.forEach_testCopysignFloat2Float2Float2(inMagnitudeValue, out);
+            verifyResultsCopysignFloat2Float2Float2(inMagnitudeValue, inSignValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInSignValue(inSignValue);
+            scriptRelaxed.forEach_testCopysignFloat2Float2Float2(inMagnitudeValue, out);
+            verifyResultsCopysignFloat2Float2Float2(inMagnitudeValue, inSignValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignFloat2Float2Float2(Allocation inMagnitudeValue, Allocation inSignValue, Allocation out, boolean relaxed) {
+        float[] arrayInMagnitudeValue = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInMagnitudeValue, (float) 42);
+        inMagnitudeValue.copyTo(arrayInMagnitudeValue);
+        float[] arrayInSignValue = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInSignValue, (float) 42);
+        inSignValue.copyTo(arrayInSignValue);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeCopysign(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 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]);
+                        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 checkCopysignFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCopysignFloat3Float3Float3() {
+        Allocation inMagnitudeValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1b468741l, false);
+        Allocation inSignValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc39ab32cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInSignValue(inSignValue);
+            script.forEach_testCopysignFloat3Float3Float3(inMagnitudeValue, out);
+            verifyResultsCopysignFloat3Float3Float3(inMagnitudeValue, inSignValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInSignValue(inSignValue);
+            scriptRelaxed.forEach_testCopysignFloat3Float3Float3(inMagnitudeValue, out);
+            verifyResultsCopysignFloat3Float3Float3(inMagnitudeValue, inSignValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignFloat3Float3Float3(Allocation inMagnitudeValue, Allocation inSignValue, Allocation out, boolean relaxed) {
+        float[] arrayInMagnitudeValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMagnitudeValue, (float) 42);
+        inMagnitudeValue.copyTo(arrayInMagnitudeValue);
+        float[] arrayInSignValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInSignValue, (float) 42);
+        inSignValue.copyTo(arrayInSignValue);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeCopysign(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 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]);
+                        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 checkCopysignFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCopysignFloat4Float4Float4() {
+        Allocation inMagnitudeValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x13a316fcl, false);
+        Allocation inSignValue = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x66669f2dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInSignValue(inSignValue);
+            script.forEach_testCopysignFloat4Float4Float4(inMagnitudeValue, out);
+            verifyResultsCopysignFloat4Float4Float4(inMagnitudeValue, inSignValue, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInSignValue(inSignValue);
+            scriptRelaxed.forEach_testCopysignFloat4Float4Float4(inMagnitudeValue, out);
+            verifyResultsCopysignFloat4Float4Float4(inMagnitudeValue, inSignValue, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCopysignFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCopysignFloat4Float4Float4(Allocation inMagnitudeValue, Allocation inSignValue, Allocation out, boolean relaxed) {
+        float[] arrayInMagnitudeValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMagnitudeValue, (float) 42);
+        inMagnitudeValue.copyTo(arrayInMagnitudeValue);
+        float[] arrayInSignValue = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInSignValue, (float) 42);
+        inSignValue.copyTo(arrayInSignValue);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeCopysign(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 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]);
+                        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 checkCopysignFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testCopysign() {
+        checkCopysignFloatFloatFloat();
+        checkCopysignFloat2Float2Float2();
+        checkCopysignFloat3Float3Float3();
+        checkCopysignFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.rs
new file mode 100644
index 0000000..3aac45b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysign.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInSignValue;
+
+float __attribute__((kernel)) testCopysignFloatFloatFloat(float inMagnitudeValue, unsigned int x) {
+    float inSignValue = rsGetElementAt_float(gAllocInSignValue, x);
+    return copysign(inMagnitudeValue, inSignValue);
+}
+
+float2 __attribute__((kernel)) testCopysignFloat2Float2Float2(float2 inMagnitudeValue, unsigned int x) {
+    float2 inSignValue = rsGetElementAt_float2(gAllocInSignValue, x);
+    return copysign(inMagnitudeValue, inSignValue);
+}
+
+float3 __attribute__((kernel)) testCopysignFloat3Float3Float3(float3 inMagnitudeValue, unsigned int x) {
+    float3 inSignValue = rsGetElementAt_float3(gAllocInSignValue, x);
+    return copysign(inMagnitudeValue, inSignValue);
+}
+
+float4 __attribute__((kernel)) testCopysignFloat4Float4Float4(float4 inMagnitudeValue, unsigned int x) {
+    float4 inSignValue = rsGetElementAt_float4(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
new file mode 100644
index 0000000..c881b0b4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCopysignRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestCopysign.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.java
new file mode 100644
index 0000000..9c321da
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestCos extends RSBaseCompute {
+
+    private ScriptC_TestCos script;
+    private ScriptC_TestCosRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCos(mRS);
+        scriptRelaxed = new ScriptC_TestCosRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkCosFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbb80fef6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCosFloatFloat(inV, out);
+            verifyResultsCosFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCosFloatFloat(inV, out);
+            verifyResultsCosFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkCosFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCosFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb2bbfaal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCosFloat2Float2(inV, out);
+            verifyResultsCosFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCosFloat2Float2(inV, out);
+            verifyResultsCosFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCos(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 checkCosFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCosFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x146e088l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCosFloat3Float3(inV, out);
+            verifyResultsCosFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCosFloat3Float3(inV, out);
+            verifyResultsCosFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCos(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 checkCosFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCosFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf7620166l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCosFloat4Float4(inV, out);
+            verifyResultsCosFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCosFloat4Float4(inV, out);
+            verifyResultsCosFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCosFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCosFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCos(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 checkCosFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testCos() {
+        checkCosFloatFloat();
+        checkCosFloat2Float2();
+        checkCosFloat3Float3();
+        checkCosFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.rs
new file mode 100644
index 0000000..c2962ba
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCos.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testCosFloatFloat(float inV) {
+    return cos(inV);
+}
+
+float2 __attribute__((kernel)) testCosFloat2Float2(float2 inV) {
+    return cos(inV);
+}
+
+float3 __attribute__((kernel)) testCosFloat3Float3(float3 inV) {
+    return cos(inV);
+}
+
+float4 __attribute__((kernel)) testCosFloat4Float4(float4 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
new file mode 100644
index 0000000..ff383e5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestCos.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.java
new file mode 100644
index 0000000..f089c5f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestCosh extends RSBaseCompute {
+
+    private ScriptC_TestCosh script;
+    private ScriptC_TestCoshRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCosh(mRS);
+        scriptRelaxed = new ScriptC_TestCoshRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkCoshFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x108cfb40l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCoshFloatFloat(inV, out);
+            verifyResultsCoshFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshFloatFloat(inV, out);
+            verifyResultsCoshFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkCoshFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCoshFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4ebcf224l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCoshFloat2Float2(inV, out);
+            verifyResultsCoshFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshFloat2Float2(inV, out);
+            verifyResultsCoshFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCosh(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 checkCoshFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCoshFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x44d81302l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCoshFloat3Float3(inV, out);
+            verifyResultsCoshFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshFloat3Float3(inV, out);
+            verifyResultsCoshFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCosh(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 checkCoshFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCoshFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3af333e0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCoshFloat4Float4(inV, out);
+            verifyResultsCoshFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCoshFloat4Float4(inV, out);
+            verifyResultsCoshFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCoshFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCoshFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCosh(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 checkCoshFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testCosh() {
+        checkCoshFloatFloat();
+        checkCoshFloat2Float2();
+        checkCoshFloat3Float3();
+        checkCoshFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.rs
new file mode 100644
index 0000000..17c6714
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCosh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testCoshFloatFloat(float inV) {
+    return cosh(inV);
+}
+
+float2 __attribute__((kernel)) testCoshFloat2Float2(float2 inV) {
+    return cosh(inV);
+}
+
+float3 __attribute__((kernel)) testCoshFloat3Float3(float3 inV) {
+    return cosh(inV);
+}
+
+float4 __attribute__((kernel)) testCoshFloat4Float4(float4 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
new file mode 100644
index 0000000..4f1c0ee
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCoshRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestCosh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.java
new file mode 100644
index 0000000..11325c5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestCospi extends RSBaseCompute {
+
+    private ScriptC_TestCospi script;
+    private ScriptC_TestCospiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCospi(mRS);
+        scriptRelaxed = new ScriptC_TestCospiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkCospiFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xcc7595d1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testCospiFloatFloat(inV, out);
+            verifyResultsCospiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiFloatFloat(inV, out);
+            verifyResultsCospiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkCospiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCospiFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x81c1536dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testCospiFloat2Float2(inV, out);
+            verifyResultsCospiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiFloat2Float2(inV, out);
+            verifyResultsCospiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCospi(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 checkCospiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCospiFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x77dc744bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testCospiFloat3Float3(inV, out);
+            verifyResultsCospiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiFloat3Float3(inV, out);
+            verifyResultsCospiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCospi(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 checkCospiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCospiFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6df79529l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testCospiFloat4Float4(inV, out);
+            verifyResultsCospiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testCospiFloat4Float4(inV, out);
+            verifyResultsCospiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCospiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCospiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeCospi(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 checkCospiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testCospi() {
+        checkCospiFloatFloat();
+        checkCospiFloat2Float2();
+        checkCospiFloat3Float3();
+        checkCospiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.rs
new file mode 100644
index 0000000..c6e5922
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testCospiFloatFloat(float inV) {
+    return cospi(inV);
+}
+
+float2 __attribute__((kernel)) testCospiFloat2Float2(float2 inV) {
+    return cospi(inV);
+}
+
+float3 __attribute__((kernel)) testCospiFloat3Float3(float3 inV) {
+    return cospi(inV);
+}
+
+float4 __attribute__((kernel)) testCospiFloat4Float4(float4 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
new file mode 100644
index 0000000..582b8c0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCospiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestCospi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.java
new file mode 100644
index 0000000..61d0021
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestCross extends RSBaseCompute {
+
+    private ScriptC_TestCross script;
+    private ScriptC_TestCrossRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestCross(mRS);
+        scriptRelaxed = new ScriptC_TestCrossRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatNFloatNFloatN {
+        public float[] inLeftVector;
+        public float[] inRightVector;
+        public Target.Floaty[] out;
+    }
+
+    private void checkCrossFloat3Float3Float3() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x382f1ad4l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xde024b21l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testCrossFloat3Float3Float3(inLeftVector, out);
+            verifyResultsCrossFloat3Float3Float3(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testCrossFloat3Float3Float3(inLeftVector, out);
+            verifyResultsCrossFloat3Float3Float3(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCrossFloat3Float3Float3(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        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++) {
+            ArgumentsFloatNFloatNFloatN args = new ArgumentsFloatNFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[3];
+            args.inRightVector = new float[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];
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(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(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]);
+                        if (!args.out[j].couldBe(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 checkCrossFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkCrossFloat4Float4Float4() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x906fbeffl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb0ddde5al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testCrossFloat4Float4Float4(inLeftVector, out);
+            verifyResultsCrossFloat4Float4Float4(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testCrossFloat4Float4Float4(inLeftVector, out);
+            verifyResultsCrossFloat4Float4Float4(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testCrossFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsCrossFloat4Float4Float4(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        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++) {
+            ArgumentsFloatNFloatNFloatN args = new ArgumentsFloatNFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[4];
+            args.inRightVector = new float[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];
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(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(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]);
+                        if (!args.out[j].couldBe(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 checkCrossFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testCross() {
+        checkCrossFloat3Float3Float3();
+        checkCrossFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.rs
new file mode 100644
index 0000000..9be99a0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCross.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInRightVector;
+
+float3 __attribute__((kernel)) testCrossFloat3Float3Float3(float3 inLeftVector, unsigned int x) {
+    float3 inRightVector = rsGetElementAt_float3(gAllocInRightVector, x);
+    return cross(inLeftVector, inRightVector);
+}
+
+float4 __attribute__((kernel)) testCrossFloat4Float4Float4(float4 inLeftVector, unsigned int x) {
+    float4 inRightVector = rsGetElementAt_float4(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
new file mode 100644
index 0000000..cd95138
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestCrossRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestCross.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.java
new file mode 100644
index 0000000..03eee53
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestDegrees extends RSBaseCompute {
+
+    private ScriptC_TestDegrees script;
+    private ScriptC_TestDegreesRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestDegrees(mRS);
+        scriptRelaxed = new ScriptC_TestDegreesRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkDegreesFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc5dde30al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testDegreesFloatFloat(inV, out);
+            verifyResultsDegreesFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesFloatFloat(inV, out);
+            verifyResultsDegreesFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeDegrees(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkDegreesFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDegreesFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe417141el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testDegreesFloat2Float2(inV, out);
+            verifyResultsDegreesFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesFloat2Float2(inV, out);
+            verifyResultsDegreesFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeDegrees(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 checkDegreesFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDegreesFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xda3234fcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testDegreesFloat3Float3(inV, out);
+            verifyResultsDegreesFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesFloat3Float3(inV, out);
+            verifyResultsDegreesFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeDegrees(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 checkDegreesFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDegreesFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd04d55dal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testDegreesFloat4Float4(inV, out);
+            verifyResultsDegreesFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testDegreesFloat4Float4(inV, out);
+            verifyResultsDegreesFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDegreesFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDegreesFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeDegrees(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 checkDegreesFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testDegrees() {
+        checkDegreesFloatFloat();
+        checkDegreesFloat2Float2();
+        checkDegreesFloat3Float3();
+        checkDegreesFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.rs
new file mode 100644
index 0000000..24c9b4b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegrees.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testDegreesFloatFloat(float inV) {
+    return degrees(inV);
+}
+
+float2 __attribute__((kernel)) testDegreesFloat2Float2(float2 inV) {
+    return degrees(inV);
+}
+
+float3 __attribute__((kernel)) testDegreesFloat3Float3(float3 inV) {
+    return degrees(inV);
+}
+
+float4 __attribute__((kernel)) testDegreesFloat4Float4(float4 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
new file mode 100644
index 0000000..8977aa0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDegreesRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestDegrees.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.java
new file mode 100644
index 0000000..6051525
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestDistance extends RSBaseCompute {
+
+    private ScriptC_TestDistance script;
+    private ScriptC_TestDistanceRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestDistance(mRS);
+        scriptRelaxed = new ScriptC_TestDistanceRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inLeftVector;
+        public float inRightVector;
+        public Target.Floaty out;
+    }
+
+    private void checkDistanceFloatFloatFloat() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x82ced52al, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x66d69793l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDistanceFloatFloatFloat(inLeftVector, out);
+            verifyResultsDistanceFloatFloatFloat(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDistanceFloatFloatFloat(inLeftVector, out);
+            verifyResultsDistanceFloatFloatFloat(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceFloatFloatFloat(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLeftVector = arrayInLeftVector[i];
+            args.inRightVector = arrayInRightVector[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkDistanceFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloatNFloat {
+        public float[] inLeftVector;
+        public float[] inRightVector;
+        public Target.Floaty out;
+    }
+
+    private void checkDistanceFloat2Float2Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x554dab2el, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc2248a3fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDistanceFloat2Float2Float(inLeftVector, out);
+            verifyResultsDistanceFloat2Float2Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat2Float2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDistanceFloat2Float2Float(inLeftVector, out);
+            verifyResultsDistanceFloat2Float2Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat2Float2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceFloat2Float2Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[2];
+            args.inRightVector = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 2 + j];
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 2 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkDistanceFloat2Float2Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDistanceFloat3Float3Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x76ec5f7cl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x67ccd359l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDistanceFloat3Float3Float(inLeftVector, out);
+            verifyResultsDistanceFloat3Float3Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat3Float3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDistanceFloat3Float3Float(inLeftVector, out);
+            verifyResultsDistanceFloat3Float3Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat3Float3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceFloat3Float3Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[3];
+            args.inRightVector = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkDistanceFloat3Float3Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDistanceFloat4Float4Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x988b13cal, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd751c73l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDistanceFloat4Float4Float(inLeftVector, out);
+            verifyResultsDistanceFloat4Float4Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat4Float4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDistanceFloat4Float4Float(inLeftVector, out);
+            verifyResultsDistanceFloat4Float4Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDistanceFloat4Float4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDistanceFloat4Float4Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[4];
+            args.inRightVector = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkDistanceFloat4Float4Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testDistance() {
+        checkDistanceFloatFloatFloat();
+        checkDistanceFloat2Float2Float();
+        checkDistanceFloat3Float3Float();
+        checkDistanceFloat4Float4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.rs
new file mode 100644
index 0000000..a682646
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistance.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInRightVector;
+
+float __attribute__((kernel)) testDistanceFloatFloatFloat(float inLeftVector, unsigned int x) {
+    float inRightVector = rsGetElementAt_float(gAllocInRightVector, x);
+    return distance(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testDistanceFloat2Float2Float(float2 inLeftVector, unsigned int x) {
+    float2 inRightVector = rsGetElementAt_float2(gAllocInRightVector, x);
+    return distance(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testDistanceFloat3Float3Float(float3 inLeftVector, unsigned int x) {
+    float3 inRightVector = rsGetElementAt_float3(gAllocInRightVector, x);
+    return distance(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testDistanceFloat4Float4Float(float4 inLeftVector, unsigned int x) {
+    float4 inRightVector = rsGetElementAt_float4(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
new file mode 100644
index 0000000..00b0dfd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDistanceRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestDistance.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.java
new file mode 100644
index 0000000..3898003
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestDot extends RSBaseCompute {
+
+    private ScriptC_TestDot script;
+    private ScriptC_TestDotRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestDot(mRS);
+        scriptRelaxed = new ScriptC_TestDotRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inLeftVector;
+        public float inRightVector;
+        public Target.Floaty out;
+    }
+
+    private void checkDotFloatFloatFloat() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf7ff2d3el, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x15f562efl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDotFloatFloatFloat(inLeftVector, out);
+            verifyResultsDotFloatFloatFloat(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDotFloatFloatFloat(inLeftVector, out);
+            verifyResultsDotFloatFloatFloat(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotFloatFloatFloat(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLeftVector = arrayInLeftVector[i];
+            args.inRightVector = arrayInRightVector[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeDot(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkDotFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloatNFloat {
+        public float[] inLeftVector;
+        public float[] inRightVector;
+        public Target.Floaty out;
+    }
+
+    private void checkDotFloat2Float2Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbf79d3a2l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x978f55bbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDotFloat2Float2Float(inLeftVector, out);
+            verifyResultsDotFloat2Float2Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat2Float2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDotFloat2Float2Float(inLeftVector, out);
+            verifyResultsDotFloat2Float2Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat2Float2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotFloat2Float2Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[2];
+            args.inRightVector = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 2 + j];
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 2 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeDot(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkDotFloat2Float2Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDotFloat3Float3Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe11887f0l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3d379ed5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDotFloat3Float3Float(inLeftVector, out);
+            verifyResultsDotFloat3Float3Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat3Float3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDotFloat3Float3Float(inLeftVector, out);
+            verifyResultsDotFloat3Float3Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat3Float3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotFloat3Float3Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[3];
+            args.inRightVector = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeDot(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkDotFloat3Float3Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkDotFloat4Float4Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2b73c3el, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe2dfe7efl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testDotFloat4Float4Float(inLeftVector, out);
+            verifyResultsDotFloat4Float4Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat4Float4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testDotFloat4Float4Float(inLeftVector, out);
+            verifyResultsDotFloat4Float4Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testDotFloat4Float4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsDotFloat4Float4Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[4];
+            args.inRightVector = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeDot(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkDotFloat4Float4Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testDot() {
+        checkDotFloatFloatFloat();
+        checkDotFloat2Float2Float();
+        checkDotFloat3Float3Float();
+        checkDotFloat4Float4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.rs
new file mode 100644
index 0000000..d7559e3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDot.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInRightVector;
+
+float __attribute__((kernel)) testDotFloatFloatFloat(float inLeftVector, unsigned int x) {
+    float inRightVector = rsGetElementAt_float(gAllocInRightVector, x);
+    return dot(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testDotFloat2Float2Float(float2 inLeftVector, unsigned int x) {
+    float2 inRightVector = rsGetElementAt_float2(gAllocInRightVector, x);
+    return dot(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testDotFloat3Float3Float(float3 inLeftVector, unsigned int x) {
+    float3 inRightVector = rsGetElementAt_float3(gAllocInRightVector, x);
+    return dot(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testDotFloat4Float4Float(float4 inLeftVector, unsigned int x) {
+    float4 inRightVector = rsGetElementAt_float4(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
new file mode 100644
index 0000000..dd94472
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestDotRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestDot.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.java
new file mode 100644
index 0000000..bc3a073
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestErf extends RSBaseCompute {
+
+    private ScriptC_TestErf script;
+    private ScriptC_TestErfRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestErf(mRS);
+        scriptRelaxed = new ScriptC_TestErfRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkErfFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa3951fb8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testErfFloatFloat(inV, out);
+            verifyResultsErfFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testErfFloatFloat(inV, out);
+            verifyResultsErfFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeErf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkErfFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x448c58dcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testErfFloat2Float2(inV, out);
+            verifyResultsErfFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testErfFloat2Float2(inV, out);
+            verifyResultsErfFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeErf(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 checkErfFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3aa779bal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testErfFloat3Float3(inV, out);
+            verifyResultsErfFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testErfFloat3Float3(inV, out);
+            verifyResultsErfFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeErf(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 checkErfFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x30c29a98l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testErfFloat4Float4(inV, out);
+            verifyResultsErfFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testErfFloat4Float4(inV, out);
+            verifyResultsErfFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeErf(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 checkErfFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testErf() {
+        checkErfFloatFloat();
+        checkErfFloat2Float2();
+        checkErfFloat3Float3();
+        checkErfFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.rs
new file mode 100644
index 0000000..246e8fb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErf.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testErfFloatFloat(float inV) {
+    return erf(inV);
+}
+
+float2 __attribute__((kernel)) testErfFloat2Float2(float2 inV) {
+    return erf(inV);
+}
+
+float3 __attribute__((kernel)) testErfFloat3Float3(float3 inV) {
+    return erf(inV);
+}
+
+float4 __attribute__((kernel)) testErfFloat4Float4(float4 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
new file mode 100644
index 0000000..5963f80
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestErf.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.java
new file mode 100644
index 0000000..856bcf4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestErfc extends RSBaseCompute {
+
+    private ScriptC_TestErfc script;
+    private ScriptC_TestErfcRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestErfc(mRS);
+        scriptRelaxed = new ScriptC_TestErfcRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkErfcFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdfa008fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testErfcFloatFloat(inV, out);
+            verifyResultsErfcFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcFloatFloat(inV, out);
+            verifyResultsErfcFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeErfc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkErfcFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfcFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb72849bbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testErfcFloat2Float2(inV, out);
+            verifyResultsErfcFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcFloat2Float2(inV, out);
+            verifyResultsErfcFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeErfc(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 checkErfcFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfcFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xad436a99l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testErfcFloat3Float3(inV, out);
+            verifyResultsErfcFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcFloat3Float3(inV, out);
+            verifyResultsErfcFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeErfc(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 checkErfcFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkErfcFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa35e8b77l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testErfcFloat4Float4(inV, out);
+            verifyResultsErfcFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testErfcFloat4Float4(inV, out);
+            verifyResultsErfcFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testErfcFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsErfcFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeErfc(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 checkErfcFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testErfc() {
+        checkErfcFloatFloat();
+        checkErfcFloat2Float2();
+        checkErfcFloat3Float3();
+        checkErfcFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.rs
new file mode 100644
index 0000000..1fc8310
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfc.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testErfcFloatFloat(float inV) {
+    return erfc(inV);
+}
+
+float2 __attribute__((kernel)) testErfcFloat2Float2(float2 inV) {
+    return erfc(inV);
+}
+
+float3 __attribute__((kernel)) testErfcFloat3Float3(float3 inV) {
+    return erfc(inV);
+}
+
+float4 __attribute__((kernel)) testErfcFloat4Float4(float4 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
new file mode 100644
index 0000000..99449ad
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestErfcRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestErfc.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.java
new file mode 100644
index 0000000..8e73056
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestExp extends RSBaseCompute {
+
+    private ScriptC_TestExp script;
+    private ScriptC_TestExpRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestExp(mRS);
+        scriptRelaxed = new ScriptC_TestExpRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkExpFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x35f888fcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testExpFloatFloat(inV, out);
+            verifyResultsExpFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExpFloatFloat(inV, out);
+            verifyResultsExpFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkExpFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x948fa500l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testExpFloat2Float2(inV, out);
+            verifyResultsExpFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExpFloat2Float2(inV, out);
+            verifyResultsExpFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp(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 checkExpFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8aaac5del, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testExpFloat3Float3(inV, out);
+            verifyResultsExpFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExpFloat3Float3(inV, out);
+            verifyResultsExpFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp(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 checkExpFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x80c5e6bcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testExpFloat4Float4(inV, out);
+            verifyResultsExpFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExpFloat4Float4(inV, out);
+            verifyResultsExpFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp(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 checkExpFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testExp() {
+        checkExpFloatFloat();
+        checkExpFloat2Float2();
+        checkExpFloat3Float3();
+        checkExpFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.rs
new file mode 100644
index 0000000..9e25653
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testExpFloatFloat(float inV) {
+    return exp(inV);
+}
+
+float2 __attribute__((kernel)) testExpFloat2Float2(float2 inV) {
+    return exp(inV);
+}
+
+float3 __attribute__((kernel)) testExpFloat3Float3(float3 inV) {
+    return exp(inV);
+}
+
+float4 __attribute__((kernel)) testExpFloat4Float4(float4 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
new file mode 100644
index 0000000..fd01beb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestExp10 extends RSBaseCompute {
+
+    private ScriptC_TestExp10 script;
+    private ScriptC_TestExp10Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestExp10(mRS);
+        scriptRelaxed = new ScriptC_TestExp10Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkExp10FloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc123e2edl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testExp10FloatFloat(inV, out);
+            verifyResultsExp10FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10FloatFloat(inV, out);
+            verifyResultsExp10FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkExp10FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp10Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc0ac42a9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testExp10Float2Float2(inV, out);
+            verifyResultsExp10Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10Float2Float2(inV, out);
+            verifyResultsExp10Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp10(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 checkExp10Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp10Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xb6c76387l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testExp10Float3Float3(inV, out);
+            verifyResultsExp10Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10Float3Float3(inV, out);
+            verifyResultsExp10Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp10(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 checkExp10Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp10Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xace28465l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testExp10Float4Float4(inV, out);
+            verifyResultsExp10Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExp10Float4Float4(inV, out);
+            verifyResultsExp10Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp10Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp10Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp10(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 checkExp10Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testExp10() {
+        checkExp10FloatFloat();
+        checkExp10Float2Float2();
+        checkExp10Float3Float3();
+        checkExp10Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.rs
new file mode 100644
index 0000000..cb52b10
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testExp10FloatFloat(float inV) {
+    return exp10(inV);
+}
+
+float2 __attribute__((kernel)) testExp10Float2Float2(float2 inV) {
+    return exp10(inV);
+}
+
+float3 __attribute__((kernel)) testExp10Float3Float3(float3 inV) {
+    return exp10(inV);
+}
+
+float4 __attribute__((kernel)) testExp10Float4Float4(float4 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
new file mode 100644
index 0000000..e3cdc42
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp10Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestExp10.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.java
new file mode 100644
index 0000000..8d1c698
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestExp2 extends RSBaseCompute {
+
+    private ScriptC_TestExp2 script;
+    private ScriptC_TestExp2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestExp2(mRS);
+        scriptRelaxed = new ScriptC_TestExp2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkExp2FloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb8b72a10l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testExp2FloatFloat(inV, out);
+            verifyResultsExp2FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2FloatFloat(inV, out);
+            verifyResultsExp2FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkExp2FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp2Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe7690e74l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testExp2Float2Float2(inV, out);
+            verifyResultsExp2Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2Float2Float2(inV, out);
+            verifyResultsExp2Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp2(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 checkExp2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp2Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdd842f52l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testExp2Float3Float3(inV, out);
+            verifyResultsExp2Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2Float3Float3(inV, out);
+            verifyResultsExp2Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp2(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 checkExp2Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExp2Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd39f5030l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testExp2Float4Float4(inV, out);
+            verifyResultsExp2Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExp2Float4Float4(inV, out);
+            verifyResultsExp2Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExp2Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExp2Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExp2(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 checkExp2Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testExp2() {
+        checkExp2FloatFloat();
+        checkExp2Float2Float2();
+        checkExp2Float3Float3();
+        checkExp2Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.rs
new file mode 100644
index 0000000..ef44e92
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testExp2FloatFloat(float inV) {
+    return exp2(inV);
+}
+
+float2 __attribute__((kernel)) testExp2Float2Float2(float2 inV) {
+    return exp2(inV);
+}
+
+float3 __attribute__((kernel)) testExp2Float3Float3(float3 inV) {
+    return exp2(inV);
+}
+
+float4 __attribute__((kernel)) testExp2Float4Float4(float4 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
new file mode 100644
index 0000000..2762dec
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExp2Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestExp2.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpRelaxed.rs
new file mode 100644
index 0000000..b0aeb3e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestExp.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.java
new file mode 100644
index 0000000..6a1609f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestExpm1 extends RSBaseCompute {
+
+    private ScriptC_TestExpm1 script;
+    private ScriptC_TestExpm1Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestExpm1(mRS);
+        scriptRelaxed = new ScriptC_TestExpm1Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkExpm1FloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa183a9e4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testExpm1FloatFloat(inV, out);
+            verifyResultsExpm1FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1FloatFloat(inV, out);
+            verifyResultsExpm1FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExpm1(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkExpm1FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpm1Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x547050a8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testExpm1Float2Float2(inV, out);
+            verifyResultsExpm1Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1Float2Float2(inV, out);
+            verifyResultsExpm1Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExpm1(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 checkExpm1Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpm1Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4a8b7186l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testExpm1Float3Float3(inV, out);
+            verifyResultsExpm1Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1Float3Float3(inV, out);
+            verifyResultsExpm1Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExpm1(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 checkExpm1Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkExpm1Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x40a69264l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testExpm1Float4Float4(inV, out);
+            verifyResultsExpm1Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testExpm1Float4Float4(inV, out);
+            verifyResultsExpm1Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testExpm1Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsExpm1Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeExpm1(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 checkExpm1Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testExpm1() {
+        checkExpm1FloatFloat();
+        checkExpm1Float2Float2();
+        checkExpm1Float3Float3();
+        checkExpm1Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.rs
new file mode 100644
index 0000000..6cc0986
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testExpm1FloatFloat(float inV) {
+    return expm1(inV);
+}
+
+float2 __attribute__((kernel)) testExpm1Float2Float2(float2 inV) {
+    return expm1(inV);
+}
+
+float3 __attribute__((kernel)) testExpm1Float3Float3(float3 inV) {
+    return expm1(inV);
+}
+
+float4 __attribute__((kernel)) testExpm1Float4Float4(float4 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
new file mode 100644
index 0000000..2dfc6b3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestExpm1Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestExpm1.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.java
new file mode 100644
index 0000000..9303e7e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFabs extends RSBaseCompute {
+
+    private ScriptC_TestFabs script;
+    private ScriptC_TestFabsRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFabs(mRS);
+        scriptRelaxed = new ScriptC_TestFabsRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkFabsFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7f929ae9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFabsFloatFloat(inV, out);
+            verifyResultsFabsFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsFloatFloat(inV, out);
+            verifyResultsFabsFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFabs(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkFabsFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFabsFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x2e5b1dc5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testFabsFloat2Float2(inV, out);
+            verifyResultsFabsFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsFloat2Float2(inV, out);
+            verifyResultsFabsFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFabs(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 checkFabsFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFabsFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x24763ea3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testFabsFloat3Float3(inV, out);
+            verifyResultsFabsFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsFloat3Float3(inV, out);
+            verifyResultsFabsFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFabs(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 checkFabsFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFabsFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1a915f81l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testFabsFloat4Float4(inV, out);
+            verifyResultsFabsFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFabsFloat4Float4(inV, out);
+            verifyResultsFabsFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFabsFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFabsFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFabs(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 checkFabsFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFabs() {
+        checkFabsFloatFloat();
+        checkFabsFloat2Float2();
+        checkFabsFloat3Float3();
+        checkFabsFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.rs
new file mode 100644
index 0000000..87d8b1e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabs.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testFabsFloatFloat(float inV) {
+    return fabs(inV);
+}
+
+float2 __attribute__((kernel)) testFabsFloat2Float2(float2 inV) {
+    return fabs(inV);
+}
+
+float3 __attribute__((kernel)) testFabsFloat3Float3(float3 inV) {
+    return fabs(inV);
+}
+
+float4 __attribute__((kernel)) testFabsFloat4Float4(float4 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
new file mode 100644
index 0000000..a43e74d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFabsRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFabs.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.java
new file mode 100644
index 0000000..e10d5df
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFastDistance extends RSBaseCompute {
+
+    private ScriptC_TestFastDistance script;
+    private ScriptC_TestFastDistanceRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFastDistance(mRS);
+        scriptRelaxed = new ScriptC_TestFastDistanceRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inLeftVector;
+        public float inRightVector;
+        public Target.Floaty out;
+    }
+
+    private void checkFastDistanceFloatFloatFloat() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb9b28b1al, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9f1626e3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testFastDistanceFloatFloatFloat(inLeftVector, out);
+            verifyResultsFastDistanceFloatFloatFloat(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testFastDistanceFloatFloatFloat(inLeftVector, out);
+            verifyResultsFastDistanceFloatFloatFloat(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastDistanceFloatFloatFloat(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLeftVector = arrayInLeftVector[i];
+            args.inRightVector = arrayInRightVector[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkFastDistanceFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloatNFloat {
+        public float[] inLeftVector;
+        public float[] inRightVector;
+        public Target.Floaty out;
+    }
+
+    private void checkFastDistanceFloat2Float2Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc7fabd9el, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x536a30fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testFastDistanceFloat2Float2Float(inLeftVector, out);
+            verifyResultsFastDistanceFloat2Float2Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat2Float2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testFastDistanceFloat2Float2Float(inLeftVector, out);
+            verifyResultsFastDistanceFloat2Float2Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat2Float2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastDistanceFloat2Float2Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[2];
+            args.inRightVector = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 2 + j];
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 2 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkFastDistanceFloat2Float2Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFastDistanceFloat3Float3Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe99971ecl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xaadeec29l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testFastDistanceFloat3Float3Float(inLeftVector, out);
+            verifyResultsFastDistanceFloat3Float3Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat3Float3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testFastDistanceFloat3Float3Float(inLeftVector, out);
+            verifyResultsFastDistanceFloat3Float3Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat3Float3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastDistanceFloat3Float3Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[3];
+            args.inRightVector = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkFastDistanceFloat3Float3Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFastDistanceFloat4Float4Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb38263al, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x50873543l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testFastDistanceFloat4Float4Float(inLeftVector, out);
+            verifyResultsFastDistanceFloat4Float4Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat4Float4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testFastDistanceFloat4Float4Float(inLeftVector, out);
+            verifyResultsFastDistanceFloat4Float4Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastDistanceFloat4Float4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastDistanceFloat4Float4Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[4];
+            args.inRightVector = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkFastDistanceFloat4Float4Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFastDistance() {
+        checkFastDistanceFloatFloatFloat();
+        checkFastDistanceFloat2Float2Float();
+        checkFastDistanceFloat3Float3Float();
+        checkFastDistanceFloat4Float4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.rs
new file mode 100644
index 0000000..114523b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistance.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInRightVector;
+
+float __attribute__((kernel)) testFastDistanceFloatFloatFloat(float inLeftVector, unsigned int x) {
+    float inRightVector = rsGetElementAt_float(gAllocInRightVector, x);
+    return fast_distance(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testFastDistanceFloat2Float2Float(float2 inLeftVector, unsigned int x) {
+    float2 inRightVector = rsGetElementAt_float2(gAllocInRightVector, x);
+    return fast_distance(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testFastDistanceFloat3Float3Float(float3 inLeftVector, unsigned int x) {
+    float3 inRightVector = rsGetElementAt_float3(gAllocInRightVector, x);
+    return fast_distance(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testFastDistanceFloat4Float4Float(float4 inLeftVector, unsigned int x) {
+    float4 inRightVector = rsGetElementAt_float4(gAllocInRightVector, x);
+    return fast_distance(inLeftVector, inRightVector);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistanceRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistanceRelaxed.rs
new file mode 100644
index 0000000..cb52325
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastDistanceRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFastDistance.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.java
new file mode 100644
index 0000000..b47adc9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFastLength extends RSBaseCompute {
+
+    private ScriptC_TestFastLength script;
+    private ScriptC_TestFastLengthRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFastLength(mRS);
+        scriptRelaxed = new ScriptC_TestFastLengthRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkFastLengthFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa2660e8fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastLengthFloatFloat(inV, out);
+            verifyResultsFastLengthFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastLengthFloatFloat(inV, out);
+            verifyResultsFastLengthFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastLengthFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkFastLengthFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloat {
+        public float[] inV;
+        public Target.Floaty out;
+    }
+
+    private void checkFastLengthFloat2Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf85e6cadl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastLengthFloat2Float(inV, out);
+            verifyResultsFastLengthFloat2Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastLengthFloat2Float(inV, out);
+            verifyResultsFastLengthFloat2Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastLengthFloat2Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkFastLengthFloat2Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFastLengthFloat3Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5764fb0el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastLengthFloat3Float(inV, out);
+            verifyResultsFastLengthFloat3Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastLengthFloat3Float(inV, out);
+            verifyResultsFastLengthFloat3Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastLengthFloat3Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkFastLengthFloat3Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFastLengthFloat4Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb66b896fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastLengthFloat4Float(inV, out);
+            verifyResultsFastLengthFloat4Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastLengthFloat4Float(inV, out);
+            verifyResultsFastLengthFloat4Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastLengthFloat4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastLengthFloat4Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkFastLengthFloat4Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFastLength() {
+        checkFastLengthFloatFloat();
+        checkFastLengthFloat2Float();
+        checkFastLengthFloat3Float();
+        checkFastLengthFloat4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.rs
new file mode 100644
index 0000000..46619d7
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLength.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testFastLengthFloatFloat(float inV) {
+    return fast_length(inV);
+}
+
+float __attribute__((kernel)) testFastLengthFloat2Float(float2 inV) {
+    return fast_length(inV);
+}
+
+float __attribute__((kernel)) testFastLengthFloat3Float(float3 inV) {
+    return fast_length(inV);
+}
+
+float __attribute__((kernel)) testFastLengthFloat4Float(float4 inV) {
+    return fast_length(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLengthRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLengthRelaxed.rs
new file mode 100644
index 0000000..d85126a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastLengthRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFastLength.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.java
new file mode 100644
index 0000000..2c3ac1a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFastNormalize extends RSBaseCompute {
+
+    private ScriptC_TestFastNormalize script;
+    private ScriptC_TestFastNormalizeRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFastNormalize(mRS);
+        scriptRelaxed = new ScriptC_TestFastNormalizeRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkFastNormalizeFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9f8882ecl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFastNormalizeFloatFloat(inV, out);
+            verifyResultsFastNormalizeFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFastNormalizeFloatFloat(inV, out);
+            verifyResultsFastNormalizeFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastNormalizeFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkFastNormalizeFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloatN {
+        public float[] inV;
+        public Target.Floaty[] out;
+    }
+
+    private void checkFastNormalizeFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x573db70l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testFastNormalizeFloat2Float2(inV, out);
+            verifyResultsFastNormalizeFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFastNormalizeFloat2Float2(inV, out);
+            verifyResultsFastNormalizeFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastNormalizeFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[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];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastNormalize(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(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]);
+                        if (!args.out[j].couldBe(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 checkFastNormalizeFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFastNormalizeFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfb8efc4el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testFastNormalizeFloat3Float3(inV, out);
+            verifyResultsFastNormalizeFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFastNormalizeFloat3Float3(inV, out);
+            verifyResultsFastNormalizeFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastNormalizeFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[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];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastNormalize(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(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]);
+                        if (!args.out[j].couldBe(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 checkFastNormalizeFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFastNormalizeFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf1aa1d2cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testFastNormalizeFloat4Float4(inV, out);
+            verifyResultsFastNormalizeFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFastNormalizeFloat4Float4(inV, out);
+            verifyResultsFastNormalizeFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFastNormalizeFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFastNormalizeFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[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];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeFastNormalize(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(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]);
+                        if (!args.out[j].couldBe(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 checkFastNormalizeFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFastNormalize() {
+        checkFastNormalizeFloatFloat();
+        checkFastNormalizeFloat2Float2();
+        checkFastNormalizeFloat3Float3();
+        checkFastNormalizeFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.rs
new file mode 100644
index 0000000..e5f009c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalize.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testFastNormalizeFloatFloat(float inV) {
+    return fast_normalize(inV);
+}
+
+float2 __attribute__((kernel)) testFastNormalizeFloat2Float2(float2 inV) {
+    return fast_normalize(inV);
+}
+
+float3 __attribute__((kernel)) testFastNormalizeFloat3Float3(float3 inV) {
+    return fast_normalize(inV);
+}
+
+float4 __attribute__((kernel)) testFastNormalizeFloat4Float4(float4 inV) {
+    return fast_normalize(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalizeRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalizeRelaxed.rs
new file mode 100644
index 0000000..e8549e3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFastNormalizeRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFastNormalize.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.java
new file mode 100644
index 0000000..c817296
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFdim extends RSBaseCompute {
+
+    private ScriptC_TestFdim script;
+    private ScriptC_TestFdimRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFdim(mRS);
+        scriptRelaxed = new ScriptC_TestFdimRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public Target.Floaty out;
+    }
+
+    private void checkFdimFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc3a47366l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc3a47367l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimFloatFloatFloat(inA, out);
+            verifyResultsFdimFloatFloatFloat(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimFloatFloatFloat(inA, out);
+            verifyResultsFdimFloatFloatFloat(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimFloatFloatFloat(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        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 * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFdim(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkFdimFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFdimFloat2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6f167f4cl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6f167f4dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimFloat2Float2Float2(inA, out);
+            verifyResultsFdimFloat2Float2Float2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimFloat2Float2Float2(inA, out);
+            verifyResultsFdimFloat2Float2Float2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimFloat2Float2Float2(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 * 2];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFdim(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFdimFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFdimFloat3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x70f480edl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x70f480eel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimFloat3Float3Float3(inA, out);
+            verifyResultsFdimFloat3Float3Float3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimFloat3Float3Float3(inA, out);
+            verifyResultsFdimFloat3Float3Float3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimFloat3Float3Float3(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFdim(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFdimFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFdimFloat4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x72d2828el, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x72d2828fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFdimFloat4Float4Float4(inA, out);
+            verifyResultsFdimFloat4Float4Float4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFdimFloat4Float4Float4(inA, out);
+            verifyResultsFdimFloat4Float4Float4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFdimFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFdimFloat4Float4Float4(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFdim(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFdimFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFdim() {
+        checkFdimFloatFloatFloat();
+        checkFdimFloat2Float2Float2();
+        checkFdimFloat3Float3Float3();
+        checkFdimFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.rs
new file mode 100644
index 0000000..e93485c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdim.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInB;
+
+float __attribute__((kernel)) testFdimFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return fdim(inA, inB);
+}
+
+float2 __attribute__((kernel)) testFdimFloat2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    return fdim(inA, inB);
+}
+
+float3 __attribute__((kernel)) testFdimFloat3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    return fdim(inA, inB);
+}
+
+float4 __attribute__((kernel)) testFdimFloat4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(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
new file mode 100644
index 0000000..caa61eb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFdimRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFdim.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.java
new file mode 100644
index 0000000..0ebc227
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFloor extends RSBaseCompute {
+
+    private ScriptC_TestFloor script;
+    private ScriptC_TestFloorRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFloor(mRS);
+        scriptRelaxed = new ScriptC_TestFloorRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkFloorFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x95badeadl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFloorFloatFloat(inV, out);
+            verifyResultsFloorFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorFloatFloat(inV, out);
+            verifyResultsFloorFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFloor(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkFloorFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFloorFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x372c9069l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testFloorFloat2Float2(inV, out);
+            verifyResultsFloorFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorFloat2Float2(inV, out);
+            verifyResultsFloorFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFloor(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 checkFloorFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFloorFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2d47b147l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testFloorFloat3Float3(inV, out);
+            verifyResultsFloorFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorFloat3Float3(inV, out);
+            verifyResultsFloorFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFloor(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 checkFloorFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFloorFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2362d225l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testFloorFloat4Float4(inV, out);
+            verifyResultsFloorFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFloorFloat4Float4(inV, out);
+            verifyResultsFloorFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFloorFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFloorFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFloor(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 checkFloorFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFloor() {
+        checkFloorFloatFloat();
+        checkFloorFloat2Float2();
+        checkFloorFloat3Float3();
+        checkFloorFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.rs
new file mode 100644
index 0000000..94dc5a6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloor.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testFloorFloatFloat(float inV) {
+    return floor(inV);
+}
+
+float2 __attribute__((kernel)) testFloorFloat2Float2(float2 inV) {
+    return floor(inV);
+}
+
+float3 __attribute__((kernel)) testFloorFloat3Float3(float3 inV) {
+    return floor(inV);
+}
+
+float4 __attribute__((kernel)) testFloorFloat4Float4(float4 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
new file mode 100644
index 0000000..6b5b69d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFloorRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFloor.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.java
new file mode 100644
index 0000000..f5f30b3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.java
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFma extends RSBaseCompute {
+
+    private ScriptC_TestFma script;
+    private ScriptC_TestFmaRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFma(mRS);
+        scriptRelaxed = new ScriptC_TestFmaRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloatFloat {
+        public float inMultiplicand1;
+        public float inMultiplicand2;
+        public float inOffset;
+        public Target.Floaty out;
+    }
+
+    private void checkFmaFloatFloatFloatFloat() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x85c419bel, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x85c419bfl, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9d441b0el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testFmaFloatFloatFloatFloat(inMultiplicand1, out);
+            verifyResultsFmaFloatFloatFloatFloat(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloatFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testFmaFloatFloatFloatFloat(inMultiplicand1, out);
+            verifyResultsFmaFloatFloatFloatFloat(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloatFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaFloatFloatFloatFloat(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        float[] arrayInMultiplicand1 = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMultiplicand1, (float) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        float[] arrayInMultiplicand2 = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMultiplicand2, (float) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        float[] arrayInOffset = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInOffset, (float) 42);
+        inOffset.copyTo(arrayInOffset);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inMultiplicand1 = arrayInMultiplicand1[i];
+                args.inMultiplicand2 = arrayInMultiplicand2[i];
+                args.inOffset = arrayInOffset[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkFmaFloatFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaFloat2Float2Float2Float2() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdda15056l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdda15057l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8aeda396l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testFmaFloat2Float2Float2Float2(inMultiplicand1, out);
+            verifyResultsFmaFloat2Float2Float2Float2(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testFmaFloat2Float2Float2Float2(inMultiplicand1, out);
+            verifyResultsFmaFloat2Float2Float2Float2(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaFloat2Float2Float2Float2(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        float[] arrayInMultiplicand1 = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInMultiplicand1, (float) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        float[] arrayInMultiplicand2 = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInMultiplicand2, (float) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        float[] arrayInOffset = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInOffset, (float) 42);
+        inOffset.copyTo(arrayInOffset);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 2 + j];
+                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);
+                CoreMathVerifier.computeFma(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 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]);
+                        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 checkFmaFloat2Float2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaFloat3Float3Float3Float3() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x349697b2l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x349697b3l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x54d5ec8al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testFmaFloat3Float3Float3Float3(inMultiplicand1, out);
+            verifyResultsFmaFloat3Float3Float3Float3(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat3Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testFmaFloat3Float3Float3Float3(inMultiplicand1, out);
+            verifyResultsFmaFloat3Float3Float3Float3(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat3Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaFloat3Float3Float3Float3(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        float[] arrayInMultiplicand1 = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand1, (float) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        float[] arrayInMultiplicand2 = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand2, (float) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        float[] arrayInOffset = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInOffset, (float) 42);
+        inOffset.copyTo(arrayInOffset);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
+                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);
+                CoreMathVerifier.computeFma(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 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]);
+                        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 checkFmaFloat3Float3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaFloat4Float4Float4Float4() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8b8bdf0el, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8b8bdf0fl, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1ebe357el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testFmaFloat4Float4Float4Float4(inMultiplicand1, out);
+            verifyResultsFmaFloat4Float4Float4Float4(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat4Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testFmaFloat4Float4Float4Float4(inMultiplicand1, out);
+            verifyResultsFmaFloat4Float4Float4Float4(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaFloat4Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaFloat4Float4Float4Float4(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        float[] arrayInMultiplicand1 = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand1, (float) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        float[] arrayInMultiplicand2 = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand2, (float) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        float[] arrayInOffset = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInOffset, (float) 42);
+        inOffset.copyTo(arrayInOffset);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
+                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);
+                CoreMathVerifier.computeFma(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 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]);
+                        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 checkFmaFloat4Float4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFma() {
+        checkFmaFloatFloatFloatFloat();
+        checkFmaFloat2Float2Float2Float2();
+        checkFmaFloat3Float3Float3Float3();
+        checkFmaFloat4Float4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.rs
new file mode 100644
index 0000000..1b720c1
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFma.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInMultiplicand2;
+rs_allocation gAllocInOffset;
+
+float __attribute__((kernel)) testFmaFloatFloatFloatFloat(float inMultiplicand1, unsigned int x) {
+    float inMultiplicand2 = rsGetElementAt_float(gAllocInMultiplicand2, x);
+    float inOffset = rsGetElementAt_float(gAllocInOffset, x);
+    return fma(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+float2 __attribute__((kernel)) testFmaFloat2Float2Float2Float2(float2 inMultiplicand1, unsigned int x) {
+    float2 inMultiplicand2 = rsGetElementAt_float2(gAllocInMultiplicand2, x);
+    float2 inOffset = rsGetElementAt_float2(gAllocInOffset, x);
+    return fma(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+float3 __attribute__((kernel)) testFmaFloat3Float3Float3Float3(float3 inMultiplicand1, unsigned int x) {
+    float3 inMultiplicand2 = rsGetElementAt_float3(gAllocInMultiplicand2, x);
+    float3 inOffset = rsGetElementAt_float3(gAllocInOffset, x);
+    return fma(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+float4 __attribute__((kernel)) testFmaFloat4Float4Float4Float4(float4 inMultiplicand1, unsigned int x) {
+    float4 inMultiplicand2 = rsGetElementAt_float4(gAllocInMultiplicand2, x);
+    float4 inOffset = rsGetElementAt_float4(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
new file mode 100644
index 0000000..723cbd6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFma.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.java
new file mode 100644
index 0000000..56ea3d9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.java
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFmax extends RSBaseCompute {
+
+    private ScriptC_TestFmax script;
+    private ScriptC_TestFmaxRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFmax(mRS);
+        scriptRelaxed = new ScriptC_TestFmaxRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public Target.Floaty out;
+    }
+
+    private void checkFmaxFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6e6fdd7al, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6e6fdd7bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxFloatFloatFloat(inA, out);
+            verifyResultsFmaxFloatFloatFloat(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxFloatFloatFloat(inA, out);
+            verifyResultsFmaxFloatFloatFloat(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloatFloatFloat(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        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 * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFmax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkFmaxFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxFloat2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd458a0c8l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd458a0c9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxFloat2Float2Float2(inA, out);
+            verifyResultsFmaxFloat2Float2Float2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxFloat2Float2Float2(inA, out);
+            verifyResultsFmaxFloat2Float2Float2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat2Float2Float2(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 * 2];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFmax(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxFloat3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd636a269l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd636a26al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxFloat3Float3Float3(inA, out);
+            verifyResultsFmaxFloat3Float3Float3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxFloat3Float3Float3(inA, out);
+            verifyResultsFmaxFloat3Float3Float3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat3Float3Float3(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFmax(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxFloat4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd814a40al, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd814a40bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxFloat4Float4Float4(inA, out);
+            verifyResultsFmaxFloat4Float4Float4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxFloat4Float4Float4(inA, out);
+            verifyResultsFmaxFloat4Float4Float4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat4Float4Float4(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFmax(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxFloat4Float4Float4" +
+                (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);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxFloat2FloatFloat2(inA, out);
+            verifyResultsFmaxFloat2FloatFloat2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxFloat2FloatFloat2(inA, out);
+            verifyResultsFmaxFloat2FloatFloat2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat2FloatFloat2(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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFmax(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxFloat2FloatFloat2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxFloat3FloatFloat3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcace055el, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xcace055fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxFloat3FloatFloat3(inA, out);
+            verifyResultsFmaxFloat3FloatFloat3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxFloat3FloatFloat3(inA, out);
+            verifyResultsFmaxFloat3FloatFloat3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat3FloatFloat3(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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFmax(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxFloat3FloatFloat3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmaxFloat4FloatFloat4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb938f9bal, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb938f9bbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFmaxFloat4FloatFloat4(inA, out);
+            verifyResultsFmaxFloat4FloatFloat4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFmaxFloat4FloatFloat4(inA, out);
+            verifyResultsFmaxFloat4FloatFloat4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmaxFloat4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmaxFloat4FloatFloat4(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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFmax(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFmaxFloat4FloatFloat4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFmax() {
+        checkFmaxFloatFloatFloat();
+        checkFmaxFloat2Float2Float2();
+        checkFmaxFloat3Float3Float3();
+        checkFmaxFloat4Float4Float4();
+        checkFmaxFloat2FloatFloat2();
+        checkFmaxFloat3FloatFloat3();
+        checkFmaxFloat4FloatFloat4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.rs
new file mode 100644
index 0000000..418c5c1
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmax.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInB;
+
+float __attribute__((kernel)) testFmaxFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
+float2 __attribute__((kernel)) testFmaxFloat2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
+float3 __attribute__((kernel)) testFmaxFloat3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
+float4 __attribute__((kernel)) testFmaxFloat4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(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);
+}
+
+float3 __attribute__((kernel)) testFmaxFloat3FloatFloat3(float3 inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return fmax(inA, inB);
+}
+
+float4 __attribute__((kernel)) testFmaxFloat4FloatFloat4(float4 inA, unsigned int x) {
+    float inB = rsGetElementAt_float(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
new file mode 100644
index 0000000..e0a124b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmaxRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFmax.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.java
new file mode 100644
index 0000000..c96daa4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.java
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFmin extends RSBaseCompute {
+
+    private ScriptC_TestFmin script;
+    private ScriptC_TestFminRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFmin(mRS);
+        scriptRelaxed = new ScriptC_TestFminRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public Target.Floaty out;
+    }
+
+    private void checkFminFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1d7b1058l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1d7b1059l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminFloatFloatFloat(inA, out);
+            verifyResultsFminFloatFloatFloat(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminFloatFloatFloat(inA, out);
+            verifyResultsFminFloatFloatFloat(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloatFloatFloat(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        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 * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFmin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkFminFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminFloat2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe75faa42l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe75faa43l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminFloat2Float2Float2(inA, out);
+            verifyResultsFminFloat2Float2Float2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminFloat2Float2Float2(inA, out);
+            verifyResultsFminFloat2Float2Float2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat2Float2Float2(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 * 2];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFmin(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminFloat3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe93dabe3l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe93dabe4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminFloat3Float3Float3(inA, out);
+            verifyResultsFminFloat3Float3Float3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminFloat3Float3Float3(inA, out);
+            verifyResultsFminFloat3Float3Float3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat3Float3Float3(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFmin(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminFloat4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xeb1bad84l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xeb1bad85l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminFloat4Float4Float4(inA, out);
+            verifyResultsFminFloat4Float4Float4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminFloat4Float4Float4(inA, out);
+            verifyResultsFminFloat4Float4Float4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat4Float4Float4(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFmin(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminFloat4Float4Float4" +
+                (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);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminFloat2FloatFloat2(inA, out);
+            verifyResultsFminFloat2FloatFloat2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminFloat2FloatFloat2(inA, out);
+            verifyResultsFminFloat2FloatFloat2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat2FloatFloat2(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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFmin(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminFloat2FloatFloat2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminFloat3FloatFloat3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x12b06accl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x12b06acdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminFloat3FloatFloat3(inA, out);
+            verifyResultsFminFloat3FloatFloat3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminFloat3FloatFloat3(inA, out);
+            verifyResultsFminFloat3FloatFloat3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat3FloatFloat3(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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFmin(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminFloat3FloatFloat3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFminFloat4FloatFloat4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x11b5f28l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x11b5f29l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testFminFloat4FloatFloat4(inA, out);
+            verifyResultsFminFloat4FloatFloat4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testFminFloat4FloatFloat4(inA, out);
+            verifyResultsFminFloat4FloatFloat4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFminFloat4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFminFloat4FloatFloat4(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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFmin(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkFminFloat4FloatFloat4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFmin() {
+        checkFminFloatFloatFloat();
+        checkFminFloat2Float2Float2();
+        checkFminFloat3Float3Float3();
+        checkFminFloat4Float4Float4();
+        checkFminFloat2FloatFloat2();
+        checkFminFloat3FloatFloat3();
+        checkFminFloat4FloatFloat4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.rs
new file mode 100644
index 0000000..1e25a34
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmin.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInB;
+
+float __attribute__((kernel)) testFminFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
+float2 __attribute__((kernel)) testFminFloat2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
+float3 __attribute__((kernel)) testFminFloat3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
+float4 __attribute__((kernel)) testFminFloat4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(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);
+}
+
+float3 __attribute__((kernel)) testFminFloat3FloatFloat3(float3 inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return fmin(inA, inB);
+}
+
+float4 __attribute__((kernel)) testFminFloat4FloatFloat4(float4 inA, unsigned int x) {
+    float inB = rsGetElementAt_float(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
new file mode 100644
index 0000000..cee70ab
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFminRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFmin.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.java
new file mode 100644
index 0000000..442cad9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFmod extends RSBaseCompute {
+
+    private ScriptC_TestFmod script;
+    private ScriptC_TestFmodRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFmod(mRS);
+        scriptRelaxed = new ScriptC_TestFmodRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inNumerator;
+        public float inDenominator;
+        public Target.Floaty out;
+    }
+
+    private void checkFmodFloatFloatFloat() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdcc790e8l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4b044e1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testFmodFloatFloatFloat(inNumerator, out);
+            verifyResultsFmodFloatFloatFloat(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testFmodFloatFloatFloat(inNumerator, out);
+            verifyResultsFmodFloatFloatFloat(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodFloatFloatFloat(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inNumerator = arrayInNumerator[i];
+                args.inDenominator = arrayInDenominator[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFmod(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkFmodFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmodFloat2Float2Float2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xebd95a82l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdc295e2bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testFmodFloat2Float2Float2(inNumerator, out);
+            verifyResultsFmodFloat2Float2Float2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testFmodFloat2Float2Float2(inNumerator, out);
+            verifyResultsFmodFloat2Float2Float2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodFloat2Float2Float2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFmod(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 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]);
+                        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 checkFmodFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmodFloat3Float3Float3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8ea54683l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xaf04f164l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testFmodFloat3Float3Float3(inNumerator, out);
+            verifyResultsFmodFloat3Float3Float3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testFmodFloat3Float3Float3(inNumerator, out);
+            verifyResultsFmodFloat3Float3Float3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodFloat3Float3Float3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFmod(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 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]);
+                        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 checkFmodFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFmodFloat4Float4Float4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x31713284l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x81e0849dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testFmodFloat4Float4Float4(inNumerator, out);
+            verifyResultsFmodFloat4Float4Float4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testFmodFloat4Float4Float4(inNumerator, out);
+            verifyResultsFmodFloat4Float4Float4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFmodFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFmodFloat4Float4Float4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeFmod(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 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]);
+                        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 checkFmodFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFmod() {
+        checkFmodFloatFloatFloat();
+        checkFmodFloat2Float2Float2();
+        checkFmodFloat3Float3Float3();
+        checkFmodFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.rs
new file mode 100644
index 0000000..8582fae
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmod.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInDenominator;
+
+float __attribute__((kernel)) testFmodFloatFloatFloat(float inNumerator, unsigned int x) {
+    float inDenominator = rsGetElementAt_float(gAllocInDenominator, x);
+    return fmod(inNumerator, inDenominator);
+}
+
+float2 __attribute__((kernel)) testFmodFloat2Float2Float2(float2 inNumerator, unsigned int x) {
+    float2 inDenominator = rsGetElementAt_float2(gAllocInDenominator, x);
+    return fmod(inNumerator, inDenominator);
+}
+
+float3 __attribute__((kernel)) testFmodFloat3Float3Float3(float3 inNumerator, unsigned int x) {
+    float3 inDenominator = rsGetElementAt_float3(gAllocInDenominator, x);
+    return fmod(inNumerator, inDenominator);
+}
+
+float4 __attribute__((kernel)) testFmodFloat4Float4Float4(float4 inNumerator, unsigned int x) {
+    float4 inDenominator = rsGetElementAt_float4(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
new file mode 100644
index 0000000..08b8164
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFmodRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFmod.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.java
new file mode 100644
index 0000000..11ad1be
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.java
@@ -0,0 +1,688 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFract extends RSBaseCompute {
+
+    private ScriptC_TestFract script;
+    private ScriptC_TestFractRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFract(mRS);
+        scriptRelaxed = new ScriptC_TestFractRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inV;
+        public Target.Floaty outFloor;
+        public Target.Floaty out;
+    }
+
+    private void checkFractFloatFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3c675d27l, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractFloatFloatFloat(inV, out);
+            verifyResultsFractFloatFloatFloat(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractFloatFloatFloat(inV, out);
+            verifyResultsFractFloatFloatFloat(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloatFloatFloat(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutFloor = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOutFloor, (float) 42);
+        outFloor.copyTo(arrayOutFloor);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(arrayOutFloor[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(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]);
+                        if (!args.outFloor.couldBe(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]);
+                        if (!args.out.couldBe(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 checkFractFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractFloat2Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xcdf8f525l, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractFloat2Float2Float2(inV, out);
+            verifyResultsFractFloat2Float2Float2(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractFloat2Float2Float2(inV, out);
+            verifyResultsFractFloat2Float2Float2(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat2Float2Float2(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutFloor = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayOutFloor, (float) 42);
+        outFloor.copyTo(arrayOutFloor);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(arrayOutFloor[i * 2 + j])) {
+                    valid = false;
+                }
+                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 outFloor: ");
+                        appendVariableToMessage(message, args.outFloor);
+                        message.append("\n");
+                        message.append("Actual   output outFloor: ");
+                        appendVariableToMessage(message, arrayOutFloor[i * 2 + j]);
+                        if (!args.outFloor.couldBe(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]);
+                        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 checkFractFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractFloat3Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcfd6f6c6l, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractFloat3Float3Float3(inV, out);
+            verifyResultsFractFloat3Float3Float3(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractFloat3Float3Float3(inV, out);
+            verifyResultsFractFloat3Float3Float3(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat3Float3Float3(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutFloor = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOutFloor, (float) 42);
+        outFloor.copyTo(arrayOutFloor);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
+                    valid = false;
+                }
+                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 outFloor: ");
+                        appendVariableToMessage(message, args.outFloor);
+                        message.append("\n");
+                        message.append("Actual   output outFloor: ");
+                        appendVariableToMessage(message, arrayOutFloor[i * 4 + j]);
+                        if (!args.outFloor.couldBe(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]);
+                        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 checkFractFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractFloat4Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd1b4f867l, false);
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutFloor(outFloor);
+            script.forEach_testFractFloat4Float4Float4(inV, out);
+            verifyResultsFractFloat4Float4Float4(inV, outFloor, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation outFloor = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutFloor(outFloor);
+            scriptRelaxed.forEach_testFractFloat4Float4Float4(inV, out);
+            verifyResultsFractFloat4Float4Float4(inV, outFloor, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat4Float4Float4(Allocation inV, Allocation outFloor, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutFloor = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOutFloor, (float) 42);
+        outFloor.copyTo(arrayOutFloor);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outFloor.couldBe(arrayOutFloor[i * 4 + j])) {
+                    valid = false;
+                }
+                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 outFloor: ");
+                        appendVariableToMessage(message, args.outFloor);
+                        message.append("\n");
+                        message.append("Actual   output outFloor: ");
+                        appendVariableToMessage(message, arrayOutFloor[i * 4 + j]);
+                        if (!args.outFloor.couldBe(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]);
+                        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 checkFractFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkFractFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9db2cad3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testFractFloatFloat(inV, out);
+            verifyResultsFractFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testFractFloatFloat(inV, out);
+            verifyResultsFractFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFract(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkFractFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc4d52edfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testFractFloat2Float2(inV, out);
+            verifyResultsFractFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testFractFloat2Float2(inV, out);
+            verifyResultsFractFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFract(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 checkFractFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbaf04fbdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testFractFloat3Float3(inV, out);
+            verifyResultsFractFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testFractFloat3Float3(inV, out);
+            verifyResultsFractFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFract(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 checkFractFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFractFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb10b709bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testFractFloat4Float4(inV, out);
+            verifyResultsFractFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testFractFloat4Float4(inV, out);
+            verifyResultsFractFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFractFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFractFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFract(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 checkFractFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFract() {
+        checkFractFloatFloatFloat();
+        checkFractFloat2Float2Float2();
+        checkFractFloat3Float3Float3();
+        checkFractFloat4Float4Float4();
+        checkFractFloatFloat();
+        checkFractFloat2Float2();
+        checkFractFloat3Float3();
+        checkFractFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.rs
new file mode 100644
index 0000000..cbc61fa
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFract.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocOutFloor;
+
+float __attribute__((kernel)) testFractFloatFloatFloat(float inV, unsigned int x) {
+    float outFloor = 0;
+    float out = fract(inV, &outFloor);
+    rsSetElementAt_float(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testFractFloat2Float2Float2(float2 inV, unsigned int x) {
+    float2 outFloor = 0;
+    float2 out = fract(inV, &outFloor);
+    rsSetElementAt_float2(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testFractFloat3Float3Float3(float3 inV, unsigned int x) {
+    float3 outFloor = 0;
+    float3 out = fract(inV, &outFloor);
+    rsSetElementAt_float3(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testFractFloat4Float4Float4(float4 inV, unsigned int x) {
+    float4 outFloor = 0;
+    float4 out = fract(inV, &outFloor);
+    rsSetElementAt_float4(gAllocOutFloor, outFloor, x);
+    return out;
+}
+
+float __attribute__((kernel)) testFractFloatFloat(float inV) {
+    return fract(inV);
+}
+
+float2 __attribute__((kernel)) testFractFloat2Float2(float2 inV) {
+    return fract(inV);
+}
+
+float3 __attribute__((kernel)) testFractFloat3Float3(float3 inV) {
+    return fract(inV);
+}
+
+float4 __attribute__((kernel)) testFractFloat4Float4(float4 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
new file mode 100644
index 0000000..26aa16a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFractRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFract.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.java
new file mode 100644
index 0000000..72de03e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestFrexp extends RSBaseCompute {
+
+    private ScriptC_TestFrexp script;
+    private ScriptC_TestFrexpRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestFrexp(mRS);
+        scriptRelaxed = new ScriptC_TestFrexpRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inV;
+        public int outExponent;
+        public Target.Floaty out;
+    }
+
+    private void checkFrexpFloatIntFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7384e56dl, false);
+        try {
+            Allocation outExponent = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutExponent(outExponent);
+            script.forEach_testFrexpFloatIntFloat(inV, out);
+            verifyResultsFrexpFloatIntFloat(inV, outExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation outExponent = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutExponent(outExponent);
+            scriptRelaxed.forEach_testFrexpFloatIntFloat(inV, out);
+            verifyResultsFrexpFloatIntFloat(inV, outExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFrexpFloatIntFloat(Allocation inV, Allocation outExponent, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOutExponent = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayOutExponent, (int) 42);
+        outExponent.copyTo(arrayOutExponent);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFrexp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.outExponent != arrayOutExponent[i * 1 + j]) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(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 outExponent: ");
+                        appendVariableToMessage(message, args.outExponent);
+                        message.append("\n");
+                        message.append("Actual   output outExponent: ");
+                        appendVariableToMessage(message, arrayOutExponent[i * 1 + j]);
+                        if (args.outExponent != arrayOutExponent[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]);
+                        if (!args.out.couldBe(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 checkFrexpFloatIntFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFrexpFloat2Int2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x88fe7701l, false);
+        try {
+            Allocation outExponent = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutExponent(outExponent);
+            script.forEach_testFrexpFloat2Int2Float2(inV, out);
+            verifyResultsFrexpFloat2Int2Float2(inV, outExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation outExponent = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutExponent(outExponent);
+            scriptRelaxed.forEach_testFrexpFloat2Int2Float2(inV, out);
+            verifyResultsFrexpFloat2Int2Float2(inV, outExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFrexpFloat2Int2Float2(Allocation inV, Allocation outExponent, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOutExponent = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayOutExponent, (int) 42);
+        outExponent.copyTo(arrayOutExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFrexp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.outExponent != arrayOutExponent[i * 2 + j]) {
+                    valid = false;
+                }
+                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 outExponent: ");
+                        appendVariableToMessage(message, args.outExponent);
+                        message.append("\n");
+                        message.append("Actual   output outExponent: ");
+                        appendVariableToMessage(message, arrayOutExponent[i * 2 + j]);
+                        if (args.outExponent != arrayOutExponent[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]);
+                        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 checkFrexpFloat2Int2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFrexpFloat3Int3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7eb0e3bal, false);
+        try {
+            Allocation outExponent = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutExponent(outExponent);
+            script.forEach_testFrexpFloat3Int3Float3(inV, out);
+            verifyResultsFrexpFloat3Int3Float3(inV, outExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation outExponent = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutExponent(outExponent);
+            scriptRelaxed.forEach_testFrexpFloat3Int3Float3(inV, out);
+            verifyResultsFrexpFloat3Int3Float3(inV, outExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFrexpFloat3Int3Float3(Allocation inV, Allocation outExponent, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOutExponent = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOutExponent, (int) 42);
+        outExponent.copyTo(arrayOutExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFrexp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.outExponent != arrayOutExponent[i * 4 + j]) {
+                    valid = false;
+                }
+                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 outExponent: ");
+                        appendVariableToMessage(message, args.outExponent);
+                        message.append("\n");
+                        message.append("Actual   output outExponent: ");
+                        appendVariableToMessage(message, arrayOutExponent[i * 4 + j]);
+                        if (args.outExponent != arrayOutExponent[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]);
+                        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 checkFrexpFloat3Int3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkFrexpFloat4Int4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x74635073l, false);
+        try {
+            Allocation outExponent = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutExponent(outExponent);
+            script.forEach_testFrexpFloat4Int4Float4(inV, out);
+            verifyResultsFrexpFloat4Int4Float4(inV, outExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation outExponent = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutExponent(outExponent);
+            scriptRelaxed.forEach_testFrexpFloat4Int4Float4(inV, out);
+            verifyResultsFrexpFloat4Int4Float4(inV, outExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testFrexpFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsFrexpFloat4Int4Float4(Allocation inV, Allocation outExponent, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOutExponent = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOutExponent, (int) 42);
+        outExponent.copyTo(arrayOutExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeFrexp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.outExponent != arrayOutExponent[i * 4 + j]) {
+                    valid = false;
+                }
+                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 outExponent: ");
+                        appendVariableToMessage(message, args.outExponent);
+                        message.append("\n");
+                        message.append("Actual   output outExponent: ");
+                        appendVariableToMessage(message, arrayOutExponent[i * 4 + j]);
+                        if (args.outExponent != arrayOutExponent[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]);
+                        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 checkFrexpFloat4Int4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testFrexp() {
+        checkFrexpFloatIntFloat();
+        checkFrexpFloat2Int2Float2();
+        checkFrexpFloat3Int3Float3();
+        checkFrexpFloat4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.rs
new file mode 100644
index 0000000..901ed3b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexp.rs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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)
+
+rs_allocation gAllocOutExponent;
+
+float __attribute__((kernel)) testFrexpFloatIntFloat(float inV, unsigned int x) {
+    int outExponent = 0;
+    float out = frexp(inV, &outExponent);
+    rsSetElementAt_int(gAllocOutExponent, outExponent, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testFrexpFloat2Int2Float2(float2 inV, unsigned int x) {
+    int2 outExponent = 0;
+    float2 out = frexp(inV, &outExponent);
+    rsSetElementAt_int2(gAllocOutExponent, outExponent, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testFrexpFloat3Int3Float3(float3 inV, unsigned int x) {
+    int3 outExponent = 0;
+    float3 out = frexp(inV, &outExponent);
+    rsSetElementAt_int3(gAllocOutExponent, outExponent, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testFrexpFloat4Int4Float4(float4 inV, unsigned int x) {
+    int4 outExponent = 0;
+    float4 out = frexp(inV, &outExponent);
+    rsSetElementAt_int4(gAllocOutExponent, outExponent, x);
+    return out;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexpRelaxed.rs
new file mode 100644
index 0000000..88acd21
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestFrexpRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestFrexp.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.java
new file mode 100644
index 0000000..4793b6d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestHalfRecip extends RSBaseCompute {
+
+    private ScriptC_TestHalfRecip script;
+    private ScriptC_TestHalfRecipRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestHalfRecip(mRS);
+        scriptRelaxed = new ScriptC_TestHalfRecipRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkHalfRecipFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x130d5b3dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testHalfRecipFloatFloat(inV, out);
+            verifyResultsHalfRecipFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRecipFloatFloat(inV, out);
+            verifyResultsHalfRecipFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRecipFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfRecip(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkHalfRecipFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHalfRecipFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x5ff23c79l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testHalfRecipFloat2Float2(inV, out);
+            verifyResultsHalfRecipFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRecipFloat2Float2(inV, out);
+            verifyResultsHalfRecipFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRecipFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfRecip(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 checkHalfRecipFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHalfRecipFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x560d5d57l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testHalfRecipFloat3Float3(inV, out);
+            verifyResultsHalfRecipFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRecipFloat3Float3(inV, out);
+            verifyResultsHalfRecipFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRecipFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfRecip(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 checkHalfRecipFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHalfRecipFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4c287e35l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testHalfRecipFloat4Float4(inV, out);
+            verifyResultsHalfRecipFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRecipFloat4Float4(inV, out);
+            verifyResultsHalfRecipFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRecipFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRecipFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfRecip(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 checkHalfRecipFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testHalfRecip() {
+        checkHalfRecipFloatFloat();
+        checkHalfRecipFloat2Float2();
+        checkHalfRecipFloat3Float3();
+        checkHalfRecipFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.rs
new file mode 100644
index 0000000..f8bcc3b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecip.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testHalfRecipFloatFloat(float inV) {
+    return half_recip(inV);
+}
+
+float2 __attribute__((kernel)) testHalfRecipFloat2Float2(float2 inV) {
+    return half_recip(inV);
+}
+
+float3 __attribute__((kernel)) testHalfRecipFloat3Float3(float3 inV) {
+    return half_recip(inV);
+}
+
+float4 __attribute__((kernel)) testHalfRecipFloat4Float4(float4 inV) {
+    return half_recip(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecipRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecipRelaxed.rs
new file mode 100644
index 0000000..ded5ceb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRecipRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestHalfRecip.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.java
new file mode 100644
index 0000000..efe890a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestHalfRsqrt extends RSBaseCompute {
+
+    private ScriptC_TestHalfRsqrt script;
+    private ScriptC_TestHalfRsqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestHalfRsqrt(mRS);
+        scriptRelaxed = new ScriptC_TestHalfRsqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkHalfRsqrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc00f0bf2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testHalfRsqrtFloatFloat(inV, out);
+            verifyResultsHalfRsqrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRsqrtFloatFloat(inV, out);
+            verifyResultsHalfRsqrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRsqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkHalfRsqrtFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHalfRsqrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf12787c6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testHalfRsqrtFloat2Float2(inV, out);
+            verifyResultsHalfRsqrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRsqrtFloat2Float2(inV, out);
+            verifyResultsHalfRsqrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRsqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfRsqrt(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 checkHalfRsqrtFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHalfRsqrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe742a8a4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testHalfRsqrtFloat3Float3(inV, out);
+            verifyResultsHalfRsqrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRsqrtFloat3Float3(inV, out);
+            verifyResultsHalfRsqrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRsqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfRsqrt(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 checkHalfRsqrtFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHalfRsqrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xdd5dc982l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testHalfRsqrtFloat4Float4(inV, out);
+            verifyResultsHalfRsqrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfRsqrtFloat4Float4(inV, out);
+            verifyResultsHalfRsqrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfRsqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfRsqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfRsqrt(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 checkHalfRsqrtFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testHalfRsqrt() {
+        checkHalfRsqrtFloatFloat();
+        checkHalfRsqrtFloat2Float2();
+        checkHalfRsqrtFloat3Float3();
+        checkHalfRsqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.rs
new file mode 100644
index 0000000..fcb34c2
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrt.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testHalfRsqrtFloatFloat(float inV) {
+    return half_rsqrt(inV);
+}
+
+float2 __attribute__((kernel)) testHalfRsqrtFloat2Float2(float2 inV) {
+    return half_rsqrt(inV);
+}
+
+float3 __attribute__((kernel)) testHalfRsqrtFloat3Float3(float3 inV) {
+    return half_rsqrt(inV);
+}
+
+float4 __attribute__((kernel)) testHalfRsqrtFloat4Float4(float4 inV) {
+    return half_rsqrt(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrtRelaxed.rs
new file mode 100644
index 0000000..a7928a8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfRsqrtRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestHalfRsqrt.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.java
new file mode 100644
index 0000000..9cf3ff2
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestHalfSqrt extends RSBaseCompute {
+
+    private ScriptC_TestHalfSqrt script;
+    private ScriptC_TestHalfSqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestHalfSqrt(mRS);
+        scriptRelaxed = new ScriptC_TestHalfSqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkHalfSqrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa15db5fal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testHalfSqrtFloatFloat(inV, out);
+            verifyResultsHalfSqrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfSqrtFloatFloat(inV, out);
+            verifyResultsHalfSqrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfSqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkHalfSqrtFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHalfSqrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x42519b8el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testHalfSqrtFloat2Float2(inV, out);
+            verifyResultsHalfSqrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfSqrtFloat2Float2(inV, out);
+            verifyResultsHalfSqrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfSqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfSqrt(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 checkHalfSqrtFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHalfSqrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x386cbc6cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testHalfSqrtFloat3Float3(inV, out);
+            verifyResultsHalfSqrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfSqrtFloat3Float3(inV, out);
+            verifyResultsHalfSqrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfSqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfSqrt(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 checkHalfSqrtFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHalfSqrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2e87dd4al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testHalfSqrtFloat4Float4(inV, out);
+            verifyResultsHalfSqrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testHalfSqrtFloat4Float4(inV, out);
+            verifyResultsHalfSqrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHalfSqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHalfSqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHalfSqrt(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 checkHalfSqrtFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testHalfSqrt() {
+        checkHalfSqrtFloatFloat();
+        checkHalfSqrtFloat2Float2();
+        checkHalfSqrtFloat3Float3();
+        checkHalfSqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.rs
new file mode 100644
index 0000000..db18b05
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrt.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testHalfSqrtFloatFloat(float inV) {
+    return half_sqrt(inV);
+}
+
+float2 __attribute__((kernel)) testHalfSqrtFloat2Float2(float2 inV) {
+    return half_sqrt(inV);
+}
+
+float3 __attribute__((kernel)) testHalfSqrtFloat3Float3(float3 inV) {
+    return half_sqrt(inV);
+}
+
+float4 __attribute__((kernel)) testHalfSqrtFloat4Float4(float4 inV) {
+    return half_sqrt(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrtRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrtRelaxed.rs
new file mode 100644
index 0000000..6fcd519
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHalfSqrtRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestHalfSqrt.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.java
new file mode 100644
index 0000000..8f2e5dd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestHypot extends RSBaseCompute {
+
+    private ScriptC_TestHypot script;
+    private ScriptC_TestHypotRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestHypot(mRS);
+        scriptRelaxed = new ScriptC_TestHypotRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public Target.Floaty out;
+    }
+
+    private void checkHypotFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x738c74c4l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x738c74c5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testHypotFloatFloatFloat(inA, out);
+            verifyResultsHypotFloatFloatFloat(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testHypotFloatFloatFloat(inA, out);
+            verifyResultsHypotFloatFloatFloat(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotFloatFloatFloat(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        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 * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkHypotFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHypotFloat2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x62f71c46l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x62f71c47l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testHypotFloat2Float2Float2(inA, out);
+            verifyResultsHypotFloat2Float2Float2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testHypotFloat2Float2Float2(inA, out);
+            verifyResultsHypotFloat2Float2Float2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotFloat2Float2Float2(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 * 2];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeHypot(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkHypotFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHypotFloat3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x64d51de7l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x64d51de8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testHypotFloat3Float3Float3(inA, out);
+            verifyResultsHypotFloat3Float3Float3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testHypotFloat3Float3Float3(inA, out);
+            verifyResultsHypotFloat3Float3Float3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotFloat3Float3Float3(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeHypot(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkHypotFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkHypotFloat4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x66b31f88l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x66b31f89l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testHypotFloat4Float4Float4(inA, out);
+            verifyResultsHypotFloat4Float4Float4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testHypotFloat4Float4Float4(inA, out);
+            verifyResultsHypotFloat4Float4Float4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testHypotFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsHypotFloat4Float4Float4(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeHypot(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkHypotFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testHypot() {
+        checkHypotFloatFloatFloat();
+        checkHypotFloat2Float2Float2();
+        checkHypotFloat3Float3Float3();
+        checkHypotFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.rs
new file mode 100644
index 0000000..fcaae50
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypot.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInB;
+
+float __attribute__((kernel)) testHypotFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return hypot(inA, inB);
+}
+
+float2 __attribute__((kernel)) testHypotFloat2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    return hypot(inA, inB);
+}
+
+float3 __attribute__((kernel)) testHypotFloat3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    return hypot(inA, inB);
+}
+
+float4 __attribute__((kernel)) testHypotFloat4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(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
new file mode 100644
index 0000000..90f3d69
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestHypotRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestHypot.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.java
new file mode 100644
index 0000000..8a24f7a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.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.
+ */
+
+// 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 java.util.Arrays;
+
+public class TestIlogb extends RSBaseCompute {
+
+    private ScriptC_TestIlogb script;
+    private ScriptC_TestIlogbRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestIlogb(mRS);
+        scriptRelaxed = new ScriptC_TestIlogbRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatInt {
+        public float inV;
+        public int out;
+    }
+
+    private void checkIlogbFloatInt() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5664967bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.forEach_testIlogbFloatInt(inV, out);
+            verifyResultsIlogbFloatInt(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloatInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testIlogbFloatInt(inV, out);
+            verifyResultsIlogbFloatInt(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloatInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsIlogbFloatInt(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i];
+                // Extract the outputs.
+                args.out = arrayOut[i * 1 + j];
+                // Ask the CoreMathVerifier to validate.
+                String errorMessage = CoreMathVerifier.verifyIlogb(args);
+                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(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 checkIlogbFloatInt" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkIlogbFloat2Int2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb6f32a61l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.forEach_testIlogbFloat2Int2(inV, out);
+            verifyResultsIlogbFloat2Int2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testIlogbFloat2Int2(inV, out);
+            verifyResultsIlogbFloat2Int2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsIlogbFloat2Int2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i * 2 + j];
+                // Extract the outputs.
+                args.out = arrayOut[i * 2 + j];
+                // Ask the CoreMathVerifier to validate.
+                String errorMessage = CoreMathVerifier.verifyIlogb(args);
+                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(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 checkIlogbFloat2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkIlogbFloat3Int3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9b3a97l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.forEach_testIlogbFloat3Int3(inV, out);
+            verifyResultsIlogbFloat3Int3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testIlogbFloat3Int3(inV, out);
+            verifyResultsIlogbFloat3Int3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsIlogbFloat3Int3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Extract the outputs.
+                args.out = arrayOut[i * 4 + j];
+                // Ask the CoreMathVerifier to validate.
+                String errorMessage = CoreMathVerifier.verifyIlogb(args);
+                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(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 checkIlogbFloat3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkIlogbFloat4Int4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4a434acdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.forEach_testIlogbFloat4Int4(inV, out);
+            verifyResultsIlogbFloat4Int4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testIlogbFloat4Int4(inV, out);
+            verifyResultsIlogbFloat4Int4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testIlogbFloat4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsIlogbFloat4Int4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatInt args = new ArgumentsFloatInt();
+                args.inV = arrayInV[i * 4 + j];
+                // Extract the outputs.
+                args.out = arrayOut[i * 4 + j];
+                // Ask the CoreMathVerifier to validate.
+                String errorMessage = CoreMathVerifier.verifyIlogb(args);
+                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(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 checkIlogbFloat4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testIlogb() {
+        checkIlogbFloatInt();
+        checkIlogbFloat2Int2();
+        checkIlogbFloat3Int3();
+        checkIlogbFloat4Int4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.rs
new file mode 100644
index 0000000..f93ab80
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogb.rs
@@ -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.
+ */
+
+// 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)
+
+
+int __attribute__((kernel)) testIlogbFloatInt(float inV) {
+    return ilogb(inV);
+}
+
+int2 __attribute__((kernel)) testIlogbFloat2Int2(float2 inV) {
+    return ilogb(inV);
+}
+
+int3 __attribute__((kernel)) testIlogbFloat3Int3(float3 inV) {
+    return ilogb(inV);
+}
+
+int4 __attribute__((kernel)) testIlogbFloat4Int4(float4 inV) {
+    return ilogb(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogbRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogbRelaxed.rs
new file mode 100644
index 0000000..995b659
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestIlogbRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestIlogb.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.java
new file mode 100644
index 0000000..6dc48ed
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.java
@@ -0,0 +1,607 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestLdexp extends RSBaseCompute {
+
+    private ScriptC_TestLdexp script;
+    private ScriptC_TestLdexpRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLdexp(mRS);
+        scriptRelaxed = new ScriptC_TestLdexpRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inMantissa;
+        public int inExponent;
+        public Target.Floaty out;
+    }
+
+    private void checkLdexpFloatIntFloat() {
+        Allocation inMantissa = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x90f0e26fl, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x2e4133c4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testLdexpFloatIntFloat(inMantissa, out);
+            verifyResultsLdexpFloatIntFloat(inMantissa, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testLdexpFloatIntFloat(inMantissa, out);
+            verifyResultsLdexpFloatIntFloat(inMantissa, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloatIntFloat(Allocation inMantissa, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInMantissa = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMantissa, (float) 42);
+        inMantissa.copyTo(arrayInMantissa);
+        int[] arrayInExponent = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inMantissa = arrayInMantissa[i];
+                args.inExponent = arrayInExponent[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLdexp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inMantissa: ");
+                        appendVariableToMessage(message, args.inMantissa);
+                        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]);
+                        if (!args.out.couldBe(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 checkLdexpFloatIntFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLdexpFloat2Int2Float2() {
+        Allocation inMantissa = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4fe92893l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xed3979e8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testLdexpFloat2Int2Float2(inMantissa, out);
+            verifyResultsLdexpFloat2Int2Float2(inMantissa, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testLdexpFloat2Int2Float2(inMantissa, out);
+            verifyResultsLdexpFloat2Int2Float2(inMantissa, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat2Int2Float2(Allocation inMantissa, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInMantissa = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInMantissa, (float) 42);
+        inMantissa.copyTo(arrayInMantissa);
+        int[] arrayInExponent = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computeLdexp(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 inMantissa: ");
+                        appendVariableToMessage(message, args.inMantissa);
+                        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]);
+                        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 checkLdexpFloat2Int2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLdexpFloat3Int3Float3() {
+        Allocation inMantissa = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3fa3335el, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xdcf384b3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testLdexpFloat3Int3Float3(inMantissa, out);
+            verifyResultsLdexpFloat3Int3Float3(inMantissa, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testLdexpFloat3Int3Float3(inMantissa, out);
+            verifyResultsLdexpFloat3Int3Float3(inMantissa, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat3Int3Float3(Allocation inMantissa, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInMantissa = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMantissa, (float) 42);
+        inMantissa.copyTo(arrayInMantissa);
+        int[] arrayInExponent = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computeLdexp(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 inMantissa: ");
+                        appendVariableToMessage(message, args.inMantissa);
+                        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]);
+                        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 checkLdexpFloat3Int3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLdexpFloat4Int4Float4() {
+        Allocation inMantissa = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2f5d3e29l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xccad8f7el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testLdexpFloat4Int4Float4(inMantissa, out);
+            verifyResultsLdexpFloat4Int4Float4(inMantissa, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testLdexpFloat4Int4Float4(inMantissa, out);
+            verifyResultsLdexpFloat4Int4Float4(inMantissa, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat4Int4Float4(Allocation inMantissa, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInMantissa = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMantissa, (float) 42);
+        inMantissa.copyTo(arrayInMantissa);
+        int[] arrayInExponent = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computeLdexp(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 inMantissa: ");
+                        appendVariableToMessage(message, args.inMantissa);
+                        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]);
+                        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 checkLdexpFloat4Int4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLdexpFloat2IntFloat2() {
+        Allocation inMantissa = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x38bd38d1l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xd60d8a26l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testLdexpFloat2IntFloat2(inMantissa, out);
+            verifyResultsLdexpFloat2IntFloat2(inMantissa, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2IntFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testLdexpFloat2IntFloat2(inMantissa, out);
+            verifyResultsLdexpFloat2IntFloat2(inMantissa, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat2IntFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat2IntFloat2(Allocation inMantissa, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInMantissa = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInMantissa, (float) 42);
+        inMantissa.copyTo(arrayInMantissa);
+        int[] arrayInExponent = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inMantissa = arrayInMantissa[i * 2 + j];
+                args.inExponent = arrayInExponent[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLdexp(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 inMantissa: ");
+                        appendVariableToMessage(message, args.inMantissa);
+                        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]);
+                        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 checkLdexpFloat2IntFloat2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLdexpFloat3IntFloat3() {
+        Allocation inMantissa = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5150f83dl, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xeea14992l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testLdexpFloat3IntFloat3(inMantissa, out);
+            verifyResultsLdexpFloat3IntFloat3(inMantissa, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3IntFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testLdexpFloat3IntFloat3(inMantissa, out);
+            verifyResultsLdexpFloat3IntFloat3(inMantissa, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat3IntFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat3IntFloat3(Allocation inMantissa, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInMantissa = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMantissa, (float) 42);
+        inMantissa.copyTo(arrayInMantissa);
+        int[] arrayInExponent = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inMantissa = arrayInMantissa[i * 4 + j];
+                args.inExponent = arrayInExponent[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLdexp(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 inMantissa: ");
+                        appendVariableToMessage(message, args.inMantissa);
+                        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]);
+                        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 checkLdexpFloat3IntFloat3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLdexpFloat4IntFloat4() {
+        Allocation inMantissa = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x69e4b7a9l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x73508fel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testLdexpFloat4IntFloat4(inMantissa, out);
+            verifyResultsLdexpFloat4IntFloat4(inMantissa, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4IntFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testLdexpFloat4IntFloat4(inMantissa, out);
+            verifyResultsLdexpFloat4IntFloat4(inMantissa, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLdexpFloat4IntFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLdexpFloat4IntFloat4(Allocation inMantissa, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInMantissa = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMantissa, (float) 42);
+        inMantissa.copyTo(arrayInMantissa);
+        int[] arrayInExponent = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inMantissa = arrayInMantissa[i * 4 + j];
+                args.inExponent = arrayInExponent[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLdexp(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 inMantissa: ");
+                        appendVariableToMessage(message, args.inMantissa);
+                        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]);
+                        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 checkLdexpFloat4IntFloat4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testLdexp() {
+        checkLdexpFloatIntFloat();
+        checkLdexpFloat2Int2Float2();
+        checkLdexpFloat3Int3Float3();
+        checkLdexpFloat4Int4Float4();
+        checkLdexpFloat2IntFloat2();
+        checkLdexpFloat3IntFloat3();
+        checkLdexpFloat4IntFloat4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.rs
new file mode 100644
index 0000000..212a2e6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexp.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInExponent;
+
+float __attribute__((kernel)) testLdexpFloatIntFloat(float inMantissa, unsigned int x) {
+    int inExponent = rsGetElementAt_int(gAllocInExponent, x);
+    return ldexp(inMantissa, inExponent);
+}
+
+float2 __attribute__((kernel)) testLdexpFloat2Int2Float2(float2 inMantissa, unsigned int x) {
+    int2 inExponent = rsGetElementAt_int2(gAllocInExponent, x);
+    return ldexp(inMantissa, inExponent);
+}
+
+float3 __attribute__((kernel)) testLdexpFloat3Int3Float3(float3 inMantissa, unsigned int x) {
+    int3 inExponent = rsGetElementAt_int3(gAllocInExponent, x);
+    return ldexp(inMantissa, inExponent);
+}
+
+float4 __attribute__((kernel)) testLdexpFloat4Int4Float4(float4 inMantissa, unsigned int x) {
+    int4 inExponent = rsGetElementAt_int4(gAllocInExponent, x);
+    return ldexp(inMantissa, inExponent);
+}
+
+float2 __attribute__((kernel)) testLdexpFloat2IntFloat2(float2 inMantissa, unsigned int x) {
+    int inExponent = rsGetElementAt_int(gAllocInExponent, x);
+    return ldexp(inMantissa, inExponent);
+}
+
+float3 __attribute__((kernel)) testLdexpFloat3IntFloat3(float3 inMantissa, unsigned int x) {
+    int inExponent = rsGetElementAt_int(gAllocInExponent, x);
+    return ldexp(inMantissa, inExponent);
+}
+
+float4 __attribute__((kernel)) testLdexpFloat4IntFloat4(float4 inMantissa, unsigned int x) {
+    int inExponent = rsGetElementAt_int(gAllocInExponent, x);
+    return ldexp(inMantissa, inExponent);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexpRelaxed.rs
new file mode 100644
index 0000000..2ab8836
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLdexpRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestLdexp.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.java
new file mode 100644
index 0000000..1e91f42
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestLength extends RSBaseCompute {
+
+    private ScriptC_TestLength script;
+    private ScriptC_TestLengthRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLength(mRS);
+        scriptRelaxed = new ScriptC_TestLengthRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkLengthFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9f7cc9fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLengthFloatFloat(inV, out);
+            verifyResultsLengthFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthFloatFloat(inV, out);
+            verifyResultsLengthFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkLengthFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloat {
+        public float[] inV;
+        public Target.Floaty out;
+    }
+
+    private void checkLengthFloat2Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x5dd9595dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLengthFloat2Float(inV, out);
+            verifyResultsLengthFloat2Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthFloat2Float(inV, out);
+            verifyResultsLengthFloat2Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthFloat2Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkLengthFloat2Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLengthFloat3Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbcdfe7bel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLengthFloat3Float(inV, out);
+            verifyResultsLengthFloat3Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthFloat3Float(inV, out);
+            verifyResultsLengthFloat3Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthFloat3Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkLengthFloat3Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLengthFloat4Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1be6761fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLengthFloat4Float(inV, out);
+            verifyResultsLengthFloat4Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLengthFloat4Float(inV, out);
+            verifyResultsLengthFloat4Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLengthFloat4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLengthFloat4Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkLengthFloat4Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testLength() {
+        checkLengthFloatFloat();
+        checkLengthFloat2Float();
+        checkLengthFloat3Float();
+        checkLengthFloat4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.rs
new file mode 100644
index 0000000..f9c451e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLength.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testLengthFloatFloat(float inV) {
+    return length(inV);
+}
+
+float __attribute__((kernel)) testLengthFloat2Float(float2 inV) {
+    return length(inV);
+}
+
+float __attribute__((kernel)) testLengthFloat3Float(float3 inV) {
+    return length(inV);
+}
+
+float __attribute__((kernel)) testLengthFloat4Float(float4 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
new file mode 100644
index 0000000..695ff5e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLengthRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestLength.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.java
new file mode 100644
index 0000000..073be67
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.java
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestLgamma extends RSBaseCompute {
+
+    private ScriptC_TestLgamma script;
+    private ScriptC_TestLgammaRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLgamma(mRS);
+        scriptRelaxed = new ScriptC_TestLgammaRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkLgammaFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x50bc4bel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLgammaFloatFloat(inV, out);
+            verifyResultsLgammaFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLgammaFloatFloat(inV, out);
+            verifyResultsLgammaFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLgamma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkLgammaFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLgammaFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x367a4132l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLgammaFloat2Float2(inV, out);
+            verifyResultsLgammaFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLgammaFloat2Float2(inV, out);
+            verifyResultsLgammaFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLgamma(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 checkLgammaFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLgammaFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2c956210l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLgammaFloat3Float3(inV, out);
+            verifyResultsLgammaFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLgammaFloat3Float3(inV, out);
+            verifyResultsLgammaFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLgamma(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 checkLgammaFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLgammaFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x22b082eel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLgammaFloat4Float4(inV, out);
+            verifyResultsLgammaFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLgammaFloat4Float4(inV, out);
+            verifyResultsLgammaFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLgamma(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 checkLgammaFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inV;
+        public int outSignOfGamma;
+        public float out;
+    }
+
+    private void checkLgammaFloatIntFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x979c4bb7l, false);
+        try {
+            Allocation outSignOfGamma = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutSignOfGamma(outSignOfGamma);
+            script.forEach_testLgammaFloatIntFloat(inV, out);
+            verifyResultsLgammaFloatIntFloat(inV, outSignOfGamma, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation outSignOfGamma = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutSignOfGamma(outSignOfGamma);
+            scriptRelaxed.forEach_testLgammaFloatIntFloat(inV, out);
+            verifyResultsLgammaFloatIntFloat(inV, outSignOfGamma, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloatIntFloat(Allocation inV, Allocation outSignOfGamma, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOutSignOfGamma = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayOutSignOfGamma, (int) 42);
+        outSignOfGamma.copyTo(arrayOutSignOfGamma);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i];
+                // Extract the outputs.
+                args.outSignOfGamma = arrayOutSignOfGamma[i * 1 + j];
+                args.out = arrayOut[i * 1 + j];
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(relaxed);
+                String errorMessage = CoreMathVerifier.verifyLgamma(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 outSignOfGamma: ");
+                        appendVariableToMessage(message, args.outSignOfGamma);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        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 checkLgammaFloatIntFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLgammaFloat2Int2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x984bcf7fl, false);
+        try {
+            Allocation outSignOfGamma = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutSignOfGamma(outSignOfGamma);
+            script.forEach_testLgammaFloat2Int2Float2(inV, out);
+            verifyResultsLgammaFloat2Int2Float2(inV, outSignOfGamma, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation outSignOfGamma = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutSignOfGamma(outSignOfGamma);
+            scriptRelaxed.forEach_testLgammaFloat2Int2Float2(inV, out);
+            verifyResultsLgammaFloat2Int2Float2(inV, outSignOfGamma, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat2Int2Float2(Allocation inV, Allocation outSignOfGamma, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOutSignOfGamma = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayOutSignOfGamma, (int) 42);
+        outSignOfGamma.copyTo(arrayOutSignOfGamma);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Extract the outputs.
+                args.outSignOfGamma = arrayOutSignOfGamma[i * 2 + j];
+                args.out = arrayOut[i * 2 + j];
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(relaxed);
+                String errorMessage = CoreMathVerifier.verifyLgamma(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 outSignOfGamma: ");
+                        appendVariableToMessage(message, args.outSignOfGamma);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        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 checkLgammaFloat2Int2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLgammaFloat3Int3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8dfe3c38l, false);
+        try {
+            Allocation outSignOfGamma = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutSignOfGamma(outSignOfGamma);
+            script.forEach_testLgammaFloat3Int3Float3(inV, out);
+            verifyResultsLgammaFloat3Int3Float3(inV, outSignOfGamma, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation outSignOfGamma = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutSignOfGamma(outSignOfGamma);
+            scriptRelaxed.forEach_testLgammaFloat3Int3Float3(inV, out);
+            verifyResultsLgammaFloat3Int3Float3(inV, outSignOfGamma, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat3Int3Float3(Allocation inV, Allocation outSignOfGamma, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOutSignOfGamma = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOutSignOfGamma, (int) 42);
+        outSignOfGamma.copyTo(arrayOutSignOfGamma);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Extract the outputs.
+                args.outSignOfGamma = arrayOutSignOfGamma[i * 4 + j];
+                args.out = arrayOut[i * 4 + j];
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(relaxed);
+                String errorMessage = CoreMathVerifier.verifyLgamma(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 outSignOfGamma: ");
+                        appendVariableToMessage(message, args.outSignOfGamma);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        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 checkLgammaFloat3Int3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLgammaFloat4Int4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x83b0a8f1l, false);
+        try {
+            Allocation outSignOfGamma = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutSignOfGamma(outSignOfGamma);
+            script.forEach_testLgammaFloat4Int4Float4(inV, out);
+            verifyResultsLgammaFloat4Int4Float4(inV, outSignOfGamma, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation outSignOfGamma = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutSignOfGamma(outSignOfGamma);
+            scriptRelaxed.forEach_testLgammaFloat4Int4Float4(inV, out);
+            verifyResultsLgammaFloat4Int4Float4(inV, outSignOfGamma, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLgammaFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLgammaFloat4Int4Float4(Allocation inV, Allocation outSignOfGamma, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayOutSignOfGamma = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOutSignOfGamma, (int) 42);
+        outSignOfGamma.copyTo(arrayOutSignOfGamma);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Extract the outputs.
+                args.outSignOfGamma = arrayOutSignOfGamma[i * 4 + j];
+                args.out = arrayOut[i * 4 + j];
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(relaxed);
+                String errorMessage = CoreMathVerifier.verifyLgamma(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 outSignOfGamma: ");
+                        appendVariableToMessage(message, args.outSignOfGamma);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        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 checkLgammaFloat4Int4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testLgamma() {
+        checkLgammaFloatFloat();
+        checkLgammaFloat2Float2();
+        checkLgammaFloat3Float3();
+        checkLgammaFloat4Float4();
+        checkLgammaFloatIntFloat();
+        checkLgammaFloat2Int2Float2();
+        checkLgammaFloat3Int3Float3();
+        checkLgammaFloat4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.rs
new file mode 100644
index 0000000..69cfa03
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgamma.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testLgammaFloatFloat(float inV) {
+    return lgamma(inV);
+}
+
+float2 __attribute__((kernel)) testLgammaFloat2Float2(float2 inV) {
+    return lgamma(inV);
+}
+
+float3 __attribute__((kernel)) testLgammaFloat3Float3(float3 inV) {
+    return lgamma(inV);
+}
+
+float4 __attribute__((kernel)) testLgammaFloat4Float4(float4 inV) {
+    return lgamma(inV);
+}
+rs_allocation gAllocOutSignOfGamma;
+
+float __attribute__((kernel)) testLgammaFloatIntFloat(float inV, unsigned int x) {
+    int outSignOfGamma = 0;
+    float out = lgamma(inV, &outSignOfGamma);
+    rsSetElementAt_int(gAllocOutSignOfGamma, outSignOfGamma, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testLgammaFloat2Int2Float2(float2 inV, unsigned int x) {
+    int2 outSignOfGamma = 0;
+    float2 out = lgamma(inV, &outSignOfGamma);
+    rsSetElementAt_int2(gAllocOutSignOfGamma, outSignOfGamma, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testLgammaFloat3Int3Float3(float3 inV, unsigned int x) {
+    int3 outSignOfGamma = 0;
+    float3 out = lgamma(inV, &outSignOfGamma);
+    rsSetElementAt_int3(gAllocOutSignOfGamma, outSignOfGamma, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testLgammaFloat4Int4Float4(float4 inV, unsigned int x) {
+    int4 outSignOfGamma = 0;
+    float4 out = lgamma(inV, &outSignOfGamma);
+    rsSetElementAt_int4(gAllocOutSignOfGamma, outSignOfGamma, x);
+    return out;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgammaRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgammaRelaxed.rs
new file mode 100644
index 0000000..c781ec2
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLgammaRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestLgamma.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.java
new file mode 100644
index 0000000..2cd529e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestLog extends RSBaseCompute {
+
+    private ScriptC_TestLog script;
+    private ScriptC_TestLogRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLog(mRS);
+        scriptRelaxed = new ScriptC_TestLogRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkLogFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2a43578dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLogFloatFloat(inV, out);
+            verifyResultsLogFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLogFloatFloat(inV, out);
+            verifyResultsLogFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkLogFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4dd9a49l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLogFloat2Float2(inV, out);
+            verifyResultsLogFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLogFloat2Float2(inV, out);
+            verifyResultsLogFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog(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 checkLogFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfaf8bb27l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLogFloat3Float3(inV, out);
+            verifyResultsLogFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLogFloat3Float3(inV, out);
+            verifyResultsLogFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog(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 checkLogFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf113dc05l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLogFloat4Float4(inV, out);
+            verifyResultsLogFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLogFloat4Float4(inV, out);
+            verifyResultsLogFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog(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 checkLogFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testLog() {
+        checkLogFloatFloat();
+        checkLogFloat2Float2();
+        checkLogFloat3Float3();
+        checkLogFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.rs
new file mode 100644
index 0000000..53c9a7d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testLogFloatFloat(float inV) {
+    return log(inV);
+}
+
+float2 __attribute__((kernel)) testLogFloat2Float2(float2 inV) {
+    return log(inV);
+}
+
+float3 __attribute__((kernel)) testLogFloat3Float3(float3 inV) {
+    return log(inV);
+}
+
+float4 __attribute__((kernel)) testLogFloat4Float4(float4 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
new file mode 100644
index 0000000..de534f0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestLog10 extends RSBaseCompute {
+
+    private ScriptC_TestLog10 script;
+    private ScriptC_TestLog10Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLog10(mRS);
+        scriptRelaxed = new ScriptC_TestLog10Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkLog10FloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3171d836l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLog10FloatFloat(inV, out);
+            verifyResultsLog10FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10FloatFloat(inV, out);
+            verifyResultsLog10FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkLog10FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog10Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe3bcdeeal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLog10Float2Float2(inV, out);
+            verifyResultsLog10Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10Float2Float2(inV, out);
+            verifyResultsLog10Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog10(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 checkLog10Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog10Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd9d7ffc8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLog10Float3Float3(inV, out);
+            verifyResultsLog10Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10Float3Float3(inV, out);
+            verifyResultsLog10Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog10(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 checkLog10Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog10Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xcff320a6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLog10Float4Float4(inV, out);
+            verifyResultsLog10Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLog10Float4Float4(inV, out);
+            verifyResultsLog10Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog10Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog10Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog10(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 checkLog10Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testLog10() {
+        checkLog10FloatFloat();
+        checkLog10Float2Float2();
+        checkLog10Float3Float3();
+        checkLog10Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.rs
new file mode 100644
index 0000000..e9b1670
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testLog10FloatFloat(float inV) {
+    return log10(inV);
+}
+
+float2 __attribute__((kernel)) testLog10Float2Float2(float2 inV) {
+    return log10(inV);
+}
+
+float3 __attribute__((kernel)) testLog10Float3Float3(float3 inV) {
+    return log10(inV);
+}
+
+float4 __attribute__((kernel)) testLog10Float4Float4(float4 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
new file mode 100644
index 0000000..90b767a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog10Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestLog10.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.java
new file mode 100644
index 0000000..3bc188a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestLog1p extends RSBaseCompute {
+
+    private ScriptC_TestLog1p script;
+    private ScriptC_TestLog1pRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLog1p(mRS);
+        scriptRelaxed = new ScriptC_TestLog1pRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkLog1pFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x1744cef6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLog1pFloatFloat(inV, out);
+            verifyResultsLog1pFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pFloatFloat(inV, out);
+            verifyResultsLog1pFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkLog1pFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog1pFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd4750faal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLog1pFloat2Float2(inV, out);
+            verifyResultsLog1pFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pFloat2Float2(inV, out);
+            verifyResultsLog1pFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog1p(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 checkLog1pFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog1pFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xca903088l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLog1pFloat3Float3(inV, out);
+            verifyResultsLog1pFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pFloat3Float3(inV, out);
+            verifyResultsLog1pFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog1p(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 checkLog1pFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog1pFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc0ab5166l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLog1pFloat4Float4(inV, out);
+            verifyResultsLog1pFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLog1pFloat4Float4(inV, out);
+            verifyResultsLog1pFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog1pFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog1pFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog1p(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 checkLog1pFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testLog1p() {
+        checkLog1pFloatFloat();
+        checkLog1pFloat2Float2();
+        checkLog1pFloat3Float3();
+        checkLog1pFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.rs
new file mode 100644
index 0000000..feb8f68
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1p.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testLog1pFloatFloat(float inV) {
+    return log1p(inV);
+}
+
+float2 __attribute__((kernel)) testLog1pFloat2Float2(float2 inV) {
+    return log1p(inV);
+}
+
+float3 __attribute__((kernel)) testLog1pFloat3Float3(float3 inV) {
+    return log1p(inV);
+}
+
+float4 __attribute__((kernel)) testLog1pFloat4Float4(float4 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
new file mode 100644
index 0000000..f40b18c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog1pRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestLog1p.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.java
new file mode 100644
index 0000000..ea4b352
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestLog2 extends RSBaseCompute {
+
+    private ScriptC_TestLog2 script;
+    private ScriptC_TestLog2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLog2(mRS);
+        scriptRelaxed = new ScriptC_TestLog2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkLog2FloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc147dc6bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLog2FloatFloat(inV, out);
+            verifyResultsLog2FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2FloatFloat(inV, out);
+            verifyResultsLog2FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkLog2FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog2Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc48141b7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLog2Float2Float2(inV, out);
+            verifyResultsLog2Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2Float2Float2(inV, out);
+            verifyResultsLog2Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog2(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 checkLog2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog2Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xba9c6295l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLog2Float3Float3(inV, out);
+            verifyResultsLog2Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2Float3Float3(inV, out);
+            verifyResultsLog2Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog2(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 checkLog2Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLog2Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb0b78373l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLog2Float4Float4(inV, out);
+            verifyResultsLog2Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLog2Float4Float4(inV, out);
+            verifyResultsLog2Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLog2Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLog2Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLog2(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 checkLog2Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testLog2() {
+        checkLog2FloatFloat();
+        checkLog2Float2Float2();
+        checkLog2Float3Float3();
+        checkLog2Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.rs
new file mode 100644
index 0000000..8f6d43c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testLog2FloatFloat(float inV) {
+    return log2(inV);
+}
+
+float2 __attribute__((kernel)) testLog2Float2Float2(float2 inV) {
+    return log2(inV);
+}
+
+float3 __attribute__((kernel)) testLog2Float3Float3(float3 inV) {
+    return log2(inV);
+}
+
+float4 __attribute__((kernel)) testLog2Float4Float4(float4 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
new file mode 100644
index 0000000..e3fc556
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLog2Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestLog2.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogRelaxed.rs
new file mode 100644
index 0000000..9664748
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestLog.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.java
new file mode 100644
index 0000000..b351a39
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestLogb extends RSBaseCompute {
+
+    private ScriptC_TestLogb script;
+    private ScriptC_TestLogbRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestLogb(mRS);
+        scriptRelaxed = new ScriptC_TestLogbRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkLogbFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xada6157bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testLogbFloatFloat(inV, out);
+            verifyResultsLogbFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbFloatFloat(inV, out);
+            verifyResultsLogbFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLogb(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkLogbFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogbFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf90b6647l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testLogbFloat2Float2(inV, out);
+            verifyResultsLogbFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbFloat2Float2(inV, out);
+            verifyResultsLogbFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLogb(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 checkLogbFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogbFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xef268725l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testLogbFloat3Float3(inV, out);
+            verifyResultsLogbFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbFloat3Float3(inV, out);
+            verifyResultsLogbFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLogb(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 checkLogbFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkLogbFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe541a803l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testLogbFloat4Float4(inV, out);
+            verifyResultsLogbFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testLogbFloat4Float4(inV, out);
+            verifyResultsLogbFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testLogbFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsLogbFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeLogb(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 checkLogbFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testLogb() {
+        checkLogbFloatFloat();
+        checkLogbFloat2Float2();
+        checkLogbFloat3Float3();
+        checkLogbFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.rs
new file mode 100644
index 0000000..40f012a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogb.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testLogbFloatFloat(float inV) {
+    return logb(inV);
+}
+
+float2 __attribute__((kernel)) testLogbFloat2Float2(float2 inV) {
+    return logb(inV);
+}
+
+float3 __attribute__((kernel)) testLogbFloat3Float3(float3 inV) {
+    return logb(inV);
+}
+
+float4 __attribute__((kernel)) testLogbFloat4Float4(float4 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
new file mode 100644
index 0000000..134e4b7
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestLogbRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestLogb.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.java
new file mode 100644
index 0000000..05060fb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.java
@@ -0,0 +1,408 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestMad extends RSBaseCompute {
+
+    private ScriptC_TestMad script;
+    private ScriptC_TestMadRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestMad(mRS);
+        scriptRelaxed = new ScriptC_TestMadRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloatFloat {
+        public float inMultiplicand1;
+        public float inMultiplicand2;
+        public float inOffset;
+        public Target.Floaty out;
+    }
+
+    private void checkMadFloatFloatFloatFloat() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x40b4de48l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x40b4de49l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc50ce0fcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testMadFloatFloatFloatFloat(inMultiplicand1, out);
+            verifyResultsMadFloatFloatFloatFloat(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloatFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testMadFloatFloatFloatFloat(inMultiplicand1, out);
+            verifyResultsMadFloatFloatFloatFloat(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloatFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadFloatFloatFloatFloat(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        float[] arrayInMultiplicand1 = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMultiplicand1, (float) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        float[] arrayInMultiplicand2 = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInMultiplicand2, (float) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        float[] arrayInOffset = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInOffset, (float) 42);
+        inOffset.copyTo(arrayInOffset);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inMultiplicand1 = arrayInMultiplicand1[i];
+                args.inMultiplicand2 = arrayInMultiplicand2[i];
+                args.inOffset = arrayInOffset[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMad(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkMadFloatFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMadFloat2Float2Float2Float2() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8a5fd7c0l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8a5fd7c1l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x318f8924l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testMadFloat2Float2Float2Float2(inMultiplicand1, out);
+            verifyResultsMadFloat2Float2Float2Float2(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testMadFloat2Float2Float2Float2(inMultiplicand1, out);
+            verifyResultsMadFloat2Float2Float2Float2(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadFloat2Float2Float2Float2(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        float[] arrayInMultiplicand1 = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInMultiplicand1, (float) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        float[] arrayInMultiplicand2 = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInMultiplicand2, (float) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        float[] arrayInOffset = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInOffset, (float) 42);
+        inOffset.copyTo(arrayInOffset);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 2 + j];
+                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);
+                CoreMathVerifier.computeMad(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 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]);
+                        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 checkMadFloat2Float2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMadFloat3Float3Float3Float3() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe1551f1cl, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe1551f1dl, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfb77d218l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testMadFloat3Float3Float3Float3(inMultiplicand1, out);
+            verifyResultsMadFloat3Float3Float3Float3(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat3Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testMadFloat3Float3Float3Float3(inMultiplicand1, out);
+            verifyResultsMadFloat3Float3Float3Float3(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat3Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadFloat3Float3Float3Float3(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        float[] arrayInMultiplicand1 = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand1, (float) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        float[] arrayInMultiplicand2 = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand2, (float) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        float[] arrayInOffset = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInOffset, (float) 42);
+        inOffset.copyTo(arrayInOffset);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
+                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);
+                CoreMathVerifier.computeMad(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 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]);
+                        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 checkMadFloat3Float3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMadFloat4Float4Float4Float4() {
+        Allocation inMultiplicand1 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x384a6678l, false);
+        Allocation inMultiplicand2 = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x384a6679l, false);
+        Allocation inOffset = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc5601b0cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInMultiplicand2(inMultiplicand2);
+            script.set_gAllocInOffset(inOffset);
+            script.forEach_testMadFloat4Float4Float4Float4(inMultiplicand1, out);
+            verifyResultsMadFloat4Float4Float4Float4(inMultiplicand1, inMultiplicand2, inOffset, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat4Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInMultiplicand2(inMultiplicand2);
+            scriptRelaxed.set_gAllocInOffset(inOffset);
+            scriptRelaxed.forEach_testMadFloat4Float4Float4Float4(inMultiplicand1, out);
+            verifyResultsMadFloat4Float4Float4Float4(inMultiplicand1, inMultiplicand2, inOffset, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMadFloat4Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMadFloat4Float4Float4Float4(Allocation inMultiplicand1, Allocation inMultiplicand2, Allocation inOffset, Allocation out, boolean relaxed) {
+        float[] arrayInMultiplicand1 = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand1, (float) 42);
+        inMultiplicand1.copyTo(arrayInMultiplicand1);
+        float[] arrayInMultiplicand2 = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInMultiplicand2, (float) 42);
+        inMultiplicand2.copyTo(arrayInMultiplicand2);
+        float[] arrayInOffset = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInOffset, (float) 42);
+        inOffset.copyTo(arrayInOffset);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inMultiplicand1 = arrayInMultiplicand1[i * 4 + j];
+                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);
+                CoreMathVerifier.computeMad(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 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]);
+                        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 checkMadFloat4Float4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testMad() {
+        checkMadFloatFloatFloatFloat();
+        checkMadFloat2Float2Float2Float2();
+        checkMadFloat3Float3Float3Float3();
+        checkMadFloat4Float4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.rs
new file mode 100644
index 0000000..aee9b23
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMad.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInMultiplicand2;
+rs_allocation gAllocInOffset;
+
+float __attribute__((kernel)) testMadFloatFloatFloatFloat(float inMultiplicand1, unsigned int x) {
+    float inMultiplicand2 = rsGetElementAt_float(gAllocInMultiplicand2, x);
+    float inOffset = rsGetElementAt_float(gAllocInOffset, x);
+    return mad(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+float2 __attribute__((kernel)) testMadFloat2Float2Float2Float2(float2 inMultiplicand1, unsigned int x) {
+    float2 inMultiplicand2 = rsGetElementAt_float2(gAllocInMultiplicand2, x);
+    float2 inOffset = rsGetElementAt_float2(gAllocInOffset, x);
+    return mad(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+float3 __attribute__((kernel)) testMadFloat3Float3Float3Float3(float3 inMultiplicand1, unsigned int x) {
+    float3 inMultiplicand2 = rsGetElementAt_float3(gAllocInMultiplicand2, x);
+    float3 inOffset = rsGetElementAt_float3(gAllocInOffset, x);
+    return mad(inMultiplicand1, inMultiplicand2, inOffset);
+}
+
+float4 __attribute__((kernel)) testMadFloat4Float4Float4Float4(float4 inMultiplicand1, unsigned int x) {
+    float4 inMultiplicand2 = rsGetElementAt_float4(gAllocInMultiplicand2, x);
+    float4 inOffset = rsGetElementAt_float4(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
new file mode 100644
index 0000000..a5e9a97
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMadRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestMad.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.java
new file mode 100644
index 0000000..961dafa
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.java
@@ -0,0 +1,3144 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestMax extends RSBaseCompute {
+
+    private ScriptC_TestMax script;
+    private ScriptC_TestMaxRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestMax(mRS);
+        scriptRelaxed = new ScriptC_TestMaxRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public Target.Floaty out;
+    }
+
+    private void checkMaxFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc2162460l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc2162461l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxFloatFloatFloat(inA, out);
+            verifyResultsMaxFloatFloatFloat(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxFloatFloatFloat(inA, out);
+            verifyResultsMaxFloatFloatFloat(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloatFloatFloat(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        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 * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkMaxFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxFloat2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x36addadal, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x36addadbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxFloat2Float2Float2(inA, out);
+            verifyResultsMaxFloat2Float2Float2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxFloat2Float2Float2(inA, out);
+            verifyResultsMaxFloat2Float2Float2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloat2Float2Float2(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 * 2];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeMax(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxFloat3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x388bdc7bl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x388bdc7cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxFloat3Float3Float3(inA, out);
+            verifyResultsMaxFloat3Float3Float3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxFloat3Float3Float3(inA, out);
+            verifyResultsMaxFloat3Float3Float3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloat3Float3Float3(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeMax(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxFloat4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3a69de1cl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3a69de1dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxFloat4Float4Float4(inA, out);
+            verifyResultsMaxFloat4Float4Float4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxFloat4Float4Float4(inA, out);
+            verifyResultsMaxFloat4Float4Float4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloat4Float4Float4(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeMax(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMaxFloat4Float4Float4" +
+                (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);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxFloat2FloatFloat2(inA, out);
+            verifyResultsMaxFloat2FloatFloat2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxFloat2FloatFloat2(inA, out);
+            verifyResultsMaxFloat2FloatFloat2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloat2FloatFloat2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 2];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    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");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxFloat2FloatFloat2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxFloat3FloatFloat3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf6c41894l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf6c41895l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxFloat3FloatFloat3(inA, out);
+            verifyResultsMaxFloat3FloatFloat3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxFloat3FloatFloat3(inA, out);
+            verifyResultsMaxFloat3FloatFloat3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloat3FloatFloat3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    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");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxFloat3FloatFloat3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMaxFloat4FloatFloat4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe52f0cf0l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe52f0cf1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxFloat4FloatFloat4(inA, out);
+            verifyResultsMaxFloat4FloatFloat4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxFloat4FloatFloat4(inA, out);
+            verifyResultsMaxFloat4FloatFloat4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxFloat4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxFloat4FloatFloat4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMax(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    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");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMaxFloat4FloatFloat4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharCharChar {
+        public byte inA;
+        public byte inB;
+        public byte out;
+    }
+
+    private void checkMaxCharCharChar() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xb6405876l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xb6405877l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxCharCharChar(inA, out);
+            verifyResultsMaxCharCharChar(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxCharCharChar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxCharCharChar(inA, out);
+            verifyResultsMaxCharCharChar(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxCharCharChar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxCharCharChar(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMaxCharCharChar" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxChar2Char2Char2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x19e42804l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0x19e42805l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxChar2Char2Char2(inA, out);
+            verifyResultsMaxChar2Char2Char2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar2Char2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxChar2Char2Char2(inA, out);
+            verifyResultsMaxChar2Char2Char2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar2Char2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxChar2Char2Char2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxChar2Char2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxChar3Char3Char3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x788338d3l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x788338d4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxChar3Char3Char3(inA, out);
+            verifyResultsMaxChar3Char3Char3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar3Char3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxChar3Char3Char3(inA, out);
+            verifyResultsMaxChar3Char3Char3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar3Char3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxChar3Char3Char3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxChar3Char3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxChar4Char4Char4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd72249a2l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0xd72249a3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxChar4Char4Char4(inA, out);
+            verifyResultsMaxChar4Char4Char4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar4Char4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxChar4Char4Char4(inA, out);
+            verifyResultsMaxChar4Char4Char4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxChar4Char4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxChar4Char4Char4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxChar4Char4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharUcharUchar {
+        public byte inA;
+        public byte inB;
+        public byte out;
+    }
+
+    private void checkMaxUcharUcharUchar() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x853a162dl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x853a162el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUcharUcharUchar(inA, out);
+            verifyResultsMaxUcharUcharUchar(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUcharUcharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUcharUcharUchar(inA, out);
+            verifyResultsMaxUcharUcharUchar(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUcharUcharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUcharUcharUchar(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMaxUcharUcharUchar" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUchar2Uchar2Uchar2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xb7e9a9dbl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xb7e9a9dcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUchar2Uchar2Uchar2(inA, out);
+            verifyResultsMaxUchar2Uchar2Uchar2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar2Uchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUchar2Uchar2Uchar2(inA, out);
+            verifyResultsMaxUchar2Uchar2Uchar2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar2Uchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUchar2Uchar2Uchar2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUchar2Uchar2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUchar3Uchar3Uchar3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xb9c7ab7cl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xb9c7ab7dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUchar3Uchar3Uchar3(inA, out);
+            verifyResultsMaxUchar3Uchar3Uchar3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar3Uchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUchar3Uchar3Uchar3(inA, out);
+            verifyResultsMaxUchar3Uchar3Uchar3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar3Uchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUchar3Uchar3Uchar3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUchar3Uchar3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUchar4Uchar4Uchar4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xbba5ad1dl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xbba5ad1el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUchar4Uchar4Uchar4(inA, out);
+            verifyResultsMaxUchar4Uchar4Uchar4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar4Uchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUchar4Uchar4Uchar4(inA, out);
+            verifyResultsMaxUchar4Uchar4Uchar4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUchar4Uchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUchar4Uchar4Uchar4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUchar4Uchar4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortShortShort {
+        public short inA;
+        public short inB;
+        public short out;
+    }
+
+    private void checkMaxShortShortShort() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x43b57294l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0x43b57295l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxShortShortShort(inA, out);
+            verifyResultsMaxShortShortShort(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShortShortShort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxShortShortShort(inA, out);
+            verifyResultsMaxShortShortShort(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShortShortShort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxShortShortShort(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.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMaxShortShortShort" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxShort2Short2Short2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x56ecb9del, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x56ecb9dfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxShort2Short2Short2(inA, out);
+            verifyResultsMaxShort2Short2Short2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort2Short2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxShort2Short2Short2(inA, out);
+            verifyResultsMaxShort2Short2Short2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort2Short2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxShort2Short2Short2(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.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxShort2Short2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxShort3Short3Short3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x58cabb7fl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x58cabb80l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxShort3Short3Short3(inA, out);
+            verifyResultsMaxShort3Short3Short3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort3Short3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxShort3Short3Short3(inA, out);
+            verifyResultsMaxShort3Short3Short3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort3Short3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxShort3Short3Short3(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.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxShort3Short3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxShort4Short4Short4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x5aa8bd20l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x5aa8bd21l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxShort4Short4Short4(inA, out);
+            verifyResultsMaxShort4Short4Short4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort4Short4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxShort4Short4Short4(inA, out);
+            verifyResultsMaxShort4Short4Short4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxShort4Short4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxShort4Short4Short4(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.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxShort4Short4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortUshortUshort {
+        public short inA;
+        public short inB;
+        public short out;
+    }
+
+    private void checkMaxUshortUshortUshort() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xb947704bl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xb947704cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUshortUshortUshort(inA, out);
+            verifyResultsMaxUshortUshortUshort(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshortUshortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUshortUshortUshort(inA, out);
+            verifyResultsMaxUshortUshortUshort(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshortUshortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUshortUshortUshort(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.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMaxUshortUshortUshort" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUshort2Ushort2Ushort2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x150b1f95l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x150b1f96l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUshort2Ushort2Ushort2(inA, out);
+            verifyResultsMaxUshort2Ushort2Ushort2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort2Ushort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUshort2Ushort2Ushort2(inA, out);
+            verifyResultsMaxUshort2Ushort2Ushort2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort2Ushort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUshort2Ushort2Ushort2(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.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUshort2Ushort2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUshort3Ushort3Ushort3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x5df0112cl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0x5df0112dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUshort3Ushort3Ushort3(inA, out);
+            verifyResultsMaxUshort3Ushort3Ushort3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort3Ushort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUshort3Ushort3Ushort3(inA, out);
+            verifyResultsMaxUshort3Ushort3Ushort3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort3Ushort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUshort3Ushort3Ushort3(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.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUshort3Ushort3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUshort4Ushort4Ushort4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xa6d502c3l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0xa6d502c4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUshort4Ushort4Ushort4(inA, out);
+            verifyResultsMaxUshort4Ushort4Ushort4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort4Ushort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUshort4Ushort4Ushort4(inA, out);
+            verifyResultsMaxUshort4Ushort4Ushort4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUshort4Ushort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUshort4Ushort4Ushort4(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.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUshort4Ushort4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntIntInt {
+        public int inA;
+        public int inB;
+        public int out;
+    }
+
+    private void checkMaxIntIntInt() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xe43d0fa9l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xe43d0faal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxIntIntInt(inA, out);
+            verifyResultsMaxIntIntInt(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxIntIntInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxIntIntInt(inA, out);
+            verifyResultsMaxIntIntInt(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxIntIntInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxIntIntInt(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMaxIntIntInt" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxInt2Int2Int2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xbb9dccd7l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xbb9dccd8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxInt2Int2Int2(inA, out);
+            verifyResultsMaxInt2Int2Int2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt2Int2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxInt2Int2Int2(inA, out);
+            verifyResultsMaxInt2Int2Int2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt2Int2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxInt2Int2Int2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxInt2Int2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxInt3Int3Int3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x867314c0l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x867314c1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxInt3Int3Int3(inA, out);
+            verifyResultsMaxInt3Int3Int3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt3Int3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxInt3Int3Int3(inA, out);
+            verifyResultsMaxInt3Int3Int3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt3Int3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxInt3Int3Int3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxInt3Int3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxInt4Int4Int4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x51485ca9l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x51485caal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxInt4Int4Int4(inA, out);
+            verifyResultsMaxInt4Int4Int4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt4Int4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxInt4Int4Int4(inA, out);
+            verifyResultsMaxInt4Int4Int4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxInt4Int4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxInt4Int4Int4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxInt4Int4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintUintUint {
+        public int inA;
+        public int inB;
+        public int out;
+    }
+
+    private void checkMaxUintUintUint() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x85f73e36l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x85f73e37l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUintUintUint(inA, out);
+            verifyResultsMaxUintUintUint(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUintUintUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUintUintUint(inA, out);
+            verifyResultsMaxUintUintUint(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUintUintUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUintUintUint(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMaxUintUintUint" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUint2Uint2Uint2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xe84d6c4l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xe84d6c5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUint2Uint2Uint2(inA, out);
+            verifyResultsMaxUint2Uint2Uint2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint2Uint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUint2Uint2Uint2(inA, out);
+            verifyResultsMaxUint2Uint2Uint2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint2Uint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUint2Uint2Uint2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUint2Uint2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUint3Uint3Uint3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x6d23e793l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x6d23e794l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUint3Uint3Uint3(inA, out);
+            verifyResultsMaxUint3Uint3Uint3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint3Uint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUint3Uint3Uint3(inA, out);
+            verifyResultsMaxUint3Uint3Uint3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint3Uint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUint3Uint3Uint3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUint3Uint3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUint4Uint4Uint4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xcbc2f862l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0xcbc2f863l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUint4Uint4Uint4(inA, out);
+            verifyResultsMaxUint4Uint4Uint4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint4Uint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUint4Uint4Uint4(inA, out);
+            verifyResultsMaxUint4Uint4Uint4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUint4Uint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUint4Uint4Uint4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUint4Uint4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongLongLong {
+        public long inA;
+        public long inB;
+        public long out;
+    }
+
+    private void checkMaxLongLongLong() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x85eceb84l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0x85eceb85l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxLongLongLong(inA, out);
+            verifyResultsMaxLongLongLong(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLongLongLong: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxLongLongLong(inA, out);
+            verifyResultsMaxLongLongLong(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLongLongLong: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxLongLongLong(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        long[] arrayOut = new long[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMaxLongLongLong" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxLong2Long2Long2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xc249c9dal, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0xc249c9dbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxLong2Long2Long2(inA, out);
+            verifyResultsMaxLong2Long2Long2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong2Long2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxLong2Long2Long2(inA, out);
+            verifyResultsMaxLong2Long2Long2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong2Long2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxLong2Long2Long2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxLong2Long2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxLong3Long3Long3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x20e8daa9l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0x20e8daaal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxLong3Long3Long3(inA, out);
+            verifyResultsMaxLong3Long3Long3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong3Long3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxLong3Long3Long3(inA, out);
+            verifyResultsMaxLong3Long3Long3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong3Long3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxLong3Long3Long3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxLong3Long3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxLong4Long4Long4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x7f87eb78l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x7f87eb79l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxLong4Long4Long4(inA, out);
+            verifyResultsMaxLong4Long4Long4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong4Long4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxLong4Long4Long4(inA, out);
+            verifyResultsMaxLong4Long4Long4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxLong4Long4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxLong4Long4Long4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxLong4Long4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongUlongUlong {
+        public long inA;
+        public long inB;
+        public long out;
+    }
+
+    private void checkMaxUlongUlongUlong() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x8f18baafl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x8f18bab0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUlongUlongUlong(inA, out);
+            verifyResultsMaxUlongUlongUlong(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlongUlongUlong: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUlongUlongUlong(inA, out);
+            verifyResultsMaxUlongUlongUlong(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlongUlongUlong: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUlongUlongUlong(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        long[] arrayOut = new long[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMaxUlongUlongUlong" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUlong2Ulong2Ulong2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x5946bc65l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x5946bc66l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUlong2Ulong2Ulong2(inA, out);
+            verifyResultsMaxUlong2Ulong2Ulong2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong2Ulong2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUlong2Ulong2Ulong2(inA, out);
+            verifyResultsMaxUlong2Ulong2Ulong2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong2Ulong2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUlong2Ulong2Ulong2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUlong2Ulong2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUlong3Ulong3Ulong3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x5b24be06l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x5b24be07l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUlong3Ulong3Ulong3(inA, out);
+            verifyResultsMaxUlong3Ulong3Ulong3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong3Ulong3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUlong3Ulong3Ulong3(inA, out);
+            verifyResultsMaxUlong3Ulong3Ulong3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong3Ulong3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUlong3Ulong3Ulong3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUlong3Ulong3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMaxUlong4Ulong4Ulong4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x5d02bfa7l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x5d02bfa8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMaxUlong4Ulong4Ulong4(inA, out);
+            verifyResultsMaxUlong4Ulong4Ulong4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong4Ulong4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMaxUlong4Ulong4Ulong4(inA, out);
+            verifyResultsMaxUlong4Ulong4Ulong4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMaxUlong4Ulong4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMaxUlong4Ulong4Ulong4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMax(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 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 != 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 checkMaxUlong4Ulong4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testMax() {
+        checkMaxFloatFloatFloat();
+        checkMaxFloat2Float2Float2();
+        checkMaxFloat3Float3Float3();
+        checkMaxFloat4Float4Float4();
+        checkMaxFloat2FloatFloat2();
+        checkMaxFloat3FloatFloat3();
+        checkMaxFloat4FloatFloat4();
+        checkMaxCharCharChar();
+        checkMaxChar2Char2Char2();
+        checkMaxChar3Char3Char3();
+        checkMaxChar4Char4Char4();
+        checkMaxUcharUcharUchar();
+        checkMaxUchar2Uchar2Uchar2();
+        checkMaxUchar3Uchar3Uchar3();
+        checkMaxUchar4Uchar4Uchar4();
+        checkMaxShortShortShort();
+        checkMaxShort2Short2Short2();
+        checkMaxShort3Short3Short3();
+        checkMaxShort4Short4Short4();
+        checkMaxUshortUshortUshort();
+        checkMaxUshort2Ushort2Ushort2();
+        checkMaxUshort3Ushort3Ushort3();
+        checkMaxUshort4Ushort4Ushort4();
+        checkMaxIntIntInt();
+        checkMaxInt2Int2Int2();
+        checkMaxInt3Int3Int3();
+        checkMaxInt4Int4Int4();
+        checkMaxUintUintUint();
+        checkMaxUint2Uint2Uint2();
+        checkMaxUint3Uint3Uint3();
+        checkMaxUint4Uint4Uint4();
+        checkMaxLongLongLong();
+        checkMaxLong2Long2Long2();
+        checkMaxLong3Long3Long3();
+        checkMaxLong4Long4Long4();
+        checkMaxUlongUlongUlong();
+        checkMaxUlong2Ulong2Ulong2();
+        checkMaxUlong3Ulong3Ulong3();
+        checkMaxUlong4Ulong4Ulong4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.rs
new file mode 100644
index 0000000..a9ca895
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMax.rs
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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)
+
+rs_allocation gAllocInB;
+
+float __attribute__((kernel)) testMaxFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return max(inA, inB);
+}
+
+float2 __attribute__((kernel)) testMaxFloat2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+float3 __attribute__((kernel)) testMaxFloat3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+float4 __attribute__((kernel)) testMaxFloat4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(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);
+}
+
+float3 __attribute__((kernel)) testMaxFloat3FloatFloat3(float3 inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return max(inA, inB);
+}
+
+float4 __attribute__((kernel)) testMaxFloat4FloatFloat4(float4 inA, unsigned int x) {
+    float inB = rsGetElementAt_float(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);
+}
+
+char2 __attribute__((kernel)) testMaxChar2Char2Char2(char2 inA, unsigned int x) {
+    char2 inB = rsGetElementAt_char2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+char3 __attribute__((kernel)) testMaxChar3Char3Char3(char3 inA, unsigned int x) {
+    char3 inB = rsGetElementAt_char3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+char4 __attribute__((kernel)) testMaxChar4Char4Char4(char4 inA, unsigned int x) {
+    char4 inB = rsGetElementAt_char4(gAllocInB, x);
+    return max(inA, inB);
+}
+
+uchar __attribute__((kernel)) testMaxUcharUcharUchar(uchar inA, unsigned int x) {
+    uchar inB = rsGetElementAt_uchar(gAllocInB, x);
+    return max(inA, inB);
+}
+
+uchar2 __attribute__((kernel)) testMaxUchar2Uchar2Uchar2(uchar2 inA, unsigned int x) {
+    uchar2 inB = rsGetElementAt_uchar2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+uchar3 __attribute__((kernel)) testMaxUchar3Uchar3Uchar3(uchar3 inA, unsigned int x) {
+    uchar3 inB = rsGetElementAt_uchar3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+uchar4 __attribute__((kernel)) testMaxUchar4Uchar4Uchar4(uchar4 inA, unsigned int x) {
+    uchar4 inB = rsGetElementAt_uchar4(gAllocInB, x);
+    return max(inA, inB);
+}
+
+short __attribute__((kernel)) testMaxShortShortShort(short inA, unsigned int x) {
+    short inB = rsGetElementAt_short(gAllocInB, x);
+    return max(inA, inB);
+}
+
+short2 __attribute__((kernel)) testMaxShort2Short2Short2(short2 inA, unsigned int x) {
+    short2 inB = rsGetElementAt_short2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+short3 __attribute__((kernel)) testMaxShort3Short3Short3(short3 inA, unsigned int x) {
+    short3 inB = rsGetElementAt_short3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+short4 __attribute__((kernel)) testMaxShort4Short4Short4(short4 inA, unsigned int x) {
+    short4 inB = rsGetElementAt_short4(gAllocInB, x);
+    return max(inA, inB);
+}
+
+ushort __attribute__((kernel)) testMaxUshortUshortUshort(ushort inA, unsigned int x) {
+    ushort inB = rsGetElementAt_ushort(gAllocInB, x);
+    return max(inA, inB);
+}
+
+ushort2 __attribute__((kernel)) testMaxUshort2Ushort2Ushort2(ushort2 inA, unsigned int x) {
+    ushort2 inB = rsGetElementAt_ushort2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+ushort3 __attribute__((kernel)) testMaxUshort3Ushort3Ushort3(ushort3 inA, unsigned int x) {
+    ushort3 inB = rsGetElementAt_ushort3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+ushort4 __attribute__((kernel)) testMaxUshort4Ushort4Ushort4(ushort4 inA, unsigned int x) {
+    ushort4 inB = rsGetElementAt_ushort4(gAllocInB, x);
+    return max(inA, inB);
+}
+
+int __attribute__((kernel)) testMaxIntIntInt(int inA, unsigned int x) {
+    int inB = rsGetElementAt_int(gAllocInB, x);
+    return max(inA, inB);
+}
+
+int2 __attribute__((kernel)) testMaxInt2Int2Int2(int2 inA, unsigned int x) {
+    int2 inB = rsGetElementAt_int2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+int3 __attribute__((kernel)) testMaxInt3Int3Int3(int3 inA, unsigned int x) {
+    int3 inB = rsGetElementAt_int3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+int4 __attribute__((kernel)) testMaxInt4Int4Int4(int4 inA, unsigned int x) {
+    int4 inB = rsGetElementAt_int4(gAllocInB, x);
+    return max(inA, inB);
+}
+
+uint __attribute__((kernel)) testMaxUintUintUint(uint inA, unsigned int x) {
+    uint inB = rsGetElementAt_uint(gAllocInB, x);
+    return max(inA, inB);
+}
+
+uint2 __attribute__((kernel)) testMaxUint2Uint2Uint2(uint2 inA, unsigned int x) {
+    uint2 inB = rsGetElementAt_uint2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+uint3 __attribute__((kernel)) testMaxUint3Uint3Uint3(uint3 inA, unsigned int x) {
+    uint3 inB = rsGetElementAt_uint3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+uint4 __attribute__((kernel)) testMaxUint4Uint4Uint4(uint4 inA, unsigned int x) {
+    uint4 inB = rsGetElementAt_uint4(gAllocInB, x);
+    return max(inA, inB);
+}
+
+long __attribute__((kernel)) testMaxLongLongLong(long inA, unsigned int x) {
+    long inB = rsGetElementAt_long(gAllocInB, x);
+    return max(inA, inB);
+}
+
+long2 __attribute__((kernel)) testMaxLong2Long2Long2(long2 inA, unsigned int x) {
+    long2 inB = rsGetElementAt_long2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+long3 __attribute__((kernel)) testMaxLong3Long3Long3(long3 inA, unsigned int x) {
+    long3 inB = rsGetElementAt_long3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+long4 __attribute__((kernel)) testMaxLong4Long4Long4(long4 inA, unsigned int x) {
+    long4 inB = rsGetElementAt_long4(gAllocInB, x);
+    return max(inA, inB);
+}
+
+ulong __attribute__((kernel)) testMaxUlongUlongUlong(ulong inA, unsigned int x) {
+    ulong inB = rsGetElementAt_ulong(gAllocInB, x);
+    return max(inA, inB);
+}
+
+ulong2 __attribute__((kernel)) testMaxUlong2Ulong2Ulong2(ulong2 inA, unsigned int x) {
+    ulong2 inB = rsGetElementAt_ulong2(gAllocInB, x);
+    return max(inA, inB);
+}
+
+ulong3 __attribute__((kernel)) testMaxUlong3Ulong3Ulong3(ulong3 inA, unsigned int x) {
+    ulong3 inB = rsGetElementAt_ulong3(gAllocInB, x);
+    return max(inA, inB);
+}
+
+ulong4 __attribute__((kernel)) testMaxUlong4Ulong4Ulong4(ulong4 inA, unsigned int x) {
+    ulong4 inB = rsGetElementAt_ulong4(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
new file mode 100644
index 0000000..2f3fecc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMaxRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestMax.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.java
new file mode 100644
index 0000000..f71fac8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.java
@@ -0,0 +1,3144 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestMin extends RSBaseCompute {
+
+    private ScriptC_TestMin script;
+    private ScriptC_TestMinRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestMin(mRS);
+        scriptRelaxed = new ScriptC_TestMinRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public Target.Floaty out;
+    }
+
+    private void checkMinFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7121573el, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7121573fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinFloatFloatFloat(inA, out);
+            verifyResultsMinFloatFloatFloat(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinFloatFloatFloat(inA, out);
+            verifyResultsMinFloatFloatFloat(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloatFloatFloat(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        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 * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkMinFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinFloat2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x49b4e454l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x49b4e455l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinFloat2Float2Float2(inA, out);
+            verifyResultsMinFloat2Float2Float2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinFloat2Float2Float2(inA, out);
+            verifyResultsMinFloat2Float2Float2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloat2Float2Float2(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 * 2];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeMin(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinFloat3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4b92e5f5l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4b92e5f6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinFloat3Float3Float3(inA, out);
+            verifyResultsMinFloat3Float3Float3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinFloat3Float3Float3(inA, out);
+            verifyResultsMinFloat3Float3Float3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloat3Float3Float3(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeMin(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinFloat4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4d70e796l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4d70e797l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinFloat4Float4Float4(inA, out);
+            verifyResultsMinFloat4Float4Float4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinFloat4Float4Float4(inA, out);
+            verifyResultsMinFloat4Float4Float4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloat4Float4Float4(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeMin(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkMinFloat4Float4Float4" +
+                (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);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinFloat2FloatFloat2(inA, out);
+            verifyResultsMinFloat2FloatFloat2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinFloat2FloatFloat2(inA, out);
+            verifyResultsMinFloat2FloatFloat2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloat2FloatFloat2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 2];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 2];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 2 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j])) {
+                    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");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinFloat2FloatFloat2" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinFloat3FloatFloat3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3ea67e02l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3ea67e03l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinFloat3FloatFloat3(inA, out);
+            verifyResultsMinFloat3FloatFloat3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinFloat3FloatFloat3(inA, out);
+            verifyResultsMinFloat3FloatFloat3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloat3FloatFloat3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 3 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    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");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinFloat3FloatFloat3" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    private void checkMinFloat4FloatFloat4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2d11725el, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2d11725fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinFloat4FloatFloat4(inA, out);
+            verifyResultsMinFloat4FloatFloat4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinFloat4FloatFloat4(inA, out);
+            verifyResultsMinFloat4FloatFloat4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinFloat4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinFloat4FloatFloat4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 4];
+        inA.copyTo(arrayInA);
+        float[] arrayInB = new float[INPUTSIZE * 1];
+        inB.copyTo(arrayInB);
+        float[] arrayOut = new float[INPUTSIZE * 4];
+        out.copyTo(arrayOut);
+        for (int i = 0; i < INPUTSIZE; i++) {
+            for (int j = 0; j < 4 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j])) {
+                    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");
+                    }
+                    message.append("\n");
+                    assertTrue("Incorrect output for checkMinFloat4FloatFloat4" +
+                            (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), valid);
+                }
+            }
+        }
+    }
+
+    public class ArgumentsCharCharChar {
+        public byte inA;
+        public byte inB;
+        public byte out;
+    }
+
+    private void checkMinCharCharChar() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xe8196e0l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 1, 0xe8196e1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinCharCharChar(inA, out);
+            verifyResultsMinCharCharChar(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinCharCharChar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinCharCharChar(inA, out);
+            verifyResultsMinCharCharChar(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinCharCharChar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinCharCharChar(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMinCharCharChar" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinChar2Char2Char2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xc8ef5ae2l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 2, 0xc8ef5ae3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinChar2Char2Char2(inA, out);
+            verifyResultsMinChar2Char2Char2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar2Char2Char2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinChar2Char2Char2(inA, out);
+            verifyResultsMinChar2Char2Char2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar2Char2Char2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinChar2Char2Char2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinChar2Char2Char2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinChar3Char3Char3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x278e6bb1l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 3, 0x278e6bb2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinChar3Char3Char3(inA, out);
+            verifyResultsMinChar3Char3Char3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar3Char3Char3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinChar3Char3Char3(inA, out);
+            verifyResultsMinChar3Char3Char3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar3Char3Char3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinChar3Char3Char3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinChar3Char3Char3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinChar4Char4Char4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x862d7c80l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_8, 4, 0x862d7c81l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinChar4Char4Char4(inA, out);
+            verifyResultsMinChar4Char4Char4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar4Char4Char4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinChar4Char4Char4(inA, out);
+            verifyResultsMinChar4Char4Char4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinChar4Char4Char4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinChar4Char4Char4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsCharCharChar args = new ArgumentsCharCharChar();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinChar4Char4Char4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUcharUcharUchar {
+        public byte inA;
+        public byte inB;
+        public byte out;
+    }
+
+    private void checkMinUcharUcharUchar() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x3445490bl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 1, 0x3445490cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUcharUcharUchar(inA, out);
+            verifyResultsMinUcharUcharUchar(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUcharUcharUchar: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUcharUcharUchar(inA, out);
+            verifyResultsMinUcharUcharUchar(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUcharUcharUchar: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUcharUcharUchar(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        byte[] arrayOut = new byte[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMinUcharUcharUchar" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUchar2Uchar2Uchar2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xcaf0b355l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 2, 0xcaf0b356l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUchar2Uchar2Uchar2(inA, out);
+            verifyResultsMinUchar2Uchar2Uchar2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar2Uchar2Uchar2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUchar2Uchar2Uchar2(inA, out);
+            verifyResultsMinUchar2Uchar2Uchar2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar2Uchar2Uchar2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUchar2Uchar2Uchar2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUchar2Uchar2Uchar2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUchar3Uchar3Uchar3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xccceb4f6l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 3, 0xccceb4f7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUchar3Uchar3Uchar3(inA, out);
+            verifyResultsMinUchar3Uchar3Uchar3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar3Uchar3Uchar3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUchar3Uchar3Uchar3(inA, out);
+            verifyResultsMinUchar3Uchar3Uchar3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar3Uchar3Uchar3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUchar3Uchar3Uchar3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUchar3Uchar3Uchar3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUchar4Uchar4Uchar4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xceacb697l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_8, 4, 0xceacb698l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUchar4Uchar4Uchar4(inA, out);
+            verifyResultsMinUchar4Uchar4Uchar4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar4Uchar4Uchar4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_8, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUchar4Uchar4Uchar4(inA, out);
+            verifyResultsMinUchar4Uchar4Uchar4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUchar4Uchar4Uchar4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUchar4Uchar4Uchar4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        byte[] arrayInA = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (byte) 42);
+        inA.copyTo(arrayInA);
+        byte[] arrayInB = new byte[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (byte) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUcharUcharUchar args = new ArgumentsUcharUcharUchar();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUchar4Uchar4Uchar4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsShortShortShort {
+        public short inA;
+        public short inB;
+        public short out;
+    }
+
+    private void checkMinShortShortShort() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xf2c0a572l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 1, 0xf2c0a573l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinShortShortShort(inA, out);
+            verifyResultsMinShortShortShort(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShortShortShort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinShortShortShort(inA, out);
+            verifyResultsMinShortShortShort(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShortShortShort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinShortShortShort(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.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMinShortShortShort" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinShort2Short2Short2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x69f3c358l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 2, 0x69f3c359l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinShort2Short2Short2(inA, out);
+            verifyResultsMinShort2Short2Short2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort2Short2Short2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinShort2Short2Short2(inA, out);
+            verifyResultsMinShort2Short2Short2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort2Short2Short2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinShort2Short2Short2(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.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinShort2Short2Short2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinShort3Short3Short3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x6bd1c4f9l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 3, 0x6bd1c4fal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinShort3Short3Short3(inA, out);
+            verifyResultsMinShort3Short3Short3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort3Short3Short3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinShort3Short3Short3(inA, out);
+            verifyResultsMinShort3Short3Short3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort3Short3Short3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinShort3Short3Short3(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.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinShort3Short3Short3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinShort4Short4Short4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x6dafc69al, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_16, 4, 0x6dafc69bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinShort4Short4Short4(inA, out);
+            verifyResultsMinShort4Short4Short4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort4Short4Short4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinShort4Short4Short4(inA, out);
+            verifyResultsMinShort4Short4Short4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinShort4Short4Short4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinShort4Short4Short4(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.
+                ArgumentsShortShortShort args = new ArgumentsShortShortShort();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinShort4Short4Short4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUshortUshortUshort {
+        public short inA;
+        public short inB;
+        public short out;
+    }
+
+    private void checkMinUshortUshortUshort() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xcc4e79c5l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 1, 0xcc4e79c6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUshortUshortUshort(inA, out);
+            verifyResultsMinUshortUshortUshort(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshortUshortUshort: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUshortUshortUshort(inA, out);
+            verifyResultsMinUshortUshortUshort(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshortUshortUshort: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUshortUshortUshort(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.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMinUshortUshortUshort" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUshort2Ushort2Ushort2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x878f4ca3l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 2, 0x878f4ca4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUshort2Ushort2Ushort2(inA, out);
+            verifyResultsMinUshort2Ushort2Ushort2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort2Ushort2Ushort2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUshort2Ushort2Ushort2(inA, out);
+            verifyResultsMinUshort2Ushort2Ushort2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort2Ushort2Ushort2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUshort2Ushort2Ushort2(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.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUshort2Ushort2Ushort2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUshort3Ushort3Ushort3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xd0743e3al, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 3, 0xd0743e3bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUshort3Ushort3Ushort3(inA, out);
+            verifyResultsMinUshort3Ushort3Ushort3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort3Ushort3Ushort3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUshort3Ushort3Ushort3(inA, out);
+            verifyResultsMinUshort3Ushort3Ushort3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort3Ushort3Ushort3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUshort3Ushort3Ushort3(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.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUshort3Ushort3Ushort3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUshort4Ushort4Ushort4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x19592fd1l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_16, 4, 0x19592fd2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUshort4Ushort4Ushort4(inA, out);
+            verifyResultsMinUshort4Ushort4Ushort4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort4Ushort4Ushort4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_16, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUshort4Ushort4Ushort4(inA, out);
+            verifyResultsMinUshort4Ushort4Ushort4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUshort4Ushort4Ushort4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUshort4Ushort4Ushort4(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.
+                ArgumentsUshortUshortUshort args = new ArgumentsUshortUshortUshort();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUshort4Ushort4Ushort4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsIntIntInt {
+        public int inA;
+        public int inB;
+        public int out;
+    }
+
+    private void checkMinIntIntInt() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xe703dfd7l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0xe703dfd8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinIntIntInt(inA, out);
+            verifyResultsMinIntIntInt(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinIntIntInt: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinIntIntInt(inA, out);
+            verifyResultsMinIntIntInt(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinIntIntInt: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinIntIntInt(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMinIntIntInt" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinInt2Int2Int2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x13df0b41l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x13df0b42l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinInt2Int2Int2(inA, out);
+            verifyResultsMinInt2Int2Int2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt2Int2Int2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinInt2Int2Int2(inA, out);
+            verifyResultsMinInt2Int2Int2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt2Int2Int2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinInt2Int2Int2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinInt2Int2Int2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinInt3Int3Int3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xdeb4532al, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xdeb4532bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinInt3Int3Int3(inA, out);
+            verifyResultsMinInt3Int3Int3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt3Int3Int3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinInt3Int3Int3(inA, out);
+            verifyResultsMinInt3Int3Int3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt3Int3Int3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinInt3Int3Int3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinInt3Int3Int3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinInt4Int4Int4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xa9899b13l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xa9899b14l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinInt4Int4Int4(inA, out);
+            verifyResultsMinInt4Int4Int4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt4Int4Int4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinInt4Int4Int4(inA, out);
+            verifyResultsMinInt4Int4Int4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinInt4Int4Int4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinInt4Int4Int4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsIntIntInt args = new ArgumentsIntIntInt();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinInt4Int4Int4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUintUintUint {
+        public int inA;
+        public int inB;
+        public int out;
+    }
+
+    private void checkMinUintUintUint() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xde387ca0l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0xde387ca1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUintUintUint(inA, out);
+            verifyResultsMinUintUintUint(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUintUintUint: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUintUintUint(inA, out);
+            verifyResultsMinUintUintUint(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUintUintUint: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUintUintUint(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        int[] arrayOut = new int[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMinUintUintUint" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUint2Uint2Uint2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xbd9009a2l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 2, 0xbd9009a3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUint2Uint2Uint2(inA, out);
+            verifyResultsMinUint2Uint2Uint2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint2Uint2Uint2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUint2Uint2Uint2(inA, out);
+            verifyResultsMinUint2Uint2Uint2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint2Uint2Uint2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUint2Uint2Uint2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUint2Uint2Uint2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUint3Uint3Uint3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x1c2f1a71l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 3, 0x1c2f1a72l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUint3Uint3Uint3(inA, out);
+            verifyResultsMinUint3Uint3Uint3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint3Uint3Uint3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUint3Uint3Uint3(inA, out);
+            verifyResultsMinUint3Uint3Uint3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint3Uint3Uint3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUint3Uint3Uint3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUint3Uint3Uint3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUint4Uint4Uint4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x7ace2b40l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 4, 0x7ace2b41l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUint4Uint4Uint4(inA, out);
+            verifyResultsMinUint4Uint4Uint4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint4Uint4Uint4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUint4Uint4Uint4(inA, out);
+            verifyResultsMinUint4Uint4Uint4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUint4Uint4Uint4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUint4Uint4Uint4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        int[] arrayInA = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (int) 42);
+        inA.copyTo(arrayInA);
+        int[] arrayInB = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (int) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUintUintUint args = new ArgumentsUintUintUint();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUint4Uint4Uint4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsLongLongLong {
+        public long inA;
+        public long inB;
+        public long out;
+    }
+
+    private void checkMinLongLongLong() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0xde2e29eel, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 1, 0xde2e29efl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinLongLongLong(inA, out);
+            verifyResultsMinLongLongLong(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLongLongLong: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinLongLongLong(inA, out);
+            verifyResultsMinLongLongLong(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLongLongLong: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinLongLongLong(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        long[] arrayOut = new long[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMinLongLongLong" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinLong2Long2Long2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x7154fcb8l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 2, 0x7154fcb9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinLong2Long2Long2(inA, out);
+            verifyResultsMinLong2Long2Long2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong2Long2Long2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinLong2Long2Long2(inA, out);
+            verifyResultsMinLong2Long2Long2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong2Long2Long2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinLong2Long2Long2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinLong2Long2Long2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinLong3Long3Long3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xcff40d87l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 3, 0xcff40d88l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinLong3Long3Long3(inA, out);
+            verifyResultsMinLong3Long3Long3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong3Long3Long3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinLong3Long3Long3(inA, out);
+            verifyResultsMinLong3Long3Long3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong3Long3Long3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinLong3Long3Long3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinLong3Long3Long3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinLong4Long4Long4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x2e931e56l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.SIGNED_64, 4, 0x2e931e57l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinLong4Long4Long4(inA, out);
+            verifyResultsMinLong4Long4Long4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong4Long4Long4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinLong4Long4Long4(inA, out);
+            verifyResultsMinLong4Long4Long4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinLong4Long4Long4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinLong4Long4Long4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsLongLongLong args = new ArgumentsLongLongLong();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinLong4Long4Long4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsUlongUlongUlong {
+        public long inA;
+        public long inB;
+        public long out;
+    }
+
+    private void checkMinUlongUlongUlong() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x3e23ed8dl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 1, 0x3e23ed8el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUlongUlongUlong(inA, out);
+            verifyResultsMinUlongUlongUlong(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlongUlongUlong: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUlongUlongUlong(inA, out);
+            verifyResultsMinUlongUlongUlong(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlongUlongUlong: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUlongUlongUlong(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 1];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        long[] arrayOut = new long[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(args);
+                // Validate the outputs.
+                boolean valid = true;
+                if (args.out != 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]);
+                        if (args.out != 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 checkMinUlongUlongUlong" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUlong2Ulong2Ulong2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x6c4dc5dfl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 2, 0x6c4dc5e0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUlong2Ulong2Ulong2(inA, out);
+            verifyResultsMinUlong2Ulong2Ulong2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong2Ulong2Ulong2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUlong2Ulong2Ulong2(inA, out);
+            verifyResultsMinUlong2Ulong2Ulong2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong2Ulong2Ulong2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUlong2Ulong2Ulong2(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 2];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
+                args.inA = arrayInA[i * 2 + j];
+                args.inB = arrayInB[i * 2 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUlong2Ulong2Ulong2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUlong3Ulong3Ulong3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x6e2bc780l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 3, 0x6e2bc781l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUlong3Ulong3Ulong3(inA, out);
+            verifyResultsMinUlong3Ulong3Ulong3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong3Ulong3Ulong3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUlong3Ulong3Ulong3(inA, out);
+            verifyResultsMinUlong3Ulong3Ulong3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong3Ulong3Ulong3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUlong3Ulong3Ulong3(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUlong3Ulong3Ulong3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMinUlong4Ulong4Ulong4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x7009c921l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.UNSIGNED_64, 4, 0x7009c922l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testMinUlong4Ulong4Ulong4(inA, out);
+            verifyResultsMinUlong4Ulong4Ulong4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong4Ulong4Ulong4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.UNSIGNED_64, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testMinUlong4Ulong4Ulong4(inA, out);
+            verifyResultsMinUlong4Ulong4Ulong4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMinUlong4Ulong4Ulong4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMinUlong4Ulong4Ulong4(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        long[] arrayInA = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInA, (long) 42);
+        inA.copyTo(arrayInA);
+        long[] arrayInB = new long[INPUTSIZE * 4];
+        Arrays.fill(arrayInB, (long) 42);
+        inB.copyTo(arrayInB);
+        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.
+                ArgumentsUlongUlongUlong args = new ArgumentsUlongUlongUlong();
+                args.inA = arrayInA[i * 4 + j];
+                args.inB = arrayInB[i * 4 + j];
+                // Figure out what the outputs should have been.
+                CoreMathVerifier.computeMin(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 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 != 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 checkMinUlong4Ulong4Ulong4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testMin() {
+        checkMinFloatFloatFloat();
+        checkMinFloat2Float2Float2();
+        checkMinFloat3Float3Float3();
+        checkMinFloat4Float4Float4();
+        checkMinFloat2FloatFloat2();
+        checkMinFloat3FloatFloat3();
+        checkMinFloat4FloatFloat4();
+        checkMinCharCharChar();
+        checkMinChar2Char2Char2();
+        checkMinChar3Char3Char3();
+        checkMinChar4Char4Char4();
+        checkMinUcharUcharUchar();
+        checkMinUchar2Uchar2Uchar2();
+        checkMinUchar3Uchar3Uchar3();
+        checkMinUchar4Uchar4Uchar4();
+        checkMinShortShortShort();
+        checkMinShort2Short2Short2();
+        checkMinShort3Short3Short3();
+        checkMinShort4Short4Short4();
+        checkMinUshortUshortUshort();
+        checkMinUshort2Ushort2Ushort2();
+        checkMinUshort3Ushort3Ushort3();
+        checkMinUshort4Ushort4Ushort4();
+        checkMinIntIntInt();
+        checkMinInt2Int2Int2();
+        checkMinInt3Int3Int3();
+        checkMinInt4Int4Int4();
+        checkMinUintUintUint();
+        checkMinUint2Uint2Uint2();
+        checkMinUint3Uint3Uint3();
+        checkMinUint4Uint4Uint4();
+        checkMinLongLongLong();
+        checkMinLong2Long2Long2();
+        checkMinLong3Long3Long3();
+        checkMinLong4Long4Long4();
+        checkMinUlongUlongUlong();
+        checkMinUlong2Ulong2Ulong2();
+        checkMinUlong3Ulong3Ulong3();
+        checkMinUlong4Ulong4Ulong4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.rs
new file mode 100644
index 0000000..dccff70
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMin.rs
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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)
+
+rs_allocation gAllocInB;
+
+float __attribute__((kernel)) testMinFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return min(inA, inB);
+}
+
+float2 __attribute__((kernel)) testMinFloat2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+float3 __attribute__((kernel)) testMinFloat3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+float4 __attribute__((kernel)) testMinFloat4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(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);
+}
+
+float3 __attribute__((kernel)) testMinFloat3FloatFloat3(float3 inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return min(inA, inB);
+}
+
+float4 __attribute__((kernel)) testMinFloat4FloatFloat4(float4 inA, unsigned int x) {
+    float inB = rsGetElementAt_float(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);
+}
+
+char2 __attribute__((kernel)) testMinChar2Char2Char2(char2 inA, unsigned int x) {
+    char2 inB = rsGetElementAt_char2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+char3 __attribute__((kernel)) testMinChar3Char3Char3(char3 inA, unsigned int x) {
+    char3 inB = rsGetElementAt_char3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+char4 __attribute__((kernel)) testMinChar4Char4Char4(char4 inA, unsigned int x) {
+    char4 inB = rsGetElementAt_char4(gAllocInB, x);
+    return min(inA, inB);
+}
+
+uchar __attribute__((kernel)) testMinUcharUcharUchar(uchar inA, unsigned int x) {
+    uchar inB = rsGetElementAt_uchar(gAllocInB, x);
+    return min(inA, inB);
+}
+
+uchar2 __attribute__((kernel)) testMinUchar2Uchar2Uchar2(uchar2 inA, unsigned int x) {
+    uchar2 inB = rsGetElementAt_uchar2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+uchar3 __attribute__((kernel)) testMinUchar3Uchar3Uchar3(uchar3 inA, unsigned int x) {
+    uchar3 inB = rsGetElementAt_uchar3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+uchar4 __attribute__((kernel)) testMinUchar4Uchar4Uchar4(uchar4 inA, unsigned int x) {
+    uchar4 inB = rsGetElementAt_uchar4(gAllocInB, x);
+    return min(inA, inB);
+}
+
+short __attribute__((kernel)) testMinShortShortShort(short inA, unsigned int x) {
+    short inB = rsGetElementAt_short(gAllocInB, x);
+    return min(inA, inB);
+}
+
+short2 __attribute__((kernel)) testMinShort2Short2Short2(short2 inA, unsigned int x) {
+    short2 inB = rsGetElementAt_short2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+short3 __attribute__((kernel)) testMinShort3Short3Short3(short3 inA, unsigned int x) {
+    short3 inB = rsGetElementAt_short3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+short4 __attribute__((kernel)) testMinShort4Short4Short4(short4 inA, unsigned int x) {
+    short4 inB = rsGetElementAt_short4(gAllocInB, x);
+    return min(inA, inB);
+}
+
+ushort __attribute__((kernel)) testMinUshortUshortUshort(ushort inA, unsigned int x) {
+    ushort inB = rsGetElementAt_ushort(gAllocInB, x);
+    return min(inA, inB);
+}
+
+ushort2 __attribute__((kernel)) testMinUshort2Ushort2Ushort2(ushort2 inA, unsigned int x) {
+    ushort2 inB = rsGetElementAt_ushort2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+ushort3 __attribute__((kernel)) testMinUshort3Ushort3Ushort3(ushort3 inA, unsigned int x) {
+    ushort3 inB = rsGetElementAt_ushort3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+ushort4 __attribute__((kernel)) testMinUshort4Ushort4Ushort4(ushort4 inA, unsigned int x) {
+    ushort4 inB = rsGetElementAt_ushort4(gAllocInB, x);
+    return min(inA, inB);
+}
+
+int __attribute__((kernel)) testMinIntIntInt(int inA, unsigned int x) {
+    int inB = rsGetElementAt_int(gAllocInB, x);
+    return min(inA, inB);
+}
+
+int2 __attribute__((kernel)) testMinInt2Int2Int2(int2 inA, unsigned int x) {
+    int2 inB = rsGetElementAt_int2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+int3 __attribute__((kernel)) testMinInt3Int3Int3(int3 inA, unsigned int x) {
+    int3 inB = rsGetElementAt_int3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+int4 __attribute__((kernel)) testMinInt4Int4Int4(int4 inA, unsigned int x) {
+    int4 inB = rsGetElementAt_int4(gAllocInB, x);
+    return min(inA, inB);
+}
+
+uint __attribute__((kernel)) testMinUintUintUint(uint inA, unsigned int x) {
+    uint inB = rsGetElementAt_uint(gAllocInB, x);
+    return min(inA, inB);
+}
+
+uint2 __attribute__((kernel)) testMinUint2Uint2Uint2(uint2 inA, unsigned int x) {
+    uint2 inB = rsGetElementAt_uint2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+uint3 __attribute__((kernel)) testMinUint3Uint3Uint3(uint3 inA, unsigned int x) {
+    uint3 inB = rsGetElementAt_uint3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+uint4 __attribute__((kernel)) testMinUint4Uint4Uint4(uint4 inA, unsigned int x) {
+    uint4 inB = rsGetElementAt_uint4(gAllocInB, x);
+    return min(inA, inB);
+}
+
+long __attribute__((kernel)) testMinLongLongLong(long inA, unsigned int x) {
+    long inB = rsGetElementAt_long(gAllocInB, x);
+    return min(inA, inB);
+}
+
+long2 __attribute__((kernel)) testMinLong2Long2Long2(long2 inA, unsigned int x) {
+    long2 inB = rsGetElementAt_long2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+long3 __attribute__((kernel)) testMinLong3Long3Long3(long3 inA, unsigned int x) {
+    long3 inB = rsGetElementAt_long3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+long4 __attribute__((kernel)) testMinLong4Long4Long4(long4 inA, unsigned int x) {
+    long4 inB = rsGetElementAt_long4(gAllocInB, x);
+    return min(inA, inB);
+}
+
+ulong __attribute__((kernel)) testMinUlongUlongUlong(ulong inA, unsigned int x) {
+    ulong inB = rsGetElementAt_ulong(gAllocInB, x);
+    return min(inA, inB);
+}
+
+ulong2 __attribute__((kernel)) testMinUlong2Ulong2Ulong2(ulong2 inA, unsigned int x) {
+    ulong2 inB = rsGetElementAt_ulong2(gAllocInB, x);
+    return min(inA, inB);
+}
+
+ulong3 __attribute__((kernel)) testMinUlong3Ulong3Ulong3(ulong3 inA, unsigned int x) {
+    ulong3 inB = rsGetElementAt_ulong3(gAllocInB, x);
+    return min(inA, inB);
+}
+
+ulong4 __attribute__((kernel)) testMinUlong4Ulong4Ulong4(ulong4 inA, unsigned int x) {
+    ulong4 inB = rsGetElementAt_ulong4(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
new file mode 100644
index 0000000..5c6564b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMinRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestMin.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.java
new file mode 100644
index 0000000..8adfe99
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.java
@@ -0,0 +1,678 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestMix extends RSBaseCompute {
+
+    private ScriptC_TestMix script;
+    private ScriptC_TestMixRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestMix(mRS);
+        scriptRelaxed = new ScriptC_TestMixRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloatFloat {
+        public float inStart;
+        public float inStop;
+        public float inFraction;
+        public Target.Floaty out;
+    }
+
+    private void checkMixFloatFloatFloatFloat() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x471d6db1l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xb4422e8fl, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc6a51d9fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixFloatFloatFloatFloat(inStart, out);
+            verifyResultsMixFloatFloatFloatFloat(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloatFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixFloatFloatFloatFloat(inStart, out);
+            verifyResultsMixFloatFloatFloatFloat(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloatFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloatFloatFloatFloat(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInStart, (float) 42);
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInStop, (float) 42);
+        inStop.copyTo(arrayInStop);
+        float[] arrayInFraction = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInFraction, (float) 42);
+        inFraction.copyTo(arrayInFraction);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i];
+                args.inStop = arrayInStop[i];
+                args.inFraction = arrayInFraction[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMix(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkMixFloatFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixFloat2Float2Float2Float2() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xa2d9ce9l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x5395e837l, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x621e0ac7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixFloat2Float2Float2Float2(inStart, out);
+            verifyResultsMixFloat2Float2Float2Float2(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixFloat2Float2Float2Float2(inStart, out);
+            verifyResultsMixFloat2Float2Float2Float2(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat2Float2Float2Float2(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInStart, (float) 42);
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInStop, (float) 42);
+        inStop.copyTo(arrayInStop);
+        float[] arrayInFraction = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInFraction, (float) 42);
+        inFraction.copyTo(arrayInFraction);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 2 + j];
+                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);
+                CoreMathVerifier.computeMix(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 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]);
+                        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 checkMixFloat2Float2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixFloat3Float3Float3Float3() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x26b009c5l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x249ee4cbl, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xb0d4f51bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixFloat3Float3Float3Float3(inStart, out);
+            verifyResultsMixFloat3Float3Float3Float3(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixFloat3Float3Float3Float3(inStart, out);
+            verifyResultsMixFloat3Float3Float3Float3(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat3Float3Float3Float3(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInStart, (float) 42);
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInStop, (float) 42);
+        inStop.copyTo(arrayInStop);
+        float[] arrayInFraction = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInFraction, (float) 42);
+        inFraction.copyTo(arrayInFraction);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 4 + j];
+                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);
+                CoreMathVerifier.computeMix(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 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]);
+                        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 checkMixFloat3Float3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixFloat4Float4Float4Float4() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x433276a1l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf5a7e15fl, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xff8bdf6fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixFloat4Float4Float4Float4(inStart, out);
+            verifyResultsMixFloat4Float4Float4Float4(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixFloat4Float4Float4Float4(inStart, out);
+            verifyResultsMixFloat4Float4Float4Float4(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat4Float4Float4Float4(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInStart, (float) 42);
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInStop, (float) 42);
+        inStop.copyTo(arrayInStop);
+        float[] arrayInFraction = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInFraction, (float) 42);
+        inFraction.copyTo(arrayInFraction);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 4 + j];
+                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);
+                CoreMathVerifier.computeMix(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 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]);
+                        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 checkMixFloat4Float4Float4Float4" +
+                (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);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x92afd1f5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixFloat2Float2FloatFloat2(inStart, out);
+            verifyResultsMixFloat2Float2FloatFloat2(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixFloat2Float2FloatFloat2(inStart, out);
+            verifyResultsMixFloat2Float2FloatFloat2(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat2Float2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat2Float2FloatFloat2(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInStart, (float) 42);
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInStop, (float) 42);
+        inStop.copyTo(arrayInStop);
+        float[] arrayInFraction = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInFraction, (float) 42);
+        inFraction.copyTo(arrayInFraction);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 2 + j];
+                args.inStop = arrayInStop[i * 2 + j];
+                args.inFraction = arrayInFraction[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMix(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 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]);
+                        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 checkMixFloat2Float2FloatFloat2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixFloat3Float3FloatFloat3() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x1b20fa80l, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd6f4de7cl, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd131a27cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixFloat3Float3FloatFloat3(inStart, out);
+            verifyResultsMixFloat3Float3FloatFloat3(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixFloat3Float3FloatFloat3(inStart, out);
+            verifyResultsMixFloat3Float3FloatFloat3(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat3Float3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat3Float3FloatFloat3(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInStart, (float) 42);
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInStop, (float) 42);
+        inStop.copyTo(arrayInStop);
+        float[] arrayInFraction = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInFraction, (float) 42);
+        inFraction.copyTo(arrayInFraction);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inFraction = arrayInFraction[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMix(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 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]);
+                        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 checkMixFloat3Float3FloatFloat3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkMixFloat4Float4FloatFloat4() {
+        Allocation inStart = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa701d3dl, false);
+        Allocation inStop = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x715beb33l, false);
+        Allocation inFraction = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfb37303l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInStop(inStop);
+            script.set_gAllocInFraction(inFraction);
+            script.forEach_testMixFloat4Float4FloatFloat4(inStart, out);
+            verifyResultsMixFloat4Float4FloatFloat4(inStart, inStop, inFraction, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInStop(inStop);
+            scriptRelaxed.set_gAllocInFraction(inFraction);
+            scriptRelaxed.forEach_testMixFloat4Float4FloatFloat4(inStart, out);
+            verifyResultsMixFloat4Float4FloatFloat4(inStart, inStop, inFraction, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testMixFloat4Float4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsMixFloat4Float4FloatFloat4(Allocation inStart, Allocation inStop, Allocation inFraction, Allocation out, boolean relaxed) {
+        float[] arrayInStart = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInStart, (float) 42);
+        inStart.copyTo(arrayInStart);
+        float[] arrayInStop = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInStop, (float) 42);
+        inStop.copyTo(arrayInStop);
+        float[] arrayInFraction = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInFraction, (float) 42);
+        inFraction.copyTo(arrayInFraction);
+        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.
+                ArgumentsFloatFloatFloatFloat args = new ArgumentsFloatFloatFloatFloat();
+                args.inStart = arrayInStart[i * 4 + j];
+                args.inStop = arrayInStop[i * 4 + j];
+                args.inFraction = arrayInFraction[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeMix(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 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]);
+                        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 checkMixFloat4Float4FloatFloat4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testMix() {
+        checkMixFloatFloatFloatFloat();
+        checkMixFloat2Float2Float2Float2();
+        checkMixFloat3Float3Float3Float3();
+        checkMixFloat4Float4Float4Float4();
+        checkMixFloat2Float2FloatFloat2();
+        checkMixFloat3Float3FloatFloat3();
+        checkMixFloat4Float4FloatFloat4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.rs
new file mode 100644
index 0000000..b83d927
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMix.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInStop;
+rs_allocation gAllocInFraction;
+
+float __attribute__((kernel)) testMixFloatFloatFloatFloat(float inStart, unsigned int x) {
+    float inStop = rsGetElementAt_float(gAllocInStop, x);
+    float inFraction = rsGetElementAt_float(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
+float2 __attribute__((kernel)) testMixFloat2Float2Float2Float2(float2 inStart, unsigned int x) {
+    float2 inStop = rsGetElementAt_float2(gAllocInStop, x);
+    float2 inFraction = rsGetElementAt_float2(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
+float3 __attribute__((kernel)) testMixFloat3Float3Float3Float3(float3 inStart, unsigned int x) {
+    float3 inStop = rsGetElementAt_float3(gAllocInStop, x);
+    float3 inFraction = rsGetElementAt_float3(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
+float4 __attribute__((kernel)) testMixFloat4Float4Float4Float4(float4 inStart, unsigned int x) {
+    float4 inStop = rsGetElementAt_float4(gAllocInStop, x);
+    float4 inFraction = rsGetElementAt_float4(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);
+    return mix(inStart, inStop, inFraction);
+}
+
+float3 __attribute__((kernel)) testMixFloat3Float3FloatFloat3(float3 inStart, unsigned int x) {
+    float3 inStop = rsGetElementAt_float3(gAllocInStop, x);
+    float inFraction = rsGetElementAt_float(gAllocInFraction, x);
+    return mix(inStart, inStop, inFraction);
+}
+
+float4 __attribute__((kernel)) testMixFloat4Float4FloatFloat4(float4 inStart, unsigned int x) {
+    float4 inStop = rsGetElementAt_float4(gAllocInStop, x);
+    float inFraction = rsGetElementAt_float(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
new file mode 100644
index 0000000..50e5e4d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestMixRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestMix.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.java
new file mode 100644
index 0000000..1848ce6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestModf extends RSBaseCompute {
+
+    private ScriptC_TestModf script;
+    private ScriptC_TestModfRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestModf(mRS);
+        scriptRelaxed = new ScriptC_TestModfRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inV;
+        public Target.Floaty outIntegralPart;
+        public Target.Floaty out;
+    }
+
+    private void checkModfFloatFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x5ccaef45l, false);
+        try {
+            Allocation outIntegralPart = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutIntegralPart(outIntegralPart);
+            script.forEach_testModfFloatFloatFloat(inV, out);
+            verifyResultsModfFloatFloatFloat(inV, outIntegralPart, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation outIntegralPart = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIntegralPart(outIntegralPart);
+            scriptRelaxed.forEach_testModfFloatFloatFloat(inV, out);
+            verifyResultsModfFloatFloatFloat(inV, outIntegralPart, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsModfFloatFloatFloat(Allocation inV, Allocation outIntegralPart, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutIntegralPart = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOutIntegralPart, (float) 42);
+        outIntegralPart.copyTo(arrayOutIntegralPart);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeModf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outIntegralPart.couldBe(arrayOutIntegralPart[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(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 outIntegralPart: ");
+                        appendVariableToMessage(message, args.outIntegralPart);
+                        message.append("\n");
+                        message.append("Actual   output outIntegralPart: ");
+                        appendVariableToMessage(message, arrayOutIntegralPart[i * 1 + j]);
+                        if (!args.outIntegralPart.couldBe(arrayOutIntegralPart[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]);
+                        if (!args.out.couldBe(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 checkModfFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkModfFloat2Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfa16305fl, false);
+        try {
+            Allocation outIntegralPart = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutIntegralPart(outIntegralPart);
+            script.forEach_testModfFloat2Float2Float2(inV, out);
+            verifyResultsModfFloat2Float2Float2(inV, outIntegralPart, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation outIntegralPart = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIntegralPart(outIntegralPart);
+            scriptRelaxed.forEach_testModfFloat2Float2Float2(inV, out);
+            verifyResultsModfFloat2Float2Float2(inV, outIntegralPart, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsModfFloat2Float2Float2(Allocation inV, Allocation outIntegralPart, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutIntegralPart = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayOutIntegralPart, (float) 42);
+        outIntegralPart.copyTo(arrayOutIntegralPart);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeModf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outIntegralPart.couldBe(arrayOutIntegralPart[i * 2 + j])) {
+                    valid = false;
+                }
+                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 outIntegralPart: ");
+                        appendVariableToMessage(message, args.outIntegralPart);
+                        message.append("\n");
+                        message.append("Actual   output outIntegralPart: ");
+                        appendVariableToMessage(message, arrayOutIntegralPart[i * 2 + j]);
+                        if (!args.outIntegralPart.couldBe(arrayOutIntegralPart[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]);
+                        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 checkModfFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkModfFloat3Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xfbf43200l, false);
+        try {
+            Allocation outIntegralPart = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutIntegralPart(outIntegralPart);
+            script.forEach_testModfFloat3Float3Float3(inV, out);
+            verifyResultsModfFloat3Float3Float3(inV, outIntegralPart, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation outIntegralPart = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIntegralPart(outIntegralPart);
+            scriptRelaxed.forEach_testModfFloat3Float3Float3(inV, out);
+            verifyResultsModfFloat3Float3Float3(inV, outIntegralPart, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsModfFloat3Float3Float3(Allocation inV, Allocation outIntegralPart, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutIntegralPart = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOutIntegralPart, (float) 42);
+        outIntegralPart.copyTo(arrayOutIntegralPart);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeModf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outIntegralPart.couldBe(arrayOutIntegralPart[i * 4 + j])) {
+                    valid = false;
+                }
+                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 outIntegralPart: ");
+                        appendVariableToMessage(message, args.outIntegralPart);
+                        message.append("\n");
+                        message.append("Actual   output outIntegralPart: ");
+                        appendVariableToMessage(message, arrayOutIntegralPart[i * 4 + j]);
+                        if (!args.outIntegralPart.couldBe(arrayOutIntegralPart[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]);
+                        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 checkModfFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkModfFloat4Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfdd233a1l, false);
+        try {
+            Allocation outIntegralPart = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutIntegralPart(outIntegralPart);
+            script.forEach_testModfFloat4Float4Float4(inV, out);
+            verifyResultsModfFloat4Float4Float4(inV, outIntegralPart, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation outIntegralPart = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutIntegralPart(outIntegralPart);
+            scriptRelaxed.forEach_testModfFloat4Float4Float4(inV, out);
+            verifyResultsModfFloat4Float4Float4(inV, outIntegralPart, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testModfFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsModfFloat4Float4Float4(Allocation inV, Allocation outIntegralPart, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutIntegralPart = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOutIntegralPart, (float) 42);
+        outIntegralPart.copyTo(arrayOutIntegralPart);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeModf(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outIntegralPart.couldBe(arrayOutIntegralPart[i * 4 + j])) {
+                    valid = false;
+                }
+                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 outIntegralPart: ");
+                        appendVariableToMessage(message, args.outIntegralPart);
+                        message.append("\n");
+                        message.append("Actual   output outIntegralPart: ");
+                        appendVariableToMessage(message, arrayOutIntegralPart[i * 4 + j]);
+                        if (!args.outIntegralPart.couldBe(arrayOutIntegralPart[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]);
+                        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 checkModfFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testModf() {
+        checkModfFloatFloatFloat();
+        checkModfFloat2Float2Float2();
+        checkModfFloat3Float3Float3();
+        checkModfFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.rs
new file mode 100644
index 0000000..802ab70
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModf.rs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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)
+
+rs_allocation gAllocOutIntegralPart;
+
+float __attribute__((kernel)) testModfFloatFloatFloat(float inV, unsigned int x) {
+    float outIntegralPart = 0;
+    float out = modf(inV, &outIntegralPart);
+    rsSetElementAt_float(gAllocOutIntegralPart, outIntegralPart, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testModfFloat2Float2Float2(float2 inV, unsigned int x) {
+    float2 outIntegralPart = 0;
+    float2 out = modf(inV, &outIntegralPart);
+    rsSetElementAt_float2(gAllocOutIntegralPart, outIntegralPart, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testModfFloat3Float3Float3(float3 inV, unsigned int x) {
+    float3 outIntegralPart = 0;
+    float3 out = modf(inV, &outIntegralPart);
+    rsSetElementAt_float3(gAllocOutIntegralPart, outIntegralPart, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testModfFloat4Float4Float4(float4 inV, unsigned int x) {
+    float4 outIntegralPart = 0;
+    float4 out = modf(inV, &outIntegralPart);
+    rsSetElementAt_float4(gAllocOutIntegralPart, outIntegralPart, x);
+    return out;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModfRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModfRelaxed.rs
new file mode 100644
index 0000000..33dd422
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestModfRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestModf.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.java
new file mode 100644
index 0000000..e17cd2b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.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.
+ */
+
+// 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 java.util.Arrays;
+
+public class TestNan extends RSBaseCompute {
+
+    private ScriptC_TestNan script;
+    private ScriptC_TestNanRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNan(mRS);
+        scriptRelaxed = new ScriptC_TestNanRelaxed(mRS);
+    }
+
+    public class ArgumentsUintFloat {
+        public int inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNanUintFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.UNSIGNED_32, 1, 0x6a8a10d2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNanUintFloat(inV, out);
+            verifyResultsNanUintFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNanUintFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNanUintFloat(inV, out);
+            verifyResultsNanUintFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNanUintFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNanUintFloat(Allocation inV, Allocation out, boolean relaxed) {
+        int[] arrayInV = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (int) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsUintFloat args = new ArgumentsUintFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNanUintFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNan() {
+        checkNanUintFloat();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.rs
new file mode 100644
index 0000000..cc2e3a9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNan.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNanUintFloat(uint inV) {
+    return nan(inV);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanRelaxed.rs
new file mode 100644
index 0000000..a428cde
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNanRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNan.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.java
new file mode 100644
index 0000000..0452cc9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAcos extends RSBaseCompute {
+
+    private ScriptC_TestNativeAcos script;
+    private ScriptC_TestNativeAcosRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAcos(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAcosRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAcosFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x657f3d94l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeAcosFloatFloat(inV, out);
+            verifyResultsNativeAcosFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcosFloatFloat(inV, out);
+            verifyResultsNativeAcosFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcosFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcosFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcosFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd87e02d8l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeAcosFloat2Float2(inV, out);
+            verifyResultsNativeAcosFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcosFloat2Float2(inV, out);
+            verifyResultsNativeAcosFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcosFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcosFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcosFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xce9923b6l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeAcosFloat3Float3(inV, out);
+            verifyResultsNativeAcosFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcosFloat3Float3(inV, out);
+            verifyResultsNativeAcosFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcosFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcosFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcosFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc4b44494l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeAcosFloat4Float4(inV, out);
+            verifyResultsNativeAcosFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcosFloat4Float4(inV, out);
+            verifyResultsNativeAcosFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcosFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcosFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcosFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAcos() {
+        checkNativeAcosFloatFloat();
+        checkNativeAcosFloat2Float2();
+        checkNativeAcosFloat3Float3();
+        checkNativeAcosFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.rs
new file mode 100644
index 0000000..3d0d277
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcos.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeAcosFloatFloat(float inV) {
+    return native_acos(inV);
+}
+
+float2 __attribute__((kernel)) testNativeAcosFloat2Float2(float2 inV) {
+    return native_acos(inV);
+}
+
+float3 __attribute__((kernel)) testNativeAcosFloat3Float3(float3 inV) {
+    return native_acos(inV);
+}
+
+float4 __attribute__((kernel)) testNativeAcosFloat4Float4(float4 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
new file mode 100644
index 0000000..26c0058
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAcos.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.java
new file mode 100644
index 0000000..0494901
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAcosh extends RSBaseCompute {
+
+    private ScriptC_TestNativeAcosh script;
+    private ScriptC_TestNativeAcoshRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAcosh(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAcoshRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAcoshFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9e417fcal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeAcoshFloatFloat(inV, out);
+            verifyResultsNativeAcoshFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcoshFloatFloat(inV, out);
+            verifyResultsNativeAcoshFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcoshFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcoshFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcoshFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xcb8e3adel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeAcoshFloat2Float2(inV, out);
+            verifyResultsNativeAcoshFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcoshFloat2Float2(inV, out);
+            verifyResultsNativeAcoshFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcoshFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcoshFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcoshFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc1a95bbcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeAcoshFloat3Float3(inV, out);
+            verifyResultsNativeAcoshFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcoshFloat3Float3(inV, out);
+            verifyResultsNativeAcoshFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcoshFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcoshFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcoshFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb7c47c9al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeAcoshFloat4Float4(inV, out);
+            verifyResultsNativeAcoshFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcoshFloat4Float4(inV, out);
+            verifyResultsNativeAcoshFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcoshFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcoshFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcoshFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAcosh() {
+        checkNativeAcoshFloatFloat();
+        checkNativeAcoshFloat2Float2();
+        checkNativeAcoshFloat3Float3();
+        checkNativeAcoshFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.rs
new file mode 100644
index 0000000..d6f4022
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcosh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeAcoshFloatFloat(float inV) {
+    return native_acosh(inV);
+}
+
+float2 __attribute__((kernel)) testNativeAcoshFloat2Float2(float2 inV) {
+    return native_acosh(inV);
+}
+
+float3 __attribute__((kernel)) testNativeAcoshFloat3Float3(float3 inV) {
+    return native_acosh(inV);
+}
+
+float4 __attribute__((kernel)) testNativeAcoshFloat4Float4(float4 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
new file mode 100644
index 0000000..d077f0d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcoshRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAcosh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.java
new file mode 100644
index 0000000..1c84749
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAcospi extends RSBaseCompute {
+
+    private ScriptC_TestNativeAcospi script;
+    private ScriptC_TestNativeAcospiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAcospi(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAcospiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAcospiFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x99c7d8ffl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeAcospiFloatFloat(inV, out);
+            verifyResultsNativeAcospiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcospiFloatFloat(inV, out);
+            verifyResultsNativeAcospiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcospiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcospiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcospiFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x78e88aabl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeAcospiFloat2Float2(inV, out);
+            verifyResultsNativeAcospiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcospiFloat2Float2(inV, out);
+            verifyResultsNativeAcospiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcospiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcospiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcospiFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6f03ab89l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeAcospiFloat3Float3(inV, out);
+            verifyResultsNativeAcospiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcospiFloat3Float3(inV, out);
+            verifyResultsNativeAcospiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcospiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcospiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAcospiFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x651ecc67l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeAcospiFloat4Float4(inV, out);
+            verifyResultsNativeAcospiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAcospiFloat4Float4(inV, out);
+            verifyResultsNativeAcospiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAcospiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAcospiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAcospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAcospiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAcospi() {
+        checkNativeAcospiFloatFloat();
+        checkNativeAcospiFloat2Float2();
+        checkNativeAcospiFloat3Float3();
+        checkNativeAcospiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.rs
new file mode 100644
index 0000000..2feadae
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeAcospiFloatFloat(float inV) {
+    return native_acospi(inV);
+}
+
+float2 __attribute__((kernel)) testNativeAcospiFloat2Float2(float2 inV) {
+    return native_acospi(inV);
+}
+
+float3 __attribute__((kernel)) testNativeAcospiFloat3Float3(float3 inV) {
+    return native_acospi(inV);
+}
+
+float4 __attribute__((kernel)) testNativeAcospiFloat4Float4(float4 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
new file mode 100644
index 0000000..9a73980
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAcospiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAcospi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.java
new file mode 100644
index 0000000..252f99b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAsin extends RSBaseCompute {
+
+    private ScriptC_TestNativeAsin script;
+    private ScriptC_TestNativeAsinRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAsin(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAsinRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAsinFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x8d3e5bc7l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeAsinFloatFloat(inV, out);
+            verifyResultsNativeAsinFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinFloatFloat(inV, out);
+            verifyResultsNativeAsinFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xebdf2133l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeAsinFloat2Float2(inV, out);
+            verifyResultsNativeAsinFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinFloat2Float2(inV, out);
+            verifyResultsNativeAsinFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe1fa4211l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeAsinFloat3Float3(inV, out);
+            verifyResultsNativeAsinFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinFloat3Float3(inV, out);
+            verifyResultsNativeAsinFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd81562efl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeAsinFloat4Float4(inV, out);
+            verifyResultsNativeAsinFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinFloat4Float4(inV, out);
+            verifyResultsNativeAsinFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAsin() {
+        checkNativeAsinFloatFloat();
+        checkNativeAsinFloat2Float2();
+        checkNativeAsinFloat3Float3();
+        checkNativeAsinFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.rs
new file mode 100644
index 0000000..9d0811b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsin.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeAsinFloatFloat(float inV) {
+    return native_asin(inV);
+}
+
+float2 __attribute__((kernel)) testNativeAsinFloat2Float2(float2 inV) {
+    return native_asin(inV);
+}
+
+float3 __attribute__((kernel)) testNativeAsinFloat3Float3(float3 inV) {
+    return native_asin(inV);
+}
+
+float4 __attribute__((kernel)) testNativeAsinFloat4Float4(float4 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
new file mode 100644
index 0000000..d695124
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAsin.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.java
new file mode 100644
index 0000000..6b72cc9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAsinh extends RSBaseCompute {
+
+    private ScriptC_TestNativeAsinh script;
+    private ScriptC_TestNativeAsinhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAsinh(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAsinhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAsinhFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4b5b925bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeAsinhFloatFloat(inV, out);
+            verifyResultsNativeAsinhFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinhFloatFloat(inV, out);
+            verifyResultsNativeAsinhFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinhFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinhFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinhFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xcde5427l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeAsinhFloat2Float2(inV, out);
+            verifyResultsNativeAsinhFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinhFloat2Float2(inV, out);
+            verifyResultsNativeAsinhFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinhFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinhFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinhFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2f97505l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeAsinhFloat3Float3(inV, out);
+            verifyResultsNativeAsinhFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinhFloat3Float3(inV, out);
+            verifyResultsNativeAsinhFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinhFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinhFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinhFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf91495e3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeAsinhFloat4Float4(inV, out);
+            verifyResultsNativeAsinhFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinhFloat4Float4(inV, out);
+            verifyResultsNativeAsinhFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinhFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinhFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAsinh() {
+        checkNativeAsinhFloatFloat();
+        checkNativeAsinhFloat2Float2();
+        checkNativeAsinhFloat3Float3();
+        checkNativeAsinhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.rs
new file mode 100644
index 0000000..21627f6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeAsinhFloatFloat(float inV) {
+    return native_asinh(inV);
+}
+
+float2 __attribute__((kernel)) testNativeAsinhFloat2Float2(float2 inV) {
+    return native_asinh(inV);
+}
+
+float3 __attribute__((kernel)) testNativeAsinhFloat3Float3(float3 inV) {
+    return native_asinh(inV);
+}
+
+float4 __attribute__((kernel)) testNativeAsinhFloat4Float4(float4 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
new file mode 100644
index 0000000..0d4b6c9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinhRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAsinh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.java
new file mode 100644
index 0000000..84b219a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAsinpi extends RSBaseCompute {
+
+    private ScriptC_TestNativeAsinpi script;
+    private ScriptC_TestNativeAsinpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAsinpi(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAsinpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAsinpiFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xad28f75al, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeAsinpiFloatFloat(inV, out);
+            verifyResultsNativeAsinpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinpiFloatFloat(inV, out);
+            verifyResultsNativeAsinpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinpiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinpiFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x715cc9eel, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeAsinpiFloat2Float2(inV, out);
+            verifyResultsNativeAsinpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinpiFloat2Float2(inV, out);
+            verifyResultsNativeAsinpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinpiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinpiFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6777eaccl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeAsinpiFloat3Float3(inV, out);
+            verifyResultsNativeAsinpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinpiFloat3Float3(inV, out);
+            verifyResultsNativeAsinpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinpiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAsinpiFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x5d930baal, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeAsinpiFloat4Float4(inV, out);
+            verifyResultsNativeAsinpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAsinpiFloat4Float4(inV, out);
+            verifyResultsNativeAsinpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAsinpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAsinpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAsinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAsinpiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAsinpi() {
+        checkNativeAsinpiFloatFloat();
+        checkNativeAsinpiFloat2Float2();
+        checkNativeAsinpiFloat3Float3();
+        checkNativeAsinpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.rs
new file mode 100644
index 0000000..d924ca7
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeAsinpiFloatFloat(float inV) {
+    return native_asinpi(inV);
+}
+
+float2 __attribute__((kernel)) testNativeAsinpiFloat2Float2(float2 inV) {
+    return native_asinpi(inV);
+}
+
+float3 __attribute__((kernel)) testNativeAsinpiFloat3Float3(float3 inV) {
+    return native_asinpi(inV);
+}
+
+float4 __attribute__((kernel)) testNativeAsinpiFloat4Float4(float4 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
new file mode 100644
index 0000000..35beace
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAsinpiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAsinpi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.java
new file mode 100644
index 0000000..12430dc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAtan extends RSBaseCompute {
+
+    private ScriptC_TestNativeAtan script;
+    private ScriptC_TestNativeAtanRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAtan(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAtanRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtanFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x25b34e42l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeAtanFloatFloat(inV, out);
+            verifyResultsNativeAtanFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanFloatFloat(inV, out);
+            verifyResultsNativeAtanFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x108a7b96l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeAtanFloat2Float2(inV, out);
+            verifyResultsNativeAtanFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanFloat2Float2(inV, out);
+            verifyResultsNativeAtanFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6a59c74l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeAtanFloat3Float3(inV, out);
+            verifyResultsNativeAtanFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanFloat3Float3(inV, out);
+            verifyResultsNativeAtanFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfcc0bd52l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeAtanFloat4Float4(inV, out);
+            verifyResultsNativeAtanFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanFloat4Float4(inV, out);
+            verifyResultsNativeAtanFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAtan() {
+        checkNativeAtanFloatFloat();
+        checkNativeAtanFloat2Float2();
+        checkNativeAtanFloat3Float3();
+        checkNativeAtanFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.rs
new file mode 100644
index 0000000..de9f739
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeAtanFloatFloat(float inV) {
+    return native_atan(inV);
+}
+
+float2 __attribute__((kernel)) testNativeAtanFloat2Float2(float2 inV) {
+    return native_atan(inV);
+}
+
+float3 __attribute__((kernel)) testNativeAtanFloat3Float3(float3 inV) {
+    return native_atan(inV);
+}
+
+float4 __attribute__((kernel)) testNativeAtanFloat4Float4(float4 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
new file mode 100644
index 0000000..4cabb28
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAtan2 extends RSBaseCompute {
+
+    private ScriptC_TestNativeAtan2 script;
+    private ScriptC_TestNativeAtan2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAtan2(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAtan2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inNumerator;
+        public float inDenominator;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtan2FloatFloatFloat() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xfb6dcb4fl, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x634c16d0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2FloatFloatFloat(inNumerator, out);
+            verifyResultsNativeAtan2FloatFloatFloat(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2FloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2FloatFloatFloat(inNumerator, out);
+            verifyResultsNativeAtan2FloatFloatFloat(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2FloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2FloatFloatFloat(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inNumerator = arrayInNumerator[i];
+                args.inDenominator = arrayInDenominator[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2FloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2Float2Float2Float2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd0059da7l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xdfda5468l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2Float2Float2Float2(inNumerator, out);
+            verifyResultsNativeAtan2Float2Float2Float2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2Float2Float2Float2(inNumerator, out);
+            verifyResultsNativeAtan2Float2Float2Float2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2Float2Float2Float2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    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]);
+                        if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2Float2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2Float3Float3Float3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x72d189a8l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xb2b5e7a1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2Float3Float3Float3(inNumerator, out);
+            verifyResultsNativeAtan2Float3Float3Float3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2Float3Float3Float3(inNumerator, out);
+            verifyResultsNativeAtan2Float3Float3Float3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2Float3Float3Float3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    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]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2Float3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2Float4Float4Float4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x159d75a9l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x85917adal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2Float4Float4Float4(inNumerator, out);
+            verifyResultsNativeAtan2Float4Float4Float4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2Float4Float4Float4(inNumerator, out);
+            verifyResultsNativeAtan2Float4Float4Float4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2Float4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2Float4Float4Float4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeAtan2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    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]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2Float4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAtan2() {
+        checkNativeAtan2FloatFloatFloat();
+        checkNativeAtan2Float2Float2Float2();
+        checkNativeAtan2Float3Float3Float3();
+        checkNativeAtan2Float4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.rs
new file mode 100644
index 0000000..66ee75e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInDenominator;
+
+float __attribute__((kernel)) testNativeAtan2FloatFloatFloat(float inNumerator, unsigned int x) {
+    float inDenominator = rsGetElementAt_float(gAllocInDenominator, x);
+    return native_atan2(inNumerator, inDenominator);
+}
+
+float2 __attribute__((kernel)) testNativeAtan2Float2Float2Float2(float2 inNumerator, unsigned int x) {
+    float2 inDenominator = rsGetElementAt_float2(gAllocInDenominator, x);
+    return native_atan2(inNumerator, inDenominator);
+}
+
+float3 __attribute__((kernel)) testNativeAtan2Float3Float3Float3(float3 inNumerator, unsigned int x) {
+    float3 inDenominator = rsGetElementAt_float3(gAllocInDenominator, x);
+    return native_atan2(inNumerator, inDenominator);
+}
+
+float4 __attribute__((kernel)) testNativeAtan2Float4Float4Float4(float4 inNumerator, unsigned int x) {
+    float4 inDenominator = rsGetElementAt_float4(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
new file mode 100644
index 0000000..ac6659f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAtan2.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.java
new file mode 100644
index 0000000..c42591c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAtan2pi extends RSBaseCompute {
+
+    private ScriptC_TestNativeAtan2pi script;
+    private ScriptC_TestNativeAtan2piRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAtan2pi(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAtan2piRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inNumerator;
+        public float inDenominator;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtan2piFloatFloatFloat() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x694fc108l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x853dc01l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2piFloatFloatFloat(inNumerator, out);
+            verifyResultsNativeAtan2piFloatFloatFloat(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2piFloatFloatFloat(inNumerator, out);
+            verifyResultsNativeAtan2piFloatFloatFloat(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2piFloatFloatFloat(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inNumerator = arrayInNumerator[i];
+                args.inDenominator = arrayInDenominator[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2piFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2piFloat2Float2Float2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8853bce2l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xc19e58bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2piFloat2Float2Float2(inNumerator, out);
+            verifyResultsNativeAtan2piFloat2Float2Float2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2piFloat2Float2Float2(inNumerator, out);
+            verifyResultsNativeAtan2piFloat2Float2Float2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2piFloat2Float2Float2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    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]);
+                        if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2piFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2piFloat3Float3Float3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2b1fa8e3l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdef578c4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2piFloat3Float3Float3(inNumerator, out);
+            verifyResultsNativeAtan2piFloat3Float3Float3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2piFloat3Float3Float3(inNumerator, out);
+            verifyResultsNativeAtan2piFloat3Float3Float3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2piFloat3Float3Float3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    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]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2piFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtan2piFloat4Float4Float4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xcdeb94e4l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb1d10bfdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testNativeAtan2piFloat4Float4Float4(inNumerator, out);
+            verifyResultsNativeAtan2piFloat4Float4Float4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testNativeAtan2piFloat4Float4Float4(inNumerator, out);
+            verifyResultsNativeAtan2piFloat4Float4Float4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtan2piFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtan2piFloat4Float4Float4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeAtan2pi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    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]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtan2piFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAtan2pi() {
+        checkNativeAtan2piFloatFloatFloat();
+        checkNativeAtan2piFloat2Float2Float2();
+        checkNativeAtan2piFloat3Float3Float3();
+        checkNativeAtan2piFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.rs
new file mode 100644
index 0000000..5804dd5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2pi.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInDenominator;
+
+float __attribute__((kernel)) testNativeAtan2piFloatFloatFloat(float inNumerator, unsigned int x) {
+    float inDenominator = rsGetElementAt_float(gAllocInDenominator, x);
+    return native_atan2pi(inNumerator, inDenominator);
+}
+
+float2 __attribute__((kernel)) testNativeAtan2piFloat2Float2Float2(float2 inNumerator, unsigned int x) {
+    float2 inDenominator = rsGetElementAt_float2(gAllocInDenominator, x);
+    return native_atan2pi(inNumerator, inDenominator);
+}
+
+float3 __attribute__((kernel)) testNativeAtan2piFloat3Float3Float3(float3 inNumerator, unsigned int x) {
+    float3 inDenominator = rsGetElementAt_float3(gAllocInDenominator, x);
+    return native_atan2pi(inNumerator, inDenominator);
+}
+
+float4 __attribute__((kernel)) testNativeAtan2piFloat4Float4Float4(float4 inNumerator, unsigned int x) {
+    float4 inDenominator = rsGetElementAt_float4(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
new file mode 100644
index 0000000..48c1ea0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtan2piRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAtan2pi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanRelaxed.rs
new file mode 100644
index 0000000..21be808
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAtan.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.java
new file mode 100644
index 0000000..c37993b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAtanh extends RSBaseCompute {
+
+    private ScriptC_TestNativeAtanh script;
+    private ScriptC_TestNativeAtanhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAtanh(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAtanhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtanhFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe7004d04l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeAtanhFloatFloat(inV, out);
+            verifyResultsNativeAtanhFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanhFloatFloat(inV, out);
+            verifyResultsNativeAtanhFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanhFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanhFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanhFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x35a682c8l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeAtanhFloat2Float2(inV, out);
+            verifyResultsNativeAtanhFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanhFloat2Float2(inV, out);
+            verifyResultsNativeAtanhFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanhFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanhFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanhFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x2bc1a3a6l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeAtanhFloat3Float3(inV, out);
+            verifyResultsNativeAtanhFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanhFloat3Float3(inV, out);
+            verifyResultsNativeAtanhFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanhFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanhFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanhFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x21dcc484l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeAtanhFloat4Float4(inV, out);
+            verifyResultsNativeAtanhFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanhFloat4Float4(inV, out);
+            verifyResultsNativeAtanhFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanhFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanhFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAtanh() {
+        checkNativeAtanhFloatFloat();
+        checkNativeAtanhFloat2Float2();
+        checkNativeAtanhFloat3Float3();
+        checkNativeAtanhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.rs
new file mode 100644
index 0000000..394e6d3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeAtanhFloatFloat(float inV) {
+    return native_atanh(inV);
+}
+
+float2 __attribute__((kernel)) testNativeAtanhFloat2Float2(float2 inV) {
+    return native_atanh(inV);
+}
+
+float3 __attribute__((kernel)) testNativeAtanhFloat3Float3(float3 inV) {
+    return native_atanh(inV);
+}
+
+float4 __attribute__((kernel)) testNativeAtanhFloat4Float4(float4 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
new file mode 100644
index 0000000..d12d443
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanhRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAtanh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.java
new file mode 100644
index 0000000..4089adb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeAtanpi extends RSBaseCompute {
+
+    private ScriptC_TestNativeAtanpi script;
+    private ScriptC_TestNativeAtanpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeAtanpi(mRS);
+        scriptRelaxed = new ScriptC_TestNativeAtanpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeAtanpiFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd1d451bdl, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeAtanpiFloatFloat(inV, out);
+            verifyResultsNativeAtanpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanpiFloatFloat(inV, out);
+            verifyResultsNativeAtanpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanpiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanpiFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4afc9ef9l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeAtanpiFloat2Float2(inV, out);
+            verifyResultsNativeAtanpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanpiFloat2Float2(inV, out);
+            verifyResultsNativeAtanpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanpiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanpiFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4117bfd7l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeAtanpiFloat3Float3(inV, out);
+            verifyResultsNativeAtanpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanpiFloat3Float3(inV, out);
+            verifyResultsNativeAtanpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanpiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeAtanpiFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3732e0b5l, -1, 1);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeAtanpiFloat4Float4(inV, out);
+            verifyResultsNativeAtanpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeAtanpiFloat4Float4(inV, out);
+            verifyResultsNativeAtanpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeAtanpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeAtanpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeAtanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!valid) {
+                    if (!errorFound) {
+                        errorFound = true;
+                        message.append("Input inV: ");
+                        appendVariableToMessage(message, args.inV);
+                        message.append("\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], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeAtanpiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeAtanpi() {
+        checkNativeAtanpiFloatFloat();
+        checkNativeAtanpiFloat2Float2();
+        checkNativeAtanpiFloat3Float3();
+        checkNativeAtanpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.rs
new file mode 100644
index 0000000..89d306c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeAtanpiFloatFloat(float inV) {
+    return native_atanpi(inV);
+}
+
+float2 __attribute__((kernel)) testNativeAtanpiFloat2Float2(float2 inV) {
+    return native_atanpi(inV);
+}
+
+float3 __attribute__((kernel)) testNativeAtanpiFloat3Float3(float3 inV) {
+    return native_atanpi(inV);
+}
+
+float4 __attribute__((kernel)) testNativeAtanpiFloat4Float4(float4 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
new file mode 100644
index 0000000..75c9ed8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeAtanpiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeAtanpi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.java
new file mode 100644
index 0000000..18c76bb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeCbrt extends RSBaseCompute {
+
+    private ScriptC_TestNativeCbrt script;
+    private ScriptC_TestNativeCbrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeCbrt(mRS);
+        scriptRelaxed = new ScriptC_TestNativeCbrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeCbrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x18086389l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeCbrtFloatFloat(inV, out);
+            verifyResultsNativeCbrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCbrtFloatFloat(inV, out);
+            verifyResultsNativeCbrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCbrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCbrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeCbrtFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCbrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x59112965l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeCbrtFloat2Float2(inV, out);
+            verifyResultsNativeCbrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCbrtFloat2Float2(inV, out);
+            verifyResultsNativeCbrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCbrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCbrt(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 checkNativeCbrtFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCbrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4f2c4a43l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeCbrtFloat3Float3(inV, out);
+            verifyResultsNativeCbrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCbrtFloat3Float3(inV, out);
+            verifyResultsNativeCbrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCbrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCbrt(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 checkNativeCbrtFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCbrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x45476b21l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeCbrtFloat4Float4(inV, out);
+            verifyResultsNativeCbrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCbrtFloat4Float4(inV, out);
+            verifyResultsNativeCbrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCbrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCbrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCbrt(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 checkNativeCbrtFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeCbrt() {
+        checkNativeCbrtFloatFloat();
+        checkNativeCbrtFloat2Float2();
+        checkNativeCbrtFloat3Float3();
+        checkNativeCbrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.rs
new file mode 100644
index 0000000..f2e44fa
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrt.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeCbrtFloatFloat(float inV) {
+    return native_cbrt(inV);
+}
+
+float2 __attribute__((kernel)) testNativeCbrtFloat2Float2(float2 inV) {
+    return native_cbrt(inV);
+}
+
+float3 __attribute__((kernel)) testNativeCbrtFloat3Float3(float3 inV) {
+    return native_cbrt(inV);
+}
+
+float4 __attribute__((kernel)) testNativeCbrtFloat4Float4(float4 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
new file mode 100644
index 0000000..bfc649d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCbrtRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeCbrt.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.java
new file mode 100644
index 0000000..bd9c6a6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeCos extends RSBaseCompute {
+
+    private ScriptC_TestNativeCos script;
+    private ScriptC_TestNativeCosRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeCos(mRS);
+        scriptRelaxed = new ScriptC_TestNativeCosRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeCosFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x777f3495l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeCosFloatFloat(inV, out);
+            verifyResultsNativeCosFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCosFloatFloat(inV, out);
+            verifyResultsNativeCosFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCosFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeCosFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCosFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xda3d0911l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeCosFloat2Float2(inV, out);
+            verifyResultsNativeCosFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCosFloat2Float2(inV, out);
+            verifyResultsNativeCosFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCosFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCos(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 checkNativeCosFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCosFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd05829efl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeCosFloat3Float3(inV, out);
+            verifyResultsNativeCosFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCosFloat3Float3(inV, out);
+            verifyResultsNativeCosFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCosFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCos(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 checkNativeCosFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCosFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc6734acdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeCosFloat4Float4(inV, out);
+            verifyResultsNativeCosFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCosFloat4Float4(inV, out);
+            verifyResultsNativeCosFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCosFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCosFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCos(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 checkNativeCosFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeCos() {
+        checkNativeCosFloatFloat();
+        checkNativeCosFloat2Float2();
+        checkNativeCosFloat3Float3();
+        checkNativeCosFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.rs
new file mode 100644
index 0000000..6717d50
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCos.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeCosFloatFloat(float inV) {
+    return native_cos(inV);
+}
+
+float2 __attribute__((kernel)) testNativeCosFloat2Float2(float2 inV) {
+    return native_cos(inV);
+}
+
+float3 __attribute__((kernel)) testNativeCosFloat3Float3(float3 inV) {
+    return native_cos(inV);
+}
+
+float4 __attribute__((kernel)) testNativeCosFloat4Float4(float4 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
new file mode 100644
index 0000000..2c38290
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeCos.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.java
new file mode 100644
index 0000000..7bdab28
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeCosh extends RSBaseCompute {
+
+    private ScriptC_TestNativeCosh script;
+    private ScriptC_TestNativeCoshRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeCosh(mRS);
+        scriptRelaxed = new ScriptC_TestNativeCoshRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeCoshFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa43ffcf5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeCoshFloatFloat(inV, out);
+            verifyResultsNativeCoshFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCoshFloatFloat(inV, out);
+            verifyResultsNativeCoshFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCoshFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCosh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeCoshFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCoshFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x16a44671l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeCoshFloat2Float2(inV, out);
+            verifyResultsNativeCoshFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCoshFloat2Float2(inV, out);
+            verifyResultsNativeCoshFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCoshFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCosh(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 checkNativeCoshFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCoshFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xcbf674fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeCoshFloat3Float3(inV, out);
+            verifyResultsNativeCoshFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCoshFloat3Float3(inV, out);
+            verifyResultsNativeCoshFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCoshFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCosh(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 checkNativeCoshFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCoshFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2da882dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeCoshFloat4Float4(inV, out);
+            verifyResultsNativeCoshFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCoshFloat4Float4(inV, out);
+            verifyResultsNativeCoshFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCoshFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCoshFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCosh(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 checkNativeCoshFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeCosh() {
+        checkNativeCoshFloatFloat();
+        checkNativeCoshFloat2Float2();
+        checkNativeCoshFloat3Float3();
+        checkNativeCoshFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.rs
new file mode 100644
index 0000000..1a0eb5a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCosh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeCoshFloatFloat(float inV) {
+    return native_cosh(inV);
+}
+
+float2 __attribute__((kernel)) testNativeCoshFloat2Float2(float2 inV) {
+    return native_cosh(inV);
+}
+
+float3 __attribute__((kernel)) testNativeCoshFloat3Float3(float3 inV) {
+    return native_cosh(inV);
+}
+
+float4 __attribute__((kernel)) testNativeCoshFloat4Float4(float4 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
new file mode 100644
index 0000000..278dbe4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCoshRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeCosh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.java
new file mode 100644
index 0000000..91b4426
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeCospi extends RSBaseCompute {
+
+    private ScriptC_TestNativeCospi script;
+    private ScriptC_TestNativeCospiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeCospi(mRS);
+        scriptRelaxed = new ScriptC_TestNativeCospiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeCospiFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9b86df38l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeCospiFloatFloat(inV, out);
+            verifyResultsNativeCospiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCospiFloatFloat(inV, out);
+            verifyResultsNativeCospiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCospiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCospi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeCospiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCospiFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x159c7c5cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeCospiFloat2Float2(inV, out);
+            verifyResultsNativeCospiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCospiFloat2Float2(inV, out);
+            verifyResultsNativeCospiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCospiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCospi(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 checkNativeCospiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCospiFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xbb79d3al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeCospiFloat3Float3(inV, out);
+            verifyResultsNativeCospiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCospiFloat3Float3(inV, out);
+            verifyResultsNativeCospiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCospiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCospi(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 checkNativeCospiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeCospiFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1d2be18l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeCospiFloat4Float4(inV, out);
+            verifyResultsNativeCospiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeCospiFloat4Float4(inV, out);
+            verifyResultsNativeCospiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeCospiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeCospiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeCospi(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 checkNativeCospiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeCospi() {
+        checkNativeCospiFloatFloat();
+        checkNativeCospiFloat2Float2();
+        checkNativeCospiFloat3Float3();
+        checkNativeCospiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.rs
new file mode 100644
index 0000000..d7aedb5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeCospiFloatFloat(float inV) {
+    return native_cospi(inV);
+}
+
+float2 __attribute__((kernel)) testNativeCospiFloat2Float2(float2 inV) {
+    return native_cospi(inV);
+}
+
+float3 __attribute__((kernel)) testNativeCospiFloat3Float3(float3 inV) {
+    return native_cospi(inV);
+}
+
+float4 __attribute__((kernel)) testNativeCospiFloat4Float4(float4 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
new file mode 100644
index 0000000..8b57ea0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeCospiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeCospi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.java
new file mode 100644
index 0000000..8485d16
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeDistance extends RSBaseCompute {
+
+    private ScriptC_TestNativeDistance script;
+    private ScriptC_TestNativeDistanceRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeDistance(mRS);
+        scriptRelaxed = new ScriptC_TestNativeDistanceRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inLeftVector;
+        public float inRightVector;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeDistanceFloatFloatFloat() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x30ae2337l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9b58b3c2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDistanceFloatFloatFloat(inLeftVector, out);
+            verifyResultsNativeDistanceFloatFloatFloat(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDistanceFloatFloatFloat(inLeftVector, out);
+            verifyResultsNativeDistanceFloatFloatFloat(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDistanceFloatFloatFloat(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inLeftVector = arrayInLeftVector[i];
+            args.inRightVector = arrayInRightVector[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNativeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNativeDistanceFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloatNFloat {
+        public float[] inLeftVector;
+        public float[] inRightVector;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeDistanceFloat2Float2Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x27286713l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1e219b6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDistanceFloat2Float2Float(inLeftVector, out);
+            verifyResultsNativeDistanceFloat2Float2Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat2Float2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDistanceFloat2Float2Float(inLeftVector, out);
+            verifyResultsNativeDistanceFloat2Float2Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat2Float2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDistanceFloat2Float2Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[2];
+            args.inRightVector = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 2 + j];
+            }
+            for (int j = 0; j < 2 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 2 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNativeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNativeDistanceFloat2Float2Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDistanceFloat3Float3Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x48c71b61l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa78a62d0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDistanceFloat3Float3Float(inLeftVector, out);
+            verifyResultsNativeDistanceFloat3Float3Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat3Float3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDistanceFloat3Float3Float(inLeftVector, out);
+            verifyResultsNativeDistanceFloat3Float3Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat3Float3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDistanceFloat3Float3Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[3];
+            args.inRightVector = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+            }
+            for (int j = 0; j < 3 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNativeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNativeDistanceFloat3Float3Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDistanceFloat4Float4Float() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6a65cfafl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4d32abeal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDistanceFloat4Float4Float(inLeftVector, out);
+            verifyResultsNativeDistanceFloat4Float4Float(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat4Float4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDistanceFloat4Float4Float(inLeftVector, out);
+            verifyResultsNativeDistanceFloat4Float4Float(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDistanceFloat4Float4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDistanceFloat4Float4Float(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloatNFloat args = new ArgumentsFloatNFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inLeftVector = new float[4];
+            args.inRightVector = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inLeftVector[j] = arrayInLeftVector[i * 4 + j];
+            }
+            for (int j = 0; j < 4 ; j++) {
+                args.inRightVector[j] = arrayInRightVector[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNativeDistance(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNativeDistanceFloat4Float4Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeDistance() {
+        checkNativeDistanceFloatFloatFloat();
+        checkNativeDistanceFloat2Float2Float();
+        checkNativeDistanceFloat3Float3Float();
+        checkNativeDistanceFloat4Float4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.rs
new file mode 100644
index 0000000..3f9c64e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistance.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInRightVector;
+
+float __attribute__((kernel)) testNativeDistanceFloatFloatFloat(float inLeftVector, unsigned int x) {
+    float inRightVector = rsGetElementAt_float(gAllocInRightVector, x);
+    return native_distance(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testNativeDistanceFloat2Float2Float(float2 inLeftVector, unsigned int x) {
+    float2 inRightVector = rsGetElementAt_float2(gAllocInRightVector, x);
+    return native_distance(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testNativeDistanceFloat3Float3Float(float3 inLeftVector, unsigned int x) {
+    float3 inRightVector = rsGetElementAt_float3(gAllocInRightVector, x);
+    return native_distance(inLeftVector, inRightVector);
+}
+
+float __attribute__((kernel)) testNativeDistanceFloat4Float4Float(float4 inLeftVector, unsigned int x) {
+    float4 inRightVector = rsGetElementAt_float4(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
new file mode 100644
index 0000000..b35e456
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDistanceRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeDistance.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.java
new file mode 100644
index 0000000..194a4df
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeDivide extends RSBaseCompute {
+
+    private ScriptC_TestNativeDivide script;
+    private ScriptC_TestNativeDivideRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeDivide(mRS);
+        scriptRelaxed = new ScriptC_TestNativeDivideRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inLeftVector;
+        public float inRightVector;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeDivideFloatFloatFloat() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x751754efl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x19040daal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDivideFloatFloatFloat(inLeftVector, out);
+            verifyResultsNativeDivideFloatFloatFloat(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDivideFloatFloatFloat(inLeftVector, out);
+            verifyResultsNativeDivideFloatFloatFloat(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDivideFloatFloatFloat(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inLeftVector = arrayInLeftVector[i];
+                args.inRightVector = arrayInRightVector[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeDivide(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeDivideFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDivideFloat2Float2Float2() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7785d6dl, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xaf507ad4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDivideFloat2Float2Float2(inLeftVector, out);
+            verifyResultsNativeDivideFloat2Float2Float2(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDivideFloat2Float2Float2(inLeftVector, out);
+            verifyResultsNativeDivideFloat2Float2Float2(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDivideFloat2Float2Float2(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeDivide(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 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]);
+                        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 checkNativeDivideFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDivideFloat3Float3Float3() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5fb90198l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x822c0e0dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDivideFloat3Float3Float3(inLeftVector, out);
+            verifyResultsNativeDivideFloat3Float3Float3(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDivideFloat3Float3Float3(inLeftVector, out);
+            verifyResultsNativeDivideFloat3Float3Float3(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDivideFloat3Float3Float3(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeDivide(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 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]);
+                        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 checkNativeDivideFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeDivideFloat4Float4Float4() {
+        Allocation inLeftVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb7f9a5c3l, false);
+        Allocation inRightVector = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x5507a146l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInRightVector(inRightVector);
+            script.forEach_testNativeDivideFloat4Float4Float4(inLeftVector, out);
+            verifyResultsNativeDivideFloat4Float4Float4(inLeftVector, inRightVector, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInRightVector(inRightVector);
+            scriptRelaxed.forEach_testNativeDivideFloat4Float4Float4(inLeftVector, out);
+            verifyResultsNativeDivideFloat4Float4Float4(inLeftVector, inRightVector, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeDivideFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeDivideFloat4Float4Float4(Allocation inLeftVector, Allocation inRightVector, Allocation out, boolean relaxed) {
+        float[] arrayInLeftVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInLeftVector, (float) 42);
+        inLeftVector.copyTo(arrayInLeftVector);
+        float[] arrayInRightVector = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInRightVector, (float) 42);
+        inRightVector.copyTo(arrayInRightVector);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeDivide(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 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]);
+                        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 checkNativeDivideFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeDivide() {
+        checkNativeDivideFloatFloatFloat();
+        checkNativeDivideFloat2Float2Float2();
+        checkNativeDivideFloat3Float3Float3();
+        checkNativeDivideFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.rs
new file mode 100644
index 0000000..6a4a6a4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivide.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInRightVector;
+
+float __attribute__((kernel)) testNativeDivideFloatFloatFloat(float inLeftVector, unsigned int x) {
+    float inRightVector = rsGetElementAt_float(gAllocInRightVector, x);
+    return native_divide(inLeftVector, inRightVector);
+}
+
+float2 __attribute__((kernel)) testNativeDivideFloat2Float2Float2(float2 inLeftVector, unsigned int x) {
+    float2 inRightVector = rsGetElementAt_float2(gAllocInRightVector, x);
+    return native_divide(inLeftVector, inRightVector);
+}
+
+float3 __attribute__((kernel)) testNativeDivideFloat3Float3Float3(float3 inLeftVector, unsigned int x) {
+    float3 inRightVector = rsGetElementAt_float3(gAllocInRightVector, x);
+    return native_divide(inLeftVector, inRightVector);
+}
+
+float4 __attribute__((kernel)) testNativeDivideFloat4Float4Float4(float4 inLeftVector, unsigned int x) {
+    float4 inRightVector = rsGetElementAt_float4(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
new file mode 100644
index 0000000..b0a48f5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeDivideRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeDivide.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.java
new file mode 100644
index 0000000..3643235
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeExp extends RSBaseCompute {
+
+    private ScriptC_TestNativeExp script;
+    private ScriptC_TestNativeExpRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeExp(mRS);
+        scriptRelaxed = new ScriptC_TestNativeExpRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeExpFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf1f6be9bl, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeExpFloatFloat(inV, out);
+            verifyResultsNativeExpFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpFloatFloat(inV, out);
+            verifyResultsNativeExpFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeExpFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x63a0ee67l, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeExpFloat2Float2(inV, out);
+            verifyResultsNativeExpFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpFloat2Float2(inV, out);
+            verifyResultsNativeExpFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp(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 checkNativeExpFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x59bc0f45l, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeExpFloat3Float3(inV, out);
+            verifyResultsNativeExpFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpFloat3Float3(inV, out);
+            verifyResultsNativeExpFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp(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 checkNativeExpFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4fd73023l, -86, 86);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeExpFloat4Float4(inV, out);
+            verifyResultsNativeExpFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpFloat4Float4(inV, out);
+            verifyResultsNativeExpFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp(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 checkNativeExpFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeExp() {
+        checkNativeExpFloatFloat();
+        checkNativeExpFloat2Float2();
+        checkNativeExpFloat3Float3();
+        checkNativeExpFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.rs
new file mode 100644
index 0000000..92e31dc
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeExpFloatFloat(float inV) {
+    return native_exp(inV);
+}
+
+float2 __attribute__((kernel)) testNativeExpFloat2Float2(float2 inV) {
+    return native_exp(inV);
+}
+
+float3 __attribute__((kernel)) testNativeExpFloat3Float3(float3 inV) {
+    return native_exp(inV);
+}
+
+float4 __attribute__((kernel)) testNativeExpFloat4Float4(float4 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
new file mode 100644
index 0000000..36996f9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeExp10 extends RSBaseCompute {
+
+    private ScriptC_TestNativeExp10 script;
+    private ScriptC_TestNativeExp10Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeExp10(mRS);
+        scriptRelaxed = new ScriptC_TestNativeExp10Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeExp10FloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x90352c54l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeExp10FloatFloat(inV, out);
+            verifyResultsNativeExp10FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10FloatFloat(inV, out);
+            verifyResultsNativeExp10FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeExp10FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp10Float2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x54876b98l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeExp10Float2Float2(inV, out);
+            verifyResultsNativeExp10Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10Float2Float2(inV, out);
+            verifyResultsNativeExp10Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp10(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 checkNativeExp10Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp10Float3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4aa28c76l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeExp10Float3Float3(inV, out);
+            verifyResultsNativeExp10Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10Float3Float3(inV, out);
+            verifyResultsNativeExp10Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp10(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 checkNativeExp10Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp10Float4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x40bdad54l, -37, 37);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeExp10Float4Float4(inV, out);
+            verifyResultsNativeExp10Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp10Float4Float4(inV, out);
+            verifyResultsNativeExp10Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp10Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp10Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp10(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 checkNativeExp10Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeExp10() {
+        checkNativeExp10FloatFloat();
+        checkNativeExp10Float2Float2();
+        checkNativeExp10Float3Float3();
+        checkNativeExp10Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.rs
new file mode 100644
index 0000000..475d70c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeExp10FloatFloat(float inV) {
+    return native_exp10(inV);
+}
+
+float2 __attribute__((kernel)) testNativeExp10Float2Float2(float2 inV) {
+    return native_exp10(inV);
+}
+
+float3 __attribute__((kernel)) testNativeExp10Float3Float3(float3 inV) {
+    return native_exp10(inV);
+}
+
+float4 __attribute__((kernel)) testNativeExp10Float4Float4(float4 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
new file mode 100644
index 0000000..ff433f9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp10Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeExp10.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.java
new file mode 100644
index 0000000..3ed45e4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeExp2 extends RSBaseCompute {
+
+    private ScriptC_TestNativeExp2 script;
+    private ScriptC_TestNativeExp2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeExp2(mRS);
+        scriptRelaxed = new ScriptC_TestNativeExp2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeExp2FloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4c6a2bc5l, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeExp2FloatFloat(inV, out);
+            verifyResultsNativeExp2FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2FloatFloat(inV, out);
+            verifyResultsNativeExp2FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeExp2FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp2Float2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xaf5062c1l, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeExp2Float2Float2(inV, out);
+            verifyResultsNativeExp2Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2Float2Float2(inV, out);
+            verifyResultsNativeExp2Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp2(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 checkNativeExp2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp2Float3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xa56b839fl, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeExp2Float3Float3(inV, out);
+            verifyResultsNativeExp2Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2Float3Float3(inV, out);
+            verifyResultsNativeExp2Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp2(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 checkNativeExp2Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExp2Float4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x9b86a47dl, -125, 125);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeExp2Float4Float4(inV, out);
+            verifyResultsNativeExp2Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExp2Float4Float4(inV, out);
+            verifyResultsNativeExp2Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExp2Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExp2Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExp2(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 checkNativeExp2Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeExp2() {
+        checkNativeExp2FloatFloat();
+        checkNativeExp2Float2Float2();
+        checkNativeExp2Float3Float3();
+        checkNativeExp2Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.rs
new file mode 100644
index 0000000..21b8a54
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeExp2FloatFloat(float inV) {
+    return native_exp2(inV);
+}
+
+float2 __attribute__((kernel)) testNativeExp2Float2Float2(float2 inV) {
+    return native_exp2(inV);
+}
+
+float3 __attribute__((kernel)) testNativeExp2Float3Float3(float3 inV) {
+    return native_exp2(inV);
+}
+
+float4 __attribute__((kernel)) testNativeExp2Float4Float4(float4 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
new file mode 100644
index 0000000..ef9f713
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExp2Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeExp2.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpRelaxed.rs
new file mode 100644
index 0000000..f947bc4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeExp.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.java
new file mode 100644
index 0000000..bba5aeb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeExpm1 extends RSBaseCompute {
+
+    private ScriptC_TestNativeExpm1 script;
+    private ScriptC_TestNativeExpm1Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeExpm1(mRS);
+        scriptRelaxed = new ScriptC_TestNativeExpm1Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeExpm1FloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7094f34bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeExpm1FloatFloat(inV, out);
+            verifyResultsNativeExpm1FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpm1FloatFloat(inV, out);
+            verifyResultsNativeExpm1FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpm1FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExpm1(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeExpm1FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpm1Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe84b7997l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeExpm1Float2Float2(inV, out);
+            verifyResultsNativeExpm1Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpm1Float2Float2(inV, out);
+            verifyResultsNativeExpm1Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpm1Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExpm1(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 checkNativeExpm1Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpm1Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xde669a75l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeExpm1Float3Float3(inV, out);
+            verifyResultsNativeExpm1Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpm1Float3Float3(inV, out);
+            verifyResultsNativeExpm1Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpm1Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExpm1(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 checkNativeExpm1Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeExpm1Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd481bb53l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeExpm1Float4Float4(inV, out);
+            verifyResultsNativeExpm1Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeExpm1Float4Float4(inV, out);
+            verifyResultsNativeExpm1Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeExpm1Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeExpm1Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeExpm1(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 checkNativeExpm1Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeExpm1() {
+        checkNativeExpm1FloatFloat();
+        checkNativeExpm1Float2Float2();
+        checkNativeExpm1Float3Float3();
+        checkNativeExpm1Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.rs
new file mode 100644
index 0000000..848bac6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeExpm1FloatFloat(float inV) {
+    return native_expm1(inV);
+}
+
+float2 __attribute__((kernel)) testNativeExpm1Float2Float2(float2 inV) {
+    return native_expm1(inV);
+}
+
+float3 __attribute__((kernel)) testNativeExpm1Float3Float3(float3 inV) {
+    return native_expm1(inV);
+}
+
+float4 __attribute__((kernel)) testNativeExpm1Float4Float4(float4 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
new file mode 100644
index 0000000..8af4aaf
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeExpm1Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeExpm1.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.java
new file mode 100644
index 0000000..650233b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeHypot extends RSBaseCompute {
+
+    private ScriptC_TestNativeHypot script;
+    private ScriptC_TestNativeHypotRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeHypot(mRS);
+        scriptRelaxed = new ScriptC_TestNativeHypotRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inA;
+        public float inB;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeHypotFloatFloatFloat() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbdf66001l, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbdf66002l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testNativeHypotFloatFloatFloat(inA, out);
+            verifyResultsNativeHypotFloatFloatFloat(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testNativeHypotFloatFloatFloat(inA, out);
+            verifyResultsNativeHypotFloatFloatFloat(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeHypotFloatFloatFloat(Allocation inA, Allocation inB, Allocation out, boolean relaxed) {
+        float[] arrayInA = new float[INPUTSIZE * 1];
+        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 * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inA = arrayInA[i];
+                args.inB = arrayInB[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeHypot(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeHypotFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeHypotFloat2Float2Float2() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x60a50e4dl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x60a50e4el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testNativeHypotFloat2Float2Float2(inA, out);
+            verifyResultsNativeHypotFloat2Float2Float2(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testNativeHypotFloat2Float2Float2(inA, out);
+            verifyResultsNativeHypotFloat2Float2Float2(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeHypotFloat2Float2Float2(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 * 2];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeHypot(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeHypotFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeHypotFloat3Float3Float3() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x62830feel, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x62830fefl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testNativeHypotFloat3Float3Float3(inA, out);
+            verifyResultsNativeHypotFloat3Float3Float3(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testNativeHypotFloat3Float3Float3(inA, out);
+            verifyResultsNativeHypotFloat3Float3Float3(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeHypotFloat3Float3Float3(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeHypot(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeHypotFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeHypotFloat4Float4Float4() {
+        Allocation inA = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6461118fl, false);
+        Allocation inB = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x64611190l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInB(inB);
+            script.forEach_testNativeHypotFloat4Float4Float4(inA, out);
+            verifyResultsNativeHypotFloat4Float4Float4(inA, inB, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInB(inB);
+            scriptRelaxed.forEach_testNativeHypotFloat4Float4Float4(inA, out);
+            verifyResultsNativeHypotFloat4Float4Float4(inA, inB, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeHypotFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeHypotFloat4Float4Float4(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 * 4];
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativeHypot(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 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(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeHypotFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeHypot() {
+        checkNativeHypotFloatFloatFloat();
+        checkNativeHypotFloat2Float2Float2();
+        checkNativeHypotFloat3Float3Float3();
+        checkNativeHypotFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.rs
new file mode 100644
index 0000000..5e68656
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypot.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInB;
+
+float __attribute__((kernel)) testNativeHypotFloatFloatFloat(float inA, unsigned int x) {
+    float inB = rsGetElementAt_float(gAllocInB, x);
+    return native_hypot(inA, inB);
+}
+
+float2 __attribute__((kernel)) testNativeHypotFloat2Float2Float2(float2 inA, unsigned int x) {
+    float2 inB = rsGetElementAt_float2(gAllocInB, x);
+    return native_hypot(inA, inB);
+}
+
+float3 __attribute__((kernel)) testNativeHypotFloat3Float3Float3(float3 inA, unsigned int x) {
+    float3 inB = rsGetElementAt_float3(gAllocInB, x);
+    return native_hypot(inA, inB);
+}
+
+float4 __attribute__((kernel)) testNativeHypotFloat4Float4Float4(float4 inA, unsigned int x) {
+    float4 inB = rsGetElementAt_float4(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
new file mode 100644
index 0000000..999a5b2
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeHypotRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeHypot.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.java
new file mode 100644
index 0000000..176f75b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.java
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeLength extends RSBaseCompute {
+
+    private ScriptC_TestNativeLength script;
+    private ScriptC_TestNativeLengthRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeLength(mRS);
+        scriptRelaxed = new ScriptC_TestNativeLengthRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLengthFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd1df20ecl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLengthFloatFloat(inV, out);
+            verifyResultsNativeLengthFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLengthFloatFloat(inV, out);
+            verifyResultsNativeLengthFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLengthFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNativeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNativeLengthFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloat {
+        public float[] inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLengthFloat2Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf1b4824cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLengthFloat2Float(inV, out);
+            verifyResultsNativeLengthFloat2Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat2Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLengthFloat2Float(inV, out);
+            verifyResultsNativeLengthFloat2Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat2Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLengthFloat2Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[2];
+            // Fill args with the input values
+            for (int j = 0; j < 2 ; j++) {
+                args.inV[j] = arrayInV[i * 2 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNativeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNativeLengthFloat2Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLengthFloat3Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x50bb10adl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLengthFloat3Float(inV, out);
+            verifyResultsNativeLengthFloat3Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat3Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLengthFloat3Float(inV, out);
+            verifyResultsNativeLengthFloat3Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat3Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLengthFloat3Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[3];
+            // Fill args with the input values
+            for (int j = 0; j < 3 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNativeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNativeLengthFloat3Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLengthFloat4Float() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xafc19f0el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLengthFloat4Float(inV, out);
+            verifyResultsNativeLengthFloat4Float(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat4Float: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLengthFloat4Float(inV, out);
+            verifyResultsNativeLengthFloat4Float(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLengthFloat4Float: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLengthFloat4Float(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatNFloat args = new ArgumentsFloatNFloat();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[4];
+            // Fill args with the input values
+            for (int j = 0; j < 4 ; j++) {
+                args.inV[j] = arrayInV[i * 4 + j];
+            }
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNativeLength(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNativeLengthFloat4Float" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeLength() {
+        checkNativeLengthFloatFloat();
+        checkNativeLengthFloat2Float();
+        checkNativeLengthFloat3Float();
+        checkNativeLengthFloat4Float();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.rs
new file mode 100644
index 0000000..9245390
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLength.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeLengthFloatFloat(float inV) {
+    return native_length(inV);
+}
+
+float __attribute__((kernel)) testNativeLengthFloat2Float(float2 inV) {
+    return native_length(inV);
+}
+
+float __attribute__((kernel)) testNativeLengthFloat3Float(float3 inV) {
+    return native_length(inV);
+}
+
+float __attribute__((kernel)) testNativeLengthFloat4Float(float4 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
new file mode 100644
index 0000000..c7f8655
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLengthRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeLength.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.java
new file mode 100644
index 0000000..d1d108b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeLog extends RSBaseCompute {
+
+    private ScriptC_TestNativeLog script;
+    private ScriptC_TestNativeLogRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeLog(mRS);
+        scriptRelaxed = new ScriptC_TestNativeLogRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLogFloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe6418d2cl, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLogFloatFloat(inV, out);
+            verifyResultsNativeLogFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogFloatFloat(inV, out);
+            verifyResultsNativeLogFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeLogFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLogFloat2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xd3eee3b0l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeLogFloat2Float2(inV, out);
+            verifyResultsNativeLogFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogFloat2Float2(inV, out);
+            verifyResultsNativeLogFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog(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 checkNativeLogFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLogFloat3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xca0a048el, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeLogFloat3Float3(inV, out);
+            verifyResultsNativeLogFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogFloat3Float3(inV, out);
+            verifyResultsNativeLogFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog(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 checkNativeLogFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLogFloat4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xc025256cl, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeLogFloat4Float4(inV, out);
+            verifyResultsNativeLogFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLogFloat4Float4(inV, out);
+            verifyResultsNativeLogFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLogFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLogFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog(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 checkNativeLogFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeLog() {
+        checkNativeLogFloatFloat();
+        checkNativeLogFloat2Float2();
+        checkNativeLogFloat3Float3();
+        checkNativeLogFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.rs
new file mode 100644
index 0000000..bcf9a5f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeLogFloatFloat(float inV) {
+    return native_log(inV);
+}
+
+float2 __attribute__((kernel)) testNativeLogFloat2Float2(float2 inV) {
+    return native_log(inV);
+}
+
+float3 __attribute__((kernel)) testNativeLogFloat3Float3(float3 inV) {
+    return native_log(inV);
+}
+
+float4 __attribute__((kernel)) testNativeLogFloat4Float4(float4 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
new file mode 100644
index 0000000..4d4278b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeLog10 extends RSBaseCompute {
+
+    private ScriptC_TestNativeLog10 script;
+    private ScriptC_TestNativeLog10Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeLog10(mRS);
+        scriptRelaxed = new ScriptC_TestNativeLog10Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLog10FloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x83219dl, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLog10FloatFloat(inV, out);
+            verifyResultsNativeLog10FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10FloatFloat(inV, out);
+            verifyResultsNativeLog10FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog10(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeLog10FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog10Float2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x779807d9l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeLog10Float2Float2(inV, out);
+            verifyResultsNativeLog10Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10Float2Float2(inV, out);
+            verifyResultsNativeLog10Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog10(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 checkNativeLog10Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog10Float3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x6db328b7l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeLog10Float3Float3(inV, out);
+            verifyResultsNativeLog10Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10Float3Float3(inV, out);
+            verifyResultsNativeLog10Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog10(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 checkNativeLog10Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog10Float4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x63ce4995l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeLog10Float4Float4(inV, out);
+            verifyResultsNativeLog10Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog10Float4Float4(inV, out);
+            verifyResultsNativeLog10Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog10Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog10Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog10(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 checkNativeLog10Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeLog10() {
+        checkNativeLog10FloatFloat();
+        checkNativeLog10Float2Float2();
+        checkNativeLog10Float3Float3();
+        checkNativeLog10Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.rs
new file mode 100644
index 0000000..e02b98a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeLog10FloatFloat(float inV) {
+    return native_log10(inV);
+}
+
+float2 __attribute__((kernel)) testNativeLog10Float2Float2(float2 inV) {
+    return native_log10(inV);
+}
+
+float3 __attribute__((kernel)) testNativeLog10Float3Float3(float3 inV) {
+    return native_log10(inV);
+}
+
+float4 __attribute__((kernel)) testNativeLog10Float4Float4(float4 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
new file mode 100644
index 0000000..341414e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog10Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeLog10.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.java
new file mode 100644
index 0000000..eaed9c2
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeLog1p extends RSBaseCompute {
+
+    private ScriptC_TestNativeLog1p script;
+    private ScriptC_TestNativeLog1pRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeLog1p(mRS);
+        scriptRelaxed = new ScriptC_TestNativeLog1pRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLog1pFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe656185dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLog1pFloatFloat(inV, out);
+            verifyResultsNativeLog1pFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog1pFloatFloat(inV, out);
+            verifyResultsNativeLog1pFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog1pFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog1p(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeLog1pFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog1pFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x68503899l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeLog1pFloat2Float2(inV, out);
+            verifyResultsNativeLog1pFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog1pFloat2Float2(inV, out);
+            verifyResultsNativeLog1pFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog1pFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog1p(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 checkNativeLog1pFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog1pFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5e6b5977l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeLog1pFloat3Float3(inV, out);
+            verifyResultsNativeLog1pFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog1pFloat3Float3(inV, out);
+            verifyResultsNativeLog1pFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog1pFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog1p(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 checkNativeLog1pFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog1pFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x54867a55l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeLog1pFloat4Float4(inV, out);
+            verifyResultsNativeLog1pFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog1pFloat4Float4(inV, out);
+            verifyResultsNativeLog1pFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog1pFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog1pFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog1p(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 checkNativeLog1pFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeLog1p() {
+        checkNativeLog1pFloatFloat();
+        checkNativeLog1pFloat2Float2();
+        checkNativeLog1pFloat3Float3();
+        checkNativeLog1pFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.rs
new file mode 100644
index 0000000..3a528db
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1p.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeLog1pFloatFloat(float inV) {
+    return native_log1p(inV);
+}
+
+float2 __attribute__((kernel)) testNativeLog1pFloat2Float2(float2 inV) {
+    return native_log1p(inV);
+}
+
+float3 __attribute__((kernel)) testNativeLog1pFloat3Float3(float3 inV) {
+    return native_log1p(inV);
+}
+
+float4 __attribute__((kernel)) testNativeLog1pFloat4Float4(float4 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
new file mode 100644
index 0000000..ff1a719
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog1pRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeLog1p.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.java
new file mode 100644
index 0000000..ba811a8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeLog2 extends RSBaseCompute {
+
+    private ScriptC_TestNativeLog2 script;
+    private ScriptC_TestNativeLog2Relaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeLog2(mRS);
+        scriptRelaxed = new ScriptC_TestNativeLog2Relaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeLog2FloatFloat() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x54fade20l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeLog2FloatFloat(inV, out);
+            verifyResultsNativeLog2FloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2FloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2FloatFloat(inV, out);
+            verifyResultsNativeLog2FloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2FloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2FloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog2(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeLog2FloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog2Float2Float2() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8c689604l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeLog2Float2Float2(inV, out);
+            verifyResultsNativeLog2Float2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2Float2Float2(inV, out);
+            verifyResultsNativeLog2Float2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2Float2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog2(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 checkNativeLog2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog2Float3Float3() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8283b6e2l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeLog2Float3Float3(inV, out);
+            verifyResultsNativeLog2Float3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2Float3Float3(inV, out);
+            verifyResultsNativeLog2Float3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2Float3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog2(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 checkNativeLog2Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeLog2Float4Float4() {
+        Allocation inV = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x789ed7c0l, 10e-10, 10e10);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeLog2Float4Float4(inV, out);
+            verifyResultsNativeLog2Float4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeLog2Float4Float4(inV, out);
+            verifyResultsNativeLog2Float4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeLog2Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeLog2Float4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeLog2(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 checkNativeLog2Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeLog2() {
+        checkNativeLog2FloatFloat();
+        checkNativeLog2Float2Float2();
+        checkNativeLog2Float3Float3();
+        checkNativeLog2Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.rs
new file mode 100644
index 0000000..0410ef4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeLog2FloatFloat(float inV) {
+    return native_log2(inV);
+}
+
+float2 __attribute__((kernel)) testNativeLog2Float2Float2(float2 inV) {
+    return native_log2(inV);
+}
+
+float3 __attribute__((kernel)) testNativeLog2Float3Float3(float3 inV) {
+    return native_log2(inV);
+}
+
+float4 __attribute__((kernel)) testNativeLog2Float4Float4(float4 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
new file mode 100644
index 0000000..148796b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLog2Relaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeLog2.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLogRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLogRelaxed.rs
new file mode 100644
index 0000000..065dece
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeLogRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeLog.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.java
new file mode 100644
index 0000000..d3ec54c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeNormalize extends RSBaseCompute {
+
+    private ScriptC_TestNativeNormalize script;
+    private ScriptC_TestNativeNormalizeRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeNormalize(mRS);
+        scriptRelaxed = new ScriptC_TestNativeNormalizeRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeNormalizeFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7e4aac53l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeNormalizeFloatFloat(inV, out);
+            verifyResultsNativeNormalizeFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeNormalizeFloatFloat(inV, out);
+            verifyResultsNativeNormalizeFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeNormalizeFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNativeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNativeNormalizeFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloatN {
+        public float[] inV;
+        public Target.Floaty[] out;
+    }
+
+    private void checkNativeNormalizeFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xedd0e45fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeNormalizeFloat2Float2(inV, out);
+            verifyResultsNativeNormalizeFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeNormalizeFloat2Float2(inV, out);
+            verifyResultsNativeNormalizeFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeNormalizeFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[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];
+            }
+            Target target = new Target(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(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]);
+                        if (!args.out[j].couldBe(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 checkNativeNormalizeFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeNormalizeFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe3ec053dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeNormalizeFloat3Float3(inV, out);
+            verifyResultsNativeNormalizeFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeNormalizeFloat3Float3(inV, out);
+            verifyResultsNativeNormalizeFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeNormalizeFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[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];
+            }
+            Target target = new Target(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(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]);
+                        if (!args.out[j].couldBe(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 checkNativeNormalizeFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeNormalizeFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xda07261bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeNormalizeFloat4Float4(inV, out);
+            verifyResultsNativeNormalizeFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeNormalizeFloat4Float4(inV, out);
+            verifyResultsNativeNormalizeFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeNormalizeFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeNormalizeFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[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];
+            }
+            Target target = new Target(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(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]);
+                        if (!args.out[j].couldBe(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 checkNativeNormalizeFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeNormalize() {
+        checkNativeNormalizeFloatFloat();
+        checkNativeNormalizeFloat2Float2();
+        checkNativeNormalizeFloat3Float3();
+        checkNativeNormalizeFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.rs
new file mode 100644
index 0000000..ba169bd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalize.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeNormalizeFloatFloat(float inV) {
+    return native_normalize(inV);
+}
+
+float2 __attribute__((kernel)) testNativeNormalizeFloat2Float2(float2 inV) {
+    return native_normalize(inV);
+}
+
+float3 __attribute__((kernel)) testNativeNormalizeFloat3Float3(float3 inV) {
+    return native_normalize(inV);
+}
+
+float4 __attribute__((kernel)) testNativeNormalizeFloat4Float4(float4 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
new file mode 100644
index 0000000..0b85dbb
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeNormalizeRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeNormalize.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.java
new file mode 100644
index 0000000..930c892
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativePowr extends RSBaseCompute {
+
+    private ScriptC_TestNativePowr script;
+    private ScriptC_TestNativePowrRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativePowr(mRS);
+        scriptRelaxed = new ScriptC_TestNativePowrRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inBase;
+        public float inExponent;
+        public Target.Floaty out;
+    }
+
+    private void checkNativePowrFloatFloatFloat() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x834d1839l, 0, 256);
+        Allocation inExponent = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xf9181f0fl, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testNativePowrFloatFloatFloat(inBase, out);
+            verifyResultsNativePowrFloatFloatFloat(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testNativePowrFloatFloatFloat(inBase, out);
+            verifyResultsNativePowrFloatFloatFloat(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativePowrFloatFloatFloat(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inBase = arrayInBase[i];
+                args.inExponent = arrayInExponent[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativePowrFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativePowrFloat2Float2Float2() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x283b11a5l, 0, 256);
+        Allocation inExponent = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb67d4abbl, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testNativePowrFloat2Float2Float2(inBase, out);
+            verifyResultsNativePowrFloat2Float2Float2(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testNativePowrFloat2Float2Float2(inBase, out);
+            verifyResultsNativePowrFloat2Float2Float2(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativePowrFloat2Float2Float2(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativePowr(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 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]);
+                        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 checkNativePowrFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativePowrFloat3Float3Float3() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x10aef718l, 0, 256);
+        Allocation inExponent = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd9fcd3el, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testNativePowrFloat3Float3Float3(inBase, out);
+            verifyResultsNativePowrFloat3Float3Float3(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testNativePowrFloat3Float3Float3(inBase, out);
+            verifyResultsNativePowrFloat3Float3Float3(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativePowrFloat3Float3Float3(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativePowr(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 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]);
+                        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 checkNativePowrFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativePowrFloat4Float4Float4() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf922dc8bl, 0, 256);
+        Allocation inExponent = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x64c24fc1l, -15, 15);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testNativePowrFloat4Float4Float4(inBase, out);
+            verifyResultsNativePowrFloat4Float4Float4(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testNativePowrFloat4Float4Float4(inBase, out);
+            verifyResultsNativePowrFloat4Float4Float4(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativePowrFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativePowrFloat4Float4Float4(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNativePowr(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 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]);
+                        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 checkNativePowrFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativePowr() {
+        checkNativePowrFloatFloatFloat();
+        checkNativePowrFloat2Float2Float2();
+        checkNativePowrFloat3Float3Float3();
+        checkNativePowrFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.rs
new file mode 100644
index 0000000..4bedb98
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowr.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInExponent;
+
+float __attribute__((kernel)) testNativePowrFloatFloatFloat(float inBase, unsigned int x) {
+    float inExponent = rsGetElementAt_float(gAllocInExponent, x);
+    return native_powr(inBase, inExponent);
+}
+
+float2 __attribute__((kernel)) testNativePowrFloat2Float2Float2(float2 inBase, unsigned int x) {
+    float2 inExponent = rsGetElementAt_float2(gAllocInExponent, x);
+    return native_powr(inBase, inExponent);
+}
+
+float3 __attribute__((kernel)) testNativePowrFloat3Float3Float3(float3 inBase, unsigned int x) {
+    float3 inExponent = rsGetElementAt_float3(gAllocInExponent, x);
+    return native_powr(inBase, inExponent);
+}
+
+float4 __attribute__((kernel)) testNativePowrFloat4Float4Float4(float4 inBase, unsigned int x) {
+    float4 inExponent = rsGetElementAt_float4(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
new file mode 100644
index 0000000..c453409
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativePowrRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativePowr.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.java
new file mode 100644
index 0000000..3793956
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeRecip extends RSBaseCompute {
+
+    private ScriptC_TestNativeRecip script;
+    private ScriptC_TestNativeRecipRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeRecip(mRS);
+        scriptRelaxed = new ScriptC_TestNativeRecipRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeRecipFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xcc4ed441l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeRecipFloatFloat(inV, out);
+            verifyResultsNativeRecipFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRecipFloatFloat(inV, out);
+            verifyResultsNativeRecipFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRecipFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeRecip(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeRecipFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRecipFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x69d54a5dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeRecipFloat2Float2(inV, out);
+            verifyResultsNativeRecipFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRecipFloat2Float2(inV, out);
+            verifyResultsNativeRecipFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRecipFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeRecip(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 checkNativeRecipFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRecipFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5ff06b3bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeRecipFloat3Float3(inV, out);
+            verifyResultsNativeRecipFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRecipFloat3Float3(inV, out);
+            verifyResultsNativeRecipFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRecipFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeRecip(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 checkNativeRecipFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRecipFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x560b8c19l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeRecipFloat4Float4(inV, out);
+            verifyResultsNativeRecipFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRecipFloat4Float4(inV, out);
+            verifyResultsNativeRecipFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRecipFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRecipFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeRecip(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 checkNativeRecipFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeRecip() {
+        checkNativeRecipFloatFloat();
+        checkNativeRecipFloat2Float2();
+        checkNativeRecipFloat3Float3();
+        checkNativeRecipFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.rs
new file mode 100644
index 0000000..7eb6419
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecip.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeRecipFloatFloat(float inV) {
+    return native_recip(inV);
+}
+
+float2 __attribute__((kernel)) testNativeRecipFloat2Float2(float2 inV) {
+    return native_recip(inV);
+}
+
+float3 __attribute__((kernel)) testNativeRecipFloat3Float3(float3 inV) {
+    return native_recip(inV);
+}
+
+float4 __attribute__((kernel)) testNativeRecipFloat4Float4(float4 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
new file mode 100644
index 0000000..432a3a9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRecipRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeRecip.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.java
new file mode 100644
index 0000000..09f6c516
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeRootn extends RSBaseCompute {
+
+    private ScriptC_TestNativeRootn script;
+    private ScriptC_TestNativeRootnRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeRootn(mRS);
+        scriptRelaxed = new ScriptC_TestNativeRootnRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inV;
+        public int inN;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeRootnFloatIntFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x237ac0f1l, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x237ac0e9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testNativeRootnFloatIntFloat(inV, out);
+            verifyResultsNativeRootnFloatIntFloat(inV, inN, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testNativeRootnFloatIntFloat(inV, out);
+            verifyResultsNativeRootnFloatIntFloat(inV, inN, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRootnFloatIntFloat(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayInN = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInN, (int) 42);
+        inN.copyTo(arrayInN);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i];
+                args.inN = arrayInN[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeRootn(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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("Input inN: ");
+                        appendVariableToMessage(message, args.inN);
+                        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]);
+                        if (!args.out.couldBe(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 checkNativeRootnFloatIntFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRootnFloat2Int2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x4afd5bcdl, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x4afd5bc5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testNativeRootnFloat2Int2Float2(inV, out);
+            verifyResultsNativeRootnFloat2Int2Float2(inV, inN, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testNativeRootnFloat2Int2Float2(inV, out);
+            verifyResultsNativeRootnFloat2Int2Float2(inV, inN, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRootnFloat2Int2Float2(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayInN = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInN, (int) 42);
+        inN.copyTo(arrayInN);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computeNativeRootn(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("Input inN: ");
+                        appendVariableToMessage(message, args.inN);
+                        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 checkNativeRootnFloat2Int2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRootnFloat3Int3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x40afc886l, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x40afc87el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testNativeRootnFloat3Int3Float3(inV, out);
+            verifyResultsNativeRootnFloat3Int3Float3(inV, inN, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testNativeRootnFloat3Int3Float3(inV, out);
+            verifyResultsNativeRootnFloat3Int3Float3(inV, inN, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRootnFloat3Int3Float3(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayInN = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInN, (int) 42);
+        inN.copyTo(arrayInN);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computeNativeRootn(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("Input inN: ");
+                        appendVariableToMessage(message, args.inN);
+                        message.append("\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 checkNativeRootnFloat3Int3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRootnFloat4Int4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x3662353fl, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x36623537l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testNativeRootnFloat4Int4Float4(inV, out);
+            verifyResultsNativeRootnFloat4Int4Float4(inV, inN, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testNativeRootnFloat4Int4Float4(inV, out);
+            verifyResultsNativeRootnFloat4Int4Float4(inV, inN, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRootnFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRootnFloat4Int4Float4(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayInN = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInN, (int) 42);
+        inN.copyTo(arrayInN);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computeNativeRootn(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("Input inN: ");
+                        appendVariableToMessage(message, args.inN);
+                        message.append("\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 checkNativeRootnFloat4Int4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeRootn() {
+        checkNativeRootnFloatIntFloat();
+        checkNativeRootnFloat2Int2Float2();
+        checkNativeRootnFloat3Int3Float3();
+        checkNativeRootnFloat4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.rs
new file mode 100644
index 0000000..dcd3e52
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootn.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInN;
+
+float __attribute__((kernel)) testNativeRootnFloatIntFloat(float inV, unsigned int x) {
+    int inN = rsGetElementAt_int(gAllocInN, x);
+    return native_rootn(inV, inN);
+}
+
+float2 __attribute__((kernel)) testNativeRootnFloat2Int2Float2(float2 inV, unsigned int x) {
+    int2 inN = rsGetElementAt_int2(gAllocInN, x);
+    return native_rootn(inV, inN);
+}
+
+float3 __attribute__((kernel)) testNativeRootnFloat3Int3Float3(float3 inV, unsigned int x) {
+    int3 inN = rsGetElementAt_int3(gAllocInN, x);
+    return native_rootn(inV, inN);
+}
+
+float4 __attribute__((kernel)) testNativeRootnFloat4Int4Float4(float4 inV, unsigned int x) {
+    int4 inN = rsGetElementAt_int4(gAllocInN, x);
+    return native_rootn(inV, inN);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootnRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootnRelaxed.rs
new file mode 100644
index 0000000..ffb70c0f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRootnRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeRootn.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.java
new file mode 100644
index 0000000..fd157b4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeRsqrt extends RSBaseCompute {
+
+    private ScriptC_TestNativeRsqrt script;
+    private ScriptC_TestNativeRsqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeRsqrt(mRS);
+        scriptRelaxed = new ScriptC_TestNativeRsqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeRsqrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x795084f6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeRsqrtFloatFloat(inV, out);
+            verifyResultsNativeRsqrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRsqrtFloatFloat(inV, out);
+            verifyResultsNativeRsqrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRsqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeRsqrtFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRsqrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xfb0a95aal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeRsqrtFloat2Float2(inV, out);
+            verifyResultsNativeRsqrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRsqrtFloat2Float2(inV, out);
+            verifyResultsNativeRsqrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRsqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeRsqrt(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 checkNativeRsqrtFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRsqrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf125b688l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeRsqrtFloat3Float3(inV, out);
+            verifyResultsNativeRsqrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRsqrtFloat3Float3(inV, out);
+            verifyResultsNativeRsqrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRsqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeRsqrt(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 checkNativeRsqrtFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeRsqrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xe740d766l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeRsqrtFloat4Float4(inV, out);
+            verifyResultsNativeRsqrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeRsqrtFloat4Float4(inV, out);
+            verifyResultsNativeRsqrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeRsqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeRsqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeRsqrt(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 checkNativeRsqrtFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeRsqrt() {
+        checkNativeRsqrtFloatFloat();
+        checkNativeRsqrtFloat2Float2();
+        checkNativeRsqrtFloat3Float3();
+        checkNativeRsqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.rs
new file mode 100644
index 0000000..ce49268
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrt.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeRsqrtFloatFloat(float inV) {
+    return native_rsqrt(inV);
+}
+
+float2 __attribute__((kernel)) testNativeRsqrtFloat2Float2(float2 inV) {
+    return native_rsqrt(inV);
+}
+
+float3 __attribute__((kernel)) testNativeRsqrtFloat3Float3(float3 inV) {
+    return native_rsqrt(inV);
+}
+
+float4 __attribute__((kernel)) testNativeRsqrtFloat4Float4(float4 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
new file mode 100644
index 0000000..6228ce5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeRsqrtRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeRsqrt.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.java
new file mode 100644
index 0000000..a49cd12
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeSin extends RSBaseCompute {
+
+    private ScriptC_TestNativeSin script;
+    private ScriptC_TestNativeSinRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeSin(mRS);
+        scriptRelaxed = new ScriptC_TestNativeSinRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSinFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9f3e52c8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeSinFloatFloat(inV, out);
+            verifyResultsNativeSinFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinFloatFloat(inV, out);
+            verifyResultsNativeSinFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeSinFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xed9e276cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeSinFloat2Float2(inV, out);
+            verifyResultsNativeSinFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinFloat2Float2(inV, out);
+            verifyResultsNativeSinFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSin(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 checkNativeSinFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe3b9484al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeSinFloat3Float3(inV, out);
+            verifyResultsNativeSinFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinFloat3Float3(inV, out);
+            verifyResultsNativeSinFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSin(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 checkNativeSinFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd9d46928l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeSinFloat4Float4(inV, out);
+            verifyResultsNativeSinFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinFloat4Float4(inV, out);
+            verifyResultsNativeSinFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSin(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 checkNativeSinFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeSin() {
+        checkNativeSinFloatFloat();
+        checkNativeSinFloat2Float2();
+        checkNativeSinFloat3Float3();
+        checkNativeSinFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.rs
new file mode 100644
index 0000000..abd9be7
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSin.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeSinFloatFloat(float inV) {
+    return native_sin(inV);
+}
+
+float2 __attribute__((kernel)) testNativeSinFloat2Float2(float2 inV) {
+    return native_sin(inV);
+}
+
+float3 __attribute__((kernel)) testNativeSinFloat3Float3(float3 inV) {
+    return native_sin(inV);
+}
+
+float4 __attribute__((kernel)) testNativeSinFloat4Float4(float4 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
new file mode 100644
index 0000000..d9d8598
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeSin.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.java
new file mode 100644
index 0000000..60c746b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeSincos extends RSBaseCompute {
+
+    private ScriptC_TestNativeSincos script;
+    private ScriptC_TestNativeSincosRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeSincos(mRS);
+        scriptRelaxed = new ScriptC_TestNativeSincosRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inV;
+        public Target.Floaty outCos;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSincosFloatFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x6436cc13l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testNativeSincosFloatFloatFloat(inV, out);
+            verifyResultsNativeSincosFloatFloatFloat(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testNativeSincosFloatFloatFloat(inV, out);
+            verifyResultsNativeSincosFloatFloatFloat(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSincosFloatFloatFloat(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutCos = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOutCos, (float) 42);
+        outCos.copyTo(arrayOutCos);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(arrayOutCos[i * 1 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                    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]);
+                        if (!args.outCos.couldBe(arrayOutCos[i * 1 + j], 0.0005)) {
+                            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]);
+                        if (!args.out.couldBe(arrayOut[i * 1 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSincosFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSincosFloat2Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xda676ea9l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testNativeSincosFloat2Float2Float2(inV, out);
+            verifyResultsNativeSincosFloat2Float2Float2(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testNativeSincosFloat2Float2Float2(inV, out);
+            verifyResultsNativeSincosFloat2Float2Float2(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSincosFloat2Float2Float2(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutCos = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayOutCos, (float) 42);
+        outCos.copyTo(arrayOutCos);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(arrayOutCos[i * 2 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                    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]);
+                        if (!args.outCos.couldBe(arrayOutCos[i * 2 + j], 0.0005)) {
+                            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]);
+                        if (!args.out.couldBe(arrayOut[i * 2 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSincosFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSincosFloat3Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xdc45704al, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testNativeSincosFloat3Float3Float3(inV, out);
+            verifyResultsNativeSincosFloat3Float3Float3(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testNativeSincosFloat3Float3Float3(inV, out);
+            verifyResultsNativeSincosFloat3Float3Float3(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSincosFloat3Float3Float3(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutCos = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOutCos, (float) 42);
+        outCos.copyTo(arrayOutCos);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(arrayOutCos[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    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]);
+                        if (!args.outCos.couldBe(arrayOutCos[i * 4 + j], 0.0005)) {
+                            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]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSincosFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSincosFloat4Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xde2371ebl, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testNativeSincosFloat4Float4Float4(inV, out);
+            verifyResultsNativeSincosFloat4Float4Float4(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testNativeSincosFloat4Float4Float4(inV, out);
+            verifyResultsNativeSincosFloat4Float4Float4(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSincosFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSincosFloat4Float4Float4(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutCos = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOutCos, (float) 42);
+        outCos.copyTo(arrayOutCos);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(arrayOutCos[i * 4 + j], 0.0005)) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                    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]);
+                        if (!args.outCos.couldBe(arrayOutCos[i * 4 + j], 0.0005)) {
+                            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]);
+                        if (!args.out.couldBe(arrayOut[i * 4 + j], 0.0005)) {
+                            message.append(" FAIL");
+                        }
+                        message.append("\n");
+                        message.append("Errors at");
+                    }
+                    message.append(" [");
+                    message.append(Integer.toString(i));
+                    message.append(", ");
+                    message.append(Integer.toString(j));
+                    message.append("]");
+                }
+            }
+        }
+        assertFalse("Incorrect output for checkNativeSincosFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeSincos() {
+        checkNativeSincosFloatFloatFloat();
+        checkNativeSincosFloat2Float2Float2();
+        checkNativeSincosFloat3Float3Float3();
+        checkNativeSincosFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.rs
new file mode 100644
index 0000000..01d2b0a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincos.rs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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)
+
+rs_allocation gAllocOutCos;
+
+float __attribute__((kernel)) testNativeSincosFloatFloatFloat(float inV, unsigned int x) {
+    float outCos = 0;
+    float out = native_sincos(inV, &outCos);
+    rsSetElementAt_float(gAllocOutCos, outCos, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testNativeSincosFloat2Float2Float2(float2 inV, unsigned int x) {
+    float2 outCos = 0;
+    float2 out = native_sincos(inV, &outCos);
+    rsSetElementAt_float2(gAllocOutCos, outCos, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testNativeSincosFloat3Float3Float3(float3 inV, unsigned int x) {
+    float3 outCos = 0;
+    float3 out = native_sincos(inV, &outCos);
+    rsSetElementAt_float3(gAllocOutCos, outCos, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testNativeSincosFloat4Float4Float4(float4 inV, unsigned int x) {
+    float4 outCos = 0;
+    float4 out = native_sincos(inV, &outCos);
+    rsSetElementAt_float4(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
new file mode 100644
index 0000000..0b9fe34
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSincosRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeSincos.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.java
new file mode 100644
index 0000000..28083e9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeSinh extends RSBaseCompute {
+
+    private ScriptC_TestNativeSinh script;
+    private ScriptC_TestNativeSinhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeSinh(mRS);
+        scriptRelaxed = new ScriptC_TestNativeSinhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSinhFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x515a0f86l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeSinhFloatFloat(inV, out);
+            verifyResultsNativeSinhFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinhFloatFloat(inV, out);
+            verifyResultsNativeSinhFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinhFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeSinhFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinhFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x57f45fbal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeSinhFloat2Float2(inV, out);
+            verifyResultsNativeSinhFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinhFloat2Float2(inV, out);
+            verifyResultsNativeSinhFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinhFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSinh(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 checkNativeSinhFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinhFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x4e0f8098l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeSinhFloat3Float3(inV, out);
+            verifyResultsNativeSinhFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinhFloat3Float3(inV, out);
+            verifyResultsNativeSinhFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinhFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSinh(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 checkNativeSinhFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinhFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x442aa176l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeSinhFloat4Float4(inV, out);
+            verifyResultsNativeSinhFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinhFloat4Float4(inV, out);
+            verifyResultsNativeSinhFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinhFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSinh(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 checkNativeSinhFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeSinh() {
+        checkNativeSinhFloatFloat();
+        checkNativeSinhFloat2Float2();
+        checkNativeSinhFloat3Float3();
+        checkNativeSinhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.rs
new file mode 100644
index 0000000..0440188
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeSinhFloatFloat(float inV) {
+    return native_sinh(inV);
+}
+
+float2 __attribute__((kernel)) testNativeSinhFloat2Float2(float2 inV) {
+    return native_sinh(inV);
+}
+
+float3 __attribute__((kernel)) testNativeSinhFloat3Float3(float3 inV) {
+    return native_sinh(inV);
+}
+
+float4 __attribute__((kernel)) testNativeSinhFloat4Float4(float4 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
new file mode 100644
index 0000000..45bc8ce
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinhRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeSinh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.java
new file mode 100644
index 0000000..8cd1abf
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeSinpi extends RSBaseCompute {
+
+    private ScriptC_TestNativeSinpi script;
+    private ScriptC_TestNativeSinpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeSinpi(mRS);
+        scriptRelaxed = new ScriptC_TestNativeSinpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSinpiFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xaee7fd93l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeSinpiFloatFloat(inV, out);
+            verifyResultsNativeSinpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinpiFloatFloat(inV, out);
+            verifyResultsNativeSinpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeSinpiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinpiFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe10bb9fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeSinpiFloat2Float2(inV, out);
+            verifyResultsNativeSinpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinpiFloat2Float2(inV, out);
+            verifyResultsNativeSinpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSinpi(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 checkNativeSinpiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinpiFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x42bdc7dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeSinpiFloat3Float3(inV, out);
+            verifyResultsNativeSinpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinpiFloat3Float3(inV, out);
+            verifyResultsNativeSinpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSinpi(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 checkNativeSinpiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSinpiFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfa46fd5bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeSinpiFloat4Float4(inV, out);
+            verifyResultsNativeSinpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSinpiFloat4Float4(inV, out);
+            verifyResultsNativeSinpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSinpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSinpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSinpi(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 checkNativeSinpiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeSinpi() {
+        checkNativeSinpiFloatFloat();
+        checkNativeSinpiFloat2Float2();
+        checkNativeSinpiFloat3Float3();
+        checkNativeSinpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.rs
new file mode 100644
index 0000000..7cd4758
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeSinpiFloatFloat(float inV) {
+    return native_sinpi(inV);
+}
+
+float2 __attribute__((kernel)) testNativeSinpiFloat2Float2(float2 inV) {
+    return native_sinpi(inV);
+}
+
+float3 __attribute__((kernel)) testNativeSinpiFloat3Float3(float3 inV) {
+    return native_sinpi(inV);
+}
+
+float4 __attribute__((kernel)) testNativeSinpiFloat4Float4(float4 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
new file mode 100644
index 0000000..455269d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSinpiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeSinpi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.java
new file mode 100644
index 0000000..75a569f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeSqrt extends RSBaseCompute {
+
+    private ScriptC_TestNativeSqrt script;
+    private ScriptC_TestNativeSqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeSqrt(mRS);
+        scriptRelaxed = new ScriptC_TestNativeSqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeSqrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x642f9b06l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeSqrtFloatFloat(inV, out);
+            verifyResultsNativeSqrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSqrtFloatFloat(inV, out);
+            verifyResultsNativeSqrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeSqrtFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSqrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6050ef3al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeSqrtFloat2Float2(inV, out);
+            verifyResultsNativeSqrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSqrtFloat2Float2(inV, out);
+            verifyResultsNativeSqrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSqrt(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 checkNativeSqrtFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSqrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x566c1018l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeSqrtFloat3Float3(inV, out);
+            verifyResultsNativeSqrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSqrtFloat3Float3(inV, out);
+            verifyResultsNativeSqrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSqrt(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 checkNativeSqrtFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeSqrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4c8730f6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeSqrtFloat4Float4(inV, out);
+            verifyResultsNativeSqrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeSqrtFloat4Float4(inV, out);
+            verifyResultsNativeSqrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeSqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeSqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeSqrt(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 checkNativeSqrtFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeSqrt() {
+        checkNativeSqrtFloatFloat();
+        checkNativeSqrtFloat2Float2();
+        checkNativeSqrtFloat3Float3();
+        checkNativeSqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.rs
new file mode 100644
index 0000000..e5dcc4e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrt.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeSqrtFloatFloat(float inV) {
+    return native_sqrt(inV);
+}
+
+float2 __attribute__((kernel)) testNativeSqrtFloat2Float2(float2 inV) {
+    return native_sqrt(inV);
+}
+
+float3 __attribute__((kernel)) testNativeSqrtFloat3Float3(float3 inV) {
+    return native_sqrt(inV);
+}
+
+float4 __attribute__((kernel)) testNativeSqrtFloat4Float4(float4 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
new file mode 100644
index 0000000..1db9ebd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeSqrtRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeSqrt.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.java
new file mode 100644
index 0000000..390538a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeTan extends RSBaseCompute {
+
+    private ScriptC_TestNativeTan script;
+    private ScriptC_TestNativeTanRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeTan(mRS);
+        scriptRelaxed = new ScriptC_TestNativeTanRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeTanFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x37b34543l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeTanFloatFloat(inV, out);
+            verifyResultsNativeTanFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanFloatFloat(inV, out);
+            verifyResultsNativeTanFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeTanFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x124981cfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeTanFloat2Float2(inV, out);
+            verifyResultsNativeTanFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanFloat2Float2(inV, out);
+            verifyResultsNativeTanFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTan(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 checkNativeTanFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x864a2adl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeTanFloat3Float3(inV, out);
+            verifyResultsNativeTanFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanFloat3Float3(inV, out);
+            verifyResultsNativeTanFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTan(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 checkNativeTanFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xfe7fc38bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeTanFloat4Float4(inV, out);
+            verifyResultsNativeTanFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanFloat4Float4(inV, out);
+            verifyResultsNativeTanFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTan(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 checkNativeTanFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeTan() {
+        checkNativeTanFloatFloat();
+        checkNativeTanFloat2Float2();
+        checkNativeTanFloat3Float3();
+        checkNativeTanFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.rs
new file mode 100644
index 0000000..603ed8c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTan.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeTanFloatFloat(float inV) {
+    return native_tan(inV);
+}
+
+float2 __attribute__((kernel)) testNativeTanFloat2Float2(float2 inV) {
+    return native_tan(inV);
+}
+
+float3 __attribute__((kernel)) testNativeTanFloat3Float3(float3 inV) {
+    return native_tan(inV);
+}
+
+float4 __attribute__((kernel)) testNativeTanFloat4Float4(float4 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
new file mode 100644
index 0000000..b098bd5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeTan.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.java
new file mode 100644
index 0000000..4b18a96
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeTanh extends RSBaseCompute {
+
+    private ScriptC_TestNativeTanh script;
+    private ScriptC_TestNativeTanhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeTanh(mRS);
+        scriptRelaxed = new ScriptC_TestNativeTanhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeTanhFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xecfeca2fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeTanhFloatFloat(inV, out);
+            verifyResultsNativeTanhFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanhFloatFloat(inV, out);
+            verifyResultsNativeTanhFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanhFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeTanhFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanhFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x80bc8e5bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeTanhFloat2Float2(inV, out);
+            verifyResultsNativeTanhFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanhFloat2Float2(inV, out);
+            verifyResultsNativeTanhFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanhFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTanh(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 checkNativeTanhFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanhFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x76d7af39l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeTanhFloat3Float3(inV, out);
+            verifyResultsNativeTanhFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanhFloat3Float3(inV, out);
+            verifyResultsNativeTanhFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanhFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTanh(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 checkNativeTanhFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanhFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x6cf2d017l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeTanhFloat4Float4(inV, out);
+            verifyResultsNativeTanhFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanhFloat4Float4(inV, out);
+            verifyResultsNativeTanhFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanhFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTanh(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 checkNativeTanhFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeTanh() {
+        checkNativeTanhFloatFloat();
+        checkNativeTanhFloat2Float2();
+        checkNativeTanhFloat3Float3();
+        checkNativeTanhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.rs
new file mode 100644
index 0000000..027a89f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeTanhFloatFloat(float inV) {
+    return native_tanh(inV);
+}
+
+float2 __attribute__((kernel)) testNativeTanhFloat2Float2(float2 inV) {
+    return native_tanh(inV);
+}
+
+float3 __attribute__((kernel)) testNativeTanhFloat3Float3(float3 inV) {
+    return native_tanh(inV);
+}
+
+float4 __attribute__((kernel)) testNativeTanhFloat4Float4(float4 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
new file mode 100644
index 0000000..f18baa7
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanhRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeTanh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.java
new file mode 100644
index 0000000..dcf2e608
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNativeTanpi extends RSBaseCompute {
+
+    private ScriptC_TestNativeTanpi script;
+    private ScriptC_TestNativeTanpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNativeTanpi(mRS);
+        scriptRelaxed = new ScriptC_TestNativeTanpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNativeTanpiFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd39357f6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNativeTanpiFloatFloat(inV, out);
+            verifyResultsNativeTanpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanpiFloatFloat(inV, out);
+            verifyResultsNativeTanpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkNativeTanpiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanpiFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xe7b090aal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNativeTanpiFloat2Float2(inV, out);
+            verifyResultsNativeTanpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanpiFloat2Float2(inV, out);
+            verifyResultsNativeTanpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTanpi(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 checkNativeTanpiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanpiFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xddcbb188l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNativeTanpiFloat3Float3(inV, out);
+            verifyResultsNativeTanpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanpiFloat3Float3(inV, out);
+            verifyResultsNativeTanpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTanpi(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 checkNativeTanpiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNativeTanpiFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd3e6d266l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNativeTanpiFloat4Float4(inV, out);
+            verifyResultsNativeTanpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNativeTanpiFloat4Float4(inV, out);
+            verifyResultsNativeTanpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNativeTanpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNativeTanpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNativeTanpi(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 checkNativeTanpiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNativeTanpi() {
+        checkNativeTanpiFloatFloat();
+        checkNativeTanpiFloat2Float2();
+        checkNativeTanpiFloat3Float3();
+        checkNativeTanpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.rs
new file mode 100644
index 0000000..e0c4b0b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNativeTanpiFloatFloat(float inV) {
+    return native_tanpi(inV);
+}
+
+float2 __attribute__((kernel)) testNativeTanpiFloat2Float2(float2 inV) {
+    return native_tanpi(inV);
+}
+
+float3 __attribute__((kernel)) testNativeTanpiFloat3Float3(float3 inV) {
+    return native_tanpi(inV);
+}
+
+float4 __attribute__((kernel)) testNativeTanpiFloat4Float4(float4 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
new file mode 100644
index 0000000..b542ad9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNativeTanpiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNativeTanpi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.java
new file mode 100644
index 0000000..57914c8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNextafter extends RSBaseCompute {
+
+    private ScriptC_TestNextafter script;
+    private ScriptC_TestNextafterRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNextafter(mRS);
+        scriptRelaxed = new ScriptC_TestNextafterRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inV;
+        public float inTarget;
+        public Target.Floaty out;
+    }
+
+    private void checkNextafterFloatFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xad412956l, false);
+        Allocation inTarget = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xafd7c03dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInTarget(inTarget);
+            script.forEach_testNextafterFloatFloatFloat(inV, out);
+            verifyResultsNextafterFloatFloatFloat(inV, inTarget, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInTarget(inTarget);
+            scriptRelaxed.forEach_testNextafterFloatFloatFloat(inV, out);
+            verifyResultsNextafterFloatFloatFloat(inV, inTarget, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNextafterFloatFloatFloat(Allocation inV, Allocation inTarget, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayInTarget = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInTarget, (float) 42);
+        inTarget.copyTo(arrayInTarget);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i];
+                args.inTarget = arrayInTarget[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeNextafter(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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("Input inTarget: ");
+                        appendVariableToMessage(message, args.inTarget);
+                        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]);
+                        if (!args.out.couldBe(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 checkNextafterFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNextafterFloat2Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x584a1e22l, false);
+        Allocation inTarget = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xf7e4d541l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInTarget(inTarget);
+            script.forEach_testNextafterFloat2Float2Float2(inV, out);
+            verifyResultsNextafterFloat2Float2Float2(inV, inTarget, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInTarget(inTarget);
+            scriptRelaxed.forEach_testNextafterFloat2Float2Float2(inV, out);
+            verifyResultsNextafterFloat2Float2Float2(inV, inTarget, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNextafterFloat2Float2Float2(Allocation inV, Allocation inTarget, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayInTarget = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInTarget, (float) 42);
+        inTarget.copyTo(arrayInTarget);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNextafter(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("Input inTarget: ");
+                        appendVariableToMessage(message, args.inTarget);
+                        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 checkNextafterFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNextafterFloat3Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5a281fc3l, false);
+        Allocation inTarget = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe4f910dcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInTarget(inTarget);
+            script.forEach_testNextafterFloat3Float3Float3(inV, out);
+            verifyResultsNextafterFloat3Float3Float3(inV, inTarget, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInTarget(inTarget);
+            scriptRelaxed.forEach_testNextafterFloat3Float3Float3(inV, out);
+            verifyResultsNextafterFloat3Float3Float3(inV, inTarget, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNextafterFloat3Float3Float3(Allocation inV, Allocation inTarget, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayInTarget = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInTarget, (float) 42);
+        inTarget.copyTo(arrayInTarget);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNextafter(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("Input inTarget: ");
+                        appendVariableToMessage(message, args.inTarget);
+                        message.append("\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 checkNextafterFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNextafterFloat4Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x5c062164l, false);
+        Allocation inTarget = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xd20d4c77l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInTarget(inTarget);
+            script.forEach_testNextafterFloat4Float4Float4(inV, out);
+            verifyResultsNextafterFloat4Float4Float4(inV, inTarget, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInTarget(inTarget);
+            scriptRelaxed.forEach_testNextafterFloat4Float4Float4(inV, out);
+            verifyResultsNextafterFloat4Float4Float4(inV, inTarget, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNextafterFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNextafterFloat4Float4Float4(Allocation inV, Allocation inTarget, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayInTarget = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInTarget, (float) 42);
+        inTarget.copyTo(arrayInTarget);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeNextafter(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("Input inTarget: ");
+                        appendVariableToMessage(message, args.inTarget);
+                        message.append("\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 checkNextafterFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNextafter() {
+        checkNextafterFloatFloatFloat();
+        checkNextafterFloat2Float2Float2();
+        checkNextafterFloat3Float3Float3();
+        checkNextafterFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.rs
new file mode 100644
index 0000000..fb9ac70
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafter.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInTarget;
+
+float __attribute__((kernel)) testNextafterFloatFloatFloat(float inV, unsigned int x) {
+    float inTarget = rsGetElementAt_float(gAllocInTarget, x);
+    return nextafter(inV, inTarget);
+}
+
+float2 __attribute__((kernel)) testNextafterFloat2Float2Float2(float2 inV, unsigned int x) {
+    float2 inTarget = rsGetElementAt_float2(gAllocInTarget, x);
+    return nextafter(inV, inTarget);
+}
+
+float3 __attribute__((kernel)) testNextafterFloat3Float3Float3(float3 inV, unsigned int x) {
+    float3 inTarget = rsGetElementAt_float3(gAllocInTarget, x);
+    return nextafter(inV, inTarget);
+}
+
+float4 __attribute__((kernel)) testNextafterFloat4Float4Float4(float4 inV, unsigned int x) {
+    float4 inTarget = rsGetElementAt_float4(gAllocInTarget, x);
+    return nextafter(inV, inTarget);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafterRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafterRelaxed.rs
new file mode 100644
index 0000000..fd8dad3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNextafterRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNextafter.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.java
new file mode 100644
index 0000000..8dd2708
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestNormalize extends RSBaseCompute {
+
+    private ScriptC_TestNormalize script;
+    private ScriptC_TestNormalizeRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestNormalize(mRS);
+        scriptRelaxed = new ScriptC_TestNormalizeRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkNormalizeFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9460061cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testNormalizeFloatFloat(inV, out);
+            verifyResultsNormalizeFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeFloatFloat(inV, out);
+            verifyResultsNormalizeFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOut, (float) 42);
+        out.copyTo(arrayOut);
+        StringBuilder message = new StringBuilder();
+        boolean errorFound = false;
+        for (int i = 0; i < INPUTSIZE; i++) {
+            ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+            // Create the appropriate sized arrays in args
+            // Fill args with the input values
+            args.inV = arrayInV[i];
+            Target target = new Target(relaxed);
+            CoreMathVerifier.computeNormalize(args, target);
+
+            // Compare the expected outputs to the actual values returned by RS.
+            boolean valid = true;
+            if (!args.out.couldBe(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]);
+                    if (!args.out.couldBe(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 checkNormalizeFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public class ArgumentsFloatNFloatN {
+        public float[] inV;
+        public Target.Floaty[] out;
+    }
+
+    private void checkNormalizeFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6e066120l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testNormalizeFloat2Float2(inV, out);
+            verifyResultsNormalizeFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeFloat2Float2(inV, out);
+            verifyResultsNormalizeFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[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];
+            }
+            Target target = new Target(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(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]);
+                        if (!args.out[j].couldBe(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 checkNormalizeFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNormalizeFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x642181fel, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testNormalizeFloat3Float3(inV, out);
+            verifyResultsNormalizeFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeFloat3Float3(inV, out);
+            verifyResultsNormalizeFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[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];
+            }
+            Target target = new Target(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(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]);
+                        if (!args.out[j].couldBe(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 checkNormalizeFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkNormalizeFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x5a3ca2dcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testNormalizeFloat4Float4(inV, out);
+            verifyResultsNormalizeFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testNormalizeFloat4Float4(inV, out);
+            verifyResultsNormalizeFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testNormalizeFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsNormalizeFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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++) {
+            ArgumentsFloatNFloatN args = new ArgumentsFloatNFloatN();
+            // Create the appropriate sized arrays in args
+            args.inV = new float[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];
+            }
+            Target target = new Target(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(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]);
+                        if (!args.out[j].couldBe(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 checkNormalizeFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testNormalize() {
+        checkNormalizeFloatFloat();
+        checkNormalizeFloat2Float2();
+        checkNormalizeFloat3Float3();
+        checkNormalizeFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.rs
new file mode 100644
index 0000000..46c8aad
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalize.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testNormalizeFloatFloat(float inV) {
+    return normalize(inV);
+}
+
+float2 __attribute__((kernel)) testNormalizeFloat2Float2(float2 inV) {
+    return normalize(inV);
+}
+
+float3 __attribute__((kernel)) testNormalizeFloat3Float3(float3 inV) {
+    return normalize(inV);
+}
+
+float4 __attribute__((kernel)) testNormalizeFloat4Float4(float4 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
new file mode 100644
index 0000000..48d69b8
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestNormalizeRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestNormalize.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.java
new file mode 100644
index 0000000..296927e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestPow extends RSBaseCompute {
+
+    private ScriptC_TestPow script;
+    private ScriptC_TestPowRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestPow(mRS);
+        scriptRelaxed = new ScriptC_TestPowRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inBase;
+        public float inExponent;
+        public Target.Floaty out;
+    }
+
+    private void checkPowFloatFloatFloat() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x622b91eel, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x49a5f734l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowFloatFloatFloat(inBase, out);
+            verifyResultsPowFloatFloatFloat(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowFloatFloatFloat(inBase, out);
+            verifyResultsPowFloatFloatFloat(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowFloatFloatFloat(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inBase = arrayInBase[i];
+                args.inExponent = arrayInExponent[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computePow(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkPowFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowFloat2Float2Float2() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x895c2294l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbbad35fal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowFloat2Float2Float2(inBase, out);
+            verifyResultsPowFloat2Float2Float2(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowFloat2Float2Float2(inBase, out);
+            verifyResultsPowFloat2Float2Float2(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowFloat2Float2Float2(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computePow(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 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]);
+                        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 checkPowFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowFloat3Float3Float3() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x71d00807l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x12cfb87dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowFloat3Float3Float3(inBase, out);
+            verifyResultsPowFloat3Float3Float3(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowFloat3Float3Float3(inBase, out);
+            verifyResultsPowFloat3Float3Float3(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowFloat3Float3Float3(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computePow(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 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]);
+                        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 checkPowFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowFloat4Float4Float4() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x5a43ed7al, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x69f23b00l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowFloat4Float4Float4(inBase, out);
+            verifyResultsPowFloat4Float4Float4(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowFloat4Float4Float4(inBase, out);
+            verifyResultsPowFloat4Float4Float4(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowFloat4Float4Float4(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computePow(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 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]);
+                        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 checkPowFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testPow() {
+        checkPowFloatFloatFloat();
+        checkPowFloat2Float2Float2();
+        checkPowFloat3Float3Float3();
+        checkPowFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.rs
new file mode 100644
index 0000000..2ef2106
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPow.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInExponent;
+
+float __attribute__((kernel)) testPowFloatFloatFloat(float inBase, unsigned int x) {
+    float inExponent = rsGetElementAt_float(gAllocInExponent, x);
+    return pow(inBase, inExponent);
+}
+
+float2 __attribute__((kernel)) testPowFloat2Float2Float2(float2 inBase, unsigned int x) {
+    float2 inExponent = rsGetElementAt_float2(gAllocInExponent, x);
+    return pow(inBase, inExponent);
+}
+
+float3 __attribute__((kernel)) testPowFloat3Float3Float3(float3 inBase, unsigned int x) {
+    float3 inExponent = rsGetElementAt_float3(gAllocInExponent, x);
+    return pow(inBase, inExponent);
+}
+
+float4 __attribute__((kernel)) testPowFloat4Float4Float4(float4 inBase, unsigned int x) {
+    float4 inExponent = rsGetElementAt_float4(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
new file mode 100644
index 0000000..042b07c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestPow.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.java
new file mode 100644
index 0000000..5a866f5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestPown extends RSBaseCompute {
+
+    private ScriptC_TestPown script;
+    private ScriptC_TestPownRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestPown(mRS);
+        scriptRelaxed = new ScriptC_TestPownRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inBase;
+        public int inExponent;
+        public Target.Floaty out;
+    }
+
+    private void checkPownFloatIntFloat() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x622f0405l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x96b9f1bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPownFloatIntFloat(inBase, out);
+            verifyResultsPownFloatIntFloat(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPownFloatIntFloat(inBase, out);
+            verifyResultsPownFloatIntFloat(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownFloatIntFloat(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        int[] arrayInExponent = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inBase = arrayInBase[i];
+                args.inExponent = arrayInExponent[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computePown(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkPownFloatIntFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPownFloat2Int2Float2() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xbe438467l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0x249076ddl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPownFloat2Int2Float2(inBase, out);
+            verifyResultsPownFloat2Int2Float2(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPownFloat2Int2Float2(inBase, out);
+            verifyResultsPownFloat2Int2Float2(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownFloat2Int2Float2(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        int[] arrayInExponent = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computePown(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 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]);
+                        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 checkPownFloat2Int2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPownFloat3Int3Float3() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe35ff8a2l, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0x144a81a8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPownFloat3Int3Float3(inBase, out);
+            verifyResultsPownFloat3Int3Float3(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPownFloat3Int3Float3(inBase, out);
+            verifyResultsPownFloat3Int3Float3(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownFloat3Int3Float3(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        int[] arrayInExponent = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computePown(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 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]);
+                        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 checkPownFloat3Int3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPownFloat4Int4Float4() {
+        Allocation inBase = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x87c6cddl, false);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0x4048c73l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPownFloat4Int4Float4(inBase, out);
+            verifyResultsPownFloat4Int4Float4(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPownFloat4Int4Float4(inBase, out);
+            verifyResultsPownFloat4Int4Float4(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPownFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPownFloat4Int4Float4(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        int[] arrayInExponent = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (int) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computePown(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 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]);
+                        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 checkPownFloat4Int4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testPown() {
+        checkPownFloatIntFloat();
+        checkPownFloat2Int2Float2();
+        checkPownFloat3Int3Float3();
+        checkPownFloat4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.rs
new file mode 100644
index 0000000..b30af22
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPown.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInExponent;
+
+float __attribute__((kernel)) testPownFloatIntFloat(float inBase, unsigned int x) {
+    int inExponent = rsGetElementAt_int(gAllocInExponent, x);
+    return pown(inBase, inExponent);
+}
+
+float2 __attribute__((kernel)) testPownFloat2Int2Float2(float2 inBase, unsigned int x) {
+    int2 inExponent = rsGetElementAt_int2(gAllocInExponent, x);
+    return pown(inBase, inExponent);
+}
+
+float3 __attribute__((kernel)) testPownFloat3Int3Float3(float3 inBase, unsigned int x) {
+    int3 inExponent = rsGetElementAt_int3(gAllocInExponent, x);
+    return pown(inBase, inExponent);
+}
+
+float4 __attribute__((kernel)) testPownFloat4Int4Float4(float4 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
new file mode 100644
index 0000000..dada2ae
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPownRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestPown.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.java
new file mode 100644
index 0000000..710d89b
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestPowr extends RSBaseCompute {
+
+    private ScriptC_TestPowr script;
+    private ScriptC_TestPowrRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestPowr(mRS);
+        scriptRelaxed = new ScriptC_TestPowrRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inBase;
+        public float inExponent;
+        public Target.Floaty out;
+    }
+
+    private void checkPowrFloatFloatFloat() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xc490ca4l, 0, 3000);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xab21ab0al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowrFloatFloatFloat(inBase, out);
+            verifyResultsPowrFloatFloatFloat(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowrFloatFloatFloat(inBase, out);
+            verifyResultsPowrFloatFloatFloat(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrFloatFloatFloat(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inBase = arrayInBase[i];
+                args.inExponent = arrayInExponent[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computePowr(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkPowrFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowrFloat2Float2Float2() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xeae1fd16l, 0, 3000);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x817a9ddcl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowrFloat2Float2Float2(inBase, out);
+            verifyResultsPowrFloat2Float2Float2(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowrFloat2Float2Float2(inBase, out);
+            verifyResultsPowrFloat2Float2Float2(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrFloat2Float2Float2(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computePowr(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 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]);
+                        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 checkPowrFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowrFloat3Float3Float3() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd355e289l, 0, 3000);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd89d205fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowrFloat3Float3Float3(inBase, out);
+            verifyResultsPowrFloat3Float3Float3(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowrFloat3Float3Float3(inBase, out);
+            verifyResultsPowrFloat3Float3Float3(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrFloat3Float3Float3(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computePowr(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 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]);
+                        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 checkPowrFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkPowrFloat4Float4Float4() {
+        Allocation inBase = createRandomFloatAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xbbc9c7fcl, 0, 3000);
+        Allocation inExponent = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2fbfa2e2l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInExponent(inExponent);
+            script.forEach_testPowrFloat4Float4Float4(inBase, out);
+            verifyResultsPowrFloat4Float4Float4(inBase, inExponent, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInExponent(inExponent);
+            scriptRelaxed.forEach_testPowrFloat4Float4Float4(inBase, out);
+            verifyResultsPowrFloat4Float4Float4(inBase, inExponent, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testPowrFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsPowrFloat4Float4Float4(Allocation inBase, Allocation inExponent, Allocation out, boolean relaxed) {
+        float[] arrayInBase = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInBase, (float) 42);
+        inBase.copyTo(arrayInBase);
+        float[] arrayInExponent = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInExponent, (float) 42);
+        inExponent.copyTo(arrayInExponent);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computePowr(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 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]);
+                        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 checkPowrFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testPowr() {
+        checkPowrFloatFloatFloat();
+        checkPowrFloat2Float2Float2();
+        checkPowrFloat3Float3Float3();
+        checkPowrFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.rs
new file mode 100644
index 0000000..66c0e5f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowr.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInExponent;
+
+float __attribute__((kernel)) testPowrFloatFloatFloat(float inBase, unsigned int x) {
+    float inExponent = rsGetElementAt_float(gAllocInExponent, x);
+    return powr(inBase, inExponent);
+}
+
+float2 __attribute__((kernel)) testPowrFloat2Float2Float2(float2 inBase, unsigned int x) {
+    float2 inExponent = rsGetElementAt_float2(gAllocInExponent, x);
+    return powr(inBase, inExponent);
+}
+
+float3 __attribute__((kernel)) testPowrFloat3Float3Float3(float3 inBase, unsigned int x) {
+    float3 inExponent = rsGetElementAt_float3(gAllocInExponent, x);
+    return powr(inBase, inExponent);
+}
+
+float4 __attribute__((kernel)) testPowrFloat4Float4Float4(float4 inBase, unsigned int x) {
+    float4 inExponent = rsGetElementAt_float4(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
new file mode 100644
index 0000000..a9c7247
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestPowrRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestPowr.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.java
new file mode 100644
index 0000000..3dbba71
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestRadians extends RSBaseCompute {
+
+    private ScriptC_TestRadians script;
+    private ScriptC_TestRadiansRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRadians(mRS);
+        scriptRelaxed = new ScriptC_TestRadiansRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkRadiansFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x42adfabl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testRadiansFloatFloat(inV, out);
+            verifyResultsRadiansFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansFloatFloat(inV, out);
+            verifyResultsRadiansFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRadians(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkRadiansFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRadiansFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xde23baf7l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testRadiansFloat2Float2(inV, out);
+            verifyResultsRadiansFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansFloat2Float2(inV, out);
+            verifyResultsRadiansFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRadians(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 checkRadiansFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRadiansFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xd43edbd5l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testRadiansFloat3Float3(inV, out);
+            verifyResultsRadiansFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansFloat3Float3(inV, out);
+            verifyResultsRadiansFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRadians(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 checkRadiansFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRadiansFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xca59fcb3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testRadiansFloat4Float4(inV, out);
+            verifyResultsRadiansFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRadiansFloat4Float4(inV, out);
+            verifyResultsRadiansFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRadiansFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRadiansFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRadians(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 checkRadiansFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testRadians() {
+        checkRadiansFloatFloat();
+        checkRadiansFloat2Float2();
+        checkRadiansFloat3Float3();
+        checkRadiansFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.rs
new file mode 100644
index 0000000..27d178a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadians.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testRadiansFloatFloat(float inV) {
+    return radians(inV);
+}
+
+float2 __attribute__((kernel)) testRadiansFloat2Float2(float2 inV) {
+    return radians(inV);
+}
+
+float3 __attribute__((kernel)) testRadiansFloat3Float3(float3 inV) {
+    return radians(inV);
+}
+
+float4 __attribute__((kernel)) testRadiansFloat4Float4(float4 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
new file mode 100644
index 0000000..b8a2669
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRadiansRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestRadians.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.java
new file mode 100644
index 0000000..5bbcc3a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestRemainder extends RSBaseCompute {
+
+    private ScriptC_TestRemainder script;
+    private ScriptC_TestRemainderRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRemainder(mRS);
+        scriptRelaxed = new ScriptC_TestRemainderRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inNumerator;
+        public float inDenominator;
+        public Target.Floaty out;
+    }
+
+    private void checkRemainderFloatFloatFloat() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x317ea229l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe2ebe35al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testRemainderFloatFloatFloat(inNumerator, out);
+            verifyResultsRemainderFloatFloatFloat(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testRemainderFloatFloatFloat(inNumerator, out);
+            verifyResultsRemainderFloatFloatFloat(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderFloatFloatFloat(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inNumerator = arrayInNumerator[i];
+                args.inDenominator = arrayInDenominator[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRemainder(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkRemainderFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRemainderFloat2Float2Float2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3fdcf8d5l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xaa4be3a6l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testRemainderFloat2Float2Float2(inNumerator, out);
+            verifyResultsRemainderFloat2Float2Float2(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testRemainderFloat2Float2Float2(inNumerator, out);
+            verifyResultsRemainderFloat2Float2Float2(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderFloat2Float2Float2(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeRemainder(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 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]);
+                        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 checkRemainderFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRemainderFloat3Float3Float3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xe2a8e4d6l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7d2776dfl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testRemainderFloat3Float3Float3(inNumerator, out);
+            verifyResultsRemainderFloat3Float3Float3(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testRemainderFloat3Float3Float3(inNumerator, out);
+            verifyResultsRemainderFloat3Float3Float3(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderFloat3Float3Float3(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeRemainder(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 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]);
+                        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 checkRemainderFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRemainderFloat4Float4Float4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8574d0d7l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x50030a18l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.forEach_testRemainderFloat4Float4Float4(inNumerator, out);
+            verifyResultsRemainderFloat4Float4Float4(inNumerator, inDenominator, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.forEach_testRemainderFloat4Float4Float4(inNumerator, out);
+            verifyResultsRemainderFloat4Float4Float4(inNumerator, inDenominator, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemainderFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemainderFloat4Float4Float4(Allocation inNumerator, Allocation inDenominator, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeRemainder(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 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]);
+                        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 checkRemainderFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testRemainder() {
+        checkRemainderFloatFloatFloat();
+        checkRemainderFloat2Float2Float2();
+        checkRemainderFloat3Float3Float3();
+        checkRemainderFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.rs
new file mode 100644
index 0000000..38de51c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainder.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInDenominator;
+
+float __attribute__((kernel)) testRemainderFloatFloatFloat(float inNumerator, unsigned int x) {
+    float inDenominator = rsGetElementAt_float(gAllocInDenominator, x);
+    return remainder(inNumerator, inDenominator);
+}
+
+float2 __attribute__((kernel)) testRemainderFloat2Float2Float2(float2 inNumerator, unsigned int x) {
+    float2 inDenominator = rsGetElementAt_float2(gAllocInDenominator, x);
+    return remainder(inNumerator, inDenominator);
+}
+
+float3 __attribute__((kernel)) testRemainderFloat3Float3Float3(float3 inNumerator, unsigned int x) {
+    float3 inDenominator = rsGetElementAt_float3(gAllocInDenominator, x);
+    return remainder(inNumerator, inDenominator);
+}
+
+float4 __attribute__((kernel)) testRemainderFloat4Float4Float4(float4 inNumerator, unsigned int x) {
+    float4 inDenominator = rsGetElementAt_float4(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
new file mode 100644
index 0000000..6a2e02f
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemainderRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestRemainder.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.java
new file mode 100644
index 0000000..d4868a6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestRemquo extends RSBaseCompute {
+
+    private ScriptC_TestRemquo script;
+    private ScriptC_TestRemquoRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRemquo(mRS);
+        scriptRelaxed = new ScriptC_TestRemquoRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatIntFloat {
+        public float inNumerator;
+        public float inDenominator;
+        public int outQuotient;
+        public float out;
+    }
+
+    private void checkRemquoFloatFloatIntFloat() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xedd4ff2al, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x2eb19f93l, false);
+        try {
+            Allocation outQuotient = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.set_gAllocOutQuotient(outQuotient);
+            script.forEach_testRemquoFloatFloatIntFloat(inNumerator, out);
+            verifyResultsRemquoFloatFloatIntFloat(inNumerator, inDenominator, outQuotient, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloatFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation outQuotient = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.set_gAllocOutQuotient(outQuotient);
+            scriptRelaxed.forEach_testRemquoFloatFloatIntFloat(inNumerator, out);
+            verifyResultsRemquoFloatFloatIntFloat(inNumerator, inDenominator, outQuotient, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloatFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemquoFloatFloatIntFloat(Allocation inNumerator, Allocation inDenominator, Allocation outQuotient, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        int[] arrayOutQuotient = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayOutQuotient, (int) 42);
+        outQuotient.copyTo(arrayOutQuotient);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
+                args.inNumerator = arrayInNumerator[i];
+                args.inDenominator = arrayInDenominator[i];
+                // Extract the outputs.
+                args.outQuotient = arrayOutQuotient[i * 1 + j];
+                args.out = arrayOut[i * 1 + j];
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(relaxed);
+                String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
+                boolean valid = errorMessage == null;
+                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("Output outQuotient: ");
+                        appendVariableToMessage(message, args.outQuotient);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        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 checkRemquoFloatFloatIntFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRemquoFloat2Float2Int2Float2() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3a27171al, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x6ba08403l, false);
+        try {
+            Allocation outQuotient = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.set_gAllocOutQuotient(outQuotient);
+            script.forEach_testRemquoFloat2Float2Int2Float2(inNumerator, out);
+            verifyResultsRemquoFloat2Float2Int2Float2(inNumerator, inDenominator, outQuotient, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat2Float2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation outQuotient = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.set_gAllocOutQuotient(outQuotient);
+            scriptRelaxed.forEach_testRemquoFloat2Float2Int2Float2(inNumerator, out);
+            verifyResultsRemquoFloat2Float2Int2Float2(inNumerator, inDenominator, outQuotient, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat2Float2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemquoFloat2Float2Int2Float2(Allocation inNumerator, Allocation inDenominator, Allocation outQuotient, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        int[] arrayOutQuotient = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayOutQuotient, (int) 42);
+        outQuotient.copyTo(arrayOutQuotient);
+        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.
+                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
+                args.inNumerator = arrayInNumerator[i * 2 + j];
+                args.inDenominator = arrayInDenominator[i * 2 + j];
+                // Extract the outputs.
+                args.outQuotient = arrayOutQuotient[i * 2 + j];
+                args.out = arrayOut[i * 2 + j];
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(relaxed);
+                String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
+                boolean valid = errorMessage == null;
+                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("Output outQuotient: ");
+                        appendVariableToMessage(message, args.outQuotient);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        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 checkRemquoFloat2Float2Int2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRemquoFloat3Float3Int3Float3() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x96052526l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf273f8afl, false);
+        try {
+            Allocation outQuotient = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.set_gAllocOutQuotient(outQuotient);
+            script.forEach_testRemquoFloat3Float3Int3Float3(inNumerator, out);
+            verifyResultsRemquoFloat3Float3Int3Float3(inNumerator, inDenominator, outQuotient, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat3Float3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation outQuotient = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.set_gAllocOutQuotient(outQuotient);
+            scriptRelaxed.forEach_testRemquoFloat3Float3Int3Float3(inNumerator, out);
+            verifyResultsRemquoFloat3Float3Int3Float3(inNumerator, inDenominator, outQuotient, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat3Float3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemquoFloat3Float3Int3Float3(Allocation inNumerator, Allocation inDenominator, Allocation outQuotient, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        int[] arrayOutQuotient = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOutQuotient, (int) 42);
+        outQuotient.copyTo(arrayOutQuotient);
+        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.
+                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                // Extract the outputs.
+                args.outQuotient = arrayOutQuotient[i * 4 + j];
+                args.out = arrayOut[i * 4 + j];
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(relaxed);
+                String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
+                boolean valid = errorMessage == null;
+                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("Output outQuotient: ");
+                        appendVariableToMessage(message, args.outQuotient);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        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 checkRemquoFloat3Float3Int3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRemquoFloat4Float4Int4Float4() {
+        Allocation inNumerator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xf1e33332l, false);
+        Allocation inDenominator = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x79476d5bl, false);
+        try {
+            Allocation outQuotient = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInDenominator(inDenominator);
+            script.set_gAllocOutQuotient(outQuotient);
+            script.forEach_testRemquoFloat4Float4Int4Float4(inNumerator, out);
+            verifyResultsRemquoFloat4Float4Int4Float4(inNumerator, inDenominator, outQuotient, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat4Float4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation outQuotient = Allocation.createSized(mRS, getElement(mRS, Element.DataType.SIGNED_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInDenominator(inDenominator);
+            scriptRelaxed.set_gAllocOutQuotient(outQuotient);
+            scriptRelaxed.forEach_testRemquoFloat4Float4Int4Float4(inNumerator, out);
+            verifyResultsRemquoFloat4Float4Int4Float4(inNumerator, inDenominator, outQuotient, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRemquoFloat4Float4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRemquoFloat4Float4Int4Float4(Allocation inNumerator, Allocation inDenominator, Allocation outQuotient, Allocation out, boolean relaxed) {
+        float[] arrayInNumerator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInNumerator, (float) 42);
+        inNumerator.copyTo(arrayInNumerator);
+        float[] arrayInDenominator = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInDenominator, (float) 42);
+        inDenominator.copyTo(arrayInDenominator);
+        int[] arrayOutQuotient = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayOutQuotient, (int) 42);
+        outQuotient.copyTo(arrayOutQuotient);
+        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.
+                ArgumentsFloatFloatIntFloat args = new ArgumentsFloatFloatIntFloat();
+                args.inNumerator = arrayInNumerator[i * 4 + j];
+                args.inDenominator = arrayInDenominator[i * 4 + j];
+                // Extract the outputs.
+                args.outQuotient = arrayOutQuotient[i * 4 + j];
+                args.out = arrayOut[i * 4 + j];
+                // Ask the CoreMathVerifier to validate.
+                Target target = new Target(relaxed);
+                String errorMessage = CoreMathVerifier.verifyRemquo(args, target);
+                boolean valid = errorMessage == null;
+                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("Output outQuotient: ");
+                        appendVariableToMessage(message, args.outQuotient);
+                        message.append("\n");
+                        message.append("Output out: ");
+                        appendVariableToMessage(message, args.out);
+                        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 checkRemquoFloat4Float4Int4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testRemquo() {
+        checkRemquoFloatFloatIntFloat();
+        checkRemquoFloat2Float2Int2Float2();
+        checkRemquoFloat3Float3Int3Float3();
+        checkRemquoFloat4Float4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.rs
new file mode 100644
index 0000000..15f0034
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquo.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInDenominator;
+rs_allocation gAllocOutQuotient;
+
+float __attribute__((kernel)) testRemquoFloatFloatIntFloat(float inNumerator, unsigned int x) {
+    float inDenominator = rsGetElementAt_float(gAllocInDenominator, x);
+    int outQuotient = 0;
+    float out = remquo(inNumerator, inDenominator, &outQuotient);
+    rsSetElementAt_int(gAllocOutQuotient, outQuotient, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testRemquoFloat2Float2Int2Float2(float2 inNumerator, unsigned int x) {
+    float2 inDenominator = rsGetElementAt_float2(gAllocInDenominator, x);
+    int2 outQuotient = 0;
+    float2 out = remquo(inNumerator, inDenominator, &outQuotient);
+    rsSetElementAt_int2(gAllocOutQuotient, outQuotient, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testRemquoFloat3Float3Int3Float3(float3 inNumerator, unsigned int x) {
+    float3 inDenominator = rsGetElementAt_float3(gAllocInDenominator, x);
+    int3 outQuotient = 0;
+    float3 out = remquo(inNumerator, inDenominator, &outQuotient);
+    rsSetElementAt_int3(gAllocOutQuotient, outQuotient, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testRemquoFloat4Float4Int4Float4(float4 inNumerator, unsigned int x) {
+    float4 inDenominator = rsGetElementAt_float4(gAllocInDenominator, x);
+    int4 outQuotient = 0;
+    float4 out = remquo(inNumerator, inDenominator, &outQuotient);
+    rsSetElementAt_int4(gAllocOutQuotient, outQuotient, x);
+    return out;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquoRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquoRelaxed.rs
new file mode 100644
index 0000000..5d2a1a6
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRemquoRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestRemquo.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.java
new file mode 100644
index 0000000..1c22e95
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestRint extends RSBaseCompute {
+
+    private ScriptC_TestRint script;
+    private ScriptC_TestRintRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRint(mRS);
+        scriptRelaxed = new ScriptC_TestRintRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkRintFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbf02db54l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testRintFloatFloat(inV, out);
+            verifyResultsRintFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRintFloatFloat(inV, out);
+            verifyResultsRintFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRint(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkRintFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRintFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x601c6298l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testRintFloat2Float2(inV, out);
+            verifyResultsRintFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRintFloat2Float2(inV, out);
+            verifyResultsRintFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRint(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 checkRintFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRintFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x56378376l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testRintFloat3Float3(inV, out);
+            verifyResultsRintFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRintFloat3Float3(inV, out);
+            verifyResultsRintFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRint(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 checkRintFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRintFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4c52a454l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testRintFloat4Float4(inV, out);
+            verifyResultsRintFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRintFloat4Float4(inV, out);
+            verifyResultsRintFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRintFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRintFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRint(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 checkRintFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testRint() {
+        checkRintFloatFloat();
+        checkRintFloat2Float2();
+        checkRintFloat3Float3();
+        checkRintFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.rs
new file mode 100644
index 0000000..4ac5eb4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRint.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testRintFloatFloat(float inV) {
+    return rint(inV);
+}
+
+float2 __attribute__((kernel)) testRintFloat2Float2(float2 inV) {
+    return rint(inV);
+}
+
+float3 __attribute__((kernel)) testRintFloat3Float3(float3 inV) {
+    return rint(inV);
+}
+
+float4 __attribute__((kernel)) testRintFloat4Float4(float4 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
new file mode 100644
index 0000000..703ca2e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRintRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestRint.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.java
new file mode 100644
index 0000000..5403dda
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestRootn extends RSBaseCompute {
+
+    private ScriptC_TestRootn script;
+    private ScriptC_TestRootnRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRootn(mRS);
+        scriptRelaxed = new ScriptC_TestRootnRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatIntFloat {
+        public float inV;
+        public int inN;
+        public Target.Floaty out;
+    }
+
+    private void checkRootnFloatIntFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4daae0ccl, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 1, 0x4daae0c4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testRootnFloatIntFloat(inV, out);
+            verifyResultsRootnFloatIntFloat(inV, inN, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloatIntFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testRootnFloatIntFloat(inV, out);
+            verifyResultsRootnFloatIntFloat(inV, inN, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloatIntFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRootnFloatIntFloat(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayInN = new int[INPUTSIZE * 1];
+        Arrays.fill(arrayInN, (int) 42);
+        inN.copyTo(arrayInN);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                args.inV = arrayInV[i];
+                args.inN = arrayInN[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRootn(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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("Input inN: ");
+                        appendVariableToMessage(message, args.inN);
+                        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]);
+                        if (!args.out.couldBe(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 checkRootnFloatIntFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRootnFloat2Int2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xcb32d88el, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 2, 0xcb32d886l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testRootnFloat2Int2Float2(inV, out);
+            verifyResultsRootnFloat2Int2Float2(inV, inN, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat2Int2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testRootnFloat2Int2Float2(inV, out);
+            verifyResultsRootnFloat2Int2Float2(inV, inN, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat2Int2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRootnFloat2Int2Float2(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayInN = new int[INPUTSIZE * 2];
+        Arrays.fill(arrayInN, (int) 42);
+        inN.copyTo(arrayInN);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computeRootn(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("Input inN: ");
+                        appendVariableToMessage(message, args.inN);
+                        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 checkRootnFloat2Int2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRootnFloat3Int3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc0e54547l, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 3, 0xc0e5453fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testRootnFloat3Int3Float3(inV, out);
+            verifyResultsRootnFloat3Int3Float3(inV, inN, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat3Int3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testRootnFloat3Int3Float3(inV, out);
+            verifyResultsRootnFloat3Int3Float3(inV, inN, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat3Int3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRootnFloat3Int3Float3(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayInN = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInN, (int) 42);
+        inN.copyTo(arrayInN);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computeRootn(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("Input inN: ");
+                        appendVariableToMessage(message, args.inN);
+                        message.append("\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 checkRootnFloat3Int3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRootnFloat4Int4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xb697b200l, false);
+        Allocation inN = createRandomAllocation(mRS, Element.DataType.SIGNED_32, 4, 0xb697b1f8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInN(inN);
+            script.forEach_testRootnFloat4Int4Float4(inV, out);
+            verifyResultsRootnFloat4Int4Float4(inV, inN, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat4Int4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInN(inN);
+            scriptRelaxed.forEach_testRootnFloat4Int4Float4(inV, out);
+            verifyResultsRootnFloat4Int4Float4(inV, inN, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRootnFloat4Int4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRootnFloat4Int4Float4(Allocation inV, Allocation inN, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        int[] arrayInN = new int[INPUTSIZE * 4];
+        Arrays.fill(arrayInN, (int) 42);
+        inN.copyTo(arrayInN);
+        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.
+                ArgumentsFloatIntFloat args = new ArgumentsFloatIntFloat();
+                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);
+                CoreMathVerifier.computeRootn(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("Input inN: ");
+                        appendVariableToMessage(message, args.inN);
+                        message.append("\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 checkRootnFloat4Int4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testRootn() {
+        checkRootnFloatIntFloat();
+        checkRootnFloat2Int2Float2();
+        checkRootnFloat3Int3Float3();
+        checkRootnFloat4Int4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.rs
new file mode 100644
index 0000000..4e400be
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootn.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInN;
+
+float __attribute__((kernel)) testRootnFloatIntFloat(float inV, unsigned int x) {
+    int inN = rsGetElementAt_int(gAllocInN, x);
+    return rootn(inV, inN);
+}
+
+float2 __attribute__((kernel)) testRootnFloat2Int2Float2(float2 inV, unsigned int x) {
+    int2 inN = rsGetElementAt_int2(gAllocInN, x);
+    return rootn(inV, inN);
+}
+
+float3 __attribute__((kernel)) testRootnFloat3Int3Float3(float3 inV, unsigned int x) {
+    int3 inN = rsGetElementAt_int3(gAllocInN, x);
+    return rootn(inV, inN);
+}
+
+float4 __attribute__((kernel)) testRootnFloat4Int4Float4(float4 inV, unsigned int x) {
+    int4 inN = rsGetElementAt_int4(gAllocInN, x);
+    return rootn(inV, inN);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootnRelaxed.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootnRelaxed.rs
new file mode 100644
index 0000000..57e29c4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRootnRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestRootn.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.java
new file mode 100644
index 0000000..3fde559
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestRound extends RSBaseCompute {
+
+    private ScriptC_TestRound script;
+    private ScriptC_TestRoundRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRound(mRS);
+        scriptRelaxed = new ScriptC_TestRoundRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkRoundFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x3f4006c3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testRoundFloatFloat(inV, out);
+            verifyResultsRoundFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundFloatFloat(inV, out);
+            verifyResultsRoundFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRound(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkRoundFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRoundFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x99eb174fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testRoundFloat2Float2(inV, out);
+            verifyResultsRoundFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundFloat2Float2(inV, out);
+            verifyResultsRoundFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRound(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 checkRoundFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRoundFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x9006382dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testRoundFloat3Float3(inV, out);
+            verifyResultsRoundFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundFloat3Float3(inV, out);
+            verifyResultsRoundFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRound(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 checkRoundFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRoundFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8621590bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testRoundFloat4Float4(inV, out);
+            verifyResultsRoundFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRoundFloat4Float4(inV, out);
+            verifyResultsRoundFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRoundFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRoundFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRound(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 checkRoundFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testRound() {
+        checkRoundFloatFloat();
+        checkRoundFloat2Float2();
+        checkRoundFloat3Float3();
+        checkRoundFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.rs
new file mode 100644
index 0000000..cf4b5e2
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRound.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testRoundFloatFloat(float inV) {
+    return round(inV);
+}
+
+float2 __attribute__((kernel)) testRoundFloat2Float2(float2 inV) {
+    return round(inV);
+}
+
+float3 __attribute__((kernel)) testRoundFloat3Float3(float3 inV) {
+    return round(inV);
+}
+
+float4 __attribute__((kernel)) testRoundFloat4Float4(float4 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
new file mode 100644
index 0000000..bd9fdcd
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRoundRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestRound.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.java
new file mode 100644
index 0000000..b4c3e23
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestRsqrt extends RSBaseCompute {
+
+    private ScriptC_TestRsqrt script;
+    private ScriptC_TestRsqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestRsqrt(mRS);
+        scriptRelaxed = new ScriptC_TestRsqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkRsqrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xaa3f3b8fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testRsqrtFloatFloat(inV, out);
+            verifyResultsRsqrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtFloatFloat(inV, out);
+            verifyResultsRsqrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRsqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkRsqrtFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRsqrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x672f6cbbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testRsqrtFloat2Float2(inV, out);
+            verifyResultsRsqrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtFloat2Float2(inV, out);
+            verifyResultsRsqrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRsqrt(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 checkRsqrtFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRsqrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x5d4a8d99l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testRsqrtFloat3Float3(inV, out);
+            verifyResultsRsqrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtFloat3Float3(inV, out);
+            verifyResultsRsqrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRsqrt(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 checkRsqrtFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkRsqrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x5365ae77l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testRsqrtFloat4Float4(inV, out);
+            verifyResultsRsqrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testRsqrtFloat4Float4(inV, out);
+            verifyResultsRsqrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testRsqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsRsqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeRsqrt(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 checkRsqrtFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testRsqrt() {
+        checkRsqrtFloatFloat();
+        checkRsqrtFloat2Float2();
+        checkRsqrtFloat3Float3();
+        checkRsqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.rs
new file mode 100644
index 0000000..38e3d10
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrt.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testRsqrtFloatFloat(float inV) {
+    return rsqrt(inV);
+}
+
+float2 __attribute__((kernel)) testRsqrtFloat2Float2(float2 inV) {
+    return rsqrt(inV);
+}
+
+float3 __attribute__((kernel)) testRsqrtFloat3Float3(float3 inV) {
+    return rsqrt(inV);
+}
+
+float4 __attribute__((kernel)) testRsqrtFloat4Float4(float4 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
new file mode 100644
index 0000000..5f52101
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestRsqrtRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestRsqrt.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.java
new file mode 100644
index 0000000..d3f12fe
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestSign extends RSBaseCompute {
+
+    private ScriptC_TestSign script;
+    private ScriptC_TestSignRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSign(mRS);
+        scriptRelaxed = new ScriptC_TestSignRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkSignFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x364ea474l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSignFloatFloat(inV, out);
+            verifyResultsSignFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSignFloatFloat(inV, out);
+            verifyResultsSignFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSign(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkSignFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSignFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x27c0ab8l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSignFloat2Float2(inV, out);
+            verifyResultsSignFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSignFloat2Float2(inV, out);
+            verifyResultsSignFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSign(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 checkSignFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSignFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xf8972b96l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSignFloat3Float3(inV, out);
+            verifyResultsSignFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSignFloat3Float3(inV, out);
+            verifyResultsSignFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSign(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 checkSignFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSignFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xeeb24c74l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSignFloat4Float4(inV, out);
+            verifyResultsSignFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSignFloat4Float4(inV, out);
+            verifyResultsSignFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSignFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSignFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSign(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 checkSignFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testSign() {
+        checkSignFloatFloat();
+        checkSignFloat2Float2();
+        checkSignFloat3Float3();
+        checkSignFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.rs
new file mode 100644
index 0000000..32be4d9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSign.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testSignFloatFloat(float inV) {
+    return sign(inV);
+}
+
+float2 __attribute__((kernel)) testSignFloat2Float2(float2 inV) {
+    return sign(inV);
+}
+
+float3 __attribute__((kernel)) testSignFloat3Float3(float3 inV) {
+    return sign(inV);
+}
+
+float4 __attribute__((kernel)) testSignFloat4Float4(float4 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
new file mode 100644
index 0000000..6e27906
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSignRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestSign.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.java
new file mode 100644
index 0000000..6acf220
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestSin extends RSBaseCompute {
+
+    private ScriptC_TestSin script;
+    private ScriptC_TestSinRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSin(mRS);
+        scriptRelaxed = new ScriptC_TestSinRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkSinFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe3401d29l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSinFloatFloat(inV, out);
+            verifyResultsSinFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSinFloatFloat(inV, out);
+            verifyResultsSinFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSin(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkSinFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x1e8cde05l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSinFloat2Float2(inV, out);
+            verifyResultsSinFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSinFloat2Float2(inV, out);
+            verifyResultsSinFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSin(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 checkSinFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x14a7fee3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSinFloat3Float3(inV, out);
+            verifyResultsSinFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSinFloat3Float3(inV, out);
+            verifyResultsSinFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSin(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 checkSinFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xac31fc1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSinFloat4Float4(inV, out);
+            verifyResultsSinFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSinFloat4Float4(inV, out);
+            verifyResultsSinFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSin(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 checkSinFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testSin() {
+        checkSinFloatFloat();
+        checkSinFloat2Float2();
+        checkSinFloat3Float3();
+        checkSinFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.rs
new file mode 100644
index 0000000..b44653e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSin.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testSinFloatFloat(float inV) {
+    return sin(inV);
+}
+
+float2 __attribute__((kernel)) testSinFloat2Float2(float2 inV) {
+    return sin(inV);
+}
+
+float3 __attribute__((kernel)) testSinFloat3Float3(float3 inV) {
+    return sin(inV);
+}
+
+float4 __attribute__((kernel)) testSinFloat4Float4(float4 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
new file mode 100644
index 0000000..dc906a3
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestSin.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.java
new file mode 100644
index 0000000..64d71d4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestSincos extends RSBaseCompute {
+
+    private ScriptC_TestSincos script;
+    private ScriptC_TestSincosRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSincos(mRS);
+        scriptRelaxed = new ScriptC_TestSincosRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inV;
+        public Target.Floaty outCos;
+        public Target.Floaty out;
+    }
+
+    private void checkSincosFloatFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xe46c48d4l, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testSincosFloatFloatFloat(inV, out);
+            verifyResultsSincosFloatFloatFloat(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testSincosFloatFloatFloat(inV, out);
+            verifyResultsSincosFloatFloatFloat(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosFloatFloatFloat(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutCos = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayOutCos, (float) 42);
+        outCos.copyTo(arrayOutCos);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(arrayOutCos[i * 1 + j])) {
+                    valid = false;
+                }
+                if (!args.out.couldBe(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]);
+                        if (!args.outCos.couldBe(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]);
+                        if (!args.out.couldBe(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 checkSincosFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSincosFloat2Float2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3e2fc77cl, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testSincosFloat2Float2Float2(inV, out);
+            verifyResultsSincosFloat2Float2Float2(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testSincosFloat2Float2Float2(inV, out);
+            verifyResultsSincosFloat2Float2Float2(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosFloat2Float2Float2(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutCos = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayOutCos, (float) 42);
+        outCos.copyTo(arrayOutCos);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(arrayOutCos[i * 2 + j])) {
+                    valid = false;
+                }
+                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 outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 2 + j]);
+                        if (!args.outCos.couldBe(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]);
+                        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 checkSincosFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSincosFloat3Float3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x400dc91dl, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testSincosFloat3Float3Float3(inV, out);
+            verifyResultsSincosFloat3Float3Float3(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testSincosFloat3Float3Float3(inV, out);
+            verifyResultsSincosFloat3Float3Float3(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosFloat3Float3Float3(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutCos = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOutCos, (float) 42);
+        outCos.copyTo(arrayOutCos);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(arrayOutCos[i * 4 + j])) {
+                    valid = false;
+                }
+                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 outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 4 + j]);
+                        if (!args.outCos.couldBe(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]);
+                        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 checkSincosFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSincosFloat4Float4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x41ebcabel, false);
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocOutCos(outCos);
+            script.forEach_testSincosFloat4Float4Float4(inV, out);
+            verifyResultsSincosFloat4Float4Float4(inV, outCos, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation outCos = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocOutCos(outCos);
+            scriptRelaxed.forEach_testSincosFloat4Float4Float4(inV, out);
+            verifyResultsSincosFloat4Float4Float4(inV, outCos, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSincosFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSincosFloat4Float4Float4(Allocation inV, Allocation outCos, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOutCos = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayOutCos, (float) 42);
+        outCos.copyTo(arrayOutCos);
+        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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSincos(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.outCos.couldBe(arrayOutCos[i * 4 + j])) {
+                    valid = false;
+                }
+                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 outCos: ");
+                        appendVariableToMessage(message, args.outCos);
+                        message.append("\n");
+                        message.append("Actual   output outCos: ");
+                        appendVariableToMessage(message, arrayOutCos[i * 4 + j]);
+                        if (!args.outCos.couldBe(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]);
+                        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 checkSincosFloat4Float4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testSincos() {
+        checkSincosFloatFloatFloat();
+        checkSincosFloat2Float2Float2();
+        checkSincosFloat3Float3Float3();
+        checkSincosFloat4Float4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.rs
new file mode 100644
index 0000000..aca40af
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincos.rs
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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)
+
+rs_allocation gAllocOutCos;
+
+float __attribute__((kernel)) testSincosFloatFloatFloat(float inV, unsigned int x) {
+    float outCos = 0;
+    float out = sincos(inV, &outCos);
+    rsSetElementAt_float(gAllocOutCos, outCos, x);
+    return out;
+}
+
+float2 __attribute__((kernel)) testSincosFloat2Float2Float2(float2 inV, unsigned int x) {
+    float2 outCos = 0;
+    float2 out = sincos(inV, &outCos);
+    rsSetElementAt_float2(gAllocOutCos, outCos, x);
+    return out;
+}
+
+float3 __attribute__((kernel)) testSincosFloat3Float3Float3(float3 inV, unsigned int x) {
+    float3 outCos = 0;
+    float3 out = sincos(inV, &outCos);
+    rsSetElementAt_float3(gAllocOutCos, outCos, x);
+    return out;
+}
+
+float4 __attribute__((kernel)) testSincosFloat4Float4Float4(float4 inV, unsigned int x) {
+    float4 outCos = 0;
+    float4 out = sincos(inV, &outCos);
+    rsSetElementAt_float4(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
new file mode 100644
index 0000000..c82d495
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSincosRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestSincos.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.java
new file mode 100644
index 0000000..20148d4
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestSinh extends RSBaseCompute {
+
+    private ScriptC_TestSinh script;
+    private ScriptC_TestSinhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSinh(mRS);
+        scriptRelaxed = new ScriptC_TestSinhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkSinhFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbda70dd1l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSinhFloatFloat(inV, out);
+            verifyResultsSinhFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhFloatFloat(inV, out);
+            verifyResultsSinhFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSinh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkSinhFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinhFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x900d0b6dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSinhFloat2Float2(inV, out);
+            verifyResultsSinhFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhFloat2Float2(inV, out);
+            verifyResultsSinhFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSinh(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 checkSinhFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinhFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x86282c4bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSinhFloat3Float3(inV, out);
+            verifyResultsSinhFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhFloat3Float3(inV, out);
+            verifyResultsSinhFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSinh(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 checkSinhFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinhFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x7c434d29l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSinhFloat4Float4(inV, out);
+            verifyResultsSinhFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSinhFloat4Float4(inV, out);
+            verifyResultsSinhFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinhFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSinh(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 checkSinhFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testSinh() {
+        checkSinhFloatFloat();
+        checkSinhFloat2Float2();
+        checkSinhFloat3Float3();
+        checkSinhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.rs
new file mode 100644
index 0000000..e677db7
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testSinhFloatFloat(float inV) {
+    return sinh(inV);
+}
+
+float2 __attribute__((kernel)) testSinhFloat2Float2(float2 inV) {
+    return sinh(inV);
+}
+
+float3 __attribute__((kernel)) testSinhFloat3Float3(float3 inV) {
+    return sinh(inV);
+}
+
+float4 __attribute__((kernel)) testSinhFloat4Float4(float4 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
new file mode 100644
index 0000000..e85464e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinhRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestSinh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.java
new file mode 100644
index 0000000..61c1d24
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestSinpi extends RSBaseCompute {
+
+    private ScriptC_TestSinpi script;
+    private ScriptC_TestSinpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSinpi(mRS);
+        scriptRelaxed = new ScriptC_TestSinpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkSinpiFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xdfd6b42cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSinpiFloatFloat(inV, out);
+            verifyResultsSinpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiFloatFloat(inV, out);
+            verifyResultsSinpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSinpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkSinpiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinpiFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7a3592b0l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSinpiFloat2Float2(inV, out);
+            verifyResultsSinpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiFloat2Float2(inV, out);
+            verifyResultsSinpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSinpi(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 checkSinpiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinpiFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x7050b38el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSinpiFloat3Float3(inV, out);
+            verifyResultsSinpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiFloat3Float3(inV, out);
+            verifyResultsSinpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSinpi(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 checkSinpiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSinpiFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x666bd46cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSinpiFloat4Float4(inV, out);
+            verifyResultsSinpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSinpiFloat4Float4(inV, out);
+            verifyResultsSinpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSinpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSinpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSinpi(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 checkSinpiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testSinpi() {
+        checkSinpiFloatFloat();
+        checkSinpiFloat2Float2();
+        checkSinpiFloat3Float3();
+        checkSinpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.rs
new file mode 100644
index 0000000..f88d225
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testSinpiFloatFloat(float inV) {
+    return sinpi(inV);
+}
+
+float2 __attribute__((kernel)) testSinpiFloat2Float2(float2 inV) {
+    return sinpi(inV);
+}
+
+float3 __attribute__((kernel)) testSinpiFloat3Float3(float3 inV) {
+    return sinpi(inV);
+}
+
+float4 __attribute__((kernel)) testSinpiFloat4Float4(float4 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
new file mode 100644
index 0000000..3cfd204
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSinpiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestSinpi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.java
new file mode 100644
index 0000000..cbb092d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestSqrt extends RSBaseCompute {
+
+    private ScriptC_TestSqrt script;
+    private ScriptC_TestSqrtRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestSqrt(mRS);
+        scriptRelaxed = new ScriptC_TestSqrtRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkSqrtFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xd07c9951l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testSqrtFloatFloat(inV, out);
+            verifyResultsSqrtFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtFloatFloat(inV, out);
+            verifyResultsSqrtFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSqrt(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkSqrtFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSqrtFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x98699aedl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testSqrtFloat2Float2(inV, out);
+            verifyResultsSqrtFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtFloat2Float2(inV, out);
+            verifyResultsSqrtFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSqrt(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 checkSqrtFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSqrtFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8e84bbcbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testSqrtFloat3Float3(inV, out);
+            verifyResultsSqrtFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtFloat3Float3(inV, out);
+            verifyResultsSqrtFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSqrt(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 checkSqrtFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkSqrtFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x849fdca9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testSqrtFloat4Float4(inV, out);
+            verifyResultsSqrtFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testSqrtFloat4Float4(inV, out);
+            verifyResultsSqrtFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testSqrtFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsSqrtFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeSqrt(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 checkSqrtFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testSqrt() {
+        checkSqrtFloatFloat();
+        checkSqrtFloat2Float2();
+        checkSqrtFloat3Float3();
+        checkSqrtFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.rs
new file mode 100644
index 0000000..ae1e96e
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrt.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testSqrtFloatFloat(float inV) {
+    return sqrt(inV);
+}
+
+float2 __attribute__((kernel)) testSqrtFloat2Float2(float2 inV) {
+    return sqrt(inV);
+}
+
+float3 __attribute__((kernel)) testSqrtFloat3Float3(float3 inV) {
+    return sqrt(inV);
+}
+
+float4 __attribute__((kernel)) testSqrtFloat4Float4(float4 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
new file mode 100644
index 0000000..019ca76
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestSqrtRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestSqrt.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.java
new file mode 100644
index 0000000..097a093
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.java
@@ -0,0 +1,847 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestStep extends RSBaseCompute {
+
+    private ScriptC_TestStep script;
+    private ScriptC_TestStepRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestStep(mRS);
+        scriptRelaxed = new ScriptC_TestStepRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloatFloat {
+        public float inEdge;
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkStepFloatFloatFloat() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x9184fbfel, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x832f44e9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloatFloatFloat(inEdge, out);
+            verifyResultsStepFloatFloatFloat(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloatFloatFloat(inEdge, out);
+            verifyResultsStepFloatFloatFloat(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloatFloatFloat(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i];
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeStep(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkStepFloatFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepFloat2Float2Float2() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x7df69504l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x8567f58bl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat2Float2Float2(inEdge, out);
+            verifyResultsStepFloat2Float2Float2(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2Float2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat2Float2Float2(inEdge, out);
+            verifyResultsStepFloat2Float2Float2(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2Float2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat2Float2Float2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeStep(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 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]);
+                        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 checkStepFloat2Float2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepFloat3Float3Float3() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x666a7a77l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x8745f72cl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat3Float3Float3(inEdge, out);
+            verifyResultsStepFloat3Float3Float3(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3Float3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat3Float3Float3(inEdge, out);
+            verifyResultsStepFloat3Float3Float3(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3Float3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat3Float3Float3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeStep(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 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]);
+                        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 checkStepFloat3Float3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepFloat4Float4Float4() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x4ede5feal, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x8923f8cdl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat4Float4Float4(inEdge, out);
+            verifyResultsStepFloat4Float4Float4(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4Float4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat4Float4Float4(inEdge, out);
+            verifyResultsStepFloat4Float4Float4(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4Float4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat4Float4Float4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                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);
+                CoreMathVerifier.computeStep(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 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]);
+                        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 checkStepFloat4Float4Float4" +
+                (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);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat2FloatFloat2(inEdge, out);
+            verifyResultsStepFloat2FloatFloat2(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2FloatFloat2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat2FloatFloat2(inEdge, out);
+            verifyResultsStepFloat2FloatFloat2(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat2FloatFloat2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat2FloatFloat2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i * 2 + j];
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeStep(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 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]);
+                        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 checkStepFloat2FloatFloat2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepFloat3FloatFloat3() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xc68f43fal, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xa53f7e7dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat3FloatFloat3(inEdge, out);
+            verifyResultsStepFloat3FloatFloat3(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3FloatFloat3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat3FloatFloat3(inEdge, out);
+            verifyResultsStepFloat3FloatFloat3(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat3FloatFloat3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat3FloatFloat3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeStep(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 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]);
+                        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 checkStepFloat3FloatFloat3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepFloat4FloatFloat4() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x31e0fccel, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x93aa72d9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloat4FloatFloat4(inEdge, out);
+            verifyResultsStepFloat4FloatFloat4(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4FloatFloat4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloat4FloatFloat4(inEdge, out);
+            verifyResultsStepFloat4FloatFloat4(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloat4FloatFloat4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloat4FloatFloat4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i * 4 + j];
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeStep(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 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]);
+                        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 checkStepFloat4FloatFloat4" +
+                (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);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloatFloat2Float2(inEdge, out);
+            verifyResultsStepFloatFloat2Float2(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloatFloat2Float2(inEdge, out);
+            verifyResultsStepFloatFloat2Float2(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloatFloat2Float2(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i];
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeStep(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 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]);
+                        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 checkStepFloatFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepFloatFloat3Float3() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x91abcbccl, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3afe18a3l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloatFloat3Float3(inEdge, out);
+            verifyResultsStepFloatFloat3Float3(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloatFloat3Float3(inEdge, out);
+            verifyResultsStepFloatFloat3Float3(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloatFloat3Float3(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i];
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeStep(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 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]);
+                        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 checkStepFloatFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkStepFloatFloat4Float4() {
+        Allocation inEdge = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xbd0c7f46l, false);
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x31193981l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.set_gAllocInV(inV);
+            script.forEach_testStepFloatFloat4Float4(inEdge, out);
+            verifyResultsStepFloatFloat4Float4(inEdge, inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.set_gAllocInV(inV);
+            scriptRelaxed.forEach_testStepFloatFloat4Float4(inEdge, out);
+            verifyResultsStepFloatFloat4Float4(inEdge, inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testStepFloatFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsStepFloatFloat4Float4(Allocation inEdge, Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInEdge = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInEdge, (float) 42);
+        inEdge.copyTo(arrayInEdge);
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloatFloat args = new ArgumentsFloatFloatFloat();
+                args.inEdge = arrayInEdge[i];
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeStep(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 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]);
+                        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 checkStepFloatFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testStep() {
+        checkStepFloatFloatFloat();
+        checkStepFloat2Float2Float2();
+        checkStepFloat3Float3Float3();
+        checkStepFloat4Float4Float4();
+        checkStepFloat2FloatFloat2();
+        checkStepFloat3FloatFloat3();
+        checkStepFloat4FloatFloat4();
+        checkStepFloatFloat2Float2();
+        checkStepFloatFloat3Float3();
+        checkStepFloatFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.rs
new file mode 100644
index 0000000..4af9b23
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStep.rs
@@ -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.
+ */
+
+// 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)
+
+rs_allocation gAllocInV;
+
+float __attribute__((kernel)) testStepFloatFloatFloat(float inEdge, unsigned int x) {
+    float inV = rsGetElementAt_float(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float2 __attribute__((kernel)) testStepFloat2Float2Float2(float2 inEdge, unsigned int x) {
+    float2 inV = rsGetElementAt_float2(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float3 __attribute__((kernel)) testStepFloat3Float3Float3(float3 inEdge, unsigned int x) {
+    float3 inV = rsGetElementAt_float3(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float4 __attribute__((kernel)) testStepFloat4Float4Float4(float4 inEdge, unsigned int x) {
+    float4 inV = rsGetElementAt_float4(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);
+}
+
+float3 __attribute__((kernel)) testStepFloat3FloatFloat3(float3 inEdge, unsigned int x) {
+    float inV = rsGetElementAt_float(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float4 __attribute__((kernel)) testStepFloat4FloatFloat4(float4 inEdge, unsigned int x) {
+    float inV = rsGetElementAt_float(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);
+}
+
+float3 __attribute__((kernel)) testStepFloatFloat3Float3(float inEdge, unsigned int x) {
+    float3 inV = rsGetElementAt_float3(gAllocInV, x);
+    return step(inEdge, inV);
+}
+
+float4 __attribute__((kernel)) testStepFloatFloat4Float4(float inEdge, unsigned int x) {
+    float4 inV = rsGetElementAt_float4(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
new file mode 100644
index 0000000..6f7175d
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestStepRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestStep.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.java
new file mode 100644
index 0000000..908ca59
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestTan extends RSBaseCompute {
+
+    private ScriptC_TestTan script;
+    private ScriptC_TestTanRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTan(mRS);
+        scriptRelaxed = new ScriptC_TestTanRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkTanFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x7bb50fa4l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTanFloatFloat(inV, out);
+            verifyResultsTanFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTanFloatFloat(inV, out);
+            verifyResultsTanFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTan(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkTanFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x43383868l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTanFloat2Float2(inV, out);
+            verifyResultsTanFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTanFloat2Float2(inV, out);
+            verifyResultsTanFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTan(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 checkTanFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x39535946l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTanFloat3Float3(inV, out);
+            verifyResultsTanFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTanFloat3Float3(inV, out);
+            verifyResultsTanFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTan(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 checkTanFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x2f6e7a24l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTanFloat4Float4(inV, out);
+            verifyResultsTanFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTanFloat4Float4(inV, out);
+            verifyResultsTanFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTan(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 checkTanFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testTan() {
+        checkTanFloatFloat();
+        checkTanFloat2Float2();
+        checkTanFloat3Float3();
+        checkTanFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.rs
new file mode 100644
index 0000000..bee11f5
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTan.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testTanFloatFloat(float inV) {
+    return tan(inV);
+}
+
+float2 __attribute__((kernel)) testTanFloat2Float2(float2 inV) {
+    return tan(inV);
+}
+
+float3 __attribute__((kernel)) testTanFloat3Float3(float3 inV) {
+    return tan(inV);
+}
+
+float4 __attribute__((kernel)) testTanFloat4Float4(float4 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
new file mode 100644
index 0000000..184ff39
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestTan.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.java
new file mode 100644
index 0000000..842c402
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestTanh extends RSBaseCompute {
+
+    private ScriptC_TestTanh script;
+    private ScriptC_TestTanhRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTanh(mRS);
+        scriptRelaxed = new ScriptC_TestTanhRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkTanhFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x594bc87al, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTanhFloatFloat(inV, out);
+            verifyResultsTanhFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhFloatFloat(inV, out);
+            verifyResultsTanhFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTanh(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkTanhFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanhFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0xb8d53a0el, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTanhFloat2Float2(inV, out);
+            verifyResultsTanhFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhFloat2Float2(inV, out);
+            verifyResultsTanhFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTanh(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 checkTanhFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanhFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0xaef05aecl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTanhFloat3Float3(inV, out);
+            verifyResultsTanhFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhFloat3Float3(inV, out);
+            verifyResultsTanhFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTanh(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 checkTanhFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanhFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0xa50b7bcal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTanhFloat4Float4(inV, out);
+            verifyResultsTanhFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTanhFloat4Float4(inV, out);
+            verifyResultsTanhFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanhFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanhFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTanh(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 checkTanhFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testTanh() {
+        checkTanhFloatFloat();
+        checkTanhFloat2Float2();
+        checkTanhFloat3Float3();
+        checkTanhFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.rs
new file mode 100644
index 0000000..41eb343
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanh.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testTanhFloatFloat(float inV) {
+    return tanh(inV);
+}
+
+float2 __attribute__((kernel)) testTanhFloat2Float2(float2 inV) {
+    return tanh(inV);
+}
+
+float3 __attribute__((kernel)) testTanhFloat3Float3(float3 inV) {
+    return tanh(inV);
+}
+
+float4 __attribute__((kernel)) testTanhFloat4Float4(float4 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
new file mode 100644
index 0000000..8148315
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanhRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestTanh.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.java
new file mode 100644
index 0000000..13be7d9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestTanpi extends RSBaseCompute {
+
+    private ScriptC_TestTanpi script;
+    private ScriptC_TestTanpiRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTanpi(mRS);
+        scriptRelaxed = new ScriptC_TestTanpiRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkTanpiFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x4820e8fl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTanpiFloatFloat(inV, out);
+            verifyResultsTanpiFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiFloatFloat(inV, out);
+            verifyResultsTanpiFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTanpi(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkTanpiFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanpiFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x53d567bbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTanpiFloat2Float2(inV, out);
+            verifyResultsTanpiFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiFloat2Float2(inV, out);
+            verifyResultsTanpiFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTanpi(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 checkTanpiFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanpiFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x49f08899l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTanpiFloat3Float3(inV, out);
+            verifyResultsTanpiFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiFloat3Float3(inV, out);
+            verifyResultsTanpiFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTanpi(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 checkTanpiFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTanpiFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x400ba977l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTanpiFloat4Float4(inV, out);
+            verifyResultsTanpiFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTanpiFloat4Float4(inV, out);
+            verifyResultsTanpiFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTanpiFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTanpiFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTanpi(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 checkTanpiFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testTanpi() {
+        checkTanpiFloatFloat();
+        checkTanpiFloat2Float2();
+        checkTanpiFloat3Float3();
+        checkTanpiFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.rs
new file mode 100644
index 0000000..d8954b1
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpi.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testTanpiFloatFloat(float inV) {
+    return tanpi(inV);
+}
+
+float2 __attribute__((kernel)) testTanpiFloat2Float2(float2 inV) {
+    return tanpi(inV);
+}
+
+float3 __attribute__((kernel)) testTanpiFloat3Float3(float3 inV) {
+    return tanpi(inV);
+}
+
+float4 __attribute__((kernel)) testTanpiFloat4Float4(float4 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
new file mode 100644
index 0000000..eb27c30
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTanpiRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestTanpi.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.java
new file mode 100644
index 0000000..cd11dc9
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestTgamma extends RSBaseCompute {
+
+    private ScriptC_TestTgamma script;
+    private ScriptC_TestTgammaRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTgamma(mRS);
+        scriptRelaxed = new ScriptC_TestTgammaRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkTgammaFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0xeda55486l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTgammaFloatFloat(inV, out);
+            verifyResultsTgammaFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaFloatFloat(inV, out);
+            verifyResultsTgammaFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTgamma(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkTgammaFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTgammaFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x3399bcbal, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTgammaFloat2Float2(inV, out);
+            verifyResultsTgammaFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaFloat2Float2(inV, out);
+            verifyResultsTgammaFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTgamma(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 checkTgammaFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTgammaFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x29b4dd98l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTgammaFloat3Float3(inV, out);
+            verifyResultsTgammaFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaFloat3Float3(inV, out);
+            verifyResultsTgammaFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTgamma(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 checkTgammaFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTgammaFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x1fcffe76l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTgammaFloat4Float4(inV, out);
+            verifyResultsTgammaFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTgammaFloat4Float4(inV, out);
+            verifyResultsTgammaFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTgammaFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTgammaFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTgamma(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 checkTgammaFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testTgamma() {
+        checkTgammaFloatFloat();
+        checkTgammaFloat2Float2();
+        checkTgammaFloat3Float3();
+        checkTgammaFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.rs
new file mode 100644
index 0000000..5431de0
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgamma.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testTgammaFloatFloat(float inV) {
+    return tgamma(inV);
+}
+
+float2 __attribute__((kernel)) testTgammaFloat2Float2(float2 inV) {
+    return tgamma(inV);
+}
+
+float3 __attribute__((kernel)) testTgammaFloat3Float3(float3 inV) {
+    return tgamma(inV);
+}
+
+float4 __attribute__((kernel)) testTgammaFloat4Float4(float4 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
new file mode 100644
index 0000000..afd1489
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTgammaRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestTgamma.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.java b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.java
new file mode 100644
index 0000000..e29de2c
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.java
@@ -0,0 +1,326 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 java.util.Arrays;
+
+public class TestTrunc extends RSBaseCompute {
+
+    private ScriptC_TestTrunc script;
+    private ScriptC_TestTruncRelaxed scriptRelaxed;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        script = new ScriptC_TestTrunc(mRS);
+        scriptRelaxed = new ScriptC_TestTruncRelaxed(mRS);
+    }
+
+    public class ArgumentsFloatFloat {
+        public float inV;
+        public Target.Floaty out;
+    }
+
+    private void checkTruncFloatFloat() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 1, 0x11eebe01l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            script.forEach_testTruncFloatFloat(inV, out);
+            verifyResultsTruncFloatFloat(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloatFloat: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 1), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncFloatFloat(inV, out);
+            verifyResultsTruncFloatFloat(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloatFloat: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncFloatFloat(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 1];
+        Arrays.fill(arrayInV, (float) 42);
+        inV.copyTo(arrayInV);
+        float[] arrayOut = new float[INPUTSIZE * 1];
+        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 < 1 ; j++) {
+                // Extract the inputs.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTrunc(args, target);
+                // Validate the outputs.
+                boolean valid = true;
+                if (!args.out.couldBe(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]);
+                        if (!args.out.couldBe(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 checkTruncFloatFloat" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTruncFloat2Float2() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 2, 0x49d4961dl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            script.forEach_testTruncFloat2Float2(inV, out);
+            verifyResultsTruncFloat2Float2(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat2Float2: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 2), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncFloat2Float2(inV, out);
+            verifyResultsTruncFloat2Float2(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat2Float2: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncFloat2Float2(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 2];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 2 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTrunc(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 checkTruncFloat2Float2" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTruncFloat3Float3() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 3, 0x3fefb6fbl, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            script.forEach_testTruncFloat3Float3(inV, out);
+            verifyResultsTruncFloat3Float3(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat3Float3: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 3), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncFloat3Float3(inV, out);
+            verifyResultsTruncFloat3Float3(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat3Float3: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncFloat3Float3(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTrunc(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 checkTruncFloat3Float3" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    private void checkTruncFloat4Float4() {
+        Allocation inV = createRandomAllocation(mRS, Element.DataType.FLOAT_32, 4, 0x360ad7d9l, false);
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            script.forEach_testTruncFloat4Float4(inV, out);
+            verifyResultsTruncFloat4Float4(inV, out, false);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat4Float4: " + e.toString());
+        }
+        try {
+            Allocation out = Allocation.createSized(mRS, getElement(mRS, Element.DataType.FLOAT_32, 4), INPUTSIZE);
+            scriptRelaxed.forEach_testTruncFloat4Float4(inV, out);
+            verifyResultsTruncFloat4Float4(inV, out, true);
+        } catch (Exception e) {
+            throw new RSRuntimeException("RenderScript. Can't invoke forEach_testTruncFloat4Float4: " + e.toString());
+        }
+    }
+
+    private void verifyResultsTruncFloat4Float4(Allocation inV, Allocation out, boolean relaxed) {
+        float[] arrayInV = new float[INPUTSIZE * 4];
+        Arrays.fill(arrayInV, (float) 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.
+                ArgumentsFloatFloat args = new ArgumentsFloatFloat();
+                args.inV = arrayInV[i * 4 + j];
+                // Figure out what the outputs should have been.
+                Target target = new Target(relaxed);
+                CoreMathVerifier.computeTrunc(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 checkTruncFloat4Float4" +
+                (relaxed ? "_relaxed" : "") + ":\n" + message.toString(), errorFound);
+    }
+
+    public void testTrunc() {
+        checkTruncFloatFloat();
+        checkTruncFloat2Float2();
+        checkTruncFloat3Float3();
+        checkTruncFloat4Float4();
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.rs b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.rs
new file mode 100644
index 0000000..350a351
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTrunc.rs
@@ -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.
+ */
+
+// 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)
+
+
+float __attribute__((kernel)) testTruncFloatFloat(float inV) {
+    return trunc(inV);
+}
+
+float2 __attribute__((kernel)) testTruncFloat2Float2(float2 inV) {
+    return trunc(inV);
+}
+
+float3 __attribute__((kernel)) testTruncFloat3Float3(float3 inV) {
+    return trunc(inV);
+}
+
+float4 __attribute__((kernel)) testTruncFloat4Float4(float4 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
new file mode 100644
index 0000000..617b687
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/generated/TestTruncRelaxed.rs
@@ -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.
+ */
+
+// Don't edit this file!  It is auto-generated by frameworks/rs/api/generate.sh.
+
+#include "TestTrunc.rs"
+#pragma rs_fp_relaxed
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/increment.rs b/tests/tests/renderscript/src/android/renderscript/cts/increment.rs
new file mode 100644
index 0000000..babc567
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/increment.rs
@@ -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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+int4 __attribute__((kernel)) increment(int4 in)
+{
+  return in + 1;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_blur.rs b/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_blur.rs
index 88f9ca5..aea9745 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_blur.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_blur.rs
@@ -74,7 +74,7 @@
     float4 blurredPixel = 0;
     int gi = 0;
     for (int r = -radius; r <= radius; r ++) {
-        int validH = rsClamp((int)y + r, (int)0, (int)(height - 1));
+        int validH = clamp((int)y + r, (int)0, (int)(height - 1));
         float4 i = rsGetElementAt_float4(ScratchPixel2, x, validH);
         blurredPixel += i * gaussian[gi++];
     }
@@ -86,11 +86,9 @@
     int gi = 0;
     for (int r = -radius; r <= radius; r ++) {
         // Stepping left and right away from the pixel
-        int validX = rsClamp((int)x + r, (int)0, (int)(width - 1));
+        int validX = clamp((int)x + r, (int)0, (int)(width - 1));
         float4 i = rsGetElementAt_float4(ScratchPixel1, validX, y);
         blurredPixel += i * gaussian[gi++];
     }
     return blurredPixel;
 }
-
-
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_resize.rs b/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_resize.rs
index fa8c8dd..ccdf42f 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_resize.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/intrinsic_resize.rs
@@ -242,3 +242,203 @@
     return (uchar)p;
 }
 
+float4 __attribute__((kernel)) bicubic_F4(uint32_t x, uint32_t y) {
+    float xf = (x + 0.5f) * scaleX - 0.5f;
+    float yf = (y + 0.5f) * scaleY - 0.5f;
+
+    int startx = (int) floor(xf - 1);
+    int starty = (int) floor(yf - 1);
+    xf = xf - floor(xf);
+    yf = yf - floor(yf);
+    int maxx = gWidthIn - 1;
+    int maxy = gHeightIn - 1;
+
+    uint32_t xs0 = (uint32_t) max(0, startx + 0);
+    uint32_t xs1 = (uint32_t) max(0, startx + 1);
+    uint32_t xs2 = (uint32_t) min(maxx, startx + 2);
+    uint32_t xs3 = (uint32_t) min(maxx, startx + 3);
+
+    uint32_t ys0 = (uint32_t) max(0, starty + 0);
+    uint32_t ys1 = (uint32_t) max(0, starty + 1);
+    uint32_t ys2 = (uint32_t) min(maxy, starty + 2);
+    uint32_t ys3 = (uint32_t) min(maxy, starty + 3);
+
+    float4 p00 = rsGetElementAt_float4(gIn, xs0, ys0);
+    float4 p01 = rsGetElementAt_float4(gIn, xs1, ys0);
+    float4 p02 = rsGetElementAt_float4(gIn, xs2, ys0);
+    float4 p03 = rsGetElementAt_float4(gIn, xs3, ys0);
+    float4 p0  = cubicInterpolate_F4(p00, p01, p02, p03, xf);
+
+    float4 p10 = rsGetElementAt_float4(gIn, xs0, ys1);
+    float4 p11 = rsGetElementAt_float4(gIn, xs1, ys1);
+    float4 p12 = rsGetElementAt_float4(gIn, xs2, ys1);
+    float4 p13 = rsGetElementAt_float4(gIn, xs3, ys1);
+    float4 p1  = cubicInterpolate_F4(p10, p11, p12, p13, xf);
+
+    float4 p20 = rsGetElementAt_float4(gIn, xs0, ys2);
+    float4 p21 = rsGetElementAt_float4(gIn, xs1, ys2);
+    float4 p22 = rsGetElementAt_float4(gIn, xs2, ys2);
+    float4 p23 = rsGetElementAt_float4(gIn, xs3, ys2);
+    float4 p2  = cubicInterpolate_F4(p20, p21, p22, p23, xf);
+
+    float4 p30 = rsGetElementAt_float4(gIn, xs0, ys3);
+    float4 p31 = rsGetElementAt_float4(gIn, xs1, ys3);
+    float4 p32 = rsGetElementAt_float4(gIn, xs2, ys3);
+    float4 p33 = rsGetElementAt_float4(gIn, xs3, ys3);
+    float4 p3  = cubicInterpolate_F4(p30, p31, p32, p33, xf);
+
+    float4 p  = cubicInterpolate_F4(p0, p1, p2, p3, yf);
+
+    return p;
+}
+
+float3 __attribute__((kernel)) bicubic_F3(uint32_t x, uint32_t y) {
+    float xf = (x + 0.5f) * scaleX - 0.5f;
+    float yf = (y + 0.5f) * scaleY - 0.5f;
+
+    int startx = (int) floor(xf - 1);
+    int starty = (int) floor(yf - 1);
+    xf = xf - floor(xf);
+    yf = yf - floor(yf);
+    int maxx = gWidthIn - 1;
+    int maxy = gHeightIn - 1;
+
+    uint32_t xs0 = (uint32_t) max(0, startx + 0);
+    uint32_t xs1 = (uint32_t) max(0, startx + 1);
+    uint32_t xs2 = (uint32_t) min(maxx, startx + 2);
+    uint32_t xs3 = (uint32_t) min(maxx, startx + 3);
+
+    uint32_t ys0 = (uint32_t) max(0, starty + 0);
+    uint32_t ys1 = (uint32_t) max(0, starty + 1);
+    uint32_t ys2 = (uint32_t) min(maxy, starty + 2);
+    uint32_t ys3 = (uint32_t) min(maxy, starty + 3);
+
+    float3 p00 = rsGetElementAt_float3(gIn, xs0, ys0);
+    float3 p01 = rsGetElementAt_float3(gIn, xs1, ys0);
+    float3 p02 = rsGetElementAt_float3(gIn, xs2, ys0);
+    float3 p03 = rsGetElementAt_float3(gIn, xs3, ys0);
+    float3 p0  = cubicInterpolate_F3(p00, p01, p02, p03, xf);
+
+    float3 p10 = rsGetElementAt_float3(gIn, xs0, ys1);
+    float3 p11 = rsGetElementAt_float3(gIn, xs1, ys1);
+    float3 p12 = rsGetElementAt_float3(gIn, xs2, ys1);
+    float3 p13 = rsGetElementAt_float3(gIn, xs3, ys1);
+    float3 p1  = cubicInterpolate_F3(p10, p11, p12, p13, xf);
+
+    float3 p20 = rsGetElementAt_float3(gIn, xs0, ys2);
+    float3 p21 = rsGetElementAt_float3(gIn, xs1, ys2);
+    float3 p22 = rsGetElementAt_float3(gIn, xs2, ys2);
+    float3 p23 = rsGetElementAt_float3(gIn, xs3, ys2);
+    float3 p2  = cubicInterpolate_F3(p20, p21, p22, p23, xf);
+
+    float3 p30 = rsGetElementAt_float3(gIn, xs0, ys3);
+    float3 p31 = rsGetElementAt_float3(gIn, xs1, ys3);
+    float3 p32 = rsGetElementAt_float3(gIn, xs2, ys3);
+    float3 p33 = rsGetElementAt_float3(gIn, xs3, ys3);
+    float3 p3  = cubicInterpolate_F3(p30, p31, p32, p33, xf);
+
+    float3 p  = cubicInterpolate_F3(p0, p1, p2, p3, yf);
+
+    return p;
+}
+
+float2 __attribute__((kernel)) bicubic_F2(uint32_t x, uint32_t y) {
+    float xf = (x + 0.5f) * scaleX - 0.5f;
+    float yf = (y + 0.5f) * scaleY - 0.5f;
+
+    int startx = (int) floor(xf - 1);
+    int starty = (int) floor(yf - 1);
+    xf = xf - floor(xf);
+    yf = yf - floor(yf);
+    int maxx = gWidthIn - 1;
+    int maxy = gHeightIn - 1;
+
+    uint32_t xs0 = (uint32_t) max(0, startx + 0);
+    uint32_t xs1 = (uint32_t) max(0, startx + 1);
+    uint32_t xs2 = (uint32_t) min(maxx, startx + 2);
+    uint32_t xs3 = (uint32_t) min(maxx, startx + 3);
+
+    uint32_t ys0 = (uint32_t) max(0, starty + 0);
+    uint32_t ys1 = (uint32_t) max(0, starty + 1);
+    uint32_t ys2 = (uint32_t) min(maxy, starty + 2);
+    uint32_t ys3 = (uint32_t) min(maxy, starty + 3);
+
+    float2 p00 = rsGetElementAt_float2(gIn, xs0, ys0);
+    float2 p01 = rsGetElementAt_float2(gIn, xs1, ys0);
+    float2 p02 = rsGetElementAt_float2(gIn, xs2, ys0);
+    float2 p03 = rsGetElementAt_float2(gIn, xs3, ys0);
+    float2 p0  = cubicInterpolate_F2(p00, p01, p02, p03, xf);
+
+    float2 p10 = rsGetElementAt_float2(gIn, xs0, ys1);
+    float2 p11 = rsGetElementAt_float2(gIn, xs1, ys1);
+    float2 p12 = rsGetElementAt_float2(gIn, xs2, ys1);
+    float2 p13 = rsGetElementAt_float2(gIn, xs3, ys1);
+    float2 p1  = cubicInterpolate_F2(p10, p11, p12, p13, xf);
+
+    float2 p20 = rsGetElementAt_float2(gIn, xs0, ys2);
+    float2 p21 = rsGetElementAt_float2(gIn, xs1, ys2);
+    float2 p22 = rsGetElementAt_float2(gIn, xs2, ys2);
+    float2 p23 = rsGetElementAt_float2(gIn, xs3, ys2);
+    float2 p2  = cubicInterpolate_F2(p20, p21, p22, p23, xf);
+
+    float2 p30 = rsGetElementAt_float2(gIn, xs0, ys3);
+    float2 p31 = rsGetElementAt_float2(gIn, xs1, ys3);
+    float2 p32 = rsGetElementAt_float2(gIn, xs2, ys3);
+    float2 p33 = rsGetElementAt_float2(gIn, xs3, ys3);
+    float2 p3  = cubicInterpolate_F2(p30, p31, p32, p33, xf);
+
+    float2 p  = cubicInterpolate_F2(p0, p1, p2, p3, yf);
+
+    return p;
+}
+
+float __attribute__((kernel)) bicubic_F1(uint32_t x, uint32_t y) {
+    float xf = (x + 0.5f) * scaleX - 0.5f;
+    float yf = (y + 0.5f) * scaleY - 0.5f;
+
+    int startx = (int) floor(xf - 1);
+    int starty = (int) floor(yf - 1);
+    xf = xf - floor(xf);
+    yf = yf - floor(yf);
+    int maxx = gWidthIn - 1;
+    int maxy = gHeightIn - 1;
+
+    uint32_t xs0 = (uint32_t) max(0, startx + 0);
+    uint32_t xs1 = (uint32_t) max(0, startx + 1);
+    uint32_t xs2 = (uint32_t) min(maxx, startx + 2);
+    uint32_t xs3 = (uint32_t) min(maxx, startx + 3);
+
+    uint32_t ys0 = (uint32_t) max(0, starty + 0);
+    uint32_t ys1 = (uint32_t) max(0, starty + 1);
+    uint32_t ys2 = (uint32_t) min(maxy, starty + 2);
+    uint32_t ys3 = (uint32_t) min(maxy, starty + 3);
+
+    float p00 = rsGetElementAt_float(gIn, xs0, ys0);
+    float p01 = rsGetElementAt_float(gIn, xs1, ys0);
+    float p02 = rsGetElementAt_float(gIn, xs2, ys0);
+    float p03 = rsGetElementAt_float(gIn, xs3, ys0);
+    float p0  = cubicInterpolate_F1(p00, p01, p02, p03, xf);
+
+    float p10 = rsGetElementAt_float(gIn, xs0, ys1);
+    float p11 = rsGetElementAt_float(gIn, xs1, ys1);
+    float p12 = rsGetElementAt_float(gIn, xs2, ys1);
+    float p13 = rsGetElementAt_float(gIn, xs3, ys1);
+    float p1  = cubicInterpolate_F1(p10, p11, p12, p13, xf);
+
+    float p20 = rsGetElementAt_float(gIn, xs0, ys2);
+    float p21 = rsGetElementAt_float(gIn, xs1, ys2);
+    float p22 = rsGetElementAt_float(gIn, xs2, ys2);
+    float p23 = rsGetElementAt_float(gIn, xs3, ys2);
+    float p2  = cubicInterpolate_F1(p20, p21, p22, p23, xf);
+
+    float p30 = rsGetElementAt_float(gIn, xs0, ys3);
+    float p31 = rsGetElementAt_float(gIn, xs1, ys3);
+    float p32 = rsGetElementAt_float(gIn, xs2, ys3);
+    float p33 = rsGetElementAt_float(gIn, xs3, ys3);
+    float p3  = cubicInterpolate_F1(p30, p31, p32, p33, xf);
+
+    float p  = cubicInterpolate_F1(p0, p1, p2, p3, yf);
+
+    return p;
+}
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/kernel_input.rs b/tests/tests/renderscript/src/android/renderscript/cts/kernel_input.rs
new file mode 100644
index 0000000..2eaca92
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/kernel_input.rs
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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(foo)
+
+#include "shared.rsh"
+
+static bool failed = false;
+
+/*
+ * This checks that modifications to input arguments done by a kernel
+ * are never reflected back to the input Allocation. In order to do
+ * this, we create kernels that modify their input arguments (the
+ * clear_input_* kernels).
+ *
+ * When the kernels modify their input arguments, these modifications
+ * should not be visible in the underlying Allocation. The
+ * verify_input_* functions can be passed the same Allocation that was
+ * used as an in input to a clear_input_* kernel. The verify_input_*
+ * functions check their input against a global variable.
+ */
+
+// 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.
+
+#define COMMON_TEST_CODE(type)                           \
+  type initial_value_##type;                             \
+  type RS_KERNEL clear_input_##type(volatile type in) {  \
+    rsDebug(#type, in);                                  \
+    in -= in;                                            \
+    rsDebug(#type, in);                                  \
+    return in;                                           \
+  }
+
+#define SCALAR_TEST(type)                         \
+  COMMON_TEST_CODE(type)                          \
+  void verify_input_##type(rs_allocation alloc) { \
+    type elem = rsGetElementAt_##type(alloc, 0);  \
+    _RS_ASSERT(elem == initial_value_##type);     \
+  }
+
+#define VEC2_TEST(type)                             \
+  COMMON_TEST_CODE(type)                            \
+  void verify_input_##type(rs_allocation alloc) {   \
+    type elem = rsGetElementAt_##type(alloc, 0);    \
+    _RS_ASSERT(elem[0] == initial_value_##type[0]); \
+    _RS_ASSERT(elem[1] == initial_value_##type[1]); \
+  }
+
+#define VEC3_TEST(type)                             \
+  COMMON_TEST_CODE(type)                            \
+  void verify_input_##type(rs_allocation alloc) {   \
+    type elem = rsGetElementAt_##type(alloc, 0);    \
+    _RS_ASSERT(elem[0] == initial_value_##type[0]); \
+    _RS_ASSERT(elem[1] == initial_value_##type[1]); \
+    _RS_ASSERT(elem[2] == initial_value_##type[2]); \
+  }
+
+#define VEC4_TEST(type)                             \
+  COMMON_TEST_CODE(type)                            \
+  void verify_input_##type(rs_allocation alloc) {   \
+    type elem = rsGetElementAt_##type(alloc, 0);    \
+    _RS_ASSERT(elem[0] == initial_value_##type[0]); \
+    _RS_ASSERT(elem[1] == initial_value_##type[1]); \
+    _RS_ASSERT(elem[2] == initial_value_##type[2]); \
+    _RS_ASSERT(elem[3] == initial_value_##type[3]); \
+  }
+
+SCALAR_TEST(char)
+
+VEC2_TEST(char2)
+
+VEC3_TEST(char3)
+
+VEC4_TEST(char4)
+
+SCALAR_TEST(double)
+
+VEC2_TEST(double2)
+
+VEC3_TEST(double3)
+
+VEC4_TEST(double4)
+
+SCALAR_TEST(float)
+
+VEC2_TEST(float2)
+
+VEC3_TEST(float3)
+
+VEC4_TEST(float4)
+
+SCALAR_TEST(int)
+
+VEC2_TEST(int2)
+
+VEC3_TEST(int3)
+
+VEC4_TEST(int4)
+
+SCALAR_TEST(long)
+
+VEC2_TEST(long2)
+
+VEC3_TEST(long3)
+
+VEC4_TEST(long4)
+
+SCALAR_TEST(short)
+
+VEC2_TEST(short2)
+
+VEC3_TEST(short3)
+
+VEC4_TEST(short4)
+
+SCALAR_TEST(uchar)
+
+VEC2_TEST(uchar2)
+
+VEC3_TEST(uchar3)
+
+VEC4_TEST(uchar4)
+
+SCALAR_TEST(uint)
+
+VEC2_TEST(uint2)
+
+VEC3_TEST(uint3)
+
+VEC4_TEST(uint4)
+
+SCALAR_TEST(ulong)
+
+VEC2_TEST(ulong2)
+
+VEC3_TEST(ulong3)
+
+VEC4_TEST(ulong4)
+
+SCALAR_TEST(ushort)
+
+VEC2_TEST(ushort2)
+
+VEC3_TEST(ushort3)
+
+VEC4_TEST(ushort4)
+
+typedef struct small {
+  int x[1];
+} small;
+
+typedef struct big {
+  int x[100];
+} big;
+
+small initial_value_small;
+
+// See comment on volatile above.
+small RS_KERNEL clear_input_small(volatile small in) {
+  rsDebug("in.x", in.x[0]);
+  in.x[0] = 0;
+  rsDebug("in.x", in.x[0]);
+  return in;
+}
+
+void verify_input_small(rs_allocation alloc) {
+  const small *elem = (const small *) rsGetElementAt(alloc, 0);
+  _RS_ASSERT(elem->x[0] == initial_value_small.x[0]);
+}
+
+big initial_value_big;
+
+// 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]);
+    in.x[i] = 0;
+    rsDebug("in.x", in.x[i]);
+  }
+  return in;
+}
+
+void verify_input_big(rs_allocation alloc) {
+  const big *elem = (const big *) rsGetElementAt(alloc, 0);
+  for (size_t i = 0; i < 100; ++i) {
+    _RS_ASSERT(elem->x[i] == initial_value_big.x[i]);
+  }
+}
+
+void checkError() {
+  if (failed) {
+    rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+  } else {
+    rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+  }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/launchclip.rs b/tests/tests/renderscript/src/android/renderscript/cts/launchclip.rs
new file mode 100644
index 0000000..ca34f4a
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/launchclip.rs
@@ -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.
+ */
+
+#include "shared.rsh"
+
+rs_allocation passfail;
+
+int dimX;
+int dimY;
+int dimZ;
+bool hasFaces;
+bool hasLod;
+int dimA0;
+int dimA1;
+int dimA2;
+int dimA3;
+
+int biasX = 0;
+int biasY = 0;
+int biasZ = 0;
+
+
+int RS_KERNEL zero() {
+    return 0;
+}
+
+int RS_KERNEL write1d(uint32_t x) {
+    return 0x80000000 | (x + biasX) | (biasY << 8) | (biasZ << 16);
+}
+
+int RS_KERNEL write2d(uint32_t x, uint32_t y) {
+    return 0x80000000 | (x + biasX) | ((y + biasY) << 8) | (biasZ << 16);
+}
+
+int RS_KERNEL write3d(uint32_t x, uint32_t y, uint32_t z) {
+    return 0x80000000 | (x + biasX) | ((y + biasY) << 8) | ((z + biasZ) << 16);
+}
+
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/matrix.rs b/tests/tests/renderscript/src/android/renderscript/cts/matrix.rs
new file mode 100644
index 0000000..8ea7c76
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/matrix.rs
@@ -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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+rs_matrix4x4 Mat;
+
+void setMatrix(rs_matrix4x4 m) {
+  Mat = m;
+}
+
+float4 __attribute__((kernel)) multiply(float4 in)
+{
+  return rsMatrixMultiply(&Mat, in);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/oob.rs b/tests/tests/renderscript/src/android/renderscript/cts/oob.rs
index b191c69..d27a8ca 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/oob.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/oob.rs
@@ -1,5 +1,4 @@
-#pragma version(1)
-#pragma rs java_package_name(android.renderscript.cts)
+#include "shared.rsh"
 
 rs_allocation aInt;
 
@@ -10,3 +9,4 @@
 void __attribute__((kernel)) write_k(int unused) {
     rsSetElementAt_int(aInt, 1, 1);
 }
+
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/reduction.rs b/tests/tests/renderscript/src/android/renderscript/cts/reduction.rs
new file mode 100644
index 0000000..19de6fe
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/reduction.rs
@@ -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.
+ */
+
+#pragma version(1)
+#pragma rs java_package_name(android.renderscript.cts)
+
+rs_allocation a;
+int reduction_stride;
+
+int4 __attribute__((kernel)) add(uint x)
+{
+  return rsGetElementAt_int4(a, x) + rsGetElementAt_int4(a, x + reduction_stride);
+}
+
+int4 __attribute__((kernel)) add2(uint x)
+{
+  rsSetElementAt_int4(a,
+                      rsGetElementAt_int4(a, x) +
+                      rsGetElementAt_int4(a, x + reduction_stride),
+                      x);
+  return 0;
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/rsAllocationCopyTest.java b/tests/tests/renderscript/src/android/renderscript/cts/rsAllocationCopyTest.java
new file mode 100644
index 0000000..f74fa38
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/rsAllocationCopyTest.java
@@ -0,0 +1,539 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Type;
+import java.util.Random;
+import android.util.Log;
+
+public class rsAllocationCopyTest extends RSBaseCompute {
+
+    public void test_rsAllocationCopy1D_Byte() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+        int offset = random.nextInt(arr_len);
+        int count = random.nextInt(arr_len - offset);
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8(mRS));
+        typeBuilder.setX(width);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn1D(aIn);
+        s.set_aOut1D(aOut);
+        s.set_xOff(offset);
+        s.set_xCount(count);
+        s.invoke_test1D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (offset <= i && i < offset + count) {
+                if (inArray[i] != outArray[i]) {
+                    result = false;
+                    break;
+                }
+            } else {
+                if (outArray[i] != 0) {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy1D_Byte failed, output array does not match input",
+                   result);
+    }
+
+    public void test_rsAllocationCopy1D_Short() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+        int offset = random.nextInt(arr_len);
+        int count = random.nextInt(arr_len - offset);
+
+        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(mRS));
+        typeBuilder.setX(width);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn1D(aIn);
+        s.set_aOut1D(aOut);
+        s.set_xOff(offset);
+        s.set_xCount(count);
+        s.invoke_test1D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (offset <= i && i < offset + count) {
+                if (inArray[i] != outArray[i]) {
+                    result = false;
+                    break;
+                }
+            } else {
+                if (outArray[i] != 0) {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy1D_Short failed, output array does not match input",
+                   result);
+    }
+
+    public void test_rsAllocationCopy1D_Int() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+        int offset = random.nextInt(arr_len);
+        int count = random.nextInt(arr_len - offset);
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        typeBuilder.setX(width);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn1D(aIn);
+        s.set_aOut1D(aOut);
+        s.set_xOff(offset);
+        s.set_xCount(count);
+        s.invoke_test1D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (offset <= i && i < offset + count) {
+                if (inArray[i] != outArray[i]) {
+                    result = false;
+                    break;
+                }
+            } else {
+                if (outArray[i] != 0) {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy1D_Int failed, output array does not match input",
+                   result);
+    }
+
+    public void test_rsAllocationCopy1D_Float() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+        int offset = random.nextInt(arr_len);
+        int count = random.nextInt(arr_len - offset);
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32(mRS));
+        typeBuilder.setX(width);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn1D(aIn);
+        s.set_aOut1D(aOut);
+        s.set_xOff(offset);
+        s.set_xCount(count);
+        s.invoke_test1D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (offset <= i && i < offset + count) {
+                if (inArray[i] != outArray[i]) {
+                    result = false;
+                    break;
+                }
+            } else {
+                if (outArray[i] != 0) {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy1D_Float failed, output array does not match input",
+                   result);
+    }
+
+    public void test_rsAllocationCopy1D_Long() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(512);
+        int arr_len = width;
+        int offset = random.nextInt(arr_len);
+        int count = random.nextInt(arr_len - offset);
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64(mRS));
+        typeBuilder.setX(width);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn1D(aIn);
+        s.set_aOut1D(aOut);
+        s.set_xOff(offset);
+        s.set_xCount(count);
+        s.invoke_test1D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < arr_len; i++) {
+            if (offset <= i && i < offset + count) {
+                if (inArray[i] != outArray[i]) {
+                    result = false;
+                    break;
+                }
+            } else {
+                if (outArray[i] != 0) {
+                    result = false;
+                    break;
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy1D_Long failed, output array does not match input",
+                   result);
+    }
+
+
+    public void test_rsAllocationCopy2D_Byte() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xOff = random.nextInt(width);
+        int yOff = random.nextInt(height);
+        int xCount = random.nextInt(width - xOff);
+        int yCount = random.nextInt(height - yOff);
+        int arr_len = width * height;
+
+        byte[] inArray = new byte[arr_len];
+        byte[] outArray = new byte[arr_len];
+        random.nextBytes(inArray);
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I8(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn2D(aIn);
+        s.set_aOut2D(aOut);
+        s.set_xOff(xOff);
+        s.set_yOff(yOff);
+        s.set_xCount(xCount);
+        s.set_yCount(yCount);
+        s.invoke_test2D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < height; i++) {
+            for (int j = 0; j < width; j++) {
+                int pos = i * width + j;
+                if (yOff <= i && i < yOff + yCount &&
+                    xOff <= j && j < xOff + xCount) {
+                    if (inArray[pos] != outArray[pos]) {
+                        result = false;
+                        break;
+                    }
+                } else {
+                    if (outArray[pos] != 0) {
+                        result = false;
+                        break;
+                    }
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy2D_Byte failed, output array does not match input",
+                   result);
+    }
+
+    public void test_rsAllocationCopy2D_Short() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xOff = random.nextInt(width);
+        int yOff = random.nextInt(height);
+        int xCount = random.nextInt(width - xOff);
+        int yCount = random.nextInt(height - yOff);
+        int arr_len = width * height;
+
+        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(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn2D(aIn);
+        s.set_aOut2D(aOut);
+        s.set_xOff(xOff);
+        s.set_yOff(yOff);
+        s.set_xCount(xCount);
+        s.set_yCount(yCount);
+        s.invoke_test2D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < height; i++) {
+            for (int j = 0; j < width; j++) {
+                int pos = i * width + j;
+                if (yOff <= i && i < yOff + yCount &&
+                    xOff <= j && j < xOff + xCount) {
+                    if (inArray[pos] != outArray[pos]) {
+                        result = false;
+                        break;
+                    }
+                } else {
+                    if (outArray[pos] != 0) {
+                        result = false;
+                        break;
+                    }
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy2D_Short failed, output array does not match input",
+                   result);
+    }
+
+    public void test_rsAllocationCopy2D_Int() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xOff = random.nextInt(width);
+        int yOff = random.nextInt(height);
+        int xCount = random.nextInt(width - xOff);
+        int yCount = random.nextInt(height - yOff);
+        int arr_len = width * height;
+
+        int[] inArray = new int[arr_len];
+        int[] outArray = new int[arr_len];
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextInt();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I32(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn2D(aIn);
+        s.set_aOut2D(aOut);
+        s.set_xOff(xOff);
+        s.set_yOff(yOff);
+        s.set_xCount(xCount);
+        s.set_yCount(yCount);
+        s.invoke_test2D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < height; i++) {
+            for (int j = 0; j < width; j++) {
+                int pos = i * width + j;
+                if (yOff <= i && i < yOff + yCount &&
+                    xOff <= j && j < xOff + xCount) {
+                    if (inArray[pos] != outArray[pos]) {
+                        result = false;
+                        break;
+                    }
+                } else {
+                    if (outArray[pos] != 0) {
+                        result = false;
+                        break;
+                    }
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy2D_Int failed, output array does not match input",
+                   result);
+    }
+
+    public void test_rsAllocationCopy2D_Float() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xOff = random.nextInt(width);
+        int yOff = random.nextInt(height);
+        int xCount = random.nextInt(width - xOff);
+        int yCount = random.nextInt(height - yOff);
+        int arr_len = width * height;
+
+        float[] inArray = new float[arr_len];
+        float[] outArray = new float[arr_len];
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextFloat();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.F32(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn2D(aIn);
+        s.set_aOut2D(aOut);
+        s.set_xOff(xOff);
+        s.set_yOff(yOff);
+        s.set_xCount(xCount);
+        s.set_yCount(yCount);
+        s.invoke_test2D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < height; i++) {
+            for (int j = 0; j < width; j++) {
+                int pos = i * width + j;
+                if (yOff <= i && i < yOff + yCount &&
+                    xOff <= j && j < xOff + xCount) {
+                    if (inArray[pos] != outArray[pos]) {
+                        result = false;
+                        break;
+                    }
+                } else {
+                    if (outArray[pos] != 0) {
+                        result = false;
+                        break;
+                    }
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy2D_Float failed, output array does not match input",
+                   result);
+    }
+
+    public void test_rsAllocationCopy2D_Long() {
+        Random random = new Random(0x172d8ab9);
+        int width = random.nextInt(128);
+        int height = random.nextInt(128);
+        int xOff = random.nextInt(width);
+        int yOff = random.nextInt(height);
+        int xCount = random.nextInt(width - xOff);
+        int yCount = random.nextInt(height - yOff);
+        int arr_len = width * height;
+
+        long[] inArray = new long[arr_len];
+        long[] outArray = new long[arr_len];
+        for (int i = 0; i < arr_len; i++) {
+            inArray[i] = random.nextLong();
+        }
+
+        Type.Builder typeBuilder = new Type.Builder(mRS, Element.I64(mRS));
+        typeBuilder.setX(width).setY(height);
+        Allocation aIn = Allocation.createTyped(mRS, typeBuilder.create());
+        Allocation aOut = Allocation.createTyped(mRS, typeBuilder.create());
+        aIn.copyFrom(inArray);
+        aOut.copyFrom(outArray);
+
+        ScriptC_rsallocationcopy s = new ScriptC_rsallocationcopy(mRS);
+        s.set_aIn2D(aIn);
+        s.set_aOut2D(aOut);
+        s.set_xOff(xOff);
+        s.set_yOff(yOff);
+        s.set_xCount(xCount);
+        s.set_yCount(yCount);
+        s.invoke_test2D();
+        mRS.finish();
+        aOut.copyTo(outArray);
+
+        boolean result = true;
+        for (int i = 0; i < height; i++) {
+            for (int j = 0; j < width; j++) {
+                int pos = i * width + j;
+                if (yOff <= i && i < yOff + yCount &&
+                    xOff <= j && j < xOff + xCount) {
+                    if (inArray[pos] != outArray[pos]) {
+                        result = false;
+                        break;
+                    }
+                } else {
+                    if (outArray[pos] != 0) {
+                        result = false;
+                        break;
+                    }
+                }
+            }
+        }
+        assertTrue("test_rsAllocationCopy2D_Long failed, output array does not match input",
+                   result);
+    }
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/rsallocationcopy.rs b/tests/tests/renderscript/src/android/renderscript/cts/rsallocationcopy.rs
new file mode 100644
index 0000000..4d76493
--- /dev/null
+++ b/tests/tests/renderscript/src/android/renderscript/cts/rsallocationcopy.rs
@@ -0,0 +1,19 @@
+#include "shared.rsh"
+
+rs_allocation aIn1D;
+rs_allocation aOut1D;
+rs_allocation aIn2D;
+rs_allocation aOut2D;
+
+int xOff = 0;
+int yOff = 0;
+int xCount = 0;
+int yCount = 0;
+
+void test1D() {
+    rsAllocationCopy1DRange(aOut1D, xOff, 0, xCount, aIn1D, xOff, 0);
+}
+
+void test2D() {
+    rsAllocationCopy2DRange(aOut2D, xOff, yOff, 0, 0, xCount, yCount, aIn2D, xOff, yOff, 0, 0);
+}
diff --git a/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh b/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh
index b91611d..2ad81fc 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh
+++ b/tests/tests/renderscript/src/android/renderscript/cts/shared.rsh
@@ -3,11 +3,11 @@
 
 static int64_t g_time;
 
-static void start(void) {
+static inline void start(void) {
     g_time = rsUptimeMillis();
 }
 
-static float end(void) {
+static inline float end(void) {
     int64_t t = rsUptimeMillis() - g_time;
     return ((float)t) / 1000.f;
 }
@@ -24,4 +24,3 @@
 /* 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/verify.rs b/tests/tests/renderscript/src/android/renderscript/cts/verify.rs
index 3563fee..c3ae802 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/verify.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/verify.rs
@@ -17,23 +17,24 @@
 #include "shared.rsh"
 
 int gAllowedIntError = 0;
+float gAllowedFloatError = 0.0001f;
+double gAllowedFloatMatError = 0.00000001;
+double gAllowedDoubleMatError = 0.00000000001;
 static bool hadError = false;
 static int2 errorLoc = {0,0};
 
-
 static bool compare_float(float f1, float f2) {
-    if (fabs(f1-f2) > 0.0001f) {
+    if (fabs(f1-f2) > gAllowedFloatError) {
         hadError = true;
         return false;
     }
     return true;
 }
 
-static bool verify_float4(rs_allocation in1, rs_allocation in2)
-{
+static bool verify_float4(rs_allocation in1, rs_allocation in2) {
     uint32_t w = rsAllocationGetDimX(in1);
     uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y=0; y < h; y++) {
+    for (uint32_t y = 0; y < h; y++) {
         for (uint32_t x=0; x < w; x++) {
             float4 pref = rsGetElementAt_float4(in1, x, y);
             float4 ptst = rsGetElementAt_float4(in2, x, y);
@@ -51,11 +52,10 @@
     return true;
 }
 
-static bool verify_float3(rs_allocation in1, rs_allocation in2)
-{
+static bool verify_float3(rs_allocation in1, rs_allocation in2) {
     uint32_t w = rsAllocationGetDimX(in1);
     uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y=0; y < h; y++) {
+    for (uint32_t y = 0; y < h; y++) {
         for (uint32_t x=0; x < w; x++) {
             float3 pref = rsGetElementAt_float3(in1, x, y);
             float3 ptst = rsGetElementAt_float3(in2, x, y);
@@ -72,11 +72,10 @@
     return true;
 }
 
-static bool verify_float2(rs_allocation in1, rs_allocation in2)
-{
+static bool verify_float2(rs_allocation in1, rs_allocation in2) {
     uint32_t w = rsAllocationGetDimX(in1);
     uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y=0; y < h; y++) {
+    for (uint32_t y = 0; y < h; y++) {
         for (uint32_t x=0; x < w; x++) {
             float2 pref = rsGetElementAt_float2(in1, x, y);
             float2 ptst = rsGetElementAt_float2(in2, x, y);
@@ -92,11 +91,10 @@
     return true;
 }
 
-static bool verify_float(rs_allocation in1, rs_allocation in2)
-{
+static bool verify_float(rs_allocation in1, rs_allocation in2) {
     uint32_t w = rsAllocationGetDimX(in1);
     uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y=0; y < h; y++) {
+    for (uint32_t y = 0; y < h; y++) {
         for (uint32_t x=0; x < w; x++) {
             float pref = rsGetElementAt_float(in1, x, y);
             float ptst = rsGetElementAt_float(in2, x, y);
@@ -111,12 +109,11 @@
     return true;
 }
 
-static bool verify_uchar4(rs_allocation in1, rs_allocation in2)
-{
+static bool verify_uchar4(rs_allocation in1, rs_allocation in2) {
     int merr = 0;
     uint32_t w = rsAllocationGetDimX(in1);
     uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y=0; y < h; y++) {
+    for (uint32_t y = 0; y < h; y++) {
         for (uint32_t x=0; x < w; x++) {
             int4 pref = convert_int4(rsGetElementAt_uchar4(in1, x, y));
             int4 ptst = convert_int4(rsGetElementAt_uchar4(in2, x, y));
@@ -138,12 +135,11 @@
     return true;
 }
 
-static bool verify_uchar3(rs_allocation in1, rs_allocation in2)
-{
+static bool verify_uchar3(rs_allocation in1, rs_allocation in2) {
     int merr = 0;
     uint32_t w = rsAllocationGetDimX(in1);
     uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y=0; y < h; y++) {
+    for (uint32_t y = 0; y < h; y++) {
         for (uint32_t x=0; x < w; x++) {
             int3 pref = convert_int3(rsGetElementAt_uchar3(in1, x, y));
             int3 ptst = convert_int3(rsGetElementAt_uchar3(in2, x, y));
@@ -164,12 +160,11 @@
     return true;
 }
 
-static bool verify_uchar2(rs_allocation in1, rs_allocation in2)
-{
+static bool verify_uchar2(rs_allocation in1, rs_allocation in2) {
     int merr = 0;
     uint32_t w = rsAllocationGetDimX(in1);
     uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y=0; y < h; y++) {
+    for (uint32_t y = 0; y < h; y++) {
         for (uint32_t x=0; x < w; x++) {
             int2 pref = convert_int2(rsGetElementAt_uchar2(in1, x, y));
             int2 ptst = convert_int2(rsGetElementAt_uchar2(in2, x, y));
@@ -189,12 +184,11 @@
     return true;
 }
 
-static bool verify_uchar(rs_allocation in1, rs_allocation in2)
-{
+static bool verify_uchar(rs_allocation in1, rs_allocation in2) {
     int merr = 0;
     uint32_t w = rsAllocationGetDimX(in1);
     uint32_t h = rsAllocationGetDimY(in1);
-    for (uint32_t y=0; y < h; y++) {
+    for (uint32_t y = 0; y < h; y++) {
         for (uint32_t x=0; x < w; x++) {
             int pref = rsGetElementAt_uchar(in1, x, y);
             int ptst = rsGetElementAt_uchar(in2, x, y);
@@ -232,7 +226,7 @@
             rsDebug(txt, rsGetElementAt_uchar(a, xy.x, xy.y)); \
             break; \
         } \
-    } else { \
+    } else if (dt == RS_TYPE_FLOAT_32) { \
         switch(vs) { \
         case 4: \
             rsDebug(txt, rsGetElementAt_float4(a, xy.x, xy.y)); \
@@ -247,11 +241,24 @@
             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)); \
+        } \
     } \
 }
 
-void verify(rs_allocation ref_in, rs_allocation tst_in, rs_allocation src_in)
-{
+void verify(rs_allocation ref_in, rs_allocation tst_in, rs_allocation src_in) {
     rs_element e = rsAllocationGetElement(ref_in);
     rs_data_type dt = rsElementGetDataType(e);
     uint32_t vs = rsElementGetVectorSize(e);
@@ -296,6 +303,135 @@
     }
 }
 
+
+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/renderscript/src/android/renderscript/cts/yuv.rs b/tests/tests/renderscript/src/android/renderscript/cts/yuv.rs
index 6d45331..4aa1564 100644
--- a/tests/tests/renderscript/src/android/renderscript/cts/yuv.rs
+++ b/tests/tests/renderscript/src/android/renderscript/cts/yuv.rs
@@ -56,6 +56,20 @@
     return (uchar4){p.x, p.y, p.z, p.w};
 }
 
+static float4 yuvToRGBA_f4(uchar y, uchar u, uchar v) {
+    float4 yuv_U_values = {0.f, -0.392f * 0.003921569f, +2.02 * 0.003921569f, 0.f};
+    float4 yuv_V_values = {1.603f * 0.003921569f, -0.815f * 0.003921569f, 0.f, 0.f};
+
+    float4 color = (float)y * 0.003921569f;
+    float4 fU = ((float)u) - 128.f;
+    float4 fV = ((float)v) - 128.f;
+
+    color += fU * yuv_U_values;
+    color += fV * yuv_V_values;
+    color = clamp(color, 0.f, 1.f);
+    return color;
+}
+
 void makeRef(rs_allocation ay, rs_allocation au, rs_allocation av, rs_allocation aout) {
     uint32_t w = rsAllocationGetDimX(ay);
     uint32_t h = rsAllocationGetDimY(ay);
@@ -80,6 +94,29 @@
     }
 }
 
+void makeRef_f4(rs_allocation ay, rs_allocation au, rs_allocation av, rs_allocation aout) {
+    uint32_t w = rsAllocationGetDimX(ay);
+    uint32_t h = rsAllocationGetDimY(ay);
+
+    for (int y = 0; y < h; y++) {
+        //rsDebug("y", y);
+        for (int x = 0; x < w; x++) {
+
+            uchar py = rsGetElementAt_uchar(ay, x, y);
+            uchar pu = rsGetElementAt_uchar(au, x >> 1, y >> 1);
+            uchar pv = rsGetElementAt_uchar(av, x >> 1, y >> 1);
+
+            //rsDebug("py", py);
+            //rsDebug(" u", pu);
+            //rsDebug(" v", pv);
+
+            float4 rgb = yuvToRGBA_f4(py, pu, pv);
+            //rsDebug("  ", rgb);
+
+            rsSetElementAt_float4(aout, rgb, x, y);
+        }
+    }
+}
 
 uchar4 __attribute__((kernel)) cvt(uint32_t x, uint32_t y) {
 
@@ -94,4 +131,16 @@
     return yuvToRGBA4(py, pu, pv);
 }
 
+float4 __attribute__((kernel)) cvt_f4(uint32_t x, uint32_t y) {
+
+    uchar py = rsGetElementAtYuv_uchar_Y(mInput, x, y);
+    uchar pu = rsGetElementAtYuv_uchar_U(mInput, x, y);
+    uchar pv = rsGetElementAtYuv_uchar_V(mInput, x, y);
+
+    //rsDebug("py2", py);
+    //rsDebug(" u2", pu);
+    //rsDebug(" v2", pv);
+
+    return rsYuvToRGBA_float4(py, pu, pv);
+}
 
diff --git a/tests/tests/rscpp/librscpptest/Android.mk b/tests/tests/rscpp/librscpptest/Android.mk
index 9813ba6..df8ce29f 100644
--- a/tests/tests/rscpp/librscpptest/Android.mk
+++ b/tests/tests/rscpp/librscpptest/Android.mk
@@ -17,18 +17,45 @@
 #
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_CLANG := true
 LOCAL_MODULE := librscpptest_jni
 LOCAL_MODULE_TAGS := optional
-LOCAL_SRC_FILES := rs_jni.cpp rs_jni_allocation.cpp
-LOCAL_SRC_FILES += setelementat.rs
+
+LOCAL_SRC_FILES := \
+    rs_jni.cpp \
+    rs_jni_allocation.cpp \
+    rs_jni_element.cpp \
+    rs_jni_foreach.cpp \
+    rs_jni_script.cpp \
+    rs_jni_type.cpp \
+    rs_jni_object.cpp
+
+LOCAL_SRC_FILES += \
+    setelementat.rs \
+    primitives.rs \
+    instance.rs \
+    clear_object.rs \
+    foreach.rs \
+    fe_all.rs \
+    noroot.rs \
+    vector.rs
 
 LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
 LOCAL_C_INCLUDES += frameworks/rs/cpp
 LOCAL_C_INCLUDES += frameworks/rs
-LOCAL_C_INCLUDES += external/stlport/stlport bionic/ bionic/libstdc++/include
 
 LOCAL_SHARED_LIBRARIES := libdl liblog
-LOCAL_STATIC_LIBRARIES := libRScpp_static libstlport_static libcutils
+LOCAL_STATIC_LIBRARIES := libRScpp_static libcutils
+
+ifeq ($(my_32_64_bit_suffix),32)
+    LOCAL_SDK_VERSION := 8
+else
+    LOCAL_SDK_VERSION := 21
+endif
+
+LOCAL_NDK_STL_VARIANT := stlport_static
+
 include $(BUILD_SHARED_LIBRARY)
 
 
diff --git a/tests/tests/rscpp/librscpptest/clear_object.rs b/tests/tests/rscpp/librscpptest/clear_object.rs
new file mode 100644
index 0000000..70ba42b
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/clear_object.rs
@@ -0,0 +1,42 @@
+#pragma version(1)
+#pragma rs java_package_name(com.android.cts.rscpp)
+
+rs_allocation allocation;
+
+void clear_allocation(int *out)
+{
+    rsClearObject( &allocation );
+    *out = ( NULL == allocation.p ? 1 : 0 );
+}
+
+rs_element element;
+
+void clear_element(int *out)
+{
+    rsClearObject( &element );
+    *out = ( NULL == element.p ? 1 : 0 );
+}
+
+rs_sampler sampler;
+
+void clear_sampler(int *out)
+{
+    rsClearObject( &sampler );
+    *out = ( NULL == sampler.p ? 1 : 0 );
+}
+
+rs_script script;
+
+void clear_script(int *out)
+{
+    rsClearObject( &script );
+    *out = ( NULL == script.p ? 1 : 0 );
+}
+
+rs_type type;
+
+void clear_type(int *out)
+{
+    rsClearObject( &type );
+    *out = ( NULL == type.p ? 1 : 0 );
+}
diff --git a/tests/tests/rscpp/librscpptest/fe_all.rs b/tests/tests/rscpp/librscpptest/fe_all.rs
new file mode 100644
index 0000000..dc20ba7
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/fe_all.rs
@@ -0,0 +1,163 @@
+#pragma version(1)
+#pragma rs java_package_name(com.android.cts.rscpp)
+
+void test_i8(const char *ain, uchar *aout) {
+    aout[0] = ain[0] + 1;
+    return;
+}
+
+void test_i8_2(const char2 *ain, uchar2 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    return;
+}
+
+void test_i8_3(const char3 *ain, uchar3 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    aout[0].z = ain[0].z + 1;
+    return;
+}
+
+void test_i8_4(const char4 *ain, uchar4 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    aout[0].z = ain[0].z + 1;
+    aout[0].w = ain[0].w + 1;
+    return;
+}
+
+void test_i16(const short *ain, ushort *aout) {
+    aout[0] = ain[0] + 1;
+    return;
+}
+
+void test_i16_2(const short2 *ain, ushort2 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    return;
+}
+
+void test_i16_3(const short3 *ain, ushort3 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    aout[0].z = ain[0].z + 1;
+    return;
+}
+
+void test_i16_4(const short4 *ain, ushort4 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    aout[0].z = ain[0].z + 1;
+    aout[0].w = ain[0].w + 1;
+    return;
+}
+
+void test_i32(const int *ain, uint *aout) {
+    aout[0] = ain[0] + 1;
+    return;
+}
+
+void test_i32_2(const int2 *ain, uint2 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    return;
+}
+
+void test_i32_3(const int3 *ain, uint3 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    aout[0].z = ain[0].z + 1;
+    return;
+}
+
+void test_i32_4(const int4 *ain, uint4 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    aout[0].z = ain[0].z + 1;
+    aout[0].w = ain[0].w + 1;
+    return;
+}
+
+void test_i64(const long *ain, ulong *aout) {
+    aout[0] = ain[0] + 1;
+    return;
+}
+
+void test_i64_2(const long2 *ain, ulong2 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    return;
+}
+
+void test_i64_3(const long3 *ain, ulong3 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    aout[0].z = ain[0].z + 1;
+    return;
+}
+
+void test_i64_4(const long4 *ain, ulong4 *aout) {
+    aout[0].x = ain[0].x + 1;
+    aout[0].y = ain[0].y + 1;
+    aout[0].z = ain[0].z + 1;
+    aout[0].w = ain[0].w + 1;
+    return;
+}
+
+void test_f32(const float *ain, float *aout) {
+    aout[0] = ain[0] + 1.0f;
+    return;
+}
+
+void test_f32_2(const float2 *ain, float2 *aout) {
+    aout[0].x = ain[0].x + 1.0f;
+    aout[0].y = ain[0].y + 1.0f;
+    return;
+}
+
+void test_f32_3(const float3 *ain, float3 *aout) {
+    aout[0].x = ain[0].x + 1.0f;
+    aout[0].y = ain[0].y + 1.0f;
+    aout[0].z = ain[0].z + 1.0f;
+    return;
+}
+
+void test_f32_4(const float4 *ain, float4 *aout) {
+    aout[0].x = ain[0].x + 1.0f;
+    aout[0].y = ain[0].y + 1.0f;
+    aout[0].z = ain[0].z + 1.0f;
+    aout[0].w = ain[0].w + 1.0f;
+    return;
+}
+
+void test_f64(const double *ain, double *aout) {
+    aout[0] = ain[0] + 1.0;
+    return;
+}
+
+void test_f64_2(const double2 *ain, double2 *aout) {
+    aout[0].x = ain[0].x + 1.0;
+    aout[0].y = ain[0].y + 1.0;
+    return;
+}
+
+void test_f64_3(const double3 *ain, double3 *aout) {
+    aout[0].x = ain[0].x + 1.0;
+    aout[0].y = ain[0].y + 1.0;
+    aout[0].z = ain[0].z + 1.0;
+    return;
+}
+
+void test_f64_4(const double4 *ain, double4 *aout) {
+    aout[0].x = ain[0].x + 1.0;
+    aout[0].y = ain[0].y + 1.0;
+    aout[0].z = ain[0].z + 1.0;
+    aout[0].w = ain[0].w + 1.0;
+    return;
+}
+
+void test_bool(const bool *ain, bool *aout) {
+    aout[0] = !ain[0];
+    return;
+}
diff --git a/tests/tests/rscpp/librscpptest/foreach.rs b/tests/tests/rscpp/librscpptest/foreach.rs
new file mode 100644
index 0000000..08e6bed
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/foreach.rs
@@ -0,0 +1,76 @@
+#include "shared.rsh"
+
+rs_allocation aRaw;
+int dimX;
+int dimY;
+static bool failed = false;
+
+void root(int *out, uint32_t x, uint32_t y) {
+    *out = x + y * dimX;
+}
+
+void foo(const int *in, int *out, uint32_t x, uint32_t y) {
+    _RS_ASSERT(*in == (x + y * dimX));
+    *out = 99 + x + y * dimX;
+    _RS_ASSERT(*out == (99 + x + y * dimX));
+}
+
+static bool test_root_output() {
+    bool failed = false;
+    int i, j;
+
+    for (j = 0; j < dimY; j++) {
+        for (i = 0; i < dimX; i++) {
+            int v = rsGetElementAt_int(aRaw, i, j);
+            _RS_ASSERT(v == (i + j * dimX));
+        }
+    }
+
+    if (failed) {
+        rsDebug("test_root_output FAILED", 0);
+    }
+    else {
+        rsDebug("test_root_output PASSED", 0);
+    }
+
+    return failed;
+}
+
+static bool test_foo_output() {
+    bool failed = false;
+    int i, j;
+
+    for (j = 0; j < dimY; j++) {
+        for (i = 0; i < dimX; i++) {
+            int v = rsGetElementAt_int(aRaw, i, j);
+            _RS_ASSERT(v == (99 + i + j * dimX));
+        }
+    }
+
+    if (failed) {
+        rsDebug("test_foo_output FAILED", 0);
+    }
+    else {
+        rsDebug("test_foo_output PASSED", 0);
+    }
+
+    return failed;
+}
+
+void verify_root() {
+    failed |= test_root_output();
+}
+
+void verify_foo() {
+    failed |= test_foo_output();
+}
+
+void foreach_test() {
+    if (failed) {
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
+
diff --git a/tests/tests/rscpp/librscpptest/instance.rs b/tests/tests/rscpp/librscpptest/instance.rs
new file mode 100644
index 0000000..097098a
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/instance.rs
@@ -0,0 +1,10 @@
+#include "shared.rsh"
+
+int i;
+rs_allocation ai;
+
+void instance_test() {
+    // Set our allocation based on the global input value.
+    rsSetElementAt(ai, &i, 0);
+}
+
diff --git a/tests/tests/rscpp/librscpptest/noroot.rs b/tests/tests/rscpp/librscpptest/noroot.rs
new file mode 100644
index 0000000..f69effc
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/noroot.rs
@@ -0,0 +1,46 @@
+#include "shared.rsh"
+
+int *a;
+rs_allocation aRaw;
+int dimX;
+int dimY;
+static bool failed = false;
+
+void foo(const int *in, int *out, uint32_t x, uint32_t y) {
+    *out = 99 + x + y * dimX;
+}
+
+static bool test_foo_output() {
+    bool failed = false;
+    int i, j;
+
+    for (j = 0; j < dimY; j++) {
+        for (i = 0; i < dimX; i++) {
+            int v = rsGetElementAt_int(aRaw, i, j);
+            _RS_ASSERT(v == (99 + i + j * dimX));
+        }
+    }
+
+    if (failed) {
+        rsDebug("test_foo_output FAILED", 0);
+    }
+    else {
+        rsDebug("test_foo_output PASSED", 0);
+    }
+
+    return failed;
+}
+
+void verify_foo() {
+    failed |= test_foo_output();
+}
+
+void noroot_test() {
+    if (failed) {
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+}
+
diff --git a/tests/tests/rscpp/librscpptest/primitives.rs b/tests/tests/rscpp/librscpptest/primitives.rs
new file mode 100644
index 0000000..8682331
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/primitives.rs
@@ -0,0 +1,53 @@
+#include "shared.rsh"
+
+// Testing primitive types
+float floatTest = 1.99f;
+double doubleTest = 2.05;
+char charTest = -8;
+short shortTest = -16;
+int intTest = -32;
+long longTest = 17179869184l; // 1 << 34
+long long longlongTest = 68719476736l; // 1 << 36
+bool boolTest = false;
+
+rs_allocation allocationTest;
+int *intPtrTest;
+
+uchar ucharTest = 8;
+ushort ushortTest = 16;
+uint uintTest = 32;
+ulong ulongTest = 4611686018427387904L;
+int64_t int64_tTest = -17179869184l; // - 1 << 34
+uint64_t uint64_tTest = 117179869184l;
+
+void test_primitive_types() {
+    bool failed = false;
+    start();
+
+    _RS_ASSERT(floatTest == 2.99f);
+    _RS_ASSERT(doubleTest == 3.05);
+    _RS_ASSERT(charTest == -16);
+    _RS_ASSERT(shortTest == -32);
+    _RS_ASSERT(intTest == -64);
+    _RS_ASSERT(longTest == 17179869185l);
+    _RS_ASSERT(longlongTest == 68719476735l);
+
+    _RS_ASSERT(ucharTest == 8);
+    _RS_ASSERT(ushortTest == 16);
+    _RS_ASSERT(uintTest == 32);
+    _RS_ASSERT(ulongTest == 4611686018427387903L);
+    _RS_ASSERT(int64_tTest == -17179869184l);
+    _RS_ASSERT(uint64_tTest == 117179869185l);
+
+    float time = end();
+
+    if (failed) {
+        rsDebug("test_primitive_types FAILED", time);
+        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
+    }
+    else {
+        rsDebug("test_primitive_types PASSED", time);
+        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
+    }
+
+}
diff --git a/tests/tests/rscpp/librscpptest/rs_jni.cpp b/tests/tests/rscpp/librscpptest/rs_jni.cpp
index f5946f5..4e60f4b 100644
--- a/tests/tests/rscpp/librscpptest/rs_jni.cpp
+++ b/tests/tests/rscpp/librscpptest/rs_jni.cpp
@@ -24,8 +24,7 @@
 #include <RenderScript.h>
 
 #define  LOG_TAG    "rscpptest"
-#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
-#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+#define  LOGV(...)  __android_log_print(ANDROID_LOG_VERBOSE,LOG_TAG,__VA_ARGS__)
 
 using namespace android::RSC;
 
@@ -51,6 +50,18 @@
     }
 }
 
+sp<const Element> makeElement(sp<RS> rs, RsDataType dt, int vecSize) {
+    if (vecSize > 1) {
+        return Element::createVector(rs, dt, vecSize);
+    } else {
+        if (dt == RS_TYPE_UNSIGNED_8) {
+            return Element::U8(rs);
+        } else {
+            return Element::F32(rs);
+        }
+    }
+}
+
 extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSInitTest_initTest(JNIEnv * env,
                                                                                  jclass obj,
                                                                                  jstring pathObj)
@@ -60,7 +71,7 @@
     for (int i = 0; i < 1000; i++) {
         sp<RS> rs = new RS();
         r &= rs->init(path);
-        LOGE("Native iteration %i, returned %i", i, (int)r);
+        LOGV("Native iteration %i, returned %i", i, (int)r);
     }
     env->ReleaseStringUTFChars(pathObj, path);
     return r;
@@ -371,4 +382,114 @@
 
 }
 
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSResizeTest_resizeTest(JNIEnv * env,
+                                                                                     jclass obj,
+                                                                                     jstring pathObj,
+                                                                                     jint X,
+                                                                                     jint Y,
+                                                                                     jfloat scaleX,
+                                                                                     jfloat scaleY,
+                                                                                     jboolean useByte,
+                                                                                     jint vecSize,
+                                                                                     jbyteArray inputByteArray,
+                                                                                     jbyteArray outputByteArray,
+                                                                                     jfloatArray inputFloatArray,
+                                                                                     jfloatArray outputFloatArray
+                                                                                     )
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+
+    sp<RS> rs = new RS();
+    rs->init(path);
+
+    RsDataType dt = RS_TYPE_UNSIGNED_8;
+    if (!useByte) {
+        dt = RS_TYPE_FLOAT_32;
+    }
+    sp<const Element> e = makeElement(rs, dt, vecSize);
+    sp<Allocation> inputAlloc = Allocation::createSized2D(rs, e, X, Y);
+
+    int outX = (int) (X * scaleX);
+    int outY = (int) (Y * scaleY);
+    sp<Allocation> outputAlloc = Allocation::createSized2D(rs, e, outX, outY);
+    sp<ScriptIntrinsicResize> resize = ScriptIntrinsicResize::create(rs);
+
+    if (useByte) {
+        jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
+        inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
+        env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
+    } else {
+        jfloat * input = (jfloat *) env->GetPrimitiveArrayCritical(inputFloatArray, 0);
+        inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
+        env->ReleasePrimitiveArrayCritical(inputFloatArray, input, 0);
+    }
+
+    resize->setInput(inputAlloc);
+    resize->forEach_bicubic(outputAlloc);
+
+    if (useByte) {
+        jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
+        outputAlloc->copy2DRangeTo(0, 0, outX, outY, output);
+        env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
+    } else {
+        jfloat * output = (jfloat *) env->GetPrimitiveArrayCritical(outputFloatArray, 0);
+        outputAlloc->copy2DRangeTo(0, 0, outX, outY, output);
+        env->ReleasePrimitiveArrayCritical(outputFloatArray, output, 0);
+    }
+
+    env->ReleaseStringUTFChars(pathObj, path);
+    return (rs->getError() == RS_SUCCESS);
+
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSYuvTest_yuvTest(JNIEnv * env,
+                                                                               jclass obj,
+                                                                               jstring pathObj,
+                                                                               jint X,
+                                                                               jint Y,
+                                                                               jbyteArray inputByteArray,
+                                                                               jbyteArray outputByteArray,
+                                                                               jint yuvFormat
+                                                                               )
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    jbyte * input = (jbyte *) env->GetPrimitiveArrayCritical(inputByteArray, 0);
+    jbyte * output = (jbyte *) env->GetPrimitiveArrayCritical(outputByteArray, 0);
+
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+
+    RSYuvFormat mYuvFormat = (RSYuvFormat)yuvFormat;
+    sp<ScriptIntrinsicYuvToRGB> syuv = ScriptIntrinsicYuvToRGB::create(mRS, Element::U8_4(mRS));;
+    sp<Allocation> inputAlloc = nullptr;
+
+    if (mYuvFormat != RS_YUV_NONE) {
+        //syuv = ScriptIntrinsicYuvToRGB::create(mRS, Element::YUV(mRS));
+        Type::Builder tb(mRS, Element::YUV(mRS));
+        tb.setX(X);
+        tb.setY(Y);
+        tb.setYuvFormat(mYuvFormat);
+        inputAlloc = Allocation::createTyped(mRS, tb.create());
+        inputAlloc->copy2DRangeFrom(0, 0, X, Y, input);
+    } else {
+        //syuv = ScriptIntrinsicYuvToRGB::create(mRS, Element::U8(mRS));
+        size_t arrLen = X * Y + ((X + 1) / 2) * ((Y + 1) / 2) * 2;
+        inputAlloc = Allocation::createSized(mRS, Element::U8(mRS), arrLen);
+        inputAlloc->copy1DRangeFrom(0, arrLen, input);
+    }
+
+    sp<const Type> tout = Type::create(mRS, Element::RGBA_8888(mRS), X, Y, 0);
+    sp<Allocation> outputAlloc = Allocation::createTyped(mRS, tout);
+
+    syuv->setInput(inputAlloc);
+    syuv->forEach(outputAlloc);
+
+    outputAlloc->copy2DRangeTo(0, 0, X, Y, output);
+
+    env->ReleasePrimitiveArrayCritical(inputByteArray, input, 0);
+    env->ReleasePrimitiveArrayCritical(outputByteArray, output, 0);
+    env->ReleaseStringUTFChars(pathObj, path);
+    return (mRS->getError() == RS_SUCCESS);
+
+}
 
diff --git a/tests/tests/rscpp/librscpptest/rs_jni_allocation.cpp b/tests/tests/rscpp/librscpptest/rs_jni_allocation.cpp
index 4157026..4b8b8a8 100644
--- a/tests/tests/rscpp/librscpptest/rs_jni_allocation.cpp
+++ b/tests/tests/rscpp/librscpptest/rs_jni_allocation.cpp
@@ -31,8 +31,8 @@
 
 using namespace android::RSC;
 
-static void createTypedHelper (sp<RS> mRS, sp<const Element> e) {
-    Type::Builder typeBuilder(mRS, e);
+static void createTypedHelper (sp<RS> rs, sp<const Element> e) {
+    Type::Builder typeBuilder(rs, e);
     for (int mips = 0; mips <= 1; mips ++) {
         bool useMips = (mips == 1);
 
@@ -45,7 +45,7 @@
                     typeBuilder.setFaces(useFaces);
                     typeBuilder.setX(x);
                     typeBuilder.setY(y);
-                    Allocation::createTyped(mRS, typeBuilder.create());
+                    Allocation::createTyped(rs, typeBuilder.create());
                 }
             }
         }
@@ -58,236 +58,147 @@
                                                                                         jstring pathObj)
 {
     const char * path = env->GetStringUTFChars(pathObj, NULL);
-    sp<RS> mRS = new RS();
-    mRS->init(path);
+    sp<RS> rs = new RS();
+    rs->init(path);
     env->ReleaseStringUTFChars(pathObj, path);
 
-    createTypedHelper(mRS, Element::A_8(mRS));
-    createTypedHelper(mRS, Element::RGBA_4444(mRS));
-    createTypedHelper(mRS, Element::RGBA_5551(mRS));
-    createTypedHelper(mRS, Element::RGB_565(mRS));
-    createTypedHelper(mRS, Element::RGB_888(mRS));
-    createTypedHelper(mRS, Element::RGBA_8888(mRS));
-    createTypedHelper(mRS, Element::F32(mRS));
-    createTypedHelper(mRS, Element::F32_2(mRS));
-    createTypedHelper(mRS, Element::F32_3(mRS));
-    createTypedHelper(mRS, Element::F32_4(mRS));
-    createTypedHelper(mRS, Element::F64(mRS));
-    createTypedHelper(mRS, Element::F64_2(mRS));
-    createTypedHelper(mRS, Element::F64_3(mRS));
-    createTypedHelper(mRS, Element::F64_4(mRS));
-    createTypedHelper(mRS, Element::I8(mRS));
-    createTypedHelper(mRS, Element::I8_2(mRS));
-    createTypedHelper(mRS, Element::I8_3(mRS));
-    createTypedHelper(mRS, Element::I8_4(mRS));
-    createTypedHelper(mRS, Element::I16(mRS));
-    createTypedHelper(mRS, Element::I16_2(mRS));
-    createTypedHelper(mRS, Element::I16_3(mRS));
-    createTypedHelper(mRS, Element::I16_4(mRS));
-    createTypedHelper(mRS, Element::I32(mRS));
-    createTypedHelper(mRS, Element::I32_2(mRS));
-    createTypedHelper(mRS, Element::I32_3(mRS));
-    createTypedHelper(mRS, Element::I32_4(mRS));
-    createTypedHelper(mRS, Element::I64(mRS));
-    createTypedHelper(mRS, Element::I64_2(mRS));
-    createTypedHelper(mRS, Element::I64_3(mRS));
-    createTypedHelper(mRS, Element::I64_4(mRS));
-    createTypedHelper(mRS, Element::U8(mRS));
-    createTypedHelper(mRS, Element::U8_2(mRS));
-    createTypedHelper(mRS, Element::U8_3(mRS));
-    createTypedHelper(mRS, Element::U8_4(mRS));
-    createTypedHelper(mRS, Element::U16(mRS));
-    createTypedHelper(mRS, Element::U16_2(mRS));
-    createTypedHelper(mRS, Element::U16_3(mRS));
-    createTypedHelper(mRS, Element::U16_4(mRS));
-    createTypedHelper(mRS, Element::U32(mRS));
-    createTypedHelper(mRS, Element::U32_2(mRS));
-    createTypedHelper(mRS, Element::U32_3(mRS));
-    createTypedHelper(mRS, Element::U32_4(mRS));
-    createTypedHelper(mRS, Element::U64(mRS));
-    createTypedHelper(mRS, Element::U64_2(mRS));
-    createTypedHelper(mRS, Element::U64_3(mRS));
-    createTypedHelper(mRS, Element::U64_4(mRS));
-    createTypedHelper(mRS, Element::MATRIX_2X2(mRS));
-    createTypedHelper(mRS, Element::MATRIX_3X3(mRS));
-    createTypedHelper(mRS, Element::MATRIX_4X4(mRS));
-    createTypedHelper(mRS, Element::SAMPLER(mRS));
-    createTypedHelper(mRS, Element::SCRIPT(mRS));
-    createTypedHelper(mRS, Element::TYPE(mRS));
-    createTypedHelper(mRS, Element::BOOLEAN(mRS));
-    createTypedHelper(mRS, Element::ELEMENT(mRS));
-    createTypedHelper(mRS, Element::ALLOCATION(mRS));
+    createTypedHelper(rs, Element::A_8(rs));
+    createTypedHelper(rs, Element::RGBA_4444(rs));
+    createTypedHelper(rs, Element::RGBA_5551(rs));
+    createTypedHelper(rs, Element::RGB_565(rs));
+    createTypedHelper(rs, Element::RGB_888(rs));
+    createTypedHelper(rs, Element::RGBA_8888(rs));
+    createTypedHelper(rs, Element::F32(rs));
+    createTypedHelper(rs, Element::F32_2(rs));
+    createTypedHelper(rs, Element::F32_3(rs));
+    createTypedHelper(rs, Element::F32_4(rs));
+    createTypedHelper(rs, Element::F64(rs));
+    createTypedHelper(rs, Element::F64_2(rs));
+    createTypedHelper(rs, Element::F64_3(rs));
+    createTypedHelper(rs, Element::F64_4(rs));
+    createTypedHelper(rs, Element::I8(rs));
+    createTypedHelper(rs, Element::I8_2(rs));
+    createTypedHelper(rs, Element::I8_3(rs));
+    createTypedHelper(rs, Element::I8_4(rs));
+    createTypedHelper(rs, Element::I16(rs));
+    createTypedHelper(rs, Element::I16_2(rs));
+    createTypedHelper(rs, Element::I16_3(rs));
+    createTypedHelper(rs, Element::I16_4(rs));
+    createTypedHelper(rs, Element::I32(rs));
+    createTypedHelper(rs, Element::I32_2(rs));
+    createTypedHelper(rs, Element::I32_3(rs));
+    createTypedHelper(rs, Element::I32_4(rs));
+    createTypedHelper(rs, Element::I64(rs));
+    createTypedHelper(rs, Element::I64_2(rs));
+    createTypedHelper(rs, Element::I64_3(rs));
+    createTypedHelper(rs, Element::I64_4(rs));
+    createTypedHelper(rs, Element::U8(rs));
+    createTypedHelper(rs, Element::U8_2(rs));
+    createTypedHelper(rs, Element::U8_3(rs));
+    createTypedHelper(rs, Element::U8_4(rs));
+    createTypedHelper(rs, Element::U16(rs));
+    createTypedHelper(rs, Element::U16_2(rs));
+    createTypedHelper(rs, Element::U16_3(rs));
+    createTypedHelper(rs, Element::U16_4(rs));
+    createTypedHelper(rs, Element::U32(rs));
+    createTypedHelper(rs, Element::U32_2(rs));
+    createTypedHelper(rs, Element::U32_3(rs));
+    createTypedHelper(rs, Element::U32_4(rs));
+    createTypedHelper(rs, Element::U64(rs));
+    createTypedHelper(rs, Element::U64_2(rs));
+    createTypedHelper(rs, Element::U64_3(rs));
+    createTypedHelper(rs, Element::U64_4(rs));
+    createTypedHelper(rs, Element::MATRIX_2X2(rs));
+    createTypedHelper(rs, Element::MATRIX_3X3(rs));
+    createTypedHelper(rs, Element::MATRIX_4X4(rs));
+    createTypedHelper(rs, Element::SAMPLER(rs));
+    createTypedHelper(rs, Element::SCRIPT(rs));
+    createTypedHelper(rs, Element::TYPE(rs));
+    createTypedHelper(rs, Element::BOOLEAN(rs));
+    createTypedHelper(rs, Element::ELEMENT(rs));
+    createTypedHelper(rs, Element::ALLOCATION(rs));
 
-    mRS->finish();
+    rs->finish();
     return true;
 }
 
-static bool helperFloatCopy(sp<RS> mRS, int nElems, int offset, int count, int copyMode) {
+static sp<const Element> makeElement(sp<RS> rs, RsDataType dt, int vecSize) {
+    if (vecSize > 1) {
+        return Element::createVector(rs, dt, vecSize);
+    } else {
+        return Element::createUser(rs, dt);
+    }
+}
+
+/**
+ * Test copyTo and copyFrom for all or part of a 1D Allocation.
+ *
+ * @param rs RS Context.
+ * @param cellCount Total number of elements in this Allocation.
+ * @param offset Offset of this Allocation for copy.
+ * @param count Number of elements need to copy.
+ * @param copyRange Copy the entire allocation or part of it (using different API).
+ * @param dt DataType intended to test.
+ * @param autoPadding Enable autoPadding or not. 
+*/
+template <class T>
+static bool helperCopy1D(sp<RS> rs, int cellCount, int offset, int count, bool copyRange,
+                         RsDataType dt, bool autoPadding = false) {
     bool passed = true;
-    sp<Allocation> A = Allocation::createSized(mRS, Element::F32(mRS), nElems);
+    int arrLen = cellCount;
+    int copyCount = count;
+    int iOffset = offset;
+    sp<Allocation> alloc = nullptr;
+
+    if (autoPadding) {
+        arrLen = cellCount * 3;
+        copyCount = count * 3;
+        iOffset = offset * 3;
+        alloc = Allocation::createSized(rs, makeElement(rs, dt, 3), cellCount);
+        alloc->setAutoPadding(autoPadding);
+    } else {
+        alloc = Allocation::createSized(rs, makeElement(rs, dt, 1), cellCount);
+    }
+
+    T* src = new T[arrLen];
+    T* dst = new T[arrLen];
+
+    for (int i = 0; i < copyCount; i++) {
+        src[i] = (T)rand();
+        dst[iOffset + i] = (T)(-1);
+    }
+
+    if (!copyRange) {
+        alloc->copy1DFrom(src);
+    } else {
+        alloc->copy1DRangeFrom(offset, count, src);
+    }
+    alloc->copy1DTo(dst);
+
+    for (int i = 0; i < copyCount; i++) {
+        if (dst[iOffset + i] != src[i]) {
+            passed = false;
+            break;
+        }
+    }
+
+    delete[] src;
+    delete[] dst;
+    return passed;
+}
+
+//Corresponding 1D allocation to allocation copy.
+static bool helperFloatAllocationCopy1D(sp<RS> rs, int cellCount, int offset, int count) {
+
+    bool passed = true;
+    sp<Allocation> srcA = Allocation::createSized(rs, Element::F32(rs), cellCount);
+    sp<Allocation> dstA = Allocation::createSized(rs, Element::F32(rs), cellCount);
 
     float *src, *dst;
-    src = new float[nElems];
-    dst = new float[nElems];
-
-    for (int i = 0; i < count; i++) {
-        src[i] = (float)i;
-        dst[offset + i] = -1.0f;
-    }
-
-    switch (copyMode) {
-    case 0: A->copy1DFrom(src); break;
-    case 1: A->copy1DRangeFrom(offset, count, src); break;
-    }
-    A->copy1DTo(dst);
-
-    for (int i = 0; i < count; i++) {
-        if (dst[offset + i] != src[i]) {
-            passed = false;
-            break;
-        }
-    }
-
-    delete[] src;
-    delete[] dst;
-    return passed;
-}
-
-static bool helperCharCopy(sp<RS> mRS, int nElems, int offset, int count, int copyMode) {
-    bool passed = true;
-    sp<Allocation> A = Allocation::createSized(mRS, Element::I8(mRS), nElems);
-
-    char *src, *dst;
-    src = new char[nElems];
-    dst = new char[nElems];
-
-    for (int i = 0; i < count; i++) {
-        src[i] = (char)i;
-        dst[offset + i] = -1;
-    }
-
-    switch (copyMode) {
-    case 0: A->copy1DFrom(src); break;
-    case 1: A->copy1DRangeFrom(offset, count, src); break;
-    }
-    A->copy1DTo(dst);
-
-    for (int i = 0; i < count; i++) {
-        if (dst[offset + i] != src[i]) {
-            passed = false;
-            break;
-        }
-    }
-
-    delete[] src;
-    delete[] dst;
-    return passed;
-}
-
-static bool helperShortCopy(sp<RS> mRS, int nElems, int offset, int count, int copyMode) {
-    bool passed = true;
-    sp<Allocation> A = Allocation::createSized(mRS, Element::I16(mRS), nElems);
-
-    short *src, *dst;
-    src = new short[nElems];
-    dst = new short[nElems];
-
-    for (int i = 0; i < count; i++) {
-        src[i] = (short)i;
-        dst[offset + i] = -1;
-    }
-
-    switch (copyMode) {
-    case 0: A->copy1DFrom(src); break;
-    case 1: A->copy1DRangeFrom(offset, count, src); break;
-    }
-    A->copy1DTo(dst);
-
-    for (int i = 0; i < count; i++) {
-        if (dst[offset + i] != src[i]) {
-            passed = false;
-            break;
-        }
-    }
-
-    delete[] src;
-    delete[] dst;
-    return passed;
-}
-
-static bool helperIntCopy(sp<RS> mRS, int nElems, int offset, int count, int copyMode) {
-    bool passed = true;
-    sp<Allocation> A = Allocation::createSized(mRS, Element::I32(mRS), nElems);
-
-    int *src, *dst;
-    src = new int[nElems];
-    dst = new int[nElems];
-
-    for (int i = 0; i < count; i++) {
-        src[i] = (int)i;
-        dst[offset + i] = -1;
-    }
-
-    switch (copyMode) {
-    case 0: A->copy1DFrom(src); break;
-    case 1: A->copy1DRangeFrom(offset, count, src); break;
-    }
-    A->copy1DTo(dst);
-
-    for (int i = 0; i < count; i++) {
-        if (dst[offset + i] != src[i]) {
-            passed = false;
-            break;
-        }
-    }
-
-    delete[] src;
-    delete[] dst;
-    return passed;
-}
-
-static bool helperDoubleCopy(sp<RS> mRS, int nElems, int offset, int count, int copyMode) {
-    bool passed = true;
-    sp<Allocation> A = Allocation::createSized(mRS, Element::F64(mRS), nElems);
-
-    double *src, *dst;
-    src = new double[nElems];
-    dst = new double[nElems];
-
-    for (int i = 0; i < count; i++) {
-        src[i] = (double)i;
-        dst[offset + i] = -1;
-    }
-
-    switch (copyMode) {
-    case 0: A->copy1DFrom(src); break;
-    case 1: A->copy1DRangeFrom(offset, count, src); break;
-    }
-    A->copy1DTo(dst);
-
-    for (int i = 0; i < count; i++) {
-        if (dst[offset + i] != src[i]) {
-            passed = false;
-            break;
-        }
-    }
-
-    delete[] src;
-    delete[] dst;
-    return passed;
-}
-
-static bool helperFloatAllocationCopy(sp<RS> mRS, int nElems, int offset, int count) {
-
-    bool passed = true;
-    sp<Allocation> srcA = Allocation::createSized(mRS, Element::F32(mRS), nElems);
-    sp<Allocation> dstA = Allocation::createSized(mRS, Element::F32(mRS), nElems);
-
-    float *src, *dst;
-    src = new float[nElems];
-    dst = new float[nElems];
-    for (int i = 0; i < nElems; i++) {
-        src[i] = (float)i;
+    src = new float[cellCount];
+    dst = new float[cellCount];
+    for (int i = 0; i < cellCount; i++) {
+        src[i] = (float)rand();
         dst[i] = -1.0f;
     }
 
@@ -309,6 +220,205 @@
     return passed;
 }
 
+/**
+ * Test copyTo and copyFrom for all or part of a 2D Allocation.
+ *
+ * @param rs RS Context.
+ * @param xElems Number of elements in X dimension in this Allocation.
+ * @param yElems Number of elements in Y dimension in this Allocation.
+ * @param xOffset Offset in X dimension of this Allocation for copy.
+ * @param yOffset Offset in Y dimension of this Allocation for copy.
+ * @param xCount Number of elements in X dimension need to copy.
+ * @param yCount Number of elements in Y dimension need to copy.
+ * @param dt DataType intended to test.
+ * @param autoPadding Enable autoPadding or not. 
+*/
+template <class T>
+static bool helperCopy2D(sp<RS> rs, int xElems, int yElems,
+                         int xOffset, int yOffset, int xCount, int yCount,
+                         RsDataType dt, bool autoPadding = false) {
+    bool passed = true;
+    int arrLen = xElems * yElems;
+    int copyCount = xCount * yCount;
+    sp<Allocation> alloc = nullptr;
+
+    if (autoPadding) {
+        arrLen = arrLen * 3;
+        copyCount = copyCount * 3;
+        alloc = Allocation::createSized2D(rs, makeElement(rs, dt, 3), xElems, yElems);
+        alloc->setAutoPadding(autoPadding);
+    } else {
+        alloc = Allocation::createSized2D(rs, makeElement(rs, dt, 1), xElems, yElems);
+    }
+
+    T* src = new T[arrLen];
+    T* dst = new T[arrLen];
+
+    for (int i = 0; i < copyCount; i++) {
+        src[i] = (T)rand();
+        dst[i] = (T)(-1);
+    }
+
+    alloc->copy2DRangeFrom(xOffset, yOffset, xCount, yCount, src);
+    alloc->copy2DRangeTo(xOffset, yOffset, xCount, yCount, dst);
+
+    for (int i = 0; i < copyCount; i++) {
+        if (dst[i] != src[i]) {
+            passed = false;
+            break;
+        }
+    }
+
+    delete[] src;
+    delete[] dst;
+    return passed;
+}
+
+//Corresponding 2D allocation to allocation copy.
+static bool helperFloatAllocationCopy2D(sp<RS> rs, int xElems, int yElems,
+                                        int xOffset, int yOffset, int xCount, int yCount) {
+
+    bool passed = true;
+    sp<Allocation> srcA = Allocation::createSized2D(rs, Element::F32(rs), xElems, yElems);
+    sp<Allocation> dstA = Allocation::createSized2D(rs, Element::F32(rs), xElems, yElems);
+
+    float *src, *dst;
+    src = new float[xElems * yElems];
+    dst = new float[xElems * yElems];
+    for (int i = 0; i < xCount * yCount; i++) {
+        src[i] = (float)rand();
+        dst[i] = -1.0f;
+    }
+
+    // First populate the source allocation
+    srcA->copy2DRangeFrom(xOffset, yOffset, xCount, yCount, src);
+    // Now test allocation to allocation copy
+    dstA->copy2DRangeFrom(xOffset, yOffset, xCount, yCount, srcA, xOffset, yOffset);
+    dstA->copy2DRangeTo(xOffset, yOffset, xCount, yCount, dst);
+
+    for (int i = 0; i < xCount * yCount; i++) {
+        if (dst[i] != src[i]) {
+            passed = false;
+            break;
+        }
+    }
+
+    delete[] src;
+    delete[] dst;
+    return passed;
+}
+
+/**
+ * Test copyTo and copyFrom for all or part of a 2D Allocation.
+ *
+ * @param rs RS Context.
+ * @param xElems Number of elements in X dimension in this Allocation.
+ * @param yElems Number of elements in Y dimension in this Allocation.
+ * @param zElems Number of elements in Z dimension in this Allocation.
+ * @param xOffset Offset in X dimension of this Allocation for copy.
+ * @param yOffset Offset in Y dimension of this Allocation for copy.
+ * @param zOffset Offset in Z dimension of this Allocation for copy.
+ * @param xCount Number of elements in X dimension need to copy.
+ * @param yCount Number of elements in Y dimension need to copy.
+ * @param zCount Number of elements in Z dimension need to copy.
+ * @param dt DataType intended to test.
+ * @param autoPadding Enable autoPadding or not. 
+*/
+template <class T>
+static bool helperCopy3D(sp<RS> rs, int xElems, int yElems, int zElems,
+                         int xOffset, int yOffset, int zOffset,
+                         int xCount, int yCount, int zCount,
+                         RsDataType dt, bool autoPadding = false) {
+    bool passed = true;
+    int arrLen = xElems * yElems * zElems;
+    int copyCount = xCount * yCount * zCount;
+    sp<Allocation> alloc = nullptr;
+
+    if (autoPadding) {
+        arrLen = arrLen * 3;
+        copyCount = copyCount * 3;
+
+        Type::Builder typeBuilder(rs, makeElement(rs, dt, 3));
+        typeBuilder.setX(xElems);
+        typeBuilder.setY(yElems);
+        typeBuilder.setZ(zElems);
+
+        alloc = Allocation::createTyped(rs, typeBuilder.create());
+        alloc->setAutoPadding(autoPadding);
+    } else {
+        Type::Builder typeBuilder(rs, makeElement(rs, dt, 1));
+        typeBuilder.setX(xElems);
+        typeBuilder.setY(yElems);
+        typeBuilder.setZ(zElems);
+
+        alloc = Allocation::createTyped(rs, typeBuilder.create());
+    }
+
+    T* src = new T[arrLen];
+    T* dst = new T[arrLen];
+
+    for (int i = 0; i < copyCount; i++) {
+        src[i] = (T)rand();
+        dst[i] = (T)(-1);
+    }
+
+    alloc->copy3DRangeFrom(xOffset, yOffset, zOffset, xCount, yCount, zCount, src);
+    alloc->copy3DRangeTo(xOffset, yOffset, zOffset, xCount, yCount, zCount, dst);
+
+    for (int i = 0; i < copyCount; i++) {
+        if (dst[i] != src[i]) {
+            passed = false;
+            break;
+        }
+    }
+
+    delete[] src;
+    delete[] dst;
+    return passed;
+}
+
+//Corresponding 3D allocation to allocation copy.
+static bool helperFloatAllocationCopy3D(sp<RS> rs, int xElems, int yElems, int zElems,
+                                        int xOffset, int yOffset, int zOffset,
+                                        int xCount, int yCount, int zCount) {
+
+    bool passed = true;
+    Type::Builder typeBuilder(rs, Element::F32(rs));
+
+    typeBuilder.setX(xElems);
+    typeBuilder.setY(yElems);
+    typeBuilder.setZ(zElems);
+
+    sp<Allocation> srcA = Allocation::createTyped(rs, typeBuilder.create());
+    sp<Allocation> dstA = Allocation::createTyped(rs, typeBuilder.create());
+
+    float *src, *dst;
+    src = new float[xElems * yElems * zElems];
+    dst = new float[xElems * yElems * zElems];
+    for (int i = 0; i < xCount * yCount * zCount; i++) {
+        src[i] = (float)rand();
+        dst[i] = -1.0f;
+    }
+
+    // First populate the source allocation
+    srcA->copy3DRangeFrom(xOffset, yOffset, zOffset, xCount, yCount, zCount, src);
+    // Now test allocation to allocation copy
+    dstA->copy3DRangeFrom(xOffset, yOffset, zOffset, xCount, yCount, zCount,
+                          srcA, xOffset, yOffset, zOffset);
+    dstA->copy3DRangeTo(xOffset, yOffset, zOffset, xCount, yCount, zCount, dst);
+
+    for (int i = 0; i < xCount * yCount * zCount; i++) {
+        if (dst[i] != src[i]) {
+            passed = false;
+            break;
+        }
+    }
+
+    delete[] src;
+    delete[] dst;
+    return passed;
+}
+
 static int elemsToTest = 20;
 
 extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSAllocationTest_test1DCopy(JNIEnv * env,
@@ -316,37 +426,180 @@
                                                                                          jstring pathObj)
 {
     const char * path = env->GetStringUTFChars(pathObj, NULL);
-    sp<RS> mRS = new RS();
-    mRS->init(path);
+    sp<RS> rs = new RS();
+    rs->init(path);
     env->ReleaseStringUTFChars(pathObj, path);
     bool passed = true;
 
     for (int s = 8; s <= elemsToTest; s += 2) {
-        for (int mode = 0; mode < 1; mode ++) {
-            passed &= helperFloatCopy(mRS, s, 0, s, mode);
-            passed &= helperCharCopy(mRS, s, 0, s, mode);
-            passed &= helperShortCopy(mRS, s, 0, s, mode);
-            passed &= helperIntCopy(mRS, s, 0, s, mode);
-            //helperBaseObjCopy(mRS, s, 0, s, mode);
-        }
+        passed &= helperCopy1D<float>(rs, s, 0, s, false, RS_TYPE_FLOAT_32);
+        passed &= helperCopy1D<char>(rs, s, 0, s, false, RS_TYPE_SIGNED_8);
+        passed &= helperCopy1D<short>(rs, s, 0, s, false, RS_TYPE_SIGNED_16);
+        passed &= helperCopy1D<int>(rs, s, 0, s, false, RS_TYPE_SIGNED_32);
+        passed &= helperCopy1D<double>(rs, s, 0, s, false, RS_TYPE_FLOAT_64);
 
         // now test copy range
-        for (int mode = 1; mode < 2; mode ++) {
-            for (int off = 0; off < s; off ++) {
-                for (int count = 1; count <= s - off; count ++) {
-                    passed &= helperFloatCopy(mRS, s, off, count, mode);
-                    passed &= helperCharCopy(mRS, s, off, count, mode);
-                    passed &= helperShortCopy(mRS, s, off, count, mode);
-                    passed &= helperIntCopy(mRS, s, off, count, mode);
-                    //helperBaseObjCopy(mRS, s, off, count, mode);
-                }
+        for (int off = 0; off < s; off ++) {
+            for (int count = 1; count <= s - off; count ++) {
+                passed &= helperCopy1D<float>(rs, s, off, count, true, RS_TYPE_FLOAT_32);
+                passed &= helperCopy1D<char>(rs, s, off, count, true, RS_TYPE_SIGNED_8);
+                passed &= helperCopy1D<short>(rs, s, off, count, true, RS_TYPE_SIGNED_16);
+                passed &= helperCopy1D<int>(rs, s, off, count, true, RS_TYPE_SIGNED_32);
+                passed &= helperCopy1D<double>(rs, s, off, count, true, RS_TYPE_FLOAT_64);
             }
         }
 
         for (int off = 0; off < s; off ++) {
             for (int count = 1; count <= s - off; count ++) {
-                passed &= helperFloatAllocationCopy(mRS, s, off, count);
-                //helperByteAllocationCopy(mRS, s, off, count);
+                passed &= helperFloatAllocationCopy1D(rs, s, off, count);
+            }
+        }
+    }
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSAllocationTest_test2DCopy(JNIEnv * env,
+                                                                                         jclass obj,
+                                                                                         jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> rs = new RS();
+    rs->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    bool passed = true;
+
+    for (int s = 8; s <= elemsToTest; s += 2) {
+        // now test copy range
+        for (int off = 0; off < s; off ++) {
+            for (int count = 1; count <= s - off; count ++) {
+                passed &= helperCopy2D<float>(rs, s, s, off, off, count, count, RS_TYPE_FLOAT_32);
+                passed &= helperCopy2D<char>(rs, s, s, off, off, count, count, RS_TYPE_SIGNED_8);
+                passed &= helperCopy2D<short>(rs, s, s, off, off, count, count, RS_TYPE_SIGNED_16);
+                passed &= helperCopy2D<int>(rs, s, s, off, off, count, count, RS_TYPE_SIGNED_32);
+                passed &= helperCopy2D<double>(rs, s, s, off, off, count, count, RS_TYPE_FLOAT_64);
+            }
+        }
+
+        for (int off = 0; off < s; off ++) {
+            for (int count = 1; count <= s - off; count ++) {
+                passed &= helperFloatAllocationCopy2D(rs, s, s, off, off, count, count);
+            }
+        }
+    }
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSAllocationTest_test3DCopy(JNIEnv * env,
+                                                                                         jclass obj,
+                                                                                         jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> rs = new RS();
+    rs->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    bool passed = true;
+
+    for (int s = 8; s <= elemsToTest; s += 2) {
+        // now test copy range
+        for (int off = 0; off < s; off ++) {
+            for (int count = 1; count <= s - off; count ++) {
+                passed &= helperCopy3D<float>(rs, s, s, s, off, off, off, count, count, count, RS_TYPE_FLOAT_32);
+                passed &= helperCopy3D<char>(rs, s, s, s, off, off, off, count, count, count, RS_TYPE_SIGNED_8);
+                passed &= helperCopy3D<short>(rs, s, s, s, off, off, off, count, count, count, RS_TYPE_SIGNED_16);
+                passed &= helperCopy3D<int>(rs, s, s, s, off, off, off, count, count, count, RS_TYPE_SIGNED_32);
+                passed &= helperCopy3D<double>(rs, s, s, s, off, off, off, count, count, count, RS_TYPE_FLOAT_64);
+            }
+        }
+
+        for (int off = 0; off < s; off ++) {
+            for (int count = 1; count <= s - off; count ++) {
+                passed &= helperFloatAllocationCopy3D(rs, s, s, s, off, off, off, count, count, count);
+            }
+        }
+    }
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSAllocationTest_test1DCopyPadded(JNIEnv * env,
+                                                                                               jclass obj,
+                                                                                               jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> rs = new RS();
+    rs->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    bool passed = true;
+
+    for (int s = 8; s <= elemsToTest; s += 2) {
+        passed &= helperCopy1D<float>(rs, s, 0, s, false, RS_TYPE_FLOAT_32, true);
+        passed &= helperCopy1D<char>(rs, s, 0, s, false, RS_TYPE_SIGNED_8, true);
+        passed &= helperCopy1D<short>(rs, s, 0, s, false, RS_TYPE_SIGNED_16, true);
+        passed &= helperCopy1D<int>(rs, s, 0, s, false, RS_TYPE_SIGNED_32, true);
+        passed &= helperCopy1D<double>(rs, s, 0, s, false, RS_TYPE_FLOAT_64, true);
+
+        // now test copy range
+        for (int off = 0; off < s; off ++) {
+            for (int count = 1; count <= s - off; count ++) {
+                passed &= helperCopy1D<float>(rs, s, off, count, true, RS_TYPE_FLOAT_32, true);
+                passed &= helperCopy1D<char>(rs, s, off, count, true, RS_TYPE_SIGNED_8, true);
+                passed &= helperCopy1D<short>(rs, s, off, count, true, RS_TYPE_SIGNED_16, true);
+                passed &= helperCopy1D<int>(rs, s, off, count, true, RS_TYPE_SIGNED_32, true);
+                passed &= helperCopy1D<double>(rs, s, off, count, true, RS_TYPE_FLOAT_64, true);
+            }
+        }
+    }
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSAllocationTest_test2DCopyPadded(JNIEnv * env,
+                                                                                               jclass obj,
+                                                                                               jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> rs = new RS();
+    rs->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    bool passed = true;
+
+    for (int s = 8; s <= elemsToTest; s += 2) {
+        // now test copy range
+        for (int off = 0; off < s; off ++) {
+            for (int count = 1; count <= s - off; count ++) {
+                passed &= helperCopy2D<float>(rs, s, s, off, off, count, count, RS_TYPE_FLOAT_32, true);
+                passed &= helperCopy2D<char>(rs, s, s, off, off, count, count, RS_TYPE_SIGNED_8, true);
+                passed &= helperCopy2D<short>(rs, s, s, off, off, count, count, RS_TYPE_SIGNED_16, true);
+                passed &= helperCopy2D<int>(rs, s, s, off, off, count, count, RS_TYPE_SIGNED_32, true);
+                passed &= helperCopy2D<double>(rs, s, s, off, off, count, count, RS_TYPE_FLOAT_64, true);
+            }
+        }
+    }
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSAllocationTest_test3DCopyPadded(JNIEnv * env,
+                                                                                               jclass obj,
+                                                                                               jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> rs = new RS();
+    rs->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    bool passed = true;
+
+    for (int s = 8; s <= elemsToTest; s += 2) {
+        // now test copy range
+        for (int off = 0; off < s; off ++) {
+            for (int count = 1; count <= s - off; count ++) {
+                passed &= helperCopy3D<float>(rs, s, s, s, off, off, off, count, count, count,
+                                              RS_TYPE_FLOAT_32, true);
+                passed &= helperCopy3D<char>(rs, s, s, s, off, off, off, count, count, count,
+                                             RS_TYPE_SIGNED_8, true);
+                passed &= helperCopy3D<short>(rs, s, s, s, off, off, off, count, count, count,
+                                              RS_TYPE_SIGNED_16, true);
+                passed &= helperCopy3D<int>(rs, s, s, s, off, off, off, count, count, count,
+                                            RS_TYPE_SIGNED_32, true);
+                passed &= helperCopy3D<double>(rs, s, s, s, off, off, off, count, count, count,
+                                               RS_TYPE_FLOAT_64, true);
             }
         }
     }
@@ -358,19 +611,19 @@
                                                                                                jstring pathObj)
 {
     const char * path = env->GetStringUTFChars(pathObj, NULL);
-    sp<RS> mRS = new RS();
-    mRS->init(path);
+    sp<RS> rs = new RS();
+    rs->init(path);
     env->ReleaseStringUTFChars(pathObj, path);
 
     bool passed = true;
 
-    Type::Builder b(mRS, Element::I32(mRS));
+    Type::Builder b(rs, Element::I32(rs));
     b.setX(48);
-    sp<Allocation> largeArray = Allocation::createTyped(mRS, b.create());
+    sp<Allocation> largeArray = Allocation::createTyped(rs, b.create());
     b.setX(1);
-    sp<Allocation> singleElement = Allocation::createTyped(mRS, b.create());
+    sp<Allocation> singleElement = Allocation::createTyped(rs, b.create());
 
-    sp<ScriptC_setelementat> script = new ScriptC_setelementat(mRS);
+    sp<ScriptC_setelementat> script = new ScriptC_setelementat(rs);
 
     script->set_memset_toValue(1);
     script->forEach_memset(singleElement);
diff --git a/tests/tests/rscpp/librscpptest/rs_jni_element.cpp b/tests/tests/rscpp/librscpptest/rs_jni_element.cpp
new file mode 100644
index 0000000..033932b
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/rs_jni_element.cpp
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <RenderScript.h>
+
+#define  LOG_TAG    "rscpptest"
+#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
+#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
+
+using namespace android::RSC;
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSElementTest_testCreatePixel(JNIEnv * env,
+                                                                                           jclass obj,
+                                                                                           jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+    passed &= (Element::createPixel(mRS,
+                                    RS_TYPE_UNSIGNED_8,
+                                    RS_KIND_PIXEL_A) != nullptr);
+    passed &= (Element::createPixel(mRS,
+                                    RS_TYPE_UNSIGNED_5_6_5,
+                                    RS_KIND_PIXEL_RGB) != nullptr);
+    passed &= (Element::createPixel(mRS,
+                                    RS_TYPE_UNSIGNED_8,
+                                    RS_KIND_PIXEL_RGB) != nullptr);
+    passed &= (Element::createPixel(mRS,
+                                    RS_TYPE_UNSIGNED_5_5_5_1,
+                                    RS_KIND_PIXEL_RGBA) != nullptr);
+    passed &= (Element::createPixel(mRS,
+                                    RS_TYPE_UNSIGNED_4_4_4_4,
+                                    RS_KIND_PIXEL_RGBA) != nullptr);
+    passed &= (Element::createPixel(mRS,
+                                    RS_TYPE_UNSIGNED_8,
+                                    RS_KIND_PIXEL_RGBA) != nullptr);
+
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSElementTest_testCreateVector(JNIEnv * env,
+                                                                                            jclass obj,
+                                                                                            jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+    for (int len = 2; len <= 4; len ++) {
+        passed &= (Element::createVector(mRS, RS_TYPE_FLOAT_32, len) != nullptr);
+        passed &= (Element::createVector(mRS, RS_TYPE_FLOAT_64, len) != nullptr);
+        passed &= (Element::createVector(mRS, RS_TYPE_SIGNED_8, len) != nullptr);
+        passed &= (Element::createVector(mRS, RS_TYPE_SIGNED_16, len) != nullptr);
+        passed &= (Element::createVector(mRS, RS_TYPE_SIGNED_32, len) != nullptr);
+        passed &= (Element::createVector(mRS, RS_TYPE_SIGNED_64, len) != nullptr);
+        passed &= (Element::createVector(mRS, RS_TYPE_UNSIGNED_8, len) != nullptr);
+        passed &= (Element::createVector(mRS, RS_TYPE_UNSIGNED_16, len) != nullptr);
+        passed &= (Element::createVector(mRS, RS_TYPE_UNSIGNED_32, len) != nullptr);
+        passed &= (Element::createVector(mRS, RS_TYPE_UNSIGNED_64, len) != nullptr);
+    }
+
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSElementTest_testPrebuiltElements(JNIEnv * env,
+                                                                                                jclass obj,
+                                                                                                jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+    passed &= (Element::A_8(mRS) != nullptr);
+    passed &= (Element::RGBA_4444(mRS) != nullptr);
+    passed &= (Element::RGBA_5551(mRS) != nullptr);
+    passed &= (Element::RGB_565(mRS) != nullptr);
+    passed &= (Element::RGB_888(mRS) != nullptr);
+    passed &= (Element::RGBA_8888(mRS) != nullptr);
+    passed &= (Element::F32(mRS) != nullptr);
+    passed &= (Element::F32_2(mRS) != nullptr);
+    passed &= (Element::F32_3(mRS) != nullptr);
+    passed &= (Element::F32_4(mRS) != nullptr);
+    passed &= (Element::F64(mRS) != nullptr);
+    passed &= (Element::F64_2(mRS) != nullptr);
+    passed &= (Element::F64_3(mRS) != nullptr);
+    passed &= (Element::F64_4(mRS) != nullptr);
+    passed &= (Element::I8(mRS) != nullptr);
+    passed &= (Element::I8_2(mRS) != nullptr);
+    passed &= (Element::I8_3(mRS) != nullptr);
+    passed &= (Element::I8_4(mRS) != nullptr);
+    passed &= (Element::I16(mRS) != nullptr);
+    passed &= (Element::I16_2(mRS) != nullptr);
+    passed &= (Element::I16_3(mRS) != nullptr);
+    passed &= (Element::I16_4(mRS) != nullptr);
+    passed &= (Element::I32(mRS) != nullptr);
+    passed &= (Element::I32_2(mRS) != nullptr);
+    passed &= (Element::I32_3(mRS) != nullptr);
+    passed &= (Element::I32_4(mRS) != nullptr);
+    passed &= (Element::I64(mRS) != nullptr);
+    passed &= (Element::I64_2(mRS) != nullptr);
+    passed &= (Element::I64_3(mRS) != nullptr);
+    passed &= (Element::I64_4(mRS) != nullptr);
+    passed &= (Element::U8(mRS) != nullptr);
+    passed &= (Element::U8_2(mRS) != nullptr);
+    passed &= (Element::U8_3(mRS) != nullptr);
+    passed &= (Element::U8_4(mRS) != nullptr);
+    passed &= (Element::U16(mRS) != nullptr);
+    passed &= (Element::U16_2(mRS) != nullptr);
+    passed &= (Element::U16_3(mRS) != nullptr);
+    passed &= (Element::U16_4(mRS) != nullptr);
+    passed &= (Element::U32(mRS) != nullptr);
+    passed &= (Element::U32_2(mRS) != nullptr);
+    passed &= (Element::U32_3(mRS) != nullptr);
+    passed &= (Element::U32_4(mRS) != nullptr);
+    passed &= (Element::U64(mRS) != nullptr);
+    passed &= (Element::U64_2(mRS) != nullptr);
+    passed &= (Element::U64_3(mRS) != nullptr);
+    passed &= (Element::U64_4(mRS) != nullptr);
+    passed &= (Element::MATRIX_2X2(mRS) != nullptr);
+    passed &= (Element::MATRIX_3X3(mRS) != nullptr);
+    passed &= (Element::MATRIX_4X4(mRS) != nullptr);
+    passed &= (Element::ALLOCATION(mRS) != nullptr);
+    passed &= (Element::SAMPLER(mRS) != nullptr);
+    passed &= (Element::SCRIPT(mRS) != nullptr);
+    passed &= (Element::TYPE(mRS) != nullptr);
+    passed &= (Element::BOOLEAN(mRS) != nullptr);
+    passed &= (Element::ELEMENT(mRS) != nullptr);
+
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSElementTest_testIsCompatible(JNIEnv * env,
+                                                                                            jclass obj,
+                                                                                            jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+    sp<const Element> ALLOCATION = Element::ALLOCATION(mRS);
+    // A_8 is in U8
+    sp<const Element> BOOLEAN = Element::BOOLEAN(mRS);
+    sp<const Element> ELEMENT = Element::ELEMENT(mRS);
+    sp<const Element> F32 = Element::F32(mRS);
+    sp<const Element> F32_2 = Element::F32_2(mRS);
+    sp<const Element> F32_3 = Element::F32_3(mRS);
+    sp<const Element> F32_4 = Element::F32_4(mRS);
+    sp<const Element> F64 = Element::F64(mRS);
+    sp<const Element> I16 = Element::I16(mRS);
+    sp<const Element> I32 = Element::I32(mRS);
+    sp<const Element> I64 = Element::I64(mRS);
+    sp<const Element> I8 = Element::I8(mRS);
+    // MATRIX4X4 is in MATRIX_4X4
+    sp<const Element> MATRIX_2X2 = Element::MATRIX_2X2(mRS);
+    sp<const Element> MATRIX_3X3 = Element::MATRIX_3X3(mRS);
+    sp<const Element> MATRIX_4X4 = Element::MATRIX_4X4(mRS);
+
+    sp<const Element> RGBA_4444 = Element::RGBA_4444(mRS);
+    sp<const Element> RGBA_5551 = Element::RGBA_5551(mRS);
+    // RGBA_8888 is in U8_4
+    sp<const Element> RGB_565 = Element::RGB_565(mRS);
+    // RGB_888 is in U8_3
+    sp<const Element> SAMPLER = Element::SAMPLER(mRS);
+    sp<const Element> SCRIPT = Element::SCRIPT(mRS);
+    sp<const Element> TYPE = Element::TYPE(mRS);
+    sp<const Element> U16 = Element::U16(mRS);
+    sp<const Element> U32 = Element::U32(mRS);
+    sp<const Element> U64 = Element::U64(mRS);
+    sp<const Element> U8 = Element::A_8(mRS);
+    sp<const Element> U8_3 = Element::RGB_888(mRS);
+    sp<const Element> U8_4 = Element::U8_4(mRS);
+
+    int numTypes = 27;
+    sp<const Element> ElementArrs[] = { ALLOCATION, BOOLEAN, ELEMENT, F32, F32_2,
+                                      F32_3, F32_4, F64, I16, I32, I64, I8,
+                                      MATRIX_2X2, MATRIX_3X3, MATRIX_4X4, RGBA_4444,
+                                      RGBA_5551, RGB_565, SAMPLER, SCRIPT, TYPE,
+                                      U16, U32, U64, U8, U8_3, U8_4 };
+
+    for (int i = 0; i < numTypes; i++) {
+        for (int j = 0; j < numTypes; j++) {
+            if (i == j) {
+                // Elements within a group are compatible
+                passed &= (ElementArrs[i]->isCompatible(ElementArrs[j]));
+            } else {
+                // Elements from different groups are incompatible
+                passed &= !(ElementArrs[i]->isCompatible(ElementArrs[j]));
+            }
+        }
+    }
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSElementTest_testElementBuilder(JNIEnv * env,
+                                                                                              jclass obj,
+                                                                                              jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+    for (int arraySize = 1; arraySize <= 3; arraySize++) {
+        // Now test array size
+        Element::Builder *eb = new Element::Builder(mRS);
+        eb->add(Element::A_8(mRS), "A_8", arraySize);
+        eb->add(Element::RGBA_4444(mRS), "RGBA_4444", arraySize);
+        eb->add(Element::RGBA_5551(mRS), "RGBA_5551", arraySize);
+        eb->add(Element::RGB_565(mRS), "RGB_565", arraySize);
+        eb->add(Element::RGB_888(mRS), "RGB_888", arraySize);
+        eb->add(Element::RGBA_8888(mRS), "RGBA_8888", arraySize);
+        eb->add(Element::F32(mRS), "F32", arraySize);
+        eb->add(Element::F32_2(mRS), "F32_2", arraySize);
+        eb->add(Element::F32_3(mRS), "F32_3", arraySize);
+        eb->add(Element::F32_4(mRS), "F32_4", arraySize);
+        eb->add(Element::F64(mRS), "F64", arraySize);
+        eb->add(Element::F64_2(mRS), "F64_2", arraySize);
+        eb->add(Element::F64_3(mRS), "F64_3", arraySize);
+        eb->add(Element::F64_4(mRS), "F64_4", arraySize);
+        eb->add(Element::I8(mRS), "I8", arraySize);
+        eb->add(Element::I8_2(mRS), "I8_2", arraySize);
+        eb->add(Element::I8_3(mRS), "I8_3", arraySize);
+        eb->add(Element::I8_4(mRS), "I8_4", arraySize);
+        eb->add(Element::I16(mRS), "I16", arraySize);
+        eb->add(Element::I16_2(mRS), "I16_2", arraySize);
+        eb->add(Element::I16_3(mRS), "I16_3", arraySize);
+        eb->add(Element::I16_4(mRS), "I16_4", arraySize);
+        eb->add(Element::I32(mRS), "I32", arraySize);
+        eb->add(Element::I32_2(mRS), "I32_2", arraySize);
+        eb->add(Element::I32_3(mRS), "I32_3", arraySize);
+        eb->add(Element::I32_4(mRS), "I32_4", arraySize);
+        eb->add(Element::I64(mRS), "I64", arraySize);
+        eb->add(Element::I64_2(mRS), "I64_2", arraySize);
+        eb->add(Element::I64_3(mRS), "I64_3", arraySize);
+        eb->add(Element::I64_4(mRS), "I64_4", arraySize);
+        eb->add(Element::U8(mRS), "U8", arraySize);
+        eb->add(Element::U8_2(mRS), "U8_2", arraySize);
+        eb->add(Element::U8_3(mRS), "U8_3", arraySize);
+        eb->add(Element::U8_4(mRS), "U8_4", arraySize);
+        eb->add(Element::U16(mRS), "U16", arraySize);
+        eb->add(Element::U16_2(mRS), "U16_2", arraySize);
+        eb->add(Element::U16_3(mRS), "U16_3", arraySize);
+        eb->add(Element::U16_4(mRS), "U16_4", arraySize);
+        eb->add(Element::U32(mRS), "U32", arraySize);
+        eb->add(Element::U32_2(mRS), "U32_2", arraySize);
+        eb->add(Element::U32_3(mRS), "U32_3", arraySize);
+        eb->add(Element::U32_4(mRS), "U32_4", arraySize);
+        eb->add(Element::U64(mRS), "U64", arraySize);
+        eb->add(Element::U64_2(mRS), "U64_2", arraySize);
+        eb->add(Element::U64_3(mRS), "U64_3", arraySize);
+        eb->add(Element::U64_4(mRS), "U64_4", arraySize);
+        eb->add(Element::MATRIX_2X2(mRS), "MATRIX_2X2", arraySize);
+        eb->add(Element::MATRIX_3X3(mRS), "MATRIX_3X3", arraySize);
+        eb->add(Element::MATRIX_4X4(mRS), "MATRIX_4X4", arraySize);
+        eb->add(Element::ALLOCATION(mRS), "ALLOCATION", arraySize);
+        eb->add(Element::SAMPLER(mRS), "SAMPLER", arraySize);
+        eb->add(Element::SCRIPT(mRS), "SCRIPT", arraySize);
+        eb->add(Element::TYPE(mRS), "TYPE", arraySize);
+        eb->add(Element::BOOLEAN(mRS), "BOOLEAN", arraySize);
+        eb->add(Element::ELEMENT(mRS), "ELEMENT", arraySize);
+        passed &= (eb->create() != nullptr);
+    }
+    return passed;
+}
+
diff --git a/tests/tests/rscpp/librscpptest/rs_jni_foreach.cpp b/tests/tests/rscpp/librscpptest/rs_jni_foreach.cpp
new file mode 100644
index 0000000..c0c0a13
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/rs_jni_foreach.cpp
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <RenderScript.h>
+
+#define  LOG_TAG    "rscpptest"
+#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 "ScriptC_foreach.h"
+#include "ScriptC_fe_all.h"
+#include "ScriptC_noroot.h"
+
+using namespace android::RSC;
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSForEachTest_testForEach(JNIEnv * env,
+                                                                                       jclass obj,
+                                                                                       jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+    int x = 7;
+
+    sp<ScriptC_fe_all> fe_all = new ScriptC_fe_all(mRS);
+    sp<const Type> t = Type::create(mRS, Element::I8(mRS), x, 0, 0);
+
+    // I8
+    sp<Allocation> in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U8(mRS), x, 0, 0);
+    sp<Allocation> out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i8(in, out);
+    mRS->finish();
+
+    // I8_2
+    t = Type::create(mRS, Element::I8_2(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U8_2(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i8_2(in, out);
+    mRS->finish();
+
+    // I8_3
+    t = Type::create(mRS, Element::I8_3(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U8_3(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i8_3(in, out);
+    mRS->finish();
+
+    // I8_4
+    t = Type::create(mRS, Element::I8_4(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U8_4(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i8_4(in, out);
+    mRS->finish();
+
+    // I16
+    t = Type::create(mRS, Element::I16(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U16(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i16(in, out);
+    mRS->finish();
+
+    // I16_2
+    t = Type::create(mRS, Element::I16_2(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U16_2(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i16_2(in, out);
+    mRS->finish();
+
+    // I16_3
+    t = Type::create(mRS, Element::I16_3(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U16_3(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i16_3(in, out);
+    mRS->finish();
+
+    // I16_4
+    t = Type::create(mRS, Element::I16_4(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U16_4(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i16_4(in, out);
+    mRS->finish();
+
+    // I32
+    t = Type::create(mRS, Element::I32(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U32(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i32(in, out);
+    mRS->finish();
+
+    // I32_2
+    t = Type::create(mRS, Element::I32_2(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U32_2(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i32_2(in, out);
+    mRS->finish();
+
+    // I32_3
+    t = Type::create(mRS, Element::I32_3(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U32_3(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i32_3(in, out);
+    mRS->finish();
+
+    // I32_4
+    t = Type::create(mRS, Element::I32_4(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U32_4(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i32_4(in, out);
+    mRS->finish();
+
+    // I64
+    t = Type::create(mRS, Element::I64(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U64(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i64(in, out);
+    mRS->finish();
+
+    // I64_2
+    t = Type::create(mRS, Element::I64_2(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U64_2(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i64_2(in, out);
+    mRS->finish();
+
+    // I64_3
+    t = Type::create(mRS, Element::I64_3(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U64_3(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i64_3(in, out);
+    mRS->finish();
+
+    // I64_4
+    t = Type::create(mRS, Element::I64_4(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::U64_4(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i64_4(in, out);
+    mRS->finish();
+
+    // F32
+    t = Type::create(mRS, Element::F32(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_f32(in, out);
+    mRS->finish();
+
+    // F32_2
+    t = Type::create(mRS, Element::F32_2(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::F32_2(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_f32_2(in, out);
+    mRS->finish();
+
+    // F32_3
+    t = Type::create(mRS, Element::F32_3(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_f32_3(in, out);
+    mRS->finish();
+
+    // F32_4
+    t = Type::create(mRS, Element::F32_4(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_f32_4(in, out);
+    mRS->finish();
+
+    // F64
+    t = Type::create(mRS, Element::F64(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_f64(in, out);
+    mRS->finish();
+
+    // F64_2
+    t = Type::create(mRS, Element::F64_2(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_f64_2(in, out);
+    mRS->finish();
+
+    // F64_3
+    t = Type::create(mRS, Element::F64_3(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_f64_3(in, out);
+    mRS->finish();
+
+    // F64_4
+    t = Type::create(mRS, Element::F64_4(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_f64_4(in, out);
+    mRS->finish();
+
+    // BOOLEAN
+    t = Type::create(mRS, Element::BOOLEAN(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_bool(in, out);
+    mRS->finish();
+
+    // A_8
+    t = Type::create(mRS, Element::I8(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::A_8(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i8(in, out);
+    mRS->finish();
+
+    // RGBA_8888
+    t = Type::create(mRS, Element::I8_4(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::RGBA_8888(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i8_4(in, out);
+    mRS->finish();
+
+    // RGB_888
+    t = Type::create(mRS, Element::I8_3(mRS), x, 0, 0);
+    in = Allocation::createTyped(mRS, t);
+    t = Type::create(mRS, Element::RGB_888(mRS), x, 0, 0);
+    out = Allocation::createTyped(mRS, t);
+    fe_all->forEach_test_i8_3(in, out);
+    mRS->finish();
+
+    return passed;
+}
+
+#define RS_MSG_TEST_PASSED 100
+#define RS_MSG_TEST_FAILED 101
+
+static int result = 0;
+static void rsMsgHandler(uint32_t msgNum, const void *msgData, size_t msgLen) {
+    if (result == 0) {
+        result = msgNum;
+    }
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSForEachTest_testMultipleForEach(JNIEnv * env,
+                                                                                               jclass obj,
+                                                                                               jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    MessageHandlerFunc_t mHandler = rsMsgHandler;
+    mRS->setMessageHandler(mHandler);
+
+    bool passed = true;
+    sp<ScriptC_foreach> s = new ScriptC_foreach(mRS);
+
+    int X = 5;
+    int Y = 7;
+    s->set_dimX(X);
+    s->set_dimY(Y);
+    sp<const Type> t = Type::create(mRS, Element::I32(mRS), X, Y, 0);
+    sp<Allocation> A = Allocation::createTyped(mRS, t);
+    s->set_aRaw(A);
+    s->forEach_root(A);
+    s->invoke_verify_root();
+    s->forEach_foo(A, A);
+    s->invoke_verify_foo();
+    s->invoke_foreach_test();
+    mRS->finish();
+    if (result == RS_MSG_TEST_FAILED) {
+        passed = false;
+    }
+    result = 0;
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSForEachTest_testNoRoot(JNIEnv * env,
+                                                                                      jclass obj,
+                                                                                      jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, NULL);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    MessageHandlerFunc_t mHandler = rsMsgHandler;
+    mRS->setMessageHandler(mHandler);
+
+    bool passed = true;
+    sp<ScriptC_noroot> s = new ScriptC_noroot(mRS);
+
+    int X = 5;
+    int Y = 7;
+    s->set_dimX(X);
+    s->set_dimY(Y);
+    sp<const Type> t = Type::create(mRS, Element::I32(mRS), X, Y, 0);
+    sp<Allocation> A = Allocation::createTyped(mRS, t);
+    s->set_aRaw(A);
+    s->forEach_foo(A, A);
+    s->invoke_verify_foo();
+    s->invoke_noroot_test();
+    mRS->finish();
+    if (result == RS_MSG_TEST_FAILED) {
+        passed = false;
+    }
+    result = 0;
+    return passed;
+}
+
diff --git a/tests/tests/rscpp/librscpptest/rs_jni_object.cpp b/tests/tests/rscpp/librscpptest/rs_jni_object.cpp
new file mode 100644
index 0000000..a530ef9
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/rs_jni_object.cpp
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <RenderScript.h>
+
+#define  LOG_TAG    "rscpptest"
+#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 <ScriptC_clear_object.h>
+
+using namespace android::RSC;
+
+#define ObjectNum 1
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSObjectTest_testClearObjectElement(JNIEnv * env,
+                                                                                                 jclass obj,
+                                                                                                 jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+
+    sp<ScriptC_clear_object> ms_clear = new ScriptC_clear_object(mRS);
+
+    sp<const Element> element = Element::BOOLEAN(mRS);
+    sp<Allocation> mOut = Allocation::createSized(mRS, Element::I32(mRS), ObjectNum);
+    ms_clear->set_element(element);
+    ms_clear->forEach_clear_element(mOut);
+
+    int tmpArray[ObjectNum];
+    mOut->copy1DTo(tmpArray);
+
+    for(int i = 0; i < ObjectNum; i++) {
+        passed &= (tmpArray[i] == 1);
+    }
+
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSObjectTest_testClearObjectType(JNIEnv * env,
+                                                                                        jclass obj,
+                                                                                        jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+
+    sp<ScriptC_clear_object> ms_clear = new ScriptC_clear_object(mRS);
+
+    sp<const Type> type= Type::create(mRS, Element::I8(mRS), 1, 0, 0);
+    sp<Allocation> mOut = Allocation::createSized(mRS, Element::I32(mRS), ObjectNum);
+    ms_clear->set_type(type);
+    ms_clear->forEach_clear_type(mOut);
+
+    int tmpArray[ObjectNum];
+    mOut->copy1DTo(tmpArray);
+
+    for(int i = 0; i < ObjectNum; i++) {
+        passed &= (tmpArray[i] == 1);
+    }
+
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSObjectTest_testClearObjectAllocation(JNIEnv * env,
+                                                                                        jclass obj,
+                                                                                        jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+
+    sp<ScriptC_clear_object> ms_clear = new ScriptC_clear_object(mRS);
+
+    sp<Allocation> mOut = Allocation::createSized(mRS, Element::I32(mRS), ObjectNum);
+    sp<Allocation> mIn = Allocation::createSized(mRS, Element::I32(mRS), ObjectNum);
+    sp<Allocation> allocation = Allocation::createTyped(mRS, mIn->getType());
+    ms_clear->set_allocation(allocation);
+    ms_clear->forEach_clear_allocation(mOut);
+
+    int tmpArray[ObjectNum];
+    mOut->copy1DTo(tmpArray);
+
+    for(int i = 0; i < ObjectNum; i++) {
+        passed &= (tmpArray[i] == 1);
+    }
+
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSObjectTest_testClearObjectSampler(JNIEnv * env,
+                                                                                        jclass obj,
+                                                                                        jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+
+    sp<ScriptC_clear_object> ms_clear = new ScriptC_clear_object(mRS);
+
+    sp<Sampler> sampler = Sampler::create(mRS, RS_SAMPLER_NEAREST, RS_SAMPLER_NEAREST,
+                                          RS_SAMPLER_WRAP, RS_SAMPLER_WRAP, 1.0f);
+    sp<Allocation> mOut = Allocation::createSized(mRS, Element::I32(mRS), ObjectNum);
+    ms_clear->set_sampler(sampler);
+    ms_clear->forEach_clear_sampler(mOut);
+
+    int tmpArray[ObjectNum];
+    mOut->copy1DTo(tmpArray);
+
+    for(int i = 0; i < ObjectNum; i++) {
+        passed &= (tmpArray[i] == 1);
+    }
+
+
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSObjectTest_testClearObjectScript(JNIEnv * env,
+                                                                                        jclass obj,
+                                                                                        jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+
+    sp<ScriptC_clear_object> ms_clear = new ScriptC_clear_object(mRS);
+
+    sp<Script> script = new ScriptC_clear_object(mRS);
+    sp<Allocation> mOut = Allocation::createSized(mRS, Element::I32(mRS), ObjectNum);
+    ms_clear->set_script(script);
+    ms_clear->forEach_clear_script(mOut);
+
+    int tmpArray[ObjectNum];
+    mOut->copy1DTo(tmpArray);
+
+    for(int i = 0; i < ObjectNum; i++) {
+        passed &= (tmpArray[i] == 1);
+    }
+
+    return passed;
+}
diff --git a/tests/tests/rscpp/librscpptest/rs_jni_script.cpp b/tests/tests/rscpp/librscpptest/rs_jni_script.cpp
new file mode 100644
index 0000000..1888341
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/rs_jni_script.cpp
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <RenderScript.h>
+
+#define  LOG_TAG    "rscpptest"
+#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 <ScriptC_primitives.h>
+#include <ScriptC_instance.h>
+#include <ScriptC_vector.h>
+
+using namespace android::RSC;
+
+#define RS_MSG_TEST_PASSED 100
+#define RS_MSG_TEST_FAILED 101
+
+static int result = 0;
+static void rsMsgHandler(uint32_t msgNum, const void *msgData, size_t msgLen) {
+    if (result == 0) {
+        result = msgNum;
+    }
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSScriptTest_testSet(JNIEnv * env,
+                                                                                  jclass obj,
+                                                                                  jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    MessageHandlerFunc_t mHandler = rsMsgHandler;
+    mRS->setMessageHandler(mHandler);
+
+    bool passed = true;
+
+    sp<const Type> t = Type::create(mRS, Element::I32(mRS), 8, 0, 0);
+    sp<Allocation> alloc = Allocation::createTyped(mRS, t);
+
+    sp<ScriptC_primitives> script = new ScriptC_primitives(mRS);
+    script->set_floatTest(2.99f);  // floatTest
+    script->set_doubleTest(3.05);  // doubleTest
+    script->set_charTest(-16);  // charTest
+    script->set_shortTest(-32);  // shortTest
+    script->set_intTest(-64);  // intTest
+    script->set_longTest(17179869185l);  // longTest
+    script->set_longlongTest(68719476735L); //longlongTest
+    script->set_ulongTest(4611686018427387903L);  // boolTest
+    script->set_uint64_tTest(117179869185l); //uint64_tTest
+    script->set_allocationTest(alloc);  // allocationTest
+    
+    script->invoke_test_primitive_types();
+    mRS->finish();
+    if (result == RS_MSG_TEST_FAILED) {
+        passed = false;
+    }
+
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSScriptTest_testInstance(JNIEnv * env,
+                                                                                       jclass obj,
+                                                                                       jstring pathObj)
+{
+    /**
+     * Test script instancing.
+     */
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    MessageHandlerFunc_t mHandler = rsMsgHandler;
+    mRS->setMessageHandler(mHandler);
+
+    bool passed = true;
+
+    sp<const Type> t = Type::create(mRS, Element::I32(mRS), 1, 0, 0);
+    sp<Allocation> ai1 = Allocation::createTyped(mRS, t);
+    sp<Allocation> ai2 = Allocation::createTyped(mRS, t);
+    sp<ScriptC_instance> instance_1 = new ScriptC_instance(mRS);
+    sp<ScriptC_instance> instance_2 = new ScriptC_instance(mRS);
+
+    instance_1->set_i(1);
+    instance_2->set_i(2);
+    instance_1->set_ai(ai1);
+    instance_2->set_ai(ai2);
+
+    // We now check to ensure that the global is not being shared across
+    // our separate script instances. Our invoke here merely sets the
+    // instanced allocation with the instanced global variable's value.
+    // If globals are being shared (i.e. not instancing scripts), then
+    // both instanced allocations will have the same resulting value
+    // (depending on the order in which the invokes complete).
+    instance_1->invoke_instance_test();
+    instance_2->invoke_instance_test();
+
+    int i1[1];
+    int i2[1];
+
+    ai1->copy1DTo(i1);
+    ai2->copy1DTo(i2);
+
+    // 3-step check ensures that a fortunate race condition wouldn't let us
+    // pass accidentally.
+    passed &= (2 == i2[0]);
+    passed &= (1 == i1[0]);
+    passed &= (2 == i2[0]);
+    mRS->finish();
+    if (result == RS_MSG_TEST_FAILED) {
+        passed = false;
+    }
+
+    return passed;
+}
+
+// Define some reasonable types for use with the vector invoke testing.
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+#define TEST_VECTOR_INVOKE(L, U) \
+L temp_##L = 0; \
+vector->invoke_vector_test_##L(temp_##L); \
+U##2 temp_##L##2; \
+vector->invoke_vector_test_##L##2(temp_##L##2); \
+U##3 temp_##L##3; \
+vector->invoke_vector_test_##L##3(temp_##L##3); \
+U##4 temp_##L##4; \
+vector->invoke_vector_test_##L##4(temp_##L##4);
+
+
+/*
+ * Test that vector invoke C++ reflection is working/present.
+ */
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSScriptTest_testVector(JNIEnv * env,
+                                                                                     jclass obj,
+                                                                                     jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+    MessageHandlerFunc_t mHandler = rsMsgHandler;
+    mRS->setMessageHandler(mHandler);
+
+    bool passed = true;
+    sp<ScriptC_vector> vector = new ScriptC_vector(mRS);
+
+    TEST_VECTOR_INVOKE(float, Float)
+    TEST_VECTOR_INVOKE(double, Double)
+    TEST_VECTOR_INVOKE(char, Byte)
+    TEST_VECTOR_INVOKE(uchar, UByte)
+    TEST_VECTOR_INVOKE(short, Short)
+    TEST_VECTOR_INVOKE(ushort, UShort)
+    TEST_VECTOR_INVOKE(int, Int)
+    TEST_VECTOR_INVOKE(uint, UInt)
+    TEST_VECTOR_INVOKE(long, Long)
+    TEST_VECTOR_INVOKE(ulong, ULong)
+
+    return passed;
+}
diff --git a/tests/tests/rscpp/librscpptest/rs_jni_type.cpp b/tests/tests/rscpp/librscpptest/rs_jni_type.cpp
new file mode 100644
index 0000000..5458a25
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/rs_jni_type.cpp
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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/log.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <RenderScript.h>
+
+#define  LOG_TAG    "rscpptest"
+#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 <ScriptC_primitives.h>
+#include <ScriptC_instance.h>
+
+using namespace android::RSC;
+
+static bool testTypeBuilderHelper(sp<RS> mRS, sp<const Element> e) {
+    const int min = 1;
+    const int max = 8;
+
+    Type::Builder b(mRS, e);
+    bool result = true;
+    for (int mips = 0; mips <= 1; mips ++) {
+        bool useMips = (mips == 1);
+        for (int faces = 0; faces <= 1; faces++) {
+            bool useFaces = (faces == 1);
+
+            b.setMipmaps(useMips);
+            b.setFaces(useFaces);
+            for (int x = min; x < max; x ++) {
+                for (int y = min; y < max; y ++) {
+                    b.setX(x);
+                    b.setY(y);
+                    result &= (b.create() != nullptr);
+                }
+            }
+        }
+    }
+    return result;
+}
+
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSTypeTest_testCreate(JNIEnv * env,
+                                                                                   jclass obj,
+                                                                                   jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+
+    passed &= testTypeBuilderHelper(mRS, Element::A_8(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::RGB_565(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::RGB_888(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::RGBA_8888(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::F32(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::F32_2(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::F32_3(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::F32_4(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::BOOLEAN(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::F64(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::I8(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::I16(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::I32(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::I64(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::U8(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::U8_4(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::U16(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::U32(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::U64(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::MATRIX_2X2(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::MATRIX_3X3(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::MATRIX_4X4(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::ALLOCATION(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::SAMPLER(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::SCRIPT(mRS));
+    passed &= testTypeBuilderHelper(mRS, Element::TYPE(mRS));
+
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSTypeTest_testGetCount(JNIEnv * env,
+                                                                                     jclass obj,
+                                                                                     jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+
+    Type::Builder b(mRS, Element::F32(mRS));
+    for (int faces = 0; faces <= 1; faces++) {
+        bool useFaces = (faces == 1);
+        uint32_t faceMultiplier = useFaces ? 6 : 1;
+        for (int x = 1; x < 8; x ++) {
+            for (int y = 1; y < 8; y ++) {
+                b.setFaces(useFaces);
+                b.setX(x);
+                b.setY(y);
+                sp<const Type> t = b.create();
+                passed &= (t->getCount() == x * y * faceMultiplier);
+            }
+        }
+    }
+
+    // Test mipmaps
+    b.setFaces(false);
+    b.setMipmaps(true);
+    b.setX(8);
+    b.setY(1);
+    sp<const Type> t = b.create();
+
+    size_t expectedCount = 8 + 4 + 2 + 1;
+    passed &= (t->getCount() == expectedCount);
+
+    b.setX(8);
+    b.setY(8);
+    t = b.create();
+    expectedCount = 8*8 + 4*4 + 2*2 + 1;
+    passed &= (t->getCount() == expectedCount);
+
+    b.setX(8);
+    b.setY(4);
+    t = b.create();
+    expectedCount = 8*4 + 4*2 + 2*1 + 1;
+    passed &= (t->getCount() == expectedCount);
+
+    b.setX(4);
+    b.setY(8);
+    t = b.create();
+    passed &= (t->getCount() == expectedCount);
+
+    b.setX(7);
+    b.setY(1);
+    t = b.create();
+    expectedCount = 7 + 3 + 1;
+    passed &= (t->getCount() == expectedCount);
+
+    b.setX(7);
+    b.setY(3);
+    t = b.create();
+    expectedCount = 7*3 + 3*1 + 1;
+    passed &= (t->getCount() == expectedCount);
+    return passed;
+}
+
+extern "C" JNIEXPORT jboolean JNICALL Java_android_cts_rscpp_RSTypeTest_testGet(JNIEnv * env,
+                                                                                jclass obj,
+                                                                                jstring pathObj)
+{
+    const char * path = env->GetStringUTFChars(pathObj, nullptr);
+    sp<RS> mRS = new RS();
+    mRS->init(path);
+    env->ReleaseStringUTFChars(pathObj, path);
+
+    bool passed = true;
+
+    sp<const Type> t = Type::create(mRS, Element::F32(mRS), 3, 4, 0);
+    passed &= (t->getElement() == Element::F32(mRS));
+    passed &= (t->getX() == 3);
+    passed &= (t->getY() == 4);
+    passed &= (t->getZ() == 0);
+
+    Type::Builder b(mRS, Element::F32(mRS));
+    b.setX(4);
+    b.setY(4);
+    b.setFaces(true);
+    passed &= (b.create()->hasFaces());
+    b.setFaces(false);
+    passed &= !(b.create()->hasFaces());
+    b.setMipmaps(true);
+    passed &= (b.create()->hasMipmaps());
+    b.setMipmaps(false);
+    passed &= !(b.create()->hasMipmaps());
+
+    return passed;
+}
+
+
+
diff --git a/tests/tests/rscpp/librscpptest/shared.rsh b/tests/tests/rscpp/librscpptest/shared.rsh
new file mode 100644
index 0000000..c5599d7
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/shared.rsh
@@ -0,0 +1,26 @@
+#pragma version(1)
+#pragma rs java_package_name(com.android.cts.rscpp)
+
+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/rscpp/librscpptest/vector.rs b/tests/tests/rscpp/librscpptest/vector.rs
new file mode 100644
index 0000000..cdea9b8
--- /dev/null
+++ b/tests/tests/rscpp/librscpptest/vector.rs
@@ -0,0 +1,19 @@
+#include "shared.rsh"
+
+#define MAKE_TEST(T) \
+void vector_test_##T(T t) {} \
+void vector_test_##T##2(T##2 t) {} \
+void vector_test_##T##3(T##3 t) {} \
+void vector_test_##T##4(T##4 t) {} \
+
+MAKE_TEST(float)
+MAKE_TEST(double)
+MAKE_TEST(char)
+MAKE_TEST(uchar)
+MAKE_TEST(short)
+MAKE_TEST(ushort)
+MAKE_TEST(int)
+MAKE_TEST(uint)
+MAKE_TEST(long)
+MAKE_TEST(ulong)
+
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSAllocationTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSAllocationTest.java
index 76dbfee..012e731 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSAllocationTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSAllocationTest.java
@@ -33,14 +33,39 @@
     }
 
     native boolean test1DCopy(String path);
-    public void testRSAllocationCopy() {
+    public void testRSAllocationCopy1D() {
         assertTrue(test1DCopy(this.getContext().getCacheDir().toString()));
     }
 
+    native boolean test2DCopy(String path);
+    public void testRSAllocationCopy2D() {
+        assertTrue(test2DCopy(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean test3DCopy(String path);
+    public void testRSAllocationCopy3D() {
+        assertTrue(test3DCopy(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean test1DCopyPadded(String path);
+    public void testRSAllocationCopy1DPadded() {
+        assertTrue(test1DCopyPadded(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean test2DCopyPadded(String path);
+    public void testRSAllocationCopy2DPadded() {
+        assertTrue(test2DCopyPadded(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean test3DCopyPadded(String path);
+    public void testRSAllocationCopy3DPadded() {
+        assertTrue(test3DCopyPadded(this.getContext().getCacheDir().toString()));
+    }
+
     native boolean testSetElementAt(String path);
     public void testRSAllocationSetElementAt() {
         assertTrue(testSetElementAt(this.getContext().getCacheDir().toString()));
     }
 
 
-}
\ No newline at end of file
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSCppTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSCppTest.java
index 9b09cc7..0b308cb 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/RSCppTest.java
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSCppTest.java
@@ -25,6 +25,7 @@
 import android.renderscript.RenderScript;
 import android.renderscript.Allocation;
 import android.renderscript.Element;
+import android.renderscript.Type;
 import android.util.Log;
 
 public class RSCppTest extends AndroidTestCase {
@@ -73,6 +74,29 @@
         }
     };
 
+    protected Element makeElement(Element.DataType dt, int vecSize) {
+        Element e;
+        if (vecSize > 1) {
+            e = Element.createVector(mRS, dt, vecSize);
+        } else {
+            if (dt == Element.DataType.UNSIGNED_8) {
+                e = Element.U8(mRS);
+            } else {
+                e = Element.F32(mRS);
+            }
+        }
+        return e;
+    }
+
+    protected Allocation makeAllocation(int w, int h, Element e) {
+        Type.Builder tb = new Type.Builder(mRS, e);
+        tb.setX(w);
+        tb.setY(h);
+        Type t = tb.create();
+        Allocation a = Allocation.createTyped(mRS, t);
+        return a;
+    }
+
     protected void checkForErrors() {
         mRS.finish();
         mVerify.invoke_checkError();
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSElementTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSElementTest.java
new file mode 100644
index 0000000..edae845
--- /dev/null
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSElementTest.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.rscpp;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.renderscript.*;
+import android.util.Log;
+
+public class RSElementTest extends RSCppTest {
+    static {
+        System.loadLibrary("rscpptest_jni");
+    }
+
+    native boolean testCreatePixel(String path);
+    public void testRSElementTestCreatePixel() {
+        assertTrue(testCreatePixel(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testCreateVector(String path);
+    public void testRSElementTestCreateVector() {
+        assertTrue(testCreateVector(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testPrebuiltElements(String path);
+    public void testRSElementTestPrebuiltElements() {
+        assertTrue(testPrebuiltElements(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testIsCompatible(String path);
+    public void testRSElementTestIsCompatible() {
+        assertTrue(testIsCompatible(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testElementBuilder(String path);
+    public void testRSElementElementBuilder() {
+        assertTrue(testElementBuilder(this.getContext().getCacheDir().toString()));
+    }
+
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSForEachTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSForEachTest.java
new file mode 100644
index 0000000..3f497bb
--- /dev/null
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSForEachTest.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.rscpp;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.renderscript.*;
+import android.util.Log;
+
+public class RSForEachTest extends RSCppTest {
+    static {
+        System.loadLibrary("rscpptest_jni");
+    }
+
+    native boolean testForEach(String path);
+    public void testRSForEachTestForEach() {
+        assertTrue(testForEach(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testMultipleForEach(String path);
+    public void testRSForEachTestMultipleForEach() {
+        assertTrue(testMultipleForEach(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testNoRoot(String path);
+    public void testRSForEachTestNoRoot() {
+        assertTrue(testNoRoot(this.getContext().getCacheDir().toString()));
+    }
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSObjectTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSObjectTest.java
new file mode 100644
index 0000000..308ca36
--- /dev/null
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSObjectTest.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.rscpp;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.renderscript.*;
+import android.util.Log;
+
+public class RSObjectTest extends RSCppTest {
+    static {
+        System.loadLibrary("rscpptest_jni");
+    }
+
+    native boolean testClearObjectElement(String path);
+    public void testRSObjectTestClearObjectElement() {
+        assertTrue(testClearObjectElement(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testClearObjectType(String path);
+    public void testRSObjectTestClearObjectType() {
+        assertTrue(testClearObjectType(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testClearObjectAllocation(String path);
+    public void testRSObjectTestClearObjectAllocation() {
+        assertTrue(testClearObjectAllocation(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testClearObjectSampler(String path);
+    public void testRSObjectTestClearObjectSampler() {
+        assertTrue(testClearObjectSampler(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testClearObjectScript(String path);
+    public void testRSObjectTestClearObjectScript() {
+        assertTrue(testClearObjectScript(this.getContext().getCacheDir().toString()));
+    }
+
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSResizeTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSResizeTest.java
new file mode 100644
index 0000000..6826b59
--- /dev/null
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSResizeTest.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.cts.rscpp;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.renderscript.*;
+import android.util.Log;
+import java.lang.Integer;
+
+public class RSResizeTest extends RSCppTest {
+    static {
+        System.loadLibrary("rscpptest_jni");
+    }
+
+    private final int inX = 307;
+    private final int inY = 157;
+
+    native boolean resizeTest(String path, int w, int h, float scaleX, float scaleY,
+                              boolean useByte, int vecSize, byte[] inB, byte[] outB,
+                              float[] inF, float[] outF);
+    private void testResize(int w, int h, Element.DataType dt, int vecSize, float scaleX, float scaleY) {
+
+        boolean useByte = false;
+        if (dt == Element.DataType.UNSIGNED_8) {
+            useByte = true;
+        }
+
+        Element e = makeElement(dt, vecSize);
+        Allocation rsInput = makeAllocation(w, h, e);
+
+        int arrSize = w * h * (vecSize == 3 ? 4 : vecSize);
+        int[] baseAlloc = new int[arrSize];
+        byte[] byteAlloc = null;
+        float[] floatAlloc = null;
+
+        RSUtils.genRandom(0x72727272, 255, 1, -128, baseAlloc);
+        if (useByte) {
+            byteAlloc = new byte[arrSize];
+            for (int i = 0; i < arrSize; i++) {
+                byteAlloc[i] = (byte)baseAlloc[i];
+            }
+            rsInput.copyFromUnchecked(byteAlloc);
+        } else {
+            //Float case
+            floatAlloc = new float[arrSize];
+            for (int i = 0; i < arrSize; i++) {
+                floatAlloc[i] = (float)baseAlloc[i];
+            }
+            rsInput.copyFromUnchecked(floatAlloc);
+        }
+
+        int outW = (int) (w*scaleX);
+        int outH = (int) (h*scaleY);
+
+        Allocation rsOutput = makeAllocation(outW, outH, e);
+        Allocation rsCppOutput = makeAllocation(outW, outH, e);
+
+        ScriptIntrinsicResize resize = ScriptIntrinsicResize.create(mRS);
+        resize.setInput(rsInput);
+        resize.forEach_bicubic(rsOutput);
+
+        int outArrSize = outW * outH * (vecSize == 3 ? 4 : vecSize);
+        byte[] nativeByteAlloc = new byte[outArrSize];
+        float[] nativeFloatAlloc = new float[outArrSize];
+        resizeTest(this.getContext().getCacheDir().toString().toString(), w, h, scaleX, scaleY,
+                   useByte, vecSize, byteAlloc, nativeByteAlloc, floatAlloc, nativeFloatAlloc);
+
+        if (useByte) {
+            rsCppOutput.copyFromUnchecked(nativeByteAlloc);
+        } else {
+            rsCppOutput.copyFromUnchecked(nativeFloatAlloc);
+        }
+        mVerify.set_image_tolerance(0.04f); // Kept loose till a better test designed
+        mVerify.invoke_verify(rsOutput, rsCppOutput, rsInput);
+        checkForErrors();
+    }
+
+    public void test_U8_4_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 1.f, 1.f);
+    }
+    public void test_U8_3_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 1.f, 1.f);
+    }
+    public void test_U8_2_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 1.f, 1.f);
+    }
+    public void test_U8_1_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 1.f, 1.f);
+    }
+
+    public void test_U8_4_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 2.f);
+    }
+    public void test_U8_3_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 2.f);
+    }
+    public void test_U8_2_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 2.f);
+    }
+    public void test_U8_1_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 2.f);
+    }
+
+    public void test_U8_4_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 2.f);
+    }
+    public void test_U8_3_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 2.f);
+    }
+    public void test_U8_2_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 2.f);
+    }
+    public void test_U8_1_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 2.f);
+    }
+
+    public void test_U8_4_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 2.f, 0.5f);
+    }
+    public void test_U8_3_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 2.f, 0.5f);
+    }
+    public void test_U8_2_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 2.f, 0.5f);
+    }
+    public void test_U8_1_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 2.f, 0.5f);
+    }
+
+    public void test_U8_4_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 4, 0.5f, 0.5f);
+    }
+    public void test_U8_3_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 3, 0.5f, 0.5f);
+    }
+    public void test_U8_2_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 2, 0.5f, 0.5f);
+    }
+    public void test_U8_1_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.UNSIGNED_8, 1, 0.5f, 0.5f);
+    }
+
+    public void test_U8_4_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 1.f, 1.f);
+    }
+    public void test_U8_3_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 1.f, 1.f);
+    }
+    public void test_U8_2_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 1.f, 1.f);
+    }
+    public void test_U8_1_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 1.f, 1.f);
+    }
+
+    public void test_U8_4_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 2.f, 2.f);
+    }
+    public void test_U8_3_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 2.f, 2.f);
+    }
+    public void test_U8_2_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 2.f, 2.f);
+    }
+    public void test_U8_1_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 2.f, 2.f);
+    }
+
+    public void test_U8_4_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 0.5f, 2.f);
+    }
+    public void test_U8_3_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 0.5f, 2.f);
+    }
+    public void test_U8_2_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 0.5f, 2.f);
+    }
+    public void test_U8_1_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 0.5f, 2.f);
+    }
+
+    public void test_U8_4_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 2.f, 0.5f);
+    }
+    public void test_U8_3_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 2.f, 0.5f);
+    }
+    public void test_U8_2_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 2.f, 0.5f);
+    }
+    public void test_U8_1_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 2.f, 0.5f);
+    }
+
+    public void test_U8_4_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 4, 0.5f, 0.5f);
+    }
+    public void test_U8_3_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 3, 0.5f, 0.5f);
+    }
+    public void test_U8_2_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 2, 0.5f, 0.5f);
+    }
+    public void test_U8_1_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.UNSIGNED_8, 1, 0.5f, 0.5f);
+    }
+
+
+    public void test_F32_4_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 1.f, 1.f);
+    }
+    public void test_F32_3_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 1.f, 1.f);
+    }
+    public void test_F32_2_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 1.f, 1.f);
+    }
+    public void test_F32_1_SCALE10_10_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 1.f, 1.f);
+    }
+
+    public void test_F32_4_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 2.f, 2.f);
+    }
+    public void test_F32_3_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 2.f, 2.f);
+    }
+    public void test_F32_2_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 2.f, 2.f);
+    }
+    public void test_F32_1_SCALE20_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 2.f, 2.f);
+    }
+
+    public void test_F32_4_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 0.5f, 2.f);
+    }
+    public void test_F32_3_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 0.5f, 2.f);
+    }
+    public void test_F32_2_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 0.5f, 2.f);
+    }
+    public void test_F32_1_SCALE05_20_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 0.5f, 2.f);
+    }
+
+    public void test_F32_4_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 2.f, 0.5f);
+    }
+    public void test_F32_3_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 2.f, 0.5f);
+    }
+    public void test_F32_2_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 2.f, 0.5f);
+    }
+    public void test_F32_1_SCALE20_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 2.f, 0.5f);
+    }
+
+    public void test_F32_4_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 4, 0.5f, 0.5f);
+    }
+    public void test_F32_3_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 3, 0.5f, 0.5f);
+    }
+    public void test_F32_2_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 2, 0.5f, 0.5f);
+    }
+    public void test_F32_1_SCALE05_05_inSqure() {
+        testResize(inX, inX, Element.DataType.FLOAT_32, 1, 0.5f, 0.5f);
+    }
+
+    public void test_F32_4_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 1.f, 1.f);
+    }
+    public void test_F32_3_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 1.f, 1.f);
+    }
+    public void test_F32_2_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 1.f, 1.f);
+    }
+    public void test_F32_1_SCALE10_10_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 1.f, 1.f);
+    }
+
+    public void test_F32_4_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 2.f, 2.f);
+    }
+    public void test_F32_3_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 2.f, 2.f);
+    }
+    public void test_F32_2_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 2.f, 2.f);
+    }
+    public void test_F32_1_SCALE20_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 2.f, 2.f);
+    }
+
+    public void test_F32_4_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 0.5f, 2.f);
+    }
+    public void test_F32_3_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 0.5f, 2.f);
+    }
+    public void test_F32_2_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 0.5f, 2.f);
+    }
+    public void test_F32_1_SCALE05_20_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 0.5f, 2.f);
+    }
+
+    public void test_F32_4_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 2.f, 0.5f);
+    }
+    public void test_F32_3_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 2.f, 0.5f);
+    }
+    public void test_F32_2_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 2.f, 0.5f);
+    }
+    public void test_F32_1_SCALE20_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 2.f, 0.5f);
+    }
+
+    public void test_F32_4_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 4, 0.5f, 0.5f);
+    }
+    public void test_F32_3_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 3, 0.5f, 0.5f);
+    }
+    public void test_F32_2_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 2, 0.5f, 0.5f);
+    }
+    public void test_F32_1_SCALE05_05_inRectangle() {
+        testResize(inX, inY, Element.DataType.FLOAT_32, 1, 0.5f, 0.5f);
+    }
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSScriptTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSScriptTest.java
new file mode 100644
index 0000000..fe45b33
--- /dev/null
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSScriptTest.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.rscpp;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.renderscript.*;
+import android.util.Log;
+
+public class RSScriptTest extends RSCppTest {
+    static {
+        System.loadLibrary("rscpptest_jni");
+    }
+
+    native boolean testSet(String path);
+    public void testRSScriptTestSet() {
+        assertTrue(testSet(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testInstance(String path);
+    public void testRSScriptTestInstance() {
+        assertTrue(testInstance(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testVector(String path);
+    public void testRSScriptTestVector() {
+        assertTrue(testVector(this.getContext().getCacheDir().toString()));
+    }
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSTypeTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSTypeTest.java
new file mode 100644
index 0000000..4453da1
--- /dev/null
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSTypeTest.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.rscpp;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.renderscript.*;
+import android.util.Log;
+
+public class RSTypeTest extends RSCppTest {
+    static {
+        System.loadLibrary("rscpptest_jni");
+    }
+
+    native boolean testCreate(String path);
+    public void testRSTypeTestCreate() {
+        assertTrue(testCreate(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testGet(String path);
+    public void testRSTypeTestGet() {
+        assertTrue(testGet(this.getContext().getCacheDir().toString()));
+    }
+
+    native boolean testGetCount(String path);
+    public void testRSTypeTestGetCount() {
+        assertTrue(testGetCount(this.getContext().getCacheDir().toString()));
+    }
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/RSYuvTest.java b/tests/tests/rscpp/src/android/cts/rscpp/RSYuvTest.java
new file mode 100644
index 0000000..8f79a4c
--- /dev/null
+++ b/tests/tests/rscpp/src/android/cts/rscpp/RSYuvTest.java
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.rscpp;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.AndroidTestCase;
+import android.renderscript.*;
+import android.util.Log;
+import java.util.Random;
+
+public class RSYuvTest extends RSCppTest {
+    static {
+        System.loadLibrary("rscpptest_jni");
+    }
+
+    int width;
+    int height;
+    byte [] by;
+    byte [] bu;
+    byte [] bv;
+    Allocation ay;
+    Allocation au;
+    Allocation av;
+
+    int getCWidth() {
+        return (width + 1) / 2;
+    }
+    int getCHeight() {
+        return (height + 1) / 2;
+    }
+
+    protected void makeYuvBuffer(int w, int h) {
+        Random r = new Random();
+        width = w;
+        height = h;
+
+        by = new byte[w*h];
+        bu = new byte[getCWidth() * getCHeight()];
+        bv = new byte[getCWidth() * getCHeight()];
+
+        for (int i=0; i < by.length; i++) {
+            by[i] = (byte)r.nextInt(256);
+        }
+        for (int i=0; i < bu.length; i++) {
+            bu[i] = (byte)r.nextInt(256);
+        }
+        for (int i=0; i < bv.length; i++) {
+            bv[i] = (byte)r.nextInt(256);
+        }
+
+        ay = Allocation.createTyped(mRS, Type.createXY(mRS, Element.U8(mRS), w, h));
+        final Type tuv = Type.createXY(mRS, Element.U8(mRS), w >> 1, h >> 1);
+        au = Allocation.createTyped(mRS, tuv);
+        av = Allocation.createTyped(mRS, tuv);
+
+        ay.copyFrom(by);
+        au.copyFrom(bu);
+        av.copyFrom(bv);
+    }
+
+    public Allocation makeOutput() {
+        return Allocation.createTyped(mRS, Type.createXY(mRS, Element.RGBA_8888(mRS), width, height));
+    }
+
+    native boolean yuvTest(String path, int X, int Y, byte[] input, byte[] output, int yuvFormat);
+    // Test for the API 17 conversion path
+    // This used a uchar buffer assuming nv21
+    public void testV17() {
+        makeYuvBuffer(120, 96);
+        Allocation aout = makeOutput();
+        Allocation aref = makeOutput();
+
+        byte tmp[] = new byte[(width * height) + (getCWidth() * getCHeight() * 2)];
+        int i = 0;
+        for (int j = 0; j < (width * height); j++) {
+            tmp[i++] = by[j];
+        }
+        for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+            tmp[i++] = bv[j];
+            tmp[i++] = bu[j];
+        }
+
+        Allocation ta = Allocation.createSized(mRS, Element.U8(mRS), tmp.length);
+        ta.copyFrom(tmp);
+
+        ScriptIntrinsicYuvToRGB syuv = ScriptIntrinsicYuvToRGB.create(mRS, Element.U8(mRS));
+        syuv.setInput(ta);
+        syuv.forEach(aout);
+
+        byte[] nativeByteAlloc = new byte[width * height * 4];
+        yuvTest(this.getContext().getCacheDir().toString(), width, height, tmp, nativeByteAlloc, 0);
+        aref.copyFromUnchecked(nativeByteAlloc);
+
+        mVerify.invoke_verify(aref, aout, ay);
+        checkForErrors();
+    }
+
+    // Test for the API 18 conversion path with yv12
+    public void test_YV12() {
+        ScriptIntrinsicYuvToRGB syuv = ScriptIntrinsicYuvToRGB.create(mRS, Element.YUV(mRS));
+
+        makeYuvBuffer(512, 512);
+        Allocation aout = makeOutput();
+        Allocation aref = makeOutput();
+
+        Type.Builder tb = new Type.Builder(mRS, Element.YUV(mRS));
+        tb.setX(width);
+        tb.setY(height);
+        tb.setYuvFormat(android.graphics.ImageFormat.YV12);
+        Allocation ta = Allocation.createTyped(mRS, tb.create(), Allocation.USAGE_SCRIPT);
+
+        byte tmp[] = new byte[(width * height) + (getCWidth() * getCHeight() * 2)];
+        int i = 0;
+        for (int j = 0; j < (width * height); j++) {
+            tmp[i++] = by[j];
+        }
+        for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+            tmp[i++] = bu[j];
+        }
+        for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+            tmp[i++] = bv[j];
+        }
+        ta.copyFrom(tmp);
+
+        syuv.setInput(ta);
+        syuv.forEach(aout);
+
+        byte[] nativeByteAlloc = new byte[width * height * 4];
+        yuvTest(this.getContext().getCacheDir().toString(), width, height, tmp, nativeByteAlloc, 1);
+        aref.copyFromUnchecked(nativeByteAlloc);
+
+        mVerify.invoke_verify(aref, aout, ay);
+        checkForErrors();
+    }
+
+    // Test for the API 18 conversion path with nv21
+    public void test_NV21() {
+        ScriptIntrinsicYuvToRGB syuv = ScriptIntrinsicYuvToRGB.create(mRS, Element.YUV(mRS));
+
+        makeYuvBuffer(512, 512);
+        Allocation aout = makeOutput();
+        Allocation aref = makeOutput();
+
+        Type.Builder tb = new Type.Builder(mRS, Element.YUV(mRS));
+        tb.setX(width);
+        tb.setY(height);
+        tb.setYuvFormat(android.graphics.ImageFormat.NV21);
+        Allocation ta = Allocation.createTyped(mRS, tb.create(), Allocation.USAGE_SCRIPT);
+
+        byte tmp[] = new byte[(width * height) + (getCWidth() * getCHeight() * 2)];
+        int i = 0;
+        for (int j = 0; j < (width * height); j++) {
+            tmp[i++] = by[j];
+        }
+        for (int j = 0; j < (getCWidth() * getCHeight()); j++) {
+            tmp[i++] = bv[j];
+            tmp[i++] = bu[j];
+        }
+        ta.copyFrom(tmp);
+
+        syuv.setInput(ta);
+        syuv.forEach(aout);
+
+        byte[] nativeByteAlloc = new byte[width * height * 4];
+        yuvTest(this.getContext().getCacheDir().toString(), width, height, tmp, nativeByteAlloc, 2);
+        aref.copyFromUnchecked(nativeByteAlloc);
+
+        mVerify.invoke_verify(aref, aout, ay);
+        checkForErrors();
+    }
+}
diff --git a/tests/tests/rscpp/src/android/cts/rscpp/verify.rs b/tests/tests/rscpp/src/android/cts/rscpp/verify.rs
index 7fd44d3..700b9d5 100644
--- a/tests/tests/rscpp/src/android/cts/rscpp/verify.rs
+++ b/tests/tests/rscpp/src/android/cts/rscpp/verify.rs
@@ -24,10 +24,10 @@
 int gAllowedIntError = 0;
 static bool hadError = false;
 static int2 errorLoc = {0,0};
-
+float image_tolerance = 0.0001f;
 
 static bool compare_float(float f1, float f2) {
-    if (fabs(f1-f2) > 0.0001f) {
+    if (fabs(f1-f2) > image_tolerance) {
         hadError = true;
         return false;
     }
diff --git a/tests/tests/security/Android.mk b/tests/tests/security/Android.mk
index c41ee58..ec36d6d 100644
--- a/tests/tests/security/Android.mk
+++ b/tests/tests/security/Android.mk
@@ -23,7 +23,7 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestserver ctstestrunner ctsdeviceutil guava
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner org.apache.http.legacy
 
 LOCAL_JNI_SHARED_LIBRARIES := libctssecurity_jni libcts_jni
 
diff --git a/tests/tests/security/AndroidManifest.xml b/tests/tests/security/AndroidManifest.xml
index 9086b0b..d8d8dfa 100644
--- a/tests/tests/security/AndroidManifest.xml
+++ b/tests/tests/security/AndroidManifest.xml
@@ -26,6 +26,7 @@
 
     <application>
         <uses-library android:name="android.test.runner" />
+        <uses-library android:name="org.apache.http.legacy" android:required="false" />
 
         <service android:name="android.security.cts.SeccompDeathTestService"
                  android:process=":death_test_service"
diff --git a/tests/tests/security/jni/Android.mk b/tests/tests/security/jni/Android.mk
index c7d854c..5e6a870 100644
--- a/tests/tests/security/jni/Android.mk
+++ b/tests/tests/security/jni/Android.mk
@@ -28,17 +28,34 @@
 		android_security_cts_LinuxRngTest.cpp \
 		android_security_cts_LoadEffectLibraryTest.cpp \
 		android_security_cts_NativeCodeTest.cpp \
-		android_security_cts_SeccompDeathTestService.cpp \
 		android_security_cts_SELinuxTest.cpp \
 		android_security_cts_MMapExecutableTest.cpp \
-		android_security_cts_NetlinkSocket.cpp \
 		android_security_cts_AudioPolicyBinderTest.cpp \
-		android_security_cts_AudioFlingerBinderTest.cpp \
+		android_security_cts_EncryptionTest.cpp \
+		android_security_cts_MediaCryptoTest.cpp \
 		android_security_cts_MediaPlayerInfoLeakTest.cpp \
+		android_security_cts_AudioFlingerBinderTest.cpp \
 		android_security_cts_AudioEffectBinderTest.cpp
 
-LOCAL_C_INCLUDES := $(JNI_H_INCLUDE)
+LOCAL_C_INCLUDES := \
+	$(JNI_H_INCLUDE) \
+	system/core/include \
+	frameworks/base/media/jni
 
-LOCAL_SHARED_LIBRARIES := libnativehelper liblog libbinder libutils libmedia libselinux libdl
+LOCAL_SHARED_LIBRARIES := \
+	libnativehelper \
+	liblog \
+	libbinder \
+	libutils \
+	libmedia \
+	libselinux \
+	libdl \
+	libcutils \
+	libcrypto \
+	libstagefright_foundation \
+	libmedia_jni
+
+LOCAL_C_INCLUDES += ndk/sources/cpufeatures
+LOCAL_STATIC_LIBRARIES := cpufeatures
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
index e16f06b..2f749b7 100644
--- a/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
+++ b/tests/tests/security/jni/CtsSecurityJniOnLoad.cpp
@@ -16,18 +16,17 @@
 
 #include <jni.h>
 #include <stdio.h>
-#include "android_security_cts_NetlinkSocket.h"
 
 extern int register_android_security_cts_KernelSettingsTest(JNIEnv*);
 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_SeccompDeathTestService(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);
 
@@ -54,10 +53,6 @@
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_SeccompDeathTestService(env)) {
-        return JNI_ERR;
-    }
-
     if (register_android_security_cts_SELinuxTest(env)) {
         return JNI_ERR;
     }
@@ -70,15 +65,11 @@
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_NetlinkSocket(env)) {
-        return JNI_ERR;
-    }
-
     if (register_android_security_cts_AudioPolicyBinderTest(env)) {
         return JNI_ERR;
     }
 
-    if (register_android_security_cts_AudioFlingerBinderTest(env)) {
+    if (register_android_security_cts_EncryptionTest(env)) {
         return JNI_ERR;
     }
 
@@ -90,5 +81,9 @@
         return JNI_ERR;
     }
 
+    if (register_android_security_cts_AudioFlingerBinderTest(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
index 25f3f80..4c27416 100644
--- a/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_AudioEffectBinderTest.cpp
@@ -64,7 +64,7 @@
         data.writeInt32(sizeof(replyData));
 
         Parcel reply;
-        status_t status = effect->asBinder()->transact(3, data, &reply);  // 3 is COMMAND
+        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);
@@ -120,19 +120,20 @@
     descriptor.uuid = *EFFECT_UUID_NULL;
     const int32_t priority = 0;
     const int sessionId = AUDIO_SESSION_OUTPUT_MIX;
-    const audio_io_handle_t io = 0; // AUDIO_IO_HANDLE_NONE
+    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, &status, &id, &enabled);
+            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());
-    effect->asBinder()->linkToDeath(deathRecipient);
+    IInterface::asBinder(effect)->linkToDeath(deathRecipient);
 
     // check exploit
     if (!isIEffectCommandSecure(effect.get())) {
diff --git a/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
index aa988fc..fb80d6b 100644
--- a/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_AudioFlingerBinderTest.cpp
@@ -91,7 +91,7 @@
     // force opening of a duplicating output
     status_t status = AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
                                           AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                                          "0");
+                                          "0", "");
     if (status != NO_ERROR) {
         return false;
     }
@@ -115,7 +115,7 @@
 
     AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
                                           AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                          "0");
+                                          "0", "");
 
     AudioSystem::setMasterMute(false);
 
@@ -135,7 +135,7 @@
     // force opening of a duplicating output
     status_t status = AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
                                           AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
-                                          "0");
+                                          "0", "");
     if (status != NO_ERROR) {
         return false;
     }
@@ -159,7 +159,7 @@
 
     AudioSystem::setDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
                                           AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
-                                          "0");
+                                          "0", "");
 
     return true;
 }
@@ -242,6 +242,53 @@
     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 },
@@ -251,6 +298,8 @@
             (void *) android_security_cts_AudioFlinger_test_listAudioPorts },
     {  "native_test_listAudioPatches", "()Z",
             (void *) android_security_cts_AudioFlinger_test_listAudioPatches },
+    {  "native_test_createEffect", "()Z",
+            (void *) android_security_cts_AudioFlinger_test_createEffect },
 };
 
 int register_android_security_cts_AudioFlingerBinderTest(JNIEnv* env)
diff --git a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
index dc191e9..1e3fc86 100644
--- a/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_AudioPolicyBinderTest.cpp
@@ -206,13 +206,45 @@
     data.writeInterfaceToken(aps->getInterfaceDescriptor());
     data.writeInt32(-1); // stream type
     data.writeInt32(-1); // device
-    aps->asBinder()->transact(GET_STREAM_VOLUME, data, &reply);
+    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 },
@@ -224,6 +256,8 @@
                 (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)
diff --git a/tests/tests/security/jni/android_security_cts_CharDeviceTest.cpp b/tests/tests/security/jni/android_security_cts_CharDeviceTest.cpp
index 9aea4b3..32f204f 100644
--- a/tests/tests/security/jni/android_security_cts_CharDeviceTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_CharDeviceTest.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <jni.h>
+#include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
diff --git a/tests/tests/security/jni/android_security_cts_EncryptionTest.cpp b/tests/tests/security/jni/android_security_cts_EncryptionTest.cpp
new file mode 100644
index 0000000..b9e390e
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_EncryptionTest.cpp
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 <cpu-features.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <jni.h>
+#include <JNIHelp.h>
+#include <openssl/aes.h>
+#include <openssl/cpu.h>
+#include <openssl/evp.h>
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include <new>
+
+#define TEST_EVP_CIPHER     EVP_aes_256_cbc()
+#define TEST_BUFSIZE        (1 * 1024 * 1024) /* 1 MiB */
+#define TEST_ITERATIONS     100 /* MiB */
+#define TEST_THRESHOLD      2000 /* ms */
+
+/*
+ * Function: deviceIsEncrypted
+ * Purpose: Check the device is encrypted
+ * Parameters: none
+ * Returns: boolean: (true) if encrypted, (false) otherwise
+ * Exceptions: none
+ */
+static jboolean android_security_cts_EncryptionTest_deviceIsEncrypted(JNIEnv *, jobject)
+{
+    char prop_value[PROP_VALUE_MAX];
+    property_get("ro.crypto.state", prop_value, "");
+
+    jboolean rc = !strcmp(prop_value, "encrypted");
+    ALOGE("EncryptionTest::deviceIsEncrypted: %d", rc);
+
+    return rc;
+}
+
+/*
+ * Function: cpuHasAes
+ * Purpose: Check if we have an ARM CPU with AES instruction
+ * Parameters: none
+ * Returns: boolean: (true) if AES is available, (false) otherwise
+ * Exceptions: none
+ */
+static jboolean android_security_cts_EncryptionTest_cpuHasAes(JNIEnv *, jobject)
+{
+    jboolean rc = false;
+    AndroidCpuFamily family = android_getCpuFamily();
+    uint64_t features = android_getCpuFeatures();
+
+    if (family == ANDROID_CPU_FAMILY_ARM) {
+        rc = (features & ANDROID_CPU_ARM_FEATURE_AES) != 0;
+    } else if (family == ANDROID_CPU_FAMILY_ARM64) {
+        rc = (features & ANDROID_CPU_ARM64_FEATURE_AES) != 0;
+    }
+
+    ALOGE("EncryptionTest::cpuHasAes: %d", rc);
+    return rc;
+}
+
+/*
+ * Function: cpuHasNeon
+ * Purpose: Check if we have an ARM CPU with NEON instructions
+ * Parameters: none
+ * Returns: boolean: (true) if NEON is available, (false) otherwise
+ * Exceptions: none
+ */
+static jboolean android_security_cts_EncryptionTest_cpuHasNeon(JNIEnv *, jobject)
+{
+    jboolean rc = false;
+    AndroidCpuFamily family = android_getCpuFamily();
+
+    if (family == ANDROID_CPU_FAMILY_ARM) {
+        rc = (android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0;
+    } else {
+        rc = (family == ANDROID_CPU_FAMILY_ARM64);
+    }
+
+    ALOGE("EncryptionTest::cpuHasNeon: %d", rc);
+    return rc;
+}
+
+/*
+ * Function: neonIsEnabled
+ * Purpose: Check if libcrypto is compiled with NEON support
+ * Parameters: none
+ * Returns: boolean: (true) if NEON is available, (false) otherwise
+ * Exceptions: none
+ */
+static jboolean android_security_cts_EncryptionTest_neonIsEnabled(JNIEnv *, jobject)
+{
+#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
+    jboolean rc = CRYPTO_is_NEON_capable();
+#else
+    jboolean rc = false;
+#endif
+
+    ALOGE("EncryptionTest::neonIsEnabled: %d", rc);
+    return rc;
+}
+
+static inline uint64_t ns()
+{
+    struct timespec ts;
+    clock_gettime(CLOCK_MONOTONIC, &ts);
+    return (uint64_t)ts.tv_sec * 1000000000 + ts.tv_nsec;
+}
+
+/*
+ * Function: aesIsFast
+ * Purpose: Test if AES performance is sufficient to require encryption
+ * Parameters: none
+ * Returns: boolean: (true) if AES performance is acceptable, (false) otherwise
+ * Exceptions: InvalidKeyException if EVP_DecryptInit fails, OutOfMemoryError
+ *             if memory allocation fails.
+ */
+static jboolean android_security_cts_EncryptionTest_aesIsFast(JNIEnv *env, jobject)
+{
+    EVP_CIPHER_CTX ctx;
+    uint8_t *buf;
+    uint8_t key[EVP_CIPHER_key_length(TEST_EVP_CIPHER)];
+    uint8_t iv[EVP_CIPHER_iv_length(TEST_EVP_CIPHER)];
+
+    memset(key, 0x42, sizeof(key));
+    memset(iv,  0x11, sizeof(iv));
+
+    EVP_CIPHER_CTX_init(&ctx);
+
+    if (!EVP_DecryptInit(&ctx, TEST_EVP_CIPHER, key, iv)) {
+        jniThrowException(env, "java/security/InvalidKeyException",
+            "EVP_DecryptInit failed");
+        return false;
+    }
+
+    buf = new (std::nothrow) uint8_t[TEST_BUFSIZE +
+                EVP_CIPHER_block_size(TEST_EVP_CIPHER)];
+
+    if (!buf) {
+        jniThrowException(env, "java/lang/OutOfMemoryError",
+            "Failed to allocate test buffer");
+        return false;
+    }
+
+    memset(buf, 0xF0, TEST_BUFSIZE);
+
+    int len;
+    uint64_t t = ns();
+
+    for (int i = 0; i < TEST_ITERATIONS; ++i) {
+        EVP_DecryptUpdate(&ctx, buf, &len, buf, TEST_BUFSIZE);
+    }
+
+    t = ns() - t;
+
+    delete[] buf;
+
+    unsigned long ms = (unsigned long)(t / 1000000);
+    double speed =
+        (double)(TEST_ITERATIONS * TEST_BUFSIZE / (1024 * 1024)) * 1000.0 / ms;
+
+    ALOGE("EncryptionTest::aesIsFast: %u iterations in %lu ms (%.01lf MiB/s) "
+        "(threshold %u ms)", TEST_ITERATIONS, ms, speed, TEST_THRESHOLD);
+
+    return ms < TEST_THRESHOLD;
+}
+
+static JNINativeMethod gMethods[] = {
+    { "deviceIsEncrypted", "()Z",
+            (void *) android_security_cts_EncryptionTest_deviceIsEncrypted },
+    { "cpuHasAes", "()Z",
+            (void *) android_security_cts_EncryptionTest_cpuHasAes },
+    { "cpuHasNeon", "()Z",
+            (void *) android_security_cts_EncryptionTest_cpuHasNeon },
+    { "neonIsEnabled", "()Z",
+            (void *) android_security_cts_EncryptionTest_neonIsEnabled },
+    { "aesIsFast", "()Z",
+            (void *) android_security_cts_EncryptionTest_aesIsFast }
+};
+
+int register_android_security_cts_EncryptionTest(JNIEnv* env)
+{
+    jclass clazz = env->FindClass("android/security/cts/EncryptionTest");
+    return env->RegisterNatives(clazz, gMethods,
+            sizeof(gMethods) / sizeof(JNINativeMethod));
+}
diff --git a/tests/tests/security/jni/android_security_cts_KernelSettingsTest.cpp b/tests/tests/security/jni/android_security_cts_KernelSettingsTest.cpp
index bab7b57..bb5e042 100644
--- a/tests/tests/security/jni/android_security_cts_KernelSettingsTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_KernelSettingsTest.cpp
@@ -20,10 +20,10 @@
 #include <sys/xattr.h>
 #include <errno.h>
 
-static jboolean android_security_cts_KernelSettingsTest_supportsXattr(JNIEnv* env, jobject thiz)
+static jboolean android_security_cts_KernelSettingsTest_supportsXattr(JNIEnv* /* env */, jobject /* thiz */)
 {
-    int result = getxattr("/system/bin/toolbox", "security.capability", NULL, 0);
-    return ((result >= 0) || (errno == ENODATA));
+    int result = getxattr("/system/bin/cat", "security.capability", NULL, 0);
+    return ((result != -1) || (errno == ENODATA));
 }
 
 static JNINativeMethod gMethods[] = {
diff --git a/tests/tests/security/jni/android_security_cts_LinuxRngTest.cpp b/tests/tests/security/jni/android_security_cts_LinuxRngTest.cpp
index 671226b..9b8016e 100644
--- a/tests/tests/security/jni/android_security_cts_LinuxRngTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_LinuxRngTest.cpp
@@ -18,6 +18,7 @@
 #include <jni.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/stat.h>
 
 /*
diff --git a/tests/tests/security/jni/android_security_cts_MediaCryptoTest.cpp b/tests/tests/security/jni/android_security_cts_MediaCryptoTest.cpp
new file mode 100644
index 0000000..abb26eb
--- /dev/null
+++ b/tests/tests/security/jni/android_security_cts_MediaCryptoTest.cpp
@@ -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.
+ */
+
+/* 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);
+}
+
+// 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;
+}
+
+
+
diff --git a/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp b/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp
index 41262ac..0c61f25 100644
--- a/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_MediaPlayerInfoLeakTest.cpp
@@ -39,15 +39,14 @@
    Parcel data, reply;
    int dummyAudioSessionId = 1;
    data.writeInterfaceToken(iMPService->getInterfaceDescriptor());
-   data.writeStrongBinder(client->asBinder());
+   data.writeStrongBinder(IInterface::asBinder(client));
    data.writeInt32(dummyAudioSessionId);
 
    // Keep synchronized with IMediaPlayerService.cpp!
     enum {
         CREATE = IBinder::FIRST_CALL_TRANSACTION,
     };
-   status_t err = iMPService->asBinder()->transact(CREATE, data, &reply);
-
+   status_t err = IInterface::asBinder(iMPService)->transact(CREATE, data, &reply);
    if (err == NO_ERROR) {
        iMP = interface_cast<IMediaPlayer>(reply.readStrongBinder());
    }
@@ -64,7 +63,7 @@
 
     Parcel data, reply;
     data.writeInterfaceToken(iMP->getInterfaceDescriptor());
-    iMP->asBinder()->transact(command, data, &reply);
+    IInterface::asBinder(iMP)->transact(command, data, &reply);
 
     int leak = reply.readInt32();
     status_t err = reply.readInt32();
@@ -76,7 +75,7 @@
 {
   // Keep synchronized with IMediaPlayer.cpp!
   enum {
-      GET_CURRENT_POSITION = 11,
+      GET_CURRENT_POSITION = 16,
   };
   return testMediaPlayerInfoLeak(GET_CURRENT_POSITION);
 }
@@ -86,7 +85,7 @@
 {
   // Keep synchronized with IMediaPlayer.cpp!
   enum {
-      GET_DURATION = 12,
+      GET_DURATION = 17,
   };
   return testMediaPlayerInfoLeak(GET_DURATION);
 }
diff --git a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
index 1c45e91..350309b 100644
--- a/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_NativeCodeTest.cpp
@@ -16,10 +16,6 @@
 
 #include <jni.h>
 #include <linux/futex.h>
-#include <linux/netlink.h>
-#include <linux/sock_diag.h>
-#include <stdio.h>
-#include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/syscall.h>
 #include <unistd.h>
@@ -28,6 +24,7 @@
 #include <sys/wait.h>
 #include <signal.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/utsname.h>
@@ -39,9 +36,6 @@
 #include <linux/sysctl.h>
 #include <arpa/inet.h>
 
-#define PASSED 0
-#define UNKNOWN_ERROR -1
-
 /*
  * Returns true iff this device is vulnerable to CVE-2013-2094.
  * A patch for CVE-2013-2094 can be found at
@@ -91,84 +85,6 @@
 }
 
 /*
- * Will hang if vulnerable, return 0 if successful, -1 on unforseen
- * error.
- */
-static jint android_security_cts_NativeCodeTest_doSockDiagTest(JNIEnv* env, jobject thiz)
-{
-    int fd, nlmsg_size, err, len;
-    char buf[1024];
-    struct sockaddr_nl nladdr;
-    struct nlmsghdr *nlh;
-    struct msghdr msg;
-    struct iovec iov;
-    struct sock_diag_req* sock_diag_data;
-
-    int major, minor;
-    struct utsname uts;
-    if (uname(&uts) != -1 &&
-        sscanf(uts.release, "%d.%d", &major, &minor) == 2 &&
-        ((major > 3) || ((major == 3) && (minor > 8)))) {
-        // Kernels above 3.8 are patched against CVE-2013-1763
-        // This test generates false positives if run on > 3.8.
-        // b/17253473
-        return PASSED;
-    }
-
-    fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
-    if (fd == -1) {
-        switch (errno) {
-            /* NETLINK_SOCK_DIAG not accessible, vector dne */
-            case EACCES:
-            case EAFNOSUPPORT:
-            case EPERM:
-            case EPROTONOSUPPORT:
-                return PASSED;
-            default:
-                return UNKNOWN_ERROR;
-        }
-    }
-    /* prepare and send netlink packet */
-    memset(&nladdr, 0, sizeof(nladdr));
-    nladdr.nl_family = AF_NETLINK;
-    nlmsg_size = NLMSG_ALIGN(NLMSG_HDRLEN + sizeof(sock_diag_data));
-    nlh = (nlmsghdr *)malloc(nlmsg_size);
-    nlh->nlmsg_len = nlmsg_size;
-    nlh->nlmsg_pid = 0;      //send packet to kernel
-    nlh->nlmsg_type = SOCK_DIAG_BY_FAMILY;
-    nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
-    iov = { (void *) nlh, nlmsg_size };
-    msg = { (void *) &nladdr, sizeof(nladdr), &iov, 1, NULL, 0, 0 };
-    sock_diag_data = (sock_diag_req *) NLMSG_DATA(nlh);
-    sock_diag_data->sdiag_family = AF_MAX+1;
-    if ((err = sendmsg(fd, &msg, 0)) == -1) {
-        /* SELinux blocked it */
-        if (errno == 22) {
-            return PASSED;
-        } else {
-            return UNKNOWN_ERROR;
-        }
-    }
-    free(nlh);
-
-    memset(&nladdr, 0, sizeof(nladdr));
-    iov = { buf, sizeof(buf) };
-    msg = { (void *) &nladdr, sizeof(nladdr), &iov, 1, NULL, 0, 0 };
-    if ((len = recvmsg(fd, &msg, 0)) == -1) {
-        return UNKNOWN_ERROR;
-    }
-    for (nlh = (struct nlmsghdr *) buf; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT (nlh, len)){
-        if (nlh->nlmsg_type == NLMSG_ERROR) {
-            /* -22 = -EINVAL from kernel */
-            if (*(int *)NLMSG_DATA(nlh) == -22) {
-                return PASSED;
-            }
-        }
-    }
-    return UNKNOWN_ERROR;
-}
-
-/*
  * Prior to https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/arch/arm/include/asm/uaccess.h?id=8404663f81d212918ff85f493649a7991209fa04
  * there was a flaw in the kernel's handling of get_user and put_user
  * requests. Normally, get_user and put_user are supposed to guarantee
@@ -340,8 +256,6 @@
             (void *) android_security_cts_NativeCodeTest_doPerfEventTest },
     {  "doPerfEventTest2", "()Z",
             (void *) android_security_cts_NativeCodeTest_doPerfEventTest2 },
-    {  "doSockDiagTest", "()I",
-            (void *) android_security_cts_NativeCodeTest_doSockDiagTest },
     {  "doVrootTest", "()Z",
             (void *) android_security_cts_NativeCodeTest_doVrootTest },
     {  "doCVE20141710Test", "()Z",
@@ -360,3 +274,4 @@
     return env->RegisterNatives(clazz, gMethods,
             sizeof(gMethods) / sizeof(JNINativeMethod));
 }
+
diff --git a/tests/tests/security/jni/android_security_cts_NetlinkSocket.cpp b/tests/tests/security/jni/android_security_cts_NetlinkSocket.cpp
deleted file mode 100644
index de315ea..0000000
--- a/tests/tests/security/jni/android_security_cts_NetlinkSocket.cpp
+++ /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.
- */
-
-#include <jni.h>
-#include <stdio.h>
-#include <cutils/log.h>
-#include <asm/types.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <errno.h>
-#include <string.h>
-#include "JNIHelp.h"
-
-#include "android_security_cts_NetlinkSocket.h"
-
-static void android_security_cts_NetlinkSocket_create(JNIEnv* env, jclass,
-    jobject fileDescriptor)
-{
-    int sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
-    if (sock == -1) {
-        ALOGE("Can't create socket %s", strerror(errno));
-        jclass SocketException = env->FindClass("java/net/SocketException");
-        env->ThrowNew(SocketException, "Can't create socket");
-        return;
-    }
-    jniSetFileDescriptorOfFD(env, fileDescriptor, sock);
-}
-
-static int android_security_cts_NetlinkSocket_sendmsg(JNIEnv *e, jclass,
-    jobject fileDescriptor, jint pid, jbyteArray packet)
-{
-    void *bytes = (void *)e->GetByteArrayElements(packet, NULL);
-    uint32_t length = (uint32_t)e->GetArrayLength(packet);
-    struct sockaddr_nl snl;
-    struct iovec iov = {bytes, length};
-    struct msghdr msg = {&snl, sizeof(snl), &iov, 1, NULL, 0, 0};
-
-    memset(&snl, 0, sizeof(snl));
-    snl.nl_family = AF_NETLINK;
-    snl.nl_pid = pid;
-
-    int sock = jniGetFDFromFileDescriptor(e, fileDescriptor);
-    int retval = sendmsg(sock, &msg, 0);
-    e->ReleaseByteArrayElements(packet, (jbyte*)bytes, 0);
-    return retval;
-}
-
-
-static JNINativeMethod gMethods[] = {
-    {  "sendmsg", "(Ljava/io/FileDescriptor;I[B)I", (void *) android_security_cts_NetlinkSocket_sendmsg },
-    {  "create_native", "(Ljava/io/FileDescriptor;)V", (void *) android_security_cts_NetlinkSocket_create },
-};
-
-int register_android_security_cts_NetlinkSocket(JNIEnv* env)
-{
-    jclass clazz = env->FindClass("android/security/cts/NetlinkSocket");
-
-    return env->RegisterNatives(clazz, gMethods,
-            sizeof(gMethods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/jni/android_security_cts_NetlinkSocket.h b/tests/tests/security/jni/android_security_cts_NetlinkSocket.h
deleted file mode 100644
index 6e61c75..0000000
--- a/tests/tests/security/jni/android_security_cts_NetlinkSocket.h
+++ /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.
- */
-
-#ifndef __ANDROID_SECURITY_CTS_H__
-#define __ANDROID_SECURITY_CTS_H__
-
-int register_android_security_cts_NetlinkSocket(JNIEnv*);
-
-#endif /* __ANDROID_SECURITY_CTS_H__ */
diff --git a/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp b/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
index c6ce1ef..a68bfb6 100644
--- a/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
+++ b/tests/tests/security/jni/android_security_cts_SELinuxTest.cpp
@@ -17,7 +17,16 @@
 #include <jni.h>
 #include <selinux/selinux.h>
 #include <JNIHelp.h>
+#include <ScopedLocalRef.h>
 #include <ScopedUtfChars.h>
+#include <UniquePtr.h>
+
+struct SecurityContext_Delete {
+    void operator()(security_context_t p) const {
+        freecon(p);
+    }
+};
+typedef UniquePtr<char[], SecurityContext_Delete> Unique_SecurityContext;
 
 /*
  * Function: checkSELinuxAccess
@@ -63,17 +72,56 @@
     return (validContext == 0) ? true : false;
 }
 
+/*
+ * Function: getFileContext
+ * Purpose: retrieves the context associated with the given path in the file system
+ * Parameters:
+ *        path: given path in the file system
+ * Returns:
+ *        string representing the security context string of the file object
+ *        the string may be NULL if an error occured
+ * Exceptions: NullPointerException if the path object is null
+ */
+static jstring getFileContext(JNIEnv *env, jobject, jstring pathStr) {
+    ScopedUtfChars path(env, pathStr);
+    if (path.c_str() == NULL) {
+        return NULL;
+    }
+
+    security_context_t tmp = NULL;
+    int ret = getfilecon(path.c_str(), &tmp);
+    Unique_SecurityContext context(tmp);
+
+    ScopedLocalRef<jstring> securityString(env, NULL);
+    if (ret != -1) {
+        securityString.reset(env->NewStringUTF(context.get()));
+    }
+
+    return securityString.release();
+}
 
 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_SeccompDeathTestService.cpp b/tests/tests/security/jni/android_security_cts_SeccompDeathTestService.cpp
deleted file mode 100644
index eb32521..0000000
--- a/tests/tests/security/jni/android_security_cts_SeccompDeathTestService.cpp
+++ /dev/null
@@ -1,34 +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 <jni.h>
-#include <signal.h>
-#include <unistd.h>
-
-void android_security_cts_SeccompDeathTestService_testSigSysSelf(JNIEnv* env, jobject thiz)
-{
-    kill(getpid(), SIGSYS);
-}
-
-static JNINativeMethod methods[] = {
-    { "testSigSysSelf", "()V",
-        (void *)android_security_cts_SeccompDeathTestService_testSigSysSelf }
-};
-
-int register_android_security_cts_SeccompDeathTestService(JNIEnv* env) {
-    jclass clazz = env->FindClass("android/security/cts/SeccompDeathTestService");
-    return env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(JNINativeMethod));
-}
diff --git a/tests/tests/security/src/android/security/cts/ARTBootASLRTest.java b/tests/tests/security/src/android/security/cts/ARTBootASLRTest.java
new file mode 100644
index 0000000..c0d0c58
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/ARTBootASLRTest.java
@@ -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.
+ */
+
+package android.security.cts;
+
+import android.test.AndroidTestCase;
+
+import junit.framework.TestCase;
+
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.io.BufferedReader;
+import java.nio.charset.Charset;
+
+/**
+ * Verify that the boot.art isn't mapped out of the system partition.
+ */
+public class ARTBootASLRTest extends AndroidTestCase {
+    public void testARTASLR() throws Exception {
+        FileInputStream ins = new FileInputStream("/proc/self/maps");
+        InputStreamReader reader = new InputStreamReader(ins, Charset.defaultCharset());
+        BufferedReader bufReader = new BufferedReader(reader);
+        String line;
+        boolean foundBootART = false;
+        while ((line = bufReader.readLine()) != null) {
+            // Check that we don't have /system/.*boot.art
+            if (line.matches("/system/.*boot\\.art")) {
+                fail("found " + line + " from system partition");
+            } else if (line.matches(".*boot\\.art")) {
+                foundBootART = true;
+            }
+        }
+        if (!foundBootART) {
+            fail("expected to find boot.art");
+        }
+        bufReader.close();
+        reader.close();
+        ins.close();
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java b/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
index 37c472e..202bd65 100644
--- a/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
+++ b/tests/tests/security/src/android/security/cts/AudioFlingerBinderTest.java
@@ -56,8 +56,16 @@
         assertTrue(native_test_listAudioPatches());
     }
 
+    /**
+     * 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_listAudioPatches();
+    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
index f3bfa20..82346a1 100644
--- a/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
+++ b/tests/tests/security/src/android/security/cts/AudioPolicyBinderTest.java
@@ -65,9 +65,18 @@
         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/CertificateData.java b/tests/tests/security/src/android/security/cts/CertificateData.java
index de7c15e..0c311e0 100644
--- a/tests/tests/security/src/android/security/cts/CertificateData.java
+++ b/tests/tests/security/src/android/security/cts/CertificateData.java
@@ -31,7 +31,7 @@
       "D1:CB:CA:5D:B2:D5:2A:7F:69:3B:67:4D:E5:F0:5A:1D:0C:95:7D:F0",
       "4D:23:78:EC:91:95:39:B5:00:7F:75:8F:03:3B:21:1E:C5:4D:8B:CF",
       "E7:B4:F6:9D:61:EC:90:69:DB:7E:90:A7:40:1A:3C:F4:7D:4F:E8:EE",
-      "DD:E1:D2:A9:01:80:2E:1D:87:5E:84:B3:80:7E:4B:B1:FD:99:41:34",
+      "C4:18:F6:4D:46:D1:DF:00:3D:27:30:13:72:43:A9:12:11:C6:75:FB",
       "69:69:56:2E:40:80:F4:24:A1:E7:19:9F:14:BA:F3:EE:58:AB:6A:BB",
       "92:5A:8F:8D:2C:6D:04:E0:66:5F:59:6A:FF:22:D8:63:E8:25:6F:3F",
       "75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE",
@@ -52,10 +52,8 @@
       "AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A",
       "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",
-      "AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E",
       "DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57",
       "74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE",
-      "85:B5:FF:67:9B:0C:79:96:1F:C8:6E:44:22:00:46:13:DB:17:92:84",
       "3E:2B:F7:F2:03:1B:96:F3:8C:E6:C4:D8:A8:5D:3E:2D:58:47:6A:0F",
       "A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0",
       "5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6",
@@ -64,6 +62,7 @@
       "59:22:A1:E1:5A:EA:16:35:21:F8:98:39:6A:46:46:B0:44:1B:0F:A9",
       "D4:DE:20:D0:5E:66:FC:53:FE:1A:50:88:2C:78:DB:28:52:CA:E4:74",
       "02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68",
+      "76:E2:7E:C1:4F:DB:82:C1:C0:A6:75:B5:05:BE:3D:29:B4:ED:DB:BB",
       "D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61",
       "93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17",
       "59:AF:82:79:91:86:C7:B4:75:07:CB:CF:03:57:46:EB:04:DD:B7:16",
@@ -73,10 +72,10 @@
       "77:47:4F:C6:30:E4:0F:4C:47:64:3F:84:BA:B8:C6:95:4A:8A:41:EC",
       "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",
-      "6B:2F:34:AD:89:58:BE:62:FD:B0:6B:5C:CE:BB:9D:D9:4F:4E:39:F3",
       "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",
@@ -84,25 +83,24 @@
       "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",
       "22:D5:D8:DF:8F:02:31:D1:8D:F7:9D:B7:CF:8A:2D:64:C9:3F:6C:3A",
       "F3:73:B3:87:06:5A:28:84:8A:F2:F3:4A:CE:19:2B:DD:C7:8E:9C:AC",
       "06:08:3F:59:3F:15:A1:04:A0:69:A4:6B:A9:03:D0:06:B7:97:09:91",
       "43:13:BB:96:F1:D5:86:9B:C1:4E:6A:92:F6:CF:F6:34:69:87:82:37",
+      "8A:5C:8C:EE:A5:03:E6:05:56:BA:D8:1B:D4:F6:C9:B0:ED:E5:2F:E0",
       "F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2",
       "05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43",
       "62:52:DC:40:F7:11:43:A2:2F:DE:9E:F7:34:8E:06:42:51:B1:81: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",
-      "85:37:1C:A6:E5:50:14:3D:CE:28:03:47:1B:DE:3A:09:E8:F8:77:0F",
-      "7E:78:4A:10:1C:82:65:CC:2D:E1:F1:6D:47:B4:40:CA:D9:0A:19:45",
       "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",
-      "80:25:EF:F4:6E:70:C8:D4:72:24:65:84:FE:40:3B:8A:8D:6A:DB:F5",
       "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",
@@ -118,6 +116,7 @@
       "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",
+      "E2:B8:29:4B:55:84:AB:6B:58:C2:90:46:6C:AC:3F:B8:39:8F:84:83",
       "1F:49:14:F7:D8:74:95:1D:DD:AE:02:C0:BE:FD:3A:2D:82:75:51:85",
       "B5:61:EB:EA:A4:DE:E4:25:4B:69:1A:98:A5:57:47:C2:34:C7:D9:71",
       "07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E",
@@ -143,10 +142,8 @@
       "CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48",
       "2B:B1:F5:3E:55:0C:1D:C5:F1:D4:E6:B7:6A:46:4B:55:06:02:AC:21",
       "47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B",
-      "39:21:C1:15:C1:5D:0E:CA:5C:CB:5B:C4:F0:7D:21:D8:05:0B:56:6A",
       "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",
-      "E0:AB:05:94:20:72:54:93:05:60:62:02:36:70:F7:CD:2E:FC:66:66",
       "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",
@@ -159,22 +156,21 @@
       "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",
       "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",
-      "9F:AD:91:A6:CE:6A:C6:C5:00:47:C4:4E:C9:D4:A5:0D:92:D8:49:79",
       "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",
       "5F:3A:FC:0A:8B:64:F6:86:67:34:74:DF:7E:A9:A2:FE:F9:FA:7A:51",
       "E6:21:F3:35:43:79:05:9A:4B:68:30:9D:8A:2F:74:22:15:87:EC:79",
-      "DA:40:18:8B:91:89:A3:ED:EE:AE:DA:97:FE:2F:9D:F5:B7:D1:8A:41",
       "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",
-      "61:57:3A:11:DF:0E:D8:7E:D5:92:65:22:EA:D0:56:D7:44:B3:23:71",
       "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",
diff --git a/tests/tests/security/src/android/security/cts/ClonedSecureRandomTest.java b/tests/tests/security/src/android/security/cts/ClonedSecureRandomTest.java
index dfefad7..d188aab 100644
--- a/tests/tests/security/src/android/security/cts/ClonedSecureRandomTest.java
+++ b/tests/tests/security/src/android/security/cts/ClonedSecureRandomTest.java
@@ -21,10 +21,12 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
+import android.os.DeadObjectException;
 import android.os.IBinder;
 import android.security.cts.activity.ISecureRandomService;
 import android.security.cts.activity.SecureRandomService;
 import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
 
 import java.io.BufferedReader;
 import java.io.EOFException;
@@ -35,10 +37,11 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+@LargeTest
 public class ClonedSecureRandomTest extends AndroidTestCase {
-    private static final int MAX_SHUTDOWN_TRIES = 10;
+    private static final int MAX_SHUTDOWN_TRIES = 50;
 
-    private static final int ANSWER_TIMEOUT_SECONDS = 60;
+    private static final int ANSWER_TIMEOUT_SECONDS = 180;
 
     private static final String SEPARATE_PROCESS_NAME = ":secureRandom";
 
diff --git a/tests/tests/security/src/android/security/cts/EncryptionTest.java b/tests/tests/security/src/android/security/cts/EncryptionTest.java
new file mode 100644
index 0000000..bd9a458
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/EncryptionTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.test.AndroidTestCase;
+import junit.framework.TestCase;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.util.Log;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class EncryptionTest extends AndroidTestCase {
+
+    static {
+        System.loadLibrary("ctssecurity_jni");
+    }
+
+    private static final String TAG = "EncryptionTest";
+
+    private static final String crypto = "/proc/crypto";
+
+    private static native boolean deviceIsEncrypted();
+
+    private static native boolean cpuHasAes();
+
+    private static native boolean cpuHasNeon();
+
+    private static native boolean neonIsEnabled();
+
+    private static native boolean aesIsFast();
+
+    private boolean hasKernelCrypto(String driver) throws Exception {
+        BufferedReader br = new BufferedReader(new FileReader(crypto));
+        Pattern p = Pattern.compile("driver\\s*:\\s*" + driver);
+
+        try {
+            String line;
+            while ((line = br.readLine()) != null) {
+                if (p.matcher(line).matches()) {
+                    Log.i(TAG, crypto + " has " + driver + " (" + line + ")");
+                    return true;
+                }
+            }
+       } finally {
+           br.close();
+       }
+
+       return false;
+    }
+
+    private boolean hasLowRAM() {
+        ActivityManager activityManager =
+            (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
+
+        return activityManager.isLowRamDevice();
+    }
+
+    public void testConfig() throws Exception {
+        if (cpuHasAes()) {
+            // If CPU has AES CE, it must be enabled in kernel
+            assertTrue(crypto + " is missing xts-aes-ce",
+                hasKernelCrypto("xts-aes-ce"));
+        } else if (cpuHasNeon()) {
+            // Otherwise, if CPU has NEON, it must be enabled
+            assertTrue(crypto + " is missing xts-aes-neon (or xts-aes-neonbs)",
+                hasKernelCrypto("xts-aes-neon") ||
+                hasKernelCrypto("xts-aes-neonbs") ||
+                hasKernelCrypto("aes-asm")); // Not recommended alone
+        }
+
+        if (cpuHasNeon()) {
+            assertTrue("libcrypto must have NEON", neonIsEnabled());
+        }
+    }
+
+    public void testEncryption() throws Exception {
+        if (deviceIsEncrypted()) {
+            return;
+        }
+
+        // Optional for low RAM devices
+        if (hasLowRAM()) {
+            Log.i(TAG, "hasLowRAM: true");
+            return;
+        }
+
+        // Required if performance is sufficient
+        assertFalse("Device encryption is required", aesIsFast());
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/HttpPost.java b/tests/tests/security/src/android/security/cts/HttpPost.java
new file mode 100644
index 0000000..7f855d9
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/HttpPost.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 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/KernelSettingsTest.java b/tests/tests/security/src/android/security/cts/KernelSettingsTest.java
index f3163be..9925e9d 100644
--- a/tests/tests/security/src/android/security/cts/KernelSettingsTest.java
+++ b/tests/tests/security/src/android/security/cts/KernelSettingsTest.java
@@ -115,7 +115,26 @@
 
     private static native boolean supportsXattr();
 
-    private String getFile(String filename) throws IOException {
+    /**
+     * ICMP redirects should be disabled.
+     */
+    public void testNoIcmpRedirects() throws IOException {
+        try {
+            assertEquals("ICMP redirects are enabled for IPv4.",
+                    "0", getFile("/proc/sys/net/ipv4/conf/all/accept_redirects"));
+        } catch (FileNotFoundException e) {
+            // Odd. The file doesn't exist... Assume we're ok.
+        }
+
+        try {
+            assertEquals("ICMP redirects are enabled for IPv6.",
+                    "0", getFile("/proc/sys/net/ipv6/conf/all/accept_redirects"));
+        } catch (FileNotFoundException e) {
+            // Odd. The file doesn't exist... Assume we're ok.
+        }
+    }
+
+    static String getFile(String filename) throws IOException {
         BufferedReader in = null;
         try {
             in = new BufferedReader(new FileReader(filename));
diff --git a/tests/tests/security/src/android/security/cts/KeyRequester.java b/tests/tests/security/src/android/security/cts/KeyRequester.java
new file mode 100644
index 0000000..26a3337
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/KeyRequester.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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
new file mode 100644
index 0000000..c4d96dd
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/KeyRequesterTask.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 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/KeystoreExploitTest.java b/tests/tests/security/src/android/security/cts/KeystoreExploitTest.java
deleted file mode 100644
index 23266c2..0000000
--- a/tests/tests/security/src/android/security/cts/KeystoreExploitTest.java
+++ /dev/null
@@ -1,60 +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.security.cts;
-
-import android.test.AndroidTestCase;
-
-import java.io.File;
-import java.lang.reflect.Method;
-
-public class KeystoreExploitTest extends AndroidTestCase {
-    public void testKeystoreCrash() throws Exception {
-        int pid = Proc.findPidFor("/system/bin/keystore");
-
-        Class<?> keystoreClass = Class.forName("android.security.KeyStore");
-        Method getInstance = keystoreClass.getMethod("getInstance");
-        Method get = keystoreClass.getMethod("get", String.class);
-
-        Object keystore = getInstance.invoke(null);
-        String keyName = "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA";
-        get.invoke(keystore, keyName);
-
-        Thread.sleep(2000); // give keystore some time to crash
-
-        assertTrue("PID=" + pid + " crashed due to a malformed key name.",
-                new File("/proc/" + pid + "/cmdline").exists());
-    }
-}
diff --git a/tests/tests/security/src/android/security/cts/MediaCryptoTest.java b/tests/tests/security/src/android/security/cts/MediaCryptoTest.java
new file mode 100644
index 0000000..b5639a7
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/MediaCryptoTest.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 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/NativeCodeTest.java b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
index 5ee8f69..ab41b4f 100644
--- a/tests/tests/security/src/android/security/cts/NativeCodeTest.java
+++ b/tests/tests/security/src/android/security/cts/NativeCodeTest.java
@@ -42,12 +42,6 @@
         assertTrue(doPerfEventTest2());
     }
 
-    public void testSockDiag() throws Exception {
-        int result = doSockDiagTest();
-        assertFalse("Encountered unexpected error: " + result + ".", (result == -1));
-        assertEquals(0, result);
-    }
-
     public void testFutex() throws Exception {
         assertTrue("Device is vulnerable to CVE-2014-3153, a vulnerability in the futex() system "
                    + "call. Please apply the security patch at "
@@ -70,7 +64,6 @@
                    + "https://github.com/torvalds/linux/commit/a134f083e79f",
                    doPingPongRootTest());
     }
-
     /**
      * Returns true iff this device is vulnerable to CVE-2013-2094.
      * A patch for CVE-2013-2094 can be found at
@@ -94,12 +87,6 @@
     private static native boolean doPerfEventTest2();
 
     /**
-     * Hangs if device is vulnerable to CVE-2013-1763, returns -1 if
-     * unexpected error occurs, 0 otherwise.
-     */
-    private static native int doSockDiagTest();
-
-    /**
      * ANDROID-11234878 / CVE-2013-6282
      *
      * Returns true if the device is patched against the vroot vulnerability, false otherwise.
@@ -152,4 +139,5 @@
      * http://seclists.org/oss-sec/2015/q2/333
      */
     private static native boolean doPingPongRootTest();
+
 }
diff --git a/tests/tests/security/src/android/security/cts/NetlinkSocket.java b/tests/tests/security/src/android/security/cts/NetlinkSocket.java
deleted file mode 100644
index 5ea80ca..0000000
--- a/tests/tests/security/src/android/security/cts/NetlinkSocket.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.security.cts;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.net.SocketException;
-
-public class NetlinkSocket {
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    private static native void create_native(FileDescriptor fd) throws SocketException;
-    private static native int sendmsg(FileDescriptor fd, int pid, byte[] bytes);
-
-    private FileDescriptor fd = new FileDescriptor();
-
-    /** no public constructors */
-    private NetlinkSocket() { }
-
-    public static NetlinkSocket create() throws SocketException {
-        NetlinkSocket retval = new NetlinkSocket();
-        create_native(retval.fd);
-        return retval;
-    }
-
-    public boolean valid() {
-        return fd.valid();
-    }
-
-    public int sendmsg(int pid, byte[] bytes) throws IOException {
-        int retval = sendmsg(fd, pid, bytes);
-        if (retval == -1) {
-            throw new IOException("Unable to send message to PID=" + pid);
-        }
-        return retval;
-    }
-}
diff --git a/tests/tests/security/src/android/security/cts/Proc.java b/tests/tests/security/src/android/security/cts/Proc.java
deleted file mode 100644
index 6fe0706..0000000
--- a/tests/tests/security/src/android/security/cts/Proc.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 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.security.cts;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-
-/**
- * Utilities for accessing /proc filesystem information.
- */
-public class Proc {
-    public static int findPidFor(String executable) throws IOException {
-        File f = new File("/proc");
-        for (File d : f.listFiles()) {
-            String cmdLineString = d.getAbsolutePath() + "/cmdline";
-            File cmdLine = new File(cmdLineString);
-            if (cmdLine.exists()) {
-                BufferedReader in = null;
-                try {
-                    in = new BufferedReader(new FileReader(cmdLine));
-                    String line = in.readLine();
-                    if ((line != null) && line.startsWith(executable)) {
-                        return Integer.decode(d.getName());
-                    }
-                } finally {
-                    if (in != null) {
-                        in.close();
-                    }
-                }
-            }
-        }
-        throw new RuntimeException("should never get here");
-    }
-}
diff --git a/tests/tests/security/src/android/security/cts/ProvisionRequester.java b/tests/tests/security/src/android/security/cts/ProvisionRequester.java
new file mode 100644
index 0000000..ee1cb9e
--- /dev/null
+++ b/tests/tests/security/src/android/security/cts/ProvisionRequester.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 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/SELinuxDomainTest.java b/tests/tests/security/src/android/security/cts/SELinuxDomainTest.java
deleted file mode 100644
index c97c8c2..0000000
--- a/tests/tests/security/src/android/security/cts/SELinuxDomainTest.java
+++ /dev/null
@@ -1,410 +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;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.IOException;
-import java.io.FileNotFoundException;
-import java.io.InputStreamReader;
-import java.lang.Runtime;
-import java.text.ParseException;
-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;
-
-/**
- * Verify that the processes running within an SELinux domain are sane.
- *
- * TODO: Author the tests for the app contexts.
- *
- */
-public class SELinuxDomainTest extends TestCase {
-
-    /**
-     * Asserts that no processes are running in a domain.
-     *
-     * @param domain
-     *  The domain or SELinux context to check.
-     */
-    private void assertDomainEmpty(String domain) throws FileNotFoundException {
-        List<ProcessDetails> procs = ProcessDetails.getProcessMap().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 FileNotFoundException {
-        List<ProcessDetails> procs = ProcessDetails.getProcessMap().get(domain);
-        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);
-    }
-
-    /**
-     * 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 FileNotFoundException {
-        List<ProcessDetails> procs = ProcessDetails.getProcessMap().get(domain);
-        if (procs == null) {
-            /* not on all devices */
-            return;
-        }
-
-        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);
-    }
-
-    /**
-     * 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 FileNotFoundException {
-        List<ProcessDetails> procs = ProcessDetails.getProcessMap().get(domain);
-        String msg = "Expected 1 or more processes in SELinux domain \"" + domain + "\""
-                + " Found \"" + procs + "\"";
-        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));
-        }
-    }
-
-    /**
-     * 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 FileNotFoundException {
-        List<ProcessDetails> procs = ProcessDetails.getProcessMap().get(domain);
-        if (procs == null) {
-            return; // domain doesn't exist
-        }
-
-        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));
-        }
-    }
-
-    /* Init is always there */
-    public void testInitDomain() throws FileNotFoundException {
-        assertDomainOne("u:r:init:s0", "/init");
-    }
-
-    /* Ueventd is always there */
-    public void testUeventdDomain() throws FileNotFoundException {
-        assertDomainOne("u:r:ueventd:s0", "/sbin/ueventd");
-    }
-
-    /* Devices always have healthd */
-    public void testHealthdDomain() throws FileNotFoundException {
-        assertDomainOne("u:r:healthd:s0", "/sbin/healthd");
-    }
-
-    /* Servicemanager is always there */
-    public void testServicemanagerDomain() throws FileNotFoundException {
-        assertDomainOne("u:r:servicemanager:s0", "/system/bin/servicemanager");
-    }
-
-    /* Vold is always there */
-    public void testVoldDomain() throws FileNotFoundException {
-        assertDomainOne("u:r:vold:s0", "/system/bin/vold");
-    }
-
-    /* netd is always there */
-    public void testNetdDomain() throws FileNotFoundException {
-        assertDomainOne("u:r:netd:s0", "/system/bin/netd");
-    }
-
-    /* Debuggerd is always there */
-    public void testDebuggerdDomain() throws FileNotFoundException {
-        assertDomainN("u:r:debuggerd:s0", "/system/bin/debuggerd", "/system/bin/debuggerd64");
-    }
-
-    /* Surface flinger is always there */
-    public void testSurfaceflingerDomain() throws FileNotFoundException {
-        assertDomainOne("u:r:surfaceflinger:s0", "/system/bin/surfaceflinger");
-    }
-
-    /* Zygote is always running */
-    public void testZygoteDomain() throws FileNotFoundException {
-        assertDomainN("u:r:zygote:s0", "zygote", "zygote64");
-    }
-
-    /* drm server is always present */
-    public void testDrmServerDomain() throws FileNotFoundException {
-        assertDomainZeroOrOne("u:r:drmserver:s0", "/system/bin/drmserver");
-    }
-
-    /* Media server is always running */
-    public void testMediaserverDomain() throws FileNotFoundException {
-        assertDomainN("u:r:mediaserver:s0", "media.log", "/system/bin/mediaserver");
-    }
-
-    /* Installd is always running */
-    public void testInstalldDomain() throws FileNotFoundException {
-        assertDomainOne("u:r:installd:s0", "/system/bin/installd");
-    }
-
-    /* keystore is always running */
-    public void testKeystoreDomain() throws FileNotFoundException {
-        assertDomainOne("u:r:keystore:s0", "/system/bin/keystore");
-    }
-
-    /* System server better be running :-P */
-    public void testSystemServerDomain() throws FileNotFoundException {
-        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 FileNotFoundException {
-        assertDomainHasExecutable("u:r:sdcardd:s0", "/system/bin/sdcard");
-    }
-
-    /* Watchdogd may or may not be there */
-    public void testWatchdogdDomain() throws FileNotFoundException {
-        assertDomainZeroOrOne("u:r:watchdogd:s0", "/sbin/watchdogd");
-    }
-
-    /* Wifi may be off so cardinality of 0 or 1 is ok */
-    public void testWpaDomain() throws FileNotFoundException {
-        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 FileNotFoundException {
-        assertDomainEmpty("u:r:init_shell:s0");
-    }
-
-    /*
-     * Nothing should be running in this domain, cardinality test is all thats
-     * needed
-     */
-    public void testRecoveryDomain() throws FileNotFoundException {
-        assertDomainEmpty("u:r:recovery:s0");
-    }
-
-    /*
-     * Nothing should be running in this domain, cardinality test is all thats
-     * needed
-     */
-    public void testSuDomain() throws FileNotFoundException {
-        assertDomainEmpty("u:r:su:s0");
-    }
-
-    /*
-     * All kthreads should be in kernel context.
-     */
-    public void testKernelDomain() throws FileNotFoundException {
-        String domain = "u:r:kernel:s0";
-        List<ProcessDetails> procs = ProcessDetails.getProcessMap().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 procTitle;
-        public long vSize;
-        public int pid;
-
-        private ProcessDetails(String procTitle, String label, long vSize, int pid) {
-            this.label = label;
-            this.procTitle = procTitle;
-            this.vSize = vSize;
-            this.pid = pid;
-        }
-
-        @Override
-        public String toString() {
-            return "pid: \"" + pid + "\"\tproctitle: \"" + procTitle + "\"\tlabel: \"" + label
-                    + "\"\tvsize: " + vSize;
-        }
-
-        public boolean isKernel() {
-            return vSize == 0;
-        }
-
-        private static long getVsizeFromStat(String stat) {
-            // Get the vSize, item #23 from the stat file
-            //                   1        2             3   4    5    6    7      8    9   10   11
-            String pattern = "^\\d+ \\(\\p{Print}*\\) \\w \\d+ \\d+ \\d+ \\d+ -?\\d+ \\d+ \\d+ \\d+ "
-                //  12   13   14   15   16   17     18     19   20   21   22    23
-                + "\\d+ \\d+ \\d+ \\d+ \\d+ \\d+ -?\\d+ -?\\d+ \\d+ \\d+ \\d+ (\\d+) .*$";
-
-            Pattern p = Pattern.compile(pattern);
-            Matcher m = p.matcher(stat);
-            assertTrue("failed match: \"" + stat + "\"", m.matches());
-            return Long.parseLong(m.group(1));
-        }
-
-        private static HashMap<String, ArrayList<ProcessDetails>> getProcessMap()
-                throws FileNotFoundException {
-
-            HashMap<String, ArrayList<ProcessDetails>> map = new HashMap<String, ArrayList<ProcessDetails>>();
-
-            File root = new File("/proc");
-            if (!root.isDirectory()) {
-                throw new FileNotFoundException("/proc is not a directory!");
-            }
-
-            for (File f : root.listFiles()) {
-
-                // We only want the pid directory entries
-                if (!f.isDirectory()) {
-                    continue;
-                }
-
-                int pid;
-                try {
-                    pid = Integer.parseInt(f.getName());
-                } catch (NumberFormatException e) {
-                    continue;
-                }
-
-                try {
-                    ProcessDetails p = getProcessDetails(pid, f);
-                    ArrayList<ProcessDetails> l = map.get(p.label);
-                    if (l == null) {
-                        l = new ArrayList<ProcessDetails>();
-                        map.put(p.label, l);
-                    }
-                    l.add(p);
-                } catch (FileNotFoundException e) {
-                    // sometimes processes go away while the test is running.
-                    // Don't freak out if this happens
-                }
-            }
-            return map;
-        }
-
-        private static ProcessDetails getProcessDetails(int pid, File f) throws FileNotFoundException {
-            Scanner tmp = null;
-            String context;
-            long vSize;
-            try {
-                tmp = new Scanner(new File(f, "attr/current"));
-                // Get the context via attr/current
-                context = tmp.next();
-                context = context.trim();
-            } finally {
-                if (tmp != null) {
-                    tmp.close();
-                    tmp = null;
-                }
-            }
-
-            try {
-                // Get the vSize, item #23 from the stat file
-                tmp = new Scanner(new File(f, "stat"));
-                String x = tmp.nextLine();
-                vSize = getVsizeFromStat(x);
-            } finally {
-                if (tmp != null) {
-                    tmp.close();
-                    tmp = null;
-                }
-            }
-
-            StringBuilder sb = new StringBuilder();
-            try {
-                tmp = new Scanner(new File(f, "cmdline"));
-
-                // Java's scanner tends to return oddly when handling
-                // long binary blobs. Probably some caching optimization.
-                while (tmp.hasNext()) {
-                    sb.append(tmp.next().replace('\0', ' '));
-                }
-            } finally {
-                if (tmp != null) {
-                    tmp.close();
-                }
-            }
-
-            // At this point we build up a valid proctitle, then split
-            // on whitespace to get the left portion. Which is either
-            // package name or process executable path. This avoids
-            // the comm 16 char width limitation and is limited to PAGE_SIZE
-            String cmdline = sb.toString().trim();
-            cmdline = cmdline.split("\\s+")[0];
-
-            return new ProcessDetails(cmdline, context, vSize, pid);
-        }
-
-    }
-}
diff --git a/tests/tests/security/src/android/security/cts/SELinuxTest.java b/tests/tests/security/src/android/security/cts/SELinuxTest.java
index 711cb91..3df7396 100644
--- a/tests/tests/security/src/android/security/cts/SELinuxTest.java
+++ b/tests/tests/security/src/android/security/cts/SELinuxTest.java
@@ -71,8 +71,6 @@
 
     public void testZygote() {
         assertFalse(checkSELinuxAccess("u:r:zygote:s0", "u:object_r:runas_exec:s0", "file", "getattr", "/system/bin/run-as"));
-        // Also check init, just as a sanity check (init is unconfined, so it should pass)
-        assertTrue(checkSELinuxAccess("u:r:init:s0", "u:object_r:runas_exec:s0", "file", "getattr", "/system/bin/run-as"));
     }
 
     public void testNoBooleans() throws Exception {
@@ -81,7 +79,40 @@
         assertEquals(0, files.length);
     }
 
+    public void testCTSIsUntrustedApp() throws IOException {
+        String found = KernelSettingsTest.getFile("/proc/self/attr/current");
+        String expected = "u:r:untrusted_app:s0";
+        String msg = "Expected prefix context: \"" + expected + "\"" +
+                        ", Found: \"" + found + "\"";
+        assertTrue(msg, found.startsWith(expected));
+    }
+
+    public void testCTSAppDataContext() throws Exception {
+        File appDataDir = getContext().getFilesDir();
+        String found = getFileContext(appDataDir.getAbsolutePath());
+        String expected = "u:object_r:app_data_file:s0";
+        String msg = "Expected prefix context: \"" + expected + "\"" +
+                        ", Found: \"" + found + "\"";
+        assertTrue(msg, found.startsWith(expected));
+    }
+
+    public void testFileContexts() throws Exception {
+        assertEquals(getFileContext("/"), "u:object_r:rootfs:s0");
+        assertEquals(getFileContext("/dev"), "u:object_r:device:s0");
+        assertEquals(getFileContext("/dev/socket"), "u:object_r:socket_device:s0");
+        assertEquals(getFileContext("/dev/binder"), "u:object_r:binder_device:s0");
+        assertEquals(getFileContext("/system"), "u:object_r:system_file:s0");
+        assertEquals(getFileContext("/system/bin/app_process"), "u:object_r:zygote_exec:s0");
+        assertEquals(getFileContext("/data"), "u:object_r:system_data_file:s0");
+        assertEquals(getFileContext("/data/app"), "u:object_r:apk_data_file:s0");
+        assertEquals(getFileContext("/data/local/tmp"), "u:object_r:shell_data_file:s0");
+        assertEquals(getFileContext("/cache"), "u:object_r:cache_file:s0");
+        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/SeccompBpfTest.java b/tests/tests/security/src/android/security/cts/SeccompBpfTest.java
deleted file mode 100644
index b7d8f2e..0000000
--- a/tests/tests/security/src/android/security/cts/SeccompBpfTest.java
+++ /dev/null
@@ -1,207 +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 android.test.AndroidTestCase;
-
-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.HandlerThread;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Test for seccomp-bpf sandboxing technology. This makes use of the
- * SeccompDeathTestService to run sandboxing death tests out-of-process.
- */
-public class SeccompBpfTest extends AndroidTestCase implements ServiceConnection,
-       IBinder.DeathRecipient {
-    static final String TAG = "SeccompBpfTest";
-
-    /**
-     * Message sent from the SeccompDeathTestService before it runs a test.
-     */
-    static final int MSG_TEST_STARTED = 1;
-    /**
-     * Message sent from the SeccompDeathTestService after a test exits cleanly.
-     */
-    static final int MSG_TEST_ENDED_CLEAN = 2;
-
-    /**
-     * Dedicated thread used to receive messages from the SeccompDeathTestService.
-     */
-    final private HandlerThread mHandlerThread = new HandlerThread("SeccompBpfTest handler");
-    /**
-     * Messenger that runs on mHandlerThread.
-     */
-    private Messenger mMessenger;
-
-    /**
-     * Condition that blocks the test/instrumentation thread that runs the
-     * test cases, while the SeccompDeathTestService runs the test out-of-process.
-     */
-    final private ConditionVariable mCondition = new ConditionVariable();
-
-    /**
-     * The SeccompDeathTestService number to run.
-     */
-    private int mTestNumber = -1;
-
-    /**
-     * If the test has started.
-     */
-    private boolean mTestStarted = false;
-    /**
-     * If the test ended (either cleanly or with death).
-     */
-    private boolean mTestEnded = false;
-    /**
-     * If the test ended cleanly or died.
-     */
-    private boolean mTestDied = false;
-
-    public void testDeathTest() {
-        runDeathTest(SeccompDeathTestService.TEST_DEATH_TEST);
-        assertTrue(mTestDied);
-    }
-
-    public void testCleanTest() {
-        runDeathTest(SeccompDeathTestService.TEST_CLEAN_TEST);
-        assertFalse(mTestDied);
-    }
-
-    public void testSigSysSelf() {
-        runDeathTest(SeccompDeathTestService.TEST_SIGSYS_SELF);
-        assertTrue(mTestDied);
-    }
-
-    /**
-     * Runs a death test by its test number, which needs to match a value in
-     * SeccompDeathTestService.
-     *
-     * This blocks until the completion of the test, after which the test body
-     * can use mTestEnded/mTestDied to see if the test died.
-     */
-    public void runDeathTest(final int testNumber) {
-        mTestStarted = false;
-        mTestEnded = false;
-        mTestDied = false;
-
-        mTestNumber = testNumber;
-
-        Log.d(TAG, "Starting runDeathTest");
-        launchDeathTestService();
-        mCondition.block();
-
-        assertTrue(mTestStarted);
-        assertTrue(mTestEnded);
-    }
-
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mHandlerThread.start();
-        mMessenger = new Messenger(new Handler(mHandlerThread.getLooper()) {
-            @Override
-            public void handleMessage(Message msg) {
-                switch (msg.what) {
-                    case MSG_TEST_STARTED:
-                        onTestStarted();
-                        break;
-                    case MSG_TEST_ENDED_CLEAN:
-                        onTestEnded(false);
-                        break;
-                    default:
-                        super.handleMessage(msg);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void tearDown() throws Exception {
-        try {
-            mHandlerThread.quitSafely();
-        } finally {
-            super.tearDown();
-        }
-    }
-
-    private void launchDeathTestService() {
-        Log.d(TAG, "launchDeathTestService");
-        mCondition.close();
-
-        Intent intent = new Intent();
-        intent.setComponent(new ComponentName("com.android.cts.security", "android.security.cts.SeccompDeathTestService"));
-
-        if (!getContext().bindService(intent, this, Context.BIND_AUTO_CREATE)) {
-            mCondition.open();
-            fail("Failed to start DeathTestService");
-        }
-    }
-
-    @Override
-    public void onServiceConnected(ComponentName name, IBinder service) {
-        Log.d(TAG, "onServiceConnected");
-
-        Messenger remoteMessenger = new Messenger(service);
-        Message msg = Message.obtain(null, SeccompDeathTestService.MSG_RUN_TEST);
-        msg.getData().putBinder(SeccompDeathTestService.REPLY_BINDER_NAME, mMessenger.getBinder());
-        msg.getData().putInt(SeccompDeathTestService.RUN_TEST_IDENTIFIER, mTestNumber);
-
-        try {
-            service.linkToDeath(this, 0);
-            remoteMessenger.send(msg);
-        } catch (RemoteException e) {
-            Log.e(TAG, "Error setting up SeccompDeathTestService: " + e.getMessage());
-        }
-        Log.d(TAG, "Send MSG_TEST_START");
-    }
-
-    private void onTestStarted() {
-        Log.d(TAG, "onTestStarted");
-        mTestStarted = true;
-    }
-
-    @Override
-    public void onServiceDisconnected(ComponentName name) {
-        Log.d(TAG, "onServiceDisconnected");
-    }
-
-    @Override
-    public void binderDied() {
-        Log.d(TAG, "binderDied");
-        if (mTestEnded)
-            return;
-        onTestEnded(true);
-    }
-
-    private void onTestEnded(boolean died) {
-        Log.d(TAG, "onTestEnded, died=" + died);
-        mTestEnded = true;
-        mTestDied = died;
-        getContext().unbindService(this);
-        mCondition.open();
-    }
-}
diff --git a/tests/tests/security/src/android/security/cts/SeccompDeathTestService.java b/tests/tests/security/src/android/security/cts/SeccompDeathTestService.java
deleted file mode 100644
index c78ea35..0000000
--- a/tests/tests/security/src/android/security/cts/SeccompDeathTestService.java
+++ /dev/null
@@ -1,122 +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 android.app.Service;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.Messenger;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Service used to run tests for seccomp-bpf sandboxing. Since sandbox violations
- * result in process termination, they cannot be run from within the test case
- * itself. The SeccompBpfTest starts this service to run code out-of-process and
- * then observes when the Binder channel dies. If the test does not die, the
- * service reports back to the test that it exited cleanly.
- */
-public class SeccompDeathTestService extends Service {
-    static final String TAG = SeccompBpfTest.TAG;
-
-    static {
-        System.loadLibrary("ctssecurity_jni");
-    }
-
-    /**
-     * Message sent from SeccompBpfTest to run a test.
-     */
-    final static int MSG_RUN_TEST = 100;
-    /**
-     * In MSG_RUN_TEST, the test number to run.
-     */
-    final static String RUN_TEST_IDENTIFIER = "android.security.cts.SeccompDeathTestService.testID";
-    /**
-     * In MSG_RUN_TEST, the Binder on which to report clean death.
-     */
-    static final String REPLY_BINDER_NAME = "android.security.cts.SeccompBpfTest";
-
-    // Test numbers that map to test methods in this service.
-    final static int TEST_DEATH_TEST = 1;
-    final static int TEST_CLEAN_TEST = 2;
-    final static int TEST_SIGSYS_SELF = 3;
-
-    final private Messenger mMessenger = new Messenger(new Handler() {
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MSG_RUN_TEST:
-                    runTest(msg);
-                    break;
-                default:
-                    super.handleMessage(msg);
-            }
-        }
-    });
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        Log.d(TAG, "onBind");
-        return mMessenger.getBinder();
-    }
-
-    private void runTest(Message msg) {
-        Log.d(TAG, "runTest");
-        IBinder harnessBinder = msg.getData().getBinder(REPLY_BINDER_NAME);
-        Messenger harness = new Messenger(harnessBinder);
-
-        try {
-            Log.d(TAG, "Send MSG_TEST_STARTED");
-            harness.send(Message.obtain(null, SeccompBpfTest.MSG_TEST_STARTED));
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to MSG_TEST_STARTED: " + e.getMessage());
-        }
-
-        demuxTest(msg.getData().getInt(RUN_TEST_IDENTIFIER));
-
-        try {
-            Log.d(TAG, "Send MSG_TEST_ENDED_CLEAN");
-            harness.send(Message.obtain(null, SeccompBpfTest.MSG_TEST_ENDED_CLEAN));
-        } catch (RemoteException e) {
-            Log.e(TAG, "Failed to MSG_TEST_ENDED_CLEAN: " + e.getMessage());
-        }
-    }
-
-    private void demuxTest(int testNumber) {
-        switch (testNumber) {
-            case TEST_DEATH_TEST:
-                testDeath();
-                break;
-            case TEST_CLEAN_TEST:
-                break;
-            case TEST_SIGSYS_SELF:
-                testSigSysSelf();
-                break;
-            default:
-                throw new RuntimeException("Unknown test number " + testNumber);
-        }
-    }
-
-    public void testDeath() {
-        String s = null;
-        s.hashCode();
-    }
-
-    public native void testSigSysSelf();
-}
diff --git a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
index 00cbfd8..fdc3058 100644
--- a/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
+++ b/tests/tests/security/src/android/security/cts/ServicePermissionsTest.java
@@ -17,6 +17,7 @@
 package android.security.cts;
 
 import android.os.IBinder;
+import android.os.DeadObjectException;
 import android.os.TransactionTooLargeException;
 import android.test.AndroidTestCase;
 import android.util.Log;
@@ -108,7 +109,7 @@
                     // probably not checking for DUMP.
                     throw e;
                 }
-            } catch (TransactionTooLargeException e) {
+            } catch (TransactionTooLargeException | DeadObjectException e) {
                 // SELinux likely prevented the dump - assume safe
                 continue;
             } finally {
diff --git a/tests/tests/security/src/android/security/cts/VoldExploitTest.java b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
index 103158f..248579c 100644
--- a/tests/tests/security/src/android/security/cts/VoldExploitTest.java
+++ b/tests/tests/security/src/android/security/cts/VoldExploitTest.java
@@ -17,23 +17,9 @@
 package android.security.cts;
 
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.os.storage.StorageManager;
 import android.test.AndroidTestCase;
 
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.SocketException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Scanner;
-import java.util.Set;
-
 public class VoldExploitTest extends AndroidTestCase {
 
     /**
@@ -45,245 +31,4 @@
         String path = sm.getMountedObbPath("/dev/null\0asec list");
         assertNull(path);
     }
-
-    /**
-     * Validate that this device isn't vulnerable to the "ZergRush"
-     * vold vulnerability (CVE-2011-3874).
-     *
-     * https://github.com/revolutionary/zergRush/blob/master/zergRush.c
-     *
-     * Note: If the ZergRush vulnerability is present, the call to
-     * {@link StorageManager#getMountedObbPath(String)} below hangs until CTS
-     * kills the testsuite (10 minutes). A timeout, while not desirable,
-     * is the typical failure for this test.
-     */
-    public void testZergRushCrash() throws Exception {
-        int pid = Proc.findPidFor("/system/bin/vold");
-
-        StorageManager sm = (StorageManager) getContext().getSystemService(Context.STORAGE_SERVICE);
-        sm.getMountedObbPath("AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA "
-                + "AAAA AAAA AAAA AAAA"
-                + "AAAA AAAA AAAA AAAA"
-                + "AAAA AAAA AAAA AAAA"
-                + "AAAA AAAA AAAA AAAA"
-                + "AAAA AAAA AAAA AAAA");
-
-        Thread.sleep(2000);  // give vold some time to crash
-
-        // Check to see if vold is still alive.
-        assertTrue(
-                "PID=" + pid + " crashed due to a malformed mount message."
-                        + " Detected unpatched ZergRush vulnerability (CVE-2011-3874).",
-                new File("/proc/" + pid + "/cmdline").exists());
-    }
-
-    /**
-     * Try to crash the vold program using CVE-2011-1823.
-     *
-     * This test attempts to send an invalid netlink messages to
-     * any process which is listening for the messages.  If we detect
-     * that any process crashed as a result of our message, then
-     * we know that we found a bug.
-     *
-     * If this test fails, it's due to CVE-2011-1823
-     *
-     * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2011-1823
-     */
-    public void testTryToCrashVold() throws IOException {
-        Set<Integer> pids = getPids();
-        assertTrue(pids.size() > 1);  // at least vold and netd should exist
-
-        Set<String> devices = new HashSet<String>();
-        devices.addAll(getSysFsPath("/etc/vold.fstab"));
-        devices.addAll(getSysFsPath("/system/etc/vold.fstab"));
-        if (devices.isEmpty()) {
-          // This vulnerability is not exploitable if there's
-          // no entry in vold.fstab
-          return;
-        }
-
-        NetlinkSocket ns;
-        try {
-            ns = NetlinkSocket.create();
-        } catch (SocketException e) {
-            // Can't create netlink socket. Not vulnerable.
-            return;
-        }
-        for (int i : pids) {
-            for (String j : devices) {
-                doAttack(ns, i, j);
-            }
-        }
-
-        // Check to see if all the processes are still alive.  If
-        // any of them have died, we found an exploitable bug.
-        for (int i : pids) {
-            assertTrue(
-                    "PID=" + i + " crashed due to a malformed netlink message."
-                    + " Detected unpatched vulnerability CVE-2011-1823.",
-                    new File("/proc/" + i + "/cmdline").exists());
-        }
-    }
-
-    /**
-     * Try to actually crash the program, by first sending a fake
-     * request to add a new disk, followed by a fake request to add
-     * a partition.
-     */
-    private static void doAttack(NetlinkSocket ns, int pid, String path)
-            throws IOException {
-        try {
-            ns.sendmsg(pid, getDiskAddedMessage(path));
-            confirmNetlinkMsgReceived();
-
-            for (int i = -1000; i > -5000; i-=1000) {
-                ns.sendmsg(pid, getPartitionAddedMessage(path, i));
-                confirmNetlinkMsgReceived();
-            }
-        } catch (IOException e) {
-            // Ignore the exception.  The process either:
-            //
-            // 1) Crashed
-            // 2) Closed the netlink socket and refused further messages
-            //
-            // If #1 occurs, our PID check in testTryToCrashVold() will
-            // detect the process crashed and trigger an error.
-            //
-            // #2 is not a security bug.  It's perfectly acceptable to
-            // refuse messages from someone trying to send you
-            // malicious content.
-        }
-    }
-
-    /**
-     * Parse the fstab.vold file, and extract out the "sysfs_path" field.
-     */
-    private static Set<String> getSysFsPath(String file) throws IOException {
-        Set<String> retval = new HashSet<String>();
-        File netlink = new File(file);
-        if (!netlink.canRead()) {
-            return retval;
-        }
-        Scanner scanner = null;
-        try {
-            scanner = new Scanner(netlink);
-            while(scanner.hasNextLine()) {
-                String line = scanner.nextLine().trim();
-                if (!line.startsWith("dev_mount")) {
-                    continue;
-                }
-
-                String[] fields = line.split("\\s+");
-                assertTrue(fields.length >= 5);
-                // Column 5 and beyond is "sysfs_path"
-                retval.addAll(Arrays.asList(fields).subList(4, fields.length));
-            }
-        } finally {
-            if (scanner != null) {
-                scanner.close();
-            }
-        }
-        return retval;
-    }
-
-    /**
-     * Poll /proc/net/netlink until all the "Rmem" fields contain
-     * "0" or approximately 10 seconds have passed.
-     *
-     * This indicates that either the netlink message was received,
-     * or the process took too long to process the incoming netlink
-     * message.
-     *
-     * See http://code.google.com/p/android/issues/detail?id=25099
-     * for information on why the timeout is needed.
-     */
-    private static void confirmNetlinkMsgReceived() {
-        try {
-            for (int ct = 0; ct < 200; ct++) {
-                boolean foundAllZeros = true;
-                for (List<String> i : parseNetlink()) {
-                    // Column 5 is the "Rmem" field, which is the
-                    // amount of kernel memory for received netlink messages.
-                    if (!i.get(4).equals("0")) {
-                        foundAllZeros = false;
-                    }
-                }
-                if (foundAllZeros) {
-                    return;
-                }
-                Thread.sleep(50);
-            }
-        } catch (InterruptedException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    /**
-     * Extract all the PIDs listening for netlink messages.
-     */
-    private static Set<Integer> getPids() {
-        List<List<String>> netlink = parseNetlink();
-        Set<Integer> retval = new HashSet<Integer>();
-        for (List<String> i : netlink) {
-            // The PID is in column 3
-            int pid = Long.decode(i.get(2)).intValue();
-            if (new File("/proc/" + pid + "/cmdline").exists()) {
-                retval.add(pid);
-            }
-        }
-        return retval;
-    }
-
-    /**
-     * Parse /proc/net/netlink and return a List of lines
-     * (excluding the first line)
-     */
-    private static List<List<String>> parseNetlink() {
-        List<List<String>> retval = new ArrayList<List<String>>();
-        File netlink = new File("/proc/net/netlink");
-        Scanner scanner = null;
-        try {
-            scanner = new Scanner(netlink);
-            while(scanner.hasNextLine()) {
-                String line = scanner.nextLine().trim();
-                if (line.startsWith("sk")) {
-                    continue;
-                }
-
-                List<String> lineList = Arrays.asList(line.split("\\s+"));
-                retval.add(lineList);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        } finally {
-            if (scanner != null) {
-                scanner.close();
-            }
-        }
-        return retval;
-    }
-
-    private static byte[] getDiskAddedMessage(String path) {
-        try {
-            return ("@/foo\0ACTION=add\0SUBSYSTEM=block\0"
-                    + "DEVPATH=" + path + "\0MAJOR=179\0MINOR=12345"
-                    + "\0DEVTYPE=disk\0").getBytes("ASCII");
-        } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private static byte[] getPartitionAddedMessage(
-            String path, int partitionNum) {
-        try {
-            return ("@/foo\0ACTION=add\0SUBSYSTEM=block\0"
-                    + "DEVPATH=" + path + "\0MAJOR=179\0MINOR=12345"
-                    + "\0DEVTYPE=blah\0PARTN=" + partitionNum + "\0")
-                    .getBytes("ASCII");
-        } catch (UnsupportedEncodingException e) {
-            throw new RuntimeException(e);
-        }
-    }
 }
diff --git a/tests/tests/security/tools/format_cert.sh b/tests/tests/security/tools/format_cert.sh
index 94407a0..604c1bc 100755
--- a/tests/tests/security/tools/format_cert.sh
+++ b/tests/tests/security/tools/format_cert.sh
@@ -26,16 +26,17 @@
 
 # Output file. If not specified, the file will be named <hash>.0 where "hash"
 # is the certificate's subject hash produced by:
-#   openssl x509 -in cert_file -subject_hash -noout
+#   openssl x509 -in cert_file -subject_hash_old -noout
 out_file="$2"
 
 # Detect whether the input file is PEM or DER.
+# It must use old_hash(MD5) function.
 in_form="pem"
-subject_hash=$("$OPENSSL" x509 -in "$in_file" -inform $in_form -subject_hash \
+subject_hash=$("$OPENSSL" x509 -in "$in_file" -inform $in_form -subject_hash_old \
     -noout 2>/dev/null)
 if [ "$?" != "0" ]; then
   in_form="der"
-  subject_hash=$("$OPENSSL" x509 -in "$in_file" -inform $in_form -subject_hash \
+  subject_hash=$("$OPENSSL" x509 -in "$in_file" -inform $in_form -subject_hash_old \
       -noout)
   if [ "$?" != "0" ]; then
     echo "Certificate file format is neither PEM nor DER"
diff --git a/tests/tests/speech/Android.mk b/tests/tests/speech/Android.mk
index 6bec012..3ab78b8 100755
--- a/tests/tests/speech/Android.mk
+++ b/tests/tests/speech/Android.mk
@@ -27,6 +27,7 @@
 
 LOCAL_PACKAGE_NAME := CtsSpeechTestCases
 
-LOCAL_SDK_VERSION := current
+# Needed for testing M API
+#LOCAL_SDK_VERSION := current
 
 include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java b/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java
index 5e6bb41..88bdc74 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/StubTextToSpeechService.java
@@ -20,12 +20,32 @@
 import android.speech.tts.SynthesisRequest;
 import android.speech.tts.TextToSpeech;
 import android.speech.tts.TextToSpeechService;
+import android.speech.tts.TtsEngines;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Locale;
 
 /**
  * Stub implementation of {@link TextToSpeechService}. Used for testing the
  * TTS engine API.
  */
 public class StubTextToSpeechService extends TextToSpeechService {
+    private static final String LOG_TAG = "StubTextToSpeechService";
+
+    // Object that onSynthesizeText will #wait on, if set to non-null
+    public static volatile Object sSynthesizeTextWait;
+
+    private ArrayList<Locale> supportedLanguages = new ArrayList<Locale>();
+    private ArrayList<Locale> supportedCountries = new ArrayList<Locale>();
+    private ArrayList<Locale> GBFallbacks = new ArrayList<Locale>();
+
+    public StubTextToSpeechService() {
+        supportedLanguages.add(new Locale("eng"));
+        supportedCountries.add(new Locale("eng", "USA"));
+        supportedCountries.add(new Locale("eng", "GBR"));
+        GBFallbacks.add(new Locale("eng", "NZL"));
+    }
 
     @Override
     protected String[] onGetLanguage() {
@@ -34,12 +54,19 @@
 
     @Override
     protected int onIsLanguageAvailable(String lang, String country, String variant) {
-        return TextToSpeech.LANG_AVAILABLE;
+        if (supportedCountries.contains(new Locale(lang, country))) {
+            return TextToSpeech.LANG_COUNTRY_AVAILABLE;
+        }
+        if (supportedLanguages.contains(new Locale(lang))) {
+            return TextToSpeech.LANG_AVAILABLE;
+        }
+ 
+        return TextToSpeech.LANG_NOT_SUPPORTED;
     }
 
     @Override
     protected int onLoadLanguage(String lang, String country, String variant) {
-        return TextToSpeech.LANG_AVAILABLE;
+        return onIsLanguageAvailable(lang, country, variant);
     }
 
     @Override
@@ -51,6 +78,18 @@
         if (callback.start(16000, AudioFormat.ENCODING_PCM_16BIT, 1) != TextToSpeech.SUCCESS) {
             return;
         }
+
+        final Object synthesizeTextWait = sSynthesizeTextWait;
+        if (synthesizeTextWait != null) {
+            synchronized (synthesizeTextWait) {
+                try {
+                    synthesizeTextWait.wait(10000);  // 10s timeout
+                } catch (InterruptedException e) {
+                    Log.e(LOG_TAG, "onSynthesizeText wait interrupted", e);
+                }
+            }
+        }
+
         byte[] data = { 0x01, 0x2 };
         if (callback.audioAvailable(data, 0, data.length) != TextToSpeech.SUCCESS) {
             return;
@@ -60,4 +99,20 @@
         }
     }
 
+    @Override
+    public String onGetDefaultVoiceNameFor(String lang, String country, String variant) {
+        Locale locale = new Locale(lang, country);
+        if (supportedCountries.contains(locale)) {
+          return TtsEngines.normalizeTTSLocale(locale).toLanguageTag();
+        }
+        if (lang.equals("eng")) {
+            if (GBFallbacks.contains(new Locale(lang, country))) {
+                return "en-GB";
+            } else {
+                return "en-US";
+            }
+        }
+        return super.onGetDefaultVoiceNameFor(lang, country, variant);
+    }
+
 }
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 c19f6c0..7425ecf 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechServiceTest.java
@@ -37,6 +37,7 @@
     @Override
     protected void setUp() throws Exception {
         super.setUp();
+        StubTextToSpeechService.sSynthesizeTextWait = null;
         mTts = TextToSpeechWrapper.createTextToSpeechMockWrapper(getContext());
         assertNotNull(mTts);
     }
@@ -74,6 +75,31 @@
         assertTrue("speak() completion timeout", waitForUtterance());
     }
 
+    public void testSpeakStop() throws Exception {
+        final Object synthesizeTextWait = new Object();
+        StubTextToSpeechService.sSynthesizeTextWait = synthesizeTextWait;
+
+        getTts().stop();
+        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));
+            assertEquals("speak() failed", TextToSpeech.SUCCESS, result);
+        }
+        getTts().stop();
+
+        // Wake up the Stubs #onSynthesizeSpeech (one that will be stopped in-progress)
+        synchronized (synthesizeTextWait) {
+          synthesizeTextWait.notify();
+        }
+
+        for (int i = 0; i < iterations; i++) {
+            assertTrue("speak() stop callback timeout", mTts.waitForStop(
+                    UTTERANCE_ID + Integer.toString(i)));
+        }
+    }
+
+
     public void testMediaPlayerFails() throws Exception {
         File sampleFile = new File(Environment.getExternalStorageDirectory(), "notsound.wav");
         try {
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 69acdd0..013a5ea 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechTest.java
@@ -94,6 +94,25 @@
         return false;
     }
 
+    private void assertContainsEngine(String engine, List<TextToSpeech.EngineInfo> engines) {
+        for (TextToSpeech.EngineInfo engineInfo : engines) {
+            if (engineInfo.name.equals(engine)) {
+                return;
+            }
+        }
+        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);
+        return params;
+    }
+
+    private boolean waitForUtterance() throws InterruptedException {
+        return mTts.waitForComplete(UTTERANCE_ID);
+    }
+
     public void testSynthesizeToFile() throws Exception {
         if (mTts == null) {
             return;
@@ -124,6 +143,21 @@
         assertTrue("speak() completion timeout", waitForUtterance());
     }
 
+    public void testSpeakStop() throws Exception {
+        getTts().stop();
+        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));
+            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)));
+        }
+    }
+
     public void testGetEnginesIncludesDefault() throws Exception {
         if (mTts == null) {
             return;
@@ -141,24 +175,4 @@
         assertNotNull("getEngines() returned null", engines);
         assertContainsEngine(TextToSpeechWrapper.MOCK_TTS_ENGINE, engines);
     }
-
-    private void assertContainsEngine(String engine, List<TextToSpeech.EngineInfo> engines) {
-        for (TextToSpeech.EngineInfo engineInfo : engines) {
-            if (engineInfo.name.equals(engine)) {
-                return;
-            }
-        }
-        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);
-        return params;
-    }
-
-    private boolean waitForUtterance() throws InterruptedException {
-        return mTts.waitForComplete(UTTERANCE_ID);
-    }
-
 }
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 f0d55bf..9d460e2 100644
--- a/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechWrapper.java
+++ b/tests/tests/speech/src/android/speech/tts/cts/TextToSpeechWrapper.java
@@ -19,9 +19,10 @@
 import android.media.MediaPlayer;
 import android.speech.tts.TextToSpeech;
 import android.speech.tts.TextToSpeech.OnInitListener;
-import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
+import android.speech.tts.UtteranceProgressListener;
 import android.util.Log;
 
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Condition;
@@ -65,7 +66,7 @@
         if (!mInitListener.waitForInit()) {
             return false;
         }
-        mTts.setOnUtteranceCompletedListener(mUtteranceListener);
+        mTts.setOnUtteranceProgressListener(mUtteranceListener);
         return true;
     }
 
@@ -73,6 +74,10 @@
         return mUtteranceListener.waitForComplete(utteranceId);
     }
 
+    public boolean waitForStop(String utteranceId) throws InterruptedException {
+        return mUtteranceListener.waitForStop(utteranceId);
+    }
+
     public TextToSpeech getTts() {
         return mTts;
     }
@@ -139,12 +144,16 @@
     /**
      * Listener for waiting for utterance completion.
      */
-    private static class UtteranceWaitListener implements OnUtteranceCompletedListener {
+    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>();
 
-        public void onUtteranceCompleted(String utteranceId) {
+        @Override
+        public void onDone(String utteranceId) {
             mLock.lock();
             try {
                 mCompletedUtterances.add(utteranceId);
@@ -154,6 +163,49 @@
             }
         }
 
+        @Override
+        public void onError(String utteranceId) {
+            mLock.lock();
+            try {
+                mErredUtterances.put(utteranceId, -1);
+                mDone.signal();
+            } finally {
+                mLock.unlock();
+            }
+        }
+
+        @Override
+        public void onError(String utteranceId, int errorCode) {
+            mLock.lock();
+            try {
+                mErredUtterances.put(utteranceId, errorCode);
+                mDone.signal();
+            } finally {
+                mLock.unlock();
+            }
+        }
+
+        @Override
+        public void onStart(String utteranceId) {
+            mLock.lock();
+            try {
+                mStartedUtterances.add(utteranceId);
+            } finally {
+                mLock.unlock();
+            }
+        }
+
+        @Override
+        public void onStop(String utteranceId, boolean isStarted) {
+            mLock.lock();
+            try {
+                mStoppedUtterances.add(utteranceId);
+                mDone.signal();
+            } finally {
+                mLock.unlock();
+            }
+        }
+
         public boolean waitForComplete(String utteranceId)
                 throws InterruptedException {
             long timeOutNanos = TimeUnit.MILLISECONDS.toNanos(TTS_INIT_MAX_WAIT_TIME);
@@ -170,6 +222,23 @@
                 mLock.unlock();
             }
         }
+
+        public boolean waitForStop(String utteranceId)
+                throws InterruptedException {
+            long timeOutNanos = TimeUnit.MILLISECONDS.toNanos(TTS_INIT_MAX_WAIT_TIME);
+            mLock.lock();
+            try {
+                while (!mStoppedUtterances.remove(utteranceId)) {
+                    if (timeOutNanos <= 0) {
+                        return false;
+                    }
+                    timeOutNanos = mDone.awaitNanos(timeOutNanos);
+                }
+                return true;
+            } finally {
+                mLock.unlock();
+            }
+        }
     }
 
     /**
diff --git a/tests/tests/systemui/Android.mk b/tests/tests/systemui/Android.mk
new file mode 100644
index 0000000..1a15fd2
--- /dev/null
+++ b/tests/tests/systemui/Android.mk
@@ -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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+# don't include this package in any target
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsSystemUiTestCases
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/systemui/AndroidManifest.xml b/tests/tests/systemui/AndroidManifest.xml
new file mode 100644
index 0000000..bf5df5b
--- /dev/null
+++ b/tests/tests/systemui/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="com.android.cts.systemui">
+    <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" />
+    <application>
+        <activity android:name=".LightStatusBarActivity"
+                android:theme="@android:style/Theme.Material.NoActionBar"></activity>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.systemui">
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/systemui/src/com/android/cts/systemui/ColorUtils.java b/tests/tests/systemui/src/com/android/cts/systemui/ColorUtils.java
new file mode 100644
index 0000000..626a179
--- /dev/null
+++ b/tests/tests/systemui/src/com/android/cts/systemui/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 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
new file mode 100644
index 0000000..3722320
--- /dev/null
+++ b/tests/tests/systemui/src/com/android/cts/systemui/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 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
new file mode 100644
index 0000000..b5bfd51
--- /dev/null
+++ b/tests/tests/systemui/src/com/android/cts/systemui/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 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
new file mode 100644
index 0000000..51d97f5
--- /dev/null
+++ b/tests/tests/telecom/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 := CtsTelecomTestCases
+
+# 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_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telecom/AndroidManifest.xml b/tests/tests/telecom/AndroidManifest.xml
new file mode 100644
index 0000000..b57e0b6
--- /dev/null
+++ b/tests/tests/telecom/AndroidManifest.xml
@@ -0,0 +1,90 @@
+<?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.telecom">
+    <uses-sdk android:minSdkVersion="21" />
+    <uses-permission android:name="android.permission.CALL_PHONE" />>
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" />
+    <uses-permission android:name="com.android.voicemail.permission.ADD_VOICEMAIL" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <service android:name="android.telecom.cts.CtsRemoteConnectionService"
+            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService" />
+            </intent-filter>
+        </service>
+
+        <service android:name="android.telecom.cts.CtsConnectionService"
+            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService" />
+            </intent-filter>
+        </service>
+
+        <service android:name="android.telecom.cts.MockInCallService"
+            android:permission="android.permission.BIND_INCALL_SERVICE" >
+            <intent-filter>
+                <action android:name="android.telecom.InCallService"/>
+            </intent-filter>
+        </service>
+
+        <activity android:name="android.telecom.cts.MockDialerActivity">
+            <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>
+            <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:scheme="voicemail" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="tel" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.telecom"
+                     android:label="CTS tests for android.telecom package">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/telecom/res/drawable/ic_phone_24dp.png b/tests/tests/telecom/res/drawable/ic_phone_24dp.png
new file mode 100644
index 0000000..b0e0205
--- /dev/null
+++ b/tests/tests/telecom/res/drawable/ic_phone_24dp.png
Binary files differ
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseRemoteTelecomTest.java b/tests/tests/telecom/src/android/telecom/cts/BaseRemoteTelecomTest.java
new file mode 100644
index 0000000..3a0dbd3
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseRemoteTelecomTest.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import android.content.ComponentName;
+import android.telecom.Connection;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.RemoteConference;
+import android.telecom.RemoteConnection;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Base class for Telecom CTS tests that require a {@link CtsConnectionService} and
+ * {@link CtsRemoteConnectionService} to verify Telecom functionality. This class
+ * extends from the {@link BaseTelecomTestWithMockServices} and should be extended
+ * for all RemoteConnection/RemoteConferencTest.
+ */
+public class BaseRemoteTelecomTest extends BaseTelecomTestWithMockServices {
+
+    public static final PhoneAccountHandle TEST_REMOTE_PHONE_ACCOUNT_HANDLE =
+            new PhoneAccountHandle(new ComponentName(PACKAGE, REMOTE_COMPONENT), REMOTE_ACCOUNT_ID);
+    public static final String TEST_REMOTE_PHONE_ACCOUNT_ADDRESS = "tel:666-TEST";
+
+    MockConnectionService remoteConnectionService = null;
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mShouldTestTelecom) {
+            tearDownRemoteConnectionService(TEST_REMOTE_PHONE_ACCOUNT_HANDLE);
+        }
+        super.tearDown();
+    }
+
+    protected void setupConnectionServices(MockConnectionService connectionService,
+            MockConnectionService remoteConnectionService, int flags) throws Exception {
+        // Setup the primary connection service first
+        setupConnectionService(connectionService, flags);
+        setupRemoteConnectionService(remoteConnectionService, flags);
+    }
+
+    protected void setupRemoteConnectionService(MockConnectionService remoteConnectionService,
+            int flags) throws Exception {
+        if (remoteConnectionService != null) {
+            this.remoteConnectionService = remoteConnectionService;
+        } else {
+            // Generate a vanilla mock connection service, if not provided.
+            this.remoteConnectionService = new MockConnectionService();
+        }
+        CtsRemoteConnectionService.setUp(TEST_REMOTE_PHONE_ACCOUNT_HANDLE,
+                this.remoteConnectionService);
+
+        if ((flags & FLAG_REGISTER) != 0) {
+            // This needs SIM subscription, so register via adb commands to get system permission.
+            TestUtils.registerSimPhoneAccount(getInstrumentation(),
+                    TEST_REMOTE_PHONE_ACCOUNT_HANDLE,
+                    REMOTE_ACCOUNT_LABEL,
+                    TEST_REMOTE_PHONE_ACCOUNT_ADDRESS);
+            // Wait till the adb commands have executed and account is in Telecom database.
+            assertPhoneAccountRegistered(TEST_REMOTE_PHONE_ACCOUNT_HANDLE);
+        }
+        if ((flags & FLAG_ENABLE) != 0) {
+            TestUtils.enablePhoneAccount(getInstrumentation(), TEST_REMOTE_PHONE_ACCOUNT_HANDLE);
+            // Wait till the adb commands have executed and account is enabled in Telecom database.
+            assertPhoneAccountEnabled(TEST_REMOTE_PHONE_ACCOUNT_HANDLE);
+        }
+    }
+
+    protected void tearDownRemoteConnectionService(PhoneAccountHandle remoteAccountHandle)
+            throws Exception {
+        assertNumConnections(this.remoteConnectionService, 0);
+        mTelecomManager.unregisterPhoneAccount(remoteAccountHandle);
+        CtsRemoteConnectionService.tearDown();
+        //Telecom doesn't unbind the remote connection service at the end of all calls today.
+        //assertCtsRemoteConnectionServiceUnbound();
+        this.remoteConnectionService = null;
+    }
+
+    MockConnection verifyConnectionForOutgoingCallOnRemoteCS() {
+        // Assuming only 1 connection present
+        return verifyConnectionForOutgoingCallOnRemoteCS(0);
+    }
+
+    MockConnection verifyConnectionForOutgoingCallOnRemoteCS(int connectionIndex) {
+        try {
+            if (!remoteConnectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                    TimeUnit.MILLISECONDS)) {
+                fail("No outgoing call connection requested by Telecom");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+
+        assertThat("Telecom should create outgoing connection for remote outgoing call",
+                remoteConnectionService.outgoingConnections.size(), not(equalTo(0)));
+        assertEquals("Telecom should not create incoming connections for remote outgoing calls",
+                0, remoteConnectionService.incomingConnections.size());
+        MockConnection connection = remoteConnectionService.outgoingConnections.get(connectionIndex);
+        return connection;
+    }
+
+    MockConnection verifyConnectionForIncomingCallOnRemoteCS() {
+        // Assuming only 1 connection present
+        return verifyConnectionForIncomingCallOnRemoteCS(0);
+    }
+
+    MockConnection verifyConnectionForIncomingCallOnRemoteCS(int connectionIndex) {
+        try {
+            if (!remoteConnectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                    TimeUnit.MILLISECONDS)) {
+                fail("No outgoing call connection requested by Telecom");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+
+        assertThat("Telecom should create incoming connections for remote incoming calls",
+                remoteConnectionService.incomingConnections.size(), not(equalTo(0)));
+        assertEquals("Telecom should not create outgoing connections for remote incoming calls",
+                0, remoteConnectionService.outgoingConnections.size());
+        MockConnection connection = remoteConnectionService.incomingConnections.get(connectionIndex);
+        setAndVerifyConnectionForIncomingCall(connection);
+        return connection;
+    }
+
+    void setAndVerifyConferenceablesForOutgoingConnectionOnRemoteCS(int connectionIndex) {
+        assertEquals("Lock should have no permits!", 0, mInCallCallbacks.lock.availablePermits());
+        /**
+         * Set the conferenceable connections on the given connection and it's remote connection
+         * counterpart.
+         */
+        // Make all other outgoing connections as conferenceable with this remote connection.
+        MockConnection connection = remoteConnectionService.outgoingConnections.get(connectionIndex);
+        List<Connection> confConnections =
+                new ArrayList<>(remoteConnectionService.outgoingConnections.size());
+        for (Connection c : remoteConnectionService.outgoingConnections) {
+            if (c != connection) {
+                confConnections.add(c);
+            }
+        }
+        connection.setConferenceableConnections(confConnections);
+        assertEquals(connection.getConferenceables(), confConnections);
+    }
+
+    MockConference verifyConferenceForOutgoingCallOnRemoteCS() {
+        try {
+            if (!remoteConnectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                    TimeUnit.MILLISECONDS)) {
+                fail("No outgoing conference requested by Telecom");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+        // Return the newly created conference object to the caller
+        MockConference conference = remoteConnectionService.conferences.get(0);
+        setAndVerifyConferenceForOutgoingCall(conference);
+        return conference;
+    }
+
+    void assertRemoteConnectionState(final RemoteConnection connection, final int state) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return state;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return connection.getState();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Remote Connection should be in state " + state
+        );
+    }
+
+    void assertRemoteConferenceState(final RemoteConference conference, final int state) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return state;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return conference.getState();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Remote Conference should be in state " + state
+        );
+    }
+
+    void assertCtsRemoteConnectionServiceUnbound() {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected(){
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return CtsRemoteConnectionService.isServiceUnbound();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "CtsRemoteConnectionService not yet unbound!"
+        );
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
new file mode 100644
index 0000000..8bb3cc1
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/BaseTelecomTestWithMockServices.java
@@ -0,0 +1,955 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.telecom.Call;
+import android.telecom.CallAudioState;
+import android.telecom.Conference;
+import android.telecom.Connection;
+import android.telecom.InCallService;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+import android.telecom.cts.MockInCallService.InCallServiceCallbacks;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Base class for Telecom CTS tests that require a {@link CtsConnectionService} and
+ * {@link MockInCallService} to verify Telecom functionality.
+ */
+public class BaseTelecomTestWithMockServices extends InstrumentationTestCase {
+
+    public static final int FLAG_REGISTER = 0x1;
+    public static final int FLAG_ENABLE = 0x2;
+
+    public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE =
+            new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID);
+
+    public static final PhoneAccount TEST_PHONE_ACCOUNT = PhoneAccount.builder(
+            TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+            .setAddress(Uri.parse("tel:555-TEST"))
+            .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
+            .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+                    PhoneAccount.CAPABILITY_VIDEO_CALLING |
+                    PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
+            .setHighlightColor(Color.RED)
+            .setShortDescription(ACCOUNT_LABEL)
+            .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
+            .addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
+            .build();
+
+    private static int sCounter = 9999;
+
+    Context mContext;
+    TelecomManager mTelecomManager;
+
+    InvokeCounter mOnBringToForegroundCounter;
+    InvokeCounter mOnCallAudioStateChangedCounter;
+    InvokeCounter mOnPostDialWaitCounter;
+    InvokeCounter mOnCannedTextResponsesLoadedCounter;
+
+    InCallServiceCallbacks mInCallCallbacks;
+    String mPreviousDefaultDialer = null;
+    MockConnectionService connectionService = null;
+
+    boolean mShouldTestTelecom = true;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+
+        mShouldTestTelecom = shouldTestTelecom(mContext);
+        if (mShouldTestTelecom) {
+            mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation());
+            TestUtils.setDefaultDialer(getInstrumentation(), PACKAGE);
+            setupCallbacks();
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mShouldTestTelecom) {
+            cleanupCalls();
+            if (!TextUtils.isEmpty(mPreviousDefaultDialer)) {
+                TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer);
+            }
+            tearDownConnectionService(TEST_PHONE_ACCOUNT_HANDLE);
+            assertMockInCallServiceUnbound();
+        }
+        super.tearDown();
+    }
+
+    protected PhoneAccount setupConnectionService(MockConnectionService connectionService,
+            int flags) throws Exception {
+        if (connectionService != null) {
+            this.connectionService = connectionService;
+        } else {
+            // Generate a vanilla mock connection service, if not provided.
+            this.connectionService = new MockConnectionService();
+        }
+        CtsConnectionService.setUp(TEST_PHONE_ACCOUNT_HANDLE, this.connectionService);
+
+        if ((flags & FLAG_REGISTER) != 0) {
+            mTelecomManager.registerPhoneAccount(TEST_PHONE_ACCOUNT);
+        }
+        if ((flags & FLAG_ENABLE) != 0) {
+            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);
+        }
+
+        return TEST_PHONE_ACCOUNT;
+    }
+
+    protected void tearDownConnectionService(PhoneAccountHandle accountHandle) throws Exception {
+        assertNumConnections(this.connectionService, 0);
+        mTelecomManager.unregisterPhoneAccount(accountHandle);
+        CtsConnectionService.tearDown();
+        assertCtsConnectionServiceUnbound();
+        this.connectionService = null;
+    }
+
+    protected void startCallTo(Uri address, PhoneAccountHandle accountHandle) {
+        final Intent intent = new Intent(Intent.ACTION_CALL, address);
+        if (accountHandle != null) {
+            intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
+        }
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        mContext.startActivity(intent);
+    }
+
+    private void sleep(long ms) {
+        try {
+            Thread.sleep(ms);
+        } catch (InterruptedException e) {
+        }
+    }
+
+    private void setupCallbacks() {
+        mInCallCallbacks = new InCallServiceCallbacks() {
+            @Override
+            public void onCallAdded(Call call, int numCalls) {
+                Log.i(TAG, "onCallAdded, Call: " + call + ", Num Calls: " + numCalls);
+                this.lock.release();
+            }
+            @Override
+            public void onCallRemoved(Call call, int numCalls) {
+                Log.i(TAG, "onCallRemoved, Call: " + call + ", Num Calls: " + numCalls);
+            }
+            @Override
+            public void onParentChanged(Call call, Call parent) {
+                Log.i(TAG, "onParentChanged, Call: " + call + ", Parent: " + parent);
+                this.lock.release();
+            }
+            @Override
+            public void onChildrenChanged(Call call, List<Call> children) {
+                Log.i(TAG, "onChildrenChanged, Call: " + call + "Children: " + children);
+                this.lock.release();
+            }
+            @Override
+            public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {
+                Log.i(TAG, "onConferenceableCallsChanged, Call: " + call + ", Conferenceables: " +
+                        conferenceableCalls);
+            }
+            @Override
+            public void onDetailsChanged(Call call, Call.Details details) {
+                Log.i(TAG, "onDetailsChanged, Call: " + call + ", Details: " + details);
+            }
+            @Override
+            public void onCallDestroyed(Call call) {
+                Log.i(TAG, "onCallDestroyed, Call: " + call);
+            }
+            @Override
+            public void onCallStateChanged(Call call, int newState) {
+                Log.i(TAG, "onCallStateChanged, Call: " + call + ", New State: " + newState);
+            }
+            @Override
+            public void onBringToForeground(boolean showDialpad) {
+                mOnBringToForegroundCounter.invoke(showDialpad);
+            }
+            @Override
+            public void onCallAudioStateChanged(CallAudioState audioState) {
+                Log.i(TAG, "onCallAudioStateChanged, audioState: " + audioState);
+                mOnCallAudioStateChangedCounter.invoke(audioState);
+            }
+            @Override
+            public void onPostDialWait(Call call, String remainingPostDialSequence) {
+                mOnPostDialWaitCounter.invoke(call, remainingPostDialSequence);
+            }
+            @Override
+            public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {
+                mOnCannedTextResponsesLoadedCounter.invoke(call, cannedTextResponses);
+            }
+        };
+
+        MockInCallService.setCallbacks(mInCallCallbacks);
+
+        // TODO: If more InvokeCounters are added in the future, consider consolidating them into a
+        // single Collection.
+        mOnBringToForegroundCounter = new InvokeCounter("OnBringToForeground");
+        mOnCallAudioStateChangedCounter = new InvokeCounter("OnCallAudioStateChanged");
+        mOnPostDialWaitCounter = new InvokeCounter("OnPostDialWait");
+        mOnCannedTextResponsesLoadedCounter = new InvokeCounter("OnCannedTextResponsesLoaded");
+    }
+
+    /**
+     * Puts Telecom in a state where there is an incoming call provided by the
+     * {@link CtsConnectionService} which can be tested.
+     */
+    void addAndVerifyNewIncomingCall(Uri incomingHandle, Bundle extras) {
+        assertEquals("Lock should have no permits!", 0, mInCallCallbacks.lock.availablePermits());
+        int currentCallCount = 0;
+        if (mInCallCallbacks.getService() != null) {
+            currentCallCount = mInCallCallbacks.getService().getCallCount();
+        }
+
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, incomingHandle);
+        mTelecomManager.addNewIncomingCall(TEST_PHONE_ACCOUNT_HANDLE, extras);
+
+        try {
+            if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+                        TimeUnit.SECONDS)) {
+                fail("No call added to InCallService.");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+
+        assertEquals("InCallService should contain 1 more call after adding a call.",
+                currentCallCount + 1,
+                mInCallCallbacks.getService().getCallCount());
+    }
+
+    /**
+     *  Puts Telecom in a state where there is an active call provided by the
+     *  {@link CtsConnectionService} which can be tested.
+     */
+    void placeAndVerifyCall() {
+        placeAndVerifyCall(null);
+    }
+
+    /**
+     *  Puts Telecom in a state where there is an active call provided by the
+     *  {@link CtsConnectionService} which can be tested.
+     *
+     *  @param videoState the video state of the call.
+     */
+    void placeAndVerifyCall(int videoState) {
+        placeAndVerifyCall(null, videoState);
+    }
+
+    /**
+     *  Puts Telecom in a state where there is an active call provided by the
+     *  {@link CtsConnectionService} which can be tested.
+     */
+    void placeAndVerifyCall(Bundle extras) {
+        placeAndVerifyCall(extras, VideoProfile.STATE_AUDIO_ONLY);
+    }
+
+    /**
+     *  Puts Telecom in a state where there is an active call provided by the
+     *  {@link CtsConnectionService} which can be tested.
+     */
+    void placeAndVerifyCall(Bundle extras, int videoState) {
+        assertEquals("Lock should have no permits!", 0, mInCallCallbacks.lock.availablePermits());
+        int currentCallCount = 0;
+        if (mInCallCallbacks.getService() != null) {
+            currentCallCount = mInCallCallbacks.getService().getCallCount();
+        }
+        placeNewCallWithPhoneAccount(extras, videoState);
+
+        try {
+            if (!mInCallCallbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+                        TimeUnit.SECONDS)) {
+                fail("No call added to InCallService.");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+
+        assertEquals("InCallService should contain 1 more call after adding a call.",
+                currentCallCount + 1,
+                mInCallCallbacks.getService().getCallCount());
+    }
+
+    MockConnection verifyConnectionForOutgoingCall() {
+        // Assuming only 1 connection present
+        return verifyConnectionForOutgoingCall(0);
+    }
+
+    MockConnection verifyConnectionForOutgoingCall(int connectionIndex) {
+        try {
+            if (!connectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                    TimeUnit.MILLISECONDS)) {
+                fail("No outgoing call connection requested by Telecom");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+
+        assertThat("Telecom should create outgoing connection for outgoing call",
+                connectionService.outgoingConnections.size(), not(equalTo(0)));
+        MockConnection connection = connectionService.outgoingConnections.get(connectionIndex);
+        return connection;
+    }
+
+    MockConnection verifyConnectionForIncomingCall() {
+        // Assuming only 1 connection present
+        return verifyConnectionForIncomingCall(0);
+    }
+
+    MockConnection verifyConnectionForIncomingCall(int connectionIndex) {
+        try {
+            if (!connectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                    TimeUnit.MILLISECONDS)) {
+                fail("No outgoing call connection requested by Telecom");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+
+        assertThat("Telecom should create incoming connections for incoming calls",
+                connectionService.incomingConnections.size(), not(equalTo(0)));
+        MockConnection connection = connectionService.incomingConnections.get(connectionIndex);
+        setAndVerifyConnectionForIncomingCall(connection);
+        return connection;
+    }
+
+    void setAndVerifyConnectionForIncomingCall(MockConnection connection) {
+        connection.setRinging();
+        assertConnectionState(connection, Connection.STATE_RINGING);
+    }
+
+    void setAndVerifyConferenceablesForOutgoingConnection(int connectionIndex) {
+        assertEquals("Lock should have no permits!", 0, mInCallCallbacks.lock.availablePermits());
+        // Make all other outgoing connections as conferenceable with this connection.
+        MockConnection connection = connectionService.outgoingConnections.get(connectionIndex);
+        List<Connection> confConnections =
+                new ArrayList<>(connectionService.outgoingConnections.size());
+        for (Connection c : connectionService.outgoingConnections) {
+            if (c != connection) {
+                confConnections.add(c);
+            }
+        }
+        connection.setConferenceableConnections(confConnections);
+        assertEquals(connection.getConferenceables(), confConnections);
+    }
+
+    void addConferenceCall(Call call1, Call call2) {
+        assertEquals("Lock should have no permits!", 0, mInCallCallbacks.lock.availablePermits());
+        int currentConfCallCount = 0;
+        if (mInCallCallbacks.getService() != null) {
+            currentConfCallCount = mInCallCallbacks.getService().getConferenceCallCount();
+        }
+        // Verify that the calls have each other on their conferenceable list before proceeding
+        List<Call> callConfList = new ArrayList<>();
+        callConfList.add(call2);
+        assertCallConferenceableList(call1, callConfList);
+
+        callConfList.clear();
+        callConfList.add(call1);
+        assertCallConferenceableList(call2, callConfList);
+
+        call1.conference(call2);
+
+        /**
+         * We should have 1 onCallAdded, 2 onChildrenChanged and 2 onParentChanged invoked, so
+         * we should have 5 available permits on the incallService lock.
+         */
+        try {
+            if (!mInCallCallbacks.lock.tryAcquire(5, 3, TimeUnit.SECONDS)) {
+                fail("Conference addition failed.");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+
+        assertEquals("InCallService should contain 1 more call after adding a conf call.",
+                currentConfCallCount + 1,
+                mInCallCallbacks.getService().getConferenceCallCount());
+    }
+
+    void splitFromConferenceCall(Call call1) {
+        assertEquals("Lock should have no permits!", 0, mInCallCallbacks.lock.availablePermits());
+
+        call1.splitFromConference();
+        /**
+         * We should have 1 onChildrenChanged and 1 onParentChanged invoked, so
+         * we should have 2 available permits on the incallService lock.
+         */
+        try {
+            if (!mInCallCallbacks.lock.tryAcquire(2, 3, TimeUnit.SECONDS)) {
+                fail("Conference split failed");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+    }
+
+    MockConference verifyConferenceForOutgoingCall() {
+        try {
+            if (!connectionService.lock.tryAcquire(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                    TimeUnit.MILLISECONDS)) {
+                fail("No outgoing conference requested by Telecom");
+            }
+        } catch (InterruptedException e) {
+            Log.i(TAG, "Test interrupted!");
+        }
+        // Return the newly created conference object to the caller
+        MockConference conference = connectionService.conferences.get(0);
+        setAndVerifyConferenceForOutgoingCall(conference);
+        return conference;
+    }
+
+    void setAndVerifyConferenceForOutgoingCall(MockConference conference) {
+        conference.setActive();
+        assertConferenceState(conference, Connection.STATE_ACTIVE);
+    }
+
+    /**
+     * Disconnect the created test call and verify that Telecom has cleared all calls.
+     */
+    void cleanupCalls() {
+        if (mInCallCallbacks != null && mInCallCallbacks.getService() != null) {
+            mInCallCallbacks.getService().disconnectAllConferenceCalls();
+            mInCallCallbacks.getService().disconnectAllCalls();
+            assertNumConferenceCalls(mInCallCallbacks.getService(), 0);
+            assertNumCalls(mInCallCallbacks.getService(), 0);
+        }
+    }
+
+    /**
+     * Place a new outgoing call via the {@link CtsConnectionService}
+     */
+    private void placeNewCallWithPhoneAccount(Bundle extras, int videoState) {
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, TEST_PHONE_ACCOUNT_HANDLE);
+
+        if (!VideoProfile.isAudioOnly(videoState)) {
+            extras.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, videoState);
+        }
+
+        mTelecomManager.placeCall(createTestNumber(), extras);
+    }
+
+    /**
+     * Create a new number each time for a new test. Telecom has special logic to reuse certain
+     * calls if multiple calls to the same number are placed within a short period of time which
+     * can cause certain tests to fail.
+     */
+    Uri createTestNumber() {
+        return Uri.fromParts("tel", String.valueOf(++sCounter), null);
+    }
+
+    public static Uri getTestNumber() {
+        return Uri.fromParts("tel", String.valueOf(sCounter), null);
+    }
+
+    void assertNumCalls(final MockInCallService inCallService, final int numCalls) {
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+            @Override
+            public Object expected() {
+                return numCalls;
+            }
+            @Override
+            public Object actual() {
+                return inCallService.getCallCount();
+            }
+        },
+        WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+        "InCallService should contain " + numCalls + " calls."
+    );
+    }
+
+    void assertNumConferenceCalls(final MockInCallService inCallService, final int numCalls) {
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+            @Override
+            public Object expected() {
+                return numCalls;
+            }
+            @Override
+            public Object actual() {
+                return inCallService.getConferenceCallCount();
+            }
+        },
+        WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+        "InCallService should contain " + numCalls + " conference calls."
+    );
+    }
+
+
+    void assertNumConnections(final MockConnectionService connService, final int numConnections) {
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+                                              @Override
+                                              public Object expected() {
+                                                  return numConnections;
+                                              }
+                                              @Override
+                                              public Object actual() {
+                                                  return connService.getAllConnections().size();
+                                              }
+                                          },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "ConnectionService should contain " + numConnections + " connections."
+        );
+    }
+
+    void assertMuteState(final InCallService incallService, final boolean isMuted) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return isMuted;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        final CallAudioState state = incallService.getCallAudioState();
+                        return state == null ? null : state.isMuted();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Phone's mute state should be: " + isMuted
+        );
+    }
+
+    void assertMuteState(final MockConnection connection, final boolean isMuted) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return isMuted;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        final CallAudioState state = connection.getCallAudioState();
+                        return state == null ? null : state.isMuted();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Connection's mute state should be: " + isMuted
+        );
+    }
+
+    void assertAudioRoute(final InCallService incallService, final int route) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return route;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        final CallAudioState state = incallService.getCallAudioState();
+                        return state == null ? null : state.getRoute();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Phone's audio route should be: " + route
+        );
+    }
+
+    void assertNotAudioRoute(final InCallService incallService, final int route) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return new Boolean(true);
+                    }
+
+                    @Override
+                    public Object actual() {
+                        final CallAudioState state = incallService.getCallAudioState();
+                        return route != state.getRoute();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Phone's audio route should not be: " + route
+        );
+    }
+
+    void assertAudioRoute(final MockConnection connection, final int route) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return route;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        final CallAudioState state = ((Connection) connection).getCallAudioState();
+                        return state == null ? null : state.getRoute();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Connection's audio route should be: " + route
+        );
+    }
+
+    void assertConnectionState(final Connection connection, final int state) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return state;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return connection.getState();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Connection should be in state " + state
+        );
+    }
+
+    void assertCallState(final Call call, final int state) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return state;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getState();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call: " + call + " should be in state " + state
+        );
+    }
+
+    void assertCallConferenceableList(final Call call, final List<Call> conferenceableList) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return conferenceableList;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getConferenceableCalls();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call: " + call + " does not have the correct conferenceable call list."
+        );
+    }
+
+    void assertDtmfString(final MockConnection connection, final String dtmfString) {
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+                @Override
+                public Object expected() {
+                    return dtmfString;
+                }
+
+                @Override
+                public Object actual() {
+                    return connection.getDtmfString();
+                }
+            },
+            WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+            "DTMF string should be equivalent to entered DTMF characters: " + dtmfString
+        );
+    }
+
+    void assertDtmfString(final MockConference conference, final String dtmfString) {
+        waitUntilConditionIsTrueOrTimeout(new Condition() {
+                @Override
+                public Object expected() {
+                    return dtmfString;
+                }
+
+                @Override
+                public Object actual() {
+                    return conference.getDtmfString();
+                }
+            },
+            WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+            "DTMF string should be equivalent to entered DTMF characters: " + dtmfString
+        );
+    }
+
+    void assertCallDisplayName(final Call call, final String name) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return name;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getDetails().getCallerDisplayName();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should have display name: " + name
+        );
+    }
+
+    void assertConnectionCallDisplayName(final Connection connection, final String name) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return name;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return connection.getCallerDisplayName();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Connection should have display name: " + name
+        );
+    }
+
+    void assertConferenceState(final Conference conference, final int state) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return state;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return conference.getState();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Conference should be in state " + state
+        );
+    }
+
+    void assertPhoneAccountRegistered(final PhoneAccountHandle handle) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return mTelecomManager.getPhoneAccount(handle) != null;
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Phone account registration failed for " + handle
+        );
+    }
+
+    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());
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Phone account enable failed for " + handle
+        );
+    }
+
+    void assertCtsConnectionServiceUnbound() {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return CtsConnectionService.isServiceUnbound();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "CtsConnectionService not yet unbound!"
+        );
+    }
+
+    void assertMockInCallServiceUnbound() {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return MockInCallService.isServiceUnbound();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "MockInCallService not yet unbound!"
+        );
+    }
+
+    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());
+    }
+
+    /**
+     * Performs some work, and waits for the condition to be met.  If the condition is not met in
+     * each step of the loop, the work is performed again.
+     *
+     * @param work The work to perform.
+     * @param condition The condition.
+     * @param timeout The timeout.
+     * @param description Description of the work being performed.
+     */
+    void doWorkAndWaitUntilConditionIsTrueOrTimeout(Work work, Condition condition, long timeout,
+            String description) {
+        final long start = System.currentTimeMillis();
+        work.doWork();
+        while (!condition.expected().equals(condition.actual())
+                && System.currentTimeMillis() - start < timeout) {
+            sleep(50);
+            work.doWork();
+        }
+        assertEquals(description, condition.expected(), condition.actual());
+    }
+
+    protected interface Condition {
+        Object expected();
+        Object actual();
+    }
+
+    protected interface Work {
+        void doWork();
+    }
+
+    /**
+     * Utility class used to track the number of times a callback was invoked, and the arguments it
+     * was invoked with. This class is prefixed Invoke rather than the more typical Call for
+     * disambiguation purposes.
+     */
+    protected static final class InvokeCounter {
+        private final String mName;
+        private final Object mLock = new Object();
+        private final ArrayList<Object[]> mInvokeArgs = new ArrayList<>();
+
+        private int mInvokeCount;
+
+        public InvokeCounter(String callbackName) {
+            mName = callbackName;
+        }
+
+        public void invoke(Object... args) {
+            synchronized (mLock) {
+                mInvokeCount++;
+                mInvokeArgs.add(args);
+                mLock.notifyAll();
+            }
+        }
+
+        public Object[] getArgs(int index) {
+            synchronized (mLock) {
+                return mInvokeArgs.get(index);
+            }
+        }
+
+        public int getInvokeCount() {
+            synchronized (mLock) {
+                return mInvokeCount;
+            }
+        }
+
+        public void waitForCount(int count) {
+            waitForCount(count, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        }
+
+        public void waitForCount(int count, long timeoutMillis) {
+            waitForCount(count, timeoutMillis, null);
+        }
+
+        public void waitForCount(int count, long timeoutMillis, String message) {
+            synchronized (mLock) {
+                final long startTimeMillis = SystemClock.uptimeMillis();
+                while (mInvokeCount < count) {
+                    try {
+                        final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
+                        final long remainingTimeMillis = timeoutMillis - elapsedTimeMillis;
+                        if (remainingTimeMillis <= 0) {
+                            if (message != null) {
+                                fail(message);
+                            } else {
+                                fail(String.format("Expected %s to be called %d times.", mName,
+                                        count));
+                            }
+                        }
+                        mLock.wait(timeoutMillis);
+                    } catch (InterruptedException ie) {
+                        /* ignore */
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.java
new file mode 100644
index 0000000..eda193d
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/BasicInCallServiceTest.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.telecom.cts;
+
+import static android.telecom.cts.TestUtils.shouldTestTelecom;
+
+import android.telecom.cts.MockInCallService.InCallServiceCallbacks;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.telecom.Call;
+import android.telecom.InCallService;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Sanity test that adding a new call via the CALL intent works correctly.
+ */
+public class BasicInCallServiceTest extends InstrumentationTestCase {
+
+    private static final Uri TEST_NUMBER = Uri.fromParts("tel", "7", null);
+
+    private Context mContext;
+    private String mPreviousDefaultDialer = null;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation());
+        TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!TextUtils.isEmpty(mPreviousDefaultDialer)) {
+            TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer);
+        }
+        super.tearDown();
+    }
+
+    /**
+     * Tests that when sending a CALL intent via the Telecom -> Telephony stack, Telecom
+     * binds to the registered {@link InCallService}s and adds a new call. This test will
+     * actually place a phone call to the number 7. It should still pass even if there is no
+     * SIM card inserted.
+     */
+    public void testTelephonyCall_bindsToInCallServiceAndAddsCall() {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+
+        final Intent intent = new Intent(Intent.ACTION_CALL, TEST_NUMBER);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+
+        final InCallServiceCallbacks callbacks = createCallbacks();
+
+        MockInCallService.setCallbacks(callbacks);
+
+        mContext.startActivity(intent);
+
+        try {
+            if (callbacks.lock.tryAcquire(TestUtils.WAIT_FOR_CALL_ADDED_TIMEOUT_S,
+                        TimeUnit.SECONDS)) {
+                return;
+            }
+        } catch (InterruptedException e) {
+        }
+
+        fail("No call added to InCallService.");
+    }
+
+    private MockInCallService.InCallServiceCallbacks createCallbacks() {
+        final InCallServiceCallbacks callbacks = new InCallServiceCallbacks() {
+            @Override
+            public void onCallAdded(Call call, int numCalls) {
+                assertEquals("InCallService should have 1 call after adding call", 1, numCalls);
+                call.disconnect();
+                lock.release();
+            }
+        };
+        return callbacks;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
new file mode 100644
index 0000000..879c995
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/CallDetailsTest.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import android.graphics.drawable.Icon;
+import android.os.Bundle;
+import android.net.Uri;
+import android.telecom.Call;
+import android.telecom.Connection;
+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 com.android.cts.telecom.R;
+
+/**
+ * Suites of tests that verifies the various Call details.
+ */
+public class CallDetailsTest extends BaseTelecomTestWithMockServices {
+
+    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;
+    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;
+
+    private StatusHints mStatusHints;
+    private Bundle mExtras = new Bundle();
+
+    private MockInCallService mInCallService;
+    private Call mCall;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mShouldTestTelecom) {
+            PhoneAccount account = setupConnectionService(
+                    new MockConnectionService() {
+                        @Override
+                        public Connection onCreateOutgoingConnection(
+                                PhoneAccountHandle connectionManagerPhoneAccount,
+                                ConnectionRequest request) {
+                            Connection connection = super.onCreateOutgoingConnection(
+                                    connectionManagerPhoneAccount,
+                                    request);
+                            // Modify the connection object created with local values.
+                            connection.setConnectionCapabilities(CONNECTION_CAPABILITIES);
+                            connection.setCallerDisplayName(
+                                    CALLER_DISPLAY_NAME,
+                                    CALLER_DISPLAY_NAME_PRESENTATION);
+                            connection.setExtras(mExtras);
+                            mStatusHints = new StatusHints(
+                                    "CTS test",
+                                    Icon.createWithResource(
+                                            getInstrumentation().getContext(),
+                                            R.drawable.ic_phone_24dp),
+                                            null);
+                            connection.setStatusHints(mStatusHints);
+                            lock.release();
+                            return connection;
+                        }
+                    }, FLAG_REGISTER | FLAG_ENABLE);
+
+            /** Place a call as a part of the setup before we test the various
+             *  Call details.
+             */
+            placeAndVerifyCall();
+            verifyConnectionForOutgoingCall();
+
+            mInCallService = mInCallCallbacks.getService();
+            mCall = mInCallService.getLastCall();
+
+            assertCallState(mCall, Call.STATE_DIALING);
+        }
+    }
+
+    /**
+     * Tests whether the getAccountHandle() getter returns the correct object.
+     */
+    public void testAccountHandle() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getAccountHandle(), is(PhoneAccountHandle.class));
+        assertEquals(TEST_PHONE_ACCOUNT_HANDLE, mCall.getDetails().getAccountHandle());
+    }
+
+    /**
+     * Tests whether the getCallCapabilities() getter returns the correct object.
+     */
+    public void testCallCapabilities() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getCallCapabilities(), is(Integer.class));
+        assertEquals(CALL_CAPABILITIES, mCall.getDetails().getCallCapabilities());
+        assertTrue(mCall.getDetails().can(Call.Details.CAPABILITY_HOLD));
+        assertTrue(mCall.getDetails().can(Call.Details.CAPABILITY_MUTE));
+        assertFalse(mCall.getDetails().can(Call.Details.CAPABILITY_MANAGE_CONFERENCE));
+        assertFalse(mCall.getDetails().can(Call.Details.CAPABILITY_RESPOND_VIA_TEXT));
+    }
+
+    /**
+     * Tests whether the getCallerDisplayName() getter returns the correct object.
+     */
+    public void testCallerDisplayName() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getCallerDisplayName(), is(String.class));
+        assertEquals(CALLER_DISPLAY_NAME, mCall.getDetails().getCallerDisplayName());
+    }
+
+    /**
+     * Tests whether the getCallerDisplayNamePresentation() getter returns the correct object.
+     */
+    public void testCallerDisplayNamePresentation() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getCallerDisplayNamePresentation(), is(Integer.class));
+        assertEquals(CALLER_DISPLAY_NAME_PRESENTATION, mCall.getDetails().getCallerDisplayNamePresentation());
+    }
+
+    /**
+     * Tests whether the getCallProperties() getter returns the correct object.
+     */
+    public void testCallProperties() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getCallProperties(), is(Integer.class));
+        assertEquals(CALL_PROPERTIES, mCall.getDetails().getCallProperties());
+    }
+
+    /**
+     * Tests whether the getConnectTimeMillis() getter returns the correct object.
+     */
+    public void testConnectTimeMillis() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getConnectTimeMillis(), is(Long.class));
+    }
+
+    /**
+     * Tests whether the getDisconnectCause() getter returns the correct object.
+     */
+    public void testDisconnectCause() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getDisconnectCause(), is(DisconnectCause.class));
+    }
+
+    /**
+     * Tests whether the getExtras() getter returns the correct object.
+     */
+    public void testExtras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        if (mCall.getDetails().getExtras() != null) {
+            assertThat(mCall.getDetails().getExtras(), is(Bundle.class));
+        }
+    }
+
+    /**
+     * Tests whether the getIntentExtras() getter returns the correct object.
+     */
+    public void testIntentExtras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getIntentExtras(), is(Bundle.class));
+    }
+
+    /**
+     * Tests whether the getGatewayInfo() getter returns the correct object.
+     */
+    public void testGatewayInfo() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        if (mCall.getDetails().getGatewayInfo() != null) {
+            assertThat(mCall.getDetails().getGatewayInfo(), is(GatewayInfo.class));
+        }
+    }
+
+    /**
+     * Tests whether the getHandle() getter returns the correct object.
+     */
+    public void testHandle() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getHandle(), is(Uri.class));
+        assertEquals(getTestNumber(), mCall.getDetails().getHandle());
+    }
+
+    /**
+     * Tests whether the getHandlePresentation() getter returns the correct object.
+     */
+    public void testHandlePresentation() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getHandlePresentation(), is(Integer.class));
+        assertEquals(MockConnectionService.CONNECTION_PRESENTATION, mCall.getDetails().getHandlePresentation());
+    }
+
+    /**
+     * Tests whether the getStatusHints() getter returns the correct object.
+     */
+    public void testStatusHints() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getStatusHints(), is(StatusHints.class));
+        assertEquals(mStatusHints.getLabel(), mCall.getDetails().getStatusHints().getLabel());
+        assertEquals(
+                mStatusHints.getIcon().toString(),
+                mCall.getDetails().getStatusHints().getIcon().toString());
+        assertEquals(mStatusHints.getExtras(), mCall.getDetails().getStatusHints().getExtras());
+    }
+
+    /**
+     * Tests whether the getVideoState() getter returns the correct object.
+     */
+    public void testVideoState() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        assertThat(mCall.getDetails().getVideoState(), is(Integer.class));
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/CallTest.java b/tests/tests/telecom/src/android/telecom/cts/CallTest.java
new file mode 100644
index 0000000..efbb69f
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/CallTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Call.Details.*;
+
+import android.telecom.Call;
+import android.test.AndroidTestCase;
+
+public class CallTest extends AndroidTestCase {
+
+    public void testCapabilitiesCan() {
+        assertTrue(Call.Details.can(CAPABILITY_HOLD, CAPABILITY_HOLD));
+        assertTrue(Call.Details.can(CAPABILITY_MUTE, CAPABILITY_MUTE));
+        assertTrue(Call.Details.can(CAPABILITY_HOLD | CAPABILITY_DISCONNECT_FROM_CONFERENCE,
+                CAPABILITY_HOLD));
+        assertTrue(Call.Details.can(CAPABILITY_MERGE_CONFERENCE
+                | CAPABILITY_DISCONNECT_FROM_CONFERENCE | CAPABILITY_MUTE,
+                CAPABILITY_MUTE));
+
+        assertFalse(Call.Details.can(CAPABILITY_MUTE, CAPABILITY_HOLD));
+        assertFalse(Call.Details.can(CAPABILITY_MERGE_CONFERENCE
+                | CAPABILITY_DISCONNECT_FROM_CONFERENCE | CAPABILITY_MUTE,
+                CAPABILITY_HOLD));
+    }
+
+    public void testCapabilitiesToString() {
+        assertEquals("[Capabilities: CAPABILITY_HOLD]",
+                Call.Details.capabilitiesToString(CAPABILITY_HOLD));
+        assertEquals("[Capabilities: CAPABILITY_SUPPORT_HOLD]",
+                Call.Details.capabilitiesToString(CAPABILITY_SUPPORT_HOLD));
+        assertEquals("[Capabilities: CAPABILITY_MERGE_CONFERENCE]",
+                Call.Details.capabilitiesToString(CAPABILITY_MERGE_CONFERENCE));
+        assertEquals("[Capabilities: CAPABILITY_SWAP_CONFERENCE]",
+                Call.Details.capabilitiesToString(CAPABILITY_SWAP_CONFERENCE));
+        assertEquals("[Capabilities: CAPABILITY_RESPOND_VIA_TEXT]",
+                Call.Details.capabilitiesToString(CAPABILITY_RESPOND_VIA_TEXT));
+        assertEquals("[Capabilities: CAPABILITY_MUTE]",
+                Call.Details.capabilitiesToString(CAPABILITY_MUTE));
+        assertEquals("[Capabilities: CAPABILITY_MANAGE_CONFERENCE]",
+                Call.Details.capabilitiesToString(CAPABILITY_MANAGE_CONFERENCE));
+
+        final int capabilities = CAPABILITY_SUPPORTS_VT_LOCAL_RX
+                | CAPABILITY_SUPPORTS_VT_LOCAL_TX
+                | CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL
+                | CAPABILITY_SUPPORTS_VT_REMOTE_RX
+                | CAPABILITY_SUPPORTS_VT_REMOTE_TX
+                | CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL
+                | CAPABILITY_CAN_PAUSE_VIDEO;
+        assertEquals("[Capabilities: "
+                + "CAPABILITY_SUPPORTS_VT_LOCAL_RX "
+                + "CAPABILITY_SUPPORTS_VT_LOCAL_TX "
+                + "CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL "
+                + "CAPABILITY_SUPPORTS_VT_REMOTE_RX "
+                + "CAPABILITY_SUPPORTS_VT_REMOTE_TX "
+                + "CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL "
+                + "CAPABILITY_CAN_PAUSE_VIDEO"
+                + "]",
+                Call.Details.capabilitiesToString(capabilities));
+    }
+
+    public void testHasProperty() {
+        assertTrue(Call.Details.hasProperty(PROPERTY_WIFI, PROPERTY_WIFI));
+        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));
+    }
+
+    public void testPropertiesToString() {
+        assertEquals("[Properties: PROPERTY_CONFERENCE]",
+                Call.Details.propertiesToString(PROPERTY_CONFERENCE));
+        assertEquals("[Properties: PROPERTY_GENERIC_CONFERENCE]",
+                Call.Details.propertiesToString(PROPERTY_GENERIC_CONFERENCE));
+        assertEquals("[Properties: PROPERTY_EMERGENCY_CALLBACK_MODE]",
+                Call.Details.propertiesToString(PROPERTY_EMERGENCY_CALLBACK_MODE));
+        assertEquals("[Properties: PROPERTY_WIFI]",
+                Call.Details.propertiesToString(PROPERTY_WIFI));
+        assertEquals("[Properties: PROPERTY_HIGH_DEF_AUDIO]",
+                Call.Details.propertiesToString(PROPERTY_HIGH_DEF_AUDIO));
+
+        final int properties = PROPERTY_CONFERENCE
+                | PROPERTY_WIFI
+                | PROPERTY_HIGH_DEF_AUDIO;
+        assertEquals("[Properties: "
+                + "PROPERTY_CONFERENCE "
+                + "PROPERTY_WIFI "
+                + "PROPERTY_HIGH_DEF_AUDIO"
+                + "]",
+                Call.Details.propertiesToString(properties));
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
new file mode 100644
index 0000000..508870c
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/ConferenceTest.java
@@ -0,0 +1,427 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+import android.os.Bundle;
+import android.telecom.Call;
+import android.telecom.Conference;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.StatusHints;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+
+import java.util.ArrayList;
+
+/**
+ * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
+ * verify the functionality of Call Conferencing.
+ */
+public class ConferenceTest extends BaseTelecomTestWithMockServices {
+
+    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;
+
+    private Call mCall1, mCall2;
+    private MockConnection mConnection1, mConnection2;
+    MockInCallService mInCallService;
+    Conference mConferenceObject;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mShouldTestTelecom) {
+            addOutgoingCalls();
+            addConferenceCall(mCall1, mCall2);
+            // Use vanilla conference object so that the CTS coverage tool detects the useage.
+            mConferenceObject = verifyConferenceForOutgoingCall();
+            verifyConferenceObject(mConferenceObject, mConnection1, mConnection2);
+        }
+    }
+
+    public void testConferenceCreate() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        if (mCall1.getParent() != conf || mCall2.getParent() != conf) {
+            fail("The 2 participating calls should contain the conference call as its parent");
+        }
+        if (!(conf.getChildren().contains(mCall1) && conf.getChildren().contains(mCall2))) {
+            fail("The conference call should contain the 2 participating calls as its children");
+        }
+        assertTrue(mConferenceObject.getConnections().contains(mConnection1));
+
+        assertConnectionState(mConferenceObject.getConnections().get(0), Connection.STATE_ACTIVE);
+        assertConnectionState(mConferenceObject.getConnections().get(1), Connection.STATE_ACTIVE);
+        assertConferenceState(mConferenceObject, Connection.STATE_ACTIVE);
+    }
+
+    public void testConferenceSplit() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        if (!(mCall1.getParent() == conf) && (conf.getChildren().contains(mCall1))) {
+            fail("Call 1 not conferenced");
+        }
+        assertTrue(mConferenceObject.getConnections().contains(mConnection1));
+
+        splitFromConferenceCall(mCall1);
+
+        if ((mCall1.getParent() == conf) || (conf.getChildren().contains(mCall1))) {
+            fail("Call 1 should not be still conferenced");
+        }
+        assertFalse(mConferenceObject.getConnections().contains(mConnection1));
+    }
+
+    public void testConferenceHoldAndUnhold() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        conf.hold();
+        assertCallState(conf, Call.STATE_HOLDING);
+        assertCallState(mCall1, Call.STATE_HOLDING);
+        assertCallState(mCall2, Call.STATE_HOLDING);
+
+        conf.unhold();
+        assertCallState(conf, Call.STATE_ACTIVE);
+        assertCallState(mCall1, Call.STATE_ACTIVE);
+        assertCallState(mCall2, Call.STATE_ACTIVE);
+    }
+
+    public void testConferenceMergeAndSwap() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        conf.mergeConference();
+        assertCallDisplayName(mCall1, TestUtils.MERGE_CALLER_NAME);
+        assertCallDisplayName(mCall2, TestUtils.MERGE_CALLER_NAME);
+        assertConnectionCallDisplayName(mConferenceObject.getConnections().get(0),
+                TestUtils.MERGE_CALLER_NAME);
+        assertConnectionCallDisplayName(mConferenceObject.getConnections().get(1),
+                TestUtils.MERGE_CALLER_NAME);
+
+        conf.swapConference();
+        assertCallDisplayName(mCall1, TestUtils.SWAP_CALLER_NAME);
+        assertCallDisplayName(mCall2, TestUtils.SWAP_CALLER_NAME);
+        assertConnectionCallDisplayName(mConferenceObject.getConnections().get(0),
+                TestUtils.SWAP_CALLER_NAME);
+        assertConnectionCallDisplayName(mConferenceObject.getConnections().get(1),
+                TestUtils.SWAP_CALLER_NAME);
+
+    }
+
+    public void testConferenceSetters() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        placeAndVerifyCall();
+        MockConnection newConnection = verifyConnectionForOutgoingCall(2);
+        final Call newCall = mInCallService.getLastCall();
+
+        ArrayList<Connection> connectionList = new ArrayList<>();
+        connectionList.add(newConnection);
+        ArrayList<Call> callList = new ArrayList<>();
+        callList.add(newCall);
+
+        assertFalse(conf.getDetails().can(Call.Details.CAPABILITY_MUTE));
+        int capabilities = mConferenceObject.getConnectionCapabilities() |
+                Connection.CAPABILITY_MUTE;
+        mConferenceObject.setConnectionCapabilities(capabilities);
+        assertCallCapability(conf, Call.Details.CAPABILITY_MUTE);
+
+        assertFalse(conf.getConferenceableCalls().contains(newCall));
+        mConferenceObject.setConferenceableConnections(connectionList);
+        assertCallConferenceableList(conf, callList);
+
+        mConferenceObject.setConnectionTime(0);
+
+        Bundle extras = new Bundle();
+        extras.putString(TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test");
+        assertNull(conf.getDetails().getExtras());
+        mConferenceObject.setExtras(extras);
+        assertCallExtras(conf, TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test");
+
+        StatusHints hints = new StatusHints("Test", null, null);
+        assertNull(conf.getDetails().getStatusHints());
+        mConferenceObject.setStatusHints(hints);
+        assertCallStatusHints(conf, hints);
+
+        assertFalse(conf.getChildren().contains(newCall));
+        mConferenceObject.addConnection(newConnection);
+        assertCallChildrenContains(conf, newCall, true);
+
+        assertTrue(conf.getChildren().contains(newCall));
+        mConferenceObject.removeConnection(newConnection);
+        assertCallChildrenContains(conf, newCall, false);
+
+        assertVideoState(conf, VideoProfile.STATE_AUDIO_ONLY);
+        final MockVideoProvider mockVideoProvider = mConnection1.getMockVideoProvider();
+        mConferenceObject.setVideoProvider(mConnection1, mockVideoProvider);
+        mConferenceObject.setVideoState(mConnection1, VideoProfile.STATE_BIDIRECTIONAL);
+        assertVideoState(conf, VideoProfile.STATE_BIDIRECTIONAL);
+
+        // Dialing state is unsupported for conference calls. so, the state remains active.
+        mConferenceObject.setDialing();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        mConferenceObject.setOnHold();
+        assertCallState(conf, Call.STATE_HOLDING);
+
+        mConferenceObject.setActive();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        mConferenceObject.setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
+        assertCallState(conf, Call.STATE_DISCONNECTED);
+
+        // Destroy state is unsupported for conference calls. so, the state remains active.
+        mConferenceObject.destroy();
+        assertCallState(conf, Call.STATE_DISCONNECTED);
+    }
+
+    public void testConferenceAddAndRemoveConnection() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        placeAndVerifyCall();
+        MockConnection newConnection = verifyConnectionForOutgoingCall(2);
+        final Call newCall = mInCallService.getLastCall();
+
+        ArrayList<Connection> connectionList = new ArrayList<>();
+        connectionList.add(newConnection);
+        ArrayList<Call> callList = new ArrayList<>();
+        callList.add(newCall);
+
+        assertFalse(conf.getChildren().contains(newCall));
+        mConferenceObject.addConnection(newConnection);
+        assertCallChildrenContains(conf, newCall, true);
+
+        assertTrue(conf.getChildren().contains(newCall));
+        mConferenceObject.removeConnection(newConnection);
+        assertCallChildrenContains(conf, newCall, false);
+    }
+
+    public void testConferenceDTMFTone() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call conf = mInCallService.getLastConferenceCall();
+        assertCallState(conf, Call.STATE_ACTIVE);
+
+        assertTrue(((MockConference)mConferenceObject).getDtmfString().isEmpty());
+        conf.playDtmfTone('1');
+        assertDtmfString((MockConference)mConferenceObject, "1");
+        conf.stopDtmfTone();
+        assertDtmfString((MockConference)mConferenceObject, "1.");
+        conf.playDtmfTone('3');
+        assertDtmfString((MockConference)mConferenceObject, "1.3");
+        conf.stopDtmfTone();
+        assertDtmfString((MockConference)mConferenceObject, "1.3.");
+    }
+
+    private void verifyConferenceObject(Conference mConferenceObject, MockConnection connection1,
+            MockConnection connection2) {
+        assertNull(mConferenceObject.getCallAudioState());
+        assertTrue(mConferenceObject.getConferenceableConnections().isEmpty());
+        assertEquals(connection1.getConnectionCapabilities(),
+                mConferenceObject.getConnectionCapabilities());
+        assertEquals(connection1.getState(), mConferenceObject.getState());
+        assertEquals(connection2.getState(), mConferenceObject.getState());
+        assertTrue(mConferenceObject.getConnections().contains(connection1));
+        assertTrue(mConferenceObject.getConnections().contains(connection2));
+        assertEquals(connection1.getDisconnectCause(), mConferenceObject.getDisconnectCause());
+        assertEquals(connection1.getExtras(), mConferenceObject.getExtras());
+        assertEquals(connection1.getPhoneAccountHandle(), mConferenceObject.getPhoneAccountHandle());
+        assertEquals(connection1.getStatusHints(), mConferenceObject.getStatusHints());
+        assertEquals(VideoProfile.STATE_AUDIO_ONLY, mConferenceObject.getVideoState());
+        assertNull(mConferenceObject.getVideoProvider());
+    }
+
+    private void addOutgoingCalls() {
+        try {
+            PhoneAccount account = setupConnectionService(
+                    new MockConnectionService() {
+                        @Override
+                        public Connection onCreateOutgoingConnection(
+                                PhoneAccountHandle connectionManagerPhoneAccount,
+                                ConnectionRequest request) {
+                            Connection connection = super.onCreateOutgoingConnection(
+                                    connectionManagerPhoneAccount,
+                                    request);
+                            // Modify the connection object created with local values.
+                            int capabilities = connection.getConnectionCapabilities();
+                            connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES);
+                            return connection;
+                        }
+                    }, FLAG_REGISTER | FLAG_ENABLE);
+        } catch(Exception e) {
+            fail("Error in setting up the connection services");
+        }
+
+        placeAndVerifyCall();
+        mConnection1 = verifyConnectionForOutgoingCall(0);
+        mInCallService = mInCallCallbacks.getService();
+        mCall1 = mInCallService.getLastCall();
+        assertCallState(mCall1, Call.STATE_DIALING);
+        mConnection1.setActive();
+        assertCallState(mCall1, Call.STATE_ACTIVE);
+
+        placeAndVerifyCall();
+        mConnection2 = verifyConnectionForOutgoingCall(1);
+        mCall2 = mInCallService.getLastCall();
+        assertCallState(mCall2, Call.STATE_DIALING);
+        mConnection2.setActive();
+        assertCallState(mCall2, Call.STATE_ACTIVE);
+
+        setAndVerifyConferenceablesForOutgoingConnection(0);
+        setAndVerifyConferenceablesForOutgoingConnection(1);
+    }
+
+    private void assertCallCapability(final Call call, final int capability) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getDetails().can(capability);
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should have capability " + capability
+        );
+    }
+
+    private void assertCallConnectTime(final Call call, final int connectTime) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return connectTime;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getDetails().getConnectTimeMillis();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should have connect time " + connectTime
+        );
+    }
+
+    private void assertCallExtras(final Call call, final String key, final String value) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return value;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getDetails().getExtras() != null ?
+                            call.getDetails().getExtras().getString(key) : null;
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should have extra " + key + "=" + value
+        );
+    }
+
+    private void assertCallStatusHints(final Call call, final StatusHints hints) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return hints;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getDetails().getStatusHints();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should have status hints " + hints
+        );
+    }
+
+    private void assertCallChildrenContains(final Call call, final Call childrenCall,
+                                            final boolean expected) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getChildren().contains(childrenCall);
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                expected == true ? "Call should have child call " + childrenCall :
+                        "Call should not have child call " + childrenCall
+        );
+    }
+
+    private void assertVideoState(final Call call, final int videoState) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return videoState;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getDetails().getVideoState();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should be in videoState " + videoState
+        );
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.java
new file mode 100644
index 0000000..836ca48
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/ConnectionServiceTest.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 android.telecom.cts;
+
+import static android.telecom.cts.TestUtils.*;
+
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telecom.ConnectionService;
+import android.util.Log;
+
+import java.util.Collection;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Test some additional {@link ConnectionService} APIs not already covered by other tests.
+ */
+public class ConnectionServiceTest extends BaseTelecomTestWithMockServices {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        if (mShouldTestTelecom) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
+    public void testAddExistingConnection() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        verifyConnectionForOutgoingCall();
+
+        // Add second connection (add existing connection)
+        final MockConnection connection = new MockConnection();
+        connection.setOnHold();
+        CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE, connection);
+        assertNumCalls(mInCallCallbacks.getService(), 2);
+        mInCallCallbacks.lock.drainPermits();
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_HOLDING);
+    }
+
+    public void testGetAllConnections() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        // Add first connection (outgoing call)
+        placeAndVerifyCall();
+        final Connection connection1 = verifyConnectionForOutgoingCall();
+
+        Collection<Connection> connections = CtsConnectionService.getAllConnectionsFromTelecom();
+        assertEquals(1, connections.size());
+        assertTrue(connections.contains(connection1));
+        // Need to move this to active since we reject the 3rd incoming call below if this is in
+        // dialing state (b/23428950).
+        connection1.setActive();
+        assertCallState(mInCallCallbacks.getService().getLastCall(), Call.STATE_ACTIVE);
+
+        // Add second connection (add existing connection)
+        final Connection connection2 = new MockConnection();
+        CtsConnectionService.addExistingConnectionToTelecom(TEST_PHONE_ACCOUNT_HANDLE, connection2);
+        assertNumCalls(mInCallCallbacks.getService(), 2);
+        mInCallCallbacks.lock.drainPermits();
+        connections = CtsConnectionService.getAllConnectionsFromTelecom();
+        assertEquals(2, connections.size());
+        assertTrue(connections.contains(connection2));
+
+        // Add third connection (incoming call)
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        final Connection connection3 = verifyConnectionForIncomingCall();
+        connections = CtsConnectionService.getAllConnectionsFromTelecom();
+        assertEquals(3, connections.size());
+        assertTrue(connections.contains(connection3));
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java b/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.java
new file mode 100644
index 0000000..b6818c8
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/ConnectionTest.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 android.telecom.cts;
+
+import static android.telecom.cts.TestUtils.shouldTestTelecom;
+
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.telecom.Connection;
+import android.telecom.DisconnectCause;
+import android.telecom.StatusHints;
+import android.telecom.TelecomManager;
+import android.test.AndroidTestCase;
+
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+public class ConnectionTest extends AndroidTestCase {
+
+    public void testStateCallbacks() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+
+        waitForStateChange(lock);
+        assertEquals(Connection.STATE_NEW, connection.getState());
+
+        connection.setInitializing();
+        waitForStateChange(lock);
+        assertEquals(Connection.STATE_INITIALIZING, connection.getState());
+
+        connection.setInitialized();
+        waitForStateChange(lock);
+        assertEquals(Connection.STATE_NEW, connection.getState());
+
+        connection.setRinging();
+        waitForStateChange(lock);
+        assertEquals(Connection.STATE_RINGING, connection.getState());
+
+        connection.setDialing();
+        waitForStateChange(lock);
+        assertEquals(Connection.STATE_DIALING, connection.getState());
+
+        connection.setActive();
+        waitForStateChange(lock);
+        assertEquals(Connection.STATE_ACTIVE, connection.getState());
+
+        connection.setOnHold();
+        waitForStateChange(lock);
+        assertEquals(Connection.STATE_HOLDING, connection.getState());
+
+        connection.setDisconnected(
+                new DisconnectCause(DisconnectCause.LOCAL, "Test call"));
+        waitForStateChange(lock);
+        assertEquals(Connection.STATE_DISCONNECTED, connection.getState());
+
+        connection.setRinging();
+        waitForStateChange(lock);
+        assertEquals("Connection should not move out of STATE_DISCONNECTED.",
+                Connection.STATE_DISCONNECTED, connection.getState());
+    }
+
+    /**
+     * {@link UnsupportedOperationException} is only thrown in L MR1+.
+     */
+    public void testFailedState() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
+            return;
+        }
+        Connection connection = Connection.createFailedConnection(
+                new DisconnectCause(DisconnectCause.LOCAL, "Test call"));
+        assertEquals(Connection.STATE_DISCONNECTED, connection.getState());
+
+        try {
+            connection.setRinging();
+        } catch (UnsupportedOperationException e) {
+            return;
+        }
+        fail("Connection should not move out of STATE_DISCONNECTED");
+    }
+
+    /**
+     * {@link UnsupportedOperationException} is only thrown in L MR1+.
+     */
+    public void testCanceledState() {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) {
+            return;
+        }
+        Connection connection = Connection.createCanceledConnection();
+        assertEquals(Connection.STATE_DISCONNECTED, connection.getState());
+
+        try {
+            connection.setDialing();
+        } catch (UnsupportedOperationException e) {
+            return;
+        }
+        fail("Connection should not move out of STATE_DISCONNECTED");
+    }
+
+    public void testSetAndGetCallerDisplayName() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        connection.setCallerDisplayName("Test User", TelecomManager.PRESENTATION_ALLOWED);
+        assertEquals("Test User", connection.getCallerDisplayName());
+        assertEquals(TelecomManager.PRESENTATION_ALLOWED,
+                connection.getCallerDisplayNamePresentation());
+    }
+
+    public void testSetAndGetAddress() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        final Uri address = Uri.fromParts("tel", "1234567", null);
+        connection.setAddress(address, TelecomManager.PRESENTATION_UNKNOWN);
+        assertEquals(address, connection.getAddress());
+        assertEquals(TelecomManager.PRESENTATION_UNKNOWN, connection.getAddressPresentation());
+    }
+
+    public void testSetAndGetConnectionCapabilities() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        final int capabilities = Connection.CAPABILITY_HOLD | Connection.CAPABILITY_CAN_PAUSE_VIDEO
+                | Connection.CAPABILITY_MANAGE_CONFERENCE | Connection.CAPABILITY_RESPOND_VIA_TEXT;
+
+        connection.setConnectionCapabilities(capabilities);
+
+        assertEquals(capabilities, connection.getConnectionCapabilities());
+    }
+
+    public void testSetAndGetDisconnectCause() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+        assertEquals(Connection.STATE_NEW, connection.getState());
+
+        final DisconnectCause disconnectCause = new DisconnectCause(DisconnectCause.REJECTED,
+                "No friends", "No friends to talk to", "No friends to talk to");
+
+        connection.setDisconnected(disconnectCause);
+
+        assertEquals(Connection.STATE_DISCONNECTED, connection.getState());
+        assertEquals(disconnectCause, connection.getDisconnectCause());
+    }
+
+    public void testSetAndGetAudioModeIsVoip() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        assertFalse(connection.getAudioModeIsVoip());
+        connection.setAudioModeIsVoip(true);
+        assertTrue(connection.getAudioModeIsVoip());
+    }
+
+    public void testSetAndGetExtras() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        assertEquals(null, connection.getExtras());
+
+        final Bundle extras = new Bundle();
+        extras.putBoolean("test-extra-key", true);
+        connection.setExtras(extras);
+
+        final Bundle retrieved = connection.getExtras();
+        assertNotNull(retrieved);
+        assertTrue(extras.getBoolean("test-extra-key"));
+    }
+
+    public void testSetAndGetStatusHints() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        assertEquals(null, connection.getStatusHints());
+
+        final StatusHints statusHints = new StatusHints("Test", null, null);
+        connection.setStatusHints(statusHints);
+        assertEquals(statusHints, connection.getStatusHints());
+    }
+
+    public void testSetAndGetRingbackRequested() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        assertFalse(connection.isRingbackRequested());
+
+        connection.setRingbackRequested(true);
+        assertTrue(connection.isRingbackRequested());
+    }
+
+    public void testSetAndGetVideoProvider() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        final Semaphore lock = new Semaphore(0);
+        Connection connection = createConnection(lock);
+        waitForStateChange(lock);
+
+        assertNull(connection.getVideoProvider());
+
+        final Connection.VideoProvider videoProvider = new MockVideoProvider(null);
+        connection.setVideoProvider(videoProvider);
+        assertEquals(videoProvider, connection.getVideoProvider());
+    }
+
+    public void testStateToString() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        assertEquals("INITIALIZING", Connection.stateToString(Connection.STATE_INITIALIZING));
+        assertEquals("NEW", Connection.stateToString(Connection.STATE_NEW));
+        assertEquals("RINGING", Connection.stateToString(Connection.STATE_RINGING));
+        assertEquals("DIALING", Connection.stateToString(Connection.STATE_DIALING));
+        assertEquals("ACTIVE", Connection.stateToString(Connection.STATE_ACTIVE));
+        assertEquals("HOLDING", Connection.stateToString(Connection.STATE_HOLDING));
+        assertEquals("DISCONNECTED", Connection.stateToString(Connection.STATE_DISCONNECTED));
+    }
+
+    public void testCapabilitiesToString() {
+        if (!shouldTestTelecom(getContext())) {
+            return;
+        }
+
+        assertEquals("[Capabilities: CAPABILITY_HOLD]",
+                Connection.capabilitiesToString(Connection.CAPABILITY_HOLD));
+        assertEquals("[Capabilities: CAPABILITY_MUTE]",
+                Connection.capabilitiesToString(Connection.CAPABILITY_MUTE));
+        assertEquals("[Capabilities: CAPABILITY_HOLD "
+                + "CAPABILITY_RESPOND_VIA_TEXT "
+                + "CAPABILITY_MANAGE_CONFERENCE]",
+                Connection.capabilitiesToString(Connection.CAPABILITY_HOLD
+                        | Connection.CAPABILITY_RESPOND_VIA_TEXT
+                        | Connection.CAPABILITY_MANAGE_CONFERENCE));
+    }
+
+    private static Connection createConnection(final Semaphore lock) {
+        BasicConnection connection = new BasicConnection();
+        connection.setLock(lock);
+        return connection;
+    }
+
+    private static void waitForStateChange(Semaphore lock) {
+        try {
+            lock.tryAcquire(1000, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("State transition timed out");
+        }
+    }
+
+    private static final class BasicConnection extends Connection {
+        private Semaphore mLock;
+
+        public void setLock(Semaphore lock) {
+            mLock = lock;
+        }
+
+        @Override
+        public void onStateChanged(int state) {
+            mLock.release();
+        }
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
new file mode 100644
index 0000000..d8d5773
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/CtsConnectionService.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Intent;
+import android.telecom.Conference;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.ConnectionService;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.RemoteConference;
+import android.telecom.RemoteConnection;
+import android.util.Log;
+
+import java.util.Collection;
+
+/**
+ * This is the official ConnectionService for Telecom's CTS App. Since telecom requires that a
+ * CS be registered in the AndroidManifest.xml file, we have to have a single implementation
+ * of a CS and this is it. To test specific CS behavior, tests will implement their own CS and
+ * tell CtsConnectionService to forward any method invocations to that test's implementation.
+ * This is set up using {@link #setUp} and should be cleaned up before the end of the test using
+ * {@link #tearDown}.
+ *
+ * sConnectionService: Contains the connection service object provided by the current test in
+ *                     progress. We use this object to forward any communication received from the
+ *                     Telecom framework to the test connection service.
+ * sTelecomConnectionService: Contains the connection service object registered to the Telecom
+ *                            framework. We use this object to forward any communication from the
+ *                            test connection service to the Telecom framework.
+ *
+ */
+public class CtsConnectionService extends ConnectionService {
+    private static String LOG_TAG = "CtsConnectionService";
+    // This is the connection service implemented by the test
+    private static ConnectionService sConnectionService;
+    // This is the connection service registered with Telecom
+    private static ConnectionService sTelecomConnectionService;
+    private static boolean mIsServiceUnbound;
+
+    public CtsConnectionService() throws Exception {
+        super();
+        sTelecomConnectionService = this;
+    }
+
+    // ConnectionService used by default as a fallback if no connection service is specified
+    // during test setup.
+    private static ConnectionService mMockConnectionService = new MockConnectionService();
+
+    /**
+     * Used to control whether the {@link MockVideoProvider} will be created when connections are
+     * created.  Used by {@link VideoCallTest#testVideoCallDelayProvider()} to test scenario where
+     * the {@link MockVideoProvider} is not created immediately when the Connection is created.
+     */
+    private static Object sLock = new Object();
+
+    public static void setUp(PhoneAccountHandle phoneAccountHandle,
+            ConnectionService connectionService) throws Exception {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                throw new Exception("Mock ConnectionService exists.  Failed to call tearDown().");
+            }
+            sConnectionService = connectionService;
+            // Cant override the onBind method for ConnectionService, so reset it here.
+            mIsServiceUnbound = false;
+        }
+    }
+
+    public static void tearDown() {
+        synchronized(sLock) {
+            sConnectionService = null;
+        }
+    }
+
+    @Override
+    public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                return sConnectionService.onCreateOutgoingConnection(
+                        connectionManagerPhoneAccount, request);
+            } else {
+                return mMockConnectionService.onCreateOutgoingConnection(
+                        connectionManagerPhoneAccount, request);
+            }
+        }
+    }
+
+    @Override
+    public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                return sConnectionService.onCreateIncomingConnection(
+                        connectionManagerPhoneAccount, request);
+            } else {
+                return mMockConnectionService.onCreateIncomingConnection(
+                        connectionManagerPhoneAccount, request);
+            }
+        }
+    }
+
+    @Override
+    public void onConference(Connection connection1, Connection connection2) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                sConnectionService.onConference(connection1, connection2);
+            } else {
+                mMockConnectionService.onConference(connection1, connection2);
+            }
+        }
+    }
+
+    @Override
+    public void onRemoteExistingConnectionAdded(RemoteConnection connection) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                sConnectionService.onRemoteExistingConnectionAdded(connection);
+            } else {
+                mMockConnectionService.onRemoteExistingConnectionAdded(connection);
+            }
+        }
+    }
+
+    public static void addConferenceToTelecom(Conference conference) {
+        synchronized(sLock) {
+            sTelecomConnectionService.addConference(conference);
+        }
+    }
+
+    public static void addExistingConnectionToTelecom(
+            PhoneAccountHandle phoneAccountHandle, Connection connection) {
+        synchronized(sLock) {
+            sTelecomConnectionService.addExistingConnection(phoneAccountHandle, connection);
+        }
+    }
+
+    public static Collection<Connection> getAllConnectionsFromTelecom() {
+        synchronized(sLock) {
+            return sTelecomConnectionService.getAllConnections();
+        }
+    }
+
+    public static RemoteConnection createRemoteOutgoingConnectionToTelecom(
+            PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        synchronized(sLock) {
+            return sTelecomConnectionService.createRemoteOutgoingConnection(
+                    connectionManagerPhoneAccount, request);
+        }
+    }
+
+    public static RemoteConnection createRemoteIncomingConnectionToTelecom(
+            PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        synchronized(sLock) {
+            return sTelecomConnectionService.createRemoteIncomingConnection(
+                    connectionManagerPhoneAccount, request);
+        }
+    }
+
+    @Override
+    public void onRemoteConferenceAdded(RemoteConference conference) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                sConnectionService.onRemoteConferenceAdded(conference);
+            } else {
+                mMockConnectionService.onRemoteConferenceAdded(conference);
+            }
+        }
+    }
+
+    @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;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/CtsRemoteConnectionService.java b/tests/tests/telecom/src/android/telecom/cts/CtsRemoteConnectionService.java
new file mode 100644
index 0000000..13b525f
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/CtsRemoteConnectionService.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Intent;
+import android.telecom.Conference;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.ConnectionService;
+import android.telecom.PhoneAccountHandle;
+import android.util.Log;
+
+/**
+ * This is the Remote ConnectionService for Telecom's CTS App. Since telecom requires that a
+ * CS be registered in the AndroidManifest.xml file, we have to have a single implementation
+ * of a CS and this is it. To test specific CS behavior, tests will implement their own CS and
+ * tell CtsRemoteConnectionService to forward any method invocations to that test's implementation.
+ * This is set up using {@link #setUp} and should be cleaned up before the end of the test using
+ * {@link #tearDown}.
+ *
+ * sConnectionService: Contains the connection service object provided by the current test in
+ *                     progress. We use this object to forward any communication received from the
+ *                     Telecom framework to the test connection service.
+ * sTelecomConnectionService: Contains the connection service object registered to the Telecom
+ *                            framework. We use this object to forward any communication from the
+ *                            test connection service to the Telecom framework.
+ *
+ */
+public class CtsRemoteConnectionService extends ConnectionService {
+    private static String LOG_TAG = "CtsConnectionService";
+    // This is the connection service implemented by the test
+    private static ConnectionService sConnectionService;
+    // This is the connection service registered with Telecom
+    private static ConnectionService sTelecomConnectionService;
+    private static boolean mIsServiceUnbound;
+
+    public CtsRemoteConnectionService() throws Exception {
+        super();
+        if (sTelecomConnectionService != null) {
+            throw new Exception("Telecom ConnectionService exists");
+        }
+        sTelecomConnectionService = this;
+    }
+
+    // ConnectionService used by default as a fallback if no connection service is specified
+    // during test setup.
+    private static ConnectionService mMockConnectionService = new MockConnectionService();
+
+    /**
+     * Used to control whether the {@link MockVideoProvider} will be created when connections are
+     * created.  Used by {@link VideoCallTest#testVideoCallDelayProvider()} to test scenario where
+     * the {@link MockVideoProvider} is not created immediately when the Connection is created.
+     */
+    private static Object sLock = new Object();
+
+    public static void setUp(PhoneAccountHandle phoneAccountHandle,
+            ConnectionService connectionService) throws Exception {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                throw new Exception("Mock ConnectionService exists.  Failed to call tearDown().");
+            }
+            sConnectionService = connectionService;
+            // Cant override the onBind method for ConnectionService, so reset it here.
+            mIsServiceUnbound = false;
+        }
+    }
+
+    public static void tearDown() {
+        synchronized(sLock) {
+            sConnectionService = null;
+        }
+    }
+
+    @Override
+    public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                return sConnectionService.onCreateOutgoingConnection(
+                        connectionManagerPhoneAccount, request);
+            } else {
+                return mMockConnectionService.onCreateOutgoingConnection(
+                        connectionManagerPhoneAccount, request);
+            }
+        }
+    }
+
+    @Override
+    public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                return sConnectionService.onCreateIncomingConnection(
+                        connectionManagerPhoneAccount, request);
+            } else {
+                return mMockConnectionService.onCreateIncomingConnection(
+                        connectionManagerPhoneAccount, request);
+            }
+        }
+    }
+
+    @Override
+    public void onConference(Connection connection1, Connection connection2) {
+        synchronized(sLock) {
+            if (sConnectionService != null) {
+                sConnectionService.onConference(connection1, connection2);
+            } else {
+                mMockConnectionService.onConference(connection1, connection2);
+            }
+        }
+    }
+
+    public static void addConferenceToTelecom(Conference conference) {
+        synchronized(sLock) {
+            sTelecomConnectionService.addConference(conference);
+        }
+    }
+
+    @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;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/DataObjectUnitTests.java b/tests/tests/telecom/src/android/telecom/cts/DataObjectUnitTests.java
new file mode 100644
index 0000000..1fbe0d5
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/DataObjectUnitTests.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.drawable.Icon;
+import android.media.ToneGenerator;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Process;
+import android.os.UserHandle;
+import android.telecom.CallAudioState;
+import android.telecom.ConnectionRequest;
+import android.telecom.DisconnectCause;
+import android.telecom.GatewayInfo;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.StatusHints;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+import android.test.InstrumentationTestCase;
+
+import com.android.cts.telecom.R;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Verifies that the setter, getter and parcelable interfaces of the Telecom data objects are
+ * working as intended.
+ */
+public class DataObjectUnitTests extends InstrumentationTestCase {
+
+
+    public void testPhoneAccount() throws Exception {
+        Context context = getInstrumentation().getContext();
+        PhoneAccountHandle accountHandle = new PhoneAccountHandle(
+                new ComponentName(PACKAGE, COMPONENT),
+                ACCOUNT_ID);
+        Icon phoneIcon = Icon.createWithResource(context, R.drawable.ic_phone_24dp);
+        Uri tel = Uri.parse("tel:555-TEST");
+        PhoneAccount account = PhoneAccount.builder(
+                accountHandle, ACCOUNT_LABEL)
+                .setAddress(tel)
+                .setSubscriptionAddress(tel)
+                .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+                .setHighlightColor(Color.RED)
+                .setShortDescription(ACCOUNT_LABEL)
+                .setSupportedUriSchemes(Arrays.asList("tel"))
+                .setIcon(phoneIcon)
+                .build();
+        assertNotNull(account);
+        assertEquals(accountHandle, account.getAccountHandle());
+        assertEquals(tel, account.getAddress());
+        assertEquals(tel, account.getSubscriptionAddress());
+        assertEquals(PhoneAccount.CAPABILITY_CALL_PROVIDER, account.getCapabilities());
+        assertEquals(Color.RED, account.getHighlightColor());
+        assertEquals(ACCOUNT_LABEL, account.getShortDescription());
+        assertEquals(ACCOUNT_LABEL, account.getLabel());
+        assertEquals(Arrays.asList("tel"), account.getSupportedUriSchemes());
+        assertEquals(phoneIcon.toString(), account.getIcon().toString());
+        assertEquals(0, account.describeContents());
+
+        // Create a parcel of the object and recreate the object back
+        // from the parcel.
+        Parcel p = Parcel.obtain();
+        account.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        PhoneAccount parcelAccount = PhoneAccount.CREATOR.createFromParcel(p);
+        assertNotNull(parcelAccount);
+        assertEquals(accountHandle, parcelAccount.getAccountHandle());
+        assertEquals(tel, parcelAccount.getAddress());
+        assertEquals(tel, parcelAccount.getSubscriptionAddress());
+        assertEquals(PhoneAccount.CAPABILITY_CALL_PROVIDER, parcelAccount.getCapabilities());
+        assertEquals(Color.RED, parcelAccount.getHighlightColor());
+        assertEquals(ACCOUNT_LABEL, parcelAccount.getShortDescription());
+        assertEquals(Arrays.asList("tel"), parcelAccount.getSupportedUriSchemes());
+        assertEquals(phoneIcon.toString(), parcelAccount.getIcon().toString());
+        assertEquals(0, parcelAccount.describeContents());
+        p.recycle();
+    }
+
+    public void testPhoneAccountHandle() throws Exception {
+        final ComponentName component = new ComponentName(PACKAGE, COMPONENT);
+        final UserHandle userHandle = Process.myUserHandle();
+        PhoneAccountHandle accountHandle = new PhoneAccountHandle(
+                component,
+                ACCOUNT_ID,
+                userHandle);
+        assertNotNull(accountHandle);
+        assertEquals(component, accountHandle.getComponentName());
+        assertEquals(ACCOUNT_ID, accountHandle.getId());
+        assertEquals(userHandle, accountHandle.getUserHandle());
+        assertEquals(0, accountHandle.describeContents());
+
+        // Create a parcel of the object and recreate the object back
+        // from the parcel.
+        Parcel p = Parcel.obtain();
+        accountHandle.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        PhoneAccountHandle unparcelled = PhoneAccountHandle.CREATOR.createFromParcel(p);
+        assertEquals(accountHandle, unparcelled);
+        assertEquals(accountHandle.getComponentName(), unparcelled.getComponentName());
+        assertEquals(accountHandle.getId(), unparcelled.getId());
+        assertEquals(accountHandle.getUserHandle(), unparcelled.getUserHandle());
+        p.recycle();
+    }
+
+    public void testConnectionRequest() throws Exception {
+        PhoneAccountHandle accountHandle = new PhoneAccountHandle(
+                new ComponentName(PACKAGE, COMPONENT),
+                ACCOUNT_ID);
+        Bundle extras = new Bundle();
+        extras.putString(
+                TelecomManager.GATEWAY_PROVIDER_PACKAGE,
+                PACKAGE);
+        ConnectionRequest request = new ConnectionRequest(
+                accountHandle,
+                Uri.parse("tel:555-TEST"),
+                extras,
+                VideoProfile.STATE_AUDIO_ONLY);
+        assertEquals(accountHandle, request.getAccountHandle());
+        assertEquals(Uri.parse("tel:555-TEST"), request.getAddress());
+        assertEquals(extras.getString(
+                TelecomManager.GATEWAY_PROVIDER_PACKAGE),
+                request.getExtras().getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE));
+        assertEquals(VideoProfile.STATE_AUDIO_ONLY, request.getVideoState());
+        assertEquals(0, request.describeContents());
+
+        // Create a parcel of the object and recreate the object back
+        // from the parcel.
+        Parcel p = Parcel.obtain();
+        request.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        ConnectionRequest parcelRequest = ConnectionRequest.CREATOR.createFromParcel(p);
+        assertEquals(accountHandle, parcelRequest.getAccountHandle());
+        assertEquals(Uri.parse("tel:555-TEST"), parcelRequest.getAddress());
+        assertEquals(
+                extras.getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE),
+                parcelRequest.getExtras().getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE));
+        assertEquals(VideoProfile.STATE_AUDIO_ONLY, parcelRequest.getVideoState());
+        assertEquals(0, parcelRequest.describeContents());
+        p.recycle();
+    }
+
+    public void testDisconnectCause() throws Exception {
+        final CharSequence label = "Out of service area";
+        final CharSequence description = "Mobile network not available";
+        final String reason = "CTS Testing";
+        DisconnectCause cause = new DisconnectCause(
+                DisconnectCause.ERROR,
+                label,
+                description,
+                reason,
+                ToneGenerator.TONE_CDMA_CALLDROP_LITE);
+        assertEquals(DisconnectCause.ERROR, cause.getCode());
+        assertEquals(label, cause.getLabel());
+        assertEquals(description, cause.getDescription());
+        assertEquals(reason, cause.getReason());
+        assertEquals(ToneGenerator.TONE_CDMA_CALLDROP_LITE, cause.getTone());
+        assertEquals(0, cause.describeContents());
+
+        // Create a parcel of the object and recreate the object back
+        // from the parcel.
+        Parcel p = Parcel.obtain();
+        cause.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        DisconnectCause parcelCause = DisconnectCause.CREATOR.createFromParcel(p);
+        assertEquals(DisconnectCause.ERROR, parcelCause.getCode());
+        assertEquals(label, parcelCause.getLabel());
+        assertEquals(description, parcelCause.getDescription());
+        assertEquals(reason, parcelCause.getReason());
+        assertEquals(ToneGenerator.TONE_CDMA_CALLDROP_LITE, parcelCause.getTone());
+        assertEquals(0, parcelCause.describeContents());
+        assertEquals(cause, parcelCause);
+        p.recycle();
+    }
+
+    public void testStatusHints() throws Exception {
+        Context context = getInstrumentation().getContext();
+        final CharSequence label = "Wi-Fi call";
+        Bundle extras = new Bundle();
+        extras.putString(
+                TelecomManager.GATEWAY_PROVIDER_PACKAGE,
+                PACKAGE);
+        Icon icon = Icon.createWithResource(context, R.drawable.ic_phone_24dp);
+        StatusHints hints = new StatusHints(
+                label,
+                icon,
+                extras);
+        assertEquals(label, hints.getLabel());
+        assertEquals(icon.toString(), hints.getIcon().toString());
+        assertEquals(extras.getString(
+                TelecomManager.GATEWAY_PROVIDER_PACKAGE),
+                hints.getExtras().getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE));
+        assertEquals(0, hints.describeContents());
+
+        // Create a parcel of the object and recreate the object back
+        // from the parcel.
+        Parcel p = Parcel.obtain();
+        hints.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        StatusHints parcelHints = StatusHints.CREATOR.createFromParcel(p);
+        assertEquals(label, parcelHints.getLabel());
+        assertEquals(icon.toString(), parcelHints.getIcon().toString());
+        assertEquals(
+                extras.getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE),
+                parcelHints.getExtras().getString(TelecomManager.GATEWAY_PROVIDER_PACKAGE));
+        assertEquals(0, parcelHints.describeContents());
+        // This fails because Bundle does not have a equals implementation.
+        // assertEquals(hints, parcelHints);
+        p.recycle();
+    }
+
+    public void testGatewayInfo() throws Exception {
+        final CharSequence label = "Wi-Fi call";
+        Uri originalAddress = Uri.parse("http://www.google.com");
+        Uri gatewayAddress = Uri.parse("http://www.google.com");
+        GatewayInfo info = new GatewayInfo(
+                PACKAGE,
+                gatewayAddress,
+                originalAddress);
+        assertEquals(PACKAGE, info.getGatewayProviderPackageName());
+        assertEquals(gatewayAddress, info.getGatewayAddress());
+        assertEquals(originalAddress, info.getOriginalAddress());
+        assertEquals(0, info.describeContents());
+        assertFalse(info.isEmpty());
+
+        // Create a parcel of the object and recreate the object back
+        // from the parcel.
+        Parcel p = Parcel.obtain();
+        info.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        GatewayInfo parcelInfo = GatewayInfo.CREATOR.createFromParcel(p);
+        assertEquals(PACKAGE, parcelInfo.getGatewayProviderPackageName());
+        assertEquals(gatewayAddress, parcelInfo.getGatewayAddress());
+        assertEquals(originalAddress, parcelInfo.getOriginalAddress());
+        assertEquals(0, parcelInfo.describeContents());
+        p.recycle();
+    }
+
+    public void testCallAudioState() throws Exception {
+        CallAudioState audioState = new CallAudioState(
+                true,
+                CallAudioState.ROUTE_EARPIECE,
+                CallAudioState.ROUTE_WIRED_OR_EARPIECE);
+        assertEquals(true, audioState.isMuted());
+        assertEquals(CallAudioState.ROUTE_EARPIECE, audioState.getRoute());
+        assertEquals(CallAudioState.ROUTE_WIRED_OR_EARPIECE, audioState.getSupportedRouteMask());
+        assertEquals(0, audioState.describeContents());
+        assertEquals("EARPIECE", CallAudioState.audioRouteToString(audioState.getRoute()));
+
+        // Create a parcel of the object and recreate the object back
+        // from the parcel.
+        Parcel p = Parcel.obtain();
+        audioState.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        CallAudioState parcelAudioState = CallAudioState.CREATOR.createFromParcel(p);
+        assertEquals(true, parcelAudioState.isMuted());
+        assertEquals(CallAudioState.ROUTE_EARPIECE, parcelAudioState.getRoute());
+        assertEquals(CallAudioState.ROUTE_WIRED_OR_EARPIECE, parcelAudioState.getSupportedRouteMask());
+        assertEquals(0, parcelAudioState.describeContents());
+        assertEquals(audioState, parcelAudioState);
+        p.recycle();
+    }
+
+    public void testVideoProfile() throws Exception {
+        VideoProfile videoProfile = new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL,
+                VideoProfile.QUALITY_HIGH);
+        assertEquals(VideoProfile.STATE_BIDIRECTIONAL, videoProfile.getVideoState());
+        assertEquals(VideoProfile.QUALITY_HIGH, videoProfile.getQuality());
+        assertEquals(0, videoProfile.describeContents());
+        assertEquals("Audio Tx Rx", VideoProfile.videoStateToString(videoProfile.getVideoState()));
+
+        // Create a parcel of the object and recreate the object back from the parcel.
+        Parcel p = Parcel.obtain();
+        videoProfile.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        VideoProfile unparcelled = VideoProfile.CREATOR.createFromParcel(p);
+        assertEquals(videoProfile.getQuality(), unparcelled.getQuality());
+        assertEquals(videoProfile.getVideoState(), unparcelled.getVideoState());
+        p.recycle();
+    }
+
+    public void testCameraCapabilities() throws Exception {
+        VideoProfile.CameraCapabilities cameraCapabilities =
+                new VideoProfile.CameraCapabilities(500, 1000);
+        assertEquals(500, cameraCapabilities.getWidth());
+        assertEquals(1000, cameraCapabilities.getHeight());
+        assertEquals(0, cameraCapabilities.describeContents());
+
+        // Create a parcel of the object and recreate the object back from the parcel.
+        Parcel p = Parcel.obtain();
+        cameraCapabilities.writeToParcel(p, 0);
+        p.setDataPosition(0);
+        VideoProfile.CameraCapabilities unparcelled =
+                VideoProfile.CameraCapabilities.CREATOR.createFromParcel(p);
+        assertEquals(cameraCapabilities.getWidth(), unparcelled.getWidth());
+        assertEquals(cameraCapabilities.getHeight(), unparcelled.getHeight());
+        p.recycle();
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/DefaultDialerOperationsTest.java b/tests/tests/telecom/src/android/telecom/cts/DefaultDialerOperationsTest.java
new file mode 100644
index 0000000..b574a96
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/DefaultDialerOperationsTest.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.ComponentName;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.provider.VoicemailContract.Voicemails;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+
+import java.util.List;
+
+
+/**
+ * Verifies that certain privileged operations can only be performed by the default dialer.
+ */
+public class DefaultDialerOperationsTest extends InstrumentationTestCase {
+    private Context mContext;
+    private TelecomManager mTelecomManager;
+    private PhoneAccountHandle mPhoneAccountHandle;
+    private String mPreviousDefaultDialer = null;
+    private String mSystemDialer = null;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation());
+        // Reset the current dialer to the system dialer, to ensure that we start each test
+        // without being the default dialer.
+        mSystemDialer = TestUtils.getSystemDialer(getInstrumentation());
+        if (!TextUtils.isEmpty(mSystemDialer)) {
+            TestUtils.setDefaultDialer(getInstrumentation(), mSystemDialer);
+        }
+        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+        final List<PhoneAccountHandle> accounts = mTelecomManager.getCallCapablePhoneAccounts();
+        if (accounts != null && !accounts.isEmpty()) {
+            mPhoneAccountHandle = accounts.get(0);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!TextUtils.isEmpty(mPreviousDefaultDialer)) {
+            // Restore the default dialer to whatever the default dialer was before the tests
+            // were started. This may or may not be the system dialer.
+            TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer);
+        }
+        super.tearDown();
+    }
+
+    public void testGetDefaultDialerPackage() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        assertEquals(mSystemDialer, mTelecomManager.getDefaultDialerPackage());
+        TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+        assertEquals(TestUtils.PACKAGE, mTelecomManager.getDefaultDialerPackage());
+    }
+
+    public void testVoicemailReadWritePermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        try {
+            mContext.getContentResolver().query(Voicemails.CONTENT_URI, null, null, null, null);
+            fail("Reading voicemails should throw SecurityException if not default Dialer");
+        } catch (SecurityException e) {
+        }
+
+        try {
+            mContext.getContentResolver().delete(Voicemails.CONTENT_URI,
+                    Voicemails._ID + "=999 AND 1=2", null);
+            fail("Deleting voicemails should throw SecurityException if not default Dialer");
+        } catch (SecurityException e) {
+        }
+
+        try {
+            mContext.getContentResolver().update(
+                    Voicemails.CONTENT_URI.buildUpon().appendPath("999").build(),
+                    new ContentValues(),
+                    null,
+                    null);
+            fail("Updating voicemails should throw SecurityException if not default Dialer");
+        } catch (SecurityException e) {
+        }
+
+        TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+        // No exception if the calling package is the default dialer.
+        mContext.getContentResolver().query(Voicemails.CONTENT_URI, null, null, null, null);
+        mContext.getContentResolver().delete(Voicemails.CONTENT_URI,
+                Voicemails._ID + "=999 AND 1=2", null);
+    }
+
+    public void testSilenceRingerPermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        try {
+            mTelecomManager.silenceRinger();
+            fail("TelecomManager.silenceRinger should throw SecurityException if not default "
+                    + "dialer");
+        } catch (SecurityException e) {
+        }
+
+        TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+        // No exception if the calling package is the default dialer.
+        mTelecomManager.silenceRinger();
+    }
+
+    public void testCancelMissedCallsNotificationPermissions()
+            throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        try {
+            mTelecomManager.cancelMissedCallsNotification();
+            fail("TelecomManager.cancelMissedCallsNotification should throw SecurityException if "
+                    + "not default dialer");
+        } catch (SecurityException e) {
+        }
+
+        TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+        // No exception if the calling package is the default dialer.
+        mTelecomManager.cancelMissedCallsNotification();
+    }
+
+    public void testHandlePinMmPermissions()
+            throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        try {
+            mTelecomManager.handleMmi("0");
+            fail("TelecomManager.handleMmi should throw SecurityException if not default dialer");
+        } catch (SecurityException e) {
+        }
+
+        try {
+            mTelecomManager.handleMmi("0", mPhoneAccountHandle);
+            fail("TelecomManager.handleMmi should throw SecurityException if not default dialer");
+        } catch (SecurityException e) {
+        }
+
+        TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+        // No exception if the calling package is the default dialer.
+        mTelecomManager.handleMmi("0");
+        mTelecomManager.handleMmi("0", mPhoneAccountHandle);
+    }
+
+    public void testGetAdnForPhoneAccountPermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        try {
+            mTelecomManager.getAdnUriForPhoneAccount(mPhoneAccountHandle);
+            fail("TelecomManager.getAdnUriForPhoneAccount should throw SecurityException if "
+                    + "not default dialer");
+        } catch (SecurityException e) {
+        }
+
+        TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+        // No exception if the calling package is the default dialer.
+        mTelecomManager.getAdnUriForPhoneAccount(mPhoneAccountHandle);
+    }
+
+    public void testSetDefaultDialerNoDialIntent_notSupported() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        final PackageManager pm = mContext.getPackageManager();
+        final ComponentName name = new ComponentName(mContext,
+                "android.telecom.cts.MockDialerActivity");
+        try {
+            pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                    PackageManager.DONT_KILL_APP);
+
+            final String result =
+                    TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+            assertNotSame(result, TestUtils.PACKAGE);
+            assertTrue("Expected failure indicating that this was not an installed dialer app",
+                    result.contains("is not an installed Dialer app"));
+        } finally {
+            pm.setComponentEnabledSetting(name, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                    PackageManager.DONT_KILL_APP);
+        }
+
+        // Now that the activity is present again in the package manager, this should succeed.
+        final String result = TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+        assertTrue("Expected success message indicating that " + TestUtils.PACKAGE + " was set as "
+                + "default dialer.", result.contains("set as default dialer"));
+        assertEquals(TestUtils.PACKAGE, TestUtils.getDefaultDialer(getInstrumentation()));
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
new file mode 100644
index 0000000..02d2f15
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/ExtendedInCallServiceTest.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+import android.content.Context;
+import android.telecom.CallAudioState;
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telecom.ConnectionService;
+import android.telecom.InCallService;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+
+import java.util.List;
+
+/**
+ * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
+ * verify the functionality of the Telecom service.
+ */
+public class ExtendedInCallServiceTest extends BaseTelecomTestWithMockServices {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mShouldTestTelecom) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
+    public void testAddNewOutgoingCallAndThenDisconnect() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        inCallService.disconnectLastCall();
+
+        assertNumCalls(inCallService, 0);
+    }
+
+    public void testMuteAndUnmutePhone() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+
+        assertCallState(call, Call.STATE_DIALING);
+
+        assertMuteState(connection, false);
+
+        // Explicitly call super implementation to enable detection of CTS coverage
+        ((InCallService) inCallService).setMuted(true);
+
+        assertMuteState(connection, true);
+        assertMuteState(inCallService, true);
+
+        inCallService.setMuted(false);
+        assertMuteState(connection, false);
+        assertMuteState(inCallService, false);
+    }
+
+    public void testSwitchAudioRoutes() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+
+        final int currentInvokeCount = mOnCallAudioStateChangedCounter.getInvokeCount();
+
+        // Only test speaker and earpiece modes because the other modes are dependent on having
+        // a bluetooth headset or wired headset connected.
+
+        // Explicitly call super implementation to enable detection of CTS coverage
+        ((InCallService) inCallService).setAudioRoute(CallAudioState.ROUTE_SPEAKER);
+        mOnCallAudioStateChangedCounter.waitForCount(currentInvokeCount + 1,
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertAudioRoute(connection, CallAudioState.ROUTE_SPEAKER);
+        assertAudioRoute(inCallService, CallAudioState.ROUTE_SPEAKER);
+
+        inCallService.setAudioRoute(CallAudioState.ROUTE_EARPIECE);
+        mOnCallAudioStateChangedCounter.waitForCount(currentInvokeCount + 2,
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertAudioRoute(connection, CallAudioState.ROUTE_EARPIECE);
+        assertAudioRoute(inCallService, CallAudioState.ROUTE_EARPIECE);
+    }
+
+    /**
+     * Tests that DTMF Tones are sent from the {@link InCallService} to the
+     * {@link ConnectionService} in the correct sequence.
+     *
+     * @see {@link Call#playDtmfTone(char)}
+     * @see {@link Call#stopDtmfTone()}
+     */
+    public void testPlayAndStopDtmfTones() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+
+        assertDtmfString(connection, "");
+
+        call.playDtmfTone('1');
+        assertDtmfString(connection, "1");
+
+        call.playDtmfTone('2');
+        assertDtmfString(connection, "12");
+
+        call.stopDtmfTone();
+        assertDtmfString(connection, "12.");
+
+        call.playDtmfTone('3');
+        call.playDtmfTone('4');
+        call.playDtmfTone('5');
+        assertDtmfString(connection, "12.345");
+
+        call.stopDtmfTone();
+        assertDtmfString(connection, "12.345.");
+    }
+
+    public void testHoldAndUnholdCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+
+        assertCallState(call, Call.STATE_DIALING);
+
+        connection.setActive();
+
+        assertCallState(call, Call.STATE_ACTIVE);
+
+        call.hold();
+        assertCallState(call, Call.STATE_HOLDING);
+        assertEquals(Connection.STATE_HOLDING, connection.getState());
+
+        call.unhold();
+        assertCallState(call, Call.STATE_ACTIVE);
+        assertEquals(Connection.STATE_ACTIVE, connection.getState());
+    }
+
+    public void testAnswerIncomingCallAudioOnly() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        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.answer(VideoProfile.STATE_AUDIO_ONLY);
+
+        assertCallState(call, Call.STATE_ACTIVE);
+        assertConnectionState(connection, Connection.STATE_ACTIVE);
+    }
+
+    public void testAnswerIncomingCallAsVideo_SendsCorrectVideoState() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        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.answer(VideoProfile.STATE_BIDIRECTIONAL);
+
+        assertCallState(call, Call.STATE_ACTIVE);
+        assertConnectionState(connection, Connection.STATE_ACTIVE);
+        assertEquals("Connection did not receive VideoState for answered call",
+                VideoProfile.STATE_BIDIRECTIONAL, connection.videoState);
+    }
+
+    public void testRejectIncomingCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        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(false, null);
+
+        assertCallState(call, Call.STATE_DISCONNECTED);
+        assertConnectionState(connection, Connection.STATE_DISCONNECTED);
+    }
+
+    public void testCanAddCall_CannotAddForExistingDialingCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+
+        assertCanAddCall(inCallService, false,
+                "Should not be able to add call with existing dialing call");
+    }
+
+    public void testCanAddCall_CanAddForExistingActiveCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+
+        connection.setActive();
+
+        assertCallState(call, Call.STATE_ACTIVE);
+
+        assertCanAddCall(inCallService, true,
+                "Should be able to add call with only one active call");
+    }
+
+    public void testCanAddCall_CannotAddIfTooManyCalls() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection1 = verifyConnectionForOutgoingCall(0);
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call1 = inCallService.getLastCall();
+        assertCallState(call1, Call.STATE_DIALING);
+
+        connection1.setActive();
+
+        assertCallState(call1, Call.STATE_ACTIVE);
+
+        placeAndVerifyCall();
+        final MockConnection connection2 = verifyConnectionForOutgoingCall(1);
+
+        final Call call2 = inCallService.getLastCall();
+        assertCallState(call2, Call.STATE_DIALING);
+        connection2.setActive();
+        assertCallState(call2, Call.STATE_ACTIVE);
+
+        assertEquals("InCallService should have 2 calls", 2, inCallService.getCallCount());
+
+        assertCanAddCall(inCallService, false,
+                "Should not be able to add call with two calls already present");
+
+        call1.hold();
+        assertCallState(call1, Call.STATE_HOLDING);
+
+        assertCanAddCall(inCallService, false,
+                "Should not be able to add call with two calls already present");
+    }
+
+    public void testOnBringToForeground() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+
+        assertCallState(call, Call.STATE_DIALING);
+
+        assertEquals(0, mOnBringToForegroundCounter.getInvokeCount());
+
+        final TelecomManager tm =
+            (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+
+        tm.showInCallScreen(false);
+
+        mOnBringToForegroundCounter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+
+        assertFalse((Boolean) mOnBringToForegroundCounter.getArgs(0)[0]);
+
+        tm.showInCallScreen(true);
+
+        mOnBringToForegroundCounter.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+
+        assertTrue((Boolean) mOnBringToForegroundCounter.getArgs(1)[0]);
+    }
+
+    public void testOnPostDialWaitAndContinue() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+
+        connection.setActive();
+        assertCallState(call, Call.STATE_ACTIVE);
+
+        final String postDialString = "12345";
+        ((Connection) connection).setPostDialWait(postDialString);
+        mOnPostDialWaitCounter.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+
+        assertEquals(postDialString, mOnPostDialWaitCounter.getArgs(0)[1]);
+        assertEquals(postDialString, call.getRemainingPostDialSequence());
+
+        final InvokeCounter counter = connection.getInvokeCounter(MockConnection.ON_POST_DIAL_WAIT);
+
+        call.postDialContinue(true);
+        counter.waitForCount(1);
+        assertTrue((Boolean) counter.getArgs(0)[0]);
+
+        call.postDialContinue(false);
+        counter.waitForCount(2);
+        assertFalse((Boolean) counter.getArgs(1)[0]);
+    }
+
+    public void testOnCannedTextResponsesLoaded() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        verifyConnectionForIncomingCall();
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+
+        final Call call = inCallService.getLastCall();
+
+        assertCallState(call, Call.STATE_RINGING);
+
+        // We can't do much to enforce the number and type of responses that are preloaded on
+        // device, so the best we can do is to make sure that the call back is called and
+        // that the returned list is non-empty.
+
+        // This test should also verify that the callback is called as well, but unfortunately it
+        // is never called right now (b/22952515).
+        // mOnCannedTextResponsesLoadedCounter.waitForCount(1);
+
+        assertGetCannedTextResponsesNotEmpty(call);
+    }
+
+    public void testGetCalls() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection1 = verifyConnectionForOutgoingCall(0);
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call1 = inCallService.getLastCall();
+        assertCallState(call1, Call.STATE_DIALING);
+
+        connection1.setActive();
+
+        assertCallState(call1, Call.STATE_ACTIVE);
+
+        List<Call> calls = inCallService.getCalls();
+        assertEquals("InCallService.getCalls() should return list with 1 call.", 1, calls.size());
+        assertEquals(call1, calls.get(0));
+
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        verifyConnectionForIncomingCall();
+
+        final Call call2 = inCallService.getLastCall();
+        calls = inCallService.getCalls();
+        assertEquals("InCallService.getCalls() should return list with 2 calls.", 2, calls.size());
+        assertEquals(call1, calls.get(0));
+        assertEquals(call2, calls.get(1));
+    }
+
+    private void assertGetCannedTextResponsesNotEmpty(final Call call) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return true;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getCannedTextResponses() != null
+                                && !call.getCannedTextResponses().isEmpty();
+                    }
+
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call.getCannedTextResponses should not be empty");
+    }
+
+    private void assertCanAddCall(final InCallService inCallService, final boolean canAddCall,
+            String message) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return canAddCall;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return inCallService.canAddCall();
+                    }
+                },
+                WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                message
+        );
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConference.java b/tests/tests/telecom/src/android/telecom/cts/MockConference.java
new file mode 100644
index 0000000..647d039
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConference.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.telecom.Conference;
+import android.telecom.Connection;
+import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.RemoteConference;
+import android.telecom.TelecomManager;
+
+/**
+ * {@link Conference} subclass that immediately performs any state changes that are a result of
+ * callbacks sent from Telecom.
+ */
+public class MockConference extends Conference {
+
+    private RemoteConference mRemoteConference = null;
+    private String mDtmfString = "";
+
+    public MockConference(PhoneAccountHandle phoneAccount) {
+        super(phoneAccount);
+    }
+
+    public MockConference(MockConnection a, MockConnection b) {
+        super(a.getPhoneAccountHandle());
+        addConnection(a);
+        addConnection(b);
+        // a is the primary connection, so inherit the properties from it.
+        setConnectionCapabilities(a.getConnectionCapabilities());
+        setStatusHints(a.getStatusHints());
+        setExtras(a.getExtras());
+    }
+
+    @Override
+    public void onDisconnect() {
+        super.onDisconnect();
+        for (Connection c : getConnections()) {
+            c.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
+            c.destroy();
+        }
+        destroy();
+        if (mRemoteConference != null) {
+            mRemoteConference.disconnect();
+        }
+    }
+
+    @Override
+    public void onSeparate(Connection connection) {
+        super.onSeparate(connection);
+        if (getConnections().contains(connection)) {
+            removeConnection(connection);
+        }
+        if (mRemoteConference != null) {
+            mRemoteConference.separate(((MockConnection)connection).getRemoteConnection());
+        }
+    }
+
+    @Override
+    public void onMerge() {
+        super.onMerge();
+        // Let's just change the connection display name for testing that onMerge was invoked.
+        for (Connection c : getConnections()) {
+            c.setCallerDisplayName(
+                    TestUtils.MERGE_CALLER_NAME, TelecomManager.PRESENTATION_ALLOWED);
+        }
+        if (mRemoteConference != null) {
+            mRemoteConference.merge();
+        }
+    }
+
+    @Override
+    public void onSwap() {
+        super.onSwap();
+        // Let's just change the connection display name for testing that onSwap was invoked.
+        for (Connection c : getConnections()) {
+            c.setCallerDisplayName(
+                    TestUtils.SWAP_CALLER_NAME, TelecomManager.PRESENTATION_ALLOWED);
+        }
+        if (mRemoteConference != null) {
+            mRemoteConference.swap();
+        }
+    }
+
+    @Override
+    public void onHold() {
+        super.onHold();
+        for (Connection c : getConnections()) {
+            c.setOnHold();
+        }
+        setOnHold();
+        if (mRemoteConference != null) {
+            mRemoteConference.hold();
+        }
+    }
+
+    @Override
+    public void onUnhold() {
+        super.onUnhold();
+        for (Connection c : getConnections()) {
+            c.setActive();
+        }
+        setActive();
+        if (mRemoteConference != null) {
+            mRemoteConference.unhold();
+        }
+    }
+
+    @Override
+    public void onPlayDtmfTone(char c) {
+        super.onPlayDtmfTone(c);
+        mDtmfString += c;
+        if (mRemoteConference != null) {
+            mRemoteConference.playDtmfTone(c);
+        }
+    }
+
+    @Override
+    public void onStopDtmfTone() {
+        super.onStopDtmfTone();
+        mDtmfString += ".";
+        if (mRemoteConference != null) {
+            mRemoteConference.stopDtmfTone();
+        }
+    }
+
+    public void setRemoteConference(RemoteConference remoteConference) {
+        mRemoteConference = remoteConference;
+    }
+
+    public RemoteConference getRemoteConference() {
+        return mRemoteConference;
+    }
+
+    public String getDtmfString() {
+        return mDtmfString;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockConnection.java b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
new file mode 100644
index 0000000..9bb83a1
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnection.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.CallAudioState.*;
+import android.telecom.CallAudioState;
+import android.telecom.Connection;
+import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.RemoteConnection;
+import android.telecom.VideoProfile;
+import android.telecom.cts.BaseTelecomTestWithMockServices.InvokeCounter;
+import android.util.SparseArray;
+
+/**
+ * {@link Connection} subclass that immediately performs any state changes that are a result of
+ * callbacks sent from Telecom.
+ */
+public class MockConnection extends Connection {
+    public static final int ON_POST_DIAL_WAIT = 1;
+
+    private CallAudioState mCallAudioState =
+            new CallAudioState(false, CallAudioState.ROUTE_EARPIECE, ROUTE_EARPIECE | ROUTE_SPEAKER);
+    private int mState = STATE_NEW;
+    public int videoState = VideoProfile.STATE_AUDIO_ONLY;
+    private String mDtmfString = "";
+    private MockVideoProvider mMockVideoProvider;
+    private PhoneAccountHandle mPhoneAccountHandle;
+    private RemoteConnection mRemoteConnection = null;
+
+    private SparseArray<InvokeCounter> mInvokeCounterMap = new SparseArray<>(10);
+
+    @Override
+    public void onAnswer() {
+        super.onAnswer();
+    }
+
+    @Override
+    public void onAnswer(int videoState) {
+        super.onAnswer(videoState);
+        this.videoState = videoState;
+        setActive();
+        if (mRemoteConnection != null) {
+            mRemoteConnection.answer();
+        }
+    }
+
+    @Override
+    public void onReject() {
+        super.onReject();
+        setDisconnected(new DisconnectCause(DisconnectCause.REJECTED));
+        if (mRemoteConnection != null) {
+            mRemoteConnection.reject();
+        }
+        destroy();
+    }
+
+    @Override
+    public void onHold() {
+        super.onHold();
+        setOnHold();
+        if (mRemoteConnection != null) {
+            mRemoteConnection.hold();
+        }
+    }
+
+    @Override
+    public void onUnhold() {
+        super.onUnhold();
+        setActive();
+        if (mRemoteConnection != null) {
+            mRemoteConnection.unhold();
+        }
+    }
+
+    @Override
+    public void onDisconnect() {
+        super.onDisconnect();
+        setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
+        if (mRemoteConnection != null) {
+            mRemoteConnection.disconnect();
+        }
+        destroy();
+    }
+
+    @Override
+    public void onAbort() {
+        super.onAbort();
+        setDisconnected(new DisconnectCause(DisconnectCause.UNKNOWN));
+        if (mRemoteConnection != null) {
+            mRemoteConnection.abort();
+        }
+        destroy();
+    }
+
+    @Override
+    public void onPlayDtmfTone(char c) {
+        super.onPlayDtmfTone(c);
+        mDtmfString += c;
+        if (mRemoteConnection != null) {
+            mRemoteConnection.playDtmfTone(c);
+        }
+    }
+
+    @Override
+    public void onStopDtmfTone() {
+        super.onStopDtmfTone();
+        mDtmfString += ".";
+        if (mRemoteConnection != null) {
+            mRemoteConnection.stopDtmfTone();
+        }
+    }
+
+    @Override
+    public void onCallAudioStateChanged(CallAudioState state) {
+        super.onCallAudioStateChanged(state);
+        mCallAudioState = state;
+        if (mRemoteConnection != null) {
+            mRemoteConnection.setCallAudioState(state);
+        }
+    }
+
+    @Override
+    public void onStateChanged(int state) {
+        super.onStateChanged(state);
+        mState = state;
+    }
+
+    @Override
+    public void onPostDialContinue(boolean proceed) {
+        super.onPostDialContinue(proceed);
+        if (mInvokeCounterMap.get(ON_POST_DIAL_WAIT) != null) {
+            mInvokeCounterMap.get(ON_POST_DIAL_WAIT).invoke(proceed);
+        }
+    }
+
+    public int getCurrentState()  {
+        return mState;
+    }
+
+    public CallAudioState getCurrentCallAudioState() {
+        return mCallAudioState;
+    }
+
+    public String getDtmfString() {
+        return mDtmfString;
+    }
+
+    public InvokeCounter getInvokeCounter(int counterIndex) {
+        if (mInvokeCounterMap.get(counterIndex) == null) {
+            mInvokeCounterMap.put(counterIndex,
+                    new InvokeCounter(getCounterLabel(counterIndex)));
+        }
+        return mInvokeCounterMap.get(counterIndex);
+    }
+
+    /**
+     * Creates a mock video provider for this connection.
+     */
+    public void createMockVideoProvider() {
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(this);
+        mMockVideoProvider = mockVideoProvider;
+        setVideoProvider(mockVideoProvider);
+    }
+
+    public void sendMockVideoQuality(int videoQuality) {
+        if (mMockVideoProvider == null) {
+            return;
+        }
+        mMockVideoProvider.sendMockVideoQuality(videoQuality);
+    }
+
+    public void sendMockCallSessionEvent(int event) {
+        if (mMockVideoProvider == null) {
+            return;
+        }
+        mMockVideoProvider.sendMockCallSessionEvent(event);
+    }
+
+    public void sendMockPeerWidth(int width) {
+        if (mMockVideoProvider == null) {
+            return;
+        }
+        mMockVideoProvider.sendMockPeerWidth(width);
+    }
+
+    public void sendMockSessionModifyRequest(VideoProfile request) {
+        if (mMockVideoProvider == null) {
+            return;
+        }
+        mMockVideoProvider.sendMockSessionModifyRequest(request);
+    }
+
+    public MockVideoProvider getMockVideoProvider() {
+        return mMockVideoProvider;
+    }
+
+    public void setPhoneAccountHandle(PhoneAccountHandle handle)  {
+        mPhoneAccountHandle = handle;
+    }
+
+    public PhoneAccountHandle getPhoneAccountHandle()  {
+        return mPhoneAccountHandle;
+    }
+
+    public void setRemoteConnection(RemoteConnection remoteConnection)  {
+        mRemoteConnection = remoteConnection;
+    }
+
+    public RemoteConnection getRemoteConnection()  {
+        return mRemoteConnection;
+    }
+
+    private static String getCounterLabel(int counterIndex) {
+        switch (counterIndex) {
+            case ON_POST_DIAL_WAIT:
+                return "onPostDialWait";
+            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
new file mode 100644
index 0000000..ad64e5c
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/MockConnectionService.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.ConnectionService;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.RemoteConference;
+import android.telecom.RemoteConnection;
+import android.telecom.TelecomManager;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Semaphore;
+
+/**
+ * Default implementation of a {@link CtsConnectionService}. This is used for the majority
+ * of Telecom CTS tests that simply require that a outgoing call is placed, or incoming call is
+ * received.
+ */
+public class MockConnectionService extends ConnectionService {
+    public static final int CONNECTION_PRESENTATION =  TelecomManager.PRESENTATION_ALLOWED;
+
+    /**
+     * Used to control whether the {@link MockVideoProvider} will be created when connections are
+     * created.  Used by {@link VideoCallTest#testVideoCallDelayProvider()} to test scenario where
+     * the {@link MockVideoProvider} is not created immediately when the Connection is created.
+     */
+    private boolean mCreateVideoProvider = true;
+
+    public Semaphore lock = new Semaphore(0);
+    public List<MockConnection> outgoingConnections = new ArrayList<MockConnection>();
+    public List<MockConnection> incomingConnections = new ArrayList<MockConnection>();
+    public List<RemoteConnection> remoteConnections = new ArrayList<RemoteConnection>();
+    public List<MockConference> conferences = new ArrayList<MockConference>();
+    public List<RemoteConference> remoteConferences = new ArrayList<RemoteConference>();
+
+    @Override
+    public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        final MockConnection connection = new MockConnection();
+        connection.setAddress(request.getAddress(), CONNECTION_PRESENTATION);
+        connection.setPhoneAccountHandle(connectionManagerPhoneAccount);
+        if (mCreateVideoProvider) {
+            connection.createMockVideoProvider();
+        } else {
+            mCreateVideoProvider = true;
+        }
+        connection.setVideoState(request.getVideoState());
+
+        outgoingConnections.add(connection);
+        lock.release();
+        return connection;
+    }
+
+    @Override
+    public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount,
+            ConnectionRequest request) {
+        final MockConnection connection = new MockConnection();
+        connection.setAddress(request.getAddress(), CONNECTION_PRESENTATION);
+        connection.createMockVideoProvider();
+        ((Connection) connection).setVideoState(request.getVideoState());
+
+        incomingConnections.add(connection);
+        lock.release();
+        return connection;
+    }
+
+    @Override
+    public void onConference(Connection connection1, Connection connection2) {
+        // Make sure that these connections are already not conferenced.
+        if (connection1.getConference() == null && connection2.getConference() == null) {
+            MockConference conference = new MockConference(
+                    (MockConnection)connection1, (MockConnection)connection2);
+            CtsConnectionService.addConferenceToTelecom(conference);
+            conferences.add(conference);
+            lock.release();
+        }
+    }
+
+    @Override
+    public void onRemoteExistingConnectionAdded(RemoteConnection connection) {
+        // Keep track of the remote connections added to the service
+        remoteConnections.add(connection);
+    }
+
+    @Override
+    public void onRemoteConferenceAdded(RemoteConference conference) {
+        // Keep track of the remote connections added to the service
+        remoteConferences.add(conference);
+    }
+
+    public void setCreateVideoProvider(boolean createVideoProvider) {
+        mCreateVideoProvider = createVideoProvider;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
new file mode 100644
index 0000000..0f1f538
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/MockInCallService.java
@@ -0,0 +1,335 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Intent;
+import android.telecom.Call;
+import android.telecom.CallAudioState;
+import android.telecom.InCallService;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+
+public class MockInCallService extends InCallService {
+    private static String LOG_TAG = "MockInCallService";
+    private ArrayList<Call> mCalls = new ArrayList<>();
+    private ArrayList<Call> mConferenceCalls = new ArrayList<>();
+    private static InCallServiceCallbacks sCallbacks;
+    private Map<Call, MockVideoCallCallback> mVideoCallCallbacks =
+            new ArrayMap<Call, MockVideoCallCallback>();
+
+    private static final Object sLock = new Object();
+    private static boolean mIsServiceUnbound;
+
+    public static abstract class InCallServiceCallbacks {
+        private MockInCallService mService;
+        public Semaphore lock = new Semaphore(0);
+
+        public void onCallAdded(Call call, int numCalls) {};
+        public void onCallRemoved(Call call, int numCalls) {};
+        public void onCallStateChanged(Call call, int state) {};
+        public void onParentChanged(Call call, Call parent) {};
+        public void onChildrenChanged(Call call, List<Call> children) {};
+        public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {};
+        public void onCallDestroyed(Call call) {};
+        public void onDetailsChanged(Call call, Call.Details details) {};
+        public void onCanAddCallsChanged(boolean canAddCalls) {}
+        public void onBringToForeground(boolean showDialpad) {}
+        public void onCallAudioStateChanged(CallAudioState audioState) {}
+        public void onPostDialWait(Call call, String remainingPostDialSequence) {}
+        public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {}
+
+        final public MockInCallService getService() {
+            return mService;
+        }
+
+        final public void setService(MockInCallService service) {
+            mService = service;
+        }
+    }
+
+    /**
+     * Note that the super implementations of the callback methods are all no-ops, but we call
+     * them anyway to make sure that the CTS coverage tool detects that we are testing them.
+     */
+    private Call.Callback mCallCallback = new Call.Callback() {
+        @Override
+        public void onStateChanged(Call call, int state) {
+            super.onStateChanged(call, state);
+            if (getCallbacks() != null) {
+                getCallbacks().onCallStateChanged(call, state);
+            }
+        }
+
+        @Override
+        public void onVideoCallChanged(Call call, InCallService.VideoCall videoCall) {
+            super.onVideoCallChanged(call, videoCall);
+            saveVideoCall(call, videoCall);
+        }
+
+        @Override
+        public void onParentChanged(Call call, Call parent) {
+            super.onParentChanged(call, parent);
+            if (getCallbacks() != null) {
+                getCallbacks().onParentChanged(call, parent);
+            }
+        }
+
+        @Override
+        public void onChildrenChanged(Call call, List<Call> children) {
+            super.onChildrenChanged(call, children);
+            if (getCallbacks() != null) {
+                getCallbacks().onChildrenChanged(call, children);
+            }
+        }
+
+        @Override
+        public void onConferenceableCallsChanged(Call call, List<Call> conferenceableCalls) {
+            super.onConferenceableCallsChanged(call, conferenceableCalls);
+            if (getCallbacks() != null) {
+                getCallbacks().onConferenceableCallsChanged(call, conferenceableCalls);
+            }
+        }
+
+        @Override
+        public void onCallDestroyed(Call call) {
+            super.onCallDestroyed(call);
+            if (getCallbacks() != null) {
+                getCallbacks().onCallDestroyed(call);
+            }
+        }
+
+        @Override
+        public void onDetailsChanged(Call call, Call.Details details) {
+            super.onDetailsChanged(call, details);
+            if (getCallbacks() != null) {
+                getCallbacks().onDetailsChanged(call, details);
+            }
+        }
+
+        @Override
+        public void onPostDialWait(Call call, String remainingPostDialSequence) {
+            super.onPostDialWait(call, remainingPostDialSequence);
+            if (getCallbacks() != null) {
+                getCallbacks().onPostDialWait(call, remainingPostDialSequence);
+            }
+        }
+
+        @Override
+        public void onCannedTextResponsesLoaded(Call call, List<String> cannedTextResponses) {
+            super.onCannedTextResponsesLoaded(call, cannedTextResponses);
+            if (getCallbacks() != null) {
+                getCallbacks().onCannedTextResponsesLoaded(call, cannedTextResponses);
+            }
+        }
+    };
+
+    private void saveVideoCall(Call call, VideoCall videoCall) {
+        if (videoCall != null) {
+            if (!mVideoCallCallbacks.containsKey(call)) {
+                MockVideoCallCallback listener = new MockVideoCallCallback(call);
+                videoCall.registerCallback(listener);
+                mVideoCallCallbacks.put(call, listener);
+            }
+        } else {
+            mVideoCallCallbacks.remove(call);
+        }
+    }
+
+    @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 onCallAdded(Call call) {
+        super.onCallAdded(call);
+        if (call.getDetails().hasProperty(Call.Details.PROPERTY_CONFERENCE) == true) {
+            if (!mConferenceCalls.contains(call)) {
+                mConferenceCalls.add(call);
+                call.registerCallback(mCallCallback);
+            }
+        } else {
+            if (!mCalls.contains(call)) {
+                mCalls.add(call);
+                call.registerCallback(mCallCallback);
+                VideoCall videoCall = call.getVideoCall();
+                if (videoCall != null) {
+                    saveVideoCall(call, videoCall);
+                }
+            }
+        }
+        if (getCallbacks() != null) {
+            getCallbacks().onCallAdded(call, mCalls.size() + mConferenceCalls.size());
+        }
+    }
+
+    @Override
+    public void onCallRemoved(Call call) {
+        super.onCallRemoved(call);
+        if (call.getDetails().hasProperty(Call.Details.PROPERTY_CONFERENCE) == true) {
+            mConferenceCalls.remove(call);
+        } else {
+            mCalls.remove(call);
+        }
+        if (getCallbacks() != null) {
+            getCallbacks().onCallRemoved(call, mCalls.size() + mConferenceCalls.size());
+            saveVideoCall(call, null /* remove videoCall */);
+        }
+    }
+
+    @Override
+    public void onCanAddCallChanged(boolean canAddCall) {
+        super.onCanAddCallChanged(canAddCall);
+        if (getCallbacks() != null) {
+            getCallbacks().onCanAddCallsChanged(canAddCall);
+        }
+    }
+
+    @Override
+    public void onBringToForeground(boolean showDialpad) {
+        super.onBringToForeground(showDialpad);
+        if (getCallbacks() != null) {
+            getCallbacks().onBringToForeground(showDialpad);
+        }
+    }
+
+    @Override
+    public void onCallAudioStateChanged(CallAudioState audioState) {
+        super.onCallAudioStateChanged(audioState);
+        if (getCallbacks() != null) {
+            getCallbacks().onCallAudioStateChanged(audioState);
+        }
+    }
+
+    /**
+     * @return the number of calls currently added to the {@code InCallService}.
+     */
+    public int getCallCount() {
+        return mCalls.size();
+    }
+
+    /**
+     * @return the number of conference calls currently added to the {@code InCallService}.
+     */
+    public int getConferenceCallCount() {
+        return mConferenceCalls.size();
+    }
+
+    /**
+     * @return the most recently added call that exists inside the {@code InCallService}
+     */
+    public Call getLastCall() {
+        if (!mCalls.isEmpty()) {
+            return mCalls.get(mCalls.size() - 1);
+        }
+        return null;
+    }
+
+    /**
+     * @return the most recently added conference call that exists inside the {@code InCallService}
+     */
+    public Call getLastConferenceCall() {
+        if (!mConferenceCalls.isEmpty()) {
+            return mConferenceCalls.get(mConferenceCalls.size() - 1);
+        }
+        return null;
+    }
+
+    public void disconnectLastCall() {
+        final Call call = getLastCall();
+        if (call != null) {
+            call.disconnect();
+        }
+    }
+
+    public void disconnectLastConferenceCall() {
+        final Call call = getLastConferenceCall();
+        if (call != null) {
+            call.disconnect();
+        }
+    }
+
+    public void disconnectAllCalls() {
+        for (final Call call: mCalls) {
+            call.disconnect();
+        }
+    }
+
+    public void disconnectAllConferenceCalls() {
+        for (final Call call: mConferenceCalls) {
+            call.disconnect();
+        }
+    }
+
+    public static void setCallbacks(InCallServiceCallbacks callbacks) {
+        synchronized (sLock) {
+            sCallbacks = callbacks;
+        }
+    }
+
+    private InCallServiceCallbacks getCallbacks() {
+        synchronized (sLock) {
+            if (sCallbacks != null) {
+                sCallbacks.setService(this);
+            }
+            return sCallbacks;
+        }
+    }
+
+    /**
+     * Determines if a video callback has been registered for the passed in call.
+     *
+     * @param call The call.
+     * @return {@code true} if a video callback has been registered.
+     */
+    public boolean isVideoCallbackRegistered(Call call) {
+        return mVideoCallCallbacks.containsKey(call);
+    }
+
+    /**
+     * Retrieves the video callbacks associated with a call.
+     * @param call The call.
+     * @return The {@link MockVideoCallCallback} instance associated with the call.
+     */
+    public MockVideoCallCallback getVideoCallCallback(Call call) {
+        return mVideoCallCallbacks.get(call);
+    }
+
+    @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;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockVideoCallCallback.java b/tests/tests/telecom/src/android/telecom/cts/MockVideoCallCallback.java
new file mode 100644
index 0000000..07e159c
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/MockVideoCallCallback.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.telecom.Call;
+import android.telecom.InCallService;
+import android.telecom.VideoProfile;
+import android.telecom.VideoProfile.CameraCapabilities;
+
+/**
+ * Mock video call Callback class.
+ */
+public class MockVideoCallCallback extends InCallService.VideoCall.Callback {
+    private Call mCall;
+    private CameraCapabilities mCameraCapabilities;
+    private long mDataUsage = MockVideoProvider.DATA_USAGE_UNDEFINED;
+    private int mVideoQuality = MockVideoProvider.VIDEO_QUALITY_UNDEFINED;
+    private int mCallSessionEvent = MockVideoProvider.SESSION_EVENT_UNDEFINED;
+    private int mPeerWidth = MockVideoProvider.PEER_WIDTH_UNDEFINED;
+    private VideoProfile mResponseProfile = null;
+    private VideoProfile mRequestProfile = null;
+
+    public MockVideoCallCallback(Call call) {
+        mCall = call;
+    }
+
+    /**
+     * Store incoming session modify request so tests can inspect it.
+     *
+     * @param videoProfile The requested video profile.
+     */
+    @Override
+    public void onSessionModifyRequestReceived(VideoProfile videoProfile) {
+        mRequestProfile = videoProfile;
+    }
+
+    /**
+     * Store incoming session modify response so tests can inspect it.
+     *
+     * @param status Status of the session modify request.
+     * @param requestedProfile The original request which was sent to the peer device.
+     * @param responseProfile The actual profile changes made by the peer device.
+     */
+    @Override
+    public void onSessionModifyResponseReceived(int status, VideoProfile requestedProfile,
+            VideoProfile responseProfile) {
+        mResponseProfile = responseProfile;
+    }
+
+    /**
+     * Store incoming session event so tests can inspect it.
+     *
+     * @param event The event.
+     */
+    @Override
+    public void onCallSessionEvent(int event) {
+        mCallSessionEvent = event;
+    }
+
+    /**
+     * Store incoming peer dimensions so tests can inspect them.
+     *
+     * @param width  The updated peer video width.
+     * @param height The updated peer video height.
+     */
+    @Override
+    public void onPeerDimensionsChanged(int width, int height) {
+        mPeerWidth = width;
+    }
+
+    /**
+     * Store incoming video quality so tests can inspect them.
+     *
+     * @param videoQuality  The updated peer video quality.  Valid values:
+     *      {@link VideoProfile#QUALITY_HIGH},
+     *      {@link VideoProfile#QUALITY_MEDIUM},
+     *      {@link VideoProfile#QUALITY_LOW},
+     */
+    @Override
+    public void onVideoQualityChanged(int videoQuality) {
+        mVideoQuality = videoQuality;
+    }
+
+    /**
+     * Store incoming call data usage so tests can inspect it.
+     *
+     * @param dataUsage The updated data usage (in bytes).
+     */
+    @Override
+    public void onCallDataUsageChanged(long dataUsage) {
+        mDataUsage = dataUsage;
+    }
+
+    /**
+     * Store incoming camera capabilities so tests can inspect them.
+     *
+     * @param cameraCapabilities The changed camera capabilities.
+     */
+    @Override
+    public void onCameraCapabilitiesChanged(CameraCapabilities cameraCapabilities) {
+        mCameraCapabilities = cameraCapabilities;
+    }
+
+    /**
+     * Returns the last received {@link CameraCapabilities}.
+     *
+     * @return The {@link CameraCapabilities}.
+     */
+    public CameraCapabilities getCameraCapabilities() {
+        return mCameraCapabilities;
+    }
+
+    /**
+     * Returns the last received data usage.
+     *
+     * @return The data usage.
+     */
+    public long getDataUsage() {
+        return mDataUsage;
+    }
+
+    /**
+     * Returns the last received video quality.
+     *
+     * @return The video quality.
+     */
+    public int getVideoQuality()
+    {
+        return mVideoQuality;
+    }
+
+    /**
+     * Returns the last received call session event.
+     *
+     * @return The call session event.
+     */
+    public int getCallSessionEvent()
+    {
+        return mCallSessionEvent;
+    }
+
+    /**
+     * Returns the last received peer width.
+     *
+     * @return The call session event.
+     */
+    public int getPeerWidth()
+    {
+        return mPeerWidth;
+    }
+
+    /**
+     * Returns the last received response video profile.
+     *
+     * @return The video profile.
+     */
+    public VideoProfile getResponseProfile() {
+        return mResponseProfile;
+    }
+
+    /**
+     * Returns the last requested video profile.
+     *
+     * @return The video profile.
+     */
+    public VideoProfile getRequestProfile() {
+        return mRequestProfile;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/MockVideoProvider.java b/tests/tests/telecom/src/android/telecom/cts/MockVideoProvider.java
new file mode 100644
index 0000000..a1b6b65
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/MockVideoProvider.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.net.Uri;
+import android.telecom.Connection;
+import android.telecom.VideoProfile;
+import android.view.Surface;
+
+import android.telecom.Connection.VideoProvider;
+
+/**
+ * Implements a mock video provider implementation.
+ */
+public class MockVideoProvider extends VideoProvider {
+    public static final String CAMERA_NONE = "none";
+    public static final String CAMERA_FRONT = "front";
+    public static final String CAMERA_BACK = "back";
+    public static final int CAMERA_FRONT_DIMENSIONS = 1024;
+    public static final int CAMERA_BACK_DIMENSIONS = 2048;
+    public static final long DATA_USAGE = 1024;
+    public static final long DATA_USAGE_UNDEFINED = -1;
+    public static final int VIDEO_QUALITY_UNDEFINED = -1;
+    public static final int SESSION_EVENT_UNDEFINED = -1;
+    public static final int PEER_WIDTH_UNDEFINED = -1;
+    public static final int DEVICE_ORIENTATION_UNDEFINED = -1;
+    public static final float ZOOM_UNDEFINED = -1.0f;
+
+    private Uri mPauseImageUri;
+    private String mCameraId = CAMERA_NONE;
+    private MockConnection mMockConnection;
+    private int mDeviceOrientation = DEVICE_ORIENTATION_UNDEFINED;
+    private float mZoom = ZOOM_UNDEFINED;
+    private Surface mPreviewSurface = null;
+    private Surface mDisplaySurface = null;
+    private VideoProfile mSessionModifyResponse = null;
+
+    public MockVideoProvider(MockConnection mockConnection) {
+        mMockConnection = mockConnection;
+    }
+
+    @Override
+    public void onSetCamera(String cameraId) {
+        handleCameraChange(cameraId);
+    }
+
+    @Override
+    public void onSetPreviewSurface(Surface surface) {
+        mPreviewSurface = surface;
+    }
+
+    @Override
+    public void onSetDisplaySurface(Surface surface) {
+        mDisplaySurface = surface;
+    }
+
+    @Override
+    public void onSetDeviceOrientation(int rotation) {
+        mDeviceOrientation = rotation;
+    }
+
+    @Override
+    public void onSetZoom(float value) {
+        mZoom = value;
+    }
+
+    /**
+     * Handles a session modification request from the {@link MockInCallService}. Assumes the peer
+     * has accepted the proposed video profile.
+     *
+     * @param fromProfile The video properties prior to the request.
+     * @param toProfile The video properties with the requested changes made.
+     */
+    @Override
+    public void onSendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
+        super.receiveSessionModifyResponse(Connection.VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS,
+                toProfile, toProfile);
+        mMockConnection.setVideoState(toProfile.getVideoState());
+    }
+
+    @Override
+    public void onSendSessionModifyResponse(VideoProfile responseProfile) {
+        mSessionModifyResponse = responseProfile;
+    }
+
+    /**
+     * Responds with the current camera capabilities.
+     */
+    @Override
+    public void onRequestCameraCapabilities() {
+        handleCameraChange(mCameraId);
+    }
+
+    /**
+     * Handles requests to retrieve the connection data usage by returning a fixed usage amount of
+     * {@code 1024} bytes.
+     */
+    @Override
+    public void onRequestConnectionDataUsage() {
+        super.setCallDataUsage(DATA_USAGE);
+    }
+
+    @Override
+    public void onSetPauseImage(Uri uri) {
+        mPauseImageUri = uri;
+    }
+
+    /**
+     * Handles a change to the current camera selection.  Responds by reporting the capabilities of
+     * the camera.
+     */
+    private void handleCameraChange(String cameraId) {
+        mCameraId = cameraId;
+        if (CAMERA_FRONT.equals(mCameraId)) {
+            super.changeCameraCapabilities(new VideoProfile.CameraCapabilities(
+                    CAMERA_FRONT_DIMENSIONS, CAMERA_FRONT_DIMENSIONS));
+        } else if (CAMERA_BACK.equals(mCameraId)) {
+            super.changeCameraCapabilities(new VideoProfile.CameraCapabilities(
+                    CAMERA_BACK_DIMENSIONS, CAMERA_BACK_DIMENSIONS));
+        }
+    }
+
+    /**
+     * Sends a mock video quality value from the provider.
+     *
+     * @param videoQuality The video quality.
+     */
+    public void sendMockVideoQuality(int videoQuality) {
+        super.changeVideoQuality(videoQuality);
+    }
+
+    /**
+     * Sends a mock call session event from the provider.
+     *
+     * @param event The call session event.
+     */
+    public void sendMockCallSessionEvent(int event) {
+        super.handleCallSessionEvent(event);
+    }
+
+    /**
+     * Sends a mock peer width from the provider.
+     *
+     * @param width The peer width.
+     */
+    public void sendMockPeerWidth(int width) {
+        super.changePeerDimensions(width, width);
+    }
+
+    /**
+     * Sends a mock session modify request from the provider.
+     *
+     * @param request The requested profile.
+     */
+    public void sendMockSessionModifyRequest(VideoProfile request) {
+        super.receiveSessionModifyRequest(request);
+    }
+
+    public int getDeviceOrientation() {
+        return mDeviceOrientation;
+    }
+
+    public float getZoom() {
+        return mZoom;
+    }
+
+    public Surface getPreviewSurface() {
+        return mPreviewSurface;
+    }
+
+    public Surface getDisplaySurface() {
+        return mDisplaySurface;
+    }
+
+    public VideoProfile getSessionModifyResponse() {
+        return mSessionModifyResponse;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/NumberDialingTest.java b/tests/tests/telecom/src/android/telecom/cts/NumberDialingTest.java
new file mode 100644
index 0000000..e95a290
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NumberDialingTest.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.telecom.cts;
+
+import static android.telecom.cts.TestUtils.shouldTestTelecom;
+
+import android.net.Uri;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+
+/**
+ * Tests that certain numbers make their way through to the connection service.
+ */
+public class NumberDialingTest extends BaseTelecomTestWithMockServices {
+
+    /**
+     * Amount of time to wait for an asynchronous method invocation to ConnectionService.
+     */
+    private static final int CS_WAIT_MILLIS = 2000;
+
+    public void testEndInPound() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final Object[] res = new Object[1];
+        Uri address = Uri.fromParts("tel", "*1234#", null);
+
+        PhoneAccount account = setupConnectionService(
+                new MockConnectionService() {
+                    @Override
+                    public Connection onCreateOutgoingConnection(
+                            PhoneAccountHandle connectionManagerPhoneAccount,
+                            ConnectionRequest request) {
+                        res[0] = request.getAddress();
+                        synchronized(res) {
+                            res.notify();
+                        }
+                        return null;  // do not actually place the call.
+                    }
+
+                }, FLAG_REGISTER | FLAG_ENABLE);
+
+        startCallTo(address, account.getAccountHandle());
+        synchronized(res) {
+            res.wait(CS_WAIT_MILLIS);
+        }
+        assertEquals(address, res[0]);
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.java
new file mode 100644
index 0000000..fa19751
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/OutgoingCallTest.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.telecom.cts;
+
+import static android.telecom.cts.TestUtils.shouldTestTelecom;
+
+import android.content.Context;
+import android.media.AudioManager;
+import android.os.Bundle;
+import android.telecom.CallAudioState;
+import android.telecom.TelecomManager;
+
+/**
+ * Verifies the behavior of Telecom during various outgoing call flows.
+ */
+public class OutgoingCallTest extends BaseTelecomTestWithMockServices {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mShouldTestTelecom) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
+    /* TODO: Need to send some commands to the UserManager via adb to do setup
+    public void testDisallowOutgoingCallsForSecondaryUser() {
+    } */
+
+    /* TODO: Need to figure out a way to mock emergency calls without adb root
+    public void testOutgoingCallBroadcast_isSentForAllCalls() {
+    } */
+
+    /**
+     * Verifies that providing the EXTRA_START_CALL_WITH_SPEAKERPHONE extra starts the call with
+     * speakerphone automatically enabled.
+     *
+     * @see {@link TelecomManager#EXTRA_START_CALL_WITH_SPEAKERPHONE}
+     */
+    public void testStartCallWithSpeakerphoneTrue_SpeakerphoneOnInCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final Bundle extras = new Bundle();
+        extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true);
+        placeAndVerifyCall(extras);
+        verifyConnectionForOutgoingCall();
+        assertAudioRoute(mInCallCallbacks.getService(), CallAudioState.ROUTE_SPEAKER);
+    }
+
+    public void testStartCallWithSpeakerphoneFalse_SpeakerphoneOffInCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final Bundle extras = new Bundle();
+        extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false);
+        placeAndVerifyCall(extras);
+        verifyConnectionForOutgoingCall();
+        assertNotAudioRoute(mInCallCallbacks.getService(), CallAudioState.ROUTE_SPEAKER);
+    }
+
+    public void testStartCallWithSpeakerphoneNotProvided_SpeakerphoneOffByDefault() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+
+        placeAndVerifyCall();
+        verifyConnectionForOutgoingCall();
+        assertNotAudioRoute(mInCallCallbacks.getService(), CallAudioState.ROUTE_SPEAKER);
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java
new file mode 100644
index 0000000..cc03288
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/PhoneAccountOperationsTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.Color;
+import android.net.Uri;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.test.InstrumentationTestCase;
+
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+
+/**
+ * Verifies some of the PhoneAccount registration related operations.
+ */
+public class PhoneAccountOperationsTest extends InstrumentationTestCase {
+    public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE =
+            new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID);
+
+    public static final PhoneAccount TEST_SIM_PHONE_ACCOUNT = PhoneAccount.builder(
+            TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+            .setAddress(Uri.parse("tel:555-TEST"))
+            .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
+            .setCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION)
+            .setHighlightColor(Color.RED)
+            .setShortDescription(ACCOUNT_LABEL)
+            .setSupportedUriSchemes(Arrays.asList(PhoneAccount.SCHEME_TEL))
+            .build();
+
+    public static final PhoneAccount TEST_NO_SIM_PHONE_ACCOUNT = PhoneAccount.builder(
+            TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+            .setAddress(Uri.parse("tel:555-TEST"))
+            .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
+            .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+                    PhoneAccount.CAPABILITY_VIDEO_CALLING)
+            .setHighlightColor(Color.RED)
+            .setShortDescription(ACCOUNT_LABEL)
+            .setSupportedUriSchemes(Arrays.asList(
+                    PhoneAccount.SCHEME_TEL, PhoneAccount.SCHEME_VOICEMAIL))
+            .build();
+
+    public static final PhoneAccount TEST_CALL_MANAGER_PHONE_ACCOUNT = PhoneAccount.builder(
+            TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+            .setAddress(Uri.parse("tel:555-TEST"))
+            .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
+            .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+                    PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
+            .setHighlightColor(Color.RED)
+            .setShortDescription(ACCOUNT_LABEL)
+            .setSupportedUriSchemes(Arrays.asList(
+                    PhoneAccount.SCHEME_TEL, PhoneAccount.SCHEME_VOICEMAIL))
+            .build();
+
+    private Context mContext;
+    private TelecomManager mTelecomManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        mTelecomManager.unregisterPhoneAccount(TEST_PHONE_ACCOUNT_HANDLE);
+        PhoneAccount retrievedPhoneAccount = mTelecomManager.getPhoneAccount(
+                TEST_PHONE_ACCOUNT_HANDLE);
+        assertNull("Test account not deregistered.", retrievedPhoneAccount);
+        super.tearDown();
+    }
+
+    public void testRegisterPhoneAccount_correctlyThrowsSecurityException() throws Exception {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+        try {
+            mTelecomManager.registerPhoneAccount(TEST_SIM_PHONE_ACCOUNT);
+            fail("TelecomManager.registerPhoneAccount should throw SecurityException if "
+                    + "not a system app.");
+        } catch (SecurityException e) {
+            assertTrue("Unexpected security exception.", (e.getMessage().indexOf(
+                    "android.permission.REGISTER_SIM_SUBSCRIPTION") >= 0));
+        }
+    }
+
+    public void testRegisterPhoneAccount_NotEnabledAutomatically() throws Exception {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+        mTelecomManager.registerPhoneAccount(TEST_NO_SIM_PHONE_ACCOUNT);
+        PhoneAccount retrievedPhoneAccount = mTelecomManager.getPhoneAccount(
+                TEST_PHONE_ACCOUNT_HANDLE);
+        assertNotNull("Failed to retrieve test account.", retrievedPhoneAccount);
+        assertFalse("Phone account should not be automatically enabled.",
+                retrievedPhoneAccount.isEnabled());
+    }
+
+    public void testRegisterPhoneAccount_DisallowEnable() throws Exception {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+        Method setIsEnabled = null;
+        PhoneAccount.Builder phoneAccountBuilder = PhoneAccount.builder(
+                TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+                .setAddress(Uri.parse("tel:555-TEST"))
+                .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
+                .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+                .setHighlightColor(Color.RED)
+                .setShortDescription(ACCOUNT_LABEL)
+                .setSupportedUriSchemes(Arrays.asList("tel"));
+        try {
+            setIsEnabled = PhoneAccount.Builder.class.getDeclaredMethod(
+                    "setIsEnabled", boolean.class);
+        } catch (NoSuchMethodException e) {
+            fail("Failed to find setIsEnabled method.");
+        }
+        setIsEnabled.invoke(phoneAccountBuilder, true);
+        final PhoneAccount phoneAccount  = phoneAccountBuilder.build();
+        mTelecomManager.registerPhoneAccount(phoneAccount);
+        PhoneAccount retrievedPhoneAccount = mTelecomManager.getPhoneAccount(
+                TEST_PHONE_ACCOUNT_HANDLE);
+        assertNotNull("Failed to retrieve test account.", retrievedPhoneAccount);
+        assertFalse("3rd party app cannot enable its own phone account.",
+                retrievedPhoneAccount.isEnabled());
+    }
+
+    public void testRegisterPhoneAccount_ListEnabledAccounts() throws Exception {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+        mTelecomManager.registerPhoneAccount(TEST_NO_SIM_PHONE_ACCOUNT);
+        final List<PhoneAccountHandle> oldAccounts = mTelecomManager.getCallCapablePhoneAccounts();
+        final int oldAccountsListSize = oldAccounts.size();
+        if (oldAccountsListSize > 0) {
+            assertFalse("Enabled Phone accounts should not contain the test account.",
+                    oldAccounts.contains(TEST_PHONE_ACCOUNT_HANDLE));
+        }
+        TestUtils.enablePhoneAccount(getInstrumentation(), TEST_PHONE_ACCOUNT_HANDLE);
+        final List<PhoneAccountHandle> newAccounts = mTelecomManager.getCallCapablePhoneAccounts();
+        assertNotNull("No enabled Phone account found.", newAccounts);
+        assertEquals("1 new enabled Phone account expected.", newAccounts.size(),
+                oldAccountsListSize + 1);
+        assertTrue("Enabled Phone accounts do not contain the test account.",
+                newAccounts.contains(TEST_PHONE_ACCOUNT_HANDLE));
+    }
+
+    public void testRegisterPhoneAccount_CheckCapabilities() throws Exception {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+        mTelecomManager.registerPhoneAccount(TEST_NO_SIM_PHONE_ACCOUNT);
+        PhoneAccount retrievedPhoneAccount = mTelecomManager.getPhoneAccount(
+                TEST_PHONE_ACCOUNT_HANDLE);
+        assertTrue("Phone account should have call provider & video calling capability.",
+                retrievedPhoneAccount.hasCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
+                        PhoneAccount.CAPABILITY_VIDEO_CALLING));
+    }
+
+    public void testRegisterPhoneAccount_CheckURISchemeSupported() throws Exception {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+        mTelecomManager.registerPhoneAccount(TEST_NO_SIM_PHONE_ACCOUNT);
+        PhoneAccount retrievedPhoneAccount = mTelecomManager.getPhoneAccount(
+                TEST_PHONE_ACCOUNT_HANDLE);
+        assertTrue("Phone account should support tel URI scheme.",
+                retrievedPhoneAccount.supportsUriScheme(PhoneAccount.SCHEME_TEL));
+        assertTrue("Phone account should support voicemail URI scheme.",
+                retrievedPhoneAccount.supportsUriScheme(PhoneAccount.SCHEME_VOICEMAIL));
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
new file mode 100644
index 0000000..787966a
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/RemoteConferenceTest.java
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.RemoteConference;
+import android.telecom.RemoteConnection;
+import android.telecom.TelecomManager;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
+ * verify the functionality of Remote Conferences.
+ * We make 2 connections on the {@link CtsConnectionService} & we create 2 connections on the
+ * {@link CtsRemoteConnectionService} via the {@link RemoteConnection} object. We store this
+ * corresponding RemoteConnection object on the connections to plumb the modifications on
+ * the connections in {@link CtsConnectionService} to the connections on
+ * {@link CtsRemoteConnectionService}. Then we create a remote conference on the
+ * {@link CtsRemoteConnectionService} and control it via the {@link RemoteConference}
+ * object. The onConference method on the managerConnectionService will initiate a remote conference
+ * creation on the remoteConnectionService and once that is completed, we create a local conference
+ * on the managerConnectionService.
+ */
+public class RemoteConferenceTest extends BaseRemoteTelecomTest {
+
+    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;
+
+    MockConnection mConnection1, mConnection2;
+    MockConnection mRemoteConnection1, mRemoteConnection2;
+    Call mCall1, mCall2;
+    MockConference mConference, mRemoteConference;
+    RemoteConference mRemoteConferenceObject;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mShouldTestTelecom) {
+            addRemoteConferenceCall();
+            verifyRemoteConferenceObject(mRemoteConferenceObject, mRemoteConference, mConference);
+        }
+    }
+
+    public void testRemoteConferenceCreate() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
+        assertCallState(confCall, Call.STATE_ACTIVE);
+
+        if (mCall1.getParent() != confCall || mCall2.getParent() != confCall) {
+            fail("The 2 participating calls should contain the conference call as its parent");
+        }
+        if (!(confCall.getChildren().contains(mCall1) && confCall.getChildren().contains(mCall2))) {
+            fail("The conference call should contain the 2 participating calls as its children");
+        }
+
+        assertConnectionState(mConnection1, Connection.STATE_ACTIVE);
+        assertConnectionState(mConnection2, Connection.STATE_ACTIVE);
+        assertConnectionState(mRemoteConnection1, Connection.STATE_ACTIVE);
+        assertConnectionState(mRemoteConnection2, Connection.STATE_ACTIVE);
+        assertConferenceState(mConference, Connection.STATE_ACTIVE);
+        assertConferenceState(mRemoteConference, Connection.STATE_ACTIVE);
+        assertRemoteConferenceState(mRemoteConferenceObject, Connection.STATE_ACTIVE);
+    }
+
+    public void testRemoteConferenceSplit() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
+        assertCallState(confCall, Call.STATE_ACTIVE);
+
+        if (!(mCall1.getParent() == confCall) && (confCall.getChildren().contains(mCall1))) {
+            fail("Call 1 not conferenced");
+        }
+        assertTrue(mConference.getConnections().contains(mConnection1));
+        assertTrue(mRemoteConference.getConnections().contains(mRemoteConnection1));
+
+        splitFromConferenceCall(mCall1);
+
+        if ((mCall1.getParent() == confCall) || (confCall.getChildren().contains(mCall1))) {
+            fail("Call 1 should not be still conferenced");
+        }
+        assertFalse(mConference.getConnections().contains(mConnection1));
+        assertFalse(mRemoteConference.getConnections().contains(mRemoteConnection1));
+    }
+
+    public void testRemoteConferenceHoldAndUnhold() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
+        assertCallState(confCall, Call.STATE_ACTIVE);
+
+        confCall.hold();
+        assertCallState(confCall, Call.STATE_HOLDING);
+        assertCallState(mCall1, Call.STATE_HOLDING);
+        assertCallState(mCall2, Call.STATE_HOLDING);
+        assertConnectionState(mConnection1, Connection.STATE_HOLDING);
+        assertConnectionState(mConnection2, Connection.STATE_HOLDING);
+        assertConnectionState(mRemoteConnection1, Connection.STATE_HOLDING);
+        assertConnectionState(mRemoteConnection2, Connection.STATE_HOLDING);
+        assertConferenceState(mConference, Connection.STATE_HOLDING);
+        assertConferenceState(mRemoteConference, Connection.STATE_HOLDING);
+        assertRemoteConferenceState(mRemoteConferenceObject, Connection.STATE_HOLDING);
+
+        confCall.unhold();
+        assertCallState(confCall, Call.STATE_ACTIVE);
+        assertCallState(mCall1, Call.STATE_ACTIVE);
+        assertCallState(mCall2, Call.STATE_ACTIVE);
+        assertConnectionState(mConnection1, Connection.STATE_ACTIVE);
+        assertConnectionState(mConnection2, Connection.STATE_ACTIVE);
+        assertConnectionState(mRemoteConnection1, Connection.STATE_ACTIVE);
+        assertConnectionState(mRemoteConnection2, Connection.STATE_ACTIVE);
+        assertConferenceState(mConference, Connection.STATE_ACTIVE);
+        assertConferenceState(mRemoteConference, Connection.STATE_ACTIVE);
+        assertRemoteConferenceState(mRemoteConferenceObject, Connection.STATE_ACTIVE);
+    }
+
+    public void testRemoteConferenceMergeAndSwap() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
+        assertCallState(confCall, Call.STATE_ACTIVE);
+
+        confCall.mergeConference();
+        assertCallDisplayName(mCall1, TestUtils.MERGE_CALLER_NAME);
+        assertCallDisplayName(mCall2, TestUtils.MERGE_CALLER_NAME);
+        assertConnectionCallDisplayName(mConnection1,
+                TestUtils.MERGE_CALLER_NAME);
+        assertConnectionCallDisplayName(mConnection2,
+                TestUtils.MERGE_CALLER_NAME);
+        assertConnectionCallDisplayName(mRemoteConnection1,
+                TestUtils.MERGE_CALLER_NAME);
+        assertConnectionCallDisplayName(mRemoteConnection2,
+                TestUtils.MERGE_CALLER_NAME);
+
+        confCall.swapConference();
+        assertCallDisplayName(mCall1, TestUtils.SWAP_CALLER_NAME);
+        assertCallDisplayName(mCall2, TestUtils.SWAP_CALLER_NAME);
+        assertConnectionCallDisplayName(mConnection1,
+                TestUtils.SWAP_CALLER_NAME);
+        assertConnectionCallDisplayName(mConnection2,
+                TestUtils.SWAP_CALLER_NAME);
+        assertConnectionCallDisplayName(mRemoteConnection1,
+                TestUtils.SWAP_CALLER_NAME);
+        assertConnectionCallDisplayName(mRemoteConnection2,
+                TestUtils.SWAP_CALLER_NAME);
+    }
+
+    public void testRemoteConferenceDTMFTone() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
+        assertCallState(confCall, Call.STATE_ACTIVE);
+
+        assertTrue(mConference.getDtmfString().isEmpty());
+        assertTrue(mRemoteConference.getDtmfString().isEmpty());
+        confCall.playDtmfTone('1');
+        assertDtmfString(mConference, "1");
+        assertDtmfString(mRemoteConference, "1");
+        confCall.stopDtmfTone();
+        assertDtmfString(mConference, "1.");
+        assertDtmfString(mRemoteConference, "1.");
+        confCall.playDtmfTone('3');
+        assertDtmfString(mConference, "1.3");
+        assertDtmfString(mRemoteConference, "1.3");
+        confCall.stopDtmfTone();
+        assertDtmfString(mConference, "1.3.");
+        assertDtmfString(mRemoteConference, "1.3.");
+    }
+
+    public void testRemoteConferenceCallbacks_StateChange() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        Handler handler = setupRemoteConferenceCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConferenceCallbacks_StateChange");
+        RemoteConference.Callback callback;
+
+        callback = new RemoteConference.Callback() {
+            @Override
+            public void onStateChanged(RemoteConference conference, int oldState, int newState) {
+                super.onStateChanged(conference, oldState, newState);
+                callbackInvoker.invoke(conference, oldState, newState);
+            }
+        };
+        mRemoteConferenceObject.registerCallback(callback, handler);
+        mRemoteConference.setOnHold();
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(Connection.STATE_ACTIVE, callbackInvoker.getArgs(0)[1]);
+        assertEquals(Connection.STATE_HOLDING, callbackInvoker.getArgs(0)[2]);
+        mRemoteConferenceObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConferenceCallbacks_Disconnect() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        Handler handler = setupRemoteConferenceCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConferenceCallbacks_Disconnect");
+        RemoteConference.Callback callback;
+
+        callback = new RemoteConference.Callback() {
+            @Override
+            public void onDisconnected(RemoteConference conference,
+                                       DisconnectCause disconnectCause) {
+                super.onDisconnected(conference, disconnectCause);
+                callbackInvoker.invoke(conference, disconnectCause);
+            }
+        };
+        mRemoteConferenceObject.registerCallback(callback, handler);
+        DisconnectCause cause = new DisconnectCause(DisconnectCause.LOCAL);
+        mRemoteConference.setDisconnected(cause);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(cause, callbackInvoker.getArgs(0)[1]);
+        mRemoteConferenceObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConferenceCallbacks_ConnectionAdd() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        Handler handler = setupRemoteConferenceCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConferenceCallbacks_ConnectionAdd");
+        RemoteConference.Callback callback;
+
+        callback = new RemoteConference.Callback() {
+            @Override
+            public void onConnectionAdded(RemoteConference conference,
+                                          RemoteConnection connection) {
+                super.onConnectionAdded(conference, connection);
+                callbackInvoker.invoke(conference, connection);
+            }
+        };
+        mRemoteConferenceObject.registerCallback(callback, handler);
+        placeAndVerifyCall();
+        RemoteConnection newRemoteConnectionObject =
+                verifyConnectionForOutgoingCall(1).getRemoteConnection();
+        MockConnection newConnection = verifyConnectionForOutgoingCallOnRemoteCS(2);
+        mRemoteConference.addConnection(newConnection);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
+        // No "equals" method in RemoteConnection
+        //assertEquals(newRemoteConnectionObject, callbackInvoker.getArgs(0)[1]);
+        mRemoteConferenceObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConferenceCallbacks_ConnectionRemove() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        Handler handler = setupRemoteConferenceCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConferenceCallbacks_ConnectionRemove");
+        RemoteConference.Callback callback;
+
+        callback = new RemoteConference.Callback() {
+            @Override
+            public void onConnectionRemoved(RemoteConference conference,
+                                            RemoteConnection connection) {
+                super.onConnectionRemoved(conference, connection);
+                callbackInvoker.invoke(conference, connection);
+            }
+        };
+        mRemoteConferenceObject.registerCallback(callback, handler);
+        placeAndVerifyCall();
+        RemoteConnection newRemoteConnectionObject =
+                verifyConnectionForOutgoingCall(1).getRemoteConnection();
+        MockConnection newConnection = verifyConnectionForOutgoingCallOnRemoteCS(2);
+        mRemoteConference.addConnection(newConnection);
+        mRemoteConference.removeConnection(newConnection);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
+        //assertEquals(newRemoteConnectionObject, callbackInvoker.getArgs(0)[1]);
+        // No "equals" method in RemoteConnection
+        mRemoteConferenceObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConferenceCallbacks_ConnectionCapabilities() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        Handler handler = setupRemoteConferenceCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConferenceCallbacks_ConnectionCapabilities");
+        RemoteConference.Callback callback;
+
+        callback = new RemoteConference.Callback() {
+            @Override
+            public void onConnectionCapabilitiesChanged(
+                    RemoteConference conference,
+                    int connectionCapabilities) {
+                super.onConnectionCapabilitiesChanged(conference, connectionCapabilities);
+                callbackInvoker.invoke(conference, connectionCapabilities);
+            }
+        };
+        mRemoteConferenceObject.registerCallback(callback, handler);
+        int capabilities = mRemoteConference.getConnectionCapabilities() | Connection.CAPABILITY_MUTE;
+        mRemoteConference.setConnectionCapabilities(capabilities);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(capabilities, callbackInvoker.getArgs(0)[1]);
+        mRemoteConferenceObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConferenceCallbacks_ConferenceableConnections() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        Handler handler = setupRemoteConferenceCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConferenceCallbacks_ConferenceableConnections");
+        RemoteConference.Callback callback;
+
+        callback = new RemoteConference.Callback() {
+            @Override
+            public void onConferenceableConnectionsChanged(
+                    RemoteConference conference,
+                    List<RemoteConnection> conferenceableConnections) {
+                super.onConferenceableConnectionsChanged(conference, conferenceableConnections);
+                callbackInvoker.invoke(conference, conferenceableConnections);
+            }
+        };
+        mRemoteConferenceObject.registerCallback(callback, handler);
+        placeAndVerifyCall();
+        RemoteConnection newRemoteConnectionObject =
+            verifyConnectionForOutgoingCall(1).getRemoteConnection();
+        MockConnection newConnection = verifyConnectionForOutgoingCallOnRemoteCS(1);
+        ArrayList<Connection> confList = new ArrayList<>();
+        confList.add(newConnection);
+        mRemoteConference.setConferenceableConnections(confList);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
+        // No "equals" method in RemoteConnection
+        //assertTrue(((List<RemoteConnection>)callbackInvoker.getArgs(0)[1]).contains(
+                //newRemoteConnectionObject));
+        mRemoteConferenceObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConferenceCallbacks_Destroy() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        Handler handler = setupRemoteConferenceCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConferenceCallbacks_Destroy");
+        RemoteConference.Callback callback;
+
+        callback = new RemoteConference.Callback() {
+            @Override
+            public void onDestroyed(RemoteConference conference) {
+                super.onDestroyed(conference);
+                callbackInvoker.invoke(conference);
+            }
+        };
+        mRemoteConferenceObject.registerCallback(callback, handler);
+        mRemoteConference.destroy();
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
+        mRemoteConferenceObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConferenceCallbacks_Extras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        Handler handler = setupRemoteConferenceCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConferenceCallbacks_Extras");
+        RemoteConference.Callback callback;
+
+        callback = new RemoteConference.Callback() {
+            @Override
+            public void onExtrasChanged(RemoteConference conference, Bundle extras) {
+                super.onExtrasChanged(conference, extras);
+                callbackInvoker.invoke(conference, extras);
+            }
+        };
+        mRemoteConferenceObject.registerCallback(callback, handler);
+        Bundle extras = new Bundle();
+        extras.putString(TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test");
+        mRemoteConference.setExtras(extras);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConferenceObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(extras, callbackInvoker.getArgs(0)[1]);
+        mRemoteConferenceObject.unregisterCallback(callback);
+    }
+
+    private void verifyRemoteConferenceObject(RemoteConference remoteConferenceObject,
+            MockConference remoteConference, MockConference conference) {
+        assertEquals(remoteConference.getConnectionCapabilities(),
+                remoteConferenceObject.getConnectionCapabilities());
+        assertTrue(remoteConferenceObject.getConferenceableConnections().isEmpty());
+        List<RemoteConnection> remoteConnections = new ArrayList<>();
+        for (Connection c: conference.getConnections()) {
+            remoteConnections.add(((MockConnection)c).getRemoteConnection());
+        }
+        assertEquals(remoteConnections, remoteConferenceObject.getConnections());
+        assertEquals(remoteConference.getDisconnectCause(), remoteConferenceObject.getDisconnectCause());
+        assertEquals(remoteConference.getExtras(), remoteConferenceObject.getExtras());
+    }
+
+    private void addRemoteConnectionOutgoingCalls() {
+        try {
+            MockConnectionService managerConnectionService = new MockConnectionService() {
+                @Override
+                public Connection onCreateOutgoingConnection(
+                        PhoneAccountHandle connectionManagerPhoneAccount,
+                        ConnectionRequest request) {
+                    MockConnection connection = (MockConnection)super.onCreateOutgoingConnection(
+                            connectionManagerPhoneAccount, request);
+                    ConnectionRequest remoteRequest = new ConnectionRequest(
+                            TEST_REMOTE_PHONE_ACCOUNT_HANDLE,
+                            request.getAddress(),
+                            request.getExtras());
+                    RemoteConnection remoteConnection =
+                            CtsConnectionService.createRemoteOutgoingConnectionToTelecom(
+                                    TEST_REMOTE_PHONE_ACCOUNT_HANDLE, remoteRequest);
+                    connection.setRemoteConnection(remoteConnection);
+                    // Modify the connection object created with local values.
+                    int capabilities = connection.getConnectionCapabilities();
+                    connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES);
+                    return connection;
+                }
+                @Override
+                public void onConference(Connection connection1, Connection connection2) {
+                    /**
+                     * Fetch the corresponding remoteConnection objects and instantiate a remote
+                     * conference creation on the remoteConnectionService instead of this
+                     * managerConnectionService.
+                     */
+                    RemoteConnection remoteConnection1 =
+                            ((MockConnection)connection1).getRemoteConnection();
+                    RemoteConnection remoteConnection2 =
+                            ((MockConnection)connection2).getRemoteConnection();
+                    if (remoteConnection1.getConference() == null &&
+                            remoteConnection2.getConference() == null) {
+                        conferenceRemoteConnections(remoteConnection1, remoteConnection2);
+                    }
+                }
+                @Override
+                public void onRemoteConferenceAdded(RemoteConference remoteConference) {
+                    /**
+                     * Now that the remote conference has been created,
+                     * let's create a local conference on this ConnectionService.
+                     */
+                    MockConference conference = new MockConference(mConnection1, mConnection2);
+                    conference.setRemoteConference(remoteConference);
+                    CtsConnectionService.addConferenceToTelecom(conference);
+                    conferences.add(conference);
+                    lock.release();
+                }
+            };
+            /**
+             * We want the conference to be instantiated on the remoteConnectionService registered
+             * with telecom.
+             */
+            MockConnectionService remoteConnectionService= new MockConnectionService() {
+                @Override
+                public Connection onCreateOutgoingConnection(
+                        PhoneAccountHandle connectionManagerPhoneAccount,
+                        ConnectionRequest request) {
+                    Connection connection = super.onCreateOutgoingConnection(
+                            connectionManagerPhoneAccount,
+                            request);
+                    // Modify the connection object created with local values.
+                    int capabilities = connection.getConnectionCapabilities();
+                    connection.setConnectionCapabilities(capabilities | CONF_CAPABILITIES);
+                    return connection;
+                }
+                @Override
+                public void onConference(Connection connection1, Connection connection2) {
+                    // Make sure that these connections are already not conferenced.
+                    if (connection1.getConference() == null &&
+                            connection2.getConference() == null) {
+                        MockConference conference = new MockConference(
+                                (MockConnection)connection1, (MockConnection)connection2);
+                        CtsRemoteConnectionService.addConferenceToTelecom(conference);
+                        conferences.add(conference);
+                        lock.release();
+                    }
+                }
+            };
+            setupConnectionServices(managerConnectionService, remoteConnectionService,
+                    FLAG_REGISTER | FLAG_ENABLE);
+        } catch(Exception e) {
+            fail("Error in setting up the connection services");
+        }
+
+        placeAndVerifyCall();
+        mConnection1 = verifyConnectionForOutgoingCall(0);
+        mRemoteConnection1 = verifyConnectionForOutgoingCallOnRemoteCS(0);
+        mCall1 = mInCallCallbacks.getService().getLastCall();
+        assertCallState(mCall1, Call.STATE_DIALING);
+        mConnection1.setActive();
+        mRemoteConnection1.setActive();
+        assertCallState(mCall1, Call.STATE_ACTIVE);
+
+        placeAndVerifyCall();
+        mConnection2 = verifyConnectionForOutgoingCall(1);
+        mRemoteConnection2 = verifyConnectionForOutgoingCallOnRemoteCS(1);
+        mCall2 = mInCallCallbacks.getService().getLastCall();
+        assertCallState(mCall2, Call.STATE_DIALING);
+        mConnection2.setActive();
+        mRemoteConnection2.setActive();
+        assertCallState(mCall2, Call.STATE_ACTIVE);
+
+        setAndVerifyConferenceablesForOutgoingConnection(0);
+        setAndVerifyConferenceablesForOutgoingConnection(1);
+        setAndVerifyConferenceablesForOutgoingConnectionOnRemoteCS(0);
+        setAndVerifyConferenceablesForOutgoingConnectionOnRemoteCS(1);
+    }
+
+    private void addRemoteConferenceCall() {
+        addRemoteConnectionOutgoingCalls();
+        /**
+         * We've 2 connections on the local connectionService which have 2 corresponding
+         * connections on the remoteConnectionService controlled via 2 RemoteConnection objects
+         * on the connectionService. We now create a conference on the local two connections
+         * which triggers a creation of conference on the remoteConnectionService via the
+         * RemoteConference object.
+         */
+
+        addConferenceCall(mCall1, mCall2);
+        mConference = verifyConferenceForOutgoingCall();
+        mRemoteConference = verifyConferenceForOutgoingCallOnRemoteCS();
+        mRemoteConferenceObject = mConference.getRemoteConference();
+        mRemoteConnection1 = (MockConnection)mRemoteConference.getConnections().get(0);
+        mRemoteConnection2 = (MockConnection)mRemoteConference.getConnections().get(1);
+    }
+
+    private Handler setupRemoteConferenceCallbacksTest() {
+        final Call confCall = mInCallCallbacks.getService().getLastConferenceCall();
+        assertCallState(confCall, Call.STATE_ACTIVE);
+
+        // Create a looper thread for the callbacks.
+        HandlerThread workerThread = new HandlerThread("CallbackThread");
+        workerThread.start();
+        Handler handler = new Handler(workerThread.getLooper());
+        return handler;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java b/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java
new file mode 100644
index 0000000..5b552a0
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/RemoteConnectionTest.java
@@ -0,0 +1,1246 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.*;
+
+import android.graphics.SurfaceTexture;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telecom.ConnectionRequest;
+import android.telecom.DisconnectCause;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.RemoteConnection;
+import android.telecom.RemoteConnection.VideoProvider;
+import android.telecom.StatusHints;
+import android.telecom.TelecomManager;
+import android.telecom.VideoProfile;
+import android.view.Surface;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Extended suite of tests that use {@link CtsConnectionService} and {@link MockInCallService} to
+ * verify the functionality of Remote Connections.
+ * We make 2 connections on the {@link CtsConnectionService} & we create 2 connections on the
+ * {@link CtsRemoteConnectionService} via the {@link RemoteConnection} object. We store this
+ * corresponding RemoteConnection object on the connections to plumb the modifications on
+ * the connections in {@link CtsConnectionService} to the connections on
+ * {@link CtsRemoteConnectionService}.
+ */
+public class RemoteConnectionTest extends BaseRemoteTelecomTest {
+
+    MockConnection mConnection;
+    MockConnection mRemoteConnection;
+    RemoteConnection mRemoteConnectionObject;
+
+    public void testRemoteConnectionOutgoingCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        addRemoteConnectionOutgoingCall();
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+
+        verifyRemoteConnectionObject(mRemoteConnectionObject, mRemoteConnection);
+
+        mConnection.setActive();
+        mRemoteConnection.setActive();
+
+        assertCallState(call, Call.STATE_ACTIVE);
+        assertConnectionState(mConnection, Connection.STATE_ACTIVE);
+        assertRemoteConnectionState(mRemoteConnectionObject, Connection.STATE_ACTIVE);
+        assertConnectionState(mRemoteConnection, Connection.STATE_ACTIVE);
+
+        call.hold();
+        assertCallState(call, Call.STATE_HOLDING);
+        assertConnectionState(mConnection, Connection.STATE_HOLDING);
+        assertRemoteConnectionState(mRemoteConnectionObject, Connection.STATE_HOLDING);
+        assertConnectionState(mRemoteConnection, Connection.STATE_HOLDING);
+
+        call.unhold();
+        assertCallState(call, Call.STATE_ACTIVE);
+        assertConnectionState(mConnection, Connection.STATE_ACTIVE);
+        assertRemoteConnectionState(mRemoteConnectionObject, Connection.STATE_ACTIVE);
+        assertConnectionState(mRemoteConnection, Connection.STATE_ACTIVE);
+
+        call.disconnect();
+        assertCallState(call, Call.STATE_DISCONNECTED);
+        assertConnectionState(mConnection, Connection.STATE_DISCONNECTED);
+        assertRemoteConnectionState(mRemoteConnectionObject, Connection.STATE_DISCONNECTED);
+        assertConnectionState(mRemoteConnection, Connection.STATE_DISCONNECTED);
+    }
+
+    public void testRemoteConnectionIncomingCallAccept() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        addRemoteConnectionIncomingCall();
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_RINGING);
+
+        verifyRemoteConnectionObject(mRemoteConnectionObject, mRemoteConnection);
+
+        assertConnectionState(mConnection, Connection.STATE_RINGING);
+        assertRemoteConnectionState(mRemoteConnectionObject, Connection.STATE_RINGING);
+        assertConnectionState(mRemoteConnection, Connection.STATE_RINGING);
+
+        call.answer(VideoProfile.STATE_AUDIO_ONLY);
+        assertCallState(call, Call.STATE_ACTIVE);
+        assertConnectionState(mConnection, Connection.STATE_ACTIVE);
+        assertRemoteConnectionState(mRemoteConnectionObject, Connection.STATE_ACTIVE);
+        assertConnectionState(mRemoteConnection, Connection.STATE_ACTIVE);
+    }
+
+    public void testRemoteConnectionIncomingCallReject() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        addRemoteConnectionIncomingCall();
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_RINGING);
+
+        verifyRemoteConnectionObject(mRemoteConnectionObject, mRemoteConnection);
+
+        assertConnectionState(mConnection, Connection.STATE_RINGING);
+        assertRemoteConnectionState(mRemoteConnectionObject, Connection.STATE_RINGING);
+        assertConnectionState(mRemoteConnection, Connection.STATE_RINGING);
+
+        call.reject(false, null);
+        assertCallState(call, Call.STATE_DISCONNECTED);
+        assertConnectionState(mConnection, Connection.STATE_DISCONNECTED);
+        assertRemoteConnectionState(mRemoteConnectionObject, Connection.STATE_DISCONNECTED);
+        assertConnectionState(mRemoteConnection, Connection.STATE_DISCONNECTED);
+    }
+
+    public void testRemoteConnectionDTMFTone() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        addRemoteConnectionIncomingCall();
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_RINGING);
+
+        verifyRemoteConnectionObject(mRemoteConnectionObject, mRemoteConnection);
+
+        assertTrue(mConnection.getDtmfString().isEmpty());
+        assertTrue(mRemoteConnection.getDtmfString().isEmpty());
+        call.playDtmfTone('1');
+        assertDtmfString(mConnection, "1");
+        assertDtmfString(mRemoteConnection, "1");
+        call.stopDtmfTone();
+        assertDtmfString(mConnection, "1.");
+        assertDtmfString(mRemoteConnection, "1.");
+        call.playDtmfTone('3');
+        assertDtmfString(mConnection, "1.3");
+        assertDtmfString(mRemoteConnection, "1.3");
+        call.stopDtmfTone();
+        assertDtmfString(mConnection, "1.3.");
+        assertDtmfString(mRemoteConnection, "1.3.");
+    }
+
+    public void testRemoteConnectionCallbacks_StateChange() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_StateChange");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onStateChanged(RemoteConnection connection, int state) {
+                super.onStateChanged(connection, state);
+                callbackInvoker.invoke(connection, state);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        mRemoteConnection.setActive();
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(Connection.STATE_ACTIVE, callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_RingbackRequest() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_RingbackRequest");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onRingbackRequested(RemoteConnection connection, boolean ringback) {
+                super.onRingbackRequested(connection, ringback);
+                callbackInvoker.invoke(connection, ringback);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        mRemoteConnection.setRingbackRequested(true);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertTrue((boolean) callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_ConnectionCapabilities() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_ConnectionCapabilities");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onConnectionCapabilitiesChanged(
+                    RemoteConnection connection,
+                    int connectionCapabilities) {
+                super.onConnectionCapabilitiesChanged(connection, connectionCapabilities);
+                callbackInvoker.invoke(connection, connectionCapabilities);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        int capabilities = mRemoteConnection.getConnectionCapabilities() | Connection.CAPABILITY_MUTE;
+        mRemoteConnection.setConnectionCapabilities(capabilities);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(capabilities, callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+
+    }
+
+    public void testRemoteConnectionCallbacks_PostDialWait() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_PostDialWait");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onPostDialWait(RemoteConnection connection,
+                                       String remainingPostDialSequence) {
+                super.onPostDialWait(connection, remainingPostDialSequence);
+                callbackInvoker.invoke(connection, remainingPostDialSequence);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        String postDialSequence = "test";
+        mRemoteConnection.setPostDialWait(postDialSequence);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(postDialSequence, callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_PostDialChar() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_PostDialChar");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onPostDialChar(RemoteConnection connection, char nextChar) {
+                super.onPostDialChar(connection, nextChar);
+                callbackInvoker.invoke(connection, nextChar);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        char postDialChar = '3';
+        ((Connection) mRemoteConnection).setNextPostDialChar(postDialChar);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(postDialChar, callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_VoipAudio() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_VoipAudio");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onVoipAudioChanged(RemoteConnection connection, boolean isVoip) {
+                super.onVoipAudioChanged(connection, isVoip);
+                callbackInvoker.invoke(connection, isVoip);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        mRemoteConnection.setAudioModeIsVoip(true);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertTrue((boolean) callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_StatusHints() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_StatusHints");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onStatusHintsChanged(RemoteConnection connection, StatusHints statusHints) {
+                super.onStatusHintsChanged(connection, statusHints);
+                callbackInvoker.invoke(connection, statusHints);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        StatusHints hints = new StatusHints("test", null, null);
+        mRemoteConnection.setStatusHints(hints);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(hints, callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_AddressChange() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_AddressChange");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onAddressChanged(RemoteConnection connection, Uri address,
+                                         int presentation) {
+                super.onAddressChanged(connection, address, presentation);
+                callbackInvoker.invoke(connection, address, presentation);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        Uri address = Uri.parse("tel:555");
+        mRemoteConnection.setAddress(address, TelecomManager.PRESENTATION_ALLOWED);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(address, callbackInvoker.getArgs(0)[1]);
+        assertEquals(TelecomManager.PRESENTATION_ALLOWED, callbackInvoker.getArgs(0)[2]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_CallerDisplayName() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_CallerDisplayName");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onCallerDisplayNameChanged(
+                    RemoteConnection connection, String callerDisplayName, int presentation) {
+                super.onCallerDisplayNameChanged(connection, callerDisplayName, presentation);
+                callbackInvoker.invoke(connection, callerDisplayName, presentation);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        String callerDisplayName = "test";
+        mRemoteConnection.setCallerDisplayName(callerDisplayName, TelecomManager.PRESENTATION_ALLOWED);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(callerDisplayName, callbackInvoker.getArgs(0)[1]);
+        assertEquals(TelecomManager.PRESENTATION_ALLOWED, callbackInvoker.getArgs(0)[2]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_VideoState() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_VideoState");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onVideoStateChanged(RemoteConnection connection, int videoState) {
+                super.onVideoStateChanged(connection, videoState);
+                callbackInvoker.invoke(connection, videoState);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        mRemoteConnection.setVideoState(VideoProfile.STATE_BIDIRECTIONAL);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(VideoProfile.STATE_BIDIRECTIONAL, callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_ConferenceableConnections() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_ConferenceableConnections");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onConferenceableConnectionsChanged(
+                    RemoteConnection connection,
+                    List<RemoteConnection> conferenceableConnections) {
+                super.onConferenceableConnectionsChanged(connection, conferenceableConnections);
+                callbackInvoker.invoke(connection, conferenceableConnections);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        //Make the existing call active to add a new call
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        mConnection.setActive();
+        mRemoteConnection.setActive();
+        assertCallState(call, Call.STATE_ACTIVE);
+        placeAndVerifyCall();
+        RemoteConnection newRemoteConnectionObject =
+                verifyConnectionForOutgoingCall(1).getRemoteConnection();
+        MockConnection newConnection = verifyConnectionForOutgoingCallOnRemoteCS(1);
+        ArrayList<Connection> confList = new ArrayList<>();
+        confList.add(newConnection);
+        mRemoteConnection.setConferenceableConnections(confList);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        //assertTrue(((List<RemoteConnection>)callbackInvoker.getArgs(0)[1]).contains(
+                //newRemoteConnectionObject)); No "equals" method in RemoteConnection
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_VideoProvider() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_VideoProvider");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onVideoProviderChanged(
+                    RemoteConnection connection, VideoProvider videoProvider) {
+                super.onVideoProviderChanged(connection, videoProvider);
+                callbackInvoker.invoke(connection, videoProvider);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        mRemoteConnection.createMockVideoProvider();
+        MockVideoProvider mockVideoProvider = mRemoteConnection.getMockVideoProvider();
+        mRemoteConnection.setVideoProvider(mockVideoProvider);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_Extras() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_Extras");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onExtrasChanged(RemoteConnection connection, Bundle extras) {
+                super.onExtrasChanged(connection, extras);
+                callbackInvoker.invoke(connection, extras);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        Bundle extras = new Bundle();
+        extras.putString(TelecomManager.EXTRA_CALL_DISCONNECT_MESSAGE, "Test");
+        mRemoteConnection.setExtras(extras);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(extras, callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+
+    }
+
+    public void testRemoteConnectionCallbacks_Disconnect() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_Disconnect");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onDisconnected(
+                    RemoteConnection connection,
+                    DisconnectCause disconnectCause) {
+                super.onDisconnected(connection, disconnectCause);
+                callbackInvoker.invoke(connection, disconnectCause);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        DisconnectCause cause = new DisconnectCause(DisconnectCause.LOCAL);
+        mRemoteConnection.setDisconnected(cause);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        assertEquals(cause, callbackInvoker.getArgs(0)[1]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionCallbacks_Destroy() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        Handler handler = setupRemoteConnectionCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionCallbacks_Destroy");
+        RemoteConnection.Callback callback;
+
+        callback = new RemoteConnection.Callback() {
+            @Override
+            public void onDestroyed(RemoteConnection connection) {
+                super.onDestroyed(connection);
+                callbackInvoker.invoke(connection);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        mRemoteConnection.destroy();
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+    }
+
+    public void testRemoteConnectionVideoCallbacks_SessionModify() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        setupRemoteConnectionVideoCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideoCallbacks_SessionModify");
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        final MockVideoProvider mockVideoProvider = mRemoteConnection.getMockVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onSessionModifyRequestReceived(
+                    VideoProvider videoProvider,
+                    VideoProfile videoProfile) {
+                super.onSessionModifyRequestReceived(videoProvider, videoProfile);
+                callbackInvoker.invoke(videoProvider, videoProfile);
+            }
+
+            @Override
+            public void onSessionModifyResponseReceived(
+                    VideoProvider videoProvider,
+                    int status,
+                    VideoProfile requestedProfile,
+                    VideoProfile responseProfile) {
+                super.onSessionModifyResponseReceived(videoProvider, status, requestedProfile,
+                        responseProfile);
+                callbackInvoker.invoke(videoProvider, status, requestedProfile, responseProfile);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        VideoProfile videoProfile = new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL);
+        mockVideoProvider.sendMockSessionModifyRequest(videoProfile);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
+        assertEquals(videoProfile, callbackInvoker.getArgs(0)[1]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideoCallbacks_SessionEvent() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        setupRemoteConnectionVideoCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideoCallbacks_SessionEvent");
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        final MockVideoProvider mockVideoProvider = mRemoteConnection.getMockVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onCallSessionEvent(VideoProvider videoProvider, int event) {
+                super.onCallSessionEvent(videoProvider, event);
+                callbackInvoker.invoke(videoProvider, event);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        mockVideoProvider.handleCallSessionEvent(Connection.VideoProvider.SESSION_EVENT_RX_PAUSE);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
+        assertEquals(Connection.VideoProvider.SESSION_EVENT_RX_PAUSE, callbackInvoker.getArgs(0)[1]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideoCallbacks_PeerDimensions() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        setupRemoteConnectionVideoCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideoCallbacks_PeerDimensions");
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        final MockVideoProvider mockVideoProvider = mRemoteConnection.getMockVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onPeerDimensionsChanged(VideoProvider videoProvider, int width,
+                                                int height) {
+                super.onPeerDimensionsChanged(videoProvider, width, height);
+                callbackInvoker.invoke(videoProvider, width, height);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        final int width = 100, heigth = 20;
+        mockVideoProvider.changePeerDimensions(width, heigth);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
+        assertEquals(width, callbackInvoker.getArgs(0)[1]);
+        assertEquals(heigth, callbackInvoker.getArgs(0)[2]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideoCallbacks_CallDataUsage() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        setupRemoteConnectionVideoCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideoCallbacks_CallDataUsage");
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        final MockVideoProvider mockVideoProvider = mRemoteConnection.getMockVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onCallDataUsageChanged(VideoProvider videoProvider, long dataUsage) {
+                super.onCallDataUsageChanged(videoProvider, dataUsage);
+                callbackInvoker.invoke(videoProvider, dataUsage);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        long callDataUsage = 10000;
+        mockVideoProvider.setCallDataUsage(callDataUsage);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
+        assertEquals(callDataUsage, callbackInvoker.getArgs(0)[1]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideoCallbacks_CameraCapabilities() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        setupRemoteConnectionVideoCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideoCallbacks_CameraCapabilities");
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        final MockVideoProvider mockVideoProvider = mRemoteConnection.getMockVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onCameraCapabilitiesChanged(
+                    VideoProvider videoProvider,
+                    VideoProfile.CameraCapabilities cameraCapabilities) {
+                super.onCameraCapabilitiesChanged(videoProvider, cameraCapabilities);
+                callbackInvoker.invoke(videoProvider, cameraCapabilities);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        VideoProfile.CameraCapabilities capabilities = new VideoProfile.CameraCapabilities(100, 200);
+        mockVideoProvider.changeCameraCapabilities(capabilities);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
+        assertEquals(capabilities, callbackInvoker.getArgs(0)[1]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideoCallbacks_VideoQuality() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        setupRemoteConnectionVideoCallbacksTest();
+
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideoCallbacks_VideoQuality");
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        final MockVideoProvider mockVideoProvider = mRemoteConnection.getMockVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onVideoQualityChanged(VideoProvider videoProvider, int videoQuality) {
+                super.onVideoQualityChanged(videoProvider, videoQuality);
+                callbackInvoker.invoke(videoProvider, videoQuality);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        final int videoQuality = 10;
+        mockVideoProvider.changeVideoQuality(videoQuality);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(0)[0]);
+        assertEquals(videoQuality, callbackInvoker.getArgs(0)[1]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideo_RequestCallDataUsage() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final long callDataUsage = 10000;
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_RequestCallDataUsage");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onRequestConnectionDataUsage() {
+                callbackInvoker.invoke();
+                super.setCallDataUsage(callDataUsage);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onCallDataUsageChanged(VideoProvider videoProvider, long dataUsage) {
+                super.onCallDataUsageChanged(videoProvider, dataUsage);
+                callbackInvoker.invoke(videoProvider, dataUsage);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        remoteVideoProvider.requestCallDataUsage();
+        callbackInvoker.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(1)[0]);
+        assertEquals(callDataUsage, callbackInvoker.getArgs(1)[1]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideo_RequestCameraCapabilities() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final VideoProfile.CameraCapabilities capabilities =
+                new VideoProfile.CameraCapabilities(100, 200);
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_RequestCameraCapabilities");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onRequestCameraCapabilities() {
+                callbackInvoker.invoke();
+                super.changeCameraCapabilities(capabilities);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onCameraCapabilitiesChanged(
+                    VideoProvider videoProvider,
+                    VideoProfile.CameraCapabilities cameraCapabilities) {
+                super.onCameraCapabilitiesChanged(videoProvider, cameraCapabilities);
+                callbackInvoker.invoke(videoProvider, cameraCapabilities);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        remoteVideoProvider.requestCameraCapabilities();
+        callbackInvoker.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(1)[0]);
+        assertEquals(capabilities, callbackInvoker.getArgs(1)[1]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideo_SendSessionModifyRequest() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        VideoProfile fromVideoProfile = new VideoProfile(VideoProfile.STATE_AUDIO_ONLY);
+        VideoProfile toVideoProfile =  new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL);
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_SendSessionModifyRequest");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onSendSessionModifyRequest(VideoProfile fromProfile,
+                                                   VideoProfile toProfile) {
+                callbackInvoker.invoke(fromProfile, toProfile);
+                super.receiveSessionModifyRequest(toProfile);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onSessionModifyRequestReceived(
+                    VideoProvider videoProvider,
+                    VideoProfile videoProfile) {
+                super.onSessionModifyRequestReceived(videoProvider, videoProfile);
+                callbackInvoker.invoke(videoProvider, videoProfile);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        remoteVideoProvider.sendSessionModifyRequest(fromVideoProfile, toVideoProfile);
+        callbackInvoker.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(fromVideoProfile, callbackInvoker.getArgs(0)[0]);
+        assertEquals(toVideoProfile, callbackInvoker.getArgs(0)[1]);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(1)[0]);
+        assertEquals(toVideoProfile, callbackInvoker.getArgs(1)[1]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideo_SendSessionModifyResponse() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        VideoProfile toVideoProfile =  new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL);
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_SendSessionModifyResponse");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onSendSessionModifyResponse(VideoProfile responseProfile) {
+                callbackInvoker.invoke(responseProfile);
+                super.receiveSessionModifyResponse(
+                        Connection.VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS,
+                        responseProfile, responseProfile);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onSessionModifyResponseReceived(
+                    VideoProvider videoProvider,
+                    int status,
+                    VideoProfile requestedProfile,
+                    VideoProfile responseProfile) {
+                super.onSessionModifyResponseReceived(videoProvider, status, requestedProfile,
+                        responseProfile);
+                callbackInvoker.invoke(videoProvider, status, requestedProfile, responseProfile);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        remoteVideoProvider.sendSessionModifyResponse(toVideoProfile);
+        callbackInvoker.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(toVideoProfile, callbackInvoker.getArgs(0)[0]);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(1)[0]);
+        assertEquals(toVideoProfile, callbackInvoker.getArgs(1)[2]);
+        assertEquals(Connection.VideoProvider.SESSION_MODIFY_REQUEST_SUCCESS,
+            callbackInvoker.getArgs(1)[1]);
+        assertEquals(toVideoProfile, callbackInvoker.getArgs(1)[3]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideo_SetCamera() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final String newCameraId = "5";
+        final VideoProfile.CameraCapabilities capabilities =
+            new VideoProfile.CameraCapabilities(100, 200);
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_SetCamera");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onSetCamera(String cameraId) {
+                callbackInvoker.invoke(cameraId);
+                super.changeCameraCapabilities(capabilities);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+        RemoteConnection.VideoProvider.Callback videoCallback;
+
+        videoCallback = new RemoteConnection.VideoProvider.Callback() {
+            @Override
+            public void onCameraCapabilitiesChanged(
+                    VideoProvider videoProvider,
+                    VideoProfile.CameraCapabilities cameraCapabilities) {
+                super.onCameraCapabilitiesChanged(videoProvider, cameraCapabilities);
+                callbackInvoker.invoke(videoProvider, cameraCapabilities);
+            }
+        };
+        remoteVideoProvider.registerCallback(videoCallback);
+        remoteVideoProvider.setCamera(newCameraId);
+        callbackInvoker.waitForCount(2, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(newCameraId, callbackInvoker.getArgs(0)[0]);
+        assertEquals(remoteVideoProvider, callbackInvoker.getArgs(1)[0]);
+        assertEquals(capabilities, callbackInvoker.getArgs(1)[1]);
+        remoteVideoProvider.unregisterCallback(videoCallback);
+    }
+
+    public void testRemoteConnectionVideo_SetDeviceOrientation() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final int newRotation = 5;
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_SetDeviceOrientation");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onSetDeviceOrientation(int rotation) {
+                callbackInvoker.invoke(rotation);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+
+        remoteVideoProvider.setDeviceOrientation(newRotation);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(newRotation, callbackInvoker.getArgs(0)[0]);
+    }
+
+    public void testRemoteConnectionVideo_SetDisplaySurface() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final Surface newSurface = new Surface(new SurfaceTexture(1));
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_SetDisplaySurface");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onSetDisplaySurface(Surface surface) {
+                callbackInvoker.invoke(surface);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+
+        remoteVideoProvider.setDisplaySurface(newSurface);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(newSurface, callbackInvoker.getArgs(0)[0]);
+    }
+
+    public void testRemoteConnectionVideo_SetPauseImage() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final Uri newUri = Uri.parse("content://");
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_SetPauseImage");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onSetPauseImage(Uri uri) {
+                callbackInvoker.invoke(uri);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+
+        remoteVideoProvider.setPauseImage(newUri);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(newUri, callbackInvoker.getArgs(0)[0]);
+    }
+
+    public void testRemoteConnectionVideo_SetPreviewSurface() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final Surface newSurface = new Surface(new SurfaceTexture(1));
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_SetPreviewSurface");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onSetPreviewSurface(Surface surface) {
+                callbackInvoker.invoke(surface);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+
+        remoteVideoProvider.setPreviewSurface(newSurface);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(newSurface, callbackInvoker.getArgs(0)[0]);
+    }
+
+    public void testRemoteConnectionVideo_SetZoom() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        final float newZoom = 1.0f;
+        final InvokeCounter callbackInvoker =
+                new InvokeCounter("testRemoteConnectionVideo_SetPreviewSurface");
+        final MockVideoProvider mockVideoProvider = new MockVideoProvider(mRemoteConnection) {
+            @Override
+            public void onSetZoom(float value) {
+                callbackInvoker.invoke(value);
+            }
+        };
+        setupRemoteConnectionVideoTest(mockVideoProvider);
+
+        final VideoProvider remoteVideoProvider = mRemoteConnectionObject.getVideoProvider();
+
+        remoteVideoProvider.setZoom(newZoom);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(newZoom, callbackInvoker.getArgs(0)[0]);
+    }
+
+    private void verifyRemoteConnectionObject(RemoteConnection remoteConnection,
+            Connection connection) {
+        assertEquals(connection.getAddress(), remoteConnection.getAddress());
+        assertEquals(connection.getAddressPresentation(),
+                remoteConnection.getAddressPresentation());
+        assertEquals(connection.getCallerDisplayName(), remoteConnection.getCallerDisplayName());
+        assertEquals(connection.getCallerDisplayNamePresentation(),
+                remoteConnection.getCallerDisplayNamePresentation());
+        assertEquals(connection.getConnectionCapabilities(),
+                remoteConnection.getConnectionCapabilities());
+        assertEquals(connection.getDisconnectCause(), remoteConnection.getDisconnectCause());
+        assertEquals(connection.getExtras(), remoteConnection.getExtras());
+        assertEquals(connection.getStatusHints(), remoteConnection.getStatusHints());
+        assertEquals(VideoProfile.STATE_AUDIO_ONLY, remoteConnection.getVideoState());
+        assertNull(remoteConnection.getVideoProvider());
+        assertTrue(remoteConnection.getConferenceableConnections().isEmpty());
+    }
+
+    private void addRemoteConnectionOutgoingCall() {
+        try {
+            MockConnectionService managerConnectionService = new MockConnectionService() {
+                @Override
+                public Connection onCreateOutgoingConnection(
+                        PhoneAccountHandle connectionManagerPhoneAccount,
+                        ConnectionRequest request) {
+                    MockConnection connection = (MockConnection)super.onCreateOutgoingConnection(
+                            connectionManagerPhoneAccount, request);
+                    ConnectionRequest remoteRequest = new ConnectionRequest(
+                            TEST_REMOTE_PHONE_ACCOUNT_HANDLE,
+                            request.getAddress(),
+                            request.getExtras());
+                    RemoteConnection remoteConnection =
+                            CtsConnectionService.createRemoteOutgoingConnectionToTelecom(
+                                    TEST_REMOTE_PHONE_ACCOUNT_HANDLE, remoteRequest);
+                    connection.setRemoteConnection(remoteConnection);
+                    return connection;
+                }
+            };
+            setupConnectionServices(managerConnectionService, null, FLAG_REGISTER | FLAG_ENABLE);
+        } catch(Exception e) {
+            fail("Error in setting up the connection services");
+        }
+        placeAndVerifyCall();
+        /**
+         * Retrieve the connection from both the connection services and see if the plumbing via
+         * RemoteConnection object is working.
+         */
+        mConnection = verifyConnectionForOutgoingCall();
+        mRemoteConnection = verifyConnectionForOutgoingCallOnRemoteCS();
+        mRemoteConnectionObject = mConnection.getRemoteConnection();
+    }
+
+    private void addRemoteConnectionIncomingCall() {
+        try {
+            MockConnectionService managerConnectionService = new MockConnectionService() {
+                @Override
+                public Connection onCreateIncomingConnection(
+                        PhoneAccountHandle connectionManagerPhoneAccount,
+                        ConnectionRequest request) {
+                    MockConnection connection = (MockConnection)super.onCreateIncomingConnection(
+                            connectionManagerPhoneAccount, request);
+                    ConnectionRequest remoteRequest = new ConnectionRequest(
+                            TEST_REMOTE_PHONE_ACCOUNT_HANDLE,
+                            request.getAddress(),
+                            request.getExtras());
+                    RemoteConnection remoteConnection =
+                            CtsConnectionService.createRemoteIncomingConnectionToTelecom(
+                                    TEST_REMOTE_PHONE_ACCOUNT_HANDLE, remoteRequest);
+                    connection.setRemoteConnection(remoteConnection);
+                    return connection;
+                }
+            };
+            setupConnectionServices(managerConnectionService, null, FLAG_REGISTER | FLAG_ENABLE);
+        } catch(Exception e) {
+            fail("Error in setting up the connection services");
+        }
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        /**
+         * Retrieve the connection from both the connection services and see if the plumbing via
+         * RemoteConnection object is working.
+         */
+        mConnection = verifyConnectionForIncomingCall();
+        mRemoteConnection = verifyConnectionForIncomingCallOnRemoteCS();
+        mRemoteConnectionObject = mConnection.getRemoteConnection();
+    }
+
+    private Handler setupRemoteConnectionCallbacksTest() {
+        addRemoteConnectionOutgoingCall();
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+        verifyRemoteConnectionObject(mRemoteConnectionObject, mRemoteConnection);
+
+        // Create a looper thread for the callbacks.
+        HandlerThread workerThread = new HandlerThread("CallbackThread");
+        workerThread.start();
+        Handler handler = new Handler(workerThread.getLooper());
+        return handler;
+    }
+
+    private Handler setupRemoteConnectionVideoCallbacksTest() {
+        addRemoteConnectionOutgoingCall();
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+        verifyRemoteConnectionObject(mRemoteConnectionObject, mRemoteConnection);
+
+        // Create a looper thread for the callbacks.
+        HandlerThread workerThread = new HandlerThread("CallbackThread");
+        workerThread.start();
+        Handler handler = new Handler(workerThread.getLooper());
+
+        final InvokeCounter callbackInvoker = new InvokeCounter("RemoteConnectionCallbacks");
+
+        RemoteConnection.Callback callback = new RemoteConnection.Callback() {
+            @Override
+            public void onVideoProviderChanged(
+                    RemoteConnection connection, VideoProvider videoProvider) {
+                callbackInvoker.invoke(connection, videoProvider);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        mRemoteConnection.createMockVideoProvider();
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+        return handler;
+    }
+
+    private Handler setupRemoteConnectionVideoTest(MockVideoProvider mockVideoProvider) {
+        addRemoteConnectionOutgoingCall();
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+        verifyRemoteConnectionObject(mRemoteConnectionObject, mRemoteConnection);
+
+        // Create a looper thread for the callbacks.
+        HandlerThread workerThread = new HandlerThread("CallbackThread");
+        workerThread.start();
+        Handler handler = new Handler(workerThread.getLooper());
+
+        final InvokeCounter callbackInvoker = new InvokeCounter("RemoteConnectionCallbacks");
+
+        RemoteConnection.Callback callback = new RemoteConnection.Callback() {
+            @Override
+            public void onVideoProviderChanged(
+                    RemoteConnection connection, VideoProvider videoProvider) {
+                callbackInvoker.invoke(connection, videoProvider);
+            }
+        };
+        mRemoteConnectionObject.registerCallback(callback, handler);
+        mRemoteConnection.setVideoProvider(mockVideoProvider);
+        callbackInvoker.waitForCount(1, WAIT_FOR_STATE_CHANGE_TIMEOUT_MS);
+        assertEquals(mRemoteConnectionObject, callbackInvoker.getArgs(0)[0]);
+        mRemoteConnectionObject.unregisterCallback(callback);
+        return handler;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/SimCallManagerTest.java b/tests/tests/telecom/src/android/telecom/cts/SimCallManagerTest.java
new file mode 100644
index 0000000..a7961c3
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/SimCallManagerTest.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 android.telecom.cts;
+
+import static android.telecom.cts.TestUtils.ACCOUNT_ID;
+import static android.telecom.cts.TestUtils.ACCOUNT_LABEL;
+import static android.telecom.cts.TestUtils.COMPONENT;
+import static android.telecom.cts.TestUtils.PACKAGE;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.Color;
+import android.net.Uri;
+import android.os.PersistableBundle;
+import android.telecom.PhoneAccount;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.telephony.CarrierConfigManager;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+
+import java.util.Arrays;
+
+/**
+ * Verifies the behavior of TelecomManager.getSimCallManager() with respect to the default dialer
+ */
+public class SimCallManagerTest extends InstrumentationTestCase {
+    public static final PhoneAccountHandle TEST_PHONE_ACCOUNT_HANDLE =
+            new PhoneAccountHandle(new ComponentName(PACKAGE, COMPONENT), ACCOUNT_ID);
+
+    public static final PhoneAccount TEST_SIM_CALL_MANAGER_ACCOUNT = PhoneAccount.builder(
+            TEST_PHONE_ACCOUNT_HANDLE, ACCOUNT_LABEL)
+            .setAddress(Uri.parse("tel:555-TEST"))
+            .setSubscriptionAddress(Uri.parse("tel:555-TEST"))
+            .setCapabilities(PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
+            .setHighlightColor(Color.RED)
+            .setShortDescription(ACCOUNT_LABEL)
+            .setSupportedUriSchemes(Arrays.asList("tel"))
+            .build();
+
+    private Context mContext;
+    private TelecomManager mTelecomManager;
+    private String mPreviousDefaultDialer = null;
+    private String mSystemDialer = null;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation());
+        // Reset the current dialer to the system dialer, to ensure that we start each test
+        // without being the default dialer.
+        mSystemDialer = TestUtils.getSystemDialer(getInstrumentation());
+        if (!TextUtils.isEmpty(mSystemDialer)) {
+            TestUtils.setDefaultDialer(getInstrumentation(), mSystemDialer);
+        }
+        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!TextUtils.isEmpty(mPreviousDefaultDialer)) {
+            // Restore the default dialer to whatever the default dialer was before the tests
+            // were started. This may or may not be the system dialer.
+            TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer);
+        }
+        super.tearDown();
+    }
+
+    public void testGetSimCallManager() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+
+        // By default, getSimCallManager should return either the carrier configured sim call
+        // manager or the system dialer's sim call manager.
+        assertEquals(mSystemDialer, mTelecomManager.getDefaultDialerPackage());
+        assertNotSame(TEST_PHONE_ACCOUNT_HANDLE, mTelecomManager.getSimCallManager());
+
+        ComponentName carrierConfigSimCallManager = null;
+        CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(
+                Context.CARRIER_CONFIG_SERVICE);
+        PersistableBundle configBundle = configManager.getConfig();
+        if (configBundle != null) {
+            final String componentString = configBundle.getString(
+                    CarrierConfigManager.KEY_DEFAULT_SIM_CALL_MANAGER_STRING);
+            if (!TextUtils.isEmpty(componentString)) {
+                carrierConfigSimCallManager = ComponentName.unflattenFromString(componentString);
+            }
+        }
+
+        // If the default dialer has not registered a sim call manager, getSimCallManager should
+        // return the carrier configured sim call manager (which can be null).
+        PhoneAccountHandle simCallManager = mTelecomManager.getSimCallManager();
+        TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+        assertEquals(TestUtils.PACKAGE, mTelecomManager.getDefaultDialerPackage());
+        assertNotSame(TEST_PHONE_ACCOUNT_HANDLE, mTelecomManager.getSimCallManager());
+        assertEquals("Sim call manager should be the carrier configured value if no default-dialer"
+                + " provided value",
+                carrierConfigSimCallManager,
+                simCallManager == null ? null : simCallManager.getComponentName());
+
+        // Once the default dialer has registered a sim call manager, getSimCallManager should
+        // return the new sim call manager.
+        mTelecomManager.registerPhoneAccount(TEST_SIM_CALL_MANAGER_ACCOUNT);
+        assertEquals("Sim call manager should be default dialer's sim call manager if provided"
+                + " by default dialer",
+                TEST_PHONE_ACCOUNT_HANDLE,
+                mTelecomManager.getSimCallManager());
+
+        // If the dialer is no longer the default dialer, it is no longer the sim call manager.
+        TestUtils.setDefaultDialer(getInstrumentation(), mSystemDialer);
+        assertNotSame(TEST_PHONE_ACCOUNT_HANDLE, mTelecomManager.getSimCallManager());
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/TelecomAvailabilityTest.java b/tests/tests/telecom/src/android/telecom/cts/TelecomAvailabilityTest.java
new file mode 100644
index 0000000..cc0afe4
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/TelecomAvailabilityTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 android.content.Context;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.net.Uri;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for Telecom service. These tests only run on L+ devices because Telecom was
+ * added in L.
+ */
+public class TelecomAvailabilityTest extends InstrumentationTestCase {
+    private static final String TAG = TelecomAvailabilityTest.class.getSimpleName();
+    private static final String TELECOM_PACKAGE_NAME = "com.android.server.telecom";
+    private static final String TELEPHONY_PACKAGE_NAME = "com.android.phone";
+
+    private PackageManager mPackageManager;
+    private Context mContext;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        mPackageManager = getInstrumentation().getTargetContext().getPackageManager();
+    }
+
+    /**
+     * Test that the Telecom APK is pre-installed and a system app (FLAG_SYSTEM).
+     */
+    public void testTelecomIsPreinstalledAndSystem() {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+
+        PackageInfo packageInfo = findOnlyTelecomPackageInfo(mPackageManager);
+        ApplicationInfo applicationInfo = packageInfo.applicationInfo;
+        assertTrue("Telecom APK must be FLAG_SYSTEM",
+                (applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
+        Log.d(TAG, String.format("Telecom APK is FLAG_SYSTEM %d", applicationInfo.flags));
+    }
+
+    /**
+     * Test that the Telecom APK is registered to handle CALL intents, and that the Telephony APK
+     * is not.
+     */
+    public void testTelecomHandlesCallIntents() {
+        if (!shouldTestTelecom(mContext)) {
+            return;
+        }
+
+        final Intent intent = new Intent(Intent.ACTION_CALL, Uri.fromParts("tel", "1234567", null));
+        final List<ResolveInfo> activities =
+                mPackageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
+
+        boolean telecomMatches = false;
+        boolean telephonyMatches = false;
+        for (ResolveInfo resolveInfo : activities) {
+            if (resolveInfo.activityInfo == null) {
+                continue;
+            }
+            if (!telecomMatches
+                    && TELECOM_PACKAGE_NAME.equals(resolveInfo.activityInfo.packageName)) {
+                telecomMatches = true;
+            } else if (!telephonyMatches
+                    && TELEPHONY_PACKAGE_NAME.equals(resolveInfo.activityInfo.packageName)) {
+                telephonyMatches = true;
+            }
+        }
+
+        assertTrue("Telecom APK must be registered to handle CALL intents", telecomMatches);
+        assertFalse("Telephony APK must NOT be registered to handle CALL intents",
+                telephonyMatches);
+    }
+
+    /**
+     * @return The {@link PackageInfo} of the only app named {@code PACKAGE_NAME}.
+     */
+    private static PackageInfo findOnlyTelecomPackageInfo(PackageManager packageManager) {
+        List<PackageInfo> telecomPackages = findMatchingPackages(packageManager);
+        assertEquals(String.format("There must be only one package named %s", TELECOM_PACKAGE_NAME),
+                1, telecomPackages.size());
+        return telecomPackages.get(0);
+    }
+
+    /**
+     * Finds all packages that have {@code PACKAGE_NAME} name.
+     *
+     * @param pm the android package manager
+     * @return a list of {@link PackageInfo} records
+     */
+    private static List<PackageInfo> findMatchingPackages(PackageManager pm) {
+        List<PackageInfo> packageInfoList = new ArrayList<PackageInfo>();
+        for (PackageInfo info : pm.getInstalledPackages(0)) {
+            if (TELECOM_PACKAGE_NAME.equals(info.packageName)) {
+                packageInfoList.add(info);
+            }
+        }
+        return packageInfoList;
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
new file mode 100644
index 0000000..d1a9723
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.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.telecom.cts;
+
+import android.app.Instrumentation;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+import android.telecom.PhoneAccountHandle;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+public class TestUtils {
+    static final String TAG = "TelecomCTSTests";
+    static final boolean HAS_TELECOM = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+    static final long WAIT_FOR_STATE_CHANGE_TIMEOUT_MS = 10000;
+    static final long WAIT_FOR_CALL_ADDED_TIMEOUT_S = 15;
+
+    // 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 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";
+    public static final String REMOTE_ACCOUNT_ID = "xtstest_REMOTE_CALL_PROVIDER_ID";
+
+    public static final String ACCOUNT_LABEL = "CTSConnectionService";
+    public static final String REMOTE_ACCOUNT_LABEL = "CTSRemoteConnectionService";
+
+    private static final String COMMAND_SET_DEFAULT_DIALER = "telecom set-default-dialer ";
+
+    private static final String COMMAND_GET_DEFAULT_DIALER = "telecom get-default-dialer";
+
+    private static final String COMMAND_GET_SYSTEM_DIALER = "telecom get-system-dialer";
+
+    private static final String COMMAND_ENABLE = "telecom set-phone-account-enabled ";
+
+    private static final String COMMAND_REGISTER_SIM = "telecom register-sim-phone-account ";
+
+    public static final String MERGE_CALLER_NAME = "calls-merged";
+    public static final String SWAP_CALLER_NAME = "calls-swapped";
+
+    public static boolean shouldTestTelecom(Context context) {
+        if (!HAS_TELECOM) {
+            return false;
+        }
+        final PackageManager pm = context.getPackageManager();
+        return pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY) &&
+                pm.hasSystemFeature(PackageManager.FEATURE_CONNECTION_SERVICE);
+    }
+
+    public static String setDefaultDialer(Instrumentation instrumentation, String packageName)
+            throws Exception {
+        return executeShellCommand(instrumentation, COMMAND_SET_DEFAULT_DIALER + packageName);
+    }
+
+    public static String getDefaultDialer(Instrumentation instrumentation) throws Exception {
+        return executeShellCommand(instrumentation, COMMAND_GET_DEFAULT_DIALER);
+    }
+
+    public static String getSystemDialer(Instrumentation instrumentation) throws Exception {
+        return executeShellCommand(instrumentation, COMMAND_GET_SYSTEM_DIALER);
+    }
+
+    public static void enablePhoneAccount(Instrumentation instrumentation,
+            PhoneAccountHandle handle) throws Exception {
+        final ComponentName component = handle.getComponentName();
+        executeShellCommand(instrumentation, COMMAND_ENABLE
+                + component.getPackageName() + "/" + component.getClassName() + " "
+                + handle.getId());
+    }
+
+    public static void registerSimPhoneAccount(Instrumentation instrumentation,
+            PhoneAccountHandle handle, String label, String address) throws Exception {
+        final ComponentName component = handle.getComponentName();
+        executeShellCommand(instrumentation, COMMAND_REGISTER_SIM
+                + component.getPackageName() + "/" + component.getClassName() + " "
+                + handle.getId() + " " + label + " " + address);
+    }
+
+    /**
+     * Executes the given shell command and returns the output in a string. Note that even
+     * if we don't care about the output, we have to read the stream completely to make the
+     * command execute.
+     */
+    public static String executeShellCommand(Instrumentation instrumentation,
+            String command) throws Exception {
+        final ParcelFileDescriptor pfd =
+                instrumentation.getUiAutomation().executeShellCommand(command);
+        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) {
+                closeQuietly(br);
+            }
+            closeQuietly(pfd);
+        }
+    }
+
+    private static void closeQuietly(AutoCloseable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java b/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java
new file mode 100644
index 0000000..fbfa998
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/VideoCallTest.java
@@ -0,0 +1,842 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.graphics.SurfaceTexture;
+import android.telecom.Call;
+import android.telecom.Connection;
+import android.telecom.InCallService;
+import android.telecom.VideoProfile;
+import android.util.Log;
+import android.view.Surface;
+import android.view.TextureView;
+
+import static android.telecom.cts.TestUtils.shouldTestTelecom;
+
+/**
+ * Suites of tests that use {@link MockVideoProvider} and {@link MockVideoCallCallback} to verify
+ * the functionality of the video APIs.
+ *
+ * Note: You'll notice the use of {@code work}, and
+ * {@code doWorkAndWaitUntilConditionIsTrueOrTimeout} here.  The problem is the
+ * {@link MockVideoProvider} is running using a Handler.  To get it to emit mock data that is
+ * in sync with the setup operations performed on the handler, we'd need access to its handler.
+ * The handler of the {@link Connection.VideoProvider} is, however, not public.  As a workaround
+ * we will call local methods on the MockVideoProvider.  This means there is a chance the
+ * VideoProvider will emit the data we're interested in before the callbacks (on the handler)
+ * are even set up.  Consequently, the callbacks we're depending on in our test may not get
+ * called.  To compensate we will call the test methods on the provider repeatedly until we
+ * hear back via our callback.  Suboptimal, but it works.
+ */
+public class VideoCallTest extends BaseTelecomTestWithMockServices {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mShouldTestTelecom) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
+    /**
+     * Tests ability to start a 2-way video call and retrieve its video state.
+     */
+    public void testMakeTwoWayVideoCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+
+        assertCallState(call, Call.STATE_DIALING);
+        connection.setActive();
+        assertCallState(call, Call.STATE_ACTIVE);
+
+        assertVideoState(call, VideoProfile.STATE_BIDIRECTIONAL);
+        assertVideoCallbackRegistered(inCallService, call, true);
+    }
+
+    /**
+     * Tests ability to start a 1-way video call and retrieve its video state.
+     */
+    public void testMakeOneWayVideoCall() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall(VideoProfile.STATE_TX_ENABLED);
+        verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+
+        assertVideoState(call, VideoProfile.STATE_TX_ENABLED);
+        assertVideoCallbackRegistered(inCallService, call, true);
+    }
+
+    /**
+     * Tests ability to upgrade an audio-only call to a video call.
+     */
+    public void testUpgradeToVideo() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
+        verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+        assertVideoState(call, VideoProfile.STATE_AUDIO_ONLY);
+        assertVideoCallbackRegistered(inCallService, call, true);
+
+        // Send request to upgrade to video.
+        InCallService.VideoCall videoCall = call.getVideoCall();
+        videoCall.sendSessionModifyRequest(new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL));
+        assertVideoState(call, VideoProfile.STATE_BIDIRECTIONAL);
+        assertResponseVideoProfileReceived(inCallService.getVideoCallCallback(call),
+                VideoProfile.STATE_BIDIRECTIONAL);
+    }
+
+    /**
+     * Tests ability to receive a session modification request.
+     */
+    public void testReceiveSessionModifyRequest() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+
+        assertVideoState(call, VideoProfile.STATE_AUDIO_ONLY);
+        assertVideoCallbackRegistered(inCallService, call, true);
+
+        // Have the video profile mock reception of a request.
+        assertRequestVideoProfileReceived(inCallService.getVideoCallCallback(call),
+                VideoProfile.STATE_BIDIRECTIONAL,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection.sendMockSessionModifyRequest(
+                                new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL));
+                    }
+                });
+    }
+
+    /**
+     * Tests ability to send a session modification response.
+     */
+    public void testSendSessionModifyResponse() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall(VideoProfile.STATE_AUDIO_ONLY);
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+        final MockVideoProvider mockVideoProvider = connection.getMockVideoProvider();
+        assertVideoState(call, VideoProfile.STATE_AUDIO_ONLY);
+        assertVideoCallbackRegistered(inCallService, call, true);
+
+        InCallService.VideoCall videoCall = call.getVideoCall();
+        videoCall.sendSessionModifyResponse(new VideoProfile(VideoProfile.STATE_BIDIRECTIONAL));
+        assertSessionModifyResponse(mockVideoProvider, VideoProfile.STATE_BIDIRECTIONAL);
+    }
+
+    /**
+     * 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
+     * expect there will be some overhead associated with configuring the camera at the start of
+     * the call.
+     */
+    public void testVideoCallDelayProvider() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        // Don't create video provider when call is created initially; we will do this later.
+        try {
+            connectionService.setCreateVideoProvider(false);
+            placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
+            final MockConnection connection = verifyConnectionForOutgoingCall();
+
+            final MockInCallService inCallService = mInCallCallbacks.getService();
+            final Call call = inCallService.getLastCall();
+
+            assertVideoState(call, VideoProfile.STATE_BIDIRECTIONAL);
+            // After initial connection creation there should not be a video provider or callbacks
+            // registered.
+            assertVideoCallbackRegistered(inCallService, call, false);
+
+            // Trigger delayed creation of video provider and registration of callbacks and assert that
+            // it happened.
+            connection.createMockVideoProvider();
+            assertVideoCallbackRegistered(inCallService, call, true);
+
+            // Ensure video providers are created in the future.
+        } finally {
+            connectionService.setCreateVideoProvider(true);
+        }
+    }
+
+
+    /**
+     * Tests ability to change the current camera.  Ensures that the camera capabilities are sent
+     * back in response.
+     */
+    public void testChangeCamera() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
+        verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+        assertVideoCallbackRegistered(inCallService, call, true);
+        final InCallService.VideoCall videoCall = call.getVideoCall();
+
+        videoCall.setCamera(MockVideoProvider.CAMERA_FRONT);
+        assertCameraCapabilitiesReceived(inCallService.getVideoCallCallback(call),
+                MockVideoProvider.CAMERA_FRONT_DIMENSIONS);
+
+        videoCall.setCamera(MockVideoProvider.CAMERA_BACK);
+        assertCameraCapabilitiesReceived(inCallService.getVideoCallCallback(call),
+                MockVideoProvider.CAMERA_BACK_DIMENSIONS);
+    }
+
+    /**
+     * Tests ability to request the camera capabilities from the video provider.
+     */
+    public void testRequestCameraCapabilities() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
+        verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+        assertVideoCallbackRegistered(inCallService, call, true);
+        final InCallService.VideoCall videoCall = call.getVideoCall();
+
+        // First, set the camera.
+        videoCall.setCamera(MockVideoProvider.CAMERA_FRONT);
+        // Retrieve the camera capabilities that are automatically send when the camera is set --
+        // ensures the cached value is cleared first.
+        inCallService.getVideoCallCallback(call).getCameraCapabilities();
+
+        // Now, request capabilities.
+        videoCall.requestCameraCapabilities();
+        assertCameraCapabilitiesReceived(inCallService.getVideoCallCallback(call),
+                MockVideoProvider.CAMERA_FRONT_DIMENSIONS);
+    }
+
+    /**
+     * Tests ability to request data usage from the video provider.
+     */
+    public void testRequestDataUsage() {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall(VideoProfile.STATE_BIDIRECTIONAL);
+        verifyConnectionForOutgoingCall();
+
+        final MockInCallService inCallService = mInCallCallbacks.getService();
+        final Call call = inCallService.getLastCall();
+        assertVideoCallbackRegistered(inCallService, call, true);
+        final InCallService.VideoCall videoCall = call.getVideoCall();
+
+        videoCall.requestCallDataUsage();
+        assertCallDataUsageReceived(inCallService.getVideoCallCallback(call),
+                MockVideoProvider.DATA_USAGE);
+    }
+
+    /**
+     * Tests ability to receive changes to the video quality from the video provider.
+     */
+    public void testReceiveVideoQuality() {
+        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);
+
+        assertVideoQualityReceived(inCallService.getVideoCallCallback(call),
+                VideoProfile.QUALITY_HIGH,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection
+                                .sendMockVideoQuality(VideoProfile.QUALITY_HIGH);
+                    }
+                });
+
+        assertVideoQualityReceived(inCallService.getVideoCallCallback(call),
+                VideoProfile.QUALITY_MEDIUM,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection
+                                .sendMockVideoQuality(VideoProfile.QUALITY_MEDIUM);
+                    }
+                });
+    }
+
+    /**
+     * Tests ability to receive call session events from the video provider.
+     */
+    public void testReceiveCallSessionEvent() {
+        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);
+
+        assertCallSessionEventReceived(inCallService.getVideoCallCallback(call),
+                Connection.VideoProvider.SESSION_EVENT_CAMERA_READY,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection.sendMockCallSessionEvent(
+                                Connection.VideoProvider.SESSION_EVENT_CAMERA_READY);
+                    }
+                });
+    }
+
+    /**
+     * Tests ability to receive changes to the peer dimensions from the video provider.
+     */
+    public void testReceivePeerDimensionChange() {
+        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);
+
+        assertPeerWidthChanged(inCallService.getVideoCallCallback(call),
+                MockVideoProvider.CAMERA_BACK_DIMENSIONS,
+                new Work() {
+                    @Override
+                    public void doWork() {
+                        connection.sendMockPeerWidth(MockVideoProvider.CAMERA_BACK_DIMENSIONS);
+                    }
+                });
+    }
+
+    /**
+     * Tests ability to set the device orientation via the provider.
+     */
+    public void testSetDeviceOrientation() {
+        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();
+
+        // Set device orientation and ensure provider knows about it.
+        videoCall.setDeviceOrientation(90);
+        assertDeviceOrientationChanged(mockVideoProvider, 90);
+    }
+
+    /**
+     * Tests ability to set the preview surface via the provider.
+     */
+    public void testSetPreviewSurface() {
+        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();
+
+        Surface surface = new Surface(new SurfaceTexture(1));
+        // Set a surface
+        videoCall.setPreviewSurface(surface);
+        assertPreviewSurfaceChanged(mockVideoProvider, true);
+
+        // Clear the surface
+        videoCall.setPreviewSurface(null);
+        assertPreviewSurfaceChanged(mockVideoProvider, false);
+    }
+
+    /**
+     * Tests ability to set the display surface via the provider.
+     */
+    public void testSetDisplaySurface() {
+        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();
+
+        // Set a surface
+        Surface surface = new Surface(new SurfaceTexture(1));
+        videoCall.setDisplaySurface(surface);
+        assertDisplaySurfaceChanged(mockVideoProvider, true);
+
+        // Clear the surface
+        videoCall.setDisplaySurface(null);
+        assertDisplaySurfaceChanged(mockVideoProvider, false);
+    }
+
+    /**
+     * Tests ability to set the camera zoom via the provider.
+     */
+    public void testSetZoom() {
+        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();
+
+        videoCall.setZoom(0.0f);
+        assertZoomChanged(mockVideoProvider, 0.0f);
+
+        videoCall.setZoom(10.0f);
+        assertZoomChanged(mockVideoProvider, 10.0f);
+
+        call.disconnect();
+    }
+
+    /**
+     * Asserts that a call video state is as expected.
+     *
+     * @param call The call.
+     * @param videoState The expected video state.
+     */
+    private void assertVideoState(final Call call, final int videoState) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return videoState;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return call.getDetails().getVideoState();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call should be in videoState " + videoState
+        );
+    }
+
+    /**
+     * Asserts whether the InCallService has registered a video call back (and hence a video call)
+     * for a call.
+     *
+     * @param inCallService The incall service.
+     * @param call The call.
+     * @param isRegistered The expected registration state.
+     */
+    private void assertVideoCallbackRegistered(final MockInCallService inCallService,
+            final Call call, final Boolean isRegistered) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return isRegistered;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return inCallService.isVideoCallbackRegistered(call);
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Video callback registration state should be " + isRegistered
+        );
+    }
+
+    /**
+     * Asserts whether the camera capabilities have changed to an expected value.  Compares the
+     * camera height only (the {@link MockVideoProvider} sets height and width to be the same.
+     *
+     * @param videoCallCallback The video call callback.
+     * @param expectedCameraWidthHeight The expected width and height.
+     */
+    private void assertCameraCapabilitiesReceived(final MockVideoCallCallback videoCallCallback,
+            final int expectedCameraWidthHeight) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expectedCameraWidthHeight;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        VideoProfile.CameraCapabilities cameraCapabilities =
+                                videoCallCallback.getCameraCapabilities();
+                        return cameraCapabilities == null ? 0 : cameraCapabilities.getHeight();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Camera width and height should be " + expectedCameraWidthHeight
+        );
+    }
+
+    /**
+     * Asserts whether the call data usage has changed to the expected value.
+     *
+     * @param videoCallCallback The video call callback.
+     * @param expectedDataUsage The expected data usage.
+     */
+    private void assertCallDataUsageReceived(final MockVideoCallCallback videoCallCallback,
+            final long expectedDataUsage) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expectedDataUsage;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return videoCallCallback.getDataUsage();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Data usage should be " + expectedDataUsage
+        );
+    }
+
+    /**
+     * Asserts whether the video quality has changed to the expected value.
+     *
+     * @param videoCallCallback The video call callback.
+     * @param expectedVideoQuality The expected video quality.
+     * @param work The work to perform to have the provider emit the video quality.
+     */
+    private void assertVideoQualityReceived(final MockVideoCallCallback videoCallCallback,
+            final int expectedVideoQuality, final Work work) {
+        doWorkAndWaitUntilConditionIsTrueOrTimeout(
+                work,
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expectedVideoQuality;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return videoCallCallback.getVideoQuality();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Video quality should be " + expectedVideoQuality
+        );
+    }
+
+    /**
+     * Asserts whether the call session event has changed to the expected value.
+     *
+     * @param videoCallCallback The video call callback.
+     * @param expectedEvent The expected event.
+     * @param work The work to be performed to send the call session event from the provider.
+     */
+    private void assertCallSessionEventReceived(final MockVideoCallCallback videoCallCallback,
+            final int expectedEvent, final Work work) {
+        doWorkAndWaitUntilConditionIsTrueOrTimeout(
+                work,
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expectedEvent;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return videoCallCallback.getCallSessionEvent();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Call session event should be " + expectedEvent
+        );
+    }
+
+    /**
+     * Asserts whether the peer width has changed to the expected value.
+     *
+     * @param videoCallCallback The video call callback.
+     * @param expectedWidth The expected width.
+     * @param work The work to be performed to send the peer width from the provider.
+     */
+    private void assertPeerWidthChanged(final MockVideoCallCallback videoCallCallback,
+            final int expectedWidth, final Work work) {
+        doWorkAndWaitUntilConditionIsTrueOrTimeout(
+                work,
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expectedWidth;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return videoCallCallback.getPeerWidth();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Peer width should be " + expectedWidth
+        );
+    }
+
+    /**
+     * Asserts whether the device orientation has changed to the expected value.
+     *
+     * @param mockVideoProvider The mock video provider.
+     * @param expected The expected device orientation.
+     */
+    private void assertDeviceOrientationChanged(final MockVideoProvider mockVideoProvider,
+            final int expected) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return mockVideoProvider.getDeviceOrientation();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Orientation should be " + expected
+        );
+    }
+
+    /**
+     * Asserts whether the preview surface has been set or not.
+     *
+     * @param mockVideoProvider The mock video provider.
+     * @param expected {@code true} if it is expected the preview surface is not null, {@code false}
+     *                             if it is expected the preview surface is null.
+     */
+    private void assertPreviewSurfaceChanged(final MockVideoProvider mockVideoProvider,
+            final boolean expected) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return mockVideoProvider.getPreviewSurface() != null;
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Preview should be set? " + expected
+        );
+    }
+
+    /**
+     * Asserts whether the display surface has been set or not.
+     *
+     * @param mockVideoProvider The mock video provider.
+     * @param expected {@code true} if it is expected the display surface is not null, {@code false}
+     *                             if it is expected the display surface is null.
+     */
+    private void assertDisplaySurfaceChanged(final MockVideoProvider mockVideoProvider,
+            final boolean expected) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        return mockVideoProvider.getDisplaySurface() != null;
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Display should be set? " + expected
+        );
+    }
+
+    /**
+     * Asserts whether the zoom has changed to the expected value.  Note: To make comparisons easier
+     * the floats are cast to ints, so ensure only whole values are used.
+     *
+     * @param mockVideoProvider The mock video provider.
+     * @param expected The expected zoom.
+     */
+    private void assertZoomChanged(final MockVideoProvider mockVideoProvider,
+            final float expected) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        // Cast to int so we're not doing float equality
+                        return (int)expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        // Cast to int so we're not doing float equality
+                        return (int)mockVideoProvider.getZoom();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Zoom should be " + expected
+        );
+    }
+
+    /**
+     * Asserts whether a response video profile has been received
+     *
+     * @param videoCallCallback The video call callback.
+     * @param expected The expected video state.
+     */
+    private void assertResponseVideoProfileReceived(final MockVideoCallCallback videoCallCallback,
+            final int expected) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        VideoProfile videoProfile = videoCallCallback.getResponseProfile();
+                        return videoProfile == null ? -1 : videoProfile.getVideoState();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Video state should be " + expected
+        );
+    }
+
+    /**
+     * Asserts whether a session modification request has been received.
+     *
+     * @param videoCallCallback The video call callback.
+     * @param expected The expected video state.
+     * @param work The work to be performed to cause the session modification request to be emit
+     *             from the provider.
+     */
+    private void assertRequestVideoProfileReceived(final MockVideoCallCallback videoCallCallback,
+            final int expected, final Work work) {
+        doWorkAndWaitUntilConditionIsTrueOrTimeout(
+                work,
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        VideoProfile videoProfile = videoCallCallback.getRequestProfile();
+                        return videoProfile == null ? -1 : videoProfile.getVideoState();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Video state should be " + expected
+        );
+    }
+
+    /**
+     * Asserts whether the provider got a session modify response with the expected value.
+     *
+     * @param mockVideoProvider The mock video provider.
+     * @param expected The expected video state of the session modify response.
+     */
+    private void assertSessionModifyResponse(final MockVideoProvider mockVideoProvider,
+            final int expected) {
+        waitUntilConditionIsTrueOrTimeout(
+                new Condition() {
+                    @Override
+                    public Object expected() {
+                        return expected;
+                    }
+
+                    @Override
+                    public Object actual() {
+                        VideoProfile responseProfile = mockVideoProvider.getSessionModifyResponse();
+                        return responseProfile == null ? -1 : responseProfile.getVideoState();
+                    }
+                },
+                TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS,
+                "Session modify response video state should be " + expected
+        );
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/VideoProfileTest.java b/tests/tests/telecom/src/android/telecom/cts/VideoProfileTest.java
new file mode 100644
index 0000000..6c16abb
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/VideoProfileTest.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 android.telecom.VideoProfile;
+import android.test.AndroidTestCase;
+
+/**
+ * Tests helper methods in the {@link VideoProfile} class.
+ */
+public class VideoProfileTest extends AndroidTestCase {
+    public void testIsAudioOnly() {
+        assertTrue(VideoProfile.isAudioOnly(VideoProfile.STATE_AUDIO_ONLY));
+        assertTrue(VideoProfile.isAudioOnly(VideoProfile.STATE_PAUSED));
+
+        assertFalse(VideoProfile.isAudioOnly(VideoProfile.STATE_BIDIRECTIONAL));
+        assertFalse(VideoProfile.isAudioOnly(VideoProfile.STATE_TX_ENABLED));
+        assertFalse(VideoProfile.isAudioOnly(VideoProfile.STATE_RX_ENABLED));
+        assertFalse(VideoProfile
+                .isAudioOnly(VideoProfile.STATE_BIDIRECTIONAL | VideoProfile.STATE_PAUSED));
+        assertFalse(VideoProfile
+                .isAudioOnly(VideoProfile.STATE_TX_ENABLED | VideoProfile.STATE_PAUSED));
+        assertFalse(VideoProfile
+                .isAudioOnly(VideoProfile.STATE_RX_ENABLED | VideoProfile.STATE_PAUSED));
+    }
+
+    public void testIsVideo() {
+        assertTrue(VideoProfile.isVideo(VideoProfile.STATE_BIDIRECTIONAL));
+        assertTrue(VideoProfile.isVideo(VideoProfile.STATE_RX_ENABLED));
+        assertTrue(VideoProfile.isVideo(VideoProfile.STATE_TX_ENABLED));
+        assertTrue(VideoProfile.isVideo(VideoProfile.STATE_BIDIRECTIONAL |
+                VideoProfile.STATE_PAUSED));
+        assertTrue(VideoProfile.isVideo(VideoProfile.STATE_RX_ENABLED | VideoProfile.STATE_PAUSED));
+        assertTrue(VideoProfile.isVideo(VideoProfile.STATE_TX_ENABLED | VideoProfile.STATE_PAUSED));
+
+        assertFalse(VideoProfile.isVideo(VideoProfile.STATE_AUDIO_ONLY));
+        assertFalse(VideoProfile.isVideo(VideoProfile.STATE_PAUSED));
+    }
+
+    public void testIsBidirectional() {
+        assertTrue(VideoProfile.isBidirectional(VideoProfile.STATE_BIDIRECTIONAL));
+        assertTrue(VideoProfile.isBidirectional(VideoProfile.STATE_BIDIRECTIONAL |
+                VideoProfile.STATE_PAUSED));
+
+        assertFalse(VideoProfile.isBidirectional(VideoProfile.STATE_TX_ENABLED));
+        assertFalse(VideoProfile.isBidirectional(VideoProfile.STATE_TX_ENABLED |
+                VideoProfile.STATE_PAUSED));
+        assertFalse(VideoProfile.isBidirectional(VideoProfile.STATE_RX_ENABLED));
+        assertFalse(VideoProfile.isBidirectional(VideoProfile.STATE_RX_ENABLED |
+                VideoProfile.STATE_PAUSED));
+    }
+
+    public void testIsPaused() {
+        assertTrue(VideoProfile.isPaused(VideoProfile.STATE_PAUSED));
+        assertTrue(VideoProfile.isPaused(VideoProfile.STATE_BIDIRECTIONAL |
+                VideoProfile.STATE_PAUSED));
+        assertTrue(VideoProfile.isPaused(VideoProfile.STATE_TX_ENABLED |
+                VideoProfile.STATE_PAUSED));
+        assertTrue(VideoProfile.isPaused(VideoProfile.STATE_RX_ENABLED |
+                VideoProfile.STATE_PAUSED));
+
+        assertFalse(VideoProfile.isPaused(VideoProfile.STATE_AUDIO_ONLY));
+        assertFalse(VideoProfile.isPaused(VideoProfile.STATE_TX_ENABLED));
+        assertFalse(VideoProfile.isPaused(VideoProfile.STATE_RX_ENABLED));
+        assertFalse(VideoProfile.isPaused(VideoProfile.STATE_BIDIRECTIONAL));
+    }
+
+    public void testIsReceptionEnabled() {
+        assertTrue(VideoProfile.isReceptionEnabled(VideoProfile.STATE_RX_ENABLED));
+        assertTrue(VideoProfile.isReceptionEnabled(VideoProfile.STATE_BIDIRECTIONAL));
+        assertTrue(VideoProfile.isReceptionEnabled(VideoProfile.STATE_RX_ENABLED |
+                VideoProfile.STATE_PAUSED));
+        assertTrue(VideoProfile.isReceptionEnabled(VideoProfile.STATE_BIDIRECTIONAL |
+                VideoProfile.STATE_PAUSED));
+
+        assertFalse(VideoProfile.isReceptionEnabled(VideoProfile.STATE_AUDIO_ONLY));
+        assertFalse(VideoProfile.isReceptionEnabled(VideoProfile.STATE_TX_ENABLED));
+        assertFalse(VideoProfile.isReceptionEnabled(VideoProfile.STATE_PAUSED));
+    }
+
+    public void testIsTransmissionEnabled() {
+        assertTrue(VideoProfile.isTransmissionEnabled(VideoProfile.STATE_TX_ENABLED));
+        assertTrue(VideoProfile.isTransmissionEnabled(VideoProfile.STATE_BIDIRECTIONAL));
+        assertTrue(VideoProfile.isTransmissionEnabled(VideoProfile.STATE_TX_ENABLED |
+                VideoProfile.STATE_PAUSED));
+        assertTrue(VideoProfile.isTransmissionEnabled(VideoProfile.STATE_BIDIRECTIONAL |
+                VideoProfile.STATE_PAUSED));
+
+        assertFalse(VideoProfile.isTransmissionEnabled(VideoProfile.STATE_AUDIO_ONLY));
+        assertFalse(VideoProfile.isTransmissionEnabled(VideoProfile.STATE_RX_ENABLED));
+        assertFalse(VideoProfile.isTransmissionEnabled(VideoProfile.STATE_PAUSED));
+    }
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/WiredHeadsetTest.java b/tests/tests/telecom/src/android/telecom/cts/WiredHeadsetTest.java
new file mode 100644
index 0000000..e7130ba
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/WiredHeadsetTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.telecom.Call;
+import android.telecom.CallAudioState;
+import android.telecom.Connection;
+
+/**
+ * Verifies Telecom behavior with regards to interactions with a wired headset. These tests
+ * validate behavior that occurs as a result of short pressing or long pressing a wired headset's
+ * media button.
+ */
+public class WiredHeadsetTest extends BaseTelecomTestWithMockServices {
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mShouldTestTelecom) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
+    public void testIncomingCallShortPress_acceptsCall() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        final MockConnection connection = verifyConnectionForIncomingCall();
+
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_RINGING);
+        assertConnectionState(connection, Connection.STATE_RINGING);
+
+        sendMediaButtonShortPress();
+        assertCallState(call,  Call.STATE_ACTIVE);
+        assertConnectionState(connection, Connection.STATE_ACTIVE);
+    }
+
+    public void testIncomingCallLongPress_rejectsCall() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        addAndVerifyNewIncomingCall(createTestNumber(), null);
+        final MockConnection connection = verifyConnectionForIncomingCall();
+
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_RINGING);
+        assertConnectionState(connection, Connection.STATE_RINGING);
+
+        sendMediaButtonLongPress();
+        assertCallState(call, Call.STATE_DISCONNECTED);
+        assertConnectionState(connection, Connection.STATE_DISCONNECTED);
+    }
+
+    public void testInCallShortPress_togglesMute() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+        final MockInCallService incallService = mInCallCallbacks.getService();
+
+        // Verify that sending short presses in succession toggles the mute state of the
+        // connection.
+        // Before the audio state is changed for the first time, the connection might not
+        // know about its audio state yet.
+        assertMuteState(incallService, false);
+        sendMediaButtonShortPress();
+        assertMuteState(connection, true);
+        assertMuteState(incallService, true);
+        sendMediaButtonShortPress();
+        assertMuteState(connection, false);
+        assertMuteState(incallService, false);
+    }
+
+    public void testInCallLongPress_hangupCall() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+
+        placeAndVerifyCall();
+        final MockConnection connection = verifyConnectionForOutgoingCall();
+
+        final Call call = mInCallCallbacks.getService().getLastCall();
+        assertCallState(call, Call.STATE_DIALING);
+
+        connection.setActive();
+        assertCallState(call, Call.STATE_ACTIVE);
+
+        sendMediaButtonLongPress();
+        assertCallState(call, Call.STATE_DISCONNECTED);
+        assertConnectionState(connection, Connection.STATE_DISCONNECTED);
+    }
+
+    private void sendMediaButtonShortPress() throws Exception {
+        sendMediaButtonPress(false /* longPress */);
+    }
+
+    private void sendMediaButtonLongPress() throws Exception {
+        sendMediaButtonPress(true /* longPress */);
+    }
+
+    private void sendMediaButtonPress(boolean longPress) throws Exception {
+        final String command = "input keyevent " + (longPress ? "--longpress" : "--shortpress")
+                + " KEYCODE_HEADSETHOOK";
+        TestUtils.executeShellCommand(getInstrumentation(), command);
+    }
+}
diff --git a/tests/tests/telecom2/Android.mk b/tests/tests/telecom2/Android.mk
new file mode 100644
index 0000000..71edb7b
--- /dev/null
+++ b/tests/tests/telecom2/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.
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_PACKAGE_NAME := CtsTelecomTestCases2
+
+# 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
+
+src_dirs := src \
+    ../telecom/src
+
+res_dirs := res \
+    ../telecom/res
+
+LOCAL_SRC_FILES := $(call all-java-files-under, $(src_dirs))
+
+LOCAL_RESOURCE_DIR := $(addprefix $(LOCAL_PATH)/, $(res_dirs))
+
+LOCAL_AAPT_FLAGS := \
+    --auto-add-overlay \
+    --extra-packages com.android.cts.telecom \
+    --rename-manifest-package com.android.cts.telecom2 \
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telecom2/AndroidManifest.xml b/tests/tests/telecom2/AndroidManifest.xml
new file mode 100644
index 0000000..e618768
--- /dev/null
+++ b/tests/tests/telecom2/AndroidManifest.xml
@@ -0,0 +1,83 @@
+<?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.telecom2">
+    <uses-sdk android:minSdkVersion="21" />
+
+    <!--
+        This app contains tests to verify Telecom's behavior when the app is missing certain
+        permissions.
+    -->
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <service android:name="android.telecom.cts.MockConnectionService"
+            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE" >
+            <intent-filter>
+                <action android:name="android.telecom.ConnectionService" />
+            </intent-filter>
+        </service>
+
+        <service android:name="android.telecom.cts.MockInCallService"
+            android:permission="android.permission.BIND_INCALL_SERVICE" >
+            <intent-filter>
+                <action android:name="android.telecom.InCallService"/>
+            </intent-filter>
+        </service>
+
+        <activity android:name="android.telecom.cts.MockDialerActivity">
+            <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>
+            <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:scheme="voicemail" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.DIAL" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.BROWSABLE" />
+                <data android:scheme="tel" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.telecom2"
+                     android:label="CTS tests for android.telecom package">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/telecom2/res/.gitignore b/tests/tests/telecom2/res/.gitignore
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/tests/telecom2/res/.gitignore
diff --git a/tests/tests/telecom2/src/android/telecom/cts/DefaultDialerOperationsNoPermissionsTest.java b/tests/tests/telecom2/src/android/telecom/cts/DefaultDialerOperationsNoPermissionsTest.java
new file mode 100644
index 0000000..b3044a2
--- /dev/null
+++ b/tests/tests/telecom2/src/android/telecom/cts/DefaultDialerOperationsNoPermissionsTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Context;
+import android.telecom.TelecomManager;
+import android.test.InstrumentationTestCase;
+import android.text.TextUtils;
+
+/**
+ * Verifies that certain privileged operations can only be performed by the default dialer.
+ */
+public class DefaultDialerOperationsNoPermissionsTest extends InstrumentationTestCase {
+    private Context mContext;
+    private TelecomManager mTelecomManager;
+    private String mPreviousDefaultDialer = null;
+    private String mSystemDialer = null;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getContext();
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        TestUtils.PACKAGE = mContext.getPackageName();
+        mPreviousDefaultDialer = TestUtils.getDefaultDialer(getInstrumentation());
+        // Reset the current dialer to the system dialer, to ensure that we start each test
+        // without being the default dialer.
+        mSystemDialer = TestUtils.getSystemDialer(getInstrumentation());
+        if (!TextUtils.isEmpty(mSystemDialer)) {
+            TestUtils.setDefaultDialer(getInstrumentation(), mSystemDialer);
+        }
+        mTelecomManager = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (!TextUtils.isEmpty(mPreviousDefaultDialer)) {
+            // Restore the default dialer to whatever the default dialer was before the tests
+            // were started. This may or may not be the system dialer.
+            TestUtils.setDefaultDialer(getInstrumentation(), mPreviousDefaultDialer);
+        }
+        super.tearDown();
+    }
+
+    public void testShowInCallScreenPermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
+            @Override
+            public void run() {
+                mTelecomManager.showInCallScreen(false);
+            }
+        }, "showInCallScreen");
+    }
+
+    public void testGetCallCapableAccountsPermissions() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
+            @Override
+            public void run() {
+                mTelecomManager.getCallCapablePhoneAccounts();
+            }
+        }, "getCallCapableAccounts");
+    }
+
+    public void testGetDefaultOutgoingPhoneAccount() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
+            @Override
+            public void run() {
+                mTelecomManager.getDefaultOutgoingPhoneAccount("tel");
+            }
+        }, "getDefaultOutgoingPhoneAccount");
+    }
+
+    public void testGetLine1Number() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
+            @Override
+            public void run() {
+                mTelecomManager.getLine1Number(null);
+            }
+        }, "getLine1Number");
+    }
+
+    public void testGetVoicemailNumber() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
+            @Override
+            public void run() {
+                mTelecomManager.getVoiceMailNumber(null);
+            }
+        }, "getVoiceMailNumber");
+    }
+
+    public void testIsVoicemailNumber() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
+            @Override
+            public void run() {
+                mTelecomManager.isVoiceMailNumber(null, null);
+            }
+        }, "isVoiceMailNumber");
+    }
+
+    public void testIsInCall() throws Exception {
+        if (!TestUtils.shouldTestTelecom(mContext)) {
+            return;
+        }
+        verifyForReadPhoneStateOrDefaultDialer(new Runnable() {
+            @Override
+            public void run() {
+                mTelecomManager.isInCall();
+            }
+        }, "isInCall");
+    }
+
+    private void verifyForReadPhoneStateOrDefaultDialer(Runnable runnable, String methodName)
+            throws Exception{
+        try {
+            runnable.run();
+            fail("TelecomManager." + methodName + " should throw SecurityException if no "
+                    + "READ_PHONE_STATE permission");
+        } catch (SecurityException e) {
+        }
+
+        TestUtils.setDefaultDialer(getInstrumentation(), TestUtils.PACKAGE);
+        runnable.run();
+    }
+}
diff --git a/tests/tests/telephony/AndroidManifest.xml b/tests/tests/telephony/AndroidManifest.xml
index 31abf12..a87a54b 100644
--- a/tests/tests/telephony/AndroidManifest.xml
+++ b/tests/tests/telephony/AndroidManifest.xml
@@ -31,6 +31,9 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
 
     <application>
+        <provider android:name="android.telephony.cts.MmsPduProvider"
+                  android:authorities="telephonyctstest"
+                  android:grantUriPermissions="true" />
         <uses-library android:name="android.test.runner" />
     </application>
 
diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java
new file mode 100644
index 0000000..4ca35b8
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/CarrierConfigManagerTest.java
@@ -0,0 +1,96 @@
+/*
+ * 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.telephony.cts;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.os.PersistableBundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+
+public class CarrierConfigManagerTest extends AndroidTestCase {
+    private CarrierConfigManager mConfigManager;
+    private TelephonyManager mTelephonyManager;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTelephonyManager = (TelephonyManager)
+                getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        mConfigManager = (CarrierConfigManager)
+                getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+    }
+
+    /**
+     * Checks whether the telephony stack should be running on this device.
+     *
+     * Note: "Telephony" means only SMS/MMS and voice calls in some contexts, but we also care if
+     * the device supports cellular data.
+     */
+    private boolean hasTelephony() {
+        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 void checkConfig(PersistableBundle config) {
+        if (config == null) {
+            assertFalse("Config should only be null when telephony is not running.", hasTelephony());
+            return;
+        }
+        assertNotNull("CarrierConfigManager should not return null config", config);
+        if (!isSimCardPresent()) {
+            // 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);
+        }
+    }
+
+    public void testGetConfig() {
+        PersistableBundle config = mConfigManager.getConfig();
+        checkConfig(config);
+    }
+
+    public void testGetConfigForSubId() {
+        PersistableBundle config =
+                mConfigManager.getConfigForSubId(SubscriptionManager.getDefaultSubId());
+        checkConfig(config);
+    }
+
+    /**
+     * Tests the CarrierConfigManager.notifyConfigChangedForSubId() API. This makes a call to
+     * notifyConfigChangedForSubId() API and expects a SecurityException since the test apk is not signed
+     * by certificate on the SIM.
+     */
+    public void testNotifyConfigChangedForSubId() {
+        try {
+            if (isSimCardPresent()) {
+                mConfigManager.notifyConfigChangedForSubId(SubscriptionManager.getDefaultSubId());
+                fail("Expected SecurityException. App doesn't have carrier privileges.");
+            }
+        } catch (SecurityException expected) {
+        }
+    }
+
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java b/tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java
new file mode 100644
index 0000000..492f8ff
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/CarrierServiceTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.cts;
+
+import android.content.Intent;
+import android.os.PersistableBundle;
+import android.service.carrier.CarrierIdentifier;
+import android.service.carrier.CarrierService;
+import android.test.ServiceTestCase;
+
+public class CarrierServiceTest extends ServiceTestCase<CarrierServiceTest.TestCarrierService> {
+    public CarrierServiceTest() { super(TestCarrierService.class); }
+
+    public void testNotifyCarrierNetworkChange_true() {
+        notifyCarrierNetworkChange(true);
+    }
+
+    public void testNotifyCarrierNetworkChange_false() {
+        notifyCarrierNetworkChange(false);
+    }
+
+    private void notifyCarrierNetworkChange(boolean active) {
+        Intent intent = new Intent(getContext(), TestCarrierService.class);
+        startService(intent);
+
+        try {
+            getService().notifyCarrierNetworkChange(active);
+            fail("Expected SecurityException for notifyCarrierNetworkChange(" + active + ")");
+        } catch (SecurityException e) { /* Expected */ }
+    }
+
+    public static class TestCarrierService extends CarrierService {
+        @Override
+        public PersistableBundle onLoadConfig(CarrierIdentifier id) { return null; }
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
new file mode 100644
index 0000000..be29794
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/CellInfoTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.telephony.cts;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.telephony.CellInfo;
+import android.telephony.CellInfoGsm;
+import android.telephony.CellInfoLte;
+import android.telephony.CellInfoWcdma;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.util.Log;
+
+import java.util.List;
+
+/**
+ * Test TelephonyManager.getAllCellInfo()
+ * <p>
+ * TODO(chesnutt): test onCellInfoChanged() once the implementation
+ * of async callbacks is complete (see http://b/13788638)
+ */
+public class CellInfoTest extends AndroidTestCase{
+    private final Object mLock = new Object();
+    private TelephonyManager mTelephonyManager;
+    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 MIN_RSSI = -150;
+    private PackageManager mPm;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mTelephonyManager =
+                (TelephonyManager)getContext().getSystemService(Context.TELEPHONY_SERVICE);
+        mCm = (ConnectivityManager)getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
+        mPm = getContext().getPackageManager();
+    }
+
+    public void testCellInfo() throws Throwable {
+
+        if(! (mPm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY))) {
+            Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
+            return;
+        }
+
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        // getAllCellInfo should never return null, and there should
+        // be at least one entry.
+        List<CellInfo> allCellInfo = mTelephonyManager.getAllCellInfo();
+        assertNotNull("TelephonyManager.getAllCellInfo() returned NULL!", allCellInfo);
+        assertTrue("TelephonyManager.getAllCellInfo() returned zero-length list!",
+            allCellInfo.size() > 0);
+
+        int numRegisteredCells = 0;
+        for (CellInfo cellInfo : allCellInfo) {
+            if (cellInfo.isRegistered()) {
+                ++numRegisteredCells;
+            }
+            if (cellInfo instanceof CellInfoLte) {
+                verifyLteInfo((CellInfoLte) cellInfo);
+            } else if (cellInfo instanceof CellInfoWcdma) {
+                verifyWcdmaInfo((CellInfoWcdma) cellInfo);
+            } else if (cellInfo instanceof CellInfoGsm) {
+                verifyGsmInfo((CellInfoGsm) cellInfo);
+            }
+        }
+        // At most two cells could be registered.
+        assertTrue("None or too many registered cells : " + numRegisteredCells,
+                numRegisteredCells > 0 && numRegisteredCells <= 2);
+    }
+
+    // Verify lte cell information is within correct range.
+    private void verifyLteInfo(CellInfoLte lte) {
+        verifyRssiDbm(lte.getCellSignalStrength().getDbm());
+        // Verify LTE physical cell id information.
+        // Only physical cell id is available for LTE neighbor.
+        int pci = lte.getCellIdentity().getPci();
+        // Physical cell id should be within [0, 503].
+        assertTrue("getPci() out of range [0, 503]", pci >= 0 && pci <= 503);
+    }
+
+    // Verify wcdma cell information is within correct range.
+    private void verifyWcdmaInfo(CellInfoWcdma wcdma) {
+        verifyRssiDbm(wcdma.getCellSignalStrength().getDbm());
+        // Verify wcdma primary scrambling code information.
+        // Primary scrambling code should be within [0, 511].
+        int psc = wcdma.getCellIdentity().getPsc();
+        assertTrue("getPsc() out of range [0, 511]", psc >= 0 && psc <= 511);
+    }
+
+    // Verify gsm cell information is within correct range.
+    private void verifyGsmInfo(CellInfoGsm gsm) {
+        verifyRssiDbm(gsm.getCellSignalStrength().getDbm());
+        // Verify gsm local area code and cellid.
+        // Local area code and cellid should be with [0, 65535].
+        int lac = gsm.getCellIdentity().getLac();
+        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);
+    }
+
+    // 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);
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java b/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java
index c1f5757..9205f0e 100644
--- a/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/CellLocationTest.java
@@ -60,6 +60,14 @@
             return;
         }
 
+        // getCellLocation should never return null,
+        // but that is allowed if the cell network type
+        // is LTE (since there is no LteCellLocation class)
+        if (mTelephonyManager.getNetworkType() != TelephonyManager.NETWORK_TYPE_LTE) {
+            assertNotNull("TelephonyManager.getCellLocation() returned null!",
+                mTelephonyManager.getCellLocation());
+        }
+
         CellLocation cl = CellLocation.getEmpty();
         if (cl instanceof GsmCellLocation) {
             GsmCellLocation gcl = (GsmCellLocation) cl;
diff --git a/tests/tests/telephony/src/android/telephony/cts/MmsPduProvider.java b/tests/tests/telephony/src/android/telephony/cts/MmsPduProvider.java
new file mode 100644
index 0000000..08164ee
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/MmsPduProvider.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.cts;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.ParcelFileDescriptor;
+import android.text.TextUtils;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+
+/**
+ * A simple provider to send MMS PDU to platform MMS service
+ */
+public class MmsPduProvider extends ContentProvider {
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        // Not supported
+        return null;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        // Not supported
+        return null;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
+        // Not supported
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        // Not supported
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        // Not supported
+        return 0;
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(Uri uri, String fileMode) throws FileNotFoundException {
+        File file = new File(getContext().getCacheDir(), uri.getPath());
+        int mode = (TextUtils.equals(fileMode, "r") ? ParcelFileDescriptor.MODE_READ_ONLY :
+                ParcelFileDescriptor.MODE_WRITE_ONLY
+                        |ParcelFileDescriptor.MODE_TRUNCATE
+                        |ParcelFileDescriptor.MODE_CREATE);
+        return ParcelFileDescriptor.open(file, mode);
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/MmsTest.java b/tests/tests/telephony/src/android/telephony/cts/MmsTest.java
new file mode 100644
index 0000000..e15b45f
--- /dev/null
+++ b/tests/tests/telephony/src/android/telephony/cts/MmsTest.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.cts;
+
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.SystemClock;
+import android.telephony.SmsManager;
+import android.telephony.TelephonyManager;
+import android.test.AndroidTestCase;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.google.android.mms.ContentType;
+import com.google.android.mms.InvalidHeaderValueException;
+import com.google.android.mms.pdu.CharacterSets;
+import com.google.android.mms.pdu.EncodedStringValue;
+import com.google.android.mms.pdu.GenericPdu;
+import com.google.android.mms.pdu.PduBody;
+import com.google.android.mms.pdu.PduComposer;
+import com.google.android.mms.pdu.PduHeaders;
+import com.google.android.mms.pdu.PduParser;
+import com.google.android.mms.pdu.PduPart;
+import com.google.android.mms.pdu.SendConf;
+import com.google.android.mms.pdu.SendReq;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Random;
+
+/**
+ * Test sending MMS using {@link android.telephony.SmsManager}.
+ */
+public class MmsTest extends AndroidTestCase {
+    private static final String TAG = "MmsTest";
+
+    private static final String ACTION_MMS_SENT = "CTS_MMS_SENT_ACTION";
+    private static final long DEFAULT_EXPIRY_TIME = 7 * 24 * 60 * 60;
+    private static final int DEFAULT_PRIORITY = PduHeaders.PRIORITY_NORMAL;
+
+    private static final String SUBJECT = "CTS MMS Test";
+    private static final String MESSAGE_BODY = "CTS MMS test message body";
+    private static final String TEXT_PART_FILENAME = "text_0.txt";
+    private static final String sSmilText =
+            "<smil>" +
+                    "<head>" +
+                        "<layout>" +
+                            "<root-layout/>" +
+                            "<region height=\"100%%\" id=\"Text\" left=\"0%%\" top=\"0%%\" width=\"100%%\"/>" +
+                        "</layout>" +
+                    "</head>" +
+                    "<body>" +
+                        "<par dur=\"8000ms\">" +
+                            "<text src=\"%s\" region=\"Text\"/>" +
+                        "</par>" +
+                    "</body>" +
+            "</smil>";
+
+    private static final long SENT_TIMEOUT = 1000 * 60 * 5; // 5 minutes
+
+    private static final String PROVIDER_AUTHORITY = "telephonyctstest";
+
+    private Random mRandom;
+    private SentReceiver mSentReceiver;
+    private TelephonyManager mTelephonyManager;
+    private PackageManager mPackageManager;
+
+    private static class SentReceiver extends BroadcastReceiver {
+        private final Object mLock;
+        private boolean mSuccess;
+        private boolean mDone;
+
+        public SentReceiver() {
+            mLock = new Object();
+            mSuccess = false;
+            mDone = false;
+        }
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.i(TAG, "Action " + intent.getAction());
+            if (!ACTION_MMS_SENT.equals(intent.getAction())) {
+                return;
+            }
+            final int resultCode = getResultCode();
+            if (resultCode == Activity.RESULT_OK) {
+                final byte[] response = intent.getByteArrayExtra(SmsManager.EXTRA_MMS_DATA);
+                if (response != null) {
+                    final GenericPdu pdu = new PduParser(
+                            response, shouldParseContentDisposition()).parse();
+                    if (pdu != null && pdu instanceof SendConf) {
+                        final SendConf sendConf = (SendConf) pdu;
+                        if (sendConf.getResponseStatus() == PduHeaders.RESPONSE_STATUS_OK) {
+                            mSuccess = true;
+                        } else {
+                            Log.e(TAG, "SendConf response status=" + sendConf.getResponseStatus());
+                        }
+                    } else {
+                        Log.e(TAG, "Not a SendConf: " +
+                                (pdu != null ? pdu.getClass().getCanonicalName() : "NULL"));
+                    }
+                } else {
+                    Log.e(TAG, "Empty response");
+                }
+            } else {
+                Log.e(TAG, "Failure result=" + resultCode);
+                if (resultCode == SmsManager.MMS_ERROR_HTTP_FAILURE) {
+                    final int httpError = intent.getIntExtra(SmsManager.EXTRA_MMS_HTTP_STATUS, 0);
+                    Log.e(TAG, "HTTP failure=" + httpError);
+                }
+            }
+            synchronized (mLock) {
+                mDone = true;
+                mLock.notify();
+            }
+        }
+
+        public boolean waitForSuccess(long timeout) {
+            synchronized(mLock) {
+                final long startTime = SystemClock.elapsedRealtime();
+                long waitTime = timeout;
+                while (waitTime > 0) {
+                    try {
+                        mLock.wait(waitTime);
+                    } catch (InterruptedException e) {
+                        // Ignore
+                    }
+                    if (mDone) {
+                        break;
+                    }
+                    waitTime = timeout - (SystemClock.elapsedRealtime() - startTime);
+                }
+                Log.i(TAG, "Wait for sent: done=" + mDone + ", success=" + mSuccess);
+                return mDone && mSuccess;
+            }
+
+        }
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        mRandom = new Random();
+        mTelephonyManager =
+                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        mPackageManager = mContext.getPackageManager();
+    }
+
+    public void testSendMmsMessage() {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            Log.i(TAG, "testSendMmsMessage skipped: no telephony available");
+            return;
+        }
+
+        Log.i(TAG, "testSendMmsMessage");
+        // Prime the MmsService so that MMS config is loaded
+        final SmsManager smsManager = SmsManager.getDefault();
+        smsManager.getAutoPersisting();
+        // MMS config is loaded asynchronously. Wait a bit so it will be loaded.
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            // Ignore
+        }
+
+        final Context context = getContext();
+        // Register sent receiver
+        mSentReceiver = new SentReceiver();
+        context.registerReceiver(mSentReceiver, new IntentFilter(ACTION_MMS_SENT));
+        // Create local provider file for sending PDU
+        final String fileName = "send." + String.valueOf(Math.abs(mRandom.nextLong())) + ".dat";
+        final File sendFile = new File(context.getCacheDir(), fileName);
+        final String selfNumber = getSimNumber(context);
+        assertTrue(!TextUtils.isEmpty(selfNumber));
+        final byte[] pdu = buildPdu(context, selfNumber, SUBJECT, MESSAGE_BODY);
+        assertNotNull(pdu);
+        assertTrue(writePdu(sendFile, pdu));
+        final Uri contentUri = (new Uri.Builder())
+                .authority(PROVIDER_AUTHORITY)
+                .path(fileName)
+                .scheme(ContentResolver.SCHEME_CONTENT)
+                .build();
+        // Send
+        final PendingIntent pendingIntent = PendingIntent.getBroadcast(
+                context, 0, new Intent(ACTION_MMS_SENT), 0);
+        smsManager.sendMultimediaMessage(context,
+                contentUri, null/*locationUrl*/, null/*configOverrides*/, pendingIntent);
+        assertTrue(mSentReceiver.waitForSuccess(SENT_TIMEOUT));
+        sendFile.delete();
+    }
+
+    private static boolean writePdu(File file, byte[] pdu) {
+        FileOutputStream writer = null;
+        try {
+            writer = new FileOutputStream(file);
+            writer.write(pdu);
+            return true;
+        } catch (final IOException e) {
+            return false;
+        } finally {
+            if (writer != null) {
+                try {
+                    writer.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+    }
+
+    private byte[] buildPdu(Context context, String selfNumber, String subject, String text) {
+        final SendReq req = new SendReq();
+        // From, per spec
+        req.setFrom(new EncodedStringValue(selfNumber));
+        // To
+        final String[] recipients = new String[1];
+        recipients[0] = selfNumber;
+        final EncodedStringValue[] encodedNumbers = EncodedStringValue.encodeStrings(recipients);
+        if (encodedNumbers != null) {
+            req.setTo(encodedNumbers);
+        }
+        // Subject
+        if (!TextUtils.isEmpty(subject)) {
+            req.setSubject(new EncodedStringValue(subject));
+        }
+        // Date
+        req.setDate(System.currentTimeMillis() / 1000);
+        // Body
+        final PduBody body = new PduBody();
+        // Add text part. Always add a smil part for compatibility, without it there
+        // may be issues on some carriers/client apps
+        final int size = addTextPart(body, text, true/* add text smil */);
+        req.setBody(body);
+        // Message size
+        req.setMessageSize(size);
+        // Message class
+        req.setMessageClass(PduHeaders.MESSAGE_CLASS_PERSONAL_STR.getBytes());
+        // Expiry
+        req.setExpiry(DEFAULT_EXPIRY_TIME);
+        // The following set methods throw InvalidHeaderValueException
+        try {
+            // Priority
+            req.setPriority(DEFAULT_PRIORITY);
+            // Delivery report
+            req.setDeliveryReport(PduHeaders.VALUE_NO);
+            // Read report
+            req.setReadReport(PduHeaders.VALUE_NO);
+        } catch (InvalidHeaderValueException e) {
+            return null;
+        }
+
+        return new PduComposer(context, req).make();
+    }
+
+    private static int addTextPart(PduBody pb, String message, boolean addTextSmil) {
+        final PduPart part = new PduPart();
+        // Set Charset if it's a text media.
+        part.setCharset(CharacterSets.UTF_8);
+        // Set Content-Type.
+        part.setContentType(ContentType.TEXT_PLAIN.getBytes());
+        // Set Content-Location.
+        part.setContentLocation(TEXT_PART_FILENAME.getBytes());
+        int index = TEXT_PART_FILENAME.lastIndexOf(".");
+        String contentId = (index == -1) ? TEXT_PART_FILENAME
+                : TEXT_PART_FILENAME.substring(0, index);
+        part.setContentId(contentId.getBytes());
+        part.setData(message.getBytes());
+        pb.addPart(part);
+        if (addTextSmil) {
+            final String smil = String.format(sSmilText, TEXT_PART_FILENAME);
+            addSmilPart(pb, smil);
+        }
+        return part.getData().length;
+    }
+
+    private static void addSmilPart(PduBody pb, String smil) {
+        final PduPart smilPart = new PduPart();
+        smilPart.setContentId("smil".getBytes());
+        smilPart.setContentLocation("smil.xml".getBytes());
+        smilPart.setContentType(ContentType.APP_SMIL.getBytes());
+        smilPart.setData(smil.getBytes());
+        pb.addPart(0, smilPart);
+    }
+
+    private static String getSimNumber(Context context) {
+        final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(
+                Context.TELEPHONY_SERVICE);
+        return telephonyManager.getLine1Number();
+    }
+
+    private static boolean shouldParseContentDisposition() {
+        return SmsManager
+                .getDefault()
+                .getCarrierConfigValues()
+                .getBoolean(SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION, true);
+    }
+}
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
index d96743c..f49a8204 100644
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/PhoneNumberUtilsTest.java
@@ -28,7 +28,10 @@
 import android.telephony.TelephonyManager;
 import android.test.AndroidTestCase;
 import android.text.Editable;
+import android.text.Spannable;
+import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
+import android.text.style.TtsSpan;
 
 import java.util.Locale;
 
@@ -326,4 +329,38 @@
         assertEquals("5567861616", PhoneNumberUtils.convertAndStrip("٥‎ ٥‎٦‎ ٧‎ ٨‎ ٦‎ ١‎ ٦‎ ١‎ ٦‎"));
 
     }
+
+    public void testGetPhoneTtsSpan() {
+        // Setup: phone number without a country code. Lets keep coverage minimal to avoid
+        // exercising the underlying PhoneNumberUtil or constraining localization changes.
+        String phoneNumber = "6512223333";
+        // Execute
+        TtsSpan ttsSpan = PhoneNumberUtils.createTtsSpan(phoneNumber);
+        // Verify: the created TtsSpan contains the phone number.
+        assertEquals("6512223333", ttsSpan.getArgs().get(TtsSpan.ARG_NUMBER_PARTS));
+    }
+
+    public void testAddPhoneTtsSpan() {
+        // Setup: phone number without a country code. Lets keep coverage minimal to avoid
+        // exercising the underlying PhoneNumberUtil or constraining localization changes.
+        Spannable spannable = new SpannableString("Hello 6502223333");
+        // Execute
+        PhoneNumberUtils.addTtsSpan(spannable, 5, spannable.length());
+        // Verify: the Spannable is annotated with a TtsSpan in the correct location.
+        TtsSpan[] ttsSpans = spannable.getSpans(5, spannable.length() - 1, TtsSpan.class);
+        assertEquals(1, ttsSpans.length);
+        assertEquals("6502223333", ttsSpans[0].getArgs().get(TtsSpan.ARG_NUMBER_PARTS));
+    }
+
+    public void testGetPhoneTtsSpannable() {
+        // Setup: phone number without a country code. Lets keep coverage minimal to avoid
+        // exercising the underlying PhoneNumberUtil or constraining localization changes.
+        CharSequence phoneNumber = "6512223333";
+        // Execute
+        Spannable spannable = (Spannable) PhoneNumberUtils.createTtsSpannable(phoneNumber);
+        // Verify: returned char sequence contains a TtsSpan with the phone number in it
+        TtsSpan[] ttsSpans = spannable.getSpans(0, spannable.length() - 1, TtsSpan.class);
+        assertEquals(1, ttsSpans.length);
+        assertEquals("6512223333", ttsSpans[0].getArgs().get(TtsSpan.ARG_NUMBER_PARTS));
+    }
 }
diff --git a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
index f0f977a..18aa23f 100644
--- a/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/PhoneStateListenerTest.java
@@ -22,6 +22,7 @@
 import android.telephony.CellLocation;
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
 import android.telephony.TelephonyManager;
 import android.net.ConnectivityManager;
 import android.test.InstrumentationTestCase;
@@ -40,6 +41,7 @@
     private boolean mOnMessageWaitingIndicatorChangedCalled;
     private boolean mOnServiceStateChangedCalled;
     private boolean mOnSignalStrengthChangedCalled;
+    private SignalStrength mSignalStrength;
     private TelephonyManager mTelephonyManager;
     private PhoneStateListener mListener;
     private final Object mLock = new Object();
@@ -152,6 +154,54 @@
         assertTrue(mOnSignalStrengthChangedCalled);
     }
 
+    public void testOnSignalStrengthsChanged() throws Throwable {
+        if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
+            Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
+            return;
+        }
+
+        TestThread t = new TestThread(new Runnable() {
+            public void run() {
+                Looper.prepare();
+
+                mListener = new PhoneStateListener() {
+                    @Override
+                    public void onSignalStrengthsChanged(SignalStrength signalStrength) {
+                        synchronized(mLock) {
+                            mSignalStrength = signalStrength;
+                            mLock.notify();
+                        }
+                    }
+                };
+                mTelephonyManager.listen(mListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
+
+                Looper.loop();
+            }
+        });
+
+        assertTrue(mSignalStrength == null);
+        t.start();
+
+        synchronized (mLock) {
+            while(mSignalStrength == null) {
+                mLock.wait();
+            }
+        }
+        t.checkException();
+        assertTrue(mSignalStrength != null);
+
+        // Call SignalStrength methods to make sure they do not throw any exceptions
+        mSignalStrength.getCdmaDbm();
+        mSignalStrength.getCdmaEcio();
+        mSignalStrength.getEvdoDbm();
+        mSignalStrength.getEvdoEcio();
+        mSignalStrength.getEvdoSnr();
+        mSignalStrength.getGsmBitErrorRate();
+        mSignalStrength.getGsmSignalStrength();
+        mSignalStrength.isGsm();
+        mSignalStrength.getLevel();
+    }
+
     public void testOnMessageWaitingIndicatorChanged() throws Throwable {
         if (mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE) == null) {
             Log.d(TAG, "Skipping test that requires ConnectivityManager.TYPE_MOBILE");
diff --git a/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java b/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
index cb9d96c..20810a8 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SimRestrictedApisTest.java
@@ -22,8 +22,7 @@
 import android.test.AndroidTestCase;
 
 public class SimRestrictedApisTest extends AndroidTestCase {
-    private static final byte[] TEST_PDU = {
-            0, 0 };
+    private static final byte[] TEST_PDU = { 0, 0 };
     private TelephonyManager mTelephonyManager;
 
     @Override
@@ -221,7 +220,7 @@
     public void testGetPreferredNetworkType() {
         try {
             if (isSimCardPresent()) {
-                TelephonyManager.getDefault().getPreferredNetworkType();
+                TelephonyManager.getDefault().getPreferredNetworkType(0);
                 fail("Expected SecurityException. App doesn't have carrier privileges.");
             }
         } catch (SecurityException expected) {
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
index 92f352f..5a80802 100755
--- a/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsManagerTest.java
@@ -49,6 +49,10 @@
         "three separate messages.This is a very long text. This text should be broken " +
         "into three separate messages.This is a very long text. This text should be " +
         "broken into three separate messages.";;
+    private static final String LONG_TEXT_WITH_32BIT_CHARS =
+        "Long dkkshsh jdjsusj kbsksbdf jfkhcu hhdiwoqiwyrygrvn?*?*!\";:'/,."
+        + "__?9#9292736&4;\"$+$+((]\\[\\℅©℅™^®°¥°¥=¢£}}£∆~¶~÷|√×."
+        + " 😯😆😉😇😂😀👕🎓😀👙🐕🐀🐶🐰🐩⛪⛲ ";
 
     private static final String SMS_SEND_ACTION = "CTS_SMS_SEND_ACTION";
     private static final String SMS_DELIVERY_ACTION = "CTS_SMS_DELIVERY_ACTION";
@@ -215,17 +219,28 @@
     public void testDivideMessage() {
         ArrayList<String> dividedMessages = divideMessage(LONG_TEXT);
         assertNotNull(dividedMessages);
-        int numParts;
         if (TelephonyUtils.isSkt(mTelephonyManager)) {
-            assertTrue(isComplete(dividedMessages, 5) || isComplete(dividedMessages, 3));
+            assertTrue(isComplete(dividedMessages, 5, LONG_TEXT)
+                    || isComplete(dividedMessages, 3, LONG_TEXT));
         } else if (TelephonyUtils.isKt(mTelephonyManager)) {
-            assertTrue(isComplete(dividedMessages, 4) || isComplete(dividedMessages, 3));
+            assertTrue(isComplete(dividedMessages, 4, LONG_TEXT)
+                    || isComplete(dividedMessages, 3, LONG_TEXT));
         } else {
-            assertTrue(isComplete(dividedMessages, 3));
+            assertTrue(isComplete(dividedMessages, 3, LONG_TEXT));
         }
     }
 
-    private boolean isComplete(List<String> dividedMessages, int numParts) {
+    public void testDivideUnicodeMessage() {
+        ArrayList<String> dividedMessages = divideMessage(LONG_TEXT_WITH_32BIT_CHARS);
+        assertNotNull(dividedMessages);
+        assertTrue(isComplete(dividedMessages, 3, LONG_TEXT_WITH_32BIT_CHARS));
+        for (String messagePiece : dividedMessages) {
+            assertFalse(Character.isHighSurrogate(
+                    messagePiece.charAt(messagePiece.length() - 1)));
+        }
+    }
+
+    private boolean isComplete(List<String> dividedMessages, int numParts, String longText) {
         if (dividedMessages.size() != numParts) {
             return false;
         }
@@ -234,7 +249,7 @@
         for (int i = 0; i < numParts; i++) {
             actualMessage += dividedMessages.get(i);
         }
-        return LONG_TEXT.equals(actualMessage);
+        return longText.equals(actualMessage);
     }
 
     public void testSendMessages() throws InterruptedException {
@@ -375,9 +390,10 @@
                 Bundle bundle = intent.getExtras();
                 if (bundle != null) {
                     Object[] obj = (Object[]) bundle.get("pdus");
+                    String format = bundle.getString("format");
                     SmsMessage[] message = new SmsMessage[obj.length];
                     for (int i = 0; i < obj.length; i++) {
-                        message[i] = SmsMessage.createFromPdu((byte[]) obj[i]);
+                        message[i] = SmsMessage.createFromPdu((byte[]) obj[i], format);
                     }
 
                     for (SmsMessage currentMessage : message) {
diff --git a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
index ff7b097..2db9ba1 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsMessageTest.java
@@ -62,6 +62,10 @@
     private static final long TIMESTAMP_MILLIS = 1149631383000l;
     private static final int SEPTETS_SKT = 80;
     private static final int SEPTETS_KT = 90;
+    private static final String LONG_TEXT_WITH_32BIT_CHARS =
+        "Long dkkshsh jdjsusj kbsksbdf jfkhcu hhdiwoqiwyrygrvn?*?*!\";:'/,."
+        + "__?9#9292736&4;\"$+$+((]\\[\\℅©℅™^®°¥°¥=¢£}}£∆~¶~÷|√×."
+        + " 😯😆😉😇😂😀👕🎓😀👙🐕🐀🐶🐰🐩⛪⛲ ";
 
     @Override
     protected void setUp() throws Exception {
@@ -71,7 +75,6 @@
         mPackageManager = getContext().getPackageManager();
     }
 
-    @SuppressWarnings("deprecation")
     public void testCreateFromPdu() throws Exception {
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
                 || mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA)) {
@@ -80,7 +83,8 @@
         }
 
         String pdu = "07916164260220F0040B914151245584F600006060605130308A04D4F29C0E";
-        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
+                SmsMessage.FORMAT_3GPP);
         assertEquals(SCA1, sms.getServiceCenterAddress());
         assertEquals(OA1, sms.getOriginatingAddress());
         assertEquals(MESSAGE_BODY1, sms.getMessageBody());
@@ -88,7 +92,7 @@
         int[] result = SmsMessage.calculateLength(sms.getMessageBody(), true);
         assertEquals(SMS_NUMBER1, result[0]);
         assertEquals(sms.getMessageBody().length(), result[1]);
-        assertRemaining(sms.getMessageBody().length(), result[2]);
+        assertRemaining(sms.getMessageBody().length(), result[2], SmsMessage.MAX_USER_DATA_SEPTETS);
         assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
         assertEquals(pdu, toHexString(sms.getPdu()));
 
@@ -106,13 +110,13 @@
         assertEquals(TIMESTAMP_MILLIS, sms.getTimestampMillis());
 
         // Test create from null Pdu
-        sms = SmsMessage.createFromPdu(null);
+        sms = SmsMessage.createFromPdu(null, SmsMessage.FORMAT_3GPP);
         assertNotNull(sms);
 
-        //Test create from long Pdu
+        // Test create from long Pdu
         pdu = "07912160130310F2040B915121927786F300036060924180008A0DA"
             + "8695DAC2E8FE9296A794E07";
-        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
         assertEquals(SCA2, sms.getServiceCenterAddress());
         assertEquals(OA2, sms.getOriginatingAddress());
         assertEquals(MESSAGE_BODY2, sms.getMessageBody());
@@ -120,30 +124,30 @@
         result = SmsMessage.calculateLength(msgBody, false);
         assertEquals(SMS_NUMBER2, result[0]);
         assertEquals(sms.getMessageBody().length(), result[1]);
-        assertRemaining(sms.getMessageBody().length(), result[2]);
+        assertRemaining(sms.getMessageBody().length(), result[2], SmsMessage.MAX_USER_DATA_SEPTETS);
         assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
 
         // Test createFromPdu Ucs to Sms
         pdu = "07912160130300F4040B914151245584"
             + "F600087010807121352B10212200A900AE00680065006C006C006F";
-        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
         assertEquals(MESSAGE_BODY3, sms.getMessageBody());
         result = SmsMessage.calculateLength(sms.getMessageBody(), true);
         assertEquals(SMS_NUMBER3, result[0]);
         assertEquals(sms.getMessageBody().length(), result[1]);
-        assertRemaining(sms.getMessageBody().length(), result[2]);
+        assertRemaining(sms.getMessageBody().length(), result[2], SmsMessage.MAX_USER_DATA_SEPTETS);
         assertEquals(SmsMessage.ENCODING_7BIT, result[3]);
     }
 
-    private void assertRemaining(int messageLength, int remaining) {
+    private void assertRemaining(int messageLength, int remaining, int maxChars) {
         if (TelephonyUtils.isSkt(mTelephonyManager)) {
             assertTrue(checkRemaining(SEPTETS_SKT, messageLength, remaining)
-                    || checkRemaining(SmsMessage.MAX_USER_DATA_SEPTETS, messageLength, remaining));
+                    || checkRemaining(maxChars, messageLength, remaining));
         } else if (TelephonyUtils.isKt(mTelephonyManager)) {
             assertTrue(checkRemaining(SEPTETS_KT, messageLength, remaining)
-                    || checkRemaining(SmsMessage.MAX_USER_DATA_SEPTETS, messageLength, remaining));
+                    || checkRemaining(maxChars, messageLength, remaining));
         } else {
-            assertTrue(checkRemaining(SmsMessage.MAX_USER_DATA_SEPTETS, messageLength, remaining));
+            assertTrue(checkRemaining(maxChars, messageLength, remaining));
         }
     }
 
@@ -160,7 +164,8 @@
 
         // "set MWI flag"
         String pdu = "07912160130310F20404D0110041006060627171118A0120";
-        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
+                SmsMessage.FORMAT_3GPP);
         assertTrue(sms.isReplace());
         assertEquals(OA3, sms.getOriginatingAddress());
         assertEquals(MESSAGE_BODY4, sms.getMessageBody());
@@ -168,12 +173,12 @@
 
         // "clear mwi flag"
         pdu = "07912160130310F20404D0100041006021924193352B0120";
-        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
         assertTrue(sms.isMWIClearMessage());
 
         // "clear MWI flag"
         pdu = "07912160130310F20404D0100041006060627161058A0120";
-        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
         assertTrue(sms.isReplace());
         assertEquals(OA4, sms.getOriginatingAddress());
         assertEquals(MESSAGE_BODY5, sms.getMessageBody());
@@ -181,13 +186,13 @@
 
         // "set MWI flag"
         pdu = "07912180958750F84401800500C87020026195702B06040102000200";
-        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
         assertTrue(sms.isMWISetMessage());
         assertTrue(sms.isMwiDontStore());
 
         // "clear mwi flag"
         pdu = "07912180958750F84401800500C07020027160112B06040102000000";
-        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
 
         assertTrue(sms.isMWIClearMessage());
         assertTrue(sms.isMwiDontStore());
@@ -206,7 +211,8 @@
             + "66C414141414D7741414236514141414141008D908918802B3135313232393737"
             + "3638332F545950453D504C4D4E008A808E022B918805810306977F83687474703"
             + "A2F2F36";
-        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
+                SmsMessage.FORMAT_3GPP);
         byte[] userData = sms.getUserData();
         assertNotNull(userData);
     }
@@ -265,7 +271,8 @@
         String pdu = "07914151551512f204038105f300007011103164638a28e6f71b50c687db" +
                          "7076d9357eb7412f7a794e07cdeb6275794c07bde8e5391d247e93f3";
 
-        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        SmsMessage sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu),
+                SmsMessage.FORMAT_3GPP);
         assertEquals(SCA4, sms.getServiceCenterAddress());
         assertTrue(sms.isEmail());
         assertEquals(EMAIL_ADD, sms.getEmailFrom());
@@ -277,7 +284,7 @@
 
         pdu = "07914151551512f204038105f400007011103105458a29e6f71b50c687db" +
                         "7076d9357eb741af0d0a442fcfe9c23739bfe16d289bdee6b5f1813629";
-        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu));
+        sms = SmsMessage.createFromPdu(hexStringToByteArray(pdu), SmsMessage.FORMAT_3GPP);
         assertEquals(SCA3, sms.getServiceCenterAddress());
         assertTrue(sms.isEmail());
         assertEquals(OA, sms.getDisplayOriginatingAddress());
@@ -286,6 +293,30 @@
         assertEquals(MB, sms.getEmailBody());
     }
 
+    public void testCalculateLength() throws Exception {
+        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
+            return;
+        }
+
+        int[] result = SmsMessage.calculateLength(LONG_TEXT_WITH_32BIT_CHARS, false);
+        assertEquals(3, result[0]);
+        assertEquals(LONG_TEXT_WITH_32BIT_CHARS.length(), result[1]);
+        // 3 parts, each with (SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2) 16-bit
+        // characters. We need to subtract one because a 32-bit character crosses the
+        // boundary of 2 parts.
+        int preMaxChars = 3 * SmsMessage.MAX_USER_DATA_BYTES_WITH_HEADER / 2 - 1;
+        // If EMS is not supported, break down EMS into single segment SMS
+        // and add page info "x/y".
+        // In the case of UCS2 encoding type, we need 8 bytes for this
+        // but we only have 6 bytes from UDH, so truncate the limit for
+        // each segment by 2 bytes (1 char). This log sms has three segments,
+        // so truncate the limit by 3 char in total
+        int maxChars = SmsMessage.hasEmsSupport() ? preMaxChars : preMaxChars - 3;
+        assertRemaining(LONG_TEXT_WITH_32BIT_CHARS.length(), result[2],
+                maxChars);
+        assertEquals(SmsMessage.ENCODING_16BIT, result[3]);
+    }
+
     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/SmsUsageMonitorShortCodeTest.java b/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
index 67cdd24..145cc84 100644
--- a/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/SmsUsageMonitorShortCodeTest.java
@@ -20,7 +20,7 @@
 import android.content.pm.PackageManager;
 import android.test.InstrumentationTestCase;
 import android.test.UiThreadTest;
-
+import android.telephony.TelephonyManager;
 import com.android.internal.telephony.SmsUsageMonitor;
 
 /**
@@ -28,6 +28,7 @@
  */
 public class SmsUsageMonitorShortCodeTest extends InstrumentationTestCase {
 
+    private TelephonyManager mTelephonyManager;
     private PackageManager mPackageManager;
     private Context mContext;
 
@@ -298,7 +299,7 @@
             new ShortCodeTest("it", "112", CATEGORY_NOT_SHORT_CODE),
             new ShortCodeTest("it", "116117", CATEGORY_FREE_SHORT_CODE),
             new ShortCodeTest("it", "4567", CATEGORY_NOT_SHORT_CODE),
-            new ShortCodeTest("it", "48000", CATEGORY_PREMIUM_SHORT_CODE),
+            new ShortCodeTest("it", "48000", CATEGORY_FREE_SHORT_CODE),
             new ShortCodeTest("it", "45678", CATEGORY_PREMIUM_SHORT_CODE),
             new ShortCodeTest("it", "56789", CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE),
             new ShortCodeTest("it", "456789", CATEGORY_NOT_SHORT_CODE),
@@ -485,6 +486,12 @@
         super.setUp();
         mContext = getInstrumentation().getTargetContext();
         mPackageManager = mContext.getPackageManager();
+        mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+    }
+
+    private boolean isCDMA112(String address) {
+        return (mTelephonyManager.getPhoneType() == TelephonyManager.PHONE_TYPE_CDMA)
+                && "112".equals(address);
     }
 
     @UiThreadTest
@@ -497,7 +504,8 @@
         SmsUsageMonitor monitor = new SmsUsageMonitor(mContext);
         for (ShortCodeTest test : sShortCodeTests) {
             assertEquals("country: " + test.countryIso + " number: " + test.address,
-                    test.category, monitor.checkDestination(test.address, test.countryIso));
+                    test.category, isCDMA112(test.address) ? CATEGORY_NOT_SHORT_CODE :
+                    monitor.checkDestination(test.address, test.countryIso));
         }
     }
 }
diff --git a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
index 2be1dcb..8b94d00 100644
--- a/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/src/android/telephony/cts/TelephonyManagerTest.java
@@ -160,7 +160,28 @@
         mTelephonyManager.getNeighboringCellInfo();
         mTelephonyManager.isNetworkRoaming();
         mTelephonyManager.getDeviceId();
+        mTelephonyManager.getDeviceId(mTelephonyManager.getDefaultSim());
         mTelephonyManager.getDeviceSoftwareVersion();
+        mTelephonyManager.getPhoneCount();
+    }
+
+    /**
+     * Tests that the phone count returned is valid.
+     */
+    public void testGetPhoneCount() {
+        int phoneCount = mTelephonyManager.getPhoneCount();
+        int phoneType = mTelephonyManager.getPhoneType();
+        switch (phoneType) {
+            case TelephonyManager.PHONE_TYPE_GSM:
+            case TelephonyManager.PHONE_TYPE_CDMA:
+                assertTrue("Phone count should be > 0", phoneCount > 0);
+                break;
+            case TelephonyManager.PHONE_TYPE_NONE:
+                assertTrue("Phone count should be 0", phoneCount == 0 || phoneCount == 1);
+                break;
+            default:
+                throw new IllegalArgumentException("Did you add a new phone type? " + phoneType);
+        }
     }
 
     /**
@@ -170,6 +191,24 @@
      */
     public void testGetDeviceId() {
         String deviceId = mTelephonyManager.getDeviceId();
+        verifyDeviceId(deviceId);
+    }
+
+    /**
+     * Tests that the device properly reports either a valid IMEI if
+     * GSM, a valid MEID or ESN if CDMA, or a valid MAC address if
+     * only a WiFi device.
+     */
+    public void testGetDeviceIdForSlotId() {
+        String deviceId = mTelephonyManager.getDeviceId(mTelephonyManager.getDefaultSim());
+        verifyDeviceId(deviceId);
+        // Also verify that no exception is thrown for any slot id (including invalid ones)
+        for (int i = -1; i <= mTelephonyManager.getPhoneCount(); i++) {
+            mTelephonyManager.getDeviceId(i);
+        }
+    }
+
+    private void verifyDeviceId(String deviceId) {
         int phoneType = mTelephonyManager.getPhoneType();
         switch (phoneType) {
             case TelephonyManager.PHONE_TYPE_GSM:
@@ -186,7 +225,10 @@
                 break;
 
             case TelephonyManager.PHONE_TYPE_NONE:
-                if (mCm.getNetworkInfo(ConnectivityManager.TYPE_WIFI) != null) {
+                boolean nwSupported = mCm.isNetworkSupported(mCm.TYPE_WIFI);
+                PackageManager packageManager = getContext().getPackageManager();
+                // only check serial number & MAC address if device report wifi feature
+                if (packageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
                     assertSerialNumber();
                     assertMacAddress(getWifiMacAddress());
                 } else if (mCm.getNetworkInfo(ConnectivityManager.TYPE_BLUETOOTH) != null) {
diff --git a/tests/tests/telephony2/Android.mk b/tests/tests/telephony2/Android.mk
new file mode 100644
index 0000000..f405210
--- /dev/null
+++ b/tests/tests/telephony2/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 := CtsTelephony2TestCases
+
+LOCAL_JAVA_LIBRARIES += android.test.runner
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/telephony2/AndroidManifest.xml b/tests/tests/telephony2/AndroidManifest.xml
new file mode 100644
index 0000000..369f75e
--- /dev/null
+++ b/tests/tests/telephony2/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.cts.telephony2">
+
+    <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.telephony2">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+
+</manifest>
+
diff --git a/tests/tests/telephony2/src/android/telephony2/cts/PhoneNumberTest.java b/tests/tests/telephony2/src/android/telephony2/cts/PhoneNumberTest.java
new file mode 100644
index 0000000..65392c4
--- /dev/null
+++ b/tests/tests/telephony2/src/android/telephony2/cts/PhoneNumberTest.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.telephony2.cts;
+
+import android.os.ParcelFileDescriptor;
+import android.telephony.TelephonyManager;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class PhoneNumberTest extends InstrumentationTestCase {
+    private static final String TAG = "PhoneNumberTest";
+
+    private void setDefaultSmsApp(boolean setToSmsApp) {
+        StringBuilder command = new StringBuilder();
+        command.append("appops set ");
+        command.append(getInstrumentation().getContext().getPackageName());
+        command.append(" WRITE_SMS ");
+        command.append(setToSmsApp ? "allow" : "default");
+
+        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
+                .executeShellCommand(command.toString());
+
+        InputStream is = new FileInputStream(pfd.getFileDescriptor());
+        try {
+            final byte[] buffer = new byte[8192];
+            while ((is.read(buffer)) != -1);
+        } catch (IOException e) {
+            Log.e(TAG, "Error managing default SMS app", e);
+        }
+    }
+
+    public void testGetLine1Number() {
+        TelephonyManager tm = getInstrumentation().getContext().getSystemService(
+                TelephonyManager.class);
+
+        setDefaultSmsApp(true);
+
+        // This shouldn't crash.
+        tm.getLine1Number();
+
+        setDefaultSmsApp(false);
+
+        // This should throw now.
+        try {
+            tm.getLine1Number();
+            fail("Should throw SecurityException");
+        } catch (SecurityException expected) {
+        }
+    }
+}
diff --git a/tests/tests/text/src/android/text/cts/BidiFormatterTest.java b/tests/tests/text/src/android/text/cts/BidiFormatterTest.java
index 645ab5b..5ace8b2 100644
--- a/tests/tests/text/src/android/text/cts/BidiFormatterTest.java
+++ b/tests/tests/text/src/android/text/cts/BidiFormatterTest.java
@@ -107,6 +107,9 @@
     }
 
     public void testUnicodeWrap() {
+        // Make sure an input of null doesn't crash anything.
+        assertNull(LTR_FMT.unicodeWrap(null));
+
         // Uniform directionality in opposite context.
         assertEquals("uniform dir opposite to LTR context",
                 RLE + "." + HE + "." + PDF + LRM,
diff --git a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
index 4895ca9..36b081c 100644
--- a/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
+++ b/tests/tests/text/src/android/text/cts/SpannableStringBuilderTest.java
@@ -18,10 +18,12 @@
 
 
 import android.test.AndroidTestCase;
+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.StrikethroughSpan;
 import android.text.style.TabStopSpan;
 import android.text.style.UnderlineSpan;
@@ -596,4 +598,46 @@
             // expected exception
         }
     }
+
+    private static class MockTextWatcher implements TextWatcher {
+        private int mDepth = 0;
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+            SpannableStringBuilder builder = (SpannableStringBuilder)s;
+            mDepth++;
+            assertEquals(mDepth, builder.getTextWatcherDepth());
+            mDepth--;
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+            SpannableStringBuilder builder = (SpannableStringBuilder)s;
+            mDepth++;
+            assertEquals(mDepth, builder.getTextWatcherDepth());
+            mDepth--;
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+            SpannableStringBuilder builder = (SpannableStringBuilder)s;
+            mDepth++;
+            assertEquals(mDepth, builder.getTextWatcherDepth());
+            if (mDepth <= builder.length()) {
+                // This will recursively call afterTextChanged.
+                builder.replace(mDepth - 1, mDepth, "a");
+            }
+            mDepth--;
+        }
+    }
+
+    public void testGetTextWatcherDepth() {
+        SpannableStringBuilder builder = new SpannableStringBuilder("hello");
+        builder.setSpan(new MockTextWatcher(), 0, builder.length(), 0);
+        assertEquals(0, builder.getTextWatcherDepth());
+        builder.replace(0, 1, "H");
+        assertEquals(0, builder.getTextWatcherDepth());
+        // MockTextWatcher replaces each character with 'a'.
+        assertEquals("aaaaa", builder.toString());
+    }
 }
diff --git a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
index b4fb8ab..329db88 100644
--- a/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
+++ b/tests/tests/text/src/android/text/cts/StaticLayoutTest.java
@@ -18,11 +18,21 @@
 
 import android.test.AndroidTestCase;
 import android.text.Editable;
+import android.text.GetChars;
+import android.text.GraphicsOperations;
+import android.text.Layout.Alignment;
+import android.text.TextUtils.TruncateAt;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.SpannedString;
 import android.text.StaticLayout;
 import android.text.TextDirectionHeuristics;
 import android.text.TextPaint;
 import android.text.TextUtils;
-import android.text.Layout.Alignment;
+
+import java.text.Normalizer;
+import java.util.ArrayList;
+import java.util.List;
 
 public class StaticLayoutTest extends AndroidTestCase {
     private static final float SPACE_MULTI = 1.0f;
@@ -49,6 +59,10 @@
     private StaticLayout mDefaultLayout;
     private TextPaint mDefaultPaint;
 
+    private class TestingTextPaint extends TextPaint {
+        // need to have a subclass to insure measurement happens in Java and not C++
+    }
+
     @Override
     protected void setUp() throws Exception {
         super.setUp();
@@ -104,6 +118,104 @@
         }
     }
 
+    public void testBuilder() {
+        {
+            // Obtain.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            StaticLayout layout = builder.build();
+            // Check values passed to obtain().
+            assertEquals(LAYOUT_TEXT, layout.getText());
+            assertEquals(mDefaultPaint, layout.getPaint());
+            assertEquals(DEFAULT_OUTER_WIDTH, layout.getWidth());
+            // Check default values.
+            assertEquals(TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    layout.getTextDirectionHeuristic());
+            assertEquals(Alignment.ALIGN_NORMAL, layout.getAlignment());
+            assertEquals(0.0f, layout.getSpacingAdd());
+            assertEquals(1.0f, layout.getSpacingMultiplier());
+            assertEquals(DEFAULT_OUTER_WIDTH, layout.getEllipsizedWidth());
+        }
+        {
+            // Obtain with null objects.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(null, 0, 0, null, 0);
+            try {
+                StaticLayout layout = builder.build();
+                fail("should throw NullPointerException here");
+            } catch (NullPointerException e) {
+            }
+        }
+        {
+            // setText.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setText(LAYOUT_TEXT_SINGLE_LINE);
+            StaticLayout layout = builder.build();
+            assertEquals(LAYOUT_TEXT_SINGLE_LINE, layout.getText());
+        }
+        {
+            // setAlignment.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setAlignment(DEFAULT_ALIGN);
+            StaticLayout layout = builder.build();
+            assertEquals(DEFAULT_ALIGN, layout.getAlignment());
+        }
+        {
+            // setTextDirection.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setTextDirection(TextDirectionHeuristics.RTL);
+            StaticLayout layout = builder.build();
+            // Always returns TextDirectionHeuristics.FIRSTSTRONG_LTR.
+            assertEquals(TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    layout.getTextDirectionHeuristic());
+        }
+        {
+            // setLineSpacing.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setLineSpacing(1.0f, 2.0f);
+            StaticLayout layout = builder.build();
+            assertEquals(1.0f, layout.getSpacingAdd());
+            assertEquals(2.0f, layout.getSpacingMultiplier());
+        }
+        {
+            // setEllipsizedWidth and setEllipsize.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setEllipsize(TruncateAt.END);
+            builder.setEllipsizedWidth(ELLIPSIZE_WIDTH);
+            StaticLayout layout = builder.build();
+            assertEquals(ELLIPSIZE_WIDTH, layout.getEllipsizedWidth());
+            assertEquals(DEFAULT_OUTER_WIDTH, layout.getWidth());
+            assertTrue(layout.getEllipsisCount(0) == 0);
+            assertTrue(layout.getEllipsisCount(5) > 0);
+        }
+        {
+            // setMaxLines.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setMaxLines(1);
+            builder.setEllipsize(TruncateAt.END);
+            StaticLayout layout = builder.build();
+            assertTrue(layout.getEllipsisCount(0) > 0);
+            assertEquals(1, layout.getLineCount());
+        }
+        {
+            // Setter methods that cannot be directly tested.
+            // setBreakStrategy, setHyphenationFrequency, setIncludePad, and setIndents.
+            StaticLayout.Builder builder = StaticLayout.Builder.obtain(LAYOUT_TEXT, 0,
+                    LAYOUT_TEXT.length(), mDefaultPaint, DEFAULT_OUTER_WIDTH);
+            builder.setBreakStrategy(StaticLayout.BREAK_STRATEGY_HIGH_QUALITY);
+            builder.setHyphenationFrequency(StaticLayout.HYPHENATION_FREQUENCY_FULL);
+            builder.setIncludePad(true);
+            builder.setIndents(null, null);
+            StaticLayout layout = builder.build();
+            assertNotNull(layout);
+        }
+    }
+
     /*
      * Get the line number corresponding to the specified vertical position.
      *  If you ask for a position above 0, you get 0. above 0 means pixel above the fire line
@@ -336,30 +448,6 @@
         assertTrue(mDefaultLayout.getEllipsisCount(3) == 0);
         assertTrue(mDefaultLayout.getEllipsisCount(4) == 0);
         assertTrue(mDefaultLayout.getEllipsisCount(5) > 0);
-
-        // Single line case and TruncateAt.END so that we have some ellipsis
-        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
-                TextUtils.TruncateAt.END,
-                1);
-        assertTrue(mDefaultLayout.getEllipsisCount(0) > 0);
-
-        // Single line case and TruncateAt.MIDDLE so that we have some ellipsis
-        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
-                TextUtils.TruncateAt.MIDDLE,
-                1);
-        assertTrue(mDefaultLayout.getEllipsisCount(0) > 0);
-
-        // Single line case and TruncateAt.END so that we have some ellipsis
-        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
-                TextUtils.TruncateAt.END,
-                1);
-        assertTrue(mDefaultLayout.getEllipsisCount(0) > 0);
-
-        // Single line case and TruncateAt.MARQUEE so that we have NO ellipsis
-        mDefaultLayout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
-                TextUtils.TruncateAt.MARQUEE,
-                1);
-        assertTrue(mDefaultLayout.getEllipsisCount(0) == 0);
     }
 
     /*
@@ -406,6 +494,65 @@
         assertEquals(outerWidth, layout.getEllipsizedWidth());
     }
 
+    public void testEllipsis_singleLine() {
+        {
+            // Single line case and TruncateAt.END so that we have some ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.END, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+        }
+        {
+            // Single line case and TruncateAt.MIDDLE so that we have some ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.MIDDLE, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+        }
+        {
+            // Single line case and TruncateAt.END so that we have some ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.END, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+        }
+        {
+            // Single line case and TruncateAt.MARQUEE so that we have NO ellipsis
+            StaticLayout layout = createEllipsizeStaticLayout(LAYOUT_TEXT_SINGLE_LINE,
+                    TextUtils.TruncateAt.MARQUEE, 1);
+            assertTrue(layout.getEllipsisCount(0) == 0);
+        }
+
+        final String text = "\u3042" // HIRAGANA LETTER A
+                + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";
+        final float textWidth = mDefaultPaint.measureText(text);
+        final int halfWidth = (int)(textWidth / 2.0f);
+        {
+            StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                    halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.END, halfWidth, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+            assertTrue(layout.getEllipsisStart(0) > 0);
+        }
+        {
+            StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                    halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.START, halfWidth, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+            assertEquals(0, mDefaultLayout.getEllipsisStart(0));
+        }
+        {
+            StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                    halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.MIDDLE, halfWidth, 1);
+            assertTrue(layout.getEllipsisCount(0) > 0);
+            assertTrue(layout.getEllipsisStart(0) > 0);
+        }
+        {
+            StaticLayout layout = new StaticLayout(text, 0, text.length(), mDefaultPaint,
+                    halfWidth, DEFAULT_ALIGN, TextDirectionHeuristics.FIRSTSTRONG_LTR,
+                    SPACE_MULTI, SPACE_ADD, false, TextUtils.TruncateAt.MARQUEE, halfWidth, 1);
+            assertEquals(0, layout.getEllipsisCount(0));
+        }
+    }
+
     /**
      * scenario description:
      * 1. set the text.
@@ -427,4 +574,423 @@
         assertTrue(layout.getLineContainsTab(0));
 
     }
+
+    // String wrapper for testing not well known implementation of CharSequence.
+    private class FakeCharSequence implements CharSequence {
+        private String mStr;
+
+        public FakeCharSequence(String str) {
+            mStr = str;
+        }
+
+        @Override
+        public char charAt(int index) {
+            return mStr.charAt(index);
+        }
+
+        @Override
+        public int length() {
+            return mStr.length();
+        }
+
+        @Override
+        public CharSequence subSequence(int start, int end) {
+            return mStr.subSequence(start, end);
+        }
+
+        @Override
+        public String toString() {
+            return mStr;
+        }
+    };
+
+    private List<CharSequence> buildTestCharSequences(String testString, Normalizer.Form[] forms) {
+        List<CharSequence> result = new ArrayList<CharSequence>();
+
+        List<String> normalizedStrings = new ArrayList<String>();
+        for (Normalizer.Form form: forms) {
+            normalizedStrings.add(Normalizer.normalize(testString, form));
+        }
+
+        for (String str: normalizedStrings) {
+            result.add(str);
+            result.add(new SpannedString(str));
+            result.add(new SpannableString(str));
+            result.add(new SpannableStringBuilder(str));  // as a GraphicsOperations implementation.
+            result.add(new FakeCharSequence(str));  // as a not well known implementation.
+        }
+        return result;
+    }
+
+    private String buildTestMessage(CharSequence seq) {
+        String normalized;
+        if (Normalizer.isNormalized(seq, Normalizer.Form.NFC)) {
+            normalized = "NFC";
+        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFD)) {
+            normalized = "NFD";
+        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFKC)) {
+            normalized = "NFKC";
+        } else if (Normalizer.isNormalized(seq, Normalizer.Form.NFKD)) {
+            normalized = "NFKD";
+        } else {
+            throw new IllegalStateException("Normalized form is not NFC/NFD/NFKC/NFKD");
+        }
+
+        StringBuilder builder = new StringBuilder();
+        for (int i = 0; i < seq.length(); ++i) {
+            builder.append(String.format("0x%04X ", Integer.valueOf(seq.charAt(i))));
+        }
+
+        return "testString: \"" + seq.toString() + "\"[" + builder.toString() + "]" +
+                ", class: " + seq.getClass().getName() +
+                ", Normalization: " + normalized;
+    }
+
+    public void testGetOffset_ASCII() {
+        String testStrings[] = { "abcde", "ab\ncd", "ab\tcd", "ab\n\nc", "ab\n\tc" };
+
+        for (String testString: testStrings) {
+            for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
+                StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                        DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+                String testLabel = buildTestMessage(seq);
+
+                assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
+                assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
+                assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
+                assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
+                assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
+                assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));
+
+                assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
+                assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
+                assertEquals(testLabel, 3, layout.getOffsetToRightOf(2));
+                assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
+                assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
+                assertEquals(testLabel, 5, layout.getOffsetToRightOf(5));
+            }
+        }
+
+        String testString = "ab\r\nde";
+        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(6));
+
+            assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(6));
+        }
+    }
+
+    public void testGetOffset_UNICODE() {
+        String testStrings[] = new String[] {
+              // Cyrillic alphabets.
+              "\u0410\u0411\u0412\u0413\u0414",
+              // Japanese Hiragana Characters.
+              "\u3042\u3044\u3046\u3048\u304A",
+        };
+
+        for (String testString: testStrings) {
+            for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
+                StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                        DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+                String testLabel = buildTestMessage(seq);
+
+                assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
+                assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
+                assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
+                assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
+                assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
+                assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));
+
+                assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
+                assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
+                assertEquals(testLabel, 3, layout.getOffsetToRightOf(2));
+                assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
+                assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
+                assertEquals(testLabel, 5, layout.getOffsetToRightOf(5));
+            }
+        }
+    }
+
+    public void testGetOffset_UNICODE_Normalization() {
+        // "A" with acute, circumflex, tilde, diaeresis, ring above.
+        String testString = "\u00C1\u00C2\u00C3\u00C4\u00C5";
+        Normalizer.Form[] oneUnicodeForms = { Normalizer.Form.NFC, Normalizer.Form.NFKC };
+        for (CharSequence seq: buildTestCharSequences(testString, oneUnicodeForms)) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));
+
+            assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 3, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 5, layout.getOffsetToRightOf(5));
+        }
+
+        Normalizer.Form[] twoUnicodeForms = { Normalizer.Form.NFD, Normalizer.Form.NFKD };
+        for (CharSequence seq: buildTestCharSequences(testString, twoUnicodeForms)) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(6));
+            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(7));
+            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(8));
+            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(9));
+            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(10));
+
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
+            assertEquals(testLabel, 8, layout.getOffsetToRightOf(6));
+            assertEquals(testLabel, 8, layout.getOffsetToRightOf(7));
+            assertEquals(testLabel, 10, layout.getOffsetToRightOf(8));
+            assertEquals(testLabel, 10, layout.getOffsetToRightOf(9));
+            assertEquals(testLabel, 10, layout.getOffsetToRightOf(10));
+        }
+    }
+
+    public void testGetOffset_UNICODE_SurrogatePairs() {
+        // Emoticons for surrogate pairs tests.
+        String testString =
+                "\uD83D\uDE00\uD83D\uDE01\uD83D\uDE02\uD83D\uDE03\uD83D\uDE04";
+        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(5));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(6));
+            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(7));
+            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(8));
+            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(9));
+            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(10));
+
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
+            assertEquals(testLabel, 8, layout.getOffsetToRightOf(6));
+            assertEquals(testLabel, 8, layout.getOffsetToRightOf(7));
+            assertEquals(testLabel, 10, layout.getOffsetToRightOf(8));
+            assertEquals(testLabel, 10, layout.getOffsetToRightOf(9));
+            assertEquals(testLabel, 10, layout.getOffsetToRightOf(10));
+        }
+    }
+
+    public void testGetOffset_UNICODE_Thai() {
+        // Thai Characters. The expected cursorable boundary is
+        // | \u0E02 | \u0E2D | \u0E1A | \u0E04\u0E38 | \u0E13 |
+        String testString = "\u0E02\u0E2D\u0E1A\u0E04\u0E38\u0E13";
+        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(5));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(6));
+
+            assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 3, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 5, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 5, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(6));
+        }
+    }
+
+    public void testGetOffset_UNICODE_Hebrew() {
+        String testString = "\u05DE\u05E1\u05E2\u05D3\u05D4"; // Hebrew Characters
+        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN,
+                    TextDirectionHeuristics.RTL, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(5));
+
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 1, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 3, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(5));
+        }
+    }
+
+    public void testGetOffset_UNICODE_Arabic() {
+        // Arabic Characters. The expected cursorable boundary is
+        // | \u0623 \u064F | \u0633 \u0652 | \u0631 \u064E | \u0629 \u064C |";
+        String testString = "\u0623\u064F\u0633\u0652\u0631\u064E\u0629\u064C";
+
+        Normalizer.Form[] oneUnicodeForms = { Normalizer.Form.NFC, Normalizer.Form.NFKC };
+        for (CharSequence seq: buildTestCharSequences(testString, oneUnicodeForms)) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(5));
+            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(6));
+            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(7));
+            assertEquals(testLabel, 8, layout.getOffsetToLeftOf(8));
+
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(5));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(6));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(7));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(8));
+        }
+    }
+
+    public void testGetOffset_UNICODE_Bidi() {
+        // String having RTL characters and LTR characters
+
+        // LTR Context
+        // The first and last two characters are LTR characters.
+        String testString = "\u0061\u0062\u05DE\u05E1\u05E2\u0063\u0064";
+        // Logical order: [L1] [L2] [R1] [R2] [R3] [L3] [L4]
+        //               0    1    2    3    4    5    6    7
+        // Display order: [L1] [L2] [R3] [R2] [R1] [L3] [L4]
+        //               0    1    2    4    3    5    6    7
+        // [L?] means ?th LTR character and [R?] means ?th RTL character.
+        for (CharSequence seq: buildTestCharSequences(testString, Normalizer.Form.values())) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(5));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(6));
+            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(7));
+
+            assertEquals(testLabel, 1, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 5, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 3, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(5));
+            assertEquals(testLabel, 7, layout.getOffsetToRightOf(6));
+            assertEquals(testLabel, 7, layout.getOffsetToRightOf(7));
+        }
+
+        // RTL Context
+        // The first and last two characters are RTL characters.
+        String testString2 = "\u05DE\u05E1\u0063\u0064\u0065\u05DE\u05E1";
+        // Logical order: [R1] [R2] [L1] [L2] [L3] [R3] [R4]
+        //               0    1    2    3    4    5    6    7
+        // Display order: [R4] [R3] [L1] [L2] [L3] [R2] [R1]
+        //               7    6    5    3    4    2    1    0
+        // [L?] means ?th LTR character and [R?] means ?th RTL character.
+        for (CharSequence seq: buildTestCharSequences(testString2, Normalizer.Form.values())) {
+            StaticLayout layout = new StaticLayout(seq, mDefaultPaint,
+                    DEFAULT_OUTER_WIDTH, DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+
+            String testLabel = buildTestMessage(seq);
+
+            assertEquals(testLabel, 1, layout.getOffsetToLeftOf(0));
+            assertEquals(testLabel, 2, layout.getOffsetToLeftOf(1));
+            assertEquals(testLabel, 4, layout.getOffsetToLeftOf(2));
+            assertEquals(testLabel, 5, layout.getOffsetToLeftOf(3));
+            assertEquals(testLabel, 3, layout.getOffsetToLeftOf(4));
+            assertEquals(testLabel, 6, layout.getOffsetToLeftOf(5));
+            assertEquals(testLabel, 7, layout.getOffsetToLeftOf(6));
+            assertEquals(testLabel, 7, layout.getOffsetToLeftOf(7));
+
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(0));
+            assertEquals(testLabel, 0, layout.getOffsetToRightOf(1));
+            assertEquals(testLabel, 1, layout.getOffsetToRightOf(2));
+            assertEquals(testLabel, 4, layout.getOffsetToRightOf(3));
+            assertEquals(testLabel, 2, layout.getOffsetToRightOf(4));
+            assertEquals(testLabel, 3, layout.getOffsetToRightOf(5));
+            assertEquals(testLabel, 5, layout.getOffsetToRightOf(6));
+            assertEquals(testLabel, 6, layout.getOffsetToRightOf(7));
+        }
+    }
+
+    public void testVeryLargeString() {
+        final int MAX_COUNT = 1 << 21;
+        final int WORD_SIZE = 32;
+        char[] longText = new char[MAX_COUNT];
+        for (int n = 0; n < MAX_COUNT; n++) {
+            longText[n] = (n % WORD_SIZE) == 0 ? ' ' : 'm';
+        }
+        String longTextString = new String(longText);
+        TextPaint paint = new TestingTextPaint();
+        StaticLayout layout = new StaticLayout(longTextString, paint, DEFAULT_OUTER_WIDTH,
+                DEFAULT_ALIGN, SPACE_MULTI, SPACE_ADD, true);
+        assertNotNull(layout);
+    }
 }
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 9d739d3..8ca1fea 100644
--- a/tests/tests/text/src/android/text/format/cts/DateFormatTest.java
+++ b/tests/tests/text/src/android/text/format/cts/DateFormatTest.java
@@ -19,19 +19,23 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
+import android.os.ParcelFileDescriptor;
 import android.provider.Settings;
-import android.test.AndroidTestCase;
+import android.test.InstrumentationTestCase;
 import android.text.format.DateFormat;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
+import java.io.FileInputStream;
+import java.io.InputStream;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.Locale;
+import java.util.Scanner;
 import java.util.TimeZone;
 
-public class DateFormatTest extends AndroidTestCase {
+public class DateFormatTest extends InstrumentationTestCase {
 
     private Context mContext;
     private ContentResolver mContentResolver;
@@ -46,17 +50,43 @@
 
     private boolean mIs24HourFormat;
     private Locale mDefaultLocale;
-    private String mDefaultFormat;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mContext = getContext();
+        enableAppOps();
+        mContext = getInstrumentation().getContext();
         mContentResolver = mContext.getContentResolver();
         mIs24HourFormat = DateFormat.is24HourFormat(mContext);
         mDefaultLocale = Locale.getDefault();
-        mDefaultFormat = Settings.System.getString(mContext.getContentResolver(),
-                Settings.System.DATE_FORMAT);
+    }
+
+    private void enableAppOps() {
+        StringBuilder cmd = new StringBuilder();
+        cmd.append("appops set ");
+        cmd.append(getInstrumentation().getContext().getPackageName());
+        cmd.append(" android:write_settings allow");
+        getInstrumentation().getUiAutomation().executeShellCommand(cmd.toString());
+
+        StringBuilder query = new StringBuilder();
+        query.append("appops get ");
+        query.append(getInstrumentation().getContext().getPackageName());
+        query.append(" android:write_settings");
+        String queryStr = query.toString();
+
+        String result = "No operations.";
+        while (result.contains("No operations")) {
+            ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation().executeShellCommand(
+                                        queryStr);
+            InputStream inputStream = new FileInputStream(pfd.getFileDescriptor());
+            result = convertStreamToString(inputStream);
+        }
+    }
+
+    private String convertStreamToString(InputStream is) {
+        try (Scanner scanner = new Scanner(is).useDelimiter("\\A")) {
+            return scanner.hasNext() ? scanner.next() : "";
+        }
     }
 
     @Override
@@ -67,7 +97,7 @@
         if (!Locale.getDefault().equals(mDefaultLocale)) {
             Locale.setDefault(mDefaultLocale);
         }
-        Settings.System.putString(mContentResolver, Settings.System.DATE_FORMAT, mDefaultFormat);
+
         super.tearDown();
     }
 
@@ -146,12 +176,6 @@
         assertTrue(source.indexOf("5") >= 0);
         assertTrue(source.indexOf("30") >= 0);
 
-        String testFormat = "yyyy-MM-dd";
-        String testOrder = "yMd";
-        Settings.System.putString(mContentResolver, Settings.System.DATE_FORMAT, testFormat);
-        String actualOrder = String.valueOf(DateFormat.getDateFormatOrder(mContext));
-        assertEquals(testOrder, actualOrder);
-
         String format = "MM/dd/yy";
         String expectedString = "12/18/08";
         Calendar calendar = new GregorianCalendar(YEAR, MONTH, DAY);
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 1e62819..9ab815f 100644
--- a/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
+++ b/tests/tests/text/src/android/text/format/cts/DateUtilsTest.java
@@ -83,6 +83,9 @@
         assertEquals("PM", DateUtils.getAMPMString(Calendar.PM));
     }
 
+    // This is to test the mapping between DateUtils' public API and
+    // libcore/icu4c's implementation. More tests, in different locales, are
+    // in libcore's CTS tests.
     public void test_getRelativeTimeSpanString() {
         if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) {
             return;
@@ -90,56 +93,32 @@
 
         final long ONE_SECOND_IN_MS = 1000;
         assertEquals("0 minutes ago",
-                     DateUtils.getRelativeTimeSpanString(mBaseTime - ONE_SECOND_IN_MS));
-        assertEquals("in 0 minutes",
-                     DateUtils.getRelativeTimeSpanString(mBaseTime + ONE_SECOND_IN_MS));
+                DateUtils.getRelativeTimeSpanString(mBaseTime - ONE_SECOND_IN_MS));
+        assertEquals("In 0 minutes",
+                DateUtils.getRelativeTimeSpanString(mBaseTime + ONE_SECOND_IN_MS));
 
         final long ONE_MINUTE_IN_MS = 60 * ONE_SECOND_IN_MS;
-        assertEquals("1 minute ago",
-                     DateUtils.getRelativeTimeSpanString(0, ONE_MINUTE_IN_MS, DateUtils.MINUTE_IN_MILLIS));
-        assertEquals("in 1 minute",
-                     DateUtils.getRelativeTimeSpanString(ONE_MINUTE_IN_MS, 0, DateUtils.MINUTE_IN_MILLIS));
-
-        assertEquals("42 minutes ago",
-                     DateUtils.getRelativeTimeSpanString(mBaseTime - (42 * ONE_MINUTE_IN_MS),
-                                                         mBaseTime, DateUtils.MINUTE_IN_MILLIS));
-        assertEquals("in 42 minutes",
-                     DateUtils.getRelativeTimeSpanString(mBaseTime + (42 * ONE_MINUTE_IN_MS),
-                                                         mBaseTime, DateUtils.MINUTE_IN_MILLIS));
+        assertEquals("1 minute ago", DateUtils.getRelativeTimeSpanString(0, ONE_MINUTE_IN_MS,
+                DateUtils.MINUTE_IN_MILLIS));
+        assertEquals("In 1 minute", DateUtils.getRelativeTimeSpanString(ONE_MINUTE_IN_MS, 0,
+                DateUtils.MINUTE_IN_MILLIS));
 
         final long ONE_HOUR_IN_MS = 60 * 60 * 1000;
         final long TWO_HOURS_IN_MS = 2 * ONE_HOUR_IN_MS;
         assertEquals("2 hours ago", DateUtils.getRelativeTimeSpanString(mBaseTime - TWO_HOURS_IN_MS,
                 mBaseTime, DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_NUMERIC_DATE));
-        assertEquals("in 2 hours", DateUtils.getRelativeTimeSpanString(mBaseTime + TWO_HOURS_IN_MS,
+        assertEquals("In 2 hours", DateUtils.getRelativeTimeSpanString(mBaseTime + TWO_HOURS_IN_MS,
                 mBaseTime, DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_NUMERIC_DATE));
-
-        assertEquals("in 42 mins", DateUtils.getRelativeTimeSpanString(mBaseTime + (42 * ONE_MINUTE_IN_MS),
-                mBaseTime, DateUtils.MINUTE_IN_MILLIS,
-                DateUtils.FORMAT_ABBREV_RELATIVE));
-
-        final long ONE_DAY_IN_MS = 24 * ONE_HOUR_IN_MS;
-        assertEquals("Tomorrow",
-                     DateUtils.getRelativeTimeSpanString(ONE_DAY_IN_MS, 0, DateUtils.DAY_IN_MILLIS, 0));
-        assertEquals("in 2 days",
-                     DateUtils.getRelativeTimeSpanString(2 * ONE_DAY_IN_MS, 0, DateUtils.DAY_IN_MILLIS, 0));
-        assertEquals("Yesterday",
-                     DateUtils.getRelativeTimeSpanString(0, ONE_DAY_IN_MS, DateUtils.DAY_IN_MILLIS, 0));
-        assertEquals("2 days ago",
-                     DateUtils.getRelativeTimeSpanString(0, 2 * ONE_DAY_IN_MS, DateUtils.DAY_IN_MILLIS, 0));
-
-        final long DAY_DURATION = 5 * 24 * 60 * 60 * 1000;
-        assertNotNull(DateUtils.getRelativeTimeSpanString(mContext, mBaseTime - DAY_DURATION, true));
-        assertNotNull(DateUtils.getRelativeTimeSpanString(mContext, mBaseTime - DAY_DURATION));
     }
 
+    // Similar to test_getRelativeTimeSpanString(). The function here is to
+    // test the mapping between DateUtils's public API and libcore/icu4c's
+    // implementation. More tests, in different locales, are in libcore's
+    // CTS tests.
     public void test_getRelativeDateTimeString() {
         final long DAY_DURATION = 5 * 24 * 60 * 60 * 1000;
-        assertNotNull(DateUtils.getRelativeDateTimeString(mContext,
-                                                          mBaseTime - DAY_DURATION,
-                                                          DateUtils.MINUTE_IN_MILLIS,
-                                                          DateUtils.DAY_IN_MILLIS,
-                                                          DateUtils.FORMAT_NUMERIC_DATE));
+        assertNotNull(DateUtils.getRelativeDateTimeString(mContext, mBaseTime - DAY_DURATION,
+                DateUtils.MINUTE_IN_MILLIS, DateUtils.DAY_IN_MILLIS, DateUtils.FORMAT_NUMERIC_DATE));
     }
 
     public void test_formatElapsedTime() {
@@ -211,7 +190,7 @@
         long fixedTime = date.getTime();
         final long HOUR_DURATION = 2 * 60 * 60 * 1000;
         assertEquals("Monday", DateUtils.formatDateRange(mContext, fixedTime,
-                     fixedTime + HOUR_DURATION, DateUtils.FORMAT_SHOW_WEEKDAY));
+                fixedTime + HOUR_DURATION, DateUtils.FORMAT_SHOW_WEEKDAY));
     }
 
     public void testIsToday() {
@@ -221,15 +200,19 @@
     }
 
     public void test_bug_7548161() {
+        if (!LocaleUtils.isCurrentLocale(mContext, Locale.US)) {
+            return;
+        }
+
         long now = System.currentTimeMillis();
         long today = now;
         long tomorrow = now + DateUtils.DAY_IN_MILLIS;
         long yesterday = now - DateUtils.DAY_IN_MILLIS;
         assertEquals("Tomorrow", DateUtils.getRelativeTimeSpanString(tomorrow, now,
-                                                                     DateUtils.DAY_IN_MILLIS, 0));
+                DateUtils.DAY_IN_MILLIS, 0));
         assertEquals("Yesterday", DateUtils.getRelativeTimeSpanString(yesterday, now,
-                                                                      DateUtils.DAY_IN_MILLIS, 0));
+                DateUtils.DAY_IN_MILLIS, 0));
         assertEquals("Today", DateUtils.getRelativeTimeSpanString(today, now,
-                                                                  DateUtils.DAY_IN_MILLIS, 0));
+                DateUtils.DAY_IN_MILLIS, 0));
     }
 }
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 bf4a684..9c3c45d 100644
--- a/tests/tests/text/src/android/text/format/cts/FormatterTest.java
+++ b/tests/tests/text/src/android/text/format/cts/FormatterTest.java
@@ -32,24 +32,24 @@
         BigDecimal bd = new BigDecimal((long) 1024, mc);
 
         // test different long values with various length
-        assertEquals("0.00B", Formatter.formatFileSize(mContext, 0));
+        assertEquals("0.00 B", Formatter.formatFileSize(mContext, 0));
 
-        assertEquals("899B", Formatter.formatFileSize(mContext, 899));
+        assertEquals("899 B", Formatter.formatFileSize(mContext, 899));
 
-        assertEquals("1.00KB", Formatter.formatFileSize(mContext, bd.pow(1).longValue()));
+        assertEquals("1.00 KB", Formatter.formatFileSize(mContext, bd.pow(1).longValue()));
 
-        assertEquals("1.00MB", Formatter.formatFileSize(mContext, bd.pow(2).longValue()));
+        assertEquals("1.00 MB", Formatter.formatFileSize(mContext, bd.pow(2).longValue()));
 
-        assertEquals("1.00GB", Formatter.formatFileSize(mContext, bd.pow(3).longValue()));
+        assertEquals("1.00 GB", Formatter.formatFileSize(mContext, bd.pow(3).longValue()));
 
-        assertEquals("1.00TB", Formatter.formatFileSize(mContext, bd.pow(4).longValue()));
+        assertEquals("1.00 TB", Formatter.formatFileSize(mContext, bd.pow(4).longValue()));
 
-        assertEquals("1.00PB", Formatter.formatFileSize(mContext, bd.pow(5).longValue()));
+        assertEquals("1.00 PB", Formatter.formatFileSize(mContext, bd.pow(5).longValue()));
 
-        assertEquals("1024PB", Formatter.formatFileSize(mContext, bd.pow(6).longValue()));
+        assertEquals("1024 PB", Formatter.formatFileSize(mContext, bd.pow(6).longValue()));
 
         // test Negative value
-        assertEquals("-1.00B", Formatter.formatFileSize(mContext, -1));
+        assertEquals("-1.00 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 cc73272..37c4f27 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", "pm");
-        assertFormatEquals(t, "%P", "pm");
+        assertFormatEquals(t, "%p", "p.m.");
+        assertFormatEquals(t, "%P", "p.m.");
         assertFormatEquals(t, "%R", "12:30");
-        assertFormatEquals(t, "%r", "12:30:15 pm");
+        assertFormatEquals(t, "%r", "12:30:15 p.m.");
         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 10d08d0..482edb0 100644
--- a/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/ArrowKeyMovementMethodTest.java
@@ -255,7 +255,7 @@
 
         assertFalse(mArrowKeyMovementMethod.onKeyDown(mTextView, mEditable,
                 KeyEvent.KEYCODE_DPAD_UP, noMetaEvent));
-        // |first line
+        // first lin|e
         // second line
         // last line
         assertSelection(0);
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 34ed2dc..ba8bad5 100644
--- a/tests/tests/text/src/android/text/method/cts/BaseKeyListenerTest.java
+++ b/tests/tests/text/src/android/text/method/cts/BaseKeyListenerTest.java
@@ -35,25 +35,92 @@
     private static final CharSequence TEST_STRING = "123456";
 
     public void testBackspace() {
-        final Editable content = Editable.Factory.getInstance().newEditable(TEST_STRING);
+        testBackspace(0);
+    }
+
+    private void testBackspace(int modifiers) {
         final MockBaseKeyListener mockBaseKeyListener = new MockBaseKeyListener();
+        final KeyEvent event = getKey(KeyEvent.KEYCODE_DEL, modifiers);
+        Editable content = Editable.Factory.getInstance().newEditable(TEST_STRING);
 
         // Nothing to delete when the cursor is at the beginning.
-        final KeyEvent delKeyEvent = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
         prepTextViewSync(content, mockBaseKeyListener, false, 0, 0);
-        mockBaseKeyListener.backspace(mTextView, content, KeyEvent.KEYCODE_DEL, delKeyEvent);
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
         assertEquals("123456", content.toString());
 
         // Delete the first three letters using a selection.
         prepTextViewSync(content, mockBaseKeyListener, false, 0, 3);
-        mockBaseKeyListener.backspace(mTextView, content, KeyEvent.KEYCODE_DEL, delKeyEvent);
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
         assertEquals("456", content.toString());
 
-        // Delete the entire line with ALT + DEL
-        final KeyEvent altDelKeyEvent = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
-                KeyEvent.KEYCODE_DEL, 0, KeyEvent.META_ALT_ON);
+        // Delete the character prior to the cursor when there's no selection
+        prepTextViewSync(content, mockBaseKeyListener, false, 2, 2);
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
+        assertEquals("46", content.toString());
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
+        assertEquals("6", content.toString());
+
+        // The deletion works on a Logical direction basis in RTL text..
+        String testText = "\u05E9\u05DC\u05D5\u05DD\u002E";
+        content = Editable.Factory.getInstance().newEditable(testText);
+
         prepTextViewSync(content, mockBaseKeyListener, false, 0, 0);
-        mockBaseKeyListener.backspace(mTextView, content, KeyEvent.KEYCODE_DEL, altDelKeyEvent);
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
+        assertEquals(testText, content.toString());
+
+        int end = testText.length();
+        prepTextViewSync(content, mockBaseKeyListener, false, end, end);
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
+        assertEquals("\u05E9\u05DC\u05D5\u05DD", content.toString());
+
+        int middle = testText.length() / 2;
+        prepTextViewSync(content, mockBaseKeyListener, false, middle, middle);
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
+        assertEquals("\u05E9\u05D5\u05DD", content.toString());
+
+        // And in BiDi text
+        testText = "\u05D6\u05D4\u0020Android\u0020\u05E2\u05D5\u05D1\u05D3";
+        content = Editable.Factory.getInstance().newEditable(testText);
+
+        prepTextViewSync(content, mockBaseKeyListener, false, 0, 0);
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
+        assertEquals(content.toString(), content.toString());
+
+        end = testText.length();
+        prepTextViewSync(content, mockBaseKeyListener, false, end, end);
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
+        assertEquals("\u05D6\u05D4\u0020Android\u0020\u05E2\u05D5\u05D1", content.toString());
+
+        prepTextViewSync(content, mockBaseKeyListener, false, 6, 6);
+        mockBaseKeyListener.backspace(mTextView, content, event.getKeyCode(), event);
+        assertEquals("\u05D6\u05D4\u0020Anroid\u0020\u05E2\u05D5\u05D1", content.toString());
+    }
+
+    public void testBackspace_withShift() {
+        testBackspace(KeyEvent.META_SHIFT_ON | KeyEvent.META_SHIFT_LEFT_ON);
+    }
+
+    public void testBackspace_withAlt() {
+        final MockBaseKeyListener mockBaseKeyListener = new MockBaseKeyListener();
+        Editable content = Editable.Factory.getInstance().newEditable(TEST_STRING);
+
+        // Delete the entire line with ALT + DEL, even if we're at the head...
+        prepTextViewSync(content, mockBaseKeyListener, false, 0, 0);
+        executeAltBackspace(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+
+        // ...or the tail...
+        content = Editable.Factory.getInstance().newEditable(TEST_STRING);
+        final int end = TEST_STRING.length();
+        prepTextViewSync(content, mockBaseKeyListener, false, end, end);
+        executeAltBackspace(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+
+        // ...or somewhere in the middle.
+        content = Editable.Factory.getInstance().newEditable(TEST_STRING);
+        final int middle = end / 2;
+        prepTextViewSync(content, mockBaseKeyListener, false, middle, middle);
+        executeAltBackspace(content, mockBaseKeyListener);
         assertEquals("", content.toString());
     }
 
@@ -86,6 +153,341 @@
         assertEquals(TEST_STRING, mTextView.getText().toString());
     }
 
+    private void assertCursorPosition(Editable content, int offset) {
+        assertEquals(offset, Selection.getSelectionStart(content));
+        assertEquals(offset, Selection.getSelectionEnd(content));
+    }
+
+    public void testBackspace_withCtrl() {
+        final MockBaseKeyListener mockBaseKeyListener = new MockBaseKeyListener();
+
+        // If the contents only having symbolic characters, delete all characters.
+        String testText = "!#$%&'()`{*}_?+";
+        Editable content = Editable.Factory.getInstance().newEditable(testText);
+        prepTextViewSync(content, mockBaseKeyListener, false, testText.length(), testText.length());
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        // Latin ASCII text
+        testText = "Hello, World. This is Android.";
+        content = Editable.Factory.getInstance().newEditable(testText);
+
+        // If the cursor is head of the text, should do nothing.
+        prepTextViewSync(content, mockBaseKeyListener, false, 0, 0);
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("Hello, World. This is Android.", content.toString());
+        assertCursorPosition(content, 0);
+
+        prepTextViewSync(content, mockBaseKeyListener, false, testText.length(), testText.length());
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("Hello, World. This is ", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("Hello, World. This ", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("Hello, World. ", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("Hello, ", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        // Latin ASCII, cursor is middle of the text.
+        testText = "Hello, World. This is Android.";
+        content = Editable.Factory.getInstance().newEditable(testText);
+        int charsFromTail = 12;  // Cursor location is 12 chars from the tail.(before "is").
+        prepTextViewSync(content, mockBaseKeyListener, false,
+                         testText.length() - charsFromTail, testText.length() - charsFromTail);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("Hello, World.  is Android.", content.toString());
+        assertCursorPosition(content, content.toString().length() - charsFromTail);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("Hello,  is Android.", content.toString());
+        assertCursorPosition(content, content.toString().length() - charsFromTail);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals(" is Android.", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals(" is Android.", content.toString());
+        assertCursorPosition(content, 0);
+
+        // Latin ASCII, cursor is inside word.
+        testText = "Hello, World. This is Android.";
+        content = Editable.Factory.getInstance().newEditable(testText);
+        charsFromTail = 14;  // Cursor location is 12 chars from the tail. (inside "This")
+        prepTextViewSync(content, mockBaseKeyListener, false,
+                         testText.length() - charsFromTail, testText.length() - charsFromTail);
+
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("Hello, World. is is Android.", content.toString());
+        assertCursorPosition(content, content.toString().length() - charsFromTail);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("Hello, is is Android.", content.toString());
+        assertCursorPosition(content, content.toString().length() - charsFromTail);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("is is Android.", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("is is Android.", content.toString());
+        assertCursorPosition(content, 0);
+
+        // Hebrew Text
+        // The deletion works on a Logical direction basis.
+        testText = "\u05E9\u05DC\u05D5\u05DD\u0020\u05D4\u05E2\u05D5\u05DC\u05DD\u002E\u0020" +
+                   "\u05D6\u05D4\u0020\u05D0\u05E0\u05D3\u05E8\u05D5\u05D0\u05D9\u05D3\u002E";
+        content = Editable.Factory.getInstance().newEditable(testText);
+        prepTextViewSync(content, mockBaseKeyListener, false, testText.length(), testText.length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("\u05E9\u05DC\u05D5\u05DD\u0020\u05D4\u05E2\u05D5\u05DC\u05DD\u002E\u0020" +
+                     "\u05D6\u05D4\u0020", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("\u05E9\u05DC\u05D5\u05DD\u0020\u05D4\u05E2\u05D5\u05DC\u05DD\u002E\u0020",
+                     content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("\u05E9\u05DC\u05D5\u05DD\u0020", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        // BiDi Text
+        // The deletion works on a Logical direction basis.
+        testText = "\u05D6\u05D4\u0020\u05DC\u002D\u0020\u0041Android\u0020\u05E2\u05D5\u05D1" +
+                   "\u05D3\u0020\u05D4\u05D9\u05D8\u05D1\u002E";
+        content = Editable.Factory.getInstance().newEditable(testText);
+        prepTextViewSync(content, mockBaseKeyListener, false, testText.length(), testText.length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("\u05D6\u05D4\u0020\u05DC\u002D\u0020\u0041Android\u0020\u05E2\u05D5\u05D1" +
+                     "\u05D3\u0020", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("\u05D6\u05D4\u0020\u05DC\u002D\u0020\u0041Android\u0020", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("\u05D6\u05D4\u0020\u05DC\u002D\u0020", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("\u05D6\u05D4\u0020", content.toString());
+        assertCursorPosition(content, content.toString().length());
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlBackspace(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+    }
+
+    public void testForwardDelete_withCtrl() {
+        final MockBaseKeyListener mockBaseKeyListener = new MockBaseKeyListener();
+
+        // If the contents only having symbolic characters, delete all characters.
+        String testText = "!#$%&'()`{*}_?+";
+        Editable content = Editable.Factory.getInstance().newEditable(testText);
+        prepTextViewSync(content, mockBaseKeyListener, false, 0, 0);
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        // Latin ASCII text
+        testText = "Hello, World. This is Android.";
+        content = Editable.Factory.getInstance().newEditable(testText);
+
+        // If the cursor is tail of the text, should do nothing.
+        prepTextViewSync(content, mockBaseKeyListener, false, testText.length(), testText.length());
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World. This is Android.", content.toString());
+        assertCursorPosition(content, testText.length());
+
+        prepTextViewSync(content, mockBaseKeyListener, false, 0, 0);
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals(", World. This is Android.", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals(". This is Android.", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals(" is Android.", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals(" Android.", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals(".", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        // Latin ASCII, cursor is middle of the text.
+        testText = "Hello, World. This is Android.";
+        content = Editable.Factory.getInstance().newEditable(testText);
+        int charsFromHead = 14;  // Cursor location is 14 chars from the head.(before "This").
+        prepTextViewSync(content, mockBaseKeyListener, false, charsFromHead, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World.  is Android.", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World.  Android.", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World. .", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World. ", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World. ", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        // Latin ASCII, cursor is inside word.
+        testText = "Hello, World. This is Android.";
+        content = Editable.Factory.getInstance().newEditable(testText);
+        charsFromHead = 16;  // Cursor location is 16 chars from the head. (inside "This")
+        prepTextViewSync(content, mockBaseKeyListener, false, charsFromHead, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World. Th is Android.", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World. Th Android.", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World. Th.", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World. Th", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("Hello, World. Th", content.toString());
+        assertCursorPosition(content, charsFromHead);
+
+        // Hebrew Text
+        // The deletion works on a Logical direction basis.
+        testText = "\u05E9\u05DC\u05D5\u05DD\u0020\u05D4\u05E2\u05D5\u05DC\u05DD\u002E\u0020" +
+                   "\u05D6\u05D4\u0020\u05D0\u05E0\u05D3\u05E8\u05D5\u05D0\u05D9\u05D3\u002E";
+        content = Editable.Factory.getInstance().newEditable(testText);
+        prepTextViewSync(content, mockBaseKeyListener, false, 0, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("\u0020\u05D4\u05E2\u05D5\u05DC\u05DD\u002E\u0020\u05D6\u05D4\u0020\u05D0" +
+                     "\u05E0\u05D3\u05E8\u05D5\u05D0\u05D9\u05D3\u002E", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("\u002E\u0020\u05D6\u05D4\u0020\u05D0\u05E0\u05D3\u05E8\u05D5\u05D0\u05D9" +
+                "\u05D3\u002E", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("\u0020\u05D0\u05E0\u05D3\u05E8\u05D5\u05D0\u05D9\u05D3\u002E",
+                     content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("\u002E", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        // BiDi Text
+        // The deletion works on a Logical direction basis.
+        testText = "\u05D6\u05D4\u0020\u05DC\u002D\u0020\u0041Android\u0020\u05E2\u05D5\u05D1" +
+                   "\u05D3\u0020\u05D4\u05D9\u05D8\u05D1\u002E";
+        content = Editable.Factory.getInstance().newEditable(testText);
+        prepTextViewSync(content, mockBaseKeyListener, false, 0, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("\u0020\u05DC\u002D\u0020\u0041Android\u0020\u05E2\u05D5\u05D1\u05D3\u0020" +
+                     "\u05D4\u05D9\u05D8\u05D1\u002E", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("\u002D\u0020\u0041Android\u0020\u05E2\u05D5\u05D1\u05D3\u0020\u05D4\u05D9" +
+                     "\u05D8\u05D1\u002E", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("\u0020\u05E2\u05D5\u05D1\u05D3\u0020\u05D4\u05D9\u05D8\u05D1\u002E",
+                     content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("\u0020\u05D4\u05D9\u05D8\u05D1\u002E", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("\u002E", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+
+        executeCtrlForwardDelete(content, mockBaseKeyListener);
+        assertEquals("", content.toString());
+        assertCursorPosition(content, 0);
+    }
+
     /*
      * Check point:
      * 1. Press 0 key, the content of TextView does not changed.
@@ -115,6 +517,35 @@
 //        assertEquals("13abcd456", mTextView.getText().toString());
     }
 
+    private void executeAltBackspace(Editable content, MockBaseKeyListener listener) {
+        final KeyEvent delKeyEvent = getKey(KeyEvent.KEYCODE_DEL,
+                KeyEvent.META_ALT_ON | KeyEvent.META_ALT_LEFT_ON);
+        listener.backspace(mTextView, content, KeyEvent.KEYCODE_DEL, delKeyEvent);
+    }
+
+    private void executeCtrlBackspace(Editable content, MockBaseKeyListener listener) {
+        final KeyEvent delKeyEvent = getKey(KeyEvent.KEYCODE_DEL,
+                KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON);
+        listener.backspace(mTextView, content, KeyEvent.KEYCODE_DEL, delKeyEvent);
+    }
+
+    private void executeCtrlForwardDelete(Editable content, MockBaseKeyListener listener) {
+        final KeyEvent delKeyEvent = getKey(KeyEvent.KEYCODE_FORWARD_DEL,
+                KeyEvent.META_CTRL_ON | KeyEvent.META_CTRL_LEFT_ON);
+        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/PasswordTransformationMethodTest.java b/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
index 4262a31..72a8e72 100644
--- a/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
+++ b/tests/tests/text/src/android/text/method/cts/PasswordTransformationMethodTest.java
@@ -19,6 +19,7 @@
 
 import android.cts.util.PollingCheck;
 import android.graphics.Rect;
+import android.os.ParcelFileDescriptor;
 import android.provider.Settings.SettingNotFoundException;
 import android.provider.Settings.System;
 import android.test.ActivityInstrumentationTestCase2;
@@ -31,6 +32,10 @@
 import android.widget.LinearLayout;
 import android.widget.LinearLayout.LayoutParams;
 
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.Scanner;
+
 /**
  * Test {@link PasswordTransformationMethod}.
  */
@@ -97,10 +102,39 @@
         mEditText = (EditText) getActivity().findViewById(EDIT_TXT_ID);
         assertTrue(mEditText.isFocused());
 
+        enableAppOps();
         savePasswordPref();
         switchShowPassword(true);
     }
 
+    private void enableAppOps() {
+        StringBuilder cmd = new StringBuilder();
+        cmd.append("appops set ");
+        cmd.append(getInstrumentation().getContext().getPackageName());
+        cmd.append(" android:write_settings allow");
+        getInstrumentation().getUiAutomation().executeShellCommand(cmd.toString());
+
+        StringBuilder query = new StringBuilder();
+        query.append("appops get ");
+        query.append(getInstrumentation().getContext().getPackageName());
+        query.append(" android:write_settings");
+        String queryStr = query.toString();
+
+        String result = "No operations.";
+        while (result.contains("No operations")) {
+            ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation().executeShellCommand(
+                                        queryStr);
+            InputStream inputStream = new FileInputStream(pfd.getFileDescriptor());
+            result = convertStreamToString(inputStream);
+        }
+    }
+
+    private String convertStreamToString(InputStream is) {
+        try (Scanner scanner = new Scanner(is).useDelimiter("\\A")) {
+            return scanner.hasNext() ? scanner.next() : "";
+        }
+    }
+
     @Override
     protected void tearDown() throws Exception {
         resumePasswordPref();
diff --git a/tests/tests/transition/Android.mk b/tests/tests/transition/Android.mk
new file mode 100644
index 0000000..3b48e25
--- /dev/null
+++ b/tests/tests/transition/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 := CtsTransitionTestCases
+
+# 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_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
diff --git a/tests/tests/transition/AndroidManifest.xml b/tests/tests/transition/AndroidManifest.xml
new file mode 100644
index 0000000..0ce1791
--- /dev/null
+++ b/tests/tests/transition/AndroidManifest.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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.cts.transition">
+    <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.transition.cts.TransitionActivity"
+            android:label="TransitionActivity"/>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="com.android.cts.transition"
+                     android:label="CTS tests for android.transition package">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/transition/res/layout/scene1.xml b/tests/tests/transition/res/layout/scene1.xml
new file mode 100644
index 0000000..140bb8d
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene1.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/redSquare" />
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          android:background="#0F0"
+          android:transitionName="green"
+          android:id="@+id/greenSquare"
+          android:layout_below="@+id/redSquare" />
+    <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/scene2.xml b/tests/tests/transition/res/layout/scene2.xml
new file mode 100644
index 0000000..541ec04
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene2.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.
+-->
+
+<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" />
+    <View android:layout_width="10dp"
+          android:layout_height="10dp"
+          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:text="@string/world"
+              android:id="@+id/world"/>
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/scene3.xml b/tests/tests/transition/res/layout/scene3.xml
new file mode 100644
index 0000000..01fb78d
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene3.xml
@@ -0,0 +1,30 @@
+<?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:id="@+id/holder">
+    <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"
+          android:layout_toRightOf="@+id/greenSquare" />
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/scene4.xml b/tests/tests/transition/res/layout/scene4.xml
new file mode 100644
index 0000000..1f1b7d6
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene4.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.
+-->
+
+<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"/>
diff --git a/tests/tests/transition/res/layout/scene5.xml b/tests/tests/transition/res/layout/scene5.xml
new file mode 100644
index 0000000..f7385f8
--- /dev/null
+++ b/tests/tests/transition/res/layout/scene5.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.
+-->
+
+<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">
+    <TextView
+            android:id="@+id/text"
+            android:text="@string/longText"
+            android:layout_width="100dp"
+            android:layout_height="100dp"/>
+</RelativeLayout>
diff --git a/tests/tests/transition/res/layout/transition_main.xml b/tests/tests/transition/res/layout/transition_main.xml
new file mode 100644
index 0000000..64de7dd
--- /dev/null
+++ b/tests/tests/transition/res/layout/transition_main.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:layout_width="match_parent"
+             android:layout_height="match_parent"
+             android:id="@+id/container"/>
diff --git a/tests/tests/transition/res/values/strings.xml b/tests/tests/transition/res/values/strings.xml
new file mode 100644
index 0000000..43b92a5
--- /dev/null
+++ b/tests/tests/transition/res/values/strings.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.
+-->
+<resources>
+    <string name="add_button">Add Button</string>
+    <string name="hello">Hello</string>
+    <string name="world">World</string>
+    <string name="longText">Gummi bears sugar plum pudding. Carrot cake chupa chups lollipop brownie candy canes carrot cake. Chocolate cake dragée chocolate danish halvah brownie. Cake jelly-o danish jelly beans carrot cake toffee jelly-o. Danish sesame snaps soufflé chocolate cupcake jujubes pudding pudding candy canes. Sesame snaps sweet chupa chups marzipan tart. Dessert brownie marzipan powder. Biscuit sugar plum soufflé topping cheesecake. Jelly-o ice cream candy canes tart. Brownie ice cream cake. Chocolate bar cake tart powder. Cookie candy canes marzipan donut jelly beans cheesecake marzipan. Carrot cake dragée cupcake liquorice tiramisu chocolate cake powder macaroon. Liquorice sugar plum powder dessert jelly.</string>
+</resources>
diff --git a/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
new file mode 100644
index 0000000..df1ba19
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/BaseTransitionTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 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.TransitionManager;
+import android.transition.TransitionValues;
+import android.transition.Visibility;
+import android.view.Choreographer;
+import android.view.Choreographer.FrameCallback;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+import java.util.ArrayList;
+
+public class BaseTransitionTest extends ActivityInstrumentationTestCase2<TransitionActivity> {
+    protected TransitionActivity mActivity;
+    protected FrameLayout mSceneRoot;
+    public float mAnimatedValue;
+    protected ArrayList<View> mTargets = new ArrayList<>();
+    protected TestTransition mTransition;
+
+    public BaseTransitionTest() {
+        super(TransitionActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        setActivityInitialTouchMode(false);
+        mActivity = getActivity();
+        mSceneRoot = (FrameLayout) mActivity.findViewById(R.id.container);
+        mTargets.clear();
+        mTransition = new TestTransition();
+    }
+
+    protected void waitForStart() throws InterruptedException {
+        waitForStart(mTransition.listener);
+    }
+
+    protected static void waitForStart(SimpleTransitionListener listener) throws InterruptedException {
+        long endTime = SystemClock.uptimeMillis() + 50;
+        synchronized (listener) {
+            while (!listener.started) {
+                long now = SystemClock.uptimeMillis();
+                long waitTime = endTime - now;
+                if (waitTime <= 0) {
+                    throw new InterruptedException();
+                }
+                listener.wait(waitTime);
+            }
+        }
+    }
+
+    protected void waitForEnd(long waitMillis) throws InterruptedException {
+        waitForEnd(mTransition.listener, waitMillis);
+    }
+
+    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);
+            }
+        }
+    }
+
+    protected void startTransition(final int layoutId) throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Scene scene = Scene.getSceneForLayout(mSceneRoot, layoutId, mActivity);
+                TransitionManager.go(scene, mTransition);
+            }
+        });
+        waitForStart();
+    }
+
+    protected void endTransition() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.endTransitions(mSceneRoot);
+            }
+        });
+    }
+
+    protected void enterScene(final int layoutId) 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 };
+        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.
+            }
+        });
+        synchronized (tripped) {
+            long endTime = SystemClock.uptimeMillis() + 60;
+            while (!tripped[0]) {
+                long waitTime = endTime - SystemClock.uptimeMillis();
+                if (waitTime <= 0) {
+                    throw new InterruptedException();
+                }
+                tripped.wait(waitTime);
+            }
+        }
+    }
+
+    public class TestTransition extends Visibility {
+        public final SimpleTransitionListener listener = new SimpleTransitionListener();
+
+        public TestTransition() {
+            addListener(listener);
+            setDuration(100);
+        }
+
+        @Override
+        public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+                TransitionValues endValues) {
+            mTargets.add(endValues.view);
+            return ObjectAnimator.ofFloat(BaseTransitionTest.this, "mAnimatedValue", 0, 1);
+        }
+
+        @Override
+        public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
+                TransitionValues endValues) {
+            mTargets.add(startValues.view);
+            return ObjectAnimator.ofFloat(BaseTransitionTest.this, "mAnimatedValue", 1, 0);
+        }
+    }
+}
diff --git a/tests/tests/transition/src/android/transition/cts/ChangeScrollTest.java b/tests/tests/transition/src/android/transition/cts/ChangeScrollTest.java
new file mode 100644
index 0000000..f5f076d
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/ChangeScrollTest.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 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 {
+
+    public ChangeScrollTest() {
+    }
+
+    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);
+                view.scrollTo(150, 300);
+            }
+        });
+        waitForStart(listener);
+        waitForAnimationFrame();
+        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();
+                assertTrue(scrollX > 0);
+                assertTrue(scrollX < 150);
+                assertTrue(scrollY > 0);
+                assertTrue(scrollY < 300);
+            }
+        });
+        waitForEnd(listener, 100);
+        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);
+            }
+        });
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java b/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java
new file mode 100644
index 0000000..113f5a5
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/SimpleTransitionListener.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Transition;
+import android.transition.Transition.TransitionListener;
+
+/**
+ * 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;
+
+    @Override
+    public synchronized void onTransitionStart(Transition transition) {
+        started = true;
+        this.transition = transition;
+        notifyAll();
+    }
+
+    @Override
+    public synchronized void onTransitionEnd(Transition transition) {
+        ended = true;
+        notifyAll();
+    }
+
+    @Override
+    public synchronized void onTransitionCancel(Transition transition) {
+        canceled = true;
+        notifyAll();
+    }
+
+    @Override
+    public synchronized void onTransitionPause(Transition transition) {
+        paused = true;
+        notifyAll();
+    }
+
+    @Override
+    public synchronized void onTransitionResume(Transition transition) {
+        resumed = true;
+        notifyAll();
+    }
+}
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionActivity.java b/tests/tests/transition/src/android/transition/cts/TransitionActivity.java
new file mode 100644
index 0000000..8236bd5
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/TransitionActivity.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 android.transition.cts;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.OvalShape;
+import android.os.Bundle;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import java.util.ArrayList;
+
+import com.android.cts.transition.R;
+
+public class TransitionActivity extends Activity {
+    @Override
+    public void onCreate(Bundle bundle){
+        super.onCreate(bundle);
+        setContentView(R.layout.transition_main);
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
new file mode 100644
index 0000000..78db908
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/TransitionManagerTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 com.android.cts.transition.R;
+
+import android.transition.Scene;
+import android.transition.TransitionManager;
+import android.view.View;
+
+public class TransitionManagerTest extends BaseTransitionTest {
+
+    public TransitionManagerTest() {
+    }
+
+    public void testBeginDelayedTransition() throws Throwable {
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+                View view = mActivity.getLayoutInflater().inflate(R.layout.scene1, mSceneRoot,
+                        false);
+                mSceneRoot.addView(view);
+            }
+        });
+
+        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);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertNotNull(mActivity.findViewById(R.id.redSquare));
+                assertNotNull(mActivity.findViewById(R.id.greenSquare));
+            }
+        });
+    }
+
+    public void testGo() throws Throwable {
+        startTransition(R.layout.scene1);
+        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);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                assertNotNull(mActivity.findViewById(R.id.redSquare));
+                assertNotNull(mActivity.findViewById(R.id.greenSquare));
+            }
+        });
+    }
+
+    public void testSetTransition1() throws Throwable {
+        final TransitionManager transitionManager = new TransitionManager();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, mActivity);
+                transitionManager.setTransition(scene, mTransition);
+                transitionManager.transitionTo(scene);
+            }
+        });
+
+        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);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                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);
+        endTransition();
+    }
+
+    public void testSetTransition2() throws Throwable {
+        final TransitionManager transitionManager = new TransitionManager();
+        final Scene[] scenes = new Scene[3];
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                scenes[0] = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, mActivity);
+                scenes[1] = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity);
+                scenes[2] = Scene.getSceneForLayout(mSceneRoot, R.layout.scene3, mActivity);
+                transitionManager.setTransition(scenes[0], scenes[1], mTransition);
+                transitionManager.transitionTo(scenes[0]);
+            }
+        });
+        Thread.sleep(50);
+        assertFalse(mTransition.listener.started);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                transitionManager.transitionTo(scenes[1]);
+            }
+        });
+
+        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);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mTransition.listener.started = false;
+                mTransition.listener.ended = false;
+                transitionManager.transitionTo(scenes[2]);
+            }
+        });
+        Thread.sleep(50);
+        assertFalse(mTransition.listener.started);
+        endTransition();
+    }
+
+    public void testEndTransitions() throws Throwable {
+        mTransition.setDuration(400);
+
+        startTransition(R.layout.scene1);
+        waitForStart();
+        endTransition();
+        waitForEnd(50);
+    }
+
+    public void testEndTransitionsBeforeStarted() throws Throwable {
+        mTransition.setDuration(400);
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene1, mActivity);
+                TransitionManager.go(scene, mTransition);
+                TransitionManager.endTransitions(mSceneRoot);
+            }
+        });
+        Thread.sleep(50);
+        assertFalse(mTransition.listener.started);
+        assertFalse(mTransition.listener.ended);
+    }
+}
+
diff --git a/tests/tests/transition/src/android/transition/cts/TransitionTest.java b/tests/tests/transition/src/android/transition/cts/TransitionTest.java
new file mode 100644
index 0000000..8a9f3a3
--- /dev/null
+++ b/tests/tests/transition/src/android/transition/cts/TransitionTest.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 android.transition.cts;
+
+import com.android.cts.transition.R;
+
+import android.animation.ObjectAnimator;
+import android.transition.AutoTransition;
+import android.transition.Scene;
+import android.transition.TransitionManager;
+import android.transition.TransitionValues;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+public class TransitionTest extends BaseTransitionTest {
+
+    public TransitionTest() {
+    }
+
+    public void testAddListener() throws Throwable {
+        startTransition(R.layout.scene1);
+        waitForStart();
+
+        final SimpleTransitionListener listener2 = new SimpleTransitionListener();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                AutoTransition autoTransition = new AutoTransition();
+                autoTransition.setDuration(100);
+                autoTransition.addListener(listener2);
+                Scene scene = Scene.getSceneForLayout(mSceneRoot, R.layout.scene2, mActivity);
+                TransitionManager.go(scene, autoTransition);
+            }
+        });
+
+        waitForStart(listener2);
+
+        assertTrue(mTransition.listener.paused);
+        assertTrue(mTransition.listener.resumed);
+        assertFalse(mTransition.listener.canceled);
+        assertFalse(mTransition.listener.ended);
+        assertTrue(mTransition.listener.started);
+
+        assertFalse(listener2.paused);
+        assertFalse(listener2.resumed);
+        assertFalse(listener2.canceled);
+        assertFalse(listener2.ended);
+        assertTrue(listener2.started);
+        endTransition();
+    }
+
+    public void testRemoveListener() throws Throwable {
+        startTransition(R.layout.scene1);
+        waitForStart();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mTransition.removeListener(mTransition.listener);
+            }
+        });
+
+        Thread.sleep(150);
+        assertFalse(mTransition.listener.ended);
+    }
+
+    public void testAddTargetId() throws Throwable {
+        enterScene(R.layout.scene4);
+        mTransition.addTarget(R.id.holder);
+        mTransition.addTarget(R.id.hello);
+        assertEquals(2, mTransition.getTargetIds().size());
+        startTransition(R.layout.scene1);
+        assertEquals(1, mTargets.size());
+        assertEquals(R.id.hello, mTargets.get(0).getId());
+        endTransition();
+    }
+
+    public void testRemoveTargetId() throws Throwable {
+        enterScene(R.layout.scene4);
+        mTransition.addTarget(R.id.holder);
+        mTransition.addTarget(R.id.hello);
+        mTransition.addTarget(R.id.redSquare);
+        assertEquals(3, mTransition.getTargetIds().size());
+        mTransition.removeTarget(0); // nothing should happen
+        mTransition.removeTarget(R.id.redSquare);
+        assertEquals(2, mTransition.getTargetIds().size());
+
+        startTransition(R.layout.scene1);
+        assertEquals(1, mTargets.size());
+        assertEquals(R.id.hello, mTargets.get(0).getId());
+        endTransition();
+    }
+
+    public void testAddTargetClass() throws Throwable {
+        enterScene(R.layout.scene4);
+        mTransition.addTarget(RelativeLayout.class);
+        mTransition.addTarget(TextView.class);
+        assertEquals(2, mTransition.getTargetTypes().size());
+        startTransition(R.layout.scene1);
+        assertEquals(1, mTargets.size());
+        assertTrue(mTargets.get(0) instanceof TextView);
+        endTransition();
+    }
+
+    public void testRemoveTargetClass() throws Throwable {
+        enterScene(R.layout.scene4);
+        mTransition.addTarget(TextView.class);
+        mTransition.addTarget(View.class);
+        mTransition.addTarget(RelativeLayout.class);
+        assertEquals(3, mTransition.getTargetTypes().size());
+        mTransition.removeTarget(ImageView.class); // should do nothing
+        mTransition.removeTarget(View.class);
+        assertEquals(2, mTransition.getTargetTypes().size());
+        startTransition(R.layout.scene1);
+        assertEquals(1, mTargets.size());
+        assertTrue(mTargets.get(0) instanceof TextView);
+        endTransition();
+    }
+
+    public void testAddTargetView() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        final View[] target = new View[1];
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                target[0] = mActivity.findViewById(R.id.hello);
+            }
+        });
+        mTransition.addTarget(target[0]);
+        assertEquals(1, mTransition.getTargets().size());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+                target[0].setVisibility(View.GONE);
+            }
+        });
+        waitForStart();
+        assertEquals(1, mTargets.size());
+        assertEquals(target[0], mTargets.get(0));
+        endTransition();
+    }
+
+    public void testRemoveTargetView() throws Throwable {
+        enterScene(R.layout.scene1);
+
+        final View[] target = new View[3];
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                target[0] = mActivity.findViewById(R.id.hello);
+                target[1] = mActivity.findViewById(R.id.greenSquare);
+                target[2] = mActivity.findViewById(R.id.redSquare);
+            }
+        });
+
+        mTransition.addTarget(target[0]);
+        mTransition.addTarget(target[1]);
+        assertEquals(2, mTransition.getTargets().size());
+        mTransition.removeTarget(target[2]); // should do nothing
+        mTransition.removeTarget(target[1]);
+        assertEquals(1, mTransition.getTargets().size());
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+                target[0].setVisibility(View.GONE);
+            }
+        });
+        waitForStart();
+        assertEquals(1, mTargets.size());
+        assertEquals(target[0], mTargets.get(0));
+        endTransition();
+    }
+
+    public void testAddTargetName() throws Throwable {
+        enterScene(R.layout.scene4);
+        mTransition.addTarget("red");
+        mTransition.addTarget("holder");
+        assertEquals(2, mTransition.getTargetNames().size());
+        assertEquals(0, mTargets.size());
+        startTransition(R.layout.scene2);
+        assertEquals(1, mTargets.size());
+        assertEquals(R.id.redSquare, mTargets.get(0).getId());
+        endTransition();
+    }
+
+    public void testRemoveTargetName() throws Throwable {
+        enterScene(R.layout.scene4);
+        mTransition.addTarget("holder");
+        mTransition.addTarget("red");
+        mTransition.addTarget("green");
+        assertEquals(3, mTransition.getTargetNames().size());
+        mTransition.removeTarget("purple"); // should do nothing
+        // try to force a different String instance
+        String greenName = new StringBuilder("gre").append("en").toString();
+        mTransition.removeTarget(greenName);
+        assertEquals(2, mTransition.getTargetNames().size());
+        startTransition(R.layout.scene1);
+        assertEquals(1, mTargets.size());
+        assertEquals(R.id.redSquare, mTargets.get(0).getId());
+        endTransition();
+    }
+
+    public void testIsTransitionRequired() throws Throwable {
+        enterScene(R.layout.scene1);
+        mTransition = new NotRequiredTransition();
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
+                mActivity.findViewById(R.id.hello).setVisibility(View.GONE);
+            }
+        });
+        waitForStart();
+        assertEquals(0, mTargets.size());
+        endTransition();
+    }
+
+    private class NotRequiredTransition extends TestTransition {
+        @Override
+        public boolean isTransitionRequired(TransitionValues startValues,
+                TransitionValues newValues) {
+            return false;
+        }
+    }
+}
+
diff --git a/tests/tests/tv/AndroidManifest.xml b/tests/tests/tv/AndroidManifest.xml
index d2b3ddf..79406e0 100644
--- a/tests/tests/tv/AndroidManifest.xml
+++ b/tests/tests/tv/AndroidManifest.xml
@@ -20,6 +20,7 @@
         package="com.android.cts.tv">
 
     <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" />
@@ -66,6 +67,15 @@
                        android:resource="@xml/stub_tv_input_service" />
         </service>
 
+        <service android:name="android.media.tv.cts.TvInputManagerTest$StubTvInputService2"
+                 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>
+
         <service android:name="android.media.tv.cts.TvInputServiceTest$CountingTvInputService"
                  android:permission="android.permission.BIND_TV_INPUT">
             <intent-filter>
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 6a50b56..b4bc6eb 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvContractTest.java
@@ -409,9 +409,8 @@
             String sortOrder) throws Exception {
         try {
             getContext().getContentResolver().query(uri, projection, null, null, sortOrder);
-            fail("Setting sortOrder should fail without ACCESS_ALL_EPG_DATA permission for " + uri);
         } catch (SecurityException e) {
-            // Expected exception
+            fail("Setting sort order shoud be allowed for " + uri);
         }
     }
 
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 48f1f44..ff66dc6 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputManagerTest.java
@@ -16,19 +16,26 @@
 
 package android.media.tv.cts;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageManager;
+import android.cts.util.PollingCheck;
 import android.media.tv.TvContentRating;
 import android.media.tv.TvInputInfo;
 import android.media.tv.TvInputManager;
 import android.os.Handler;
 import android.test.ActivityInstrumentationTestCase2;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
  * Test for {@link android.media.tv.TvInputManager}.
  */
 public class TvInputManagerTest extends ActivityInstrumentationTestCase2<TvViewStubActivity> {
+    /** The maximum time to wait for an operation. */
+    private static final long TIME_OUT_MS = 15000L;
+
     private static final String[] VALID_TV_INPUT_SERVICES = {
         StubTunerTvInputService.class.getName()
     };
@@ -40,7 +47,7 @@
 
     private String mStubId;
     private TvInputManager mManager;
-    private TvInputManager.TvInputCallback mCallabck = new TvInputManager.TvInputCallback() {};
+    private LoggingCallback mCallabck = new LoggingCallback();
 
     private static TvInputInfo getInfoForClassName(List<TvInputInfo> list, String name) {
         for (TvInputInfo info : list) {
@@ -62,7 +69,7 @@
         }
         mManager = (TvInputManager) getActivity().getSystemService(Context.TV_INPUT_SERVICE);
         mStubId = getInfoForClassName(
-                mManager.getTvInputList(), StubTunerTvInputService.class.getName()).getId();
+                mManager.getTvInputList(), StubTvInputService2.class.getName()).getId();
     }
 
     public void testGetInputState() throws Exception {
@@ -77,7 +84,7 @@
             return;
         }
         assertEquals(mManager.getTvInputInfo(mStubId), getInfoForClassName(
-                mManager.getTvInputList(), StubTunerTvInputService.class.getName()));
+                mManager.getTvInputList(), StubTvInputService2.class.getName()));
     }
 
     public void testGetTvInputList() throws Exception {
@@ -134,4 +141,90 @@
         });
         getInstrumentation().waitForIdleSync();
     }
+
+    public void testInputAddedAndRemoved() {
+        if (!Utils.hasTvInputFramework(getActivity())) {
+            return;
+        }
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mManager.registerCallback(mCallabck, new Handler());
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        // Test if onInputRemoved() is called.
+        mCallabck.resetLogs();
+        PackageManager pm = getActivity().getPackageManager();
+        ComponentName component = new ComponentName(getActivity(), StubTvInputService2.class);
+        assertTrue(PackageManager.COMPONENT_ENABLED_STATE_DISABLED != pm.getComponentEnabledSetting(
+                component));
+        pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+                PackageManager.DONT_KILL_APP);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mCallabck.isInputRemoved(mStubId);
+            }
+        }.run();
+
+        // Test if onInputAdded() is called.
+        mCallabck.resetLogs();
+        assertEquals(PackageManager.COMPONENT_ENABLED_STATE_DISABLED, pm.getComponentEnabledSetting(
+                component));
+        pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                PackageManager.DONT_KILL_APP);
+        new PollingCheck(TIME_OUT_MS) {
+            @Override
+            protected boolean check() {
+                return mCallabck.isInputAdded(mStubId);
+            }
+        }.run();
+
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mManager.unregisterCallback(mCallabck);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+    }
+
+    private static class LoggingCallback extends TvInputManager.TvInputCallback {
+        private final List<String> mAddedInputs = new ArrayList<>();
+        private final List<String> mRemovedInputs = new ArrayList<>();
+
+        @Override
+        public synchronized void onInputAdded(String inputId) {
+            mAddedInputs.add(inputId);
+        }
+
+        @Override
+        public synchronized void onInputRemoved(String inputId) {
+            mRemovedInputs.add(inputId);
+        }
+
+        public synchronized void resetLogs() {
+            mAddedInputs.clear();
+            mRemovedInputs.clear();
+        }
+
+        public synchronized boolean isInputAdded(String inputId) {
+            return mRemovedInputs.isEmpty() && mAddedInputs.size() == 1 && mAddedInputs.contains(
+                    inputId);
+        }
+
+        public synchronized boolean isInputRemoved(String inputId) {
+            return mAddedInputs.isEmpty() && mRemovedInputs.size() == 1 && mRemovedInputs.contains(
+                    inputId);
+        }
+    }
+
+    public static class StubTvInputService2 extends StubTvInputService {
+        @Override
+        public Session onCreateSession(String inputId) {
+            return null;
+        }
+    }
 }
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 7068035..b4c863a 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvInputServiceTest.java
@@ -20,6 +20,7 @@
 import android.app.Instrumentation;
 import android.content.Context;
 import android.cts.util.PollingCheck;
+import android.media.PlaybackParams;
 import android.media.tv.TvContentRating;
 import android.media.tv.TvContract;
 import android.media.tv.TvInputInfo;
@@ -34,7 +35,9 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.Surface;
+import android.view.SurfaceView;
 import android.view.View;
+import android.widget.LinearLayout;
 
 import com.android.cts.tv.R;
 
@@ -59,6 +62,8 @@
     private TvInputManager mManager;
     private TvInputInfo mStubInfo;
     private final StubCallback mCallback = new StubCallback();
+    private final StubTimeShiftPositionCallback mTimeShiftPositionCallback =
+            new StubTimeShiftPositionCallback();
 
     private static class StubCallback extends TvView.TvInputCallback {
         private int mChannelRetunedCount;
@@ -69,6 +74,7 @@
         private int mVideoSizeChanged;
         private int mContentAllowedCount;
         private int mContentBlockedCount;
+        private int mTimeShiftStatusChangedCount;
 
         @Override
         public void onChannelRetuned(String inputId, Uri channelUri) {
@@ -110,6 +116,11 @@
             mContentBlockedCount++;
         }
 
+        @Override
+        public void onTimeShiftStatusChanged(String inputId, int status) {
+            mTimeShiftStatusChangedCount++;
+        }
+
         public void resetCounts() {
             mChannelRetunedCount = 0;
             mVideoAvailableCount = 0;
@@ -118,6 +129,27 @@
             mTrackChangedCount = 0;
             mContentAllowedCount = 0;
             mContentBlockedCount = 0;
+            mTimeShiftStatusChangedCount = 0;
+        }
+    }
+
+    private static class StubTimeShiftPositionCallback extends TvView.TimeShiftPositionCallback {
+        private int mTimeShiftStartPositionChanged;
+        private int mTimeShiftCurrentPositionChanged;
+
+        @Override
+        public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
+            mTimeShiftStartPositionChanged++;
+        }
+
+        @Override
+        public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
+            mTimeShiftCurrentPositionChanged++;
+        }
+
+        public void resetCounts() {
+            mTimeShiftStartPositionChanged = 0;
+            mTimeShiftCurrentPositionChanged = 0;
         }
     }
 
@@ -161,6 +193,12 @@
         verifyCommandDispatchTouchEvent();
         verifyCommandDispatchTrackballEvent();
         verifyCommandDispatchGenericMotionEvent();
+        verifyCommandTimeShiftPause();
+        verifyCommandTimeShiftResume();
+        verifyCommandTimeShiftSeekTo();
+        verifyCommandTimeShiftSetPlaybackParams();
+        verifyCommandSetTimeShiftPositionCallback();
+        verifyCommandOverlayViewSizeChanged();
         verifyCallbackChannelRetuned();
         verifyCallbackVideoAvailable();
         verifyCallbackVideoUnavailable();
@@ -168,6 +206,8 @@
         verifyCallbackTrackSelected();
         verifyCallbackContentAllowed();
         verifyCallbackContentBlocked();
+        verifyCallbackTimeShiftStatusChanged();
+        verifyCallbackLayoutSurface();
 
         runTestOnUiThread(new Runnable() {
             @Override
@@ -320,6 +360,89 @@
         }.run();
     }
 
+    public void verifyCommandTimeShiftPause() {
+        resetCounts();
+        mTvView.timeShiftPause();
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mTimeShiftPauseCount > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCommandTimeShiftResume() {
+        resetCounts();
+        mTvView.timeShiftResume();
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mTimeShiftResumeCount > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCommandTimeShiftSeekTo() {
+        resetCounts();
+        mTvView.timeShiftSeekTo(0);
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mTimeShiftSeekToCount > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCommandTimeShiftSetPlaybackParams() {
+        resetCounts();
+        mTvView.timeShiftSetPlaybackParams(new PlaybackParams().setSpeed(2.0f)
+                .setAudioFallbackMode(PlaybackParams.AUDIO_FALLBACK_MODE_DEFAULT));
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mTimeShiftSetPlaybackParamsCount > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCommandSetTimeShiftPositionCallback() {
+        resetCounts();
+        mTvView.setTimeShiftPositionCallback(mTimeShiftPositionCallback);
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mTimeShiftPositionCallback.mTimeShiftCurrentPositionChanged > 0
+                        && mTimeShiftPositionCallback.mTimeShiftStartPositionChanged > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCommandOverlayViewSizeChanged() {
+        resetCounts();
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTvView.setLayoutParams(new LinearLayout.LayoutParams(10, 20));
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                CountingSession session = CountingTvInputService.sSession;
+                return session != null && session.mOverlayViewSizeChangedCount > 0;
+            }
+        }.run();
+    }
+
     public void verifyCallbackChannelRetuned() {
         resetCounts();
         CountingSession session = CountingTvInputService.sSession;
@@ -431,11 +554,50 @@
         }.run();
     }
 
+    public void verifyCallbackTimeShiftStatusChanged() {
+        resetCounts();
+        CountingSession session = CountingTvInputService.sSession;
+        assertNotNull(session);
+        session.notifyTimeShiftStatusChanged(TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mCallback.mTimeShiftStatusChangedCount > 0;
+            }
+        }.run();
+    }
+
+    public void verifyCallbackLayoutSurface() {
+        resetCounts();
+        final int left = 10;
+        final int top = 20;
+        final int right = 30;
+        final int bottom = 40;
+        CountingSession session = CountingTvInputService.sSession;
+        assertNotNull(session);
+        session.layoutSurface(left, top, right, bottom);
+        new PollingCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                int childCount = mTvView.getChildCount();
+                for (int i = 0; i < childCount; ++i) {
+                    View v = mTvView.getChildAt(i);
+                    if (v instanceof SurfaceView) {
+                        return v.getLeft() == left && v.getTop() == top && v.getRight() == right
+                                && v.getBottom() == bottom;
+                    }
+                }
+                return false;
+            }
+        }.run();
+    }
+
     private void resetCounts() {
         if (CountingTvInputService.sSession != null) {
             CountingTvInputService.sSession.resetCounts();
         }
         mCallback.resetCounts();
+        mTimeShiftPositionCallback.resetCounts();
     }
 
     public static class CountingTvInputService extends StubTvInputService {
@@ -461,6 +623,13 @@
             public volatile int mTouchEventCount;
             public volatile int mTrackballEventCount;
             public volatile int mGenricMotionEventCount;
+            public volatile int mOverlayViewSizeChangedCount;
+            public volatile int mTimeShiftPauseCount;
+            public volatile int mTimeShiftResumeCount;
+            public volatile int mTimeShiftSeekToCount;
+            public volatile int mTimeShiftSetPlaybackParamsCount;
+            public volatile long mTimeShiftGetCurrentPositionCount;
+            public volatile long mTimeShiftGetStartPositionCount;
 
             CountingSession(Context context) {
                 super(context);
@@ -479,6 +648,13 @@
                 mTouchEventCount = 0;
                 mTrackballEventCount = 0;
                 mGenricMotionEventCount = 0;
+                mOverlayViewSizeChangedCount = 0;
+                mTimeShiftPauseCount = 0;
+                mTimeShiftResumeCount = 0;
+                mTimeShiftSeekToCount = 0;
+                mTimeShiftSetPlaybackParamsCount = 0;
+                mTimeShiftGetCurrentPositionCount = 0;
+                mTimeShiftGetStartPositionCount = 0;
             }
 
             @Override
@@ -559,6 +735,41 @@
                 mGenricMotionEventCount++;
                 return false;
             }
+
+            @Override
+            public void onTimeShiftPause() {
+                mTimeShiftPauseCount++;
+            }
+
+            @Override
+            public void onTimeShiftResume() {
+                mTimeShiftResumeCount++;
+            }
+
+            @Override
+            public void onTimeShiftSeekTo(long timeMs) {
+                mTimeShiftSeekToCount++;
+            }
+
+            @Override
+            public void onTimeShiftSetPlaybackParams(PlaybackParams param) {
+                mTimeShiftSetPlaybackParamsCount++;
+            }
+
+            @Override
+            public long onTimeShiftGetCurrentPosition() {
+                return ++mTimeShiftGetCurrentPositionCount;
+            }
+
+            @Override
+            public long onTimeShiftGetStartPosition() {
+                return ++mTimeShiftGetStartPositionCount;
+            }
+
+            @Override
+            public void onOverlayViewSizeChanged(int width, int height) {
+                mOverlayViewSizeChangedCount++;
+            }
         }
     }
 }
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 6232861..1c59462 100644
--- a/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
+++ b/tests/tests/tv/src/android/media/tv/cts/TvViewTest.java
@@ -272,6 +272,8 @@
                 case TvTrackInfo.TYPE_VIDEO:
                     assertEquals(track.getVideoHeight(), selectedTrack.getVideoHeight());
                     assertEquals(track.getVideoWidth(), selectedTrack.getVideoWidth());
+                    assertEquals(track.getVideoPixelAspectRatio(),
+                            selectedTrack.getVideoPixelAspectRatio(), 0.001f);
                     break;
                 case TvTrackInfo.TYPE_AUDIO:
                     assertEquals(track.getAudioChannelCount(),
@@ -281,6 +283,7 @@
                     break;
                 case TvTrackInfo.TYPE_SUBTITLE:
                     assertEquals(track.getLanguage(), selectedTrack.getLanguage());
+                    assertEquals(track.getDescription(), selectedTrack.getDescription());
                     break;
                 default:
                     fail("Unrecognized type: " + track.getType());
@@ -295,7 +298,7 @@
         TvTrackInfo videoTrack1 = new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, "video-HD")
                 .setVideoHeight(1920).setVideoWidth(1080).build();
         TvTrackInfo videoTrack2 = new TvTrackInfo.Builder(TvTrackInfo.TYPE_VIDEO, "video-SD")
-                .setVideoHeight(640).setVideoWidth(360).build();
+                .setVideoHeight(640).setVideoWidth(360).setVideoPixelAspectRatio(1.09f).build();
         TvTrackInfo audioTrack1 =
                 new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, "audio-stereo-eng")
                 .setLanguage("eng").setAudioChannelCount(2).setAudioSampleRate(48000).build();
@@ -307,13 +310,16 @@
         TvTrackInfo subtitleTrack2 =
                 new TvTrackInfo.Builder(TvTrackInfo.TYPE_SUBTITLE, "subtitle-esp")
                 .setLanguage("esp").build();
+        TvTrackInfo subtitleTrack3 =
+                new TvTrackInfo.Builder(TvTrackInfo.TYPE_SUBTITLE, "subtitle-eng2")
+                .setLanguage("eng").setDescription("audio commentary").build();
 
         StubTunerTvInputService.injectTrack(videoTrack1, videoTrack2, audioTrack1, audioTrack2,
                 subtitleTrack1, subtitleTrack2);
 
         final List<TvTrackInfo> tracks = new ArrayList<TvTrackInfo>();
         Collections.addAll(tracks, videoTrack1, videoTrack2, audioTrack1, audioTrack2,
-                subtitleTrack1, subtitleTrack2);
+                subtitleTrack1, subtitleTrack2, subtitleTrack3);
         tryTuneAllChannels(new Runnable() {
             @Override
             public void run() {
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 3c6028f..2f3f48c8 100755
--- a/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
+++ b/tests/tests/uiautomation/src/android/app/uiautomation/cts/UiAutomationTest.java
@@ -165,6 +165,9 @@
             // Wait for things to settle.
             getUiDevice().waitForIdle();
 
+            // Wait for Activity draw finish
+            getInstrumentation().waitForIdleSync();
+
             // Clear the window animation stats to be with a clean slate.
             uiAutomation.clearWindowAnimationFrameStats();
 
@@ -177,6 +180,9 @@
             // Wait for things to settle.
             getUiDevice().waitForIdle();
 
+            // Wait for Activity draw finish
+            getInstrumentation().waitForIdleSync();
+
             // Get the frame stats.
             WindowAnimationFrameStats stats = uiAutomation.getWindowAnimationFrameStats();
 
@@ -245,14 +251,14 @@
         final int frameCount = stats.getFrameCount();
         for (int i = 0; i < frameCount; i++) {
             final long expectedTimeNano = stats.getFramePostedTimeNano(i);
-            assertTrue(expectedTimeNano > lastExpectedTimeNano);
+            assertTrue(expectedTimeNano >= lastExpectedTimeNano);
             lastExpectedTimeNano = expectedTimeNano;
 
             final long presentedTimeNano = stats.getFramePresentedTimeNano(i);
             if (lastPresentedTimeNano == FrameStats.UNDEFINED_TIME_NANO) {
                 assertTrue(presentedTimeNano == FrameStats.UNDEFINED_TIME_NANO);
             } else if (presentedTimeNano != FrameStats.UNDEFINED_TIME_NANO) {
-                assertTrue(presentedTimeNano > lastPresentedTimeNano);
+                assertTrue(presentedTimeNano >= lastPresentedTimeNano);
             }
             lastPresentedTimeNano = presentedTimeNano;
 
@@ -260,7 +266,7 @@
             if (lastPreparedTimeNano == FrameStats.UNDEFINED_TIME_NANO) {
                 assertTrue(preparedTimeNano == FrameStats.UNDEFINED_TIME_NANO);
             } else if (preparedTimeNano != FrameStats.UNDEFINED_TIME_NANO) {
-                assertTrue(preparedTimeNano > lastPreparedTimeNano);
+                assertTrue(preparedTimeNano >= lastPreparedTimeNano);
             }
             lastPreparedTimeNano = preparedTimeNano;
         }
diff --git a/tests/tests/uidisolation/Android.mk b/tests/tests/uidisolation/Android.mk
index 8529407..c21b6df 100644
--- a/tests/tests/uidisolation/Android.mk
+++ b/tests/tests/uidisolation/Android.mk
@@ -23,6 +23,8 @@
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctstestrunner ctstestserver
 
+LOCAL_JAVA_LIBRARIES := org.apache.http.legacy
+
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := CtsUidIsolationTestCases
diff --git a/tests/tests/uidisolation/AndroidManifest.xml b/tests/tests/uidisolation/AndroidManifest.xml
index a8c6848..86efb6f 100644
--- a/tests/tests/uidisolation/AndroidManifest.xml
+++ b/tests/tests/uidisolation/AndroidManifest.xml
@@ -18,6 +18,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.cts.uidisolation">
 
+    <uses-library android:name="org.apache.http.legacy" android:required="false" />
+
     <application android:label="UidIsolationTest">
       <activity android:name="android.uidisolation.cts.ServiceRunnerActivity"
                 android:label="UidIsolationTest"/>
diff --git a/tests/tests/uirendering/AndroidManifest.xml b/tests/tests/uirendering/AndroidManifest.xml
index 413dfba..b8d84a6 100644
--- a/tests/tests/uirendering/AndroidManifest.xml
+++ b/tests/tests/uirendering/AndroidManifest.xml
@@ -26,7 +26,7 @@
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
                      android:targetPackage="com.android.cts.uirendering">
     </instrumentation>
 
diff --git a/tests/tests/uirendering/res/drawable-nodpi/black1.png b/tests/tests/uirendering/res/drawable-nodpi/black1.png
index 3487ced..bbfc2c1 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 8fd3b50..6a8a830 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 199cccc..cd0465b 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 985635e..0819c8a 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 6889a3a..16f03e2 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 9554dee..98174f0 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 0483355..8b017ba 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 6584147..5fc1f9c 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 49d01ac..1aca9cf 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 6fe4a76..47ecd67 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 7a4be5a..6c9cb58 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 a5f9ef2..0afb3ae 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 dfa59da..6822edb 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 283ddc4..b49d2d6 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 e615186..5b187bc 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 3e15fc8..057edc0 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 9637262..a780f16 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 0afbb9a..6ddb52b 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/res/layout/circle_clipped_webview.xml b/tests/tests/uirendering/res/layout/circle_clipped_webview.xml
new file mode 100644
index 0000000..44b65be
--- /dev/null
+++ b/tests/tests/uirendering/res/layout/circle_clipped_webview.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.
+  -->
+<android.uirendering.cts.testclasses.view.CircleClipFrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="@dimen/test_width"
+    android:layout_height="@dimen/test_height">
+    <WebView
+        android:id="@+id/webview"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"/>
+</android.uirendering.cts.testclasses.view.CircleClipFrameLayout>
diff --git a/tests/tests/uirendering/res/layout/simple_red_layout.xml b/tests/tests/uirendering/res/layout/simple_red_layout.xml
index 2af8db6..1c551d3 100644
--- a/tests/tests/uirendering/res/layout/simple_red_layout.xml
+++ b/tests/tests/uirendering/res/layout/simple_red_layout.xml
@@ -16,5 +16,4 @@
 <View xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/test_width"
     android:layout_height="@dimen/test_height"
-    android:id="@+id/test_root"
-    android:background="#f00" />
+    android:background="#f00"/>
diff --git a/tests/tests/uirendering/res/layout/test_container.xml b/tests/tests/uirendering/res/layout/test_container.xml
index 94a8eab..deff9de 100644
--- a/tests/tests/uirendering/res/layout/test_container.xml
+++ b/tests/tests/uirendering/res/layout/test_container.xml
@@ -13,12 +13,16 @@
        limitations under the License.
   -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/test_container"
     android:layout_width="match_parent"
     android:layout_height="match_parent">
-    <ViewStub
-        android:id="@+id/test_content_stub"
+    <FrameLayout
         android:layout_gravity="center"
+        android:id="@+id/test_content_wrapper"
         android:layout_width="@dimen/test_width"
-        android:layout_height="@dimen/test_height"/>
+        android:layout_height="@dimen/test_height">
+        <ViewStub
+            android:id="@+id/test_content_stub"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"/>
+    </FrameLayout>
 </FrameLayout>
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/ColorVerifier.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/ColorVerifier.java
index 7f62b3e..aa91c2e 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/ColorVerifier.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/ColorVerifier.java
@@ -15,27 +15,31 @@
  */
 package android.uirendering.cts.bitmapverifiers;
 
+import android.annotation.ColorInt;
+
 /**
  * Checks to see if a bitmap is entirely a single color
  */
 public class ColorVerifier extends PerPixelBitmapVerifier {
+    @ColorInt
     private int mColor;
 
-    public ColorVerifier(int color) {
+    public ColorVerifier(@ColorInt int color) {
         this(color, DEFAULT_THRESHOLD);
     }
 
-    public ColorVerifier(int color, int colorTolerance) {
+    public ColorVerifier(@ColorInt int color, int colorTolerance) {
         super(colorTolerance);
         mColor = color;
     }
 
-    public ColorVerifier(int color, int colorThreshold, float spatialTolerance) {
+    public ColorVerifier(@ColorInt int color, int colorThreshold, float spatialTolerance) {
         super(colorThreshold, spatialTolerance);
         mColor = color;
     }
 
     @Override
+    @ColorInt
     protected int getExpectedColor(int x, int y) {
         return mColor;
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/GoldenImageVerifier.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/GoldenImageVerifier.java
index d4a63de..42e8960 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/GoldenImageVerifier.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/GoldenImageVerifier.java
@@ -25,8 +25,8 @@
     private int[] mGoldenBitmapArray;
 
     public GoldenImageVerifier(Bitmap goldenBitmap, BitmapComparer bitmapComparer) {
-        mGoldenBitmapArray = new int[goldenBitmap.getWidth() * goldenBitmap.getHeight()];
-        goldenBitmap.getPixels(mGoldenBitmapArray, 0, goldenBitmap.getWidth(), 0, 0,
+        mGoldenBitmapArray = new int[ActivityTestBase.TEST_WIDTH * ActivityTestBase.TEST_HEIGHT];
+        goldenBitmap.getPixels(mGoldenBitmapArray, 0, ActivityTestBase.TEST_WIDTH, 0, 0,
                 ActivityTestBase.TEST_WIDTH, ActivityTestBase.TEST_HEIGHT);
         mBitmapComparer = bitmapComparer;
     }
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/PerPixelBitmapVerifier.java b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/PerPixelBitmapVerifier.java
index 2d00db5..8fe75ee 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/PerPixelBitmapVerifier.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/bitmapverifiers/PerPixelBitmapVerifier.java
@@ -15,6 +15,7 @@
  */
 package android.uirendering.cts.bitmapverifiers;
 
+import android.annotation.ColorInt;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.uirendering.cts.testinfrastructure.ActivityTestBase;
@@ -47,6 +48,7 @@
         mSpatialTolerance = spatialTolerance;
     }
 
+    @ColorInt
     protected int getExpectedColor(int x, int y) {
         return Color.WHITE;
     }
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 1d5cd16..b324b06 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/BitmapFilterTests.java
@@ -120,6 +120,7 @@
                     canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0));
                 }
                 canvas.drawBitmap(scaleUp ? mSmallGridBitmap : mBigGridBitmap, 0, 0, paint);
+                canvas.setDrawFilter(null);
             }
         };
         createTest()
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
new file mode 100644
index 0000000..becc2f7
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/CanvasStateTests.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Canvas;
+import android.graphics.Path;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.uirendering.cts.testinfrastructure.ActivityTestBase;
+import android.uirendering.cts.testinfrastructure.CanvasClient;
+
+/**
+ * Tests of state query-able from canvas at draw time.
+ *
+ * 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.
+ */
+public class CanvasStateTests extends ActivityTestBase {
+
+    @SmallTest
+    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);
+
+                        isNonEmpty = canvas.clipRect(0, 40, 20, 60);
+                        assertFalse("clip state should be empty", isNonEmpty);
+                        canvas.restore();
+                    }
+                })
+                .runWithoutVerification();
+    }
+
+    @SmallTest
+    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);
+
+                        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
+    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);
+
+                        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();
+                    }
+                })
+                .runWithoutVerification();
+    }
+    @SmallTest
+    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);
+
+                        // 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();
+                    }
+                })
+                .runWithoutVerification();
+    }
+}
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 e7ed7ac..5833f20 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/FontRenderingTests.java
@@ -32,17 +32,24 @@
 import com.android.cts.uirendering.R;
 
 public class FontRenderingTests extends ActivityTestBase {
-    // Threshold is barely loose enough for differences between sw and hw renderers
-    static double MSSIM_THRESHOLD = 0.91;
-
-    private final BitmapComparer mFuzzyComparer = new MSSIMComparer(MSSIM_THRESHOLD);
+    // Thresholds are barely loose enough for differences between sw and hw renderers.
+    private static final double REGULAR_THRESHOLD = 0.92;
+    private static final double THIN_THRESHOLD = 0.87;
 
     // Representative characters including some from Unicode 7
-    private final String mTestString1 = "Hamburg \u20bd";
-    private final String mTestString2 = "\u20b9\u0186\u0254\u1e24\u1e43";
+    private static final String sTestString1 = "Hambu";
+    private static final String sTestString2 = "rg \u20bd";
+    private static final String sTestString3 = "\u20b9\u0186\u0254\u1e24\u1e43";
 
-    private void fontTestBody(final Typeface typeface, int id) {
+    private void fontTestBody(String family, int style, int id) {
         Bitmap goldenBitmap = BitmapFactory.decodeResource(getActivity().getResources(), id);
+
+        // adjust threshold based on thinness - more variance is expected in thin cases
+        boolean thinTestCase = family.endsWith("-thin") && ((style & Typeface.BOLD) == 0);
+        BitmapComparer comparer = new MSSIMComparer(
+                thinTestCase ? THIN_THRESHOLD : REGULAR_THRESHOLD);
+
+        final Typeface typeface = Typeface.create(family, style);
         createTest()
                 .addCanvasClient(new CanvasClient() {
                     @Override
@@ -50,174 +57,201 @@
                         Paint p = new Paint();
                         p.setAntiAlias(true);
                         p.setColor(Color.BLACK);
-                        p.setTextSize(30);
+                        p.setTextSize(26);
                         p.setTypeface(typeface);
-                        canvas.drawText(mTestString1, 10, 60, p);
-                        canvas.drawText(mTestString2, 10, 100, p);
+                        canvas.drawText(sTestString1, 1, 20, p);
+                        canvas.drawText(sTestString2, 1, 50, p);
+                        canvas.drawText(sTestString3, 1, 80, p);
                     }
                 })
-                .runWithVerifier(new GoldenImageVerifier(goldenBitmap, mFuzzyComparer));
+                .runWithVerifier(new GoldenImageVerifier(goldenBitmap, comparer));
     }
 
     @SmallTest
     public void testDefaultFont() {
-        Typeface tf = Typeface.create("sans-serif", Typeface.NORMAL);
-        fontTestBody(tf, R.drawable.hello1);
+        fontTestBody("sans-serif",
+                Typeface.NORMAL,
+                R.drawable.hello1);
     }
 
     @SmallTest
     public void testBoldFont() {
-        Typeface tf = Typeface.create("sans-serif", Typeface.BOLD);
-        fontTestBody(tf, R.drawable.bold1);
+        fontTestBody("sans-serif",
+                Typeface.BOLD,
+                R.drawable.bold1);
     }
 
     @SmallTest
     public void testItalicFont() {
-        Typeface tf = Typeface.create("sans-serif", Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.italic1);
+        fontTestBody("sans-serif",
+                Typeface.ITALIC,
+                R.drawable.italic1);
     }
 
     @SmallTest
     public void testBoldItalicFont() {
-        Typeface tf = Typeface.create("sans-serif", Typeface.BOLD | Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.bolditalic1);
+        fontTestBody("sans-serif",
+                Typeface.BOLD | Typeface.ITALIC,
+                R.drawable.bolditalic1);
     }
 
     @SmallTest
     public void testMediumFont() {
-        Typeface tf = Typeface.create("sans-serif-medium", Typeface.NORMAL);
-        fontTestBody(tf, R.drawable.medium1);
+        fontTestBody("sans-serif-medium",
+                Typeface.NORMAL,
+                R.drawable.medium1);
     }
 
     @SmallTest
     public void testMediumBoldFont() {
         // bold attribute on medium base font = black
-        Typeface tf = Typeface.create("sans-serif-medium", Typeface.BOLD);
-        fontTestBody(tf, R.drawable.black1);
+        fontTestBody("sans-serif-medium",
+                Typeface.BOLD,
+                R.drawable.black1);
     }
 
     @SmallTest
     public void testMediumItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-medium", Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.mediumitalic1);
+        fontTestBody("sans-serif-medium",
+                Typeface.ITALIC,
+                R.drawable.mediumitalic1);
     }
 
     @SmallTest
     public void testMediumBoldItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-medium", Typeface.BOLD | Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.blackitalic1);
+        fontTestBody("sans-serif-medium",
+                Typeface.BOLD | Typeface.ITALIC,
+                R.drawable.blackitalic1);
     }
 
     @SmallTest
     public void testLightFont() {
-        Typeface tf = Typeface.create("sans-serif-light", Typeface.NORMAL);
-        fontTestBody(tf, R.drawable.light1);
+        fontTestBody("sans-serif-light",
+                Typeface.NORMAL,
+                R.drawable.light1);
     }
 
     @SmallTest
     public void testLightBoldFont() {
         // bold attribute on light base font = medium
-        Typeface tf = Typeface.create("sans-serif-light", Typeface.BOLD);
-        fontTestBody(tf, R.drawable.medium1);
+        fontTestBody("sans-serif-light",
+                Typeface.BOLD,
+                R.drawable.medium1);
     }
 
     @SmallTest
     public void testLightItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-light", Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.lightitalic1);
+        fontTestBody("sans-serif-light",
+                Typeface.ITALIC,
+                R.drawable.lightitalic1);
     }
 
     @SmallTest
     public void testLightBoldItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-light", Typeface.BOLD | Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.mediumitalic1);
+        fontTestBody("sans-serif-light",
+                Typeface.BOLD | Typeface.ITALIC,
+                R.drawable.mediumitalic1);
     }
 
     @SmallTest
     public void testThinFont() {
-        Typeface tf = Typeface.create("sans-serif-thin", Typeface.NORMAL);
-        fontTestBody(tf, R.drawable.thin1);
+        fontTestBody("sans-serif-thin",
+                Typeface.NORMAL,
+                R.drawable.thin1);
     }
 
     @SmallTest
     public void testThinBoldFont() {
         // bold attribute on thin base font = normal
-        Typeface tf = Typeface.create("sans-serif-thin", Typeface.BOLD);
-        fontTestBody(tf, R.drawable.hello1);
+        fontTestBody("sans-serif-thin",
+                Typeface.BOLD,
+                R.drawable.hello1);
     }
 
     @SmallTest
     public void testThinItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-thin", Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.thinitalic1);
+        fontTestBody("sans-serif-thin",
+                Typeface.ITALIC,
+                R.drawable.thinitalic1);
     }
 
     @SmallTest
     public void testThinBoldItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-thin", Typeface.BOLD | Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.italic1);
+        fontTestBody("sans-serif-thin",
+                Typeface.BOLD | Typeface.ITALIC,
+                R.drawable.italic1);
     }
 
     @SmallTest
     public void testBlackFont() {
-        Typeface tf = Typeface.create("sans-serif-black", Typeface.NORMAL);
-        fontTestBody(tf, R.drawable.black1);
+        fontTestBody("sans-serif-black",
+                Typeface.NORMAL,
+                R.drawable.black1);
     }
 
     @SmallTest
     public void testBlackBoldFont() {
         // bold attribute on black base font = black
-        Typeface tf = Typeface.create("sans-serif-black", Typeface.BOLD);
-        fontTestBody(tf, R.drawable.black1);
+        fontTestBody("sans-serif-black",
+                Typeface.BOLD,
+                R.drawable.black1);
     }
 
     @SmallTest
     public void testBlackItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-black", Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.blackitalic1);
+        fontTestBody("sans-serif-black",
+                Typeface.ITALIC,
+                R.drawable.blackitalic1);
     }
 
     @SmallTest
     public void testBlackBoldItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-black", Typeface.BOLD | Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.blackitalic1);
+        fontTestBody("sans-serif-black",
+                Typeface.BOLD | Typeface.ITALIC,
+                R.drawable.blackitalic1);
     }
 
     /* condensed fonts */
 
     @SmallTest
     public void testCondensedFont() {
-        Typeface tf = Typeface.create("sans-serif-condensed", Typeface.NORMAL);
-        fontTestBody(tf, R.drawable.condensed1);
+        fontTestBody("sans-serif-condensed",
+                Typeface.NORMAL,
+                R.drawable.condensed1);
     }
 
     @SmallTest
     public void testCondensedBoldFont() {
-        Typeface tf = Typeface.create("sans-serif-condensed", Typeface.BOLD);
-        fontTestBody(tf, R.drawable.condensedbold1);
+        fontTestBody("sans-serif-condensed",
+                Typeface.BOLD,
+                R.drawable.condensedbold1);
     }
 
     @SmallTest
     public void testCondensedItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-condensed", Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.condenseditalic1);
+        fontTestBody("sans-serif-condensed",
+                Typeface.ITALIC,
+                R.drawable.condenseditalic1);
     }
 
     @SmallTest
     public void testCondensedBoldItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-condensed", Typeface.BOLD | Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.condensedbolditalic1);
+        fontTestBody("sans-serif-condensed",
+                Typeface.BOLD | Typeface.ITALIC,
+                R.drawable.condensedbolditalic1);
     }
 
     @SmallTest
     public void testCondensedLightFont() {
-        Typeface tf = Typeface.create("sans-serif-condensed-light", Typeface.NORMAL);
-        fontTestBody(tf, R.drawable.condensedlight1);
+        fontTestBody("sans-serif-condensed-light",
+                Typeface.NORMAL,
+                R.drawable.condensedlight1);
     }
 
     @SmallTest
     public void testCondensedLightItalicFont() {
-        Typeface tf = Typeface.create("sans-serif-condensed-light", Typeface.ITALIC);
-        fontTestBody(tf, R.drawable.condensedlightitalic1);
+        fontTestBody("sans-serif-condensed-light",
+                Typeface.ITALIC,
+                R.drawable.condensedlightitalic1);
     }
 }
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 c86ff76..dfaaaea 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/InfrastructureTests.java
@@ -75,7 +75,7 @@
         final Rect clipRect = new Rect(0, 0, 50, 50);
         ViewInitializer viewInitializer = new ViewInitializer() {
             @Override
-            public void intializeView(View view) {
+            public void initializeView(View view) {
                 view.setClipBounds(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
new file mode 100644
index 0000000..a5f76dd
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/LayerTests.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 android.uirendering.cts.testclasses;
+
+import android.annotation.ColorInt;
+import android.graphics.Color;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.test.suitebuilder.annotation.SmallTest;
+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;
+
+public class LayerTests extends ActivityTestBase {
+    @SmallTest
+    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);
+
+                        // reduce alpha by another 50% (ensuring two alphas combine correctly)
+                        view.setAlpha(0.5f);
+                    }
+                })
+                .runWithVerifier(new ColorVerifier(expectedColor));
+    }
+
+    @SmallTest
+    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);
+                    }
+                })
+                .runWithVerifier(new ColorVerifier(expectedColor));
+    }
+
+    @SmallTest
+    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);
+                    }
+                })
+                .runWithVerifier(new ColorVerifier(expectedColor));
+    }
+}
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 6911cf0..38777a2 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PathClippingTests.java
@@ -1,5 +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.uirendering.cts.testclasses;
 
+import android.content.pm.PackageManager;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -14,14 +31,15 @@
 import android.uirendering.cts.testinfrastructure.ViewInitializer;
 import android.view.View;
 import android.view.ViewGroup;
+import android.webkit.WebView;
 import com.android.cts.uirendering.R;
 
 public class PathClippingTests extends ActivityTestBase {
     // draw circle with hole in it, with stroked circle
-    static final CanvasClient sCircleDrawCanvasClient = new CanvasClient() {
+    static final CanvasClient sTorusDrawCanvasClient = new CanvasClient() {
         @Override
         public String getDebugString() {
-            return "StrokedCircleDraw";
+            return "TorusDraw";
         }
 
         @Override
@@ -36,10 +54,10 @@
     };
 
     // draw circle with hole in it, by path operations + path clipping
-    static final CanvasClient sCircleClipCanvasClient = new CanvasClient() {
+    static final CanvasClient sTorusClipCanvasClient = new CanvasClient() {
         @Override
         public String getDebugString() {
-            return "CircleClipDraw";
+            return "TorusClipDraw";
         }
 
         @Override
@@ -60,15 +78,15 @@
     @SmallTest
     public void testCircleWithCircle() {
         createTest()
-                .addCanvasClient(sCircleDrawCanvasClient, false)
-                .addCanvasClient(sCircleClipCanvasClient)
+                .addCanvasClient(sTorusDrawCanvasClient, false)
+                .addCanvasClient(sTorusClipCanvasClient)
                 .runWithComparer(new MSSIMComparer(0.90));
     }
 
     @SmallTest
     public void testCircleWithPoints() {
         createTest()
-                .addCanvasClient(sCircleClipCanvasClient)
+                .addCanvasClient(sTorusClipCanvasClient)
                 .runWithVerifier(new SamplePointVerifier(
                         new Point[] {
                                 // inside of circle
@@ -92,7 +110,7 @@
         createTest()
                 .addLayout(R.layout.blue_padded_layout, new ViewInitializer() {
                     @Override
-                    public void intializeView(View view) {
+                    public void initializeView(View view) {
                         ViewGroup rootView = (ViewGroup) view;
                         rootView.setClipChildren(true);
                         View childView = rootView.getChildAt(0);
@@ -143,4 +161,32 @@
                 })
                 .runWithComparer(new MSSIMComparer(0.90));
     }
+
+    @SmallTest
+    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);
+                    }
+                }, 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);
+                    }
+                })
+                .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
new file mode 100644
index 0000000..6619b11
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/PictureTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Picture;
+import android.graphics.Rect;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.uirendering.cts.bitmapverifiers.ColorVerifier;
+import android.uirendering.cts.bitmapverifiers.RectVerifier;
+import android.uirendering.cts.testinfrastructure.ActivityTestBase;
+import android.uirendering.cts.testinfrastructure.CanvasClient;
+
+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() {
+        Paint pt = new Paint();
+        pt.setColor(Color.GREEN);
+        Picture pic = new Picture();
+        Canvas subcanvas = pic.beginRecording(ActivityTestBase.TEST_WIDTH,
+                                              ActivityTestBase.TEST_HEIGHT);
+        subcanvas.drawRect(sRect, pt);
+        pic.endRecording();
+
+        return pic;
+    }
+
+    public void testPictureRespectsClip() throws Exception {
+        createTest()
+            .addCanvasClient(
+                new CanvasClient() {
+                    @Override
+                    public void draw(Canvas canvas, int width, int height) {
+                        Picture pic = greenSquare();
+                        canvas.clipRect(sOffsetRect);
+                        pic.draw(canvas);  // should be clipped out
+                    }
+                }
+            ).runWithVerifier(new ColorVerifier(Color.WHITE));
+    }
+
+    public void testPictureRespectsTranslate() throws Exception {
+        createTest()
+            .addCanvasClient(
+                new CanvasClient() {
+                    @Override
+                    public void draw(Canvas canvas, int width, int 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
new file mode 100644
index 0000000..85764a6
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ShaderTests.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.uirendering.cts.testclasses;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ComposeShader;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.RadialGradient;
+import android.graphics.Shader;
+import android.test.suitebuilder.annotation.SmallTest;
+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;
+
+public class ShaderTests extends ActivityTestBase {
+    @SmallTest
+    public void testSinglePixelBitmapShader() {
+        createTest()
+                .addCanvasClient(new CanvasClient() {
+                    Paint mPaint = new Paint();
+                    @Override
+                    public void draw(Canvas canvas, int width, int height) {
+                        if (mPaint.getShader() == null) {
+                            Bitmap shaderBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+                            shaderBitmap.eraseColor(Color.BLUE);
+                            mPaint.setShader(new BitmapShader(shaderBitmap,
+                                    Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));
+                        }
+                        canvas.drawRect(0, 0, width, height, mPaint);
+                    }
+                })
+                .runWithVerifier(new ColorVerifier(Color.BLUE));
+    }
+
+    @SmallTest
+    public void testSinglePixelComposeShader() {
+        createTest()
+                .addCanvasClient(new CanvasClient() {
+                    Paint mPaint = new Paint();
+
+                    @Override
+                    public void draw(Canvas canvas, int width, int height) {
+                        if (mPaint.getShader() == null) {
+                            // BLUE as SRC for Compose
+                            Bitmap shaderBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+                            shaderBitmap.eraseColor(Color.BLUE);
+                            BitmapShader bitmapShader = new BitmapShader(shaderBitmap,
+                                    Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
+
+                            // Fully opaque gradient mask (via DST_IN).
+                            // In color array, only alpha channel will matter.
+                            RadialGradient gradientShader = new RadialGradient(
+                                    10, 10, 10,
+                                    new int[] { Color.RED, Color.GREEN, Color.BLUE }, null,
+                                    Shader.TileMode.CLAMP);
+
+                            mPaint.setShader(new ComposeShader(
+                                    bitmapShader, gradientShader, PorterDuff.Mode.DST_IN));
+                        }
+                        canvas.drawRect(0, 0, width, height, mPaint);
+                    }
+                })
+                .runWithVerifier(new ColorVerifier(Color.BLUE));
+    }
+
+    @SmallTest
+    public void testComplexShaderUsage() {
+        /*
+         * This test not only builds a very complex drawing operation, but also tests an
+         * implementation detail of HWUI, using the largest number of texture sample sources
+         * possible - 4.
+         *
+         * 1) Bitmap passed to canvas.drawBitmap
+         * 2) gradient color lookup
+         * 3) gradient dither lookup
+         * 4) Bitmap in BitmapShader
+          */
+        createTest()
+                .addCanvasClient(new CanvasClient() {
+                    Paint mPaint = new Paint();
+                    Bitmap mBitmap;
+
+                    @Override
+                    public void draw(Canvas canvas, int width, int height) {
+                        if (mBitmap == null) {
+                            mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
+                            // Primary content mask
+                            Canvas bitmapCanvas = new Canvas(mBitmap);
+                            final float radius = width / 2.0f;
+                            bitmapCanvas.drawCircle(width / 2, height / 2, radius, mPaint);
+
+                            // Bitmap shader mask, partially overlapping content
+                            Bitmap shaderBitmap = Bitmap.createBitmap(
+                                    width, height, Bitmap.Config.ALPHA_8);
+                            bitmapCanvas = new Canvas(shaderBitmap);
+                            bitmapCanvas.drawCircle(width / 2, 0, radius, mPaint);
+                            bitmapCanvas.drawCircle(width / 2, height, radius, mPaint);
+                            BitmapShader bitmapShader = new BitmapShader(shaderBitmap,
+                                    Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
+
+                            // Gradient fill
+                            RadialGradient gradientShader = new RadialGradient(
+                                    width / 2, height / 2, radius,
+                                    new int[] { Color.RED, Color.BLUE, Color.GREEN },
+                                    null, Shader.TileMode.CLAMP);
+
+                            mPaint.setShader(new ComposeShader(gradientShader, bitmapShader,
+                                    PorterDuff.Mode.DST_IN));
+                        }
+                        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
+                    }
+                })
+                // expect extremely similar rendering results between SW and HW, since there's no AA
+                .runWithComparer(new MSSIMComparer(0.98f));
+    }
+}
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 32ab0e4..71b4f3f 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/SweepTests.java
@@ -345,17 +345,6 @@
                 null, bitmapVerifiers);
     }
 
-    /*
-    @SmallTest
-    public void testShaderSweeps() {
-        int mask = DisplayModifier.Accessor.AA_MASK
-                | DisplayModifier.Accessor.SHADER_MASK
-                | DisplayModifier.Accessor.XFERMODE_MASK
-                | DisplayModifier.Accessor.SHAPES_MASK;
-        sweepModifiersForMask(mask, null, DEFAULT_MSSIM_COMPARER, null);
-    }
-    */
-
     protected void sweepModifiersForMask(int mask, final DisplayModifier drawOp,
             BitmapComparer[] bitmapComparers, BitmapVerifier[] bitmapVerifiers) {
         if ((mask & DisplayModifier.Accessor.ALL_OPTIONS_MASK) == 0) {
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 343228f..f1f7c99 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/ViewClippingTests.java
@@ -28,13 +28,13 @@
 
     final ViewInitializer BOUNDS_CLIP_INIT = new ViewInitializer() {
         @Override
-        public void intializeView(View rootView) {
+        public void initializeView(View rootView) {
             ((ViewGroup)rootView).setClipChildren(true);
         }
     };
     final ViewInitializer PADDING_CLIP_INIT = new ViewInitializer() {
         @Override
-        public void intializeView(View rootView) {
+        public void initializeView(View rootView) {
             ViewGroup child = (ViewGroup) rootView.findViewById(R.id.child);
             child.setClipToPadding(true);
             child.setWillNotDraw(true);
@@ -43,7 +43,7 @@
     };
     final ViewInitializer OUTLINE_CLIP_INIT = new ViewInitializer() {
         @Override
-        public void intializeView(View rootView) {
+        public void initializeView(View rootView) {
             View child = rootView.findViewById(R.id.child);
             child.setOutlineProvider(new ViewOutlineProvider() {
                 @Override
@@ -56,7 +56,7 @@
     };
     final ViewInitializer CLIP_BOUNDS_CLIP_INIT = new ViewInitializer() {
         @Override
-        public void intializeView(View view) {
+        public void initializeView(View view) {
             view.setClipBounds(CLIP_BOUNDS_RECT);
         }
     };
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/CircleClipFrameLayout.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/CircleClipFrameLayout.java
new file mode 100644
index 0000000..4329c60
--- /dev/null
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/CircleClipFrameLayout.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.view;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Path;
+import android.util.AttributeSet;
+import android.widget.FrameLayout;
+
+public class CircleClipFrameLayout extends FrameLayout {
+    final Path mClipPath = new Path();
+    public CircleClipFrameLayout(Context context) {
+        this(context, null);
+    }
+
+    public CircleClipFrameLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public CircleClipFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public CircleClipFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        canvas.save();
+
+        mClipPath.reset();
+        mClipPath.addOval(0, 0, getWidth(), getHeight(), Path.Direction.CW);
+        canvas.clipPath(mClipPath);
+        super.dispatchDraw(canvas);
+
+        canvas.restore();
+    }
+}
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/UnclippedBlueView.java b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/UnclippedBlueView.java
index b8935fb..900e14d 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/UnclippedBlueView.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testclasses/view/UnclippedBlueView.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.view;
 
 import android.content.Context;
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 2a21b6b..526f4f9 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ActivityTestBase.java
@@ -28,7 +28,8 @@
 import android.uirendering.cts.util.BitmapDumper;
 import android.util.Log;
 
-import java.util.concurrent.Semaphore;
+import android.support.test.InstrumentationRegistry;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -79,6 +80,10 @@
      */
     @Override
     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());
@@ -90,7 +95,6 @@
      */
     @Override
     public void tearDown() {
-        final Semaphore available = new Semaphore(0, true);
         if (mTestCaseBuilder != null) {
             List<TestCase> testCases = mTestCaseBuilder.getTestCases();
 
@@ -113,17 +117,10 @@
             @Override
             public void run() {
                 getActivity().finish();
-                available.release();
             }
         };
 
         getActivity().runOnUiThread(finishRunnable);
-        // Make sure to start case only after the previous one finished
-        try {
-            available.acquire();
-        } catch (InterruptedException exception) {
-            exception.printStackTrace();
-        }
     }
 
     static int[] getBitmapPixels(Bitmap bitmap) {
@@ -266,6 +263,20 @@
             }
         }
 
+        /**
+         * Runs a test where each testcase is run without verification. Should only be used
+         * where custom CanvasClients, Views, or ViewInitializers do their own internal
+         * test assertions.
+         */
+        public void runWithoutVerification() {
+            runWithVerifier(new BitmapVerifier() {
+                @Override
+                public boolean verify(int[] bitmap, int offset, int stride, int width, int height) {
+                    return true;
+                }
+            });
+        }
+
         public TestCaseBuilder addWebView(String webViewUrl,
                 @Nullable ViewInitializer viewInitializer) {
             return addWebView(webViewUrl, viewInitializer, false)
diff --git a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DisplayModifier.java b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DisplayModifier.java
index b42ac88..99a9ef6 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DisplayModifier.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DisplayModifier.java
@@ -519,14 +519,17 @@
             for (Map.Entry<String, LinkedHashMap<String, DisplayModifier>> entry :
                     mDisplayMap.entrySet()) {
                 int displayModifierIndex = mIndices[mapIndex];
-                mDebugString += "Modification : " + entry.getKey();
+                if (!mDebugString.isEmpty()) {
+                    mDebugString += ", ";
+                }
+                mDebugString += entry.getKey();
                 // Loop until we find the modification we are going to use
                 for (Map.Entry<String, DisplayModifier> modifierEntry :
                         entry.getValue().entrySet()) {
                     // Once we find the modification we want, then we will add it to the list,
                     // and the last applied modifications
                     if (displayModifierIndex == 0) {
-                        mDebugString += " value : " + modifierEntry.getKey() + " ";
+                        mDebugString += ": " + modifierEntry.getKey();
                         modifierArrayList.add(modifierEntry.getValue());
                         break;
                     }
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 ce4a3be..57c67bd 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/DrawActivity.java
@@ -39,6 +39,7 @@
 
     private Handler mHandler;
     private View mView;
+    private View mViewWrapper;
     private boolean mOnTv;
 
     public void onCreate(Bundle bundle){
@@ -93,6 +94,7 @@
             int drawCountDelay = 0;
             setContentView(R.layout.test_container);
             ViewStub stub = (ViewStub) findViewById(R.id.test_content_stub);
+            mViewWrapper = findViewById(R.id.test_content_wrapper);
             switch (message.what) {
                 case LAYOUT_MSG: {
                     stub.setLayoutResource(message.arg1);
@@ -119,9 +121,12 @@
             }
 
             if (mViewInitializer != null) {
-                mViewInitializer.intializeView(mView);
+                mViewInitializer.initializeView(mView);
             }
-            mView.setLayerType(message.arg2, null);
+
+            // set layer on wrapper parent of view, so view initializer
+            // can control layer type of View under test.
+            mViewWrapper.setLayerType(message.arg2, null);
 
             DrawCounterListener onDrawListener = new DrawCounterListener(drawCountDelay);
 
@@ -147,7 +152,7 @@
                 mView.postInvalidate();
             } else {
                 synchronized (mLock) {
-                    mLock.set(mView.getLeft(), mView.getTop());
+                    mLock.set(mViewWrapper.getLeft(), mViewWrapper.getTop());
                     mLock.notify();
                 }
                 mView.getViewTreeObserver().removeOnPreDrawListener(this);
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 8980df3..9a3cbb1 100644
--- a/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java
+++ b/tests/tests/uirendering/src/android/uirendering/cts/testinfrastructure/ViewInitializer.java
@@ -21,5 +21,5 @@
  * Called after a view is created to set various properties on the view
  */
 public abstract class ViewInitializer {
-    public abstract void intializeView(View view);
+    public abstract void initializeView(View view);
 }
diff --git a/tests/tests/util/src/android/util/cts/ArrayMapTest.java b/tests/tests/util/src/android/util/cts/ArrayMapTest.java
index 7fdd0da..130b354 100644
--- a/tests/tests/util/src/android/util/cts/ArrayMapTest.java
+++ b/tests/tests/util/src/android/util/cts/ArrayMapTest.java
@@ -310,7 +310,7 @@
 
     private static void dump(ArrayMap map1, ArrayMap map2) {
         Log.e("test", "ArrayMap of " + map1.size() + " entries:");
-        for (int i=0; i<map2.size(); i++) {
+        for (int i=0; i<map1.size(); i++) {
             Log.e("test", "    " + map1.keyAt(i) + " -> " + map1.valueAt(i));
         }
         Log.e("test", "ArrayMap of " + map2.size() + " entries:");
diff --git a/tests/tests/util/src/android/util/cts/ArraySetTest.java b/tests/tests/util/src/android/util/cts/ArraySetTest.java
new file mode 100644
index 0000000..112459c
--- /dev/null
+++ b/tests/tests/util/src/android/util/cts/ArraySetTest.java
@@ -0,0 +1,495 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 android.util.ArraySet;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+// As is the case with ArraySet itself, ArraySetTest borrows heavily from ArrayMapTest.
+
+public class ArraySetTest extends AndroidTestCase {
+    private static final String TAG = "ArraySetTest";
+
+    private static final boolean DEBUG = false;
+
+    private static final int OP_ADD = 1;
+    private static final int OP_REM = 2;
+
+    private static int[] OPS = new int[] {
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD, OP_ADD,
+            OP_ADD, OP_ADD, OP_ADD,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+            OP_REM, OP_REM, OP_REM,
+            OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM, OP_REM,
+    };
+
+    private static int[] KEYS = new int[] {
+            // General adding and removing.
+              -1,   1900,    600,    200,   1200,   1500,   1800,    100,   1900,
+            2100,    300,    800,    600,   1100,   1300,   2000,   1000,   1400,
+             600,     -1,   1900,    600,    300,   2100,    200,    800,    800,
+            1800,   1500,   1300,   1100,   2000,   1400,   1000,   1200,   1900,
+
+            // Shrink when removing item from end.
+             100,    200,    300,    400,    500,    600,    700,    800,    900,
+             900,    800,    700,    600,    500,    400,    300,    200,    100,
+
+            // Shrink when removing item from middle.
+             100,    200,    300,    400,    500,    600,    700,    800,    900,
+             900,    800,    700,    600,    500,    400,    200,    300,    100,
+
+            // Shrink when removing item from front.
+             100,    200,    300,    400,    500,    600,    700,    800,    900,
+             900,    800,    700,    600,    500,    400,    100,    200,    300,
+
+            // Test hash collisions.
+             105,    106,    108,    104,    102,    102,    107,      5,    205,
+               4,    202,    203,      3,      5,    101,    109,    200,    201,
+               0,     -1,    100,
+             106,    108,    104,    102,    103,    105,    107,    101,    109,
+              -1,    100,      0,
+               4,      5,      3,      5,    200,    203,    202,    201,    205,
+    };
+
+    public static class ControlledHash {
+        final int mValue;
+
+        ControlledHash(int value) {
+            mValue = value;
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o == null) {
+                return false;
+            }
+            return mValue == ((ControlledHash)o).mValue;
+        }
+
+        @Override
+        public final int hashCode() {
+            return mValue/100;
+        }
+
+        @Override
+        public final String toString() {
+            return Integer.toString(mValue);
+        }
+    }
+
+    private static boolean compare(Object v1, Object v2) {
+        if (v1 == null) {
+            return v2 == null;
+        }
+        if (v2 == null) {
+            return false;
+        }
+        return v1.equals(v2);
+    }
+
+    private static <E> void compareSets(HashSet<E> set, ArraySet<E> array) {
+        assertEquals("Bad size", set.size(), array.size());
+
+        // Check that every entry in HashSet is in ArraySet.
+        for (E entry : set) {
+            assertTrue("ArraySet missing value: " + entry, array.contains(entry));
+        }
+
+        // Check that every entry in ArraySet is in HashSet using ArraySet.iterator().
+        for (E entry : array) {
+            assertTrue("ArraySet (via iterator) has unexpected value: " + entry,
+                    set.contains(entry));
+        }
+
+        // Check that every entry in ArraySet is in HashSet using ArraySet.valueAt().
+        for (int i = 0; i < array.size(); ++i) {
+            E entry = array.valueAt(i);
+            assertTrue("ArraySet (via valueAt) has unexpected value: " + entry,
+                    set.contains(entry));
+        }
+
+        if (set.hashCode() != array.hashCode()) {
+            assertEquals("Set hash codes differ", set.hashCode(), array.hashCode());
+        }
+
+        assertTrue("HashSet.equals(ArraySet) failed", set.equals(array));
+        assertTrue("ArraySet.equals(HashSet) failed", array.equals(set));
+
+        assertTrue("HashSet.containsAll(ArraySet) failed", set.containsAll(array));
+        assertTrue("ArraySet.containsAll(HashSet) failed", array.containsAll(set));
+    }
+
+    private static <E> void compareArraySetAndRawArray(ArraySet<E> arraySet, Object[] rawArray) {
+        assertEquals("Bad size", arraySet.size(), rawArray.length);
+        for (int i = 0; i < rawArray.length; ++i) {
+            assertEquals("ArraySet<E> and raw array unequal at index " + i,
+                    arraySet.valueAt(i), rawArray[i]);
+        }
+    }
+
+    private static <E> void validateArraySet(ArraySet<E> array) {
+        int index = 0;
+        Iterator<E> iter = array.iterator();
+        while (iter.hasNext()) {
+            E value = iter.next();
+            E realValue = array.valueAt(index);
+            if (!compare(realValue, value)) {
+                fail("Bad array set entry: expected " + realValue
+                        + ", got " + value + " at index " + index);
+            }
+            index++;
+        }
+
+        assertEquals("Length of iteration was unequal to size()", array.size(), index);
+    }
+
+    private static <E> void dump(HashSet<E> set, ArraySet<E> array) {
+        Log.e(TAG, "HashSet of " + set.size() + " entries:");
+        for (E entry : set) {
+            Log.e(TAG, "    " + entry);
+        }
+        Log.e(TAG, "ArraySet of " + array.size() + " entries:");
+        for (int i = 0; i < array.size(); i++) {
+            Log.e(TAG, "    " + array.valueAt(i));
+        }
+    }
+
+    private static void dump(ArraySet set1, ArraySet set2) {
+        Log.e(TAG, "ArraySet of " + set1.size() + " entries:");
+        for (int i = 0; i < set1.size(); i++) {
+            Log.e(TAG, "    " + set1.valueAt(i));
+        }
+        Log.e(TAG, "ArraySet of " + set2.size() + " entries:");
+        for (int i = 0; i < set2.size(); i++) {
+            Log.e(TAG, "    " + set2.valueAt(i));
+        }
+    }
+
+    public void testTest() {
+        assertEquals("OPS and KEYS must be equal length", OPS.length, KEYS.length);
+    }
+
+    public void testBasicArraySet() {
+        HashSet<ControlledHash> hashSet = new HashSet<ControlledHash>();
+        ArraySet<ControlledHash> arraySet = new ArraySet<ControlledHash>();
+
+        for (int i = 0; i < OPS.length; i++) {
+            ControlledHash key = KEYS[i] < 0 ? null : new ControlledHash(KEYS[i]);
+            String strKey = KEYS[i] < 0 ? null : Integer.toString(KEYS[i]);
+            switch (OPS[i]) {
+                case OP_ADD:
+                    if (DEBUG) Log.i(TAG, "Adding key: " + key);
+                    boolean hashAdded = hashSet.add(key);
+                    boolean arrayAdded = arraySet.add(key);
+                    assertEquals("Adding key " + key + " was not symmetric in HashSet and "
+                            + "ArraySet", hashAdded, arrayAdded);
+                    break;
+                case OP_REM:
+                    if (DEBUG) Log.i(TAG, "Removing key: " + key);
+                    boolean hashRemoved = hashSet.remove(key);
+                    boolean arrayRemoved = arraySet.remove(key);
+                    assertEquals("Removing key " + key + " was not symmetric in HashSet and "
+                            + "ArraySet", hashRemoved, arrayRemoved);
+                    break;
+                default:
+                    fail("Bad operation " + OPS[i] + " @ " + i);
+                    return;
+            }
+            if (DEBUG) dump(hashSet, arraySet);
+
+            try {
+                validateArraySet(arraySet);
+            } catch (Throwable e) {
+                Log.e(TAG, e.getMessage());
+                dump(hashSet, arraySet);
+                throw e;
+            }
+
+            try {
+                compareSets(hashSet, arraySet);
+            } catch (Throwable e) {
+                Log.e(TAG, e.getMessage());
+                dump(hashSet, arraySet);
+                throw e;
+            }
+        }
+
+        // Check to see if HashSet.iterator().remove() works as expected.
+        arraySet.add(new ControlledHash(50000));
+        ControlledHash lookup = new ControlledHash(50000);
+        Iterator<ControlledHash> it = arraySet.iterator();
+        while (it.hasNext()) {
+            if (it.next().equals(lookup)) {
+                it.remove();
+            }
+        }
+        if (arraySet.contains(lookup)) {
+            String msg = "Bad ArraySet iterator: didn't remove test key";
+            Log.e(TAG, msg);
+            dump(hashSet, arraySet);
+            fail(msg);
+        }
+
+        Log.e(TAG, "Test successful; printing final map.");
+        dump(hashSet, arraySet);
+    }
+
+    public void testCopyArraySet() {
+        // set copy constructor test
+        ArraySet newSet = new ArraySet<Integer>();
+        for (int i = 0; i < 10; ++i) {
+            newSet.add(i);
+        }
+
+        ArraySet copySet = new ArraySet(newSet);
+        if (!compare(copySet, newSet)) {
+            String msg = "ArraySet copy constructor failure: expected " +
+                    newSet + ", got " + copySet;
+            Log.e(TAG, msg);
+            dump(newSet, copySet);
+            fail(msg);
+            return;
+        }
+    }
+
+    public void testEqualsArrayMap() {
+        ArraySet<Integer> set1 = new ArraySet<Integer>();
+        ArraySet<Integer> set2 = new ArraySet<Integer>();
+        HashSet<Integer> set3 = new HashSet<Integer>();
+        if (!compare(set1, set2) || !compare(set1, set3) || !compare(set3, set2)) {
+            fail("ArraySet equals failure for empty sets " + set1 + ", " +
+                    set2 + ", " + set3);
+        }
+
+        for (int i = 0; i < 10; ++i) {
+            set1.add(i);
+            set2.add(i);
+            set3.add(i);
+        }
+        if (!compare(set1, set2) || !compare(set1, set3) || !compare(set3, set2)) {
+            fail("ArraySet equals failure for populated sets " + set1 + ", " +
+                    set2 + ", " + set3);
+        }
+
+        set1.remove(0);
+        if (compare(set1, set2) || compare(set1, set3) || compare(set3, set1)) {
+            fail("ArraySet equals failure for set size " + set1 + ", " +
+                    set2 + ", " + set3);
+        }
+    }
+
+    public void testIsEmpty() {
+        ArraySet<Integer> set = new ArraySet<Integer>();
+        assertEquals("New ArraySet should have size==0", 0, set.size());
+        assertTrue("New ArraySet should be isEmptry", set.isEmpty());
+
+        set.add(3);
+        assertEquals("ArraySet has incorrect size", 1, set.size());
+        assertFalse("ArraySet should not be isEmptry", set.isEmpty());
+
+        set.remove(3);
+        assertEquals("ArraySet should have size==0", 0, set.size());
+        assertTrue("ArraySet should be isEmptry", set.isEmpty());
+    }
+
+    public void testRemoveAt() {
+        ArraySet<Integer> set = new ArraySet<Integer>();
+
+        for (int i = 0; i < 10; ++i) {
+            set.add(i * 10);
+        }
+
+        int indexToDelete = 6;
+        assertEquals(10, set.size());
+        assertEquals(indexToDelete * 10, set.valueAt(indexToDelete).intValue());
+        assertEquals(indexToDelete * 10, set.removeAt(indexToDelete).intValue());
+        assertEquals(9, set.size());
+
+        for (int i = 0; i < 9; ++i) {
+            int expectedValue = ((i >= indexToDelete) ? (i + 1) : i) * 10;
+            assertEquals(expectedValue, set.valueAt(i).intValue());
+        }
+
+        for (int i = 9; i > 0; --i) {
+            set.removeAt(0);
+            assertEquals(i - 1, set.size());
+        }
+
+        assertTrue(set.isEmpty());
+
+        try {
+            set.removeAt(0);
+            fail("Expected ArrayIndexOutOfBoundsException");
+        } catch (ArrayIndexOutOfBoundsException expected) {
+            // expected
+        }
+    }
+
+    public void testIndexOf() {
+        ArraySet<Integer> set = new ArraySet<Integer>();
+
+        for (int i = 0; i < 10; ++i) {
+            set.add(i * 10);
+        }
+
+        for (int i = 0; i < 10; ++i) {
+            assertEquals("indexOf(" + (i * 10) + ")", i, set.indexOf(i * 10));
+        }
+    }
+
+    public void testAddAll() {
+        ArraySet<Integer> arraySet = new ArraySet<Integer>();
+        ArraySet<Integer> testArraySet = new ArraySet<Integer>();
+        ArrayList<Integer> testArrayList = new ArrayList<Integer>();
+
+        for (int i = 0; i < 10; ++i) {
+            testArraySet.add(i * 10);
+            testArrayList.add(i * 10);
+        }
+
+        assertTrue(arraySet.isEmpty());
+
+        // addAll(ArraySet) has no return value.
+        arraySet.addAll(testArraySet);
+        assertTrue("ArraySet.addAll(ArraySet) failed", arraySet.containsAll(testArraySet));
+
+        arraySet.clear();
+        assertTrue(arraySet.isEmpty());
+
+        // addAll(Collection) returns true if any items were added.
+        assertTrue(arraySet.addAll(testArrayList));
+        assertTrue("ArraySet.addAll(Container) failed", arraySet.containsAll(testArrayList));
+        assertTrue("ArraySet.addAll(Container) failed", arraySet.containsAll(testArraySet));
+        // Adding the same Collection should return false.
+        assertFalse(arraySet.addAll(testArrayList));
+        assertTrue("ArraySet.addAll(Container) failed", arraySet.containsAll(testArrayList));
+    }
+
+    public void testRemoveAll() {
+        ArraySet<Integer> arraySet = new ArraySet<Integer>();
+        ArraySet<Integer> arraySetToRemove = new ArraySet<Integer>();
+        ArrayList<Integer> arrayListToRemove = new ArrayList<Integer>();
+
+        for (int i = 0; i < 10; ++i) {
+            arraySet.add(i * 10);
+        }
+
+        for (int i = 6; i < 15; ++i) {
+            arraySetToRemove.add(i * 10);
+        }
+
+        for (int i = 3; i > -3; --i) {
+            arrayListToRemove.add(i * 10);
+        }
+
+        assertEquals(10, arraySet.size());
+
+        // Remove [6,14] (really [6,9]) via another ArraySet.
+        assertTrue(arraySet.removeAll(arraySetToRemove));
+        assertEquals(6, arraySet.size());
+        assertFalse(arraySet.removeAll(arraySetToRemove));
+        assertEquals(6, arraySet.size());
+
+        // Remove [-2,3] (really [0,3]) via an ArrayList (ie Collection).
+        assertTrue(arraySet.removeAll(arrayListToRemove));
+        assertEquals(2, arraySet.size());
+        assertFalse(arraySet.removeAll(arrayListToRemove));
+        assertEquals(2, arraySet.size());
+
+        // Remove the rest of the items.
+        ArraySet<Integer> copy = new ArraySet<Integer>(arraySet);
+        assertTrue(arraySet.removeAll(copy));
+        assertEquals(0, arraySet.size());
+        assertFalse(arraySet.removeAll(copy));
+        assertEquals(0, arraySet.size());
+    }
+
+    public void testRetainAll() {
+        ArraySet<Integer> arraySet = new ArraySet<Integer>();
+        ArrayList<Integer> arrayListToRetain = new ArrayList<Integer>();
+
+        for (int i = 0; i < 10; ++i) {
+            arraySet.add(i * 10);
+        }
+
+        arrayListToRetain.add(30);
+        arrayListToRetain.add(50);
+        arrayListToRetain.add(51); // bogus value
+
+        assertEquals(10, arraySet.size());
+
+        assertTrue(arraySet.retainAll(arrayListToRetain));
+        assertEquals(2, arraySet.size());
+
+        assertTrue(arraySet.contains(30));
+        assertTrue(arraySet.contains(50));
+        assertFalse(arraySet.contains(51));
+
+        // Nothing should change.
+        assertFalse(arraySet.retainAll(arrayListToRetain));
+        assertEquals(2, arraySet.size());
+    }
+
+    public void testToArray() {
+        ArraySet<Integer> arraySet = new ArraySet<Integer>();
+        for (int i = 0; i < 10; ++i) {
+            arraySet.add(i * 10);
+        }
+
+        // Allocate a new array with the right type given a zero-length ephemeral array.
+        Integer[] copiedArray = arraySet.toArray(new Integer[0]);
+        compareArraySetAndRawArray(arraySet, copiedArray);
+
+        // Allocate a new array with the right type given an undersized array.
+        Integer[] undersizedArray = new Integer[5];
+        copiedArray = arraySet.toArray(undersizedArray);
+        compareArraySetAndRawArray(arraySet, copiedArray);
+        assertNotSame(undersizedArray, copiedArray);
+
+        // Use the passed array that is large enough to hold the ArraySet.
+        Integer[] rightSizedArray = new Integer[10];
+        copiedArray = arraySet.toArray(rightSizedArray);
+        compareArraySetAndRawArray(arraySet, copiedArray);
+        assertSame(rightSizedArray, copiedArray);
+
+        // Create a new Object[] array.
+        Object[] objectArray = arraySet.toArray();
+        compareArraySetAndRawArray(arraySet, objectArray);
+    }
+}
diff --git a/tests/tests/util/src/android/util/cts/EventLogTest.java b/tests/tests/util/src/android/util/cts/EventLogTest.java
index bbff3bc..2d856c4 100644
--- a/tests/tests/util/src/android/util/cts/EventLogTest.java
+++ b/tests/tests/util/src/android/util/cts/EventLogTest.java
@@ -37,21 +37,24 @@
         EventLog.writeEvent(ANSWER_TAG, markerData);
         EventLog.writeEvent(ANSWER_TAG, 12345);
         EventLog.writeEvent(ANSWER_TAG, 23456L);
+        EventLog.writeEvent(ANSWER_TAG, 42.4242f);
         EventLog.writeEvent(ANSWER_TAG, "Test");
-        EventLog.writeEvent(ANSWER_TAG, 12345, 23456L, "Test");
+        EventLog.writeEvent(ANSWER_TAG, 12345, 23456L, 42.4242f, "Test");
 
         List<EventLog.Event> events = getEventsAfterMarker(markerData, ANSWER_TAG);
-        assertEquals(4, events.size());
+        assertEquals(5, events.size());
         assertEquals(ANSWER_TAG, events.get(0).getTag());
         assertEquals(12345, events.get(0).getData());
         assertEquals(23456L, events.get(1).getData());
-        assertEquals("Test", events.get(2).getData());
+        assertEquals(42.4242f, events.get(2).getData());
+        assertEquals("Test", events.get(3).getData());
 
-        Object[] arr = (Object[]) events.get(3).getData();
-        assertEquals(3, arr.length);
+        Object[] arr = (Object[]) events.get(4).getData();
+        assertEquals(4, arr.length);
         assertEquals(12345, arr[0]);
         assertEquals(23456L, arr[1]);
-        assertEquals("Test", arr[2]);
+        assertEquals(42.4242f, arr[2]);
+        assertEquals("Test", arr[3]);
     }
 
     public void testWriteEventWithOversizeValue() throws Exception {
@@ -67,10 +70,11 @@
         EventLog.writeEvent(ANSWER_TAG, "hi", longString.toString());
         EventLog.writeEvent(ANSWER_TAG, 12345, longString.toString());
         EventLog.writeEvent(ANSWER_TAG, 12345L, longString.toString());
+        EventLog.writeEvent(ANSWER_TAG, 42.4242f, longString.toString());
         EventLog.writeEvent(ANSWER_TAG, longString.toString(), longString.toString());
         EventLog.writeEvent(ANSWER_TAG, longArray);
         List<Event> events = getEventsAfterMarker(markerData, ANSWER_TAG);
-        assertEquals(6, events.size());
+        assertEquals(7, events.size());
 
         // subtract: log header, type byte, final newline
         final int max = 4096 - 20 - 4 - 1;
@@ -97,15 +101,21 @@
         assertEquals(12345L, arr3[0]);
         assertEquals(max - 2 - 9 - 5, ((String) arr3[1]).length());
 
-        // subtract: array header, string header (second string is dropped entirely)
+        // subtract: array header, float, string header
         Object[] arr4 = (Object[]) events.get(4).getData();
-        assertEquals(1, arr4.length);
-        assertEquals(max - 2 - 5, ((String) arr4[0]).length());
+        assertEquals(2, arr4.length);
+        assertEquals(42.4242f, arr4[0]);
+        assertEquals(max - 2 - 5 - 5, ((String) arr4[1]).length());
 
+        // subtract: array header, string header (second string is dropped entirely)
         Object[] arr5 = (Object[]) events.get(5).getData();
-        assertEquals(255, arr5.length);
-        assertEquals(12345, arr5[0]);
-        assertEquals(12345, arr5[arr5.length - 1]);
+        assertEquals(1, arr5.length);
+        assertEquals(max - 2 - 5, ((String) arr5[0]).length());
+
+        Object[] arr6 = (Object[]) events.get(6).getData();
+        assertEquals(255, arr6.length);
+        assertEquals(12345, arr6[0]);
+        assertEquals(12345, arr6[arr6.length - 1]);
     }
 
     public void testWriteNullEvent() throws Exception {
diff --git a/tests/tests/util/src/android/util/cts/FloatMathTest.java b/tests/tests/util/src/android/util/cts/FloatMathTest.java
deleted file mode 100644
index 4d0b572..0000000
--- a/tests/tests/util/src/android/util/cts/FloatMathTest.java
+++ /dev/null
@@ -1,45 +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.util.cts;
-
-import junit.framework.TestCase;
-import android.util.FloatMath;
-
-public class FloatMathTest extends TestCase {
-    public void testFloatMathMethods() {
-        // ceil
-        assertEquals(8.0f, FloatMath.ceil(7.2f));
-        assertEquals(-6.0f, FloatMath.ceil(-6.3f));
-
-        // floor
-        assertEquals(7.0f, FloatMath.floor(7.2f));
-        assertEquals(-7.0f, FloatMath.floor(-6.3f));
-
-        // sin
-        assertEquals(-0.26237485f, FloatMath.sin(50));
-        assertEquals(-0.71487643f, FloatMath.sin(150));
-        assertEquals(0.26237485f, FloatMath.sin(-50));
-
-        // cos
-        assertEquals(0.964966f, FloatMath.cos(50));
-        assertEquals(0.69925081f, FloatMath.cos(150));
-        assertEquals(0.964966f, FloatMath.cos(-50));
-
-        // sqrt
-        assertEquals(5.0f, FloatMath.sqrt(25));
-    }
-
-}
diff --git a/tests/tests/view/AndroidManifest.xml b/tests/tests/view/AndroidManifest.xml
index a36e6fd..b7e0076 100644
--- a/tests/tests/view/AndroidManifest.xml
+++ b/tests/tests/view/AndroidManifest.xml
@@ -92,7 +92,7 @@
         </activity>
 
         <activity android:name="android.view.animation.cts.GridLayoutAnimCtsActivity"
-            android:label="GridLayoutAnimCtsActivity">
+            android:label="GridLayoutAnimCtsActivity" android:configChanges="orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -100,7 +100,7 @@
         </activity>
 
         <activity android:name="android.view.animation.cts.LayoutAnimCtsActivity"
-            android:label="LayoutAnimCtsActivity">
+            android:label="LayoutAnimCtsActivity" android:configChanges="orientation|screenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN"/>
                 <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
@@ -150,7 +150,11 @@
         <activity android:name="android.view.cts.GestureDetectorCtsActivity"
             android:label="GestureDetectorCtsActivity"
             android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
-            
+
+        <activity android:name="android.view.cts.ScaleGestureDetectorCtsActivity"
+            android:label="ScaleGestureDetectorCtsActivity"
+            android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
+
         <activity android:name="android.view.cts.GLSurfaceViewCtsActivity"
             android:label="GLSurfaceViewCts"/>
 
@@ -159,6 +163,10 @@
                 android:resource="@xml/merge" />
         </activity>
 
+        <activity android:name="android.view.cts.ActionModeCtsActivity"
+            android:label="ActionModeCtsActivity">
+        </activity>
+
         <activity android:name="android.view.cts.ViewGroupCtsActivity"
             android:label="WidgetViewGroupCtsActivity">
             <intent-filter>
@@ -167,6 +175,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.view.cts.SearchEventActivity"
+            android:label="SearchEventActivity">
+            <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.CtsActivity"
             android:label="CtsActivity">
             <intent-filter>
diff --git a/tests/tests/view/res/layout/inflater_override_theme_layout.xml b/tests/tests/view/res/layout/inflater_override_theme_layout.xml
index 2d2a578..93a765b 100644
--- a/tests/tests/view/res/layout/inflater_override_theme_layout.xml
+++ b/tests/tests/view/res/layout/inflater_override_theme_layout.xml
@@ -43,4 +43,13 @@
             android:theme="?attr/themeOverrideAttr" />
     </LinearLayout>
 
+    <include
+        layout="@layout/single_view_layout"
+        android:id="@+id/view_include"
+        android:theme="@style/Theme_OverrideInclude" />
+
+    <include
+        layout="@layout/single_view_layout"
+        android:id="@+id/view_include_notheme" />
+
 </LinearLayout>
diff --git a/tests/tests/view/res/layout/single_view_layout.xml b/tests/tests/view/res/layout/single_view_layout.xml
new file mode 100644
index 0000000..5f66983
--- /dev/null
+++ b/tests/tests/view/res/layout/single_view_layout.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.
+-->
+
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content"
+      android:theme="@style/Theme_OverrideView" />
diff --git a/tests/tests/view/res/layout/view_layout.xml b/tests/tests/view/res/layout/view_layout.xml
index fa817dc..b501a4d 100644
--- a/tests/tests/view/res/layout/view_layout.xml
+++ b/tests/tests/view/res/layout/view_layout.xml
@@ -21,7 +21,8 @@
     android:id="@+id/viewlayout_root"
     android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:scrollIndicators="left|right">
 
     <android.view.cts.MockView
         android:id="@+id/mock_view"
@@ -34,6 +35,7 @@
         android:layout_height="200px"
         android:scrollbars="horizontal|vertical"
         android:fadingEdge="horizontal|vertical"
+        android:scrollIndicators="top|bottom"
         android:fadingEdgeLength="20px"/>
 
     <android.view.cts.MockView
diff --git a/tests/tests/view/res/values/styles.xml b/tests/tests/view/res/values/styles.xml
index 20c80f8..9de4abd 100644
--- a/tests/tests/view/res/values/styles.xml
+++ b/tests/tests/view/res/values/styles.xml
@@ -150,6 +150,14 @@
     <style name="Theme_OverrideAttr">
         <item name="themeType">3</item>
     </style>
+
+    <style name="Theme_OverrideInclude">
+        <item name="themeType">4</item>
+    </style>
+
+    <style name="Theme_OverrideView">
+        <item name="themeType">5</item>
+    </style>
     
     <style name="Theme_ThemedDrawableTest">
         <item name="themeBoolean">true</item>
diff --git a/tests/tests/view/res/xml/keyboard.xml b/tests/tests/view/res/xml/keyboard.xml
new file mode 100644
index 0000000..dd64cc0
--- /dev/null
+++ b/tests/tests/view/res/xml/keyboard.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+    android:keyWidth="10%p"
+    android:horizontalGap="0px"
+    android:verticalGap="0px"
+    android:keyHeight="10px"
+    >
+
+    <Row>
+        <Key android:codes="-1" android:keyLabel="Sticky!"
+                android:isModifier="true" android:isSticky="true" />
+        <Key android:codes="120" android:keyLabel="x" />
+    </Row>
+</Keyboard>
diff --git a/tests/tests/view/src/android/view/cts/ActionModeCallback2Test.java b/tests/tests/view/src/android/view/cts/ActionModeCallback2Test.java
new file mode 100644
index 0000000..e75b7ae
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ActionModeCallback2Test.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Rect;
+import android.test.AndroidTestCase;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+public class ActionModeCallback2Test extends AndroidTestCase {
+    private static final int VIEW_WIDTH = 123;
+    private static final int VIEW_HEIGHT = 456;
+
+    public void testCallbackOnGetContentRectDefaultWithView() {
+        View view = new View(mContext);
+        view.setLeft(0);
+        view.setRight(VIEW_WIDTH);
+        view.setTop(0);
+        view.setBottom(VIEW_HEIGHT);
+
+        Rect outRect = new Rect();
+        MockActionModeCallback2 callback = new MockActionModeCallback2();
+        callback.onGetContentRect(null, view, outRect);
+
+        assertEquals(0, outRect.top);
+        assertEquals(0, outRect.left);
+        assertEquals(VIEW_HEIGHT, outRect.bottom);
+        assertEquals(VIEW_WIDTH, outRect.right);
+    }
+
+    public void testCallbackOnGetContentRectDefaultWithoutView() {
+        Rect outRect = new Rect();
+        MockActionModeCallback2 callback = new MockActionModeCallback2();
+        callback.onGetContentRect(null, null, outRect);
+
+        assertEquals(0, outRect.top);
+        assertEquals(0, outRect.left);
+        assertEquals(0, outRect.bottom);
+        assertEquals(0, outRect.right);
+    }
+
+    private static class MockActionModeCallback2 extends ActionMode.Callback2 {
+        @Override
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            return false;
+        }
+
+        @Override
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            return false;
+        }
+
+        @Override
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            return false;
+        }
+
+        @Override
+        public void onDestroyActionMode(ActionMode mode) {}
+    }
+
+}
diff --git a/tests/tests/view/src/android/view/cts/ActionModeCtsActivity.java b/tests/tests/view/src/android/view/cts/ActionModeCtsActivity.java
new file mode 100644
index 0000000..c03db59
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ActionModeCtsActivity.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.view.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class ActionModeCtsActivity extends Activity {
+
+    public View contentView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        contentView = new FrameLayout(this);
+        setContentView(contentView);
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ActionModeTest.java b/tests/tests/view/src/android/view/cts/ActionModeTest.java
new file mode 100644
index 0000000..534db311
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ActionModeTest.java
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.Rect;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+
+public class ActionModeTest extends ActivityInstrumentationTestCase2<ActionModeCtsActivity> {
+
+    public ActionModeTest() {
+        super(ActionModeCtsActivity.class);
+    }
+
+    public void testSetType() {
+        ActionMode actionMode = new MockActionMode();
+        assertEquals(ActionMode.TYPE_PRIMARY, actionMode.getType());
+
+        actionMode.setType(ActionMode.TYPE_FLOATING);
+        assertEquals(ActionMode.TYPE_FLOATING, actionMode.getType());
+
+        actionMode.setType(ActionMode.TYPE_PRIMARY);
+        assertEquals(ActionMode.TYPE_PRIMARY, actionMode.getType());
+    }
+
+    public void testInvalidateContentRectDoesNotInvalidateFull() {
+        MockActionMode actionMode = new MockActionMode();
+
+        actionMode.invalidateContentRect();
+
+        assertFalse(actionMode.mInvalidateWasCalled);
+    }
+
+    public void testInvalidateContentRectOnFloatingCallsCallback() {
+        final View view = getActivity().contentView;
+        final MockActionModeCallback2 callback = new MockActionModeCallback2();
+
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                ActionMode mode = view.startActionMode(callback, ActionMode.TYPE_FLOATING);
+                assertNotNull(mode);
+                mode.invalidateContentRect();
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        assertTrue(callback.mIsOnGetContentRectCalled);
+    }
+
+    public void testSetAndGetTitleOptionalHint() {
+        MockActionMode actionMode = new MockActionMode();
+
+        // Check default value.
+        assertFalse(actionMode.getTitleOptionalHint());
+        // Test set and get.
+        actionMode.setTitleOptionalHint(true);
+        assertTrue(actionMode.getTitleOptionalHint());
+        actionMode.setTitleOptionalHint(false);
+        assertFalse(actionMode.getTitleOptionalHint());
+    }
+
+    public void testSetAndGetTag() {
+        MockActionMode actionMode = new MockActionMode();
+        Object tag = new Object();
+
+        // Check default value.
+        assertNull(actionMode.getTag());
+
+        actionMode.setTag(tag);
+        assertSame(tag, actionMode.getTag());
+    }
+
+    public void testIsTitleOptional() {
+        MockActionMode actionMode = new MockActionMode();
+
+        // Check default value.
+        assertFalse(actionMode.isTitleOptional());
+    }
+
+    public void testIsUiFocusable() {
+        MockActionMode actionMode = new MockActionMode();
+
+        // Check default value.
+        assertTrue(actionMode.isUiFocusable());
+    }
+
+    public void testHide() {
+        MockActionMode actionMode = new MockActionMode();
+
+        actionMode.hide(0);
+        actionMode.hide(ActionMode.DEFAULT_HIDE_DURATION);
+    }
+
+    public void testOnWindowFocusChanged() {
+        MockActionMode actionMode = new MockActionMode();
+
+        actionMode.onWindowFocusChanged(true);
+        actionMode.onWindowFocusChanged(false);
+    }
+
+    private static class MockActionModeCallback2 extends ActionMode.Callback2 {
+        boolean mIsOnGetContentRectCalled = false;
+
+        @Override
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            return true;
+        }
+
+        @Override
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            return true;
+        }
+
+        @Override
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            return false;
+        }
+
+        @Override
+        public void onDestroyActionMode(ActionMode mode) {}
+
+        @Override
+        public void onGetContentRect(ActionMode mode, View view, Rect outRect) {
+            mIsOnGetContentRectCalled = true;
+            super.onGetContentRect(mode, view, outRect);
+        }
+    }
+
+    private static class MockActionMode extends ActionMode {
+        boolean mInvalidateWasCalled = false;
+
+        @Override
+        public void setTitle(CharSequence title) {}
+
+        @Override
+        public void setTitle(int resId) {}
+
+        @Override
+        public void setSubtitle(CharSequence subtitle) {}
+
+        @Override
+        public void setSubtitle(int resId) {}
+
+        @Override
+        public void setCustomView(View view) {}
+
+        @Override
+        public void invalidate() {
+            mInvalidateWasCalled = true;
+        }
+
+        @Override
+        public void finish() {}
+
+        @Override
+        public Menu getMenu() {
+            return null;
+        }
+
+        @Override
+        public CharSequence getTitle() {
+            return null;
+        }
+
+        @Override
+        public CharSequence getSubtitle() {
+            return null;
+        }
+
+        @Override
+        public View getCustomView() {
+            return null;
+        }
+
+        @Override
+        public MenuInflater getMenuInflater() {
+            return null;
+        }
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java b/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java
index c40f095..012a13d 100644
--- a/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java
+++ b/tests/tests/view/src/android/view/cts/ContextThemeWrapperTest.java
@@ -43,11 +43,11 @@
     }
 
     public void testConstructor() {
-        // new the ContextThemeWrapper instance
         new ContextThemeWrapper();
 
-        // new the ContextThemeWrapper instance
         new ContextThemeWrapper(getContext(), R.style.TextAppearance);
+
+        new ContextThemeWrapper(getContext(), getContext().getTheme());
     }
 
     public void testAccessTheme() {
diff --git a/tests/tests/view/src/android/view/cts/GestureDetectorCtsActivity.java b/tests/tests/view/src/android/view/cts/GestureDetectorCtsActivity.java
index f02a0d6..1c02a89 100644
--- a/tests/tests/view/src/android/view/cts/GestureDetectorCtsActivity.java
+++ b/tests/tests/view/src/android/view/cts/GestureDetectorCtsActivity.java
@@ -25,6 +25,7 @@
 import android.view.ViewGroup;
 import android.view.GestureDetector.SimpleOnGestureListener;
 import android.view.View.OnTouchListener;
+import android.view.View.OnGenericMotionListener;
 import android.widget.Button;
 
 public class GestureDetectorCtsActivity extends Activity {
@@ -38,6 +39,7 @@
     public boolean onDoubleTap;
     public boolean onDoubleTapEvent;
     public boolean onSingleTapConfirmed;
+    public boolean onContextClick;
 
     private GestureDetector mGestureDetector;
     private MockOnGestureListener mOnGestureListener;
@@ -56,6 +58,7 @@
 
         mGestureDetector = new GestureDetector(this, mOnGestureListener, mHandler);
         mGestureDetector.setOnDoubleTapListener(mOnGestureListener);
+        mGestureDetector.setContextClickListener(mOnGestureListener);
         mView = new View(this);
         mButton = new Button(this);
         mTop = new Button(this);
@@ -86,7 +89,13 @@
         return mGestureDetector;
     }
 
+    public MockOnGestureListener getListener() {
+        return mOnGestureListener;
+    }
+
     public class MockOnGestureListener extends SimpleOnGestureListener {
+        private MotionEvent mPreviousContextClickEvent;
+
         public boolean onDown(MotionEvent e) {
             isDown = true;
             return true;
@@ -129,14 +138,29 @@
             onSingleTapConfirmed = true;
             return false;
         }
+
+        public boolean onContextClick(MotionEvent e) {
+            onContextClick = true;
+            mPreviousContextClickEvent = e;
+            return false;
+        }
+
+        public MotionEvent getPreviousContextClickEvent() {
+            return mPreviousContextClickEvent;
+        }
     }
 
-    class MockOnTouchListener implements OnTouchListener {
+    class MockOnTouchListener implements OnTouchListener, OnGenericMotionListener {
 
         public boolean onTouch(View v, MotionEvent event) {
             mGestureDetector.onTouchEvent(event);
             return true;
         }
+
+        public boolean onGenericMotion(View v, MotionEvent event) {
+            mGestureDetector.onGenericMotionEvent(event);
+            return true;
+        }
     }
 
 }
diff --git a/tests/tests/view/src/android/view/cts/GestureDetectorTest.java b/tests/tests/view/src/android/view/cts/GestureDetectorTest.java
index c568cf1..f06455d 100644
--- a/tests/tests/view/src/android/view/cts/GestureDetectorTest.java
+++ b/tests/tests/view/src/android/view/cts/GestureDetectorTest.java
@@ -19,18 +19,31 @@
 import android.content.Context;
 import android.os.Handler;
 import android.os.Looper;
+import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
+import android.view.cts.GestureDetectorCtsActivity.MockOnGestureListener;
 import android.view.GestureDetector;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
 import android.view.GestureDetector.SimpleOnGestureListener;
 
 public class GestureDetectorTest extends
         ActivityInstrumentationTestCase2<GestureDetectorCtsActivity> {
 
+    private static final float X_3F = 3.0f;
+    private static final float Y_4F = 4.0f;
+
     private GestureDetector mGestureDetector;
     private GestureDetectorCtsActivity mActivity;
+    private MockOnGestureListener mListener;
     private Context mContext;
 
+    private long mDownTime;
+    private long mEventTime;
+    private MotionEvent mButtonPressPrimaryMotionEvent;
+    private MotionEvent mButtonPressSecondaryMotionEvent;
+
     public GestureDetectorTest() {
         super("com.android.cts.view", GestureDetectorCtsActivity.class);
     }
@@ -40,6 +53,7 @@
         super.setUp();
         mActivity = getActivity();
         mGestureDetector = mActivity.getGestureDetector();
+        mListener = mActivity.getListener();
         mContext = getInstrumentation().getTargetContext();
         mActivity.isDown = false;
         mActivity.isScroll = false;
@@ -50,6 +64,17 @@
         mActivity.onDoubleTap = false;
         mActivity.onDoubleTapEvent = false;
         mActivity.onSingleTapConfirmed = false;
+        mActivity.onContextClick = false;
+
+        mDownTime = SystemClock.uptimeMillis();
+        mEventTime = SystemClock.uptimeMillis();
+        mButtonPressPrimaryMotionEvent = MotionEvent.obtain(mDownTime, mEventTime,
+                MotionEvent.ACTION_BUTTON_PRESS, X_3F, Y_4F, 0);
+        mButtonPressPrimaryMotionEvent.setActionButton(MotionEvent.BUTTON_STYLUS_PRIMARY);
+
+        mButtonPressSecondaryMotionEvent = MotionEvent.obtain(mDownTime, mEventTime,
+                MotionEvent.ACTION_BUTTON_PRESS, X_3F, Y_4F, 0);
+        mButtonPressSecondaryMotionEvent.setActionButton(MotionEvent.BUTTON_SECONDARY);
     }
 
     @UiThreadTest
@@ -75,4 +100,35 @@
         mGestureDetector.setIsLongpressEnabled(false);
         assertFalse(mGestureDetector.isLongpressEnabled());
     }
+
+    public void testOnSetContextClickListener() {
+        mActivity.onContextClick = false;
+        mGestureDetector.setContextClickListener(null);
+        mGestureDetector.onGenericMotionEvent(mButtonPressPrimaryMotionEvent);
+        assertFalse(mActivity.onContextClick);
+
+        mGestureDetector.setContextClickListener(mListener);
+        mGestureDetector.onGenericMotionEvent(mButtonPressPrimaryMotionEvent);
+        assertTrue(mActivity.onContextClick);
+        assertSame(mButtonPressPrimaryMotionEvent, mListener.getPreviousContextClickEvent());
+    }
+
+    public void testOnContextClick() {
+        mActivity.onContextClick = false;
+        mListener.onContextClick(mButtonPressPrimaryMotionEvent);
+        assertTrue(mActivity.onContextClick);
+        assertSame(mButtonPressPrimaryMotionEvent, mListener.getPreviousContextClickEvent());
+
+        mActivity.onContextClick = false;
+        mGestureDetector.onGenericMotionEvent(mButtonPressSecondaryMotionEvent);
+        assertTrue(mActivity.onContextClick);
+        assertSame(mButtonPressSecondaryMotionEvent, mListener.getPreviousContextClickEvent());
+    }
+
+    public void testOnGenericMotionEvent() {
+        mActivity.onContextClick = false;
+        mGestureDetector.onGenericMotionEvent(mButtonPressPrimaryMotionEvent);
+        assertTrue(mActivity.onContextClick);
+        assertSame(mButtonPressPrimaryMotionEvent, mListener.getPreviousContextClickEvent());
+    }
 }
diff --git a/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java b/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
index bf83086..00b9fe9 100644
--- a/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
+++ b/tests/tests/view/src/android/view/cts/LayoutInflaterTest.java
@@ -17,7 +17,7 @@
 package android.view.cts;
 
 import com.android.cts.view.R;
-import com.android.internal.util.XmlUtils;
+import android.view.cts.util.XmlUtils;
 
 import org.xmlpull.v1.XmlPullParser;
 
@@ -29,7 +29,6 @@
 import android.content.res.Resources.Theme;
 import android.content.res.XmlResourceParser;
 import android.test.AndroidTestCase;
-import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.util.Xml;
@@ -370,6 +369,8 @@
         verifyThemeType(container, "view_outer", R.id.view_outer, 1);
         verifyThemeType(container, "view_inner", R.id.view_inner, 2);
         verifyThemeType(container, "view_attr", R.id.view_attr, 3);
+        verifyThemeType(container, "view_include", R.id.view_include, 4);
+        verifyThemeType(container, "view_include_notheme", R.id.view_include_notheme, 5);
     }
 
     private void verifyThemeType(View container, String tag, int id, int type) {
diff --git a/tests/tests/view/src/android/view/cts/MenuInflaterTest.java b/tests/tests/view/src/android/view/cts/MenuInflaterTest.java
index 6007730..7e3517f 100644
--- a/tests/tests/view/src/android/view/cts/MenuInflaterTest.java
+++ b/tests/tests/view/src/android/view/cts/MenuInflaterTest.java
@@ -17,10 +17,8 @@
 package android.view.cts;
 
 import com.android.cts.view.R;
-import com.android.internal.view.menu.MenuBuilder;
 
 import android.app.Activity;
-import android.content.Context;
 import android.content.res.Resources;
 import android.cts.util.WidgetTestUtils;
 import android.graphics.Bitmap;
@@ -31,6 +29,7 @@
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.SubMenu;
+import android.widget.PopupMenu;
 
 /**
  * Test {@link MenuInflater}.
@@ -50,6 +49,10 @@
         mActivity = getActivity();
     }
 
+    private Menu createMenu(Activity context) {
+        return new PopupMenu(context, null).getMenu();
+    }
+
     @UiThreadTest
     public void testConstructor() {
         new MenuInflater(mActivity);
@@ -57,7 +60,7 @@
 
     @UiThreadTest
     public void testInflate() {
-        Menu menu = new MenuBuilder(mActivity);
+        Menu menu = createMenu(mActivity);
         assertEquals(0, menu.size());
 
         if (mMenuInflater == null) {
@@ -89,7 +92,7 @@
         }
 
         // the visibility and shortcut
-        Menu menu = new MenuBuilder(mActivity);
+        Menu menu = createMenu(mActivity);
         mMenuInflater.inflate(R.menu.visible_shortcut, menu);
 
         assertTrue(menu.findItem(R.id.visible_item).isVisible());
@@ -103,7 +106,7 @@
         assertEquals('c', menu.findItem(R.id.hidden_by_group).getAlphabeticShortcut());
 
         // the titles and icons
-        menu = new MenuBuilder(mActivity);
+        menu = createMenu(mActivity);
         mMenuInflater.inflate(com.android.cts.view.R.menu.title_icon, menu);
 
         assertEquals("Start", menu.findItem(R.id.start).getTitle());
@@ -119,7 +122,7 @@
                 R.drawable.failed);
 
         // the orders and categories
-        menu = new MenuBuilder(mActivity);
+        menu = createMenu(mActivity);
         mMenuInflater.inflate(com.android.cts.view.R.menu.category_order, menu);
         // default category
         assertEquals(R.id.most_used_items, menu.findItem(R.id.first_most_item).getGroupId());
@@ -143,7 +146,7 @@
         assertEquals(Menu.CATEGORY_SECONDARY + 4, menu.findItem(R.id.last_least_item).getOrder());
 
         // the checkables
-        menu = new MenuBuilder(mActivity);
+        menu = createMenu(mActivity);
         mMenuInflater.inflate(com.android.cts.view.R.menu.checkable, menu);
         // noncheckables
         assertEquals(R.id.noncheckable_group,
diff --git a/tests/tests/view/src/android/view/cts/MockTextView.java b/tests/tests/view/src/android/view/cts/MockTextView.java
index dc9420d..0c73614 100644
--- a/tests/tests/view/src/android/view/cts/MockTextView.java
+++ b/tests/tests/view/src/android/view/cts/MockTextView.java
@@ -179,19 +179,19 @@
     }
 
     public int getFrameLeft() {
-        return mLeft;
+        return getLeft();
     }
 
     public int getFrameTop() {
-        return mTop;
+        return getTop();
     }
 
     public int getFrameRight() {
-        return mRight;
+        return getRight();
     }
 
     public int getFrameBottom() {
-        return mBottom;
+        return getBottom();
     }
 
     public int getBottomPaddingOffset() {
diff --git a/tests/tests/view/src/android/view/cts/MockView.java b/tests/tests/view/src/android/view/cts/MockView.java
index 9093089..579d4fb 100644
--- a/tests/tests/view/src/android/view/cts/MockView.java
+++ b/tests/tests/view/src/android/view/cts/MockView.java
@@ -29,6 +29,7 @@
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
 import android.view.ViewParent;
 import android.view.ContextMenu.ContextMenuInfo;
 
@@ -104,8 +105,8 @@
         return mCalledInvalidate;
     }
 
-    public void setParent(ViewParent parent) {
-        mParent = parent;
+    public void setParent(ViewGroup parent) {
+        parent.addView(this);
     }
 
     public static int[] getEnabledStateSet() {
@@ -162,16 +163,6 @@
     }
 
     @Override
-    protected void initializeFadingEdge(TypedArray a) {
-        super.initializeFadingEdge(a);
-    }
-
-    @Override
-    protected void initializeScrollbars(TypedArray a) {
-        super.initializeScrollbars(a);
-    }
-
-    @Override
     protected int getHorizontalScrollbarHeight() {
         return super.getHorizontalScrollbarHeight();
     }
diff --git a/tests/tests/view/src/android/view/cts/MotionEventTest.java b/tests/tests/view/src/android/view/cts/MotionEventTest.java
index cdedca4..10ea33a 100644
--- a/tests/tests/view/src/android/view/cts/MotionEventTest.java
+++ b/tests/tests/view/src/android/view/cts/MotionEventTest.java
@@ -180,6 +180,40 @@
         assertEquals(mMotionEvent2.getDeviceId(), motionEvent.getDeviceId());
     }
 
+    public void testReadFromParcelWithInvalidPointerCountSize() {
+        Parcel parcel = Parcel.obtain();
+        mMotionEvent2.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+
+        // Move to pointer id count.
+        parcel.setDataPosition(4);
+        parcel.writeInt(17);
+
+        parcel.setDataPosition(0);
+        try {
+            MotionEvent.CREATOR.createFromParcel(parcel);
+            fail("deserialized invalid parcel");
+        } catch (RuntimeException e) {
+            // Expected.
+        }
+    }
+
+    public void testReadFromParcelWithInvalidSampleSize() {
+        Parcel parcel = Parcel.obtain();
+        mMotionEvent2.writeToParcel(parcel, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
+
+        // Move to sample count.
+        parcel.setDataPosition(2 * 4);
+        parcel.writeInt(0x000f0000);
+
+        parcel.setDataPosition(0);
+        try {
+            MotionEvent.CREATOR.createFromParcel(parcel);
+            fail("deserialized invalid parcel");
+        } catch (RuntimeException e) {
+            // Expected.
+        }
+    }
+
     public void testToString() {
         // make sure this method never throw exception.
         mMotionEvent2.toString();
diff --git a/tests/tests/view/src/android/view/cts/ScaleGestureDetectorCtsActivity.java b/tests/tests/view/src/android/view/cts/ScaleGestureDetectorCtsActivity.java
new file mode 100644
index 0000000..606d536
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ScaleGestureDetectorCtsActivity.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 android.view.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.ScaleGestureDetector;
+import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
+
+public class ScaleGestureDetectorCtsActivity extends Activity {
+
+    private ScaleGestureDetector mScaleGestureDetector;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        mScaleGestureDetector = new ScaleGestureDetector(this, new SimpleOnScaleGestureListener(),
+                new Handler());
+    }
+
+    public ScaleGestureDetector getScaleGestureDetector() {
+        return mScaleGestureDetector;
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/ScaleGestureDetectorTest.java b/tests/tests/view/src/android/view/cts/ScaleGestureDetectorTest.java
new file mode 100644
index 0000000..b8ba200
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/ScaleGestureDetectorTest.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.view.cts;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.ScaleGestureDetector;
+import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
+
+public class ScaleGestureDetectorTest extends
+        ActivityInstrumentationTestCase2<ScaleGestureDetectorCtsActivity> {
+
+    private ScaleGestureDetector mScaleGestureDetector;
+    private ScaleGestureDetectorCtsActivity mActivity;
+    private Context mContext;
+
+    public ScaleGestureDetectorTest() {
+        super("com.android.cts.view", ScaleGestureDetectorCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+        mScaleGestureDetector = mActivity.getScaleGestureDetector();
+        mContext = getInstrumentation().getTargetContext();
+    }
+
+    @UiThreadTest
+    public void testConstructor() {
+        new ScaleGestureDetector(
+                mContext, new SimpleOnScaleGestureListener(), new Handler(Looper.getMainLooper()));
+        new ScaleGestureDetector(mContext, new SimpleOnScaleGestureListener());
+    }
+
+    public void testAccessStylusScaleEnabled() {
+        assertTrue(mScaleGestureDetector.isStylusScaleEnabled());
+        mScaleGestureDetector.setStylusScaleEnabled(true);
+
+        mScaleGestureDetector.setStylusScaleEnabled(false);
+        assertFalse(mScaleGestureDetector.isStylusScaleEnabled());
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/view/src/android/view/cts/SearchEventActivity.java b/tests/tests/view/src/android/view/cts/SearchEventActivity.java
new file mode 100644
index 0000000..6cc8c85
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/SearchEventActivity.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.view.cts;
+
+import com.android.cts.view.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.SearchEvent;
+
+public class SearchEventActivity extends Activity {
+
+    private static SearchEvent mSearchEvent;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.windowstub_layout);
+    }
+
+    @Override
+    public boolean onSearchRequested() {
+        mSearchEvent = getSearchEvent();
+        return true;
+    }
+
+    public SearchEvent getTestSearchEvent() {
+        return mSearchEvent;
+    }
+
+    public void reset() {
+        mSearchEvent = null;
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/SearchEventTest.java b/tests/tests/view/src/android/view/cts/SearchEventTest.java
new file mode 100644
index 0000000..4df52a1
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/SearchEventTest.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.view.cts;
+
+import com.android.cts.view.R;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.SearchEvent;
+
+public class SearchEventTest extends ActivityInstrumentationTestCase2<SearchEventActivity> {
+
+    private Instrumentation mInstrumentation;
+    private SearchEventActivity mActivity;
+
+    public SearchEventTest() {
+        super(SearchEventActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mActivity = getActivity();
+    }
+
+    public void testTest() throws Exception {
+        mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_SEARCH);
+        SearchEvent se = mActivity.getTestSearchEvent();
+        assertNotNull(se);
+        InputDevice id = se.getInputDevice();
+        assertNotNull(id);
+        assertEquals(-1, id.getId());
+    }
+}
diff --git a/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java b/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java
index 38e9130..5fe4aea 100644
--- a/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewConfigurationTest.java
@@ -42,11 +42,17 @@
         ViewConfiguration.getTouchSlop();
         ViewConfiguration.getWindowTouchSlop();
         ViewConfiguration.getMinimumFlingVelocity();
+        ViewConfiguration.getMaximumFlingVelocity();
         ViewConfiguration.getMaximumDrawingCacheSize();
         ViewConfiguration.getZoomControlsTimeout();
         ViewConfiguration.getGlobalActionKeyTimeout();
         ViewConfiguration.getScrollFriction();
+        ViewConfiguration.getScrollBarFadeDuration();
+        ViewConfiguration.getScrollDefaultDelay();
         ViewConfiguration.getDoubleTapTimeout();
+        ViewConfiguration.getKeyRepeatTimeout();
+        ViewConfiguration.getKeyRepeatDelay();
+        ViewConfiguration.getDefaultActionModeHideDuration();
     }
 
     @SuppressWarnings("deprecation")
@@ -61,9 +67,14 @@
         vc.getScaledEdgeSlop();
         vc.getScaledFadingEdgeLength();
         vc.getScaledMaximumDrawingCacheSize();
+        vc.getScaledMaximumFlingVelocity();
         vc.getScaledMinimumFlingVelocity();
+        vc.getScaledOverflingDistance();
+        vc.getScaledOverscrollDistance();
+        vc.getScaledPagingTouchSlop();
         vc.getScaledScrollBarSize();
         vc.getScaledTouchSlop();
         vc.getScaledWindowTouchSlop();
+        vc.hasPermanentMenuKey();
     }
 }
diff --git a/tests/tests/view/src/android/view/cts/ViewGroupTest.java b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
index f1064a7..7fc5579 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroupTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroupTest.java
@@ -16,7 +16,7 @@
 
 package android.view.cts;
 
-import com.android.internal.util.XmlUtils;
+import android.view.cts.util.XmlUtils;
 
 
 import android.content.Context;
@@ -36,8 +36,12 @@
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.SparseArray;
+import android.view.ActionMode;
 import android.view.Display;
 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.view.ViewGroup;
@@ -454,7 +458,7 @@
         MockTextView textView = new MockTextView(mContext);
         vg.addView(textView);
         vg.requestChildFocus(textView, null);
-        textView.setFrame(1, 1, 100, 100);
+        textView.layout(1, 1, 100, 100);
 
         assertTrue(vg.dispatchKeyEvent(event));
     }
@@ -525,7 +529,7 @@
         d.getMetrics(metrics);
         int screenWidth = metrics.widthPixels;
         int screenHeight = metrics.heightPixels;
-        vg.setFrame(0, 0, screenWidth, screenHeight);
+        vg.layout(0, 0, screenWidth, screenHeight);
         vg.setLayoutParams(new ViewGroup.LayoutParams(screenWidth, screenHeight));
 
         MockTextView textView = new MockTextView(mContext);
@@ -550,7 +554,7 @@
         assertFalse(vg.dispatchTouchEvent(me));
         assertNull(mMotionEvent);
 
-        textView.setFrame(0, 0, screenWidth, screenHeight);
+        textView.layout(0, 0, screenWidth, screenHeight);
         assertTrue(vg.dispatchTouchEvent(me));
         assertSame(me, mMotionEvent);
     }
@@ -564,7 +568,7 @@
 
         MockTextView textView = new MockTextView(mContext);
         vg.addView(textView);
-        textView.setFrame(1, 1, 100, 100);
+        textView.layout(1, 1, 100, 100);
         vg.requestChildFocus(textView, null);
         assertTrue(vg.dispatchTrackballEvent(me));
     }
@@ -575,7 +579,7 @@
         assertFalse(vg.dispatchUnhandledMove(textView, View.FOCUS_DOWN));
 
         vg.addView(textView);
-        textView.setFrame(1, 1, 100, 100);
+        textView.layout(1, 1, 100, 100);
         vg.requestChildFocus(textView, null);
         assertTrue(vg.dispatchUnhandledMove(textView, View.FOCUS_DOWN));
     }
@@ -765,13 +769,13 @@
         MockViewGroup vg = new MockViewGroup(mContext);
         MockTextView textView = new MockTextView(mContext);
 
-        textView.setFrame(1, 1, 100, 100);
+        textView.layout(1, 1, 100, 100);
         Rect rect = new Rect(1, 1, 50, 50);
         Point p = new Point();
         assertFalse(vg.getChildVisibleRect(textView, rect, p));
 
-        textView.setFrame(0, 0, 0, 0);
-        vg.setFrame(20, 20, 60, 60);
+        textView.layout(0, 0, 0, 0);
+        vg.layout(20, 20, 60, 60);
         rect = new Rect(10, 10, 40, 40);
         p = new Point();
         assertTrue(vg.getChildVisibleRect(textView, rect, p));
@@ -994,7 +998,7 @@
             // expected
         }
         vg.addView(textView);
-        textView.setFrame(1, 2, 3, 4);
+        textView.layout(1, 2, 3, 4);
         Rect rect = new Rect();
         vg.offsetDescendantRectToMyCoords(textView, rect);
         assertEquals(2, rect.bottom);
@@ -1005,7 +1009,7 @@
 
     public void testOffsetRectIntoDescendantCoords() {
         MockViewGroup vg = new MockViewGroup(mContext);
-        vg.setFrame(10, 20, 30, 40);
+        vg.layout(10, 20, 30, 40);
         MockTextView textView = new MockTextView(mContext);
 
         try {
@@ -1015,7 +1019,7 @@
         } catch (RuntimeException e) {
             // expected
         }
-        textView.setFrame(1, 2, 3, 4);
+        textView.layout(1, 2, 3, 4);
         vg.addView(textView);
 
         Rect rect = new Rect(5, 6, 7, 8);
@@ -1372,8 +1376,8 @@
 
         MockViewGroup vg = new MockViewGroup(mContext);
         MockTextView textView = new MockTextView(mContext);
-        textView.setFrame(1, 2, 30, 40);
-        vg.setFrame(1, 1, 100, 200);
+        textView.layout(1, 2, 30, 40);
+        vg.layout(1, 1, 100, 200);
         vg.setClipChildren(true);
 
         MockCanvas canvas = new MockCanvas(bitmap);
@@ -1430,7 +1434,7 @@
         final int frameRight = 100;
         final int frameBottom = 200;
         MockViewGroup vg = new MockViewGroup(mContext);
-        vg.setFrame(frameLeft, frameTop, frameRight, frameBottom);
+        vg.layout(frameLeft, frameTop, frameRight, frameBottom);
 
         vg.setClipToPadding(true);
         MockCanvas canvas = new MockCanvas();
@@ -1660,6 +1664,166 @@
         assertFalse(vg.isGetChildStaticTransformationCalled);
     }
 
+    public void testStartActionModeForChildRespectsSubclassModeOnPrimary() {
+        MockViewGroupSubclass vgParent = new MockViewGroupSubclass(mContext);
+        MockViewGroupSubclass vg = new MockViewGroupSubclass(mContext);
+        vg.shouldReturnOwnTypelessActionMode = true;
+        vgParent.addView(vg);
+        MockTextView textView = new MockTextView(mContext);
+        vg.addView(textView);
+
+        textView.startActionMode(NO_OP_ACTION_MODE_CALLBACK, ActionMode.TYPE_PRIMARY);
+
+        assertTrue(vg.isStartActionModeForChildTypedCalled);
+        assertTrue(vg.isStartActionModeForChildTypelessCalled);
+        // Call should not bubble up as we have an intercepting implementation.
+        assertFalse(vgParent.isStartActionModeForChildTypedCalled);
+    }
+
+    public void testStartActionModeForChildIgnoresSubclassModeOnFloating() {
+        MockViewGroupSubclass vgParent = new MockViewGroupSubclass(mContext);
+        MockViewGroupSubclass vg = new MockViewGroupSubclass(mContext);
+        vg.shouldReturnOwnTypelessActionMode = true;
+        vgParent.addView(vg);
+        MockTextView textView = new MockTextView(mContext);
+        vg.addView(textView);
+
+        textView.startActionMode(NO_OP_ACTION_MODE_CALLBACK, ActionMode.TYPE_FLOATING);
+
+        assertTrue(vg.isStartActionModeForChildTypedCalled);
+        assertFalse(vg.isStartActionModeForChildTypelessCalled);
+        // Call should bubble up as we have a floating type.
+        assertTrue(vgParent.isStartActionModeForChildTypedCalled);
+    }
+
+    public void testStartActionModeForChildTypedBubblesUpToParent() {
+        MockViewGroupSubclass vgParent = new MockViewGroupSubclass(mContext);
+        MockViewGroupSubclass vg = new MockViewGroupSubclass(mContext);
+        vgParent.addView(vg);
+        MockTextView textView = new MockTextView(mContext);
+        vg.addView(textView);
+
+        textView.startActionMode(NO_OP_ACTION_MODE_CALLBACK, ActionMode.TYPE_FLOATING);
+
+        assertTrue(vg.isStartActionModeForChildTypedCalled);
+        assertTrue(vgParent.isStartActionModeForChildTypedCalled);
+    }
+
+    public void testStartActionModeForChildTypelessBubblesUpToParent() {
+        MockViewGroupSubclass vgParent = new MockViewGroupSubclass(mContext);
+        MockViewGroupSubclass vg = new MockViewGroupSubclass(mContext);
+        vgParent.addView(vg);
+        MockTextView textView = new MockTextView(mContext);
+        vg.addView(textView);
+
+        textView.startActionMode(NO_OP_ACTION_MODE_CALLBACK);
+
+        assertTrue(vg.isStartActionModeForChildTypedCalled);
+        assertTrue(vg.isStartActionModeForChildTypelessCalled);
+        assertTrue(vgParent.isStartActionModeForChildTypedCalled);
+    }
+
+    private static final ActionMode.Callback NO_OP_ACTION_MODE_CALLBACK =
+            new ActionMode.Callback() {
+                @Override
+                public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+                    return false;
+                }
+
+                @Override
+                public void onDestroyActionMode(ActionMode mode) {}
+
+                @Override
+                public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+                    return false;
+                }
+
+                @Override
+                public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+                    return false;
+                }
+            };
+
+    private static final ActionMode NO_OP_ACTION_MODE =
+            new ActionMode() {
+                @Override
+                public void setTitle(CharSequence title) {}
+
+                @Override
+                public void setTitle(int resId) {}
+
+                @Override
+                public void setSubtitle(CharSequence subtitle) {}
+
+                @Override
+                public void setSubtitle(int resId) {}
+
+                @Override
+                public void setCustomView(View view) {}
+
+                @Override
+                public void invalidate() {}
+
+                @Override
+                public void finish() {}
+
+                @Override
+                public Menu getMenu() {
+                    return null;
+                }
+
+                @Override
+                public CharSequence getTitle() {
+                    return null;
+                }
+
+                @Override
+                public CharSequence getSubtitle() {
+                    return null;
+                }
+
+                @Override
+                public View getCustomView() {
+                    return null;
+                }
+
+                @Override
+                public MenuInflater getMenuInflater() {
+                    return null;
+                }
+            };
+
+    private static class MockViewGroupSubclass extends ViewGroup {
+        boolean isStartActionModeForChildTypedCalled = false;
+        boolean isStartActionModeForChildTypelessCalled = false;
+        boolean shouldReturnOwnTypelessActionMode = false;
+
+        public MockViewGroupSubclass(Context context) {
+            super(context);
+        }
+
+        @Override
+        public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) {
+            isStartActionModeForChildTypelessCalled = true;
+            if (shouldReturnOwnTypelessActionMode) {
+                return NO_OP_ACTION_MODE;
+            }
+            return super.startActionModeForChild(originalView, callback);
+        }
+
+        @Override
+        public ActionMode startActionModeForChild(
+                View originalView, ActionMode.Callback callback, int type) {
+            isStartActionModeForChildTypedCalled = true;
+            return super.startActionModeForChild(originalView, callback, type);
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int l, int t, int r, int b) {
+            // no-op
+        }
+    }
+
     static public int resetRtlPropertiesCount;
     static public int resetResolvedLayoutDirectionCount;
     static public int resetResolvedTextDirectionCount;
@@ -1747,11 +1911,6 @@
         }
 
         @Override
-        public boolean setFrame(int l, int t, int r, int b) {
-            return super.setFrame(l, t, r, b);
-        }
-
-        @Override
         public void dispatchRestoreInstanceState(
                 SparseArray<Parcelable> container) {
             isDispatchRestoreInstanceStateCalled = true;
@@ -1781,11 +1940,6 @@
         }
 
         @Override
-        public boolean gatherTransparentRegion(Region region) {
-            return false;
-        }
-
-        @Override
         public boolean dispatchTouchEvent(MotionEvent event) {
             super.dispatchTouchEvent(event);
             return true;
@@ -1998,21 +2152,6 @@
         }
 
         @Override
-        public boolean setFrame(int left, int top, int right, int bottom) {
-            return super.setFrame(left, top, right, bottom);
-        }
-
-        @Override
-        public boolean isChildrenDrawnWithCacheEnabled() {
-            return super.isChildrenDrawnWithCacheEnabled();
-        }
-
-        @Override
-        public void setChildrenDrawnWithCacheEnabled(boolean enabled) {
-            super.setChildrenDrawnWithCacheEnabled(enabled);
-        }
-
-        @Override
         public void measureChild(View child, int parentWidthMeasureSpec,
                 int parentHeightMeasureSpec) {
             measureChildCalledTime++;
@@ -2163,6 +2302,21 @@
             super.resetResolvedDrawables();
             resetResolvedDrawablesCount++;
         }
+
+        @Override
+        public boolean setFrame(int left, int top, int right, int bottom) {
+            return super.setFrame(left, top, right, bottom);
+        }
+
+        @Override
+        public void setChildrenDrawnWithCacheEnabled(boolean enabled) {
+            super.setChildrenDrawnWithCacheEnabled(enabled);
+        }
+
+        @Override
+        public boolean isChildrenDrawnWithCacheEnabled() {
+            return super.isChildrenDrawnWithCacheEnabled();
+        }
     }
 
     static class MockView2 extends View {
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 ded715a..5dadffd 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 java.io.IOException;
+import com.android.cts.view.R;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -27,10 +27,9 @@
 import android.util.AttributeSet;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
+import android.view.cts.util.XmlUtils;
 
-import com.android.cts.view.R;
-import com.android.internal.util.XmlUtils;
-
+import java.io.IOException;
 
 public class ViewGroup_LayoutParamsTest extends AndroidTestCase {
     private ViewGroup.LayoutParams mLayoutParams;
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 d3fed0d..e53cba2 100644
--- a/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewGroup_MarginLayoutParamsTest.java
@@ -16,17 +16,16 @@
 
 package android.view.cts;
 
+import com.android.cts.view.R;
+
 import android.content.Context;
 import android.content.res.XmlResourceParser;
 import android.test.InstrumentationTestCase;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.MarginLayoutParams;
-
+import android.view.cts.util.XmlUtils;
 import android.widget.LinearLayout;
-import com.android.internal.util.XmlUtils;
-import com.android.cts.view.R;
-
 
 public class ViewGroup_MarginLayoutParamsTest extends InstrumentationTestCase {
 
@@ -90,7 +89,9 @@
     public void testSetMarginsRelative() {
         // create a new MarginLayoutParams instance
         mMarginLayoutParams = new ViewGroup.MarginLayoutParams(320, 480);
-        mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+        mMarginLayoutParams.setMargins(0, 30, 0, 140);
+        mMarginLayoutParams.setMarginStart(20);
+        mMarginLayoutParams.setMarginEnd(120);
         assertEquals(20, mMarginLayoutParams.getMarginStart());
         assertEquals(30, mMarginLayoutParams.topMargin);
         assertEquals(120, mMarginLayoutParams.getMarginEnd());
@@ -121,7 +122,9 @@
         assertEquals(false, mMarginLayoutParams.isMarginRelative());
 
         // LTR / relative margin case
-        mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+        mMarginLayoutParams.setMargins(0, 30, 0, 140);
+        mMarginLayoutParams.setMarginStart(20);
+        mMarginLayoutParams.setMarginEnd(120);
         vg.setLayoutParams(mMarginLayoutParams);
 
         assertEquals(20, mMarginLayoutParams.getMarginStart());
@@ -152,7 +155,9 @@
         assertEquals(false, mMarginLayoutParams.isMarginRelative());
 
         // RTL / relative margin case
-        mMarginLayoutParams.setMarginsRelative(20, 30, 120, 140);
+        mMarginLayoutParams.setMargins(0, 30, 0, 140);
+        mMarginLayoutParams.setMarginStart(20);
+        mMarginLayoutParams.setMarginEnd(120);
         vg.setLayoutParams(mMarginLayoutParams);
 
         assertEquals(20, mMarginLayoutParams.getMarginStart());
diff --git a/tests/tests/view/src/android/view/cts/ViewStubTest.java b/tests/tests/view/src/android/view/cts/ViewStubTest.java
index 53e251a..c9cd44b 100644
--- a/tests/tests/view/src/android/view/cts/ViewStubTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewStubTest.java
@@ -18,8 +18,6 @@
 
 import com.android.cts.view.R;
 
-import dalvik.annotation.KnownFailure;
-
 import org.xmlpull.v1.XmlPullParser;
 
 import android.app.Activity;
@@ -157,13 +155,16 @@
 
     public void testAccessInflatedId() {
         ViewStub viewStub = new ViewStub(mContext);
-        assertEquals(0, viewStub.getInflatedId());
+        assertEquals("Default ViewStub inflated ID is View.NO_ID",
+                View.NO_ID, viewStub.getInflatedId());
 
         viewStub.setInflatedId(R.id.inflated_id);
-        assertEquals(R.id.inflated_id, viewStub.getInflatedId());
+        assertEquals("Set ViewStub inflated ID to package resource ID",
+                R.id.inflated_id, viewStub.getInflatedId());
 
-        viewStub.setInflatedId(-1);
-        assertEquals(-1, viewStub.getInflatedId());
+        viewStub.setInflatedId(View.NO_ID);
+        assertEquals("Set ViewStub inflated ID to View.NO_ID",
+                View.NO_ID, viewStub.getInflatedId());
     }
 
     @UiThreadTest
diff --git a/tests/tests/view/src/android/view/cts/ViewTest.java b/tests/tests/view/src/android/view/cts/ViewTest.java
index ffbec1e..2c5b30a 100644
--- a/tests/tests/view/src/android/view/cts/ViewTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTest.java
@@ -16,28 +16,26 @@
 
 package android.view.cts;
 
-import android.content.res.ColorStateList;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.ColorFilter;
-import android.graphics.PorterDuff;
-
-import android.os.Bundle;
 import com.android.cts.view.R;
 import com.android.internal.view.menu.ContextMenuBuilder;
-import com.google.android.collect.Lists;
 
 import android.content.Context;
+import android.content.res.ColorStateList;
 import android.content.res.Resources;
 import android.content.res.XmlResourceParser;
 import android.cts.util.PollingCheck;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
 import android.graphics.Point;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.StateListDrawable;
+import android.os.Bundle;
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.os.Vibrator;
@@ -56,12 +54,15 @@
 import android.view.HapticFeedbackConstants;
 import android.view.InputDevice;
 import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
 import android.view.MotionEvent;
 import android.view.SoundEffectConstants;
 import android.view.TouchDelegate;
 import android.view.View;
 import android.view.View.BaseSavedState;
 import android.view.View.OnClickListener;
+import android.view.View.OnContextClickListener;
 import android.view.View.OnCreateContextMenuListener;
 import android.view.View.OnFocusChangeListener;
 import android.view.View.OnKeyListener;
@@ -248,6 +249,31 @@
         assertSame(parent, view.getParent());
     }
 
+    public void testAccessScrollIndicators() {
+        View view = mActivity.findViewById(R.id.viewlayout_root);
+
+        assertEquals(View.SCROLL_INDICATOR_LEFT | View.SCROLL_INDICATOR_RIGHT,
+                view.getScrollIndicators());
+    }
+
+    public void testSetScrollIndicators() {
+        View view = new View(mActivity);
+
+        view.setScrollIndicators(0);
+        assertEquals(0, view.getScrollIndicators());
+
+        view.setScrollIndicators(View.SCROLL_INDICATOR_LEFT | View.SCROLL_INDICATOR_RIGHT);
+        assertEquals(View.SCROLL_INDICATOR_LEFT | View.SCROLL_INDICATOR_RIGHT,
+                view.getScrollIndicators());
+
+        view.setScrollIndicators(View.SCROLL_INDICATOR_TOP, View.SCROLL_INDICATOR_TOP);
+        assertEquals(View.SCROLL_INDICATOR_LEFT | View.SCROLL_INDICATOR_RIGHT
+                        | View.SCROLL_INDICATOR_TOP, view.getScrollIndicators());
+
+        view.setScrollIndicators(0, view.getScrollIndicators());
+        assertEquals(0, view.getScrollIndicators());
+    }
+
     public void testFindViewById() {
         View parent = mActivity.findViewById(R.id.viewlayout_root);
         assertSame(parent, parent.findViewById(R.id.viewlayout_root));
@@ -398,7 +424,9 @@
         assertTrue(view.isLayoutRequested());
 
         view.setParent(mMockParent);
-        assertFalse(mMockParent.hasRequestLayout());
+        assertTrue(mMockParent.hasRequestLayout());
+
+        mMockParent.reset();
         view.requestLayout();
         assertTrue(view.isLayoutRequested());
         assertTrue(mMockParent.hasRequestLayout());
@@ -856,6 +884,18 @@
         assertFalse(view.isClickable());
     }
 
+    public void testAccessContextClickable() {
+        View view = new View(mActivity);
+
+        assertFalse(view.isContextClickable());
+
+        view.setContextClickable(true);
+        assertTrue(view.isContextClickable());
+
+        view.setContextClickable(false);
+        assertFalse(view.isContextClickable());
+    }
+
     public void testGetContextMenuInfo() {
         MockView view = new MockView(mActivity);
 
@@ -1104,8 +1144,8 @@
         mockView2.setParent(mMockParent);
 
         mMockParent.dispatchSetSelected(true);
-        assertFalse(mockView1.isSelected());
-        assertFalse(mockView2.isSelected());
+        assertTrue(mockView1.isSelected());
+        assertTrue(mockView2.isSelected());
 
         mMockParent.dispatchSetSelected(false);
         assertFalse(mockView1.isSelected());
@@ -1128,8 +1168,8 @@
         mockView2.setParent(mMockParent);
 
         mMockParent.dispatchSetPressed(true);
-        assertFalse(mockView1.isPressed());
-        assertFalse(mockView2.isPressed());
+        assertTrue(mockView1.isPressed());
+        assertTrue(mockView2.isPressed());
 
         mMockParent.dispatchSetPressed(false);
         assertFalse(mockView1.isPressed());
@@ -1216,7 +1256,7 @@
         assertFalse(view.fitSystemWindows(insets));
         assertFalse(view.fitSystemWindows(null));
 
-        view = new MockView(mActivity, attrs, com.android.internal.R.attr.fitsSystemWindows);
+        view = new MockView(mActivity, attrs, android.R.attr.fitsSystemWindows);
         assertFalse(view.fitSystemWindows(insets));
         assertFalse(view.fitSystemWindows(null));
     }
@@ -1290,6 +1330,31 @@
         assertTrue(view.isLongClickable());
     }
 
+    public void testPerformContextClick() {
+        MockView view = new MockView(mActivity);
+        view.setParent(mMockParent);
+        OnContextClickListenerImpl listener = new OnContextClickListenerImpl();
+
+        view.setOnContextClickListener(listener);
+        assertFalse(listener.hasOnContextClick());
+
+        assertTrue(view.performContextClick());
+        assertTrue(listener.hasOnContextClick());
+        assertSame(view, listener.getLastViewContextClicked());
+    }
+
+    public void testSetOnContextClickListener() {
+        MockView view = new MockView(mActivity);
+        view.setParent(mMockParent);
+
+        assertFalse(view.performContextClick());
+        assertFalse(view.isContextClickable());
+
+        view.setOnContextClickListener(new OnContextClickListenerImpl());
+        assertTrue(view.performContextClick());
+        assertTrue(view.isContextClickable());
+    }
+
     public void testAccessOnFocusChangeListener() {
         View view = new View(mActivity);
         OnFocusChangeListener listener = new OnFocusChangeListenerImpl();
@@ -2077,24 +2142,24 @@
         assertEquals(viewId, container.keyAt(0));
 
         container.clear();
-        container.put(viewId, new BaseSavedState(BaseSavedState.EMPTY_STATE));
+        container.put(viewId, new android.graphics.Rect());
         try {
             view.restoreHierarchyState(container);
-            fail("should throw IllegalArgumentException");
+            fail("Parcelable state must be an AbsSaveState, should throw IllegalArgumentException");
         } catch (IllegalArgumentException e) {
             // expected
         }
 
         try {
             view.restoreHierarchyState(null);
-            fail("should throw NullPointerException");
+            fail("Cannot pass null to restoreHierarchyState(), should throw NullPointerException");
         } catch (NullPointerException e) {
             // expected
         }
 
         try {
             view.saveHierarchyState(null);
-            fail("should throw NullPointerException");
+            fail("Cannot pass null to saveHierarchyState(), should throw NullPointerException");
         } catch (NullPointerException e) {
             // expected
         }
@@ -2434,7 +2499,6 @@
         assertFalse(view.hasCalledDrawableStateChanged());
         view.setPressed(true);
         assertTrue(view.hasCalledDrawableStateChanged());
-        assertFalse(view.hasCalledOnCreateDrawableState());
         assertTrue(Arrays.equals(MockView.getPressedEnabledStateSet(), view.getDrawableState()));
         assertTrue(view.hasCalledOnCreateDrawableState());
 
@@ -2445,7 +2509,6 @@
         view.refreshDrawableState();
         assertTrue(view.hasCalledDrawableStateChanged());
         assertTrue(mMockParent.hasChildDrawableStateChanged());
-        assertFalse(view.hasCalledOnCreateDrawableState());
         assertTrue(Arrays.equals(MockView.getPressedEnabledStateSet(), view.getDrawableState()));
         assertTrue(view.hasCalledOnCreateDrawableState());
     }
@@ -2992,16 +3055,13 @@
 
     @UiThreadTest
     public void testScrollbarStyle() {
-        MockView view = (MockView) mActivity.findViewById(R.id.mock_view);
+        MockView view = (MockView) mActivity.findViewById(R.id.scroll_view);
         Bitmap bitmap = Bitmap.createBitmap(200, 300, Bitmap.Config.RGB_565);
         BitmapDrawable d = new BitmapDrawable(bitmap);
         view.setBackgroundDrawable(d);
         view.setHorizontalFadingEdgeEnabled(true);
         view.setVerticalFadingEdgeEnabled(true);
 
-        view.setHorizontalScrollBarEnabled(true);
-        view.setVerticalScrollBarEnabled(true);
-        view.initializeScrollbars(mActivity.obtainStyledAttributes(android.R.styleable.View));
         assertTrue(view.isHorizontalScrollBarEnabled());
         assertTrue(view.isVerticalScrollBarEnabled());
         int verticalScrollBarWidth = view.getVerticalScrollbarWidth();
@@ -3111,9 +3171,30 @@
         assertEquals(fadingEdgeLength, view.getVerticalFadingEdgeLength());
     }
 
+    @UiThreadTest
+    public void testScrollIndicators() {
+        MockView view = (MockView) mActivity.findViewById(R.id.scroll_view);
+
+        assertEquals("Set indicators match those specified in XML",
+                View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM,
+                view.getScrollIndicators());
+
+        view.setScrollIndicators(0);
+        assertEquals("Cleared indicators", 0, view.getScrollIndicators());
+
+        view.setScrollIndicators(View.SCROLL_INDICATOR_START | View.SCROLL_INDICATOR_RIGHT);
+        assertEquals("Set start and right indicators",
+                View.SCROLL_INDICATOR_START | View.SCROLL_INDICATOR_RIGHT,
+                view.getScrollIndicators());
+
+    }
+
     public void testOnStartAndFinishTemporaryDetach() throws Throwable {
         final MockListView listView = new MockListView(mActivity);
-        List<String> items = Lists.newArrayList("1", "2", "3");
+        List<String> items = new ArrayList<>();
+        items.add("1");
+        items.add("2");
+        items.add("3");
         final Adapter<String> adapter = new Adapter<String>(mActivity, 0, items);
 
         runTestOnUiThread(new Runnable() {
@@ -3367,6 +3448,156 @@
                 bg.hasCalledSetTint());
     }
 
+    public void testStartActionModeWithParent() {
+        View view = new View(mActivity);
+        MockViewGroup parent = new MockViewGroup(mActivity);
+        parent.addView(view);
+
+        ActionMode mode = view.startActionMode(null);
+
+        assertNotNull(mode);
+        assertEquals(NO_OP_ACTION_MODE, mode);
+        assertTrue(parent.isStartActionModeForChildCalled);
+        assertEquals(ActionMode.TYPE_PRIMARY, parent.startActionModeForChildType);
+    }
+
+    public void testStartActionModeWithoutParent() {
+        View view = new View(mActivity);
+
+        ActionMode mode = view.startActionMode(null);
+
+        assertNull(mode);
+    }
+
+    public void testStartActionModeTypedWithParent() {
+        View view = new View(mActivity);
+        MockViewGroup parent = new MockViewGroup(mActivity);
+        parent.addView(view);
+
+        ActionMode mode = view.startActionMode(null, ActionMode.TYPE_FLOATING);
+
+        assertNotNull(mode);
+        assertEquals(NO_OP_ACTION_MODE, mode);
+        assertTrue(parent.isStartActionModeForChildCalled);
+        assertEquals(ActionMode.TYPE_FLOATING, parent.startActionModeForChildType);
+    }
+
+    public void testStartActionModeTypedWithoutParent() {
+        View view = new View(mActivity);
+
+        ActionMode mode = view.startActionMode(null, ActionMode.TYPE_FLOATING);
+
+        assertNull(mode);
+    }
+
+    private static class MockViewGroup extends ViewGroup {
+        boolean isStartActionModeForChildCalled = false;
+        int startActionModeForChildType = ActionMode.TYPE_PRIMARY;
+
+        public MockViewGroup(Context context) {
+            super(context);
+        }
+
+        @Override
+        public ActionMode startActionModeForChild(View originalView, ActionMode.Callback callback) {
+            isStartActionModeForChildCalled = true;
+            startActionModeForChildType = ActionMode.TYPE_PRIMARY;
+            return NO_OP_ACTION_MODE;
+        }
+
+        @Override
+        public ActionMode startActionModeForChild(
+                View originalView, ActionMode.Callback callback, int type) {
+            isStartActionModeForChildCalled = true;
+            startActionModeForChildType = type;
+            return NO_OP_ACTION_MODE;
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int l, int t, int r, int b) {
+            // no-op
+        }
+    }
+
+    private static final ActionMode NO_OP_ACTION_MODE =
+            new ActionMode() {
+                @Override
+                public void setTitle(CharSequence title) {}
+
+                @Override
+                public void setTitle(int resId) {}
+
+                @Override
+                public void setSubtitle(CharSequence subtitle) {}
+
+                @Override
+                public void setSubtitle(int resId) {}
+
+                @Override
+                public void setCustomView(View view) {}
+
+                @Override
+                public void invalidate() {}
+
+                @Override
+                public void finish() {}
+
+                @Override
+                public Menu getMenu() {
+                    return null;
+                }
+
+                @Override
+                public CharSequence getTitle() {
+                    return null;
+                }
+
+                @Override
+                public CharSequence getSubtitle() {
+                    return null;
+                }
+
+                @Override
+                public View getCustomView() {
+                    return null;
+                }
+
+                @Override
+                public MenuInflater getMenuInflater() {
+                    return null;
+                }
+            };
+
+    public void testTranslationSetter() {
+        View view = new View(mActivity);
+        float offset = 10.0f;
+        view.setTranslationX(offset);
+        view.setTranslationY(offset);
+        view.setTranslationZ(offset);
+        view.setElevation(offset);
+
+        assertEquals("Incorrect translationX", offset, view.getTranslationX());
+        assertEquals("Incorrect translationY", offset, view.getTranslationY());
+        assertEquals("Incorrect translationZ", offset, view.getTranslationZ());
+        assertEquals("Incorrect elevation", offset, view.getElevation());
+    }
+
+    public void testXYZ() {
+        View view = new View(mActivity);
+        float offset = 10.0f;
+        float start = 15.0f;
+        view.setTranslationX(offset);
+        view.setLeft((int) start);
+        view.setTranslationY(offset);
+        view.setTop((int) start);
+        view.setTranslationZ(offset);
+        view.setElevation(start);
+
+        assertEquals("Incorrect X value", offset + start, view.getX());
+        assertEquals("Incorrect Y value", offset + start, view.getY());
+        assertEquals("Incorrect Z value", offset + start, view.getZ());
+    }
+
     private static class MockDrawable extends Drawable {
         private boolean mCalledSetTint = false;
 
@@ -3445,7 +3676,7 @@
         }
     }
 
-    private final static class MockViewParent extends View implements ViewParent {
+    private final static class MockViewParent extends ViewGroup {
         private boolean mHasClearChildFocus = false;
         private boolean mHasRequestLayout = false;
         private boolean mHasCreateContextMenu = false;
@@ -3485,12 +3716,12 @@
         }
 
         @Override
-        protected void dispatchSetPressed(boolean pressed) {
+        public void dispatchSetPressed(boolean pressed) {
             super.dispatchSetPressed(pressed);
         }
 
         @Override
-        protected void dispatchSetSelected(boolean selected) {
+        public void dispatchSetSelected(boolean selected) {
             super.dispatchSetSelected(selected);
         }
 
@@ -3523,23 +3754,15 @@
             return false;
         }
 
+        @Override
+        protected void onLayout(boolean changed, int l, int t, int r, int b) {
+
+        }
+
         public boolean hasGetChildVisibleRect() {
             return mHasGetChildVisibleRect;
         }
 
-        public void invalidateChild(View child, Rect r) {
-            mTempRect = new Rect(r);
-            mHasInvalidateChild = true;
-        }
-
-        public Rect getTempRect() {
-            return mTempRect;
-        }
-
-        public boolean hasInvalidateChild() {
-            return mHasInvalidateChild;
-        }
-
         public ViewParent invalidateChildInParent(int[] location, Rect r) {
             return null;
         }
@@ -3560,6 +3783,7 @@
 
         }
 
+        @Override
         public void requestLayout() {
             mHasRequestLayout = true;
         }
@@ -3582,6 +3806,11 @@
             return null;
         }
 
+        public ActionMode startActionModeForChild(View originalView,
+                ActionMode.Callback callback, int type) {
+            return null;
+        }
+
         public boolean hasShowContextMenuForChild() {
             return mHasShowContextMenuForChild;
         }
@@ -3757,6 +3986,30 @@
         }
     }
 
+    private static final class OnContextClickListenerImpl implements OnContextClickListener {
+        private boolean mHasContextClick = false;
+        private View mLastViewContextClicked;
+
+        public boolean hasOnContextClick() {
+            return mHasContextClick;
+        }
+
+        public void reset() {
+            mHasContextClick = false;
+            mLastViewContextClicked = null;
+        }
+
+        public boolean onContextClick(View v) {
+            mHasContextClick = true;
+            mLastViewContextClicked = v;
+            return true;
+        }
+
+        public View getLastViewContextClicked() {
+            return mLastViewContextClicked;
+        }
+    }
+
     private static final class OnFocusChangeListenerImpl implements OnFocusChangeListener {
         private boolean mHasOnFocusChange = false;
 
diff --git a/tests/tests/view/src/android/view/cts/ViewTreeObserverTest.java b/tests/tests/view/src/android/view/cts/ViewTreeObserverTest.java
index 1b21dac..7071808 100644
--- a/tests/tests/view/src/android/view/cts/ViewTreeObserverTest.java
+++ b/tests/tests/view/src/android/view/cts/ViewTreeObserverTest.java
@@ -25,8 +25,6 @@
 import android.test.TouchUtils;
 import android.view.View;
 import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.InternalInsetsInfo;
-import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
 import android.view.ViewTreeObserver.OnGlobalFocusChangeListener;
 import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.ViewTreeObserver.OnPreDrawListener;
@@ -155,22 +153,6 @@
         }.run();
     }
 
-    public void testAddOnComputeInternalInsetsListener() {
-        final View view1 = mActivity.findViewById(R.id.view1);
-        mViewTreeObserver = view1.getViewTreeObserver();
-
-        MockOnComputeInternalInsetsListener listener = new MockOnComputeInternalInsetsListener();
-        mViewTreeObserver.addOnComputeInternalInsetsListener(listener);
-    }
-
-    public void testRemoveOnComputeInternalInsetsListener() {
-        final View view1 = mActivity.findViewById(R.id.view1);
-        mViewTreeObserver = view1.getViewTreeObserver();
-
-        MockOnComputeInternalInsetsListener listener = new MockOnComputeInternalInsetsListener();
-        mViewTreeObserver.removeOnComputeInternalInsetsListener(listener);
-    }
-
     public void testDispatchOnGlobalLayout() {
         final LinearLayout layout = (LinearLayout) mActivity.findViewById(R.id.linearlayout);
         mViewTreeObserver = layout.getViewTreeObserver();
@@ -434,12 +416,6 @@
         }
     }
 
-    private class MockOnComputeInternalInsetsListener implements OnComputeInternalInsetsListener {
-        @Override
-        public void onComputeInternalInsets(InternalInsetsInfo inoutInfo) {
-        }
-    }
-
     private static class MockOnScrollChangedListener implements OnScrollChangedListener {
         private boolean mCalledOnScrollChanged = false;
 
diff --git a/tests/tests/view/src/android/view/cts/WindowTest.java b/tests/tests/view/src/android/view/cts/WindowTest.java
index 3c5386d..dcfcfb7 100644
--- a/tests/tests/view/src/android/view/cts/WindowTest.java
+++ b/tests/tests/view/src/android/view/cts/WindowTest.java
@@ -49,6 +49,7 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.MotionEvent;
+import android.view.SearchEvent;
 import android.view.Surface;
 import android.view.SurfaceHolder;
 import android.view.SurfaceView;
@@ -1105,6 +1106,10 @@
             return mIsOnPanelClosedCalled;
         }
 
+        public boolean onSearchRequested(SearchEvent searchEvent) {
+            return onSearchRequested();
+        }
+
         public boolean onSearchRequested() {
             return false;
         }
@@ -1113,6 +1118,11 @@
             return null;
         }
 
+        public ActionMode onWindowStartingActionMode(
+                ActionMode.Callback callback, int type) {
+            return null;
+        }
+
         public void onActionModeStarted(ActionMode mode) {
         }
 
diff --git a/tests/tests/view/src/android/view/cts/util/XmlUtils.java b/tests/tests/view/src/android/view/cts/util/XmlUtils.java
new file mode 100644
index 0000000..f1df4ff
--- /dev/null
+++ b/tests/tests/view/src/android/view/cts/util/XmlUtils.java
@@ -0,0 +1,1666 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.util.ArrayMap;
+import android.util.Base64;
+import android.util.Xml;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ProtocolException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+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 XmlUtils {
+
+    public static void skipCurrentTag(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+               && (type != XmlPullParser.END_TAG
+                       || parser.getDepth() > outerDepth)) {
+        }
+    }
+
+    public static final int
+    convertValueToList(CharSequence value, String[] options, int defaultValue)
+    {
+        if (null != value) {
+            for (int i = 0; i < options.length; i++) {
+                if (value.equals(options[i]))
+                    return i;
+            }
+        }
+
+        return defaultValue;
+    }
+
+    public static final boolean
+    convertValueToBoolean(CharSequence value, boolean defaultValue)
+    {
+        boolean result = false;
+
+        if (null == value)
+            return defaultValue;
+
+        if (value.equals("1")
+        ||  value.equals("true")
+        ||  value.equals("TRUE"))
+            result = true;
+
+        return result;
+    }
+
+    public static final int
+    convertValueToInt(CharSequence charSeq, int defaultValue)
+    {
+        if (null == charSeq)
+            return defaultValue;
+
+        String nm = charSeq.toString();
+
+        // XXX This code is copied from Integer.decode() so we don't
+        // have to instantiate an Integer!
+
+        int value;
+        int sign = 1;
+        int index = 0;
+        int len = nm.length();
+        int base = 10;
+
+        if ('-' == nm.charAt(0)) {
+            sign = -1;
+            index++;
+        }
+
+        if ('0' == nm.charAt(index)) {
+            //  Quick check for a zero by itself
+            if (index == (len - 1))
+                return 0;
+
+            char    c = nm.charAt(index + 1);
+
+            if ('x' == c || 'X' == c) {
+                index += 2;
+                base = 16;
+            } else {
+                index++;
+                base = 8;
+            }
+        }
+        else if ('#' == nm.charAt(index))
+        {
+            index++;
+            base = 16;
+        }
+
+        return Integer.parseInt(nm.substring(index), base) * sign;
+    }
+
+    public static int convertValueToUnsignedInt(String value, int defaultValue) {
+        if (null == value) {
+            return defaultValue;
+        }
+
+        return parseUnsignedIntAttribute(value);
+    }
+
+    public static int parseUnsignedIntAttribute(CharSequence charSeq) {
+        String  value = charSeq.toString();
+
+        long    bits;
+        int     index = 0;
+        int     len = value.length();
+        int     base = 10;
+
+        if ('0' == value.charAt(index)) {
+            //  Quick check for zero by itself
+            if (index == (len - 1))
+                return 0;
+
+            char    c = value.charAt(index + 1);
+
+            if ('x' == c || 'X' == c) {     //  check for hex
+                index += 2;
+                base = 16;
+            } else {                        //  check for octal
+                index++;
+                base = 8;
+            }
+        } else if ('#' == value.charAt(index)) {
+            index++;
+            base = 16;
+        }
+
+        return (int) Long.parseLong(value.substring(index), base);
+    }
+
+    /**
+     * Flatten a List into an output stream as XML.  The list can later be
+     * read back with readListXml().
+     *
+     * @param val The list to be flattened.
+     * @param out Where to write the XML data.
+     *
+     * @see #writeListXml(List, String, XmlSerializer)
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readListXml
+     */
+    public static final void writeListXml(List val, OutputStream out)
+    throws XmlPullParserException, IOException
+    {
+        XmlSerializer serializer = Xml.newSerializer();
+        serializer.setOutput(out, StandardCharsets.UTF_8.name());
+        serializer.startDocument(null, true);
+        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+        writeListXml(val, null, serializer);
+        serializer.endDocument();
+    }
+
+    /**
+     * Flatten a Map into an XmlSerializer.  The map can later be read back
+     * with readThisMapXml().
+     *
+     * @param val The map to be flattened.
+     * @param name Name attribute to include with this list's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the map into.
+     *
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     */
+    public static final void writeMapXml(Map val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        writeMapXml(val, name, out, null);
+    }
+
+    /**
+     * Flatten a Map into an XmlSerializer.  The map can later be read back
+     * with readThisMapXml().
+     *
+     * @param val The map to be flattened.
+     * @param name Name attribute to include with this list's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the map into.
+     * @param callback Method to call when an Object type is not recognized.
+     *
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     *
+     * @hide
+     */
+    public static final void writeMapXml(Map val, String name, XmlSerializer out,
+            WriteMapCallback callback) throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "map");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        writeMapXml(val, out, callback);
+
+        out.endTag(null, "map");
+    }
+
+    /**
+     * Flatten a Map into an XmlSerializer.  The map can later be read back
+     * with readThisMapXml(). This method presumes that the start tag and
+     * name attribute have already been written and does not write an end tag.
+     *
+     * @param val The map to be flattened.
+     * @param out XmlSerializer to write the map into.
+     *
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     *
+     * @hide
+     */
+    public static final void writeMapXml(Map val, XmlSerializer out,
+            WriteMapCallback callback) throws XmlPullParserException, IOException {
+        if (val == null) {
+            return;
+        }
+
+        Set s = val.entrySet();
+        Iterator i = s.iterator();
+
+        while (i.hasNext()) {
+            Map.Entry e = (Map.Entry)i.next();
+            writeValueXml(e.getValue(), (String)e.getKey(), out, callback);
+        }
+    }
+
+    /**
+     * Flatten a List into an XmlSerializer.  The list can later be read back
+     * with readThisListXml().
+     *
+     * @param val The list to be flattened.
+     * @param name Name attribute to include with this list's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the list into.
+     *
+     * @see #writeListXml(List, OutputStream)
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readListXml
+     */
+    public static final void writeListXml(List val, String name, XmlSerializer out)
+    throws XmlPullParserException, IOException
+    {
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "list");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        int N = val.size();
+        int i=0;
+        while (i < N) {
+            writeValueXml(val.get(i), null, out);
+            i++;
+        }
+
+        out.endTag(null, "list");
+    }
+
+    public static final void writeSetXml(Set val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "set");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        for (Object v : val) {
+            writeValueXml(v, null, out);
+        }
+
+        out.endTag(null, "set");
+    }
+
+    /**
+     * Flatten a byte[] into an XmlSerializer.  The list can later be read back
+     * with readThisByteArrayXml().
+     *
+     * @param val The byte array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     */
+    public static final void writeByteArrayXml(byte[] val, String name,
+            XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "byte-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        StringBuilder sb = new StringBuilder(val.length*2);
+        for (int i=0; i<N; i++) {
+            int b = val[i];
+            int h = b>>4;
+            sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
+            h = b&0xff;
+            sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
+        }
+
+        out.text(sb.toString());
+
+        out.endTag(null, "byte-array");
+    }
+
+    /**
+     * Flatten an int[] into an XmlSerializer.  The list can later be read back
+     * with readThisIntArrayXml().
+     *
+     * @param val The int array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeIntArrayXml(int[] val, String name,
+            XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "int-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Integer.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "int-array");
+    }
+
+    /**
+     * Flatten a long[] into an XmlSerializer.  The list can later be read back
+     * with readThisLongArrayXml().
+     *
+     * @param val The long array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeLongArrayXml(long[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "long-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Long.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "long-array");
+    }
+
+    /**
+     * Flatten a double[] into an XmlSerializer.  The list can later be read back
+     * with readThisDoubleArrayXml().
+     *
+     * @param val The double array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeDoubleArrayXml(double[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "double-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Double.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "double-array");
+    }
+
+    /**
+     * Flatten a String[] into an XmlSerializer.  The list can later be read back
+     * with readThisStringArrayXml().
+     *
+     * @param val The String array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeStringArrayXml(String[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "string-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", val[i]);
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "string-array");
+    }
+
+    /**
+     * Flatten a boolean[] into an XmlSerializer.  The list can later be read back
+     * with readThisBooleanArrayXml().
+     *
+     * @param val The boolean array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeBooleanArrayXml(boolean[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "boolean-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Boolean.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "boolean-array");
+    }
+
+    /**
+     * Flatten an object's value into an XmlSerializer.  The value can later
+     * be read back with readThisValueXml().
+     *
+     * Currently supported value types are: null, String, Integer, Long,
+     * Float, Double Boolean, Map, List.
+     *
+     * @param v The object to be flattened.
+     * @param name Name attribute to include with this value's tag, or null
+     *             for none.
+     * @param out XmlSerializer to write the object into.
+     *
+     * @see #writeMapXml
+     * @see #writeListXml
+     * @see #readValueXml
+     */
+    public static final void writeValueXml(Object v, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        writeValueXml(v, name, out, null);
+    }
+
+    /**
+     * Flatten an object's value into an XmlSerializer.  The value can later
+     * be read back with readThisValueXml().
+     *
+     * Currently supported value types are: null, String, Integer, Long,
+     * Float, Double Boolean, Map, List.
+     *
+     * @param v The object to be flattened.
+     * @param name Name attribute to include with this value's tag, or null
+     *             for none.
+     * @param out XmlSerializer to write the object into.
+     * @param callback Handler for Object types not recognized.
+     *
+     * @see #writeMapXml
+     * @see #writeListXml
+     * @see #readValueXml
+     */
+    private static final void writeValueXml(Object v, String name, XmlSerializer out,
+            WriteMapCallback callback)  throws XmlPullParserException, IOException {
+        String typeStr;
+        if (v == null) {
+            out.startTag(null, "null");
+            if (name != null) {
+                out.attribute(null, "name", name);
+            }
+            out.endTag(null, "null");
+            return;
+        } else if (v instanceof String) {
+            out.startTag(null, "string");
+            if (name != null) {
+                out.attribute(null, "name", name);
+            }
+            out.text(v.toString());
+            out.endTag(null, "string");
+            return;
+        } else if (v instanceof Integer) {
+            typeStr = "int";
+        } else if (v instanceof Long) {
+            typeStr = "long";
+        } else if (v instanceof Float) {
+            typeStr = "float";
+        } else if (v instanceof Double) {
+            typeStr = "double";
+        } else if (v instanceof Boolean) {
+            typeStr = "boolean";
+        } else if (v instanceof byte[]) {
+            writeByteArrayXml((byte[])v, name, out);
+            return;
+        } else if (v instanceof int[]) {
+            writeIntArrayXml((int[])v, name, out);
+            return;
+        } else if (v instanceof long[]) {
+            writeLongArrayXml((long[])v, name, out);
+            return;
+        } else if (v instanceof double[]) {
+            writeDoubleArrayXml((double[])v, name, out);
+            return;
+        } else if (v instanceof String[]) {
+            writeStringArrayXml((String[])v, name, out);
+            return;
+        } else if (v instanceof boolean[]) {
+            writeBooleanArrayXml((boolean[])v, name, out);
+            return;
+        } else if (v instanceof Map) {
+            writeMapXml((Map)v, name, out);
+            return;
+        } else if (v instanceof List) {
+            writeListXml((List) v, name, out);
+            return;
+        } else if (v instanceof Set) {
+            writeSetXml((Set) v, name, out);
+            return;
+        } else if (v instanceof CharSequence) {
+            // XXX This is to allow us to at least write something if
+            // we encounter styled text...  but it means we will drop all
+            // of the styling information. :(
+            out.startTag(null, "string");
+            if (name != null) {
+                out.attribute(null, "name", name);
+            }
+            out.text(v.toString());
+            out.endTag(null, "string");
+            return;
+        } else if (callback != null) {
+            callback.writeUnknownObject(v, name, out);
+            return;
+        } else {
+            throw new RuntimeException("writeValueXml: unable to write value " + v);
+        }
+
+        out.startTag(null, typeStr);
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+        out.attribute(null, "value", v.toString());
+        out.endTag(null, typeStr);
+    }
+
+    /**
+     * Read a HashMap from an InputStream containing XML.  The stream can
+     * previously have been written by writeMapXml().
+     *
+     * @param in The InputStream from which to read.
+     *
+     * @return HashMap The resulting map.
+     *
+     * @see #readListXml
+     * @see #readValueXml
+     * @see #readThisMapXml
+     * #see #writeMapXml
+     */
+    @SuppressWarnings("unchecked")
+    public static final HashMap<String, ?> readMapXml(InputStream in)
+    throws XmlPullParserException, IOException
+    {
+        XmlPullParser   parser = Xml.newPullParser();
+        parser.setInput(in, StandardCharsets.UTF_8.name());
+        return (HashMap<String, ?>) readValueXml(parser, new String[1]);
+    }
+
+    /**
+     * Read an ArrayList from an InputStream containing XML.  The stream can
+     * previously have been written by writeListXml().
+     *
+     * @param in The InputStream from which to read.
+     *
+     * @return ArrayList The resulting list.
+     *
+     * @see #readMapXml
+     * @see #readValueXml
+     * @see #readThisListXml
+     * @see #writeListXml
+     */
+    public static final ArrayList readListXml(InputStream in)
+    throws XmlPullParserException, IOException
+    {
+        XmlPullParser   parser = Xml.newPullParser();
+        parser.setInput(in, StandardCharsets.UTF_8.name());
+        return (ArrayList)readValueXml(parser, new String[1]);
+    }
+
+
+    /**
+     * Read a HashSet from an InputStream containing XML. The stream can
+     * previously have been written by writeSetXml().
+     *
+     * @param in The InputStream from which to read.
+     *
+     * @return HashSet The resulting set.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     *
+     * @see #readValueXml
+     * @see #readThisSetXml
+     * @see #writeSetXml
+     */
+    public static final HashSet readSetXml(InputStream in)
+            throws XmlPullParserException, IOException {
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(in, null);
+        return (HashSet) readValueXml(parser, new String[1]);
+    }
+
+    /**
+     * Read a HashMap object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeMapXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the map.
+     *
+     * @param parser The XmlPullParser from which to read the map data.
+     * @param endTag Name of the tag that will end the map, usually "map".
+     * @param name An array of one string, used to return the name attribute
+     *             of the map's tag.
+     *
+     * @return HashMap The newly generated map.
+     *
+     * @see #readMapXml
+     */
+    public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+        return readThisMapXml(parser, endTag, name, null);
+    }
+
+    /**
+     * Read a HashMap object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeMapXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the map.
+     *
+     * @param parser The XmlPullParser from which to read the map data.
+     * @param endTag Name of the tag that will end the map, usually "map".
+     * @param name An array of one string, used to return the name attribute
+     *             of the map's tag.
+     *
+     * @return HashMap The newly generated map.
+     *
+     * @see #readMapXml
+     * @hide
+     */
+    public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag,
+            String[] name, ReadMapCallback callback)
+            throws XmlPullParserException, IOException
+    {
+        HashMap<String, Object> map = new HashMap<String, Object>();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, false);
+                map.put(name[0], val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return map;
+                }
+                throw new XmlPullParserException(
+                    "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Like {@link #readThisMapXml}, but returns an ArrayMap instead of HashMap.
+     * @hide
+     */
+    public static final ArrayMap<String, ?> readThisArrayMapXml(XmlPullParser parser, String endTag,
+            String[] name, ReadMapCallback callback)
+            throws XmlPullParserException, IOException
+    {
+        ArrayMap<String, Object> map = new ArrayMap<>();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, true);
+                map.put(name[0], val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return map;
+                }
+                throw new XmlPullParserException(
+                    "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read an ArrayList object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeListXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return HashMap The newly generated list.
+     *
+     * @see #readListXml
+     */
+    public static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+        return readThisListXml(parser, endTag, name, null, false);
+    }
+
+    /**
+     * Read an ArrayList object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeListXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return HashMap The newly generated list.
+     *
+     * @see #readListXml
+     */
+    private static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
+            String[] name, ReadMapCallback callback, boolean arrayMap)
+            throws XmlPullParserException, IOException {
+        ArrayList list = new ArrayList();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, arrayMap);
+                list.add(val);
+                //System.out.println("Adding to list: " + val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return list;
+                }
+                throw new XmlPullParserException(
+                    "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a HashSet object from an XmlPullParser. The XML data could previously
+     * have been generated by writeSetXml(). The XmlPullParser must be positioned
+     * <em>after</em> the tag that begins the set.
+     *
+     * @param parser The XmlPullParser from which to read the set data.
+     * @param endTag Name of the tag that will end the set, usually "set".
+     * @param name An array of one string, used to return the name attribute
+     *             of the set's tag.
+     *
+     * @return HashSet The newly generated set.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     *
+     * @see #readSetXml
+     */
+    public static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name)
+            throws XmlPullParserException, IOException {
+        return readThisSetXml(parser, endTag, name, null, false);
+    }
+
+    /**
+     * Read a HashSet object from an XmlPullParser. The XML data could previously
+     * have been generated by writeSetXml(). The XmlPullParser must be positioned
+     * <em>after</em> the tag that begins the set.
+     *
+     * @param parser The XmlPullParser from which to read the set data.
+     * @param endTag Name of the tag that will end the set, usually "set".
+     * @param name An array of one string, used to return the name attribute
+     *             of the set's tag.
+     *
+     * @return HashSet The newly generated set.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     *
+     * @see #readSetXml
+     * @hide
+     */
+    private static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name,
+            ReadMapCallback callback, boolean arrayMap)
+            throws XmlPullParserException, IOException {
+        HashSet set = new HashSet();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, arrayMap);
+                set.add(val);
+                //System.out.println("Adding to set: " + val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return set;
+                }
+                throw new XmlPullParserException(
+                        "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+                "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read an int[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeIntArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated int[].
+     *
+     * @see #readListXml
+     */
+    public static final int[] readThisIntArrayXml(XmlPullParser parser,
+            String endTag, String[] name)
+            throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException(
+                    "Need num attribute in byte-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException(
+                    "Not a number in num attribute in byte-array");
+        }
+        parser.next();
+
+        int[] array = new int[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Integer.parseInt(
+                                parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException(
+                                "Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException(
+                                "Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException(
+                            "Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException(
+                        "Expected " + endTag + " end tag at: "
+                        + parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a long[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeLongArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated long[].
+     *
+     * @see #readListXml
+     */
+    public static final long[] readThisLongArrayXml(XmlPullParser parser,
+            String endTag, String[] name)
+            throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in long-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in long-array");
+        }
+        parser.next();
+
+        long[] array = new long[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Long.parseLong(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a double[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeDoubleArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "double-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated double[].
+     *
+     * @see #readListXml
+     */
+    public static final double[] readThisDoubleArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in double-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in double-array");
+        }
+        parser.next();
+
+        double[] array = new double[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Double.parseDouble(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a String[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeStringArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "string-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated String[].
+     *
+     * @see #readListXml
+     */
+    public static final String[] readThisStringArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in string-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in string-array");
+        }
+        parser.next();
+
+        String[] array = new String[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = parser.getAttributeValue(null, "value");
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a boolean[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeBooleanArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "string-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated boolean[].
+     *
+     * @see #readListXml
+     */
+    public static final boolean[] readThisBooleanArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in string-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in string-array");
+        }
+        parser.next();
+
+        boolean[] array = new boolean[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Boolean.valueOf(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a flattened object from an XmlPullParser.  The XML data could
+     * previously have been written with writeMapXml(), writeListXml(), or
+     * writeValueXml().  The XmlPullParser must be positioned <em>at</em> the
+     * tag that defines the value.
+     *
+     * @param parser The XmlPullParser from which to read the object.
+     * @param name An array of one string, used to return the name attribute
+     *             of the value's tag.
+     *
+     * @return Object The newly generated value object.
+     *
+     * @see #readMapXml
+     * @see #readListXml
+     * @see #writeValueXml
+     */
+    public static final Object readValueXml(XmlPullParser parser, String[] name)
+    throws XmlPullParserException, IOException
+    {
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                return readThisValueXml(parser, name, null, false);
+            } else if (eventType == parser.END_TAG) {
+                throw new XmlPullParserException(
+                    "Unexpected end tag at: " + parser.getName());
+            } else if (eventType == parser.TEXT) {
+                throw new XmlPullParserException(
+                    "Unexpected text: " + parser.getText());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Unexpected end of document");
+    }
+
+    private static final Object readThisValueXml(XmlPullParser parser, String[] name,
+            ReadMapCallback callback, boolean arrayMap)
+            throws XmlPullParserException, IOException {
+        final String valueName = parser.getAttributeValue(null, "name");
+        final String tagName = parser.getName();
+
+        //System.out.println("Reading this value tag: " + tagName + ", name=" + valueName);
+
+        Object res;
+
+        if (tagName.equals("null")) {
+            res = null;
+        } else if (tagName.equals("string")) {
+            String value = "";
+            int eventType;
+            while ((eventType = parser.next()) != parser.END_DOCUMENT) {
+                if (eventType == parser.END_TAG) {
+                    if (parser.getName().equals("string")) {
+                        name[0] = valueName;
+                        //System.out.println("Returning value for " + valueName + ": " + value);
+                        return value;
+                    }
+                    throw new XmlPullParserException(
+                        "Unexpected end tag in <string>: " + parser.getName());
+                } else if (eventType == parser.TEXT) {
+                    value += parser.getText();
+                } else if (eventType == parser.START_TAG) {
+                    throw new XmlPullParserException(
+                        "Unexpected start tag in <string>: " + parser.getName());
+                }
+            }
+            throw new XmlPullParserException(
+                "Unexpected end of document in <string>");
+        } else if ((res = readThisPrimitiveValueXml(parser, tagName)) != null) {
+            // all work already done by readThisPrimitiveValueXml
+        } else if (tagName.equals("int-array")) {
+            res = readThisIntArrayXml(parser, "int-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("long-array")) {
+            res = readThisLongArrayXml(parser, "long-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("double-array")) {
+            res = readThisDoubleArrayXml(parser, "double-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("string-array")) {
+            res = readThisStringArrayXml(parser, "string-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("boolean-array")) {
+            res = readThisBooleanArrayXml(parser, "boolean-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("map")) {
+            parser.next();
+            res = arrayMap
+                    ? readThisArrayMapXml(parser, "map", name, callback)
+                    : readThisMapXml(parser, "map", name, callback);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("list")) {
+            parser.next();
+            res = readThisListXml(parser, "list", name, callback, arrayMap);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("set")) {
+            parser.next();
+            res = readThisSetXml(parser, "set", name, callback, arrayMap);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (callback != null) {
+            res = callback.readThisUnknownObjectXml(parser, tagName);
+            name[0] = valueName;
+            return res;
+        } else {
+            throw new XmlPullParserException("Unknown tag: " + tagName);
+        }
+
+        // Skip through to end tag.
+        int eventType;
+        while ((eventType = parser.next()) != parser.END_DOCUMENT) {
+            if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(tagName)) {
+                    name[0] = valueName;
+                    //System.out.println("Returning value for " + valueName + ": " + res);
+                    return res;
+                }
+                throw new XmlPullParserException(
+                    "Unexpected end tag in <" + tagName + ">: " + parser.getName());
+            } else if (eventType == parser.TEXT) {
+                throw new XmlPullParserException(
+                "Unexpected text in <" + tagName + ">: " + parser.getName());
+            } else if (eventType == parser.START_TAG) {
+                throw new XmlPullParserException(
+                    "Unexpected start tag in <" + tagName + ">: " + parser.getName());
+            }
+        }
+        throw new XmlPullParserException(
+            "Unexpected end of document in <" + tagName + ">");
+    }
+
+    private static final Object readThisPrimitiveValueXml(XmlPullParser parser, String tagName)
+    throws XmlPullParserException, IOException
+    {
+        try {
+            if (tagName.equals("int")) {
+                return Integer.parseInt(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("long")) {
+                return Long.valueOf(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("float")) {
+                return new Float(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("double")) {
+                return new Double(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("boolean")) {
+                return Boolean.valueOf(parser.getAttributeValue(null, "value"));
+            } else {
+                return null;
+            }
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need value attribute in <" + tagName + ">");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException(
+                    "Not a number in value attribute in <" + tagName + ">");
+        }
+    }
+
+    public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException
+    {
+        int type;
+        while ((type=parser.next()) != parser.START_TAG
+                   && type != parser.END_DOCUMENT) {
+            ;
+        }
+
+        if (type != parser.START_TAG) {
+            throw new XmlPullParserException("No start tag found");
+        }
+
+        if (!parser.getName().equals(firstElementName)) {
+            throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
+                    ", expected " + firstElementName);
+        }
+    }
+
+    public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException
+    {
+        int type;
+        while ((type=parser.next()) != parser.START_TAG
+                   && type != parser.END_DOCUMENT) {
+            ;
+        }
+    }
+
+    public static boolean nextElementWithin(XmlPullParser parser, int outerDepth)
+            throws IOException, XmlPullParserException {
+        for (;;) {
+            int type = parser.next();
+            if (type == XmlPullParser.END_DOCUMENT
+                    || (type == XmlPullParser.END_TAG && parser.getDepth() == outerDepth)) {
+                return false;
+            }
+            if (type == XmlPullParser.START_TAG
+                    && parser.getDepth() == outerDepth + 1) {
+                return true;
+            }
+        }
+    }
+
+    public static int readIntAttribute(XmlPullParser in, String name, int defaultValue) {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    public static int readIntAttribute(XmlPullParser in, String name) throws IOException {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            throw new ProtocolException("problem parsing " + name + "=" + value + " as int");
+        }
+    }
+
+    public static void writeIntAttribute(XmlSerializer out, String name, int value)
+            throws IOException {
+        out.attribute(null, name, Integer.toString(value));
+    }
+
+    public static long readLongAttribute(XmlPullParser in, String name, long defaultValue) {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Long.parseLong(value);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    public static long readLongAttribute(XmlPullParser in, String name) throws IOException {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Long.parseLong(value);
+        } catch (NumberFormatException e) {
+            throw new ProtocolException("problem parsing " + name + "=" + value + " as long");
+        }
+    }
+
+    public static void writeLongAttribute(XmlSerializer out, String name, long value)
+            throws IOException {
+        out.attribute(null, name, Long.toString(value));
+    }
+
+    public static float readFloatAttribute(XmlPullParser in, String name) throws IOException {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Float.parseFloat(value);
+        } catch (NumberFormatException e) {
+            throw new ProtocolException("problem parsing " + name + "=" + value + " as long");
+        }
+    }
+
+    public static void writeFloatAttribute(XmlSerializer out, String name, float value)
+            throws IOException {
+        out.attribute(null, name, Float.toString(value));
+    }
+
+    public static boolean readBooleanAttribute(XmlPullParser in, String name) {
+        final String value = in.getAttributeValue(null, name);
+        return Boolean.parseBoolean(value);
+    }
+
+    public static boolean readBooleanAttribute(XmlPullParser in, String name,
+            boolean defaultValue) {
+        final String value = in.getAttributeValue(null, name);
+        if (value == null) {
+            return defaultValue;
+        } else {
+            return Boolean.parseBoolean(value);
+        }
+    }
+
+    public static void writeBooleanAttribute(XmlSerializer out, String name, boolean value)
+            throws IOException {
+        out.attribute(null, name, Boolean.toString(value));
+    }
+
+    public static Uri readUriAttribute(XmlPullParser in, String name) {
+        final String value = in.getAttributeValue(null, name);
+        return (value != null) ? Uri.parse(value) : null;
+    }
+
+    public static void writeUriAttribute(XmlSerializer out, String name, Uri value)
+            throws IOException {
+        if (value != null) {
+            out.attribute(null, name, value.toString());
+        }
+    }
+
+    public static String readStringAttribute(XmlPullParser in, String name) {
+        return in.getAttributeValue(null, name);
+    }
+
+    public static void writeStringAttribute(XmlSerializer out, String name, String value)
+            throws IOException {
+        if (value != null) {
+            out.attribute(null, name, value);
+        }
+    }
+
+    public static byte[] readByteArrayAttribute(XmlPullParser in, String name) {
+        final String value = in.getAttributeValue(null, name);
+        if (value != null) {
+            return Base64.decode(value, Base64.DEFAULT);
+        } else {
+            return null;
+        }
+    }
+
+    public static void writeByteArrayAttribute(XmlSerializer out, String name, byte[] value)
+            throws IOException {
+        if (value != null) {
+            out.attribute(null, name, Base64.encodeToString(value, Base64.DEFAULT));
+        }
+    }
+
+    public static Bitmap readBitmapAttribute(XmlPullParser in, String name) {
+        final byte[] value = readByteArrayAttribute(in, name);
+        if (value != null) {
+            return BitmapFactory.decodeByteArray(value, 0, value.length);
+        } else {
+            return null;
+        }
+    }
+
+    @Deprecated
+    public static void writeBitmapAttribute(XmlSerializer out, String name, Bitmap value)
+            throws IOException {
+        if (value != null) {
+            final ByteArrayOutputStream os = new ByteArrayOutputStream();
+            value.compress(CompressFormat.PNG, 90, os);
+            writeByteArrayAttribute(out, name, os.toByteArray());
+        }
+    }
+
+    /** @hide */
+    public interface WriteMapCallback {
+        /**
+         * Called from writeMapXml when an Object type is not recognized. The implementer
+         * must write out the entire element including start and end tags.
+         *
+         * @param v The object to be written out
+         * @param name The mapping key for v. Must be written into the "name" attribute of the
+         *             start tag.
+         * @param out The XML output stream.
+         * @throws XmlPullParserException on unrecognized Object type.
+         * @throws IOException on XmlSerializer serialization errors.
+         * @hide
+         */
+         public void writeUnknownObject(Object v, String name, XmlSerializer out)
+                 throws XmlPullParserException, IOException;
+    }
+
+    /** @hide */
+    public interface ReadMapCallback {
+        /**
+         * Called from readThisMapXml when a START_TAG is not recognized. The input stream
+         * is positioned within the start tag so that attributes can be read using in.getAttribute.
+         *
+         * @param in the XML input stream
+         * @param tag the START_TAG that was not recognized.
+         * @return the Object parsed from the stream which will be put into the map.
+         * @throws XmlPullParserException if the START_TAG is not recognized.
+         * @throws IOException on XmlPullParser serialization errors.
+         * @hide
+         */
+        public Object readThisUnknownObjectXml(XmlPullParser in, String tag)
+                throws XmlPullParserException, IOException;
+    }
+}
diff --git a/tests/tests/view/src/android/view/inputmethod/cts/KeyboardTest.java b/tests/tests/view/src/android/view/inputmethod/cts/KeyboardTest.java
new file mode 100644
index 0000000..ce7f9d7
--- /dev/null
+++ b/tests/tests/view/src/android/view/inputmethod/cts/KeyboardTest.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.view.inputmethod.cts;
+
+import com.android.cts.view.R;
+
+import android.os.Build.VERSION;
+import android.os.Build.VERSION_CODES;
+import android.test.AndroidTestCase;
+import android.inputmethodservice.Keyboard;
+import android.inputmethodservice.Keyboard.Key;
+
+import java.util.List;
+
+public class KeyboardTest extends AndroidTestCase {
+
+    public void testKeyOnPressedAndReleased() {
+        Key nonStickyKey = null;
+        Key stickyKey = null;
+        // Indirectly instantiate Keyboard.Key with XML resources.
+        final Keyboard keyboard = new Keyboard(getContext(), R.xml.keyboard);
+        for (final Key key : keyboard.getKeys()) {
+            if (!key.sticky) {
+                nonStickyKey = key;
+                break;
+            }
+        }
+        for (final Key key : keyboard.getModifierKeys()) {
+            if (key.sticky) {
+                stickyKey = key;
+                break;
+            }
+        }
+
+        // Asserting existences of following keys is not the goal of this test, but this should work
+        // anyway.
+        assertNotNull(nonStickyKey);
+        assertNotNull(stickyKey);
+
+        // At first, both "pressed" and "on" must be false.
+        assertFalse(nonStickyKey.pressed);
+        assertFalse(stickyKey.pressed);
+        assertFalse(nonStickyKey.on);
+        assertFalse(stickyKey.on);
+
+        // Pressing the key must flip the "pressed" state only.
+        nonStickyKey.onPressed();
+        stickyKey.onPressed();
+        assertTrue(nonStickyKey.pressed);
+        assertTrue(stickyKey.pressed);
+        assertFalse(nonStickyKey.on);
+        assertFalse(stickyKey.on);
+
+        // Releasing the key inside the key area must flip the "pressed" state and toggle the "on"
+        // state if the key is marked as sticky.
+        nonStickyKey.onReleased(true /* inside */);
+        stickyKey.onReleased(true /* inside */);
+        assertFalse(nonStickyKey.pressed);
+        assertFalse(stickyKey.pressed);
+        assertFalse(nonStickyKey.on);
+        assertTrue(stickyKey.on);   // The key state is toggled.
+
+        // Pressing the key again must flip the "pressed" state only.
+        nonStickyKey.onPressed();
+        stickyKey.onPressed();
+        assertTrue(nonStickyKey.pressed);
+        assertTrue(stickyKey.pressed);
+        assertFalse(nonStickyKey.on);
+        assertTrue(stickyKey.on);
+
+        // Releasing the key inside the key area must flip the "pressed" state and toggle the "on"
+        // state if the key is marked as sticky hence we will be back to the initial state.
+        nonStickyKey.onReleased(true /* inside */);
+        stickyKey.onReleased(true /* inside */);
+        assertFalse(nonStickyKey.pressed);
+        assertFalse(stickyKey.pressed);
+        assertFalse(nonStickyKey.on);
+        assertFalse(stickyKey.on);
+
+        // Pressing then releasing the key outside the key area must not affect the "on" state.
+        nonStickyKey.onPressed();
+        stickyKey.onPressed();
+        nonStickyKey.onReleased(false /* inside */);
+        stickyKey.onReleased(false /* inside */);
+        assertFalse(nonStickyKey.pressed);
+        assertFalse(stickyKey.pressed);
+        assertFalse(nonStickyKey.on);
+        assertFalse(stickyKey.on);
+    }
+}
diff --git a/tests/tests/voiceinteraction/Android.mk b/tests/tests/voiceinteraction/Android.mk
new file mode 100644
index 0000000..b8f95e3
--- /dev/null
+++ b/tests/tests/voiceinteraction/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 := CtsVoiceInteractionCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsVoiceInteractionTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/voiceinteraction/AndroidManifest.xml b/tests/tests/voiceinteraction/AndroidManifest.xml
new file mode 100644
index 0000000..4c6989f
--- /dev/null
+++ b/tests/tests/voiceinteraction/AndroidManifest.xml
@@ -0,0 +1,44 @@
+<?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.voiceinteraction.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.BIND_VOICE_INTERACTION" />
+
+    <application>
+      <uses-library android:name="android.test.runner" />
+
+      <activity android:name="TestStartActivity"
+                android:label="Voice Interaction Target">
+          <intent-filter>
+              <action android:name="android.intent.action.TEST_START_ACTIVITY" />
+              <category android:name="android.intent.category.LAUNCHER" />
+              <category android:name="android.intent.category.DEFAULT" />
+          </intent-filter>
+      </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.voiceinteraction.cts"
+                     android:label="CTS tests of android.voiceinteraction">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/voiceinteraction/AndroidTest.xml b/tests/tests/voiceinteraction/AndroidTest.xml
new file mode 100644
index 0000000..fa1ab70
--- /dev/null
+++ b/tests/tests/voiceinteraction/AndroidTest.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/Android.mk b/tests/tests/voiceinteraction/common/Android.mk
new file mode 100644
index 0000000..8b994c9
--- /dev/null
+++ b/tests/tests/voiceinteraction/common/Android.mk
@@ -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.
+
+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 := CtsVoiceInteractionCommon
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java b/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
new file mode 100644
index 0000000..ff3bcfd
--- /dev/null
+++ b/tests/tests/voiceinteraction/common/src/android/voiceinteraction/common/Utils.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.common;
+
+import android.app.VoiceInteractor;
+import android.app.VoiceInteractor.PickOptionRequest.Option;
+import android.os.Bundle;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class Utils {
+    public enum TestCaseType {
+        COMPLETION_REQUEST_TEST,
+        COMPLETION_REQUEST_CANCEL_TEST,
+        CONFIRMATION_REQUEST_TEST,
+        CONFIRMATION_REQUEST_CANCEL_TEST,
+        ABORT_REQUEST_TEST,
+        ABORT_REQUEST_CANCEL_TEST,
+        PICKOPTION_REQUEST_TEST,
+        PICKOPTION_REQUEST_CANCEL_TEST,
+        COMMANDREQUEST_TEST,
+        COMMANDREQUEST_CANCEL_TEST,
+        SUPPORTS_COMMANDS_TEST,
+    }
+    public static final String TESTCASE_TYPE = "testcase_type";
+    public static final String TESTINFO = "testinfo";
+    public static final String BROADCAST_INTENT = "android.intent.action.VOICE_TESTAPP";
+    public static final String TEST_PROMPT = "testprompt";
+    public static final String PICKOPTON_1 = "one";
+    public static final String PICKOPTON_2 = "two";
+    public static final String PICKOPTON_3 = "3";
+    public static final String TEST_COMMAND = "test_command";
+    public static final String TEST_ONCOMMAND_RESULT = "test_oncommand_result";
+    public static final String TEST_ONCOMMAND_RESULT_VALUE = "test_oncommand_result value";
+
+    public static final String CONFIRMATION_REQUEST_SUCCESS = "confirmation ok";
+    public static final String COMPLETION_REQUEST_SUCCESS = "completion ok";
+    public static final String ABORT_REQUEST_SUCCESS = "abort ok";
+    public static final String PICKOPTION_REQUEST_SUCCESS = "pickoption ok";
+    public static final String COMMANDREQUEST_SUCCESS = "commandrequest ok";
+    public static final String SUPPORTS_COMMANDS_SUCCESS = "supportsCommands ok";
+
+    public static final String CONFIRMATION_REQUEST_CANCEL_SUCCESS = "confirm cancel ok";
+    public static final String COMPLETION_REQUEST_CANCEL_SUCCESS = "completion canel ok";
+    public static final String ABORT_REQUEST_CANCEL_SUCCESS = "abort cancel ok";
+    public static final String PICKOPTION_REQUEST_CANCEL_SUCCESS = "pickoption  cancel ok";
+    public static final String COMMANDREQUEST_CANCEL_SUCCESS = "commandrequest cancel ok";
+    public static final String TEST_ERROR = "Error In Test:";
+
+    public static final String toBundleString(Bundle bundle) {
+        if (bundle == null) {
+            return "*** Bundle is null ****";
+        }
+        StringBuffer buf = new StringBuffer("Bundle is: ");
+        String testType = bundle.getString(TESTCASE_TYPE);
+        if (testType != null) {
+            buf.append("testcase type = " + testType);
+        }
+        ArrayList<String> info = bundle.getStringArrayList(TESTINFO);
+        if (info != null) {
+            for (String s : info) {
+                buf.append(s + "\n\t\t");
+            }
+        }
+        return buf.toString();
+    }
+
+    public static final String toOptionsString(Option[] options) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{");
+        for (int i = 0; i < options.length; i++) {
+            if (i >= 1) {
+                sb.append(", ");
+            }
+            sb.append(options[i].getLabel());
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    public static final void addErrorResult(final Bundle testinfo, final String msg) {
+        testinfo.getStringArrayList(testinfo.getString(Utils.TESTCASE_TYPE))
+            .add(TEST_ERROR + " " + msg);
+    }
+}
diff --git a/tests/tests/voiceinteraction/res/xml/interaction_service.xml b/tests/tests/voiceinteraction/res/xml/interaction_service.xml
new file mode 100644
index 0000000..dd7e7b8
--- /dev/null
+++ b/tests/tests/voiceinteraction/res/xml/interaction_service.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.
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:sessionService="android.voiceinteraction.service.MainInteractionSessionService"
+    android:recognitionService="android.voiceinteraction.service.MainRecognitionService"
+    android:settingsActivity="android.voiceinteraction.service.SettingsActivity"
+    android:supportsAssist="false" />
diff --git a/tests/tests/voiceinteraction/service/Android.mk b/tests/tests/voiceinteraction/service/Android.mk
new file mode 100644
index 0000000..4338f13
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/Android.mk
@@ -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.
+
+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 := CtsVoiceInteractionCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsVoiceInteractionService
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/voiceinteraction/service/AndroidManifest.xml b/tests/tests/voiceinteraction/service/AndroidManifest.xml
new file mode 100644
index 0000000..faf3d76
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/AndroidManifest.xml
@@ -0,0 +1,61 @@
+<?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.voiceinteraction.service">
+
+    <application>
+      <uses-library android:name="android.test.runner" />
+      <service android:name=".MainInteractionService"
+              android:label="CTS test voice interaction service"
+              android:permission="android.permission.BIND_VOICE_INTERACTION"
+              android:process=":interactor"
+              android:exported="true">
+          <meta-data android:name="android.voice_interaction"
+                     android:resource="@xml/interaction_service" />
+          <intent-filter>
+              <action android:name="android.service.voice.VoiceInteractionService" />
+          </intent-filter>
+      </service>
+      <activity android:name=".VoiceInteractionMain" >
+          <intent-filter>
+              <action android:name="android.intent.action.START_TEST" />
+              <category android:name="android.intent.category.DEFAULT" />
+          </intent-filter>
+      </activity>
+      <activity android:name=".SettingsActivity"
+                android:label="Voice Interaction Settings">
+          <intent-filter>
+              <action android:name="android.intent.action.MAIN" />
+              <category android:name="android.intent.category.DEFAULT" />
+          </intent-filter>
+      </activity>
+      <service android:name=".MainInteractionSessionService"
+              android:permission="android.permission.BIND_VOICE_INTERACTION"
+              android:process=":session">
+      </service>
+      <service android:name=".MainRecognitionService"
+              android:label="CTS Voice Recognition Service">
+          <intent-filter>
+              <action android:name="android.speech.RecognitionService" />
+              <category android:name="android.intent.category.DEFAULT" />
+          </intent-filter>
+          <meta-data android:name="android.speech" android:resource="@xml/recognition_service" />
+      </service>
+    </application>
+</manifest>
+
diff --git a/tests/tests/voiceinteraction/service/res/xml/interaction_service.xml b/tests/tests/voiceinteraction/service/res/xml/interaction_service.xml
new file mode 100644
index 0000000..dd7e7b8
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/res/xml/interaction_service.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.
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:sessionService="android.voiceinteraction.service.MainInteractionSessionService"
+    android:recognitionService="android.voiceinteraction.service.MainRecognitionService"
+    android:settingsActivity="android.voiceinteraction.service.SettingsActivity"
+    android:supportsAssist="false" />
diff --git a/tests/tests/voiceinteraction/service/res/xml/recognition_service.xml b/tests/tests/voiceinteraction/service/res/xml/recognition_service.xml
new file mode 100644
index 0000000..fafed99
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/res/xml/recognition_service.xml
@@ -0,0 +1,18 @@
+<?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.
+-->
+
+<recognition-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:settingsActivity="android.voiceinteraction.service.SettingsActivity" />
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionService.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionService.java
new file mode 100644
index 0000000..1af7bd5
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionService.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 android.voiceinteraction.service;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionService;
+import android.util.Log;
+
+public class MainInteractionService extends VoiceInteractionService {
+    static final String TAG = "MainInteractionService";
+    private Intent mIntent;
+    private boolean mReady = false;
+
+    @Override
+    public void onReady() {
+        super.onReady();
+        mReady = true;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        Log.i(TAG, "onStartCommand received");
+        mIntent = intent;
+        maybeStart();
+        return START_NOT_STICKY;
+    }
+
+    private void maybeStart() {
+       if (mIntent == null || !mReady) {
+            Log.wtf(TAG, "Can't start session because either intent is null or onReady() "
+                    + "is not called yet. mIntent = " + mIntent + ", mReady = " + mReady);
+        } else {
+            Log.i(TAG, "Yay! about to start session with TestApp");
+            if (isActiveService(this, new ComponentName(this, getClass()))) {
+                Bundle args = new Bundle();
+                Intent intent = new Intent();
+                intent.setComponent(new ComponentName("android.voiceinteraction.testapp",
+                        "android.voiceinteraction.testapp.TestApp"));
+                args.putParcelable("intent", intent);
+                showSession(args, 0);
+            } else {
+                Log.wtf(TAG, "**** Not starting MainInteractionService because" +
+                    " it is not set as the current voice interaction service");
+            }
+        }
+    }
+}
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
new file mode 100644
index 0000000..eeb4047
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSession.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.service;
+
+import android.app.VoiceInteractor;
+import android.app.VoiceInteractor.Prompt;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.service.voice.VoiceInteractionSession.ConfirmationRequest;
+import android.service.voice.VoiceInteractionSession.PickOptionRequest;
+import android.util.Log;
+import android.voiceinteraction.common.Utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class MainInteractionSession extends VoiceInteractionSession {
+    static final String TAG = "MainInteractionSession";
+
+    Intent mStartIntent;
+    List<MyTask> mUsedTasks = new ArrayList<MyTask>();
+
+    MainInteractionSession(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    @Override
+    public void onDestroy() {
+        Log.i(TAG, "Canceling the Asynctask in onDestroy()");
+        for (MyTask t : mUsedTasks) {
+            t.cancel(true);
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    public void onShow(Bundle args, int showFlags) {
+        super.onShow(args, showFlags);
+        mStartIntent = args.getParcelable("intent");
+        startVoiceActivity(mStartIntent);
+    }
+
+    void assertPromptFromTestApp(CharSequence prompt, Bundle extras) {
+        String str = prompt.toString();
+        if (str.equals(Utils.TEST_PROMPT)) {
+            Log.i(TAG, "prompt received ok from TestApp in Session");
+        } else {
+            Utils.addErrorResult(extras, "Invalid prompt received: " + str);
+        }
+    }
+
+    synchronized MyTask newTask() {
+        MyTask t = new MyTask();
+        mUsedTasks.add(t);
+        return t;
+    }
+
+    @Override
+    public boolean[] onGetSupportedCommands(String[] commands) {
+        boolean[] results = new boolean[commands.length];
+        Log.i(TAG, "in onGetSupportedCommands");
+        for (int idx = 0; idx < commands.length; idx++) {
+            results[idx] = Utils.TEST_COMMAND.equals(commands[idx]);
+            Log.i(TAG, "command " + commands[idx] + ", support = " + results[idx]);
+        }
+        return results;
+    }
+
+    @Override
+    public void onRequestConfirmation(ConfirmationRequest request) {
+        Bundle extras = request.getExtras();
+        CharSequence prompt = request.getVoicePrompt().getVoicePromptAt(0);
+        Log.i(TAG, "in Session onRequestConfirmation recvd. prompt=" + prompt +
+                ", extras=" + Utils.toBundleString(extras));
+        assertPromptFromTestApp(prompt, extras);
+        AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setExtras(extras);
+        if (isTestTypeCancel(extras)) {
+            Log.i(TAG, "Sending Cancel.");
+            newTask().execute(
+                    asyncTaskArg.setTestType(Utils.TestCaseType.CONFIRMATION_REQUEST_CANCEL_TEST));
+        } else {
+            Log.i(TAG, "in Session sending sendConfirmationResult. " +
+                    Utils.toBundleString(extras));
+            newTask().execute(
+                    asyncTaskArg.setTestType(Utils.TestCaseType.CONFIRMATION_REQUEST_TEST));
+        }
+    }
+
+    @Override
+    public void onRequestCompleteVoice(CompleteVoiceRequest request) {
+        Bundle extras = request.getExtras();
+        CharSequence prompt = request.getVoicePrompt().getVoicePromptAt(0);
+        Log.i(TAG, "in Session onRequestCompleteVoice recvd. message=" +
+                prompt + ", extras=" + Utils.toBundleString(extras));
+        assertPromptFromTestApp(prompt, extras);
+        AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setExtras(extras);
+        if (isTestTypeCancel(extras)) {
+            Log.i(TAG, "Sending Cancel.");
+            newTask().execute(
+                    asyncTaskArg.setTestType(Utils.TestCaseType.COMPLETION_REQUEST_CANCEL_TEST));
+        } else {
+            Log.i(TAG, "in Session sending sendConfirmationResult. " +
+                    Utils.toBundleString(extras));
+            newTask().execute(
+                    asyncTaskArg.setTestType(Utils.TestCaseType.COMPLETION_REQUEST_TEST));
+        }
+    }
+
+    @Override
+    public void onRequestAbortVoice(AbortVoiceRequest request) {
+        Bundle extras = request.getExtras();
+        CharSequence prompt = request.getVoicePrompt().getVoicePromptAt(0);
+        Log.i(TAG, "in Session onRequestAbortVoice recvd. message=" +
+                prompt + ", extras=" + Utils.toBundleString(extras));
+        assertPromptFromTestApp(prompt, extras);
+        AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setExtras(extras);
+        if (isTestTypeCancel(extras)) {
+            Log.i(TAG, "Sending Cancel.");
+            newTask().execute(
+                    asyncTaskArg.setTestType(Utils.TestCaseType.ABORT_REQUEST_CANCEL_TEST));
+        } else {
+            Log.i(TAG, "in Session sending sendAbortResult. " +
+                Utils.toBundleString(extras));
+            newTask().execute(asyncTaskArg.setTestType(Utils.TestCaseType.ABORT_REQUEST_TEST));
+        }
+    }
+
+    @Override
+    public void onRequestCommand(CommandRequest request) {
+        Bundle extras = request.getExtras();
+        Log.i(TAG, "in Session onRequestCommand recvd. Bundle = " +
+                Utils.toBundleString(extras));
+
+        // Make sure that the input request has Utils.TEST_COMMAND sent by TestApp
+        String command = request.getCommand();
+        if (command.equals(Utils.TEST_COMMAND)) {
+            Log.i(TAG, "command received ok from TestApp in Session");
+        } else {
+            Utils.addErrorResult(extras, "Invalid TEST_COMMAND received: " + command);
+        }
+        // Add a field and value in the bundle to be sent to TestApp.
+        // TestApp will ensure that these are transmitted correctly.
+        extras.putString(Utils.TEST_ONCOMMAND_RESULT, Utils.TEST_ONCOMMAND_RESULT_VALUE);
+        AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setExtras(extras);
+        if (isTestTypeCancel(extras)) {
+            Log.i(TAG, "Sending Cancel.");
+            newTask().execute(
+                    asyncTaskArg.setTestType(Utils.TestCaseType.COMMANDREQUEST_CANCEL_TEST));
+        } else {
+            Log.i(TAG, "in Session sending sendResult. " +
+                    Utils.toBundleString(extras) + ", string_in_bundle: " +
+                    Utils.TEST_ONCOMMAND_RESULT + " = " + Utils.TEST_ONCOMMAND_RESULT_VALUE);
+            newTask().execute(asyncTaskArg.setTestType(Utils.TestCaseType.COMMANDREQUEST_TEST));
+        }
+    }
+
+    void assertPickOptionsFromTestApp(VoiceInteractor.PickOptionRequest.Option[] options,
+            Bundle extras) {
+        if ((options.length != 2) ||
+            !options[0].getLabel().toString().equals(Utils.PICKOPTON_1) ||
+            !options[1].getLabel().toString().equals(Utils.PICKOPTON_2)) {
+            Utils.addErrorResult(extras, "Pickoptions Not received correctly in Session.");
+        } else {
+            Log.i(TAG, "Pickoptions received ok from TestApp in Session");
+        }
+    }
+
+    @Override
+    public void onRequestPickOption(PickOptionRequest request) {
+        Bundle extras = request.getExtras();
+        CharSequence prompt = request.getVoicePrompt().getVoicePromptAt(0);
+        Log.i(TAG, "in Session onRequestPickOption recvd. message=" +
+                prompt + ", options = " + Utils.toOptionsString(request.getOptions()) +
+                ", extras=" + Utils.toBundleString(extras));
+        VoiceInteractor.PickOptionRequest.Option[] picked
+            = new VoiceInteractor.PickOptionRequest.Option[1];
+        assertPromptFromTestApp(prompt, extras);
+        assertPickOptionsFromTestApp(request.getOptions(), extras);
+        picked[0] = new VoiceInteractor.PickOptionRequest.Option(Utils.PICKOPTON_3, 0);
+        AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request)
+                .setExtras(extras)
+                .setPickedOptions(picked);
+        if (isTestTypeCancel(extras)) {
+            Log.i(TAG, "in MainInteractionSession, Sending Cancel.");
+            newTask().execute(
+                    asyncTaskArg.setTestType(Utils.TestCaseType.PICKOPTION_REQUEST_CANCEL_TEST));
+        } else {
+            Log.i(TAG, "in MainInteractionSession sending sendPickOptionResult. " +
+                    Utils.toBundleString(extras));
+            newTask().execute(asyncTaskArg.setTestType(Utils.TestCaseType.PICKOPTION_REQUEST_TEST));
+        }
+    }
+
+    public static final boolean isTestTypeCancel(Bundle extras) {
+        Utils.TestCaseType testCaseType;
+        try {
+            testCaseType = Utils.TestCaseType.valueOf(extras.getString(Utils.TESTCASE_TYPE));
+        } catch (IllegalArgumentException | NullPointerException e) {
+            Log.wtf(TAG, "unexpected testCaseType value in Bundle received", e);
+            return true;
+        }
+        return testCaseType == Utils.TestCaseType.COMPLETION_REQUEST_CANCEL_TEST ||
+                testCaseType == Utils.TestCaseType.COMMANDREQUEST_CANCEL_TEST ||
+                testCaseType == Utils.TestCaseType.CONFIRMATION_REQUEST_CANCEL_TEST ||
+                testCaseType == Utils.TestCaseType.PICKOPTION_REQUEST_CANCEL_TEST ||
+                testCaseType == Utils.TestCaseType.ABORT_REQUEST_CANCEL_TEST;
+    }
+
+    private class AsyncTaskArg {
+        ConfirmationRequest confReq;
+        CommandRequest commandReq;
+        CompleteVoiceRequest compReq;
+        AbortVoiceRequest abortReq;
+        PickOptionRequest pickReq;
+        Bundle extras;
+        VoiceInteractor.PickOptionRequest.Option[] picked;
+        Utils.TestCaseType testType;
+
+        AsyncTaskArg setTestType(Utils.TestCaseType t) {testType = t; return this;}
+        AsyncTaskArg setRequest(CommandRequest r) {commandReq = r; return this;}
+        AsyncTaskArg setRequest(ConfirmationRequest r) {confReq = r; return this;}
+        AsyncTaskArg setRequest(CompleteVoiceRequest r) {compReq = r; return this;}
+        AsyncTaskArg setRequest(AbortVoiceRequest r) {abortReq = r; return this;}
+        AsyncTaskArg setRequest(PickOptionRequest r) {pickReq = r; return this;}
+        AsyncTaskArg setExtras(Bundle e) {extras = e;  return this;}
+        AsyncTaskArg setPickedOptions(VoiceInteractor.PickOptionRequest.Option[] p) {
+            picked = p;
+            return this;
+        }
+    }
+
+    private class MyTask extends AsyncTask<AsyncTaskArg, Void, Void> {
+        @Override
+        protected Void doInBackground(AsyncTaskArg... params) {
+            AsyncTaskArg arg = params[0];
+            Log.i(TAG, "in MyTask - doInBackground: requestType = " +
+                    arg.testType.toString());
+            switch (arg.testType) {
+                case ABORT_REQUEST_CANCEL_TEST:
+                    arg.abortReq.cancel();
+                    break;
+                case ABORT_REQUEST_TEST:
+                    arg.abortReq.sendAbortResult(arg.extras);
+                    break;
+                case COMMANDREQUEST_CANCEL_TEST:
+                    arg.commandReq.cancel();
+                    break;
+                case COMMANDREQUEST_TEST:
+                    Log.i(TAG, "in MyTask sendResult. " +
+                            Utils.toBundleString(arg.extras) + ", string_in_bundle: " +
+                            Utils.TEST_ONCOMMAND_RESULT + " = " +
+                            Utils.TEST_ONCOMMAND_RESULT_VALUE);
+                    arg.commandReq.sendResult(arg.extras);
+                    break;
+                case COMPLETION_REQUEST_CANCEL_TEST:
+                    arg.compReq.cancel();
+                    break;
+                case COMPLETION_REQUEST_TEST:
+                    arg.compReq.sendCompleteResult(arg.extras);
+                    break;
+                case CONFIRMATION_REQUEST_CANCEL_TEST:
+                     arg.confReq.cancel();
+                     break;
+                case CONFIRMATION_REQUEST_TEST:
+                     arg.confReq.sendConfirmationResult(true, arg.extras);
+                     break;
+                case PICKOPTION_REQUEST_CANCEL_TEST:
+                     arg.pickReq.cancel();
+                     break;
+                case PICKOPTION_REQUEST_TEST:
+                     StringBuilder buf = new StringBuilder();
+                     for (VoiceInteractor.PickOptionRequest.Option s : arg.picked) {
+                         buf.append("option: " + s.toString() + ", ");
+                     }
+                     Log.i(TAG, "******** Sending PickoptionResult: " +
+                             "picked: size = " + arg.picked.length +
+                             ", Options = " + buf.toString() +
+                             ", Bundle: " + Utils.toBundleString(arg.extras));
+                     arg.pickReq.sendPickOptionResult(arg.picked, arg.extras);
+                     break;
+               default:
+                   Log.i(TAG, "Doing nothing for the testcase type: " + arg.testType);
+                   break;
+            }
+            return null;
+        }
+    }
+}
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSessionService.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSessionService.java
new file mode 100644
index 0000000..43bfc8d
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainInteractionSessionService.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.service;
+
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.service.voice.VoiceInteractionSessionService;
+
+public class MainInteractionSessionService extends VoiceInteractionSessionService {
+    @Override
+    public VoiceInteractionSession onNewSession(Bundle args) {
+        return new MainInteractionSession(this);
+    }
+}
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainRecognitionService.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainRecognitionService.java
new file mode 100644
index 0000000..5bf203f
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/MainRecognitionService.java
@@ -0,0 +1,55 @@
+/*
+ * 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.voiceinteraction.service;
+
+import android.content.Intent;
+import android.speech.RecognitionService;
+import android.util.Log;
+
+/**
+ * Stub recognition service needed to be a complete voice interactor.
+ */
+public class MainRecognitionService extends RecognitionService {
+    private static final String TAG = "MainRecognitionService";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, "onCreate");
+    }
+
+    @Override
+    protected void onStartListening(Intent recognizerIntent, Callback listener) {
+        Log.i(TAG, "onStartListening");
+    }
+
+    @Override
+    protected void onCancel(Callback listener) {
+        Log.i(TAG, "onCancel");
+    }
+
+    @Override
+    protected void onStopListening(Callback listener) {
+        Log.i(TAG, "onStopListening");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        Log.i(TAG, "onDestroy");
+    }
+}
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/SettingsActivity.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/SettingsActivity.java
new file mode 100644
index 0000000..97f59f8
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/SettingsActivity.java
@@ -0,0 +1,30 @@
+/*
+ * 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.voiceinteraction.service;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Stub activity to test out settings selection for voice interactor.
+ */
+public class SettingsActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/VoiceInteractionMain.java b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/VoiceInteractionMain.java
new file mode 100644
index 0000000..388b47f
--- /dev/null
+++ b/tests/tests/voiceinteraction/service/src/android/voiceinteraction/service/VoiceInteractionMain.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 android.voiceinteraction.service;
+
+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 java.util.ArrayList;
+import java.util.Arrays;
+
+public class VoiceInteractionMain extends Activity {
+    static final String TAG = "VoiceInteractionMain";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = new Intent();
+        intent.setComponent(new ComponentName(this, MainInteractionService.class));
+        ComponentName serviceName = startService(intent);
+        Log.i(TAG, "Started service: " + serviceName);
+    }
+}
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestStartActivity.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestStartActivity.java
new file mode 100644
index 0000000..682667f
--- /dev/null
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/TestStartActivity.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.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;
+
+public class TestStartActivity extends Activity {
+    static final String TAG = "TestStartActivity";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, " in onCreate");
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log.i(TAG, " in onResume");
+        Intent intent = new Intent();
+        intent.setAction("android.intent.action.START_TEST");
+        intent.setComponent(new ComponentName("android.voiceinteraction.service",
+                "android.voiceinteraction.service.VoiceInteractionMain"));
+        startActivity(intent);
+    }
+
+    @Override protected void onPause() {
+        Log.i(TAG, " in onPause");
+        super.onPause();
+    }
+
+    @Override protected void onStart() {
+        super.onStart();
+        Log.i(TAG, " in onStart");
+    }
+
+    @Override protected void onRestart() {
+        super.onRestart();
+        Log.i(TAG, " in onRestart");
+    }
+
+    @Override protected void onStop() {
+        Log.i(TAG, " in onStop");
+        super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.i(TAG, " in onDestroy");
+        super.onDestroy();
+    }
+}
diff --git a/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java
new file mode 100644
index 0000000..6b47eb4
--- /dev/null
+++ b/tests/tests/voiceinteraction/src/android/voiceinteraction/cts/VoiceInteractionTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 VoiceInteractionTest extends ActivityInstrumentationTestCase2<TestStartActivity> {
+    static final String TAG = "VoiceInteractionTest";
+    private static final int TIMEOUT_MS = 20 * 1000;
+
+    private TestStartActivity mTestActivity;
+    private Context mContext;
+    private TestResultsReceiver mReceiver;
+    private Bundle mResults;
+    private final CountDownLatch mLatch = new CountDownLatch(1);
+
+    public VoiceInteractionTest() {
+        super(TestStartActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        startTestActivity();
+        mContext = getInstrumentation().getTargetContext();
+        mReceiver = new TestResultsReceiver();
+        mContext.registerReceiver(mReceiver, new IntentFilter(Utils.BROADCAST_INTENT));
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mReceiver != null) {
+            try {
+                mContext.unregisterReceiver(mReceiver);
+            } catch (IllegalArgumentException e) {
+                // This exception is thrown if mReceiver in
+                // the above call to unregisterReceiver is never registered.
+                // If so, no harm done by ignoring this exception.
+            }
+            mReceiver = null;
+        }
+        super.tearDown();
+    }
+
+    private void startTestActivity() throws Exception {
+        Intent intent = new Intent();
+        intent.setAction("android.intent.action.TEST_START_ACTIVITY");
+        intent.setComponent(new ComponentName(getInstrumentation().getContext(),
+                TestStartActivity.class));
+        setActivityIntent(intent);
+        mTestActivity = getActivity();
+    }
+
+    public void testAll() throws Exception {
+        if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Failed to receive broadcast in " + TIMEOUT_MS + "msec");
+            return;
+        }
+        if (mResults == null) {
+            fail("no results received at all!");
+            return;
+        }
+        int numFails = 0;
+        for (Utils.TestCaseType t : Utils.TestCaseType.values()) {
+            String singleResult = mResults.getString(t.toString());
+            if (singleResult == null) {
+                numFails++;
+                Log.i(TAG, "No testresults received for " + t);
+            } else {
+                verifySingleTestcaseResult(t, singleResult);
+            }
+        }
+        assertEquals(0, numFails);
+        mTestActivity.finish();
+    }
+
+    private void verifySingleTestcaseResult(Utils.TestCaseType testCaseType, String result) {
+        Log.i(TAG, "Recevied testresult: " + result + " for " + testCaseType);
+        switch (testCaseType) {
+          case ABORT_REQUEST_CANCEL_TEST:
+              assertTrue(result.equals(Utils.ABORT_REQUEST_CANCEL_SUCCESS));
+              break;
+          case ABORT_REQUEST_TEST:
+              assertTrue(result.equals(Utils.ABORT_REQUEST_SUCCESS));
+              break;
+          case COMMANDREQUEST_TEST:
+              assertTrue(result.equals(Utils.COMMANDREQUEST_SUCCESS));
+              break;
+          case COMMANDREQUEST_CANCEL_TEST:
+              assertTrue(result.equals(Utils.COMMANDREQUEST_CANCEL_SUCCESS));
+              break;
+          case COMPLETION_REQUEST_CANCEL_TEST:
+              assertTrue(result.equals(Utils.COMPLETION_REQUEST_CANCEL_SUCCESS));
+              break;
+          case COMPLETION_REQUEST_TEST:
+              assertTrue(result.equals(Utils.COMPLETION_REQUEST_SUCCESS));
+              break;
+          case CONFIRMATION_REQUEST_CANCEL_TEST:
+              assertTrue(result.equals(Utils.CONFIRMATION_REQUEST_CANCEL_SUCCESS));
+              break;
+          case CONFIRMATION_REQUEST_TEST:
+              assertTrue(result.equals(Utils.CONFIRMATION_REQUEST_SUCCESS));
+              break;
+          case PICKOPTION_REQUEST_CANCEL_TEST:
+              assertTrue(result.equals(Utils.PICKOPTION_REQUEST_CANCEL_SUCCESS));
+              break;
+          case PICKOPTION_REQUEST_TEST:
+              assertTrue(result.equals(Utils.PICKOPTION_REQUEST_SUCCESS));
+              break;
+          case SUPPORTS_COMMANDS_TEST:
+              assertTrue(result.equals(Utils.SUPPORTS_COMMANDS_SUCCESS));
+              break;
+          default:
+              Log.wtf(TAG, "not expected");
+              break;
+        }
+        Log.i(TAG, testCaseType + " passed");
+    }
+
+
+    class TestResultsReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equalsIgnoreCase(Utils.BROADCAST_INTENT)) {
+                Log.i(TAG, "received broadcast with results ");
+                VoiceInteractionTest.this.mResults = intent.getExtras();
+                mLatch.countDown();
+            }
+        }
+    }
+}
diff --git a/tests/tests/voiceinteraction/testapp/Android.mk b/tests/tests/voiceinteraction/testapp/Android.mk
new file mode 100644
index 0000000..7453880
--- /dev/null
+++ b/tests/tests/voiceinteraction/testapp/Android.mk
@@ -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.
+
+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 := CtsVoiceInteractionCommon
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsVoiceInteractionApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/voiceinteraction/testapp/AndroidManifest.xml b/tests/tests/voiceinteraction/testapp/AndroidManifest.xml
new file mode 100644
index 0000000..15069ec
--- /dev/null
+++ b/tests/tests/voiceinteraction/testapp/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.voiceinteraction.testapp">
+
+    <application>
+      <uses-library android:name="android.test.runner" />
+
+      <activity android:name="TestApp"
+                android:label="Voice Interaction Test App"
+                android:theme="@android:style/Theme.DeviceDefault">
+          <intent-filter>
+              <action android:name="android.intent.action.TEST_APP" />
+              <category android:name="android.intent.category.DEFAULT" />
+              <category android:name="android.intent.category.VOICE" />
+          </intent-filter>
+      </activity>
+    </application>
+</manifest>
diff --git a/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java b/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java
new file mode 100644
index 0000000..1ef6a5c
--- /dev/null
+++ b/tests/tests/voiceinteraction/testapp/src/android/voiceinteraction/testapp/TestApp.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.testapp;
+
+import android.app.Activity;
+import android.app.VoiceInteractor;
+import android.app.VoiceInteractor.AbortVoiceRequest;
+import android.app.VoiceInteractor.CommandRequest;
+import android.app.VoiceInteractor.CompleteVoiceRequest;
+import android.app.VoiceInteractor.ConfirmationRequest;
+import android.app.VoiceInteractor.PickOptionRequest;
+import android.app.VoiceInteractor.PickOptionRequest.Option;
+import android.app.VoiceInteractor.Prompt;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionService;
+import android.util.Log;
+
+import java.util.ArrayList;
+
+import android.voiceinteraction.common.Utils;
+
+public class TestApp extends Activity {
+    static final String TAG = "TestApp";
+
+    VoiceInteractor mInteractor;
+    Bundle mTestinfo = new Bundle();
+    Bundle mTotalInfo = new Bundle();
+    Utils.TestCaseType mTestInProgress;
+    int mIndex = 0;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, "TestApp created");
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        mInteractor = getVoiceInteractor();
+        continueTests();
+    }
+
+    private void continueTests() {
+        if (mIndex == Utils.TestCaseType.values().length) {
+            // all tests done
+            Log.i(TAG, "Ready to broadcast");
+            broadcastResults();
+            finish();
+            return;
+        }
+        mTestInProgress = (Utils.TestCaseType.values())[mIndex++];
+        testSetup();
+        switch (mTestInProgress) {
+          case ABORT_REQUEST_TEST:
+          case ABORT_REQUEST_CANCEL_TEST:
+              abortRequest();
+              break;
+
+          case COMPLETION_REQUEST_TEST:
+          case COMPLETION_REQUEST_CANCEL_TEST:
+              completionRequest();
+              break;
+
+          case CONFIRMATION_REQUEST_TEST:
+          case CONFIRMATION_REQUEST_CANCEL_TEST:
+              confirmationRequest();
+              break;
+
+          case PICKOPTION_REQUEST_TEST:
+          case PICKOPTION_REQUEST_CANCEL_TEST:
+              pickOptionRequest();
+              break;
+
+          case COMMANDREQUEST_TEST:
+          case COMMANDREQUEST_CANCEL_TEST:
+              commandRequest();
+              break;
+
+          case SUPPORTS_COMMANDS_TEST:
+              String[] commands = {Utils.TEST_COMMAND};
+              boolean[] supported = mInteractor.supportsCommands(commands);
+              Log.i(TAG, "from supportsCommands: " + supported);
+              if (supported.length == 1 && supported[0]) {
+                addTestResult(Utils.SUPPORTS_COMMANDS_SUCCESS);
+              } else {
+                addTestResult(Utils.TEST_ERROR + " supported commands failure!");
+              }
+              saveTestResults();
+              continueTests();
+              break;
+        }
+    }
+
+    private void testSetup() {
+        mTestinfo.putStringArrayList(Utils.TESTINFO, new ArrayList<String>());
+        mTestinfo.putString(Utils.TESTCASE_TYPE, mTestInProgress.toString());
+    }
+
+    private void saveTestResults() {
+        ArrayList<String> info = mTestinfo.getStringArrayList(Utils.TESTINFO);
+        if (info != null) {
+            StringBuilder buf = new StringBuilder();
+            int count = 0;
+            for (String s : info) {
+                buf.append(s);
+                if (count++ > 0) {
+                    buf.append(", ");
+                }
+            }
+            mTotalInfo.putString(mTestInProgress.toString(), buf.toString());
+            Log.i(TAG, "results for " + mTestInProgress + " = " +
+                    mTotalInfo.getString(mTestInProgress.toString()));
+        }
+    }
+
+    private void broadcastResults() {
+        Intent intent = new Intent(Utils.BROADCAST_INTENT);
+        intent.putExtras(mTotalInfo);
+        Log.i(TAG, "broadcasting: " + intent.toString() + ", Bundle = " + mTotalInfo.toString());
+        sendOrderedBroadcast(intent, null, new DoneReceiver(),
+                             null, Activity.RESULT_OK, null, null);
+    }
+
+    private void confirmationRequest() {
+        Prompt prompt = new Prompt(Utils.TEST_PROMPT);
+        ConfirmationRequest req = new VoiceInteractor.ConfirmationRequest(prompt, mTestinfo) {
+            @Override
+            public void onCancel() {
+                Log.i(TAG, "confirmation request Canceled!");
+                addTestResult(Utils.CONFIRMATION_REQUEST_CANCEL_SUCCESS);
+                saveTestResults();
+                continueTests();
+            }
+
+            @Override
+            public void onConfirmationResult(boolean confirmed, Bundle result) {
+                mTestinfo = result;
+                Log.i(TAG, "Confirmation result: confirmed=" + confirmed +
+                        ", recvd bundle =" + Utils.toBundleString(result));
+                addTestResult(Utils.CONFIRMATION_REQUEST_SUCCESS);
+                saveTestResults();
+                continueTests();
+            }
+        };
+        mInteractor.submitRequest(req);
+    }
+
+    private void completionRequest() {
+        Prompt prompt = new Prompt(Utils.TEST_PROMPT);
+        CompleteVoiceRequest req = new VoiceInteractor.CompleteVoiceRequest(prompt, mTestinfo) {
+            @Override
+            public void onCancel() {
+                Log.i(TAG, "completionRequest Canceled!");
+                addTestResult(Utils.COMPLETION_REQUEST_CANCEL_SUCCESS);
+                saveTestResults();
+                continueTests();
+            }
+
+            @Override
+            public void onCompleteResult(Bundle result) {
+                mTestinfo = result;
+                Log.i(TAG, "Completion result: recvd bundle =" +
+                        Utils.toBundleString(result));
+                addTestResult(Utils.COMPLETION_REQUEST_SUCCESS);
+                saveTestResults();
+                continueTests();
+            }
+        };
+        mInteractor.submitRequest(req);
+    }
+
+    private void abortRequest() {
+        Prompt prompt = new Prompt(Utils.TEST_PROMPT);
+        AbortVoiceRequest req = new VoiceInteractor.AbortVoiceRequest(prompt, mTestinfo) {
+            @Override
+            public void onCancel() {
+                Log.i(TAG, "abortRequest Canceled!");
+                addTestResult(Utils.ABORT_REQUEST_CANCEL_SUCCESS);
+                saveTestResults();
+                continueTests();
+            }
+
+            @Override
+            public void onAbortResult(Bundle result) {
+                mTestinfo = result;
+                Log.i(TAG, "Abort result: recvd bundle =" + Utils.toBundleString(result));
+                addTestResult(Utils.ABORT_REQUEST_SUCCESS);
+                saveTestResults();
+                continueTests();
+            }
+        };
+        mInteractor.submitRequest(req);
+    }
+
+    private void pickOptionRequest() {
+        Prompt prompt = new Prompt(Utils.TEST_PROMPT);
+        PickOptionRequest.Option[] options = new VoiceInteractor.PickOptionRequest.Option[2];
+        options[0] = new Option(Utils.PICKOPTON_1, -1);
+        options[1] = new Option(Utils.PICKOPTON_2, -1);
+        Log.i(TAG, "pickOptionRequest initiated with Bundle = ");
+        PickOptionRequest req = new VoiceInteractor.PickOptionRequest(prompt, options, mTestinfo) {
+            @Override
+            public void onCancel() {
+                Log.i(TAG, "pickOptionRequest Canceled!");
+                addTestResult(Utils.PICKOPTION_REQUEST_CANCEL_SUCCESS);
+                saveTestResults();
+                continueTests();
+            }
+
+            @Override
+            public void onPickOptionResult(boolean finished, Option[] selections, Bundle result) {
+                mTestinfo = result;
+                Log.i(TAG, "PickOption result: finished = " + finished +
+                        ", selections = " + Utils.toOptionsString(selections) +
+                        ", recvd bundle =" + Utils.toBundleString(result));
+                if ((selections.length != 1) ||
+                    !selections[0].getLabel().toString().equals(Utils.PICKOPTON_3)) {
+                    Utils.addErrorResult(result,
+                            "Pickoption Selections Not received correctly in TestApp.");
+                } else {
+                    addTestResult(Utils.PICKOPTION_REQUEST_SUCCESS);
+                }
+                saveTestResults();
+                continueTests();
+            }
+        };
+        mInteractor.submitRequest(req);
+    }
+
+    private void commandRequest() {
+        CommandRequest req = new VoiceInteractor.CommandRequest(Utils.TEST_COMMAND, mTestinfo) {
+            @Override
+            public void onCancel() {
+                Log.i(TAG, "commandRequest Canceled!");
+                addTestResult(Utils.COMMANDREQUEST_CANCEL_SUCCESS);
+                saveTestResults();
+                continueTests();
+            }
+
+            @Override
+            public void onCommandResult(boolean isCompleted, Bundle result) {
+                mTestinfo = result;
+                Log.i(TAG, "CommandRequest onCommandResult result: isCompleted = " + isCompleted +
+                        ", recvd bundle =" + Utils.toBundleString(result));
+                String received = result.getString(Utils.TEST_ONCOMMAND_RESULT);
+                if (received != null && received.equals(Utils.TEST_ONCOMMAND_RESULT_VALUE)) {
+                    addTestResult(Utils.COMMANDREQUEST_SUCCESS);
+                } else {
+                    Utils.addErrorResult(result,
+                            "Invalid commandrequest result received: " + received);
+                }
+                saveTestResults();
+                continueTests();
+            }
+        };
+        mInteractor.submitRequest(req);
+    }
+
+    private void addTestResult(final String msg) {
+        mTestinfo.getStringArrayList(Utils.TESTINFO).add(msg);
+    }
+
+    class DoneReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            Log.i(TAG, "Done_broadcast " + intent.getAction());
+        }
+    }
+}
diff --git a/tests/tests/voicesettings/Android.mk b/tests/tests/voicesettings/Android.mk
new file mode 100644
index 0000000..71fead6
--- /dev/null
+++ b/tests/tests/voicesettings/Android.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 := CtsVoiceSettingsCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsVoiceSettingsTestCases
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_PACKAGE)
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/tests/voicesettings/AndroidManifest.xml b/tests/tests/voicesettings/AndroidManifest.xml
new file mode 100644
index 0000000..bf938f9
--- /dev/null
+++ b/tests/tests/voicesettings/AndroidManifest.xml
@@ -0,0 +1,45 @@
+<!--
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.voicesettings.cts">
+
+    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
+    <uses-permission android:name="android.permission.BIND_VOICE_INTERACTION" />
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+
+        <activity android:name="TestStartActivity"
+                  android:label="The Target Activity for VoiceSettings CTS Test">
+            <intent-filter>
+                <action android:name="android.intent.action.TEST_START_ACTIVITY_ZEN_MODE" />
+                <action android:name="android.intent.action.TEST_START_ACTIVITY_AIRPLANE_MODE" />
+                <action android:name="android.intent.action.TEST_START_ACTIVITY_BATTERYSAVER_MODE" />
+                <category android:name="android.intent.category.LAUNCHER" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
+                     android:targetPackage="android.voicesettings.cts"
+                     android:label="CTS tests of android.voicesettings">
+        <meta-data android:name="listener"
+            android:value="com.android.cts.runner.CtsTestRunListener" />
+    </instrumentation>
+</manifest>
+
diff --git a/tests/tests/voicesettings/AndroidTest.xml b/tests/tests/voicesettings/AndroidTest.xml
new file mode 100644
index 0000000..e3be691
--- /dev/null
+++ b/tests/tests/voicesettings/AndroidTest.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 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>
diff --git a/tests/tests/voicesettings/common/Android.mk b/tests/tests/voicesettings/common/Android.mk
new file mode 100644
index 0000000..1478ef2
--- /dev/null
+++ b/tests/tests/voicesettings/common/Android.mk
@@ -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.
+
+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 := CtsVoiceSettingsCommon
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/tests/voicesettings/common/src/android/voicesettings/common/Utils.java b/tests/tests/voicesettings/common/src/android/voicesettings/common/Utils.java
new file mode 100644
index 0000000..44514b0
--- /dev/null
+++ b/tests/tests/voicesettings/common/src/android/voicesettings/common/Utils.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 common.src.android.voicesettings.common;
+
+import android.os.Bundle;
+
+public class Utils {
+    public enum TestcaseType {
+        ZEN_MODE_ON,
+        ZEN_MODE_OFF,
+        AIRPLANE_MODE_ON,
+        AIRPLANE_MODE_OFF,
+        BATTERYSAVER_MODE_ON,
+        BATTERYSAVER_MODE_OFF,
+    }
+    public static final String TESTCASE_TYPE = "Testcase_type";
+    public static final String BROADCAST_INTENT =
+            "android.intent.action.FROM_VOICESETTINGS_CTS_TEST_";
+    public static final int NUM_MINUTES_FOR_ZENMODE = 10;
+
+    public static final String toBundleString(Bundle bundle) {
+        if (bundle == null) {
+            return "*** Bundle is null ****";
+        }
+        StringBuilder buf = new StringBuilder();
+        if (bundle != null) {
+            buf.append("extras: ");
+            for (String s : bundle.keySet()) {
+                buf.append("(" + s + " = " + bundle.get(s) + "), ");
+            }
+        }
+        return buf.toString();
+    }
+}
diff --git a/tests/tests/voicesettings/res/xml/interaction_service.xml b/tests/tests/voicesettings/res/xml/interaction_service.xml
new file mode 100644
index 0000000..bf40892
--- /dev/null
+++ b/tests/tests/voicesettings/res/xml/interaction_service.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.
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:sessionService="android.voicesettings.service.MainInteractionSessionService"
+    android:recognitionService="android.voicesettings.service.MainRecognitionService"
+    android:settingsActivity="android.voicesettings.service.SettingsActivity"
+    android:supportsAssist="false" />
diff --git a/tests/tests/voicesettings/service/Android.mk b/tests/tests/voicesettings/service/Android.mk
new file mode 100644
index 0000000..97866d5
--- /dev/null
+++ b/tests/tests/voicesettings/service/Android.mk
@@ -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.
+
+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 := CtsVoiceSettingsCommon ctstestrunner ctsdeviceutil
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsVoiceSettingsService
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/tests/voicesettings/service/AndroidManifest.xml b/tests/tests/voicesettings/service/AndroidManifest.xml
new file mode 100644
index 0000000..13671b6
--- /dev/null
+++ b/tests/tests/voicesettings/service/AndroidManifest.xml
@@ -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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.voicesettings.service">
+
+    <application>
+        <uses-library android:name="android.test.runner" />
+        <service android:name=".MainInteractionService"
+                android:label="CTS test voice interaction service"
+                android:permission="android.permission.BIND_VOICE_INTERACTION"
+                android:process=":interactor"
+                android:exported="true">
+            <meta-data android:name="android.voice_interaction"
+                       android:resource="@xml/interaction_service" />
+            <intent-filter>
+                <action android:name="android.service.voice.VoiceInteractionService" />
+            </intent-filter>
+        </service>
+        <activity android:name=".VoiceInteractionMain" >
+            <intent-filter>
+                <action android:name="android.intent.action.VIMAIN_ZEN_MODE_ON" />
+                <action android:name="android.intent.action.VIMAIN_ZEN_MODE_OFF" />
+                <action android:name="android.intent.action.VIMAIN_AIRPLANE_MODE_ON" />
+                <action android:name="android.intent.action.VIMAIN_AIRPLANE_MODE_OFF" />
+                <action android:name="android.intent.action.VIMAIN_BATTERYSAVER_MODE_ON" />
+                <action android:name="android.intent.action.VIMAIN_BATTERYSAVER_MODE_OFF" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <activity android:name=".SettingsActivity"
+                  android:label="Voice Interaction Settings">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+        <service android:name=".MainInteractionSessionService"
+                android:permission="android.permission.BIND_VOICE_INTERACTION"
+                android:process=":session">
+        </service>
+        <service android:name=".MainRecognitionService"
+                android:label="CTS Voice Recognition Service">
+            <intent-filter>
+                <action android:name="android.speech.RecognitionService" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="android.speech" android:resource="@xml/recognition_service" />
+        </service>
+    </application>
+</manifest>
+
diff --git a/tests/tests/voicesettings/service/res/xml/interaction_service.xml b/tests/tests/voicesettings/service/res/xml/interaction_service.xml
new file mode 100644
index 0000000..bf40892
--- /dev/null
+++ b/tests/tests/voicesettings/service/res/xml/interaction_service.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.
+-->
+
+<voice-interaction-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:sessionService="android.voicesettings.service.MainInteractionSessionService"
+    android:recognitionService="android.voicesettings.service.MainRecognitionService"
+    android:settingsActivity="android.voicesettings.service.SettingsActivity"
+    android:supportsAssist="false" />
diff --git a/tests/tests/voicesettings/service/res/xml/recognition_service.xml b/tests/tests/voicesettings/service/res/xml/recognition_service.xml
new file mode 100644
index 0000000..9d80f24
--- /dev/null
+++ b/tests/tests/voicesettings/service/res/xml/recognition_service.xml
@@ -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.
+-->
+
+<recognition-service xmlns:android="http://schemas.android.com/apk/res/android"
+    android:settingsActivity="android.voicesettings.service.SettingsActivity" />
diff --git a/tests/tests/voicesettings/service/src/android/voicesettings/service/MainInteractionService.java b/tests/tests/voicesettings/service/src/android/voicesettings/service/MainInteractionService.java
new file mode 100644
index 0000000..6302b78
--- /dev/null
+++ b/tests/tests/voicesettings/service/src/android/voicesettings/service/MainInteractionService.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.voicesettings.service;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionService;
+import android.util.Log;
+import common.src.android.voicesettings.common.Utils;
+
+public class MainInteractionService extends VoiceInteractionService {
+    static final String TAG = "MainInteractionService";
+    private Intent mIntent;
+    private boolean mReady = false;
+
+    @Override
+    public void onReady() {
+        super.onReady();
+        mReady = true;
+    }
+
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+        Log.i(TAG, "onStartCommand received");
+        mIntent = intent;
+        Log.i(TAG, "received_testcasetype = " + mIntent.getStringExtra(Utils.TESTCASE_TYPE));
+        maybeStart();
+        return START_NOT_STICKY;
+    }
+
+    private void maybeStart() {
+       if (mIntent == null || !mReady) {
+            Log.wtf(TAG, "Can't start session because either intent is null or onReady() "
+                    + "is not called yet. mIntent = " + mIntent + ", mReady = " + mReady);
+        } else {
+            Log.i(TAG, "Yay! about to start MainInteractionSession");
+            if (isActiveService(this, new ComponentName(this, getClass()))) {
+                Bundle args = new Bundle();
+                args.putString(Utils.TESTCASE_TYPE, mIntent.getStringExtra(Utils.TESTCASE_TYPE));
+                Log.i(TAG, "xferring_testcasetype = " + args.getString(Utils.TESTCASE_TYPE));
+                showSession(args, 0);
+            } else {
+                Log.wtf(TAG, "**** Not starting MainInteractionService because" +
+                    " it is not set as the current voice interaction service");
+            }
+        }
+    }
+}
diff --git a/tests/tests/voicesettings/service/src/android/voicesettings/service/MainInteractionSession.java b/tests/tests/voicesettings/service/src/android/voicesettings/service/MainInteractionSession.java
new file mode 100644
index 0000000..aff1160
--- /dev/null
+++ b/tests/tests/voicesettings/service/src/android/voicesettings/service/MainInteractionSession.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.voicesettings.service;
+
+import static android.provider.Settings.ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE;
+import static android.provider.Settings.EXTRA_DO_NOT_DISTURB_MODE_ENABLED;
+import static android.provider.Settings.EXTRA_DO_NOT_DISTURB_MODE_MINUTES;
+import static android.provider.Settings.ACTION_VOICE_CONTROL_AIRPLANE_MODE;
+import static android.provider.Settings.EXTRA_AIRPLANE_MODE_ENABLED;
+import static android.provider.Settings.ACTION_VOICE_CONTROL_BATTERY_SAVER_MODE;
+import static android.provider.Settings.EXTRA_BATTERY_SAVER_MODE_ENABLED;
+
+import android.app.VoiceInteractor;
+import android.content.Context;
+import android.content.Intent;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.util.Log;
+
+import common.src.android.voicesettings.common.Utils;
+import common.src.android.voicesettings.common.Utils.TestcaseType;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MainInteractionSession extends VoiceInteractionSession {
+    static final String TAG = "MainInteractionSession";
+
+    List<MyTask> mUsedTasks = new ArrayList<MyTask>();
+    Context mContext;
+    TestcaseType mTestType;
+
+    MainInteractionSession(Context context) {
+        super(context);
+        mContext = context;
+    }
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+    }
+
+    @Override
+    public void onDestroy() {
+        Log.i(TAG, "Canceling the Asynctasks in onDestroy()");
+        for (MyTask t : mUsedTasks) {
+            t.cancel(true);
+        }
+        super.onDestroy();
+    }
+
+    @Override
+    public void onShow(Bundle args, int showFlags) {
+        super.onShow(args, showFlags);
+        String testCaseType = args.getString(Utils.TESTCASE_TYPE);
+        Log.i(TAG, "received_testcasetype = " + testCaseType);
+        try {
+            mTestType = TestcaseType.valueOf(testCaseType);
+        } catch (IllegalArgumentException e) {
+            Log.wtf(TAG, e);
+            return;
+        } catch (NullPointerException e) {
+            Log.wtf(TAG, e);
+            return;
+        }
+        Intent intent;
+        switch(mTestType) {
+            case ZEN_MODE_ON:
+                intent = new Intent(ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE);
+                intent.putExtra(EXTRA_DO_NOT_DISTURB_MODE_ENABLED, true);
+                intent.putExtra(EXTRA_DO_NOT_DISTURB_MODE_MINUTES, Utils.NUM_MINUTES_FOR_ZENMODE);
+                break;
+            case ZEN_MODE_OFF:
+                intent = new Intent(ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE);
+                intent.putExtra(EXTRA_DO_NOT_DISTURB_MODE_ENABLED, false);
+                break;
+            case AIRPLANE_MODE_ON:
+                intent = new Intent(ACTION_VOICE_CONTROL_AIRPLANE_MODE);
+                intent.putExtra(EXTRA_AIRPLANE_MODE_ENABLED, true);
+                break;
+            case AIRPLANE_MODE_OFF:
+                intent = new Intent(ACTION_VOICE_CONTROL_AIRPLANE_MODE);
+                intent.putExtra(EXTRA_AIRPLANE_MODE_ENABLED, false);
+                break;
+            case BATTERYSAVER_MODE_ON:
+                intent = new Intent(ACTION_VOICE_CONTROL_BATTERY_SAVER_MODE);
+                intent.putExtra(EXTRA_BATTERY_SAVER_MODE_ENABLED, true);
+                break;
+            case BATTERYSAVER_MODE_OFF:
+                intent = new Intent(ACTION_VOICE_CONTROL_BATTERY_SAVER_MODE);
+                intent.putExtra(EXTRA_BATTERY_SAVER_MODE_ENABLED, false);
+                break;
+            default:
+                Log.i(TAG, "Not implemented!");
+                return;
+        }
+        Log.i(TAG, "starting_voiceactivity: " + intent.toString());
+        startVoiceActivity(intent);
+    }
+
+    @Override
+    public void onTaskFinished(Intent intent, int taskId) {
+        // extras contain the info on what the activity started above did.
+        // we probably could verify this also.
+        Bundle extras = intent.getExtras();
+        Log.i(TAG, "in onTaskFinished: testcasetype = " + mTestType + ", intent: " +
+                intent.toString() + Utils.toBundleString(extras));
+        Intent broadcastIntent = new Intent(Utils.BROADCAST_INTENT + mTestType.toString());
+        if (extras == null) {
+            extras = new Bundle();
+        }
+        extras.putString(Utils.TESTCASE_TYPE, mTestType.toString());
+        broadcastIntent.putExtras(extras);
+        Log.i(TAG, "sending_broadcast: Bundle = " + Utils.toBundleString(extras) +
+                ", intent = " + broadcastIntent.toString());
+        mContext.sendBroadcast(broadcastIntent);
+    }
+
+    synchronized MyTask newTask() {
+        MyTask t = new MyTask();
+        mUsedTasks.add(t);
+        return t;
+    }
+
+    @Override
+    public void onRequestCompleteVoice(CompleteVoiceRequest request) {
+        VoiceInteractor.Prompt prompt = request.getVoicePrompt();
+        CharSequence message = (prompt != null ? prompt.getVoicePromptAt(0) : "(none)");
+        Log.i(TAG, "in Session testcasetype = " + mTestType +
+                ", onRequestCompleteVoice recvd. message = " + message);
+        AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setCompleteReq(true);
+        newTask().execute(asyncTaskArg);
+    }
+
+    @Override
+    public void onRequestAbortVoice(AbortVoiceRequest request) {
+        AsyncTaskArg asyncTaskArg = new AsyncTaskArg().setRequest(request).setCompleteReq(false);
+        Log.i(TAG, "in Session sending sendAbortResult. ");
+        newTask().execute(asyncTaskArg);
+    }
+
+    private class AsyncTaskArg {
+        CompleteVoiceRequest mCompReq;
+        AbortVoiceRequest mAbortReq;
+        boolean isCompleteRequest = true;
+
+        AsyncTaskArg setRequest(CompleteVoiceRequest r) {
+            mCompReq = r;
+            return this;
+        }
+
+        AsyncTaskArg setRequest(AbortVoiceRequest r) {
+            mAbortReq = r;
+            return this;
+        }
+
+        AsyncTaskArg setCompleteReq(boolean flag) {
+            isCompleteRequest = flag;
+            return this;
+        }
+    }
+
+    private class MyTask extends AsyncTask<AsyncTaskArg, Void, Void> {
+        @Override
+        protected Void doInBackground(AsyncTaskArg... params) {
+            AsyncTaskArg arg = params[0];
+            Log.i(TAG, "in MyTask - doInBackground: testType = " +
+                    MainInteractionSession.this.mTestType);
+            if (arg.isCompleteRequest) {
+                arg.mCompReq.sendCompleteResult(new Bundle());
+            } else {
+                arg.mAbortReq.sendAbortResult(new Bundle());
+            }
+            return null;
+        }
+    }
+}
diff --git a/tests/tests/voicesettings/service/src/android/voicesettings/service/MainInteractionSessionService.java b/tests/tests/voicesettings/service/src/android/voicesettings/service/MainInteractionSessionService.java
new file mode 100644
index 0000000..2b302b8
--- /dev/null
+++ b/tests/tests/voicesettings/service/src/android/voicesettings/service/MainInteractionSessionService.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.voicesettings.service;
+
+import android.os.Bundle;
+import android.service.voice.VoiceInteractionSession;
+import android.service.voice.VoiceInteractionSessionService;
+
+public class MainInteractionSessionService extends VoiceInteractionSessionService {
+    @Override
+    public VoiceInteractionSession onNewSession(Bundle args) {
+        return new MainInteractionSession(this);
+    }
+}
diff --git a/tests/tests/voicesettings/service/src/android/voicesettings/service/MainRecognitionService.java b/tests/tests/voicesettings/service/src/android/voicesettings/service/MainRecognitionService.java
new file mode 100644
index 0000000..9b0e95d
--- /dev/null
+++ b/tests/tests/voicesettings/service/src/android/voicesettings/service/MainRecognitionService.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.voicesettings.service;
+
+import android.content.Intent;
+import android.speech.RecognitionService;
+import android.util.Log;
+
+/**
+ * Stub recognition service needed to be a complete voice interactor.
+ */
+public class MainRecognitionService extends RecognitionService {
+    private static final String TAG = "MainRecognitionService";
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        Log.i(TAG, "onCreate");
+    }
+
+    @Override
+    protected void onStartListening(Intent recognizerIntent, Callback listener) {
+        Log.i(TAG, "onStartListening");
+    }
+
+    @Override
+    protected void onCancel(Callback listener) {
+        Log.i(TAG, "onCancel");
+    }
+
+    @Override
+    protected void onStopListening(Callback listener) {
+        Log.i(TAG, "onStopListening");
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        Log.i(TAG, "onDestroy");
+    }
+}
diff --git a/tests/tests/voicesettings/service/src/android/voicesettings/service/SettingsActivity.java b/tests/tests/voicesettings/service/src/android/voicesettings/service/SettingsActivity.java
new file mode 100644
index 0000000..140bca4
--- /dev/null
+++ b/tests/tests/voicesettings/service/src/android/voicesettings/service/SettingsActivity.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 android.voicesettings.service;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Stub activity to test out settings selection for voice interactor.
+ */
+public class SettingsActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/tests/tests/voicesettings/service/src/android/voicesettings/service/VoiceInteractionMain.java b/tests/tests/voicesettings/service/src/android/voicesettings/service/VoiceInteractionMain.java
new file mode 100644
index 0000000..adc2980
--- /dev/null
+++ b/tests/tests/voicesettings/service/src/android/voicesettings/service/VoiceInteractionMain.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 android.voicesettings.service;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.util.Log;
+
+import common.src.android.voicesettings.common.Utils;
+
+public class VoiceInteractionMain extends Activity {
+    static final String TAG = "VoiceInteractionMain";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Intent intent = new Intent();
+        String testCaseType = getIntent().getStringExtra(Utils.TESTCASE_TYPE);
+        Log.i(TAG, "received_testcasetype = " + testCaseType);
+        intent.putExtra(Utils.TESTCASE_TYPE, testCaseType);
+        intent.setComponent(new ComponentName(this, MainInteractionService.class));
+        ComponentName serviceName = startService(intent);
+        Log.i(TAG, "Started service: " + serviceName);
+    }
+}
diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java b/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.java
new file mode 100644
index 0000000..9ce743e
--- /dev/null
+++ b/tests/tests/voicesettings/src/android/voicesettings/cts/AirplaneModeTest.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.voicesettings.cts;
+
+import static android.provider.Settings.ACTION_VOICE_CONTROL_AIRPLANE_MODE;
+
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.util.Log;
+
+import common.src.android.voicesettings.common.Utils;
+
+public class AirplaneModeTest extends VoiceSettingsTestBase {
+    static final String TAG = "AirplaneModeTest";
+
+    private static final int AIRPLANE_MODE_IS_OFF = 0;
+    private static final int AIRPLANE_MODE_IS_ON = 1;
+
+    public AirplaneModeTest() {
+        super();
+    }
+
+    public void testAll() throws Exception {
+        if (!isIntentSupported(ACTION_VOICE_CONTROL_AIRPLANE_MODE)) {
+            Log.e(TAG, "Voice intent for Airplane Mode NOT supported. existing the test");
+            return;
+        }
+        int mode;
+        try {
+            mode = getMode();
+            Log.i(TAG, "Before testing, AIRPLANE_MODE is set to: " + mode);
+        } catch (Settings.SettingNotFoundException e) {
+            // if the mode is not supported, don't run the test.
+            Log.i(TAG, "airplane mode is not found in Settings. Skipping AirplaneModeTest");
+            return;
+        }
+        startTestActivity("AIRPLANE_MODE");
+        if (mode == AIRPLANE_MODE_IS_OFF) {
+            // mode is currently OFF.
+            // run a test to turn it on.
+            // After successful run of the test, run a test to turn it back off.
+            if (!runTest(Utils.TestcaseType.AIRPLANE_MODE_ON, AIRPLANE_MODE_IS_ON)) {
+                // the test failed. don't test the next one.
+                return;
+            }
+            runTest(Utils.TestcaseType.AIRPLANE_MODE_OFF, AIRPLANE_MODE_IS_OFF);
+        } else {
+            // mode is currently ON.
+            // run a test to turn it off.
+            // After successful run of the test, run a test to turn it back on.
+            if (!runTest(Utils.TestcaseType.AIRPLANE_MODE_OFF, AIRPLANE_MODE_IS_OFF)) {
+                // the test failed. don't test the next one.
+                return;
+            }
+            runTest(Utils.TestcaseType.AIRPLANE_MODE_ON, AIRPLANE_MODE_IS_ON);
+        }
+    }
+
+    private boolean runTest(Utils.TestcaseType test, int expectedMode) throws Exception {
+        if (!startTestAndWaitForBroadcast(test)) {
+            return false;
+        }
+
+        // verify the test results
+        int mode = getMode();
+        Log.i(TAG, "After testing, AIRPLANE_MODE is set to: " + mode);
+        assertEquals(expectedMode, mode);
+        Log.i(TAG, "Successfully Tested: " + test);
+        return true;
+    }
+
+    private int getMode() throws Settings.SettingNotFoundException {
+        return Settings.Global.getInt(mContext.getContentResolver(),
+            Settings.Global.AIRPLANE_MODE_ON);
+    }
+}
diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/BatterySaverModeTest.java b/tests/tests/voicesettings/src/android/voicesettings/cts/BatterySaverModeTest.java
new file mode 100644
index 0000000..983e27b
--- /dev/null
+++ b/tests/tests/voicesettings/src/android/voicesettings/cts/BatterySaverModeTest.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.voicesettings.cts;
+
+import static android.provider.Settings.ACTION_VOICE_CONTROL_BATTERY_SAVER_MODE;
+
+import android.content.Context;
+import android.os.PowerManager;
+import android.util.Log;
+
+import common.src.android.voicesettings.common.Utils;
+
+public class BatterySaverModeTest extends VoiceSettingsTestBase {
+    static final String TAG = "BatterySaverModeTest";
+
+    public BatterySaverModeTest() {
+        super();
+    }
+
+    public void testAll() throws Exception {
+        if (!isIntentSupported(ACTION_VOICE_CONTROL_BATTERY_SAVER_MODE)) {
+            Log.e(TAG, "Voice intent for Battery Saver Mode NOT supported. existing the test");
+            return;
+        }
+        startTestActivity("BATTERYSAVER_MODE");
+        boolean modeIsOn = isModeOn();
+        Log.i(TAG, "Before testing, BATTERYSAVER_MODE is set to: " + modeIsOn);
+        if (modeIsOn) {
+            // mode is currently ON.
+            // run a test to turn it off.
+            // After successful run of the test, run a test to turn it back on.
+            if (!runTest(Utils.TestcaseType.BATTERYSAVER_MODE_OFF, false)) {
+                // the test failed. don't test the next one.
+                return;
+            }
+            runTest(Utils.TestcaseType.BATTERYSAVER_MODE_ON, true);
+        } else {
+            // mode is currently OFF.
+            // run a test to turn it on.
+            // After successful run of the test, run a test to turn it back off.
+            if (!runTest(Utils.TestcaseType.BATTERYSAVER_MODE_ON, true)) {
+                // the test failed. don't test the next one.
+                return;
+            }
+            runTest(Utils.TestcaseType.BATTERYSAVER_MODE_OFF, false);
+        }
+    }
+
+    private boolean runTest(Utils.TestcaseType test, boolean expectedMode) throws Exception {
+        if (!startTestAndWaitForBroadcast(test)) {
+            return false;
+        }
+
+        // Verify the test results
+        // Since CTS test needs the device to be connected to the host computer via USB,
+        // Batter Saver mode can't be turned on/off.
+        // The most we can do is that the broadcast frmo MainInteractionSession is received
+        // because that signals the firing and completion of BatterySaverModeVoiceActivity
+        // caused by the intent to set Battery Saver mode.
+        return true;
+    }
+
+    private boolean isModeOn() {
+        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+        return powerManager.isPowerSaveMode();
+    }
+}
diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/TestStartActivity.java b/tests/tests/voicesettings/src/android/voicesettings/cts/TestStartActivity.java
new file mode 100644
index 0000000..cef29b1
--- /dev/null
+++ b/tests/tests/voicesettings/src/android/voicesettings/cts/TestStartActivity.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.voicesettings.cts;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.util.Log;
+
+import common.src.android.voicesettings.common.Utils;
+
+public class TestStartActivity extends Activity {
+    static final String TAG = "TestStartActivity";
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        Log.i(TAG, " in onCreate");
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+        Log.i(TAG, " in onResume");
+    }
+
+    void startTest(String testCaseType) {
+        Intent intent = new Intent();
+        Log.i(TAG, "received_testcasetype = " + testCaseType);
+        intent.putExtra(Utils.TESTCASE_TYPE, testCaseType);
+        intent.setAction("android.intent.action.VIMAIN_" + testCaseType);
+        intent.setComponent(new ComponentName("android.voicesettings.service",
+                "android.voicesettings.service.VoiceInteractionMain"));
+        startActivity(intent);
+    }
+
+    @Override
+    protected void onPause() {
+        Log.i(TAG, " in onPause");
+        super.onPause();
+    }
+
+    @Override
+    protected void onStart() {
+        super.onStart();
+        Log.i(TAG, " in onStart");
+    }
+
+    @Override
+    protected void onRestart() {
+        super.onRestart();
+        Log.i(TAG, " in onRestart");
+    }
+
+    @Override
+    protected void onStop() {
+        Log.i(TAG, " in onStop");
+        super.onStop();
+    }
+
+    @Override
+    protected void onDestroy() {
+        Log.i(TAG, " in onDestroy");
+        super.onDestroy();
+    }
+}
diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/VoiceSettingsTestBase.java b/tests/tests/voicesettings/src/android/voicesettings/cts/VoiceSettingsTestBase.java
new file mode 100644
index 0000000..529c160
--- /dev/null
+++ b/tests/tests/voicesettings/src/android/voicesettings/cts/VoiceSettingsTestBase.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 android.voicesettings.cts;
+
+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.test.ActivityInstrumentationTestCase2;
+import android.util.Log;
+
+import common.src.android.voicesettings.common.Utils;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class VoiceSettingsTestBase extends ActivityInstrumentationTestCase2<TestStartActivity> {
+    static final String TAG = "VoiceSettingsTestBase";
+    protected static final int TIMEOUT_MS = 20 * 1000;
+
+    protected Context mContext;
+    protected Bundle mResultExtras;
+    private CountDownLatch mLatch;
+    private ActivityDoneReceiver mActivityDoneReceiver = null;
+    private TestStartActivity mActivity;
+    private Utils.TestcaseType mTestCaseType;
+
+    public VoiceSettingsTestBase() {
+        super(TestStartActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mContext = getInstrumentation().getTargetContext();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mActivityDoneReceiver != null) {
+            try {
+                mContext.unregisterReceiver(mActivityDoneReceiver);
+            } catch (IllegalArgumentException e) {
+                // This exception is thrown if mActivityDoneReceiver in
+                // the above call to unregisterReceiver is never registered.
+                // If so, no harm done by ignoring this exception.
+            }
+            mActivityDoneReceiver = null;
+        }
+        super.tearDown();
+    }
+
+    protected boolean isIntentSupported(String intentStr) {
+        Intent intent = new Intent(intentStr);
+        final PackageManager manager = mContext.getPackageManager();
+        assertNotNull(manager);
+        if (manager.resolveActivity(intent, 0) == null) {
+            Log.i(TAG, "No Voice Activity found for the intent: " + intentStr);
+            return false;
+        }
+        return true;
+    }
+
+    protected void startTestActivity(String intentSuffix) {
+        Intent intent = new Intent();
+        intent.setAction("android.intent.action.TEST_START_ACTIVITY_" + intentSuffix);
+        intent.setComponent(new ComponentName(getInstrumentation().getContext(),
+                TestStartActivity.class));
+        setActivityIntent(intent);
+        mActivity = getActivity();
+    }
+
+    protected void registerBroadcastReceiver(Utils.TestcaseType testCaseType) throws Exception {
+        mTestCaseType = testCaseType;
+        mLatch = new CountDownLatch(1);
+        mActivityDoneReceiver = new ActivityDoneReceiver();
+        mContext.registerReceiver(mActivityDoneReceiver,
+                new IntentFilter(Utils.BROADCAST_INTENT + testCaseType.toString()));
+    }
+
+    protected boolean startTestAndWaitForBroadcast(Utils.TestcaseType testCaseType)
+            throws Exception {
+        Log.i(TAG, "Begin Testing: " + testCaseType);
+        registerBroadcastReceiver(testCaseType);
+        mActivity.startTest(testCaseType.toString());
+        if (!mLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS)) {
+            fail("Failed to receive broadcast in " + TIMEOUT_MS + "msec");
+            return false;
+        }
+        return true;
+    }
+
+    class ActivityDoneReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(
+                    Utils.BROADCAST_INTENT +
+                        VoiceSettingsTestBase.this.mTestCaseType.toString())) {
+                Bundle extras = intent.getExtras();
+                Log.i(TAG, "received_broadcast for " + Utils.toBundleString(extras));
+                VoiceSettingsTestBase.this.mResultExtras = extras;
+                mLatch.countDown();
+            }
+        }
+    }
+}
diff --git a/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java b/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.java
new file mode 100644
index 0000000..420da8f
--- /dev/null
+++ b/tests/tests/voicesettings/src/android/voicesettings/cts/ZenModeTest.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 android.voicesettings.cts;
+
+import static android.provider.Settings.ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE;
+import static android.provider.Settings.EXTRA_DO_NOT_DISTURB_MODE_ENABLED;
+import static android.provider.Settings.EXTRA_DO_NOT_DISTURB_MODE_MINUTES;
+
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.util.Log;
+
+import common.src.android.voicesettings.common.Utils;
+
+public class ZenModeTest extends VoiceSettingsTestBase {
+    static final String TAG = "ZenModeTest";
+
+    // The following are hidden in frameworks/base/core/java/android/provider/Settings.java
+    // If they weren't, we could have used them directly here.
+    private static final String ZEN_MODE = "zen_mode";
+    private static final int ZEN_MODE_IS_OFF = 0;
+    private static final int ZEN_MODE_IS_ALARMS = 3;
+
+    public ZenModeTest() {
+        super();
+    }
+
+    public void testAll() throws Exception {
+        if (!isIntentSupported(ACTION_VOICE_CONTROL_DO_NOT_DISTURB_MODE)) {
+            Log.e(TAG, "Voice intent for Zen Mode NOT supported. existing the test");
+            return;
+        }
+        int mode;
+        try {
+            mode = getMode();
+            Log.i(TAG, "Before testing, zen-mode is set to: " + mode);
+        } catch (Settings.SettingNotFoundException e) {
+            // if the mode is not supported, don't run the test.
+            Log.i(TAG, "zen_mode is not found in Settings. Skipping ZenModeTest");
+            return;
+        }
+        startTestActivity("ZEN_MODE");
+        if (mode == ZEN_MODE_IS_OFF) {
+            // mode is currently OFF.
+            // run a test to turn it on.
+            // After successful run of the test, run a test to turn it back off.
+            if (!runTest(Utils.TestcaseType.ZEN_MODE_ON, ZEN_MODE_IS_ALARMS)) {
+                // the test failed. don't test the next one.
+                return;
+            }
+            runTest(Utils.TestcaseType.ZEN_MODE_OFF, ZEN_MODE_IS_OFF);
+        } else {
+            // mode is currently ON.
+            // run a test to turn it off.
+            // After successful run of the test, run a test to turn it back on.
+            if (!runTest(Utils.TestcaseType.ZEN_MODE_OFF, ZEN_MODE_IS_OFF)) {
+                // the test failed. don't test the next one.
+                return;
+            }
+            runTest(Utils.TestcaseType.ZEN_MODE_ON, ZEN_MODE_IS_ALARMS);
+        }
+    }
+
+    private boolean runTest(Utils.TestcaseType test, int expectedMode) throws Exception {
+        if (!startTestAndWaitForBroadcast(test)) {
+            return false;
+        }
+
+        // verify the test results
+        int mode = getMode();
+        Log.i(TAG, "After testing, zen-mode is set to: " + mode);
+        assertEquals(expectedMode, mode);
+        Log.i(TAG, "results_received: " + Utils.toBundleString(mResultExtras));
+        assertNotNull(mResultExtras);
+        if (expectedMode == ZEN_MODE_IS_ALARMS) {
+            assertTrue(mResultExtras.getBoolean(EXTRA_DO_NOT_DISTURB_MODE_ENABLED));
+            assertEquals(Utils.NUM_MINUTES_FOR_ZENMODE,
+                    mResultExtras.getInt(EXTRA_DO_NOT_DISTURB_MODE_MINUTES));
+        } else {
+            assertFalse(mResultExtras.getBoolean(EXTRA_DO_NOT_DISTURB_MODE_ENABLED));
+        }
+        Log.i(TAG, "Successfully Tested: " + test);
+        return true;
+    }
+
+    private int getMode() throws Settings.SettingNotFoundException {
+        return Settings.Global.getInt(mContext.getContentResolver(), ZEN_MODE);
+    }
+}
diff --git a/tests/tests/webkit/Android.mk b/tests/tests/webkit/Android.mk
index c2d8c3c..17a1f27 100644
--- a/tests/tests/webkit/Android.mk
+++ b/tests/tests/webkit/Android.mk
@@ -21,7 +21,7 @@
 # and when built explicitly put it in the data partition
 LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
 
-LOCAL_JAVA_LIBRARIES := android.test.runner
+LOCAL_JAVA_LIBRARIES := android.test.runner org.apache.http.legacy
 
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctsdeviceutillegacy ctstestserver ctstestrunner
 
diff --git a/tests/tests/webkit/AndroidManifest.xml b/tests/tests/webkit/AndroidManifest.xml
index a5bc2bb..fa25824 100644
--- a/tests/tests/webkit/AndroidManifest.xml
+++ b/tests/tests/webkit/AndroidManifest.xml
@@ -20,7 +20,6 @@
 
     <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
     <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
-    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <application android:maxRecents="1">
@@ -28,6 +27,7 @@
                   android:exported="true"
                   android:authorities="android.webkit.cts.MockContentProvider" />
         <uses-library android:name="android.test.runner" />
+        <uses-library android:name="org.apache.http.legacy" android:required="false" />
 
         <activity android:name="android.webkit.cts.CookieSyncManagerCtsActivity"
             android:label="CookieSyncManagerCtsActivity"
diff --git a/tests/tests/webkit/assets/webkit/test_bad_image_url.html b/tests/tests/webkit/assets/webkit/test_bad_image_url.html
new file mode 100644
index 0000000..b9e0054
--- /dev/null
+++ b/tests/tests/webkit/assets/webkit/test_bad_image_url.html
@@ -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.
+-->
+
+<html>
+  <body>
+    <img src="invalidscheme://some/resource" />
+  </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 c612886..856b4aa 100644
--- a/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/CookieManagerTest.java
@@ -319,8 +319,6 @@
         assertFalse(anyDeleted.get());
     }
 
-    /*
-    TODO: uncomment when acceptThirdPartyCookies implementation lands
     public void testThirdPartyCookie() throws Throwable {
         if (!NullWebViewUtils.isWebViewAvailable()) {
             return;
@@ -377,7 +375,6 @@
             mOnUiThread.getSettings().setJavaScriptEnabled(false);
         }
     }
-    */
 
     public void testb3167208() throws Exception {
         if (!NullWebViewUtils.isWebViewAvailable()) {
diff --git a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
index ba0e0e9..32b6167 100644
--- a/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/GeolocationTest.java
@@ -17,6 +17,7 @@
 package android.webkit.cts;
 
 import android.content.Context;
+import android.cts.util.LocationUtils;
 import android.cts.util.NullWebViewUtils;
 import android.cts.util.PollingCheck;
 import android.graphics.Bitmap;
@@ -136,6 +137,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
+        LocationUtils.registerMockLocationProvider(getInstrumentation(), true);
         WebView webview = getActivity().getWebView();
 
         if (webview != null) {
@@ -185,6 +187,7 @@
                 } catch (IllegalArgumentException e) {} // Not much to do about this
             }
         }
+        LocationUtils.registerMockLocationProvider(getInstrumentation(), false);
 
         if (mOnUiThread != null) {
             mOnUiThread.cleanUp();
diff --git a/tests/tests/webkit/src/android/webkit/cts/PostMessageTest.java b/tests/tests/webkit/src/android/webkit/cts/PostMessageTest.java
new file mode 100644
index 0000000..2a6af6e
--- /dev/null
+++ b/tests/tests/webkit/src/android/webkit/cts/PostMessageTest.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.NullWebViewUtils;
+import android.cts.util.PollingCheck;
+import android.net.Uri;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.webkit.WebMessage;
+import android.webkit.WebMessagePort;
+import android.webkit.WebView;
+
+import java.util.concurrent.CountDownLatch;
+import junit.framework.Assert;
+
+public class PostMessageTest extends ActivityInstrumentationTestCase2<WebViewCtsActivity> {
+    public static final long TIMEOUT = 20000L;
+
+    private WebView mWebView;
+    private WebViewOnUiThread mOnUiThread;
+
+    private static final String WEBVIEW_MESSAGE = "from_webview";
+    private static final String BASE_URI = "http://www.example.com";
+
+    public PostMessageTest() {
+        super("com.android.cts.webkit", WebViewCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final WebViewCtsActivity activity = getActivity();
+        mWebView = activity.getWebView();
+        if (mWebView != null) {
+            mOnUiThread = new WebViewOnUiThread(this, mWebView);
+            mOnUiThread.getSettings().setJavaScriptEnabled(true);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mOnUiThread != null) {
+            mOnUiThread.cleanUp();
+        }
+        super.tearDown();
+    }
+
+    private static final String TITLE_FROM_POST_MESSAGE =
+            "<!DOCTYPE html><html><body>"
+            + "    <script>"
+            + "        var received = '';"
+            + "        onmessage = function (e) {"
+            + "            received += e.data;"
+            + "            document.title = received; };"
+            + "    </script>"
+            + "</body></html>";
+
+    // Acks each received message from the message channel with a seq number.
+    private static final String CHANNEL_MESSAGE =
+            "<!DOCTYPE html><html><body>"
+            + "    <script>"
+            + "        var counter = 0;"
+            + "        onmessage = function (e) {"
+            + "            var myPort = e.ports[0];"
+            + "            myPort.onmessage = function (f) {"
+            + "                myPort.postMessage(f.data + counter++);"
+            + "            }"
+            + "        }"
+            + "   </script>"
+            + "</body></html>";
+
+    private void loadPage(String data) {
+        mOnUiThread.loadDataWithBaseURLAndWaitForCompletion(BASE_URI, data,
+                "text/html", "UTF-8", null);
+    }
+
+    private void waitForTitle(final String title) {
+        new PollingCheck(TIMEOUT) {
+            @Override
+            protected boolean check() {
+                return mOnUiThread.getTitle().equals(title);
+            }
+        }.run();
+    }
+
+    // Post a string message to main frame and make sure it is received.
+    public void testSimpleMessageToMainFrame() throws Throwable {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        loadPage(TITLE_FROM_POST_MESSAGE);
+        WebMessage message = new WebMessage(WEBVIEW_MESSAGE);
+        mOnUiThread.postWebMessage(message, Uri.parse(BASE_URI));
+        waitForTitle(WEBVIEW_MESSAGE);
+    }
+
+    // Post multiple messages to main frame and make sure they are received in
+    // correct order.
+    public void testMultipleMessagesToMainFrame() throws Throwable {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        loadPage(TITLE_FROM_POST_MESSAGE);
+        for (int i = 0; i < 10; i++) {
+            mOnUiThread.postWebMessage(new WebMessage(Integer.toString(i)),
+                    Uri.parse(BASE_URI));
+        }
+        waitForTitle("0123456789");
+    }
+
+    // Create a message channel and make sure it can be used for data transfer to/from js.
+    public void testMessageChannel() throws Throwable {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        loadPage(CHANNEL_MESSAGE);
+        final WebMessagePort[] channel = mOnUiThread.createWebMessageChannel();
+        WebMessage message = new WebMessage(WEBVIEW_MESSAGE, new WebMessagePort[]{channel[1]});
+        mOnUiThread.postWebMessage(message, Uri.parse(BASE_URI));
+        final int messageCount = 3;
+        final CountDownLatch latch = new CountDownLatch(messageCount);
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < messageCount; i++) {
+                    channel[0].postMessage(new WebMessage(WEBVIEW_MESSAGE + i));
+                }
+                channel[0].setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
+                    @Override
+                    public void onMessage(WebMessagePort port, WebMessage message) {
+                        int i = messageCount - (int)latch.getCount();
+                        assertEquals(WEBVIEW_MESSAGE + i + i, message.getData());
+                        latch.countDown();
+                    }
+                });
+            }
+        });
+        // Wait for all the responses to arrive.
+        boolean ignore = latch.await(TIMEOUT, java.util.concurrent.TimeUnit.MILLISECONDS);
+    }
+
+    // Test that a message port that is closed cannot used to send a message
+    public void testClose() throws Throwable {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        loadPage(CHANNEL_MESSAGE);
+        final WebMessagePort[] channel = mOnUiThread.createWebMessageChannel();
+        WebMessage message = new WebMessage(WEBVIEW_MESSAGE, new WebMessagePort[]{channel[1]});
+        mOnUiThread.postWebMessage(message, Uri.parse(BASE_URI));
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    channel[0].close();
+                    channel[0].postMessage(new WebMessage(WEBVIEW_MESSAGE));
+                } catch (IllegalStateException ex) {
+                    // expect to receive an exception
+                    return;
+                }
+                Assert.fail("A closed port cannot be used to transfer messages");
+            }
+         });
+    }
+
+    // Sends a new message channel from JS to Java.
+    private static final String CHANNEL_FROM_JS =
+            "<!DOCTYPE html><html><body>"
+            + "    <script>"
+            + "        var counter = 0;"
+            + "        var mc = new MessageChannel();"
+            + "        var received = '';"
+            + "        mc.port1.onmessage = function (e) {"
+            + "               received = e.data;"
+            + "               document.title = e.data;"
+            + "        };"
+            + "        onmessage = function (e) {"
+            + "            var myPort = e.ports[0];"
+            + "            myPort.postMessage('', [mc.port2]);"
+            + "        };"
+            + "   </script>"
+            + "</body></html>";
+
+    // Test a message port created in JS can be received and used for message transfer.
+    public void testReceiveMessagePort() throws Throwable {
+        final String hello = "HELLO";
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        loadPage(CHANNEL_FROM_JS);
+        final WebMessagePort[] channel = mOnUiThread.createWebMessageChannel();
+        WebMessage message = new WebMessage(WEBVIEW_MESSAGE, new WebMessagePort[]{channel[1]});
+        mOnUiThread.postWebMessage(message, Uri.parse(BASE_URI));
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                channel[0].setWebMessageCallback(new WebMessagePort.WebMessageCallback() {
+                    @Override
+                    public void onMessage(WebMessagePort port, WebMessage message) {
+                        message.getPorts()[0].postMessage(new WebMessage(hello));
+                    }
+                });
+            }
+        });
+        waitForTitle(hello);
+    }
+}
diff --git a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
index 30b8210..1ab5e5a 100644
--- a/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
+++ b/tests/tests/webkit/src/android/webkit/cts/TestHtmlConstants.java
@@ -67,6 +67,9 @@
     public static final String STOP_LOADING_URL = "webkit/test_stop_loading.html";
     public static final String BLANK_TAG_URL = "webkit/blank_tag.html";
     public static final String PAGE_WITH_LINK_URL = "webkit/page_with_link.html";
+    // Not a real page, just triggers a 404 response.
+    public static final String NON_EXISTENT_PAGE_URL = "webkit/generate_404.html";
+    public static final String BAD_IMAGE_PAGE_URL = "webkit/test_bad_image_url.html";
 
     // Must match the title of the page at
     // android/frameworks/base/core/res/res/raw/loaderror.html
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
index e9ff48f..592e308 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebSettingsTest.java
@@ -95,7 +95,7 @@
      * brackets are optional):
      * <p/>
      * Mozilla/5.0 (Linux;[ U;] Android <version>;[ <language>-<country>;]
-     * [<devicemodel>;] Build/<buildID>[; wv]) AppleWebKit/<major>.<minor> (KHTML, like Gecko)
+     * [<devicemodel>;] Build/<buildID>; wv) AppleWebKit/<major>.<minor> (KHTML, like Gecko)
      * Version/<major>.<minor> Chrome/<major>.<minor>.<branch>.<build>[ Mobile]
      * Safari/<major>.<minor>
      */
@@ -107,7 +107,7 @@
         Log.i(LOG_TAG, String.format("Checking user agent string %s", actualUserAgentString));
         final String patternString =
                 "Mozilla/5\\.0 \\(Linux;( U;)? Android ([^;]+);( (\\w+)-(\\w+);)?" +
-                "\\s?(.*)\\sBuild/(.+?)(; wv)?\\) AppleWebKit/(\\d+)\\.(\\d+) " +
+                "\\s?(.*)\\sBuild/(.+); wv\\) AppleWebKit/(\\d+)\\.(\\d+) " +
                 "\\(KHTML, like Gecko\\) " +
                 "Version/\\d+\\.\\d+ Chrome/\\d+\\.\\d+\\.\\d+\\.\\d+( Mobile)? " +
                 "Safari/(\\d+)\\.(\\d+)";
@@ -119,12 +119,11 @@
         //  5   - language
         //  6 - device model (optional)
         //  7 - build ID
-        //  8 - WebView identifier "; wv" (optional)
-        //  9 - AppleWebKit major version number
-        // 10 - AppleWebKit minor version number
-        // 11 - " Mobile" string (optional)
-        // 12 - Safari major version number
-        // 13 - Safari minor version number
+        //  8 - AppleWebKit major version number
+        //  9 - AppleWebKit minor version number
+        // 10 - " Mobile" string (optional)
+        // 11 - Safari major version number
+        // 12 - Safari minor version number
         Log.i(LOG_TAG, String.format("Trying to match pattern %s", patternString));
         final Pattern userAgentExpr = Pattern.compile(patternString);
         Matcher patternMatcher = userAgentExpr.matcher(actualUserAgentString);
@@ -506,6 +505,16 @@
         assertTrue(mSettings.getPluginsEnabled());
     }
 
+    public void testOffscreenPreRaster() {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        assertFalse(mSettings.getOffscreenPreRaster());
+
+        mSettings.setOffscreenPreRaster(true);
+        assertTrue(mSettings.getOffscreenPreRaster());
+    }
+
     public void testAccessPluginsPath() {
         if (!NullWebViewUtils.isWebViewAvailable()) {
             return;
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
index 5b906ba..0697429 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewClientTest.java
@@ -27,6 +27,7 @@
 import android.webkit.HttpAuthHandler;
 import android.webkit.ValueCallback;
 import android.webkit.WebChromeClient;
+import android.webkit.WebResourceError;
 import android.webkit.WebResourceRequest;
 import android.webkit.WebResourceResponse;
 import android.webkit.WebSettings;
@@ -223,6 +224,37 @@
                 webViewClient.hasOnReceivedErrorCode());
     }
 
+    public void testOnReceivedErrorForSubresource() throws Exception {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        final MockWebViewClient webViewClient = new MockWebViewClient();
+        mOnUiThread.setWebViewClient(webViewClient);
+        mWebServer = new CtsTestServer(getActivity());
+
+        assertEquals(null, webViewClient.hasOnReceivedResourceError());
+        String url = mWebServer.getAssetUrl(TestHtmlConstants.BAD_IMAGE_PAGE_URL);
+        mOnUiThread.loadUrlAndWaitForCompletion(url);
+        assertTrue(webViewClient.hasOnReceivedResourceError() != null);
+        assertEquals(WebViewClient.ERROR_UNSUPPORTED_SCHEME,
+                webViewClient.hasOnReceivedResourceError().getErrorCode());
+    }
+
+    public void testOnReceivedHttpError() throws Exception {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        final MockWebViewClient webViewClient = new MockWebViewClient();
+        mOnUiThread.setWebViewClient(webViewClient);
+        mWebServer = new CtsTestServer(getActivity());
+
+        assertEquals(null, webViewClient.hasOnReceivedHttpError());
+        String url = mWebServer.getAssetUrl(TestHtmlConstants.NON_EXISTENT_PAGE_URL);
+        mOnUiThread.loadUrlAndWaitForCompletion(url);
+        assertTrue(webViewClient.hasOnReceivedHttpError() != null);
+        assertEquals(404, webViewClient.hasOnReceivedHttpError().getStatusCode());
+    }
+
     public void testOnFormResubmission() throws Exception {
         if (!NullWebViewUtils.isWebViewAvailable()) {
             return;
@@ -504,6 +536,8 @@
         private boolean mOnPageFinishedCalled;
         private boolean mOnLoadResourceCalled;
         private int mOnReceivedErrorCode;
+        private WebResourceError mOnReceivedResourceError;
+        private WebResourceResponse mOnReceivedHttpError;
         private boolean mOnFormResubmissionCalled;
         private boolean mDoUpdateVisitedHistoryCalled;
         private boolean mOnReceivedHttpAuthRequestCalled;
@@ -532,6 +566,14 @@
             return mOnReceivedErrorCode;
         }
 
+        public WebResourceError hasOnReceivedResourceError() {
+            return mOnReceivedResourceError;
+        }
+
+        public WebResourceResponse hasOnReceivedHttpError() {
+            return mOnReceivedHttpError;
+        }
+
         public boolean hasOnFormResubmissionCalled() {
             return mOnFormResubmissionCalled;
         }
@@ -589,6 +631,20 @@
         }
 
         @Override
+        public void onReceivedError(WebView view, WebResourceRequest request,
+                WebResourceError error) {
+            super.onReceivedError(view, request, error);
+            mOnReceivedResourceError = error;
+        }
+
+        @Override
+        public void onReceivedHttpError(WebView view,  WebResourceRequest request,
+                WebResourceResponse errorResponse) {
+            super.onReceivedHttpError(view, request, errorResponse);
+            mOnReceivedHttpError = errorResponse;
+        }
+
+        @Override
         public void onFormResubmission(WebView view, Message dontResend, Message resend) {
             mOnFormResubmissionCalled = true;
             dontResend.sendToTarget();
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
index dcdeead..6555731 100644
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewSslTest.java
@@ -37,6 +37,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.security.KeyFactory;
+import java.security.KeyStore;
 import java.security.PrivateKey;
 import java.security.Principal;
 import java.security.cert.CertificateFactory;
@@ -764,6 +765,36 @@
         assertEquals(callCount + 1, webViewClient.getClientCertRequestCount());
     }
 
+    public void testProceedClientCertRequestKeyWithAndroidKeystoreKey() throws Throwable {
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+        mWebServer = new CtsTestServer(getActivity(), CtsTestServer.SslMode.NEEDS_CLIENT_AUTH);
+        String url = mWebServer.getAssetUrl(TestHtmlConstants.HELLO_WORLD_URL);
+        final ClientCertWebViewClient webViewClient = new ClientCertWebViewClient(
+                mOnUiThread,
+                true // use an Android Keystore backed private key
+                );
+        mOnUiThread.setWebViewClient(webViewClient);
+        clearClientCertPreferences();
+        mOnUiThread.loadUrlAndWaitForCompletion(url);
+        assertTrue(TestHtmlConstants.HELLO_WORLD_TITLE.equals(mOnUiThread.getTitle()));
+
+        // Test that the user's response for this server is kept in cache. Load a different
+        // page from the same server and make sure we don't receive a client cert request callback.
+        int callCount = webViewClient.getClientCertRequestCount();
+        url = mWebServer.getAssetUrl(TestHtmlConstants.HTML_URL1);
+        mOnUiThread.loadUrlAndWaitForCompletion(url);
+        assertTrue(TestHtmlConstants.HTML_URL1_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals(callCount, webViewClient.getClientCertRequestCount());
+
+        // Now clear the cache and reload the page. We should receive a new callback.
+        clearClientCertPreferences();
+        mOnUiThread.loadUrlAndWaitForCompletion(url);
+        assertTrue(TestHtmlConstants.HTML_URL1_TITLE.equals(mOnUiThread.getTitle()));
+        assertEquals(callCount + 1, webViewClient.getClientCertRequestCount());
+    }
+
     public void testIgnoreClientCertRequest() throws Throwable {
         if (!NullWebViewUtils.isWebViewAvailable()) {
             return;
@@ -925,12 +956,20 @@
         public static final int CANCEL = 2;
         public static final int IGNORE = 3;
 
+        private final boolean mKeyFromAndroidKeystore;
+
         private int mClientCertRequests;
         private int mAction = PROCEED;
         private Principal[] mPrincipals;
 
         public ClientCertWebViewClient(WebViewOnUiThread onUiThread) {
+            this(onUiThread, false);
+        }
+
+        public ClientCertWebViewClient(WebViewOnUiThread onUiThread,
+                boolean keyFromAndroidKeystore) {
             super(onUiThread);
+            mKeyFromAndroidKeystore = keyFromAndroidKeystore;
         }
 
         public int getClientCertRequestCount() {
@@ -973,6 +1012,21 @@
                     KeyFactory keyFactory = KeyFactory.getInstance("RSA");
                     PrivateKey key = keyFactory.generatePrivate(
                         new PKCS8EncodedKeySpec(FAKE_RSA_KEY_1));
+
+                    if (mKeyFromAndroidKeystore) {
+                        // Key needs to be backed by Android Keystore -- import it there.
+                        KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
+                        keyStore.load(null);
+                        Log.d(LOGTAG, "Importing private key into Android Keystore...");
+                        keyStore.setEntry(
+                                "fake1",
+                                new KeyStore.PrivateKeyEntry(key, certChain),
+                                null);
+
+                        key = (PrivateKey) keyStore.getKey("fake1", null);
+                        Log.i(LOGTAG, "Imported private key into Android Keystore. key: " + key);
+                    }
+
                     request.proceed(key, certChain);
                     return;
                 } catch (Exception e) {
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index 561df3a..23c8dba 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -65,6 +65,7 @@
 import android.webkit.WebView;
 import android.webkit.WebView.HitTestResult;
 import android.webkit.WebView.PictureListener;
+import android.webkit.WebView.VisualStateCallback;
 import android.webkit.WebViewClient;
 import android.webkit.WebViewDatabase;
 import android.webkit.cts.WebViewOnUiThread.WaitForLoadedClient;
@@ -122,6 +123,11 @@
      */
     private static final long SCROLL_WAIT_INTERVAL_MS = 200;
 
+    /**
+     * Epsilon used in page scale value comparisons.
+     */
+    private static final float PAGE_SCALE_EPSILON = 0.0001f;
+
     private WebView mWebView;
     private CtsTestServer mWebServer;
     private WebViewOnUiThread mOnUiThread;
@@ -219,6 +225,9 @@
         // full address
         assertEquals("455 LARKSPUR DRIVE CALIFORNIA SPRINGS CALIFORNIA 92826",
                 WebView.findAddress("455 LARKSPUR DRIVE CALIFORNIA SPRINGS CALIFORNIA 92826"));
+        // Zipcode is optional.
+        assertEquals("455 LARKSPUR DRIVE CALIFORNIA SPRINGS CALIFORNIA",
+                WebView.findAddress("455 LARKSPUR DRIVE CALIFORNIA SPRINGS CALIFORNIA"));
         // not an address
         assertNull(WebView.findAddress("This is not an address: no town, no state, no zip."));
     }
@@ -330,7 +339,7 @@
         // that a scale change does *not* happen.
         Thread.sleep(500);
         currScale = mOnUiThread.getScale();
-        assertEquals(currScale, previousScale);
+        assertEquals(currScale, previousScale, PAGE_SCALE_EPSILON);
 
         assertTrue(mOnUiThread.zoomOut());
         previousScale = currScale;
@@ -354,7 +363,7 @@
         // that a scale change does *not* happen.
         Thread.sleep(500);
         currScale = mOnUiThread.getScale();
-        assertEquals(currScale, previousScale);
+        assertEquals(currScale, previousScale, PAGE_SCALE_EPSILON);
 
         mOnUiThread.zoomBy(1.25f);
         previousScale = currScale;
@@ -378,7 +387,7 @@
         // that a scale change does *not* happen.
         Thread.sleep(500);
         currScale = mOnUiThread.getScale();
-        assertEquals(currScale, previousScale);
+        assertEquals(currScale, previousScale, PAGE_SCALE_EPSILON);
 
         mOnUiThread.zoomBy(0.8f);
         previousScale = currScale;
@@ -402,30 +411,7 @@
         // that a scale change does *not* happen.
         Thread.sleep(500);
         currScale = mOnUiThread.getScale();
-        assertEquals(currScale, previousScale);
-    }
-
-    @UiThreadTest
-    public void testSetScrollBarStyle() {
-        if (!NullWebViewUtils.isWebViewAvailable()) {
-            return;
-        }
-
-        mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
-        assertFalse(mWebView.overlayHorizontalScrollbar());
-        assertFalse(mWebView.overlayVerticalScrollbar());
-
-        mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
-        assertTrue(mWebView.overlayHorizontalScrollbar());
-        assertTrue(mWebView.overlayVerticalScrollbar());
-
-        mWebView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_INSET);
-        assertFalse(mWebView.overlayHorizontalScrollbar());
-        assertFalse(mWebView.overlayVerticalScrollbar());
-
-        mWebView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
-        assertTrue(mWebView.overlayHorizontalScrollbar());
-        assertTrue(mWebView.overlayVerticalScrollbar());
+        assertEquals(currScale, previousScale, PAGE_SCALE_EPSILON);
     }
 
     @UiThreadTest
@@ -434,15 +420,12 @@
             return;
         }
 
+        // These functions have no effect; just verify they don't crash
         mWebView.setHorizontalScrollbarOverlay(true);
         mWebView.setVerticalScrollbarOverlay(false);
+
         assertTrue(mWebView.overlayHorizontalScrollbar());
         assertFalse(mWebView.overlayVerticalScrollbar());
-
-        mWebView.setHorizontalScrollbarOverlay(false);
-        mWebView.setVerticalScrollbarOverlay(true);
-        assertFalse(mWebView.overlayHorizontalScrollbar());
-        assertTrue(mWebView.overlayVerticalScrollbar());
     }
 
     @UiThreadTest
@@ -2446,6 +2429,47 @@
         }
     }
 
+    public void testVisualStateCallbackCalled() throws Exception {
+        // Check that the visual state callback is called correctly.
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+
+        final CountDownLatch callbackLatch = new CountDownLatch(1);
+        final long kRequest = 100;
+
+        mOnUiThread.loadUrl("about:blank");
+
+        mOnUiThread.postVisualStateCallback(kRequest, new VisualStateCallback() {
+            public void onComplete(long requestId) {
+                assertEquals(kRequest, requestId);
+                callbackLatch.countDown();
+            }
+        });
+
+        assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
+    }
+
+    public void testOnPageCommitVisibleCalled() throws Exception {
+        // Check that the onPageCommitVisible callback is called
+        // correctly.
+        if (!NullWebViewUtils.isWebViewAvailable()) {
+            return;
+        }
+
+        final CountDownLatch callbackLatch = new CountDownLatch(1);
+
+        mOnUiThread.setWebViewClient(new WebViewClient() {
+                public void onPageCommitVisible(WebView view, String url) {
+                    assertEquals(url, "about:blank");
+                    callbackLatch.countDown();
+                }
+            });
+
+        mOnUiThread.loadUrl("about:blank");
+        assertTrue(callbackLatch.await(TEST_TIMEOUT, TimeUnit.MILLISECONDS));
+    }
+
     private void savePrintedPage(final PrintDocumentAdapter adapter,
             final ParcelFileDescriptor descriptor, final FutureTask<Boolean> result) {
         adapter.onWrite(new PageRange[] {PageRange.ALL_PAGES}, descriptor,
diff --git a/tests/tests/widget/AndroidManifest.xml b/tests/tests/widget/AndroidManifest.xml
index 4b88c01..bc43106 100644
--- a/tests/tests/widget/AndroidManifest.xml
+++ b/tests/tests/widget/AndroidManifest.xml
@@ -327,6 +327,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.widget.cts.DatePickerDialogCtsActivity"
+                  android:label="DatePickerDialogCtsActivity">
+            <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" />
 
diff --git a/tests/tests/widget/res/layout/relative_layout_baseline.xml b/tests/tests/widget/res/layout/relative_layout_baseline.xml
new file mode 100644
index 0000000..f4e9174
--- /dev/null
+++ b/tests/tests/widget/res/layout/relative_layout_baseline.xml
@@ -0,0 +1,67 @@
+<?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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_margin="5dp" >
+
+    <RelativeLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content" >
+
+        <Button
+            android:id="@+id/button1"
+            android:layout_alignParentTop="true"
+            android:layout_width="150dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dp"
+            android:text="@string/relative_view1"
+            android:layout_alignBottom="@+id/button2" />
+        <Button
+            android:id="@+id/button2"
+            android:layout_alignParentTop="true"
+            android:layout_toRightOf="@id/button1"
+            android:layout_width="150dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="20dp"
+            android:text="@string/relative_view2" />
+        <Button
+            android:id="@+id/button3"
+            android:layout_alignTop="@+id/button4"
+            android:layout_width="150dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:layout_alignBaseline="@+id/button4"
+            android:text="@string/relative_view3" />
+        <Button
+            android:id="@+id/button4"
+            android:layout_below="@id/button2"
+            android:layout_toRightOf="@id/button3"
+            android:layout_width="150dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="@string/relative_view4" />
+
+        <TextView
+            android:id="@+id/textView"
+            android:layout_below="@+id/button3"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+    </RelativeLayout>
+
+</ScrollView>
\ No newline at end of file
diff --git a/tests/tests/widget/res/layout/switch_layout.xml b/tests/tests/widget/res/layout/switch_layout.xml
new file mode 100644
index 0000000..a34845b
--- /dev/null
+++ b/tests/tests/widget/res/layout/switch_layout.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
+  -->
+
+<Switch xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:thumbTint="@android:color/white"
+        android:thumbTintMode="src_over"
+        android:trackTint="@android:color/black"
+        android:trackTintMode="src_atop" />
diff --git a/tests/tests/widget/res/layout/textview_layout.xml b/tests/tests/widget/res/layout/textview_layout.xml
index bf7f757..e3144eb 100644
--- a/tests/tests/widget/res/layout/textview_layout.xml
+++ b/tests/tests/widget/res/layout/textview_layout.xml
@@ -53,6 +53,7 @@
 
             <TextView android:id="@+id/textview_text"
                     android:text="@string/text_view_hello"
+                    android:breakStrategy="simple"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"/>
 
diff --git a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
index 9d8c7d2..2b38827 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsListViewTest.java
@@ -194,12 +194,53 @@
         assertSame(mListView, onScrollListener.getView());
         assertEquals(mListView.getChildCount(), onScrollListener.getVisibleItemCount());
         assertEquals(mCountryList.length, onScrollListener.getTotalItemCount());
-        assertEquals(OnScrollListener.SCROLL_STATE_IDLE, onScrollListener.getScrollState());
 
         assertTrue(onScrollListener.isOnScrollCalled());
         assertTrue(onScrollListener.isOnScrollStateChangedCalled());
     }
 
+    public void testFling() throws Throwable {
+        MockOnScrollListener onScrollListener = new MockOnScrollListener();
+        mListView.setOnScrollListener(onScrollListener);
+
+        setAdapter();
+
+        // Fling down from top, expect a scroll.
+        fling(10000, onScrollListener);
+        assertTrue(onScrollListener.isOnScrollCalled());
+        assertTrue(0 < onScrollListener.getFirstVisibleItem());
+
+        // Fling up the same amount, expect a scroll to the original position.
+        fling(-10000, onScrollListener);
+        assertTrue(onScrollListener.isOnScrollCalled());
+        assertEquals(0, onScrollListener.getFirstVisibleItem());
+
+        // Fling up again, expect no scroll, as the viewport is already at top.
+        fling(-10000, onScrollListener);
+        assertFalse(onScrollListener.isOnScrollCalled());
+        assertEquals(0, onScrollListener.getFirstVisibleItem());
+
+        // Fling up again with a huge velocity, expect no scroll.
+        fling(-50000, onScrollListener);
+        assertFalse(onScrollListener.isOnScrollCalled());
+        assertEquals(0, onScrollListener.getFirstVisibleItem());
+    }
+
+    private void fling(int velocityY, MockOnScrollListener onScrollListener) throws Throwable {
+        onScrollListener.reset();
+
+        final int v = velocityY;
+        runTestOnUiThread(new Runnable() {
+            public void run() {
+                mListView.fling(v);
+            }
+        });
+
+        do {
+            mInstrumentation.waitForIdleSync();
+        } while (onScrollListener.getScrollState() != OnScrollListener.SCROLL_STATE_IDLE);
+    }
+
     public void testGetFocusedRect() throws Throwable {
         setAdapter(mAdapter_short);
         setListSelection(0);
diff --git a/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java b/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
index 419a1c8..dfad3bbb 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsSeekBarTest.java
@@ -60,7 +60,7 @@
 
         new MyAbsSeekBar(mActivity, null);
 
-        new MyAbsSeekBar(mActivity, null, com.android.internal.R.attr.progressBarStyle);
+        new MyAbsSeekBar(mActivity, null, android.R.attr.progressBarStyle);
     }
 
     public void testAccessThumbOffset() {
diff --git a/tests/tests/widget/src/android/widget/cts/AbsSpinnerTest.java b/tests/tests/widget/src/android/widget/cts/AbsSpinnerTest.java
index 10e1658..9669c7c 100644
--- a/tests/tests/widget/src/android/widget/cts/AbsSpinnerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AbsSpinnerTest.java
@@ -58,7 +58,7 @@
 
         new Spinner(mContext, null);
 
-        new Spinner(mContext, null, com.android.internal.R.attr.spinnerStyle);
+        new Spinner(mContext, null, android.R.attr.spinnerStyle);
 
         new Gallery(mContext);
         new Gallery(mContext, null);
diff --git a/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java b/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java
index 6a2240e..ccbdd56 100644
--- a/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/AdapterViewTest.java
@@ -317,13 +317,8 @@
             //expected
         }
 
-        try {
-            assertEquals(AdapterView.INVALID_POSITION,
-                    mAdapterView.getPositionForView(new ImageView(mActivity)));
-            fail("Should throw NullPointerException");
-        } catch (NullPointerException e) {
-            //expected
-        }
+        assertEquals(AdapterView.INVALID_POSITION,
+                mAdapterView.getPositionForView(new ImageView(mActivity)));
     }
 
     public void testChangeFocusable() {
diff --git a/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java b/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java
index 1e17ea7..fdca64c 100644
--- a/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ArrayAdapterTest.java
@@ -21,6 +21,7 @@
 import java.util.List;
 
 import android.content.Context;
+import android.content.res.Resources.Theme;
 import android.database.DataSetObserver;
 import android.test.InstrumentationTestCase;
 import android.test.UiThreadTest;
@@ -204,6 +205,12 @@
         mArrayAdapter.setDropDownViewResource(INVALD_ID);
     }
 
+    public void testAccessDropDownViewTheme() {
+        Theme theme = mContext.getResources().newTheme();
+        mArrayAdapter.setDropDownViewTheme(theme);
+        assertSame(theme, mArrayAdapter.getDropDownViewTheme());
+    }
+
     /**
      * insert the item to the specific position, notify data changed
      * check -1, normal, > count
diff --git a/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java b/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java
index bf5382a..98bf047 100644
--- a/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CompoundButtonTest.java
@@ -188,6 +188,7 @@
         // set null drawable
         compoundButton = new MockCompoundButton(mContext);
         compoundButton.setButtonDrawable(null);
+        assertNull(compoundButton.getButtonDrawable());
 
         // set drawable when checkedTextView is GONE
         compoundButton = new MockCompoundButton(mContext);
@@ -197,6 +198,7 @@
         assertEquals(StateSet.WILD_CARD, firstDrawable.getState());
 
         compoundButton.setButtonDrawable(firstDrawable);
+        assertSame(firstDrawable, compoundButton.getButtonDrawable());
         assertFalse(firstDrawable.isVisible());
 
         // update drawable when checkedTextView is VISIBLE
@@ -206,6 +208,7 @@
         assertEquals(StateSet.WILD_CARD, secondDrawable.getState());
 
         compoundButton.setButtonDrawable(secondDrawable);
+        assertSame(secondDrawable, compoundButton.getButtonDrawable());
         assertTrue(secondDrawable.isVisible());
         // the firstDrawable is not active.
         assertFalse(firstDrawable.isVisible());
@@ -240,7 +243,7 @@
         compoundButton.setChecked(true);
         int[] checkedState = compoundButton.onCreateDrawableState(0);
         assertEquals(state[0], checkedState[0]);
-        assertEquals(com.android.internal.R.attr.state_checked,
+        assertEquals(android.R.attr.state_checked,
                 checkedState[checkedState.length - 1]);
 
         // compoundButton is not checked again.
diff --git a/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java b/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
index 0916e59..730083e 100644
--- a/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/CursorAdapterTest.java
@@ -19,8 +19,8 @@
 import java.io.File;
 
 import android.content.Context;
+import android.content.res.Resources.Theme;
 import android.cts.util.PollingCheck;
-import android.cts.util.ReadElf;
 import android.cts.util.TestThread;
 import android.database.ContentObserver;
 import android.database.Cursor;
@@ -39,7 +39,6 @@
 
 import com.android.cts.widget.R;
 
-
 /**
  * Test {@link CursorAdapter}.
  */
@@ -253,6 +252,14 @@
     }
 
     @UiThreadTest
+    public void testAccessDropDownViewTheme() {
+        CursorAdapter cursorAdapter = new MockCursorAdapter(mContext, null);
+        Theme theme = mContext.getResources().newTheme();
+        cursorAdapter.setDropDownViewTheme(theme);
+        assertSame(theme, cursorAdapter.getDropDownViewTheme());
+    }
+
+    @UiThreadTest
     public void testGetFilter() {
         CursorAdapter cursorAdapter = new MockCursorAdapter(mContext, mCursor);
         Filter filter = cursorAdapter.getFilter();
@@ -338,14 +345,23 @@
     }
 
     private final class MockCursorAdapter extends CursorAdapter {
+        private Context mContext;
+        private boolean mAutoRequery;
+
         private boolean mContentChanged = false;
 
         public MockCursorAdapter(Context context, Cursor c) {
             super(context, c);
+
+            mContext = context;
+            mAutoRequery = false;
         }
 
         public MockCursorAdapter(Context context, Cursor c, boolean autoRequery) {
             super(context, c, autoRequery);
+
+            mContext = context;
+            mAutoRequery = autoRequery;
         }
 
         public Context getContext() {
@@ -375,6 +391,9 @@
         @Override
         public void init(Context context, Cursor c, boolean autoRequery) {
             super.init(context, c, autoRequery);
+
+            mContext = context;
+            mAutoRequery = autoRequery;
         }
 
         @Override
diff --git a/tests/tests/widget/src/android/widget/cts/DatePickerDialogCtsActivity.java b/tests/tests/widget/src/android/widget/cts/DatePickerDialogCtsActivity.java
new file mode 100644
index 0000000..ea8c3c4
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/DatePickerDialogCtsActivity.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 android.widget.cts;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+/**
+ * A minimal application for DatePickerDialog test.
+ */
+public class DatePickerDialogCtsActivity extends Activity {
+    /**
+     * Called with the activity is first created.
+     */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/DatePickerDialogTest.java b/tests/tests/widget/src/android/widget/cts/DatePickerDialogTest.java
new file mode 100644
index 0000000..1477f73
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/DatePickerDialogTest.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.widget.cts;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.DatePickerDialog;
+import android.content.Context;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+
+/**
+ * Test {@link DatePickerDialog}.
+ */
+public class DatePickerDialogTest extends
+        ActivityInstrumentationTestCase2<DatePickerDialogCtsActivity> {
+
+    private Activity mActivity;
+
+    public DatePickerDialogTest() {
+        super(DatePickerDialogCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mActivity = getActivity();
+    }
+
+    @UiThreadTest
+    @SuppressWarnings("deprecation")
+    public void testConstructor() {
+        new DatePickerDialog(mActivity, null, 1970, 1, 1);
+
+        new DatePickerDialog(mActivity, AlertDialog.THEME_TRADITIONAL, null, 1970, 1, 1);
+
+        new DatePickerDialog(mActivity, AlertDialog.THEME_HOLO_DARK, null, 1970, 1, 1);
+
+        new DatePickerDialog(mActivity,
+                android.R.style.Theme_Material_Dialog_Alert, null, 1970, 1, 1);
+
+        try {
+            new DatePickerDialog(null, null, 1970, 1, 1);
+            fail("should throw NullPointerException");
+        } catch (Exception e) {
+        }
+    }
+
+    @UiThreadTest
+    public void testShowDismiss() {
+        DatePickerDialog d = createDatePickerDialog();
+
+        d.show();
+        assertTrue("Showing date picker", d.isShowing());
+
+        d.show();
+        assertTrue("Date picker still showing", d.isShowing());
+
+        d.dismiss();
+        assertFalse("Dismissed date picker", d.isShowing());
+
+        d.dismiss();
+        assertFalse("Date picker still dismissed", d.isShowing());
+    }
+
+    private MockDatePickerDialog createDatePickerDialog() {
+        return new MockDatePickerDialog(mActivity, null, 1970, 1, 1);
+    }
+
+    private class MockDatePickerDialog extends DatePickerDialog {
+        public MockDatePickerDialog(Context context, OnDateSetListener callBack,
+                int year, int monthOfYear, int dayOfMonth) {
+            super(context, callBack, year, monthOfYear, dayOfMonth);
+        }
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/DatePickerTest.java b/tests/tests/widget/src/android/widget/cts/DatePickerTest.java
index fdadc2c..3fa238e 100644
--- a/tests/tests/widget/src/android/widget/cts/DatePickerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/DatePickerTest.java
@@ -17,7 +17,6 @@
 package android.widget.cts;
 
 import com.android.cts.widget.R;
-import com.android.internal.util.XmlUtils;
 
 import android.content.Context;
 import android.content.res.XmlResourceParser;
@@ -29,6 +28,7 @@
 import android.util.Xml;
 import android.view.View;
 import android.widget.DatePicker;
+import android.widget.cts.util.XmlUtils;
 
 /**
  * Test {@link DatePicker}.
diff --git a/tests/tests/widget/src/android/widget/cts/DialerFilterTest.java b/tests/tests/widget/src/android/widget/cts/DialerFilterTest.java
index a8584ae..68a17e7 100644
--- a/tests/tests/widget/src/android/widget/cts/DialerFilterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/DialerFilterTest.java
@@ -387,9 +387,9 @@
         final MockDialerFilter dialerFilter = new MockDialerFilter(mActivity);
 
         final EditText text1 = new EditText(mActivity);
-        text1.setId(com.android.internal.R.id.hint);
+        text1.setId(android.R.id.hint);
         final EditText text2 = new EditText(mActivity);
-        text2.setId(com.android.internal.R.id.primary);
+        text2.setId(android.R.id.primary);
 
         dialerFilter.addView(text1, new RelativeLayout.LayoutParams(
                 RelativeLayout.LayoutParams.WRAP_CONTENT,
diff --git a/tests/tests/widget/src/android/widget/cts/DigitalClockTest.java b/tests/tests/widget/src/android/widget/cts/DigitalClockTest.java
index 2f2cc1a..86a9672 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 java.io.IOException;
+import com.android.cts.widget.R;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -29,9 +29,9 @@
 import android.util.Xml;
 import android.widget.DigitalClock;
 import android.widget.LinearLayout;
+import android.widget.cts.util.XmlUtils;
 
-import com.android.cts.widget.R;
-import com.android.internal.util.XmlUtils;
+import java.io.IOException;
 
 
 /**
diff --git a/tests/tests/widget/src/android/widget/cts/GalleryTest.java b/tests/tests/widget/src/android/widget/cts/GalleryTest.java
index 2813965..581107c 100644
--- a/tests/tests/widget/src/android/widget/cts/GalleryTest.java
+++ b/tests/tests/widget/src/android/widget/cts/GalleryTest.java
@@ -17,16 +17,17 @@
 package android.widget.cts;
 
 import com.android.cts.widget.R;
-import com.android.internal.view.menu.ContextMenuBuilder;
-
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
 import android.app.Activity;
 import android.app.Instrumentation;
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
 import android.cts.util.WidgetTestUtils;
+import android.graphics.drawable.Drawable;
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
@@ -36,7 +37,8 @@
 import android.view.ContextMenu;
 import android.view.Gravity;
 import android.view.KeyEvent;
-import android.view.MotionEvent;
+import android.view.MenuItem;
+import android.view.SubMenu;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ContextMenu.ContextMenuInfo;
@@ -305,35 +307,6 @@
         assertEquals(index + 1, gallery.getChildDrawingOrder(childCount, index));
     }
 
-    @UiThreadTest
-    public void testGetContextMenuInfo() {
-        MockOnCreateContextMenuListener listener = new MockOnCreateContextMenuListener();
-        MyGallery gallery = new MyGallery(mContext);
-        gallery.setOnCreateContextMenuListener(listener);
-        assertFalse(listener.hasCreatedContextMenu());
-        gallery.createContextMenu(new ContextMenuBuilder(mContext));
-        assertTrue(listener.hasCreatedContextMenu());
-        assertSame(gallery.getContextMenuInfo(), listener.getContextMenuInfo());
-    }
-
-    private static class MockOnCreateContextMenuListener implements OnCreateContextMenuListener {
-        private boolean hasCreatedContextMenu;
-        private ContextMenuInfo mContextMenuInfo;
-
-        public boolean hasCreatedContextMenu() {
-            return hasCreatedContextMenu;
-        }
-
-        public ContextMenuInfo getContextMenuInfo() {
-            return mContextMenuInfo;
-        }
-
-        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
-            hasCreatedContextMenu = true;
-            mContextMenuInfo = menuInfo;
-        }
-    }
-
     private static class ImageAdapter extends BaseAdapter {
         public ImageAdapter(Context c) {
             mContext = c;
diff --git a/tests/tests/widget/src/android/widget/cts/GridViewTest.java b/tests/tests/widget/src/android/widget/cts/GridViewTest.java
index 042986c..3c615bd 100644
--- a/tests/tests/widget/src/android/widget/cts/GridViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/GridViewTest.java
@@ -83,7 +83,7 @@
 
         new GridView(mActivity, null);
 
-        new GridView(mActivity, null, com.android.internal.R.attr.gridViewStyle);
+        new GridView(mActivity, null, android.R.attr.gridViewStyle);
 
         XmlPullParser parser = mActivity.getResources().getXml(R.layout.gridview_layout);
         AttributeSet attrs = Xml.asAttributeSet(parser);
diff --git a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
index c93d4a1..aa1df34 100644
--- a/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ImageViewTest.java
@@ -38,6 +38,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.graphics.drawable.PaintDrawable;
 import android.net.Uri;
 import android.test.ActivityInstrumentationTestCase;
@@ -173,6 +174,23 @@
     }
 
     @UiThreadTest
+    public void testSetImageIcon() {
+        mImageView = findImageViewById(R.id.imageview);
+        mImageView.setImageIcon(null);
+        assertNull(mImageView.getDrawable());
+
+        Icon icon = Icon.createWithResource(mActivity, R.drawable.testimage);
+        mImageView.setImageIcon(icon);
+        assertTrue(mImageView.isLayoutRequested());
+        assertNotNull(mImageView.getDrawable());
+        Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
+        BitmapDrawable testimageBitmap = (BitmapDrawable) drawable;
+        Drawable imageViewDrawable = mImageView.getDrawable();
+        BitmapDrawable imageViewBitmap = (BitmapDrawable) imageViewDrawable;
+        WidgetTestUtils.assertEquals(testimageBitmap.getBitmap(), imageViewBitmap.getBitmap());
+    }
+
+    @UiThreadTest
     public void testSetImageResource() {
         mImageView = findImageViewById(R.id.imageview);
         mImageView.setImageResource(-1);
@@ -181,7 +199,7 @@
         mImageView.setImageResource(R.drawable.testimage);
         assertTrue(mImageView.isLayoutRequested());
         assertNotNull(mImageView.getDrawable());
-        Drawable drawable = mActivity.getResources().getDrawable(R.drawable.testimage);
+        Drawable drawable = mActivity.getDrawable(R.drawable.testimage);
         BitmapDrawable testimageBitmap = (BitmapDrawable) drawable;
         Drawable imageViewDrawable = mImageView.getDrawable();
         BitmapDrawable imageViewBitmap = (BitmapDrawable) imageViewDrawable;
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 8ecca6f..31be765 100644
--- a/tests/tests/widget/src/android/widget/cts/LinearLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/LinearLayout_LayoutParamsTest.java
@@ -17,8 +17,6 @@
 package android.widget.cts;
 
 import com.android.cts.widget.R;
-import com.android.internal.util.XmlUtils;
-
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -27,6 +25,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.view.ViewGroup.MarginLayoutParams;
 import android.widget.LinearLayout;
+import android.widget.cts.util.XmlUtils;
 
 import java.io.IOException;
 
diff --git a/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
new file mode 100644
index 0000000..c4636fc
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/ListPopupWindowTest.java
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.app.Instrumentation;
+import android.content.Context;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.view.Display;
+import android.view.View;
+import android.view.WindowManager;
+import android.widget.ListPopupWindow;
+import android.widget.PopupWindow;
+import android.widget.PopupWindow.OnDismissListener;
+
+public class ListPopupWindowTest extends
+        ActivityInstrumentationTestCase2<MockPopupWindowCtsActivity> {
+    private Instrumentation mInstrumentation;
+    private Activity mActivity;
+
+    /** The list popup window. */
+    private ListPopupWindow mPopupWindow;
+
+    /**
+     * Instantiates a new popup window test.
+     */
+    public ListPopupWindowTest() {
+        super(MockPopupWindowCtsActivity.class);
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see android.test.ActivityInstrumentationTestCase#setUp()
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mActivity = getActivity();
+    }
+
+    public void testConstructor() {
+        new ListPopupWindow(mActivity);
+
+        new ListPopupWindow(mActivity, null);
+
+        new ListPopupWindow(mActivity, null, android.R.attr.popupWindowStyle);
+
+        new ListPopupWindow(mActivity, null, 0, android.R.style.Widget_Material_ListPopupWindow);
+    }
+
+    public void testAccessBackground() {
+        mPopupWindow = new ListPopupWindow(mActivity);
+
+        Drawable drawable = new ColorDrawable();
+        mPopupWindow.setBackgroundDrawable(drawable);
+        assertSame(drawable, mPopupWindow.getBackground());
+
+        mPopupWindow.setBackgroundDrawable(null);
+        assertNull(mPopupWindow.getBackground());
+    }
+
+    public void testAccessAnimationStyle() {
+        mPopupWindow = new ListPopupWindow(mActivity);
+        assertEquals(0, mPopupWindow.getAnimationStyle());
+
+        mPopupWindow.setAnimationStyle(android.R.style.Animation_Toast);
+        assertEquals(android.R.style.Animation_Toast, mPopupWindow.getAnimationStyle());
+
+        // abnormal values
+        mPopupWindow.setAnimationStyle(-100);
+        assertEquals(-100, mPopupWindow.getAnimationStyle());
+    }
+
+    public void testAccessHeight() {
+        mPopupWindow = new ListPopupWindow(mActivity);
+        assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, mPopupWindow.getHeight());
+
+        int height = getDisplay().getHeight() / 2;
+        mPopupWindow.setHeight(height);
+        assertEquals(height, mPopupWindow.getHeight());
+
+        height = getDisplay().getHeight();
+        mPopupWindow.setHeight(height);
+        assertEquals(height, mPopupWindow.getHeight());
+
+        mPopupWindow.setHeight(0);
+        assertEquals(0, mPopupWindow.getHeight());
+
+        height = getDisplay().getHeight() * 2;
+        mPopupWindow.setHeight(height);
+        assertEquals(height, mPopupWindow.getHeight());
+
+        height = -getDisplay().getHeight() / 2;
+        mPopupWindow.setHeight(height);
+        assertEquals(height, mPopupWindow.getHeight());
+    }
+
+    /**
+     * Gets the display.
+     *
+     * @return the display
+     */
+    private Display getDisplay() {
+        WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
+        return wm.getDefaultDisplay();
+    }
+
+    public void testAccessWidth() {
+        mPopupWindow = new ListPopupWindow(mActivity);
+        assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, mPopupWindow.getWidth());
+
+        int width = getDisplay().getWidth() / 2;
+        mPopupWindow.setWidth(width);
+        assertEquals(width, mPopupWindow.getWidth());
+
+        width = getDisplay().getWidth();
+        mPopupWindow.setWidth(width);
+        assertEquals(width, mPopupWindow.getWidth());
+
+        mPopupWindow.setWidth(0);
+        assertEquals(0, mPopupWindow.getWidth());
+
+        width = getDisplay().getWidth() * 2;
+        mPopupWindow.setWidth(width);
+        assertEquals(width, mPopupWindow.getWidth());
+
+        width = - getDisplay().getWidth() / 2;
+        mPopupWindow.setWidth(width);
+        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);
+
+        final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
+        mPopupWindow.setAnchorView(upperAnchor);
+
+        mInstrumentation.runOnMainSync(new Runnable() {
+            public void run() {
+                mPopupWindow.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertTrue(mPopupWindow.isShowing());
+
+        mPopupWindow.getListView().getLocationOnScreen(viewOnScreenXY);
+        upperAnchor.getLocationOnScreen(anchorXY);
+        mPopupWindow.getListView().getLocationInWindow(viewInWindowXY);
+        assertEquals(anchorXY[0] + viewInWindowXY[0], viewOnScreenXY[0]);
+        assertEquals(anchorXY[1] + viewInWindowXY[1] + upperAnchor.getHeight(), viewOnScreenXY[1]);
+
+        dismissPopup();
+    }
+
+    public void testSetWindowLayoutType() {
+        mPopupWindow = new ListPopupWindow(mActivity);
+
+        final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
+        mPopupWindow.setAnchorView(upperAnchor);
+        mPopupWindow.setWindowLayoutType(
+                WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+
+        mInstrumentation.runOnMainSync(new Runnable() {
+            public void run() {
+                mPopupWindow.show();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        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();
+
+        mPopupWindow.dismiss();
+        assertFalse(mPopupWindow.isShowing());
+
+        mPopupWindow.dismiss();
+        assertFalse(mPopupWindow.isShowing());
+    }
+
+    public void testSetOnDismissListener() {
+        mPopupWindow = new ListPopupWindow(mActivity);
+        mPopupWindow.setOnDismissListener(null);
+
+        MockOnDismissListener onDismissListener = new MockOnDismissListener();
+        mPopupWindow.setOnDismissListener(onDismissListener);
+        showPopup();
+        dismissPopup();
+        assertEquals(1, onDismissListener.getOnDismissCalledCount());
+
+        showPopup();
+        dismissPopup();
+        assertEquals(2, onDismissListener.getOnDismissCalledCount());
+
+        mPopupWindow.setOnDismissListener(null);
+        showPopup();
+        dismissPopup();
+        assertEquals(2, onDismissListener.getOnDismissCalledCount());
+    }
+
+    public void testAccessInputMethodMode() {
+        mPopupWindow = new ListPopupWindow(mActivity);
+        assertEquals(PopupWindow.INPUT_METHOD_NEEDED, mPopupWindow.getInputMethodMode());
+
+        mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_FROM_FOCUSABLE);
+        assertEquals(PopupWindow.INPUT_METHOD_FROM_FOCUSABLE, mPopupWindow.getInputMethodMode());
+
+        mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
+        assertEquals(PopupWindow.INPUT_METHOD_NEEDED, mPopupWindow.getInputMethodMode());
+
+        mPopupWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
+        assertEquals(PopupWindow.INPUT_METHOD_NOT_NEEDED, mPopupWindow.getInputMethodMode());
+
+        mPopupWindow.setInputMethodMode(-1);
+        assertEquals(-1, mPopupWindow.getInputMethodMode());
+    }
+
+    /**
+     * 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 {
+
+        /** 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++;
+        }
+
+    }
+
+    /**
+     * 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.setAnchorView(anchor);
+                mPopupWindow.show();
+                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.waitForIdleSync();
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/ListViewTest.java b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
index 5f0967a..838f7a8 100644
--- a/tests/tests/widget/src/android/widget/cts/ListViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ListViewTest.java
@@ -17,7 +17,6 @@
 package android.widget.cts;
 
 import com.android.cts.widget.R;
-import com.google.android.collect.Lists;
 
 import org.xmlpull.v1.XmlPullParser;
 
@@ -32,12 +31,14 @@
 import android.test.UiThreadTest;
 import android.test.suitebuilder.annotation.MediumTest;
 import android.util.AttributeSet;
+import android.util.Pair;
 import android.util.SparseBooleanArray;
 import android.util.Xml;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.LayoutAnimationController;
+import android.widget.AbsListView;
 import android.widget.AdapterView;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ArrayAdapter;
@@ -46,7 +47,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 
 import junit.framework.Assert;
@@ -361,6 +361,53 @@
         assertEquals(2, mListView.getHeaderViewsCount());
     }
 
+    public void testHeaderFooterType() throws Throwable {
+        final TextView headerView = new TextView(getActivity());
+        final List<Pair<View, View>> mismatch = new ArrayList<Pair<View, View>>();
+        final ArrayAdapter adapter = new ArrayAdapter<String>(mActivity,
+                android.R.layout.simple_list_item_1, mNameList) {
+            @Override
+            public int getItemViewType(int position) {
+                return position == 0 ? AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER :
+                        super.getItemViewType(position - 1);
+            }
+
+            @Override
+            public View getView(int position, View convertView, ViewGroup parent) {
+                if (position == 0) {
+                    if (convertView != null && convertView != headerView) {
+                        mismatch.add(new Pair<View, View>(headerView, convertView));
+                    }
+                    return headerView;
+                } else {
+                    return super.getView(position - 1, convertView, parent);
+                }
+            }
+
+            @Override
+            public int getCount() {
+                return super.getCount() + 1;
+            }
+        };
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mListView.setAdapter(adapter);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        runTestOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                adapter.notifyDataSetChanged();
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        assertEquals(0, mismatch.size());
+    }
+
     public void testAccessDivider() {
         mInstrumentation.runOnMainSync(new Runnable() {
             public void run() {
@@ -380,7 +427,6 @@
 
         final Drawable d = mActivity.getResources().getDrawable(R.drawable.scenery);
 
-        Rect r2 = d.getBounds();
         mInstrumentation.runOnMainSync(new Runnable() {
             public void run() {
                 mListView.setDivider(d);
@@ -388,7 +434,7 @@
         });
         mInstrumentation.waitForIdleSync();
         assertSame(d, mListView.getDivider());
-        assertEquals(r2.bottom - r2.top, mListView.getDividerHeight());
+        assertEquals(d.getBounds().height(), mListView.getDividerHeight());
 
         mInstrumentation.runOnMainSync(new Runnable() {
             public void run() {
@@ -397,7 +443,7 @@
         });
         mInstrumentation.waitForIdleSync();
         assertEquals(10, mListView.getDividerHeight());
-        assertEquals(10, r2.bottom - r2.top);
+        assertEquals(10, d.getBounds().height());
     }
 
     public void testSetSelection() {
@@ -679,7 +725,8 @@
     @MediumTest
     public void testRequestLayout() throws Exception {
         ListView listView = new ListView(mActivity);
-        List<String> items = Lists.newArrayList("hello");
+        List<String> items = new ArrayList<>();
+        items.add("hello");
         Adapter<String> adapter = new Adapter<String>(mActivity, 0, items);
         listView.setAdapter(adapter);
 
@@ -703,7 +750,8 @@
         ListView listView = new ListView(mActivity);
         // We use a header as the unselectable item to remain after the selectable one is removed.
         listView.addHeaderView(new View(mActivity), null, false);
-        List<String> items = Lists.newArrayList("hello");
+        List<String> items = new ArrayList<>();
+        items.add("hello");
         Adapter<String> adapter = new Adapter<String>(mActivity, 0, items);
         listView.setAdapter(adapter);
 
diff --git a/tests/tests/widget/src/android/widget/cts/MockTextView.java b/tests/tests/widget/src/android/widget/cts/MockTextView.java
index 138338c..977e4b2 100644
--- a/tests/tests/widget/src/android/widget/cts/MockTextView.java
+++ b/tests/tests/widget/src/android/widget/cts/MockTextView.java
@@ -179,19 +179,19 @@
     }
 
     public int getFrameLeft() {
-        return mLeft;
+        return getLeft();
     }
 
     public int getFrameTop() {
-        return mTop;
+        return getTop();
     }
 
     public int getFrameRight() {
-        return mRight;
+        return getRight();
     }
 
     public int getFrameBottom() {
-        return mBottom;
+        return getBottom();
     }
 
     public int getBottomPaddingOffset() {
diff --git a/tests/tests/widget/src/android/widget/cts/MyGallery.java b/tests/tests/widget/src/android/widget/cts/MyGallery.java
index 91665ee..27b5d45 100644
--- a/tests/tests/widget/src/android/widget/cts/MyGallery.java
+++ b/tests/tests/widget/src/android/widget/cts/MyGallery.java
@@ -49,10 +49,6 @@
         return super.getChildStaticTransformation(child, t);
     }
 
-    protected void setParent(ViewParent v) {
-        mParent = v;
-    }
-
     @Override
     protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
         return super.checkLayoutParams(p);
diff --git a/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
new file mode 100644
index 0000000..2dff4cb
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/PopupMenuTest.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.Gravity;
+import android.widget.PopupMenu;
+
+
+public class PopupMenuTest extends
+        ActivityInstrumentationTestCase2<MockPopupWindowCtsActivity> {
+    private Instrumentation mInstrumentation;
+    private Activity mActivity;
+
+    public PopupMenuTest() {
+        super("com.android.cts.widget", MockPopupWindowCtsActivity.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mInstrumentation = getInstrumentation();
+        mActivity = getActivity();
+    }
+
+    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());
+    }
+
+    public void testOnDismissListener() {
+        final PopupMenu popupMenu = new PopupMenu(mActivity,
+                mActivity.findViewById(R.id.anchor_middle_left));
+        TestPopupDismissListener listener = new TestPopupDismissListener();
+        popupMenu.setOnDismissListener(listener);
+
+        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());
+    }
+
+    private class TestPopupDismissListener implements PopupMenu.OnDismissListener {
+        int mDismissCount;
+
+        @Override
+        public void onDismiss(PopupMenu menu) {
+            mDismissCount++;
+        }
+
+        int getDismissCount() {
+            return mDismissCount;
+        }
+    }
+}
diff --git a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
index ae12f9c..bb638e4 100644
--- a/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
+++ b/tests/tests/widget/src/android/widget/cts/PopupWindowTest.java
@@ -29,6 +29,8 @@
 import android.os.SystemClock;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
+import android.transition.Transition;
+import android.transition.TransitionValues;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.MotionEvent;
@@ -73,7 +75,7 @@
 
         new PopupWindow(mActivity, null);
 
-        new PopupWindow(mActivity, null, com.android.internal.R.attr.popupWindowStyle);
+        new PopupWindow(mActivity, null, android.R.attr.popupWindowStyle);
 
         mPopupWindow = new PopupWindow();
         assertEquals(0, mPopupWindow.getWidth());
@@ -141,12 +143,8 @@
         // default is -1
         assertEquals(-1, mPopupWindow.getAnimationStyle());
 
-        mPopupWindow.setAnimationStyle(com.android.internal.R.style.Animation_Toast);
-        assertEquals(com.android.internal.R.style.Animation_Toast,
-                mPopupWindow.getAnimationStyle());
-
-        mPopupWindow.setAnimationStyle(com.android.internal.R.style.Animation_DropDownDown);
-        assertEquals(com.android.internal.R.style.Animation_DropDownDown,
+        mPopupWindow.setAnimationStyle(android.R.style.Animation_Toast);
+        assertEquals(android.R.style.Animation_Toast,
                 mPopupWindow.getAnimationStyle());
 
         // abnormal values
@@ -189,8 +187,7 @@
 
     public void testAccessHeight() {
         mPopupWindow = new PopupWindow(mActivity);
-        // default is 0
-        assertEquals(0, mPopupWindow.getHeight());
+        assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, mPopupWindow.getHeight());
 
         int height = getDisplay().getHeight() / 2;
         mPopupWindow.setHeight(height);
@@ -224,7 +221,7 @@
 
     public void testAccessWidth() {
         mPopupWindow = new PopupWindow(mActivity);
-        assertEquals(0, mPopupWindow.getWidth());
+        assertEquals(WindowManager.LayoutParams.WRAP_CONTENT, mPopupWindow.getWidth());
 
         int width = getDisplay().getWidth() / 2;
         mPopupWindow.setWidth(width);
@@ -335,6 +332,41 @@
         dismissPopup();
     }
 
+    public void testOverlapAnchor() {
+        int[] anchorXY = new int[2];
+        int[] viewOnScreenXY = new int[2];
+        int[] viewInWindowXY = new int[2];
+
+        mPopupWindow = createPopupWindow(createPopupContent());
+        final View upperAnchor = mActivity.findViewById(R.id.anchor_upper);
+        upperAnchor.getLocationOnScreen(anchorXY);
+
+        assertFalse(mPopupWindow.getOverlapAnchor());
+        mPopupWindow.setOverlapAnchor(true);
+        assertTrue(mPopupWindow.getOverlapAnchor());
+
+        mInstrumentation.runOnMainSync(new Runnable() {
+            public void run() {
+                mPopupWindow.showAsDropDown(upperAnchor, 0, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        mPopupWindow.getContentView().getLocationOnScreen(viewOnScreenXY);
+        mPopupWindow.getContentView().getLocationInWindow(viewInWindowXY);
+        assertEquals(anchorXY[0] + viewInWindowXY[0], viewOnScreenXY[0]);
+        assertEquals(anchorXY[1] + viewInWindowXY[1], viewOnScreenXY[1]);
+    }
+
+    public void testAccessWindowLayoutType() {
+        mPopupWindow = createPopupWindow(createPopupContent());
+        assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
+                mPopupWindow.getWindowLayoutType());
+        mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
+        assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL,
+                mPopupWindow.getWindowLayoutType());
+    }
+
     public void testGetMaxAvailableHeight() {
         mPopupWindow = createPopupWindow(createPopupContent());
 
@@ -422,7 +454,7 @@
         mPopupWindow.setOutsideTouchable(true);
 
         WindowManager.LayoutParams p = (WindowManager.LayoutParams)
-                mPopupWindow.getContentView().getLayoutParams();
+                mPopupWindow.getContentView().getRootView().getLayoutParams();
 
         assertEquals(0, WindowManager.LayoutParams.FLAG_IGNORE_CHEEK_PRESSES & p.flags);
         assertEquals(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
@@ -452,6 +484,36 @@
                 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM & p.flags);
     }
 
+    public void testEnterExitTransition() {
+        mPopupWindow = createPopupWindow(createPopupContent());
+        final View anchorView = mActivity.findViewById(R.id.anchor_upper);
+
+        final MockTransition enterTransition = new MockTransition();
+        final MockTransition exitTransition = new MockTransition();
+        mPopupWindow.setEnterTransition(enterTransition);
+        mPopupWindow.setExitTransition(exitTransition);
+
+        mInstrumentation.runOnMainSync(new Runnable() {
+            public void run() {
+                mPopupWindow.showAsDropDown(anchorView, 0, 0);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertEquals(1, enterTransition.getTransitionCount());
+        assertEquals(0, exitTransition.getTransitionCount());
+
+        mInstrumentation.runOnMainSync(new Runnable() {
+            public void run() {
+                mPopupWindow.dismiss();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertEquals(1, enterTransition.getTransitionCount());
+        assertEquals(1, exitTransition.getTransitionCount());
+    }
+
     public void testUpdatePositionAndDimension() {
         int[] fstXY = new int[2];
         int[] sndXY = new int[2];
@@ -752,7 +814,7 @@
         mPopupWindow = new PopupWindow(new TextView(mActivity));
         showPopup();
 
-        ViewGroup.LayoutParams p = mPopupWindow.getContentView().getLayoutParams();
+        ViewGroup.LayoutParams p = mPopupWindow.getContentView().getRootView().getLayoutParams();
         assertEquals(0, p.width);
         assertEquals(0, p.height);
 
@@ -828,6 +890,48 @@
         }
     }
 
+    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));
diff --git a/tests/tests/widget/src/android/widget/cts/QuickContactBadgeTest.java b/tests/tests/widget/src/android/widget/cts/QuickContactBadgeTest.java
new file mode 100644
index 0000000..a65bbe9
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/QuickContactBadgeTest.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 android.widget.cts;
+
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.ContextWrapper;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.UserHandle;
+import android.provider.ContactsContract;
+import android.provider.ContactsContract.Contacts;
+import android.test.InstrumentationTestCase;
+import android.test.UiThreadTest;
+import android.widget.QuickContactBadge;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class QuickContactBadgeTest extends InstrumentationTestCase {
+
+    @UiThreadTest
+    public void testPrioritizedMimetype() throws InterruptedException {
+        final String plainMimeType = "text/plain";
+        final Uri nonExistentContactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, 0);
+        final CountDownLatch latch = new CountDownLatch(1);
+        final Context context = new ContextWrapper(getInstrumentation().getContext()) {
+            @Override
+            public void startActivity(Intent intent) {
+                testCallback(intent);
+            }
+
+            // @Override
+            public void startActivityAsUser(Intent intent, UserHandle user) {
+                testCallback(intent);
+            }
+
+            // @Override
+            public void startActivityAsUser(Intent intent, Bundle options, UserHandle user) {
+                testCallback(intent);
+            }
+
+            private void testCallback(Intent intent) {
+                assertEquals(plainMimeType, intent.getStringExtra(
+                        ContactsContract.QuickContact.EXTRA_PRIORITIZED_MIMETYPE));
+                latch.countDown();
+            }
+        };
+
+        // Execute: create QuickContactBadge with a prioritized mimetype and click on it
+        QuickContactBadge badge = new QuickContactBadge(context);
+        badge.setPrioritizedMimeType(plainMimeType);
+        badge.assignContactUri(nonExistentContactUri);
+        badge.onClick(badge);
+
+        // Verify: the QuickContactBadge attempts to start an activity, and sets the
+        // prioritized mimetype. We don't know which method will be used to start the activity,
+        // so we check all options.
+        assertTrue(latch.await(1, TimeUnit.SECONDS));
+    }
+}
+
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 4b1aa5b..b14c0e8 100644
--- a/tests/tests/widget/src/android/widget/cts/RadioGroup_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RadioGroup_LayoutParamsTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.internal.R;
+import android.R;
 
 
 import org.xmlpull.v1.XmlPullParser;
diff --git a/tests/tests/widget/src/android/widget/cts/RatingBarTest.java b/tests/tests/widget/src/android/widget/cts/RatingBarTest.java
index 1bb42e8..211d7fe 100644
--- a/tests/tests/widget/src/android/widget/cts/RatingBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RatingBarTest.java
@@ -18,7 +18,6 @@
 
 import com.android.cts.widget.R;
 
-
 import android.content.Context;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
@@ -45,7 +44,7 @@
     }
 
     public void testConstructor() {
-        new RatingBar(mContext, null, com.android.internal.R.attr.ratingBarStyle);
+        new RatingBar(mContext, null, android.R.attr.ratingBarStyle);
 
         new RatingBar(mContext, null);
 
diff --git a/tests/tests/widget/src/android/widget/cts/RelativeLayoutTest.java b/tests/tests/widget/src/android/widget/cts/RelativeLayoutTest.java
index b5ce5c9..b228ca6 100644
--- a/tests/tests/widget/src/android/widget/cts/RelativeLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RelativeLayoutTest.java
@@ -17,8 +17,6 @@
 package android.widget.cts;
 
 import com.android.cts.widget.R;
-import com.android.internal.util.XmlUtils;
-
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -36,6 +34,7 @@
 import android.view.ViewGroup.LayoutParams;
 import android.widget.AbsListView;
 import android.widget.RelativeLayout;
+import android.widget.cts.util.XmlUtils;
 
 import java.io.IOException;
 
@@ -318,6 +317,42 @@
         assertFalse(myRelativeLayout.checkLayoutParams(p3));
     }
 
+    public void testGetRule() {
+        RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(0, 0);
+        p.addRule(RelativeLayout.LEFT_OF, R.id.abslistview_root);
+        p.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
+
+        assertEquals("Get resource ID rule", R.id.abslistview_root,
+                p.getRule(RelativeLayout.LEFT_OF));
+        assertEquals("Get boolean rule", RelativeLayout.TRUE,
+                p.getRule(RelativeLayout.CENTER_IN_PARENT));
+        assertEquals("Get missing rule", 0, p.getRule(RelativeLayout.ABOVE));
+    }
+
+    /**
+     * Tests to prevent regressions in baseline alignment.
+     */
+    public void testBaselineAlignment() {
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mActivity.setContentView(R.layout.relative_layout_baseline);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
+
+        View button = mActivity.findViewById(R.id.button1);
+        assertTrue(button.getHeight() > 0);
+
+        button = mActivity.findViewById(R.id.button2);
+        assertTrue(button.getHeight() > 0);
+
+        button = mActivity.findViewById(R.id.button3);
+        assertTrue(button.getHeight() > 0);
+
+        button = mActivity.findViewById(R.id.button4);
+        assertTrue(button.getHeight() > 0);
+    }
+
     private class MyRelativeLayout extends RelativeLayout {
         public MyRelativeLayout(Context context) {
             super(context);
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 a3bd95c..07c7b77 100644
--- a/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RelativeLayout_LayoutParamsTest.java
@@ -18,7 +18,6 @@
 
 import com.android.cts.widget.R;
 
-
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.ViewAsserts;
 import android.view.View;
@@ -186,11 +185,13 @@
         assertEquals(0, rules[RelativeLayout.ALIGN_START]);
         assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_LEFT]);
         assertEquals(0, rules[RelativeLayout.ALIGN_RIGHT]);
-        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+        rules = layoutParams.getRules();
         assertEquals(R.id.relative_view21, rules[RelativeLayout.BELOW]);
         assertEquals(0, rules[RelativeLayout.ALIGN_START]);
         assertEquals(0, rules[RelativeLayout.ALIGN_LEFT]);
         assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_RIGHT]);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_LTR);
 
         // view3, has same top position with view1 and same bottom position with view2,
         // and on the right of view1.1.
@@ -206,12 +207,14 @@
         assertEquals(0, rules[RelativeLayout.END_OF]);
         assertEquals(0, rules[RelativeLayout.LEFT_OF]);
         assertEquals(R.id.relative_view21, rules[RelativeLayout.RIGHT_OF]);
-        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+        rules = layoutParams.getRules();
         assertEquals(R.id.relative_view21, rules[RelativeLayout.ALIGN_TOP]);
         assertEquals(R.id.relative_view22, rules[RelativeLayout.ALIGN_BOTTOM]);
         assertEquals(0, rules[RelativeLayout.END_OF]);
         assertEquals(R.id.relative_view21, rules[RelativeLayout.LEFT_OF]);
         assertEquals(0, rules[RelativeLayout.RIGHT_OF]);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_LTR);
 
         // view4, has same right position with view3 and above view3.
         // TEST: android:layout_alignEnd; android:layout_above
@@ -224,11 +227,13 @@
         assertEquals(0, rules[RelativeLayout.ALIGN_LEFT]);
         assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_RIGHT]);
         assertEquals(R.id.relative_view23, rules[RelativeLayout.ABOVE]);
-        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+        rules = layoutParams.getRules();
         assertEquals(0, rules[RelativeLayout.ALIGN_END]);
         assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_LEFT]);
         assertEquals(0, rules[RelativeLayout.ALIGN_RIGHT]);
         assertEquals(R.id.relative_view23, rules[RelativeLayout.ABOVE]);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_LTR);
 
         // view5 goes on the left-bottom.
         // TEST: android:layout_alignParentBottom; android:layout_alignParentStart
@@ -241,11 +246,13 @@
         assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_START]);
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
         assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
-        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+        rules = layoutParams.getRules();
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_BOTTOM]);
         assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_START]);
         assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_LTR);
 
         // view6 goes on the top-right.
         // TEST: android:layout_alignParentTop; android:layout_alignParentEnd
@@ -258,11 +265,13 @@
         assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_END]);
         assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
-        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+        rules = layoutParams.getRules();
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_TOP]);
         assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_END]);
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.ALIGN_PARENT_LEFT]);
         assertEquals(0, rules[RelativeLayout.ALIGN_PARENT_RIGHT]);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_LTR);
 
         // view7, has same baseline with view6 and centered horizontally within its parent.
         // TEST: android:layout_alignBaseline; android:layout_centerHorizontal
@@ -273,9 +282,11 @@
         rules = layoutParams.getRules();
         assertEquals(R.id.relative_view26, rules[RelativeLayout.ALIGN_BASELINE]);
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_HORIZONTAL]);
-        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+        rules = layoutParams.getRules();
         assertEquals(R.id.relative_view26, rules[RelativeLayout.ALIGN_BASELINE]);
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_HORIZONTAL]);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_LTR);
 
         // view8, centered vertically within its parent and on the left of view1.
         // TEST: android:layout_toStartOf; android:layout_centerVertical
@@ -288,11 +299,13 @@
         assertEquals(R.id.relative_view21, rules[RelativeLayout.LEFT_OF]);
         assertEquals(0, rules[RelativeLayout.RIGHT_OF]);
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_VERTICAL]);
-        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+        rules = layoutParams.getRules();
         assertEquals(0, rules[RelativeLayout.START_OF]);
         assertEquals(0, rules[RelativeLayout.LEFT_OF]);
         assertEquals(R.id.relative_view21, rules[RelativeLayout.RIGHT_OF]);
         assertEquals(RelativeLayout.TRUE, rules[RelativeLayout.CENTER_VERTICAL]);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_LTR);
 
         // view9, has same top and bottom position with view3 and same left position with its parent
         // TEST: android:layout_alignStart; android:layout_alignTop; android:layout_alignBottom;
@@ -308,12 +321,14 @@
         assertEquals(0, rules[RelativeLayout.ALIGN_RIGHT]);
         assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_TOP]);
         assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_BOTTOM]);
-        rules = layoutParams.getRules(View.LAYOUT_DIRECTION_RTL);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_RTL);
+        rules = layoutParams.getRules();
         assertEquals(0, rules[RelativeLayout.ALIGN_START]);
         assertEquals(0, rules[RelativeLayout.ALIGN_LEFT]);
         assertEquals(R.id.gravity_bottom, rules[RelativeLayout.ALIGN_RIGHT]);
         assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_TOP]);
         assertEquals(R.id.relative_view23, rules[RelativeLayout.ALIGN_BOTTOM]);
+        layoutParams.resolveLayoutDirection(View.LAYOUT_DIRECTION_LTR);
     }
 
     public void testAccessRule1() {
diff --git a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
index 328f9f3..58738a1 100644
--- a/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/RemoteViewsTest.java
@@ -16,6 +16,7 @@
 
 package android.widget.cts;
 
+import android.graphics.drawable.Icon;
 import android.test.UiThreadTest;
 import com.android.cts.widget.R;
 
@@ -152,6 +153,33 @@
         }
     }
 
+    public void testSetIcon() {
+        ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
+        assertNull(image.getDrawable());
+
+        Icon iconBlack = Icon.createWithResource(mActivity, R.drawable.icon_black);
+        mRemoteViews.setIcon(R.id.remoteView_image, "setImageIcon", iconBlack);
+        mRemoteViews.reapply(mActivity, mResult);
+        assertNotNull(image.getDrawable());
+        BitmapDrawable dBlack = (BitmapDrawable) mActivity.getDrawable(R.drawable.icon_black);
+        WidgetTestUtils.assertEquals(dBlack.getBitmap(),
+                ((BitmapDrawable) image.getDrawable()).getBitmap());
+    }
+
+    public void testSetImageViewIcon() {
+        ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
+        assertNull(image.getDrawable());
+
+        Icon iconBlue = Icon.createWithResource(mActivity, R.drawable.icon_blue);
+        mRemoteViews.setImageViewIcon(R.id.remoteView_image, iconBlue);
+        mRemoteViews.reapply(mActivity, mResult);
+        assertNotNull(image.getDrawable());
+        BitmapDrawable dBlue = (BitmapDrawable) mActivity.getDrawable(R.drawable.icon_blue);
+        WidgetTestUtils.assertEquals(dBlue.getBitmap(),
+                ((BitmapDrawable) image.getDrawable()).getBitmap());
+
+    }
+
     public void testSetImageViewResource() {
         ImageView image = (ImageView) mResult.findViewById(R.id.remoteView_image);
         assertNull(image.getDrawable());
@@ -159,8 +187,7 @@
         mRemoteViews.setImageViewResource(R.id.remoteView_image, R.drawable.testimage);
         mRemoteViews.reapply(mActivity, mResult);
         assertNotNull(image.getDrawable());
-        BitmapDrawable d = (BitmapDrawable) mActivity
-                .getResources().getDrawable(R.drawable.testimage);
+        BitmapDrawable d = (BitmapDrawable) mActivity.getDrawable(R.drawable.testimage);
         WidgetTestUtils.assertEquals(d.getBitmap(),
                 ((BitmapDrawable) image.getDrawable()).getBitmap());
 
diff --git a/tests/tests/widget/src/android/widget/cts/ResourceCursorAdapterTest.java b/tests/tests/widget/src/android/widget/cts/ResourceCursorAdapterTest.java
index 28bfd06..580be27 100644
--- a/tests/tests/widget/src/android/widget/cts/ResourceCursorAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/ResourceCursorAdapterTest.java
@@ -170,13 +170,20 @@
     }
 
     private static class MockResourceCursorAdapter extends ResourceCursorAdapter {
+        private final boolean mAutoRequery;
+
         public MockResourceCursorAdapter(Context context, int layout, Cursor c) {
             super(context, layout, c);
+
+            // Default is true.
+            mAutoRequery = true;
         }
 
         public MockResourceCursorAdapter(Context context, int layout,
                 Cursor c, boolean autoRequery) {
             super(context, layout, c, autoRequery);
+
+            mAutoRequery = autoRequery;
         }
 
         @Override
diff --git a/tests/tests/widget/src/android/widget/cts/SeekBarTest.java b/tests/tests/widget/src/android/widget/cts/SeekBarTest.java
index 54bbedf..43aada2 100644
--- a/tests/tests/widget/src/android/widget/cts/SeekBarTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SeekBarTest.java
@@ -54,7 +54,7 @@
 
         new SeekBar(mActivity, null);
 
-        new SeekBar(mActivity, null, com.android.internal.R.attr.seekBarStyle);
+        new SeekBar(mActivity, null, android.R.attr.seekBarStyle);
     }
 
     public void testSetOnSeekBarChangeListener() {
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
index c530293..28ff15e 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleAdapterTest.java
@@ -16,10 +16,11 @@
 
 package android.widget.cts;
 
-import com.android.internal.R;
+import android.R;
 
 
 import android.content.Context;
+import android.content.res.Resources.Theme;
 import android.cts.util.WidgetTestUtils;
 import android.graphics.Bitmap;
 import android.graphics.drawable.BitmapDrawable;
@@ -260,6 +261,12 @@
         }
     }
 
+    public void testAccessDropDownViewTheme() {
+        Theme theme = mContext.getResources().newTheme();
+        mSimpleAdapter.setDropDownViewTheme(theme);
+        assertSame(theme, mSimpleAdapter.getDropDownViewTheme());
+    }
+
     public void testAccessViewBinder() {
         // no binder default
         assertNull(mSimpleAdapter.getViewBinder());
diff --git a/tests/tests/widget/src/android/widget/cts/SimpleExpandableListAdapterTest.java b/tests/tests/widget/src/android/widget/cts/SimpleExpandableListAdapterTest.java
index a7bfc31..d1c63c0 100644
--- a/tests/tests/widget/src/android/widget/cts/SimpleExpandableListAdapterTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SimpleExpandableListAdapterTest.java
@@ -16,7 +16,7 @@
 
 package android.widget.cts;
 
-import com.android.internal.R;
+import android.R;
 
 
 import android.content.Context;
diff --git a/tests/tests/widget/src/android/widget/cts/SpinnerTest.java b/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
index 1989626..ea37470 100644
--- a/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/SpinnerTest.java
@@ -23,8 +23,10 @@
 import android.app.Dialog;
 import android.content.Context;
 import android.content.res.Resources.NotFoundException;
+import android.content.res.Resources.Theme;
 import android.test.ActivityInstrumentationTestCase2;
 import android.test.UiThreadTest;
+import android.view.ContextThemeWrapper;
 import android.widget.ArrayAdapter;
 import android.widget.Spinner;
 
@@ -50,7 +52,18 @@
 
         new Spinner(mTargetContext, null);
 
-        new Spinner(mTargetContext, null, com.android.internal.R.attr.spinnerStyle);
+        new Spinner(mTargetContext, null, android.R.attr.spinnerStyle);
+
+        new Spinner(mTargetContext, Spinner.MODE_DIALOG);
+
+        new Spinner(mTargetContext, null, android.R.attr.spinnerStyle,
+                Spinner.MODE_DIALOG);
+
+        new Spinner(mTargetContext, null, android.R.attr.spinnerStyle, 0,
+                Spinner.MODE_DIALOG);
+
+        new Spinner(mTargetContext, null, android.R.attr.spinnerStyle, 0,
+                Spinner.MODE_DIALOG, mTargetContext.getTheme());
 
         Spinner spinner = (Spinner) getActivity().findViewById(R.id.spinner1);
         assertEquals(mTargetContext.getString(R.string.text_view_hello), spinner.getPrompt());
@@ -156,6 +169,18 @@
         // TODO: find the dialog and get its title to assert whether setPromptId() takes effect?
     }
 
+    @UiThreadTest
+    public void testGetPopupContext() {
+        Theme theme = mTargetContext.getResources().newTheme();
+        Spinner themeSpinner = new Spinner(mTargetContext, null,
+                android.R.attr.spinnerStyle, 0, Spinner.MODE_DIALOG, theme);
+        assertNotSame(mTargetContext, themeSpinner.getPopupContext());
+        assertSame(theme, themeSpinner.getPopupContext().getTheme());
+
+        ContextThemeWrapper context = (ContextThemeWrapper)themeSpinner.getPopupContext();
+        assertSame(mTargetContext, context.getBaseContext());
+    }
+
     public void testOnLayout() {
         // onLayout() is implementation details, do NOT test
     }
diff --git a/tests/tests/widget/src/android/widget/cts/SwitchTest.java b/tests/tests/widget/src/android/widget/cts/SwitchTest.java
new file mode 100644
index 0000000..164e7bf
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/SwitchTest.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 android.widget.cts;
+
+import com.android.cts.widget.R;
+
+import android.content.Context;
+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.widget.Switch;
+
+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);
+
+        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 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());
+    }
+
+    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());
+
+        ColorStateList colors = ColorStateList.valueOf(Color.RED);
+        aSwitch.setTrackTintList(colors);
+        aSwitch.setTrackTintMode(Mode.XOR);
+
+        assertSame(colors, aSwitch.getTrackTintList());
+        assertEquals(Mode.XOR, aSwitch.getTrackTintMode());
+    }
+}
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 1363491..5745808 100644
--- a/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TabHost_TabSpecTest.java
@@ -65,7 +65,7 @@
         mTabHost.addTab(tabSpec);
         mTabHost.setCurrentTab(1);
         View currentTabView = mTabHost.getCurrentTabView();
-        int idTitle = com.android.internal.R.id.title;
+        int idTitle = android.R.id.title;
         TextView tvTitle = (TextView) currentTabView.findViewById(idTitle);
         assertEquals(TAG_TAB2, tvTitle.getText().toString());
 
@@ -90,8 +90,8 @@
         mTabHost.addTab(tabSpec);
         mTabHost.setCurrentTab(1);
         View currentTabView = mTabHost.getCurrentTabView();
-        int idTitle = com.android.internal.R.id.title;
-        int idIcon = com.android.internal.R.id.icon;
+        int idTitle = android.R.id.title;
+        int idIcon = android.R.id.icon;
         TextView tvTitle = (TextView) currentTabView.findViewById(idTitle);
         ImageView ivIcon = ((ImageView) currentTabView.findViewById(idIcon));
         assertEquals("", tvTitle.getText().toString());
diff --git a/tests/tests/widget/src/android/widget/cts/TableLayoutTest.java b/tests/tests/widget/src/android/widget/cts/TableLayoutTest.java
index 5259736..b9f0d1f 100644
--- a/tests/tests/widget/src/android/widget/cts/TableLayoutTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TableLayoutTest.java
@@ -18,7 +18,6 @@
 
 import com.android.cts.widget.R;
 
-
 import android.content.Context;
 import android.content.res.XmlResourceParser;
 import android.test.ActivityInstrumentationTestCase2;
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 20a9937..cbc41ce 100644
--- a/tests/tests/widget/src/android/widget/cts/TableLayout_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TableLayout_LayoutParamsTest.java
@@ -16,6 +16,10 @@
 
 package android.widget.cts;
 
+import com.android.cts.widget.R;
+
+import org.xmlpull.v1.XmlPullParser;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
@@ -23,12 +27,7 @@
 import android.util.AttributeSet;
 import android.util.Xml;
 import android.widget.TableLayout;
-
-import com.android.internal.R;
-import com.android.internal.util.XmlUtils;
-
-
-import org.xmlpull.v1.XmlPullParser;
+import android.widget.cts.util.XmlUtils;
 
 /**
  * Test {@link TableLayout.LayoutParams}.
@@ -74,56 +73,59 @@
 
         // base_attr_pixel: layout_width = 400px, layout_height = 600px
         AttributeSet attrs = getAttrs("base_attr_pixel");
-        TypedArray a = mTargetContext.obtainStyledAttributes(attrs, R.styleable.ViewGroup_Layout);
+        TypedArray a = mTargetContext.obtainStyledAttributes(attrs,
+                android.R.styleable.ViewGroup_Layout);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_width,
-                R.styleable.ViewGroup_Layout_layout_height);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_width,
+                android.R.styleable.ViewGroup_Layout_layout_height);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.width);
         assertEquals(600, mockLayoutParams.height);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_height,
-                R.styleable.ViewGroup_Layout_layout_width);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_height,
+                android.R.styleable.ViewGroup_Layout_layout_width);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.width);
         assertEquals(400, mockLayoutParams.height);
 
         a.recycle();
         // base_attr_fillwrap: layout_width = "match_parent", layout_height = "wrap_content"
         attrs = getAttrs("base_attr_fillwrap");
-        a = mTargetContext.obtainStyledAttributes(attrs, R.styleable.ViewGroup_Layout);
+        a = mTargetContext.obtainStyledAttributes(attrs, android.R.styleable.ViewGroup_Layout);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_width,
-                R.styleable.ViewGroup_Layout_layout_height);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_width,
+                android.R.styleable.ViewGroup_Layout_layout_height);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.width);
         assertEquals(TableLayout.LayoutParams.WRAP_CONTENT, mockLayoutParams.height);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_height,
-                R.styleable.ViewGroup_Layout_layout_width);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_height,
+                android.R.styleable.ViewGroup_Layout_layout_width);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.width);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.height);
 
         a.recycle();
         // base_attr_noheight: layout_width = 600px, no layout_height.
         attrs = getAttrs("base_attr_noheight");
-        a = mTargetContext.obtainStyledAttributes(attrs, R.styleable.ViewGroup_Layout);
+        a = mTargetContext.obtainStyledAttributes(attrs, android.R.styleable.ViewGroup_Layout);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_width,
-                R.styleable.ViewGroup_Layout_layout_height);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_width,
+                android.R.styleable.ViewGroup_Layout_layout_height);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.width);
         assertEquals(TableLayout.LayoutParams.WRAP_CONTENT, mockLayoutParams.height);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_height,
-                R.styleable.ViewGroup_Layout_layout_width);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_height,
+                android.R.styleable.ViewGroup_Layout_layout_width);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.width);
         assertEquals(600, mockLayoutParams.height);
 
         try {
-            mockLayoutParams.setBaseAttributes(null, R.styleable.ViewGroup_Layout_layout_width,
-                    R.styleable.ViewGroup_Layout_layout_height);
+            mockLayoutParams.setBaseAttributes(null,
+                    android.R.styleable.ViewGroup_Layout_layout_width,
+                    android.R.styleable.ViewGroup_Layout_layout_height);
             fail("Should throw NullPointerException");
         } catch (NullPointerException e) {
         }
 
-        mockLayoutParams.setBaseAttributes(a, -1, R.styleable.ViewGroup_Layout_layout_height);
+        mockLayoutParams.setBaseAttributes(a, -1,
+                android.R.styleable.ViewGroup_Layout_layout_height);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.width);
         assertEquals(TableLayout.LayoutParams.WRAP_CONTENT, mockLayoutParams.height);
 
@@ -138,8 +140,7 @@
         XmlResourceParser parser = null;
         AttributeSet attrs = null;
         try {
-            parser = mTargetContext.getResources()
-                    .getXml(com.android.cts.widget.R.xml.base_attributes);
+            parser = mTargetContext.getResources().getXml(R.xml.base_attributes);
 
             int type;
             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
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 cf2603f..8308414 100644
--- a/tests/tests/widget/src/android/widget/cts/TableRow_LayoutParamsTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TableRow_LayoutParamsTest.java
@@ -16,6 +16,10 @@
 
 package android.widget.cts;
 
+import com.android.cts.widget.R;
+
+import org.xmlpull.v1.XmlPullParser;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
@@ -28,12 +32,7 @@
 import android.view.ViewGroup.MarginLayoutParams;
 import android.widget.TableLayout;
 import android.widget.TableRow;
-
-import com.android.internal.R;
-import com.android.internal.util.XmlUtils;
-
-
-import org.xmlpull.v1.XmlPullParser;
+import android.widget.cts.util.XmlUtils;
 
 /**
  * Test {@link TableRow.LayoutParams}.
@@ -92,8 +91,8 @@
         assertEquals(0, layoutParams.span);
 
         TableCtsActivity activity = getActivity();
-        activity.setContentView(com.android.cts.widget.R.layout.table_layout_2);
-        int idTable = com.android.cts.widget.R.id.table2;
+        activity.setContentView(R.layout.table_layout_2);
+        int idTable = R.id.table2;
         TableLayout tableLayout = (TableLayout) activity.findViewById(idTable);
         View vVitural1 = ((TableRow) tableLayout.getChildAt(0)).getVirtualChildAt(1);
         layoutParams = (TableRow.LayoutParams) vVitural1.getLayoutParams();
@@ -117,65 +116,67 @@
 
         // base_attr_pixel: layout_width = 400px, layout_height = 600px
         AttributeSet attrs = getAttrs("base_attr_pixel");
-        TypedArray a = mTargetContext.obtainStyledAttributes(attrs, R.styleable.ViewGroup_Layout);
+        TypedArray a = mTargetContext.obtainStyledAttributes(attrs,
+                android.R.styleable.ViewGroup_Layout);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_width,
-                R.styleable.ViewGroup_Layout_layout_height);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_width,
+                android.R.styleable.ViewGroup_Layout_layout_height);
         assertEquals(400, mockLayoutParams.width);
         assertEquals(600, mockLayoutParams.height);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_height,
-                R.styleable.ViewGroup_Layout_layout_width);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_height,
+                android.R.styleable.ViewGroup_Layout_layout_width);
         assertEquals(600, mockLayoutParams.width);
         assertEquals(400, mockLayoutParams.height);
 
         a.recycle();
         // base_attr_fillwrap: layout_width = "match_parent", layout_height = "wrap_content"
         attrs = getAttrs("base_attr_fillwrap");
-        a = mTargetContext.obtainStyledAttributes(attrs, R.styleable.ViewGroup_Layout);
+        a = mTargetContext.obtainStyledAttributes(attrs, android.R.styleable.ViewGroup_Layout);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_width,
-                R.styleable.ViewGroup_Layout_layout_height);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_width,
+                android.R.styleable.ViewGroup_Layout_layout_height);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.width);
         assertEquals(TableLayout.LayoutParams.WRAP_CONTENT, mockLayoutParams.height);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_height,
-                R.styleable.ViewGroup_Layout_layout_width);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_height,
+                android.R.styleable.ViewGroup_Layout_layout_width);
         assertEquals(TableLayout.LayoutParams.WRAP_CONTENT, mockLayoutParams.width);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.height);
 
         a.recycle();
         // base_attr_noheight: layout_width = 600px, no layout_height.
         attrs = getAttrs("base_attr_noheight");
-        a = mTargetContext.obtainStyledAttributes(attrs, R.styleable.ViewGroup_Layout);
+        a = mTargetContext.obtainStyledAttributes(attrs, android.R.styleable.ViewGroup_Layout);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_width,
-                R.styleable.ViewGroup_Layout_layout_height);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_width,
+                android.R.styleable.ViewGroup_Layout_layout_height);
         assertEquals(600, mockLayoutParams.width);
         assertEquals(TableLayout.LayoutParams.WRAP_CONTENT, mockLayoutParams.height);
 
-        mockLayoutParams.setBaseAttributes(a, R.styleable.ViewGroup_Layout_layout_height,
-                R.styleable.ViewGroup_Layout_layout_width);
+        mockLayoutParams.setBaseAttributes(a, android.R.styleable.ViewGroup_Layout_layout_height,
+                android.R.styleable.ViewGroup_Layout_layout_width);
         assertEquals(TableLayout.LayoutParams.MATCH_PARENT, mockLayoutParams.width);
         assertEquals(600, mockLayoutParams.height);
 
         try {
-            mockLayoutParams.setBaseAttributes(null, R.styleable.ViewGroup_Layout_layout_width,
-                    R.styleable.ViewGroup_Layout_layout_height);
+            mockLayoutParams.setBaseAttributes(null,
+                    android.R.styleable.ViewGroup_Layout_layout_width,
+                    android.R.styleable.ViewGroup_Layout_layout_height);
             fail("Should throw NullPointerException");
         } catch (NullPointerException e) {
         }
 
         try {
             mockLayoutParams.setBaseAttributes(a, -1,
-                    R.styleable.ViewGroup_Layout_layout_height);
+                    android.R.styleable.ViewGroup_Layout_layout_height);
             fail("Should throw ArrayIndexOutOfBoundsException");
         } catch (ArrayIndexOutOfBoundsException e) {
         }
 
         try {
             mockLayoutParams.setBaseAttributes(null,
-                    R.styleable.ViewGroup_Layout_layout_width, -1);
+                    android.R.styleable.ViewGroup_Layout_layout_width, -1);
             fail("Should throw ArrayIndexOutOfBoundsException");
         } catch (NullPointerException e) {
         }
@@ -185,8 +186,7 @@
         XmlResourceParser parser = null;
         AttributeSet attrs = null;
         try {
-            parser = mTargetContext.getResources()
-                    .getXml(com.android.cts.widget.R.xml.base_attributes);
+            parser = mTargetContext.getResources().getXml(R.xml.base_attributes);
 
             int type;
             while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 480e1a6..829171c 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -17,7 +17,6 @@
 package android.widget.cts;
 
 import com.android.cts.widget.R;
-import com.android.internal.util.FastMath;
 
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -25,6 +24,7 @@
 import android.app.Instrumentation;
 import android.app.Instrumentation.ActivityMonitor;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.ColorStateList;
 import android.content.res.Resources.NotFoundException;
 import android.cts.util.PollingCheck;
@@ -33,6 +33,7 @@
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Path;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.Typeface;
@@ -40,7 +41,9 @@
 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.text.Editable;
@@ -75,16 +78,21 @@
 import android.util.TypedValue;
 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;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.View.OnCreateContextMenuListener;
 import android.view.View.OnLongClickListener;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.inputmethod.BaseInputConnection;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.ExtractedText;
 import android.view.inputmethod.ExtractedTextRequest;
+import android.view.inputmethod.InputConnection;
 import android.widget.EditText;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
@@ -94,6 +102,7 @@
 import android.widget.TextView.OnEditorActionListener;
 
 import java.io.IOException;
+import java.util.Locale;
 
 /**
  * Test {@link TextView}.
@@ -128,6 +137,21 @@
         mInstrumentation = getInstrumentation();
     }
 
+    /**
+     * Promotes the TextView to editable and places focus in it to allow simulated typing.
+     */
+    private void initTextViewForTyping() {
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView = findTextView(R.id.textview_text);
+                mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
+                mTextView.setText("", BufferType.EDITABLE);
+                mTextView.requestFocus();
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
     public void testConstructor() {
         new TextView(mActivity);
 
@@ -762,37 +786,38 @@
         float add = 1.2f;
         float mult = 1.4f;
         setLineSpacing(add, mult);
-        assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
+        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
         add = 0.0f;
         mult = 1.4f;
         setLineSpacing(add, mult);
-        assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
+        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
 
         // abnormal
         add = -1.2f;
         mult = 1.4f;
         setLineSpacing(add, mult);
-        assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
+        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
         add = -1.2f;
         mult = -1.4f;
         setLineSpacing(add, mult);
-        assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
+        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
         add = 1.2f;
         mult = 0.0f;
         setLineSpacing(add, mult);
-        assertEquals(FastMath.round(originalLineHeight * mult + add), mTextView.getLineHeight());
+        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
 
         // edge
         add = Float.MIN_VALUE;
         mult = Float.MIN_VALUE;
         setLineSpacing(add, mult);
-        float expected = originalLineHeight * mult + add;
-        assertEquals(FastMath.round(expected), mTextView.getLineHeight());
+        assertEquals(Math.round(originalLineHeight * mult + add), mTextView.getLineHeight());
+
+        // edge case where the behavior of Math.round() deviates from
+        // FastMath.round(), requiring us to use an explicit 0 value
         add = Float.MAX_VALUE;
         mult = Float.MAX_VALUE;
         setLineSpacing(add, mult);
-        expected = originalLineHeight * mult + add;
-        assertEquals(FastMath.round(expected), mTextView.getLineHeight());
+        assertEquals(0, mTextView.getLineHeight());
     }
 
     public void testInstanceState() {
@@ -1241,6 +1266,537 @@
         }
     }
 
+    public void testUndo_insert() {
+        initTextViewForTyping();
+
+        // Type some text.
+        mInstrumentation.sendStringSync("abc");
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Precondition: The cursor is at the end of the text.
+                assertEquals(3, mTextView.getSelectionStart());
+
+                // Undo removes the typed string in one step.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+                assertEquals(0, mTextView.getSelectionStart());
+
+                // Redo restores the text and cursor position.
+                mTextView.onTextContextMenuItem(android.R.id.redo);
+                assertEquals("abc", mTextView.getText().toString());
+                assertEquals(3, mTextView.getSelectionStart());
+
+                // Undoing the redo clears the text again.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+
+                // Undo when the undo stack is empty does nothing.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testUndo_delete() {
+        initTextViewForTyping();
+
+        // Simulate deleting text and undoing it.
+        mInstrumentation.sendStringSync("xyz");
+        sendKeys(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL);
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Precondition: The text was actually deleted.
+                assertEquals("", mTextView.getText().toString());
+                assertEquals(0, mTextView.getSelectionStart());
+
+                // Undo restores the typed string and cursor position in one step.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("xyz", mTextView.getText().toString());
+                assertEquals(3, mTextView.getSelectionStart());
+
+                // Redo removes the text in one step.
+                mTextView.onTextContextMenuItem(android.R.id.redo);
+                assertEquals("", mTextView.getText().toString());
+                assertEquals(0, mTextView.getSelectionStart());
+
+                // Undoing the redo restores the text again.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("xyz", mTextView.getText().toString());
+                assertEquals(3, mTextView.getSelectionStart());
+
+                // Undoing again undoes the original typing.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+                assertEquals(0, mTextView.getSelectionStart());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    // Initialize the text view for simulated IME typing. Must be called on UI thread.
+    private InputConnection initTextViewForSimulatedIme() {
+        mTextView = findTextView(R.id.textview_text);
+        mTextView.setKeyListener(QwertyKeyListener.getInstance(false, Capitalize.NONE));
+        mTextView.setText("", BufferType.EDITABLE);
+        return mTextView.onCreateInputConnection(new EditorInfo());
+    }
+
+    // Simulates IME composing text behavior.
+    private void setComposingTextInBatch(InputConnection input, CharSequence text) {
+        input.beginBatchEdit();
+        input.setComposingText(text, 1);  // Leave cursor at end.
+        input.endBatchEdit();
+    }
+
+    @UiThreadTest
+    public void testUndo_imeInsertLatin() {
+        InputConnection input = initTextViewForSimulatedIme();
+
+        // Simulate IME text entry behavior. The Latin IME enters text by replacing partial words,
+        // such as "c" -> "ca" -> "cat" -> "cat ".
+        setComposingTextInBatch(input, "c");
+        setComposingTextInBatch(input, "ca");
+
+        // The completion and space are added in the same batch.
+        input.beginBatchEdit();
+        input.commitText("cat", 1);
+        input.commitText(" ", 1);
+        input.endBatchEdit();
+
+        // The repeated replacements undo in a single step.
+        mTextView.onTextContextMenuItem(android.R.id.undo);
+        assertEquals("", mTextView.getText().toString());
+    }
+
+    @UiThreadTest
+    public void testUndo_imeInsertJapanese() {
+        InputConnection input = initTextViewForSimulatedIme();
+
+        // The Japanese IME does repeated replacements of Latin characters to hiragana to kanji.
+        final String HA = "\u306F";  // HIRAGANA LETTER HA
+        final String NA = "\u306A";  // HIRAGANA LETTER NA
+        setComposingTextInBatch(input, "h");
+        setComposingTextInBatch(input, HA);
+        setComposingTextInBatch(input, HA + "n");
+        setComposingTextInBatch(input, HA + NA);
+
+        // The result may be a surrogate pair. The composition ends in the same batch.
+        input.beginBatchEdit();
+        input.commitText("\uD83C\uDF37", 1);  // U+1F337 TULIP
+        input.setComposingText("", 1);
+        input.endBatchEdit();
+
+        // The repeated replacements are a single undo step.
+        mTextView.onTextContextMenuItem(android.R.id.undo);
+        assertEquals("", mTextView.getText().toString());
+    }
+
+    @UiThreadTest
+    public void testUndo_imeCancel() {
+        InputConnection input = initTextViewForSimulatedIme();
+        mTextView.setText("flower");
+
+        // Start typing a composition.
+        final String HA = "\u306F";  // HIRAGANA LETTER HA
+        setComposingTextInBatch(input, "h");
+        setComposingTextInBatch(input, HA);
+        setComposingTextInBatch(input, HA + "n");
+
+        // Cancel the composition.
+        setComposingTextInBatch(input, "");
+
+        // Undo and redo do nothing.
+        mTextView.onTextContextMenuItem(android.R.id.undo);
+        assertEquals("flower", mTextView.getText().toString());
+        mTextView.onTextContextMenuItem(android.R.id.redo);
+        assertEquals("flower", mTextView.getText().toString());
+    }
+
+    @UiThreadTest
+    public void testUndo_imeEmptyBatch() {
+        InputConnection input = initTextViewForSimulatedIme();
+        mTextView.setText("flower");
+
+        // Send an empty batch edit. This happens if the IME is hidden and shown.
+        input.beginBatchEdit();
+        input.endBatchEdit();
+
+        // Undo and redo do nothing.
+        mTextView.onTextContextMenuItem(android.R.id.undo);
+        assertEquals("flower", mTextView.getText().toString());
+        mTextView.onTextContextMenuItem(android.R.id.redo);
+        assertEquals("flower", mTextView.getText().toString());
+    }
+
+    public void testUndo_setText() {
+        initTextViewForTyping();
+
+        // Create two undo operations, an insert and a delete.
+        mInstrumentation.sendStringSync("xyz");
+        sendKeys(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL);
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Calling setText() clears both undo operations, so undo doesn't happen.
+                mTextView.setText("Hello", BufferType.EDITABLE);
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("Hello", mTextView.getText().toString());
+
+                // Clearing text programmatically does not undo either.
+                mTextView.setText("", BufferType.EDITABLE);
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testRedo_setText() {
+        initTextViewForTyping();
+
+        // Type some text. This creates an undo entry.
+        mInstrumentation.sendStringSync("abc");
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Undo the typing to create a redo entry.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+
+                // Calling setText() clears the redo stack, so redo doesn't happen.
+                mTextView.setText("Hello", BufferType.EDITABLE);
+                mTextView.onTextContextMenuItem(android.R.id.redo);
+                assertEquals("Hello", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testUndo_directAppend() {
+        initTextViewForTyping();
+
+        // Type some text.
+        mInstrumentation.sendStringSync("abc");
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Programmatically append some text.
+                mTextView.append("def");
+                assertEquals("abcdef", mTextView.getText().toString());
+
+                // Undo removes the append as a separate step.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("abc", mTextView.getText().toString());
+
+                // Another undo removes the original typing.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testUndo_directInsert() {
+        initTextViewForTyping();
+
+        // Type some text.
+        mInstrumentation.sendStringSync("abc");
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Directly modify the underlying Editable to insert some text.
+                // NOTE: This is a violation of the API of getText() which specifies that the
+                // returned object should not be modified. However, some apps do this anyway and
+                // the framework needs to handle it.
+                Editable text = (Editable) mTextView.getText();
+                text.insert(0, "def");
+                assertEquals("defabc", mTextView.getText().toString());
+
+                // Undo removes the insert as a separate step.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("abc", mTextView.getText().toString());
+
+                // Another undo removes the original typing.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testUndo_noCursor() {
+        initTextViewForTyping();
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Append some text to create an undo operation. There is no cursor present.
+                mTextView.append("cat");
+
+                // Place the cursor at the end of the text so the undo will have to change it.
+                Selection.setSelection((Spannable) mTextView.getText(), 3);
+
+                // Undo the append. This should not crash, despite not having a valid cursor
+                // position in the undo operation.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testUndo_textWatcher() {
+        initTextViewForTyping();
+
+        // Add a TextWatcher that converts the text to spaces on each change.
+        mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher());
+
+        // Type some text.
+        mInstrumentation.sendStringSync("abc");
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // TextWatcher altered the text.
+                assertEquals("   ", mTextView.getText().toString());
+
+                // Undo reverses both changes in one step.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testUndo_textWatcherDirectAppend() {
+        initTextViewForTyping();
+
+        // Add a TextWatcher that converts the text to spaces on each change.
+        mTextView.addTextChangedListener(new ConvertToSpacesTextWatcher());
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Programmatically append some text. The TextWatcher changes it to spaces.
+                mTextView.append("abc");
+                assertEquals("   ", mTextView.getText().toString());
+
+                // Undo reverses both changes in one step.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testUndo_shortcuts() {
+        initTextViewForTyping();
+
+        // Type some text.
+        mInstrumentation.sendStringSync("abc");
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Pressing Control-Z triggers undo.
+                KeyEvent control = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z, 0,
+                        KeyEvent.META_CTRL_LEFT_ON);
+                assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, control));
+                assertEquals("", mTextView.getText().toString());
+
+                // Pressing Control-Shift-Z triggers redo.
+                KeyEvent controlShift = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_Z,
+                        0, KeyEvent.META_CTRL_LEFT_ON | KeyEvent.META_SHIFT_LEFT_ON);
+                assertTrue(mTextView.onKeyShortcut(KeyEvent.KEYCODE_Z, controlShift));
+                assertEquals("abc", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testUndo_saveInstanceState() {
+        initTextViewForTyping();
+
+        // Type some text to create an undo operation.
+        mInstrumentation.sendStringSync("abc");
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Parcel and unparcel the TextView.
+                Parcelable state = mTextView.onSaveInstanceState();
+                mTextView.onRestoreInstanceState(state);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // Delete a character to create a new undo operation.
+        sendKeys(KeyEvent.KEYCODE_DEL);
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                assertEquals("ab", mTextView.getText().toString());
+
+                // Undo the delete.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("abc", mTextView.getText().toString());
+
+                // Undo the typing, which verifies that the original undo operation was parceled
+                // correctly.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+
+                // Parcel and unparcel the undo stack (which is empty but has been used and may
+                // contain other state).
+                Parcelable state = mTextView.onSaveInstanceState();
+                mTextView.onRestoreInstanceState(state);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testUndo_saveInstanceStateEmpty() {
+        initTextViewForTyping();
+
+        // Type and delete to create two new undo operations.
+        mInstrumentation.sendStringSync("a");
+        sendKeys(KeyEvent.KEYCODE_DEL);
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Empty the undo stack then parcel and unparcel the TextView. While the undo
+                // stack contains no operations it may contain other state.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                Parcelable state = mTextView.onSaveInstanceState();
+                mTextView.onRestoreInstanceState(state);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // Create two more undo operations.
+        mInstrumentation.sendStringSync("b");
+        sendKeys(KeyEvent.KEYCODE_DEL);
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Verify undo still works.
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("b", mTextView.getText().toString());
+                mTextView.onTextContextMenuItem(android.R.id.undo);
+                assertEquals("", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testCopyAndPaste() {
+        initTextViewForTyping();
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.setText("abcd", BufferType.EDITABLE);
+                mTextView.setSelected(true);
+
+                // Copy "bc".
+                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
+                mTextView.onTextContextMenuItem(android.R.id.copy);
+
+                // Paste "bc" between "b" and "c".
+                Selection.setSelection((Spannable) mTextView.getText(), 2, 2);
+                mTextView.onTextContextMenuItem(android.R.id.paste);
+                assertEquals("abbccd", mTextView.getText().toString());
+
+                // Select entire text and paste "bc".
+                Selection.selectAll((Spannable) mTextView.getText());
+                mTextView.onTextContextMenuItem(android.R.id.paste);
+                assertEquals("bc", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    public void testCutAndPaste() {
+        initTextViewForTyping();
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.setText("abcd", BufferType.EDITABLE);
+                mTextView.setSelected(true);
+
+                // Cut "bc".
+                Selection.setSelection((Spannable) mTextView.getText(), 1, 3);
+                mTextView.onTextContextMenuItem(android.R.id.cut);
+                assertEquals("ad", mTextView.getText().toString());
+
+                // Cut "ad".
+                Selection.setSelection((Spannable) mTextView.getText(), 0, 2);
+                mTextView.onTextContextMenuItem(android.R.id.cut);
+                assertEquals("", mTextView.getText().toString());
+
+                // Paste "ad".
+                mTextView.onTextContextMenuItem(android.R.id.paste);
+                assertEquals("ad", mTextView.getText().toString());
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    private static boolean hasSpansAtMiddleOfText(final TextView textView, final Class<?> type) {
+        final Spannable spannable = (Spannable)textView.getText();
+        final int at = spannable.length() / 2;
+        return spannable.getSpans(at, at, type).length > 0;
+    }
+
+    public void testCutAndPaste_withAndWithoutStyle() {
+        initTextViewForTyping();
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.setText("example", BufferType.EDITABLE);
+                mTextView.setSelected(true);
+
+                // Set URLSpan.
+                final Spannable spannable = (Spannable) mTextView.getText();
+                spannable.setSpan(new URLSpan("http://example.com"), 0, spannable.length(), 0);
+                assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
+
+                // Cut entire text.
+                Selection.selectAll((Spannable) mTextView.getText());
+                mTextView.onTextContextMenuItem(android.R.id.cut);
+                assertEquals("", mTextView.getText().toString());
+
+                // Paste without style.
+                mTextView.onTextContextMenuItem(android.R.id.pasteAsPlainText);
+                assertEquals("example", mTextView.getText().toString());
+                // Check that the text doesn't have URLSpan.
+                assertFalse(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
+
+                // Paste with style.
+                Selection.selectAll((Spannable) mTextView.getText());
+                mTextView.onTextContextMenuItem(android.R.id.paste);
+                assertEquals("example", mTextView.getText().toString());
+                // Check that the text has URLSpan.
+                assertTrue(hasSpansAtMiddleOfText(mTextView, URLSpan.class));
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+    }
+
+    @UiThreadTest
+    public void testSaveInstanceState() {
+        TextView originalTextView = new TextView(mActivity);
+        final String text = "This is a string";
+        originalTextView.setText(text);
+        originalTextView.setFreezesText(true);  // needed to actually save state
+        Parcelable state = originalTextView.onSaveInstanceState();
+
+        TextView restoredTextView = new TextView(mActivity);
+        restoredTextView.onRestoreInstanceState(state);
+        assertEquals(text, restoredTextView.getText().toString());
+    }
+
+    @UiThreadTest
+    public void testSaveInstanceStateSelection() {
+        TextView originalTextView = new TextView(mActivity);
+        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();
+
+        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());
+    }
+
     @UiThreadTest
     public void testSetText() {
         TextView tv = findTextView(R.id.textview_text);
@@ -1583,17 +2139,7 @@
     }
 
     public void testPressKey() {
-        final QwertyKeyListener qwertyKeyListener
-                = QwertyKeyListener.getInstance(false, Capitalize.NONE);
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                mTextView = findTextView(R.id.textview_text);
-                mTextView.setKeyListener(qwertyKeyListener);
-                mTextView.setText("", BufferType.EDITABLE);
-                mTextView.requestFocus();
-            }
-        });
-        mInstrumentation.waitForIdleSync();
+        initTextViewForTyping();
 
         mInstrumentation.sendStringSync("a");
         assertEquals("a", mTextView.getText().toString());
@@ -2107,6 +2653,88 @@
         assertTrue(mTextView.getHeight() <= maxLines * mTextView.getLineHeight());
     }
 
+    public int calculateTextWidth(String text) {
+        mTextView = findTextView(R.id.textview_text);
+
+        // Set the TextView width as the half of the whole text.
+        float[] widths = new float[text.length()];
+        mTextView.getPaint().getTextWidths(text, widths);
+        float textfieldWidth = 0.0f;
+        for (int i = 0; i < text.length(); ++i) {
+            textfieldWidth += widths[i];
+        }
+        return (int)textfieldWidth;
+
+    }
+
+    @UiThreadTest
+    public void testHyphenationNotHappen_frequencyNone() {
+        final int[] BREAK_STRATEGIES = {
+            Layout.BREAK_STRATEGY_SIMPLE, Layout.BREAK_STRATEGY_HIGH_QUALITY,
+            Layout.BREAK_STRATEGY_BALANCED };
+
+        mTextView = findTextView(R.id.textview_text);
+
+        for (int breakStrategy : BREAK_STRATEGIES) {
+            for (int charWidth = 10; charWidth < 120; charWidth += 5) {
+                // Change the text view's width to charWidth width.
+                mTextView.setWidth(calculateTextWidth(LONG_TEXT.substring(0, charWidth)));
+
+                mTextView.setText(LONG_TEXT);
+                mTextView.setBreakStrategy(breakStrategy);
+
+                mTextView.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
+
+                mTextView.requestLayout();
+                mTextView.onPreDraw();  // For freezing the layout.
+                Layout layout = mTextView.getLayout();
+
+                final int lineCount = layout.getLineCount();
+                for (int line = 0; line < lineCount; ++line) {
+                    final int lineEnd = layout.getLineEnd(line);
+                    // In any width, any break strategy, hyphenation should not happen if
+                    // HYPHENATION_FREQUENCY_NONE is specified.
+                    assertTrue(lineEnd == LONG_TEXT.length() ||
+                            Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1)));
+                }
+            }
+        }
+    }
+
+    @UiThreadTest
+    public void testHyphenationNotHappen_breakStrategySimple() {
+        final int[] HYPHENATION_FREQUENCIES = {
+            Layout.HYPHENATION_FREQUENCY_NORMAL, Layout.HYPHENATION_FREQUENCY_FULL,
+            Layout.HYPHENATION_FREQUENCY_NONE };
+
+        mTextView = findTextView(R.id.textview_text);
+
+        for (int hyphenationFrequency: HYPHENATION_FREQUENCIES) {
+            for (int charWidth = 10; charWidth < 120; charWidth += 5) {
+                // Change the text view's width to charWidth width.
+                mTextView.setWidth(calculateTextWidth(LONG_TEXT.substring(0, charWidth)));
+
+                mTextView.setText(LONG_TEXT);
+                mTextView.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
+
+                mTextView.setHyphenationFrequency(hyphenationFrequency);
+
+                mTextView.requestLayout();
+                mTextView.onPreDraw();  // For freezing the layout.
+                Layout layout = mTextView.getLayout();
+
+                final int lineCount = layout.getLineCount();
+                for (int line = 0; line < lineCount; ++line) {
+                    final int lineEnd = layout.getLineEnd(line);
+                    // In any width, any hyphenation frequency, hyphenation should not happen if
+                    // BREAK_STRATEGY_SIMPLE is specified.
+                    assertTrue(lineEnd == LONG_TEXT.length() ||
+                            Character.isWhitespace(LONG_TEXT.charAt(lineEnd - 1)));
+                }
+            }
+        }
+    }
+
     @UiThreadTest
     public void testSetMaxLinesException() {
         mTextView = new TextView(mActivity);
@@ -2324,7 +2952,7 @@
         assertEquals(40, mTextView.getPaddingBottom());
     }
 
-    public void testSetTextAppearance() {
+    public void testDeprecatedSetTextAppearance() {
         mTextView = new TextView(mActivity);
 
         mTextView.setTextAppearance(mActivity, R.style.TextAppearance_All);
@@ -2353,10 +2981,49 @@
         assertEquals(null, mTextView.getTypeface());
     }
 
+    public void testSetTextAppearance() {
+        mTextView = new TextView(mActivity);
+
+        mTextView.setTextAppearance(R.style.TextAppearance_All);
+        assertEquals(mActivity.getResources().getColor(R.drawable.black),
+                mTextView.getCurrentTextColor());
+        assertEquals(20f, mTextView.getTextSize(), 0.01f);
+        assertEquals(Typeface.BOLD, mTextView.getTypeface().getStyle());
+        assertEquals(mActivity.getResources().getColor(R.drawable.red),
+                mTextView.getCurrentHintTextColor());
+        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
+                mTextView.getLinkTextColors().getDefaultColor());
+
+        mTextView.setTextAppearance(R.style.TextAppearance_Colors);
+        assertEquals(mActivity.getResources().getColor(R.drawable.black),
+                mTextView.getCurrentTextColor());
+        assertEquals(mActivity.getResources().getColor(R.drawable.blue),
+                mTextView.getCurrentHintTextColor());
+        assertEquals(mActivity.getResources().getColor(R.drawable.yellow),
+                mTextView.getLinkTextColors().getDefaultColor());
+
+        mTextView.setTextAppearance(R.style.TextAppearance_NotColors);
+        assertEquals(17f, mTextView.getTextSize(), 0.01f);
+        assertEquals(Typeface.NORMAL, mTextView.getTypeface().getStyle());
+
+        mTextView.setTextAppearance(R.style.TextAppearance_Style);
+        assertEquals(null, mTextView.getTypeface());
+    }
+
     public void testOnPreDraw() {
         // Do not test. Implementation details.
     }
 
+    public void testAccessCompoundDrawableTint() {
+        mTextView = new TextView(mActivity);
+
+        ColorStateList colors = ColorStateList.valueOf(Color.RED);
+        mTextView.setCompoundDrawableTintList(colors);
+        mTextView.setCompoundDrawableTintMode(PorterDuff.Mode.XOR);
+        assertSame(colors, mTextView.getCompoundDrawableTintList());
+        assertEquals(PorterDuff.Mode.XOR, mTextView.getCompoundDrawableTintMode());
+    }
+
     public void testSetHorizontallyScrolling() {
         // make the text view has more than one line
         mTextView = findTextView(R.id.textview_text);
@@ -2845,21 +3512,6 @@
         assertEquals(1, mTextView.getImeActionId());
     }
 
-    public void testSetTextLong() {
-        mActivity.runOnUiThread(new Runnable() {
-            public void run() {
-                final int MAX_COUNT = 1 << 21;
-                char[] longText = new char[MAX_COUNT];
-                for (int n = 0; n < MAX_COUNT; n++) {
-                    longText[n] = 'm';
-                }
-                mTextView = findTextView(R.id.textview_text);
-                mTextView.setText(new String(longText));
-            }
-        });
-        mInstrumentation.waitForIdleSync();
-    }
-
     @UiThreadTest
     public void testSetExtractedText() {
         mTextView = findTextView(R.id.textview_text);
@@ -3005,6 +3657,39 @@
         assertTrue(mTextView.didTouchFocusSelect());
     }
 
+    public void testSelectAllJustAfterTap() {
+        // Prepare an EditText with focus.
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView = new EditText(mActivity);
+                mActivity.setContentView(mTextView);
+
+                assertFalse(mTextView.didTouchFocusSelect());
+                mTextView.setFocusable(true);
+                mTextView.requestFocus();
+                assertTrue(mTextView.didTouchFocusSelect());
+
+                mTextView.setText("Hello, World.", BufferType.SPANNABLE);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // Tap the view to show InsertPointController.
+        TouchUtils.tapView(this, mTextView);
+
+        // Execute SelectAll context menu.
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView.onTextContextMenuItem(android.R.id.selectAll);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // The selection must be whole of the text contents.
+        assertEquals(0, mTextView.getSelectionStart());
+        assertEquals(mTextView.length(), mTextView.getSelectionEnd());
+    }
+
     public void testExtractText() {
         mTextView = new TextView(mActivity);
 
@@ -3022,6 +3707,11 @@
 
         assertEquals(mActivity.getResources().getString(R.string.text_view_hello),
                 outText.text.toString());
+
+        // Tests for invalid arguments.
+        assertFalse(mTextView.extractText(request, null));
+        assertFalse(mTextView.extractText(null, outText));
+        assertFalse(mTextView.extractText(null, null));
     }
 
     @UiThreadTest
@@ -3051,6 +3741,12 @@
 
         tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
         assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getRawTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getRawTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getRawTextDirection());
     }
 
     @UiThreadTest
@@ -3077,6 +3773,12 @@
 
         tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
         assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
     }
 
     @UiThreadTest
@@ -3105,6 +3807,12 @@
 
         tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
         assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
     }
 
     @UiThreadTest
@@ -3131,6 +3839,12 @@
 
         tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
         assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
     }
 
     @UiThreadTest
@@ -3160,6 +3874,12 @@
         tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
         assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
 
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
+
         // Force to RTL text direction on the layout
         ll.setTextDirection(View.TEXT_DIRECTION_RTL);
 
@@ -3180,6 +3900,12 @@
 
         tv.setTextDirection(View.TEXT_DIRECTION_LOCALE);
         assertEquals(View.TEXT_DIRECTION_LOCALE, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
+
+        tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
+        assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
     }
 
     @UiThreadTest
@@ -3201,6 +3927,126 @@
     }
 
     @UiThreadTest
+    public void testTextDirectionFirstStrongLtr() {
+        {
+            // The first directional character is LTR, the paragraph direction is LTR.
+            LinearLayout ll = new LinearLayout(mActivity);
+
+            TextView tv = new TextView(mActivity);
+            tv.setText("this is a test");
+            ll.addView(tv);
+
+            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
+            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
+
+            tv.onPreDraw();  // For freezing layout.
+            Layout layout = tv.getLayout();
+            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
+        }
+        {
+            // The first directional character is RTL, the paragraph direction is RTL.
+            LinearLayout ll = new LinearLayout(mActivity);
+
+            TextView tv = new TextView(mActivity);
+            tv.setText("\u05DD\u05DE"); // Hebrew
+            ll.addView(tv);
+
+            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
+            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
+
+            tv.onPreDraw();  // For freezing layout.
+            Layout layout = tv.getLayout();
+            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
+        }
+        {
+            // The first directional character is not a strong directional character, the paragraph
+            // direction is LTR.
+            LinearLayout ll = new LinearLayout(mActivity);
+
+            TextView tv = new TextView(mActivity);
+            tv.setText("\uFFFD");  // REPLACEMENT CHARACTER. Neutral direction.
+            ll.addView(tv);
+
+            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_LTR);
+            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_LTR, tv.getTextDirection());
+
+            tv.onPreDraw();  // For freezing layout.
+            Layout layout = tv.getLayout();
+            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
+        }
+    }
+
+    @UiThreadTest
+    public void testTextDirectionFirstStrongRtl() {
+        {
+            // The first directional character is LTR, the paragraph direction is LTR.
+            LinearLayout ll = new LinearLayout(mActivity);
+
+            TextView tv = new TextView(mActivity);
+            tv.setText("this is a test");
+            ll.addView(tv);
+
+            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
+            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
+
+            tv.onPreDraw();  // For freezing layout.
+            Layout layout = tv.getLayout();
+            assertEquals(Layout.DIR_LEFT_TO_RIGHT, layout.getParagraphDirection(0));
+        }
+        {
+            // The first directional character is RTL, the paragraph direction is RTL.
+            LinearLayout ll = new LinearLayout(mActivity);
+
+            TextView tv = new TextView(mActivity);
+            tv.setText("\u05DD\u05DE"); // Hebrew
+            ll.addView(tv);
+
+            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
+            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
+
+            tv.onPreDraw();  // For freezing layout.
+            Layout layout = tv.getLayout();
+            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
+        }
+        {
+            // The first directional character is not a strong directional character, the paragraph
+            // direction is RTL.
+            LinearLayout ll = new LinearLayout(mActivity);
+
+            TextView tv = new TextView(mActivity);
+            tv.setText("\uFFFD");  // REPLACEMENT CHARACTER. Neutral direction.
+            ll.addView(tv);
+
+            tv.setTextDirection(View.TEXT_DIRECTION_FIRST_STRONG_RTL);
+            assertEquals(View.TEXT_DIRECTION_FIRST_STRONG_RTL, tv.getTextDirection());
+
+            tv.onPreDraw();  // For freezing layout.
+            Layout layout = tv.getLayout();
+            assertEquals(Layout.DIR_RIGHT_TO_LEFT, layout.getParagraphDirection(0));
+        }
+    }
+
+    public void testAllCapsLocalization() {
+        String testString = "abcdefghijklmnopqrstuvwxyz";
+
+        // The capitalized characters of "i" on Turkish and Azerbaijani are different from English.
+        Locale[] testLocales = {
+            new Locale("az", "AZ"),
+            new Locale("tr", "TR"),
+            new Locale("en", "US"),
+        };
+
+        TextView tv = new TextView(mActivity);
+        tv.setAllCaps(true);
+        for (Locale locale: testLocales) {
+            tv.setTextLocale(locale);
+            assertEquals("Locale: " + locale.getDisplayName(),
+                         testString.toUpperCase(locale),
+                         tv.getTransformationMethod().getTransformation(testString, tv).toString());
+        }
+    }
+
+    @UiThreadTest
     public void testTextAlignmentDefault() {
         TextView tv = new TextView(getActivity());
         assertEquals(View.TEXT_ALIGNMENT_GRAVITY, tv.getRawTextAlignment());
@@ -3553,6 +4399,191 @@
         assertNull(drawables[BOTTOM]);
     }
 
+    public void testSetGetBreakStrategy() {
+        TextView tv = new TextView(mActivity);
+
+        final PackageManager pm = getInstrumentation().getTargetContext().getPackageManager();
+
+        // The default value is from the theme, here the default is BREAK_STRATEGY_HIGH_QUALITY for
+        // TextView except for Android Wear. The default value for Android Wear is
+        // BREAK_STRATEGY_BALANCED.
+        if (pm.hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+            // Android Wear
+            assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy());
+        } else {
+            // All other form factor.
+            assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy());
+        }
+
+        tv.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
+        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, tv.getBreakStrategy());
+
+        tv.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
+        assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, tv.getBreakStrategy());
+
+        tv.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED);
+        assertEquals(Layout.BREAK_STRATEGY_BALANCED, tv.getBreakStrategy());
+
+        EditText et = new EditText(mActivity);
+
+        // The default value is from the theme, here the default is BREAK_STRATEGY_SIMPLE for
+        // EditText.
+        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy());
+
+        et.setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE);
+        assertEquals(Layout.BREAK_STRATEGY_SIMPLE, et.getBreakStrategy());
+
+        et.setBreakStrategy(Layout.BREAK_STRATEGY_HIGH_QUALITY);
+        assertEquals(Layout.BREAK_STRATEGY_HIGH_QUALITY, et.getBreakStrategy());
+
+        et.setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED);
+        assertEquals(Layout.BREAK_STRATEGY_BALANCED, et.getBreakStrategy());
+    }
+
+    public void testSetGetHyphenationFrequency() {
+        TextView tv = new TextView(mActivity);
+
+        assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency());
+
+        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE);
+        assertEquals(Layout.HYPHENATION_FREQUENCY_NONE, tv.getHyphenationFrequency());
+
+        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL);
+        assertEquals(Layout.HYPHENATION_FREQUENCY_NORMAL, tv.getHyphenationFrequency());
+
+        tv.setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_FULL);
+        assertEquals(Layout.HYPHENATION_FREQUENCY_FULL, tv.getHyphenationFrequency());
+    }
+
+    public void testSetAndGetCustomSelectionActionModeCallback() {
+        final String text = "abcde";
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                mTextView = new EditText(mActivity);
+                mActivity.setContentView(mTextView);
+                mTextView.setText(text, BufferType.SPANNABLE);
+                mTextView.setTextIsSelectable(true);
+                mTextView.requestFocus();
+                mTextView.setSelected(true);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // Check default value.
+        assertNull(mTextView.getCustomSelectionActionModeCallback());
+
+        MockActionModeCallback callbackBlockActionMode = new MockActionModeCallback(false);
+        mTextView.setCustomSelectionActionModeCallback(callbackBlockActionMode);
+        assertEquals(callbackBlockActionMode,
+                mTextView.getCustomSelectionActionModeCallback());
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Set selection and try to start action mode.
+                final Bundle args = new Bundle();
+                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
+                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
+                mTextView.performAccessibilityAction(
+                        AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertEquals(1, callbackBlockActionMode.getCreateCount());
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Remove selection and stop action mode.
+                mTextView.onTextContextMenuItem(android.R.id.copy);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // Action mode was blocked.
+        assertEquals(0, callbackBlockActionMode.getDestroyCount());
+
+        // Overwrite callback.
+        MockActionModeCallback callbackStartActionMode = new MockActionModeCallback(true);
+        mTextView.setCustomSelectionActionModeCallback(callbackStartActionMode);
+        assertEquals(callbackStartActionMode, mTextView.getCustomSelectionActionModeCallback());
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Set selection and try to start action mode.
+                final Bundle args = new Bundle();
+                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, 0);
+                args.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_END_INT, text.length());
+                mTextView.performAccessibilityAction(
+                        AccessibilityNodeInfo.ACTION_SET_SELECTION, args);
+
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        assertEquals(1, callbackStartActionMode.getCreateCount());
+
+        mActivity.runOnUiThread(new Runnable() {
+            public void run() {
+                // Remove selection and stop action mode.
+                mTextView.onTextContextMenuItem(android.R.id.copy);
+            }
+        });
+        mInstrumentation.waitForIdleSync();
+
+        // Action mode was started
+        assertEquals(1, callbackStartActionMode.getDestroyCount());
+    }
+
+    public void testSetAndGetCustomInseltionActionMode() {
+        initTextViewForTyping();
+        // Check default value.
+        assertNull(mTextView.getCustomInsertionActionModeCallback());
+
+        MockActionModeCallback callback = new MockActionModeCallback(false);
+        mTextView.setCustomInsertionActionModeCallback(callback);
+        assertEquals(callback, mTextView.getCustomInsertionActionModeCallback());
+        // TODO(Bug: 22033189): Tests the set callback is actually used.
+    }
+
+    private static class MockActionModeCallback implements ActionMode.Callback {
+        private int mCreateCount = 0;
+        private int mDestroyCount = 0;
+        private final boolean mAllowToStartActionMode;
+
+        public MockActionModeCallback(boolean allowToStartActionMode) {
+            mAllowToStartActionMode = allowToStartActionMode;
+        }
+
+        public int getCreateCount() {
+            return mCreateCount;
+        }
+
+        public int getDestroyCount() {
+            return mDestroyCount;
+        }
+
+        @Override
+        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+            return false;
+        }
+
+        @Override
+        public void onDestroyActionMode(ActionMode mode) {
+            mDestroyCount++;
+        }
+
+        @Override
+        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+            mCreateCount++;
+            return mAllowToStartActionMode;
+        }
+
+        @Override
+        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+            return false;
+        }
+    };
+
     private static class MockOnEditorActionListener implements OnEditorActionListener {
         private boolean isOnEditorActionCalled;
 
@@ -3925,4 +4956,35 @@
             }
         }
     }
+
+    /**
+     * A TextWatcher that converts the text to spaces whenever the text changes.
+     */
+    private static class ConvertToSpacesTextWatcher implements TextWatcher {
+        boolean mChangingText;
+
+        @Override
+        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        }
+
+        @Override
+        public void onTextChanged(CharSequence s, int start, int before, int count) {
+        }
+
+        @Override
+        public void afterTextChanged(Editable s) {
+            // Avoid infinite recursion.
+            if (mChangingText) {
+                return;
+            }
+            mChangingText = true;
+            // Create a string of s.length() spaces.
+            StringBuilder builder = new StringBuilder(s.length());
+            for (int i = 0; i < s.length(); i++) {
+                builder.append(' ');
+            }
+            s.replace(0, s.length(), builder.toString());
+            mChangingText = false;
+        }
+    }
 }
diff --git a/tests/tests/widget/src/android/widget/cts/TextView_SaveStateTest.java b/tests/tests/widget/src/android/widget/cts/TextView_SaveStateTest.java
deleted file mode 100644
index 801a6fd..0000000
--- a/tests/tests/widget/src/android/widget/cts/TextView_SaveStateTest.java
+++ /dev/null
@@ -1,70 +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 android.os.Parcel;
-import android.test.InstrumentationTestCase;
-import android.text.TextUtils;
-import android.view.AbsSavedState;
-import android.widget.TextView;
-
-/**
- * Test {@link TextView.SavedState}.
- */
-public class TextView_SaveStateTest extends InstrumentationTestCase {
-    public void testToString() {
-        Parcel source = creatTestParcel(0, 0, true, "This is content");
-        TextView.SavedState state = TextView.SavedState.CREATOR.createFromParcel(source);
-
-        assertNotNull(state.toString());
-
-        source = creatTestParcel(5, 10, false, "This is another content");
-        state = TextView.SavedState.CREATOR.createFromParcel(source);
-
-        assertNotNull(state.toString());
-    }
-
-    public void testWriteToParcel() {
-        Parcel source = creatTestParcel(0, 0, true, "This is content");
-        TextView.SavedState state = TextView.SavedState.CREATOR.createFromParcel(source);
-        assertNotNull(state);
-    }
-
-    /**
-     * Gets the parcel.
-     *
-     * @param start the start
-     * @param end the end
-     * @param frozenWithFocus the frozen with focus
-     * @param text the text
-     * @return the parcel
-     */
-    private Parcel creatTestParcel(int start, int end, boolean frozenWithFocus, String text) {
-        Parcel source = Parcel.obtain();
-
-        source.writeParcelable(AbsSavedState.EMPTY_STATE, 0);
-        source.writeInt(start);
-        source.writeInt(end);
-        source.writeInt(frozenWithFocus ? 1 : 0);
-        TextView textView = new TextView(getInstrumentation().getTargetContext());
-        textView.setText(text);
-        TextUtils.writeToParcel(textView.getText(), source, 0);
-        source.setDataPosition(0);
-        return source;
-    }
-}
diff --git a/tests/tests/widget/src/android/widget/cts/TimePickerTest.java b/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
index fcf787a..1ce2844 100644
--- a/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TimePickerTest.java
@@ -167,6 +167,37 @@
         assertEquals(Integer.valueOf(23), mTimePicker.getCurrentHour());
     }
 
+    public void testAccessHour() {
+        mTimePicker = new TimePicker(mContext);
+
+        // AM/PM mode
+        mTimePicker.setIs24HourView(false);
+
+        mTimePicker.setHour(0);
+        assertEquals(0, mTimePicker.getHour());
+
+        mTimePicker.setHour(12);
+        assertEquals(12, mTimePicker.getHour());
+
+        mTimePicker.setHour(13);
+        assertEquals(13, mTimePicker.getHour());
+
+        mTimePicker.setHour(23);
+        assertEquals(23, mTimePicker.getHour());
+
+        // for 24 hour mode
+        mTimePicker.setIs24HourView(true);
+
+        mTimePicker.setHour(0);
+        assertEquals(0, mTimePicker.getHour());
+
+        mTimePicker.setHour(13);
+        assertEquals(13, mTimePicker.getHour());
+
+        mTimePicker.setHour(23);
+        assertEquals(23, mTimePicker.getHour());
+    }
+
     public void testAccessIs24HourView() {
         mTimePicker = new TimePicker(mContext);
         assertFalse(mTimePicker.is24HourView());
@@ -194,6 +225,22 @@
         assertEquals(Integer.valueOf(59), mTimePicker.getCurrentMinute());
     }
 
+    public void testAccessMinute() {
+        mTimePicker = new TimePicker(mContext);
+
+        mTimePicker.setMinute(0);
+        assertEquals(0, mTimePicker.getMinute());
+
+        mTimePicker.setMinute(12);
+        assertEquals(12, mTimePicker.getMinute());
+
+        mTimePicker.setMinute(33);
+        assertEquals(33, mTimePicker.getMinute());
+
+        mTimePicker.setMinute(59);
+        assertEquals(59, mTimePicker.getMinute());
+    }
+
     public void testGetBaseline() {
         mTimePicker = new TimePicker(mContext);
         assertEquals(-1, mTimePicker.getBaseline());
diff --git a/tests/tests/widget/src/android/widget/cts/TwoLineListItemTest.java b/tests/tests/widget/src/android/widget/cts/TwoLineListItemTest.java
index 0d5807f..18dd407 100644
--- a/tests/tests/widget/src/android/widget/cts/TwoLineListItemTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TwoLineListItemTest.java
@@ -91,9 +91,9 @@
     public void testOnFinishInflate() {
         MockTwoLineListItem twoLineListItem = new MockTwoLineListItem(mActivity);
         TextView text1 = new TextView(mActivity);
-        text1.setId(com.android.internal.R.id.text1);
+        text1.setId(android.R.id.text1);
         TextView text2 = new TextView(mActivity);
-        text2.setId(com.android.internal.R.id.text2);
+        text2.setId(android.R.id.text2);
         LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,
                 LayoutParams.WRAP_CONTENT);
         twoLineListItem.addView(text1, params);
diff --git a/tests/tests/widget/src/android/widget/cts/util/ListScenario.java b/tests/tests/widget/src/android/widget/cts/util/ListScenario.java
index 11d670d..b61673c 100644
--- a/tests/tests/widget/src/android/widget/cts/util/ListScenario.java
+++ b/tests/tests/widget/src/android/widget/cts/util/ListScenario.java
@@ -17,6 +17,7 @@
 package android.widget.cts.util;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -35,8 +36,6 @@
 import android.widget.ListView;
 import android.widget.TextView;
 
-import com.google.android.collect.Maps;
-
 /**
  * Utility base class for creating various List scenarios.  Configurable by the number
  * of items, how tall each item should be (in relation to the screen height), and
@@ -52,7 +51,7 @@
 
     private int mStartingSelectionPosition;
     private double mItemScreenSizeFactor;
-    private Map<Integer, Double> mOverrideItemScreenSizeFactors = Maps.newHashMap();
+    private Map<Integer, Double> mOverrideItemScreenSizeFactors = new HashMap<>();
 
     private int mScreenHeight;
 
@@ -102,7 +101,7 @@
         private double mItemScreenSizeFactor = 1 / 5;
         private Double mFadingEdgeScreenSizeFactor = null;
 
-        private Map<Integer, Double> mOverrideItemScreenSizeFactors = Maps.newHashMap();
+        private Map<Integer, Double> mOverrideItemScreenSizeFactors = new HashMap<>();
 
         // separators
         private List<Integer> mUnselectableItems = new ArrayList<Integer>(8);
diff --git a/tests/tests/widget/src/android/widget/cts/util/XmlUtils.java b/tests/tests/widget/src/android/widget/cts/util/XmlUtils.java
new file mode 100644
index 0000000..1ff922f
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/util/XmlUtils.java
@@ -0,0 +1,1667 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR 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 org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.graphics.Bitmap;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.util.ArrayMap;
+import android.util.Base64;
+import android.util.Xml;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ProtocolException;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/** {@hide} */
+public class XmlUtils {
+
+    public static void skipCurrentTag(XmlPullParser parser)
+            throws XmlPullParserException, IOException {
+        int outerDepth = parser.getDepth();
+        int type;
+        while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
+               && (type != XmlPullParser.END_TAG
+                       || parser.getDepth() > outerDepth)) {
+        }
+    }
+
+    public static final int
+    convertValueToList(CharSequence value, String[] options, int defaultValue)
+    {
+        if (null != value) {
+            for (int i = 0; i < options.length; i++) {
+                if (value.equals(options[i]))
+                    return i;
+            }
+        }
+
+        return defaultValue;
+    }
+
+    public static final boolean
+    convertValueToBoolean(CharSequence value, boolean defaultValue)
+    {
+        boolean result = false;
+
+        if (null == value)
+            return defaultValue;
+
+        if (value.equals("1")
+        ||  value.equals("true")
+        ||  value.equals("TRUE"))
+            result = true;
+
+        return result;
+    }
+
+    public static final int
+    convertValueToInt(CharSequence charSeq, int defaultValue)
+    {
+        if (null == charSeq)
+            return defaultValue;
+
+        String nm = charSeq.toString();
+
+        // XXX This code is copied from Integer.decode() so we don't
+        // have to instantiate an Integer!
+
+        int value;
+        int sign = 1;
+        int index = 0;
+        int len = nm.length();
+        int base = 10;
+
+        if ('-' == nm.charAt(0)) {
+            sign = -1;
+            index++;
+        }
+
+        if ('0' == nm.charAt(index)) {
+            //  Quick check for a zero by itself
+            if (index == (len - 1))
+                return 0;
+
+            char    c = nm.charAt(index + 1);
+
+            if ('x' == c || 'X' == c) {
+                index += 2;
+                base = 16;
+            } else {
+                index++;
+                base = 8;
+            }
+        }
+        else if ('#' == nm.charAt(index))
+        {
+            index++;
+            base = 16;
+        }
+
+        return Integer.parseInt(nm.substring(index), base) * sign;
+    }
+
+    public static int convertValueToUnsignedInt(String value, int defaultValue) {
+        if (null == value) {
+            return defaultValue;
+        }
+
+        return parseUnsignedIntAttribute(value);
+    }
+
+    public static int parseUnsignedIntAttribute(CharSequence charSeq) {
+        String  value = charSeq.toString();
+
+        long    bits;
+        int     index = 0;
+        int     len = value.length();
+        int     base = 10;
+
+        if ('0' == value.charAt(index)) {
+            //  Quick check for zero by itself
+            if (index == (len - 1))
+                return 0;
+
+            char    c = value.charAt(index + 1);
+
+            if ('x' == c || 'X' == c) {     //  check for hex
+                index += 2;
+                base = 16;
+            } else {                        //  check for octal
+                index++;
+                base = 8;
+            }
+        } else if ('#' == value.charAt(index)) {
+            index++;
+            base = 16;
+        }
+
+        return (int) Long.parseLong(value.substring(index), base);
+    }
+
+    /**
+     * Flatten a List into an output stream as XML.  The list can later be
+     * read back with readListXml().
+     *
+     * @param val The list to be flattened.
+     * @param out Where to write the XML data.
+     *
+     * @see #writeListXml(List, String, XmlSerializer)
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readListXml
+     */
+    public static final void writeListXml(List val, OutputStream out)
+    throws XmlPullParserException, IOException
+    {
+        XmlSerializer serializer = Xml.newSerializer();
+        serializer.setOutput(out, StandardCharsets.UTF_8.name());
+        serializer.startDocument(null, true);
+        serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+        writeListXml(val, null, serializer);
+        serializer.endDocument();
+    }
+
+    /**
+     * Flatten a Map into an XmlSerializer.  The map can later be read back
+     * with readThisMapXml().
+     *
+     * @param val The map to be flattened.
+     * @param name Name attribute to include with this list's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the map into.
+     *
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     */
+    public static final void writeMapXml(Map val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        writeMapXml(val, name, out, null);
+    }
+
+    /**
+     * Flatten a Map into an XmlSerializer.  The map can later be read back
+     * with readThisMapXml().
+     *
+     * @param val The map to be flattened.
+     * @param name Name attribute to include with this list's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the map into.
+     * @param callback Method to call when an Object type is not recognized.
+     *
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     *
+     * @hide
+     */
+    public static final void writeMapXml(Map val, String name, XmlSerializer out,
+            WriteMapCallback callback) throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "map");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        writeMapXml(val, out, callback);
+
+        out.endTag(null, "map");
+    }
+
+    /**
+     * Flatten a Map into an XmlSerializer.  The map can later be read back
+     * with readThisMapXml(). This method presumes that the start tag and
+     * name attribute have already been written and does not write an end tag.
+     *
+     * @param val The map to be flattened.
+     * @param out XmlSerializer to write the map into.
+     *
+     * @see #writeListXml
+     * @see #writeValueXml
+     * @see #readMapXml
+     *
+     * @hide
+     */
+    public static final void writeMapXml(Map val, XmlSerializer out,
+            WriteMapCallback callback) throws XmlPullParserException, IOException {
+        if (val == null) {
+            return;
+        }
+
+        Set s = val.entrySet();
+        Iterator i = s.iterator();
+
+        while (i.hasNext()) {
+            Map.Entry e = (Map.Entry)i.next();
+            writeValueXml(e.getValue(), (String)e.getKey(), out, callback);
+        }
+    }
+
+    /**
+     * Flatten a List into an XmlSerializer.  The list can later be read back
+     * with readThisListXml().
+     *
+     * @param val The list to be flattened.
+     * @param name Name attribute to include with this list's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the list into.
+     *
+     * @see #writeListXml(List, OutputStream)
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readListXml
+     */
+    public static final void writeListXml(List val, String name, XmlSerializer out)
+    throws XmlPullParserException, IOException
+    {
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "list");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        int N = val.size();
+        int i=0;
+        while (i < N) {
+            writeValueXml(val.get(i), null, out);
+            i++;
+        }
+
+        out.endTag(null, "list");
+    }
+
+    public static final void writeSetXml(Set val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "set");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        for (Object v : val) {
+            writeValueXml(v, null, out);
+        }
+
+        out.endTag(null, "set");
+    }
+
+    /**
+     * Flatten a byte[] into an XmlSerializer.  The list can later be read back
+     * with readThisByteArrayXml().
+     *
+     * @param val The byte array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     */
+    public static final void writeByteArrayXml(byte[] val, String name,
+            XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "byte-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        StringBuilder sb = new StringBuilder(val.length*2);
+        for (int i=0; i<N; i++) {
+            int b = val[i];
+            int h = b>>4;
+            sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
+            h = b&0xff;
+            sb.append(h >= 10 ? ('a'+h-10) : ('0'+h));
+        }
+
+        out.text(sb.toString());
+
+        out.endTag(null, "byte-array");
+    }
+
+    /**
+     * Flatten an int[] into an XmlSerializer.  The list can later be read back
+     * with readThisIntArrayXml().
+     *
+     * @param val The int array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeIntArrayXml(int[] val, String name,
+            XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "int-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Integer.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "int-array");
+    }
+
+    /**
+     * Flatten a long[] into an XmlSerializer.  The list can later be read back
+     * with readThisLongArrayXml().
+     *
+     * @param val The long array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeLongArrayXml(long[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "long-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Long.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "long-array");
+    }
+
+    /**
+     * Flatten a double[] into an XmlSerializer.  The list can later be read back
+     * with readThisDoubleArrayXml().
+     *
+     * @param val The double array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeDoubleArrayXml(double[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "double-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Double.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "double-array");
+    }
+
+    /**
+     * Flatten a String[] into an XmlSerializer.  The list can later be read back
+     * with readThisStringArrayXml().
+     *
+     * @param val The String array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeStringArrayXml(String[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "string-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", val[i]);
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "string-array");
+    }
+
+    /**
+     * Flatten a boolean[] into an XmlSerializer.  The list can later be read back
+     * with readThisBooleanArrayXml().
+     *
+     * @param val The boolean array to be flattened.
+     * @param name Name attribute to include with this array's tag, or null for
+     *             none.
+     * @param out XmlSerializer to write the array into.
+     *
+     * @see #writeMapXml
+     * @see #writeValueXml
+     * @see #readThisIntArrayXml
+     */
+    public static final void writeBooleanArrayXml(boolean[] val, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+
+        if (val == null) {
+            out.startTag(null, "null");
+            out.endTag(null, "null");
+            return;
+        }
+
+        out.startTag(null, "boolean-array");
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+
+        final int N = val.length;
+        out.attribute(null, "num", Integer.toString(N));
+
+        for (int i=0; i<N; i++) {
+            out.startTag(null, "item");
+            out.attribute(null, "value", Boolean.toString(val[i]));
+            out.endTag(null, "item");
+        }
+
+        out.endTag(null, "boolean-array");
+    }
+
+    /**
+     * Flatten an object's value into an XmlSerializer.  The value can later
+     * be read back with readThisValueXml().
+     *
+     * Currently supported value types are: null, String, Integer, Long,
+     * Float, Double Boolean, Map, List.
+     *
+     * @param v The object to be flattened.
+     * @param name Name attribute to include with this value's tag, or null
+     *             for none.
+     * @param out XmlSerializer to write the object into.
+     *
+     * @see #writeMapXml
+     * @see #writeListXml
+     * @see #readValueXml
+     */
+    public static final void writeValueXml(Object v, String name, XmlSerializer out)
+            throws XmlPullParserException, IOException {
+        writeValueXml(v, name, out, null);
+    }
+
+    /**
+     * Flatten an object's value into an XmlSerializer.  The value can later
+     * be read back with readThisValueXml().
+     *
+     * Currently supported value types are: null, String, Integer, Long,
+     * Float, Double Boolean, Map, List.
+     *
+     * @param v The object to be flattened.
+     * @param name Name attribute to include with this value's tag, or null
+     *             for none.
+     * @param out XmlSerializer to write the object into.
+     * @param callback Handler for Object types not recognized.
+     *
+     * @see #writeMapXml
+     * @see #writeListXml
+     * @see #readValueXml
+     */
+    private static final void writeValueXml(Object v, String name, XmlSerializer out,
+            WriteMapCallback callback)  throws XmlPullParserException, IOException {
+        String typeStr;
+        if (v == null) {
+            out.startTag(null, "null");
+            if (name != null) {
+                out.attribute(null, "name", name);
+            }
+            out.endTag(null, "null");
+            return;
+        } else if (v instanceof String) {
+            out.startTag(null, "string");
+            if (name != null) {
+                out.attribute(null, "name", name);
+            }
+            out.text(v.toString());
+            out.endTag(null, "string");
+            return;
+        } else if (v instanceof Integer) {
+            typeStr = "int";
+        } else if (v instanceof Long) {
+            typeStr = "long";
+        } else if (v instanceof Float) {
+            typeStr = "float";
+        } else if (v instanceof Double) {
+            typeStr = "double";
+        } else if (v instanceof Boolean) {
+            typeStr = "boolean";
+        } else if (v instanceof byte[]) {
+            writeByteArrayXml((byte[])v, name, out);
+            return;
+        } else if (v instanceof int[]) {
+            writeIntArrayXml((int[])v, name, out);
+            return;
+        } else if (v instanceof long[]) {
+            writeLongArrayXml((long[])v, name, out);
+            return;
+        } else if (v instanceof double[]) {
+            writeDoubleArrayXml((double[])v, name, out);
+            return;
+        } else if (v instanceof String[]) {
+            writeStringArrayXml((String[])v, name, out);
+            return;
+        } else if (v instanceof boolean[]) {
+            writeBooleanArrayXml((boolean[])v, name, out);
+            return;
+        } else if (v instanceof Map) {
+            writeMapXml((Map)v, name, out);
+            return;
+        } else if (v instanceof List) {
+            writeListXml((List) v, name, out);
+            return;
+        } else if (v instanceof Set) {
+            writeSetXml((Set) v, name, out);
+            return;
+        } else if (v instanceof CharSequence) {
+            // XXX This is to allow us to at least write something if
+            // we encounter styled text...  but it means we will drop all
+            // of the styling information. :(
+            out.startTag(null, "string");
+            if (name != null) {
+                out.attribute(null, "name", name);
+            }
+            out.text(v.toString());
+            out.endTag(null, "string");
+            return;
+        } else if (callback != null) {
+            callback.writeUnknownObject(v, name, out);
+            return;
+        } else {
+            throw new RuntimeException("writeValueXml: unable to write value " + v);
+        }
+
+        out.startTag(null, typeStr);
+        if (name != null) {
+            out.attribute(null, "name", name);
+        }
+        out.attribute(null, "value", v.toString());
+        out.endTag(null, typeStr);
+    }
+
+    /**
+     * Read a HashMap from an InputStream containing XML.  The stream can
+     * previously have been written by writeMapXml().
+     *
+     * @param in The InputStream from which to read.
+     *
+     * @return HashMap The resulting map.
+     *
+     * @see #readListXml
+     * @see #readValueXml
+     * @see #readThisMapXml
+     * #see #writeMapXml
+     */
+    @SuppressWarnings("unchecked")
+    public static final HashMap<String, ?> readMapXml(InputStream in)
+    throws XmlPullParserException, IOException
+    {
+        XmlPullParser   parser = Xml.newPullParser();
+        parser.setInput(in, StandardCharsets.UTF_8.name());
+        return (HashMap<String, ?>) readValueXml(parser, new String[1]);
+    }
+
+    /**
+     * Read an ArrayList from an InputStream containing XML.  The stream can
+     * previously have been written by writeListXml().
+     *
+     * @param in The InputStream from which to read.
+     *
+     * @return ArrayList The resulting list.
+     *
+     * @see #readMapXml
+     * @see #readValueXml
+     * @see #readThisListXml
+     * @see #writeListXml
+     */
+    public static final ArrayList readListXml(InputStream in)
+    throws XmlPullParserException, IOException
+    {
+        XmlPullParser   parser = Xml.newPullParser();
+        parser.setInput(in, StandardCharsets.UTF_8.name());
+        return (ArrayList)readValueXml(parser, new String[1]);
+    }
+
+
+    /**
+     * Read a HashSet from an InputStream containing XML. The stream can
+     * previously have been written by writeSetXml().
+     *
+     * @param in The InputStream from which to read.
+     *
+     * @return HashSet The resulting set.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     *
+     * @see #readValueXml
+     * @see #readThisSetXml
+     * @see #writeSetXml
+     */
+    public static final HashSet readSetXml(InputStream in)
+            throws XmlPullParserException, IOException {
+        XmlPullParser parser = Xml.newPullParser();
+        parser.setInput(in, null);
+        return (HashSet) readValueXml(parser, new String[1]);
+    }
+
+    /**
+     * Read a HashMap object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeMapXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the map.
+     *
+     * @param parser The XmlPullParser from which to read the map data.
+     * @param endTag Name of the tag that will end the map, usually "map".
+     * @param name An array of one string, used to return the name attribute
+     *             of the map's tag.
+     *
+     * @return HashMap The newly generated map.
+     *
+     * @see #readMapXml
+     */
+    public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+        return readThisMapXml(parser, endTag, name, null);
+    }
+
+    /**
+     * Read a HashMap object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeMapXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the map.
+     *
+     * @param parser The XmlPullParser from which to read the map data.
+     * @param endTag Name of the tag that will end the map, usually "map".
+     * @param name An array of one string, used to return the name attribute
+     *             of the map's tag.
+     *
+     * @return HashMap The newly generated map.
+     *
+     * @see #readMapXml
+     * @hide
+     */
+    public static final HashMap<String, ?> readThisMapXml(XmlPullParser parser, String endTag,
+            String[] name, ReadMapCallback callback)
+            throws XmlPullParserException, IOException
+    {
+        HashMap<String, Object> map = new HashMap<String, Object>();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, false);
+                map.put(name[0], val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return map;
+                }
+                throw new XmlPullParserException(
+                    "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Like {@link #readThisMapXml}, but returns an ArrayMap instead of HashMap.
+     * @hide
+     */
+    public static final ArrayMap<String, ?> readThisArrayMapXml(XmlPullParser parser, String endTag,
+            String[] name, ReadMapCallback callback)
+            throws XmlPullParserException, IOException
+    {
+        ArrayMap<String, Object> map = new ArrayMap<>();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, true);
+                map.put(name[0], val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return map;
+                }
+                throw new XmlPullParserException(
+                    "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read an ArrayList object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeListXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return HashMap The newly generated list.
+     *
+     * @see #readListXml
+     */
+    public static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+        return readThisListXml(parser, endTag, name, null, false);
+    }
+
+    /**
+     * Read an ArrayList object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeListXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return HashMap The newly generated list.
+     *
+     * @see #readListXml
+     */
+    private static final ArrayList readThisListXml(XmlPullParser parser, String endTag,
+            String[] name, ReadMapCallback callback, boolean arrayMap)
+            throws XmlPullParserException, IOException {
+        ArrayList list = new ArrayList();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, arrayMap);
+                list.add(val);
+                //System.out.println("Adding to list: " + val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return list;
+                }
+                throw new XmlPullParserException(
+                    "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a HashSet object from an XmlPullParser. The XML data could previously
+     * have been generated by writeSetXml(). The XmlPullParser must be positioned
+     * <em>after</em> the tag that begins the set.
+     *
+     * @param parser The XmlPullParser from which to read the set data.
+     * @param endTag Name of the tag that will end the set, usually "set".
+     * @param name An array of one string, used to return the name attribute
+     *             of the set's tag.
+     *
+     * @return HashSet The newly generated set.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     *
+     * @see #readSetXml
+     */
+    public static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name)
+            throws XmlPullParserException, IOException {
+        return readThisSetXml(parser, endTag, name, null, false);
+    }
+
+    /**
+     * Read a HashSet object from an XmlPullParser. The XML data could previously
+     * have been generated by writeSetXml(). The XmlPullParser must be positioned
+     * <em>after</em> the tag that begins the set.
+     *
+     * @param parser The XmlPullParser from which to read the set data.
+     * @param endTag Name of the tag that will end the set, usually "set".
+     * @param name An array of one string, used to return the name attribute
+     *             of the set's tag.
+     *
+     * @return HashSet The newly generated set.
+     *
+     * @throws XmlPullParserException
+     * @throws IOException
+     *
+     * @see #readSetXml
+     * @hide
+     */
+    private static final HashSet readThisSetXml(XmlPullParser parser, String endTag, String[] name,
+            ReadMapCallback callback, boolean arrayMap)
+            throws XmlPullParserException, IOException {
+        HashSet set = new HashSet();
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                Object val = readThisValueXml(parser, name, callback, arrayMap);
+                set.add(val);
+                //System.out.println("Adding to set: " + val);
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return set;
+                }
+                throw new XmlPullParserException(
+                        "Expected " + endTag + " end tag at: " + parser.getName());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+                "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read an int[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeIntArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated int[].
+     *
+     * @see #readListXml
+     */
+    public static final int[] readThisIntArrayXml(XmlPullParser parser,
+            String endTag, String[] name)
+            throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException(
+                    "Need num attribute in byte-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException(
+                    "Not a number in num attribute in byte-array");
+        }
+        parser.next();
+
+        int[] array = new int[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Integer.parseInt(
+                                parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException(
+                                "Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException(
+                                "Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException(
+                            "Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException(
+                        "Expected " + endTag + " end tag at: "
+                        + parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a long[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeLongArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "list".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated long[].
+     *
+     * @see #readListXml
+     */
+    public static final long[] readThisLongArrayXml(XmlPullParser parser,
+            String endTag, String[] name)
+            throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in long-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in long-array");
+        }
+        parser.next();
+
+        long[] array = new long[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Long.parseLong(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a double[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeDoubleArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "double-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated double[].
+     *
+     * @see #readListXml
+     */
+    public static final double[] readThisDoubleArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in double-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in double-array");
+        }
+        parser.next();
+
+        double[] array = new double[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Double.parseDouble(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a String[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeStringArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "string-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated String[].
+     *
+     * @see #readListXml
+     */
+    public static final String[] readThisStringArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in string-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in string-array");
+        }
+        parser.next();
+
+        String[] array = new String[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = parser.getAttributeValue(null, "value");
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a boolean[] object from an XmlPullParser.  The XML data could
+     * previously have been generated by writeBooleanArrayXml().  The XmlPullParser
+     * must be positioned <em>after</em> the tag that begins the list.
+     *
+     * @param parser The XmlPullParser from which to read the list data.
+     * @param endTag Name of the tag that will end the list, usually "string-array".
+     * @param name An array of one string, used to return the name attribute
+     *             of the list's tag.
+     *
+     * @return Returns a newly generated boolean[].
+     *
+     * @see #readListXml
+     */
+    public static final boolean[] readThisBooleanArrayXml(XmlPullParser parser, String endTag,
+            String[] name) throws XmlPullParserException, IOException {
+
+        int num;
+        try {
+            num = Integer.parseInt(parser.getAttributeValue(null, "num"));
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need num attribute in string-array");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException("Not a number in num attribute in string-array");
+        }
+        parser.next();
+
+        boolean[] array = new boolean[num];
+        int i = 0;
+
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                if (parser.getName().equals("item")) {
+                    try {
+                        array[i] = Boolean.valueOf(parser.getAttributeValue(null, "value"));
+                    } catch (NullPointerException e) {
+                        throw new XmlPullParserException("Need value attribute in item");
+                    } catch (NumberFormatException e) {
+                        throw new XmlPullParserException("Not a number in value attribute in item");
+                    }
+                } else {
+                    throw new XmlPullParserException("Expected item tag at: " + parser.getName());
+                }
+            } else if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(endTag)) {
+                    return array;
+                } else if (parser.getName().equals("item")) {
+                    i++;
+                } else {
+                    throw new XmlPullParserException("Expected " + endTag + " end tag at: " +
+                            parser.getName());
+                }
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException("Document ended before " + endTag + " end tag");
+    }
+
+    /**
+     * Read a flattened object from an XmlPullParser.  The XML data could
+     * previously have been written with writeMapXml(), writeListXml(), or
+     * writeValueXml().  The XmlPullParser must be positioned <em>at</em> the
+     * tag that defines the value.
+     *
+     * @param parser The XmlPullParser from which to read the object.
+     * @param name An array of one string, used to return the name attribute
+     *             of the value's tag.
+     *
+     * @return Object The newly generated value object.
+     *
+     * @see #readMapXml
+     * @see #readListXml
+     * @see #writeValueXml
+     */
+    public static final Object readValueXml(XmlPullParser parser, String[] name)
+    throws XmlPullParserException, IOException
+    {
+        int eventType = parser.getEventType();
+        do {
+            if (eventType == parser.START_TAG) {
+                return readThisValueXml(parser, name, null, false);
+            } else if (eventType == parser.END_TAG) {
+                throw new XmlPullParserException(
+                    "Unexpected end tag at: " + parser.getName());
+            } else if (eventType == parser.TEXT) {
+                throw new XmlPullParserException(
+                    "Unexpected text: " + parser.getText());
+            }
+            eventType = parser.next();
+        } while (eventType != parser.END_DOCUMENT);
+
+        throw new XmlPullParserException(
+            "Unexpected end of document");
+    }
+
+    private static final Object readThisValueXml(XmlPullParser parser, String[] name,
+            ReadMapCallback callback, boolean arrayMap)
+            throws XmlPullParserException, IOException {
+        final String valueName = parser.getAttributeValue(null, "name");
+        final String tagName = parser.getName();
+
+        //System.out.println("Reading this value tag: " + tagName + ", name=" + valueName);
+
+        Object res;
+
+        if (tagName.equals("null")) {
+            res = null;
+        } else if (tagName.equals("string")) {
+            String value = "";
+            int eventType;
+            while ((eventType = parser.next()) != parser.END_DOCUMENT) {
+                if (eventType == parser.END_TAG) {
+                    if (parser.getName().equals("string")) {
+                        name[0] = valueName;
+                        //System.out.println("Returning value for " + valueName + ": " + value);
+                        return value;
+                    }
+                    throw new XmlPullParserException(
+                        "Unexpected end tag in <string>: " + parser.getName());
+                } else if (eventType == parser.TEXT) {
+                    value += parser.getText();
+                } else if (eventType == parser.START_TAG) {
+                    throw new XmlPullParserException(
+                        "Unexpected start tag in <string>: " + parser.getName());
+                }
+            }
+            throw new XmlPullParserException(
+                "Unexpected end of document in <string>");
+        } else if ((res = readThisPrimitiveValueXml(parser, tagName)) != null) {
+            // all work already done by readThisPrimitiveValueXml
+        } else if (tagName.equals("int-array")) {
+            res = readThisIntArrayXml(parser, "int-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("long-array")) {
+            res = readThisLongArrayXml(parser, "long-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("double-array")) {
+            res = readThisDoubleArrayXml(parser, "double-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("string-array")) {
+            res = readThisStringArrayXml(parser, "string-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("boolean-array")) {
+            res = readThisBooleanArrayXml(parser, "boolean-array", name);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("map")) {
+            parser.next();
+            res = arrayMap
+                    ? readThisArrayMapXml(parser, "map", name, callback)
+                    : readThisMapXml(parser, "map", name, callback);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("list")) {
+            parser.next();
+            res = readThisListXml(parser, "list", name, callback, arrayMap);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (tagName.equals("set")) {
+            parser.next();
+            res = readThisSetXml(parser, "set", name, callback, arrayMap);
+            name[0] = valueName;
+            //System.out.println("Returning value for " + valueName + ": " + res);
+            return res;
+        } else if (callback != null) {
+            res = callback.readThisUnknownObjectXml(parser, tagName);
+            name[0] = valueName;
+            return res;
+        } else {
+            throw new XmlPullParserException("Unknown tag: " + tagName);
+        }
+
+        // Skip through to end tag.
+        int eventType;
+        while ((eventType = parser.next()) != parser.END_DOCUMENT) {
+            if (eventType == parser.END_TAG) {
+                if (parser.getName().equals(tagName)) {
+                    name[0] = valueName;
+                    //System.out.println("Returning value for " + valueName + ": " + res);
+                    return res;
+                }
+                throw new XmlPullParserException(
+                    "Unexpected end tag in <" + tagName + ">: " + parser.getName());
+            } else if (eventType == parser.TEXT) {
+                throw new XmlPullParserException(
+                "Unexpected text in <" + tagName + ">: " + parser.getName());
+            } else if (eventType == parser.START_TAG) {
+                throw new XmlPullParserException(
+                    "Unexpected start tag in <" + tagName + ">: " + parser.getName());
+            }
+        }
+        throw new XmlPullParserException(
+            "Unexpected end of document in <" + tagName + ">");
+    }
+
+    private static final Object readThisPrimitiveValueXml(XmlPullParser parser, String tagName)
+    throws XmlPullParserException, IOException
+    {
+        try {
+            if (tagName.equals("int")) {
+                return Integer.parseInt(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("long")) {
+                return Long.valueOf(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("float")) {
+                return new Float(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("double")) {
+                return new Double(parser.getAttributeValue(null, "value"));
+            } else if (tagName.equals("boolean")) {
+                return Boolean.valueOf(parser.getAttributeValue(null, "value"));
+            } else {
+                return null;
+            }
+        } catch (NullPointerException e) {
+            throw new XmlPullParserException("Need value attribute in <" + tagName + ">");
+        } catch (NumberFormatException e) {
+            throw new XmlPullParserException(
+                    "Not a number in value attribute in <" + tagName + ">");
+        }
+    }
+
+    public static final void beginDocument(XmlPullParser parser, String firstElementName) throws XmlPullParserException, IOException
+    {
+        int type;
+        while ((type=parser.next()) != parser.START_TAG
+                   && type != parser.END_DOCUMENT) {
+            ;
+        }
+
+        if (type != parser.START_TAG) {
+            throw new XmlPullParserException("No start tag found");
+        }
+
+        if (!parser.getName().equals(firstElementName)) {
+            throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
+                    ", expected " + firstElementName);
+        }
+    }
+
+    public static final void nextElement(XmlPullParser parser) throws XmlPullParserException, IOException
+    {
+        int type;
+        while ((type=parser.next()) != parser.START_TAG
+                   && type != parser.END_DOCUMENT) {
+            ;
+        }
+    }
+
+    public static boolean nextElementWithin(XmlPullParser parser, int outerDepth)
+            throws IOException, XmlPullParserException {
+        for (;;) {
+            int type = parser.next();
+            if (type == XmlPullParser.END_DOCUMENT
+                    || (type == XmlPullParser.END_TAG && parser.getDepth() == outerDepth)) {
+                return false;
+            }
+            if (type == XmlPullParser.START_TAG
+                    && parser.getDepth() == outerDepth + 1) {
+                return true;
+            }
+        }
+    }
+
+    public static int readIntAttribute(XmlPullParser in, String name, int defaultValue) {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    public static int readIntAttribute(XmlPullParser in, String name) throws IOException {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            throw new ProtocolException("problem parsing " + name + "=" + value + " as int");
+        }
+    }
+
+    public static void writeIntAttribute(XmlSerializer out, String name, int value)
+            throws IOException {
+        out.attribute(null, name, Integer.toString(value));
+    }
+
+    public static long readLongAttribute(XmlPullParser in, String name, long defaultValue) {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Long.parseLong(value);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    public static long readLongAttribute(XmlPullParser in, String name) throws IOException {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Long.parseLong(value);
+        } catch (NumberFormatException e) {
+            throw new ProtocolException("problem parsing " + name + "=" + value + " as long");
+        }
+    }
+
+    public static void writeLongAttribute(XmlSerializer out, String name, long value)
+            throws IOException {
+        out.attribute(null, name, Long.toString(value));
+    }
+
+    public static float readFloatAttribute(XmlPullParser in, String name) throws IOException {
+        final String value = in.getAttributeValue(null, name);
+        try {
+            return Float.parseFloat(value);
+        } catch (NumberFormatException e) {
+            throw new ProtocolException("problem parsing " + name + "=" + value + " as long");
+        }
+    }
+
+    public static void writeFloatAttribute(XmlSerializer out, String name, float value)
+            throws IOException {
+        out.attribute(null, name, Float.toString(value));
+    }
+
+    public static boolean readBooleanAttribute(XmlPullParser in, String name) {
+        final String value = in.getAttributeValue(null, name);
+        return Boolean.parseBoolean(value);
+    }
+
+    public static boolean readBooleanAttribute(XmlPullParser in, String name,
+            boolean defaultValue) {
+        final String value = in.getAttributeValue(null, name);
+        if (value == null) {
+            return defaultValue;
+        } else {
+            return Boolean.parseBoolean(value);
+        }
+    }
+
+    public static void writeBooleanAttribute(XmlSerializer out, String name, boolean value)
+            throws IOException {
+        out.attribute(null, name, Boolean.toString(value));
+    }
+
+    public static Uri readUriAttribute(XmlPullParser in, String name) {
+        final String value = in.getAttributeValue(null, name);
+        return (value != null) ? Uri.parse(value) : null;
+    }
+
+    public static void writeUriAttribute(XmlSerializer out, String name, Uri value)
+            throws IOException {
+        if (value != null) {
+            out.attribute(null, name, value.toString());
+        }
+    }
+
+    public static String readStringAttribute(XmlPullParser in, String name) {
+        return in.getAttributeValue(null, name);
+    }
+
+    public static void writeStringAttribute(XmlSerializer out, String name, String value)
+            throws IOException {
+        if (value != null) {
+            out.attribute(null, name, value);
+        }
+    }
+
+    public static byte[] readByteArrayAttribute(XmlPullParser in, String name) {
+        final String value = in.getAttributeValue(null, name);
+        if (value != null) {
+            return Base64.decode(value, Base64.DEFAULT);
+        } else {
+            return null;
+        }
+    }
+
+    public static void writeByteArrayAttribute(XmlSerializer out, String name, byte[] value)
+            throws IOException {
+        if (value != null) {
+            out.attribute(null, name, Base64.encodeToString(value, Base64.DEFAULT));
+        }
+    }
+
+    public static Bitmap readBitmapAttribute(XmlPullParser in, String name) {
+        final byte[] value = readByteArrayAttribute(in, name);
+        if (value != null) {
+            return BitmapFactory.decodeByteArray(value, 0, value.length);
+        } else {
+            return null;
+        }
+    }
+
+    @Deprecated
+    public static void writeBitmapAttribute(XmlSerializer out, String name, Bitmap value)
+            throws IOException {
+        if (value != null) {
+            final ByteArrayOutputStream os = new ByteArrayOutputStream();
+            value.compress(CompressFormat.PNG, 90, os);
+            writeByteArrayAttribute(out, name, os.toByteArray());
+        }
+    }
+
+    /** @hide */
+    public interface WriteMapCallback {
+        /**
+         * Called from writeMapXml when an Object type is not recognized. The implementer
+         * must write out the entire element including start and end tags.
+         *
+         * @param v The object to be written out
+         * @param name The mapping key for v. Must be written into the "name" attribute of the
+         *             start tag.
+         * @param out The XML output stream.
+         * @throws XmlPullParserException on unrecognized Object type.
+         * @throws IOException on XmlSerializer serialization errors.
+         * @hide
+         */
+         public void writeUnknownObject(Object v, String name, XmlSerializer out)
+                 throws XmlPullParserException, IOException;
+    }
+
+    /** @hide */
+    public interface ReadMapCallback {
+        /**
+         * Called from readThisMapXml when a START_TAG is not recognized. The input stream
+         * is positioned within the start tag so that attributes can be read using in.getAttribute.
+         *
+         * @param in the XML input stream
+         * @param tag the START_TAG that was not recognized.
+         * @return the Object parsed from the stream which will be put into the map.
+         * @throws XmlPullParserException if the START_TAG is not recognized.
+         * @throws IOException on XmlPullParser serialization errors.
+         * @hide
+         */
+        public Object readThisUnknownObjectXml(XmlPullParser in, String tag)
+                throws XmlPullParserException, IOException;
+    }
+}
diff --git a/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk b/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
index 90bdb61..3827754 100644
--- a/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
+++ b/tests/uiautomator/test-apps/CtsUiAutomatorApp/Android.mk
@@ -30,4 +30,4 @@
 
 LOCAL_DEX_PREOPT := false
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tests/webgl/Android.mk b/tests/webgl/Android.mk
deleted file mode 100755
index ce22dd8..0000000
--- a/tests/webgl/Android.mk
+++ /dev/null
@@ -1,34 +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
-
-# When built, explicitly put it in the data partition.
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-
-LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceutil ctstestrunner
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-# Must match the package name in CtsTestCaseList.mk
-LOCAL_PACKAGE_NAME := CtsWebGLTestCases
-
-LOCAL_SDK_VERSION := current
-
-include $(BUILD_CTS_PACKAGE)
diff --git a/tests/webgl/AndroidManifest.xml b/tests/webgl/AndroidManifest.xml
deleted file mode 100755
index d648032..0000000
--- a/tests/webgl/AndroidManifest.xml
+++ /dev/null
@@ -1,45 +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="android.webgl.cts">
-
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.INTERNET" />
-
-    <application android:maxRecents="1">
-        <uses-library android:name="android.test.runner" />
-        <activity android:name="android.webgl.WebGLActivity" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-
-
-    <!--  self-instrumenting test package. -->
-    <instrumentation
-        android:name="android.support.test.runner.AndroidJUnitRunner"
-        android:label="CTS WebGL tests"
-        android:targetPackage="android.webgl.cts" >
-        <meta-data
-            android:name="listener"
-            android:value="com.android.cts.runner.CtsTestRunListener" />
-    </instrumentation>
-</manifest>
-
diff --git a/tests/webgl/res/raw/extract_webgl_tests.py b/tests/webgl/res/raw/extract_webgl_tests.py
deleted file mode 100755
index 1511632..0000000
--- a/tests/webgl/res/raw/extract_webgl_tests.py
+++ /dev/null
@@ -1,69 +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.
-
-import sys
-import os
-
-if len(sys.argv) != 3:
-  raise Exception("Usage: extract_webgl_tests.py <webgl_sdk_tests_path> <version>")
-
-top_list = sys.argv[1] + "/00_test_list.txt"
-version = sys.argv[2]
-tests = []
-lists = []
-lists.append(top_list)
-
-def filter_by_version(lines):
-  version_lines = [ line for line in lines if "--min-version" in line ]
-  version_lines.extend([ line for line in lines if "--max-version" in line ])
-  lines = [ line for line in lines if not line in version_lines ]
-  for line in version_lines:
-    assert len(line.split()) == 3
-    min_version = line.split()[1] if line.split()[0] == "--min-version" else "0.0.0"
-    max_version = line.split()[1] if line.split()[0] == "--max-version" else "9.9.9"
-    test = line.split()[2]
-    if (version >= min_version and version <= max_version):
-      lines.append(test)
-  return lines
-
-while not len(lists) == 0:
-  lists2 = lists
-  lists = []
-  for list in lists2:
-    directory = os.path.dirname(os.path.realpath(list))
-    with open(list) as file:
-      # Filter out comments and --min-version
-      lines = [ line.strip() for line in file.readlines()]
-      lines = [ line for line in lines if not "//" in line ]
-      lines = [ line for line in lines if not "#" in line ]
-      lines = [ line.replace("--slow","") for line in lines ]
-      lines = filter_by_version(lines)
-      # Append lists and tests found in this list.
-      lines = [ directory + "/" + line for line in lines ]
-      lists.extend([ line for line in lines if "00_test_list.txt" in line ])
-      tests.extend([ line for line in lines if ".html" in line ])
-
-# Directories for formating test-names/relative-paths.
-name_directory = os.path.dirname(os.path.realpath(top_list))
-path_directory = os.path.realpath(os.path.join(name_directory, os.pardir))
-
-tests = sorted(tests)
-for test in tests:
-  test_path = test.replace(path_directory + "/", "")
-  test_name = test.replace(name_directory + "/", "")
-  test_name = test_name.replace("/","_")
-  test_name = test_name.replace(".","_")
-  test_name = test_name.replace("-","_")
-  print "    public void test_" + test_name + "() throws Exception { doTest(\"" + test_path + "\"); }"
-
diff --git a/tests/webgl/res/raw/harness.html b/tests/webgl/res/raw/harness.html
deleted file mode 100644
index 5ae56ef..0000000
--- a/tests/webgl/res/raw/harness.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE html>
-<!-- saved from url=(0057)http://www.corp.google.com/~vollick/timing-functions.html -->
-<html>
-<head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-
-<script type="text/javascript">
-    // Check for WebGL Support.
-    function supportsWebGL() {
-        var canvas = document.createElement('canvas');
-        gl = canvas.getContext("webgl");
-        return !!gl;
-    }
-
-    // Pass the WebGL harness calls through to the native app.
-    webglTestHarness = {
-        notifyFinished: function() {
-            WebGLCallback.notifyFinished();
-        },
-        reportResults: function(type, success, msg) {
-            WebGLCallback.reportResults(type, success, msg);
-        }
-    }
-    function navigateToTest() {
-        if (supportsWebGL())
-            window.open(WebGLCallback.getUrlToTest(), "TestFrame");
-        else
-            WebGLCallback.notifyFinished();
-    }
-    window.addEventListener('load', navigateToTest, false);
-</script>
-
-<style type="text/css">
-body, html { margin: 0; padding: 0; height: 100%; overflow: hidden; }
-#content { position:absolute; left: 0; right: 0; bottom: 0; top: 0px; }
-</style>
-
-</head>
-
-<body>
-  <div id="content">
-    <iframe name="TestFrame" width="100%" height="100%" frameborder="0"/>
-  </div>
-</body>
-</html>
diff --git a/tests/webgl/res/raw/webgl_sdk_tests.zip b/tests/webgl/res/raw/webgl_sdk_tests.zip
deleted file mode 100644
index a2086b0..0000000
--- a/tests/webgl/res/raw/webgl_sdk_tests.zip
+++ /dev/null
Binary files differ
diff --git a/tests/webgl/src/android/webgl/WebGLActivity.java b/tests/webgl/src/android/webgl/WebGLActivity.java
deleted file mode 100644
index 3f911c4..0000000
--- a/tests/webgl/src/android/webgl/WebGLActivity.java
+++ /dev/null
@@ -1,142 +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.webgl;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.Resources;
-import android.cts.util.NullWebViewUtils;
-import android.os.Bundle;
-import android.util.Log;
-import android.webgl.cts.R;
-import android.webkit.WebView;
-import android.webkit.JavascriptInterface;
-import android.webkit.WebViewClient;
-import android.widget.Toast;
-import java.lang.Override;
-import java.io.InputStream;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-
-/**
- * A simple activity for testing WebGL Conformance with WebView.
- */
-public class WebGLActivity extends Activity {
-
-    Semaphore mFinished = new Semaphore(0, false);
-    Semaphore mDestroyed = new Semaphore(0, false);
-    String mWebGlHarnessUrl;
-    WebView mWebView;
-
-    // The following members are synchronized.
-    String mWebGLTestUrl;
-    boolean mPassed = true;
-    StringBuilder mMessage = new StringBuilder("\n");
-
-    @Override
-    public void onCreate(Bundle icicle) {
-        super.onCreate(icicle);
-
-        mWebGlHarnessUrl = "file://" + getCacheDir() + "/harness.html";
-        try {
-            mWebView = new WebView(this);
-        } catch (Exception e) {
-            NullWebViewUtils.determineIfWebViewAvailable(this, e);
-        }
-
-        if (mWebView == null) {
-            return;
-        }
-
-        mWebView.getSettings().setJavaScriptEnabled(true);
-        mWebView.getSettings().setAllowFileAccessFromFileURLs(true);
-        mWebView.getSettings().setMediaPlaybackRequiresUserGesture(false);
-        mWebView.setWebViewClient(new WebViewClient() {
-            @Override
-            public boolean shouldOverrideUrlLoading(WebView webView, String url) {
-                return false;
-            }
-        });
-
-        mWebView.addJavascriptInterface(new Object() {
-            @JavascriptInterface
-            public String getUrlToTest() {
-                synchronized(WebGLActivity.this) {
-                    return mWebGLTestUrl;
-                }
-            }
-
-            @JavascriptInterface
-            public void reportResults(String type, boolean success, String message) {
-                synchronized(WebGLActivity.this) {
-                    mMessage.append((success ? "PASS " : "FAIL ") + message + "\n");
-                    mPassed &= success;
-                }
-            }
-
-            @JavascriptInterface
-            public void notifyFinished() {
-                mFinished.release();
-            }
-
-            @JavascriptInterface
-            public void alert(String string) {
-                Log.i(mWebGLTestUrl, string);
-            }
-        }, "WebGLCallback");
-        setContentView(mWebView);
-    }
-
-    public void navigateToTest(String url) throws Exception {
-        if (!NullWebViewUtils.isWebViewAvailable()) {
-            return;
-        }
-
-        synchronized(WebGLActivity.this) {
-            mWebGLTestUrl = url;
-        }
-
-        // Load harness.html, which will load mWebGLTestUrl in an <iframe>.
-        runOnUiThread(new Runnable() {
-            public void run() {
-                mWebView.loadUrl(mWebGlHarnessUrl);
-            }
-        });
-
-        // Wait on test completion.
-        boolean finished = mFinished.tryAcquire(60, TimeUnit.SECONDS);
-        String message;
-        synchronized(WebGLActivity.this) {
-            message = mMessage.toString();
-        }
-
-        // Destroy the webview and wait for it.
-        runOnUiThread(new Runnable() {
-            public void run() {
-                mWebView.destroy();
-                finish();
-                mDestroyed.release();
-            }
-        });
-        mDestroyed.acquire();
-
-        if (!finished)
-            throw new Exception("\n" + url + "\n Test timed-out after 60 seconds: " + message);
-        if(!mPassed)
-            throw new Exception("\n" + url + "\n Test failed: " + message);
-    }
-}
diff --git a/tests/webgl/src/android/webgl/cts/WebGLConformanceSuite.java b/tests/webgl/src/android/webgl/cts/WebGLConformanceSuite.java
deleted file mode 100644
index 60f663a..0000000
--- a/tests/webgl/src/android/webgl/cts/WebGLConformanceSuite.java
+++ /dev/null
@@ -1,51 +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.webgl.cts;
-
-import android.util.Log;
-import android.webgl.cts.R;
-import android.webgl.WebGLActivity;
-import java.lang.Override;
-import java.io.File;
-import java.io.InputStream;
-
-/**
- * A Singleton class to wrap the WebGL Conformance Test Suite.
- */
-public class WebGLConformanceSuite {
-    private final String TAG = "WebGLConformanceSuite";
-    private static volatile WebGLConformanceSuite mInstance = null;
-
-    private WebGLConformanceSuite(WebGLActivity activity) throws Exception {
-        Log.i(TAG, "Unzipping WebGL Conformance Suite: "
-                + activity.getCacheDir().getPath());
-        InputStream suite = activity.getResources().openRawResource(R.raw.webgl_sdk_tests);
-        ZipUtil.unzipToPath(suite, activity.getCacheDir());
-        InputStream harness = activity.getResources().openRawResource(R.raw.harness);
-        ZipUtil.streamToPath(harness, activity.getCacheDir(), "harness.html");
-    }
-
-    public static WebGLConformanceSuite init(WebGLActivity activity)
-            throws Exception {
-        if (mInstance == null) {
-            synchronized (WebGLConformanceSuite.class) {
-                mInstance = new WebGLConformanceSuite(activity);
-            }
-        }
-        return mInstance;
-    }
-}
diff --git a/tests/webgl/src/android/webgl/cts/WebGLTest.java b/tests/webgl/src/android/webgl/cts/WebGLTest.java
deleted file mode 100644
index d45c190..0000000
--- a/tests/webgl/src/android/webgl/cts/WebGLTest.java
+++ /dev/null
@@ -1,419 +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.webgl.cts;
-
-import android.webgl.WebGLActivity;
-import android.webgl.cts.R;
-import android.test.ActivityInstrumentationTestCase2;
-import java.io.InputStream;
-
-/**
- * A simple wrapper to load each WebGL conformance test in WebView.
- *
- * This test uses {@link android.test.ActivityInstrumentationTestCase2} to instrument the
- * {@link android.webgl.WebGLActivity}.
- */
-public class WebGLTest extends ActivityInstrumentationTestCase2<WebGLActivity> {
-
-    /**
-     * A reference to the activity whose shared preferences are being tested.
-     */
-    private WebGLActivity mActivity;
-    private WebGLConformanceSuite mWebGL_1_0_1;
-
-    public WebGLTest() {
-        super(WebGLActivity.class);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        // Start the activity and get a reference to it.
-        mActivity = getActivity();
-        // Wait for the UI Thread to become idle.
-        getInstrumentation().waitForIdleSync();
-        mWebGL_1_0_1 = WebGLConformanceSuite.init(mActivity);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Scrub the activity so it can be freed. The next time the setUp will create a new activity
-        // rather than reusing the old one.
-        mActivity = null;
-        super.tearDown();
-    }
-
-    protected void doTest(String testPage) throws Exception {
-        mActivity.navigateToTest(testPage);
-    }
-
-    /**
-     * The remainder of this file is generated using this command:
-     * extract_webgl_tests.py tests 1.0.1
-     */
-    public void test_conformance_attribs_gl_enable_vertex_attrib_html() throws Exception { doTest("tests/conformance/attribs/gl-enable-vertex-attrib.html"); }
-    public void test_conformance_attribs_gl_vertex_attrib_zero_issues_html() throws Exception { doTest("tests/conformance/attribs/gl-vertex-attrib-zero-issues.html"); }
-    public void test_conformance_attribs_gl_vertex_attrib_html() throws Exception { doTest("tests/conformance/attribs/gl-vertex-attrib.html"); }
-    public void test_conformance_attribs_gl_vertexattribpointer_offsets_html() throws Exception { doTest("tests/conformance/attribs/gl-vertexattribpointer-offsets.html"); }
-    public void test_conformance_attribs_gl_vertexattribpointer_html() throws Exception { doTest("tests/conformance/attribs/gl-vertexattribpointer.html"); }
-    public void test_conformance_buffers_buffer_bind_test_html() throws Exception { doTest("tests/conformance/buffers/buffer-bind-test.html"); }
-    public void test_conformance_buffers_buffer_data_array_buffer_html() throws Exception { doTest("tests/conformance/buffers/buffer-data-array-buffer.html"); }
-    public void test_conformance_buffers_index_validation_copies_indices_html() throws Exception { doTest("tests/conformance/buffers/index-validation-copies-indices.html"); }
-    public void test_conformance_buffers_index_validation_crash_with_buffer_sub_data_html() throws Exception { doTest("tests/conformance/buffers/index-validation-crash-with-buffer-sub-data.html"); }
-    public void test_conformance_buffers_index_validation_verifies_too_many_indices_html() throws Exception { doTest("tests/conformance/buffers/index-validation-verifies-too-many-indices.html"); }
-    public void test_conformance_buffers_index_validation_with_resized_buffer_html() throws Exception { doTest("tests/conformance/buffers/index-validation-with-resized-buffer.html"); }
-    public void test_conformance_buffers_index_validation_html() throws Exception { doTest("tests/conformance/buffers/index-validation.html"); }
-    public void test_conformance_canvas_buffer_offscreen_test_html() throws Exception { doTest("tests/conformance/canvas/buffer-offscreen-test.html"); }
-    public void test_conformance_canvas_buffer_preserve_test_html() throws Exception { doTest("tests/conformance/canvas/buffer-preserve-test.html"); }
-    public void test_conformance_canvas_canvas_test_html() throws Exception { doTest("tests/conformance/canvas/canvas-test.html"); }
-    public void test_conformance_canvas_canvas_zero_size_html() throws Exception { doTest("tests/conformance/canvas/canvas-zero-size.html"); }
-    public void test_conformance_canvas_drawingbuffer_static_canvas_test_html() throws Exception { doTest("tests/conformance/canvas/drawingbuffer-static-canvas-test.html"); }
-    public void test_conformance_canvas_drawingbuffer_test_html() throws Exception { doTest("tests/conformance/canvas/drawingbuffer-test.html"); }
-    public void test_conformance_canvas_viewport_unchanged_upon_resize_html() throws Exception { doTest("tests/conformance/canvas/viewport-unchanged-upon-resize.html"); }
-    public void test_conformance_context_constants_and_properties_html() throws Exception { doTest("tests/conformance/context/constants-and-properties.html"); }
-    public void test_conformance_context_context_attributes_alpha_depth_stencil_antialias_html() throws Exception { doTest("tests/conformance/context/context-attributes-alpha-depth-stencil-antialias.html"); }
-    public void test_conformance_context_context_lost_restored_html() throws Exception { doTest("tests/conformance/context/context-lost-restored.html"); }
-    public void test_conformance_context_context_lost_html() throws Exception { doTest("tests/conformance/context/context-lost.html"); }
-    public void test_conformance_context_context_type_test_html() throws Exception { doTest("tests/conformance/context/context-type-test.html"); }
-    public void test_conformance_context_incorrect_context_object_behaviour_html() throws Exception { doTest("tests/conformance/context/incorrect-context-object-behaviour.html"); }
-    public void test_conformance_context_methods_html() throws Exception { doTest("tests/conformance/context/methods.html"); }
-    public void test_conformance_context_premultiplyalpha_test_html() throws Exception { doTest("tests/conformance/context/premultiplyalpha-test.html"); }
-    public void test_conformance_context_resource_sharing_test_html() throws Exception { doTest("tests/conformance/context/resource-sharing-test.html"); }
-    public void test_conformance_extensions_oes_standard_derivatives_html() throws Exception { doTest("tests/conformance/extensions/oes-standard-derivatives.html"); }
-    public void test_conformance_extensions_oes_texture_float_with_canvas_html() throws Exception { doTest("tests/conformance/extensions/oes-texture-float-with-canvas.html"); }
-    public void test_conformance_extensions_oes_texture_float_with_image_data_html() throws Exception { doTest("tests/conformance/extensions/oes-texture-float-with-image-data.html"); }
-    public void test_conformance_extensions_oes_texture_float_with_image_html() throws Exception { doTest("tests/conformance/extensions/oes-texture-float-with-image.html"); }
-    public void test_conformance_extensions_oes_texture_float_with_video_html() throws Exception { doTest("tests/conformance/extensions/oes-texture-float-with-video.html"); }
-    public void test_conformance_extensions_oes_texture_float_html() throws Exception { doTest("tests/conformance/extensions/oes-texture-float.html"); }
-    public void test_conformance_extensions_oes_vertex_array_object_html() throws Exception { doTest("tests/conformance/extensions/oes-vertex-array-object.html"); }
-    public void test_conformance_extensions_webgl_debug_renderer_info_html() throws Exception { doTest("tests/conformance/extensions/webgl-debug-renderer-info.html"); }
-    public void test_conformance_extensions_webgl_debug_shaders_html() throws Exception { doTest("tests/conformance/extensions/webgl-debug-shaders.html"); }
-    public void test_conformance_glsl_functions_glsl_function_abs_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-abs.html"); }
-    public void test_conformance_glsl_functions_glsl_function_acos_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-acos.html"); }
-    public void test_conformance_glsl_functions_glsl_function_asin_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-asin.html"); }
-    public void test_conformance_glsl_functions_glsl_function_atan_xy_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-atan-xy.html"); }
-    public void test_conformance_glsl_functions_glsl_function_atan_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-atan.html"); }
-    public void test_conformance_glsl_functions_glsl_function_ceil_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-ceil.html"); }
-    public void test_conformance_glsl_functions_glsl_function_clamp_float_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-clamp-float.html"); }
-    public void test_conformance_glsl_functions_glsl_function_clamp_gentype_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-clamp-gentype.html"); }
-    public void test_conformance_glsl_functions_glsl_function_cos_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-cos.html"); }
-    public void test_conformance_glsl_functions_glsl_function_cross_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-cross.html"); }
-    public void test_conformance_glsl_functions_glsl_function_distance_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-distance.html"); }
-    public void test_conformance_glsl_functions_glsl_function_dot_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-dot.html"); }
-    public void test_conformance_glsl_functions_glsl_function_faceforward_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-faceforward.html"); }
-    public void test_conformance_glsl_functions_glsl_function_floor_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-floor.html"); }
-    public void test_conformance_glsl_functions_glsl_function_fract_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-fract.html"); }
-    public void test_conformance_glsl_functions_glsl_function_length_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-length.html"); }
-    public void test_conformance_glsl_functions_glsl_function_max_float_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-max-float.html"); }
-    public void test_conformance_glsl_functions_glsl_function_max_gentype_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-max-gentype.html"); }
-    public void test_conformance_glsl_functions_glsl_function_min_float_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-min-float.html"); }
-    public void test_conformance_glsl_functions_glsl_function_min_gentype_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-min-gentype.html"); }
-    public void test_conformance_glsl_functions_glsl_function_mix_float_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-mix-float.html"); }
-    public void test_conformance_glsl_functions_glsl_function_mix_gentype_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-mix-gentype.html"); }
-    public void test_conformance_glsl_functions_glsl_function_mod_float_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-mod-float.html"); }
-    public void test_conformance_glsl_functions_glsl_function_mod_gentype_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-mod-gentype.html"); }
-    public void test_conformance_glsl_functions_glsl_function_normalize_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-normalize.html"); }
-    public void test_conformance_glsl_functions_glsl_function_reflect_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-reflect.html"); }
-    public void test_conformance_glsl_functions_glsl_function_sign_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-sign.html"); }
-    public void test_conformance_glsl_functions_glsl_function_sin_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-sin.html"); }
-    public void test_conformance_glsl_functions_glsl_function_smoothstep_float_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-smoothstep-float.html"); }
-    public void test_conformance_glsl_functions_glsl_function_smoothstep_gentype_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-smoothstep-gentype.html"); }
-    public void test_conformance_glsl_functions_glsl_function_step_float_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-step-float.html"); }
-    public void test_conformance_glsl_functions_glsl_function_step_gentype_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function-step-gentype.html"); }
-    public void test_conformance_glsl_functions_glsl_function_html() throws Exception { doTest("tests/conformance/glsl/functions/glsl-function.html"); }
-    public void test_conformance_glsl_implicit_add_int_float_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_int_float.vert.html"); }
-    public void test_conformance_glsl_implicit_add_int_mat2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_int_mat2.vert.html"); }
-    public void test_conformance_glsl_implicit_add_int_mat3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_int_mat3.vert.html"); }
-    public void test_conformance_glsl_implicit_add_int_mat4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_int_mat4.vert.html"); }
-    public void test_conformance_glsl_implicit_add_int_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_int_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_add_int_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_int_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_add_int_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_int_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_add_ivec2_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_ivec2_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_add_ivec3_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_ivec3_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_add_ivec4_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/add_ivec4_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_assign_int_to_float_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/assign_int_to_float.vert.html"); }
-    public void test_conformance_glsl_implicit_assign_ivec2_to_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/assign_ivec2_to_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_assign_ivec3_to_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/assign_ivec3_to_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_assign_ivec4_to_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/assign_ivec4_to_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_construct_struct_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/construct_struct.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_int_float_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_int_float.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_int_mat2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_int_mat2.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_int_mat3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_int_mat3.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_int_mat4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_int_mat4.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_int_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_int_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_int_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_int_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_int_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_int_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_ivec2_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_ivec2_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_ivec3_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_ivec3_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_divide_ivec4_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/divide_ivec4_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_equal_int_float_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/equal_int_float.vert.html"); }
-    public void test_conformance_glsl_implicit_equal_ivec2_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/equal_ivec2_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_equal_ivec3_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/equal_ivec3_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_equal_ivec4_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/equal_ivec4_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_function_int_float_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/function_int_float.vert.html"); }
-    public void test_conformance_glsl_implicit_function_ivec2_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/function_ivec2_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_function_ivec3_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/function_ivec3_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_function_ivec4_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/function_ivec4_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_greater_than_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/greater_than.vert.html"); }
-    public void test_conformance_glsl_implicit_greater_than_equal_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/greater_than_equal.vert.html"); }
-    public void test_conformance_glsl_implicit_less_than_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/less_than.vert.html"); }
-    public void test_conformance_glsl_implicit_less_than_equal_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/less_than_equal.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_int_float_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_int_float.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_int_mat2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_int_mat2.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_int_mat3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_int_mat3.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_int_mat4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_int_mat4.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_int_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_int_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_int_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_int_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_int_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_int_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_ivec2_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_ivec2_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_ivec3_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_ivec3_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_multiply_ivec4_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/multiply_ivec4_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_not_equal_int_float_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/not_equal_int_float.vert.html"); }
-    public void test_conformance_glsl_implicit_not_equal_ivec2_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/not_equal_ivec2_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_not_equal_ivec3_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/not_equal_ivec3_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_not_equal_ivec4_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/not_equal_ivec4_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_int_float_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_int_float.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_int_mat2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_int_mat2.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_int_mat3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_int_mat3.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_int_mat4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_int_mat4.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_int_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_int_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_int_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_int_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_int_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_int_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_ivec2_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_ivec2_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_ivec3_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_ivec3_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_subtract_ivec4_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/subtract_ivec4_vec4.vert.html"); }
-    public void test_conformance_glsl_implicit_ternary_int_float_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/ternary_int_float.vert.html"); }
-    public void test_conformance_glsl_implicit_ternary_ivec2_vec2_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/ternary_ivec2_vec2.vert.html"); }
-    public void test_conformance_glsl_implicit_ternary_ivec3_vec3_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/ternary_ivec3_vec3.vert.html"); }
-    public void test_conformance_glsl_implicit_ternary_ivec4_vec4_vert_html() throws Exception { doTest("tests/conformance/glsl/implicit/ternary_ivec4_vec4.vert.html"); }
-    public void test_conformance_glsl_misc_attrib_location_length_limits_html() throws Exception { doTest("tests/conformance/glsl/misc/attrib-location-length-limits.html"); }
-    public void test_conformance_glsl_misc_embedded_struct_definitions_forbidden_html() throws Exception { doTest("tests/conformance/glsl/misc/embedded-struct-definitions-forbidden.html"); }
-    public void test_conformance_glsl_misc_empty_main_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/empty_main.vert.html"); }
-    public void test_conformance_glsl_misc_gl_position_unset_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/gl_position_unset.vert.html"); }
-    public void test_conformance_glsl_misc_glsl_function_nodes_html() throws Exception { doTest("tests/conformance/glsl/misc/glsl-function-nodes.html"); }
-    public void test_conformance_glsl_misc_glsl_long_variable_names_html() throws Exception { doTest("tests/conformance/glsl/misc/glsl-long-variable-names.html"); }
-    public void test_conformance_glsl_misc_non_ascii_comments_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/non-ascii-comments.vert.html"); }
-    public void test_conformance_glsl_misc_non_ascii_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/non-ascii.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_256_character_identifier_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-256-character-identifier.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_257_character_identifier_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-257-character-identifier.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with__webgl_identifier_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-_webgl-identifier.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_arbitrary_indexing_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-arbitrary-indexing.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_arbitrary_indexing_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-arbitrary-indexing.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_attrib_array_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-attrib-array.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_attrib_struct_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-attrib-struct.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_clipvertex_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-clipvertex.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_default_precision_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-default-precision.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_default_precision_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-default-precision.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_define_line_continuation_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-define-line-continuation.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_dfdx_no_ext_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-dfdx-no-ext.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_dfdx_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-dfdx.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_error_directive_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-error-directive.html"); }
-    public void test_conformance_glsl_misc_shader_with_explicit_int_cast_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-explicit-int-cast.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_float_return_value_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-float-return-value.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_frag_depth_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-frag-depth.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_function_recursion_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-function-recursion.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_glcolor_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-glcolor.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_gles_1_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-gles-1.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_gles_symbol_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-gles-symbol.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_glprojectionmatrix_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-glprojectionmatrix.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_implicit_vec3_to_vec4_cast_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-implicit-vec3-to-vec4-cast.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_include_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-include.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_int_return_value_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-int-return-value.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_invalid_identifier_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-invalid-identifier.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_ivec2_return_value_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-ivec2-return-value.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_ivec3_return_value_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-ivec3-return-value.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_ivec4_return_value_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-ivec4-return-value.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_limited_indexing_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-limited-indexing.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_long_line_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-long-line.html"); }
-    public void test_conformance_glsl_misc_shader_with_non_ascii_error_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-non-ascii-error.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_precision_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-precision.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_quoted_error_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-quoted-error.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_undefined_preprocessor_symbol_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-undefined-preprocessor-symbol.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_uniform_in_loop_condition_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-uniform-in-loop-condition.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_vec2_return_value_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-vec2-return-value.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_vec3_return_value_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-vec3-return-value.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_vec4_return_value_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-vec4-return-value.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_version_100_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-version-100.frag.html"); }
-    public void test_conformance_glsl_misc_shader_with_version_100_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-version-100.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_version_120_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-version-120.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_version_130_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-version-130.vert.html"); }
-    public void test_conformance_glsl_misc_shader_with_webgl_identifier_vert_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-with-webgl-identifier.vert.html"); }
-    public void test_conformance_glsl_misc_shader_without_precision_frag_html() throws Exception { doTest("tests/conformance/glsl/misc/shader-without-precision.frag.html"); }
-    public void test_conformance_glsl_misc_shared_html() throws Exception { doTest("tests/conformance/glsl/misc/shared.html"); }
-    public void test_conformance_glsl_misc_struct_nesting_exceeds_maximum_html() throws Exception { doTest("tests/conformance/glsl/misc/struct-nesting-exceeds-maximum.html"); }
-    public void test_conformance_glsl_misc_struct_nesting_under_maximum_html() throws Exception { doTest("tests/conformance/glsl/misc/struct-nesting-under-maximum.html"); }
-    public void test_conformance_glsl_misc_uniform_location_length_limits_html() throws Exception { doTest("tests/conformance/glsl/misc/uniform-location-length-limits.html"); }
-    public void test_conformance_glsl_reserved__webgl_field_vert_html() throws Exception { doTest("tests/conformance/glsl/reserved/_webgl_field.vert.html"); }
-    public void test_conformance_glsl_reserved__webgl_function_vert_html() throws Exception { doTest("tests/conformance/glsl/reserved/_webgl_function.vert.html"); }
-    public void test_conformance_glsl_reserved__webgl_struct_vert_html() throws Exception { doTest("tests/conformance/glsl/reserved/_webgl_struct.vert.html"); }
-    public void test_conformance_glsl_reserved__webgl_variable_vert_html() throws Exception { doTest("tests/conformance/glsl/reserved/_webgl_variable.vert.html"); }
-    public void test_conformance_glsl_reserved_webgl_field_vert_html() throws Exception { doTest("tests/conformance/glsl/reserved/webgl_field.vert.html"); }
-    public void test_conformance_glsl_reserved_webgl_function_vert_html() throws Exception { doTest("tests/conformance/glsl/reserved/webgl_function.vert.html"); }
-    public void test_conformance_glsl_reserved_webgl_struct_vert_html() throws Exception { doTest("tests/conformance/glsl/reserved/webgl_struct.vert.html"); }
-    public void test_conformance_glsl_reserved_webgl_variable_vert_html() throws Exception { doTest("tests/conformance/glsl/reserved/webgl_variable.vert.html"); }
-    public void test_conformance_glsl_variables_gl_fragcoord_html() throws Exception { doTest("tests/conformance/glsl/variables/gl-fragcoord.html"); }
-    public void test_conformance_glsl_variables_gl_frontfacing_html() throws Exception { doTest("tests/conformance/glsl/variables/gl-frontfacing.html"); }
-    public void test_conformance_glsl_variables_gl_pointcoord_html() throws Exception { doTest("tests/conformance/glsl/variables/gl-pointcoord.html"); }
-    public void test_conformance_limits_gl_max_texture_dimensions_html() throws Exception { doTest("tests/conformance/limits/gl-max-texture-dimensions.html"); }
-    public void test_conformance_limits_gl_min_attribs_html() throws Exception { doTest("tests/conformance/limits/gl-min-attribs.html"); }
-    public void test_conformance_limits_gl_min_textures_html() throws Exception { doTest("tests/conformance/limits/gl-min-textures.html"); }
-    public void test_conformance_limits_gl_min_uniforms_html() throws Exception { doTest("tests/conformance/limits/gl-min-uniforms.html"); }
-    public void test_conformance_misc_bad_arguments_test_html() throws Exception { doTest("tests/conformance/misc/bad-arguments-test.html"); }
-    public void test_conformance_misc_error_reporting_html() throws Exception { doTest("tests/conformance/misc/error-reporting.html"); }
-    public void test_conformance_misc_functions_returning_strings_html() throws Exception { doTest("tests/conformance/misc/functions-returning-strings.html"); }
-    public void test_conformance_misc_instanceof_test_html() throws Exception { doTest("tests/conformance/misc/instanceof-test.html"); }
-    public void test_conformance_misc_invalid_passed_params_html() throws Exception { doTest("tests/conformance/misc/invalid-passed-params.html"); }
-    public void test_conformance_misc_is_object_html() throws Exception { doTest("tests/conformance/misc/is-object.html"); }
-    public void test_conformance_misc_null_object_behaviour_html() throws Exception { doTest("tests/conformance/misc/null-object-behaviour.html"); }
-    public void test_conformance_misc_object_deletion_behaviour_html() throws Exception { doTest("tests/conformance/misc/object-deletion-behaviour.html"); }
-    public void test_conformance_misc_shader_precision_format_html() throws Exception { doTest("tests/conformance/misc/shader-precision-format.html"); }
-    public void test_conformance_misc_type_conversion_test_html() throws Exception { doTest("tests/conformance/misc/type-conversion-test.html"); }
-    public void test_conformance_misc_uninitialized_test_html() throws Exception { doTest("tests/conformance/misc/uninitialized-test.html"); }
-    public void test_conformance_misc_webgl_specific_html() throws Exception { doTest("tests/conformance/misc/webgl-specific.html"); }
-    public void test_conformance_more_conformance_constants_html() throws Exception { doTest("tests/conformance/more/conformance/constants.html"); }
-    public void test_conformance_more_conformance_getContext_html() throws Exception { doTest("tests/conformance/more/conformance/getContext.html"); }
-    public void test_conformance_more_conformance_methods_html() throws Exception { doTest("tests/conformance/more/conformance/methods.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_A_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-A.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_B1_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-B1.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_B2_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-B2.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_B3_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-B3.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_B4_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-B4.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_C_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-C.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_D_G_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-D_G.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_G_I_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-G_I.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_L_S_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-L_S.html"); }
-    public void test_conformance_more_conformance_quickCheckAPI_S_V_html() throws Exception { doTest("tests/conformance/more/conformance/quickCheckAPI-S_V.html"); }
-    public void test_conformance_more_conformance_webGLArrays_html() throws Exception { doTest("tests/conformance/more/conformance/webGLArrays.html"); }
-    public void test_conformance_more_functions_bindBuffer_html() throws Exception { doTest("tests/conformance/more/functions/bindBuffer.html"); }
-    public void test_conformance_more_functions_bindBufferBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/bindBufferBadArgs.html"); }
-    public void test_conformance_more_functions_bindFramebufferLeaveNonZero_html() throws Exception { doTest("tests/conformance/more/functions/bindFramebufferLeaveNonZero.html"); }
-    public void test_conformance_more_functions_bufferData_html() throws Exception { doTest("tests/conformance/more/functions/bufferData.html"); }
-    public void test_conformance_more_functions_bufferDataBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/bufferDataBadArgs.html"); }
-    public void test_conformance_more_functions_bufferSubData_html() throws Exception { doTest("tests/conformance/more/functions/bufferSubData.html"); }
-    public void test_conformance_more_functions_bufferSubDataBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/bufferSubDataBadArgs.html"); }
-    public void test_conformance_more_functions_copyTexImage2D_html() throws Exception { doTest("tests/conformance/more/functions/copyTexImage2D.html"); }
-    public void test_conformance_more_functions_copyTexImage2DBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/copyTexImage2DBadArgs.html"); }
-    public void test_conformance_more_functions_copyTexSubImage2D_html() throws Exception { doTest("tests/conformance/more/functions/copyTexSubImage2D.html"); }
-    public void test_conformance_more_functions_copyTexSubImage2DBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/copyTexSubImage2DBadArgs.html"); }
-    public void test_conformance_more_functions_deleteBufferBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/deleteBufferBadArgs.html"); }
-    public void test_conformance_more_functions_drawArrays_html() throws Exception { doTest("tests/conformance/more/functions/drawArrays.html"); }
-    public void test_conformance_more_functions_drawArraysOutOfBounds_html() throws Exception { doTest("tests/conformance/more/functions/drawArraysOutOfBounds.html"); }
-    public void test_conformance_more_functions_drawElements_html() throws Exception { doTest("tests/conformance/more/functions/drawElements.html"); }
-    public void test_conformance_more_functions_drawElementsBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/drawElementsBadArgs.html"); }
-    public void test_conformance_more_functions_isTests_html() throws Exception { doTest("tests/conformance/more/functions/isTests.html"); }
-    public void test_conformance_more_functions_readPixels_html() throws Exception { doTest("tests/conformance/more/functions/readPixels.html"); }
-    public void test_conformance_more_functions_readPixelsBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/readPixelsBadArgs.html"); }
-    public void test_conformance_more_functions_texImage2D_html() throws Exception { doTest("tests/conformance/more/functions/texImage2D.html"); }
-    public void test_conformance_more_functions_texImage2DBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/texImage2DBadArgs.html"); }
-    public void test_conformance_more_functions_texImage2DHTML_html() throws Exception { doTest("tests/conformance/more/functions/texImage2DHTML.html"); }
-    public void test_conformance_more_functions_texImage2DHTMLBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/texImage2DHTMLBadArgs.html"); }
-    public void test_conformance_more_functions_texSubImage2D_html() throws Exception { doTest("tests/conformance/more/functions/texSubImage2D.html"); }
-    public void test_conformance_more_functions_texSubImage2DBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/texSubImage2DBadArgs.html"); }
-    public void test_conformance_more_functions_texSubImage2DHTML_html() throws Exception { doTest("tests/conformance/more/functions/texSubImage2DHTML.html"); }
-    public void test_conformance_more_functions_texSubImage2DHTMLBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/texSubImage2DHTMLBadArgs.html"); }
-    public void test_conformance_more_functions_uniformMatrix_html() throws Exception { doTest("tests/conformance/more/functions/uniformMatrix.html"); }
-    public void test_conformance_more_functions_uniformMatrixBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/uniformMatrixBadArgs.html"); }
-    public void test_conformance_more_functions_uniformf_html() throws Exception { doTest("tests/conformance/more/functions/uniformf.html"); }
-    public void test_conformance_more_functions_uniformfArrayLen1_html() throws Exception { doTest("tests/conformance/more/functions/uniformfArrayLen1.html"); }
-    public void test_conformance_more_functions_uniformfBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/uniformfBadArgs.html"); }
-    public void test_conformance_more_functions_uniformi_html() throws Exception { doTest("tests/conformance/more/functions/uniformi.html"); }
-    public void test_conformance_more_functions_uniformiBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/uniformiBadArgs.html"); }
-    public void test_conformance_more_functions_vertexAttrib_html() throws Exception { doTest("tests/conformance/more/functions/vertexAttrib.html"); }
-    public void test_conformance_more_functions_vertexAttribBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/vertexAttribBadArgs.html"); }
-    public void test_conformance_more_functions_vertexAttribPointer_html() throws Exception { doTest("tests/conformance/more/functions/vertexAttribPointer.html"); }
-    public void test_conformance_more_functions_vertexAttribPointerBadArgs_html() throws Exception { doTest("tests/conformance/more/functions/vertexAttribPointerBadArgs.html"); }
-    public void test_conformance_more_glsl_arrayOutOfBounds_html() throws Exception { doTest("tests/conformance/more/glsl/arrayOutOfBounds.html"); }
-    public void test_conformance_more_glsl_uniformOutOfBounds_html() throws Exception { doTest("tests/conformance/more/glsl/uniformOutOfBounds.html"); }
-    public void test_conformance_programs_get_active_test_html() throws Exception { doTest("tests/conformance/programs/get-active-test.html"); }
-    public void test_conformance_programs_gl_bind_attrib_location_test_html() throws Exception { doTest("tests/conformance/programs/gl-bind-attrib-location-test.html"); }
-    public void test_conformance_programs_gl_get_active_attribute_html() throws Exception { doTest("tests/conformance/programs/gl-get-active-attribute.html"); }
-    public void test_conformance_programs_gl_get_active_uniform_html() throws Exception { doTest("tests/conformance/programs/gl-get-active-uniform.html"); }
-    public void test_conformance_programs_gl_getshadersource_html() throws Exception { doTest("tests/conformance/programs/gl-getshadersource.html"); }
-    public void test_conformance_programs_gl_shader_test_html() throws Exception { doTest("tests/conformance/programs/gl-shader-test.html"); }
-    public void test_conformance_programs_invalid_UTF_16_html() throws Exception { doTest("tests/conformance/programs/invalid-UTF-16.html"); }
-    public void test_conformance_programs_program_test_html() throws Exception { doTest("tests/conformance/programs/program-test.html"); }
-    public void test_conformance_reading_read_pixels_pack_alignment_html() throws Exception { doTest("tests/conformance/reading/read-pixels-pack-alignment.html"); }
-    public void test_conformance_reading_read_pixels_test_html() throws Exception { doTest("tests/conformance/reading/read-pixels-test.html"); }
-    public void test_conformance_renderbuffers_framebuffer_object_attachment_html() throws Exception { doTest("tests/conformance/renderbuffers/framebuffer-object-attachment.html"); }
-    public void test_conformance_renderbuffers_framebuffer_test_html() throws Exception { doTest("tests/conformance/renderbuffers/framebuffer-test.html"); }
-    public void test_conformance_renderbuffers_renderbuffer_initialization_html() throws Exception { doTest("tests/conformance/renderbuffers/renderbuffer-initialization.html"); }
-    public void test_conformance_rendering_draw_arrays_out_of_bounds_html() throws Exception { doTest("tests/conformance/rendering/draw-arrays-out-of-bounds.html"); }
-    public void test_conformance_rendering_draw_elements_out_of_bounds_html() throws Exception { doTest("tests/conformance/rendering/draw-elements-out-of-bounds.html"); }
-    public void test_conformance_rendering_gl_clear_html() throws Exception { doTest("tests/conformance/rendering/gl-clear.html"); }
-    public void test_conformance_rendering_gl_drawelements_html() throws Exception { doTest("tests/conformance/rendering/gl-drawelements.html"); }
-    public void test_conformance_rendering_gl_scissor_test_html() throws Exception { doTest("tests/conformance/rendering/gl-scissor-test.html"); }
-    public void test_conformance_rendering_line_loop_tri_fan_html() throws Exception { doTest("tests/conformance/rendering/line-loop-tri-fan.html"); }
-    public void test_conformance_rendering_more_than_65536_indices_html() throws Exception { doTest("tests/conformance/rendering/more-than-65536-indices.html"); }
-    public void test_conformance_rendering_multisample_corruption_html() throws Exception { doTest("tests/conformance/rendering/multisample-corruption.html"); }
-    public void test_conformance_rendering_point_size_html() throws Exception { doTest("tests/conformance/rendering/point-size.html"); }
-    public void test_conformance_rendering_triangle_html() throws Exception { doTest("tests/conformance/rendering/triangle.html"); }
-    public void test_conformance_state_gl_enable_enum_test_html() throws Exception { doTest("tests/conformance/state/gl-enable-enum-test.html"); }
-    public void test_conformance_state_gl_enum_tests_html() throws Exception { doTest("tests/conformance/state/gl-enum-tests.html"); }
-    public void test_conformance_state_gl_get_calls_html() throws Exception { doTest("tests/conformance/state/gl-get-calls.html"); }
-    public void test_conformance_state_gl_geterror_html() throws Exception { doTest("tests/conformance/state/gl-geterror.html"); }
-    public void test_conformance_state_gl_getstring_html() throws Exception { doTest("tests/conformance/state/gl-getstring.html"); }
-    public void test_conformance_state_gl_object_get_calls_html() throws Exception { doTest("tests/conformance/state/gl-object-get-calls.html"); }
-    public void test_conformance_textures_compressed_tex_image_html() throws Exception { doTest("tests/conformance/textures/compressed-tex-image.html"); }
-    public void test_conformance_textures_copy_tex_image_and_sub_image_2d_html() throws Exception { doTest("tests/conformance/textures/copy-tex-image-and-sub-image-2d.html"); }
-    public void test_conformance_textures_gl_pixelstorei_html() throws Exception { doTest("tests/conformance/textures/gl-pixelstorei.html"); }
-    public void test_conformance_textures_gl_teximage_html() throws Exception { doTest("tests/conformance/textures/gl-teximage.html"); }
-    public void test_conformance_textures_origin_clean_conformance_html() throws Exception { doTest("tests/conformance/textures/origin-clean-conformance.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_array_buffer_view_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-array-buffer-view.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_canvas_rgb565_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-canvas-rgb565.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_canvas_rgba4444_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-canvas-rgba4444.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_canvas_rgba5551_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-canvas-rgba5551.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_canvas_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-canvas.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_image_data_rgb565_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-image-data-rgb565.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_image_data_rgba4444_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-image-data-rgba4444.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_image_data_rgba5551_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-image-data-rgba5551.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_image_data_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-image-data.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_image_rgb565_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-image-rgb565.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_image_rgba4444_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-image-rgba4444.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_image_rgba5551_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-image-rgba5551.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_image_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-image.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_video_rgb565_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-video-rgb565.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_video_rgba4444_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-video-rgba4444.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_video_rgba5551_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-video-rgba5551.html"); }
-    public void test_conformance_textures_tex_image_and_sub_image_2d_with_video_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-sub-image-2d-with-video.html"); }
-    public void test_conformance_textures_tex_image_and_uniform_binding_bugs_html() throws Exception { doTest("tests/conformance/textures/tex-image-and-uniform-binding-bugs.html"); }
-    public void test_conformance_textures_tex_image_with_format_and_type_html() throws Exception { doTest("tests/conformance/textures/tex-image-with-format-and-type.html"); }
-    public void test_conformance_textures_tex_image_with_invalid_data_html() throws Exception { doTest("tests/conformance/textures/tex-image-with-invalid-data.html"); }
-    public void test_conformance_textures_tex_input_validation_html() throws Exception { doTest("tests/conformance/textures/tex-input-validation.html"); }
-    public void test_conformance_textures_tex_sub_image_2d_bad_args_html() throws Exception { doTest("tests/conformance/textures/tex-sub-image-2d-bad-args.html"); }
-    public void test_conformance_textures_tex_sub_image_2d_html() throws Exception { doTest("tests/conformance/textures/tex-sub-image-2d.html"); }
-    public void test_conformance_textures_texparameter_test_html() throws Exception { doTest("tests/conformance/textures/texparameter-test.html"); }
-    public void test_conformance_textures_texture_active_bind_2_html() throws Exception { doTest("tests/conformance/textures/texture-active-bind-2.html"); }
-    public void test_conformance_textures_texture_active_bind_html() throws Exception { doTest("tests/conformance/textures/texture-active-bind.html"); }
-    public void test_conformance_textures_texture_complete_html() throws Exception { doTest("tests/conformance/textures/texture-complete.html"); }
-    public void test_conformance_textures_texture_mips_html() throws Exception { doTest("tests/conformance/textures/texture-mips.html"); }
-    public void test_conformance_textures_texture_npot_video_html() throws Exception { doTest("tests/conformance/textures/texture-npot-video.html"); }
-    public void test_conformance_textures_texture_npot_html() throws Exception { doTest("tests/conformance/textures/texture-npot.html"); }
-    public void test_conformance_textures_texture_size_cube_maps_html() throws Exception { doTest("tests/conformance/textures/texture-size-cube-maps.html"); }
-    public void test_conformance_textures_texture_size_html() throws Exception { doTest("tests/conformance/textures/texture-size.html"); }
-    public void test_conformance_textures_texture_transparent_pixels_initialized_html() throws Exception { doTest("tests/conformance/textures/texture-transparent-pixels-initialized.html"); }
-    public void test_conformance_typedarrays_array_buffer_crash_html() throws Exception { doTest("tests/conformance/typedarrays/array-buffer-crash.html"); }
-    public void test_conformance_typedarrays_array_buffer_view_crash_html() throws Exception { doTest("tests/conformance/typedarrays/array-buffer-view-crash.html"); }
-    public void test_conformance_typedarrays_array_unit_tests_html() throws Exception { doTest("tests/conformance/typedarrays/array-unit-tests.html"); }
-    public void test_conformance_typedarrays_data_view_crash_html() throws Exception { doTest("tests/conformance/typedarrays/data-view-crash.html"); }
-    public void test_conformance_typedarrays_data_view_test_html() throws Exception { doTest("tests/conformance/typedarrays/data-view-test.html"); }
-    public void test_conformance_uniforms_gl_uniform_arrays_html() throws Exception { doTest("tests/conformance/uniforms/gl-uniform-arrays.html"); }
-    public void test_conformance_uniforms_gl_uniform_bool_html() throws Exception { doTest("tests/conformance/uniforms/gl-uniform-bool.html"); }
-    public void test_conformance_uniforms_gl_uniformmatrix4fv_html() throws Exception { doTest("tests/conformance/uniforms/gl-uniformmatrix4fv.html"); }
-    public void test_conformance_uniforms_gl_unknown_uniform_html() throws Exception { doTest("tests/conformance/uniforms/gl-unknown-uniform.html"); }
-    public void test_conformance_uniforms_null_uniform_location_html() throws Exception { doTest("tests/conformance/uniforms/null-uniform-location.html"); }
-    public void test_conformance_uniforms_uniform_location_html() throws Exception { doTest("tests/conformance/uniforms/uniform-location.html"); }
-    public void test_conformance_uniforms_uniform_samplers_test_html() throws Exception { doTest("tests/conformance/uniforms/uniform-samplers-test.html"); }
-}
diff --git a/tests/webgl/src/android/webgl/cts/ZipUtil.java b/tests/webgl/src/android/webgl/cts/ZipUtil.java
deleted file mode 100644
index 4b28e63..0000000
--- a/tests/webgl/src/android/webgl/cts/ZipUtil.java
+++ /dev/null
@@ -1,117 +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.webgl.cts;
-
-import android.util.Log;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.String;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-
-/**
- * Some boilerplate code to unzip files.
- */
-public class ZipUtil {
-    private final static String TAG = "ZipUtil";
-
-    /**
-     * Stream to a file.
-     */
-    public static void streamToPath(InputStream is,
-                                  File directory,
-                                  String name) throws Exception {
-        File file = new File(directory, name);
-        streamToPath(is, file);
-    }
-
-    public static void streamToPath(InputStream is,
-                                  File file) throws Exception {
-        Log.i(TAG, "Streaming to path " + file.getPath());
-        OutputStream os = null;
-        os = new FileOutputStream(file);
-        int count = -1;
-        byte[] buffer = new byte[10 * 1024];
-        while ((count = is.read(buffer)) != -1) {
-            os.write(buffer, 0, count);
-        }
-        os.close();
-    }
-
-    /**
-     * Unzip to a directory.
-     */
-    public static void unzipToPath(InputStream is,
-                                   File filePath) throws Exception {
-        ZipInputStream zis = new ZipInputStream(is);
-        unzipToPath(zis, filePath.getPath());
-    }
-
-    public static void unzipToPath(ZipInputStream zis,
-                                   String path) throws Exception {
-        Log.i(TAG, "Unzipping to path " + path);
-        byte[] buffer = new byte[10 * 1024];
-        ZipEntry entry;
-        while ((entry = zis.getNextEntry()) != null) {
-            File entryFile = new File(path, entry.getName());
-            if (entry.isDirectory()) {
-                if (!entryFile.exists()) {
-                   entryFile.mkdirs();
-                }
-                continue;
-            }
-            if (entryFile.getParentFile() != null &&
-                    !entryFile.getParentFile().exists()) {
-                entryFile.getParentFile().mkdirs();
-            }
-            if (!entryFile.exists()) {
-                entryFile.createNewFile();
-                entryFile.setReadable(true);
-                entryFile.setExecutable(true);
-            }
-            streamToPath(zis, entryFile);
-        }
-        zis.close();
-    }
-
-    /**
-     * Cleanup a directory.
-     */
-    static public boolean deleteDirectory(String directoryPath) {
-        File path = new File(directoryPath);
-        return deleteDirectory(path);
-    }
-
-    static public boolean deleteDirectory(File path) {
-        if (path.exists()) {
-            File[] files = path.listFiles();
-            for(int i = 0; i < files.length; i++) {
-                if(files[i].isDirectory()) {
-                    deleteDirectory(files[i]);
-                } else {
-                    files[i].delete();
-                }
-            }
-            return path.delete();
-        }
-        return false;
-    }
-}
diff --git a/tools/Android.mk b/tools/Android.mk
index 0a05aed..8cb90db 100644
--- a/tools/Android.mk
+++ b/tools/Android.mk
@@ -12,4 +12,32 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+# Build the CTS harness
+
+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
+PRECONDITIONS_APK := $(CTS_TESTCASES_OUT)/CtsPreconditionsApp.apk
+
+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): $(JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(ADDITIONAL_TF_JARS) $(PRECONDITIONS_APK) | $(ACP) $(HOST_OUT_EXECUTABLES)/adb
+	mkdir -p $(PRIVATE_TESTS_DIR)
+	mkdir -p $(PRIVATE_PLANS_DIR)
+	mkdir -p $(PRIVATE_TOOLS_DIR)
+	$(ACP) -fp $(JUNIT_HOST_JAR) $(HOSTTESTLIB_JAR) $(TF_JAR) $(CTS_TF_JAR) $(CTS_TF_EXEC_PATH) $(ADDITIONAL_TF_JARS) $(PRIVATE_TOOLS_DIR)
+
+.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))
+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 2a62aa0..73cea67 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
@@ -24,6 +24,8 @@
 /** Representation of a class in the API with constructors and methods. */
 class ApiClass implements Comparable<ApiClass>, HasCoverage {
 
+    private static final String VOID = "void";
+
     private final String mName;
 
     private final boolean mDeprecated;
@@ -34,10 +36,25 @@
 
     private final List<ApiMethod> mApiMethods = new ArrayList<ApiMethod>();
 
-    ApiClass(String name, boolean deprecated, boolean classAbstract) {
+    private final String mSuperClassName;
+
+    private ApiClass mSuperClass;
+
+    /**
+     * @param name The name of the class
+     * @param deprecated true iff the class is marked as deprecated
+     * @param classAbstract true iff the class is abstract
+     * @param superClassName The fully qualified name of the super class
+     */
+    ApiClass(
+            String name,
+            boolean deprecated,
+            boolean classAbstract,
+            String superClassName) {
         mName = name;
         mDeprecated = deprecated;
         mAbstract = classAbstract;
+        mSuperClassName = superClassName;
     }
 
     @Override
@@ -54,22 +71,20 @@
         return mDeprecated;
     }
 
+    public String getSuperClassName() {
+        return mSuperClassName;
+    }
+
     public boolean isAbstract() {
         return mAbstract;
     }
 
+    public void setSuperClass(ApiClass superClass) { mSuperClass = superClass; }
+
     public void addConstructor(ApiConstructor constructor) {
         mApiConstructors.add(constructor);
     }
 
-    public ApiConstructor getConstructor(List<String> parameterTypes) {
-        for (ApiConstructor constructor : mApiConstructors) {
-            if (parameterTypes.equals(constructor.getParameterTypes())) {
-                return constructor;
-            }
-        }
-        return null;
-    }
 
     public Collection<ApiConstructor> getConstructors() {
         return Collections.unmodifiableList(mApiConstructors);
@@ -79,15 +94,29 @@
         mApiMethods.add(method);
     }
 
-    public ApiMethod getMethod(String name, List<String> parameterTypes, String returnType) {
-        for (ApiMethod method : mApiMethods) {
-            if (name.equals(method.getName())
-                    && parameterTypes.equals(method.getParameterTypes())
-                    && returnType.equals(method.getReturnType())) {
-                return method;
-            }
+    /** Look for a matching constructor and mark it as covered */
+    public void markConstructorCovered(List<String> parameterTypes) {
+        if (mSuperClass != null) {
+            // Mark matching constructors in the superclass
+            mSuperClass.markConstructorCovered(parameterTypes);
         }
-        return null;
+        ApiConstructor apiConstructor = getConstructor(parameterTypes);
+        if (apiConstructor != null) {
+            apiConstructor.setCovered(true);
+        }
+
+    }
+
+    /** Look for a matching method and if found and mark it as covered */
+    public void markMethodCovered(String name, List<String> parameterTypes, String returnType) {
+        if (mSuperClass != null) {
+            // Mark matching methods in the super class
+            mSuperClass.markMethodCovered(name, parameterTypes, returnType);
+        }
+        ApiMethod apiMethod = getMethod(name, parameterTypes, returnType);
+        if (apiMethod != null) {
+            apiMethod.setCovered(true);
+        }
     }
 
     public Collection<ApiMethod> getMethods() {
@@ -121,4 +150,94 @@
             return (float) getNumCoveredMethods() / getTotalMethods() * 100;
         }
     }
+
+    @Override
+    public int getMemberSize() {
+        return getTotalMethods();
+    }
+
+    private ApiMethod getMethod(String name, List<String> parameterTypes, String returnType) {
+        for (ApiMethod method : mApiMethods) {
+            boolean methodNameMatch = name.equals(method.getName());
+            boolean parameterTypeMatch =
+                    compareParameterTypes(method.getParameterTypes(), parameterTypes);
+            boolean returnTypeMatch = compareType(method.getReturnType(), returnType);
+            if (methodNameMatch && parameterTypeMatch && returnTypeMatch) {
+                return method;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * The method compares two lists of parameters. If the {@code apiParameterTypeList} contains
+     * generic types, test parameter types are ignored.
+     *
+     * @param apiParameterTypeList The list of parameter types from the API
+     * @param testParameterTypeList The list of parameter types used in a test
+     * @return true iff the list of types are the same.
+     */
+    private static boolean compareParameterTypes(
+            List<String> apiParameterTypeList, List<String> testParameterTypeList) {
+        if (apiParameterTypeList.equals(testParameterTypeList)) {
+            return true;
+        }
+        if (apiParameterTypeList.size() != testParameterTypeList.size()) {
+            return false;
+        }
+
+        for (int i = 0; i < apiParameterTypeList.size(); i++) {
+            String apiParameterType = apiParameterTypeList.get(i);
+            String testParameterType = testParameterTypeList.get(i);
+            if (!compareType(apiParameterType, testParameterType)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Compare class types.
+     * @param apiType The type as reported by the api
+     * @param testType The type as found used in a test
+     * @return true iff the strings are equal,
+     * or the apiType is generic and the test type is not void
+     */
+    private static boolean compareType(String apiType, String testType) {
+        return apiType.equals(testType) ||
+                isGenericType(apiType) && !testType.equals(VOID) ||
+                isGenericArrayType(apiType) && isArrayType(testType) ;
+    }
+
+    /**
+     * @return true iff the given parameterType is a generic type.
+     */
+    private static boolean isGenericType(String type) {
+        return type.length() == 1 &&
+                type.charAt(0) >= 'A' &&
+                type.charAt(0) <= 'Z';
+    }
+
+    /**
+     * @return true iff {@code type} ends with an [].
+     */
+    private static boolean isArrayType(String type) {
+        return type.endsWith("[]");
+    }
+
+    /**
+     * @return true iff the given parameterType is an array of generic type.
+     */
+    private static boolean isGenericArrayType(String type) {
+        return type.length() == 3 && isGenericType(type.substring(0, 1)) && isArrayType(type);
+    }
+
+    private ApiConstructor getConstructor(List<String> parameterTypes) {
+        for (ApiConstructor constructor : mApiConstructors) {
+            if (compareParameterTypes(constructor.getParameterTypes(), parameterTypes)) {
+                return constructor;
+            }
+        }
+        return null;
+    }
 }
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiCoverage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiCoverage.java
index adf2ea9..953aab3 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiCoverage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiCoverage.java
@@ -39,10 +39,11 @@
         return Collections.unmodifiableCollection(mPackages.values());
     }
 
-    public void removeEmptyAbstractClasses() {
+    /** Iterate through all packages and update all classes to include its superclass */
+    public void resolveSuperClasses() {
         for (Map.Entry<String, ApiPackage> entry : mPackages.entrySet()) {
             ApiPackage pkg = entry.getValue();
-            pkg.removeEmptyAbstractClasses();
+            pkg.resolveSuperClasses(mPackages);
         }
     }
 }
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiMethod.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiMethod.java
index 053cd12..582c2b6 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiMethod.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiMethod.java
@@ -29,15 +29,35 @@
 
     private final String mReturnType;
 
-    private boolean mDeprecated;
+    private final boolean mDeprecated;
+
+    private final String mVisibility;
+
+    private final boolean mStaticMethod;
+
+    private final boolean mFinalMethod;
+
+    private final boolean mAbstractMethod;
 
     private boolean mIsCovered;
 
-    ApiMethod(String name, List<String> parameterTypes, String returnType, boolean deprecated) {
+    ApiMethod(
+            String name,
+            List<String> parameterTypes,
+            String returnType,
+            boolean deprecated,
+            String visibility,
+            boolean staticMethod,
+            boolean finalMethod,
+            boolean abstractMethod) {
         mName = name;
         mParameterTypes = new ArrayList<String>(parameterTypes);
         mReturnType = returnType;
         mDeprecated = deprecated;
+        mVisibility = visibility;
+        mStaticMethod = staticMethod;
+        mFinalMethod = finalMethod;
+        mAbstractMethod = abstractMethod;
     }
 
     @Override
@@ -65,6 +85,14 @@
         return mIsCovered;
     }
 
+    public String getVisibility() { return mVisibility; }
+
+    public boolean isAbstractMethod() { return mAbstractMethod; }
+
+    public boolean isStaticMethod() { return mStaticMethod; }
+
+    public boolean isFinalMethod() { return mFinalMethod; }
+
     public void setCovered(boolean covered) {
         mIsCovered = covered;
     }
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
index c83256c..7be7e3c 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/ApiPackage.java
@@ -72,14 +72,31 @@
         return (float) getNumCoveredMethods() / getTotalMethods() * 100;
     }
 
-    public void removeEmptyAbstractClasses() {
+    @Override
+    public int getMemberSize() {
+        return getTotalMethods();
+    }
+
+    /** Iterate through all classes and add superclass. */
+    public void resolveSuperClasses(Map<String, ApiPackage> packageMap) {
         Iterator<Entry<String, ApiClass>> it = mApiClassMap.entrySet().iterator();
         while (it.hasNext()) {
             Map.Entry<String, ApiClass> entry = it.next();
-            ApiClass cls = entry.getValue();
-            if (cls.isAbstract() && (cls.getTotalMethods() == 0)) {
-                // this is essentially interface
-                it.remove();
+            ApiClass apiClass = entry.getValue();
+            if (apiClass.getSuperClassName() != null) {
+                String superClassName = apiClass.getSuperClassName();
+                // Split the fully qualified class name into package and class name.
+                String packageName = superClassName.substring(0, superClassName.lastIndexOf('.'));
+                String className = superClassName.substring(
+                        superClassName.lastIndexOf('.') + 1, superClassName.length());
+                if (packageMap.containsKey(packageName)) {
+                    ApiPackage apiPackage = packageMap.get(packageName);
+                    ApiClass superClass = apiPackage.getClass(className);
+                    if (superClass != null) {
+                        // Add the super class
+                        apiClass.setSuperClass(superClass);
+                    }
+                }
             }
         }
     }
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
index d596cba..caea3d6 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CtsApiCoverage.java
@@ -22,10 +22,12 @@
 import org.xml.sax.helpers.XMLReaderFactory;
 
 import java.io.File;
+import java.io.FilenameFilter;
 import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -37,6 +39,13 @@
  */
 public class CtsApiCoverage {
 
+    private static final FilenameFilter SUPPORTED_FILE_NAME_FILTER = new FilenameFilter() {
+        public boolean accept(File dir, String name) {
+            String fileName = name.toLowerCase();
+            return fileName.endsWith(".apk") || fileName.endsWith(".jar");
+        }
+    };
+
     private static final int FORMAT_TXT = 0;
 
     private static final int FORMAT_XML = 1;
@@ -71,8 +80,7 @@
         int format = FORMAT_TXT;
         String dexDeps = "dexDeps";
         String apiXmlPath = "";
-        // By default only care about packages starting with "android"
-        String packageFilter = "android";
+        PackageFilter packageFilter = new PackageFilter();
         String reportTitle = "CTS API Coverage";
 
         for (int i = 0; i < args.length; i++) {
@@ -95,14 +103,19 @@
                 } else if ("-a".equals(args[i])) {
                     apiXmlPath = getExpectedArg(args, ++i);
                 } else if ("-p".equals(args[i])) {
-                    packageFilter = getExpectedArg(args, ++i);
+                    packageFilter.addPrefixToFilter(getExpectedArg(args, ++i));
                 } else if ("-t".equals(args[i])) {
                     reportTitle = getExpectedArg(args, ++i);
                 } else {
                     printUsage();
                 }
             } else {
-                testApks.add(new File(args[i]));
+                File file = new File(args[i]);
+                if (file.isDirectory()) {
+                    testApks.addAll(Arrays.asList(file.listFiles(SUPPORTED_FILE_NAME_FILTER)));
+                } else {
+                    testApks.add(file);
+                }
             }
         }
 
@@ -118,7 +131,8 @@
          */
 
         ApiCoverage apiCoverage = getEmptyApiCoverage(apiXmlPath);
-        apiCoverage.removeEmptyAbstractClasses();
+        // Add superclass information into api coverage.
+        apiCoverage.resolveSuperClasses();
         for (File testApk : testApks) {
             addApiCoverage(apiCoverage, testApk, dexDeps);
         }
@@ -188,7 +202,7 @@
     }
 
     private static void outputCoverageReport(ApiCoverage apiCoverage, List<File> testApks,
-            File outputFile, int format, String packageFilter, String reportTitle)
+            File outputFile, int format, PackageFilter packageFilter, String reportTitle)
                 throws IOException, TransformerException, InterruptedException {
 
         OutputStream out = outputFile != null
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
index b9f9e9c..de9f5d5 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/CurrentXmlHandler.java
@@ -40,6 +40,12 @@
 
     private boolean mCurrentMethodIsAbstract;
 
+    private String mCurrentMethodVisibility;
+
+    private boolean mCurrentMethodStaticMethod;
+
+    private boolean mCurrentMethodFinalMethod;
+
     private boolean mDeprecated;
 
 
@@ -69,7 +75,9 @@
             mIgnoreCurrentClass = false;
             mCurrentClassName = getValue(attributes, "name");
             mDeprecated = isDeprecated(attributes);
-            ApiClass apiClass = new ApiClass(mCurrentClassName, mDeprecated, isAbstract(attributes));
+            String superClass = attributes.getValue("extends");
+            ApiClass apiClass = new ApiClass(
+                    mCurrentClassName, mDeprecated, is(attributes, "abstract"), superClass);
             ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
             apiPackage.addClass(apiClass);
         } else if ("interface".equalsIgnoreCase(localName)) {
@@ -82,7 +90,10 @@
             mDeprecated = isDeprecated(attributes);
             mCurrentMethodName = getValue(attributes, "name");
             mCurrentMethodReturnType = getValue(attributes, "return");
-            mCurrentMethodIsAbstract = isAbstract(attributes);
+            mCurrentMethodIsAbstract = is(attributes, "abstract");
+            mCurrentMethodVisibility = getValue(attributes, "visibility");
+            mCurrentMethodStaticMethod = is(attributes, "static");
+            mCurrentMethodFinalMethod = is(attributes, "final");
             mCurrentParameterTypes.clear();
         } else if ("parameter".equalsIgnoreCase(localName)) {
             mCurrentParameterTypes.add(getValue(attributes, "type"));
@@ -107,11 +118,15 @@
             ApiClass apiClass = apiPackage.getClass(mCurrentClassName);
             apiClass.addConstructor(apiConstructor);
         }  else if ("method".equalsIgnoreCase(localName)) {
-            if (mCurrentMethodIsAbstract) { // do not add abstract method
-                return;
-            }
-            ApiMethod apiMethod = new ApiMethod(mCurrentMethodName, mCurrentParameterTypes,
-                    mCurrentMethodReturnType, mDeprecated);
+            ApiMethod apiMethod = new ApiMethod(
+                    mCurrentMethodName,
+                    mCurrentParameterTypes,
+                    mCurrentMethodReturnType,
+                    mDeprecated,
+                    mCurrentMethodVisibility,
+                    mCurrentMethodStaticMethod,
+                    mCurrentMethodFinalMethod,
+                    mCurrentMethodIsAbstract);
             ApiPackage apiPackage = mApiCoverage.getPackage(mCurrentPackageName);
             ApiClass apiClass = apiPackage.getClass(mCurrentClassName);
             apiClass.addMethod(apiMethod);
@@ -129,8 +144,8 @@
         return "deprecated".equals(attributes.getValue("deprecated"));
     }
 
-    private boolean isAbstract(Attributes attributes) {
-        return "true".equals(attributes.getValue("abstract"));
+    private static boolean is(Attributes attributes, String valueName) {
+        return "true".equals(attributes.getValue(valueName));
     }
 
     private boolean isEnum(Attributes attributes) {
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/DexDepsXmlHandler.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/DexDepsXmlHandler.java
index 0a90bdd..3df532e 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/DexDepsXmlHandler.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/DexDepsXmlHandler.java
@@ -73,10 +73,7 @@
             if (apiPackage != null) {
                 ApiClass apiClass = apiPackage.getClass(mCurrentClassName);
                 if (apiClass != null) {
-                    ApiConstructor apiConstructor = apiClass.getConstructor(mCurrentParameterTypes);
-                    if (apiConstructor != null) {
-                        apiConstructor.setCovered(true);
-                    }
+                    apiClass.markConstructorCovered(mCurrentParameterTypes);
                 }
             }
         }  else if ("method".equalsIgnoreCase(localName)) {
@@ -84,11 +81,8 @@
             if (apiPackage != null) {
                 ApiClass apiClass = apiPackage.getClass(mCurrentClassName);
                 if (apiClass != null) {
-                    ApiMethod apiMethod = apiClass.getMethod(mCurrentMethodName,
-                            mCurrentParameterTypes, mCurrentMethodReturnType);
-                    if (apiMethod != null) {
-                        apiMethod.setCovered(true);
-                    }
+                    apiClass.markMethodCovered(
+                            mCurrentMethodName, mCurrentParameterTypes, mCurrentMethodReturnType);
                 }
             }
         }
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/HasCoverage.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/HasCoverage.java
index 3b369bb..f8d8054 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/HasCoverage.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/HasCoverage.java
@@ -20,13 +20,33 @@
 
 interface HasCoverage {
     float getCoveragePercentage();
+    int getMemberSize();
     String getName();
 }
 
 class CoverageComparator implements Comparator<HasCoverage> {
     public int compare(HasCoverage entity, HasCoverage otherEntity) {
-        int diff = Math.round(entity.getCoveragePercentage())
-                - Math.round(otherEntity.getCoveragePercentage());
-        return diff != 0 ? diff : entity.getName().compareTo(otherEntity.getName());
+        int lhsPct = Math.round(entity.getCoveragePercentage());
+        int rhsPct = Math.round(otherEntity.getCoveragePercentage());
+        int diff = Integer.compare(getCoveragePercentageSegment(lhsPct),
+                getCoveragePercentageSegment(rhsPct));
+        return diff != 0 ? diff :
+            Integer.compare(otherEntity.getMemberSize(), entity.getMemberSize());
+    }
+
+    /**
+     * Distill coverage percentage down to 3 major segments
+     * @param coveragePercentage
+     * @return
+     */
+    private int getCoveragePercentageSegment(int coveragePercentage) {
+        // note that this segmentation logic is duplicated in api-coverage.xsl
+        if (coveragePercentage <= 50) {
+            return 0;
+        } else if (coveragePercentage <= 80) {
+            return 1;
+        } else {
+            return 2;
+        }
     }
 }
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java
index dfe609d..0e6b54a 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/HtmlReport.java
@@ -37,7 +37,7 @@
 class HtmlReport {
 
     public static void printHtmlReport(final List<File> testApks, final ApiCoverage apiCoverage,
-            final String packageFilter, final String reportTitle, final OutputStream out)
+            final PackageFilter packageFilter, final String reportTitle, final OutputStream out)
                 throws IOException, TransformerException {
         final PipedOutputStream xmlOut = new PipedOutputStream();
         final PipedInputStream xmlIn = new PipedInputStream(xmlOut);
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/PackageFilter.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/PackageFilter.java
new file mode 100644
index 0000000..b196d8f
--- /dev/null
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/PackageFilter.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.cts.apicoverage;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Util class to support package filtering logic
+ * <p>
+ * A list of package prefixes can be added to the filter, and {{@link #accept(String)} method will
+ * decide if the provided package name matches any of the prefixes.
+ */
+public class PackageFilter {
+
+    private List<String> mFilters = new ArrayList<>();
+
+    /**
+     * Check if a particular package name matches any of the package prefixes configured in filter.
+     * If no filters are configured, any package names will be accepted
+     * @param packageName
+     * @return
+     */
+    public boolean accept(String packageName) {
+        if (mFilters.isEmpty()) {
+            return true;
+        }
+        for (String filter : mFilters) {
+            if (packageName.startsWith(filter)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void addPrefixToFilter(String prefix) {
+        mFilters.add(prefix);
+    }
+
+    public void clearFilter() {
+        mFilters.clear();
+    }
+}
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/TextReport.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/TextReport.java
index 23b44c3..3adc020 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/TextReport.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/TextReport.java
@@ -27,7 +27,8 @@
  */
 class TextReport {
 
-    public static void printTextReport(ApiCoverage api, String packageFilter, OutputStream outputStream) {
+    public static void printTextReport(ApiCoverage api, PackageFilter packageFilter,
+            OutputStream outputStream) {
         PrintStream out = new PrintStream(outputStream);
 
         CoverageComparator comparator = new CoverageComparator();
@@ -35,8 +36,7 @@
         Collections.sort(packages, comparator);
 
         for (ApiPackage apiPackage : packages) {
-            if (apiPackage.getName().startsWith(packageFilter)
-                    && apiPackage.getTotalMethods() > 0) {
+            if (packageFilter.accept(apiPackage.getName()) && apiPackage.getTotalMethods() > 0) {
                 printPackage(apiPackage, out);
             }
         }
@@ -45,7 +45,7 @@
         out.println();
 
         for (ApiPackage apiPackage : packages) {
-            if (apiPackage.getName().startsWith(packageFilter)) {
+            if (packageFilter.accept(apiPackage.getName())) {
                 printPackage(apiPackage, out);
 
                 List<ApiClass> classes = new ArrayList<ApiClass>(apiPackage.getClasses());
@@ -103,7 +103,18 @@
     private static void printMethod(ApiMethod method, PrintStream out) {
         StringBuilder builder = new StringBuilder("    [")
                 .append(method.isCovered() ? "X" : " ")
-                .append("] ").append(method.getReturnType()).append(" ")
+                .append("] ")
+                .append(method.getVisibility()).append(" ");
+        if (method.isAbstractMethod()) {
+            builder.append("abstract ");
+        }
+        if (method.isStaticMethod()) {
+            builder.append("static ");
+        }
+        if (method.isFinalMethod()) {
+            builder.append("final ");
+        }
+        builder.append(method.getReturnType()).append(" ")
                 .append(method.getName()).append("(");
         List<String> parameterTypes = method.getParameterTypes();
         int numParameterTypes = parameterTypes.size();
diff --git a/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java b/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
index df10fa4..4310d20 100644
--- a/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
+++ b/tools/cts-api-coverage/src/com/android/cts/apicoverage/XmlReport.java
@@ -32,7 +32,7 @@
 class XmlReport {
 
     public static void printXmlReport(List<File> testApks, ApiCoverage apiCoverage,
-            String packageFilter, String reportTitle, OutputStream outputStream) {
+            PackageFilter packageFilter, String reportTitle, OutputStream outputStream) {
         PrintStream out = new PrintStream(outputStream);
         out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
         out.println("<?xml-stylesheet type=\"text/xsl\"  href=\"api-coverage.xsl\"?>");
@@ -57,8 +57,7 @@
         int totalMethods = 0;
         int totalCoveredMethods = 0;
         for (ApiPackage pkg : packages) {
-            if (pkg.getName().startsWith(packageFilter)
-                   && pkg.getTotalMethods() > 0) {
+            if (packageFilter.accept(pkg.getName()) && pkg.getTotalMethods() > 0) {
                 int pkgTotal = pkg.getTotalMethods();
                 totalMethods += pkgTotal;
                 int pkgTotalCovered = pkg.getNumCoveredMethods();
@@ -67,7 +66,7 @@
                         + "\" numCovered=\"" + pkgTotalCovered
                         + "\" numTotal=\"" + pkgTotal
                         + "\" coveragePercentage=\""
-                            + Math.round(pkg.getCoveragePercentage())
+                        + Math.round(pkg.getCoveragePercentage())
                         + "\">");
 
                 List<ApiClass> classes = new ArrayList<ApiClass>(pkg.getClasses());
@@ -104,6 +103,10 @@
                             out.println("<method name=\"" + method.getName()
                                     + "\" returnType=\"" + method.getReturnType()
                                     + "\" deprecated=\"" + method.isDeprecated()
+                                    + "\" static=\"" + method.isStaticMethod()
+                                    + "\" final=\"" + method.isFinalMethod()
+                                    + "\" visibility=\"" + method.getVisibility()
+                                    + "\" abstract=\"" + method.isAbstractMethod()
                                     + "\" covered=\"" + method.isCovered() + "\">");
                             if (method.isDeprecated()) {
                                 if (method.isCovered()) {
diff --git a/tools/cts-api-coverage/src/res/api-coverage.xsl b/tools/cts-api-coverage/src/res/api-coverage.xsl
index 1ac3402..1a56eb0 100644
--- a/tools/cts-api-coverage/src/res/api-coverage.xsl
+++ b/tools/cts-api-coverage/src/res/api-coverage.xsl
@@ -21,6 +21,7 @@
     <xsl:template match="/">
         <html>
             <head>
+                <title><xsl:value-of select="api-coverage/@title" /></title>
                 <script type="text/javascript">
                     function toggleVisibility(id) {
                         element = document.getElementById(id); 
@@ -87,7 +88,7 @@
                 &nbsp;(<xsl:value-of select="api-coverage/total/@numCovered" />/<xsl:value-of select="api-coverage/total/@numTotal" />)
                 </div>
                 <div class="apks" onclick="toggleVisibility('sourceApks')">
-                    Source APKs (<xsl:value-of select="count(api-coverage/debug/sources/apk)" />)
+                    Source Modules (<xsl:value-of select="count(api-coverage/debug/sources/apk)" />)
                 </div>
                 <div id="sourceApks" style="display: none">
                     <ul>
@@ -100,14 +101,17 @@
                     <xsl:for-each select="api-coverage/api/package">
                         <xsl:call-template name="packageOrClassListItem">
                             <xsl:with-param name="bulletClass" select="'package'" />
+                            <xsl:with-param name="toggleId" select="@name" />
                         </xsl:call-template>
                         <div class="packageDetails" id="{@name}" style="display: none">
                             <ul>
                                 <xsl:for-each select="class">
+                                    <xsl:variable name="packageClassId" select="concat(../@name, '.', @name)"/>
                                     <xsl:call-template name="packageOrClassListItem">
                                         <xsl:with-param name="bulletClass" select="'class'" />
+                                        <xsl:with-param name="toggleId" select="$packageClassId" />
                                     </xsl:call-template>
-                                    <div class="classDetails" id="{@name}" style="display: none">
+                                    <div class="classDetails" id="{$packageClassId}" style="display: none">
                                         <xsl:for-each select="constructor">
                                             <xsl:call-template name="methodListItem" />
                                         </xsl:for-each>
@@ -123,9 +127,10 @@
             </body>
         </html>
     </xsl:template>
-    
+
     <xsl:template name="packageOrClassListItem">
         <xsl:param name="bulletClass" />
+        <xsl:param name="toggleId"/>
 
         <xsl:variable name="colorClass">
             <xsl:choose>
@@ -134,7 +139,7 @@
                 <xsl:otherwise>green</xsl:otherwise>
             </xsl:choose>
         </xsl:variable>
-        
+
         <xsl:variable name="deprecatedClass">
             <xsl:choose>
                 <xsl:when test="@deprecated = 'true'">deprecated</xsl:when>
@@ -142,15 +147,15 @@
             </xsl:choose>
         </xsl:variable>
 
-        <li class="{$bulletClass}" onclick="toggleVisibility('{@name}')">
+        <li class="{$bulletClass}" onclick="toggleVisibility('{$toggleId}')">
             <span class="{$colorClass} {$deprecatedClass}">
                 <b><xsl:value-of select="@name" /></b>
                 &nbsp;<xsl:value-of select="@coveragePercentage" />%
                 &nbsp;(<xsl:value-of select="@numCovered" />/<xsl:value-of select="@numTotal" />)
             </span>
-        </li>   
+        </li>
     </xsl:template>
-  
+
   <xsl:template name="methodListItem">
 
     <xsl:variable name="deprecatedClass">
@@ -165,6 +170,10 @@
         <xsl:when test="@covered = 'true'">[X]</xsl:when>
         <xsl:otherwise>[ ]</xsl:otherwise>
       </xsl:choose>
+      <xsl:if test="@visibility != ''">&nbsp;<xsl:value-of select="@visibility" /></xsl:if>
+      <xsl:if test="@abstract = 'true'">&nbsp;abstract</xsl:if>
+      <xsl:if test="@static = 'true'">&nbsp;static</xsl:if>
+      <xsl:if test="@final = 'true'">&nbsp;final</xsl:if>
       <xsl:if test="@returnType != ''">&nbsp;<xsl:value-of select="@returnType" /></xsl:if>
       <b>&nbsp;<xsl:value-of select="@name" /></b><xsl:call-template name="formatParameters" />
     </span>
diff --git a/tools/cts-device-info/Android.mk b/tools/cts-device-info/Android.mk
new file mode 100644
index 0000000..5f2b223
--- /dev/null
+++ b/tools/cts-device-info/Android.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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)
+
+DEVICE_INFO_PERMISSIONS :=
+
+DEVICE_INFO_ACTIVITIES :=
+
+LOCAL_PACKAGE_NAME := CtsDeviceInfo
+
+include $(BUILD_CTS_DEVICE_INFO_PACKAGE)
+
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
new file mode 100644
index 0000000..886193c
--- /dev/null
+++ b/tools/cts-device-info/src/com/android/cts/deviceinfo/SampleDeviceInfo.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.cts.deviceinfo;
+
+import android.os.Bundle;
+
+import com.android.compatibility.common.deviceinfo.DeviceInfoActivity;
+
+/**
+ * Sample device info collector.
+ */
+public class SampleDeviceInfo extends DeviceInfoActivity {
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    protected void collectDeviceInfo() {
+        boolean[] booleans = {Boolean.TRUE, Boolean.FALSE};
+        double[] doubles = {Double.MAX_VALUE, Double.MIN_VALUE};
+        int[] ints = {Integer.MAX_VALUE, Integer.MIN_VALUE};
+        long[] longs = {Long.MAX_VALUE, Long.MIN_VALUE};
+
+        // Group Foo
+        startGroup("foo");
+        addResult("foo_boolean", Boolean.TRUE);
+
+        // Group Bar
+        startGroup("bar");
+        addArray("bar_string", new String[] {
+                "bar-string-1",
+                "bar-string-2",
+                "bar-string-3"});
+
+        addArray("bar_boolean", booleans);
+        addArray("bar_double", doubles);
+        addArray("bar_int", ints);
+        addArray("bar_long", longs);
+        endGroup(); // bar
+
+        addResult("foo_double", Double.MAX_VALUE);
+        addResult("foo_int", Integer.MAX_VALUE);
+        addResult("foo_long", Long.MAX_VALUE);
+        addResult("foo_string", "foo-string");
+        endGroup(); // foo
+    }
+}
+
diff --git a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
index 94761fb..fb6691d 100644
--- a/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
+++ b/tools/cts-java-scanner/src/com/android/cts/javascanner/DocletRunner.java
@@ -89,6 +89,7 @@
         List<String> classPath = new ArrayList<String>();
         classPath.add("./prebuilts/misc/common/tradefed/tradefed-prebuilt.jar");
         classPath.add("./prebuilts/misc/common/ub-uiautomator/ub-uiautomator.jar");
+        classPath.add("./prebuilts/misc/common/ub-janktesthelper/ub-janktesthelper.jar");
         return join(classPath, ":");
     }
 
diff --git a/tools/cts-media/copy_media.sh b/tools/cts-media/copy_media.sh
new file mode 100755
index 0000000..cfec807
--- /dev/null
+++ b/tools/cts-media/copy_media.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+# 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.
+#
+adb_options=" "
+max_resolution=3
+if [ $# -eq 0 ]; then
+  echo "assuming default resolution"
+elif [ "$1" = "-s" ]; then
+  adb_options=""$1" "$2""
+elif [ "$1" = "720x480" ]; then
+  max_resolution=1
+elif [ "$1" = "1280x720" ]; then
+  max_resolution=2
+elif [ "$1" = "1920x1080" ]; then
+  max_resolution=3
+elif [ "$1" = "all" ]; then
+  max_resolution=3
+else
+  echo "Usage: copy_media.sh [720x480|1280x720|1920x1080] [-s serial]"
+  echo "  for testing up to 1280x720, copy_media.sh 1280x720"
+  echo "  default resolution, when no argument is specified, is 1920x1080"
+  echo "  copy_media.sh all will copy all the files."
+  exit
+fi
+
+if [ $# -gt 2 ]; then
+  echo "adb option exists"
+  adb_options=""$2" "$3""
+fi
+
+echo "max resolution is $1"
+echo "adb options "$adb_options""
+
+if [ $max_resolution -ge 3 ]; then
+  echo "copying 1920x1080"
+  adb $adb_options push bbb_short/1920x1080 /sdcard/test/bbb_short/1920x1080
+  adb $adb_options push bbb_full/1920x1080 /sdcard/test/bbb_full/1920x1080
+fi
+
+if [ $max_resolution -ge 2 ]; then
+  echo "copying 1280x720"
+  adb $adb_options push bbb_short/1280x720 /sdcard/test/bbb_short/1280x720
+  adb $adb_options push bbb_full/1280x720 /sdcard/test/bbb_full/1280x720
+fi
+
+if [ $max_resolution -ge 1 ]; then
+  echo "copying 720x480"
+  adb $adb_options push bbb_short/720x480 /sdcard/test/bbb_short/720x480
+  adb $adb_options push bbb_full/720x480 /sdcard/test/bbb_full/720x480
+fi
+
+echo "copying all others"
+adb $adb_options push bbb_short/176x144 /sdcard/test/bbb_short/176x144
+adb $adb_options push bbb_full/176x144 /sdcard/test/bbb_full/176x144
+adb $adb_options push bbb_short/480x360 /sdcard/test/bbb_short/480x360
+adb $adb_options push bbb_full/480x360 /sdcard/test/bbb_full/480x360
diff --git a/tools/cts-media/get_achievable_rates.py b/tools/cts-media/get_achievable_rates.py
new file mode 100755
index 0000000..9dde743
--- /dev/null
+++ b/tools/cts-media/get_achievable_rates.py
@@ -0,0 +1,402 @@
+#!/usr/bin/python
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT 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 argparse, math, re, sys
+import xml.etree.ElementTree as ET
+from collections import defaultdict, namedtuple
+import itertools
+
+
+def createLookup(values, key):
+  """Creates a lookup table for a collection of values based on keys.
+
+  Arguments:
+    values: a collection of arbitrary values. Must be iterable.
+    key: a function of one argument that returns the key for a value.
+
+  Returns:
+    A dict mapping keys (as generated by the key argument) to lists of
+    values. All values in the lists have the same key, and are in the order
+    they appeared in the collection.
+  """
+  lookup = defaultdict(list)
+  for v in values:
+    lookup[key(v)].append(v)
+  return lookup
+
+
+def _intify(value):
+  """Returns a value converted to int if possible, else the original value."""
+  try:
+    return int(value)
+  except ValueError:
+    return value
+
+
+class Size(namedtuple('Size', ['width', 'height'])):
+  """A namedtuple with width and height fields."""
+  def __str__(self):
+    return '%dx%d' % (self.width, self.height)
+
+
+class _VideoResultBase(object):
+  """Helper methods for results. Not for use by applications.
+
+  Attributes:
+    codec: The name of the codec (string) or None
+    size: Size representing the video size or None
+    mime: The mime-type of the codec (string) or None
+    rates: The measured achievable frame rates
+    is_decoder: True iff codec is a decoder.
+  """
+
+  def __init__(self, is_decoder):
+    self.codec = None
+    self.mime = None
+    self.size = None
+    self._rates_from_failure = []
+    self._rates_from_message = []
+    self.is_decoder = is_decoder
+
+  def _inited(self):
+    """Returns true iff codec, mime and size was set."""
+    return None not in (self.codec, self.mime, self.size)
+
+  def __len__(self):
+    # don't report any result if codec name, mime type and size is unclear
+    if not self._inited():
+      return 0
+    return len(self.rates)
+
+  @property
+  def rates(self):
+    return self._rates_from_failure or self._rates_from_message
+
+  def _parseDict(self, value):
+    """Parses a MediaFormat from its string representation sans brackets."""
+    return dict((k, _intify(v))
+                for k, v in re.findall(r'([^ =]+)=([^ [=]+(?:|\[[^\]]+\]))(?:, |$)', value))
+
+  def _cleanFormat(self, format):
+    """Removes internal fields from a parsed MediaFormat."""
+    format.pop('what', None)
+    format.pop('image-data', None)
+
+  MESSAGE_PATTERN = r'(?P<key>\w+)=(?P<value>\{[^}]*\}|[^ ,{}]+)'
+
+  def _parsePartialResult(self, message_match):
+    """Parses a partial test result conforming to the message pattern.
+
+    Returns:
+      A tuple of string key and int, string or dict value, where dict has
+      string keys mapping to int or string values.
+    """
+    key, value = message_match.group('key', 'value')
+    if value.startswith('{'):
+      value = self._parseDict(value[1:-1])
+      if key.endswith('Format'):
+        self._cleanFormat(value)
+    else:
+      value = _intify(value)
+    return key, value
+
+  def _parseValuesFromBracket(self, line):
+    """Returns the values enclosed in brackets without the brackets.
+
+    Parses a line matching the pattern "<tag>: [<values>]" and returns <values>.
+
+    Raises:
+      ValueError: if the line does not match the pattern.
+    """
+    try:
+      return re.match(r'^[^:]+: *\[(?P<values>.*)\]\.$', line).group('values')
+    except AttributeError:
+      raise ValueError('line does not match "tag: [value]": %s' % line)
+
+  def _parseRawData(self, line):
+    """Parses the raw data line for video performance tests.
+
+    Yields:
+      Dict objects corresponding to parsed results, mapping string keys to
+      int, string or dict values.
+    """
+    try:
+      values = self._parseValuesFromBracket(line)
+      result = {}
+      for m in re.finditer(self.MESSAGE_PATTERN + r'(?P<sep>,? +|$)', values):
+        key, value = self._parsePartialResult(m)
+        result[key] = value
+        if m.group('sep') != ' ':
+          yield result
+          result = {}
+    except ValueError:
+      print >> sys.stderr, 'could not parse line %s' % repr(line)
+
+  def _tryParseMeasuredFrameRate(self, line):
+    """Parses a line starting with 'Measured frame rate:'."""
+    if line.startswith('Measured frame rate: '):
+      try:
+        values = self._parseValuesFromBracket(line)
+        values = re.split(r' *, *', values)
+        self._rates_from_failure = list(map(float, values))
+      except ValueError:
+        print >> sys.stderr, 'could not parse line %s' % repr(line)
+
+  def parse(self, test):
+    """Parses the ValueArray and FailedScene lines of a test result.
+
+    Arguments:
+      test: An ElementTree <Test> element.
+    """
+    failure = test.find('FailedScene')
+    if failure is not None:
+      trace = failure.find('StackTrace')
+      if trace is not None:
+        for line in re.split(r'[\r\n]+', trace.text):
+          self._parseFailureLine(line)
+    details = test.find('Details')
+    if details is not None:
+      for array in details.iter('ValueArray'):
+        message = array.get('message')
+        self._parseMessage(message, array)
+
+  def _parseFailureLine(self, line):
+    raise NotImplementedError
+
+  def _parseMessage(self, message, array):
+    raise NotImplementedError
+
+  def getData(self):
+    """Gets the parsed test result data.
+
+    Yields:
+       Result objects containing at least codec, size, mime and rates attributes."""
+    yield self
+
+
+class VideoEncoderDecoderTestResult(_VideoResultBase):
+  """Represents a result from a VideoEncoderDecoderTest performance case."""
+
+  def __init__(self, unused_m):
+    super(VideoEncoderDecoderTestResult, self).__init__(is_decoder=False)
+
+  # If a VideoEncoderDecoderTest succeeds, it provides the results in the
+  # message of a ValueArray. If fails, it provides the results in the failure
+  # using raw data. (For now it also includes some data in the ValueArrays even
+  # if it fails, which we ignore.)
+
+  def _parseFailureLine(self, line):
+    """Handles parsing a line from the failure log."""
+    self._tryParseMeasuredFrameRate(line)
+    if line.startswith('Raw data: '):
+      for result in self._parseRawData(line):
+        fmt = result['EncOutputFormat']
+        self.size = Size(fmt['width'], fmt['height'])
+        self.codec = result['codec']
+        self.mime = fmt['mime']
+
+  def _parseMessage(self, message, array):
+    """Handles parsing a message from ValueArrays."""
+    if message.startswith('codec='):
+      result = dict(self._parsePartialResult(m)
+                  for m in re.finditer(self.MESSAGE_PATTERN + '(?: |$)', message))
+      if 'EncInputFormat' in result:
+        self.codec = result['codec']
+        fmt = result['EncInputFormat']
+        self.size = Size(fmt['width'], fmt['height'])
+        self.mime = result['EncOutputFormat']['mime']
+        self._rates_from_message.append(1000000./result['min'])
+
+
+class VideoDecoderPerfTestResult(_VideoResultBase):
+  """Represents a result from a VideoDecoderPerfTest performance case."""
+
+  # If a VideoDecoderPerfTest succeeds, it provides the results in the message
+  # of a ValueArray. If fails, it provides the results in the failure only
+  # using raw data.
+
+  def __init__(self, unused_m):
+    super(VideoDecoderPerfTestResult, self).__init__(is_decoder=True)
+
+  def _parseFailureLine(self, line):
+    """Handles parsing a line from the failure log."""
+    self._tryParseMeasuredFrameRate(line)
+    # if the test failed, we can only get the codec/size/mime from the raw data.
+    if line.startswith('Raw data: '):
+      for result in self._parseRawData(line):
+        fmt = result['DecOutputFormat']
+        self.size = Size(fmt['width'], fmt['height'])
+        self.codec = result['codec']
+        self.mime = result['mime']
+
+  def _parseMessage(self, message, array):
+    """Handles parsing a message from ValueArrays."""
+    if message.startswith('codec='):
+      result = dict(self._parsePartialResult(m)
+                  for m in re.finditer(self.MESSAGE_PATTERN + '(?: |$)', message))
+      if result.get('decodeto') == 'surface':
+        self.codec = result['codec']
+        fmt = result['DecOutputFormat']
+        self.size = Size(fmt['width'], fmt['height'])
+        self.mime = result['mime']
+        self._rates_from_message.append(1000000. / result['min'])
+
+
+class Results(object):
+  """Container that keeps all test results."""
+  def __init__(self):
+      self._results = [] # namedtuples
+      self._device = None
+
+  VIDEO_ENCODER_DECODER_TEST_REGEX = re.compile(
+      'test(.*)(\d{4})x(\d{4})(Goog|Other)$')
+
+  VIDEO_DECODER_PERF_TEST_REGEX = re.compile(
+      'test(VP[89]|H26[34]|MPEG4|HEVC)(\d+)x(\d+)(.*)$')
+
+  TestCaseSpec = namedtuple('TestCaseSpec', 'package path class_ regex result_class')
+
+  def _getTestCases(self):
+    return [
+      self.TestCaseSpec(package='CtsDeviceVideoPerf',
+                   path='TestSuite/TestSuite/TestSuite/TestSuite/TestCase',
+                   class_='VideoEncoderDecoderTest',
+                   regex=self.VIDEO_ENCODER_DECODER_TEST_REGEX,
+                   result_class=VideoEncoderDecoderTestResult),
+      self.TestCaseSpec(package='CtsMediaTestCases',
+                   path='TestSuite/TestSuite/TestSuite/TestCase',
+                   class_='VideoDecoderPerfTest',
+                   regex=self.VIDEO_DECODER_PERF_TEST_REGEX,
+                   result_class=VideoDecoderPerfTestResult)
+    ]
+
+  def _verifyDeviceInfo(self, device):
+    assert self._device in (None, device), "expected %s device" % self._device
+    self._device = device
+
+  def importXml(self, xml):
+    self._verifyDeviceInfo(xml.find('DeviceInfo/BuildInfo').get('buildName'))
+
+    packages = createLookup(self._getTestCases(), lambda tc: tc.package)
+
+    for pkg in xml.iter('TestPackage'):
+      tests_in_package = packages.get(pkg.get('name'))
+      if not tests_in_package:
+        continue
+      paths = createLookup(tests_in_package, lambda tc: tc.path)
+      for path, tests_in_path in paths.items():
+        classes = createLookup(tests_in_path, lambda tc: tc.class_)
+        for tc in pkg.iterfind(path):
+          tests_in_class = classes.get(tc.get('name'))
+          if not tests_in_class:
+            continue
+          for test in tc.iter('Test'):
+            for tc in tests_in_class:
+              m = tc.regex.match(test.get('name'))
+              if m:
+                result = tc.result_class(m)
+                result.parse(test)
+                self._results.append(result)
+
+  def importFile(self, path):
+    print >> sys.stderr, 'Importing "%s"...' % path
+    try:
+      return self.importXml(ET.parse(path))
+    except ET.ParseError:
+      raise ValueError('not a valid XML file')
+
+  def getData(self):
+    for result in self._results:
+      for data in result.getData():
+        yield data
+
+  def dumpXml(self, results):
+    yield '<?xml version="1.0" encoding="utf-8" ?>'
+    yield '<!-- Copyright 2015 The Android Open Source Project'
+    yield ''
+    yield '     Licensed under the Apache License, Version 2.0 (the "License");'
+    yield '     you may not use this file except in compliance with the License.'
+    yield '     You may obtain a copy of the License at'
+    yield ''
+    yield '          http://www.apache.org/licenses/LICENSE-2.0'
+    yield ''
+    yield '     Unless required by applicable law or agreed to in writing, software'
+    yield '     distributed under the License is distributed on an "AS IS" BASIS,'
+    yield '     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.'
+    yield '     See the License for the specific language governing permissions and'
+    yield '     limitations under the License.'
+    yield '-->'
+    yield ''
+    yield '<MediaCodecs>'
+    last_section = None
+    Comp = namedtuple('Comp', 'is_decoder google mime name')
+    by_comp = createLookup(results,
+                           lambda e: Comp(is_decoder=e.is_decoder, google='.google.' in e.codec, mime=e.mime, name=e.codec))
+    for comp in sorted(by_comp):
+      section = 'Decoders' if comp.is_decoder else 'Encoders'
+      if section != last_section:
+        if last_section:
+          yield '    </%s>' % last_section
+        yield '    <%s>' % section
+        last_section = section
+      yield '        <MediaCodec name="%s" type="%s" update="true">' % (comp.name, comp.mime)
+      by_size = createLookup(by_comp[comp], lambda e: e.size)
+      for size in sorted(by_size):
+        values = list(itertools.chain(*(e.rates for e in by_size[size])))
+        min_, max_ = min(values), max(values)
+        med_ = int(math.sqrt(min_ * max_))
+        yield '            <Limit name="measured-frame-rate-%s" range="%d-%d" />' % (size, med_, med_)
+      yield '        </MediaCodec>'
+    if last_section:
+      yield '    </%s>' % last_section
+    yield '</MediaCodecs>'
+
+
+class Main(object):
+  """Executor of this utility."""
+
+  def __init__(self):
+    self._result = Results()
+
+    self._parser = argparse.ArgumentParser('get_achievable_framerates')
+    self._parser.add_argument('result_xml', nargs='+')
+
+  def _parseArgs(self):
+    self._args = self._parser.parse_args()
+
+  def _importXml(self, xml):
+    self._result.importFile(xml)
+
+  def _report(self):
+    for line in self._result.dumpXml(r for r in self._result.getData() if r):
+      print line
+
+  def run(self):
+    self._parseArgs()
+    try:
+      for xml in self._args.result_xml:
+        try:
+          self._importXml(xml)
+        except (ValueError, IOError, AssertionError) as e:
+          print >> sys.stderr, e
+          raise KeyboardInterrupt
+      self._report()
+    except KeyboardInterrupt:
+      print >> sys.stderr, 'Interrupted.'
+
+if __name__ == '__main__':
+  Main().run()
+
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 833bf69..328b855 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
@@ -20,6 +20,7 @@
 
 import vogar.Expectation;
 import vogar.ExpectationStore;
+import vogar.Result;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -228,7 +229,8 @@
     }
 
     public static boolean isKnownFailure(ExpectationStore expectationStore, String testName) {
-        return expectationStore != null && expectationStore.get(testName) != Expectation.SUCCESS;
+        return expectationStore != null
+            && expectationStore.get(testName).getResult() != Result.SUCCESS;
     }
 
     // Returns the list of ABIs supported by this TestCase on this architecture.
diff --git a/tools/device-setup/TestDeviceSetup/Android.mk b/tools/device-setup/TestDeviceSetup/Android.mk
index 7238117..edb85d2 100644
--- a/tools/device-setup/TestDeviceSetup/Android.mk
+++ b/tools/device-setup/TestDeviceSetup/Android.mk
@@ -30,7 +30,7 @@
 
 LOCAL_PACKAGE_NAME := TestDeviceSetup
 
-include $(BUILD_PACKAGE)
+include $(BUILD_CTS_SUPPORT_PACKAGE)
 
 # ======================================================
 # also build a static host library for the device info constants
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
index 856ba0f..c336d3c 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoConstants.java
@@ -76,4 +76,6 @@
     public static final String MEMORY_CLASS = "memory_class";
     public static final String LARGE_MEMORY_CLASS = "large_memory_class";
     public static final String TOTAL_MEMORY = "total_memory";
+    public static final String REFERENCE_BUILD_FINGERPRINT =
+            "reference_build_fingerprint";
 }
diff --git a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
index 16abaed..37f8558 100644
--- a/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
+++ b/tools/device-setup/TestDeviceSetup/src/android/tests/getinfo/DeviceInfoInstrument.java
@@ -81,11 +81,13 @@
         addResult(BUILD_ABIS_64, TextUtils.join(",", Build.SUPPORTED_64_BIT_ABIS));
         addResult(SERIAL_NUMBER, Build.SERIAL);
 
+        addResult(REFERENCE_BUILD_FINGERPRINT,
+            SystemProperties.get("ro.build.reference.fingerprint", ""));
+
         addResult(VERSION_RELEASE, Build.VERSION.RELEASE);
         addResult(VERSION_SDK, Build.VERSION.SDK);
-        addResult(VERSION_BASE_OS, SystemProperties.get("ro.build.version.base_os", ""));
-        addResult(VERSION_SECURITY_PATCH,
-            SystemProperties.get("ro.build.version.security_patch", ""));
+        addResult(VERSION_BASE_OS, Build.VERSION.BASE_OS);
+        addResult(VERSION_SECURITY_PATCH, Build.VERSION.SECURITY_PATCH);
 
         DisplayMetrics metrics = new DisplayMetrics();
         WindowManager wm = (WindowManager) getContext().getSystemService(
@@ -459,7 +461,7 @@
     private String getTotalMemory() {
         ActivityManager activityManager = (ActivityManager) getContext()
                 .getSystemService(Context.ACTIVITY_SERVICE);
-        
+
         MemoryInfo memoryInfo = new MemoryInfo();
         activityManager.getMemoryInfo(memoryInfo);
         return String.valueOf(memoryInfo.totalMem);
diff --git a/tools/junit/Android.mk b/tools/junit/Android.mk
index b581149..90e6924 100644
--- a/tools/junit/Android.mk
+++ b/tools/junit/Android.mk
@@ -21,3 +21,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := junit4-target
 LOCAL_DEX_PREOPT := false
 include $(BUILD_JAVA_LIBRARY)
+
+cts_library_jar := $(CTS_TESTCASES_OUT)/$(LOCAL_MODULE).jar
+$(cts_library_jar): $(LOCAL_BUILT_MODULE)
+	$(copy-file-to-target)
diff --git a/tools/selinux/SELinuxNeverallowTestFrame.py b/tools/selinux/SELinuxNeverallowTestFrame.py
index 0bf766d..45900de 100644
--- a/tools/selinux/SELinuxNeverallowTestFrame.py
+++ b/tools/selinux/SELinuxNeverallowTestFrame.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 src_header = """/*
  * Copyright (C) 2014 The Android Open Source Project
diff --git a/tools/selinux/SELinuxNeverallowTestGen.py b/tools/selinux/SELinuxNeverallowTestGen.py
index 9cb1e24..bc775d6 100755
--- a/tools/selinux/SELinuxNeverallowTestGen.py
+++ b/tools/selinux/SELinuxNeverallowTestGen.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
 
 import re
 import sys
diff --git a/tools/tradefed-host/.classpath b/tools/tradefed-host/.classpath
index e716219..dbeeb01 100644
--- a/tools/tradefed-host/.classpath
+++ b/tools/tradefed-host/.classpath
@@ -7,5 +7,6 @@
 	<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 bd28575..1f73e95 100644
--- a/tools/tradefed-host/Android.mk
+++ b/tools/tradefed-host/Android.mk
@@ -27,6 +27,8 @@
 LOCAL_JAVA_LIBRARIES := tradefed-prebuilt hosttestlib
 LOCAL_STATIC_JAVA_LIBRARIES := ctsdeviceinfolib
 
+LOCAL_JAR_MANIFEST := MANIFEST.mf
+
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 
 include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tools/tradefed-host/MANIFEST.mf b/tools/tradefed-host/MANIFEST.mf
new file mode 100644
index 0000000..5528c06
--- /dev/null
+++ b/tools/tradefed-host/MANIFEST.mf
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: com.android.cts.tradefed.testtype
+Implementation-Version: %BUILD_NUMBER%
diff --git a/tools/tradefed-host/etc/cts-tradefed b/tools/tradefed-host/etc/cts-tradefed
index 9a643de..5903454 100755
--- a/tools/tradefed-host/etc/cts-tradefed
+++ b/tools/tradefed-host/etc/cts-tradefed
@@ -49,21 +49,22 @@
   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
-      HOST=`uname`
-      if [ "$HOST" == "Linux" ]; then
-          OS="linux-x86"
-      elif [ "$HOST" == "Darwin" ]; then
-          OS="darwin-x86"
-      else
-          echo "Unrecognized OS"
-          exit
-      fi
       CTS_ROOT=${ANDROID_BUILD_TOP}/${OUT_DIR:-out}/host/${OS}/cts
     fi
     if [ ! -d ${CTS_ROOT} ]; then
@@ -85,6 +86,16 @@
     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/preconditions/Android.mk b/tools/tradefed-host/preconditions/Android.mk
new file mode 100644
index 0000000..bcd7b49
--- /dev/null
+++ b/tools/tradefed-host/preconditions/Android.mk
@@ -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.
+
+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
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := CtsPreconditionsApp
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_CTS_SUPPORT_PACKAGE)
diff --git a/tools/tradefed-host/preconditions/AndroidManifest.xml b/tools/tradefed-host/preconditions/AndroidManifest.xml
new file mode 100644
index 0000000..02b3534
--- /dev/null
+++ b/tools/tradefed-host/preconditions/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?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.preconditions">
+    <application>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <!--  self-instrumenting test package. -->
+    <instrumentation
+        android:name="android.support.test.runner.AndroidJUnitRunner"
+        android:label="CTS device-side preconditions test"
+        android:targetPackage="com.android.cts.preconditions" >
+    </instrumentation>
+</manifest>
diff --git a/tools/tradefed-host/preconditions/src/com/android/cts/preconditions/PreconditionsTest.java b/tools/tradefed-host/preconditions/src/com/android/cts/preconditions/PreconditionsTest.java
new file mode 100644
index 0000000..64a2b31
--- /dev/null
+++ b/tools/tradefed-host/preconditions/src/com/android/cts/preconditions/PreconditionsTest.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.cts.preconditions;
+
+import android.app.KeyguardManager;
+import android.content.Context;
+import android.os.Environment;
+import android.test.AndroidTestCase;
+
+/**
+ * An AndroidTestCase class to verify that device-side preconditions are met for CTS
+ */
+public class PreconditionsTest extends AndroidTestCase {
+
+    /**
+     * Test if device has no screen lock
+     * @throws Exception
+     */
+    public void testScreenUnlocked() throws Exception {
+        KeyguardManager km =
+                (KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
+        assertFalse("Device must have screen lock disabled", km.isDeviceSecure());
+    }
+
+    /**
+     * Test if device has accessible external storage
+     * @throws Exception
+     */
+    public void testExternalStoragePresent() throws Exception {
+        String state = Environment.getExternalStorageState();
+        assertTrue("Device must have writable external storage mounted in order to run CTS",
+                Environment.MEDIA_MOUNTED.equals(state));
+    }
+
+}
diff --git a/tools/tradefed-host/res/config/common-config.xml b/tools/tradefed-host/res/config/common-config.xml
new file mode 100644
index 0000000..e1ac66d
--- /dev/null
+++ b/tools/tradefed-host/res/config/common-config.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="Common base configuration for CTS module">
+    <!--
+      This common base configuration contains some commonly used preparers
+      -->
+    <target_preparer class="com.android.cts.tradefed.targetprep.CtsFilePusher">
+        <option name="cleanup" value="true" />
+    </target_preparer>
+    <target_preparer class="com.android.cts.tradefed.targetprep.CtsApkInstaller">
+        <option name="cleanup-apks" value="true" />
+    </target_preparer>
+    <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer" />
+</configuration>
diff --git a/tools/tradefed-host/res/config/cts.xml b/tools/tradefed-host/res/config/cts.xml
index 416b400..a5665be 100644
--- a/tools/tradefed-host/res/config/cts.xml
+++ b/tools/tradefed-host/res/config/cts.xml
@@ -19,6 +19,8 @@
     <option name="enable-root" value="false" />
     <build_provider class="com.android.cts.tradefed.build.CtsBuildProvider" />
     <device_recovery class="com.android.tradefed.device.WaitDeviceRecovery" />
+    <target_preparer class="com.android.cts.tradefed.targetprep.DevicePreconditionPreparer" />
+    <target_preparer class="com.android.cts.tradefed.targetprep.HostPreconditionPreparer" />
     <test class="com.android.cts.tradefed.testtype.CtsTest" />
     <logger class="com.android.tradefed.log.FileLogger" />
     <result_reporter class="com.android.cts.tradefed.result.CtsXmlResultReporter" />
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 0acb43b..a39d8b6 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,8 @@
     @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 = "5.1_r4";
+    public static final String CTS_BUILD_VERSION = "6.0_r2";
+    public static final String CTS_PACKAGE = "com.android.cts.tradefed.testtype";
 
     /**
      * {@inheritDoc}
@@ -41,7 +42,9 @@
         if (mCtsRootDirPath == null) {
             throw new IllegalArgumentException("Missing --cts-install-path");
         }
-        IFolderBuildInfo ctsBuild = new FolderBuildInfo(CTS_BUILD_VERSION, "cts", "cts");
+        IFolderBuildInfo ctsBuild = new FolderBuildInfo(
+            Package.getPackage(CTS_PACKAGE).getImplementationVersion(),
+            "cts", "cts");
         ctsBuild.setRootDir(new File(mCtsRootDirPath));
         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 ca4e050..24239e6 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
@@ -24,6 +24,7 @@
 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;
 import com.android.tradefed.config.ConfigurationException;
@@ -48,7 +49,8 @@
 
     protected static final String ADD_PATTERN = "a(?:dd)?";
 
-    private CtsBuildHelper mCtsBuild = null;
+    private IFolderBuildInfo mBuildInfo = null;
+    private CtsBuildHelper mBuildHelper = null;
 
     CtsConsole() {
         super();
@@ -56,7 +58,8 @@
 
     @Override
     public void run() {
-        printLine(String.format("Android CTS %s", CtsBuildProvider.CTS_BUILD_VERSION));
+        printLine(String.format("Android CTS %s build:%s",
+                CtsBuildProvider.CTS_BUILD_VERSION, getCtsBuildInfo().getBuildId()));
         super.run();
     }
 
@@ -69,7 +72,7 @@
         trie.put(new Runnable() {
             @Override
             public void run() {
-                CtsBuildHelper ctsBuild = getCtsBuild();
+                CtsBuildHelper ctsBuild = getCtsBuildHelper();
                 if (ctsBuild != null) {
                     listPlans(ctsBuild);
                 }
@@ -78,7 +81,7 @@
         trie.put(new Runnable() {
             @Override
             public void run() {
-                CtsBuildHelper ctsBuild = getCtsBuild();
+                CtsBuildHelper ctsBuild = getCtsBuildHelper();
                 if (ctsBuild != null) {
                     listPackages(ctsBuild);
                 }
@@ -87,7 +90,7 @@
         trie.put(new Runnable() {
             @Override
             public void run() {
-                CtsBuildHelper ctsBuild = getCtsBuild();
+                CtsBuildHelper ctsBuild = getCtsBuildHelper();
                 if (ctsBuild != null) {
                     listResults(ctsBuild);
                 }
@@ -114,7 +117,7 @@
                 for (int i = 2; i < args.size(); i++) {
                     flatArgs[i - 2] = args.get(i).get(0);
                 }
-                CtsBuildHelper ctsBuild = getCtsBuild();
+                CtsBuildHelper ctsBuild = getCtsBuildHelper();
                 if (ctsBuild != null) {
                     // FIXME may want to only add certain ABIs
                     addDerivedPlan(ctsBuild, AbiUtils.getAbisSupportedByCts(), flatArgs);
@@ -230,22 +233,28 @@
         }
     }
 
-    private CtsBuildHelper getCtsBuild() {
-        if (mCtsBuild == null) {
-            String ctsInstallPath = System.getProperty("CTS_ROOT");
-            if (ctsInstallPath != null) {
-                mCtsBuild = new CtsBuildHelper(new File(ctsInstallPath));
-                try {
-                    mCtsBuild.validateStructure();
-                } catch (FileNotFoundException e) {
-                    printLine(String.format("Invalid cts install: %s", e.getMessage()));
-                    mCtsBuild = null;
-                }
-            } else {
+    private IFolderBuildInfo getCtsBuildInfo() {
+        if (mBuildInfo == null) {
+            try {
+                mBuildInfo = (IFolderBuildInfo) new CtsBuildProvider().getBuild();
+            } catch (IllegalArgumentException e) {
                 printLine("Could not find CTS install location: CTS_ROOT env variable not set");
             }
         }
-        return mCtsBuild;
+        return mBuildInfo;
+    }
+
+    private CtsBuildHelper getCtsBuildHelper() {
+        if (mBuildHelper == null) {
+            try {
+                mBuildHelper = new CtsBuildHelper(getCtsBuildInfo());
+                mBuildHelper.validateStructure();
+            } catch (FileNotFoundException e) {
+                printLine(String.format("Invalid cts install: %s", e.getMessage()));
+                mBuildHelper = null;
+            }
+        }
+        return mBuildHelper;
     }
 
     public static void main(String[] args) throws InterruptedException, ConfigurationException {
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 903ac74..61561a5 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
@@ -16,7 +16,11 @@
 package com.android.cts.tradefed.device;
 
 import com.android.cts.util.AbiUtils;
+import com.android.cts.tradefed.result.CtsXmlResultReporter;
+import com.android.ddmlib.IDevice;
 import com.android.ddmlib.Log;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.build.IFolderBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.result.ITestInvocationListener;
@@ -39,10 +43,21 @@
     private static final String APK_NAME = "TestDeviceSetup";
     public static final String APP_PACKAGE_NAME = "android.tests.devicesetup";
     private static final String INSTRUMENTATION_NAME = "android.tests.getinfo.DeviceInfoInstrument";
+
+    private static final String EXTENDED_APK_NAME = "CtsDeviceInfo";
+    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";
+    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()) {
             IDS.add(AbiUtils.createId(abi, APP_PACKAGE_NAME));
+            EXTENDED_IDS.add(AbiUtils.createId(abi, EXTENDED_APP_PACKAGE_NAME));
         }
     }
 
@@ -56,9 +71,37 @@
      */
     public static void collectDeviceInfo(ITestDevice device, String abi, File testApkDir,
             ITestInvocationListener listener) throws DeviceNotAvailableException {
-        File apkFile = new File(testApkDir, String.format("%s.apk", APK_NAME));
+        runInstrumentation(device, abi, testApkDir, listener, APK_NAME, APP_PACKAGE_NAME,
+            INSTRUMENTATION_NAME);
+    }
+
+    /**
+     * Installs and runs the extended device info collector instrumentation, and forwards results
+     * to the listener.
+     *
+     * @param device
+     * @param listener
+     * @throws DeviceNotAvailableException
+     */
+    public static void collectExtendedDeviceInfo(ITestDevice device, String abi, File testApkDir,
+            ITestInvocationListener listener, IBuildInfo buildInfo)
+            throws DeviceNotAvailableException {
+        // Clear files in device test result directory
+        String deviceResultDir = getDeviceResultDir(device);
+        device.executeShellCommand(String.format("rm -rf %s", deviceResultDir));
+        runInstrumentation(device, abi, testApkDir, listener, EXTENDED_APK_NAME,
+            EXTENDED_APP_PACKAGE_NAME, EXTENDED_INSTRUMENTATION_NAME);
+        // Copy files in remote result directory to local directory
+        pullExtendedDeviceInfoResults(device, buildInfo);
+    }
+
+    private static void runInstrumentation(ITestDevice device, String abi, File testApkDir,
+            ITestInvocationListener listener, String apkName, String packageName,
+            String instrumentName) throws DeviceNotAvailableException {
+        File apkFile = new File(testApkDir, String.format("%s.apk", apkName));
         if (!apkFile.exists()) {
             Log.e(LOG_TAG, String.format("Could not find %s", apkFile.getAbsolutePath()));
+            return;
         }
         // collect the instrumentation bundle results using instrumentation test
         // should work even though no tests will actually be run
@@ -67,9 +110,56 @@
         instrTest.setInstallFile(apkFile);
         // no need to collect tests and re-run
         instrTest.setRerunMode(false);
-        instrTest.setPackageName(APP_PACKAGE_NAME);
-        instrTest.setRunName(AbiUtils.createId(abi, APP_PACKAGE_NAME));
-        instrTest.setRunnerName(INSTRUMENTATION_NAME);
+        instrTest.setPackageName(packageName);
+        instrTest.setRunName(AbiUtils.createId(abi, packageName));
+        instrTest.setRunnerName(instrumentName);
         instrTest.run(listener);
     }
+
+    private static void pullExtendedDeviceInfoResults(ITestDevice device, IBuildInfo buildInfo)
+            throws DeviceNotAvailableException {
+        if (!(buildInfo instanceof IFolderBuildInfo)) {
+            Log.e(LOG_TAG, "Invalid instance of buildInfo");
+            return;
+        }
+        File localResultDir = new File(buildInfo.getBuildAttributes().get(
+                CtsXmlResultReporter.CTS_RESULT_DIR));
+        if (localResultDir == null || !localResultDir.isDirectory()) {
+            Log.e(LOG_TAG, "Local result directory is null or is not a directory");
+            return;
+        }
+
+        localResultDir = new File(localResultDir, DEVICE_INFO_FILES);
+        localResultDir.mkdirs();
+
+
+        String deviceResultDir = getDeviceResultDir(device);
+
+        // Pull files from device result directory to local result directory
+        String command = String.format("adb -s %s pull %s %s", device.getSerialNumber(),
+                deviceResultDir, localResultDir.getAbsolutePath());
+        if (!execute(command)) {
+            Log.e(LOG_TAG, String.format("Failed to run %s", command));
+        }
+    }
+
+    private static boolean execute(String command) {
+        try {
+            Process p = Runtime.getRuntime().exec(new String[] {"/bin/bash", "-c", command});
+            return (p.waitFor() == 0);
+        } catch (Exception e) {
+            Log.e(LOG_TAG, e);
+            return false;
+        }
+    }
+
+    private static String getDeviceResultDir(ITestDevice device) {
+        String externalStorePath = device.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+        if (externalStorePath == null) {
+            Log.e(LOG_TAG, String.format(
+                    "Failed to get external storage path on device %s", device.getSerialNumber()));
+            return null;
+        }
+        return String.format("%s/%s", externalStorePath, DEVICE_INFO_FILES);
+    }
 }
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 5029dfe..b7f064f 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
@@ -43,6 +43,7 @@
     private TestResults mResults = new TestResults();
     private TestPackageResult mCurrentPkgResult = null;
     private boolean mIsDeviceInfoRun = false;
+    private boolean mIsExtendedDeviceInfoRun = false;
 
     @Override
     public void invocationStarted(IBuildInfo buildInfo) {
@@ -63,8 +64,11 @@
             logCompleteRun(mCurrentPkgResult);
         }
         mIsDeviceInfoRun = DeviceInfoCollector.IDS.contains(id);
+        mIsExtendedDeviceInfoRun = DeviceInfoCollector.EXTENDED_IDS.contains(id);
         if (mIsDeviceInfoRun) {
             logResult("Collecting device info");
+        } else if (mIsExtendedDeviceInfoRun) {
+            logResult("Collecting extended device info");
         } else  {
             if (mCurrentPkgResult == null || !id.equals(mCurrentPkgResult.getId())) {
                 logResult("-----------------------------------------");
@@ -132,9 +136,13 @@
     }
 
     private void logCompleteRun(TestPackageResult pkgResult) {
-        if (pkgResult.getAppPackageName().equals(DeviceInfoCollector.APP_PACKAGE_NAME)) {
+        String appPackageName = pkgResult.getAppPackageName();
+        if (appPackageName.equals(DeviceInfoCollector.APP_PACKAGE_NAME)) {
             logResult("Device info collection complete");
             return;
+        } else if (appPackageName.equals(DeviceInfoCollector.EXTENDED_APP_PACKAGE_NAME)) {
+            logResult("Extended device info collection complete");
+            return;
         }
         logResult("%s package complete: Passed %d, Failed %d, Not Executed %d",
                 pkgResult.getId(), pkgResult.countTests(CtsTestStatus.PASS),
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 8cb4072..3efc7fc 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
@@ -25,7 +25,6 @@
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.build.IFolderBuildInfo;
 import com.android.tradefed.config.Option;
-import com.android.tradefed.config.Option.Importance;
 import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.result.ILogSaver;
 import com.android.tradefed.result.ILogSaverListener;
@@ -42,6 +41,7 @@
 import org.kxml2.io.KXmlSerializer;
 
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -62,6 +62,7 @@
 
     private static final String LOG_TAG = "CtsXmlResultReporter";
 
+    public static final String CTS_RESULT_DIR = "cts-result-dir";
     static final String TEST_RESULT_FILE_NAME = "testResult.xml";
     static final String CTS_RESULT_FILE_VERSION = "4.4";
     private static final String[] CTS_RESULT_RESOURCES = {"cts_result.xsl", "cts_result.css",
@@ -97,6 +98,9 @@
     @Option(name = "include-test-log-tags", description = "Include test log tags in XML report.")
     private boolean mIncludeTestLogTags = false;
 
+    @Option(name = "use-log-saver", description = "Also saves generated result XML with log saver")
+    private boolean mUseLogSaver = false;
+
     protected IBuildInfo mBuildInfo;
     private String mStartTime;
     private String mDeviceSerial;
@@ -104,10 +108,12 @@
     private TestPackageResult mCurrentPkgResult = null;
     private Test mCurrentTest = null;
     private boolean mIsDeviceInfoRun = false;
+    private boolean mIsExtendedDeviceInfoRun = false;
     private ResultReporter mReporter;
     private File mLogDir;
     private String mSuiteName;
     private String mReferenceUrl;
+    private ILogSaver mLogSaver;
 
     public void setReportDir(File reportDir) {
         mReportDir = reportDir;
@@ -155,6 +161,8 @@
         mSuiteName = ctsBuildHelper.getSuiteName();
         mReporter = new ResultReporter(mResultServer, mSuiteName);
 
+        ctsBuild.addBuildAttribute(CTS_RESULT_DIR, mReportDir.getAbsolutePath());
+
         // TODO: allow customization of log dir
         // create a unique directory for saving logs, with same name as result dir
         File rootLogDir = getBuildHelper(ctsBuild).getLogsDir();
@@ -249,13 +257,14 @@
 
     @Override
     public void setLogSaver(ILogSaver logSaver) {
-      // Don't need to keep a reference to logSaver, because we don't save extra logs in this class.
+        mLogSaver = logSaver;
     }
 
     @Override
     public void testRunStarted(String id, int numTests) {
         mIsDeviceInfoRun = DeviceInfoCollector.IDS.contains(id);
-        if (!mIsDeviceInfoRun) {
+        mIsExtendedDeviceInfoRun = DeviceInfoCollector.EXTENDED_IDS.contains(id);
+        if (!mIsDeviceInfoRun && !mIsExtendedDeviceInfoRun) {
             mCurrentPkgResult = mResults.getOrCreatePackage(id);
             mCurrentPkgResult.setDeviceSerial(mDeviceSerial);
         }
@@ -266,7 +275,7 @@
      */
     @Override
     public void testStarted(TestIdentifier test) {
-        if (!mIsDeviceInfoRun) {
+        if (!mIsDeviceInfoRun && !mIsExtendedDeviceInfoRun) {
             mCurrentTest = mCurrentPkgResult.insertTest(test);
         }
     }
@@ -276,7 +285,7 @@
      */
     @Override
     public void testFailed(TestIdentifier test, String trace) {
-        if (!mIsDeviceInfoRun) {
+        if (!mIsDeviceInfoRun && !mIsExtendedDeviceInfoRun) {
             mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
         }
     }
@@ -287,7 +296,7 @@
     @Override
     public void testAssumptionFailure(TestIdentifier test, String trace) {
         // TODO: do something different here?
-        if (!mIsDeviceInfoRun) {
+        if (!mIsDeviceInfoRun && !mIsExtendedDeviceInfoRun) {
             mCurrentPkgResult.reportTestFailure(test, CtsTestStatus.FAIL, trace);
         }
     }
@@ -305,7 +314,7 @@
      */
     @Override
     public void testEnded(TestIdentifier test, Map<String, String> testMetrics) {
-        if (!mIsDeviceInfoRun) {
+        if (!mIsDeviceInfoRun && !mIsExtendedDeviceInfoRun) {
             mCurrentPkgResult.reportTestEnded(test, testMetrics);
         }
     }
@@ -317,11 +326,22 @@
     public void testRunEnded(long elapsedTime, Map<String, String> runMetrics) {
         if (mIsDeviceInfoRun) {
             mResults.populateDeviceInfoMetrics(runMetrics);
+        } else if (mIsExtendedDeviceInfoRun) {
+            checkExtendedDeviceInfoMetrics(runMetrics);
         } else {
             mCurrentPkgResult.populateMetrics(runMetrics);
         }
     }
 
+    private void checkExtendedDeviceInfoMetrics(Map<String, String> runMetrics) {
+        for (Map.Entry<String, String> metricEntry : runMetrics.entrySet()) {
+            String value = metricEntry.getValue();
+            if (!value.endsWith(".deviceinfo.json")) {
+                CLog.e(String.format("%s failed: %s", metricEntry.getKey(), value));
+            }
+        }
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -335,6 +355,18 @@
 
         File reportFile = getResultFile(mReportDir);
         createXmlResult(reportFile, mStartTime, elapsedTime);
+        if (mUseLogSaver) {
+            FileInputStream fis = null;
+            try {
+                fis = new FileInputStream(reportFile);
+                mLogSaver.saveLogData("cts-result", LogDataType.XML, fis);
+            } catch (IOException ioe) {
+                CLog.e("error saving XML with log saver");
+                CLog.e(ioe);
+            } finally {
+                StreamUtil.close(fis);
+            }
+        }
         copyFormattingFiles(mReportDir);
         zipResults(mReportDir);
 
@@ -400,7 +432,10 @@
         serializer.attribute(ns, "endtime", endTime);
         serializer.attribute(ns, "version", CTS_RESULT_FILE_VERSION);
         serializer.attribute(ns, "suite", mSuiteName);
-        mResults.serialize(serializer);
+        if (mReferenceUrl != null) {
+            serializer.attribute(ns, "referenceUrl", mReferenceUrl);
+        }
+        mResults.serialize(serializer, mBuildInfo.getBuildId());
         // TODO: not sure why, but the serializer doesn't like this statement
         //serializer.endTag(ns, RESULT_TAG);
     }
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 f5a3d02..45224f6 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
@@ -254,12 +254,12 @@
             if (perfResult == null) {
                 perfResult = CtsHostStore.removeCtsResult(mDeviceSerial, mAbi, test.toString());
             }
-            if (perfResult != null) {
+            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()) {
-                    Test result = findTest(test);
                     result.setResultStatus(CtsTestStatus.PASS);
                     result.setSummary(m.group(1));
                     result.setDetails(m.group(2));
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 8c1a5bd..9f67f2d 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
@@ -104,9 +104,9 @@
      * @param serializer
      * @throws IOException
      */
-    public void serialize(KXmlSerializer serializer) throws IOException {
+    public void serialize(KXmlSerializer serializer, String buildId) throws IOException {
         mDeviceInfo.serialize(serializer);
-        serializeHostInfo(serializer);
+        serializeHostInfo(serializer, buildId);
         serializeTestSummary(serializer);
         // sort before serializing
         List<TestPackageResult> pkgs = new ArrayList<TestPackageResult>(mPackageResults.values());
@@ -121,7 +121,7 @@
      *
      * @param serializer
      */
-    private void serializeHostInfo(KXmlSerializer serializer) throws IOException {
+    private void serializeHostInfo(KXmlSerializer serializer, String buildId) throws IOException {
         serializer.startTag(ns, "HostInfo");
 
         String hostName = "";
@@ -143,6 +143,7 @@
 
         serializer.startTag(ns, "Cts");
         serializer.attribute(ns, "version", CtsBuildProvider.CTS_BUILD_VERSION);
+        serializer.attribute(ns, "build", buildId);
         // TODO: consider outputting other tradefed options here
         serializer.startTag(ns, "IntValue");
         serializer.attribute(ns, "name", "testStatusTimeoutMs");
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsApkInstaller.java b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsApkInstaller.java
new file mode 100644
index 0000000..08061b1
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsApkInstaller.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.targetprep;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+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 CTS test case repository
+ */
+@OptionClass(alias="cts-apk-installer")
+public class CtsApkInstaller extends TestAppInstallSetup {
+
+    private CtsBuildHelper mBuildHelper = null;
+
+    protected CtsBuildHelper getCtsBuildHelper(IBuildInfo buildInfo) {
+        if (mBuildHelper == null) {
+            mBuildHelper = CtsBuildHelper.createBuildHelper(buildInfo);
+        }
+        return mBuildHelper;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected File getLocalPathForFilename(IBuildInfo buildInfo, String apkFileName)
+            throws TargetSetupError {
+        try {
+            return getCtsBuildHelper(buildInfo).getTestApp(apkFileName);
+        } catch (FileNotFoundException e) {
+            throw new TargetSetupError(String.format("apk not found: %s", apkFileName), e);
+        }
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsFilePusher.java b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsFilePusher.java
new file mode 100644
index 0000000..c6ae2e1
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/CtsFilePusher.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 com.android.cts.tradefed.targetprep;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.config.OptionClass;
+import com.android.tradefed.targetprep.PushFilePreparer;
+
+import java.io.File;
+
+/**
+ * Pushes specified testing artifacts from CTS test case repository
+ */
+@OptionClass(alias="cts-file-pusher")
+public class CtsFilePusher extends PushFilePreparer {
+
+    private CtsBuildHelper mBuildHelper;
+
+    protected CtsBuildHelper getCtsBuildHelper(IBuildInfo buildInfo) {
+        if (mBuildHelper == null) {
+            mBuildHelper = CtsBuildHelper.createBuildHelper(buildInfo);
+        }
+        return mBuildHelper;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public File resolveRelativeFilePath(IBuildInfo buildInfo, String fileName) {
+        return new File(getCtsBuildHelper(buildInfo).getTestCasesDir(), fileName);
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/DevicePreconditionPreparer.java b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/DevicePreconditionPreparer.java
new file mode 100644
index 0000000..039470b
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/DevicePreconditionPreparer.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.targetprep;
+
+import com.android.cts.tradefed.build.CtsBuildHelper;
+import com.android.cts.tradefed.testtype.Abi;
+import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.build.IBuildInfo;
+import com.android.tradefed.build.IFolderBuildInfo;
+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.result.InputStreamSource;
+import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.result.LogDataType;
+import com.android.tradefed.result.TestSummary;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.InstrumentationTest;
+import com.android.tradefed.targetprep.BuildError;
+import com.android.tradefed.targetprep.ITargetPreparer;
+import com.android.tradefed.targetprep.TargetSetupError;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * A {@link ITargetPreparer} that performs precondition checks on the device-side for CTS.
+ * <p/>
+ * This class instruments an APK containing tests verifying that the device meets CTS
+ * preconditions. At present, the APK contains tests to ensure that the device's screen is not
+ * locked, and that the device's external storage is present and writable. The test lives under
+ * //cts/tools/tradefed-host/preconditions, and can be modified to perform further checks and tasks
+ * from the device-side.
+ */
+@OptionClass(alias="device-precondition-preparer")
+public class DevicePreconditionPreparer implements ITargetPreparer {
+
+    /* This option also exists in the HostPreconditionPreparer */
+    @Option(name = "skip-preconditions",
+            description = "Whether to skip precondition checks and automation")
+    protected boolean mSkipPreconditions = false;
+
+    /* Constants for the InstrumentationTest */
+    private static final String APK_NAME = "CtsPreconditionsApp.apk";
+    private static final String PACKAGE_NAME = "com.android.cts.preconditions";
+    private static final String RUNNER_NAME = "android.support.test.runner.AndroidJUnitRunner";
+
+    /* Map used to track test failures */
+    private ConcurrentHashMap<TestIdentifier, String> testFailures = new ConcurrentHashMap<>();
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setUp(ITestDevice device, IBuildInfo buildInfo) throws TargetSetupError,
+            BuildError, DeviceNotAvailableException {
+        if (mSkipPreconditions) {
+            return; // skipping device-side preconditions
+        }
+
+        try {
+            if (!instrument(device, buildInfo)) {
+                throw new TargetSetupError("Not all device-side preconditions met");
+            }
+        } catch (FileNotFoundException e) {
+            throw new TargetSetupError(
+                    String.format("Couldn't find %s to instrument", APK_NAME), e);
+        }
+    }
+
+    /* Instruments the APK on the device, and logs precondition test failures, if any are found.
+     * Returns true if all tests pass, and otherwise returns false */
+    private boolean instrument(ITestDevice device, IBuildInfo buildInfo)
+            throws DeviceNotAvailableException, FileNotFoundException {
+        ITestInvocationListener listener = new PreconditionPreparerListener();
+        CtsBuildHelper mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
+        File apkFile = mCtsBuild.getTestApp(APK_NAME); // get the APK file with the CtsBuildHelper
+        InstrumentationTest instrTest = new InstrumentationTest();
+        instrTest.setDevice(device);
+        instrTest.setInstallFile(apkFile);
+        instrTest.setPackageName(PACKAGE_NAME);
+        instrTest.setRunnerName(RUNNER_NAME);
+        instrTest.run(listener);
+        boolean success = true;
+        if (!testFailures.isEmpty()) {
+            success = false; // at least one precondition has failed
+            for (TestIdentifier test : testFailures.keySet()) {
+                String trace = testFailures.get(test);
+                CLog.e("Precondition test %s failed.\n%s", test.getTestName(), trace);
+            }
+        }
+        return success;
+    }
+
+    /**
+     * The PreconditionPreparerListener is an implementation of ITestInvocationListener
+     * that adds entries to the ConcurrentHashMap 'testFailures' of the outer class whenever
+     * a test fails. The listener also logs information if the test run fails, for debugging
+     * purposes.
+     */
+    public class PreconditionPreparerListener implements ITestInvocationListener {
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void testFailed(TestIdentifier test, String trace) {
+            testFailures.put(test, trace);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void testRunFailed(String errorMessage) {
+            CLog.e("Device-side preconditions test run failed: %s", errorMessage);
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void testEnded(TestIdentifier test, Map<String, String> metrics) {}
+
+        /**
+         * {@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 testAssumptionFailure(TestIdentifier test, String trace) {}
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void testIgnored(TestIdentifier test) {}
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void testRunStopped(long elapsedTime) {}
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void testRunEnded(long elapsedTime, Map<String, String> runMetrics) {}
+    }
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparer.java b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparer.java
new file mode 100644
index 0000000..8998f16
--- /dev/null
+++ b/tools/tradefed-host/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparer.java
@@ -0,0 +1,538 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.targetprep;
+
+import com.android.ddmlib.IDevice;
+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.ITargetPreparer;
+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.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipFile;
+
+/**
+ * A {@link ITargetPreparer} that performs steps on the host-side to meet the preconditions of CTS.
+ * <p/>
+ * This class is intended for runs of CTS against a device running a user build.
+ * <p/>
+ * This class performs checks to verify that the location services are on, WiFi is connected,
+ * the device locale is set to 'en-US', and that the device runs a user build. The class also
+ * performs automation to ensure that 3rd party app installs are enabled, the 'Stay Awake' setting
+ * is turned on, and that the appropriate media files are pushed to the device for the media tests.
+ * Additionally, options are provided for automatically connecting to a specific WiFi network.
+ */
+@OptionClass(alias="host-precondition-preparer")
+public class HostPreconditionPreparer implements ITargetPreparer {
+
+    /* This option also exists in the DevicePreconditionPreparer */
+    @Option(name = "skip-preconditions",
+            description = "Whether to skip precondition checks and automation")
+    protected boolean mSkipPreconditions = false;
+
+    @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 option 'wifi-ssid'")
+    protected String mWifiPsk = null;
+
+    @Option(name = "skip-media-download",
+            description = "Whether to skip verifying/downloading media files")
+    protected boolean mSkipMediaDownload = false;
+
+    @Option(name = "local-media-path",
+            description = "Absolute path of the media files directory on the host, containing" +
+            "'bbb_short' and 'bbb_full' directories")
+    protected String mLocalMediaPath = null;
+
+    private static final String LOG_TAG = HostPreconditionPreparer.class.getSimpleName();
+
+    private static final String WIFI_FEATURE = "android.hardware.wifi";
+    private static final String LOCATION_GPS_FEATURE = "android.hardware.location.gps";
+    private static final String LOCATION_NETWORK_FEATURE = "android.hardware.location.network";
+
+    /* Constants found in android.provider.Settings */
+    protected static final String STAY_ON_WHILE_PLUGGED_IN = "stay_on_while_plugged_in";
+    protected static final String PACKAGE_VERIFIER_INCLUDE_ADB = "verifier_verify_adb_installs";
+    protected static final String LOCATION_PROVIDERS_ALLOWED = "location_providers_allowed";
+    /* Constant from android.os.BatteryManager */
+    private static final int BATTERY_PLUGGED_USB = 2;
+
+    /* Name and expected value of the device's locale property */
+    private static final String LOCALE_PROPERTY_STRING = "ro.product.locale";
+    private static final String US_EN_LOCALE_STRING = "en-US";
+    /* Name and expected value of the device's build type property */
+    private static final String BUILD_TYPE_PROPERTY_STRING = "ro.build.type";
+    private static final String USER_BUILD_STRING = "user";
+
+    /* Logged if the preparer fails to identify the device's maximum video playback resolution */
+    private static final String MAX_PLAYBACK_RES_FAILURE_MSG =
+            "Unable to parse maximum video playback resolution, pushing all media files";
+
+    /*
+     * The URL from which to download the compressed media files
+     * TODO: Find a way to retrieve this programmatically
+     */
+    private static final String MEDIA_URL_STRING =
+            "https://dl.google.com/dl/android/cts/android-cts-media-1.1.zip";
+
+    /*
+     * A default name for the local directory into which media files will be downloaded, if option
+     * "local-media-path" is not provided. This name is intentionally predetermined and final, so
+     * that when running CTS repeatedly, media files downloaded to the host in a previous run of
+     * CTS can be found in this directory, which will live inside the local temp directory.
+     */
+    private static final String MEDIA_FOLDER_NAME = "android-cts-media";
+
+    /* Constants identifying video playback 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; // 480x360, the default max playback resolution
+    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
+
+    /* Array of Dimensions aligning with and corresponding to the resolution constants above */
+    protected static final Dimension[] resolutions = {
+            new Dimension(176, 144),
+            new Dimension(480, 360),
+            new Dimension(720, 480),
+            new Dimension(1280, 720),
+            new Dimension(1920, 1080)
+    };
+
+    /*********************************************************************************************
+     * HELPER METHODS
+     *********************************************************************************************/
+
+    /* Helper that logs a message with LogLevel.INFO */
+    private static void printInfo(String msg) {
+        LogUtil.printLog(Log.LogLevel.INFO, LOG_TAG, msg);
+    }
+
+    /* Helper that logs a message with LogLevel.WARN */
+    private static void printWarning(String msg) {
+        LogUtil.printLog(Log.LogLevel.WARN, LOG_TAG, msg);
+    }
+
+    /* Helper that determines whether the device supports a feature */
+    private boolean hasFeature(ITestDevice device, String feature)
+            throws DeviceNotAvailableException {
+        String pmFeatures = device.executeShellCommand("pm list features");
+        return pmFeatures.contains(feature);
+    }
+
+    /*
+     * Returns a string representation of the dimension
+     * For dimension of width = 480 and height = 360, the resolution string is "480x360"
+     */
+    protected static String resolutionString(Dimension resolution) {
+        return String.format("%dx%d", resolution.width, resolution.height);
+    }
+
+    /*
+     * Returns the device's absolute path to the directory containing 'short' media files, given
+     * a resolution. The instance of ITestDevice is used to identify the mount point for
+     * external storage.
+     */
+    protected String getDeviceShortDir(ITestDevice device, Dimension resolution) {
+        String mountPoint = device.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+        return String.format("%s/test/bbb_short/%s", mountPoint, resolutionString(resolution));
+    }
+
+    /*
+     * Returns the device's absolute path to the directory containing 'full' media files, given
+     * a resolution. The instance of ITestDevice is used to identify the mount point for
+     * external storage.
+     */
+    protected String getDeviceFullDir(ITestDevice device, Dimension resolution) {
+        String mountPoint = device.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE);
+        return String.format("%s/test/bbb_full/%s", mountPoint, resolutionString(resolution));
+    }
+
+    /*
+     * 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 of the 'smallest app' field is used as an estimate for
+     * maximum video playback resolution, and is rounded down to the nearest dimension in the
+     * resolutions array.
+     */
+    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
+            printInfo(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) {
+            // match was found, but not an identifiable resolution
+            printInfo(MAX_PLAYBACK_RES_FAILURE_MSG);
+            return resolutions[RES_1920_1080];
+        }
+        // ensure that the larger of the two values found is assigned to 'width'
+        int height = Math.min(first, second);
+        int width = Math.max(first, second);
+        return getMaxVideoPlaybackResolution(width, height);
+    }
+
+    /*
+     * 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 predefined url MEDIA_URL_STRING.
+     * The compressed file is downloaded and unzipped into mLocalMediaPath.
+     */
+    private void downloadMediaToHost() throws TargetSetupError {
+
+        URL url;
+        try {
+            url = new URL(MEDIA_URL_STRING);
+        } catch (MalformedURLException e) {
+            throw new TargetSetupError(
+                    String.format("Trouble finding android media files at %s", MEDIA_URL_STRING));
+        }
+
+        File mediaFolder = new File(mLocalMediaPath);
+        File mediaFolderZip = new File(mediaFolder.getAbsolutePath() + ".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;
+            printInfo("Downloading media files to host");
+            while ((count = in.read(buffer)) >= 0) {
+                out.write(buffer, 0, count);
+            }
+            out.flush();
+            out.close();
+            in.close();
+
+            printInfo("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
+     */
+    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) {
+                printInfo(String.format(
+                        "Device cannot support resolutions %s and larger, media copying complete",
+                        resString));
+                return;
+            }
+            String deviceShortFilePath = getDeviceShortDir(device, copiedResolution);
+            String deviceFullFilePath = getDeviceFullDir(device, copiedResolution);
+            if (!device.doesFileExist(deviceShortFilePath) ||
+                    !device.doesFileExist(deviceFullFilePath)) {
+                printInfo(String.format("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++;
+        }
+    }
+
+    /*
+     * Returns true if all media files of a resolution less than or equal to 'mvpr' exist on the
+     * device, and otherwise returns false.
+     */
+    private 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 deviceShortFilePath = getDeviceShortDir(device, copiedResolution);
+            String deviceFullFilePath = getDeviceFullDir(device, copiedResolution);
+            if (!device.doesFileExist(deviceShortFilePath) ||
+                    !device.doesFileExist(deviceFullFilePath)) {
+                // media files of valid resolution not found on the device, and must be pushed
+                return false;
+            }
+            resIndex++;
+        }
+        return true;
+    }
+
+    /* Static method that returns a directory called 'dirName' in the system's temp directory */
+    private static File createSimpleTempDir(String dirName) throws IOException {
+        // find system's temp directory
+        File throwaway = File.createTempFile(dirName, null);
+        String systemTempDir = throwaway.getParent();
+        // create directory with simple name within temp directory
+        File simpleTempDir = new File(systemTempDir, dirName);
+        // delete file used to find temp directory
+        throwaway.delete();
+        return simpleTempDir;
+    }
+
+    /* Method that creates a local media path, and ensures that the necessary media files live
+     * within that path */
+    private void createLocalMediaPath() throws TargetSetupError {
+        File mediaFolder;
+        try {
+            mediaFolder = createSimpleTempDir(MEDIA_FOLDER_NAME);
+        } 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 or filled by previous runs of MediaPreparer
+            downloadMediaToHost(); //download media into mLocalMediaPath
+        }
+        updateLocalMediaPath(mediaFolder);
+    }
+
+    /*********************************************************************************************
+     * PRECONDITION METHODS
+     *********************************************************************************************/
+
+    /**
+     * Prevents the screen from sleeping while charging via USB
+     */
+    protected void enableStayAwakeSetting(ITestDevice device) throws DeviceNotAvailableException {
+        String shellCmd = String.format("settings put global %s %d",
+                STAY_ON_WHILE_PLUGGED_IN, BATTERY_PLUGGED_USB);
+        device.executeShellCommand(shellCmd);
+    }
+
+    /**
+     * Prevents package verification on apps installed through ADB/ADT/USB
+     */
+    protected void disableAdbAppVerification(ITestDevice device)
+            throws DeviceNotAvailableException {
+        String shellCmd = String.format("settings put global %s 0", PACKAGE_VERIFIER_INCLUDE_ADB);
+        device.executeShellCommand(shellCmd);
+    }
+
+    /**
+     * Prevents the keyguard from re-emerging during the CTS test, which can cause some failures
+     * Note: the shell command run here is not supported on L
+     */
+    protected void disableKeyguard(ITestDevice device) throws DeviceNotAvailableException {
+        device.executeShellCommand("wm disable-keyguard");
+    }
+
+    /**
+     * Prints a warning if the device's locale is something other than US English, as some tests
+     * may pass or fail depending on the 'en-US' locale.
+     */
+    protected void verifyLocale(ITestDevice device) throws DeviceNotAvailableException {
+        String locale = device.getProperty(LOCALE_PROPERTY_STRING);
+        if (locale == null) {
+            printWarning(String.format("Property %s not found on device", LOCALE_PROPERTY_STRING));
+            return;
+        }
+        if (!locale.equalsIgnoreCase(US_EN_LOCALE_STRING)) {
+            printWarning(String.format("Expected locale en-US, detected locale \"%s\"", locale));
+        }
+    }
+
+    /**
+     * Prints a warning if the device is not running a user build. This is not allowed for
+     * testing production devices, but should not block testers from running CTS on a userdebug
+     * build.
+     */
+    protected void verifyUserBuild(ITestDevice device) throws DeviceNotAvailableException {
+        String buildType = device.getProperty(BUILD_TYPE_PROPERTY_STRING);
+        if (buildType == null) {
+            printWarning(
+                    String.format("Property %s not found on device", BUILD_TYPE_PROPERTY_STRING));
+            return;
+        }
+        if (!buildType.equalsIgnoreCase(USER_BUILD_STRING)) {
+            printWarning(String.format("Expected user build, detected type \"%s\"", buildType));
+        }
+    }
+
+    /**
+     * Throws a TargetSetupError if location services are not enabled by gps or a network
+     */
+    protected void checkLocationServices(ITestDevice device)
+            throws DeviceNotAvailableException, TargetSetupError {
+
+        String shellCmd = String.format("settings get secure %s", LOCATION_PROVIDERS_ALLOWED);
+        String locationServices = device.executeShellCommand(shellCmd);
+        if (!locationServices.contains("gps") && !locationServices.contains("network")) {
+            // location services are not enabled by gps nor by the network
+            throw new TargetSetupError(
+                    "Location services must be enabled for several CTS test packages");
+        }
+    }
+
+    /**
+     * Throws a TargetSetupError if the device is not connected to a WiFi network. Testers can
+     * optionally supply a 'wifi-ssid' and 'wifi-psk' (in the options above) to attempt connection
+     * to a specific network.
+     */
+    protected void runWifiPrecondition(ITestDevice device)
+            throws TargetSetupError, DeviceNotAvailableException {
+
+        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 if needed
+            if (!device.connectToWifiNetworkIfNeeded(mWifiSsid, mWifiPsk)) {
+                throw new TargetSetupError("Unable to establish network connection," +
+                        "some CTS packages require an active network connection");
+            }
+        }
+    }
+
+    /**
+     * Checks that media files for the mediastress tests are present on the device, and if not,
+     * pushes them onto the device.
+     */
+    protected void runMediaPrecondition(ITestDevice device)
+            throws TargetSetupError, DeviceNotAvailableException {
+        if (mSkipMediaDownload) {
+            return; // skip this precondition
+        }
+        Dimension mvpr = getMaxVideoPlaybackResolution(device);
+        if (mediaFilesExistOnDevice(device, mvpr)) {
+            return; // media files already found on the device
+        }
+        if (mLocalMediaPath == null) {
+            createLocalMediaPath(); // make new path on host containing media files
+        }
+        printInfo(String.format("Media files located on host at: %s", mLocalMediaPath));
+        copyMediaFiles(device, mvpr);
+    }
+
+    public void setUp(ITestDevice device, IBuildInfo buildInfo)
+            throws TargetSetupError, BuildError, DeviceNotAvailableException {
+        if (mSkipPreconditions) {
+            return; // skipping host-side preconditions
+        }
+
+        /* run each host-side precondition */
+        enableStayAwakeSetting(device);
+        disableAdbAppVerification(device);
+        disableKeyguard(device);
+        verifyLocale(device);
+        verifyUserBuild(device);
+
+        if (hasFeature(device, LOCATION_NETWORK_FEATURE) ||
+                hasFeature(device, LOCATION_GPS_FEATURE)) {
+            checkLocationServices(device); // only check location services if supported
+        }
+
+        if (hasFeature(device, WIFI_FEATURE)) {
+            runWifiPrecondition(device); // check wifi precondition only if device supports wifi
+        }
+
+        runMediaPrecondition(device);
+    }
+
+}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/AccessibilityServiceTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/AccessibilityServiceTestRunner.java
deleted file mode 100644
index eafd608..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/AccessibilityServiceTestRunner.java
+++ /dev/null
@@ -1,91 +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.tradefed.testtype;
-
-import com.android.cts.util.AbiUtils;
-import com.android.ddmlib.Log;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.util.FileUtil;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-
-/**
- * Running the accessibility tests requires modification of secure
- * settings. Secure settings cannot be changed from device CTS tests
- * since system signature permission is required. Such settings can
- * be modified by the shell user, so a host side test is used for
- * installing a package with a delegating accessibility service, enabling
- * this service, running these tests, disabling the service, and removing
- * the delegating accessibility service package.
- *
- * @deprecated This class is not required in current CTS builds. Still
- * maintained so cts-tradefed can run against older CTS builds that still
- * require this class.
- */
-@Deprecated
-public class AccessibilityServiceTestRunner extends CtsInstrumentationApkTest {
-
-    private static final String LOG_TAG = AccessibilityServiceTestRunner.class.getSimpleName();
-
-    private static final String DELEGATING_ACCESSIBLITY_SERVICE_PACKAGE_NAME =
-        "android.accessibilityservice.delegate";
-
-    private static final String DELEGATING_ACCESSIBLITY_SERVICE_NAME =
-        "android.accessibilityservice.delegate.DelegatingAccessibilityService";
-
-    private static final String DELEGATING_ACCESSIBLITY_SERVICE_APK =
-        "CtsDelegatingAccessibilityService.apk";
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        beforeTest();
-        super.run(listener);
-        afterTest();
-    }
-
-    private void beforeTest() throws DeviceNotAvailableException {
-        installApkAndAssert(DELEGATING_ACCESSIBLITY_SERVICE_APK);
-        enableAccessibilityAndDelegatingService();
-    }
-
-    private void afterTest() throws DeviceNotAvailableException {
-        AccessibilityTestRunner.disableAccessibilityAndServices(getDevice());
-        uninstallAndAssert(DELEGATING_ACCESSIBLITY_SERVICE_PACKAGE_NAME);
-    }
-
-    private void installApkAndAssert(String apkName) throws DeviceNotAvailableException {
-        File file = FileUtil.getFileForPath(mCtsBuild.getTestCasesDir(), apkName);
-        String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-        String errorMessage = getDevice().installPackage(file, true, options);
-        TestCase.assertNull("Error installing: " + apkName, errorMessage);
-    }
-
-    private void uninstallAndAssert(String packageName) throws DeviceNotAvailableException {
-        String errorMessage = getDevice().uninstallPackage(packageName);
-        TestCase.assertNull("Error uninstalling: " + packageName, errorMessage);
-    }
-
-    private void enableAccessibilityAndDelegatingService() throws DeviceNotAvailableException {
-        String componentName = DELEGATING_ACCESSIBLITY_SERVICE_PACKAGE_NAME + "/"
-            + DELEGATING_ACCESSIBLITY_SERVICE_NAME;
-        AccessibilityTestRunner.enableAccessibilityAndServices(getDevice(),
-                componentName);
-    }
-}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/AccessibilityTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/AccessibilityTestRunner.java
deleted file mode 100644
index 9ba4109..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/AccessibilityTestRunner.java
+++ /dev/null
@@ -1,108 +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.tradefed.testtype;
-
-import com.android.cts.tradefed.targetprep.SettingsToggler;
-import com.android.cts.util.AbiUtils;
-import com.android.ddmlib.Log;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.device.ITestDevice;
-import com.android.tradefed.result.ITestInvocationListener;
-import com.android.tradefed.util.FileUtil;
-
-import junit.framework.TestCase;
-
-import java.io.File;
-
-/**
- * Running the accessibility tests requires modification of secure
- * settings. Secure settings cannot be changed from device CTS tests
- * since system signature permission is required. Such settings can
- * be modified by the shell user, so a host side test is used for
- * installing a package with some accessibility services, enabling
- * these services, running the tests, disabling the services, and removing
- * the accessibility services package.
- */
-public class AccessibilityTestRunner extends CtsInstrumentationApkTest {
-
-    private static final String LOG_TAG = AccessibilityTestRunner.class.getSimpleName();
-
-    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 static final String SOME_ACCESSIBLITY_SERVICES_APK =
-        "CtsSomeAccessibilityServices.apk";
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        beforeTest();
-        super.run(listener);
-        afterTest();
-    }
-
-    private void beforeTest() throws DeviceNotAvailableException {
-        installApkAndAssert(SOME_ACCESSIBLITY_SERVICES_APK);
-        enableAccessibilityAndServices();
-    }
-
-    private void afterTest() throws DeviceNotAvailableException {
-        disableAccessibilityAndServices(getDevice());
-        uninstallAndAssert(SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME);
-    }
-
-    private void installApkAndAssert(String apkName) throws DeviceNotAvailableException {
-        File file = FileUtil.getFileForPath(mCtsBuild.getTestCasesDir(), apkName);
-        String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-        String errorMessage = getDevice().installPackage(file, true, options);
-        TestCase.assertNull("Error installing: " + apkName, errorMessage);
-    }
-
-    private void uninstallAndAssert(String packageName) throws DeviceNotAvailableException {
-        String errorMessage = getDevice().uninstallPackage(packageName);
-        TestCase.assertNull("Error uninstalling: " + packageName, errorMessage);
-    }
-
-    private void enableAccessibilityAndServices() throws DeviceNotAvailableException {
-        String enabledServicesValue =
-              SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME + "/" + SPEAKING_ACCESSIBLITY_SERVICE_NAME
-            + ":"
-            + SOME_ACCESSIBLITY_SERVICES_PACKAGE_NAME + "/" + VIBRATING_ACCESSIBLITY_SERVICE_NAME;
-        enableAccessibilityAndServices(getDevice(), enabledServicesValue);
-    }
-
-    static void enableAccessibilityAndServices(ITestDevice device, String value)
-            throws DeviceNotAvailableException {
-        SettingsToggler.setSecureString(device, "enabled_accessibility_services", value);
-        SettingsToggler.setSecureString(device,
-                "touch_exploration_granted_accessibility_services", value);
-        SettingsToggler.setSecureInt(device, "accessibility_enabled", 1);
-    }
-
-    static void disableAccessibilityAndServices(ITestDevice device)
-            throws DeviceNotAvailableException {
-        SettingsToggler.updateSecureString(device, "enabled_accessibility_services", "");
-        SettingsToggler.updateSecureString(device,
-                "touch_exploration_granted_accessibility_services", "");
-        SettingsToggler.updateSecureInt(device, "accessibility_enabled", 0);
-    }
-}
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 c2c2a10..244f348 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
@@ -37,12 +37,18 @@
 import com.android.tradefed.result.InputStreamSource;
 import com.android.tradefed.result.LogDataType;
 import com.android.tradefed.result.ResultForwarder;
+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.IResumableTest;
 import com.android.tradefed.testtype.IShardableTest;
+import com.android.tradefed.testtype.InstrumentationTest;
 import com.android.tradefed.util.AbiFormatter;
 import com.android.tradefed.util.RunUtil;
 import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
@@ -58,11 +64,13 @@
 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;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map;
 import java.util.Set;
 
@@ -82,6 +90,8 @@
     private static final String TEST_OPTION = "test";
     public static final String CONTINUE_OPTION = "continue-session";
     public static final String RUN_KNOWN_FAILURES_OPTION = "run-known-failures";
+    private static final String INCLUDE_FILTERS_OPTION = "include";
+    private static final String EXCLUDE_FILTERS_OPTION = "exclude";
 
     public static final String PACKAGE_NAME_METRIC = "packageName";
     public static final String PACKAGE_ABI_METRIC = "packageAbi";
@@ -180,9 +190,14 @@
             "Collect dEQP logs from the device.")
     private boolean mCollectDeqpLogs = false;
 
+    @Option(name = INCLUDE_FILTERS_OPTION, description = "Positive filters to pass to tests.")
+    private List<String> mPositiveFilters = new ArrayList<> ();
+
+    @Option(name = EXCLUDE_FILTERS_OPTION, description = "Negative filters to pass to tests.")
+    private List<String> mNegativeFilters = new ArrayList<> ();
+
     @Option(name = "min-pre-reboot-package-count", description =
             "The minimum number of packages to require a pre test reboot")
-
     private int mMinPreRebootPackageCount = 2;
     private final int mShardAssignment;
     private final int mTotalShards;
@@ -237,6 +252,20 @@
         }
     }
 
+
+    /**
+     * 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.
      */
@@ -275,9 +304,8 @@
         @Override
         public void testFailed(TestIdentifier test, String trace) {
             super.testFailed(test, trace);
-            // sleep a small amount of time to ensure test failure stack trace makes it into logcat
-            // capture
-            RunUtil.getDefault().sleep(10);
+            // sleep 2s to ensure test failure stack trace makes it into logcat capture
+            RunUtil.getDefault().sleep(2 * 1000);
             InputStreamSource logSource = mDevice.getLogcat(mNumLogcatBytes);
             super.testLog(String.format("logcat-%s_%s", test.getClassName(), test.getTestName()),
                     LogDataType.TEXT, logSource);
@@ -525,9 +553,33 @@
                 if (test instanceof DeqpTestRunner) {
                     ((DeqpTestRunner)test).setCollectLogs(mCollectDeqpLogs);
                 }
+                if (test instanceof GeeTest) {
+                    if (!mPositiveFilters.isEmpty()) {
+                        String positivePatterns = join(mPositiveFilters, ":");
+                        ((GeeTest)test).setPositiveFilters(positivePatterns);
+                    }
+                    if (!mNegativeFilters.isEmpty()) {
+                        String negativePatterns = join(mNegativeFilters, ":");
+                        ((GeeTest)test).setPositiveFilters(negativePatterns);
+                    }
+                }
+                if (test instanceof InstrumentationTest) {
+                    if (!mPositiveFilters.isEmpty()) {
+                        String annotation = join(mPositiveFilters, ",");
+                        ((InstrumentationTest)test).addInstrumentationArg(
+                                "annotation", annotation);
+                    }
+                    if (!mNegativeFilters.isEmpty()) {
+                        String notAnnotation = join(mNegativeFilters, ",");
+                        ((InstrumentationTest)test).addInstrumentationArg(
+                                "notAnnotation", notAnnotation);
+                    }
+                }
 
                 forwardPackageDetails(testPackage.getPackageDef(), listener);
+                performPackagePrepareSetup(testPackage.getPackageDef());
                 test.run(filterMap.get(testPackage.getPackageDef().getId()));
+                performPackagePreparerTearDown(testPackage.getPackageDef());
                 if (i < mTestPackageList.size() - 1) {
                     TestPackage nextPackage = mTestPackageList.get(i + 1);
                     rebootIfNecessary(testPackage, nextPackage);
@@ -562,6 +614,79 @@
     }
 
     /**
+     * Invokes {@link ITargetPreparer}s configured for the test package. {@link TargetSetupError}s
+     * thrown by any preparer will be rethrown as {@link RuntimeException} so that the entire test
+     * package will be skipped for execution. Note that preparers will be invoked in the same order
+     * as they are defined in the module test config.
+     * @param packageDef definition for the test package
+     * @throws DeviceNotAvailableException
+     */
+    private void performPackagePrepareSetup(ITestPackageDef packageDef)
+            throws DeviceNotAvailableException {
+        List<ITargetPreparer> preparers = packageDef.getPackagePreparers();
+        if (preparers != null) {
+            for (ITargetPreparer preparer : preparers) {
+                if (preparer instanceof IAbiReceiver) {
+                    ((IAbiReceiver) preparer).setAbi(packageDef.getAbi());
+                }
+                try {
+                    preparer.setUp(getDevice(), mBuildInfo);
+                } catch (BuildError e) {
+                    // This should only happen for flashing new build
+                    CLog.e("Unexpected BuildError from preparer: %s",
+                        preparer.getClass().getCanonicalName());
+                } catch (TargetSetupError e) {
+                    // log preparer class then rethrow & let caller handle
+                    CLog.e("TargetSetupError in preparer: %s",
+                        preparer.getClass().getCanonicalName());
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Invokes clean up step for {@link ITargetCleaner}s configured for the test package. Note that
+     * the cleaners will be invoked in the reverse order as they are defined in module test config.
+     * @param packageDef definition for the test package
+     * @throws DeviceNotAvailableException
+     */
+    private void performPackagePreparerTearDown(ITestPackageDef packageDef)
+            throws DeviceNotAvailableException {
+        List<ITargetPreparer> preparers = packageDef.getPackagePreparers();
+        if (preparers != null) {
+            ListIterator<ITargetPreparer> itr = preparers.listIterator(preparers.size());
+            // do teardown in reverse order
+            while (itr.hasPrevious()) {
+                ITargetPreparer preparer = itr.previous();
+                if (preparer instanceof ITargetCleaner) {
+                    ((ITargetCleaner) preparer).tearDown(getDevice(), mBuildInfo, null);
+                }
+            }
+        }
+    }
+
+    /**
+     * Helper method to join strings. Exposed for unit tests
+     * @param input
+     * @param conjunction
+     * @return string with elements of the input list with interleaved conjunction.
+     */
+    protected static String join(List<String> input, String conjunction) {
+        StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        for (String item : input) {
+            if (first) {
+                first = false;
+            } else {
+                sb.append(conjunction);
+            }
+            sb.append(item);
+        }
+        return sb.toString();
+    }
+
+    /**
      * @param allTestPackageDefList The package list to filter
      * @param deviceAbiSet The ABIs supported by the device being tested
      * @return A {@link List} of {@link ITestPackageDef}s that should be tested
@@ -701,6 +826,10 @@
             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));
@@ -947,6 +1076,8 @@
         if (!mSkipDeviceInfo) {
             String abi = AbiFormatter.getDefaultAbi(device, "");
             DeviceInfoCollector.collectDeviceInfo(device, abi, ctsBuild.getTestCasesDir(), listener);
+            DeviceInfoCollector.collectExtendedDeviceInfo(
+                device, abi, ctsBuild.getTestCasesDir(), listener, mBuildInfo);
         }
     }
 
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 8eb1621..6f4d42d 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
@@ -2,7 +2,11 @@
 
 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;
+import com.android.ddmlib.ShellCommandUnresponsiveException;
+import com.android.ddmlib.TimeoutException;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.build.IBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -15,15 +19,28 @@
 import com.android.tradefed.testtype.IBuildReceiver;
 import com.android.tradefed.testtype.IDeviceTest;
 import com.android.tradefed.testtype.IRemoteTest;
+import com.android.tradefed.util.IRunUtil;
+import com.android.tradefed.util.RunInterruptedException;
+import com.android.tradefed.util.RunUtil;
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Test runner for dEQP tests
@@ -35,30 +52,45 @@
     private static final String DEQP_ONDEVICE_APK = "com.drawelements.deqp.apk";
     private static final String DEQP_ONDEVICE_PKG = "com.drawelements.deqp";
     private static final String INCOMPLETE_LOG_MESSAGE = "Crash: Incomplete test log";
+    private static final String SKIPPED_INSTANCE_LOG_MESSAGE = "Configuration skipped";
+    private static final String NOT_EXECUTABLE_LOG_MESSAGE = "Abort: Test cannot be executed";
+    private static final String CASE_LIST_FILE_NAME = "/sdcard/dEQP-TestCaseList.txt";
+    private static final String LOG_FILE_NAME = "/sdcard/TestLog.qpa";
+    public static final String FEATURE_LANDSCAPE = "android.hardware.screen.landscape";
+    public static final String FEATURE_PORTRAIT = "android.hardware.screen.portrait";
 
-    private final int TESTCASE_BATCH_LIMIT = 1000;
+    private static final int TESTCASE_BATCH_LIMIT = 1000;
+    private static final BatchRunConfiguration DEFAULT_CONFIG =
+        new BatchRunConfiguration("rgba8888d24s8", "unspecified", "window");
 
-    private boolean mLogData;
-
-    private ITestDevice mDevice;
+    private static final int UNRESPOSIVE_CMD_TIMEOUT_MS = 10*60*1000; // ten minutes
 
     private final String mPackageName;
     private final String mName;
-    private Collection<TestIdentifier> mTests;
+    private final Collection<TestIdentifier> mRemainingTests;
+    private final Map<TestIdentifier, Set<BatchRunConfiguration>> mTestInstances;
+    private final TestInstanceResultListener mInstanceListerner = new TestInstanceResultListener();
+    private final Map<TestIdentifier, Integer> mTestInstabilityRatings;
     private IAbi mAbi;
     private CtsBuildHelper mCtsBuild;
+    private boolean mLogData = false;
+    private ITestDevice mDevice;
+    private Set<String> mDeviceFeatures;
+    private Map<String, Boolean> mConfigQuerySupportCache = new HashMap<>();
+    private IRunUtil mRunUtil = RunUtil.getDefault();
 
-    private TestIdentifier mCurrentTestId;
-    private boolean mGotTestResult;
-    private String mCurrentTestLog;
+    private IRecovery mDeviceRecovery = new Recovery();
+    {
+        mDeviceRecovery.setSleepProvider(new SleepProvider());
+    }
 
-    private ITestInvocationListener mListener;
-
-    public DeqpTestRunner(String packageName, String name, Collection<TestIdentifier> tests) {
+    public DeqpTestRunner(String packageName, String name, Collection<TestIdentifier> tests,
+            Map<TestIdentifier, List<Map<String,String>>> testInstances) {
         mPackageName = packageName;
         mName = name;
-        mTests = tests;
-        mLogData = false;
+        mRemainingTests = new LinkedList<>(tests); // avoid modifying arguments
+        mTestInstances = parseTestInstances(tests, testInstances);
+        mTestInstabilityRatings = new HashMap<>();
     }
 
     /**
@@ -95,18 +127,452 @@
     }
 
     /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setDevice(ITestDevice device) {
+        mDevice = device;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public ITestDevice getDevice() {
+        return mDevice;
+    }
+
+    /**
+     * Set recovery handler.
+     *
+     * Exposed for unit testing.
+     */
+    public void setRecovery(IRecovery deviceRecovery) {
+        mDeviceRecovery = deviceRecovery;
+    }
+
+    /**
+     * Set IRunUtil.
+     *
+     * Exposed for unit testing.
+     */
+    public void setRunUtil(IRunUtil runUtil) {
+        mRunUtil = runUtil;
+    }
+
+    private static final class CapabilityQueryFailureException extends Exception {
+    };
+
+    /**
+     * Test configuration of dEPQ test instance execution.
+     * Exposed for unit testing
+     */
+    public static final class BatchRunConfiguration {
+        public static final String ROTATION_UNSPECIFIED = "unspecified";
+        public static final String ROTATION_PORTRAIT = "0";
+        public static final String ROTATION_LANDSCAPE = "90";
+        public static final String ROTATION_REVERSE_PORTRAIT = "180";
+        public static final String ROTATION_REVERSE_LANDSCAPE = "270";
+
+        private final String mGlConfig;
+        private final String mRotation;
+        private final String mSurfaceType;
+
+        public BatchRunConfiguration(String glConfig, String rotation, String surfaceType) {
+            mGlConfig = glConfig;
+            mRotation = rotation;
+            mSurfaceType = surfaceType;
+        }
+
+        /**
+         * Get string that uniquely identifies this config
+         */
+        public String getId() {
+            return String.format("{glformat=%s,rotation=%s,surfacetype=%s}",
+                    mGlConfig, mRotation, mSurfaceType);
+        }
+
+        /**
+         * Get the GL config used in this configuration.
+         */
+        public String getGlConfig() {
+            return mGlConfig;
+        }
+
+        /**
+         * Get the screen rotation used in this configuration.
+         */
+        public String getRotation() {
+            return mRotation;
+        }
+
+        /**
+         * Get the surface type used in this configuration.
+         */
+        public String getSurfaceType() {
+            return mSurfaceType;
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (other == null) {
+                return false;
+            } else if (!(other instanceof BatchRunConfiguration)) {
+                return false;
+            } else {
+                return getId().equals(((BatchRunConfiguration)other).getId());
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return getId().hashCode();
+        }
+    }
+
+    /**
+     * dEQP test instance listerer and invocation result forwarded
+     */
+    private class TestInstanceResultListener {
+        private ITestInvocationListener mSink;
+        private BatchRunConfiguration mRunConfig;
+
+        private TestIdentifier mCurrentTestId;
+        private boolean mGotTestResult;
+        private String mCurrentTestLog;
+
+        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) {
+            mSink = sink;
+        }
+
+        public void setCurrentConfig(BatchRunConfiguration runConfig) {
+            mRunConfig = runConfig;
+        }
+
+        /**
+         * Get currently processed test id, or null if not currently processing a test case
+         */
+        public TestIdentifier getCurrentTestId() {
+            return mCurrentTestId;
+        }
+
+        /**
+         * Forward result to sink
+         */
+        private void forwardFinalizedPendingResult(TestIdentifier testId) {
+            if (mRemainingTests.contains(testId)) {
+                final PendingResult result = mPendingResults.get(testId);
+
+                mPendingResults.remove(testId);
+                mRemainingTests.remove(testId);
+
+                // Forward results to the sink
+                mSink.testStarted(testId);
+
+                // Test Log
+                if (mLogData) {
+                    for (Map.Entry<BatchRunConfiguration, String> entry :
+                            result.testLogs.entrySet()) {
+                        final ByteArrayInputStreamSource source
+                                = new ByteArrayInputStreamSource(entry.getValue().getBytes());
+
+                        mSink.testLog(testId.getClassName() + "." + testId.getTestName() + "@"
+                                + entry.getKey().getId(), LogDataType.XML, source);
+
+                        source.cancel();
+                    }
+                }
+
+                // Error message
+                if (!result.allInstancesPassed) {
+                    final StringBuilder errorLog = new StringBuilder();
+
+                    for (Map.Entry<BatchRunConfiguration, String> entry :
+                            result.errorMessages.entrySet()) {
+                        if (errorLog.length() > 0) {
+                            errorLog.append('\n');
+                        }
+                        errorLog.append(String.format("=== with config %s ===\n",
+                                entry.getKey().getId()));
+                        errorLog.append(entry.getValue());
+                    }
+
+                    mSink.testFailed(testId, errorLog.toString());
+                }
+
+                final Map<String, String> emptyMap = Collections.emptyMap();
+                mSink.testEnded(testId, emptyMap);
+            }
+        }
+
+        /**
+         * Declare existence of a test and instances
+         */
+        public void setTestInstances(TestIdentifier testId, Set<BatchRunConfiguration> configs) {
+            // Test instances cannot change at runtime, ignore if we have already set this
+            if (!mPendingResults.containsKey(testId)) {
+                final PendingResult pendingResult = new PendingResult();
+                pendingResult.allInstancesPassed = true;
+                pendingResult.testLogs = new LinkedHashMap<>();
+                pendingResult.errorMessages = new LinkedHashMap<>();
+                pendingResult.remainingConfigs = new HashSet<>(configs); // avoid mutating argument
+                mPendingResults.put(testId, pendingResult);
+            }
+        }
+
+        /**
+         * Query if test instance has not yet been executed
+         */
+        public boolean isPendingTestInstance(TestIdentifier testId,
+                BatchRunConfiguration config) {
+            final PendingResult result = mPendingResults.get(testId);
+            if (result == null) {
+                // test is not in the current working batch of the runner, i.e. it cannot be
+                // "partially" completed.
+                if (!mRemainingTests.contains(testId)) {
+                    // The test has been fully executed. Not pending.
+                    return false;
+                } else {
+                    // Test has not yet been executed. Check if such instance exists
+                    return mTestInstances.get(testId).contains(config);
+                }
+            } else {
+                // could be partially completed, check this particular config
+                return result.remainingConfigs.contains(config);
+            }
+        }
+
+        /**
+         * Fake execution of an instance with current config
+         */
+        public void skipTest(TestIdentifier testId) {
+            final PendingResult result = mPendingResults.get(testId);
+
+            result.errorMessages.put(mRunConfig, SKIPPED_INSTANCE_LOG_MESSAGE);
+            result.remainingConfigs.remove(mRunConfig);
+
+            // Pending result finished, report result
+            if (result.remainingConfigs.isEmpty()) {
+                forwardFinalizedPendingResult(testId);
+            }
+        }
+
+        /**
+         * Fake failure of an instance with current config
+         */
+        public void abortTest(TestIdentifier testId, String errorMessage) {
+            final PendingResult result = mPendingResults.get(testId);
+
+            // Mark as executed
+            result.allInstancesPassed = false;
+            result.errorMessages.put(mRunConfig, errorMessage);
+            result.remainingConfigs.remove(mRunConfig);
+
+            // Pending result finished, report result
+            if (result.remainingConfigs.isEmpty()) {
+                forwardFinalizedPendingResult(testId);
+            }
+
+            if (testId.equals(mCurrentTestId)) {
+                mCurrentTestId = null;
+            }
+        }
+
+        /**
+         * Handles beginning of dEQP session.
+         */
+        private void handleBeginSession(Map<String, String> values) {
+            // ignore
+        }
+
+        /**
+         * Handles end of dEQP session.
+         */
+        private void handleEndSession(Map<String, String> values) {
+            // ignore
+        }
+
+        /**
+         * Handles beginning of dEQP testcase.
+         */
+        private void handleBeginTestCase(Map<String, String> values) {
+            mCurrentTestId = pathToIdentifier(values.get("dEQP-BeginTestCase-TestCasePath"));
+            mCurrentTestLog = "";
+            mGotTestResult = false;
+
+            // mark instance as started
+            if (mPendingResults.get(mCurrentTestId) != null) {
+                mPendingResults.get(mCurrentTestId).remainingConfigs.remove(mRunConfig);
+            } else {
+                CLog.w("Got unexpected start of %s", mCurrentTestId);
+            }
+        }
+
+        /**
+         * Handles end of dEQP testcase.
+         */
+        private void handleEndTestCase(Map<String, String> values) {
+            final PendingResult result = mPendingResults.get(mCurrentTestId);
+
+            if (result != null) {
+                if (!mGotTestResult) {
+                    result.allInstancesPassed = false;
+                    result.errorMessages.put(mRunConfig, INCOMPLETE_LOG_MESSAGE);
+                    CLog.i("Test %s failed as it ended before receiving result.", mCurrentTestId);
+                }
+
+                if (mLogData && mCurrentTestLog != null && mCurrentTestLog.length() > 0) {
+                    result.testLogs.put(mRunConfig, mCurrentTestLog);
+                }
+
+                // Pending result finished, report result
+                if (result.remainingConfigs.isEmpty()) {
+                    forwardFinalizedPendingResult(mCurrentTestId);
+                }
+            } else {
+                CLog.w("Got unexpected end of %s", mCurrentTestId);
+            }
+            mCurrentTestId = null;
+        }
+
+        /**
+         * Handles dEQP testcase result.
+         */
+        private void handleTestCaseResult(Map<String, String> values) {
+            String code = values.get("dEQP-TestCaseResult-Code");
+            String details = values.get("dEQP-TestCaseResult-Details");
+
+            if (mPendingResults.get(mCurrentTestId) == null) {
+                CLog.w("Got unexpected result for %s", mCurrentTestId);
+                mGotTestResult = true;
+                return;
+            }
+
+            if (code.compareTo("Pass") == 0) {
+                mGotTestResult = true;
+            } else if (code.compareTo("NotSupported") == 0) {
+                mGotTestResult = true;
+            } else if (code.compareTo("QualityWarning") == 0) {
+                mGotTestResult = true;
+            } else if (code.compareTo("CompatibilityWarning") == 0) {
+                mGotTestResult = true;
+            } else if (code.compareTo("Fail") == 0 || code.compareTo("ResourceError") == 0
+                    || code.compareTo("InternalError") == 0 || code.compareTo("Crash") == 0
+                    || code.compareTo("Timeout") == 0) {
+                mPendingResults.get(mCurrentTestId).allInstancesPassed = false;
+                mPendingResults.get(mCurrentTestId)
+                        .errorMessages.put(mRunConfig, code + ": " + details);
+                mGotTestResult = true;
+            } else {
+                String codeError = "Unknown result code: " + code;
+                mPendingResults.get(mCurrentTestId).allInstancesPassed = false;
+                mPendingResults.get(mCurrentTestId)
+                        .errorMessages.put(mRunConfig, codeError + ": " + details);
+                mGotTestResult = true;
+                CLog.e("Got invalid result code '%s' for test %s", code, mCurrentTestId);
+            }
+        }
+
+        /**
+         * Handles terminated dEQP testcase.
+         */
+        private void handleTestCaseTerminate(Map<String, String> values) {
+            final PendingResult result = mPendingResults.get(mCurrentTestId);
+
+            if (result != null) {
+                String reason = values.get("dEQP-TerminateTestCase-Reason");
+                mPendingResults.get(mCurrentTestId).allInstancesPassed = false;
+                mPendingResults.get(mCurrentTestId)
+                        .errorMessages.put(mRunConfig, "Terminated: " + reason);
+
+                // Pending result finished, report result
+                if (result.remainingConfigs.isEmpty()) {
+                    forwardFinalizedPendingResult(mCurrentTestId);
+                }
+            } else {
+                CLog.w("Got unexpected termination of %s", mCurrentTestId);
+            }
+
+            mCurrentTestId = null;
+            mGotTestResult = true;
+        }
+
+        /**
+         * Handles dEQP testlog data.
+         */
+        private void handleTestLogData(Map<String, String> values) {
+            mCurrentTestLog = mCurrentTestLog + values.get("dEQP-TestLogData-Log");
+        }
+
+        /**
+         * Handles new instrumentation status message.
+         */
+        public void handleStatus(Map<String, String> values) {
+            String eventType = values.get("dEQP-EventType");
+
+            if (eventType == null) {
+                return;
+            }
+
+            if (eventType.compareTo("BeginSession") == 0) {
+                handleBeginSession(values);
+            } else if (eventType.compareTo("EndSession") == 0) {
+                handleEndSession(values);
+            } else if (eventType.compareTo("BeginTestCase") == 0) {
+                handleBeginTestCase(values);
+            } else if (eventType.compareTo("EndTestCase") == 0) {
+                handleEndTestCase(values);
+            } else if (eventType.compareTo("TestCaseResult") == 0) {
+                handleTestCaseResult(values);
+            } else if (eventType.compareTo("TerminateTestCase") == 0) {
+                handleTestCaseTerminate(values);
+            } else if (eventType.compareTo("TestLogData") == 0) {
+                handleTestLogData(values);
+            }
+        }
+
+        /**
+         * Signal listener that batch ended and forget incomplete results.
+         */
+        public void endBatch() {
+            // end open test if when stream ends
+            if (mCurrentTestId != null) {
+                // Current instance was removed from remainingConfigs when case
+                // started. Mark current instance as pending.
+                if (mPendingResults.get(mCurrentTestId) != null) {
+                    mPendingResults.get(mCurrentTestId).remainingConfigs.add(mRunConfig);
+                } else {
+                    CLog.w("Got unexpected internal state of %s", mCurrentTestId);
+                }
+            }
+            mCurrentTestId = null;
+        }
+    }
+
+    /**
      * dEQP instrumentation parser
      */
-    class InstrumentationParser extends MultiLineReceiver {
-        private DeqpTestRunner mDeqpTests;
+    private static class InstrumentationParser extends MultiLineReceiver {
+        private TestInstanceResultListener mListener;
 
         private Map<String, String> mValues;
         private String mCurrentName;
         private String mCurrentValue;
+        private int mResultCode;
+        private boolean mGotExitValue = false;
 
 
-        public InstrumentationParser(DeqpTestRunner tests) {
-            mDeqpTests = tests;
+        public InstrumentationParser(TestInstanceResultListener listener) {
+            mListener = listener;
         }
 
         /**
@@ -125,7 +591,7 @@
                         mCurrentValue = null;
                     }
 
-                    mDeqpTests.handleStatus(mValues);
+                    mListener.handleStatus(mValues);
                     mValues = null;
                 } else if (line.startsWith("INSTRUMENTATION_STATUS: dEQP-")) {
                     if (mCurrentName != null) {
@@ -142,6 +608,13 @@
 
                     mCurrentName = line.substring(nameBegin, nameEnd);
                     mCurrentValue = line.substring(valueBegin);
+                } else if (line.startsWith("INSTRUMENTATION_CODE: ")) {
+                    try {
+                        mResultCode = Integer.parseInt(line.substring(22));
+                        mGotExitValue = true;
+                    } catch (NumberFormatException ex) {
+                        CLog.w("Instrumentation code format unexpected");
+                    }
                 } else if (mCurrentValue != null) {
                     mCurrentValue = mCurrentValue + line;
                 }
@@ -161,7 +634,7 @@
             }
 
             if (mValues != null) {
-                mDeqpTests.handleStatus(mValues);
+                mListener.handleStatus(mValues);
                 mValues = null;
             }
         }
@@ -173,12 +646,413 @@
         public boolean isCancelled() {
             return false;
         }
+
+        /**
+         * Returns whether target instrumentation exited normally.
+         */
+        public boolean wasSuccessful() {
+            return mGotExitValue;
+        }
+
+        /**
+         * Returns Instrumentation return code
+         */
+        public int getResultCode() {
+            return mResultCode;
+        }
+    }
+
+    /**
+     * dEQP platfom query instrumentation parser
+     */
+    private static class PlatformQueryInstrumentationParser extends MultiLineReceiver {
+        private Map<String,String> mResultMap = new LinkedHashMap<>();
+        private int mResultCode;
+        private boolean mGotExitValue = false;
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void processNewLines(String[] lines) {
+            for (String line : lines) {
+                if (line.startsWith("INSTRUMENTATION_RESULT: ")) {
+                    final String parts[] = line.substring(24).split("=",2);
+                    if (parts.length == 2) {
+                        mResultMap.put(parts[0], parts[1]);
+                    } else {
+                        CLog.w("Instrumentation status format unexpected");
+                    }
+                } else if (line.startsWith("INSTRUMENTATION_CODE: ")) {
+                    try {
+                        mResultCode = Integer.parseInt(line.substring(22));
+                        mGotExitValue = true;
+                    } catch (NumberFormatException ex) {
+                        CLog.w("Instrumentation code format unexpected");
+                    }
+                }
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public boolean isCancelled() {
+            return false;
+        }
+
+        /**
+         * Returns whether target instrumentation exited normally.
+         */
+        public boolean wasSuccessful() {
+            return mGotExitValue;
+        }
+
+        /**
+         * Returns Instrumentation return code
+         */
+        public int getResultCode() {
+            return mResultCode;
+        }
+
+        public Map<String,String> getResultMap() {
+            return mResultMap;
+        }
+    }
+
+    /**
+     * Interface for sleeping.
+     *
+     * Exposed for unit testing
+     */
+    public static interface ISleepProvider {
+        public void sleep(int milliseconds);
+    };
+
+    private static class SleepProvider implements ISleepProvider {
+        public void sleep(int milliseconds) {
+            try {
+                Thread.sleep(milliseconds);
+            } catch (InterruptedException ex) {
+            }
+        }
+    };
+
+    /**
+     * Interface for failure recovery.
+     *
+     * Exposed for unit testing
+     */
+    public static interface IRecovery {
+        /**
+         * Sets the sleep provider IRecovery works on
+         */
+        public void setSleepProvider(ISleepProvider sleepProvider);
+
+        /**
+         * Sets the device IRecovery works on
+         */
+        public void setDevice(ITestDevice device);
+
+        /**
+         * Informs Recovery that test execution has progressed since the last recovery
+         */
+        public void onExecutionProgressed();
+
+        /**
+         * Tries to recover device after failed refused connection.
+         *
+         * @throws DeviceNotAvailableException if recovery did not succeed
+         */
+        public void recoverConnectionRefused() throws DeviceNotAvailableException;
+
+        /**
+         * Tries to recover device after abnormal execution termination or link failure.
+         *
+         * @param progressedSinceLastCall true if test execution has progressed since last call
+         * @throws DeviceNotAvailableException if recovery did not succeed
+         */
+        public void recoverComLinkKilled() throws DeviceNotAvailableException;
+    };
+
+    /**
+     * State machine for execution failure recovery.
+     *
+     * Exposed for unit testing
+     */
+    public static class Recovery implements IRecovery {
+        private int RETRY_COOLDOWN_MS = 6000; // 6 seconds
+        private int PROCESS_KILL_WAIT_MS = 1000; // 1 second
+
+        private static enum MachineState {
+            WAIT, // recover by waiting
+            RECOVER, // recover by calling recover()
+            REBOOT, // recover by rebooting
+            FAIL, // cannot recover
+        };
+
+        private MachineState mState = MachineState.WAIT;
+        private ITestDevice mDevice;
+        private ISleepProvider mSleepProvider;
+
+        private static class ProcessKillFailureException extends Exception {
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void setSleepProvider(ISleepProvider sleepProvider) {
+            mSleepProvider = sleepProvider;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void setDevice(ITestDevice device) {
+            mDevice = device;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void onExecutionProgressed() {
+            mState = MachineState.WAIT;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void recoverConnectionRefused() throws DeviceNotAvailableException {
+            switch (mState) {
+                case WAIT: // not a valid stratedy for connection refusal, fallthrough
+                case RECOVER:
+                    // First failure, just try to recover
+                    CLog.w("ADB connection failed, trying to recover");
+                    mState = MachineState.REBOOT; // the next step is to reboot
+
+                    try {
+                        recoverDevice();
+                    } catch (DeviceNotAvailableException ex) {
+                        // chain forward
+                        recoverConnectionRefused();
+                    }
+                    break;
+
+                case REBOOT:
+                    // Second failure in a row, try to reboot
+                    CLog.w("ADB connection failed after recovery, rebooting device");
+                    mState = MachineState.FAIL; // the next step is to fail
+
+                    try {
+                        rebootDevice();
+                    } catch (DeviceNotAvailableException ex) {
+                        // chain forward
+                        recoverConnectionRefused();
+                    }
+                    break;
+
+                case FAIL:
+                    // Third failure in a row, just fail
+                    CLog.w("Cannot recover ADB connection");
+                    throw new DeviceNotAvailableException("failed to connect after reboot");
+            }
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void recoverComLinkKilled() throws DeviceNotAvailableException {
+            switch (mState) {
+                case WAIT:
+                    // First failure, just try to wait and try again
+                    CLog.w("ADB link failed, retrying after a cooldown period");
+                    mState = MachineState.RECOVER; // the next step is to recover the device
+
+                    waitCooldown();
+
+                    // even if the link to deqp on-device process was killed, the process might
+                    // still be alive. Locate and terminate such unwanted processes.
+                    try {
+                        killDeqpProcess();
+                    } catch (DeviceNotAvailableException ex) {
+                        // chain forward
+                        recoverComLinkKilled();
+                    } catch (ProcessKillFailureException ex) {
+                        // chain forward
+                        recoverComLinkKilled();
+                    }
+                    break;
+
+                case RECOVER:
+                    // Second failure, just try to recover
+                    CLog.w("ADB link failed, trying to recover");
+                    mState = MachineState.REBOOT; // the next step is to reboot
+
+                    try {
+                        recoverDevice();
+                        killDeqpProcess();
+                    } catch (DeviceNotAvailableException ex) {
+                        // chain forward
+                        recoverComLinkKilled();
+                    } catch (ProcessKillFailureException ex) {
+                        // chain forward
+                        recoverComLinkKilled();
+                    }
+                    break;
+
+                case REBOOT:
+                    // Third failure in a row, try to reboot
+                    CLog.w("ADB link failed after recovery, rebooting device");
+                    mState = MachineState.FAIL; // the next step is to fail
+
+                    try {
+                        rebootDevice();
+                    } catch (DeviceNotAvailableException ex) {
+                        // chain forward
+                        recoverComLinkKilled();
+                    }
+                    break;
+
+                case FAIL:
+                    // Fourth failure in a row, just fail
+                    CLog.w("Cannot recover ADB connection");
+                    throw new DeviceNotAvailableException("link killed after reboot");
+            }
+        }
+
+        private void waitCooldown() {
+            mSleepProvider.sleep(RETRY_COOLDOWN_MS);
+        }
+
+        private Iterable<Integer> getDeqpProcessPids() throws DeviceNotAvailableException {
+            final List<Integer> pids = new ArrayList<Integer>(2);
+            final String processes = mDevice.executeShellCommand("ps | grep com.drawelements");
+            final String[] lines = processes.split("(\\r|\\n)+");
+            for (String line : lines) {
+                final String[] fields = line.split("\\s+");
+                if (fields.length < 2) {
+                    continue;
+                }
+
+                try {
+                    final int processId = Integer.parseInt(fields[1], 10);
+                    pids.add(processId);
+                } catch (NumberFormatException ex) {
+                    continue;
+                }
+            }
+            return pids;
+        }
+
+        private void killDeqpProcess() throws DeviceNotAvailableException,
+                ProcessKillFailureException {
+            for (Integer processId : getDeqpProcessPids()) {
+                CLog.i("Killing deqp device process with ID %d", processId);
+                mDevice.executeShellCommand(String.format("kill -9 %d", processId));
+            }
+
+            mSleepProvider.sleep(PROCESS_KILL_WAIT_MS);
+
+            // check that processes actually died
+            if (getDeqpProcessPids().iterator().hasNext()) {
+                // a process is still alive, killing failed
+                CLog.w("Failed to kill all deqp processes on device");
+                throw new ProcessKillFailureException();
+            }
+        }
+
+        public void recoverDevice() throws DeviceNotAvailableException {
+            // Work around the API. We need to call recoverDevice() on the test device and
+            // we know that mDevice is a TestDevice. However even though the recoverDevice()
+            // method is public suggesting it should be publicly accessible, the class itself
+            // and its super-interface (IManagedTestDevice) are package-private.
+            final Method recoverDeviceMethod;
+            try {
+                recoverDeviceMethod = mDevice.getClass().getMethod("recoverDevice");
+                recoverDeviceMethod.setAccessible(true);
+            } catch (NoSuchMethodException ex) {
+                throw new AssertionError("Test device must have recoverDevice()");
+            }
+
+            try {
+                recoverDeviceMethod.invoke(mDevice);
+            } catch (InvocationTargetException ex) {
+                if (ex.getCause() instanceof DeviceNotAvailableException) {
+                    throw (DeviceNotAvailableException)ex.getCause();
+                } else if (ex.getCause() instanceof RuntimeException) {
+                    throw (RuntimeException)ex.getCause();
+                } else {
+                    throw new AssertionError("unexpected throw", ex);
+                }
+            } catch (IllegalAccessException ex) {
+                throw new AssertionError("unexpected throw", ex);
+            }
+        }
+
+        private void rebootDevice() throws DeviceNotAvailableException {
+            mDevice.reboot();
+        }
+    };
+
+    /**
+     * Parse map of instance arguments to map of BatchRunConfigurations
+     */
+    private static Map<TestIdentifier, Set<BatchRunConfiguration>> parseTestInstances(
+            Collection<TestIdentifier> tests,
+            Map<TestIdentifier, List<Map<String,String>>> testInstances) {
+        final Map<TestIdentifier, Set<BatchRunConfiguration>> instances = new HashMap<>();
+        for (final TestIdentifier test : tests) {
+            final Set<BatchRunConfiguration> testInstanceSet = new LinkedHashSet<>();
+            if (testInstances.get(test).isEmpty()) {
+                // no instances defined, use default
+                testInstanceSet.add(DEFAULT_CONFIG);
+            } else {
+                for (Map<String, String> instanceArgs : testInstances.get(test)) {
+                    testInstanceSet.add(parseRunConfig(instanceArgs));
+                }
+            }
+            instances.put(test, testInstanceSet);
+        }
+        return instances;
+    }
+
+    private static BatchRunConfiguration parseRunConfig(Map<String,String> instanceArguments) {
+        final String glConfig;
+        final String rotation;
+        final String surfaceType;
+
+        if (instanceArguments.containsKey("glconfig")) {
+            glConfig = instanceArguments.get("glconfig");
+        } else {
+            glConfig = DEFAULT_CONFIG.getGlConfig();
+        }
+        if (instanceArguments.containsKey("rotation")) {
+            rotation = instanceArguments.get("rotation");
+        } else {
+            rotation = DEFAULT_CONFIG.getRotation();
+        }
+        if (instanceArguments.containsKey("surfaceType")) {
+            surfaceType = instanceArguments.get("surfaceType");
+        } else {
+            surfaceType = DEFAULT_CONFIG.getSurfaceType();
+        }
+
+        return new BatchRunConfiguration(glConfig, rotation, surfaceType);
+    }
+
+    private Set<BatchRunConfiguration> getTestRunConfigs (TestIdentifier testId) {
+        return mTestInstances.get(testId);
     }
 
     /**
      * Converts dEQP testcase path to TestIdentifier.
      */
-    private TestIdentifier pathToIdentifier(String testPath) {
+    private static TestIdentifier pathToIdentifier(String testPath) {
         String[] components = testPath.split("\\.");
         String name = components[components.length - 1];
         String className = null;
@@ -194,150 +1068,14 @@
         return new TestIdentifier(className, name);
     }
 
-    /**
-     * Handles beginning of dEQP session.
-     */
-    private void handleBeginSession(Map<String, String> values) {
-        String id = AbiUtils.createId(mAbi.getName(), mPackageName);
-        mListener.testRunStarted(id, mTests.size());
-    }
-
-    /**
-     * Handles end of dEQP session.
-     */
-    private void handleEndSession(Map<String, String> values) {
-        Map <String, String> emptyMap = Collections.emptyMap();
-        mListener.testRunEnded(0, emptyMap);
-    }
-
-    /**
-     * Handles beginning of dEQP testcase.
-     */
-    private void handleBeginTestCase(Map<String, String> values) {
-        mCurrentTestId = pathToIdentifier(values.get("dEQP-BeginTestCase-TestCasePath"));
-        mCurrentTestLog = "";
-        mGotTestResult = false;
-
-        mListener.testStarted(mCurrentTestId);
-        mTests.remove(mCurrentTestId);
-    }
-
-    /**
-     * Handles end of dEQP testcase.
-     */
-    private void handleEndTestCase(Map<String, String> values) {
-        Map <String, String> emptyMap = Collections.emptyMap();
-
-        if (!mGotTestResult) {
-            mListener.testFailed(mCurrentTestId,
-                    INCOMPLETE_LOG_MESSAGE);
-        }
-
-        if (mLogData && mCurrentTestLog != null && mCurrentTestLog.length() > 0) {
-            ByteArrayInputStreamSource source
-                    = new ByteArrayInputStreamSource(mCurrentTestLog.getBytes());
-
-            mListener.testLog(mCurrentTestId.getClassName() + "."
-                    + mCurrentTestId.getTestName(), LogDataType.XML, source);
-
-            source.cancel();
-        }
-
-        mListener.testEnded(mCurrentTestId, emptyMap);
-        mCurrentTestId = null;
-    }
-
-    /**
-     * Handles dEQP testcase result.
-     */
-    private void handleTestCaseResult(Map<String, String> values) {
-        String code = values.get("dEQP-TestCaseResult-Code");
-        String details = values.get("dEQP-TestCaseResult-Details");
-
-        if (code.compareTo("Pass") == 0) {
-            mGotTestResult = true;
-        } else if (code.compareTo("NotSupported") == 0) {
-            mGotTestResult = true;
-        } else if (code.compareTo("QualityWarning") == 0) {
-            mGotTestResult = true;
-        } else if (code.compareTo("CompatibilityWarning") == 0) {
-            mGotTestResult = true;
-        } else if (code.compareTo("Fail") == 0 || code.compareTo("ResourceError") == 0
-                || code.compareTo("InternalError") == 0 || code.compareTo("Crash") == 0
-                || code.compareTo("Timeout") == 0) {
-            mListener.testFailed(mCurrentTestId,
-                    code + ": " + details);
-            mGotTestResult = true;
-        } else {
-            mListener.testFailed(mCurrentTestId,
-                    "Unknown result code: " + code + ": " + details);
-            mGotTestResult = true;
-        }
-    }
-
-    /**
-     * Handles terminated dEQP testcase.
-     */
-    private void handleTestCaseTerminate(Map<String, String> values) {
-        Map <String, String> emptyMap = Collections.emptyMap();
-
-        String reason = values.get("dEQP-TerminateTestCase-Reason");
-        mListener.testFailed(mCurrentTestId,
-                "Terminated: " + reason);
-        mListener.testEnded(mCurrentTestId, emptyMap);
-
-        if (mLogData && mCurrentTestLog != null && mCurrentTestLog.length() > 0) {
-            ByteArrayInputStreamSource source
-                    = new ByteArrayInputStreamSource(mCurrentTestLog.getBytes());
-
-            mListener.testLog(mCurrentTestId.getClassName() + "."
-                    + mCurrentTestId.getTestName(), LogDataType.XML, source);
-
-            source.cancel();
-        }
-
-        mCurrentTestId = null;
-        mGotTestResult = true;
-    }
-
-    /**
-     * Handles dEQP testlog data.
-     */
-    private void handleTestLogData(Map<String, String> values) {
-        mCurrentTestLog = mCurrentTestLog + values.get("dEQP-TestLogData-Log");
-    }
-
-    /**
-     * Handles new instrumentation status message.
-     */
-    public void handleStatus(Map<String, String> values) {
-        String eventType = values.get("dEQP-EventType");
-
-        if (eventType == null) {
-            return;
-        }
-
-        if (eventType.compareTo("BeginSession") == 0) {
-            handleBeginSession(values);
-        } else if (eventType.compareTo("EndSession") == 0) {
-            handleEndSession(values);
-        } else if (eventType.compareTo("BeginTestCase") == 0) {
-            handleBeginTestCase(values);
-        } else if (eventType.compareTo("EndTestCase") == 0) {
-            handleEndTestCase(values);
-        } else if (eventType.compareTo("TestCaseResult") == 0) {
-            handleTestCaseResult(values);
-        } else if (eventType.compareTo("TerminateTestCase") == 0) {
-            handleTestCaseTerminate(values);
-        } else if (eventType.compareTo("TestLogData") == 0) {
-            handleTestLogData(values);
-        }
+    private String getId() {
+        return AbiUtils.createId(mAbi.getName(), mPackageName);
     }
 
     /**
      * Generates tescase trie from dEQP testcase paths. Used to define which testcases to execute.
      */
-    private String generateTestCaseTrieFromPaths(Collection<String> tests) {
+    private static String generateTestCaseTrieFromPaths(Collection<String> tests) {
         String result = "{";
         boolean first = true;
 
@@ -390,51 +1128,502 @@
     /**
      * Generates testcase trie from TestIdentifiers.
      */
-    private String generateTestCaseTrie(Collection<TestIdentifier> tests) {
+    private static String generateTestCaseTrie(Collection<TestIdentifier> tests) {
         ArrayList<String> testPaths = new ArrayList<String>();
 
         for (TestIdentifier test : tests) {
             testPaths.add(test.getClassName() + "." + test.getTestName());
-
-            // Limit number of testcases for each run
-            if (testPaths.size() > TESTCASE_BATCH_LIMIT)
-                break;
         }
 
         return generateTestCaseTrieFromPaths(testPaths);
     }
 
+    private static class TestBatch {
+        public BatchRunConfiguration config;
+        public List<TestIdentifier> tests;
+    }
+
+    private TestBatch selectRunBatch() {
+        return selectRunBatch(mRemainingTests, null);
+    }
+
     /**
-     * Executes tests on the device.
+     * Creates a TestBatch from the given tests or null if not tests remaining.
+     *
+     *  @param pool List of tests to select from
+     *  @param requiredConfig Select only instances with pending requiredConfig, or null to select
+     *         any run configuration.
      */
-    private void executeTests(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        InstrumentationParser parser = new InstrumentationParser(this);
-        String caseListFileName = "/sdcard/dEQP-TestCaseList.txt";
-        String logFileName = "/sdcard/TestLog.qpa";
-        String testCases = generateTestCaseTrie(mTests);
+    private TestBatch selectRunBatch(Collection<TestIdentifier> pool,
+            BatchRunConfiguration requiredConfig) {
+        // select one test (leading test) that is going to be executed and then pack along as many
+        // other compatible instances as possible.
 
-        mDevice.executeShellCommand("rm " + caseListFileName);
-        mDevice.executeShellCommand("rm " + logFileName);
-        mDevice.pushString(testCases + "\n", caseListFileName);
+        TestIdentifier leadingTest = null;
+        for (TestIdentifier test : pool) {
+            if (!mRemainingTests.contains(test)) {
+                continue;
+            }
+            if (requiredConfig != null &&
+                    !mInstanceListerner.isPendingTestInstance(test, requiredConfig)) {
+                continue;
+            }
+            leadingTest = test;
+            break;
+        }
 
-        String instrumentationName =
+        // no remaining tests?
+        if (leadingTest == null) {
+            return null;
+        }
+
+        BatchRunConfiguration leadingTestConfig = null;
+        if (requiredConfig != null) {
+            leadingTestConfig = requiredConfig;
+        } else {
+            for (BatchRunConfiguration runConfig : getTestRunConfigs(leadingTest)) {
+                if (mInstanceListerner.isPendingTestInstance(leadingTest, runConfig)) {
+                    leadingTestConfig = runConfig;
+                    break;
+                }
+            }
+        }
+
+        // test pending <=> test has a pending config
+        if (leadingTestConfig == null) {
+            throw new AssertionError("search postcondition failed");
+        }
+
+        final int leadingInstability = getTestInstabilityRating(leadingTest);
+
+        final TestBatch runBatch = new TestBatch();
+        runBatch.config = leadingTestConfig;
+        runBatch.tests = new ArrayList<>();
+        runBatch.tests.add(leadingTest);
+
+        for (TestIdentifier test : pool) {
+            if (test == leadingTest) {
+                // do not re-select the leading tests
+                continue;
+            }
+            if (!mInstanceListerner.isPendingTestInstance(test, leadingTestConfig)) {
+                // select only compatible
+                continue;
+            }
+            if (getTestInstabilityRating(test) != leadingInstability) {
+                // pack along only cases in the same stability category. Packing more dangerous
+                // tests along jeopardizes the stability of this run. Packing more stable tests
+                // along jeopardizes their stability rating.
+                continue;
+            }
+            if (runBatch.tests.size() >= getBatchSizeLimitForInstability(leadingInstability)) {
+                // batch size is limited.
+                break;
+            }
+            runBatch.tests.add(test);
+        }
+
+        return runBatch;
+    }
+
+    private int getBatchNumPendingCases(TestBatch batch) {
+        int numPending = 0;
+        for (TestIdentifier test : batch.tests) {
+            if (mInstanceListerner.isPendingTestInstance(test, batch.config)) {
+                ++numPending;
+            }
+        }
+        return numPending;
+    }
+
+    private int getBatchSizeLimitForInstability(int batchInstabilityRating) {
+        // reduce group size exponentially down to one
+        return Math.max(1, TESTCASE_BATCH_LIMIT / (1 << batchInstabilityRating));
+    }
+
+    private int getTestInstabilityRating(TestIdentifier testId) {
+        if (mTestInstabilityRatings.containsKey(testId)) {
+            return mTestInstabilityRatings.get(testId);
+        } else {
+            return 0;
+        }
+    }
+
+    private void recordTestInstability(TestIdentifier testId) {
+        mTestInstabilityRatings.put(testId, getTestInstabilityRating(testId) + 1);
+    }
+
+    private void clearTestInstability(TestIdentifier testId) {
+        mTestInstabilityRatings.put(testId, 0);
+    }
+
+    /**
+     * Executes all tests on the device.
+     */
+    private void runTests() throws DeviceNotAvailableException, CapabilityQueryFailureException {
+        for (;;) {
+            TestBatch batch = selectRunBatch();
+
+            if (batch == null) {
+                break;
+            }
+
+            runTestRunBatch(batch);
+        }
+    }
+
+    /**
+     * Runs a TestBatch by either faking it or executing it on a device.
+     */
+    private void runTestRunBatch(TestBatch batch) throws DeviceNotAvailableException,
+            CapabilityQueryFailureException {
+        // prepare instance listener
+        mInstanceListerner.setCurrentConfig(batch.config);
+        for (TestIdentifier test : batch.tests) {
+            mInstanceListerner.setTestInstances(test, getTestRunConfigs(test));
+        }
+
+        // execute only if config is executable, else fake results
+        if (isSupportedRunConfiguration(batch.config)) {
+            executeTestRunBatch(batch);
+        } else {
+            fakePassTestRunBatch(batch);
+        }
+    }
+
+    private boolean isSupportedRunConfiguration(BatchRunConfiguration runConfig)
+            throws DeviceNotAvailableException, CapabilityQueryFailureException {
+        // orientation support
+        if (!BatchRunConfiguration.ROTATION_UNSPECIFIED.equals(runConfig.getRotation())) {
+            final Set<String> features = getDeviceFeatures(mDevice);
+
+            if (isPortraitClassRotation(runConfig.getRotation()) &&
+                    !features.contains(FEATURE_PORTRAIT)) {
+                return false;
+            }
+            if (isLandscapeClassRotation(runConfig.getRotation()) &&
+                    !features.contains(FEATURE_LANDSCAPE)) {
+                return false;
+            }
+        }
+
+        if (isOpenGlEsPackage()) {
+            // renderability support for OpenGL ES tests
+            return isSupportedGlesRenderConfig(runConfig);
+        } else {
+            return true;
+        }
+    }
+
+    private static final class AdbComLinkOpenError extends Exception {
+        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
+     *
+     * @throws AdbComLinkOpenError if connection cannot be established.
+     * @throws AdbComLinkKilledError if established connection is killed prematurely.
+     */
+    private void executeShellCommandAndReadOutput(final String command,
+            final IShellOutputReceiver receiver)
+            throws AdbComLinkOpenError, AdbComLinkKilledError {
+        try {
+            mDevice.getIDevice().executeShellCommand(command, receiver,
+                    UNRESPOSIVE_CMD_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        } catch (TimeoutException ex) {
+            // Opening connection timed out
+            CLog.e("Opening connection timed out for command: '%s'", command);
+            throw new AdbComLinkOpenError("opening connection timed out", ex);
+        } catch (AdbCommandRejectedException ex) {
+            // Command rejected
+            CLog.e("Device rejected command: '%s'", command);
+            throw new AdbComLinkOpenError("command rejected", ex);
+        } catch (IOException ex) {
+            // shell command channel killed
+            CLog.e("Channel died for command: '%s'", command);
+            throw new AdbComLinkKilledError("command link killed", ex);
+        } catch (ShellCommandUnresponsiveException ex) {
+            // shell command halted
+            CLog.e("No output from command in %d ms: '%s'", UNRESPOSIVE_CMD_TIMEOUT_MS, command);
+            throw new AdbComLinkKilledError("command link hung", ex);
+        }
+    }
+
+    /**
+     * Executes given test batch on a device
+     */
+    private void executeTestRunBatch(TestBatch batch) throws DeviceNotAvailableException {
+        // attempt full run once
+        executeTestRunBatchRun(batch);
+
+        // split remaining tests to two sub batches and execute both. This will terminate
+        // since executeTestRunBatchRun will always progress for a batch of size 1.
+        final ArrayList<TestIdentifier> pendingTests = new ArrayList<>();
+
+        for (TestIdentifier test : batch.tests) {
+            if (mInstanceListerner.isPendingTestInstance(test, batch.config)) {
+                pendingTests.add(test);
+            }
+        }
+
+        final int divisorNdx = pendingTests.size() / 2;
+        final List<TestIdentifier> headList = pendingTests.subList(0, divisorNdx);
+        final List<TestIdentifier> tailList = pendingTests.subList(divisorNdx, pendingTests.size());
+
+        // head
+        for (;;) {
+            TestBatch subBatch = selectRunBatch(headList, batch.config);
+
+            if (subBatch == null) {
+                break;
+            }
+
+            executeTestRunBatch(subBatch);
+        }
+
+        // tail
+        for (;;) {
+            TestBatch subBatch = selectRunBatch(tailList, batch.config);
+
+            if (subBatch == null) {
+                break;
+            }
+
+            executeTestRunBatch(subBatch);
+        }
+
+        if (getBatchNumPendingCases(batch) != 0) {
+            throw new AssertionError("executeTestRunBatch postcondition failed");
+        }
+    }
+
+    /**
+     * Runs one execution pass over the given batch.
+     *
+     * Tries to run the batch. Always makes progress (executes instances or modifies stability
+     * scores).
+     */
+    private void executeTestRunBatchRun(TestBatch batch) throws DeviceNotAvailableException {
+        if (getBatchNumPendingCases(batch) != batch.tests.size()) {
+            throw new AssertionError("executeTestRunBatchRun precondition failed");
+        }
+
+        checkInterrupted(); // throws if interrupted
+
+        final String testCases = generateTestCaseTrie(batch.tests);
+
+        mDevice.executeShellCommand("rm " + CASE_LIST_FILE_NAME);
+        mDevice.executeShellCommand("rm " + LOG_FILE_NAME);
+        mDevice.pushString(testCases + "\n", CASE_LIST_FILE_NAME);
+
+        final String instrumentationName =
                 "com.drawelements.deqp/com.drawelements.deqp.testercore.DeqpInstrumentation";
 
-        String command = String.format(
-                "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
-                    + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\""
-                    + " -e deqpLogData \"%s\" %s",
-                AbiUtils.createAbiFlag(mAbi.getName()), logFileName, caseListFileName, mLogData,
-                instrumentationName);
+        final StringBuilder deqpCmdLine = new StringBuilder();
+        deqpCmdLine.append("--deqp-caselist-file=");
+        deqpCmdLine.append(CASE_LIST_FILE_NAME);
+        deqpCmdLine.append(" ");
+        deqpCmdLine.append(getRunConfigDisplayCmdLine(batch.config));
 
-        mDevice.executeShellCommand(command, parser);
-        parser.flush();
+        // If we are not logging data, do not bother outputting the images from the test exe.
+        if (!mLogData) {
+            deqpCmdLine.append(" --deqp-log-images=disable");
+        }
+
+        deqpCmdLine.append(" --deqp-watchdog=enable");
+
+        final String command = String.format(
+                "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \"%s\""
+                    + " -e deqpLogData \"%s\" %s",
+                AbiUtils.createAbiFlag(mAbi.getName()), LOG_FILE_NAME, deqpCmdLine.toString(),
+                mLogData, instrumentationName);
+
+        final int numRemainingInstancesBefore = getNumRemainingInstances();
+        final InstrumentationParser parser = new InstrumentationParser(mInstanceListerner);
+        Throwable interruptingError = null;
+
+        try {
+            executeShellCommandAndReadOutput(command, parser);
+        } catch (Throwable ex) {
+            interruptingError = ex;
+        } finally {
+            parser.flush();
+        }
+
+        final boolean progressedSinceLastCall = mInstanceListerner.getCurrentTestId() != null ||
+                getNumRemainingInstances() < numRemainingInstancesBefore;
+
+        if (progressedSinceLastCall) {
+            mDeviceRecovery.onExecutionProgressed();
+        }
+
+        // interrupted, try to recover
+        if (interruptingError != null) {
+            if (interruptingError instanceof AdbComLinkOpenError) {
+                CLog.i("Recovering from comm link error");
+                mDeviceRecovery.recoverConnectionRefused();
+            } else if (interruptingError instanceof AdbComLinkKilledError) {
+                CLog.i("Recovering from comm link killed");
+                mDeviceRecovery.recoverComLinkKilled();
+            } else if (interruptingError instanceof RunInterruptedException) {
+                // external run interruption request. Terminate immediately.
+                CLog.i("Run termination requested. Throwing forward.");
+                throw (RunInterruptedException)interruptingError;
+            } else {
+                CLog.e(interruptingError);
+                throw new RuntimeException(interruptingError);
+            }
+
+            // recoverXXX did not throw => recovery succeeded
+        } else if (!parser.wasSuccessful()) {
+            CLog.i("Parse not successful. Will attempt comm link recovery.");
+            mDeviceRecovery.recoverComLinkKilled();
+            // recoverXXX did not throw => recovery succeeded
+        }
+
+        // Progress guarantees.
+        if (batch.tests.size() == 1) {
+            final TestIdentifier onlyTest = batch.tests.iterator().next();
+            final boolean wasTestExecuted =
+                    !mInstanceListerner.isPendingTestInstance(onlyTest, batch.config) &&
+                    mInstanceListerner.getCurrentTestId() == null;
+            final boolean wasLinkFailure = !parser.wasSuccessful() || interruptingError != null;
+
+            // Link failures can be caused by external events, require at least two observations
+            // until bailing.
+            if (!wasTestExecuted && (!wasLinkFailure || getTestInstabilityRating(onlyTest) > 0)) {
+                recordTestInstability(onlyTest);
+                // If we cannot finish the test, mark the case as a crash.
+                //
+                // If we couldn't even start the test, fail the test instance as non-executable.
+                // This is required so that a consistently crashing or non-existent tests will
+                // not cause futile (non-terminating) re-execution attempts.
+                if (mInstanceListerner.getCurrentTestId() != null) {
+                    CLog.w("Test '%s' started, but not completed", onlyTest);
+                    mInstanceListerner.abortTest(onlyTest, INCOMPLETE_LOG_MESSAGE);
+                } else {
+                    CLog.w("Test '%s' could not start", onlyTest);
+                    mInstanceListerner.abortTest(onlyTest, NOT_EXECUTABLE_LOG_MESSAGE);
+                }
+            } else if (wasTestExecuted) {
+                clearTestInstability(onlyTest);
+            }
+        }
+        else
+        {
+            // Analyze results to update test stability ratings. If there is no interrupting test
+            // logged, increase instability rating of all remaining tests. If there is a
+            // interrupting test logged, increase only its instability rating.
+            //
+            // A successful run of tests clears instability rating.
+            if (mInstanceListerner.getCurrentTestId() == null) {
+                for (TestIdentifier test : batch.tests) {
+                    if (mInstanceListerner.isPendingTestInstance(test, batch.config)) {
+                        recordTestInstability(test);
+                    } else {
+                        clearTestInstability(test);
+                    }
+                }
+            } else {
+                recordTestInstability(mInstanceListerner.getCurrentTestId());
+                for (TestIdentifier test : batch.tests) {
+                    // \note: isPendingTestInstance is false for getCurrentTestId. Current ID is
+                    // considered 'running' and will be restored to 'pending' in endBatch().
+                    if (!test.equals(mInstanceListerner.getCurrentTestId()) &&
+                            !mInstanceListerner.isPendingTestInstance(test, batch.config)) {
+                        clearTestInstability(test);
+                    }
+                }
+            }
+        }
+
+        mInstanceListerner.endBatch();
+    }
+
+    private static String getRunConfigDisplayCmdLine(BatchRunConfiguration runConfig) {
+        final StringBuilder deqpCmdLine = new StringBuilder();
+        if (!runConfig.getGlConfig().isEmpty()) {
+            deqpCmdLine.append("--deqp-gl-config-name=");
+            deqpCmdLine.append(runConfig.getGlConfig());
+        }
+        if (!runConfig.getRotation().isEmpty()) {
+            if (deqpCmdLine.length() != 0) {
+                deqpCmdLine.append(" ");
+            }
+            deqpCmdLine.append("--deqp-screen-rotation=");
+            deqpCmdLine.append(runConfig.getRotation());
+        }
+        if (!runConfig.getSurfaceType().isEmpty()) {
+            if (deqpCmdLine.length() != 0) {
+                deqpCmdLine.append(" ");
+            }
+            deqpCmdLine.append("--deqp-surface-type=");
+            deqpCmdLine.append(runConfig.getSurfaceType());
+        }
+        return deqpCmdLine.toString();
+    }
+
+    private int getNumRemainingInstances() {
+        int retVal = 0;
+        for (TestIdentifier testId : mRemainingTests) {
+            // If case is in current working set, sum only not yet executed instances.
+            // If case is not in current working set, sum all instances (since they are not yet
+            // executed).
+            if (mInstanceListerner.mPendingResults.containsKey(testId)) {
+                retVal += mInstanceListerner.mPendingResults.get(testId).remainingConfigs.size();
+            } else {
+                retVal += mTestInstances.get(testId).size();
+            }
+        }
+        return retVal;
+    }
+
+    /**
+     * Checks if this execution has been marked as interrupted and throws if it has.
+     */
+    private void checkInterrupted() throws RunInterruptedException {
+        // Work around the API. RunUtil::checkInterrupted is private but we can call it indirectly
+        // by sleeping a value <= 0.
+        mRunUtil.sleep(0);
+    }
+
+    /**
+     * Pass given batch tests without running it
+     */
+    private void fakePassTestRunBatch(TestBatch batch) {
+        for (TestIdentifier test : batch.tests) {
+            CLog.d("Skipping test '%s' invocation in config '%s'", test.toString(),
+                    batch.config.getId());
+            mInstanceListerner.skipTest(test);
+        }
+    }
+
+    /**
+     * Pass all remaining tests without running them
+     */
+    private void fakePassTests(ITestInvocationListener listener) {
+        Map <String, String> emptyMap = Collections.emptyMap();
+        for (TestIdentifier test : mRemainingTests) {
+            CLog.d("Skipping test '%s', Opengl ES version not supported", test.toString());
+            listener.testStarted(test);
+            listener.testEnded(test, emptyMap);
+        }
+        mRemainingTests.clear();
     }
 
     /**
      * Check if device supports OpenGL ES version.
      */
-    static boolean isSupportedGles(ITestDevice device, int requiredMajorVersion, int requiredMinorVersion) throws DeviceNotAvailableException {
+    private static boolean isSupportedGles(ITestDevice device, int requiredMajorVersion,
+            int requiredMinorVersion) throws DeviceNotAvailableException {
         String roOpenglesVersion = device.getProperty("ro.opengles.version");
 
         if (roOpenglesVersion == null)
@@ -450,6 +1639,112 @@
     }
 
     /**
+     * Query if rendertarget is supported
+     */
+    private boolean isSupportedGlesRenderConfig(BatchRunConfiguration runConfig)
+            throws DeviceNotAvailableException, CapabilityQueryFailureException {
+        // query if configuration is supported
+        final StringBuilder configCommandLine =
+                new StringBuilder(getRunConfigDisplayCmdLine(runConfig));
+        if (configCommandLine.length() != 0) {
+            configCommandLine.append(" ");
+        }
+        configCommandLine.append("--deqp-gl-major-version=");
+        configCommandLine.append(getGlesMajorVersion());
+        configCommandLine.append(" --deqp-gl-minor-version=");
+        configCommandLine.append(getGlesMinorVersion());
+
+        final String commandLine = configCommandLine.toString();
+
+        // check for cached result first
+        if (mConfigQuerySupportCache.containsKey(commandLine)) {
+            return mConfigQuerySupportCache.get(commandLine);
+        }
+
+        final boolean supported = queryIsSupportedConfigCommandLine(commandLine);
+        mConfigQuerySupportCache.put(commandLine, supported);
+        return supported;
+    }
+
+    private boolean queryIsSupportedConfigCommandLine(String deqpCommandLine)
+            throws DeviceNotAvailableException, CapabilityQueryFailureException {
+        final String instrumentationName =
+                "com.drawelements.deqp/com.drawelements.deqp.platformutil.DeqpPlatformCapabilityQueryInstrumentation";
+        final String command = String.format(
+                "am instrument %s -w -e deqpQueryType renderConfigSupported -e deqpCmdLine \"%s\""
+                    + " %s",
+                AbiUtils.createAbiFlag(mAbi.getName()), deqpCommandLine, instrumentationName);
+
+        final PlatformQueryInstrumentationParser parser = new PlatformQueryInstrumentationParser();
+        mDevice.executeShellCommand(command, parser);
+        parser.flush();
+
+        if (parser.wasSuccessful() && parser.getResultCode() == 0 &&
+                parser.getResultMap().containsKey("Supported")) {
+            if ("Yes".equals(parser.getResultMap().get("Supported"))) {
+                return true;
+            } else if ("No".equals(parser.getResultMap().get("Supported"))) {
+                return false;
+            } else {
+                CLog.e("Capability query did not return a result");
+                throw new CapabilityQueryFailureException();
+            }
+        } else if (parser.wasSuccessful()) {
+            CLog.e("Failed to run capability query. Code: %d, Result: %s",
+                    parser.getResultCode(), parser.getResultMap().toString());
+            throw new CapabilityQueryFailureException();
+        } else {
+            CLog.e("Failed to run capability query");
+            throw new CapabilityQueryFailureException();
+        }
+    }
+
+    /**
+     * Return feature set supported by the device
+     */
+    private Set<String> getDeviceFeatures(ITestDevice device)
+            throws DeviceNotAvailableException, CapabilityQueryFailureException {
+        if (mDeviceFeatures == null) {
+            mDeviceFeatures = queryDeviceFeatures(device);
+        }
+        return mDeviceFeatures;
+    }
+
+    /**
+     * Query feature set supported by the device
+     */
+    private static Set<String> queryDeviceFeatures(ITestDevice device)
+            throws DeviceNotAvailableException, CapabilityQueryFailureException {
+        // NOTE: Almost identical code in BaseDevicePolicyTest#hasDeviceFeatures
+        // TODO: Move this logic to ITestDevice.
+        String command = "pm list features";
+        String commandOutput = device.executeShellCommand(command);
+
+        // Extract the id of the new user.
+        HashSet<String> availableFeatures = 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(":");
+            if (tokens.length < 2 || !"feature".equals(tokens[0])) {
+                CLog.e("Failed parse features. Unexpect format on line \"%s\"", tokens[0]);
+                throw new CapabilityQueryFailureException();
+            }
+            availableFeatures.add(tokens[1]);
+        }
+        return availableFeatures;
+    }
+
+    private boolean isPortraitClassRotation(String rotation) {
+        return BatchRunConfiguration.ROTATION_PORTRAIT.equals(rotation) ||
+                BatchRunConfiguration.ROTATION_REVERSE_PORTRAIT.equals(rotation);
+    }
+
+    private boolean isLandscapeClassRotation(String rotation) {
+        return BatchRunConfiguration.ROTATION_LANDSCAPE.equals(rotation) ||
+                BatchRunConfiguration.ROTATION_REVERSE_LANDSCAPE.equals(rotation);
+    }
+
+    /**
      * Install dEQP OnDevice Package
      */
     private void installTestApk() throws DeviceNotAvailableException {
@@ -473,60 +1768,53 @@
     }
 
     /**
-     * {@inheritDoc}
+     * Parse gl nature from package name
      */
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        mListener = listener;
-
-        if ((mName.equals( "dEQP-GLES3") && isSupportedGles(mDevice, 3, 0))
-            || (mName.equals("dEQP-GLES31") && isSupportedGles(mDevice, 3, 1))) {
-
-            // Make sure there is no pre-existing package form earlier interrupted test run.
-            uninstallTestApk();
-            installTestApk();
-
-            while (!mTests.isEmpty()) {
-                executeTests(listener);
-
-                // Set test to failed if it didn't receive test result
-                if (mCurrentTestId != null) {
-                    Map <String, String> emptyMap = Collections.emptyMap();
-
-                    if (mLogData && mCurrentTestLog != null && mCurrentTestLog.length() > 0) {
-                        ByteArrayInputStreamSource source
-                                = new ByteArrayInputStreamSource(mCurrentTestLog.getBytes());
-
-                        mListener.testLog(mCurrentTestId.getClassName() + "."
-                                + mCurrentTestId.getTestName(), LogDataType.XML, source);
-
-                        source.cancel();
-                    }
-                    if (!mGotTestResult) {
-                        mListener.testFailed(mCurrentTestId,
-                            INCOMPLETE_LOG_MESSAGE);
-                    }
-
-                    mListener.testEnded(mCurrentTestId, emptyMap);
-                    mCurrentTestId = null;
-                    mListener.testRunEnded(0, emptyMap);
-                }
-            }
-
-            uninstallTestApk();
+    private boolean isOpenGlEsPackage() {
+        if ("dEQP-GLES2".equals(mName) || "dEQP-GLES3".equals(mName) ||
+                "dEQP-GLES31".equals(mName)) {
+            return true;
+        } else if ("dEQP-EGL".equals(mName)) {
+            return false;
         } else {
-            /* Pass all tests if OpenGL ES version is not supported */
-            Map <String, String> emptyMap = Collections.emptyMap();
-            String id = AbiUtils.createId(mAbi.getName(), mPackageName);
-            mListener.testRunStarted(id, mTests.size());
+            throw new IllegalStateException("dEQP runner was created with illegal name");
+        }
+    }
 
-            for (TestIdentifier test : mTests) {
-                CLog.d("Skipping test '%s', Opengl ES version not supported", test.toString());
-                mListener.testStarted(test);
-                mListener.testEnded(test, emptyMap);
-            }
+    /**
+     * Check GL support (based on package name)
+     */
+    private boolean isSupportedGles() throws DeviceNotAvailableException {
+        return isSupportedGles(mDevice, getGlesMajorVersion(), getGlesMinorVersion());
+    }
 
-            mListener.testRunEnded(0, emptyMap);
+    /**
+     * Get GL major version (based on package name)
+     */
+    private int getGlesMajorVersion() throws DeviceNotAvailableException {
+        if ("dEQP-GLES2".equals(mName)) {
+            return 2;
+        } else if ("dEQP-GLES3".equals(mName)) {
+            return 3;
+        } else if ("dEQP-GLES31".equals(mName)) {
+            return 3;
+        } else {
+            throw new IllegalStateException("getGlesMajorVersion called for non gles pkg");
+        }
+    }
+
+    /**
+     * Get GL minor version (based on package name)
+     */
+    private int getGlesMinorVersion() throws DeviceNotAvailableException {
+        if ("dEQP-GLES2".equals(mName)) {
+            return 0;
+        } else if ("dEQP-GLES3".equals(mName)) {
+            return 0;
+        } else if ("dEQP-GLES31".equals(mName)) {
+            return 1;
+        } else {
+            throw new IllegalStateException("getGlesMinorVersion called for non gles pkg");
         }
     }
 
@@ -534,15 +1822,35 @@
      * {@inheritDoc}
      */
     @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
+    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
+        final Map<String, String> emptyMap = Collections.emptyMap();
+        final boolean isSupportedApi = !isOpenGlEsPackage() || isSupportedGles();
 
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
+        listener.testRunStarted(getId(), mRemainingTests.size());
+
+        try {
+            if (isSupportedApi) {
+                // Make sure there is no pre-existing package form earlier interrupted test run.
+                uninstallTestApk();
+                installTestApk();
+
+                mInstanceListerner.setSink(listener);
+                mDeviceRecovery.setDevice(mDevice);
+                runTests();
+
+                uninstallTestApk();
+            } else {
+                // Pass all tests if OpenGL ES version is not supported
+                CLog.i("Package %s not supported by the device. Tests trivially pass.", mPackageName);
+                fakePassTests(listener);
+            }
+        } catch (CapabilityQueryFailureException ex) {
+            // Platform is not behaving correctly, for example crashing when trying to create
+            // a window. Instead of silenty failing, signal failure by leaving the rest of the
+            // test cases in "NotExecuted" state
+            uninstallTestApk();
+        }
+
+        listener.testRunEnded(0, emptyMap);
     }
 }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DisplayTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DisplayTestRunner.java
deleted file mode 100644
index 3dee99e..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/DisplayTestRunner.java
+++ /dev/null
@@ -1,47 +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.tradefed.testtype;
-
-import com.android.cts.tradefed.targetprep.SettingsToggler;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.result.ITestInvocationListener;
-
-/**
- * Running the display tests requires modification of secure settings to create an overlay display.
- * Secure settings cannot be changed from device CTS tests since system signature permission is
- * required. Such settings can be modified by the shell user, so a host side test is used.
- */
-public class DisplayTestRunner extends CtsInstrumentationApkTest {
-    private static final String OVERLAY_DISPLAY_DEVICES_SETTING_NAME = "overlay_display_devices";
-
-    // Use a non-standard pattern, must match values in tests/tests/display/.../DisplayTest.java
-    private static final String OVERLAY_DISPLAY_DEVICES_SETTING_VALUE = "181x161/214";
-
-    @Override
-    public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
-        // CLog.e("run: About to enable overlay display.");
-        SettingsToggler.setGlobalString(getDevice(), OVERLAY_DISPLAY_DEVICES_SETTING_NAME,
-                OVERLAY_DISPLAY_DEVICES_SETTING_VALUE);
-
-        super.run(listener);
-
-        // Tear down overlay display.
-        // CLog.e("run: About to disable overlay display.");
-        SettingsToggler.setGlobalString(getDevice(), OVERLAY_DISPLAY_DEVICES_SETTING_NAME,
-                "");
-    }
-}
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 6c2ed65..9cbcd20 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
@@ -29,6 +29,8 @@
 import com.android.tradefed.testtype.IRemoteTest;
 
 import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * Test runner for native gTests.
@@ -43,8 +45,9 @@
     private static final String NATIVE_TESTS_DIRECTORY = "/data/local/tmp/cts-native-tests";
     private static final String NATIVE_TESTS_DIRECTORY_TMP = "/data/local/tmp";
     private static final String ANDROID_PATH_SEPARATOR = "/";
+    private static final String GTEST_FLAG_FILTER = "--gtest_filter=";
 
-    private int mMaxTestTimeMs = 1 * 60 * 1000;
+    private int mMaxTestTimeMs = 1 * 90 * 1000;
 
     private CtsBuildHelper mCtsBuild;
     private ITestDevice mDevice;
@@ -53,11 +56,48 @@
 
     private final String mPackageName;
 
+    private String mPositiveFilters = "";
+    private String mNegativeFilters = "";
+
     public GeeTest(String packageName, String exeName) {
         mPackageName = packageName;
         mExeName = exeName;
     }
 
+    public void setPositiveFilters(String positiveFilters) {
+        mPositiveFilters = positiveFilters;
+    }
+
+    public void setNegativeFilters(String negativeFilters) {
+        mNegativeFilters = negativeFilters;
+    }
+
+    protected String getGTestFilters() {
+        // If both filters are empty or null return empty string.
+        if (mPositiveFilters == null && mNegativeFilters == null) {
+            return "";
+        }
+        if (mPositiveFilters.isEmpty() && mNegativeFilters.isEmpty()) {
+            return "";
+        }
+        // Build filter string.
+        StringBuilder sb = new StringBuilder();
+        sb.append(GTEST_FLAG_FILTER);
+        boolean hasPositiveFilters = false;
+        if (mPositiveFilters != null && !mPositiveFilters.isEmpty()) {
+            sb.append(mPositiveFilters);
+            hasPositiveFilters = true;
+        }
+        if (mNegativeFilters != null && ! mNegativeFilters.isEmpty()) {
+            if (hasPositiveFilters) {
+                sb.append(":");
+            }
+            sb.append("-");
+            sb.append(mNegativeFilters);
+        }
+        return sb.toString();
+    }
+
     /**
      * @param abi The ABI to run the test on
      */
@@ -113,7 +153,7 @@
         resultParser.setFakePackagePrefix(mPackageName + ".");
 
         String fullPath = NATIVE_TESTS_DIRECTORY + ANDROID_PATH_SEPARATOR + mExeName;
-        String flags = "";
+        String flags = getGTestFilters();
         CLog.v("Running gtest %s %s on %s", fullPath, flags, mDevice.getSerialNumber());
         // force file to be executable
         CLog.v("%s", mDevice.executeShellCommand(String.format("chmod 755 %s", fullPath)));
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 8a5c822..630dee3 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
@@ -17,11 +17,13 @@
 package com.android.cts.tradefed.testtype;
 
 import com.android.ddmlib.testrunner.TestIdentifier;
+import com.android.tradefed.targetprep.ITargetPreparer;
 import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.testtype.IRemoteTest;
 
 import java.io.File;
 import java.util.Collection;
+import java.util.List;
 
 /**
  * Container for CTS test info.
@@ -70,6 +72,11 @@
     public IAbi getAbi();
 
     /**
+     * @return the estimated running time of this test package.
+     */
+    public long getRuntimeHint();
+
+    /**
      * Set the filter to use for tests
      *
      * @param testFilter
@@ -98,4 +105,9 @@
      */
     public String getTargetPackageName();
 
+    /**
+     * Return a list of preparers used for setup or teardown of test cases in this package
+     * @return
+     */
+    public List<ITargetPreparer> getPackagePreparers();
 }
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRemoteTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRemoteTestRunner.java
deleted file mode 100644
index 72dccd4..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRemoteTestRunner.java
+++ /dev/null
@@ -1,282 +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.tradefed.testtype;
-
-import com.android.ddmlib.AdbCommandRejectedException;
-import com.android.ddmlib.IShellEnabledDevice;
-import com.android.ddmlib.Log;
-import com.android.ddmlib.ShellCommandUnresponsiveException;
-import com.android.ddmlib.TimeoutException;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.ITestRunListener;
-import com.android.ddmlib.testrunner.InstrumentationResultParser;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.TimeUnit;
-
-public class PrintTestRemoteTestRunner implements IRemoteAndroidTestRunner {
-
-    private final String mPackageName;
-    private final String mRunnerName;
-    private IShellEnabledDevice mRemoteDevice;
-    // default to no timeout
-    private long mMaxTimeToOutputResponse = 0;
-    private TimeUnit mMaxTimeUnits = TimeUnit.MILLISECONDS;
-    private String mRunName = null;
-
-    /** map of name-value instrumentation argument pairs */
-    private Map<String, String> mArgMap;
-    private InstrumentationResultParser mParser;
-
-    private static final String LOG_TAG = "RemoteAndroidTest";
-    private static final String DEFAULT_RUNNER_NAME = "android.test.InstrumentationTestRunner";
-
-    private static final char CLASS_SEPARATOR = ',';
-    private static final char METHOD_SEPARATOR = '#';
-    private static final char RUNNER_SEPARATOR = '/';
-
-    // defined instrumentation argument names
-    private static final String CLASS_ARG_NAME = "class";
-    private static final String LOG_ARG_NAME = "log";
-    private static final String DEBUG_ARG_NAME = "debug";
-    private static final String COVERAGE_ARG_NAME = "coverage";
-    private static final String PACKAGE_ARG_NAME = "package";
-    private static final String SIZE_ARG_NAME = "size";
-
-    // This command starts a shell Java program (installed by this class)
-    // in the folder owned by the shell user. This app creates a proxy
-    // which does privileged operations such as wiping a package's user
-    // data and then starts the tests passing the proxy. This enables
-    // the tests to clear the print spooler data.
-    private static final String INSTRUMENTATION_COMMAND =
-            "chmod 755 /data/local/tmp/print-instrument && "
-            + "/data/local/tmp/print-instrument instrument -w -r %1$s %2$s";
-
-    /**
-     * Creates a remote Android test runner.
-     *
-     * @param packageName the Android application package that contains the
-     *            tests to run
-     * @param runnerName the instrumentation test runner to execute. If null,
-     *            will use default runner
-     * @param remoteDevice the Android device to execute tests on
-     */
-    public PrintTestRemoteTestRunner(String packageName, String runnerName,
-            IShellEnabledDevice remoteDevice) {
-
-        mPackageName = packageName;
-        mRunnerName = runnerName;
-        mRemoteDevice = remoteDevice;
-        mArgMap = new Hashtable<String, String>();
-    }
-
-    /**
-     * Alternate constructor. Uses default instrumentation runner.
-     *
-     * @param packageName the Android application package that contains the
-     *            tests to run
-     * @param remoteDevice the Android device to execute tests on
-     */
-    public PrintTestRemoteTestRunner(String packageName, IShellEnabledDevice remoteDevice) {
-        this(packageName, null, remoteDevice);
-    }
-
-    @Override
-    public String getPackageName() {
-        return mPackageName;
-    }
-
-    @Override
-    public String getRunnerName() {
-        if (mRunnerName == null) {
-            return DEFAULT_RUNNER_NAME;
-        }
-        return mRunnerName;
-    }
-
-    /**
-     * Returns the complete instrumentation component path.
-     */
-    private String getRunnerPath() {
-        return getPackageName() + RUNNER_SEPARATOR + getRunnerName();
-    }
-
-    @Override
-    public void setClassName(String className) {
-        addInstrumentationArg(CLASS_ARG_NAME, className);
-    }
-
-    @Override
-    public void setClassNames(String[] classNames) {
-        StringBuilder classArgBuilder = new StringBuilder();
-
-        for (int i = 0; i < classNames.length; i++) {
-            if (i != 0) {
-                classArgBuilder.append(CLASS_SEPARATOR);
-            }
-            classArgBuilder.append(classNames[i]);
-        }
-        setClassName(classArgBuilder.toString());
-    }
-
-    @Override
-    public void setMethodName(String className, String testName) {
-        setClassName(className + METHOD_SEPARATOR + testName);
-    }
-
-    @Override
-    public void setTestPackageName(String packageName) {
-        addInstrumentationArg(PACKAGE_ARG_NAME, packageName);
-    }
-
-    @Override
-    public void addInstrumentationArg(String name, String value) {
-        if (name == null || value == null) {
-            throw new IllegalArgumentException("name or value arguments cannot be null");
-        }
-        mArgMap.put(name, value);
-    }
-
-    @Override
-    public void removeInstrumentationArg(String name) {
-        if (name == null) {
-            throw new IllegalArgumentException("name argument cannot be null");
-        }
-        mArgMap.remove(name);
-    }
-
-    @Override
-    public void addBooleanArg(String name, boolean value) {
-        addInstrumentationArg(name, Boolean.toString(value));
-    }
-
-    @Override
-    public void setLogOnly(boolean logOnly) {
-        addBooleanArg(LOG_ARG_NAME, logOnly);
-    }
-
-    @Override
-    public void setDebug(boolean debug) {
-        addBooleanArg(DEBUG_ARG_NAME, debug);
-    }
-
-    @Override
-    public void setCoverage(boolean coverage) {
-        addBooleanArg(COVERAGE_ARG_NAME, coverage);
-    }
-
-    @Override
-    public void setTestCollection(boolean b) {
-        throw new UnsupportedOperationException("Test Collection mode is not supported");
-    }
-
-    @Override
-    public void setTestSize(TestSize size) {
-        addInstrumentationArg(SIZE_ARG_NAME, ""/*size.getRunnerValue()*/);
-    }
-
-    @Override
-    public void setMaxtimeToOutputResponse(int maxTimeToOutputResponse) {
-        setMaxTimeToOutputResponse(maxTimeToOutputResponse, TimeUnit.MILLISECONDS);
-    }
-
-    @Override
-    public void setMaxTimeToOutputResponse(long maxTimeToOutputResponse, TimeUnit maxTimeUnits) {
-        mMaxTimeToOutputResponse = maxTimeToOutputResponse;
-        mMaxTimeUnits = maxTimeUnits;
-    }
-
-    @Override
-    public void setRunName(String runName) {
-        mRunName = runName;
-    }
-
-    @Override
-    public void run(ITestRunListener... listeners) throws TimeoutException,
-            AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
-        run(Arrays.asList(listeners));
-    }
-
-    @Override
-    public void run(Collection<ITestRunListener> listeners) throws TimeoutException,
-            AdbCommandRejectedException, ShellCommandUnresponsiveException, IOException {
-        final String runCaseCommandStr = String.format(INSTRUMENTATION_COMMAND,
-              getArgsCommand(), getRunnerPath());
-        Log.i(LOG_TAG,
-                String.format("Running %1$s on %2$s", runCaseCommandStr, mRemoteDevice.getName()));
-        String runName = mRunName == null ? mPackageName : mRunName;
-        mParser = new InstrumentationResultParser(runName, listeners);
-
-        try {
-            mRemoteDevice.executeShellCommand(runCaseCommandStr, mParser, mMaxTimeToOutputResponse,
-                    mMaxTimeUnits);
-        } catch (IOException e) {
-            Log.w(LOG_TAG, String.format("IOException %1$s when running tests %2$s on %3$s",
-                    e.toString(), getPackageName(), mRemoteDevice.getName()));
-            // rely on parser to communicate results to listeners
-            mParser.handleTestRunFailed(e.toString());
-            throw e;
-        } catch (ShellCommandUnresponsiveException e) {
-            Log.w(LOG_TAG, String.format(
-                    "ShellCommandUnresponsiveException %1$s when running tests %2$s on %3$s",
-                    e.toString(), getPackageName(), mRemoteDevice.getName()));
-            mParser.handleTestRunFailed(String
-                    .format("Failed to receive adb shell test output within %1$d ms. "
-                            + "Test may have timed out, or adb connection to device became"
-                            + "unresponsive", mMaxTimeToOutputResponse));
-            throw e;
-        } catch (TimeoutException e) {
-            Log.w(LOG_TAG, String.format("TimeoutException when running tests %1$s on %2$s",
-                    getPackageName(), mRemoteDevice.getName()));
-            mParser.handleTestRunFailed(e.toString());
-            throw e;
-        } catch (AdbCommandRejectedException e) {
-            Log.w(LOG_TAG, String.format(
-                    "AdbCommandRejectedException %1$s when running tests %2$s on %3$s",
-                    e.toString(), getPackageName(), mRemoteDevice.getName()));
-            mParser.handleTestRunFailed(e.toString());
-            throw e;
-        }
-    }
-
-    @Override
-    public void cancel() {
-        if (mParser != null) {
-            mParser.cancel();
-        }
-    }
-
-    /**
-     * Returns the full instrumentation command line syntax for the provided
-     * instrumentation arguments. Returns an empty string if no arguments were
-     * specified.
-     */
-    private String getArgsCommand() {
-        StringBuilder commandBuilder = new StringBuilder();
-        for (Entry<String, String> argPair : mArgMap.entrySet()) {
-            final String argCmd = String.format(" -e %1$s %2$s", argPair.getKey(),
-                    argPair.getValue());
-            commandBuilder.append(argCmd);
-        }
-        return commandBuilder.toString();
-    }
-}
diff --git a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRunner.java b/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRunner.java
deleted file mode 100644
index 44d2d3a..0000000
--- a/tools/tradefed-host/src/com/android/cts/tradefed/testtype/PrintTestRunner.java
+++ /dev/null
@@ -1,232 +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.tradefed.testtype;
-
-import com.android.cts.tradefed.build.CtsBuildHelper;
-import com.android.cts.tradefed.targetprep.SettingsToggler;
-import com.android.cts.util.AbiUtils;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner;
-import com.android.ddmlib.testrunner.IRemoteAndroidTestRunner.TestSize;
-import com.android.tradefed.build.IBuildInfo;
-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.testtype.IBuildReceiver;
-import com.android.tradefed.testtype.IDeviceTest;
-import com.android.tradefed.testtype.IRemoteTest;
-import com.android.tradefed.util.StringEscapeUtils;
-
-import java.io.FileNotFoundException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Running the print tests requires modification of secure settings. Secure
- * settings cannot be changed from device CTS tests since system signature
- * permission is required. Such settings can be modified by the shell user,
- * so a host side test driver is used for enabling these services, running
- * the tests, and disabling the services.
- */
-public class PrintTestRunner implements IBuildReceiver, IRemoteTest, IDeviceTest  {
-
-    private static final String PRINT_TEST_AND_SERVICES_APP_NAME =
-            "CtsPrintTestCases.apk";
-
-    private static final String PRINT_TESTS_PACKAGE_NAME =
-            "com.android.cts.print";
-
-    private static final String FIRST_PRINT_SERVICE_NAME =
-            "android.print.cts.services.FirstPrintService";
-
-    private static final String SECOND_PRINT_SERVICE_NAME =
-            "android.print.cts.services.SecondPrintService";
-
-    private static final String SHELL_USER_FOLDER = "data/local/tmp";
-
-    private static final String PRINT_INSTRUMENT_JAR = "CtsPrintInstrument.jar";
-
-    private static final String PRINT_INSTRUMENT_SCRIPT = "print-instrument";
-
-    private ITestDevice mDevice;
-
-    private CtsBuildHelper mCtsBuild;
-
-    private IAbi mAbi;
-    private String mPackageName;
-    private String mRunnerName = "android.test.InstrumentationTestRunner";
-    private String mTestClassName;
-    private String mTestMethodName;
-    private String mTestPackageName;
-    private int mTestTimeout = 10 * 60 * 1000;  // 10 minutes
-    private String mTestSize;
-    private String mRunName = null;
-    private Map<String, String> mInstrArgMap = new HashMap<String, String>();
-
-    /**
-     * @param abi The ABI to run the test on
-     */
-    public void setAbi(IAbi abi) {
-        mAbi = abi;
-    }
-
-    @Override
-    public void setBuild(IBuildInfo buildInfo) {
-        mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
-    }
-
-    @Override
-    public void setDevice(ITestDevice device) {
-        mDevice = device;
-    }
-
-    @Override
-    public ITestDevice getDevice() {
-        return mDevice;
-    }
-
-    public void setPackageName(String packageName) {
-        mPackageName = packageName;
-    }
-
-    public void setRunnerName(String runnerName) {
-        mRunnerName = runnerName;
-    }
-
-    public void setClassName(String testClassName) {
-        mTestClassName = testClassName;
-    }
-
-    public void setMethodName(String testMethodName) {
-        mTestMethodName = StringEscapeUtils.escapeShell(testMethodName);
-    }
-
-    public void setTestPackageName(String testPackageName) {
-        mTestPackageName = testPackageName;
-    }
-
-    public void setTestSize(String size) {
-        mTestSize = size;
-    }
-
-    public void setRunName(String runName) {
-        mRunName = runName;
-    }
-
-    @Override
-    public void run(final ITestInvocationListener listener) throws DeviceNotAvailableException {
-        installShellProgramAndScriptFiles();
-        installTestsAndServicesApk();
-        enablePrintServices();
-        doRunTests(listener);
-        disablePrintServices();
-        uninstallTestsAndServicesApk();
-        uninstallShellProgramAndScriptFiles();
-    }
-
-    private void doRunTests(ITestInvocationListener listener)
-            throws DeviceNotAvailableException {
-        if (mPackageName == null) {
-            throw new IllegalArgumentException("package name has not been set");
-        }
-        if (mDevice == null) {
-            throw new IllegalArgumentException("Device has not been set");
-        }
-
-        IRemoteAndroidTestRunner runner =  new PrintTestRemoteTestRunner(mPackageName,
-                mRunnerName, mDevice.getIDevice());
-
-        if (mTestClassName != null) {
-            if (mTestMethodName != null) {
-                runner.setMethodName(mTestClassName, mTestMethodName);
-            } else {
-                runner.setClassName(mTestClassName);
-            }
-        } else if (mTestPackageName != null) {
-            runner.setTestPackageName(mTestPackageName);
-        }
-        if (mTestSize != null) {
-            runner.setTestSize(TestSize.getTestSize(mTestSize));
-        }
-        runner.setMaxTimeToOutputResponse(mTestTimeout, TimeUnit.MILLISECONDS);
-        if (mRunName != null) {
-            runner.setRunName(mRunName);
-        }
-        for (Map.Entry<String, String> argEntry : mInstrArgMap.entrySet()) {
-            runner.addInstrumentationArg(argEntry.getKey(), argEntry.getValue());
-        }
-
-        mDevice.runInstrumentationTests(runner, listener);
-    }
-
-    private void installShellProgramAndScriptFiles() throws DeviceNotAvailableException {
-        installFile(PRINT_INSTRUMENT_JAR);
-        installFile(PRINT_INSTRUMENT_SCRIPT);
-    }
-
-    private void installFile(String fileName) throws DeviceNotAvailableException {
-        try {
-            final boolean success = getDevice().pushFile(mCtsBuild.getTestApp(
-                    fileName), SHELL_USER_FOLDER + "/" + fileName);
-            if (!success) {
-                throw new IllegalArgumentException("Failed to install "
-                        + fileName + " on " + getDevice().getSerialNumber());
-           }
-        } catch (FileNotFoundException fnfe) {
-            throw new IllegalArgumentException("Cannot find file: " + fileName);
-        }
-    }
-
-    private void uninstallShellProgramAndScriptFiles() throws DeviceNotAvailableException {
-        getDevice().executeShellCommand("rm " + SHELL_USER_FOLDER + "/"
-                + PRINT_INSTRUMENT_JAR);
-        getDevice().executeShellCommand("rm " + SHELL_USER_FOLDER + "/"
-                + PRINT_INSTRUMENT_SCRIPT);
-    }
-
-    private void installTestsAndServicesApk() throws DeviceNotAvailableException {
-        try {
-            String[] options = {AbiUtils.createAbiFlag(mAbi.getName())};
-            String installCode = getDevice().installPackage(mCtsBuild.getTestApp(
-                    PRINT_TEST_AND_SERVICES_APP_NAME), true, options);
-            if (installCode != null) {
-                throw new IllegalArgumentException("Failed to install "
-                        + PRINT_TEST_AND_SERVICES_APP_NAME + " on " + getDevice().getSerialNumber()
-                        + ". Reason: " + installCode);
-           }
-        } catch (FileNotFoundException fnfe) {
-            throw new IllegalArgumentException("Cannot find file: "
-                    + PRINT_TEST_AND_SERVICES_APP_NAME);
-        }
-    }
-
-    private void uninstallTestsAndServicesApk() throws DeviceNotAvailableException {
-        getDevice().uninstallPackage(PRINT_TESTS_PACKAGE_NAME);
-    }
-
-    private void enablePrintServices() throws DeviceNotAvailableException {
-        String enabledServicesValue = PRINT_TESTS_PACKAGE_NAME + "/" + FIRST_PRINT_SERVICE_NAME
-                + ":" + PRINT_TESTS_PACKAGE_NAME + "/" + SECOND_PRINT_SERVICE_NAME;
-        SettingsToggler.setSecureString(getDevice(), "enabled_print_services",
-                enabledServicesValue);
-    }
-
-    private void disablePrintServices() throws DeviceNotAvailableException {
-        SettingsToggler.setSecureString(getDevice(), "enabled_print_services", "");
-    }
-}
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 9ef6257..d08c0bc 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
@@ -20,6 +20,7 @@
 import com.android.ddmlib.Log.LogLevel;
 import com.android.ddmlib.testrunner.TestIdentifier;
 import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.targetprep.ITargetPreparer;
 import com.android.tradefed.testtype.IAbi;
 import com.android.tradefed.testtype.IRemoteTest;
 import com.android.tradefed.testtype.InstrumentationTest;
@@ -35,7 +36,11 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.Collection;
+import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Container for CTS test info.
@@ -49,14 +54,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 ACCESSIBILITY_TEST =
-            "com.android.cts.tradefed.testtype.AccessibilityTestRunner";
-    public static final String ACCESSIBILITY_SERVICE_TEST =
-            "com.android.cts.tradefed.testtype.AccessibilityServiceTestRunner";
-    public static final String PRINT_TEST =
-            "com.android.cts.tradefed.testtype.PrintTestRunner";
-    public static final String DISPLAY_TEST =
-            "com.android.cts.tradefed.testtype.DisplayTestRunner";
     public static final String UIAUTOMATOR_TEST = "uiAutomator";
     public static final String JUNIT_DEVICE_TEST = "jUnitDeviceTest";
 
@@ -69,13 +66,18 @@
     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;
 
     // use a LinkedHashSet for predictable iteration insertion-order, and fast
     // lookups
     private Collection<TestIdentifier> mTests = new LinkedHashSet<TestIdentifier>();
     // also maintain an index of known test classes
     private Collection<String> mTestClasses = new LinkedHashSet<String>();
+    // store instance arguments in order too for consistency
+    private Map<TestIdentifier, List<Map<String, String>>> mTestInstanceArguments =
+            new LinkedHashMap<>();
 
     // dynamic options, not parsed from package xml
     private String mClassName;
@@ -136,6 +138,18 @@
      * {@inheritDoc}
      */
     @Override
+    public long getRuntimeHint() {
+        return mRuntimeHint;
+    }
+
+    void setRuntimeHint(long runtimeHint) {
+        mRuntimeHint = runtimeHint;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public String getName() {
         return mName;
     }
@@ -210,6 +224,22 @@
     }
 
     /**
+     * Setter for injecting a list of {@link ITargetPreparer}s as configured in module test config.
+     * @param preparers
+     */
+    void setPackagePreparers(List<ITargetPreparer> preparers) {
+        mPreparers = preparers;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<ITargetPreparer> getPackagePreparers() {
+        return mPreparers;
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
@@ -240,7 +270,8 @@
             mDigest = generateDigest(testCaseDir, mJarPath);
             return vmHostTest;
         } else if (DEQP_TEST.equals(mTestType)) {
-            DeqpTestRunner deqpTest = new DeqpTestRunner(mAppPackageName, mName, mTests);
+            DeqpTestRunner deqpTest =
+                    new DeqpTestRunner(mAppPackageName, mName, mTests, mTestInstanceArguments);
             deqpTest.setAbi(mAbi);
             return deqpTest;
         } else if (NATIVE_TEST.equals(mTestType)) {
@@ -252,19 +283,6 @@
             WrappedGTest wrappedGeeTest = new WrappedGTest(mAppNameSpace, mAppPackageName, mName, mRunner);
             wrappedGeeTest.setAbi(mAbi);
             return wrappedGeeTest;
-        } else if (ACCESSIBILITY_TEST.equals(mTestType)) {
-            AccessibilityTestRunner test = new AccessibilityTestRunner();
-            return setInstrumentationTest(test, testCaseDir);
-        } else if (PRINT_TEST.equals(mTestType)) {
-            PrintTestRunner test = new PrintTestRunner();
-            return setPrintTest(test, testCaseDir);
-        } else if (ACCESSIBILITY_SERVICE_TEST.equals(mTestType)) {
-            @SuppressWarnings("deprecation")
-            AccessibilityServiceTestRunner test = new AccessibilityServiceTestRunner();
-            return setInstrumentationTest(test, testCaseDir);
-        } else if (DISPLAY_TEST.equals(mTestType)) {
-            DisplayTestRunner test = new DisplayTestRunner();
-            return setInstrumentationTest(test, testCaseDir);
         } else if (UIAUTOMATOR_TEST.equals(mTestType)) {
             UiAutomatorJarTest uiautomatorTest = new UiAutomatorJarTest();
             return setUiAutomatorTest(uiautomatorTest);
@@ -291,19 +309,6 @@
         }
     }
 
-    private PrintTestRunner setPrintTest(PrintTestRunner printTest,
-            File testCaseDir) {
-        printTest.setRunName(mAppPackageName);
-        printTest.setPackageName(mAppNameSpace);
-        printTest.setRunnerName(mRunner);
-        printTest.setTestPackageName(mTestPackageName);
-        printTest.setClassName(mClassName);
-        printTest.setMethodName(mMethodName);
-        printTest.setAbi(mAbi);
-        mDigest = generateDigest(testCaseDir, String.format("%s.apk", mName));
-        return printTest;
-    }
-
     /**
      * Populates given {@link CtsInstrumentationApkTest} with data from the package xml.
      *
@@ -316,9 +321,6 @@
         instrTest.setRunName(mAppPackageName);
         instrTest.setPackageName(mAppNameSpace);
         instrTest.setRunnerName(mRunner);
-        instrTest.setTestPackageName(mTestPackageName);
-        instrTest.setClassName(mClassName);
-        instrTest.setMethodName(mMethodName);
         instrTest.setAbi(mAbi);
         instrTest.setTestsToRun(mTests, false
             /* force batch mode off to always run using testFile */);
@@ -379,6 +381,7 @@
     void addTest(TestIdentifier testDef, int timeout) {
         mTests.add(testDef);
         mTestClasses.add(testDef.getClassName());
+        mTestInstanceArguments.put(testDef, new LinkedList<Map<String, String>>());
         // 0 means no timeout, so keep 0 if already is.
         if ((timeout > mTimeoutInMins) && (mTimeoutInMins != 0)) {
             mTimeoutInMins = timeout;
@@ -386,6 +389,16 @@
     }
 
     /**
+     * Add a test instance to an existing {@link TestIdentifier}.
+     */
+    void addTestInstance(TestIdentifier testDef, Map<String, String> instanceArguments) {
+        if (!mTestInstanceArguments.containsKey(testDef)) {
+            throw new IllegalStateException("test id does not name an existing test");
+        }
+        mTestInstanceArguments.get(testDef).add(instanceArguments);
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
@@ -394,6 +407,15 @@
     }
 
     /**
+     * Get the instance argument map for tests.
+     * <p/>
+     * Exposed for unit testing.
+     */
+    public Map<TestIdentifier, List<Map<String, String>>> getTestInstanceArguments() {
+        return mTestInstanceArguments;
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
@@ -427,8 +449,8 @@
         } catch (IOException e) {
             CLog.e(e);
         } finally {
-            StreamUtil.closeStream(d);
-            StreamUtil.closeStream(fileStream);
+            StreamUtil.close(d);
+            StreamUtil.close(fileStream);
         }
         return "failed to generate digest";
     }
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 aea6613..7e16170 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
@@ -17,6 +17,9 @@
 
 import com.android.cts.util.AbiUtils;
 import com.android.ddmlib.Log;
+import com.android.tradefed.config.ConfigurationException;
+import com.android.tradefed.config.ConfigurationFactory;
+import com.android.tradefed.config.IConfiguration;
 import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
 
 import java.io.BufferedInputStream;
@@ -27,8 +30,8 @@
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -63,22 +66,68 @@
     private void parse(File dir) {
         File[] xmlFiles = dir.listFiles(new XmlFilter());
         for (File xmlFile : xmlFiles) {
-            parseTestFromXml(xmlFile);
+            parseModuleTestConfigs(xmlFile);
         }
     }
 
-    private void parseTestFromXml(File xmlFile)  {
+    /**
+     * Infer package preparer config from package XML definition file and return if exists
+     * @param pkgXml {@link File} instance referencing the package XML definition
+     * @return the matching package preparer if exists, <code>null</code> otherwise
+     */
+    private File getPreparerDefForPackage(File pkgXml) {
+        String fullPath = pkgXml.getAbsolutePath();
+        int lastDot = fullPath.lastIndexOf('.');
+        if (lastDot == -1) {
+            // huh?
+            return null;
+        }
+        File preparer = new File(fullPath.substring(0, lastDot) + ".config");
+        if (preparer.exists()) {
+            return preparer;
+        }
+        return null;
+    }
+
+    /**
+     * Processes test module definition XML file, and stores parsed data structure in class member
+     * variable. Parsed config objects will be associated with each applicable ABI type so multiple
+     * {@link TestPackageDef}s will be generated accordingly. In addition, based on
+     * &lt;module name&gt;.config file naming convention, this method also looks for the optional
+     * module test config, and attaches defined configuration objects to the {@link TestPackageDef}
+     * representing the module accordingly.
+     * @param xmlFile the module definition XML
+     */
+    private void parseModuleTestConfigs(File xmlFile)  {
         TestPackageXmlParser parser = new TestPackageXmlParser(mIncludeKnownFailures);
         try {
             parser.parse(createStreamFromFile(xmlFile));
+            // based on test module XML file path, and the <module name>.config naming convention,
+            // infers the module test config file, and parses it
+            File preparer = getPreparerDefForPackage(xmlFile);
+            IConfiguration config = null;
+            if (preparer != null) {
+                try {
+                    // invokes parser to process the test module config file
+                    config = ConfigurationFactory.getInstance().createConfigurationFromArgs(
+                            new String[]{preparer.getAbsolutePath()});
+                } catch (ConfigurationException e) {
+                    throw new RuntimeException(
+                            String.format("error parsing config file: %s", xmlFile.getName()), e);
+                }
+            }
             Set<TestPackageDef> defs = parser.getTestPackageDefs();
             if (defs.isEmpty()) {
                 Log.w(LOG_TAG, String.format("Could not find test package info in xml file %s",
                         xmlFile.getAbsolutePath()));
             }
+            // loops over multiple package defs defined for each ABI type
             for (TestPackageDef def : defs) {
                 String name = def.getAppPackageName();
                 String abi = def.getAbi().getName();
+                if (config != null) {
+                    def.setPackagePreparers(config.getTargetPreparers());
+                }
                 if (!mTestMap.containsKey(abi)) {
                     mTestMap.put(abi, new HashMap<String, TestPackageDef>());
                 }
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 baceb8b..951c461 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
@@ -59,6 +59,7 @@
      *     <TestSuite ...>
      *        <TestCase>
      *           <Test>
+     *             <TestInstance> (optional)
      */
     private class TestPackageHandler extends DefaultHandler {
 
@@ -66,9 +67,11 @@
         private static final String TEST_SUITE_TAG = "TestSuite";
         private static final String TEST_CASE_TAG = "TestCase";
         private static final String TEST_TAG = "Test";
+        private static final String TEST_INSTANCE_TAG = "TestInstance";
 
         // holds current class name segments
         private Stack<String> mClassNameStack = new Stack<String>();
+        private TestIdentifier mTestId;
 
         @Override
         public void startElement(String uri, String localName, String name, Attributes attributes) {
@@ -83,6 +86,10 @@
                 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()) {
                     Abi abi = new Abi(abiName, AbiUtils.getBitness(abiName));
@@ -99,6 +106,7 @@
                     }
                     packageDef.setTargetBinaryName(targetBinaryName);
                     packageDef.setTargetNameSpace(targetNameSpace);
+                    packageDef.setRuntimeHint(runTimeHint);
                     packageDef.setAbi(abi);
                     mPackageDefs.put(abiName, packageDef);
                 }
@@ -139,6 +147,7 @@
                             classNameBuilder.append(".");
                         }
                     }
+                    mTestId = new TestIdentifier(classNameBuilder.toString(), methodName);
                     int timeout = -1;
                     String timeoutStr = attributes.getValue("timeout");
                     if (timeoutStr != null) {
@@ -158,14 +167,24 @@
                             }
                         }
                         for (String abi : abis) {
-                            TestIdentifier testId = new TestIdentifier(
-                                    classNameBuilder.toString(), methodName);
-                            mPackageDefs.get(abi).addTest(testId, timeout);
+                            mPackageDefs.get(abi).addTest(mTestId, timeout);
                         }
                     }
                 }
+            } else if (TEST_INSTANCE_TAG.equals(localName)) {
+                if (mTestId != null) {
+                    final Map<String, String> instanceArguments = genAttributeMap(attributes);
+                    for (TestPackageDef packageDef : mPackageDefs.values()) {
+                        if (packageDef.getTests().contains(mTestId)) {
+                            packageDef.addTestInstance(mTestId, instanceArguments);
+                        }
+                    }
+                } else {
+                    Log.e(LOG_TAG, String.format(
+                            "Invalid XML: encountered a '%s' tag not enclosed within a '%s' tag",
+                            TEST_INSTANCE_TAG, TEST_TAG));
+                }
             }
-
         }
 
         private String getTestType(Attributes attributes) {
@@ -182,6 +201,8 @@
         public void endElement (String uri, String localName, String qName) {
             if (TEST_SUITE_TAG.equals(localName) || TEST_CASE_TAG.equals(localName)) {
                 mClassNameStack.pop();
+            } else if (TEST_TAG.equals(localName)) {
+                mTestId = null;
             }
         }
 
@@ -192,6 +213,19 @@
             return stringValue != null &&
                     Boolean.parseBoolean(stringValue);
         }
+
+        private Map<String, String> genAttributeMap(Attributes attributes) {
+            final Map<String, String> attribMap = new HashMap<String, String>();
+            for (int i = 0; i < attributes.getLength(); ++i) {
+                final String localName = attributes.getLocalName(i);
+                final String namespace = attributes.getURI(i);
+                final String fullyQualifiedName =
+                        (namespace.isEmpty()) ? (localName) : (namespace + ":" + localName);
+
+                attribMap.put(fullyQualifiedName, attributes.getValue(i));
+            }
+            return attribMap;
+        }
     }
 
     @Override
diff --git a/tools/tradefed-host/tests/run_unit_func_tests.sh b/tools/tradefed-host/tests/run_unit_func_tests.sh
new file mode 100755
index 0000000..461a80d
--- /dev/null
+++ b/tools/tradefed-host/tests/run_unit_func_tests.sh
@@ -0,0 +1,48 @@
+#!/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 the cts-tradefed 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 hosttestlib.jar cts-tradefed.jar cts-tradefed-tests.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 --class com.android.cts.tradefed.FuncTests "$@"
diff --git a/tools/tradefed-host/tests/run_unit_tests.sh b/tools/tradefed-host/tests/run_unit_tests.sh
index 771dc75..d089c05 100755
--- a/tools/tradefed-host/tests/run_unit_tests.sh
+++ b/tools/tradefed-host/tests/run_unit_tests.sh
@@ -46,4 +46,3 @@
 
 java $RDBG_FLAG \
   -cp ${JAR_PATH} com.android.tradefed.command.Console run singleCommand host -n --class com.android.cts.tradefed.UnitTests "$@"
-
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/FuncTests.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/FuncTests.java
new file mode 100644
index 0000000..a9420d2
--- /dev/null
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/FuncTests.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.cts.tradefed;
+
+import com.android.cts.tradefed.device.DeviceInfoCollectorFuncTest;
+import com.android.tradefed.testtype.DeviceTestSuite;
+
+import junit.framework.Test;
+
+/**
+ * A test suite for all cts-tradefed functional tests.
+ * <p/>
+ * Tests listed here should require a device.
+ */
+public class FuncTests extends DeviceTestSuite {
+
+    public FuncTests() {
+        super();
+
+        // device package
+        addTestSuite(DeviceInfoCollectorFuncTest.class);
+    }
+
+    public static Test suite() {
+        return new FuncTests();
+    }
+}
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java
index ad1430e..6fa648e 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/UnitTests.java
@@ -22,9 +22,11 @@
 import com.android.cts.tradefed.result.TestSummaryXmlTest;
 import com.android.cts.tradefed.result.TestTest;
 import com.android.cts.tradefed.result.TestLogTest;
+import com.android.cts.tradefed.targetprep.HostPreconditionPreparerTest;
 import com.android.cts.tradefed.testtype.Abi;
 import com.android.cts.tradefed.testtype.CtsTestTest;
 import com.android.cts.tradefed.testtype.DeqpTestRunnerTest;
+import com.android.cts.tradefed.testtype.GeeTestTest;
 import com.android.cts.tradefed.testtype.JarHostTestTest;
 import com.android.cts.tradefed.testtype.TestFilterTest;
 import com.android.cts.tradefed.testtype.TestPackageDefTest;
@@ -58,15 +60,19 @@
         addTestSuite(TestTest.class);
         addTestSuite(TestLogTest.class);
 
+        // targetprep package
+        addTestSuite(HostPreconditionPreparerTest.class);
+
         // testtype package
         addTestSuite(CtsTestTest.class);
+        addTestSuite(DeqpTestRunnerTest.class);
+        addTestSuite(GeeTestTest.class);
         addTestSuite(JarHostTestTest.class);
         addTestSuite(TestFilterTest.class);
         addTestSuite(TestPackageDefTest.class);
         addTestSuite(TestPackageXmlParserTest.class);
         addTestSuite(TestPlanTest.class);
         addTestSuite(WrappedGTestResultParserTest.class);
-        addTestSuite(DeqpTestRunnerTest.class);
     }
 
     public static Test suite() {
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/device/DeviceInfoCollectorFuncTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/device/DeviceInfoCollectorFuncTest.java
index 52a205b..60e30cc 100644
--- a/tools/tradefed-host/tests/src/com/android/cts/tradefed/device/DeviceInfoCollectorFuncTest.java
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/device/DeviceInfoCollectorFuncTest.java
@@ -15,33 +15,77 @@
  */
 package com.android.cts.tradefed.device;
 
+import com.android.ddmlib.Log.LogLevel;
 import com.android.cts.tradefed.UnitTests;
+import com.android.cts.tradefed.result.CtsXmlResultReporter;
 import com.android.tradefed.build.BuildInfo;
+import com.android.tradefed.build.IFolderBuildInfo;
 import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
 import com.android.tradefed.result.CollectingTestListener;
 import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.util.FileUtil;
 
 import java.io.File;
+import java.util.HashMap;
 import java.util.Map;
 
+import org.easymock.EasyMock;
+
 /**
  * Functional test for {@link DeviceInfoCollector}.
  * <p/>
- * TODO: this test assumes the TestDeviceSetup apk is located in the "java.io.tmpdir"
+ * TODO: this test assumes the TestDeviceSetup and DeviceInfoCollector apks are located in the
+ * "java.io.tmpdir"
  */
 public class DeviceInfoCollectorFuncTest extends DeviceTestCase {
 
-    public void testCollectDeviceInfo() throws DeviceNotAvailableException {
-        CollectingTestListener testListener = new CollectingTestListener();
+    private CollectingTestListener testListener;
+    private File mResultDir;
+    private IFolderBuildInfo mMockBuildInfo;
 
-        testListener.invocationStarted(new BuildInfo());
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        testListener = new CollectingTestListener();
+        mResultDir = FileUtil.createTempDir("cts-result-dir");
+        mMockBuildInfo = EasyMock.createMock(IFolderBuildInfo.class);
+        Map<String, String> attributes = new HashMap<>();
+        attributes.put(CtsXmlResultReporter.CTS_RESULT_DIR, mResultDir.getAbsolutePath());
+        EasyMock.expect(mMockBuildInfo.getBuildAttributes()).andStubReturn(attributes);
+        EasyMock.replay(mMockBuildInfo);
+
+        assertNotNull(getDevice().getSerialNumber());
+    }
+
+    public void testCollectDeviceInfo() throws DeviceNotAvailableException {
+        testListener.invocationStarted(mMockBuildInfo);
         DeviceInfoCollector.collectDeviceInfo(getDevice(), UnitTests.ABI.getName(), new File(
                 System.getProperty("java.io.tmpdir")), testListener);
         assertNotNull(testListener.getCurrentRunResults());
-        assertTrue(testListener.getCurrentRunResults().getRunMetrics().size() > 0);
-        for (Map.Entry<String, String> metricEntry : testListener.getCurrentRunResults().getRunMetrics().entrySet()) {
-            System.out.println(String.format("%s=%s", metricEntry.getKey(), metricEntry.getValue()));
-        }
+
+        Map<String, String> runMetrics = testListener.getCurrentRunResults().getRunMetrics();
+        assertTrue(runMetrics.size() > 0);
+        displayMetrics(runMetrics);
         testListener.invocationEnded(0);
     }
+
+    public void testExtendedDeviceInfo() throws DeviceNotAvailableException {
+        testListener.invocationStarted(mMockBuildInfo);
+        DeviceInfoCollector.collectExtendedDeviceInfo(getDevice(), UnitTests.ABI.getName(),
+                new File(System.getProperty("java.io.tmpdir")), testListener, mMockBuildInfo);
+        assertNotNull(testListener.getCurrentRunResults());
+
+        Map<String, String> runMetrics = testListener.getCurrentRunResults().getRunMetrics();
+        assertTrue(runMetrics.size() > 0);
+        displayMetrics(runMetrics);
+        testListener.invocationEnded(0);
+    }
+
+    private void displayMetrics(Map<String, String> runMetrics) {
+        for (Map.Entry<String, String> metricEntry : runMetrics.entrySet()) {
+            CLog.logAndDisplay(LogLevel.INFO,
+                    String.format("%s=%s", metricEntry.getKey(), metricEntry.getValue()));
+        }
+    }
 }
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 ae4a41e..958dbe4 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
@@ -39,6 +39,7 @@
 import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -47,8 +48,9 @@
  */
 public class CtsXmlResultReporterTest extends TestCase {
 
+    private static final String TEST_SUMMARY_URL = "http://www.google.com?q=android";
     private static final List<TestSummary> SUMMARY_LIST =
-            new ArrayList<>(Arrays.asList(new TestSummary("TEST_SUMMARY_URL")));
+            new ArrayList<>(Arrays.asList(new TestSummary(TEST_SUMMARY_URL)));
     private CtsXmlResultReporter mResultReporter;
     private ByteArrayOutputStream mOutputStream;
     private File mBuildDir;
@@ -84,10 +86,16 @@
         File plansDir = new File(repoDir, "plans");
         assertTrue(casesDir.mkdirs());
         assertTrue(plansDir.mkdirs());
-        mMockBuild = EasyMock.createNiceMock(IFolderBuildInfo.class);
+        mMockBuild = EasyMock.createMock(IFolderBuildInfo.class);
         EasyMock.expect(mMockBuild.getDeviceSerial()).andStubReturn(null);
         EasyMock.expect(mMockBuild.getRootDir()).andStubReturn(mBuildDir);
-        EasyMock.replay(mMockBuild);
+        mMockBuild.addBuildAttribute(EasyMock.cmpEq(CtsXmlResultReporter.CTS_RESULT_DIR),
+                (String) EasyMock.anyObject());
+        EasyMock.expectLastCall();
+        Map<String, String> attributes = new HashMap<>();
+        attributes.put(CtsXmlResultReporter.CTS_RESULT_DIR, "");
+        EasyMock.expect(mMockBuild.getBuildAttributes()).andStubReturn(attributes);
+        EasyMock.expect(mMockBuild.getBuildId()).andStubReturn("");
     }
 
     @Override
@@ -109,10 +117,11 @@
             "<?xml-stylesheet type=\"text/xsl\" href=\"cts_result.xsl\"?>";
         final String expectedTestOutput = String.format(
             "<TestResult testPlan=\"NA\" starttime=\"ignore\" endtime=\"ignore\" " +
-                    "version=\"%s\" suite=\"%s\"> ", CTS_RESULT_FILE_VERSION, "CTS" );
+                    "version=\"%s\" suite=\"%s\"> ", CTS_RESULT_FILE_VERSION, "CTS");
         final String expectedSummaryOutput =
             "<Summary failed=\"0\" notExecuted=\"0\" timeout=\"0\" pass=\"0\" />";
         final String expectedEndTag = "</TestResult>";
+        EasyMock.replay(mMockBuild);
         mResultReporter.invocationStarted(mMockBuild);
         mResultReporter.invocationEnded(1);
         String actualOutput = getOutput();
@@ -120,9 +129,10 @@
         assertTrue(String.format("test output did not contain expected test result [%s]. Got %s",
                 expectedTestOutput, actualOutput), actualOutput.contains(expectedTestOutput));
         assertTrue(String.format("test output did not contain expected test summary [%s]. Got %s",
-                expectedTestOutput, actualOutput), actualOutput.contains(expectedSummaryOutput));
+                expectedSummaryOutput, actualOutput), actualOutput.contains(expectedSummaryOutput));
         assertTrue(String.format("test output did not contain expected TestResult end tag. Got %s",
                 actualOutput), actualOutput.endsWith(expectedEndTag));
+        EasyMock.verify(mMockBuild);
     }
 
     /**
@@ -131,15 +141,21 @@
     public void testSinglePass() {
         Map<String, String> emptyMap = Collections.emptyMap();
         final TestIdentifier testId = new TestIdentifier("com.foo.FooTest", "testFoo");
+        EasyMock.replay(mMockBuild);
         mResultReporter.invocationStarted(mMockBuild);
         mResultReporter.testRunStarted(AbiUtils.createId(UnitTests.ABI.getName(), "run"), 1);
         mResultReporter.testStarted(testId);
         mResultReporter.testEnded(testId, emptyMap);
         mResultReporter.testRunEnded(3000, emptyMap);
-        mResultReporter.invocationEnded(1);
         mResultReporter.putSummary(SUMMARY_LIST);
+        mResultReporter.invocationEnded(1);
         String output =  getOutput();
         // TODO: consider doing xml based compare
+        final String expectedTestOutput = String.format(
+            "<TestResult testPlan=\"NA\" starttime=\"ignore\" endtime=\"ignore\" " +
+                    "version=\"%s\" suite=\"%s\" referenceUrl=\"%s\"> ",
+                            CTS_RESULT_FILE_VERSION, "CTS", TEST_SUMMARY_URL);
+        assertTrue("Found output: " + output, output.contains(expectedTestOutput));
         assertTrue(output.contains(
               "<Summary failed=\"0\" notExecuted=\"0\" timeout=\"0\" pass=\"1\" />"));
         assertTrue(output.contains("<TestPackage name=\"\" appPackageName=\"run\" abi=\"" +
@@ -149,6 +165,7 @@
         final String testCaseTag = String.format(
                 "<Test name=\"%s\" result=\"pass\"", testId.getTestName());
         assertTrue(output.contains(testCaseTag));
+        EasyMock.verify(mMockBuild);
     }
 
     /**
@@ -158,6 +175,7 @@
         Map<String, String> emptyMap = Collections.emptyMap();
         final TestIdentifier testId = new TestIdentifier("FooTest", "testFoo");
         final String trace = "this is a trace\nmore trace\nyet more trace";
+        EasyMock.replay(mMockBuild);
         mResultReporter.invocationStarted(mMockBuild);
         mResultReporter.testRunStarted(AbiUtils.createId(UnitTests.ABI.getName(), "run"), 1);
         mResultReporter.testStarted(testId);
@@ -179,6 +197,7 @@
         // Check that no TestLog tags were added, because the flag wasn't enabled.
         final String testLogTag = String.format("<TestLog type=\"logcat\" url=\"url\" />");
         assertFalse(output, output.contains(testLogTag));
+        EasyMock.verify(mMockBuild);
     }
 
     /**
@@ -192,6 +211,7 @@
         // Include TestLogTags in the XML.
         mResultReporter.setIncludeTestLogTags(true);
 
+        EasyMock.replay(mMockBuild);
         mResultReporter.invocationStarted(mMockBuild);
         mResultReporter.testRunStarted(AbiUtils.createId(UnitTests.ABI.getName(), "run"), 1);
         mResultReporter.testStarted(testId);
@@ -206,11 +226,13 @@
         final String output = getOutput();
         final String testLogTag = String.format("<TestLog type=\"logcat\" url=\"url\" />");
         assertTrue(output, output.contains(testLogTag));
+        EasyMock.verify(mMockBuild);
     }
 
     public void testDeviceSetup() {
         Map<String, String> emptyMap = Collections.emptyMap();
         final TestIdentifier testId = new TestIdentifier("android.tests.devicesetup", "TestDeviceSetup");
+        EasyMock.replay(mMockBuild);
         mResultReporter.invocationStarted(mMockBuild);
         mResultReporter.testRunStarted(AbiUtils.createId(UnitTests.ABI.getName(), testId.getClassName()), 1);
         mResultReporter.testStarted(testId);
@@ -221,6 +243,7 @@
         // TODO: consider doing xml based compare
         final String deviceSetupTag = "appPackageName=\"android.tests.devicesetup\"";
         assertFalse(output, output.contains(deviceSetupTag));
+        EasyMock.verify(mMockBuild);
     }
 
     /**
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparerTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparerTest.java
new file mode 100644
index 0000000..44c6a4d
--- /dev/null
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/targetprep/HostPreconditionPreparerTest.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.targetprep;
+
+import com.android.ddmlib.IDevice;
+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;
+
+/**
+ * Unit tests for {@link HostPreconditionPreparer}.
+ */
+public class HostPreconditionPreparerTest extends TestCase {
+
+    private HostPreconditionPreparer mHostPreconditionPreparer;
+    private ITestDevice mMockDevice;
+    private OptionSetter mOptionSetter;
+
+    private final Dimension DEFAULT_DIMENSION =
+            HostPreconditionPreparer.resolutions[HostPreconditionPreparer.RES_DEFAULT];
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        mHostPreconditionPreparer = new HostPreconditionPreparer();
+        mMockDevice = EasyMock.createMock(ITestDevice.class);
+        mOptionSetter = new OptionSetter(mHostPreconditionPreparer);
+
+        EasyMock.expect(mMockDevice.getMountPoint(IDevice.MNT_EXTERNAL_STORAGE)).andReturn(
+                "/sdcard").anyTimes();
+    }
+
+    public void testLocationServicesOnGpsNetwork() throws Exception {
+        String shellCmd = String.format(
+                "settings get secure %s", HostPreconditionPreparer.LOCATION_PROVIDERS_ALLOWED);
+
+        // expect location to be enabled by both gps and network
+        EasyMock.expect(
+                mMockDevice.executeShellCommand(shellCmd)).andReturn("\ngps,network\n").once();
+        EasyMock.replay(mMockDevice);
+        mHostPreconditionPreparer.checkLocationServices(mMockDevice);
+    }
+
+    public void testLocationServicesOnGps() throws Exception {
+        String shellCmd = String.format(
+                "settings get secure %s", HostPreconditionPreparer.LOCATION_PROVIDERS_ALLOWED);
+
+        // expect location to be enabled by gps only
+        EasyMock.expect(
+                mMockDevice.executeShellCommand(shellCmd)).andReturn("\ngps\n").once();
+        EasyMock.replay(mMockDevice);
+        mHostPreconditionPreparer.checkLocationServices(mMockDevice);
+    }
+
+    public void testLocationServicesOnNetwork() throws Exception {
+        String shellCmd = String.format(
+                "settings get secure %s", HostPreconditionPreparer.LOCATION_PROVIDERS_ALLOWED);
+
+        // expect location to be enabled by network only
+        EasyMock.expect(
+                mMockDevice.executeShellCommand(shellCmd)).andReturn("\nnetwork\n").once();
+        EasyMock.replay(mMockDevice);
+        mHostPreconditionPreparer.checkLocationServices(mMockDevice);
+    }
+
+    public void testLocationServicesOff() throws Exception {
+        String shellCmd = String.format(
+                "settings get secure %s", HostPreconditionPreparer.LOCATION_PROVIDERS_ALLOWED);
+
+        // expect location to be disabled
+        EasyMock.expect(
+                mMockDevice.executeShellCommand(shellCmd)).andReturn("\n\n").once();
+        EasyMock.replay(mMockDevice);
+        try {
+            mHostPreconditionPreparer.checkLocationServices(mMockDevice);
+            fail("TargetSetupError expected");
+        } catch (TargetSetupError e) {
+            // Expected
+        }
+    }
+
+    public void testWifiConnected() throws Exception {
+        EasyMock.expect(mMockDevice.checkConnectivity()).andReturn(true).once();
+        EasyMock.replay(mMockDevice);
+        mHostPreconditionPreparer.runWifiPrecondition(mMockDevice);
+    }
+
+    public void testWifiDisconnected() throws Exception {
+        EasyMock.expect(mMockDevice.checkConnectivity()).andReturn(false).once();
+        EasyMock.replay(mMockDevice);
+        try {
+            mHostPreconditionPreparer.runWifiPrecondition(mMockDevice);
+            fail("TargetSetupError expected");
+        } catch (TargetSetupError e) {
+            // Expected
+        }
+    }
+
+    public void testWifiConnectionSuccessful() throws Exception {
+        EasyMock.expect(
+                mMockDevice.connectToWifiNetworkIfNeeded("wifi-ssid", "wifi-psk")).andReturn(true).once();
+        mOptionSetter.setOptionValue("wifi-ssid", "wifi-ssid");
+        mOptionSetter.setOptionValue("wifi-psk", "wifi-psk");
+        EasyMock.replay(mMockDevice);
+        mHostPreconditionPreparer.runWifiPrecondition(mMockDevice);
+    }
+
+    public void testWifiConnectionUnuccessful() throws Exception {
+        EasyMock.expect(
+                mMockDevice.connectToWifiNetworkIfNeeded("wifi-ssid", "wifi-psk")).andReturn(false).once();
+        mOptionSetter.setOptionValue("wifi-ssid", "wifi-ssid");
+        mOptionSetter.setOptionValue("wifi-psk", "wifi-psk");
+        EasyMock.replay(mMockDevice);
+        try {
+            mHostPreconditionPreparer.runWifiPrecondition(mMockDevice);
+            fail("TargetSetupError expected");
+        } catch (TargetSetupError e) {
+            // Expected
+        }
+    }
+
+    public void testResolutionString() throws Exception {
+        assertEquals("480x360", mHostPreconditionPreparer.resolutionString(DEFAULT_DIMENSION));
+    }
+
+    public void testGetDeviceDirs() throws Exception {
+        EasyMock.replay(mMockDevice);
+        String shortDir =
+                mHostPreconditionPreparer.getDeviceShortDir(mMockDevice, DEFAULT_DIMENSION);
+        String fullDir =
+                mHostPreconditionPreparer.getDeviceFullDir(mMockDevice, DEFAULT_DIMENSION);
+        assertEquals(shortDir, "/sdcard/test/bbb_short/480x360");
+        assertEquals(fullDir, "/sdcard/test/bbb_full/480x360");
+    }
+
+    public void testGetMaxVideoPlaybackResolutionFound() throws Exception {
+        // set "smallest app" field to DEFAULT_DIMENSION
+        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 = mHostPreconditionPreparer.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 = mHostPreconditionPreparer.getMaxVideoPlaybackResolution(mMockDevice);
+        Dimension maxRes =
+                HostPreconditionPreparer.resolutions[HostPreconditionPreparer.RES_1920_1080];
+        assertEquals(result,maxRes);
+    }
+
+    public void testSkipMediaDownload() throws Exception {
+        mOptionSetter.setOptionValue("skip-media-download", "true");
+        EasyMock.replay();
+        mHostPreconditionPreparer.runMediaPrecondition(mMockDevice);
+    }
+
+}
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 30e2ba8..98caad1 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
@@ -23,6 +23,7 @@
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.result.ITestInvocationListener;
+import com.android.tradefed.targetprep.ITargetPreparer;
 import com.android.tradefed.testtype.IRemoteTest;
 import com.android.tradefed.util.xml.AbstractXmlParser.ParseException;
 
@@ -34,6 +35,7 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.InputStream;
+import java.util.Arrays;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -285,6 +287,8 @@
         EasyMock.expect(mMockPackageDef.getAbi()).andReturn(UnitTests.ABI).atLeastOnce();
         EasyMock.expect(mMockPackageDef.getId()).andReturn(ID).atLeastOnce();
         EasyMock.expect(mMockPackageDef.getDigest()).andReturn("digest").atLeastOnce();
+        EasyMock.expect(mMockPackageDef.getPackagePreparers()).andReturn(
+                    new ArrayList<ITargetPreparer>()).atLeastOnce();
         mMockTest.run((ITestInvocationListener) EasyMock.anyObject());
     }
 
@@ -293,6 +297,7 @@
      * been specified
      */
     public void testRun_nothingToRun() throws DeviceNotAvailableException {
+        replayMocks();
         try {
             mCtsTest.run(mMockListener);
             fail("IllegalArgumentException not thrown");
@@ -308,6 +313,7 @@
     public void testRun_packagePlan() throws DeviceNotAvailableException {
         mCtsTest.setPlanName(PLAN_NAME);
         mCtsTest.addPackageName(PACKAGE_NAME);
+        replayMocks();
         try {
             mCtsTest.run(mMockListener);
             fail("IllegalArgumentException not thrown");
@@ -323,6 +329,7 @@
     public void testRun_planClass() throws DeviceNotAvailableException {
         mCtsTest.setPlanName(PLAN_NAME);
         mCtsTest.setClassName("class");
+        replayMocks();
         try {
             mCtsTest.run(mMockListener);
             fail("IllegalArgumentException not thrown");
@@ -338,6 +345,7 @@
     public void testRun_packageClass() throws DeviceNotAvailableException {
         mCtsTest.addPackageName(PACKAGE_NAME);
         mCtsTest.setClassName("class");
+        replayMocks();
         try {
             mCtsTest.run(mMockListener);
             fail("IllegalArgumentException not thrown");
@@ -354,6 +362,7 @@
         mCtsTest.setPlanName(PLAN_NAME);
         mCtsTest.addPackageName(PACKAGE_NAME);
         mCtsTest.setClassName("class");
+        replayMocks();
         try {
             mCtsTest.run(mMockListener);
             fail("IllegalArgumentException not thrown");
@@ -369,6 +378,7 @@
     public void testRun_planContinue() throws DeviceNotAvailableException {
         mCtsTest.setPlanName(PLAN_NAME);
         mCtsTest.setContinueSessionId(1);
+        replayMocks();
         try {
             mCtsTest.run(mMockListener);
             fail("IllegalArgumentException not thrown");
@@ -377,6 +387,34 @@
         }
     }
 
+    /**
+     * Test {@link CtsTestTest#join} works.
+     * @throws DeviceNotAvailableException
+     */
+    public void testJoin() throws DeviceNotAvailableException {
+        String expected = "a@b@c";
+        String actual = mCtsTest.join(new ArrayList<String>(Arrays.asList("a", "b", "c")), "@");
+        assertEquals(expected, actual);
+    }
+
+    /**
+     * Test {@link CtsTestTest#join} for a single element list.
+     * @throws DeviceNotAvailableException
+     */
+    public void testSingleJoin() throws DeviceNotAvailableException {
+        String actual = mCtsTest.join(new ArrayList<String>(Arrays.asList("foo")), "@");
+        assertEquals("foo", actual);
+    }
+
+    /**
+     * Test {@link CtsTestTest#join} for an empty list.
+     * @throws DeviceNotAvailableException
+     */
+    public void testEmptyJoin() throws DeviceNotAvailableException {
+        String actual = mCtsTest.join(new ArrayList<String>(), "@");
+        assertEquals("", actual);
+    }
+
     private void replayMocks(Object... mocks) {
         EasyMock.replay(mMockRepo, mMockPlan, mMockDevice, mMockPackageDef, mMockListener, mMockTest);
         EasyMock.replay(mocks);
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 c41793f..7ec09c9 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
@@ -18,22 +18,32 @@
 import com.android.cts.tradefed.build.StubCtsBuildHelper;
 import com.android.cts.tradefed.UnitTests;
 import com.android.cts.util.AbiUtils;
+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;
 
 import junit.framework.TestCase;
 
 import org.easymock.EasyMock;
 import org.easymock.IAnswer;
+import org.easymock.IMocksControl;
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Unit tests for {@link DeqpTestRunner}.
@@ -45,8 +55,60 @@
     private static final String LOG_FILE_NAME = "/sdcard/TestLog.qpa";
     private static final String INSTRUMENTATION_NAME =
             "com.drawelements.deqp/com.drawelements.deqp.testercore.DeqpInstrumentation";
+    private static final String QUERY_INSTRUMENTATION_NAME =
+            "com.drawelements.deqp/com.drawelements.deqp.platformutil.DeqpPlatformCapabilityQueryInstrumentation";
     private static final String DEQP_ONDEVICE_APK = "com.drawelements.deqp.apk";
     private static final String DEQP_ONDEVICE_PKG = "com.drawelements.deqp";
+    private static final String ONLY_LANDSCAPE_FEATURES =
+            "feature:"+DeqpTestRunner.FEATURE_LANDSCAPE;
+    private static final String ALL_FEATURES =
+            ONLY_LANDSCAPE_FEATURES + "\nfeature:"+DeqpTestRunner.FEATURE_PORTRAIT;
+    private static List<Map<String,String>> DEFAULT_INSTANCE_ARGS;
+
+    static {
+        DEFAULT_INSTANCE_ARGS = new ArrayList<>(1);
+        DEFAULT_INSTANCE_ARGS.add(new HashMap<String,String>());
+        DEFAULT_INSTANCE_ARGS.iterator().next().put("glconfig", "rgba8888d24s8");
+        DEFAULT_INSTANCE_ARGS.iterator().next().put("rotation", "unspecified");
+        DEFAULT_INSTANCE_ARGS.iterator().next().put("surfacetype", "window");
+    }
+
+    private static class StubRecovery implements DeqpTestRunner.IRecovery {
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void setSleepProvider(DeqpTestRunner.ISleepProvider sleepProvider) {
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void setDevice(ITestDevice device) {
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void onExecutionProgressed() {
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void recoverConnectionRefused() throws DeviceNotAvailableException {
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void recoverComLinkKilled() throws DeviceNotAvailableException {
+        }
+    };
 
     /**
      * {@inheritDoc}
@@ -105,14 +167,17 @@
         ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
         ITestInvocationListener mockListener
                 = EasyMock.createStrictMock(ITestInvocationListener.class);
+        IDevice mockIDevice = EasyMock.createMock(IDevice.class);
         Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
-
         tests.add(testId);
 
+        Map<TestIdentifier, List<Map<String, String>>> instance = new HashMap<>();
+        instance.put(testId, DEFAULT_INSTANCE_ARGS);
+
         DeqpTestRunner deqpTest = new DeqpTestRunner(NAME,
                 "dEQP-GLES" + Integer.toString(requiredMajorVersion)
                 + (requiredMinorVersion > 0 ? Integer.toString(requiredMinorVersion) : ""),
-                tests);
+                tests, instance);
         deqpTest.setAbi(UnitTests.ABI);
 
         int version = (majorVersion << 16) | minorVersion;
@@ -129,37 +194,19 @@
                     EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName()))))
                     .andReturn(null).once();
 
-            EasyMock.expect(mockDevice.executeShellCommand(
-                    EasyMock.eq("rm " + CASE_LIST_FILE_NAME))).andReturn("").once();
+            expectRenderConfigQuery(mockDevice, requiredMajorVersion,
+                    requiredMinorVersion);
 
-            EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + LOG_FILE_NAME)))
-                    .andReturn("").once();
+            String commandLine = String.format(
+                    "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8 "
+                    + "--deqp-screen-rotation=unspecified "
+                    + "--deqp-surface-type=window "
+                    + "--deqp-log-images=disable "
+                    + "--deqp-watchdog=enable",
+                    CASE_LIST_FILE_NAME);
 
-            EasyMock.expect(mockDevice.pushString(testTrie + "\n", CASE_LIST_FILE_NAME))
-                    .andReturn(true).once();
-
-            String command = String.format(
-                    "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
-                        + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\" "
-                        + "-e deqpLogData \"%s\" %s",
-                    AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
-                    CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
-
-            mockDevice.executeShellCommand(EasyMock.eq(command),
-                    EasyMock.<IShellOutputReceiver>notNull());
-
-            EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-                @Override
-                public Object answer() {
-                    IShellOutputReceiver receiver
-                            = (IShellOutputReceiver)EasyMock.getCurrentArguments()[1];
-
-                    receiver.addOutput(output.getBytes(), 0, output.length());
-                    receiver.flush();
-
-                    return null;
-                }
-            });
+            runInstrumentationLineAndAnswer(mockDevice, mockIDevice, testTrie, commandLine,
+                    output);
 
             EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
                     .andReturn("").once();
@@ -177,7 +224,7 @@
         mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
         EasyMock.expectLastCall().once();
 
-        EasyMock.replay(mockDevice);
+        EasyMock.replay(mockDevice, mockIDevice);
         EasyMock.replay(mockListener);
 
         deqpTest.setDevice(mockDevice);
@@ -185,7 +232,49 @@
         deqpTest.run(mockListener);
 
         EasyMock.verify(mockListener);
-        EasyMock.verify(mockDevice);
+        EasyMock.verify(mockDevice, mockIDevice);
+    }
+
+    private void expectRenderConfigQuery(ITestDevice mockDevice, int majorVersion,
+            int minorVersion) throws Exception {
+        expectRenderConfigQuery(mockDevice,
+                String.format("--deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-gl-major-version=%d "
+                + "--deqp-gl-minor-version=%d", majorVersion, minorVersion));
+    }
+
+    private void expectRenderConfigQuery(ITestDevice mockDevice, String commandLine)
+            throws Exception {
+        expectRenderConfigQueryAndReturn(mockDevice, commandLine, "Yes");
+    }
+
+    private void expectRenderConfigQueryAndReturn(ITestDevice mockDevice, String commandLine,
+            String output) throws Exception {
+        final String queryOutput = "INSTRUMENTATION_RESULT: Supported=" + output + "\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+        final String command = String.format(
+                "am instrument %s -w -e deqpQueryType renderConfigSupported -e deqpCmdLine "
+                    + "\"%s\" %s",
+                AbiUtils.createAbiFlag(UnitTests.ABI.getName()), commandLine,
+                QUERY_INSTRUMENTATION_NAME);
+
+        mockDevice.executeShellCommand(EasyMock.eq(command),
+                EasyMock.<IShellOutputReceiver>notNull());
+
+        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+            @Override
+            public Object answer() {
+                IShellOutputReceiver receiver
+                        = (IShellOutputReceiver)EasyMock.getCurrentArguments()[1];
+
+                receiver.addOutput(queryOutput.getBytes(), 0, queryOutput.length());
+                receiver.flush();
+
+                return null;
+            }
+        });
     }
 
     /**
@@ -227,11 +316,15 @@
         ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
         ITestInvocationListener mockListener
                 = EasyMock.createStrictMock(ITestInvocationListener.class);
-        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        IDevice mockIDevice = EasyMock.createMock(IDevice.class);
 
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
         tests.add(testId);
 
-        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests);
+        Map<TestIdentifier, List<Map<String, String>>> instance = new HashMap<>();
+        instance.put(testId, DEFAULT_INSTANCE_ARGS);
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instance);
         deqpTest.setAbi(UnitTests.ABI);
 
         int version = 3 << 16;
@@ -245,37 +338,17 @@
                 EasyMock.eq(true), EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName()))))
                 .andReturn(null).once();
 
-        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + CASE_LIST_FILE_NAME)))
-                .andReturn("").once();
+        expectRenderConfigQuery(mockDevice, 3, 0);
 
-        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + LOG_FILE_NAME)))
-                .andReturn("").once();
+        String commandLine = String.format(
+                "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable",
+                CASE_LIST_FILE_NAME);
 
-        EasyMock.expect(mockDevice.pushString(testTrie + "\n", CASE_LIST_FILE_NAME)).andReturn(true)
-                .once();
-
-        String command = String.format(
-                "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
-                    + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\" "
-                    + "-e deqpLogData \"%s\" %s",
-                AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
-                CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
-
-        mockDevice.executeShellCommand(EasyMock.eq(command),
-                EasyMock.<IShellOutputReceiver>notNull());
-
-        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-            @Override
-            public Object answer() {
-                IShellOutputReceiver receiver
-                        = (IShellOutputReceiver)EasyMock.getCurrentArguments()[1];
-
-                receiver.addOutput(output.getBytes(), 0, output.length());
-                receiver.flush();
-
-                return null;
-            }
-        });
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice, testTrie, commandLine, output);
 
         mockListener.testRunStarted(ID, 1);
         EasyMock.expectLastCall().once();
@@ -285,7 +358,8 @@
 
         if (!pass) {
             mockListener.testFailed(testId,
-                    resultCode + ": Detail" + resultCode);
+                    "=== with config {glformat=rgba8888d24s8,rotation=unspecified,surfacetype=window} ===\n"
+                    + resultCode + ": Detail" + resultCode);
 
             EasyMock.expectLastCall().once();
         }
@@ -299,7 +373,7 @@
         EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
                 .once();
 
-        EasyMock.replay(mockDevice);
+        EasyMock.replay(mockDevice, mockIDevice);
         EasyMock.replay(mockListener);
 
         deqpTest.setDevice(mockDevice);
@@ -307,7 +381,7 @@
         deqpTest.run(mockListener);
 
         EasyMock.verify(mockListener);
-        EasyMock.verify(mockDevice);
+        EasyMock.verify(mockDevice, mockIDevice);
     }
 
     /**
@@ -411,13 +485,17 @@
         ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
         ITestInvocationListener mockListener
                 = EasyMock.createStrictMock(ITestInvocationListener.class);
+        IDevice mockIDevice = EasyMock.createMock(IDevice.class);
+
         Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        Map<TestIdentifier, List<Map<String, String>>> instances = new HashMap<>();
 
         for (TestIdentifier id : testIds) {
             tests.add(id);
+            instances.put(id, DEFAULT_INSTANCE_ARGS);
         }
 
-        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests);
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instances);
         deqpTest.setAbi(UnitTests.ABI);
 
         int version = 3 << 16;
@@ -430,37 +508,17 @@
                 EasyMock.eq(true), EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName()))))
                 .andReturn(null).once();
 
-        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + CASE_LIST_FILE_NAME)))
-                .andReturn("").once();
+        expectRenderConfigQuery(mockDevice, 3, 0);
 
-        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + LOG_FILE_NAME)))
-                .andReturn("").once();
+        String commandLine = String.format(
+                "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable",
+                CASE_LIST_FILE_NAME);
 
-        EasyMock.expect(mockDevice.pushString(testTrie + "\n", CASE_LIST_FILE_NAME))
-                .andReturn(true).once();
-
-        String command = String.format(
-                "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
-                    + "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8\" "
-                    + "-e deqpLogData \"%s\" %s",
-                AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
-                CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
-
-        mockDevice.executeShellCommand(EasyMock.eq(command),
-                EasyMock.<IShellOutputReceiver>notNull());
-
-        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-            @Override
-            public Object answer() {
-                IShellOutputReceiver receiver
-                        = (IShellOutputReceiver)EasyMock.getCurrentArguments()[1];
-
-                receiver.addOutput(output.getBytes(), 0, output.length());
-                receiver.flush();
-
-                return null;
-            }
-        });
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice, testTrie, commandLine, output);
 
         mockListener.testRunStarted(ID, testPaths.length);
         EasyMock.expectLastCall().once();
@@ -481,7 +539,7 @@
         EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
                 .once();
 
-        EasyMock.replay(mockDevice);
+        EasyMock.replay(mockDevice, mockIDevice);
         EasyMock.replay(mockListener);
 
         deqpTest.setDevice(mockDevice);
@@ -489,10 +547,371 @@
         deqpTest.run(mockListener);
 
         EasyMock.verify(mockListener);
+        EasyMock.verify(mockDevice, mockIDevice);
+    }
+
+    /**
+     * Test running a unexecutable test.
+     */
+    public void testRun_unexecutableTests() throws Exception {
+        final String instrumentationAnswerNoExecs =
+                "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+
+        final TestIdentifier[] testIds = {
+                new TestIdentifier("dEQP-GLES3.missing", "no"),
+                new TestIdentifier("dEQP-GLES3.missing", "nope"),
+                new TestIdentifier("dEQP-GLES3.missing", "donotwant"),
+        };
+
+        final String[] testPaths = {
+                "dEQP-GLES3.missing.no",
+                "dEQP-GLES3.missing.nope",
+                "dEQP-GLES3.missing.donotwant",
+        };
+
+        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
+        ITestInvocationListener mockListener
+                = EasyMock.createStrictMock(ITestInvocationListener.class);
+        IDevice mockIDevice = EasyMock.createMock(IDevice.class);
+
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        Map<TestIdentifier, List<Map<String, String>>> instances = new HashMap<>();
+
+        for (TestIdentifier id : testIds) {
+            tests.add(id);
+            instances.put(id, DEFAULT_INSTANCE_ARGS);
+        }
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instances);
+        deqpTest.setAbi(UnitTests.ABI);
+
+        int version = 3 << 16;
+        EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+                .andReturn(Integer.toString(version)).atLeastOnce();
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
+                .once();
+        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+                EasyMock.eq(true), EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName()))))
+                .andReturn(null).once();
+
+        expectRenderConfigQuery(mockDevice, 3, 0);
+
+        String commandLine = String.format(
+                "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable",
+                CASE_LIST_FILE_NAME);
+
+        // first try
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{missing{no,nope,donotwant}}}", commandLine, instrumentationAnswerNoExecs);
+
+        // splitting begins
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{missing{no}}}", commandLine, instrumentationAnswerNoExecs);
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{missing{nope,donotwant}}}", commandLine, instrumentationAnswerNoExecs);
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{missing{nope}}}", commandLine, instrumentationAnswerNoExecs);
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{missing{donotwant}}}", commandLine, instrumentationAnswerNoExecs);
+
+        mockListener.testRunStarted(ID, testPaths.length);
+        EasyMock.expectLastCall().once();
+
+        for (int i = 0; i < testPaths.length; i++) {
+            mockListener.testStarted(EasyMock.eq(testIds[i]));
+            EasyMock.expectLastCall().once();
+
+            mockListener.testFailed(EasyMock.eq(testIds[i]),
+                    EasyMock.eq("=== with config {glformat=rgba8888d24s8,rotation=unspecified,surfacetype=window} ===\n"
+                    + "Abort: Test cannot be executed"));
+            EasyMock.expectLastCall().once();
+
+            mockListener.testEnded(EasyMock.eq(testIds[i]),
+                    EasyMock.<Map<String, String>>notNull());
+            EasyMock.expectLastCall().once();
+        }
+
+        mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).andReturn("")
+                .once();
+
+        EasyMock.replay(mockDevice, mockIDevice);
+        EasyMock.replay(mockListener);
+
+        deqpTest.setDevice(mockDevice);
+        deqpTest.setBuildHelper(new StubCtsBuildHelper());
+        deqpTest.run(mockListener);
+
+        EasyMock.verify(mockListener);
+        EasyMock.verify(mockDevice, mockIDevice);
+    }
+
+    /**
+     * Test that test are left unexecuted if pm list query fails
+     */
+    public void testRun_queryPmListFailure()
+            throws Exception {
+        final TestIdentifier testId = new TestIdentifier("dEQP-GLES3.orientation", "test");
+
+        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
+        ITestInvocationListener mockListener
+                = EasyMock.createStrictMock(ITestInvocationListener.class);
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        tests.add(testId);
+
+        Map<TestIdentifier, List<Map<String, String>>> instance = new HashMap<>();
+        instance.put(testId, new ArrayList<Map<String,String>>(1));
+        instance.get(testId).add(new HashMap<String,String>());
+        instance.get(testId).iterator().next().put("glconfig", "rgba8888d24s8");
+        instance.get(testId).iterator().next().put("rotation", "90");
+        instance.get(testId).iterator().next().put("surfacetype", "window");
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instance);
+        deqpTest.setAbi(UnitTests.ABI);
+        deqpTest.setDevice(mockDevice);
+        deqpTest.setBuildHelper(new StubCtsBuildHelper());
+
+        int version = 3 << 16;
+        EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+                .andReturn(Integer.toString(version)).atLeastOnce();
+
+        EasyMock.expect(mockDevice.executeShellCommand("pm list features"))
+                .andReturn("not a valid format");
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+            andReturn("").once();
+
+        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+                EasyMock.eq(true),
+                EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+                .once();
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+                .andReturn("").once();
+
+        mockListener.testRunStarted(ID, 1);
+        EasyMock.expectLastCall().once();
+
+        mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        EasyMock.replay(mockDevice);
+        EasyMock.replay(mockListener);
+        deqpTest.run(mockListener);
+        EasyMock.verify(mockListener);
         EasyMock.verify(mockDevice);
     }
 
     /**
+     * Test that test are left unexecuted if renderablity query fails
+     */
+    public void testRun_queryRenderabilityFailure()
+            throws Exception {
+        final TestIdentifier testId = new TestIdentifier("dEQP-GLES3.orientation", "test");
+
+        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
+        ITestInvocationListener mockListener
+                = EasyMock.createStrictMock(ITestInvocationListener.class);
+
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        tests.add(testId);
+
+        Map<TestIdentifier, List<Map<String, String>>> instance = new HashMap<>();
+        instance.put(testId, new ArrayList<Map<String,String>>(1));
+        instance.get(testId).add(new HashMap<String,String>());
+        instance.get(testId).iterator().next().put("glconfig", "rgba8888d24s8");
+        instance.get(testId).iterator().next().put("rotation", "unspecified");
+        instance.get(testId).iterator().next().put("surfacetype", "window");
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instance);
+        deqpTest.setAbi(UnitTests.ABI);
+        deqpTest.setDevice(mockDevice);
+        deqpTest.setBuildHelper(new StubCtsBuildHelper());
+
+        int version = 3 << 16;
+        EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+                .andReturn(Integer.toString(version)).atLeastOnce();
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+            andReturn("").once();
+
+        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+                EasyMock.eq(true),
+                EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+                .once();
+
+        expectRenderConfigQueryAndReturn(mockDevice,
+                "--deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0", "Maybe?");
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+                .andReturn("").once();
+
+        mockListener.testRunStarted(ID, 1);
+        EasyMock.expectLastCall().once();
+
+        mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        EasyMock.replay(mockDevice);
+        EasyMock.replay(mockListener);
+        deqpTest.run(mockListener);
+        EasyMock.verify(mockListener);
+        EasyMock.verify(mockDevice);
+    }
+
+    /**
+     * Test that orientation is supplied to runner correctly
+     */
+    private void testOrientation(final String rotation, final String featureString)
+            throws Exception {
+        final TestIdentifier testId = new TestIdentifier("dEQP-GLES3.orientation", "test");
+        final String testPath = "dEQP-GLES3.orientation.test";
+        final String testTrie = "{dEQP-GLES3{orientation{test}}}";
+        final String output = "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=" + testPath + "\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+
+        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
+        ITestInvocationListener mockListener
+                = EasyMock.createStrictMock(ITestInvocationListener.class);
+        IDevice mockIDevice = EasyMock.createMock(IDevice.class);
+
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        tests.add(testId);
+
+        Map<TestIdentifier, List<Map<String, String>>> instance = new HashMap<>();
+        instance.put(testId, new ArrayList<Map<String,String>>(1));
+        instance.get(testId).add(new HashMap<String,String>());
+        instance.get(testId).iterator().next().put("glconfig", "rgba8888d24s8");
+        instance.get(testId).iterator().next().put("rotation", rotation);
+        instance.get(testId).iterator().next().put("surfacetype", "window");
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instance);
+        deqpTest.setAbi(UnitTests.ABI);
+        deqpTest.setDevice(mockDevice);
+        deqpTest.setBuildHelper(new StubCtsBuildHelper());
+
+        int version = 3 << 16;
+        EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+                .andReturn(Integer.toString(version)).atLeastOnce();
+
+        if (!rotation.equals(DeqpTestRunner.BatchRunConfiguration.ROTATION_UNSPECIFIED)) {
+            EasyMock.expect(mockDevice.executeShellCommand("pm list features"))
+                    .andReturn(featureString);
+        }
+
+        final boolean isPortraitOrientation =
+                rotation.equals(DeqpTestRunner.BatchRunConfiguration.ROTATION_PORTRAIT) ||
+                rotation.equals(DeqpTestRunner.BatchRunConfiguration.ROTATION_REVERSE_PORTRAIT);
+        final boolean isLandscapeOrientation =
+                rotation.equals(DeqpTestRunner.BatchRunConfiguration.ROTATION_LANDSCAPE) ||
+                rotation.equals(DeqpTestRunner.BatchRunConfiguration.ROTATION_REVERSE_LANDSCAPE);
+        final boolean executable =
+                rotation.equals(DeqpTestRunner.BatchRunConfiguration.ROTATION_UNSPECIFIED) ||
+                (isPortraitOrientation &&
+                featureString.contains(DeqpTestRunner.FEATURE_PORTRAIT)) ||
+                (isLandscapeOrientation &&
+                featureString.contains(DeqpTestRunner.FEATURE_LANDSCAPE));
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+            andReturn("").once();
+
+        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+                EasyMock.eq(true),
+                EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+                .once();
+
+        if (executable) {
+            expectRenderConfigQuery(mockDevice, String.format(
+                    "--deqp-gl-config-name=rgba8888d24s8 --deqp-screen-rotation=%s "
+                    + "--deqp-surface-type=window --deqp-gl-major-version=3 "
+                    + "--deqp-gl-minor-version=0", rotation));
+
+            String commandLine = String.format(
+                    "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8 "
+                    + "--deqp-screen-rotation=%s "
+                    + "--deqp-surface-type=window "
+                    + "--deqp-log-images=disable "
+                    + "--deqp-watchdog=enable",
+                    CASE_LIST_FILE_NAME, rotation);
+
+            runInstrumentationLineAndAnswer(mockDevice, mockIDevice, testTrie, commandLine,
+                    output);
+        }
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+                .andReturn("").once();
+
+        mockListener.testRunStarted(ID, 1);
+        EasyMock.expectLastCall().once();
+
+        mockListener.testStarted(EasyMock.eq(testId));
+        EasyMock.expectLastCall().once();
+
+        mockListener.testEnded(EasyMock.eq(testId), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        EasyMock.replay(mockDevice, mockIDevice);
+        EasyMock.replay(mockListener);
+        deqpTest.run(mockListener);
+        EasyMock.verify(mockListener);
+        EasyMock.verify(mockDevice, mockIDevice);
+    }
+
+    /**
      * Test OpeGL ES3 tests on device with OpenGL ES2.
      */
     public void testRun_require30DeviceVersion20() throws Exception {
@@ -596,4 +1015,1336 @@
     public void testRun_resultTimeout() throws Exception {
         testResultCode("Timeout", false);
     }
+    /**
+     * Test dEQP Orientation
+     */
+    public void testRun_orientationLandscape() throws Exception {
+        testOrientation("90", ALL_FEATURES);
+    }
+
+    /**
+     * Test dEQP Orientation
+     */
+    public void testRun_orientationPortrait() throws Exception {
+        testOrientation("0", ALL_FEATURES);
+    }
+
+    /**
+     * Test dEQP Orientation
+     */
+    public void testRun_orientationReverseLandscape() throws Exception {
+        testOrientation("270", ALL_FEATURES);
+    }
+
+    /**
+     * Test dEQP Orientation
+     */
+    public void testRun_orientationReversePortrait() throws Exception {
+        testOrientation("180", ALL_FEATURES);
+    }
+
+    /**
+     * Test dEQP Orientation
+     */
+    public void testRun_orientationUnspecified() throws Exception {
+        testOrientation("unspecified", ALL_FEATURES);
+    }
+
+    /**
+     * Test dEQP Orientation with limited features
+     */
+    public void testRun_orientationUnspecifiedLimitedFeatures() throws Exception {
+        testOrientation("unspecified", ONLY_LANDSCAPE_FEATURES);
+    }
+
+    /**
+     * Test dEQP Orientation with limited features
+     */
+    public void testRun_orientationLandscapeLimitedFeatures() throws Exception {
+        testOrientation("90", ONLY_LANDSCAPE_FEATURES);
+    }
+
+    /**
+     * Test dEQP Orientation with limited features
+     */
+    public void testRun_orientationPortraitLimitedFeatures() throws Exception {
+        testOrientation("0", ONLY_LANDSCAPE_FEATURES);
+    }
+
+    /**
+     * Test dEQP unsupported pixel format
+     */
+    public void testRun_unsupportedPixelFormat() throws Exception {
+        final String pixelFormat = "rgba5658d16m4";
+        final TestIdentifier testId = new TestIdentifier("dEQP-GLES3.pixelformat", "test");
+        final String testPath = "dEQP-GLES3.pixelformat.test";
+        final String testTrie = "{dEQP-GLES3{pixelformat{test}}}";
+        final String output = "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=" + testPath + "\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+
+        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
+        ITestInvocationListener mockListener
+                = EasyMock.createStrictMock(ITestInvocationListener.class);
+
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        tests.add(testId);
+
+        Map<TestIdentifier, List<Map<String, String>>> instance = new HashMap<>();
+        instance.put(testId, new ArrayList<Map<String,String>>(1));
+        instance.get(testId).add(new HashMap<String,String>());
+        instance.get(testId).iterator().next().put("glconfig", pixelFormat);
+        instance.get(testId).iterator().next().put("rotation", "unspecified");
+        instance.get(testId).iterator().next().put("surfacetype", "window");
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instance);
+        deqpTest.setAbi(UnitTests.ABI);
+        deqpTest.setDevice(mockDevice);
+        deqpTest.setBuildHelper(new StubCtsBuildHelper());
+
+        int version = 3 << 16;
+        EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+                .andReturn(Integer.toString(version)).atLeastOnce();
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+            andReturn("").once();
+
+        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+                EasyMock.eq(true),
+                EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+                .once();
+
+        expectRenderConfigQueryAndReturn(mockDevice, String.format(
+                "--deqp-gl-config-name=%s --deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0", pixelFormat), "No");
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+                .andReturn("").once();
+
+        mockListener.testRunStarted(ID, 1);
+        EasyMock.expectLastCall().once();
+
+        mockListener.testStarted(EasyMock.eq(testId));
+        EasyMock.expectLastCall().once();
+
+        mockListener.testEnded(EasyMock.eq(testId), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        EasyMock.replay(mockDevice);
+        EasyMock.replay(mockListener);
+        deqpTest.run(mockListener);
+        EasyMock.verify(mockListener);
+        EasyMock.verify(mockDevice);
+    }
+
+    /**
+     * Test dEQP with multiple instances
+     */
+    public void testRun_multipleInstances() throws Exception {
+        final String instrumentationAnswerConfigAPass1 =
+                "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.passall\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.failone\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.crashtwo\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"; // early eof
+        final String instrumentationAnswerConfigAPass2 =
+                "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.crashtwo\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"; // early eof
+        final String instrumentationAnswerConfigBPass1 =
+                "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.passall\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.skipone\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+        final String instrumentationAnswerConfigBPass2 =
+                "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.crashtwo\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TerminateTestCase-Reason=Magic\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TerminateTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+        final String instrumentationAnswerConfigCPass1 =
+                "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.failone\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Fail\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Fail\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+        final String instrumentationAnswerConfigCPass2 =
+                "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.instances.crashtwo\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+
+        final TestIdentifier[] testIds = {
+                new TestIdentifier("dEQP-GLES3.instances", "passall"),
+                new TestIdentifier("dEQP-GLES3.instances", "failone"),
+                new TestIdentifier("dEQP-GLES3.instances", "crashtwo"),
+                new TestIdentifier("dEQP-GLES3.instances", "skipone"),
+        };
+
+        final String[] testPaths = {
+                "dEQP-GLES3.instances.passall",
+                "dEQP-GLES3.instances.failone",
+                "dEQP-GLES3.instances.crashtwo",
+                "dEQP-GLES3.instances.skipone",
+        };
+
+        Map<String,String> supportedConfigA = new HashMap<>();
+        supportedConfigA.put("glconfig", "rgba8888d24s8");
+        supportedConfigA.put("rotation", "unspecified");
+        supportedConfigA.put("surfacetype", "window");
+
+        Map<String,String> supportedConfigB = new HashMap<>();
+        supportedConfigB.put("glconfig", "rgba8888d24s8");
+        supportedConfigB.put("rotation", "90");
+        supportedConfigB.put("surfacetype", "window");
+
+        Map<String,String> supportedConfigC = new HashMap<>();
+        supportedConfigC.put("glconfig", "rgba8888d24s8");
+        supportedConfigC.put("rotation", "180");
+        supportedConfigC.put("surfacetype", "window");
+
+        Map<String,String> unsupportedConfig = new HashMap<>();
+        unsupportedConfig.put("glconfig", "rgb565d16s0");
+        unsupportedConfig.put("rotation", "unspecified");
+        unsupportedConfig.put("surfacetype", "window");
+
+        Map<TestIdentifier, List<Map<String, String>>> instances = new HashMap<>();
+
+        // pass all
+        instances.put(testIds[0], new ArrayList<Map<String,String>>());
+        instances.get(testIds[0]).add(supportedConfigA);
+        instances.get(testIds[0]).add(supportedConfigB);
+
+        // fail one
+        instances.put(testIds[1], new ArrayList<Map<String,String>>());
+        instances.get(testIds[1]).add(supportedConfigA);
+        instances.get(testIds[1]).add(supportedConfigC);
+
+        // crash two
+        instances.put(testIds[2], new ArrayList<Map<String,String>>());
+        instances.get(testIds[2]).add(supportedConfigA);
+        instances.get(testIds[2]).add(supportedConfigC);
+        instances.get(testIds[2]).add(supportedConfigB);
+
+        // skip one
+        instances.put(testIds[3], new ArrayList<Map<String,String>>());
+        instances.get(testIds[3]).add(supportedConfigB);
+        instances.get(testIds[3]).add(unsupportedConfig);
+
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        for (TestIdentifier id : testIds) {
+            tests.add(id);
+        }
+
+        ITestInvocationListener mockListener
+                = EasyMock.createStrictMock(ITestInvocationListener.class);
+        IMocksControl orderedControl = EasyMock.createStrictControl();
+        ITestDevice mockDevice = orderedControl.createMock(ITestDevice.class);
+        IDevice mockIDevice = orderedControl.createMock(IDevice.class);
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instances);
+        deqpTest.setAbi(UnitTests.ABI);
+        deqpTest.setDevice(mockDevice);
+        deqpTest.setBuildHelper(new StubCtsBuildHelper());
+
+        int version = 3 << 16;
+        EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+                .andReturn(Integer.toString(version)).atLeastOnce();
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+            andReturn("").once();
+
+        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+                EasyMock.eq(true),
+                EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+                .once();
+
+        // query config A
+        expectRenderConfigQueryAndReturn(mockDevice,
+                "--deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0", "Yes");
+
+        // run config A - first pass
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{instances{passall,failone,crashtwo}}}",
+                "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+                + " --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable", instrumentationAnswerConfigAPass1);
+
+        // run config A - second pass
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{instances{crashtwo}}}",
+                "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+                + " --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable", instrumentationAnswerConfigAPass2);
+
+        // query for config B
+
+        EasyMock.expect(mockDevice.executeShellCommand("pm list features")).andReturn(ALL_FEATURES)
+                .once();
+
+        expectRenderConfigQueryAndReturn(mockDevice,
+                "--deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=90 "
+                + "--deqp-surface-type=window "
+                + "--deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0", "Yes");
+
+        // run for config B - first pass
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{instances{passall,skipone}}}",
+                "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+                + " --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=90 "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable", instrumentationAnswerConfigBPass1);
+
+        // query for config C
+        expectRenderConfigQueryAndReturn(mockDevice,
+                "--deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=180 "
+                + "--deqp-surface-type=window "
+                + "--deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0", "Yes");
+
+        // run for config C - first pass
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{instances{failone}}}",
+                "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+                + " --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=180 "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable", instrumentationAnswerConfigCPass1);
+
+        // run for config C - second pass
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{instances{crashtwo}}}",
+                "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+                + " --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=180 "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable", instrumentationAnswerConfigCPass2);
+
+        // run for config B - second pass (crashtwo has been deferred due to its instability)
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{instances{crashtwo}}}",
+                "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+                + " --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=90 "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable", instrumentationAnswerConfigBPass2);
+
+        // query for unsupported config
+        expectRenderConfigQueryAndReturn(mockDevice,
+                "--deqp-gl-config-name=rgb565d16s0 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0", "No");
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG)))
+                .andReturn("").once();
+
+        mockListener.testRunStarted(ID, 4);
+        EasyMock.expectLastCall().once();
+
+        // pass all
+        mockListener.testStarted(EasyMock.eq(testIds[0]));
+        EasyMock.expectLastCall().once();
+
+        mockListener.testEnded(EasyMock.eq(testIds[0]), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        // fail one
+        mockListener.testStarted(EasyMock.eq(testIds[1]));
+        EasyMock.expectLastCall().once();
+
+        mockListener.testFailed(testIds[1],
+                "=== with config {glformat=rgba8888d24s8,rotation=180,surfacetype=window} ===\n"
+                + "Fail: Fail");
+        EasyMock.expectLastCall().once();
+
+        mockListener.testEnded(EasyMock.eq(testIds[1]), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        // crash two
+        mockListener.testStarted(EasyMock.eq(testIds[2]));
+        EasyMock.expectLastCall().once();
+
+        mockListener.testFailed(testIds[2],
+                "=== with config {glformat=rgba8888d24s8,rotation=unspecified,surfacetype=window} ===\n"
+                + "Crash: Incomplete test log\n"
+                + "=== with config {glformat=rgba8888d24s8,rotation=90,surfacetype=window} ===\n"
+                + "Terminated: Magic");
+        EasyMock.expectLastCall().once();
+
+        mockListener.testEnded(EasyMock.eq(testIds[2]), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        // skip one
+        mockListener.testStarted(EasyMock.eq(testIds[3]));
+        EasyMock.expectLastCall().once();
+
+        mockListener.testEnded(EasyMock.eq(testIds[3]), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+        EasyMock.expectLastCall().once();
+
+        orderedControl.replay();
+        EasyMock.replay(mockListener);
+        deqpTest.setRecovery(new StubRecovery());
+        deqpTest.run(mockListener);
+        EasyMock.verify(mockListener);
+        orderedControl.verify();
+    }
+
+    private void testMultipleInstancesLossOfDeviceMidInstance(final boolean recoverySuccessful)
+            throws Exception {
+        final String instrumentationAnswerFine =
+                "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.loss.instance\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Pass\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+        final String instrumentationAnswerCrash =
+                "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=dEQP-GLES3.loss.instance\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"; // early <EOF>
+
+        final TestIdentifier testId = new TestIdentifier("dEQP-GLES3.loss", "instance");
+
+        Map<String,String> supportedConfigA = new HashMap<>();
+        supportedConfigA.put("glconfig", "rgba8888d24s8");
+        supportedConfigA.put("rotation", "unspecified");
+        supportedConfigA.put("surfacetype", "window");
+
+        Map<String,String> supportedConfigB = new HashMap<>();
+        supportedConfigB.put("glconfig", "rgba8888d24s8");
+        supportedConfigB.put("rotation", "90");
+        supportedConfigB.put("surfacetype", "window");
+
+        Map<String,String> supportedConfigC = new HashMap<>();
+        supportedConfigC.put("glconfig", "rgba8888d24s8");
+        supportedConfigC.put("rotation", "180");
+        supportedConfigC.put("surfacetype", "window");
+
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        tests.add(testId);
+
+        Map<TestIdentifier, List<Map<String, String>>> instance = new HashMap<>();
+        instance.put(testId, new ArrayList<Map<String,String>>());
+        instance.get(testId).add(supportedConfigA);
+        instance.get(testId).add(supportedConfigB);
+        instance.get(testId).add(supportedConfigC);
+
+        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
+        ITestInvocationListener mockListener
+                = EasyMock.createStrictMock(ITestInvocationListener.class);
+        IDevice mockIDevice = EasyMock.createMock(IDevice.class);
+        DeqpTestRunner.IRecovery mockRecovery = EasyMock.createMock(DeqpTestRunner.IRecovery.class);
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instance);
+        deqpTest.setAbi(UnitTests.ABI);
+        deqpTest.setDevice(mockDevice);
+        deqpTest.setBuildHelper(new StubCtsBuildHelper());
+        deqpTest.setRecovery(mockRecovery);
+
+        int version = 3 << 16;
+        EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+                .andReturn(Integer.toString(version)).atLeastOnce();
+        EasyMock.expect(mockDevice.executeShellCommand("pm list features")).andReturn(ALL_FEATURES)
+                .anyTimes();
+
+        mockRecovery.onExecutionProgressed();
+        EasyMock.expectLastCall().atLeastOnce();
+
+        mockRecovery.setDevice(mockDevice);
+        EasyMock.expectLastCall().atLeastOnce();
+
+        if (!recoverySuccessful) {
+            EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+                andReturn("").once();
+        } else {
+            EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+                andReturn("").times(2);
+        }
+
+        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+                EasyMock.eq(true),
+                EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+                .once();
+
+        // query config A
+        expectRenderConfigQueryAndReturn(mockDevice,
+                "--deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0", "Yes");
+
+        // run config A
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                "{dEQP-GLES3{loss{instance}}}",
+                "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+                + " --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable", instrumentationAnswerFine);
+
+        // query config B
+        expectRenderConfigQueryAndReturn(mockDevice,
+                "--deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=90 "
+                + "--deqp-surface-type=window "
+                + "--deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0", "Yes");
+
+        // run config B
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + CASE_LIST_FILE_NAME)))
+                .andReturn("").once();
+
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + LOG_FILE_NAME)))
+                .andReturn("").once();
+
+        EasyMock.expect(mockDevice.pushString("{dEQP-GLES3{loss{instance}}}\n", CASE_LIST_FILE_NAME))
+                .andReturn(true).once();
+
+        String command = String.format(
+                "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \""
+                + "--deqp-caselist-file=%s"
+                + " --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=90 "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable\" "
+                + "-e deqpLogData \"%s\" %s",
+                AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME,
+                CASE_LIST_FILE_NAME, false, INSTRUMENTATION_NAME);
+
+        EasyMock.expect(mockDevice.getIDevice()).andReturn(mockIDevice);
+        mockIDevice.executeShellCommand(EasyMock.eq(command),
+                EasyMock.<IShellOutputReceiver>notNull(), EasyMock.anyLong(),
+                EasyMock.isA(TimeUnit.class));
+
+        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+            @Override
+            public Object answer() throws ShellCommandUnresponsiveException {
+                IShellOutputReceiver receiver
+                        = (IShellOutputReceiver)EasyMock.getCurrentArguments()[1];
+
+                receiver.addOutput(instrumentationAnswerCrash.getBytes(), 0,
+                        instrumentationAnswerCrash.length());
+                throw new ShellCommandUnresponsiveException();
+            }
+        });
+
+        if (!recoverySuccessful) {
+            mockRecovery.recoverComLinkKilled();
+            EasyMock.expectLastCall().andThrow(new DeviceNotAvailableException()).once();
+        } else {
+            mockRecovery.recoverComLinkKilled();
+            EasyMock.expectLastCall().once();
+
+            // retry running config B
+            runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                    "{dEQP-GLES3{loss{instance}}}",
+                    "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+                    + " --deqp-gl-config-name=rgba8888d24s8 "
+                    + "--deqp-screen-rotation=90 "
+                    + "--deqp-surface-type=window "
+                    + "--deqp-log-images=disable "
+                    + "--deqp-watchdog=enable", instrumentationAnswerFine);
+
+            // query config C
+            expectRenderConfigQueryAndReturn(mockDevice,
+                    "--deqp-gl-config-name=rgba8888d24s8 "
+                    + "--deqp-screen-rotation=180 "
+                    + "--deqp-surface-type=window "
+                    + "--deqp-gl-major-version=3 "
+                    + "--deqp-gl-minor-version=0", "Yes");
+
+            // run config C
+            runInstrumentationLineAndAnswer(mockDevice, mockIDevice,
+                    "{dEQP-GLES3{loss{instance}}}",
+                    "--deqp-caselist-file=" + CASE_LIST_FILE_NAME
+                    + " --deqp-gl-config-name=rgba8888d24s8 "
+                    + "--deqp-screen-rotation=180 "
+                    + "--deqp-surface-type=window "
+                    + "--deqp-log-images=disable "
+                    + "--deqp-watchdog=enable", instrumentationAnswerFine);
+        }
+
+        mockListener.testRunStarted(ID, 1);
+        EasyMock.expectLastCall().once();
+
+        // result is reported only if device is available
+        if (recoverySuccessful) {
+            mockListener.testStarted(EasyMock.eq(testId));
+            EasyMock.expectLastCall().once();
+
+            mockListener.testEnded(EasyMock.eq(testId), EasyMock.<Map<String, String>>notNull());
+            EasyMock.expectLastCall().once();
+
+            mockListener.testRunEnded(EasyMock.anyLong(), EasyMock.<Map<String, String>>notNull());
+            EasyMock.expectLastCall().once();
+        }
+
+        EasyMock.replay(mockDevice, mockIDevice);
+        EasyMock.replay(mockListener);
+        EasyMock.replay(mockRecovery);
+
+        try {
+            deqpTest.run(mockListener);
+
+            if (!recoverySuccessful) {
+                fail("did not get DeviceNotAvailableException");
+            }
+        } catch (DeviceNotAvailableException ex) {
+            if (recoverySuccessful) {
+                fail("got DeviceNotAvailableException");
+            }
+        }
+
+        EasyMock.verify(mockRecovery);
+        EasyMock.verify(mockListener);
+        EasyMock.verify(mockDevice, mockIDevice);
+    }
+
+    /**
+     * Test dEQP with runner if device is lost during one of multiple instances.
+     */
+    public void testRun_multipleInstancesLossOfDeviceMidInstance() throws Exception {
+        testMultipleInstancesLossOfDeviceMidInstance(false);
+    }
+
+    /**
+     * Test dEQP with runner if device is lost during one of multiple instances but recovery
+     * is successful.
+     */
+    public void testRun_multipleInstancesLossOfDeviceMidInstanceAndRecovery() throws Exception {
+        testMultipleInstancesLossOfDeviceMidInstance(true);
+    }
+
+    public static interface RecoverableTestDevice extends ITestDevice {
+        public void recoverDevice() throws DeviceNotAvailableException;
+    }
+
+    private static enum RecoveryEvent {
+        PROGRESS,
+        FAIL_CONNECTION_REFUSED,
+        FAIL_LINK_KILLED,
+    };
+
+    private void runRecoveryWithPattern(DeqpTestRunner.Recovery recovery, RecoveryEvent[] events)
+            throws DeviceNotAvailableException {
+        for (RecoveryEvent event : events) {
+            switch (event) {
+                case PROGRESS:
+                    recovery.onExecutionProgressed();
+                    break;
+                case FAIL_CONNECTION_REFUSED:
+                    recovery.recoverConnectionRefused();
+                    break;
+                case FAIL_LINK_KILLED:
+                    recovery.recoverComLinkKilled();
+                    break;
+            }
+        }
+    }
+
+    private void setRecoveryExpectationWait(DeqpTestRunner.ISleepProvider mockSleepProvider) {
+        mockSleepProvider.sleep(EasyMock.gt(0));
+        EasyMock.expectLastCall().once();
+    }
+
+    private void setRecoveryExpectationKillProcess(RecoverableTestDevice mockDevice,
+            DeqpTestRunner.ISleepProvider mockSleepProvider) throws DeviceNotAvailableException {
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.contains("ps"))).
+                andReturn("root 1234 com.drawelement.deqp").once();
+
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("kill -9 1234"))).
+                andReturn("").once();
+
+        // Recovery checks if kill failed
+        mockSleepProvider.sleep(EasyMock.gt(0));
+        EasyMock.expectLastCall().once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.contains("ps"))).
+                andReturn("").once();
+    }
+
+    private void setRecoveryExpectationRecovery(RecoverableTestDevice mockDevice)
+            throws DeviceNotAvailableException {
+        mockDevice.recoverDevice();
+        EasyMock.expectLastCall().once();
+    }
+
+    private void setRecoveryExpectationReboot(RecoverableTestDevice mockDevice)
+            throws DeviceNotAvailableException {
+        mockDevice.reboot();
+        EasyMock.expectLastCall().once();
+    }
+
+    private int setRecoveryExpectationOfAConnFailure(RecoverableTestDevice mockDevice,
+            DeqpTestRunner.ISleepProvider mockSleepProvider, int numConsecutiveErrors)
+            throws DeviceNotAvailableException {
+        switch (numConsecutiveErrors) {
+            case 0:
+            case 1:
+                setRecoveryExpectationRecovery(mockDevice);
+                return 2;
+            case 2:
+                setRecoveryExpectationReboot(mockDevice);
+                return 3;
+            default:
+                return 4;
+        }
+    }
+
+    private int setRecoveryExpectationOfAComKilled(RecoverableTestDevice mockDevice,
+            DeqpTestRunner.ISleepProvider mockSleepProvider, int numConsecutiveErrors)
+            throws DeviceNotAvailableException {
+        switch (numConsecutiveErrors) {
+            case 0:
+                setRecoveryExpectationWait(mockSleepProvider);
+                setRecoveryExpectationKillProcess(mockDevice, mockSleepProvider);
+                return 1;
+            case 1:
+                setRecoveryExpectationRecovery(mockDevice);
+                setRecoveryExpectationKillProcess(mockDevice, mockSleepProvider);
+                return 2;
+            case 2:
+                setRecoveryExpectationReboot(mockDevice);
+                return 3;
+            default:
+                return 4;
+        }
+    }
+
+    private void setRecoveryExpectationsOfAPattern(RecoverableTestDevice mockDevice,
+            DeqpTestRunner.ISleepProvider mockSleepProvider, RecoveryEvent[] events)
+            throws DeviceNotAvailableException {
+        int numConsecutiveErrors = 0;
+        for (RecoveryEvent event : events) {
+            switch (event) {
+                case PROGRESS:
+                    numConsecutiveErrors = 0;
+                    break;
+                case FAIL_CONNECTION_REFUSED:
+                    numConsecutiveErrors = setRecoveryExpectationOfAConnFailure(mockDevice,
+                            mockSleepProvider, numConsecutiveErrors);
+                    break;
+                case FAIL_LINK_KILLED:
+                    numConsecutiveErrors = setRecoveryExpectationOfAComKilled(mockDevice,
+                            mockSleepProvider, numConsecutiveErrors);
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Test dEQP runner recovery state machine.
+     */
+    private void testRecoveryWithPattern(boolean expectSuccess, RecoveryEvent...pattern)
+            throws Exception {
+        DeqpTestRunner.Recovery recovery = new DeqpTestRunner.Recovery();
+        IMocksControl orderedControl = EasyMock.createStrictControl();
+        RecoverableTestDevice mockDevice = orderedControl.createMock(RecoverableTestDevice.class);
+        DeqpTestRunner.ISleepProvider mockSleepProvider =
+                orderedControl.createMock(DeqpTestRunner.ISleepProvider.class);
+
+        setRecoveryExpectationsOfAPattern(mockDevice, mockSleepProvider, pattern);
+
+        orderedControl.replay();
+
+        recovery.setDevice(mockDevice);
+        recovery.setSleepProvider(mockSleepProvider);
+        try {
+            runRecoveryWithPattern(recovery, pattern);
+            if (!expectSuccess) {
+                fail("Expected DeviceNotAvailableException");
+            }
+        } catch (DeviceNotAvailableException ex) {
+            if (expectSuccess) {
+                fail("Did not expect DeviceNotAvailableException");
+            }
+        }
+
+        orderedControl.verify();
+    }
+
+    // basic patterns
+
+    public void testRecovery_NoEvents() throws Exception {
+        testRecoveryWithPattern(true);
+    }
+
+    public void testRecovery_AllOk() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.PROGRESS, RecoveryEvent.PROGRESS);
+    }
+
+    // conn fail patterns
+
+    public void testRecovery_OneConnectionFailureBegin() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.FAIL_CONNECTION_REFUSED,
+                RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_TwoConnectionFailuresBegin() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.FAIL_CONNECTION_REFUSED,
+                RecoveryEvent.FAIL_CONNECTION_REFUSED, RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_ThreeConnectionFailuresBegin() throws Exception {
+        testRecoveryWithPattern(false, RecoveryEvent.FAIL_CONNECTION_REFUSED,
+                RecoveryEvent.FAIL_CONNECTION_REFUSED, RecoveryEvent.FAIL_CONNECTION_REFUSED);
+    }
+
+    public void testRecovery_OneConnectionFailureMid() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.PROGRESS,
+                RecoveryEvent.FAIL_CONNECTION_REFUSED, RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_TwoConnectionFailuresMid() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.PROGRESS,
+                RecoveryEvent.FAIL_CONNECTION_REFUSED, RecoveryEvent.FAIL_CONNECTION_REFUSED,
+                RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_ThreeConnectionFailuresMid() throws Exception {
+        testRecoveryWithPattern(false, RecoveryEvent.PROGRESS,
+                RecoveryEvent.FAIL_CONNECTION_REFUSED, RecoveryEvent.FAIL_CONNECTION_REFUSED,
+                RecoveryEvent.FAIL_CONNECTION_REFUSED);
+    }
+
+    // link fail patterns
+
+    public void testRecovery_OneLinkFailureBegin() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_TwoLinkFailuresBegin() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.FAIL_LINK_KILLED, RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_ThreeLinkFailuresBegin() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.FAIL_LINK_KILLED, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_FourLinkFailuresBegin() throws Exception {
+        testRecoveryWithPattern(false, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.FAIL_LINK_KILLED, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.FAIL_LINK_KILLED);
+    }
+
+    public void testRecovery_OneLinkFailureMid() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.PROGRESS,
+                RecoveryEvent.FAIL_LINK_KILLED, RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_TwoLinkFailuresMid() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.PROGRESS,
+                RecoveryEvent.FAIL_LINK_KILLED, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_ThreeLinkFailuresMid() throws Exception {
+        testRecoveryWithPattern(true, RecoveryEvent.PROGRESS,
+                RecoveryEvent.FAIL_LINK_KILLED, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.FAIL_LINK_KILLED, RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_FourLinkFailuresMid() throws Exception {
+        testRecoveryWithPattern(false, RecoveryEvent.PROGRESS, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.FAIL_LINK_KILLED, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.FAIL_LINK_KILLED);
+    }
+
+    // mixed patterns
+
+    public void testRecovery_MixedFailuresProgressBetween() throws Exception {
+        testRecoveryWithPattern(true,
+                RecoveryEvent.PROGRESS, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.PROGRESS, RecoveryEvent.FAIL_CONNECTION_REFUSED,
+                RecoveryEvent.PROGRESS, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.PROGRESS, RecoveryEvent.FAIL_CONNECTION_REFUSED,
+                RecoveryEvent.PROGRESS);
+    }
+
+    public void testRecovery_MixedFailuresNoProgressBetween() throws Exception {
+        testRecoveryWithPattern(true,
+                RecoveryEvent.PROGRESS, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.FAIL_CONNECTION_REFUSED, RecoveryEvent.FAIL_LINK_KILLED,
+                RecoveryEvent.PROGRESS);
+    }
+
+    /**
+     * Test recovery if process cannot be killed
+     */
+    public void testRecovery_unkillableProcess () throws Exception {
+        DeqpTestRunner.Recovery recovery = new DeqpTestRunner.Recovery();
+        IMocksControl orderedControl = EasyMock.createStrictControl();
+        RecoverableTestDevice mockDevice = orderedControl.createMock(RecoverableTestDevice.class);
+        DeqpTestRunner.ISleepProvider mockSleepProvider =
+                orderedControl.createMock(DeqpTestRunner.ISleepProvider.class);
+
+        // recovery attempts to kill the process after a timeout
+        mockSleepProvider.sleep(EasyMock.gt(0));
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.contains("ps"))).
+                andReturn("root 1234 com.drawelement.deqp").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("kill -9 1234"))).
+                andReturn("").once();
+
+        // Recovery checks if kill failed
+        mockSleepProvider.sleep(EasyMock.gt(0));
+        EasyMock.expectLastCall().once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.contains("ps"))).
+                andReturn("root 1234 com.drawelement.deqp").once();
+
+        // Recovery resets the connection
+        mockDevice.recoverDevice();
+        EasyMock.expectLastCall().once();
+
+        // and attempts to kill the process again
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.contains("ps"))).
+                andReturn("root 1234 com.drawelement.deqp").once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("kill -9 1234"))).
+                andReturn("").once();
+
+        // Recovery checks if kill failed
+        mockSleepProvider.sleep(EasyMock.gt(0));
+        EasyMock.expectLastCall().once();
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.contains("ps"))).
+                andReturn("root 1234 com.drawelement.deqp").once();
+
+        // recovery reboots the device
+        mockDevice.reboot();
+        EasyMock.expectLastCall().once();
+
+        orderedControl.replay();
+        recovery.setDevice(mockDevice);
+        recovery.setSleepProvider(mockSleepProvider);
+        recovery.recoverComLinkKilled();
+        orderedControl.verify();
+    }
+
+    /**
+     * Test external interruption before batch run.
+     */
+    public void testInterrupt_killBeforeBatch() throws Exception {
+        final TestIdentifier testId = new TestIdentifier("dEQP-GLES3.interrupt", "test");
+
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        tests.add(testId);
+
+        Map<TestIdentifier, List<Map<String, String>>> instance = new HashMap<>();
+        instance.put(testId, DEFAULT_INSTANCE_ARGS);
+
+        ITestInvocationListener mockListener
+                = EasyMock.createStrictMock(ITestInvocationListener.class);
+        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
+        IDevice mockIDevice = EasyMock.createMock(IDevice.class);
+        IRunUtil mockRunUtil = EasyMock.createMock(IRunUtil.class);
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instance);
+        deqpTest.setAbi(UnitTests.ABI);
+        deqpTest.setDevice(mockDevice);
+        deqpTest.setBuildHelper(new StubCtsBuildHelper());
+        deqpTest.setRunUtil(mockRunUtil);
+
+        int version = 3 << 16;
+        EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+                .andReturn(Integer.toString(version)).atLeastOnce();
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+            andReturn("").once();
+
+        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+                EasyMock.eq(true),
+                EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+                .once();
+
+        expectRenderConfigQuery(mockDevice,
+                "--deqp-gl-config-name=rgba8888d24s8 --deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window --deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0");
+
+        mockRunUtil.sleep(0);
+        EasyMock.expectLastCall().andThrow(new RunInterruptedException());
+
+        mockListener.testRunStarted(ID, 1);
+        EasyMock.expectLastCall().once();
+
+        EasyMock.replay(mockDevice, mockIDevice);
+        EasyMock.replay(mockListener);
+        EasyMock.replay(mockRunUtil);
+        try {
+            deqpTest.run(mockListener);
+            fail("expected RunInterruptedException");
+        } catch (RunInterruptedException ex) {
+            // expected
+        }
+        EasyMock.verify(mockRunUtil);
+        EasyMock.verify(mockListener);
+        EasyMock.verify(mockDevice, mockIDevice);
+    }
+
+    /**
+     * Test external interruption in testFailed().
+     */
+    public void testInterrupt_killReportTestFailed() throws Exception {
+        final TestIdentifier testId = new TestIdentifier("dEQP-GLES3.interrupt", "test");
+        final String testPath = "dEQP-GLES3.interrupt.test";
+        final String testTrie = "{dEQP-GLES3{interrupt{test}}}";
+        final String output = "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=2014.x\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=releaseId\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=0xcafebabe\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Name=targetName\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=SessionInfo\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-SessionInfo-Value=android\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=BeginTestCase\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-BeginTestCase-TestCasePath=" + testPath + "\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Code=Fail\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-TestCaseResult-Details=Fail\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=TestCaseResult\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndTestCase\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_STATUS: dEQP-EventType=EndSession\r\n"
+                + "INSTRUMENTATION_STATUS_CODE: 0\r\n"
+                + "INSTRUMENTATION_CODE: 0\r\n";
+
+        Collection<TestIdentifier> tests = new ArrayList<TestIdentifier>();
+        tests.add(testId);
+
+        Map<TestIdentifier, List<Map<String, String>>> instance = new HashMap<>();
+        instance.put(testId, DEFAULT_INSTANCE_ARGS);
+
+        ITestInvocationListener mockListener
+                = EasyMock.createStrictMock(ITestInvocationListener.class);
+        ITestDevice mockDevice = EasyMock.createMock(ITestDevice.class);
+        IDevice mockIDevice = EasyMock.createMock(IDevice.class);
+        IRunUtil mockRunUtil = EasyMock.createMock(IRunUtil.class);
+
+        DeqpTestRunner deqpTest = new DeqpTestRunner(NAME, NAME, tests, instance);
+        deqpTest.setAbi(UnitTests.ABI);
+        deqpTest.setDevice(mockDevice);
+        deqpTest.setBuildHelper(new StubCtsBuildHelper());
+        deqpTest.setRunUtil(mockRunUtil);
+
+        int version = 3 << 16;
+        EasyMock.expect(mockDevice.getProperty("ro.opengles.version"))
+                .andReturn(Integer.toString(version)).atLeastOnce();
+
+        EasyMock.expect(mockDevice.uninstallPackage(EasyMock.eq(DEQP_ONDEVICE_PKG))).
+            andReturn("").once();
+
+        EasyMock.expect(mockDevice.installPackage(EasyMock.<File>anyObject(),
+                EasyMock.eq(true),
+                EasyMock.eq(AbiUtils.createAbiFlag(UnitTests.ABI.getName())))).andReturn(null)
+                .once();
+
+        expectRenderConfigQuery(mockDevice,
+                "--deqp-gl-config-name=rgba8888d24s8 --deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window --deqp-gl-major-version=3 "
+                + "--deqp-gl-minor-version=0");
+
+        mockRunUtil.sleep(0);
+        EasyMock.expectLastCall().once();
+
+        String commandLine = String.format(
+                "--deqp-caselist-file=%s --deqp-gl-config-name=rgba8888d24s8 "
+                + "--deqp-screen-rotation=unspecified "
+                + "--deqp-surface-type=window "
+                + "--deqp-log-images=disable "
+                + "--deqp-watchdog=enable",
+                CASE_LIST_FILE_NAME);
+
+        runInstrumentationLineAndAnswer(mockDevice, mockIDevice, testTrie, commandLine,
+                output);
+
+        mockListener.testRunStarted(ID, 1);
+        EasyMock.expectLastCall().once();
+
+        mockListener.testStarted(EasyMock.eq(testId));
+        EasyMock.expectLastCall().once();
+
+        mockListener.testFailed(EasyMock.eq(testId), EasyMock.<String>notNull());
+        EasyMock.expectLastCall().andThrow(new RunInterruptedException());
+
+        EasyMock.replay(mockDevice, mockIDevice);
+        EasyMock.replay(mockListener);
+        EasyMock.replay(mockRunUtil);
+        try {
+            deqpTest.run(mockListener);
+            fail("expected RunInterruptedException");
+        } catch (RunInterruptedException ex) {
+            // expected
+        }
+        EasyMock.verify(mockRunUtil);
+        EasyMock.verify(mockListener);
+        EasyMock.verify(mockDevice, mockIDevice);
+    }
+
+    private void runInstrumentationLineAndAnswer(ITestDevice mockDevice, IDevice mockIDevice,
+            final String testTrie, final String cmd, final String output) throws Exception {
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + CASE_LIST_FILE_NAME)))
+                .andReturn("").once();
+
+        EasyMock.expect(mockDevice.executeShellCommand(EasyMock.eq("rm " + LOG_FILE_NAME)))
+                .andReturn("").once();
+
+        EasyMock.expect(mockDevice.pushString(testTrie + "\n", CASE_LIST_FILE_NAME))
+                .andReturn(true).once();
+
+        String command = String.format(
+                "am instrument %s -w -e deqpLogFileName \"%s\" -e deqpCmdLine \"%s\" "
+                    + "-e deqpLogData \"%s\" %s",
+                AbiUtils.createAbiFlag(UnitTests.ABI.getName()), LOG_FILE_NAME, cmd, false,
+                INSTRUMENTATION_NAME);
+
+        EasyMock.expect(mockDevice.getIDevice()).andReturn(mockIDevice);
+        mockIDevice.executeShellCommand(EasyMock.eq(command),
+                EasyMock.<IShellOutputReceiver>notNull(), EasyMock.anyLong(),
+                EasyMock.isA(TimeUnit.class));
+
+        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
+            @Override
+            public Object answer() {
+                IShellOutputReceiver receiver
+                        = (IShellOutputReceiver)EasyMock.getCurrentArguments()[1];
+
+                receiver.addOutput(output.getBytes(), 0, output.length());
+                receiver.flush();
+
+                return null;
+            }
+        });
+    }
 }
diff --git a/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/GeeTestTest.java b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/GeeTestTest.java
new file mode 100644
index 0000000..93272be
--- /dev/null
+++ b/tools/tradefed-host/tests/src/com/android/cts/tradefed/testtype/GeeTestTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.UnitTests;
+
+import junit.framework.TestCase;
+
+/**
+ * Unit tests for {@link GeeTest}.
+ */
+public class GeeTestTest extends TestCase {
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+     /**
+     * Test {@link GeeTestTest#getGTestFilters}
+     * @throws DeviceNotAvailableException
+     */
+    public void testGetGTestFilters() {
+        GeeTest test = new GeeTest("package_foo", "exe_foo");
+        test.setPositiveFilters("a");
+        test.setNegativeFilters("b");
+        String actual = test.getGTestFilters();
+        assertEquals("--gtest_filter=a:-b", actual);
+    }
+
+    /**
+     * Test {@link GeeTestTest#getGTestFilters} with only positive filters
+     * @throws DeviceNotAvailableException
+     */
+    public void testGetGTestFiltersPositiveOnly() {
+        GeeTest test = new GeeTest("package_foo", "exe_foo");
+        test.setPositiveFilters("a");
+        String actual = test.getGTestFilters();
+        assertEquals("--gtest_filter=a", actual);
+    }
+
+    /**
+     * Test {@link GeeTestTest#getGTestFilters} with only negative filters
+     * @throws DeviceNotAvailableException
+     */
+    public void testGetGTestFiltersNegativeOnly() {
+        GeeTest test = new GeeTest("package_foo", "exe_foo");
+        test.setNegativeFilters("b");
+        String actual = test.getGTestFilters();
+        assertEquals("--gtest_filter=-b", actual);
+    }
+
+    /**
+     * Test {@link GeeTestTest#getGTestFilters} with empty filters
+     * @throws DeviceNotAvailableException
+     */
+    public void testGetGTestFiltersWithNoFilters() {
+        GeeTest test = new GeeTest("package_foo", "exe_foo");
+        String actual = test.getGTestFilters();
+        assertEquals("", actual);
+    }
+}
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 6d87a61..bd48c51 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
@@ -25,6 +25,8 @@
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 /**
  * Unit tests for {@link TestPackageXmlParser}.
@@ -65,6 +67,29 @@
 
     private static final String NO_TEST_DATA = "<invalid />";
 
+    private static final String INSTANCED_TEST_DATA =
+        "<TestPackage>\n" +
+        "    <TestSuite name=\"com\" >\n" +
+        "        <TestSuite name=\"example\" >\n" +
+        "            <TestCase name=\"ExampleTest\" >\n" +
+        "                <Test name=\"testMultiInstanced\" >\n" +
+        "                    <TestInstance foo=\"bar\" />\n" +
+        "                    <TestInstance foo=\"baz\" foo2=\"baz2\"/>\n" +
+        "                </Test>\n" +
+        "                <Test name=\"testSingleInstanced\" >\n" +
+        "                    <TestInstance foo=\"bar\" />\n" +
+        "                </Test>\n" +
+        "                <Test name=\"testEmptyInstances\" >\n" +
+        "                    <TestInstance />\n" +
+        "                    <TestInstance />\n" +
+        "                </Test>\n" +
+        "                <Test name=\"testNotInstanced\" >\n" +
+        "                </Test>\n" +
+        "            </TestCase>\n" +
+        "        </TestSuite>\n" +
+        "    </TestSuite>\n" +
+        "</TestPackage>";
+
     /**
      * Test parsing test case xml containing an instrumentation test definition.
      */
@@ -162,6 +187,90 @@
         assertTrue(parser.getTestPackageDefs().isEmpty());
     }
 
+    /**
+     * Test parsing a test case xml with multiple test instances
+     */
+    public void testParse_instancedMultiple() throws ParseException  {
+        TestPackageXmlParser parser = new TestPackageXmlParser(true);
+        parser.parse(getStringAsStream(INSTANCED_TEST_DATA));
+        for (TestPackageDef def : parser.getTestPackageDefs()) {
+            final TestIdentifier testId =
+                    new TestIdentifier("com.example.ExampleTest", "testMultiInstanced");
+            final List<Map<String, String>> targetInstances =
+                    def.getTestInstanceArguments().get(testId);
+            assertNotNull(targetInstances);
+            assertEquals(2, targetInstances.size());
+
+            final Iterator<Map<String, String>> iterator = targetInstances.iterator();
+            final Map<String, String> firstInstance = iterator.next();
+            final Map<String, String> secondInstance = iterator.next();
+
+            assertEquals("bar", firstInstance.get("foo"));
+            assertEquals("baz", secondInstance.get("foo"));
+            assertEquals("baz2", secondInstance.get("foo2"));
+        }
+    }
+
+    /**
+     * Test parsing a test case xml with single test instance
+     */
+    public void testParse_instancedSingle() throws ParseException  {
+        TestPackageXmlParser parser = new TestPackageXmlParser(true);
+        parser.parse(getStringAsStream(INSTANCED_TEST_DATA));
+        for (TestPackageDef def : parser.getTestPackageDefs()) {
+            final TestIdentifier testId =
+                    new TestIdentifier("com.example.ExampleTest", "testSingleInstanced");
+            final List<Map<String, String>> targetInstances =
+                    def.getTestInstanceArguments().get(testId);
+            assertNotNull(targetInstances);
+            assertEquals(1, targetInstances.size());
+
+            final Iterator<Map<String, String>> iterator = targetInstances.iterator();
+            final Map<String, String> firstInstance = iterator.next();
+
+            assertEquals("bar", firstInstance.get("foo"));
+        }
+    }
+
+    /**
+     * Test parsing a test case xml with multiple test instances with no data
+     */
+    public void testParse_instancedEmptys() throws ParseException  {
+        TestPackageXmlParser parser = new TestPackageXmlParser(true);
+        parser.parse(getStringAsStream(INSTANCED_TEST_DATA));
+        for (TestPackageDef def : parser.getTestPackageDefs()) {
+            final TestIdentifier testId =
+                    new TestIdentifier("com.example.ExampleTest", "testEmptyInstances");
+            final List<Map<String, String>> targetInstances =
+                    def.getTestInstanceArguments().get(testId);
+            assertNotNull(targetInstances);
+            assertEquals(2, targetInstances.size());
+
+            final Iterator<Map<String, String>> iterator = targetInstances.iterator();
+            final Map<String, String> firstInstance = iterator.next();
+            final Map<String, String> secondInstance = iterator.next();
+
+            assertTrue(firstInstance.isEmpty());
+            assertTrue(secondInstance.isEmpty());
+        }
+    }
+
+    /**
+     * Test parsing a test case xml with no test instances
+     */
+    public void testParse_instancedNoInstances() throws ParseException  {
+        TestPackageXmlParser parser = new TestPackageXmlParser(true);
+        parser.parse(getStringAsStream(INSTANCED_TEST_DATA));
+        for (TestPackageDef def : parser.getTestPackageDefs()) {
+            final TestIdentifier testId =
+                    new TestIdentifier("com.example.ExampleTest", "testNotInstanced");
+            final List<Map<String, String>> targetInstances =
+                    def.getTestInstanceArguments().get(testId);
+            assertNotNull(targetInstances);
+            assertTrue(targetInstances.isEmpty());
+        }
+    }
+
     private InputStream getStringAsStream(String input) {
         return new ByteArrayInputStream(input.getBytes());
     }
diff --git a/tools/utils/CollectAllTests.java b/tools/utils/CollectAllTests.java
index 95b77f2..83c451e 100644
--- a/tools/utils/CollectAllTests.java
+++ b/tools/utils/CollectAllTests.java
@@ -447,6 +447,9 @@
                                                                     expectations,
                                                                     testClassName,
                                                                     testName);
+        int timeoutInMinutes = VogarUtils.timeoutInMinutes(expectations,
+                                                           testClassName,
+                                                           testName);
         TestClass testClass;
         if (testCases.containsKey(testClassName)) {
             testClass = testCases.get(testClassName);
@@ -456,7 +459,7 @@
         }
 
         testClass.mCases.add(new TestMethod(testName, "", "", supportedAbis,
-              knownFailure, false, false));
+              knownFailure, false, false, timeoutInMinutes));
     }
 
     private static boolean isJunit3Test(Class<?> klass) {
diff --git a/tools/utils/DescriptionGenerator.java b/tools/utils/DescriptionGenerator.java
index 09e1118..1e2542f 100644
--- a/tools/utils/DescriptionGenerator.java
+++ b/tools/utils/DescriptionGenerator.java
@@ -86,6 +86,7 @@
     static final String ATTRIBUTE_NAME = "name";
     static final String ATTRIBUTE_ABIS = "abis";
     static final String ATTRIBUTE_HOST_CONTROLLER = "HostController";
+    static final String ATTRIBUTE_TIMEOUT = "timeout";
 
     static final String XML_OUTPUT_PATH = "./description.xml";
 
@@ -438,6 +439,10 @@
                     if ((caze.mController != null) && (caze.mController.length() != 0)) {
                         setAttribute(caseNode, ATTRIBUTE_HOST_CONTROLLER, caze.mController);
                     }
+                    if (caze.mTimeoutInMinutes != 0) {
+                        setAttribute(caseNode, ATTRIBUTE_TIMEOUT,
+                                     Integer.toString(caze.mTimeoutInMinutes));
+                    }
 
                     if (caze.mDescription != null && !caze.mDescription.equals("")) {
                         caseNode.appendChild(mDoc.createElement(TAG_DESCRIPTION))
@@ -573,9 +578,10 @@
                             VogarUtils.buildFullTestName(clazz.toString(), name));
                     Set<String> supportedAbis =
                             VogarUtils.extractSupportedAbis(architecture, expectation);
+                    int timeoutInMinutes = VogarUtils.timeoutInMinutes(expectation);
                     cases.add(new TestMethod(
                             name, method.commentText(), controller, supportedAbis,
-                                    knownFailure, isBroken, isSuppressed));
+                                    knownFailure, isBroken, isSuppressed, timeoutInMinutes));
                 }
             }
 
@@ -635,6 +641,7 @@
         String mKnownFailure;
         boolean mIsBroken;
         boolean mIsSuppressed;
+        int mTimeoutInMinutes;  // zero to use default timeout.
 
         /**
          * Construct an test case object.
@@ -644,7 +651,10 @@
          * @param knownFailure The reason of known failure.
          */
         TestMethod(String name, String description, String controller, Set<String> abis,
-                String knownFailure, boolean isBroken, boolean isSuppressed) {
+                String knownFailure, boolean isBroken, boolean isSuppressed, int timeoutInMinutes) {
+            if (timeoutInMinutes < 0) {
+                throw new IllegalArgumentException("timeoutInMinutes < 0: " + timeoutInMinutes);
+            }
             mName = name;
             mDescription = description;
             mController = controller;
@@ -652,6 +662,7 @@
             mKnownFailure = knownFailure;
             mIsBroken = isBroken;
             mIsSuppressed = isSuppressed;
+            mTimeoutInMinutes = timeoutInMinutes;
         }
     }
 }
diff --git a/tools/utils/VogarUtils.java b/tools/utils/VogarUtils.java
index 5e8b944..8e77e7c 100644
--- a/tools/utils/VogarUtils.java
+++ b/tools/utils/VogarUtils.java
@@ -19,6 +19,7 @@
 import vogar.Expectation;
 import vogar.ExpectationStore;
 import vogar.ModeId;
+import vogar.Result;
 
 import java.io.File;
 import java.io.FilenameFilter;
@@ -52,14 +53,14 @@
         }
         String fullTestName = buildFullTestName(testClassName, testMethodName);
         Expectation expectation = expectationStore.get(fullTestName);
-        if (expectation == Expectation.SUCCESS) {
+        if (expectation.getResult() == Result.SUCCESS) {
             return false;
         }
 
         String description = expectation.getDescription();
         boolean foundAbi = AbiUtils.parseAbiList(description).size() > 0;
 
-        return expectation != Expectation.SUCCESS && !foundAbi;
+        return expectation.getResult() != Result.SUCCESS && !foundAbi;
     }
 
     public static ExpectationStore provideExpectationStore(String dir) throws IOException {
@@ -119,7 +120,7 @@
                                                    String className,
                                                    String testName) {
 
-        String fullTestName = VogarUtils.buildFullTestName(className, testName);
+        String fullTestName = buildFullTestName(className, testName);
         Set<String> supportedAbiSet = AbiUtils.getAbisForArch(architecture);
         for (ExpectationStore expectationStore : expectationStores) {
             Expectation expectation = expectationStore.get(fullTestName);
@@ -128,4 +129,44 @@
 
         return supportedAbiSet;
     }
+
+    /**
+     * Returns the greatest timeout in minutes for the test in all
+     * expectation stores, or 0 if no timeout was found.
+     */
+    public static int timeoutInMinutes(ExpectationStore[] expectationStores,
+            final String testClassName,
+            final String testMethodName) {
+        int timeoutInMinutes = 0;
+        for (ExpectationStore expectationStore : expectationStores) {
+            timeoutInMinutes = Math.max(timeoutInMinutes,
+                                        timeoutInMinutes(expectationStore,
+                                                         testClassName,
+                                                         testMethodName));
+        }
+        return timeoutInMinutes;
+    }
+
+    /**
+     * Returns the timeout in minutes for the test in the expectation
+     * stores, or 0 if no timeout was found.
+     */
+    public static int timeoutInMinutes(ExpectationStore expectationStore,
+            final String testClassName,
+            final String testMethodName) {
+        if (expectationStore == null) {
+            return 0;
+        }
+        String fullTestName = buildFullTestName(testClassName, testMethodName);
+        return timeoutInMinutes(expectationStore.get(fullTestName));
+    }
+
+    /**
+     * Returns the timeout in minutes for the expectation. Currently a
+     * tag of large results in a 60 minute timeout, otherwise 0 is
+     * returned to indicate a default timeout should be used.
+     */
+    public static int timeoutInMinutes(Expectation expectation) {
+        return expectation.getTags().contains("large") ? 60 : 0;
+    }
 }
diff --git a/tools/utils/buildCts.py b/tools/utils/buildCts.py
index 4d04e1a..a6c76b1 100755
--- a/tools/utils/buildCts.py
+++ b/tools/utils/buildCts.py
@@ -30,6 +30,12 @@
   """Return all directories under the given root directory."""
   return [x for x in os.listdir(root) if os.path.isdir(os.path.join(root, x))]
 
+def ReadFileLines(filePath):
+  """Reads a file and returns its contents as a line list."""
+  f = open(filePath, 'r');
+  lines = [line.strip() for line in f.readlines()]
+  f.close()
+  return lines
 
 def GetMakeFileVars(makefile_path):
   """Extracts variable definitions from the given make file.
@@ -153,13 +159,17 @@
     plan.Include('com\.android\.cts\..*')#TODO(stuartscott): Should PDK have all these?
     self.__WritePlan(plan, 'PDK')
 
+    temporarily_known_failure_tests = BuildCtsTemporarilyKnownFailureList();
     flaky_tests = BuildCtsFlakyTestList()
+    releasekey_tests = BuildListForReleaseBuildTest()
 
     # CTS Stable plan
     plan = tools.TestPlan(packages)
     plan.Exclude(r'com\.android\.cts\.browserbench')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
+    for package, test_list in releasekey_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-stable')
 
     # CTS Flaky plan - list of tests known to be flaky in lab environment
@@ -183,7 +193,10 @@
     plan.Exclude(r'com\.android\.cts\.browserbench')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
+    for package, test_list in releasekey_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-kitkat-small')
+    self.__WritePlan(plan, 'CTS-public-small')
 
     # CTS - sub plan for public, medium size tests
     plan = tools.TestPlan(packages)
@@ -193,7 +206,10 @@
     plan.Exclude(r'com\.android\.cts\.browserbench')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
+    for package, test_list in releasekey_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-kitkat-medium')
+    self.__WritePlan(plan, 'CTS-public-medium')
 
     # CTS - sub plan for hardware tests which is public, large
     plan = tools.TestPlan(packages)
@@ -202,8 +218,24 @@
     plan.Exclude(r'com\.android\.cts\.browserbench')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
+    for package, test_list in releasekey_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-hardware')
 
+    # CTS - sub plan for camera tests which is public, large
+    plan = tools.TestPlan(packages)
+    plan.Exclude('.*')
+    plan.Include(r'android\.camera$')
+    misc_camera_tests = BuildCtsMiscCameraList()
+    for package, test_list in misc_camera_tests.iteritems():
+      plan.Include(package+'$')
+      plan.IncludeTests(package, test_list)
+    for package, test_list in flaky_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
+    for package, test_list in releasekey_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
+    self.__WritePlan(plan, 'CTS-camera')
+
     # CTS - sub plan for media tests which is public, large
     plan = tools.TestPlan(packages)
     plan.Exclude('.*')
@@ -212,6 +244,8 @@
     plan.Exclude(r'com\.android\.cts\.browserbench')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
+    for package, test_list in releasekey_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-media')
 
     # CTS - sub plan for mediastress tests which is public, large
@@ -221,6 +255,8 @@
     plan.Exclude(r'com\.android\.cts\.browserbench')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
+    for package, test_list in releasekey_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-mediastress')
 
     # CTS - sub plan for new tests that is vetted for L launch
@@ -231,9 +267,17 @@
     plan.Exclude(r'com\.android\.cts\.browserbench')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
+    for package, test_list in releasekey_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-l-tests')
 
-    #CTS - sub plan for new test packages added for staging
+    # CTS - sub plan for tests in drawelement packages
+    plan = tools.TestPlan(packages)
+    plan.Exclude('.*')
+    plan.Include(r'com\.drawelements\.')
+    self.__WritePlan(plan, 'CTS-DEQP')
+
+    # CTS - sub plan for new test packages added for staging
     plan = tools.TestPlan(packages)
     for package, test_list in small_tests.iteritems():
       plan.Exclude(package+'$')
@@ -241,6 +285,7 @@
       plan.Exclude(package+'$')
     for package, tests_list in new_test_packages.iteritems():
       plan.Exclude(package+'$')
+    plan.Exclude(r'com\.drawelements\.')
     plan.Exclude(r'android\.hardware$')
     plan.Exclude(r'android\.media$')
     plan.Exclude(r'android\.view$')
@@ -248,16 +293,21 @@
     plan.Exclude(r'com\.android\.cts\.browserbench')
     for package, test_list in flaky_tests.iteritems():
       plan.ExcludeTests(package, test_list)
+    for package, test_list in releasekey_tests.iteritems():
+      plan.ExcludeTests(package, test_list)
+    self.__WritePlan(plan, 'CTS-m-tests')
+
+
+    # CTS - sub plan for new test packages added for staging
+    plan = tools.TestPlan(packages)
+    plan.Exclude('.*')
+    for package, test_list in temporarily_known_failure_tests.iteritems():
+      plan.Include(package+'$')
+      plan.IncludeTests(package, test_list)
     self.__WritePlan(plan, 'CTS-staging')
 
     plan = tools.TestPlan(packages)
     plan.Exclude('.*')
-    plan.Include(r'com\.drawelements\.')
-    self.__WritePlan(plan, 'CTS-DEQP')
-
-    plan = tools.TestPlan(packages)
-    plan.Exclude('.*')
-    plan.Include(r'android\.webgl')
     self.__WritePlan(plan, 'CTS-webview')
 
 
@@ -281,7 +331,7 @@
       'com.android.cts.browserbench' : []}
 
 def BuildAospSmallSizeTestList():
-  """ Construct a defaultdict that lists packages names of small tests
+  """ Construct a default dict that lists packages names of small tests
       already published to aosp. """
   return {
       'android.aadb' : [],
@@ -335,6 +385,7 @@
       'com.android.cts.dram' : [],
       'com.android.cts.filesystemperf' : [],
       'com.android.cts.jank' : [],
+      'com.android.cts.jank2' : [],
       'com.android.cts.opengl' : [],
       'com.android.cts.simplecpu' : [],
       'com.android.cts.ui' : [],
@@ -370,52 +421,118 @@
       'android.signature' : [],
       'android.tv' : [],
       'android.uiautomation' : [],
-      'android.uirendering' : [],
-      'android.webgl' : [],
-      'com.drawelements.deqp.gles3' : [],
-      'com.drawelements.deqp.gles31' : []}
+      'android.uirendering' : []}
+
+def BuildListForReleaseBuildTest():
+  """ Construct a defaultdict that maps package name to a list of tests
+      that are expected to pass only when running against a user/release-key build. """
+  return {
+      'android.app' : [
+          'android.app.cts.ActivityManagerTest#testIsRunningInTestHarness',],
+      'android.dpi' : [
+          'android.dpi.cts.DefaultManifestAttributesSdkTest#testPackageHasExpectedSdkVersion',],
+      'android.host.security' : [
+          'android.cts.security.SELinuxHostTest#testAllEnforcing',
+          'android.cts.security.SELinuxHostTest#testSuDomain',],
+      'android.os' : [
+          'android.os.cts.BuildVersionTest#testReleaseVersion',
+          'android.os.cts.BuildTest#testIsSecureUserBuild',],
+      'android.security' : [
+          'android.security.cts.BannedFilesTest#testNoSu',
+          'android.security.cts.BannedFilesTest#testNoSuInPath',
+          'android.security.cts.PackageSignatureTest#testPackageSignatures',
+          'android.security.cts.SELinuxDomainTest#testSuDomain',],
+      '' : []}
 
 def BuildCtsFlakyTestList():
   """ Construct a defaultdict that maps package name to a list of tests
-      that are known to be flaky in the lab or not passing on userdebug builds. """
+      that flaky during dev cycle and cause other subsequent tests to fail. """
+  return {
+      'android.camera' : [
+          'android.hardware.cts.CameraTest#testVideoSnapshot',
+          'android.hardware.cts.CameraGLTest#testCameraToSurfaceTextureMetadata',
+          'android.hardware.cts.CameraGLTest#testSetPreviewTextureBothCallbacks',
+          'android.hardware.cts.CameraGLTest#testSetPreviewTexturePreviewCallback',],
+      'android.media' : [
+          'android.media.cts.DecoderTest#testCodecResetsH264WithSurface',
+          'android.media.cts.StreamingMediaPlayerTest#testHLS',],
+      'android.net' : [
+          'android.net.cts.ConnectivityManagerTest#testStartUsingNetworkFeature_enableHipri',
+          'android.net.cts.DnsTest#testDnsWorks',
+          'android.net.cts.SSLCertificateSocketFactoryTest#testCreateSocket',
+          'android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_bind',
+          'android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_simple',
+          'android.net.cts.SSLCertificateSocketFactoryTest#test_createSocket_wrapping',
+          'android.net.cts.TrafficStatsTest#testTrafficStatsForLocalhost',
+          'android.net.wifi.cts.NsdManagerTest#testAndroidTestCaseSetupProperly',],
+      'android.security' : [
+          'android.security.cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdp6Ports',
+          'android.security.cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdpPorts',],
+      'android.webkit' : [
+          'android.webkit.cts.WebViewClientTest#testOnUnhandledKeyEvent',],
+      'com.android.cts.filesystemperf' : [
+          'com.android.cts.filesystemperf.RandomRWTest#testRandomRead',
+          'com.android.cts.filesystemperf.RandomRWTest#testRandomUpdate',],
+      '' : []}
+
+def BuildCtsTemporarilyKnownFailureList():
+  """ Construct a defaultdict that maps package name to a list of tests
+      that are known failures during dev cycle but expected to be fixed before launch """
+  return {
+      'android.alarmclock' : [
+          'android.alarmclock.cts.DismissAlarmTest#testAll',
+          'android.alarmclock.cts.SetAlarmTest#testAll',
+          'android.alarmclock.cts.SnoozeAlarmTest#testAll',
+      ],
+      'android.assist' : [
+          'android.assist.cts.AssistantContentViewTest',
+          'android.assist.cts.ExtraAssistDataTest',
+          'android.assist.cts.FocusChangeTest',
+          'android.assist.cts.LargeViewHierarchyTest',
+          'android.assist.cts.ScreenshotTest',
+          'android.assist.cts.TextViewTest',
+          'android.assist.cts.WebViewTest',
+      ],
+      'android.calllog' : [
+          'android.calllog.cts.CallLogBackupTest#testSingleCallBackup',
+      ],
+      'android.dumpsys' : [
+          'android.dumpsys.cts.DumpsysHostTest#testBatterystatsOutput',
+          'android.dumpsys.cts.DumpsysHostTest#testGfxinfoFramestats',
+      ],
+      'android.telecom' : [
+          'android.telecom.cts.ExtendedInCallServiceTest#testAddNewOutgoingCallAndThenDisconnect',
+          'android.telecom.cts.RemoteConferenceTest#testRemoteConferenceCallbacks_ConferenceableConnections',
+      ],
+      'android.transition' : [
+          'android.transition.cts.ChangeScrollTest#testChangeScroll',
+      ],
+      'android.voicesettings' : [
+          'android.voicesettings.cts.ZenModeTest#testAll',
+      ],
+      'com.android.cts.systemui' : [
+          'com.android.cts.systemui.LightStatusBarTests#testLightStatusBarIcons',
+      ],
+      'com.android.cts.app.os' : [
+          'com.android.cts.app.os.OsHostTests#testNonExportedActivities',
+      ],
+      'com.android.cts.devicepolicy' : [
+          'com.android.cts.devicepolicy.MixedDeviceOwnerTest#testPackageInstallUserRestrictions',
+          'com.android.cts.devicepolicy.MixedProfileOwnerTest#testPackageInstallUserRestrictions',
+      ],
+      '' : []}
+
+def BuildCtsMiscCameraList():
+  """ Construct a defaultdict that maps package name to a list of tests
+      that are relevant to camera but does not reside in camera test package """
   return {
       'android.app' : [
-          'cts.ActivityManagerTest#testIsRunningInTestHarness',],
-      'android.dpi' : [
-          'cts.DefaultManifestAttributesSdkTest#testPackageHasExpectedSdkVersion',],
-      'android.hardware' : [
-          'cts.CameraTest#testVideoSnapshot',
-          'cts.CameraGLTest#testCameraToSurfaceTextureMetadata',
-          'cts.CameraGLTest#testSetPreviewTextureBothCallbacks',
-          'cts.CameraGLTest#testSetPreviewTexturePreviewCallback',],
-      'android.media' : [
-          'cts.DecoderTest#testCodecResetsH264WithSurface',
-          'cts.StreamingMediaPlayerTest#testHLS',],
-      'android.net' : [
-          'cts.ConnectivityManagerTest#testStartUsingNetworkFeature_enableHipri',
-          'cts.DnsTest#testDnsWorks',
-          'cts.SSLCertificateSocketFactoryTest#testCreateSocket',
-          'cts.SSLCertificateSocketFactoryTest#test_createSocket_bind',
-          'cts.SSLCertificateSocketFactoryTest#test_createSocket_simple',
-          'cts.SSLCertificateSocketFactoryTest#test_createSocket_wrapping',
-          'cts.TrafficStatsTest#testTrafficStatsForLocalhost',
-          'wifi.cts.NsdManagerTest#testAndroidTestCaseSetupProperly',],
-      'android.os' : [
-          'cts.BuildVersionTest#testReleaseVersion',
-          'cts.BuildTest#testIsSecureUserBuild',],
-      'android.security' : [
-          'cts.BannedFilesTest#testNoSu',
-          'cts.BannedFilesTest#testNoSuInPath',
-          'cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdp6Ports',
-          'cts.ListeningPortsTest#testNoRemotelyAccessibleListeningUdpPorts',
-          'cts.PackageSignatureTest#testPackageSignatures',
-          'cts.SELinuxDomainTest#testSuDomain',
-          'cts.SELinuxHostTest#testAllEnforcing',],
-      'android.webkit' : [
-          'cts.WebViewClientTest#testOnUnhandledKeyEvent',],
-      'com.android.cts.filesystemperf' : [
-          'RandomRWTest#testRandomRead',
-          'RandomRWTest#testRandomUpdate',],
+          'android.app.cts.SystemFeaturesTest#testCameraFeatures',
+      ],
+      'android.permission' : [
+          'android.permission.cts.CameraPermissionTest',
+          'android.permission.cts.Camera2PermissionTest',
+      ],
       '' : []}
 
 def LogGenerateDescription(name):
diff --git a/tools/utils/cts/tools.py b/tools/utils/cts/tools.py
index 649e4d7..832e1f2 100644
--- a/tools/utils/cts/tools.py
+++ b/tools/utils/cts/tools.py
@@ -134,7 +134,7 @@
     """
     packaged_test_list = []
     for test in test_list:
-      packaged_test_list.append(package + '.' + test)
+      packaged_test_list.append(test)
 
     if package in self.includedTestsMap:
       self.includedTestsMap[package] += packaged_test_list
@@ -152,7 +152,7 @@
     """
     packaged_test_list = []
     for test in test_list:
-      packaged_test_list.append(package + '.' + test)
+      packaged_test_list.append(test)
     if package in self.excludedTestsMap:
       self.excludedTestsMap[package] += packaged_test_list
     else:
diff --git a/tools/vm-tests-tf/Android.mk b/tools/vm-tests-tf/Android.mk
index 88f2a53..b1cbe37 100644
--- a/tools/vm-tests-tf/Android.mk
+++ b/tools/vm-tests-tf/Android.mk
@@ -14,6 +14,28 @@
 
 LOCAL_PATH := $(call my-dir)
 
+# test dex library
+# ============================================================
+include $(CLEAR_VARS)
+
+# custom variables used to generate test description. do not touch!
+LOCAL_SRC_FILES := $(call all-java-files-under, src/dot)
+
+LOCAL_MODULE := cts-tf-dalvik-lib
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_MODULE_TAGS := optional
+LOCAL_JAVA_LIBRARIES := junit-targetdex
+
+include $(BUILD_JAVA_LIBRARY)
+
+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)
@@ -29,31 +51,46 @@
 LOCAL_MODULE_TAGS := optional
 
 LOCAL_JAVA_LIBRARIES := dx dasm cfassembler junit
-LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR)
+LOCAL_JAVA_LIBRARIES += jack
+
+LOCAL_CLASSPATH := $(HOST_JDK_TOOLS_JAR) $(private_jill_jarjar_asm)
 
 include $(BUILD_HOST_JAVA_LIBRARY)
 
 # Buid android.core.vm-tests-tf.jar
 # ============================================================
 #
+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)
+
+$(vmteststf_jar): PRIVATE_JACK_VM_ARGS := $(LOCAL_JACK_VM_ARGS)
+$(vmteststf_jar): 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_LIB_FOLDER := $(LOCAL_PATH)/lib
 $(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)
-$(vmteststf_jar) : $(vmteststf_dep_jars) $(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar
+ifndef LOCAL_JACK_ENABLED
+$(vmteststf_jar) : $(vmteststf_dep_jars) $(JACK_JAR) $(JILL_JAR) $(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
 	@echo "Write generated Main_*.java files to $(PRIVATE_INTERMEDIATES_MAIN_FILES)"
 	$(hide) java -cp $(PRIVATE_CLASS_PATH) util.build.BuildDalvikSuite $(PRIVATE_SRC_FOLDER) $(PRIVATE_INTERMEDIATES) \
-		$(HOST_OUT_JAVA_LIBRARIES)/cts-tf-dalvik-buildutil.jar:$(PRIVATE_LIB_FOLDER)/junit.jar:$(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar \
+		$(HOST_OUT_JAVA_LIBRARIES)/cts-tf-dalvik-buildutil.jar:$(HOST_OUT_JAVA_LIBRARIES)/tradefed-prebuilt.jar \
 		$(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).jar \
@@ -62,6 +99,26 @@
 		$(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
+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
+	$(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 \
+		$(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) 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 \
+		$(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
+endif # LOCAL_JACK_ENABLED
 
 # Clean up temp vars
 intermediates :=
diff --git a/tools/vm-tests-tf/etc/starttests b/tools/vm-tests-tf/etc/starttests
index be8fad4..4c5c0b1 100755
--- a/tools/vm-tests-tf/etc/starttests
+++ b/tools/vm-tests-tf/etc/starttests
@@ -63,7 +63,6 @@
 scriptdata=$dalviktestdir/data/scriptdata
 report=$dalviktest/report.html
 curdate=`date`
-curmode=""
 datadir=/tmp/${USER}
 base=$OUT
 framework=$base/system/framework
@@ -100,14 +99,6 @@
 mkdir -p $datadir
 mkdir -p $datadir/dalvik-cache
 
-if [ "$TARGET_SIMULATOR" = "true" ]; then
-    echo "Simulator mode, $interpreter interpreter";
-    curmode="simulator"
-else
-    echo "Emulator mode, $interpreter interpreter";
-    curmode="emulator"
-fi
-
 echo ""
 
 pre_report="<html><head><style>
@@ -118,7 +109,7 @@
 </style></head>
 <body>
 <h1>Dalvik VM test suite results</h1>
-Generated $curdate (using the $curmode)
+Generated $curdate (using the emulator)
 <p>
 <table width='100%'>
 <tr><td>Status</td><td>Target</td><td>Category</td><td>Details</td></tr>"
@@ -136,12 +127,8 @@
 export jallcnt=0
 export jcolumns=0
 
-# TODO unhack
-if [ "$TARGET_SIMULATOR" = "true" ]; then
-    echo -n ""
-else
-    adb push $dexcore /data/local/tmp/dexcore.jar >> /dev/null 2>&1
-fi
+# TODO unhack; dimitry: unhack what?
+adb push $dexcore /data/local/tmp/dexcore.jar >> /dev/null 2>&1
 
 function classnameToJar()
 {
@@ -175,40 +162,25 @@
         # write dalvik output to file
         echo -n "mk_b:" > $datadir/dalvikout
 
-        if [ "$TARGET_SIMULATOR" = "true" ]; then
-            classpath=`classnameToJar ${mainclass}`
-            for dep in ${deps}; do
-                depJar=`classnameToJar ${dep}`
-                classpath=${classpath}:${depJar}
-            done
-            $valgrind $exe -Xmx512M -Xss32K -Xbootclasspath:$bpath $debug_opts \
-                -classpath $dexcore:$classpath $mainclass >> $datadir/dalvikout 2>&1
+        classpath="/data/local/tmp/dexcore.jar"
+        deps=${deps}" "${mainclass}
+        pushedjars=""
+        for dep in ${deps}; do
+            depJar=`classnameToJar ${dep}`
+            depFileName=`basename ${depJar}`
+            deviceFileName=/data/local/tmp/${depFileName}
+            adb push ${depJar} ${deviceFileName} &> /dev/null
+            classpath=${classpath}:${deviceFileName}
+            pushedjars=${pushedjars}" "${deviceFileName}
+        done
 
-            RESULTCODE=$?
-            if [ ${RESULTCODE} -ne 0 ]; then
-                echo "Dalvik VM failed, result=${RESULTCODE}" >> $datadir/dalvikout 2>&1
-            fi
-        else
-            classpath="/data/local/tmp/dexcore.jar"
-            deps=${deps}" "${mainclass}
-            pushedjars=""
-            for dep in ${deps}; do
-                depJar=`classnameToJar ${dep}`
-                depFileName=`basename ${depJar}`
-                deviceFileName=/data/local/tmp/${depFileName}
-                adb push ${depJar} ${deviceFileName} &> /dev/null
-                classpath=${classpath}:${deviceFileName}
-                pushedjars=${pushedjars}" "${deviceFileName}
-            done
+        adb shell dalvikvm -Djava.io.tmpdir=/data/local/tmp \
+            -classpath $classpath $mainclass >> $datadir/dalvikout 2>&1 && \
+            echo -n dvmpassed: >> $datadir/dalvikout 2>&1
 
-            adb shell dalvikvm -Djava.io.tmpdir=/data/local/tmp \
-                -classpath $classpath $mainclass >> $datadir/dalvikout 2>&1 && \
-                echo -n dvmpassed: >> $datadir/dalvikout 2>&1
-
-            for jar in ${pushedjars}; do
-                adb shell rm ${jar} &> /dev/null
-            done
-        fi
+        for jar in ${pushedjars}; do
+            adb shell rm ${jar} &> /dev/null
+        done
 
         echo -n "mk_s:" >> $datadir/dalvikout
         # Verify tmpout only contains mkdxc_start;mkdxc_stop -> no system.out/err
diff --git a/tools/vm-tests-tf/jill-jarjar-rules.txt b/tools/vm-tests-tf/jill-jarjar-rules.txt
new file mode 100644
index 0000000..ee6f403
--- /dev/null
+++ b/tools/vm-tests-tf/jill-jarjar-rules.txt
@@ -0,0 +1 @@
+rule org.objectweb.** com.android.jill.@0
\ No newline at end of file
diff --git a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_11.d b/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_11.d
index 75fb804..0506be0 100644
--- a/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_11.d
+++ b/tools/vm-tests-tf/src/dot/junit/opcodes/new_instance/d/T_new_instance_11.d
@@ -28,13 +28,16 @@
 .limit regs 6
 
        const v4, 5
-       move-object v1, v5
-Label0:
-       move-object v0, v1
+       goto LabelEntry
+
+LabelBwd:
+       invoke-virtual {v1}, java/lang/Object/hashCode()I
+
+LabelEntry:
        new-instance v1, java/lang/Integer
-       
+
        add-int/lit8 v4, v4, -1
-       if-nez v4, Label0
+       if-nez v4, LabelBwd
 
        invoke-direct {v1, v4}, java/lang/Integer/<init>(I)V
        return-void
diff --git a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
index c772c33..0e31884 100644
--- a/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
+++ b/tools/vm-tests-tf/src/util/build/BuildDalvikSuite.java
@@ -78,6 +78,7 @@
 
     private int testClassCnt = 0;
     private int testMethodsCnt = 0;
+    private boolean useJack;
 
     /*
      * using a linked hashmap to keep the insertion order for iterators.
@@ -101,39 +102,47 @@
      */
     public static void main(String[] args) throws IOException {
 
-        if (args.length > 5) {
-            JAVASRC_FOLDER = args[0];
-            OUTPUT_FOLDER = args[1];
-            CLASS_PATH = args[2];
-            MAIN_SRC_OUTPUT_FOLDER = args[3];
-            CLASSES_OUTPUT_FOLDER = MAIN_SRC_OUTPUT_FOLDER + "/classes";
-
-            COMPILED_CLASSES_FOLDER = args[4];
-
-            HOSTJUNIT_SRC_OUTPUT_FOLDER = args[5];
-            HOSTJUNIT_CLASSES_OUTPUT_FOLDER = HOSTJUNIT_SRC_OUTPUT_FOLDER + "/classes";
-
-            if (args.length > 6) {
-                // optional: restrict to e.g. "opcodes.add_double"
-                restrictTo = args[6];
-                System.out.println("restricting build to: " + restrictTo);
-            }
-
-        } 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);
-        }
+        parseArgs(args);
 
         long start = System.currentTimeMillis();
-        BuildDalvikSuite cat = new BuildDalvikSuite();
+        BuildDalvikSuite cat = new BuildDalvikSuite(false);
         cat.compose();
         long end = System.currentTimeMillis();
 
         System.out.println("elapsed seconds: " + (end - start) / 1000);
     }
 
+    public static void parseArgs(String[] args) {
+      if (args.length > 5) {
+          JAVASRC_FOLDER = args[0];
+          OUTPUT_FOLDER = args[1];
+          CLASS_PATH = args[2];
+          MAIN_SRC_OUTPUT_FOLDER = args[3];
+          CLASSES_OUTPUT_FOLDER = MAIN_SRC_OUTPUT_FOLDER + "/classes";
+
+          COMPILED_CLASSES_FOLDER = args[4];
+
+          HOSTJUNIT_SRC_OUTPUT_FOLDER = args[5];
+          HOSTJUNIT_CLASSES_OUTPUT_FOLDER = HOSTJUNIT_SRC_OUTPUT_FOLDER + "/classes";
+
+          if (args.length > 6) {
+              // optional: restrict to e.g. "opcodes.add_double"
+              restrictTo = args[6];
+              System.out.println("restricting build to: " + restrictTo);
+          }
+
+      } 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);
+      }
+    }
+
+    public BuildDalvikSuite(boolean useJack) {
+      this.useJack = useJack;
+    }
+
     public void compose() throws IOException {
         System.out.println("Collecting all junit tests...");
         new TestRunner() {
@@ -182,19 +191,21 @@
         li.add(method);
     }
     private String curJunitFileName = null;
+    private String curJunitName = null;
     private String curJunitFileData = "";
 
-    private JavacBuildStep javacHostJunitBuildStep;
+    private SourceBuildStep hostJunitBuildStep;
 
     private void flushHostJunitFile() {
         if (curJunitFileName != null) {
             File toWrite = new File(curJunitFileName);
             String absPath = toWrite.getAbsolutePath();
             // add to java source files for later compilation
-            javacHostJunitBuildStep.addSourceFile(absPath);
+            hostJunitBuildStep.addSourceFile(absPath);
             // write file
             curJunitFileData += "\n}\n";
             writeToFileMkdir(toWrite, curJunitFileData);
+
             curJunitFileName = null;
             curJunitFileData = "";
         }
@@ -211,6 +222,8 @@
         curJunitFileData = getWarningMessage() +
         "package " + pName + ";\n" +
         "import java.io.IOException;\n" +
+        "import java.util.concurrent.TimeUnit;\n\n" +
+        "import com.android.tradefed.device.CollectingOutputReceiver;\n" +
         "import com.android.tradefed.testtype.IAbi;\n" +
         "import com.android.tradefed.testtype.IAbiReceiver;\n" +
         "import com.android.tradefed.testtype.DeviceTestCase;\n" +
@@ -223,10 +236,15 @@
       String cmd = String.format("ANDROID_DATA=%s dalvikvm|#ABI#| -Xmx512M -Xss32K " +
               "-Djava.io.tmpdir=%s -classpath %s %s", TARGET_JAR_ROOT_PATH, TARGET_JAR_ROOT_PATH,
               classpath, mainclass);
-      return "    String cmd = AbiFormatter.formatCmdForAbi(\"" + cmd + "\", mAbi.getBitness());\n" +
-              "    String res = getDevice().executeShellCommand(cmd);\n" +
-              "    // A sucessful adb shell command returns an empty string.\n" +
-              "    assertEquals(cmd, \"\", res);";
+      StringBuilder code = new StringBuilder();
+      code.append("    String cmd = AbiFormatter.formatCmdForAbi(\"")
+          .append(cmd)
+          .append("\", mAbi.getBitness());\n")
+          .append("    CollectingOutputReceiver receiver = new CollectingOutputReceiver();\n")
+          .append("    getDevice().executeShellCommand(cmd, receiver, 6, TimeUnit.MINUTES, 1);\n")
+          .append("    // A sucessful adb shell command returns an empty string.\n")
+          .append("    assertEquals(cmd, \"\", receiver.getOutput());");
+      return code.toString();
     }
 
     private String getWarningMessage() {
@@ -267,11 +285,11 @@
         String datafileContent = "";
         Set<BuildStep> targets = new TreeSet<BuildStep>();
 
-        javacHostJunitBuildStep = new JavacBuildStep(HOSTJUNIT_CLASSES_OUTPUT_FOLDER, CLASS_PATH);
+        SourceBuildStep srcBuildStep;
+        hostJunitBuildStep = new JavacBuildStep(
+            HOSTJUNIT_CLASSES_OUTPUT_FOLDER, CLASS_PATH);
 
-
-        JavacBuildStep javacBuildStep = new JavacBuildStep(
-                CLASSES_OUTPUT_FOLDER, CLASS_PATH);
+        srcBuildStep = new JavacBuildStep(CLASSES_OUTPUT_FOLDER, CLASS_PATH);
 
         for (Entry<String, List<String>> entry : map.entrySet()) {
 
@@ -334,19 +352,25 @@
                 "    public static void main(String[] args) throws Exception {" +
                 methodContent + "\n}\n";
 
-                String fileName = getFileName(pName, method, ".java");
                 File sourceFile = getFileFromPackage(pName, method);
 
-                File classFile = new File(CLASSES_OUTPUT_FOLDER + "/" +
-                        getFileName(pName, method, ".class"));
-                // if (sourceFile.lastModified() > classFile.lastModified()) {
                 writeToFile(sourceFile, content);
-                javacBuildStep.addSourceFile(sourceFile.getAbsolutePath());
+                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, ""));
+                        CLASSES_OUTPUT_FOLDER, getFileName(pName, method, ""), null);
                 targets.add(dexBuildStep);
-                // }
 
 
                 // prepare the entry in the data file for the bash script.
@@ -442,22 +466,23 @@
         scriptDataDir.mkdirs();
         writeToFile(new File(scriptDataDir, "scriptdata"), datafileContent);
 
-        if (!javacHostJunitBuildStep.build()) {
+        if (!hostJunitBuildStep.build()) {
             System.out.println("main javac cts-host-hostjunit-classes build step failed");
             System.exit(1);
         }
 
-        if (javacBuildStep.build()) {
-            for (BuildStep buildStep : targets) {
-                if (!buildStep.build()) {
-                    System.out.println("building failed. buildStep: " +
-                            buildStep.getClass().getName() + ", " + buildStep);
-                    System.exit(1);
-                }
+        if (!useJack) {
+            if (!srcBuildStep.build()) {
+                System.out.println("main src dalvik-cts-buildutil build step failed");
+                System.exit(1);
             }
-        } else {
-            System.out.println("main javac dalvik-cts-buildutil build step failed");
-            System.exit(1);
+        }
+        for (BuildStep buildStep : targets) {
+            if (!buildStep.build()) {
+                System.out.println("building failed. buildStep: " +
+                        buildStep.getClass().getName() + ", " + buildStep);
+                System.exit(1);
+            }
         }
     }
 
@@ -514,19 +539,37 @@
             return;
         }
 
-        if (new File(sourceFolder, fileName + ".java").exists()) {
-
+        File srcFile = new File(sourceFolder, fileName + ".java");
+        if (srcFile.exists()) {
+            JackBuildStep jackBuildStep = null;
+            if (useJack) {
+                jackBuildStep = new JackBuildStep(
+                        COMPILED_CLASSES_FOLDER + File.separator + fileName + ".jack",
+                        CLASS_PATH);
+                jackBuildStep.addSourceFile(srcFile.getAbsolutePath());
+            }
             BuildStep dexBuildStep = generateDexBuildStep(
-                    COMPILED_CLASSES_FOLDER, fileName);
+                COMPILED_CLASSES_FOLDER, fileName, jackBuildStep);
             targets.add(dexBuildStep);
             return;
         }
 
         try {
             if (Class.forName(dependentTestClassName) != null) {
+                JillBuildStep jillBuildStep = null;
+                if (useJack) {
+                    BuildStep.BuildFile classFile = new BuildStep.BuildFile(
+                        COMPILED_CLASSES_FOLDER, fileName + ".class");
 
+                    BuildStep.BuildFile jackFile = new BuildStep.BuildFile(
+                        COMPILED_CLASSES_FOLDER,
+                        fileName + ".jack");
+
+                    jillBuildStep = new JillBuildStep(classFile,
+                        jackFile);
+                }
                 BuildStep dexBuildStep = generateDexBuildStep(
-                        COMPILED_CLASSES_FOLDER, fileName);
+                    COMPILED_CLASSES_FOLDER, fileName, jillBuildStep);
                 targets.add(dexBuildStep);
                 return;
             }
@@ -539,24 +582,50 @@
     }
 
     private BuildStep generateDexBuildStep(String classFileFolder,
-            String classFileName) {
-        BuildStep.BuildFile classFile = new BuildStep.BuildFile(
-                classFileFolder, classFileName + ".class");
+            String classFileName, BuildStep dependency) {
+        if (!useJack) {
+            BuildStep.BuildFile classFile = new BuildStep.BuildFile(
+                    classFileFolder, classFileName + ".class");
 
-        BuildStep.BuildFile tmpJarFile = new BuildStep.BuildFile(OUTPUT_FOLDER,
-                classFileName + "_tmp.jar");
+            BuildStep.BuildFile tmpJarFile = new BuildStep.BuildFile(
+                    OUTPUT_FOLDER,
+                    classFileName + "_tmp.jar");
 
-        JarBuildStep jarBuildStep = new JarBuildStep(classFile, classFileName +
-                ".class", tmpJarFile, false);
+            JarBuildStep jarBuildStep = new JarBuildStep(classFile,
+                    classFileName + ".class", tmpJarFile, false);
 
-        BuildStep.BuildFile outputFile = new BuildStep.BuildFile(OUTPUT_FOLDER,
-                classFileName + ".jar");
+            if (dependency != null) {
+                jarBuildStep.addChild(dependency);
+            }
 
-        DexBuildStep dexBuildStep = new DexBuildStep(tmpJarFile, outputFile,
-                true);
+            BuildStep.BuildFile outputFile = new BuildStep.BuildFile(
+                    OUTPUT_FOLDER,
+                    classFileName + ".jar");
 
-        dexBuildStep.addChild(jarBuildStep);
-        return dexBuildStep;
+            DxBuildStep dexBuildStep = new DxBuildStep(tmpJarFile,
+                    outputFile,
+                    true);
+
+            dexBuildStep.addChild(jarBuildStep);
+            return dexBuildStep;
+        } else {
+          BuildStep.BuildFile jackFile = new BuildStep.BuildFile(
+              classFileFolder, classFileName + ".jack");
+
+          BuildStep.BuildFile outputFile = new BuildStep.BuildFile(
+                  OUTPUT_FOLDER,
+                  classFileName + ".jar");
+
+          JackDexBuildStep dexBuildStep = new JackDexBuildStep(jackFile,
+                  outputFile,
+                  true);
+
+          if (dependency != null) {
+              dexBuildStep.addChild(dependency);
+          }
+          return dexBuildStep;
+
+        }
 
     }
 
@@ -747,7 +816,7 @@
 
     private void writeToFile(File file, String content) {
         try {
-            if (file.length() == content.length()) {
+            if (file.exists() && file.length() == content.length()) {
                 FileReader reader = new FileReader(file);
                 char[] charContents = new char[(int) file.length()];
                 reader.read(charContents);
diff --git a/tools/vm-tests-tf/src/util/build/DexBuildStep.java b/tools/vm-tests-tf/src/util/build/DexBuildStep.java
deleted file mode 100644
index 6aba51c..0000000
--- a/tools/vm-tests-tf/src/util/build/DexBuildStep.java
+++ /dev/null
@@ -1,83 +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 util.build;
-
-import com.android.dx.command.dexer.Main;
-import java.io.IOException;
-
-public class DexBuildStep extends BuildStep {
-
-    private final boolean deleteInputFileAfterBuild;
-
-    DexBuildStep(BuildFile inputFile, BuildFile outputFile,
-            boolean deleteInputFileAfterBuild) {
-        super(inputFile, outputFile);
-        this.deleteInputFileAfterBuild = deleteInputFileAfterBuild;
-    }
-
-    @Override
-    boolean build() {
-
-        if (super.build()) {
-            Main.Arguments args = new Main.Arguments();
-
-            args.jarOutput = true;
-            args.fileNames = new String[] {inputFile.fileName.getAbsolutePath()};
-
-            args.outName = outputFile.fileName.getAbsolutePath();
-
-            int result = 0;
-            try {
-                result = Main.run(args);
-            } catch (IOException e) {
-                e.printStackTrace();
-                return false;
-            }
-
-            if (result == 0) {
-                if (deleteInputFileAfterBuild) {
-                    inputFile.fileName.delete();
-                }
-                return true;
-            } else {
-                System.err.println("exception while dexing "
-                        + inputFile.fileName.getAbsolutePath() + " to "
-                        + args.outName);
-                return false;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return inputFile.hashCode() ^ outputFile.hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (super.equals(obj)) {
-            DexBuildStep other = (DexBuildStep) obj;
-
-            return inputFile.equals(other.inputFile)
-                    && outputFile.equals(other.outputFile);
-        }
-        return false;
-    }
-
-
-}
diff --git a/tools/vm-tests-tf/src/util/build/DxBuildStep.java b/tools/vm-tests-tf/src/util/build/DxBuildStep.java
new file mode 100644
index 0000000..6e347b2
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/DxBuildStep.java
@@ -0,0 +1,83 @@
+/*
+ * 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 util.build;
+
+import com.android.dx.command.dexer.Main;
+import java.io.IOException;
+
+public class DxBuildStep extends BuildStep {
+
+    private final boolean deleteInputFileAfterBuild;
+
+    DxBuildStep(BuildFile inputFile, BuildFile outputFile,
+            boolean deleteInputFileAfterBuild) {
+        super(inputFile, outputFile);
+        this.deleteInputFileAfterBuild = deleteInputFileAfterBuild;
+    }
+
+    @Override
+    boolean build() {
+
+        if (super.build()) {
+            Main.Arguments args = new Main.Arguments();
+
+            args.jarOutput = true;
+            args.fileNames = new String[] {inputFile.fileName.getAbsolutePath()};
+
+            args.outName = outputFile.fileName.getAbsolutePath();
+
+            int result = 0;
+            try {
+                result = Main.run(args);
+            } catch (IOException e) {
+                e.printStackTrace();
+                return false;
+            }
+
+            if (result == 0) {
+                if (deleteInputFileAfterBuild) {
+                    inputFile.fileName.delete();
+                }
+                return true;
+            } else {
+                System.err.println("exception while dexing "
+                        + inputFile.fileName.getAbsolutePath() + " to "
+                        + args.outName);
+                return false;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return inputFile.hashCode() ^ outputFile.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (super.equals(obj)) {
+            DxBuildStep other = (DxBuildStep) obj;
+
+            return inputFile.equals(other.inputFile)
+                    && outputFile.equals(other.outputFile);
+        }
+        return false;
+    }
+
+
+}
diff --git a/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java b/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
new file mode 100644
index 0000000..a508e5b
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/JackBuildDalvikSuite.java
@@ -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.
+ */
+
+package util.build;
+
+import java.io.IOException;
+
+public class JackBuildDalvikSuite {
+
+    public static void main(String[] args) throws IOException {
+
+        BuildDalvikSuite.parseArgs(args);
+
+        long start = System.currentTimeMillis();
+        BuildDalvikSuite cat = new BuildDalvikSuite(true);
+        cat.compose();
+        long end = System.currentTimeMillis();
+
+        System.out.println("elapsed seconds: " + (end - start) / 1000);
+    }
+}
diff --git a/tools/vm-tests-tf/src/util/build/JackBuildStep.java b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
new file mode 100644
index 0000000..1e1ede6
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/JackBuildStep.java
@@ -0,0 +1,93 @@
+/*
+ * 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 util.build;
+
+import com.android.jack.Jack;
+import com.android.jack.Main;
+import com.android.jack.Options;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class JackBuildStep extends SourceBuildStep {
+
+    private final String destPath;
+    private final String classPath;
+    private final Set<String> sourceFiles = new HashSet<String>();
+
+    public JackBuildStep(String destPath, String classPath) {
+        this.destPath = destPath;
+        this.classPath = classPath;
+    }
+
+    @Override
+    public void addSourceFile(String sourceFile) {
+        sourceFiles.add(sourceFile);
+    }
+
+    @Override
+    boolean build() {
+        if (super.build()) {
+            if (sourceFiles.isEmpty()) {
+                return true;
+            }
+
+            File outDir = new File(destPath).getParentFile();
+            if (!outDir.exists() && !outDir.mkdirs()) {
+                System.err.println("failed to create output dir: "
+                        + 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);
+
+            try {
+                Options options = Main.parseCommandLine(commandLine);
+                Jack.checkAndRun(options);
+            } catch (Throwable ex) {
+                ex.printStackTrace();
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (super.equals(obj)) {
+            JackBuildStep other = (JackBuildStep) obj;
+            return destPath.equals(other.destPath) && classPath.equals(other.classPath)
+                    && sourceFiles.equals(other.sourceFiles);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return destPath.hashCode() ^ classPath.hashCode() ^ sourceFiles.hashCode();
+    }
+}
diff --git a/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
new file mode 100644
index 0000000..304eaa0
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/JackDexBuildStep.java
@@ -0,0 +1,96 @@
+/*
+ * 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 util.build;
+
+import com.android.jack.Jack;
+import com.android.jack.Main;
+import com.android.jack.Options;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JackDexBuildStep extends BuildStep {
+
+    private final boolean deleteInputFileAfterBuild;
+
+    JackDexBuildStep(BuildFile inputFile, BuildFile outputFile,
+            boolean deleteInputFileAfterBuild) {
+        super(inputFile, outputFile);
+        this.deleteInputFileAfterBuild = deleteInputFileAfterBuild;
+    }
+
+    @Override
+    boolean build() {
+
+        if (super.build()) {
+            String outputFilePath = outputFile.fileName.getAbsolutePath();
+            if (outputFilePath.endsWith(".dex")) {
+              throw new AssertionError(
+                  "DexBuildStep does not support dex output outside of an archive");
+            }
+
+            File outDir = outputFile.fileName.getParentFile();
+            if (!outDir.exists() && !outDir.mkdirs()) {
+                System.err.println("failed to create output dir: "
+                        + outDir.getAbsolutePath());
+                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());
+
+            try {
+               Options options = Main.parseCommandLine(commandLine);
+               Jack.checkAndRun(options);
+                if (deleteInputFileAfterBuild) {
+                    inputFile.fileName.delete();
+                }
+                return true;
+            } catch (Throwable ex) {
+                System.err.println("exception while dexing "
+                        + inputFile.fileName.getAbsolutePath() + " to "
+                        + outputFile.fileName.getAbsolutePath());
+                ex.printStackTrace();
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return inputFile.hashCode() ^ outputFile.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (super.equals(obj)) {
+            JackDexBuildStep other = (JackDexBuildStep) obj;
+
+            return inputFile.equals(other.inputFile)
+                    && outputFile.equals(other.outputFile);
+        }
+        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 7d7033f..d08a2c6 100644
--- a/tools/vm-tests-tf/src/util/build/JavacBuildStep.java
+++ b/tools/vm-tests-tf/src/util/build/JavacBuildStep.java
@@ -23,7 +23,7 @@
 import java.util.HashSet;
 import java.util.Set;
 
-public class JavacBuildStep extends BuildStep {
+public class JavacBuildStep extends SourceBuildStep {
 
     private final String destPath;
     private final String classPath;
@@ -32,12 +32,13 @@
         this.destPath = destPath;
         this.classPath = classPath;
     }
-    
+
+    @Override
     public void addSourceFile(String sourceFile)
     {
         sourceFiles.add(sourceFile);
     }
-    
+
     @Override
     boolean build() {
         if (super.build())
@@ -46,7 +47,7 @@
             {
                 return true;
             }
-            
+
             File destFile = new File(destPath);
             if (!destFile.exists() && !destFile.mkdirs())
             {
@@ -59,13 +60,12 @@
             commandLine[1] = classPath;
             commandLine[2] = "-d";
             commandLine[3] = destPath;
-             
+
             String[] files = new String[sourceFiles.size()];
             sourceFiles.toArray(files);
-            
+
             System.arraycopy(files, 0, commandLine, args, files.length);
-            
-            
+
             return Main.compile(commandLine, new PrintWriter(System.err)) == 0;
         }
         return false;
@@ -73,17 +73,16 @@
 
     @Override
     public boolean equals(Object obj) {
-        // TODO Auto-generated method stub
         if (super.equals(obj))
         {
             JavacBuildStep other = (JavacBuildStep) obj;
-            return destPath.equals(other.destPath) 
+            return destPath.equals(other.destPath)
                 && classPath.equals(other.classPath)
                 && sourceFiles.equals(other.sourceFiles);
         }
         return false;
     }
-    
+
     @Override
     public int hashCode() {
         return destPath.hashCode() ^ classPath.hashCode() ^ sourceFiles.hashCode();
diff --git a/tools/vm-tests-tf/src/util/build/JillBuildStep.java b/tools/vm-tests-tf/src/util/build/JillBuildStep.java
new file mode 100644
index 0000000..d2e435e
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/JillBuildStep.java
@@ -0,0 +1,75 @@
+/*
+ * 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 util.build;
+
+import com.android.jill.Jill;
+import com.android.jill.Main;
+import com.android.jill.Options;
+
+import java.io.File;
+
+public class JillBuildStep extends BuildStep {
+
+    JillBuildStep(BuildFile inputFile, BuildFile outputFile) {
+        super(inputFile, outputFile);
+    }
+
+    @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();
+
+            try {
+                Options options = Main.getOptions(commandLine);
+                Jill.process(options);
+            } catch (Throwable ex) {
+                ex.printStackTrace();
+                return false;
+            }
+
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (super.equals(obj)) {
+            JillBuildStep other = (JillBuildStep) obj;
+
+            return inputFile.equals(other.inputFile) && outputFile.equals(other.outputFile);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return inputFile.hashCode() ^ outputFile.hashCode();
+    }
+}
diff --git a/tools/vm-tests-tf/src/util/build/SourceBuildStep.java b/tools/vm-tests-tf/src/util/build/SourceBuildStep.java
new file mode 100644
index 0000000..4a68a05
--- /dev/null
+++ b/tools/vm-tests-tf/src/util/build/SourceBuildStep.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 util.build;
+
+public abstract class SourceBuildStep extends BuildStep {
+
+  public abstract void addSourceFile(String sourceFile);
+
+}